thrift-0.23.0/0000755000175000017500000000000015170007202013346 5ustar00buildbuild00000000000000thrift-0.23.0/bower.json0000664000175000017500000000046415170007142015370 0ustar00buildbuild00000000000000{ "name": "thrift", "version": "0.23.0", "homepage": "https://github.com/apache/thrift.git", "authors": [ "Apache Thrift " ], "description": "Apache Thrift", "main": "lib/js/src/thrift.js", "keywords": [ "thrift" ], "license": "Apache v2", "ignore": [] } thrift-0.23.0/.travis.yml0000664000175000017500000001332315165535636015510 0ustar00buildbuild00000000000000# # 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. # # build Apache Thrift on Travis CI - https://travis-ci.com/ # # Docker Integration # see: build/docker/README.md # sudo: required # https://docs.travis-ci.com/user/reference/linux dist: focal language: cpp services: - docker install: # https://docs.travis-ci.com/user/common-build-problems/#build-times-out-because-no-output-was-received # adding `travis_wait` because kerl building in the docker file takes >10 min for building erlang # without printing to stdout, resulting in build failures - if [[ `uname` == "Linux" ]]; then travis_wait 40 build/docker/refresh.sh; fi stages: - docker # docker images - thrift # thrift build jobs env: global: - SCRIPT="cmake.sh" - BUILD_ARG="" - BUILD_ENV="-e CC=gcc -e CXX=g++ -e THRIFT_CROSSTEST_CONCURRENCY=4" - 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) - DOCKER_REPO="thrift/thrift-build" # DOCKER_USER (provide in your Travis settings if you want to build and update docker images once, instead of on every job) # DOCKER_PASS (same) jobs: include: # ========================= stage: docker ========================= - script: true env: - JOB="Docker Build ubuntu-focal 20.04 LTS" - DISTRO=ubuntu-focal - TRAVIS_BUILD_STAGE=docker - script: true env: - JOB="Docker Build ubuntu-jammy 22.04 LTS" - DISTRO=ubuntu-jammy - TRAVIS_BUILD_STAGE=docker - script: true env: - JOB="Docker Build ubuntu-noble 24.04 LTS" - DISTRO=ubuntu-noble - TRAVIS_BUILD_STAGE=docker # ========================= stage: thrift ======================= # ------------------------- phase: cross ------------------------ - stage: thrift script: build/docker/run.sh env: - JOB="Cross Language Tests (Binary Protocol)" - SCRIPT="cross-test.sh" - BUILD_ARG="-'(binary)'" - stage: thrift script: build/docker/run.sh env: - JOB="Cross Language Tests (Header, JSON Protocols)" - SCRIPT="cross-test.sh" - BUILD_ARG="-'(header|json)'" - stage: thrift script: build/docker/run.sh env: - JOB="Cross Language Tests (Compact and Multiplexed Protocols)" - SCRIPT="cross-test.sh" - BUILD_ARG="-'(compact|multiplexed)'" # ------------------------- phase: sca -------------------------- # QA jobs for code analytics and metrics - stage: thrift script: build/docker/run.sh env: - JOB="Static Code Analysis" - SCRIPT="sca.sh" # C and C++ undefined behavior. # A binary crashes if undefined behavior occurs and produces a stack trace. # python is disabled, see: THRIFT-4360 - script: build/docker/run.sh env: - JOB="UBSan" - SCRIPT="ubsan.sh" - BUILD_ARG="--without-python --without-py3" # ------------------------- phase: autotools -------------------- # TODO: Remove them once migrated to CMake # TODO fix the missing python2 deps or get rid of python2 # - script: build/docker/run.sh # env: # - JOB="Autotools (Ubuntu Jammy)" # - DISTRO=ubuntu-jammy # - SCRIPT="autotools.sh" - script: build/docker/run.sh env: - JOB="Autotools (Ubuntu Focal)" - DISTRO=ubuntu-focal - SCRIPT="autotools.sh" # ------------------------- phase: cmake ------------------------ - script: build/docker/run.sh env: - JOB="CMake" - BUILD_ARG="-DCMAKE_BUILD_TYPE=Debug" - script: build/docker/run.sh env: - JOB="CMake" - BUILD_ARG="-DCMAKE_BUILD_TYPE=Release" # ------------------------- phase: dist ------------------------- - script: build/docker/run.sh env: - JOB="make dist" - SCRIPT="make-dist.sh" - script: build/docker/run.sh env: - JOB="Debian Packages" - SCRIPT="dpkg.sh" # ------------------------- phase: coverity --------------------- # We build the coverity scan build once monthly using a travis cron job - if: (env(COVERITY_SCAN_NOTIFICATION_EMAIL) IS present) AND (branch IN (master)) AND (type IN (cron)) script: build/docker/run.sh env: - JOB="Coverity Scan" - SCRIPT="covscan.sh" # ------------------------- phase: swift ------------------------ # We lint the podspec - os: osx osx_image: xcode11.3 language: swift script: - gem update cocoapods - pod lib lint --allow-warnings --swift-version=5.1 env: - JOB="pod lib lint" ### ------------------------- phase: osx -------------------------- # disabled due to the time delays it imposes on build jobs # - os: osx # osx_image: xcode9 # script: build/docker/scripts/autotools.sh thrift-0.23.0/config.sub0000755000175000017500000010511615166015674015356 0ustar00buildbuild00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ | linux-musl* | linux-relibc* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; vxworks-simlinux | vxworks-simwindows | vxworks-spe) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: thrift-0.23.0/build/0000775000175000017500000000000015167543515014471 5ustar00buildbuild00000000000000thrift-0.23.0/build/appveyor/0000775000175000017500000000000015167543515016336 5ustar00buildbuild00000000000000thrift-0.23.0/build/appveyor/MSYS-appveyor-full.bat0000664000175000017500000000532215165535636022431 0ustar00buildbuild00000000000000:: :: 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. :: :: :: Appveyor script for MSYS :: :: :: Installs third party packages we need for a cmake build :: @ECHO ON SETLOCAL EnableDelayedExpansion CD build\appveyor || EXIT /B SET APPVEYOR_SCRIPTS=%APPVEYOR_BUILD_FOLDER%\build\appveyor SET BUILDDIR=%APPVEYOR_BUILD_FOLDER%\..\build\%PROFILE%\%PLATFORM% SET INSTDIR=%APPVEYOR_BUILD_FOLDER%\..\install\%PROFILE%\%PLATFORM% SET SRCDIR=%APPVEYOR_BUILD_FOLDER% ECHO Unsupported PROFILE=%PROFILE% or PLATFORM=%PLATFORM% EXIT /B 1 SET BASH=C:\msys64\usr\bin\bash SET CMAKE=/c/msys64/mingw64/bin/cmake.exe CALL win_showenv.bat || EXIT /B SET PACKAGES=^ base-devel ^ mingw-w64-x86_64-toolchain ^ bison ^ flex ^ make ^ mingw-w64-x86_64-cmake ^ mingw-w64-x86_64-libevent ^ mingw-w64-x86_64-openssl ^ mingw-w64-x86_64-zlib :: Upgrade things %BASH% -lc "pacman --noconfirm -Syu %IGNORE%" || EXIT /B %BASH% -lc "pacman --noconfirm -Syu %IGNORE%" || EXIT /B %BASH% -lc "pacman --noconfirm --needed -S %PACKAGES%" || EXIT /B :: :: Configure and build our software with cmake :: SET CMAKEARGS=^ -G'%GENERATOR%' ^ -DBoost_DEBUG=ON ^ -DBoost_NAMESPACE=libboost ^ -DBOOST_INCLUDEDIR=%BOOST_INCLUDEDIR% ^ -DBOOST_LIBRARYDIR=%BOOST_LIBRARYDIR% ^ -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^ -DCMAKE_C_COMPILER=gcc.exe ^ -DCMAKE_CXX_COMPILER=g++.exe ^ -DCMAKE_MAKE_PROGRAM=make.exe ^ -DCMAKE_INSTALL_PREFIX=%INSTDIR_MSYS% ^ -DLIBEVENT_ROOT=%LIBEVENT_ROOT% ^ -DOPENSSL_LIBRARIES=%OPENSSL_LIBRARIES% ^ -DOPENSSL_ROOT_DIR=%OPENSSL_ROOT% ^ -DOPENSSL_USE_STATIC_LIBS=ON ^ -DWITH_BOOST_STATIC=ON ^ -DWITH_JAVA=OFF ^ -DWITH_LIBEVENT=ON ^ -DWITH_PYTHON=%WITH_PYTHON% ^ -DWITH_SHARED_LIB=OFF ^ -DWITH_STATIC_LIB=ON %BASH% -lc "mkdir %BUILDDIR% && cd %BUILDDIR% && %CMAKE% %SRCDIR_MSYS% %CMAKEARGS% && %CMAKE% --build . --config %CONFIGURATION% && %CMAKE% --install . --config %CONFIGURATION%" || EXIT /B :: :: Execute our tests :: :: This test randomly fails on mingw; see Jira THRIFT-4106 SET DISABLED_TESTS=(concurrency_test) SET DISABLED_TESTS_COMMAND=--exclude-regex '%DISABLED_TESTS%' %BASH% -lc "cd %BUILDDIR% && ctest.exe --build-config %CONFIGURATION% --timeout 300 --extra-verbose %DISABLED_TESTS_COMMAND%" || EXIT /B thrift-0.23.0/build/appveyor/build-zlib.bat0000664000175000017500000000320615165535636021067 0ustar00buildbuild00000000000000:: :: 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. :: SETLOCAL EnableDelayedExpansion SET PACKAGE=zlib-%ZLIB_VERSION% SET BUILDDIR=%WIN3P%\zlib-build SET INSTDIR=%WIN3P%\zlib-inst SET SRCDIR=%WIN3P%\%PACKAGE% SET URLFILE=%PACKAGE%.tar.gz :: This allows us to tolerate when the current version is archived SET URL=http://zlib.net/%URLFILE% SET FURL=http://zlib.net/fossils/%URLFILE% :: Download - support running a local build or a build in appveyor CD "%WIN3P%" || EXIT /B IF "%APPVEYOR_BUILD_ID%" == "" ( curl -L -f -o "%URLFILE%" "%URL%" IF ERRORLEVEL 1 ( curl -L -f -o "%URLFILE%" "%FURL%" ) ) ELSE ( appveyor DownloadFile "%URL%" IF ERRORLEVEL 1 ( appveyor DownloadFile "%FURL%" || EXIT /B ) ) 7z x "%URLFILE%" -so | 7z x -si -ttar > nul || EXIT /B :: Generate MKDIR "%BUILDDIR%" || EXIT /B CD "%BUILDDIR%" || EXIT /B cmake "%SRCDIR%" ^ -G"NMake Makefiles" ^ -DCMAKE_INSTALL_PREFIX="%INSTDIR%" ^ -DCMAKE_BUILD_TYPE="%CONFIGURATION%" || EXIT /B :: Build nmake /fMakefile install || EXIT /B IF "%CONFIGURATION%" == "Debug" ( COPY "%BUILDDIR%\zlibd.pdb" "%INSTDIR%\bin\" || EXIT /B ) ENDLOCAL thrift-0.23.0/build/appveyor/win_showenv.bat0000664000175000017500000000465415165535636021410 0ustar00buildbuild00000000000000:: :: 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. :: ECHO/ ECHO =============================================================================== IF "%PROFILE_CLASS%" == "MSVC" ( ECHO Versions ECHO ------------------------------------------------------------------------------- ECHO boost = %BOOST_VERSION% ECHO libevent = %LIBEVENT_VERSION% ECHO python = %PYTHON_VERSION% ECHO qt = %QT_VERSION% ECHO zlib = %ZLIB_VERSION% ECHO/ ) ECHO Appveyor Variables ECHO ------------------------------------------------------------------------------- ECHO APPVEYOR_BUILD_FOLDER = %APPVEYOR_BUILD_FOLDER% ECHO CONFIGURATION = %CONFIGURATION% ECHO PLATFORM = %PLATFORM% ECHO PROFILE = %PROFILE% ECHO/ ECHO Our Variables ECHO ------------------------------------------------------------------------------- ECHO APPVEYOR_SCRIPTS = %APPVEYOR_SCRIPTS% ECHO BASH = %BASH% ECHO BOOST_ROOT = %BOOST_ROOT% ECHO BOOST_INCLUDEDIR = %BOOST_INCLUDEDIR% ECHO BOOST_LIBRARYDIR = %BOOST_LIBRARYDIR% ECHO BUILDDIR = %BUILDDIR% ECHO COMPILER = %COMPILER% ECHO GENERATOR = %GENERATOR% ECHO INSTDIR = %INSTDIR% ECHO JAVA_HOME = %JAVA_HOME% ECHO OPENSSL_ROOT = %OPENSSL_ROOT% ECHO SETUP = %SETUP% ECHO SRCDIR = %SRCDIR% ECHO WIN3P = %WIN3P% ECHO WITH_PYTHON = %WITH_PYTHON% ECHO ZLIB_STATIC_SUFFIX = %ZLIB_STATIC_SUFFIX% IF NOT "%PROFILE_CLASS%" == "MSVC" ( ECHO/ ECHO UNIXy PATH ECHO ------------------------------------------------------------------------------- %BASH% -lc "echo $PATH" ) ECHO/ ECHO Windows PATH ECHO ------------------------------------------------------------------------------- ECHO %PATH% ECHO =============================================================================== ECHO/ thrift-0.23.0/build/appveyor/CYGWIN-appveyor-full.bat0000664000175000017500000000516715165535636022645 0ustar00buildbuild00000000000000:: :: 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. :: :: :: Appveyor script for CYGWIN :: :: :: Installs third party packages we need for a cmake build :: @ECHO ON SETLOCAL EnableDelayedExpansion CD build\appveyor || EXIT /B SET APPVEYOR_SCRIPTS=%APPVEYOR_BUILD_FOLDER%\build\appveyor SET BUILDDIR=%APPVEYOR_BUILD_FOLDER%\..\build\%PROFILE%\%PLATFORM% SET INSTDIR=%APPVEYOR_BUILD_FOLDER%\..\install\%PROFILE%\%PLATFORM% SET SRCDIR=%APPVEYOR_BUILD_FOLDER% :: compiler and generator detection SET COMPILER=gcc SET GENERATOR=Unix Makefiles IF "%PLATFORM%" == "x64" ( SET CYGWINROOT=C:\cygwin64 ) ELSE ( SET CYGWINROOT=C:\cygwin ) IF "%PLATFORM%" == "x64" ( SET SETUP=!CYGWINROOT!\setup-x86_64.exe ) ELSE ( SET SETUP=!CYGWINROOT!\setup-x86.exe ) SET BASH=!CYGWINROOT!\bin\bash.exe SET BUILDDIR=%BUILDDIR:\=/% SET BUILDDIR=/cygdrive/c!BUILDDIR:~2! SET INSTDIR=%INSTDIR:\=/% SET INSTDIR=/cygdrive/c!INSTDIR:~2! SET SRCDIR=%SRCDIR:\=/% SET SRCDIR=/cygdrive/c!SRCDIR:~2! CALL win_showenv.bat || EXIT /B :: :: Install apt-cyg for package management because its easier to use :: than Cygwins setup.exe. But both are possible to use. :: %BASH% -lc "wget https://rawgit.com/transcode-open/apt-cyg/master/apt-cyg && install apt-cyg /bin && rm -f apt-cyg" || EXIT /B %BASH% -lc "apt-cyg update" || EXIT /B %BASH% -lc "apt-cyg install unzip xz cmake make bison flex gcc-g++ libboost-devel libevent-devel openssl-devel zlib-devel" || EXIT /B :: :: Configure and build our software with cmake :: SET CMAKEARGS=^ -G'%GENERATOR%' ^ -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^ -DCMAKE_INSTALL_PREFIX=%INSTDIR% ^ -DCMAKE_CXX_FLAGS="-D_GNU_SOURCE" ^ -DWITH_JAVA=OFF ^ -DWITH_PYTHON=OFF :: -DCMAKE_CXX_EXTENSIONS=ON ^ :: -DCMAKE_CXX_STANDARD=11 ^ %BASH% -lc "mkdir -p %BUILDDIR% && cd %BUILDDIR% && cmake.exe %SRCDIR% %CMAKEARGS% && cmake --build . --config %CONFIGURATION% && cmake --install . --config %CONFIGURATION%" || EXIT /B :: :: Execute our tests :: SET DISABLED_TESTS_COMMAND=--exclude-regex '%DISABLED_TESTS%' %BASH% -lc "cd %BUILDDIR% && ctest.exe --build-config %CONFIGURATION% --timeout 300 --extra-verbose %DISABLED_TESTS_COMMAND%" || EXIT /B thrift-0.23.0/build/appveyor/MSVC-appveyor-full.bat0000664000175000017500000001604315167543515022405 0ustar00buildbuild00000000000000:: :: 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. :: :: :: Appveyor script for MSVC :: :: :: Installs (or builds) third party packages we need :: @ECHO ON SETLOCAL EnableDelayedExpansion CD build\appveyor || EXIT /B SET APPVEYOR_SCRIPTS=%APPVEYOR_BUILD_FOLDER%\build\appveyor SET BUILDDIR=%APPVEYOR_BUILD_FOLDER%\..\build\%PROFILE%\%PLATFORM% SET INSTDIR=%APPVEYOR_BUILD_FOLDER%\..\install\%PROFILE%\%PLATFORM% SET SRCDIR=%APPVEYOR_BUILD_FOLDER% IF "%PROFILE%" == "MSVC2017" ( IF "%PLATFORM%" == "x86" ( CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" || EXIT /B ) ELSE ( CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" || EXIT /B ) ) ELSE IF "%PROFILE%" == "MSVC2019" ( IF "%PLATFORM%" == "x86" ( CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat" || EXIT /B ) ELSE ( CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" || EXIT /B ) ) ELSE IF "%PROFILE%" == "MSVC2022" ( IF "%PLATFORM%" == "x86" ( CALL "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat" || EXIT /B ) ELSE ( CALL "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" || EXIT /B ) ) ELSE ( ECHO Unsupported PROFILE=%PROFILE% or PLATFORM=%PLATFORM% EXIT /B 1 ) :: Put back the @ECHO since vcvars*.bat above disables it @ECHO ON :: compiler and generator detection :: VS2017 uses "Generator Win64" syntax, VS2019+ use "-A x64" flag IF /i "%PLATFORM%" == "x64" ( SET GENARCH= Win64 SET CMAKE_ARCH_FLAG=-A x64 ) ELSE ( SET GENARCH= SET CMAKE_ARCH_FLAG=-A Win32 ) IF "%PROFILE%" == "MSVC2017" ( SET GENERATOR=Visual Studio 15 2017!GENARCH! SET COMPILER=vc141 SET CMAKE_ARCH_FLAG= ) ELSE IF "%PROFILE%" == "MSVC2019" ( SET GENERATOR=Visual Studio 16 2019 SET COMPILER=vc142 ) ELSE IF "%PROFILE%" == "MSVC2022" ( SET GENERATOR=Visual Studio 17 2022 SET COMPILER=vc143 ) ELSE ( ECHO [error] unable to determine the CMake generator and compiler to use from MSVC profile %PROFILE% EXIT /B 1 ) :: PLATFORM is x86 or x64 :: NORM_PLATFORM is 32 or 64 IF "%PLATFORM%" == "x86" ( SET NORM_PLATFORM=32 ) ELSE ( SET NORM_PLATFORM=64 ) :: FindBoost needs forward slashes so cmake doesn't see something as an escaped character SET BOOST_ROOT=C:/Libraries/boost_%BOOST_VERSION:.=_% SET BOOST_LIBRARYDIR=!BOOST_ROOT!/lib%NORM_PLATFORM%-msvc-%COMPILER:~-3,2%.%COMPILER:~-1,1% SET OPENSSL_ROOT=C:\OpenSSL-Win%NORM_PLATFORM% SET WIN3P=%APPVEYOR_BUILD_FOLDER%\thirdparty IF "%PYTHON_VERSION%" == "" ( SET WITH_PYTHON=OFF SET CMAKE_PYTHON_OPTS="" ) ELSE ( SET WITH_PYTHON=ON IF /i "%PLATFORM%" == "x64" (SET PTEXT=-x64) SET PYTHON_ROOT=C:\Python%PYTHON_VERSION:.=%!PTEXT! SET PATH=!PYTHON_ROOT!\scripts;!PYTHON_ROOT!;!PATH! SET CMAKE_PYTHON_OPTS=-DPython3_FIND_STRATEGY=LOCATION -DPython3_ROOT=!PYTHON_ROOT! -DPython3_EXECUTABLE=!PYTHON_ROOT!\python.exe ) IF "%CONFIGURATION%" == "Debug" (SET ZLIB_LIB_SUFFIX=d) IF NOT "%QT_VERSION%" == "" ( IF /i "%PLATFORM%" == "x64" (SET QTEXT=_64) SET PATH=C:\Qt\%QT_VERSION%\%PROFILE%!QTEXT!\bin;!PATH! ) @ECHO OFF CALL win_showenv.bat || EXIT /B MKDIR "%WIN3P%" || EXIT /B @ECHO ON choco feature enable -n allowGlobalConfirmation || EXIT /B :: Things to install when NOT running in appveyor: IF "%APPVEYOR_BUILD_ID%" == "" ( choco upgrade -y chocolatey || EXIT /B choco install -y curl || EXIT /B choco install -y 7zip || EXIT /B choco install -y python3 || EXIT /B choco install -y openssl.light || EXIT /B ) choco install -y jdk8 || EXIT /B choco install -y winflexbison3 || EXIT /B :: zlib - not available through chocolatey CD "%APPVEYOR_SCRIPTS%" || EXIT /B call build-zlib.bat || EXIT /B :: libevent - not available through chocolatey CD "%APPVEYOR_SCRIPTS%" || EXIT /B call build-libevent.bat || EXIT /B :: python packages (ensure we use the configured Python) IF "%WITH_PYTHON%" == "ON" ( "!PYTHON_ROOT!\python.exe" -m ensurepip --upgrade || EXIT /B "!PYTHON_ROOT!\python.exe" -m pip install --upgrade pip setuptools wheel || EXIT /B "!PYTHON_ROOT!\python.exe" -m pip ^ install backports.ssl_match_hostname ^ ipaddress ^ tornado>=6.3.0 ^ twisted>=24.3.0 ^ zope.interface>=6.1 || EXIT /B ) :: Adobe Flex SDK 4.6 for ActionScript MKDIR "C:\Adobe\Flex\SDK\4.6" || 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" :: :: Configure and build our software with cmake :: MKDIR "%BUILDDIR%" || EXIT /B CD "%BUILDDIR%" || EXIT /B :: When libraries cannot be found, things might have been updated :: so uncomment this and submit a pull request to see what's there :: now... :: DIR C:\Libraries :: DIR C:\Libraries\boost_1_69_0\lib* :: DIR C:\Libraries\boost_1_68_0\lib* :: DIR C:\Libraries\boost_1_67_0\lib* :: DIR C:\Libraries\boost_1_66_0\lib* :: DIR C:\Libraries\boost_1_65_0\lib* :: DIR C:\Libraries\boost_1_64_0\lib* :: DIR C:\Libraries\boost_1_63_0\lib* :: DIR C:\Libraries\boost_1_62_0\lib* :: DIR C:\Libraries\boost_1_61_0\lib* :: DIR C:\Libraries\boost_1_60_0\lib* cmake.exe "%SRCDIR%" ^ -G"%GENERATOR%" %CMAKE_ARCH_FLAG% ^ -DBISON_EXECUTABLE="C:\ProgramData\chocolatey\lib\winflexbison3\tools\win_bison.exe" ^ -DBOOST_ROOT="%BOOST_ROOT%" ^ -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" ^ -DBUILD_SHARED_LIBS="%BUILD_SHARED_LIBS%" ^ -DCMAKE_BUILD_TYPE="%CONFIGURATION%" ^ -DCMAKE_INSTALL_PREFIX="%INSTDIR%" ^ -DFLEX_EXECUTABLE="C:\ProgramData\chocolatey\lib\winflexbison3\tools\win_flex.exe" ^ -DLIBEVENT_ROOT="%WIN3P%\libevent-%LIBEVENT_VERSION%-stable" ^ -DOPENSSL_ROOT_DIR="%OPENSSL_ROOT%" ^ -DOPENSSL_USE_STATIC_LIBS=OFF ^ -DZLIB_LIBRARY="%WIN3P%\zlib-inst\lib\zlib%ZLIB_LIB_SUFFIX%.lib" ^ -DZLIB_ROOT="%WIN3P%\zlib-inst" ^ -DWITH_PYTHON=%WITH_PYTHON% %CMAKE_PYTHON_OPTS% || EXIT /B cmake.exe --build . --config "%CONFIGURATION%" || EXIT /B cmake.exe --install . --config "%CONFIGURATION%" || EXIT /B :: :: Execute our tests :: :: Add directories to the path to find DLLs of third party libraries so tests run properly! SET PATH=%BOOST_LIBRARYDIR:/=\%;%OPENSSL_ROOT%\bin;%WIN3P%\zlib-inst\bin;%PATH% SET DISABLED_TESTS_COMMAND=--exclude-regex '%DISABLED_TESTS%' ctest.exe --build-config %CONFIGURATION% --timeout 300 --extra-verbose %DISABLED_TESTS_COMMAND% || EXIT /B thrift-0.23.0/build/appveyor/MINGW-appveyor-full.bat0000664000175000017500000000776015165535636022527 0ustar00buildbuild00000000000000:: :: 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. :: :: :: Appveyor script for MINGW on MSYS2 :: :: :: Installs third party packages we need for a cmake build :: @ECHO ON SETLOCAL EnableDelayedExpansion CD build\appveyor || EXIT /B SET APPVEYOR_SCRIPTS=%APPVEYOR_BUILD_FOLDER%\build\appveyor SET BUILDDIR=%APPVEYOR_BUILD_FOLDER%\..\build\%PROFILE%\%PLATFORM% SET INSTDIR=%APPVEYOR_BUILD_FOLDER%\..\install\%PROFILE%\%PLATFORM% SET SRCDIR=%APPVEYOR_BUILD_FOLDER% :: PLATFORM is x86 or x64 :: NORM_PLATFORM is 32 or 64 IF "%PLATFORM%" == "x86" ( SET NORM_PLATFORM=32 ) ELSE ( SET NORM_PLATFORM=64 ) :: PLATFORM = x86 means MINGWPLAT i686 :: PLATFORM = x64 means MINGWPLAT x86_64 IF "%PLATFORM%" == "x86" ( SET MINGWPLAT=i686 ) ELSE ( SET MINGWPLAT=x86_64 ) :: compiler and generator detection SET COMPILER=gcc SET GENERATOR=MinGW Makefiles SET BASH=C:\msys64\usr\bin\bash.exe !BASH! -lc "sed -i '/export PATH=\/mingw32\/bin/d' ~/.bash_profile && sed -i '/export PATH=\/mingw64\/bin/d' ~/.bash_profile && echo 'export PATH=/mingw%NORM_PLATFORM%/bin:$PATH' >> ~/.bash_profile" || EXIT /B SET BUILDDIR=%BUILDDIR:\=/% SET BUILDDIR=/c!BUILDDIR:~2! SET INSTDIR=%INSTDIR:\=/% SET INSTDIR=/c!INSTDIR:~2! SET SRCDIR=%SRCDIR:\=/% SET SRCDIR=/c!SRCDIR:~2! CALL win_showenv.bat || EXIT /B SET PACKAGES=^ base-devel ^ mingw-w64-x86_64-toolchain ^ bison ^ flex ^ make ^ mingw-w64-%MINGWPLAT%-boost ^ mingw-w64-%MINGWPLAT%-cmake ^ mingw-w64-%MINGWPLAT%-libevent ^ mingw-w64-%MINGWPLAT%-openssl ^ mingw-w64-%MINGWPLAT%-toolchain ^ mingw-w64-%MINGWPLAT%-zlib ::mingw-w64-%MINGWPLAT%-qt5 : WAY too large (1GB download!) - tested in cygwin builds anyway :: Upgrade things %BASH% -lc "pacman --noconfirm -Syu %IGNORE%" || EXIT /B %BASH% -lc "pacman --noconfirm -Syu %IGNORE%" || EXIT /B %BASH% -lc "pacman --noconfirm --needed -S %PACKAGES%" || EXIT /B :: These instructions are for a manual update of specific package versions. :: Fall back to this in case the above does not work anymore (broken upstream). :::: Updata the new key ::%BASH% -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-1~20210213-2-any.pkg.tar.xz" || EXIT /B ::%BASH% -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-1~20210213-2-any.pkg.tar.xz.sig" || EXIT /B ::%BASH% -lc "pacman-key --verify msys2-keyring-1~20210213-2-any.pkg.tar.xz.sig" || EXIT /B ::%BASH% -lc "pacman --noconfirm -U --config <(echo) msys2-keyring-1~20210213-2-any.pkg.tar.xz" || EXIT /B :::: Upgrade things ::%BASH% -lc "pacman --noconfirm -Sy" || EXIT /B ::%BASH% -lc "pacman --noconfirm -Udd https://repo.msys2.org/msys/x86_64/pacman-5.2.2-5-x86_64.pkg.tar.xz" || EXIT /B ::%BASH% -lc "pacman --noconfirm --needed -S %PACKAGES%" || EXIT /B :: :: Configure and build our software with cmake :: SET CMAKEARGS=^ -G'%GENERATOR%' ^ -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^ -DCMAKE_INSTALL_PREFIX=%INSTDIR% ^ -DCMAKE_MAKE_PROGRAM=/mingw%NORM_PLATFORM%/bin/mingw32-make ^ -DCMAKE_C_COMPILER=/mingw%NORM_PLATFORM%/bin/gcc.exe ^ -DCMAKE_CXX_COMPILER=/mingw%NORM_PLATFORM%/bin/g++.exe ^ -DOPENSSL_ROOT_DIR=/mingw%NORM_PLATFORM% ^ -DWITH_PYTHON=OFF %BASH% -lc "mkdir -p %BUILDDIR% && cd %BUILDDIR% && cmake.exe %SRCDIR% %CMAKEARGS% && cmake --build . --config %CONFIGURATION% && cmake --install . --config %CONFIGURATION%" || EXIT /B :: :: Execute our tests :: SET DISABLED_TESTS_COMMAND=--exclude-regex '%DISABLED_TESTS%' %BASH% -lc "cd %BUILDDIR% && ctest.exe --build-config %CONFIGURATION% --timeout 300 --extra-verbose %DISABLED_TESTS_COMMAND%" || EXIT /B thrift-0.23.0/build/appveyor/README.md0000664000175000017500000000160515165535636017622 0ustar00buildbuild00000000000000 # AppVeyor Build AppVeyor is capable of building MSVC as well as MSYS2, MinGW and Cygwin builds targeting the MS Windows platform. It has many versions of boost and python installed as well. See what appveyor has [installed on build workers](https://www.appveyor.com/docs/installed-software/). We run a matrix build on AppVeyor. See appveyor.yml for more details. thrift-0.23.0/build/appveyor/simulate-appveyor.bat0000664000175000017500000000166115165535636022523 0ustar00buildbuild00000000000000:: :: 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. :: :: :: Helps build thrift by pretending to be appveyor :: Usage: :: cd build\appveyor :: simulate-appveyor.bat [Debug|Release] [x86|x64] [CYGWIN|MINGW|MSVC201?] :: SETLOCAL EnableDelayedExpansion SET APPVEYOR_BUILD_FOLDER=%~dp0..\.. SET CONFIGURATION=%1 SET PLATFORM=%2 SET PROFILE=%3 CD %APPVEYOR_BUILD_FOLDER% CALL build\appveyor\%PROFILE_CLASS%-appveyor-full.bat || EXIT /B thrift-0.23.0/build/appveyor/build-libevent.bat0000664000175000017500000000406015167543515021733 0ustar00buildbuild00000000000000:: :: 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. :: SETLOCAL EnableDelayedExpansion SET URLFILE=libevent-%LIBEVENT_VERSION%-stable.tar.gz SET URL=https://github.com/libevent/libevent/releases/download/release-%LIBEVENT_VERSION%-stable/%URLFILE% :: Download - support running a local build or a build in appveyor CD "%WIN3P%" || EXIT /B IF "%APPVEYOR_BUILD_ID%" == "" ( curl -L -f -o "%URLFILE%" "%URL%" ) ELSE ( appveyor DownloadFile "%URL%" ) 7z x "%URLFILE%" -so | 7z x -si -ttar > nul || EXIT /B CD "libevent-%LIBEVENT_VERSION%-stable" || EXIT /B :: libevent's nmake config ships with EVENT__HAVE_STDINT_H commented out, :: but MSVC needs stdint.h for UINT32_MAX in minheap-internal.h. IF EXIST "WIN32-Code\nmake\event2\event-config.h" ( powershell -NoProfile -Command "(Get-Content 'WIN32-Code\nmake\event2\event-config.h') -replace '/\* #define EVENT__HAVE_STDINT_H 1 \*/', '#define EVENT__HAVE_STDINT_H 1' | Set-Content 'WIN32-Code\nmake\event2\event-config.h'" ) ELSE IF EXIST "WIN32-Code\event2\event-config.h" ( powershell -NoProfile -Command "(Get-Content 'WIN32-Code\event2\event-config.h') -replace '/\* #define EVENT__HAVE_STDINT_H 1 \*/', '#define EVENT__HAVE_STDINT_H 1' | Set-Content 'WIN32-Code\event2\event-config.h'" ) nmake -f Makefile.nmake static_libs || EXIT /B :: in libevent 2.0 there is no nmake subdirectory in WIN32-Code, but in 2.1 there is mkdir lib || EXIT /B move *.lib lib\ || EXIT /B move WIN32-Code\event2\* include\event2\ || move WIN32-Code\nmake\event2\* include\event2\ || EXIT /B move *.h include\ || EXIT /B ENDLOCAL thrift-0.23.0/build/cmake/0000775000175000017500000000000015167543515015551 5ustar00buildbuild00000000000000thrift-0.23.0/build/cmake/FindLibevent.cmake0000664000175000017500000000275515165535636021140 0ustar00buildbuild00000000000000# find LibEvent # an event notification library (http://libevent.org/) # # Usage: # LIBEVENT_INCLUDE_DIRS, where to find LibEvent headers # LIBEVENT_LIBRARIES, LibEvent libraries # Libevent_FOUND, If false, do not try to use libevent set(LIBEVENT_ROOT CACHE PATH "Root directory of libevent installation") set(LibEvent_EXTRA_PREFIXES /usr/local /opt/local "$ENV{HOME}" ${LIBEVENT_ROOT}) foreach(prefix ${LibEvent_EXTRA_PREFIXES}) list(APPEND LibEvent_INCLUDE_PATHS "${prefix}/include") list(APPEND LibEvent_LIBRARIES_PATHS "${prefix}/lib") endforeach() # Looking for "event.h" will find the Platform SDK include dir on windows # so we also look for a peer header like evhttp.h to get the right path find_path(LIBEVENT_INCLUDE_DIRS evhttp.h event.h PATHS ${LibEvent_INCLUDE_PATHS}) # "lib" prefix is needed on Windows in some cases # newer versions of libevent use three libraries find_library(LIBEVENT_LIBRARIES NAMES event event_core event_extra libevent PATHS ${LibEvent_LIBRARIES_PATHS}) if (LIBEVENT_LIBRARIES AND LIBEVENT_INCLUDE_DIRS) set(Libevent_FOUND TRUE) set(LIBEVENT_LIBRARIES ${LIBEVENT_LIBRARIES}) else () set(Libevent_FOUND FALSE) endif () if (Libevent_FOUND) if (NOT Libevent_FIND_QUIETLY) message(STATUS "Found libevent: ${LIBEVENT_LIBRARIES}") endif () else () if (LibEvent_FIND_REQUIRED) message(FATAL_ERROR "Could NOT find libevent.") endif () message(STATUS "libevent NOT found.") endif () mark_as_advanced( LIBEVENT_LIBRARIES LIBEVENT_INCLUDE_DIRS ) thrift-0.23.0/build/cmake/BoostMacros.cmake0000664000175000017500000000430015167543515021003 0ustar00buildbuild00000000000000# # 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. # # CMake 4.0+ removed the FindBoost module (CMP0167). Use OLD behavior to # preserve compatibility with existing ${Boost_LIBRARIES} usage. if(POLICY CMP0167) cmake_policy(SET CMP0167 OLD) endif() # CMake 3.27+ warns and ignores upper-case _ROOT variables unless # CMP0144 is set. We pass BOOST_ROOT on Windows builds, so enable NEW behavior. if(POLICY CMP0144) cmake_policy(SET CMP0144 NEW) endif() # Force using FindBoost instead of Boost's own BoostConfig.cmake. # BoostConfig.cmake does not populate ${Boost_LIBRARIES} the same way, # which causes linking failures on Windows. set(Boost_NO_BOOST_CMAKE ON) set(BOOST_MINREV 1.56) macro(REQUIRE_BOOST_HEADERS) find_package(Boost ${BOOST_MINREV} QUIET REQUIRED) if (NOT Boost_FOUND) message(FATAL_ERROR "Boost ${BOOST_MINREV} or later is required to build sources in ${CMAKE_CURRENT_SOURCE_DIR}") endif() if (DEFINED Boost_INCLUDE_DIRS) # pre-boost 1.70.0 aware cmake, otherwise it is using targets include_directories(SYSTEM "${Boost_INCLUDE_DIRS}") endif() endmacro() macro(REQUIRE_BOOST_LIBRARIES libs) message(STATUS "Locating boost libraries required by sources in ${CMAKE_CURRENT_SOURCE_DIR}") find_package(Boost ${BOOST_MINREV} REQUIRED COMPONENTS ${${libs}}) if (NOT Boost_FOUND) message(FATAL_ERROR "Boost ${BOOST_MINREV} or later is required to build sources in ${CMAKE_CURRENT_SOURCE_DIR}, or use -DBUILD_TESTING=OFF") endif() endmacro() thrift-0.23.0/build/cmake/ConfigureChecks.cmake0000664000175000017500000000641415165535636021625 0ustar00buildbuild00000000000000# # 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(CheckFunctionExists) include(CheckIncludeFile) include(CheckIncludeFiles) include(CheckSymbolExists) include(CheckStructHasMember) include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) if (Inttypes_FOUND) # This allows the inttypes.h and stdint.h checks to succeed on platforms that # do not natively provide there. set (CMAKE_REQUIRED_INCLUDES ${INTTYPES_INCLUDE_DIRS}) endif () check_include_file(arpa/inet.h HAVE_ARPA_INET_H) check_include_file(fcntl.h HAVE_FCNTL_H) check_include_file(getopt.h HAVE_GETOPT_H) check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(netdb.h HAVE_NETDB_H) check_include_file(netinet/in.h HAVE_NETINET_IN_H) check_include_file(signal.h HAVE_SIGNAL_H) check_include_file(stdint.h HAVE_STDINT_H) check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(pthread.h HAVE_PTHREAD_H) check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H) check_include_file(sys/param.h HAVE_SYS_PARAM_H) check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H) check_include_file(sys/socket.h HAVE_SYS_SOCKET_H) check_include_file(sys/stat.h HAVE_SYS_STAT_H) check_include_file(sys/time.h HAVE_SYS_TIME_H) check_include_file(sys/un.h HAVE_SYS_UN_H) check_include_file(poll.h HAVE_POLL_H) check_include_file(sys/poll.h HAVE_SYS_POLL_H) check_include_file(sys/select.h HAVE_SYS_SELECT_H) check_include_file(sched.h HAVE_SCHED_H) check_include_file(string.h HAVE_STRING_H) check_include_file(strings.h HAVE_STRINGS_H) # Check for afunix.h on Windows (since Windows 10 Insider Build 17063): check_cxx_source_compiles( " #define WIN32_LEAN_AND_MEAN #include #include #include int main(){(void)sizeof(((struct sockaddr_un *)0)->sun_path); return 0;} " HAVE_AF_UNIX_H) check_function_exists(gethostbyname HAVE_GETHOSTBYNAME) check_function_exists(gethostbyname_r HAVE_GETHOSTBYNAME_R) check_function_exists(strerror_r HAVE_STRERROR_R) check_function_exists(sched_get_priority_max HAVE_SCHED_GET_PRIORITY_MAX) check_function_exists(sched_get_priority_min HAVE_SCHED_GET_PRIORITY_MIN) check_cxx_source_compiles( " #include int main(){char b;char *a = strerror_r(0, &b, 0); static_cast(a); return(0);} " STRERROR_R_CHAR_P) set(PACKAGE ${PACKAGE_NAME}) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(VERSION ${thrift_VERSION}) # generate a config.h file configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/thrift/config.h") include_directories("${CMAKE_CURRENT_BINARY_DIR}") thrift-0.23.0/build/cmake/FindGLIB.cmake0000664000175000017500000001256215165535636020102 0ustar00buildbuild00000000000000# - Try to find Glib and its components (gio, gobject etc) # Once done, this will define # # GLIB_FOUND - system has Glib # GLIB_INCLUDE_DIRS - the Glib include directories # GLIB_LIBRARIES - link these to use Glib # # Optionally, the COMPONENTS keyword can be passed to find_package() # and Glib components can be looked for. Currently, the following # components can be used, and they define the following variables if # found: # # gio: GLIB_GIO_LIBRARIES # gobject: GLIB_GOBJECT_LIBRARIES # gmodule: GLIB_GMODULE_LIBRARIES # gthread: GLIB_GTHREAD_LIBRARIES # # Note that the respective _INCLUDE_DIR variables are not set, since # all headers are in the same directory as GLIB_INCLUDE_DIRS. # # Copyright (C) 2012 Raphael Kubo da Costa # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS # IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. find_package(PkgConfig) pkg_check_modules(PC_GLIB QUIET glib-2.0) find_library(GLIB_LIBRARIES NAMES glib-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS} ) # Files in glib's main include path may include glibconfig.h, which, # for some odd reason, is normally in $LIBDIR/glib-2.0/include. get_filename_component(_GLIB_LIBRARY_DIR ${GLIB_LIBRARIES} PATH) find_path(GLIBCONFIG_INCLUDE_DIR NAMES glibconfig.h HINTS ${PC_LIBDIR} ${PC_LIBRARY_DIRS} ${_GLIB_LIBRARY_DIR} ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0/include ) find_path(GLIB_INCLUDE_DIR NAMES glib.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0 ) set(GLIB_INCLUDE_DIRS ${GLIB_INCLUDE_DIR} ${GLIBCONFIG_INCLUDE_DIR}) if(GLIBCONFIG_INCLUDE_DIR) # Version detection file(READ "${GLIBCONFIG_INCLUDE_DIR}/glibconfig.h" GLIBCONFIG_H_CONTENTS) string(REGEX MATCH "#define GLIB_MAJOR_VERSION ([0-9]+)" _dummy "${GLIBCONFIG_H_CONTENTS}") set(GLIB_VERSION_MAJOR "${CMAKE_MATCH_1}") string(REGEX MATCH "#define GLIB_MINOR_VERSION ([0-9]+)" _dummy "${GLIBCONFIG_H_CONTENTS}") set(GLIB_VERSION_MINOR "${CMAKE_MATCH_1}") string(REGEX MATCH "#define GLIB_MICRO_VERSION ([0-9]+)" _dummy "${GLIBCONFIG_H_CONTENTS}") set(GLIB_VERSION_MICRO "${CMAKE_MATCH_1}") set(GLIB_VERSION "${GLIB_VERSION_MAJOR}.${GLIB_VERSION_MINOR}.${GLIB_VERSION_MICRO}") endif() # Additional Glib components. We only look for libraries, as not all of them # have corresponding headers and all headers are installed alongside the main # glib ones. foreach (_component ${GLIB_FIND_COMPONENTS}) if (${_component} STREQUAL "gio") find_library(GLIB_GIO_LIBRARIES NAMES gio-2.0 HINTS ${_GLIB_LIBRARY_DIR}) set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GIO_LIBRARIES) elseif (${_component} STREQUAL "gobject") find_library(GLIB_GOBJECT_LIBRARIES NAMES gobject-2.0 HINTS ${_GLIB_LIBRARY_DIR}) set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GOBJECT_LIBRARIES) elseif (${_component} STREQUAL "gmodule") find_library(GLIB_GMODULE_LIBRARIES NAMES gmodule-2.0 HINTS ${_GLIB_LIBRARY_DIR}) set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GMODULE_LIBRARIES) elseif (${_component} STREQUAL "gthread") find_library(GLIB_GTHREAD_LIBRARIES NAMES gthread-2.0 HINTS ${_GLIB_LIBRARY_DIR}) set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GTHREAD_LIBRARIES) elseif (${_component} STREQUAL "gio-unix") # gio-unix is compiled as part of the gio library, but the include paths # are separate from the shared glib ones. Since this is currently only used # by WebKitGTK+ we don't go to extraordinary measures beyond pkg-config. pkg_check_modules(GIO_UNIX QUIET gio-unix-2.0) endif () endforeach () include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLIB REQUIRED_VARS GLIB_INCLUDE_DIRS GLIB_LIBRARIES ${ADDITIONAL_REQUIRED_VARS} VERSION_VAR GLIB_VERSION) mark_as_advanced( GLIBCONFIG_INCLUDE_DIR GLIB_GIO_LIBRARIES GLIB_GIO_UNIX_LIBRARIES GLIB_GMODULE_LIBRARIES GLIB_GOBJECT_LIBRARIES GLIB_GTHREAD_LIBRARIES GLIB_INCLUDE_DIR GLIB_INCLUDE_DIRS GLIB_LIBRARIES ) thrift-0.23.0/build/cmake/FindAnt.cmake0000664000175000017500000000214615165535636020104 0ustar00buildbuild00000000000000# # 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. # # ANT_FOUND - system has Ant # Ant_EXECUTABLE - the Ant executable # # It will search the environment variable ANT_HOME if it is set include(FindPackageHandleStandardArgs) find_program(Ant_EXECUTABLE NAMES ant PATHS $ENV{ANT_HOME}/bin) find_package_handle_standard_args(Ant DEFAULT_MSG Ant_EXECUTABLE) mark_as_advanced(Ant_EXECUTABLE) thrift-0.23.0/build/cmake/ThriftConfig.cmake.in0000664000175000017500000000544115167543515021552 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # set(THRIFT_VERSION @thrift_VERSION@) @PACKAGE_INIT@ set_and_check(THRIFT_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) include("${THRIFT_CMAKE_DIR}/thriftTargets.cmake") endif() set(THRIFT_LIBRARIES thrift::thrift) if(@ZLIB_FOUND@ AND @WITH_ZLIB@) if (NOT TARGET thriftz::thriftz) include("${THRIFT_CMAKE_DIR}/thriftzTargets.cmake") endif() 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(@Libevent_FOUND@ AND @WITH_LIBEVENT@) if (NOT TARGET thriftnb::thriftnb) include("${THRIFT_CMAKE_DIR}/thriftnbTargets.cmake") endif() set(THRIFT_LIBRARIES thriftnb::thriftnb) endif() if ("${THRIFT_LIBRARIES}" STREQUAL "") message(FATAL_ERROR "thrift libraries were not found") endif() if (NOT Thrift_FIND_QUIETLY) message(STATUS "Found thrift: ${PACKAGE_PREFIX_DIR}") endif() include(CMakeFindDependencyMacro) if(@ZLIB_FOUND@ AND @WITH_ZLIB@) find_dependency(ZLIB) endif() if(@OPENSSL_FOUND@ AND @WITH_OPENSSL@) find_dependency(OpenSSL) endif() if(@Libevent_FOUND@ AND @WITH_LIBEVENT@) if(DEFINED CMAKE_MODULE_PATH) set(THRIFT_CMAKE_MODULE_PATH_OLD ${CMAKE_MODULE_PATH}) else() unset(THRIFT_CMAKE_MODULE_PATH_OLD) endif() set(CMAKE_MODULE_PATH "${THRIFT_CMAKE_DIR}") find_dependency(Libevent) if(DEFINED THRIFT_CMAKE_MODULE_PATH_OLD) set(CMAKE_MODULE_PATH ${THRIFT_CMAKE_MODULE_PATH_OLD}) unset(THRIFT_CMAKE_MODULE_PATH_OLD) else() unset(CMAKE_MODULE_PATH) endif() endif() check_required_components(Thrift) thrift-0.23.0/build/cmake/config.h.in0000664000175000017500000001201115165535636017572 0ustar00buildbuild00000000000000/* * 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. */ /* config.h generated by CMake from config.h.in */ #ifndef CONFIG_H #define CONFIG_H /* Name of package */ #cmakedefine PACKAGE "${PACKAGE}" /* Define to the address where bug reports for this package should be sent. */ #cmakedefine PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}" /* Define to the full name of this package. */ #cmakedefine PACKAGE_NAME "${PACKAGE_NAME}" /* Define to the one symbol short name of this package. */ #cmakedefine PACKAGE_TARNAME "${PACKAGE_TARNAME}" /* Define to the home page for this package. */ #cmakedefine PACKAGE_URL "${PACKAGE_URL}" /* Define to the version of this package. */ #define PACKAGE_VERSION "${PACKAGE_VERSION}" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "${PACKAGE_STRING}" /************************** DEFINES *************************/ /* Define if the AI_ADDRCONFIG symbol is unavailable */ #cmakedefine AI_ADDRCONFIG 0 /* Possible value for SIGNED_RIGHT_SHIFT_IS */ /* TODO: This is just set to 1 for the moment port the macro aclocal/ax_signed_right_shift.m4 to CMake to make this work */ #define ARITHMETIC_RIGHT_SHIFT 1 /* Indicates the effect of the right shift operator on negative signed integers */ /* TODO: This is just set to 1 for the moment */ #define SIGNED_RIGHT_SHIFT_IS 1 /* Use *.h extension for parser header file */ /* TODO: This might now be necessary anymore as it is set only for automake < 1.11 see: aclocal/ac_prog_bison.m4 */ #cmakedefine BISON_USE_PARSER_H_EXTENSION 1 /* Define to 1 if strerror_r returns char *. */ #cmakedefine STRERROR_R_CHAR_P 1 /************************** HEADER FILES *************************/ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_FCNTL_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SIGNAL_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_PTHREAD_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_RESOURCE_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_UN_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_POLL_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_POLL_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SCHED_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_AF_UNIX_H 1 /*************************** FUNCTIONS ***************************/ /* Define to 1 if you have the `gethostbyname' function. */ #cmakedefine HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the `gethostbyname_r' function. */ #cmakedefine HAVE_GETHOSTBYNAME_R 1 /* Define to 1 if you have the `strerror_r' function. */ #cmakedefine HAVE_STRERROR_R 1 /* Define to 1 if you have the `sched_get_priority_max' function. */ #cmakedefine HAVE_SCHED_GET_PRIORITY_MAX 1 /* Define to 1 if you have the `sched_get_priority_min' function. */ #cmakedefine HAVE_SCHED_GET_PRIORITY_MIN 1 /* Define to 1 if strerror_r returns char *. */ #cmakedefine STRERROR_R_CHAR_P 1 #endif thrift-0.23.0/build/cmake/CPackConfig.cmake0000664000175000017500000000502515165535636020667 0ustar00buildbuild00000000000000# # 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. # #TODO: Should we bundle system libraries for DLLs? #include(InstallRequiredSystemLibraries) # For help take a look at: # http://www.cmake.org/Wiki/CMake:CPackConfiguration ### general settings set(CPACK_PACKAGE_NAME "thrift") set(CPACK_PACKAGE_VERSION "${PACKAGE_VERSION}") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Apache Thrift") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_VENDOR "Apache Software Foundation") set(CPACK_PACKAGE_CONTACT "dev@thrift.apache.org") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}") ### versions set(CPACK_PACKAGE_VERSION_MAJOR ${thrift_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${thrift_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${thrift_VERSION_PATCH}) ### source generator set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") ### zip generator set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_INSTALL_DIRECTORY "thrift") if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set(CPACK_GENERATOR "NSIS") set(CPACK_NSIS_HELP_LINK "http://thrift.apache.org") set(CPACK_NSIS_MENU_LINKS "http://thrift.apache.org" "Apache Thrift - Web Site" "https://issues.apache.org/jira/browse/THRIFT" "Apache Thrift - Issues") set(CPACK_NSIS_CONTACT ${CPACK_PACKAGE_CONTACT}) set(CPACK_NSIS_MODIFY_PATH "ON") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") else() set(CPACK_GENERATOR "DEB" ) set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${CPACK_PACKAGE_CONTACT}) endif() include(CPack) thrift-0.23.0/build/cmake/GenerateConfigModule.cmake0000664000175000017500000000342315165535636022606 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # include(CMakePackageConfigHelpers) # 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 INCLUDE_INSTALL_DIR CMAKE_INSTALL_DIR BIN_INSTALL_DIR ) write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/ThriftConfigVersion.cmake" VERSION ${thrift_VERSION_MAJOR}.${thrift_VERSION_MINOR}.${thrift_VERSION_PATCH} COMPATIBILITY SameMajorVersion ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ThriftConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/ThriftConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_DIR}/thrift") if(WITH_LIBEVENT) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/FindLibevent.cmake" DESTINATION "${CMAKE_INSTALL_DIR}/thrift") endif() endif() thrift-0.23.0/build/cmake/StaticCodeAnalysis.cmake0000664000175000017500000000065415165535636022311 0ustar00buildbuild00000000000000find_package(ClangTools QUIET) if(clang-tidy_FOUND AND run-clang-tidy_FOUND AND NOT TARGET do_run_clang_tidy) add_custom_target( do_run_clang_tidy COMMAND ClangTools::run-clang-tidy -clang-tidy-binary "$" -p ${CMAKE_BINARY_DIR} "-quiet" > ./run-clang-tidy.txt DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) endif() thrift-0.23.0/build/cmake/FindClangTools.cmake0000664000175000017500000000242115165535636021423 0ustar00buildbuild00000000000000# - Try to find Clang tools # # The following are set after configuration is done: # clang-tidy_FOUND # ClangTools::clang-tidy # clang-apply-replacements_FOUND # ClangTools::clang-apply-replacements # run-clang-tidy_FOUND # ClangTools::run-clang-tidy include_guard() include(FindPackageHandleStandardArgs) foreach(program_name IN ITEMS clang-tidy clang-apply-replacements) find_program(${program_name}_BINARY NAMES ${program_name}-devel ${program_name}-8 ${program_name} PATH_SUFFIXES "LLVM/bin") find_package_handle_standard_args(${program_name} DEFAULT_MSG ${program_name}_BINARY) if(${program_name}_FOUND AND NOT TARGET ClangTools::${program_name}) add_executable(ClangTools::${program_name} IMPORTED) set_property(TARGET ClangTools::${program_name} PROPERTY IMPORTED_LOCATION "${${program_name}_BINARY}") endif() endforeach() find_program(run-clang-tidy_BINARY NAMES run-clang-tidy run-clang-tidy.py PATH_SUFFIXES "LLVM/bin" "llvm-devel/share/clang") find_package_handle_standard_args(run-clang-tidy DEFAULT_MSG run-clang-tidy_BINARY) if(run-clang-tidy_FOUND AND NOT TARGET ClangTools::run-clang-tidy) add_executable(ClangTools::run-clang-tidy IMPORTED) set_property(TARGET ClangTools::run-clang-tidy PROPERTY IMPORTED_LOCATION "${run-clang-tidy_BINARY}") endif() thrift-0.23.0/build/cmake/README-MSYS2.md0000664000175000017500000000472315165535636017714 0ustar00buildbuild00000000000000 # Building thrift on Windows (MinGW64/MSYS2) Thrift uses cmake to make it easier to build the project on multiple platforms, however to build a fully functional and production ready thrift on Windows requires a number of third party libraries to be obtained. Once third party libraries are ready, the right combination of options must be passed to cmake in order to generate the correct environment. > Note: libevent and libevent-devel do not work with this toolchain as they do not properly detect mingw64 and expect some headers to exist that do not, so the non-blocking server is not currently built into this solution. ## MSYS2 Download and fully upgrade msys2 following the instructions at: https://msys2.github.io/ Install the necessary toolchain items for C++: $ pacman --needed -S bison flex make mingw-w64-x86_64-openssl \ mingw-w64-x86_64-boost mingw-w64-x86_64-cmake \ mingw-w64-x86_64-toolchain mingw-w64-x86_64-zlib Update your msys2 bash path to include /mingw64/bin by adding a line to your ~/.bash_profiles using this command: echo "export PATH=/mingw64/bin:\$PATH" >> ~/.bash_profile After that, close your shell and open a new one. Use cmake to create a MinGW makefile, out of tree (assumes you are in the top level of the thrift source tree): mkdir ../thrift-build cd ../thrift-build cmake -G"MinGW Makefiles" -DCMAKE_MAKE_PROGRAM=/mingw64/bin/mingw32-make \ -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc.exe \ -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++.exe \ -DWITH_LIBEVENT=OFF \ -DWITH_SHARED_LIB=OFF -DWITH_STATIC_LIB=ON \ -DWITH_JAVA=OFF -DWITH_PYTHON=OFF -DWITH_PERL=OFF \ ../thrift Build thrift (inside thrift-build): cmake --build . Run the tests (inside thrift-build): ctest > If you run into issues, check Apache Jira THRIFT-4046 for patches relating to MinGW64/MSYS2 builds. ## Tested With msys2 64-bit 2016-10-26 distribution thrift-0.23.0/build/cmake/FindInttypes.cmake0000664000175000017500000000254315165535636021202 0ustar00buildbuild00000000000000# # 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. # # find msinttypes on compilers that don't provide it, for example # VS2010 # Usage: # Provide INTTYPES_ROOT if you need it # Result: INTTYPES_INCLUDE_DIRS, where to find inttypes.h # Result: Inttypes_FOUND, If false, inttypes.h was not found find_path(INTTYPES_INCLUDE_DIRS inttypes.h HINTS ${INTTYPES_ROOT}) if (INTTYPES_INCLUDE_DIRS) set(Inttypes_FOUND TRUE) else () set(Inttypes_FOUND FALSE) if (Inttypes_FIND_REQUIRED) message(FATAL_ERROR "Could NOT find inttypes.h") endif () message(STATUS "inttypes.h NOT found") endif () mark_as_advanced( INTTYPES_INCLUDE_DIRS ) thrift-0.23.0/build/cmake/DefineCMakeDefaults.cmake0000664000175000017500000000651615165535636022351 0ustar00buildbuild00000000000000# # 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. # # Always include srcdir and builddir in include path # This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in # about every subdir # since cmake 2.4.0 set(CMAKE_INCLUDE_CURRENT_DIR ON) # Put the include dirs which are in the source or build tree # before all other include dirs, so the headers in the sources # are preferred over the already installed ones # since cmake 2.4.1 set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) # Use colored output # since cmake 2.4.0 set(CMAKE_COLOR_MAKEFILE ON) # Create the compile command database for clang by default set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Set the CMAKE_BUILD_TYPE if it is not already defined include(BuildType) # Put the libraries and binaries that get built into directories at the # top of the build tree rather than in hard-to-find leaf # directories. This simplifies manual testing and the use of the build # tree rather than installed thrift libraries. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) # # "rpath" support. # See http://www.itk.org/Wiki/index.php?title=CMake_RPATH_handling # # On MacOSX, for shared libraries, enable rpath support. set(CMAKE_MACOSX_RPATH TRUE) # # On any OS, for executables, allow linking with shared libraries in non-system # locations and running the executables without LD_PRELOAD or similar. # This requires the library to be built with rpath support. set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # # C++ Language Level Defaults - this depends on the compiler capabilities # if (NOT DEFINED CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 11) # C++11 message(STATUS "Setting C++11 as the default language level.") message(STATUS "To specify a different C++ language level, set CMAKE_CXX_STANDARD") endif() if (CMAKE_CXX_STANDARD EQUAL 98) message(FATAL_ERROR "only C++11 or above C++ standard is supported") elseif (CMAKE_CXX_STANDARD EQUAL 11) # should not fallback to C++98 set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() if (NOT DEFINED CMAKE_CXX_EXTENSIONS) set(CMAKE_CXX_EXTENSIONS OFF) # use standards compliant language level for portability endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") include(CheckCXXCompilerFlag) set(CMAKE_REQUIRED_QUIET ON) check_cxx_compiler_flag("/Zc:__cplusplus" res_var) if (res_var) # Make MSVC reporting correct value for __cplusplus # See https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/ add_compile_options("/Zc:__cplusplus") endif() endif() thrift-0.23.0/build/cmake/ThriftMacros.cmake0000664000175000017500000000371615165535636021172 0ustar00buildbuild00000000000000# # 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. # macro(ADD_PKGCONFIG_THRIFT name) configure_file("${name}.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc" DESTINATION "${PKGCONFIG_INSTALL_DIR}") endmacro(ADD_PKGCONFIG_THRIFT) macro(ADD_LIBRARY_THRIFT name) add_library(${name} ${ARGN}) target_include_directories(${name} INTERFACE $) set_target_properties(${name} PROPERTIES OUTPUT_NAME ${name}${THRIFT_RUNTIME_POSTFIX} # windows link variants (/MT, /MD, /MTd, /MDd) get different names VERSION ${thrift_VERSION}) # set_target_properties(${name} PROPERTIES PUBLIC_HEADER "${thriftcpp_HEADERS}") install(TARGETS ${name} EXPORT "${name}Targets" RUNTIME DESTINATION "${BIN_INSTALL_DIR}" LIBRARY DESTINATION "${LIB_INSTALL_DIR}" ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" PUBLIC_HEADER DESTINATION "${INCLUDE_INSTALL_DIR}") export(EXPORT "${name}Targets" FILE "${CMAKE_CURRENT_BINARY_DIR}/${name}/${name}Targets.cmake" NAMESPACE "${name}::") install(EXPORT "${name}Targets" FILE "${name}Targets.cmake" NAMESPACE "${name}::" DESTINATION "${CMAKE_INSTALL_DIR}/thrift") endmacro()thrift-0.23.0/build/cmake/FindGradle.cmake0000664000175000017500000000223715165535636020561 0ustar00buildbuild00000000000000# # 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. # # GRADLE_FOUND - system has Gradle # GRADLE_EXECUTABLE - the Gradle executable # # It will search the environment variable GRADLE_HOME if it is set include(FindPackageHandleStandardArgs) find_program(GRADLE_EXECUTABLE NAMES gradle PATHS $ENV{GRADLE_HOME}/bin NO_CMAKE_FIND_ROOT_PATH) find_package_handle_standard_args(Gradle DEFAULT_MSG GRADLE_EXECUTABLE) mark_as_advanced(GRADLE_EXECUTABLE) thrift-0.23.0/build/cmake/DefineInstallationPaths.cmake0000664000175000017500000000364515165535636023342 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Define the default install paths set(BIN_INSTALL_DIR "bin" CACHE PATH "The binary install dir (default: bin)") # 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})") endif() set(INCLUDE_INSTALL_DIR "include" CACHE PATH "The library install dir (default: include)") set(CMAKE_INSTALL_DIR "lib/cmake" CACHE PATH "The subdirectory to install cmake config files (default: cmake)") set(PKGCONFIG_INSTALL_DIR "lib/pkgconfig" CACHE PATH "The subdirectory to install pkgconfig config files (default: lib/pkgconfig)") set(DOC_INSTALL_DIR "share/doc" CACHE PATH "The subdirectory to install documentation files (default: share/doc)") set(prefix "${CMAKE_INSTALL_PREFIX}") set(exec_prefix "${CMAKE_INSTALL_PREFIX}/bin") set(libdir "${CMAKE_INSTALL_PREFIX}/lib") set(includedir "${CMAKE_INSTALL_PREFIX}/include") set(cmakedir "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DIR}") thrift-0.23.0/build/cmake/BuildType.cmake0000664000175000017500000000271415165535636020463 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # originally from: # https://raw.githubusercontent.com/OpenChemistry/tomviz/master/cmake/BuildType.cmake # Set a default build type if none was specified set(default_build_type "RelWithDebInfo") if(EXISTS "${CMAKE_SOURCE_DIR}/.git") set(default_build_type "Debug") endif() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to '${default_build_type}' as none was specified.") set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() thrift-0.23.0/build/cmake/mingw32-toolchain.cmake0000664000175000017500000000153115165535636022022 0ustar00buildbuild00000000000000# CMake mingw32 cross compile toolchain file # the name of the target operating system SET(CMAKE_SYSTEM_NAME Windows) # which compilers to use for C and C++ SET(CMAKE_C_COMPILER i586-mingw32msvc-gcc) SET(CMAKE_CXX_COMPILER i586-mingw32msvc-g++) SET(CMAKE_RC_COMPILER i586-mingw32msvc-windres) # here is the target environment located SET(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(BUILD_SHARED_LIBS OFF) SET(CMAKE_EXE_LINKER_FLAGS "-static") set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-static-libgcc") set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-static-libstdc++") thrift-0.23.0/build/cmake/android-toolchain.cmake0000664000175000017500000000201315165535636022150 0ustar00buildbuild00000000000000set(ANDROID_NDK "/opt/android-ndk" CACHE) set(ANDROID_PLATFORM "android-15" CACHE) set(ANDROID_ARCH "arch-arm" CACHE) set(ANDROID_TOOL_ARCH "android-arm" CACHE) set(ANDROID_CPU "armeabi-v7a" CACHE) set(ANDROID_GCC_VERSION 4.9 CACHE) set(HOST_ARCH linux-x86_64 CACHE) set(CMAKE_SYSTEM_NAME Android) set(ANDROID_SYSROOT "${ANDROID_NDK}/platforms/${ANDROID_PLATFORM}/${ANDROID_ARCH}") set(ANDROID_TRIPLET arm-linux-androideabi) set(ANDROID_STL "${ANDROID_NDK}/sources/cxx-stl/gnu-libstd++/${ANDROID_GCC_VERSION}") set(_COMPILER_ROOT ${ANDROID_NDK}/prebuilt/${ANDROID_TRIPLET}-${ANDROID_GCC_VERSION}/prebuilt/${HOST_ARCH}) set(CMAKE_C_COMPILER ${_COMPILER_ROOT}/bin/${ANDROID_TRIPLET}-gcc) set(CMAKE_CXCX_COMPILER ${_COMPILER_ROOT}/bin/${ANDROID_TRIPLET}-g++) include_directories( ${ANDROID_STL}/include ${ANDROID_STL}/libs/${ANDROID_CPU}/include) set(CMAKE_FIND_ROOT_PATH ${ANDROID_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) thrift-0.23.0/build/cmake/uninstall.cmake0000664000175000017500000000275015165535636020573 0ustar00buildbuild00000000000000# # 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. # cmake_minimum_required(VERSION 3.4) set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt") if(NOT EXISTS ${MANIFEST}) message(FATAL_ERROR "Cannot find install mainfest: ${MANIFEST}") endif() file(STRINGS ${MANIFEST} files) foreach(file ${files}) if(EXISTS ${file} OR IS_SYMLINK ${file}) message(STATUS "Removing: ${file}") execute_process( COMMAND ${CMAKE_COMMAND} -E remove ${file} RESULT_VARIABLE result OUTPUT_QUIET ERROR_VARIABLE stderr ERROR_STRIP_TRAILING_WHITESPACE ) if(NOT ${result} EQUAL 0) message(FATAL_ERROR "${stderr}") endif() else() message(STATUS "Does-not-exist: ${file}") endif() endforeach(file) thrift-0.23.0/build/cmake/README.md0000664000175000017500000000363515165535636017042 0ustar00buildbuild00000000000000# Apache Thrift - CMake Build ## Goal Extend Apache Thrift's *make cross* approach to the build system. Due to growing the field of operating system support, a proper executable and library detection mechanism running on as much platforms as possible becomes required. The other aspect to simplify the release process and package generation process. As nice side benefit of CMake is the generation of development environment specific soultion files. => No solution files within source tree. ## Prerequisites These are language-specific, however for C++ you must provide: - Boost - OpenSSL You may optionally provide: - libevent - zlib ## Usage To use CMake you first create an out-of-tree build directory, then use CMake to generate a build framework, then build: mkdir /tmp/build cd /tmp/build cmake /location/to/thrift if you use a specific toolchain pass it to cmake, the same for options: cmake -DCMAKE_TOOLCHAIN_FILE=../build/cmake/mingw32-toolchain.cmake .. cmake -DCMAKE_C_COMPILER=clang-3.5 -DCMAKE_CXX_COMPILER=clang++-3.5 .. cmake -DTHRIFT_COMPILER_HS=OFF .. cmake -DWITH_ZLIB=ON .. and open the development environment you like with the solution or do this: make make check make cross make dist or on Windows, the following will produce a solution file you can use inside Visual Studio: cmake -G "Visual Studio 15 2017 Win64" \ -DBOOST_ROOT=C:/3rdparty/boost_1_69_0 \ -DBOOST_LIBRARYDIR=C:/3rdparty/boost_1_69_0/lib64-msvc-14.1^ -DZLIB_ROOT=C:/3rdparty/zlib-1.2.11 ## TODO * git hash or tag based versioning depending on source state * build tutorial * build test * enable/disable * make cross * make dist (create an alias to make package_source) * make doc * cpack (C++ and make dist only ?) * thrift-compiler * libthrift * tutorial * test * merge into /README.mdthrift-0.23.0/build/cmake/DefineOptions.cmake0000664000175000017500000002205615167543515021326 0ustar00buildbuild00000000000000# # 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(CMakeDependentOption) set(THRIFT_COMPILER "" CACHE FILEPATH "External Thrift compiler to use during build") # Additional components option(BUILD_COMPILER "Build Thrift compiler" ON) if(BUILD_COMPILER OR EXISTS ${THRIFT_COMPILER}) set(HAVE_COMPILER ON) endif() CMAKE_DEPENDENT_OPTION(BUILD_TESTING "Build with unit tests" ON "HAVE_COMPILER" OFF) CMAKE_DEPENDENT_OPTION(BUILD_TUTORIALS "Build Thrift tutorials" ON "HAVE_COMPILER" OFF) option(BUILD_LIBRARIES "Build Thrift libraries" ON) # Libraries to build # Each language library can be enabled or disabled using the WITH_ flag. # By default CMake checks if the required dependencies for a language are present # and enables the library if all are found. This means the default is to build as # much as possible but leaving out libraries if their dependencies are not met. if (NOT Boost_USE_STATIC_LIBS) add_definitions(-DBOOST_ALL_DYN_LINK) add_definitions(-DBOOST_TEST_DYN_LINK) endif() # as3 option(WITH_AS3 "Build ActionScript 3 Thrift Library" ON) if (WITH_AS3) set(POSSIBLE_PATHS "${FLEX_HOME}/bin" "$ENV{FLEX_HOME}/bin") find_program(HAVE_COMPC NAMES compc HINTS ${POSSIBLE_PATHS}) endif () CMAKE_DEPENDENT_OPTION(BUILD_AS3 "Build as3 library" ON "BUILD_LIBRARIES;WITH_AS3;HAVE_COMPC" OFF) # C++ option(WITH_CPP "Build C++ Thrift library" ON) if(WITH_CPP) # NOTE: Currently the following options are C++ specific, # but in future other libraries might reuse them. # So they are not dependent on WITH_CPP but setting them without WITH_CPP currently # has no effect. if(ZLIB_LIBRARY) # FindZLIB.cmake does not normalize path so we need to do it ourselves. file(TO_CMAKE_PATH ${ZLIB_LIBRARY} ZLIB_LIBRARY) endif() find_package(ZLIB QUIET) CMAKE_DEPENDENT_OPTION(WITH_ZLIB "Build with ZLIB support" ON "ZLIB_FOUND" OFF) find_package(Libevent QUIET) CMAKE_DEPENDENT_OPTION(WITH_LIBEVENT "Build with libevent support" ON "Libevent_FOUND" OFF) find_package(Qt5 QUIET COMPONENTS Core Network) CMAKE_DEPENDENT_OPTION(WITH_QT5 "Build with Qt5 support" ON "Qt5_FOUND" OFF) endif() CMAKE_DEPENDENT_OPTION(BUILD_CPP "Build C++ library" ON "BUILD_LIBRARIES;WITH_CPP" OFF) # C GLib option(WITH_C_GLIB "Build C (GLib) Thrift library" ON) if(WITH_C_GLIB) find_package(GLIB QUIET COMPONENTS gobject) endif() CMAKE_DEPENDENT_OPTION(BUILD_C_GLIB "Build C (GLib) library" ON "BUILD_LIBRARIES;WITH_C_GLIB;GLIB_FOUND" OFF) # OpenSSL if(WITH_CPP OR WITH_C_GLIB) find_package(OpenSSL) CMAKE_DEPENDENT_OPTION(WITH_OPENSSL "Build with OpenSSL support" ON "OPENSSL_FOUND" OFF) endif() # Java option(WITH_JAVA "Build Java Thrift library" ON) if(ANDROID) find_package(Gradle QUIET) CMAKE_DEPENDENT_OPTION(BUILD_JAVA "Build Java library" ON "BUILD_LIBRARIES;WITH_JAVA;GRADLE_FOUND" OFF) else() find_package(Gradle QUIET) find_package(Java QUIET) CMAKE_DEPENDENT_OPTION(BUILD_JAVA "Build Java library" ON "BUILD_LIBRARIES;WITH_JAVA;JAVA_FOUND;GRADLE_FOUND" OFF) endif() # Javascript option(WITH_JAVASCRIPT "Build Javascript Thrift library" ON) CMAKE_DEPENDENT_OPTION(BUILD_JAVASCRIPT "Build Javascript library" ON "BUILD_LIBRARIES;WITH_JAVASCRIPT;NOT WIN32; NOT CYGWIN" OFF) # NodeJS option(WITH_NODEJS "Build NodeJS Thrift library" ON) CMAKE_DEPENDENT_OPTION(BUILD_NODEJS "Build NodeJS library" ON "BUILD_LIBRARIES;WITH_NODEJS" OFF) # Python option(WITH_PYTHON "Build Python Thrift library" ON) find_package(Python3 COMPONENTS Interpreter # for Python executable Development # for Python.h ) CMAKE_DEPENDENT_OPTION(BUILD_PYTHON "Build Python library" ON "BUILD_LIBRARIES;WITH_PYTHON;Python3_Interpreter_FOUND;Python3_Development_FOUND" OFF) # Common library options # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html # Default on Windows is static, shared mode library support needs work... if(WIN32) set(DEFAULT_BUILD_SHARED_LIBS ON) else() set(DEFAULT_BUILD_SHARED_LIBS OFF) endif() option(BUILD_SHARED_LIBS "Build shared libraries" ${DEFAULT_BUILD_SHARED_LIBS}) if (WITH_SHARED_LIB) message(WARNING "WITH_SHARED_LIB is deprecated; use -DBUILD_SHARED_LIBS=ON instead") set(BUILD_SHARED_LIBS ON) elseif (WITH_STATIC_LIB) if (WITH_SHARED_LIB) message(FATAL_ERROR "Cannot build shared and static together; set BUILD_SHARED_LIBS instead.") endif () message(WARNING "WITH_STATIC_LIB is deprecated; use -DBUILD_SHARED_LIBS=OFF instead") set(BUILD_SHARED_LIBS OFF) endif () # Visual Studio only options if(MSVC) option(WITH_MT "Build using the static runtime 'MT' instead of the shared DLL-specific runtime 'MD' (MSVC only)" OFF) endif(MSVC) macro(MESSAGE_DEP flag summary) if(NOT ${flag}) message(STATUS " - ${summary}") endif() endmacro(MESSAGE_DEP flag summary) macro(PRINT_CONFIG_SUMMARY) message(STATUS "----------------------------------------------------------") message(STATUS "Thrift version: ${thrift_VERSION} (${thrift_VERSION_MAJOR}.${thrift_VERSION_MINOR}.${thrift_VERSION_PATCH})") message(STATUS "Thrift package version: ${PACKAGE_VERSION}") message(STATUS) message(STATUS "Build configuration summary") message(STATUS " Build compiler: ${BUILD_COMPILER}") message(STATUS " Build libraries: ${BUILD_LIBRARIES}") message(STATUS " Build tests: ${BUILD_TESTING}") MESSAGE_DEP(HAVE_COMPILER "Disabled because BUILD_COMPILER=OFF and no valid THRIFT_COMPILER is given") message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") message(STATUS) message(STATUS "Language libraries:") message(STATUS) message(STATUS " Build as3 library: ${BUILD_AS3}") MESSAGE_DEP(WITH_AS3 "Disabled by WITH_AS3=OFF") MESSAGE_DEP(HAVE_COMPC "Adobe Flex compc was not found - did you set env var FLEX_HOME?") message(STATUS) message(STATUS " Build with OpenSSL: ${WITH_OPENSSL}") if(WITH_OPENSSL) message(STATUS " Version: ${OPENSSL_VERSION}") endif() message(STATUS) message(STATUS " Build C++ library: ${BUILD_CPP}") MESSAGE_DEP(WITH_CPP "Disabled by WITH_CPP=OFF") if (BUILD_CPP) message(STATUS " C++ Language Level: ${CXX_LANGUAGE_LEVEL}") message(STATUS " Build shared libraries: ${BUILD_SHARED_LIBS}") message(STATUS " Build with libevent support: ${WITH_LIBEVENT}") message(STATUS " Build with Qt5 support: ${WITH_QT5}") message(STATUS " Build with ZLIB support: ${WITH_ZLIB}") endif () message(STATUS) message(STATUS " Build C (GLib) library: ${BUILD_C_GLIB}") MESSAGE_DEP(WITH_C_GLIB "Disabled by WITH_C_GLIB=OFF") MESSAGE_DEP(GLIB_FOUND "GLib missing") message(STATUS) message(STATUS " Build Java library: ${BUILD_JAVA}") MESSAGE_DEP(WITH_JAVA "Disabled by WITH_JAVA=OFF") if(ANDROID) MESSAGE_DEP(GRADLE_FOUND "Gradle missing") else() MESSAGE_DEP(JAVA_FOUND "Java Runtime missing") MESSAGE_DEP(GRADLE_FOUND "Gradle missing") endif() message(STATUS " Build Javascript library: ${BUILD_JAVASCRIPT}") MESSAGE_DEP(WITH_JAVASCRIPT "Disabled by WITH_JAVASCRIPT=OFF") message(STATUS " Build NodeJS library: ${BUILD_NODEJS}") MESSAGE_DEP(WITH_NODEJS "Disabled by WITH_NODEJS=OFF") message(STATUS) message(STATUS " Build Python library: ${BUILD_PYTHON}") MESSAGE_DEP(WITH_PYTHON "Disabled by WITH_PYTHON=OFF") MESSAGE_DEP(Python3_Interpreter_FOUND "Python interpreter missing") MESSAGE_DEP(Python3_Development_FOUND "Python libraries missing") if(BUILD_PYTHON) message(STATUS " Version: ${Python3_VERSION}") endif() if(MSVC) message(STATUS " Using static runtime library: ${WITH_MT}") endif(MSVC) message(STATUS) message(STATUS) message(STATUS "----------------------------------------------------------") endmacro(PRINT_CONFIG_SUMMARY) thrift-0.23.0/build/cmake/NewPlatformDebug.cmake0000664000175000017500000000254015165535636021764 0ustar00buildbuild00000000000000# # 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. # # # For debugging new platforms, just to see what some environment flags are... # macro(SHOWFLAG flag) message(STATUS "${flag} = ${${flag}}") endmacro(SHOWFLAG) set(NEWPLATFORMDEBUG ON) if(NEWPLATFORMDEBUG) SHOWFLAG("APPLE") SHOWFLAG("BORLAND") SHOWFLAG("CMAKE_C_COMPILER_ID") SHOWFLAG("CMAKE_CXX_COMPILER_ID") SHOWFLAG("CMAKE_COMPILER_IS_GNUCC") SHOWFLAG("CMAKE_COMPILER_IS_GNUCXX") SHOWFLAG("CYGWIN") SHOWFLAG("MINGW") SHOWFLAG("MSVC") SHOWFLAG("MSVC_VERSION") SHOWFLAG("MSYS") SHOWFLAG("UNIX") SHOWFLAG("WATCOM") SHOWFLAG("WIN32") endif(NEWPLATFORMDEBUG) thrift-0.23.0/build/cmake/DefinePlatformSpecifc.cmake0000664000175000017500000001121015165535636022745 0ustar00buildbuild00000000000000# # 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. # # Uncomment this to show some basic cmake variables about platforms # include (NewPlatformDebug) # For Debug build types, default to "d"-suffix in library names. set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Set debug library postfix") # basic options foreach(lang IN ITEMS C CXX) if("CMAKE_${lang}_COMPILER_ID" STREQUAL "MSVC") # These flags are not supported (or needed) with Clang-Cl on Windows: set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /MP") # parallel build endif() if("CMAKE_${lang}_COMPILER_ID" STREQUAL "MSVC" OR "${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "MSVC") set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /W3") # warning level 3 include(CheckCXXCompilerFlag) set(CMAKE_REQUIRED_QUIET ON) check_cxx_compiler_flag("/source-charset:utf-8" res_var) if (res_var) set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /source-charset:utf-8") endif() check_cxx_compiler_flag("/execution-charset:utf-8" res_var) if (res_var) set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /execution-charset:utf-8") endif() add_definitions("-DUNICODE -D_UNICODE") elseif("CMAKE_${lang}_COMPILER_ID" STREQUAL "Clang") set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -Wall") set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -ferror-limit=1") elseif("CMAKE_${lang}_COMPILER_ID" STREQUAL "GNU") set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -Wall -Wextra") set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -fmax-errors=1") endif() endforeach() # Visual Studio specific options if(MSVC) # Allow for shared library builds if(BUILD_SHARED_LIBS) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON CACHE TYPE BOOL FORCE) endif() #For visual studio the library naming is as following: # Dynamic libraries: # - thrift.dll for release library # - thriftd.dll for debug library # # Static libraries: # - thriftmd.lib for /MD release build # - thriftmt.lib for /MT release build # # - thriftmdd.lib for /MD debug build # - thriftmtd.lib for /MT debug build # # the same holds for other libraries like libthriftz etc. # Build using /MT option instead of /MD if the WITH_MT options is set if(WITH_MT) set(CompilerFlags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO ) foreach(CompilerFlag ${CompilerFlags}) string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") endforeach() set(THRIFT_RUNTIME_POSTFIX "mt" CACHE STRING "Set runtime library postfix" FORCE) else(WITH_MT) set(THRIFT_RUNTIME_POSTFIX "md" CACHE STRING "Set runtime library postfix" FORCE) endif(WITH_MT) # Disable boost auto linking pragmas - cmake includes the right files add_definitions("-DBOOST_ALL_NO_LIB") elseif(UNIX) find_program( MEMORYCHECK_COMMAND valgrind ) set( MEMORYCHECK_COMMAND_OPTIONS "--gen-suppressions=all --leak-check=full" ) set( MEMORYCHECK_SUPPRESSIONS_FILE "${PROJECT_SOURCE_DIR}/test/valgrind.suppress" ) endif() add_definitions("-D__STDC_FORMAT_MACROS") add_definitions("-D__STDC_LIMIT_MACROS") # C++ Language Level set(CXX_LANGUAGE_LEVEL "C++${CMAKE_CXX_STANDARD}") if (CMAKE_CXX_STANDARD_REQUIRED) string(CONCAT CXX_LANGUAGE_LEVEL "${CXX_LANGUAGE_LEVEL} [compiler must support it]") else() string(CONCAT CXX_LANGUAGE_LEVEL "${CXX_LANGUAGE_LEVEL} [fallback to earlier if compiler does not support it]") endif() if (CMAKE_CXX_EXTENSIONS) string(CONCAT CXX_LANGUAGE_LEVEL "${CXX_LANGUAGE_LEVEL} [with compiler-specific extensions]") endif() if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register") endif() thrift-0.23.0/build/docker/0000775000175000017500000000000015167543515015740 5ustar00buildbuild00000000000000thrift-0.23.0/build/docker/ubuntu-focal/0000775000175000017500000000000015167543515020344 5ustar00buildbuild00000000000000thrift-0.23.0/build/docker/ubuntu-focal/Dockerfile0000664000175000017500000002742415167543515022347 0ustar00buildbuild00000000000000# 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 Focal # with some updated packages. # FROM buildpack-deps:focal-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 # 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/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 # node.js RUN mkdir -p /etc/apt/keyrings && \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list ### install general dependencies RUN apt-get update -yq && \ 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 # Because Ubuntu 20.04 turned EOL in April/May 2025, Microsoft does not support .NET 9 or higher on that platform 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.24.3 ENV GOLANG_DOWNLOAD_URL=https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz 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 # 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 \ `# 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 && \ `# disable sandboxing see https://github.com/ocaml/opam/issues/4327` \ opam init --yes --disable-sandboxing && \ 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.4 \ php7.4-cli \ php7.4-dev \ php7.4-mbstring \ php7.4-xml \ php7.4-curl \ php7.4-xdebug \ php-pear \ re2c # Install Composer 2 explicitly to avoid distro package version drift. RUN curl -sS https://getcomposer.org/installer | php -- --2 --install-dir=/usr/local/bin --filename=composer && \ composer --version RUN apt-get install -y --no-install-recommends \ `# Python3 dependencies` \ python3-all \ python3-all-dbg \ python3-all-dev \ python3-pip \ python3-setuptools \ python3-wheel RUN python3 -m pip install --no-cache-dir --upgrade "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1" RUN apt-get install -y --no-install-recommends \ `# Ruby dependencies` \ ruby \ ruby-dev \ ruby-bundler 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 \ libedit-dev \ libz3-dev \ libpython2-dev \ libxml2-dev && \ cd / && \ wget --quiet https://download.swift.org/swift-5.7-release/ubuntu2004/swift-5.7-RELEASE/swift-5.7-RELEASE-ubuntu20.04.tar.gz && \ tar xf swift-5.7-RELEASE-ubuntu20.04.tar.gz && \ mv swift-5.7-RELEASE-ubuntu20.04 /usr/share/swift && \ rm swift-5.7-RELEASE-ubuntu20.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 && \ chown -R ${uid}:${uid} $THRIFT_ROOT/ COPY Dockerfile $THRIFT_ROOT/ WORKDIR $THRIFT_ROOT/src USER ${user} thrift-0.23.0/build/docker/ubuntu-noble/0000775000175000017500000000000015167543515020357 5ustar00buildbuild00000000000000thrift-0.23.0/build/docker/ubuntu-noble/Dockerfile0000664000175000017500000002510015167543515022347 0ustar00buildbuild00000000000000# 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 Noble # with some updated packages. # FROM buildpack-deps:noble-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 # Create a user ARG user=build ARG group=build ARG uid=1001 ARG gid=1001 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 # node.js RUN mkdir -p /etc/apt/keyrings && \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list ### install general dependencies RUN apt-get update -yq && \ apt-get install -y --no-install-recommends \ `# General dependencies` \ bash-completion \ bison \ build-essential \ clang \ cmake \ debhelper \ flex \ gdb \ 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 \ 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 add-apt-repository ppa:dotnet/backports RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ dotnet-sdk-10.0 \ dotnet-runtime-10.0 \ aspnetcore-runtime-10.0 \ dotnet-apphost-pack-10.0 # Erlang dependencies 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 && \ 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.24.3 ENV GOLANG_DOWNLOAD_URL=https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz 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 # 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 \ `# 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.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 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 && \ `# disable sandboxing see https://github.com/ocaml/opam/issues/4327` \ opam init --yes --disable-sandboxing && \ 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` \ php8.3 \ php8.3-cli \ php8.3-dev \ php8.3-mbstring \ php8.3-xml \ php8.3-curl \ php8.3-xdebug \ php-pear \ re2c \ composer RUN apt-get install -y --no-install-recommends \ `# Python3 dependencies` \ python3-all \ python3-all-dbg \ python3-all-dev \ python3-pip \ python3-setuptools \ python3-wheel RUN python3 -m pip install --no-cache-dir --upgrade --break-system-packages \ "tornado>=6.3.0" \ "twisted>=24.3.0" \ "zope.interface>=6.1" RUN apt-get install -y --no-install-recommends \ `# Ruby dependencies` \ ruby \ ruby-dev \ ruby-bundler 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 \ libedit-dev \ libz3-dev \ python3-flake8 \ libxml2-dev && \ cd / && \ wget --quiet https://download.swift.org/swift-6.1-release/ubuntu2404/swift-6.1-RELEASE/swift-6.1-RELEASE-ubuntu24.04.tar.gz && \ tar xf swift-6.1-RELEASE-ubuntu24.04.tar.gz && \ mv swift-6.1-RELEASE-ubuntu24.04 /usr/share/swift && \ rm swift-6.1-RELEASE-ubuntu24.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 #RUN 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 && \ chown -R ${uid}:${uid} $THRIFT_ROOT/ COPY Dockerfile $THRIFT_ROOT/ WORKDIR $THRIFT_ROOT/src USER ${user} thrift-0.23.0/build/docker/ubuntu-jammy/0000775000175000017500000000000015167543515020375 5ustar00buildbuild00000000000000thrift-0.23.0/build/docker/ubuntu-jammy/Dockerfile0000664000175000017500000002505415167543515022375 0ustar00buildbuild00000000000000# 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 Jammy # with some updated packages. # FROM buildpack-deps:jammy-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 # 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 # node.js RUN mkdir -p /etc/apt/keyrings && \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list ### install general dependencies RUN apt-get update -yq && \ 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 \ 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 add-apt-repository ppa:dotnet/backports RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ dotnet-sdk-10.0 \ dotnet-runtime-10.0 \ aspnetcore-runtime-10.0 \ dotnet-apphost-pack-10.0 # Erlang dependencies 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 && \ 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.24.3 ENV GOLANG_DOWNLOAD_URL=https://go.dev/dl/go$GOLANG_VERSION.linux-amd64.tar.gz 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 # 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 \ `# 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.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 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 && \ `# disable sandboxing see https://github.com/ocaml/opam/issues/4327` \ opam init --yes --disable-sandboxing && \ 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` \ php8.1 \ php8.1-cli \ php8.1-dev \ php8.1-mbstring \ php8.1-xml \ php8.1-curl \ php8.1-xdebug \ php-pear \ re2c \ composer RUN apt-get install -y --no-install-recommends \ `# Python3 dependencies` \ python3-all \ python3-all-dbg \ python3-all-dev \ python3-pip \ python3-setuptools \ python3-wheel RUN python3 -m pip install --no-cache-dir --upgrade "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1" RUN apt-get install -y --no-install-recommends \ `# Ruby dependencies` \ ruby \ ruby-dev \ ruby-bundler 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 \ libedit-dev \ libz3-dev \ libpython2-dev \ libxml2-dev && \ cd / && \ wget --quiet https://download.swift.org/swift-5.7-release/ubuntu2204/swift-5.7-RELEASE/swift-5.7-RELEASE-ubuntu22.04.tar.gz && \ tar xf swift-5.7-RELEASE-ubuntu22.04.tar.gz && \ mv swift-5.7-RELEASE-ubuntu22.04 /usr/share/swift && \ rm swift-5.7-RELEASE-ubuntu22.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 && \ chown -R ${uid}:${uid} $THRIFT_ROOT/ COPY Dockerfile $THRIFT_ROOT/ WORKDIR $THRIFT_ROOT/src USER ${user} thrift-0.23.0/build/docker/run.sh0000775000175000017500000000204215165535636017104 0ustar00buildbuild00000000000000#!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOCKER_TAG=$DOCKER_REPO:$DISTRO printenv | sort docker run --net=host -e BUILD_LIBS="$BUILD_LIBS" $BUILD_ENV -v $(pwd):/thrift/src \ -it $DOCKER_TAG build/docker/scripts/$SCRIPT $BUILD_ARG thrift-0.23.0/build/docker/msvc/0000775000175000017500000000000015167543515016710 5ustar00buildbuild00000000000000thrift-0.23.0/build/docker/msvc/build.bat0000664000175000017500000000573115167543515020505 0ustar00buildbuild00000000000000:: :: Licensed under the Apache License, Version 2.0 (the "License"); :: you may not use this file except in compliance with the License. :: You may obtain a copy of the License at :: :: http://www.apache.org/licenses/LICENSE-2.0 :: :: Unless required by applicable law or agreed to in writing, software :: distributed under the License is distributed on an "AS IS" BASIS, :: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. :: See the License for the specific language governing permissions and :: limitations under the License. :: :: :: Build script example for inside the windows docker container :: :: C:\build is the out-of-tree build directory :: C:\install is the location where artifacts are placed :: C:\thrift is where the sources are :: IF EXIST "C:\Program Files\dotnet\dotnet.exe" ( FOR /F "tokens=1" %%I IN ('"C:\Program Files\dotnet\dotnet.exe" --list-sdks 2^>NUL') DO ( SET DOTNET_SDK_VERSION=%%I GOTO GOT_DOTNET_SDK ) ) :GOT_DOTNET_SDK IF DEFINED DOTNET_SDK_VERSION ( IF EXIST "C:\Program Files\dotnet\sdk\%DOTNET_SDK_VERSION%\Sdks" ( SET MSBuildSDKsPath=C:\Program Files\dotnet\sdk\%DOTNET_SDK_VERSION%\Sdks ) ) :: Make and go into the out-of-tree directory IF NOT EXIST C:\build (MKDIR C:\build) cd c:\build :: Generate the out-of-tree build files cmake^ -DCMAKE_GENERATOR_PLATFORM=x64^ -DBOOST_ROOT=%BOOST_ROOT%^ -DFLEX_HOME=%FLEX_HOME%^ -DLIBEVENT_ROOT=%LIBEVENT_ROOT%^ -DZLIB_ROOT=%ZLIB_ROOT%^ -DCMAKE_BUILD_TYPE=Release^ -DBUILD_SHARED_LIBS=OFF^ -DCMAKE_INSTALL_PREFIX=C:\install^ c:\thrift || EXIT /B :: Build cmake --build . --config Release || EXIT /B :: Test ctest -C Release || EXIT /B :: Install (needed before netstd scripts so thrift.exe is in C:\install\bin) cmake --install . || EXIT /B :: Build and test .NET (netstd) library if dotnet CLI is available IF /I "%THRIFT_BUILD_DOTNET%"=="OFF" GOTO SKIP_DOTNET IF EXIST "C:\Program Files (x86)\dotnet\dotnet.exe" SET PATH=C:\Program Files (x86)\dotnet;%PATH% IF EXIST "C:\Program Files\dotnet\dotnet.exe" SET PATH=C:\Program Files\dotnet;%PATH% where dotnet >NUL 2>NUL IF ERRORLEVEL 1 ( ECHO dotnet CLI not found, skipping netstd build/test GOTO SKIP_DOTNET ) SET HAS_DOTNET_SDK= FOR /F "delims=" %%I IN ('dotnet --list-sdks 2^>NUL') DO SET HAS_DOTNET_SDK=1 IF NOT DEFINED HAS_DOTNET_SDK ( ECHO dotnet SDK not found, skipping netstd build/test GOTO SKIP_DOTNET ) PUSHD C:\thrift\lib\netstd IF EXIST C:\install\bin\thrift.exe SET PATH=C:\install\bin;%PATH% IF EXIST C:\build\bin\Release\thrift.exe SET PATH=C:\build\bin\Release;%PATH% IF EXIST C:\build\compiler\cpp\Release\thrift.exe SET PATH=C:\build\compiler\cpp\Release;%PATH% IF EXIST C:\build\compiler\cpp\thrift.exe SET PATH=C:\build\compiler\cpp;%PATH% where thrift >NUL 2>NUL IF ERRORLEVEL 1 ( ECHO thrift compiler not found on PATH, skipping netstd build/test POPD GOTO SKIP_DOTNET ) call build.cmd || EXIT /B IF /I NOT "%THRIFT_TEST_DOTNET%"=="OFF" ( call runtests.cmd || EXIT /B ) POPD :SKIP_DOTNET thrift-0.23.0/build/docker/msvc/build-compiler.bat0000664000175000017500000000250515167543515022311 0ustar00buildbuild00000000000000:: :: Licensed under the Apache License, Version 2.0 (the "License"); :: you may not use this file except in compliance with the License. :: You may obtain a copy of the License at :: :: http://www.apache.org/licenses/LICENSE-2.0 :: :: Unless required by applicable law or agreed to in writing, software :: distributed under the License is distributed on an "AS IS" BASIS, :: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. :: See the License for the specific language governing permissions and :: limitations under the License. :: :: :: Build script example for inside the windows docker container :: :: C:\build is the out-of-tree build directory :: C:\install is the location where artifacts are placed :: C:\thrift is where the sources are :: :: Make and go into the out-of-tree directory IF NOT EXIST C:\build (MKDIR C:\build) cd c:\build :: Generate the out-of-tree build files cmake^ -DBOOST_ROOT=C:\Libraries\boost_1_89_0^ -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_89_0\lib64-msvc-14.1^ -DBUILD_LIBRARIES=OFF^ -DBUILD_TESTING=ON^ -DCMAKE_BUILD_TYPE=Release^ -DCMAKE_INSTALL_PREFIX=C:\install^ -DWITH_MT=ON^ c:\thrift || EXIT /B :: Build cmake --build . --target thrift-compiler thrift_compiler_tests --config Release || EXIT /B :: Test ctest -C Release || EXIT /B :: Install cmake --install .thrift-0.23.0/build/docker/msvc/README.md0000664000175000017500000000325315167543515020172 0ustar00buildbuild00000000000000# Building Thrift using Docker for Windows The build image is very large (just under 30GB) so plan accordingly. Once Microsoft supports build tools in nano, it should get better. Install Docker for Windows and switch to Windows container mode. Pull from docker hub: PS C:\> docker pull thrift/thrift-build:msvc2017 or build in a docker for windows environment: PS C:\Thrift> docker build -t thrift/thrift-build:msvc2017 -f build\docker\msvc2017\Dockerfile build\ The following directories are used inside the container: C:\Build the out-of-tree build directory C:\Install the install target directory C:\Thrift the source tree You can override these as docker volumes if desired. ### Compiler To build a portable windows thrift compiler (with a statically linked runtime) and get it placed into C:\install: docker run -v C:\thrift:C:\thrift^ -v C:\install:C:\install^ --rm -t thrift/thrift-build:msvc2017^ C:\thrift\build\docker\msvc2017\build-compiler.bat The end result is a portable windows thrift compiler located at C:\Install\bin\thrift.exe If you run it through the [Dependency Walker](http://www.dependencywalker.com/) you will see it only depends on KERNEL32.DLL which means the runtime is statically linked, so the executable is portable and self-contained. This is how the windows thrift compiler is built for each Apache Thrift release. ### Libraries To build, test everything and get the C++ SDK placed into C:\install: docker run -v C:\thrift:C:\thrift^ -v C:\install:C:\install^ -m 4096 --rm -t thrift/thrift-build:msvc2017^ C:\thrift\build\docker\msvc2017\build.batthrift-0.23.0/build/docker/msvc/Dockerfile0000664000175000017500000001151115167543515020701 0ustar00buildbuild00000000000000# escape=` # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # FROM mcr.microsoft.com/dotnet/framework/sdk:4.8.1-windowsservercore-ltsc2025 # Restore the default Windows shell for correct batch processing below. SHELL ["cmd", "/S", "/C"] # Install Build Tools excluding workloads and components with known issues. ADD --checksum=sha256:93bf06959261a301aca6406d058ade08f34ae83ca458fe3ed0689aa2105d9ccc https://aka.ms/vs/17/release/vs_BuildTools.exe C:\TEMP\vs_buildtools.exe RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache ` --installPath C:\BuildTools ` --add Microsoft.VisualStudio.Component.VC.CoreBuildTools ` --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` --add Microsoft.VisualStudio.Component.Windows10SDK.19041 ` || IF "%ERRORLEVEL%"=="3010" EXIT 0 RUN DEL C:\TEMP\vs_buildtools.exe # Install CMake ADD --checksum=sha256:a10fc2527ec0727a5913acd310cddafba1e5b4ca765ca23cc6a53c55eebb7c1 https://github.com/Kitware/CMake/releases/download/v4.1.2/cmake-4.1.2-windows-x86_64.msi C:\TEMP\cmake.msi RUN msiexec.exe /i C:\TEMP\cmake.msi /qn && ` SETX PATH "%PATH%;C:\Program Files\CMake\bin" && ` DEL C:\TEMP\cmake.msi # Install boost (for the thrift runtime library build) ADD --checksum=sha256:bff575f21343f602c7b6c3ad3883a28053a1a50cde2153102d30479f85911738 https://boost.teeks99.com/bin/1.88.0/boost_1_88_0-msvc-14.3-64.exe C:\TEMP\boost.exe ENV BOOST_ROOT=C:\Libraries\boost_1_88_0 RUN C:\TEMP\boost.exe /DIR=%BOOST_ROOT% /SILENT && ` DEL C:\TEMP\boost.exe && ` SETX BOOST_LIBRARYDIR "%BOOST_ROOT%\lib64-msvc-14.3" && ` SETX PATH "%BOOST_LIBRARYDIR%;%PATH%" # Install chocolatey RUN @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" ` -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command ` "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" ` && SETX PATH "%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" # Install winflexbison (for the thrift compiler build) RUN choco install winflexbison3 -y # Install 7zip and curl (used by the libevent and zlib build scripts) RUN choco install 7zip curl -y # Install libevent COPY appveyor\build-libevent.bat C:\TEMP\build-libevent.bat ENV LIBEVENT_VERSION=2.1.8 ENV WIN3P=C:\TEMP\WIN3P RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && ` MKDIR C:\TEMP\WIN3P && ` C:\TEMP\build-libevent.bat && ` MKDIR C:\Libraries\libevent-%LIBEVENT_VERSION% && ` MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\include C:\Libraries\libevent-%LIBEVENT_VERSION% && ` MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\lib C:\Libraries\libevent-%LIBEVENT_VERSION% && ` RMDIR /S /Q C:\TEMP\WIN3P && ` SETX LIBEVENT_ROOT "C:\Libraries\libevent-%LIBEVENT_VERSION%" # Install zlib COPY appveyor\build-zlib.bat C:\TEMP\build-zlib.bat ENV ZLIB_VERSION=1.3.1 ENV WIN3P=C:\TEMP\WIN3P RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && ` MKDIR C:\TEMP\WIN3P && ` C:\TEMP\build-zlib.bat && ` MOVE C:\TEMP\WIN3P\zlib-inst C:\Libraries\zlib-%ZLIB_VERSION% && ` RMDIR /S /Q C:\TEMP\WIN3P && ` SETX ZLIB_ROOT "C:\Libraries\zlib-%ZLIB_VERSION%" && ` SETX PATH "%ZLIB_ROOT%\bin;%PATH%" # Install OpenSSL 3.6.1 ADD --checksum=sha256:8ce11c409adbd177ca627115bc697c3b66c414bb36175ebb375341eb426894a8 https://slproweb.com/download/Win64OpenSSL-3_6_1.exe C:\TEMP\openssl.exe RUN C:\TEMP\openssl.exe /silent && ` DEL C:\TEMP\openssl.exe && ` SETX OPENSSL_ROOT "C:\OpenSSL-Win64" && ` SETX PATH "%OPENSSL_ROOT%\bin;%PATH%" # Install java RUN choco install jdk8 -y # Install python3 RUN choco install python3 -y RUN pip install setuptools # Install Adobe Flex 4.6 SDK and set FLEX_HOME so it can be found ADD --checksum=sha256:622b63f29de44600ff8d4231174a70fcb3085812c0e146a42e91877ca8b46798 http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip C:\Adobe\Flex\SDK\4.6\SDK.zip RUN CD C:\Adobe\Flex\SDK\4.6 && ` 7z x SDK.zip && ` DEL SDK.zip && ` SETX FLEX_HOME "C:\Adobe\Flex\SDK\4.6" RUN choco install nodejs -y # Start developer command prompt with any other commands specified. ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && # Default to PowerShell if no other command specified. CMD powershell.exe -NoLogo -ExecutionPolicy Bypass thrift-0.23.0/build/docker/README.md0000664000175000017500000002077015165535636017230 0ustar00buildbuild00000000000000# Docker Integration # Due to the large number of languages supported by Apache Thrift, docker containers are used to build and test the project on a variety of platforms to provide maximum test coverage. ## Appveyor Integration ## At this time the Appveyor scripts do not use docker containers. Once Microsoft supports Visual Studio Build Tools running inside nano containers (instead of Core, which is huge) then we will consider using containers for the Windows builds as well. ## Travis CI Integration ## The Travis CI scripts use the following environment variables and logic to determine their behavior: ### Environment Variables ### | Variable | Default | Usage | | -------- | ----- | ------- | | `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-focal` ### Forks ### If you have forked the Apache Thrift repository and you would like to use your own Docker Hub account to store thrift build images, you can use the Travis CI web interface to set the `DOCKER_USER`, `DOCKER_PASS`, and `DOCKER_REPO` variables in a secure manner. Your fork builds will then pull, push, and tag the docker images in your account. ### Logic ### The Travis CI build runs in two phases - first the docker images are rebuilt for each of the supported containers if they do not match the Dockerfile that was used to build the most recent tag. If a `DOCKER_PASS` environment variable is specified, the docker stage builds will attempt to log into Docker Hub and push the resulting tags. ## Supported Containers ## The Travis CI (continuous integration) builds use the Ubuntu Noble (24.04 LTS), Jammy (22.04 LTS) and Focal (20.04 LTS) images to maximize language level coverage. ### Ubuntu ### * focal (stable) * jammy (stable) * noble (next stable) ## Unsupported Containers ## These containers may be in various states, and may not build everything. They can be found in the `old/` subdirectory. ### CentOS ### * 7.3 * make check in lib/py may hang in test_sslsocket - root cause unknown ### Debian ### * jessie * stretch * make check in lib/cpp fails due to https://svn.boost.org/trac10/ticket/12507 ## Building like Travis CI does, locally ## We recommend you build locally the same way Travis CI does, so that when you submit your pull request you will run into fewer surprises. To make it a little easier, put the following into your `~/.bash_aliases` file: # Kill all running containers. alias dockerkillall='docker kill $(docker ps -q)' # Delete all stopped containers. alias dockercleanc='printf "\n>>> Deleting stopped containers\n\n" && docker rm $(docker ps -a -q)' # Delete all untagged images. alias dockercleani='printf "\n>>> Deleting untagged images\n\n" && docker rmi $(docker images -q -f dangling=true)' # Delete all stopped containers and untagged images. alias dockerclean='dockercleanc || true && dockercleani' # Build a thrift docker image (run from top level of git repo): argument #1 is image type (ubuntu, centos, etc). function dockerbuild { docker build -t $1 build/docker/$1 } # Run a thrift docker image: argument #1 is image type (ubuntu, centos, etc). function dockerrun { docker run -v $(pwd):/thrift/src -it $1 /bin/bash } 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-focal build/docker/refresh.sh To run all unit tests (just like Travis CI does): 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-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: thrift$ dockerclean You need to run the docker commands from the root of the local clone of the thrift git repository for them to work. When you are done in the root docker shell you can `exit` to go back to your user host shell. Once the unit tests and cross test passes locally, submit the changes, and if desired squash the pull request to one commit to make it easier to merge (the committers can squash at commit time now that GitHub is the master repository). Now you are building like Travis CI does! ## Raw Commands for Building with Docker ## If you do not want to use the same scripts Travis CI does, you can do it manually: Build the image: 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: thrift$ docker run -v $(pwd):/thrift/src -it thrift /bin/bash ## Core Tool Versions per Dockerfile ## Last updated: March 5, 2024 | Tool | ubuntu-focal | ubuntu-jammy | ubuntu-noble | Notes | | :-------- | :------------ | :------------ | :------------ | :---- | | 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 ## | Tool | ubuntu-focal | ubuntu-jammy | ubuntu-noble | Notes | | :-------- | :------------ | :------------ | :------------ | :---- | | as of | Mar 06, 2018 | Jul 1, 2019 | | | | 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.7.2-1 | 2.7.2-1 | | | | delphi | | | | Not in CI | | 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 | 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 | 8.3 | | | 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.7 | 5.7 | 6.1 | | thrift-0.23.0/build/docker/scripts/0000775000175000017500000000000015165535636017432 5ustar00buildbuild00000000000000thrift-0.23.0/build/docker/scripts/coverity.sh0000775000175000017500000000251615165535636021641 0ustar00buildbuild00000000000000#! /bin/bash # # This script allows you to run coverity on the project and submit the # results. Do this inside the docker build container. Only works if # you are a coverity scan thrift project admin with access to the # necessary security token. # # Environment Variables # # COVERITY_SCAN_NOTIFICATION_EMAIL - email address to notify # COVERITY_SCAN_TOKEN - the Coverity Scan token (should be secure) # VERSION - the version to report we scanned set -ex wget -nv https://entrust.com/root-certificates/entrust_l1k.cer -O /tmp/scanca.cer pushd /tmp if [[ "$1" != "--skipdownload" ]]; then rm -rf coverity_tool.tgz cov-analysis* wget -nv -O coverity_tool.tgz https://scan.coverity.com/download/cxx/linux64 --post-data "project=thrift&token=$COVERITY_SCAN_TOKEN" tar xzf coverity_tool.tgz fi COVBIN=$(echo $(pwd)/cov-analysis*/bin) export PATH=$COVBIN:$PATH popd ./bootstrap.sh ./configure $* rm -rf cov-int/ cov-build --dir cov-int make check -j3 tail -50 cov-int/build-log.txt tar cJf cov-int.tar.xz cov-int/ curl --cacert /tmp/scanca.cer \ --form token="$COVERITY_SCAN_TOKEN" \ --form email="$COVERITY_SCAN_NOTIFICATION_EMAIL" \ --form file=@cov-int.tar.xz \ --form version="$VERSION" \ --form description="thrift master" \ https://scan.coverity.com/builds?project=thrift thrift-0.23.0/build/docker/scripts/cross-test.sh0000775000175000017500000000056515165535636022105 0ustar00buildbuild00000000000000#!/bin/sh set -ev ./bootstrap.sh ./configure --enable-tutorial=no make -j3 precross set +e make cross$1 RET=$? if [ $RET -ne 0 ]; then if [ -f "test/features/log/unexpected_failures.log" ]; then cat "test/features/log/unexpected_failures.log" fi if [ -f "test/log/unexpected_failures.log" ]; then cat "test/log/unexpected_failures.log" fi fi exit $RET thrift-0.23.0/build/docker/scripts/dpkg.sh0000775000175000017500000000007315165535636020716 0ustar00buildbuild00000000000000#!/bin/sh set -ev dpkg-buildpackage -tc -us -uc ls -al .. thrift-0.23.0/build/docker/scripts/covscan.sh0000775000175000017500000000336215165535636021431 0ustar00buildbuild00000000000000# # Coverity Scan Travis build script # To run this interactively, set the environment variables yourself, # and run this inside a docker container. # # Command-Line Arguments # # --skipdownload to skip re-downloading the Coverity Scan build package (large) # # Environment Variables (required) # # COVERITY_SCAN_NOTIFICATION_EMAIL - email address to notify # COVERITY_SCAN_TOKEN - the Coverity Scan token (should be secure) # # Environment Variables (defaulted) # # COVERITY_SCAN_BUILD_COMMAND - defaults to "build/docker/scripts/autotools.sh" # COVERITY_SCAN_DESCRIPTION - defaults to TRAVIS_BRANCH or "master" if empty # COVERITY_SCAN_PROJECT - defaults to "thrift" set -ex COVERITY_SCAN_BUILD_COMMAND=${COVERITY_SCAN_BUILD_COMMAND:-build/docker/scripts/autotools.sh} COVERITY_SCAN_DESCRIPTION=${COVERITY_SCAN_DESCRIPTION:-${TRAVIS_BRANCH:-master}} COVERITY_SCAN_PROJECT=${COVERITY_SCAN_PROJECT:-thrift} # download the coverity scan package pushd /tmp if [[ "$1" != "--skipdownload" ]]; then rm -rf coverity_tool.tgz cov-analysis* wget https://scan.coverity.com/download/linux64 --post-data "token=$COVERITY_SCAN_TOKEN&project=$COVERITY_SCAN_PROJECT" -O coverity_tool.tgz tar xzf coverity_tool.tgz fi COVBIN=$(echo $(pwd)/cov-analysis*/bin) export PATH=$COVBIN:$PATH popd # build the project with coverity scan rm -rf cov-int/ cov-build --dir cov-int $COVERITY_SCAN_BUILD_COMMAND tar cJf cov-int.tar.xz cov-int/ curl --form token="$COVERITY_SCAN_TOKEN" \ --form email="$COVERITY_SCAN_NOTIFICATION_EMAIL" \ --form file=@cov-int.tar.xz \ --form version="$(git describe --tags)" \ --form description="$COVERITY_SCAN_DESCRIPTION" \ https://scan.coverity.com/builds?project="$COVERITY_SCAN_PROJECT" thrift-0.23.0/build/docker/scripts/autotools.sh0000775000175000017500000000054315165535636022024 0ustar00buildbuild00000000000000#!/bin/sh set -ev mkdir -p ~/.m2 tee >~/.m2/settings.xml < secure-central https://repo.maven.apache.org/maven2 central EOF ./bootstrap.sh ./configure $* make check -j3 thrift-0.23.0/build/docker/scripts/make-dist.sh0000775000175000017500000000017715165535636021654 0ustar00buildbuild00000000000000#!/bin/sh set -ev ./bootstrap.sh ./configure $* make dist tar xvf thrift-*.tar.gz cd thrift-* ./build/docker/scripts/cmake.sh thrift-0.23.0/build/docker/scripts/cmake.sh0000775000175000017500000000057715165535636021062 0ustar00buildbuild00000000000000#!/bin/sh set -ev CMAKE_FLAGS=$* MAKEPROG=make if ninja --version >/dev/null 2>&1; then MAKEPROG=ninja CMAKE_FLAGS="-GNinja $CMAKE_FLAGS" fi mkdir -p cmake_build && cd cmake_build cmake $CMAKE_FLAGS .. for LIB in $BUILD_LIBS; do if ! grep "^BUILD_${LIB}:BOOL=ON$" CMakeCache.txt ; then echo "failed to configure $LIB" exit 1 fi done $MAKEPROG -j3 cpack ctest -VV thrift-0.23.0/build/docker/scripts/ubsan.sh0000775000175000017500000000175015165535636021104 0ustar00buildbuild00000000000000#!/bin/sh set -e # Wraps autotools.sh, but each binary crashes if it exhibits undefined behavior. # Set the undefined behavior flags. This crashes on all undefined behavior except for # undefined casting, aka "vptr". # TODO: fix undefined vptr behavior and turn this option back on. export CFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -O0 -ggdb3 -fno-omit-frame-pointer" export CXXFLAGS="${CFLAGS}" export LDFLAGS="-lubsan" export UBSAN_OPTIONS=print_stacktrace=1 # # work around https://svn.boost.org/trac10/ticket/11632 if present # sed -i 's/, stream_t(rdbuf()) /, stream_t(pbase_type::member.get())/g' /usr/include/boost/format/alt_sstream.hpp # llvm-symbolizer must be on PATH to get a stack trace on error CLANG_PATH="$(mktemp -d)" trap "rm -rf ${CLANG_PATH}" EXIT ln -s "$(whereis llvm-symbolizer-4.0 | rev | cut -d ' ' -f 1 | rev)" \ "${CLANG_PATH}/llvm-symbolizer" export PATH="${CLANG_PATH}:${PATH}" llvm-symbolizer -version build/docker/scripts/autotools.sh $* thrift-0.23.0/build/docker/scripts/sca.sh0000775000175000017500000000331415165535636020540 0ustar00buildbuild00000000000000#!/bin/bash set -ev # # Generate thrift files so the static code analysis includes an analysis # of the files the thrift compiler spits out. If running interactively # set the NOBUILD environment variable to skip the boot/config/make phase. # if [[ -z "$NOBUILD" ]]; then ./bootstrap.sh ./configure --enable-tutorial=no make -j3 precross fi # # C/C++ static code analysis with cppcheck # add --error-exitcode=1 to --enable=all as soon as everything is fixed # # Python code style check with flake8 # # search for TODO etc within source tree # some statistics about the code base # some info about the build machine # Compiler cppcheck (All) cppcheck --force --quiet --inline-suppr --enable=all -j2 compiler/cpp/src # C++ cppcheck (All) cppcheck --force --quiet --inline-suppr --enable=all -j2 lib/cpp/src lib/cpp/test test/cpp tutorial/cpp # C Glib cppcheck (All) cppcheck --force --quiet --inline-suppr --enable=all -j2 lib/c_glib/src lib/c_glib/test test/c_glib/src tutorial/c_glib # Silent error checks # See THRIFT-4371 : flex generated code triggers "possible null pointer dereference" in yy_init_buffer cppcheck --force --quiet --inline-suppr --suppress="*:thrift/thriftl.cc" --error-exitcode=1 -j2 compiler/cpp/src cppcheck --force --quiet --inline-suppr --error-exitcode=1 -j2 lib/cpp/src lib/cpp/test test/cpp tutorial/cpp cppcheck --force --quiet --inline-suppr --error-exitcode=1 -j2 lib/c_glib/src lib/c_glib/test test/c_glib/src tutorial/c_glib # Python code style flake8 # PHP code style composer install --quiet ./vendor/bin/phpcs # TODO etc echo FIXMEs: `grep -r FIXME * | wc -l` echo HACKs: `grep -r HACK * | wc -l` echo TODOs: `grep -r TODO * | wc -l` # LoC sloccount . # System Info dpkg -l uname -a thrift-0.23.0/build/docker/refresh.sh0000775000175000017500000000543015165535636017742 0ustar00buildbuild00000000000000#!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # The build has two stages: "docker" and "test" # The "docker" stage is meant to rebuild the docker images # if needed. If we cannot push that result however then # there is no reason to do anything. # The "test" stage is an actual test job. Even if the docker # image doesn't match what's in the repo, we still build # the image so the build job can run properly. # set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOCKER_TAG=$DOCKER_REPO:$DISTRO function dockerfile_changed { # image may not exist yet, so we have to let it fail silently: docker pull $DOCKER_TAG || true docker run $DOCKER_TAG bash -c 'cd .. && sha512sum Dockerfile' > .Dockerfile.sha512 sha512sum -c .Dockerfile.sha512 } # # If this build has no DOCKER_PASS and it is in the docker stage # then there's no reason to do any processing because we cannot # push the result if the Dockerfile changed. # if [[ "$TRAVIS_BUILD_STAGE" == "docker" ]] && [[ -z "$DOCKER_PASS" ]]; then echo Detected docker stage build and no defined DOCKER_PASS, this build job will be skipped. echo Subsequent jobs in the test stage may each rebuild the docker image. exit 0 fi pushd ${SCRIPT_DIR}/$DISTRO if dockerfile_changed; then echo Dockerfile has not changed. No need to rebuild. exit 0 else echo Dockerfile has changed. fi popd # # Dockerfile has changed - rebuild it for the current build job. # If it is a "docker" stage build then we want to push it back # to the DOCKER_REPO. If it is a "test" stage build then we do # not. If nobody defined a DOCKER_PASS then it doesn't matter. # echo Rebuilding docker image $DISTRO docker build --tag $DOCKER_TAG build/docker/$DISTRO if [[ "$TRAVIS_BUILD_STAGE" == "docker" ]] && [[ ! -z "$DOCKER_USER" ]] && [[ ! -z "$DOCKER_PASS" ]]; then echo Pushing docker image $DOCKER_TAG docker login -u $DOCKER_USER -p $DOCKER_PASS docker push $DOCKER_TAG else echo Not pushing docker image: either not a docker stage build job, or one of DOCKER_USER or DOCKER_PASS is undefined. fi thrift-0.23.0/build/veralign.sh0000775000175000017500000002535615167543515016652 0ustar00buildbuild00000000000000#!/usr/bin/env bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # The veralign script sets the appropriate versions in all of # the package configuration files for all of the supported # languages. It is used to prepare a release or move master # forward to the next anticipated version. # # USAGE # ----------------------------------------------------------- # usage: veralign.sh # # EXAMPLE # ----------------------------------------------------------- # $ ./veralign.sh 0.12.0 1.0.0 # $ ./veralign.sh 1.0.0 1.1.0 # # IMPORTANT USAGE NOTE # ----------------------------------------------------------- # Define the environment variable DRYRUN to have the script # print out all matches to the oldVersion hilighted so that # you can verify it will change the right things. # declare -A FILES # These files require a manual touch: FILES[CHANGES.md]=manual FILES[debian/changelog]=manual FILES[doap.rdf]=manual # These files can be updated automatically: FILES[ApacheThrift.nuspec]=simpleReplace FILES[appveyor.yml]=simpleReplace FILES[bower.json]=jsonReplace FILES[CMakeLists.txt]=simpleReplace FILES[compiler/cpp/src/thrift/version.h]=simpleReplace FILES[configure.ac]=configureReplace FILES[contrib/Rebus/Properties/AssemblyInfo.cs]=simpleReplace FILES[contrib/thrift.spec]=simpleReplace FILES[contrib/zeromq/csharp/AssemblyInfo.cs]=simpleReplace FILES[contrib/thrift-maven-plugin/pom.xml]=pomReplace FILES[doc/specs/idl.md]=simpleReplace FILES[lib/d/src/thrift/base.d]=simpleReplace FILES[lib/dart/pubspec.yaml]=pubspecReplace FILES[lib/delphi/src/Thrift.pas]=simpleReplace FILES[lib/erl/src/thrift.app.src]=simpleReplace FILES[lib/haxe/haxelib.json]=simpleReplace FILES[lib/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/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.net10/Thrift.Compile.net10.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 FILES[lib/py/setup.py]=simpleReplace FILES[lib/rb/thrift.gemspec]=simpleReplace FILES[lib/rs/Cargo.toml]=simpleReplace FILES[lib/st/package.xml]=simpleReplace FILES[lib/swift/Sources/Thrift.swift]=simpleReplace FILES[lib/swift/Tests/ThriftTests/ThriftTests.swift]=simpleReplace FILES[lib/ts/package-lock.json]=jsonReplace FILES[lib/ts/package.json]=jsonReplace FILES[package-lock.json]=jsonReplace FILES[package.json]=jsonReplace FILES[sonar-project.properties]=simpleReplace FILES[test/dart/test_client/pubspec.yaml]=pubspecReplace FILES[test/erl/src/thrift_test.app.src]=simpleReplace FILES[test/netstd/Client/Client.csproj]=simpleReplace FILES[test/netstd/Server/Server.csproj]=simpleReplace FILES[Thrift.podspec]=simpleReplace FILES[tutorial/dart/client/pubspec.yaml]=pubspecReplace FILES[tutorial/dart/console_client/pubspec.yaml]=pubspecReplace FILES[tutorial/dart/server/pubspec.yaml]=pubspecReplace FILES[tutorial/delphi/DelphiClient/DelphiClient.dproj]=simpleReplace FILES[tutorial/delphi/DelphiServer/DelphiServer.dproj]=simpleReplace FILES[tutorial/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 if [ ! -f "CHANGES.md" ]; then >&2 echo "error: run veralign.sh while in the thrift root directory" exit 1 fi if [ $# -ne 2 ]; then >&2 echo "usage: veralign.sh " exit 1 fi jq --version 1>/dev/null 2>/dev/null if [ $? -ne 0 ]; then >&2 echo "error: the 'jq' package is not installed" exit 1 fi # # validateVersion: check that a version matches the major.minor.patch # format which is the lowest common denominator supported by all # project systems. # \param $1 the version # \returns 0 if the version is compliant # function validateVersion { local result local valid valid=$(echo "$1" | sed '/^[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+$/!{q22}') result=$? if [ $result -eq 22 ]; then >&2 echo "error: version '$1' does not conform to the required major.minor.patch format" return ${result} fi } OLDVERSION=$1 NEWVERSION=$2 validateVersion "${OLDVERSION}" || exit $? validateVersion "${NEWVERSION}" || exit $? # # escapeVersion: escape the version for use as a sed search # \param $1 the version to escape # \output the escaped string # \returns 0 # \example VERSEARCH=$(escapeVersion "[1.0.0]"); echo $VERSEARCH; => "\[1\.0\.0\]" # function escapeVersion { echo "$(echo "$1" | sed 's/\./\\./g' | sed 's/\[/\\\[/g' | sed 's/\]/\\\]/g')" } # Set up verbose hilighting if running interactive if [ "$(tput colors)" -ne 0 ]; then reverse=$(tput rev) red=$(tput setaf 1) green=$(tput setaf 2) yellow=$(tput setaf 3) normal=$(tput sgr0) fi declare -A MANUAL # # manual: note that update of said file is manual # \param $1 filename to do replacements on # \returns 0 # function manual { MANUAL["$1"]="" return 0 } # # configureReplace: replace the AC_INIT field in configure.ac # \param $1 filename to do replacements on # \returns 0 on success # function configureReplace { replace "$1" "[thrift], [${OLDVERSION}]" "[thrift], [${NEWVERSION}]" } # # jsonReplace: replace a specific version field in a JSON file # must be a top level "version" field in the json structure # \param $1 filename to do replacements on # \returns 0 on success # function jsonReplace { local result local output if [ ! -z "$DRYRUN" ]; then output=$(jq -e ".version" "$1") else output=$(jq -e ".version = \"${NEWVERSION}\"" "$1" > tmp.$$.json && mv tmp.$$.json "$1") fi result=$? if [ $? -ne 0 ]; then printf "%-60s | %5d | ${red}ERROR${normal}: version tag not found" "$1" "$count" echo return 1 elif [ ! -z "$DRYRUN" ]; then output=${output%\"} output=${output#\"} printf "%-60s | %5d | MATCHES: version: \"${reverse}${green}${output}${normal}\"" "$1" 1 echo return 0 fi printf "%-60s | %5d | ${green}OK${normal}" "$1" 1 echo return 0 } # # pubspecReplace: replace a specific version field in a YAML file # must be a top level "version" field in the yaml structure # did not find a package that preserves comments so this is # somewhat brain-dead, but it gets the job done # \param $1 filename to do replacements on # \returns 0 on success # function pubspecReplace { replace "$1" "version: ${OLDVERSION}" "version: ${NEWVERSION}" } # # pomReplace: replace a specific version field in a maven pom file # must be a top level "version" field in the xml structure # \param $1 filename to do replacements on # \returns 0 on success # function pomReplace { replace "$1" "^ ${OLDVERSION}<\/version>" " ${NEWVERSION}<\/version>" } # # replace: replace occurrences of one string with another # the file specified must contain the old string at least once # in order to be successful. # \param $1 filename to do replacements on # \param $2 the "old" string to be replaced # \param $3 the "new" striing to replace it with # \returns 0 on success # function replace { local result local output local oldString="$2" local newString="$3" local oldRegex=$(escapeVersion "${oldString}") local count=$(grep -Ec "${oldRegex}" "$1") local verbose if [ $count -eq 0 ]; then printf "%-60s | %5d | ${red}NOT FOUND${normal}: ${oldString}" "$1" 0 echo return 1 elif [ ! -z "$DRYRUN" ]; then printf "%-60s | %5d | MATCHES:" "$1" "$count" echo while read -r line; do echo " > $(echo "$line" | sed "s/${oldRegex}/${reverse}${green}${oldString}${normal}/g")" done < <(grep -E "${oldRegex}" "$1") return 0 fi output=$(sed -i "s/${oldRegex}/${newString}/g" "$1") result=$? if [ $result -ne 0 ]; then printf "%-60s | %5d | ${red}ERROR${normal}: %s" "$1" "$count" "$output" echo return 1 fi printf "%-60s | %5d | ${green}OK${normal}" "$1" "$count" echo return 0 } # # simpleReplace: replace occurrences of ${OLDVERSION} with ${NEWVERSION} # the file specified must contain OLDVERSION at least once # in order to be successful. # \param $1 filename to do replacements on # \param $2 the "old" string to be replaced # \param $3 the "new" striing to replace it with # \returns 0 on success # function simpleReplace { replace "$1" "${OLDVERSION}" "${NEWVERSION}" } echo "" echo "Apache Thrift Version Alignment Tool" echo "------------------------------------" echo "" echo "Previous Version: ${OLDVERSION}" echo " New Version: ${NEWVERSION}" echo "" echo "-------------------------------------------------------------+-------+----------------------" echo "Filename | Count | Status " echo "-------------------------------------------------------------+-------+----------------------" for file in $(echo "${!FILES[@]}" | sort); do ${FILES[$file]} $file || exit $? done echo echo "Files that must be modified manually:" echo for manu in $(echo "${!MANUAL[@]}" | sort); do echo " > ${yellow}${manu}${normal}" done exit 0 thrift-0.23.0/build/fixchanges.sh0000775000175000017500000000303215165535636017150 0ustar00buildbuild00000000000000#!/usr/bin/env bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # fixchanges will take a file as input and look for text matching # the pattern [THRIFT-nnnn] (the number of digits is not important) # which is not a markdown link, and change it to be a markdown link. # The tool writes to stdout so you can redirect it to a temporary # file and then compare against the original file before replacing # it. # # This tool was developed after the 0.12.0 release to assist with # generation of CHANGES.md content. # while IFS='' read -r line || [[ -n "$line" ]]; do if [[ "$line" =~ ^(.*)\[(THRIFT-[[:digit:]]+)\][^\(](.*)$ ]]; then echo "${BASH_REMATCH[1]}[${BASH_REMATCH[2]}](https://issues.apache.org/jira/browse/${BASH_REMATCH[2]}) ${BASH_REMATCH[3]}" else echo "$line" fi done < "$1" thrift-0.23.0/.dockerignore0000664000175000017500000000000615165535636016045 0ustar00buildbuild00000000000000.git/ thrift-0.23.0/config.hin0000644000175000017500000003266615170007166015341 0ustar00buildbuild00000000000000/* config.hin. Generated from configure.ac by autoheader. */ #ifndef CONFIG_H #define CONFIG_H /* Define if the AI_ADDRCONFIG symbol is unavailable */ #undef AI_ADDRCONFIG /* Possible value for SIGNED_RIGHT_SHIFT_IS */ #undef ARITHMETIC_RIGHT_SHIFT /* Defines automake version */ #undef AUTOMAKE_VERSION /* Use *.h extension for parser header file */ #undef BISON_USE_PARSER_H_EXTENSION /* Defines bison version */ #undef BISON_VERSION /* Define to 1 if using 'alloca.c'. */ #undef C_ALLOCA /* Define to 1 if you have the `alarm' function. */ #undef HAVE_ALARM /* Define to 1 if you have 'alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if works. */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* define if the Boost library is available */ #undef HAVE_BOOST /* Define to 1 if you have the `bzero' function. */ #undef HAVE_BZERO /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK /* Define to 1 if you have the `ftruncate' function. */ #undef HAVE_FTRUNCATE /* Define to 1 if you have the `gethostbyname' function. */ #undef HAVE_GETHOSTBYNAME /* Define to 1 if you have the `gethostbyname_r' function. */ #undef HAVE_GETHOSTBYNAME_R /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the `inet_ntoa' function. */ #undef HAVE_INET_NTOA /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LAUXLIB_H /* define if libevent is available */ #undef HAVE_LIBEVENT /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the `rt' library (-lrt). */ #undef HAVE_LIBRT /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_LUACONF_H /* Define to 1 if you have the header file. */ #undef HAVE_LUALIB_H /* Define to 1 if you have the header file. */ #undef HAVE_LUA_H /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the `mkdir' function. */ #undef HAVE_MKDIR /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_RAND_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_X509V3_H /* Define to 1 if you have the header file. */ #undef HAVE_POLL_H /* Define to 1 if you have the `pow' function. */ #undef HAVE_POW /* Define to 1 if you have the header file. */ #undef HAVE_PTHREAD_H /* Define to 1 if the system has the type `ptrdiff_t'. */ #undef HAVE_PTRDIFF_T /* Define to 1 if your system has a GNU libc compatible `realloc' function, and to 0 otherwise. */ #undef HAVE_REALLOC /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH /* Define to 1 if you have the `sched_get_priority_max' function. */ #undef HAVE_SCHED_GET_PRIORITY_MAX /* Define to 1 if you have the `sched_get_priority_min' function. */ #undef HAVE_SCHED_GET_PRIORITY_MIN /* Define to 1 if you have the header file. */ #undef HAVE_SCHED_H /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if you have the `sqrt' function. */ #undef HAVE_SQRT /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ #undef HAVE_STAT_EMPTY_STRING_BUG /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define if you have `strerror_r'. */ #undef HAVE_STRERROR_R /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK /* Define to 1 if you have the header file. */ #undef HAVE_VFORK_H /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK /* define if zlib is available */ #undef HAVE_ZLIB /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Possible value for SIGNED_RIGHT_SHIFT_IS */ #undef LOGICAL_RIGHT_SHIFT /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ #undef LSTAT_FOLLOWS_SLASHED_SYMLINK /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Define to the type of arg 1 for `select'. */ #undef SELECT_TYPE_ARG1 /* Define to the type of args 2, 3 and 4 for `select'. */ #undef SELECT_TYPE_ARG234 /* Define to the type of arg 5 for `select'. */ #undef SELECT_TYPE_ARG5 /* Indicates the effect of the right shift operator on negative signed integers */ #undef SIGNED_RIGHT_SHIFT_IS /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Define to 1 if strerror_r returns char *. */ #undef STRERROR_R_CHAR_P /* Define to 1 if you can safely include both and . This macro is obsolete. */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Possible value for SIGNED_RIGHT_SHIFT_IS */ #undef UNKNOWN_RIGHT_SHIFT /* Version number of package */ /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT32_T /* Define for Solaris 2.5.1 so the uint64_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT64_T /* Define for Solaris 2.5.1 so the uint8_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT8_T /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to the type of a signed integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef int16_t /* Define to the type of a signed integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef int32_t /* Define to the type of a signed integer type of width exactly 64 bits if such a type exists and the standard includes do not define it. */ #undef int64_t /* Define to the type of a signed integer type of width exactly 8 bits if such a type exists and the standard includes do not define it. */ #undef int8_t /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc /* Define to `int' if does not define. */ #undef mode_t /* Define to `long int' if does not define. */ #undef off_t /* Define as a signed integer type capable of holding a process identifier. */ #undef pid_t /* Define to rpl_realloc if the replacement function should be used. */ #undef realloc /* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported only directly. */ #undef restrict /* Work around a bug in older versions of Sun C++, which did not #define __restrict__ or support _Restrict or __restrict__ even though the corresponding Sun C compiler ended up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. This workaround can be removed once we assume Oracle Developer Studio 12.5 (2016) or later. */ #if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__ # define _Restrict # define __restrict__ #endif /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if does not define. */ #undef ssize_t /* Define to the type of an unsigned integer type of width exactly 16 bits if such a type exists and the standard includes do not define it. */ #undef uint16_t /* Define to the type of an unsigned integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef uint32_t /* Define to the type of an unsigned integer type of width exactly 64 bits if such a type exists and the standard includes do not define it. */ #undef uint64_t /* Define to the type of an unsigned integer type of width exactly 8 bits if such a type exists and the standard includes do not define it. */ #undef uint8_t /* Define as `fork' if `vfork' does not work. */ #undef vfork /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ #undef volatile #endif thrift-0.23.0/phpcs.xml.dist0000664000175000017500000000135515165535636016202 0ustar00buildbuild00000000000000 The coding standard for thrift. lib/php/lib lib/php/test lib/php/test/packages/* lib/php/test/* lib/php/test/* thrift-0.23.0/jitpack.yml0000664000175000017500000000007615165535636015550 0ustar00buildbuild00000000000000install: - gradle -Prelease=true -p lib/java/ clean install thrift-0.23.0/tutorial/0000755000175000017500000000000015170007202015211 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/go/0000755000175000017500000000000015170007202015616 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/go/src/0000755000175000017500000000000015170007202016405 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/go/src/handler.go0000664000175000017500000000537415165535636020411 0ustar00buildbuild00000000000000package main /* * 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 ( "context" "fmt" "strconv" "github.com/apache/thrift/tutorial/go/gen-go/shared" "github.com/apache/thrift/tutorial/go/gen-go/tutorial" ) type CalculatorHandler struct { log map[int]*shared.SharedStruct } func NewCalculatorHandler() *CalculatorHandler { return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)} } func (p *CalculatorHandler) Ping(ctx context.Context) (err error) { fmt.Print("ping()\n") return nil } func (p *CalculatorHandler) Add(ctx context.Context, num1 int32, num2 int32) (retval17 int32, err error) { fmt.Print("add(", num1, ",", num2, ")\n") return num1 + num2, nil } func (p *CalculatorHandler) Calculate(ctx context.Context, logid int32, w *tutorial.Work) (val int32, err error) { fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n") switch w.Op { case tutorial.Operation_ADD: val = w.Num1 + w.Num2 case tutorial.Operation_SUBTRACT: val = w.Num1 - w.Num2 case tutorial.Operation_MULTIPLY: val = w.Num1 * w.Num2 case tutorial.Operation_DIVIDE: if w.Num2 == 0 { ouch := tutorial.NewInvalidOperation() ouch.WhatOp = int32(w.Op) ouch.Why = "Cannot divide by 0" err = ouch return } val = w.Num1 / w.Num2 default: ouch := tutorial.NewInvalidOperation() ouch.WhatOp = int32(w.Op) ouch.Why = "Unknown operation" err = ouch return } entry := shared.NewSharedStruct() entry.Key = logid entry.Value = strconv.Itoa(int(val)) k := int(logid) /* oldvalue, exists := p.log[k] if exists { fmt.Print("Replacing ", oldvalue, " with ", entry, " for key ", k, "\n") } else { fmt.Print("Adding ", entry, " for key ", k, "\n") } */ p.log[k] = entry return val, err } func (p *CalculatorHandler) GetStruct(ctx context.Context, key int32) (*shared.SharedStruct, error) { fmt.Print("getStruct(", key, ")\n") v := p.log[int(key)] return v, nil } func (p *CalculatorHandler) Zip(ctx context.Context) (err error) { fmt.Print("zip()\n") return nil } thrift-0.23.0/tutorial/go/src/server.go0000664000175000017500000000337315165535636020277 0ustar00buildbuild00000000000000package main /* * 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 ( "crypto/tls" "fmt" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/tutorial/go/gen-go/tutorial" ) func runServer(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory, addr string, secure bool) error { var transport thrift.TServerTransport var err error if secure { cfg := new(tls.Config) if cert, err := tls.LoadX509KeyPair("server.crt", "server.key"); err == nil { cfg.Certificates = append(cfg.Certificates, cert) } else { return err } transport, err = thrift.NewTSSLServerSocket(addr, cfg) } else { transport, err = thrift.NewTServerSocket(addr) } if err != nil { return err } fmt.Printf("%T\n", transport) handler := NewCalculatorHandler() processor := tutorial.NewCalculatorProcessor(handler) server := thrift.NewTSimpleServer4(processor, transport, transportFactory, protocolFactory) fmt.Println("Starting the simple server... on ", addr) return server.Serve() } thrift-0.23.0/tutorial/go/src/main.go0000664000175000017500000000517115165535636017713 0ustar00buildbuild00000000000000package main /* * 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 ( "crypto/tls" "flag" "fmt" "os" "github.com/apache/thrift/lib/go/thrift" ) func Usage() { fmt.Fprint(os.Stderr, "Usage of ", os.Args[0], ":\n") flag.PrintDefaults() fmt.Fprint(os.Stderr, "\n") } func main() { flag.Usage = Usage server := flag.Bool("server", false, "Run server") protocol := flag.String("P", "binary", "Specify the protocol (binary, compact, json, simplejson)") framed := flag.Bool("framed", false, "Use framed transport") buffered := flag.Bool("buffered", false, "Use buffered transport") addr := flag.String("addr", "localhost:9090", "Address to listen to") secure := flag.Bool("secure", false, "Use tls secure transport") flag.Parse() var protocolFactory thrift.TProtocolFactory switch *protocol { case "compact": protocolFactory = thrift.NewTCompactProtocolFactoryConf(nil) case "simplejson": protocolFactory = thrift.NewTSimpleJSONProtocolFactoryConf(nil) case "json": protocolFactory = thrift.NewTJSONProtocolFactory() case "binary", "": protocolFactory = thrift.NewTBinaryProtocolFactoryConf(nil) default: fmt.Fprint(os.Stderr, "Invalid protocol specified", protocol, "\n") Usage() os.Exit(1) } var transportFactory thrift.TTransportFactory cfg := &thrift.TConfiguration{ TLSConfig: &tls.Config{ InsecureSkipVerify: true, }, } if *buffered { transportFactory = thrift.NewTBufferedTransportFactory(8192) } else { transportFactory = thrift.NewTTransportFactory() } if *framed { transportFactory = thrift.NewTFramedTransportFactoryConf(transportFactory, cfg) } if *server { if err := runServer(transportFactory, protocolFactory, *addr, *secure); err != nil { fmt.Println("error running server:", err) } } else { if err := runClient(transportFactory, protocolFactory, *addr, *secure, cfg); err != nil { fmt.Println("error running client:", err) } } } thrift-0.23.0/tutorial/go/src/client.go0000664000175000017500000000540715165535636020247 0ustar00buildbuild00000000000000package main /* * 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 ( "context" "fmt" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/tutorial/go/gen-go/tutorial" ) var defaultCtx = context.Background() func handleClient(client *tutorial.CalculatorClient) (err error) { client.Ping(defaultCtx) fmt.Println("ping()") sum, _ := client.Add(defaultCtx, 1, 1) fmt.Print("1+1=", sum, "\n") work := tutorial.NewWork() work.Op = tutorial.Operation_DIVIDE work.Num1 = 1 work.Num2 = 0 quotient, err := client.Calculate(defaultCtx, 1, work) if err != nil { switch v := err.(type) { case *tutorial.InvalidOperation: fmt.Println("Invalid operation:", v) default: fmt.Println("Error during operation:", err) } } else { fmt.Println("Whoa we can divide by 0 with new value:", quotient) } work.Op = tutorial.Operation_SUBTRACT work.Num1 = 15 work.Num2 = 10 diff, err := client.Calculate(defaultCtx, 1, work) if err != nil { switch v := err.(type) { case *tutorial.InvalidOperation: fmt.Println("Invalid operation:", v) default: fmt.Println("Error during operation:", err) } return err } else { fmt.Print("15-10=", diff, "\n") } log, err := client.GetStruct(defaultCtx, 1) if err != nil { fmt.Println("Unable to get struct:", err) return err } else { fmt.Println("Check log:", log.Value) } return err } func runClient(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory, addr string, secure bool, cfg *thrift.TConfiguration) error { var transport thrift.TTransport if secure { transport = thrift.NewTSSLSocketConf(addr, cfg) } else { transport = thrift.NewTSocketConf(addr, cfg) } transport, err := transportFactory.GetTransport(transport) if err != nil { return err } defer transport.Close() if err := transport.Open(); err != nil { return err } iprot := protocolFactory.GetProtocol(transport) oprot := protocolFactory.GetProtocol(transport) return handleClient(tutorial.NewCalculatorClient(thrift.NewTStandardClient(iprot, oprot))) } thrift-0.23.0/tutorial/go/server.key0000664000175000017500000000325015165535636017665 0ustar00buildbuild00000000000000-----BEGIN PRIVATE KEY----- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCqE9TE9wEXp5LR tLQVDSGQGV78+7ZtP/I/ZaJ6Q6ZGlfxDFvZjFF73seNhAvlKlYm/jflIHYLnNOCy SN8I2Xw6L9MbC+jvwkEKfQo4eDoxZnOZjNF5J1/lZtBeOowMkhhzBMH1Rds351/H jKNg6ZKg2Cldd0j7HbDtEixOLgLbPRpBcaYrLrNMasf3Hal+x8/b8ue28x93HSQB GmZmMIUwAinEu/fNP4lLGl/0kZb76TnyRpYSPYojtS6CnkH+QLYnsRREXJYwD1Xk u62LipkXwCkRTnZ5nUsDMX6FPKgjQFQCWDXG/N096+PRUQAChhrXsJ+gF3NqWtDm trhVQF4nAgMBAAECggEAW/y52YYW6ypROGbZ94DQpFV0kLO7qT8q0Ksxw5sPNaIt fEPRIymDa8ikyHWJS5Oxmw84wo5jnJV26jaLmwe2Lupq7Xf1lqej8f5LJtuv7cQR xfzp1vM65KJFFJHp6WqjGqJ6HSSZOpVDsnQYcXQjQCdpyAmaSWd3p+FqYSZ1mQmD bFNI7jqpczWSZhTdotQ7p7Hn9TVCehflP3yGIB3bQ+wCcCB85dOBz201L+YgaIck Sz43A4NvWaQIRLRDw7s9GW4jY5T0Jv282WIeAlVpVxLIwu48r4R4yGTIx9Ydowvq 57+Y5iPPjAXxu0V9t00oS3bYxDaKh2DUfc/5zowq8QKBgQDYNVPXmaG0aIH4vjQ9 7fRdw/UDkYcQbn6CnglQOu77/S8ogQzpKCVJgJgkZNqOVtQMEPzekGEcLTbje1gU 8Bky2k+PL9UwbFy0emnOVh4rqrNXHsRvJcehNT/PRb5hjF3MUMFV/0iD4b+naFaE jrSWiZ2ZXj2qfwAK52GFbtOuBQKBgQDJYQuGiY0r22E4waJmCSKczoBT3cwlVzWj V2ljgA9RHLNTVkvNNYQLGu2qngFrtwpeaSnsMDerVG4wKAQWyCnYzxVrlnC4uDrJ HXuFEltBWi9Ffbgfsnd3749AT0oBP1NT2tMleguyf5DFgjCR3VRJLdrVaaZ8row/ LqKcFMqnOwKBgB+OIO99l7E584Y3VG6ZdSneOLtNmRXX2pT7tcZE465ZdHGH7Dd3 SYHhx9K/+Xn+yDH+pLli/xlarAEldmSP6k2WuTfftlC78AfTOfAId5zN7CDR9791 Fx67I9X/itq33tS8EIuZl57P6uXm/4GXRloWOa8xpvRkVsBApuYPl8t1AoGATQDS y2sllDObBXzlgGbV2WgNIgSZ311toTv3jJiXQsjauW8yJRHln+l4H9mzaWDgkiFc ang1kUoDqF5k0eFQPxtQcYdhKwEnWWfwp33RbzfxA32DPnubuzzbZhfrkHaKgnIW cyor9uFYlm2l7ODZLfJez2RKyTplXnOSsmQw6akCgYAz3dj9Hskyj+HVJ+ht1OcE c7ai/ESkSA7Vajp0tjJp0EKjW/zq8DvUSXOtcdnJgkKycFluLwbmnaN4txBds1C1 Qr8Rt2sUCCBNZe1L6DHe3XBdbkJe9sgZVNTjtUSQrzy8UhvsCqG4YWeCu07Szcbc rdPUV9/uQkdx8VrShxlD8A== -----END PRIVATE KEY----- thrift-0.23.0/tutorial/go/server.crt0000664000175000017500000000276115165535636017673 0ustar00buildbuild00000000000000-----BEGIN CERTIFICATE----- MIIENzCCAx+gAwIBAgIJAOYfYfw7NCOcMA0GCSqGSIb3DQEBBQUAMIGxMQswCQYD VQQGEwJVUzERMA8GA1UECAwITWFyeWxhbmQxFDASBgNVBAcMC0ZvcmVzdCBIaWxs MScwJQYDVQQKDB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xFjAUBgNV BAsMDUFwYWNoZSBUaHJpZnQxEjAQBgNVBAMMCWxvY2FsaG9zdDEkMCIGCSqGSIb3 DQEJARYVZGV2QHRocmlmdC5hcGFjaGUub3JnMB4XDTE0MDQwNzE4NTgwMFoXDTIy MDYyNDE4NTgwMFowgbExCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNYXJ5bGFuZDEU MBIGA1UEBwwLRm9yZXN0IEhpbGwxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29mdHdh cmUgRm91bmRhdGlvbjEWMBQGA1UECwwNQXBhY2hlIFRocmlmdDESMBAGA1UEAwwJ bG9jYWxob3N0MSQwIgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0LmFwYWNoZS5vcmcw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqE9TE9wEXp5LRtLQVDSGQ GV78+7ZtP/I/ZaJ6Q6ZGlfxDFvZjFF73seNhAvlKlYm/jflIHYLnNOCySN8I2Xw6 L9MbC+jvwkEKfQo4eDoxZnOZjNF5J1/lZtBeOowMkhhzBMH1Rds351/HjKNg6ZKg 2Cldd0j7HbDtEixOLgLbPRpBcaYrLrNMasf3Hal+x8/b8ue28x93HSQBGmZmMIUw AinEu/fNP4lLGl/0kZb76TnyRpYSPYojtS6CnkH+QLYnsRREXJYwD1Xku62LipkX wCkRTnZ5nUsDMX6FPKgjQFQCWDXG/N096+PRUQAChhrXsJ+gF3NqWtDmtrhVQF4n AgMBAAGjUDBOMB0GA1UdDgQWBBQo8v0wzQPx3EEexJPGlxPK1PpgKjAfBgNVHSME GDAWgBQo8v0wzQPx3EEexJPGlxPK1PpgKjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBGFRiJslcX0aJkwZpzTwSUdgcfKbpvNEbCNtVohfQVTI4a/oN5 U+yqDZJg3vOaOuiAZqyHcIlZ8qyesCgRN314Tl4/JQ++CW8mKj1meTgo5YFxcZYm T9vsI3C+Nzn84DINgI9mx6yktIt3QOKZRDpzyPkUzxsyJ8J427DaimDrjTR+fTwD 1Dh09xeeMnSa5zeV1HEDyJTqCXutLetwQ/IyfmMBhIx+nvB5f67pz/m+Dv6V0r3I p4HCcdnDUDGJbfqtoqsAATQQWO+WWuswB6mOhDbvPTxhRpZq6AkgWqv4S+u3M2GO r5p9FrBgavAw5bKO54C0oQKpN/5fta5l6Ws0 -----END CERTIFICATE----- thrift-0.23.0/tutorial/go/Makefile.in0000644000175000017500000004422615170007167017705 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/go ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ GOBUILDEXTRA = -buildvcs=false EXTRA_DIST = \ src/client.go \ src/handler.go \ src/server.go \ src/main.go \ server.crt \ server.key all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/go/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/go/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-go/tutorial/calculator.go gen-go/shared/shared_service.go: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/tutorial/go/gen-go/$(COMPILER_EXTRAFLAG) -r $< all-local: gen-go/tutorial/calculator.go check: thirdparty-dep all $(GO) build $(GOBUILDEXTRA) -o go-tutorial ./src $(GO) build $(GOBUILDEXTRA) -o calculator-remote ./gen-go/tutorial/calculator-remote/calculator-remote.go thirdparty-dep: tutorialserver: all $(GO) run src/*.go -server=true tutorialclient: all $(GO) run src/*.go tutorialsecureserver: all $(GO) run src/*.go -server=true -secure=true tutorialsecureclient: all $(GO) run src/*.go -secure=true clean-local: $(RM) -r gen-* go-tutorial calculator-remote distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/go/Makefile.am0000664000175000017500000000334715165535636017710 0ustar00buildbuild00000000000000# # 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. # GOBUILDEXTRA = -buildvcs=false gen-go/tutorial/calculator.go gen-go/shared/shared_service.go: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/tutorial/go/gen-go/$(COMPILER_EXTRAFLAG) -r $< all-local: gen-go/tutorial/calculator.go check: thirdparty-dep all $(GO) build $(GOBUILDEXTRA) -o go-tutorial ./src $(GO) build $(GOBUILDEXTRA) -o calculator-remote ./gen-go/tutorial/calculator-remote/calculator-remote.go thirdparty-dep: tutorialserver: all $(GO) run src/*.go -server=true tutorialclient: all $(GO) run src/*.go tutorialsecureserver: all $(GO) run src/*.go -server=true -secure=true tutorialsecureclient: all $(GO) run src/*.go -secure=true clean-local: $(RM) -r gen-* go-tutorial calculator-remote distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ src/client.go \ src/handler.go \ src/server.go \ src/main.go \ server.crt \ server.key thrift-0.23.0/tutorial/erl/0000775000175000017500000000000015165535636016022 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/erl/client.sh0000775000175000017500000000233415165535636017641 0ustar00buildbuild00000000000000#!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ERL_THRIFT=../../lib/erl if ! [ -d ${ERL_THRIFT}/ebin ]; then echo "Please build the Thrift library by running \`make' in ${ERL_THRIFT}" exit 1 fi if ! [ -d gen-erl ]; then ../../compiler/cpp/thrift -r --gen erl ../tutorial.thrift fi erlc -I ${ERL_THRIFT}/include -I ${ERL_THRIFT}/ebin \ -I gen-erl -o gen-erl gen-erl/*.erl && erlc -I ${ERL_THRIFT}/include -I gen-erl *.erl && erl +K true -pa ${ERL_THRIFT}/ebin -pa gen-erl thrift-0.23.0/tutorial/erl/client.erl0000664000175000017500000000473315165535636020013 0ustar00buildbuild00000000000000%% %% 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. %% -module(client). -include("calculator_thrift.hrl"). -export([t/0]). p(X) -> io:format("~p~n", [X]), ok. t() -> Port = 9090, {ok, Client0} = thrift_client_util:new("127.0.0.1", Port, calculator_thrift, []), {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []), io:format("ping~n", []), {Client2, {ok, Sum}} = thrift_client:call(Client1, add, [1, 1]), io:format("1+1=~p~n", [Sum]), {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]), io:format("1+4=~p~n", [Sum1]), Work = #'Work'{op=?TUTORIAL_OPERATION_SUBTRACT, num1=15, num2=10}, {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]), io:format("15-10=~p~n", [Diff]), {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]), io:format("Log: ~p~n", [Log]), Client6 = try Work1 = #'Work'{op=?TUTORIAL_OPERATION_DIVIDE, num1=1, num2=0}, {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, [2, Work1]), io:format("LAME: exception handling is broken~n", []), ClientS1 catch throw:{ClientS2, Z} -> io:format("Got exception where expecting - the " ++ "following is NOT a problem!!!~n"), p(Z), ClientS2 end, {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []), io:format("zip~n", []), {_Client8, ok} = thrift_client:close(Client7), ok. thrift-0.23.0/tutorial/erl/server.sh0000775000175000017500000000233415165535636017671 0ustar00buildbuild00000000000000#!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ERL_THRIFT=../../lib/erl if ! [ -d ${ERL_THRIFT}/ebin ]; then echo "Please build the Thrift library by running \`make' in ${ERL_THRIFT}" exit 1 fi if ! [ -d gen-erl ]; then ../../compiler/cpp/thrift -r --gen erl ../tutorial.thrift fi erlc -I ${ERL_THRIFT}/include -I ${ERL_THRIFT}/ebin \ -I gen-erl -o gen-erl gen-erl/*.erl && erlc -I ${ERL_THRIFT}/include -I gen-erl *.erl && erl +K true -pa ${ERL_THRIFT}/ebin -pa gen-erl thrift-0.23.0/tutorial/erl/README.md0000664000175000017500000000031715165535636017302 0ustar00buildbuild00000000000000To try things out, run % ./server.sh Erlang R14B (erts-5.8.1) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.1 (abort with ^G) > server:start(). > client:t(). thrift-0.23.0/tutorial/erl/json_client.erl0000664000175000017500000000614615165535636021044 0ustar00buildbuild00000000000000%% %% Licensed to the Apache Software Foundation (ASF) under one %% or more contributor license agreements. See the NOTICE file %% distributed with this work for additional information %% regarding copyright ownership. The ASF licenses this file %% to you under the Apache License, Version 2.0 (the %% "License"); you may not use this file except in compliance %% with the License. You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% %% The JSON protocol over HTTP implementation was created by %% Peter Neumark based on %% the binary protocol + socket tutorial. Use with the same server %% that the Javascript tutorial uses! -module(json_client). -include("calculator_thrift.hrl"). -export([t/0]). %% Client constructor for the http transports %% with the json protocol new_client(Host, Path, Service, _Options) -> {ProtoOpts, TransOpts} = {[],[]}, TransportFactory = fun() -> thrift_http_transport:new(Host, Path, TransOpts) end, {ok, ProtocolFactory} = thrift_json_protocol:new_protocol_factory( TransportFactory, ProtoOpts), {ok, Protocol} = ProtocolFactory(), thrift_client:new(Protocol, Service). p(X) -> io:format("~p~n", [X]), ok. t() -> inets:start(), {ok, Client0} = new_client("127.0.0.1:8088", "/thrift/service/tutorial/", calculator_thrift, []), {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []), io:format("ping~n", []), {Client2, {ok, Sum}} = thrift_client:call(Client1, add, [1, 1]), io:format("1+1=~p~n", [Sum]), {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]), io:format("1+4=~p~n", [Sum1]), Work = #'Work'{op=?TUTORIAL_OPERATION_SUBTRACT, num1=15, num2=10}, {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]), io:format("15-10=~p~n", [Diff]), {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]), io:format("Log: ~p~n", [Log]), Client6 = try Work1 = #'Work'{op=?TUTORIAL_OPERATION_DIVIDE, num1=1, num2=0}, {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, [2, Work1]), io:format("LAME: exception handling is broken~n", []), ClientS1 catch throw:{ClientS2, Z} -> io:format("Got exception where expecting - the " ++ "following is NOT a problem!!!~n"), p(Z), ClientS2 end, {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []), io:format("zip~n", []), {_Client8, ok} = thrift_client:close(Client7), ok. thrift-0.23.0/tutorial/erl/server.erl0000664000175000017500000000463115165535636020040 0ustar00buildbuild00000000000000%% %% 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. %% -module(server). -include("calculator_thrift.hrl"). -export([start/0, start/1, handle_function/2, stop/1, ping/0, add/2, calculate/2, getStruct/1, zip/0]). debug(Format, Data) -> error_logger:info_msg(Format, Data). ping() -> debug("ping()",[]), ok. add(N1, N2) -> debug("add(~p,~p)",[N1,N2]), N1+N2. calculate(Logid, Work) -> { Op, Num1, Num2 } = { Work#'Work'.op, Work#'Work'.num1, Work#'Work'.num2 }, debug("calculate(~p, {~p,~p,~p})", [Logid, Op, Num1, Num2]), case Op of ?TUTORIAL_OPERATION_ADD -> Num1 + Num2; ?TUTORIAL_OPERATION_SUBTRACT -> Num1 - Num2; ?TUTORIAL_OPERATION_MULTIPLY -> Num1 * Num2; ?TUTORIAL_OPERATION_DIVIDE when Num2 == 0 -> throw(#'InvalidOperation'{whatOp=Op, why="Cannot divide by 0"}); ?TUTORIAL_OPERATION_DIVIDE -> Num1 div Num2; _Else -> throw(#'InvalidOperation'{whatOp=Op, why="Invalid operation"}) end. getStruct(Key) -> debug("getStruct(~p)", [Key]), #'SharedStruct'{key=Key, value="RARG"}. zip() -> debug("zip", []), ok. %% start() -> start(9090). start(Port) -> Handler = ?MODULE, thrift_socket_server:start([{handler, Handler}, {service, calculator_thrift}, {port, Port}, {name, tutorial_server}]). stop(Server) -> thrift_socket_server:stop(Server). handle_function(Function, Args) when is_atom(Function), is_tuple(Args) -> case apply(?MODULE, Function, tuple_to_list(Args)) of ok -> ok; Reply -> {reply, Reply} end. thrift-0.23.0/tutorial/swift/0000755000175000017500000000000015170007202016345 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/0000755000175000017500000000000015170007201020246 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/0000775000175000017500000000000015165535636022572 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Package.swift0000664000175000017500000000572715165535636025216 0ustar00buildbuild00000000000000// swift-tools-version:5.5 // 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: "ThriftFuzzTesting", dependencies: [ .package(name: "Thrift", path: "../") ], targets: [ // Generated code from Thrift definitions .target( name: "Fuzz", dependencies: ["Thrift"], path: "Sources/Fuzz" ), // Common utilities for fuzzing .target( name: "FuzzCommon", dependencies: ["Thrift", "Fuzz"], path: "Sources/FuzzCommon" ), .executableTarget( name: "FuzzParseBinary", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzParseBinary", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzRoundtripBinary", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzRoundtripBinary", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzParseCompact", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzParseCompact", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzRoundtripCompact", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzRoundtripCompact", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzParseJSON", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzParseJSON", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzRoundtripJSON", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzRoundtripJSON", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ) ] ) thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/README.md0000664000175000017500000000122215165535636024046 0ustar00buildbuild00000000000000# Swift Fuzzing README The Swift Thrift implementation uses LLVM's libFuzzer for fuzzing. ## Fuzzer Structure We currently have several fuzz targets that test different aspects of the Thrift implementation: * FuzzParseBinary -- Tries to deserialize the code-generated FuzzTest struct from arbitrary input data using the binary protocol * FuzzRoundtripBinary -- Tries to deserialize a FuzzTest struct and then tests roundtrip serialization/deserialization with the binary protocol * FuzzParseCompact * FuzzRoundtripCompact * FuzzParseJSON * FuzzRoundtripJSON The fuzzers need a dummy main() to ensure that compilation in non-fuzzer modes doesn't regress.thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/0000775000175000017500000000000015165535636024215 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzParseBinary/0000775000175000017500000000000015165535636027313 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzParseBinary/main.swift0000664000175000017500000000224215165535636031315 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { _ = parseObjectWithProtocol(start: start, count: count, protocolType: TBinaryProtocol.self) return 0 } @main public struct FuzzParseBinary { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } }thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzRoundtripJSON/0000775000175000017500000000000015165535636027554 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzRoundtripJSON/main.swift0000664000175000017500000000226615165535636031564 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { return roundtripWithProtocol( start: start, count: count, protocolType: TJSONProtocol.self ) } @main public struct FuzzRoundtripJSON { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } } thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzRoundtripBinary/0000775000175000017500000000000015165535636030227 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzRoundtripBinary/main.swift0000664000175000017500000000227015165535636032232 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { return roundtripWithProtocol( start: start, count: count, protocolType: TBinaryProtocol.self ) } @main public struct FuzzRoundtripBinary { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } }thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzRoundtripCompact/0000775000175000017500000000000015165535636030371 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzRoundtripCompact/main.swift0000664000175000017500000000227215165535636032376 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { return roundtripWithProtocol( start: start, count: count, protocolType: TCompactProtocol.self ) } @main public struct FuzzRoundtripCompact { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } }thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzParseJSON/0000775000175000017500000000000015165535636026640 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzParseJSON/main.swift0000664000175000017500000000223715165535636030646 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { _ = parseObjectWithProtocol(start: start, count: count, protocolType: TJSONProtocol.self) return 0 } @main public struct FuzzParseJSON { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } } thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzCommon/0000775000175000017500000000000015165535636026324 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzCommon/FuzzUtils.swift0000664000175000017500000001011115165535636031353 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. import Foundation import Thrift import Fuzz /// Generic parser that returns a parsed object from binary data - for use as a converter public func parseObjectWithProtocol( start: UnsafeRawPointer, count: Int, protocolType: P.Type) -> Fuzz.FuzzTest? { let data = Data(bytes: start, count: count) let transport = TMemoryBufferTransport(readBuffer: data) let proto = P(on: transport) do { return try Fuzz.FuzzTest.read(from: proto) } catch { return nil } } /// Test roundtrip serialization/deserialization with the specified protocol and conversion function public func roundtripWithProtocol( start: UnsafeRawPointer, count: Int, protocolType: P.Type ) -> Int32 { // Try to convert data to a test object guard let testObj = parseObjectWithProtocol(start: start, count: count, protocolType: protocolType) else { return 0 } // Now do a roundtrip test with the converted object do { // Serialize let writeTransport = TMemoryBufferTransport() let writeProto = P(on: writeTransport) try testObj.write(to: writeProto) try writeTransport.flush() // Deserialize let readTransport = TMemoryBufferTransport(readBuffer: writeTransport.writeBuffer) let readProto = P(on: readTransport) let deserialized = try Fuzz.FuzzTest.read(from: readProto) // This should always be true, but we check just to be sure guard deserialized == testObj else { fatalError("Roundtrip test failed: objects not equal after serialization/deserialization") } } catch { // Catch expected exceptions } return 0 } /// Typedef for the fuzzer function signature required by libFuzzer public typealias FuzzTarget = @convention(c) (UnsafeRawPointer, Int) -> Int32 // Import the libFuzzer driver function @_silgen_name("LLVMFuzzerRunDriver") public func LLVMFuzzerRunDriver( _ argc: UnsafeMutablePointer, _ argv: UnsafeMutablePointer>>, _ userCb: @escaping @convention(c) (UnsafeRawPointer, Int) -> Int32) -> Int32 // Run the libFuzzer driver with the given test function // We use this to get around swift compilation issues, which create main functions that otherwise // conflict with the libfuzzer main. // See more documentation here: https://llvm.org/docs/LibFuzzer.html#using-libfuzzer-as-a-library public func runLibFuzzerDriver(testOneInput: @escaping FuzzTarget) -> Never { // Create C-style arguments to pass to LLVMFuzzerRunDriver var args = CommandLine.arguments.map { strdup($0) } var argc = Int32(args.count) var argv = args.map { UnsafeMutablePointer($0!) } let argvPtr = UnsafeMutablePointer>.allocate(capacity: args.count) argvPtr.initialize(from: &argv, count: args.count) let argvPtrPtr = UnsafeMutablePointer>>.allocate(capacity: 1) argvPtrPtr.pointee = argvPtr // Start the fuzzer engine with our test function let result = LLVMFuzzerRunDriver(&argc, argvPtrPtr, testOneInput) // Clean up argvPtrPtr.deallocate() argvPtr.deallocate() exit(Int32(result)) } thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzParseCompact/0000775000175000017500000000000015165535636027455 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/FuzzTesting/Sources/FuzzParseCompact/main.swift0000664000175000017500000000224515165535636031462 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { _ = parseObjectWithProtocol(start: start, count: count, protocolType: TCompactProtocol.self) return 0 } @main public struct FuzzParseCompact { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/0000775000175000017500000000000015167543515021375 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/0000775000175000017500000000000015170007142023641 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/TFramedTransportTests.swift0000664000175000017500000001327715165535636031235 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift /// Testig TFramedTransport /// class TFramedTransportTests: XCTestCase { var underlyingTransport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TBinaryProtocol! var transport: TFramedTransport! override func setUp() { super.setUp() transport = TFramedTransport(transport:underlyingTransport) proto = TBinaryProtocol(on: transport) underlyingTransport.reset() } override func tearDown() { super.tearDown() underlyingTransport.reset() } func testInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String! do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try? transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readVal.message) got \(writeVal.message)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testUnsafeBitcastUpdate() { let value: Double = 3.14159 let val: Int64 = 31415926 let uval: UInt64 = 31415926 let i64 = Int64(bitPattern: value.bitPattern) let ubc = unsafeBitCast(value, to: Int64.self) XCTAssertEqual(i64, ubc, "Bitcast Double-> i64 Values don't match") let dbl = Double(bitPattern: UInt64(val)) let ubdb = unsafeBitCast(val, to: Double.self) XCTAssertEqual(dbl, ubdb, "Bitcast i64 -> Double Values don't match") let db2 = Double(bitPattern: uval) let usbc2 = unsafeBitCast(uval, to: Double.self) XCTAssertEqual(db2, usbc2, "Bitcast u64 -> Double Values don't match") } static var allTests : [(String, (TFramedTransportTests) -> () throws -> Void)] { return [ ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testDataWriteRead", testDataWriteRead), ("testStructWriteRead", testStructWriteRead), ("testUnsafeBitcastUpdate", testUnsafeBitcastUpdate) ] } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/TSocketServerTests.swift0000664000175000017500000000335515165535636030535 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift private protocol CalculatorService { } private class Calculator: CalculatorService { } private class CalculatorProcessor: TProcessor { private let service: CalculatorService init(service: CalculatorService) { self.service = service } var processCalled = false func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { processCalled = true } } class TSocketServerTests: XCTestCase { func testInit() throws { let service: CalculatorService = Calculator() let processor: CalculatorProcessor = CalculatorProcessor(service: service) let _: TSocketServer = try TSocketServer(port: 9090, inProtocol: TBinaryProtocol.self, outProtocol: TBinaryProtocol.self, processor: processor) } static var allTests : [(String, (TSocketServerTests) -> () throws -> Void)] { return [ ("testInit", testInit), ] } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/TMultiplexedProcessorTests.swift0000664000175000017500000001321215165535636032303 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift private protocol CalculatorService { } private class Calculator: CalculatorService { } private class CalculatorProcessor: TProcessor { private let service: CalculatorService init(service: CalculatorService) { self.service = service } var processCalled = false func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { processCalled = true } } class TMultiplexedProcessorTests: XCTestCase { let sut = MultiplexedProcessor() var transport: TMemoryBufferTransport = TMemoryBufferTransport { $0.reset(readBuffer: $1) } lazy var proto = TMultiplexedProtocol(on: transport) override func setUp() { super.setUp() transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testExceptionMessageThrowsError() throws { try proto.writeMessageBegin(name: "message", type: .exception, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.incompatibleMessageType(let type) = error else { XCTFail() return } XCTAssertEqual(type, .exception) } } func testReplyMessageThrowsError() throws { try proto.writeMessageBegin(name: "message", type: .reply, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.incompatibleMessageType(let type) = error else { XCTFail() return } XCTAssertEqual(type, .reply) } } func testMissingDefaultProcessorThrowsError() throws { try proto.writeMessageBegin(name: "message", type: .call, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.missingDefaultProcessor = error else { XCTFail() return } } } func testUsesDefaultProcessorForNonMultiplexedMessage() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(defaultProcessor: calculatorProcessor) try proto.writeMessageBegin(name: "message", type: .call, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) XCTAssertTrue(calculatorProcessor.processCalled) } func testUsesProcessorForMultiplexedMessage() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(processor: calculatorProcessor, for: "Calculator") try proto.writeMessageBegin(name: "Calculator:message", type: .call, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) XCTAssertTrue(calculatorProcessor.processCalled) } func testMissingProcessorForMultiplexedMessageThrowsError() throws { try proto.writeMessageBegin(name: "Calculator:message", type: .call, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.missingProcessor(let serviceName) = error else { XCTFail() return } XCTAssertEqual(serviceName, "Calculator") } } func testCallMessageDoesNotThrowError() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(defaultProcessor: calculatorProcessor) try proto.writeMessageBegin(name: "message", type: .call, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) } func testOneWayMessageDoesNotThrowError() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(defaultProcessor: calculatorProcessor) try proto.writeMessageBegin(name: "message", type: .oneway, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) } static var allTests : [(String, (TMultiplexedProcessorTests) -> () throws -> Void)] { return [ ("testExceptionMessageThrowsError", testExceptionMessageThrowsError), ("testReplyMessageThrowsError", testReplyMessageThrowsError), ("testMissingDefaultProcessorThrowsError", testMissingDefaultProcessorThrowsError), ("testUsesDefaultProcessorForNonMultiplexedMessage", testUsesDefaultProcessorForNonMultiplexedMessage), ("testUsesProcessorForMultiplexedMessage", testUsesProcessorForMultiplexedMessage), ("testMissingProcessorForMultiplexedMessageThrowsError", testMissingProcessorForMultiplexedMessageThrowsError), ("testCallMessageDoesNotThrowError", testCallMessageDoesNotThrowError), ("testOneWayMessageDoesNotThrowError", testOneWayMessageDoesNotThrowError) ] } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/ThriftTests.swift0000664000175000017500000000207515170007142027206 0ustar00buildbuild00000000000000/* * 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 XCTest @testable import Thrift class ThriftTests: XCTestCase { func testVersion() { XCTAssertEqual(Thrift().version, "0.23.0") } static var allTests : [(String, (ThriftTests) -> () throws -> Void)] { return [ ("testVersion", testVersion), ] } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/TJSONProtocolTests.swift0000664000175000017500000001724615165535636030415 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift class TJSONProtocolTests: XCTestCase { var transport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TJSONProtocol! override func setUp() { super.setUp() proto = TJSONProtocol(on: transport) transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testUInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt8WriteRead() { let writeVal: Int8 = -120 try? proto.write(writeVal) try? transport.flush() let readVal: Int8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead2() { let writeVal: String = "你好世界 means hello world!" try? proto.write(writeVal) try? transport.flush() let readVal: String do { print(writeVal) readVal = try proto.read() print(readVal) } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testUUIDWriteRead() { let writeVal: UUID = UUID() try? proto.write(writeVal) try? transport.flush() let newUuid = UUID() let readVal: UUID = (try? proto.read()) ?? newUuid XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try? transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal: TApplicationError = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") let readValMessage = readVal.message ?? "", writeValMessage = writeVal.message ?? "" XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readValMessage) got \(writeValMessage)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testBase64WriteRead() { let writeText = "!testing base64 read and write ..." let writeData = writeText.data(using: .utf8)! let writeVal = [UInt8](writeData) try? proto.writeJsonBase64(bytes: writeVal) try? transport.flush() var data = Data() if let readVal = try? proto.readJsonBase64() { data = Data(bytes: readVal, count: readVal.count) } let readText = String(decoding: data, as: UTF8.self) XCTAssertEqual(readText, writeText, "Error message mismatch, expected \(readText) got \(writeText)") } func testBase64WriteRead2() { let writeText = "你好世界 means hello world!" let writeData = writeText.data(using: .utf8)! let writeVal = [UInt8](writeData) try? proto.writeJsonBase64(bytes: writeVal) try? transport.flush() var data = Data() if let readVal = try? proto.readJsonBase64() { data = Data(bytes: readVal, count: readVal.count) } let readText = String(decoding: data, as: UTF8.self) XCTAssertEqual(readText, writeText, "Error message mismatch, expected \(readText) got \(writeText)") } static var allTests : [(String, (TJSONProtocolTests) -> () throws -> Void)] { return [ ("testUInt8WriteRead", testUInt8WriteRead), ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testStringWriteRead2", testStringWriteRead2), ("testDataWriteRead", testDataWriteRead), ("testUUIDWriteRead", testUUIDWriteRead), ("testStructWriteRead", testStructWriteRead), ("testBase64WriteRead", testBase64WriteRead), ("testBase64WriteRead2", testBase64WriteRead2) ] } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/TBinaryProtocolTests.swift0000664000175000017500000001347315167543515031063 0ustar00buildbuild00000000000000/* * 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. */ // // TBinaryProtocolTests.swift // Thrift // // Created by Christopher Simpson on 8/18/16. // // import XCTest import Foundation @testable import Thrift /// Testing Binary protocol read/write against itself /// Uses separate read/write transport/protocols class TBinaryProtocolTests: XCTestCase { var transport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TBinaryProtocol! override func setUp() { super.setUp() proto = TBinaryProtocol(on: transport) transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String! do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try? transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readVal.message) got \(writeVal.message)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testUnsafeBitcastUpdate() { let value: Double = 3.14159 let val: Int64 = 31415926 let uval: UInt64 = 31415926 let i64 = Int64(bitPattern: value.bitPattern) let ubc = unsafeBitCast(value, to: Int64.self) XCTAssertEqual(i64, ubc, "Bitcast Double-> i64 Values don't match") let dbl = Double(bitPattern: UInt64(val)) let ubdb = unsafeBitCast(val, to: Double.self) XCTAssertEqual(dbl, ubdb, "Bitcast i64 -> Double Values don't match") let db2 = Double(bitPattern: uval) let usbc2 = unsafeBitCast(uval, to: Double.self) XCTAssertEqual(db2, usbc2, "Bitcast u64 -> Double Values don't match") } static var allTests : [(String, (TBinaryProtocolTests) -> () throws -> Void)] { return [ ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testDataWriteRead", testDataWriteRead), ("testStructWriteRead", testStructWriteRead), ("testUnsafeBitcastUpdate", testUnsafeBitcastUpdate) ] } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/ThriftTests/TCompactProtocolTests.swift0000664000175000017500000001775215167543515031231 0ustar00buildbuild00000000000000/* * 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. */ // // TCompactProtocolTests.swift // Thrift // // Created by Christopher Simpson on 8/19/16. // // import XCTest import Foundation @testable import Thrift /// Testing Binary protocol read/write against itself /// Uses separate read/write transport/protocols class TCompactProtocolTests: XCTestCase { var transport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TCompactProtocol! override func setUp() { super.setUp() proto = TCompactProtocol(on: transport) transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String! do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readVal.message) got \(writeVal.message)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testInt32ZigZag() { let zero: Int32 = 0 let one: Int32 = 1 let nOne: Int32 = -1 let two: Int32 = 2 let nTwo: Int32 = -2 let max = Int32.max let min = Int32.min XCTAssertEqual(proto.i32ToZigZag(zero), UInt32(0), "Error 32bit zigzag on \(zero)") XCTAssertEqual(proto.zigZagToi32(0), zero, "Error 32bit zigzag on \(zero)") XCTAssertEqual(proto.i32ToZigZag(nOne), UInt32(1), "Error 32bit zigzag on \(nOne)") XCTAssertEqual(proto.zigZagToi32(1), nOne, "Error 32bit zigzag on \(nOne)") XCTAssertEqual(proto.i32ToZigZag(one), UInt32(2), "Error 32bit zigzag on \(one)") XCTAssertEqual(proto.zigZagToi32(2), one, "Error 32bit zigzag on \(one)") XCTAssertEqual(proto.i32ToZigZag(nTwo), UInt32(3), "Error 32bit zigzag on \(nTwo)") XCTAssertEqual(proto.zigZagToi32(3), nTwo, "Error 32bit zigzag on \(nTwo)") XCTAssertEqual(proto.i32ToZigZag(two), UInt32(4), "Error 32bit zigzag on \(two)") XCTAssertEqual(proto.zigZagToi32(4), two, "Error 32bit zigzag on \(two)") let uMaxMinusOne: UInt32 = UInt32.max - 1 XCTAssertEqual(proto.i32ToZigZag(max), uMaxMinusOne, "Error 32bit zigzag on \(max)") XCTAssertEqual(proto.zigZagToi32(uMaxMinusOne), max, "Error 32bit zigzag on \(max)") XCTAssertEqual(proto.i32ToZigZag(min), UInt32.max, "Error 32bit zigzag on \(min)") XCTAssertEqual(proto.zigZagToi32(UInt32.max), min, "Error 32bit zigzag on \(min)") } func testInt64ZigZag() { let zero: Int64 = 0 let one: Int64 = 1 let nOne: Int64 = -1 let two: Int64 = 2 let nTwo: Int64 = -2 let max = Int64.max let min = Int64.min XCTAssertEqual(proto.i64ToZigZag(zero), UInt64(0), "Error 64bit zigzag on \(zero)") XCTAssertEqual(proto.zigZagToi64(0), zero, "Error 64bit zigzag on \(zero)") XCTAssertEqual(proto.i64ToZigZag(nOne), UInt64(1), "Error 64bit zigzag on \(nOne)") XCTAssertEqual(proto.zigZagToi64(1), nOne, "Error 64bit zigzag on \(nOne)") XCTAssertEqual(proto.i64ToZigZag(one), UInt64(2), "Error 64bit zigzag on \(one)") XCTAssertEqual(proto.zigZagToi64(2), one, "Error 64bit zigzag on \(one)") XCTAssertEqual(proto.i64ToZigZag(nTwo), UInt64(3), "Error 64bit zigzag on \(nTwo)") XCTAssertEqual(proto.zigZagToi64(3), nTwo, "Error 64bit zigzag on \(nTwo)") XCTAssertEqual(proto.i64ToZigZag(two), UInt64(4), "Error 64bit zigzag on \(two)") XCTAssertEqual(proto.zigZagToi64(4), two, "Error 64bit zigzag on \(two)") let uMaxMinusOne: UInt64 = UInt64.max - 1 XCTAssertEqual(proto.i64ToZigZag(max), uMaxMinusOne, "Error 64bit zigzag on \(max)") XCTAssertEqual(proto.zigZagToi64(uMaxMinusOne), max, "Error 64bit zigzag on \(max)") XCTAssertEqual(proto.i64ToZigZag(min), UInt64.max, "Error 64bit zigzag on \(min)") XCTAssertEqual(proto.zigZagToi64(UInt64.max), min, "Error 64bit zigzag on \(min)") } static var allTests : [(String, (TCompactProtocolTests) -> () throws -> Void)] { return [ ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testDataWriteRead", testDataWriteRead), ("testStructWriteRead", testStructWriteRead), ("testInt32ZigZag", testInt32ZigZag), ("testInt64ZigZag", testInt64ZigZag) ] } } thrift-0.23.0/tutorial/swift/swift-dep/Tests/LinuxMain.swift0000664000175000017500000000174015167543515024361 0ustar00buildbuild00000000000000/* * 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 XCTest @testable import ThriftTests XCTMain([ testCase(ThriftTests.allTests), testCase(TBinaryProtocolTests.allTests), testCase(TCompactProtocolTests.allTests), ]) thrift-0.23.0/tutorial/swift/swift-dep/Package.swift0000664000175000017500000000211115165535636022702 0ustar00buildbuild00000000000000// 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: "Sources"), .testTarget(name: "ThriftTests", dependencies: ["Thrift"]) ] ) thrift-0.23.0/tutorial/swift/swift-dep/README.md0000664000175000017500000002034615165535636021562 0ustar00buildbuild00000000000000Thrift Swift Library ========================= License ------- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ## Build swift build ## Test swift test ## Install Library ##### Cocoapods Add the following to your podfile ```ruby pod 'Thrift-swift3', :git => 'git@github.com:apache/thrift.git', :branch => 'master' ``` ##### SPM Unfortunately due to some limitations in SPM, the Package manifest and Sources directory must be at the root of the project. To get around that for the time being, you can use this mirrored repo. Add the following to your Package.swift ```swift dependencies: [ .Package(url: "https://github.com/apocolipse/Thrift-Swift.git", majorVersion: 1) ] ``` ## Thrift Compiler You can compile IDL sources for Swift 3 with the following command: thrift --gen swift thrift_file ## Client Example ```swift let transport = TSocketTransport(hostname: "localhost", port: 9090)! // var proto = TCompactProtocol(transport: transport) let proto = TBinaryProtocol(on: transport) // var client = HermesClient(inoutProtocol: proto) let client = ThriftTestClient(inoutProtocol: proto) do { try client.testVoid() } catch let error { print("\(error)") } ``` ## Library Notes - Eliminated Protocol Factories, They were only used in async clients and server implementations, where Generics provide a better alternative. - Swifty Errors, All `TError` types have a nested `ErrorCode` Enum as well as some extra flavor where needed. - Value typed everything. `TTransport` operates on value typed `Data` rather than reference typed `NSData` or `UnsafeBufferPointer`s - Swift 3 Named protocols. Swift 3 naming conventions suggest the elimination of redundant words that can be inferred from variable/function signatures. This renaming is applied throughout the Swift 3 library converting most naming conventions used in the Swift2/Cocoa library to Swift 3-esque naming conventions. eg. ```swift func readString() throws -> String func writeString(_ val: String) throws ``` have been renamed to eliminate redundant words: ```swift func read() throws -> String func write(_ val: String) throws ``` - Eliminated `THTTPTransport` that uses `NSURLConnection` due to it being deprecated and not available at all in Swift 3 for Linux. `THTTPSessionTransport` from the Swift2/Cocoa library that uses `NSURLSession` has been renamed to `THTTPTransport` for this library and leverages `URLSession`, providing both synchronous (with semaphores) and asynchronous behavior. - Probably some More things I've missed here. ## Generator Notes #### Generator Flags | Flag | Description | | ------------- |:-------------:| | async_clients | Generate clients which invoke asynchronously via block syntax. Asynchronous classes are appended with `_Async` | | no_strict* | Generates non-strict structs | | debug_descriptions | Allow use of debugDescription so the app can add description via a cateogory/extension | | log_unexpected | Log every time an unexpected field ID or type is encountered. | | safe_enums | Generate enum types with an unknown case to handle unspecified values rather than throw a serialization error | *Most thrift libraries allow empty initialization of Structs, initializing `required` fields with nil/null/None (Python and Node generators). Swift on the other hand requires initializers to initialize all non-Optional fields, and thus the Swift 3 generator does not provide default values (unlike the Swift 2/Cocoa generator). In other languages, this allows the sending of NULL values in fields that are marked `required`, and thus will throw an error in Swift clients attempting to validate fields. The `no_strict` option here will ignore the validation check, as well as behave similar to the Swift2/Cocoa generator and initialize required fields with empty initializers (where possible). ## Whats implemented #### Library ##### Transports - [x] TSocketTransport - CFSocket and PosixSocket variants available. CFSocket variant only currently available for Darwin platforms - [x] THTTPTransport - Currently only available for Darwin platforms, Swift Foundation URLSession implementation needs completion on linux. - [x] TSocketServer - Uses CFSockets only for binding, should be working on linux - [x] TFramedTransport - [x] TMemoryBufferTransport - [x] TFileTransport - A few variants using File handles and file descriptors. - [x] TStreamTransport - Fully functional in Darwin, Foundation backing not yet completed in Linux (This limits TCFSocketTransport to Darwin) - [ ] HTTPServer - Currently there is no lightweight HTTPServer implementation the Swift Standard Library, so other 3rd party alternatives are required and out of scope for the Thrift library. Examples using Perfect will be provided. - [ ] Other (gz, etc) ##### Protocols - [x] TBinaryProtocol - [x] TCompactProtocol - [x] TJSONProtocol ##### Generator - [x] Code Complete Generator - [x] Async clients - [x] Documentation Generation - Generator will transplant IDL docs to Swift code for easy lookup in Xcode - [ ] Default Values - TODO - [ ] no_strict mode - TODO - [ ] Namespacing - Still haven't nailed down a good paradigm for namespacing. It will likely involve creating subdirectories for different namespaces and expecting the developer to import each subdirectory as separate modules. It could extend to creating SPM Package manifests with sub-modules within the generated module ## Example HTTP Server with Perfect ```swift import PerfectLib import PerfectHTTP import PerfectHTTPServer import Dispatch let logQueue = DispatchQueue(label: "log", qos: .background, attributes: .concurrent) let pQueue = DispatchQueue(label: "log", qos: .userInitiated, attributes: .concurrent) class TPerfectServer { private var server = HTTPServer() private var processor: TProcessor init(address: String? = nil, path: String? = nil, port: Int, processor: TProcessor, inProtocol: InProtocol.Type, outProtocol: OutProtocol.Type) throws { self.processor = processor if let address = address { server.serverAddress = address } server.serverPort = UInt16(port) var routes = Routes() var uri = "/" if let path = path { uri += path } routes.add(method: .post, uri: uri) { request, response in pQueue.async { response.setHeader(.contentType, value: "application/x-thrift") let itrans = TMemoryBufferTransport() if let bytes = request.postBodyBytes { let data = Data(bytes: bytes) itrans.reset(readBuffer: data) } let otrans = TMemoryBufferTransport(flushHandler: { trans, buff in let array = buff.withUnsafeBytes { Array(UnsafeBufferPointer(start: $0, count: buff.count)) } response.status = .ok response.setBody(bytes: array) response.completed() }) let inproto = InProtocol(on: itrans) let outproto = OutProtocol(on: otrans) do { try processor.process(on: inproto, outProtocol: outproto) try otrans.flush() } catch { response.status = .badRequest response.completed() } } } server.addRoutes(routes) } func serve() throws { try server.start() } } ``` #### Example Usage ```swift class ServiceHandler : Service { ... } let server = try? TPerfectServer(port: 9090, processor: ServiceProcessor(service: ServiceHandler()), inProtocol: TBinaryProtocol.self, outProtocol: TBinaryProtocol.self) try? server?.serve() ``` thrift-0.23.0/tutorial/swift/swift-dep/Sources/0000775000175000017500000000000015170007142021677 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/swift-dep/Sources/TSocketTransport.swift0000664000175000017500000001566315165535636026303 0ustar00buildbuild00000000000000 /* * 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. */ #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc import Dispatch #endif import Foundation import CoreFoundation #if !swift(>=4.2) // Swift 3/4 compatibility fileprivate extension RunLoopMode { static let `default` = defaultRunLoopMode } #endif private struct Sys { #if os(Linux) static let read = Glibc.read static let write = Glibc.write static let close = Glibc.close #else static let read = Darwin.read static let write = Darwin.write static let close = Darwin.close #endif } extension in_addr { public init?(hostent: hostent?) { guard let host = hostent, host.h_addr_list != nil, host.h_addr_list.pointee != nil else { return nil } self.init() memcpy(&self, host.h_addr_list.pointee!, Int(host.h_length)) } } #if os(Linux) /// TCFSocketTransport currently unavailable /// remove comments and build to see why/fix /// currently CF[Read|Write]Stream's can't cast to [Input|Output]Streams which breaks thigns #else extension Stream.PropertyKey { static let SSLPeerTrust = Stream.PropertyKey(kCFStreamPropertySSLPeerTrust as String) } /// TCFSocketTransport, uses CFSockets and (NS)Stream's public class TCFSocketTransport: TStreamTransport { public init?(hostname: String, port: Int, secure: Bool = false) { var inputStream: InputStream var outputStream: OutputStream var readStream: Unmanaged? var writeStream: Unmanaged? CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostname as CFString, UInt32(port), &readStream, &writeStream) if let readStream = readStream?.takeRetainedValue(), let writeStream = writeStream?.takeRetainedValue() { CFReadStreamSetProperty(readStream, .shouldCloseNativeSocket, kCFBooleanTrue) CFWriteStreamSetProperty(writeStream, .shouldCloseNativeSocket, kCFBooleanTrue) if secure { CFReadStreamSetProperty(readStream, .socketSecurityLevel, StreamSocketSecurityLevel.negotiatedSSL.rawValue as CFString) CFWriteStreamSetProperty(writeStream, .socketSecurityLevel, StreamSocketSecurityLevel.negotiatedSSL.rawValue as CFString) } inputStream = readStream as InputStream inputStream.schedule(in: .current, forMode: .default) inputStream.open() outputStream = writeStream as OutputStream outputStream.schedule(in: .current, forMode: .default) outputStream.open() } else { if readStream != nil { readStream?.release() } if writeStream != nil { writeStream?.release() } super.init(inputStream: nil, outputStream: nil) return nil } super.init(inputStream: inputStream, outputStream: outputStream) self.input?.delegate = self self.output?.delegate = self } } extension TCFSocketTransport: StreamDelegate { } #endif /// TSocketTransport, posix sockets. Supports IPv4 only for now public class TSocketTransport : TTransport { public var socketDescriptor: Int32 /// Initialize from an already set up socketDescriptor. /// Expects socket thats already bound/connected (i.e. from listening) /// /// - parameter socketDescriptor: posix socket descriptor (Int32) public init(socketDescriptor: Int32) { self.socketDescriptor = socketDescriptor } public convenience init(hostname: String, port: Int) throws { guard let hp = gethostbyname(hostname.cString(using: .utf8)!)?.pointee, let hostAddr = in_addr(hostent: hp) else { throw TTransportError(error: .unknown, message: "Invalid address: \(hostname)") } #if os(Linux) let sock = socket(AF_INET, Int32(SOCK_STREAM.rawValue), 0) var addr = sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: in_port_t(htons(UInt16(port))), sin_addr: hostAddr, sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #else let sock = socket(AF_INET, SOCK_STREAM, 0) var addr = sockaddr_in(sin_len: UInt8(MemoryLayout.size), sin_family: sa_family_t(AF_INET), sin_port: in_port_t(htons(UInt16(port))), sin_addr: hostAddr, sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #endif let addrPtr = withUnsafePointer(to: &addr){ UnsafePointer(OpaquePointer($0)) } let connected = connect(sock, addrPtr, UInt32(MemoryLayout.size)) if connected != 0 { throw TTransportError(error: .notOpen, message: "Error binding to host: \(hostname) \(port)") } self.init(socketDescriptor: sock) } public convenience init(path: String) throws { let socket = UnixSocket(path: path) let errno = socket.connect() guard errno == 0 else { throw TTransportError(error: .notOpen, message: "Error binding to socket at path: \(path). Errno: \(errno)") } self.init(socketDescriptor: socket.fd) } deinit { close() } public func readAll(size: Int) throws -> Data { var out = Data() while out.count < size { out.append(try self.read(size: size)) } return out } public func read(size: Int) throws -> Data { var buff = Array.init(repeating: 0, count: size) let readBytes = Sys.read(socketDescriptor, &buff, size) return Data(buff[0.. 0 { let written = writeBuffer.withUnsafeBytes { Sys.write(socketDescriptor, $0.baseAddress!, writeBuffer.count) } writeBuffer = writeBuffer.subdata(in: written ..< writeBuffer.count) bytesToWrite -= written } } public func flush() throws { // nothing to do } public func close() { shutdown(socketDescriptor, Int32(SHUT_RDWR)) _ = Sys.close(socketDescriptor) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TJSONProtocol.swift0000664000175000017500000011363715165535636025431 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation /** JSON protocol implementation for thrift. This is a full-feature protocol supporting Write and Read. Please see the C++ class header for a detailed description of the protocol's wire format Adapted from netstd C# version */ public class TJSONProtocol: TProtocol { static let Version: Int = 1 public var transport: TTransport // Temporary buffer used by several methods private var tempBuffer: [UInt8] = [0,0,0,0] private var contextStack: JSONContextStack = JSONContextStack() private var currentContext: JSONBaseContext? private var context: JSONBaseContext { get throws { if (currentContext != nil) { return currentContext! } throw TProtocolError(error: .depthLimit, message: "Current context is nil") } } /** Reader that manages a 1-byte buffer */ private var optionalReader: LookaheadReader? private var reader: LookaheadReader { get throws { if (optionalReader != nil) { return optionalReader! } throw TProtocolError(error: .depthLimit, message: "Lookahead reader is nil") } } // MARK: TJSONProtocol Constructor public required init(on transport: TTransport) { self.transport = transport currentContext = JSONBaseContext(on: self) optionalReader = LookaheadReader(on: self) } // MARK: TJSONProtocol helpers /** Push a new JSON context onto the context stack */ func pushContext(_ context: JSONBaseContext) { contextStack.push(context) currentContext = context } /** Pop current JSON context from the context stack */ func popContext() { _ = contextStack.pop() currentContext = contextStack.isEmpty() ? JSONBaseContext(on: self) : contextStack.peek() } /** Reset context stack to pristine state. Allows for reusal of the protocol even in cases where the protocol instance was in an undefined state due to dangling/stale/obsolete contexts */ func resetContext() { contextStack.clear() currentContext = JSONBaseContext(on: self) } /** Read a byte that must match bytes[0]; otherwise an exception is thrown. - bytes: Input bytes array */ func readJsonSyntaxChar(bytes: [UInt8]) throws { let ch: UInt8 = try reader.read() if (ch != bytes[0]) { throw TProtocolError(error: .invalidData, message: "Unexpected character: \(ch.asCharacter())") } } /** Write the bytes in array buffer as a JSON characters, escaping as needed */ func writeJsonString(bytes: [UInt8]) throws { try context.writeConditionalDelimiter() try transport.writeJSONQuote() let len: Int = bytes.count for i in 0..= 0x30) { if (bytes[i] == TJSONProtocolConstants.Backslash[0]) { try transport.writeJSONBackslash() try transport.writeJSONBackslash() } else { try transport.write(data: Data(bytes: [bytes[i]], count: 1)) } } else { tempBuffer[0] = TJSONProtocolConstants.JsonCharTable[Int(bytes[i])] if (tempBuffer[0] == 1) { try transport.write(data: Data(bytes: [bytes[i]], count: 1)) } else if (tempBuffer[0] > 1) { try transport.writeJSONBackslash() try transport.write(data: Data(bytes: [tempBuffer[0]], count: 1)) } else { try transport.writeJSONEscSequences() tempBuffer[0] = (bytes[i] >> 4).toHexChar() tempBuffer[1] = (bytes[i]).toHexChar() try transport.write(data: Data(bytes: [tempBuffer[0], tempBuffer[1]], count:2)) } } } try transport.writeJSONQuote() } /** Write out number as a JSON value. If the context dicates so, it will be wrapped in quotes to output as a JSON string. */ func writeJsonInteger(num: Int64) throws { try context.writeConditionalDelimiter() let str: String = String(num) let escapeNum: Bool = try context.escapeNumbers() if (escapeNum) { try transport.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count)) } let strData: Data = str.data(using: .utf8)! try transport.write(data: strData) if (escapeNum) { try transport.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count)) } } /** Write out a double as a JSON value. If it is Nan or Infinity or if the context dictates escaping, write out as JSON string. */ func writeJsonDouble(num: Double) throws { try context.writeConditionalDelimiter() let str = String(num) var special = false switch(str[0]) { case "N", "I": // Nan or Infinity special = true case "-": if (str[1] == "I") { // -Infinity special = true } default: special = false } let escapeNum = try context.escapeNumbers() let escapeNumOrSpecial = special || escapeNum if (escapeNumOrSpecial) { try transport.writeJSONQuote() } if let strData = str.data(using: .utf8) { try transport.write(data: strData) } else { throw TProtocolError(error: .invalidData, message: "Cannot convert double number to data bytes") } if (escapeNumOrSpecial) { try transport.writeJSONQuote() } } /** Write out contents of byte array as a JSON string with base-64 encoded data */ func writeJsonBase64(bytes: [UInt8]) throws { try context.writeConditionalDelimiter() try transport.writeJSONQuote() var len = bytes.count var off = 0 while (len >= 3) { // Encode 3 bytes at a time TBase64Utils.encode(src: bytes, srcOff: off, len: 3, dst: &tempBuffer, dstOff: 0) try transport.write(data: Data(bytes: tempBuffer, count: 4)) off += 3 len -= 3 } if (len > 0) { // Encode remainder TBase64Utils.encode(src: bytes, srcOff: off, len: len, dst: &tempBuffer, dstOff: 0) try transport.write(data: Data(bytes: tempBuffer, count: len + 1)) } try transport.writeJSONQuote() } func writeJsonObjectStart() throws { try context.writeConditionalDelimiter() try transport.writeJSONLeftBrace() pushContext(JSONPairContext(on: self)) } func writeJsonObjectEnd() throws { popContext() try transport.writeJSONRightBrace() } func writeJsonArrayStart() throws { try context.writeConditionalDelimiter() try transport.writeJSONLeftBracket() pushContext(JSONListContext(on: self)) } func writeJsonArrayEnd() throws { popContext() try transport.writeJSONRightBracket() } /** Read in a JSON string, unescaping as appropriate. Skip reading from the context if skipContext is true. */ func readJsonString(skipContext: Bool) throws -> [UInt8] { var codeunits: [Character] = [] if (!skipContext) { try context.readConditionalDelimiter() } try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) var dataBuffer = Data() while (true) { var ch: UInt8 = try reader.read() if (ch == TJSONProtocolConstants.Quote[0]) { break } // Escaped? if (ch != TJSONProtocolConstants.EscSequences[0]) { dataBuffer.append([ch], count: 1) continue } // distinguish between \uXXXX and \? ch = try reader.read() if (ch != TJSONProtocolConstants.EscSequences[1]) { // control chars like \n guard let off: Int = TJSONProtocolConstants.EscSequences.firstIndex(of: ch) else { throw TProtocolError(error: .invalidData, message: "Expected control char") } ch = TJSONProtocolConstants.EscapeCharValues[off] dataBuffer.append([ch], count: 1) continue } // It's \uXXXX let tempData: Data = try transport.readAll(size: 4) let wch = Int16( ((tempData[0]).toHexChar() << 12) + ((tempData[1]).toHexChar() << 8) + ((tempData[2]).toHexChar() << 4) + ((tempData[3]).toHexChar()) ) guard let wchScalar = UnicodeScalar(Int(wch)) else { throw TProtocolError(error: .invalidData, message: "Expected Unicode character") } if (try wch.magnitude.isHighSurrogate()) { if (codeunits.count > 0) { throw TProtocolError(error: .invalidData, message: "Exptected low surrogate char") } codeunits.append(Character(wchScalar)) } else if (try wch.magnitude.isLowSurrogate()) { if (codeunits.count == 0) { throw TProtocolError(error: .invalidData, message: "Exptected high surrogate char") } codeunits.append(Character(wchScalar)) guard let codeunitsData = String(codeunits).data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Codeunits cannot be converted to string bytes") } dataBuffer.append(codeunitsData) codeunits.removeAll() } else { let bytesArray: [UInt8] = withUnsafeBytes(of: wch.bigEndian, Array.init) dataBuffer.append(Data(bytes: bytesArray, count: bytesArray.count)) } } if (codeunits.count > 0) { throw TProtocolError(error: .invalidData, message: "Expected low surrogate char") } let bytesResult: [UInt8] = dataBuffer.map { $0 } return bytesResult } /** Read in a sequence of characters that are all valid in JSON numbers. Does not do a complete regex check to validate that this is actually a number. */ func readJsonNumericChars() throws -> String { var str = "" while(true) { // TODO: Workaround for primitive types with TJSONProtocol: think - how to rewrite into more easy from without exception do { let ch: UInt8 = try reader.peek() if (!ch.isJsonNumeric()) { break } let c = try reader.read() str.append(c.asCharacter()) } catch is TTransportError { break } catch let error { throw error } } return str } /** Read in a JSON number. If the context dictates, read in enclosing quotes. */ func readJsonInteger() throws -> Int64 { try context.readConditionalDelimiter() let escapeNum = try context.escapeNumbers() if (escapeNum) { try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) } let str: String = try readJsonNumericChars() if (escapeNum) { try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) } guard let result = Int64(str) else { throw TProtocolError(error: .invalidData, message: "Cannot convert \(str) to Int64") } return result } /** Read in a JSON double value. Throw if the value is not wrapped in quotes when expected or if wrapped in quotes when not expected. */ func readJsonDouble() throws -> Double { try context.readConditionalDelimiter() let escapeNum = try context.escapeNumbers() if (try reader.peek() == TJSONProtocolConstants.Quote[0]) { let arr: [UInt8] = try readJsonString(skipContext: true) if let str: String = String(data: Data(arr), encoding: .utf8), let dub = Double(str) { if (!escapeNum && !dub.isNaN && !dub.isInfinite) { throw TProtocolError(error: .invalidData, message: "Numeric data unexpectedly quoted") } return dub } else { throw TProtocolError(error: .invalidData, message: "Numeric data convertion to double failed") } } if (escapeNum) { try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) } let str: String = try readJsonNumericChars() if let dub = Double(str) { return dub } else { throw TProtocolError(error: .invalidData, message: "Numeric data convertion to double failed") } } /** Read in a JSON string containing base-64 encoded data and decode it. */ func readJsonBase64() throws -> [UInt8] { var b = try readJsonString(skipContext: false) var len = b.count var off = 0 var size = 0 // Reduce len to ignore fill bytes while( (len > 0) && (b[len - 1] == "=".asciiBytes()[0]) ) { len -= 1 } // Read & decode full byte triplets = 4 source bytes while (len > 4) { // Decode 4 bytes at a time TBase64Utils.decode(src: b, srcOff: off, len: 4, dst: &b, dstOff: size) // Nb: decode in place off += 4 len -= 4 size += 3 } // Don't decode if we hit the end or got a single leftover byte // (invalid base64 but legal for skip of reqular string exType) if (len > 1) { // Decode remainder TBase64Utils.decode(src: b, srcOff: off, len: len, dst: &b, dstOff: size) // NB: decode in place size += len - 1 } let result: [UInt8] = Array(b[0.. (String, TMessageType, Int32) { resetContext() try readJsonArrayStart() let version = try readJsonInteger() if (version != TJSONProtocol.Version) { throw TProtocolError(error: .badVersion(expected: "\(TJSONProtocol.Version)", got: "\(version)"), message: "Bad version") } let buf = try readJsonString(skipContext: false) guard let name = String(bytes: buf, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Invalid message name") } guard let type = TMessageType(rawValue: Int32(try readJsonInteger())) else { throw TProtocolError(error: .invalidData, message: "Invalid message type") } let seqID = try readJsonInteger() return (name, type, Int32(seqID)) } public func readMessageEnd() throws { try readJsonArrayEnd() } public func readStructBegin() throws -> String { try readJsonObjectStart() return "" } public func readStructEnd() throws { try readJsonObjectEnd() } public func readFieldBegin() throws -> (String, TType, Int32) { let ch = try reader.peek() if (ch == TJSONProtocolConstants.RightBrace[0]) { return ("", TType.stop, 0) } let fieldID = try readJsonInteger() try readJsonObjectStart() let fieldName: [UInt8] = try readJsonString(skipContext: false) let fieldType: TType = try TType.getTypeIdForTypeName(fieldName) guard let name = String(bytes: fieldName, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Invalid field name") } return (name, fieldType, Int32(fieldID)) } public func readFieldEnd() throws { try readJsonObjectEnd() } public func readMapBegin() throws -> (TType, TType, Int32) { try readJsonArrayStart() let keyTypeName = try readJsonString(skipContext: false) let keyType = try TType.getTypeIdForTypeName(keyTypeName) let valueTypeName = try readJsonString(skipContext: false) let valueType = try TType.getTypeIdForTypeName(valueTypeName) let count = try readJsonInteger() try checkReadBytesAvailable(keyType: keyType, valueType: valueType, count: Int32(count)) try readJsonObjectStart() return (keyType, valueType, Int32(count)) } public func readMapEnd() throws { try readJsonObjectEnd() try readJsonArrayEnd() } public func readSetBegin() throws -> (TType, Int32) { try readJsonArrayStart() let elementTypeName = try readJsonString(skipContext: false) let elementType = try TType.getTypeIdForTypeName(elementTypeName) let count = try readJsonInteger() try checkReadBytesAvailable(elementType, Int32(count)) return (elementType, Int32(count)) } public func readSetEnd() throws { try readJsonArrayEnd() } public func readListBegin() throws -> (TType, Int32) { try readJsonArrayStart() let elementTypeName = try readJsonString(skipContext: false) let elementType = try TType.getTypeIdForTypeName(elementTypeName) let count = try readJsonInteger() try checkReadBytesAvailable(elementType, Int32(count)) return (elementType, Int32(count)) } public func readListEnd() throws { try readJsonArrayEnd() } public func read() throws -> String { let buf = try readJsonString(skipContext: false) guard let str = String(bytes: buf, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert bytes to string") } return str } public func read() throws -> Bool { let intValue = try readJsonInteger() return intValue == 0 ? false : true } public func read() throws -> UInt8 { return UInt8(try readJsonInteger()) } public func read() throws -> Int8 { return Int8(try readJsonInteger()) } public func read() throws -> Int16 { return Int16(try readJsonInteger()) } public func read() throws -> Int32 { return Int32(try readJsonInteger()) } public func read() throws -> Int64 { return try readJsonInteger() } public func read() throws -> Double { return try readJsonDouble() } public func read() throws -> Data { let base64Bytes = try readJsonBase64() return Data(bytes: base64Bytes, count: base64Bytes.count) } public func read() throws -> UUID { let buf = try readJsonString(skipContext: false) guard let id = String(bytes: buf, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert bytes to string") } guard let uuid = UUID(uuidString: id) else { throw TProtocolError(error: .invalidData, message: "Cannot convert string to uuid") } return uuid } public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { resetContext() try writeJsonArrayStart() try writeJsonInteger(num: Int64(TJSONProtocol.Version)) guard let nameData = name.data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert message name to bytes data") } try writeJsonString(bytes: [UInt8] (nameData)) try writeJsonInteger(num: Int64(messageType.rawValue)) try writeJsonInteger(num: Int64(sequenceID)) } public func writeMessageEnd() throws { try writeJsonArrayEnd() } public func writeStructBegin(name: String) throws { try writeJsonObjectStart() } public func writeStructEnd() throws { try writeJsonObjectEnd() } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try writeJsonInteger(num: Int64(fieldID)) try writeJsonObjectStart() let fieldTypeName = try fieldType.getTypeNameForTypeId() try writeJsonString(bytes: fieldTypeName) } public func writeFieldStop() throws { // Nop } public func writeFieldEnd() throws { try writeJsonObjectEnd() } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try writeJsonArrayStart() let mapKeyTypeName = try keyType.getTypeNameForTypeId() try writeJsonString(bytes: mapKeyTypeName) let mapValueTypeName = try valueType.getTypeNameForTypeId() try writeJsonString(bytes: mapValueTypeName) try writeJsonInteger(num: Int64(size)) try writeJsonObjectStart() } public func writeMapEnd() throws { try writeJsonObjectEnd() try writeJsonArrayEnd() } public func writeSetBegin(elementType: TType, size: Int32) throws { try writeJsonArrayStart() let elementTypeName = try elementType.getTypeNameForTypeId() try writeJsonString(bytes: elementTypeName) try writeJsonInteger(num: Int64(size)) } public func writeSetEnd() throws { try writeJsonArrayEnd() } public func writeListBegin(elementType: TType, size: Int32) throws { try writeJsonArrayStart() let elementTypeName = try elementType.getTypeNameForTypeId() try writeJsonString(bytes: elementTypeName) try writeJsonInteger(num: Int64(size)) } public func writeListEnd() throws { try writeJsonArrayEnd() } public func write(_ value: String) throws { guard let strData = value.data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert string value to bytes data") } try writeJsonString(bytes: [UInt8](strData)) } public func write(_ value: Bool) throws { try writeJsonInteger(num: value ? 1 : 0) } public func write(_ value: UInt8) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int8) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int16) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int32) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int64) throws { try writeJsonInteger(num: value) } public func write(_ value: Double) throws { try writeJsonDouble(num: value) } public func write(_ value: Data) throws { try writeJsonBase64(bytes: [UInt8](value)) } public func write(_ value: UUID) throws { guard let strData = value.uuidString.data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert UUID value to bytes data") } try writeJsonString(bytes: [UInt8](strData)) } // MARK: - Private functions private func checkReadBytesAvailable(keyType: TType, valueType: TType, count: Int32) throws { let elmSize = try getMinSerializedSize(keyType) + getMinSerializedSize(valueType) _ = count * elmSize // TODO: implement checkReadBytesAvailable in TTransport // transport.checkReadBytesAvailable(size: count * elmSize) } private func checkReadBytesAvailable(_ elementType: TType, _ count: Int32) throws { let elmSize = try getMinSerializedSize(elementType) _ = count * elmSize // TODO: implement checkReadBytesAvailable in TTransport // transport.checkReadBytesAvailable(size: count * elmSize) } private func getMinSerializedSize(_ type: TType) throws -> Int32 { switch(type) { case .stop, .void: return 0 case .bool, .i8, .i16, .i32, .i64, .double: return 1 case .string, .struct, .map, .set, .list: return 2 // empty object default: throw TProtocolError(error: .invalidData, message: "Invalid TType") } } // MARK: - TJSONProtocol inner classes /* Base class for tracking JSON contexts that may require inserting/reading additional JSON syntax characters This base context does nothing */ class JSONBaseContext { var proto: TJSONProtocol init(on proto: TJSONProtocol) { self.proto = proto } func writeConditionalDelimiter() throws { } func readConditionalDelimiter() throws { } func escapeNumbers() -> Bool { return false } } /* Context for JSON lists. will insert/read commas before each item except for the first one */ class JSONListContext: JSONBaseContext { private var first: Bool = true override init(on proto: TJSONProtocol) { super.init(on: proto) } override func writeConditionalDelimiter() throws { if (first) { first = false } else { try proto.transport.writeJSONComma() } } override func readConditionalDelimiter() throws { if (first) { first = false } else { try proto.readJsonSyntaxChar(bytes: TJSONProtocolConstants.Comma) } } } /* Context for JSON records. Will insert/read colons before the value portion of each record pair, and commas before each key except the first. In addition, will indicate that numbers in the key position need to be escaped in quotes (since JSON keys must be strings). */ class JSONPairContext : JSONBaseContext { private var colon: Bool = true private var first: Bool = true override init(on proto: TJSONProtocol) { super.init(on: proto) } override func writeConditionalDelimiter() throws { if (first) { first = false colon = true } else { if (colon) { try proto.transport.writeJSONColon() } else { try proto.transport.writeJSONComma() } self.colon = !self.colon } } override func readConditionalDelimiter() throws { if (first) { first = false colon = true } else { try proto.readJsonSyntaxChar(bytes: colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma) self.colon = !self.colon } } override func escapeNumbers() -> Bool { return colon } } class JSONContextStack { private var items: [JSONBaseContext] = [] func peek() -> JSONBaseContext { guard let topElement = items.first else { fatalError("This stack is empty.") } return topElement } func pop() -> JSONBaseContext { return items.removeFirst() } func push(_ element: JSONBaseContext) { items.insert(element, at: 0) } func clear() { items.removeAll() } func isEmpty() -> Bool { return items.count == 0 } } class LookaheadReader { private var byteData: UInt8? private var hasData: Bool = false var proto: TJSONProtocol init(on proto: TJSONProtocol) { self.proto = proto } func read() throws -> UInt8 { if (hasData) { hasData = false } else { let data = try proto.transport.readAll(size: 1) byteData = Array(data)[0] } if let byte = byteData { return byte } throw TProtocolError(error: .invalidData, message: "Reader does not have data to read") } func peek() throws -> UInt8 { if (!hasData) { let data = try proto.transport.readAll(size: 1) byteData = Array(data)[0] hasData = true } if let byte = byteData { return byte } throw TProtocolError(error: .invalidData, message: "Reader does not have data to peek") } } } // MARK: TJSONProtocolConstants /** TJSONProtocol Constants properties/fields */ public struct TJSONProtocolConstants { public static let Comma: [UInt8] = ",".asciiBytes() public static let Colon: [UInt8] = ":".asciiBytes() public static let LeftBrace: [UInt8] = "{".asciiBytes() public static let RightBrace: [UInt8] = "}".asciiBytes() public static let LeftBracket: [UInt8] = "[".asciiBytes() public static let RightBracket: [UInt8] = "]".asciiBytes() public static let Quote: [UInt8] = "\"".asciiBytes() public static let Backslash: [UInt8] = "\\".asciiBytes() public static let JsonCharTable: [UInt8] = [ 0, 0, 0, 0, 0, 0, 0, 0, b, t, n, 0, f, r, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, qt, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] // \b -> \u{0008} // \f -> \u{000C} public static let EscapeChars: [Character] = ["\"", "\\", "/", "\u{0008}", "\u{000C}", "\n", "\r", "\t" ] public static let EscapeCharValues: [UInt8] = "\"\\/\u{0008}\u{000C}\n\r\t".asciiBytes() public static let EscSequences: [UInt8] = "\\u00".asciiBytes() public struct TypeNames { public static let NameBool: [UInt8] = "tf".asciiBytes() public static let NameByte: [UInt8] = "i8".asciiBytes() public static let NameI16: [UInt8] = "i16".asciiBytes() public static let NameI32: [UInt8] = "i32".asciiBytes() public static let NameI64: [UInt8] = "i64".asciiBytes() public static let NameDouble: [UInt8] = "dbl".asciiBytes() public static let NameStruct: [UInt8] = "rec".asciiBytes() public static let NameString: [UInt8] = "str".asciiBytes() public static let NameMap: [UInt8] = "map".asciiBytes() public static let NameList: [UInt8] = "lst".asciiBytes() public static let NameSet: [UInt8] = "set".asciiBytes() } // MARK: private fields helpers private static let b: UInt8 = "b".asciiBytes()[0] private static let t: UInt8 = "t".asciiBytes()[0] private static let n: UInt8 = "n".asciiBytes()[0] private static let f: UInt8 = "f".asciiBytes()[0] private static let r: UInt8 = "r".asciiBytes()[0] private static let qt: UInt8 = "\"".asciiBytes()[0] } // MARK: Extensions extension String { public func asciiBytes() -> [UInt8] { var result: [UInt8] = [] for char in self { result.append(char.asciiValue!) } return result } subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] } } extension Character { public func asciiByte() -> UInt8 { return self.asciiValue! } } extension UInt8 { /** Convert a byte containing a hex value to its corresponding hex character */ public func toHexChar() -> UInt8 { var value = self & 0x0F if (value < 10) { let zeroChar = Character("0").asciiValue! return value + zeroChar } value -= 10 let aChar = Character("a").asciiValue! return value + aChar } public func isJsonNumeric() -> Bool { let numberBytes = "+-.0123456789Ee".asciiBytes() if (numberBytes.contains(self)) { return true } return false } public func asCharacter() -> Character { let scalar = UnicodeScalar(self) return Character(scalar) } } extension UInt16 { public func isHighSurrogate() throws -> Bool { let wch = self if let d800 = UInt16("D800", radix: 16), let dbff = UInt16("DBFF", radix: 16) { return wch >= d800 && wch <= dbff } else { throw TProtocolError(error: .invalidData, message: "isHighSurrogate failed") } } public func isLowSurrogate() throws -> Bool{ let wch = self if let dc00 = UInt16("DC00", radix: 16), let dfff = UInt16("DFFF", radix: 16) { return wch >= dc00 && wch <= dfff } else { throw TProtocolError(error: .invalidData, message: "isLowSurrogate failed") } } } extension TType { public static func getTypeIdForTypeName(_ name: [UInt8]) throws -> TType { var result = TType.stop if (name.count > 1) { switch(name[0]) { case "t".asciiBytes()[0]: result = TType.bool case "i".asciiBytes()[0]: switch(name[1]) { case "8".asciiBytes()[0]: result = TType.i8 case "1".asciiBytes()[0]: result = TType.i16 case "3".asciiBytes()[0]: result = TType.i32 case "6".asciiBytes()[0]: result = TType.i64 default: result = TType.stop } case "d".asciiBytes()[0]: result = TType.double case "l".asciiBytes()[0]: result = TType.list case "m".asciiBytes()[0]: result = TType.map case "r".asciiBytes()[0]: result = TType.struct case "s".asciiBytes()[0]: if (name[1] == "t".asciiBytes()[0]) { result = TType.string } else if (name[1] == "e".asciiBytes()[0]) { result = TType.set } default: result = TType.stop } } if (result == TType.stop) { throw TProtocolError(error: .notImplemented, message: "Unrecognized exType") } return result } public func getTypeNameForTypeId() throws -> [UInt8] { let typeId = self switch(typeId) { case .bool: return TJSONProtocolConstants.TypeNames.NameBool case .i8: return TJSONProtocolConstants.TypeNames.NameByte case .i16: return TJSONProtocolConstants.TypeNames.NameI16 case .i32: return TJSONProtocolConstants.TypeNames.NameI32 case .i64: return TJSONProtocolConstants.TypeNames.NameI64 case .double: return TJSONProtocolConstants.TypeNames.NameDouble case .string: return TJSONProtocolConstants.TypeNames.NameString case .struct: return TJSONProtocolConstants.TypeNames.NameStruct case .map: return TJSONProtocolConstants.TypeNames.NameMap case .set: return TJSONProtocolConstants.TypeNames.NameSet case .list: return TJSONProtocolConstants.TypeNames.NameList default: throw TProtocolError(error: .invalidData, message: "TypeId: \(typeId) does not have mapping Name") } } } extension TTransport { func writeJSONColon() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Colon, count: TJSONProtocolConstants.Colon.count)) } func writeJSONComma() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Comma, count: TJSONProtocolConstants.Comma.count)) } func writeJSONQuote() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count)) } func writeJSONBackslash() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Backslash, count: TJSONProtocolConstants.Backslash.count)) } func writeJSONEscSequences() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.EscSequences, count: TJSONProtocolConstants.EscSequences.count)) } func writeJSONLeftBrace() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.LeftBrace, count: TJSONProtocolConstants.LeftBrace.count)) } func writeJSONRightBrace() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.RightBrace, count: TJSONProtocolConstants.RightBrace.count)) } func writeJSONLeftBracket() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.LeftBracket, count: TJSONProtocolConstants.LeftBracket.count)) } func writeJSONRightBracket() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.RightBracket, count: TJSONProtocolConstants.RightBracket.count)) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TProtocol.swift0000664000175000017500000001372415170007142024711 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public enum TMessageType: Int32 { case call = 1 case reply = 2 case exception = 3 case oneway = 4 } public enum TType: Int32 { case stop = 0 case void = 1 case bool = 2 case i8 = 3 case double = 4 case i16 = 6 case i32 = 8 case i64 = 10 case string = 11 case `struct` = 12 case map = 13 case set = 14 case list = 15 case uuid = 16 } public protocol TProtocol { var transport: TTransport { get set } init(on transport: TTransport) // Reading Methods func readMessageBegin() throws -> (String, TMessageType, Int32) func readMessageEnd() throws func readStructBegin() throws -> String func readStructEnd() throws func readFieldBegin() throws -> (String, TType, Int32) func readFieldEnd() throws func readMapBegin() throws -> (TType, TType, Int32) func readMapEnd() throws func readSetBegin() throws -> (TType, Int32) func readSetEnd() throws func readListBegin() throws -> (TType, Int32) func readListEnd() throws func read() throws -> String func read() throws -> Bool func read() throws -> UInt8 func read() throws -> Int8 func read() throws -> Int16 func read() throws -> Int32 func read() throws -> Int64 func read() throws -> Double func read() throws -> Data func read() throws -> UUID // Writing methods func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws func writeMessageEnd() throws func writeStructBegin(name: String) throws func writeStructEnd() throws func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws func writeFieldStop() throws func writeFieldEnd() throws func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws func writeMapEnd() throws func writeSetBegin(elementType: TType, size: Int32) throws func writeSetEnd() throws func writeListBegin(elementType: TType, size: Int32) throws func writeListEnd() throws func write(_ value: String) throws func write(_ value: Bool) throws func write(_ value: UInt8) throws func write(_ value: Int8) throws func write(_ value: Int16) throws func write(_ value: Int32) throws func write(_ value: Int64) throws func write(_ value: Double) throws func write(_ value: Data) throws func write(_ value: UUID) throws } public extension TProtocol { func writeFieldValue(_ value: TSerializable, name: String, type: TType, id: Int32) throws { try writeFieldBegin(name: name, type: type, fieldID: id) try value.write(to: self) try writeFieldEnd() } func validateValue(_ value: Any?, named name: String) throws { if value == nil { throw TProtocolError(error: .unknown, message: "Missing required value for field: \(name)") } } func readResultMessageBegin() throws { let (_, type, _) = try readMessageBegin(); if type == .exception { let x = try readException() throw x } return } func readException() throws -> TApplicationError { return try TApplicationError.read(from: self) } func writeException(messageName name: String, sequenceID: Int32, ex: TApplicationError) throws { try writeMessageBegin(name: name, type: .exception, sequenceID: sequenceID) try ex.write(to: self) try writeMessageEnd() } func skip(type: TType) throws { try skip(type: type, depth: 0) } private func skip(type: TType, depth: Int) throws { let nextDepth = depth + 1 if nextDepth > 64 { throw TProtocolError(error: .depthLimit, message: "Maximum skip depth exceeded") } switch type { case .bool: _ = try read() as Bool case .i8: _ = try read() as Int8 case .i16: _ = try read() as Int16 case .i32: _ = try read() as Int32 case .i64: _ = try read() as Int64 case .double: _ = try read() as Double case .string: _ = try read() as String case .uuid: _ = try read() as UUID case .struct: _ = try readStructBegin() while true { let (_, fieldType, _) = try readFieldBegin() if fieldType == .stop { break } try skip(type: fieldType, depth: nextDepth) try readFieldEnd() } try readStructEnd() case .map: let (keyType, valueType, size) = try readMapBegin() if size < 0 { throw TProtocolError(error: .negativeSize, message: "Negative map size: \(size)") } for _ in 0..=4.2) // Swift 3/4 compatibility fileprivate extension RunLoopMode { static let `default` = defaultRunLoopMode } #endif #if os(Linux) public class TSSLSocketTransport { init(hostname: String, port: UInt16) { // FIXME! assert(false, "Security not available in Linux, TSSLSocketTransport Unavilable for now") } } #else let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian let htons = isLittleEndian ? _OSSwapInt16 : { $0 } let htonl = isLittleEndian ? _OSSwapInt32 : { $0 } public class TSSLSocketTransport: TStreamTransport { var sslHostname: String var sd: Int32 = 0 public init(hostname: String, port: UInt16) throws { sslHostname = hostname var readStream: Unmanaged? var writeStream: Unmanaged? /* create a socket structure */ var pin: sockaddr_in = sockaddr_in() var hp: UnsafeMutablePointer? = nil for i in 0..<10 { hp = gethostbyname(hostname.cString(using: String.Encoding.utf8)!) if hp == nil { print("failed to resolve hostname \(hostname)") herror("resolv") if i == 9 { super.init(inputStream: nil, outputStream: nil) // have to init before throwing throw TSSLSocketTransportError(error: .hostanameResolution(hostname: hostname)) } Thread.sleep(forTimeInterval: 0.2) } else { break } } pin.sin_family = UInt8(AF_INET) pin.sin_addr = in_addr(s_addr: UInt32((hp?.pointee.h_addr_list.pointee?.pointee)!)) // Is there a better way to get this??? pin.sin_port = htons(port) /* create the socket */ sd = socket(Int32(AF_INET), Int32(SOCK_STREAM), Int32(IPPROTO_TCP)) if sd == -1 { super.init(inputStream: nil, outputStream: nil) // have to init before throwing throw TSSLSocketTransportError(error: .socketCreate(port: Int(port))) } /* open a connection */ // need a non-self ref to sd, otherwise the j complains let sd_local = sd let connectResult = withUnsafePointer(to: &pin) { connect(sd_local, UnsafePointer(OpaquePointer($0)), socklen_t(MemoryLayout.size)) } if connectResult == -1 { super.init(inputStream: nil, outputStream: nil) // have to init before throwing throw TSSLSocketTransportError(error: .connect) } CFStreamCreatePairWithSocket(kCFAllocatorDefault, sd, &readStream, &writeStream) CFReadStreamSetProperty(readStream?.takeRetainedValue(), .socketNativeHandle, kCFBooleanTrue) CFWriteStreamSetProperty(writeStream?.takeRetainedValue(), .socketNativeHandle, kCFBooleanTrue) var inputStream: InputStream? = nil var outputStream: OutputStream? = nil if readStream != nil && writeStream != nil { CFReadStreamSetProperty(readStream?.takeRetainedValue(), .socketSecurityLevel, kCFStreamSocketSecurityLevelTLSv1) let settings: [String: Bool] = [kCFStreamSSLValidatesCertificateChain as String: true] CFReadStreamSetProperty(readStream?.takeRetainedValue(), .SSLSettings, settings as CFTypeRef) CFWriteStreamSetProperty(writeStream?.takeRetainedValue(), .SSLSettings, settings as CFTypeRef) inputStream = readStream!.takeRetainedValue() inputStream?.schedule(in: .current, forMode: .default) inputStream?.open() outputStream = writeStream!.takeRetainedValue() outputStream?.schedule(in: .current, forMode: .default) outputStream?.open() readStream?.release() writeStream?.release() } super.init(inputStream: inputStream, outputStream: outputStream) self.input?.delegate = self self.output?.delegate = self } func recoverFromTrustFailure(_ myTrust: SecTrust, lastTrustResult: SecTrustResultType) -> Bool { let trustTime = SecTrustGetVerifyTime(myTrust) let currentTime = CFAbsoluteTimeGetCurrent() let timeIncrement = 31536000 // from TSSLSocketTransport.m let newTime = currentTime - Double(timeIncrement) if trustTime - newTime != 0 { let newDate = CFDateCreate(nil, newTime) SecTrustSetVerifyDate(myTrust, newDate!) var tr = lastTrustResult let success = withUnsafeMutablePointer(to: &tr) { trPtr -> Bool in if SecTrustEvaluate(myTrust, trPtr) != errSecSuccess { return false } return true } if !success { return false } } if lastTrustResult == .proceed || lastTrustResult == .unspecified { return false } print("TSSLSocketTransport: Unable to recover certificate trust failure") return true } public func isOpen() -> Bool { return sd > 0 } } extension TSSLSocketTransport: StreamDelegate { public func stream(_ aStream: Stream, handle eventCode: Stream.Event) { switch eventCode { case Stream.Event(): break case Stream.Event.hasBytesAvailable: break case Stream.Event.openCompleted: break case Stream.Event.hasSpaceAvailable: var proceed = false var trustResult: SecTrustResultType = .invalid var newPolicies: CFMutableArray? repeat { let trust: SecTrust = aStream.property(forKey: .SSLPeerTrust) as! SecTrust // Add new policy to current list of policies let policy = SecPolicyCreateSSL(false, sslHostname as CFString?) var ppolicy = policy // mutable for pointer let policies: UnsafeMutablePointer? = nil if SecTrustCopyPolicies(trust, policies!) != errSecSuccess { break } withUnsafeMutablePointer(to: &ppolicy) { ptr in newPolicies = CFArrayCreateMutableCopy(nil, 0, policies?.pointee) CFArrayAppendValue(newPolicies, ptr) } // update trust policies if SecTrustSetPolicies(trust, newPolicies!) != errSecSuccess { break } // Evaluate the trust chain let success = withUnsafeMutablePointer(to: &trustResult) { trustPtr -> Bool in if SecTrustEvaluate(trust, trustPtr) != errSecSuccess { return false } return true } if !success { break } switch trustResult { case .proceed: proceed = true case .unspecified: proceed = true case .recoverableTrustFailure: proceed = self.recoverFromTrustFailure(trust, lastTrustResult: trustResult) case .deny: break case .fatalTrustFailure: break case .otherError: break case .invalid: break default: break } } while false if !proceed { print("TSSLSocketTransport: Cannot trust certificate. Result: \(trustResult)") aStream.close() } case Stream.Event.errorOccurred: break case Stream.Event.endEncountered: break default: break } } } #endif thrift-0.23.0/tutorial/swift/swift-dep/Sources/TCompactProtocol.swift0000664000175000017500000004332415170007142026217 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import CoreFoundation public enum TCType: UInt8 { case stop = 0x00 case boolean_TRUE = 0x01 case boolean_FALSE = 0x02 case i8 = 0x03 case i16 = 0x04 case i32 = 0x05 case i64 = 0x06 case double = 0x07 case binary = 0x08 case list = 0x09 case set = 0x0A case map = 0x0B case `struct` = 0x0C case uuid = 0x0D public static let typeMask: UInt8 = 0xE0 // 1110 0000 public static let typeBits: UInt8 = 0x07 // 0000 0111 public static let typeShiftAmount = 5 } public class TCompactProtocol: TProtocol { public static let protocolID: UInt8 = 0x82 public static let version: UInt8 = 1 public static let versionMask: UInt8 = 0x1F // 0001 1111 public var transport: TTransport var lastField: [UInt8] = [] var lastFieldId: UInt8 = 0 var boolFieldName: String? var boolFieldType: TType? var boolFieldId: Int32? var booleanValue: Bool? var currentMessageName: String? public required init(on transport: TTransport) { self.transport = transport } /// Mark: - TCompactProtocol helpers func writebyteDirect(_ byte: UInt8) throws { let byte = Data([byte]) try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: byte) } } func writeVarint32(_ val: UInt32) throws { var val = val var i32buf = [UInt8](repeating: 0, count: 5) var idx = 0 while true { if (val & ~0x7F) == 0 { i32buf[idx] = UInt8(val) idx += 1 break } else { i32buf[idx] = UInt8((val & 0x7F) | 0x80) idx += 1 val >>= 7 } } try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: Data(i32buf[0..>= 7 } } try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: Data(varint64out[0.. Data { var result = Data() if size != 0 { try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { result = try self.transport.readAll(size: size) } } return result } func readVarint32() throws -> UInt32 { var result: UInt32 = 0 var shift: UInt32 = 0 while true { let byte: UInt8 = try read() result |= UInt32(byte & 0x7F) << shift if (byte & 0x80) == 0 { break } shift += 7 } return result } func readVarint64() throws -> UInt64 { var result: UInt64 = 0 var shift: UInt64 = 0 while true { let byte: UInt8 = try read() result |= UInt64(byte & 0x7F) << shift if (byte & 0x80) == 0 { break } shift += 7 } return result } func ttype(_ compactTypeVal: UInt8) throws -> TType { guard let compactType = TCType(rawValue: compactTypeVal) else { throw TProtocolError(message: "Unknown TCType value: \(compactTypeVal)") } switch compactType { case .stop: return .stop; case .boolean_FALSE, .boolean_TRUE: return .bool; case .i8: return .i8; case .i16: return .i16; case .i32: return .i32; case .i64: return .i64; case .double: return .double; case .binary: return .string; case .list: return .list; case .set: return .set; case .map: return .map; case .struct: return .struct; case .uuid: return .uuid; } } func compactType(_ ttype: TType) -> TCType { switch ttype { case .stop: return .stop case .void: return .i8 case .bool: return .boolean_FALSE case .i8: return .i8 case .double: return .double case .i16: return .i16 case .i32: return .i32 case .i64: return .i64 case .string: return .binary case .struct: return .struct case .map: return .map case .set: return .set case .list: return .list case .uuid: return .uuid } } /// ZigZag encoding maps signed integers to unsigned integers so that /// numbers with a small absolute value (for instance, -1) have /// a small varint encoded value too. It does this in a way that /// "zig-zags" back and forth through the positive and negative integers, /// so that -1 is encoded as 1, 1 is encoded as 2, -2 is encoded as 3, and so /// /// - parameter n: number to zigzag /// /// - returns: zigzaged UInt32 func i32ToZigZag(_ n : Int32) -> UInt32 { return UInt32(bitPattern: Int32(n << 1) ^ Int32(n >> 31)) } func i64ToZigZag(_ n : Int64) -> UInt64 { return UInt64(bitPattern: Int64(n << 1) ^ Int64(n >> 63)) } func zigZagToi32(_ n: UInt32) -> Int32 { return Int32(n >> 1) ^ (-Int32(n & 1)) } func zigZagToi64(_ n: UInt64) -> Int64 { return Int64(n >> 1) ^ (-Int64(n & 1)) } /// Mark: - TProtocol public func readMessageBegin() throws -> (String, TMessageType, Int32) { let protocolId: UInt8 = try read() if protocolId != TCompactProtocol.protocolID { let expected = String(format:"%2X", TCompactProtocol.protocolID) let got = String(format:"%2X", protocolId) throw TProtocolError(message: "Wrong Protocol ID \(got)", extendedError: .mismatchedProtocol(expected: expected, got: got)) } let versionAndType: UInt8 = try read() let version: UInt8 = versionAndType & TCompactProtocol.versionMask if version != TCompactProtocol.version { throw TProtocolError(error: .badVersion(expected: "\(TCompactProtocol.version)", got:"\(version)")) } let type = (versionAndType >> UInt8(TCType.typeShiftAmount)) & TCType.typeBits guard let mtype = TMessageType(rawValue: Int32(type)) else { throw TProtocolError(message: "Unknown TMessageType value: \(type)") } let varint = zigZagToi32(try readVarint32()) let sequenceId = Int32(varint) let name: String = try read() return (name, mtype, Int32(sequenceId)) } public func readMessageEnd() throws { } public func readStructBegin() throws -> String { lastField.append(lastFieldId) lastFieldId = 0 return "" } public func readStructEnd() throws { lastFieldId = lastField.last ?? 0 lastField.removeLast() } public func readFieldBegin() throws -> (String, TType, Int32) { let byte: UInt8 = try read() guard let type = TCType(rawValue: byte & 0x0F) else { throw TProtocolError(message: "Unknown TCType \(byte & 0x0F)") } // if it's a stop, then we can return immediately, as the struct is over if type == .stop { return ("", .stop, 0) } var fieldId: Int16 = 0 // mask off the 4MSB of the type header. it could contain a field id delta let modifier = (byte & 0xF0) >> 4 if modifier == 0 { // not a delta. look ahead for the zigzag varint field id fieldId = try read() } else { // has a delta. add the delta to the last Read field id. fieldId = Int16(lastFieldId + modifier) } let fieldType = try ttype(type.rawValue) // if this happens to be a boolean field, the value is encoded in the type if type == .boolean_TRUE || type == .boolean_FALSE { // save the boolean value in a special instance variable booleanValue = type == .boolean_TRUE } guard fieldId >= 0 && fieldId <= Int16(UInt8.max) else { throw TProtocolError(error: .invalidData, message: "Field id out of range: \(fieldId)") } // push the new field onto the field stack so we can keep the deltas going lastFieldId = UInt8(fieldId) return ("", fieldType, Int32(fieldId)) } public func readFieldEnd() throws { } public func read() throws -> String { let length = try readVarint32() var result: String if length != 0 { let data = try readBinary(Int(length)) result = String(data: data, encoding: String.Encoding.utf8) ?? "" } else { result = "" } return result } public func read() throws -> Bool { if let val = booleanValue { self.booleanValue = nil return val } else { let result = try read() as UInt8 return TCType(rawValue: result) == .boolean_TRUE } } public func read() throws -> UInt8 { var buff: UInt8 = 0 try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1)[0] } return buff } public func read() throws -> Int8 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1) } return buff.withUnsafeBytes { pntr in return pntr.load(as: Int8.self) } } public func read() throws -> Int16 { let v = try readVarint32() return Int16(zigZagToi32(v)) } public func read() throws -> Int32 { let v = try readVarint32() return zigZagToi32(v) } public func read() throws -> Int64 { let v = try readVarint64() return zigZagToi64(v) } public func read() throws -> Double { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 8) } let i64: UInt64 = buff.withUnsafeBytes { $0.load(as: UInt64.self) } let bits = CFSwapInt64LittleToHost(i64) return Double(bitPattern: bits) } public func read() throws -> Data { let length = try readVarint32() return try readBinary(Int(length)) } public func read() throws -> UUID { let data = try self.transport.readAll(size: 16) let lsb = data[0.. (TType, TType, Int32) { var keyAndValueType: UInt8 = 8 let size = try readVarint32() if size != 0 { keyAndValueType = try read() } let keyType = try ttype(keyAndValueType >> 4) let valueType = try ttype(keyAndValueType & 0xF) return (keyType, valueType, Int32(size)) } public func readMapEnd() throws { } public func readSetBegin() throws -> (TType, Int32) { return try readListBegin() } public func readSetEnd() throws { } public func readListBegin() throws -> (TType, Int32) { let sizeAndType: UInt8 = try read() var size: UInt32 = UInt32(sizeAndType >> 4) & 0x0f if size == 15 { size = try readVarint32() } let elementType = try ttype(sizeAndType & 0x0F) return (elementType, Int32(size)) } public func readListEnd() throws { } public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { try writebyteDirect(TCompactProtocol.protocolID) let nextByte: UInt8 = (TCompactProtocol.version & TCompactProtocol.versionMask) | (UInt8((UInt32(messageType.rawValue) << UInt32(TCType.typeShiftAmount))) & TCType.typeMask) try writebyteDirect(nextByte) try writeVarint32(i32ToZigZag(sequenceID)) try write(name) currentMessageName = name } public func writeMessageEnd() throws { currentMessageName = nil } public func writeStructBegin(name: String) throws { lastField.append(lastFieldId) lastFieldId = 0 } public func writeStructEnd() throws { lastFieldId = lastField.last ?? 0 lastField.removeLast() } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { if fieldType == .bool { boolFieldName = name boolFieldType = fieldType boolFieldId = fieldID return } else { try writeFieldBeginInternal(name: name, type: fieldType, fieldID: fieldID, typeOverride: 0xFF) } } func writeFieldBeginInternal(name: String, type fieldType: TType, fieldID: Int32, typeOverride: UInt8) throws { let typeToWrite = typeOverride == 0xFF ? compactType(fieldType).rawValue : typeOverride // check if we can use delta encoding for the field id let diff = UInt8(fieldID) - lastFieldId if (UInt8(fieldID) > lastFieldId) && (diff <= 15) { // Write them together try writebyteDirect((UInt8(fieldID) - lastFieldId) << 4 | typeToWrite) } else { // Write them separate try writebyteDirect(typeToWrite) try write(Int16(fieldID)) } lastFieldId = UInt8(fieldID) } public func writeFieldStop() throws { try writebyteDirect(TCType.stop.rawValue) } public func writeFieldEnd() throws { } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { if size == 0 { try writebyteDirect(0) } else { try writeVarint32(UInt32(size)) let compactedTypes = compactType(keyType).rawValue << 4 | compactType(valueType).rawValue try writebyteDirect(compactedTypes) } } public func writeMapEnd() throws { } public func writeSetBegin(elementType: TType, size: Int32) throws { try writeCollectionBegin(elementType, size: size) } public func writeSetEnd() throws { } public func writeListBegin(elementType: TType, size: Int32) throws { try writeCollectionBegin(elementType, size: size) } public func writeListEnd() throws { } public func write(_ value: String) throws { try write(value.data(using: String.Encoding.utf8)!) } public func write(_ value: Bool) throws { if let boolFieldId = boolFieldId, let boolFieldType = boolFieldType, let boolFieldName = boolFieldName { // we haven't written the field header yet let compactType: TCType = value ? .boolean_TRUE : .boolean_FALSE try writeFieldBeginInternal(name: boolFieldName, type: boolFieldType, fieldID: boolFieldId, typeOverride: compactType.rawValue) self.boolFieldId = nil self.boolFieldType = nil self.boolFieldName = nil } else { // we're not part of a field, so just write the value. try writebyteDirect(value ? TCType.boolean_TRUE.rawValue : TCType.boolean_FALSE.rawValue) } } public func write(_ value: UInt8) throws { try writebyteDirect(value) } public func write(_ value: Int8) throws { var value = value let buff = Data(bytes: &value, count: MemoryLayout.size(ofValue: value)) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int16) throws { try writeVarint32(i32ToZigZag(Int32(value))) } public func write(_ value: Int32) throws { try writeVarint32(i32ToZigZag(value)) } public func write(_ value: Int64) throws { try writeVarint64(i64ToZigZag(value)) } public func write(_ value: Double) throws { var bits = CFSwapInt64HostToLittle(value.bitPattern) let data = withUnsafePointer(to: &bits) { return Data(bytes: UnsafePointer(OpaquePointer($0)), count: MemoryLayout.size) } try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: data) } } public func write(_ data: Data) throws { try writeVarint32(UInt32(data.count)) try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: data) } } public func write(_ value: UUID) throws { let data = withUnsafePointer(to: value.uuid) { Data(bytes: $0, count: MemoryLayout.size(ofValue: value.uuid)) } let msb = data[0.. ()) throws { // Need mutable copy var error = error do { try block() } catch let err as TError { var message = error.message ?? "" message += "\nFile: \(sourceFile)\n" message += "Line: \(sourceLine)\n" message += "Method: \(sourceMethod)" message += "\nOriginal Error:\n" + err.description error.message = message throw error } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TError.swift0000664000175000017500000000460015165535636024214 0ustar00buildbuild00000000000000/* * 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. */ /// TErrorCode /// /// Protocol for TError conformers' enum's to conform to. /// Generic Int Thrift error code to allow error cases to have /// associated values. public protocol TErrorCode : CustomStringConvertible { var thriftErrorCode: Int { get } } /// TError /// /// Base protocol for all Thrift Error(Exception) types to conform to public protocol TError : Error, CustomStringConvertible { /// Enum for error cases. Can be typealiased to any conforming enum /// or defined nested. associatedtype Code: TErrorCode /// Error Case, value from internal enum var error: Code { get set } /// Optional additional message var message: String? { get set } /// Default error case for the error type, used for generic init() static var defaultCase: Code { get } init() } extension TError { /// Human readable description of error. Default provided for you in the /// format \(Self.self): \(error.errorDescription) \n message /// eg: /// /// TApplicationError (1): Invalid Message Type /// An unknown Error has occured. public var description: String { var out = "\(Self.self) (\(error.thriftErrorCode)): " + error.description + "\n" if let message = message { out += "Message: \(message)" } return out } /// Simple default Initializer for TError's /// /// - parameter error: ErrorCode value. Default: defaultCase /// - parameter message: Custom message with error. Optional /// /// - returns: <#return value description#> public init(error: Code, message: String? = nil) { self.init() self.error = error self.message = message } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TStruct.swift0000664000175000017500000000661215165535636024414 0ustar00buildbuild00000000000000/* * 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. */ /// Protocol for Generated Structs to conform to /// Dictionary maps field names to internal IDs and uses Reflection /// to iterate through all fields. /// `writeFieldValue(_:name:type:id:)` calls `TSerializable.write(to:)` internally /// giving a nice recursive behavior for nested TStructs, TLists, TMaps, and TSets public protocol TStruct : TSerializable { static var fieldIds: [String: Int32] { get } static var structName: String { get } } public extension TStruct { static var fieldIds: [String: (id: Int32, type: TType)] { return [:] } static var thriftType: TType { return .struct } func write(to proto: TProtocol) throws { // Write struct name first try proto.writeStructBegin(name: Self.structName) try self.forEach { name, value, id in // Write to protocol try proto.writeFieldValue(value, name: name, type: value.thriftType, id: id) } try proto.writeFieldStop() try proto.writeStructEnd() } /// Provides a block for handling each (available) thrift property using reflection /// Caveat: Skips over optional values /// Provides a block for handling each (available) thrift property using reflection /// /// - parameter block: block for handling property /// /// - throws: rethrows any Error thrown in block private func forEach(_ block: (_ name: String, _ value: TSerializable, _ id: Int32) throws -> Void) rethrows { // Mirror the object, getting (name: String?, value: Any) for every property let mirror = Mirror(reflecting: self) // Iterate through all children, ignore empty property names for (propName, propValue) in mirror.children { guard let propName = propName else { continue } if let tval = unwrap(any: propValue, parent: mirror) as? TSerializable, let id = Self.fieldIds[propName] { try block(propName, tval, id) } } } /// Any can mysteriously be an Optional at the same time, /// this checks and always returns Optional without double wrapping /// we then try to bind value as TSerializable to ignore any extension properties /// and the like and verify the property exists and grab the Thrift /// property ID at the same time /// /// - parameter any: Any instance to attempt to unwrap /// /// - returns: Unwrapped Any as Optional private func unwrap(any: Any, parent: Mirror) -> Any? { let mi = Mirror(reflecting: any) if parent.displayStyle != .enum && mi.displayStyle != .optional { return any } if mi.children.count == 0 { return nil } let (_, some) = mi.children.first! return some } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/Thrift.swift0000664000175000017500000000151615170007142024220 0ustar00buildbuild00000000000000/* * 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. */ class Thrift { let version = "0.23.0" } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TBinary.swift0000664000175000017500000000212415165535636024346 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation extension Data : TSerializable { public static var thriftType: TType { return .string } public static func read(from proto: TProtocol) throws -> Data { return try proto.read() as Data } public func write(to proto: TProtocol) throws { try proto.write(self) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TMultiplexedProtocol.swift0000664000175000017500000000432215165535636027142 0ustar00buildbuild00000000000000/* * 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. */ extension String { static let multiplexSeparator = ":" } /** `TMultiplexedProtocol` is a protocol-independent concrete decorator that allows a Thrift client to communicate with a multiplexing Thrift server, by prepending the service name to the function name during function calls. - Note: THIS IS NOT USED BY SERVERS. On the server, use `TMultiplexedProcessor` to handle request from a multiplexing client. */ public class TMultiplexedProtocol: TWrappedProtocol { public var serviceName = "" public convenience init(on transport: TTransport, serviceName: String) { self.init(on: transport) self.serviceName = serviceName } override public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { switch messageType { case .call, .oneway: var serviceFunction = serviceName serviceFunction += serviceName == "" ? "" : .multiplexSeparator serviceFunction += name return try super.writeMessageBegin(name: serviceFunction, type: messageType, sequenceID: sequenceID) default: return try super.writeMessageBegin(name: name, type: messageType, sequenceID: sequenceID) } } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TBinaryProtocol.swift0000664000175000017500000003045615165535636026101 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public struct TBinaryProtocolVersion { static let version1 = Int32(bitPattern: 0x80010000) static let versionMask = Int32(bitPattern: 0xffff0000) } public class TBinaryProtocol: TProtocol { public var messageSizeLimit: UInt32 = 0 public var transport: TTransport // class level properties for setting global config (useful for server in lieu of Factory design) public static var strictRead: Bool = false public static var strictWrite: Bool = true private var strictRead: Bool private var strictWrite: Bool var currentMessageName: String? var currentFieldName: String? public convenience init(transport: TTransport, strictRead: Bool, strictWrite: Bool) { self.init(on: transport) self.strictRead = strictRead self.strictWrite = strictWrite } public required init(on transport: TTransport) { self.transport = transport self.strictWrite = TBinaryProtocol.strictWrite self.strictRead = TBinaryProtocol.strictRead } func readStringBody(_ size: Int) throws -> String { var data = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport read failed")) { data = try self.transport.readAll(size: size) } return String(data: data, encoding: String.Encoding.utf8) ?? "" } /// Mark: - TProtocol public func readMessageBegin() throws -> (String, TMessageType, Int32) { let size: Int32 = try read() var messageName = "" var type = TMessageType.exception if size < 0 { let version = size & TBinaryProtocolVersion.versionMask if version != TBinaryProtocolVersion.version1 { throw TProtocolError(error: .badVersion(expected: "\(TBinaryProtocolVersion.version1)", got: "\(version)")) } type = TMessageType(rawValue: Int32(size) & 0x00FF) ?? type messageName = try read() } else { if strictRead { let errorMessage = "Missing message version, old client? Message Name: \(currentMessageName ?? "")" throw TProtocolError(error: .invalidData, message: errorMessage) } if messageSizeLimit > 0 && size > Int32(messageSizeLimit) { throw TProtocolError(error: .sizeLimit(limit: Int(messageSizeLimit), got: Int(size))) } messageName = try readStringBody(Int(size)) type = TMessageType(rawValue: Int32(try read() as UInt8)) ?? type } let seqID: Int32 = try read() return (messageName, type, seqID) } public func readMessageEnd() throws { return } public func readStructBegin() throws -> String { return "" } public func readStructEnd() throws { return } public func readFieldBegin() throws -> (String, TType, Int32) { let fieldType = TType(rawValue: Int32(try read() as UInt8)) ?? TType.stop var fieldID: Int32 = 0 if fieldType != .stop { fieldID = Int32(try read() as Int16) } return ("", fieldType, fieldID) } public func readFieldEnd() throws { return } public func readMapBegin() throws -> (TType, TType, Int32) { var raw = Int32(try read() as UInt8) guard let keyType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for keyType TType: \(raw)") } raw = Int32(try read() as UInt8) guard let valueType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for valueType TType: \(raw)") } let size: Int32 = try read() return (keyType, valueType, size) } public func readMapEnd() throws { return } public func readSetBegin() throws -> (TType, Int32) { let raw = Int32(try read() as UInt8) guard let elementType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for elementType TType: \(raw)") } let size: Int32 = try read() return (elementType, size) } public func readSetEnd() throws { return } public func readListBegin() throws -> (TType, Int32) { let raw = Int32(try read() as UInt8) guard let elementType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for elementType TType: \(raw)") } let size: Int32 = try read() return (elementType, size) } public func readListEnd() throws { return } public func read() throws -> String { let data: Data = try read() guard let str = String.init(data: data, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Couldn't encode UTF-8 from data read") } return str } public func read() throws -> Bool { return (try read() as UInt8) == 1 } public func read() throws -> UInt8 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1) } return buff[0] } public func read() throws -> Int8 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1) } return buff.withUnsafeBytes { pntr in return pntr.load(as: Int8.self) } } public func read() throws -> Int16 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 2) } var ret = Int16(buff[0] & 0xff) << 8 ret |= Int16(buff[1] & 0xff) return ret } public func read() throws -> Int32 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 4) } var ret = Int32(buff[0] & 0xff) << 24 ret |= Int32(buff[1] & 0xff) << 16 ret |= Int32(buff[2] & 0xff) << 8 ret |= Int32(buff[3] & 0xff) return ret } public func read() throws -> Int64 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 8) } var ret = Int64(buff[0] & 0xff) << 56 ret |= Int64(buff[1] & 0xff) << 48 ret |= Int64(buff[2] & 0xff) << 40 ret |= Int64(buff[3] & 0xff) << 32 ret |= Int64(buff[4] & 0xff) << 24 ret |= Int64(buff[5] & 0xff) << 16 ret |= Int64(buff[6] & 0xff) << 8 ret |= Int64(buff[7] & 0xff) return ret } public func read() throws -> Double { let val = try read() as Int64 return Double(bitPattern: UInt64(bitPattern: val)) } public func read() throws -> Data { let size = Int(try read() as Int32) var data = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { data = try self.transport.readAll(size: size) } return data } public func read() throws -> UUID { let data = try self.transport.readAll(size: 16) let lsb = data[0..<8] let msb = data[8..<16] var id = UUID().uuid withUnsafeMutableBytes(of: &id) { pntr in var copyData = msb copyData.append(lsb) copyData.copyBytes(to: pntr) } return UUID(uuid: id) } // Write methods public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { if strictWrite { let version = TBinaryProtocolVersion.version1 | Int32(messageType.rawValue) try write(version) try write(name) try write(sequenceID) } else { try write(name) try write(UInt8(messageType.rawValue)) try write(sequenceID) } currentMessageName = name } public func writeMessageEnd() throws { currentMessageName = nil } public func writeStructBegin(name: String) throws { return } public func writeStructEnd() throws { return } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try write(UInt8(fieldType.rawValue)) try write(Int16(fieldID)) } public func writeFieldStop() throws { try write(UInt8(TType.stop.rawValue)) } public func writeFieldEnd() throws { return } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try write(UInt8(keyType.rawValue)) try write(UInt8(valueType.rawValue)) try write(size) } public func writeMapEnd() throws { return } public func writeSetBegin(elementType: TType, size: Int32) throws { try write(UInt8(elementType.rawValue)) try write(size) } public func writeSetEnd() throws { return } public func writeListBegin(elementType: TType, size: Int32) throws { try write(UInt8(elementType.rawValue)) try write(size) } public func writeListEnd() throws { return } public func write(_ value: String) throws { try write(value.data(using: .utf8)!) } public func write(_ value: Bool) throws { let byteVal: UInt8 = value ? 1 : 0 try write(byteVal) } public func write(_ value: UInt8) throws { let buff = Data([value]) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int8) throws { var value = value let buff = Data(bytes: &value, count: MemoryLayout.size(ofValue: value)) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int16) throws { var buff = Data() buff.append(Data([UInt8(0xff & (value >> 8))])) buff.append(Data([UInt8(0xff & (value))])) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int32) throws { var buff = Data() buff.append(Data([UInt8(0xff & (value >> 24))])) buff.append(Data([UInt8(0xff & (value >> 16))])) buff.append(Data([UInt8(0xff & (value >> 8))])) buff.append(Data([UInt8(0xff & (value))])) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int64) throws { var buff = Data() buff.append(Data([UInt8(0xff & (value >> 56))])) buff.append(Data([UInt8(0xff & (value >> 48))])) buff.append(Data([UInt8(0xff & (value >> 40))])) buff.append(Data([UInt8(0xff & (value >> 32))])) buff.append(Data([UInt8(0xff & (value >> 24))])) buff.append(Data([UInt8(0xff & (value >> 16))])) buff.append(Data([UInt8(0xff & (value >> 8))])) buff.append(Data([UInt8(0xff & (value))])) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Double) throws { // Notably unsafe, since Double and Int64 are the same size, this should work fine try self.write(Int64(bitPattern: value.bitPattern)) } public func write(_ data: Data) throws { try write(Int32(data.count)) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: data) } } public func write(_ value: UUID) throws { let data = withUnsafePointer(to: value.uuid) { Data(bytes: $0, count: MemoryLayout.size(ofValue: value.uuid)) } let msb = data[0..<8] let lsb = data[8..<16] var buff = Data() buff.append(lsb) buff.append(msb) try self.transport.write(data: buff) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TMultiplexedProcessor.swift0000664000175000017500000000651015165535636027321 0ustar00buildbuild00000000000000/* * 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. */ /** `TMultiplexedProcessor` is a `TProcessor` allowing a single `TServer` to provide multiple services. To do so, you instantiate the processor and then register additional processors with it, as shown in the following example: let processor = MultiplexedProcessor() processor.register(CalculatorProcessor(service: CalculatorService()), for: "Calculator") processor.register(WeatherProcessor(service: CalculatorService()), for: "Weather") let server = TPerfectServer(port: 9090, processor: processor, TCompactProtocol.self, TCompactProtocol.self) try server.start() */ public class MultiplexedProcessor: TProcessor { enum Error: Swift.Error { case incompatibleMessageType(TMessageType) case missingProcessor(String) case missingDefaultProcessor } private var processors = [String: TProcessor]() private var defaultProcessor: TProcessor? public init(defaultProcessor: TProcessor? = nil) { self.defaultProcessor = defaultProcessor } public func register(defaultProcessor processor: TProcessor) { defaultProcessor = processor } public func register(processor: TProcessor, for service: String) { processors[service] = processor } public func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { let message = try inProtocol.readMessageBegin() guard message.1 == .call || message.1 == .oneway else { throw Error.incompatibleMessageType(message.1) } if let separatorIndex = message.0.firstIndex(of: Character(.multiplexSeparator)) { let serviceName = String(message.0.prefix(upTo: separatorIndex)) let messageName = String(message.0.suffix(from: message.0.index(after: separatorIndex))) guard let processor = processors[serviceName] else { throw Error.missingProcessor(serviceName)} let storedMessage = StoredMessage(message: (messageName, message.1, message.2), proto: inProtocol) try processor.process(on: storedMessage, outProtocol: outProtocol) } else { guard let processor = defaultProcessor else { throw Error.missingDefaultProcessor } try processor.process(on: inProtocol, outProtocol: outProtocol) } } } private final class StoredMessage: TProtocolDecorator { private let message: (String, TMessageType, Int32) init(message: (String, TMessageType, Int32), proto: TProtocol) { self.message = message super.init(proto: proto) } required init(on transport: TTransport) { fatalError("init(on:) has not been implemented") } override func readMessageBegin() throws -> (String, TMessageType, Int32) { return message } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TFileTransport.swift0000664000175000017500000000531615165535636025724 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc #endif /// TFileTransport /// Foundation-less Swift File transport. /// Uses C fopen/fread/fwrite, /// provided by Glibc in linux and Darwin on OSX/iOS public class TFileTransport: TTransport { var fileHandle: UnsafeMutablePointer? = nil public init (fileHandle: UnsafeMutablePointer) { self.fileHandle = fileHandle } public convenience init(filename: String) throws { var fileHandle: UnsafeMutablePointer? filename.withCString({ cFilename in "rw".withCString({ cMode in fileHandle = fopen(cFilename, cMode) }) }) if let fileHandle = fileHandle { self.init(fileHandle: fileHandle) } else { throw TTransportError(error: .notOpen) } } deinit { fclose(self.fileHandle) } public func readAll(size: Int) throws -> Data { let read = try self.read(size: size) if read.count != size { throw TTransportError(error: .endOfFile) } return read } public func read(size: Int) throws -> Data { // set up read buffer, position 0 var read = Data(capacity: size) var position = 0 // read character buffer var nextChar: UInt8 = 0 // continue until we've read size bytes while read.count < size { if fread(&nextChar, 1, 1, self.fileHandle) == 1 { read[position] = nextChar // Increment output byte pointer position += 1 } else { throw TTransportError(error: .endOfFile) } } return read } public func write(data: Data) throws { let bytesWritten = data.withUnsafeBytes { fwrite($0.baseAddress!, 1, data.count, self.fileHandle) } if bytesWritten != data.count { throw TTransportError(error: .unknown) } } public func flush() throws { return } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TList.swift0000664000175000017500000000735515165535636024050 0ustar00buildbuild00000000000000/* * 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. */ public struct TList : RandomAccessCollection, MutableCollection, ExpressibleByArrayLiteral, TSerializable, Hashable { public typealias Storage = Array public typealias Indices = Storage.Indices internal var storage = Storage() public init() { } public init(arrayLiteral elements: Element...) { self.storage = Storage(elements) } public init(_ sequence: Source) where Source.Iterator.Element == Element { storage = Storage(sequence) } /// Mark: Hashable public func hash(into hasher: inout Hasher) { hasher.combine(storage) } /// Mark: TSerializable public static var thriftType : TType { return .list } public static func read(from proto: TProtocol) throws -> TList { let (elementType, size) = try proto.readListBegin() if elementType != Element.thriftType { throw TProtocolError(error: .invalidData, extendedError: .unexpectedType(type: elementType)) } var list = TList() for _ in 0.. Element { get { return storage[position] } set { storage[position] = newValue } } public subscript(range: Range) -> SubSequence { get { return storage[range] } set { storage[range] = newValue } } public var startIndex: Index { return storage.startIndex } public var endIndex: Index { return storage.endIndex } public func formIndex(after i: inout Index) { storage.formIndex(after: &i) } public func formIndex(before i: inout Int) { storage.formIndex(before: &i) } public func index(after i: Index) -> Index { return storage.index(after: i) } public func index(before i: Int) -> Int { return storage.index(before: i) } } extension TList : RangeReplaceableCollection { public mutating func replaceSubrange(_ subrange: Range, with newElements: C) where C.Iterator.Element == Element { storage.replaceSubrange(subrange, with: newElements) } } extension TList : CustomStringConvertible, CustomDebugStringConvertible { public var description : String { return storage.description } public var debugDescription : String { return storage.debugDescription } } public func ==(lhs: TList, rhs: TList) -> Bool { return lhs.storage.elementsEqual(rhs.storage) { $0 == $1 } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TSet.swift0000664000175000017500000001267415165535636023670 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public struct TSet : SetAlgebra, Hashable, Collection, ExpressibleByArrayLiteral, TSerializable { /// Typealias for Storage type public typealias Storage = Set /// Internal Storage used for TSet (Set\) internal var storage : Storage /// Mark: Collection public typealias Element = Storage.Element public typealias Indices = Storage.Indices public typealias Index = Storage.Index public typealias IndexDistance = Int public typealias SubSequence = Storage.SubSequence public var indices: Indices { return storage.indices } // Must implement isEmpty even though both SetAlgebra and Collection provide it due to their conflciting default implementations public var isEmpty: Bool { return storage.isEmpty } public func distance(from start: Index, to end: Index) -> IndexDistance { return storage.distance(from: start, to: end) } public func index(_ i: Index, offsetBy n: IndexDistance) -> Index { return storage.index(i, offsetBy: n) } public func index(_ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index) -> Index? { return storage.index(i, offsetBy: n, limitedBy: limit) } #if swift(>=3.2) public subscript (position: Storage.Index) -> Element { return storage[position] } #else public subscript (position: Storage.Index) -> Element? { return storage[position] } #endif /// Mark: SetAlgebra internal init(storage: Set) { self.storage = storage } public func contains(_ member: Element) -> Bool { return storage.contains(member) } public mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element) { return storage.insert(newMember) } public mutating func remove(_ member: Element) -> Element? { return storage.remove(member) } public func union(_ other: TSet) -> TSet { return TSet(storage: storage.union(other.storage)) } public mutating func formIntersection(_ other: TSet) { return storage.formIntersection(other.storage) } public mutating func formSymmetricDifference(_ other: TSet) { return storage.formSymmetricDifference(other.storage) } public mutating func formUnion(_ other: TSet) { return storage.formUnion(other.storage) } public func intersection(_ other: TSet) -> TSet { return TSet(storage: storage.intersection(other.storage)) } public func symmetricDifference(_ other: TSet) -> TSet { return TSet(storage: storage.symmetricDifference(other.storage)) } public mutating func update(with newMember: Element) -> Element? { return storage.update(with: newMember) } /// Mark: IndexableBase public var startIndex: Index { return storage.startIndex } public var endIndex: Index { return storage.endIndex } public func index(after i: Index) -> Index { return storage.index(after: i) } public func formIndex(after i: inout Storage.Index) { storage.formIndex(after: &i) } public subscript(bounds: Range) -> SubSequence { return storage[bounds] } /// Mark: Hashable public func hash(into hasher: inout Hasher) { hasher.combine(storage) } /// Mark: TSerializable public static var thriftType : TType { return .set } public init() { storage = Storage() } public init(arrayLiteral elements: Element...) { self.storage = Storage(elements) } public init(_ sequence: Source) where Source.Iterator.Element == Element { storage = Storage(sequence) } public static func read(from proto: TProtocol) throws -> TSet { let (elementType, size) = try proto.readSetBegin() if elementType != Element.thriftType { throw TProtocolError(error: .invalidData, extendedError: .unexpectedType(type: elementType)) } var set = TSet() for _ in 0..(lhs: TSet, rhs: TSet) -> Bool { return lhs.storage == rhs.storage } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TApplicationError.swift0000664000175000017500000001331715165535636026405 0ustar00buildbuild00000000000000/* * 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. */ public struct TApplicationError : TError { public enum Code : TErrorCode { case unknown case unknownMethod(methodName: String?) case invalidMessageType case wrongMethodName(methodName: String?) case badSequenceId case missingResult(methodName: String?) case internalError case protocolError case invalidTransform case invalidProtocol case unsupportedClientType /// Initialize a TApplicationError with a Thrift error code /// Normally this would be achieved with RawRepresentable however /// by doing this we can allow for associated properties on enum cases for /// case specific context data in a Swifty, type-safe manner. /// /// - parameter thriftErrorCode: Integer TApplicationError(exception) error code. /// Default to 0 (.unknown) public init(thriftErrorCode: Int) { switch thriftErrorCode { case 1: self = .unknownMethod(methodName: nil) case 2: self = .invalidMessageType case 3: self = .wrongMethodName(methodName: nil) case 4: self = .badSequenceId case 5: self = .missingResult(methodName: nil) case 6: self = .internalError case 7: self = .protocolError case 8: self = .invalidProtocol case 9: self = .invalidTransform case 10: self = .unsupportedClientType default: self = .unknown } } public var thriftErrorCode: Int { switch self { case .unknown: return 0 case .unknownMethod: return 1 case .invalidMessageType: return 2 case .wrongMethodName: return 3 case .badSequenceId: return 4 case .missingResult: return 5 case .internalError: return 6 case .protocolError: return 7 case .invalidProtocol: return 8 case .invalidTransform: return 9 case .unsupportedClientType: return 10 } } public var description: String { /// Output "for #methodName" if method is not nil else empty let methodUnwrap: (String?) -> String = { method in return "\(method == nil ? "" : " for \(method ?? "")")" } switch self { case .unknown: return "Unknown TApplicationError" case .unknownMethod(let method): return "Unknown Method\(methodUnwrap(method))" case .invalidMessageType: return "Invalid Message Type" case .wrongMethodName(let method): return "Wrong Method Name\(methodUnwrap(method))" case .badSequenceId: return "Bad Sequence ID" case .missingResult(let method): return "Missing Result\(methodUnwrap(method))" case .internalError: return "Internal Error" case .protocolError: return "Protocol Error" case .invalidProtocol: return "Invalid Protocol" case .invalidTransform: return "Invalid Transform" case .unsupportedClientType: return "Unsupported Client Type" } } } public init() { } public init(thriftErrorCode code: Int, message: String? = nil) { self.error = Code(thriftErrorCode: code) self.message = message } public var error: Code = .unknown public var message: String? = nil public static var defaultCase: Code { return .unknown } } extension TApplicationError : TSerializable { public static var thriftType: TType { return .struct } public static func read(from proto: TProtocol) throws -> TApplicationError { var errorCode: Int = 0 var message: String? = nil _ = try proto.readStructBegin() fields: while true { let (_, fieldType, fieldID) = try proto.readFieldBegin() switch (fieldID, fieldType) { case (_, .stop): break fields case (1, .string): message = try proto.read() case (2, .i32): errorCode = Int(try proto.read() as Int32) case let (_, unknownType): try proto.skip(type: unknownType) } try proto.readFieldEnd() } try proto.readStructEnd() return TApplicationError(thriftErrorCode: errorCode, message: message) } public func write(to proto: TProtocol) throws { try proto.writeStructBegin(name: "TApplicationException") try proto.writeFieldBegin(name: "message", type: .string, fieldID: 1) try proto.write(message ?? "") try proto.writeFieldEnd() try proto.writeFieldBegin(name: "type", type: .i32, fieldID: 2) let val = Int32(error.thriftErrorCode) try proto.write(val) try proto.writeFieldEnd() try proto.writeFieldStop() try proto.writeStructEnd() } } extension TApplicationError: Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(error.thriftErrorCode) hasher.combine(message) } } public func ==(lhs: TApplicationError, rhs: TApplicationError) -> Bool { return lhs.error.thriftErrorCode == rhs.error.thriftErrorCode && lhs.message == rhs.message } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TWrappedProtocol.swift0000664000175000017500000001354515165535636026257 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation // For (NS)Data /// Generic protocol, implementes TProtocol and wraps a concrete protocol. /// Useful for generically subclassing protocols to override specific methods /// (i.e. TMultiplexedProtocol) open class TWrappedProtocol : TProtocol { var concreteProtocol: Protocol public var transport: TTransport { get { return concreteProtocol.transport } set { concreteProtocol.transport = newValue } } public required init(on transport: TTransport) { self.concreteProtocol = Protocol(on: transport) } // Read methods public func readMessageBegin() throws -> (String, TMessageType, Int32) { return try concreteProtocol.readMessageBegin() } public func readMessageEnd() throws { try concreteProtocol.readMessageEnd() } public func readStructBegin() throws -> String { return try concreteProtocol.readStructBegin() } public func readStructEnd() throws { try concreteProtocol.readStructEnd() } public func readFieldBegin() throws -> (String, TType, Int32) { return try concreteProtocol.readFieldBegin() } public func readFieldEnd() throws { try concreteProtocol.readFieldEnd() } public func readMapBegin() throws -> (TType, TType, Int32) { return try concreteProtocol.readMapBegin() } public func readMapEnd() throws { try concreteProtocol.readMapEnd() } public func readSetBegin() throws -> (TType, Int32) { return try concreteProtocol.readSetBegin() } public func readSetEnd() throws { try concreteProtocol.readSetEnd() } public func readListBegin() throws -> (TType, Int32) { return try concreteProtocol.readListBegin() } public func readListEnd() throws { try concreteProtocol.readListEnd() } public func read() throws -> String { return try concreteProtocol.read() } public func read() throws -> Bool { return try concreteProtocol.read() } public func read() throws -> UInt8 { return try concreteProtocol.read() } public func read() throws -> Int8 { return try concreteProtocol.read() } public func read() throws -> Int16 { return try concreteProtocol.read() } public func read() throws -> Int32 { return try concreteProtocol.read() } public func read() throws -> Int64 { return try concreteProtocol.read() } public func read() throws -> Double { return try concreteProtocol.read() } public func read() throws -> Data { return try concreteProtocol.read() } public func read() throws -> UUID { return try concreteProtocol.read() } // Write methods public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { return try concreteProtocol.writeMessageBegin(name: name, type: messageType, sequenceID: sequenceID) } public func writeMessageEnd() throws { try concreteProtocol.writeMessageEnd() } public func writeStructBegin(name: String) throws { try concreteProtocol.writeStructBegin(name: name) } public func writeStructEnd() throws { try concreteProtocol.writeStructEnd() } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try concreteProtocol.writeFieldBegin(name: name, type: fieldType, fieldID: fieldID) } public func writeFieldStop() throws { try concreteProtocol.writeFieldStop() } public func writeFieldEnd() throws { try concreteProtocol.writeFieldEnd() } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try concreteProtocol.writeMapBegin(keyType: keyType, valueType: valueType, size: size) } public func writeMapEnd() throws { try concreteProtocol.writeMapEnd() } public func writeSetBegin(elementType: TType, size: Int32) throws { try concreteProtocol.writeSetBegin(elementType: elementType, size: size) } public func writeSetEnd() throws { try concreteProtocol.writeSetEnd() } public func writeListBegin(elementType: TType, size: Int32) throws { try concreteProtocol.writeListBegin(elementType: elementType, size: size) } public func writeListEnd() throws { try concreteProtocol.writeListEnd() } public func write(_ value: String) throws { try concreteProtocol.write(value) } public func write(_ value: Bool) throws { try concreteProtocol.write(value) } public func write(_ value: UInt8) throws { try concreteProtocol.write(value) } public func write(_ value: Int8) throws { try concreteProtocol.write(value) } public func write(_ value: Int16) throws { try concreteProtocol.write(value) } public func write(_ value: Int32) throws { try concreteProtocol.write(value) } public func write(_ value: Int64) throws { try concreteProtocol.write(value) } public func write(_ value: Double) throws { try concreteProtocol.write(value) } public func write(_ data: Data) throws { try concreteProtocol.write(data) } public func write(_ value: UUID) throws { try concreteProtocol.write(value) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TFramedTransport.swift0000664000175000017500000000632715165535636026246 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TFramedTransport: TTransport { public static let headerSize = 4 public static let initFrameSize = 1024 private static let defaultMaxLength = 16384000 public var transport: TTransport private var writeBuffer = Data() private var maxSize = TFramedTransport.defaultMaxLength private var remainingBytes = 0 public init(transport: TTransport, maxSize: Int) { self.transport = transport self.maxSize = maxSize } public convenience init(transport: TTransport) { self.init(transport: transport, maxSize: TFramedTransport.defaultMaxLength) } func readHeader() throws { let read = try transport.readAll(size: TFramedTransport.headerSize) remainingBytes = Int(decodeFrameSize(data: read)) } /// Mark: - TTransport public func read(size: Int) throws -> Data { while (remainingBytes <= 0) { try readHeader() } let toRead = min(size, remainingBytes) if toRead < 0 { try close() throw TTransportError(error: .negativeSize, message: "Read a negative frame size (\(toRead))!") } if toRead > maxSize { try close() throw TTransportError(error: .sizeLimit(limit: maxSize, got: toRead)) } let data = try transport.readAll(size: toRead) remainingBytes -= data.count return data } public func flush() throws { // copy buffer and reset let buff = writeBuffer writeBuffer = Data() let frameSize = encodeFrameSize(size: UInt32(buff.count)) try transport.write(data: frameSize) try transport.write(data: buff) try transport.flush() } public func write(data: Data) throws { writeBuffer.append(data) } private func encodeFrameSize(size: UInt32) -> Data { var data = Data() data.append(Data([UInt8(0xff & (size >> 24))])) data.append(Data([UInt8(0xff & (size >> 16))])) data.append(Data([UInt8(0xff & (size >> 8))])) data.append(Data([UInt8(0xff & (size))])) return data } private func decodeFrameSize(data: Data) -> UInt32 { var size: UInt32 size = (UInt32(data[0] & 0xff) << 24) size |= (UInt32(data[1] & 0xff) << 16) size |= (UInt32(data[2] & 0xff) << 8) size |= (UInt32(data[3] & 0xff)) return size } public func close() throws { try transport.close() } public func open() throws { try transport.open() } public func isOpen() throws -> Bool { return try transport.isOpen() } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TClient.swift0000664000175000017500000000254715165535636024351 0ustar00buildbuild00000000000000/* * 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. */ open class TClient { public let inProtocol: TProtocol public let outProtocol: TProtocol required public init(inoutProtocol: TProtocol) { self.inProtocol = inoutProtocol self.outProtocol = inoutProtocol } required public init(inProtocol: TProtocol, outProtocol: TProtocol) { self.inProtocol = inProtocol self.outProtocol = outProtocol } } open class TAsyncClient { public var factory: Factory public init(with protocol: Protocol.Type, factory: Factory) { self.factory = factory } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/THTTPSessionTransport.swift0000664000175000017500000001335015165535636027165 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation // Conditional import for URLRequest // It was moved from Foundation to FoundationNetworking in 5.1, but // not on Darwin. See https://stackoverflow.com/a/58606520 #if canImport(FoundationNetworking) import FoundationNetworking #endif import Dispatch public class THTTPSessionTransport: TAsyncTransport { public class Factory : TAsyncTransportFactory { public var responseValidate: ((HTTPURLResponse?, Data?) throws -> Void)? var session: URLSession var url: URL public class func setupDefaultsForSessionConfiguration(_ config: URLSessionConfiguration, withProtocolName protocolName: String?) { var thriftContentType = "application/x-thrift" if let protocolName = protocolName { thriftContentType += "; p=\(protocolName)" } config.requestCachePolicy = .reloadIgnoringLocalCacheData config.urlCache = nil config.httpShouldUsePipelining = true config.httpShouldSetCookies = true config.httpAdditionalHeaders = ["Content-Type": thriftContentType, "Accept": thriftContentType, "User-Agent": "Thrift/Swift (Session)"] } public init(session: URLSession, url: URL) { self.session = session self.url = url } public func newTransport() -> THTTPSessionTransport { return THTTPSessionTransport(factory: self) } func validateResponse(_ response: HTTPURLResponse?, data: Data?) throws { try responseValidate?(response, data) } func taskWithRequest(_ request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> ()) throws -> URLSessionTask { let newTask: URLSessionTask? = session.dataTask(with: request, completionHandler: completionHandler) if let newTask = newTask { return newTask } else { throw TTransportError(error: .unknown, message: "Failed to create session data task") } } } var factory: Factory var requestData = Data() var responseData = Data() var responseDataOffset: Int = 0 init(factory: Factory) { self.factory = factory } public func readAll(size: Int) throws -> Data { let read = try self.read(size: size) if read.count != size { throw TTransportError(error: .endOfFile) } return read } public func read(size: Int) throws -> Data { let avail = responseData.count - responseDataOffset let (start, stop) = (responseDataOffset, responseDataOffset + min(size, avail)) let read = responseData.subdata(in: start.. Void) { var error: Error? var task: URLSessionTask? var request = URLRequest(url: factory.url) request.httpMethod = "POST" request.httpBody = requestData requestData = Data() do { task = try factory.taskWithRequest(request, completionHandler: { (data, response, taskError) in // Check if there was an error with the network if taskError != nil { error = TTransportError(error: .timedOut) completed(self, error) return } // Check response type if taskError == nil && !(response is HTTPURLResponse) { error = THTTPTransportError(error: .invalidResponse) completed(self, error) return } // Check status code if let httpResponse = response as? HTTPURLResponse { if taskError == nil && httpResponse.statusCode != 200 { if httpResponse.statusCode == 401 { error = THTTPTransportError(error: .authentication) } else { error = THTTPTransportError(error: .invalidStatus(statusCode: httpResponse.statusCode)) } } // Allow factory to check if error != nil { do { try self.factory.validateResponse(httpResponse, data: data) } catch let validateError { error = validateError } } self.responseDataOffset = 0 if error != nil { self.responseData = Data() } else { self.responseData = data ?? Data() } completed(self, error) } }) } catch let taskError { error = taskError } if let error = error, task == nil { completed(self, error) } task?.resume() } public func flush() throws { let completed = DispatchSemaphore(value: 0) var internalError: Error? flush() { _, error in internalError = error completed.signal() } _ = completed.wait(timeout: DispatchTime.distantFuture) if let error = internalError { throw error } } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/UnixSocket.swift0000664000175000017500000000535215165535636025100 0ustar00buildbuild00000000000000/* * 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. */ #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc import Dispatch #endif import Foundation private struct Sys { #if os(Linux) static let read = Glibc.read static let write = Glibc.write static let close = Glibc.close static let socket = Glibc.socket static let connect = Glibc.connect static let bind = Glibc.bind static let recv = Glibc.recv #else static let read = Darwin.read static let write = Darwin.write static let close = Darwin.close static let socket = Darwin.socket static let connect = Darwin.connect static let bind = Darwin.bind static let recv = Darwin.recv #endif } public class UnixSocket { public var fd: Int32 private var socketAddress: sockaddr_un public init(path: String) { socketAddress = sockaddr_un() socketAddress.sun_family = sa_family_t(AF_UNIX) let lengthOfPath = path.withCString { Int(strlen($0)) } guard lengthOfPath < MemoryLayout.size(ofValue: socketAddress.sun_path) else { fatalError() } _ = withUnsafeMutablePointer(to: &socketAddress.sun_path.0) { ptr in path.withCString { strncpy(ptr, $0, lengthOfPath) } } #if os(Linux) fd = Sys.socket(AF_UNIX, 1 /*SOCK_STREAM*/, 0); #else fd = Sys.socket(AF_UNIX, SOCK_STREAM, 0); #endif } public func connect() -> 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))) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/LinuxHelper.swift0000664000175000017500000000304015165535636025233 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import CoreFoundation #if os(Linux) /// Extensions for Linux for incomplete Foundation API's. /// swift-corelibs-foundation is not yet 1:1 with OSX/iOS Foundation extension UInt { public static func &(lhs: UInt, rhs: Int) -> UInt { let cast = UInt(bitPattern: rhs) return lhs & cast } } #else extension CFStreamPropertyKey { static let shouldCloseNativeSocket = CFStreamPropertyKey(kCFStreamPropertyShouldCloseNativeSocket) // Exists as Stream.PropertyKey.socketSecuritylevelKey but doesn't work with CFReadStreamSetProperty static let socketSecurityLevel = CFStreamPropertyKey(kCFStreamPropertySocketSecurityLevel) static let SSLSettings = CFStreamPropertyKey(kCFStreamPropertySSLSettings) } #endif thrift-0.23.0/tutorial/swift/swift-dep/Sources/TSerializable.swift0000664000175000017500000000710715165535636025536 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public protocol TSerializable { /// TType for instance static var thriftType: TType { get } /// Read TSerializable instance from Protocol static func read(from proto: TProtocol) throws -> Self /// Write TSerializable instance to Protocol func write(to proto: TProtocol) throws } extension TSerializable { public static func write(_ value: Self, to proto: TProtocol) throws { try value.write(to: proto) } /// convenience for member access public var thriftType: TType { return Self.thriftType } } /// Default read/write for primitave Thrift types: /// Bool, Int8 (byte), Int16, Int32, Int64, Double, String extension Bool : TSerializable { public static var thriftType: TType { return .bool } public static func read(from proto: TProtocol) throws -> Bool { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Int8 : TSerializable { public static var thriftType: TType { return .i8 } public static func read(from proto: TProtocol) throws -> Int8 { return try proto.read() as Int8 } public func write(to proto: TProtocol) throws { try proto.write(Int8(self)) } } extension Int16 : TSerializable { public static var thriftType: TType { return .i16 } public static func read(from proto: TProtocol) throws -> Int16 { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Int32 : TSerializable { public static var thriftType: TType { return .i32 } public static func read(from proto: TProtocol) throws -> Int32 { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Int64 : TSerializable { public static var thriftType: TType { return .i64 } public static func read(from proto: TProtocol) throws -> Int64 { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Double : TSerializable { public static var thriftType: TType { return .double } public static func read(from proto: TProtocol) throws -> Double { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension String : TSerializable { public static var thriftType: TType { return .string } public static func read(from proto: TProtocol) throws -> String { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension UUID : TSerializable { public static var thriftType: TType { .uuid } public static func read(from proto: TProtocol) throws -> UUID { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TSocketServer.swift0000664000175000017500000001711215165535636025544 0ustar00buildbuild00000000000000/* * 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. */ #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc import Dispatch #endif import Foundation import CoreFoundation public let TSocketServerClientConnectionFinished = "TSocketServerClientConnectionFinished" public let TSocketServerProcessorKey = "TSocketServerProcessor" public let TSocketServerTransportKey = "TSocketServerTransport" open class TSocketServer { var socketFileHandle: FileHandle var processingQueue = DispatchQueue(label: "TSocketServer.processing", qos: .background, attributes: .concurrent) let processor: Processor public init(port: Int, inProtocol: InProtocol.Type, outProtocol: OutProtocol.Type, processor: Processor) throws { self.processor = processor // create a socket var fd: Int32 = -1 #if os(Linux) let sock = CFSocketCreate(kCFAllocatorDefault, PF_INET, Int32(SOCK_STREAM.rawValue), Int32(IPPROTO_TCP), 0, nil, nil) #else let sock = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, 0, nil, nil) #endif if sock != nil { CFSocketSetSocketFlags(sock, CFSocketGetSocketFlags(sock) & ~CFOptionFlags(kCFSocketCloseOnInvalidate)) fd = CFSocketGetNative(sock) var yes = 1 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, UInt32(MemoryLayout.size)) let inPort = in_port_t(UInt16(truncatingIfNeeded: port).bigEndian) #if os(Linux) var addr = sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: inPort, sin_addr: in_addr(s_addr: in_addr_t(0)), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #else var addr = sockaddr_in(sin_len: UInt8(MemoryLayout.size), sin_family: sa_family_t(AF_INET), sin_port: inPort, sin_addr: in_addr(s_addr: in_addr_t(0)), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #endif let ptr = withUnsafePointer(to: &addr) { return UnsafePointer(OpaquePointer($0)) } let address = Data(bytes: ptr, count: MemoryLayout.size) let cfaddr = address.withUnsafeBytes { CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, $0.bindMemory(to: UInt8.self).baseAddress!, address.count, kCFAllocatorNull) } if CFSocketSetAddress(sock, cfaddr) != CFSocketError.success { //kCFSocketSuccess { CFSocketInvalidate(sock) print("TSocketServer: Could not bind to address") throw TTransportError(error: .notOpen, message: "Could not bind to address") } } else { print("TSocketServer: No server socket") throw TTransportError(error: .notOpen, message: "Could not create socket") } // wrap it in a file handle so we can get messages from it socketFileHandle = FileHandle(fileDescriptor: fd, closeOnDealloc: true) // throw away our socket CFSocketInvalidate(sock) print("TSocketServer: Listening on TCP port \(port)") // tell socket to listen acceptConnectionInBackgroundAndNotify(handle: socketFileHandle) } public init(path: String, inProtocol: InProtocol.Type, outProtocol: OutProtocol.Type, processor: Processor) throws { self.processor = processor // create a socket let socket = UnixSocket(path: path) let fd = socket.fd if fd == -1 { print("TSocketServer: No server socket") throw TTransportError(error: .notOpen, message: "Could not create socket") } // wrap it in a file handle so we can get messages from it socketFileHandle = FileHandle(fileDescriptor: fd, closeOnDealloc: true) // register for notifications of accepted incoming connections _ = NotificationCenter.default.addObserver(forName: .NSFileHandleConnectionAccepted, object: nil, queue: nil) { [weak self] notification in guard let strongSelf = self else { return } guard let clientSocket = notification.userInfo?[NSFileHandleNotificationFileHandleItem] as? FileHandle else { return } strongSelf.connectionAccepted(clientSocket) } let bindRes = socket.bind() guard bindRes == 0 else { print("TServerSocket: bind failed") throw TTransportError(error: .notOpen, message: "Could not create socket") } let listenRes = listen(fd, 1024) guard listenRes == 0 else { print("TServerSocket: listen failed") throw TTransportError(error: .notOpen, message: "Could not create socket") } // tell socket to listen acceptConnectionInBackgroundAndNotify(handle: socketFileHandle) print("TSocketServer: Listening on unix path \(path)") } private func acceptConnectionInBackgroundAndNotify(handle: FileHandle) { DispatchQueue(label: "TSocketServer.connectionAccept").async { let acceptedFD = accept(handle.fileDescriptor, nil, nil) DispatchQueue.main.async { self.connectionAccepted(FileHandle(fileDescriptor: acceptedFD)) } } } func connectionAccepted(_ clientSocket: FileHandle) { // Now that we have a client connected, handle the request on queue processingQueue.async { self.handleClientConnection(clientSocket) } // continue accepting connections acceptConnectionInBackgroundAndNotify(handle: socketFileHandle) } open func createTransport(fileHandle: FileHandle) -> TTransport { return TFileHandleTransport(fileHandle: fileHandle) } func handleClientConnection(_ clientSocket: FileHandle) { let transport = createTransport(fileHandle: clientSocket) let inProtocol = InProtocol(on: transport) let outProtocol = OutProtocol(on: transport) do { while true { try processor.process(on: inProtocol, outProtocol: outProtocol) } } catch let error { print("Error processing request: \(error)") } DispatchQueue.main.async { NotificationCenter.default .post(name: Notification.Name(rawValue: TSocketServerClientConnectionFinished), object: nil, userInfo: [TSocketServerProcessorKey: self.processor, TSocketServerTransportKey: transport]) } } } public class TFramedSocketServer: TSocketServer { open override func createTransport(fileHandle: FileHandle) -> TTransport { return TFramedTransport(transport: super.createTransport(fileHandle: fileHandle)) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TProtocolDecorator.swift0000664000175000017500000001130015165535636026562 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation class TProtocolDecorator: TProtocol { private let proto: TProtocol var transport: TTransport init(proto: TProtocol) { self.proto = proto self.transport = proto.transport } required init(on transport: TTransport) { fatalError("init(on:) has not been implemented") } func readMessageBegin() throws -> (String, TMessageType, Int32) { return try proto.readMessageBegin() } func readMessageEnd() throws { try proto.readMessageEnd() } func readStructBegin() throws -> String { return try proto.readStructBegin() } func readStructEnd() throws { try proto.readStructEnd() } func readFieldBegin() throws -> (String, TType, Int32) { return try proto.readFieldBegin() } func readFieldEnd() throws { try proto.readFieldEnd() } func readMapBegin() throws -> (TType, TType, Int32) { return try proto.readMapBegin() } func readMapEnd() throws { try proto.readMapEnd() } func readSetBegin() throws -> (TType, Int32) { return try proto.readSetBegin() } func readSetEnd() throws { try proto.readSetEnd() } func readListBegin() throws -> (TType, Int32) { return try proto.readListBegin() } func readListEnd() throws { try proto.readListEnd() } func read() throws -> String { return try proto.read() } func read() throws -> Bool { return try proto.read() } func read() throws -> UInt8 { return try proto.read() } func read() throws -> Int8 { return try proto.read() } func read() throws -> Int16 { return try proto.read() } func read() throws -> Int32 { return try proto.read() } func read() throws -> Int64 { return try proto.read() } func read() throws -> Double { return try proto.read() } func read() throws -> Data { return try proto.read() } func read() throws -> UUID { return try proto.read() } func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { try proto.writeMessageBegin(name: name, type: messageType, sequenceID: sequenceID) } func writeMessageEnd() throws { try proto.writeMessageEnd() } func writeStructBegin(name: String) throws { try proto.writeStructBegin(name: name) } func writeStructEnd() throws { try proto.writeStructEnd() } func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try proto.writeFieldBegin(name: name, type: fieldType, fieldID: fieldID) } func writeFieldStop() throws { try proto.writeFieldStop() } func writeFieldEnd() throws { try proto.writeFieldEnd() } func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try proto.writeMapBegin(keyType: keyType, valueType: valueType, size: size) } func writeMapEnd() throws { try proto.writeMapEnd() } func writeSetBegin(elementType: TType, size: Int32) throws { try proto.writeSetBegin(elementType: elementType, size: size) } func writeSetEnd() throws { try proto.writeSetEnd() } func writeListBegin(elementType: TType, size: Int32) throws { try proto.writeListBegin(elementType: elementType, size: size) } func writeListEnd() throws { try proto.writeListEnd() } func write(_ value: String) throws { try proto.write(value) } func write(_ value: Bool) throws { try proto.write(value) } func write(_ value: UInt8) throws { try proto.write(value) } func write(_ value: Int8) throws { try proto.write(value) } func write(_ value: Int16) throws { try proto.write(value) } func write(_ value: Int32) throws { try proto.write(value) } func write(_ value: Int64) throws { try proto.write(value) } func write(_ value: Double) throws { try proto.write(value) } func write(_ value: Data) throws { try proto.write(value) } func write(_ value: UUID) throws { try proto.write(value) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TBase64Utils.swift0000664000175000017500000000770215165535636025176 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TBase64Utils { private static let EncodeTable: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" private static let NA: UInt8 = UInt8(255) private static let DecodeTable: [UInt8] = [ NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62, NA, NA, NA, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NA, NA, NA, NA, NA, NA, NA, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NA, NA, NA, NA, NA, NA, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ] static func encode(src: [UInt8], srcOff: Int, len: Int, dst: inout [UInt8], dstOff: Int) { if (src.count == 0) { return } var index: UInt8 = 0 index = src[srcOff] >> 2 & 0x3F dst[dstOff] = EncodeTable[Int(index)].asciiValue! if (len == 3) { index = ((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F) dst[dstOff + 1] = EncodeTable[Int(index)].asciiValue! index = ((src[srcOff + 1] << 2) & 0x3C) | ((src[srcOff + 2] >> 6) & 0x03) dst[dstOff + 2] = EncodeTable[Int(index)].asciiValue! index = (src[srcOff + 2] & 0x3F) dst[dstOff + 3] = EncodeTable[Int(index)].asciiValue! } else if (len == 2) { index = ((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F) dst[dstOff + 1] = EncodeTable[Int(index)].asciiValue! index = ((src[srcOff + 1] << 2) & 0x3C) dst[dstOff + 2] = EncodeTable[Int(index)].asciiValue! } else { // len == 1 index = ((src[srcOff] << 4) & 0x30) dst[dstOff + 1] = EncodeTable[Int(index)].asciiValue! } } static func decode(src: [UInt8], srcOff: Int, len: Int, dst: inout [UInt8], dstOff: Int) { if (src.count == 0) { return } dst[dstOff] = (DecodeTable[Int(src[srcOff] & 0x0FF)] << 2) | (DecodeTable[Int(src[srcOff + 1] & 0x0FF)] >> 4) if (len > 2) { dst[dstOff + 1] = ((DecodeTable[Int(src[srcOff + 1] & 0x0FF)] << 4) & 0xF0) | (DecodeTable[Int(src[srcOff + 2] & 0x0FF)] >> 2) if (len > 3) { dst[dstOff + 2] = ((DecodeTable[Int(src[srcOff + 2] & 0x0FF)] << 6) & 0xC0) | (DecodeTable[Int(src[srcOff + 3] & 0x0FF)]) } } } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TFileHandleTransport.swift0000664000175000017500000000314015165535636027031 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TFileHandleTransport: TTransport { var inputFileHandle: FileHandle var outputFileHandle: FileHandle public init(inputFileHandle: FileHandle, outputFileHandle: FileHandle) { self.inputFileHandle = inputFileHandle self.outputFileHandle = outputFileHandle } public convenience init(fileHandle: FileHandle) { self.init(inputFileHandle: fileHandle, outputFileHandle: fileHandle) } public func read(size: Int) throws -> Data { var data = Data() while data.count < size { let read = inputFileHandle.readData(ofLength: size - data.count) data.append(read) if read.count == 0 { break } } return data } public func write(data: Data) throws { outputFileHandle.write(data) } public func flush() throws { return } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TMap.swift0000664000175000017500000001220615165535636023641 0ustar00buildbuild00000000000000/* * 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. */ public struct TMap: Collection, ExpressibleByDictionaryLiteral, Hashable, TSerializable { public typealias Storage = Dictionary public typealias Element = Storage.Element public typealias Index = Storage.Index public typealias IndexDistance = Int public typealias Indices = Storage.Indices public typealias SubSequence = Storage.SubSequence internal var storage = Storage() /// Mark: Be Like Dictionary public func indexForKey(_ key: Key) -> Index? { return storage.index(forKey: key) } public mutating func updateValue(_ value: Value, forKey key: Key) -> Value? { return storage.updateValue(value, forKey: key) } public mutating func removeValueForKey(_ key: Key) -> Value? { return storage.removeValue(forKey: key) } public init(minimumCapacity: Int) { storage = Storage(minimumCapacity: minimumCapacity) } /// init from Dictionary public init(_ dict: [Key: Value]) { storage = dict } /// read only access to storage if needed as Dictionary public var dictionary: [Key: Value] { return storage } public subscript (key: Key) -> Value? { get { return storage[key] } set { storage[key] = newValue } } /// Mark: Collection public var indices: Indices { return storage.indices } public func distance(from start: Index, to end: Index) -> IndexDistance { return storage.distance(from: start, to: end) } public func index(_ i: Index, offsetBy n: IndexDistance) -> Index { return storage.index(i, offsetBy: n) } public func index(_ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index) -> Index? { return storage.index(i, offsetBy: n, limitedBy: limit) } public subscript(position: Index) -> Element { return storage[position] } /// Mark: IndexableBase public var startIndex: Index { return storage.startIndex } public var endIndex: Index { return storage.endIndex } public func index(after i: Index) -> Index { return storage.index(after: i) } public func formIndex(after i: inout Index) { storage.formIndex(after: &i) } public subscript(bounds: Range) -> SubSequence { return storage[bounds] } /// Mark: DictionaryLiteralConvertible public init(dictionaryLiteral elements: (Key, Value)...) { storage = Storage() for (key, value) in elements { storage[key] = value } } /// Mark: Hashable public func hash(into hasher: inout Hasher) { hasher.combine(storage) } /// Mark: TSerializable public static var thriftType : TType { return .map } public init() { storage = Storage() } public static func read(from proto: TProtocol) throws -> TMap { let (keyType, valueType, size) = try proto.readMapBegin() if size > 0 { if keyType != Key.thriftType { throw TProtocolError(error: .invalidData, message: "Unexpected TMap Key Type", extendedError: .unexpectedType(type: keyType)) } if valueType != Value.thriftType { throw TProtocolError(error: .invalidData, message: "Unexpected TMap Value Type", extendedError: .unexpectedType(type: valueType)) } } var map = TMap() for _ in 0..(lhs: TMap, rhs: TMap) -> Bool { if lhs.count != rhs.count { return false } return lhs.storage == rhs.storage } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TStreamTransport.swift0000664000175000017500000001042715165535636026277 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import CoreFoundation #if !swift(>=4.2) // Swift 3/4 compatibility fileprivate extension RunLoopMode { static let `default` = defaultRunLoopMode } #endif #if os(Linux) /// Currently unavailable in Linux /// Remove comments and build to fix /// Currently kConstants for CFSockets don't exist in linux and not all have been moved /// to property structs yet #else // Must inherit NSObject for NSStreamDelegate conformance public class TStreamTransport : NSObject, TTransport { public var input: InputStream? = nil public var output: OutputStream? = nil public init(inputStream: InputStream?, outputStream: OutputStream?) { input = inputStream output = outputStream } public convenience init(inputStream: InputStream?) { self.init(inputStream: inputStream, outputStream: nil) } public convenience init(outputStream: OutputStream?) { self.init(inputStream: nil, outputStream: outputStream) } deinit { close() } public func readAll(size: Int) throws -> Data { guard let input = input else { throw TTransportError(error: .unknown) } var read = Data() while read.count < size { var buffer = Array(repeating: 0, count: size - read.count) let bytesRead = buffer.withUnsafeMutableBufferPointer { bufferPtr in return input.read(bufferPtr.baseAddress!, maxLength: size - read.count) } if bytesRead <= 0 { throw TTransportError(error: .notOpen) } read.append(Data(buffer)) } return read } public func read(size: Int) throws -> Data { guard let input = input else { throw TTransportError(error: .unknown) } var read = Data() while read.count < size { var buffer = Array(repeating: 0, count: size - read.count) let bytesRead = buffer.withUnsafeMutableBufferPointer { input.read($0.baseAddress!, maxLength: size - read.count) } if bytesRead <= 0 { break } read.append(Data(buffer)) } return read } public func write(data: Data) throws { guard let output = output else { throw TTransportError(error: .unknown) } var bytesWritten = 0 while bytesWritten < data.count { bytesWritten = data.withUnsafeBytes { output.write($0.bindMemory(to: UInt8.self).baseAddress!, maxLength: data.count) } if bytesWritten == -1 { throw TTransportError(error: .notOpen) } else if bytesWritten == 0 { throw TTransportError(error: .endOfFile) } } } public func flush() throws { return } public func close() { if input != nil { // Close and reset inputstream if let cf: CFReadStream = input { CFReadStreamSetProperty(cf, .shouldCloseNativeSocket, kCFBooleanTrue) } input?.delegate = nil input?.close() input?.remove(from: .current, forMode: .default) input = nil } if output != nil { // Close and reset output stream if let cf: CFWriteStream = output { CFWriteStreamSetProperty(cf, .shouldCloseNativeSocket, kCFBooleanTrue) } output?.delegate = nil output?.close() output?.remove(from: .current, forMode: .default) output = nil } } } #endif thrift-0.23.0/tutorial/swift/swift-dep/Sources/TMemoryBufferTransport.swift0000664000175000017500000000426315165535636027447 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TMemoryBufferTransport : TTransport { public private(set) var readBuffer = Data() public private(set) var writeBuffer = Data() public private(set) var position = 0 public var bytesRemainingInBuffer: Int { return readBuffer.count - position } public func consumeBuffer(size: Int) { position += size } public func clear() { readBuffer = Data() writeBuffer = Data() } private var flushHandler: ((TMemoryBufferTransport, Data) -> ())? public init(flushHandler: ((TMemoryBufferTransport, Data) -> ())? = nil) { self.flushHandler = flushHandler } public convenience init(readBuffer: Data, flushHandler: ((TMemoryBufferTransport, Data) -> ())? = nil) { self.init() self.readBuffer = readBuffer } public func reset(readBuffer: Data = Data(), writeBuffer: Data = Data()) { self.readBuffer = readBuffer self.writeBuffer = writeBuffer } public func read(size: Int) throws -> Data { let amountToRead = min(bytesRemainingInBuffer, size) if amountToRead > 0 { let ret = readBuffer.subdata(in: Range(uncheckedBounds: (lower: position, upper: position + amountToRead))) position += ret.count return ret } return Data() } public func write(data: Data) throws { writeBuffer.append(data) } public func flush() throws { flushHandler?(self, writeBuffer) } } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TTransport.swift0000664000175000017500000000341515165535636025122 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public protocol TTransport { // Required func read(size: Int) throws -> Data func write(data: Data) throws func flush() throws // Optional (default provided) func readAll(size: Int) throws -> Data func isOpen() throws -> Bool func open() throws func close() throws } public extension TTransport { func isOpen() throws -> Bool { return true } func open() throws { } func close() throws { } func readAll(size: Int) throws -> Data { var buff = Data() var have = 0 while have < size { let chunk = try self.read(size: size - have) have += chunk.count buff.append(chunk) if chunk.count == 0 { throw TTransportError(error: .endOfFile) } } return buff } } public protocol TAsyncTransport : TTransport { // Factory func flush(_ completion: @escaping (TAsyncTransport, Error?) ->()) } public protocol TAsyncTransportFactory { associatedtype Transport : TAsyncTransport func newTransport() -> Transport } thrift-0.23.0/tutorial/swift/swift-dep/Sources/TProcessor.swift0000664000175000017500000000157315165535636025110 0ustar00buildbuild00000000000000/* * 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. */ public protocol TProcessor { func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws } thrift-0.23.0/tutorial/swift/swift-dep/Makefile.in0000644000175000017500000006066215170007167022340 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/swift ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . EXTRA_DIST = \ Package.swift \ Sources \ Tests \ FuzzTesting \ README.md MAINTAINERCLEANFILES = \ Makefile \ Makefile.in all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/swift/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/swift/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-exec-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile all-local: swift build --configuration release install-exec-hook: swift install clean-local: swift package clean rm -rf .build rm -rf FuzzTesting/.build rm -rf FuzzTesting/Sources/Fuzz/* precross: swift build check-local: swift test FuzzTesting/Sources/Fuzz: mkdir -p FuzzTesting/Sources/Fuzz fuzz-gen: FuzzTesting/Sources/Fuzz $(top_builddir)/compiler/cpp/thrift --gen swift -r -out FuzzTesting/Sources/Fuzz $(top_srcdir)/test/FuzzTest.thrift fuzz-local: fuzz-gen cd FuzzTesting && swift build --configuration release ${SWIFTFLAGS} fuzz: all-local fuzz-local @echo "Built fuzzers successfully" distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/swift/swift-dep/Makefile.am0000664000175000017500000000306615165535636022337 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . all-local: swift build --configuration release install-exec-hook: swift install clean-local: swift package clean rm -rf .build rm -rf FuzzTesting/.build rm -rf FuzzTesting/Sources/Fuzz/* precross: swift build check-local: swift test FuzzTesting/Sources/Fuzz: mkdir -p FuzzTesting/Sources/Fuzz fuzz-gen: FuzzTesting/Sources/Fuzz $(top_builddir)/compiler/cpp/thrift --gen swift -r -out FuzzTesting/Sources/Fuzz $(top_srcdir)/test/FuzzTest.thrift fuzz-local: fuzz-gen cd FuzzTesting && swift build --configuration release ${SWIFTFLAGS} fuzz: all-local fuzz-local @echo "Built fuzzers successfully" distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ Package.swift \ Sources \ Tests \ FuzzTesting \ README.md MAINTAINERCLEANFILES = \ Makefile \ Makefile.in thrift-0.23.0/tutorial/swift/Package.swift0000664000175000017500000000415115165535636021006 0ustar00buildbuild00000000000000// 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 thriftDependency: Target.Dependency = .product(name: "Thrift", package: "swift-dep") let package = Package( name: "swift-tutorial", platforms: [ .macOS(.v10_13) ], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .executable(name: "TutorialServer", targets: ["TutorialServer"]), .executable(name: "TutorialClient", targets: ["TutorialClient"]), .executable(name: "TutorialRunner", targets: ["TutorialRunner"]) ], dependencies: [ // Dependencies declare other packages that this package depends on. .package(path: "./swift-dep"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "Common", dependencies: [thriftDependency]), .target( name: "TutorialServer", dependencies: [thriftDependency, "Common"]), .target( name: "TutorialClient", dependencies: [thriftDependency, "Common"]), .target(name: "TutorialRunner") ] ) thrift-0.23.0/tutorial/swift/README.md0000664000175000017500000000034415165535636017654 0ustar00buildbuild00000000000000# Thrift Swift Tutorial ================================================== ## Run the tutorial code (client + server): `make tutorial` ## Run the server only `make tutorialserver` ## Run the client only `make tutorialclient` thrift-0.23.0/tutorial/swift/Sources/0000755000175000017500000000000015170007202017770 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/Sources/TutorialRunner/0000755000175000017500000000000015170007202022765 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/Sources/TutorialRunner/main.swift0000664000175000017500000000224615165535636025022 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation let swiftUrl = URL(fileURLWithPath: "/usr/bin/swift") let server = Process() server.executableURL = swiftUrl server.arguments = ["run", "TutorialServer"] try server.run() Thread.sleep(forTimeInterval: 2) let client = Process() client.executableURL = swiftUrl client.arguments = ["run", "TutorialClient"] try client.run() client.waitUntilExit() server.terminate() thrift-0.23.0/tutorial/swift/Sources/TutorialServer/0000755000175000017500000000000015170007202022762 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/Sources/TutorialServer/main.swift0000664000175000017500000000210615165535636025012 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import Common import Thrift let service = CalculatorService() let processor = CalculatorProcessor(service: service) let server = try TSocketServer(port: 9090, inProtocol: TBinaryProtocol.self, outProtocol: TBinaryProtocol.self, processor: processor) RunLoop.main.run() thrift-0.23.0/tutorial/swift/Sources/TutorialServer/CalculatorService.swift0000664000175000017500000000413415165535636027503 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import Common struct CalculatorError: Error { } class CalculatorService: Calculator { var resultMap = [Int32:SharedStruct]() func ping() throws { print("ping()") } func add(num1: Int32, num2: Int32) throws -> Int32 { print("add(\(num1), \(num2))") return num1 + num2 } func calculate(logid: Int32, w: Work) throws -> Int32 { print("calculate(\(logid), \(w))") let result: Int32 = try { switch w.op { case .add: return w.num1 + w.num2 case .subtract: return w.num1 - w.num2 case .multiply: return w.num1 * w.num2 case .divide: guard w.num2 != 0 else { throw InvalidOperation(whatOp: w.op.rawValue, why: "Cannot divide by 0") } return w.num1 / w.num2 } }() let resultEntry = SharedStruct(key: logid, value: "\(result)") resultMap[logid] = resultEntry return result } func zip() throws { print("zip()") } func getStruct(key: Int32) throws -> SharedStruct { print("getStruct(\(key))") guard let entry = resultMap[key] else { throw CalculatorError() } return entry } } thrift-0.23.0/tutorial/swift/Sources/TutorialClient/0000755000175000017500000000000015170007202022732 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/swift/Sources/TutorialClient/main.swift0000664000175000017500000000270715165535636024771 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import Thrift import Common let transport = try TSocketTransport(hostname: "localhost", port: 9090) let inOutProto = TBinaryProtocol(on: transport) let client = CalculatorClient(inoutProtocol: inOutProto) try client.ping() print("1+1= \(try client.add(num1: 1, num2: 1))") let work = Work(num1: 1, num2: 0, op: .divide) do { _ = try client.calculate(logid: 1, w: work) assertionFailure("Hm... shouldn't be able to divide by zero") } catch let error as InvalidOperation { print("Invalid operation: \(error.why)") } work.op = .subtract work.num1 = 15 work.num2 = 10 print("15-10= \(try client.calculate(logid: 1, w: work))") print("Done!") thrift-0.23.0/tutorial/swift/Makefile.in0000644000175000017500000004332015170007167020426 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/swift ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ Package.swift \ swift-dep \ Sources/TutorialClient/main.swift \ Sources/TutorialRunner/main.swift \ Sources/TutorialServer/main.swift \ Sources/TutorialServer/CalculatorService.swift \ README.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/swift/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/swift/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile # # Common thrift code generation rules # 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 tutorialserver: gen_swift swift run TutorialServer tutorialclient: gen_swift swift run TutorialClient # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/swift/Makefile.am0000664000175000017500000000247415165535636020437 0ustar00buildbuild00000000000000# # 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. # # # Common thrift code generation rules # 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 tutorialserver: gen_swift swift run TutorialServer tutorialclient: gen_swift swift run TutorialClient EXTRA_DIST = \ Package.swift \ swift-dep \ Sources/TutorialClient/main.swift \ Sources/TutorialRunner/main.swift \ Sources/TutorialServer/main.swift \ Sources/TutorialServer/CalculatorService.swift \ README.md thrift-0.23.0/tutorial/tutorial.thrift0000664000175000017500000001153215165535636020327 0ustar00buildbuild00000000000000/* * 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. */ # Thrift Tutorial # Mark Slee (mcslee@facebook.com) # # This file aims to teach you how to use Thrift, in a .thrift file. Neato. The # first thing to notice is that .thrift files support standard shell comments. # This lets you make your thrift file executable and include your Thrift build # step on the top line. And you can place comments like this anywhere you like. # # Before running this file, you will need to have installed the thrift compiler # into /usr/local/bin. /** * The first thing to know about are types. The available types in Thrift are: * * bool Boolean, one byte * i8 (byte) Signed 8-bit integer * i16 Signed 16-bit integer * i32 Signed 32-bit integer * i64 Signed 64-bit integer * double 64-bit floating point value * string String * binary Blob (byte array) * map Map from one type to another * list Ordered list of one type * set Set of unique elements of one type * * Did you also notice that Thrift supports C style comments? */ // Just in case you were wondering... yes. We support simple C comments too. /** * Thrift files can reference other Thrift files to include common struct * and service definitions. These are found using the current path, or by * searching relative to any paths specified with the -I compiler flag. * * Included objects are accessed using the name of the .thrift file as a * prefix. i.e. shared.SharedObject */ include "shared.thrift" /** * Thrift files can namespace, package, or prefix their output in various * target languages. */ namespace cl tutorial namespace cpp tutorial namespace d tutorial namespace dart tutorial namespace java tutorial namespace php tutorial namespace perl tutorial namespace haxe tutorial namespace netstd tutorial /** * Thrift lets you do typedefs to get pretty names for your types. Standard * C style here. */ typedef i32 MyInteger /** * Thrift also lets you define constants for use across languages. Complex * types and structs are specified using JSON notation. */ const i32 INT32CONSTANT = 9853 const map MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} /** * You can define enums, which are just 32 bit integers. Values are optional * and start at 1 if not supplied, C style again. */ enum Operation { ADD = 1, SUBTRACT = 2, MULTIPLY = 3, DIVIDE = 4 } /** * Structs are the basic complex data structures. They are comprised of fields * which each have an integer identifier, a type, a symbolic name, and an * optional default value. * * Fields can be declared "optional", which ensures they will not be included * in the serialized output if they aren't set. Note that this requires some * manual management in some languages. */ struct Work { 1: i32 num1 = 0, 2: i32 num2, 3: Operation op, 4: optional string comment, } /** * Structs can also be exceptions, if they are nasty. */ exception InvalidOperation { 1: i32 whatOp, 2: string why } /** * Ahh, now onto the cool part, defining a service. Services just need a name * and can optionally inherit from another service using the extends keyword. */ service Calculator extends shared.SharedService { /** * A method definition looks like C code. It has a return type, arguments, * and optionally a list of exceptions that it may throw. Note that argument * lists and exception lists are specified using the exact same syntax as * field lists in struct or exception definitions. */ void ping(), i32 add(1:i32 num1, 2:i32 num2), i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), /** * This method has a oneway modifier. That means the client only makes * a request and does not listen for any response at all. Oneway methods * must be void. */ oneway void zip() } /** * That just about covers the basics. Take a look in the test/ folder for more * detailed examples. After you run this file, your generated code shows up * in folders with names gen-. The generated code isn't too scary * to look at. It even has pretty indentation. */ thrift-0.23.0/tutorial/perl/0000755000175000017500000000000015170007202016153 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/perl/PerlClient.pl0000664000175000017500000000400115165535636020573 0ustar00buildbuild00000000000000#!/usr/bin/env perl # # 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. # use strict; use warnings; use lib '../../lib/perl/lib'; use lib 'gen-perl'; use Thrift; use Thrift::BinaryProtocol; use Thrift::Socket; use Thrift::BufferedTransport; use shared::SharedService; use tutorial::Calculator; use shared::Types; use tutorial::Types; use Data::Dumper; my $socket = Thrift::Socket->new('localhost',9090); my $transport = Thrift::BufferedTransport->new($socket,1024,1024); my $protocol = Thrift::BinaryProtocol->new($transport); my $client = tutorial::CalculatorClient->new($protocol); eval{ $transport->open(); $client->ping(); print "ping()\n"; my $sum = $client->add(1,1); print "1+1=$sum\n"; my $work = tutorial::Work->new(); $work->op(tutorial::Operation::DIVIDE); $work->num1(1); $work->num2(0); eval { $client->calculate(1, $work); print "Whoa! We can divide by zero?\n"; }; if($@) { warn 'InvalidOperation: '.Dumper($@); } $work->op(tutorial::Operation::SUBTRACT); $work->num1(15); $work->num2(10); my $diff = $client->calculate(1, $work); print "15-10=$diff\n"; my $log = $client->getStruct(1); print "Log: $log->{value}\n"; $transport->close(); }; if($@){ warn(Dumper($@)); } thrift-0.23.0/tutorial/perl/Makefile.in0000644000175000017500000004311615170007167020237 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/perl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ PerlServer.pl \ PerlClient.pl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/perl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/perl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-perl/tutorial/Calculator.pm gen-perl/shared/SharedService.pm: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen perl -r $< all-local: gen-perl/tutorial/Calculator.pm tutorialserver: all ${PERL} PerlServer.pl tutorialclient: all ${PERL} PerlClient.pl clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/perl/PerlServer.pl0000664000175000017500000000553115165535636020634 0ustar00buildbuild00000000000000#!/usr/bin/env perl # # 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. # use strict; use lib '../../lib/perl/lib'; use lib 'gen-perl'; use Thrift::Socket; use Thrift::Server; use Thrift::ServerSocket; use tutorial::Calculator; package CalculatorHandler; use base qw(tutorial::CalculatorIf); sub new { my $classname = shift; my $self = {}; return bless($self,$classname); } sub ping { print "ping()\n"; } sub add { my($self, $n1, $n2) = @_; printf("add(%d,%d)\n", $n1, $n2); return $n1 + $n2; } sub calculate { my($self, $logid, $work) = @_; my $op = $work->{op}; my $num1 = $work->{num1}; my $num2 = $work->{num2}; printf("calculate(%d, %d %d %d)\n", $logid, $num1, $num2, $op); my $val; if ($op == tutorial::Operation::ADD) { $val = $num1 + $num2; } elsif ($op == tutorial::Operation::SUBTRACT) { $val = $num1 - $num2; } elsif ($op == tutorial::Operation::MULTIPLY) { $val = $num1 * $num2; } elsif ($op == tutorial::Operation::DIVIDE) { if ($num2 == 0) { my $x = tutorial::InvalidOperation->new(); $x->whatOp($op); $x->why('Cannot divide by 0'); die $x; } $val = $num1 / $num2; } else { my $x = tutorial::InvalidOperation->new(); $x->whatOp($op); $x->why('Invalid operation'); die $x; } my $log = shared::SharedStruct->new(); $log->key($logid); $log->value(int($val)); $self->{log}->{$logid} = $log; return $val; } sub getStruct { my($self, $key) = @_; printf("getStruct(%d)\n", $key); return $self->{log}->{$key}; } sub zip { my($self) = @_; print "zip()\n"; } eval { my $handler = CalculatorHandler->new(); my $processor = tutorial::CalculatorProcessor->new($handler); my $serversocket = Thrift::ServerSocket->new(9090); my $forkingserver = Thrift::ForkingServer->new($processor, $serversocket); print "Starting the server...\n"; $forkingserver->serve(); print "done.\n"; }; if ($@) { if ($@ =~ m/TException/ and exists $@->{message}) { my $message = $@->{message}; my $code = $@->{code}; my $out = $code . ':' . $message; die $out; } else { die $@; } } thrift-0.23.0/tutorial/perl/Makefile.am0000664000175000017500000000222715165535636020241 0ustar00buildbuild00000000000000# # 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. # gen-perl/tutorial/Calculator.pm gen-perl/shared/SharedService.pm: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen perl -r $< all-local: gen-perl/tutorial/Calculator.pm tutorialserver: all ${PERL} PerlServer.pl tutorialclient: all ${PERL} PerlClient.pl clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ PerlServer.pl \ PerlClient.pl thrift-0.23.0/tutorial/py.tornado/0000755000175000017500000000000015170007202017306 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/py.tornado/PythonClient.py0000775000175000017500000000560715165535636022342 0ustar00buildbuild00000000000000#!/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. # import glob import logging import sys sys.path.append('gen-py.tornado') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import Calculator from tutorial.ttypes import Operation, Work, InvalidOperation from thrift import TTornado from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from tornado import gen from tornado import ioloop @gen.coroutine def communicate(): # create client transport = TTornado.TTornadoStreamTransport('localhost', 9090) # open the transport, bail on error try: yield transport.open() print('Transport is opened') except TTransport.TTransportException as ex: logging.error(ex) raise gen.Return() pfactory = TBinaryProtocol.TBinaryProtocolFactory() client = Calculator.Client(transport, pfactory) # ping yield client.ping() print("ping()") # add sum_ = yield client.add(1, 1) print("1 + 1 = {0}".format(sum_)) # make a oneway call without a callback (schedule the write and continue # without blocking) client.zip() print("zip() without callback") # make a oneway call with a callback (we'll wait for the stream write to # complete before continuing) client.zip() print("zip() with callback") # calculate 1/0 work = Work() work.op = Operation.DIVIDE work.num1 = 1 work.num2 = 0 try: quotient = yield client.calculate(1, work) print("Whoa? You know how to divide by zero ? -> {0}".format(quotient)) except InvalidOperation as io: print("InvalidOperation: {0}".format(io)) # calculate 15-10 work.op = Operation.SUBTRACT work.num1 = 15 work.num2 = 10 diff = yield client.calculate(1, work) print("15 - 10 = {0}".format(diff)) # getStruct log = yield client.getStruct(1) print("Check log: {0}".format(log.value)) # close the transport client._transport.close() raise gen.Return() def main(): # create an ioloop, do the above, then stop ioloop.IOLoop.current().run_sync(communicate) if __name__ == "__main__": main() thrift-0.23.0/tutorial/py.tornado/PythonServer.py0000775000175000017500000000512515165535636022365 0ustar00buildbuild00000000000000#!/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. # import glob import sys sys.path.append('gen-py.tornado') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import Calculator from tutorial.ttypes import Operation, InvalidOperation from shared.ttypes import SharedStruct from thrift import TTornado from thrift.protocol import TBinaryProtocol from tornado import ioloop class CalculatorHandler(object): def __init__(self): self.log = {} def ping(self): print("ping()") def add(self, n1, n2): print("add({}, {})".format(n1, n2)) return n1 + n2 def calculate(self, logid, work): print("calculate({}, {})".format(logid, work)) if work.op == Operation.ADD: val = work.num1 + work.num2 elif work.op == Operation.SUBTRACT: val = work.num1 - work.num2 elif work.op == Operation.MULTIPLY: val = work.num1 * work.num2 elif work.op == Operation.DIVIDE: if work.num2 == 0: raise InvalidOperation(work.op, "Cannot divide by 0") val = work.num1 / work.num2 else: raise InvalidOperation(work.op, "Invalid operation") log = SharedStruct() log.key = logid log.value = '%d' % (val) self.log[logid] = log return val def getStruct(self, key): print("getStruct({})".format(key)) return self.log[key] def zip(self): print("zip()") def main(): handler = CalculatorHandler() processor = Calculator.Processor(handler) pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = TTornado.TTornadoServer(processor, pfactory) print("Starting the server...") server.bind(9090) server.start(1) ioloop.IOLoop.instance().start() print("done.") if __name__ == "__main__": main() thrift-0.23.0/tutorial/py.tornado/Makefile.in0000644000175000017500000004320415170007167021370 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/py.tornado ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ PythonServer.py \ PythonClient.py all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/py.tornado/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/py.tornado/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-py.tornado/tutorial/Calculator.py gen-py.tornado/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen py:tornado -r $< all-local: gen-py.tornado/tutorial/Calculator.py tutorialserver: all ${PYTHON} PythonServer.py tutorialclient: all ${PYTHON} PythonClient.py clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/py.tornado/Makefile.am0000664000175000017500000000227315165535636021375 0ustar00buildbuild00000000000000# # 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. # gen-py.tornado/tutorial/Calculator.py gen-py.tornado/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen py:tornado -r $< all-local: gen-py.tornado/tutorial/Calculator.py tutorialserver: all ${PYTHON} PythonServer.py tutorialclient: all ${PYTHON} PythonClient.py clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ PythonServer.py \ PythonClient.py thrift-0.23.0/tutorial/shared.thrift0000664000175000017500000000240215165535636017726 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * This Thrift file can be included by other Thrift files that want to share * these definitions. */ namespace cl shared namespace cpp shared namespace d share // "shared" would collide with the eponymous D keyword. namespace dart shared namespace java shared namespace perl shared namespace php shared namespace haxe shared namespace netstd shared struct SharedStruct { 1: i32 key 2: string value } service SharedService { SharedStruct getStruct(1: i32 key) } thrift-0.23.0/tutorial/dart/0000755000175000017500000000000015170007202016143 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/dart/client/0000755000175000017500000000000015170007202017421 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/dart/client/pubspec.yaml0000664000175000017500000000220415170007142021751 0ustar00buildbuild00000000000000# 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. name: tutorial_client version: 0.23.0 description: A Dart client implementation of the Apache Thrift tutorial author: Apache Thrift Developers homepage: http://thrift.apache.org environment: sdk: ">=2.12.0 <4.0.0" dependencies: shared: path: ../gen-dart/shared thrift: path: ../../../lib/dart tutorial: path: ../gen-dart/tutorial thrift-0.23.0/tutorial/dart/client/web/0000755000175000017500000000000015170007202020176 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/dart/client/web/index.html0000664000175000017500000000224015165535636022220 0ustar00buildbuild00000000000000 Thrift Tutorial
thrift-0.23.0/tutorial/dart/client/web/styles.css0000664000175000017500000000205615165535636022265 0ustar00buildbuild00000000000000/* * 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 url(https://fonts.googleapis.com/css?family=Roboto); html, body { width: 100%; height: 100%; margin: 0; padding: 10px; font-family: 'Roboto', sans-serif; } h3 { border-bottom: solid; border-width: thin; padding-top: 20px; } thrift-0.23.0/tutorial/dart/client/web/client.dart0000664000175000017500000002035715167543515022363 0ustar00buildbuild00000000000000/// 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 'dart:html'; import 'package:thrift/thrift.dart'; import 'package:thrift/thrift_browser.dart'; import 'package:shared/shared.dart'; import 'package:tutorial/tutorial.dart'; /// Adapted from the AS3 tutorial void main() { new CalculatorUI(querySelector('#output') as DivElement ).start(); } class CalculatorUI { final DivElement output; CalculatorUI(this.output); late TTransport _transport; late Calculator _calculatorClient; void start() { _buildInterface(); _initConnection(); } void _validate() { if (!_transport.isOpen) { window.alert("The transport is not open!"); } } void _initConnection() { _transport = new TAsyncClientSocketTransport( new TWebSocket(Uri.parse('ws://127.0.0.1:9090/ws')), new TMessageReader(new TBinaryProtocolFactory())); TProtocol protocol = new TBinaryProtocol(_transport); _transport.open(); _calculatorClient = new CalculatorClient(protocol); } void _buildInterface() { output.children.forEach((e) { e.remove(); }); _buildPingComponent(); _buildAddComponent(); _buildCalculatorComponent(); _buildGetStructComponent(); } void _buildPingComponent() { output.append(new HeadingElement.h3()..text = "Ping"); ButtonElement pingButton = new ButtonElement() ..text = "PING" ..onClick.listen(_onPingClick); output.append(pingButton); } void _onPingClick(MouseEvent e) { _validate(); _calculatorClient.ping(); } void _buildAddComponent() { output.append(new HeadingElement.h3()..text = "Add"); InputElement num1 = new InputElement() ..id = "add1" ..type = "number" ..style.fontSize = "14px" ..style.width = "50px"; output.append(num1); SpanElement op = new SpanElement() ..text = "+" ..style.fontSize = "14px" ..style.marginLeft = "10px"; output.append(op); InputElement num2 = new InputElement() ..id = "add2" ..type = "number" ..style.fontSize = "14px" ..style.width = "50px" ..style.marginLeft = "10px"; output.append(num2); ButtonElement addButton = new ButtonElement() ..text = "=" ..style.fontSize = "14px" ..style.marginLeft = "10px" ..onClick.listen(_onAddClick); output.append(addButton); SpanElement result = new SpanElement() ..id = "addResult" ..style.fontSize = "14px" ..style.marginLeft = "10px"; output.append(result); } void _onAddClick(MouseEvent e) { _validate(); InputElement num1 = querySelector("#add1") as InputElement; InputElement num2 = querySelector("#add2")as InputElement; SpanElement result = querySelector("#addResult") as SpanElement; _calculatorClient .add(int.parse(num1.value ?? "0"), int.parse(num2.value ?? "0")) .then((int n) { result.text = "$n"; }); } void _buildCalculatorComponent() { output.append(new HeadingElement.h3()..text = "Calculator"); InputElement num1 = new InputElement() ..id = "calc1" ..type = "number" ..style.fontSize = "14px" ..style.width = "50px"; output.append(num1); SelectElement op = new SelectElement() ..id = "calcOp" ..multiple = false ..selectedIndex = 0 ..style.fontSize = "16px" ..style.marginLeft = "10px" ..style.width = "50px"; OptionElement addOp = new OptionElement() ..text = "+" ..value = Operation.ADD.toString(); op.add(addOp, 0); OptionElement subtractOp = new OptionElement() ..text = "-" ..value = Operation.SUBTRACT.toString(); op.add(subtractOp, 1); OptionElement multiplyOp = new OptionElement() ..text = "*" ..value = Operation.MULTIPLY.toString(); op.add(multiplyOp, 2); OptionElement divideOp = new OptionElement() ..text = "/" ..value = Operation.DIVIDE.toString(); op.add(divideOp, 3); output.append(op); InputElement num2 = new InputElement() ..id = "calc2" ..type = "number" ..style.fontSize = "14px" ..style.width = "50px" ..style.marginLeft = "10px"; output.append(num2); ButtonElement calcButton = new ButtonElement() ..text = "=" ..style.fontSize = "14px" ..style.marginLeft = "10px" ..onClick.listen(_onCalcClick); output.append(calcButton); SpanElement result = new SpanElement() ..id = "calcResult" ..style.fontSize = "14px" ..style.marginLeft = "10px"; output.append(result); output.append(new BRElement()); output.append(new BRElement()); LabelElement logIdLabel = new LabelElement() ..text = "Log ID:" ..style.fontSize = "14px"; output.append(logIdLabel); InputElement logId = new InputElement() ..id = "logId" ..type = "number" ..value = "1" ..style.fontSize = "14px" ..style.width = "50px" ..style.marginLeft = "10px"; output.append(logId); LabelElement commentLabel = new LabelElement() ..text = "Comment:" ..style.fontSize = "14px" ..style.marginLeft = "10px"; output.append(commentLabel); InputElement comment = new InputElement() ..id = "comment" ..style.fontSize = "14px" ..style.width = "100px" ..style.marginLeft = "10px"; output.append(comment); } void _onCalcClick(MouseEvent e) { _validate(); InputElement num1 = querySelector("#calc1") as InputElement; InputElement num2 = querySelector("#calc2")as InputElement; SelectElement op = querySelector("#calcOp") as SelectElement; SpanElement result = querySelector("#calcResult") as SpanElement; InputElement logId = querySelector("#logId") as InputElement; InputElement comment = querySelector("#comment") as InputElement; int logIdValue = int.parse(logId.value ?? "0"); logId.value = (logIdValue + 1).toString(); Work work = new Work(); work.num1 = int.parse(num1.value!); work.num2 = int.parse(num2.value!); work.op = int.parse(op.options[op.selectedIndex!].value); work.comment = comment.value!; _calculatorClient.calculate(logIdValue, work).then((int n) { result.text = "$n"; }); } void _buildGetStructComponent() { output.append(new HeadingElement.h3()..text = "Get Struct"); LabelElement logIdLabel = new LabelElement() ..text = "Struct Key:" ..style.fontSize = "14px"; output.append(logIdLabel); InputElement logId = new InputElement() ..id = "structKey" ..type = "number" ..value = "1" ..style.fontSize = "14px" ..style.width = "50px" ..style.marginLeft = "10px"; output.append(logId); ButtonElement getStructButton = new ButtonElement() ..text = "GET" ..style.fontSize = "14px" ..style.marginLeft = "10px" ..onClick.listen(_onGetStructClick); output.append(getStructButton); output.append(new BRElement()); output.append(new BRElement()); TextAreaElement result = new TextAreaElement() ..id = "getStructResult" ..style.fontSize = "14px" ..style.width = "300px" ..style.height = "50px" ..style.marginLeft = "10px"; output.append(result); } void _onGetStructClick(MouseEvent e) { _validate(); InputElement structKey = querySelector("#structKey") as InputElement; TextAreaElement result = querySelector("#getStructResult") as TextAreaElement; _calculatorClient .getStruct(int.parse(structKey.value!)) .then((SharedStruct? s) { result.text = "${s?.toString()}"; }); } } thrift-0.23.0/tutorial/dart/build.sh0000664000175000017500000000262315165535636017630 0ustar00buildbuild00000000000000#!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # 'License'); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. set -e; rm -r gen-dart || true; thrift --gen dart ../shared.thrift; cd gen-dart/shared; pub get; cd ../..; thrift --gen dart ../tutorial.thrift; cd gen-dart/tutorial; pub get; cd ../..; cd client; pub get; cd ..; cd console_client; pub get; cd ..; cd server; pub get; cd ..; dartfmt -w gen-dart; echo "\nEnjoy the Dart tutorial!"; echo "\nTo run the server:"; echo "> dart server/bin/main.dart"; echo "\nTo run the client:"; echo "# Serve the app from the client directory and view in a browser"; echo "> cd client;"; echo "> pub serve;"; echo "\nTo run the console client:"; echo "> dart console_client/bin/main.dart"; echo ""; thrift-0.23.0/tutorial/dart/server/0000755000175000017500000000000015170007202017451 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/dart/server/bin/0000755000175000017500000000000015170007202020221 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/dart/server/bin/main.dart0000664000175000017500000001041015167543515022041 0ustar00buildbuild00000000000000/// 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 'dart:async'; import 'dart:io'; import 'package:args/args.dart'; import 'package:logging/logging.dart'; import 'package:thrift/thrift.dart'; import 'package:thrift/thrift_console.dart'; import 'package:tutorial/tutorial.dart'; import 'package:shared/shared.dart'; late TProtocol _protocol; late TProcessor _processor; late WebSocket _webSocket; main(List args) { Logger.root.level = Level.ALL; Logger.root.onRecord.listen((LogRecord rec) { print('${rec.level.name}: ${rec.time}: ${rec.message}'); }); var parser = new ArgParser(); parser.addOption('port', defaultsTo: '9090', help: 'The port to listen on'); parser.addOption('type', defaultsTo: 'tcp', allowed: ['ws', 'tcp'], help: 'The type of socket', allowedHelp: {'ws': 'WebSocket', 'tcp': 'TCP Socket'}); ArgResults? results; try { results = parser.parse(args); } catch (e) { results = null; } if (results == null) { print(parser.usage); exit(0); } int port = int.parse(results['port']); String socketType = results['type']; if (socketType == 'tcp') { _runTcpServer(port); } else if (socketType == 'ws') { _runWebSocketServer(port); } } Future _runWebSocketServer(int port) async { var httpServer = await HttpServer.bind('127.0.0.1', port); print('listening for WebSocket connections on $port'); httpServer.listen((HttpRequest request) async { if (request.uri.path == '/ws') { _webSocket = await WebSocketTransformer.upgrade(request); await _initProcessor(new TWebSocket(_webSocket)); } else { print('Invalid path: ${request.uri.path}'); } }); } Future _runTcpServer(int port) async { var serverSocket = await ServerSocket.bind('127.0.0.1', port); print('listening for TCP connections on $port'); Socket socket = await serverSocket.first; await _initProcessor(new TTcpSocket(socket)); } Future _initProcessor(TSocket socket) async { TServerSocketTransport transport = new TServerSocketTransport(socket); transport.onIncomingMessage.listen(_processMessage); _processor = new CalculatorProcessor(new CalculatorServer()); _protocol = new TBinaryProtocol(transport); await _protocol.transport.open(); print('connected'); } Future _processMessage(_) async { _processor.process(_protocol, _protocol); } class CalculatorServer implements Calculator { final Map _log = {}; Future ping() async { print('ping()'); } Future add(int num1, int num2) async { print('add($num1, $num2)'); return num1 + num2; } Future calculate(int logid, Work? work) async { print('calulate($logid, ${work.toString()})'); late int val; switch (work!.op) { case Operation.ADD: val = work.num1 + work.num2; break; case Operation.SUBTRACT: val = work.num1 - work.num2; break; case Operation.MULTIPLY: val = work.num1 * work.num2; break; case Operation.DIVIDE: if (work.num2 == 0) { var x = new InvalidOperation(); x.whatOp = work.op; x.why = 'Cannot divide by 0'; throw x; } val = (work.num1 / work.num2).floor(); break; } var log = new SharedStruct(); log.key = logid; log.value = '$val "${work.comment}"'; this._log[logid] = log; return val; } Future zip() async { print('zip()'); } Future getStruct(int key) async { print('getStruct($key)'); return _log[key]; } } thrift-0.23.0/tutorial/dart/server/pubspec.yaml0000664000175000017500000000221615170007142022004 0ustar00buildbuild00000000000000# 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. name: tutorial_server version: 0.23.0 description: A Dart server to support the Apache Thrift tutorial author: Apache Thrift Developers homepage: http://thrift.apache.org environment: sdk: ">=2.12.0 <4.0.0" dependencies: args: "^2.4.2" shared: path: ../gen-dart/shared thrift: path: ../../../lib/dart tutorial: path: ../gen-dart/tutorial thrift-0.23.0/tutorial/dart/console_client/0000755000175000017500000000000015170007202021143 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/dart/console_client/bin/0000755000175000017500000000000015170007202021713 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/dart/console_client/bin/main.dart0000664000175000017500000000743115167543515023544 0ustar00buildbuild00000000000000/// 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 'dart:async'; import 'dart:io'; import 'package:args/args.dart'; import 'package:logging/logging.dart'; import 'package:thrift/thrift.dart'; import 'package:thrift/thrift_console.dart'; import 'package:tutorial/tutorial.dart'; late TTransport _transport; late Calculator _calculator; int logid = 0; const Map operationLookup = const { '+': Operation.ADD, '-': Operation.SUBTRACT, '*': Operation.MULTIPLY, '/': Operation.DIVIDE }; main(List args) { Logger.root.level = Level.ALL; Logger.root.onRecord.listen((LogRecord rec) { print('${rec.level.name}: ${rec.time}: ${rec.message}'); }); var parser = new ArgParser(); parser.addOption('port', defaultsTo: '9090', help: 'The port to connect to'); ArgResults? results; try { results = parser.parse(args); } catch (e) { results = null; } if (results == null) { print(parser.usage); exit(0); } int port = int.parse(results['port']); _initConnection(port).then((_) => _run()); } Future _initConnection(int port) async { var socket = await Socket.connect('127.0.0.1', port); _transport = new TAsyncClientSocketTransport( new TTcpSocket(socket), new TMessageReader(new TBinaryProtocolFactory())); TProtocol protocol = new TBinaryProtocol(_transport); await _transport.open(); _calculator = new CalculatorClient(protocol); } Future _run() async { _help(); while (true) { stdout.write("> "); var input = stdin.readLineSync(); var parts = input?.split(' '); var command = parts?[0]; var args = parts!.length > 1 ? parts.sublist(1) : []; switch (command) { case 'ping': await _ping(); break; case 'add': await _add(int.parse(args[0]), int.parse(args[1])); break; case 'calc': int? op = operationLookup[args[1]]; if (!Operation.VALID_VALUES.contains(op)) { stdout.writeln('Unknown operator ${args[1]}'); break; } var work = new Work() ..num1 = int.parse(args[0]) ..op = op! ..num2 = int.parse(args[2]) ..comment = args.length > 3 ? args[3] : ''; await _calc(work); break; case 'struct': await _struct(int.parse(args[0])); break; case 'help': default: _help(); break; } } } void _help() { stdout.writeln('Commands:'); stdout.writeln(' help'); stdout.writeln(' ping'); stdout.writeln(' add x y'); stdout.writeln(' calc x op y [comment]'); stdout.writeln(' struct id'); stdout.writeln(''); } Future _ping() async { await _calculator.ping(); stdout.writeln('ping succeeded'); } Future _add(int x, int y) async { int result = await _calculator.add(x, y); stdout.writeln('= $result'); } Future _calc(Work work) async { int result = await _calculator.calculate(logid++, work); stdout.writeln('= $result'); } Future _struct(int key) async { var struct = await _calculator.getStruct(key); stdout.writeln(struct.toString()); } thrift-0.23.0/tutorial/dart/console_client/pubspec.yaml0000664000175000017500000000227715170007142023505 0ustar00buildbuild00000000000000# 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. name: tutorial_console_client version: 0.23.0 description: > A Dart console client to implementation of the Apache Thrift tutorial author: Apache Thrift Developers homepage: http://thrift.apache.org environment: sdk: ">=2.12.0 <4.0.0" dependencies: args: ^2.4.2 collection: ^1.1.0 shared: path: ../gen-dart/shared thrift: path: ../../../lib/dart tutorial: path: ../gen-dart/tutorial thrift-0.23.0/tutorial/dart/Makefile.in0000644000175000017500000004646415170007167020240 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/dart ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ # Use 'dart pub' if 'pub' command is not available DARTPUB = dart pub DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ BUILT_SOURCES = gen-dart/tutorial/lib/tutorial.dart gen-dart/shared/lib/shared.dart EXTRA_DIST = \ client/web/client.dart \ client/web/index.html \ client/web/styles.css \ client/pubspec.yaml \ console_client/bin/main.dart \ console_client/pubspec.yaml \ server/bin/main.dart \ server/pubspec.yaml \ build.sh all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/dart/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/dart/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile all-local installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: all check install install-am install-exec install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am dist-hook \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-dart/tutorial/lib/tutorial.dart gen-dart/shared/lib/shared.dart: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen dart -r $< all-local: gen-dart/tutorial/lib/tutorial.dart pub-get clean-local: $(RM) -r gen-*/ find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type d -name "packages" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type f -name "pubspec.lock" | xargs $(RM) dist-hook: $(RM) -r $(distdir)/gen-*/ find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r find $(distdir) -type d -name "packages" | xargs $(RM) -r find $(distdir) -type f -name ".packages" | xargs $(RM) find $(distdir) -type f -name "pubspec.lock" | xargs $(RM) pub-get: pub-get-gen pub-get-client pub-get-console-client pub-get-server pub-get-gen: pub-get-tutorial pub-get-shared pub-get-tutorial: gen-dart/tutorial/lib/tutorial.dart cd gen-dart/tutorial; ${DARTPUB} get pub-get-shared: gen-dart/shared/lib/shared.dart cd gen-dart/shared; ${DARTPUB} get pub-get-client: cd client; ${DARTPUB} get pub-get-console-client: cd console_client; ${DARTPUB} get pub-get-server: cd server; ${DARTPUB} get tutorialserver: pub-get-gen pub-get-server ${DART} server/bin/main.dart tutorialclient: pub-get-gen pub-get-client cd client; ${DARTPUB} serve tutorialconsoleclient: pub-get-console-client ${DART} console_client/bin/main.dart distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/dart/Makefile.am0000664000175000017500000000505315167543515020226 0ustar00buildbuild00000000000000# # 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. # BUILT_SOURCES = gen-dart/tutorial/lib/tutorial.dart gen-dart/shared/lib/shared.dart # Use 'dart pub' if 'pub' command is not available DARTPUB = dart pub gen-dart/tutorial/lib/tutorial.dart gen-dart/shared/lib/shared.dart: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen dart -r $< all-local: gen-dart/tutorial/lib/tutorial.dart pub-get clean-local: $(RM) -r gen-*/ find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type d -name "packages" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type f -name "pubspec.lock" | xargs $(RM) dist-hook: $(RM) -r $(distdir)/gen-*/ find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r find $(distdir) -type d -name "packages" | xargs $(RM) -r find $(distdir) -type f -name ".packages" | xargs $(RM) find $(distdir) -type f -name "pubspec.lock" | xargs $(RM) pub-get: pub-get-gen pub-get-client pub-get-console-client pub-get-server pub-get-gen: pub-get-tutorial pub-get-shared pub-get-tutorial: gen-dart/tutorial/lib/tutorial.dart cd gen-dart/tutorial; ${DARTPUB} get pub-get-shared: gen-dart/shared/lib/shared.dart cd gen-dart/shared; ${DARTPUB} get pub-get-client: cd client; ${DARTPUB} get pub-get-console-client: cd console_client; ${DARTPUB} get pub-get-server: cd server; ${DARTPUB} get tutorialserver: pub-get-gen pub-get-server ${DART} server/bin/main.dart tutorialclient: pub-get-gen pub-get-client cd client; ${DARTPUB} serve 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 \ client/web/styles.css \ client/pubspec.yaml \ console_client/bin/main.dart \ console_client/pubspec.yaml \ server/bin/main.dart \ server/pubspec.yaml \ build.sh thrift-0.23.0/tutorial/ocaml/0000775000175000017500000000000015170007142016311 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/ocaml/CalcClient.ml0000775000175000017500000000447415165535636020702 0ustar00buildbuild00000000000000(* 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. *) open Arg open Thrift open Tutorial_types open Shared_types exception Die;; let sod = function Some v -> v | None -> raise Die;; type connection = { trans : Transport.t ; proto : Thrift.Protocol.t; calc : Calculator.client ; } let connect ~host port = let tx = new TSocket.t host port in let proto = new TBinaryProtocol.t tx in let calc = new Calculator.client proto proto in tx#opn; { trans = tx ; proto = proto; calc = calc } ;; let doclient () = let cli = connect ~host:"127.0.0.1" 9090 in try cli.calc#ping ; Printf.printf "ping()\n" ; flush stdout ; (let sum = cli.calc#add (Int32.of_int 1) (Int32.of_int 1) in Printf.printf "1+1=%ld\n" sum ; flush stdout) ; (let w = new work in w#set_op Operation.DIVIDE ; w#set_num1 (Int32.of_int 1) ; w#set_num2 (Int32.of_int 0) ; try let quotient = cli.calc#calculate (Int32.of_int 1) w in Printf.printf "Whoa? We can divide by zero!\n" ; flush stdout with InvalidOperation io -> Printf.printf "InvalidOperation: %s\n" io#grab_why ; flush stdout) ; (let w = new work in w#set_op Operation.SUBTRACT ; w#set_num1 (Int32.of_int 15) ; w#set_num2 (Int32.of_int 10) ; let diff = cli.calc#calculate (Int32.of_int 1) w in Printf.printf "15-10=%ld\n" diff ; flush stdout) ; (let ss = cli.calc#getStruct (Int32.of_int 1) in Printf.printf "Check log: %s\n" ss#grab_value ; flush stdout) ; cli.trans#close with Transport.E (_,what) -> Printf.printf "ERROR: %s\n" what ; flush stdout ;; doclient();; thrift-0.23.0/tutorial/ocaml/_oasis0000664000175000017500000000143415170007142017513 0ustar00buildbuild00000000000000Name: tutorial Version: 0.23.0 OASISFormat: 0.3 Synopsis: OCaml Tutorial example Authors: Apache Thrift Developers License: Apache-2.0 Homepage: http://thrift.apache.org BuildTools: ocamlbuild Plugins: META (0.3), DevFiles (0.3) Library tutorial_thrift Path: gen-ocaml FindlibName: tutorial_thrift buildTools: ocamlbuild BuildDepends: threads,thrift Modules: Calculator,Shared_consts,Tutorial_consts,SharedService,Shared_types,Tutorial_types XMETARequires: threads Executable CalcClient Path: . MainIs: CalcClient.ml Build$: true CompiledObject: best BuildDepends: thrift, tutorial_thrift, threads Executable CalcServer Path: . MainIs: CalcServer.ml Build$: true CompiledObject: best BuildDepends: thrift, tutorial_thrift, threads thrift-0.23.0/tutorial/ocaml/CalcServer.ml0000775000175000017500000000473515165535636020732 0ustar00buildbuild00000000000000(* 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. *) open Arg open Thrift open Tutorial_types open Shared_types exception Die;; let sod = function Some v -> v | None -> raise Die;; class calc_handler = object (self) inherit Calculator.iface val log = Hashtbl.create 23 method ping = Printf.printf "ping()\n" ; flush stdout method add a b = Printf.printf"add(%ld,%ld)\n" (sod a) (sod b); flush stdout ; Int32.add (sod a) (sod b) method calculate logid w = let w = sod w in Printf.printf "calculate(%ld,{%ld,%ld,%ld})\n" (sod logid) (Operation.to_i w#grab_op) w#grab_num1 w#grab_num2; flush stdout ; let rv = match w#grab_op with Operation.ADD -> Int32.add w#grab_num1 w#grab_num2 | Operation.SUBTRACT -> Int32.sub w#grab_num1 w#grab_num2 | Operation.MULTIPLY -> Int32.mul w#grab_num1 w#grab_num2 | Operation.DIVIDE -> if w#grab_num2 = Int32.zero then let io = new invalidOperation in io#set_whatOp (Operation.to_i w#grab_op) ; io#set_why "Cannot divide by 0" ; raise (InvalidOperation io) else Int32.div w#grab_num1 w#grab_num2 in let ss = new sharedStruct in ss#set_key (sod logid) ; let buffer = Int32.to_string rv in ss#set_value buffer ; Hashtbl.add log (sod logid) ss ; rv method zip = Printf.printf "zip()\n"; flush stdout method getStruct logid = Printf.printf "getStruct(%ld)\n" (sod logid) ; flush stdout ; Hashtbl.find log (sod logid) end let doserver () = let h = new calc_handler in let proc = new Calculator.processor h in let port = 9090 in let pf = new TBinaryProtocol.factory in let server = new TThreadedServer.t proc (new TServerSocket.t port) (new Transport.factory) pf pf in server#serve ;; doserver();; thrift-0.23.0/tutorial/ocaml/README.md0000664000175000017500000000111015165535636017603 0ustar00buildbuild00000000000000 This is the ocaml tutorial example. It assumes that you've already built and installed the thrift ocaml runtime libraries in lib/ocaml. To compile this, you will need to generate the Thrift sources for ocaml in this directory (due to limitations in the OASIS build-tool): % thrift -r --gen ocaml ../tutorial.thrift % oasis setup % make This will produce two executables Calc{Server,Client}. where is one of "byte" or "native", depending on your ocaml installation. Just run the server in the background, then the client (as you would do for the C++ example). thrift-0.23.0/tutorial/py.twisted/0000755000175000017500000000000015170007202017323 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/py.twisted/PythonClient.py0000775000175000017500000000442715165535636022356 0ustar00buildbuild00000000000000#!/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. # import glob import sys sys.path.append('gen-py.twisted') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import Calculator from tutorial.ttypes import InvalidOperation, Operation, Work from twisted.internet.defer import inlineCallbacks from twisted.internet import reactor from twisted.internet.protocol import ClientCreator from thrift.transport import TTwisted from thrift.protocol import TBinaryProtocol @inlineCallbacks def main(client): yield client.ping() print('ping()') sum = yield client.add(1, 1) print(('1+1=%d' % (sum))) work = Work() work.op = Operation.DIVIDE work.num1 = 1 work.num2 = 0 try: quotient = yield client.calculate(1, work) print('Whoa? You know how to divide by zero?') print('FYI the answer is %d' % quotient) except InvalidOperation as e: print(('InvalidOperation: %r' % e)) work.op = Operation.SUBTRACT work.num1 = 15 work.num2 = 10 diff = yield client.calculate(1, work) print(('15-10=%d' % (diff))) log = yield client.getStruct(1) print(('Check log: %s' % (log.value))) reactor.stop() if __name__ == '__main__': d = ClientCreator(reactor, TTwisted.ThriftClientProtocol, Calculator.Client, TBinaryProtocol.TBinaryProtocolFactory(), ).connectTCP("127.0.0.1", 9090) d.addCallback(lambda conn: conn.client) d.addCallback(main) reactor.run() thrift-0.23.0/tutorial/py.twisted/PythonServer.py0000775000175000017500000000513415165535636022402 0ustar00buildbuild00000000000000#!/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. # import glob import sys sys.path.append('gen-py.twisted') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import Calculator from tutorial.ttypes import InvalidOperation, Operation from shared.ttypes import SharedStruct from zope.interface import implements from twisted.internet import reactor from thrift.transport import TTwisted from thrift.protocol import TBinaryProtocol class CalculatorHandler: implements(Calculator.Iface) def __init__(self): self.log = {} def ping(self): print('ping()') def add(self, n1, n2): print('add(%d,%d)' % (n1, n2)) return n1 + n2 def calculate(self, logid, work): print('calculate(%d, %r)' % (logid, work)) if work.op == Operation.ADD: val = work.num1 + work.num2 elif work.op == Operation.SUBTRACT: val = work.num1 - work.num2 elif work.op == Operation.MULTIPLY: val = work.num1 * work.num2 elif work.op == Operation.DIVIDE: if work.num2 == 0: raise InvalidOperation(work.op, 'Cannot divide by 0') val = work.num1 / work.num2 else: raise InvalidOperation(work.op, 'Invalid operation') log = SharedStruct() log.key = logid log.value = '%d' % (val) self.log[logid] = log return val def getStruct(self, key): print('getStruct(%d)' % (key)) return self.log[key] def zip(self): print('zip()') if __name__ == '__main__': handler = CalculatorHandler() processor = Calculator.Processor(handler) pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = reactor.listenTCP( 9090, TTwisted.ThriftServerFactory(processor, pfactory), interface="127.0.0.1") reactor.run() thrift-0.23.0/tutorial/py.twisted/PythonServer.tac0000775000175000017500000000324215165535636022517 0ustar00buildbuild00000000000000#!/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 twisted.application import internet, service from thrift.transport import TTwisted import glob import sys sys.path.append('gen-py.twisted') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import Calculator from PythonServer import CalculatorHandler from thrift.protocol import TBinaryProtocol def make_application(): application = service.Application('CalcServer') handler = CalculatorHandler() processor = Calculator.Processor(handler) serverFactory = TTwisted.ThriftServerFactory( processor, TBinaryProtocol.TBinaryProtocolFactory()) calcService = internet.TCPServer(9090, serverFactory) multiService = service.MultiService() calcService.setServiceParent(multiService) multiService.setServiceParent(application) return application if __name__ == '__main__': application = make_application() thrift-0.23.0/tutorial/py.twisted/Makefile.in0000644000175000017500000004320015170007167021401 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/py.twisted ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ PythonClient.py \ PythonServer.py \ PythonServer.tac all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/py.twisted/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/py.twisted/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-py/tutorial/Calculator.py gen-py/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen py:twisted -r $< all-local: gen-py/tutorial/Calculator.py tutorialserver: all ${PYTHON} PythonServer.py tutorialclient: all ${PYTHON} PythonClient.py clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/py.twisted/Makefile.am0000664000175000017500000000226715165535636021415 0ustar00buildbuild00000000000000# # 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. # gen-py/tutorial/Calculator.py gen-py/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen py:twisted -r $< all-local: gen-py/tutorial/Calculator.py tutorialserver: all ${PYTHON} PythonServer.py tutorialclient: all ${PYTHON} PythonClient.py clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ PythonClient.py \ PythonServer.py \ PythonServer.tac thrift-0.23.0/tutorial/cl/0000755000175000017500000000000015170007202015607 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/cl/tutorial-implementation.lisp0000664000175000017500000000325015165535636023415 0ustar00buildbuild00000000000000(in-package #:tutorial-implementation) ;;;; 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. (defun tutorial.calculator-implementation:ping () (format t "ping()~%")) (defun tutorial.calculator-implementation:add (num1 num2) (format t "add(~a, ~a)~%" num1 num2) (+ num1 num2)) (defun tutorial.calculator-implementation:calculate (logid work) (format t "calculate(~a, ~a)~%" logid work) (handler-case (let* ((num1 (tutorial:work-num1 work)) (num2 (tutorial:work-num2 work)) (op (tutorial:work-op work)) (result (cond ((= op tutorial:operation.add) (+ num1 num2)) ((= op tutorial:operation.subtract) (- num1 num2)) ((= op tutorial:operation.multiply) (* num1 num2)) ((= op tutorial:operation.divide) (/ num1 num2))))) (shared-implementation::add-log logid result) result) (division-by-zero () (error 'tutorial:invalidoperation :why "Division by zero." :what-op (tutorial:work-op work))))) (defun tutorial.calculator-implementation:zip () (format t "zip()~%")) thrift-0.23.0/tutorial/cl/make-tutorial-client.lisp0000664000175000017500000000534615165535636022571 0ustar00buildbuild00000000000000(in-package #:cl-user) ;;;; 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. (require "asdf") (load (merge-pathnames "load-locally.lisp" *load-truename*)) (require "sb-grovel") ;; necessary for :net.didierverna.clon.termio (asdf:load-asd (first (directory (merge-pathnames "../../lib/cl/externals/software/clon-*/termio/net.didierverna.clon.termio.asd" *load-truename*)))) (asdf:load-system :net.didierverna.clon) (asdf:load-asd (merge-pathnames "gen-cl/shared/thrift-gen-shared.asd" *load-truename*)) (asdf:load-asd (merge-pathnames "gen-cl/tutorial/thrift-gen-tutorial.asd" *load-truename*)) (asdf:load-asd (merge-pathnames "thrift-tutorial.asd" *load-truename*)) (asdf:load-system :thrift-tutorial) (net.didierverna.clon:nickname-package) (defun main () "Entry point for the binary." (thrift:with-client (prot #u"thrift://127.0.0.1:9090") (tutorial.calculator:ping prot) (format t "ping()~%") (format t "1 + 1 = ~a~%" (tutorial.calculator:add prot 1 1)) (let ((work-instance (tutorial:make-work :num1 5 :num2 0 :op tutorial:operation.divide :comment "Booya!"))) (handler-case (format t "5 / 0 = ~a - Oh, really? An exception should have been thrown here.~%" (tutorial.calculator:calculate prot 1 work-instance)) (tutorial:invalidoperation (e) (format t "---~%(Expected) Invalid Operation caught: ~%~a~%---~%" e)))) (let ((work-instance (tutorial:make-work :num1 15 :num2 10 :op tutorial:operation.subtract :comment "Playing nice this time."))) (handler-case (format t "15 - 10 = ~a~%" (tutorial.calculator:calculate prot 1 work-instance)) (tutorial:invalidoperation (e) (format t "---~%(Unexpected) Invalid Operation caught: ~%~a~%---~%" e)))) (format t "Check log: ~a~%" (shared.shared-service:get-struct prot 1)))) (clon:dump "TutorialClient" main) thrift-0.23.0/tutorial/cl/thrift-tutorial.asd0000664000175000017500000000137015165535636021471 0ustar00buildbuild00000000000000;;;; 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. (asdf:defsystem #:thrift-tutorial :depends-on (#:thrift-gen-tutorial) :serial t :components ((:file "shared-implementation") (:file "tutorial-implementation"))) thrift-0.23.0/tutorial/cl/shared-implementation.lisp0000664000175000017500000000171215165535636023021 0ustar00buildbuild00000000000000(in-package #:shared-implementation) ;;;; 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. (defvar *structs* (make-hash-table)) (defun shared.shared-service-implementation:get-struct (key) (format t "getStruct(~a)~%" key) (gethash key *structs*)) (defun add-log (key value) (setf (gethash key *structs*) (make-instance 'shared:sharedstruct :key key :value (write-to-string value)))) thrift-0.23.0/tutorial/cl/make-tutorial-server.lisp0000664000175000017500000000267315165535636022621 0ustar00buildbuild00000000000000(in-package #:cl-user) ;;;; 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. (require "asdf") (load (merge-pathnames "load-locally.lisp" *load-truename*)) (require "sb-grovel") ;; necessary for :net.didierverna.clon.termio (asdf:load-asd (first (directory (merge-pathnames "../../lib/cl/externals/software/clon-*/termio/net.didierverna.clon.termio.asd" *load-truename*)))) (asdf:load-system :net.didierverna.clon) (asdf:load-asd (merge-pathnames "gen-cl/shared/thrift-gen-shared.asd" *load-truename*)) (asdf:load-asd (merge-pathnames "gen-cl/tutorial/thrift-gen-tutorial.asd" *load-truename*)) (asdf:load-asd (merge-pathnames "thrift-tutorial.asd" *load-truename*)) (asdf:load-system :thrift-tutorial) (net.didierverna.clon:nickname-package) (defun main () "Entry point for the binary." (thrift:serve #u"thrift://127.0.0.1:9090" tutorial:calculator)) (clon:dump "TutorialServer" main) thrift-0.23.0/tutorial/cl/Makefile.in0000644000175000017500000004503215170007167017672 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/cl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ALL_FILE_PREREQS = \ load-locally.lisp \ make-tutorial-server.lisp \ make-tutorial-client.lisp \ shared-implementation.lisp \ thrift-tutorial.asd \ tutorial-implementation.lisp EXTRA_DIST = \ tutorial-implementation.lisp \ shared-implementation.lisp \ thrift-tutorial.asd \ make-tutorial-server.lisp \ make-tutorial-client.lisp \ load-locally.lisp all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/cl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/cl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile setup-local-lisp-env: ../../lib/cl/ensure-externals.sh bash ../../lib/cl/ensure-externals.sh gen-cl: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen cl -r $< # NOTE: the server and client cannot be built in parallel # because on loading the make-tutorial-* scripts SBCL will # attempt to compile their dependencies. Unfortunately, # because their dependencies are shared, parallel jobs can # end up overwriting or corrupting the compiled files all-local: gen-cl setup-local-lisp-env $(ALL_FILE_PREREQS) $(SBCL) --script make-tutorial-server.lisp $(SBCL) --script make-tutorial-client.lisp tutorialserver: all ./TutorialServer tutorialclient: all ./TutorialClient clean-local: -$(RM) -r gen-* -$(RM) -r externals -$(RM) -r quicklisp -$(RM) -r lib -$(RM) quicklisp.lisp -$(RM) backport-update.zip -$(RM) shared-implementation.fasl -$(RM) tutorial-implementation.fasl -$(RM) TutorialServer -$(RM) TutorialClient distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/cl/Makefile.am0000775000175000017500000000415115165535636017676 0ustar00buildbuild00000000000000# # 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. setup-local-lisp-env: ../../lib/cl/ensure-externals.sh bash ../../lib/cl/ensure-externals.sh gen-cl: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen cl -r $< ALL_FILE_PREREQS = \ load-locally.lisp \ make-tutorial-server.lisp \ make-tutorial-client.lisp \ shared-implementation.lisp \ thrift-tutorial.asd \ tutorial-implementation.lisp # NOTE: the server and client cannot be built in parallel # because on loading the make-tutorial-* scripts SBCL will # attempt to compile their dependencies. Unfortunately, # because their dependencies are shared, parallel jobs can # end up overwriting or corrupting the compiled files all-local: gen-cl setup-local-lisp-env $(ALL_FILE_PREREQS) $(SBCL) --script make-tutorial-server.lisp $(SBCL) --script make-tutorial-client.lisp tutorialserver: all ./TutorialServer tutorialclient: all ./TutorialClient clean-local: -$(RM) -r gen-* -$(RM) -r externals -$(RM) -r quicklisp -$(RM) -r lib -$(RM) quicklisp.lisp -$(RM) backport-update.zip -$(RM) shared-implementation.fasl -$(RM) tutorial-implementation.fasl -$(RM) TutorialServer -$(RM) TutorialClient distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ tutorial-implementation.lisp \ shared-implementation.lisp \ thrift-tutorial.asd \ make-tutorial-server.lisp \ make-tutorial-client.lisp \ load-locally.lisp thrift-0.23.0/tutorial/cl/load-locally.lisp0000664000175000017500000000166015165535636021106 0ustar00buildbuild00000000000000(in-package #:cl-user) ;;;; 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. ;;;; Just a script for loading the library itself, using bundled dependencies. ;;;; This is an identical copy of the file in lib/cl. (require "asdf") (load (merge-pathnames "externals/bundle.lisp" *load-truename*)) (asdf:load-asd (merge-pathnames "lib/de.setf.thrift-backport-update/thrift.asd" *load-truename*)) (asdf:load-system :thrift) thrift-0.23.0/tutorial/c_glib/0000755000175000017500000000000015170007202016430 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/c_glib/c_glib_client.c0000664000175000017500000001345515165535636021410 0ustar00buildbuild00000000000000/* * 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 #include "gen-c_glib/calculator.h" int main (void) { ThriftSocket *socket; ThriftTransport *transport; ThriftProtocol *protocol; CalculatorIf *client; GError *error = NULL; InvalidOperation *invalid_operation = NULL; Work *work; gint32 sum; gint32 diff; int exit_status = 0; #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif socket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", 9090, NULL); transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", socket, NULL); protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL); thrift_transport_open (transport, &error); /* In the C (GLib) implementation of Thrift, service methods on the server are accessed via a generated client class that implements the service interface. In this tutorial, we access a Calculator service through an instance of CalculatorClient, which implements CalculatorIf. */ client = g_object_new (TYPE_CALCULATOR_CLIENT, "input_protocol", protocol, "output_protocol", protocol, NULL); /* Each of the client methods requires at least two parameters: A pointer to the client-interface implementation (the client object), and a handle to a GError structure to receive information about any error that occurs. On success, client methods return TRUE. A return value of FALSE indicates an error occurred and the error parameter has been set. */ if (!error && calculator_if_ping (client, &error)) { puts ("ping()"); } /* Service methods that return a value do so by passing the result back via an output parameter (here, "sum"). */ if (!error && calculator_if_add (client, &sum, 1, 1, &error)) { printf ("1+1=%d\n", sum); } /* Thrift structs are implemented as GObjects, with each of the struct's members exposed as an object property. */ work = g_object_new (TYPE_WORK, NULL); if (!error) { g_object_set (work, "num1", 1, "num2", 0, "op", OPERATION_DIVIDE, NULL); /* Exceptions are passed back from service methods in a manner similar to return values. */ if (calculator_if_calculate (client, NULL, 1, work, &invalid_operation, &error)) { puts ("Whoa? We can divide by zero!"); } else { if (invalid_operation) { gchar *why; /* Like structs, exceptions are implemented as objects with properties. */ g_object_get (invalid_operation, "why", &why, NULL); printf ("InvalidOperation: %s\n", why); if (why != NULL) g_free (why); g_object_unref (invalid_operation); invalid_operation = NULL; } g_clear_error (&error); } } if (!error) { /* Struct objects can be reused across method invocations. */ g_object_set (work, "num1", 15, "num2", 10, "op", OPERATION_SUBTRACT, NULL); if (calculator_if_calculate (client, &diff, 1, work, &invalid_operation, &error)) { printf ("15-10=%d\n", diff); } } g_object_unref (work); if (!error) { SharedStruct *shared_struct; gchar *value; shared_struct = g_object_new (TYPE_SHARED_STRUCT, NULL); /* As defined in the Thrift file, the Calculator service extends the SharedService service. Correspondingly, in the generated code CalculatorIf inherits from SharedServiceIf, and the parent service's methods are accessible through a simple cast. */ if (shared_service_client_get_struct (SHARED_SERVICE_IF (client), &shared_struct, 1, &error)) { g_object_get (shared_struct, "value", &value, NULL); printf ("Check log: %s\n", value); g_free (value); } g_object_unref (shared_struct); } if (error) { printf ("ERROR: %s\n", error->message); g_clear_error (&error); exit_status = 1; } thrift_transport_close (transport, NULL); g_object_unref (client); g_object_unref (protocol); g_object_unref (transport); g_object_unref (socket); return exit_status; } thrift-0.23.0/tutorial/c_glib/c_glib_server.c0000664000175000017500000004443415165535636021441 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include #include "gen-c_glib/calculator.h" G_BEGIN_DECLS /* In the C (GLib) implementation of Thrift, the actual work done by a server---that is, the code that runs when a client invokes a service method---is defined in a separate "handler" class that implements the service interface. Here we define the TutorialCalculatorHandler class, which implements the CalculatorIf interface and provides the behavior expected by tutorial clients. (Typically this code would be placed in its own module but for clarity this tutorial is presented entirely in a single file.) For each service the Thrift compiler generates an abstract base class from which handler implementations should inherit. In our case TutorialCalculatorHandler inherits from CalculatorHandler, defined in gen-c_glib/calculator.h. If you're new to GObject, try not to be intimidated by the quantity of code here---much of it is boilerplate and can mostly be copied-and-pasted from existing work. For more information refer to the GObject Reference Manual, available online at https://developer.gnome.org/gobject/. */ #define TYPE_TUTORIAL_CALCULATOR_HANDLER \ (tutorial_calculator_handler_get_type ()) #define TUTORIAL_CALCULATOR_HANDLER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ TYPE_TUTORIAL_CALCULATOR_HANDLER, \ TutorialCalculatorHandler)) #define TUTORIAL_CALCULATOR_HANDLER_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), \ TYPE_TUTORIAL_CALCULATOR_HANDLER, \ TutorialCalculatorHandlerClass)) #define IS_TUTORIAL_CALCULATOR_HANDLER(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ TYPE_TUTORIAL_CALCULATOR_HANDLER)) #define IS_TUTORIAL_CALCULATOR_HANDLER_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), \ TYPE_TUTORIAL_CALCULATOR_HANDLER)) #define TUTORIAL_CALCULATOR_HANDLER_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ TYPE_TUTORIAL_CALCULATOR_HANDLER, \ TutorialCalculatorHandlerClass)) struct _TutorialCalculatorHandler { CalculatorHandler parent_instance; /* private */ GHashTable *log; }; typedef struct _TutorialCalculatorHandler TutorialCalculatorHandler; struct _TutorialCalculatorHandlerClass { CalculatorHandlerClass parent_class; }; typedef struct _TutorialCalculatorHandlerClass TutorialCalculatorHandlerClass; GType tutorial_calculator_handler_get_type (void); G_END_DECLS /* ---------------------------------------------------------------- */ /* The implementation of TutorialCalculatorHandler follows. */ G_DEFINE_TYPE (TutorialCalculatorHandler, tutorial_calculator_handler, TYPE_CALCULATOR_HANDLER) /* Each of a handler's methods accepts at least two parameters: A pointer to the service-interface implementation (the handler object itself) and a handle to a GError structure to receive information about any error that occurs. On success, a handler method returns TRUE. A return value of FALSE indicates an error occurred and the error parameter has been set. (Methods should not return FALSE without first setting the error parameter.) */ static gboolean tutorial_calculator_handler_ping (CalculatorIf *iface, GError **error) { THRIFT_UNUSED_VAR (iface); THRIFT_UNUSED_VAR (error); puts ("ping()"); return TRUE; } /* Service-method parameters are passed through as parameters to the handler method. If the service method returns a value an output parameter, _return, is additionally passed to the handler method. This parameter should be set appropriately before the method returns, whenever it succeeds. The return value from this method happens to be of a base type, i32, but note if a method returns a complex type such as a map or list *_return will point to a pre-allocated data structure that does not need to be re-allocated and should not be destroyed. */ static gboolean tutorial_calculator_handler_add (CalculatorIf *iface, gint32 *_return, const gint32 num1, const gint32 num2, GError **error) { THRIFT_UNUSED_VAR (iface); THRIFT_UNUSED_VAR (error); printf ("add(%d,%d)\n", num1, num2); *_return = num1 + num2; return TRUE; } /* Any handler method can return a ThriftApplicationException to the client by setting its error parameter appropriately and returning FALSE. See the ThriftApplicationExceptionError enumeration defined in thrift_application_exception.h for a list of recognized exception types (GError codes). If a service method can also throw a custom exception (that is, one defined in the .thrift file) an additional output parameter will be provided (here, "ouch") to hold an instance of the exception, when necessary. Note there will be a separate parameter added for each type of exception the method can throw. Unlike return values, exception objects are never pre-created; this is always the responsibility of the handler method. */ static gboolean tutorial_calculator_handler_calculate (CalculatorIf *iface, gint32 *_return, const gint32 logid, const Work *w, InvalidOperation **ouch, GError **error) { TutorialCalculatorHandler *self; gint *log_key; gchar log_value[12]; SharedStruct *log_struct; gint num1; gint num2; Operation op; gboolean result = TRUE; THRIFT_UNUSED_VAR (error); g_return_val_if_fail (IS_TUTORIAL_CALCULATOR_HANDLER (iface), FALSE); self = TUTORIAL_CALCULATOR_HANDLER (iface); /* Remember: Exception objects are never pre-created */ g_assert (*ouch == NULL); /* Fetch the contents of our Work parameter. Note that integer properties of thirty-two bits or fewer in width are _always_ of type gint, regardless of the range of values they hold. A common error is trying to retrieve, say, a structure member defined in the .thrift file as type i16 into a variable of type gint16, which will clobber variables adjacent on the stack. Remember: If you're retrieving an integer property the receiving variable must be of either type gint or gint64, as appropriate. */ g_object_get ((Work *)w, "num1", &num1, "num2", &num2, "op", &op, NULL); printf ("calculate(%d,{%d,%d,%d})\n", logid, op, num1, num2); switch (op) { case OPERATION_ADD: *_return = num1 + num2; break; case OPERATION_SUBTRACT: *_return = num1 - num2; break; case OPERATION_MULTIPLY: *_return = num1 * num2; break; case OPERATION_DIVIDE: if (num2 == 0) { /* For each custom exception type a subclass of ThriftStruct is generated by the Thrift compiler. Throw an exception by setting the corresponding output parameter to a new instance of its type and returning FALSE. */ *ouch = g_object_new (TYPE_INVALID_OPERATION, "whatOp", op, "why", g_strdup ("Cannot divide by 0"), NULL); result = FALSE; /* Note the call to g_strdup above: All the memory used by a ThriftStruct's properties belongs to the object itself and will be freed on destruction. Removing this call to g_strdup will lead to a segmentation fault as the object tries to release memory allocated statically to the program. */ } else { *_return = num1 / num2; } break; default: *ouch = g_object_new (TYPE_INVALID_OPERATION, "whatOp", op, "why", g_strdup ("Invalid Operation"), NULL); result = FALSE; } /* On success, log a record of the result to our hash table */ if (result) { log_key = g_malloc (sizeof *log_key); *log_key = logid; snprintf (log_value, sizeof log_value, "%d", *_return); log_struct = g_object_new (TYPE_SHARED_STRUCT, "key", *log_key, "value", g_strdup (log_value), NULL); g_hash_table_replace (self->log, log_key, log_struct); } return result; } /* A one-way method has the same signature as an equivalent, regular method that returns no value. */ static gboolean tutorial_calculator_handler_zip (CalculatorIf *iface, GError **error) { THRIFT_UNUSED_VAR (iface); THRIFT_UNUSED_VAR (error); puts ("zip()"); return TRUE; } /* As specified in the .thrift file (tutorial.thrift), the Calculator service extends the SharedService service. Correspondingly, in the generated code the Calculator interface, CalculatorIf, extends the SharedService interface, SharedServiceIf, and subclasses of CalculatorHandler should implement its methods as well. Here we provide an implementation for the getStruct method from the parent service. */ static gboolean tutorial_calculator_handler_get_struct (SharedServiceIf *iface, SharedStruct **_return, const gint32 key32, GError **error) { gint key = (gint)key32; TutorialCalculatorHandler *self; SharedStruct *log_struct; gint log_key; gchar *log_value; THRIFT_UNUSED_VAR (error); g_return_val_if_fail (IS_TUTORIAL_CALCULATOR_HANDLER (iface), FALSE); self = TUTORIAL_CALCULATOR_HANDLER (iface); /* Remember: Complex return types are always pre-created and need only be populated */ g_assert (*_return != NULL); printf ("getStruct(%d)\n", key); /* If the key exists in our log, return the corresponding logged data (or an empty SharedStruct structure if it does not). Incidentally, note we _must_ here copy the values from the hash table into the return structure. All memory used by the return structure belongs to the structure itself and will be freed once a response is sent to the client. If we merely freed *_return and set it to point to our hash-table entry, that would mean memory would be released (effectively, data erased) out of the hash table! */ log_struct = g_hash_table_lookup (self->log, &key); if (log_struct != NULL) { g_object_get (log_struct, "key", &log_key, "value", &log_value, NULL); g_object_set (*_return, "key", log_key, "value", g_strdup (log_value), NULL); } return TRUE; } /* TutorialCalculatorHandler's instance finalizer (destructor) */ static void tutorial_calculator_handler_finalize (GObject *object) { TutorialCalculatorHandler *self = TUTORIAL_CALCULATOR_HANDLER (object); /* Free our calculation-log hash table */ g_hash_table_unref (self->log); self->log = NULL; /* Chain up to the parent class */ G_OBJECT_CLASS (tutorial_calculator_handler_parent_class)-> finalize (object); } /* TutorialCalculatorHandler's instance initializer (constructor) */ static void tutorial_calculator_handler_init (TutorialCalculatorHandler *self) { /* Create our calculation-log hash table */ self->log = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_object_unref); } /* TutorialCalculatorHandler's class initializer */ static void tutorial_calculator_handler_class_init (TutorialCalculatorHandlerClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); SharedServiceHandlerClass *shared_service_handler_class = SHARED_SERVICE_HANDLER_CLASS (klass); CalculatorHandlerClass *calculator_handler_class = CALCULATOR_HANDLER_CLASS (klass); /* Register our destructor */ gobject_class->finalize = tutorial_calculator_handler_finalize; /* Register our implementations of CalculatorHandler's methods */ calculator_handler_class->ping = tutorial_calculator_handler_ping; calculator_handler_class->add = tutorial_calculator_handler_add; calculator_handler_class->calculate = tutorial_calculator_handler_calculate; calculator_handler_class->zip = tutorial_calculator_handler_zip; /* Register our implementation of SharedServiceHandler's method */ shared_service_handler_class->get_struct = tutorial_calculator_handler_get_struct; } /* ---------------------------------------------------------------- */ /* That ends the implementation of TutorialCalculatorHandler. Everything below is fairly generic code that sets up a minimal Thrift server for tutorial clients. */ /* Our server object, declared globally so it is accessible within the SIGINT signal handler */ ThriftServer *server = NULL; /* A flag that indicates whether the server was interrupted with SIGINT (i.e. Ctrl-C) so we can tell whether its termination was abnormal */ gboolean sigint_received = FALSE; /* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the server */ static void sigint_handler (int signal_number) { THRIFT_UNUSED_VAR (signal_number); /* Take note we were called */ sigint_received = TRUE; /* Shut down the server gracefully */ if (server != NULL) thrift_server_stop (server); } int main (void) { TutorialCalculatorHandler *handler; CalculatorProcessor *processor; ThriftServerTransport *server_transport; ThriftTransportFactory *transport_factory; ThriftProtocolFactory *protocol_factory; struct sigaction sigint_action; GError *error = NULL; int exit_status = 0; #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif /* Create an instance of our handler, which provides the service's methods' implementation */ handler = g_object_new (TYPE_TUTORIAL_CALCULATOR_HANDLER, NULL); /* Create an instance of the service's processor, automatically generated by the Thrift compiler, which parses incoming messages and dispatches them to the appropriate method in the handler */ processor = g_object_new (TYPE_CALCULATOR_PROCESSOR, "handler", handler, NULL); /* Create our server socket, which binds to the specified port and listens for client connections */ server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", 9090, NULL); /* Create our transport factory, used by the server to wrap "raw" incoming connections from the client (in this case with a ThriftBufferedTransport to improve performance) */ transport_factory = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, NULL); /* Create our protocol factory, which determines which wire protocol the server will use (in this case, Thrift's binary protocol) */ protocol_factory = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, NULL); /* Create the server itself */ server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER, "processor", processor, "server_transport", server_transport, "input_transport_factory", transport_factory, "output_transport_factory", transport_factory, "input_protocol_factory", protocol_factory, "output_protocol_factory", protocol_factory, NULL); /* Install our SIGINT handler, which handles Ctrl-C being pressed by stopping the server gracefully (not strictly necessary, but a nice touch) */ memset (&sigint_action, 0, sizeof (sigint_action)); sigint_action.sa_handler = sigint_handler; sigint_action.sa_flags = SA_RESETHAND; sigaction (SIGINT, &sigint_action, NULL); /* Start the server, which will run until its stop method is invoked (from within the SIGINT handler, in this case) */ puts ("Starting the server..."); thrift_server_serve (server, &error); /* If the server stopped for any reason other than having been interrupted by the user, report the error */ if (!sigint_received) { g_message ("thrift_server_serve: %s", error != NULL ? error->message : "(null)"); g_clear_error (&error); } puts ("done."); g_object_unref (server); g_object_unref (transport_factory); g_object_unref (protocol_factory); g_object_unref (server_transport); g_object_unref (processor); g_object_unref (handler); return exit_status; } thrift-0.23.0/tutorial/c_glib/Makefile.in0000644000175000017500000010555515170007167020522 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = tutorial_server$(EXEEXT) tutorial_client$(EXEEXT) subdir = tutorial/c_glib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) libtutorialgencglib_la_DEPENDENCIES = \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la am__dirstamp = $(am__leading_dot)dirstamp nodist_libtutorialgencglib_la_OBJECTS = \ gen-c_glib/libtutorialgencglib_la-calculator.lo \ gen-c_glib/libtutorialgencglib_la-shared_service.lo \ gen-c_glib/libtutorialgencglib_la-shared_types.lo \ gen-c_glib/libtutorialgencglib_la-tutorial_types.lo libtutorialgencglib_la_OBJECTS = \ $(nodist_libtutorialgencglib_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libtutorialgencglib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am_tutorial_client_OBJECTS = c_glib_client.$(OBJEXT) tutorial_client_OBJECTS = $(am_tutorial_client_OBJECTS) tutorial_client_DEPENDENCIES = libtutorialgencglib.la \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la am_tutorial_server_OBJECTS = c_glib_server.$(OBJEXT) tutorial_server_OBJECTS = $(am_tutorial_server_OBJECTS) tutorial_server_DEPENDENCIES = libtutorialgencglib.la \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la tutorial_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(tutorial_server_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/c_glib_client.Po \ ./$(DEPDIR)/c_glib_server.Po \ gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-calculator.Plo \ gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_service.Plo \ gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_types.Plo \ gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-tutorial_types.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist_libtutorialgencglib_la_SOURCES) \ $(tutorial_client_SOURCES) $(tutorial_server_SOURCES) DIST_SOURCES = $(tutorial_client_SOURCES) $(tutorial_server_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc BUILT_SOURCES = \ gen-c_glib/calculator.h \ gen-c_glib/shared_service.h \ gen-c_glib/shared_types.h \ gen-c_glib/tutorial_types.h AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) @GCOV_CFLAGS@ -I$(top_builddir)/lib/c_glib/src/thrift AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -Igen-c_glib AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) @GCOV_LDFLAGS@ noinst_LTLIBRARIES = \ libtutorialgencglib.la nodist_libtutorialgencglib_la_SOURCES = \ gen-c_glib/calculator.c \ gen-c_glib/calculator.h \ gen-c_glib/shared_service.c \ gen-c_glib/shared_service.h \ gen-c_glib/shared_types.c \ gen-c_glib/shared_types.h \ gen-c_glib/tutorial_types.c \ gen-c_glib/tutorial_types.h libtutorialgencglib_la_LIBADD = \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la libtutorialgencglib_la_CFLAGS = \ $(AM_CFLAGS) -Wno-unused-function tutorial_server_SOURCES = \ c_glib_server.c tutorial_server_LDFLAGS = $(OPENSSL_LIBS) tutorial_server_LDADD = \ libtutorialgencglib.la \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la tutorial_client_SOURCES = \ c_glib_client.c tutorial_client_LDADD = \ libtutorialgencglib.la \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la EXTRA_DIST = \ c_glib_server.c \ c_glib_client.c all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/c_glib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/c_glib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gen-c_glib/$(am__dirstamp): @$(MKDIR_P) gen-c_glib @: > gen-c_glib/$(am__dirstamp) gen-c_glib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gen-c_glib/$(DEPDIR) @: > gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtutorialgencglib_la-calculator.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtutorialgencglib_la-shared_service.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtutorialgencglib_la-shared_types.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtutorialgencglib_la-tutorial_types.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) libtutorialgencglib.la: $(libtutorialgencglib_la_OBJECTS) $(libtutorialgencglib_la_DEPENDENCIES) $(EXTRA_libtutorialgencglib_la_DEPENDENCIES) $(AM_V_CCLD)$(libtutorialgencglib_la_LINK) $(libtutorialgencglib_la_OBJECTS) $(libtutorialgencglib_la_LIBADD) $(LIBS) tutorial_client$(EXEEXT): $(tutorial_client_OBJECTS) $(tutorial_client_DEPENDENCIES) $(EXTRA_tutorial_client_DEPENDENCIES) @rm -f tutorial_client$(EXEEXT) $(AM_V_CCLD)$(LINK) $(tutorial_client_OBJECTS) $(tutorial_client_LDADD) $(LIBS) tutorial_server$(EXEEXT): $(tutorial_server_OBJECTS) $(tutorial_server_DEPENDENCIES) $(EXTRA_tutorial_server_DEPENDENCIES) @rm -f tutorial_server$(EXEEXT) $(AM_V_CCLD)$(tutorial_server_LINK) $(tutorial_server_OBJECTS) $(tutorial_server_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f gen-c_glib/*.$(OBJEXT) -rm -f gen-c_glib/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_glib_client.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c_glib_server.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-calculator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_service.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-tutorial_types.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< gen-c_glib/libtutorialgencglib_la-calculator.lo: gen-c_glib/calculator.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtutorialgencglib_la-calculator.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-calculator.Tpo -c -o gen-c_glib/libtutorialgencglib_la-calculator.lo `test -f 'gen-c_glib/calculator.c' || echo '$(srcdir)/'`gen-c_glib/calculator.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-calculator.Tpo gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-calculator.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/calculator.c' object='gen-c_glib/libtutorialgencglib_la-calculator.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtutorialgencglib_la-calculator.lo `test -f 'gen-c_glib/calculator.c' || echo '$(srcdir)/'`gen-c_glib/calculator.c gen-c_glib/libtutorialgencglib_la-shared_service.lo: gen-c_glib/shared_service.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtutorialgencglib_la-shared_service.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_service.Tpo -c -o gen-c_glib/libtutorialgencglib_la-shared_service.lo `test -f 'gen-c_glib/shared_service.c' || echo '$(srcdir)/'`gen-c_glib/shared_service.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_service.Tpo gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_service.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/shared_service.c' object='gen-c_glib/libtutorialgencglib_la-shared_service.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtutorialgencglib_la-shared_service.lo `test -f 'gen-c_glib/shared_service.c' || echo '$(srcdir)/'`gen-c_glib/shared_service.c gen-c_glib/libtutorialgencglib_la-shared_types.lo: gen-c_glib/shared_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtutorialgencglib_la-shared_types.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_types.Tpo -c -o gen-c_glib/libtutorialgencglib_la-shared_types.lo `test -f 'gen-c_glib/shared_types.c' || echo '$(srcdir)/'`gen-c_glib/shared_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_types.Tpo gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/shared_types.c' object='gen-c_glib/libtutorialgencglib_la-shared_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtutorialgencglib_la-shared_types.lo `test -f 'gen-c_glib/shared_types.c' || echo '$(srcdir)/'`gen-c_glib/shared_types.c gen-c_glib/libtutorialgencglib_la-tutorial_types.lo: gen-c_glib/tutorial_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtutorialgencglib_la-tutorial_types.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-tutorial_types.Tpo -c -o gen-c_glib/libtutorialgencglib_la-tutorial_types.lo `test -f 'gen-c_glib/tutorial_types.c' || echo '$(srcdir)/'`gen-c_glib/tutorial_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-tutorial_types.Tpo gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-tutorial_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/tutorial_types.c' object='gen-c_glib/libtutorialgencglib_la-tutorial_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtutorialgencglib_la_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtutorialgencglib_la-tutorial_types.lo `test -f 'gen-c_glib/tutorial_types.c' || echo '$(srcdir)/'`gen-c_glib/tutorial_types.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf gen-c_glib/.libs gen-c_glib/_libs style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f gen-c_glib/$(DEPDIR)/$(am__dirstamp) -rm -f gen-c_glib/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/c_glib_client.Po -rm -f ./$(DEPDIR)/c_glib_server.Po -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-calculator.Plo -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-tutorial_types.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/c_glib_client.Po -rm -f ./$(DEPDIR)/c_glib_server.Po -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-calculator.Plo -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-shared_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtutorialgencglib_la-tutorial_types.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: all check install install-am install-exec install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-c_glib/calculator.c gen-c_glib/calculator.h gen-c_glib/shared_service.c gen-c_glib/shared_service.h gen-c_glib/shared_types.c gen-c_glib/shared_types.h gen-c_glib/tutorial_types.c gen-c_glib/tutorial_types.h: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen c_glib -r $< clean-local: $(RM) gen-c_glib/* tutorialserver: all ./tutorial_server tutorialclient: all ./tutorial_client distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/c_glib/Makefile.am0000664000175000017500000000512015165535636020511 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc BUILT_SOURCES = \ gen-c_glib/calculator.h \ gen-c_glib/shared_service.h \ gen-c_glib/shared_types.h \ gen-c_glib/tutorial_types.h AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) @GCOV_CFLAGS@ -I$(top_builddir)/lib/c_glib/src/thrift AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -Igen-c_glib AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) @GCOV_LDFLAGS@ noinst_LTLIBRARIES = \ libtutorialgencglib.la nodist_libtutorialgencglib_la_SOURCES = \ gen-c_glib/calculator.c \ gen-c_glib/calculator.h \ gen-c_glib/shared_service.c \ gen-c_glib/shared_service.h \ gen-c_glib/shared_types.c \ gen-c_glib/shared_types.h \ gen-c_glib/tutorial_types.c \ gen-c_glib/tutorial_types.h libtutorialgencglib_la_LIBADD = \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la libtutorialgencglib_la_CFLAGS = \ $(AM_CFLAGS) -Wno-unused-function noinst_PROGRAMS = \ tutorial_server \ tutorial_client tutorial_server_SOURCES = \ c_glib_server.c tutorial_server_LDFLAGS = $(OPENSSL_LIBS) tutorial_server_LDADD = \ libtutorialgencglib.la \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la tutorial_client_SOURCES = \ c_glib_client.c tutorial_client_LDADD = \ libtutorialgencglib.la \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la gen-c_glib/calculator.c gen-c_glib/calculator.h gen-c_glib/shared_service.c gen-c_glib/shared_service.h gen-c_glib/shared_types.c gen-c_glib/shared_types.h gen-c_glib/tutorial_types.c gen-c_glib/tutorial_types.h: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen c_glib -r $< clean-local: $(RM) gen-c_glib/* tutorialserver: all ./tutorial_server tutorialclient: all ./tutorial_client distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ c_glib_server.c \ c_glib_client.c thrift-0.23.0/tutorial/java/0000755000175000017500000000000015170007202016132 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/java/src/0000775000175000017500000000000015165535636016750 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/java/src/CalculatorHandler.java0000664000175000017500000000464115165535636023207 0ustar00buildbuild00000000000000/* * 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 org.apache.thrift.TException; // Generated code import tutorial.*; import shared.*; import java.util.HashMap; public class CalculatorHandler implements Calculator.Iface { private HashMap log; public CalculatorHandler() { log = new HashMap(); } public void ping() { System.out.println("ping()"); } public int add(int n1, int n2) { System.out.println("add(" + n1 + "," + n2 + ")"); return n1 + n2; } public int calculate(int logid, Work work) throws InvalidOperation { System.out.println("calculate(" + logid + ", {" + work.op + "," + work.num1 + "," + work.num2 + "})"); int val = 0; switch (work.op) { case ADD: val = work.num1 + work.num2; break; case SUBTRACT: val = work.num1 - work.num2; break; case MULTIPLY: val = work.num1 * work.num2; break; case DIVIDE: if (work.num2 == 0) { InvalidOperation io = new InvalidOperation(); io.whatOp = work.op.getValue(); io.why = "Cannot divide by 0"; throw io; } val = work.num1 / work.num2; break; default: InvalidOperation io = new InvalidOperation(); io.whatOp = work.op.getValue(); io.why = "Unknown operation"; throw io; } SharedStruct entry = new SharedStruct(); entry.key = logid; entry.value = Integer.toString(val); log.put(logid, entry); return val; } public SharedStruct getStruct(int key) { System.out.println("getStruct(" + key + ")"); return log.get(key); } public void zip() { System.out.println("zip()"); } } thrift-0.23.0/tutorial/java/src/JavaClient.java0000664000175000017500000000667515165535636021651 0ustar00buildbuild00000000000000/* * 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. */ // Generated code import tutorial.*; import shared.*; import org.apache.thrift.TException; import org.apache.thrift.transport.TSSLTransportFactory; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; public class JavaClient { public static void main(String [] args) { if (args.length != 1) { System.out.println("Please enter 'simple' or 'secure'"); System.exit(0); } try { TTransport transport; if (args[0].contains("simple")) { transport = new TSocket("localhost", 9090); transport.open(); } else { /* * Similar to the server, you can use the parameters to setup client parameters or * use the default settings. On the client side, you will need a TrustStore which * contains the trusted certificate along with the public key. * For this example it's a self-signed cert. */ TSSLTransportParameters params = new TSSLTransportParameters(); params.setTrustStore("../../lib/java/test/resources/.truststore", "thrift", "SunX509", "JKS"); /* * Get a client transport instead of a server transport. The connection is opened on * invocation of the factory method, no need to specifically call open() */ transport = TSSLTransportFactory.getClientSocket("localhost", 9091, 0, params); } TProtocol protocol = new TBinaryProtocol(transport); Calculator.Client client = new Calculator.Client(protocol); perform(client); transport.close(); } catch (TException x) { x.printStackTrace(); } } private static void perform(Calculator.Client client) throws TException { client.ping(); System.out.println("ping()"); int sum = client.add(1,1); System.out.println("1+1=" + sum); Work work = new Work(); work.op = Operation.DIVIDE; work.num1 = 1; work.num2 = 0; try { int quotient = client.calculate(1, work); System.out.println("Whoa we can divide by 0"); } catch (InvalidOperation io) { System.out.println("Invalid operation: " + io.why); } work.op = Operation.SUBTRACT; work.num1 = 15; work.num2 = 10; try { int diff = client.calculate(1, work); System.out.println("15-10=" + diff); } catch (InvalidOperation io) { System.out.println("Invalid operation: " + io.why); } SharedStruct log = client.getStruct(1); System.out.println("Check log: " + log.value); } } thrift-0.23.0/tutorial/java/src/JavaServer.java0000664000175000017500000000761215165535636021671 0ustar00buildbuild00000000000000/* * 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 org.apache.thrift.server.TServer; import org.apache.thrift.server.TServer.Args; import org.apache.thrift.server.TSimpleServer; import org.apache.thrift.server.TThreadPoolServer; import org.apache.thrift.transport.TSSLTransportFactory; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TServerTransport; import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters; // Generated code import tutorial.*; import shared.*; import java.util.HashMap; public class JavaServer { public static CalculatorHandler handler; public static Calculator.Processor processor; public static void main(String [] args) { try { handler = new CalculatorHandler(); processor = new Calculator.Processor(handler); Runnable simple = new Runnable() { public void run() { simple(processor); } }; Runnable secure = new Runnable() { public void run() { secure(processor); } }; new Thread(simple).start(); new Thread(secure).start(); } catch (Exception x) { x.printStackTrace(); } } public static void simple(Calculator.Processor processor) { try { TServerTransport serverTransport = new TServerSocket(9090); TServer server = new TSimpleServer(new Args(serverTransport).processor(processor)); // Use this for a multithreaded server // TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor)); System.out.println("Starting the simple server..."); server.serve(); } catch (Exception e) { e.printStackTrace(); } } public static void secure(Calculator.Processor processor) { try { /* * Use TSSLTransportParameters to setup the required SSL parameters. In this example * we are setting the keystore and the keystore password. Other things like algorithms, * cipher suites, client auth etc can be set. */ TSSLTransportParameters params = new TSSLTransportParameters(); // The Keystore contains the private key params.setKeyStore("../../lib/java/test/resources/.keystore", "thrift", null, null); /* * Use any of the TSSLTransportFactory to get a server transport with the appropriate * SSL configuration. You can use the default settings if properties are set in the command line. * Ex: -Djavax.net.ssl.keyStore=.keystore and -Djavax.net.ssl.keyStorePassword=thrift * * Note: You need not explicitly call open(). The underlying server socket is bound on return * from the factory class. */ TServerTransport serverTransport = TSSLTransportFactory.getServerSocket(9091, 0, null, params); TServer server = new TSimpleServer(new Args(serverTransport).processor(processor)); // Use this for a multi threaded server // TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor)); System.out.println("Starting the secure server..."); server.serve(); } catch (Exception e) { e.printStackTrace(); } } } thrift-0.23.0/tutorial/java/build.properties0000664000175000017500000000036415165535636021401 0ustar00buildbuild00000000000000# Maven Ant tasks Jar details mvn.ant.task.version=2.1.3 mvn.repo=https://repo1.maven.org/maven2 mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version} mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar thrift-0.23.0/tutorial/java/build.xml0000664000175000017500000001335415165535636020010 0ustar00buildbuild00000000000000 Thrift Java Tutorial tutorial client simple: tutorial client secure: tutorial client simple: tutorial client secure: thrift-0.23.0/tutorial/java/README.md0000664000175000017500000000070615165535636017443 0ustar00buildbuild00000000000000Thrift Java Tutorial ================================================== 1) Compile the Java library thrift/lib/java$ make or: thrift/lib/java$ ant 4) Run the tutorial: start server and client with one step: thrift/tutorial/java$ make tutorial or: thrift/tutorial/java$ make tutorialserver thrift/tutorial/java$ make tutorialclient or: thrift/tutorial/java$ ant tutorialserver thrift/tutorial/java$ ant tutorialclient thrift-0.23.0/tutorial/java/Makefile.in0000644000175000017500000004343215170007167020217 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/java ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ build.properties \ build.xml \ src \ README.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/java/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/java/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile export CLASSPATH # Make sure this doesn't fail if ant is not configured. clean-local: ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \ $$ANT $(ANT_FLAGS) clean all-local: $(ANT) $(ANT_FLAGS) compile check-local: all $(ANT) $(ANT_FLAGS) test tutorial: all $(ANT) $(ANT_FLAGS) tutorial tutorialserver: all $(ANT) $(ANT_FLAGS) tutorialserver tutorialclient: all $(ANT) $(ANT_FLAGS) tutorialclient distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/java/Makefile.am0000664000175000017500000000243715165535636020223 0ustar00buildbuild00000000000000# # 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. # export CLASSPATH # Make sure this doesn't fail if ant is not configured. clean-local: ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \ $$ANT $(ANT_FLAGS) clean all-local: $(ANT) $(ANT_FLAGS) compile check-local: all $(ANT) $(ANT_FLAGS) test tutorial: all $(ANT) $(ANT_FLAGS) tutorial tutorialserver: all $(ANT) $(ANT_FLAGS) tutorialserver tutorialclient: all $(ANT) $(ANT_FLAGS) tutorialclient distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ build.properties \ build.xml \ src \ README.md thrift-0.23.0/tutorial/py/0000755000175000017500000000000015170007202015641 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/py/setup.cfg0000664000175000017500000000002715165535636017510 0ustar00buildbuild00000000000000[flake8] ignore = E402 thrift-0.23.0/tutorial/py/PythonClient.py0000775000175000017500000000446215165535636020673 0ustar00buildbuild00000000000000#!/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. # import sys import glob sys.path.append('gen-py') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import Calculator from tutorial.ttypes import InvalidOperation, Operation, Work from thrift import Thrift from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol def main(): # Make socket transport = TSocket.TSocket('localhost', 9090) # Buffering is critical. Raw sockets are very slow transport = TTransport.TBufferedTransport(transport) # Wrap in a protocol protocol = TBinaryProtocol.TBinaryProtocol(transport) # Create a client to use the protocol encoder client = Calculator.Client(protocol) # Connect! transport.open() client.ping() print('ping()') sum_ = client.add(1, 1) print('1+1=%d' % sum_) work = Work() work.op = Operation.DIVIDE work.num1 = 1 work.num2 = 0 try: quotient = client.calculate(1, work) print('Whoa? You know how to divide by zero?') print('FYI the answer is %d' % quotient) except InvalidOperation as e: print('InvalidOperation: %r' % e) work.op = Operation.SUBTRACT work.num1 = 15 work.num2 = 10 diff = client.calculate(1, work) print('15-10=%d' % diff) log = client.getStruct(1) print('Check log: %s' % log.value) # Close! transport.close() if __name__ == '__main__': try: main() except Thrift.TException as tx: print('%s' % tx.message) thrift-0.23.0/tutorial/py/PythonServer.py0000775000175000017500000000563515165535636020726 0ustar00buildbuild00000000000000#!/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. # import glob import sys sys.path.append('gen-py') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import Calculator from tutorial.ttypes import InvalidOperation, Operation from shared.ttypes import SharedStruct from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.server import TServer class CalculatorHandler: def __init__(self): self.log = {} def ping(self): print('ping()') def add(self, n1, n2): print('add(%d,%d)' % (n1, n2)) return n1 + n2 def calculate(self, logid, work): print('calculate(%d, %r)' % (logid, work)) if work.op == Operation.ADD: val = work.num1 + work.num2 elif work.op == Operation.SUBTRACT: val = work.num1 - work.num2 elif work.op == Operation.MULTIPLY: val = work.num1 * work.num2 elif work.op == Operation.DIVIDE: if work.num2 == 0: raise InvalidOperation(work.op, 'Cannot divide by 0') val = work.num1 / work.num2 else: raise InvalidOperation(work.op, 'Invalid operation') log = SharedStruct() log.key = logid log.value = '%d' % (val) self.log[logid] = log return val def getStruct(self, key): print('getStruct(%d)' % (key)) return self.log[key] def zip(self): print('zip()') if __name__ == '__main__': handler = CalculatorHandler() processor = Calculator.Processor(handler) transport = TSocket.TServerSocket(host='127.0.0.1', port=9090) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) # You could do one of these for a multithreaded server # server = TServer.TThreadedServer( # processor, transport, tfactory, pfactory) # server = TServer.TThreadPoolServer( # processor, transport, tfactory, pfactory) print('Starting the server...') server.serve() print('done.') thrift-0.23.0/tutorial/py/Makefile.in0000644000175000017500000004313115170007167017722 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/py ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ setup.cfg \ PythonServer.py \ PythonClient.py all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/py/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/py/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-py/tutorial/Calculator.py gen-py/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen py -r $< all-local: gen-py/tutorial/Calculator.py tutorialserver: all ${PYTHON} PythonServer.py tutorialclient: all ${PYTHON} PythonClient.py clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/py/Makefile.am0000664000175000017500000000225015165535636017723 0ustar00buildbuild00000000000000# # 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. # gen-py/tutorial/Calculator.py gen-py/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen py -r $< all-local: gen-py/tutorial/Calculator.py tutorialserver: all ${PYTHON} PythonServer.py tutorialclient: all ${PYTHON} PythonClient.py clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ setup.cfg \ PythonServer.py \ PythonClient.py thrift-0.23.0/tutorial/delphi/0000775000175000017500000000000015165535636016505 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/delphi/DelphiClient/0000775000175000017500000000000015170007142021027 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/delphi/DelphiClient/DelphiClient.dpr0000664000175000017500000000667515165535636024142 0ustar00buildbuild00000000000000(* * 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. *) program DelphiClient; {$APPTYPE CONSOLE} {$D 'Copyright (c) 2012 The Apache Software Foundation'} uses SysUtils, Generics.Collections, Thrift in '..\..\..\lib\delphi\src\Thrift.pas', Thrift.Collections in '..\..\..\lib\delphi\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\..\lib\delphi\src\Thrift.Configuration.pas', Thrift.Exception in '..\..\..\lib\delphi\src\Thrift.Exception.pas', Thrift.Utils in '..\..\..\lib\delphi\src\Thrift.Utils.pas', Thrift.Stream in '..\..\..\lib\delphi\src\Thrift.Stream.pas', Thrift.Protocol in '..\..\..\lib\delphi\src\Thrift.Protocol.pas', Thrift.Server in '..\..\..\lib\delphi\src\Thrift.Server.pas', Thrift.Transport in '..\..\..\lib\delphi\src\Thrift.Transport.pas', Thrift.Transport.WinHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.WinHTTP.pas', Thrift.Transport.MsxmlHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.MsxmlHTTP.pas', Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas', Shared in '..\gen-delphi\Shared.pas', Tutorial in '..\gen-delphi\Tutorial.pas'; type DelphiTutorialClient = class public class procedure Main; end; //--- DelphiTutorialClient --------------------------------------- class procedure DelphiTutorialClient.Main; var transport : ITransport; protocol : IProtocol; client : TCalculator.Iface; work : IWork; sum, quotient, diff : Integer; log : ISharedStruct; begin try transport := TSocketImpl.Create( 'localhost', 9090); protocol := TBinaryProtocolImpl.Create( transport); client := TCalculator.TClient.Create( protocol); transport.Open; client.ping; WriteLn('ping()'); sum := client.add( 1, 1); WriteLn( Format( '1+1=%d', [sum])); work := TWorkImpl.Create; work.Op := TOperation.DIVIDE; work.Num1 := 1; work.Num2 := 0; try quotient := client.calculate(1, work); WriteLn( 'Whoa we can divide by 0'); WriteLn( Format('1/0=%d',[quotient])); except on io: TInvalidOperation do WriteLn( 'Invalid operation: ' + io.Why); end; work.Op := TOperation.SUBTRACT; work.Num1 := 15; work.Num2 := 10; try diff := client.calculate( 1, work); WriteLn( Format('15-10=%d', [diff])); except on io: TInvalidOperation do WriteLn( 'Invalid operation: ' + io.Why); end; log := client.getStruct(1); WriteLn( Format( 'Check log: %s', [log.Value])); transport.Close(); except on e : Exception do WriteLn( e.ClassName+': '+e.Message); end; end; begin try DelphiTutorialClient.Main; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. thrift-0.23.0/tutorial/delphi/DelphiClient/DelphiClient.dproj0000664000175000017500000001505515170007142024441 0ustar00buildbuild00000000000000 {2B8FB3A1-2F9E-4883-8C53-0F56220B34F6} DelphiClient.dpr 12.3 True Debug Win32 Console None DCC32 true true Base true true Base true ..\..\..\lib\delphi\src;$(DCC_UnitSearchPath) 00400000 .\dcu\$(Config)\$(Platform) WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias) ..\bin\$(Config)\$(Platform) false false false false false DEBUG;$(DCC_Define) false true false RELEASE;$(DCC_Define) 0 false MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 True False 0 12 0 0 False False False False False 1033 1252 Thrift Tutorial 0.23.0.0 DelphiClient Copyright © 2012 The Apache Software Foundation DelphiClient.exe Thrift 0.23.0.0 DelphiClient.dpr --transport framed --http http://example.org True 12 thrift-0.23.0/tutorial/delphi/DelphiServer/0000775000175000017500000000000015170007142021057 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/delphi/DelphiServer/DelphiServer.dproj0000664000175000017500000001425315170007142024520 0ustar00buildbuild00000000000000 {2B8FB3A1-2F9E-4883-8C53-0F56220B34F6} DelphiServer.dpr 12.3 True Debug Win32 Console None DCC32 true true Base true true Base true 00400000 .\dcu\$(Config)\$(Platform) WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias) ..\bin\$(Config)\$(Platform) false false false false false DEBUG;$(DCC_Define) false true false RELEASE;$(DCC_Define) 0 false MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 True False 0 12 0 0 False False False False False 1033 1252 Thrift Tutorial 0.23.0.0 DelphiServer Copyright © 2012 The Apache Software Foundation DelphiServer.exe Thrift 0.23.0.0 DelphiServer.dpr True 12 thrift-0.23.0/tutorial/delphi/DelphiServer/DelphiServer.dpr0000664000175000017500000001124115165535636024203 0ustar00buildbuild00000000000000(* * 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. *) program DelphiServer; {$APPTYPE CONSOLE} {$D 'Copyright (c) 2012 The Apache Software Foundation'} {$Q+} // throws exceptions on numeric overflows uses SysUtils, Generics.Collections, Thrift in '..\..\..\lib\delphi\src\Thrift.pas', Thrift.Collections in '..\..\..\lib\delphi\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\..\lib\delphi\src\Thrift.Configuration.pas', Thrift.Exception in '..\..\..\lib\delphi\src\Thrift.Exception.pas', Thrift.Utils in '..\..\..\lib\delphi\src\Thrift.Utils.pas', Thrift.Stream in '..\..\..\lib\delphi\src\Thrift.Stream.pas', Thrift.Protocol in '..\..\..\lib\delphi\src\Thrift.Protocol.pas', Thrift.Server in '..\..\..\lib\delphi\src\Thrift.Server.pas', Thrift.Transport in '..\..\..\lib\delphi\src\Thrift.Transport.pas', Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas', Shared in '..\gen-delphi\Shared.pas', Tutorial in '..\gen-delphi\Tutorial.pas'; type TCalculatorHandler = class( TInterfacedObject, TSharedService.Iface, TCalculator.Iface) protected FLog : TDictionary< Integer, ISharedStruct>; // TSharedService.Iface function getStruct(key: Integer): ISharedStruct; // TCalculator.Iface procedure ping(); function add(num1: Integer; num2: Integer): Integer; function calculate(logid: Integer; const w: IWork): Integer; procedure zip(); public constructor Create; destructor Destroy; override; end; DelphiTutorialServer = class public class procedure Main; end; //--- TCalculatorHandler --------------------------------------------------- constructor TCalculatorHandler.Create; begin inherited Create; FLog := TDictionary< Integer, ISharedStruct>.Create(); end; destructor TCalculatorHandler.Destroy; begin try FreeAndNil( FLog); finally inherited Destroy; end; end; procedure TCalculatorHandler.ping; begin WriteLn( 'ping()'); end; function TCalculatorHandler.add(num1: Integer; num2: Integer): Integer; begin WriteLn( Format( 'add( %d, %d)', [num1, num2])); result := num1 + num2; end; function TCalculatorHandler.calculate(logid: Integer; const w: IWork): Integer; var entry : ISharedStruct; begin try WriteLn( Format('calculate( %d, [%d,%d,%d])', [logid, Ord(w.Op), w.Num1, w.Num2])); case w.Op of TOperation.ADD : result := w.Num1 + w.Num2; TOperation.SUBTRACT : result := w.Num1 - w.Num2; TOperation.MULTIPLY : result := w.Num1 * w.Num2; TOperation.DIVIDE : result := Round( w.Num1 / w.Num2); else raise TInvalidOperation.Create( Ord(w.Op), 'Unknown operation'); end; except on e:Thrift.TException do raise; // let Thrift Exceptions pass through on e:Exception do raise TInvalidOperation.Create( Ord(w.Op), e.Message); // repackage all other end; entry := TSharedStructImpl.Create; entry.Key := logid; entry.Value := IntToStr( result); FLog.AddOrSetValue( logid, entry); end; function TCalculatorHandler.getStruct(key: Integer): ISharedStruct; begin WriteLn( Format( 'getStruct(%d)', [key])); result := FLog[key]; end; procedure TCalculatorHandler.zip; begin WriteLn( 'zip()'); end; //--- DelphiTutorialServer ---------------------------------------------------------------------- class procedure DelphiTutorialServer.Main; var handler : TCalculator.Iface; processor : IProcessor; transport : IServerTransport; server : IServer; begin try handler := TCalculatorHandler.Create; processor := TCalculator.TProcessorImpl.Create( handler); transport := TServerSocketImpl.Create( 9090); server := TSimpleServer.Create( processor, transport); WriteLn( 'Starting the server...'); server.Serve(); except on e: Exception do WriteLn( e.Message); end; WriteLn('done.'); end; begin try DelphiTutorialServer.Main; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. thrift-0.23.0/tutorial/delphi/Tutorial.groupproj0000664000175000017500000000400115165535636022254 0ustar00buildbuild00000000000000 {3D042C7F-3EF2-4574-8304-AB7FB79F814C} Default.Personality.12 thrift-0.23.0/tutorial/README.md0000664000175000017500000000260515165535636016522 0ustar00buildbuild00000000000000Thrift Tutorial License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Tutorial ======== 1) First things first, you'll need to install the Thrift compiler and the language libraries. Do that using the instructions in the top level README.md file. 2) Read tutorial.thrift to learn about the syntax of a Thrift file 3) Compile the code for the language of your choice: ``` $ thrift $ thrift -r --gen cpp tutorial.thrift ``` 4) Take a look at the generated code. 5) Look in the language directories for sample client/server code. 6) That's about it for now. This tutorial is intentionally brief. It should be just enough to get you started and ready to build your own project. thrift-0.23.0/tutorial/php/0000755000175000017500000000000015170007202016000 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/php/PhpClient.php0000775000175000017500000000467715165535636020447 0ustar00buildbuild00000000000000#!/usr/bin/env php registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib'); $loader->registerNamespace('shared', $GEN_DIR); $loader->registerNamespace('tutorial', $GEN_DIR); $loader->register(); /* * 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. */ use Thrift\Protocol\TBinaryProtocol; use Thrift\Transport\TSocket; use Thrift\Transport\THttpClient; use Thrift\Transport\TBufferedTransport; use Thrift\Exception\TException; try { if (array_search('--http', $argv)) { $socket = new THttpClient('localhost', 8080, '/php/PhpServer.php'); } else { $socket = new TSocket('localhost', 9090); } $transport = new TBufferedTransport($socket, 1024, 1024); $protocol = new TBinaryProtocol($transport); $client = new \tutorial\CalculatorClient($protocol); $transport->open(); $client->ping(); print "ping()\n"; $sum = $client->add(1,1); print "1+1=$sum\n"; $work = new \tutorial\Work(); $work->op = \tutorial\Operation::DIVIDE; $work->num1 = 1; $work->num2 = 0; try { $client->calculate(1, $work); print "Whoa! We can divide by zero?\n"; } catch (\tutorial\InvalidOperation $io) { print "InvalidOperation: $io->why\n"; } $work->op = \tutorial\Operation::SUBTRACT; $work->num1 = 15; $work->num2 = 10; $diff = $client->calculate(1, $work); print "15-10=$diff\n"; $log = $client->getStruct(1); print "Log: $log->value\n"; $transport->close(); } catch (TException $tx) { print 'TException: '.$tx->getMessage()."\n"; } ?> thrift-0.23.0/tutorial/php/runserver.py0000775000175000017500000000214415165535636020440 0ustar00buildbuild00000000000000#!/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. # import os import BaseHTTPServer import CGIHTTPServer # chdir(2) into the tutorial directory. os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) class Handler(CGIHTTPServer.CGIHTTPRequestHandler): cgi_directories = ['/php'] BaseHTTPServer.HTTPServer(('', 8080), Handler).serve_forever() thrift-0.23.0/tutorial/php/PhpServer.php0000775000175000017500000000737015165535636020470 0ustar00buildbuild00000000000000#!/usr/bin/env php registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib'); $loader->registerNamespace('shared', $GEN_DIR); $loader->registerNamespace('tutorial', $GEN_DIR); $loader->register(); /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * This is not a stand-alone server. It should be run as a normal * php web script (like through Apache's mod_php) or as a cgi script * (like with the included runserver.py). You can connect to it with * THttpClient in any language that supports it. The PHP tutorial client * will work if you pass it the argument "--http". */ if (php_sapi_name() == 'cli') { ini_set("display_errors", "stderr"); } use Thrift\Protocol\TBinaryProtocol; use Thrift\Transport\TPhpStream; use Thrift\Transport\TBufferedTransport; class CalculatorHandler implements \tutorial\CalculatorIf { protected $log = array(); public function ping() { error_log("ping()"); } public function add($num1, $num2) { error_log("add({$num1}, {$num2})"); return $num1 + $num2; } public function calculate($logid, \tutorial\Work $w) { error_log("calculate({$logid}, {{$w->op}, {$w->num1}, {$w->num2}})"); switch ($w->op) { case \tutorial\Operation::ADD: $val = $w->num1 + $w->num2; break; case \tutorial\Operation::SUBTRACT: $val = $w->num1 - $w->num2; break; case \tutorial\Operation::MULTIPLY: $val = $w->num1 * $w->num2; break; case \tutorial\Operation::DIVIDE: if ($w->num2 == 0) { $io = new \tutorial\InvalidOperation(); $io->whatOp = $w->op; $io->why = "Cannot divide by 0"; throw $io; } $val = $w->num1 / $w->num2; break; default: $io = new \tutorial\InvalidOperation(); $io->whatOp = $w->op; $io->why = "Invalid Operation"; throw $io; } $log = new \shared\SharedStruct(); $log->key = $logid; $log->value = (string)$val; $this->log[$logid] = $log; return $val; } public function getStruct($key) { error_log("getStruct({$key})"); // This actually doesn't work because the PHP interpreter is // restarted for every request. //return $this->log[$key]; return new \shared\SharedStruct(array("key" => $key, "value" => "PHP is stateless!")); } public function zip() { error_log("zip()"); } }; header('Content-Type', 'application/x-thrift'); if (php_sapi_name() == 'cli') { echo "\r\n"; } $handler = new CalculatorHandler(); $processor = new \tutorial\CalculatorProcessor($handler); $transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W)); $protocol = new TBinaryProtocol($transport, true, true); $transport->open(); $processor->process($protocol, $protocol); $transport->close(); thrift-0.23.0/tutorial/php/Makefile.in0000644000175000017500000004315015170007167020062 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/php ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ PhpServer.php \ PhpClient.php \ runserver.py all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/php/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/php/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-php/tutorial/Calculator.php gen-php/shared/SharedService.php: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen php:server -r $< all-local: gen-php/tutorial/Calculator.php tutorialserver: all ${PYTHON} runserver.py tutorialclient: all ${PHP} PhpClient.php --http clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/php/Makefile.am0000664000175000017500000000226415165535636020067 0ustar00buildbuild00000000000000# # 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. # gen-php/tutorial/Calculator.php gen-php/shared/SharedService.php: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen php:server -r $< all-local: gen-php/tutorial/Calculator.php tutorialserver: all ${PYTHON} runserver.py tutorialclient: all ${PHP} PhpClient.php --http clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ PhpServer.php \ PhpClient.php \ runserver.py thrift-0.23.0/tutorial/netstd/0000755000175000017500000000000015170007202016512 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/netstd/Tutorial.sln0000664000175000017500000001177015165535636021070 0ustar00buildbuild00000000000000Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26114.2 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netstd\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interfaces", "Interfaces\Interfaces.csproj", "{B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{E08F5B84-2B4A-4E09-82D1-E0715775CE5E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.Build.0 = Debug|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.ActiveCfg = Debug|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.Build.0 = Debug|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.ActiveCfg = Debug|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.Build.0 = Debug|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.ActiveCfg = Release|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.Build.0 = Release|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.ActiveCfg = Release|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.Build.0 = Release|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.ActiveCfg = Release|Any CPU {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.Build.0 = Release|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.ActiveCfg = Debug|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.Build.0 = Debug|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.ActiveCfg = Debug|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.Build.0 = Debug|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.ActiveCfg = Release|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.Build.0 = Release|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.ActiveCfg = Release|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.Build.0 = Release|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.ActiveCfg = Release|Any CPU {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.Build.0 = Release|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.ActiveCfg = Debug|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.Build.0 = Debug|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.ActiveCfg = Debug|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.Build.0 = Debug|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.Build.0 = Release|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.ActiveCfg = Release|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.Build.0 = Release|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.ActiveCfg = Release|Any CPU {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.Build.0 = Release|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.ActiveCfg = Debug|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.Build.0 = Debug|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.ActiveCfg = Debug|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.Build.0 = Debug|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.Build.0 = Release|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.ActiveCfg = Release|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.Build.0 = Release|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.ActiveCfg = Release|Any CPU {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {070A5D1D-B29D-4603-999D-693DB444AD0D} EndGlobalSection EndGlobal thrift-0.23.0/tutorial/netstd/Client/0000775000175000017500000000000015170007142017735 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/netstd/Client/Properties/0000775000175000017500000000000015165535636022113 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/netstd/Client/Properties/AssemblyInfo.cs0000664000175000017500000000326115165535636025037 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("Thrift")] [assembly: AssemblyCopyright("The Apache Software Foundation")] [assembly: AssemblyTrademark("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("de78a01b-f7c6-49d1-97da-669d2ed37641")]thrift-0.23.0/tutorial/netstd/Client/Program.cs0000664000175000017500000003665615167543515021732 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Microsoft.Extensions.Logging; using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; using Thrift; using Thrift.Protocol; using Thrift.Transport; using Thrift.Transport.Client; using tutorial; #pragma warning disable IDE0057 // substr namespace Client { public static class LoggingHelper { public static ILoggerFactory LogFactory { get; } = LoggerFactory.Create(builder => { ConfigureLogging(builder); }); public static void ConfigureLogging(ILoggingBuilder logging) { logging.SetMinimumLevel(LogLevel.Trace); logging.AddConsole(); logging.AddDebug(); } public static ILogger CreateLogger() => LogFactory.CreateLogger(); } public class Program { private static readonly ILogger Logger = LoggingHelper.CreateLogger(); private static readonly TConfiguration Configuration = new(); private static void DisplayHelp() { Logger.LogInformation(@" Usage: Client -help will diplay help information Client -tr: -bf: -pr: [-mc:] [-multiplex] will run client with specified arguments (tcp transport and binary protocol by default) and with 1 client Options: -tr (transport): tcp - (default) tcp transport (localhost:9090) tcptls - tcp tls transport (localhost:9090) namedpipe - namedpipe transport (pipe "".test"") http - http transport (http://localhost:9090) -bf (buffering): none - (default) no buffering buffered - buffered transport framed - framed transport -pr (protocol): binary - (default) binary protocol compact - compact protocol json - json protocol -multiplex - adds multiplexed protocol -mc (multiple clients): - number of multiple clients to connect to server (max 100, default 1) Sample: Client -tr:tcp -pr:binary "); } public static async Task Main(string[] args) { args ??= []; // -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; } Logger.LogInformation("Starting client..."); using var source = new CancellationTokenSource(); await RunAsync(args, source.Token); } private static async Task RunAsync(string[] args, CancellationToken cancellationToken) { var numClients = GetNumberOfClients(args); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("Selected # of clients: {numClients}", numClients); var transport = GetTransport(args); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("Selected client transport: {transport}", transport); var protocol = MakeProtocol( args, MakeTransport(args)); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("Selected client protocol: {GetProtocol(args)}", GetProtocol(args)); var mplex = GetMultiplex(args); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("Multiplex {mplex}", mplex); var tasks = new Task[numClients]; for (int i = 0; i < numClients; i++) { var task = RunClientAsync(protocol, mplex, cancellationToken); tasks[i] = task; } Task.WaitAll(tasks, cancellationToken); } private static bool GetMultiplex(string[] args) { var mplex = args.FirstOrDefault(x => x.StartsWith("-multiplex")); return !string.IsNullOrEmpty(mplex); } private static Protocol GetProtocol(string[] args) { var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(protocol)) return Protocol.Binary; protocol = protocol.Substring(0, 1).ToUpperInvariant() + protocol.Substring(1).ToLowerInvariant(); if (Enum.TryParse(protocol, true, out Protocol selectedProtocol)) return selectedProtocol; else return Protocol.Binary; } private static Buffering GetBuffering(string[] args) { var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(buffering)) return Buffering.None; buffering = buffering.Substring(0, 1).ToUpperInvariant() + buffering.Substring(1).ToLowerInvariant(); if (Enum.TryParse(buffering, out var selectedBuffering)) return selectedBuffering; else return Buffering.None; } private static Transport GetTransport(string[] args) { var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(transport)) return Transport.Tcp; transport = transport.Substring(0, 1).ToUpperInvariant() + transport.Substring(1).ToLowerInvariant(); if (Enum.TryParse(transport, true, out Transport selectedTransport)) return selectedTransport; else return Transport.Tcp; } private static TTransport MakeTransport(string[] args) { // construct endpoint transport TTransport? transport = null; Transport selectedTransport = GetTransport(args); { switch (selectedTransport) { case Transport.Tcp: transport = new TSocketTransport(IPAddress.Loopback, 9090, Configuration); break; case Transport.NamedPipe: transport = new TNamedPipeTransport(".test", Configuration); break; case Transport.Http: transport = new THttpTransport(new Uri("http://localhost:9090"), Configuration); break; case Transport.TcpTls: transport = new TTlsSocketTransport(IPAddress.Loopback, 9090, Configuration, GetCertificate(), CertValidator, LocalCertificateSelectionCallback); break; default: Debug.Assert(false, "unhandled case"); break; } } // optionally add layered transport(s) Buffering selectedBuffering = GetBuffering(args); switch (selectedBuffering) { case Buffering.Buffered: transport = new TBufferedTransport(transport); break; case Buffering.Framed: transport = new TFramedTransport(transport); break; default: // layered transport(s) are optional Debug.Assert(selectedBuffering == Buffering.None, "unhandled case"); break; } return transport; } private static int GetNumberOfClients(string[] args) { var numClients = args.FirstOrDefault(x => x.StartsWith("-mc"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("Selected # of clients: {numClients}", numClients); if (int.TryParse(numClients, out int c) && (0 < c) && (c <= 100)) return c; else return 1; } private static X509Certificate2 GetCertificate() { // due to files location in net core better to take certs from top folder var dir = Directory.GetParent(Directory.GetCurrentDirectory()); if (dir != null) { var certFile = GetCertPath(dir); //return new X509Certificate2(certFile, "ThriftTest"); return X509CertificateLoader.LoadPkcs12FromFile(certFile, "ThriftTest"); } else { if (Logger.IsEnabled(LogLevel.Error)) 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) { var topDir = di; var certFile = topDir?.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories).FirstOrDefault(); if (certFile == null) { if (maxCount == 0) throw new FileNotFoundException("Cannot find file in directories"); return GetCertPath(di?.Parent, --maxCount); } return certFile.FullName; } private static X509Certificate2 LocalCertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate? remoteCertificate, string[] acceptableIssuers) { return GetCertificate(); } private static bool CertValidator(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) { return true; } private static TProtocol MakeProtocol(string[] args, TTransport transport) { Protocol selectedProtocol = GetProtocol(args); return selectedProtocol switch { Protocol.Binary => new TBinaryProtocol(transport), Protocol.Compact => new TCompactProtocol(transport), Protocol.Json => new TJsonProtocol(transport), _ => throw new Exception("unhandled protocol"), }; } private static async Task RunClientAsync(TProtocol protocol, bool multiplex, CancellationToken cancellationToken) { try { try { if( multiplex) protocol = new TMultiplexedProtocol(protocol, nameof(Calculator)); var client = new Calculator.Client(protocol); await ExecuteCalculatorClientOperations(client, cancellationToken); } catch (Exception ex) { if (Logger.IsEnabled(LogLevel.Error)) Logger.LogError("{ex}",ex); } finally { protocol.Transport.Close(); } } catch (TApplicationException x) { if (Logger.IsEnabled(LogLevel.Error)) Logger.LogError("{x}",x); } } private static async Task ExecuteCalculatorClientOperations( Calculator.Client client, CancellationToken cancellationToken) { await client.OpenTransportAsync(cancellationToken); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Ping()", client.ClientId); await client.ping(cancellationToken); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Add(1,1)", client.ClientId); var sum = await client.add(1, 1, cancellationToken); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Add(1,1)={sum}", client.ClientId, sum); var work = new Work { Op = Operation.DIVIDE, Num1 = 1, Num2 = 0 }; try { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Calculate(1)", client.ClientId); await client.calculate(1, work, cancellationToken); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Whoa we can divide by 0", client.ClientId); } catch (InvalidOperation io) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Invalid operation: {io}", client.ClientId, io); } work.Op = Operation.SUBTRACT; work.Num1 = 15; work.Num2 = 10; try { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Calculate(1)", client.ClientId); var diff = await client.calculate(1, work, cancellationToken); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} 15-10={diff}", client.ClientId, diff); } catch (InvalidOperation io) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Invalid operation: {io}", client.ClientId, io); } if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} GetStruct(1)", client.ClientId); var log = await client.getStruct(1, cancellationToken); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Check log: {log.Value}", client.ClientId, log.Value); if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{client.ClientId} Zip() with delay 100mc on server side", client.ClientId); await client.zip(cancellationToken); } private enum Transport { Tcp, NamedPipe, Http, TcpBuffered, Framed, TcpTls } private enum Protocol { Binary, Compact, Json, } private enum Buffering { None, Buffered, Framed } } } thrift-0.23.0/tutorial/netstd/Client/ThriftTest.pfx0000664000175000017500000000514515165535636022603 0ustar00buildbuild000000000000000‚ a0‚  *†H†÷  ‚ ‚ 0‚ 0‚ *†H†÷  ‚‚ü0‚ø0‚ô *†H†÷   ‚þ0‚ú0 *†H†÷  0PÓ:ÙD’ЂØ9—Ëÿ)ÝùwÆ®g;b ­B_Š4Æ·Õuº­"¯³þwÛëKbEá†KªþÚ€ ˜ÆcX&Hl>A0;ÐÃß{aú2v«ŒLÜáÞÆOçðl­»¡‡ Ì7¢V/]ÀÂóa Fçùð¤¦÷Nx4÷ïÓTÀ-nÈÉ`‚PEu6‰;=…Ÿ¯Cµ&³¸Ø ·öÏ–Þ-ºÇêIÇy┹ˆ!–—ĤGϲ°'ɵ¤¥AàÍ XQ€2Qïû²žšëFRÈêÉNü†_jà-?@hç'ð­üö‰”‚y®UH e¬íÕn®HþV©¾ßŠ‚Ë%ó§}:´ƒsñŠ­Ñy€Á%eêPjå‘¡_«eòÂÐs)P´ê·Ã‡&V¬‡KåP;ù§0Ö‰`ñH:—£àv7Üp+îŸì™«ÚÝñFÁ¥§ÐͦxßÉY嫈îf~$`fÌZlr¢.ìì«sžÌQ1úÇ“ àvã ¿6Úv .]Hc“ƒ·ùÛ4ÍÓ¿¶‘;Š˜í}•¼á·éw^õ¤wŸïë)­U⋉f.ž] $=Gr)da‘]ž`iº ¥Œú¢ìnû·œ?õa²æ`×—ýZ HOÒ«Øžå‹ê&lI‘øý2ÓøùJÓt÷;xHµP±‰–Rzüžƒ×# 騲í ]ÓRÍøÞÓëGdšñ=Gì“®ºW@J¡šäÅGSƒì‘G³:øº±}ß¶KMÕÎmÚ|(µ§U&HôáãÙç–“FzÿÅ¿6xÞ>y²°£:»Ë®Ã¤…L>C8obó×û gx,‘P~³h~®†ÅÀ¥³i~tÅ$ªaøNÌtÛ"„4¾”Û¥ŽˆÔjÿ_Ô1ø˜ òBwd^RѸ׆ä^jö:ue.Ë®wȤv ø8ÒÆ/°ö1o{ÉicÂ/›|ÜbZ'ÛŽ®ù*FëfÜÇ0÷¯5¡$,¿™¾U ¦J(‹ \`[l¶=]$2‡ƒOl`H p`|fxèU9«Gxw÷oÕ±´»ðU,çŽ$·ôDü±“Ngb‚‹Ï];­,bæš}+„Ý7`æ`rlײlë¾5&™xÇ|•Šà€1>Ú{Z\N¤¬ i¸ÇÔ„ÍëT>Ñ×aeÊÙ¼óqEÂÐ-sB^'Ôˆ:Ö_dÒ^!gâŒæºúš*‰6g¼Å)»(šéE⽓÷»5“xÔ…ï·2ÊJL¢‘†Ðª¥²*¬¨ºït¨»M•ÒU9ÞÈGB™ø¤Ò¨Ù l+÷@í™Ór@äéÂÉÅ)¶5_îòAh Æ€òS:“ õûú¯z[:#&·aY<ñ ü\›ƒ,„ÆIøŠŽ%ÐXŒ4#¼Ã­óMŸ ‚¥•ý (£©1“]7;ªF¦È9òË÷:6 ¡}QÚšî¸ÓrˆÉ=ŽÚsê&imVôðÅ7öÂøR7ª)ÁR¥5Í6V ÈF§êoà{Ñ"¼É!ëóêôÜÏ£W6¶sÿÇû@œ+·Òé®;-Pa-¦„õrÅX>StVSÌ€ça¾xÃÍ¡›_6«.gpÇr:¯Ù¨Z&½‹±A—püµw@’XÓqþ?1â0  +‚710 *†H†÷  10] *†H†÷  1PNte-017de0ac-82d9-4478-8b4f-a6370451f3bf0] +‚71PNMicrosoft Software Key Storage Provider0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0ˆvŒ¸Þ´]Ѐ‚¨¯×¤Wc!ûÁ¨¶i›}˜%bHö æ û”Ñ—·ÑòåhR‘€-íÞx¦0j¼q ¯ç!§)$³Þº~¸Ž=Ø; E×;÷}É' Áº¯‚šü+ÇR°?tºåõ‹€ÃýÅf¯RmF@œ"x†<¯·ýùÓ÷¸JQ¥Ý-À¨ö¨æ# ’ÜÉ]©‹ƒÐ2L5«F³cxwHépÿõÝúd ‘çóدá\ƒ{Wp:eÇr#ƒû8Ï¿ð9†øPäpÂQQek Ì ")$)NúûuV!°"ð8ûƒeÈŒ»K @5ª«µ¤”¹„0Ì‚r?dͺ‡]:ŽV?n¶åØ+¦­cꈯÓD›À‚Vª8·T!:7üªG(}]T+j`ê’¼È?WV´C­À’=µþtH'Àðv%eöˆ£¢#éæy{JÆ}Ž&¯åë<´˜U§=Ej³@C×ïÚ©L ÝuiÜ"‘HÎqèZG3B"J~À?Ì.øæ@øcÈ…WàÍ8lä9­¿µF«¸ˆ±¬…’9gòðgKÁ8xÝû{½yñ^GdŒ@Ê=ʉL\äô´Ýw%C¦øúö¢©Ý"ɽ¡a¨™²Fx 7<;elÂNiîìtåÔP¢²·ö{ºí]ÜòSò½jµÄeÚ01 hææÊ—d=Ř@+³µCÈ…GF=µ#ä8…‡iï6™Ÿ¼ƒ_Ôè'™j®à¯-÷ ý\éñ@L„0¼@`,¹’+ —ǵÏl‚ÚilÕ(Ï'öïùѿڛj8—î0sµ^¨µ0fÃ×}VX‘>Oº/] ûŒÓ´¤eŠ=È|Ÿ$0˜ëƒ~&õMqôI‚†:ãþÖ®%òÁúµÍwùßZ –GióÆìÃŒ-u± Õ…'·èâ)#”H"±%å‚Rµ…s„vÙé!í)r3m†'ºç•Änc† 6•fœÿ}U+Obˆë}Áw­BDÿrú³\÷~ÅÁL#nÚõÖŠöªÚ蕎‘xnÞ\fYZ÷»7Òbh@X*øÚʃšˆéF›V4a$Û«\M3Yd0ÕÙÝuj•~ð„Úfi$ñs”lÒà û|]H=±õØ.½y@<¢|ã’ÌÓnÌ^þÒŽ¦tÃݧ,ƒW­'p-T‰×h9â·\Ö¸jd~SiÑÒIëØßÞdÕÑLbfÀîbzú÷‘V~FFl L90;00++á7×î…ìI–Äî¹%-j3á^?¬8›]ð9 3«Ý޹Ðthrift-0.23.0/tutorial/netstd/Client/Client.csproj0000664000175000017500000000340415170007142022376 0ustar00buildbuild00000000000000 net10.0 latestMajor Client Client Exe 0.23.0.0 enable false false false false thrift-0.23.0/tutorial/netstd/build.cmd0000664000175000017500000000164115165535636020327 0ustar00buildbuild00000000000000@echo off rem /* rem * Licensed to the Apache Software Foundation (ASF) under one rem * or more contributor license agreements. See the NOTICE file rem * distributed with this work for additional information rem * regarding copyright ownership. The ASF licenses this file rem * to you under the Apache License, Version 2.0 (the rem * "License"); you may not use this file except in compliance rem * with the License. You may obtain a copy of the License at rem * rem * http://www.apache.org/licenses/LICENSE-2.0 rem * rem * Unless required by applicable law or agreed to in writing, rem * software distributed under the License is distributed on an rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY rem * KIND, either express or implied. See the License for the rem * specific language governing permissions and limitations rem * under the License. rem */ setlocal dotnet --info dotnet build :eof thrift-0.23.0/tutorial/netstd/build.sh0000775000175000017500000000154515165535636020204 0ustar00buildbuild00000000000000#!/usr/bin/env bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #exit if any command fails set -e dotnet --info dotnet build thrift-0.23.0/tutorial/netstd/Server/0000775000175000017500000000000015170007142017765 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/netstd/Server/Properties/0000775000175000017500000000000015165535636022143 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/netstd/Server/Properties/AssemblyInfo.cs0000664000175000017500000000326115165535636025067 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("Thrift")] [assembly: AssemblyCopyright("The Apache Software Foundation")] [assembly: AssemblyTrademark("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e210fc10-5aff-4b04-ac21-58afc7b74b0c")]thrift-0.23.0/tutorial/netstd/Server/Server.csproj0000664000175000017500000000352415170007142022461 0ustar00buildbuild00000000000000 net10.0 latestMajor Server Server Exe 0.23.0.0 enable false false false false 7.0.9 thrift-0.23.0/tutorial/netstd/Server/Program.cs0000664000175000017500000004252515167543515021752 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using shared; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; using Thrift; using Thrift.Processor; using Thrift.Protocol; using Thrift.Server; using Thrift.Transport; using Thrift.Transport.Server; using tutorial; #pragma warning disable IDE0057 // substr namespace Server { public static class LoggingHelper { public static ILoggerFactory LogFactory { get; } = LoggerFactory.Create(builder => { ConfigureLogging(builder); }); public static void ConfigureLogging(ILoggingBuilder logging) { logging.SetMinimumLevel(LogLevel.Trace); logging.AddConsole(); logging.AddDebug(); } public static ILogger CreateLogger() => LogFactory.CreateLogger(); } public class Program { private static readonly ILogger Logger = LoggingHelper.CreateLogger(); private static readonly TConfiguration Configuration = new(); public static async Task Main(string[] args) { args ??= []; // -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(); await RunAsync(args, source.Token); Logger.LogInformation("Press any key to stop..."); Console.ReadLine(); source.Cancel(); Logger.LogInformation("Server stopped"); } private static void DisplayHelp() { Logger.LogInformation(@" Usage: Server -help will diplay help information Server -tr: -bf: -pr: [-multiplex] will run server with specified arguments (tcp transport, no buffering, and binary protocol by default) Options: -tr (transport): tcp - (default) tcp transport (localhost:9090) tcptls - tcp transport with tls (localhost:9090) namedpipe - namedpipe transport (pipe "".test"") http - http transport (localhost:9090) -bf (buffering): none - (default) no buffering buffered - buffered transport framed - framed transport -pr (protocol): binary - (default) binary protocol compact - compact protocol json - json protocol -multiplex - adds multiplexed protocol Sample: Server -tr:tcp "); } private static async Task RunAsync(string[] args, CancellationToken cancellationToken) { var selectedTransport = GetTransport(args); var selectedBuffering = GetBuffering(args); var selectedProtocol = GetProtocol(args); var multiplex = GetMultiplex(args); if (selectedTransport == Transport.Http) { if (multiplex) throw new Exception("This tutorial sample code does not yet allow multiplex over http (although Thrift itself of course does)"); new HttpServerSample().Run(cancellationToken); } else { await RunSelectedConfigurationAsync(selectedTransport, selectedBuffering, selectedProtocol, multiplex, cancellationToken); } } private static bool GetMultiplex(string[] args) { var mplex = args.FirstOrDefault(x => x.StartsWith("-multiplex")); return !string.IsNullOrEmpty(mplex); } private static Protocol GetProtocol(string[] args) { var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(protocol)) return Protocol.Binary; protocol = protocol.Substring(0, 1).ToUpperInvariant() + protocol.Substring(1).ToLowerInvariant(); if (Enum.TryParse(protocol, true, out Protocol selectedProtocol)) return selectedProtocol; else return Protocol.Binary; } private static Buffering GetBuffering(string[] args) { var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(buffering)) return Buffering.None; buffering = buffering.Substring(0, 1).ToUpperInvariant() + buffering.Substring(1).ToLowerInvariant(); if( Enum.TryParse(buffering, out var selectedBuffering)) return selectedBuffering; else return Buffering.None; } private static Transport GetTransport(string[] args) { var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':').Skip(1).Take(1).FirstOrDefault(); if (string.IsNullOrEmpty(transport)) return Transport.Tcp; transport = transport.Substring(0, 1).ToUpperInvariant() + transport.Substring(1).ToLowerInvariant(); if( Enum.TryParse(transport, true, out Transport selectedTransport)) return selectedTransport; else return Transport.Tcp; } private static async Task RunSelectedConfigurationAsync(Transport transport, Buffering buffering, Protocol protocol, bool multiplex, CancellationToken cancellationToken) { TServerTransport serverTransport = transport switch { Transport.Tcp => new TServerSocketTransport(9090, Configuration), Transport.NamedPipe => new TNamedPipeServerTransport(".test", Configuration, NamedPipeServerFlags.None, 64), Transport.TcpTls => new TTlsServerSocketTransport(9090, Configuration, GetCertificate(), ClientCertValidator, LocalCertificateSelectionCallback), _ => throw new ArgumentException("unsupported value $transport", nameof(transport)), }; TTransportFactory? transportFactory = buffering switch { Buffering.Buffered => new TBufferedTransport.Factory(), Buffering.Framed => new TFramedTransport.Factory(), // layered transport(s) are optional Buffering.None => null, _ => throw new ArgumentException("unsupported value $buffering", nameof(buffering)), }; TProtocolFactory protocolFactory = protocol switch { Protocol.Binary => new TBinaryProtocol.Factory(), Protocol.Compact => new TCompactProtocol.Factory(), Protocol.Json => new TJsonProtocol.Factory(), _ => throw new ArgumentException("unsupported value $protocol", nameof(protocol)), }; var handler = new CalculatorAsyncHandler(); ITAsyncProcessor processor = new Calculator.AsyncProcessor(handler); if (multiplex) { var multiplexedProcessor = new TMultiplexedProcessor(); multiplexedProcessor.RegisterProcessor(nameof(Calculator), processor); processor = multiplexedProcessor; } try { if( Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation( "TSimpleAsyncServer with \n{transport} transport\n{buffering} buffering\nmultiplex = {multiplex}\n{protocol} protocol", transport, buffering, multiplex ? "yes" : "no", protocol ); var server = new TSimpleAsyncServer( itProcessorFactory: new TSingletonProcessorFactory(processor), serverTransport: serverTransport, inputTransportFactory: transportFactory, outputTransportFactory: transportFactory, inputProtocolFactory: protocolFactory, outputProtocolFactory: protocolFactory, logger: LoggingHelper.CreateLogger()); Logger.LogInformation("Starting the server..."); await server.ServeAsync(cancellationToken); } catch (Exception x) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("{x}",x); } } 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 X509CertificateLoader.LoadPkcs12FromFile(certFile, "ThriftTest"); } private static string GetCertPath(DirectoryInfo? di, int maxCount = 6) { var topDir = di; var certFile = topDir?.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories).FirstOrDefault(); if (certFile == null) { if (maxCount == 0) throw new FileNotFoundException("Cannot find file in directories"); return GetCertPath(di?.Parent, --maxCount); } return certFile.FullName; } private static X509Certificate2 LocalCertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate? remoteCertificate, string[] acceptableIssuers) { return GetCertificate(); } private static bool ClientCertValidator(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) { return true; } private enum Transport { Tcp, NamedPipe, Http, TcpTls, } private enum Buffering { None, Buffered, Framed, } private enum Protocol { Binary, Compact, Json, } public class HttpServerSample { public void Run(CancellationToken cancellationToken) { var config = new ConfigurationBuilder() .AddEnvironmentVariables(prefix: "ASPNETCORE_") .Build(); var host = new HostBuilder(). ConfigureWebHost(webhostbuilder => { webhostbuilder.UseConfiguration(config) .UseUrls("http://localhost:9090") .UseContentRoot(Directory.GetCurrentDirectory()) .UseStartup() .UseKestrel() .ConfigureLogging((ctx, logging) => LoggingHelper.ConfigureLogging(logging)) ; }) .Build(); Logger.LogTrace("test"); Logger.LogCritical("test"); host.RunAsync(cancellationToken).GetAwaiter().GetResult(); } public class Startup { public Startup(IWebHostEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfigurationRoot Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // NOTE: this is not really the recommended way to do it // because the HTTP server cannot be configured properly to e.g. accept framed or multiplex services.AddTransient(); services.AddTransient(); services.AddTransient(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { _ = env; _ = loggerFactory; app.UseMiddleware(); } } } public class CalculatorAsyncHandler : Calculator.IAsync { private readonly Dictionary _log = []; public CalculatorAsyncHandler() { } public async Task getStruct(int key, CancellationToken cancellationToken) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("GetStruct({key})", key); return _log[key]; } public async Task ping(CancellationToken cancellationToken) { Logger.LogInformation("Ping()"); } public async Task add(int num1, int num2, CancellationToken cancellationToken) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("Add({num1},{num2})", num1, num2); return num1 + num2; } public async Task calculate(int logid, Work? w, CancellationToken cancellationToken) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("Calculate({logid}, [{w.Op},{w.Num1},{w.Num2}])", logid, w?.Op, w?.Num1, w?.Num2); int val; switch (w?.Op) { case Operation.ADD: val = w.Num1 + w.Num2; break; case Operation.SUBTRACT: val = w.Num1 - w.Num2; break; case Operation.MULTIPLY: val = w.Num1 * w.Num2; break; case Operation.DIVIDE: if (w.Num2 == 0) { var io = new InvalidOperation { WhatOp = (int) w.Op, Why = "Cannot divide by 0" }; throw io; } val = w.Num1 / w.Num2; break; default: { var io = new InvalidOperation { WhatOp = ((int?)w?.Op) ?? -1, Why = "Unknown operation" }; throw io; } } var entry = new SharedStruct { Key = logid, Value = val.ToString() }; _log[logid] = entry; return val; } public async Task zip(CancellationToken cancellationToken) { Logger.LogInformation("Zip() with delay 100mc"); await Task.Delay(100, CancellationToken.None); } } public class SharedServiceAsyncHandler : SharedService.IAsync { public async Task getStruct(int key, CancellationToken cancellationToken) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformation("GetStruct({key})", key); return new SharedStruct() { Key = key, Value = "GetStruct" }; } } } } thrift-0.23.0/tutorial/netstd/Server/ThriftTest.pfx0000664000175000017500000000514515165535636022633 0ustar00buildbuild000000000000000‚ a0‚  *†H†÷  ‚ ‚ 0‚ 0‚ *†H†÷  ‚‚ü0‚ø0‚ô *†H†÷   ‚þ0‚ú0 *†H†÷  0PÓ:ÙD’ЂØ9—Ëÿ)ÝùwÆ®g;b ­B_Š4Æ·Õuº­"¯³þwÛëKbEá†KªþÚ€ ˜ÆcX&Hl>A0;ÐÃß{aú2v«ŒLÜáÞÆOçðl­»¡‡ Ì7¢V/]ÀÂóa Fçùð¤¦÷Nx4÷ïÓTÀ-nÈÉ`‚PEu6‰;=…Ÿ¯Cµ&³¸Ø ·öÏ–Þ-ºÇêIÇy┹ˆ!–—ĤGϲ°'ɵ¤¥AàÍ XQ€2Qïû²žšëFRÈêÉNü†_jà-?@hç'ð­üö‰”‚y®UH e¬íÕn®HþV©¾ßŠ‚Ë%ó§}:´ƒsñŠ­Ñy€Á%eêPjå‘¡_«eòÂÐs)P´ê·Ã‡&V¬‡KåP;ù§0Ö‰`ñH:—£àv7Üp+îŸì™«ÚÝñFÁ¥§ÐͦxßÉY嫈îf~$`fÌZlr¢.ìì«sžÌQ1úÇ“ àvã ¿6Úv .]Hc“ƒ·ùÛ4ÍÓ¿¶‘;Š˜í}•¼á·éw^õ¤wŸïë)­U⋉f.ž] $=Gr)da‘]ž`iº ¥Œú¢ìnû·œ?õa²æ`×—ýZ HOÒ«Øžå‹ê&lI‘øý2ÓøùJÓt÷;xHµP±‰–Rzüžƒ×# 騲í ]ÓRÍøÞÓëGdšñ=Gì“®ºW@J¡šäÅGSƒì‘G³:øº±}ß¶KMÕÎmÚ|(µ§U&HôáãÙç–“FzÿÅ¿6xÞ>y²°£:»Ë®Ã¤…L>C8obó×û gx,‘P~³h~®†ÅÀ¥³i~tÅ$ªaøNÌtÛ"„4¾”Û¥ŽˆÔjÿ_Ô1ø˜ òBwd^RѸ׆ä^jö:ue.Ë®wȤv ø8ÒÆ/°ö1o{ÉicÂ/›|ÜbZ'ÛŽ®ù*FëfÜÇ0÷¯5¡$,¿™¾U ¦J(‹ \`[l¶=]$2‡ƒOl`H p`|fxèU9«Gxw÷oÕ±´»ðU,çŽ$·ôDü±“Ngb‚‹Ï];­,bæš}+„Ý7`æ`rlײlë¾5&™xÇ|•Šà€1>Ú{Z\N¤¬ i¸ÇÔ„ÍëT>Ñ×aeÊÙ¼óqEÂÐ-sB^'Ôˆ:Ö_dÒ^!gâŒæºúš*‰6g¼Å)»(šéE⽓÷»5“xÔ…ï·2ÊJL¢‘†Ðª¥²*¬¨ºït¨»M•ÒU9ÞÈGB™ø¤Ò¨Ù l+÷@í™Ór@äéÂÉÅ)¶5_îòAh Æ€òS:“ õûú¯z[:#&·aY<ñ ü\›ƒ,„ÆIøŠŽ%ÐXŒ4#¼Ã­óMŸ ‚¥•ý (£©1“]7;ªF¦È9òË÷:6 ¡}QÚšî¸ÓrˆÉ=ŽÚsê&imVôðÅ7öÂøR7ª)ÁR¥5Í6V ÈF§êoà{Ñ"¼É!ëóêôÜÏ£W6¶sÿÇû@œ+·Òé®;-Pa-¦„õrÅX>StVSÌ€ça¾xÃÍ¡›_6«.gpÇr:¯Ù¨Z&½‹±A—püµw@’XÓqþ?1â0  +‚710 *†H†÷  10] *†H†÷  1PNte-017de0ac-82d9-4478-8b4f-a6370451f3bf0] +‚71PNMicrosoft Software Key Storage Provider0‚ï *†H†÷  ‚à0‚Ü0‚Õ *†H†÷ 0 *†H†÷  0ˆvŒ¸Þ´]Ѐ‚¨¯×¤Wc!ûÁ¨¶i›}˜%bHö æ û”Ñ—·ÑòåhR‘€-íÞx¦0j¼q ¯ç!§)$³Þº~¸Ž=Ø; E×;÷}É' Áº¯‚šü+ÇR°?tºåõ‹€ÃýÅf¯RmF@œ"x†<¯·ýùÓ÷¸JQ¥Ý-À¨ö¨æ# ’ÜÉ]©‹ƒÐ2L5«F³cxwHépÿõÝúd ‘çóدá\ƒ{Wp:eÇr#ƒû8Ï¿ð9†øPäpÂQQek Ì ")$)NúûuV!°"ð8ûƒeÈŒ»K @5ª«µ¤”¹„0Ì‚r?dͺ‡]:ŽV?n¶åØ+¦­cꈯÓD›À‚Vª8·T!:7üªG(}]T+j`ê’¼È?WV´C­À’=µþtH'Àðv%eöˆ£¢#éæy{JÆ}Ž&¯åë<´˜U§=Ej³@C×ïÚ©L ÝuiÜ"‘HÎqèZG3B"J~À?Ì.øæ@øcÈ…WàÍ8lä9­¿µF«¸ˆ±¬…’9gòðgKÁ8xÝû{½yñ^GdŒ@Ê=ʉL\äô´Ýw%C¦øúö¢©Ý"ɽ¡a¨™²Fx 7<;elÂNiîìtåÔP¢²·ö{ºí]ÜòSò½jµÄeÚ01 hææÊ—d=Ř@+³µCÈ…GF=µ#ä8…‡iï6™Ÿ¼ƒ_Ôè'™j®à¯-÷ ý\éñ@L„0¼@`,¹’+ —ǵÏl‚ÚilÕ(Ï'öïùѿڛj8—î0sµ^¨µ0fÃ×}VX‘>Oº/] ûŒÓ´¤eŠ=È|Ÿ$0˜ëƒ~&õMqôI‚†:ãþÖ®%òÁúµÍwùßZ –GióÆìÃŒ-u± Õ…'·èâ)#”H"±%å‚Rµ…s„vÙé!í)r3m†'ºç•Änc† 6•fœÿ}U+Obˆë}Áw­BDÿrú³\÷~ÅÁL#nÚõÖŠöªÚ蕎‘xnÞ\fYZ÷»7Òbh@X*øÚʃšˆéF›V4a$Û«\M3Yd0ÕÙÝuj•~ð„Úfi$ñs”lÒà û|]H=±õØ.½y@<¢|ã’ÌÓnÌ^þÒŽ¦tÃݧ,ƒW­'p-T‰×h9â·\Ö¸jd~SiÑÒIëØßÞdÕÑLbfÀîbzú÷‘V~FFl L90;00++á7×î…ìI–Äî¹%-j3á^?¬8›]ð9 3«Ý޹Ðthrift-0.23.0/tutorial/netstd/README.md0000664000175000017500000002022715165535636020023 0ustar00buildbuild00000000000000# Building of samples for different platforms # Requirements - NET Core Standard 3.1 (LTS) runtime or SDK (see below for further info) # How to build - Download and install the latest .NET Core SDK for your platform https://dotnet.microsoft.com/download/dotnet-core - Ensure that you have thrift.exe which supports netstd lib and it added to PATH - Go to current folder - Run **build.sh** or **build.cmd** from the root of cloned repository - Check tests in **src/Tests** folder - Continue with /tutorials/netstd # How to run Depending on the platform, the name of the generated executables will vary. On Linux, it is just "Client" or "Server", on Windows it is "Client.exe" and "Server.exe". In the following, we use the abbreviated form "Client" and "Server". - build - go to folder (Client/Server) - run the generated executables: server first, then client from a second console # Known issues - In trace logging mode you can see some not important internal exceptions # Running of samples On machines that do not have the SDK installed, you need to install the NET Core runtime first. The SDK is only needed to build programs, otherwise the runtime is sufficient. # NetCore Server Usage: Server -help will diplay help information Server -tr: -pr: will run server with specified arguments (tcp transport and binary protocol by default) Options: -tr (transport): tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090) namedpipe - namedpipe transport will be used (pipe address - "".test"") http - http transport will be used (http address - ""localhost:9090"") tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090) -bf (buffering): none - (default) no transport factory will be used buffered - buffered transport factory will be used framed - framed transport factory will be used (this must match the client) -pr (protocol): binary - (default) binary protocol will be used compact - compact protocol will be used json - json protocol will be used multiplexed - multiplexed protocol will be used Sample: Server -tr:tcp **Remarks**: For TcpTls mode certificate's file ThriftTest.pfx should be in directory with binaries in case of command line usage (or at project level in case of debugging from IDE). Password for certificate - "ThriftTest". # NetCore Client Usage: Client -help will diplay help information Client -tr: -pr: -mc: will run client with specified arguments (tcp transport and binary protocol by default) Options: -tr (transport): tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090) namedpipe - namedpipe transport will be used (pipe address - "".test"") http - http transport will be used (address - ""http://localhost:9090"") tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090) -bf (buffering): none - (default) no transport factory will be used buffered - buffered transport factory will be used framed - framed transport factory will be used (this must match the client) -pr (protocol): binary - (default) binary protocol will be used compact - compact protocol will be used json - json protocol will be used multiplexed - multiplexed protocol will be used -mc (multiple clients): - number of multiple clients to connect to server (max 100, default 1) Sample: Client -tr:tcp -pr:binary -mc:10 Remarks: For TcpTls mode certificate's file ThriftTest.pfx should be in directory with binaries in case of command line usage (or at project level in case of debugging from IDE). Password for certificate - "ThriftTest". # How to test communication between NetCore and Python * Generate code with the latest **thrift** utility * Ensure that **thrift** generated folder **gen-py** with generated code for Python exists * Create **client.py** and **server.py** from the code examples below and save them to the folder with previosly generated folder **gen-py** * Run netstd samples (client and server) and python samples (client and server) Remarks: Samples of client and server code below use correct methods (operations) and fields (properties) according to generated contracts from *.thrift files At Windows 10 add record **127.0.0.1 testserver** to **C:\Windows\System32\drivers\etc\hosts** file for correct work of python server **Python Client:** ```python import sys import glob sys.path.append('gen-py') from tutorial import Calculator from tutorial.ttypes import InvalidOperation, Operation, Work from thrift import Thrift from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol def main(): # Make socket transport = TSocket.TSocket('127.0.0.1', 9090) # Buffering is critical. Raw sockets are very slow transport = TTransport.TBufferedTransport(transport) # Wrap in a protocol protocol = TBinaryProtocol.TBinaryProtocol(transport) # Create a client to use the protocol encoder client = Calculator.Client(protocol) # Connect! transport.open() client.Ping() print('ping()') sum = client.Add(1, 1) print(('1+1=%d' % (sum))) work = Work() work.Op = Operation.Divide work.Num1 = 1 work.Num2 = 0 try: quotient = client.Calculate(1, work) print('Whoa? You know how to divide by zero?') print('FYI the answer is %d' % quotient) except InvalidOperation as e: print(('InvalidOperation: %r' % e)) work.Op = Operation.Substract work.Num1 = 15 work.Num2 = 10 diff = client.Calculate(1, work) print(('15-10=%d' % (diff))) log = client.GetStruct(1) print(('Check log: %s' % (log.Value))) client.Zip() print('zip()') # Close! transport.close() if __name__ == '__main__': try: main() except Thrift.TException as tx: print('%s' % tx.message) ``` **Python Server:** ```python import glob import sys sys.path.append('gen-py') from tutorial import Calculator from tutorial.ttypes import InvalidOperation, Operation from shared.ttypes import SharedStruct from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.server import TServer class CalculatorHandler: def __init__(self): self.log = {} def Ping(self): print('ping()') def Add(self, n1, n2): print('add(%d,%d)' % (n1, n2)) return n1 + n2 def Calculate(self, logid, work): print('calculate(%d, %r)' % (logid, work)) if work.Op == Operation.Add: val = work.Num1 + work.Num2 elif work.Op == Operation.Substract: val = work.Num1 - work.Num2 elif work.Op == Operation.Multiply: val = work.Num1 * work.Num2 elif work.Op == Operation.Divide: if work.Num2 == 0: raise InvalidOperation(work.Op, 'Cannot divide by 0') val = work.Num1 / work.Num2 else: raise InvalidOperation(work.Op, 'Invalid operation') log = SharedStruct() log.Key = logid log.Value = '%d' % (val) self.log[logid] = log return val def GetStruct(self, key): print('getStruct(%d)' % (key)) return self.log[key] def Zip(self): print('zip()') if __name__ == '__main__': handler = CalculatorHandler() processor = Calculator.Processor(handler) transport = TSocket.TServerSocket(host="testserver", port=9090) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) print('Starting the server...') server.serve() print('done.') # You could do one of these for a multithreaded server # server = TServer.TThreadedServer(processor, transport, tfactory, pfactory) # server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) ``` thrift-0.23.0/tutorial/netstd/Makefile.in0000644000175000017500000005746215170007167020607 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/netstd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . EXTRA_DIST = \ Client \ Interfaces \ README.md \ Server \ Tutorial.sln \ build.cmd \ build.sh all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/netstd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/netstd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile all-local: $(DOTNETCORE) build -c Release clean-local: $(RM) Interfaces.dll $(RM) -r Client/bin $(RM) -r Client/obj $(RM) -r Server/bin $(RM) -r Server/obj $(RM) -r Interfaces/bin $(RM) -r Interfaces/obj distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/netstd/Makefile.am0000664000175000017500000000221615165535636020576 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . all-local: $(DOTNETCORE) build -c Release clean-local: $(RM) Interfaces.dll $(RM) -r Client/bin $(RM) -r Client/obj $(RM) -r Server/bin $(RM) -r Server/obj $(RM) -r Interfaces/bin $(RM) -r Interfaces/obj distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ Client \ Interfaces \ README.md \ Server \ Tutorial.sln \ build.cmd \ build.sh thrift-0.23.0/tutorial/netstd/Interfaces/0000775000175000017500000000000015170007142020602 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/netstd/Interfaces/GlobalSuppressions.cs0000664000175000017500000000240515165535636025012 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // This file is used by Code Analysis to maintain SuppressMessage // attributes that are applied to this project. // Project-level suppressions either have no target or are given // a specific target and scoped to a namespace, type, member, etc. using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("Performance", "CA1822", Justification = "", Scope = "module")] [assembly: SuppressMessage("Style", "IDE0083", Justification = "", Scope = "module")] thrift-0.23.0/tutorial/netstd/Interfaces/Properties/0000775000175000017500000000000015165535636022760 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs0000664000175000017500000000326115165535636025704 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("Thrift")] [assembly: AssemblyCopyright("The Apache Software Foundation")] [assembly: AssemblyTrademark("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("4d13163d-9067-4c9c-8af0-64e08451397d")]thrift-0.23.0/tutorial/netstd/Interfaces/Interfaces.csproj0000664000175000017500000000456715170007142024123 0ustar00buildbuild00000000000000 net10.0 Interfaces Interfaces 0.23.0.0 enable false false false false thrift-0.23.0/tutorial/nodejs/0000755000175000017500000000000015170007202016473 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/nodejs/NodeClientPromise.js0000664000175000017500000000416215165535636022446 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var 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, }); 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.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?"); }) .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); }) .then(function (message) { console.log("Check log: " + message.value); }) .finally(function () { //close the connection once we're done connection.end(); }); thrift-0.23.0/tutorial/nodejs/NodeServer.js0000664000175000017500000000455215165535636021142 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var thrift = require("thrift"); var Calculator = require("./gen-nodejs/Calculator"); var ttypes = require("./gen-nodejs/tutorial_types"); var SharedStruct = require("./gen-nodejs/shared_types").SharedStruct; var data = {}; var server = thrift.createServer(Calculator, { ping: function (result) { console.log("ping()"); result(null); }, add: function (n1, n2, result) { console.log("add(", n1, ",", n2, ")"); result(null, n1 + n2); }, calculate: function (logid, work, result) { console.log("calculate(", logid, ",", work, ")"); var val = 0; if (work.op == ttypes.Operation.ADD) { val = work.num1 + work.num2; } else if (work.op === ttypes.Operation.SUBTRACT) { val = work.num1 - work.num2; } else if (work.op === ttypes.Operation.MULTIPLY) { val = work.num1 * work.num2; } else if (work.op === ttypes.Operation.DIVIDE) { if (work.num2 === 0) { var x = new ttypes.InvalidOperation(); x.whatOp = work.op; x.why = "Cannot divide by 0"; result(x); return; } val = work.num1 / work.num2; } else { var x = new ttypes.InvalidOperation(); x.whatOp = work.op; x.why = "Invalid operation"; result(x); return; } var entry = new SharedStruct(); entry.key = logid; entry.value = "" + val; data[logid] = entry; result(null, val); }, getStruct: function (key, result) { console.log("getStruct(", key, ")"); result(null, data[key]); }, zip: function () { console.log("zip()"); }, }); server.listen(9090); thrift-0.23.0/tutorial/nodejs/NodeClient.js0000664000175000017500000000407715165535636021114 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var 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, }); 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.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) { if (err) { console.log("InvalidOperation " + err); } else { console.log("Whoa? You know how to divide by zero?"); } }); work.op = ttypes.Operation.SUBTRACT; work.num1 = 15; work.num2 = 10; client.calculate(1, work, function (err, message) { console.log("15-10=" + message); client.getStruct(1, function (err, message) { console.log("Check log: " + message.value); //close the connection once we're done connection.end(); }); }); thrift-0.23.0/tutorial/nodejs/NodeServerPromise.js0000664000175000017500000000440215165535636022473 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var thrift = require("thrift"); var Calculator = require("./gen-nodejs/Calculator"); var ttypes = require("./gen-nodejs/tutorial_types"); var SharedStruct = require("./gen-nodejs/shared_types").SharedStruct; var data = {}; var server = thrift.createServer(Calculator, { ping: function () { console.log("ping()"); }, add: function (n1, n2) { console.log("add(", n1, ",", n2, ")"); return n1 + n2; }, calculate: function (logid, work) { console.log("calculate(", logid, ",", work, ")"); var val = 0; if (work.op == ttypes.Operation.ADD) { val = work.num1 + work.num2; } else if (work.op === ttypes.Operation.SUBTRACT) { val = work.num1 - work.num2; } else if (work.op === ttypes.Operation.MULTIPLY) { val = work.num1 * work.num2; } else if (work.op === ttypes.Operation.DIVIDE) { if (work.num2 === 0) { var x = new ttypes.InvalidOperation(); x.whatOp = work.op; 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"; throw x; } var entry = new SharedStruct(); entry.key = logid; entry.value = "" + val; data[logid] = entry; return val; }, getStruct: function (key) { console.log("getStruct(", key, ")"); return data[key]; }, zip: function () { console.log("zip()"); }, }); server.listen(9090); thrift-0.23.0/tutorial/nodejs/Makefile.in0000644000175000017500000004407215170007167020561 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/nodejs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ NodeServer.js \ NodeClient.js \ NodeServerPromise.js \ NodeClientPromise.js all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/nodejs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/nodejs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-nodejs/Calculator.js gen-nodejs/SharedService.js: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen js:node -r $< all-local: gen-nodejs/Calculator.js tutorialserver: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeServer.js tutorialclient: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeClient.js tutorialserver_promise: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeServerPromise.js tutorialclient_promise: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeClientPromise.js clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/nodejs/Makefile.am0000664000175000017500000000317615165535636020565 0ustar00buildbuild00000000000000# # 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. # gen-nodejs/Calculator.js gen-nodejs/SharedService.js: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen js:node -r $< all-local: gen-nodejs/Calculator.js tutorialserver: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeServer.js tutorialclient: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeClient.js tutorialserver_promise: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeServerPromise.js tutorialclient_promise: all NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeClientPromise.js clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ NodeServer.js \ NodeClient.js \ NodeServerPromise.js \ NodeClientPromise.js thrift-0.23.0/tutorial/Makefile.in0000644000175000017500000006224415170007167017300 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ # do nothing, just build the compiler @MINGW_FALSE@@WITH_C_GLIB_TRUE@am__append_1 = c_glib @MINGW_FALSE@@WITH_CPP_TRUE@am__append_2 = cpp @MINGW_FALSE@@WITH_D_TRUE@am__append_3 = d @MINGW_FALSE@@WITH_JAVA_TRUE@am__append_4 = java js @MINGW_FALSE@@WITH_PYTHON_TRUE@am__append_5 = py py.twisted py.tornado @MINGW_FALSE@@WITH_RUBY_TRUE@am__append_6 = rb @MINGW_FALSE@@WITH_HAXE_TRUE@am__append_7 = haxe @MINGW_FALSE@@WITH_DOTNET_TRUE@am__append_8 = netstd @MINGW_FALSE@@WITH_GO_TRUE@am__append_9 = go @MINGW_FALSE@@WITH_NODEJS_TRUE@am__append_10 = nodejs @MINGW_FALSE@@WITH_DART_TRUE@am__append_11 = dart @MINGW_FALSE@@WITH_RS_TRUE@am__append_12 = rs @MINGW_FALSE@@WITH_CL_TRUE@am__append_13 = cl @MINGW_FALSE@@WITH_PERL_TRUE@am__append_14 = perl @MINGW_FALSE@@WITH_PHP_TRUE@am__append_15 = php @MINGW_FALSE@@WITH_SWIFT_TRUE@am__append_16 = swift subdir = tutorial ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = c_glib cpp d java js py py.twisted py.tornado rb haxe \ netstd go nodejs dart rs cl perl php swift am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) $(am__append_6) \ $(am__append_7) $(am__append_8) $(am__append_9) \ $(am__append_10) $(am__append_11) $(am__append_12) \ $(am__append_13) $(am__append_14) $(am__append_15) \ $(am__append_16) # 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 = \ d \ delphi \ erl \ ocaml \ shared.thrift \ tutorial.thrift \ README.md all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive @MINGW_TRUE@all-local: all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @MINGW_TRUE@clean-local: clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # # generate html for tutorial.thrift # @MINGW_FALSE@all-local: @MINGW_FALSE@ $(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/tutorial/tutorial.thrift @MINGW_FALSE@clean-local: @MINGW_FALSE@ rm -rf $(top_srcdir)/tutorial/gen-html distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/haxe/0000755000175000017500000000000015170007202016136 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/haxe/make_all.sh0000664000175000017500000000222215165535636020264 0ustar00buildbuild00000000000000#!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # invoke Thrift comnpiler thrift -r -gen haxe ../tutorial.thrift # output folder if [ ! -d bin ]; then mkdir bin fi # invoke Haxe compoiler for target in *.hxml; do echo -------------------------- echo Building ${target} ... echo -------------------------- if [ ! -d bin/${target} ]; then mkdir bin/${target} fi haxe --cwd . ${target} done #eof thrift-0.23.0/tutorial/haxe/Tutorial.hxproj0000664000175000017500000000374115165535636021231 0ustar00buildbuild00000000000000 thrift -r -gen haxe ../tutorial.thrift thrift-0.23.0/tutorial/haxe/cpp.hxml0000664000175000017500000000217515165535636017646 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp gen-haxe -cp ../../lib/haxe/src #this class wil be used as entry point for your app. -main Main #CPP target -cpp bin #To produce 64 bit binaries the file should define the HXCPP_M64 compile variable: #-D HXCPP_M64 # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/tutorial/haxe/src/0000775000175000017500000000000015165535636016754 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/haxe/src/Main.hx0000664000175000017500000002525415165535636020211 0ustar00buildbuild00000000000000/* * 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; import org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.server.*; import org.apache.thrift.meta_data.*; import tutorial.*; import shared.*; enum Prot { binary; json; compact; } enum Trns { socket; http; } class Main { private static var server : Bool = false; private static var framed : Bool = false; private static var buffered : Bool = false; private static var prot : Prot = binary; private static var trns : Trns = socket; private static var targetHost : String = "localhost"; private static var targetPort : Int = 9090; static function main() { #if ! (flash || js || phpwebserver) try { ParseArgs(); } catch (e : String) { trace(e); trace(GetHelp()); return; } #elseif phpwebserver //forcing server server = true; trns = http; initPhpWebServer(); //check method if(php.Web.getMethod() != 'POST') { Sys.println('http endpoint for thrift test server'); return; } #end try { if (server) RunServer(); else RunClient(); } catch (e : String) { trace(e); } trace("Completed."); } #if phpwebserver private static function initPhpWebServer() { //remap trace to error log haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { // handle trace var newValue : Dynamic; if (infos != null && infos.customParams!=null) { var extra:String = ""; for( v in infos.customParams ) extra += "," + v; newValue = v + extra; } else { newValue = v; } var msg = infos != null ? infos.fileName + ':' + infos.lineNumber + ': ' : ''; Sys.stderr().writeString('${msg}${newValue}\n'); } } #end #if ! (flash || js) private static function GetHelp() : String { return Sys.programPath+" modus layered transport protocol\n" +"Options:\n" +" modus: client, server (default: client)\n" +" layered: framed, buffered (default: none)\n" +" transport: socket, http (default: socket)\n" +" protocol: binary, json, compact (default: binary)\n" +"\n" +"All arguments are optional.\n"; } private static function ParseArgs() : Void { var step = 0; for (arg in Sys.args()) { // server|client switch(step) { case 0: ++step; if ( arg == "client") server = false; else if ( arg == "server") server = true; else throw "First argument must be 'server' or 'client'"; case 1: if ( arg == "framed") { framed = true; } else if ( arg == "buffered") { buffered = true; } else if ( arg == "socket") { trns = socket; ++step; } else if ( arg == "http") { trns = http; ++step; } else { throw "Unknown transport "+arg; } case 2: if ( arg == "binary") { prot = binary; ++step; } else if ( arg == "json") { prot = json; ++step; } else if ( arg == "compact") { prot = compact; ++step; } else { throw "Unknown protocol "+arg; } default: throw "Unexpected argument "+arg; } if ( framed && buffered) { trace("WN: framed supersedes buffered"); } } } #end private static function ClientSetup() : Calculator { trace("Client configuration:"); // endpoint transport var transport : TTransport; switch(trns) { case socket: trace('- socket transport $targetHost:$targetPort'); transport = new TSocket( targetHost, targetPort); case http: var uri = 'http://${targetHost}:${targetPort}'; trace('- HTTP transport $uri'); transport = new THttpClient(uri); default: throw "Unhandled transport"; } // optinal layered transport if ( framed) { trace("- framed transport"); transport = new TFramedTransport(transport); } else if ( buffered) { trace("- buffered transport"); transport = new TBufferedTransport(transport); } // protocol var protocol : TProtocol; switch(prot) { case binary: trace("- binary protocol"); protocol = new TBinaryProtocol( transport); case json: trace("- JSON protocol"); protocol = new TJSONProtocol( transport); case compact: trace("- compact protocol"); protocol = new TCompactProtocol( transport); default: throw "Unhandled protocol"; } // put everything together transport.open(); return new CalculatorImpl(protocol,protocol); } private static function RunClient() : Void { var client = ClientSetup(); try { client.ping(); trace("ping() successful"); } catch(error : TException) { trace('ping() failed: $error'); } catch(error : Dynamic) { trace('ping() failed: $error'); } try { var sum = client.add( 1, 1); trace('1+1=$sum'); } catch(error : TException) { trace('add() failed: $error'); } catch(error : Dynamic) { trace('add() failed: $error'); } var work = new tutorial.Work(); work.op = tutorial.Operation.DIVIDE; work.num1 = 1; work.num2 = 0; try { var quotient = client.calculate( 1, work); trace('Whoa we can divide by 0! Result = $quotient'); } catch(error : TException) { trace('calculate() failed: $error'); } catch(error : Dynamic) { trace('calculate() failed: $error'); } work.op = tutorial.Operation.SUBTRACT; work.num1 = 15; work.num2 = 10; try { var diff = client.calculate( 1, work); trace('15-10=$diff'); } catch(error : TException) { trace('calculate() failed: $error'); } catch(error : Dynamic) { trace('calculate() failed: $error'); } try { var log : SharedStruct = client.getStruct( 1); var logval = log.value; trace('Check log: $logval'); } catch(error : TException) { trace('getStruct() failed: $error'); } catch(error : Dynamic) { trace('getStruct() failed: $error'); } } private static function ServerSetup() : TServer { trace("Server configuration:"); // endpoint transport var transport : TServerTransport = null; switch(trns) { case socket: #if (flash || js) throw 'current platform does not support socket servers'; #else trace('- socket transport port $targetPort'); transport = new TServerSocket( targetPort); #end case http: #if !phpwebserver throw "HTTP server not implemented yet"; //trace("- http transport"); //transport = new THttpClient( targetHost); #else trace("- http transport"); transport = new TWrappingServerTransport( new TStreamTransport( new TFileStream("php://input", Read), new TFileStream("php://output", Append), null ) ); #end default: throw "Unhandled transport"; } // optional: layered transport var transfactory : TTransportFactory = null; if ( framed) { trace("- framed transport"); transfactory = new TFramedTransportFactory(); } else if ( buffered) { trace("- buffered transport"); transfactory = new TBufferedTransportFactory(); } // protocol var protfactory : TProtocolFactory = null; switch(prot) { case binary: trace("- binary protocol"); protfactory = new TBinaryProtocolFactory(); case json: trace("- JSON protocol"); protfactory = new TJSONProtocolFactory(); case compact: trace("- compact protocol"); protfactory = new TCompactProtocolFactory(); default: throw "Unhandled protocol"; } var handler : Calculator_service = new CalculatorHandler(); var processor = new CalculatorProcessor(handler); var server = new TSimpleServer( processor, transport, transfactory, protfactory); #if phpwebserver server.runOnce = true; #end return server; } private static function RunServer() : Void { try { var server = ServerSetup(); trace("\nStarting the server..."); server.Serve(); } catch( e : Dynamic) { trace('RunServer() failed: $e'); } trace("done."); } } thrift-0.23.0/tutorial/haxe/src/CalculatorHandler.hx0000664000175000017500000000537215165535636022713 0ustar00buildbuild00000000000000/* * 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; import haxe.ds.IntMap; import org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.server.*; import org.apache.thrift.meta_data.*; import tutorial.*; import shared.*; class CalculatorHandler implements Calculator_service { private var log = new IntMap(); public function new() { } public function ping() : Void { trace("ping()"); } public function add( num1 : haxe.Int32, num2 : haxe.Int32) : haxe.Int32 { trace('add( $num1, $num2)'); return num1 + num2; } public function calculate( logid : haxe.Int32, work : Work) : haxe.Int32 { trace('calculate( $logid, '+work.op+","+work.num1+","+work.num2+")"); var val : haxe.Int32 = 0; switch (work.op) { case Operation.ADD: val = work.num1 + work.num2; case Operation.SUBTRACT: val = work.num1 - work.num2; case Operation.MULTIPLY: val = work.num1 * work.num2; case Operation.DIVIDE: if (work.num2 == 0) { var io = new InvalidOperation(); io.whatOp = work.op; io.why = "Cannot divide by 0"; throw io; } val = Std.int( work.num1 / work.num2); default: var io = new InvalidOperation(); io.whatOp = work.op; io.why = "Unknown operation"; throw io; } var entry = new SharedStruct(); entry.key = logid; entry.value = '$val'; log.set(logid, entry); return val; } public function getStruct( key : haxe.Int32) : SharedStruct { trace('getStruct($key)'); return log.get(key); } // oneway method, no args public function zip() : Void { trace("zip()"); } } thrift-0.23.0/tutorial/haxe/php-web-server.hxml0000664000175000017500000000214215165535636021724 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp gen-haxe -cp ../../lib/haxe/src #this class wil be used as entry point for your app. -main Main #PHP target -php bin/php-web-server/ -D php-front=Main-debug.php #defines -D phpwebserver # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce full thrift-0.23.0/tutorial/haxe/flash.hxml0000664000175000017500000000215515165535636020157 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp gen-haxe -cp ../../lib/haxe/src #this class wil be used as entry point for your app. -main Main #Flash target -swf bin/Tutorial.swf # libs -lib uuid #Add debug information -debug # we need some goodies from sys.net # --macro allowPackage("sys") #dead code elimination : remove unused code -dce fullthrift-0.23.0/tutorial/haxe/javascript.hxml0000664000175000017500000000252115165535636021225 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp gen-haxe -cp ../../lib/haxe/src #this class wil be used as entry point for your app. -main Main #JavaScript target -js bin/Tutorial.js #You can use -D source-map-content (requires Haxe 3.1+) to have the .hx #files directly embedded into the map file, this way you only have to #upload it, and it will be always in sync with the compiled .js even if #you modify your .hx files. -D source-map-content # libs -lib uuid #Generate source map and add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/tutorial/haxe/python.hxml0000664000175000017500000000205515165535636020402 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp gen-haxe -cp ../../lib/haxe/src #this class wil be used as entry point for your app. -main Main #Python target -python bin/Tutorial.py # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/tutorial/haxe/project.hide0000664000175000017500000000522415165535636020471 0ustar00buildbuild00000000000000{ "type" : 0 ,"target" : 4 ,"name" : "Apache Thrift Tutorial" ,"main" : null ,"projectPackage" : "" ,"company" : "Apache Software Foundation (ASF)" ,"license" : "Apache License, Version 2.0" ,"url" : "http://www.apache.org/licenses/LICENSE-2.0" ,"targetData" : [ { "pathToHxml" : "flash.hxml" ,"runActionType" : 1 ,"runActionText" : "bin/Tutorial.swf" } ,{ "pathToHxml" : "javascript.hxml" ,"runActionType" : 1 ,"runActionText" : "bin\\index.html" } ,{ "pathToHxml" : "neko.hxml" ,"runActionType" : 2 ,"runActionText" : "neko bin/Tutorial.n" } ,{ "pathToHxml" : "php.hxml" } ,{ "pathToHxml" : "cpp.hxml" ,"runActionType" : 2 ,"runActionText" : "bin/Main-debug.exe" } ,{ "pathToHxml" : "java.hxml" } ,{ "pathToHxml" : "csharp.hxml" ,"runActionType" : 2 ,"runActionText" : "bin\\Tutorial.exe\\bin\\Main-Debug.exe" } ,{ "pathToHxml" : "python.hxml" ,"runActionType" : 2 ,"runActionText" : "python bin/Tutorial.py" } ] ,"files" : [ { "path" : "src\\org\\apache\\thrift\\server\\TServer.hx" ,"useTabs" : true ,"indentSize" : 4 ,"foldedRegions" : [ ] ,"activeLine" : 76 } ,{ "path" : "src\\org\\apache\\thrift\\server\\TSimpleServer.hx" ,"useTabs" : true ,"indentSize" : 4 ,"foldedRegions" : [ ] ,"activeLine" : 100 } ,{ "path" : "src\\shared\\SharedServiceProcessor.hx" ,"useTabs" : true ,"indentSize" : 4 ,"foldedRegions" : [ ] ,"activeLine" : 20 } ,{ "path" : "src\\tutorial\\CalculatorProcessor.hx" ,"useTabs" : true ,"indentSize" : 4 ,"foldedRegions" : [ ] ,"activeLine" : 79 } ,{ "path" : "src\\Main.hx" ,"useTabs" : true ,"indentSize" : 4 ,"foldedRegions" : [ ] ,"activeLine" : 0 } ] ,"activeFile" : "src\\Main.hx" ,"openFLTarget" : null ,"openFLBuildMode" : "Debug" ,"runActionType" : null ,"runActionText" : null ,"buildActionCommand" : null ,"hiddenItems" : [ ] ,"showHiddenItems" : false }thrift-0.23.0/tutorial/haxe/make_all.bat0000664000175000017500000000350515165535636020425 0ustar00buildbuild00000000000000@echo off rem /* rem * Licensed to the Apache Software Foundation (ASF) under one rem * or more contributor license agreements. See the NOTICE file rem * distributed with this work for additional information rem * regarding copyright ownership. The ASF licenses this file rem * to you under the Apache License, Version 2.0 (the rem * "License"); you may not use this file except in compliance rem * with the License. You may obtain a copy of the License at rem * rem * http://www.apache.org/licenses/LICENSE-2.0 rem * rem * Unless required by applicable law or agreed to in writing, rem * software distributed under the License is distributed on an rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY rem * KIND, either express or implied. See the License for the rem * specific language governing permissions and limitations rem * under the License. rem */ setlocal if "%HOMEDRIVE%"=="" goto MISSINGVARS if "%HOMEPATH%"=="" goto MISSINGVARS if "%HAXEPATH%"=="" goto NOTINSTALLED set path=%HAXEPATH%;%HAXEPATH%\..\neko;%path% rem # invoke Thrift comnpiler thrift -r -gen haxe ..\tutorial.thrift if errorlevel 1 goto STOP rem # invoke Haxe compiler for all targets for %%a in (*.hxml) do ( rem * filter Python, as it is not supported by Haxe 3.1.3 (but will be in 3.1.4) if not "%%a"=="python.hxml" ( echo -------------------------- echo Building %%a ... echo -------------------------- haxe --cwd . %%a ) ) echo. echo done. pause goto eof :NOTINSTALLED echo FATAL: Either Haxe is not installed, or the HAXEPATH variable is not set. pause goto eof :MISSINGVARS echo FATAL: Unable to locate home folder. echo. echo Both HOMEDRIVE and HOMEPATH need to be set to point to your Home folder. echo The current values are: echo HOMEDRIVE=%HOMEDRIVE% echo HOMEPATH=%HOMEPATH% pause goto eof :STOP pause goto eof :eof thrift-0.23.0/tutorial/haxe/router.php0000664000175000017500000000171415165535636020221 0ustar00buildbuild00000000000000&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/haxe ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ BIN_CPP = bin/Main-debug BIN_PHP = bin/php/Main-debug.php BIN_PHP_WEB = bin/php-web-server/Main-debug.php EXTRA_DIST = \ src \ cpp.hxml \ csharp.hxml \ flash.hxml \ java.hxml \ javascript.hxml \ php-web-server.hxml \ neko.hxml \ php.hxml \ python.hxml \ router.php \ project.hide \ Tutorial.hxproj \ make_all.bat \ make_all.sh all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/haxe/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/haxe/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-haxe/tutorial/calculator.hx gen-haxe/shared/shared_service.hx: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen haxe -r $< all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_PHP_WEB) check: gen-haxe/tutorial/calculator.hx $(BIN_CPP): \ src/*.hx \ ../../lib/haxe/src/org/apache/thrift/**/*.hx \ gen-haxe/tutorial/calculator.hx $(HAXE) --cwd . cpp.hxml $(BIN_PHP): \ src/*.hx \ ../../lib/haxe/src/org/apache/thrift/**/*.hx \ gen-haxe/tutorial/calculator.hx $(HAXE) --cwd . php.hxml $(BIN_PHP_WEB): \ src/*.hx \ ../../lib/haxe/src/org/apache/thrift/**/*.hx \ gen-haxe/tutorial/calculator.hx $(HAXE) --cwd . php-web-server.hxml tutorialserver: all $(BIN_CPP) server tutorialserver_php: all php -f $(BIN_PHP) server tutorialclient: all $(BIN_CPP) tutorialclient_php: all php -f $(BIN_PHP) tutorialsecureserver: all $(BIN_CPP) server secure tutorialsecureserver_php: all php -f $(BIN_PHP) server secure tutorialsecureclient: all $(BIN_CPP) secure tutorialsecureclient_php: all php -f $(BIN_PHP) secure tutorialserver_php_http: all php -S 127.0.0.1:9090 router.php tutorialclient_http: all $(BIN_CPP) client http clean-local: $(RM) -r gen-haxe bin distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/haxe/php.hxml0000664000175000017500000000207515165535636017652 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp gen-haxe -cp ../../lib/haxe/src #this class wil be used as entry point for your app. -main Main #PHP target -php bin/php/ -D php-front=Main-debug.php # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce full thrift-0.23.0/tutorial/haxe/Makefile.am0000664000175000017500000000450015165535636020220 0ustar00buildbuild00000000000000# # 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. # BIN_CPP = bin/Main-debug BIN_PHP = bin/php/Main-debug.php BIN_PHP_WEB = bin/php-web-server/Main-debug.php gen-haxe/tutorial/calculator.hx gen-haxe/shared/shared_service.hx: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen haxe -r $< all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_PHP_WEB) check: gen-haxe/tutorial/calculator.hx $(BIN_CPP): \ src/*.hx \ ../../lib/haxe/src/org/apache/thrift/**/*.hx \ gen-haxe/tutorial/calculator.hx $(HAXE) --cwd . cpp.hxml $(BIN_PHP): \ src/*.hx \ ../../lib/haxe/src/org/apache/thrift/**/*.hx \ gen-haxe/tutorial/calculator.hx $(HAXE) --cwd . php.hxml $(BIN_PHP_WEB): \ src/*.hx \ ../../lib/haxe/src/org/apache/thrift/**/*.hx \ gen-haxe/tutorial/calculator.hx $(HAXE) --cwd . php-web-server.hxml tutorialserver: all $(BIN_CPP) server tutorialserver_php: all php -f $(BIN_PHP) server tutorialclient: all $(BIN_CPP) tutorialclient_php: all php -f $(BIN_PHP) tutorialsecureserver: all $(BIN_CPP) server secure tutorialsecureserver_php: all php -f $(BIN_PHP) server secure tutorialsecureclient: all $(BIN_CPP) secure tutorialsecureclient_php: all php -f $(BIN_PHP) secure tutorialserver_php_http: all php -S 127.0.0.1:9090 router.php tutorialclient_http: all $(BIN_CPP) client http clean-local: $(RM) -r gen-haxe bin distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ src \ cpp.hxml \ csharp.hxml \ flash.hxml \ java.hxml \ javascript.hxml \ php-web-server.hxml \ neko.hxml \ php.hxml \ python.hxml \ router.php \ project.hide \ Tutorial.hxproj \ make_all.bat \ make_all.sh thrift-0.23.0/tutorial/cpp/0000755000175000017500000000000015170007202015773 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/cpp/CppClient.cpp0000664000175000017500000000465415165535636020420 0ustar00buildbuild00000000000000/* * 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 "../gen-cpp/Calculator.h" using namespace std; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace tutorial; using namespace shared; int main() { std::shared_ptr socket(new TSocket("localhost", 9090)); std::shared_ptr transport(new TBufferedTransport(socket)); std::shared_ptr protocol(new TBinaryProtocol(transport)); CalculatorClient client(protocol); try { transport->open(); client.ping(); cout << "ping()" << '\n'; cout << "1 + 1 = " << client.add(1, 1) << '\n'; Work work; work.op = Operation::DIVIDE; work.num1 = 1; work.num2 = 0; try { client.calculate(1, work); cout << "Whoa? We can divide by zero!" << '\n'; } catch (InvalidOperation& io) { 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 << '\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 << '\n'; transport->close(); } catch (TException& tx) { cout << "ERROR: " << tx.what() << '\n'; } } thrift-0.23.0/tutorial/cpp/CMakeLists.txt0000664000175000017500000000401115165535636020556 0ustar00buildbuild00000000000000# # 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(BoostMacros) REQUIRE_BOOST_HEADERS() #Make sure gen-cpp files can be included include_directories("${CMAKE_CURRENT_BINARY_DIR}") include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp") include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src") include(ThriftMacros) set(tutorialgencpp_SOURCES gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp ) add_library(tutorialgencpp STATIC ${tutorialgencpp_SOURCES}) target_link_libraries(tutorialgencpp thrift) add_custom_command(OUTPUT gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp COMMAND ${THRIFT_COMPILER} --gen cpp -r ${PROJECT_SOURCE_DIR}/tutorial/tutorial.thrift ) add_executable(TutorialServer CppServer.cpp) target_link_libraries(TutorialServer tutorialgencpp) target_link_libraries(TutorialServer thrift) if (ZLIB_FOUND) target_link_libraries(TutorialServer ${ZLIB_LIBRARIES}) endif () add_executable(TutorialClient CppClient.cpp) target_link_libraries(TutorialClient tutorialgencpp) target_link_libraries(TutorialClient thrift) if (ZLIB_FOUND) target_link_libraries(TutorialClient ${ZLIB_LIBRARIES}) endif () thrift-0.23.0/tutorial/cpp/Makefile.in0000644000175000017500000007215615170007167020065 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = TutorialServer$(EXEEXT) TutorialClient$(EXEEXT) subdir = tutorial/cpp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) libtutorialgencpp_la_DEPENDENCIES = \ $(top_builddir)/lib/cpp/libthrift.la am__dirstamp = $(am__leading_dot)dirstamp nodist_libtutorialgencpp_la_OBJECTS = gen-cpp/Calculator.lo \ gen-cpp/SharedService.lo gen-cpp/shared_types.lo \ gen-cpp/tutorial_constants.lo gen-cpp/tutorial_types.lo libtutorialgencpp_la_OBJECTS = $(nodist_libtutorialgencpp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_TutorialClient_OBJECTS = CppClient.$(OBJEXT) TutorialClient_OBJECTS = $(am_TutorialClient_OBJECTS) TutorialClient_DEPENDENCIES = libtutorialgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la am_TutorialServer_OBJECTS = CppServer.$(OBJEXT) TutorialServer_OBJECTS = $(am_TutorialServer_OBJECTS) TutorialServer_DEPENDENCIES = libtutorialgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/CppClient.Po \ ./$(DEPDIR)/CppServer.Po gen-cpp/$(DEPDIR)/Calculator.Plo \ gen-cpp/$(DEPDIR)/SharedService.Plo \ gen-cpp/$(DEPDIR)/shared_types.Plo \ gen-cpp/$(DEPDIR)/tutorial_constants.Plo \ gen-cpp/$(DEPDIR)/tutorial_types.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist_libtutorialgencpp_la_SOURCES) \ $(TutorialClient_SOURCES) $(TutorialServer_SOURCES) DIST_SOURCES = $(TutorialClient_SOURCES) $(TutorialServer_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc BUILT_SOURCES = gen-cpp/shared_types.cpp \ gen-cpp/tutorial_types.cpp noinst_LTLIBRARIES = libtutorialgencpp.la nodist_libtutorialgencpp_la_SOURCES = \ gen-cpp/Calculator.cpp \ gen-cpp/Calculator.h \ gen-cpp/SharedService.cpp \ gen-cpp/SharedService.h \ gen-cpp/shared_types.cpp \ gen-cpp/shared_types.h \ gen-cpp/tutorial_constants.cpp \ gen-cpp/tutorial_constants.h \ gen-cpp/tutorial_types.cpp \ gen-cpp/tutorial_types.h libtutorialgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la TutorialServer_SOURCES = \ CppServer.cpp TutorialServer_LDADD = \ libtutorialgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la TutorialClient_SOURCES = \ CppClient.cpp TutorialClient_LDADD = \ libtutorialgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp AM_CXXFLAGS = -Wall -Wextra -pedantic AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) EXTRA_DIST = \ CMakeLists.txt \ CppClient.cpp \ CppServer.cpp all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/cpp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/cpp/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gen-cpp/$(am__dirstamp): @$(MKDIR_P) gen-cpp @: > gen-cpp/$(am__dirstamp) gen-cpp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gen-cpp/$(DEPDIR) @: > gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/Calculator.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/SharedService.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/shared_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/tutorial_constants.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/tutorial_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) libtutorialgencpp.la: $(libtutorialgencpp_la_OBJECTS) $(libtutorialgencpp_la_DEPENDENCIES) $(EXTRA_libtutorialgencpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libtutorialgencpp_la_OBJECTS) $(libtutorialgencpp_la_LIBADD) $(LIBS) TutorialClient$(EXEEXT): $(TutorialClient_OBJECTS) $(TutorialClient_DEPENDENCIES) $(EXTRA_TutorialClient_DEPENDENCIES) @rm -f TutorialClient$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TutorialClient_OBJECTS) $(TutorialClient_LDADD) $(LIBS) TutorialServer$(EXEEXT): $(TutorialServer_OBJECTS) $(TutorialServer_DEPENDENCIES) $(EXTRA_TutorialServer_DEPENDENCIES) @rm -f TutorialServer$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TutorialServer_OBJECTS) $(TutorialServer_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f gen-cpp/*.$(OBJEXT) -rm -f gen-cpp/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CppClient.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CppServer.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/Calculator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/SharedService.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/shared_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/tutorial_constants.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/tutorial_types.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf gen-cpp/.libs gen-cpp/_libs style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f gen-cpp/$(DEPDIR)/$(am__dirstamp) -rm -f gen-cpp/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/CppClient.Po -rm -f ./$(DEPDIR)/CppServer.Po -rm -f gen-cpp/$(DEPDIR)/Calculator.Plo -rm -f gen-cpp/$(DEPDIR)/SharedService.Plo -rm -f gen-cpp/$(DEPDIR)/shared_types.Plo -rm -f gen-cpp/$(DEPDIR)/tutorial_constants.Plo -rm -f gen-cpp/$(DEPDIR)/tutorial_types.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/CppClient.Po -rm -f ./$(DEPDIR)/CppServer.Po -rm -f gen-cpp/$(DEPDIR)/Calculator.Plo -rm -f gen-cpp/$(DEPDIR)/SharedService.Plo -rm -f gen-cpp/$(DEPDIR)/shared_types.Plo -rm -f gen-cpp/$(DEPDIR)/tutorial_constants.Plo -rm -f gen-cpp/$(DEPDIR)/tutorial_types.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: all check install install-am install-exec install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # # Common thrift code generation rules # gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen cpp -r $< clean-local: $(RM) gen-cpp/* tutorialserver: all ./TutorialServer tutorialclient: all ./TutorialClient style-local: $(CPPSTYLE_CMD) distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/cpp/CppServer.cpp0000664000175000017500000001314715165535636020445 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include #include #include "../gen-cpp/Calculator.h" using namespace std; using namespace apache::thrift; using namespace apache::thrift::concurrency; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace apache::thrift::server; using namespace tutorial; using namespace shared; class CalculatorHandler : public CalculatorIf { public: CalculatorHandler() = default; void ping() override { cout << "ping()" << '\n'; } int32_t add(const int32_t n1, const int32_t n2) override { cout << "add(" << n1 << ", " << n2 << ")" << '\n'; return n1 + n2; } int32_t calculate(const int32_t logid, const Work& work) override { cout << "calculate(" << logid << ", " << work << ")" << '\n'; int32_t val; switch (work.op) { case Operation::ADD: val = work.num1 + work.num2; break; case Operation::SUBTRACT: val = work.num1 - work.num2; break; case Operation::MULTIPLY: val = work.num1 * work.num2; break; case Operation::DIVIDE: if (work.num2 == 0) { InvalidOperation io; io.whatOp = work.op; io.why = "Cannot divide by 0"; throw io; } val = work.num1 / work.num2; break; default: InvalidOperation io; io.whatOp = work.op; io.why = "Invalid Operation"; throw io; } SharedStruct ss; ss.key = logid; ss.value = to_string(val); log[logid] = ss; return val; } void getStruct(SharedStruct& ret, const int32_t logid) override { cout << "getStruct(" << logid << ")" << '\n'; ret = log[logid]; } void zip() override { cout << "zip()" << '\n'; } protected: map log; }; /* CalculatorIfFactory is code generated. CalculatorCloneFactory is useful for getting access to the server side of the transport. It is also useful for making per-connection state. Without this CloneFactory, all connections will end up sharing the same handler instance. */ class CalculatorCloneFactory : virtual public CalculatorIfFactory { public: ~CalculatorCloneFactory() override = default; CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) override { std::shared_ptr sock = std::dynamic_pointer_cast(connInfo.transport); cout << "Incoming connection\n"; cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; return new CalculatorHandler; } void releaseHandler( ::shared::SharedServiceIf* handler) override { delete handler; } }; int main() { TThreadedServer server( std::make_shared(std::make_shared()), std::make_shared(9090), //port std::make_shared(), std::make_shared()); /* // if you don't need per-connection state, do the following instead TThreadedServer server( std::make_shared(std::make_shared()), std::make_shared(9090), //port std::make_shared(), std::make_shared()); */ /** * Here are some alternate server types... // This server only allows one connection at a time, but spawns no threads TSimpleServer server( std::make_shared(std::make_shared()), std::make_shared(9090), std::make_shared(), std::make_shared()); const int workerCount = 4; std::shared_ptr threadManager = ThreadManager::newSimpleThreadManager(workerCount); threadManager->threadFactory( std::make_shared()); threadManager->start(); // This server allows "workerCount" connection at a time, and reuses threads TThreadPoolServer server( std::make_shared(std::make_shared()), std::make_shared(9090), std::make_shared(), std::make_shared(), threadManager); */ cout << "Starting the server..." << '\n'; server.serve(); cout << "Done." << '\n'; return 0; } thrift-0.23.0/tutorial/cpp/Makefile.am0000664000175000017500000000446215165535636020064 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc BUILT_SOURCES = gen-cpp/shared_types.cpp \ gen-cpp/tutorial_types.cpp noinst_LTLIBRARIES = libtutorialgencpp.la nodist_libtutorialgencpp_la_SOURCES = \ gen-cpp/Calculator.cpp \ gen-cpp/Calculator.h \ gen-cpp/SharedService.cpp \ gen-cpp/SharedService.h \ gen-cpp/shared_types.cpp \ gen-cpp/shared_types.h \ gen-cpp/tutorial_constants.cpp \ gen-cpp/tutorial_constants.h \ gen-cpp/tutorial_types.cpp \ gen-cpp/tutorial_types.h libtutorialgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la noinst_PROGRAMS = \ TutorialServer \ TutorialClient TutorialServer_SOURCES = \ CppServer.cpp TutorialServer_LDADD = \ libtutorialgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la TutorialClient_SOURCES = \ CppClient.cpp TutorialClient_LDADD = \ libtutorialgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la # # Common thrift code generation rules # gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen cpp -r $< AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp AM_CXXFLAGS = -Wall -Wextra -pedantic AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) clean-local: $(RM) gen-cpp/* tutorialserver: all ./TutorialServer tutorialclient: all ./TutorialClient style-local: $(CPPSTYLE_CMD) distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ CMakeLists.txt \ CppClient.cpp \ CppServer.cpp thrift-0.23.0/tutorial/rb/0000755000175000017500000000000015170007202015614 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/rb/RubyClient.rb0000775000175000017500000000347715167543515020263 0ustar00buildbuild00000000000000#!/usr/bin/env ruby # # 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. # $:.push('gen-rb') $:.unshift '../../lib/rb/lib' require 'thrift' require 'calculator' begin port = ARGV[0] || 9090 transport = Thrift::BufferedTransport.new(Thrift::Socket.new('localhost', port)) protocol = Thrift::BinaryProtocol.new(transport) client = Calculator::Client.new(protocol) transport.open() client.ping() print "ping()\n" sum = client.add(1, 1) print "1+1=", sum, "\n" sum = client.add(1, 4) print "1+4=", sum, "\n" work = Work.new() work.op = Operation::SUBTRACT work.num1 = 15 work.num2 = 10 diff = client.calculate(1, work) print "15-10=", diff, "\n" log = client.getStruct(1) print "Log: ", log.value, "\n" begin work.op = Operation::DIVIDE work.num1 = 1 work.num2 = 0 quot = client.calculate(1, work) puts "Whoa, we can divide by 0 now?" rescue InvalidOperation => io print "InvalidOperation: ", io.why, "\n" end client.zip() print "zip\n" transport.close() rescue Thrift::Exception => tx print 'Thrift::Exception: ', tx.message, "\n" end thrift-0.23.0/tutorial/rb/RubyServer.rb0000775000175000017500000000445515167543515020310 0ustar00buildbuild00000000000000#!/usr/bin/env ruby # # 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. # $:.push('gen-rb') $:.unshift '../../lib/rb/lib' require 'thrift' require 'calculator' require 'shared_types' class CalculatorHandler def initialize() @log = {} end def ping() puts "ping()" end def add(n1, n2) print "add(", n1, ",", n2, ")\n" return n1 + n2 end def calculate(logid, work) print "calculate(", logid, ", {", work.op, ",", work.num1, ",", work.num2, "})\n" if work.op == Operation::ADD val = work.num1 + work.num2 elsif work.op == Operation::SUBTRACT val = work.num1 - work.num2 elsif work.op == Operation::MULTIPLY val = work.num1 * work.num2 elsif work.op == Operation::DIVIDE if work.num2 == 0 x = InvalidOperation.new() x.whatOp = work.op x.why = "Cannot divide by 0" raise x end val = work.num1 / work.num2 else x = InvalidOperation.new() x.whatOp = work.op x.why = "Invalid operation" raise x end entry = SharedStruct.new() entry.key = logid entry.value = "#{val}" @log[logid] = entry return val end def getStruct(key) print "getStruct(", key, ")\n" return @log[key] end def zip() print "zip\n" end end handler = CalculatorHandler.new() processor = Calculator::Processor.new(handler) transport = Thrift::ServerSocket.new(9090) transportFactory = Thrift::BufferedTransportFactory.new() server = Thrift::SimpleServer.new(processor, transport, transportFactory) puts "Starting the server..." server.serve() puts "done." thrift-0.23.0/tutorial/rb/Makefile.in0000644000175000017500000004305015170007167017675 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/rb ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ RubyServer.rb \ RubyClient.rb all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/rb/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/rb/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-rb/calculator.rb gen-rb/shared_service.rb: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen rb -r $< all-local: gen-rb/calculator.rb tutorialserver: all ${RUBY} RubyServer.rb tutorialclient: all ${RUBY} RubyClient.rb clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/rb/Makefile.am0000664000175000017500000000216715165535636017705 0ustar00buildbuild00000000000000# # 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. # gen-rb/calculator.rb gen-rb/shared_service.rb: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen rb -r $< all-local: gen-rb/calculator.rb tutorialserver: all ${RUBY} RubyServer.rb tutorialclient: all ${RUBY} RubyClient.rb clean-local: $(RM) -r gen-* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ RubyServer.rb \ RubyClient.rb thrift-0.23.0/tutorial/js/0000755000175000017500000000000015170007202015625 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/js/src/0000775000175000017500000000000015165535636016443 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/js/src/Httpd.java0000664000175000017500000003030115165535636020366 0ustar00buildbuild00000000000000/* * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.URLDecoder; import java.util.Locale; import org.apache.http.ConnectionClosedException; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpServerConnection; import org.apache.http.HttpStatus; import org.apache.http.MethodNotSupportedException; import org.apache.http.entity.ContentProducer; import org.apache.http.entity.EntityTemplate; import org.apache.http.entity.FileEntity; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.DefaultHttpServerConnection; import org.apache.http.impl.NoConnectionReuseStrategy; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.BasicHttpProcessor; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.protocol.HttpRequestHandlerRegistry; import org.apache.http.protocol.HttpService; import org.apache.http.util.EntityUtils; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TMemoryBuffer; // Generated code import tutorial.*; import shared.*; import java.util.HashMap; /** * Basic, yet fully functional and spec compliant, HTTP/1.1 file server. *

* Please note the purpose of this application is demonstrate the usage of * HttpCore APIs. It is NOT intended to demonstrate the most efficient way of * building an HTTP file server. * * */ public class Httpd { public static void main(String[] args) throws Exception { if (args.length < 1) { System.err.println("Please specify document root directory"); System.exit(1); } Thread t = new RequestListenerThread(8088, args[0]); t.setDaemon(false); t.start(); } static class HttpFileHandler implements HttpRequestHandler { private final String docRoot; public HttpFileHandler(final String docRoot) { super(); this.docRoot = docRoot; } public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH); if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) { throw new MethodNotSupportedException(method + " method not supported"); } String target = request.getRequestLine().getUri(); if (request instanceof HttpEntityEnclosingRequest && target.equals("/thrift/service/tutorial/")) { HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); byte[] entityContent = EntityUtils.toByteArray(entity); System.out.println("Incoming content: " + new String(entityContent)); final String output = this.thriftRequest(entityContent); System.out.println("Outgoing content: "+output); EntityTemplate body = new EntityTemplate(new ContentProducer() { public void writeTo(final OutputStream outstream) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); writer.write(output); writer.flush(); } }); body.setContentType("text/html; charset=UTF-8"); response.setEntity(body); } else { final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8")); if (!file.exists()) { response.setStatusCode(HttpStatus.SC_NOT_FOUND); EntityTemplate body = new EntityTemplate(new ContentProducer() { public void writeTo(final OutputStream outstream) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); writer.write("

"); writer.write("File "); writer.write(file.getPath()); writer.write(" not found"); writer.write("

"); writer.flush(); } }); body.setContentType("text/html; charset=UTF-8"); response.setEntity(body); System.out.println("File " + file.getPath() + " not found"); } else if (!file.canRead() || file.isDirectory()) { response.setStatusCode(HttpStatus.SC_FORBIDDEN); EntityTemplate body = new EntityTemplate(new ContentProducer() { public void writeTo(final OutputStream outstream) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); writer.write("

"); writer.write("Access denied"); writer.write("

"); writer.flush(); } }); body.setContentType("text/html; charset=UTF-8"); response.setEntity(body); System.out.println("Cannot read file " + file.getPath()); } else { response.setStatusCode(HttpStatus.SC_OK); FileEntity body = new FileEntity(file, "text/html"); response.setEntity(body); System.out.println("Serving file " + file.getPath()); } } } private String thriftRequest(byte[] input){ try{ //Input TMemoryBuffer inbuffer = new TMemoryBuffer(input.length); inbuffer.write(input); TProtocol inprotocol = new TJSONProtocol(inbuffer); //Output TMemoryBuffer outbuffer = new TMemoryBuffer(100); TProtocol outprotocol = new TJSONProtocol(outbuffer); TProcessor processor = new Calculator.Processor(new CalculatorHandler()); processor.process(inprotocol, outprotocol); byte[] output = new byte[outbuffer.length()]; outbuffer.readAll(output, 0, output.length); return new String(output,"UTF-8"); }catch(Throwable t){ return "Error:"+t.getMessage(); } } } static class RequestListenerThread extends Thread { private final ServerSocket serversocket; private final HttpParams params; private final HttpService httpService; public RequestListenerThread(int port, final String docroot) throws IOException { this.serversocket = new ServerSocket(port); this.params = new BasicHttpParams(); this.params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 1000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); // Set up the HTTP protocol processor HttpProcessor httpproc = new BasicHttpProcessor(); // Set up request handlers HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry(); reqistry.register("*", new HttpFileHandler(docroot)); // Set up the HTTP service this.httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory()); this.httpService.setParams(this.params); this.httpService.setHandlerResolver(reqistry); } public void run() { System.out.println("Listening on port " + this.serversocket.getLocalPort()); System.out.println("Point your browser to http://localhost:8088/tutorial/js/tutorial.html"); while (!Thread.interrupted()) { try { // Set up HTTP connection Socket socket = this.serversocket.accept(); DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); System.out.println("Incoming connection from " + socket.getInetAddress()); conn.bind(socket, this.params); // Start worker thread Thread t = new WorkerThread(this.httpService, conn); t.setDaemon(true); t.start(); } catch (InterruptedIOException ex) { break; } catch (IOException e) { System.err.println("I/O error initialising connection thread: " + e.getMessage()); break; } } } } static class WorkerThread extends Thread { private final HttpService httpservice; private final HttpServerConnection conn; public WorkerThread(final HttpService httpservice, final HttpServerConnection conn) { super(); this.httpservice = httpservice; this.conn = conn; } public void run() { System.out.println("New connection thread"); HttpContext context = new BasicHttpContext(null); try { while (!Thread.interrupted() && this.conn.isOpen()) { this.httpservice.handleRequest(this.conn, context); } } catch (ConnectionClosedException ex) { System.err.println("Client closed connection"); } catch (IOException ex) { System.err.println("I/O error: " + ex.getMessage()); } catch (HttpException ex) { System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage()); } finally { try { this.conn.shutdown(); } catch (IOException ignore) { } } } } } thrift-0.23.0/tutorial/js/build.properties0000664000175000017500000000036415165535636021074 0ustar00buildbuild00000000000000# Maven Ant tasks Jar details mvn.ant.task.version=2.1.3 mvn.repo=https://repo1.maven.org/maven2 mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version} mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar thrift-0.23.0/tutorial/js/build.xml0000664000175000017500000001165215165535636017502 0ustar00buildbuild00000000000000 Thrift JavaScript Tutorial thrift-0.23.0/tutorial/js/tutorial.html0000664000175000017500000000756315165535636020420 0ustar00buildbuild00000000000000 Thrift Javascript Bindings - Tutorial Example

Thrift Javascript Bindings

num1
Operation
num2
result
autoupdate

This Java Script example uses tutorial.thrift and a Thrift server using JSON protocol and HTTP transport.

Valid XHTML 1.0!

thrift-0.23.0/tutorial/js/Makefile.in0000644000175000017500000004325015170007167017710 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/js ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ build.properties \ build.xml \ src \ tutorial.html all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/js/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/js/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile export CLASSPATH # Make sure this doesn't fail if ant is not configured. clean-local: ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \ $$ANT $(ANT_FLAGS) clean all-local: $(ANT) $(ANT_FLAGS) compile check-local: all $(ANT) $(ANT_FLAGS) test tutorialserver: all $(ANT) $(ANT_FLAGS) tutorialserver distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/js/Makefile.am0000664000175000017500000000227515165535636017716 0ustar00buildbuild00000000000000# # 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. # export CLASSPATH # Make sure this doesn't fail if ant is not configured. clean-local: ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \ $$ANT $(ANT_FLAGS) clean all-local: $(ANT) $(ANT_FLAGS) compile check-local: all $(ANT) $(ANT_FLAGS) test tutorialserver: all $(ANT) $(ANT_FLAGS) tutorialserver distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ build.properties \ build.xml \ src \ tutorial.html thrift-0.23.0/tutorial/rs/0000755000175000017500000000000015170007202015635 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/rs/src/0000755000175000017500000000000015170007202016424 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/rs/src/bin/0000755000175000017500000000000015170007202017174 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/rs/src/bin/tutorial_server.rs0000664000175000017500000001405315165535636023025 0ustar00buildbuild00000000000000// 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. use std::collections::HashMap; use std::convert::{From, Into}; use std::default::Default; use std::sync::Mutex; use clap::{clap_app, value_t}; use thrift::protocol::{TCompactInputProtocolFactory, TCompactOutputProtocolFactory}; use thrift::server::TServer; use thrift::transport::{TFramedReadTransportFactory, TFramedWriteTransportFactory}; use thrift_tutorial::shared::{SharedServiceSyncHandler, SharedStruct}; use thrift_tutorial::tutorial::{CalculatorSyncHandler, CalculatorSyncProcessor}; use thrift_tutorial::tutorial::{InvalidOperation, Operation, Work}; fn main() { match run() { Ok(()) => println!("tutorial server ran successfully"), Err(e) => { println!("tutorial server failed with error {:?}", e); std::process::exit(1); } } } fn run() -> thrift::Result<()> { let options = clap_app!(rust_tutorial_server => (version: "0.1.0") (author: "Apache Thrift Developers ") (about: "Thrift Rust tutorial server") (@arg port: --port +takes_value "port on which the tutorial server listens") ); let matches = options.get_matches(); let port = value_t!(matches, "port", u16).unwrap_or(9090); let listen_address = format!("127.0.0.1:{}", port); println!("binding to {}", listen_address); let i_tran_fact = TFramedReadTransportFactory::new(); let i_prot_fact = TCompactInputProtocolFactory::new(); let o_tran_fact = TFramedWriteTransportFactory::new(); let o_prot_fact = TCompactOutputProtocolFactory::new(); // demux incoming messages let processor = CalculatorSyncProcessor::new(CalculatorServer { ..Default::default() }); // create the server and start listening let mut server = TServer::new( i_tran_fact, i_prot_fact, o_tran_fact, o_prot_fact, processor, 10, ); server.listen(&listen_address) } /// Handles incoming Calculator service calls. struct CalculatorServer { log: Mutex>, } impl Default for CalculatorServer { fn default() -> CalculatorServer { CalculatorServer { log: Mutex::new(HashMap::new()), } } } // since Calculator extends SharedService we have to implement the // handler for both traits. // // SharedService handler impl SharedServiceSyncHandler for CalculatorServer { fn handle_get_struct(&self, key: i32) -> thrift::Result { let log = self.log.lock().unwrap(); log.get(&key) .cloned() .ok_or_else(|| format!("could not find log for key {}", key).into()) } } // Calculator handler impl CalculatorSyncHandler for CalculatorServer { fn handle_ping(&self) -> thrift::Result<()> { println!("pong!"); Ok(()) } fn handle_add(&self, num1: i32, num2: i32) -> thrift::Result { println!("handling add: n1:{} n2:{}", num1, num2); Ok(num1 + num2) } fn handle_calculate(&self, logid: i32, w: Work) -> thrift::Result { println!("handling calculate: l:{}, w:{:?}", logid, w); let res = if let Some(ref op) = w.op { if w.num1.is_none() || w.num2.is_none() { Err(InvalidOperation { what_op: Some(op.into()), why: Some("no operands specified".to_owned()), }) } else { // so that I don't have to call unwrap() multiple times below let num1 = w.num1.as_ref().expect("operands checked"); let num2 = w.num2.as_ref().expect("operands checked"); match *op { Operation::ADD => Ok(num1 + num2), Operation::SUBTRACT => Ok(num1 - num2), Operation::MULTIPLY => Ok(num1 * num2), Operation::DIVIDE => { if *num2 == 0 { Err(InvalidOperation { what_op: Some(op.into()), why: Some("divide by 0".to_owned()), }) } else { Ok(num1 / num2) } } _ => { let op_val: i32 = op.into(); Err(InvalidOperation { what_op: Some(op_val), why: Some(format!("unsupported operation type '{}'", op_val)), }) } } } } else { Err(InvalidOperation::new( None, "no operation specified".to_owned(), )) }; // if the operation was successful log it if let Ok(ref v) = res { let mut log = self.log.lock().unwrap(); log.insert(logid, SharedStruct::new(logid, format!("{}", v))); } // the try! macro automatically maps errors // but, since we aren't using that here we have to map errors manually // // exception structs defined in the IDL have an auto-generated // impl of From::from res.map_err(From::from) } fn handle_zip(&self) -> thrift::Result<()> { println!("handling zip"); Ok(()) } } thrift-0.23.0/tutorial/rs/src/bin/tutorial_client.rs0000664000175000017500000001044115165535636022772 0ustar00buildbuild00000000000000// 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. use clap::{clap_app, value_t}; use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol}; use thrift::transport::{ ReadHalf, TFramedReadTransport, TFramedWriteTransport, TIoChannel, TTcpChannel, WriteHalf, }; use thrift_tutorial::shared::TSharedServiceSyncClient; use thrift_tutorial::tutorial::{CalculatorSyncClient, Operation, TCalculatorSyncClient, Work}; fn main() { match run() { Ok(()) => println!("tutorial client ran successfully"), Err(e) => { println!("tutorial client failed with error {:?}", e); std::process::exit(1); } } } fn run() -> thrift::Result<()> { let options = clap_app!(rust_tutorial_client => (version: "0.1.0") (author: "Apache Thrift Developers ") (about: "Thrift Rust tutorial client") (@arg host: --host +takes_value "host on which the tutorial server listens") (@arg port: --port +takes_value "port on which the tutorial server listens") ); let matches = options.get_matches(); // get any passed-in args or the defaults let host = matches.value_of("host").unwrap_or("127.0.0.1"); let port = value_t!(matches, "port", u16).unwrap_or(9090); // build our client and connect to the host:port let mut client = new_client(host, port)?; // alright! // let's start making some calls // let's start with a ping; the server should respond println!("ping!"); client.ping()?; // simple add println!("add"); let res = client.add(1, 2)?; println!("added 1, 2 and got {}", res); let logid = 32; // let's do...a multiply! let res = client.calculate(logid, Work::new(7, 8, Operation::MULTIPLY, None))?; println!("multiplied 7 and 8 and got {}", res); // let's get the log for it let res = client.get_struct(logid /* 32 */)?; println!("got log {:?} for operation {}", res, logid); // ok - let's be bad :( // do a divide by 0 // logid doesn't matter; won't be recorded let res = client.calculate(77, Work::new(2, 0, Operation::DIVIDE, "we bad".to_owned())); // we should have gotten an exception back match res { Ok(v) => panic!("should not have succeeded with result {}", v), Err(e) => println!("divide by zero failed with error {:?}", e), } // let's do a one-way call println!("zip"); client.zip()?; // and then close out with a final ping println!("ping!"); client.ping()?; Ok(()) } type ClientInputProtocol = TCompactInputProtocol>>; type ClientOutputProtocol = TCompactOutputProtocol>>; fn new_client( host: &str, port: u16, ) -> thrift::Result> { let mut c = TTcpChannel::new(); // open the underlying TCP stream println!("connecting to tutorial server on {}:{}", 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 let (i_chan, o_chan) = c.split()?; // wrap the raw sockets (slow) with a buffered transport of some kind let i_tran = TFramedReadTransport::new(i_chan); let o_tran = TFramedWriteTransport::new(o_chan); // now create the protocol implementations let i_prot = TCompactInputProtocol::new(i_tran); let o_prot = TCompactOutputProtocol::new(o_tran); // we're done! Ok(CalculatorSyncClient::new(i_prot, o_prot)) } thrift-0.23.0/tutorial/rs/src/lib.rs0000664000175000017500000000150015165535636017563 0ustar00buildbuild00000000000000// 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. pub mod shared; pub mod tutorial; thrift-0.23.0/tutorial/rs/Cargo.toml0000664000175000017500000000047715165535636017624 0ustar00buildbuild00000000000000[package] name = "thrift-tutorial" version = "0.1.0" edition = "2021" license = "Apache-2.0" authors = ["Apache Thrift Developers "] exclude = ["Makefile*", "shared.rs", "tutorial.rs"] publish = false [dependencies] clap = "~2.33" bitflags = "=1.2" [dependencies.thrift] path = "../../lib/rs" thrift-0.23.0/tutorial/rs/README.md0000664000175000017500000001454615165535636017155 0ustar00buildbuild00000000000000# Rust Language Bindings for Thrift ## Getting Started 1. Get the [Thrift compiler](https://thrift.apache.org). 2. Add the thrift crate to your `Cargo.toml`. ```toml thrift = "x.y.z" # x.y.z is the version of the thrift compiler ``` 3. Generate Rust sources for your IDL (for example, `Tutorial.thrift`). ```shell thrift -out my_rust_program/src --gen rs -r Tutorial.thrift ``` 4. Use the generated source in your code. ```rust // generated Rust module from Thrift IDL mod tutorial; use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol}; use thrift::protocol::{TInputProtocol, TOutputProtocol}; use thrift::transport::{TFramedReadTransport, TFramedWriteTransport}; use thrift::transport::{TIoChannel, TTcpChannel}; use tutorial::{CalculatorSyncClient, TCalculatorSyncClient}; use tutorial::{Operation, Work}; fn main() { match run() { Ok(()) => println!("client ran successfully"), Err(e) => { println!("client failed with {:?}", e); std::process::exit(1); } } } fn run() -> thrift::Result<()> { // // build client // println!("connect to server on 127.0.0.1:9090"); let mut c = TTcpChannel::new(); c.open("127.0.0.1:9090")?; let (i_chan, o_chan) = c.split()?; let i_prot = TCompactInputProtocol::new( TFramedReadTransport::new(i_chan) ); let o_prot = TCompactOutputProtocol::new( TFramedWriteTransport::new(o_chan) ); let mut client = CalculatorSyncClient::new(i_prot, o_prot); // // alright! - let's make some calls // // two-way, void return client.ping()?; // two-way with some return let res = client.calculate( 72, Work::new(7, 8, Operation::Multiply, None) )?; println!("multiplied 7 and 8, got {}", res); // two-way and returns a Thrift-defined exception let res = client.calculate( 77, Work::new(2, 0, Operation::Divide, None) ); match res { Ok(v) => panic!("shouldn't have succeeded with result {}", v), Err(e) => println!("divide by zero failed with {:?}", e), } // one-way client.zip()?; // done! Ok(()) } ``` ## Code Generation ### Thrift Files and Generated Modules The Thrift code generator takes each Thrift file and generates a Rust module with the same name snake-cased. For example, running the compiler on `ThriftTest.thrift` creates `thrift_test.rs`. To use these generated files add `mod ...` and `use ...` declarations to your `lib.rs` or `main.rs` - one for each generated file. ### Results and Errors The Thrift runtime library defines a `thrift::Result` and a `thrift::Error` type, both of which are used throughout the runtime library and in all generated code. Conversions are defined from `std::io::Error`, `str` and `String` into `thrift::Error`. ### Thrift Type and their Rust Equivalents Thrift defines a number of types, each of which is translated into its Rust equivalent by the code generator. * Primitives (bool, i8, i16, i32, i64, double, string, binary) * Typedefs * Enums * Containers * Structs * Unions * Exceptions * Services * Constants (primitives, containers, structs) In addition, unless otherwise noted, thrift includes are translated into `use ...` statements in the generated code, and all declarations, parameters, traits and types in the generated code are namespaced appropriately. The following subsections cover each type and their generated Rust equivalent. ### Primitives Thrift primitives have straightforward Rust equivalents. * bool: `bool` * i8: `i8` * i16: `i16` * i32: `i32` * i64: `i64` * double: `OrderedFloat` * string: `String` * binary: `Vec` ### Typedefs A typedef is translated to a `pub type` declaration. ```thrift typedef i64 UserId typedef map MapType ``` ```rust pub type UserId = i64; pub type MapType = BTreeMap; ``` ### Enums A Thrift enum is represented as a Rust enum, and each variant is transcribed 1:1. ```thrift enum Numberz { ONE = 1, TWO, THREE, FIVE = 5, SIX, EIGHT = 8 } ``` ```rust #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum Numberz { ONE = 1, TWO = 2, THREE = 3, FIVE = 5, SIX = 6, EIGHT = 8, } impl TryFrom for Numberz { // ... } ``` ### Containers Thrift has three container types: list, set and map. They are translated into Rust `Vec`, `BTreeSet` and `BTreeMap` respectively. Any Thrift type (this includes structs, enums and typedefs) can be a list/set element or a map key/value. #### List ```thrift list numbers ``` ```rust numbers: Vec ``` #### Set ```thrift set numbers ``` ```rust numbers: BTreeSet ``` #### Map ```thrift map numbers ``` ```rust numbers: BTreeMap ``` ### Structs A Thrift struct is represented as a Rust struct, and each field transcribed 1:1. ```thrift struct CrazyNesting { 1: string string_field, 2: optional set set_field, 3: required list< map, map>>>> > 4: binary binary_field } ``` ```rust #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct CrazyNesting { pub string_field: Option, pub set_field: Option>, pub list_field: Vec< BTreeMap< BTreeSet, BTreeMap>>> > >, pub binary_field: Option>, } impl CrazyNesting { pub fn read_from_in_protocol(i_prot: &mut TInputProtocol) -> thrift::Result { // ... } pub fn write_to_out_protocol(&self, o_prot: &mut TOutputProtocol) -> thrift::Result<()> { // ... } } ``` ##### Optionality Thrift has 3 "optionality" types: 1. Required 2. Optional 3. Default The Rust code generator encodes *Required* fields as the bare type itself, while *Optional* and *Default* fields are encoded as `Option`. ```thrift struct Foo { 1: required string bar // 1. required 2: optional string baz // 2. optional 3: string qux // 3. default } ``` ```rust pub struct Foo { bar: String, // 1. required baz: Option, // 2. optional qux: Option, // 3. default } ``` ## Known Issues * Struct constants are not supported * Map, list and set constants require a const holder struct thrift-0.23.0/tutorial/rs/Makefile.in0000644000175000017500000004367615170007167017734 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tutorial/rs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ Cargo.toml \ src/lib.rs \ src/bin/tutorial_server.rs \ src/bin/tutorial_client.rs \ README.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/rs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/rs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-rs/tutorial.rs gen-rs/shared.rs: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) -out src --gen rs -r $< all-local: gen-rs/tutorial.rs $(CARGO) build $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings [ -d bin ] || mkdir bin cp target/debug/tutorial_server bin/tutorial_server cp target/debug/tutorial_client bin/tutorial_client check: all tutorialserver: all bin/tutorial_server tutorialclient: all bin/tutorial_client clean-local: $(CARGO) clean -$(RM) Cargo.lock -$(RM) src/shared.rs -$(RM) src/tutorial.rs -$(RM) -r bin distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/rs/Makefile.am0000664000175000017500000000302715165535636017722 0ustar00buildbuild00000000000000# # 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. # THRIFT = $(top_builddir)/compiler/cpp/thrift gen-rs/tutorial.rs gen-rs/shared.rs: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) -out src --gen rs -r $< all-local: gen-rs/tutorial.rs $(CARGO) build $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings [ -d bin ] || mkdir bin cp target/debug/tutorial_server bin/tutorial_server cp target/debug/tutorial_client bin/tutorial_client check: all tutorialserver: all bin/tutorial_server tutorialclient: all bin/tutorial_client clean-local: $(CARGO) clean -$(RM) Cargo.lock -$(RM) src/shared.rs -$(RM) src/tutorial.rs -$(RM) -r bin distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ Cargo.toml \ src/lib.rs \ src/bin/tutorial_server.rs \ src/bin/tutorial_client.rs \ README.md thrift-0.23.0/tutorial/Makefile.am0000664000175000017500000000363315165535636017301 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = if MINGW # do nothing, just build the compiler else if WITH_C_GLIB SUBDIRS += c_glib endif if WITH_CPP SUBDIRS += cpp endif if WITH_D SUBDIRS += d endif if WITH_JAVA SUBDIRS += java SUBDIRS += js endif if WITH_PYTHON SUBDIRS += py SUBDIRS += py.twisted SUBDIRS += py.tornado endif if WITH_RUBY SUBDIRS += rb endif if WITH_HAXE SUBDIRS += haxe endif if WITH_DOTNET SUBDIRS += netstd endif if WITH_GO SUBDIRS += go endif if WITH_NODEJS SUBDIRS += nodejs endif if WITH_DART SUBDIRS += dart endif if WITH_RS SUBDIRS += rs endif if WITH_CL SUBDIRS += cl endif if WITH_PERL SUBDIRS += perl endif if WITH_PHP SUBDIRS += php endif if WITH_SWIFT SUBDIRS += swift endif # # generate html for tutorial.thrift # all-local: $(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/tutorial/tutorial.thrift clean-local: rm -rf $(top_srcdir)/tutorial/gen-html 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 = \ d \ delphi \ erl \ ocaml \ shared.thrift \ tutorial.thrift \ README.md thrift-0.23.0/tutorial/d/0000775000175000017500000000000015170007176015450 5ustar00buildbuild00000000000000thrift-0.23.0/tutorial/d/server.d0000664000175000017500000000563015165535636017142 0ustar00buildbuild00000000000000/* * 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. */ module server; import std.conv : to; import std.stdio; import thrift.codegen.processor; import thrift.protocol.binary; import thrift.server.simple; import thrift.server.transport.socket; import thrift.transport.buffered; import share.SharedService; import share.shared_types; import tutorial.Calculator; import tutorial.tutorial_types; /** * The actual implementation of the Calculator interface that is called by * the server to answer the requests. */ class CalculatorHandler : Calculator { void ping() { writeln("ping()"); } int add(int n1, int n2) { writefln("add(%s,%s)", n1, n2); return n1 + n2; } int calculate(int logid, ref const(Work) work) { writefln("calculate(%s, {%s, %s, %s})", logid, work.op, work.num1, work.num2); int val; switch (work.op) { case Operation.ADD: val = work.num1 + work.num2; break; case Operation.SUBTRACT: val = work.num1 - work.num2; break; case Operation.MULTIPLY: val = work.num1 * work.num2; break; case Operation.DIVIDE: if (work.num2 == 0) { auto io = new InvalidOperation(); io.whatOp = work.op; io.why = "Cannot divide by 0"; throw io; } val = work.num1 / work.num2; break; default: auto io = new InvalidOperation(); io.whatOp = work.op; io.why = "Invalid Operation"; throw io; } auto ss = SharedStruct(); ss.key = logid; ss.value = to!string(val); log[logid] = ss; return val; } SharedStruct getStruct(int logid) { writefln("getStruct(%s)", logid); return log[logid]; } void zip() { writeln("zip()"); } protected: SharedStruct[int] log; } void main() { auto protocolFactory = new TBinaryProtocolFactory!(); auto processor = new TServiceProcessor!Calculator(new CalculatorHandler); auto serverTransport = new TServerSocket(9090); auto transportFactory = new TBufferedTransportFactory; auto server = new TSimpleServer( processor, serverTransport, transportFactory, protocolFactory); writeln("Starting the server on port 9090..."); server.serve(); writeln("done."); } thrift-0.23.0/tutorial/d/async_client.d0000664000175000017500000000465415165535636020314 0ustar00buildbuild00000000000000/* * 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. */ module async_client; import std.exception; import std.stdio; import thrift.async.libevent; import thrift.async.socket; import thrift.base; import thrift.codegen.async_client; import thrift.protocol.binary; import thrift.transport.buffered; import tutorial.Calculator; import tutorial.tutorial_types; void main() { auto asyncManager = new TLibeventAsyncManager; // If we are done, gracefully stop the async manager to avoid hanging on // appplication shutdown. scope (exit) asyncManager.stop(); auto socket = new TAsyncSocket(asyncManager, "localhost", 9090); auto client = new TAsyncClient!Calculator( socket, new TBufferedTransportFactory, new TBinaryProtocolFactory!TBufferedTransport ); socket.open(); // Invoke all the methods. auto pingResult = client.ping(); auto addResult = client.add(1, 1); auto work = Work(); work.op = Operation.DIVIDE; work.num1 = 1; work.num2 = 0; auto quotientResult = client.calculate(1, work); work.op = Operation.SUBTRACT; work.num1 = 15; work.num2 = 10; auto diffResult = client.calculate(1, work); auto logResult = client.getStruct(1); // Await the responses. pingResult.waitGet(); writeln("ping()"); int sum = addResult.waitGet(); writefln("1 + 1 = %s", sum); try { quotientResult.waitGet(); writeln("Whoa we can divide by 0"); } catch (InvalidOperation io) { writeln("Invalid operation: " ~ io.why); } writefln("15 - 10 = %s", diffResult.waitGet()); // TFuture is implicitly convertible to the result type via »alias this«, // for which it (eagerly, of course) awaits completion. writefln("Check log: %s", logResult.value); } thrift-0.23.0/tutorial/d/client.d0000664000175000017500000000350215165535636017106 0ustar00buildbuild00000000000000/* * 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. */ module client; import std.stdio; import thrift.base; import thrift.codegen.client; import thrift.protocol.binary; import thrift.transport.buffered; import thrift.transport.socket; import tutorial.Calculator; import tutorial.tutorial_types; void main() { auto socket = new TSocket("localhost", 9090); auto transport = new TBufferedTransport(socket); auto protocol = tBinaryProtocol(transport); auto client = tClient!Calculator(protocol); transport.open(); client.ping(); writeln("ping()"); int sum = client.add(1, 1); writefln("1 + 1 = %s", sum); auto work = Work(); work.op = Operation.DIVIDE; work.num1 = 1; work.num2 = 0; try { int quotient = client.calculate(1, work); writeln("Whoa we can divide by 0"); } catch (InvalidOperation io) { writeln("Invalid operation: " ~ io.why); } work.op = Operation.SUBTRACT; work.num1 = 15; work.num2 = 10; int diff = client.calculate(1, work); writefln("15 - 10 = %s", diff); auto log = client.getStruct(1); writefln("Check log: %s", log.value); } thrift-0.23.0/tutorial/d/Makefile0000644000175000017500000004535215170007176017117 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # tutorial/d/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu am__append_1 = async_client subdir = tutorial/d ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/tutorial/d abs_srcdir = /thrift/src/tutorial/d abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. LIB_D_DIR = $(top_srcdir)/lib/d GEN_SRC = gen-d/share/SharedService.d gen-d/share/shared_types.d \ gen-d/tutorial/tutorial_types.d gen-d/tutorial/Calculator.d PROGS = server client $(am__append_1) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/d/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/d/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile $(GEN_SRC): $(top_srcdir)/tutorial/tutorial.thrift $(top_builddir)/compiler/cpp/thrift --gen d -r $< server: server.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd server.d ${GEN_SRC} client: client.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd client.d ${GEN_SRC} async_client: async_client.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd-event -L-lthriftd -L-levent async_client.d ${GEN_SRC} all-local: $(PROGS) clean: $(RM) -f $(PROGS) $(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/ find $(destdir) -type f -name '*.o' | xargs rm -f # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/d/Makefile.in0000644000175000017500000004441715170007167017525 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_D_EVENT_TESTS_TRUE@am__append_1 = async_client subdir = tutorial/d ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ LIB_D_DIR = $(top_srcdir)/lib/d GEN_SRC = gen-d/share/SharedService.d gen-d/share/shared_types.d \ gen-d/tutorial/tutorial_types.d gen-d/tutorial/Calculator.d PROGS = server client $(am__append_1) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tutorial/d/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign tutorial/d/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile $(GEN_SRC): $(top_srcdir)/tutorial/tutorial.thrift $(top_builddir)/compiler/cpp/thrift --gen d -r $< server: server.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd server.d ${GEN_SRC} client: client.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd client.d ${GEN_SRC} @WITH_D_EVENT_TESTS_TRUE@async_client: async_client.d $(GEN_SRC) @WITH_D_EVENT_TESTS_TRUE@ $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd-event -L-lthriftd -L-levent async_client.d ${GEN_SRC} all-local: $(PROGS) clean: $(RM) -f $(PROGS) $(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/ find $(destdir) -type f -name '*.o' | xargs rm -f # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/tutorial/d/Makefile.am0000664000175000017500000000333715165535636017525 0ustar00buildbuild00000000000000# # 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. # LIB_D_DIR = $(top_srcdir)/lib/d GEN_SRC = gen-d/share/SharedService.d gen-d/share/shared_types.d \ gen-d/tutorial/tutorial_types.d gen-d/tutorial/Calculator.d $(GEN_SRC): $(top_srcdir)/tutorial/tutorial.thrift $(top_builddir)/compiler/cpp/thrift --gen d -r $< server: server.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd server.d ${GEN_SRC} client: client.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd client.d ${GEN_SRC} PROGS = server client if WITH_D_EVENT_TESTS async_client: async_client.d $(GEN_SRC) $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd-event -L-lthriftd -L-levent async_client.d ${GEN_SRC} PROGS += async_client endif all-local: $(PROGS) clean: $(RM) -f $(PROGS) $(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/ find $(destdir) -type f -name '*.o' | xargs rm -f thrift-0.23.0/depcomp0000755000175000017500000005602015166010001014722 0ustar00buildbuild00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: thrift-0.23.0/doc/0000775000175000017500000000000015167543515014137 5ustar00buildbuild00000000000000thrift-0.23.0/doc/ReleaseManagement.md0000664000175000017500000006322715167543515020050 0ustar00buildbuild00000000000000# Apache Thrift Release Management Instructions for preparing and distributing a release of Apache Thrift are fairly complex. These procedures are documented here, and we're working to automate as much of this as possible. There are few projects like ours that integrate with 28 programming languages. Given the extreme number of package management systems that Apache Thrift integrates with (compared to perhaps any), part of the burden of releasing Apache Thrift is to manually package and upload some of these [language-specific packages](http://thrift.apache.org/lib). It is important to note here that Apache Thrift is designed for version interoperability, so one can use a version 0.7.0 client with a 0.12.0 server. A particular version number does not make any guarantees as to the features available in any given language. See the [Language Feature Matrix](https://github.com/apache/thrift/blob/master/LANGUAGES.md) to learn more. ## Concepts ### Versioning Apache Thrift and the vast majority of package management systems out there conform to the [SemVer 2.0](https://semver.org/spec/v2.0.0.html) version numbering specification. Apache Thrift uses the following versioning rules: - *major* is currently always zero; - *minor* is increased for each release cycle; - *patch* is increased for patch builds between release cycles to address critical defect, security, or packaging issues Further, if there are only packaging changes for a single third-party distribution point to correct an issue, the major.minor.patch may remain the same while adding a suffix compatible with that distribution point, for example, "0.12.0.1" for nuget, or "0.12.0-1" for maven. #### External Package Patches It is common to have language-specific critical defects or packaging errors that need to be resolved between releases of Apache Thrift. The project handles these on a case-by-case basis for languages that have their own [package management systems](http://thrift.apache.org/lib). When a language-specific patch is made, the patch level of the distribution pushed to the external package manager is bumped. As such, there may be cases between Apache Thrift releases where there are (for example) a `0.12.1` and `0.12.2` version of a Haskell Hackage package, and perhaps also a `0.12.3` version of a dlang dub package. You will not find a tag or an official project release in these cases, however, the code changes will be reflected in the release branch and in master. In these cases we would not release a version of Apache Thrift nor would we refresh all the external language packages. #### Version in the master branch The master branch will always contain the next anticipated release version. When a release cycle begins, a branch is cut from master. The release branch will already have all of the correct versions, and therefore release branches can be easily merged back into master. (This was not true of releases before 0.12.0). ### Code Repository The authoritative repository for Apache Thrift is stored in [GitHub](https://github.com/apache/thrift). It is mirrored by [GitBox](https://gitbox.apache.org/repos/asf?p=thrift.git). ### Branches All code (submitted via pull request or direct push) is committed to the `master` branch. Until version 1.0 of Apache Thrift each release branch was named ``, for example in version `0.12.0` there is a branch named the same. For version 1.0 releases any beyond, releases will have a branch named `release/`. ### Tags Up to version `0.12.0` each release of Apache Thrift was tagged with a `` tag. Starting with the `0.12.0` release, each release of Apache Thrift will be tagged with a `v` tag to satisfy external package management tools (such as ones for dlang and golang). For example the tag of version `0.12.0` is `v0.12.0`. ## Release Procedures ### Release Schedule Apache Thrift has no official release schedule, however the project aims to release at least twice per year. A complete release cycle will take about 1 week to complete, if things go well, with half of that time waiting for a vote. ### Release Manager Before a release cycle begins, someone must nominate themselves on the development mailing list as the release manager for that release. In order to be a release manager you must meet the following criteria: 1. You are a [member](http://people.apache.org/phonebook.html?pmc=thrift) of the Apache PMC group. 1. Your profile at https://id.apache.org/ is valid and contains a PGP key. If it does not, see the [Apache OpenPGP Instructions](https://www.apache.org/dev/openpgp.html). If your PGP private key creation seems to hang indefinitely while creating entropy, try these fixes: - Generate disk I/O with: `dd if=/dev/sda of=/dev/zero` - Install the `rng-tools` package. 1. Your PGP key is visible in the [Apache Committer Keys](http://people.apache.org/keys/committer/) for code signing. This list is updated periodically from your Apache ID (see previous step). 1. You have read and agree with the contents of the [ASF Release Distribution Policy](https://www.apache.org/dev/release-distribution.html). 1. You have access and the ability to use subversion. All distribution artifacts are released through a subversion commit. 1. You can build in the Linux Docker Container, and you have Visual Studio 2017. 1. You have sufficient time to complete a release distribution. ### Release Candidate All Apache Thrift releases go through a 72-hour final release candidate voting procedure. Votes from members of the Apache Thrift PMC are binding, and all others are non-binding. For these examples, the `master` branch is at version 1.0.0 and that is the next release. 1. Scrub the Apache Jira backlog. There are a couple things to do: 1. [Open Issues without a Component](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20status%20!%3D%20Closed%20and%20component%20is%20empty) - make sure everything has an assigned component, as the release notes are grouped together by language. 1. [Open Issues with a Fix Version](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20status%20in%20(OPEN%2C%20%27IN%20PROGRESS%27%2C%20REOPENED)%20and%20fixVersion%20is%20not%20empty) - these will be issues that someone placed a fixVersion on in Jira, but have not been resolved or closed yet. They are likely stale somehow. Resolutions for these issues include resolving or closing the issue in Jira, or simply removing the fixVersion if the issue hasn't been fixed. 1. [Open Blocking Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(blocker)%20and%20status%20not%20in%20(closed,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,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. 1. Check that the version number in the `master` branch matches the version number of the upcoming release. To check the `master` branch version, run: ```bash thrift$ grep AC_INIT configure.ac | cut -d'[' -f3 | cut -d']' -f1 1.0.0 ``` If it does not match (this should be extremely rare), you need to submit a pull request setting the `master` branch to the desired version of the upcoming release. In the following example, we prepare to commit a branch where the version number is changed from `1.0.0` to `1.1.0`: ```bash thrift$ git checkout -b fix-version-for-release thrift$ build/veralign.sh 1.0.0 1.1.0 # check to see if any of the manually modified files needs changes thrift$ git push ... # make a pull request ``` 1. Create a release branch for the release, in this example `1.0.0`: ```bash thrift$ git checkout master thrift$ git pull thrift$ git checkout -b "release/1.0.0" thrift$ git push ``` Now there is a `release/1.0.0` branch in GitHub for Apache Thrift. By creating a release branch we allow work to continue on the `master` branch for the next release while we finalize this one. Note that `release/1.0.0` and `master` in this example are now identical, and therefore it is possible to merge the release branch back into `master` at the end of the release! 1. Modify these files manually, inserting the release into them at the appropriate location. Follow existing patterns in each file: - `doap.rdf` - `debian/changelog` 1. Generate the content for `CHANGES.md` - this is one of the most time-consuming parts of the release cycle. It is a lot of work, but the result is well worth it to the consumers of Apache Thrift: 1. Find all [Issues Fixed but not Closed in 1.0.0](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20thrift%20and%20fixVersion%20%3D%201.0.0%20and%20status%20!%3D%20closed) (adjust the version in the link to suit your needs). 1. Export the list of issues to a CSV (Current Fields) and open in Excel (or a similar spreadsheet). 1. Hide all columns except for the issue id (i.e. THRIFT-nnnn), the component (first one), and the summary. 1. Sort by component ascending and then by id ascending. 1. Create a fourth column that will contain the contents of each line that goes into the release notes. Once you have the formula working in one cell paste it into the other rows to populate them. Use a formula to get the column to look like this: ```vcol Issue Component Summary RelNote THRIFT-123 C++ - Library Drop C++03 [THRIFT-123](https://issues.apache.org/jira/browse/THRIFT-3978) - Drop C++03 ``` For example, if the row above was row "1" in EXCEL it would look something like: ```text =CONCAT("[", A1, "]", "https://issues.apache.org/jira/browse/", 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. 1. Find all [Open Critical Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(critical)%20and%20status%20not%20in%20(closed)%20and%20type%20not%20in%20(%22wish%22)%20order%20by%20component%20ASC) and add them to `CHANGES.md` in the list of known critical issues for the release. 1. Commit all changes to the release branch. 1. Generate the source tarball. 1. On a linux system get a clean copy of the release branch, for example: ```bash git clone -b "release/1.0.0" git@github.com:apache/thrift.git thrift-1.0.0-src ``` 1. In the clean copy of the release branch, 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 ``` The result will be a file named `thrift-1.0.0.tar.gz`. Check the size and make sure it is roughly 4MB. It could get larger over time, but it shouldn't jump by orders of magnitude. Once satisfied you can exit the docker container with `exit`. 1. Validate the contents of the tarball Unpack the tarball in some empty folder and do a fresh git clone of the branch into another. Now compare both folders and check for any files missing. These need to be added to the appropriate `EXTRA_DIST` makefile section(s). If necessary, commit the changes and repeat generating the source tarball until no more differences can be found. 1. Generate signatures and checksums for the tarball: ```bash gpg --armor --output thrift-1.0.0.tar.gz.asc --detach-sig thrift-1.0.0.tar.gz md5sum thrift-1.0.0.tar.gz > thrift-1.0.0.tar.gz.md5 sha1sum thrift-1.0.0.tar.gz > thrift-1.0.0.tar.gz.sha1 sha256sum thrift-1.0.0.tar.gz > thrift-1.0.0.tar.gz.sha256 1. Generate the Windows Thrift Compiler. This is a statically linked compiler that is portable and folks find it useful to be able to download one, especially if they are using third-party distributed runtime libraries for interpreted languages on Windows. There are two ways to generate this: - Using a Development VM 1. On a Windows machine with Visual Studio, pull down the source code and checkout the release branch. 1. Open an x64 Native Tools Command Prompt for VS 2017 and create an out-of-tree build directory. 1. Install the latest version of cmake. 1. Install chocolatey and install winflexbison with chocolatey. 1. Run cmake to generate an out-of-tree build environment: ```cmd C:\build> cmake ..\thrift -DBISON_EXECUTABLE=c:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=c:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DWITH_MT=ON -DWITH_SHARED_LIB=OFF -DWITH_CPP=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DBUILD_TESTING=OFF -DBUILD_TUTORIALS=OFF -DBUILD_COMPILER=ON C:\build> cmake --build . --config Release ``` - Using [Docker for Windows](../build/docker/msvc2017/README.md), follow the instructions for building the compiler. - In both cases: 1. Verify the executable only depends on kernel32.dll using [depends.exe](http://www.dependencywalker.com/). 1. Copy the executable `thrift.exe` to your linux system where the signed tarball lives and rename it to `thrift-1.0.0.exe` (substitute the correct version, of course). 1. Sign the executable the same way you signed the tarball. 1. Upload the release artifacts to the Apache Dist/Dev site. This requires subversion: ```bash ~$ mkdir -p dist/dev ~$ cd dist/dev ~/dist/dev$ svn co "https://dist.apache.org/repos/dist/dev/thrift" thrift ~/dist/dev$ cd thrift ``` Copy the tarball, windows compiler executable, and 8 additional signing files into a new directory for the release: ``` bash ~/dist/dev/thrift$ mkdir 1.0.0-rc0 # copy the files into the directory ~/dist/dev/thrift$ svn add 1.0.0-rc0 ``` The layout of the files should match the [current release](https://www.apache.org/dist/thrift/). Once done, add the release candidate and check it in: ```bash ~/dist/dev/thrift$ svn status # verify everything is correct ~/dist/dev/thrift$ svn commit -m "Apache Thrift 1.0.0-rc0 in dist dev" \ --username --password ``` 1. Verify the release candidate artifacts are available at: [https://dist.apache.org/repos/dist/dev/thrift/](https://dist.apache.org/repos/dist/dev/thrift/) 1. Send a voting announcement message to `dev@thrift.apache.org` following this template as a guide: ```code To: dev@thrift.apache.org Subject: [VOTE] Apache Thrift 1.0.0-rc0 release candidate --- All, I propose that we accept the following release candidate as the official Apache Thrift 1.0.0 release: https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.tar.gz The release candidate was created from the release/1.0.0 branch and can be cloned using: git clone -b release/1.0.0 https://github.com/apache/thrift.git The release candidates GPG signature can be found at: https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.tar.gz.asc The release candidates checksums are: md5: sha1: sha256: A prebuilt statically-linked Windows compiler is available at: https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.exe Prebuilt statically-linked Windows compiler GPG signature: https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.exe.asc Prebuilt statically-linked Windows compiler checksums are: md5: sha1: sha256: The source tree as ZIP file to be published via Github releases: https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.zip ZIP source tree GPG signature: https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.zip.asc ZIP source tree checksums are: md5: sha1: sha256: The CHANGES list for this release is available at: https://github.com/apache/thrift/blob/release/1.0.0/CHANGES.md Please download, verify sig/sum, install and test the libraries and languages of your choice. 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 [ ] +0 [ ] -1 Do not release this as Apache Thrift 1.0.0 because... ``` 1. If any issues are brought up with the release candidate, you will need to package another and reset the voting clock. Voting on the development mailing list provides additional benefits (wisdom from [Christopher Tubbs](https://issues.apache.org/jira/browse/THRIFT-4506?focusedCommentId=16791902&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16791902)): - It creates a public record for the vote, - It allows for participation/evaluation from our wider user audience (more diversity in evaluators improves quality), and - It provides more entry points for potential future committers/PMC members to earn merit through participation. ### Official Release 1. Send a message to `dev@thrift.apache.org` with the voting results. Use this template as a guide: ```code To: dev~thrift.apache.org Subject: [VOTE][RESULT] Release Apache Thrift 1.0.0 --- All, Including my own vote of +1 we have N binding +1 and no -1. The vote for the Apache Thrift 1.0.0 release is ***successful***. Thank you to all who helped test and verify. ``` 1. Use svn to checkout the release part of thrift (similar to dev) and copy the files over from dev, matching the previous release structure: ```bash ~$ mkdir -p dist/release ~$ cd dist/release ~/dist/release$ svn co "https://dist.apache.org/repos/dist/release/thrift" thrift ~/dist/release$ cd thrift ~/dist/release/thrift$ mkdir 1.0.0 ~/dist/release/thrift$ cp -p ../../dev/thrift/1.0.0-rc0/* 1.0.0/ ~/dist/release/thrift$ svn status # verify everything is correct ~/dist/release/thrift$ svn commit -m "Apache Thrift 1.0.0 official release" \ --username --password ``` **NOTE** Once you check-in, you need to wait about a day for all the mirrors to update. You cannot send the announcement email or update the web site until the mirrors are updated. 1. Create and push a tag for the release, for example "v1.0.0". **NOTE:** All new releases must have the "v" prefix to satisfy third-party package managers (dlang dub, golang, etc..) **NOTE:** You **should** [sign the release tag](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work). Since you already have a GPG signing key for publishing the Apache Release, you want to [upload that key to your GitHub account](https://help.github.com/en/articles/adding-a-new-gpg-key-to-your-github-account). Once the key is known by GitHub you can sign the tag. ```bash ~/thrift$ # make sure you are on the release branch ~/thrift$ git checkout release/1.0.0 ~/thrift$ git pull ~/thrift$ git tag -s v1.0.0 -m "Version 1.0.0" ~/thrift$ git push --tags ``` **NOTE:** If you get the error "gpg failed to sign the data" when tagging, try this fix: ```export GPG_TTY=$(tty)```. Alternatively, it may be necessary to specify the ```-u ``` as an additional argument. 1. Create a new release from the [GitHub Tags Page](https://github.com/apache/thrift/tags). Attach the statically built Windows thrift compiler as a binary here. You may find it useful to use the button that automates release notes. We have *some* automation in place to get packages published to various package managers. To leverage this: - Please first create a "pre-release" and save. - Then look at the Actions tab and look for the prereleased action. It will upload packages to package managers that we have automated and support "test" or "staging" modes. - Go check out those packages and make sure they look correct. - Come back to the release page and uncheck the "pre-release" checkbox and save. This will cause another action to get launched that publishes packages for real. 1. Merge the release branch into master. This ensures all changes made to fix up the release are in master. ```bash ~/thrift$ git checkout master ~/thrift$ git pull ~/thrift$ git merge release/1.0.0 ``` The merge of 1.0.0 into master should proceed as a fast-forward since the 1.0.0 release branch. If there are discrepancies the best thing to do is resolve them and then submit a pull request. This pull request must be *MERGED* and not *REBASED* after the CI build is successful. You may want to do this yourself and mark the pull request as `[DO NOT MERGE]`. 1. Update the web site content to include the new release. The repository is located at https://github.com/apache/thrift-website and there are plenty of instructions how to update both staging and live web site. With regard to the release, its actually quite simple: check out the main branch and edit two lines in _config.yml, then commit. The build bot will update staging. After checking everything is right, simply fast-forward "asf-site" to "asf-staging" and push, then production site will automatically get updated as well 1. Make an announcement on the dev@ and user@ mailing lists of the release. There's no template to follow, but you can point folks to the official web site at https://thrift.apache.org, and to the GitHub site at https://github.org/apache.thrift. ### Post-Release 1. Visit https://reporter.apache.org/addrelease.html?thrift and register it. You will get an automated reminder as the one who committed into dist. This informs the Apache Board of Directors of releases through project reports. 1. Create a local branch to bump the release number to the next anticipated release: ```bash ~/thrift$ git checkout -b bump-master ~/thrift$ build/veralign.sh 1.0.0 1.1.0 ``` The veralign script will set the version number in all of the language packaging files and headers. You do not need to worry about the manually modified files at this time. You should however ensure everything is correct by looking at the diff. 1. Create a pull request to advance master to the next anticipated release. 1. In Apache Jira, select all tickets where the fix version is the release and the status is not closed ([example](https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20fixVersion%20%3D%201.0%20%20and%20status%20!%3D%20Closed)) and use the bulk editing tool to close them. 1. **FIXME** Ask someone with admin access to Apache Jira to change the fixVersion in question from unreleased to released, for example: https://issues.apache.org/jira/browse/THRIFT-4686 1. Ensure that the [Jira release page](https://issues.apache.org/jira/projects/THRIFT?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=unreleased) for the version has the same number of issues in the version as issues done, and that there are no issues in progress and no issues to do, and no warnings. Finally, mark it as released and set the date of the release. * [Report any CVEs](https://apache.org/security/committers.html) that were fixed. You can email `security@apache.org` if you are not sure if there are any CVEs to report. #### Third Party Package Managers See https://thrift.apache.org/lib/ for the current status of each external package manager's distribution. The information below is from the 0.12.0 release: > This section needs to be updated with detailed instructions for each language, or pointers to the README.md files in each language directory with detailed release instructions for the given package management system. * [dart] Releasing this requires a google account. * You will need to install the same version of dart that is used in the docker image. * Go into lib/dart and run "pub publish --dry-run" and resolve any warnings. * Run "pub publish" and go through the google account authorization to allow it. * [dlang] Within a day, the dlang dub site https://code.dlang.org/packages/apache-thrift?tab=info should pick up the release based on the tag. No action is needed. * [npmjs] @jfarrell is the only one who can do this right now. https://issues.apache.org/jira/browse/THRIFT-4688 * [perl] A submission to CPAN is necessary (normally jeking3 does this): * Checkout the release branch or tag on a linux system. * Fire up the docker build container. * Run "make clean" and remove any gen-perl directories. * Inside `lib/perl` run the script `build-cpan-dist.sh`. * Upload the resulting package. If there's a mistake that needs to be corrected, increase the suffix. (_1, _2, ...) and upload another. You cannot replace a release on CPAN. * [php] @jfarrell, @bufferoverflow, @jeking3 are the only ones who can do this right now. * Once the release is tagged, one just has to hit the "Update" button to pick it up. * [pypi] @jfarrell is the only one who can do this right now. https://issues.apache.org/jira/browse/THRIFT-4687 * [rust] Any thrift project committer is allowed to upload a new crate. If you have any questions email `dev@thrift.apache.org`. thrift-0.23.0/doc/images/0000775000175000017500000000000015165535636015407 5ustar00buildbuild00000000000000thrift-0.23.0/doc/images/thrift-layers.png0000664000175000017500000006511315165535636020720 0ustar00buildbuild00000000000000‰PNG  IHDR1¡f±ÊØsRGB®ÎégAMA± üaPLTE $$ ($,H,DD0Pm]Y0Y}4]4a‰uÎÿü¿uNU?¨šHII OjLJJRcRR¢“’…Ô˜””(¤Æ¤¤D!5&%% ©1))QHII‰BjLJJRcRR¢“’…ØÆÔ}i< À»QÝ—šqÛ5ïK|Ÿ]óBg«ªHJJD<Æ ™C¨àoÌdP,:çgÌÀ¼eãx<0o£z„Ly?/÷o‚Û{ œø¯I¹°ñS·(\®øCWFøn$ù](cü›à®OjLJTÜÆ Ìk®û/òDéЄԘ”|qÓø¥=j†_·è\Ý—¾¤R¯“,IÂã4ëÂH>¬ÆÌ ðLÌ–‹vcŒêa«eã(ŸKÀ“jú&™n¦¼¹«yj‡tg•/¥Ø÷H7Ú±7Am­«4¶š0k`'[k”z´­vß)ncæ-:'guÿ…³œ·ô`kð,¯¨Fò!¡Žó“]´Þ~ø¶cn„â(‹9ùÆkW*ëi¶ò¥Û3\!ä°z9áh‚ìÈ[i®ˆÔÀ*ÎÜRÖ8Œñì;åÄe 'Š:º×ñÑÙÊj•6rä§Õ”>ü$§§i °cnT÷%.ˆÃðFFbã€o•/¥ØžQšgãh‚Ú®Ò|#5°Š3·”5c<ûN¹q#ÉDy¥£*o ~ÖʵšÝH;cCÛVÖF’{j¹1+À†U¾*ÅöŒìÊör{Ô>u•V›©‚¬â¬-å9çãÚwÊ…ˆÓ˜ã|Œíâ¼QÙe¥'¡ä °’Þ\!’6†¦?´‰½|UŠí)Ãz¹£ jŸºJÛ±Š³¶”G^c¼­M¹ p£ g¿È»1˜ÿä™.ùxbï cÌ]¡”Eçhs{ùFÖšÏÈ‹ùr<²5!¬1ÆzkKy¤3ÆØ$å‚ÄiŒJW€¬PÙEɯÛ2ƈ ¶ä³'¾"¾1¶]ñ«ÉWûfªÛ3²+y9p4AíSWi»1VqÖ–òœ×{mR.@Æ'-|±JèÒ!U%‰JcóÔØJ>ëTÇ ¾1ö]Q5hÑ^¾*ÅþŒªyæïl‚TVSi»1¶âÌ-¥n¼•°4ûN¹qcÎ8(Ep°Þˆü@šp’`þNIÉ“žãóhµ™|rÒ ¯!±'Ÿý)ÙUC^o–/¥Øžá:Ï»K½\ n‚ä¿®Òâ×À*ÎÜRÖð #Õðî;åÄaŒy„¥¼Cv!U$oð`@%%¿‡G¶äSÏÙR(¤1ü:ÚÈ õFû®°±RÊ*ßpÀ¶Gze³ñ WŒÞœ*aÕ‡+bÔÀ*ÎØÒXÃ¥wA!í¾S.<œç1vTvM*怑’R*”´1%P…”'¥lŒý<'%¥4(ecÓ³…”’Ãߘ””/©1))QHII‰BjLJJRcRR¢“’…Ô˜”ÈŒƒó ‚â¤äÉWŠÑÔ,5&%ãçϽ3 ^K÷Ës8žË.¢SˆJ1šš¥Æ¤D¹‰Ä!^N *ìµÑ_žŒ=Ì¢RŒ®f©1) ÜDj"™%åæððèÉ“ñ”)L¥MÍRcR"À¹id泉@% Ÿ ŸµïRäSBT-Ü÷ÔãÈËõë·`òÙ¥ñ³T©Ù”å Ruµ¦fʘá9ߊÉ?ZÜËÜãå›.„gn«÷màÛd]¾ÜÉEß)Kùr—Ö:WódnŠëI¨°˹nÉÄ­~Íš½lÌ”7'Á¥Ê˜Ì÷7¯]¿¥³ÿàÏ£žÈˆ1T©¹IUŠ™1¥j†¦fʘ#s¿‘ÿÛË?Ù¸ßÎcD1Ó1^õ"”­žß&ëòdÁTôø d9On;G¥µ&TÚÜžóãã=se)O,ç–&·zøb3uNFr!/—ʘ‡×®ß@yu1/zö 1æfTji"dn6ŒqÖŒhŒ(bGLaD…^òEDQèt ZϺŒ?Ÿ˜1gÏ#Þ‰ó+¤e‚ÆœMÒ1‘¸)cºûؘ›—~;–ZÆ<´zÖüI¢RÌRËGÍ¢#ŠØSE§‹Ÿ/l ÒÚÎø¹ÄŒAŽ'gÌ(™ó sþ|rÆüê|2q aÌÒ‘ûä‘ïJØ”¬1îšE5F±!¦(Dëbø"²„œ,hEg;?›˜1Èññs‰3Œ¹¯1÷޾7÷ÉbNævþ*ic’ˆ[=+£7æ;£Ô=cÙ¸Æ|ï¡Õë¶ì*Ecœ5‹dŒ8bGLaD…C—h'/6 k f>g‹eÌpó$3Zc@Ç6.,cD;b #¢Z]ž¼Ø¨c²¿¾É  $O–î|)gc¨eß^:t`bÏ·;&&ÓS{Z¾–¾pŒEìˆ)Œx"„Ó%„/•dLKvsÿh ýÝ;²ÿ›™_û9ålÌáogÆî[:U¾3|ß·4óªÌáìHË·;Æ.cÄbŠBDQ°.ù¼Ø¨ cî½ÆdöcIÉÃãÌ6µÞMyÏÊð·t¨ËÔaxŽîgó ÙÔ Gìˆ)Œˆ¢pèûäÅFóÍìÓ˜feLeŽ16c0΀ïŒÞ‡áæ1F±#¦0"Š Õ%ÆÉ‹J2æþQLÃÌYÙ…` ©2påÀáìhåÏÊD;b #žát‰æK‰”Ú&¹ù&Nþ­3ÿäéð™áùØ.çJYŠh MÇpÊÿ혔 ݇…=CÅ4Æ;¢ÙZIíˆaŒ8bCLQˆ( Ö%±““`Ì=CØ‹#ù$]²4¡ò%ؘ¨ø£N}´U oÌýæ['ò„†8ÆÄ  Æ„kh)u6ùá Ž1âˆ1…Q]’8y±1)Æ`8pàLŠc &8ßÌúÔ&ÒC¶«œÆpç‹aL3©Ëy‘Eìˆ)Œˆ"huÉïäÅÆä£fO÷ e'èÂÖ½#ÍH2ã]ÜN uÏ€ª b¿¾o„ãš$ÀÄG3úøÃÍá6ÊKïå·N¨ñ‡áˆ'K ÜŒ¡ö¾5DÆ|ûÀz[wÑŒEìˆ)Œx"„Ó%¶/“d öÒ,gè÷ qÝaØ~åþa䈊6+£‘„ª²í›Ù1ºdêmÃ_ žDž™õ¾/êo 7‡Ûh{)¬¤Ò¸ô—M§`ågLη†È˜ïŒ¶àŸí.’1âˆQ…Q¬K!N^lLÚ#ï›ð¼”K”¦|¾>™Æ zTU:öseé!evÇ6GuïðÍÊðÇm4^J÷‡›Õ‡àä9×xå8+Ã_Ð[C|Ó ‰ðøÀ¹ oŒ(bGLaD”ûÆCÇÉ µLòÒL²1Íb _å2¡©‹'/‹e yìk UÚK(cÔKi̺Ø0F=WÆèßâY ;¸9Ð,w!Eìˆ) «‚Ma Œ:¬ÑEfcÙý÷ÜóßGanÞº€I3Æœ•±1÷u kLc2ÞÃx±Œé ÓuJe3fW³2仆0ÆÈKùÊÂá* ³2õ—]ž³2ËŸ·†Ä˜8³2‘ÄBLaH—ûÿi„Æ–{”1b‹M2|k¤Ûî¹wHÛ{‰l eB8Bžù+c¬;þøâ¬ût!ÈW¥¨˜øCÃŽü.cÔõìsÌÙÜ„1Æx)ŠRolCÿÉs²âÃI¨¡XÆø¼5$ÆÄ9óO D†}¡¡å¸ÅØ’=¬=ycp4¾‡ŽJÉÁêk™ƒÐÆp±¨#o$HBbI¦lŠzcœùsŨN9Þß)c*þÌßë ëbøÂïºôÎ -Ž7öéЙ(á‰L€1Þ{ØÏΘhÞßñ7&FÝŒ‰XZc¢QchÞ!ÊEncD…C÷ç`,\Ÿƒ¡p$ˤCg~_Bñ%c4ïïø§nþÆD-­LA3¿}€?%\ƈ)Šº$ð¹±\Lš1@½©Cßá™Õ~ÛšãrÆh4Dª[°1 tiel @«cCjÄé8l{B3…7&œ.I|Ì2“5+C¢È›:tIÇI¼í E2&NÝge‘J+ßY”¯ÈÐ×eÐÌ¥C-¶'4„4†u‰xòRH&ÇäÊX @tÈU×»(‰lOh(–11êtæ­´r5VH3÷àaË·—Ž.¶'4„1Æ¡Kè“—‚2IÆààk¼©Ãiƒ¥m|ÍÜxÂKÑŒ‰^· c¢•V¶ÆÐ»¨òK{ŒïÌÄ6&¤.Åôe’ŒQ_B‘7u8mîÆ­ý /E2&NÝü‰ZZ™ÓAS¯fùŠ ò4óÛö'¼ä2&”.E^˜I1Æø ¿©ÃisÏ"Ûžð`LŒ ¾ÆÄ©›¿1QKËaLŒ‹¸E1†~ã ·J ‚sØb{ÂKnc4ºLÞlÌ`Òfe‘ñ7§™‘/ÎÊ¢<+‹B°1hh䋸E›•E&—1_DÅdè*Å€ç!/—­1í’k¶4â丈[ÞÆˆ,“~òb£Œ‰sA¸,‰s·ŒYJáäÅFE+¢^.Oc`EÔ‹¸åkŒ¥KIÌÆ *Øh—p‰25&úEÜ27¦Ät•`Lœ ÂeiLœ‹¸ålL霼بcâ\.Kcâ\Ä-_cJéäÅF¥ÌÊ¢R¶³²¨”¯1"Š¢Dt©1 ‡ðÆ”Ž. 5&`ÌÙñó¿JÚ˜9þqû©ÒàßÄyèœPi¿:7ú²œ³T’96*ÿÕCû“jxA!COtïíÛW?WžüY¸o_ïÎöúµ«ã3n“Y(E&Ä ŒÙÔ°vyíº-fÍ”1çEiX‚ŒþÊm ²2¡ºâ4Æ8X$ÀèY †ãçHÀ}çÑ‘—_6ì’Îñ#d1Ïcˆ1Ù´¦~á¥'ËÍ –ر1'fþa‰²…ëç 8uyBvgÑ‹¬+,µæ'?ž~ò©}+ªª¦L›65Ó¢3¥êRõÈW¯£kV??êç÷'ÊÌu[¶oßÞÙÙf0Æ£b5ÔÞÞ¶iÍmhºäzL:3³%Ú1æèÌ¿ŒÎ_ôp;ó…/üG“?wñ™Ï|æS&Ÿ>Î|ÌÍL¤›?”ý‡À[Agå¤F [½P¡™GewÛÃGIš°{þØÌ·ÇÅút!Œ¹dfá¹dZÕÅꃺˑ»þ¼_ßÚÿü_üâúOÿ×çê3b¶›?¤ô~¿i×®þþþÝìK aÔ'1;žèδµ}bÊ”Kfþþ¿ýýþ-‡:þ7‹ß¿dꔫV¨÷c\cLtcôº(_bêâõ…Œy›+hãí°ÆxkèªTIáÐÌì÷ì9´1yˆJÆœ$cŒO°“18/ŽÏ|'kñ×û©wYƨ÷Þ}ŒùKjÛí·S¤Öf7ºûQ¬1GœÜ²}ÿþƒü922úœLŒyö‰î™Ììª)—Ø[åÏ_üå_þ¡zI%ˆð—L©š±iÍš†÷'1_ŒhL .þ¾ 9¼¾¸ÂìdfíI÷;i'CU—/ÿøÌ]î=¿ΘH{öìø“‡1'=ÆHºçBTPHrüõ_ÿ Q|•ù2£ª÷Õ?q3¸Ë¯µÜ<4ÈÕ–ÿSÚ!ýjïX1‡ùwÿÎ0†d.`bøb3fÇŽÙU¿yÉß:›ªGZ/!@ ÌÜ%>Ç|‘ŒÉ`®×ð}ÓeŒßñDK€.¶¼§‹ÄU"êƸõã!ŒÑÔÐY9©’B£ ˜Ùã1fKî(EUökßóÇfž8y.–1b U—-¢ %‹Y=PÆÐçýA#¹eôZÉ1߀ QéR Ò00æÛÏ˘'{{ɘù9ÍáC‚aDƒù*³cGÛ&ݧýßo RBã‹ÚG€.Î(ªôÈ© ˆcL~º¨JaÏ=î=ç4& Q?þ±?™yôäÛ1ŒY€dÊ—Ûoÿ¢Û˜ýƒ=­µµ”^mxãj¢Ë£Òµsâd|]€eÌ>2¦V‚àE"b 1¨p`8$EÆðG15ßÁ mŒVµƒ˜ºúBÆœˆfŒ·†®ÚI•~ºÐž£“Œ¨È¢8ÆHR’¾“1•¯1GƒŒùKc⯠¤•Œ4 ª©ÒJˆ°bæöñm!l3X6F"âF¢ãŠ#BiÒ•1ü²ØÆèä‹„L°¢FHÔü‰fLT]\Yë¨S4c5Ž1’ @r 9º0_øâL‡1MÁÆ8[+e­•6šØÏoÌŽ·µÖçˆØŒ™`Œ„I‚#Hh‰IóejiŒî{þ!ŒIRgjÁM •“*)‚uŒ‰«‹~Ïá<`$ ˜`]œ¾`>õ¹Æ$gͧ¤#Ή‘=JÚØ:ž(c8$ÑA4¾P±ºØÃGÚ˜\Ý訛§U¥dŸŠ°Æ$œ@‘4 $4³13¼³1ÔS] kL~­ÕǹàÆH„€„È#+BÒ¢¼ŒÑꢊ©KX_Âã­¡«vR%EˆnáŒI<"#IÀH"ÿÑÅ«‹áKXcüâ,u67\k oŒDH„؉cEÈ ¸Æèä Âåõ…#A˜¨º¸úѯN!Œ)„¨¡‘,’Œ¿/VýLL_B·µ¹ã\Hc$F@"䉑Èj‘˘˜ºØÓÒÌß’ËM •“)BërS QC#Y$ ·.F2ˆ/\?Î]ìä2¦ q.˜1"çì^ôâ÷c"ƒ i|1Ê“@‰’Irº€`cru££nžnT•’y4¦p ÂÉBÒ€pŸ¼p.X¾Põ,œº€`còkmÎ8Æ éu_8,ž¨ÆhuQåÆÔ%†/ÆxkèªTI­A€1…L \ÆH’„¿.fõ,\à `Œ_œ¥±ÎæFnmŒ‘å]!«E‚žHÆèä Âåõ…#OàgLT]\ý¢N~ÆXT½1œ@Ò€< \º8žîtÐèüŒ‰ÛÚHqNÚ‰³1[xÂS{Zšù&dhÑÔÐY9©‘"Ž.@kLáEÕãñEÒ tà %eWÏÄG 5¦XqN؉Q8]8.Žð„4AÒø"åÅÓ%_|Œ‘Z™¸*'Ub<ݨ*%¥¡5FvhâܳìS3üŒ‘, $ ½.” fõ,ü}ñ1†Ë°¡ ‘Ææhm”8'kŒ;H®XdµÈÀPÆhuQÅr¤æÝåŽUvâø]ùè’m”zrcÕŽ‘j)lõ²UJŠÎAncœ;NHTcTIÆ• ._80~³1ƒÜƨb¤­fk³]¸q·6ÛØÚ%Ÿ•GD!Œ‘øÝèbÃ-4ñÉmŒ¿.ó‡h£‰‰®Z2F… ÌêúóùGí¾d±Ññ»Œü•!ù#­•^”ªµÒf]þÔOêÅý(•’‚s’Ãçž©á”;ŠûEÔõk@Nd'>û…Ïåi ·–Jâ¶uóî~ÄÚjmŽ>-Ž1®EO.c$86(NV^1pÄn %Çò.à sç#ñ cŒ½r@ªDÀÕfÒF;È+üqî;Ìš9RÕ•ŒË™kd»¾ŒŸ«‡úPé.Û5Ôø¹¼Œ1Z‹’êÐÚå]-öÖR˜éOµVâ<¹ÆHŒAR”£wñl,dx¢Ce"Rfbð„uþТ g>ÿùe£8}ÉvÑð–¥9›:ÂÐp cîäÕûü3P˜n'Bµ¤îm‹ñŒ‘ÚIÝ캠a̧æÞE]ùyUat£ÚŸªbõ±a+Ù‡cœ;æ=ÏQÇ‘Ï`H;ùÔüìu vˆ÷üùç¹ ÎdñGQС5†Ó€qûºÐL£Kž·£>twûòãw!0 ˆo —£Z›í¢±#)áC˜ŒÓü"ÛÅSö.:Xš-¥>•Ö.Á22ÂlüâщãëèI!ŒñŽÀ|@é¢ÙÂó… ðD2†K´'ÆT§xó‡  òmþÈãtp‘1†}¡áÈK¬¦˜!pXRRKêþ.çJ´Æ8+ÇÙj@yuóYò> œùü3Ü“ªfÔŸ¦NváƒÖížqìÂ-vÌÓ@iÿ#Æž±·Vj¸Ê% €»ýÑMÆž›w}ñöåÐ)1Ê)ñÔ É€JÅ5ÆÑZ”„vâOŒùÔ§”1j.NK 6µÔl%”Û"Ý«>0IÚ˜¿ÕÄH…ç‹ÑÂÞ*Ξ*3ÄäMi⡌Q“15EYTd𥇜ÆÒ⣴εÒ½1ºô ºqà³èÅÏá(oÎZ»j¹fd‹Ôý1º=#ôjÏ”BŸB£ðO=hÏl µ”@ÕdÇ‘Œa_ô£‹yi,ËãK+âÏ)ñ…Ï}N¥Äçp,kŒ½µ”\u˜ñò¤×f u?u=Œ1Zжq+ï|ž˜£‚±È÷f0É#áf„Üá¡Kc¹ÂÒ*Ö« 0¡ÁØ4æ“K”1¤ ‡ƒ òÃ)…±$ár®ôGkŒÔÌé‹u .ýä'âßÈÈûÂt2†ÿx¾h‘ý:E•hp ñyþ©XОÍêƒÏâ§Î͵)aÇÏi' ÈN ¡d M/è|„–Ü6ÆuèëÅ;G0-¨1*!ù•‹¸áÉe —ë§ Èv!;lÆPjb6ÆÆ`ÌUqƒ;š…ðŒç%º·-Æ1Fª¤pé‚*9ó§²Mc09˜8¾Î4f‰T8­1²O…µg¹^ôqi”˹‚¤j@k)fÌÆ'ÎI#‘!ò8˜„0F,1 Ð¥H¾øãîFU)yERh)|éñŒ%¢ ÐS¬8'lŒÄ†È'<9M JA 5FjeÏZÙÆP 5F*TXÊݱ¥4t©1+·ß.½X0Rc<„2¦Ät©1©19˜1æ ‘ëÿ(+E]Àn ²€ŒùêWÿ¢ÀüÕÿ^)ƨOû'Àßä2¦ué³¢ªjÚ%E`š2¦~-³½lgeï’æ$À»~3À˜£3ÿ°Dù®;oÇO§®·¼è1¦çYWX>ë6¦H\¼¯—Œ©UcÌ`qâ<óÅ䌙--IŒ1ã'¾ø|Iò"²‡jhAu-Fe±gWO¾]œ(½xô3rèÐÝÈ‚M—J9=RÆ,Nk½qŽŒ1bµðbiJBL]¨"Ëk½Æœ@–"G=ÆL©®È[WOŽŸ.ÆžÑä“* ž¥,Ø·ja‘È =65ØŒ)Vœ%¾1·Œé]!MIŠ^ †Ýu[úÆàðyâhIrâ¤'žoŸ<)+ ô²C“"EéäÉ·ÇÏ" :ºwöí+"½;2kp£Œ9Qœ”@k%¼1áX (VFHhžê0fiXš¼í²‹TWïž‹¥·ß§,x™³ ·Wú®Ðô‚̦úóŘŸá`UòÆ2fGÒ±²…Äc eÃx ¢ñ…µ…D¿ç¢D‰ö#ÆdßQD2mõ K c§‹ÔÚüP±ÚÜžÉH3’$Ó¶†C²²©ÓmLJ)adA[[†h+›êV,¶#•)q¬Xq°TS’ÂIjL‰cdÁ&bMq¨¯o@vØŒ‘º”:öXIS’ IjL‰cfõÚª"±bÅ’Å ,ǘÖÍí…ÕŠ&5¦  ,8cÜmEaÁ‚…c¤.¥Ž+òEš’*$©1¥Ïø¹×8 6! fÏ(WÏ^è4¦lÆ+„jÁÍÒ–„¸z!‡DkÌs[KU=ƒ²ª°<'{³³[Ö–cFt`n¾f᥉ œ³²ýRŸÂ¢‹s$lG—¹Ò’Äx?‡„Ùå4æØGn)M>²ˆëç 8uýÈK²;‹ÝEÙóGgÉ'?†žènkÛ´pêÔiï*<Ó¦M½Ó$ˆ2fÿÏŸ›´8GCŪ½½mÓšÛÕ´©SgpHtÆ<÷ÑÿPš|TcÌe]aù¨÷à·µ(Qúã[ÆŒOvg2m §L¹äÃ…ç½Ó¦\¼ª¡a…õ~ÌîH… ‹&ÎÑàXu VmmŸH4VÓ§M™a„¤œŒ9ô1Vc>²ß³çbóÖ˜aÌÎ;VM¹äOÿôߘ?ýè´ª‹7­YÓ`¼ç¿°HÆ|dÿ˜„7&f¬2™ÙUS¦'ª?½ì¢ªþ”ŒÛ˜âD':]ô–; o˘·d‡cE2棇O˧ý»Ÿìí]Põ0¦Ðΰ1Ll¬ObÍwœ#b;ºÌ®úÍé–T¨þŒŒ1B²®ÉùÙå±ý¥kÌáÉ2æ‡nW‹f̱S6cVˆ1…åÏþÆìØÑÆÔUcÌ‹dÌ2±"c>--Ê›¯\c($õk—{¾SÊÆ¼êš͘W'Ýõ²ß¸äÏ€ôcø4ß;dc¶Õ˜ü¦e–1ûȘ¯$ª¯¼ÆpH4ß(Kñò‘ºG·É5¦°|…Œ1¾>Uì1&cÔw0Ù˜d`c8$©1¡(%c>ýiéÅ‚acþ2F93· Æè¾çŸãåB4Æþ[2ekLR±RÆøü2FjŒ—Ô˜Ô˜Ô˜(¤Æ¤Æ¤ÆD!5&5&5& ©1©1©1QHII‰BjLjLjLRcRcRc¢““…Ô˜Ô˜ Ϙ=Çç©?VÜ*ÜÒÿ½‚r5fO#ßUñ¶ŽŠ0¦ú=91ÑЯ¹hæ¤ØÃEH,ãŘfZmßÕ2R…o|I̘=´EØv&oÌžFu[ý Wuâ§꾫7Ççñ6A$cLõú+EcbÄ'ê7Ë×q¢V¿£n£ÅÐN$c gõ;u²81³3Ac¢Ä«pÆX·rO7͹•¹PŒ±nsÆ§ØÆTAê.;þS¾-ž1Žz¯¤'øÆ— ˜êsE2†(Ccôñ‰eLõÑÆóÇçÑ$ ]ŒÈ;|J°¯èºµúEY4VÓ¶Ëh>§"G²æÆf, “UA²©õJ]ÎxG5fÙyÚ UràVš(5òs²€m'Žo¤Zbãh'<´oàÓGìm̱WPvÆ Euü™i’ 3æêwJ@âdÈàEœ­ÐHüöàž¶52 e1ÎÐÑtO*È(Éx¥³òJa'òy ¬1Œ±ÆÇÌšBx÷hÏ{;y©ú ŽZȽ‚xƨ*ê3bÏ@Î×ç9Ƭ¤Ô@4Qg±¡(’1jÛ(ñ‰i ˸¯U"Ê©/bJMº—mUæzê(=‹[[A(Éx¥Y„:çáe#“è³2Å8ŒqìÀXà{®½–8gþö° X¢€`/!÷ cP­ÜÂäi §„i 5ÔÛ“~LöƒôñÉÃu-cð,ºFd¸÷q/A2Á#JÖ=<ÌÈJU’Sã?íÌ7ƒÈÆ`ZfVÔ2ƾc+Î7ZbŽ1Ü#b´D+°—{ÉÏÊBŸ1|I”Š?³wCR³2=ñ¡SûCk1 ó"Ž˜ü 6” ©Ì!š»ÔI ݪ•R’ñJ\<àã.ÐÄ9!cì;0øÞ?wó0ÆŒ-Ñ ì%ä^AùCs2ÕPü©N¥„£B©~Çi úÝ< y‡"%éÁèà¨Ê¯¦[+“P’þ<Hv¢ÏÊpCýF§ ¦1ŽX u¨Q¡ŒáˆÑ­@ÔBî”12M§†RäKó<&z|ò˜•áŒúøF˺T r¡ëu¾­Ò†¨ÔP¡Ã-OVª’¬WZP$ÉÇ[Ù‰sæO5Xf7ƹY ªòfzò™•£%1&ä^AÙà Ñhóbãù2»V¦'ª19aba¾2DQŒI–ˆÆ$G,cò%¿ó˜|(Ž11H‰HjLjLjLRcRc’5¦8¤Æ¤Æä 5ÆAjLjLRc¤Æ¤Æä 5ÆAjLjLRc¤Æ¤Æä 5ÆAjLjLRc¤Æ¤Æä 5ÆAjÌfÌî&-Ûeµ†Ô©1˜1g6Þõ% ‹ü•Iqs3v*ª2©1Rc.4cþõXDeRc¤Æ\hƼuìÇÑ”Iqs3qæÕ—¢)“ã 5†ŒùJáù÷¥bÌØ[•1Œécã=©1‘¸@ǘGÔÿç¿«ÿèÖÉ1&²2ncþ„øÊ•ÁÆüqi¢5FÖ­1²®°¸©švÉ%ï*8±1mõ+Ș ==ýÛ‹“c¢*c›•Í®úÍi‰…ê’iUÆûʬ¥ÑkÌ]²ªÀüøUwO>'k Ì]bÌ¡gŸVƉ‹÷õî€1µ`CgOOT§ÐüØmLDeĘnÄj®´$1®Þ×ûøêuƼõÒŸ+I~ü’;o'Þ:V”ºþø%ϱï_‹¥³1#0†² m†ô^¡™:W3Ƭn1`‹Û·oߺu?:ÇçÇÇÞ’øZDRÆ VlÌŠK¥- qéB6Õu[úÆLP K“cž#]L)/½êîɱ·ŽiϧÇÏŽàÀÙ½·oß¾¶UÅ¡¾ÆljX±ʬ^ßÚÚëÔϺH¥có’{ADQfÜ2fß&iKB¬ÙÇ!у+I^õƒº–•E³ç3ʼnÒá·Æ,cE£wGfMÃ’Å‹çÏ_Þš–f×ÑÁÁ—^’ZÇ­•ðÚ‰  ÅêÐPG÷N]‡CòÎìÜÆLŒy«$9£;¥²g4YœcÏʘŽ' LßSy#½L/È`R¶˜XÑPßÞ¾Ù–¦§çÅ£ƒ¿xõÍSRñXœÓ E˘Þ^iKBpH6ñŒYѰêæ)S.AYA`g¿û»pãMúЇ?üâÇ©ù‡§›Æ|Æ\þ;ï»þÆ›n’¶9áísÆm¿þ-Lƒ ex|2>‰™É´}"wΉ„ËÆåÓ§M™QßÐÀïǬsÏÊJؘ7Ý=“˘PEƼ Ïä4&\i×MñËiLÈÒ.û.„17\Ãu×ýŽ?ïyÏ{T\)Hl fe kÖÜV5å’ÿQ>üGbW>*°7&lÏGÝÆ\çcLÈ–NßãP(óÜwuÆÜµì9Ê Ã˜;vÌÓÆ?ú£›núæ†?¸á#…‡ÐИêÕÓôÓýÙå3»K×ϧýO²£®»ößÜr 'I§‚ ]ÚµÓ!ÇÏÃ¥™ÅII„«´ë®}÷w_;ýÝËnä­ë4\Ë\e"öÀeÌŠ5mmŸ¨úK>¢F‹ „èažÐ:Õ†„2ÆÑÐà¸måÁ9€±Aaösn˜ŸöïíMmäv¡¤1k”8 ÔPUíF2&Cïaò'1Ëǘc.cμ`Œ†œuíµ—Ã˜±± c¸´P ¦bÈ:`Œ³´•{÷wÒ¾{½À±­z¥³*×]'Öï½ü²YdLCãטÃiÃoÊeLõÖ[oº©zàV³¥ÙF©¬OܶÒPÄÿôæ‡?æ—»ŒÉÑFnPòH§(œæÜp³cGfSýZï÷cJÚ®¦ÅØ«~Æí•àW]uù-/ã,-G‚£¸éƒ¯ŽMœò5&biï^†##/sãÔÈm —qÕU¿ó^1æÿ“lÒ#ÉäÅL.« ¡ ·­žo@9ù…¯0/¶1ê;˜¾mtµRµÌy†f æ|ˆŒéíÍh¿QVÆ ÛQlÌ›ccoê‰\Z 1ÑK3Œqö¥ Š!¤à*‰°“é Î& ©daf”­ Àsæï0²l…,0æÕ[›'&æ]}s]m×5³znõ‹[c^÷fë_Rß k !M3 JÅ4PWÝðA2†¾Q¦ûÖrÙc¶Ó•Gþ)dLœÒüáÒÌâ¤$ÂU'…YÆØŠ°Á¥I1RŠ•f³#—1’B†/ª¶*С×Ç^OÆ|€m¼¾vàVs}¶®¹NªEPÕ¬¸“S»1s£´‘[HxG™›è’1•i ·ÑÈȰ cÞ«5†K‹šà@oŒ³´ð•sc±4˘œÇ_I#ÆL$å ïT¸ñF?cŒõ0ædÌõx€¿k`ÌûªG®‘šyãhLnaÜÆü±4Hƒ4O¡é×J£ÆŸ_Æ(ccŒ&FMp½1ÎÒÂ'8п41ÑK{O8c$‡fÉðÂ{e°çn¸‘ÉkŒ±†—oýÀõ6cÞ‡á¥úœaŒU7ƒ@cBÖiž`µÒã µ‚Îc*Ò«‰¡“ÈàÊ+ËcL>¥]é1&~i(Îc —f'%®Ò¸8)&”1’BgRIöjeíÙL$·1¤ŒQ5¾6Fd þ®k®›ud^s£TÍ·cÂÎiž ô¶’[A­|­¬²Œ1›È% DäLI~¯ÂeLüÒTqNc¸4³8)‰p•æHp—¦;‰^¹+«Ë¾ÆH ŽLR;Ì<âDróØ«6ëÈÄD×5vc Kõè<Ÿ–J˜ÆHën$/îVZ$*Íibì¿ò »1\Š›uä8fá×cÞ}«¶4¿¿òŠ+lƥŨœQšÝ˜Æ„ÆmŒ4Hë Zio&Ú‰VVš1±RÒÙQ–1×ÚJ›Õóé#ó®¯îª¸¦ºëšë²ó0¯».{üVwm¼+®ªmD9Ù:zXóâ­5]×HA Ø<܆aLìÒ¸81’Aá‰ö+y¤3æ}\1OÕ¸nR)Áªš‰Þ˜ðÂh‘Ö f#=˯. ’Œ Ρpe3ÆVl¨~ñÓ[¯!cèz(fe[¯¹¶¹S1Øyxxå•ÍuÍuRŽ`\9ª›o‚Û0Œ‰Zš³©^c$‡f&¹É1£D’$"<Æ\uR&dK¥j&Zc"ã5FZ'p#µ­tOÆì­Å2&ëJ¤<ñ1†zHˆÙQvc¤$Þ—¥‘³2zÓíÚkaÌUbŒ1+#cjúo•rÓ)ŠÈY7ßÊ™ÆHI„«4.NŠÜ¥yŒ‘,*‘|†I"‚v,)¤ps9“³¥ªjš–ꌉ"L 1®F†]Œiéúmy¤%x53ë•:1\P´ÆPûþÕŒssàÛQ6c¤,* 6\)Șë0-;~«Ý˜«øÌÿJ<¤ºÛf#eÅIp†1Rðo*³.Mi¾Æ˜‰äÖ%\"¹3\)…«j„¦nc" ã1FšÌVr#[39¼Ò:E5Æñ "Î×£É!Vµîªl£2& £<ƸJË•àÙyòÀ@Œù-Uš§rR3ªš¦4.cÌÒªÏQ `r–Þ&¼Ê(•/Ü5שE)èq%e’KŸ¢D ¡ì:­-„Çš–zã’..úÆÍ'!¼ÆDÆÏM+mÍ$S¸™h§4ÌM¥ãÊHé( ×µ_ c\ÅQiÎ~w•V3à<ïw£)mÖyWUÎs”P9»1®ÒšéB7‰W[c¸Ô+k^äs+,^Q3j¹¬3†3 ©då‘¢¹Ž?E‰Lªíºæ† ×øe’Íúe Ë Ïy¯ Ž›1…Ñc4RÛÌÂ43Ž1tÀB^ÐRÍ(Ò¸V’Ĺ:KKX%‹.cj^\tîø­²nÖºQ±9vÙõÛ³z>­e5o[Çö£¤1š”äŽc  ýs”äÁ2Ư4ÕíAýn3F_åöUÙ:T¿7BCBPõLc\¥¡8=1käŠQ©Wf뮬¥’ZØû!ÇmŒuäu'Ò76ãxk¦’錹–*†Ðã¬Çõ®UuWV½…s¾QQ½šíh³glvU¯1ÜFŸV†nf c߈þÀ55ƒ·^Q»‘KOØVãa-bÇÆ¢Û˜Q6Eõã¬Ø†Q‰€[È5lI;¢m­Ý(´Æø'8ɇS 6¦†jãî†1WæÐ%÷a’1Œq'¸”F¹M—P¯Ñ:‚«g£i*ƒÞ6J½’ÂÉ)c$ºŒÆë¸ëÌ$I¥kh𒍓¬Ñ 1†ºþŽ–fëäúH5Z™=~«1×vý6ŒÁ×8Œy½i‘a´ÆX­”jä7ÍÄØØÌÆpÓ0ÄSB·ÔmGbK÷ªÕÜ1èxZÇÆ¢Ç#'ð*.ÅòˆEÆ`;’mC£Ò‡áâäahŒAv³1-´µ£0'¦1Rá,§ 0Œ‘’{åÄe2y;Ú›\=Ã)‰0J³Œ¹òJUê\$Ë&c,]¬T’s`I%dÒïý}¼Nòƃǘ+` jF¡§‹ïò®ª„¶^gQ1ÔŠA5UUm¸Œܽ{÷V/»}…ñc?(8„q6M jfÆPGl¿&;G j9–•1|¥ñÏ\ÔÃ+-cð,Ò #9d¢GWµÔµØBÆ\!…9\Á¶„Ѹq•†Öra–1Õsc+͘•QiC•Ë’Y™ 1v¥x9‘8•èãÆ’.YßïۘˮÀ ƒº±1Õ/ÞŠ³+LçQ+ÑD2†ÆŒ¨áŒ1þëDúMè?ÿóÆmŒyT2Ö•±°ÍÌǘšêùíZ+Åcð¯ü4úÉ\ÔSs7x•i ÀdN3xk\clI$ ƒ` ^…º¢Ôž|q£+‘­sâ0Æ[šCõÂK£r`õœÆ8J#c0²ãü€&º3%„1ÎLR󡹎? Tiž‡£ï<•6^´Æ6&Ûu fd4Q´ƒMÆÃsÆxÿ·Ñ—^Òü'‹‚Ç—/öF†of cxîDçõ³à,¦fàˆÑj5Ÿ}0Ùè{sÑǘšQ§1ˆ©qcìÈ0†‹7ð3Æ›’œÞÔA€¡Éöà‹ÍoiŽá¥æ&äøSK>،ѕFÆÐf”7êü7°zbÌ»5Må«€rµD)B§D Œ1’E„=0­oÆágê¨Ý6JÚxñCÓ2À3Â:´”ÏüÙ 1æŠìÄÄÆ =Æü뫯ºÿ»ÑW_}ËW1n_¤…¦œa›Íz ’ DîŠ`Öó(«9Bôd-ÏÆE1œM–1R.R.ÉŽÄLáŒ"€Öw{‚‡Ä4Æ[šê}ÙN5Ål—†1ÞʹêæÉ†1~¥9šŠÌÔã1FÒ¸3IÒ$7.c¦ÿÖå2ÈoÕrã2fb쌟ÿ,“ñ#-$ì­D#÷D0¦H¸ˆZ|Œ‘ât”eÌ¿ñ¦$m³&ºtÕ±Œ‘rªnöÊE4FÊ<¥X5¸ù°‘G.]¢d’ÖrFWµ¸‰ŒÛÕFj¤½•‘Ž L%£’GˆÙQ–1—KAŒ*Mfß2‹ ·×ùj<ôýÍAÝ0F R¨âd‹(ÆH9ŠÈ¥¹ù;“¢wØË.›þîË¡Œì7 IcÌfÆh%¨Lcâw”Ö£4™•‰1Æ#ï Xgp¼Æ¥ÅÁkLœÒ¼Æ8¼±Éa 21êf´1ê¨ -$âùRŠÆ„"И|:ÊkŒ­4ž•òR›1Æ œ~$Æ9n+-.cTi‘‹sóAW&InDBg ”‘=F'qcÜ…X­gL¼²á0ÆYKÁïÂ9ŒQcKcTiùTÎaLìÒ|É3‘\Æ@™ø$m̳±¸Í¬4cbç ËUš­8cŒ…&týOfeêZ@NcÜ¥ÅÁ2&ŸÒÜÆÜdf’dE JÞÕÆ| ŠJ2&Ÿ$²0ñ–f\]®˜h´Æ¾J~k.c¼¥ÅÁ0&¿ÒtÆä›IÑŒ¡!:˜“¯/gŒ¬ÎØßJ¤4›1òD^ØŒ‘gâà1&ïo°1ôy(ØÑj’6Gje¾Í¬,cd]ž˜ÆÈržÆÈbžÆÈbLÜÆÜ(É6cj\ÆÐÇa68Ç”I0& [ˆÔ7©1±Èa Ý¡—0‡ÅÝqúxŸ bð¡©®ÚÀAâÆH=ó&5ÆMjL,ŒÁ¬ “2úP.}óEQj¶WCõNV‘Æ©gޤƸI‰E1WЧkù«Ù:5àԌʇNiI)©1ùPtcX6fž³}判ƃԘ|(²1-ô¢yƬŒ¿1…ó˜–®ßVïd¥ÆƒÔ˜|(²1ôµ Œ&ræÏï^ѵ²¬ñU¥–ôÌ¿ð¤ÆäÃ$ÌÊ"““,E4†ß^¿¼Œ1>A’¶ÿ9¶$I¢ ý7ì©1vœÆ\yåå±agÊÁ˜÷J…óá=%nLmdÞkó°Ö˜w—&ÓuÆÈº<™.ÆHqÓ/‹Ët.AŒIªrʘ|K›.ÆüÿlÌEÓ’à¢*$R/sÛÌK¦3²·X$cÌ¡gŸ†1‰µ‘‘†Â˜½Æ¼ºè+%ÊV¯1IÕuѱScc§–Ý¥–îª ¿~sfcR•Ûý ó\Þ¥Qõæ7lÚIÇß三´iÅâùµ55Õ@öŽ[>À˜ÓÍcLÂPCÛë[aÌö~‡1c¯îßýÃRdÿ 2ÇÁØ›/=—H]÷?ÇÆ{nÿ¸uwO\¶lß¾}ëÖÝûß„1\Zþ ´WÏà@6˜gi[·÷ô´´nîÞÙ·oÕŒ©IqéŠ}½;ÛæÃÆeßݸuëVÙ[v?‡‘^º6ãçFG0-ëÞ›hÕÐúµ«½Æ¼ylð¹çö—Ïiây u•Õù€¢‘”ÈÊ—Ðòƒ,L Ñz½r×nò=TZÞ<÷Üà1´›y–†v)cžÚ·¯71ö=Õ—io a–5mܺ{·ì,h)â––1‰¶‘Q }hu­Û˜‰3o;öR)rŒ²ÚÉ™S¿H¢®Ç޽z 2ŽzõØààÑŸþù! &Dé?:ø Š'J“òóâØ±7©Ýgò-ÖÚÚÝý$¥Sb<…Ùý#kaÌʦí8V Êîbpì§<= 6f¨#é6*¨¡ß{¨Ök ÒðÔ›%ȩӚpŽ%RÙS§Îðè…ÒNžÆaêгÄ‘èè g0ÈýÇ3™ºQå¨ngNçWÚëhÙó4È zŸJzûÇ‘WÓ aþ竲»è½ãçG_{yÊììK¬ŒÙÐåbÌi»12ãçy\?ô4±—莜2/«#Pi1~ò—£#8qÞ¹óñÇûO†L¦½žŽ¼f7z'·åtêÙ7qG²dÚ6Õ7@:2 J§ÆÀ„üefïÞ'™¾<ù$Ùµ¹µƒÌð‰IN-ã'G‡‡pn¶¹ng’áíí@˜Õ|ä¥Dšäv¿ÃG…ööö6ª^[‚lZS߀#ŒÙ•c‰ðkJ˜¾>CÓ×··»™–•ãçi¡Ë›‘QíßO€G}´~sëZ¦©ÓœÝO"t"c6·?òÈšd©ohX±„. ®kâCï.5F.¶01ΟêÛÙ¾™Œé?Zºƒ Ne›€ÊYûàêÕH£’bTÿ¡m߯G†'ËŠK“1+­ÿÔ»1ûzW­ˆÄš}û`Ì£<È,ÉAfâüIœü÷XWÍ׿Ëzfõ:³k 1çÏaRÝÚú¨Fz&!–,^¼˜Æ˜Ô;ãˆ8÷عO‘7¯Â1c;ÞÝ0f}gÏAcØ.-ÆO²2êÝ&•í °aÆ-ý»©Í“o Mª‡0)#c$Ó“b ”Á ³Á6ýcî.QΪúÙ¡ÿø-4¯ÿ\øCï^ò{Oí»T>–) èŠ}½ºÐº±³¿_ŠÔ±b¿< Ãþh]òºÙýýý»:;·mßÒD Õ‘ì|–ÎNy àbˆíÛ;u-~}â yŠƒÒ«±QS„Žövœ¦':-3¤™_»zC§ù±21æ¦(MVîæú9ˆR×¶5ý³<ôã>Ðúÿ<úHfÇ`Ì”iï Í”ªª…ûz3kx²[SSûÀÜ'…jh:¥â+÷GÚzÛJy†•M‘¶îì‰ññmÈã04½.Ýe̳ÝÝti Ò$ȪU,ÎòÕ4…póµÒäúǹ‚v¢Ôõ¾mM5òЗ¯ýëÿõ¿®Éd2dÌ´9w‡fó£Ìšú%KæH™šö¯”Gax ?Z3Gax )ÊÖ+{"Våì¶ûäqšNH·ÆÅ0fg&³iöŒD¹y!]^nÀ©Û–×µ²6Æ3-;©ÿ+Š1sÅ—@cú hÌc4¦ÿH´ª¼͘Ÿj&ÞQP§¡0fÇŽ…Se¶œSnδmzDÓï0fü§¥kÌîA&š1ÍÑù»pˆ1˜•…3få®HÆtИH[G6fø±HƼ’§1æ§ý{{?$—/·$Á”ª«wìhÛTÿðƒë·tö-c:ßpt¼lé‰d̶ ÇïÄ; –1ûfWM™qsrL«šÑÛ›ùÃËÔeÁÔ˜¢ÓŘŽfLsþ9¢1¯D3æ•¢c|kyvÕE7C¦Ìyóc|Óvy95&5&˜22f.Œ Û}9¹›Æ“¡ïùoØ’:öàæŽ‘š²0õ”GtÆpë´äaL`-˜ 3F~£b阘k–ÇL.c²‡ÉNLþ†dÄßYÙß=ƒ3Ò$¬1|æ7¦dt@Wû°ð5†kïÆa U³2ÕÔ c(“#¡‘,7Z­3F­ 5+Se5.²OïƒS˜#{0Î`ôÂæ8KǘÂbV†.8|=‚3ëüßÀ:óÇäÁ8§sQ:Ãc|Ïü¡ 6Ä8Ú˜9\ÇR'zc¸Þœgþ¨ü§¹©l ž±{f?ó§s}eŒÚÞ0ÆhµÎYæÌŸË’ #âm‘6cB‘“,áÎüý±Œ±ASu[J_ ïù[­ö㊈‡1¹I™\’5†¦ë ‹#ªm(º@Œ¡qDµZ?Æ8g‹Ô˜tŒq‘~®,Ô˜$Œq^Â- ©1¡HIRcB‘Òºbá÷AA©1¾¸Œ ÿ‹Ô %mLà]Äu5÷ŽÙu}‘/RŽñåO~[D®öª§é¢§ÿù¥Å7æfIý¤Æh(ec‚ß’vQcäý·;Àz=°C}–ˆŒ1Ö«§±x8òè¤5fešroýÀ´¶þ¿dvô’1SÂS%Æ¨ßæ%"u4uʃp„¨¸H¯|LîCÑcäa(š_‰Vü‘âüAA›•u¨7¡É¥…eŒ¬Ïª§y5¿å1o4Eú9¬Çrý6ý^Ù}ô{e2&S(cϯÉý{e/Dú™°hçl¥#Â@ßó—‡ax ù•æHtÄÝÉn ÎûAA1†§[–1î1FÖgeŒá%Í›ÊAh‰2J5mûy䋚•aZ¶cß—FbîŽ};2k–„š•5½»*6š¢l¼2Úï•E›•íŠöËÍG¢ÍÊŽx~-(å4+ãAÃ6Æð„ò cÌ¡1F=­#R\c~$?ØÞ #º)SCéñ<æ…BS´1&øƒ‚. eÌ#–1ôù<"KŸ7c°Þø¤!ŸÇDD{“°1_ûúœ9¢Looï~ô#ú?CC²ÂØOüScJyŒ þ  ‹„¡WæÏàɇiyÆO“%xš>ѪÖ×ÈÓP÷´]x¼ÆL̺\ö8þB³¾dÖ8&eAÆé,c ü{e¯•sŒ‰B²Æèᯠ²:|žEñŒ!eÖl¢»Í&Ú¸Þ!LYSZW—‹x­,E1†¦_òíZ>O‡"cB¤)Œ!eê׬i¨oŸuCCÊ% œ0…5¦³|¹0>%£ÇgÖc2f’¼1æ«,H™¿ÿ{Êþ‡è&va’0F*˜ËG;´ÆÐ÷X´$dŒ¾üÔ˜É%§1ò“¾„2Fe;²¿vù|(–ùóÏuø2‡ŒáK… GN•¼1šïIc‹‘“,ÅcD™9sjkkå‘Em<ðP[{§<2 ²\aRÒÆÐ7ñScTª1ôµcÌùšùk„ô»Xö¯Ðj¡žÆŸ}SIx˘ÚÕëVbÔY·nåòuëjéonðTíê•ô¬ÚÈieÏîÝsædOOÐ×ØÇŽ˜?áe}âXÆÈ—ƒq7Fß‚§Ûx¶% tÆÜA?F äråçÈdá4F¶æ;ºr©^kas÷ž‘‰Ã5ô›H¨Ñõóbü…d^¡¶qû6È«ÀËz¯1ŽW`~>zåÛz05&YBC·KéGJøçæÔÝ)ü¡cS•øp`¥³¥fÎ5s Æòšj–4á™%M5s–×Ò ~–62驞ÓR½ôÔÌÉò[QÍü£\¨ ²ÅJUÓz› Öç…–òÇ"²cÍü#zcH€fõS( h o-¿-&K²Ž°ŒÁþ²ô{"ÙoÐÃ× d³Æ/—1d¬a –à <ã5Æz1:c JcèíúÅN(µ +A€1öMUæÏYf=Z«—ì÷µÔÜGÆÐ þšjøYdLc¶Á•êo잃"駆šùG¹˜ët˜ÇjÓÎþ)"ZâZÐO«à8Íɤ7Ûf›i[µ‡ÆðÖÒNY’u„e  ñÈŽ°1ì#•Û‘Uj2.c¨YŽ‚%ð^cì¯Ã}jL! aŒüvrm,˜øãÜT¥þÊ&1´Vÿ=¦Zs0zð=Ý´6c…z–¨])Æì"cHcŒ™P¿Ó%©í2†æê0÷‘°Æ¨r5k:èóç÷xI5C­`rƒšØëd =P_±HI–Æð4wAW &Zcl¿þenÊ©¿ò±øžh­žÓ:88XÝ:ØŒûfZ€+´‚ž¥VŠ1_ï‡1Íü»þ˜©!‰ð>õpý*”q]Ý=+£;5/̆cxDzÑ’m3…wV†­ÍÄV„µ°ÍÊPeU!œlˆ?|“àQ0ÞÄÇ~/¦Æ”0³2êbÌ1aÆ Y0ÑC§Ü{M®MÙØPÆ(¤;<ÆxÎü1Ç¢+T‹ÜÆ`3ó%¹á­McÔk-cŒuçƒ× ŒZ¨Àh‘Wð °oŸ“,!ÏüýñØ͘ûä‘Ö¤«Ì΢Pxgehfe&Þ׺ Ž¡Ã-ÆhĸÉEjL²ä0†¿þHcñŒ‘WS‚Æ„"§12WRc&—œcL."ãȼ\Ày†|ŒÉE´z'lŒ“É6&áÿ965&˜ˆÆ4§Æx˜dcüßÉgLcNñ%5ÆKYsèÙ§aÌ쪪)S¦\”UU0Fþwòr6&êw0;£t_‰´yjL8`ÌŒé†1 §ª,IŠ‹ç˜öúV³½\ÿ¯åññó0æëá1ò( È/Dê¿ä>G†#eÇ ¯¼eó]ÃI3ÔÑÝýd_ïS‰ÒÛÛÛ÷øê¿÷P­×˜³ÃG޼P‚92lŽ1ftôµDç™dÃ-Co«6²˜ƒ¼½,ääÀg@®íÕÒüÐA÷…ï@Ú:4G޼2üJ„ Ë¢$6w_Ú‰Œy Æ`ÙùøŽ¤É´=Òa”1§-c&ξAQ)=^0r"a^yùå— Qò•¡êÍÊæ‡æ Cmã៾ñÓÙ1<üÆäLH¨‡UdžNý‡Z7··ÿ “iK˜M4¬X^[»r]çîA5Ĉ1ãgß(QÎñTÂ"ží¨\”7H¥aJ½’àìÙhÙuóü&e†1­íííê'~äwK¡¡aÅb 1+›ÜÆ3¥‰N{I˜§Ÿ}öÙ'* x$"]$a(dï3²ôX”­óõÅ4æQÊïDY–,cö»)uÔ‘CO{£Ð-÷å@7ÑÑÑÚòüðð‰“y|/ cŒO’Å`~yCay™„Ù»÷É †¬ÙÜÚÒeNªJÉÅy:óoÝü}šB)_(Ï“ƒÙUnƨ!æÙgŸÞÛ×'×þ*’¾¾½Ýí­¬Ì‰Ô˜P¨«Ë­í°1 1$ýç@[zÊԘx›ª”xªo'2=GO¤ƒL(Tjt´oÚ´¦~ÕªU$M¢,Á‰Ìêr6f_fáìJeîÂÌ>ƒA¦§§Xz(%1¦;ÓÖ¶f¡|ì8!æ.\EãÖòÕ«7”1t#·›Mÿ›^…rñÂ}O±1-=»Ž¦Ó²PŒŸS©±3“Yx±Ä1!¦Þ¶iÍš††‡VcŒé?ê4fã¿”(ÇTý`Ìˇ=AÆ\Ze~ û7‹B±vt0æqÓ˜cƒŠf£êàøÓ;v|YžX_]„þ¸:Ó¶iMÃÚWoètóæ¢ýÄs 2˜·rýÔõ6fFÕ´YÕÉ%ÙŒé9úóÝÿ½’l¿ø"/6‹ÞT=súÑÛ;»ªê’ꚤ˜5­jÆŽm›ê~p=Œq~JæÍeo¾ùæ)Å[~œñeÌ.>>[ÆtwãÄFÕ»¶«'+Z6¦/£Œ9øóÝÑ+f¿é¤?n BjS$–%` }Æì›]uQõéÄXcz{3ôQÌÕ¶8?‰IÆH§ÄF­ƒ Ͻ1MêÉJ£Z1™ïon]ßÙsðglŒt ~ðGú#é– ¤.E#)cè[Ë0¦FžM2†¾ƒYÿ°Ö˜\½"!× ‘ÖÀEçÇoŒôK±|)º0‰3· ÆÐ÷üýŒ‘Ø{‘k@ëà’óÄ2føÂ3fëFîF:Â鎤W‘Š“7Æç·dÄ ¾ ¹ ´.7oRcé¤?n BªQ\ÊØ‰½ ¹ ´.5.PcÖ:Œ‘~ðGú#é– ¤Ŧl‘Ø{‘kHkà2!5¦H¾L–0gŒ„\ƒZ™ ©1ÒþH Ý„Ô`¨,c$â$Ð:¸À¤¸Ð‘ŽðGú#é– dÿ“BE#!÷"ÖÁÅ%ÇnŒt„/ÒH·!{Ÿ$*È ¹‰´.,IRcî@º%ÙùdQ1ÆHÈ5H upY‰’ãôGÒ-AÈ®'J1FBîE­ƒKJ˜Ô?¤?n Bv<™T†1r i \Nâ¤Æè‘î@º%ÙíäR ÆHÈ5H¤up1É“£Cº#é•@d¯“Lù#!× ÖÁ…‚Ô ÒH·!ûœtÊÞ ¹ ´.¢0L¾1MçäQÁ gŒôGÒ-AÈK€É1&L¯†2FBnиhÑ¢eÃüP"­ 8ÖØÌ÷PÄyƒ"ÓÈÁkl:O·ýºñ1~֤ČáÎDº%Ù!£zÎÞ¾Y dL½Â ¹ÁñÆfÜ6.z!ÇCñõ òñÆ=¿Þ誻úÁ˜eÃTOu{¤´QˆtK²;¡2I Ws#·hl:©îÞ–Hk Å—+Œù5¤F=¿Ë·ÞÚ–’1Ü-H·!;3ñST dL½šË ¹ÅñF .;<Öx´Ó³±±c˜§A ã[±È çèvQ3EüXc?m…êà~@~³<:â†Ö46áÏþš_Ž-𪦷Õ+=ã<†*×øUT=Bͬ†,ÛJ±•ºÒz5)àÔó“#‡1܈AÈ®l˜Æ˜ý‡P–áØLk L¡ÎcòïÕÆHÌm Ðt ½ÀÆ@Œ5®Çèþ8;Ç_PáæsÄQìþxã.ËkTA4‡õò,[Ä%oÝtîx#Îu¨âŠa Eu£Ø¡ª[Õª"UϨë9ªÿÀFzÌ)•4ÆpŸ"N"{²c3F5›c€{jtá)”1ù÷j 9bKËtè¢ýzã¹Æ#i6©ŸGæ¿1Ò%pW#{q£7ºä : eLþ½Ù˜34<ƒ1ÿø)6cj¢5†Làrr£µe(c¤f¥`L§ß:bKUtÄv`ãàÆó<;F’ÂÏé¸W‚‘}x¡.Dßír3°hcÒ=…3&ß^lÌØÀ"R†Naç1¾i æƒ0†Bn3†Ô6 ZphnÆÏ`‰_À³HPÆ`¸£š+Ím±åÁR]@ý¨Ö¿nÄ|w`#­§×Å鎨Or!»Ð0°h‡¦Ø¡Þán*83&ï^h E™ º¶,WQÔµ2ìLÍÊðxÙVì•’keqÚÈdh#ªÁ]Ö´wX +\¶¤ºOž1|Nˆ[®€-¶TÑ&«\žRsލ ¥)‰¢5Fú#6"Ùj 5Ýn 5±§j^ fLÞ½É ´ÏÊÞ>®£;ÿc‹bL© 1Fú#é– ¤øÒ¤`ÆäMc$Ò&–1¼uÔ,ÍeLÌ!þ7FúÃé– ¤ðR¥Œ‘HÛ0ás!Ó-YRÐÙRc‚PŒ”]²”¿1h¼iqI @º%)¹„)wc$Ð:xÃb“ã‹tKRnISæÆH¤5ðfÅ'5Æé–@¤ØÒ¦¬‘@ëà­&Ô=Ò-AH¡¥N#ÖÁÛL ©1:¤[‚"KŸ²5F­ƒ·˜$Rc¼H·!–•g ¯Ÿ4RcÜH·"å•g ¯žX»rƒÕåb Nýa ”ioïÎd2?¨PÚÛ¿_ßúŒéé?š1á8AfhˆŽ¦Ý”IæF; ³¼¶veSçþAé21fâüÉáŸ<eZ߯Xêë7¯}hõê [v™=”’LËøhJ‡Ó„S£¾þ{k1'[‰IYÙ3~ò—ÃÏ÷P\™‡þ^Eòðíkzpõêu<)K æ£êhšpn<üðÚµa„¡!Æêr1fâäIÓÓ‚À¬_ûP¥ò t0:yˆI äBr)ž Ôf]“bÊ̘ñ“'H™ž–õë×SZU,ë6lèìÙŸ1À”½P¹AS2Æê²1fâ4”yaéܲ¬«H6@— [:wõL‡˜ŒcÂÊ 764mïìßmëò1füôë?>ØOqéÜR©lïì„/û¦CLh2Ü¿+ñÜØ¾Òïìò1£Ìë'~vôàþ~°«B¡¶qÿ¤ÂD‡ÓÃGRø’Ì *n·«?ÊʘÓ'_ÿùϬhŽþ´tN Ο"7ÜýQNÆP\^ÒT6hbêKt –®þ(/c(.™ †Z(M‰DarÃÝåf  &T2ÒÌ”HEŠ6(CcRR&‘Ô˜””(¤Æ¤¤„gbâÕOEöLëŸIEND®B`‚thrift-0.23.0/doc/images/cyel.png0000664000175000017500000000166215165535636017056 0ustar00buildbuild00000000000000‰PNG  IHDRàw=ø pHYs  šœdIDATHÇÕ–Oh\UÆ÷ÍÌ›IšÚI*±° ‚D—.ƒ4X-".t-´X©-bÅ…(íεDZȦ….¡[©K¡ÚÒÖ$¤ÅH:i3é›ysÿœãâ¾ÉL2è¦ îã=î÷óïûŒªò(¯„G|•·{)KÇK¨¾È4!LäEõ¼¿Œ÷×Õ¹Y¼?_~u& Â0ƒ$’¥ã¨Î˜êÔË íÅ”ªPÙš¯B^GëW‘•‹—pþýòkg¯ÿgYüì0èWf×C¦: ¶aì-J£`R¨îEî-nüÐÂù•©s§ÿ•@æ?ýÆŒ¼ý‰Ù1vÜM âºÚ1ÄCeÞÜþ™ÿéÛÊ[$Gš‘gÌÈäW@€ hˆ`ÁöØîªÀîIÂÂ%ÂâÏï¤ï]=ÛG~ÿ8Ř?“уãÆ_mƒj$ê!¸XM°àÛ]i:´ò nnæ&¾µ?ýèo»Ù¦ÞO›Úä¸q×À7 ´ŠhÆðÍžg-¤ Ò„[ô#{~Ÿºlºß¦ÎMÓ—ÅhQA‘(ÑF\!Q^$ÅœÃT+à²)àÇMêÜKÈzÜ ¡Ð^7÷@:2ù-àY\¥Mb*àyåaõª+šìz´ *Q’Â\+̳}çAzè²Å6N„ú `ãps÷Á­½®I½‚§+‹¨@¸ À±Új»öwC§J{ª‡K%ߺ@º%ˆÀ’@X…°ÌéÚI=²ýãò£á¯|ÕßáóÊ8i©Æ†C6VJ9šÉ-`/¯·ׯ˜¤Øž,ã¹±a¾/ïa2Ù &$-¦nÇd÷À¯òëÝŒŸ:Å:UU¤EUeÀ<û8•Ùw9ðäN^OK<&¼`W|`ñvƒsožáü­UlQ›¼ê6=øßýUüG\‰ýP±÷IEND®B`‚thrift-0.23.0/doc/images/cred.png0000664000175000017500000000222115165535636017027 0ustar00buildbuild00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEá :'.IDATHÇÕ–_hÖeÇ¿ï»ßÞù®¹-ËTƒéèÂW`1ºi¡“¤¥»(YA°‘„Y͉/¢PºÛ.‡W›Ál5ô¡t¡¤dmNËönÉl[sÛûþþ<ÿÏéâ÷›3ÞfzáE~ÏÃçó;ç{žç<)fÆÃi<äáÝksìü™fÞ™·’£?ã¬Yû]'¢>gÝÀ³»ÚÜJ>R+¥hìü™f>VóDýÖ²òGày¼Ò @E!d¡07‹ÙÉñ‹dìÞmm{¯ß7àê¹ÓRàÃk7mΖe³¬ˆz­ÖÃF†9²i/S—.ñšJ³ÙöüÂBãÄÏ—9:Ôôú[GÿpõÜé/jŸÜôaye%¬ˆ:³“¿ô°U€µ`c­ÁJ•ŒÆüÓ/t”U=Ú==1©׿|éíwºVŒœýnOÍãõÇ+*«¡‚üË«§F†@8;7¬5XI@kÜÚ¼­¹¢¦öû?~Çìø¯m;öt¢¨Š®œ9•!GG2™ ¢Å¹ÎÕ—‡ ÕòßjÖ P¼4O¢YóÃàÐÂÍÉÎêêJ°‡>íÊÈÚÖªÚµëm\¨ÿ±‡¥‹XÄ!ÀR‚¥¤K HˆÎöõèÅù ë6ÔCÉÖbÑö4«d/D–ÑÃ]óx-H–al‘#Dï*ÏC*ò·gÝÁ=LBD8ÑönLœ*ƒXÄ`«õpII i=W°Ö®!«AFç8 fÜØQRE°&Öä€PNŠ\:» ¬y}€Œ…8©@³3±sfÀQ plt,¶’Iš–ÒƒTà#­`Iÿ[ÓVë*v¶Ž…¼ZŠÀ‚­¿ZZ‚u"°`%c]”[SgR 68(,›Ÿûp˜¬ÃIÅQÀY íµÛéi,X)û ·çnD"jüíùW:8(€ü<Ø_PP>(ôÁQˆ,Dœ2£1²û½«£F3æôv¼û¦08´0wDÔ=öâžfòà ‰&,€#?v…É5!ÁZct÷þfd3ÝöÖ-ø¸åë~½âe7ppß‘ÒÚÇTUW¤ì|êøW=0:ÑÂaY0ctïÁò¼nóçMèÉÂÑ–þþ÷ïÙpRA¾‹ÿšŸ·üIéÆÝ£¯ík'­{aô0ŒÍ%q×!nâÒ²v›Ÿk”cÓÀg>¿ï†óí­ ójÊ·zkÖ©4¼ly|ê}Lvff:¼àÍ–þþ«ÔÑàTÛ«% ìÐ  [’­KÌœpÀ7;Ož|ð–ù¿yUü Y3TJÎÑÚéIEND®B`‚thrift-0.23.0/doc/images/credfull.png0000664000175000017500000000204115165535636017712 0ustar00buildbuild00000000000000‰PNG  IHDRàw=ø pHYs  šœÓIDATHÇÕ–Ï‹•UÇ?÷Þ¹wî½Î¤ã8£æFrrF‚`µ‹VBÜ(Zý FJ$Eê"ÝD‹Z)D†Cу̀«J,ÄwgtæÞ¹÷}Ï{~>-Î;NrÓ…‹^8¼/x>çûý>眷 "<ΧÈc~ú49òpI‚¼*!4‚÷ãâÂNïÁº‹ÞØKÞºÓÁ¸ŸÆ}éW«QXÍ¢ù“‡ÇEäDeÇË»û‡†)Uúé«Õ!L{Ó^¤ó÷%–.ž¿à­{û™£'.=4`îëCû@ެÙÓ¨Uö¢¤s1újÊe ë6Ðn^cæçï•·îàóŸwü?³_}ôi}×Þ÷jF),Î#ÝÛˆÓàb-ƒhh ÖP"<¹•ù‹SÜ:öèî“¿ì_0óÅoTŸ{åÛ'F6n7Áv ð>·1r€è,Ò¶\šd~òÜ›/MLêé¢ëŸ¨çÕªÂÌeHï€Ñ+«5:Ú£3dù{YÍR7}ŽáÑ x•9ûÂÖJ X×èÛ¹¥ÔšCÒ’)D¥¥ˆŠ¥,C2Y†dd TŠtÚT¯_fèéíc>M=mê­Ý[ñé.€ÓˆH´'pq¬‹ƒhÕh“¥ žµ}Eši²øæ€ÓvWÉh‚é‚ww‹Kžîß9Ø{‹«4¬¡^¯2µ§W6›Š&Eºy°Ë ¼G|Ȼȳ1“{ h…XC¹¼Ÿ±¥à´An"­ÎŠ5"àCxX“½—,ÍGa5’,æ> ì¬MÕÚ’Öà<„eq.¾“!&X+DgÑ!´QCó~M«nw|ÐX‚Ê øÜžX—ïk"`Ù&“ÝmáB¹H¢Ä1ÝkQÒ™h͆·ëHÚçVÎÆ \ÞAÖÄ}`õ](ÁC½ÎÜÍ&zÝÎé;­Å×mÛ6ºyý¾-k×зÔ!$*®ÖGËV²ñ B±^ÁÔ«\kqã/Ž7¼¼ûÀ ǧÝýÍ?®;>|jûÆÊ¦j¬oã@¡X)!õ7UÊŸ¿µ pøä¡/œ3ë ãâ91²‘Ý##ëèûK B'5dæfRnÍpx§áå÷GºÑ~¨Jx ¡!1„]ùÔ´®§€_yô+óóWñôû&¿sÐîÆIEND®B`‚thrift-0.23.0/doc/images/cgrn.png0000664000175000017500000000214515165535636017050 0ustar00buildbuild00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEá : ‘fRœòIDATHÇÕ–K¨VUÇû|ûè^»jŠdAé |@$4m˜”A!jA4I0 iQä j8J"ÁIRâ$•Ô7ùŠ›v}|^ï=çì×Z«Á÷u¯òqµ‰ƒ6öyÀÿwÖÚë¿övfƃx4ïõñÈÙµ 5{É”MQuUNnOŸÜ‰X7NûÈ~Ü·6—ù4Ü|):rví*5Ûëxa}Ñ\A³Ù¦Ý (”º,™N:Óã\¾üû!òê»[ŽþÏ€ÃgÖlvî¡¡MR*ÉV“¤D,P¸…kÑnŽqýÆ'N®C²»^;¶ç¾€ÆW¤î•í##‹H®ƒH‰š`&ˆ”HÖˆZB5Ól 1X<Æ…+?ñËÉÓïyó×ó¾ùyõæfk×£#+¨™ÄD2E-‘,¡–0$"&] Àhë)Îüq”ñßÎlù|ë•}}€¯Ž®m;gçǾ¼œÆæNAœÜA »—…Þœ0œ,æûo êŸÞ»=ĻʴnÓ@{ýrkÞ$iEVЛ­&[¨'«'X=+,Ôã­$¹ }då“*¶©Ï!h rE¶SO–@Ö “@’šÜ{gÈÖ}F=XMöj)1³¡ÏupϨÔº‹šPºéSÔæÒÔMQ&âAOŽŠx#ˆ04Yy®k·L OÎJ¸ `=ˆZê®…F²$$*9Ñ+Q 1(dey ôÓ5j™73!CW\39éÑÔ›ÓLåÈÿ–Ö€¹Zåêas©ûÇ Ù fFN†™‘‚!YI±+œ£’“‘5t h†˜‘•‰>€v¼,ËUᮀ¡˜‚fæ ÉˆÉæ¢Èé™N,¡Îým€ã}U”Sypò¢R˜ A•’f”P Õ´àK¡ª”ºB-ä<烬‘„–kЙNûQÊý_›873 Ñ+~F™)…ê¶âKÁWН29G’Ô³e+D¬WÉWLvì‚™íï|¶õÏXå™ÏßDÅ øÅ׉1ú^ë{˜ëGÍÆW;5À;‡v§8o³ÛüAû“¥ccÛ–,YLŠJPßí?NPí® èìý@£…£É•ë·øë†íùnwzûžNVvL\¿uóÒä­÷_6Ü^0º$ŠjÆ™€Z@«(hƒLMu8{Å"ð>ðá=Ûµs®P<¿­¹²=ä¾X4ƳKG‡Ð¢à¡á ¥ªf@#W§„;+^?üi´k!Óùí^TMÀ /t­u›FxѵOÔS2Í,ÞwËüßœ*þ®Yòœ·ÇIEND®B`‚thrift-0.23.0/doc/committers.md0000664000175000017500000000317315165535636016656 0ustar00buildbuild00000000000000## Process used by committers to review and submit patches 1. Make sure that there is an issue for the patch(s) you are about to commit in our [Jira issue tracker](http://issues.apache.org/jira/browse/THRIFT) 1. Check out the latest version of the source code * git clone https://github.com/apache/thrift.git thrift 1. Apply the patch * curl https://issues.apache.org/jira/... |git apply --ignore-space-change or * curl https://github.com//thrift/commit/.patch |git apply --ignore-space-change 1. Inspect the applied patch to ensure that all [Legal aspects on Submission of Contributions (Patches)](http://www.apache.org/licenses/LICENSE-2.0.html#contributions) are met 1. Run the necessary unit tests and cross-language test cases to verify the patch 1. Commit the patch git --config user.name "Your Name" git --config user.email "YourApacheID@apache.org" git add -A git commit 1. The commit message should be in the format: THRIFT-####: Client: Patch: Description of what was fixed or addressed. If this is a github pull request then add the below comment to automatically close the GitHub request, where #NNNN is the PR number: This closes #NNNN 1. Double check the patch committed and that nothing was missed then push the patch git status git show HEAD git push origin master 1. Resolve the Jira issue and set the following for the changelog * Component the patch is for * fixVersion to the current version on master thrift-0.23.0/doc/install/0000775000175000017500000000000015165535636015610 5ustar00buildbuild00000000000000thrift-0.23.0/doc/install/debian.md0000664000175000017500000000434515165535636017362 0ustar00buildbuild00000000000000## Debian/Ubuntu install The following command will install tools and libraries required to build and install the Apache Thrift compiler and C++ libraries on a Debian/Ubuntu Linux based system. sudo apt-get install automake bison flex g++ git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config Debian 7/Ubuntu 12 users need to manually install a more recent version of automake and (for C++ library and test support) boost: wget http://ftp.debian.org/debian/pool/main/a/automake-1.15/automake_1.15-3_all.deb sudo dpkg -i automake_1.15-3_all.deb wget http://sourceforge.net/projects/boost/files/boost/1.60.0/boost_1_60_0.tar.gz tar xvf boost_1_60_0.tar.gz cd boost_1_60_0 ./bootstrap.sh sudo ./b2 install ## Optional packages If you would like to build Apache Thrift libraries for other programming languages you may need to install additional packages. The following languages require the specified additional packages: * Java * packages: gradle (version 8.4) * You will also need Java JDK v1.8 or higher. Type **javac** to see a list of available packages, pick the one you prefer and **apt-get install** it (e.g. default-jdk). * Ruby * ruby-full ruby-dev ruby-rspec rake rubygems bundler * Python * python-all python-all-dev python-all-dbg * Perl * libbit-vector-perl libclass-accessor-class-perl * Php, install * php5-dev php5-cli phpunit * C_glib * libglib2.0-dev * Erlang * erlang-base erlang-eunit erlang-dev rebar * NetStd * apt-transport-https dotnet-sdk-6.0 aspnetcore-runtime-6.0 * Thrift Compiler for Windows * mingw-w64 mingw-w64-x86-64-dev nsis * Rust * rustc cargo * Haxe * haxe * Lua * lua5.3 liblua5.3-dev * NodeJs * nodejs npm * dotnetcore * https://www.microsoft.com/net/learn/get-started/linuxubuntu * d-lang * curl -fsS https://dlang.org/install.sh | bash -s dmd * dart & pub * https://www.dartlang.org/install/linux * https://www.dartlang.org/tools/pub/installing ## Additional reading For more information on the requirements see: [Apache Thrift Requirements](/docs/install) For more information on building and installing Thrift see: [Building from source](/docs/BuildingFromSource) thrift-0.23.0/doc/install/windows.md0000664000175000017500000001774015165535636017635 0ustar00buildbuild00000000000000## Windows Setup The Thrift environment consists of two main parts: The Thrift compiler EXE and the language-dependent libraries. Most of these libraries will require some kind of build and/or installation. But regarding the Thrift compiler utility, there are a number of different alternatives. The first one of these alternatives is to download the **pre-built Thrift Compiler EXE** and only build the libraries needed from source, following one of the "Setup from source" methods outlined below. The other two options are to build the Thrift compiler from source. The most recommended way to achieve this is by means of the **Visual Studio C++ build project**. Alternatively, the Thrift compiler can also be built via **Cygwin** or **MinGW** build environments, however this method is not only less comfortable, but more time-consuming and requires much more manual effort. ## Prebuilt Thrift compiler The windows Thrift compiler is available as a prebuilt exe available [here](/download). Note that there is no installation tool, rather this EXE file *is* already the Thrift compiler utility. Download the file and put it into some suitable location of your choice. Now pick one of the "Build and install target libraries" below to continue. ## Setup from source via Visual Studio C++ (recommended) ### Requirements Thrift's compiler is written in C++ and designed to be portable, but there are some system requirements. Thrift's runtime libraries are written in various languages, which are also required for the particular language interface. * Visual Studio C++, any recent version should do * Flex and Bison, e.g. the WinFlexBison package * [Apache Thrift Requirements](/docs/install) ### Build and install the compiler After all requirements are in place, use the `compiler/cpp/compiler.vcxproj` build project to build the Thrift compiler. Copy the resulting EXE file to a location of your choice. ### Build and install target libraries A few of the target language libraries also do provide Visual Studio project files, such as C++ and C#. These are located in the `lib//` folders. Most of the language packages must be built and installed manually using build tools better suited to those languages. Typical examples are Java, Ruby, Delphi, or PHP. Look for the `README.md` file in the `lib//` folder for more details on how to build and install each language's library package. ## Setup from source via Cygwin ### Requirements Thrift's compiler is written in C++ and designed to be portable, but there are some system requirements. Thrift's runtime libraries are written in various languages, which are also required for the particular language interface. * Cygwin or MinGW * [Apache Thrift Requirements](/docs/install) ### Installing from source If you are building from the first time out of the source repository, you will need to generate the configure scripts. (This is not necessary if you downloaded a tarball.) From the top directory, do: ./bootstrap.sh Once the configure scripts are generated, thrift can be configured. From the top directory, do: export CXXFLAGS="-D PTHREAD_MUTEX_RECURSIVE_NP=PTHREAD_MUTEX_RECURSIVE" ./configure Setting the CXXFLAGS environmental variable works around compile errors with PTHREAD_MUTEX_RECURSIVE_NP being undeclared, by replacing it with the newer, portable PTHREAD_MUTEX_RECURSIVE. (Tested on cygwin 20100320, Thrift r760184, latest pthread.) **Optional:** You **may not** be able to make from the root Thrift directory due to errors (see below to resolve). To make the compiler only, change to the compiler directory before running make: cd compiler/cpp Now make the thrift compiler (& runtime libraries if make is run from the thrift root directory): make make install ### Build and install target libraries Some language packages must be installed manually using build tools better suited to those languages. Typical examples are Java, Ruby, or PHP. Look for the README file in the `lib//` folder for more details on the installation of each language library package. ### Possible issues with Cygwin install See also Possible issues with MinGW install. #### Syntax error in ./configure The following error occurs for some users when running ./configure: ./configure: line 21183: syntax error near unexpected token `MONO,' ./configure: line 21183: ` PKG_CHECK_MODULES(MONO, mono >= 1.2.6, have_mono=yes, have_mono=no)' To resolve this, you'll need to find your pkg.m4 (installed by the pkg-config package) file and copy it to the thrift/aclocal directory. From the top-level thrift directory, you can copy the file by running cp /usr/share/aclocal/pkg.m4 aclocal Finally, re-run ./bootstrap.sh and ./configure. (Note that pkg.m4 is created by the pkg-config tool. If your /usr/share/aclocal directory doesn't contain the pkg.m4 file, you may not have pkg-config installed.) #### Installing perl runtime libraries Sometimes, there will be an error during the install of the perl libraries with chmod. A workaround is to avoid installing the perl libraries if they are not needed. If you don't need perl, run configure with --without-perl. If you need perl, and are happy to manually install it, replace the contents of thrift/lib/perl/Makefile with the following, after building thrift: TODO #### Linking to installed C++ runtime libraries Sometimes, the installed libthrift.a will not link using g++, with linker errors about missing vtables and exceptions for Thrift classes. A workaround is to link the compiled object files directly from your Thrift build, corresponding to the missing classes. This can be implemented in a Makefile using the following lines: THRIFT_O=/thrift/lib/cpp LTHRIFT=$(THRIFT_O)/Thrift.o $(THRIFT_O)/TSocket.o $(THRIFT_O)/TBinaryProtocol.o $(THRIFT_O)/TBufferTransports.o Then linking using $(LTHRIFT) instead of -lthrift. TODO - diagnose the issue further #### C++ runtime segfault with cygwin 1.7.5-1, g++-4.3.4, fork() and throw If your thrift C++ programs segfault on throw after fork()ing, compile them with g++-3. The issue and patch are described on the Cygwin mailing list at http://cygwin.com/ml/cygwin/2010-05/msg00203.html This issue should be fixed in Cygwin versions after 1.7.5-1, or g++ 4.5.0. ## Setup from source via MinGW ### Requirements To compile the Thrift generator & runtime libraries (untested) without the cygwin.dll dependency you need to install MinGW (www.mingw.org). * MinGW * [Apache Thrift Requirements](/docs/install) In addition, you need to add the following entry to your windows PATH variable. C:\MINGW\BIN Next, open compiler/cpp/Makefile.am and add the following line to thrift_CXXFLAGS -DMINGW -mno-cygwin -lfl Run bootstrap.sh: ./bootstrap.sh Make sure you have java in your $PATH variable, if not do(adjust path if necessary): export PATH=$PATH:"/cygdrive/c/program files/java/jre1.8.0_191/bin" Run configure - using CXXFLAGS to work around an issue with an old pthreads define (untested on MinGW - works on Cygwin): export CXXFLAGS="-D PTHREAD_MUTEX_RECURSIVE_NP=PTHREAD_MUTEX_RECURSIVE" ./configure ''Optional:'' To make the compiler only, change to the compiler directory before running make: cd compiler/cpp Run make: mingw32-make.exe ### Possible issues with MinGW install See also Possible issues with Cygwin install, including the discussion about PTHREAD_MUTEX_RECURSIVE_NP. #### yywrap is not found Make sure you add -lfl in your cxxflags in Makefile, also try adding -Lc:/cygwin/libs #### boost is not found Try and change the include dir to use the windows path from c like this: Edit compiler/cpp/Makefile, look for the declaration of BOOST_CPPFLAGS, change that line for BOOST_CPPFLAGS = -Ic:/cygwin/usr/include/boost-1_53_0 #### realpath is not found add -DMINGW -mno-cygwin to the CXXDEFS variable in Makefile ## Additional reading For more information on the requirements see: [Apache Thrift Requirements](/docs/install) For more information on building and installing Thrift see: [Building from source](/docs/BuildingFromSource) thrift-0.23.0/doc/install/centos.md0000664000175000017500000000431715165535636017432 0ustar00buildbuild00000000000000# Building Apache Thrift on CentOS 6.5 Starting with a minimal installation, the following steps are required to build Apache Thrift on Centos 6.5. This example builds from source, using the current development master branch. These instructions should also work with Apache Thrift releases beginning with 0.9.2. ## Update the System sudo yum -y update ## Install the Platform Development Tools sudo yum -y groupinstall "Development Tools" ## Upgrade autoconf/automake/bison sudo yum install -y wget ### Upgrade autoconf wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz tar xvf autoconf-2.69.tar.gz cd autoconf-2.69 ./configure --prefix=/usr make sudo make install cd .. ### Upgrade automake wget http://ftp.gnu.org/gnu/automake/automake-1.14.tar.gz tar xvf automake-1.14.tar.gz cd automake-1.14 ./configure --prefix=/usr make sudo make install cd .. ### Upgrade bison wget http://ftp.gnu.org/gnu/bison/bison-2.5.1.tar.gz tar xvf bison-2.5.1.tar.gz cd bison-2.5.1 ./configure --prefix=/usr make sudo make install cd .. ## Add Optional C++ Language Library Dependencies All languages require the Apache Thrift IDL Compiler and at this point everything needed to make the IDL Compiler is installed (if you only need the compiler you can skip to the Build step). If you will be developing Apache Thrift clients/servers in C++ you will also need additional packages to support the C++ shared library build. ### Install C++ Lib Dependencies sudo yum -y install libevent-devel zlib-devel openssl-devel ### Upgrade Boost >= 1.56 wget http://sourceforge.net/projects/boost/files/boost/1.56.0/boost_1_56_0.tar.gz tar xvf boost_1_56_0.tar.gz cd boost_1_56_0 ./bootstrap.sh sudo ./b2 install ## Build and Install the Apache Thrift IDL Compiler git clone https://github.com/apache/thrift.git cd thrift ./bootstrap.sh ./configure --with-lua=no make sudo make install This will build the compiler (thrift/compiler/cpp/thrift --version) and any language libraries supported. The make install step installs the compiler on the path: /usr/local/bin/thrift You can use the ./configure --enable-libs=no switch to build the Apache Thrift IDL Compiler only without lib builds. To run tests use "make check". thrift-0.23.0/doc/install/os_x.md0000664000175000017500000000164415165535636017107 0ustar00buildbuild00000000000000## OS X Setup The following command install all the required tools and libraries to build and install the Apache Thrift compiler on a OS X based system. ### Install Boost Download the boost library from [boost.org](http://www.boost.org) untar compile with ./bootstrap.sh sudo ./b2 threading=multi address-model=64 variant=release stage install ### Install libevent Download [libevent](http://monkey.org/~provos/libevent), untar and compile with ./configure --prefix=/usr/local make sudo make install ### Building Apache Thrift Download the latest version of [Apache Thrift](/download), untar and compile with ./configure --prefix=/usr/local/ --with-boost=/usr/local --with-libevent=/usr/local ## Additional reading For more information on the requirements see: [Apache Thrift Requirements](/docs/install) For more information on building and installing Thrift see: [Building from source](/docs/BuildingFromSource) thrift-0.23.0/doc/install/README.md0000664000175000017500000000235315165535636017072 0ustar00buildbuild00000000000000 ## Basic requirements * A relatively POSIX-compliant *NIX system * Cygwin or MinGW can be used on Windows (but there are better options, see below) * g++ 4.2 * boost 1.56.0 * Runtime libraries for lex and yacc might be needed for the compiler. ## Requirements for building from source * GNU build tools: * autoconf 2.65 * automake 1.13 * libtool 1.5.24 * pkg-config autoconf macros (pkg.m4) * lex and yacc (developed primarily with flex and bison) * libssl-dev ## Requirements for building the compiler from source on Windows * Visual Studio C++ * Flex and Bison (e.g. the WinFlexBison package) ## Language requirements These are only required if you choose to build the libraries for the given language * C++ * Boost 1.56.0 * libevent (optional, to build the nonblocking server) * zlib (optional) * Qt (optional) * Java * Java 17 (latest LTS) * 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 7.1 (optionally including header files for extension modules) * Ruby 1.8 * bundler gem * Erlang R12 (R11 works but not recommended) * Perl 5 * Bit::Vector * Class::Accessor * Haxe 3.1.3 * Go 1.4 * Delphi 2010 thrift-0.23.0/doc/coding_standards.md0000664000175000017500000000435015165535636017774 0ustar00buildbuild00000000000000# Thrift Coding Standards Any fool can write code that a computer can understand. Good programmers write code that humans can understand. -- Martin Fowler, 1999 The purpose of this document is to make everyone's life easier. It's easier when you read good, well-formatted, with a clearly defined purpose, code. But the only way to read clean code is to write such. This document can help achieve that, but keep in mind that those are not silver-bullet, fix-all-at-once rules. Just think about readability while writing code. Write code like you would have to read it ten years from now. ## General Coding Standards Thrift has some history. Not all existing code follows those rules. But we want to improve over time. When making a small change / bugfix - like a single line fix - do *not* refactor the whole function. That disturbs code repository history. Whenever adding something new and / or making bigger refactoring - follow those rules as strictly as you can. When in doubt - contact other developers (using dev@ mailing list or IRC). Code review is the best way to improve readability. ### Basics * Use spaces, not tabs * Use only ASCII characters in file and directory names * Commit to the repository using Unix-style line endings (LF) On Windows: git config core.autocrlf true * Maximum line width - 100 characters * If not specified otherwise in language specific standard - use 2 spaces as indent/tab ### Comments * Each file has to start with a comment containing [Apache License](http://www.apache.org/licenses/LICENSE-2.0) * Public API of a library should be documented, preferably using format native for language-specific documentation generation tools (Javadoc, Doxygen etc.) * Other comments are discouraged - comments are lies. When one has to make comment it means one failed to write readable code. Instead of "I should write a comment here" think "I should clean it up" * Do not leave "TODO/FIXME" comments - file [Jira](http://issues.apache.org/jira/browse/THRIFT) issue instead ### Naming Finding proper names is the most important and most difficult task in software development. ## Language-Specific Coding Standards For detailed information see `lib/LANG/coding_standards.md` thrift-0.23.0/doc/specs/0000775000175000017500000000000015170007142015235 5ustar00buildbuild00000000000000thrift-0.23.0/doc/specs/thrift-binary-protocol.md0000664000175000017500000002366715165535636022240 0ustar00buildbuild00000000000000Thrift Binary protocol encoding =============================== This document describes the wire encoding for RPC using the older Thrift *binary protocol*. The information here is _mostly_ based on the Java implementation in the Apache thrift library (version 0.9.1 and 0.9.3). Other implementation, however, should behave the same. For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache.org/static/files/thrift-20070401.pdf). # Contents * Binary protocol * Base types * Message * Struct * List and Set * Map * BNF notation used in this document # Binary protocol ## Base types ### Integer encoding In the _binary protocol_ integers are encoded with the most significant byte first (big endian byte order, aka network order). An `int8` needs 1 byte, an `int16` 2, an `int32` 4 and an `int64` needs 8 bytes. The CPP version has the option to use the binary protocol with little endian order. Little endian gives a small but noticeable performance boost because contemporary CPUs use little endian when storing integers to RAM. ### Enum encoding The generated code encodes `Enum`s by taking the ordinal value and then encoding that as an int32. ### Binary encoding Binary is sent as follows: ``` Binary protocol, binary data, 4+ bytes: +--------+--------+--------+--------+--------+...+--------+ | byte length | bytes | +--------+--------+--------+--------+--------+...+--------+ ``` Where: * `byte length` is the length of the byte array, a signed 32 bit integer encoded in network (big endian) order (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. ### 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. Both the binary protocol and the compact protocol then encode the int64 in 8 bytes in big endian order. ### Boolean encoding Values of `bool` type are first converted to an int8. True is converted to `1`, false to `0`. ### 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. *Note*: Since the length is fixed, no `byte length` prefix is necessary and the field is always 16 bytes long. ## Message A `Message` can be encoded in two different ways: ``` Binary protocol Message, strict encoding, 12+ bytes: +--------+--------+--------+--------+--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+ |1vvvvvvv|vvvvvvvv|unused |00000mmm| name length | name | seq id | +--------+--------+--------+--------+--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+ ``` Where: * `vvvvvvvvvvvvvvv` is the version, an unsigned 15 bit number fixed to `1` (in binary: `000 0000 0000 0001`). The leading bit is `1`. * `unused` is an ignored byte. * `mmm` is the message type, an unsigned 3 bit integer. The 5 leading bits must be `0` as some clients (checked for java in 0.9.1) take the whole byte. * `name length` is the byte length of the name field, a signed 32 bit integer encoded in network (big endian) order (must be >= 0). * `name` is the method name, a UTF-8 encoded string. * `seq id` is the sequence id, a signed 32 bit integer encoded in network (big endian) order. The second, older encoding (aka non-strict) is: ``` Binary protocol Message, old encoding, 9+ bytes: +--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+--------+ | name length | name |00000mmm| seq id | +--------+--------+--------+--------+--------+...+--------+--------+--------+--------+--------+--------+ ``` Where `name length`, `name`, `mmm`, `seq id` are as above. Because `name length` must be positive (therefore the first bit is always `0`), the first bit allows the receiver to see whether the strict format or the old format is used. Therefore a server and client using the different variants of the binary protocol can transparently talk with each other. However, when strict mode is enforced, the old format is rejected. Message types are encoded with the following values: * _Call_: 1 * _Reply_: 2 * _Exception_: 3 * _Oneway_: 4 ## Struct A *Struct* is a sequence of zero or more fields, followed by a stop field. Each field starts with a field header and is followed by the encoded field value. The encoding can be summarized by the following BNF: ``` struct ::= ( field-header field-value )* stop-field field-header ::= field-type field-id ``` Because each field header contains the field-id (as defined by the Thrift IDL file), the fields can be encoded in any order. Thrift's type system is not extensible; you can only encode the primitive types and structs. Therefore is also possible to handle unknown fields while decoding; these are simply ignored. While decoding the field type can be used to determine how to decode the field value. Note that the field name is not encoded so field renames in the IDL do not affect forward and backward compatibility. The default Java implementation (Apache Thrift 0.9.1) has undefined behavior when it tries to decode a field that has another field-type than what is expected. Theoretically, this could be detected at the cost of some additional checking. Other implementation may perform this check and then either ignore the field, or return a protocol exception. A *Union* is encoded exactly the same as a struct with the additional restriction that at most 1 field may be encoded. An *Exception* is encoded exactly the same as a struct. ### Struct encoding In the binary protocol field headers and the stop field are encoded as follows: ``` Binary protocol field header and field value: +--------+--------+--------+--------+...+--------+ |tttttttt| field id | field value | +--------+--------+--------+--------+...+--------+ Binary protocol stop field: +--------+ |00000000| +--------+ ``` Where: * `tttttttt` the field-type, a signed 8 bit integer. * `field id` the field-id, a signed 16 bit integer in big endian order. * `field-value` the encoded field value. The following field-types are used: * `BOOL`, encoded as `2` * `I8`, encoded as `3` * `DOUBLE`, encoded as `4` * `I16`, encoded as `6` * `I32`, encoded as `8` * `I64`, encoded as `10` * `BINARY`, used for binary and string fields, encoded as `11` * `STRUCT`, used for structs and union fields, encoded as `12` * `MAP`, encoded as `13` * `SET`, encoded as `14` * `LIST`, encoded as `15` * `UUID`, encoded as `16` ## List and Set List and sets are encoded the same: a header indicating the size and the element-type of the elements, followed by the encoded elements. ``` Binary protocol list (5+ bytes) and elements: +--------+--------+--------+--------+--------+--------+...+--------+ |tttttttt| size | elements | +--------+--------+--------+--------+--------+--------+...+--------+ ``` Where: * `tttttttt` is the element-type, encoded as an int8 * `size` is the size, encoded as an int32, positive values only * `elements` the element values The element-type values are the same as field-types. The full list is included in the struct section above. The maximum list/set size is configurable. By default, there is no limit (meaning the limit is the maximum int32 value: 2147483647). ## Map Maps are encoded with a header indicating the size, the element-type of the keys and the element-type of the elements, followed by the encoded elements. The encoding follows this BNF: ``` map ::= key-element-type value-element-type size ( key value )* ``` ``` Binary protocol map (6+ bytes) and key value pairs: +--------+--------+--------+--------+--------+--------+--------+...+--------+ |kkkkkkkk|vvvvvvvv| size | key value pairs | +--------+--------+--------+--------+--------+--------+--------+...+--------+ ``` Where: * `kkkkkkkk` is the key element-type, encoded as an int8 * `vvvvvvvv` is the value element-type, encoded as an int8 * `size` is the size of the map, encoded as an int32, positive values only * `key value pairs` are the encoded keys and values The element-type values are the same as field-types. The full list is included in the struct section above. The maximum map size is configurable. By default there is no limit (meaning the limit is the maximum int32 value: 2147483647). # BNF notation used in this document The following BNF notation is used: * a plus `+` appended to an item represents repetition; the item is repeated 1 or more times * a star `*` appended to an item represents optional repetition; the item is repeated 0 or more times * a pipe `|` between items represents choice, the first matching item is selected * parenthesis `(` and `)` are used for grouping multiple items thrift-0.23.0/doc/specs/SequenceNumbers.md0000664000175000017500000000232015165535636020702 0ustar00buildbuild00000000000000# Sequence Number # Apache Thrift built sequence numbers into every protocol exchange to allow for clients that may submit multiple outstanding requests on a single transport connection. This is typically done by asynchronous clients. The following rules apply to sequence numbers: 1. A sequence number is a signed 32-bit integer. Negative values are allowed. 1. Sequence numbers `MUST` be unique across all outstanding requests on a given transport connection. There is no requirement for unique numbers between different transport connections even if they are from the same client. 1. A server `MUST` reply to a client with the same sequence number that was used in the request. This includes any exception-based reply. 1. A client `MAY` use sequence numbers if it needs them for proper operation. 1. A client `SHOULD` set the sequence number to zero if it does not rely on them. 1. Wrapped protocols (such as THeaderProtocol) `SHOULD` use the same sequence number on the wrapping as is used on the payload protocol. Servers will not inspect or make any logic choices based on the sequence number sent by the client. The server's only job is to process the request and reply with the same sequence number. thrift-0.23.0/doc/specs/thrift-parameter-validation-proposal.md0000664000175000017500000002671115165535636025053 0ustar00buildbuild00000000000000# Thrift Parameter Validation Proposal > Version 1.1 > > Dec 15, 2021 > > duanyi.aster@bytedance.com, wangtieju@bytedance.com ### 1. Abstract *** This document presents a proposed set of annotations to the Thrift IDL. The new annotations will supports parameter validation using build-in or third-party validators. The goal of this proposal is to define semantics and behavior of validation annotations, rather than to discuss their implementation. ### 2. Background *** Parameter validation is a common need for web service. In the past, we usually write our validating logics after a RPC message deserialized by thrift. This ways works flexibly enough but restrict poorly: It is dangerous that service A and service B using the same IDL have two different validating rule, which often misdirects developers. Even if we extract our validating codes to a single module, simple and repeated work (ex. `if xx.Field1 > 1 then ...`) is really disturbing. If we can use build tool to generating codes for simple and unchangeable restraint, the web service will be more robust and developers will benefits from lighter work. Compared to other IDL, the parameter validation gradually gets strong community supports like PGV ([protoc-gen-validate](https://github.com/envoyproxy/protoc-gen-validate)), benefiting from pb's strong plugin mechanism (lacking official plugin mechanism is one reason for we submit this proposal). Take a long-term view, auto-generated parameter validation may be a step towards code-less web service. ### 3. Proposal *** This proposal includes three part: Validate Annotation Semantics, Validate Rule and Validate Feedback. The first declare how to write a validate annotation, the middle explain how every annotation should behave, the last introduces a mechanism of validating feedback. #### 3.1 Validate Annotation Semantics This semantics uses same rule of [Thrift IDL](https://thrift.apache.org/docs/idl). The validate option only works on struct fields, thus we must start from Field semantics part. - Field ```peg Field <- FieldID? FieldReq? FieldType Identifier ('=' ConstValue)? ValidateAnnotations? ListSeparator? ``` - ValidateAnnotations ```peg ValidateAnnotations <- '(' ValidateRule+ ListSeparator? ')' ``` - ValidateRule ```peg ValidateRule <- ('validate' | 'vt') Validator+ = '"' ValidatingValue? '"' ``` - Validator Build-in validating logics. See [Supported Validator](#321-supported-validator) part. ```peg Validator <- '.' Identifier ``` - ValidatingValue ```peg ValidatingValue <- (ToolFunction '(' )? Arguments ')'? ``` - ToolFunction Build-in or user-defined tool functions. See [Tool Function](#325-tool-function) part. ```peg ToolFunction <- '@' Identifier ``` - Arguments ```peg Arguments <- (DynamicValue ListSeparator?)* ``` - DynamicValue ```peg DynamicValue <- ConstValue | FieldReference ``` - FieldReference See [Field Reference](#324-field-reference) part. ```apache FieldReference <- '$' ReferPath ReferPath <- FieldName? ( ('['IntConstant']') | ('.'Identifier) )? ``` - All other semantics keep same with [standard definition](https://thrift.apache.org/docs/idl) ### 3.2 Validate Rule The validate rule is works as a Boolean Expression, and Validator is core logic for one validate rule. Every Validator works like an Operator, calculating the Validating Value and Field Value, and then compare. For example, `gt` (greater than) will compare the right Validating Value with value of the field it belongs to, and return `true` if field value is greater than value or `false` if field value is not. We appoint that: Only if the validate rule returns true, the validated parameter is valid. If there are several validate rules defined in annotations of a field, Validator will take the logical relation as "and". Simply put, commas in annotations can be treated as "and". #### 3.2.1 Supported Validator Below lists the support validators. Value type means the type of validating value, field type means type of validated field. | validator | behavior | value type | field type | secondary validator | | ------------ | ------------------------------------- | ------------------------------------ | ---------------------- | ------------------- | | const | must be constant | string, bool | same with value | - | | defined_only | must be defined value | enum | enum | - | | not_nil | must not be empty | "true" | any | - | | skip | skip validate | "true" | any | - | | eq | equals to (`==`) | i8, i16, i32, i64, f64, string, bool | same with value | - | | ne | not equals to (`!=`) | i8, i16, i32, i64, f64, string, bool | same with value | - | | lt | less than (`<`) | i8, i16, i32, i64, f64 | same with value | - | | le | less equal (`<=`) | i8, i16, i32, i64, f64 | same with value | - | | gt | greater than (`>`) | i8, i16, i32, i64, f64 | same with value | - | | ge | greater equal (`>=`) | i8, i16, i32, i64, f64 | same with value | - | | in | within given container | i8, i16, i32, i64, f64, enum | same with value | - | | not_in | not within given container | i8, i16, i32, i64, f64, enum | same with value | - | | elem | field's element constraint | any | list, set | support | | key | field's element key constraint | any | map | support | | value | field's element value constraint | any | map | support | | min_size | minimal length | i8, i16, i32, i64 | string, list, set, map | - | | max_size | maximal length | i8, i16, i32, i64 | string, list, set, map | - | | prefix | field prefix must be (case-sensitive) | string | string | - | | suffix | suffix must be (case-sensitive) | string | string | - | | contains | must contain (case-sensitive) | string | string | - | | not_contains | must not contain (case-sensitive) | string | string | - | | pattern | basic regular expression | string | string | - | - Basic Regular Expression (BRE), the syntax of BRE can be found in [manual](https://www.gnu.org/software/sed/manual/html_node/BRE-syntax.html) of GNU sed. - Secondary validator (`elem`, `key` and `value`) is a successive validator, usually used at container-type field. See below Set/List/Map examples. - Add suffix "_escape" to validators to prevent value of rule conflicting with tool function. For example, you can use `"vt.eq_escape" = "@len(A)"` to match literal `@len(A)`. #### 3.2.2 IDL example - Number ``` struct NumericDemo{ 1: double Value (validator.ge = "1000.1", validator.le = "10000.1") 2: i8 Type (validator.in = "[1, 2, 4]") } ``` - String/Binary ``` struct StringDemo{ 1: string Uninitialized (vt.const = "abc") 2: string Name (vt.min_size = "6", vt.max_size = "12") 3: string SomeStuffs (vt.pattern = "[0-9A-Za-z]+") 4: string DebugInfo (vt.prefix = "[Debug]") 5: string ErrorMessage (vt.contains = "Error") } ``` - Bool ``` struct BoolDemo { 1: bool AMD (vt.const = "true") } ``` - Enum ``` enum Type { Bool I8 I16 I32 I64 String Struct List Set Map } struct EnumDemo { 1: Type AddressType (vt.in = "[String]") 2: Type ValueType (vt.defined_only = "true") } ``` - Set/List ``` struct SetListDemo { 1: list Persons (vt.min_size = "5", vt.max_size = "10") 2: set HealthPoints (vt.elem.gt = "0") } ``` - Map ``` struct MapDemo { 1: map IdName (vt.min_size = "5", vt.max_size = "10") 2: map Some (vt.key.gt = "0", vt.value.lt = "1000") } ``` #### 3.2.3 Arguments Arguments can by static literals or dynamic variables. If one literal expression contains any Field Reference or Tool Function, it becomes dynamic variables. Every dynamic variables finally get calculated and finally become a Thrift Constant Value. #### 3.2.4 Field Reference Field Reference is used to refer to another field's value in Validating Value, therefore user can compare more than one field. The referenced field must be within same struct. Identifier must be the field name referred. - Field Reference Rule 1. `$x` represents a variable named x, and its scope is within current struct 2. `$` indicates the current field in which the validator is located 3. `$x['k']` indicates a reference to the key k of variable x (which must be map) 4. `$x[i]` indicates a reference to the i + 1 element of variable x (which must be list) - Example ``` struct FieldReferenceExample { 1: string A (vt.eq = "$B") //field A must equal to field B 2: list C } ``` #### 3.2.5 Tool Function Tool Function is use to enhance the operating of Validating Value. For example, if we want to ensure one field is larger than the length of string field A, we can use `len()` function: `vt.gt = "@len($A)"`. The arguments can be either literals or variables, and no size limit. However, we won't suggest any build-in function here, because the category is too big and always language-related. Instead, we only propose one mechanism for thrift developers to extends their implementation according to used language. Supported functions: | function | behavior | arguments | results | supported language | | -------- | ----------------------- | ----------------------------------- | -------- | ------------------ | | len | the length of the field | 1: string, binary, list, set or map | 1. int64 | go | ### 3.3 Feedback The generated validating codes should be included in struct's `Validate() TApplicationException` method. If all validate rule declared by one struct get passed, the struct's `Validate() TApplicationException` method returns nil (or just returns without exception, depending on specific language implementation); Otherwise it returns `TApplicationException` and report feedback message indicating failure reason. Due to language function implementations are different, we won't constrain the interface of feedback messages. However, by practice we suggest developers to give below three detail information: - The position where first validating failure happens. - The validator who reports the failure. - The red-handed field value and validating value when the failure happens thrift-0.23.0/doc/specs/thrift-compact-protocol.md0000664000175000017500000002755015165535636022375 0ustar00buildbuild00000000000000Thrift Compact protocol encoding ================================ This documents describes the wire encoding for RPC using the Thrift *compact protocol*. The information here is _mostly_ based on the Java implementation in the Apache thrift library (version 0.9.1) and [THRIFT-110 A more compact format](https://issues.apache.org/jira/browse/THRIFT-110). Other implementation however, should behave the same. For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache.org/static/files/thrift-20070401.pdf). # Contents * Compact protocol * Base types * Message * Struct * List and Set * Map * BNF notation used in this document # Compact protocol ## Base types ### Integer encoding 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 `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 ToZigzag(n: Long): Long = (n << 1) ^ (n >> 63) def FromZigzag(n: Long): Long = (n >>> 1) ^ - (n & 1) ``` 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 = 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) ``` 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`. ### Binary encoding Binary is sent as follows: ``` Binary protocol, binary data, 1+ bytes: +--------+...+--------+--------+...+--------+ | byte length | bytes | +--------+...+--------+--------+...+--------+ ``` Where: * `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. ### 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. ### 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 `2`. ### Universal unique identifier encoding 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: ``` Compact protocol Message (4+ bytes): +--------+--------+--------+...+--------+--------+...+--------+--------+...+--------+ |pppppppp|mmmvvvvv| seq id | name length | name | +--------+--------+--------+...+--------+--------+...+--------+--------+...+--------+ ``` 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 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: * _Call_: 1 * _Reply_: 2 * _Exception_: 3 * _Oneway_: 4 ### Struct A *Struct* is a sequence of zero or more fields, followed by a stop field. Each field starts with a field header and is followed by the encoded field value. The encoding can be summarized by the following BNF: ``` struct ::= ( field-header field-value )* stop-field field-header ::= field-type field-id ``` Because each field header contains the field-id (as defined by the Thrift IDL file), the fields can be encoded in any order. Thrift's type system is not extensible; you can only encode the primitive types and structs. Therefore is also possible to handle unknown fields while decoding; these are simply ignored. While decoding the field type can be used to determine how to decode the field value. Note that the field name is not encoded so field renames in the IDL do not affect forward and backward compatibility. The default Java implementation (Apache Thrift 0.9.1) has undefined behavior when it tries to decode a field that has another field-type than what is expected. Theoretically this could be detected at the cost of some additional checking. Other implementation may perform this check and then either ignore the field, or return a protocol exception. A *Union* is encoded exactly the same as a struct with the additional restriction that at most 1 field may be encoded. An *Exception* is encoded exactly the same as a struct. ### Struct encoding ``` Compact protocol field header (short form) and field value: +--------+--------+...+--------+ |ddddtttt| field value | +--------+--------+...+--------+ Compact protocol field header (1 to 3 bytes, long form) and field value: +--------+--------+...+--------+--------+...+--------+ |0000tttt| field id | field value | +--------+--------+...+--------+--------+...+--------+ Compact protocol stop field: +--------+ |00000000| +--------+ ``` 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 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 first of the struct. The short form should be used when the field id delta is in the range 1 - 15 (inclusive). The following field-types can be encoded: * `BOOLEAN_TRUE`, encoded as `1` * `BOOLEAN_FALSE`, encoded as `2` * `I8`, encoded as `3` * `I16`, encoded as `4` * `I32`, encoded as `5` * `I64`, encoded as `6` * `DOUBLE`, encoded as `7` * `BINARY`, used for binary and string fields, encoded as `8` * `LIST`, encoded as `9` * `SET`, encoded as `10` * `MAP`, encoded as `11` * `STRUCT`, used for both structs and union fields, encoded as `12` * `UUID`, encoded as `13` Note that because there are 2 specific field types for the boolean values, the encoding of a boolean field value has no length (0 bytes). ## List and Set List and sets are encoded the same: a header indicating the size and the element-type of the elements, followed by the encoded elements. ``` Compact protocol list header (1 byte, short form) and elements: +--------+--------+...+--------+ |sssstttt| elements | +--------+--------+...+--------+ Compact protocol list header (2+ bytes, long form) and elements: +--------+--------+...+--------+--------+...+--------+ |1111tttt| size | elements | +--------+--------+...+--------+--------+...+--------+ ``` 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 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 1 below): * `BOOL`, encoded as `1` or `2` (see note 2 below) * `I8`, encoded as `3` * `I16`, encoded as `4` * `I32`, encoded as `5` * `I64`, encoded as `6` * `DOUBLE`, encoded as `7` * `BINARY`, used for binary and string fields, encoded as `8` * `LIST`, encoded as `9` * `SET`, encoded as `10` * `MAP`, encoded as `11` * `STRUCT`, used for structs and union fields, encoded as `12` * `UUID`, encoded as `13` *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). ## Map Maps are encoded with a header indicating the size, the type of the keys and the element-type of the elements, followed by the encoded elements. The encoding follows this BNF: ``` map ::= empty-map | non-empty-map empty-map ::= `0` non-empty-map ::= size key-element-type value-element-type (key value)+ ``` ``` Compact protocol map header (1 byte, empty map): +--------+ |00000000| +--------+ Compact protocol map header (2+ bytes, non empty map) and key value pairs: +--------+...+--------+--------+--------+...+--------+ | size |kkkkvvvv| key value pairs | +--------+...+--------+--------+--------+...+--------+ ``` Where: * `size` is the size, a var int (int32), strictly positive values * `kkkk` is the key element-type, a 4 bit unsigned int * `vvvv` is the value element-type, a 4 bit unsigned int * `key value pairs` are the encoded keys and values The element-types are the same as for lists. The full list is included in the 'List and set' section. The maximum map size is configurable. By default there is no limit (meaning the limit is the maximum int32 value: 2147483647). # BNF notation used in this document The following BNF notation is used: * a plus `+` appended to an item represents repetition; the item is repeated 1 or more times * a star `*` appended to an item represents optional repetition; the item is repeated 0 or more times * a pipe `|` between items represents choice, the first matching item is selected * parenthesis `(` and `)` are used for grouping multiple items thrift-0.23.0/doc/specs/idl.md0000664000175000017500000002732515170007142016340 0ustar00buildbuild00000000000000## Thrift interface description language For Thrift version 0.23.0. The Thrift interface definition language (IDL) allows for the definition of [Thrift Types](/docs/types). A Thrift IDL file is processed by the Thrift code generator to produce code for the various target languages to support the defined structs and services in the IDL file. ## Description Here is a description of the Thrift IDL. ## Document Every Thrift document contains 0 or more headers followed by 0 or more definitions. [1] Document ::= Header* Definition* ## Header A header is either a Thrift include, a C++ include, or a namespace declaration. [2] Header ::= Include | CppInclude | Namespace ### Thrift Include An include makes all the symbols from another file visible (with a prefix) and adds corresponding include statements into the code generated for this Thrift document. [3] Include ::= 'include' Literal ### C++ Include A C++ include adds a custom C++ include to the output of the C++ code generator for this Thrift document. [4] CppInclude ::= 'cpp_include' Literal ### Namespace A namespace declares which namespaces/package/module/etc. the type definitions in this file will be declared in for the target languages. The namespace scope indicates which language the namespace applies to; a scope of '*' indicates that the namespace applies to all target languages. [5] Namespace ::= ( 'namespace' ( NamespaceScope Identifier ) ) [6] NamespaceScope ::= '*' | 'c_glib' | 'cpp' | 'delphi' | 'haxe' | 'go' | 'java' | 'js' | 'lua' | 'netstd' | 'perl' | 'php' | 'py' | 'py.twisted' | 'rb' | 'st' | 'xsd' ## Definition [7] Definition ::= Const | Typedef | Enum | Struct | Union | Exception | Service ### Const [8] Const ::= 'const' FieldType Identifier '=' ConstValue ListSeparator? ### Typedef A typedef creates an alternate name for a type. [9] Typedef ::= 'typedef' DefinitionType Identifier ### Enum An enum creates an enumerated type, with named values. If no constant value is supplied, the value is either 0 for the first element, or one greater than the preceding value for any subsequent element. Any constant value that is supplied must be non-negative. [10] Enum ::= 'enum' Identifier '{' (Identifier ('=' IntConstant)? ListSeparator?)* '}' ### Struct Structs are the fundamental compositional type in Thrift. The name of each field must be unique within the struct. [11] Struct ::= 'struct' Identifier 'xsd_all'? '{' Field* '}' N.B.: The `xsd_all` keyword has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged ### Union Unions are similar to structs, except that they provide a means to transport exactly one field of a possible set of fields, just like union {} in C++. Consequently, union members are implicitly considered optional (see requiredness). [12] Union ::= 'union' Identifier 'xsd_all'? '{' Field* '}' N.B.: The `xsd_all` keyword has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged ### Exception Exceptions are similar to structs except that they are intended to integrate with the native exception handling mechanisms in the target languages. The name of each field must be unique within the exception. [13] Exception ::= 'exception' Identifier '{' Field* '}' ### Service A service provides the interface for a set of functionality provided by a Thrift server. The interface is simply a list of functions. A service can extend another service, which simply means that it provides the functions of the extended service in addition to its own. [14] Service ::= 'service' Identifier ( 'extends' Identifier )? '{' Function* '}' ## Field [15] Field ::= FieldID? FieldReq? FieldType Identifier ('=' ConstValue)? XsdFieldOptions ListSeparator? ### Field ID [16] FieldID ::= IntConstant ':' ### Field Requiredness There are two explicit requiredness values, and a third one that is applied implicitly if neither *required* nor *optional* are given: *default* requiredness. [17] FieldReq ::= 'required' | 'optional' The general rules for requiredness are as follows: #### required - Write: Required fields are always written and are expected to be set. - Read: Required fields are always read and are expected to be contained in the input stream. - Defaults values: are always written If a required field is missing during read, the expected behaviour is to indicate an unsuccessful read operation to the caller, e.g. by throwing an exception or returning an error. Because of this behaviour, required fields drastically limit the options with regard to soft versioning. Because they must be present on read, the fields cannot be deprecated. If a required field would be removed (or changed to optional), the data are no longer compatible between versions. #### optional - Write: Optional fields are only written when they are set - Read: Optional fields may, or may not be part of the input stream. - Default values: are written when the isset flag is set Most language implementations use the recommended practice of so-called "isset" flags to indicate whether a particular optional field is set or not. Only fields with this flag set are written, and conversely the flag is only set when a field value has been read from the input stream. #### default requiredness (implicit) - Write: In theory, the fields are always written. There are some exceptions to that rule, see below. - Read: Like optional, the field may, or may not be part of the input stream. - Default values: may not be written (see next section) Default requiredness is a good starting point. The desired behaviour is a mix of optional and required, hence the internal name "opt-in, req-out". Although in theory these fields are supposed to be written ("req-out"), in reality unset fields are not always written. This is especially the case, when the field contains a value, which by definition cannot be transported through thrift. The only way to achieve this is by not writing that field at all, and that's what most languages do. #### Semantics of Default Values There are ongoing discussions about that topic, see JIRA for details. Not all implementations treat default values in the very same way, but the current status quo is more or less that default fields are typically set at initialization time. Therefore, a value that equals the default may not be written, because the read end will set the value implicitly. On the other hand, an implementation is free to write the default value anyways, as there is no hard restriction that prevents this. The major point to keep in mind here is the fact, that any unwritten default value implicitly becomes part of the interface version. If that default is changed, the interface changes. If, in contrast, the default value is written into the output data, the default in the IDL can change at any time without affecting serialized data. ### XSD Options N.B.: These have some internal purpose at Facebook but serve no current purpose in Thrift. The use of these options is strongly discouraged. [18] XsdFieldOptions ::= 'xsd_optional'? 'xsd_nillable'? XsdAttrs? [19] XsdAttrs ::= 'xsd_attrs' '{' Field* '}' ## Functions [20] Function ::= 'oneway'? FunctionType Identifier '(' Field* ')' Throws? ListSeparator? [21] FunctionType ::= FieldType | 'void' [22] Throws ::= 'throws' '(' Field* ')' ## Types [23] FieldType ::= Identifier | BaseType | ContainerType [24] DefinitionType ::= BaseType | ContainerType [25] BaseType ::= 'bool' | 'byte' | 'i8' | 'i16' | 'i32' | 'i64' | 'double' | 'string' | 'binary' | 'uuid' [26] ContainerType ::= MapType | SetType | ListType [27] MapType ::= 'map' CppType? '<' FieldType ',' FieldType '>' [28] SetType ::= 'set' CppType? '<' FieldType '>' [29] ListType ::= 'list' CppType? '<' FieldType '>' [30] CppType ::= 'cpp_type' Literal ## Constant Values [31] ConstValue ::= IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap [32] IntConstant ::= ('+' | '-')? Digit+ [33] DoubleConstant ::= ('+' | '-')? Digit* ('.' Digit+)? ( ('E' | 'e') IntConstant )? [34] ConstList ::= '[' (ConstValue ListSeparator?)* ']' [35] ConstMap ::= '{' (ConstValue ':' ConstValue ListSeparator?)* '}' ## Basic Definitions ### Literal [36] Literal ::= ('"' [^"]* '"') | ("'" [^']* "'") ### Identifier [37] Identifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' )* [38] STIdentifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' | '-' )* ### List Separator [39] ListSeparator ::= ',' | ';' ### Letters and Digits [40] Letter ::= ['A'-'Z'] | ['a'-'z'] [41] Digit ::= ['0'-'9'] ## Reserved keywords "BEGIN", "END", "__CLASS__", "__DIR__", "__FILE__", "__FUNCTION__", "__LINE__", "__METHOD__", "__NAMESPACE__", "abstract", "alias", "and", "args", "as", "assert", "begin", "break", "case", "catch", "class", "clone", "continue", "declare", "def", "default", "del", "delete", "do", "dynamic", "elif", "else", "elseif", "elsif", "end", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "ensure", "except", "exec", "finally", "float", "for", "foreach", "from", "function", "global", "goto", "if", "implements", "import", "in", "inline", "instanceof", "interface", "is", "lambda", "module", "native", "new", "next", "nil", "not", "or", "package", "pass", "public", "print", "private", "protected", "raise", "redo", "rescue", "retry", "register", "return", "self", "sizeof", "static", "super", "switch", "synchronized", "then", "this", "throw", "transient", "try", "undef", "unless", "unsigned", "until", "use", "var", "virtual", "volatile", "when", "while", "with", "xor", "yield" ## Examples Here are some examples of Thrift definitions, using the Thrift IDL: * [ThriftTest.thrift][] used by the Thrift TestFramework * Thrift [tutorial][] * Facebook's [fb303.thrift][] * [Apache Cassandra's][] Thrift IDL: [cassandra.thrift][] * [Evernote API][] [ThriftTest.thrift]: https://raw.githubusercontent.com/apache/thrift/master/test/ThriftTest.thrift [tutorial]: /tutorial/ [fb303.thrift]: https://raw.githubusercontent.com/apache/thrift/master/contrib/fb303/if/fb303.thrift [Apache Cassandra's]: http://cassandra.apache.org/ [cassandra.thrift]: https://gitbox.apache.org/repos/asf?p=cassandra.git;a=blob_plain;f=interface/cassandra.thrift;hb=refs/heads/cassandra-3.0 [Evernote API]: https://github.com/evernote/evernote-thrift ## To Do/Questions Initialization of Base Types for all Languages? * Do all Languages initialize them to 0, bool=false and string=""? or null, undefined? Why does position of `CppType` vary between `SetType` and `ListType`? * std::set does sort the elements automatically, that's the design. see [Thrift Types](/docs/types) or the [C++ std:set reference][] for further details * The question is, how other languages are doing that? What about custom objects, do they have a Compare function to set the order correctly? [C++ std:set reference]: http://www.cplusplus.com/reference/stl/set/ Why can't `DefinitionType` be the same as `FieldType` (i.e. include `Identifier`)? Examine the `smalltalk.prefix` and `smalltalk.category` status (esp `smalltalk.category`, which takes `STIdentifier` as its argument)... What to do about `ListSeparator`? Do we really want to be as lax as we currently are? Should `Field*` really be `Field+` in `Struct`, `Enum`, etc.? thrift-0.23.0/doc/specs/thrift-sasl-spec.txt0000664000175000017500000001355015165535636021214 0ustar00buildbuild00000000000000A Thrift SASL message shall be a byte array of the following form: | 1-byte status code | 4-byte payload length | variable-length payload | The length fields shall be interpreted as integers, with the high byte sent first. This indicates the length of the field immediately following it, not including the status code or the length bytes. The possible status codes are: 0x01 - START - Hello, let's go on a date. 0x02 - OK - Everything's been going alright so far, let's see each other again. 0x03 - BAD - I understand what you're saying. I really do. I just don't like it. We have to break up. 0x04 - ERROR - We can't go on like this. It's like you're speaking another language. 0x05 - COMPLETE - Will you marry me? The Thrift SASL communication will proceed as follows: 1. The client is configured at instantiation of the transport with a single underlying SASL security mechanism that it supports. 2. The server is configured with a mapping of underlying security mechanism name -> mechanism options. 3. At connection time, the client will initiate communication by sending the server a START message. The payload of this message will be the name of the underlying security mechanism that the client would like to use. This mechanism name shall be 1-20 characters in length, and follow the specifications for SASL mechanism names specified in RFC 2222. 4. The server receives this message and, if the mechanism name provided is among the set of mechanisms this server transport is configured to accept, appropriate initialization of the underlying security mechanism may take place. If the mechanism name is not one which the server is configured to support, the server shall return the BAD byte, followed by a 4-byte, potentially zero-value message length, followed by the potentially zero-length payload which may be a status code or message indicating failure. No further communication may take place via this transport. If the mechanism name is one which the server supports, then proceed to step 5. 5. Following the START message, the client must send another message containing the "initial response" of the chosen SASL implementation. The client may send this message piggy-backed on the "START" message of step 3. The message type of this message must be either "OK" or "COMPLETE", depending on whether the SASL implementation indicates that this side of the authentication has been satisfied. 6. The server then provides the byte array of the payload received to its underlying security mechanism. A challenge is generated by the underlying security mechanism on the server, and this is used as the payload for a message sent to the client. This message shall consist of an OK byte, followed by the non-zero message length word, followed by the payload. 7. The client receives this message from the server and passes the payload to its underlying security mechanism to generate a response. The client then sends the server an OK byte, followed by the non-zero-value length of the response, followed by the bytes of the response as the payload. 8. Steps 6 and 7 are repeated until both security mechanisms are satisfied with the challenge/response exchange. When either side has completed its security protocol, its next message shall be the COMPLETE byte, followed by a 4-byte potentially zero-value length word, followed by a potentially zero-length payload. This payload will be empty except for those underlying security mechanisms which provide additional data with success. If at any point in time either side is able to interpret the challenge or response sent by the other, but is dissatisfied with the contents thereof, this side should send the other a BAD byte, followed by a 4-byte potentially zero-value length word, followed by an optional, potentially zero-length message encoded in UTF-8 indicating failure. This message should be passed to the protocol above the thrift transport by whatever mechanism is appropriate and idiomatic for the particular language these thrift bindings are for. If at any point in time either side fails to interpret the challenge or response sent by the other, this side should send the other an ERROR byte, followed by a 4-byte potentially zero-value length word, followed by an optional, potentially zero-length message encoded in UTF-8. This message should be passed to the protocol above the thrift transport by whatever mechanism is appropriate and idiomatic for the particular language these thrift bindings are for. If step 8 completes successfully, then the communication is considered authenticated and subsequent communication may commence. If step 8 fails to complete successfully, then no further communication may take place via this transport. 8. All writes to the underlying transport must be prefixed by the 4-byte length of the payload data, followed by the payload. All reads from this transport should read the 4-byte length word, then read the full quantity of bytes specified by this length word. If no SASL QOP (quality of protection) is negotiated during steps 6 and 7, then all subsequent writes to/reads from this transport are written/read unaltered, save for the length prefix, to the underlying transport. If a SASL QOP is negotiated, then this must be used by the Thrift transport for all subsequent communication. This is done by wrapping subsequent writes to the transport using the underlying security mechanism, and unwrapping subsequent reads from the underlying transport. Note that in this case, the length prefix of the write to the underlying transport is the length of the data after it has been wrapped by the underlying security mechanism. Note that the complete message must be read before giving this data to the underlying security mechanism for unwrapping. If at any point in time reading of a message fails either because of a malformed length word or failure to unwrap by the underlying security mechanism, then all further communication on this transport must cease. thrift-0.23.0/doc/specs/HeaderFormat.md0000664000175000017500000000763315165535636020153 0ustar00buildbuild00000000000000 Header format for the THeader.h =============================== 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f +----------------------------------------------------------------+ | 0| LENGTH | +----------------------------------------------------------------+ | 0| HEADER MAGIC | FLAGS | +----------------------------------------------------------------+ | SEQUENCE NUMBER | +----------------------------------------------------------------+ | 0| Header Size(/32) | ... +--------------------------------- Header is of variable size: (and starts at offset 14) +----------------------------------------------------------------+ | PROTOCOL ID (varint) | NUM TRANSFORMS (varint) | +----------------------------------------------------------------+ | TRANSFORM 0 ID (varint) | TRANSFORM 0 DATA ... +----------------------------------------------------------------+ | ... ... | +----------------------------------------------------------------+ | INFO 0 ID (varint) | INFO 0 DATA ... +----------------------------------------------------------------+ | ... ... | +----------------------------------------------------------------+ | | | PAYLOAD | | | +----------------------------------------------------------------+ The `LENGTH` field is 32 bits, and counts the remaining bytes in the packet, NOT including the length field. The header size field is 16 bits, and defines the size of the header remaining NOT including the `HEADER MAGIC`, `FLAGS`, `SEQUENCE NUMBER` and header size fields. The Header size field is in bytes/4. The transform ID's are varints. The data for each transform is defined by the transform ID in the code - no size is given in the header. If a transform ID is specified from a client and the server doesn't know about the transform ID, an error MUST be returned as we don't know how to transform the data. Conversely, data in the info headers is ignorable. This should only be things like timestamps, debugging tracing, etc. Using the header size you should be able to skip this data and read the payload safely if you don't know the info ID. Info's should be oldest supported to newest supported order, so that if we read an info ID we don't support, none of the remaining info ID's will be supported either, and we can safely skip to the payload. Info ID's and transform ID's should share the same ID space. ### PADDING: Header will be padded out to next 4-byte boundary with `0x00`. Max frame size is `0x3FFFFFFF`, which is slightly less than `HTTP_MAGIC`. This allows us to distinguish between different (older) transports. ### Transform IDs: ZLIB_TRANSFORM 0x01 - No data for this. Use zlib to (de)compress the data. HMAC_TRANSFORM 0x02 - Variable amount of mac data. One byte to specify size. Mac data is appended at the end of the packet. SNAPPY_TRANSFORM 0x03 - No data for this. Use snappy to (de)compress the data. ### Info IDs: INFO_KEYVALUE 0x01 - varint32 number of headers. - key/value pairs of varstrings (varint16 length plus no-trailing-null string). Implementations MUST NOT alter either key or value in any way. thrift-0.23.0/doc/specs/thrift-protocol-spec.md0000664000175000017500000000613615165535636021676 0ustar00buildbuild00000000000000Thrift Protocol Structure ==================================================================== Last Modified: 2007-Jun-29 This document describes the structure of the Thrift protocol without specifying the encoding. Thus, the order of elements could in some cases be rearranged depending upon the TProtocol implementation, but this document specifies the minimum required structure. There are some "dumb" terminals like STRING and INT that take the place of an actual encoding specification. The key point to notice is that ALL messages are just one wrapped ``. Depending upon the message type, the `` can be interpreted as the argument list to a function, the return value of a function, or an exception. -------------------------------------------------------------------- ``` ::= ::= ::= STRING ::= T_CALL | T_REPLY | T_EXCEPTION | T_ONEWAY ::= I32 ::= * ::= ::= STRING ::= T_STOP ::= ::= ::= STRING ::= T_BOOL | T_BYTE | T_I8 | T_I16 | T_I32 | T_I64 | T_DOUBLE | T_STRING | T_BINARY | T_STRUCT | T_MAP | T_SET | T_LIST | T_UUID ::= I16 ::= I8 | I16 | I32 | I64 | DOUBLE | STRING | BINARY | | | ::= * ::= ::= ::= ::= I32 ::= * ::= ::= ::= I32 ::= * ::= ::= ::= I32 ``` thrift-0.23.0/doc/specs/thrift-rpc.md0000664000175000017500000002154715165535636017674 0ustar00buildbuild00000000000000Thrift Remote Procedure Call ============================ This document describes the high-level message exchange between the Thrift RPC client and server. See [thrift-binary-protocol.md] and [thrift-compact-protocol.md] for a description of how the exchanges are encoded on the wire. In addition, this document compares the binary protocol with the compact protocol. Finally, it describes the framed vs. unframed transport. The information here is _mostly_ based on the Java implementation in the Apache thrift library (version 0.9.1 and 0.9.3). Other implementation, however, should behave the same. For background on Thrift see the [Thrift whitepaper (pdf)](https://thrift.apache.org/static/files/thrift-20070401.pdf). # Contents * Thrift Message exchange for Remote Procedure Call * Message * Request struct * Response struct * Protocol considerations * Comparing binary and compact protocol * Compatibility * Framed vs unframed transport # Thrift Remote Procedure Call Message exchange Both the binary protocol and the compact protocol assume a transport layer that exposes a bi-directional byte stream, for example a TCP socket. Both use the following exchange: 1. Client sends a `Message` (type `Call` or `Oneway`). The TMessage contains some metadata and the name of the method to invoke. 2. Client sends method arguments (a struct defined by the generate code). 3. Server sends a `Message` (type `Reply` or `Exception`) to start the response. 4. Server sends a struct containing the method result or exception. The pattern is a simple half duplex protocol where the parties alternate in sending a `Message` followed by a struct. What these are is described below. Although the standard Apache Thrift Java clients do not support pipelining (sending multiple requests without waiting for an response), the standard Apache Thrift Java servers do support it. ## Message A *Message* contains: * _Name_, a string (can be empty). * _Message type_, a message types, one of `Call`, `Reply`, `Exception` and `Oneway`. * _Sequence id_, a signed int32 integer. The *sequence id* is a simple message id assigned by the client. The server will use the same sequence id in the message of the response. The client uses this number to detect out of order responses. Each client has an int32 field which is increased for each message. The sequence id simply wraps around when it overflows. The *name* indicates the service method name to invoke. The server copies the name in the response message. When the *multiplexed protocol* is used, the name contains the service name, a colon `:` and the method name. The multiplexed protocol is not compatible with other protocols. The *message type* indicates what kind of message is sent. Clients send requests with TMessages of type `Call` or `Oneway` (step 1 in the protocol exchange). Servers send responses with messages of type `Exception` or `Reply` (step 3). Type `Reply` is used when the service method completes normally. That is, it returns a value or it throws one of the exceptions defined in the Thrift IDL file. Type `Exception` is used for other exceptions. That is: when the service method throws an exception that is not declared in the Thrift IDL file, or some other part of the Thrift stack throws an exception. For example when the server could not encode or decode a message or struct. In the Java implementation (0.9.3) there is different behavior for the synchronous and asynchronous server. In the async server all exceptions are sent as a `TApplicationException` (see 'Response struct' below). In the synchronous Java implementation only (undeclared) exceptions that extend `TException` are send as a `TApplicationException`. Unchecked exceptions lead to an immediate close of the connection. Type `Oneway` is only used starting from Apache Thrift 0.9.3. Earlier versions do _not_ send TMessages of type `Oneway`, even for service methods defined with the `oneway` modifier. When the client sends a request with type `Oneway`, the server must _not_ send a response (steps 3 and 4 are skipped). Note that the Thrift IDL enforces a return type of `void` and does not allow exceptions for oneway services. ## Request struct The struct that follows the message of type `Call` or `Oneway` contains the arguments of the service method. The argument ids correspond to the field ids. The name of the struct is the name of the method with `_args` appended. For methods without arguments an struct is sent without fields. ## Response struct The struct that follows the message of type `Reply` are structs in which exactly 1 of the following fields is encoded: * A field with name `success` and id `0`, used in case the method completed normally. * An exception field, name and id are as defined in the `throws` clause in the Thrift IDL's service method definition. When the message is of type `Exception` the struct is encoded as if it was declared by the following IDL: ``` exception TApplicationException { 1: string message, 2: i32 type } ``` The following exception types are defined in the java implementation (0.9.3): * _unknown_: 0, used in case the type from the peer is unknown. * _unknown method_: 1, used in case the method requested by the client is unknown by the server. * _invalid message type_: 2, no usage was found. * _wrong method name_: 3, no usage was found. * _bad sequence id_: 4, used internally by the client to indicate a wrong sequence id in the response. * _missing result_: 5, used internally by the client to indicate a response without any field (result nor exception). * _internal error_: 6, used when the server throws an exception that is not declared in the Thrift IDL file. * _protocol error_: 7, used when something goes wrong during decoding. For example when a list is too long or a required field is missing. * _invalid transform_: 8, no usage was found. * _invalid protocol_: 9, no usage was found. * _unsupported client type_: 10, no usage was found. # Protocol considerations ## Comparing binary and compact protocol The binary protocol is fairly simple and therefore easy to process. The compact protocol needs less bytes to send the same data at the cost of additional processing. As bandwidth is usually the bottleneck, the compact protocol is almost always slightly faster. ## Compatibility A server could automatically determine whether a client talks the binary protocol or the compact protocol by investigating the first byte. If the value is `1000 0000` or `0000 0000` (assuming a name shorter than ±16 MB) it is the binary protocol. When the value is `1000 0010` it is talking the compact protocol. ## Framed vs. unframed transport The first thrift binary wire format was unframed. This means that information is sent out in a single stream of bytes. With unframed transport the (generated) processors will read directly from the socket (though Apache Thrift does try to grab all available bytes from the socket in a buffer when it can). Later, Thrift introduced the framed transport. With framed transport the full request and response (the TMessage and the following struct) are first written to a buffer. Then when the struct is complete (transport method `flush` is hijacked for this), the length of the buffer is written to the socket first, followed by the buffered bytes. The combination is called a _frame_. On the receiver side the complete frame is first read in a buffer before the message is passed to a processor. The length prefix is a 4 byte signed int, send in network (big endian) order. The following must be true: `0` <= length <= `16384000` (16M). Framed transport was introduced to ease the implementation of async processors. An async processor is only invoked when all data is received. Unfortunately, framed transport is not ideal for large messages as the entire frame stays in memory until the message has been processed. In addition, the java implementation merges the incoming data to a single, growing byte array. Every time the byte array is full it needs to be copied to a new larger byte array. Framed and unframed transports are not compatible with each other. thrift-0.23.0/doc/specs/thrift-tconfiguration.md0000664000175000017500000001277015165535636022141 0ustar00buildbuild00000000000000Thrift TConfiguration ==================================================================== Last Modified: 2019-Dec-03 Starting with THRIFT-5021 the need to centralize certain limit settings that are used throughout the whole protocol / transport stack became an obvious need. Previous patches already added some of these limits, but they were not consistently managed and just randomly distributed across the code base. # Design goals Following the tradition of similar experience across languages in Thrift, any implementation should meet these design goals: * There MUST be a standard CTOR (or equivalent thereof) that provides a default TConfiguration instance. * The default values used SHOULD be implemented as outlined below. * For backwards compatibility, the protocol / transport stack should accept null TConfiguration argument, in which case it should fallback to a default instance automatically. This is to prevent from code-breaking changes as much as possible. # Implementation The new TConfiguration class or struct currently holds three settings: ## MaxMessageSize The MaxMessageSize member defines the maximum size of a (received) message, in bytes. The default value is represented by a constant named DEFAULT_MAX_MESSAGE_SIZE, whose value is 100 * 1024 * 1024 bytes. ## MaxFrameSize MaxFrameSize limits the size of one frame of data for the TFramedTransport. Since all implementations currently send messages in one frame only if TFramedTransport is used, this value may interfere with MaxMessageSize. In the case of an conflict, the smaller value of the two is used (see remark below). The default value is called DEFAULT_MAX_FRAME_SIZE and has a value of 16384000 bytes. ## RecursionLimit The RecursionLimit defines, how deep structures may be nested into each other. The default named DEFAULT_RECURSION_DEPTH allows for structures nested up to 64 levels deep. # Further considerations ## MaxFrameSize vs. MaxMessageSize The difference between the two options is, that MaxFrameSize exists much longer and it is used only in conjunction with TFramedTransport. In contrast, MaxMessageSize is intended to be a general device to be used with any transport or protocol. In order to combine both approaches in the most optimal way when using TFramedTransport, it is recommended that the implementation SHOULD update the remaining number of bytes to read based on the received frame size value for the current message. For calculation purposes it is important to know, that MaxFrameSize excludes the 4 bytes that hold the frame size, while MaxMessageSize is always looking at the whole data. Hence, when updating the remaining read byte count, the known message size should be set to frameSize + sizeof(i32). ## Error handling If any limit is exceeded, an error should be thrown. Additionally, it may be helpful to check larger memory allocations against the remaining max number of bytes before the allocation attempt takes place. # Q&A ## Is this a breaking change or not? There is actually two answers to that question. 1. If done right, it should not be a breaking change vis-á-vis compiling your source code that uses Thrift. 1. It may, however, be a breaking change in the way it limits the accepted overall size of messages or the accepted frame size. This behaviour is by design. If your application hits any of these limits during normal operation, it may require you to instantiate an actual TConfiguration and tweak the settings according to your needs. ## Is splitting the general transport base class into Endpoint and Layered transport base classes necessary? No, it's not. However, it turned out that this split is a great help when it comes to managing the TConfiguration instance that is passed through the stack. Having two distinct base classes for each of the different transport types not only allows to implement a shared solution for this. The added benefit is, that a clear distinction between the two transport types makes the Thrift architectural idea much more clear to "newbie" developers. ## I want to contribute an implementation of TConfiguration and I am not sure whether to pick class or struct? Short answer: Pick whatever is more efficient in the language of your choice. Technically, remember that the instance is passed down the stack and should therefore be cheap on copying. To ensure this and to make sure all pieces of the protocol / transport stack are really pointing to the same TConfiguration instance, we want to pass the instance **by reference** rather than by value. For example, in the C# language a class is a suitable choice for this, because classes are naturally reference parameters, while structs are not. thrift-0.23.0/doc/specs/thrift.tex0000664000175000017500000013710315165535636017306 0ustar00buildbuild00000000000000%----------------------------------------------------------------------------- % % Thrift whitepaper % % Name: thrift.tex % % Authors: Mark Slee (mcslee@facebook.com) % % Created: 05 March 2007 % % You will need a copy of sigplanconf.cls to format this document. % It is available at . % %----------------------------------------------------------------------------- \documentclass[nocopyrightspace,blockstyle]{sigplanconf} \usepackage{amssymb} \usepackage{amsfonts} \usepackage{amsmath} \usepackage{url} \begin{document} % \conferenceinfo{WXYZ '05}{date, City.} % \copyrightyear{2007} % \copyrightdata{[to be supplied]} % \titlebanner{banner above paper title} % These are ignored unless % \preprintfooter{short description of paper} % 'preprint' option specified. \title{Thrift: Scalable Cross-Language Services Implementation} \subtitle{} \authorinfo{Mark Slee, Aditya Agarwal and Marc Kwiatkowski} {Facebook, 156 University Ave, Palo Alto, CA} {\{mcslee,aditya,marc\}@facebook.com} \maketitle \begin{abstract} Thrift is a software library and set of code-generation tools developed at Facebook to expedite development and implementation of efficient and scalable backend services. Its primary goal is to enable efficient and reliable communication across programming languages by abstracting the portions of each language that tend to require the most customization into a common library that is implemented in each language. Specifically, Thrift allows developers to define datatypes and service interfaces in a single language-neutral file and generate all the necessary code to build RPC clients and servers. This paper details the motivations and design choices we made in Thrift, as well as some of the more interesting implementation details. It is not intended to be taken as research, but rather it is an exposition on what we did and why. \end{abstract} % \category{D.3.3}{Programming Languages}{Language constructs and features} %\terms %Languages, serialization, remote procedure call %\keywords %Data description language, interface definition language, remote procedure call \section{Introduction} As Facebook's traffic and network structure have scaled, the resource demands of many operations on the site (i.e. search, ad selection and delivery, event logging) have presented technical requirements drastically outside the scope of the LAMP framework. In our implementation of these services, various programming languages have been selected to optimize for the right combination of performance, ease and speed of development, availability of existing libraries, etc. By and large, Facebook's engineering culture has tended towards choosing the best tools and implementations available over standardizing on any one programming language and begrudgingly accepting its inherent limitations. Given this design choice, we were presented with the challenge of building a transparent, high-performance bridge across many programming languages. We found that most available solutions were either too limited, did not offer sufficient datatype freedom, or suffered from subpar performance. \footnote{See Appendix A for a discussion of alternative systems.} The solution that we have implemented combines a language-neutral software stack implemented across numerous programming languages and an associated code generation engine that transforms a simple interface and data definition language into client and server remote procedure call libraries. Choosing static code generation over a dynamic system allows us to create validated code that can be run without the need for any advanced introspective run-time type checking. It is also designed to be as simple as possible for the developer, who can typically define all the necessary data structures and interfaces for a complex service in a single short file. Surprised that a robust open solution to these relatively common problems did not yet exist, we committed early on to making the Thrift implementation open source. In evaluating the challenges of cross-language interaction in a networked environment, some key components were identified: \textit{Types.} A common type system must exist across programming languages without requiring that the application developer use custom Thrift datatypes or write their own serialization code. That is, a C++ programmer should be able to transparently exchange a strongly typed STL map for a dynamic Python dictionary. Neither programmer should be forced to write any code below the application layer to achieve this. Section 2 details the Thrift type system. \textit{Transport.} Each language must have a common interface to bidirectional raw data transport. The specifics of how a given transport is implemented should not matter to the service developer. The same application code should be able to run against TCP stream sockets, raw data in memory, or files on disk. Section 3 details the Thrift Transport layer. \textit{Protocol.} Datatypes must have some way of using the Transport layer to encode and decode themselves. Again, the application developer need not be concerned by this layer. Whether the service uses an XML or binary protocol is immaterial to the application code. All that matters is that the data can be read and written in a consistent, deterministic matter. Section 4 details the Thrift Protocol layer. \textit{Versioning.} For robust services, the involved datatypes must provide a mechanism for versioning themselves. Specifically, it should be possible to add or remove fields in an object or alter the argument list of a function without any interruption in service (or, worse yet, nasty segmentation faults). Section 5 details Thrift's versioning system. \textit{Processors.} Finally, we generate code capable of processing data streams to accomplish remote procedure calls. Section 6 details the generated code and TProcessor paradigm. Section 7 discusses implementation details, and Section 8 describes our conclusions. \section{Types} The goal of the Thrift type system is to enable programmers to develop using completely natively defined types, no matter what programming language they use. By design, the Thrift type system does not introduce any special dynamic types or wrapper objects. It also does not require that the developer write any code for object serialization or transport. The Thrift IDL (Interface Definition Language) file is logically a way for developers to annotate their data structures with the minimal amount of extra information necessary to tell a code generator how to safely transport the objects across languages. \subsection{Base Types} The type system rests upon a few base types. In considering which types to support, we aimed for clarity and simplicity over abundance, focusing on the key types available in all programming languages, omitting any niche types available only in specific languages. The base types supported by Thrift are: \begin{itemize} \item \texttt{bool} A boolean value, true or false \item \texttt{byte} A signed byte \item \texttt{i16} A 16-bit signed integer \item \texttt{i32} A 32-bit signed integer \item \texttt{i64} A 64-bit signed integer \item \texttt{double} A 64-bit floating point number \item \texttt{string} An encoding-agnostic text or binary string \item \texttt{binary} A byte array representation for blobs \end{itemize} Of particular note is the absence of unsigned integer types. Because these types have no direct translation to native primitive types in many languages, the advantages they afford are lost. Further, there is no way to prevent the application developer in a language like Python from assigning a negative value to an integer variable, leading to unpredictable behavior. From a design standpoint, we observed that unsigned integers were very rarely, if ever, used for arithmetic purposes, but in practice were much more often used as keys or identifiers. In this case, the sign is irrelevant. Signed integers serve this same purpose and can be safely cast to their unsigned counterparts (most commonly in C++) when absolutely necessary. \subsection{Structs} A Thrift struct defines a common object to be used across languages. A struct is essentially equivalent to a class in object oriented programming languages. A struct has a set of strongly typed fields, each with a unique name identifier. The basic syntax for defining a Thrift struct looks very similar to a C struct definition. Fields may be annotated with an integer field identifier (unique to the scope of that struct) and optional default values. Field identifiers will be automatically assigned if omitted, though they are strongly encouraged for versioning reasons discussed later. \subsection{Containers} Thrift containers are strongly typed containers that map to the most commonly used containers in common programming languages. They are annotated using the C++ template (or Java Generics) style. There are three types available: \begin{itemize} \item \texttt{list} An ordered list of elements. Translates directly into an STL \texttt{vector}, Java \texttt{ArrayList}, or native array in scripting languages. May contain duplicates. \item \texttt{set} An unordered set of unique elements. Translates into an STL \texttt{set}, Java \texttt{HashSet}, \texttt{set} in Python, or native dictionary in PHP/Ruby. \item \texttt{map} A map of strictly unique keys to values Translates into an STL \texttt{map}, Java \texttt{HashMap}, PHP associative array, or Python/Ruby dictionary. \end{itemize} While defaults are provided, the type mappings are not explicitly fixed. Custom code generator directives have been added to substitute custom types in destination languages (i.e. \texttt{hash\_map} or Google's sparse hash map can be used in C++). The only requirement is that the custom types support all the necessary iteration primitives. Container elements may be of any valid Thrift type, including other containers or structs. \begin{verbatim} struct Example { 1:i32 number=10, 2:i64 bigNumber, 3:double decimals, 4:string name="thrifty" }\end{verbatim} In the target language, each definition generates a type with two methods, \texttt{read} and \texttt{write}, which perform serialization and transport of the objects using a Thrift TProtocol object. \subsection{Exceptions} Exceptions are syntactically and functionally equivalent to structs except that they are declared using the \texttt{exception} keyword instead of the \texttt{struct} keyword. The generated objects inherit from an exception base class as appropriate in each target programming language, in order to seamlessly integrate with native exception handling in any given language. Again, the design emphasis is on making the code familiar to the application developer. \subsection{Services} Services are defined using Thrift types. Definition of a service is semantically equivalent to defining an interface (or a pure virtual abstract class) in object oriented programming. The Thrift compiler generates fully functional client and server stubs that implement the interface. Services are defined as follows: \begin{verbatim} service { () [throws ()] ... }\end{verbatim} An example: \begin{verbatim} service StringCache { void set(1:i32 key, 2:string value), string get(1:i32 key) throws (1:KeyNotFound knf), void delete(1:i32 key) } \end{verbatim} Note that \texttt{void} is a valid type for a function return, in addition to all other defined Thrift types. Additionally, an \texttt{async} modifier keyword may be added to a \texttt{void} function, which will generate code that does not wait for a response from the server. Note that a pure \texttt{void} function will return a response to the client which guarantees that the operation has completed on the server side. With \texttt{async} method calls the client will only be guaranteed that the request succeeded at the transport layer. (In many transport scenarios this is inherently unreliable due to the Byzantine Generals' Problem. Therefore, application developers should take care only to use the async optimization in cases where dropped method calls are acceptable or the transport is known to be reliable.) Also of note is the fact that argument lists and exception lists for functions are implemented as Thrift structs. All three constructs are identical in both notation and behavior. \section{Transport} The transport layer is used by the generated code to facilitate data transfer. \subsection{Interface} A key design choice in the implementation of Thrift was to decouple the transport layer from the code generation layer. Though Thrift is typically used on top of the TCP/IP stack with streaming sockets as the base layer of communication, there was no compelling reason to build that constraint into the system. The performance tradeoff incurred by an abstracted I/O layer (roughly one virtual method lookup / function call per operation) was immaterial compared to the cost of actual I/O operations (typically invoking system calls). Fundamentally, generated Thrift code only needs to know how to read and write data. The origin and destination of the data are irrelevant; it may be a socket, a segment of shared memory, or a file on the local disk. The Thrift transport interface supports the following methods: \begin{itemize} \item \texttt{open} Opens the transport \item \texttt{close} Closes the transport \item \texttt{isOpen} Indicates whether the transport is open \item \texttt{read} Reads from the transport \item \texttt{write} Writes to the transport \item \texttt{flush} Forces any pending writes \end{itemize} There are a few additional methods not documented here which are used to aid in batching reads and optionally signaling the completion of a read or write operation from the generated code. In addition to the above \texttt{TTransport} interface, there is a\\ \texttt{TServerTransport} interface used to accept or create primitive transport objects. Its interface is as follows: \begin{itemize} \item \texttt{open} Opens the transport \item \texttt{listen} Begins listening for connections \item \texttt{accept} Returns a new client transport \item \texttt{close} Closes the transport \end{itemize} \subsection{Implementation} The transport interface is designed for simple implementation in any programming language. New transport mechanisms can be easily defined as needed by application developers. \subsubsection{TSocket} The \texttt{TSocket} class is implemented across all target languages. It provides a common, simple interface to a TCP/IP stream socket. \subsubsection{TFileTransport} The \texttt{TFileTransport} is an abstraction of an on-disk file to a data stream. It can be used to write out a set of incoming Thrift requests to a file on disk. The on-disk data can then be replayed from the log, either for post-processing or for reproduction and/or simulation of past events. \subsubsection{Utilities} The Transport interface is designed to support easy extension using common OOP techniques, such as composition. Some simple utilities include the \texttt{TBufferedTransport}, which buffers the writes and reads on an underlying transport, the \texttt{TFramedTransport}, which transmits data with frame size headers for chunking optimization or nonblocking operation, and the \texttt{TMemoryBuffer}, which allows reading and writing directly from the heap or stack memory owned by the process. \section{Protocol} A second major abstraction in Thrift is the separation of data structure from transport representation. Thrift enforces a certain messaging structure when transporting data, but it is agnostic to the protocol encoding in use. That is, it does not matter whether data is encoded as XML, human-readable ASCII, or a dense binary format as long as the data supports a fixed set of operations that allow it to be deterministically read and written by generated code. \subsection{Interface} The Thrift Protocol interface is very straightforward. It fundamentally supports two things: 1) bidirectional sequenced messaging, and 2) encoding of base types, containers, and structs. \begin{verbatim} writeMessageBegin(name, type, seq) writeMessageEnd() writeStructBegin(name) writeStructEnd() writeFieldBegin(name, type, id) writeFieldEnd() writeFieldStop() writeMapBegin(ktype, vtype, size) writeMapEnd() writeListBegin(etype, size) writeListEnd() writeSetBegin(etype, size) writeSetEnd() writeBool(bool) writeByte(byte) writeI16(i16) writeI32(i32) writeI64(i64) writeDouble(double) writeString(string) name, type, seq = readMessageBegin() readMessageEnd() name = readStructBegin() readStructEnd() name, type, id = readFieldBegin() readFieldEnd() k, v, size = readMapBegin() readMapEnd() etype, size = readListBegin() readListEnd() etype, size = readSetBegin() readSetEnd() bool = readBool() byte = readByte() i16 = readI16() i32 = readI32() i64 = readI64() double = readDouble() string = readString() \end{verbatim} Note that every \texttt{write} function has exactly one \texttt{read} counterpart, with the exception of \texttt{writeFieldStop()}. This is a special method that signals the end of a struct. The procedure for reading a struct is to \texttt{readFieldBegin()} until the stop field is encountered, and then to \texttt{readStructEnd()}. The generated code relies upon this call sequence to ensure that everything written by a protocol encoder can be read by a matching protocol decoder. Further note that this set of functions is by design more robust than necessary. For example, \texttt{writeStructEnd()} is not strictly necessary, as the end of a struct may be implied by the stop field. This method is a convenience for verbose protocols in which it is cleaner to separate these calls (e.g. a closing \texttt{} tag in XML). \subsection{Structure} Thrift structures are designed to support encoding into a streaming protocol. The implementation should never need to frame or compute the entire data length of a structure prior to encoding it. This is critical to performance in many scenarios. Consider a long list of relatively large strings. If the protocol interface required reading or writing a list to be an atomic operation, then the implementation would need to perform a linear pass over the entire list before encoding any data. However, if the list can be written as iteration is performed, the corresponding read may begin in parallel, theoretically offering an end-to-end speedup of $(kN - C)$, where $N$ is the size of the list, $k$ the cost factor associated with serializing a single element, and $C$ is fixed offset for the delay between data being written and becoming available to read. Similarly, structs do not encode their data lengths a priori. Instead, they are encoded as a sequence of fields, with each field having a type specifier and a unique field identifier. Note that the inclusion of type specifiers allows the protocol to be safely parsed and decoded without any generated code or access to the original IDL file. Structs are terminated by a field header with a special \texttt{STOP} type. Because all the basic types can be read deterministically, all structs (even those containing other structs) can be read deterministically. The Thrift protocol is self-delimiting without any framing and regardless of the encoding format. In situations where streaming is unnecessary or framing is advantageous, it can be very simply added into the transport layer, using the \texttt{TFramedTransport} abstraction. \subsection{Implementation} Facebook has implemented and deployed a space-efficient binary protocol which is used by most backend services. Essentially, it writes all data in a flat binary format. Integer types are converted to network byte order, strings are prepended with their byte length, and all message and field headers are written using the primitive integer serialization constructs. String names for fields are omitted - when using generated code, field identifiers are sufficient. We decided against some extreme storage optimizations (i.e. packing small integers into ASCII or using a 7-bit continuation format) for the sake of simplicity and clarity in the code. These alterations can easily be made if and when we encounter a performance-critical use case that demands them. \section{Versioning} Thrift is robust in the face of versioning and data definition changes. This is critical to enable staged rollouts of changes to deployed services. The system must be able to support reading of old data from log files, as well as requests from out-of-date clients to new servers, and vice versa. \subsection{Field Identifiers} Versioning in Thrift is implemented via field identifiers. The field header for every member of a struct in Thrift is encoded with a unique field identifier. The combination of this field identifier and its type specifier is used to uniquely identify the field. The Thrift definition language supports automatic assignment of field identifiers, but it is good programming practice to always explicitly specify field identifiers. Identifiers are specified as follows: \begin{verbatim} struct Example { 1:i32 number=10, 2:i64 bigNumber, 3:double decimals, 4:string name="thrifty" }\end{verbatim} To avoid conflicts between manually and automatically assigned identifiers, fields with identifiers omitted are assigned identifiers decrementing from -1, and the language only supports the manual assignment of positive identifiers. When data is being deserialized, the generated code can use these identifiers to properly identify the field and determine whether it aligns with a field in its definition file. If a field identifier is not recognized, the generated code can use the type specifier to skip the unknown field without any error. Again, this is possible due to the fact that all datatypes are self delimiting. Field identifiers can (and should) also be specified in function argument lists. In fact, argument lists are not only represented as structs on the backend, but actually share the same code in the compiler frontend. This allows for version-safe modification of method parameters \begin{verbatim} service StringCache { void set(1:i32 key, 2:string value), string get(1:i32 key) throws (1:KeyNotFound knf), void delete(1:i32 key) } \end{verbatim} The syntax for specifying field identifiers was chosen to echo their structure. Structs can be thought of as a dictionary where the identifiers are keys, and the values are strongly-typed named fields. Field identifiers internally use the \texttt{i16} Thrift type. Note, however, that the \texttt{TProtocol} abstraction may encode identifiers in any format. \subsection{Isset} When an unexpected field is encountered, it can be safely ignored and discarded. When an expected field is not found, there must be some way to signal to the developer that it was not present. This is implemented via an inner \texttt{isset} structure inside the defined objects. (Isset functionality is implicit with a \texttt{null} value in PHP, \texttt{None} in Python and \texttt{nil} in Ruby.) Essentially, the inner \texttt{isset} object of each Thrift struct contains a boolean value for each field which denotes whether or not that field is present in the struct. When a reader receives a struct, it should check for a field being set before operating directly on it. \begin{verbatim} class Example { public: Example() : number(10), bigNumber(0), decimals(0), name("thrifty") {} int32_t number; int64_t bigNumber; double decimals; std::string name; struct __isset { __isset() : number(false), bigNumber(false), decimals(false), name(false) {} bool number; bool bigNumber; bool decimals; bool name; } __isset; ... } \end{verbatim} \subsection{Case Analysis} There are four cases in which version mismatches may occur. \begin{enumerate} \item \textit{Added field, old client, new server.} In this case, the old client does not send the new field. The new server recognizes that the field is not set, and implements default behavior for out-of-date requests. \item \textit{Removed field, old client, new server.} In this case, the old client sends the removed field. The new server simply ignores it. \item \textit{Added field, new client, old server.} The new client sends a field that the old server does not recognize. The old server simply ignores it and processes as normal. \item \textit{Removed field, new client, old server.} This is the most dangerous case, as the old server is unlikely to have suitable default behavior implemented for the missing field. It is recommended that in this situation the new server be rolled out prior to the new clients. \end{enumerate} \subsection{Protocol/Transport Versioning} The \texttt{TProtocol} abstractions are also designed to give protocol implementations the freedom to version themselves in whatever manner they see fit. Specifically, any protocol implementation is free to send whatever it likes in the \texttt{writeMessageBegin()} call. It is entirely up to the implementor how to handle versioning at the protocol level. The key point is that protocol encoding changes are safely isolated from interface definition version changes. Note that the exact same is true of the \texttt{TTransport} interface. For example, if we wished to add some new checksumming or error detection to the \texttt{TFileTransport}, we could simply add a version header into the data it writes to the file in such a way that it would still accept old log files without the given header. \section{RPC Implementation} \subsection{TProcessor} The last core interface in the Thrift design is the \texttt{TProcessor}, perhaps the most simple of the constructs. The interface is as follows: \begin{verbatim} interface TProcessor { bool process(TProtocol in, TProtocol out) throws TException } \end{verbatim} The key design idea here is that the complex systems we build can fundamentally be broken down into agents or services that operate on inputs and outputs. In most cases, there is actually just one input and output (an RPC client) that needs handling. \subsection{Generated Code} When a service is defined, we generate a \texttt{TProcessor} instance capable of handling RPC requests to that service, using a few helpers. The fundamental structure (illustrated in pseudo-C++) is as follows: \begin{verbatim} Service.thrift => Service.cpp interface ServiceIf class ServiceClient : virtual ServiceIf TProtocol in TProtocol out class ServiceProcessor : TProcessor ServiceIf handler ServiceHandler.cpp class ServiceHandler : virtual ServiceIf TServer.cpp TServer(TProcessor processor, TServerTransport transport, TTransportFactory tfactory, TProtocolFactory pfactory) serve() \end{verbatim} From the Thrift definition file, we generate the virtual service interface. A client class is generated, which implements the interface and uses two \texttt{TProtocol} instances to perform the I/O operations. The generated processor implements the \texttt{TProcessor} interface. The generated code has all the logic to handle RPC invocations via the \texttt{process()} call, and takes as a parameter an instance of the service interface, as implemented by the application developer. The user provides an implementation of the application interface in separate, non-generated source code. \subsection{TServer} Finally, the Thrift core libraries provide a \texttt{TServer} abstraction. The \texttt{TServer} object generally works as follows. \begin{itemize} \item Use the \texttt{TServerTransport} to get a \texttt{TTransport} \item Use the \texttt{TTransportFactory} to optionally convert the primitive transport into a suitable application transport (typically the \texttt{TBufferedTransportFactory} is used here) \item Use the \texttt{TProtocolFactory} to create an input and output protocol for the \texttt{TTransport} \item Invoke the \texttt{process()} method of the \texttt{TProcessor} object \end{itemize} The layers are appropriately separated such that the server code needs to know nothing about any of the transports, encodings, or applications in play. The server encapsulates the logic around connection handling, threading, etc. while the processor deals with RPC. The only code written by the application developer lives in the definitional Thrift file and the interface implementation. Facebook has deployed multiple \texttt{TServer} implementations, including the single-threaded \texttt{TSimpleServer}, thread-per-connection \texttt{TThreadedServer}, and thread-pooling \texttt{TThreadPoolServer}. The \texttt{TProcessor} interface is very general by design. There is no requirement that a \texttt{TServer} take a generated \texttt{TProcessor} object. Thrift allows the application developer to easily write any type of server that operates on \texttt{TProtocol} objects (for instance, a server could simply stream a certain type of object without any actual RPC method invocation). \section{Implementation Details} \subsection{Target Languages} Thrift currently supports five target languages: C++, Java, Python, Ruby, and PHP. At Facebook, we have deployed servers predominantly in C++, Java, and Python. Thrift services implemented in PHP have also been embedded into the Apache web server, providing transparent backend access to many of our frontend constructs using a \texttt{THttpClient} implementation of the \texttt{TTransport} interface. Though Thrift was explicitly designed to be much more efficient and robust than typical web technologies, as we were designing our XML-based REST web services API we noticed that Thrift could be easily used to define our service interface. Though we do not currently employ SOAP envelopes (in the authors' opinions there is already far too much repetitive enterprise Java software to do that sort of thing), we were able to quickly extend Thrift to generate XML Schema Definition files for our service, as well as a framework for versioning different implementations of our web service. Though public web services are admittedly tangential to Thrift's core use case and design, Thrift facilitated rapid iteration and affords us the ability to quickly migrate our entire XML-based web service onto a higher performance system should the need arise. \subsection{Generated Structs} We made a conscious decision to make our generated structs as transparent as possible. All fields are publicly accessible; there are no \texttt{set()} and \texttt{get()} methods. Similarly, use of the \texttt{isset} object is not enforced. We do not include any \texttt{FieldNotSetException} construct. Developers have the option to use these fields to write more robust code, but the system is robust to the developer ignoring the \texttt{isset} construct entirely and will provide suitable default behavior in all cases. This choice was motivated by the desire to ease application development. Our stated goal is not to make developers learn a rich new library in their language of choice, but rather to generate code that allow them to work with the constructs that are most familiar in each language. We also made the \texttt{read()} and \texttt{write()} methods of the generated objects public so that the objects can be used outside of the context of RPC clients and servers. Thrift is a useful tool simply for generating objects that are easily serializable across programming languages. \subsection{RPC Method Identification} Method calls in RPC are implemented by sending the method name as a string. One issue with this approach is that longer method names require more bandwidth. We experimented with using fixed-size hashes to identify methods, but in the end concluded that the savings were not worth the headaches incurred. Reliably dealing with conflicts across versions of an interface definition file is impossible without a meta-storage system (i.e. to generate non-conflicting hashes for the current version of a file, we would have to know about all conflicts that ever existed in any previous version of the file). We wanted to avoid too many unnecessary string comparisons upon method invocation. To deal with this, we generate maps from strings to function pointers, so that invocation is effectively accomplished via a constant-time hash lookup in the common case. This requires the use of a couple interesting code constructs. Because Java does not have function pointers, process functions are all private member classes implementing a common interface. \begin{verbatim} private class ping implements ProcessFunction { public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException { ...} } HashMap processMap_ = new HashMap(); \end{verbatim} In C++, we use a relatively esoteric language construct: member function pointers. \begin{verbatim} std::map processMap_; \end{verbatim} Using these techniques, the cost of string processing is minimized, and we reap the benefit of being able to easily debug corrupt or misunderstood data by inspecting it for known string method names. \subsection{Servers and Multithreading} Thrift services require basic multithreading to handle simultaneous requests from multiple clients. For the Python and Java implementations of Thrift server logic, the standard threading libraries distributed with the languages provide adequate support. For the C++ implementation, no standard multithread runtime library exists. Specifically, robust, lightweight, and portable thread manager and timer class implementations do not exist. We investigated existing implementations, namely \texttt{boost::thread}, \texttt{boost::threadpool}, \texttt{ACE\_Thread\_Manager} and \texttt{ACE\_Timer}. While \texttt{boost::threads}\cite{boost.threads} provides clean, lightweight and robust implementations of multi-thread primitives (mutexes, conditions, threads) it does not provide a thread manager or timer implementation. \texttt{boost::threadpool}\cite{boost.threadpool} also looked promising but was not far enough along for our purposes. We wanted to limit the dependency on third-party libraries as much as possible. Because\\ \texttt{boost::threadpool} is not a pure template library and requires runtime libraries and because it is not yet part of the official Boost distribution we felt it was not ready for use in Thrift. As \texttt{boost::threadpool} evolves and especially if it is added to the Boost distribution we may reconsider our decision to not use it. ACE has both a thread manager and timer class in addition to multi-thread primitives. The biggest problem with ACE is that it is ACE. Unlike Boost, ACE API quality is poor. Everything in ACE has large numbers of dependencies on everything else in ACE - thus forcing developers to throw out standard classes, such as STL collections, in favor of ACE's homebrewed implementations. In addition, unlike Boost, ACE implementations demonstrate little understanding of the power and pitfalls of C++ programming and take no advantage of modern templating techniques to ensure compile time safety and reasonable compiler error messages. For all these reasons, ACE was rejected. Instead, we chose to implement our own library, described in the following sections. \subsection{Thread Primitives} The Thrift thread libraries are implemented in the namespace\\ \texttt{facebook::thrift::concurrency} and have three components: \begin{itemize} \item primitives \item thread pool manager \item timer manager \end{itemize} As mentioned above, we were hesitant to introduce any additional dependencies on Thrift. We decided to use \texttt{boost::shared\_ptr} because it is so useful for multithreaded application, it requires no link-time or runtime libraries (i.e. it is a pure template library) and it is due to become part of the C++0x standard. We implement standard \texttt{Mutex} and \texttt{Condition} classes, and a \texttt{Monitor} class. The latter is simply a combination of a mutex and condition variable and is analogous to the \texttt{Monitor} implementation provided for the Java \texttt{Object} class. This is also sometimes referred to as a barrier. We provide a \texttt{Synchronized} guard class to allow Java-like synchronized blocks. This is just a bit of syntactic sugar, but, like its Java counterpart, clearly delimits critical sections of code. Unlike its Java counterpart, we still have the ability to programmatically lock, unlock, block, and signal monitors. \begin{verbatim} void run() { {Synchronized s(manager->monitor); if (manager->state == TimerManager::STARTING) { manager->state = TimerManager::STARTED; manager->monitor.notifyAll(); } } } \end{verbatim} We again borrowed from Java the distinction between a thread and a runnable class. A \texttt{Thread} is the actual schedulable object. The \texttt{Runnable} is the logic to execute within the thread. The \texttt{Thread} implementation deals with all the platform-specific thread creation and destruction issues, while the \texttt{Runnable} implementation deals with the application-specific per-thread logic. The benefit of this approach is that developers can easily subclass the Runnable class without pulling in platform-specific super-classes. \subsection{Thread, Runnable, and shared\_ptr} We use \texttt{boost::shared\_ptr} throughout the \texttt{ThreadManager} and \texttt{TimerManager} implementations to guarantee cleanup of dead objects that can be accessed by multiple threads. For \texttt{Thread} class implementations, \texttt{boost::shared\_ptr} usage requires particular attention to make sure \texttt{Thread} objects are neither leaked nor dereferenced prematurely while creating and shutting down threads. Thread creation requires calling into a C library. (In our case the POSIX thread library, \texttt{libpthread}, but the same would be true for WIN32 threads). Typically, the OS makes few, if any, guarantees about when \texttt{ThreadMain}, a C thread's entry-point function, will be called. Therefore, it is possible that our thread create call, \texttt{ThreadFactory::newThread()} could return to the caller well before that time. To ensure that the returned \texttt{Thread} object is not prematurely cleaned up if the caller gives up its reference prior to the \texttt{ThreadMain} call, the \texttt{Thread} object makes a weak reference to itself in its \texttt{start} method. With the weak reference in hand the \texttt{ThreadMain} function can attempt to get a strong reference before entering the \texttt{Runnable::run} method of the \texttt{Runnable} object bound to the \texttt{Thread}. If no strong references to the thread are obtained between exiting \texttt{Thread::start} and entering \texttt{ThreadMain}, the weak reference returns \texttt{null} and the function exits immediately. The need for the \texttt{Thread} to make a weak reference to itself has a significant impact on the API. Since references are managed through the \texttt{boost::shared\_ptr} templates, the \texttt{Thread} object must have a reference to itself wrapped by the same \texttt{boost::shared\_ptr} envelope that is returned to the caller. This necessitated the use of the factory pattern. \texttt{ThreadFactory} creates the raw \texttt{Thread} object and a \texttt{boost::shared\_ptr} wrapper, and calls a private helper method of the class implementing the \texttt{Thread} interface (in this case, \texttt{PosixThread::weakRef}) to allow it to make add weak reference to itself through the \texttt{boost::shared\_ptr} envelope. \texttt{Thread} and \texttt{Runnable} objects reference each other. A \texttt{Runnable} object may need to know about the thread in which it is executing, and a Thread, obviously, needs to know what \texttt{Runnable} object it is hosting. This interdependency is further complicated because the lifecycle of each object is independent of the other. An application may create a set of \texttt{Runnable} object to be reused in different threads, or it may create and forget a \texttt{Runnable} object once a thread has been created and started for it. The \texttt{Thread} class takes a \texttt{boost::shared\_ptr} reference to the hosted \texttt{Runnable} object in its constructor, while the \texttt{Runnable} class has an explicit \texttt{thread} method to allow explicit binding of the hosted thread. \texttt{ThreadFactory::newThread} binds the objects to each other. \subsection{ThreadManager} \texttt{ThreadManager} creates a pool of worker threads and allows applications to schedule tasks for execution as free worker threads become available. The \texttt{ThreadManager} does not implement dynamic thread pool resizing, but provides primitives so that applications can add and remove threads based on load. This approach was chosen because implementing load metrics and thread pool size is very application specific. For example some applications may want to adjust pool size based on running-average of work arrival rates that are measured via polled samples. Others may simply wish to react immediately to work-queue depth high and low water marks. Rather than trying to create a complex API abstract enough to capture these different approaches, we simply leave it up to the particular application and provide the primitives to enact the desired policy and sample current status. \subsection{TimerManager} \texttt{TimerManager} allows applications to schedule \texttt{Runnable} objects for execution at some point in the future. Its specific task is to allows applications to sample \texttt{ThreadManager} load at regular intervals and make changes to the thread pool size based on application policy. Of course, it can be used to generate any number of timer or alarm events. The default implementation of \texttt{TimerManager} uses a single thread to execute expired \texttt{Runnable} objects. Thus, if a timer operation needs to do a large amount of work and especially if it needs to do blocking I/O, that should be done in a separate thread. \subsection{Nonblocking Operation} Though the Thrift transport interfaces map more directly to a blocking I/O model, we have implemented a high performance \texttt{TNonBlockingServer} in C++ based on \texttt{libevent} and the \texttt{TFramedTransport}. We implemented this by moving all I/O into one tight event loop using a state machine. Essentially, the event loop reads framed requests into \texttt{TMemoryBuffer} objects. Once entire requests are ready, they are dispatched to the \texttt{TProcessor} object which can read directly from the data in memory. \subsection{Compiler} The Thrift compiler is implemented in C++ using standard \texttt{lex}/\texttt{yacc} lexing and parsing. Though it could have been implemented with fewer lines of code in another language (i.e. Python Lex-Yacc (PLY) or \texttt{ocamlyacc}), using C++ forces explicit definition of the language constructs. Strongly typing the parse tree elements (debatably) makes the code more approachable for new developers. Code generation is done using two passes. The first pass looks only for include files and type definitions. Type definitions are not checked during this phase, since they may depend upon include files. All included files are sequentially scanned in a first pass. Once the include tree has been resolved, a second pass over all files is taken that inserts type definitions into the parse tree and raises an error on any undefined types. The program is then generated against the parse tree. Due to inherent complexities and potential for circular dependencies, we explicitly disallow forward declaration. Two Thrift structs cannot each contain an instance of the other. (Since we do not allow \texttt{null} struct instances in the generated C++ code, this would actually be impossible.) \subsection{TFileTransport} The \texttt{TFileTransport} logs Thrift requests/structs by framing incoming data with its length and writing it out to disk. Using a framed on-disk format allows for better error checking and helps with the processing of a finite number of discrete events. The\\ \texttt{TFileWriterTransport} uses a system of swapping in-memory buffers to ensure good performance while logging large amounts of data. A Thrift log file is split up into chunks of a specified size; logged messages are not allowed to cross chunk boundaries. A message that would cross a chunk boundary will cause padding to be added until the end of the chunk and the first byte of the message are aligned to the beginning of the next chunk. Partitioning the file into chunks makes it possible to read and interpret data from a particular point in the file. \section{Facebook Thrift Services} Thrift has been employed in a large number of applications at Facebook, including search, logging, mobile, ads and the developer platform. Two specific usages are discussed below. \subsection{Search} Thrift is used as the underlying protocol and transport layer for the Facebook Search service. The multi-language code generation is well suited for search because it allows for application development in an efficient server side language (C++) and allows the Facebook PHP-based web application to make calls to the search service using Thrift PHP libraries. There is also a large variety of search stats, deployment and testing functionality that is built on top of generated Python code. Additionally, the Thrift log file format is used as a redo log for providing real-time search index updates. Thrift has allowed the search team to leverage each language for its strengths and to develop code at a rapid pace. \subsection{Logging} The Thrift \texttt{TFileTransport} functionality is used for structured logging. Each service function definition along with its parameters can be considered to be a structured log entry identified by the function name. This log can then be used for a variety of purposes, including inline and offline processing, stats aggregation and as a redo log. \section{Conclusions} Thrift has enabled Facebook to build scalable backend services efficiently by enabling engineers to divide and conquer. Application developers can focus on application code without worrying about the sockets layer. We avoid duplicated work by writing buffering and I/O logic in one place, rather than interspersing it in each application. Thrift has been employed in a wide variety of applications at Facebook, including search, logging, mobile, ads, and the developer platform. We have found that the marginal performance cost incurred by an extra layer of software abstraction is far eclipsed by the gains in developer efficiency and systems reliability. \appendix \section{Similar Systems} The following are software systems similar to Thrift. Each is (very!) briefly described: \begin{itemize} \item \textit{SOAP.} XML-based. Designed for web services via HTTP, excessive XML parsing overhead. \item \textit{CORBA.} Relatively comprehensive, debatably overdesigned and heavyweight. Comparably cumbersome software installation. \item \textit{COM.} Embraced mainly in Windows client software. Not an entirely open solution. \item \textit{Pillar.} Lightweight and high-performance, but missing versioning and abstraction. \item \textit{Protocol Buffers.} Closed-source, owned by Google. Described in Sawzall paper. \end{itemize} \acks Many thanks for feedback on Thrift (and extreme trial by fire) are due to Martin Smith, Karl Voskuil and Yishan Wong. Thrift is a successor to Pillar, a similar system developed by Adam D'Angelo, first while at Caltech and continued later at Facebook. Thrift simply would not have happened without Adam's insights. \begin{thebibliography}{} \bibitem{boost.threads} Kempf, William, ``Boost.Threads'', \url{http://www.boost.org/doc/html/threads.html} \bibitem{boost.threadpool} Henkel, Philipp, ``threadpool'', \url{http://threadpool.sourceforge.net} \end{thebibliography} \end{document} thrift-0.23.0/doc/licenses/0000775000175000017500000000000015165535636015747 5ustar00buildbuild00000000000000thrift-0.23.0/doc/licenses/otp-base-license.txt0000664000175000017500000000216415165535636021645 0ustar00buildbuild00000000000000Tue Oct 24 12:28:44 CDT 2006 Copyright (c) <2006> Permission is hereby granted, free of charge, to any person obtaining a copy of this software (OTP Base, fslib, G.A.S) and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. thrift-0.23.0/.clang-format0000664000175000017500000000324415165535636015753 0ustar00buildbuild00000000000000--- Language: Cpp # BasedOnStyle: LLVM AccessModifierOffset: -2 ConstructorInitializerIndentWidth: 2 AlignEscapedNewlinesLeft: false AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: false AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AllowShortFunctionsOnASingleLine: Inline AlwaysBreakTemplateDeclarations: true AlwaysBreakBeforeMultilineStrings: true BreakBeforeBinaryOperators: true BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BinPackParameters: false ColumnLimit: 100 ConstructorInitializerAllOnOneLineOrOnePerLine: true DerivePointerAlignment: false IndentCaseLabels: false IndentWrappedFunctionNames: false IndentFunctionDeclarationAfterType: false MaxEmptyLinesToKeep: 1 KeepEmptyLinesAtTheStartOfBlocks: true NamespaceIndentation: None ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakBeforeFirstCallParameter: 190 PenaltyBreakComment: 300 PenaltyBreakString: 10000 PenaltyBreakFirstLessLess: 120 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 1200 PointerAlignment: Left SpacesBeforeTrailingComments: 1 Cpp11BracedListStyle: true Standard: Auto IndentWidth: 2 TabWidth: 4 UseTab: Never BreakBeforeBraces: Attach SpacesInParentheses: false SpacesInAngles: false SpaceInEmptyParentheses: false SpacesInCStyleCastParentheses: false SpacesInContainerLiterals: true SpaceBeforeAssignmentOperators: true ContinuationIndentWidth: 4 CommentPragmas: '^ IWYU pragma:' ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] SpaceBeforeParens: ControlStatements DisableFormat: false ... thrift-0.23.0/ylwrap0000755000175000017500000001531415166015674014637 0ustar00buildbuild00000000000000#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . get_dirname () { case $1 in */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; # Otherwise, we want the empty string (not "."). esac } # guard FILE # ---------- # The CPP macro used to guard inclusion of FILE. guard () { printf '%s\n' "$1" \ | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ -e 's/__*/_/g' } # quote_for_sed [STRING] # ---------------------- # Return STRING (or stdin) quoted to be used as a sed pattern. quote_for_sed () { case $# in 0) cat;; 1) printf '%s\n' "$1";; esac \ | sed -e 's|[][\\.*]|\\&|g' } case "$1" in '') echo "$0: No files given. Try '$0 --help' for more information." 1>&2 exit 1 ;; --basedir) basedir=$2 shift 2 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . EOF exit $? ;; -v|--v*) echo "ylwrap $scriptversion" exit $? ;; esac # The input. input=$1 shift # We'll later need for a correct munging of "#line" directives. input_sub_rx=`get_dirname "$input" | quote_for_sed` case $input in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input=`pwd`/$input ;; esac input_rx=`get_dirname "$input" | quote_for_sed` # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot=false if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot=true fi # The parser itself, the first file, is the destination of the .y.c # rule in the Makefile. parser=$1 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for # instance, we rename #include "y.tab.h" into #include "parse.h" # during the conversion from y.tab.c to parse.c. sed_fix_filenames= # Also rename header guards, as Bison 2.7 for instance uses its header # guard in its implementation file. sed_fix_header_guards= while test $# -ne 0; do if test x"$1" = x"--"; then shift break fi from=$1 # Handle y_tab.c and y_tab.h output by DOS if $y_tab_nodot; then case $from in "y.tab.c") from=y_tab.c;; "y.tab.h") from=y_tab.h;; esac fi shift to=$1 shift sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" done # The program to run. prog=$1 shift # Make any relative path in $prog absolute. case $prog in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog=`pwd`/$prog ;; esac dirname=ylwrap$$ do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 mkdir $dirname || exit 1 cd $dirname case $# in 0) "$prog" "$input" ;; *) "$prog" "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then for from in * do to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend '../'. case $to in [\\/]* | ?:[\\/]*) target=$to;; *) target=../$to;; esac # Do not overwrite unchanged header files to avoid useless # recompilations. Always update the parser itself: it is the # destination of the .y.c rule in the Makefile. Divert the # output of all other files to a temporary file so we can # compare them to existing versions. if test $from != $parser; then realtarget=$target target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` fi # Munge "#line" or "#" directives. Don't let the resulting # debug information point at an absolute srcdir. Use the real # output file name, not yy.lex.c for instance. Adjust the # include guards too. sed -e "/^#/!b" \ -e "s|$input_rx|$input_sub_rx|" \ -e "$sed_fix_filenames" \ -e "$sed_fix_header_guards" \ "$from" >"$target" || ret=$? # Check whether files must be updated. if test "$from" != "$parser"; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$to is unchanged" rm -f "$target" else echo "updating $to" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the parser. This is a # blatant hack to let us support using "yacc -d". If -d is not # specified, don't fail when the header file is "missing". if test "$from" = "$parser"; then ret=1 fi fi done fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: thrift-0.23.0/CLAUDE.md0000664000175000017500000000001315167543515014643 0ustar00buildbuild00000000000000@AGENTS.md thrift-0.23.0/test/0000755000175000017500000000000015170007201014324 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/0000755000175000017500000000000015170007201014731 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/src/0000755000175000017500000000000015170007201015520 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/src/bin/0000775000175000017500000000000015165535636016320 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/src/bin/testclient/0000775000175000017500000000000015165535636020476 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/src/bin/testclient/main.go0000664000175000017500000002416115165535636021755 0ustar00buildbuild00000000000000/* * 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 main import ( "bytes" "context" "flag" "fmt" t "log" "reflect" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/test/go/src/common" "github.com/apache/thrift/test/go/src/gen/thrifttest" ) var host = flag.String("host", "localhost", "Host to connect") var port = flag.Int64("port", 9090, "Port number to connect") var domain_socket = flag.String("domain-socket", "", "Domain Socket (e.g. /tmp/thrifttest.thrift), instead of host and port") var transport = flag.String("transport", "buffered", "Transport: buffered, framed, http, zlib") var _ = flag.Bool("zlib", false, "For compatibility. Ignored.") var protocol = flag.String("protocol", "binary", "Protocol: binary, compact, json") var ssl = flag.Bool("ssl", false, "Encrypted Transport using SSL") var testloops = flag.Int("testloops", 1, "Number of Tests") func main() { flag.Parse() 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 range *testloops { callEverything(client) } } var rmapmap = map[int32]map[int32]int32{ -4: {-4: -4, -3: -3, -2: -2, -1: -1}, 4: {4: 4, 3: 3, 2: 2, 1: 1}, } var xxs = &thrifttest.Xtruct{ StringThing: "Hello2", ByteThing: 42, I32Thing: 4242, I64Thing: 424242, } var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "Xception"} var defaultCtx = context.Background() func callEverything(client *thrifttest.ThriftTestClient) { var err error if err = client.TestVoid(defaultCtx); err != nil { t.Fatalf("Unexpected error in TestVoid() call: ", err) } thing, err := client.TestString(defaultCtx, "thing") if err != nil { t.Fatalf("Unexpected error in TestString() call: ", err) } if thing != "thing" { t.Fatalf("Unexpected TestString() result, expected 'thing' got '%s' ", thing) } bl, err := client.TestBool(defaultCtx, true) if err != nil { t.Fatalf("Unexpected error in TestBool() call: ", err) } if !bl { t.Fatalf("Unexpected TestBool() result expected true, got %f ", bl) } bl, err = client.TestBool(defaultCtx, false) if err != nil { t.Fatalf("Unexpected error in TestBool() call: ", err) } if bl { t.Fatalf("Unexpected TestBool() result expected false, got %f ", bl) } b, err := client.TestByte(defaultCtx, 42) if err != nil { t.Fatalf("Unexpected error in TestByte() call: ", err) } if b != 42 { t.Fatalf("Unexpected TestByte() result expected 42, got %d ", b) } i32, err := client.TestI32(defaultCtx, 4242) if err != nil { t.Fatalf("Unexpected error in TestI32() call: ", err) } if i32 != 4242 { t.Fatalf("Unexpected TestI32() result expected 4242, got %d ", i32) } i64, err := client.TestI64(defaultCtx, 424242) if err != nil { t.Fatalf("Unexpected error in TestI64() call: ", err) } if i64 != 424242 { t.Fatalf("Unexpected TestI64() result expected 424242, got %d ", i64) } d, err := client.TestDouble(defaultCtx, 42.42) if err != nil { t.Fatalf("Unexpected error in TestDouble() call: ", err) } if d != 42.42 { t.Fatalf("Unexpected TestDouble() result expected 42.42, got %f ", d) } binout := make([]byte, 256) for i := range binout { binout[i] = byte(i) } bin, err := client.TestBinary(defaultCtx, binout) if err != nil { t.Fatalf("TestBinary failed with %v", err) } if !bytes.Equal(binout, bin) { t.Fatalf("Unexpected TestBinary() result expected % 02x, got % 02x ", binout, bin) } uout := thrift.Tuuid{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, } u, err := client.TestUuid(defaultCtx, uout) if err != nil { t.Fatalf("TestUuid failed with %v", err) } if u != uout { t.Fatalf("Unexpected TestUuid() result expected %v, got %v", uout, u) } xs := thrifttest.NewXtruct() xs.StringThing = "thing" xs.ByteThing = 42 xs.I32Thing = 4242 xs.I64Thing = 424242 xsret, err := client.TestStruct(defaultCtx, xs) if err != nil { t.Fatalf("Unexpected error in TestStruct() call: ", err) } if *xs != *xsret { t.Fatalf("Unexpected TestStruct() result expected %#v, got %#v ", xs, xsret) } x2 := thrifttest.NewXtruct2() x2.StructThing = xs x2ret, err := client.TestNest(defaultCtx, x2) if err != nil { t.Fatalf("Unexpected error in TestNest() call: ", err) } if !reflect.DeepEqual(x2, x2ret) { t.Fatalf("Unexpected TestNest() result expected %#v, got %#v ", x2, x2ret) } m := map[int32]int32{1: 2, 3: 4, 5: 42} mret, err := client.TestMap(defaultCtx, m) if err != nil { t.Fatalf("Unexpected error in TestMap() call: ", err) } if !reflect.DeepEqual(m, mret) { t.Fatalf("Unexpected TestMap() result expected %#v, got %#v ", m, mret) } sm := map[string]string{"a": "2", "b": "blah", "some": "thing"} smret, err := client.TestStringMap(defaultCtx, sm) if err != nil { t.Fatalf("Unexpected error in TestStringMap() call: ", err) } if !reflect.DeepEqual(sm, smret) { t.Fatalf("Unexpected TestStringMap() result expected %#v, got %#v ", sm, smret) } s := []int32{1, 2, 42} sret, err := client.TestSet(defaultCtx, s) if err != nil { t.Fatalf("Unexpected error in TestSet() call: ", err) } // Sets can be in any order, but Go slices are ordered, so reflect.DeepEqual won't work. stemp := map[int32]struct{}{} for _, val := range s { stemp[val] = struct{}{} } for _, val := range sret { if _, ok := stemp[val]; !ok { t.Fatalf("Unexpected TestSet() result expected %#v, got %#v ", s, sret) } } l := []int32{1, 2, 42} lret, err := client.TestList(defaultCtx, l) if err != nil { t.Fatalf("Unexpected error in TestList() call: ", err) } if !reflect.DeepEqual(l, lret) { t.Fatalf("Unexpected TestList() result expected %#v, got %#v ", l, lret) } eret, err := client.TestEnum(defaultCtx, thrifttest.Numberz_TWO) if err != nil { t.Fatalf("Unexpected error in TestEnum() call: ", err) } if eret != thrifttest.Numberz_TWO { t.Fatalf("Unexpected TestEnum() result expected %#v, got %#v ", thrifttest.Numberz_TWO, eret) } tret, err := client.TestTypedef(defaultCtx, thrifttest.UserId(42)) if err != nil { t.Fatalf("Unexpected error in TestTypedef() call: ", err) } if tret != thrifttest.UserId(42) { t.Fatalf("Unexpected TestTypedef() result expected %#v, got %#v ", thrifttest.UserId(42), tret) } mapmap, err := client.TestMapMap(defaultCtx, 42) if err != nil { t.Fatalf("Unexpected error in TestMapMap() call: ", err) } if !reflect.DeepEqual(mapmap, rmapmap) { t.Fatalf("Unexpected TestMapMap() result expected %#v, got %#v ", rmapmap, mapmap) } crazy := thrifttest.NewInsanity() crazy.UserMap = map[thrifttest.Numberz]thrifttest.UserId{ thrifttest.Numberz_FIVE: 5, thrifttest.Numberz_EIGHT: 8, } truck1 := thrifttest.NewXtruct() truck1.StringThing = "Goodbye4" truck1.ByteThing = 4 truck1.I32Thing = 4 truck1.I64Thing = 4 truck2 := thrifttest.NewXtruct() truck2.StringThing = "Hello2" truck2.ByteThing = 2 truck2.I32Thing = 2 truck2.I64Thing = 2 crazy.Xtructs = []*thrifttest.Xtruct{ truck1, truck2, } insanity, err := client.TestInsanity(defaultCtx, crazy) if err != nil { t.Fatalf("Unexpected error in TestInsanity() call: ", err) } if !reflect.DeepEqual(crazy, insanity[1][2]) { t.Fatalf("Unexpected TestInsanity() first result expected %#v, got %#v ", crazy, insanity[1][2]) } if !reflect.DeepEqual(crazy, insanity[1][3]) { t.Fatalf("Unexpected TestInsanity() second result expected %#v, got %#v ", crazy, insanity[1][3]) } if len(insanity[2][6].UserMap) > 0 || len(insanity[2][6].Xtructs) > 0 { t.Fatalf("Unexpected TestInsanity() non-empty result got %#v ", insanity[2][6]) } xxsret, err := client.TestMulti(defaultCtx, 42, 4242, 424242, map[int16]string{1: "blah", 2: "thing"}, thrifttest.Numberz_EIGHT, thrifttest.UserId(24)) if err != nil { t.Fatalf("Unexpected error in TestMulti() call: ", err) } if !reflect.DeepEqual(xxs, xxsret) { t.Fatalf("Unexpected TestMulti() result expected %#v, got %#v ", xxs, xxsret) } err = client.TestException(defaultCtx, "Xception") if err == nil { t.Fatalf("Expecting exception in TestException() call") } if !reflect.DeepEqual(err, xcept) { t.Fatalf("Unexpected TestException() result expected %#v, got %#v ", xcept, err) } err = client.TestException(defaultCtx, "TException") _, ok := err.(thrift.TApplicationException) if err == nil || !ok { t.Fatalf("Unexpected TestException() result expected ApplicationError, got %#v ", err) } ign, err := client.TestMultiException(defaultCtx, "Xception", "ignoreme") if ign != nil || err == nil { t.Fatalf("Expecting exception in TestMultiException() call") } if !reflect.DeepEqual(err, &thrifttest.Xception{ErrorCode: 1001, Message: "This is an Xception"}) { t.Fatalf("Unexpected TestMultiException() %#v ", err) } ign, err = client.TestMultiException(defaultCtx, "Xception2", "ignoreme") if ign != nil || err == nil { t.Fatalf("Expecting exception in TestMultiException() call") } expecting := &thrifttest.Xception2{ErrorCode: 2002, StructThing: &thrifttest.Xtruct{StringThing: "This is an Xception2"}} if !reflect.DeepEqual(err, expecting) { t.Fatalf("Unexpected TestMultiException() %#v ", err) } err = client.TestOneway(defaultCtx, 2) if err != nil { t.Fatalf("Unexpected error in TestOneway() call: ", err) } //Make sure the connection still alive if err = client.TestVoid(defaultCtx); err != nil { t.Fatalf("Unexpected error in TestVoid() call: ", err) } } thrift-0.23.0/test/go/src/bin/testserver/0000775000175000017500000000000015165535636020526 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/src/bin/testserver/main.go0000664000175000017500000000501415165535636022001 0ustar00buildbuild00000000000000/* * 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 main import ( "flag" "fmt" "log" "net/http" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/test/go/src/common" ) var host = flag.String("host", "localhost", "Host to connect") var port = flag.Int64("port", 9090, "Port number to connect") var domain_socket = flag.String("domain-socket", "", "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port") var transport = flag.String("transport", "buffered", "Transport: buffered, framed, http, zlib") var _ = flag.Bool("zlib", false, "For compatibility. Ignored.") var protocol = flag.String("protocol", "binary", "Protocol: binary, compact, json, header") var ssl = flag.Bool("ssl", false, "Encrypted Transport using SSL") var certPath = flag.String("certPath", "keys", "Directory that contains SSL certificates") func main() { flag.Parse() 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) } if *transport == "http" { http.HandleFunc("/", thrift.NewThriftHandlerFunc(processor, protocolFactory, protocolFactory)) if *ssl { err := http.ListenAndServeTLS(fmt.Sprintf(":%d", *port), *certPath+"/server.pem", *certPath+"/server.key", nil) if err != nil { fmt.Println(err) return } } else { if err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil); err != nil { fmt.Println(err) return } } } else { server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) if err = server.Listen(); err != nil { return } go server.AcceptLoop() server.Serve() } } thrift-0.23.0/test/go/src/bin/stress/0000775000175000017500000000000015165535636017643 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/src/bin/stress/main.go0000664000175000017500000001535115165535636021123 0ustar00buildbuild00000000000000/* * 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 main import ( "context" "flag" "fmt" "log" _ "net/http/pprof" "os" "runtime" "runtime/pprof" "sync" "sync/atomic" "time" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/test/go/src/gen/stress" ) var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file") var memprofile = flag.String("memprofile", "", "write memory profile to this file") var ( host = flag.String("host", "localhost", "Host to connect") port = flag.Int64("port", 9091, "Port number to connect") loop = flag.Int("loops", 50000, "The number of remote thrift calls each client makes") runserver = flag.Int("server", 1, "Run the Thrift server in this process") clients = flag.Int("clients", 20, "Number of client threads to create - 0 implies no clients, i.e. server only") callName = flag.String("call", "echoVoid", "Service method to call, one of echoVoid, echoByte, echoI32, echoI64, echoString, echiList, echoSet, echoMap") compact = flag.Bool("compact", false, "Use compact protocol instead of binary.") framed = flag.Bool("framed", false, "Use framed transport instead of buffered.") ) var hostPort string type callT int64 const ( echoVoid callT = iota echoByte echoI32 echoI64 echoString echiList echoSet echoMap ) var callTMap = map[string]callT{ "echoVoid": echoVoid, "echoByte": echoByte, "echoI32": echoI32, "echoI64": echoI64, "echoString": echoString, "echiList": echiList, "echoSet": echoSet, "echoMap": echoMap, } var callType callT var ready, done sync.WaitGroup var clicounter int64 = 0 var counter int64 = 0 func main() { flag.Parse() if *memprofile != "" { runtime.MemProfileRate = 100 } var ok bool if callType, ok = callTMap[*callName]; !ok { log.Fatal("Unknown service call", *callName) } if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } hostPort = fmt.Sprintf("%s:%d", *host, *port) var protocolFactory thrift.TProtocolFactory var transportFactory thrift.TTransportFactory if *compact { protocolFactory = thrift.NewTCompactProtocolFactoryConf(nil) } else { protocolFactory = thrift.NewTBinaryProtocolFactoryConf(nil) } if *framed { transportFactory = thrift.NewTTransportFactory() transportFactory = thrift.NewTFramedTransportFactoryConf(transportFactory, nil) } else { transportFactory = thrift.NewTBufferedTransportFactory(8192) } if *runserver > 0 { serverTransport, err := thrift.NewTServerSocket(hostPort) if err != nil { log.Fatalf("Unable to create server socket: %s", err) } processor := stress.NewServiceProcessor(&handler{}) server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) if *clients == 0 { server.Serve() } else { go server.Serve() } } //start clients if *clients != 0 { ready.Add(*clients + 1) done.Add(*clients) for range *clients { go client(protocolFactory) } ready.Done() ready.Wait() //run! startTime := time.Now() //wait for completion done.Wait() endTime := time.Now() duration := endTime.Sub(startTime) log.Printf("%d calls in %v (%f calls per second)\n", clicounter, duration, float64(clicounter)/duration.Seconds()) } if *memprofile != "" { f, err := os.Create(*memprofile) if err != nil { log.Fatal(err) } pprof.WriteHeapProfile(f) f.Close() return } } func client(protocolFactory thrift.TProtocolFactory) { ctx := context.Background() trans := thrift.NewTSocketConf(hostPort, nil) btrans := thrift.NewTBufferedTransport(trans, 2048) client := stress.NewServiceClientFactory(btrans, protocolFactory) err := trans.Open() if err != nil { log.Fatalf("Unable to open connection: %s", err) } ready.Done() ready.Wait() switch callType { case echoVoid: for range *loop { client.EchoVoid(ctx) atomic.AddInt64(&clicounter, 1) } case echoByte: for range *loop { client.EchoByte(ctx, 42) atomic.AddInt64(&clicounter, 1) } case echoI32: for range *loop { client.EchoI32(ctx, 4242) atomic.AddInt64(&clicounter, 1) } case echoI64: for range *loop { client.EchoI64(ctx, 424242) atomic.AddInt64(&clicounter, 1) } case echoString: 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 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 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 range *loop { client.EchoMap(ctx, m) atomic.AddInt64(&clicounter, 1) } } done.Done() } type handler struct{} func (h *handler) EchoVoid(ctx context.Context) (err error) { atomic.AddInt64(&counter, 1) return nil } func (h *handler) EchoByte(ctx context.Context, arg int8) (r int8, err error) { atomic.AddInt64(&counter, 1) return arg, nil } func (h *handler) EchoI32(ctx context.Context, arg int32) (r int32, err error) { atomic.AddInt64(&counter, 1) return arg, nil } func (h *handler) EchoI64(ctx context.Context, arg int64) (r int64, err error) { atomic.AddInt64(&counter, 1) return arg, nil } func (h *handler) EchoString(ctx context.Context, arg string) (r string, err error) { atomic.AddInt64(&counter, 1) return arg, nil } func (h *handler) EchoList(ctx context.Context, arg []int8) (r []int8, err error) { atomic.AddInt64(&counter, 1) return arg, nil } func (h *handler) EchoSet(ctx context.Context, arg []int8) (r []int8, err error) { atomic.AddInt64(&counter, 1) return arg, nil } func (h *handler) EchoMap(ctx context.Context, arg map[int8]int8) (r map[int8]int8, err error) { atomic.AddInt64(&counter, 1) return arg, nil } thrift-0.23.0/test/go/src/common/0000775000175000017500000000000015165535636017040 5ustar00buildbuild00000000000000thrift-0.23.0/test/go/src/common/clientserver_test.go0000664000175000017500000003065715165535636023146 0ustar00buildbuild00000000000000/* * 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 common import ( "context" "errors" "fmt" "reflect" "sync" "testing" "github.com/golang/mock/gomock" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/test/go/src/gen/thrifttest" ) type test_unit struct { host string port int64 domain_socket string transport string protocol string ssl bool } var units = []test_unit{ {"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) { wg := &sync.WaitGroup{} wg.Add(len(units)) for _, unit := range units { go func(u test_unit) { defer wg.Done() doUnit(t, &u) }(unit) } wg.Wait() } func doUnit(t *testing.T, unit *test_unit) { 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(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{ -4: {-4: -4, -3: -3, -2: -2, -1: -1}, 4: {4: 4, 3: 3, 2: 2, 1: 1}, } var xxs = &thrifttest.Xtruct{ StringThing: "Hello2", ByteThing: 42, I32Thing: 4242, I64Thing: 424242, } var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "some"} var defaultCtx = context.Background() func callEverythingWithMock(t *testing.T, client *thrifttest.ThriftTestClient, handler *MockThriftTest) { u := thrift.Tuuid{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, } gomock.InOrder( handler.EXPECT().TestVoid(gomock.Any()), handler.EXPECT().TestString(gomock.Any(), "thing").Return("thing", nil), handler.EXPECT().TestBool(gomock.Any(), true).Return(true, nil), handler.EXPECT().TestBool(gomock.Any(), false).Return(false, nil), handler.EXPECT().TestByte(gomock.Any(), int8(42)).Return(int8(42), nil), handler.EXPECT().TestI32(gomock.Any(), int32(4242)).Return(int32(4242), nil), handler.EXPECT().TestI64(gomock.Any(), int64(424242)).Return(int64(424242), nil), // TODO: add TestBinary() handler.EXPECT().TestUuid(gomock.Any(), u).Return(u, nil), handler.EXPECT().TestDouble(gomock.Any(), float64(42.42)).Return(float64(42.42), nil), handler.EXPECT().TestStruct(gomock.Any(), &thrifttest.Xtruct{StringThing: "thing", ByteThing: 42, I32Thing: 4242, I64Thing: 424242}).Return(&thrifttest.Xtruct{StringThing: "thing", ByteThing: 42, I32Thing: 4242, I64Thing: 424242}, nil), handler.EXPECT().TestNest(gomock.Any(), &thrifttest.Xtruct2{StructThing: &thrifttest.Xtruct{StringThing: "thing", ByteThing: 42, I32Thing: 4242, I64Thing: 424242}}).Return(&thrifttest.Xtruct2{StructThing: &thrifttest.Xtruct{StringThing: "thing", ByteThing: 42, I32Thing: 4242, I64Thing: 424242}}, nil), handler.EXPECT().TestMap(gomock.Any(), map[int32]int32{1: 2, 3: 4, 5: 42}).Return(map[int32]int32{1: 2, 3: 4, 5: 42}, nil), handler.EXPECT().TestStringMap(gomock.Any(), map[string]string{"a": "2", "b": "blah", "some": "thing"}).Return(map[string]string{"a": "2", "b": "blah", "some": "thing"}, nil), handler.EXPECT().TestSet(gomock.Any(), []int32{1, 2, 42}).Return([]int32{1, 2, 42}, nil), handler.EXPECT().TestList(gomock.Any(), []int32{1, 2, 42}).Return([]int32{1, 2, 42}, nil), handler.EXPECT().TestEnum(gomock.Any(), thrifttest.Numberz_TWO).Return(thrifttest.Numberz_TWO, nil), handler.EXPECT().TestTypedef(gomock.Any(), thrifttest.UserId(42)).Return(thrifttest.UserId(42), nil), handler.EXPECT().TestMapMap(gomock.Any(), int32(42)).Return(rmapmap, nil), // TODO: not testing insanity handler.EXPECT().TestMulti(gomock.Any(), int8(42), int32(4242), int64(424242), map[int16]string{1: "blah", 2: "thing"}, thrifttest.Numberz_EIGHT, thrifttest.UserId(24)).Return(xxs, nil), handler.EXPECT().TestException(gomock.Any(), "some").Return(xcept), handler.EXPECT().TestException(gomock.Any(), "TException").Return(errors.New("Just random exception")), handler.EXPECT().TestMultiException(gomock.Any(), "Xception", "ignoreme").Return(nil, &thrifttest.Xception{ErrorCode: 1001, Message: "This is an Xception"}), handler.EXPECT().TestMultiException(gomock.Any(), "Xception2", "ignoreme").Return(nil, &thrifttest.Xception2{ErrorCode: 2002, StructThing: &thrifttest.Xtruct{StringThing: "This is an Xception2"}}), handler.EXPECT().TestOneway(gomock.Any(), int32(2)).Return(nil), handler.EXPECT().TestVoid(gomock.Any()), ) var err error if err = client.TestVoid(defaultCtx); err != nil { t.Errorf("Unexpected error in TestVoid() call: %s", err) } thing, err := client.TestString(defaultCtx, "thing") if err != nil { t.Errorf("Unexpected error in TestString() call: %s", err) } if thing != "thing" { t.Errorf("Unexpected TestString() result, expected 'thing' got '%s' ", thing) } bl, err := client.TestBool(defaultCtx, true) if err != nil { t.Errorf("Unexpected error in TestBool() call: %s", err) } if !bl { t.Errorf("Unexpected TestBool() result expected true, got %v ", bl) } bl, err = client.TestBool(defaultCtx, false) if err != nil { t.Errorf("Unexpected error in TestBool() call: %s", err) } if bl { t.Errorf("Unexpected TestBool() result expected false, got %v ", bl) } b, err := client.TestByte(defaultCtx, 42) if err != nil { t.Errorf("Unexpected error in TestByte() call: %s", err) } if b != 42 { t.Errorf("Unexpected TestByte() result expected 42, got %d ", b) } i32, err := client.TestI32(defaultCtx, 4242) if err != nil { t.Errorf("Unexpected error in TestI32() call: %s", err) } if i32 != 4242 { t.Errorf("Unexpected TestI32() result expected 4242, got %d ", i32) } i64, err := client.TestI64(defaultCtx, 424242) if err != nil { t.Errorf("Unexpected error in TestI64() call: %s", err) } if i64 != 424242 { t.Errorf("Unexpected TestI64() result expected 424242, got %d ", i64) } // TODO: add TestBinary() call uret, err := client.TestUuid(defaultCtx, u) if err != nil { t.Errorf("Unexpected error in TestUuid() call: %s", err) } if uret != u { t.Errorf("Unexpected TestUuid() result expected %v, got %v ", uret, u) } d, err := client.TestDouble(defaultCtx, 42.42) if err != nil { t.Errorf("Unexpected error in TestDouble() call: %s", err) } if d != 42.42 { t.Errorf("Unexpected TestDouble() result expected 42.42, got %f ", d) } xs := thrifttest.NewXtruct() xs.StringThing = "thing" xs.ByteThing = 42 xs.I32Thing = 4242 xs.I64Thing = 424242 xsret, err := client.TestStruct(defaultCtx, xs) if err != nil { t.Errorf("Unexpected error in TestStruct() call: %s", err) } if *xs != *xsret { t.Errorf("Unexpected TestStruct() result expected %#v, got %#v ", xs, xsret) } x2 := thrifttest.NewXtruct2() x2.StructThing = xs x2ret, err := client.TestNest(defaultCtx, x2) if err != nil { t.Errorf("Unexpected error in TestNest() call: %s", err) } if !reflect.DeepEqual(x2, x2ret) { t.Errorf("Unexpected TestNest() result expected %#v, got %#v ", x2, x2ret) } m := map[int32]int32{1: 2, 3: 4, 5: 42} mret, err := client.TestMap(defaultCtx, m) if err != nil { t.Errorf("Unexpected error in TestMap() call: %s", err) } if !reflect.DeepEqual(m, mret) { t.Errorf("Unexpected TestMap() result expected %#v, got %#v ", m, mret) } sm := map[string]string{"a": "2", "b": "blah", "some": "thing"} smret, err := client.TestStringMap(defaultCtx, sm) if err != nil { t.Errorf("Unexpected error in TestStringMap() call: %s", err) } if !reflect.DeepEqual(sm, smret) { t.Errorf("Unexpected TestStringMap() result expected %#v, got %#v ", sm, smret) } s := []int32{1, 2, 42} sret, err := client.TestSet(defaultCtx, s) if err != nil { t.Errorf("Unexpected error in TestSet() call: %s", err) } // Sets can be in any order, but Go slices are ordered, so reflect.DeepEqual won't work. stemp := map[int32]struct{}{} for _, val := range s { stemp[val] = struct{}{} } for _, val := range sret { if _, ok := stemp[val]; !ok { t.Fatalf("Unexpected TestSet() result expected %#v, got %#v ", s, sret) } } l := []int32{1, 2, 42} lret, err := client.TestList(defaultCtx, l) if err != nil { t.Errorf("Unexpected error in TestList() call: %s", err) } if !reflect.DeepEqual(l, lret) { t.Errorf("Unexpected TestList() result expected %#v, got %#v ", l, lret) } eret, err := client.TestEnum(defaultCtx, thrifttest.Numberz_TWO) if err != nil { t.Errorf("Unexpected error in TestEnum() call: %s", err) } if eret != thrifttest.Numberz_TWO { t.Errorf("Unexpected TestEnum() result expected %#v, got %#v ", thrifttest.Numberz_TWO, eret) } tret, err := client.TestTypedef(defaultCtx, thrifttest.UserId(42)) if err != nil { t.Errorf("Unexpected error in TestTypedef() call: %s", err) } if tret != thrifttest.UserId(42) { t.Errorf("Unexpected TestTypedef() result expected %#v, got %#v ", thrifttest.UserId(42), tret) } mapmap, err := client.TestMapMap(defaultCtx, 42) if err != nil { t.Errorf("Unexpected error in TestMapmap() call: %s", err) } if !reflect.DeepEqual(mapmap, rmapmap) { t.Errorf("Unexpected TestMapmap() result expected %#v, got %#v ", rmapmap, mapmap) } xxsret, err := client.TestMulti(defaultCtx, 42, 4242, 424242, map[int16]string{1: "blah", 2: "thing"}, thrifttest.Numberz_EIGHT, thrifttest.UserId(24)) if err != nil { t.Errorf("Unexpected error in TestMulti() call: %s", err) } if !reflect.DeepEqual(xxs, xxsret) { t.Errorf("Unexpected TestMulti() result expected %#v, got %#v ", xxs, xxsret) } err = client.TestException(defaultCtx, "some") if err == nil { t.Errorf("Expecting exception in TestException() call") } if !reflect.DeepEqual(err, xcept) { t.Errorf("Unexpected TestException() result expected %#v, got %#v ", xcept, err) } // TODO: connection is being closed on this err = client.TestException(defaultCtx, "TException") if err == nil { t.Error("expected exception got nil") } else if tex, ok := err.(thrift.TApplicationException); !ok { t.Errorf("Unexpected TestException() result expected ApplicationError, got %T ", err) } else if tex.TypeId() != thrift.INTERNAL_ERROR { t.Errorf("expected internal_error got %v", tex.TypeId()) } ign, err := client.TestMultiException(defaultCtx, "Xception", "ignoreme") if ign != nil || err == nil { t.Errorf("Expecting exception in TestMultiException() call") } if !reflect.DeepEqual(err, &thrifttest.Xception{ErrorCode: 1001, Message: "This is an Xception"}) { t.Errorf("Unexpected TestMultiException() %#v ", err) } ign, err = client.TestMultiException(defaultCtx, "Xception2", "ignoreme") if ign != nil || err == nil { t.Errorf("Expecting exception in TestMultiException() call") } expecting := &thrifttest.Xception2{ErrorCode: 2002, StructThing: &thrifttest.Xtruct{StringThing: "This is an Xception2"}} if !reflect.DeepEqual(err, expecting) { t.Errorf("Unexpected TestMultiException() %#v ", err) } err = client.TestOneway(defaultCtx, 2) if err != nil { t.Errorf("Unexpected error in TestOneway() call: %s", err) } //Make sure the connection still alive if err = client.TestVoid(defaultCtx); err != nil { t.Errorf("Unexpected error in TestVoid() call: %s", err) } } thrift-0.23.0/test/go/src/common/server.go0000664000175000017500000001062115165535636020675 0ustar00buildbuild00000000000000/* * 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 common import ( "compress/zlib" "crypto/tls" "flag" "fmt" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/test/go/src/gen/thrifttest" ) var ( debugServerProtocol bool ) func init() { flag.BoolVar(&debugServerProtocol, "debug_server_protocol", false, "turn server protocol trace on") } func GetServerParams( host string, port int64, domain_socket string, transport string, protocol string, ssl bool, certPath string, handler thrifttest.ThriftTest, ) (thrift.TProcessor, thrift.TServerTransport, thrift.TTransportFactory, thrift.TProtocolFactory, string /* addr */, error) { var err error hostPort := fmt.Sprintf("%s:%d", host, port) var cfg *thrift.TConfiguration = nil var protocolFactory thrift.TProtocolFactory switch protocol { case "compact": protocolFactory = thrift.NewTCompactProtocolFactoryConf(cfg) case "simplejson": protocolFactory = thrift.NewTSimpleJSONProtocolFactoryConf(cfg) case "json": protocolFactory = thrift.NewTJSONProtocolFactory() case "binary": protocolFactory = thrift.NewTBinaryProtocolFactoryConf(nil) case "header": protocolFactory = thrift.NewTHeaderProtocolFactoryConf(nil) default: 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 } else { cfg.Certificates = append(cfg.Certificates, cert) } 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 { 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 } var transportFactory thrift.TTransportFactory switch transport { case "http": // there is no such factory, and we don't need any transportFactory = nil case "framed": transportFactory = thrift.NewTTransportFactory() transportFactory = thrift.NewTFramedTransportFactoryConf(transportFactory, nil) case "buffered": transportFactory = thrift.NewTBufferedTransportFactory(8192) case "zlib": transportFactory = thrift.NewTZlibTransportFactory(zlib.BestCompression) case "": transportFactory = thrift.NewTTransportFactory() default: return nil, nil, nil, nil, "", fmt.Errorf("invalid transport specified %s", transport) } processor := thrifttest.NewThriftTestProcessor(handler) return processor, serverTransport, transportFactory, protocolFactory, addr, nil } thrift-0.23.0/test/go/src/common/simple_handler.go0000664000175000017500000001021115165535636022350 0ustar00buildbuild00000000000000/* * 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 common import ( "errors" "time" "github.com/apache/thrift/lib/go/thrift" //lint:ignore ST1001 allow dot import here . "github.com/apache/thrift/test/go/src/gen/thrifttest" ) var SimpleHandler = &simpleHandler{} type simpleHandler struct{} func (p *simpleHandler) TestVoid() (err error) { return nil } func (p *simpleHandler) TestString(thing string) (r string, err error) { return thing, nil } func (p *simpleHandler) TestBool(thing []byte) (r []byte, err error) { return thing, nil } func (p *simpleHandler) TestByte(thing int8) (r int8, err error) { return thing, nil } func (p *simpleHandler) TestI32(thing int32) (r int32, err error) { return thing, nil } func (p *simpleHandler) TestI64(thing int64) (r int64, err error) { return thing, nil } func (p *simpleHandler) TestDouble(thing float64) (r float64, err error) { return thing, nil } func (p *simpleHandler) TestBinary(thing []byte) (r []byte, err error) { return thing, nil } func (p *simpleHandler) TestUuid(thing thrift.Tuuid) (r thrift.Tuuid, err error) { return thing, nil } func (p *simpleHandler) TestStruct(thing *Xtruct) (r *Xtruct, err error) { return r, err } func (p *simpleHandler) TestNest(nest *Xtruct2) (r *Xtruct2, err error) { return nest, nil } func (p *simpleHandler) TestMap(thing map[int32]int32) (r map[int32]int32, err error) { return thing, nil } func (p *simpleHandler) TestStringMap(thing map[string]string) (r map[string]string, err error) { return thing, nil } func (p *simpleHandler) TestSet(thing []int32) (r []int32, err error) { return thing, nil } func (p *simpleHandler) TestList(thing []int32) (r []int32, err error) { return thing, nil } func (p *simpleHandler) TestEnum(thing Numberz) (r Numberz, err error) { return thing, nil } func (p *simpleHandler) TestTypedef(thing UserId) (r UserId, err error) { return thing, nil } func (p *simpleHandler) TestMapMap(hello int32) (r map[int32]map[int32]int32, err error) { r = map[int32]map[int32]int32{ -4: {-4: -4, -3: -3, -2: -2, -1: -1}, 4: {4: 4, 3: 3, 2: 2, 1: 1}, } return } func (p *simpleHandler) TestInsanity(argument *Insanity) (r map[UserId]map[Numberz]*Insanity, err error) { //lint:ignore ST1005 To be consistent with other language libraries. return nil, errors.New("No Insanity") } func (p *simpleHandler) TestMulti(arg0 int8, arg1 int32, arg2 int64, arg3 map[int16]string, arg4 Numberz, arg5 UserId) (r *Xtruct, err error) { r = NewXtruct() r.StringThing = "Hello2" r.ByteThing = arg0 r.I32Thing = arg1 r.I64Thing = arg2 return } func (p *simpleHandler) TestException(arg string) (err error) { switch arg { case "Xception": e := NewXception() e.ErrorCode = 1001 e.Message = arg return e case "TException": //lint:ignore ST1005 To be consistent with other language libraries. return errors.New("Just TException") } return } func (p *simpleHandler) TestMultiException(arg0 string, arg1 string) (r *Xtruct, err error) { switch arg0 { case "Xception": e := NewXception() e.ErrorCode = 1001 e.Message = "This is an Xception" return nil, e case "Xception2": e := NewXception2() e.ErrorCode = 2002 e.StructThing.StringThing = "This is an Xception2" return nil, e default: r = NewXtruct() r.StringThing = arg1 return } } func (p *simpleHandler) TestOneway(secondsToSleep int32) (err error) { time.Sleep(time.Second * time.Duration(secondsToSleep)) return } thrift-0.23.0/test/go/src/common/client.go0000664000175000017500000000625015165535636020650 0ustar00buildbuild00000000000000/* * 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 common import ( "compress/zlib" "crypto/tls" "flag" "fmt" "net/http" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/test/go/src/gen/thrifttest" ) var debugClientProtocol bool func init() { flag.BoolVar(&debugClientProtocol, "debug_client_protocol", false, "turn client protocol trace on") } func StartClient( addr string, transport string, protocol string, ssl bool, ) (client *thrifttest.ThriftTestClient, trans thrift.TTransport, err error) { cfg := &thrift.TConfiguration{ TLSConfig: &tls.Config{ InsecureSkipVerify: true, }, } var protocolFactory thrift.TProtocolFactory switch protocol { case "compact": protocolFactory = thrift.NewTCompactProtocolFactoryConf(cfg) case "simplejson": protocolFactory = thrift.NewTSimpleJSONProtocolFactoryConf(cfg) case "json": protocolFactory = thrift.NewTJSONProtocolFactory() case "binary": protocolFactory = thrift.NewTBinaryProtocolFactoryConf(cfg) case "header": protocolFactory = thrift.NewTHeaderProtocolFactoryConf(cfg) default: return nil, nil, fmt.Errorf("invalid protocol specified %s", protocol) } if debugClientProtocol { protocolFactory = thrift.NewTDebugProtocolFactoryWithLogger(protocolFactory, "client:", thrift.StdLogger(nil)) } if ssl { trans = thrift.NewTSSLSocketConf(addr, cfg) } else { trans = thrift.NewTSocketConf(addr, nil) } if err != nil { return nil, nil, err } switch transport { case "http": if ssl { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} trans, err = thrift.NewTHttpClientWithOptions(fmt.Sprintf("https://%s/", addr), thrift.THttpClientOptions{Client: client}) } else { trans, err = thrift.NewTHttpClient(fmt.Sprintf("http://%s/", addr)) } case "framed": trans = thrift.NewTFramedTransportConf(trans, cfg) case "buffered": trans = thrift.NewTBufferedTransport(trans, 8192) case "zlib": trans, err = thrift.NewTZlibTransport(trans, zlib.BestCompression) case "": // Do nothing default: return nil, nil, fmt.Errorf("invalid transport specified %s", transport) } if err != nil { return nil, nil, err } if err = trans.Open(); err != nil { return nil, nil, err } iprot := protocolFactory.GetProtocol(trans) oprot := protocolFactory.GetProtocol(trans) client = thrifttest.NewThriftTestClient(thrift.NewTStandardClient(iprot, oprot)) return } thrift-0.23.0/test/go/src/common/printing_handler.go0000664000175000017500000002755515165535636022734 0ustar00buildbuild00000000000000/* * 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 common import ( "context" "encoding/hex" "errors" "fmt" "time" "github.com/apache/thrift/lib/go/thrift" //lint:ignore ST1001 allow dot import here . "github.com/apache/thrift/test/go/src/gen/thrifttest" ) var PrintingHandler = &printingHandler{} type printingHandler struct{} // Prints "testVoid()" and returns nothing. func (p *printingHandler) TestVoid(ctx context.Context) (err error) { fmt.Println("testVoid()") return nil } // Prints 'testString("%s")' with thing as '%s' // @param string thing - the string to print // @return string - returns the string 'thing' // // Parameters: // - Thing func (p *printingHandler) TestString(ctx context.Context, thing string) (r string, err error) { fmt.Printf("testString(\"%s\")\n", thing) return thing, nil } // Prints 'testBool("%t")' with thing as 'true' or 'false' // @param bool thing - the bool to print // @return bool - returns the bool 'thing' // // Parameters: // - Thing func (p *printingHandler) TestBool(ctx context.Context, thing bool) (r bool, err error) { fmt.Printf("testBool(%t)\n", thing) return thing, nil } // Prints 'testByte("%d")' with thing as '%d' // @param byte thing - the byte to print // @return byte - returns the byte 'thing' // // Parameters: // - Thing func (p *printingHandler) TestByte(ctx context.Context, thing int8) (r int8, err error) { fmt.Printf("testByte(%d)\n", thing) return thing, nil } // Prints 'testI32("%d")' with thing as '%d' // @param i32 thing - the i32 to print // @return i32 - returns the i32 'thing' // // Parameters: // - Thing func (p *printingHandler) TestI32(ctx context.Context, thing int32) (r int32, err error) { fmt.Printf("testI32(%d)\n", thing) return thing, nil } // Prints 'testI64("%d")' with thing as '%d' // @param i64 thing - the i64 to print // @return i64 - returns the i64 'thing' // // Parameters: // - Thing func (p *printingHandler) TestI64(ctx context.Context, thing int64) (r int64, err error) { fmt.Printf("testI64(%d)\n", thing) return thing, nil } // Prints 'testDouble("%f")' with thing as '%f' // @param double thing - the double to print // @return double - returns the double 'thing' // // Parameters: // - Thing func (p *printingHandler) TestDouble(ctx context.Context, thing float64) (r float64, err error) { fmt.Printf("testDouble(%f)\n", thing) return thing, nil } // Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data // @param []byte thing - the binary to print // @return []byte - returns the binary 'thing' // // Parameters: // - Thing func (p *printingHandler) TestBinary(ctx context.Context, thing []byte) (r []byte, err error) { fmt.Printf("testBinary(%s)\n", hex.EncodeToString(thing)) return thing, nil } // Prints 'testUuid("%s")' where '%s' is the uuid given. Note that the uuid byte order should be correct. // @param uuid thing - the uuid to print // @return uuid - returns the uuid 'thing' // // Parameters: // - Thing func (p *printingHandler) TestUuid(ctx context.Context, thing thrift.Tuuid) (r thrift.Tuuid, err error) { fmt.Printf("testUuid(%s)\n", thing.String()) return thing, nil } // Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values // @param Xtruct thing - the Xtruct to print // @return Xtruct - returns the Xtruct 'thing' // // Parameters: // - Thing func (p *printingHandler) TestStruct(ctx context.Context, thing *Xtruct) (r *Xtruct, err error) { fmt.Printf("testStruct({\"%s\", %d, %d, %d})\n", thing.StringThing, thing.ByteThing, thing.I32Thing, thing.I64Thing) return thing, err } // Prints 'testNest("{%s}")' where thing has been formatted into a string of the nested struct // @param Xtruct2 thing - the Xtruct2 to print // @return Xtruct2 - returns the Xtruct2 'thing' // // Parameters: // - Thing func (p *printingHandler) TestNest(ctx context.Context, nest *Xtruct2) (r *Xtruct2, err error) { thing := nest.StructThing fmt.Printf("testNest({%d, {\"%s\", %d, %d, %d}, %d})\n", nest.ByteThing, thing.StringThing, thing.ByteThing, thing.I32Thing, thing.I64Thing, nest.I32Thing) return nest, nil } // Prints 'testMap("{%s")' where thing has been formatted into a string of 'key => value' pairs // // separated by commas and new lines // // @param map thing - the map to print // @return map - returns the map 'thing' // // Parameters: // - Thing func (p *printingHandler) TestMap(ctx context.Context, thing map[int32]int32) (r map[int32]int32, err error) { fmt.Printf("testMap({") first := true for k, v := range thing { if first { first = false } else { fmt.Printf(", ") } fmt.Printf("%d => %d", k, v) } fmt.Printf("})\n") return thing, nil } // Prints 'testStringMap("{%s}")' where thing has been formatted into a string of 'key => value' pairs // // separated by commas and new lines // // @param map thing - the map to print // @return map - returns the map 'thing' // // Parameters: // - Thing func (p *printingHandler) TestStringMap(ctx context.Context, thing map[string]string) (r map[string]string, err error) { fmt.Printf("testStringMap({") first := true for k, v := range thing { if first { first = false } else { fmt.Printf(", ") } fmt.Printf("%s => %s", k, v) } fmt.Printf("})\n") return thing, nil } // Prints 'testSet("{%s}")' where thing has been formatted into a string of values // // separated by commas and new lines // // @param set thing - the set to print // @return set - returns the set 'thing' // // Parameters: // - Thing func (p *printingHandler) TestSet(ctx context.Context, thing []int32) (r []int32, err error) { fmt.Printf("testSet({") first := true for k := range thing { if first { first = false } else { fmt.Printf(", ") } fmt.Printf("%d", k) } fmt.Printf("})\n") return thing, nil } // Prints 'testList("{%s}")' where thing has been formatted into a string of values // // separated by commas and new lines // // @param list thing - the list to print // @return list - returns the list 'thing' // // Parameters: // - Thing func (p *printingHandler) TestList(ctx context.Context, thing []int32) (r []int32, err error) { fmt.Printf("testList({") for i, v := range thing { if i != 0 { fmt.Printf(", ") } fmt.Printf("%d", v) } fmt.Printf("})\n") return thing, nil } // Prints 'testEnum("%d")' where thing has been formatted into it's numeric value // @param Numberz thing - the Numberz to print // @return Numberz - returns the Numberz 'thing' // // Parameters: // - Thing func (p *printingHandler) TestEnum(ctx context.Context, thing Numberz) (r Numberz, err error) { fmt.Printf("testEnum(%d)\n", thing) return thing, nil } // Prints 'testTypedef("%d")' with thing as '%d' // @param UserId thing - the UserId to print // @return UserId - returns the UserId 'thing' // // Parameters: // - Thing func (p *printingHandler) TestTypedef(ctx context.Context, thing UserId) (r UserId, err error) { fmt.Printf("testTypedef(%d)\n", thing) return thing, nil } // Prints 'testMapMap("%d")' with hello as '%d' // @param i32 hello - the i32 to print // @return map> - returns a dictionary with these values: // // {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, } // // Parameters: // - Hello func (p *printingHandler) TestMapMap(ctx context.Context, hello int32) (r map[int32]map[int32]int32, err error) { fmt.Printf("testMapMap(%d)\n", hello) r = map[int32]map[int32]int32{ -4: {-4: -4, -3: -3, -2: -2, -1: -1}, 4: {4: 4, 3: 3, 2: 2, 1: 1}, } return } // So you think you've got this all worked, out eh? // // Creates a the returned map with these values and prints it out: // // { 1 => { 2 => argument, // 3 => argument, // }, // 2 => { 6 => , }, // } // // @return map> - a map with the above values // // Parameters: // - Argument func (p *printingHandler) TestInsanity(ctx context.Context, argument *Insanity) (r map[UserId]map[Numberz]*Insanity, err error) { fmt.Printf("testInsanity()\n") r = make(map[UserId]map[Numberz]*Insanity) r[1] = map[Numberz]*Insanity{ 2: argument, 3: argument, } r[2] = map[Numberz]*Insanity{ 6: NewInsanity(), } return } // Prints 'testMulti()' // @param byte arg0 - // @param i32 arg1 - // @param i64 arg2 - // @param map arg3 - // @param Numberz arg4 - // @param UserId arg5 - // @return Xtruct - returns an Xtruct with StringThing = "Hello2, ByteThing = arg0, I32Thing = arg1 // // and I64Thing = arg2 // // Parameters: // - Arg0 // - Arg1 // - Arg2 // - Arg3 // - Arg4 // - Arg5 func (p *printingHandler) TestMulti(ctx context.Context, arg0 int8, arg1 int32, arg2 int64, arg3 map[int16]string, arg4 Numberz, arg5 UserId) (r *Xtruct, err error) { fmt.Printf("testMulti()\n") r = NewXtruct() r.StringThing = "Hello2" r.ByteThing = arg0 r.I32Thing = arg1 r.I64Thing = arg2 return } // Print 'testException(%s)' with arg as '%s' // @param string arg - a string indication what type of exception to throw // if arg == "Xception" throw Xception with errorCode = 1001 and message = arg // elsen if arg == "TException" throw TException // else do not throw anything // // Parameters: // - Arg func (p *printingHandler) TestException(ctx context.Context, arg string) (err error) { fmt.Printf("testException(%s)\n", arg) switch arg { case "Xception": e := NewXception() e.ErrorCode = 1001 e.Message = arg return e case "TException": //lint:ignore ST1005 To be consistent with other language libraries. return errors.New("Just TException") } return } // Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s' // @param string arg - a string indication what type of exception to throw // if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception" // elsen if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and message = "This is an Xception2" // else do not throw anything // @return Xtruct - an Xtruct with StringThing = arg1 // // Parameters: // - Arg0 // - Arg1 func (p *printingHandler) TestMultiException(ctx context.Context, arg0 string, arg1 string) (r *Xtruct, err error) { fmt.Printf("testMultiException(%s, %s)\n", arg0, arg1) switch arg0 { case "Xception": e := NewXception() e.ErrorCode = 1001 e.Message = "This is an Xception" return nil, e case "Xception2": e := NewXception2() e.ErrorCode = 2002 e.StructThing = NewXtruct() e.StructThing.StringThing = "This is an Xception2" return nil, e default: r = NewXtruct() r.StringThing = arg1 return } } // Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d' // sleep 'secondsToSleep' // Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d' // @param i32 secondsToSleep - the number of seconds to sleep // // Parameters: // - SecondsToSleep func (p *printingHandler) TestOneway(ctx context.Context, secondsToSleep int32) (err error) { fmt.Printf("testOneway(%d): Sleeping...\n", secondsToSleep) time.Sleep(time.Second * time.Duration(secondsToSleep)) fmt.Printf("testOneway(%d): done sleeping!\n", secondsToSleep) return } thrift-0.23.0/test/go/src/common/context_test.go0000664000175000017500000000532715165535636022121 0ustar00buildbuild00000000000000/* * 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 common import ( "context" "fmt" "net" "net/http" "net/url" "os" "syscall" "testing" "time" "github.com/apache/thrift/lib/go/thrift" ) type slowHttpHandler struct{} func (slowHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { time.Sleep(1 * time.Second) } func TestHttpContextTimeout(t *testing.T) { 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: addr, Handler: slowHttpHandler{}} go server.ListenAndServe() 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() unwrapErr := func(err error) error { for { //lint:ignore S1034 type switch is more appropriate here. switch err.(type) { case thrift.TTransportException: err = err.(thrift.TTransportException).Err() case *url.Error: err = err.(*url.Error).Err case *net.OpError: err = err.(*net.OpError).Err case *os.SyscallError: err = err.(*os.SyscallError).Err default: return err } } } serverStartupDeadline := time.Now().Add(5 * time.Second) for { ctx, _ := context.WithTimeout(context.Background(), 50*time.Millisecond) err = client.TestVoid(ctx) err = unwrapErr(err) if err != syscall.ECONNREFUSED || time.Now().After(serverStartupDeadline) { break } time.Sleep(time.Millisecond) } if err == nil { t.Errorf("Request completed (should have timed out)") return } // We've got to switch on `err.Error()` here since go1.7 doesn't properly return // `context.DeadlineExceeded` error and `http.errRequestCanceled` is not exported. // See https://github.com/golang/go/issues/17711 switch err.Error() { case context.DeadlineExceeded.Error(), "net/http: request canceled": // Expected error default: t.Errorf("Unexpected error: %s", err) } } thrift-0.23.0/test/go/genmock.sh0000664000175000017500000000045215165535636016741 0ustar00buildbuild00000000000000#!/bin/sh set -e export GOPATH=$(mktemp -d -t gopath-XXXXXXXXXX) go install github.com/golang/mock/mockgen `go env GOPATH`/bin/mockgen -destination=src/common/mock_handler.go -package=common github.com/apache/thrift/test/go/src/gen/thrifttest ThriftTest chmod a+w -R $GOPATH && rm -Rf $GOPATH thrift-0.23.0/test/go/go.sum0000664000175000017500000000546715165535636016130 0ustar00buildbuild00000000000000github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= thrift-0.23.0/test/go/Makefile.in0000644000175000017500000004531415170007167017020 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/go ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ BUILT_SOURCES = gopath GOBUILDEXTRA = -buildvcs=false THRIFTCMD = $(THRIFT) -out src/gen --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/test/go/src/gen/$(COMPILER_EXTRAFLAG) THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift EXTRA_DIST = \ src/bin \ src/common \ go.mod \ go.sum \ genmock.sh all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/go/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/go/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: all check install install-am install-exec install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile precross: bin/testclient bin/testserver ThriftTest.thrift: $(THRIFTTEST) grep -v list.*map.*list.*map $(THRIFTTEST) > ThriftTest.thrift .PHONY: gopath # Thrift for GO has problems with complex map keys: THRIFT-2063 gopath: $(THRIFT) ThriftTest.thrift mkdir -p src/gen $(THRIFTCMD) ThriftTest.thrift $(THRIFTCMD) ../StressTest.thrift $(THRIFTCMD) ../ConstantsDemo.thrift touch gopath bin/testclient: gopath $(GO) build $(GOBUILDEXTRA) -o bin/testclient ./src/bin/testclient bin/testserver: gopath $(GO) build $(GOBUILDEXTRA) -o bin/testserver ./src/bin/testserver bin/stress: gopath $(GO) build $(GOBUILDEXTRA) -o bin/stress ./src/bin/stress clean-local: $(RM) -r src/gen src/github.com/golang src/thrift bin pkg gopath ThriftTest.thrift check_PROGRAMS: bin/testclient bin/testserver bin/stress check: gopath genmock $(GO) test -v ./src/common/... $(GO) test -v ./src/gen/... genmock: gopath sh genmock.sh distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/go/go.mod0000664000175000017500000000064515167543515016071 0ustar00buildbuild00000000000000module github.com/apache/thrift/test/go go 1.25 require ( github.com/apache/thrift v0.0.0-00010101000000-000000000000 github.com/golang/mock v1.6.0 ) require ( golang.org/x/mod v0.4.2 // indirect golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect golang.org/x/tools v0.1.1 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect ) replace github.com/apache/thrift => ../../ thrift-0.23.0/test/go/Makefile.am0000664000175000017500000000410315165535636017013 0ustar00buildbuild00000000000000# # 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. # BUILT_SOURCES = gopath GOBUILDEXTRA = -buildvcs=false THRIFTCMD = $(THRIFT) -out src/gen --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/test/go/src/gen/$(COMPILER_EXTRAFLAG) THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift precross: bin/testclient bin/testserver ThriftTest.thrift: $(THRIFTTEST) grep -v list.*map.*list.*map $(THRIFTTEST) > ThriftTest.thrift .PHONY: gopath # Thrift for GO has problems with complex map keys: THRIFT-2063 gopath: $(THRIFT) ThriftTest.thrift mkdir -p src/gen $(THRIFTCMD) ThriftTest.thrift $(THRIFTCMD) ../StressTest.thrift $(THRIFTCMD) ../ConstantsDemo.thrift touch gopath bin/testclient: gopath $(GO) build $(GOBUILDEXTRA) -o bin/testclient ./src/bin/testclient bin/testserver: gopath $(GO) build $(GOBUILDEXTRA) -o bin/testserver ./src/bin/testserver bin/stress: gopath $(GO) build $(GOBUILDEXTRA) -o bin/stress ./src/bin/stress clean-local: $(RM) -r src/gen src/github.com/golang src/thrift bin pkg gopath ThriftTest.thrift check_PROGRAMS: bin/testclient bin/testserver bin/stress check: gopath genmock $(GO) test -v ./src/common/... $(GO) test -v ./src/gen/... genmock: gopath sh genmock.sh distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ src/bin \ src/common \ go.mod \ go.sum \ genmock.sh thrift-0.23.0/test/erl/0000775000175000017500000000000015170007175015122 5ustar00buildbuild00000000000000thrift-0.23.0/test/erl/src/0000775000175000017500000000000015170007142015703 5ustar00buildbuild00000000000000thrift-0.23.0/test/erl/src/thrift_test.app.src0000664000175000017500000000376015170007142021540 0ustar00buildbuild00000000000000%% %% 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. %% %%% -*- mode:erlang -*- {application, thrift_test, [ % A quick description of the application. {description, "Thrift cross language test"}, % The version of the applicaton {vsn, "0.23.0"}, % All modules used by the application. {modules, [ test_client, test_thrift_server ]}, % All of the registered names the application uses. This can be ignored. {registered, []}, % Applications that are to be started prior to this one. This can be ignored % leave it alone unless you understand it well and let the .rel files in % your release handle this. {applications, [kernel, stdlib]}, % OTP application loader will load, but not start, included apps. Again % this can be ignored as well. To load but not start an application it % is easier to include it in the .rel file followed by the atom 'none' {included_applications, []}, % configuration parameters similar to those in the config file specified % on the command line. can be fetched with gas:get_env {env, [ % If an error/crash occurs during processing of a function, % should the TApplicationException serialized back to the client % include the erlang backtrace? {exceptions_include_traces, true} ]} ]}. thrift-0.23.0/test/erl/src/test_client.erl0000664000175000017500000001630615165535636020754 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_client). -export([start/0, start/1]). -include("gen-erl/thrift_test_types.hrl"). -record(options, {port = 9090, client_opts = []}). parse_args(Args) -> parse_args(Args, #options{}). parse_args([], Opts) -> Opts; parse_args([Head | Rest], Opts) -> NewOpts = case Head of "--port=" ++ Port -> case string:to_integer(Port) of {IntPort,_} when is_integer(IntPort) -> Opts#options{port = IntPort}; _Else -> erlang:error({bad_arg, Head}) end; "--transport=" ++ Trans -> % TODO: Enable Buffered and HTTP transport case Trans of "framed" -> Opts#options{client_opts = [{framed, true} | Opts#options.client_opts]}; _Else -> Opts end; "--ssl" -> ssl:start(), SslOptions = {ssloptions, [ {cacertfile, "../keys/CA.pem"}, {certfile, "../keys/client.pem"}, {keyfile, "../keys/client.key"} ]}, Opts#options{client_opts = [{ssltransport, true} | [SslOptions | Opts#options.client_opts]]}; "--protocol=" ++ Proto -> Opts#options{client_opts = [{protocol, list_to_atom(Proto)}]}; _Else -> erlang:error({bad_arg, Head}) end, parse_args(Rest, NewOpts). start() -> start(init:get_plain_arguments()). start(Args) -> #options{port = Port, client_opts = ClientOpts} = parse_args(Args), {ok, Client0} = thrift_client_util:new( "127.0.0.1", Port, thrift_test_thrift, ClientOpts), DemoXtruct = #'thrift.test.Xtruct'{ string_thing = <<"Zero">>, byte_thing = 1, i32_thing = 9128361, i64_thing = 9223372036854775807}, DemoNest = #'thrift.test.Xtruct2'{ byte_thing = 7, struct_thing = DemoXtruct, % Note that we don't set i32_thing, it will come back as undefined % from the Python server, but 0 from the C++ server, since it is not % optional i32_thing = 2}, % Is it safe to match these things? DemoDict = dict:from_list([ {Key, Key-10} || Key <- lists:seq(0,10) ]), DemoSet = sets:from_list([ Key || Key <- lists:seq(-3,3) ]), DemoInsane = #'thrift.test.Insanity'{ userMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_FIVE, 5000}]), xtructs = [#'thrift.test.Xtruct'{ string_thing = <<"Truck">>, byte_thing = 8, i32_thing = 8, i64_thing = 8}]}, error_logger:info_msg("testVoid"), {Client01, {ok, ok}} = thrift_client:call(Client0, testVoid, []), error_logger:info_msg("testString"), {Client02, {ok, <<"Test">>}} = thrift_client:call(Client01, testString, ["Test"]), error_logger:info_msg("testString"), {Client03, {ok, <<"Test">>}} = thrift_client:call(Client02, testString, [<<"Test">>]), error_logger:info_msg("testByte"), {Client04, {ok, 63}} = thrift_client:call(Client03, testByte, [63]), error_logger:info_msg("testI32"), {Client05, {ok, -1}} = thrift_client:call(Client04, testI32, [-1]), error_logger:info_msg("testI32"), {Client06, {ok, 0}} = thrift_client:call(Client05, testI32, [0]), error_logger:info_msg("testI64"), {Client07, {ok, -34359738368}} = thrift_client:call(Client06, testI64, [-34359738368]), error_logger:info_msg("testDouble"), {Client08, {ok, -5.2098523}} = thrift_client:call(Client07, testDouble, [-5.2098523]), %% TODO: add testBinary() call error_logger:info_msg("testStruct"), {Client09, {ok, DemoXtruct}} = thrift_client:call(Client08, testStruct, [DemoXtruct]), error_logger:info_msg("testNest"), {Client10, {ok, DemoNest}} = thrift_client:call(Client09, testNest, [DemoNest]), error_logger:info_msg("testMap"), {Client11, {ok, DemoDict}} = thrift_client:call(Client10, testMap, [DemoDict]), error_logger:info_msg("testSet"), {Client12, {ok, DemoSet}} = thrift_client:call(Client11, testSet, [DemoSet]), error_logger:info_msg("testList"), {Client13, {ok, [-1,2,3]}} = thrift_client:call(Client12, testList, [[-1,2,3]]), error_logger:info_msg("testEnum"), {Client14, {ok, 1}} = thrift_client:call(Client13, testEnum, [?THRIFT_TEST_NUMBERZ_ONE]), error_logger:info_msg("testTypedef"), {Client15, {ok, 309858235082523}} = thrift_client:call(Client14, testTypedef, [309858235082523]), error_logger:info_msg("testInsanity"), {Client16, {ok, InsaneResult}} = thrift_client:call(Client15, testInsanity, [DemoInsane]), io:format("~p~n", [InsaneResult]), {Client17, {ok, #'thrift.test.Xtruct'{string_thing = <<"Message">>}}} = thrift_client:call(Client16, testMultiException, ["Safe", "Message"]), Client18 = try {ClientS1, Result1} = thrift_client:call(Client17, testMultiException, ["Xception", "Message"]), io:format("Unexpected return! ~p~n", [Result1]), ClientS1 catch throw:{ClientS2, {exception, ExnS1 = #'thrift.test.Xception'{}}} -> #'thrift.test.Xception'{errorCode = 1001, message = <<"This is an Xception">>} = ExnS1, ClientS2; throw:{ClientS2, {exception, _ExnS1 = #'thrift.test.Xception2'{}}} -> io:format("Wrong exception type!~n", []), ClientS2 end, Client19 = try {ClientS3, Result2} = thrift_client:call(Client18, testMultiException, ["Xception2", "Message"]), io:format("Unexpected return! ~p~n", [Result2]), ClientS3 catch throw:{ClientS4, {exception, _ExnS2 = #'thrift.test.Xception'{}}} -> io:format("Wrong exception type!~n", []), ClientS4; throw:{ClientS4, {exception, ExnS2 = #'thrift.test.Xception2'{}}} -> #'thrift.test.Xception2'{errorCode = 2002, struct_thing = #'thrift.test.Xtruct'{ string_thing = <<"This is an Xception2">>}} = ExnS2, ClientS4 end, %% Started = erlang:monotonic_time(milli_seconds), {_, StartSec, StartUSec} = erlang:timestamp(), error_logger:info_msg("testOneway"), {Client20, {ok, ok}} = thrift_client:call(Client19, testOneway, [1]), {_, EndSec, EndUSec} = erlang:timestamp(), Elapsed = (EndSec - StartSec) * 1000 + (EndUSec - StartUSec) / 1000, if Elapsed > 1000 -> exit(1); true -> true end, thrift_client:close(Client20). thrift-0.23.0/test/erl/src/test_thrift_server.erl0000664000175000017500000002025715165535636022364 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_server). -export([start/0, start/1, start_link/2, handle_function/2, handle_error/2]). -include("thrift_constants.hrl"). -include("gen-erl/thrift_test_types.hrl"). -record(options, {port = 9090, server_opts = []}). parse_args(Args) -> parse_args(Args, #options{}). parse_args([], Opts) -> Opts; parse_args([Head | Rest], Opts) -> NewOpts = case Head of "--port=" ++ Port -> case string:to_integer(Port) of {IntPort,_} when is_integer(IntPort) -> Opts#options{port = IntPort}; _Else -> erlang:error({bad_arg, Head}) end; "--transport=" ++ Trans -> case Trans of "framed" -> Opts#options{server_opts = [{framed, true} | Opts#options.server_opts]}; _Else -> Opts end; "--ssl" -> ssl:start(), SslOptions = {ssloptions, [ {certfile, "../keys/server.pem"} ,{keyfile, "../keys/server.key"} ]}, Opts#options{server_opts = [{ssltransport, true} | [SslOptions | Opts#options.server_opts]]}; "--protocol=" ++ Proto -> Opts#options{server_opts = [{protocol, list_to_atom(Proto)} | Opts#options.server_opts]}; _Else -> erlang:error({bad_arg, Head}) end, parse_args(Rest, NewOpts). start() -> start(init:get_plain_arguments()). start(Args) -> #options{port = Port, server_opts = ServerOpts} = parse_args(Args), spawn(fun() -> start_link(Port, ServerOpts), receive after infinity -> ok end end). start_link(Port, ServerOpts) -> thrift_socket_server:start([{handler, ?MODULE}, {service, thrift_test_thrift}, {port, Port}] ++ ServerOpts). handle_function(testVoid, {}) -> io:format("testVoid~n"), ok; handle_function(testString, {S}) when is_binary(S) -> io:format("testString: ~p~n", [S]), {reply, S}; handle_function(testBool, {B}) when is_boolean(B) -> io:format("testBool: ~p~n", [B]), {reply, B}; handle_function(testByte, {I8}) when is_integer(I8) -> io:format("testByte: ~p~n", [I8]), {reply, I8}; handle_function(testI32, {I32}) when is_integer(I32) -> io:format("testI32: ~p~n", [I32]), {reply, I32}; handle_function(testI64, {I64}) when is_integer(I64) -> io:format("testI64: ~p~n", [I64]), {reply, I64}; handle_function(testDouble, {Double}) when is_float(Double) -> io:format("testDouble: ~p~n", [Double]), {reply, Double}; handle_function(testBinary, {S}) when is_binary(S) -> io:format("testBinary: ~p~n", [S]), {reply, S}; handle_function(testStruct, {Struct = #'thrift.test.Xtruct'{string_thing = String, byte_thing = Byte, i32_thing = I32, i64_thing = I64}}) when is_binary(String), is_integer(Byte), is_integer(I32), is_integer(I64) -> io:format("testStruct: ~p~n", [Struct]), {reply, Struct}; handle_function(testNest, {Nest}) when is_record(Nest, 'thrift.test.Xtruct2'), is_record(Nest#'thrift.test.Xtruct2'.struct_thing, 'thrift.test.Xtruct') -> io:format("testNest: ~p~n", [Nest]), {reply, Nest}; handle_function(testMap, {Map}) -> io:format("testMap: ~p~n", [dict:to_list(Map)]), {reply, Map}; handle_function(testStringMap, {Map}) -> io:format("testStringMap: ~p~n", [dict:to_list(Map)]), {reply, Map}; handle_function(testSet, {Set}) -> true = sets:is_set(Set), io:format("testSet: ~p~n", [sets:to_list(Set)]), {reply, Set}; handle_function(testList, {List}) when is_list(List) -> io:format("testList: ~p~n", [List]), {reply, List}; handle_function(testEnum, {Enum}) when is_integer(Enum) -> io:format("testEnum: ~p~n", [Enum]), {reply, Enum}; handle_function(testTypedef, {UserID}) when is_integer(UserID) -> io:format("testTypedef: ~p~n", [UserID]), {reply, UserID}; handle_function(testMapMap, {Hello}) -> io:format("testMapMap: ~p~n", [Hello]), PosList = [{I, I} || I <- lists:seq(1, 4)], NegList = [{-I, -I} || I <- lists:seq(1, 4)], MapMap = dict:from_list([{4, dict:from_list(PosList)}, {-4, dict:from_list(NegList)}]), {reply, MapMap}; handle_function(testInsanity, {Insanity}) when is_record(Insanity, 'thrift.test.Insanity') -> Hello = #'thrift.test.Xtruct'{string_thing = <<"Hello2">>, byte_thing = 2, i32_thing = 2, i64_thing = 2}, Goodbye = #'thrift.test.Xtruct'{string_thing = <<"Goodbye4">>, byte_thing = 4, i32_thing = 4, i64_thing = 4}, Crazy = #'thrift.test.Insanity'{ userMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_EIGHT, 8}]), xtructs = [Goodbye] }, Looney = #'thrift.test.Insanity'{}, FirstMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_TWO, Insanity}, {?THRIFT_TEST_NUMBERZ_THREE, Insanity}]), SecondMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_SIX, Looney}]), Insane = dict:from_list([{1, FirstMap}, {2, SecondMap}]), io:format("Return = ~p~n", [Insane]), {reply, Insane}; handle_function(testMulti, Args = {Arg0, Arg1, Arg2, _Arg3, Arg4, Arg5}) when is_integer(Arg0), is_integer(Arg1), is_integer(Arg2), is_integer(Arg4), is_integer(Arg5) -> io:format("testMulti(~p)~n", [Args]), {reply, #'thrift.test.Xtruct'{string_thing = <<"Hello2">>, byte_thing = Arg0, i32_thing = Arg1, i64_thing = Arg2}}; handle_function(testException, {String}) when is_binary(String) -> io:format("testException(~p)~n", [String]), case String of <<"Xception">> -> throw(#'thrift.test.Xception'{errorCode = 1001, message = String}); <<"TException">> -> throw({?TApplicationException_Structure}); _ -> ok end; handle_function(testMultiException, {Arg0, Arg1}) -> io:format("testMultiException(~p, ~p)~n", [Arg0, Arg1]), case Arg0 of <<"Xception">> -> throw(#'thrift.test.Xception'{errorCode = 1001, message = <<"This is an Xception">>}); <<"Xception2">> -> throw(#'thrift.test.Xception2'{errorCode = 2002, struct_thing = #'thrift.test.Xtruct'{string_thing = <<"This is an Xception2">>}}); _ -> {reply, #'thrift.test.Xtruct'{string_thing = Arg1}} end; handle_function(testOneway, {Seconds}) -> io:format("testOneway: ~p~n", [Seconds]), timer:sleep(1000 * Seconds), ok. % This is not mandatory but improving test logs. handle_error(Arg1, Arg2) -> io:format("handle_error is called: ~p ~p~n", [Arg1, Arg2]). thrift-0.23.0/test/erl/Makefile0000644000175000017500000004475415170007175016576 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # test/erl/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = test/erl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/test/erl abs_srcdir = /thrift/src/test/erl abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. THRIFT_FILES = $(wildcard ../*.thrift) ERL_FLAG = erl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/erl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/erl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am dist-hook distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic \ maintainer-clean-local mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # make sure ThriftTest.thrift is generated last to prevent conflicts with other *.thrift files .generated: $(THRIFT_FILES) for f in $(THRIFT_FILES) ; do \ $(THRIFT) --gen $(ERL_FLAG) -o src $$f ; \ done ; \ $(THRIFT) --gen $(ERL_FLAG) -o src ../v0.16/ThriftTest.thrift touch .generated precross: .generated $(REBAR) compile maintainer-clean-local: $(RM) -r ebin/ clean: $(REBAR) clean $(RM) .generated $(RM) -r .rebar/ $(RM) -r src/gen-erl/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) $(distdir)/.generated $(RM) -r $(distdir)/.rebar/ $(RM) -r $(distdir)/ebin/ $(RM) -r $(distdir)/src/gen-erl/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/erl/Makefile.in0000644000175000017500000004371415170007167017177 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/erl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ THRIFT_FILES = $(wildcard ../*.thrift) ERL_FLAG = erl all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/erl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/erl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am dist-hook distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic \ maintainer-clean-local mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # make sure ThriftTest.thrift is generated last to prevent conflicts with other *.thrift files .generated: $(THRIFT_FILES) for f in $(THRIFT_FILES) ; do \ $(THRIFT) --gen $(ERL_FLAG) -o src $$f ; \ done ; \ $(THRIFT) --gen $(ERL_FLAG) -o src ../v0.16/ThriftTest.thrift touch .generated precross: .generated $(REBAR) compile maintainer-clean-local: $(RM) -r ebin/ clean: $(REBAR) clean $(RM) .generated $(RM) -r .rebar/ $(RM) -r src/gen-erl/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) $(distdir)/.generated $(RM) -r $(distdir)/.rebar/ $(RM) -r $(distdir)/ebin/ $(RM) -r $(distdir)/src/gen-erl/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/erl/rebar.config0000664000175000017500000000013615165535636017420 0ustar00buildbuild00000000000000{sub_dirs, ["../../lib/erl"]}. {erl_opts, [ debug_info, {i, "../../lib/erl/include"} ]}. thrift-0.23.0/test/erl/Makefile.am0000664000175000017500000000271115165535636017173 0ustar00buildbuild00000000000000# # 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. # THRIFT_FILES = $(wildcard ../*.thrift) ERL_FLAG = erl # make sure ThriftTest.thrift is generated last to prevent conflicts with other *.thrift files .generated: $(THRIFT_FILES) for f in $(THRIFT_FILES) ; do \ $(THRIFT) --gen $(ERL_FLAG) -o src $$f ; \ done ; \ $(THRIFT) --gen $(ERL_FLAG) -o src ../v0.16/ThriftTest.thrift touch .generated precross: .generated $(REBAR) compile maintainer-clean-local: $(RM) -r ebin/ clean: $(REBAR) clean $(RM) .generated $(RM) -r .rebar/ $(RM) -r src/gen-erl/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) $(distdir)/.generated $(RM) -r $(distdir)/.rebar/ $(RM) -r $(distdir)/ebin/ $(RM) -r $(distdir)/src/gen-erl/ thrift-0.23.0/test/swift/0000775000175000017500000000000015170007175015474 5ustar00buildbuild00000000000000thrift-0.23.0/test/swift/CrossTests/0000775000175000017500000000000015170007175017610 5ustar00buildbuild00000000000000thrift-0.23.0/test/swift/CrossTests/Package.swift0000664000175000017500000000331015165535636022232 0ustar00buildbuild00000000000000// 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: "CrossTests", products: [ .executable(name: "TestServer", targets: ["TestServer"]), .executable(name: "TestClient", targets: ["TestClient"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. .package(path: "../../../lib/swift") ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target( name: "Common", dependencies: ["Thrift"]), .target( name: "TestServer", dependencies: ["Thrift", "Common"]), .target( name: "TestClient", dependencies: ["Thrift", "Common"]) ] ) thrift-0.23.0/test/swift/CrossTests/Sources/0000775000175000017500000000000015165535636021247 5ustar00buildbuild00000000000000thrift-0.23.0/test/swift/CrossTests/Sources/TestClient/0000775000175000017500000000000015165535636023325 5ustar00buildbuild00000000000000thrift-0.23.0/test/swift/CrossTests/Sources/TestClient/main.swift0000664000175000017500000003013615165535636025332 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. import Foundation import Thrift import Common import XCTest enum Error: Int32 { case baseTypes = 1 case structs = 2 case containers = 4 case exceptions = 8 case unknown = 64 case timeout = 128 } class TestClient { var client: ThriftTestClient var resultCode: Int32 = 0 public init(parameters: TestClientParameters) throws { let transport = try TestClient.getTransport(parameters: parameters) let proto = try TestClient.getProtocol(parameters: parameters, transport: transport) client = ThriftTestClient(inoutProtocol: proto) } static func getTransport(parameters: TestClientParameters) throws -> TTransport { 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) } if parameters.transport == .buffered { return socketTransport } throw ParserError.unsupportedOption } static func getProtocol(parameters: TestClientParameters, transport: TTransport) throws -> TProtocol { if parameters.proto == .binary { return TBinaryProtocol(on: transport) } if parameters.proto == .compact { return TCompactProtocol(on: transport) } throw ParserError.unsupportedOption } func run() throws { do { try testVoid() try testString() try testBool() try testByte() try testI32() try testI64() try testDouble() try testBinary() try testStruct() try testNest() try testMap() try testSet() try testList() try testEnum() try testTypedef() try testMapMap() try testInsanity() try testMulti() try testException() try testMultiException() // Swift generator doesn't yet support one way functions (THRIFT-5468) /*try testOneway() try testOnewayThenNormal()*/ try testUuid() } catch let error { print("\(error)") resultCode |= Error.unknown.rawValue } exit(resultCode) } func testVoid() throws { print("testVoid") try client.testVoid() } func testString1(_ s1: String) throws { print("testString(\(s1))") let r1 = try client.testString(thing: s1) print(r1) if s1 != r1 { resultCode |= Error.baseTypes.rawValue } } func testString() throws { try testString1(String(repeating: "Python", count: 20)) try testString1("") try testString1("\t\n/\\\\\r{}:パイソン") try testString1(""" 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ú, 粵語 """) } func testBool1(_ s1: Bool) throws { print("testBool(\(s1))") let r1 = try client.testBool(thing: s1) print(r1) if s1 != r1 { resultCode |= Error.baseTypes.rawValue } } func testBool() throws { try testBool1(true) try testBool1(false) } func testByte() throws { print("testByte") if try client.testByte(thing: 63) != 63 { resultCode |= Error.baseTypes.rawValue } if try client.testByte(thing: -127) != -127 { resultCode |= Error.baseTypes.rawValue } } func testI32() throws { print("testI32") if try client.testI32(thing: -1) != -1 { resultCode |= Error.baseTypes.rawValue } if try client.testI32(thing: 0) != 0 { resultCode |= Error.baseTypes.rawValue } } func testI64() throws { print("testI64") if try client.testI64(thing: 1) != 1 || client.testI64(thing: -34359738368) != -34359738368 { resultCode |= Error.baseTypes.rawValue } } func testDouble() throws { print("testDouble") for testValue in [-5.235098235, 0, -1, -0.000341012439638598279] { if try client.testDouble(thing: testValue) != testValue { resultCode |= Error.baseTypes.rawValue } } } func testBinary() throws { print("testBinary") let val = Data(Array(0...255)) if try client.testBinary(thing: val) != val { resultCode |= Error.baseTypes.rawValue } } func testStruct() throws { print("testStruct") let x = Xtruct(string_thing: "Zero", byte_thing: 1, i32_thing: -3, i64_thing: -5) if try client.testStruct(thing: x) != x { resultCode |= Error.structs.rawValue } } func testNest() throws { print("testNest") let inner = Xtruct(string_thing: "Zero", byte_thing: 1, i32_thing: -3, i64_thing: -5) let x = Xtruct2(byte_thing: 0, struct_thing: inner, i32_thing: 0) if try client.testNest(thing: x) != x { resultCode |= Error.structs.rawValue } } func testMap() throws { print("testMap") let x = TMap([0: 1, 1: 2, 2: 3, 3: 4, -1: -2]) if try client.testMap(thing: x) != x { resultCode |= Error.containers.rawValue } } func testSet() throws { print("testSet") let x = TSet([8, 1, 42]) if try client.testSet(thing: x) != x { resultCode |= Error.containers.rawValue } } func testList() throws { print("testList") let x = TList([1, 4, 9, -42]) if try client.testList(thing: x) != x { resultCode |= Error.containers.rawValue } } func testEnum() throws { print("testEnum") let x = Numberz.five if try client.testEnum(thing: x) != x { resultCode |= Error.containers.rawValue } } func testTypedef() throws { print("testTypedef") let x = UserId(bitPattern: 0xffffffffffffff) if try client.testTypedef(thing: x) != x { resultCode |= Error.containers.rawValue } } func testMapMap() throws { print("testMapMap") let x = TMap>([ -4: [-4: -4, -3: -3, -2: -2, -1: -1], 4: [4: 4, 3: 3, 2: 2, 1: 1] ]) if try client.testMapMap(hello: 42) != x { resultCode |= Error.containers.rawValue } } func testInsanity() throws { print("testInsanity()") let argument = Insanity(userMap: [.eight: 8], xtructs: []) let expected = TMap>([ 1: [ .two: argument, .three: argument ], 2: [ .six: Insanity(userMap: [:], xtructs: []) ] ]) if try client.testInsanity(argument: argument) != expected { resultCode |= Error.containers.rawValue } } func testMulti() throws { print("testMulti") let x = Xtruct(string_thing: "Hello2", byte_thing: 74, i32_thing: 0xff00ff, i64_thing: 0xffffffffd0d0) if try client.testMulti(arg0: x.byte_thing, arg1: x.i32_thing, arg2: x.i64_thing, arg3: .init([0: "abc"]), arg4: Numberz.five, arg5: 0xf0f0f0) != x { resultCode |= Error.containers.rawValue } } func testException() throws { print("testException") try client.testException(arg: "Safe") do { try client.testException(arg: "Xception") resultCode |= Error.exceptions.rawValue } catch let error as Xception { guard error.errorCode == 1001, error.message == "Xception" else { resultCode |= Error.exceptions.rawValue return } } catch { resultCode |= Error.exceptions.rawValue } do { try client.testException(arg: "TException") resultCode |= Error.exceptions.rawValue } catch is TError { } catch { resultCode |= Error.exceptions.rawValue } try client.testException(arg: "success") } func testMultiException() throws { print("testMultiException") do { _ = try client.testMultiException(arg0: "Xception", arg1: "ignore") } catch let error as Xception { guard error.errorCode == 1001, error.message == "This is an Xception" else { resultCode |= Error.exceptions.rawValue return } } catch { resultCode |= Error.exceptions.rawValue } do { _ = try client.testMultiException(arg0: "Xception2", arg1: "ignore") } catch let error as Xception2 { guard error.errorCode == 2002, error.struct_thing.string_thing == "This is an Xception2" else { resultCode |= Error.exceptions.rawValue return } } let y = try client.testMultiException(arg0: "success", arg1: "foobar") if y.string_thing != "foobar" { resultCode |= Error.exceptions.rawValue } } // Swift generator doesn't yet support one way functions (THRIFT-5468) /*func testOneway() throws { print("testOneway") let start = CACurrentMediaTime() try client.testOneway(secondsToSleep: 1) let end = CACurrentMediaTime() let duration = end - start let delta = abs(1 - duration) print("oneway sleep took \(end - start) sec") guard delta < 0.5 else { print("oneway sleep took \(end - start) sec") resultCode |= Error.unknown.rawValue return } } func testOnewayThenNormal() throws { print("testOnewayThenNormal") try client.testOneway(secondsToSleep: 1) if try client.testString(thing: "Swift") != "Swift" { resultCode |= Error.baseTypes.rawValue } }*/ func testUuid() throws { let uuid = UUID() guard try client.testUuid(thing: uuid) == uuid else { resultCode |= Error.baseTypes.rawValue return } } } let parameters = try TestClientParameters(arguments: CommandLine.arguments) if parameters.showHelp { parameters.printHelp() exit(0) } Thread.sleep(forTimeInterval: 1) try TestClient(parameters: parameters).run() thrift-0.23.0/test/swift/CrossTests/Sources/Common/0000775000175000017500000000000015165535636022477 5ustar00buildbuild00000000000000thrift-0.23.0/test/swift/CrossTests/Sources/Common/Parameters.swift0000664000175000017500000002117115165535636025662 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. import Foundation import Thrift public enum Protocol: String { case binary case compact case header case json } public enum Transport: String { case buffered case framed case http case anonpipe case zlib } public enum ServerType: String { case simple case threadPool = "thread-pool" case threaded case nonblocking } public enum ParserError: Error { case unknownArgument(argument: String) case missingParameter(argument: String) case invalidParameter(argument: String, parameter: String) case unsupportedOption } public class ParametersBase { public var showHelp = false public var port: Int? public var domainSocket: String? public var namedPipe: String? public var proto: Protocol? public var transport: Transport? public var multiplex = false public var abstractNamespace = false public var ssl = false public var zlib = false public init (arguments: [String]) throws { if arguments.count > 1 { for argument in arguments[1...] { let equalSignPos = argument.firstIndex(of: "=") ?? argument.endIndex let name = String(argument[.. String { print("testString(\"\(thing)\")") return thing } /// Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false' /// @param bool thing - the bool data to print /// @return bool - returns the bool 'thing' /// /// - Parameters: /// - thing: /// - Returns: Bool /// - Throws: func testBool(thing: Bool) throws -> Bool { print("testBool\"(\(thing ? "true" : "false")\")") return thing } /// Prints 'testByte("%d")' with thing as '%d' /// The types i8 and byte are synonyms, use of i8 is encouraged, byte still exists for the sake of compatibility. /// @param byte thing - the i8/byte to print /// @return i8 - returns the i8/byte 'thing' /// /// - Parameters: /// - thing: /// - Returns: Int8 /// - Throws: func testByte(thing: Int8) throws -> Int8 { print("testByte(\"\(thing)\")") return thing } /// Prints 'testI32("%d")' with thing as '%d' /// @param i32 thing - the i32 to print /// @return i32 - returns the i32 'thing' /// /// - Parameters: /// - thing: /// - Returns: Int32 /// - Throws: func testI32(thing: Int32) throws -> Int32 { print("testI32(\"\(thing)\")") return thing } /// Prints 'testI64("%d")' with thing as '%d' /// @param i64 thing - the i64 to print /// @return i64 - returns the i64 'thing' /// /// - Parameters: /// - thing: /// - Returns: Int64 /// - Throws: func testI64(thing: Int64) throws -> Int64 { print("testI64(\"\(thing)\")") return thing } /// Prints 'testDouble("%f")' with thing as '%f' /// @param double thing - the double to print /// @return double - returns the double 'thing' /// /// - Parameters: /// - thing: /// - Returns: Double /// - Throws: func testDouble(thing: Double) throws -> Double { print("testDouble(\"\(thing)\")") return thing } /// Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data /// @param binary thing - the binary data to print /// @return binary - returns the binary 'thing' /// /// - Parameters: /// - thing: /// - Returns: Data /// - Throws: func testBinary(thing: Data) throws -> Data { print("testBinary(\"\(thing)\")") return thing } /// Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values /// @param Xtruct thing - the Xtruct to print /// @return Xtruct - returns the Xtruct 'thing' /// /// - Parameters: /// - thing: /// - Returns: Xtruct /// - Throws: func testStruct(thing: Xtruct) throws -> Xtruct { print("testStruct({\([thing.string_thing, "\(thing.byte_thing)", "\(thing.i32_thing)", "\(thing.i64_thing)"].joined(separator: ", "))})") return thing } /// Prints 'testNest("{%s}")' where thing has been formatted into a string of the nested struct /// @param Xtruct2 thing - the Xtruct2 to print /// @return Xtruct2 - returns the Xtruct2 'thing' /// /// - Parameters: /// - thing: /// - Returns: Xtruct2 /// - Throws: func testNest(thing: Xtruct2) throws -> Xtruct2 { print("testNest(\(thing)") return thing } /// Prints 'testMap("{%s")' where thing has been formatted into a string of 'key => value' pairs /// separated by commas and new lines /// @param map thing - the map to print /// @return map - returns the map 'thing' /// /// - Parameters: /// - thing: /// - Returns: TMap /// - Throws: func testMap(thing: TMap) throws -> TMap { print("testMap(\(thing)") return thing } /// Prints 'testStringMap("{%s}")' where thing has been formatted into a string of 'key => value' pairs /// separated by commas and new lines /// @param map thing - the map to print /// @return map - returns the map 'thing' /// /// - Parameters: /// - thing: /// - Returns: TMap /// - Throws: func testStringMap(thing: TMap) throws -> TMap { print("testStringMap(\(thing)") return thing } /// Prints 'testSet("{%s}")' where thing has been formatted into a string of values /// separated by commas and new lines /// @param set thing - the set to print /// @return set - returns the set 'thing' /// /// - Parameters: /// - thing: /// - Returns: TSet /// - Throws: func testSet(thing: TSet) throws -> TSet { print("testSet\(thing)") return thing } /// Prints 'testList("{%s}")' where thing has been formatted into a string of values /// separated by commas and new lines /// @param list thing - the list to print /// @return list - returns the list 'thing' /// /// - Parameters: /// - thing: /// - Returns: TList /// - Throws: func testList(thing: TList) throws -> TList { print("testList\(thing)") return thing } /// Prints 'testEnum("%d")' where thing has been formatted into its numeric value /// @param Numberz thing - the Numberz to print /// @return Numberz - returns the Numberz 'thing' /// /// - Parameters: /// - thing: /// - Returns: Numberz /// - Throws: func testEnum(thing: Numberz) throws -> Numberz { print("testEnum\(thing.rawValue)") return thing } /// Prints 'testTypedef("%d")' with thing as '%d' /// @param UserId thing - the UserId to print /// @return UserId - returns the UserId 'thing' /// /// - Parameters: /// - thing: /// - Returns: UserId /// - Throws: func testTypedef(thing: UserId) throws -> UserId { print("testTypedef(\(thing)") return thing } /// Prints 'testMapMap("%d")' with hello as '%d' /// @param i32 hello - the i32 to print /// @return map> - returns a dictionary with these values: /// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, } /// /// - Parameters: /// - hello: /// - Returns: TMap> /// - Throws: func testMapMap(hello: Int32) throws -> TMap> { print("testMapMap(\(hello)") return TMap>([ -4: [-4: -4, -3: -3, -2: -2, -1: -1], 4: [4: 4, 3: 3, 2: 2, 1: 1] ]) } /// So you think you've got this all worked out, eh? /// Creates a map with these values and prints it out: /// { 1 => { 2 => argument, /// 3 => argument, /// }, /// 2 => { 6 => , }, /// } /// @return map> - a map with the above values /// /// - Parameters: /// - argument: /// - Returns: TMap> /// - Throws: func testInsanity(argument: Insanity) throws -> TMap> { return TMap>([ 1: [ .two: argument, .three: argument ], 2: [ .six: Insanity(userMap: [:], xtructs: []) ] ]) } /// Prints 'testMulti()' /// @param i8 arg0 - /// @param i32 arg1 - /// @param i64 arg2 - /// @param map arg3 - /// @param Numberz arg4 - /// @param UserId arg5 - /// @return Xtruct - returns an Xtruct with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1 /// and i64_thing = arg2 /// /// - Parameters: /// - arg0: /// - arg1: /// - arg2: /// - arg3: /// - arg4: /// - arg5: /// - Returns: Xtruct /// - Throws: func testMulti(arg0: Int8, arg1: Int32, arg2: Int64, arg3: TMap, arg4: Numberz, arg5: UserId) throws -> Xtruct { print("testMulti()") return Xtruct(string_thing: "Hello2", byte_thing: arg0, i32_thing: arg1, i64_thing: arg2) } /// Print 'testException(%s)' with arg as '%s' /// @param string arg - a string indication what type of exception to throw /// if arg == "Xception" throw Xception with errorCode = 1001 and message = arg /// else if arg == "TException" throw TException /// else do not throw anything /// /// - Parameters: /// - arg: /// - Throws: Xception func testException(arg: String) throws { print("testException(\(arg)") if arg == "Xception" { throw Xception(errorCode: 1001, message: arg) } else if arg == "TException" { throw TApplicationError() // is type TError (TException Swift equiv) } } /// Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s' /// @param string arg - a string indicating what type of exception to throw /// if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception" /// else if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and struct_thing.string_thing = "This is an Xception2" /// else do not throw anything /// @return Xtruct - an Xtruct with string_thing = arg1 /// /// - Parameters: /// - arg0: /// - arg1: /// - Returns: Xtruct /// - Throws: Xception, Xception2 func testMultiException(arg0: String, arg1: String) throws -> Xtruct { print("testMultiException(\(arg0), \(arg1)") if arg0 == "Xception" { throw Xception(errorCode: 1001, message: "This is an Xception") } else if arg0 == "Xception2" { throw Xception2(errorCode: 2002, struct_thing: Xtruct(string_thing: "This is an Xception2", byte_thing: 0, i32_thing: 0, i64_thing: 0)) } return Xtruct(string_thing: arg1, byte_thing: 0, i32_thing: 0, i64_thing: 0) } /// Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d' /// sleep 'secondsToSleep' /// Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d' /// @param i32 secondsToSleep - the number of seconds to sleep /// /// - Parameters: /// - secondsToSleep: /// - Throws: func testOneway(secondsToSleep: Int32) throws { print("testOneway(\(secondsToSleep): Sleeping...") Thread.sleep(forTimeInterval: TimeInterval(secondsToSleep)) } func testUuid(thing: UUID) throws -> UUID { print("testUuid(\(thing))") return thing } } class SecondServiceImpl : SecondService { /// Prints 'testString("%s")' with thing as '%s' /// @param string thing - the string to print /// @return string - returns the string 'thing' /// /// - Parameters: /// - thing: /// - Returns: String /// - Throws: func secondtestString(thing: String) throws -> String { print("testString(\"\(thing)\")") return thing } } thrift-0.23.0/test/swift/CrossTests/Sources/TestServer/main.swift0000664000175000017500000000572415165535636025367 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. import Foundation import Thrift import Common class TestServer { var server: Any? func run() throws { let parameters = try TestServerParameters(arguments: CommandLine.arguments) if parameters.showHelp { parameters.printHelp() return } let service = ThriftTestImpl() let processor = ThriftTestProcessor(service: service) 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, .none): let proto = TBinaryProtocol.self server = try TFramedSocketServer(port: parameters.port!, inProtocol: proto, outProtocol: proto, processor: processor) case (.compact, .buffered, .none): let proto = TCompactProtocol.self server = try TSocketServer(port: parameters.port!, inProtocol: proto, outProtocol: proto, processor: processor) 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 } } } let server = TestServer() try server.run() RunLoop.main.run() thrift-0.23.0/test/swift/CrossTests/Makefile0000644000175000017500000004427115170007175021256 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # test/swift/CrossTests/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = test/swift/CrossTests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/test/swift/CrossTests abs_srcdir = /thrift/src/test/swift/CrossTests abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. TESTTHRIFT = ../../ThriftTest.thrift all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/swift/CrossTests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/swift/CrossTests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: $(THRIFT) $(TESTTHRIFT) $(THRIFT) -o Sources/Common --gen swift $(TESTTHRIFT) precross: stubs swift build check: stubs clean-local: $(RM) -r Sources/Common/gen-swift/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) -r $(distdir)/gen-swift/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/swift/CrossTests/Makefile.in0000644000175000017500000004315115170007167021660 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/swift/CrossTests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TESTTHRIFT = ../../ThriftTest.thrift all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/swift/CrossTests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/swift/CrossTests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: $(THRIFT) $(TESTTHRIFT) $(THRIFT) -o Sources/Common --gen swift $(TESTTHRIFT) precross: stubs swift build check: stubs clean-local: $(RM) -r Sources/Common/gen-swift/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) -r $(distdir)/gen-swift/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/swift/CrossTests/Makefile.am0000664000175000017500000000210415165535636021655 0ustar00buildbuild00000000000000# # 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. # TESTTHRIFT=../../ThriftTest.thrift stubs: $(THRIFT) $(TESTTHRIFT) $(THRIFT) -o Sources/Common --gen swift $(TESTTHRIFT) precross: stubs swift build check: stubs clean-local: $(RM) -r Sources/Common/gen-swift/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) -r $(distdir)/gen-swift/ thrift-0.23.0/test/swift/Makefile0000644000175000017500000006001215170007175017131 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # test/swift/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = test/swift ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/test/swift abs_srcdir = /thrift/src/test/swift abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. SUBDIRS = CrossTests all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/swift/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/swift/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am precross: $(MAKE) -C CrossTests precross # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/swift/Makefile.in0000644000175000017500000005674415170007167017560 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/swift ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = CrossTests all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/swift/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/swift/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am precross: $(MAKE) -C CrossTests precross # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/swift/Makefile.am0000664000175000017500000000160115165535636017542 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = CrossTests distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am precross: $(MAKE) -C CrossTests precross thrift-0.23.0/test/perl/0000775000175000017500000000000015170007175015302 5ustar00buildbuild00000000000000thrift-0.23.0/test/perl/TestClient.pl0000775000175000017500000002435415165535636017744 0ustar00buildbuild00000000000000#!/usr/bin/env perl # # 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. # use 5.10.0; use strict; use warnings; use Data::Dumper; use Getopt::Long qw(GetOptions); use Time::HiRes qw(gettimeofday); use lib '../../lib/perl/lib'; use lib 'gen-perl'; use Thrift; use Thrift::BinaryProtocol; use Thrift::BufferedTransport; use Thrift::FramedTransport; use Thrift::MultiplexedProtocol; use Thrift::SSLSocket; use Thrift::Socket; use Thrift::UnixSocket; use ThriftTest::SecondService; use ThriftTest::ThriftTest; use ThriftTest::Types; $|++; sub usage { print <<"EOF"; Usage: $0 [OPTIONS] Options: (default) --ca CA to validate server with. --cert Certificate to use. Required if using --ssl. --ciphers Acceptable cipher list. --domain-socket Use a unix domain socket. --help Show usage. --key Certificate key. Required if using --ssl. --port 9090 Port to use. --protocol {binary} binary Protocol to use. --ssl If present, use SSL. --transport {buffered|framed} buffered Transport to use. EOF } my %opts = ( 'port' => 9090, 'protocol' => 'binary', 'transport' => 'buffered' ); GetOptions(\%opts, qw ( ca=s cert=s ciphers=s key=s domain-socket=s help host=s port=i protocol=s ssl transport=s )) || exit 1; if ($opts{help}) { usage(); exit 0; } my $socket = undef; if ($opts{'domain-socket'}) { $socket = Thrift::UnixSocket->new($opts{'domain-socket'}); } elsif ($opts{ssl}) { $socket = Thrift::SSLSocket->new(\%opts); } else { $socket = Thrift::Socket->new($opts{host}, $opts{port}); } my $transport; if ($opts{transport} eq 'buffered') { $transport = Thrift::BufferedTransport->new($socket, 1024, 1024); } elsif ($opts{transport} eq 'framed') { $transport = Thrift::FramedTransport->new($socket); } else { usage(); exit 1; } my $protocol; my $protocol2; if ($opts{protocol} eq 'binary' || $opts{protocol} eq 'multi') { $protocol = Thrift::BinaryProtocol->new($transport); } else { usage(); exit 1; } my $secondService = undef; if (index($opts{protocol}, 'multi') == 0) { $protocol2 = Thrift::MultiplexedProtocol->new($protocol, 'SecondService'); $protocol = Thrift::MultiplexedProtocol->new($protocol, 'ThriftTest'); $secondService = ThriftTest::SecondServiceClient->new($protocol2); } my $testClient = ThriftTest::ThriftTestClient->new($protocol); eval { $transport->open(); }; if($@){ die(Dumper($@)); } use constant ERR_BASETYPES => 1; use constant ERR_STRUCTS => 2; use constant ERR_CONTAINERS => 4; use constant ERR_EXCEPTIONS => 8; use constant ERR_PROTOCOL => 16; use constant ERR_UNKNOWN => 64; my $start = gettimeofday(); # # VOID TEST # print('testVoid()'); $testClient->testVoid(); print(" = void\n"); # # STRING TEST # print('testString("Test")'); my $s = $testClient->testString('Test'); print(qq| = "$s"\n|); exit(ERR_BASETYPES) if ($s ne 'Test'); # # MULTIPLEXED TEST # if (index($opts{protocol}, 'multi') == 0) { print('secondtestString("Test2")'); $s = $secondService->secondtestString('Test2'); print(qq| = "$s"\n|); exit(ERR_PROTOCOL) if ($s ne 'testString("Test2")'); } # # BOOL TEST # print('testBool(1)'); my $t = $testClient->testBool(1); print(" = $t\n"); exit(ERR_BASETYPES) if ($t ne 1); print('testBool(0)'); my $f = $testClient->testBool(0); print(" = $f\n"); exit(ERR_BASETYPES) if ($f ne q||); # # BYTE TEST # print('testByte(1)'); my $u8 = $testClient->testByte(1); print(" = $u8\n"); # # I32 TEST # print('testI32(-1)'); my $i32 = $testClient->testI32(-1); print(" = $i32\n"); exit(ERR_BASETYPES) if ($i32 ne -1); # # I64 TEST # print('testI64(-34359738368)'); my $i64 = $testClient->testI64(-34359738368); print(" = $i64\n"); exit(ERR_BASETYPES) if ($i64 ne -34359738368); # # DOUBLE TEST # print('testDouble(-852.234234234)'); my $dub = $testClient->testDouble(-852.234234234); print(" = $dub\n"); exit(ERR_BASETYPES) if ($dub ne -852.234234234); # # BINARY TEST # print("testBinary(pack('C*', 0..255))"); my $bin = $testClient->testBinary(pack('C*', 0..255)); printf(" = %s\n", join ' ', map { sprintf '%02x', $_ } unpack('C*', $bin)); exit(ERR_BASETYPES) if ($bin ne pack('C*', 0..255)); # # STRUCT TEST # print('testStruct({"Zero", 1, -3, -5})'); my $out = ThriftTest::Xtruct->new(); $out->string_thing('Zero'); $out->byte_thing(1); $out->i32_thing(-3); $out->i64_thing(-5); my $in = $testClient->testStruct($out); print(' = {"'.$in->string_thing.'", '. $in->byte_thing.', '. $in->i32_thing.', '. $in->i64_thing."}\n"); # # NESTED STRUCT TEST # print('testNest({1, {"Zero", 1, -3, -5}, 5}'); my $out2 = ThriftTest::Xtruct2->new(); $out2->byte_thing(1); $out2->struct_thing($out); $out2->i32_thing(5); my $in2 = $testClient->testNest($out2); $in = $in2->struct_thing; print(' = {'.$in2->byte_thing.', {"'. $in->string_thing.'", '. $in->byte_thing.', '. $in->i32_thing.', '. $in->i64_thing.'}, '. $in2->i32_thing."}\n"); # # MAP TEST # my $mapout = {}; for (my $i = 0; $i < 5; ++$i) { $mapout->{$i} = $i-10; } print('testMap({'); my $first = 1; while( my($key,$val) = each %$mapout) { if ($first) { $first = 0; } else { print(', '); } print("$key => $val"); } print('})'); my $mapin = $testClient->testMap($mapout); print(' = {'); $first = 1; while( my($key,$val) = each %$mapin){ if ($first) { $first = 0; } else { print(', '); } print("$key => $val"); } print("}\n"); # # SET TEST # my $setout = []; for (my $i = -2; $i < 3; ++$i) { push(@$setout, $i); } print('testSet({'.join(',',@$setout).'})'); my $setin = $testClient->testSet($setout); print(' = {'.join(',',@$setout)."}\n"); # # LIST TEST # my $listout = []; for (my $i = -2; $i < 3; ++$i) { push(@$listout, $i); } print('testList({'.join(',',@$listout).'})'); my $listin = $testClient->testList($listout); print(' = {'.join(',',@$listin)."}\n"); # # ENUM TEST # print('testEnum(ONE)'); my $ret = $testClient->testEnum(ThriftTest::Numberz::ONE); print(" = $ret\n"); print('testEnum(TWO)'); $ret = $testClient->testEnum(ThriftTest::Numberz::TWO); print(" = $ret\n"); print('testEnum(THREE)'); $ret = $testClient->testEnum(ThriftTest::Numberz::THREE); print(" = $ret\n"); print('testEnum(FIVE)'); $ret = $testClient->testEnum(ThriftTest::Numberz::FIVE); print(" = $ret\n"); print('testEnum(EIGHT)'); $ret = $testClient->testEnum(ThriftTest::Numberz::EIGHT); print(" = $ret\n"); # # TYPEDEF TEST # print('testTypedef(309858235082523)'); my $uid = $testClient->testTypedef(309858235082523); print(" = $uid\n"); # # NESTED MAP TEST # print('testMapMap(1)'); my $mm = $testClient->testMapMap(1); print(' = {'); while( my ($key,$val) = each %$mm) { print("$key => {"); while( my($k2,$v2) = each %$val) { print("$k2 => $v2, "); } print('}, '); } print("}\n"); # # INSANITY TEST # my $insane = ThriftTest::Insanity->new(); $insane->{userMap}->{ThriftTest::Numberz::FIVE} = 5000; my $truck = ThriftTest::Xtruct->new(); $truck->string_thing('Hello2'); $truck->byte_thing(2); $truck->i32_thing(2); $truck->i64_thing(2); my $truck2 = ThriftTest::Xtruct->new(); $truck2->string_thing('Goodbye4'); $truck2->byte_thing(4); $truck2->i32_thing(4); $truck2->i64_thing(4); push(@{$insane->{xtructs}}, $truck); push(@{$insane->{xtructs}}, $truck2); print('testInsanity()'); my $whoa = $testClient->testInsanity($insane); print(' = {'); while( my ($key,$val) = each %$whoa) { print("$key => {"); while( my($k2,$v2) = each %$val) { print("$k2 => {"); my $userMap = $v2->{userMap}; print('{'); if (ref($userMap) eq 'HASH') { while( my($k3,$v3) = each %$userMap) { print("$k3 => $v3, "); } } print('}, '); my $xtructs = $v2->{xtructs}; print('{'); if (ref($xtructs) eq 'ARRAY') { foreach my $x (@$xtructs) { print('{"'.$x->{string_thing}.'", '. $x->{byte_thing}.', '.$x->{i32_thing}.', '.$x->{i64_thing}.'}, '); } } print('}'); print('}, '); } print('}, '); } print("}\n"); # # EXCEPTION TEST # print(q|testException('Xception')|); eval { $testClient->testException('Xception'); print(" void\nFAILURE\n"); }; if($@ && $@->UNIVERSAL::isa('ThriftTest::Xception')) { print(' caught xception '.$@->{errorCode}.': '.$@->{message}."\n"); } # # Normal tests done. # my $stop = gettimeofday(); my $elp = sprintf('%d',1000*($stop - $start), 0); print("Total time: $elp ms\n"); # # Extraneous "I don't trust PHP to pack/unpack integer" tests # # Max I32 my $num = 2**30 + 2**30 - 1; my $num2 = $testClient->testI32($num); if ($num != $num2) { print "Missed max32 $num = $num2\n"; } # Min I32 $num = 0 - 2**31; $num2 = $testClient->testI32($num); if ($num != $num2) { print "Missed min32 $num = $num2\n"; } # Max Number I can get out of my perl $num = 2**40; $num2 = $testClient->testI64($num); if ($num != $num2) { print "Missed max64 $num = $num2\n"; } # Max Number I can get out of my perl $num = 0 - 2**40; $num2 = $testClient->testI64($num); if ($num != $num2) { print "Missed min64 $num = $num2\n"; } $transport->close(); thrift-0.23.0/test/perl/TestServer.pl0000664000175000017500000002323615165535636017767 0ustar00buildbuild00000000000000#!/usr/bin/env perl # # 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. # use 5.10.0; use strict; use warnings; use Data::Dumper; use Getopt::Long qw(GetOptions); use Time::HiRes qw(gettimeofday); $SIG{INT} = \&sigint_handler; use lib '../../lib/perl/lib'; use lib 'gen-perl'; use Thrift; use Thrift::BinaryProtocol; use Thrift::BufferedTransport; use Thrift::FramedTransport; use Thrift::MultiplexedProcessor; use Thrift::SSLServerSocket; use Thrift::ServerSocket; use Thrift::Server; use Thrift::UnixServerSocket; use ThriftTest::SecondService; use ThriftTest::ThriftTest; use ThriftTest::Types; $|++; sub usage { print <<"EOF"; Usage: $0 [OPTIONS] Options: (default) --ca Certificate authority file (optional). --cert Certificate file. Required if using --ssl. --ciphers Acceptable cipher list. --domain-socket Use a unix domain socket. --help Show usage. --key Private key file for certificate. Required if using --ssl and private key is not in the certificate file. --port 9090 Port to use. --protocol {binary} binary Protocol to use. --ssl If present, use SSL/TLS. --transport {buffered|framed} buffered Transport to use. EOF } my %opts = ( 'port' => 9090, 'protocol' => 'binary', 'transport' => 'buffered' ); GetOptions(\%opts, qw ( ca=s cert=s ciphers=s domain-socket=s help host=s key=s port=i protocol=s ssl transport=s )) || exit 1; if ($opts{help}) { usage(); exit 0; } if ($opts{ssl} and not defined $opts{cert}) { usage(); exit 1; } my $handler = ThriftTestHandler->new(); my $handler2 = SecondServiceHandler->new(); my $processor = ThriftTest::ThriftTestProcessor->new($handler); my $processor2 = ThriftTest::SecondServiceProcessor->new($handler2); my $serversocket; if ($opts{'domain-socket'}) { unlink($opts{'domain-socket'}); $serversocket = Thrift::UnixServerSocket->new($opts{'domain-socket'}); } elsif ($opts{ssl}) { $serversocket = Thrift::SSLServerSocket->new(\%opts); } else { $serversocket = Thrift::ServerSocket->new(\%opts); } my $transport; if ($opts{transport} eq 'buffered') { $transport = Thrift::BufferedTransportFactory->new(); } elsif ($opts{transport} eq 'framed') { $transport = Thrift::FramedTransportFactory->new(); } else { usage(); exit 1; } my $protocol; if ($opts{protocol} eq 'binary' || $opts{protocol} eq 'multi') { $protocol = Thrift::BinaryProtocolFactory->new(); } else { usage(); exit 1; } if (index($opts{protocol}, 'multi') == 0) { my $newProcessor = Thrift::MultiplexedProcessor->new($protocol); $newProcessor->defaultProcessor($processor); $newProcessor->registerProcessor('ThriftTest', $processor); $newProcessor->registerProcessor('SecondService', $processor2); $processor = $newProcessor; } my $ssltag = ''; if ($opts{ssl}) { $ssltag = '(SSL)'; } my $listening_on = "$opts{port} $ssltag"; if ($opts{'domain-socket'}) { $listening_on = $opts{'domain-socket'}; } my $server = Thrift::SimpleServer->new($processor, $serversocket, $transport, $protocol); print qq|Starting "simple" server ($opts{transport}/$opts{protocol}) listen on: $listening_on\n|; $server->serve(); print "done.\n"; sub sigint_handler { print "received SIGINT, stopping...\n"; $server->stop(); } ### ### Test server implementation ### package ThriftTestHandler; use base qw( ThriftTest::ThriftTestIf ); sub new { my $classname = shift; my $self = {}; return bless($self, $classname); } sub testVoid { print("testVoid()\n"); } sub testString { my $self = shift; my $thing = shift; print("testString($thing)\n"); return $thing; } sub testBool { my $self = shift; my $thing = shift; my $str = $thing ? 'true' : 'false'; print("testBool($str)\n"); return $thing; } sub testByte { my $self = shift; my $thing = shift; print("testByte($thing)\n"); return $thing; } sub testI32 { my $self = shift; my $thing = shift; print("testI32($thing)\n"); return $thing; } sub testI64 { my $self = shift; my $thing = shift; print("testI64($thing)\n"); return $thing; } sub testDouble { my $self = shift; my $thing = shift; print("testDouble($thing)\n"); return $thing; } sub testBinary { my $self = shift; my $thing = shift; my @bytes = split //, $thing; print 'testBinary('; printf( '%02lx', ord $_ ) foreach (@bytes); print ")\n"; return $thing; } sub testStruct { my $self = shift; my $thing = shift; printf(qq|testStruct({"%s", %d, %d, %lld})\n|, $thing->{string_thing}, $thing->{byte_thing}, $thing->{i32_thing}, $thing->{i64_thing}); return $thing; } sub testNest { my $self = shift; my $nest = shift; my $thing = $nest->{struct_thing}; printf(qq|testNest({%d, {"%s", %d, %d, %lld}, %d})\n|, $nest->{byte_thing}, $thing->{string_thing}, $thing->{byte_thing}, $thing->{i32_thing}, $thing->{i64_thing}, $nest->{i32_thing}); return $nest; } sub testMap { my $self = shift; my $thing = shift; printf "testMap({%s})\n", join( ', ', map { $_ . ' => ' . $thing->{$_} } sort keys %$thing ); return $thing; } sub testStringMap { my $self = shift; my $thing = shift; printf "testStringMap({%s})\n", join( ', ', map { $_ . ' => ' . $thing->{$_} } sort keys %$thing ); return $thing; } sub testSet { my $self = shift; my $thing = shift; my @result = sort keys %$thing; printf "testSet({%s})\n", join(', ', @result ); return \@result; } sub testList { my $self = shift; my $thing = shift; print "testList({%s})\n", join(', ', @$thing); return $thing; } sub testEnum { my $self = shift; my $thing = shift; print "testEnum($thing)\n"; return $thing; } sub testTypedef { my $self = shift; my $thing = shift; print("testTypedef($thing)\n"); return $thing; } sub testMapMap { my $self = shift; my $hello = shift; printf("testMapMap(%d)\n", $hello); my $result = { 4 => { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }, -4 => { -1 => -1, -2 => -2, -3 => -3, -4 => -4 } }; return $result; } sub testInsanity { my $self = shift; my $argument = shift; print("testInsanity()\n"); my $hello = ThriftTest::Xtruct->new({string_thing => 'Hello2', byte_thing => 2, i32_thing => 2, i64_thing => 2}); my @hellos; push(@hellos, $hello); my $goodbye = ThriftTest::Xtruct->new({string_thing => 'Goodbye4', byte_thing => 4, i32_thing => 4, i64_thing => 4}); my @goodbyes; push(@goodbyes, $goodbye); my $crazy = ThriftTest::Insanity->new({userMap => { ThriftTest::Numberz::EIGHT => 8 }, xtructs => \@goodbyes}); my $loony = ThriftTest::Insanity->new(); my $result = { 1 => { ThriftTest::Numberz::TWO => $argument, ThriftTest::Numberz::THREE => $argument }, 2 => { ThriftTest::Numberz::SIX => $loony } }; return $result; } sub testMulti { my $self = shift; my $arg0 = shift; my $arg1 = shift; my $arg2 = shift; my $arg3 = shift; my $arg4 = shift; my $arg5 = shift; print("testMulti()\n"); return ThriftTest::Xtruct->new({string_thing => 'Hello2', byte_thing => $arg0, i32_thing => $arg1, i64_thing => $arg2}); } sub testException { my $self = shift; my $arg = shift; print("testException($arg)\n"); if ($arg eq 'Xception') { die ThriftTest::Xception->new({errorCode => 1001, message => $arg}); } elsif ($arg eq 'TException') { die 'astring'; # all unhandled exceptions become TExceptions } else { return ThriftTest::Xtruct->new({string_thing => $arg}); } } sub testMultiException { my $self = shift; my $arg0 = shift; my $arg1 = shift; printf("testMultiException(%s, %s)\n", $arg0, $arg1); if ($arg0 eq 'Xception') { die ThriftTest::Xception->new({errorCode => 1001, message => 'This is an Xception'}); } elsif ($arg0 eq 'Xception2') { my $struct_thing = ThriftTest::Xtruct->new({string_thing => 'This is an Xception2'}); die ThriftTest::Xception2->new({errorCode => 2002, struct_thing => $struct_thing}); } else { return ThriftTest::Xtruct->new({string_thing => $arg1}); } } sub testOneway { my $self = shift; my $num = shift; print("testOneway($num): received\n"); } ### ### Test server implementation ### package SecondServiceHandler; use base qw( ThriftTest::SecondServiceIf ); sub new { my $classname = shift; my $self = {}; return bless($self, $classname); } sub secondtestString { my $self = shift; my $thing = shift; print("testString($thing)\n"); return qq|testString("$thing")|; } 1; thrift-0.23.0/test/perl/Makefile0000644000175000017500000004404215170007175016744 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # test/perl/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = test/perl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/test/perl abs_srcdir = /thrift/src/test/perl abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/perl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/perl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: ../v0.16/ThriftTest.thrift $(THRIFT) --gen perl ../v0.16/ThriftTest.thrift precross: stubs check: stubs clean-local: $(RM) -r gen-perl/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) -r $(distdir)/gen-perl/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/perl/Makefile.in0000644000175000017500000004277715170007167017367 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/perl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/perl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/perl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: ../v0.16/ThriftTest.thrift $(THRIFT) --gen perl ../v0.16/ThriftTest.thrift precross: stubs check: stubs clean-local: $(RM) -r gen-perl/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) -r $(distdir)/gen-perl/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/perl/Makefile.am0000664000175000017500000000177715165535636017366 0ustar00buildbuild00000000000000# # 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. # stubs: ../v0.16/ThriftTest.thrift $(THRIFT) --gen perl ../v0.16/ThriftTest.thrift precross: stubs check: stubs clean-local: $(RM) -r gen-perl/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am dist-hook: $(RM) -r $(distdir)/gen-perl/ thrift-0.23.0/test/v0.16/0000755000175000017500000000000015170007201015076 5ustar00buildbuild00000000000000thrift-0.23.0/test/v0.16/ConstantsDemo.thrift0000664000175000017500000000404415165535636021133 0ustar00buildbuild00000000000000/* * 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 yozone namespace erl consts_ namespace haxe constantsDemo struct thing { 1: i32 hello, 2: i32 goodbye } enum enumconstants { ONE = 1, TWO = 2 } // struct thing2 { // /** standard docstring */ // 1: enumconstants val = TWO // } typedef i32 myIntType const myIntType myInt = 3 //const map GEN_ENUM_NAMES = {ONE : "HOWDY", TWO: "PARTNER"} const i32 hex_const = 0x0001F const i32 negative_hex_constant = -0x0001F const i32 GEN_ME = -3523553 const double GEn_DUB = 325.532 const double GEn_DU = 085.2355 const string GEN_STRING = "asldkjasfd" const double e10 = 1e10 // fails with 0.9.3 and earlier const double e11 = -1e10 const map GEN_MAP = { 35532 : 233, 43523 : 853 } const list GEN_LIST = [ 235235, 23598352, 3253523 ] const map> GEN_MAPMAP = { 235 : { 532 : 53255, 235:235}} const map GEN_MAP2 = { "hello" : 233, "lkj98d" : 853, 'lkjsdf' : 098325 } const thing GEN_THING = { 'hello' : 325, 'goodbye' : 325352 } const map GEN_WHAT = { 35 : { 'hello' : 325, 'goodbye' : 325352 } } const set GEN_SET = [ 235, 235, 53235 ] exception Blah { 1: i32 bing } exception Gak {} service yowza { void blingity(), i32 blangity() throws (1: Blah hoot ) } thrift-0.23.0/test/v0.16/FuzzTestNoUuid.thrift0000664000175000017500000000565315165535636021303 0ustar00buildbuild00000000000000/* * 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 fuzz namespace java org.apache.thrift.fuzz namespace py fuzz namespace swift Fuzz // Test typedefs typedef i64 UserId typedef binary BinaryData // Test all primitive types in a compact struct struct BasicTypes { 1: bool bool_field, 2: i8 byte_field, 3: i16 i16_field, 4: i32 i32_field, 5: i64 i64_field, 6: double double_field, 7: string string_field, 8: binary binary_field, } // Test optional/required/default requiredness struct Requiredness { 1: required i32 req_field, 2: optional i32 opt_field, 3: i32 default_field, // default requiredness 4: optional string opt_with_default = "test", 5: required bool req_with_default = true } // Test field ID edge cases struct FieldIDTest { 1: i32 first, 100: i32 gap, 255: i32 medium_id, 32767: i32 large_id, } // Test empty struct struct EmptyStruct {} // Test union union TestUnion { 1: i32 int_field, 2: string string_field, 3: BasicTypes struct_field, 4: binary binary_field } // Test containers (but not too deeply nested) struct Containers { 1: list int_list, 2: set string_set, 3: map int_string_map, 4: list struct_list, 5: map> nested_map, 6: set typedef_set, } // Test enum with various values enum TestEnum { ZERO = 0, ONE = 1, TWO = 2, NEGATIVE = -1, LARGE = 32767, HEX_VALUE = 0xFF } // Do not test recursive structures here, as not all languages (e.g. c_glib) support them. // struct RecursiveStruct { // 1: optional RecursiveStruct recurse, // 2: i32 data, // 3: optional list children // } // Main test structure - kept minimal but comprehensive struct FuzzTest { 1: required BasicTypes basic, 2: required Requiredness required_test, 3: required Containers containers, 4: required TestUnion union_field, // 5: optional RecursiveStruct recursive, 6: optional EmptyStruct empty, 7: optional FieldIDTest field_ids, 8: required TestEnum enum_field, 9: optional map enum_map, 10: UserId user_id, 11: BinaryData data, }thrift-0.23.0/test/v0.16/ThriftTest.thrift0000664000175000017500000002627115165535636020460 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace c_glib TTest namespace cpp thrift.test namespace delphi Thrift.Test namespace go thrifttest namespace java thrift.test namespace js ThriftTest namespace lua ThriftTest namespace netstd ThriftTest namespace perl ThriftTest namespace php ThriftTest namespace py ThriftTest namespace py.twisted ThriftTest namespace rb Thrift.Test namespace st ThriftTest namespace xsd test (uri = 'http://thrift.apache.org/ns/ThriftTest') // Presence of namespaces and sub-namespaces for which there is // no generator should compile with warnings only namespace noexist ThriftTest namespace cpp.noexist ThriftTest namespace * thrift.test /** * Docstring! */ enum Numberz { ONE = 1, TWO, THREE, FIVE = 5, SIX, EIGHT = 8 } const Numberz myNumberz = Numberz.ONE; // the following is expected to fail: // const Numberz urNumberz = ONE; typedef i64 UserId struct Bonk { 1: string message, 2: i32 type } typedef map MapType struct Bools { 1: bool im_true, 2: bool im_false, } struct Xtruct { 1: string string_thing, 4: i8 byte_thing, 9: i32 i32_thing, 11: i64 i64_thing } struct Xtruct2 { 1: i8 byte_thing, // used to be byte, hence the name 2: Xtruct struct_thing, 3: i32 i32_thing } struct Xtruct3 { 1: string string_thing, 4: i32 changed, 9: i32 i32_thing, 11: i64 i64_thing } struct Insanity { 1: map userMap, 2: list xtructs } (python.immutable= "") struct CrazyNesting { 1: string string_field, 2: optional set set_field, // Do not insert line break as test/go/Makefile.am is removing this line with pattern match 3: required list (python.immutable = ""), map(python.immutable = "")> (python.immutable = "")>>>> list_field, 4: binary binary_field } union SomeUnion { 1: map map_thing, 2: string string_thing, 3: i32 i32_thing, 4: Xtruct3 xtruct_thing, 5: Insanity insanity_thing } exception Xception { 1: i32 errorCode, 2: string message } exception Xception2 { 1: i32 errorCode, 2: Xtruct struct_thing } struct EmptyStruct {} struct OneField { 1: EmptyStruct field } service ThriftTest { /** * Prints "testVoid()" and returns nothing. */ void testVoid(), /** * Prints 'testString("%s")' with thing as '%s' * @param string thing - the string to print * @return string - returns the string 'thing' */ string testString(1: string thing), /** * Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false' * @param bool thing - the bool data to print * @return bool - returns the bool 'thing' */ bool testBool(1: bool thing), /** * Prints 'testByte("%d")' with thing as '%d' * The types i8 and byte are synonyms, use of i8 is encouraged, byte still exists for the sake of compatibility. * @param byte thing - the i8/byte to print * @return i8 - returns the i8/byte 'thing' */ i8 testByte(1: i8 thing), /** * Prints 'testI32("%d")' with thing as '%d' * @param i32 thing - the i32 to print * @return i32 - returns the i32 'thing' */ i32 testI32(1: i32 thing), /** * Prints 'testI64("%d")' with thing as '%d' * @param i64 thing - the i64 to print * @return i64 - returns the i64 'thing' */ i64 testI64(1: i64 thing), /** * Prints 'testDouble("%f")' with thing as '%f' * @param double thing - the double to print * @return double - returns the double 'thing' */ double testDouble(1: double thing), /** * Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data * @param binary thing - the binary data to print * @return binary - returns the binary 'thing' */ binary testBinary(1: binary thing), /** * Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values * @param Xtruct thing - the Xtruct to print * @return Xtruct - returns the Xtruct 'thing' */ Xtruct testStruct(1: Xtruct thing), /** * Prints 'testNest("{%s}")' where thing has been formatted into a string of the nested struct * @param Xtruct2 thing - the Xtruct2 to print * @return Xtruct2 - returns the Xtruct2 'thing' */ Xtruct2 testNest(1: Xtruct2 thing), /** * Prints 'testMap("{%s")' where thing has been formatted into a string of 'key => value' pairs * separated by commas and new lines * @param map thing - the map to print * @return map - returns the map 'thing' */ map testMap(1: map thing), /** * Prints 'testStringMap("{%s}")' where thing has been formatted into a string of 'key => value' pairs * separated by commas and new lines * @param map thing - the map to print * @return map - returns the map 'thing' */ map testStringMap(1: map thing), /** * Prints 'testSet("{%s}")' where thing has been formatted into a string of values * separated by commas and new lines * @param set thing - the set to print * @return set - returns the set 'thing' */ set testSet(1: set thing), /** * Prints 'testList("{%s}")' where thing has been formatted into a string of values * separated by commas and new lines * @param list thing - the list to print * @return list - returns the list 'thing' */ list testList(1: list thing), /** * Prints 'testEnum("%d")' where thing has been formatted into its numeric value * @param Numberz thing - the Numberz to print * @return Numberz - returns the Numberz 'thing' */ Numberz testEnum(1: Numberz thing), /** * Prints 'testTypedef("%d")' with thing as '%d' * @param UserId thing - the UserId to print * @return UserId - returns the UserId 'thing' */ UserId testTypedef(1: UserId thing), /** * Prints 'testMapMap("%d")' with hello as '%d' * @param i32 hello - the i32 to print * @return map> - returns a dictionary with these values: * {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, } */ map> testMapMap(1: i32 hello), /** * So you think you've got this all worked out, eh? * * Creates a map with these values and prints it out: * { 1 => { 2 => argument, * 3 => argument, * }, * 2 => { 6 => , }, * } * @return map> - a map with the above values */ map> testInsanity(1: Insanity argument), /** * Prints 'testMulti()' * @param i8 arg0 - * @param i32 arg1 - * @param i64 arg2 - * @param map arg3 - * @param Numberz arg4 - * @param UserId arg5 - * @return Xtruct - returns an Xtruct with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1 * and i64_thing = arg2 */ Xtruct testMulti(1: i8 arg0, 2: i32 arg1, 3: i64 arg2, 4: map arg3, 5: Numberz arg4, 6: UserId arg5), /** * Print 'testException(%s)' with arg as '%s' * @param string arg - a string indication what type of exception to throw * if arg == "Xception" throw Xception with errorCode = 1001 and message = arg * else if arg == "TException" throw TException * else do not throw anything */ void testException(1: string arg) throws(1: Xception err1), /** * Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s' * @param string arg - a string indicating what type of exception to throw * if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception" * else if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and struct_thing.string_thing = "This is an Xception2" * else do not throw anything * @return Xtruct - an Xtruct with string_thing = arg1 */ Xtruct testMultiException(1: string arg0, 2: string arg1) throws(1: Xception err1, 2: Xception2 err2) /** * Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d' * sleep 'secondsToSleep' * Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d' * @param i32 secondsToSleep - the number of seconds to sleep */ oneway void testOneway(1:i32 secondsToSleep) } service SecondService { /** * Prints 'testString("%s")' with thing as '%s' * @param string thing - the string to print * @return string - returns the string 'thing' */ string secondtestString(1: string thing) } struct VersioningTestV1 { 1: i32 begin_in_both, 3: string old_string, 12: i32 end_in_both } struct VersioningTestV2 { 1: i32 begin_in_both, 2: i32 newint, 3: i8 newbyte, 4: i16 newshort, 5: i64 newlong, 6: double newdouble 7: Bonk newstruct, 8: list newlist, 9: set newset, 10: map newmap, 11: string newstring, 12: i32 end_in_both } struct ListTypeVersioningV1 { 1: list myints; 2: string hello; } struct ListTypeVersioningV2 { 1: list strings; 2: string hello; } struct GuessProtocolStruct { 7: map map_field, } struct LargeDeltas { 1: Bools b1, 10: Bools b10, 100: Bools b100, 500: bool check_true, 1000: Bools b1000, 1500: bool check_false, 2000: VersioningTestV2 vertwo2000, 2500: set a_set2500, 3000: VersioningTestV2 vertwo3000, 4000: list big_numbers } struct NestedListsI32x2 { 1: list> integerlist } struct NestedListsI32x3 { 1: list>> integerlist } struct NestedMixedx2 { 1: list> int_set_list 2: map> map_int_strset 3: list>> map_int_strset_list } struct ListBonks { 1: list bonk } struct NestedListsBonk { 1: list>> bonk } struct BoolTest { 1: optional bool b = true; 2: optional string s = "true"; } struct StructA { 1: required string s; } struct StructB { 1: optional StructA aa; 2: required StructA ab; } struct OptionalSetDefaultTest { 1: optional set with_default = [ "test" ] } struct OptionalBinary { 1: optional set bin_set = {} 2: optional map bin_map = {} } thrift-0.23.0/test/v0.16/NameConflictTest.thrift0000664000175000017500000000540615165535636021557 0ustar00buildbuild00000000000000/* * 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. */ // Naming testcases, sepcifically for these tickets (but not limited to them) // THRIFT-2508 Uncompileable C# code due to language keywords in IDL // THRIFT-2557 error CS0542 member names cannot be the same as their enclosing type struct using { 1: double single 2: double integer } struct delegate { 1: string partial 2: delegate delegate } struct get { 1: bool sbyte } struct partial { 1: using using 2: bool read 3: bool write } enum Maybe { JUST = 1, TRUE = 2, FALSE = 3 } enum Either { LEFT = 1, RIGHT = 2 } struct foldr { 1: string id } struct of { 1: string let 2: string where } struct ofOf { 1: of Of } struct ClassAndProp { 1: bool ClassAndProp 2: bool ClassAndProp_ 3: bool ClassAndProp__ 4: bool ClassAndProper } struct second_chance { 1: bool SECOND_CHANCE 2: bool SECOND_CHANCE_ 3: bool SECOND_CHANCE__ 4: bool SECOND_CHANCES } struct NOW_EAT_THIS { 1: bool now_eat_this 2: bool now_eat_this_ 3: bool now_eat_this__ 4: bool now_eat_this_and_this } struct TheEdgeCase { 1: bool theEdgeCase 2: bool theEdgeCase_ 3: bool theEdgeCase__ 4: bool TheEdgeCase 5: bool TheEdgeCase_ 6: bool TheEdgeCase__ } struct Tricky_ { 1: bool tricky 2: bool Tricky } struct Nested { 1: ClassAndProp ClassAndProp 2: second_chance second_chance 3: NOW_EAT_THIS NOW_EAT_THIS 4: TheEdgeCase TheEdgeCase 5: Tricky_ Tricky_ 6: Nested Nested } exception Problem_ { 1: bool problem 2: bool Problem } struct Thrift5626 { 1: i8 i8 2: i16 i16 3: i32 i32 4: i64 i64 //5: uuid uuid 6: string string 7: binary binary 8: bool bool 9: byte byte 10: list list 11: set set 12: map map } service extern { delegate event(1: partial get) void Foo(1: Nested Foo_args) throws (1: Problem_ Foo_result) } service qualified { Maybe maybe(1: Maybe foldr) Either either(1: foldr of) } // eof thrift-0.23.0/test/v0.16/DebugProtoTest.thrift0000664000175000017500000002413115167543515021260 0ustar00buildbuild00000000000000/* * 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 c_glib TTest namespace cpp thrift.test.debug namespace java thrift.test namespace rb Thrift.Test struct Doubles { 1: double nan, 2: double inf, 3: double neginf, 4: double repeating, 5: double big, 6: double tiny, 7: double zero, 8: double negzero, } struct OneOfEach { 1: bool im_true, 2: bool im_false, 3: i8 a_bite = 0x7f, 4: i16 integer16 = 0x7fff, 5: i32 integer32, 6: i64 integer64 = 10000000000, 7: double double_precision, 8: string some_characters, 9: string zomg_unicode, 10: bool what_who, 11: binary base64, 12: list byte_list = [1, 2, 3], 13: list i16_list = [1,2,3], 14: list i64_list = [1,2,3] } struct Bonk { 1: i32 type, 2: string message, } struct Nesting { 1: Bonk my_bonk, 2: OneOfEach my_ooe, } struct HolyMoley { 1: list big, 2: set (python.immutable = "")> contain, 3: map> bonks, } struct Backwards { 2: i32 first_tag2, 1: i32 second_tag1, } struct Empty { } ( python.immutable = "", ) struct Wrapper { 1: Empty foo } ( python.immutable = "", ) struct RandomStuff { 1: i32 a, 2: i32 b, 3: i32 c, 4: i32 d, 5: list myintlist, 6: map maps, 7: i64 bigint, 8: double triple, } struct Base64 { 1: i32 a, 2: binary b1, 3: binary b2, 4: binary b3, 5: binary b4, 6: binary b5, 7: binary b6, } struct CompactProtoTestStruct { // primitive fields 1: i8 a_byte; 2: i16 a_i16; 3: i32 a_i32; 4: i64 a_i64; 5: double a_double; 6: string a_string; 7: binary a_binary; 8: bool true_field; 9: bool false_field; 10: Empty empty_struct_field; // primitives in lists 11: list byte_list; 12: list i16_list; 13: list i32_list; 14: list i64_list; 15: list double_list; 16: list string_list; 17: list binary_list; 18: list boolean_list; 19: list struct_list; // primitives in sets 20: set byte_set; 21: set i16_set; 22: set i32_set; 23: set i64_set; 24: set double_set; 25: set string_set; 26: set binary_set; 27: set boolean_set; 28: set struct_set; // maps // primitives as keys 29: map byte_byte_map; 30: map i16_byte_map; 31: map i32_byte_map; 32: map i64_byte_map; 33: map double_byte_map; 34: map string_byte_map; 35: map binary_byte_map; 36: map boolean_byte_map; // primitives as values 37: map byte_i16_map; 38: map byte_i32_map; 39: map byte_i64_map; 40: map byte_double_map; 41: map byte_string_map; 42: map byte_binary_map; 43: map byte_boolean_map; // collections as keys 44: map (python.immutable = ""), i8> list_byte_map; 45: map (python.immutable = ""), i8> set_byte_map; 46: map (python.immutable = ""), i8> map_byte_map; // collections as values 47: map> byte_map_map; 48: map> byte_set_map; 49: map> byte_list_map; // large field IDs 500 : i64 field500; 5000 : i64 field5000; 20000 : i64 field20000; } // To be used to test the serialization of an empty map struct SingleMapTestStruct { 1: required map i32_map; } const CompactProtoTestStruct COMPACT_TEST = { 'a_byte' : 127, 'a_i16' : 32000, 'a_i32' : 1000000000, 'a_i64' : 0xffffffffff, 'a_double' : 5.6789, 'a_string' : "my string", //'a_binary,' 'true_field' : 1, 'false_field' : 0, 'empty_struct_field' : {}, 'byte_list' : [-127, -1, 0, 1, 127], 'i16_list' : [-1, 0, 1, 0x7fff], 'i32_list' : [-1, 0, 0xff, 0xffff, 0xffffff, 0x7fffffff], 'i64_list' : [-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff], 'double_list' : [0.1, 0.2, 0.3], 'string_list' : ["first", "second", "third"], //'binary_list,' 'boolean_list' : [1, 1, 1, 0, 0, 0], 'struct_list' : [{}, {}], 'byte_set' : [-127, -1, 0, 1, 127], 'i16_set' : [-1, 0, 1, 0x7fff], 'i32_set' : [1, 2, 3], 'i64_set' : [-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff], 'double_set' : [0.1, 0.2, 0.3], 'string_set' : ["first", "second", "third"], //'binary_set,' 'boolean_set' : [1, 0], 'struct_set' : [{}], 'byte_byte_map' : {1 : 2}, 'i16_byte_map' : {1 : 1, -1 : 1, 0x7fff : 1}, 'i32_byte_map' : {1 : 1, -1 : 1, 0x7fffffff : 1}, 'i64_byte_map' : {0 : 1, 1 : 1, -1 : 1, 0x7fffffffffffffff : 1}, 'double_byte_map' : {-1.1 : 1, 1.1 : 1}, 'string_byte_map' : {"first" : 1, "second" : 2, "third" : 3, "" : 0}, //'binary_byte_map,' 'boolean_byte_map' : {1 : 1, 0 : 0}, 'byte_i16_map' : {1 : 1, 2 : -1, 3 : 0x7fff}, 'byte_i32_map' : {1 : 1, 2 : -1, 3 : 0x7fffffff}, 'byte_i64_map' : {1 : 1, 2 : -1, 3 : 0x7fffffffffffffff}, 'byte_double_map' : {1 : 0.1, 2 : -0.1, 3 : 1000000.1}, 'byte_string_map' : {1 : "", 2 : "blah", 3 : "loooooooooooooong string"}, //'byte_binary_map,' 'byte_boolean_map' : {1 : 1, 2 : 0}, 'list_byte_map' : {[1, 2, 3] : 1, [0, 1] : 2, [] : 0}, 'set_byte_map' : {[1, 2, 3] : 1, [0, 1] : 2, [] : 0}, 'map_byte_map' : {{1 : 1} : 1, {2 : 2} : 2, {} : 0}, 'byte_map_map' : {0 : {}, 1 : {1 : 1}, 2 : {1 : 1, 2 : 2}}, 'byte_set_map' : {0 : [], 1 : [1], 2 : [1, 2]}, 'byte_list_map' : {0 : [], 1 : [1], 2 : [1, 2]}, 'field500' : 500, 'field5000' : 5000, 'field20000' : 20000, } const i32 MYCONST = 2 exception ExceptionWithAMap { 1: string blah; 2: map map_field; } exception MutableException { 1: string msg; } (python.immutable = "false") exception ExceptionWithoutFields {} service ServiceForExceptionWithAMap { void methodThatThrowsAnException() throws (1: ExceptionWithAMap xwamap); } service Srv { i32 Janky(1: i32 arg); // return type only methods void voidMethod(); i32 primitiveMethod(); CompactProtoTestStruct structMethod(); void methodWithDefaultArgs(1: i32 something = MYCONST); oneway void onewayMethod(); bool declaredExceptionMethod(1: bool shouldThrow) throws (1: ExceptionWithAMap xwamap); } service Inherited extends Srv { i32 identity(1: i32 arg) } service EmptyService {} // The only purpose of this thing is to increase the size of the generated code // so that ZlibTest has more highly compressible data to play with. struct BlowUp { 1: map(python.immutable = ""),set (python.immutable = "")>> b1; 2: map(python.immutable = ""),set (python.immutable = "")>> b2; 3: map(python.immutable = ""),set (python.immutable = "")>> b3; 4: map(python.immutable = ""),set (python.immutable = "")>> b4; } struct ReverseOrderStruct { 4: string first; 3: i16 second; 2: i32 third; 1: i64 fourth; } service ReverseOrderService { void myMethod(4: string first, 3: i16 second, 2: i32 third, 1: i64 fourth); } enum SomeEnum { ONE = 1 TWO = 2 } /** This is a docstring on a constant! */ const SomeEnum MY_SOME_ENUM = SomeEnum.ONE const SomeEnum MY_SOME_ENUM_1 = 1 /*const SomeEnum MY_SOME_ENUM_2 = 7*/ const map MY_ENUM_MAP = { SomeEnum.ONE : SomeEnum.TWO } struct StructWithSomeEnum { 1: SomeEnum blah; } const map EXTRA_CRAZY_MAP = { SomeEnum.ONE : {"blah" : SomeEnum.TWO} } union TestUnion { /** * A doc string */ 1: string string_field; 2: i32 i32_field; 3: OneOfEach struct_field; 4: list struct_list; 5: i32 other_i32_field; 6: SomeEnum enum_field; 7: set i32_set; 8: map i32_map; } union TestUnionMinusStringField { 2: i32 i32_field; 3: OneOfEach struct_field; 4: list struct_list; 5: i32 other_i32_field; 6: SomeEnum enum_field; 7: set i32_set; 8: map i32_map; } union ComparableUnion { 1: string string_field; 2: binary binary_field; } struct StructWithAUnion { 1: TestUnion test_union; } struct PrimitiveThenStruct { 1: i32 blah; 2: i32 blah2; 3: Backwards bw; } typedef map SomeMap struct StructWithASomemap { 1: required SomeMap somemap_field; } struct BigFieldIdStruct { 1: string field1; 45: string field2; } struct BreaksRubyCompactProtocol { 1: string field1; 2: BigFieldIdStruct field2; 3: i32 field3; } struct TupleProtocolTestStruct { optional i32 field1; optional i32 field2; optional i32 field3; optional i32 field4; optional i32 field5; optional i32 field6; optional i32 field7; optional i32 field8; optional i32 field9; optional i32 field10; optional i32 field11; optional i32 field12; } struct ListDoublePerf { 1: list field; } thrift-0.23.0/test/lua/0000775000175000017500000000000015170007175015121 5ustar00buildbuild00000000000000thrift-0.23.0/test/lua/test_basic_client.lua0000664000175000017500000001401715165535636021321 0ustar00buildbuild00000000000000-- 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. require('TSocket') require('TBufferedTransport') require('TFramedTransport') require('THttpTransport') require('TCompactProtocol') require('TJsonProtocol') require('TBinaryProtocol') require('ThriftTest_ThriftTest') local liblualongnumber = require('liblualongnumber') local client function teardown() if client then -- close the connection client:close() end end function parseArgs(rawArgs) local opt = { protocol='binary', transport='buffered', port='9090', } for i, str in pairs(rawArgs) do if i > 0 then k, v = string.match(str, '--(%w+)=(%w+)') assert(opt[k] ~= nil, 'Unknown argument') opt[k] = v end end return opt end function assertEqual(val1, val2, msg) assert(val1 == val2, msg) end function testBasicClient(rawArgs) local opt = parseArgs(rawArgs) local socket = TSocket:new{ port = tonumber(opt.port) } assert(socket, 'Failed to create client socket') socket:setTimeout(5000) local transports = { buffered = TBufferedTransport, framed = TFramedTransport, http = THttpTransport, } assert(transports[opt.transport] ~= nil) local transport = transports[opt.transport]:new{ trans = socket, isServer = false } local protocols = { binary = TBinaryProtocol, compact = TCompactProtocol, json = TJSONProtocol, } assert(protocols[opt.protocol] ~= nil) local protocol = protocols[opt.protocol]:new{ trans = transport } assert(protocol, 'Failed to create binary protocol') client = ThriftTestClient:new{ protocol = protocol } assert(client, 'Failed to create client') -- Open the transport local status, _ = pcall(transport.open, transport) assert(status, 'Failed to connect to server') -- String 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') -- Byte assertEqual(client:testByte(0x01), 1, 'Failed testByte 1') assertEqual(client:testByte(0x40), 64, 'Failed testByte 2') assertEqual(client:testByte(0x7f), 127, 'Failed testByte 3') assertEqual(client:testByte(0x80), -128, 'Failed testByte 4') assertEqual(client:testByte(0xbf), -65, 'Failed testByte 5') assertEqual(client:testByte(0xff), -1, 'Failed testByte 6') assertEqual(client:testByte(128), -128, 'Failed testByte 7') assertEqual(client:testByte(255), -1, 'Failed testByte 8') -- I32 assertEqual(client:testI32(0x00000001), 1, 'Failed testI32 1') assertEqual(client:testI32(0x40000000), 1073741824, 'Failed testI32 2') assertEqual(client:testI32(0x7fffffff), 2147483647, 'Failed testI32 3') assertEqual(client:testI32(0x80000000), -2147483648, 'Failed testI32 4') assertEqual(client:testI32(0xbfffffff), -1073741825, 'Failed testI32 5') assertEqual(client:testI32(0xffffffff), -1, 'Failed testI32 6') assertEqual(client:testI32(2147483648), -2147483648, 'Failed testI32 7') assertEqual(client:testI32(4294967295), -1, 'Failed testI32 8') -- I64 (lua only supports 16 decimal precision so larger numbers are -- initialized by their string value) local long = liblualongnumber.new assertEqual(client:testI64(long(0x0000000000000001)), long(1), 'Failed testI64 1') assertEqual(client:testI64(long(0x4000000000000000)), long(4611686018427387904), 'Failed testI64 2') assertEqual(client:testI64(long('0x7fffffffffffffff')), long('9223372036854775807'), 'Failed testI64 3') assertEqual(client:testI64(long(0x8000000000000000)), long(-9223372036854775808), 'Failed testI64 4') assertEqual(client:testI64(long('0xbfffffffffffffff')), long('-4611686018427387905'), 'Failed testI64 5') assertEqual(client:testI64(long('0xffffffffffffffff')), long(-1), 'Failed testI64 6') -- Double assertEqual( client:testDouble(1.23456789), 1.23456789, 'Failed testDouble 1') assertEqual( client:testDouble(0.123456789), 0.123456789, 'Failed testDouble 2') assertEqual( client:testDouble(0.123456789), 0.123456789, 'Failed testDouble 3') -- TODO testBinary() ... -- Accuracy of 16 decimal digits (rounds) local a, b = 1.12345678906666663, 1.12345678906666661 assertEqual(a, b) assertEqual(client:testDouble(a), b, 'Failed testDouble 5') -- Struct local o = Xtruct:new{ string_thing = 'Zero', byte_thing = 1, i32_thing = -3, i64_thing = long(-5) } local r = client:testStruct(o) assertEqual(o.string_thing, r.string_thing, 'Failed testStruct 1') assertEqual(o.byte_thing, r.byte_thing, 'Failed testStruct 2') assertEqual(o.i32_thing, r.i32_thing, 'Failed testStruct 3') assertEqual(o.i64_thing, r.i64_thing, 'Failed testStruct 4') -- oneway client:testOneway(3) -- TODO add list map set exception etc etc end testBasicClient(arg) teardown() thrift-0.23.0/test/lua/test_basic_server.lua0000664000175000017500000001244715165535636021356 0ustar00buildbuild00000000000000-- 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. require('ThriftTest_ThriftTest') require('TSocket') require('TBufferedTransport') require('TFramedTransport') require('THttpTransport') require('TCompactProtocol') require('TJsonProtocol') require('TBinaryProtocol') require('TServer') local liblualongnumber = require('liblualongnumber') -------------------------------------------------------------------------------- -- Handler TestHandler = ThriftTestIface:new{} -- Stops the server function TestHandler:testVoid() end function TestHandler:testString(str) return str end function TestHandler:testBool(bool) return bool end function TestHandler:testByte(byte) return byte end function TestHandler:testI32(i32) return i32 end function TestHandler:testI64(i64) return i64 end function TestHandler:testDouble(d) return d end 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 -------------------------------------------------------------------------------- -- Test local server function teardown() if server then server:close() end end function parseArgs(rawArgs) local opt = { protocol='binary', transport='buffered', port='9090', } for i, str in pairs(rawArgs) do if i > 0 then k, v = string.match(str, '--(%w+)=(%w+)') assert(opt[k] ~= nil, 'Unknown argument') opt[k] = v end end return opt end function testBasicServer(rawArgs) local opt = parseArgs(rawArgs) -- Handler & Processor local handler = TestHandler:new{} assert(handler, 'Failed to create handler') local processor = ThriftTestProcessor:new{ handler = handler } assert(processor, 'Failed to create processor') -- Server Socket local socket = TServerSocket:new{ port = opt.port } assert(socket, 'Failed to create server socket') -- Transport & Factory local transports = { buffered = TBufferedTransportFactory, framed = TFramedTransportFactory, http = THttpTransportFactory, } assert(transports[opt.transport], 'Failed to create framed transport factory') local trans_factory = transports[opt.transport]:new{} local protocols = { binary = TBinaryProtocolFactory, compact = TCompactProtocolFactory, json = TJSONProtocolFactory, } local prot_factory = protocols[opt.protocol]:new{} assert(prot_factory, 'Failed to create binary protocol factory') -- Simple Server server = TSimpleServer:new{ processor = processor, serverTransport = socket, transportFactory = trans_factory, protocolFactory = prot_factory } assert(server, 'Failed to create server') server:setExceptionHandler(function (err) error(err) end) -- Serve server:serve() server = nil end testBasicServer(arg) teardown() thrift-0.23.0/test/lua/Makefile0000644000175000017500000004400315170007175016560 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # test/lua/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = test/lua ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/test/lua abs_srcdir = /thrift/src/test/lua abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/lua/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/lua/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile 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/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/lua/Makefile.in0000644000175000017500000004277215170007167017201 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/lua ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/lua/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/lua/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile 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/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/lua/Makefile.am0000664000175000017500000000202015165535636017163 0ustar00buildbuild00000000000000# # 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. # THRIFT = $(top_builddir)/compiler/cpp/thrift 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/ thrift-0.23.0/test/SpecificNameTest.thrift0000664000175000017500000000176615165535636020776 0ustar00buildbuild00000000000000/* * 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 test.specificname struct a { 1: i32 number, 2: string message, } struct b { 1: i32 number, 2: string message, } service EchoService { void echoA(1: a arg), void echoB(2: b arg), } thrift-0.23.0/test/result.js0000664000175000017500000000451215165535636016232 0ustar00buildbuild00000000000000/* 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. */ $.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"; }); }); thrift-0.23.0/test/DenseLinkingTest.thrift0000664000175000017500000000443615165535636021017 0ustar00buildbuild00000000000000/* * 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. */ /* ../compiler/cpp/thrift -gen cpp:dense DebugProtoTest.thrift ../compiler/cpp/thrift -gen cpp:dense DenseLinkingTest.thrift g++ -Wall -g -I../lib/cpp/src -I/usr/local/include/boost-1_33_1 \ DebugProtoTest.cpp gen-cpp/DebugProtoTest_types.cpp \ gen-cpp/DenseLinkingTest_types.cpp \ ../lib/cpp/.libs/libthrift.a -o DebugProtoTest ./DebugProtoTest */ /* The idea of this test is that everything is structurally identical to DebugProtoTest. If I messed up the naming of the reflection local typespecs, then compiling this should give errors because of doubly defined symbols. */ namespace cpp thrift.test namespace java thrift.test struct OneOfEachZZ { 1: bool im_true, 2: bool im_false, 3: byte a_bite, 4: i16 integer16, 5: i32 integer32, 6: i64 integer64, 7: double double_precision, 8: string some_characters, 9: string zomg_unicode, 10: bool what_who, } struct BonkZZ { 1: i32 type, 2: string message, } struct NestingZZ { 1: BonkZZ my_bonk, 2: OneOfEachZZ my_ooe, } struct HolyMoleyZZ { 1: list big, 2: set> contain, 3: map> bonks, } struct BackwardsZZ { 2: i32 first_tag2, 1: i32 second_tag1, } struct EmptyZZ { } struct WrapperZZ { 1: EmptyZZ foo } struct RandomStuffZZ { 1: i32 a, 2: i32 b, 3: i32 c, 4: i32 d, 5: list myintlist, 6: map maps, 7: i64 bigint, 8: double triple, } service Srv { i32 Janky(1: i32 arg) } service UnderscoreSrv { i64 some_rpc_call(1: string message) } thrift-0.23.0/test/keys/0000775000175000017500000000000015165535636015327 5ustar00buildbuild00000000000000thrift-0.23.0/test/keys/client.pem0000664000175000017500000001003515165535636017307 0ustar00buildbuild00000000000000Bag Attributes localKeyID: 16 42 EA 1B 7C AC BD 29 96 5A A8 B6 3C AB 85 E3 7D 12 C3 D4 subject=CN = localhost, emailAddress = dev@thrift.apache.org, OU = Apache Thrift, O = The Apache Software Foundation, L = Forest Hill, ST = Maryland, C = US issuer=CN = localhost, emailAddress = dev@thrift.apache.org, OU = Apache Thrift, O = The Apache Software Foundation, L = Forest Hill, ST = Maryland, C = US -----BEGIN CERTIFICATE----- MIIE2DCCAsACAQEwDQYJKoZIhvcNAQELBQAwgbExEjAQBgNVBAMMCWxvY2FsaG9z dDEkMCIGCSqGSIb3DQEJARYVZGV2QHRocmlmdC5hcGFjaGUub3JnMRYwFAYDVQQL DA1BcGFjaGUgVGhyaWZ0MScwJQYDVQQKDB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZv dW5kYXRpb24xFDASBgNVBAcMC0ZvcmVzdCBIaWxsMREwDwYDVQQIDAhNYXJ5bGFu ZDELMAkGA1UEBhMCVVMwHhcNMjIwNjMwMjIzNzMxWhcNMzAwOTE2MjIzNzMxWjCB sTESMBAGA1UEAwwJbG9jYWxob3N0MSQwIgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0 LmFwYWNoZS5vcmcxFjAUBgNVBAsMDUFwYWNoZSBUaHJpZnQxJzAlBgNVBAoMHlRo ZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbjEUMBIGA1UEBwwLRm9yZXN0IEhp bGwxETAPBgNVBAgMCE1hcnlsYW5kMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAMkGl9ZGVq/mTrcojrq7eqZTww1gmgOPNWN1QNzv i+cPI8Egbik04n/AFWvgtnvKKnKQfOLkBHJHyTdXmPqvdU9w8Zd9dvXk75mBvbtx yse6UZCxZnXrqv5YfMGb2BEvcsL5I5s6d3gL4eNObYzFD7vUjAbpamUSE7NOeMn7 qO0rPIcODDXL+Okr9/TBcO/XvRSUK0exsX03FC07gtTddV9lEYCkJvQMCCQmFdQ5 al7Vz4iLleG5hsCwz/W5zHcsqVtzm8CEQzr00AoR8Ar/WkGh1ibmissi5Bo2DcvR Ko3pvDVOAY+gj9Ypxe2z7MImn1T7ZVdr0JXUu9jmMgKMQz8CAwEAATANBgkqhkiG 9w0BAQsFAAOCAgEAH3QwBNbb2IP+ozcM5w4WppG7W/ha0WUcEKgf8Ay7w4/+X79Y Z7mxltoCz5Bc54EMXDaoTg5PbwPSmTNDqoFSRf07Fhp8IG5n19CvrTCMFcM8BbDx g5CZ6W1WoHpCW6/zNlflsSVFbGSrkwzmpgnn3+EJcVWzMDcQXufpkefbH2x7bHC/ 0JsfEYh5iPyJeDWx0CyiyoqfRx08cDuB/OLZgq63dkDNnd4zqDTT8zLT6zMTq1Ka pApb+5o0rapgHQP5+O3QAZrfnWLYXOPk17yQTekvwVpiSzwdPlOija5X+BLrLyNu EEYlR7Vz2qj/DAUN9vhCIdF4Bk8Yfk9txH5oJUmC0c2bfUkrCJgfbyK1GL00BkON aso8whDf8LF5BAl/ooofzvZXt+bw4Sp+LuX+OAcJUlqeK7IUdHQqnhhw5FOfenVO Z7MkMt2qtm3BlPzMWlZoeLNrkx4BzsBElFJ0Ds37uLk+LIg3whg+MYMFJPwXqUhs 6Ss76/cu/AhoHoX8k5wT5eNpzyWL8hNyDSosGDAgejjYFBXMlNzFYvG5zVE0EP7C i78cIdgSARKocOOeFpA3GEJL+ISi0g1ut8A1/kxgFp5dxGjfOAGHeDeaVWhWuhjz m7CjPwlfAvIBJJlC96MhPakY6tbyA0hW0/GiOfaoanJvVdWJF7lEdKle1Zs= -----END CERTIFICATE----- Bag Attributes localKeyID: 16 42 EA 1B 7C AC BD 29 96 5A A8 B6 3C AB 85 E3 7D 12 C3 D4 Key Attributes: -----BEGIN ENCRYPTED PRIVATE KEY----- MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIXssR4DibuUICAggA MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECG0hY3ghCtwkBIIEyLAZKLA15mz3 ig2qipY2rD8xMs5/kP0bixjxwzpWsTAjkUTZq6UYWgQxE2CnAAysCUveftySMg5A Fs0gvi6pTh7yGheqpJf7+tEjs7qhaIHdT39gS6d9A2+rAye0/FybW/3zGInQVQmb 47SF9lq93gevzR3nBFF6RWSeX3jCwhp6HpbuI0nt1XeJbmEW8ol+RqFHuzclj6UL jXIgNBayW89HfSzIRCUDTlG9MTPIE+rdx5FyRVFgw5Z1lYJbm5rBEY7tQU6Ut7Kt Is4KRTs5hAQkfe0K0i0hZn7Don5Go4EIBQQ4IZIaOm0F3SWpe9AuZi3NtwiBOTsn ObKTZGI7v+j6IVwVRSTy61u1EiRvNzUBnoItuOZXbCMe/1VdqET1Gc909rSdkeYg dEQ3XmGN09+0OKEcspEdtRC22T44LATm5RHiA3wkIqc7hI9IZ4tD0P5OzOrWkMLC GXUmkWUodzLwQAASwUNrez4LVI4fA4mZNTdT0Kgo9H/xRq95I32E6pkP5GX+IklA f7Yj5pfQHeL2ZygerApgaNwTvUhT+GyD6Ukd7eB21r599bn+FsTIYqkbBvE+Nle4 ZQfZ31lzUxkfkxfXMSbFufupAe6McfU3RdbPZL/4YEW/ukn96olThgJADSmtjxZI +5EifMdjmZlPsd6xmcSFIe0GgqYegpprj7niT0HUKH+1+1T7EmwSXaN18vDFtNlz sVmM6ElSvdRR0VKlzGQ5E9JkeHN5ELqtZGPG0OeblCfu40t84t5N+Fyi2Ykdp7Yx 6AkBGuXNVnfCFPRgumtFTtUdSc/BdEWLnvE3spfolYpIfOsrw3bMjlr9sm5JpCfX zZxlxjiSXjNrIIaG7VFUdBXsT1ctL/Oa6JbIzCW7nnPTfCHmlqsOczpF6pXP+gPR tFy2nlk6dNPPyiEhiOdv8c9YlwmRi477bnz++jYJATFNbrtLQdN/jN3Txu6gDEcH +xvgibcVA7LG8U9T/olOqHdboOIcvOnHdBeOPZVmBQi+4+FPet42fzeP7d+wARED Wou/+EXCqMDW8bhukkac7/1CBZmvnC3mlNtmjAEbi5NT0vPP0sv5ff5zr9KJZnFD 1ltO/Qk5GPuxm/2jW05WrUWv6Po0k25rlAKGnT54VoA+6Sl2288NgeZ9ZPC5WByU BF68xMiyeiAyrkRg8sV7raxF6GX3pK+iNcgh63TI8Mko22tHyXsVB3z7mfNnpM+W aSiHrXKQkX9vxjLj4GxkMTfVT9zZfMOMKkKS3EYVVulixJ7NYafw+nGv2018CZiA FeTb0dBh1ATMhoxwpb5kdmzAjnf67wQejQhrI0mBPhn2gmO2ilQdRWydG6sXEi0s dsBXyfSSE3pdC9MD7j98tG/KeXErjWlyfx3FP5YCTbhUKqzd8grwwtBp3Vb1iP8X t9N2YaQq5djme+afg2A2iDahSgXCNuB0RV+roqq0Rroehgytt7QSMkva+AenX6t8 lJrAivnHAz7464eD8vzRPRUfxwgX7A1zyE0wV3n45NN9Fv0rrVTo1vaAeakurGWw H5vqFcd2WVN/iKMzQ6S1IUDxUneoyf9qmgsGu4XxAtsOe2myaHaPylwS7fujQaz9 bk0ymLXuco7mflouywgROQ== -----END ENCRYPTED PRIVATE KEY----- thrift-0.23.0/test/keys/client.crt0000664000175000017500000000331415165535636017320 0ustar00buildbuild00000000000000-----BEGIN CERTIFICATE----- MIIE2DCCAsACAQEwDQYJKoZIhvcNAQELBQAwgbExEjAQBgNVBAMMCWxvY2FsaG9z dDEkMCIGCSqGSIb3DQEJARYVZGV2QHRocmlmdC5hcGFjaGUub3JnMRYwFAYDVQQL DA1BcGFjaGUgVGhyaWZ0MScwJQYDVQQKDB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZv dW5kYXRpb24xFDASBgNVBAcMC0ZvcmVzdCBIaWxsMREwDwYDVQQIDAhNYXJ5bGFu ZDELMAkGA1UEBhMCVVMwHhcNMjIwNjMwMjIzNzMxWhcNMzAwOTE2MjIzNzMxWjCB sTESMBAGA1UEAwwJbG9jYWxob3N0MSQwIgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0 LmFwYWNoZS5vcmcxFjAUBgNVBAsMDUFwYWNoZSBUaHJpZnQxJzAlBgNVBAoMHlRo ZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbjEUMBIGA1UEBwwLRm9yZXN0IEhp bGwxETAPBgNVBAgMCE1hcnlsYW5kMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAMkGl9ZGVq/mTrcojrq7eqZTww1gmgOPNWN1QNzv i+cPI8Egbik04n/AFWvgtnvKKnKQfOLkBHJHyTdXmPqvdU9w8Zd9dvXk75mBvbtx yse6UZCxZnXrqv5YfMGb2BEvcsL5I5s6d3gL4eNObYzFD7vUjAbpamUSE7NOeMn7 qO0rPIcODDXL+Okr9/TBcO/XvRSUK0exsX03FC07gtTddV9lEYCkJvQMCCQmFdQ5 al7Vz4iLleG5hsCwz/W5zHcsqVtzm8CEQzr00AoR8Ar/WkGh1ibmissi5Bo2DcvR Ko3pvDVOAY+gj9Ypxe2z7MImn1T7ZVdr0JXUu9jmMgKMQz8CAwEAATANBgkqhkiG 9w0BAQsFAAOCAgEAH3QwBNbb2IP+ozcM5w4WppG7W/ha0WUcEKgf8Ay7w4/+X79Y Z7mxltoCz5Bc54EMXDaoTg5PbwPSmTNDqoFSRf07Fhp8IG5n19CvrTCMFcM8BbDx g5CZ6W1WoHpCW6/zNlflsSVFbGSrkwzmpgnn3+EJcVWzMDcQXufpkefbH2x7bHC/ 0JsfEYh5iPyJeDWx0CyiyoqfRx08cDuB/OLZgq63dkDNnd4zqDTT8zLT6zMTq1Ka pApb+5o0rapgHQP5+O3QAZrfnWLYXOPk17yQTekvwVpiSzwdPlOija5X+BLrLyNu EEYlR7Vz2qj/DAUN9vhCIdF4Bk8Yfk9txH5oJUmC0c2bfUkrCJgfbyK1GL00BkON aso8whDf8LF5BAl/ooofzvZXt+bw4Sp+LuX+OAcJUlqeK7IUdHQqnhhw5FOfenVO Z7MkMt2qtm3BlPzMWlZoeLNrkx4BzsBElFJ0Ds37uLk+LIg3whg+MYMFJPwXqUhs 6Ss76/cu/AhoHoX8k5wT5eNpzyWL8hNyDSosGDAgejjYFBXMlNzFYvG5zVE0EP7C i78cIdgSARKocOOeFpA3GEJL+ISi0g1ut8A1/kxgFp5dxGjfOAGHeDeaVWhWuhjz m7CjPwlfAvIBJJlC96MhPakY6tbyA0hW0/GiOfaoanJvVdWJF7lEdKle1Zs= -----END CERTIFICATE----- thrift-0.23.0/test/keys/client.key0000664000175000017500000000321715165535636017322 0ustar00buildbuild00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEAyQaX1kZWr+ZOtyiOurt6plPDDWCaA481Y3VA3O+L5w8jwSBu KTTif8AVa+C2e8oqcpB84uQEckfJN1eY+q91T3Dxl3129eTvmYG9u3HKx7pRkLFm deuq/lh8wZvYES9ywvkjmzp3eAvh405tjMUPu9SMBulqZRITs054yfuo7Ss8hw4M Ncv46Sv39MFw79e9FJQrR7GxfTcULTuC1N11X2URgKQm9AwIJCYV1DlqXtXPiIuV 4bmGwLDP9bnMdyypW3ObwIRDOvTQChHwCv9aQaHWJuaKyyLkGjYNy9Eqjem8NU4B j6CP1inF7bPswiafVPtlV2vQldS72OYyAoxDPwIDAQABAoIBAQC/2ez68LI2uaQS JUDicZ6CMpqKn9Ec6IXZX8QBlxR79fT3kc3QwcoQhe9rv1ApIC4WnFKz701XC6+7 g3xacy2QHYhUPcdUsaMBa9L5m4Ydy3Ggl83jaIEOsMCPvf4dmJz7+u3CbbAq/5wb ZXQjzsZPSnBBAG8r+m6Wx6N7kRQNE28MUD/dgiKUmLaTlsFb+YnTcVIWjqrip5Z3 gpeGpUcPUjGo4/KTHm9Lx+4HuiHC8I32qyy02Zh6s5/S5n0edsqePFnUXe9j9eSb gARUNFGBq6VOMQ+9hxAVuyNrIj32PCskuw1Oh7Ce29FOXIf9niLazaiiRrwBuC1V aDjxcQ4RAoGBAOzqz6rRzarhXpX0GprpvNIyMBiQvgGlSA6lQ3IP2+lcQN5hCvmg ULcaLak6D6BuJ4+UZN7kMqjNt9WOAG2xpTC1AQfZqXQEMrQ9v/2VLs7VFVX5MALy HEEKPkkY5MDprj9byg8lK7CQ4x3SSLQe5596gfAqYLqULpyeOF1foG8FAoGBANk3 tNbFMZK9lTr8qODuya5DX6eTva2YWe0EkDr4rDFmNgyez1y6Sibli8XF/5vMs7bf 4uNseFkKV9XHargiTRvqTiqPzD9g6SdCzz4KWLQAf1eC5Q9dOeQUkDgg1GxbeZKa tCEiieWvqL2HcQ5wOO6C/SO9/JysDCO1acVe9hRzAoGBAKavSe5X8AiCyYZdGP7W 5mdIsjgGVfhYbgsH0R0F9WYI5wbOZeddGIzKmUePtwDbn2/QKuv6x32mRum0H68N pjhPkOsSA7vBXF8ddt+Vvzn8ByfWyyW3a5OC/nF1VzQ29MZU8SOYtlViirgng8le WP4GNjdfyXBb4zODygo/xmN1AoGAU1no7rDkgOZ2qRfixc1bXp9DyU4L7t0TRLwH jFl32cza2KTn9TEW2y4iIFYF64b1PytSKOqqk6BAbCwFa3reE+Qo8nQTcA6D6Sjd 1XSq7Qdz1eTIeMjROhAZ9y/B04KWeAcdL8nNGHH7Uh7y5xNxBTUGZfy1PnlWfy1R 1QbHbrkCgYEAimg6HLaW5lan6vcYA30/u8WuypWiBtCjqiTW3BM5OIl7FUH/4opx sCopQoHE6PuA7ky1DD/8UZfdqYC34vmSWg+90HmgUfU0WCmRAgfDQ7SitwC0eicT U2Kf5i1v92whfzkS0Josz40pugRFBwBY7e4VV8O+okoKmTylIblph8I= -----END RSA PRIVATE KEY----- thrift-0.23.0/test/keys/client_v3.key0000664000175000017500000000321715165535636017732 0ustar00buildbuild00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEAsqPCAkuOxPmJ773z1KWaJyYWswj7zTVITm/uF0pIMSTzJh13 6Y7qJDMfKHZuO0EEEuvWgjxuDQCoi9G8lIyq3TV04scUmC0eQpZDizz3XRqW7F2n Mzapyp9I2dG0mRwVTb/iWlSIvGfIiWQZaX32P9V7/0CWH3zYBk7Sve9N5rymcjMQ FR7aNlNpU4tw2Oa8Jz8d4CjsljeZQ8K2fE+R9fUN+aq0DQlvhiBuKHHUCpypNneL dc5XB6dUUAsTlq8OjbWLbUqAiK3gdrsIgfx9dxKcBoQxXrkjKM3/VAM2PNFVZ4nz 6Klxt5n0QlZBsq4EQmcUxUr7JoVBFkeaJABiQwIDAQABAoIBAQCv5F/1xJHJzu6L OVxpJ7mWDIHTPOg50NnmKX2kPwbAJOKox+E2/fn7NL7cJ2g4PbcWLlKjH384nEpY iWYGWk8uyiDR3jWf9OTTqYLOCXSCnti12Sz1V0BtetLPbhVFoIo1aNcmHBAaepHQ /dersFQT3E9gMCbg0BsgcuI8E/F/WuFOI0LT0KikYH3r7QUE8yxoL37c+02X1DuP mpMhYSI3fUy33ix0Nkoeuy/br0j+5tRiKvSG6VAbGeFFRU6QZAyEhnpIZf8MjwcX DH2O5xuA6TnFosBsMlvVhrjqPUB/j/aGMb2+kyBl2JUEvwaeuatYdwdoOdARJ7gI L80776sJAoGBAOFr1//7VAF11qNYRHSc+y9wUTUTv5UXTNSuCBMRTQl9kgJSBFO3 SqmkhwrvBNKlvuGQGuYOHo0nQgDClegyf6FcOVvfWsSwDQdjOyw6PKgDL6vOZaAe Jrmp5Fs2n93GornHI87YPm2Gj274654UcOIG1eWzaOIyuEN7cqrUdY7/AoGBAMrf VwY/94YJFC9GCRzoeiAxserDqsdSquHlMA+TgZCQmsq7GPvVBa99gFYX5v6RkMh9 rEDaSb51ECMUo1Yot+UYjyRP1i3goDr/nAqGQxFEJm8JGhibDIfUWSdRh0cQ8OfT /M7FqhhYWCTCY3L4H2k+xGWmUsfpC+bijjvHmjC9AoGBAN/rDGkO8udwcoFXkMh1 l14MJ96de1VSC9PH++VU7j1bKsp7RikSjWvuLubBfvzv/6h4SP/1TovQT1QJ9nbs krNqtN96AuQWLRsFiyXnw5DxeU0kfPaMfNM428lvfWYDhmkcU4mIbJrHa3tEcGha zbb4K0k86hanYzpFSiY/XXdpAoGAaHJV7ozOVf6kmrYXCQATqDGNpQ16BkbkXYrO lKZfxVr9prRu53DEDZaylSCXN6cgAGjbX0RDRUAlv7nnYftyugtL3ukPnu0P8XAa GT0ImIIau33XJqXk7KWCBQEvgYISVXjJpncT3JbXQo2l/9II8flzydW4tt2f2A36 JoLcOo0CgYEAiDBPwbiwPf2paFan/Av52KDB6Lsq4EYYLeqTApACqkQLw9lDsCml dLD3t/ElCVTwhgRYFlo0rgC33TGGz7Kq+twcgZJ+7O7x+qa3YWTqtAYadyGZhl/p xGYwSQcKFWqu7TLrW9WK+SnV2Ku2G1IySlFUK4++9nNC2jRX13LaPMo= -----END RSA PRIVATE KEY----- thrift-0.23.0/test/keys/client.p120000664000175000017500000000543515165535636017140 0ustar00buildbuild000000000000000‚ 0‚ ß *†H†÷  ‚ Ђ Ì0‚ È0‚ *†H†÷  ‚p0‚l0‚e *†H†÷ 0 *†H†÷  0æÜñ­¤#9€‚8µèùMš¤ðjËœXlír‰6Äà>w]À‚xŠ’I\k„ø 5 $GköÆoà2Nèy&é#ùé«aáÑ»Êüaª P®á”<,I}Ê=g`þY‚§Ý¨®tma+»º{œ†³”—»“Ÿ¦| h—"T@ .‹Qº’]DLàP]^ÈoòT€ª´!£,Þ.£‚fÏ~ÖgÖŽkú0¹Š¦ª9$NQ•^¾ðÔˆrÿ hC9ãúühÉŽ¥Œ º:Ÿ×§e¼ðk»g¿©2jÕWkEzîeöˆiTd^W§-»®‰|:±yZ0±;ã7Úk\þZÒŠ˜3_ ŒL<°6³¨ …%1šmÀdóßG>ZÊ14á=#Ü*æ–³ä`ôASÌŸosk–B‡·gV%XD¶yÂÊJ*Òì ¹ô¢Ééû\üãR‘“ˆXö:ün‰Ç]ÿ_íCËU(d§ï,°J´Œñ©x‹d£.[¦rËpžÃ$>òO'jx#óéþWê£9# ÷¶ðÃýRu‡.tØ>˜ ©ÜŠmé¸ü¨1ª2ÚÑ¢x¤0hš•WOwE/¥8Œ„U †òÙ¡/dš–ô¼É¡³¬Öг\—Oäµÿû£Ÿ^~î…z<àzî-å?®Ç!›gÙ¹#¶#¨by†öxékÝFᳪˆ !íÞÈĵ«5g{¬„´F‚ißàðA•†§ú¹Î·ïiÎÀ²ˆÔí?å ðßúÇ?` ¸—q»’ĹIÓ®júŸGgpÇ…Ÿl+UÔ)ª€þ÷=›ðY² QQÅëÄÌNµ£Ü¯Óúèáô=ŠÄ#ØÒÑ|ÂaƒÐ¼ 7TcxÓr¦¼‘Í<|® ]>eÓ)±iÆëî°"ç|¤%R¢ä§?u?Ã%ËckxóÐô’ÆXm[·Ë}ÄɲFy5R¶÷ï¨NŸ‰•WÀ«_a'X 0 UÖ³=òöaz|³óÙ3›írÖ¸%sÀêlû©3¦øŠJf^f*ÊËdÄ^’Ûôí1”‰–•>ỳ”Ó½‹àäPÈßKÂÙŒd,µŸ" ƒé.Ò¬àŽÊž_VTϹƒ_IÞêÕ¶Ù{: Ðì™8«;Î$[<&ý@¦fVì˜È„Ô<Í*GÜkùõnc¡Á¸è¤B5Jöåà’øñÃbªOä^zئ¬_¯`d¥«"äõ™=rgJá8›£š5T®ËÌ3cq² «LÚ¡ªrlòŽI¤J±8é¤Ç¶ð"úÀqÑáÃùÑ2x$™/«2&4±r U+àPKŸ¦…ûPâIWßK%qaž²™)Sºª R °J_0*·_µGAûÅš~ÆÉöïä‡C“’ÙË!7aÙÒ» ì)»É=2@§Å%È´`}à|¦YÞò2y€Éì¸vÙ‹Ò{/}#®¿+5ÿÒ‰Dzfó¦Ñ"¨rí(BÝ(äå Òÿh-R¦sÕd Ä5­!A$ªàðéÇ#õ¸÷™ºxD7-\=¨öí0îm®t7`œéÔºëkn2EÌ“Úüª@^]I$™wo#-²mâ±ö ‡x_íÌàÄè“tWÔYýO˜7ˆçš[}ÊÈþÆ”Ç ­Ïƒ"D® >‡2Jžé†˜ù¡P“!X!bwN­üUZÖ M®fÙ0‚A *†H†÷  ‚2‚.0‚*0‚& *†H†÷   ‚î0‚ê0 *†H†÷  0Û¡s#uæI÷‚È· ‘8~ðC÷.“R@¯kŠ‘—¨YØõúó¤—çI‰p&Œ¢®^,¹A¹Y0É`Qy‚iÕDé¦É‡ï¨è+Fpò¼*Û5ÆÒÜ3 —â®áu@°Š’‚EB·L‘T jä3ûÔ*WŽª8+í€kɃ¨ïæº)#š'"ÅiÄ•3ˆÖ‡MÖw‚uΧšcå²voÜŒ™©1wÒ1¨u VžÃ>ë{@xnÒbamL±Ï%"ךøEåAîžJà ,%º‚3ØõiÑ,m\YúºrkB¸ú¦lÕWk2š@/ULem-µFɤœiDÿHò(0å^­ß3 #µ*‰3ÁNvC¤o~ØD‰Z9ò™JuåÈÊV¿ ÏòE[<oµ½7™‚â]àçž"(qæ-6–ߤhä%¢HöÆ&‹36jpc±úmN–T;je›~ÝÌRíJ2ócCj3Ž« $jC•¾A ‘Ú58‘ÂÃ.‘ÍK@k|t¾Ã?„ÚÛ)!-!Zn&»}mþ×F‡QÍÕ6é/¼¦§dÜÿŒµ¹QµœPìwò);%@jPq[ÁÉï7Æç"ÓõxfPÇIç¶Ø©w¼§ ÅÞ'jé“×6'ݸ?ò Ê`[XO—A>5m½‡$œAbn1DzÏFð˜`HÎW+Ø}ÚÜòZ6$…÷6þq ª³¾v³ÖÂIìƒóüEÆËƒsT|r M ì†) g¾§Š¼—C T:¿»·Z££¼â‹Î%(¥å¨¬àÇë|gñ@¬t ¬z :‚£&wi…â5t*ŽÝ(œ¥?Ú• ™ˆT4Å[€W¤]€TìLý¼ùŸl·V*ˆ6h7¤ä³ƒë{çÏcÕǪõl#®.uëâ"3Rw g1„…¨¸!´°j$’gÄç(ETA†aŸ¿¥NðW"¬ˆ*ınѪMl÷ŸÐÅ/n2’¤{ψì°@šƒÅ£=‡S±j .¤;Þ覑œG@_äèè\¸1Åqï+ó_V\4ƒýŽ †¨#ÉQëØkùj?ê“ã#¤šËwþç b)ç6AOàÉ—,Èáà|Õ×2Â󤢮”°Ç\ñü™¡˜ºÊ"ˆ¤€”DZÁíç&¦sõPúmé:i¡fß«¦†é]AÐ1;N4öEg…§¢ÅÀúDå#x‘~‚µÚ[1Ç|±×ë° âNtŸúà«c†¾T-}ë؉—ÒdˆUîœêl÷ŽÖ]âÛ@‰£{UÐŽt—Ô·£r(¶sƾ¯T[¿FK¬±ó^Ä|3À¾Ãë.åÑ-C«K#š? F8Y®Î,ŸÀ×V3a’ךÂëéêøD³Tf`‹ýYQÌ bïÏ×Åà-OF›`îÁe³öÂp ‡’þÑ)-XbBÈÆ³u¾d=s$¤ANW‰i\D¢øüÁÊ›ü†ñ|»Y€‰9¼zùqœË…ŃäR ÞW<Öô‹•ÂÔ]<ï†AÂℱôÚác³_í§DúÁÃoeE…˜ƒí X¸rÚ—¹ŸôˆÌøvReÐö~T‰…P;IþÉw³Qc91%0# *†H†÷  1Bê|¬½)–Z¨¶<«…ã}ÃÔ010!0 +üÍ¿’§îèä2êB'ì!(ý'²¥‹Ï¤Àthrift-0.23.0/test/keys/server.pem0000664000175000017500000001303215165535636017337 0ustar00buildbuild00000000000000-----BEGIN CERTIFICATE----- MIIGuTCCBKGgAwIBAgIUDG+EIHE1EFeuj0ddWtxGQAPatt8wDQYJKoZIhvcNAQEL BQAwgbExEjAQBgNVBAMMCWxvY2FsaG9zdDEkMCIGCSqGSIb3DQEJARYVZGV2QHRo cmlmdC5hcGFjaGUub3JnMRYwFAYDVQQLDA1BcGFjaGUgVGhyaWZ0MScwJQYDVQQK DB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xFDASBgNVBAcMC0ZvcmVz dCBIaWxsMREwDwYDVQQIDAhNYXJ5bGFuZDELMAkGA1UEBhMCVVMwHhcNMjIwNjMw MjIzNzI4WhcNMzAwOTE2MjIzNzI4WjCBsTESMBAGA1UEAwwJbG9jYWxob3N0MSQw IgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0LmFwYWNoZS5vcmcxFjAUBgNVBAsMDUFw YWNoZSBUaHJpZnQxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRh dGlvbjEUMBIGA1UEBwwLRm9yZXN0IEhpbGwxETAPBgNVBAgMCE1hcnlsYW5kMQsw CQYDVQQGEwJVUzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM/uam3B XjI0x6hfdqdr4ATbiDA7niD8MShpyqBmdpMWu7ng91grZPCDl7T/6xCrdT92NI7m CpnA5hBK/0W8+5Y8NnKjkwZym9H5kO18FQ+hH1mJq3bx57mxsZAE1Iwbr21W/Kxh 6Jx279ayywVAU6l9cH/aS5t3pl0qZUysBi3me2J88z6oYA3FNRaxX3kO4I8iJjYu vIfpWmXf8By/TOLzNkR1pJLXe849tAGrTtm+goLw59RMhIgxlS05DH3nGNKamWQ4 gr2H5do+2pFzKoom4vCryKgc/NXyEQNc/1FRJsi3/XK/NlezoPw+xV33AeDopmmK VsQ4RJONyVlgksCD2Q2odrCR/ryqirA5BTH8pQFfvCQfr4G6zkSzSDBTC9ZI2IIx JFs87mVpcu+0n+u482vdwsUAeByE3opA99MYrlrZDjLYl40Y0kzWHK42Is3iBz03 B4VFKUrsUXa5bcquYPkr1oVycamH1QTwXtgkU6DspAjuR3tUQT4i7sSEnoV8pGl0 gLWpGABxhGde0Z0V/x14BNFJ+ZG2uiUpLvMJshqBle1kIj+CqySQMc3mFpkdBTUZ nyVVuVRc6+oGGfBujOvqFKuS9rOhpCSBBVwbq5/lPSgtvy2uBiiTwlFLMgPvV66X xQGbbgTxOjIdrL1i6smD/6RXkbIMKOFb/o4NAgMBAAGjgcYwgcMwHQYDVR0OBBYE FKgE4SRwWu2cxDhjzef4eUmUnR3aMB8GA1UdIwQYMBaAFKgE4SRwWu2cxDhjzef4 eUmUnR3aMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgHmMB0GA1Ud JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA+BgNVHREENzA1hwR/AAABhxAAAAAA AAAAAAAAAAAAAAABhxAAAAAAAAAAAAAA//9/AAABgglsb2NhbGhvc3QwDQYJKoZI hvcNAQELBQADggIBAIsl4jTS2dbrt7CStvwInf8InjaGqOrj4c0HDYVYBi33JkHx WasCJbjs+YWsQYcK3/rE9iYyZA/cwIE89x2ec1JX42SrayPLIdUF5VSo+DP3knTH Si7zt3igmziyKTsLoliISwOKwF5mdc+qeOE8CuExi7xIV4xlJxfM+XW6aeHdskof KSTd4qqzyO+wMezKb8u9/b0rMGNCvaM1etcWNlrfP2SXayLAfFkKypSbER1uIUzg ZnhSGyfYee6DrIATihPyOofjbUbqfF7MJtDTqTLhqhkndF+T7IR2LcR4XdtkxtdT F1WwKcM2FX/cjpdtGX76U6hPD6uWXDISk8IiS8HX10x0wamlVvK3zz9UsWwQp5DD EjG/XtMU59oAyiiGIbZllUWKOOabCcId8dvYZw4zoObCrYiYb2qvPcJPyUOzcCPn wsOS22lgTqEfoNzlrmh39YI8pvNDh+t0SkK8Nhllm4o/hIQkIxYlqsp4IkCnyxpO dgRMt2H+98FCNLGs3EIkmaeKD42OyglvdzM0IYHT2VDRfhwpjPvSEw/lJyYIi3R0 BEWNGA9Jx+BKZRxmyOerUqCMmImwMoLtKudEHpWz5bXcUkmqsmGXaHabVW7Z3nfN ZwdSLNHgHLNYBGe6Ak198CFHGmP/9XbV41cGNXctfe92baDv5IMgWOi35X5w -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- MIIJPwIBADANBgkqhkiG9w0BAQEFAASCCSkwggklAgEAAoICAQDP7mptwV4yNMeo X3ana+AE24gwO54g/DEoacqgZnaTFru54PdYK2Twg5e0/+sQq3U/djSO5gqZwOYQ Sv9FvPuWPDZyo5MGcpvR+ZDtfBUPoR9Ziat28ee5sbGQBNSMG69tVvysYeicdu/W sssFQFOpfXB/2kubd6ZdKmVMrAYt5ntifPM+qGANxTUWsV95DuCPIiY2LryH6Vpl 3/Acv0zi8zZEdaSS13vOPbQBq07ZvoKC8OfUTISIMZUtOQx95xjSmplkOIK9h+Xa PtqRcyqKJuLwq8ioHPzV8hEDXP9RUSbIt/1yvzZXs6D8PsVd9wHg6KZpilbEOEST jclZYJLAg9kNqHawkf68qoqwOQUx/KUBX7wkH6+Bus5Es0gwUwvWSNiCMSRbPO5l aXLvtJ/ruPNr3cLFAHgchN6KQPfTGK5a2Q4y2JeNGNJM1hyuNiLN4gc9NweFRSlK 7FF2uW3KrmD5K9aFcnGph9UE8F7YJFOg7KQI7kd7VEE+Iu7EhJ6FfKRpdIC1qRgA cYRnXtGdFf8deATRSfmRtrolKS7zCbIagZXtZCI/gqskkDHN5haZHQU1GZ8lVblU XOvqBhnwbozr6hSrkvazoaQkgQVcG6uf5T0oLb8trgYok8JRSzID71eul8UBm24E 8ToyHay9YurJg/+kV5GyDCjhW/6ODQIDAQABAoICABd4zF7TYzS7rIYfMJ+5l7I0 rezz7ee/UDVFq+/rYRs9h7d147X6QAy+bhOqh/h7wmKFj21KHow4sD/Kl4Jh0Oym o2bRfDlQGrLbPzbvuNjo0UckOUzWBdh6bJbbVLr0LRtkpGU5MC7pZi2QRUa0ej05 wcdM9xf3q7n8nS7IhHIOAIOfoz3BeAZV6qZDI4ng2gyOSE35fKLC/sddPhegqKc9 2TRlK0zAMmOXp4hAtEf0L3tkgmb+tD9DiZlvRS+5NJ4hgYtErc2DV7kJO1cL7xNl TFzqp14C16+3AaClkNS3Gm+yBVQ8rX+88UFIPLNcvMOMv6xOR3ki+OrHKKGEO0x3 vd0Q5gcgbwxD2sEHajlbo9UkSEJnaUeUD0s/kQBYWCLIcosayPQh3Z3xLE4+ir+r bbvAK4b2bJHeww2X9NrHB3dA8xjISIvzGoGL6M6nrgEgiov+L9rAyAlFhpY6872R ttfgN3aP2ZK7tmfz+7G/cfWyPfSRJpTVIrtfpJw9CWuzFrAgOuPUTP5eOjjxPXeQ eZuaABXVkM+V8xoqVE9KiD6UrE2401lPpoLevxm/i/oJePtFSdruu9ARBxVt2/gz No2PKXYuJaoyOPKPqSWnJiI0ZI9KpvMBXdUcuI3dv8y5dumKfKqAKliAvaXNMdfU 8HeeVqDsh3eotH56YUFpAoIBAQD+rP491LtjrF/cCX6wdAAgkgfpQ7nnM8XM+606 xbeepHJllhTfsE7K69Gs0GSDHRjh6q/GYnr2GnZ2q1kTVUeJ0gXmlPVOudxlxHlw W2vfVBivoMC2z5pb1shdmcwyuxG+NJWogW3nn3JzbPY5ZKIT3O+YMF71NeAiAMqF h0MuKpIysfqUqMHD2dOz3kb2pci048WTnMH4GnHnz7g6oB5nV9cz/BTr2XJN9kye FfDhBSZX4IMcPLcUvzuv3NAW+lNGASCyrfCxx5SDZcx45jdpTqyK2mXLrmUKB+tZ /4RRKuMrngydZYT73T+Qy5b9KM1O/yPLfNm++f0jPJlpn2dXAoIBAQDRAzMZ97SY ELqwx3pnTdQoKV7q5hXv03SZOGuh4yhyOXdiWTZAftA0xQ7UkoH1nKF9FaLDupD6 8tnG4kaZB7OiKUf9rFM42MS2be7bz7Q9Cg9s0rWAtUowTWMDi5bRX9zOhiphPFuY 71TdI59YhVQPpK0roZcKeCxEDaKpywfAbAkApHaGUpZJAx4Gx/97iQZZdBCw24Ec EyD1Xxsl1q54tJwiYncxlghpy4aVO5zXeDyHuH9jtDoM+dxvobytrHMtbwu6YGK4 6RI/1sggoZ+89ZONFrXz8o0/0f+uP9bLL4ds4b0PINHKGV1AG1SBfOmLkhKx/y76 BhY1zsHuFws7AoIBAHAxN4N3nuGnA0fE6wnC4Hd4vYF2c4Q125KU4Nh+V4jMuxSj jCiK2/sq7eCqoUzdWaPUpoDHy5F1UPCwRXpt3CkL28ubnYGEAWLXrgPgUmI9Au8D 60HdrQt+UCBj64ABxyw6sB9efVNHe7z7qHDaM0h60RYDYSG3DTkNjipKzz6cRHGO 1Gv+9/VWlZusdSidGhEOMnD34r9wrvNHH8q71QkDumtNRs4rqd5Mfa46zjXi9eRK pJeg66p5IEs2BHnK5zp0rrnoRJuc54EHLI+qI4kBvqMg2S1kc2B64qRwGxNCyHbj ln0URwRJkIIyHh8ChYeigFtZcfde27RVMuRD89sCggEABJ41etVmQBXeihleMvod PeXsGvSKd4oMgXYlqqYCNsPeR2YBNNuYbhIMidXS2UJkrwbTWc+9dE35UdOeC7OH 3IVc+dXc4NypO/6h0Gl+afrW7GibagSXZwnOrj1fT7D2h/me5hcXTwG6tkgbNTF8 8fuJd/VSCQEuuTIz7dx2h2HbsQ/xLnaUq3hOKYgxtOEKKt/Nnpq694vUppc7WlKr +C7FZF0YlRfjh7Lfflya0oftjnIdHm7U+YRrwmuoZ43v3YkekTef9sXviUmNkmr/ xIUIhY2C56jsRgS1yXvPmx2puFYkfzkSaYy16ryv2UyRPGw1zYj92LhZtUakMkaA EQKB/wLQfRkaMz0RtxzyroTLcc1mlJmSyE/Cb6032R4BmA0t2MDFUePmRYsp7f2I 47z5a9R1oJtY0lNl1JeSWqNvL9iAmFAkN96hC0mk4xvWZBOhIPfMx6hVKms9Zbwd yHVfUFudAjp/cY4zXBKbSj7emz/L+yM0E0Dz07HqvqX3CcWrR0gbC6GE3wRr5XM2 asZAQXYadPjO4W9vsiT0UWrj6zKWwr0mH7gLk+VXzqE/25+aSx4Z6N1IAkR7gW23 2I5xxNtaanZH6jmJ1CGZA3mWazQCl0vOc3QoyzH9TqQbL+VL7Y75lUTSwW8IPPL1 OV2cxV8xD52Pk7JlPVRIgWOT2Q== -----END PRIVATE KEY----- thrift-0.23.0/test/keys/server.key0000664000175000017500000000630415165535636017352 0ustar00buildbuild00000000000000-----BEGIN PRIVATE KEY----- MIIJPwIBADANBgkqhkiG9w0BAQEFAASCCSkwggklAgEAAoICAQDP7mptwV4yNMeo X3ana+AE24gwO54g/DEoacqgZnaTFru54PdYK2Twg5e0/+sQq3U/djSO5gqZwOYQ Sv9FvPuWPDZyo5MGcpvR+ZDtfBUPoR9Ziat28ee5sbGQBNSMG69tVvysYeicdu/W sssFQFOpfXB/2kubd6ZdKmVMrAYt5ntifPM+qGANxTUWsV95DuCPIiY2LryH6Vpl 3/Acv0zi8zZEdaSS13vOPbQBq07ZvoKC8OfUTISIMZUtOQx95xjSmplkOIK9h+Xa PtqRcyqKJuLwq8ioHPzV8hEDXP9RUSbIt/1yvzZXs6D8PsVd9wHg6KZpilbEOEST jclZYJLAg9kNqHawkf68qoqwOQUx/KUBX7wkH6+Bus5Es0gwUwvWSNiCMSRbPO5l aXLvtJ/ruPNr3cLFAHgchN6KQPfTGK5a2Q4y2JeNGNJM1hyuNiLN4gc9NweFRSlK 7FF2uW3KrmD5K9aFcnGph9UE8F7YJFOg7KQI7kd7VEE+Iu7EhJ6FfKRpdIC1qRgA cYRnXtGdFf8deATRSfmRtrolKS7zCbIagZXtZCI/gqskkDHN5haZHQU1GZ8lVblU XOvqBhnwbozr6hSrkvazoaQkgQVcG6uf5T0oLb8trgYok8JRSzID71eul8UBm24E 8ToyHay9YurJg/+kV5GyDCjhW/6ODQIDAQABAoICABd4zF7TYzS7rIYfMJ+5l7I0 rezz7ee/UDVFq+/rYRs9h7d147X6QAy+bhOqh/h7wmKFj21KHow4sD/Kl4Jh0Oym o2bRfDlQGrLbPzbvuNjo0UckOUzWBdh6bJbbVLr0LRtkpGU5MC7pZi2QRUa0ej05 wcdM9xf3q7n8nS7IhHIOAIOfoz3BeAZV6qZDI4ng2gyOSE35fKLC/sddPhegqKc9 2TRlK0zAMmOXp4hAtEf0L3tkgmb+tD9DiZlvRS+5NJ4hgYtErc2DV7kJO1cL7xNl TFzqp14C16+3AaClkNS3Gm+yBVQ8rX+88UFIPLNcvMOMv6xOR3ki+OrHKKGEO0x3 vd0Q5gcgbwxD2sEHajlbo9UkSEJnaUeUD0s/kQBYWCLIcosayPQh3Z3xLE4+ir+r bbvAK4b2bJHeww2X9NrHB3dA8xjISIvzGoGL6M6nrgEgiov+L9rAyAlFhpY6872R ttfgN3aP2ZK7tmfz+7G/cfWyPfSRJpTVIrtfpJw9CWuzFrAgOuPUTP5eOjjxPXeQ eZuaABXVkM+V8xoqVE9KiD6UrE2401lPpoLevxm/i/oJePtFSdruu9ARBxVt2/gz No2PKXYuJaoyOPKPqSWnJiI0ZI9KpvMBXdUcuI3dv8y5dumKfKqAKliAvaXNMdfU 8HeeVqDsh3eotH56YUFpAoIBAQD+rP491LtjrF/cCX6wdAAgkgfpQ7nnM8XM+606 xbeepHJllhTfsE7K69Gs0GSDHRjh6q/GYnr2GnZ2q1kTVUeJ0gXmlPVOudxlxHlw W2vfVBivoMC2z5pb1shdmcwyuxG+NJWogW3nn3JzbPY5ZKIT3O+YMF71NeAiAMqF h0MuKpIysfqUqMHD2dOz3kb2pci048WTnMH4GnHnz7g6oB5nV9cz/BTr2XJN9kye FfDhBSZX4IMcPLcUvzuv3NAW+lNGASCyrfCxx5SDZcx45jdpTqyK2mXLrmUKB+tZ /4RRKuMrngydZYT73T+Qy5b9KM1O/yPLfNm++f0jPJlpn2dXAoIBAQDRAzMZ97SY ELqwx3pnTdQoKV7q5hXv03SZOGuh4yhyOXdiWTZAftA0xQ7UkoH1nKF9FaLDupD6 8tnG4kaZB7OiKUf9rFM42MS2be7bz7Q9Cg9s0rWAtUowTWMDi5bRX9zOhiphPFuY 71TdI59YhVQPpK0roZcKeCxEDaKpywfAbAkApHaGUpZJAx4Gx/97iQZZdBCw24Ec EyD1Xxsl1q54tJwiYncxlghpy4aVO5zXeDyHuH9jtDoM+dxvobytrHMtbwu6YGK4 6RI/1sggoZ+89ZONFrXz8o0/0f+uP9bLL4ds4b0PINHKGV1AG1SBfOmLkhKx/y76 BhY1zsHuFws7AoIBAHAxN4N3nuGnA0fE6wnC4Hd4vYF2c4Q125KU4Nh+V4jMuxSj jCiK2/sq7eCqoUzdWaPUpoDHy5F1UPCwRXpt3CkL28ubnYGEAWLXrgPgUmI9Au8D 60HdrQt+UCBj64ABxyw6sB9efVNHe7z7qHDaM0h60RYDYSG3DTkNjipKzz6cRHGO 1Gv+9/VWlZusdSidGhEOMnD34r9wrvNHH8q71QkDumtNRs4rqd5Mfa46zjXi9eRK pJeg66p5IEs2BHnK5zp0rrnoRJuc54EHLI+qI4kBvqMg2S1kc2B64qRwGxNCyHbj ln0URwRJkIIyHh8ChYeigFtZcfde27RVMuRD89sCggEABJ41etVmQBXeihleMvod PeXsGvSKd4oMgXYlqqYCNsPeR2YBNNuYbhIMidXS2UJkrwbTWc+9dE35UdOeC7OH 3IVc+dXc4NypO/6h0Gl+afrW7GibagSXZwnOrj1fT7D2h/me5hcXTwG6tkgbNTF8 8fuJd/VSCQEuuTIz7dx2h2HbsQ/xLnaUq3hOKYgxtOEKKt/Nnpq694vUppc7WlKr +C7FZF0YlRfjh7Lfflya0oftjnIdHm7U+YRrwmuoZ43v3YkekTef9sXviUmNkmr/ xIUIhY2C56jsRgS1yXvPmx2puFYkfzkSaYy16ryv2UyRPGw1zYj92LhZtUakMkaA EQKB/wLQfRkaMz0RtxzyroTLcc1mlJmSyE/Cb6032R4BmA0t2MDFUePmRYsp7f2I 47z5a9R1oJtY0lNl1JeSWqNvL9iAmFAkN96hC0mk4xvWZBOhIPfMx6hVKms9Zbwd yHVfUFudAjp/cY4zXBKbSj7emz/L+yM0E0Dz07HqvqX3CcWrR0gbC6GE3wRr5XM2 asZAQXYadPjO4W9vsiT0UWrj6zKWwr0mH7gLk+VXzqE/25+aSx4Z6N1IAkR7gW23 2I5xxNtaanZH6jmJ1CGZA3mWazQCl0vOc3QoyzH9TqQbL+VL7Y75lUTSwW8IPPL1 OV2cxV8xD52Pk7JlPVRIgWOT2Q== -----END PRIVATE KEY----- thrift-0.23.0/test/keys/CA.pem0000664000175000017500000001771515165535636016330 0ustar00buildbuild00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 0c:6f:84:20:71:35:10:57:ae:8f:47:5d:5a:dc:46:40:03:da:b6:df Signature Algorithm: sha256WithRSAEncryption Issuer: CN = localhost, emailAddress = dev@thrift.apache.org, OU = Apache Thrift, O = The Apache Software Foundation, L = Forest Hill, ST = Maryland, C = US Validity Not Before: Jun 30 22:37:28 2022 GMT Not After : Sep 16 22:37:28 2030 GMT Subject: CN = localhost, emailAddress = dev@thrift.apache.org, OU = Apache Thrift, O = The Apache Software Foundation, L = Forest Hill, ST = Maryland, C = US Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: 00:cf:ee:6a:6d:c1:5e:32:34:c7:a8:5f:76:a7:6b: e0:04:db:88:30:3b:9e:20:fc:31:28:69:ca:a0:66: 76:93:16:bb:b9:e0:f7:58:2b:64:f0:83:97:b4:ff: eb:10:ab:75:3f:76:34:8e:e6:0a:99:c0:e6:10:4a: ff:45:bc:fb:96:3c:36:72:a3:93:06:72:9b:d1:f9: 90:ed:7c:15:0f:a1:1f:59:89:ab:76:f1:e7:b9:b1: b1:90:04:d4:8c:1b:af:6d:56:fc:ac:61:e8:9c:76: ef:d6:b2:cb:05:40:53:a9:7d:70:7f:da:4b:9b:77: a6:5d:2a:65:4c:ac:06:2d:e6:7b:62:7c:f3:3e:a8: 60:0d:c5:35:16:b1:5f:79:0e:e0:8f:22:26:36:2e: bc:87:e9:5a:65:df:f0:1c:bf:4c:e2:f3:36:44:75: a4:92:d7:7b:ce:3d:b4:01:ab:4e:d9:be:82:82:f0: e7:d4:4c:84:88:31:95:2d:39:0c:7d:e7:18:d2:9a: 99:64:38:82:bd:87:e5:da:3e:da:91:73:2a:8a:26: e2:f0:ab:c8:a8:1c:fc:d5:f2:11:03:5c:ff:51:51: 26:c8:b7:fd:72:bf:36:57:b3:a0:fc:3e:c5:5d:f7: 01:e0:e8:a6:69:8a:56:c4:38:44:93:8d:c9:59:60: 92:c0:83:d9:0d:a8:76:b0:91:fe:bc:aa:8a:b0:39: 05:31:fc:a5:01:5f:bc:24:1f:af:81:ba:ce:44:b3: 48:30:53:0b:d6:48:d8:82:31:24:5b:3c:ee:65:69: 72:ef:b4:9f:eb:b8:f3:6b:dd:c2:c5:00:78:1c:84: de:8a:40:f7:d3:18:ae:5a:d9:0e:32:d8:97:8d:18: d2:4c:d6:1c:ae:36:22:cd:e2:07:3d:37:07:85:45: 29:4a:ec:51:76:b9:6d:ca:ae:60:f9:2b:d6:85:72: 71:a9:87:d5:04:f0:5e:d8:24:53:a0:ec:a4:08:ee: 47:7b:54:41:3e:22:ee:c4:84:9e:85:7c:a4:69:74: 80:b5:a9:18:00:71:84:67:5e:d1:9d:15:ff:1d:78: 04:d1:49:f9:91:b6:ba:25:29:2e:f3:09:b2:1a:81: 95:ed:64:22:3f:82:ab:24:90:31:cd:e6:16:99:1d: 05:35:19:9f:25:55:b9:54:5c:eb:ea:06:19:f0:6e: 8c:eb:ea:14:ab:92:f6:b3:a1:a4:24:81:05:5c:1b: ab:9f:e5:3d:28:2d:bf:2d:ae:06:28:93:c2:51:4b: 32:03:ef:57:ae:97:c5:01:9b:6e:04:f1:3a:32:1d: ac:bd:62:ea:c9:83:ff:a4:57:91:b2:0c:28:e1:5b: fe:8e:0d Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: A8:04:E1:24:70:5A:ED:9C:C4:38:63:CD:E7:F8:79:49:94:9D:1D:DA X509v3 Authority Key Identifier: keyid:A8:04:E1:24:70:5A:ED:9C:C4:38:63:CD:E7:F8:79:49:94:9D:1D:DA X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Key Usage: critical Digital Signature, Non Repudiation, Key Encipherment, Certificate Sign, CRL Sign X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication X509v3 Subject Alternative Name: IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1, IP Address:0:0:0:0:0:FFFF:7F00:1, DNS:localhost Signature Algorithm: sha256WithRSAEncryption 8b:25:e2:34:d2:d9:d6:eb:b7:b0:92:b6:fc:08:9d:ff:08:9e: 36:86:a8:ea:e3:e1:cd:07:0d:85:58:06:2d:f7:26:41:f1:59: ab:02:25:b8:ec:f9:85:ac:41:87:0a:df:fa:c4:f6:26:32:64: 0f:dc:c0:81:3c:f7:1d:9e:73:52:57:e3:64:ab:6b:23:cb:21: d5:05:e5:54:a8:f8:33:f7:92:74:c7:4a:2e:f3:b7:78:a0:9b: 38:b2:29:3b:0b:a2:58:88:4b:03:8a:c0:5e:66:75:cf:aa:78: e1:3c:0a:e1:31:8b:bc:48:57:8c:65:27:17:cc:f9:75:ba:69: e1:dd:b2:4a:1f:29:24:dd:e2:aa:b3:c8:ef:b0:31:ec:ca:6f: cb:bd:fd:bd:2b:30:63:42:bd:a3:35:7a:d7:16:36:5a:df:3f: 64:97:6b:22:c0:7c:59:0a:ca:94:9b:11:1d:6e:21:4c:e0:66: 78:52:1b:27:d8:79:ee:83:ac:80:13:8a:13:f2:3a:87:e3:6d: 46:ea:7c:5e:cc:26:d0:d3:a9:32:e1:aa:19:27:74:5f:93:ec: 84:76:2d:c4:78:5d:db:64:c6:d7:53:17:55:b0:29:c3:36:15: 7f:dc:8e:97:6d:19:7e:fa:53:a8:4f:0f:ab:96:5c:32:12:93: c2:22:4b:c1:d7:d7:4c:74:c1:a9:a5:56:f2:b7:cf:3f:54:b1: 6c:10:a7:90:c3:12:31:bf:5e:d3:14:e7:da:00:ca:28:86:21: b6:65:95:45:8a:38:e6:9b:09:c2:1d:f1:db:d8:67:0e:33:a0: e6:c2:ad:88:98:6f:6a:af:3d:c2:4f:c9:43:b3:70:23:e7:c2: c3:92:db:69:60:4e:a1:1f:a0:dc:e5:ae:68:77:f5:82:3c:a6: f3:43:87:eb:74:4a:42:bc:36:19:65:9b:8a:3f:84:84:24:23: 16:25:aa:ca:78:22:40:a7:cb:1a:4e:76:04:4c:b7:61:fe:f7: c1:42:34:b1:ac:dc:42:24:99:a7:8a:0f:8d:8e:ca:09:6f:77: 33:34:21:81:d3:d9:50:d1:7e:1c:29:8c:fb:d2:13:0f:e5:27: 26:08:8b:74:74:04:45:8d:18:0f:49:c7:e0:4a:65:1c:66:c8: e7:ab:52:a0:8c:98:89:b0:32:82:ed:2a:e7:44:1e:95:b3:e5: b5:dc:52:49:aa:b2:61:97:68:76:9b:55:6e:d9:de:77:cd:67: 07:52:2c:d1:e0:1c:b3:58:04:67:ba:02:4d:7d:f0:21:47:1a: 63:ff:f5:76:d5:e3:57:06:35:77:2d:7d:ef:76:6d:a0:ef:e4: 83:20:58:e8:b7:e5:7e:70 -----BEGIN CERTIFICATE----- MIIGuTCCBKGgAwIBAgIUDG+EIHE1EFeuj0ddWtxGQAPatt8wDQYJKoZIhvcNAQEL BQAwgbExEjAQBgNVBAMMCWxvY2FsaG9zdDEkMCIGCSqGSIb3DQEJARYVZGV2QHRo cmlmdC5hcGFjaGUub3JnMRYwFAYDVQQLDA1BcGFjaGUgVGhyaWZ0MScwJQYDVQQK DB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xFDASBgNVBAcMC0ZvcmVz dCBIaWxsMREwDwYDVQQIDAhNYXJ5bGFuZDELMAkGA1UEBhMCVVMwHhcNMjIwNjMw MjIzNzI4WhcNMzAwOTE2MjIzNzI4WjCBsTESMBAGA1UEAwwJbG9jYWxob3N0MSQw IgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0LmFwYWNoZS5vcmcxFjAUBgNVBAsMDUFw YWNoZSBUaHJpZnQxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRh dGlvbjEUMBIGA1UEBwwLRm9yZXN0IEhpbGwxETAPBgNVBAgMCE1hcnlsYW5kMQsw CQYDVQQGEwJVUzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM/uam3B XjI0x6hfdqdr4ATbiDA7niD8MShpyqBmdpMWu7ng91grZPCDl7T/6xCrdT92NI7m CpnA5hBK/0W8+5Y8NnKjkwZym9H5kO18FQ+hH1mJq3bx57mxsZAE1Iwbr21W/Kxh 6Jx279ayywVAU6l9cH/aS5t3pl0qZUysBi3me2J88z6oYA3FNRaxX3kO4I8iJjYu vIfpWmXf8By/TOLzNkR1pJLXe849tAGrTtm+goLw59RMhIgxlS05DH3nGNKamWQ4 gr2H5do+2pFzKoom4vCryKgc/NXyEQNc/1FRJsi3/XK/NlezoPw+xV33AeDopmmK VsQ4RJONyVlgksCD2Q2odrCR/ryqirA5BTH8pQFfvCQfr4G6zkSzSDBTC9ZI2IIx JFs87mVpcu+0n+u482vdwsUAeByE3opA99MYrlrZDjLYl40Y0kzWHK42Is3iBz03 B4VFKUrsUXa5bcquYPkr1oVycamH1QTwXtgkU6DspAjuR3tUQT4i7sSEnoV8pGl0 gLWpGABxhGde0Z0V/x14BNFJ+ZG2uiUpLvMJshqBle1kIj+CqySQMc3mFpkdBTUZ nyVVuVRc6+oGGfBujOvqFKuS9rOhpCSBBVwbq5/lPSgtvy2uBiiTwlFLMgPvV66X xQGbbgTxOjIdrL1i6smD/6RXkbIMKOFb/o4NAgMBAAGjgcYwgcMwHQYDVR0OBBYE FKgE4SRwWu2cxDhjzef4eUmUnR3aMB8GA1UdIwQYMBaAFKgE4SRwWu2cxDhjzef4 eUmUnR3aMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgHmMB0GA1Ud JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA+BgNVHREENzA1hwR/AAABhxAAAAAA AAAAAAAAAAAAAAABhxAAAAAAAAAAAAAA//9/AAABgglsb2NhbGhvc3QwDQYJKoZI hvcNAQELBQADggIBAIsl4jTS2dbrt7CStvwInf8InjaGqOrj4c0HDYVYBi33JkHx WasCJbjs+YWsQYcK3/rE9iYyZA/cwIE89x2ec1JX42SrayPLIdUF5VSo+DP3knTH Si7zt3igmziyKTsLoliISwOKwF5mdc+qeOE8CuExi7xIV4xlJxfM+XW6aeHdskof KSTd4qqzyO+wMezKb8u9/b0rMGNCvaM1etcWNlrfP2SXayLAfFkKypSbER1uIUzg ZnhSGyfYee6DrIATihPyOofjbUbqfF7MJtDTqTLhqhkndF+T7IR2LcR4XdtkxtdT F1WwKcM2FX/cjpdtGX76U6hPD6uWXDISk8IiS8HX10x0wamlVvK3zz9UsWwQp5DD EjG/XtMU59oAyiiGIbZllUWKOOabCcId8dvYZw4zoObCrYiYb2qvPcJPyUOzcCPn wsOS22lgTqEfoNzlrmh39YI8pvNDh+t0SkK8Nhllm4o/hIQkIxYlqsp4IkCnyxpO dgRMt2H+98FCNLGs3EIkmaeKD42OyglvdzM0IYHT2VDRfhwpjPvSEw/lJyYIi3R0 BEWNGA9Jx+BKZRxmyOerUqCMmImwMoLtKudEHpWz5bXcUkmqsmGXaHabVW7Z3nfN ZwdSLNHgHLNYBGe6Ak198CFHGmP/9XbV41cGNXctfe92baDv5IMgWOi35X5w -----END CERTIFICATE----- thrift-0.23.0/test/keys/client_v3.crt0000664000175000017500000000351615165535636017734 0ustar00buildbuild00000000000000-----BEGIN CERTIFICATE----- MIIFOTCCAyGgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBsTESMBAGA1UEAwwJbG9j YWxob3N0MSQwIgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0LmFwYWNoZS5vcmcxFjAU BgNVBAsMDUFwYWNoZSBUaHJpZnQxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29mdHdh cmUgRm91bmRhdGlvbjEUMBIGA1UEBwwLRm9yZXN0IEhpbGwxETAPBgNVBAgMCE1h cnlsYW5kMQswCQYDVQQGEwJVUzAeFw0yMjA2MzAyMjM3MzlaFw0zMDA5MTYyMjM3 MzlaMIGxMRIwEAYDVQQDDAlsb2NhbGhvc3QxJDAiBgkqhkiG9w0BCQEWFWRldkB0 aHJpZnQuYXBhY2hlLm9yZzEWMBQGA1UECwwNQXBhY2hlIFRocmlmdDEnMCUGA1UE CgweVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRQwEgYDVQQHDAtGb3Jl c3QgSGlsbDERMA8GA1UECAwITWFyeWxhbmQxCzAJBgNVBAYTAlVTMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsqPCAkuOxPmJ773z1KWaJyYWswj7zTVI Tm/uF0pIMSTzJh136Y7qJDMfKHZuO0EEEuvWgjxuDQCoi9G8lIyq3TV04scUmC0e QpZDizz3XRqW7F2nMzapyp9I2dG0mRwVTb/iWlSIvGfIiWQZaX32P9V7/0CWH3zY Bk7Sve9N5rymcjMQFR7aNlNpU4tw2Oa8Jz8d4CjsljeZQ8K2fE+R9fUN+aq0DQlv hiBuKHHUCpypNneLdc5XB6dUUAsTlq8OjbWLbUqAiK3gdrsIgfx9dxKcBoQxXrkj KM3/VAM2PNFVZ4nz6Klxt5n0QlZBsq4EQmcUxUr7JoVBFkeaJABiQwIDAQABo1ow WDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DA+BgNVHREENzA1hwR/AAABhxAAAAAA AAAAAAAAAAAAAAABhxAAAAAAAAAAAAAA//9/AAABgglsb2NhbGhvc3QwDQYJKoZI hvcNAQELBQADggIBAH8vPs4l8VITIOvuxPPtRngiUteSxU+MQ/oYbuASguNQ7s4f ZmCnBFQm7n0TvFkaR8nSCKrKy0ok3Dm+RflCySq37K/aI+6okQXPkBk4VVcCnd/l Z0V966pqibxrH5oLH69nOBelZPxpmcWy8ZgTYyNGph6GXQ0G5bFRpSNDjrMZjjtu Om40MEMO/k8eD1xXJnuVxdIic8XcSFSLAeTV2ye/stFkU50ZNJy8zAa4D97tTc9z AFgNgb3i08P6Rs8HYOmBY8DxOwFi32kEgsNDnh5oZMj69UwQUSYaFzh+uVPr1b9F qEN66unWJl1/bb9XATfIvLU2nmVXZ32O5POIRdx/mhPSDUtO11OHlnfyrWqjYIUk Q6+iKznR88w+aTQReL+85C71xtFa5UYeEjrsew9YdJZnfURh2gX8Lf8wxpiHatd9 msX5er86hqWsV/cbhTkeZiJyh2qP/LZF32VH1ztUkauK7/l3r15pKp9b0pDJl69O KC6MzRWIS7cn/m3Hl9Ghcp3wAS3jgmwNg0PQKlCsWTQ/cmd+9Piy/wx4sdvu8N/M b1lUrduLwO+NisfT+U4lI1aY100S5EjjyUXettorvdmt/947PbLxZgd4ydzXN1q8 jmoDZYxLFsbXR5NcbmJ8ldkKDf7E0NTGmHPuk5jM4EwmnnGttHMOnlgn+G5C -----END CERTIFICATE----- thrift-0.23.0/test/keys/server.p120000664000175000017500000001057515165535636017171 0ustar00buildbuild000000000000000‚y0‚? *†H†÷  ‚0‚,0‚(0‚_ *†H†÷  ‚P0‚L0‚E *†H†÷ 0 *†H†÷  0Û¡÷«:ºß€‚ª3}CdWÐö=wB<îÆôäŒÒš|ÃîNž°`ëìM´]®Òá÷z!ìc4&]ö‰9?/ÁÆúKDì 5G ôÛ÷¼Qⱞ¦ç­¸Omö 7”!’²ÚìoU¸“•õ.`êSÈ7n¾Ë]þÊx\0”dì—Æf»{›xjKh< ôFbMÜã›x³’ƒíå}%=†Ž«?OuþN:ÕhÁ)Ç’'Š¡€Qì[4À^BóNœ (Ô½Þñ[ò¶pÖä¶8Nz]m`IªËí|¥—“·´3¢ÊDöíÝ,EÅòx3VúŠkc±xSŠVæ¨ïG„ EÞh¾èešÆÄœÔ²¨È‹Ó]@0ñ¤Ô¨H>ôwbØ]Ð Í!J<À¸uf zå{ 9y–ºž¨ ÍXÓ iÜIoªž£•×ú£þ¼¡²‘ˆàŠø%J5¦‡iħ¼9¿¹§‰q+¼ÙÏQæ{òÕéH¥P¢;wŒH´¯0tr˜)^”5Í̺Si¼¦“ÖïìÙÿÅ}}¬xh|„i{†Ê¢bv2˜´I2À$‰£[œd;%°°Ï4Cß=¾|Œ1ê¯Z K3&å•;'¸Ëf¾Y’È;N‰†k¬}z~•tájSUµÂF—7¡ñõûxÇ¡…MÌ k°6ð"µúÐÔüÂŒ–€8Å«\HÖ½‘œb-ý¸ƒ@Ó UÖn¬ŒWÓ<ÐQð”ÊbY\ùI%Ùã±UØ+ŠÂ›¶µ kódÌŒSK‡¡Œ C1¬@ãIƒž/^rÍwÌÖ¦µm½^wµ0ãÕÿ^fbÙZ£B…;‰^zã-vŽ:°´R gþ?çÕ#.Š|)1]èr5’²”j¨(&¶,}x#› v¹xj›ôü0¦ª+t¤Â7…+¨²Þ«ŒñPJ¾4Ò¨æx8 ¹³9|·)Á¦ ´sÜ(Œ•¦)ipu E”u·Ýó×Ë‘am”¼‰¤¯„ø÷ýÈÓ¥B R³zÞG Ô&?ªr\Ÿä̰2©#þ°Z¯tÚZöÙA“m%Î2ÚŸñˆ\‡à „w”ÄòýO‡A/òÄZ;y©YÑÀ¸ä›lðâXÎ6·ËM@ÈžûIO…Ÿ®ê+ŸÐ•PNÙ‘aî#MÈ%ó¿zFÿY!¨#28w®óˆ`áY¾‡ws+ïÍòª¦”êØæóõÀ¨ˆr†s1Ïåðôa€¨)Gζ£éÑÇG¾Ëû. ¯Ž_/`øßËU€= ˆø²¡þÕ1îÔRs#„õH- 1:Ùã _¤_ºS´M{Ù°£´69;°? ƒ–`*÷œ7bnSå„zu(’bª¬–ÈB⬠á´ÍÍÖ”üp/@ÎT¶’¯;H^)ÚR$ÚÏH;jçÌ}ûÈ(Ô]ºÆ xˆ”e–¹R:PCt!éa5áÖoϱ!ÁÄÒ?©»=ÏË­¿Ìªd6æºÕ“GV>zÊ`ólppÿ¾‡nñÈ w´Õ± •ë*q¨R(Ø6ñQ-ï—±R`é^å4Pö¥ûEZ½ýÄ®½jÝÚ™F³=LñI檔œÌvÎ…]kÌ‹¤´0WRn\òQ—zÄk±a(™ŽøjŽô‰†õ—±•¢@pÃy Á³íQ2¾«½Ñ{Œ£Gø µøÃø[ORùÊj?è}É£þ¡8çZ·Sš^·-*§“ŒŸ1ÎW¹nsžŒ¾ˆÑ“rÕ¢O\˜¡ bìOƒ>qÎøõõhmiõêQÖtLŽfDêŸ2PT¥c•0è/­jÑÖ‰ËõªÁë»9ñoj4œG£…,T¤YÔâ‚þðp¬š§RP BO!†s²÷êd3åF–¢ý¥Œ•1㊡/6± ô{—›­‹ÍB¥ÀÛwóDç![éý²ôT„_ÝÜ‹¹é—ÈÖ÷5.=uQ7È/öàk<ˆtùcl.ÑÈe «@X×®fŽh¸N’¤ •T³ÄÇT”:b‚– ¿ÙÒs9UÝ-Ü£(9‹éÑ7O’]ÐСÝ2:&è `ߺ@q*ýgo“—ÙÀ”Ž™SÝàsF q6*Ø£üt$-ÉëŠSÛ¦³Á¢ÀAV…GÆR¸vÂY"mÉ‘Xr¦j£0@×÷$wKc±cÛZOm×v“ß÷ îz³Á\A°2ï ¿EíË¢êÔVQõ‹¨d+Þ×p­uÅh†(™-`¬¡>Þ4±[^UÐ y^ºuo>mã× ¹ºüá’)Q‘)€áþ0¯y½(N†²a9FQnUc bâ­U^xkzŒ •‹ãœÕW•ÖÛû«fgSòN¦/=,uË#}’=e´šÜþ®æý7p¤¨ÊÈUúê¯årXK$’t«X¯—…e,‰‚…fù9üp¦?âÃÍàO{køÙ¦¢ßðÈö?ð¥˜jê‚Ek뾫·ÙXð‡ÃMÐ|³2Š{¯RQ"tÕÁ„ Ý0ÎU¡g·@D°ö)Y3$›¿´`\B™&©U=þ‹"ªzþï§,±›z-æÎÒÁÒ/Â7¯‡1Ôù€Vú¸æ0á­|ÔcÞ%ËVþ즧8nsbËÖÚAÜQ½š2^öêS¦¤®ûJcauLF¬E¸ƒV2kÑcàÁ‰_{¢Îü@Gy¸P Ø¡Xœ†÷¸Ó´¬,ßß½’Ûša-óœ¶Gº¿V¡)#w«ªÉí%Ä‡â¦Æ¹¸lñßôº læ§*‘K‘EÕIIä‡-?ÉÅö‹+< ª„އ„°§qÔe¦K.¹,‰6;_Òi²¶\_Ö¹¤=7*áôÙìÆÅ#ë:¡µºsõaÉ__5 ‹ÞS™Lt1 ˆmí{EŠ&¥¬^*»­r ¸³qÛÝßOvZ}uÑÂ1ò]bIÚÆÁÇ)ÕÀÎ_n¶ørðô%=ðØù>µBM¹C*ÚÇF¹º›Û¸0˳]·ÛoÙ¨VH§¯ÜZÈ{_Èñ焹ý•uä:° Ãûmˆ£SRpòRù¢]Yñ_ò¼˜ËxwoD®mcÌ“èm¿$À¶¬uéŸ ìÞ˜»9ÌÊ0·u6™vÎ=\~JaúÃ¥ YWÛáH€[ìk®xŠ”„{ 'U Ž¥®Gå3½ªXõ¦0y’/¡û0ß‹H³¨ñ«©OpT÷ÅÆSÓ“@—«öy¯|Üž=Áƒä R(a¾Ä[QBY½fè\ˆ÷¦on!7ß›ýÒ„t©¹±Zð ¥éÎd5]¤®KÄ•ÁŒ 6TFÕ»f!€Ùòr¿ß6©ôµ$ì,û 1EUÌ…û›ß¤ñ´g:ÏÇïC&«4»wE>Òænc!:÷Íæ¹^·¿º©…à•­L¡ÂÒЭp ZEþÆ‘[|g~ %~Ê›ñ~‹K29“ˆ8…so/ŠQdÙÎÐå«LHTWÂk¨½ÑhAm˜ßëµ€5ÙÂ,ü`w˜/¥Rz ç2;sÓê+ü¾I%¢`,(Œ·ãOj¯ëÃo[)S€Òò L ÂIŸ505™j–ÖìX4Ž?÷ЇâE´ÀÒ¿Ï?âᢑ¢HC÷ƒJfÛÅžÈÅ}ŒÞ²ì²`D|ß$Š@5­®D;ˆëØ4s®òøòRn6è fÁ7CÇÖš±Ü,¦ÜëõÓª­Cî«ß{Wn%=ýªÞŸÆÎÄS¶@ |.’G¾»ÖS‹èwŽ-‘û"½¡l…æÌ^ó.‡£œùÒ-wé )«ëûèªqÛò‹Q]¿'Ú"g8ùOÜ„c Gñ[z|ý—1!ö+ºç¿€NgCm¶ü¹ j‡²vöU?1 "*zØ1A+•üÀ3ç:³Ü¯ùRdä×G¢#À/ÌpêMµÊ[xuuy+žÓtŒhœVòòËC^œOd …f£hÌÑ1é—À³Bà4O»kÙŸ1ê–çÁy Åä1—<1%0# *†H†÷  1ª}Ô×\¥T¤Ï ]Fue©Ù‚F010!0 +ÚM°!ªäÖfS'ЍÀe<ô‚mÊ™¹Ãlthrift-0.23.0/test/keys/README.md0000664000175000017500000000603015165535636016605 0ustar00buildbuild00000000000000# Test Keys and Certificates This folder is dedicated to test keys and certificates provided in multiple formats. Primary use are unit test suites and cross language tests. test/keys **The files in this directory must never be used on production systems.** ## SSL Keys and Certificates ## create certificates we use the following parameters for test key and certificate creation C=US, ST=Maryland, L=Forest Hill, O=The Apache Software Foundation, OU=Apache Thrift, CN=localhost/emailAddress=dev@thrift.apache.org ### create self-signed server key and certificate openssl req -new -x509 -nodes -days 3000 -out server.crt -keyout server.key openssl x509 -in server.crt -text > CA.pem cat server.crt server.key > server.pem Export password is "thrift" without the quotes openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12 ### create client key and certificate openssl genrsa -out client.key create a signing request: openssl req -new -key client.key -out client.csr sign the client certificate with the server.key openssl x509 -req -days 3000 -in client.csr -CA CA.pem -CAkey server.key -set_serial 01 -out client.crt export certificate in PKCS12 format (Export password is "thrift" without the quotes) openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 export certificate in PEM format for OpenSSL usage openssl pkcs12 -in client.p12 -out client.pem -clcerts ### create client key and certificate with altnames copy openssl.cnf from your system e.g. /etc/ssl/openssl.cnf and append following to the end of [ v3_req ] subjectAltName=@alternate_names [ alternate_names ] IP.1=127.0.0.1 IP.2=::1 IP.3=::ffff:127.0.0.1 create a signing request: openssl req -new -key client_v3.key -out client_v3.csr -config openssl.cnf \ -subj "/C=US/ST=Maryland/L=Forest Hill/O=The Apache Software Foundation/OU=Apache Thrift/CN=localhost" -extensions v3_req sign the client certificate with the server.key openssl x509 -req -days 3000 -in client_v3.csr -CA CA.pem -CAkey server.key -set_serial 01 -out client_v3.crt -extensions v3_req -extfile openssl.cnf ## Java key and certificate import Java Test Environment uses key and trust store password "thrift" without the quotes list keystore entries keytool -list -storepass thrift -keystore ../../lib/java/test/.keystore list truststore entries keytool -list -storepass thrift -keystore ../../lib/java/test/.truststore delete an entry keytool -delete -storepass thrift -keystore ../../lib/java/test/.truststore -alias ssltest import certificate into truststore keytool -importcert -storepass thrift -keystore ../../lib/java/test/.truststore -alias localhost --file server.crt import key into keystore keytool -importkeystore -storepass thrift -keystore ../../lib/java/test/.keystore -srcstoretype pkcs12 -srckeystore server.p12 # Test SSL server and clients openssl s_client -connect localhost:9090 openssl s_server -accept 9090 -www thrift-0.23.0/test/keys/server.crt0000664000175000017500000000452615165535636017356 0ustar00buildbuild00000000000000-----BEGIN CERTIFICATE----- MIIGuTCCBKGgAwIBAgIUDG+EIHE1EFeuj0ddWtxGQAPatt8wDQYJKoZIhvcNAQEL BQAwgbExEjAQBgNVBAMMCWxvY2FsaG9zdDEkMCIGCSqGSIb3DQEJARYVZGV2QHRo cmlmdC5hcGFjaGUub3JnMRYwFAYDVQQLDA1BcGFjaGUgVGhyaWZ0MScwJQYDVQQK DB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xFDASBgNVBAcMC0ZvcmVz dCBIaWxsMREwDwYDVQQIDAhNYXJ5bGFuZDELMAkGA1UEBhMCVVMwHhcNMjIwNjMw MjIzNzI4WhcNMzAwOTE2MjIzNzI4WjCBsTESMBAGA1UEAwwJbG9jYWxob3N0MSQw IgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0LmFwYWNoZS5vcmcxFjAUBgNVBAsMDUFw YWNoZSBUaHJpZnQxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRh dGlvbjEUMBIGA1UEBwwLRm9yZXN0IEhpbGwxETAPBgNVBAgMCE1hcnlsYW5kMQsw CQYDVQQGEwJVUzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM/uam3B XjI0x6hfdqdr4ATbiDA7niD8MShpyqBmdpMWu7ng91grZPCDl7T/6xCrdT92NI7m CpnA5hBK/0W8+5Y8NnKjkwZym9H5kO18FQ+hH1mJq3bx57mxsZAE1Iwbr21W/Kxh 6Jx279ayywVAU6l9cH/aS5t3pl0qZUysBi3me2J88z6oYA3FNRaxX3kO4I8iJjYu vIfpWmXf8By/TOLzNkR1pJLXe849tAGrTtm+goLw59RMhIgxlS05DH3nGNKamWQ4 gr2H5do+2pFzKoom4vCryKgc/NXyEQNc/1FRJsi3/XK/NlezoPw+xV33AeDopmmK VsQ4RJONyVlgksCD2Q2odrCR/ryqirA5BTH8pQFfvCQfr4G6zkSzSDBTC9ZI2IIx JFs87mVpcu+0n+u482vdwsUAeByE3opA99MYrlrZDjLYl40Y0kzWHK42Is3iBz03 B4VFKUrsUXa5bcquYPkr1oVycamH1QTwXtgkU6DspAjuR3tUQT4i7sSEnoV8pGl0 gLWpGABxhGde0Z0V/x14BNFJ+ZG2uiUpLvMJshqBle1kIj+CqySQMc3mFpkdBTUZ nyVVuVRc6+oGGfBujOvqFKuS9rOhpCSBBVwbq5/lPSgtvy2uBiiTwlFLMgPvV66X xQGbbgTxOjIdrL1i6smD/6RXkbIMKOFb/o4NAgMBAAGjgcYwgcMwHQYDVR0OBBYE FKgE4SRwWu2cxDhjzef4eUmUnR3aMB8GA1UdIwQYMBaAFKgE4SRwWu2cxDhjzef4 eUmUnR3aMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgHmMB0GA1Ud JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA+BgNVHREENzA1hwR/AAABhxAAAAAA AAAAAAAAAAAAAAABhxAAAAAAAAAAAAAA//9/AAABgglsb2NhbGhvc3QwDQYJKoZI hvcNAQELBQADggIBAIsl4jTS2dbrt7CStvwInf8InjaGqOrj4c0HDYVYBi33JkHx WasCJbjs+YWsQYcK3/rE9iYyZA/cwIE89x2ec1JX42SrayPLIdUF5VSo+DP3knTH Si7zt3igmziyKTsLoliISwOKwF5mdc+qeOE8CuExi7xIV4xlJxfM+XW6aeHdskof KSTd4qqzyO+wMezKb8u9/b0rMGNCvaM1etcWNlrfP2SXayLAfFkKypSbER1uIUzg ZnhSGyfYee6DrIATihPyOofjbUbqfF7MJtDTqTLhqhkndF+T7IR2LcR4XdtkxtdT F1WwKcM2FX/cjpdtGX76U6hPD6uWXDISk8IiS8HX10x0wamlVvK3zz9UsWwQp5DD EjG/XtMU59oAyiiGIbZllUWKOOabCcId8dvYZw4zoObCrYiYb2qvPcJPyUOzcCPn wsOS22lgTqEfoNzlrmh39YI8pvNDh+t0SkK8Nhllm4o/hIQkIxYlqsp4IkCnyxpO dgRMt2H+98FCNLGs3EIkmaeKD42OyglvdzM0IYHT2VDRfhwpjPvSEw/lJyYIi3R0 BEWNGA9Jx+BKZRxmyOerUqCMmImwMoLtKudEHpWz5bXcUkmqsmGXaHabVW7Z3nfN ZwdSLNHgHLNYBGe6Ak198CFHGmP/9XbV41cGNXctfe92baDv5IMgWOi35X5w -----END CERTIFICATE----- thrift-0.23.0/test/keys/keygen/0000775000175000017500000000000015170007202016564 5ustar00buildbuild00000000000000thrift-0.23.0/test/keys/keygen/make-serverkey.sh0000664000175000017500000000776015165535636022111 0ustar00buildbuild00000000000000#!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # tested with git bash on Windows # probably needs a bit of tweaking for other environments # re the "//SKIP=this" in sub see at https://stackoverflow.com/a/54924640/499466 echo init folder rm *.p12 2> /dev/null rm *.pem 2> /dev/null rm *.crt 2> /dev/null rm *.key 2> /dev/null rm *.cfg 2> /dev/null rm *.csr 2> /dev/null #cp ../*.key . echo writing config echo '[ req ]' > my.cfg echo 'default_bits= 4096' >> my.cfg echo 'distinguished_name=req' >> my.cfg echo 'x509_extensions = v3_ca' >> my.cfg echo 'req_extensions = v3_req' >> my.cfg echo '' >> my.cfg echo '[ v3_req ]' >> my.cfg echo 'basicConstraints = CA:FALSE' >> my.cfg echo 'keyUsage = nonRepudiation, digitalSignature, keyEncipherment' >> my.cfg echo 'subjectAltName=@alternate_names' >> my.cfg echo '' >> my.cfg echo '[ alternate_names ]' >> my.cfg echo 'IP.1=127.0.0.1' >> my.cfg echo 'IP.2=::1' >> my.cfg echo 'IP.3=::ffff:127.0.0.1' >> my.cfg echo 'DNS.1=localhost' >> my.cfg echo '' >> my.cfg echo '[ v3_ca ]' >> my.cfg echo 'subjectKeyIdentifier=hash' >> my.cfg echo 'authorityKeyIdentifier=keyid:always,issuer' >> my.cfg echo 'basicConstraints = critical, CA:TRUE, pathlen:0' >> my.cfg echo 'keyUsage = critical, cRLSign, keyCertSign, nonRepudiation, digitalSignature, keyEncipherment' >> my.cfg echo 'extendedKeyUsage = serverAuth, clientAuth' >> my.cfg echo 'subjectAltName=@alternate_names' >> my.cfg echo '' >> my.cfg echo echo step 1a winpty openssl req \ -new \ -x509 \ -nodes \ -days 3000 \ -out server.crt \ -keyout server.key \ -subj '//SKIP=this/CN=localhost/emailAddress=dev@thrift.apache.org/OU=Apache Thrift/O=The Apache Software Foundation/L=Forest Hill/ST=Maryland/C=US' \ -extensions v3_ca \ -config my.cfg echo echo step 1b openssl x509 -in server.crt -text > CA.pem echo echo step 1c cat server.crt server.key > server.pem echo echo step 2 echo 'Use "thrift" as password (without the quotes)' winpty openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12 echo echo step 3 winpty openssl genrsa -out client.key echo echo step 4 winpty openssl req \ -new \ -subj '//SKIP=this/CN=localhost/emailAddress=dev@thrift.apache.org/OU=Apache Thrift/O=The Apache Software Foundation/L=Forest Hill/ST=Maryland/C=US' \ -key client.key \ -out client.csr echo echo step 5 winpty openssl x509 -req -days 3000 -in client.csr -CA CA.pem -CAkey server.key -set_serial 01 -out client.crt echo echo step 6 winpty openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 echo echo step 7 winpty openssl pkcs12 -in client.p12 -out client.pem -clcerts echo echo step 8a openssl genrsa -out client_v3.key echo echo step 8b winpty openssl req \ -new \ -subj '//SKIP=this/CN=localhost/emailAddress=dev@thrift.apache.org/OU=Apache Thrift/O=The Apache Software Foundation/L=Forest Hill/ST=Maryland/C=US' \ -key client_v3.key \ -out client_v3.csr \ -extensions v3_req \ -config my.cfg echo echo step 9 winpty openssl x509 -req -days 3000 -in client_v3.csr -CA CA.pem -CAkey server.key -set_serial 01 -out client_v3.crt -extensions v3_req -extfile my.cfg echo echo cleanup rm *.cfg 2> /dev/null rm *.csr 2> /dev/null echo echo test openssl s_client -connect localhost:9090 & openssl s_server -accept 9090 -www echo echo done thrift-0.23.0/test/UnsafeTypes.thrift0000664000175000017500000000155315165535636020050 0ustar00buildbuild00000000000000/* * 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 java thrift.test struct UnsafeBytes { 1: binary bytes; } thrift-0.23.0/test/OptionalRequiredTest.thrift0000664000175000017500000000420415165535636021724 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace c_glib TTest namespace cpp thrift.test namespace java thrift.test struct OldSchool { 1: i16 im_int; 2: string im_str; 3: list> im_big; } struct Simple { 1: /* :) */ i16 im_default; 2: required i16 im_required; 3: optional i16 im_optional; } struct Tricky1 { 1: /* :) */ i16 im_default; } struct Tricky2 { 1: optional i16 im_optional; } struct Tricky3 { 1: required i16 im_required; } struct OptionalDefault { 1: optional i16 opt_int = 1234; 2: optional string opt_str = "default"; } struct Complex { 1: i16 cp_default; 2: required i16 cp_required; 3: optional i16 cp_optional; 4: map the_map; 5: required Simple req_simp; 6: optional Simple opt_simp; } struct ManyOpt { 1: optional i32 opt1; 2: optional i32 opt2; 3: optional i32 opt3; 4: i32 def4; 5: optional i32 opt5; 6: optional i32 opt6; } struct JavaTestHelper { 1: required i32 req_int; 2: optional i32 opt_int; 3: required string req_obj; 4: optional string opt_obj; 5: required binary req_bin; 6: optional binary opt_bin; } struct Binaries { 4: binary bin; 5: required binary req_bin; 6: optional binary opt_bin; } thrift-0.23.0/test/VoidMethExceptionsTest.thrift0000664000175000017500000000254315165535636022223 0ustar00buildbuild00000000000000/* * 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 java thrift.test.voidmethexceptions exception TExampleException { 1: required string message; } service TAppService01 { string returnString(1: string msg, 2: bool throwException) throws (1:TExampleException error); void returnVoidThrows(1: string msg, 2: bool throwException) throws (1:TExampleException error); void returnVoidNoThrowsRuntimeException(1: string msg, 2: bool throwException); void returnVoidNoThrowsTApplicationException(1: string msg, 2: bool throwException); oneway void onewayVoidNoThrows(1: string msg, 2: bool throwException); } thrift-0.23.0/test/DoubleConstantsTest.thrift0000664000175000017500000000361115165535636021546 0ustar00buildbuild00000000000000/* * 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 java thrift.test namespace cpp thrift.test // more tests on double constants (precision and type checks) const double DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST = 1 const double DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST = -100 const double DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST = 9223372036854775807 const double DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST = -9223372036854775807 const double DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST = 3.14159265359 const double DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST = 1000000.1 const double DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST = -1000000.1 const double DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST = 1.7e+308 const double DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST = 9223372036854775816.43 const double DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST = -1.7e+308 const double DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST = -9223372036854775816.43 const list DOUBLE_LIST_TEST = [1,-100,100,9223372036854775807,-9223372036854775807,3.14159265359,1000000.1,-1000000.1,1.7e+308,-1.7e+308,9223372036854775816.43,-9223372036854775816.43] thrift-0.23.0/test/Include.thrift0000664000175000017500000000160315165535636017161 0ustar00buildbuild00000000000000/* * 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 "v0.16/ThriftTest.thrift" struct IncludeTest { 1: required ThriftTest.Bools bools }thrift-0.23.0/test/ExceptionStruct.thrift0000664000175000017500000000307315165535636020744 0ustar00buildbuild00000000000000/* * 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 thrift-0.23.0/test/ConstantsDemo.thrift0000664000175000017500000000561215167543515020360 0ustar00buildbuild00000000000000/* * 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 yozone namespace erl consts_ namespace haxe constantsDemo namespace go constantsdemo namespace rb ConstantsDemo typedef uuid myUUID struct thing { 1: i32 hello, 2: i32 goodbye 3: uuid id 4: myUUID my_id 5: optional myUUID my_optional_id } enum enumconstants { ONE = 1, TWO = 2 } // struct thing2 { // /** standard docstring */ // 1: enumconstants val = TWO // } typedef i32 myIntType const myIntType myInt = 3 //const map GEN_ENUM_NAMES = {ONE : "HOWDY", TWO: "PARTNER"} const i32 hex_const = 0x0001F const i32 negative_hex_constant = -0x0001F const i32 GEN_ME = -3523553 const double GEn_DUB = 325.532 const double GEn_DU = 085.2355 const string GEN_STRING = "asldkjasfd" const double e10 = 1e10 // fails with 0.9.3 and earlier const double e11 = -1e10 // uuids are accepted with or without curly braces const uuid GEN_UUID = '00000000-4444-CCCC-ffff-0123456789ab' const uuid GEN_GUID = '{00112233-4455-6677-8899-aaBBccDDeeFF}' const myUUID MY_UUID = '00000000-4444-CCCC-ffff-0123456789ab' const myUUID MY_GUID = '{00112233-4455-6677-8899-aaBBccDDeeFF}' const map GEN_MAP = { 35532 : 233, 43523 : 853 } const list GEN_LIST = [ 235235, 23598352, 3253523 ] const map> GEN_MAPMAP = { 235 : { 532 : 53255, 235:235}} const map GEN_MAP2 = { "hello" : 233, "lkj98d" : 853, 'lkjsdf' : 098325 } const thing GEN_THING = { 'hello' : 325, 'goodbye' : 325352, 'id' : '{00112233-4455-6677-8899-aaBBccDDeeFF}', 'my_id': '00000000-4444-CCCC-ffff-0123456789ab', 'my_optional_id': '00000000-4444-CCCC-ffff-0123456789ab' } const map GEN_WHAT = { 35 : { 'hello' : 325, 'goodbye' : 325352, 'id' : '00000000-4444-CCCC-ffff-0123456789ab', 'my_id': '00000000-4444-CCCC-ffff-0123456789ab', 'my_optional_id': '00000000-4444-CCCC-ffff-0123456789ab' } } const set GEN_SET = [ 235, 235, 53235 ] const set GUID_SET = [ '{00112233-4455-6677-8899-aaBBccDDeeFF}', '00000000-4444-CCCC-ffff-0123456789ab' ] exception Blah { 1: i32 bing } exception Gak {} service yowza { void blingity(), i32 blangity() throws (1: Blah hoot ) } thrift-0.23.0/test/EnumContainersTest.thrift0000664000175000017500000000264515165535636021377 0ustar00buildbuild00000000000000/* * 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 java thrift.test.enumcontainers enum GreekGodGoddess { ARES, APHRODITE, ZEUS, POSEIDON, HERA, } typedef GreekGodGoddess GreekGodGoddessType typedef i32 Power struct GodBean { 1: optional map power, 2: optional set goddess, 3: optional map byAlias, 4: optional set images, } const map ATTRIBUTES = { GreekGodGoddess.ZEUS: "lightning bolt", GreekGodGoddess.POSEIDON: "trident", } const set BEAUTY = [ GreekGodGoddess.APHRODITE, GreekGodGoddess.HERA ] thrift-0.23.0/test/DocTest.thrift0000664000175000017500000001416715165535636017154 0ustar00buildbuild00000000000000/* * 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. */ /** * Program doctext. * * Seriously, this is the documentation for this whole program. */ namespace java thrift.test namespace cpp thrift.test // C++ comment /* c style comment */ # the new unix comment /** Some doc text goes here. Wow I am [nesting these] (no more nesting.) */ enum Numberz { /** This is how to document a parameter */ ONE = 1, /** And this is a doc for a parameter that has no specific value assigned */ TWO, THREE, FIVE = 5, SIX, EIGHT = 8 } /** This is how you would do a typedef doc */ typedef i64 UserId /** And this is where you would document a struct */ struct Xtruct { /** And the members of a struct */ 1: string string_thing /** doct text goes before a comma */ 4: i8 byte_thing, 9: i32 i32_thing, 11: i64 i64_thing } /** * You can document constants now too. Yeehaw! */ const i32 INT32CONSTANT = 9853 const i16 INT16CONSTANT = 1616 /** Everyone get in on the docu-action! */ const map MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} struct Xtruct2 { 1: i8 byte_thing, 2: Xtruct struct_thing, 3: i32 i32_thing } /** Struct insanity */ struct Insanity { /** This is doc for field 1 */ 1: map userMap, /** And this is doc for field 2 */ 2: list xtructs } exception Xception { 1: i32 errorCode, 2: string message } exception Xception2 { 1: i32 errorCode, 2: Xtruct struct_thing } /* C1 */ /** Doc */ /* C2 */ /* C3 */ struct EmptyStruct {} struct OneField { 1: EmptyStruct field } /** This is where you would document a Service */ service ThriftTest { /** And this is how you would document functions in a service */ void testVoid(), string testString(1: string thing), i8 testByte(1: byte thing), i32 testI32(1: i32 thing), /** Like this one */ i64 testI64(1: i64 thing), double testDouble(1: double thing), Xtruct testStruct(1: Xtruct thing), Xtruct2 testNest(1: Xtruct2 thing), map testMap(1: map thing), set testSet(1: set thing), list testList(1: list thing), /** This is an example of a function with params documented */ Numberz testEnum( /** This param is a thing */ 1: Numberz thing ), UserId testTypedef(1: UserId thing), map> testMapMap(1: i32 hello), /* So you think you've got this all worked, out eh? */ map> testInsanity(1: Insanity argument), } /// This style of Doxy-comment doesn't work. typedef i32 SorryNoGo /** * This is a trivial example of a multiline docstring. */ typedef i32 TrivialMultiLine /** * This is the canonical example * of a multiline docstring. */ typedef i32 StandardMultiLine /** * The last line is non-blank. * I said non-blank! */ typedef i32 LastLine /** Both the first line * are non blank. ;-) * and the last line */ typedef i32 FirstAndLastLine /** * INDENTED TITLE * The text is less indented. */ typedef i32 IndentedTitle /** First line indented. * Unfortunately, this does not get indented. */ typedef i32 FirstLineIndent /** * void code_in_comment() { * printf("hooray code!"); * } */ typedef i32 CodeInComment /** * Indented Docstring. * This whole docstring is indented. * This line is indented further. */ typedef i32 IndentedDocstring /** Irregular docstring. * We will have to punt * on this thing */ typedef i32 Irregular1 /** * note the space * before these lines * but not this * one */ typedef i32 Irregular2 /** * Flush against * the left. */ typedef i32 Flush /** No stars in this one. It should still work fine, though. Including indenting. */ typedef i32 NoStars /** Trailing whitespace Sloppy trailing whitespace is truncated. */ typedef i32 TrailingWhitespace /** * This is a big one. * * We'll have some blank lines in it. * * void as_well_as(some code) { * puts("YEEHAW!"); * } */ typedef i32 BigDog /** * * */ typedef i32 TotallyDegenerate /**no room for newline here*/ /* * / */ typedef i32 TestFor3501a /** * / */ typedef i32 TestFor3501b /* Comment-end tokens can of course have more than one asterisk */ struct TestFor3709_00 { /* ? */ 1: i32 foo } /* Comment-end tokens can of course have more than one asterisk **/ struct TestFor3709_01 { /* ? */ 1: i32 foo } /* Comment-end tokens can of course have more than one asterisk ***/ struct TestFor3709_02 { /* ? */ 1: i32 foo } /** Comment-end tokens can of course have more than one asterisk */ struct TestFor3709_03 { /* ? */ 1: i32 foo } /** Comment-end tokens can of course have more than one asterisk **/ struct TestFor3709_04 { /* ? */ 1: i32 foo } /** Comment-end tokens can of course have more than one asterisk ***/ struct TestFor3709_05 { /* ? */ 1: i32 foo } /*** Comment-end tokens can of course have more than one asterisk */ struct TestFor3709_06 { /* ? */ 1: i32 foo } /*** Comment-end tokens can of course have more than one asterisk **/ struct TestFor3709_07 { /* ? */ 1: i32 foo } /*** Comment-end tokens can of course have more than one asterisk ***/ struct TestFor3709_08 { /* ? */ 1: i32 foo } struct TestFor3709 { /** This is a comment */ 1: required string id, /** This is also a comment **/ 2: required string typeId, /** Yet another comment! */ 3: required i32 endTimestamp } /* THE END */ thrift-0.23.0/test/BrokenConstants.thrift0000664000175000017500000000164315165535636020717 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const i64 myint = 68719476736 const i64 broken = 9876543210987654321 // A little over 2^63 enum foo { bar = 68719476736 } thrift-0.23.0/test/Recursive.thrift0000664000175000017500000000222715165535636017550 0ustar00buildbuild00000000000000/* * 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 RecTree { 1: list children 2: i16 item } struct RecList { 1: RecList & nextitem 3: i16 item } struct CoRec { 1: CoRec2 & other } struct CoRec2 { 1: CoRec other } struct VectorTest { 1: list lister; } service TestService { RecTree echoTree(1:RecTree tree) RecList echoList(1:RecList lst) CoRec echoCoRec(1:CoRec item) } thrift-0.23.0/test/ThriftTest.thrift0000664000175000017500000002670715165535636017712 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace c_glib TTest namespace cpp thrift.test namespace delphi Thrift.Test namespace go thrifttest namespace java thrift.test namespace js ThriftTest namespace lua ThriftTest namespace netstd ThriftTest namespace perl ThriftTest namespace php ThriftTest namespace py ThriftTest namespace py.twisted ThriftTest namespace rb Thrift.Test namespace st ThriftTest namespace xsd test (uri = 'http://thrift.apache.org/ns/ThriftTest') // Presence of namespaces and sub-namespaces for which there is // no generator should compile with warnings only namespace noexist ThriftTest namespace cpp.noexist ThriftTest namespace * thrift.test /** * Docstring! */ enum Numberz { ONE = 1, TWO, THREE, FIVE = 5, SIX, EIGHT = 8 } const Numberz myNumberz = Numberz.ONE; // the following is expected to fail: // const Numberz urNumberz = ONE; typedef i64 UserId struct Bonk { 1: string message, 2: i32 type } typedef map MapType struct Bools { 1: bool im_true, 2: bool im_false, } struct Xtruct { 1: string string_thing, 4: i8 byte_thing, 9: i32 i32_thing, 11: i64 i64_thing } struct Xtruct2 { 1: i8 byte_thing, // used to be byte, hence the name 2: Xtruct struct_thing, 3: i32 i32_thing } struct Xtruct3 { 1: string string_thing, 4: i32 changed, 9: i32 i32_thing, 11: i64 i64_thing } struct Insanity { 1: map userMap, 2: list xtructs } (python.immutable= "") struct CrazyNesting { 1: string string_field, 2: optional set set_field, // Do not insert line break as test/go/Makefile.am is removing this line with pattern match 3: required list (python.immutable = ""), map(python.immutable = "")> (python.immutable = "")>>>> list_field, 4: binary binary_field 5: uuid uuid_field } union SomeUnion { 1: map map_thing, 2: string string_thing, 3: i32 i32_thing, 4: Xtruct3 xtruct_thing, 5: Insanity insanity_thing } exception Xception { 1: i32 errorCode, 2: string message } exception Xception2 { 1: i32 errorCode, 2: Xtruct struct_thing } struct EmptyStruct {} struct OneField { 1: EmptyStruct field } service ThriftTest { /** * Prints "testVoid()" and returns nothing. */ void testVoid(), /** * Prints 'testString("%s")' with thing as '%s' * @param string thing - the string to print * @return string - returns the string 'thing' */ string testString(1: string thing), /** * Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false' * @param bool thing - the bool data to print * @return bool - returns the bool 'thing' */ bool testBool(1: bool thing), /** * Prints 'testByte("%d")' with thing as '%d' * The types i8 and byte are synonyms, use of i8 is encouraged, byte still exists for the sake of compatibility. * @param byte thing - the i8/byte to print * @return i8 - returns the i8/byte 'thing' */ i8 testByte(1: i8 thing), /** * Prints 'testI32("%d")' with thing as '%d' * @param i32 thing - the i32 to print * @return i32 - returns the i32 'thing' */ i32 testI32(1: i32 thing), /** * Prints 'testI64("%d")' with thing as '%d' * @param i64 thing - the i64 to print * @return i64 - returns the i64 'thing' */ i64 testI64(1: i64 thing), /** * Prints 'testDouble("%f")' with thing as '%f' * @param double thing - the double to print * @return double - returns the double 'thing' */ double testDouble(1: double thing), /** * Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data * @param binary thing - the binary data to print * @return binary - returns the binary 'thing' */ binary testBinary(1: binary thing), /** * Prints 'testUuid("%s")' where '%s' is the uuid given. Note that the uuid byte order should be correct. * @param uuid thing - the uuid to print * @return uuid - returns the uuid 'thing' */ uuid testUuid(1: uuid thing), /** * Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values * @param Xtruct thing - the Xtruct to print * @return Xtruct - returns the Xtruct 'thing' */ Xtruct testStruct(1: Xtruct thing), /** * Prints 'testNest("{%s}")' where thing has been formatted into a string of the nested struct * @param Xtruct2 thing - the Xtruct2 to print * @return Xtruct2 - returns the Xtruct2 'thing' */ Xtruct2 testNest(1: Xtruct2 thing), /** * Prints 'testMap("{%s")' where thing has been formatted into a string of 'key => value' pairs * separated by commas and new lines * @param map thing - the map to print * @return map - returns the map 'thing' */ map testMap(1: map thing), /** * Prints 'testStringMap("{%s}")' where thing has been formatted into a string of 'key => value' pairs * separated by commas and new lines * @param map thing - the map to print * @return map - returns the map 'thing' */ map testStringMap(1: map thing), /** * Prints 'testSet("{%s}")' where thing has been formatted into a string of values * separated by commas and new lines * @param set thing - the set to print * @return set - returns the set 'thing' */ set testSet(1: set thing), /** * Prints 'testList("{%s}")' where thing has been formatted into a string of values * separated by commas and new lines * @param list thing - the list to print * @return list - returns the list 'thing' */ list testList(1: list thing), /** * Prints 'testEnum("%d")' where thing has been formatted into its numeric value * @param Numberz thing - the Numberz to print * @return Numberz - returns the Numberz 'thing' */ Numberz testEnum(1: Numberz thing), /** * Prints 'testTypedef("%d")' with thing as '%d' * @param UserId thing - the UserId to print * @return UserId - returns the UserId 'thing' */ UserId testTypedef(1: UserId thing), /** * Prints 'testMapMap("%d")' with hello as '%d' * @param i32 hello - the i32 to print * @return map> - returns a dictionary with these values: * {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, } */ map> testMapMap(1: i32 hello), /** * So you think you've got this all worked out, eh? * * Creates a map with these values and prints it out: * { 1 => { 2 => argument, * 3 => argument, * }, * 2 => { 6 => , }, * } * @return map> - a map with the above values */ map> testInsanity(1: Insanity argument), /** * Prints 'testMulti()' * @param i8 arg0 - * @param i32 arg1 - * @param i64 arg2 - * @param map arg3 - * @param Numberz arg4 - * @param UserId arg5 - * @return Xtruct - returns an Xtruct with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1 * and i64_thing = arg2 */ Xtruct testMulti(1: i8 arg0, 2: i32 arg1, 3: i64 arg2, 4: map arg3, 5: Numberz arg4, 6: UserId arg5), /** * Print 'testException(%s)' with arg as '%s' * @param string arg - a string indication what type of exception to throw * if arg == "Xception" throw Xception with errorCode = 1001 and message = arg * else if arg == "TException" throw TException * else do not throw anything */ void testException(1: string arg) throws(1: Xception err1), /** * Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s' * @param string arg - a string indicating what type of exception to throw * if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception" * else if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and struct_thing.string_thing = "This is an Xception2" * else do not throw anything * @return Xtruct - an Xtruct with string_thing = arg1 */ Xtruct testMultiException(1: string arg0, 2: string arg1) throws(1: Xception err1, 2: Xception2 err2) /** * Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d' * sleep 'secondsToSleep' * Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d' * @param i32 secondsToSleep - the number of seconds to sleep */ oneway void testOneway(1:i32 secondsToSleep) } service SecondService { /** * Prints 'testString("%s")' with thing as '%s' * @param string thing - the string to print * @return string - returns the string 'thing' */ string secondtestString(1: string thing) } struct VersioningTestV1 { 1: i32 begin_in_both, 3: string old_string, 12: i32 end_in_both } struct VersioningTestV2 { 1: i32 begin_in_both, 2: i32 newint, 3: i8 newbyte, 4: i16 newshort, 5: i64 newlong, 6: double newdouble 7: Bonk newstruct, 8: list newlist, 9: set newset, 10: map newmap, 11: string newstring, 12: i32 end_in_both } struct ListTypeVersioningV1 { 1: list myints; 2: string hello; } struct ListTypeVersioningV2 { 1: list strings; 2: string hello; } struct GuessProtocolStruct { 7: map map_field, } struct LargeDeltas { 1: Bools b1, 10: Bools b10, 100: Bools b100, 500: bool check_true, 1000: Bools b1000, 1500: bool check_false, 2000: VersioningTestV2 vertwo2000, 2500: set a_set2500, 3000: VersioningTestV2 vertwo3000, 4000: list big_numbers } struct NestedListsI32x2 { 1: list> integerlist } struct NestedListsI32x3 { 1: list>> integerlist } struct NestedMixedx2 { 1: list> int_set_list 2: map> map_int_strset 3: list>> map_int_strset_list } struct ListBonks { 1: list bonk } struct NestedListsBonk { 1: list>> bonk } struct BoolTest { 1: optional bool b = true; 2: optional string s = "true"; } struct StructA { 1: required string s; } struct StructB { 1: optional StructA aa; 2: required StructA ab; } struct OptionalSetDefaultTest { 1: optional set with_default = [ "test" ] } struct OptionalBinary { 1: optional set bin_set = {} 2: optional map bin_map = {} } thrift-0.23.0/test/SmallTest.thrift0000664000175000017500000000306415165535636017511 0ustar00buildbuild00000000000000/* * 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 rb TestNamespace struct Goodbyez { 1: i32 val = 325; } struct BoolPasser { 1: bool value = 1 } struct Hello { 1: i32 simple = 53, 2: map complex = {23:532, 6243:632, 2355:532}, 3: map> complexer, 4: string words = "words", 5: Goodbyez thinz = {'val' : 36632} } const map> CMAP = { 235: {235:235}, 53:{53:53} } const i32 CINT = 325; const Hello WHOA = {'simple' : 532} exception Goodbye { 1: i32 simple, 2: map complex, 3: map> complexer, } struct Thinger { 1: i32 dummy } service SmallService { Thinger testThinger(1:Thinger bootz), Hello testMe(1:i32 hello=64, 2: Hello wonk) throws (1: Goodbye g), void testVoid() throws (1: Goodbye g), i32 testI32(1:i32 boo) } thrift-0.23.0/test/py.tornado/0000775000175000017500000000000015170007175016435 5ustar00buildbuild00000000000000thrift-0.23.0/test/py.tornado/setup.cfg0000664000175000017500000000005515165535636020272 0ustar00buildbuild00000000000000[flake8] ignore = E402 max-line-length = 100 thrift-0.23.0/test/py.tornado/test_suite.py0000775000175000017500000001433415167543515021220 0ustar00buildbuild00000000000000#!/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. # import datetime import glob import os import sys import time import unittest basepath = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, basepath + '/gen-py.tornado') sys.path.insert(0, glob.glob(os.path.join(basepath, '../../lib/py/build/lib*'))[0]) try: __import__('tornado') except ImportError: print("module `tornado` not found, skipping test") sys.exit(0) from tornado import gen from tornado.testing import AsyncTestCase, bind_unused_port, gen_test from thrift import TTornado from thrift.Thrift import TApplicationException from thrift.protocol import TBinaryProtocol from ThriftTest import ThriftTest from ThriftTest.ttypes import Xception, Xtruct class TestHandler(object): def __init__(self, test_instance): self.test_instance = test_instance def testVoid(self): pass def testString(self, s): if s == 'unexpected_error': raise Exception(s) return s def testByte(self, b): return b def testI16(self, i16): return i16 def testI32(self, i32): return i32 def testI64(self, i64): return i64 def testDouble(self, dub): return dub def testBinary(self, thing): return thing def testStruct(self, thing): return thing def testException(self, s): if s == 'Xception': raise Xception(1001, s) elif s == 'throw_undeclared': raise ValueError('testing undeclared exception') def testOneway(self, seconds): start = time.time() def fire_oneway(): end = time.time() self.test_instance.stop((start, end, seconds)) self.test_instance.io_loop.add_timeout( datetime.timedelta(seconds=seconds), fire_oneway) raise Exception('testing exception in oneway method') def testNest(self, thing): return thing @gen.coroutine def testMap(self, thing): yield gen.moment raise gen.Return(thing) def testSet(self, thing): return thing def testList(self, thing): return thing def testEnum(self, thing): return thing def testTypedef(self, thing): return thing class ThriftTestCase(AsyncTestCase): def setUp(self): super(ThriftTestCase, self).setUp() sock, self.port = bind_unused_port() sock.close() # server self.handler = TestHandler(self) self.processor = ThriftTest.Processor(self.handler) self.pfactory = TBinaryProtocol.TBinaryProtocolFactory() self.server = TTornado.TTornadoServer(self.processor, self.pfactory, io_loop=self.io_loop) self.server.bind(self.port) self.server.start(1) # client transport = TTornado.TTornadoStreamTransport('localhost', self.port, io_loop=self.io_loop) pfactory = TBinaryProtocol.TBinaryProtocolFactory() self.io_loop.run_sync(transport.open) self.client = ThriftTest.Client(transport, pfactory) @gen_test def test_void(self): v = yield self.client.testVoid() self.assertEqual(v, None) @gen_test def test_string(self): v = yield self.client.testString('Python') self.assertEqual(v, 'Python') @gen_test def test_byte(self): v = yield self.client.testByte(63) self.assertEqual(v, 63) @gen_test def test_i32(self): v = yield self.client.testI32(-1) self.assertEqual(v, -1) v = yield self.client.testI32(0) self.assertEqual(v, 0) @gen_test def test_i64(self): v = yield self.client.testI64(-34359738368) self.assertEqual(v, -34359738368) @gen_test def test_double(self): v = yield self.client.testDouble(-5.235098235) self.assertEqual(v, -5.235098235) @gen_test def test_struct(self): x = Xtruct() x.string_thing = "Zero" x.byte_thing = 1 x.i32_thing = -3 x.i64_thing = -5 y = yield self.client.testStruct(x) self.assertEqual(y.string_thing, "Zero") self.assertEqual(y.byte_thing, 1) self.assertEqual(y.i32_thing, -3) self.assertEqual(y.i64_thing, -5) @gen_test def test_oneway(self): self.client.testOneway(1) v = yield self.client.testI32(-1) self.assertEqual(v, -1) @gen_test def test_map(self): """ TestHandler.testMap is a coroutine, this test checks if gen.Return() from a coroutine works. """ expected = {1: 1} res = yield self.client.testMap(expected) self.assertEqual(res, expected) @gen_test def test_exception(self): try: yield self.client.testException('Xception') except Xception as ex: self.assertEqual(ex.errorCode, 1001) self.assertEqual(ex.message, 'Xception') else: self.fail("should have gotten exception") try: yield self.client.testException('throw_undeclared') except TApplicationException: pass else: self.fail("should have gotten exception") yield self.client.testException('Safe') def suite(): suite = unittest.TestSuite() loader = unittest.TestLoader() suite.addTest(loader.loadTestsFromTestCase(ThriftTestCase)) return suite if __name__ == '__main__': unittest.TestProgram(defaultTest='suite', testRunner=unittest.TextTestRunner(verbosity=1)) thrift-0.23.0/test/py.tornado/Makefile0000644000175000017500000004471015170007175020101 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # test/py.tornado/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = test/py.tornado ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = $(top_srcdir)/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/test/py.tornado abs_srcdir = /thrift/src/test/py.tornado abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/py.tornado/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/py.tornado/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile thrift_gen: ../v0.16/ThriftTest.thrift ../SmallTest.thrift $(THRIFT) --gen py:tornado ../v0.16/ThriftTest.thrift $(THRIFT) --gen py:tornado ../SmallTest.thrift check: thrift_gen ./test_suite.py clean-local: $(RM) -r build find . -type f \( -iname "*.pyc" \) | xargs rm -f find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf $(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 $(RM) -r $(distdir)/gen-py*/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/py.tornado/Makefile.in0000644000175000017500000004365215170007167020513 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/py.tornado ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_srcdir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/py.tornado/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/py.tornado/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile thrift_gen: ../v0.16/ThriftTest.thrift ../SmallTest.thrift $(THRIFT) --gen py:tornado ../v0.16/ThriftTest.thrift $(THRIFT) --gen py:tornado ../SmallTest.thrift check: thrift_gen ./test_suite.py clean-local: $(RM) -r build find . -type f \( -iname "*.pyc" \) | xargs rm -f find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf $(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 $(RM) -r $(distdir)/gen-py*/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/py.tornado/Makefile.am0000664000175000017500000000265315165535636020513 0ustar00buildbuild00000000000000# # 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. # THRIFT = $(top_srcdir)/compiler/cpp/thrift thrift_gen: ../v0.16/ThriftTest.thrift ../SmallTest.thrift $(THRIFT) --gen py:tornado ../v0.16/ThriftTest.thrift $(THRIFT) --gen py:tornado ../SmallTest.thrift check: thrift_gen ./test_suite.py clean-local: $(RM) -r build find . -type f \( -iname "*.pyc" \) | xargs rm -f find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf $(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 $(RM) -r $(distdir)/gen-py*/ thrift-0.23.0/test/EnumTest.thrift0000664000175000017500000000701015165535636017340 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace c_glib TTest enum MyEnum1 { ME1_0 = 0, ME1_1 = 1, ME1_2, ME1_3, ME1_5 = 5, ME1_6, } enum MyEnum2 { ME2_0, ME2_1, ME2_2, } enum MyEnum2_again { // enum value identifiers may appear again in another enum type ME0_1, ME1_1, ME2_1, ME3_1, } enum MyEnum3 { ME3_0, ME3_1, ME3_N2 = -2, ME3_N1, ME3_D0, ME3_D1, ME3_9 = 9, ME3_10, } enum MyEnum4 { ME4_A = 0x7ffffffd ME4_B ME4_C // attempting to define another enum value here fails // with an overflow error, as we overflow values that can be // represented with an i32. } enum MyEnum5 { e1 // fails with 0.9.3 and earlier e2 = 42 // fails with 0.9.3 and earlier } enum MyEnumWithCustomOstream { custom1 = 1, CustoM2 } (cpp.customostream) struct MyStruct { 1: MyEnum2 me2_2 = MyEnum1.ME2_2 2: MyEnum3 me3_n2 = MyEnum3.ME3_N2 3: MyEnum3 me3_d1 = MyEnum3.ME3_D1 } struct EnumTestStruct { 1: MyEnum3 a_enum; 2: list enum_list; 3: set enum_set; 4: map enum_enum_map; // collections as keys 44: map (python.immutable = ""), MyEnum3> list_enum_map; 45: map (python.immutable = ""), MyEnum3> set_enum_map; 46: map (python.immutable = ""), MyEnum3> map_enum_map; // collections as values 47: map> enum_map_map; 48: map> enum_set_map; 49: map> enum_list_map; } const EnumTestStruct ENUM_TEST = { 'a_enum': MyEnum3.ME3_D1, 'enum_list': [MyEnum3.ME3_D1, MyEnum3.ME3_0, MyEnum3.ME3_N2], 'enum_set': [MyEnum3.ME3_D1, MyEnum3.ME3_N1], 'enum_enum_map': {MyEnum3.ME3_D1: MyEnum3.ME3_0, MyEnum3.ME3_0: MyEnum3.ME3_D1}, 'list_enum_map': {[MyEnum3.ME3_D1, MyEnum3.ME3_0]: MyEnum3.ME3_0, [MyEnum3.ME3_D1]: MyEnum3.ME3_0, [MyEnum3.ME3_0]: MyEnum3.ME3_D1}, 'set_enum_map': {[MyEnum3.ME3_D1, MyEnum3.ME3_0]: MyEnum3.ME3_0, [MyEnum3.ME3_D1]: MyEnum3.ME3_0}, 'map_enum_map': {{MyEnum3.ME3_N1: MyEnum3.ME3_10}: MyEnum3.ME3_1}, 'enum_map_map': {MyEnum3.ME3_N1: {MyEnum3.ME3_D1: MyEnum3.ME3_D1}}, 'enum_set_map': {MyEnum3.ME3_N2: [MyEnum3.ME3_D1, MyEnum3.ME3_N1], MyEnum3.ME3_10: [MyEnum3.ME3_D1, MyEnum3.ME3_N1]}, 'enum_list_map': {MyEnum3.ME3_D1: [MyEnum3.ME3_10], MyEnum3.ME3_0: [MyEnum3.ME3_9, MyEnum3.ME3_10]}, } service EnumTestService { MyEnum3 testEnum(1: MyEnum3 enum1), list testEnumList(1: list enum1), set testEnumSet(1: set enum1), map testEnumMap(1: map enum1), EnumTestStruct testEnumStruct(1: EnumTestStruct enum1), } thrift-0.23.0/test/ManyOptionals.thrift0000664000175000017500000001021015165535636020365 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // The java codegenerator has a few different codepaths depending // on how many optionals the struct has; this attempts to exercise // them. namespace java thrift.test struct Opt4 { 1: i32 def1; 2: i32 def2; 3: i32 def3; 4: i32 def4; } struct Opt13 { 1: i32 def1; 2: i32 def2; 3: i32 def3; 4: i32 def4; 5: i32 def5; 6: i32 def6; 7: i32 def7; 8: i32 def8; 9: i32 def9; 10: i32 def10; 11: i32 def11; 12: i32 def12; 13: i32 def13; } struct Opt30 { 1: i32 def1; 2: i32 def2; 3: i32 def3; 4: i32 def4; 5: i32 def5; 6: i32 def6; 7: i32 def7; 8: i32 def8; 9: i32 def9; 10: i32 def10; 11: i32 def11; 12: i32 def12; 13: i32 def13; 14: i32 def14; 15: i32 def15; 16: i32 def16; 17: i32 def17; 18: i32 def18; 19: i32 def19; 20: i32 def20; 21: i32 def21; 22: i32 def22; 23: i32 def23; 24: i32 def24; 25: i32 def25; 26: i32 def26; 27: i32 def27; 28: i32 def28; 29: i32 def29; 30: i32 def30; } struct Opt64 { 1: i32 def1; 2: i32 def2; 3: i32 def3; 4: i32 def4; 5: i32 def5; 6: i32 def6; 7: i32 def7; 8: i32 def8; 9: i32 def9; 10: i32 def10; 11: i32 def11; 12: i32 def12; 13: i32 def13; 14: i32 def14; 15: i32 def15; 16: i32 def16; 17: i32 def17; 18: i32 def18; 19: i32 def19; 20: i32 def20; 21: i32 def21; 22: i32 def22; 23: i32 def23; 24: i32 def24; 25: i32 def25; 26: i32 def26; 27: i32 def27; 28: i32 def28; 29: i32 def29; 30: i32 def30; 31: i32 def31; 32: i32 def32; 33: i32 def33; 34: i32 def34; 35: i32 def35; 36: i32 def36; 37: i32 def37; 38: i32 def38; 39: i32 def39; 40: i32 def40; 41: i32 def41; 42: i32 def42; 43: i32 def43; 44: i32 def44; 45: i32 def45; 46: i32 def46; 47: i32 def47; 48: i32 def48; 49: i32 def49; 50: i32 def50; 51: i32 def51; 52: i32 def52; 53: i32 def53; 54: i32 def54; 55: i32 def55; 56: i32 def56; 57: i32 def57; 58: i32 def58; 59: i32 def59; 60: i32 def60; 61: i32 def61; 62: i32 def62; 63: i32 def63; 64: i32 def64; } struct Opt80 { 1: i32 def1; 2: i32 def2; 3: i32 def3; 4: i32 def4; 5: i32 def5; 6: i32 def6; 7: i32 def7; 8: i32 def8; 9: i32 def9; 10: i32 def10; 11: i32 def11; 12: i32 def12; 13: i32 def13; 14: i32 def14; 15: i32 def15; 16: i32 def16; 17: i32 def17; 18: i32 def18; 19: i32 def19; 20: i32 def20; 21: i32 def21; 22: i32 def22; 23: i32 def23; 24: i32 def24; 25: i32 def25; 26: i32 def26; 27: i32 def27; 28: i32 def28; 29: i32 def29; 30: i32 def30; 31: i32 def31; 32: i32 def32; 33: i32 def33; 34: i32 def34; 35: i32 def35; 36: i32 def36; 37: i32 def37; 38: i32 def38; 39: i32 def39; 40: i32 def40; 41: i32 def41; 42: i32 def42; 43: i32 def43; 44: i32 def44; 45: i32 def45; 46: i32 def46; 47: i32 def47; 48: i32 def48; 49: i32 def49; 50: i32 def50; 51: i32 def51; 52: i32 def52; 53: i32 def53; 54: i32 def54; 55: i32 def55; 56: i32 def56; 57: i32 def57; 58: i32 def58; 59: i32 def59; 60: i32 def60; 61: i32 def61; 62: i32 def62; 63: i32 def63; 64: i32 def64; 65: i32 def65; 66: i32 def66; 67: i32 def67; 68: i32 def68; 69: i32 def69; 70: i32 def70; 71: i32 def71; 72: i32 def72; 73: i32 def73; 74: i32 def74; 75: i32 def75; 76: i32 def76; 77: i32 def77; 78: i32 def78; 79: i32 def79; 80: i32 def80; } thrift-0.23.0/test/dart/0000775000175000017500000000000015170007175015272 5ustar00buildbuild00000000000000thrift-0.23.0/test/dart/test_client/0000775000175000017500000000000015170007142017601 5ustar00buildbuild00000000000000thrift-0.23.0/test/dart/test_client/bin/0000775000175000017500000000000015167543515020370 5ustar00buildbuild00000000000000thrift-0.23.0/test/dart/test_client/bin/main.dart0000664000175000017500000002417615167543515022202 0ustar00buildbuild00000000000000/// 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 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:args/args.dart'; import 'package:collection/collection.dart'; import 'package:thrift/thrift.dart'; import 'package:thrift/thrift_console.dart'; import 'package:thrift_test/thrift_test.dart'; import 'package:http/io_client.dart'; const TEST_BASETYPES = 1; // 0000 0001 const TEST_STRUCTS = 2; // 0000 0010 const TEST_CONTAINERS = 4; // 0000 0100 const TEST_EXCEPTIONS = 8; // 0000 1000 const TEST_UNKNOWN = 64; // 0100 0000 (Failed to prepare environemt etc.) const TEST_TIMEOUT = 128; // 1000 0000 const TEST_NOTUSED = 48; // 0011 0000 (reserved bits) typedef Future FutureFunction(); class TTest { final int errorCode; final String name; final FutureFunction func; TTest(this.errorCode, this.name, this.func); } class TTestError extends Error { final actual; final expected; TTestError(this.actual, this.expected); String toString() => '$actual != $expected'; } late List _tests; late ThriftTestClient client; late bool verbose; /// Adapted from TestClient.php main(List args) async { ArgResults? results = _parseArgs(args); if (results == null) { exit(TEST_UNKNOWN); } verbose = results['verbose'] == true; await _initTestClient( host: results['host'], port: int.parse(results['port']), transportType: results['transport'], protocolType: results['protocol']).catchError((e) { stdout.writeln('Error:'); stdout.writeln('$e'); if (e is Error) { stdout.writeln('${e.stackTrace}'); } exit(TEST_UNKNOWN); }); // run tests _tests = _createTests(); int result = 0; for (TTest test in _tests) { if (verbose) stdout.write('${test.name}... '); try { await test.func(); if (verbose) stdout.writeln('success!'); } catch (e) { if (verbose) stdout.writeln('$e'); result = result | test.errorCode; } } exit(result); } ArgResults? _parseArgs(List args) { var parser = new ArgParser(); parser.addOption('host', defaultsTo: 'localhost', help: 'The server host'); parser.addOption('port', defaultsTo: '9090', help: 'The port to connect to'); parser.addOption('transport', defaultsTo: 'buffered', allowed: ['buffered', 'framed', 'http'], help: 'The transport name', allowedHelp: { 'buffered': 'TBufferedTransport', 'framed': 'TFramedTransport' }); parser.addOption('protocol', defaultsTo: 'binary', allowed: ['binary', 'compact', 'json'], help: 'The protocol name', allowedHelp: { 'binary': 'TBinaryProtocol', 'compact': 'TCompactProtocol', 'json': 'TJsonProtocol' }); parser.addFlag('verbose', defaultsTo: true); ArgResults? results; try { results = parser.parse(args); } catch (e) { stdout.writeln('$e\n'); } if (results == null) stdout.write(parser.usage); return results; } TProtocolFactory getProtocolFactory(String protocolType) { if (protocolType == 'binary') { return new TBinaryProtocolFactory(); } else if (protocolType == 'compact') { return new TCompactProtocolFactory(); } else if (protocolType == 'json') { return new TJsonProtocolFactory(); } throw new ArgumentError.value(protocolType); } Future _initTestClient( {required String host, required int port, required String transportType, required String protocolType}) async { TTransport transport; var protocolFactory = getProtocolFactory(protocolType); if (transportType == 'http') { var httpClient = IOClient(); var uri = Uri.parse('http://$host:$port'); var config = new THttpConfig(uri, {}); transport = new THttpClientTransport(httpClient, config); } else { var socket = await Socket.connect(host, port); transport = new TClientSocketTransport(new TTcpSocket(socket)); if (transportType == 'framed') { transport = new TFramedTransport(transport); } } var protocol = protocolFactory.getProtocol(transport); client = new ThriftTestClient(protocol); await transport.open(); } List _createTests() { List tests = []; var xtruct = new Xtruct() ..string_thing = 'Zero' ..byte_thing = 1 ..i32_thing = -3 ..i64_thing = -5; tests.add(new TTest(TEST_BASETYPES, 'testVoid', () async { await client.testVoid(); })); tests.add(new TTest(TEST_BASETYPES, 'testString', () async { var input = 'Test'; var result = await client.testString(input); if (result != input) throw new TTestError(result, input); })); tests.add(new TTest(TEST_BASETYPES, 'testBool', () async { var input = true; var result = await client.testBool(input); if (result != input) throw new TTestError(result, input); })); tests.add(new TTest(TEST_BASETYPES, 'testByte', () async { var input = 64; var result = await client.testByte(input); if (result != input) throw new TTestError(result, input); })); tests.add(new TTest(TEST_BASETYPES, 'testI32', () async { var input = 2147483647; var result = await client.testI32(input); if (result != input) throw new TTestError(result, input); })); tests.add(new TTest(TEST_BASETYPES, 'testI64', () async { var input = 9223372036854775807; var result = await client.testI64(input); if (result != input) throw new TTestError(result, input); })); tests.add(new TTest(TEST_BASETYPES, 'testDouble', () async { var input = 3.1415926; var result = await client.testDouble(input); if (result != input) throw new TTestError(result, input); })); tests.add(new TTest(TEST_BASETYPES, 'testBinary', () async { var utf8Codec = const Utf8Codec(); var input = utf8Codec.encode('foo'); var result = await client.testBinary(input); var equality = const ListEquality(); if (!equality.equals(result, input)) throw new TTestError(result, input); })); tests.add(new TTest(TEST_CONTAINERS, 'testStruct', () async { var result = await client.testStruct(xtruct); if ('$result' != '$xtruct') throw new TTestError(result, xtruct); })); tests.add(new TTest(TEST_CONTAINERS, 'testNest', () async { var input = new Xtruct2() ..byte_thing = 1 ..struct_thing = xtruct ..i32_thing = -3; var result = await client.testNest(input); if ('$result' != '$input') throw new TTestError(result, input); })); tests.add(new TTest(TEST_CONTAINERS, 'testMap', () async { Map input = {1: -10, 2: -9, 3: -8, 4: -7, 5: -6}; var result = await client.testMap(input); var equality = const MapEquality(); if (!equality.equals(result, input)) throw new TTestError(result, input); })); tests.add(new TTest(TEST_CONTAINERS, 'testSet', () async { var input = new Set.from([-2, -1, 0, 1, 2]); var result = await client.testSet(input); var equality = const SetEquality(); if (!equality.equals(result, input)) throw new TTestError(result, input); })); tests.add(new TTest(TEST_CONTAINERS, 'testList', () async { var input = [-2, -1, 0, 1, 2]; var result = await client.testList(input); var equality = const ListEquality(); if (!equality.equals(result, input)) throw new TTestError(result, input); })); tests.add(new TTest(TEST_CONTAINERS, 'testEnum', () async { await _testEnum(Numberz.ONE); await _testEnum(Numberz.TWO); await _testEnum(Numberz.THREE); await _testEnum(Numberz.FIVE); await _testEnum(Numberz.EIGHT); })); tests.add(new TTest(TEST_BASETYPES, 'testTypedef', () async { var input = 309858235082523; var result = await client.testTypedef(input); if (result != input) throw new TTestError(result, input); })); tests.add(new TTest(TEST_CONTAINERS, 'testMapMap', () async { Map>? result = await client.testMapMap(1); if (result != null && (result.isEmpty || (result[result.keys.first] != null && result[result.keys.first]!.isEmpty))) { throw new TTestError(result, 'Map>'); } })); tests.add(new TTest(TEST_CONTAINERS, 'testInsanity', () async { var input = new Insanity(); input.userMap = {Numberz.FIVE: 5000}; input.xtructs = [xtruct]; Map>? result = await client.testInsanity(input); if (result != null && ( result.isEmpty || (result[result.keys.first] != null && result[result.keys.first]!.isEmpty))) { throw new TTestError(result, 'Map>'); } })); tests.add(new TTest(TEST_CONTAINERS, 'testMulti', () async { var input = new Xtruct() ..string_thing = 'Hello2' ..byte_thing = 123 ..i32_thing = 456 ..i64_thing = 789; var result = await client.testMulti(input.byte_thing, input.i32_thing, input.i64_thing, {1: 'one'}, Numberz.EIGHT, 5678); if ('$result' != '$input') throw new TTestError(result, input); })); tests.add(new TTest(TEST_EXCEPTIONS, 'testException', () async { try { await client.testException('Xception'); } on Xception catch (_) { return; } throw new TTestError(null, 'Xception'); })); tests.add(new TTest(TEST_EXCEPTIONS, 'testMultiException', () async { try { await client.testMultiException('Xception2', 'foo'); } on Xception2 catch (_) { return; } throw new TTestError(null, 'Xception2'); })); return tests; } Future _testEnum(int input) async { var result = await client.testEnum(input); if (result != input) throw new TTestError(result, input); } thrift-0.23.0/test/dart/test_client/pubspec.yaml0000664000175000017500000000225715170007142022134 0ustar00buildbuild00000000000000# 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. name: thrift_test_client version: 0.23.0 description: A client integration test for the Dart Thrift library author: Apache Thrift Developers homepage: http://thrift.apache.org environment: sdk: ">=2.12.0 <4.0.0" dependencies: args: "^2.4.2" http: ^1.2.0 thrift: path: ../../../lib/dart thrift_test: path: ../gen-dart/thrift_test dev_dependencies: test: ">=0.12.30 <2.0.0" thrift-0.23.0/test/dart/Makefile0000644000175000017500000004542615170007175016743 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # test/dart/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = test/dart ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart # Dart build command DARTPUB = dart pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/test/dart abs_srcdir = /thrift/src/test/dart abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. EXTRA_DIST = \ test_client all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/dart/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/dart/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-dart/thrift_test/lib/thrift_test.dart: ../v0.16/ThriftTest.thrift $(THRIFT) --gen dart ../v0.16/ThriftTest.thrift pub-get-gen: gen-dart/thrift_test/lib/thrift_test.dart cd gen-dart/thrift_test; ${DARTPUB} get pub-get: pub-get-gen cd test_client; ${DARTPUB} get stubs: gen-dart/thrift_test/lib/thrift_test.dart pub-get precross: stubs check: stubs clean-local: $(RM) -r gen-dart/ test_client/.pub find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type d -name "packages" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type f -name "pubspec.lock" | xargs $(RM) dist-hook: $(RM) -r $(distdir)/gen-dart/ $(distdir)/test_client/.pub find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r find $(distdir) -type d -name "packages" | xargs $(RM) -r find $(distdir) -type f -name ".packages" | xargs $(RM) client: stubs ${DART} test_client/bin/main.dart distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/dart/Makefile.in0000644000175000017500000004437715170007167017355 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = test/dart ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ # Dart build command DARTPUB = dart pub DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ test_client all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/dart/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/dart/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-dart/thrift_test/lib/thrift_test.dart: ../v0.16/ThriftTest.thrift $(THRIFT) --gen dart ../v0.16/ThriftTest.thrift pub-get-gen: gen-dart/thrift_test/lib/thrift_test.dart cd gen-dart/thrift_test; ${DARTPUB} get pub-get: pub-get-gen cd test_client; ${DARTPUB} get stubs: gen-dart/thrift_test/lib/thrift_test.dart pub-get precross: stubs check: stubs clean-local: $(RM) -r gen-dart/ test_client/.pub find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type d -name "packages" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type f -name "pubspec.lock" | xargs $(RM) dist-hook: $(RM) -r $(distdir)/gen-dart/ $(distdir)/test_client/.pub find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r find $(distdir) -type d -name "packages" | xargs $(RM) -r find $(distdir) -type f -name ".packages" | xargs $(RM) client: stubs ${DART} test_client/bin/main.dart distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/test/dart/Makefile.am0000664000175000017500000000342315167543515017341 0ustar00buildbuild00000000000000# # 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. # # Dart build command DARTPUB = dart pub gen-dart/thrift_test/lib/thrift_test.dart: ../v0.16/ThriftTest.thrift $(THRIFT) --gen dart ../v0.16/ThriftTest.thrift pub-get-gen: gen-dart/thrift_test/lib/thrift_test.dart cd gen-dart/thrift_test; ${DARTPUB} get pub-get: pub-get-gen cd test_client; ${DARTPUB} get stubs: gen-dart/thrift_test/lib/thrift_test.dart pub-get precross: stubs check: stubs clean-local: $(RM) -r gen-dart/ test_client/.pub find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type d -name "packages" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type f -name "pubspec.lock" | xargs $(RM) dist-hook: $(RM) -r $(distdir)/gen-dart/ $(distdir)/test_client/.pub find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r find $(distdir) -type d -name "packages" | xargs $(RM) -r find $(distdir) -type f -name ".packages" | xargs $(RM) client: stubs ${DART} test_client/bin/main.dart distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ test_client thrift-0.23.0/test/tests.json0000664000175000017500000003314515170007142016375 0ustar00buildbuild00000000000000[ { "name": "c_glib", "platforms": [ "Linux" ], "server": { "command": [ "test_server", "--lt-debug" ], "protocols": [ "binary:multi", "compact:multic" ] }, "client": { "command": [ "test_client", "--lt-debug" ], "protocols": [ "multi:binary", "multic:compact" ], "sockets": [ "ip-ssl" ] }, "transports": [ "buffered", "framed" ], "sockets": [ "ip", "domain" ], "protocols": [ "binary", "compact", "multi", "multic" ], "workdir": "c_glib" }, { "name": "cl", "server": { "command": ["TestServer"], "workdir": "cl", "protocols": ["binary", "multi"], "transports": ["buffered", "framed"], "sockets": ["ip"] }, "client": { "command": ["TestClient"], "workdir": "cl", "protocols": ["binary", "multi"], "transports": ["buffered", "framed"], "sockets": ["ip"] } }, { "name": "d", "server": { "command": [ "thrift_test_server", "--trace" ] }, "client": { "command": [ "thrift_test_client" ] }, "transports": [ "http", "buffered", "framed", "zlib" ], "sockets": [ "ip", "ip-ssl" ], "protocols": [ "binary", "compact", "json" ], "workdir": "../lib/d/test" }, { "name": "go", "server": { "command": [ "testserver", "--certPath=../../keys" ] }, "client": { "timeout": 15, "command": [ "testclient" ] }, "transports": [ "buffered", "framed", "http", "zlib" ], "sockets": [ "ip", "ip-ssl" ], "protocols": [ "binary", "compact", "json", "header" ], "workdir": "go/bin" }, { "name": "java", "join_args": false, "server": { "delay": 15, "command": [ "build/runserver" ], "protocols": [ "binary:multi", "compact:multic", "json:multij" ] }, "client": { "timeout": 13, "command": [ "build/runclient" ], "transports": [ "http" ], "protocols": [ "multi:binary", "multic:compact", "multij:json" ] }, "transports": [ "buffered", "framed", "framed:fastframed", "zlib" ], "sockets": [ "ip", "ip-ssl" ], "protocols": [ "binary", "compact", "json", "multi", "multic", "multij" ], "workdir": "../lib/java" }, { "name": "kotlin", "join_args": false, "server": { "delay": 15, "command": [ "cross-test-server/build/install/TestServer/bin/TestServer" ], "protocols": [ "binary" ] }, "client": { "timeout": 13, "command": [ "cross-test-client/build/install/TestClient/bin/TestClient" ], "transports": [ "framed" ], "protocols": [ "binary" ], "sockets": [ "ip", "ip-ssl" ] }, "transports": [ "framed" ], "sockets": [ "ip" ], "protocols": [ "binary", "compact", "json" ], "workdir": "../lib/kotlin" }, { "name": "nodejs", "env": { "NODE_PATH": "../lib" }, "server": { "command": [ "node", "server.mjs", "--type=tcp" ] }, "client": { "timeout": 6, "command": [ "node", "client.mjs", "--type=tcp" ] }, "transports": [ "buffered", "framed", "http", "websocket" ], "sockets": [ "ip", "ip-ssl", "domain" ], "protocols": [ "compact", "binary", "json", "header" ], "workdir": "../lib/nodejs/test" }, { "name": "hs", "server": { "command": [ "TestServer" ] }, "client": { "timeout": 6, "transports": [ "http" ], "command": [ "TestClient" ] }, "transports": [ "buffered", "framed" ], "sockets": [ "ip" ], "protocols": [ "header", "compact", "binary", "json" ], "workdir": "hs" }, { "name": "py", "server": { "extra_args": ["TSimpleServer"], "command": [ "TestServer.py", "--verbose", "--genpydir=gen-py" ] }, "client": { "timeout": 15, "command": [ "TestClient.py", "--verbose", "--host=localhost", "--genpydir=gen-py" ] }, "transports": [ "buffered", "framed", "http", "zlib" ], "sockets": [ "ip", "ip-ssl", "domain" ], "protocols": [ "binary", "binary:accel", "compact", "compact:accelc", "header", "json", "multi", "multi:multia", "multia", "multiac", "multic", "multic:multiac", "multih", "multij" ], "workdir": "py" }, { "comment": "Using 'python3' executable to test py2 and 3 at once", "name": "py3", "server": { "extra_args": ["TSimpleServer"], "command": [ "python3", "TestServer.py", "--verbose", "--genpydir=gen-py" ] }, "client": { "timeout": 15, "command": [ "python3", "TestClient.py", "--host=localhost", "--genpydir=gen-py" ] }, "transports": [ "buffered", "framed", "http", "zlib" ], "sockets": [ "ip", "ip-ssl", "domain" ], "protocols": [ "binary", "binary:accel", "compact", "compact:accelc", "header", "json", "multi", "multi:multia", "multia", "multiac", "multic", "multic:multiac", "multih", "multij" ], "workdir": "py" }, { "name": "cpp", "server": { "command": [ "TestServer" ], "protocols": [ "binary:multi", "compact:multic", "header:multih", "json:multij" ] }, "client": { "timeout": 15, "command": [ "TestClient" ], "protocols": [ "multi:binary", "multic:compact", "multih:header", "multij:json" ] }, "transports": [ "buffered", "http", "framed", "zlib" ], "sockets": [ "ip", "ip-ssl", "domain", "domain-socketactivated" ], "protocols": [ "compact", "binary", "json", "header", "multi", "multic", "multih", "multij" ], "workdir": "cpp" }, { "name": "rb", "server": { "command": [ "ruby", "../integration/TestServer.rb" ] }, "client": { "timeout": 10, "command": [ "ruby", "../integration/TestClient.rb", "--" ] }, "transports": [ "buffered", "framed" ], "sockets": [ "domain", "ip", "ip-ssl" ], "protocols": [ "binary", "binary:accel", "compact", "json", "header" ], "workdir": "rb/gen-rb" }, { "name": "netstd", "transports": [ "buffered", "framed" ], "sockets": [ "ip", "ip-ssl" ], "protocols": [ "binary", "compact", "json" ], "server": { "command": [ "dotnet", "run", "--no-build", "--project=Server/Server.csproj", "--configuration=Release", "server" ] }, "client": { "timeout": 10, "command": [ "dotnet", "run", "--no-build", "--project=Client/Client.csproj", "--configuration=Release", "client" ] }, "workdir": "netstd" }, { "name": "perl", "transports": [ "buffered", "framed" ], "sockets": [ "ip", "ip-ssl", "domain" ], "protocols": [ "binary", "multi" ], "client": { "command": [ "perl", "-Igen-perl/", "-I../../lib/perl/lib/", "TestClient.pl", "--ca=../keys/CA.pem", "--cert=../keys/client.crt", "--key=../keys/client.key" ], "protocols": [ "multi:binary" ] }, "server": { "command": [ "perl", "-Igen-perl/", "-I../../lib/perl/lib/", "TestServer.pl", "--cert=../keys/server.crt", "--key=../keys/server.key" ], "protocols": [ "binary:multi" ] }, "workdir": "perl" }, { "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": [ "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", "TestClient.php" ] }, "workdir": "php" }, { "name": "dart", "client": { "timeout": 30, "transports": [ "buffered", "framed", "http" ], "sockets": [ "ip" ], "protocols": [ "binary", "compact", "json" ], "command": [ "dart", "--enable-asserts", "test_client/bin/main.dart", "--verbose" ] }, "workdir": "dart" }, { "name": "erl", "transports": [ "buffered", "framed" ], "sockets": [ "ip", "ip-ssl" ], "protocols": [ "binary", "compact" ], "client": { "command": [ "erl", "+K", "true", "-noshell", "-pa", "../../lib/erl/_build/default/lib/thrift/ebin/", "-pa", "./_build/default/lib/thrift_test/ebin", "-s", "test_client", "-s", "init", "stop", "-extra" ] }, "server": { "command": [ "erl", "+K", "true", "-noshell", "-pa", "../../lib/erl/_build/default/lib/thrift/ebin/", "-pa", "./_build/default/lib/thrift_test/ebin", "-s", "test_thrift_server", "-extra" ] }, "workdir": "erl" }, { "name": "js", "transports": [ "http" ], "sockets": [ "ip" ], "protocols": [ "json" ], "client": { "command": [ "phantomjs", "test/phantom-client.js" ] }, "workdir": "../lib/js" }, { "name": "lua", "TODO": "Add dll to LUA_CPATH", "env": { "LUA_PATH": ";;gen-lua/?.lua;../../lib/lua/?.lua", "LUA_CPATH": ";;../../lib/lua/.libs/?.so" }, "client": { "timeout": 5, "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" }, { "name": "rs", "env": { "RUST_BACKTRACE": "1", "RUST_LOG": "info" }, "server": { "command": [ "test_server" ], "protocols": [ "binary:multi", "compact:multic" ] }, "client": { "timeout": 6, "command": [ "test_client" ], "protocols": [ "multi:binary", "multic:compact" ] }, "sockets": [ "ip", "domain" ], "transports": [ "buffered", "framed" ], "protocols": [ "binary", "compact", "multi", "multic" ], "workdir": "rs/bin" }, { "name": "nodets", "env": { "NODE_PATH": "../lib" }, "server": { "command": [ "runServer.sh" ] }, "client": { "timeout": 6, "command": [ "runClient.sh" ] }, "protocols": [ "binary" ], "sockets": [ "ip" ], "transports": [ "buffered" ], "workdir": "../lib/nodets/test" }, { "name": "swift", "server": { "command": ["TestServer"], "workdir": "swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug", "protocols": ["binary", "compact"], "transports": ["buffered", "framed"], "sockets": ["ip", "domain"] }, "client": { "command": ["TestClient"], "workdir": "swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug", "protocols": ["binary", "compact"], "transports": ["buffered", "framed"], "sockets": ["ip", "domain"] } } ] thrift-0.23.0/test/ocaml/0000775000175000017500000000000015165535636015447 5ustar00buildbuild00000000000000thrift-0.23.0/test/ocaml/client/0000775000175000017500000000000015165535636016725 5ustar00buildbuild00000000000000thrift-0.23.0/test/ocaml/client/TestClient.ml0000664000175000017500000000443615165535636021344 0ustar00buildbuild00000000000000(* 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. *) open Thrift;; open ThriftTest_types;; let s = new TSocket.t "127.0.0.1" 9090;; let p = new TBinaryProtocol.t s;; let c = new ThriftTest.client p p;; let sod = function Some v -> v | None -> raise Thrift_error;; s#opn; print_string (c#testString "bya"); print_char '\n'; print_int (c#testByte 8); print_char '\n'; print_int (c#testByte (-8)); print_char '\n'; print_int (c#testI32 32); print_char '\n'; print_string (Int64.to_string (c#testI64 64L)); print_char '\n'; print_float (c#testDouble 3.14); print_char '\n'; let l = [1;2;3;4] in if l = (c#testList l) then print_string "list ok\n" else print_string "list fail\n";; let h = Hashtbl.create 5 in let a = Hashtbl.add h in for i=1 to 10 do a i (10*i) done; let r = c#testMap h in for i=1 to 10 do try let g = Hashtbl.find r i in print_int i; print_char ' '; print_int g; print_char '\n' with Not_found -> print_string ("Can't find "^(string_of_int i)^"\n") done;; let s = Hashtbl.create 5 in let a = Hashtbl.add s in for i = 1 to 10 do a i true done; let r = c#testSet s in for i = 1 to 10 do try let g = Hashtbl.find r i in print_int i; print_char '\n' with Not_found -> print_string ("Can't find "^(string_of_int i)^"\n") done;; try c#testException "Xception" with Xception _ -> print_string "testException ok\n";; try ignore(c#testMultiException "Xception" "bya") with Xception e -> Printf.printf "%d %s\n" (sod e#get_errorCode) (sod e#get_message);; thrift-0.23.0/test/ocaml/client/Makefile0000664000175000017500000000211315165535636020362 0ustar00buildbuild00000000000000# # 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. # SOURCES = ../gen-ocaml/ThriftTest_types.ml ../gen-ocaml/ThriftTest_consts.ml ../gen-ocaml/SecondService.ml ../gen-ocaml/ThriftTest.ml TestClient.ml RESULT = tc INCDIRS = "../../../lib/ocaml/src/" "../gen-ocaml/" LIBS = unix thrift all: nc OCAMLMAKEFILE = ../../../lib/ocaml/OCamlMakefile include $(OCAMLMAKEFILE) thrift-0.23.0/test/ocaml/server/0000775000175000017500000000000015165535636016755 5ustar00buildbuild00000000000000thrift-0.23.0/test/ocaml/server/Makefile0000664000175000017500000000212415165535636020414 0ustar00buildbuild00000000000000# # 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. # SOURCES = ../gen-ocaml/ThriftTest_types.ml ../gen-ocaml/ThriftTest_consts.ml ../gen-ocaml/SecondService.ml ../gen-ocaml/ThriftTest.ml TestServer.ml RESULT = ts INCDIRS = "../../../lib/ocaml/src/" "../gen-ocaml/" LIBS = thrift THREADS = yes all: nc OCAMLMAKEFILE = ../../../lib/ocaml/OCamlMakefile include $(OCAMLMAKEFILE) thrift-0.23.0/test/ocaml/server/TestServer.ml0000664000175000017500000001064215165535636021420 0ustar00buildbuild00000000000000(* 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. *) open Thrift open ThriftTest_types let p = Printf.printf;; exception Die;; let sod = function Some v -> v | None -> raise Die;; class test_handler = object (self) inherit ThriftTest.iface method testVoid = p "testVoid()\n" method testString x = p "testString(%s)\n" (sod x); (sod x) method testByte x = p "testByte(%d)\n" (sod x); (sod x) method testI32 x = p "testI32(%d)\n" (sod x); (sod x) method testI64 x = p "testI64(%s)\n" (Int64.to_string (sod x)); (sod x) method testDouble x = p "testDouble(%f)\n" (sod x); (sod x) method testBinary x = p "testBinary(%s)\n" (sod x); (sod x) method testStruct x = p "testStruct(---)\n"; (sod x) method testNest x = p "testNest(---)\n"; (sod x) method testMap x = p "testMap(---)\n"; (sod x) method testSet x = p "testSet(---)\n"; (sod x) method testList x = p "testList(---)\n"; (sod x) method testEnum x = p "testEnum(---)\n"; (sod x) method testTypedef x = p "testTypedef(---)\n"; (sod x) method testMapMap x = p "testMapMap(%d)\n" (sod x); let mm = Hashtbl.create 3 in let pos = Hashtbl.create 7 in let neg = Hashtbl.create 7 in for i=1 to 4 do Hashtbl.add pos i i; Hashtbl.add neg (-i) (-i); done; Hashtbl.add mm 4 pos; Hashtbl.add mm (-4) neg; mm method testInsanity x = p "testInsanity()\n"; p "testinsanity()\n"; let hello = new xtruct in let goodbye = new xtruct in let crazy = new insanity in let looney = new insanity in let cumap = Hashtbl.create 7 in let insane = Hashtbl.create 7 in let firstmap = Hashtbl.create 7 in let secondmap = Hashtbl.create 7 in hello#set_string_thing "Hello2"; hello#set_byte_thing 2; hello#set_i32_thing 2; hello#set_i64_thing 2L; goodbye#set_string_thing "Goodbye4"; goodbye#set_byte_thing 4; goodbye#set_i32_thing 4; goodbye#set_i64_thing 4L; Hashtbl.add cumap Numberz.EIGHT 8L; Hashtbl.add cumap Numberz.FIVE 5L; crazy#set_userMap cumap; crazy#set_xtructs [goodbye; hello]; Hashtbl.add firstmap Numberz.TWO crazy; Hashtbl.add firstmap Numberz.THREE crazy; Hashtbl.add secondmap Numberz.SIX looney; Hashtbl.add insane 1L firstmap; Hashtbl.add insane 2L secondmap; insane method testMulti a0 a1 a2 a3 a4 a5 = p "testMulti()\n"; let hello = new xtruct in hello#set_string_thing "Hello2"; hello#set_byte_thing (sod a0); hello#set_i32_thing (sod a1); hello#set_i64_thing (sod a2); hello method testException s = p "testException(%S)\n" (sod s); if (sod s) = "Xception" then let x = new xception in x#set_errorCode 1001; x#set_message "This is an Xception"; raise (Xception x) else () method testMultiException a0 a1 = p "testMultiException(%S, %S)\n" (sod a0) (sod a1); if (sod a0) = "Xception" then let x = new xception in x#set_errorCode 1001; x#set_message "This is an Xception"; raise (Xception x) else (if (sod a0) = "Xception2" then let x = new xception2 in let s = new xtruct in x#set_errorCode 2002; s#set_string_thing "This as an Xception2"; x#set_struct_thing s; raise (Xception2 x) else ()); let res = new xtruct in res#set_string_thing (sod a1); res method testOneway i = Unix.sleep (sod i) end;; let h = new test_handler in let proc = new ThriftTest.processor h in let port = 9090 in let pf = new TBinaryProtocol.factory in let server = new TThreadedServer.t proc (new TServerSocket.t port) (new Transport.factory) pf pf in server#serve thrift-0.23.0/test/ocaml/Makefile0000664000175000017500000000157515165535636017117 0ustar00buildbuild00000000000000# # 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. # all: cd client; make; cd ..; cd server; make clean: cd client; make clean; cd ..; cd server; make clean thrift-0.23.0/test/threads/0000775000175000017500000000000015165535636016006 5ustar00buildbuild00000000000000thrift-0.23.0/test/threads/ThreadsServer.cpp0000664000175000017500000001043415165535636021275 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. #include "ThreadsTest.h" #include #include #include #include #include #include #include #include #if _WIN32 #include #endif using boost::shared_ptr; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace apache::thrift::server; using namespace apache::thrift::concurrency; class ThreadsTestHandler : virtual public ThreadsTestIf { public: ThreadsTestHandler() { // Your initialization goes here } int32_t threadOne(const int32_t sleep) { // Your implementation goes here printf("threadOne\n"); go2sleep(1, sleep); return 1; } int32_t threadTwo(const int32_t sleep) { // Your implementation goes here printf("threadTwo\n"); go2sleep(2, sleep); return 1; } int32_t threadThree(const int32_t sleep) { // Your implementation goes here printf("threadThree\n"); go2sleep(3, sleep); return 1; } int32_t threadFour(const int32_t sleep) { // Your implementation goes here printf("threadFour\n"); go2sleep(4, sleep); return 1; } int32_t stop() { printf("stop\n"); server_->stop(); return 1; } void setServer(boost::shared_ptr server) { server_ = server; } protected: void go2sleep(int thread, int seconds) { Monitor m; Synchronized s(m); for (int i = 0; i < seconds; ++i) { fprintf(stderr, "Thread %d: sleep %d\n", thread, i); try { m.wait(1000); } catch(const TimedOutException&) { } } fprintf(stderr, "THREAD %d DONE\n", thread); } private: boost::shared_ptr server_; }; int main(int argc, char **argv) { #if _WIN32 transport::TWinsockSingleton::create(); #endif int port = 9090; shared_ptr handler(new ThreadsTestHandler()); shared_ptr processor(new ThreadsTestProcessor(handler)); shared_ptr serverTransport(new TServerSocket(port)); shared_ptr transportFactory(new TBufferedTransportFactory()); shared_ptr protocolFactory(new TBinaryProtocolFactory()); /* shared_ptr threadManager = ThreadManager::newSimpleThreadManager(10); shared_ptr threadFactory = shared_ptr(new ThreadFactory()); threadManager->threadFactory(threadFactory); threadManager->start(); shared_ptr server = shared_ptr(new TThreadPoolServer(processor, serverTransport, transportFactory, protocolFactory, threadManager)); */ shared_ptr server = shared_ptr(new TThreadedServer(processor, serverTransport, transportFactory, protocolFactory)); handler->setServer(server); server->serve(); fprintf(stderr, "done.\n"); return 0; } thrift-0.23.0/test/threads/Makefile0000664000175000017500000000331415165535636017447 0ustar00buildbuild00000000000000# # 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. # # Default target is everything ifndef thrift_home thrift_home=../../ endif #thrift_home target: all ifndef boost_home boost_home=/usr/local/include/boost-1_33_1 endif #boost_home target: all include_paths = $(thrift_home)/lib/cpp/src \ $(boost_home) include_flags = $(patsubst %,-I%, $(include_paths)) # Tools ifndef THRIFT THRIFT = ../../compiler/cpp/thrift endif # THRIFT CC = g++ LD = g++ # Compiler flags LFL = -L$(thrift_home)/lib/cpp/.libs -lthrift CCFL = -Wall -O3 -g -I./gen-cpp $(include_flags) CFL = $(CCFL) $(LFL) all: server client stubs: ThreadsTest.thrift $(THRIFT) --gen cpp --gen py ThreadsTest.thrift server: stubs $(CC) -o ThreadsServer $(CFL) ThreadsServer.cpp ./gen-cpp/ThreadsTest.cpp ./gen-cpp/ThreadsTest_types.cpp client: stubs $(CC) -o ThreadsClient $(CFL) ThreadsClient.cpp ./gen-cpp/ThreadsTest.cpp ./gen-cpp/ThreadsTest_types.cpp clean: $(RM) -r *.o ThreadsServer ThreadsClient gen-cpp gen-py thrift-0.23.0/test/threads/ThreadsTest.thrift0000664000175000017500000000172715165535636021471 0ustar00buildbuild00000000000000/* * 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. */ service ThreadsTest { i32 threadOne(1: i32 sleep=15), i32 threadTwo(2: i32 sleep=15), i32 threadThree(3: i32 sleep=15), i32 threadFour(4: i32 sleep=15) i32 stop(); } thrift-0.23.0/test/threads/ThreadsClient.cpp0000664000175000017500000000416515165535636021251 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. #include "ThreadsTest.h" #include #include #include #include #include #include #include #if _WIN32 #include #endif using boost::shared_ptr; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace apache::thrift::server; using namespace apache::thrift::concurrency; int main(int argc, char **argv) { #if _WIN32 transport::TWinsockSingleton::create(); #endif int port = 9090; std::string host = "localhost"; shared_ptr transport(new TSocket(host, port)); shared_ptr protocol(new TBinaryProtocol(transport)); transport->open(); ThreadsTestClient client(protocol); int val; val = client.threadOne(5); fprintf(stderr, "%d\n", val); val = client.stop(); fprintf(stderr, "%d\n", val); val = client.threadTwo(5); fprintf(stderr, "%d\n", val); transport->close(); fprintf(stderr, "done.\n"); return 0; } thrift-0.23.0/test/rebuild_known_failures.sh0000664000175000017500000000106215165535636021443 0ustar00buildbuild00000000000000#!/bin/bash if [ -z $1 ]; then echo Usage: $0 LANGUAGE echo Re-list all failures of a specific LANGUAGE into known_failures_Linux.json echo LANGUAGE should be library name like cpp, java, py etc exit 1 fi if [ -z $PYTHON]; then PYTHON=python fi TARGET_LANG=$1 OUT_FILE=known_failures_Linux.json echo Rebuilding known failures for $TARGET_LANG TMPFILE=.__tmp__rebuild__ grep -v -e "\"$1-" -e "\-$1_" $OUT_FILE > $TMPFILE mv $TMPFILE $OUT_FILE $PYTHON test.py --client $1 $PYTHON test.py -U merge $PYTHON test.py --server $1 $PYTHON test.py -U merge thrift-0.23.0/test/known_failures_Linux.json0000664000175000017500000011550415170007142021440 0ustar00buildbuild00000000000000[ "c_glib-netstd_binary_buffered-ip", "c_glib-netstd_binary_framed-ip", "c_glib-netstd_compact_buffered-ip", "c_glib-netstd_compact_framed-ip", "c_glib-netstd_multi-binary_buffered-ip", "c_glib-netstd_multi-binary_framed-ip", "c_glib-netstd_multic-compact_buffered-ip", "c_glib-netstd_multic-compact_framed-ip", "cl-c_glib_binary_buffered-ip", "cl-c_glib_binary_framed-ip", "cl-c_glib_multi-binary_buffered-ip", "cl-c_glib_multi-binary_framed-ip", "cl-c_glib_multi_buffered-ip", "cl-c_glib_multi_framed-ip", "cl-go_binary_buffered-ip", "cl-go_binary_framed-ip", "cl-netstd_binary_buffered-ip", "cl-netstd_binary_framed-ip", "cl-rb_binary-accel_buffered-ip", "cl-rb_binary-accel_framed-ip", "cl-rb_binary_buffered-ip", "cl-rb_binary_framed-ip", "cl-rs_binary_buffered-ip", "cl-rs_binary_framed-ip", "cl-rs_multi-binary_buffered-ip", "cl-rs_multi-binary_framed-ip", "cl-rs_multi_buffered-ip", "cl-rs_multi_framed-ip", "cpp-dart_binary_http-ip", "cpp-dart_compact_http-ip", "cpp-dart_json_http-ip", "cpp-dart_multi-binary_http-ip", "cpp-dart_multic-compact_http-ip", "cpp-dart_multij-json_http-ip", "cpp-go_binary_http-ip", "cpp-go_binary_http-ip-ssl", "cpp-go_compact_http-ip", "cpp-go_compact_http-ip-ssl", "cpp-go_header_http-ip", "cpp-go_header_http-ip-ssl", "cpp-go_json_http-ip", "cpp-go_json_http-ip-ssl", "cpp-go_multi-binary_http-ip", "cpp-go_multi-binary_http-ip-ssl", "cpp-go_multic-compact_http-ip", "cpp-go_multic-compact_http-ip-ssl", "cpp-go_multih-header_http-ip", "cpp-go_multih-header_http-ip-ssl", "cpp-go_multij-json_http-ip", "cpp-go_multij-json_http-ip-ssl", "cpp-java_binary_http-ip", "cpp-java_binary_http-ip-ssl", "cpp-java_compact_http-ip", "cpp-java_compact_http-ip-ssl", "cpp-java_json_http-ip", "cpp-java_json_http-ip-ssl", "cpp-java_multi-binary_http-ip", "cpp-java_multi-binary_http-ip-ssl", "cpp-java_multi_http-ip", "cpp-java_multi_http-ip-ssl", "cpp-java_multic-compact_http-ip", "cpp-java_multic-compact_http-ip-ssl", "cpp-java_multic_http-ip", "cpp-java_multic_http-ip-ssl", "cpp-java_multij-json_http-ip", "cpp-java_multij-json_http-ip-ssl", "cpp-java_multij_http-ip", "cpp-java_multij_http-ip-ssl", "cpp-netstd_binary_buffered-ip", "cpp-netstd_binary_buffered-ip-ssl", "cpp-netstd_binary_framed-ip", "cpp-netstd_binary_framed-ip-ssl", "cpp-netstd_compact_buffered-ip", "cpp-netstd_compact_buffered-ip-ssl", "cpp-netstd_compact_framed-ip", "cpp-netstd_compact_framed-ip-ssl", "cpp-netstd_json_buffered-ip", "cpp-netstd_json_buffered-ip-ssl", "cpp-netstd_json_framed-ip", "cpp-netstd_json_framed-ip-ssl", "cpp-netstd_multi-binary_buffered-ip", "cpp-netstd_multi-binary_buffered-ip-ssl", "cpp-netstd_multi-binary_framed-ip", "cpp-netstd_multi-binary_framed-ip-ssl", "cpp-netstd_multic-compact_buffered-ip", "cpp-netstd_multic-compact_buffered-ip-ssl", "cpp-netstd_multic-compact_framed-ip", "cpp-netstd_multic-compact_framed-ip-ssl", "cpp-netstd_multij-json_buffered-ip", "cpp-netstd_multij-json_buffered-ip-ssl", "cpp-netstd_multij-json_framed-ip", "cpp-netstd_multij-json_framed-ip-ssl", "cpp-nodejs_binary_http-domain", "cpp-nodejs_binary_http-ip", "cpp-nodejs_binary_http-ip-ssl", "cpp-nodejs_binary_websocket-domain", "cpp-nodejs_compact_http-domain", "cpp-nodejs_compact_http-ip", "cpp-nodejs_compact_http-ip-ssl", "cpp-nodejs_compact_websocket-domain", "cpp-nodejs_header_http-domain", "cpp-nodejs_header_http-ip", "cpp-nodejs_header_http-ip-ssl", "cpp-nodejs_header_websocket-domain", "cpp-nodejs_header_websocket-ip", "cpp-nodejs_header_websocket-ip-ssl", "cpp-nodejs_json_http-domain", "cpp-nodejs_json_http-ip", "cpp-nodejs_json_http-ip-ssl", "cpp-nodejs_json_websocket-domain", "cpp-nodejs_multi-binary_http-domain", "cpp-nodejs_multi-binary_http-ip", "cpp-nodejs_multi-binary_http-ip-ssl", "cpp-nodejs_multi-binary_websocket-domain", "cpp-nodejs_multic-compact_http-domain", "cpp-nodejs_multic-compact_http-ip", "cpp-nodejs_multic-compact_http-ip-ssl", "cpp-nodejs_multic-compact_websocket-domain", "cpp-nodejs_multih-header_http-domain", "cpp-nodejs_multih-header_http-ip", "cpp-nodejs_multih-header_http-ip-ssl", "cpp-nodejs_multih-header_websocket-domain", "cpp-nodejs_multih-header_websocket-ip", "cpp-nodejs_multih-header_websocket-ip-ssl", "cpp-nodejs_multij-json_http-domain", "cpp-nodejs_multij-json_http-ip", "cpp-nodejs_multij-json_http-ip-ssl", "cpp-nodejs_multij-json_websocket-domain", "cpp-php_binary-accel_buffered-ip", "cpp-php_binary-accel_framed-ip", "cpp-php_json_buffered-ip", "cpp-php_json_framed-ip", "cpp-php_multi-accel_buffered-ip", "cpp-php_multi-accel_framed-ip", "cpp-php_multij-json_buffered-ip", "cpp-php_multij-json_framed-ip", "cpp-py_binary-accel_http-domain", "cpp-py_binary-accel_http-ip", "cpp-py_binary-accel_http-ip-ssl", "cpp-py_binary_http-domain", "cpp-py_binary_http-ip", "cpp-py_binary_http-ip-ssl", "cpp-py_compact-accelc_http-domain", "cpp-py_compact-accelc_http-ip", "cpp-py_compact-accelc_http-ip-ssl", "cpp-py_compact_http-domain", "cpp-py_compact_http-ip", "cpp-py_compact_http-ip-ssl", "cpp-py_header_http-domain", "cpp-py_header_http-ip", "cpp-py_header_http-ip-ssl", "cpp-py_json_http-domain", "cpp-py_json_http-ip", "cpp-py_json_http-ip-ssl", "cpp-py_multi-accel_http-domain", "cpp-py_multi-accel_http-ip", "cpp-py_multi-accel_http-ip-ssl", "cpp-py_multi-binary_http-domain", "cpp-py_multi-binary_http-ip", "cpp-py_multi-binary_http-ip-ssl", "cpp-py_multi-multia_http-domain", "cpp-py_multi-multia_http-ip", "cpp-py_multi-multia_http-ip-ssl", "cpp-py_multi_http-domain", "cpp-py_multi_http-ip", "cpp-py_multi_http-ip-ssl", "cpp-py_multic-accelc_http-domain", "cpp-py_multic-accelc_http-ip", "cpp-py_multic-accelc_http-ip-ssl", "cpp-py_multic-compact_http-domain", "cpp-py_multic-compact_http-ip", "cpp-py_multic-compact_http-ip-ssl", "cpp-py_multic-multiac_http-domain", "cpp-py_multic-multiac_http-ip", "cpp-py_multic-multiac_http-ip-ssl", "cpp-py_multic_http-domain", "cpp-py_multic_http-ip", "cpp-py_multic_http-ip-ssl", "cpp-py_multih-header_http-domain", "cpp-py_multih-header_http-ip", "cpp-py_multih-header_http-ip-ssl", "cpp-py_multih_http-domain", "cpp-py_multih_http-ip", "cpp-py_multih_http-ip-ssl", "cpp-py_multij-json_http-domain", "cpp-py_multij-json_http-ip", "cpp-py_multij-json_http-ip-ssl", "cpp-py_multij_http-domain", "cpp-py_multij_http-ip", "cpp-py_multij_http-ip-ssl", "d-cl_binary_buffered-ip", "d-cl_binary_framed-ip", "d-cpp_binary_buffered-ip", "d-cpp_binary_buffered-ip-ssl", "d-cpp_binary_framed-ip", "d-cpp_binary_framed-ip-ssl", "d-cpp_binary_http-ip", "d-cpp_binary_http-ip-ssl", "d-cpp_binary_zlib-ip", "d-cpp_binary_zlib-ip-ssl", "d-cpp_compact_buffered-ip", "d-cpp_compact_buffered-ip-ssl", "d-cpp_compact_framed-ip", "d-cpp_compact_framed-ip-ssl", "d-cpp_compact_http-ip", "d-cpp_compact_http-ip-ssl", "d-cpp_compact_zlib-ip", "d-cpp_compact_zlib-ip-ssl", "d-cpp_json_buffered-ip", "d-cpp_json_buffered-ip-ssl", "d-cpp_json_framed-ip", "d-cpp_json_framed-ip-ssl", "d-cpp_json_http-ip", "d-cpp_json_http-ip-ssl", "d-cpp_json_zlib-ip", "d-cpp_json_zlib-ip-ssl", "d-d_binary_http-ip", "d-d_compact_http-ip", "d-d_json_http-ip", "d-dart_binary_http-ip", "d-dart_compact_http-ip", "d-dart_json_http-ip", "d-go_binary_http-ip", "d-go_binary_http-ip-ssl", "d-go_compact_http-ip", "d-go_compact_http-ip-ssl", "d-go_json_http-ip", "d-go_json_http-ip-ssl", "d-java_binary_http-ip", "d-java_binary_http-ip-ssl", "d-java_compact_http-ip", "d-java_compact_http-ip-ssl", "d-java_json_http-ip", "d-java_json_http-ip-ssl", "d-js_json_http-ip", "d-netstd_binary_buffered-ip", "d-netstd_binary_buffered-ip-ssl", "d-netstd_binary_framed-ip", "d-netstd_binary_framed-ip-ssl", "d-netstd_compact_buffered-ip", "d-netstd_compact_buffered-ip-ssl", "d-netstd_compact_framed-ip", "d-netstd_compact_framed-ip-ssl", "d-netstd_json_buffered-ip", "d-netstd_json_buffered-ip-ssl", "d-netstd_json_framed-ip", "d-netstd_json_framed-ip-ssl", "d-nodejs_binary_buffered-ip", "d-nodejs_binary_buffered-ip-ssl", "d-nodejs_binary_framed-ip", "d-nodejs_binary_framed-ip-ssl", "d-nodejs_binary_http-ip", "d-nodejs_binary_http-ip-ssl", "d-nodejs_compact_buffered-ip", "d-nodejs_compact_buffered-ip-ssl", "d-nodejs_compact_framed-ip", "d-nodejs_compact_framed-ip-ssl", "d-nodejs_compact_http-ip", "d-nodejs_compact_http-ip-ssl", "d-nodejs_json_buffered-ip", "d-nodejs_json_buffered-ip-ssl", "d-nodejs_json_framed-ip", "d-nodejs_json_framed-ip-ssl", "d-nodejs_json_http-ip", "d-nodejs_json_http-ip-ssl", "d-nodets_binary_buffered-ip", "d-py_binary-accel_buffered-ip", "d-py_binary-accel_buffered-ip-ssl", "d-py_binary-accel_framed-ip", "d-py_binary-accel_framed-ip-ssl", "d-py_binary-accel_http-ip", "d-py_binary-accel_http-ip-ssl", "d-py_binary-accel_zlib-ip", "d-py_binary-accel_zlib-ip-ssl", "d-py_binary_buffered-ip", "d-py_binary_buffered-ip-ssl", "d-py_binary_framed-ip", "d-py_binary_framed-ip-ssl", "d-py_binary_http-ip", "d-py_binary_http-ip-ssl", "d-py_binary_zlib-ip", "d-py_binary_zlib-ip-ssl", "d-py_compact-accelc_buffered-ip", "d-py_compact-accelc_buffered-ip-ssl", "d-py_compact-accelc_framed-ip", "d-py_compact-accelc_framed-ip-ssl", "d-py_compact-accelc_http-ip", "d-py_compact-accelc_http-ip-ssl", "d-py_compact-accelc_zlib-ip", "d-py_compact-accelc_zlib-ip-ssl", "d-py_compact_buffered-ip", "d-py_compact_buffered-ip-ssl", "d-py_compact_framed-ip", "d-py_compact_framed-ip-ssl", "d-py_compact_http-ip", "d-py_compact_http-ip-ssl", "d-py_compact_zlib-ip", "d-py_compact_zlib-ip-ssl", "d-py_json_buffered-ip", "d-py_json_buffered-ip-ssl", "d-py_json_framed-ip", "d-py_json_framed-ip-ssl", "d-py_json_http-ip", "d-py_json_http-ip-ssl", "d-py_json_zlib-ip", "d-py_json_zlib-ip-ssl", "erl-cpp_binary_buffered-ip", "erl-cpp_compact_buffered-ip", "erl-netstd_binary_buffered-ip", "erl-netstd_binary_buffered-ip-ssl", "erl-netstd_binary_framed-ip", "erl-netstd_binary_framed-ip-ssl", "erl-netstd_compact_buffered-ip", "erl-netstd_compact_buffered-ip-ssl", "erl-netstd_compact_framed-ip", "erl-netstd_compact_framed-ip-ssl", "erl-nodejs_binary_buffered-ip", "erl-nodejs_compact_buffered-ip", "erl-nodets_binary_buffered-ip", "erl-rb_binary-accel_buffered-ip", "erl-rb_binary-accel_buffered-ip-ssl", "erl-rb_binary-accel_framed-ip", "erl-rb_binary-accel_framed-ip-ssl", "erl-rb_binary_buffered-ip", "erl-rb_binary_buffered-ip-ssl", "erl-rb_binary_framed-ip", "erl-rb_binary_framed-ip-ssl", "erl-rb_compact_buffered-ip", "erl-rb_compact_buffered-ip-ssl", "erl-rb_compact_framed-ip", "erl-rb_compact_framed-ip-ssl", "go-cpp_binary_http-ip", "go-cpp_binary_http-ip-ssl", "go-cpp_compact_http-ip", "go-cpp_compact_http-ip-ssl", "go-cpp_header_http-ip", "go-cpp_header_http-ip-ssl", "go-cpp_json_http-ip", "go-cpp_json_http-ip-ssl", "go-d_binary_http-ip", "go-d_binary_http-ip-ssl", "go-d_compact_http-ip", "go-d_compact_http-ip-ssl", "go-d_json_http-ip", "go-d_json_http-ip-ssl", "go-dart_binary_http-ip", "go-dart_compact_http-ip", "go-dart_json_http-ip", "go-java_binary_http-ip", "go-java_binary_http-ip-ssl", "go-java_compact_http-ip", "go-java_compact_http-ip-ssl", "go-java_json_http-ip", "go-java_json_http-ip-ssl", "go-netstd_binary_buffered-ip", "go-netstd_binary_buffered-ip-ssl", "go-netstd_binary_framed-ip", "go-netstd_binary_framed-ip-ssl", "go-netstd_compact_buffered-ip", "go-netstd_compact_buffered-ip-ssl", "go-netstd_compact_framed-ip", "go-netstd_compact_framed-ip-ssl", "go-netstd_json_buffered-ip", "go-netstd_json_buffered-ip-ssl", "go-netstd_json_framed-ip", "go-netstd_json_framed-ip-ssl", "go-py_binary-accel_zlib-ip-ssl", "go-py_compact-accelc_zlib-ip-ssl", "hs-netstd_binary_buffered-ip", "hs-netstd_binary_framed-ip", "hs-netstd_compact_buffered-ip", "hs-netstd_compact_framed-ip", "hs-netstd_json_buffered-ip", "hs-netstd_json_framed-ip", "hs-php_binary-accel_buffered-ip", "hs-php_binary-accel_framed-ip", "hs-php_json_buffered-ip", "hs-php_json_framed-ip", "java-erl_binary_buffered-ip-ssl", "java-erl_binary_fastframed-framed-ip-ssl", "java-erl_binary_framed-ip-ssl", "java-erl_compact_buffered-ip-ssl", "java-erl_compact_fastframed-framed-ip-ssl", "java-erl_compact_framed-ip-ssl", "java-erl_multi-binary_buffered-ip-ssl", "java-erl_multi-binary_fastframed-framed-ip-ssl", "java-erl_multi-binary_framed-ip-ssl", "java-erl_multic-compact_buffered-ip-ssl", "java-erl_multic-compact_fastframed-framed-ip-ssl", "java-erl_multic-compact_framed-ip-ssl", "java-netstd_binary_buffered-ip", "java-netstd_binary_buffered-ip-ssl", "java-netstd_binary_fastframed-framed-ip", "java-netstd_binary_fastframed-framed-ip-ssl", "java-netstd_binary_framed-ip", "java-netstd_binary_framed-ip-ssl", "java-netstd_compact_buffered-ip", "java-netstd_compact_buffered-ip-ssl", "java-netstd_compact_fastframed-framed-ip", "java-netstd_compact_fastframed-framed-ip-ssl", "java-netstd_compact_framed-ip", "java-netstd_compact_framed-ip-ssl", "java-netstd_json_buffered-ip", "java-netstd_json_buffered-ip-ssl", "java-netstd_json_fastframed-framed-ip", "java-netstd_json_fastframed-framed-ip-ssl", "java-netstd_json_framed-ip", "java-netstd_json_framed-ip-ssl", "java-netstd_multi-binary_buffered-ip", "java-netstd_multi-binary_buffered-ip-ssl", "java-netstd_multi-binary_fastframed-framed-ip", "java-netstd_multi-binary_fastframed-framed-ip-ssl", "java-netstd_multi-binary_framed-ip", "java-netstd_multi-binary_framed-ip-ssl", "java-netstd_multic-compact_buffered-ip", "java-netstd_multic-compact_buffered-ip-ssl", "java-netstd_multic-compact_fastframed-framed-ip", "java-netstd_multic-compact_fastframed-framed-ip-ssl", "java-netstd_multic-compact_framed-ip", "java-netstd_multic-compact_framed-ip-ssl", "java-netstd_multij-json_buffered-ip", "java-netstd_multij-json_buffered-ip-ssl", "java-netstd_multij-json_fastframed-framed-ip", "java-netstd_multij-json_fastframed-framed-ip-ssl", "java-netstd_multij-json_framed-ip", "java-netstd_multij-json_framed-ip-ssl", "java-php_binary-accel_buffered-ip", "java-php_binary-accel_fastframed-framed-ip", "java-php_binary-accel_framed-ip", "java-php_json_buffered-ip", "java-php_json_fastframed-framed-ip", "java-php_json_framed-ip", "java-php_multi-accel_buffered-ip", "java-php_multi-accel_fastframed-framed-ip", "java-php_multi-accel_framed-ip", "java-php_multij-json_buffered-ip", "java-php_multij-json_fastframed-framed-ip", "java-php_multij-json_framed-ip", "kotlin-netstd_binary_framed-ip", "kotlin-netstd_compact_framed-ip", "kotlin-netstd_json_framed-ip", "netstd-c_glib_binary_buffered-ip", "netstd-c_glib_binary_buffered-ip-ssl", "netstd-c_glib_binary_framed-ip", "netstd-c_glib_binary_framed-ip-ssl", "netstd-c_glib_compact_buffered-ip", "netstd-c_glib_compact_buffered-ip-ssl", "netstd-c_glib_compact_framed-ip", "netstd-c_glib_compact_framed-ip-ssl", "netstd-cl_binary_buffered-ip", "netstd-cl_binary_framed-ip", "netstd-cpp_binary_buffered-ip", "netstd-cpp_binary_buffered-ip-ssl", "netstd-cpp_binary_framed-ip", "netstd-cpp_binary_framed-ip-ssl", "netstd-cpp_compact_buffered-ip", "netstd-cpp_compact_buffered-ip-ssl", "netstd-cpp_compact_framed-ip", "netstd-cpp_compact_framed-ip-ssl", "netstd-cpp_json_buffered-ip", "netstd-cpp_json_buffered-ip-ssl", "netstd-cpp_json_framed-ip", "netstd-cpp_json_framed-ip-ssl", "netstd-d_binary_buffered-ip", "netstd-d_binary_buffered-ip-ssl", "netstd-d_binary_framed-ip", "netstd-d_binary_framed-ip-ssl", "netstd-d_compact_buffered-ip", "netstd-d_compact_buffered-ip-ssl", "netstd-d_compact_framed-ip", "netstd-d_compact_framed-ip-ssl", "netstd-d_json_buffered-ip", "netstd-d_json_buffered-ip-ssl", "netstd-d_json_framed-ip", "netstd-d_json_framed-ip-ssl", "netstd-dart_binary_buffered-ip", "netstd-dart_binary_framed-ip", "netstd-dart_compact_buffered-ip", "netstd-dart_compact_framed-ip", "netstd-dart_json_buffered-ip", "netstd-dart_json_framed-ip", "netstd-erl_binary_buffered-ip", "netstd-erl_binary_buffered-ip-ssl", "netstd-erl_binary_framed-ip", "netstd-erl_binary_framed-ip-ssl", "netstd-erl_compact_buffered-ip", "netstd-erl_compact_buffered-ip-ssl", "netstd-erl_compact_framed-ip", "netstd-erl_compact_framed-ip-ssl", "netstd-go_binary_buffered-ip", "netstd-go_binary_buffered-ip-ssl", "netstd-go_binary_framed-ip", "netstd-go_binary_framed-ip-ssl", "netstd-go_compact_buffered-ip", "netstd-go_compact_buffered-ip-ssl", "netstd-go_compact_framed-ip", "netstd-go_compact_framed-ip-ssl", "netstd-go_json_buffered-ip", "netstd-go_json_buffered-ip-ssl", "netstd-go_json_framed-ip", "netstd-go_json_framed-ip-ssl", "netstd-hs_binary_buffered-ip", "netstd-hs_binary_framed-ip", "netstd-hs_compact_buffered-ip", "netstd-hs_compact_framed-ip", "netstd-hs_json_buffered-ip", "netstd-hs_json_framed-ip", "netstd-java_binary_buffered-ip", "netstd-java_binary_buffered-ip-ssl", "netstd-java_binary_framed-fastframed-ip", "netstd-java_binary_framed-fastframed-ip-ssl", "netstd-java_binary_framed-ip", "netstd-java_binary_framed-ip-ssl", "netstd-java_compact_buffered-ip", "netstd-java_compact_buffered-ip-ssl", "netstd-java_compact_framed-fastframed-ip", "netstd-java_compact_framed-fastframed-ip-ssl", "netstd-java_compact_framed-ip", "netstd-java_compact_framed-ip-ssl", "netstd-java_json_buffered-ip", "netstd-java_json_buffered-ip-ssl", "netstd-java_json_framed-fastframed-ip", "netstd-java_json_framed-fastframed-ip-ssl", "netstd-java_json_framed-ip", "netstd-java_json_framed-ip-ssl", "netstd-kotlin_binary_framed-ip", "netstd-kotlin_compact_framed-ip", "netstd-kotlin_json_framed-ip", "netstd-lua_binary_buffered-ip", "netstd-lua_binary_framed-ip", "netstd-lua_compact_buffered-ip", "netstd-lua_compact_framed-ip", "netstd-lua_json_buffered-ip", "netstd-lua_json_framed-ip", "netstd-netstd_binary_buffered-ip", "netstd-netstd_binary_buffered-ip-ssl", "netstd-netstd_binary_framed-ip", "netstd-netstd_binary_framed-ip-ssl", "netstd-netstd_compact_buffered-ip", "netstd-netstd_compact_buffered-ip-ssl", "netstd-netstd_compact_framed-ip", "netstd-netstd_compact_framed-ip-ssl", "netstd-netstd_json_buffered-ip", "netstd-netstd_json_buffered-ip-ssl", "netstd-netstd_json_framed-ip", "netstd-netstd_json_framed-ip-ssl", "netstd-nodejs_binary_buffered-ip", "netstd-nodejs_binary_buffered-ip-ssl", "netstd-nodejs_binary_framed-ip", "netstd-nodejs_binary_framed-ip-ssl", "netstd-nodejs_compact_buffered-ip", "netstd-nodejs_compact_buffered-ip-ssl", "netstd-nodejs_compact_framed-ip", "netstd-nodejs_compact_framed-ip-ssl", "netstd-nodejs_json_buffered-ip", "netstd-nodejs_json_buffered-ip-ssl", "netstd-nodejs_json_framed-ip", "netstd-nodejs_json_framed-ip-ssl", "netstd-nodets_binary_buffered-ip", "netstd-perl_binary_buffered-ip", "netstd-perl_binary_buffered-ip-ssl", "netstd-perl_binary_framed-ip", "netstd-perl_binary_framed-ip-ssl", "netstd-php_binary-accel_buffered-ip", "netstd-php_binary-accel_framed-ip", "netstd-php_binary_buffered-ip", "netstd-php_binary_framed-ip", "netstd-php_compact_buffered-ip", "netstd-php_compact_framed-ip", "netstd-php_json_buffered-ip", "netstd-php_json_framed-ip", "netstd-py_binary-accel_buffered-ip", "netstd-py_binary-accel_buffered-ip-ssl", "netstd-py_binary-accel_framed-ip", "netstd-py_binary-accel_framed-ip-ssl", "netstd-py_binary_buffered-ip", "netstd-py_binary_buffered-ip-ssl", "netstd-py_binary_framed-ip", "netstd-py_binary_framed-ip-ssl", "netstd-py_compact-accelc_buffered-ip", "netstd-py_compact-accelc_buffered-ip-ssl", "netstd-py_compact-accelc_framed-ip", "netstd-py_compact-accelc_framed-ip-ssl", "netstd-py_compact_buffered-ip", "netstd-py_compact_buffered-ip-ssl", "netstd-py_compact_framed-ip", "netstd-py_compact_framed-ip-ssl", "netstd-py_json_buffered-ip", "netstd-py_json_buffered-ip-ssl", "netstd-py_json_framed-ip", "netstd-py_json_framed-ip-ssl", "netstd-rb_binary-accel_buffered-ip", "netstd-rb_binary-accel_buffered-ip-ssl", "netstd-rb_binary-accel_framed-ip", "netstd-rb_binary-accel_framed-ip-ssl", "netstd-rb_binary_buffered-ip", "netstd-rb_binary_buffered-ip-ssl", "netstd-rb_binary_framed-ip", "netstd-rb_binary_framed-ip-ssl", "netstd-rb_compact_buffered-ip", "netstd-rb_compact_buffered-ip-ssl", "netstd-rb_compact_framed-ip", "netstd-rb_compact_framed-ip-ssl", "netstd-rb_json_buffered-ip", "netstd-rb_json_buffered-ip-ssl", "netstd-rb_json_framed-ip", "netstd-rb_json_framed-ip-ssl", "netstd-rs_binary_buffered-ip", "netstd-rs_binary_framed-ip", "netstd-rs_compact_buffered-ip", "netstd-rs_compact_framed-ip", "nodejs-cpp_binary_http-domain", "nodejs-cpp_binary_http-ip", "nodejs-cpp_binary_http-ip-ssl", "nodejs-cpp_compact_http-domain", "nodejs-cpp_compact_http-ip", "nodejs-cpp_compact_http-ip-ssl", "nodejs-cpp_header_http-domain", "nodejs-cpp_header_http-ip", "nodejs-cpp_header_http-ip-ssl", "nodejs-cpp_json_http-domain", "nodejs-cpp_json_http-ip", "nodejs-cpp_json_http-ip-ssl", "nodejs-d_binary_http-ip", "nodejs-d_binary_http-ip-ssl", "nodejs-d_compact_http-ip", "nodejs-d_compact_http-ip-ssl", "nodejs-d_json_http-ip", "nodejs-d_json_http-ip-ssl", "nodejs-dart_binary_http-ip", "nodejs-dart_compact_http-ip", "nodejs-dart_json_http-ip", "nodejs-go_binary_http-ip", "nodejs-go_binary_http-ip-ssl", "nodejs-go_compact_http-ip", "nodejs-go_compact_http-ip-ssl", "nodejs-go_header_http-ip", "nodejs-go_header_http-ip-ssl", "nodejs-go_json_http-ip", "nodejs-go_json_http-ip-ssl", "nodejs-hs_binary_http-ip", "nodejs-hs_compact_http-ip", "nodejs-hs_header_http-ip", "nodejs-hs_json_http-ip", "nodejs-java_binary_http-ip", "nodejs-java_binary_http-ip-ssl", "nodejs-java_compact_http-ip", "nodejs-java_compact_http-ip-ssl", "nodejs-java_json_http-ip", "nodejs-java_json_http-ip-ssl", "nodejs-js_json_http-ip", "nodejs-lua_binary_http-ip", "nodejs-lua_compact_http-ip", "nodejs-lua_json_http-ip", "nodejs-netstd_binary_buffered-ip", "nodejs-netstd_binary_buffered-ip-ssl", "nodejs-netstd_binary_framed-ip", "nodejs-netstd_binary_framed-ip-ssl", "nodejs-netstd_compact_buffered-ip", "nodejs-netstd_compact_buffered-ip-ssl", "nodejs-netstd_compact_framed-ip", "nodejs-netstd_compact_framed-ip-ssl", "nodejs-netstd_json_buffered-ip", "nodejs-netstd_json_buffered-ip-ssl", "nodejs-netstd_json_framed-ip", "nodejs-netstd_json_framed-ip-ssl", "nodejs-nodejs_binary_websocket-domain", "nodejs-nodejs_compact_websocket-domain", "nodejs-nodejs_header_websocket-domain", "nodejs-nodejs_json_websocket-domain", "nodejs-php_binary-accel_buffered-ip", "nodejs-php_binary-accel_framed-ip", "nodejs-php_json_buffered-ip", "nodejs-php_json_framed-ip", "nodejs-py_binary-accel_http-domain", "nodejs-py_binary-accel_http-ip", "nodejs-py_binary-accel_http-ip-ssl", "nodejs-py_binary_http-domain", "nodejs-py_binary_http-ip", "nodejs-py_binary_http-ip-ssl", "nodejs-py_compact-accelc_http-domain", "nodejs-py_compact-accelc_http-ip", "nodejs-py_compact-accelc_http-ip-ssl", "nodejs-py_compact_http-domain", "nodejs-py_compact_http-ip", "nodejs-py_compact_http-ip-ssl", "nodejs-py_header_http-domain", "nodejs-py_header_http-ip", "nodejs-py_header_http-ip-ssl", "nodejs-py_json_http-domain", "nodejs-py_json_http-ip", "nodejs-py_json_http-ip-ssl", "nodets-netstd_binary_buffered-ip", "nodets-php_binary-accel_buffered-ip", "perl-netstd_binary_buffered-ip", "perl-netstd_binary_buffered-ip-ssl", "perl-netstd_binary_framed-ip", "perl-netstd_binary_framed-ip-ssl", "perl-netstd_multi-binary_buffered-ip", "perl-netstd_multi-binary_buffered-ip-ssl", "perl-netstd_multi-binary_framed-ip", "perl-netstd_multi-binary_framed-ip-ssl", "py-cpp_accel-binary_http-domain", "py-cpp_accel-binary_http-ip", "py-cpp_accel-binary_http-ip-ssl", "py-cpp_accel-binary_zlib-domain", "py-cpp_accel-binary_zlib-ip", "py-cpp_accel-binary_zlib-ip-ssl", "py-cpp_accelc-compact_http-domain", "py-cpp_accelc-compact_http-ip", "py-cpp_accelc-compact_http-ip-ssl", "py-cpp_accelc-compact_zlib-domain", "py-cpp_accelc-compact_zlib-ip", "py-cpp_accelc-compact_zlib-ip-ssl", "py-cpp_binary_http-domain", "py-cpp_binary_http-ip", "py-cpp_binary_http-ip-ssl", "py-cpp_compact_http-domain", "py-cpp_compact_http-ip", "py-cpp_compact_http-ip-ssl", "py-cpp_header_http-domain", "py-cpp_header_http-ip", "py-cpp_header_http-ip-ssl", "py-cpp_json_http-domain", "py-cpp_json_http-ip", "py-cpp_json_http-ip-ssl", "py-cpp_multi-binary_http-domain", "py-cpp_multi-binary_http-ip", "py-cpp_multi-binary_http-ip-ssl", "py-cpp_multi_http-domain", "py-cpp_multi_http-ip", "py-cpp_multi_http-ip-ssl", "py-cpp_multia-binary_http-domain", "py-cpp_multia-binary_http-ip", "py-cpp_multia-binary_http-ip-ssl", "py-cpp_multia-binary_zlib-domain", "py-cpp_multia-binary_zlib-ip", "py-cpp_multia-binary_zlib-ip-ssl", "py-cpp_multia-multi_http-domain", "py-cpp_multia-multi_http-ip", "py-cpp_multia-multi_http-ip-ssl", "py-cpp_multia-multi_zlib-domain", "py-cpp_multia-multi_zlib-ip", "py-cpp_multia-multi_zlib-ip-ssl", "py-cpp_multiac-compact_http-domain", "py-cpp_multiac-compact_http-ip", "py-cpp_multiac-compact_http-ip-ssl", "py-cpp_multiac-compact_zlib-domain", "py-cpp_multiac-compact_zlib-ip", "py-cpp_multiac-compact_zlib-ip-ssl", "py-cpp_multiac-multic_http-domain", "py-cpp_multiac-multic_http-ip", "py-cpp_multiac-multic_http-ip-ssl", "py-cpp_multiac-multic_zlib-domain", "py-cpp_multiac-multic_zlib-ip", "py-cpp_multiac-multic_zlib-ip-ssl", "py-cpp_multic-compact_http-domain", "py-cpp_multic-compact_http-ip", "py-cpp_multic-compact_http-ip-ssl", "py-cpp_multic_http-domain", "py-cpp_multic_http-ip", "py-cpp_multic_http-ip-ssl", "py-cpp_multih-header_http-domain", "py-cpp_multih-header_http-ip", "py-cpp_multih-header_http-ip-ssl", "py-cpp_multih_http-domain", "py-cpp_multih_http-ip", "py-cpp_multih_http-ip-ssl", "py-cpp_multij-json_http-domain", "py-cpp_multij-json_http-ip", "py-cpp_multij-json_http-ip-ssl", "py-cpp_multij_http-domain", "py-cpp_multij_http-ip", "py-cpp_multij_http-ip-ssl", "py-d_accel-binary_http-ip", "py-d_accel-binary_http-ip-ssl", "py-d_accelc-compact_http-ip", "py-d_accelc-compact_http-ip-ssl", "py-d_binary_http-ip", "py-d_binary_http-ip-ssl", "py-d_compact_http-ip", "py-d_compact_http-ip-ssl", "py-d_json_http-ip", "py-d_json_http-ip-ssl", "py-dart_accel-binary_http-ip", "py-dart_accelc-compact_http-ip", "py-dart_binary_http-ip", "py-dart_compact_http-ip", "py-dart_json_http-ip", "py-go_accel-binary_buffered-ip-ssl", "py-go_accel-binary_framed-ip-ssl", "py-go_accel-binary_zlib-ip-ssl", "py-go_accelc-compact_buffered-ip-ssl", "py-go_accelc-compact_framed-ip-ssl", "py-go_accelc-compact_zlib-ip-ssl", "py-go_binary_buffered-ip-ssl", "py-go_binary_framed-ip-ssl", "py-go_binary_zlib-ip-ssl", "py-go_compact_buffered-ip-ssl", "py-go_compact_framed-ip-ssl", "py-go_compact_zlib-ip-ssl", "py-go_header_buffered-ip-ssl", "py-go_header_framed-ip-ssl", "py-go_header_zlib-ip-ssl", "py-go_json_buffered-ip-ssl", "py-go_json_framed-ip-ssl", "py-go_json_zlib-ip-ssl", "py-hs_accel-binary_http-ip", "py-hs_accelc-compact_http-ip", "py-hs_binary_http-ip", "py-hs_compact_http-ip", "py-hs_header_http-ip", "py-hs_json_http-ip", "py-java_accel-binary_buffered-ip", "py-java_accel-binary_buffered-ip-ssl", "py-java_accel-binary_framed-fastframed-ip", "py-java_accel-binary_framed-fastframed-ip-ssl", "py-java_accel-binary_framed-ip", "py-java_accel-binary_framed-ip-ssl", "py-java_accel-binary_http-ip", "py-java_accel-binary_http-ip-ssl", "py-java_accel-binary_zlib-ip", "py-java_accel-binary_zlib-ip-ssl", "py-java_accelc-compact_buffered-ip", "py-java_accelc-compact_buffered-ip-ssl", "py-java_accelc-compact_framed-fastframed-ip", "py-java_accelc-compact_framed-fastframed-ip-ssl", "py-java_accelc-compact_framed-ip", "py-java_accelc-compact_framed-ip-ssl", "py-java_accelc-compact_http-ip", "py-java_accelc-compact_http-ip-ssl", "py-java_accelc-compact_zlib-ip", "py-java_accelc-compact_zlib-ip-ssl", "py-java_binary_buffered-ip", "py-java_binary_buffered-ip-ssl", "py-java_binary_framed-fastframed-ip", "py-java_binary_framed-fastframed-ip-ssl", "py-java_binary_framed-ip", "py-java_binary_framed-ip-ssl", "py-java_binary_http-ip", "py-java_binary_http-ip-ssl", "py-java_binary_zlib-ip", "py-java_binary_zlib-ip-ssl", "py-java_compact_buffered-ip", "py-java_compact_buffered-ip-ssl", "py-java_compact_framed-fastframed-ip", "py-java_compact_framed-fastframed-ip-ssl", "py-java_compact_framed-ip", "py-java_compact_framed-ip-ssl", "py-java_compact_http-ip", "py-java_compact_http-ip-ssl", "py-java_compact_zlib-ip", "py-java_compact_zlib-ip-ssl", "py-java_json_buffered-ip", "py-java_json_buffered-ip-ssl", "py-java_json_framed-fastframed-ip", "py-java_json_framed-fastframed-ip-ssl", "py-java_json_framed-ip", "py-java_json_framed-ip-ssl", "py-java_json_http-ip", "py-java_json_http-ip-ssl", "py-java_json_zlib-ip", "py-java_json_zlib-ip-ssl", "py-java_multi-binary_buffered-ip", "py-java_multi-binary_buffered-ip-ssl", "py-java_multi-binary_framed-fastframed-ip", "py-java_multi-binary_framed-fastframed-ip-ssl", "py-java_multi-binary_framed-ip", "py-java_multi-binary_framed-ip-ssl", "py-java_multi-binary_http-ip", "py-java_multi-binary_http-ip-ssl", "py-java_multi-binary_zlib-ip", "py-java_multi-binary_zlib-ip-ssl", "py-java_multi_buffered-ip", "py-java_multi_buffered-ip-ssl", "py-java_multi_framed-fastframed-ip", "py-java_multi_framed-fastframed-ip-ssl", "py-java_multi_framed-ip", "py-java_multi_framed-ip-ssl", "py-java_multi_http-ip", "py-java_multi_http-ip-ssl", "py-java_multi_zlib-ip", "py-java_multi_zlib-ip-ssl", "py-java_multia-binary_buffered-ip", "py-java_multia-binary_buffered-ip-ssl", "py-java_multia-binary_framed-fastframed-ip", "py-java_multia-binary_framed-fastframed-ip-ssl", "py-java_multia-binary_framed-ip", "py-java_multia-binary_framed-ip-ssl", "py-java_multia-binary_http-ip", "py-java_multia-binary_http-ip-ssl", "py-java_multia-binary_zlib-ip", "py-java_multia-binary_zlib-ip-ssl", "py-java_multia-multi_buffered-ip", "py-java_multia-multi_buffered-ip-ssl", "py-java_multia-multi_framed-fastframed-ip", "py-java_multia-multi_framed-fastframed-ip-ssl", "py-java_multia-multi_framed-ip", "py-java_multia-multi_framed-ip-ssl", "py-java_multia-multi_http-ip", "py-java_multia-multi_http-ip-ssl", "py-java_multia-multi_zlib-ip", "py-java_multia-multi_zlib-ip-ssl", "py-java_multiac-compact_buffered-ip", "py-java_multiac-compact_buffered-ip-ssl", "py-java_multiac-compact_framed-fastframed-ip", "py-java_multiac-compact_framed-fastframed-ip-ssl", "py-java_multiac-compact_framed-ip", "py-java_multiac-compact_framed-ip-ssl", "py-java_multiac-compact_http-ip", "py-java_multiac-compact_http-ip-ssl", "py-java_multiac-compact_zlib-ip", "py-java_multiac-compact_zlib-ip-ssl", "py-java_multiac-multic_buffered-ip", "py-java_multiac-multic_buffered-ip-ssl", "py-java_multiac-multic_framed-fastframed-ip", "py-java_multiac-multic_framed-fastframed-ip-ssl", "py-java_multiac-multic_framed-ip", "py-java_multiac-multic_framed-ip-ssl", "py-java_multiac-multic_http-ip", "py-java_multiac-multic_http-ip-ssl", "py-java_multiac-multic_zlib-ip", "py-java_multiac-multic_zlib-ip-ssl", "py-java_multic-compact_buffered-ip", "py-java_multic-compact_buffered-ip-ssl", "py-java_multic-compact_framed-fastframed-ip", "py-java_multic-compact_framed-fastframed-ip-ssl", "py-java_multic-compact_framed-ip", "py-java_multic-compact_framed-ip-ssl", "py-java_multic-compact_http-ip", "py-java_multic-compact_http-ip-ssl", "py-java_multic-compact_zlib-ip", "py-java_multic-compact_zlib-ip-ssl", "py-java_multic_buffered-ip", "py-java_multic_buffered-ip-ssl", "py-java_multic_framed-fastframed-ip", "py-java_multic_framed-fastframed-ip-ssl", "py-java_multic_framed-ip", "py-java_multic_framed-ip-ssl", "py-java_multic_http-ip", "py-java_multic_http-ip-ssl", "py-java_multic_zlib-ip", "py-java_multic_zlib-ip-ssl", "py-java_multij-json_buffered-ip", "py-java_multij-json_buffered-ip-ssl", "py-java_multij-json_framed-fastframed-ip", "py-java_multij-json_framed-fastframed-ip-ssl", "py-java_multij-json_framed-ip", "py-java_multij-json_framed-ip-ssl", "py-java_multij-json_http-ip", "py-java_multij-json_http-ip-ssl", "py-java_multij-json_zlib-ip", "py-java_multij-json_zlib-ip-ssl", "py-java_multij_buffered-ip", "py-java_multij_buffered-ip-ssl", "py-java_multij_framed-fastframed-ip", "py-java_multij_framed-fastframed-ip-ssl", "py-java_multij_framed-ip", "py-java_multij_framed-ip-ssl", "py-java_multij_http-ip", "py-java_multij_http-ip-ssl", "py-java_multij_zlib-ip", "py-java_multij_zlib-ip-ssl", "py-lua_accel-binary_http-ip", "py-lua_accelc-compact_http-ip", "py-lua_binary_http-ip", "py-lua_compact_http-ip", "py-lua_json_http-ip", "py-netstd_accel-binary_buffered-ip", "py-netstd_accel-binary_buffered-ip-ssl", "py-netstd_accel-binary_framed-ip", "py-netstd_accel-binary_framed-ip-ssl", "py-netstd_accelc-compact_buffered-ip", "py-netstd_accelc-compact_buffered-ip-ssl", "py-netstd_accelc-compact_framed-ip", "py-netstd_accelc-compact_framed-ip-ssl", "py-netstd_binary_buffered-ip", "py-netstd_binary_buffered-ip-ssl", "py-netstd_binary_framed-ip", "py-netstd_binary_framed-ip-ssl", "py-netstd_compact_buffered-ip", "py-netstd_compact_buffered-ip-ssl", "py-netstd_compact_framed-ip", "py-netstd_compact_framed-ip-ssl", "py-netstd_json_buffered-ip", "py-netstd_json_buffered-ip-ssl", "py-netstd_json_framed-ip", "py-netstd_json_framed-ip-ssl", "py-nodejs_accel-binary_http-domain", "py-nodejs_accelc-compact_http-domain", "py-nodejs_binary_http-domain", "py-nodejs_compact_http-domain", "py-nodejs_header_http-domain", "py-nodejs_json_http-domain", "py-php_accel_buffered-ip", "py-php_accel_framed-ip", "py-php_binary-accel_buffered-ip", "py-php_binary-accel_framed-ip", "py-php_json_buffered-ip", "py-php_json_framed-ip", "py-rb_accel-binary_buffered-domain", "py-rb_accel-binary_buffered-ip", "py-rb_accel-binary_buffered-ip-ssl", "py-rb_accel-binary_framed-domain", "py-rb_accel-binary_framed-ip", "py-rb_accel-binary_framed-ip-ssl", "py-rb_accel_buffered-domain", "py-rb_accel_buffered-ip", "py-rb_accel_buffered-ip-ssl", "py-rb_accel_framed-domain", "py-rb_accel_framed-ip", "py-rb_accel_framed-ip-ssl", "py-rb_accelc-compact_buffered-domain", "py-rb_accelc-compact_buffered-ip", "py-rb_accelc-compact_buffered-ip-ssl", "py-rb_accelc-compact_framed-domain", "py-rb_accelc-compact_framed-ip", "py-rb_accelc-compact_framed-ip-ssl", "py-rb_binary-accel_buffered-domain", "py-rb_binary-accel_buffered-ip", "py-rb_binary-accel_buffered-ip-ssl", "py-rb_binary-accel_framed-domain", "py-rb_binary-accel_framed-ip", "py-rb_binary-accel_framed-ip-ssl", "py-rb_binary_buffered-domain", "py-rb_binary_buffered-ip", "py-rb_binary_buffered-ip-ssl", "py-rb_binary_framed-domain", "py-rb_binary_framed-ip", "py-rb_binary_framed-ip-ssl", "py-rb_compact_buffered-domain", "py-rb_compact_buffered-ip", "py-rb_compact_buffered-ip-ssl", "py-rb_compact_framed-domain", "py-rb_compact_framed-ip", "py-rb_compact_framed-ip-ssl", "py-rb_header_buffered-domain", "py-rb_header_buffered-ip", "py-rb_header_buffered-ip-ssl", "py-rb_header_framed-domain", "py-rb_header_framed-ip", "py-rb_header_framed-ip-ssl", "py-rb_json_buffered-domain", "py-rb_json_buffered-ip", "py-rb_json_buffered-ip-ssl", "py-rb_json_framed-domain", "py-rb_json_framed-ip", "py-rb_json_framed-ip-ssl", "py-rs_accel-binary_buffered-domain", "py-rs_accel-binary_buffered-ip", "py-rs_accel-binary_framed-domain", "py-rs_accel-binary_framed-ip", "py-rs_accelc-compact_buffered-domain", "py-rs_accelc-compact_buffered-ip", "py-rs_accelc-compact_framed-domain", "py-rs_accelc-compact_framed-ip", "py-rs_binary_buffered-domain", "py-rs_binary_buffered-ip", "py-rs_binary_framed-domain", "py-rs_binary_framed-ip", "py-rs_compact_buffered-domain", "py-rs_compact_buffered-ip", "py-rs_compact_framed-domain", "py-rs_compact_framed-ip", "py-rs_multi-binary_buffered-domain", "py-rs_multi-binary_buffered-ip", "py-rs_multi-binary_framed-domain", "py-rs_multi-binary_framed-ip", "py-rs_multi_buffered-domain", "py-rs_multi_buffered-ip", "py-rs_multi_framed-domain", "py-rs_multi_framed-ip", "py-rs_multia-binary_buffered-domain", "py-rs_multia-binary_buffered-ip", "py-rs_multia-binary_framed-domain", "py-rs_multia-binary_framed-ip", "py-rs_multia-multi_buffered-domain", "py-rs_multia-multi_buffered-ip", "py-rs_multia-multi_framed-domain", "py-rs_multia-multi_framed-ip", "py-rs_multiac-compact_buffered-domain", "py-rs_multiac-compact_buffered-ip", "py-rs_multiac-compact_framed-domain", "py-rs_multiac-compact_framed-ip", "py-rs_multiac-multic_buffered-domain", "py-rs_multiac-multic_buffered-ip", "py-rs_multiac-multic_framed-domain", "py-rs_multiac-multic_framed-ip", "py-rs_multic-compact_buffered-domain", "py-rs_multic-compact_buffered-ip", "py-rs_multic-compact_framed-domain", "py-rs_multic-compact_framed-ip", "py-rs_multic_buffered-domain", "py-rs_multic_buffered-ip", "py-rs_multic_framed-domain", "py-rs_multic_framed-ip", "rb-cpp_json_buffered-domain", "rb-cpp_json_buffered-ip", "rb-cpp_json_buffered-ip-ssl", "rb-cpp_json_framed-domain", "rb-cpp_json_framed-ip", "rb-cpp_json_framed-ip-ssl", "rb-netstd_accel-binary_buffered-ip", "rb-netstd_accel-binary_buffered-ip-ssl", "rb-netstd_accel-binary_framed-ip", "rb-netstd_accel-binary_framed-ip-ssl", "rb-netstd_binary_buffered-ip", "rb-netstd_binary_buffered-ip-ssl", "rb-netstd_binary_framed-ip", "rb-netstd_binary_framed-ip-ssl", "rb-netstd_compact_buffered-ip", "rb-netstd_compact_buffered-ip-ssl", "rb-netstd_compact_framed-ip", "rb-netstd_compact_framed-ip-ssl", "rb-netstd_json_buffered-ip", "rb-netstd_json_buffered-ip-ssl", "rb-netstd_json_framed-ip", "rb-netstd_json_framed-ip-ssl", "rb-py_header_buffered-ip-ssl", "rb-py_header_framed-ip-ssl", "rs-netstd_binary_buffered-ip", "rs-netstd_binary_framed-ip", "rs-netstd_compact_buffered-ip", "rs-netstd_compact_framed-ip", "rs-netstd_multi-binary_buffered-ip", "rs-netstd_multi-binary_framed-ip", "rs-netstd_multic-compact_buffered-ip", "rs-netstd_multic-compact_framed-ip" ]thrift-0.23.0/test/index.html0000664000175000017500000000325515165535636016356 0ustar00buildbuild00000000000000 Apache Thrift - integration test suite

Apache Thrift - integration test suite: Results

Server Client Protocol Transport Result (log) Expected

Test Information



browse raw log



thrift-0.23.0/test/Int64Test.thrift0000664000175000017500000000350015165535636017340 0ustar00buildbuild00000000000000/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * Contains some contributions under the Thrift Software License.
 * Please see doc/old-thrift-license.txt in the Thrift distribution for
 * details.
 */

namespace js Int64Test

const i64 SMALL_INT64 = 42
const i64 MAX_JS_SAFE_INT64 = 9007199254740991
const i64 MIN_JS_SAFE_INT64 = -9007199254740991
const i64 MAX_JS_SAFE_PLUS_ONE_INT64 = 9007199254740992
const i64 MIN_JS_SAFE_MINUS_ONE_INT64 = -9007199254740992
const i64 MAX_SIGNED_INT64 = 9223372036854775807
const i64 MIN_SIGNED_INT64 = -9223372036854775808

const list INT64_LIST = [SMALL_INT64, MAX_JS_SAFE_INT64, MIN_JS_SAFE_INT64, MAX_JS_SAFE_PLUS_ONE_INT64, MIN_JS_SAFE_MINUS_ONE_INT64, MAX_SIGNED_INT64, MIN_SIGNED_INT64]

const map INT64_2_INT64_MAP = {
    SMALL_INT64: SMALL_INT64,
    MAX_JS_SAFE_INT64: MAX_JS_SAFE_INT64,
    MIN_JS_SAFE_INT64: MIN_JS_SAFE_INT64,
    MAX_JS_SAFE_PLUS_ONE_INT64: MAX_JS_SAFE_PLUS_ONE_INT64,
    MIN_JS_SAFE_MINUS_ONE_INT64: MIN_JS_SAFE_MINUS_ONE_INT64,
    MAX_SIGNED_INT64: MAX_SIGNED_INT64,
    MIN_SIGNED_INT64: MIN_SIGNED_INT64
    }
thrift-0.23.0/test/ReuseObjects.thrift0000664000175000017500000000174715165535636020204 0ustar00buildbuild00000000000000/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// The java codegenerator has option to reuse objects for deserialization

namespace java thrift.test

include "v0.16/ThriftTest.thrift"

struct Reuse {
  1: i32 val1;
  2: set val2;
}

thrift-0.23.0/test/AnnotationTest.thrift0000664000175000017500000000371515165535636020556 0ustar00buildbuild00000000000000/*
 * 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.
 */

typedef list ( cpp.template = "std::list" ) int_linked_list

struct foo {
  1: i32 bar ( presence = "required" );
  2: i32 baz ( presence = "manual", cpp.use_pointer = "", );
  3: i32 qux;
  4: i32 bop;
} (
  cpp.type = "DenseFoo",
  python.type = "DenseFoo",
  java.final = "",
  annotation.without.value,
)

exception foo_error {
  1: i32 error_code ( foo="bar" )
  2: string error_msg
} (foo = "bar")

typedef string ( unicode.encoding = "UTF-16" ) non_latin_string (foo="bar")
typedef list< double ( cpp.fixed_point = "16" ) > tiny_float_list

enum weekdays {
  SUNDAY ( weekend = "yes" ),
  MONDAY,
  TUESDAY,
  WEDNESDAY,
  THURSDAY,
  FRIDAY,
  SATURDAY ( weekend = "yes" )
} (foo.bar="baz")

struct ostr_default {
  1: i32 bar;
}

struct ostr_custom {
  1: i32 bar;
} (cpp.customostream)


service foo_service {
  void foo() ( foo = "bar" )
} (a.b="c")

service deprecate_everything {
  void Foo( ) ( deprecated = "This method has neither 'x' nor \"y\"" )
  void Bar( ) ( deprecated = "Fails to deliver 中文 колбаÑа" )
  void Baz( ) ( deprecated = "Need this to work with tabs (\t) or Umlauts (äöüÄÖÜß) too" )
  void Deprecated() ( deprecated ) // no comment
}


thrift-0.23.0/test/Types.thrift0000664000175000017500000000162515167543515016703 0ustar00buildbuild00000000000000/*
 * 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 Type1 {
  1: i32 number,
  2: string message,
}

service BaseService {
  Type1 testEpisode(1:Type1 arg)
}thrift-0.23.0/test/py.twisted/0000775000175000017500000000000015170007175016452 5ustar00buildbuild00000000000000thrift-0.23.0/test/py.twisted/setup.cfg0000664000175000017500000000005515165535636020307 0ustar00buildbuild00000000000000[flake8]
ignore = E402
max-line-length = 100
thrift-0.23.0/test/py.twisted/test_suite.py0000775000175000017500000001312615165535636021236 0ustar00buildbuild00000000000000#!/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.
#

import glob
import os
import sys
import time

basepath = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.join(basepath, 'gen-py.twisted'))
sys.path.insert(0, glob.glob(os.path.join(basepath, '../../lib/py/build/lib.*'))[0])

from thrift.Thrift import TApplicationException

from ThriftTest import ThriftTest
from ThriftTest.ttypes import Xception, Xtruct
from thrift.transport import TTwisted
from thrift.protocol import TBinaryProtocol

from twisted.trial import unittest
from twisted.internet import defer, reactor
from twisted.internet.protocol import ClientCreator

from zope.interface import implementer


@implementer(ThriftTest.Iface)
class TestHandler:
    def __init__(self):
        self.onewaysQueue = defer.DeferredQueue()

    def testVoid(self):
        pass

    def testString(self, s):
        return s

    def testByte(self, b):
        return b

    def testI16(self, i16):
        return i16

    def testI32(self, i32):
        return i32

    def testI64(self, i64):
        return i64

    def testDouble(self, dub):
        return dub

    def testBinary(self, thing):
        return thing

    def testStruct(self, thing):
        return thing

    def testException(self, s):
        if s == 'Xception':
            raise Xception(1001, s)
        elif s == "throw_undeclared":
            raise ValueError("foo")

    def testOneway(self, seconds):
        def fireOneway(t):
            self.onewaysQueue.put((t, time.time(), seconds))
        reactor.callLater(seconds, fireOneway, time.time())
        raise Exception('')

    def testNest(self, thing):
        return thing

    def testMap(self, thing):
        return thing

    def testSet(self, thing):
        return thing

    def testList(self, thing):
        return thing

    def testEnum(self, thing):
        return thing

    def testTypedef(self, thing):
        return thing


class ThriftTestCase(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.handler = TestHandler()
        self.processor = ThriftTest.Processor(self.handler)
        self.pfactory = TBinaryProtocol.TBinaryProtocolFactory()

        self.server = reactor.listenTCP(
            0, TTwisted.ThriftServerFactory(self.processor, self.pfactory), interface="127.0.0.1")

        self.portNo = self.server.getHost().port

        self.txclient = yield ClientCreator(reactor,
                                            TTwisted.ThriftClientProtocol,
                                            ThriftTest.Client,
                                            self.pfactory).connectTCP("127.0.0.1", self.portNo)
        self.client = self.txclient.client

    @defer.inlineCallbacks
    def tearDown(self):
        yield self.server.stopListening()
        self.txclient.transport.loseConnection()

    @defer.inlineCallbacks
    def testVoid(self):
        self.assertEquals((yield self.client.testVoid()), None)

    @defer.inlineCallbacks
    def testString(self):
        self.assertEquals((yield self.client.testString('Python')), 'Python')

    @defer.inlineCallbacks
    def testByte(self):
        self.assertEquals((yield self.client.testByte(63)), 63)

    @defer.inlineCallbacks
    def testI32(self):
        self.assertEquals((yield self.client.testI32(-1)), -1)
        self.assertEquals((yield self.client.testI32(0)), 0)

    @defer.inlineCallbacks
    def testI64(self):
        self.assertEquals((yield self.client.testI64(-34359738368)), -34359738368)

    @defer.inlineCallbacks
    def testDouble(self):
        self.assertEquals((yield self.client.testDouble(-5.235098235)), -5.235098235)

    # TODO: def testBinary(self) ...

    @defer.inlineCallbacks
    def testStruct(self):
        x = Xtruct()
        x.string_thing = "Zero"
        x.byte_thing = 1
        x.i32_thing = -3
        x.i64_thing = -5
        y = yield self.client.testStruct(x)

        self.assertEquals(y.string_thing, "Zero")
        self.assertEquals(y.byte_thing, 1)
        self.assertEquals(y.i32_thing, -3)
        self.assertEquals(y.i64_thing, -5)

    @defer.inlineCallbacks
    def testException(self):
        try:
            yield self.client.testException('Xception')
            self.fail("should have gotten exception")
        except Xception as x:
            self.assertEquals(x.errorCode, 1001)
            self.assertEquals(x.message, 'Xception')

        try:
            yield self.client.testException("throw_undeclared")
            self.fail("should have gotten exception")
        except TApplicationException:
            pass

        yield self.client.testException('Safe')

    @defer.inlineCallbacks
    def testOneway(self):
        yield self.client.testOneway(1)
        start, end, seconds = yield self.handler.onewaysQueue.get()
        self.assertAlmostEquals(seconds, (end - start), places=1)
        self.assertEquals((yield self.client.testI32(-1)), -1)
thrift-0.23.0/test/py.twisted/Makefile0000644000175000017500000004472515170007175020124 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/py.twisted/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#
# 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.
#

am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
subdir = test/py.twisted
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = /thrift/src/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/py.twisted
abs_srcdir = /thrift/src/test/py.twisted
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..
all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/py.twisted/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/py.twisted/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am dist-hook distclean \
	distclean-generic distclean-libtool distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


TRIAL ?= trial

stubs: ../v0.16/ThriftTest.thrift ../SmallTest.thrift
	$(THRIFT) --gen py:twisted ../v0.16/ThriftTest.thrift
	$(THRIFT) --gen py:twisted ../SmallTest.thrift

check: stubs
	$(TRIAL) ./test_suite.py

clean-local:
	$(RM) -r build
	find . -type f \( -iname "*.pyc" \) | xargs rm -f
	find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(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
	$(RM) -r $(distdir)/gen-py*/

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/py.twisted/Makefile.in0000644000175000017500000004364015170007167020525 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/py.twisted
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/py.twisted/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/py.twisted/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am dist-hook distclean \
	distclean-generic distclean-libtool distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


TRIAL ?= trial

stubs: ../v0.16/ThriftTest.thrift ../SmallTest.thrift
	$(THRIFT) --gen py:twisted ../v0.16/ThriftTest.thrift
	$(THRIFT) --gen py:twisted ../SmallTest.thrift

check: stubs
	$(TRIAL) ./test_suite.py

clean-local:
	$(RM) -r build
	find . -type f \( -iname "*.pyc" \) | xargs rm -f
	find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(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
	$(RM) -r $(distdir)/gen-py*/

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/py.twisted/Makefile.am0000664000175000017500000000261615165535636020527 0ustar00buildbuild00000000000000#
# 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.
#

TRIAL ?= trial

stubs: ../v0.16/ThriftTest.thrift ../SmallTest.thrift
	$(THRIFT) --gen py:twisted ../v0.16/ThriftTest.thrift
	$(THRIFT) --gen py:twisted ../SmallTest.thrift

check: stubs
	$(TRIAL) ./test_suite.py

clean-local:
	$(RM) -r build
	find . -type f \( -iname "*.pyc" \) | xargs rm -f
	find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(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
	$(RM) -r $(distdir)/gen-py*/
thrift-0.23.0/test/features/0000755000175000017500000000000015170007201016142 5ustar00buildbuild00000000000000thrift-0.23.0/test/features/setup.cfg0000664000175000017500000000003715165535636020013 0ustar00buildbuild00000000000000[flake8]
max-line-length = 100
thrift-0.23.0/test/features/tls.sh0000775000175000017500000000277315165535636017344 0ustar00buildbuild00000000000000#!/bin/bash

#
# Checks to make sure TLSv1.0 or later is allowed by a server.
#

THRIFTHOST=localhost
THRIFTPORT=9090

while [[ $# -ge 1 ]]; do
  arg="$1"
  argIN=(${arg//=/ })

  case ${argIN[0]} in
    -h|--host)
    THRIFTHOST=${argIN[1]}
    shift # past argument
    ;;
    -p|--port)
    THRIFTPORT=${argIN[1]}
    shift # past argument
    ;;
    *)
          # unknown option ignored
    ;;
  esac

  shift   # past argument or value
done

declare -A EXPECT_NEGOTIATE
EXPECT_NEGOTIATE[tls1]=1
EXPECT_NEGOTIATE[tls1_1]=1
EXPECT_NEGOTIATE[tls1_2]=1
EXPECT_NEGOTIATE[tls1_3]=1

failures=0

function tls
{
  for PROTO in "${!EXPECT_NEGOTIATE[@]}"; do

    local nego
    local negodenied
    local res

    echo "openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -$PROTO 2>&1 < /dev/null"
    nego=$(openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -$PROTO 2>&1 < /dev/null)
    negodenied=$?
    echo "result of command: $negodenied"

    res="enabled"; if [[ ${EXPECT_NEGOTIATE[$PROTO]} -eq 0 ]]; then res="disabled"; fi

    if [[ $negodenied -ne ${EXPECT_NEGOTIATE[$PROTO]} ]]; then
      echo "$PROTO negotiation allowed"
    else
      echo "[warn] $PROTO negotiation did not work"
      echo $nego
      ((failures++))
    fi
  done
}

tls

if [[ $failures -eq 4 ]]; then
  echo "[fail] At least one of TLSv1.0, TLSv1.1, TLSv1.2, or TLSv1.3 needs to work, but does not"
  exit $failures
fi

echo "[pass] At least one of TLSv1.0, TLSv1.1, TLSv1.2, or TLSv1.3 worked"
exit 0
thrift-0.23.0/test/features/tests.json0000664000175000017500000000501515165535636020230 0ustar00buildbuild00000000000000[
  {
    "description": "THeader detects unframed binary wire format",
    "name": "theader_unframed_binary",
    "command": [
      "python",
      "theader_binary.py",
      "--override-protocol=binary",
      "--override-transport=buffered"
    ],
    "protocols": ["header"],
    "transports": ["buffered"],
    "sockets": ["ip"],
    "workdir": "features"
  },
  {
    "description": "THeader detects framed binary wire format",
    "name": "theader_framed_binary",
    "command": [
      "python",
      "theader_binary.py",
      "--override-protocol=binary",
      "--override-transport=framed"
    ],
    "protocols": ["header"],
    "transports": ["buffered"],
    "sockets": ["ip"],
    "workdir": "features"
  },
  {
    "description": "THeader detects unframed compact wire format",
    "name": "theader_unframed_compact",
    "command": [
      "python",
      "theader_binary.py",
      "--override-protocol=compact",
      "--override-transport=buffered"
    ],
    "protocols": ["header"],
    "transports": ["buffered"],
    "sockets": ["ip"],
    "workdir": "features"
  },
  {
    "description": "THeader detects framed compact wire format",
    "name": "theader_framed_compact",
    "command": [
      "python",
      "theader_binary.py",
      "--override-protocol=compact",
      "--override-transport=framed"
    ],
    "protocols": ["header"],
    "transports": ["buffered"],
    "sockets": ["ip"],
    "workdir": "features"
  },
  {
    "name": "limit_string_length",
    "command": [
      "python",
      "string_limit.py",
      "--limit=50"
    ],
    "remote_args": [
      "--string-limit=50"
    ],
    "protocols": [
      "compact"
    ],
    "transports": ["buffered"],
    "sockets": ["ip"],
    "workdir": "features"
  },
  {
    "name": "limit_container_length",
    "command": [
      "python",
      "container_limit.py",
      "--limit=50"
    ],
    "remote_args": [
      "--container-limit=50"
    ],
    "protocols": [
      "compact"
    ],
    "transports": ["buffered"],
    "sockets": ["ip"],
    "workdir": "features"
  },
  {
    "name": "nosslv3",
    "comment": "check to make sure SSLv3 is not supported",
    "command": [
      "nosslv3.sh"
    ],
    "protocols": ["binary"],
    "transports": ["buffered"],
    "sockets": ["ip-ssl"],
    "workdir": "features"
  },
  {
    "name": "tls",
    "comment": "check to make sure TLSv1.0 or later is supported",
    "command": [
      "tls.sh"
    ],
    "protocols": ["binary"],
    "transports": ["buffered"],
    "sockets": ["ip-ssl"],
    "workdir": "features"
  }
]
thrift-0.23.0/test/features/nosslv3.sh0000775000175000017500000000213015165535636020134 0ustar00buildbuild00000000000000#!/bin/bash

#
# Checks to make sure SSLv3 is not allowed by a server.
#

THRIFTHOST=localhost
THRIFTPORT=9090

while [[ $# -ge 1 ]]; do
  arg="$1"
  argIN=(${arg//=/ })

  case ${argIN[0]} in
    -h|--host)
    THRIFTHOST=${argIN[1]}
    shift # past argument
    ;;
    -p|--port)
    THRIFTPORT=${argIN[1]}
    shift # past argument
    ;;
    *)
          # unknown option ignored
    ;;
  esac

  shift   # past argument or value
done

function nosslv3
{
  local nego
  local negodenied
  local opensslv

  opensslv=$(openssl version | cut -d' ' -f2)
  if [[ $opensslv > "1.0" ]]; then
    echo "[pass] OpenSSL 1.1 or later - no need to check ssl3"
    return 0
  fi

  # echo "openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -ssl3 2>&1 < /dev/null"
  nego=$(openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -ssl3 2>&1 < /dev/null)
  negodenied=$?

  if [[ $negodenied -ne 0 ]]; then
    echo "[pass] SSLv3 negotiation disabled"
    echo $nego
    return 0
  fi

  echo "[fail] SSLv3 negotiation enabled!  stdout:"
  echo $nego
  return 1
}

nosslv3
exit $?
thrift-0.23.0/test/features/util.py0000664000175000017500000000377215167543515017527 0ustar00buildbuild00000000000000#
# 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 argparse
import socket

from local_thrift import thrift  # noqa
from thrift.transport.TSocket import TSocket
from thrift.transport.TTransport import TBufferedTransport, TFramedTransport
from thrift.transport.THttpClient import THttpClient
from thrift.protocol.TBinaryProtocol import TBinaryProtocol
from thrift.protocol.TCompactProtocol import TCompactProtocol
from thrift.protocol.TJSONProtocol import TJSONProtocol


def add_common_args(p):
    p.add_argument('--host', default='localhost')
    p.add_argument('--port', type=int, default=9090)
    p.add_argument('--protocol', default='binary')
    p.add_argument('--transport', default='buffered')
    p.add_argument('--ssl', action='store_true')


def parse_common_args(argv):
    p = argparse.ArgumentParser()
    add_common_args(p)
    return p.parse_args(argv)


def init_protocol(args):
    sock = TSocket(args.host, args.port, socket_family=socket.AF_INET)
    sock.setTimeout(500)
    trans = {
        'buffered': TBufferedTransport,
        'framed': TFramedTransport,
        'http': THttpClient,
    }[args.transport](sock)
    trans.open()
    return {
        'binary': TBinaryProtocol,
        'compact': TCompactProtocol,
        'json': TJSONProtocol,
    }[args.protocol](trans)
thrift-0.23.0/test/features/known_failures_Linux.json0000664000175000017500000000523515165535636023277 0ustar00buildbuild00000000000000[
    "c_glib-limit_container_length_binary_buffered-ip",
    "c_glib-limit_string_length_binary_buffered-ip",
    "cl-limit_string_length_binary_buffered-ip",
    "cl-limit_container_length_binary_buffered-ip",
    "cpp-theader_framed_binary_multih-header_buffered-ip",
    "cpp-theader_framed_compact_multih-header_buffered-ip",
    "cpp-theader_unframed_binary_multih-header_buffered-ip",
    "cpp-theader_unframed_compact_multih-header_buffered-ip",
    "netstd-limit_container_length_binary_buffered-ip",
    "netstd-limit_container_length_compact_buffered-ip",
    "netstd-limit_string_length_binary_buffered-ip",
    "netstd-limit_string_length_compact_buffered-ip",
    "netstd-tls_binary_buffered-ip-ssl",
    "d-limit_container_length_binary_buffered-ip",
    "d-limit_container_length_compact_buffered-ip",
    "d-limit_string_length_binary_buffered-ip",
    "d-limit_string_length_compact_buffered-ip",
    "erl-limit_container_length_binary_buffered-ip",
    "erl-limit_container_length_compact_buffered-ip",
    "erl-limit_string_length_binary_buffered-ip",
    "erl-limit_string_length_compact_buffered-ip",
    "go-limit_container_length_binary_buffered-ip",
    "go-limit_container_length_compact_buffered-ip",
    "go-limit_string_length_binary_buffered-ip",
    "go-limit_string_length_compact_buffered-ip",
    "hs-limit_container_length_binary_buffered-ip",
    "hs-limit_container_length_compact_buffered-ip",
    "hs-limit_string_length_binary_buffered-ip",
    "hs-limit_string_length_compact_buffered-ip",
    "nodejs-limit_container_length_binary_buffered-ip",
    "nodejs-limit_container_length_compact_buffered-ip",
    "nodejs-limit_string_length_binary_buffered-ip",
    "nodejs-limit_string_length_compact_buffered-ip",
    "perl-limit_container_length_binary_buffered-ip",
    "perl-limit_string_length_binary_buffered-ip",
    "rb-limit_container_length_accel-binary_buffered-ip",
    "rb-limit_container_length_binary_buffered-ip",
    "rb-limit_container_length_compact_buffered-ip",
    "rb-limit_string_length_accel-binary_buffered-ip",
    "rb-limit_string_length_binary_buffered-ip",
    "rb-limit_string_length_compact_buffered-ip",
    "rs-limit_container_length_binary_buffered-ip",
    "rs-limit_container_length_compact_buffered-ip",
    "rs-limit_container_length_multic-compact_buffered-ip",
    "rs-limit_string_length_binary_buffered-ip",
    "rs-limit_string_length_compact_buffered-ip",
    "rs-limit_string_length_multic-compact_buffered-ip",
    "netstd-limit_string_length_compact_buffered-ip",
    "netstd-limit_container_length_compact_buffered-ip",
    "nodejs-theader_framed_binary_header_buffered-ip",
    "nodejs-theader_framed_compact_header_buffered-ip"
]
thrift-0.23.0/test/features/index.html0000664000175000017500000000326615165535636020176 0ustar00buildbuild00000000000000




Apache Thrift - integration test suite






Apache Thrift - integration test suite: Results

Server Client Protocol Transport Result (log) Expected

Test Information



browse raw log files



thrift-0.23.0/test/features/local_thrift/0000775000175000017500000000000015165535636020644 5ustar00buildbuild00000000000000thrift-0.23.0/test/features/local_thrift/__init__.py0000664000175000017500000000230615165535636022756 0ustar00buildbuild00000000000000#
# 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 glob
import os
import sys

_SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__))
_ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(_SCRIPT_DIR)))
_LIBDIR = os.path.join(_ROOT_DIR, 'lib', 'py', 'build', 'lib.*')

for libpath in glob.glob(_LIBDIR):
    if libpath.endswith('-%d.%d' % (sys.version_info[0], sys.version_info[1])):
        sys.path.insert(0, libpath)
        thrift = __import__('thrift')
        break
thrift-0.23.0/test/features/string_limit.py0000664000175000017500000000464615167543515021257 0ustar00buildbuild00000000000000#!/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.
#

import argparse
import sys

from util import add_common_args, init_protocol
from local_thrift import thrift  # noqa
from thrift.Thrift import TMessageType, TType


# TODO: generate from ThriftTest.thrift
def test_string(proto, value):
    method_name = 'testString'
    ttype = TType.STRING
    proto.writeMessageBegin(method_name, TMessageType.CALL, 3)
    proto.writeStructBegin(method_name + '_args')
    proto.writeFieldBegin('thing', ttype, 1)
    proto.writeString(value)
    proto.writeFieldEnd()
    proto.writeFieldStop()
    proto.writeStructEnd()
    proto.writeMessageEnd()
    proto.trans.flush()

    _, mtype, _ = proto.readMessageBegin()
    assert mtype == TMessageType.REPLY
    proto.readStructBegin()
    _, ftype, fid = proto.readFieldBegin()
    assert fid == 0
    assert ftype == ttype
    result = proto.readString()
    proto.readFieldEnd()
    _, ftype, _ = proto.readFieldBegin()
    assert ftype == TType.STOP
    proto.readStructEnd()
    proto.readMessageEnd()
    assert value == result


def main(argv):
    p = argparse.ArgumentParser()
    add_common_args(p)
    p.add_argument('--limit', type=int)
    args = p.parse_args()
    proto = init_protocol(args)
    test_string(proto, 'a' * (args.limit - 1))
    test_string(proto, 'a' * (args.limit - 1))
    print('[OK]: limit - 1')
    test_string(proto, 'a' * args.limit)
    test_string(proto, 'a' * args.limit)
    print('[OK]: just limit')
    try:
        test_string(proto, 'a' * (args.limit + 1))
    except Exception:
        print('[OK]: limit + 1')
    else:
        print('[ERROR]: limit + 1')
        assert False


if __name__ == '__main__':
    main(sys.argv[1:])
thrift-0.23.0/test/features/container_limit.py0000664000175000017500000000533015167543515021722 0ustar00buildbuild00000000000000#!/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.
#

import argparse
import sys

from util import add_common_args, init_protocol
from local_thrift import thrift  # noqa
from thrift.Thrift import TMessageType, TType


# TODO: generate from ThriftTest.thrift
def test_list(proto, value):
    method_name = 'testList'
    ttype = TType.LIST
    etype = TType.I32
    proto.writeMessageBegin(method_name, TMessageType.CALL, 3)
    proto.writeStructBegin(method_name + '_args')
    proto.writeFieldBegin('thing', ttype, 1)
    proto.writeListBegin(etype, len(value))
    for e in value:
        proto.writeI32(e)
    proto.writeListEnd()
    proto.writeFieldEnd()
    proto.writeFieldStop()
    proto.writeStructEnd()
    proto.writeMessageEnd()
    proto.trans.flush()

    _, mtype, _ = proto.readMessageBegin()
    assert mtype == TMessageType.REPLY
    proto.readStructBegin()
    _, ftype, fid = proto.readFieldBegin()
    assert fid == 0
    assert ftype == ttype
    etype2, len2 = proto.readListBegin()
    assert etype == etype2
    assert len2 == len(value)
    for i in range(len2):
        v = proto.readI32()
        assert v == value[i]
    proto.readListEnd()
    proto.readFieldEnd()
    _, ftype, _ = proto.readFieldBegin()
    assert ftype == TType.STOP
    proto.readStructEnd()
    proto.readMessageEnd()


def main(argv):
    p = argparse.ArgumentParser()
    add_common_args(p)
    p.add_argument('--limit', type=int)
    args = p.parse_args()
    proto = init_protocol(args)
    # TODO: test set and map
    test_list(proto, list(range(args.limit - 1)))
    test_list(proto, list(range(args.limit - 1)))
    print('[OK]: limit - 1')
    test_list(proto, list(range(args.limit)))
    test_list(proto, list(range(args.limit)))
    print('[OK]: just limit')
    try:
        test_list(proto, list(range(args.limit + 1)))
    except Exception:
        print('[OK]: limit + 1')
    else:
        print('[ERROR]: limit + 1')
        assert False


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
thrift-0.23.0/test/features/theader_binary.py0000664000175000017500000000561615167543515021531 0ustar00buildbuild00000000000000#!/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.
#

import argparse
import socket
import sys

from util import add_common_args
from local_thrift import thrift  # noqa
from thrift.Thrift import TMessageType, TType
from thrift.transport.TSocket import TSocket
from thrift.transport.TTransport import TBufferedTransport, TFramedTransport
from thrift.protocol.TBinaryProtocol import TBinaryProtocol
from thrift.protocol.TCompactProtocol import TCompactProtocol


def test_void(proto):
    proto.writeMessageBegin('testVoid', TMessageType.CALL, 3)
    proto.writeStructBegin('testVoid_args')
    proto.writeFieldStop()
    proto.writeStructEnd()
    proto.writeMessageEnd()
    proto.trans.flush()

    _, mtype, _ = proto.readMessageBegin()
    assert mtype == TMessageType.REPLY
    proto.readStructBegin()
    _, ftype, _ = proto.readFieldBegin()
    assert ftype == TType.STOP
    proto.readStructEnd()
    proto.readMessageEnd()


# THeader stack should accept binary protocol with optionally framed transport
def main(argv):
    p = argparse.ArgumentParser()
    add_common_args(p)
    # Since THeaderTransport acts as framed transport when detected frame, we
    # cannot use --transport=framed as it would result in 2 layered frames.
    p.add_argument('--override-transport')
    p.add_argument('--override-protocol')
    args = p.parse_args()
    assert args.protocol == 'header'
    assert args.transport == 'buffered'
    assert not args.ssl

    sock = TSocket(args.host, args.port, socket_family=socket.AF_INET)
    if not args.override_transport or args.override_transport == 'buffered':
        trans = TBufferedTransport(sock)
    elif args.override_transport == 'framed':
        print('TFRAMED')
        trans = TFramedTransport(sock)
    else:
        raise ValueError('invalid transport')
    trans.open()

    if not args.override_protocol or args.override_protocol == 'binary':
        proto = TBinaryProtocol(trans)
    elif args.override_protocol == 'compact':
        proto = TCompactProtocol(trans)
    else:
        raise ValueError('invalid transport')

    test_void(proto)
    test_void(proto)

    trans.close()


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
thrift-0.23.0/test/features/Makefile.in0000644000175000017500000004266715170007167020241 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/features
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = \
	local_thrift \
	index.html \
	container_limit.py \
	index.html \
	known_failures_Linux.json \
	Makefile.am \
        nosslv3.sh \
	string_limit.py \
	tests.json \
	theader_binary.py \
	setup.cfg \
        tls.sh \
	util.py

all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/features/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/features/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	cscopelist-am ctags-am distclean distclean-generic \
	distclean-libtool distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags-am uninstall uninstall-am

.PRECIOUS: Makefile


distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/features/Makefile.am0000664000175000017500000000205715167543515020227 0ustar00buildbuild00000000000000#
# 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.
#

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	local_thrift \
	index.html \
	container_limit.py \
	index.html \
	known_failures_Linux.json \
	Makefile.am \
        nosslv3.sh \
	string_limit.py \
	tests.json \
	theader_binary.py \
	setup.cfg \
        tls.sh \
	util.py
thrift-0.23.0/test/cl/0000775000175000017500000000000015170007175014736 5ustar00buildbuild00000000000000thrift-0.23.0/test/cl/make-test-client.lisp0000664000175000017500000000752015165535636021015 0ustar00buildbuild00000000000000(in-package #:cl-user)

;;;; 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.

#+(or) (when (not (boundp 'sb-impl::default-external-format)
                 (setf sb-impl::default-external-format :UTF-8)))

(require "asdf")
(load (merge-pathnames "../../lib/cl/load-locally.lisp" *load-truename*))
(require "sb-grovel") ;; necessary for :net.didierverna.clon.termio
(asdf:load-asd (first (directory (merge-pathnames "../../lib/cl/externals/software/clon-*/termio/net.didierverna.clon.termio.asd"
                                                  *load-truename*))))
(asdf:load-system :net.didierverna.clon)
(asdf:load-system :fiasco)
(asdf:load-asd (merge-pathnames "gen-cl/ThriftTest/thrift-gen-ThriftTest.asd" *load-truename*))
(asdf:load-system :thrift-gen-thrifttest)

(net.didierverna.clon:nickname-package)

(defpackage #:thrift-cross
  (:use #:common-lisp #:fiasco)
  (:export #:cross-test))

(in-package #:thrift-cross)

(defparameter *prot* nil)

(load (merge-pathnames "tests.lisp" *load-truename*) :external-format :UTF-8)

(clon:defsynopsis ()
  (text :contents "The Common Lisp client for Thrift's cross-language test suite.")
  (group (:header "Allowed options:")
    (flag :short-name "h" :long-name "help"
          :description "Print this help and exit.")
    (stropt :long-name "host"
            :description "The host to connect to."
            :default-value "localhost"
            :argument-name "ARG")
    (stropt :long-name "port"
            :description "Number of the port to listen for connections on."
            :default-value "9090"
            :argument-name "ARG"
            :argument-type :optional)
    (stropt :long-name "transport"
            :description "Transport: transport to use (\"buffered\", \"framed\")"
            :default-value "buffered"
            :argument-name "ARG")
    (stropt :long-name "protocol"
            :description "Protocol: protocol to use (\"binary\", \"multi\")"
            :default-value "binary"
            :argument-name "ARG")))

(defun main ()
  "Entry point for our standalone application."
  (clon:make-context)
  (when (clon:getopt :short-name "h")
    (clon:help)
    (clon:exit))
  (let ((port "9090")
        (host "localhost")
        (framed nil)
        (multiplexed nil))
    (clon:do-cmdline-options (option name value source)
      (print (list option name value source))
      (if (string= name "host")
          (setf host value))
      (if (string= name "port")
          (setf port value))
      (if (string= name "transport")
          (cond ((string= value "buffered") (setf framed nil))
                ((string= value "framed") (setf framed t))
                (t (error "Unsupported transport."))))
      (if (string= name "protocol")
          (cond ((string= value "binary") (setf multiplexed nil))
                ((string= value "multi") (setf multiplexed t))
                (t (error "Unsupported protocol.")))))
    (terpri)
    (setf *prot* (thrift.implementation::client (puri:parse-uri
                                                 (concatenate 'string "thrift://" host ":" port))
                                                :framed framed
                                                :multiplexed multiplexed))
    (let ((result (cross-test :multiplexed multiplexed)))
      (thrift.implementation::close *prot*)
      (clon:exit result))))

(clon:dump "TestClient" main)
thrift-0.23.0/test/cl/make-test-server.lisp0000664000175000017500000000703515165535636021046 0ustar00buildbuild00000000000000(in-package #:cl-user)

;;;; 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.

(require "asdf")
(load (merge-pathnames "../../lib/cl/load-locally.lisp" *load-truename*))
(require "sb-grovel") ;; necessary for :net.didierverna.clon.termio
(asdf:load-asd (first (directory (merge-pathnames "../../lib/cl/externals/software/clon-*/termio/net.didierverna.clon.termio.asd"
                                                  *load-truename*))))
(asdf:load-system :net.didierverna.clon)
(asdf:load-asd (merge-pathnames "gen-cl/ThriftTest/thrift-gen-ThriftTest.asd" *load-truename*))
(asdf:load-system :thrift-gen-thrifttest)
(load (merge-pathnames "implementation.lisp" *load-truename*))

(net.didierverna.clon:nickname-package)

(clon:defsynopsis ()
  (text :contents "The Common Lisp server for Thrift's cross-language test suite.")
  (group (:header "Allowed options:")
    (flag :short-name "h" :long-name "help"
          :description "Print this help and exit.")
    (stropt :long-name "port"
            :description "Number of the port to listen for connections on."
            :default-value "9090"
            :argument-name "ARG"
            :argument-type :optional)
    (stropt :long-name "server-type"
            :description "The type of server, currently only \"simple\" is available."
            :default-value "simple"
            :argument-name "ARG")
    (stropt :long-name "transport"
            :description "Transport: transport to use (\"buffered\" or \"framed\")"
            :default-value "buffered"
            :argument-name "ARG")
    (stropt :long-name "protocol"
            :description "Protocol: protocol to use (\"binary\" or \"multi\")"
            :default-value "binary"
            :argument-name "ARG")))

(defun main ()
  "Entry point for our standalone application."
  (clon:make-context)
  (when (clon:getopt :short-name "h")
    (clon:help)
    (clon:exit))
  (let ((port "9090")
        (framed nil)
        (multiplexed nil))
    (clon:do-cmdline-options (option name value source)
      (print (list option name value source))
      (if (string= name "port")
          (setf port value))
      (if (string= name "transport")
          (cond ((string= value "buffered") (setf framed nil))
                ((string= value "framed") (setf framed t))
                (t (error "Unsupported transport."))))
      (if (string= name "protocol")
          (cond ((string= value "binary") (setf multiplexed nil))
                ((string= value "multi") (setf multiplexed t))
                (t (error "Unsupported protocol.")))))
    (terpri)
    (let ((services (if multiplexed
                        (list thrift.test:thrift-test thrift.test:second-service)
                        thrift.test:thrift-test)))
      (thrift:serve (puri:parse-uri (concatenate 'string
                                                 "thrift://127.0.0.1:"
                                                 port))
                    services
                    :framed framed
                    :multiplexed multiplexed)))
  (clon:exit))

(clon:dump "TestServer" main)
thrift-0.23.0/test/cl/implementation.lisp0000664000175000017500000001205715165535636020675 0ustar00buildbuild00000000000000(in-package #:thrift.test-implementation)

;;;; 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.

(defun thrift.test.thrift-test-implementation:test-void ()
  (format t "testVoid()~%"))

(defun thrift.test.thrift-test-implementation:test-string (thing)
  (format t "testString(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-bool (thing)
  (format t "testBool(~a)~%" (if thing "true" "false"))
  thing)

(defun thrift.test.thrift-test-implementation:test-byte (thing)
  (format t "testByte(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-i32 (thing)
  (format t "testI32(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-i64 (thing)
  (format t "testI64(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-double (thing)
  (format t "testDouble(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-binary (thing)
  (format t "testBinary(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-struct (thing)
  (format t "testStruct(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-nest (thing)
  (format t "testNest(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-map (thing)
  (format t "testMap(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-string-map (thing)
  (format t "testStringMap(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-set (thing)
  (format t "testSet(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-list (thing)
  (format t "testList(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-enum (thing)
  (format t "testEnum(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-typedef (thing)
  (format t "testTypedef(~a)~%" thing)
  thing)

(defun thrift.test.thrift-test-implementation:test-map-map (hello)
  (format t "testMapMap(~a)~%" hello)
  '((-4 . ((-4 . -4) (-3 . -3) (-2 . -2) (-1 . -1))) (4 . ((1 . 1) (2 . 2) (3 . 3) (4 . 4)))))

(defun thrift.test.thrift-test-implementation:test-insanity (argument)
  (let ((result `((1 . ((2 . ,argument) (3 . ,argument)))
                  (2 . ((6 . ,(thrift.test::make-insanity :user-map nil :xtructs nil)))))))
    (format t "~a~%" result)
    result))

(defun thrift.test.thrift-test-implementation:test-multi (arg0 arg1 arg2 arg3 arg4 arg5)
  (declare (ignorable arg3 arg4 arg5))
  (format t "testMulti()~%")
  (thrift.test:make-xtruct :string-thing "Hello2"
                           :byte-thing arg0
                           :i32-thing arg1
                           :i64-thing arg2))

(defun thrift.test.thrift-test-implementation:test-exception (arg)
  (format t "testException(~a)~%" arg)
  (cond
    ((string= arg "Xception") (error 'thrift.test:xception
                                     :error-code 1001
                                     :message arg))
    ((string= arg "TException") (error 'thrift.test:xception
                                       :error-code 0
                                       :message "Stuff!"))))

(defun thrift.test.thrift-test-implementation:test-multi-exception (arg0 arg1)
  (format t "testMultiException(~a, ~a)~%" arg0 arg1)
  (cond
    ((string= arg0 "Xception") (error 'thrift.test:xception
                                     :error-code 1001
                                     :message "This is an Xception"))
    ((string= arg0 "Xception2") (error 'thrift.test:xception2
                                     :error-code 2002
                                     :struct-thing (thrift.test:make-xtruct :string-thing "This is an Xception2"
                                                                            :byte-thing 0
                                                                            :i32-thing 0
                                                                            :i64-thing 0))))
  (thrift.test:make-xtruct :string-thing arg1
                           :byte-thing 0
                           :i32-thing 0
                           :i64-thing 0))

(defun thrift.test.thrift-test-implementation:test-oneway (seconds)
  (format t "testOneway(~a): Sleeping...~%" seconds)
  (sleep seconds)
  (format t "testOneway(~a): done sleeping!~%" seconds))

;;; Removed from the IDL definition.
#+(or)
(defun thrift.test.second-service-implementation:blah-blah ()
  (format t "blahBlah()~%"))

(defun thrift.test.second-service-implementation:secondtest-string (thing)
  (format t "secondtestString(~a)~%" thing)
  (concatenate 'string "testString(\"" thing "\")"))

thrift-0.23.0/test/cl/Makefile0000644000175000017500000004423115170007175016400 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/cl/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#
# 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.
#

am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
subdir = test/cl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = $(top_builddir)/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/cl
abs_srcdir = /thrift/src/test/cl
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..
EXTRA_DIST = \
	implementation.lisp \
	make-test-client.lisp \
	make-test-server.lisp \
	tests.lisp

all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/cl/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/cl/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am distclean distclean-generic \
	distclean-libtool distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: ../ThriftTest.thrift
	$(THRIFT) --gen cl ../ThriftTest.thrift

TestServer: make-test-server.lisp
	$(SBCL) --script make-test-server.lisp

TestClient: make-test-client.lisp
	$(SBCL) --script make-test-client.lisp

precross: stubs TestServer TestClient

clean-local:
	$(RM) -r gen-cl
	$(RM) TestServer
	$(RM) TestClient

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/cl/tests.lisp0000664000175000017500000003423115165535636017010 0ustar00buildbuild00000000000000(in-package #:thrift-cross)

;;;; 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.

;;;; The tests here only make sense in the context of a TestServer
;;;; running and the dynamic variable thrift-cross::*prot*
;;;; being set with a client connection to the TestServer. Normally,
;;;; this is handled in make-test-client.lisp.


;;; Standard Thrift cross-test error codes
(defparameter *test_basetypes* 1)
(defparameter *test_structs* 2)
(defparameter *test_containers* 4)
(defparameter *test_exceptions* 8)
(defparameter *test_unknown* 64)
(defparameter *test_timeout* 128)

(defun cross-test (&key (multiplexed nil))
  "The main cross-test runner."
  (let ((result nil))
    (handler-case
        (progn
          (unless (run-package-tests :package :base-types)
            (pushnew *test_basetypes* result))
          (unless (run-package-tests :package :structs)
            (pushnew *test_structs* result))
          (unless (run-package-tests :package :containers)
            (pushnew *test_containers* result))
          (unless (run-package-tests :package :exceptions)
            (pushnew *test_exceptions* result))
          (unless (run-package-tests :package :misc)
            (pushnew *test_unknown* result))

          ;; It doesn't seem like anyone actually uses
          ;; the second test service when testing multiplexing,
          ;; so this would fail against servers in other
          ;; languages. For now, anyway.
          #+(or)
          (when multiplexed
            (unless (run-package-tests :package :multiplex)
              (pushnew *test_unknown* result))))
      (error (e) (pushnew *test_unknown* result)))
    (apply #'+ result)))

(fiasco:define-test-package #:base-types)

(in-package #:base-types)

(defconstant *lang-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, 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ú, 粵語")

(defparameter *trick-string* (format nil "quote: \" backslash: \\ newline: ~% backspace: ~C ~
                                          tab: ~T junk: !@#$%&()(&%$#{}{}<><><" #\backspace))

(defconstant *binary-sequence* #(128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127))

(deftest void-test ()
  (is (null (thrift.test.thrift-test:test-void thrift-cross::*prot*))))

(deftest boolean-test ()
  (is (thrift.test.thrift-test:test-bool thrift-cross::*prot* t))
  (is (not (thrift.test.thrift-test:test-bool thrift-cross::*prot* nil))))

(deftest integer-test ()
  (is (= (thrift.test.thrift-test:test-byte thrift-cross::*prot* 127) 127))
  (is (= (thrift.test.thrift-test:test-byte thrift-cross::*prot* -128) -128))
  (is (= (thrift.test.thrift-test:test-byte thrift-cross::*prot* 42) 42))
  (is (= (thrift.test.thrift-test:test-byte thrift-cross::*prot* 0) 0))
  (is (= (thrift.test.thrift-test:test-i32 thrift-cross::*prot* 0) 0))
  (is (= (thrift.test.thrift-test:test-i32 thrift-cross::*prot* 2147483647) 2147483647))
  (is (= (thrift.test.thrift-test:test-i32 thrift-cross::*prot* -2147483648) -2147483648))
  (is (= (thrift.test.thrift-test:test-i64 thrift-cross::*prot* 0) 0))
  (is (= (thrift.test.thrift-test:test-i64 thrift-cross::*prot* 9223372036854775807) 9223372036854775807))
  (is (= (thrift.test.thrift-test:test-i64 thrift-cross::*prot* -9223372036854775808) -9223372036854775808)))

(deftest double-test ()
  (is (= (thrift.test.thrift-test:test-double thrift-cross::*prot* 0.0) 0))
  (is (= (thrift.test.thrift-test:test-double thrift-cross::*prot* 42.0) 42))
  (is (= (thrift.test.thrift-test:test-double thrift-cross::*prot* -555.0) -555))
  (is (= (thrift.test.thrift-test:test-double thrift-cross::*prot* -52.3678) -52.3678)))

(deftest string-test ()
  (is (string= (thrift.test.thrift-test:test-string thrift-cross::*prot* "") ""))
  (is (string= (thrift.test.thrift-test:test-string thrift-cross::*prot* "(defun botsbuildbots () (botsbuilsbots))")
               "(defun botsbuildbots () (botsbuilsbots))"))
  (is (string= (thrift.test.thrift-test:test-string thrift-cross::*prot* *lang-string*) *lang-string*))
  (is (string= (thrift.test.thrift-test:test-string thrift-cross::*prot* *trick-string*) *trick-string*)))

(deftest binary-test ()
  (is (equalp (thrift.test.thrift-test:test-binary thrift-cross::*prot* #()) #()))
  (is (equalp (thrift.test.thrift-test:test-binary thrift-cross::*prot* *binary-sequence*) *binary-sequence*)))

(deftest enum-test ()
  (is (= (thrift.test.thrift-test:test-enum thrift-cross::*prot* thrift.test:numberz.five) thrift.test:numberz.five))
  (is (= (thrift.test.thrift-test:test-enum thrift-cross::*prot* thrift.test:numberz.eight) thrift.test:numberz.eight))
  (is (= (thrift.test.thrift-test:test-enum thrift-cross::*prot* thrift.test:numberz.one) thrift.test:numberz.one)))

(deftest typedef-test ()
  (is (= (thrift.test.thrift-test:test-typedef thrift-cross::*prot* 309858235082523) 309858235082523)))

(fiasco:define-test-package #:structs)

(in-package #:structs)

(defparameter *test-struct* (thrift.test:make-xtruct :string-thing "Hell is empty."
                                                     :byte-thing -2
                                                     :i32-thing 42
                                                     :i64-thing 42424242))

(defparameter *test-nest* (thrift.test:make-xtruct2 :byte-thing 42
                                                    :struct-thing *test-struct*
                                                    :i32-thing -42))

(deftest struct-test ()
  (let ((rec-struct (thrift.test.thrift-test:test-struct thrift-cross::*prot* *test-struct*)))
    (is (string= (thrift.test:xtruct-string-thing *test-struct*)
                 (thrift.test:xtruct-string-thing rec-struct)))
    (is (= (thrift.test:xtruct-byte-thing *test-struct*)
           (thrift.test:xtruct-byte-thing rec-struct)))
    (is (= (thrift.test:xtruct-i32-thing *test-struct*)
           (thrift.test:xtruct-i32-thing rec-struct)))
    (is (= (thrift.test:xtruct-i64-thing *test-struct*)
           (thrift.test:xtruct-i64-thing rec-struct)))))

(deftest nest-test ()
  (let* ((rec-nest (thrift.test.thrift-test:test-nest thrift-cross::*prot* *test-nest*))
         (rec-struct (thrift.test:xtruct2-struct-thing rec-nest)))
    (is (string= (thrift.test:xtruct-string-thing *test-struct*)
                 (thrift.test:xtruct-string-thing rec-struct)))
    (is (= (thrift.test:xtruct-byte-thing *test-struct*)
           (thrift.test:xtruct-byte-thing rec-struct)))
    (is (= (thrift.test:xtruct-i32-thing *test-struct*)
           (thrift.test:xtruct-i32-thing rec-struct)))
    (is (= (thrift.test:xtruct-i64-thing *test-struct*)
           (thrift.test:xtruct-i64-thing rec-struct)))
    (is (= (thrift.test:xtruct2-byte-thing *test-nest*)
           (thrift.test:xtruct2-byte-thing rec-nest)))
    (is (= (thrift.test:xtruct2-i32-thing *test-nest*)
           (thrift.test:xtruct2-i32-thing rec-nest)))))

(fiasco:define-test-package #:containers)

(in-package #:containers)

(deftest list-test ()
  (is (null (thrift.test.thrift-test:test-list thrift-cross::*prot* nil)))
  (is (equal (thrift.test.thrift-test:test-list thrift-cross::*prot* '(42 -42 0 5)) '(42 -42 0 5))))

(deftest set-test ()
  (is (null (thrift.test.thrift-test:test-set thrift-cross::*prot* nil)))
  (is (equal (sort (thrift.test.thrift-test:test-set thrift-cross::*prot* (list 42 -42 0 5)) #'<)
             '(-42 0 5 42))))

(defun map= (map1 map2 &key (car-predicate #'equal) (cdr-predicate #'equal))
  "Compare two assoc maps according to the predicates given."
  (not (set-exclusive-or map1 map2 :test (lambda (el1 el2)
                                           (and (funcall car-predicate
                                                         (car el1)
                                                         (car el2))
                                                (funcall cdr-predicate
                                                         (cdr el1)
                                                         (cdr el2)))))))

(deftest map-test ()
  (is (null (thrift.test.thrift-test:test-map thrift-cross::*prot* nil)))
  (is (map= (thrift.test.thrift-test:test-map thrift-cross::*prot* '((0 . 1) (42 . -42) (5 . 5)))
            '((0 . 1) (42 . -42) (5 . 5))))
  (is (map= (thrift.test.thrift-test:test-map-map thrift-cross::*prot* 42)
            '((-4 . ((-4 . -4) (-3 . -3) (-2 . -2) (-1 . -1)))
              (4 . ((1 . 1) (2 . 2) (3 . 3) (4 . 4))))
            :cdr-predicate #'map=)))

(fiasco:define-test-package #:exceptions)

(in-package #:exceptions)

(defun test-xception (expected-code expected-message function &rest args)
  "A helper function to test whether xception is signalled, and whether its fields have the expected values."
  (handler-case (progn (apply function args)
                       nil)
    (thrift.test:xception (ex) (and (= (thrift.test::xception-error-code ex) expected-code)
                                    (string= (thrift.test::xception-message ex) expected-message)))))

(defun test-xception2 (expected-code expected-message function &rest args)
  "A helper function to test whether xception2 is signalled, and whether its fields have the expected values."
  (handler-case (progn (apply function args)
                       nil)
    (thrift.test:xception2 (ex) (and (= (thrift.test::xception2-error-code ex) expected-code)
                                     (string= (thrift.test::xtruct-string-thing
                                               (thrift.test::xception2-struct-thing ex))
                                              expected-message)))))

(deftest exception-test ()
  (is (test-xception 1001 "Xception" #'thrift.test.thrift-test:test-exception thrift-cross::*prot* "Xception"))
  (signals thrift:application-error (thrift.test.thrift-test:test-exception thrift-cross::*prot* "TException"))
  (finishes (thrift.test.thrift-test:test-exception thrift-cross::*prot* "success")))

(deftest multi-exception-test ()
  (is (test-xception 1001
                     "This is an Xception"
                     #'thrift.test.thrift-test:test-multi-exception
                     thrift-cross::*prot*
                     "Xception"
                     "meaningless"))
  (is (test-xception2 2002
                      "This is an Xception2"
                      #'thrift.test.thrift-test:test-multi-exception
                      thrift-cross::*prot*
                      "Xception2"
                      "meaningless too!"))
  (is (string= "foobar" (thrift.test:xtruct-string-thing
                         (thrift.test.thrift-test:test-multi-exception thrift-cross::*prot*
                                                           "success!"
                                                           "foobar")))))

(fiasco:define-test-package #:misc)

(in-package #:misc)

(deftest oneway-test ()
  (is (null (thrift.test.thrift-test:test-oneway thrift-cross::*prot* 1))))

(fiasco:define-test-package #:multiplex)

(in-package #:multiplex)

(deftest multiplex-test ()
  ;; Removed from the IDL definition.
  ;; (finishes (thrift.test.second-service:blah-blah thrift-cross::*prot*))
  (is (string= "asd" (thrift.test.second-service:secondtest-string thrift-cross::*prot* "asd"))))
thrift-0.23.0/test/cl/Makefile.in0000644000175000017500000004322315170007167017006 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/cl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = $(top_builddir)/compiler/cpp/thrift
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = \
	implementation.lisp \
	make-test-client.lisp \
	make-test-server.lisp \
	tests.lisp

all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/cl/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/cl/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am distclean distclean-generic \
	distclean-libtool distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: ../ThriftTest.thrift
	$(THRIFT) --gen cl ../ThriftTest.thrift

TestServer: make-test-server.lisp
	$(SBCL) --script make-test-server.lisp

TestClient: make-test-client.lisp
	$(SBCL) --script make-test-client.lisp

precross: stubs TestServer TestClient

clean-local:
	$(RM) -r gen-cl
	$(RM) TestServer
	$(RM) TestClient

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/cl/Makefile.am0000775000175000017500000000243015165535636017010 0ustar00buildbuild00000000000000#
# 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.
#

THRIFT = $(top_builddir)/compiler/cpp/thrift

stubs: ../ThriftTest.thrift
	$(THRIFT) --gen cl ../ThriftTest.thrift

TestServer: make-test-server.lisp
	$(SBCL) --script make-test-server.lisp

TestClient: make-test-client.lisp
	$(SBCL) --script make-test-client.lisp

precross: stubs TestServer TestClient

clean-local:
	$(RM) -r gen-cl
	$(RM) TestServer
	$(RM) TestClient

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	implementation.lisp \
	make-test-client.lisp \
	make-test-server.lisp \
	tests.lisp
thrift-0.23.0/test/c_glib/0000775000175000017500000000000015170007201015545 5ustar00buildbuild00000000000000thrift-0.23.0/test/c_glib/src/0000775000175000017500000000000015170007202016335 5ustar00buildbuild00000000000000thrift-0.23.0/test/c_glib/src/thrift_test_handler.c0000664000175000017500000005631715165535636022576 0ustar00buildbuild00000000000000/*
 * 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 

#include "thrift_test_handler.h"

/* A handler that implements the TTestThriftTestIf interface */

G_DEFINE_TYPE (ThriftTestHandler,
               thrift_test_handler,
               T_TEST_TYPE_THRIFT_TEST_HANDLER)

gboolean
thrift_test_handler_test_void (TTestThriftTestIf  *iface,
                               GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testVoid()\n");

  return TRUE;
}

gboolean
thrift_test_handler_test_string (TTestThriftTestIf  *iface,
                                 gchar             **_return,
                                 const gchar        *thing,
                                 GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testString(\"%s\")\n", thing);
  *_return = g_strdup (thing);

  return TRUE;
}

gboolean
thrift_test_handler_test_bool (TTestThriftTestIf  *iface,
                               gboolean           *_return,
                               const gboolean      thing,
                               GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testBool(%s)\n", thing ? "true" : "false");
  *_return = thing;

  return TRUE;
}

gboolean
thrift_test_handler_test_byte (TTestThriftTestIf  *iface,
                               gint8              *_return,
                               const gint8         thing,
                               GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testByte(%d)\n", (gint)thing);
  *_return = thing;

  return TRUE;
}

gboolean
thrift_test_handler_test_i32 (TTestThriftTestIf  *iface,
                              gint32             *_return,
                              const gint32        thing,
                              GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testI32(%d)\n", thing);
  *_return = thing;

  return TRUE;
}

gboolean
thrift_test_handler_test_i64 (TTestThriftTestIf  *iface,
                              gint64             *_return,
                              const gint64        thing,
                              GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testI64(%" PRId64 ")\n", thing);
  *_return = thing;

  return TRUE;
}

gboolean
thrift_test_handler_test_double (TTestThriftTestIf  *iface,
                                 gdouble            *_return,
                                 const gdouble       thing,
                                 GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testDouble(%f)\n", thing);
  *_return = thing;

  return TRUE;
}

gboolean 
thrift_test_handler_test_binary (TTestThriftTestIf *iface,
                                 GByteArray ** _return,
                                 const GByteArray * thing,
                                 GError **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testBinary()\n");  // TODO: hex output
  g_byte_array_ref((GByteArray *)thing);
  *_return = (GByteArray *)thing;

  return TRUE;
}

gboolean
thrift_test_handler_test_struct (TTestThriftTestIf  *iface,
                                 TTestXtruct       **_return,
                                 const TTestXtruct  *thing,
                                 GError            **error)
{
  gchar *string_thing = NULL;
  gint   byte_thing;
  gint   i32_thing;
  gint64 i64_thing;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  g_object_get ((TTestXtruct *)thing,
                "string_thing", &string_thing,
                "byte_thing",   &byte_thing,
                "i32_thing",    &i32_thing,
                "i64_thing",    &i64_thing,
                NULL);

  printf ("testStruct({\"%s\", %d, %d, %" PRId64 "})\n",
          string_thing,
          (gint)byte_thing,
          i32_thing,
          i64_thing);

  g_object_set (*_return,
                "string_thing", string_thing,
                "byte_thing",   byte_thing,
                "i32_thing",    i32_thing,
                "i64_thing",    i64_thing,
                NULL);

  if (string_thing != NULL)
    g_free (string_thing);

  return TRUE;
}

gboolean
thrift_test_handler_test_nest (TTestThriftTestIf   *iface,
                               TTestXtruct2       **_return,
                               const TTestXtruct2  *thing,
                               GError             **error)
{
  gchar *inner_string_thing = NULL;
  gint   byte_thing, inner_byte_thing;
  gint   i32_thing, inner_i32_thing;
  gint64 inner_i64_thing;
  TTestXtruct *struct_thing;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  g_object_get ((TTestXtruct2 *)thing,
                "byte_thing",   &byte_thing,
                "struct_thing", &struct_thing,
                "i32_thing",    &i32_thing,
                NULL);
  g_object_get (struct_thing,
                "string_thing", &inner_string_thing,
                "byte_thing",   &inner_byte_thing,
                "i32_thing",    &inner_i32_thing,
                "i64_thing",    &inner_i64_thing,
                NULL);

  printf ("testNest({%d, {\"%s\", %d, %d, %" PRId64 "}, %d})\n",
          byte_thing,
          inner_string_thing,
          inner_byte_thing,
          inner_i32_thing,
          inner_i64_thing,
          i32_thing);

  g_object_set (*_return,
                "byte_thing",   byte_thing,
                "struct_thing", struct_thing,
                "i32_thing",    i32_thing,
                NULL);

  if (inner_string_thing != NULL)
    g_free (inner_string_thing);
  g_object_unref (struct_thing);

  return TRUE;
}

gboolean
thrift_test_handler_test_map (TTestThriftTestIf  *iface,
                              GHashTable        **_return,
                              const GHashTable   *thing,
                              GError            **error)
{
  GHashTableIter hash_table_iter;
  gpointer key;
  gpointer value;
  gboolean first = TRUE;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testMap({");
  g_hash_table_iter_init (&hash_table_iter, (GHashTable *)thing);
  while (g_hash_table_iter_next (&hash_table_iter,
                                 &key,
                                 &value)) {
    gint32 *new_key;
    gint32 *new_value;

    if (first)
      first = FALSE;
    else
      printf (", ");

    printf ("%d => %d", *(gint32 *)key, *(gint32 *)value);

    new_key = g_malloc (sizeof *new_key);
    *new_key = *(gint32 *)key;
    new_value = g_malloc (sizeof *new_value);
    *new_value = *(gint32 *)value;
    g_hash_table_insert (*_return, new_key, new_value);
  }
  printf ("})\n");

  return TRUE;
}

gboolean
thrift_test_handler_test_string_map (TTestThriftTestIf  *iface,
                                     GHashTable        **_return,
                                     const GHashTable   *thing,
                                     GError            **error)
{
  GHashTableIter hash_table_iter;
  gpointer key;
  gpointer value;
  gboolean first = TRUE;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testStringMap({");
  g_hash_table_iter_init (&hash_table_iter, (GHashTable *)thing);
  while (g_hash_table_iter_next (&hash_table_iter,
                                 &key,
                                 &value)) {
    gchar *new_key;
    gchar *new_value;

    if (first)
      first = FALSE;
    else
      printf (", ");

    printf ("%s => %s", (gchar *)key, (gchar *)value);

    new_key = g_strdup ((gchar *)key);
    new_value = g_strdup ((gchar *)value);
    g_hash_table_insert (*_return, new_key, new_value);
  }
  printf ("})\n");

  return TRUE;
}

gboolean
thrift_test_handler_test_set (TTestThriftTestIf  *iface,
                              GHashTable        **_return,
                              const GHashTable   *thing,
                              GError            **error)
{
  GHashTableIter hash_table_iter;
  gpointer key;
  gboolean first = TRUE;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testSet({");
  g_hash_table_iter_init (&hash_table_iter, (GHashTable *)thing);
  while (g_hash_table_iter_next (&hash_table_iter,
                                 &key,
                                 NULL)) {
    gint32 *new_key;

    if (first)
      first = FALSE;
    else
      printf (", ");

    printf ("%d", *(gint32 *)key);

    new_key = g_malloc (sizeof *new_key);
    *new_key = *(gint32 *)key;
    g_hash_table_insert (*_return, new_key, NULL);
  }
  printf ("})\n");

  return TRUE;
}

gboolean
thrift_test_handler_test_list (TTestThriftTestIf  *iface,
                               GArray            **_return,
                               const GArray       *thing,
                               GError            **error)
{
  guint i;
  gboolean first = TRUE;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testList({");
  for (i = 0; i < thing->len; i += 1) {
    gint32 value;
    gint32 new_value;

    if (first)
      first = FALSE;
    else
      printf (", ");

    value = g_array_index (thing, gint32, i);
    printf ("%d", value);

    new_value = value;
    g_array_append_val (*_return, new_value);
  }
  printf ("})\n");

  return TRUE;
}

gboolean
thrift_test_handler_test_enum (TTestThriftTestIf   *iface,
                               TTestNumberz        *_return,
                               const TTestNumberz   thing,
                               GError             **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testEnum(%d)\n", thing);
  *_return = thing;

  return TRUE;
}

gboolean
thrift_test_handler_test_typedef (TTestThriftTestIf  *iface,
                                  TTestUserId        *_return,
                                  const TTestUserId   thing,
                                  GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testTypedef(%" PRId64 ")\n", thing);
  *_return = thing;

  return TRUE;
}

gboolean
thrift_test_handler_test_map_map (TTestThriftTestIf  *iface,
                                  GHashTable        **_return,
                                  const gint32        hello,
                                  GError            **error)
{
  GHashTable *positive;
  GHashTable *negative;
  gint32 *key;
  gint32 *value;
  guint i;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testMapMap(%d)\n", hello);

  positive = g_hash_table_new_full (g_int_hash,
                                    g_int_equal,
                                    g_free,
                                    g_free);
  negative = g_hash_table_new_full (g_int_hash,
                                    g_int_equal,
                                    g_free,
                                    g_free);

  for (i = 1; i < 5; i += 1) {
    key = g_malloc (sizeof *key);
    value = g_malloc (sizeof *value);
    *key = i;
    *value = i;
    g_hash_table_insert (positive, key, value);

    key = g_malloc (sizeof *key);
    value = g_malloc (sizeof *value);
    *key = -i;
    *value = -i;
    g_hash_table_insert (negative, key, value);
  }

  key = g_malloc (sizeof *key);
  *key = 4;
  g_hash_table_insert (*_return, key, positive);

  key = g_malloc (sizeof *key);
  *key = -4;
  g_hash_table_insert (*_return, key, negative);

  return TRUE;
}

gboolean
thrift_test_handler_test_insanity (TTestThriftTestIf    *iface,
                                   GHashTable          **_return,
                                   const TTestInsanity  *argument,
                                   GError              **error)
{
  TTestXtruct *xtruct_in;

  gchar *string_thing = NULL;
  gint   byte_thing;
  gint   i32_thing;
  gint64 i64_thing;

  GPtrArray *xtructs;

  TTestInsanity *looney;

  GHashTable *user_map;
  GHashTable *first_map;
  GHashTable *second_map;

  GHashTableIter hash_table_iter;
  GHashTableIter inner_hash_table_iter;
  GHashTableIter user_map_iter;

  gpointer key;
  gpointer value;

  TTestUserId *user_id;

  guint i;

  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testInsanity()\n");

  first_map = g_hash_table_new_full (g_direct_hash,
                                     g_direct_equal,
                                     NULL,
                                     g_object_unref);
  second_map = g_hash_table_new_full (g_direct_hash,
                                      g_direct_equal,
                                      NULL,
                                      g_object_unref);

  g_hash_table_insert (first_map,
                       GINT_TO_POINTER (T_TEST_NUMBERZ_TWO),
                       (gpointer)argument);
  g_hash_table_insert (first_map,
                       GINT_TO_POINTER (T_TEST_NUMBERZ_THREE),
                       (gpointer)argument);

  /* Increment argument's ref count by two because first_map now holds
     two references to it and the caller is not aware we have made any
     additional references to argument.  (That is, caller owns argument
     and will unref it explicitly in addition to unref-ing *_return.)

     We do this instead of creating a copy of argument in order to mimic
     the C++ implementation (and since, frankly, the world needs less
     argument, not more). */
  g_object_ref ((gpointer)argument);
  g_object_ref ((gpointer)argument);

  looney = g_object_new (T_TEST_TYPE_INSANITY, NULL);
  g_hash_table_insert (second_map,
                       GINT_TO_POINTER (T_TEST_NUMBERZ_SIX),
                       looney);

  user_id = g_malloc (sizeof *user_id);
  *user_id = 1;
  g_hash_table_insert (*_return, user_id, first_map);

  user_id = g_malloc (sizeof *user_id);
  *user_id = 2;
  g_hash_table_insert (*_return, user_id, second_map);

  printf ("return");
  printf (" = {");
  g_hash_table_iter_init (&hash_table_iter, *_return);
  while (g_hash_table_iter_next (&hash_table_iter,
                                 &key,
                                 &value)) {
    printf ("%" PRId64 " => {", *(TTestUserId *)key);

    g_hash_table_iter_init (&inner_hash_table_iter,
                            (GHashTable *)value);
    while (g_hash_table_iter_next (&inner_hash_table_iter,
                                   &key,
                                   &value)) {
      printf ("%d => {", (TTestNumberz)key);

      g_object_get ((TTestInsanity *)value,
                    "userMap", &user_map,
                    "xtructs", &xtructs,
                    NULL);

      printf ("{");
      g_hash_table_iter_init (&user_map_iter, user_map);
      while (g_hash_table_iter_next (&user_map_iter,
                                     &key,
                                     &value)) {
        printf ("%d => %" PRId64 ", ",
                (TTestNumberz)key,
                *(TTestUserId *)value);
      }
      printf ("}, ");
      g_hash_table_unref (user_map);

      printf ("{");
      for (i = 0; i < xtructs->len; ++i) {
        xtruct_in = g_ptr_array_index (xtructs, i);
        g_object_get (xtruct_in,
                      "string_thing", &string_thing,
                      "byte_thing",   &byte_thing,
                      "i32_thing",    &i32_thing,
                      "i64_thing",    &i64_thing,
                      NULL);

        printf ("{\"%s\", %d, %d, %" PRId64 "}, ",
                string_thing,
                byte_thing,
                i32_thing,
                i64_thing);
        if (string_thing != NULL) {
          g_free (string_thing);
        }
      }
      printf ("}");
      g_ptr_array_unref (xtructs);

      printf ("}, ");
    }
    printf ("}, ");
  }
  printf ("}\n");

  return TRUE;
}

gboolean
thrift_test_handler_test_multi (TTestThriftTestIf   *iface,
                                TTestXtruct        **_return,
                                const gint8          arg0,
                                const gint32         arg1,
                                const gint64         arg2,
                                const GHashTable    *arg3,
                                const TTestNumberz   arg4,
                                const TTestUserId    arg5,
                                GError             **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);
  THRIFT_UNUSED_VAR (arg3);
  THRIFT_UNUSED_VAR (arg4);
  THRIFT_UNUSED_VAR (arg5);

  printf ("testMulti()\n");

  g_object_set (*_return,
                "string_thing", "Hello2",
                "byte_thing",    arg0,
                "i32_thing",     arg1,
                "i64_thing",     arg2,
                NULL);

  return TRUE;
}

gboolean
thrift_test_handler_test_exception (TTestThriftTestIf  *iface,
                                    const gchar        *arg,
                                    TTestXception     **err1,
                                    GError            **error)
{
  THRIFT_UNUSED_VAR (iface);

  TTestXtruct *xtruct;
  gboolean result;

  printf ("testException(%s)\n", arg);

  /* Unlike argument objects, exception objects are not pre-created */
  g_assert (*err1 == NULL);

  if (strncmp (arg, "Xception", 9) == 0) {
    /* "Throw" a custom exception: Set the corresponding exception
       argument, set *error to NULL and return FALSE */
    *err1 = g_object_new (T_TEST_TYPE_XCEPTION,
                          "errorCode", 1001,
                          "message",   arg,
                          NULL);
    *error = NULL;
    result = FALSE;
  }
  else if (strncmp (arg, "TException", 11) == 0) {
    /* "Throw" a generic TException (ThriftApplicationException): Set
       all exception arguments to NULL, set *error and return FALSE */
    *err1 = NULL;
    g_set_error (error,
                 thrift_application_exception_error_quark (),
                 THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN,
                 "Default TException.");
    result = FALSE;
  }
  else {
    *err1 = NULL;
    *error = NULL;

    /* This code is duplicated from the C++ test suite, though it
       appears to serve no purpose */
    xtruct = g_object_new (T_TEST_TYPE_XTRUCT,
                           "string_thing", arg,
                           NULL);
    g_object_unref (xtruct);

    result = TRUE;
  }

  return result;
}

gboolean
thrift_test_handler_test_multi_exception (TTestThriftTestIf  *iface,
                                          TTestXtruct       **_return,
                                          const gchar        *arg0,
                                          const gchar        *arg1,
                                          TTestXception     **err1,
                                          TTestXception2    **err2,
                                          GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  TTestXtruct *struct_thing;
  gboolean result;

  printf ("testMultiException(%s, %s)\n", arg0, arg1);

  g_assert (*err1 == NULL);
  g_assert (*err2 == NULL);

  if (strncmp (arg0, "Xception", 8) == 0 && strlen(arg0) == 8) {
    *err1 = g_object_new (T_TEST_TYPE_XCEPTION,
                          "errorCode", 1001,
                          "message",  "This is an Xception",
                          NULL);
    result = FALSE;
  }
  else if (strncmp (arg0, "Xception2", 9) == 0) {
    *err2 = g_object_new (T_TEST_TYPE_XCEPTION2,
                          "errorCode", 2002,
                          NULL);

    g_object_get (*err2,
                  "struct_thing", &struct_thing,
                  NULL);
    g_object_set (struct_thing,
                  "string_thing", "This is an Xception2",
                  NULL);
    g_object_set (*err2,
                  "struct_thing", struct_thing,
                  NULL);
    g_object_unref (struct_thing);

    result = FALSE;
  }
  else {
    g_object_set (*_return,
                  "string_thing", arg1,
                  NULL);
    result = TRUE;
  }

  return result;
}

gboolean
thrift_test_handler_test_oneway (TTestThriftTestIf  *iface,
                                 const gint32        secondsToSleep,
                                 GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("testOneway(%d): Sleeping...\n", secondsToSleep);
  sleep (secondsToSleep);
  printf ("testOneway(%d): done sleeping!\n", secondsToSleep);

  return TRUE;
}

static void
thrift_test_handler_init (ThriftTestHandler *self)
{
  THRIFT_UNUSED_VAR (self);
}

static void
thrift_test_handler_class_init (ThriftTestHandlerClass *klass)
{
  TTestThriftTestHandlerClass *base_class =
    T_TEST_THRIFT_TEST_HANDLER_CLASS (klass);

  base_class->test_void =
    klass->test_void =
    thrift_test_handler_test_void;
  base_class->test_string =
    klass->test_string =
    thrift_test_handler_test_string;
  base_class->test_bool =
    klass->test_bool =
    thrift_test_handler_test_bool;
  base_class->test_byte =
    klass->test_byte =
    thrift_test_handler_test_byte;
  base_class->test_i32 =
    klass->test_i32 =
    thrift_test_handler_test_i32;
  base_class->test_i64 =
    klass->test_i64 =
    thrift_test_handler_test_i64;
  base_class->test_double =
    klass->test_double =
    thrift_test_handler_test_double;
  base_class->test_binary =
    klass->test_binary =
    thrift_test_handler_test_binary;
  base_class->test_struct =
    klass->test_struct =
    thrift_test_handler_test_struct;
  base_class->test_nest =
    klass->test_nest =
    thrift_test_handler_test_nest;
  base_class->test_map =
    klass->test_map =
    thrift_test_handler_test_map;
  base_class->test_string_map =
    klass->test_string_map =
    thrift_test_handler_test_string_map;
  base_class->test_set =
    klass->test_set =
    thrift_test_handler_test_set;
  base_class->test_list =
    klass->test_list =
    thrift_test_handler_test_list;
  base_class->test_enum =
    klass->test_enum =
    thrift_test_handler_test_enum;
  base_class->test_typedef =
    klass->test_typedef =
    thrift_test_handler_test_typedef;
  base_class->test_map_map =
    klass->test_map_map =
    thrift_test_handler_test_map_map;
  base_class->test_insanity =
    klass->test_insanity =
    thrift_test_handler_test_insanity;
  base_class->test_multi =
    klass->test_multi =
    thrift_test_handler_test_multi;
  base_class->test_exception =
    klass->test_exception =
    thrift_test_handler_test_exception;
  base_class->test_multi_exception =
    klass->test_multi_exception =
    thrift_test_handler_test_multi_exception;
  base_class->test_oneway =
    klass->test_oneway =
    thrift_test_handler_test_oneway;
}
thrift-0.23.0/test/c_glib/src/test_server.c0000664000175000017500000002647315165535636021107 0ustar00buildbuild00000000000000/*
 * 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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "../gen-c_glib/t_test_thrift_test.h"
#include "../gen-c_glib/t_test_second_service.h"

#include "thrift_test_handler.h"
#include "thrift_second_service_handler.h"

/* Our server object, declared globally so it is accessible within the SIGINT
   signal handler */
ThriftServer *server = NULL;

/* A flag that indicates whether the server was interrupted with SIGINT
   (i.e. Ctrl-C) so we can tell whether its termination was abnormal */
gboolean sigint_received = FALSE;

/* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the server */
static void
sigint_handler (int signal_number)
{
  THRIFT_UNUSED_VAR (signal_number);

  /* Take note we were called */
  sigint_received = TRUE;

  /* Shut down the server gracefully */
  if (server != NULL)
    thrift_server_stop (server);
}

int
main (int argc, char **argv)
{
  static gint   port = 9090;
  static gchar *path_option = NULL;
  static gchar *server_type_option = NULL;
  static gchar *transport_option = NULL;
  static gchar *protocol_option = NULL;
  static gint   string_limit = 0;
  static gint   container_limit = 0;

  static
    GOptionEntry option_entries[] = {
    { "port",            0, 0, G_OPTION_ARG_INT,      &port,
      "Port number to connect (=9090)", NULL },
    { "domain-socket",   0, 0, G_OPTION_ARG_STRING,   &path_option,
      "Unix socket domain path to connect", NULL },
    { "server-type",     0, 0, G_OPTION_ARG_STRING,   &server_type_option,
      "Type of server: simple (=simple)", NULL },
    { "transport",       0, 0, G_OPTION_ARG_STRING,   &transport_option,
      "Transport: buffered, framed, zlib (=buffered)", NULL },
    { "protocol",        0, 0, G_OPTION_ARG_STRING,   &protocol_option,
      "Protocol: binary, compact (=binary)", NULL },
    { "string-limit",    0, 0, G_OPTION_ARG_INT,      &string_limit,
      "Max string length (=none)", NULL },
    { "container-limit", 0, 0, G_OPTION_ARG_INT,      &container_limit,
      "Max container length (=none)", NULL },
    { NULL }
  };

  gchar *server_name            = "simple";
  gchar *transport_name         = "buffered";
  GType  transport_factory_type = THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY;
  gchar *protocol_name          = "binary";
  GType  protocol_factory_type  = THRIFT_TYPE_BINARY_PROTOCOL_FACTORY;

  TTestThriftTestHandler *handler;
  TTestThriftTestHandler *handler_second_service = NULL;
  ThriftProcessor        *processor;
  ThriftProcessor        *processor_test = NULL;
  ThriftProcessor        *processor_second_service = NULL;
  ThriftServerTransport  *server_transport;
  ThriftTransportFactory *transport_factory;
  ThriftProtocolFactory  *protocol_factory;

  struct sigaction sigint_action;

  GOptionContext *option_context;
  gboolean        options_valid = TRUE;

  GError *error = NULL;

#if (!GLIB_CHECK_VERSION (2, 36, 0))
  g_type_init ();
#endif

  /* Configure and parse our command-line options */
  option_context = g_option_context_new (NULL);
  g_option_context_add_main_entries (option_context,
                                     option_entries,
                                     NULL);
  if (g_option_context_parse (option_context,
                              &argc,
                              &argv,
                              &error) == FALSE) {
    fprintf (stderr, "%s\n", error->message);
    g_clear_error (&error);
    g_option_context_free (option_context);
    return 255;
  }
  g_option_context_free (option_context);

  /* Validate the parsed options */
  if (server_type_option != NULL &&
      strncmp (server_type_option, "simple", 7) != 0) {
    fprintf (stderr, "Unknown server type %s\n", protocol_option);
    options_valid = FALSE;
  }

  if (protocol_option != NULL) {
    if (strncmp (protocol_option, "compact", 8) == 0) {
      protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
      protocol_name = "compact";
    }
    else if (strncmp (protocol_option, "multi", 6) == 0) {
	protocol_name = "binary:multi";
    }
    else if (strncmp (protocol_option, "multic", 7) == 0) {
	protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
	protocol_name = "compact:multic";
    }
    else if (strncmp (protocol_option, "binary", 7) != 0) {
      fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
      options_valid = FALSE;
    }
  }

  if (transport_option != NULL) {
    if (strncmp (transport_option, "framed", 7) == 0) {
      transport_factory_type = THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY;
      transport_name = "framed";
    }
    else if (strncmp (transport_option, "zlib", 5) == 0) {
      transport_factory_type = THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY;
      transport_name = "zlib";
    }
    else if (strncmp (transport_option, "buffered", 9) != 0) {
      fprintf (stderr, "Unknown transport type %s\n", transport_option);
      options_valid = FALSE;
    }
  }

  if (!options_valid)
    return 254;

  /* Establish all our connection objects */
  handler           = g_object_new (TYPE_THRIFT_TEST_HANDLER,
                                    NULL);



  if(strstr(protocol_name, ":multi")){
      /* When a multiplexed processor is involved the handler is not
         registered as usual. We create the processor and the real
         processor is registered. Multiple processors can be registered
         at once. This is why we don't have a constructor property */
      processor = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROCESSOR,
					 NULL);

      handler_second_service = g_object_new (TYPE_SECOND_SERVICE_HANDLER,
     	                                    NULL);

      processor_test = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
				    "handler", handler,
				    NULL);
      processor_second_service =   g_object_new (T_TEST_TYPE_SECOND_SERVICE_PROCESSOR,
				    "handler", handler_second_service,
				    NULL);

      /* We register a test processor with Multiplexed name ThriftTest */
      if(!thrift_multiplexed_processor_register_processor(processor,
						      "ThriftTest", processor_test,
						      &error)){
	    g_message ("thrift_server_serve: %s",
	               error != NULL ? error->message : "(null)");
	    g_clear_error (&error);
      }
      /* We register a second test processor with Multiplexed name SecondService
       * we are responsible of freeing the processor when it's not used anymore */
      if(!thrift_multiplexed_processor_register_processor(processor,
						      "SecondService", processor_second_service,
						      &error)){
	    g_message ("thrift_server_serve: %s",
	               error != NULL ? error->message : "(null)");
	    g_clear_error (&error);
      }

  }else{
      processor = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
                                        "handler", handler,
                                        NULL);
  }
  if (path_option) {
    server_transport  = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
                                      "path", path_option,
                                      NULL);
  } else {
    server_transport  = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
                                      "port", port,
                                      NULL);
  }
  transport_factory = g_object_new (transport_factory_type,
                                    NULL);

  if (strstr (protocol_name, "compact") != NULL) {
    protocol_factory  = g_object_new (protocol_factory_type,
                                      "string_limit", string_limit,
                                      "container_limit", container_limit,
                                      NULL);
  } else {
    protocol_factory  = g_object_new (protocol_factory_type,
                                      NULL);
  }

  server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
                         "processor",                processor,
                         "server_transport",         server_transport,
                         "input_transport_factory",  transport_factory,
                         "output_transport_factory", transport_factory,
                         "input_protocol_factory",   protocol_factory,
                         "output_protocol_factory",  protocol_factory,
                         NULL);

  /* Install our SIGINT handler, which handles Ctrl-C being pressed by stopping
     the server gracefully */
  memset (&sigint_action, 0, sizeof (sigint_action));
  sigint_action.sa_handler = sigint_handler;
  sigint_action.sa_flags = SA_RESETHAND;
  sigaction (SIGINT, &sigint_action, NULL);

  if (path_option) {
    printf ("Starting \"%s\" server (%s/%s) listen on: %s\n",
            server_name,
            transport_name,
            protocol_name,
            path_option);
  } else {
    printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
            server_name,
            transport_name,
            protocol_name,
            port);
  }
  fflush (stdout);

  /* Serve clients until SIGINT is received (Ctrl-C is pressed) */
  thrift_server_serve (server, &error);

  /* If the server stopped for any reason other than being interrupted by the
     user, report the error */
  if (!sigint_received) {
    g_message ("thrift_server_serve: %s",
               error != NULL ? error->message : "(null)");
  }

  puts ("done.");

  g_clear_error (&error);
  g_object_unref (server);
  g_object_unref (protocol_factory);
  g_object_unref (transport_factory);
  g_object_unref (server_transport);
  g_object_unref (processor);
  g_object_unref (handler);
  if(handler_second_service){
      g_object_unref (handler_second_service);
  }
  if(processor_test){
      g_object_unref (processor_test);
  }
  if(processor_second_service){
      g_object_unref (processor_second_service);
  }

  return 0;
}
thrift-0.23.0/test/c_glib/src/thrift_test_handler.h0000664000175000017500000003530015165535636022570 0ustar00buildbuild00000000000000/*
 * 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_TEST_HANDLER_H
#define _THRIFT_TEST_HANDLER_H

#include 
#include 

#include "../gen-c_glib/t_test_thrift_test.h"

G_BEGIN_DECLS

/* A handler that implements the TTestThriftTestIf interface */

#define TYPE_THRIFT_TEST_HANDLER (thrift_test_handler_get_type ())

#define THRIFT_TEST_HANDLER(obj)                                \
  (G_TYPE_CHECK_INSTANCE_CAST ((obj),                           \
                               TYPE_THRIFT_TEST_HANDLER,        \
                               ThriftTestHandler))
#define IS_THRIFT_TEST_HANDLER(obj)                             \
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj),                           \
                               TYPE_THRIFT_TEST_HANDLER))
#define THRIFT_TEST_HANDLER_CLASS(c)                    \
  (G_TYPE_CHECK_CLASS_CAST ((c),                        \
                            TYPE_THRIFT_TEST_HANDLER,   \
                            ThriftTestHandlerClass))
#define IS_THRIFT_TEST_HANDLER_CLASS(c)                 \
  (G_TYPE_CHECK_CLASS_TYPE ((c),                        \
                            TYPE_THRIFT_TEST_HANDLER))
#define THRIFT_TEST_HANDLER_GET_CLASS(obj)              \
  (G_TYPE_INSTANCE_GET_CLASS ((obj),                    \
                              TYPE_THRIFT_TEST_HANDLER, \
                              ThriftTestHandlerClass))

typedef struct _ThriftTestHandler ThriftTestHandler;
typedef struct _ThriftTestHandlerClass ThriftTestHandlerClass;

struct _ThriftTestHandler {
  TTestThriftTestHandler parent;
};

struct _ThriftTestHandlerClass {
  TTestThriftTestHandlerClass parent;

  gboolean (*test_void)            (TTestThriftTestIf    *iface,
                                    GError              **error);
  gboolean (*test_string)          (TTestThriftTestIf    *iface,
                                    gchar               **_return,
                                    const gchar          *thing,
                                    GError              **error);
  gboolean (*test_bool)            (TTestThriftTestIf    *iface,
                                    gboolean*_return,
                                    const gboolean        thing,
                                    GError              **error);
  gboolean (*test_byte)            (TTestThriftTestIf    *iface,
                                    gint8*_return,
                                    const gint8           thing,
                                    GError              **error);
  gboolean (*test_i32)             (TTestThriftTestIf    *iface,
                                    gint32*_return,
                                    const gint32          thing,
                                    GError              **error);
  gboolean (*test_i64)             (TTestThriftTestIf    *iface,
                                    gint64*_return,
                                    const gint64          thing,
                                    GError              **error);
  gboolean (*test_double)          (TTestThriftTestIf    *iface,
                                    gdouble*_return,
                                    const gdouble         thing,
                                    GError              **error);
  gboolean (*test_binary)          (TTestThriftTestIf    *iface,
                                    GByteArray        **_return,
                                    const GByteArray     *thing,
                                    GError              **error);
  gboolean (*test_struct)          (TTestThriftTestIf    *iface,
                                    TTestXtruct         **_return,
                                    const TTestXtruct    *thing,
                                    GError              **error);
  gboolean (*test_nest)            (TTestThriftTestIf    *iface,
                                    TTestXtruct2        **_return,
                                    const TTestXtruct2   *thing,
                                    GError              **error);
  gboolean (*test_map)             (TTestThriftTestIf    *iface,
                                    GHashTable          **_return,
                                    const GHashTable     *thing,
                                    GError              **error);
  gboolean (*test_string_map)      (TTestThriftTestIf    *iface,
                                    GHashTable          **_return,
                                    const GHashTable     *thing,
                                    GError              **error);
  gboolean (*test_set)             (TTestThriftTestIf    *iface,
                                    GHashTable          **_return,
                                    const GHashTable     *thing,
                                    GError              **error);
  gboolean (*test_list)            (TTestThriftTestIf    *iface,
                                    GArray              **_return,
                                    const GArray         *thing,
                                    GError              **error);
  gboolean (*test_enum)            (TTestThriftTestIf    *iface,
                                    TTestNumberz*_return,
                                    const TTestNumberz    thing,
                                    GError              **error);
  gboolean (*test_typedef)         (TTestThriftTestIf    *iface,
                                    TTestUserId*_return,
                                    const TTestUserId     thing,
                                    GError              **error);
  gboolean (*test_map_map)         (TTestThriftTestIf    *iface,
                                    GHashTable          **_return,
                                    const gint32          hello,
                                    GError              **error);
  gboolean (*test_insanity)        (TTestThriftTestIf    *iface,
                                    GHashTable          **_return,
                                    const TTestInsanity  *argument,
                                    GError              **error);
  gboolean (*test_multi)           (TTestThriftTestIf    *iface,
                                    TTestXtruct         **_return,
                                    const gint8           arg0,
                                    const gint32          arg1,
                                    const gint64          arg2,
                                    const GHashTable     *arg3,
                                    const TTestNumberz    arg4,
                                    const TTestUserId     arg5,
                                    GError              **error);
  gboolean (*test_exception)       (TTestThriftTestIf    *iface,
                                    const gchar          *arg,
                                    TTestXception       **err1,
                                    GError              **error);
  gboolean (*test_multi_exception) (TTestThriftTestIf    *iface,
                                    TTestXtruct         **_return,
                                    const gchar          *arg0,
                                    const gchar          *arg1,
                                    TTestXception       **err1,
                                    TTestXception2      **err2,
                                    GError              **error);
  gboolean (*test_oneway)          (TTestThriftTestIf    *iface,
                                    const gint32          secondsToSleep,
                                    GError              **error);
};

/* Used by THRIFT_TEST_HANDLER_GET_TYPE */
GType thrift_test_handler_get_type (void);

gboolean thrift_test_handler_test_void            (TTestThriftTestIf    *iface,
                                                   GError              **error);
gboolean thrift_test_handler_test_string          (TTestThriftTestIf    *iface,
                                                   gchar               **_return,
                                                   const gchar          *thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_byte            (TTestThriftTestIf    *iface,
                                                   gint8*_return,
                                                   const gint8           thing,
                                                   GError              **error);
gboolean t_test_thrift_test_if_test_i32           (TTestThriftTestIf    *iface,
                                                   gint32*_return,
                                                   const gint32          thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_i64             (TTestThriftTestIf    *iface,
                                                   gint64*_return,
                                                   const gint64          thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_double          (TTestThriftTestIf    *iface,
                                                   gdouble*_return,
                                                   const gdouble         thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_struct          (TTestThriftTestIf    *iface,
                                                   TTestXtruct         **_return,
                                                   const TTestXtruct    *thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_nest            (TTestThriftTestIf    *iface,
                                                   TTestXtruct2        **_return,
                                                   const TTestXtruct2   *thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_map             (TTestThriftTestIf    *iface,
                                                   GHashTable          **_return,
                                                   const GHashTable     *thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_string_map      (TTestThriftTestIf    *iface,
                                                   GHashTable          **_return,
                                                   const GHashTable     *thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_set             (TTestThriftTestIf    *iface,
                                                   GHashTable          **_return,
                                                   const GHashTable     *thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_list            (TTestThriftTestIf    *iface,
                                                   GArray              **_return,
                                                   const GArray         *thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_typedef         (TTestThriftTestIf    *iface,
                                                   TTestUserId*_return,
                                                   const TTestUserId     thing,
                                                   GError              **error);
gboolean thrift_test_handler_test_map_map         (TTestThriftTestIf    *iface,
                                                   GHashTable          **_return,
                                                   const gint32          hello,
                                                   GError              **error);
gboolean thrift_test_handler_test_insanity        (TTestThriftTestIf    *iface,
                                                   GHashTable          **_return,
                                                   const TTestInsanity  *argument,
                                                   GError              **error);
gboolean thrift_test_handler_test_multi           (TTestThriftTestIf    *iface,
                                                   TTestXtruct         **_return,
                                                   const gint8           arg0,
                                                   const gint32          arg1,
                                                   const gint64          arg2,
                                                   const GHashTable     *arg3,
                                                   const TTestNumberz    arg4,
                                                   const TTestUserId     arg5,
                                                   GError              **error);
gboolean thrift_test_handler_test_exception       (TTestThriftTestIf    *iface,
                                                   const gchar          *arg,
                                                   TTestXception       **err1,
                                                   GError              **error);
gboolean thrift_test_handler_test_multi_exception (TTestThriftTestIf    *iface,
                                                   TTestXtruct         **_return,
                                                   const gchar          *arg0,
                                                   const gchar          *arg1,
                                                   TTestXception       **err1,
                                                   TTestXception2      **err2,
                                                   GError              **error);
gboolean thrift_test_handler_test_oneway          (TTestThriftTestIf    *iface,
                                                   const gint32          secondsToSleep,
                                                   GError              **error);

G_END_DECLS

#endif /* _THRIFT_TEST_HANDLER_H */
thrift-0.23.0/test/c_glib/src/test_client.c0000664000175000017500000016437415165535636021062 0ustar00buildbuild00000000000000/*
 * 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 

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "../gen-c_glib/t_test_second_service.h"
#include "../gen-c_glib/t_test_thrift_test.h"

/* Handle SIGPIPE signals (indicating the server has closed the
   connection prematurely) by outputting an error message before
   exiting. */
static void
sigpipe_handler (int signal_number)
{
  THRIFT_UNUSED_VAR (signal_number);

  /* Flush standard output to make sure the test results so far are
     logged */
  fflush (stdout);

  fputs ("Broken pipe (server closed connection prematurely)\n", stderr);
  fflush (stderr);

  /* Re-raise the signal, this time invoking the default signal
     handler, to terminate the program */
  raise (SIGPIPE);
}

/* Compare two gint32 values. Used for sorting and finding integer
   values within a GList. */
static gint
gint32_compare (gconstpointer a, gconstpointer b)
{
  gint32 int32_a = *(gint32 *)a;
  gint32 int32_b = *(gint32 *)b;
  int result = 0;

  if (int32_a < int32_b)
    result = -1;
  else if (int32_a > int32_b)
    result = 1;

  return result;
}

int
main (int argc, char **argv)
{
  static gchar *  host = NULL;
  static gint     port = 9090;
  static gchar *  path = NULL;
  static gboolean ssl  = FALSE;
  static gchar *  transport_option = NULL;
  static gchar *  protocol_option = NULL;
  static gint     num_tests = 1;

  static
    GOptionEntry option_entries[] ={
    { "host",            'h', 0, G_OPTION_ARG_STRING,   &host,
      "Host to connect (=localhost)", NULL },
    { "port",            'p', 0, G_OPTION_ARG_INT,      &port,
      "Port number to connect (=9090)", NULL },
    { "domain-socket",    0, 0, G_OPTION_ARG_STRING,   &path,
      "Unix socket domain path to connect", NULL },
    { "ssl",             's', 0, G_OPTION_ARG_NONE,     &ssl,
      "Enable SSL", NULL },
    { "transport",       't', 0, G_OPTION_ARG_STRING,   &transport_option,
      "Transport: buffered, framed (=buffered)", NULL },
    { "protocol",        'r', 0, G_OPTION_ARG_STRING,   &protocol_option,
      "Protocol: binary, compact, multi, multic (=binary)", NULL },
    { "testloops",       'n', 0, G_OPTION_ARG_INT,      &num_tests,
      "Number of tests (=1)", NULL },
    { NULL }
  };

  struct sigaction sigpipe_action;

  GType  socket_type    = THRIFT_TYPE_SOCKET;
  gchar *socket_name    = "ip";
  GType  transport_type = THRIFT_TYPE_BUFFERED_TRANSPORT;
  gchar *transport_name = "buffered";
  GType  protocol_type  = THRIFT_TYPE_BINARY_PROTOCOL;
  gchar *protocol_name  = "binary";

  ThriftSocket    *socket = NULL;
  ThriftTransport *transport = NULL;
  ThriftProtocol  *protocol = NULL;
  ThriftProtocol  *protocol2 = NULL;            // for multiplexed tests
  ThriftProtocol  *multiplexed_protocol = NULL;

  TTestThriftTestIf *test_client = NULL;
  TTestSecondServiceIf *second_service = NULL;  // for multiplexed tests

  struct timeval time_start, time_stop, time_elapsed;
  guint64 time_elapsed_usec, time_total_usec = 0;
  guint64 time_min_usec = G_MAXUINT64, time_max_usec = 0, time_avg_usec;

  GOptionContext *option_context;
  gboolean options_valid = TRUE;
  int test_num = 0;
  int fail_count = 0;
  GError *error = NULL;

#if (!GLIB_CHECK_VERSION (2, 36, 0))
  g_type_init ();
#endif

  /* Configure and parse our command-line options */
  option_context = g_option_context_new (NULL);
  g_option_context_add_main_entries (option_context,
                                     option_entries,
                                     NULL);
  if (!g_option_context_parse (option_context,
                               &argc,
                               &argv,
                               &error)) {
    fprintf (stderr, "%s\n", error->message);
    g_clear_error (&error);
    g_option_context_free (option_context);
    return 255;
  }
  g_option_context_free (option_context);

  /* Set remaining default values for unspecified options */
  if (host == NULL)
    host = g_strdup ("localhost");

  /* Validate the parsed options */
  if (protocol_option != NULL) {
    if (strncmp (protocol_option, "compact", 8) == 0) {
      protocol_type = THRIFT_TYPE_COMPACT_PROTOCOL;
      protocol_name = "compact";
    }
    else if (strncmp (protocol_option, "multi", 6) == 0) {
      protocol_type = THRIFT_TYPE_MULTIPLEXED_PROTOCOL;
      protocol_name = "binary:multi";
    }
    else if (strncmp (protocol_option, "multic", 7) == 0) {
      protocol_type = THRIFT_TYPE_MULTIPLEXED_PROTOCOL;
      protocol_name = "compact:multic";
    }
    else if (strncmp (protocol_option, "binary", 7) == 0) {
      printf("We are going with default protocol\n");
    }
    else {
      fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
      options_valid = FALSE;
    }
  }

  if (transport_option != NULL) {
    if (strncmp (transport_option, "framed", 7) == 0) {
      transport_type = THRIFT_TYPE_FRAMED_TRANSPORT;
      transport_name = "framed";
    }
    else if (strncmp (transport_option, "buffered", 9) != 0) {
      fprintf (stderr, "Unknown transport type %s\n", transport_option);
      options_valid = FALSE;
    }
  }

  if (ssl) {
    socket_type = THRIFT_TYPE_SSL_SOCKET;
    socket_name = "ip-ssl";
    printf("Type name %s\n", g_type_name (socket_type));
  }

  if (!options_valid)
    return 254;

  if (path) {
    printf ("Connecting (%s/%s) to: %s/%s\n",
            transport_name,
            protocol_name,
            socket_name,
            path);
  } else {
    printf ("Connecting (%s/%s) to: %s/%s:%d\n",
            transport_name,
            protocol_name,
            socket_name,
            host,
            port);
  }

  /* Install our SIGPIPE handler, which outputs an error message to
     standard error before exiting so testers can know what
     happened */
  memset (&sigpipe_action, 0, sizeof (sigpipe_action));
  sigpipe_action.sa_handler = sigpipe_handler;
  sigpipe_action.sa_flags = SA_RESETHAND;
  sigaction (SIGPIPE, &sigpipe_action, NULL);

  if (ssl) {
    thrift_ssl_socket_initialize_openssl();
  }

  /* Establish all our connection objects */
  if (path) {
    socket = g_object_new (socket_type,
                           "path", path,
                           NULL);
  } else {
    socket = g_object_new (socket_type,
                           "hostname", host,
                           "port",     port,
                           NULL);
  }

  if (ssl && !thrift_ssl_load_cert_from_file(THRIFT_SSL_SOCKET(socket), "../keys/CA.pem")) {
    fprintf(stderr, "Unable to load validation certificate ../keys/CA.pem - did you run in the test/c_glib directory?\n");
    g_clear_object (&socket);
    return 253;
  }

  transport = g_object_new (transport_type,
                            "transport", socket,
                            NULL);

  if (protocol_type == THRIFT_TYPE_MULTIPLEXED_PROTOCOL) {
    // TODO: A multiplexed test should also test "Second" (see Java TestServer)
    // The context comes from the name of the thrift file. If multiple thrift
    // schemas are used we have to redo the way this is done.
    if (strncmp(protocol_name, "binary:", 7) == 0) {
      multiplexed_protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
                                           "transport", transport,
                                           NULL);
    } else if (strncmp(protocol_name, "compact:", 8) == 0) {
      multiplexed_protocol = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL,
                                           "transport", transport,
                                           NULL);
    } else {
      fprintf(stderr, "Unknown multiplex protocol name: %s\n", protocol_name);
      g_clear_object (&transport);
      g_clear_object (&socket);
      return 252;
    }
    protocol = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROTOCOL,
                             "transport",    transport,
                             "protocol",     multiplexed_protocol,
                             "service-name", "ThriftTest",
                             NULL);;
    if (NULL == protocol) {
      g_clear_object (&multiplexed_protocol);
      g_clear_object (&transport);
      g_clear_object (&socket);
      return 251;
    }

    // Make a second protocol and client running on the same multiplexed transport
    protocol2 = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROTOCOL,
                              "transport",    transport,
                              "protocol",     multiplexed_protocol,
                              "service-name", "SecondService",
                              NULL);

    second_service = g_object_new (T_TEST_TYPE_SECOND_SERVICE_CLIENT,
                                   "input_protocol",  protocol2,
                                   "output_protocol", protocol2,
                                   NULL);
  }else{
    protocol = g_object_new (protocol_type,
           "transport", transport,
           NULL);
  }

  test_client = g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT,
                              "input_protocol",  protocol,
                              "output_protocol", protocol,
                              NULL);

  /* Execute the actual tests */
  for (test_num = 0; test_num < num_tests; ++test_num) {
    if (thrift_transport_open (transport, &error)) {
      gchar   *string  = NULL;
      gboolean boolean = 0;
      gint8    byte    = 0;
      gint32   int32   = 0;
      gint64   int64   = 0;
      gdouble  dub     = 0;

      gint byte_thing, i32_thing, inner_byte_thing, inner_i32_thing;
      gint64 i64_thing, inner_i64_thing;

      TTestXtruct  *xtruct_out,  *xtruct_out2, *xtruct_in,  *inner_xtruct_in;
      TTestXtruct2 *xtruct2_out, *xtruct2_in;

      GHashTable *map_out, *map_in, *inner_map_in;
      GHashTable *set_out, *set_in;
      gpointer key, value;
      gint32 *i32_key_ptr, *i32_value_ptr;
      GHashTableIter hash_table_iter, inner_hash_table_iter;
      GList *keys_out, *keys_in, *keys_elem;

      GArray *list_out, *list_in;

      TTestNumberz numberz;
      TTestNumberz numberz2;

      TTestUserId user_id, *user_id_ptr, *user_id_ptr2;

      TTestInsanity *insanity_out, *insanity_in;
      GHashTable *user_map;
      GHashTableIter user_map_iter;
      GPtrArray *xtructs;

      TTestXception  *xception  = NULL;
      TTestXception2 *xception2 = NULL;

      gboolean oneway_result;
      struct timeval oneway_start, oneway_end, oneway_elapsed;
      gint oneway_elapsed_usec;

      gboolean first;
      gint32 i, j;

      if (path) {
        printf ("Test #%d, connect %s\n", test_num + 1, path);
      } else {
        printf ("Test #%d, connect %s:%d\n", test_num + 1, host, port);
      }
      gettimeofday (&time_start, NULL);

      /* These test routines have been ported from the C++ test
         client, care being taken to ensure their output remains as
         close as possible to the original to facilitate diffs.

         For simplicity comments have been omitted, but every routine
         has the same basic structure:

         - Create and populate data structures as necessary.

         - Format and output (to the console) a representation of the
           outgoing data.

         - Issue the remote method call to the server.

         - Format and output a representation of the returned data.

         - Verify the returned data matches what was expected.

         - Deallocate any created data structures.

         Note the recognized values and expected behaviour of each
         remote method are described in ThriftTest.thrift, which
         you'll find in the top-level "test" folder. */

      /**
       * VOID TEST
       */
      printf ("testVoid()");
      if (t_test_thrift_test_if_test_void (test_client, &error)) {
        printf (" = void\n");
      }
      else {
        if(error!=NULL){
          printf ("%s\n", error->message);
          g_error_free (error);
          error = NULL;
        }
        fail_count++;
      }

      /**
       * STRING TEST
       */
      printf ("testString(\"Test\")");
      if (t_test_thrift_test_if_test_string (test_client,
                                             &string,
                                             "Test",
                                             &error)) {
        printf (" = \"%s\"\n", string);
        if (strncmp (string, "Test", 5) != 0)
          fail_count++;

        g_free (string);
        string = NULL;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * Multiplexed Test - do this right in the middle of the normal Test Client run
       */
      if (second_service) {
        printf ("testSecondServiceMultiplexSecondTestString(\"2nd\")");
        if (t_test_second_service_if_secondtest_string (second_service,
                                                        &string,
                                                        "2nd",
                                                        &error)) {
          printf (" = \"%s\"\n", string);
          if (strcmp (string, "testString(\"2nd\")") != 0) {
            ++fail_count;
          }

          g_free (string);
          string = NULL;
        } else {
          printf ("%s\n", error->message);
          g_error_free (error);
          error = NULL;

          ++fail_count;
        }
      }

      /**
       * BOOL TEST
       */
      printf ("testByte(true)");
      if (t_test_thrift_test_if_test_bool (test_client,
                                           &boolean,
                                           1,
                                           &error)) {
        printf (" = %s\n", boolean ? "true" : "false");
        if (boolean != 1)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }
      printf ("testByte(false)");
      if (t_test_thrift_test_if_test_bool (test_client,
                                           &boolean,
                                           0,
                                           &error)) {
        printf (" = %s\n", boolean ? "true" : "false");
        if (boolean != 0)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * BYTE TEST
       */
      printf ("testByte(1)");
      if (t_test_thrift_test_if_test_byte (test_client,
                                           &byte,
                                           1,
                                           &error)) {
        printf (" = %d\n", byte);
        if (byte != 1)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }
      printf ("testByte(-1)");
      if (t_test_thrift_test_if_test_byte (test_client,
                                           &byte,
                                           -1,
                                           &error)) {
        printf (" = %d\n", byte);
        if (byte != -1)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * I32 TEST
       */
      printf ("testI32(-1)");
      if (t_test_thrift_test_if_test_i32 (test_client,
                                          &int32,
                                          -1,
                                          &error)) {
        printf (" = %d\n", int32);
        if (int32 != -1)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * I64 TEST
       */
      printf ("testI64(-34359738368)");
      if (t_test_thrift_test_if_test_i64 (test_client,
                                          &int64,
                                          (gint64)-34359738368,
                                          &error)) {
        printf (" = %" PRId64 "\n", int64);
        if (int64 != (gint64)-34359738368)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * DOUBLE TEST
       */
      printf("testDouble(-5.2098523)");
      if (t_test_thrift_test_if_test_double (test_client,
                                             &dub,
                                             -5.2098523,
                                             &error)) {
        printf (" = %f\n", dub);
        if ((dub - (-5.2098523)) > 0.001)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * BINARY TEST
       */
      printf ("testBinary(empty)");
      GByteArray *emptyArray = g_byte_array_new();
      GByteArray *result = NULL;
      if (t_test_thrift_test_if_test_binary (test_client,
                                             &result,
                                             emptyArray,
                                             &error)) {
        GBytes *response = g_byte_array_free_to_bytes(result);  // frees result
        result = NULL;
        gsize siz = g_bytes_get_size(response);
        if (siz == 0) {
          printf(" = empty\n");
        } else {
          printf(" = not empty (%ld bytes)\n", (long)siz);
          ++fail_count;
        }
        g_bytes_unref(response);
      } else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }
      g_byte_array_unref(emptyArray);
      emptyArray = NULL;

      // TODO: add testBinary() with data
      printf ("testBinary([-128..127]) = {");
      const signed char bin_data[256]
        = {-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114,
           -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99,
           -98,  -97,  -96,  -95,  -94,  -93,  -92,  -91,  -90,  -89,  -88,  -87,  -86,  -85,  -84,
           -83,  -82,  -81,  -80,  -79,  -78,  -77,  -76,  -75,  -74,  -73,  -72,  -71,  -70,  -69,
           -68,  -67,  -66,  -65,  -64,  -63,  -62,  -61,  -60,  -59,  -58,  -57,  -56,  -55,  -54,
           -53,  -52,  -51,  -50,  -49,  -48,  -47,  -46,  -45,  -44,  -43,  -42,  -41,  -40,  -39,
           -38,  -37,  -36,  -35,  -34,  -33,  -32,  -31,  -30,  -29,  -28,  -27,  -26,  -25,  -24,
           -23,  -22,  -21,  -20,  -19,  -18,  -17,  -16,  -15,  -14,  -13,  -12,  -11,  -10,  -9,
           -8,   -7,   -6,   -5,   -4,   -3,   -2,   -1,   0,    1,    2,    3,    4,    5,    6,
           7,    8,    9,    10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,
           22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
           37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
           52,   53,   54,   55,   56,   57,   58,   59,   60,   61,   62,   63,   64,   65,   66,
           67,   68,   69,   70,   71,   72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
           82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,   95,   96,
           97,   98,   99,   100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,  111,
           112,  113,  114,  115,  116,  117,  118,  119,  120,  121,  122,  123,  124,  125,  126,
           127};
      GByteArray *fullArray = g_byte_array_new();
      g_byte_array_append(fullArray, (guint8 *)(&bin_data[0]), 256);
      if (t_test_thrift_test_if_test_binary (test_client,
                                             &result,
                                             fullArray,
                                             &error)) {
        GBytes *response = g_byte_array_free_to_bytes(result);  // frees result
        result = NULL;
        gsize siz = g_bytes_get_size(response);
        gconstpointer ptr = g_bytes_get_data(response, &siz);
        if (siz == 256) {
          gboolean first = 1;
          gboolean failed = 0;
          int i;

          for (i = 0; i < 256; ++i) {
            if (!first)
              printf(",");
            else
              first = 0;
            int val = ((signed char *)ptr)[i];
            printf("%d", val);
            if (!failed && val != i - 128) {
              failed = 1;
            }
          }
          printf("} ");
          if (failed) {
            printf("FAIL (bad content) size %ld OK\n", (long)siz);
            ++fail_count;
          } else {
            printf("OK size %ld OK\n", (long)siz);
          }
        } else {
          printf(" = bad size %ld\n", (long)siz);
          ++fail_count;
        }
        g_bytes_unref(response);
      } else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }
      g_byte_array_unref(fullArray);
      fullArray = NULL;

      /**
       * STRUCT TEST
       */
      printf ("testStruct({\"Zero\", 1, -3, -5})");
      xtruct_out = g_object_new (T_TEST_TYPE_XTRUCT,
                                 "string_thing", "Zero",
                                 "byte_thing",        1,
                                 "i32_thing",        -3,
                                 "i64_thing",      -5LL,
                                 NULL);
      xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);

      if (t_test_thrift_test_if_test_struct (test_client,
                                             &xtruct_in,
                                             xtruct_out,
                                             &error)) {
        g_object_get (xtruct_in,
                      "string_thing", &string,
                      "byte_thing",   &byte_thing,
                      "i32_thing",    &i32_thing,
                      "i64_thing",    &i64_thing,
                      NULL);

        printf (" = {\"%s\", %d, %d, %" PRId64 "}\n",
                string,
                byte_thing,
                i32_thing,
                i64_thing);
        if ((string == NULL || strncmp (string, "Zero", 5) != 0) ||
            byte_thing != 1 ||
            i32_thing != -3 ||
            i64_thing != (gint64)-5)
          fail_count++;

        if (string) {
          g_free (string);
          string = NULL;
        }
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }
      // g_clear_object(&xtruct_out); used below
      g_clear_object(&xtruct_in);

      /**
       * NESTED STRUCT TEST
       */
      printf ("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
      xtruct2_out = g_object_new (T_TEST_TYPE_XTRUCT2,
                                  "byte_thing",            1,
                                  "struct_thing", xtruct_out,
                                  "i32_thing",             5,
                                  NULL);
      xtruct2_in = g_object_new (T_TEST_TYPE_XTRUCT2, NULL);

      if (t_test_thrift_test_if_test_nest (test_client,
                                           &xtruct2_in,
                                           xtruct2_out,
                                           &error)) {
        g_object_get (xtruct2_in,
                      "byte_thing",   &byte_thing,
                      "struct_thing", &xtruct_in,
                      "i32_thing",    &i32_thing,
                      NULL);
        g_object_get (xtruct_in,
                      "string_thing", &string,
                      "byte_thing",   &inner_byte_thing,
                      "i32_thing",    &inner_i32_thing,
                      "i64_thing",    &inner_i64_thing,
                      NULL);

        printf (" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
                byte_thing,
                string,
                inner_byte_thing,
                inner_i32_thing,
                inner_i64_thing,
                i32_thing);
        if (byte_thing != 1 ||
            (string == NULL || strncmp (string, "Zero", 5) != 0) ||
            inner_byte_thing != 1 ||
            inner_i32_thing != -3 ||
            inner_i64_thing != (gint64)-5 ||
            i32_thing != 5)
          fail_count++;

        if (string) {
          g_free(string);
          string = NULL;
        }
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      g_clear_object(&xtruct_in);
      g_clear_object(&xtruct2_in);
      g_clear_object(&xtruct2_out);
      g_clear_object(&xtruct_out);

      /**
       * MAP TEST
       */
      map_out = g_hash_table_new_full (g_int_hash,
                                       g_int_equal,
                                       g_free,
                                       g_free);
      for (i = 0; i < 5; ++i) {
        i32_key_ptr   = g_malloc (sizeof *i32_key_ptr);
        i32_value_ptr = g_malloc (sizeof *i32_value_ptr);

        *i32_key_ptr   = i;
        *i32_value_ptr = i - 10;

        g_hash_table_insert (map_out, i32_key_ptr, i32_value_ptr);
      }
      printf ("testMap({");
      first = TRUE;
      g_hash_table_iter_init (&hash_table_iter, map_out);
      while (g_hash_table_iter_next (&hash_table_iter,
                                     &key,
                                     &value)) {
        if (first)
          first = FALSE;
        else
          printf (", ");

        printf ("%d => %d", *(gint32 *)key, *(gint32 *)value);
      }
      printf ("})");

      map_in = g_hash_table_new_full (g_int_hash,
                                      g_int_equal,
                                      g_free,
                                      g_free);

      if (t_test_thrift_test_if_test_map (test_client,
                                          &map_in,
                                          map_out,
                                          &error)) {
        printf (" = {");
        first = TRUE;
        g_hash_table_iter_init (&hash_table_iter, map_in);
        while (g_hash_table_iter_next (&hash_table_iter,
                                       &key,
                                       &value)) {
          if (first)
            first = FALSE;
          else
            printf (", ");

          printf ("%d => %d", *(gint32 *)key, *(gint32 *)value);
        }
        printf ("}\n");

        if (g_hash_table_size (map_in) != g_hash_table_size (map_out))
          fail_count++;
        else {
          g_hash_table_iter_init (&hash_table_iter, map_out);
          while (g_hash_table_iter_next (&hash_table_iter,
                                         &key,
                                         &value)) {
            gpointer in_value = g_hash_table_lookup (map_in, key);
            if (in_value == NULL ||
                *(gint32 *)in_value != *(gint32 *)value) {
              fail_count++;
              break;
            }
          }
        }
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      g_hash_table_unref (map_in);
      g_hash_table_unref (map_out);

      /**
       * STRING MAP TEST
       */
      map_out = g_hash_table_new_full (g_str_hash,
                                       g_str_equal,
                                       NULL,
                                       NULL);
      g_hash_table_insert (map_out, "a",    "2");
      g_hash_table_insert (map_out, "b",    "blah");
      g_hash_table_insert (map_out, "some", "thing");
      printf ("testStringMap({");
      first = TRUE;
      g_hash_table_iter_init (&hash_table_iter, map_out);
      while (g_hash_table_iter_next (&hash_table_iter,
                                     &key,
                                     &value)) {
        if (first)
          first = FALSE;
        else
          printf (", ");

        printf ("\"%s\" => \"%s\"", (gchar *)key, (gchar *)value);
      }
      printf (")}");

      map_in = g_hash_table_new_full (g_str_hash,
                                      g_str_equal,
                                      g_free,
                                      g_free);

      if (t_test_thrift_test_if_test_string_map (test_client,
                                                 &map_in,
                                                 map_out,
                                                 &error)) {
        printf (" = {");
        first = TRUE;
        g_hash_table_iter_init (&hash_table_iter, map_in);
        while (g_hash_table_iter_next (&hash_table_iter,
                                       &key,
                                       &value)) {
          if (first)
            first = FALSE;
          else
            printf (", ");

          printf ("\"%s\" => \"%s\"", (gchar *)key, (gchar *)value);
        }
        printf ("}\n");

        if (g_hash_table_size (map_in) != g_hash_table_size (map_out))
          fail_count++;
        else {
          g_hash_table_iter_init (&hash_table_iter, map_out);
          while (g_hash_table_iter_next (&hash_table_iter,
                                         &key,
                                         &value)) {
            gpointer in_value = g_hash_table_lookup (map_in, key);
            if (in_value == NULL ||
                strcmp ((gchar *)in_value, (gchar *)value) != 0) {
              fail_count++;
              break;
            }
          }
        }
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      g_hash_table_unref (map_in);
      g_hash_table_unref (map_out);

      /**
       * SET TEST
       */
      set_out = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, NULL);
      for (i = -2; i < 3; ++i) {
        i32_key_ptr = g_malloc (sizeof *i32_key_ptr);
        *i32_key_ptr = i;

        g_hash_table_insert (set_out, i32_key_ptr, NULL);
      }
      printf ("testSet({");
      first = TRUE;
      keys_out = g_hash_table_get_keys (set_out);
      keys_elem = keys_out;
      while (keys_elem != NULL) {
        if (first)
          first = FALSE;
        else
          printf (", ");

        printf ("%d", *(gint32 *)keys_elem->data);

        keys_elem = keys_elem->next;
      }
      printf ("})");

      set_in = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, NULL);

      if (t_test_thrift_test_if_test_set (test_client,
                                          &set_in,
                                          set_out,
                                          &error)) {
        printf(" = {");
        first = TRUE;
        keys_in = g_hash_table_get_keys (set_in);
        keys_elem = keys_in;
        while (keys_elem != NULL) {
          if (first)
            first = FALSE;
          else
            printf (", ");

          printf ("%d", *(gint32 *)keys_elem->data);

          keys_elem = keys_elem->next;
        }
        printf ("}\n");

        if (g_list_length (keys_in) != g_list_length (keys_out))
          fail_count++;
        else {
          keys_elem = keys_out;
          while (keys_elem != NULL) {
            if (g_list_find_custom (keys_in,
                                    keys_elem->data,
                                    gint32_compare) == NULL) {
              fail_count++;
              break;
            }

            keys_elem = keys_elem->next;
          }
        }

        g_list_free (keys_in);
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      g_hash_table_unref (set_in);
      g_list_free (keys_out);
      g_hash_table_unref (set_out);

      /**
       * LIST TEST
       */
      list_out = g_array_new (FALSE, TRUE, sizeof (gint32));
      for (i = -2; i < 3; ++i) {
        g_array_append_val (list_out, i);
      }
      printf ("testList({");
      first = TRUE;
      for (i = 0; i < (gint32)list_out->len; ++i) {
        if (first)
          first = FALSE;
        else
          printf (", ");

        printf ("%d", g_array_index (list_out, gint32, i));
      }
      printf ("})");

      list_in = g_array_new (FALSE, TRUE, sizeof (gint32));

      if (t_test_thrift_test_if_test_list (test_client,
                                           &list_in,
                                           list_out,
                                           &error)) {
        printf (" = {");
        first = TRUE;
        for (i = 0; i < (gint32)list_in->len; ++i) {
          if (first)
            first = FALSE;
          else
            printf (", ");

          printf ("%d", g_array_index (list_in, gint32, i));
        }
        printf ("}\n");

        if (list_in->len != list_out->len ||
            memcmp (list_in->data,
                    list_out->data,
                    list_in->len * sizeof (gint32)) != 0)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      g_array_unref (list_in);
      g_array_unref (list_out);

      /**
       * ENUM TEST
       */
      printf("testEnum(ONE)");
      if (t_test_thrift_test_if_test_enum (test_client,
                                           &numberz,
                                           T_TEST_NUMBERZ_ONE,
                                           &error)) {
        printf(" = %d\n", numberz);
        if (numberz != T_TEST_NUMBERZ_ONE)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      printf("testEnum(TWO)");
      if (t_test_thrift_test_if_test_enum (test_client,
                                           &numberz,
                                           T_TEST_NUMBERZ_TWO,
                                           &error)) {
        printf(" = %d\n", numberz);
        if (numberz != T_TEST_NUMBERZ_TWO)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      printf("testEnum(THREE)");
      if (t_test_thrift_test_if_test_enum (test_client,
                                           &numberz,
                                           T_TEST_NUMBERZ_THREE,
                                           &error)) {
        printf(" = %d\n", numberz);
        if (numberz != T_TEST_NUMBERZ_THREE)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      printf("testEnum(FIVE)");
      if (t_test_thrift_test_if_test_enum (test_client,
                                           &numberz,
                                           T_TEST_NUMBERZ_FIVE,
                                           &error)) {
        printf(" = %d\n", numberz);
        if (numberz != T_TEST_NUMBERZ_FIVE)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      printf("testEnum(EIGHT)");
      if (t_test_thrift_test_if_test_enum (test_client,
                                           &numberz,
                                           T_TEST_NUMBERZ_EIGHT,
                                           &error)) {
        printf(" = %d\n", numberz);
        if (numberz != T_TEST_NUMBERZ_EIGHT)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * TYPEDEF TEST
       */
      printf ("testTypedef(309858235082523)");
      if (t_test_thrift_test_if_test_typedef (test_client,
                                              &user_id,
                                              309858235082523LL,
                                              &error)) {
        printf(" = %" PRId64 "\n", user_id);
        if (user_id != 309858235082523LL)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * NESTED MAP TEST
       */
      printf ("testMapMap(1)");
      map_in = g_hash_table_new_full (g_int_hash,
                                      g_int_equal,
                                      g_free,
                                      (GDestroyNotify)g_hash_table_unref);
      if (t_test_thrift_test_if_test_map_map (test_client,
                                              &map_in,
                                              1,
                                              &error)) {
        g_hash_table_iter_init (&hash_table_iter, map_in);

        printf (" = {");
        while (g_hash_table_iter_next (&hash_table_iter,
                                       &key,
                                       &value)) {
          printf ("%d => {", *(gint32 *)key);

          g_hash_table_iter_init (&inner_hash_table_iter,
                                  (GHashTable *)value);
          while (g_hash_table_iter_next (&inner_hash_table_iter,
                                         &key,
                                         &value)) {
            printf ("%d => %d, ", *(gint32 *)key, *(gint32 *)value);
          }

          printf ("}, ");
        }
        printf ("}\n");

        if (g_hash_table_size (map_in) != 2)
          fail_count++;
        else {
          gint32 inner_keys[] = {1, 2, 3, 4};
          gint32 i32_key;

          i32_key = -4;
          inner_map_in = g_hash_table_lookup (map_in, &i32_key);
          if (inner_map_in == NULL ||
              g_hash_table_size (inner_map_in) != 4)
            fail_count++;
          else {
            keys_in = g_hash_table_get_keys (inner_map_in);
            keys_in = g_list_sort (keys_in, gint32_compare);

            for (i = 0; i < 4; i++) {
              keys_elem = g_list_nth (keys_in, 3 - i);

              if (*(gint32 *)keys_elem->data != (-1 * inner_keys[i]) ||
                  *(gint32 *)g_hash_table_lookup (inner_map_in,
                                                  keys_elem->data) !=
                  (-1 * inner_keys[i])) {
                fail_count++;
                break;
              }
            }

            g_list_free (keys_in);
          }

          i32_key = 4;
          inner_map_in = g_hash_table_lookup (map_in, &i32_key);
          if (inner_map_in == NULL ||
              g_hash_table_size (inner_map_in) != 4)
            fail_count++;
          else {
            keys_in = g_hash_table_get_keys (inner_map_in);
            keys_in = g_list_sort (keys_in, gint32_compare);

            for (i = 0; i < 4; i++) {
              keys_elem = g_list_nth (keys_in, i);

              if (*(gint32 *)keys_elem->data != inner_keys[i] ||
                  *(gint32 *)g_hash_table_lookup (inner_map_in,
                                                  keys_elem->data) !=
                  inner_keys[i]) {
                fail_count++;
                break;
              }
            }

            g_list_free (keys_in);
          }
        }
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      g_hash_table_unref (map_in);

      /**
       * INSANITY TEST
       */
      insanity_out = g_object_new (T_TEST_TYPE_INSANITY, NULL);
      g_object_get (insanity_out,
                    "userMap", &user_map,
                    "xtructs", &xtructs,
                    NULL);

      numberz = T_TEST_NUMBERZ_FIVE;
      numberz2 = T_TEST_NUMBERZ_EIGHT;
      user_id_ptr = g_malloc (sizeof *user_id_ptr);
      *user_id_ptr = 5;
      user_id_ptr2 = g_malloc (sizeof *user_id_ptr);
      *user_id_ptr2 = 8;
      g_hash_table_insert (user_map, (gpointer)numberz, user_id_ptr);
      g_hash_table_insert (user_map, (gpointer)numberz2, user_id_ptr2);
      g_hash_table_unref (user_map);

      xtruct_out = g_object_new (T_TEST_TYPE_XTRUCT,
                                 "string_thing", "Hello2",
                                 "byte_thing",   2,
                                 "i32_thing",    2,
                                 "i64_thing",    2LL,
                                 NULL);
      xtruct_out2 = g_object_new (T_TEST_TYPE_XTRUCT,
                                 "string_thing", "Goodbye4",
                                 "byte_thing",   4,
                                 "i32_thing",    4,
                                 "i64_thing",    4LL,
                                 NULL);
      g_ptr_array_add (xtructs, xtruct_out2);
      g_ptr_array_add (xtructs, xtruct_out);
      g_ptr_array_unref (xtructs);

      map_in = g_hash_table_new_full (g_int64_hash,
                                      g_int64_equal,
                                      g_free,
                                      (GDestroyNotify)g_hash_table_unref);

      printf("testInsanity()");
      if (t_test_thrift_test_if_test_insanity (test_client,
                                               &map_in,
                                               insanity_out,
                                               &error)) {
        printf (" = {");
        g_hash_table_iter_init (&hash_table_iter, map_in);
        while (g_hash_table_iter_next (&hash_table_iter,
                                       &key,
                                       &value)) {
          printf ("%" PRId64 " => {", *(TTestUserId *)key);

          g_hash_table_iter_init (&inner_hash_table_iter,
                                  (GHashTable *)value);
          while (g_hash_table_iter_next (&inner_hash_table_iter,
                                         &key,
                                         &value)) {
            printf ("%d => {", (TTestNumberz)key);

            g_object_get ((TTestInsanity *)value,
                          "userMap", &user_map,
                          "xtructs", &xtructs,
                          NULL);

            printf ("{");
            g_hash_table_iter_init (&user_map_iter, user_map);
            while (g_hash_table_iter_next (&user_map_iter,
                                           &key,
                                           &value)) {
              printf ("%d => %" PRId64 ", ",
                      (TTestNumberz)key,
                      *(TTestUserId *)value);
            }
            printf ("}, ");
            g_hash_table_unref (user_map);

            printf("{");
            for (i = 0; i < (gint32)xtructs->len; ++i) {
              xtruct_in = g_ptr_array_index (xtructs, i);
              g_object_get (xtruct_in,
                            "string_thing", &string,
                            "byte_thing",   &byte_thing,
                            "i32_thing",    &i32_thing,
                            "i64_thing",    &i64_thing,
                            NULL);

              printf ("{\"%s\", %d, %d, %" PRId64 "}, ",
                      string,
                      byte_thing,
                      i32_thing,
                      i64_thing);
              if (string != NULL)
                g_free (string);
            }
            printf ("}");
            g_ptr_array_unref (xtructs);

            printf ("}, ");
          }
          printf("}, ");
        }
        printf("}\n");

        if (g_hash_table_size (map_in) != 2)
          fail_count++;
        else {
          TTestNumberz numberz_key_values[] = {
            T_TEST_NUMBERZ_TWO, T_TEST_NUMBERZ_THREE
          };
          gint user_map_values[] = { 5, 8 };
          TTestUserId user_id_key;

          user_id_key = 1;
          inner_map_in = g_hash_table_lookup (map_in, &user_id_key);
          if (inner_map_in == NULL ||
              g_hash_table_size (inner_map_in) != 2)
            fail_count++;
          else {
            TTestNumberz numberz_key;

            for (i = 0; i < 2; ++i) {
              numberz_key = numberz_key_values[i];
              insanity_in =
                g_hash_table_lookup (inner_map_in,
                                     (gconstpointer)numberz_key);
              if (insanity_in == NULL)
                fail_count++;
              else {
                g_object_get (insanity_in,
                              "userMap", &user_map,
                              "xtructs", &xtructs,
                              NULL);

                if (user_map == NULL)
                  fail_count++;
                else {
                  if (g_hash_table_size (user_map) != 2)
                    fail_count++;
                  else {
                    for (j = 0; j < 2; ++j) {
                      numberz_key = (TTestNumberz)user_map_values[j];

                      value =
                        g_hash_table_lookup (user_map,
                                             (gconstpointer)numberz_key);
                      if (value == NULL ||
                          *(TTestUserId *)value != (TTestUserId)user_map_values[j])
                        fail_count++;
                    }
                  }

                  g_hash_table_unref (user_map);
                }

                if (xtructs == NULL)
                  fail_count++;
                else {
                  if (xtructs->len != 2)
                    fail_count++;
                  else {
                    xtruct_in = g_ptr_array_index (xtructs, 0);
                    g_object_get (xtruct_in,
                                  "string_thing", &string,
                                  "byte_thing",   &byte_thing,
                                  "i32_thing",    &i32_thing,
                                  "i64_thing",    &i64_thing,
                                  NULL);
                    if ((string == NULL ||
                         strncmp (string, "Goodbye4", 9) != 0) ||
                        byte_thing != 4 ||
                        i32_thing != 4 ||
                        i64_thing != 4)
                      fail_count++;

                    if (string != NULL)
                      g_free (string);

                    xtruct_in = g_ptr_array_index (xtructs, 1);
                    g_object_get (xtruct_in,
                                  "string_thing", &string,
                                  "byte_thing",   &byte_thing,
                                  "i32_thing",    &i32_thing,
                                  "i64_thing",    &i64_thing,
                                  NULL);
                    if ((string == NULL ||
                         strncmp (string, "Hello2", 7) != 0) ||
                        byte_thing != 2 ||
                        i32_thing != 2 ||
                        i64_thing != 2)
                      fail_count++;

                    if (string != NULL)
                      g_free (string);
                  }

                  g_ptr_array_unref (xtructs);
                }
              }
            }
          }

          user_id_key = 2;
          inner_map_in = g_hash_table_lookup (map_in, &user_id_key);
          if (inner_map_in == NULL ||
              g_hash_table_size (inner_map_in) != 1)
            fail_count++;
          else {
            insanity_in =
              g_hash_table_lookup (inner_map_in,
                                   (gconstpointer)T_TEST_NUMBERZ_SIX);
            if (insanity_in == NULL)
              fail_count++;
            else {
              g_object_get (insanity_in,
                            "userMap", &user_map,
                            "xtructs", &xtructs,
                            NULL);

              if (user_map == NULL)
                fail_count++;
              else {
                if (g_hash_table_size (user_map) != 0)
                  fail_count++;

                g_hash_table_unref (user_map);
              }

              if (xtructs == NULL)
                fail_count++;
              else {
                if (xtructs->len != 0)
                  fail_count++;

                g_ptr_array_unref (xtructs);
              }
            }
          }
        }
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      g_hash_table_unref (map_in);
      g_clear_object (&insanity_out);

      /* test exception */
      printf ("testClient.testException(\"Xception\") =>");
      if (!t_test_thrift_test_if_test_exception (test_client,
                                                 "Xception",
                                                 &xception,
                                                 &error) &&
          xception != NULL) {
        g_object_get (xception,
                      "errorCode", &int32,
                      "message",   &string,
                      NULL);
        printf ("  {%u, \"%s\"}\n", int32, string);
        g_free (string);

        g_clear_object (&xception);

        g_error_free (error);
        error = NULL;
      }
      else {
        printf ("  void\nFAILURE\n");
        fail_count++;

        if (xception != NULL) {
          g_object_unref (xception);
          xception = NULL;
        }

        if (error != NULL) {
          g_error_free (error);
          error = NULL;
        }
      }

      printf ("testClient.testException(\"TException\") =>");
      if (!t_test_thrift_test_if_test_exception (test_client,
                                                 "TException",
                                                 &xception,
                                                 &error) &&
          xception == NULL &&
          error != NULL) {
        printf ("  Caught TException\n");

        g_error_free (error);
        error = NULL;
      }
      else {
        printf ("  void\nFAILURE\n");
        fail_count++;

        g_clear_object (&xception);

        if (error != NULL) {
          g_error_free (error);
          error = NULL;
        }
      }

      printf ("testClient.testException(\"success\") =>");
      if (t_test_thrift_test_if_test_exception (test_client,
                                                "success",
                                                &xception,
                                                &error))
        printf ("  void\n");
      else {
        printf ("  void\nFAILURE\n");
        fail_count++;

        g_clear_object (&xception);

        g_error_free (error);
        error = NULL;
      }

      g_assert (error == NULL);

      /* test multi exception */
      printf ("testClient.testMultiException(\"Xception\", \"test 1\") =>");
      xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);
      if (!t_test_thrift_test_if_test_multi_exception (test_client,
                                                       &xtruct_in,
                                                       "Xception",
                                                       "test 1",
                                                       &xception,
                                                       &xception2,
                                                       &error) &&
          xception != NULL &&
          xception2 == NULL) {
        g_object_get (xception,
                      "errorCode", &int32,
                      "message",   &string,
                      NULL);
        printf ("  {%u, \"%s\"}\n", int32, string);
        g_free (string);

        g_object_unref (xception);
        xception = NULL;

        g_error_free (error);
        error = NULL;
      }
      else {
        printf ("  result\nFAILURE\n");
        fail_count++;

        g_clear_object (&xception);
        g_clear_object (&xception2);

        if (error != NULL) {
          g_error_free (error);
          error = NULL;
        }
      }
      g_object_unref (xtruct_in);

      printf ("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
      xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);
      if (!t_test_thrift_test_if_test_multi_exception (test_client,
                                                       &xtruct_in,
                                                       "Xception2",
                                                       "test 2",
                                                       &xception,
                                                       &xception2,
                                                       &error) &&
          xception == NULL &&
          xception2 != NULL) {
        g_object_get (xception2,
                      "errorCode",    &int32,
                      "struct_thing", &inner_xtruct_in,
                      NULL);
        g_object_get (inner_xtruct_in,
                      "string_thing", &string,
                      NULL);
        printf ("  {%u, {\"%s\"}}\n", int32, string);
        g_free (string);

        g_clear_object (&inner_xtruct_in);
        g_clear_object (&xception2);

        g_error_free (error);
        error = NULL;
      }
      else {
        printf ("  result\nFAILURE\n");
        fail_count++;

        g_clear_object (&xception);
        g_clear_object (&xception2);

        if (error != NULL) {
          g_error_free (error);
          error = NULL;
        }
      }
      g_clear_object (&xtruct_in);

      printf ("testClient.testMultiException(\"success\", \"test 3\") =>");
      xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);
      if (t_test_thrift_test_if_test_multi_exception (test_client,
                                                      &xtruct_in,
                                                      "success",
                                                      "test 3",
                                                      &xception,
                                                      &xception2,
                                                      &error) &&
          xception == NULL &&
          xception2 == NULL) {
        g_object_get (xtruct_in,
                      "string_thing", &string,
                      NULL);
        printf ("  {{\"%s\"}}\n", string);
        g_free (string);
      }
      else {
        printf ("  result\nFAILURE\n");
        fail_count++;

        g_clear_object (&xception);
        g_clear_object (&xception2);

        if (error != NULL) {
          g_error_free (error);
          error = NULL;
        }
      }
      g_clear_object (&xtruct_in);

      /* test oneway void */
      printf ("testClient.testOneway(1) =>");
      gettimeofday (&oneway_start, NULL);
      oneway_result = t_test_thrift_test_if_test_oneway (test_client,
                                                         1,
                                                         &error);
      gettimeofday (&oneway_end, NULL);
      timersub (&oneway_end, &oneway_start, &oneway_elapsed);
      oneway_elapsed_usec =
        oneway_elapsed.tv_sec * 1000 * 1000 + oneway_elapsed.tv_usec;

      if (oneway_result) {
        if (oneway_elapsed_usec > 200 * 1000) {
          printf ("  FAILURE - took %.2f ms\n",
                  (double)oneway_elapsed_usec / 1000.0);
          fail_count++;
        }
        else
          printf ("  success - took %.2f ms\n",
                  (double)oneway_elapsed_usec / 1000.0);
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      /**
       * redo a simple test after the oneway to make sure we aren't "off by
       * one" -- if the server treated oneway void like normal void, this next
       * test will fail since it will get the void confirmation rather than
       * the correct result. In this circumstance, the client will receive the
       * error:
       *
       *   application error: Wrong method name
       */
      /**
       * I32 TEST
       */
      printf ("re-test testI32(-1)");
      if (t_test_thrift_test_if_test_i32 (test_client,
                                          &int32,
                                          -1,
                                          &error)) {
        printf (" = %d\n", int32);
        if (int32 != -1)
          fail_count++;
      }
      else {
        printf ("%s\n", error->message);
        g_error_free (error);
        error = NULL;

        fail_count++;
      }

      gettimeofday (&time_stop, NULL);
      timersub (&time_stop, &time_start, &time_elapsed);
      time_elapsed_usec =
        time_elapsed.tv_sec * 1000 * 1000 + time_elapsed.tv_usec;

      printf("Total time: %" PRIu64 " us\n", time_elapsed_usec);

      time_total_usec += time_elapsed_usec;
      if (time_elapsed_usec < time_min_usec)
        time_min_usec = time_elapsed_usec;
      if (time_elapsed_usec > time_max_usec)
        time_max_usec = time_elapsed_usec;

      thrift_transport_close (transport, &error);
    }
    else {
      printf ("Connect failed: %s\n", error->message);
      g_error_free (error);
      error = NULL;

      goto out;
    }
  }

  /* All done---output statistics */
  puts ("\nAll tests done.");
  printf("Number of failures: %d\n", fail_count);

  time_avg_usec = time_total_usec / num_tests;

  printf ("Min time: %" PRIu64 " us\n", time_min_usec);
  printf ("Max time: %" PRIu64 " us\n", time_max_usec);
  printf ("Avg time: %" PRIu64 " us\n", time_avg_usec);

out:
  g_clear_object(&second_service);
  g_clear_object(&protocol2);
  g_clear_object(&test_client);
  g_clear_object(&protocol);
  g_clear_object(&multiplexed_protocol);
  g_clear_object(&transport);
  g_clear_object(&socket);

  if (ssl) {
    thrift_ssl_socket_finalize_openssl();
  }

  return fail_count;
}
thrift-0.23.0/test/c_glib/src/thrift_second_service_handler.c0000664000175000017500000000405015165535636024575 0ustar00buildbuild00000000000000/*
 * 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 

#include "thrift_second_service_handler.h"

/* A handler that implements the TTestSecondServiceIf interface */

G_DEFINE_TYPE (SecondServiceHandler,
               second_service_handler,
	       T_TEST_TYPE_SECOND_SERVICE_HANDLER);


gboolean
second_service_handler_secondtest_string (TTestSecondServiceIf  *iface,
                                 gchar             **_return,
                                 const gchar        *thing,
                                 GError            **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);
  gchar buffer[256];

  printf ("testSecondServiceMultiplexSecondTestString(\"%s\")\n", thing);
  snprintf(buffer, 255, "testString(\"%s\")", thing);
  *_return = g_strdup (buffer);

  return TRUE;
}

static void
second_service_handler_init (SecondServiceHandler *self)
{
  THRIFT_UNUSED_VAR (self);
}

static void
second_service_handler_class_init (SecondServiceHandlerClass *klass)
{
  TTestSecondServiceHandlerClass *base_class =
      T_TEST_SECOND_SERVICE_HANDLER_CLASS (klass);


  base_class->secondtest_string =
      second_service_handler_secondtest_string;

}
thrift-0.23.0/test/c_glib/src/thrift_second_service_handler.h0000664000175000017500000000551615165535636024612 0ustar00buildbuild00000000000000/*
 * 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 _SECOND_SERVICE_HANDLER_H
#define _SECOND_SERVICE_HANDLER_H

#include 
#include 

#include "../gen-c_glib/t_test_second_service.h"

G_BEGIN_DECLS

/* A handler that implements the TTestSecondServiceIf interface */

#define TYPE_SECOND_SERVICE_HANDLER (second_service_handler_get_type ())

#define SECOND_SERVICE_HANDLER(obj)                                \
  (G_TYPE_CHECK_INSTANCE_CAST ((obj),                           \
                               TYPE_SECOND_SERVICE_HANDLER,        \
                               SecondServiceHandler))
#define IS_SECOND_SERVICE_HANDLER(obj)                             \
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj),                           \
                               TYPE_SECOND_SERVICE_HANDLER))
#define SECOND_SERVICE_HANDLER_CLASS(c)                    \
  (G_TYPE_CHECK_CLASS_CAST ((c),                        \
                            TYPE_SECOND_SERVICE_HANDLER,   \
                            SecondServiceHandlerClass))
#define IS_SECOND_SERVICE_HANDLER_CLASS(c)                 \
  (G_TYPE_CHECK_CLASS_TYPE ((c),                        \
                            TYPE_SECOND_SERVICE_HANDLER))
#define SECOND_SERVICE_HANDLER_GET_CLASS(obj)              \
  (G_TYPE_INSTANCE_GET_CLASS ((obj),                    \
                              TYPE_SECOND_SERVICE_HANDLER, \
                              SecondServiceHandlerClass))

typedef struct _SecondServiceHandler SecondServiceHandler;
typedef struct _SecondServiceHandlerClass SecondServiceHandlerClass;

struct _SecondServiceHandler {
  TTestSecondServiceHandler parent;
};

struct _SecondServiceHandlerClass {
  TTestSecondServiceHandlerClass parent;

};

/* Used by SECOND_SERVICE_HANDLER_GET_TYPE */
GType second_service_handler_get_type (void);

gboolean second_service_handler_blah_blah (TTestSecondServiceIf *iface, GError **error);
gboolean second_service_handler_secondtest_string          (TTestSecondServiceIf *iface, gchar ** _return, const gchar * thing, GError **error);

G_END_DECLS

#endif /* _SECOND_SERVICE_HANDLER_H */
thrift-0.23.0/test/c_glib/CMakeLists.txt0000664000175000017500000000460015165535636020333 0ustar00buildbuild00000000000000#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

# Contains the thrift specific target_link_libraries
include(ThriftMacros)

find_package(GLIB REQUIRED COMPONENTS gobject)
include_directories(SYSTEM "${GLIB_INCLUDE_DIR}")
include_directories(SYSTEM "${GLIBCONFIG_INCLUDE_DIR}")

#Make sure gen-c_glib files can be included
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-c_glib")
include_directories("${PROJECT_SOURCE_DIR}/lib/c_glib/src")
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")

set(crosstestgencglib_SOURCES
	gen-c_glib/t_test_second_service.c
	gen-c_glib/t_test_second_service.h
	gen-c_glib/t_test_thrift_test.c
	gen-c_glib/t_test_thrift_test.h
	gen-c_glib/t_test_thrift_test_types.c
	gen-c_glib/t_test_thrift_test_types.h
)
add_library(crosstestgencglib STATIC ${crosstestgencglib_SOURCES})
target_link_libraries(crosstestgencglib thrift_c_glib)

if (WITH_ZLIB)
  target_link_libraries(crosstestgencglib thrift_c_glib_zlib)
endif ()

add_executable(test_server src/test_server.c src/thrift_test_handler.c src/thrift_second_service_handler.c)
target_link_libraries(test_server crosstestgencglib ${ZLIB_LIBRARIES})

add_executable(test_client src/test_client.c)
target_link_libraries(test_client crosstestgencglib "${OPENSSL_LIBRARIES}")

#
# Common thrift code generation rules
#

add_custom_command(OUTPUT gen-c_glib/t_test_second_service.c  gen-c_glib/t_test_second_service.h  gen-c_glib/t_test_thrift_test.c  gen-c_glib/t_test_thrift_test.h  gen-c_glib/t_test_thrift_test_types.c  gen-c_glib/t_test_thrift_test_types.h
    COMMAND ${THRIFT_COMPILER} --gen c_glib -r ${PROJECT_SOURCE_DIR}/test/v0.16/ThriftTest.thrift
)
thrift-0.23.0/test/c_glib/Makefile0000644000175000017500000007162215170007175017225 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/c_glib/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.




am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
check_PROGRAMS = test_client$(EXEEXT) test_server$(EXEEXT)
subdir = test/c_glib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libtestcglib_la_DEPENDENCIES =  \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la
am__dirstamp = $(am__leading_dot)dirstamp
nodist_libtestcglib_la_OBJECTS = gen-c_glib/t_test_second_service.lo \
	gen-c_glib/t_test_thrift_test.lo \
	gen-c_glib/t_test_thrift_test_types.lo
libtestcglib_la_OBJECTS = $(nodist_libtestcglib_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
am__v_lt_1 = 
am_test_client_OBJECTS = src/test_client.$(OBJEXT)
test_client_OBJECTS = $(am_test_client_OBJECTS)
test_client_DEPENDENCIES = libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la
am_test_server_OBJECTS = src/thrift_test_handler.$(OBJEXT) \
	src/thrift_second_service_handler.$(OBJEXT) \
	src/test_server.$(OBJEXT)
test_server_OBJECTS = $(am_test_server_OBJECTS)
test_server_DEPENDENCIES = libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = 
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = gen-c_glib/$(DEPDIR)/t_test_second_service.Plo \
	gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo \
	gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo \
	src/$(DEPDIR)/test_client.Po src/$(DEPDIR)/test_server.Po \
	src/$(DEPDIR)/thrift_second_service_handler.Po \
	src/$(DEPDIR)/thrift_test_handler.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_$(V))
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
am__v_CC_0 = @echo "  CC      " $@;
am__v_CC_1 = 
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_$(V))
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = $(nodist_libtestcglib_la_SOURCES) $(test_client_SOURCES) \
	$(test_server_SOURCES)
DIST_SOURCES = $(test_client_SOURCES) $(test_server_SOURCES)
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates.  Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
  BEGIN { nonempty = 0; } \
  { items[$$0] = 1; nonempty = 1; } \
  END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique.  This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
  list='$(am__tagged_files)'; \
  unique=`for i in $$list; do \
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  done | $(am__uniquify_input)`
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = /thrift/src/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/c_glib
abs_srcdir = /thrift/src/test/c_glib
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..

#
# 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.
#
AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
noinst_LTLIBRARIES = libtestcglib.la
nodist_libtestcglib_la_SOURCES = \
	gen-c_glib/t_test_second_service.c \
	gen-c_glib/t_test_second_service.h \
	gen-c_glib/t_test_thrift_test.c \
	gen-c_glib/t_test_thrift_test.h \
	gen-c_glib/t_test_thrift_test_types.c \
	gen-c_glib/t_test_thrift_test_types.h

libtestcglib_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la
test_client_SOURCES = \
	src/test_client.c

test_client_LDADD = \
	libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la

test_server_SOURCES = \
	src/thrift_test_handler.c \
	src/thrift_test_handler.h \
	src/thrift_second_service_handler.c \
	src/thrift_second_service_handler.h \
	src/test_server.c

test_server_LDADD = \
	libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la

AM_CFLAGS = -g -Wall -Wextra $(GLIB_CFLAGS) $(GOBJECT_CFLAGS)
AM_CXXFLAGS = $(AM_CFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -Igen-c_glib -I$(top_builddir)/lib/c_glib/src/thrift
AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) 
EXTRA_DIST = \
	src

all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/c_glib/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/c_glib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

clean-checkPROGRAMS:
	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list

clean-noinstLTLIBRARIES:
	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
	@list='$(noinst_LTLIBRARIES)'; \
	locs=`for p in $$list; do echo $$p; done | \
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
	      sort -u`; \
	test -z "$$locs" || { \
	  echo rm -f $${locs}; \
	  rm -f $${locs}; \
	}
gen-c_glib/$(am__dirstamp):
	@$(MKDIR_P) gen-c_glib
	@: > gen-c_glib/$(am__dirstamp)
gen-c_glib/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-c_glib/$(DEPDIR)
	@: > gen-c_glib/$(DEPDIR)/$(am__dirstamp)
gen-c_glib/t_test_second_service.lo: gen-c_glib/$(am__dirstamp) \
	gen-c_glib/$(DEPDIR)/$(am__dirstamp)
gen-c_glib/t_test_thrift_test.lo: gen-c_glib/$(am__dirstamp) \
	gen-c_glib/$(DEPDIR)/$(am__dirstamp)
gen-c_glib/t_test_thrift_test_types.lo: gen-c_glib/$(am__dirstamp) \
	gen-c_glib/$(DEPDIR)/$(am__dirstamp)

libtestcglib.la: $(libtestcglib_la_OBJECTS) $(libtestcglib_la_DEPENDENCIES) $(EXTRA_libtestcglib_la_DEPENDENCIES) 
	$(AM_V_CCLD)$(LINK)  $(libtestcglib_la_OBJECTS) $(libtestcglib_la_LIBADD) $(LIBS)
src/$(am__dirstamp):
	@$(MKDIR_P) src
	@: > src/$(am__dirstamp)
src/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) src/$(DEPDIR)
	@: > src/$(DEPDIR)/$(am__dirstamp)
src/test_client.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

test_client$(EXEEXT): $(test_client_OBJECTS) $(test_client_DEPENDENCIES) $(EXTRA_test_client_DEPENDENCIES) 
	@rm -f test_client$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_client_OBJECTS) $(test_client_LDADD) $(LIBS)
src/thrift_test_handler.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)
src/thrift_second_service_handler.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)
src/test_server.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

test_server$(EXEEXT): $(test_server_OBJECTS) $(test_server_DEPENDENCIES) $(EXTRA_test_server_DEPENDENCIES) 
	@rm -f test_server$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_server_OBJECTS) $(test_server_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)
	-rm -f gen-c_glib/*.$(OBJEXT)
	-rm -f gen-c_glib/*.lo
	-rm -f src/*.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

include gen-c_glib/$(DEPDIR)/t_test_second_service.Plo # am--include-marker
include gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo # am--include-marker
include gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo # am--include-marker
include src/$(DEPDIR)/test_client.Po # am--include-marker
include src/$(DEPDIR)/test_server.Po # am--include-marker
include src/$(DEPDIR)/thrift_second_service_handler.Po # am--include-marker
include src/$(DEPDIR)/thrift_test_handler.Po # am--include-marker

$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

.c.o:
	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
	$(am__mv) $$depbase.Tpo $$depbase.Po
#	$(AM_V_CC)source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(AM_V_CC_no)$(COMPILE) -c -o $@ $<

.c.obj:
	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
	$(am__mv) $$depbase.Tpo $$depbase.Po
#	$(AM_V_CC)source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`

.c.lo:
	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
	$(am__mv) $$depbase.Tpo $$depbase.Plo
#	$(AM_V_CC)source='$<' object='$@' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(AM_V_CC_no)$(LTCOMPILE) -c -o $@ $<

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
	-rm -rf gen-c_glib/.libs gen-c_glib/_libs
style-local: 

ID: $(am__tagged_files)
	$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags

tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	set x; \
	here=`pwd`; \
	$(am__define_uniq_tagged_files); \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: ctags-am

CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	$(am__define_uniq_tagged_files); \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am

cscopelist-am: $(am__tagged_files)
	list='$(am__tagged_files)'; \
	case "$(srcdir)" in \
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
	  *) sdir=$(subdir)/$(srcdir) ;; \
	esac; \
	for i in $$list; do \
	  if test -f "$$i"; then \
	    echo "$(subdir)/$$i"; \
	  else \
	    echo "$$sdir/$$i"; \
	  fi; \
	done >> $(top_builddir)/cscope.files

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
	-rm -f gen-c_glib/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-c_glib/$(am__dirstamp)
	-rm -f src/$(DEPDIR)/$(am__dirstamp)
	-rm -f src/$(am__dirstamp)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES mostlyclean-am

distclean: distclean-am
		-rm -f gen-c_glib/$(DEPDIR)/t_test_second_service.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo
	-rm -f src/$(DEPDIR)/test_client.Po
	-rm -f src/$(DEPDIR)/test_server.Po
	-rm -f src/$(DEPDIR)/thrift_second_service_handler.Po
	-rm -f src/$(DEPDIR)/thrift_test_handler.Po
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f gen-c_glib/$(DEPDIR)/t_test_second_service.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo
	-rm -f src/$(DEPDIR)/test_client.Po
	-rm -f src/$(DEPDIR)/test_server.Po
	-rm -f src/$(DEPDIR)/thrift_second_service_handler.Po
	-rm -f src/$(DEPDIR)/thrift_test_handler.Po
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: check-am install-am install-strip

.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
	clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am dist-hook \
	distclean distclean-compile distclean-generic \
	distclean-libtool distclean-tags distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-compile \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags tags-am uninstall uninstall-am

.PRECIOUS: Makefile


precross: libtestcglib.la test_client test_server

#
# Common thrift code generation rules
#
gen-c_glib/t_test_second_service.c  gen-c_glib/t_test_second_service.h  gen-c_glib/t_test_thrift_test.c  gen-c_glib/t_test_thrift_test.h  gen-c_glib/t_test_thrift_test_types.c  gen-c_glib/t_test_thrift_test_types.h: $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT)
	$(THRIFT) --gen c_glib -r $<

clean-local:
	$(RM) -r gen-c_glib/
	$(RM) test_client
	$(RM) test_server
	$(RM) libtestcglib.la
	find . -type f -iname "*.o" | xargs rm -f

dist-hook:
	$(RM) -r $(distdir)/gen-c_glib/
	$(RM) $(distdir)/test_client
	$(RM) $(distdir)/test_server
	$(RM) $(distdir)/libtestcglib.la
	find $(distdir) -type f -iname "*.o" | xargs rm -f

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/c_glib/Makefile.in0000644000175000017500000007223415170007167017633 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
check_PROGRAMS = test_client$(EXEEXT) test_server$(EXEEXT)
subdir = test/c_glib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libtestcglib_la_DEPENDENCIES =  \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la
am__dirstamp = $(am__leading_dot)dirstamp
nodist_libtestcglib_la_OBJECTS = gen-c_glib/t_test_second_service.lo \
	gen-c_glib/t_test_thrift_test.lo \
	gen-c_glib/t_test_thrift_test_types.lo
libtestcglib_la_OBJECTS = $(nodist_libtestcglib_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 
am_test_client_OBJECTS = src/test_client.$(OBJEXT)
test_client_OBJECTS = $(am_test_client_OBJECTS)
test_client_DEPENDENCIES = libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la
am_test_server_OBJECTS = src/thrift_test_handler.$(OBJEXT) \
	src/thrift_second_service_handler.$(OBJEXT) \
	src/test_server.$(OBJEXT)
test_server_OBJECTS = $(am_test_server_OBJECTS)
test_server_DEPENDENCIES = libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = 
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = gen-c_glib/$(DEPDIR)/t_test_second_service.Plo \
	gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo \
	gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo \
	src/$(DEPDIR)/test_client.Po src/$(DEPDIR)/test_server.Po \
	src/$(DEPDIR)/thrift_second_service_handler.Po \
	src/$(DEPDIR)/thrift_test_handler.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo "  CC      " $@;
am__v_CC_1 = 
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = $(nodist_libtestcglib_la_SOURCES) $(test_client_SOURCES) \
	$(test_server_SOURCES)
DIST_SOURCES = $(test_client_SOURCES) $(test_server_SOURCES)
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates.  Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
  BEGIN { nonempty = 0; } \
  { items[$$0] = 1; nonempty = 1; } \
  END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique.  This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
  list='$(am__tagged_files)'; \
  unique=`for i in $$list; do \
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  done | $(am__uniquify_input)`
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@

#
# 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.
#
AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
noinst_LTLIBRARIES = libtestcglib.la
nodist_libtestcglib_la_SOURCES = \
	gen-c_glib/t_test_second_service.c \
	gen-c_glib/t_test_second_service.h \
	gen-c_glib/t_test_thrift_test.c \
	gen-c_glib/t_test_thrift_test.h \
	gen-c_glib/t_test_thrift_test_types.c \
	gen-c_glib/t_test_thrift_test_types.h

libtestcglib_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la
test_client_SOURCES = \
	src/test_client.c

test_client_LDADD = \
	libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la

test_server_SOURCES = \
	src/thrift_test_handler.c \
	src/thrift_test_handler.h \
	src/thrift_second_service_handler.c \
	src/thrift_second_service_handler.h \
	src/test_server.c

test_server_LDADD = \
	libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la

AM_CFLAGS = -g -Wall -Wextra $(GLIB_CFLAGS) $(GOBJECT_CFLAGS)
AM_CXXFLAGS = $(AM_CFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -Igen-c_glib -I$(top_builddir)/lib/c_glib/src/thrift
AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) @GCOV_LDFLAGS@
EXTRA_DIST = \
	src

all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/c_glib/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/c_glib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

clean-checkPROGRAMS:
	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list

clean-noinstLTLIBRARIES:
	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
	@list='$(noinst_LTLIBRARIES)'; \
	locs=`for p in $$list; do echo $$p; done | \
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
	      sort -u`; \
	test -z "$$locs" || { \
	  echo rm -f $${locs}; \
	  rm -f $${locs}; \
	}
gen-c_glib/$(am__dirstamp):
	@$(MKDIR_P) gen-c_glib
	@: > gen-c_glib/$(am__dirstamp)
gen-c_glib/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-c_glib/$(DEPDIR)
	@: > gen-c_glib/$(DEPDIR)/$(am__dirstamp)
gen-c_glib/t_test_second_service.lo: gen-c_glib/$(am__dirstamp) \
	gen-c_glib/$(DEPDIR)/$(am__dirstamp)
gen-c_glib/t_test_thrift_test.lo: gen-c_glib/$(am__dirstamp) \
	gen-c_glib/$(DEPDIR)/$(am__dirstamp)
gen-c_glib/t_test_thrift_test_types.lo: gen-c_glib/$(am__dirstamp) \
	gen-c_glib/$(DEPDIR)/$(am__dirstamp)

libtestcglib.la: $(libtestcglib_la_OBJECTS) $(libtestcglib_la_DEPENDENCIES) $(EXTRA_libtestcglib_la_DEPENDENCIES) 
	$(AM_V_CCLD)$(LINK)  $(libtestcglib_la_OBJECTS) $(libtestcglib_la_LIBADD) $(LIBS)
src/$(am__dirstamp):
	@$(MKDIR_P) src
	@: > src/$(am__dirstamp)
src/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) src/$(DEPDIR)
	@: > src/$(DEPDIR)/$(am__dirstamp)
src/test_client.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

test_client$(EXEEXT): $(test_client_OBJECTS) $(test_client_DEPENDENCIES) $(EXTRA_test_client_DEPENDENCIES) 
	@rm -f test_client$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_client_OBJECTS) $(test_client_LDADD) $(LIBS)
src/thrift_test_handler.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)
src/thrift_second_service_handler.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)
src/test_server.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

test_server$(EXEEXT): $(test_server_OBJECTS) $(test_server_DEPENDENCIES) $(EXTRA_test_server_DEPENDENCIES) 
	@rm -f test_server$(EXEEXT)
	$(AM_V_CCLD)$(LINK) $(test_server_OBJECTS) $(test_server_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)
	-rm -f gen-c_glib/*.$(OBJEXT)
	-rm -f gen-c_glib/*.lo
	-rm -f src/*.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/t_test_second_service.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_client.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_server.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/thrift_second_service_handler.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/thrift_test_handler.Po@am__quote@ # am--include-marker

$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

.c.o:
@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<

.c.obj:
@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`

.c.lo:
@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
	-rm -rf gen-c_glib/.libs gen-c_glib/_libs
style-local: 

ID: $(am__tagged_files)
	$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags

tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	set x; \
	here=`pwd`; \
	$(am__define_uniq_tagged_files); \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: ctags-am

CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	$(am__define_uniq_tagged_files); \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am

cscopelist-am: $(am__tagged_files)
	list='$(am__tagged_files)'; \
	case "$(srcdir)" in \
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
	  *) sdir=$(subdir)/$(srcdir) ;; \
	esac; \
	for i in $$list; do \
	  if test -f "$$i"; then \
	    echo "$(subdir)/$$i"; \
	  else \
	    echo "$$sdir/$$i"; \
	  fi; \
	done >> $(top_builddir)/cscope.files

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
	-rm -f gen-c_glib/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-c_glib/$(am__dirstamp)
	-rm -f src/$(DEPDIR)/$(am__dirstamp)
	-rm -f src/$(am__dirstamp)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES mostlyclean-am

distclean: distclean-am
		-rm -f gen-c_glib/$(DEPDIR)/t_test_second_service.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo
	-rm -f src/$(DEPDIR)/test_client.Po
	-rm -f src/$(DEPDIR)/test_server.Po
	-rm -f src/$(DEPDIR)/thrift_second_service_handler.Po
	-rm -f src/$(DEPDIR)/thrift_test_handler.Po
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f gen-c_glib/$(DEPDIR)/t_test_second_service.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test.Plo
	-rm -f gen-c_glib/$(DEPDIR)/t_test_thrift_test_types.Plo
	-rm -f src/$(DEPDIR)/test_client.Po
	-rm -f src/$(DEPDIR)/test_server.Po
	-rm -f src/$(DEPDIR)/thrift_second_service_handler.Po
	-rm -f src/$(DEPDIR)/thrift_test_handler.Po
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: check-am install-am install-strip

.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
	clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am dist-hook \
	distclean distclean-compile distclean-generic \
	distclean-libtool distclean-tags distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-compile \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags tags-am uninstall uninstall-am

.PRECIOUS: Makefile


precross: libtestcglib.la test_client test_server

#
# Common thrift code generation rules
#
gen-c_glib/t_test_second_service.c  gen-c_glib/t_test_second_service.h  gen-c_glib/t_test_thrift_test.c  gen-c_glib/t_test_thrift_test.h  gen-c_glib/t_test_thrift_test_types.c  gen-c_glib/t_test_thrift_test_types.h: $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT)
	$(THRIFT) --gen c_glib -r $<

clean-local:
	$(RM) -r gen-c_glib/
	$(RM) test_client
	$(RM) test_server
	$(RM) libtestcglib.la
	find . -type f -iname "*.o" | xargs rm -f

dist-hook:
	$(RM) -r $(distdir)/gen-c_glib/
	$(RM) $(distdir)/test_client
	$(RM) $(distdir)/test_server
	$(RM) $(distdir)/libtestcglib.la
	find $(distdir) -type f -iname "*.o" | xargs rm -f

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/c_glib/Makefile.am0000664000175000017500000000521515165535636017632 0ustar00buildbuild00000000000000#
# 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.
#
AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc

noinst_LTLIBRARIES = libtestcglib.la
nodist_libtestcglib_la_SOURCES = \
	gen-c_glib/t_test_second_service.c \
	gen-c_glib/t_test_second_service.h \
	gen-c_glib/t_test_thrift_test.c \
	gen-c_glib/t_test_thrift_test.h \
	gen-c_glib/t_test_thrift_test_types.c \
	gen-c_glib/t_test_thrift_test_types.h

libtestcglib_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la

precross: libtestcglib.la test_client test_server

check_PROGRAMS = \
	test_client \
	test_server

test_client_SOURCES = \
	src/test_client.c

test_client_LDADD = \
	libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la

test_server_SOURCES = \
	src/thrift_test_handler.c \
	src/thrift_test_handler.h \
	src/thrift_second_service_handler.c \
	src/thrift_second_service_handler.h \
	src/test_server.c

test_server_LDADD = \
	libtestcglib.la \
	$(top_builddir)/lib/c_glib/libthrift_c_glib.la

#
# Common thrift code generation rules
#
gen-c_glib/t_test_second_service.c  gen-c_glib/t_test_second_service.h  gen-c_glib/t_test_thrift_test.c  gen-c_glib/t_test_thrift_test.h  gen-c_glib/t_test_thrift_test_types.c  gen-c_glib/t_test_thrift_test_types.h: $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT)
	$(THRIFT) --gen c_glib -r $<

AM_CFLAGS = -g -Wall -Wextra $(GLIB_CFLAGS) $(GOBJECT_CFLAGS)
AM_CXXFLAGS = $(AM_CFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -Igen-c_glib -I$(top_builddir)/lib/c_glib/src/thrift
AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) @GCOV_LDFLAGS@

clean-local:
	$(RM) -r gen-c_glib/
	$(RM) test_client
	$(RM) test_server
	$(RM) libtestcglib.la
	find . -type f -iname "*.o" | xargs rm -f

dist-hook:
	$(RM) -r $(distdir)/gen-c_glib/
	$(RM) $(distdir)/test_client
	$(RM) $(distdir)/test_server
	$(RM) $(distdir)/libtestcglib.la
	find $(distdir) -type f -iname "*.o" | xargs rm -f

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	src
thrift-0.23.0/test/NameConflictTest.thrift0000664000175000017500000000540415165535636021003 0ustar00buildbuild00000000000000/*
 * 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.
 */

// Naming testcases, sepcifically for these tickets (but not limited to them)
// THRIFT-2508 Uncompileable C# code due to language keywords in IDL
// THRIFT-2557 error CS0542 member names cannot be the same as their enclosing type


struct using {
    1: double single
    2: double integer
}

struct delegate {
    1: string partial
    2: delegate delegate
}

struct get {
    1: bool sbyte
}

struct partial {
    1: using using
    2: bool read
    3: bool write
}

enum Maybe {
  JUST = 1,
  TRUE = 2,
  FALSE = 3
}

enum Either {
  LEFT = 1,
  RIGHT = 2
}

struct foldr {
  1: string id
}

struct of {
  1: string let
  2: string where
}

struct ofOf {
  1: of Of
}


struct ClassAndProp {
  1: bool ClassAndProp
  2: bool ClassAndProp_
  3: bool ClassAndProp__
  4: bool ClassAndProper
}

struct second_chance {
  1: bool SECOND_CHANCE
  2: bool SECOND_CHANCE_
  3: bool SECOND_CHANCE__
  4: bool SECOND_CHANCES
}

struct NOW_EAT_THIS {
  1: bool now_eat_this
  2: bool now_eat_this_
  3: bool now_eat_this__
  4: bool now_eat_this_and_this
}

struct TheEdgeCase {
  1: bool theEdgeCase
  2: bool theEdgeCase_
  3: bool theEdgeCase__
  4: bool TheEdgeCase
  5: bool TheEdgeCase_
  6: bool TheEdgeCase__
}

struct Tricky_ {
  1: bool tricky
  2: bool Tricky
}

struct Nested {
  1: ClassAndProp ClassAndProp
  2: second_chance second_chance
  3: NOW_EAT_THIS NOW_EAT_THIS
  4: TheEdgeCase TheEdgeCase
  5: Tricky_ Tricky_
  6: Nested Nested
}

exception Problem_ {
  1: bool problem
  2: bool Problem
}

struct Thrift5626 {
   1: i8       i8
   2: i16      i16
   3: i32      i32
   4: i64      i64
   5: uuid     uuid
   6: string   string
   7: binary   binary
   8: bool     bool
   9: byte     byte
  10: list        list
  11: set         set
  12: map  map
}

service extern {
    delegate event(1: partial get)
    void Foo(1: Nested Foo_args) throws (1: Problem_ Foo_result)
}

service qualified {
    Maybe maybe(1: Maybe foldr)
    Either either(1: foldr of)
}
// eof
thrift-0.23.0/test/audit/0000775000175000017500000000000015165535636015462 5ustar00buildbuild00000000000000thrift-0.23.0/test/audit/break8.thrift0000664000175000017500000001225715165535636020067 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break8 - requiredness addedd in struct5

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: required string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break15.thrift0000664000175000017500000001231315165535636020136 0ustar00buildbuild00000000000000/*
 * 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.
 */

// break15 - derived2_function1 return type changed from list to list
namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/test.thrift0000664000175000017500000001217315165535636017667 0ustar00buildbuild00000000000000/*
 * 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 test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break32.thrift0000664000175000017500000001225715165535636020144 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break32- Exception1 field type changed for id =1

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i64 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break28.thrift0000664000175000017500000001230715165535636020145 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break28- derived1_function5 arguement type changed map to list
namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: list function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break5.thrift0000664000175000017500000001230215165535636020053 0ustar00buildbuild00000000000000/*
 * 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.
 */

// member field type changed in test_struct1(bool to list)

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};

//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: list struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break24.thrift0000664000175000017500000001223615165535636020142 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break24 - removed inheritance from derived1.

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break14.thrift0000664000175000017500000001227415165535636020143 0ustar00buildbuild00000000000000/*
 * 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.
 */

// derived1_function6 return type changed from string to double 

namespace cpp test
//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    double derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break9.thrift0000664000175000017500000001221415165535636020061 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break9 - Struct field removed from struct1


namespace cpp test
//Constants

const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};

//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break23.thrift0000664000175000017500000001232415165535636020137 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break23 - required struct field added to struct4

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2,
    3: required i64 struct4_member3
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break29.thrift0000664000175000017500000001227615165535636020153 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break29 - base_function2 arguemnt type changed list to string

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: string function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/warning.thrift0000664000175000017500000001214615165535636020355 0ustar00buildbuild00000000000000/*
 * 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 test

//Constants

const i32 const1 = 123;
const double const2 = 23.2;
const map const3 = {"hello":"class", "thrift":"audit"};

//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.4,
    5: string struct1_member5,
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 changed19
}

struct test_struct2 {
    1: list struct2_member1,
    2: list changed22,
    3: list struct2_member3,
    4: list struct2_member4 =[1.0, 2.1],
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:10, 2:20},
    2: map struct3_member2 = {1:1.1, 2:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1 = 1.1,
    2: string struct5_member2 = "Thrift Audit Tess"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base{
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break17.thrift0000664000175000017500000001234215165535636020142 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break17 - derived2_function6 return type changed from map to map

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/thrift_audit_test.pl0000664000175000017500000002133715165535636021552 0ustar00buildbuild00000000000000#!/usr/bin/perl -w

# 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.


#break1 - Thrift method removed from service base
#break2 - Struct field changed in test_struct1(i16 to i32)
#break3 - Struct field changed in test_struct1(enum1 to enum2)
#break4 - Field type changed in test_struct1(bool to string)
#break5- member field type changed in test_struct1(bool to list)
#break6-  Field type changed in test_struct2 (list to list)
#break7 - requiredness removed in struct6
#break8 - requiredness addedd in struct5
#break9 - Struct field removed from struct1
#break10 - Struct field removed from struct2 id = 1
#break11 - Struct field removed from struct3 last id
#break12 -  derived1_function1 return type changed from enum1 to enum2
#break13 - derived1_function6 return type changed from struct1 to struct2
#break14 -  derived1_function4 return type changed from string to double 
#break15 - derived2_function1 return type changed from list to list
#break16 - derived2_function5 return type changed from map to map
#break17 - derived2_function6 return type changed from map to map
#break18- oneway removed from base_oneway
#break19 - oneway added to base_function1
#break20 - first enum value removed from enum1
#break21- last enum value removed from enum2
#break22 - in-between enum value removed from enum1
#break23 - required struct field added to struct4
#break24 - removed inheritance of derived1.
#break25 - changed inheritance of derived2.
#break26 - Field type changed in base_function1 argument id=3
#break27 - argument changed base_function2 list to list id =8
#break28- derived1_function5 arguement type changed map to list
#break29 - base_function2 arguemnt type changed list to string
#break30- derived1_function6 argument changed struct1 to map
#break31 - Exception removed to base_function2
#break32- Exception1 field type changed for id =1
#break33 - derived1_function1 exception type changed.
#break34 - Field added to struct with Field ID being in between two existing field IDs

#warning.thrift
#Changing defaults
#Id=1 struct5
#id=2 struct5 
#id=4 struct2(list)
#id=3 struct2(list  default values removed)
#id 4 struct1 change in double value
#id 5 struct1 (default string value removed)
#id=1 struct3 (change in map values)
#id2 struct3 (change in map keys)

#change in inheritance for derived1 and derived2

#change in struct field names
#id9 struct1
#id2 struct2

use strict;
use warnings;
use Getopt::Std;

# globals
my $gArguments = "";                # arguments that will be passed to AuditTool
my $gAuditToolPath = "";
my $gPreviousThriftPath;            # previous thrift path
my $gCurrentThriftPath;             # current thrift path
my $gThriftFileFolder;
my $gBreakingFilesCount =34; 

my $gVerbose = 0;
#functions
sub auditBreakingChanges;
sub auditNonBreakingChanges;

main();

sub main
{
    parseOptions();
    auditBreakingChanges();
    auditNonBreakingChanges();
}

sub parseOptions
{
    my %options = ();
    if ( getopts ('vf:o:t:',\%options) )
    {
        # current (new) thrift folder
        if ($options{'f'})
        {
            $gThriftFileFolder = $options{'f'};
            $gPreviousThriftPath = $gThriftFileFolder."/test.thrift";
        }
        else
        {
            die "Missing Folder containing thrift files\n";
        }

        if($options{'t'})
        {
            $gAuditToolPath = $options{'t'};
        }
        else
        {
            die "Audit Tool Path required \n";
        }

        if ($options{'v'})
        {
            $gVerbose = 1;
        }

    }
}

sub auditBreakingChanges
{
    my $breakingFileBaseName = $gThriftFileFolder."/break";
    my $newThriftFile;
    for(my $i=1; $i <= $gBreakingFilesCount; $i++)
    {
        $newThriftFile = $breakingFileBaseName."$i.thrift";
        my $arguments =  $gPreviousThriftPath." ".$newThriftFile;
        my ($exitCode, $output) = callThriftAuditTool($arguments);
        print $output if $gVerbose eq 1;

        if($exitCode == 1)
        {
            # thrift_audit returns 1 when it is not able to find files or other non-audit failures
            print "exiting with exit code =1 i = ".$i."\n";
            print $output;
            exit $exitCode;
        }
        if($exitCode != 2)
        {
            # thrift-audit return 2 for audit failures. So for Breaking changes we should get 2 as return value.
            print $output;
            die "\nTEST FAILURE: Breaking Change not detected for thrift file $newThriftFile, code=$exitCode \n";
        }
        if(index($output,getMessageSubString("break$i")) == -1)
        {
            #Audit tool detected failure, but not the expected one. The change in breaking thrift file does not match getMessageSubString()
            print $output;
            die "\nTest FAILURE: Audit tool detected failure, but not the expected one!\n";
        }
        else
        {
            #Thrift audit tool has detected audit failure and has returned exited to status code 2
            print "Test Pass: Audit Failure detected for thrift file break$i.thrift \n";
        }
    }

}

sub auditNonBreakingChanges
{
    my $breakingFileBaseName = $gThriftFileFolder."/warning";
    my $newThriftFile;
    $newThriftFile = $breakingFileBaseName.".thrift";
    my $arguments =  $gPreviousThriftPath." ".$newThriftFile;
    my ($exitCode, $output) = callThriftAuditTool($arguments);
    print $output if $gVerbose eq 1;

    if($exitCode == 1)
    {
        # thrift_audit returns 1 when it is not able to find files or other non-audit failures
        print "exiting with exit code = 1  for file warning.thrift\n";
        exit $exitCode;
    }
    elsif($exitCode != 0)
    {
        # thrift-audit return 0 if there are no audit failures.
        die "\nTEST FAILURE: Non Breaking changes returned failure for thrift file $newThriftFile \n";
    }
    else
    {
        #Thrift audit tool has exited with status 0. 
        print "Test Pass: Audit tool exits with success for warnings \n";
    }


}

# -----------------------------------------------------------------------------------------------------
# call thriftAuditTool script
sub callThriftAuditTool ( $ )
{
    my $args = shift;

    my $command = "$gAuditToolPath --audit $args";
    my $output = `$command 2>&1`;
    my $exitCode = $? >> 8;

    return ($exitCode,$output);
}

sub getMessageSubString( $ )
{
    my $fileName = shift;
    my %lookupTable = (
        "break1"  => "base_function3",
        "break2"  => "test_struct1",
        "break3"  => "test_struct1",
        "break4"  => "test_struct1",
        "break5"  => "test_struct1",
        "break6"  => "test_struct2",
        "break7"  => "test_struct6",
        "break8"  => "test_struct5",
        "break9"  => "test_struct1",
        "break10" => "test_struct2",
        "break11" => "test_struct3",
        "break12" => "derived1_function1",
        "break13" => "derived1_function6",
        "break14" => "derived1_function4",
        "break15" => "derived2_function1",
        "break16" => "derived2_function5",
        "break17" => "derived2_function6",
        "break18" => "base_oneway",
        "break19" => "base_function1",
        "break20" => "test_enum1",
        "break21" => "test_enum2",
        "break22" => "test_enum1",
        "break23" => "test_struct4",
        "break24" => "derived1",
        "break25" => "derived2",
        "break26" => "base_function1",
        "break27" => "base_function2_args",
        "break28" => "derived1_function5_args",
        "break29" => "base_function2_args",
        "break30" => "derived1_function6",
        "break31" => "base_function2_exception",
        "break32" => "test_exception1",
        "break33" => "derived1_function1_exception",
        "break34" => "test_struct3",
    );
    if (not exists $lookupTable{ $fileName })
    {
        print "in the null case\n";
        return "NULL";
    }
    
    my $retval = $lookupTable{ $fileName };
    print "$fileName => $retval\n";
    return $lookupTable{ $fileName };
}
thrift-0.23.0/test/audit/break26.thrift0000664000175000017500000001227615165535636020150 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break26 - Field type changed in base_function1 argument id=3
namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: double function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}

thrift-0.23.0/test/audit/break13.thrift0000664000175000017500000001227615165535636020144 0ustar00buildbuild00000000000000/*
 * 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.
 */

// derived1_function6 return type changed from struct1 to struct2

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct2 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break18.thrift0000664000175000017500000001224015165535636020140 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break18- oneway removed from base_oneway

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break25.thrift0000664000175000017500000001224215165535636020140 0ustar00buildbuild00000000000000/*
 * 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.
 */

//Changed inheritance of derived2

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends derived1 {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break27.thrift0000664000175000017500000001231115165535636020137 0ustar00buildbuild00000000000000/*
 * 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.
 */

// break27 - argument changed base_function2 list to list id =8
namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break21.thrift0000664000175000017500000001222515165535636020135 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break21- last enum value removed from enum2

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break20.thrift0000664000175000017500000001223015165535636020130 0ustar00buildbuild00000000000000/*
 * 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.
 */

// break 20 - first enum value removed from enum1

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break7.thrift0000664000175000017500000001223515165535636020062 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break7 - requiredness removed in struct6

namespace cpp test
//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break3.thrift0000664000175000017500000001227315165535636020060 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break3 - Struct field changed in test_struct1(enum1 to enum2)

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum2 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break11.thrift0000664000175000017500000001220515165535636020132 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break11 - Struct field removed from struct3 id =7

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break30.thrift0000664000175000017500000001233515165535636020137 0ustar00buildbuild00000000000000/*
 * 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.
 */

// break30- derived1_function6 argument changed struct1 to map
namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    map derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break10.thrift0000664000175000017500000001221515165535636020132 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break10 - Struct field removed from struct2 id =1

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/README.md0000664000175000017500000000203715165535636016743 0ustar00buildbuild00000000000000Typical usage
=============
```
thrift.exe --audit  
```
Example run
===========
```
> thrift.exe --audit test.thrift break1.thrift
[Thrift Audit Failure:break1.thrift] New Thrift File has missing function base_function3
[Thrift Audit Warning:break1.thrift] Constant const3 has different value
```

Problems that the audit tool can catch
======================================
Errors
* Removing an enum value
* Changing the type of a struct field
* Changing the required-ness of a struct field
* Removing a struct field
* Adding a required struct field
* Adding a struct field 'in the middle'.  This usually indicates an old ID has been recycled
* Struct removed
* Oneway-ness change
* Return type change
* Missing function
* Missing service
* Change in service inheritance

Warnings
* Removing a language namespace declaration
* Changing a namespace
* Changing an enum value's name
* Removing an enum class
* Default value changed
* Struct field name change
* Removed constant
* Type of constant changed
* Value of constant changed
    thrift-0.23.0/test/audit/break6.thrift0000664000175000017500000001227315165535636020063 0ustar00buildbuild00000000000000/*
 * 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.
 */

// Field type changed in test_struct2 (list to list)

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break16.thrift0000664000175000017500000001236115165535636020142 0ustar00buildbuild00000000000000/*
 * 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.
 */

// break 16 - derived2_function5 return type changed from map to map

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break34.thrift0000664000175000017500000001241015165535636020135 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break34 - Field added to struct with Field ID being in between two existing field IDs

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    6: map struct3_member6,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break22.thrift0000664000175000017500000001223315165535636020135 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break22 - in-between enum value removed from enum1

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break33.thrift0000664000175000017500000001226315165535636020142 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break33 - derived1_function1 exception type changed.

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception1 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break12.thrift0000664000175000017500000001227215165535636020137 0ustar00buildbuild00000000000000/*
 * 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.
 */

// derived1_function1 return type changed from enum1 to enum2

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum2 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break31.thrift0000664000175000017500000001221715165535636020137 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break31 - Exception removed to base_function2

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break19.thrift0000664000175000017500000001225615165535636020150 0ustar00buildbuild00000000000000/*
 * 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.
 */

//break19 - oneway added to base_function1

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32 ],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    oneway void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break4.thrift0000664000175000017500000001226015165535636020055 0ustar00buildbuild00000000000000/*
 * 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.
 */

//Field type changed in test_struct1(bool to string)
namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};


//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: string struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 =[23, 32],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break1.thrift0000664000175000017500000001221015165535636020045 0ustar00buildbuild00000000000000/*
 * 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.
 */

//Thrift Method removed from service base.

namespace cpp test

//constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};

//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3= [23, 32],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/audit/break2.thrift0000664000175000017500000001224115165535636020052 0ustar00buildbuild00000000000000/*
 * 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 field changed in test_struct1

namespace cpp test

//Constants
const i32 const1 = 123;
const double const2 = 23.3;
const map const3 = {"hello":"world", "thrift":"audit"};

//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i32 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list struct2_member1,
    2: list struct2_member2,
    3: list struct2_member3 = [23, 32],
    4: list struct2_member4,
    5: list struct2_member5,
    6: list struct2_member6,
    7: list struct2_member7,
    8: list struct2_member8,
    9: list struct2_member9
}

struct test_struct3 {
    1: map struct3_member1 = {1:2, 3:4},
    2: map struct3_member2 = {10:1.1, 20:2.1},
    3: map struct3_member3,
    4: map struct3_member4,
    5: map struct3_member5,
    7: map struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5,
        6: list function2_arg6,
        7: list function2_arg7,
        8: list function2_arg8,
        9: list function2_arg9) throws (1:test_exception2 e),

    void base_function3(),

}

service derived1 extends base {
    
    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list function2_arg1,
        2: list function2_arg2,
        3: list function2_arg3,
        4: list function2_arg4,
        5: list function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map function5_arg1,
        2: map function5_arg2,
        3: map function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),
    
    list derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),
    
}
thrift-0.23.0/test/py/0000775000175000017500000000000015170007175014770 5ustar00buildbuild00000000000000thrift-0.23.0/test/py/generate.cmake0000664000175000017500000000575415167543515017610 0ustar00buildbuild00000000000000macro(GENERATE FILENAME GENERATOR OUTPUTDIR)
  file(MAKE_DIRECTORY ${MY_CURRENT_BINARY_DIR}/${OUTPUTDIR})
  execute_process(COMMAND ${THRIFTCOMPILER} --gen ${GENERATOR} -out ${MY_CURRENT_BINARY_DIR}/${OUTPUTDIR} ${FILENAME}
                  RESULT_VARIABLE CMD_RESULT)
  if(CMD_RESULT)
        message(FATAL_ERROR "Error generating ${FILENAME} with generator ${GENERATOR}")
  endif()
endmacro(GENERATE)

generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py gen-py-default)
generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py:slots gen-py-slots)
generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py:old_style gen-py-oldstyle)
generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py:no_utf8strings gen-py-no_utf8strings)
generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py:dynamic gen-py-dynamic)
generate(${MY_PROJECT_DIR}/test/ThriftTest.thrift py:dynamic,slots gen-py-dynamicslots)
generate(${MY_PROJECT_DIR}/test/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/DebugProtoTest.thrift py gen-py-default)
generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:slots gen-py-slots)
generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:old_style gen-py-oldstyle)
generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:no_utf8strings gen-py-no_utf8strings)
generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:dynamic gen-py-dynamic)
generate(${MY_PROJECT_DIR}/test/DebugProtoTest.thrift py:dynamic,slots gen-py-dynamicslots)
generate(${MY_PROJECT_DIR}/test/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)
generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:old_style gen-py-oldstyle)
generate(${MY_PROJECT_DIR}/test/DoubleConstantsTest.thrift py:no_utf8strings gen-py-no_utf8strings)
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)
generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:old_style gen-py-oldstyle)
generate(${MY_PROJECT_DIR}/test/Recursive.thrift py:no_utf8strings gen-py-no_utf8strings)
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)
thrift-0.23.0/test/py/setup.cfg0000664000175000017500000000003715165535636016625 0ustar00buildbuild00000000000000[flake8]
max-line-length = 100
thrift-0.23.0/test/py/TestClient.py0000775000175000017500000005673115167543515017450 0ustar00buildbuild00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# 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 os
import ssl
import sys
import time
import unittest
import uuid

from optparse import OptionParser
from util import local_libpath
sys.path.insert(0, local_libpath())
from thrift.protocol import TProtocol, TProtocolDecorator

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))


class AbstractTest(unittest.TestCase):
    def setUp(self):
        if options.trans == 'http':
            uri = '{0}://{1}:{2}{3}'.format(('https' if options.ssl else 'http'),
                                            options.host,
                                            options.port,
                                            (options.http_path if options.http_path else '/'))
            if options.ssl:
                __cafile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "server.pem")
                __certfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "client.crt")
                __keyfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "client.key")
                self.transport = THttpClient.THttpClient(uri, cafile=__cafile, cert_file=__certfile, key_file=__keyfile)
            else:
                self.transport = THttpClient.THttpClient(uri)
        else:
            if options.ssl:
                from thrift.transport import TSSLSocket
                keys_dir = os.path.join(os.path.dirname(SCRIPT_DIR), "keys")
                ca_certs = os.path.join(keys_dir, "server.pem")
                certfile = os.path.join(keys_dir, "client.crt")
                keyfile = os.path.join(keys_dir, "client.key")
                ssl_version = getattr(ssl, "PROTOCOL_TLS_CLIENT", ssl.PROTOCOL_TLSv1)
                socket = TSSLSocket.TSSLSocket(
                    options.host,
                    options.port,
                    certfile=certfile,
                    keyfile=keyfile,
                    ca_certs=ca_certs,
                    cert_reqs=ssl.CERT_REQUIRED,
                    ssl_version=ssl_version,
                )
            else:
                socket = TSocket.TSocket(options.host, options.port, options.domain_socket)
            # frame or buffer depending upon args
            self.transport = TTransport.TBufferedTransport(socket)
            if options.trans == 'framed':
                self.transport = TTransport.TFramedTransport(socket)
            elif options.trans == 'buffered':
                self.transport = TTransport.TBufferedTransport(socket)
            elif options.trans == '':
                raise AssertionError('Unknown --transport option: %s' % options.trans)
            if options.zlib:
                self.transport = TZlibTransport.TZlibTransport(self.transport, 9)
        self.transport.open()
        protocol = self.get_protocol(self.transport)
        self.client = ThriftTest.Client(protocol)
        # for multiplexed services:
        protocol2 = self.get_protocol2(self.transport)
        self.client2 = SecondService.Client(protocol2) if protocol2 is not None else None

    def tearDown(self):
        self.transport.close()

    def testVoid(self):
        print('testVoid')
        self.client.testVoid()

    def testString(self):
        print('testString')
        self.assertEqual(self.client.testString('Python' * 20), 'Python' * 20)
        self.assertEqual(self.client.testString(''), '')
        s1 = u'\b\t\n/\\\\\r{}:パイソン"'
        s2 = u"""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ú, 粵語"""
        self.assertEqual(self.client.testString(s1), s1)
        self.assertEqual(self.client.testString(s2), s2)

    def testMultiplexed(self):
        if self.client2 is not None:
            print('testMultiplexed')
            self.assertEqual(self.client2.secondtestString('foobar'), 'testString("foobar")')

    def testBool(self):
        print('testBool')
        self.assertEqual(self.client.testBool(True), True)
        self.assertEqual(self.client.testBool(False), False)

    def testByte(self):
        print('testByte')
        self.assertEqual(self.client.testByte(63), 63)
        self.assertEqual(self.client.testByte(-127), -127)

    def testI32(self):
        print('testI32')
        self.assertEqual(self.client.testI32(-1), -1)
        self.assertEqual(self.client.testI32(0), 0)

    def testI64(self):
        print('testI64')
        self.assertEqual(self.client.testI64(1), 1)
        self.assertEqual(self.client.testI64(-34359738368), -34359738368)

    def testDouble(self):
        print('testDouble')
        self.assertEqual(self.client.testDouble(-5.235098235), -5.235098235)
        self.assertEqual(self.client.testDouble(0), 0)
        self.assertEqual(self.client.testDouble(-1), -1)
        self.assertEqual(self.client.testDouble(-0.000341012439638598279), -0.000341012439638598279)

    def testBinary(self):
        print('testBinary')
        val = bytearray([i for i in range(0, 256)])
        self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)

    def testUuid(self):
        print('testUuid')
        val1 = uuid.UUID('00112233-4455-6677-8899-aabbccddeeff')
        val2 = uuid.uuid4()
        self.assertEqual(self.client.testUuid(val1), val1)
        self.assertEqual(self.client.testUuid(val2), val2)

    def testStruct(self):
        print('testStruct')
        x = Xtruct()
        x.string_thing = "Zero"
        x.byte_thing = 1
        x.i32_thing = -3
        x.i64_thing = -5
        y = self.client.testStruct(x)
        self.assertEqual(y, x)

    def testNest(self):
        print('testNest')
        inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
        x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
        y = self.client.testNest(x)
        self.assertEqual(y, x)

    def testMap(self):
        print('testMap')
        x = {0: 1, 1: 2, 2: 3, 3: 4, -1: -2}
        y = self.client.testMap(x)
        self.assertEqual(y, x)

    def testSet(self):
        print('testSet')
        x = set([8, 1, 42])
        y = self.client.testSet(x)
        self.assertEqual(y, x)

    def testList(self):
        print('testList')
        x = [1, 4, 9, -42]
        y = self.client.testList(x)
        self.assertEqual(y, x)

    def testEnum(self):
        print('testEnum')
        x = Numberz.FIVE
        y = self.client.testEnum(x)
        self.assertEqual(y, x)

    def testTypedef(self):
        print('testTypedef')
        x = 0xffffffffffffff  # 7 bytes of 0xff
        y = self.client.testTypedef(x)
        self.assertEqual(y, x)

    def testMapMap(self):
        print('testMapMap')
        x = {
            -4: {-4: -4, -3: -3, -2: -2, -1: -1},
            4: {4: 4, 3: 3, 2: 2, 1: 1},
        }
        y = self.client.testMapMap(42)
        self.assertEqual(y, x)

    def testMulti(self):
        print('testMulti')
        xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0)
        y = self.client.testMulti(xpected.byte_thing,
                                  xpected.i32_thing,
                                  xpected.i64_thing,
                                  {0: 'abc'},
                                  Numberz.FIVE,
                                  0xf0f0f0)
        self.assertEqual(y, xpected)

    def testException(self):
        print('testException')
        self.client.testException('Safe')
        try:
            self.client.testException('Xception')
            self.fail("should have gotten exception")
        except Xception as x:
            self.assertEqual(x.errorCode, 1001)
            self.assertEqual(x.message, 'Xception')
            # TODO ensure same behavior for repr within generated python variants
            # ensure exception's repr method works
            # x_repr = repr(x)
            # self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')')

        try:
            self.client.testException('TException')
            self.fail("should have gotten exception")
        except TException:
            pass

        # Should not throw
        self.client.testException('success')

    def testMultiException(self):
        print('testMultiException')
        try:
            self.client.testMultiException('Xception', 'ignore')
        except Xception as ex:
            self.assertEqual(ex.errorCode, 1001)
            self.assertEqual(ex.message, 'This is an Xception')

        try:
            self.client.testMultiException('Xception2', 'ignore')
        except Xception2 as ex:
            self.assertEqual(ex.errorCode, 2002)
            self.assertEqual(ex.struct_thing.string_thing, 'This is an Xception2')

        y = self.client.testMultiException('success', 'foobar')
        self.assertEqual(y.string_thing, 'foobar')

    def testException__traceback__(self):
        print('testException__traceback__')
        self.client.testException('Safe')
        expect_slots = uses_slots = False
        expect_dynamic = uses_dynamic = False
        try:
            self.client.testException('Xception')
            self.fail("should have gotten exception")
        except Xception as x:
            uses_slots = hasattr(x, '__slots__')
            uses_dynamic = (not isinstance(x, TException))
            # We set expected values here so that we get clean tracebackes when
            # the assertions fail.
            try:
                x.__traceback__ = x.__traceback__
                # If `__traceback__` was set without errors than we expect that
                # the slots option was used and that dynamic classes were not.
                expect_slots = True
                expect_dynamic = False
            except Exception as e:
                self.assertTrue(isinstance(e, TypeError))
                # There are no other meaningful tests we can preform because we
                # are unable to determine the desired state of either `__slots__`
                # or `dynamic`.
                return

        self.assertEqual(expect_slots, uses_slots)
        self.assertEqual(expect_dynamic, uses_dynamic)

    def testOneway(self):
        print('testOneway')
        start = time.time()
        self.client.testOneway(1)  # type is int, not float
        end = time.time()
        self.assertTrue(end - start < 3,
                        "oneway sleep took %f sec" % (end - start))

    def testOnewayThenNormal(self):
        print('testOnewayThenNormal')
        self.client.testOneway(1)  # type is int, not float
        self.assertEqual(self.client.testString('Python'), 'Python')


# LAST_SEQID is a global because we have one transport and multiple protocols
# running on it (when multiplexed)
LAST_SEQID = None


class TPedanticSequenceIdProtocolWrapper(TProtocolDecorator.TProtocolDecorator):
    """
    Wraps any protocol with sequence ID checking: looks for outbound
    uniqueness as well as request/response alignment.
    """

    def __init__(self, protocol):
        # TProtocolDecorator.__new__ does all the heavy lifting
        pass

    def writeMessageBegin(self, name, type, seqid):
        global LAST_SEQID
        if LAST_SEQID and LAST_SEQID == seqid:
            raise TProtocol.TProtocolException(
                TProtocol.TProtocolException.INVALID_DATA,
                "Python client reused sequence ID {0}".format(seqid))
        LAST_SEQID = seqid
        super(TPedanticSequenceIdProtocolWrapper, self).writeMessageBegin(
            name, type, seqid)

    def readMessageBegin(self):
        (name, type, seqid) =\
            super(TPedanticSequenceIdProtocolWrapper, self).readMessageBegin()
        if LAST_SEQID != seqid:
            raise TProtocol.TProtocolException(
                TProtocol.TProtocolException.INVALID_DATA,
                "We sent seqid {0} and server returned seqid {1}".format(
                    self.last, seqid))
        return (name, type, seqid)


def make_pedantic(proto):
    """ Wrap a protocol in the pedantic sequence ID wrapper. """
    return TPedanticSequenceIdProtocolWrapper(proto)


class MultiplexedOptionalTest(AbstractTest):
    def get_protocol2(self, transport):
        return None


class BinaryTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        return make_pedantic(TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport))


class MultiplexedBinaryTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")

    def get_protocol2(self, transport):
        wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")


class AcceleratedBinaryTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        return make_pedantic(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport))


class MultiplexedAcceleratedBinaryTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")

    def get_protocol2(self, transport):
        wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")


class CompactTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        return make_pedantic(TCompactProtocol.TCompactProtocolFactory().getProtocol(transport))


class MultiplexedCompactTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")

    def get_protocol2(self, transport):
        wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")


class AcceleratedCompactTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        return make_pedantic(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport))


class MultiplexedAcceleratedCompactTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")

    def get_protocol2(self, transport):
        wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")


class JSONTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        return make_pedantic(TJSONProtocol.TJSONProtocolFactory().getProtocol(transport))


class MultiplexedJSONTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        wrapped_proto = make_pedantic(TJSONProtocol.TJSONProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")

    def get_protocol2(self, transport):
        wrapped_proto = make_pedantic(TJSONProtocol.TJSONProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")


class HeaderTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        factory = THeaderProtocol.THeaderProtocolFactory()
        return make_pedantic(factory.getProtocol(transport))


class MultiplexedHeaderTest(MultiplexedOptionalTest):
    def get_protocol(self, transport):
        wrapped_proto = make_pedantic(THeaderProtocol.THeaderProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")

    def get_protocol2(self, transport):
        wrapped_proto = make_pedantic(THeaderProtocol.THeaderProtocolFactory().getProtocol(transport))
        return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")


def suite():
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    if options.proto == 'binary':  # look for --proto on cmdline
        suite.addTest(loader.loadTestsFromTestCase(BinaryTest))
    elif options.proto == 'accel':
        suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
    elif options.proto == 'accelc':
        suite.addTest(loader.loadTestsFromTestCase(AcceleratedCompactTest))
    elif options.proto == 'compact':
        suite.addTest(loader.loadTestsFromTestCase(CompactTest))
    elif options.proto == 'header':
        suite.addTest(loader.loadTestsFromTestCase(HeaderTest))
    elif options.proto == 'json':
        suite.addTest(loader.loadTestsFromTestCase(JSONTest))
    elif options.proto == 'multi':
        suite.addTest(loader.loadTestsFromTestCase(MultiplexedBinaryTest))
    elif options.proto == 'multia':
        suite.addTest(loader.loadTestsFromTestCase(MultiplexedAcceleratedBinaryTest))
    elif options.proto == 'multiac':
        suite.addTest(loader.loadTestsFromTestCase(MultiplexedAcceleratedCompactTest))
    elif options.proto == 'multic':
        suite.addTest(loader.loadTestsFromTestCase(MultiplexedCompactTest))
    elif options.proto == 'multih':
        suite.addTest(loader.loadTestsFromTestCase(MultiplexedHeaderTest))
    elif options.proto == 'multij':
        suite.addTest(loader.loadTestsFromTestCase(MultiplexedJSONTest))
    else:
        raise AssertionError('Unknown protocol given with --protocol: %s' % options.proto)
    return suite


class OwnArgsTestProgram(unittest.TestProgram):
    def parseArgs(self, argv):
        if args:
            self.testNames = args
        else:
            self.testNames = ([self.defaultTest])
        self.createTests()


if __name__ == "__main__":
    parser = OptionParser()
    parser.add_option('--libpydir', type='string', dest='libpydir',
                      help='include this directory in sys.path for locating library code')
    parser.add_option('--genpydir', type='string', dest='genpydir',
                      help='include this directory in sys.path for locating generated code')
    parser.add_option("--port", type="int", dest="port",
                      help="connect to server at port")
    parser.add_option("--host", type="string", dest="host",
                      help="connect to server")
    parser.add_option("--zlib", action="store_true", dest="zlib",
                      help="use zlib wrapper for compressed transport")
    parser.add_option("--ssl", action="store_true", dest="ssl",
                      help="use SSL for encrypted transport")
    parser.add_option("--http", dest="http_path",
                      help="Use the HTTP transport with the specified path")
    parser.add_option('-v', '--verbose', action="store_const",
                      dest="verbose", const=2,
                      help="verbose output")
    parser.add_option('-q', '--quiet', action="store_const",
                      dest="verbose", const=0,
                      help="minimal output")
    parser.add_option('--protocol', dest="proto", type="string",
                      help="protocol to use, one of: accel, accelc, binary, compact, header, json, multi, multia, multiac, multic, multih, multij")
    parser.add_option('--transport', dest="trans", type="string",
                      help="transport to use, one of: buffered, framed, http")
    parser.add_option('--domain-socket', dest="domain_socket", type="string",
                      help="Unix domain socket path")
    parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary')
    options, args = parser.parse_args()

    if options.genpydir:
        sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir))

    if options.http_path:
        options.trans = 'http'

    from ThriftTest import SecondService
    from ThriftTest import ThriftTest
    from ThriftTest.ttypes import Xtruct, Xtruct2, Numberz, Xception, Xception2
    from thrift.Thrift import TException
    from thrift.transport import TTransport
    from thrift.transport import TSocket
    from thrift.transport import THttpClient
    from thrift.transport import TZlibTransport
    from thrift.protocol import TBinaryProtocol
    from thrift.protocol import TCompactProtocol
    from thrift.protocol import THeaderProtocol
    from thrift.protocol import TJSONProtocol
    from thrift.protocol import TMultiplexedProtocol

    OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1))
thrift-0.23.0/test/py/TestTypes.py0000664000175000017500000000525315167543515017324 0ustar00buildbuild00000000000000#!/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
from uuid import UUID

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]})

    def test_uuid(self):
        self.assertEqual(Client.testUuid.__annotations__, {'return': UUID, 'thing': UUID})
thrift-0.23.0/test/py/TSimpleJSONProtocolTest.py0000664000175000017500000000755715165535636022025 0ustar00buildbuild00000000000000#!/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.ttypes import Bonk, VersioningTestV1, VersioningTestV2
from thrift.protocol import TJSONProtocol
from thrift.transport import TTransport

import json
import unittest


class SimpleJSONProtocolTest(unittest.TestCase):
    protocol_factory = TJSONProtocol.TSimpleJSONProtocolFactory()

    def _assertDictEqual(self, a, b, msg=None):
        if hasattr(self, 'assertDictEqual'):
            # assertDictEqual only in Python 2.7. Depends on your machine.
            self.assertDictEqual(a, b, msg)
            return

        # Substitute implementation not as good as unittest library's
        self.assertEquals(len(a), len(b), msg)
        for k, v in a.iteritems():
            self.assertTrue(k in b, msg)
            self.assertEquals(b.get(k), v, msg)

    def _serialize(self, obj):
        trans = TTransport.TMemoryBuffer()
        prot = self.protocol_factory.getProtocol(trans)
        obj.write(prot)
        return trans.getvalue()

    def _deserialize(self, objtype, data):
        prot = self.protocol_factory.getProtocol(TTransport.TMemoryBuffer(data))
        ret = objtype()
        ret.read(prot)
        return ret

    def testWriteOnly(self):
        self.assertRaises(NotImplementedError,
                          self._deserialize, VersioningTestV1, b'{}')

    def testSimpleMessage(self):
        v1obj = VersioningTestV1(
            begin_in_both=12345,
            old_string='aaa',
            end_in_both=54321)
        expected = dict(begin_in_both=v1obj.begin_in_both,
                        old_string=v1obj.old_string,
                        end_in_both=v1obj.end_in_both)
        actual = json.loads(self._serialize(v1obj).decode('ascii'))

        self._assertDictEqual(expected, actual)

    def testComplicated(self):
        v2obj = VersioningTestV2(
            begin_in_both=12345,
            newint=1,
            newbyte=2,
            newshort=3,
            newlong=4,
            newdouble=5.0,
            newstruct=Bonk(message="Hello!", type=123),
            newlist=[7, 8, 9],
            newset=set([42, 1, 8]),
            newmap={1: 2, 2: 3},
            newstring="Hola!",
            end_in_both=54321)
        expected = dict(begin_in_both=v2obj.begin_in_both,
                        newint=v2obj.newint,
                        newbyte=v2obj.newbyte,
                        newshort=v2obj.newshort,
                        newlong=v2obj.newlong,
                        newdouble=v2obj.newdouble,
                        newstruct=dict(message=v2obj.newstruct.message,
                                       type=v2obj.newstruct.type),
                        newlist=v2obj.newlist,
                        newset=list(v2obj.newset),
                        newmap=v2obj.newmap,
                        newstring=v2obj.newstring,
                        end_in_both=v2obj.end_in_both)

        # Need to load/dump because map keys get escaped.
        expected = json.loads(json.dumps(expected))
        actual = json.loads(self._serialize(v2obj).decode('ascii'))
        self._assertDictEqual(expected, actual)


if __name__ == '__main__':
    unittest.main()
thrift-0.23.0/test/py/FastbinaryTest.py0000664000175000017500000001635115167543515020323 0ustar00buildbuild00000000000000#!/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.
#

r"""
PYTHONPATH=./gen-py:../../lib/py/build/lib... ./FastbinaryTest.py
"""

# TODO(dreiss): Test error cases.  Check for memory leaks.

import math
import timeit

from copy import deepcopy
from pprint import pprint

from thrift.transport import TTransport
from thrift.protocol.TBinaryProtocol import TBinaryProtocol, TBinaryProtocolAccelerated
from thrift.protocol.TCompactProtocol import TCompactProtocol, TCompactProtocolAccelerated

from DebugProtoTest import Srv
from DebugProtoTest.ttypes import Backwards, Bonk, Empty, HolyMoley, OneOfEach, RandomStuff, Wrapper


class TDevNullTransport(TTransport.TTransportBase):
    def __init__(self):
        pass

    def isOpen(self):
        return True


ooe1 = OneOfEach()
ooe1.im_true = True
ooe1.im_false = False
ooe1.a_bite = 0xd6
ooe1.integer16 = 27000
ooe1.integer32 = 1 << 24
ooe1.integer64 = 6000 * 1000 * 1000
ooe1.double_precision = math.pi
ooe1.some_characters = "Debug THIS!"
ooe1.zomg_unicode = u"\xd7\n\a\t"

ooe2 = OneOfEach()
ooe2.integer16 = 16
ooe2.integer32 = 32
ooe2.integer64 = 64
ooe2.double_precision = (math.sqrt(5) + 1) / 2
ooe2.some_characters = ":R (me going \"rrrr\")"
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)
hm.big.append(ooe2)
hm.big[0].a_bite = 0x22
hm.big[1].a_bite = 0x22

hm.contain.add(("and a one", "and a two"))
hm.contain.add(("then a one, two", "three!", "FOUR!"))
hm.contain.add(("\xd7\n\a\t",))
hm.contain.add(())

hm.bonks["nothing"] = []
hm.bonks["something"] = [
    Bonk(**{"type": 1, "message": "Wait."}),
    Bonk(**{"type": 2, "message": "What?"}),
]
hm.bonks["poe"] = [
    Bonk(**{"type": 3, "message": "quoth"}),
    Bonk(**{"type": 4, "message": "the raven"}),
    Bonk(**{"type": 5, "message": "nevermore"}),
]

rs = RandomStuff()
rs.a = 1
rs.b = 2
rs.c = 3
rs.myintlist = list(range(20))
rs.maps = {1: Wrapper(**{"foo": Empty()}), 2: Wrapper(**{"foo": Empty()})}
rs.bigint = 124523452435
rs.triple = 3.14

# make sure this splits two buffers in a buffered protocol
rshuge = RandomStuff()
rshuge.myintlist = list(range(10000))

my_zero = Srv.Janky_result(**{"success": 5})


class Test(object):
    def __init__(self, fast, slow):
        self._fast = fast
        self._slow = slow

    def _check_write(self, o):
        trans_fast = TTransport.TMemoryBuffer()
        trans_slow = TTransport.TMemoryBuffer()
        prot_fast = self._fast(trans_fast, fallback=False)
        prot_slow = self._slow(trans_slow)

        o.write(prot_fast)
        o.write(prot_slow)
        ORIG = trans_slow.getvalue()
        MINE = trans_fast.getvalue()
        if ORIG != MINE:
            print("actual  : %s\nexpected: %s" % (repr(MINE), repr(ORIG)))
            raise Exception('write value mismatch')

    def _check_read(self, o):
        prot = self._slow(TTransport.TMemoryBuffer())
        o.write(prot)

        slow_version_binary = prot.trans.getvalue()

        prot = self._fast(
            TTransport.TMemoryBuffer(slow_version_binary), fallback=False)
        c = o.__class__()
        c.read(prot)
        if c != o:
            print("actual  : ")
            pprint(repr(c))
            print("expected: ")
            pprint(repr(o))
            raise Exception('read value mismatch')

        prot = self._fast(
            TTransport.TBufferedTransport(
                TTransport.TMemoryBuffer(slow_version_binary)), fallback=False)
        c = o.__class__()
        c.read(prot)
        if c != o:
            print("actual  : ")
            pprint(repr(c))
            print("expected: ")
            pprint(repr(o))
            raise Exception('read value mismatch')

    def do_test(self):
        self._check_write(HolyMoley())
        self._check_read(HolyMoley())

        self._check_write(hm)
        no_set = deepcopy(hm)
        no_set.contain = set()
        self._check_read(no_set)
        self._check_read(hm)

        self._check_write(rs)
        self._check_read(rs)

        self._check_write(rshuge)
        self._check_read(rshuge)

        self._check_write(my_zero)
        self._check_read(my_zero)

        self._check_read(Backwards(**{"first_tag2": 4, "second_tag1": 2}))

        # One case where the serialized form changes, but only superficially.
        o = Backwards(**{"first_tag2": 4, "second_tag1": 2})
        trans_fast = TTransport.TMemoryBuffer()
        trans_slow = TTransport.TMemoryBuffer()
        prot_fast = self._fast(trans_fast, fallback=False)
        prot_slow = self._slow(trans_slow)

        o.write(prot_fast)
        o.write(prot_slow)
        ORIG = trans_slow.getvalue()
        MINE = trans_fast.getvalue()
        assert id(ORIG) != id(MINE)

        prot = self._fast(TTransport.TMemoryBuffer(), fallback=False)
        o.write(prot)
        prot = self._slow(
            TTransport.TMemoryBuffer(prot.trans.getvalue()))
        c = o.__class__()
        c.read(prot)
        if c != o:
            print("copy: ")
            pprint(repr(c))
            print("orig: ")
            pprint(repr(o))


def do_test(fast, slow):
    Test(fast, slow).do_test()


def do_benchmark(protocol, iters=5000, skip_slow=False):
    setup = """
from __main__ import hm, rs, TDevNullTransport
from thrift.protocol.{0} import {0}{1}
trans = TDevNullTransport()
prot = {0}{1}(trans{2})
"""

    setup_fast = setup.format(protocol, 'Accelerated', ', fallback=False')
    if not skip_slow:
        setup_slow = setup.format(protocol, '', '')

    print("Starting Benchmarks")

    if not skip_slow:
        print("HolyMoley Standard = %f" %
              timeit.Timer('hm.write(prot)', setup_slow).timeit(number=iters))

    print("HolyMoley Acceler. = %f" %
          timeit.Timer('hm.write(prot)', setup_fast).timeit(number=iters))

    if not skip_slow:
        print("FastStruct Standard = %f" %
              timeit.Timer('rs.write(prot)', setup_slow).timeit(number=iters))

    print("FastStruct Acceler. = %f" %
          timeit.Timer('rs.write(prot)', setup_fast).timeit(number=iters))


if __name__ == '__main__':
    print('Testing TBinaryAccelerated')
    do_test(TBinaryProtocolAccelerated, TBinaryProtocol)
    do_benchmark('TBinaryProtocol')
    print('Testing TCompactAccelerated')
    do_test(TCompactProtocolAccelerated, TCompactProtocol)
    do_benchmark('TCompactProtocol')
thrift-0.23.0/test/py/SerializationTest.py0000664000175000017500000004207615167543515021041 0ustar00buildbuild00000000000000#!/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.ttypes import (
    Bonk,
    Bools,
    LargeDeltas,
    ListBonks,
    NestedListsBonk,
    NestedListsI32x2,
    NestedListsI32x3,
    NestedMixedx2,
    Numberz,
    VersioningTestV1,
    VersioningTestV2,
    Xtruct,
    Xtruct2,
)

from Recursive.ttypes import RecTree
from Recursive.ttypes import RecList
from Recursive.ttypes import CoRec
from Recursive.ttypes import CoRec2
from Recursive.ttypes import VectorTest
from DebugProtoTest.ttypes import CompactProtoTestStruct, Empty
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol, TCompactProtocol, TJSONProtocol
from thrift.TSerialization import serialize, deserialize
import unittest


class AbstractTest(unittest.TestCase):

    def setUp(self):
        self.v1obj = VersioningTestV1(
            begin_in_both=12345,
            old_string='aaa',
            end_in_both=54321,
        )

        self.v2obj = VersioningTestV2(
            begin_in_both=12345,
            newint=1,
            newbyte=2,
            newshort=3,
            newlong=4,
            newdouble=5.0,
            newstruct=Bonk(message="Hello!", type=123),
            newlist=[7, 8, 9],
            newset=set([42, 1, 8]),
            newmap={1: 2, 2: 3},
            newstring="Hola!",
            end_in_both=54321,
        )

        self.bools = Bools(im_true=True, im_false=False)
        self.bools_flipped = Bools(im_true=False, im_false=True)

        self.large_deltas = LargeDeltas(
            b1=self.bools,
            b10=self.bools_flipped,
            b100=self.bools,
            check_true=True,
            b1000=self.bools_flipped,
            check_false=False,
            vertwo2000=VersioningTestV2(newstruct=Bonk(message='World!', type=314)),
            a_set2500=set(['lazy', 'brown', 'cow']),
            vertwo3000=VersioningTestV2(newset=set([2, 3, 5, 7, 11])),
            big_numbers=[2 ** 8, 2 ** 16, 2 ** 31 - 1, -(2 ** 31 - 1)]
        )

        self.compact_struct = CompactProtoTestStruct(
            a_byte=127,
            a_i16=32000,
            a_i32=1000000000,
            a_i64=0xffffffffff,
            a_double=5.6789,
            a_string="my string",
            true_field=True,
            false_field=False,
            empty_struct_field=Empty(),
            byte_list=[-127, -1, 0, 1, 127],
            i16_list=[-1, 0, 1, 0x7fff],
            i32_list=[-1, 0, 0xff, 0xffff, 0xffffff, 0x7fffffff],
            i64_list=[-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff],
            double_list=[0.1, 0.2, 0.3],
            string_list=["first", "second", "third"],
            boolean_list=[True, True, True, False, False, False],
            struct_list=[Empty(), Empty()],
            byte_set=set([-127, -1, 0, 1, 127]),
            i16_set=set([-1, 0, 1, 0x7fff]),
            i32_set=set([1, 2, 3]),
            i64_set=set([-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff]),
            double_set=set([0.1, 0.2, 0.3]),
            string_set=set(["first", "second", "third"]),
            boolean_set=set([True, False]),
            # struct_set=set([Empty()]), # unhashable instance
            byte_byte_map={1: 2},
            i16_byte_map={1: 1, -1: 1, 0x7fff: 1},
            i32_byte_map={1: 1, -1: 1, 0x7fffffff: 1},
            i64_byte_map={0: 1, 1: 1, -1: 1, 0x7fffffffffffffff: 1},
            double_byte_map={-1.1: 1, 1.1: 1},
            string_byte_map={"first": 1, "second": 2, "third": 3, "": 0},
            boolean_byte_map={True: 1, False: 0},
            byte_i16_map={1: 1, 2: -1, 3: 0x7fff},
            byte_i32_map={1: 1, 2: -1, 3: 0x7fffffff},
            byte_i64_map={1: 1, 2: -1, 3: 0x7fffffffffffffff},
            byte_double_map={1: 0.1, 2: -0.1, 3: 1000000.1},
            byte_string_map={1: "", 2: "blah", 3: "loooooooooooooong string"},
            byte_boolean_map={1: True, 2: False},
            # list_byte_map # unhashable
            # set_byte_map={set([1, 2, 3]) : 1, set([0, 1]) : 2, set([]) : 0}, # unhashable
            # map_byte_map # unhashable
            byte_map_map={0: {}, 1: {1: 1}, 2: {1: 1, 2: 2}},
            byte_set_map={0: set([]), 1: set([1]), 2: set([1, 2])},
            byte_list_map={0: [], 1: [1], 2: [1, 2]},
        )

        self.nested_lists_i32x2 = NestedListsI32x2(
            [
                [1, 1, 2],
                [2, 7, 9],
                [3, 5, 8]
            ]
        )

        self.nested_lists_i32x3 = NestedListsI32x3(
            [
                [
                    [2, 7, 9],
                    [3, 5, 8]
                ],
                [
                    [1, 1, 2],
                    [1, 4, 9]
                ]
            ]
        )

        self.nested_mixedx2 = NestedMixedx2(int_set_list=[
            set([1, 2, 3]),
            set([1, 4, 9]),
            set([1, 2, 3, 5, 8, 13, 21]),
            set([-1, 0, 1])
        ],
            # note, the sets below are sets of chars, since the strings are iterated
            map_int_strset={10: set('abc'), 20: set('def'), 30: set('GHI')},
            map_int_strset_list=[
                {10: set('abc'), 20: set('def'), 30: set('GHI')},
                {100: set('lmn'), 200: set('opq'), 300: set('RST')},
                {1000: set('uvw'), 2000: set('wxy'), 3000: set('XYZ')}]
        )

        self.nested_lists_bonk = NestedListsBonk(
            [
                [
                    [
                        Bonk(message='inner A first', type=1),
                        Bonk(message='inner A second', type=1)
                    ],
                    [
                        Bonk(message='inner B first', type=2),
                        Bonk(message='inner B second', type=2)
                    ]
                ]
            ]
        )

        self.list_bonks = ListBonks(
            [
                Bonk(message='inner A', type=1),
                Bonk(message='inner B', type=2),
                Bonk(message='inner C', type=0)
            ]
        )

    def _serialize(self, obj):
        trans = TTransport.TMemoryBuffer()
        prot = self.protocol_factory.getProtocol(trans)
        obj.write(prot)
        return trans.getvalue()

    def _deserialize(self, objtype, data):
        prot = self.protocol_factory.getProtocol(TTransport.TMemoryBuffer(data))
        ret = objtype()
        ret.read(prot)
        return ret

    def testForwards(self):
        obj = self._deserialize(VersioningTestV2, self._serialize(self.v1obj))
        self.assertEqual(obj.begin_in_both, self.v1obj.begin_in_both)
        self.assertEqual(obj.end_in_both, self.v1obj.end_in_both)

    def testBackwards(self):
        obj = self._deserialize(VersioningTestV1, self._serialize(self.v2obj))
        self.assertEqual(obj.begin_in_both, self.v2obj.begin_in_both)
        self.assertEqual(obj.end_in_both, self.v2obj.end_in_both)

    def testSerializeV1(self):
        obj = self._deserialize(VersioningTestV1, self._serialize(self.v1obj))
        self.assertEqual(obj, self.v1obj)

    def testSerializeV2(self):
        obj = self._deserialize(VersioningTestV2, self._serialize(self.v2obj))
        self.assertEqual(obj, self.v2obj)

    def testBools(self):
        self.assertNotEqual(self.bools, self.bools_flipped)
        self.assertNotEqual(self.bools, self.v1obj)
        obj = self._deserialize(Bools, self._serialize(self.bools))
        self.assertEqual(obj, self.bools)
        obj = self._deserialize(Bools, self._serialize(self.bools_flipped))
        self.assertEqual(obj, self.bools_flipped)
        rep = repr(self.bools)
        self.assertTrue(len(rep) > 0)

    def testLargeDeltas(self):
        # test large field deltas (meaningful in CompactProto only)
        obj = self._deserialize(LargeDeltas, self._serialize(self.large_deltas))
        self.assertEqual(obj, self.large_deltas)
        rep = repr(self.large_deltas)
        self.assertTrue(len(rep) > 0)

    def testNestedListsI32x2(self):
        obj = self._deserialize(NestedListsI32x2, self._serialize(self.nested_lists_i32x2))
        self.assertEqual(obj, self.nested_lists_i32x2)
        rep = repr(self.nested_lists_i32x2)
        self.assertTrue(len(rep) > 0)

    def testNestedListsI32x3(self):
        obj = self._deserialize(NestedListsI32x3, self._serialize(self.nested_lists_i32x3))
        self.assertEqual(obj, self.nested_lists_i32x3)
        rep = repr(self.nested_lists_i32x3)
        self.assertTrue(len(rep) > 0)

    def testNestedMixedx2(self):
        obj = self._deserialize(NestedMixedx2, self._serialize(self.nested_mixedx2))
        self.assertEqual(obj, self.nested_mixedx2)
        rep = repr(self.nested_mixedx2)
        self.assertTrue(len(rep) > 0)

    def testNestedListsBonk(self):
        obj = self._deserialize(NestedListsBonk, self._serialize(self.nested_lists_bonk))
        self.assertEqual(obj, self.nested_lists_bonk)
        rep = repr(self.nested_lists_bonk)
        self.assertTrue(len(rep) > 0)

    def testListBonks(self):
        obj = self._deserialize(ListBonks, self._serialize(self.list_bonks))
        self.assertEqual(obj, self.list_bonks)
        rep = repr(self.list_bonks)
        self.assertTrue(len(rep) > 0)

    def testCompactStruct(self):
        # test large field deltas (meaningful in CompactProto only)
        obj = self._deserialize(CompactProtoTestStruct, self._serialize(self.compact_struct))
        self.assertEqual(obj, self.compact_struct)
        rep = repr(self.compact_struct)
        self.assertTrue(len(rep) > 0)

    def testIntegerLimits(self):
        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),
                      CompactProtoTestStruct(a_i64=9223372036854775808), CompactProtoTestStruct(a_i64=-9223372036854775809)
                      ]

        for value in bad_values:
            self.assertRaises(Exception, self._serialize, value)

    def testRecTree(self):
        """Ensure recursive tree node can be created."""
        children = []
        for idx in range(1, 5):
            node = RecTree(item=idx, children=None)
            children.append(node)

        parent = RecTree(item=0, children=children)
        serde_parent = self._deserialize(RecTree, self._serialize(parent))
        self.assertEqual(0, serde_parent.item)
        self.assertEqual(4, len(serde_parent.children))
        for child in serde_parent.children:
            # Cannot use assertIsInstance in python 2.6?
            self.assertTrue(isinstance(child, RecTree))

    def _buildLinkedList(self):
        head = cur = RecList(item=0)
        for idx in range(1, 5):
            node = RecList(item=idx)
            cur.nextitem = node
            cur = node
        return head

    def _collapseLinkedList(self, head):
        out_list = []
        cur = head
        while cur is not None:
            out_list.append(cur.item)
            cur = cur.nextitem
        return out_list

    def testRecList(self):
        """Ensure recursive linked list can be created."""
        rec_list = self._buildLinkedList()
        serde_list = self._deserialize(RecList, self._serialize(rec_list))
        out_list = self._collapseLinkedList(serde_list)
        self.assertEqual([0, 1, 2, 3, 4], out_list)

    def testCoRec(self):
        """Ensure co-recursive structures can be created."""
        item1 = CoRec()
        item2 = CoRec2()

        item1.other = item2
        item2.other = item1

        # NOTE [econner724,2017-06-21]: These objects cannot be serialized as serialization
        # results in an infinite loop. fbthrift also suffers from this
        # problem.

    def testRecVector(self):
        """Ensure a list of recursive nodes can be created."""
        mylist = [self._buildLinkedList(), self._buildLinkedList()]
        myvec = VectorTest(lister=mylist)

        serde_vec = self._deserialize(VectorTest, self._serialize(myvec))
        golden_list = [0, 1, 2, 3, 4]
        for cur_list in serde_vec.lister:
            out_list = self._collapseLinkedList(cur_list)
            self.assertEqual(golden_list, out_list)


class NormalBinaryTest(AbstractTest):
    protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()


class AcceleratedBinaryTest(AbstractTest):
    protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False)


class CompactProtocolTest(AbstractTest):
    protocol_factory = TCompactProtocol.TCompactProtocolFactory()


class AcceleratedCompactTest(AbstractTest):
    protocol_factory = TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False)


class JSONProtocolTest(AbstractTest):
    protocol_factory = TJSONProtocol.TJSONProtocolFactory()


class AcceleratedFramedTest(unittest.TestCase):
    def testSplit(self):
        """Test FramedTransport and BinaryProtocolAccelerated

        Tests that TBinaryProtocolAccelerated and TFramedTransport
        play nicely together when a read spans a frame"""

        protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
        bigstring = "".join(chr(byte) for byte in range(ord("a"), ord("z") + 1))

        databuf = TTransport.TMemoryBuffer()
        prot = protocol_factory.getProtocol(databuf)
        prot.writeI32(42)
        prot.writeString(bigstring)
        prot.writeI16(24)
        data = databuf.getvalue()
        cutpoint = len(data) // 2
        parts = [data[:cutpoint], data[cutpoint:]]

        framed_buffer = TTransport.TMemoryBuffer()
        framed_writer = TTransport.TFramedTransport(framed_buffer)
        for part in parts:
            framed_writer.write(part)
            framed_writer.flush()
        self.assertEqual(len(framed_buffer.getvalue()), len(data) + 8)

        # Recreate framed_buffer so we can read from it.
        framed_buffer = TTransport.TMemoryBuffer(framed_buffer.getvalue())
        framed_reader = TTransport.TFramedTransport(framed_buffer)
        prot = protocol_factory.getProtocol(framed_reader)
        self.assertEqual(prot.readI32(), 42)
        self.assertEqual(prot.readString(), bigstring)
        self.assertEqual(prot.readI16(), 24)


class SerializersTest(unittest.TestCase):

    def testSerializeThenDeserialize(self):
        obj = Xtruct2(i32_thing=1,
                      struct_thing=Xtruct(string_thing="foo"))

        s1 = serialize(obj)
        for i in range(10):
            self.assertEqual(s1, serialize(obj))
            objcopy = Xtruct2()
            deserialize(objcopy, serialize(obj))
            self.assertEqual(obj, objcopy)

        obj = Xtruct(string_thing="bar")
        objcopy = Xtruct()
        deserialize(objcopy, serialize(obj))
        self.assertEqual(obj, objcopy)

        # test booleans
        obj = Bools(im_true=True, im_false=False)
        objcopy = Bools()
        deserialize(objcopy, serialize(obj))
        self.assertEqual(obj, objcopy)

        # test enums
        def _enumerate_enum(enum_class):
            if hasattr(enum_class, '_VALUES_TO_NAMES'):
                # old-style enums
                for num, name in enum_class._VALUES_TO_NAMES.items():
                    yield (num, name)
            else:
                # assume Python 3.4+ IntEnum-based
                from enum import IntEnum
                self.assertTrue((issubclass(enum_class, IntEnum)))
                for num in enum_class:
                    yield (num.value, num.name)

        for num, name in _enumerate_enum(Numberz):
            obj = Bonk(message='enum Numberz value %d is string %s' % (num, name), type=num)
            objcopy = Bonk()
            deserialize(objcopy, serialize(obj))
            self.assertEqual(obj, objcopy)


def suite():
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()

    suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
    suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
    suite.addTest(loader.loadTestsFromTestCase(AcceleratedCompactTest))
    suite.addTest(loader.loadTestsFromTestCase(CompactProtocolTest))
    suite.addTest(loader.loadTestsFromTestCase(JSONProtocolTest))
    suite.addTest(loader.loadTestsFromTestCase(AcceleratedFramedTest))
    suite.addTest(loader.loadTestsFromTestCase(SerializersTest))
    return suite


if __name__ == "__main__":
    unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
thrift-0.23.0/test/py/util.py0000664000175000017500000000244515167543515016335 0ustar00buildbuild00000000000000#
# 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 glob
import os
import sys

_SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
_ROOT_DIR = os.path.dirname(os.path.dirname(_SCRIPT_DIR))


def local_libpath():
    # Handle MM.mm and MMmm -> Code copied from _import_local_thrift and adapted
    for libpath in glob.glob(os.path.join(_ROOT_DIR, 'lib', 'py', 'build', 'lib.*')):
        for pattern in ('-%d.%d', '-%d%d'):
            postfix = pattern % (sys.version_info[0], sys.version_info[1])
            if libpath.endswith(postfix):
                return libpath
thrift-0.23.0/test/py/TestSyntax.py0000775000175000017500000000172415165535636017513 0ustar00buildbuild00000000000000#!/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.
#

# Just import these generated files to make sure they are syntactically valid
from DebugProtoTest import EmptyService  # noqa
from DebugProtoTest import Inherited  # noqa
thrift-0.23.0/test/py/TestServer.py0000775000175000017500000004070615167543515017473 0ustar00buildbuild00000000000000#!/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.
#
import logging
import os
import signal
import ssl
import sys
import time
from optparse import OptionParser

from util import local_libpath
sys.path.insert(0, local_libpath())
from thrift.protocol import TProtocol, TProtocolDecorator
from thrift.Thrift import TException

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))


class TestHandler(object):
    def __init__(self, options):
        self.options = options

    def testVoid(self):
        if self.options.verbose > 1:
            logging.info('testVoid()')

    def testString(self, str):
        if self.options.verbose > 1:
            logging.info('testString(%s)' % str)
        return str

    def testBool(self, boolean):
        if self.options.verbose > 1:
            logging.info('testBool(%s)' % str(boolean).lower())
        return boolean

    def testByte(self, byte):
        if self.options.verbose > 1:
            logging.info('testByte(%d)' % byte)
        return byte

    def testI16(self, i16):
        if self.options.verbose > 1:
            logging.info('testI16(%d)' % i16)
        return i16

    def testI32(self, i32):
        if self.options.verbose > 1:
            logging.info('testI32(%d)' % i32)
        return i32

    def testI64(self, i64):
        if self.options.verbose > 1:
            logging.info('testI64(%d)' % i64)
        return i64

    def testDouble(self, dub):
        if self.options.verbose > 1:
            logging.info('testDouble(%f)' % dub)
        return dub

    def testBinary(self, thing):
        if self.options.verbose > 1:
            logging.info('testBinary()')  # TODO: hex output
        return thing

    def testUuid(self, thing):
        if self.options.verbose > 1:
            logging.info('testUuid(%s)' % thing)
        return thing

    def testStruct(self, thing):
        if self.options.verbose > 1:
            logging.info('testStruct({%s, %s, %s, %s})' % (thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing))
        return thing

    def testException(self, arg):
        from ThriftTest.ttypes import Xception
        # if self.options.verbose > 1:
        logging.info('testException(%s)' % arg)
        if arg == 'Xception':
            raise Xception(errorCode=1001, message=arg)
        elif arg == 'TException':
            raise TException(message='This is a TException')

    def testMultiException(self, arg0, arg1):
        from ThriftTest.ttypes import Xtruct, Xception, Xception2

        if self.options.verbose > 1:
            logging.info('testMultiException(%s, %s)' % (arg0, arg1))
        if arg0 == 'Xception':
            raise Xception(errorCode=1001, message='This is an Xception')
        elif arg0 == 'Xception2':
            raise Xception2(
                errorCode=2002,
                struct_thing=Xtruct(string_thing='This is an Xception2'))
        return Xtruct(string_thing=arg1)

    def testOneway(self, seconds):
        if self.options.verbose > 1:
            logging.info('testOneway(%d) => sleeping...' % seconds)
        time.sleep(seconds / 3)  # be quick
        if self.options.verbose > 1:
            logging.info('done sleeping')

    def testNest(self, thing):
        if self.options.verbose > 1:
            logging.info('testNest(%s)' % thing)
        return thing

    def testMap(self, thing):
        if self.options.verbose > 1:
            logging.info('testMap(%s)' % thing)
        return thing

    def testStringMap(self, thing):
        if self.options.verbose > 1:
            logging.info('testStringMap(%s)' % thing)
        return thing

    def testSet(self, thing):
        if self.options.verbose > 1:
            logging.info('testSet(%s)' % thing)
        return thing

    def testList(self, thing):
        if self.options.verbose > 1:
            logging.info('testList(%s)' % thing)
        return thing

    def testEnum(self, thing):
        if self.options.verbose > 1:
            logging.info('testEnum(%s)' % thing)
        return thing

    def testTypedef(self, thing):
        if self.options.verbose > 1:
            logging.info('testTypedef(%s)' % thing)
        return thing

    def testMapMap(self, thing):
        if self.options.verbose > 1:
            logging.info('testMapMap(%s)' % thing)
        return {
            -4: {
                -4: -4,
                -3: -3,
                -2: -2,
                -1: -1,
            },
            4: {
                4: 4,
                3: 3,
                2: 2,
                1: 1,
            },
        }

    def testInsanity(self, argument):
        from ThriftTest.ttypes import Insanity

        if self.options.verbose > 1:
            logging.info('testInsanity(%s)' % argument)
        return {
            1: {
                2: argument,
                3: argument,
            },
            2: {6: Insanity()},
        }

    def testMulti(self, arg0, arg1, arg2, arg3, arg4, arg5):
        from ThriftTest.ttypes import Xtruct

        if self.options.verbose > 1:
            logging.info('testMulti(%s, %s, %s, %s, %s, %s)' % (arg0, arg1, arg2, arg3, arg4, arg5))
        return Xtruct(string_thing='Hello2',
                      byte_thing=arg0, i32_thing=arg1, i64_thing=arg2)


class SecondHandler(object):
    def secondtestString(self, argument):
        return "testString(\"" + argument + "\")"


# LAST_SEQID is a global because we have one transport and multiple protocols
# running on it (when multiplexed)
LAST_SEQID = None


class TPedanticSequenceIdProtocolWrapper(TProtocolDecorator.TProtocolDecorator):
    """
    Wraps any protocol with sequence ID checking: looks for outbound
    uniqueness as well as request/response alignment.
    """

    def __init__(self, protocol):
        # TProtocolDecorator.__new__ does all the heavy lifting
        pass

    def readMessageBegin(self):
        global LAST_SEQID
        (name, type, seqid) =\
            super(TPedanticSequenceIdProtocolWrapper, self).readMessageBegin()
        if LAST_SEQID is not None and LAST_SEQID == seqid:
            raise TProtocol.TProtocolException(
                TProtocol.TProtocolException.INVALID_DATA,
                "We received the same seqid {0} twice in a row".format(seqid))
        LAST_SEQID = seqid
        return (name, type, seqid)


def make_pedantic(proto):
    """ Wrap a protocol in the pedantic sequence ID wrapper. """
    # NOTE: this is disabled for now as many clients send seqid
    #       of zero and that is okay, need a way to identify
    #       clients that MUST send seqid unique to function right
    #       or just force all implementations to send unique seqids (preferred)
    return proto  # TPedanticSequenceIdProtocolWrapper(proto)


class TPedanticSequenceIdProtocolFactory(TProtocol.TProtocolFactory):
    def __init__(self, encapsulated):
        super(TPedanticSequenceIdProtocolFactory, self).__init__()
        self.encapsulated = encapsulated

    def getProtocol(self, trans):
        return make_pedantic(self.encapsulated.getProtocol(trans))


def main(options):
    # common header allowed client types
    allowed_client_types = [
        THeaderTransport.THeaderClientType.HEADERS,
        THeaderTransport.THeaderClientType.FRAMED_BINARY,
        THeaderTransport.THeaderClientType.UNFRAMED_BINARY,
        THeaderTransport.THeaderClientType.FRAMED_COMPACT,
        THeaderTransport.THeaderClientType.UNFRAMED_COMPACT,
    ]

    # set up the protocol factory form the --protocol option
    prot_factories = {
        'accel': TBinaryProtocol.TBinaryProtocolAcceleratedFactory(),
        'multia': TBinaryProtocol.TBinaryProtocolAcceleratedFactory(),
        'accelc': TCompactProtocol.TCompactProtocolAcceleratedFactory(),
        'multiac': TCompactProtocol.TCompactProtocolAcceleratedFactory(),
        'binary': TPedanticSequenceIdProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory()),
        'multi': TPedanticSequenceIdProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory()),
        'compact': TCompactProtocol.TCompactProtocolFactory(),
        'multic': TCompactProtocol.TCompactProtocolFactory(),
        'header': THeaderProtocol.THeaderProtocolFactory(allowed_client_types),
        'multih': THeaderProtocol.THeaderProtocolFactory(allowed_client_types),
        'json': TJSONProtocol.TJSONProtocolFactory(),
        'multij': TJSONProtocol.TJSONProtocolFactory(),
    }
    pfactory = prot_factories.get(options.proto, None)
    if pfactory is None:
        raise AssertionError('Unknown --protocol option: %s' % options.proto)
    try:
        pfactory.string_length_limit = options.string_limit
        pfactory.container_length_limit = options.container_limit
    except Exception:
        # Ignore errors for those protocols that does not support length limit
        pass

    # get the server type (TSimpleServer, TNonblockingServer, etc...)
    if len(args) > 1:
        raise AssertionError('Only one server type may be specified, not multiple types.')
    server_type = args[0]
    if options.trans == 'http':
        server_type = 'THttpServer'

    # Set up the handler and processor objects
    handler = TestHandler(options)
    processor = ThriftTest.Processor(handler)

    if options.proto.startswith('multi'):
        secondHandler = SecondHandler()
        secondProcessor = SecondService.Processor(secondHandler)

        multiplexedProcessor = TMultiplexedProcessor()
        multiplexedProcessor.registerDefault(processor)
        multiplexedProcessor.registerProcessor('ThriftTest', processor)
        multiplexedProcessor.registerProcessor('SecondService', secondProcessor)
        processor = multiplexedProcessor

    global server

    # Handle THttpServer as a special case
    if server_type == 'THttpServer':
        if options.ssl:
            __certfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "server.crt")
            __keyfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "server.key")
            server = THttpServer.THttpServer(processor, ('', options.port), pfactory, cert_file=__certfile, key_file=__keyfile)
        else:
            server = THttpServer.THttpServer(processor, ('', options.port), pfactory)
        server.serve()
        sys.exit(0)

    # set up server transport and transport factory

    host = None
    if options.ssl:
        from thrift.transport import TSSLSocket
        keys_dir = os.path.join(os.path.dirname(SCRIPT_DIR), 'keys')
        ca_certs = os.path.join(keys_dir, 'client.pem')
        certfile = os.path.join(keys_dir, 'server.crt')
        keyfile = os.path.join(keys_dir, 'server.key')
        ssl_version = getattr(ssl, 'PROTOCOL_TLS_SERVER', ssl.PROTOCOL_TLSv1)
        transport = TSSLSocket.TSSLServerSocket(
            host,
            options.port,
            certfile=certfile,
            keyfile=keyfile,
            ca_certs=ca_certs,
            cert_reqs=ssl.CERT_REQUIRED,
            ssl_version=ssl_version,
        )
    else:
        transport = TSocket.TServerSocket(host, options.port, options.domain_socket)
    tfactory = TTransport.TBufferedTransportFactory()
    if options.trans == 'buffered':
        tfactory = TTransport.TBufferedTransportFactory()
    elif options.trans == 'framed':
        tfactory = TTransport.TFramedTransportFactory()
    elif options.trans == '':
        raise AssertionError('Unknown --transport option: %s' % options.trans)
    else:
        tfactory = TTransport.TBufferedTransportFactory()
    # if --zlib, then wrap server transport, and use a different transport factory
    if options.zlib:
        if server_type != "TProcessPoolServer":
            transport = TZlibTransport.TZlibTransport(transport)  # wrap with zlib
        # Avoid wrapping the server transport for process pools; TZlibTransport isn't picklable on spawn.
        tfactory = TZlibTransport.TZlibTransportFactory()

    # do server-specific setup here:
    if server_type == "TNonblockingServer":
        server = TNonblockingServer.TNonblockingServer(processor, transport, inputProtocolFactory=pfactory)
    elif server_type == "TProcessPoolServer":
        import signal
        from thrift.server import TProcessPoolServer
        server = TProcessPoolServer.TProcessPoolServer(processor, transport, tfactory, pfactory)
        server.setNumWorkers(5)

        def set_alarm():
            def clean_shutdown(signum, frame):
                for worker in server.workers:
                    if options.verbose > 0:
                        logging.info('Terminating worker: %s' % worker)
                    worker.terminate()
                if options.verbose > 0:
                    logging.info('Requesting server to stop()')
                try:
                    server.stop()
                except Exception:
                    pass
            signal.signal(signal.SIGALRM, clean_shutdown)
            signal.alarm(4)
        set_alarm()
    else:
        # look up server class dynamically to instantiate server
        ServerClass = getattr(TServer, server_type)
        server = ServerClass(processor, transport, tfactory, pfactory)
    # enter server main loop
    server.serve()


def exit_gracefully(signum, frame):
    print("SIGINT received\n")
    server.shutdown()   # doesn't work properly, yet
    sys.exit(0)


if __name__ == '__main__':
    signal.signal(signal.SIGINT, exit_gracefully)

    parser = OptionParser()
    parser.add_option('--libpydir', type='string', dest='libpydir',
                      help='include this directory to sys.path for locating library code')
    parser.add_option('--genpydir', type='string', dest='genpydir',
                      default='gen-py',
                      help='include this directory to sys.path for locating generated code')
    parser.add_option("--port", type="int", dest="port",
                      help="port number for server to listen on")
    parser.add_option("--zlib", action="store_true", dest="zlib",
                      help="use zlib wrapper for compressed transport")
    parser.add_option("--ssl", action="store_true", dest="ssl",
                      help="use SSL for encrypted transport")
    parser.add_option('-v', '--verbose', action="store_const",
                      dest="verbose", const=2,
                      help="verbose output")
    parser.add_option('-q', '--quiet', action="store_const",
                      dest="verbose", const=0,
                      help="minimal output")
    parser.add_option('--protocol', dest="proto", type="string",
                      help="protocol to use, one of: accel, accelc, binary, compact, json, multi, multia, multiac, multic, multih, multij")
    parser.add_option('--transport', dest="trans", type="string",
                      help="transport to use, one of: buffered, framed, http")
    parser.add_option('--domain-socket', dest="domain_socket", type="string",
                      help="Unix domain socket path")
    parser.add_option('--container-limit', dest='container_limit', type='int', default=None)
    parser.add_option('--string-limit', dest='string_limit', type='int', default=None)
    parser.set_defaults(port=9090, verbose=1, proto='binary', transport='buffered')
    options, args = parser.parse_args()

    # Print TServer log to stdout so that the test-runner can redirect it to log files
    logging.basicConfig(level=options.verbose)

    sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir))

    from ThriftTest import ThriftTest, SecondService
    from thrift.TMultiplexedProcessor import TMultiplexedProcessor
    from thrift.transport import THeaderTransport
    from thrift.transport import TTransport
    from thrift.transport import TSocket
    from thrift.transport import TZlibTransport
    from thrift.protocol import TBinaryProtocol
    from thrift.protocol import TCompactProtocol
    from thrift.protocol import THeaderProtocol
    from thrift.protocol import TJSONProtocol
    from thrift.server import TServer, TNonblockingServer, THttpServer

    sys.exit(main(options))
thrift-0.23.0/test/py/TestRenderedDoubleConstants.py0000664000175000017500000002452015165535636023001 0ustar00buildbuild00000000000000#
# 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 unittest

from DoubleConstantsTest import constants

#
# In order to run the test under Windows. We need to create symbolic link
# name 'thrift' to '../src' folder by using:
#
# mklink /D thrift ..\src
#


class TestRenderedDoubleConstants(unittest.TestCase):
    ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST = \
        "failed to verify a double constant generated by Thrift (expected = %f, got = %f)"
    ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_LIST_TEST =\
        "failed to verify a list item by Thrift (expected = %f, got = %f)"
    ASSERTION_MESSAGE_FOR_TYPE_CHECKS = "the rendered variable with name %s is not of double type"

    # to make sure the variables inside Thrift files are generated correctly
    def test_rendered_double_constants(self):
        EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1.0
        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100.0
        EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807.0
        EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807.0
        EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359
        EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1
        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1
        EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308
        EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43
        EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308
        EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT,
            places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT,
                constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT,
            places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT,
                constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT,
            places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT,
                constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST,
            EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS, places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS,
                constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE,
            places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE,
                constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST,
            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE, places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE,
                constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE, places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE,
                constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST,
            EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE, places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE,
                constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE, places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE,
                constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST))
        self.assertAlmostEqual(
            constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST,
            EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE, places=7,
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST % (
                EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE,
                constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST))
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST")
        self.assertTrue(
            isinstance(constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, float),
            msg=TestRenderedDoubleConstants.ASSERTION_MESSAGE_FOR_TYPE_CHECKS %
            "DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST")

    # to make sure the variables inside Thrift files are generated correctly
    def test_rendered_double_list(self):
        EXPECTED_DOUBLE_LIST = [1.0, -100.0, 100.0, 9223372036854775807.0, -9223372036854775807.0, 3.14159265359,
                                1000000.1, -1000000.1, 1.7e+308, -1.7e+308, 9223372036854775816.43,
                                -9223372036854775816.43]
        self.assertEqual(len(constants.DOUBLE_LIST_TEST), len(EXPECTED_DOUBLE_LIST))
        for i, expectedValue in enumerate(EXPECTED_DOUBLE_LIST):
            self.assertAlmostEqual(constants.DOUBLE_LIST_TEST[i], expectedValue, places=7)


def suite():
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    suite.addTest(loader.loadTestsFromTestCase(TestRenderedDoubleConstants))
    return suite


if __name__ == "__main__":
    unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
thrift-0.23.0/test/py/CMakeLists.txt0000664000175000017500000000253515167543515017546 0ustar00buildbuild00000000000000#
# 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.
#

add_test(NAME python_test_generate
    COMMAND ${CMAKE_COMMAND}
            -DTHRIFTCOMPILER=$
            -DMY_PROJECT_DIR=${PROJECT_SOURCE_DIR}
            -DMY_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
            -DMY_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
    -P ${CMAKE_CURRENT_SOURCE_DIR}/generate.cmake
)

add_test(NAME python_test
    COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/RunClientServer.py --gen-base=${CMAKE_CURRENT_BINARY_DIR}
    DEPENDS python_test_generate
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

thrift-0.23.0/test/py/TestSocket.py0000775000175000017500000000503615167543515017452 0ustar00buildbuild00000000000000#!/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 thrift.transport import TSocket
import unittest
import time
import socket
import random
import sys


class TimeoutTest(unittest.TestCase):
    def setUp(self):
        for i in range(50):
            try:
                # find a port we can use
                self.listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.port = random.randint(10000, 30000)
                self.listen_sock.bind(('localhost', self.port))
                self.listen_sock.listen(5)
                break
            except Exception:
                if i == 49:
                    raise

    def testConnectTimeout(self):
        starttime = time.time()

        try:
            leaky = []
            for i in range(100):
                socket = TSocket.TSocket('localhost', self.port)
                socket.setTimeout(10)
                socket.open()
                leaky.append(socket)
        except Exception:
            self.assertTrue(time.time() - starttime < 5.0)

    def testWriteTimeout(self):
        starttime = time.time()

        try:
            socket = TSocket.TSocket('localhost', self.port)
            socket.setTimeout(10)
            socket.open()
            lsock = self.listen_sock.accept()
            while True:
                lsock.write("hi" * 100)

        except Exception:
            self.assertTrue(time.time() - starttime < 5.0)


if __name__ == '__main__':
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()

    suite.addTest(loader.loadTestsFromTestCase(TimeoutTest))

    testRunner = unittest.TextTestRunner(verbosity=2)
    result = testRunner.run(suite)

    # Exit with non-zero code if tests failed
    if result.failures or result.errors:
        sys.exit(1)
    else:
        sys.exit(0)
thrift-0.23.0/test/py/Makefile0000644000175000017500000006445215170007175016441 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/py/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
subdir = test/py
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__tty_colors_dummy = \
  mgn= red= grn= lgn= blu= brg= std=; \
  am__color_tests=no
am__tty_colors = { \
  $(am__tty_colors_dummy); \
  if test "X$(AM_COLOR_TESTS)" = Xno; then \
    am__color_tests=no; \
  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
    am__color_tests=yes; \
  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
    am__color_tests=yes; \
  fi; \
  if test $$am__color_tests = yes; then \
    red=''; \
    grn=''; \
    lgn=''; \
    blu=''; \
    mgn=''; \
    brg=''; \
    std=''; \
  fi; \
}
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = /thrift/src/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/py
abs_srcdir = /thrift/src/test/py
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..

#
# 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.
#
AUTOMAKE_OPTIONS = serial-tests
py_unit_tests = RunClientServer.py
thrift_gen = \
        gen-py/ThriftTest/__init__.py           \
        gen-py/DebugProtoTest/__init__.py \
        gen-py/DoubleConstantsTest/__init__.py \
        gen-py/Recursive/__init__.py \
        gen-py-default/ThriftTest/__init__.py           \
        gen-py-default/DebugProtoTest/__init__.py \
        gen-py-default/DoubleConstantsTest/__init__.py \
        gen-py-default/Recursive/__init__.py \
        gen-py-slots/ThriftTest/__init__.py           \
        gen-py-slots/DebugProtoTest/__init__.py \
        gen-py-slots/DoubleConstantsTest/__init__.py \
        gen-py-slots/Recursive/__init__.py \
        gen-py-oldstyle/ThriftTest/__init__.py \
        gen-py-oldstyle/DebugProtoTest/__init__.py \
        gen-py-oldstyle/DoubleConstantsTest/__init__.py \
        gen-py-oldstyle/Recursive/__init__.py \
        gen-py-no_utf8strings/ThriftTest/__init__.py \
        gen-py-no_utf8strings/DebugProtoTest/__init__.py \
        gen-py-no_utf8strings/DoubleConstantsTest/__init__.py \
        gen-py-no_utf8strings/Recursive/__init__.py \
        gen-py-dynamic/ThriftTest/__init__.py           \
        gen-py-dynamic/DebugProtoTest/__init__.py \
        gen-py-dynamic/DoubleConstantsTest/__init__.py \
        gen-py-dynamic/Recursive/__init__.py \
        gen-py-dynamicslots/ThriftTest/__init__.py           \
        gen-py-dynamicslots/DebugProtoTest/__init__.py \
        gen-py-dynamicslots/DoubleConstantsTest/__init__.py \
        gen-py-dynamicslots/Recursive/__init__.py \
        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-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

BUILT_SOURCES = $(thrift_gen)
helper_scripts = \
        TestClient.py                           \
        TestServer.py

check_SCRIPTS = \
        $(thrift_gen) \
        $(py_unit_tests)                        \
        $(helper_scripts)

TESTS = $(py_unit_tests)
all: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/py/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/py/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


check-TESTS: $(TESTS)
	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
	srcdir=$(srcdir); export srcdir; \
	list=' $(TESTS) '; \
	$(am__tty_colors); \
	if test -n "$$list"; then \
	  for tst in $$list; do \
	    if test -f ./$$tst; then dir=./; \
	    elif test -f $$tst; then dir=; \
	    else dir="$(srcdir)/"; fi; \
	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
	      all=`expr $$all + 1`; \
	      case " $(XFAIL_TESTS) " in \
	      *[\ \	]$$tst[\ \	]*) \
		xpass=`expr $$xpass + 1`; \
		failed=`expr $$failed + 1`; \
		col=$$red; res=XPASS; \
	      ;; \
	      *) \
		col=$$grn; res=PASS; \
	      ;; \
	      esac; \
	    elif test $$? -ne 77; then \
	      all=`expr $$all + 1`; \
	      case " $(XFAIL_TESTS) " in \
	      *[\ \	]$$tst[\ \	]*) \
		xfail=`expr $$xfail + 1`; \
		col=$$lgn; res=XFAIL; \
	      ;; \
	      *) \
		failed=`expr $$failed + 1`; \
		col=$$red; res=FAIL; \
	      ;; \
	      esac; \
	    else \
	      skip=`expr $$skip + 1`; \
	      col=$$blu; res=SKIP; \
	    fi; \
	    echo "$${col}$$res$${std}: $$tst"; \
	  done; \
	  if test "$$all" -eq 1; then \
	    tests="test"; \
	    All=""; \
	  else \
	    tests="tests"; \
	    All="All "; \
	  fi; \
	  if test "$$failed" -eq 0; then \
	    if test "$$xfail" -eq 0; then \
	      banner="$$All$$all $$tests passed"; \
	    else \
	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
	    fi; \
	  else \
	    if test "$$xpass" -eq 0; then \
	      banner="$$failed of $$all $$tests failed"; \
	    else \
	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
	    fi; \
	  fi; \
	  dashes="$$banner"; \
	  skipped=""; \
	  if test "$$skip" -ne 0; then \
	    if test "$$skip" -eq 1; then \
	      skipped="($$skip test was not run)"; \
	    else \
	      skipped="($$skip tests were not run)"; \
	    fi; \
	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
	      dashes="$$skipped"; \
	  fi; \
	  report=""; \
	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
	    report="Please report to $(PACKAGE_BUGREPORT)"; \
	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
	      dashes="$$report"; \
	  fi; \
	  dashes=`echo "$$dashes" | sed s/./=/g`; \
	  if test "$$failed" -eq 0; then \
	    col="$$grn"; \
	  else \
	    col="$$red"; \
	  fi; \
	  echo "$${col}$$dashes$${std}"; \
	  echo "$${col}$$banner$${std}"; \
	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
	  test -z "$$report" || echo "$${col}$$report$${std}"; \
	  echo "$${col}$$dashes$${std}"; \
	  test "$$failed" -eq 0; \
	else :; fi

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
	$(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile
installdirs:
install: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: all check check-am install install-am install-exec \
	install-strip

.PHONY: all all-am check check-TESTS check-am clean clean-generic \
	clean-libtool clean-local cscopelist-am ctags-am dist-hook \
	distclean distclean-generic distclean-libtool distdir dvi \
	dvi-am html html-am info info-am install install-am \
	install-data install-data-am install-dvi install-dvi-am \
	install-exec install-exec-am install-html install-html-am \
	install-info install-info-am install-man install-pdf \
	install-pdf-am install-ps install-ps-am install-strip \
	installcheck installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

precross: $(thrift_gen)

gen-py/%/__init__.py: ../%.thrift $(THRIFT)
	test -f ../$(notdir $<) \
	&& $(THRIFT) --gen py  ../$(notdir $<) \
	|| $(THRIFT) --gen py  $<

gen-py-default/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-default || $(MKDIR_P) gen-py-default
	test -f ../$(notdir $<) \
	&& $(THRIFT) --gen py -out gen-py-default ../$(notdir $<) \
	|| $(THRIFT) --gen py -out gen-py-default $<

gen-py-slots/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-slots || $(MKDIR_P) gen-py-slots
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:slots -out gen-py-slots ../$(notdir $<) \
	|| $(THRIFT) --gen py:slots -out gen-py-slots $<

gen-py-oldstyle/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-oldstyle || $(MKDIR_P) gen-py-oldstyle
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:old_style -out gen-py-oldstyle ../$(notdir $<) \
	|| $(THRIFT) --gen py:old_style -out gen-py-oldstyle $<

gen-py-no_utf8strings/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-no_utf8strings || $(MKDIR_P) gen-py-no_utf8strings
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:no_utf8strings -out gen-py-no_utf8strings ../$(notdir $<) \
	|| $(THRIFT) --gen py:no_utf8strings -out gen-py-no_utf8strings $<

gen-py-dynamic/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-dynamic || $(MKDIR_P) gen-py-dynamic
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:dynamic -out gen-py-dynamic ../$(notdir $<) \
	|| $(THRIFT) --gen py:dynamic -out gen-py-dynamic $<

gen-py-dynamicslots/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-dynamicslots || $(MKDIR_P) gen-py-dynamicslots
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:dynamic,slots -out gen-py-dynamicslots ../$(notdir $<) \
	|| $(THRIFT) --gen py:dynamic,slots -out gen-py-dynamicslots $<

gen-py-enum/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-enum || $(MKDIR_P) gen-py-enum
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:enum -out gen-py-enum ../$(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
	find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(RM) -r gen-py*/

dist-hook:
	find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f
	find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(RM) -r $(distdir)/gen-py*/

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/py/TestFrozen.py0000775000175000017500000001257415167543515017472 0ustar00buildbuild00000000000000#!/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 DebugProtoTest import Srv
from DebugProtoTest.ttypes import CompactProtoTestStruct, Empty, Wrapper
from DebugProtoTest.ttypes import ExceptionWithAMap, MutableException, ExceptionWithoutFields
from thrift.Thrift import TFrozenDict
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol, TCompactProtocol
from collections.abc import Hashable
import unittest


class TestFrozenBase(unittest.TestCase):
    def _roundtrip(self, src, dst):
        otrans = TTransport.TMemoryBuffer()
        optoro = self.protocol(otrans)
        src.write(optoro)
        itrans = TTransport.TMemoryBuffer(otrans.getvalue())
        iproto = self.protocol(itrans)
        return dst.read(iproto) or dst

    def test_dict_is_hashable_only_after_frozen(self):
        d0 = {}
        self.assertFalse(isinstance(d0, Hashable))
        d1 = TFrozenDict(d0)
        self.assertTrue(isinstance(d1, Hashable))

    def test_struct_with_collection_fields(self):
        pass

    def test_set(self):
        """Test that annotated set field can be serialized and deserialized"""
        x = CompactProtoTestStruct(set_byte_map={
            frozenset([42, 100, -100]): 99,
            frozenset([0]): 100,
            frozenset([]): 0,
        })
        x2 = self._roundtrip(x, CompactProtoTestStruct())
        self.assertEqual(x2.set_byte_map[frozenset([42, 100, -100])], 99)
        self.assertEqual(x2.set_byte_map[frozenset([0])], 100)
        self.assertEqual(x2.set_byte_map[frozenset([])], 0)

    def test_map(self):
        """Test that annotated map field can be serialized and deserialized"""
        x = CompactProtoTestStruct(map_byte_map={
            TFrozenDict({42: 42, 100: -100}): 99,
            TFrozenDict({0: 0}): 100,
            TFrozenDict({}): 0,
        })
        x2 = self._roundtrip(x, CompactProtoTestStruct())
        self.assertEqual(x2.map_byte_map[TFrozenDict({42: 42, 100: -100})], 99)
        self.assertEqual(x2.map_byte_map[TFrozenDict({0: 0})], 100)
        self.assertEqual(x2.map_byte_map[TFrozenDict({})], 0)

    def test_list(self):
        """Test that annotated list field can be serialized and deserialized"""
        x = CompactProtoTestStruct(list_byte_map={
            (42, 100, -100): 99,
            (0,): 100,
            (): 0,
        })
        x2 = self._roundtrip(x, CompactProtoTestStruct())
        self.assertEqual(x2.list_byte_map[(42, 100, -100)], 99)
        self.assertEqual(x2.list_byte_map[(0,)], 100)
        self.assertEqual(x2.list_byte_map[()], 0)

    def test_empty_struct(self):
        """Test that annotated empty struct can be serialized and deserialized"""
        x = CompactProtoTestStruct(empty_struct_field=Empty())
        x2 = self._roundtrip(x, CompactProtoTestStruct())
        self.assertEqual(x2.empty_struct_field, Empty())

    def test_struct(self):
        """Test that annotated struct can be serialized and deserialized"""
        x = Wrapper(foo=Empty())
        self.assertEqual(x.foo, Empty())
        x2 = self._roundtrip(x, Wrapper)
        self.assertEqual(x2.foo, Empty())

    def test_frozen_exception(self):
        exc = ExceptionWithAMap(blah='foo')
        with self.assertRaises(TypeError):
            exc.blah = 'bar'
        mutexc = MutableException(msg='foo')
        mutexc.msg = 'bar'
        self.assertEqual(mutexc.msg, 'bar')

    def test_frozen_exception_with_no_fields(self):
        ExceptionWithoutFields()

    def test_frozen_exception_serialization(self):
        result = Srv.declaredExceptionMethod_result(
            xwamap=ExceptionWithAMap(blah="error"))
        deserialized = self._roundtrip(
            result, Srv.declaredExceptionMethod_result())
        self.assertEqual(result, deserialized)


class TestFrozen(TestFrozenBase):
    def protocol(self, trans):
        return TBinaryProtocol.TBinaryProtocolFactory().getProtocol(trans)


class TestFrozenAcceleratedBinary(TestFrozenBase):
    def protocol(self, trans):
        return TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(trans)


class TestFrozenAcceleratedCompact(TestFrozenBase):
    def protocol(self, trans):
        return TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(trans)


def suite():
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    suite.addTest(loader.loadTestsFromTestCase(TestFrozen))
    suite.addTest(loader.loadTestsFromTestCase(TestFrozenAcceleratedBinary))
    suite.addTest(loader.loadTestsFromTestCase(TestFrozenAcceleratedCompact))
    return suite


if __name__ == "__main__":
    unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
thrift-0.23.0/test/py/explicit_module/0000775000175000017500000000000015167543515020167 5ustar00buildbuild00000000000000thrift-0.23.0/test/py/explicit_module/test5.thrift0000664000175000017500000000225615165535636022465 0ustar00buildbuild00000000000000/*
 * 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 py test5

include "shared_types.thrift"

enum TestEnum {
  TestEnum0 = 0,
  TestEnum1 = 1,
}

struct TestStruct {
    1: optional string param1
    2: optional TestEnum param2
    3: optional shared_types.SharedEnum param3
}

/**
 * Structs can also be exceptions, if they are nasty.
 */
exception TestException {
  1: i32 whatOp,
  2: shared_types.SharedEnum why
  3: TestEnum who
}thrift-0.23.0/test/py/explicit_module/test1.thrift0000664000175000017500000000155315165535636022460 0ustar00buildbuild00000000000000/*
 * 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 py foo.bar.baz

struct astruct {
  1: i32 how_unoriginal;
}
thrift-0.23.0/test/py/explicit_module/test2.thrift0000664000175000017500000000155615165535636022464 0ustar00buildbuild00000000000000/*
 * 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 "test1.thrift"

struct another {
  1: test1.astruct something;
}
thrift-0.23.0/test/py/explicit_module/shared_types.thrift0000664000175000017500000000157215165535636024113 0ustar00buildbuild00000000000000/*
 * 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 py shared_types

enum SharedEnum {
  SharedEnum0 = 0,
  SharedEnum1 = 1
}

thrift-0.23.0/test/py/explicit_module/runtest.sh0000775000175000017500000000375615165535636022250 0ustar00buildbuild00000000000000#!/bin/bash

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

rm -rf gen-py
../../../compiler/cpp/thrift --gen py test1.thrift || exit 1
../../../compiler/cpp/thrift --gen py test2.thrift || exit 1
../../../compiler/cpp/thrift --gen py test3.thrift && exit 1  # Fail since test3.thrift has python keywords
../../../compiler/cpp/thrift --gen py:enum shared_types.thrift || exit 1
../../../compiler/cpp/thrift --gen py:enum test4.thrift || exit 1
../../../compiler/cpp/thrift --gen py:enum test5.thrift || exit 1
mkdir -p ./gen-py/test5_slots
../../../compiler/cpp/thrift --gen py:enum,slots -out ./gen-py/test5_slots test5.thrift || exit 1
PYTHONPATH=./gen-py python -c 'import foo.bar.baz' || exit 1
PYTHONPATH=./gen-py python -c 'import test2' || exit 1
PYTHONPATH=./gen-py python -c 'import test1' &>/dev/null && exit 1  # Should fail.
PYTHONPATH=./gen-py python -c 'import test4.constants' || exit 1
PYTHONPATH=./gen-py python EnumSerializationTest.py || exit 1
PYTHONPATH=./gen-py python EnumSerializationTest.py slot|| exit 1
cp -r gen-py simple
../../../compiler/cpp/thrift -r --gen py test2.thrift || exit 1
PYTHONPATH=./gen-py python -c 'import test2' || exit 1
diff -ur simple gen-py > thediffs
file thediffs | grep -s -q empty || exit 1
rm -rf simple thediffs
echo 'All tests pass!'
thrift-0.23.0/test/py/explicit_module/EnumSerializationTest.py0000664000175000017500000000662015167543515025047 0ustar00buildbuild00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# 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 __future__ import annotations

import sys
from shared_types.ttypes import SharedEnum
from thrift.TSerialization import serialize, deserialize
from thrift.protocol import TBinaryProtocol
from thrift.transport import TTransport


def deserialize_immutable(base,
                          buf,
                          protocol_factory=TBinaryProtocol.TBinaryProtocolFactory()):
    transport = TTransport.TMemoryBuffer(buf)
    protocol = protocol_factory.getProtocol(transport)
    return base.read(protocol)


def serialization_deserialization_struct_enum_test():
    test_obj = TestStruct(param1="test_string", param2=TestEnum.TestEnum1, param3=SharedEnum.SharedEnum1)
    test_obj_serialized = serialize(test_obj)
    test_obj2 = deserialize(TestStruct(), test_obj_serialized)
    assert test_obj.param1 == test_obj2.param1
    assert test_obj.param2 == test_obj2.param2
    assert test_obj.param3 == test_obj2.param3


def serialization_deserialization_struct_enum_as_string_test():
    test_obj = TestStruct(param1="test_string", param2=TestEnum.TestEnum1.name, param3=SharedEnum.SharedEnum1.name)
    test_obj_serialized = serialize(test_obj)
    test_obj2 = deserialize(TestStruct(), test_obj_serialized)
    assert test_obj.param1 == test_obj2.param1
    assert test_obj.param2 == test_obj2.param2
    assert test_obj.param3 == test_obj2.param3


def serialization_deserialization_exception_enum_as_string_test():
    test_obj = TestException(whatOp=0, why=SharedEnum.SharedEnum0.name, who=TestEnum.TestEnum0.name)
    test_obj_serialized = serialize(test_obj)
    test_obj2 = deserialize_immutable(TestException, test_obj_serialized)
    assert test_obj.whatOp == test_obj2.whatOp
    assert test_obj.why == test_obj2.why
    assert test_obj.who == test_obj2.who


def serialization_deserialization_exception_enum_test():
    test_obj = TestException(whatOp=0, why=SharedEnum.SharedEnum0, who=TestEnum.TestEnum0)
    test_obj_serialized = serialize(test_obj)
    test_obj2 = deserialize_immutable(TestException, test_obj_serialized)
    assert test_obj.whatOp == test_obj2.whatOp
    assert test_obj.why == test_obj2.why
    assert test_obj.who == test_obj2.who


if __name__ == "__main__":
    args = sys.argv[1:]
    if args:
        from test5_slots.test5.ttypes import TestEnum, TestStruct, TestException
    else:
        from test5.ttypes import TestEnum, TestStruct, TestException
    serialization_deserialization_struct_enum_test()
    serialization_deserialization_struct_enum_as_string_test()
    serialization_deserialization_exception_enum_as_string_test()
    serialization_deserialization_exception_enum_test()
thrift-0.23.0/test/py/explicit_module/test3.thrift0000664000175000017500000000153615165535636022463 0ustar00buildbuild00000000000000/*
 * 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 py validations

struct from {
  1: i32 def;
}

thrift-0.23.0/test/py/explicit_module/test4.thrift0000664000175000017500000000205615165535636022462 0ustar00buildbuild00000000000000/*
 * 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 py test4

include "shared_types.thrift"

enum TestEnum {
  TestEnum0 = 0,
  TestEnum1 = 1,
}

const map typeConversion = {
  TestEnum.TestEnum0: shared_types.SharedEnum0,
  TestEnum.TestEnum1: shared_types.SharedEnum1,
}thrift-0.23.0/test/py/Makefile.in0000644000175000017500000006341515170007167017045 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/py
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__tty_colors_dummy = \
  mgn= red= grn= lgn= blu= brg= std=; \
  am__color_tests=no
am__tty_colors = { \
  $(am__tty_colors_dummy); \
  if test "X$(AM_COLOR_TESTS)" = Xno; then \
    am__color_tests=no; \
  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
    am__color_tests=yes; \
  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
    am__color_tests=yes; \
  fi; \
  if test $$am__color_tests = yes; then \
    red=''; \
    grn=''; \
    lgn=''; \
    blu=''; \
    mgn=''; \
    brg=''; \
    std=''; \
  fi; \
}
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@

#
# 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.
#
AUTOMAKE_OPTIONS = serial-tests
py_unit_tests = RunClientServer.py
thrift_gen = \
        gen-py/ThriftTest/__init__.py           \
        gen-py/DebugProtoTest/__init__.py \
        gen-py/DoubleConstantsTest/__init__.py \
        gen-py/Recursive/__init__.py \
        gen-py-default/ThriftTest/__init__.py           \
        gen-py-default/DebugProtoTest/__init__.py \
        gen-py-default/DoubleConstantsTest/__init__.py \
        gen-py-default/Recursive/__init__.py \
        gen-py-slots/ThriftTest/__init__.py           \
        gen-py-slots/DebugProtoTest/__init__.py \
        gen-py-slots/DoubleConstantsTest/__init__.py \
        gen-py-slots/Recursive/__init__.py \
        gen-py-oldstyle/ThriftTest/__init__.py \
        gen-py-oldstyle/DebugProtoTest/__init__.py \
        gen-py-oldstyle/DoubleConstantsTest/__init__.py \
        gen-py-oldstyle/Recursive/__init__.py \
        gen-py-no_utf8strings/ThriftTest/__init__.py \
        gen-py-no_utf8strings/DebugProtoTest/__init__.py \
        gen-py-no_utf8strings/DoubleConstantsTest/__init__.py \
        gen-py-no_utf8strings/Recursive/__init__.py \
        gen-py-dynamic/ThriftTest/__init__.py           \
        gen-py-dynamic/DebugProtoTest/__init__.py \
        gen-py-dynamic/DoubleConstantsTest/__init__.py \
        gen-py-dynamic/Recursive/__init__.py \
        gen-py-dynamicslots/ThriftTest/__init__.py           \
        gen-py-dynamicslots/DebugProtoTest/__init__.py \
        gen-py-dynamicslots/DoubleConstantsTest/__init__.py \
        gen-py-dynamicslots/Recursive/__init__.py \
        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-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

BUILT_SOURCES = $(thrift_gen)
helper_scripts = \
        TestClient.py                           \
        TestServer.py

check_SCRIPTS = \
        $(thrift_gen) \
        $(py_unit_tests)                        \
        $(helper_scripts)

TESTS = $(py_unit_tests)
all: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/py/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/py/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


check-TESTS: $(TESTS)
	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
	srcdir=$(srcdir); export srcdir; \
	list=' $(TESTS) '; \
	$(am__tty_colors); \
	if test -n "$$list"; then \
	  for tst in $$list; do \
	    if test -f ./$$tst; then dir=./; \
	    elif test -f $$tst; then dir=; \
	    else dir="$(srcdir)/"; fi; \
	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
	      all=`expr $$all + 1`; \
	      case " $(XFAIL_TESTS) " in \
	      *[\ \	]$$tst[\ \	]*) \
		xpass=`expr $$xpass + 1`; \
		failed=`expr $$failed + 1`; \
		col=$$red; res=XPASS; \
	      ;; \
	      *) \
		col=$$grn; res=PASS; \
	      ;; \
	      esac; \
	    elif test $$? -ne 77; then \
	      all=`expr $$all + 1`; \
	      case " $(XFAIL_TESTS) " in \
	      *[\ \	]$$tst[\ \	]*) \
		xfail=`expr $$xfail + 1`; \
		col=$$lgn; res=XFAIL; \
	      ;; \
	      *) \
		failed=`expr $$failed + 1`; \
		col=$$red; res=FAIL; \
	      ;; \
	      esac; \
	    else \
	      skip=`expr $$skip + 1`; \
	      col=$$blu; res=SKIP; \
	    fi; \
	    echo "$${col}$$res$${std}: $$tst"; \
	  done; \
	  if test "$$all" -eq 1; then \
	    tests="test"; \
	    All=""; \
	  else \
	    tests="tests"; \
	    All="All "; \
	  fi; \
	  if test "$$failed" -eq 0; then \
	    if test "$$xfail" -eq 0; then \
	      banner="$$All$$all $$tests passed"; \
	    else \
	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
	    fi; \
	  else \
	    if test "$$xpass" -eq 0; then \
	      banner="$$failed of $$all $$tests failed"; \
	    else \
	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
	    fi; \
	  fi; \
	  dashes="$$banner"; \
	  skipped=""; \
	  if test "$$skip" -ne 0; then \
	    if test "$$skip" -eq 1; then \
	      skipped="($$skip test was not run)"; \
	    else \
	      skipped="($$skip tests were not run)"; \
	    fi; \
	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
	      dashes="$$skipped"; \
	  fi; \
	  report=""; \
	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
	    report="Please report to $(PACKAGE_BUGREPORT)"; \
	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
	      dashes="$$report"; \
	  fi; \
	  dashes=`echo "$$dashes" | sed s/./=/g`; \
	  if test "$$failed" -eq 0; then \
	    col="$$grn"; \
	  else \
	    col="$$red"; \
	  fi; \
	  echo "$${col}$$dashes$${std}"; \
	  echo "$${col}$$banner$${std}"; \
	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
	  test -z "$$report" || echo "$${col}$$report$${std}"; \
	  echo "$${col}$$dashes$${std}"; \
	  test "$$failed" -eq 0; \
	else :; fi

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
	$(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile
installdirs:
install: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: all check check-am install install-am install-exec \
	install-strip

.PHONY: all all-am check check-TESTS check-am clean clean-generic \
	clean-libtool clean-local cscopelist-am ctags-am dist-hook \
	distclean distclean-generic distclean-libtool distdir dvi \
	dvi-am html html-am info info-am install install-am \
	install-data install-data-am install-dvi install-dvi-am \
	install-exec install-exec-am install-html install-html-am \
	install-info install-info-am install-man install-pdf \
	install-pdf-am install-ps install-ps-am install-strip \
	installcheck installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

precross: $(thrift_gen)

gen-py/%/__init__.py: ../%.thrift $(THRIFT)
	test -f ../$(notdir $<) \
	&& $(THRIFT) --gen py  ../$(notdir $<) \
	|| $(THRIFT) --gen py  $<

gen-py-default/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-default || $(MKDIR_P) gen-py-default
	test -f ../$(notdir $<) \
	&& $(THRIFT) --gen py -out gen-py-default ../$(notdir $<) \
	|| $(THRIFT) --gen py -out gen-py-default $<

gen-py-slots/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-slots || $(MKDIR_P) gen-py-slots
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:slots -out gen-py-slots ../$(notdir $<) \
	|| $(THRIFT) --gen py:slots -out gen-py-slots $<

gen-py-oldstyle/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-oldstyle || $(MKDIR_P) gen-py-oldstyle
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:old_style -out gen-py-oldstyle ../$(notdir $<) \
	|| $(THRIFT) --gen py:old_style -out gen-py-oldstyle $<

gen-py-no_utf8strings/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-no_utf8strings || $(MKDIR_P) gen-py-no_utf8strings
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:no_utf8strings -out gen-py-no_utf8strings ../$(notdir $<) \
	|| $(THRIFT) --gen py:no_utf8strings -out gen-py-no_utf8strings $<

gen-py-dynamic/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-dynamic || $(MKDIR_P) gen-py-dynamic
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:dynamic -out gen-py-dynamic ../$(notdir $<) \
	|| $(THRIFT) --gen py:dynamic -out gen-py-dynamic $<

gen-py-dynamicslots/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-dynamicslots || $(MKDIR_P) gen-py-dynamicslots
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:dynamic,slots -out gen-py-dynamicslots ../$(notdir $<) \
	|| $(THRIFT) --gen py:dynamic,slots -out gen-py-dynamicslots $<

gen-py-enum/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-enum || $(MKDIR_P) gen-py-enum
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:enum -out gen-py-enum ../$(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
	find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(RM) -r gen-py*/

dist-hook:
	find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f
	find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(RM) -r $(distdir)/gen-py*/

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/py/TestEof.py0000775000175000017500000001077615165535636016745 0ustar00buildbuild00000000000000#!/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.ttypes import Xtruct
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.protocol import TCompactProtocol
import unittest


class TestEof(unittest.TestCase):

    def make_data(self, pfactory=None):
        trans = TTransport.TMemoryBuffer()
        if pfactory:
            prot = pfactory.getProtocol(trans)
        else:
            prot = TBinaryProtocol.TBinaryProtocol(trans)

        x = Xtruct()
        x.string_thing = "Zero"
        x.byte_thing = 0

        x.write(prot)

        x = Xtruct()
        x.string_thing = "One"
        x.byte_thing = 1

        x.write(prot)

        return trans.getvalue()

    def testTransportReadAll(self):
        """Test that readAll on any type of transport throws an EOFError"""
        trans = TTransport.TMemoryBuffer(self.make_data())
        trans.readAll(1)

        try:
            trans.readAll(10000)
        except EOFError:
            return

        self.fail("Should have gotten EOFError")

    def eofTestHelper(self, pfactory):
        trans = TTransport.TMemoryBuffer(self.make_data(pfactory))
        prot = pfactory.getProtocol(trans)

        x = Xtruct()
        x.read(prot)
        self.assertEqual(x.string_thing, "Zero")
        self.assertEqual(x.byte_thing, 0)

        x = Xtruct()
        x.read(prot)
        self.assertEqual(x.string_thing, "One")
        self.assertEqual(x.byte_thing, 1)

        try:
            x = Xtruct()
            x.read(prot)
        except EOFError:
            return

        self.fail("Should have gotten EOFError")

    def eofTestHelperStress(self, pfactory):
        """Test the ability of TBinaryProtocol to deal with the removal of every byte in the file"""
        # TODO: we should make sure this covers more of the code paths

        data = self.make_data(pfactory)
        for i in range(0, len(data) + 1):
            trans = TTransport.TMemoryBuffer(data[0:i])
            prot = pfactory.getProtocol(trans)
            try:
                x = Xtruct()
                x.read(prot)
                x.read(prot)
                x.read(prot)
            except EOFError:
                continue
            self.fail("Should have gotten an EOFError")

    def testBinaryProtocolEof(self):
        """Test that TBinaryProtocol throws an EOFError when it reaches the end of the stream"""
        self.eofTestHelper(TBinaryProtocol.TBinaryProtocolFactory())
        self.eofTestHelperStress(TBinaryProtocol.TBinaryProtocolFactory())

    def testBinaryProtocolAcceleratedBinaryEof(self):
        """Test that TBinaryProtocolAccelerated throws an EOFError when it reaches the end of the stream"""
        self.eofTestHelper(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False))
        self.eofTestHelperStress(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False))

    def testCompactProtocolEof(self):
        """Test that TCompactProtocol throws an EOFError when it reaches the end of the stream"""
        self.eofTestHelper(TCompactProtocol.TCompactProtocolFactory())
        self.eofTestHelperStress(TCompactProtocol.TCompactProtocolFactory())

    def testCompactProtocolAcceleratedCompactEof(self):
        """Test that TCompactProtocolAccelerated throws an EOFError when it reaches the end of the stream"""
        self.eofTestHelper(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False))
        self.eofTestHelperStress(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False))


def suite():
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    suite.addTest(loader.loadTestsFromTestCase(TestEof))
    return suite


if __name__ == "__main__":
    unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
thrift-0.23.0/test/py/Makefile.am0000664000175000017500000001327515167543515017045 0ustar00buildbuild00000000000000#
# 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.
#
AUTOMAKE_OPTIONS = serial-tests

py_unit_tests = RunClientServer.py

thrift_gen =                                    \
        gen-py/ThriftTest/__init__.py           \
        gen-py/DebugProtoTest/__init__.py \
        gen-py/DoubleConstantsTest/__init__.py \
        gen-py/Recursive/__init__.py \
        gen-py-default/ThriftTest/__init__.py           \
        gen-py-default/DebugProtoTest/__init__.py \
        gen-py-default/DoubleConstantsTest/__init__.py \
        gen-py-default/Recursive/__init__.py \
        gen-py-slots/ThriftTest/__init__.py           \
        gen-py-slots/DebugProtoTest/__init__.py \
        gen-py-slots/DoubleConstantsTest/__init__.py \
        gen-py-slots/Recursive/__init__.py \
        gen-py-oldstyle/ThriftTest/__init__.py \
        gen-py-oldstyle/DebugProtoTest/__init__.py \
        gen-py-oldstyle/DoubleConstantsTest/__init__.py \
        gen-py-oldstyle/Recursive/__init__.py \
        gen-py-no_utf8strings/ThriftTest/__init__.py \
        gen-py-no_utf8strings/DebugProtoTest/__init__.py \
        gen-py-no_utf8strings/DoubleConstantsTest/__init__.py \
        gen-py-no_utf8strings/Recursive/__init__.py \
        gen-py-dynamic/ThriftTest/__init__.py           \
        gen-py-dynamic/DebugProtoTest/__init__.py \
        gen-py-dynamic/DoubleConstantsTest/__init__.py \
        gen-py-dynamic/Recursive/__init__.py \
        gen-py-dynamicslots/ThriftTest/__init__.py           \
        gen-py-dynamicslots/DebugProtoTest/__init__.py \
        gen-py-dynamicslots/DoubleConstantsTest/__init__.py \
        gen-py-dynamicslots/Recursive/__init__.py \
        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-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)

helper_scripts=                                 \
        TestClient.py                           \
        TestServer.py

check_SCRIPTS=                                  \
        $(thrift_gen) \
        $(py_unit_tests)                        \
        $(helper_scripts)

TESTS= $(py_unit_tests)


gen-py/%/__init__.py: ../%.thrift $(THRIFT)
	test -f ../$(notdir $<) \
	&& $(THRIFT) --gen py  ../$(notdir $<) \
	|| $(THRIFT) --gen py  $<

gen-py-default/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-default || $(MKDIR_P) gen-py-default
	test -f ../$(notdir $<) \
	&& $(THRIFT) --gen py -out gen-py-default ../$(notdir $<) \
	|| $(THRIFT) --gen py -out gen-py-default $<

gen-py-slots/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-slots || $(MKDIR_P) gen-py-slots
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:slots -out gen-py-slots ../$(notdir $<) \
	|| $(THRIFT) --gen py:slots -out gen-py-slots $<

gen-py-oldstyle/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-oldstyle || $(MKDIR_P) gen-py-oldstyle
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:old_style -out gen-py-oldstyle ../$(notdir $<) \
	|| $(THRIFT) --gen py:old_style -out gen-py-oldstyle $<

gen-py-no_utf8strings/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-no_utf8strings || $(MKDIR_P) gen-py-no_utf8strings
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:no_utf8strings -out gen-py-no_utf8strings ../$(notdir $<) \
	|| $(THRIFT) --gen py:no_utf8strings -out gen-py-no_utf8strings $<

gen-py-dynamic/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-dynamic || $(MKDIR_P) gen-py-dynamic
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:dynamic -out gen-py-dynamic ../$(notdir $<) \
	|| $(THRIFT) --gen py:dynamic -out gen-py-dynamic $<

gen-py-dynamicslots/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-dynamicslots || $(MKDIR_P) gen-py-dynamicslots
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:dynamic,slots -out gen-py-dynamicslots ../$(notdir $<) \
	|| $(THRIFT) --gen py:dynamic,slots -out gen-py-dynamicslots $<

gen-py-enum/%/__init__.py: ../%.thrift $(THRIFT)
	test -d gen-py-enum || $(MKDIR_P) gen-py-enum
	test ../$(notdir $<) \
	&& $(THRIFT) --gen py:enum -out gen-py-enum ../$(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
	find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(RM) -r gen-py*/

dist-hook:
	find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f
	find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
	$(RM) -r $(distdir)/gen-py*/
thrift-0.23.0/test/py/RunClientServer.py0000775000175000017500000003353215167543515020456 0ustar00buildbuild00000000000000#!/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.
#

import platform
import copy
import os
import signal
import socket
import subprocess
import sys
import time
from optparse import OptionParser

from util import local_libpath

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))

SCRIPTS = [
    'FastbinaryTest.py',
    'TestFrozen.py',
    'TestRenderedDoubleConstants.py',
    'TSimpleJSONProtocolTest.py',
    'SerializationTest.py',
    'TestEof.py',
    'TestSyntax.py',
    'TestSocket.py',
    'TestTypes.py'
]
FRAMED = ["TNonblockingServer"]
SKIP_ZLIB = ['TNonblockingServer', 'THttpServer']
SKIP_SSL = ['THttpServer']
EXTRA_DELAY = dict(TProcessPoolServer=5.5)

PROTOS = [
    'accel',
    'accelc',
    'binary',
    'compact',
    'json',
    'header',
]


def default_servers():
    servers = [
        'TSimpleServer',
        'TThreadedServer',
        'TThreadPoolServer',
        'TNonblockingServer',
        'THttpServer',
    ]
    if platform.system() != 'Windows':
        servers.append('TProcessPoolServer')
        servers.append('TForkingServer')
    return servers


def relfile(fname):
    return os.path.join(SCRIPT_DIR, fname)


def setup_pypath(libdir, gendir):
    dirs = [libdir, gendir]
    env = copy.deepcopy(os.environ)
    pypath = env.get('PYTHONPATH', None)
    if pypath:
        dirs.append(pypath)
    env['PYTHONPATH'] = os.pathsep.join(dirs)
    if gendir.endswith('gen-py-no_utf8strings'):
        env['THRIFT_TEST_PY_NO_UTF8STRINGS'] = '1'
    return env


def runScriptTest(libdir, genbase, genpydir, script):
    env = setup_pypath(libdir, os.path.join(genbase, genpydir))
    script_args = [sys.executable, relfile(script)]
    print('\nTesting script: %s\n----' % (' '.join(script_args)))
    ret = subprocess.call(script_args, env=env)
    if ret != 0:
        print('*** FAILED ***', file=sys.stderr)
        print('LIBDIR: %s' % libdir, file=sys.stderr)
        print('PY_GEN: %s' % genpydir, file=sys.stderr)
        print('SCRIPT: %s' % script, file=sys.stderr)
        raise Exception("Script subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(script_args)))


def pick_unused_port():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('127.0.0.1', 0))
    port = sock.getsockname()[1]
    sock.close()
    return port


def runServiceTest(libdir, genbase, genpydir, server_class, proto, port, use_zlib, use_ssl, verbose):
    env = setup_pypath(libdir, os.path.join(genbase, genpydir))
    # Build command line arguments
    server_args = [sys.executable, relfile('TestServer.py')]
    cli_args = [sys.executable, relfile('TestClient.py')]
    for which in (server_args, cli_args):
        which.append('--protocol=%s' % proto)  # accel, binary, compact or json
        which.append('--port=%d' % port)  # default to 9090
        if use_zlib:
            which.append('--zlib')
        if use_ssl:
            which.append('--ssl')
        if verbose == 0:
            which.append('-q')
        if verbose == 2:
            which.append('-v')
    # server-specific option to select server class
    server_args.append(server_class)
    # client-specific cmdline options
    if server_class in FRAMED:
        cli_args.append('--transport=framed')
    else:
        cli_args.append('--transport=buffered')
    if server_class == 'THttpServer':
        cli_args.append('--http=/')
    if verbose > 0:
        print('Testing server %s: %s' % (server_class, ' '.join(server_args)))
    popen_kwargs = {'env': env}
    # Windows uses process groups; POSIX starts a new session so we can killpg().
    if platform.system() == 'Windows':
        if hasattr(subprocess, 'CREATE_NEW_PROCESS_GROUP'):
            popen_kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
    else:
        popen_kwargs['start_new_session'] = True
    serverproc = subprocess.Popen(server_args, **popen_kwargs)

    def ensureServerAlive():
        if serverproc.poll() is not None:
            print(('FAIL: Server process (%s) failed with retcode %d')
                  % (' '.join(server_args), serverproc.returncode))
            raise Exception('Server subprocess %s died, args: %s'
                            % (server_class, ' '.join(server_args)))

    # Wait for the server to start accepting connections on the given port.
    sleep_time = 0.1  # Seconds
    max_attempts = 100
    attempt = 0
    while True:
        sock4 = socket.socket()
        sock6 = socket.socket(socket.AF_INET6)
        try:
            if sock4.connect_ex(('127.0.0.1', port)) == 0 \
                    or sock6.connect_ex(('::1', port)) == 0:
                break
            attempt += 1
            if attempt >= max_attempts:
                raise Exception("TestServer not ready on port %d after %.2f seconds"
                                % (port, sleep_time * attempt))
            ensureServerAlive()
            time.sleep(sleep_time)
        finally:
            sock4.close()
            sock6.close()

    try:
        if verbose > 0:
            print('Testing client: %s' % (' '.join(cli_args)))
        ret = subprocess.call(cli_args, env=env)
        if ret != 0:
            print('*** FAILED ***', file=sys.stderr)
            print('LIBDIR: %s' % libdir, file=sys.stderr)
            print('PY_GEN: %s' % genpydir, file=sys.stderr)
            raise Exception("Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args)))
    finally:
        # check that server didn't die, but still attempt cleanup
        cleanup_exc = None
        try:
            ensureServerAlive()
        except Exception as exc:
            cleanup_exc = exc
        extra_sleep = EXTRA_DELAY.get(server_class, 0)
        if extra_sleep > 0 and verbose > 0:
            print('Giving %s (proto=%s,zlib=%s,ssl=%s) an extra %d seconds for child'
                  'processes to terminate via alarm'
                  % (server_class, proto, use_zlib, use_ssl, extra_sleep))
            time.sleep(extra_sleep)
        sig = signal.SIGKILL if platform.system() != 'Windows' else signal.SIGABRT
        try:
            if platform.system() == 'Windows':
                os.kill(serverproc.pid, sig)
            else:
                # POSIX: kill the whole process group to reap forked children.
                os.killpg(serverproc.pid, sig)
        except OSError:
            pass
        serverproc.wait()
        if cleanup_exc:
            raise cleanup_exc


class TestCases(object):
    def __init__(self, genbase, libdir, port, gendirs, servers, verbose):
        self.genbase = genbase
        self.libdir = libdir
        self.port = port
        self.verbose = verbose
        self.gendirs = gendirs
        self.servers = servers

    def default_conf(self):
        return {
            'gendir': self.gendirs[0],
            'server': self.servers[0],
            'proto': PROTOS[0],
            'zlib': False,
            'ssl': False,
        }

    def run(self, conf, test_count):
        with_zlib = conf['zlib']
        with_ssl = conf['ssl']
        try_server = conf['server']
        try_proto = conf['proto']
        genpydir = conf['gendir']
        # skip any servers that don't work with the Zlib transport
        if with_zlib and try_server in SKIP_ZLIB:
            return False
        # skip any servers that don't work with SSL
        if with_ssl and try_server in SKIP_SSL:
            return False
        # Skip SSL issues -> See THRIFT-5901
        if with_ssl:
            print('Skipping \'with_ssl\' tests')
            return False
        if self.verbose > 0:
            print('\nTest run #%d:  (includes %s) Server=%s,  Proto=%s,  zlib=%s,  SSL=%s'
                  % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl))
        port = self.port if self.port else pick_unused_port()
        runServiceTest(self.libdir, self.genbase, genpydir, try_server, try_proto, port, with_zlib, with_ssl, self.verbose)
        if self.verbose > 0:
            print('OK: Finished (includes %s)  %s / %s proto / zlib=%s / SSL=%s.   %d combinations tested.'
                  % (genpydir, try_server, try_proto, with_zlib, with_ssl, test_count))
        return True

    def test_feature(self, name, values):
        test_count = 0
        conf = self.default_conf()
        for try_server in values:
            conf[name] = try_server
            if self.run(conf, test_count):
                test_count += 1
        return test_count

    def run_all_tests(self):
        test_count = 0
        for try_server in self.servers:
            for genpydir in self.gendirs:
                for try_proto in PROTOS:
                    for with_zlib in (False, True):
                        # skip any servers that don't work with the Zlib transport
                        if with_zlib and try_server in SKIP_ZLIB:
                            continue
                        for with_ssl in (False, True):
                            # skip any servers that don't work with SSL
                            if with_ssl and try_server in SKIP_SSL:
                                continue
                            # Skip SSL issues -> See THRIFT-5901
                            if with_ssl:
                                print('Skipping \'with_ssl\' tests')
                                continue
                            test_count += 1
                            if self.verbose > 0:
                                print('\nTest run #%d:  (includes %s) Server=%s,  Proto=%s,  zlib=%s,  SSL=%s'
                                      % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl))
                            port = self.port if self.port else pick_unused_port()
                            runServiceTest(self.libdir, self.genbase, genpydir, try_server, try_proto, port, with_zlib, with_ssl, self.verbose)
                            if self.verbose > 0:
                                print('OK: Finished (includes %s)  %s / %s proto / zlib=%s / SSL=%s.   %d combinations tested.'
                                      % (genpydir, try_server, try_proto, with_zlib, with_ssl, test_count))
        return test_count


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,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=0,
                      help="port number for server to listen on (0 = auto)")
    parser.add_option('-v', '--verbose', action="store_const",
                      dest="verbose", const=2,
                      help="verbose output")
    parser.add_option('-q', '--quiet', action="store_const",
                      dest="verbose", const=0,
                      help="minimal output")
    parser.add_option('-L', '--libdir', dest="libdir", default=local_libpath(),
                      help="directory path that contains Thrift Python library")
    parser.add_option('--gen-base', dest="gen_base", default=SCRIPT_DIR,
                      help="directory path that contains Thrift Python library")
    parser.set_defaults(verbose=1)
    options, args = parser.parse_args()

    generated_dirs = []
    for gp_dir in options.genpydirs.split(','):
        if gp_dir == 'type_hints' and (sys.version_info < (3, 7)):
            print('Skipping \'type_hints\' test since python 3.7 or later is required')
            continue
        generated_dirs.append('gen-py-%s' % (gp_dir))

    # commandline permits a single class name to be specified to override SERVERS=[...]
    servers = default_servers()
    if len(args) == 1:
        if args[0] in servers:
            servers = args
        else:
            print('Unavailable server type "%s", please choose one of: %s' % (args[0], servers))
            sys.exit(0)

    tests = TestCases(options.gen_base, options.libdir, options.port, generated_dirs, servers, options.verbose)

    # run tests without a client/server first
    print('----------------')
    print(' Executing individual test scripts with various generated code directories')
    print(' Directories to be tested: ' + ', '.join(generated_dirs))
    print(' Scripts to be tested: ' + ', '.join(SCRIPTS))
    print('----------------')
    for genpydir in generated_dirs:
        for script in SCRIPTS:
            runScriptTest(options.libdir, options.gen_base, genpydir, script)

    print('----------------')
    print(' Executing Client/Server tests with various generated code directories')
    print(' Servers to be tested: ' + ', '.join(servers))
    print(' Directories to be tested: ' + ', '.join(generated_dirs))
    print(' Protocols to be tested: ' + ', '.join(PROTOS))
    print(' Options to be tested: ZLIB(yes/no), SSL(yes/no)')
    print('----------------')

    if options.all:
        tests.run_all_tests()
    else:
        tests.test_feature('gendir', generated_dirs)
        tests.test_feature('server', servers)
        tests.test_feature('proto', PROTOS)
        tests.test_feature('zlib', [False, True])
        tests.test_feature('ssl', [False, True])


if __name__ == '__main__':
    sys.exit(main())
thrift-0.23.0/test/delphi/0000775000175000017500000000000015167543515015616 5ustar00buildbuild00000000000000thrift-0.23.0/test/delphi/UuidV8Test.thrift0000664000175000017500000000302715167543515021026 0ustar00buildbuild00000000000000/*
 * 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.
 */

/**
 * Test file for UUIDv8 deterministic GUID generation.
 * Covers: struct field-order sensitivity, service inheritance (parent hash),
 * and various field/return types.
 */

namespace delphi UuidV8Test

// --- Structs ---

struct Point {
  1: i32 x
  2: i32 y
}

// Same fields as Point but in reverse order — must produce a different GUID
struct PointReversed {
  1: i32 y
  2: i32 x
}

struct Container {
  1: list items
  2: map counts
  3: set flags
}

// --- Services ---

service BaseService {
  void ping()
  string echo(1: string msg)
}

// Extends BaseService — GUID must incorporate parent's hash
service ExtendedService extends BaseService {
  i32 add(1: i32 a, 2: i32 b)
  oneway void fire(1: string event)
}
thrift-0.23.0/test/FuzzTest.thrift0000664000175000017500000000561115167543515017374 0ustar00buildbuild00000000000000/*
 * 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 fuzz
namespace java org.apache.thrift.fuzz
namespace py fuzz
namespace rb Fuzz
namespace swift Fuzz

// Test typedefs
typedef i64 UserId
typedef binary BinaryData

// Test all primitive types in a compact struct
struct BasicTypes {
    1: bool bool_field,
    2: i8 byte_field,
    3: i16 i16_field,
    4: i32 i32_field,
    5: i64 i64_field,
    6: double double_field,
    7: string string_field,
    8: binary binary_field,
    9: uuid uuid_field
}

// Test optional/required/default requiredness
struct Requiredness {
    1: required i32 req_field,
    2: optional i32 opt_field,
    3: i32 default_field,  // default requiredness
    4: optional string opt_with_default = "test",
    5: required bool req_with_default = true
}

// Test field ID edge cases
struct FieldIDTest {
    1: i32 first,
    100: i32 gap,
    255: i32 medium_id,
    32767: i32 large_id,
}

// Test empty struct
struct EmptyStruct {}

// Test union
union TestUnion {
    1: i32 int_field,
    2: string string_field,
    3: BasicTypes struct_field,
    4: binary binary_field
}

// Test containers (but not too deeply nested)
struct Containers {
    1: list int_list,
    2: set string_set,
    3: map int_string_map,
    4: list struct_list,
    5: map> nested_map,
    6: set typedef_set,
}

// Test enum with various values
enum TestEnum {
    ZERO = 0,
    ONE = 1,
    TWO = 2,
    NEGATIVE = -1,
    LARGE = 32767,
    HEX_VALUE = 0xFF
}

// Test recursive structure
struct RecursiveStruct {
    1: optional RecursiveStruct & recurse,
    2: i32 data,
    3: optional list children
}

// Main test structure - kept minimal but comprehensive
struct FuzzTest {
    1: required BasicTypes basic,
    2: required Requiredness required_test,
    3: required Containers containers,
    4: required TestUnion union_field,
    5: optional RecursiveStruct recursive,
    6: optional EmptyStruct empty,
    7: optional FieldIDTest field_ids,
    8: required TestEnum enum_field,
    9: optional map enum_map,
    10: UserId user_id,
    11: BinaryData data,
}thrift-0.23.0/test/JsDeepConstructorTest.thrift0000664000175000017500000000243315165535636022060 0ustar00buildbuild00000000000000/*
 * 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 Simple {
  1: string value
}

struct Complex {
  1: Simple struct_field
  2: list struct_list_field
  3: set struct_set_field
  4: map struct_map_field
  5: list>>> struct_nested_containers_field
  6: map> > struct_nested_containers_field2
  7: list> list_of_list_field
  8: list>> list_of_list_of_list_field
}

struct ComplexList {
  1: list struct_list_field;
}
thrift-0.23.0/test/StressTest.thrift0000664000175000017500000000220715165535636017722 0ustar00buildbuild00000000000000/*
 * 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 test.stress
namespace d thrift.test.stress
namespace go stress

service Service {

  void echoVoid(),
  i8 echoByte(1: i8 arg),
  i32 echoI32(1: i32 arg),
  i64 echoI64(1: i64 arg),
  string echoString(1: string arg),
  list  echoList(1: list arg),
  set  echoSet(1: set arg),
  map  echoMap(1: map arg),
}

thrift-0.23.0/test/valgrind.suppress0000664000175000017500000000344615165535636017777 0ustar00buildbuild00000000000000{
   boost/get_once_per_thread_epoch/ignore
   Memcheck:Leak
   match-leak-kinds: reachable
   fun:malloc
   fun:_ZN5boost6detail25get_once_per_thread_epochEv
}
{
   boostthreads/once/ignore
   Helgrind:Race
   fun:_ZN5boost13thread_detail17enter_once_regionERNS_9once_flagE
   fun:_ZN5boost6detail23get_current_thread_dataEv
   fun:_ZN5boost6detail20interruption_checkerC1EP15pthread_mutex_tP14pthread_cond_t
   fun:_ZN5boost22condition_variable_any4waitINS_11unique_lockINS_11timed_mutexEEEEEvRT_
   fun:_ZN6apache6thrift11concurrency7Monitor4Impl11waitForeverEv
   fun:_ZN6apache6thrift11concurrency7Monitor4Impl19waitForTimeRelativeEl
   fun:_ZN6apache6thrift11concurrency7Monitor4Impl4waitEl
   fun:_ZNK6apache6thrift11concurrency7Monitor4waitEl
   fun:_ZN6apache6thrift11concurrency11BoostThread5startEv
   fun:_ZN6apache6thrift11concurrency4test18ThreadFactoryTests12reapNThreadsEii
   fun:main
}
{
   pthread/creation-tls/ignore
   Helgrind:Race
   fun:mempcpy
   fun:_dl_allocate_tls_init
   fun:get_cached_stack
   fun:allocate_stack
   fun:pthread_create@@GLIBC_2.2*
   obj:/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so
   fun:_ZN6apache6thrift11concurrency13PthreadThread5startEv
   fun:_ZN6apache6thrift11concurrency4test18ThreadFactoryTests12reapNThreadsEii
   fun:main
}
{
   boost-thread/creation-tls/ignore
   Helgrind:Race
   fun:mempcpy
   fun:_dl_allocate_tls_init
   fun:get_cached_stack
   fun:allocate_stack
   fun:pthread_create@@GLIBC_2.2.5
   obj:/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so
   fun:_ZN5boost6thread21start_thread_noexceptEv
   fun:_ZN5boost6thread12start_threadEv
   fun:_ZN5boost6threadC1ISt5_BindIFPFPvS3_ES3_EEEEOT_
   fun:_ZN6apache6thrift11concurrency11BoostThread5startEv
   fun:_ZN6apache6thrift11concurrency4test18ThreadFactoryTests12reapNThreadsEii
   fun:main
}


thrift-0.23.0/test/partial/0000775000175000017500000000000015165535636016010 5ustar00buildbuild00000000000000thrift-0.23.0/test/partial/thrift_test_schema.thrift0000664000175000017500000001034015165535636023107 0ustar00buildbuild00000000000000/*
 * 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 java org.apache.thrift.partial

// This thrift file is meant for testing partial deserialization.
// It includes all field types and most combinations of complex types.
// Those fields help ensure correctness of partial deserialization.

enum TstEnum {
    UNKNOWN = 0,
    E_ONE = 1,
    E_TWO = 2
}

struct SmallStruct {
    // Primitive fields
    1: optional byte byteField;
    2: optional i16 i16Field;
    3: optional i32 i32Field;
    4: optional i64 i64Field;
    5: optional double doubleField;
    6: optional string stringField;

    // Enum
    7: optional TstEnum enumField;
}

// TODO(kpandit): Need to add bool field
struct TestStruct {
    // Primitive fields
    1: optional byte byteField;
    2: optional i16 i16Field;
    3: optional i32 i32Field;
    4: optional i64 i64Field;
    5: optional double doubleField;
    6: optional string stringField;

    // Enum
    7: optional TstEnum enumField;

    8: optional binary binaryField;

    // List
    10: optional list byteList;
    11: optional list i16List;
    12: optional list i32List;
    13: optional list i64List;
    14: optional list doubleList;
    15: optional list stringList;
    16: optional list enumList;
    17: optional list> listList;
    18: optional list> setList;
    19: optional list> mapList;
    20: optional list structList;
    21: optional list binaryList;

    // Set
    30: optional set byteSet;
    31: optional set i16Set;
    32: optional set i32Set;
    33: optional set i64Set;
    34: optional set doubleSet;
    35: optional set stringSet;
    36: optional set enumSet;
    37: optional set> listSet (nolint = "set.value.type");
    38: optional set> setSet (nolint = "set.value.type");
    39: optional set> mapSet (nolint = "set.value.type");
    40: optional set structSet (nolint = "set.value.type");
    41: optional set binarySet;

    // Map
    50: optional map byteMap;
    51: optional map i16Map;
    52: optional map i32Map;
    53: optional map i64Map;
    54: optional map doubleMap;
    55: optional map stringMap;
    56: optional map enumMap;
    57: optional map> listMap;
    58: optional map> setMap;
    59: optional map> mapMap;
    60: optional map structMap (nolint = "map.key.type");
    61: optional map binaryMap;

    70: optional SmallStruct structField;
}

struct InnermostStruct {
  1: optional string value;
  2: optional i32 intValue;
}

struct InnerStruct {
  1: optional InnermostStruct value;
  2: optional i32 intValue;
}

struct OuterStruct {
  1: optional InnerStruct value;
  2: optional map structMap;
}

union SimpleUnion {
  1: optional i32 intValue;
  2: optional string stringValue;
}

struct StructWithUnions {
  1: optional i32 intValue;
  2: optional SmallStruct smallStruct;
  3: optional SimpleUnion simpleUnion;
  4: optional list unionList;
  5: optional set unionSet (nolint = "set.value.type");
  6: optional map keyUnionMap (nolint = "map.key.type");
  7: optional map valUnionMap;
  8: optional map unionMap (nolint = "map.key.type");
}
thrift-0.23.0/test/README.md0000664000175000017500000001604315165535636015637 0ustar00buildbuild00000000000000# Apache Thrift - integration test suite

This is the cross everything integration test suite for Apache Thrift.

## Run

### A. Using Make

The test can be executed by:

    make cross

This starts the [test.py](test.py) script which does the real cross test with
different transports, protocols and languages.

Note that this skips any language that is not built locally. It also skips
tests that are known to be failing. If you need more control over which tests
to run, read following section.

### B. Using test script directly

Alternatively, you can invoke [test.py](test.py) directly. You need to run`make
precross` once before executing it for the first time.

For example, if you changed something in `nodejs` library and need to verify
the patch, you can skip everything except `nodejs` itself and some reference
implementation (currently `cpp` and `java` are recommended) like this:

    ./configure --without-c_glib --without-erlang --without-lua ...
    make precross -j8
    test/test.py --server cpp,java --client nodejs
    test/test.py --server nodejs --client cpp,java

Another useful flag is --regex. For example, to run all tests that involve
Java TBinaryProtocol:

    test/test.py --regex "java.*binary"

## Test case definition file

The cross test cases are defined in [tests.json](tests.json).
The root element is collection of test target definitions.
Each test target definition looks like this:

    {
      "name": "somelib",

      "client": {
        "command": ["somelib_client_executable"],
        "workdir": "somelib/bin",
        "protocols": ["binary"],
        "transports": ["buffered"],
        "sockets": ["ip"],
      },
      "server": {
        "command": ["somelib_server_executable"],
        "workdir": "somelib/bin",
        "protocols": ["binary"],
        "transports": ["buffered"],
        "sockets": ["ip", "ip-ssl"],
      }
    }

Either client or server definition or both should be present.

Parameters that are common to both `client` and `server` can be put to target
definition root:

    {
      "name": "somelib",

      "workdir": "somelib/bin",
      "protocols": ["binary"],
      "transports": ["buffered"],
      "sockets": ["ip"],

      "client": { "command": ["somelib_client_executable"] },
      "server": {
        "command": ["somelib_server_executable"],
        "sockets": ["ip-ssl"]
      }
    }

For the complete list of supported keys and their effect, see source code
comment at the opt of [crossrunner/collect.py](crossrunner/collect.py).


## List of known failures

Since many cross tests currently fail (mainly due to partial incompatibility
around exception handling), the test script specifically report for "not known
before" failures.

For this purpose, test cases known to (occasionally) fail are listed in
`known_failures_.json` where `` matches with python
`platform.system()` string.

Currently, only Linux version is included.

FYI, the file is initially generated by

    test/test.py --update-expected-failures=overwrite

after a full test run, then repeatedly

    test/test.py --skip-known-failures
    test/test.py --update-expected-failures=merge

to update the known failures, run

    make fail

## Test executable specification

### Command line parameters

Unit tests for languages are usually located under lib//test/
cross language tests according to [ThriftTest.thrift](ThriftTest.thrift) shall be
provided for every language including executables with the following command
line interface:

**Server command line interface:**

    $ ./TestServer -h
    Allowed options:
      -h | --help                  produce help message
      --port=arg (9090)            Port number to listen
      --domain-socket=arg          Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)
      --pipe=arg                   Windows Named Pipe (e.g. MyThriftPipe)
      --server-type=arg (simple)   type of server, "simple", "thread-pool",
                                   "threaded", or "nonblocking"
      --transport=arg (buffered)   transport: buffered, framed, http, anonpipe, zlib
      --protocol=arg (binary)      protocol: binary, compact, header, json
      --multiplex                  Add TMultiplexedProtocol service name "ThriftTest"
      --abstract-namespace         Create the domain socket in the Abstract Namespace 
                                   (no connection with filesystem pathnames)
      --ssl                        Encrypted Transport using SSL
      --zlib                       Wrapped Transport using Zlib
      --processor-events           processor-events
      -n=arg | --workers=arg (=4)  Number of thread pools workers. Only valid for
                                   thread-pool server type

**Client command line interface:**

    $ ./TestClient -h
    Allowed options:
      -h | --help                  produce help message
      --host=arg (localhost)       Host to connect
      --port=arg (9090)            Port number to connect
      --domain-socket=arg          Domain Socket (e.g. /tmp/ThriftTest.thrift),
                                   instead of host and port
      --pipe=arg                   Windows Named Pipe (e.g. MyThriftPipe)
      --anon-pipes hRead hWrite    Windows Anonymous Pipes pair (handles)
      --abstract-namespace         Create the domain socket in the Abstract Namespace
                                   (no connection with filesystem pathnames)
      --transport=arg (buffered)   Transport: buffered, framed, http, evhttp, zlib
      --protocol=arg (binary)      Protocol: binary, compact, header, json
      --multiplex                  Add TMultiplexedProtocol service name "ThriftTest"
      --ssl                        Encrypted Transport using SSL
      --zlib                       Wrap Transport with Zlib
      -n=arg | --testloops=arg (1) Number of Tests
      -t=arg | --threads=arg (1)   Number of Test threads

If you have executed the **make check** or **make cross** then you will be able to browse
[gen-html/ThriftTest.html](gen-html/ThriftTest.html) with the test documentation.

### Return code

The return code (exit code) shall be 0 on success, or an integer in the range 1 - 255 on errors.
In order to signal failed tests, the return code shall be composed from these bits to indicate
failing tests:

      #define TEST_BASETYPES     1  // 0000 0001
      #define TEST_STRUCTS       2  // 0000 0010
      #define TEST_CONTAINERS    4  // 0000 0100
      #define TEST_EXCEPTIONS    8  // 0000 1000
      #define TEST_UNKNOWN      64  // 0100 0000 (Failed to prepare environment etc.)
      #define TEST_TIMEOUT     128  // 1000 0000
      #define TEST_NOTUSED      48  // 0011 0000 (reserved bits)

Tests that have not been executed at all count as errors.

**Example:**

During tests, the test client notices that some of the Struct tests fail.
Furthermore, due to some other problem none of the Exception tests is executed.
Therefore, the test client returns the code `10 = 2 | 8`, indicating the failure
of both test 2 (TEST_STRUCTS) and test 8 (TEST_EXCEPTIONS).


## SSL
Test Keys and Certificates are provided in multiple formats under the following
directory [test/keys](keys)
thrift-0.23.0/test/crossrunner/0000775000175000017500000000000015167543515016734 5ustar00buildbuild00000000000000thrift-0.23.0/test/crossrunner/setup.cfg0000664000175000017500000000003715165535636020560 0ustar00buildbuild00000000000000[flake8]
max-line-length = 100
thrift-0.23.0/test/crossrunner/util.py0000664000175000017500000000221315165535636020264 0ustar00buildbuild00000000000000#
# 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 copy


def domain_socket_path(port):
    return '/tmp/ThriftTest.thrift.%d' % port


def merge_dict(base, update):
    """Update dict concatenating list values"""
    res = copy.deepcopy(base)
    for k, v in list(update.items()):
        if k in list(res.keys()) and isinstance(v, list):
            res[k].extend(v)
        else:
            res[k] = v
    return res
thrift-0.23.0/test/crossrunner/run.py0000664000175000017500000004102115167543515020110 0ustar00buildbuild00000000000000#
# 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 contextlib
import multiprocessing
import multiprocessing.managers
import os
import platform
import random
import socket
import subprocess
import sys
import time

from .report import ExecReporter, SummaryReporter
from .test import TestEntry
from .util import domain_socket_path

RESULT_ERROR = 64
RESULT_TIMEOUT = 128
SIGNONE = 0
SIGKILL = 15

# globals
ports = None
stop = None


class ExecutionContext(object):
    def __init__(self, cmd, cwd, env, stop_signal, is_server, report):
        self._log = multiprocessing.get_logger()
        self.cmd = cmd
        self.cwd = cwd
        self.env = env
        self.stop_signal = stop_signal
        self.is_server = is_server
        self.report = report
        self.expired = False
        self.killed = False
        self.proc = None

    def _popen_args(self):
        args = {
            'cwd': self.cwd,
            'env': self.env,
            'stdout': self.report.out,
            'stderr': subprocess.STDOUT,
        }
        # make sure child processes doesn't remain after killing
        if platform.system() == 'Windows':
            DETACHED_PROCESS = 0x00000008
            args.update(creationflags=DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP)
        else:
            args.update(preexec_fn=os.setsid)
        return args

    def start(self):
        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)
        self.report.begin()
        self.proc = subprocess.Popen(self.cmd, **self._popen_args())
        self._log.debug('    PID: %d', self.proc.pid)
        self._log.debug('   PGID: %d', os.getpgid(self.proc.pid))
        return self._scoped()

    @contextlib.contextmanager
    def _scoped(self):
        yield self
        if self.is_server:
            # the server is supposed to run until we stop it
            if self.returncode is not None:
                self.report.died()
            else:
                if self.stop_signal != SIGNONE:
                    if self.sigwait(self.stop_signal):
                        self.report.end(self.returncode)
                    else:
                        self.report.killed()
                else:
                    self.sigwait(SIGKILL)
        else:
            # the client is supposed to exit normally
            if self.returncode is not None:
                self.report.end(self.returncode)
            else:
                self.sigwait(SIGKILL)
                self.report.killed()
        self._log.debug('[{0}] exited with return code {1}'.format(self.proc.pid, self.returncode))

    # Send a signal to the process and then wait for it to end
    # If the signal requested is SIGNONE, no signal is sent, and
    # instead we just wait for the process to end; further if it
    # does not end normally with SIGNONE, we mark it as expired.
    # If the process fails to end and the signal is not SIGKILL,
    # it re-runs with SIGKILL so that a real process kill occurs
    # returns True if the process ended, False if it may not have
    def sigwait(self, sig=SIGKILL, timeout=2):
        try:
            if sig != SIGNONE:
                self._log.debug('[{0}] send signal {1}'.format(self.proc.pid, sig))
                if sig == SIGKILL:
                    self.killed = True
                try:
                    if platform.system() != 'Windows':
                        os.killpg(os.getpgid(self.proc.pid), sig)
                    else:
                        self.proc.send_signal(sig)
                except Exception:
                    self._log.info('[{0}] Failed to kill process'.format(self.proc.pid), exc_info=sys.exc_info())
            self._log.debug('[{0}] wait begin, timeout {1} sec(s)'.format(self.proc.pid, timeout))
            self.proc.communicate(timeout=timeout)
            self._log.debug('[{0}] process ended with return code {1}'.format(self.proc.pid, self.returncode))
            self.report.end(self.returncode)
            return True
        except subprocess.TimeoutExpired:
            self._log.info('[{0}] timeout waiting for process to end'.format(self.proc.pid))
            if sig == SIGNONE:
                self.expired = True
            return False if sig == SIGKILL else self.sigwait(SIGKILL, 1)

    # called on the client process to wait for it to end naturally
    def wait(self, timeout):
        self.sigwait(SIGNONE, timeout)

    @property
    def returncode(self):
        return self.proc.returncode if self.proc else None


def exec_context(port, logdir, test, prog, is_server):
    report = ExecReporter(logdir, test, prog)
    prog.build_command(port)
    return ExecutionContext(prog.command, prog.workdir, prog.env, prog.stop_signal, is_server, report)


def run_test(testdir, logdir, test_dict, max_retry, async_mode=True):
    logger = multiprocessing.get_logger()

    def ensure_socket_open(sv, port, test):
        slept = 0.1
        time.sleep(slept)
        sleep_step = 0.1
        while True:
            if slept > test.delay:
                logger.warn('[{0}] slept for {1} seconds but server is not open'.format(sv.proc.pid, slept))
                return False
            if test.socket == 'domain':
                if not os.path.exists(domain_socket_path(port)):
                    logger.debug('[{0}] domain(unix) socket not available yet. slept for {1} seconds so far'.format(sv.proc.pid, slept))
                    time.sleep(sleep_step)
                    slept += sleep_step
            elif test.socket == 'abstract':
                return True
            else:
                # Create sockets every iteration because refused sockets cannot be
                # reused on some systems.
                sock4 = socket.socket()
                sock6 = socket.socket(family=socket.AF_INET6)
                try:
                    if sock4.connect_ex(('127.0.0.1', port)) == 0 \
                            or sock6.connect_ex(('::1', port)) == 0:
                        return True
                    if sv.proc.poll() is not None:
                        logger.warn('[{0}] server process is exited'.format(sv.proc.pid))
                        return False
                    logger.debug('[{0}] socket not available yet. slept for {1} seconds so far'.format(sv.proc.pid, slept))
                    time.sleep(sleep_step)
                    slept += sleep_step
                finally:
                    sock4.close()
                    sock6.close()
            logger.debug('[{0}] server ready - waited for {1} seconds'.format(sv.proc.pid, slept))
            return True

    try:
        max_bind_retry = 3
        retry_count = 0
        bind_retry_count = 0
        test = TestEntry(testdir, **test_dict)
        while True:
            if stop.is_set():
                logger.debug('Skipping because shutting down')
                return (retry_count, None)
            logger.debug('Start')
            with PortAllocator.alloc_port_scoped(ports, test.socket) as port:
                logger.debug('Start with port %d' % port)
                sv = exec_context(port, logdir, test, test.server, True)
                cl = exec_context(port, logdir, test, test.client, False)

                logger.debug('Starting server')
                with sv.start():
                    port_ok = ensure_socket_open(sv, port, test)
                    if port_ok:
                        connect_retry_count = 0
                        max_connect_retry = 12
                        connect_retry_wait = 0.25
                        while True:
                            if sv.proc.poll() is not None:
                                logger.info('not starting client because server process is absent')
                                break
                            logger.debug('Starting client')
                            cl.start()
                            logger.debug('Waiting client (up to %d secs)' % test.timeout)
                            cl.wait(test.timeout)
                            if not cl.report.maybe_false_positive() or connect_retry_count >= max_connect_retry:
                                if connect_retry_count > 0 and connect_retry_count < max_connect_retry:
                                    logger.info('[%s]: Connected after %d retry (%.2f sec each)' % (test.server.name, connect_retry_count, connect_retry_wait))
                                # Wait for 50ms to see if server does not die at the end.
                                time.sleep(0.05)
                                break
                            logger.debug('Server may not be ready, waiting %.2f second...' % connect_retry_wait)
                            time.sleep(connect_retry_wait)
                            connect_retry_count += 1

            if sv.report.maybe_false_positive() and bind_retry_count < max_bind_retry:
                logger.warn('[%s]: Detected socket bind failure, retrying...', test.server.name)
                bind_retry_count += 1
            else:
                result = RESULT_TIMEOUT if cl.expired else cl.returncode if (cl.proc and cl.proc.poll()) is not None else RESULT_ERROR

                # For servers that handle a controlled shutdown by signal
                # if they are killed, or return an error code, that is a
                # problem.  For servers that are not signal-aware, we simply
                # kill them off; if we didn't kill them off, something else
                # happened (crashed?)
                if test.server.stop_signal != 0:
                    # for bash scripts, 128+N is the exit code for signal N, since we are sending
                    # DEFAULT_SIGNAL=1, 128 + 1 is the expected err code
                    # http://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
                    allowed_return_code = set([-1, 0, 128 + 1])
                    if sv.killed or sv.returncode not in allowed_return_code:
                        result |= RESULT_ERROR
                else:
                    if not sv.killed:
                        result |= RESULT_ERROR

                if result == 0 or retry_count >= max_retry:
                    return (retry_count, result)
                else:
                    logger.info('[%s-%s]: test failed, retrying...', test.server.name, test.client.name)
                    retry_count += 1
    except Exception:
        if not async_mode:
            raise
        logger.warn('Error executing [%s]', test.name, exc_info=True)
        return (retry_count, RESULT_ERROR)
    except Exception:
        logger.info('Interrupted execution', exc_info=True)
        if not async_mode:
            raise
        stop.set()
        return (retry_count, RESULT_ERROR)


class PortAllocator(object):
    def __init__(self):
        self._log = multiprocessing.get_logger()
        self._lock = multiprocessing.Lock()
        self._ports = set()
        self._dom_ports = set()
        self._last_alloc = 0

    def _get_tcp_port(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind(('', 0))
        port = sock.getsockname()[1]
        self._lock.acquire()
        try:
            ok = port not in self._ports
            if ok:
                self._ports.add(port)
                self._last_alloc = time.time()
        finally:
            self._lock.release()
            sock.close()
        return port if ok else self._get_tcp_port()

    def _get_domain_port(self):
        port = random.randint(1024, 65536)
        self._lock.acquire()
        try:
            ok = port not in self._dom_ports
            if ok:
                self._dom_ports.add(port)
        finally:
            self._lock.release()
        return port if ok else self._get_domain_port()

    def alloc_port(self, socket_type):
        if socket_type in ('domain', 'abstract', 'domain-socketactivated'):
            return self._get_domain_port()
        else:
            return self._get_tcp_port()

    # static method for inter-process invokation
    @staticmethod
    @contextlib.contextmanager
    def alloc_port_scoped(allocator, socket_type):
        port = allocator.alloc_port(socket_type)
        yield port
        allocator.free_port(socket_type, port)

    def free_port(self, socket_type, port):
        self._log.debug('free_port')
        self._lock.acquire()
        try:
            if socket_type in ['domain', 'domain-socketactivated']:
                self._dom_ports.remove(port)
                path = domain_socket_path(port)
                if os.path.exists(path):
                    os.remove(path)
            elif socket_type == 'abstract':
                self._dom_ports.remove(port)
            else:
                self._ports.remove(port)
        except IOError:
            self._log.info('Error while freeing port', exc_info=sys.exc_info())
        finally:
            self._lock.release()


class NonAsyncResult(object):
    def __init__(self, value):
        self._value = value

    def get(self, timeout=None):
        return self._value

    def wait(self, timeout=None):
        pass

    def ready(self):
        return True

    def successful(self):
        return self._value == 0


class TestDispatcher(object):
    def __init__(self, testdir, basedir, logdir_rel, concurrency):
        self._log = multiprocessing.get_logger()
        self.testdir = testdir
        self._report = SummaryReporter(basedir, logdir_rel, concurrency > 1)
        self.logdir = self._report.testdir
        # seems needed for python 2.x to handle keyboard interrupt
        self._stop = multiprocessing.Event()
        self._async = concurrency > 1
        if not self._async:
            self._pool = None
            global stop
            global ports
            stop = self._stop
            ports = PortAllocator()
        else:
            self._m = multiprocessing.managers.BaseManager()
            self._m.register('ports', PortAllocator)
            self._m.start()
            self._pool = multiprocessing.Pool(concurrency, TestDispatcher._pool_init, (self._m.address, self._stop))
        self._log.debug(
            'TestDispatcher started with %d concurrent jobs' % concurrency)

    @staticmethod
    def _pool_init(address, stop_event):
        global stop
        global m
        global ports
        stop = stop_event
        m = multiprocessing.managers.BaseManager(address)
        m.register('ports')
        m.connect()
        ports = m.ports()

    def _dispatch_sync(self, test, cont, max_retry):
        r = run_test(self.testdir, self.logdir, test, max_retry, async_mode=False)
        cont(r)
        return NonAsyncResult(r)

    def _dispatch_async(self, test, cont, max_retry):
        self._log.debug('_dispatch_async')
        return self._pool.apply_async(func=run_test, args=(self.testdir, self.logdir, test, max_retry), callback=cont)

    def dispatch(self, test, max_retry):
        index = self._report.add_test(test)

        def cont(result):
            if not self._stop.is_set():
                if result and len(result) == 2:
                    retry_count, returncode = result
                else:
                    retry_count = 0
                    returncode = RESULT_ERROR
                self._log.debug('freeing port')
                self._log.debug('adding result')
                self._report.add_result(index, returncode, returncode == RESULT_TIMEOUT, retry_count)
                self._log.debug('finish continuation')
        fn = self._dispatch_async if self._async else self._dispatch_sync
        return fn(test, cont, max_retry)

    def wait(self):
        if self._async:
            self._pool.close()
            self._pool.join()
            self._m.shutdown()
        return self._report.end()

    def terminate(self):
        self._stop.set()
        if self._async:
            self._pool.terminate()
            self._pool.join()
            self._m.shutdown()
thrift-0.23.0/test/crossrunner/report.py0000664000175000017500000004076015167543515020630 0ustar00buildbuild00000000000000#
# 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 datetime
import json
import multiprocessing
import os
import platform
import re
import subprocess
import sys
import time
import traceback

from .test import TestEntry

LOG_DIR = 'log'
RESULT_HTML = 'index.html'
RESULT_JSON = 'results.json'
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
        for r in results:
            if not r[success_index]:
                yield TestEntry.get_name(*r)
    try:
        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')
        return False
    fails = collect_failures(results['results'])
    if not overwrite:
        known = load_known_failures(testdir)
        known.extend(fails)
        fails = known
    fails_json = json.dumps(sorted(set(fails)), indent=2, separators=(',', ': '))
    if save:
        with logfile_open(os.path.join(testdir, FAIL_JSON % platform.system()), 'w+') as fp:
            fp.write(fails_json)
        sys.stdout.write('Successfully updated known failures.\n')
    if out:
        sys.stdout.write(fails_json)
        sys.stdout.write('\n')
    return True


def load_known_failures(testdir):
    try:
        with logfile_open(os.path.join(testdir, FAIL_JSON % platform.system()), 'r') as fp:
            return json.load(fp)
    except IOError:
        return []


class TestReporter(object):
    # Unfortunately, standard library doesn't handle timezone well
    # DATETIME_FORMAT = '%a %b %d %H:%M:%S %Z %Y'
    DATETIME_FORMAT = '%a %b %d %H:%M:%S %Y'

    def __init__(self):
        self._log = multiprocessing.get_logger()
        self._lock = multiprocessing.Lock()

    @classmethod
    def test_logfile(cls, test_name, prog_kind, dir=None):
        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()

    @property
    def _elapsed(self):
        return time.time() - self._start_time

    @classmethod
    def _format_date(cls):
        return '%s' % datetime.datetime.now().strftime(cls.DATETIME_FORMAT)

    def _print_date(self):
        print(self._format_date(), file=self.out)

    def _print_bar(self, out=None):
        print(
            '===============================================================================',
            file=(out or self.out))

    def _print_exec_time(self):
        print('Test execution took {:.1f} seconds.'.format(self._elapsed), file=self.out)


class ExecReporter(TestReporter):
    def __init__(self, testdir, test, prog):
        super(ExecReporter, self).__init__()
        self._test = test
        self._prog = prog
        self.logpath = self.test_logfile(test.name, prog.kind, testdir)
        self.out = None

    def begin(self):
        self._start()
        self._open()
        if self.out and not self.out.closed:
            self._print_header()
        else:
            self._log.debug('Output stream is not available.')

    def end(self, returncode):
        self._lock.acquire()
        try:
            if self.out and not self.out.closed:
                self._print_footer(returncode)
                self._close()
                self.out = None
            else:
                self._log.debug('Output stream is not available.')
        finally:
            self._lock.release()

    def killed(self):
        print(file=self.out)
        print('Server process is successfully killed.', file=self.out)
        self.end(None)

    def died(self):
        print(file=self.out)
        print('*** Server process has died unexpectedly ***', file=self.out)
        self.end(None)

    _init_failure_exprs = {
        'server': list(map(re.compile, [
            '[Aa]ddress already in use',
            'Could not bind',
            'EADDRINUSE',
        ])),
        'client': list(map(re.compile, [
            '[Cc]onnection refused',
            'Could not connect to',
            'Could not open UNIX ',       # domain socket (rb)
            'ECONNREFUSED',
            'econnrefused',               # erl
            'CONNECTION-REFUSED-ERROR',   # cl
            'connect ENOENT',             # nodejs domain socket
            'No such file or directory',  # domain socket
            'Sockets.TcpClient.Connect',  # csharp
        ])),
    }

    def maybe_false_positive(self):
        """Searches through log file for socket bind error.
        Returns True if suspicious expression is found, otherwise False"""
        try:
            if self.out and not self.out.closed:
                self.out.flush()
            exprs = self._init_failure_exprs[self._prog.kind]

            def match(line):
                for expr in exprs:
                    if expr.search(line):
                        self._log.info("maybe false positive: %s" % line)
                        return True

            with logfile_open(self.logpath, 'r') as fp:
                if any(map(match, fp)):
                    return True
        except (KeyboardInterrupt, SystemExit):
            raise
        except Exception as ex:
            self._log.warn('[%s]: Error while detecting false positive: %s' % (self._test.name, str(ex)))
            self._log.info(traceback.print_exc())
        return False

    def _open(self):
        self.out = logfile_open(self.logpath, 'w+')

    def _close(self):
        self.out.close()

    def _print_header(self):
        self._print_date()
        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)
        self._print_bar()
        self.out.flush()

    def _print_footer(self, returncode=None):
        self._print_bar()
        if returncode is not None:
            print('Return code: %d (negative values indicate kill by signal)' % returncode, file=self.out)
        else:
            print('Process is killed.', file=self.out)
        self._print_exec_time()
        self._print_date()


class SummaryReporter(TestReporter):
    def __init__(self, basedir, testdir_relative, concurrent=True):
        super(SummaryReporter, self).__init__()
        self._basedir = basedir
        self._testdir_rel = testdir_relative
        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()
        self._revision = self._get_revision()
        self._tests = []
        if not os.path.exists(self.logdir):
            os.mkdir(self.logdir)
        self._known_failures = load_known_failures(self.testdir)
        self._unexpected_success = []
        self._flaky_success = []
        self._unexpected_failure = []
        self._expected_failure = []
        self._print_header()

    def __getstate__(self):
        """Prepare object for pickling - remove unpicklable file handle (Since Python 3.14)"""
        state = self.__dict__.copy()
        # Remove the unpicklable file handle
        state['out'] = None
        return state

    def __setstate__(self, state):
        """Restore object after unpickling - restore stdout"""
        self.__dict__.update(state)
        # Restore stdout (since that's what it was initialized to)
        self.out = sys.stdout

    @property
    def testdir(self):
        return os.path.join(self._basedir, self._testdir_rel)

    def _result_string(self, test):
        if test.success:
            if test.retry_count == 0:
                return 'success'
            elif test.retry_count == 1:
                return 'flaky(1 retry)'
            else:
                return 'flaky(%d retries)' % test.retry_count
        elif test.expired:
            return 'failure(timeout)'
        else:
            return 'failure(%d)' % test.returncode

    def _get_revision(self):
        p = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'],
                             cwd=self.testdir, stdout=subprocess.PIPE)
        out, _ = p.communicate()
        return out.strip()

    def _format_test(self, test, with_result=True):
        name = '%s-%s' % (test.server.name, test.client.name)
        trans = '%s-%s' % (test.transport, test.socket)
        if not with_result:
            return '{:24s}{:18s}{:25s}'.format(name[:23], test.protocol[:17], trans[:24])
        else:
            return '{:24s}{:18s}{:25s}{:s}\n'.format(name[:23], test.protocol[:17],
                                                     trans[:24], self._result_string(test))

    def _print_test_header(self):
        self._print_bar()
        print(
            '{:24s}{:18s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'),
            file=self.out)

    def _print_header(self):
        self._start()
        print('Apache Thrift - Integration Test Suite', file=self.out)
        self._print_date()
        self._print_test_header()

    def _print_unexpected_failure(self):
        if len(self._unexpected_failure) > 0:
            self.out.writelines([
                '*** Following %d failures were unexpected ***:\n' % len(self._unexpected_failure),
                'If it is introduced by you, please fix it before submitting the code.\n',
                # 'If not, please report at https://issues.apache.org/jira/browse/THRIFT\n',
            ])
            self._print_test_header()
            for i in self._unexpected_failure:
                self.out.write(self._format_test(self._tests[i]))
            self._print_bar()
        else:
            print('No unexpected failures.', file=self.out)

    def _print_flaky_success(self):
        if len(self._flaky_success) > 0:
            print(
                'Following %d tests were expected to cleanly succeed but needed retry:' % len(self._flaky_success),
                file=self.out)
            self._print_test_header()
            for i in self._flaky_success:
                self.out.write(self._format_test(self._tests[i]))
            self._print_bar()

    def _print_unexpected_success(self):
        if len(self._unexpected_success) > 0:
            print(
                'Following %d tests were known to fail but succeeded (maybe flaky):' % len(self._unexpected_success),
                file=self.out)
            self._print_test_header()
            for i in self._unexpected_success:
                self.out.write(self._format_test(self._tests[i]))
            self._print_bar()

    def _http_server_command(self, port):
        return 'python -m http.server %d' % port

    def _print_footer(self):
        fail_count = len(self._expected_failure) + len(self._unexpected_failure)
        self._print_bar()
        self._print_unexpected_success()
        self._print_flaky_success()
        self._print_unexpected_failure()
        self._write_html_data()
        self._assemble_log('unexpected failures', self._unexpected_failure)
        self._assemble_log('known failures', self._expected_failure)
        self.out.writelines([
            'You can browse results at:\n',
            '\tfile://%s/%s\n' % (self.testdir, RESULT_HTML),
            '# If you use Chrome, run:\n',
            '# \tcd %s\n#\t%s\n' % (self._basedir, self._http_server_command(8001)),
            '# then browse:\n',
            '# \thttp://localhost:%d/%s/\n' % (8001, self._testdir_rel),
            'Full log for each test is here:\n',
            '\ttest/log/server_client_protocol_transport_client.log\n',
            '\ttest/log/server_client_protocol_transport_server.log\n',
            '%d failed of %d tests in total.\n' % (fail_count, len(self._tests)),
        ])
        self._print_exec_time()
        self._print_date()

    def _render_result(self, test):
        return [
            test.server.name,
            test.client.name,
            test.protocol,
            test.transport,
            test.socket,
            test.success,
            test.as_expected,
            test.returncode,
            {
                'server': self.test_logfile(test.name, test.server.kind),
                'client': self.test_logfile(test.name, test.client.kind),
            },
        ]

    def _write_html_data(self):
        """Writes JSON data to be read by result html"""
        results = [self._render_result(r) for r in self._tests]
        with logfile_open(self.out_path, 'w+') as fp:
            fp.write(json.dumps({
                'date': self._format_date(),
                'revision': str(self._revision),
                'platform': self._platform,
                'duration': '{:.1f}'.format(self._elapsed),
                'results': results,
            }, indent=2))

    def _assemble_log(self, title, indexes):
        if len(indexes) > 0:
            def add_prog_log(fp, test, prog_kind):
                print('*************************** %s message ***************************' % prog_kind,
                      file=fp)
                path = self.test_logfile(test.name, prog_kind, self.testdir)
                if os.path.exists(path):
                    with logfile_open(path, 'r') as prog_fp:
                        print(prog_fp.read(), file=fp)
            filename = title.replace(' ', '_') + '.log'
            with logfile_open(os.path.join(self.logdir, filename), 'w+') as fp:
                for test in map(self._tests.__getitem__, indexes):
                    fp.write('TEST: [%s]\n' % test.name)
                    add_prog_log(fp, test, test.server.kind)
                    add_prog_log(fp, test, test.client.kind)
                    fp.write('**********************************************************************\n\n')
            print('%s are logged to %s/%s/%s' % (title.capitalize(), self._testdir_rel, LOG_DIR, filename))

    def end(self):
        self._print_footer()
        return len(self._unexpected_failure) == 0

    def add_test(self, test_dict):
        test = TestEntry(self.testdir, **test_dict)
        self._lock.acquire()
        try:
            if not self.concurrent:
                self.out.write(self._format_test(test, False))
                self.out.flush()
            self._tests.append(test)
            return len(self._tests) - 1
        finally:
            self._lock.release()

    def add_result(self, index, returncode, expired, retry_count):
        self._lock.acquire()
        try:
            failed = returncode is None or returncode != 0
            flaky = not failed and retry_count != 0
            test = self._tests[index]
            known = test.name in self._known_failures
            if failed:
                if known:
                    self._log.debug('%s failed as expected' % test.name)
                    self._expected_failure.append(index)
                else:
                    self._log.info('unexpected failure: %s' % test.name)
                    self._unexpected_failure.append(index)
            elif flaky and not known:
                self._log.info('unexpected flaky success: %s' % test.name)
                self._flaky_success.append(index)
            elif not flaky and known:
                self._log.info('unexpected success: %s' % test.name)
                self._unexpected_success.append(index)
            test.success = not failed
            test.returncode = returncode
            test.retry_count = retry_count
            test.expired = expired
            test.as_expected = known == failed
            if not self.concurrent:
                self.out.write(self._result_string(test) + '\n')
            else:
                self.out.write(self._format_test(test))
        finally:
            self._lock.release()
thrift-0.23.0/test/crossrunner/collect.py0000664000175000017500000001441015165535636020736 0ustar00buildbuild00000000000000#
# 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 platform
import re
from itertools import product

from .util import merge_dict
from .test import TestEntry

# Those keys are passed to execution as is.
# Note that there are keys other than these, namely:
# delay: After server is started, client start is delayed for the value
# (seconds).
# timeout: Test timeout after client is started (seconds).
# platforms: Supported platforms. Should match platform.system() value.
# protocols: list of supported protocols
# transports: list of supported transports
# sockets: list of supported sockets
#
# protocols and transports entries can be colon separated "spec:impl" pair
# (e.g. binary:accel) where test is run for any matching "spec" while actual
# argument passed to test executable is "impl".
# Otherwise "spec" is equivalent to "spec:spec" pair.
# (e.g. "binary" is equivalent to "binary:binary" in tests.json)
#
VALID_JSON_KEYS = [
    'name',  # name of the library, typically a language name
    'workdir',  # work directory where command is executed
    'command',  # test command
    'extra_args',  # args appended to command after other args are appended
    'remote_args',  # args added to the other side of the program
    'join_args',  # whether args should be passed as single concatenated string
    'env',  # additional environmental variable
]

DEFAULT_MAX_DELAY = 5
DEFAULT_SIGNAL = 1
DEFAULT_TIMEOUT = 5


def _collect_testlibs(config, server_match, client_match=[None]):
    """Collects server/client configurations from library configurations"""
    def expand_libs(config):
        for lib in config:
            sv = lib.pop('server', None)
            cl = lib.pop('client', None)
            yield lib, sv, cl

    def yield_testlibs(base_configs, configs, match):
        for base, conf in zip(base_configs, configs):
            if conf:
                if not match or base['name'] in match:
                    platforms = conf.get('platforms') or base.get('platforms')
                    if not platforms or platform.system() in platforms:
                        yield merge_dict(base, conf)

    libs, svs, cls = zip(*expand_libs(config))
    servers = list(yield_testlibs(libs, svs, server_match))
    clients = list(yield_testlibs(libs, cls, client_match))
    return servers, clients


def collect_features(config, match):
    res = list(map(re.compile, match))
    return list(filter(lambda c: any(map(lambda r: r.search(c['name']), res)), config))


def _do_collect_tests(servers, clients):
    def intersection(key, o1, o2):
        """intersection of two collections.
        collections are replaced with sets the first time"""
        def cached_set(o, key):
            v = o[key]
            if not isinstance(v, set):
                v = set(v)
                o[key] = v
            return v
        return cached_set(o1, key) & cached_set(o2, key)

    def intersect_with_spec(key, o1, o2):
        # store as set of (spec, impl) tuple
        def cached_set(o):
            def to_spec_impl_tuples(values):
                for v in values:
                    spec, _, impl = v.partition(':')
                    yield spec, impl or spec
            v = o[key]
            if not isinstance(v, set):
                v = set(to_spec_impl_tuples(set(v)))
                o[key] = v
            return v
        for spec1, impl1 in cached_set(o1):
            for spec2, impl2 in cached_set(o2):
                if spec1 == spec2:
                    name = impl1 if impl1 == impl2 else '%s-%s' % (impl1, impl2)
                    yield name, impl1, impl2

    def maybe_max(key, o1, o2, default):
        """maximum of two if present, otherwise default value"""
        v1 = o1.get(key)
        v2 = o2.get(key)
        return max(v1, v2) if v1 and v2 else v1 or v2 or default

    def filter_with_validkeys(o):
        ret = {}
        for key in VALID_JSON_KEYS:
            if key in o:
                ret[key] = o[key]
        return ret

    def merge_metadata(o, **ret):
        for key in VALID_JSON_KEYS:
            if key in o:
                ret[key] = o[key]
        return ret

    for sv, cl in product(servers, clients):
        for proto, proto1, proto2 in intersect_with_spec('protocols', sv, cl):
            for trans, trans1, trans2 in intersect_with_spec('transports', sv, cl):
                for sock in intersection('sockets', sv, cl):
                    yield {
                        'server': merge_metadata(sv, **{'protocol': proto1, 'transport': trans1}),
                        'client': merge_metadata(cl, **{'protocol': proto2, 'transport': trans2}),
                        'delay': maybe_max('delay', sv, cl, DEFAULT_MAX_DELAY),
                        'stop_signal': maybe_max('stop_signal', sv, cl, DEFAULT_SIGNAL),
                        'timeout': maybe_max('timeout', sv, cl, DEFAULT_TIMEOUT),
                        'protocol': proto,
                        'transport': trans,
                        'socket': sock
                    }


def _filter_entries(tests, regex):
    if regex:
        return filter(lambda t: re.search(regex, TestEntry.get_name(**t)), tests)
    return tests


def collect_cross_tests(tests_dict, server_match, client_match, regex):
    sv, cl = _collect_testlibs(tests_dict, server_match, client_match)
    return list(_filter_entries(_do_collect_tests(sv, cl), regex))


def collect_feature_tests(tests_dict, features_dict, server_match, feature_match, regex):
    sv, _ = _collect_testlibs(tests_dict, server_match)
    ft = collect_features(features_dict, feature_match)
    return list(_filter_entries(_do_collect_tests(sv, ft), regex))
thrift-0.23.0/test/crossrunner/test.py0000664000175000017500000001253015167543515020266 0ustar00buildbuild00000000000000#
# 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 copy
import multiprocessing
import os
import sys
from .util import merge_dict, domain_socket_path


class TestProgram(object):
    def __init__(self, kind, name, protocol, transport, socket, workdir, stop_signal, command, env=None,
                 extra_args=[], extra_args2=[], join_args=False, **kwargs):

        self.kind = kind
        self.name = name
        self.protocol = protocol
        self.transport = transport
        self.socket = socket
        self.workdir = workdir
        self.stop_signal = stop_signal
        self.command = None
        self._base_command = self._fix_cmd_path(command)
        if env:
            self.env = copy.copy(os.environ)
            self.env.update(env)
        else:
            self.env = os.environ
        self._extra_args = extra_args
        self._extra_args2 = extra_args2
        self._join_args = join_args

    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 = os.path.join(self.workdir, arg)
            return p if os.path.exists(p) else arg

        if cmd[0] == 'python':
            cmd[0] = sys.executable
        else:
            cmd[0] = abs_if_exists(cmd[0])
        return cmd

    def _socket_args(self, socket, port):
        support_socket_activation = self.kind == 'server' and sys.platform != "win32"
        return {
            'ip-ssl': ['--ssl'],
            'domain': ['--domain-socket=%s' % domain_socket_path(port)],
            'domain-socketactivated': (['--emulate-socketactivation'] if support_socket_activation else []) + ['--domain-socket=%s' % domain_socket_path(port)],
            'abstract': ['--abstract-namespace', '--domain-socket=%s' % domain_socket_path(port)],
        }.get(socket, None)

    def _transport_args(self, transport):
        return {
            'zlib': ['--zlib'],
        }.get(transport, None)

    def build_command(self, port):
        cmd = copy.copy(self._base_command)
        args = copy.copy(self._extra_args2)
        args.append('--protocol=' + self.protocol)
        args.append('--transport=' + self.transport)
        transport_args = self._transport_args(self.transport)
        if transport_args:
            args += transport_args
        socket_args = self._socket_args(self.socket, port)
        if socket_args:
            args += socket_args
        args.append('--port=%d' % port)
        if self._join_args:
            cmd.append('%s' % " ".join(args))
        else:
            cmd.extend(args)
        if self._extra_args:
            cmd.extend(self._extra_args)
        self.command = cmd
        return self.command


class TestEntry(object):
    def __init__(self, testdir, server, client, delay, timeout, **kwargs):
        self.testdir = testdir
        self._log = multiprocessing.get_logger()
        self._config = kwargs
        self.protocol = kwargs['protocol']
        self.transport = kwargs['transport']
        self.socket = kwargs['socket']
        srv_dict = self._fix_workdir(merge_dict(self._config, server))
        cli_dict = self._fix_workdir(merge_dict(self._config, client))
        cli_dict['extra_args2'] = srv_dict.pop('remote_args', [])
        srv_dict['extra_args2'] = cli_dict.pop('remote_args', [])
        self.server = TestProgram('server', **srv_dict)
        self.client = TestProgram('client', **cli_dict)
        self.delay = delay
        self.timeout = timeout
        self._name = None
        # results
        self.success = None
        self.as_expected = None
        self.returncode = None
        self.expired = False
        self.retry_count = 0

    def _fix_workdir(self, config):
        key = 'workdir'
        path = config.get(key, None)
        if not path:
            path = self.testdir
        if os.path.isabs(path):
            path = os.path.realpath(path)
        else:
            path = os.path.realpath(os.path.join(self.testdir, path))
        config.update({key: path})
        return config

    @classmethod
    def get_name(cls, server, client, protocol, transport, socket, *args, **kwargs):
        return '%s-%s_%s_%s-%s' % (server, client, protocol, transport, socket)

    @property
    def name(self):
        if not self._name:
            self._name = self.get_name(
                self.server.name, self.client.name, self.protocol, self.transport, self.socket)
        return self._name

    @property
    def transport_name(self):
        return '%s-%s' % (self.transport, self.socket)


def test_name(server, client, protocol, transport, socket, **kwargs):
    return TestEntry.get_name(server['name'], client['name'], protocol, transport, socket)
thrift-0.23.0/test/crossrunner/__init__.py0000664000175000017500000000175715165535636021062 0ustar00buildbuild00000000000000#
# 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 .test import test_name  # noqa
from .collect import collect_cross_tests, collect_feature_tests  # noqa
from .run import TestDispatcher  # noqa
from .report import generate_known_failures, load_known_failures  # noqa
thrift-0.23.0/test/php/0000775000175000017500000000000015170007175015127 5ustar00buildbuild00000000000000thrift-0.23.0/test/php/TestInline.php0000664000175000017500000000156715165535636017743 0ustar00buildbuild00000000000000/*
 * 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.
 */


thrift-0.23.0/test/php/TestServer.php0000664000175000017500000000530015170007142017736 0ustar00buildbuild00000000000000registerDefinition('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();
thrift-0.23.0/test/php/Client.php0000664000175000017500000000116715165535636017077 0ustar00buildbuild00000000000000registerDefinition('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();
thrift-0.23.0/test/php/TestClient.php0000775000175000017500000003201615167543515017734 0ustar00buildbuild00000000000000addPsr4('', $GEN_DIR);
} else {
  $loader = new ThriftClassLoader();
  $loader->registerDefinition('ThriftTest', $GEN_DIR);
  $loader->register();
}

/*
 * 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 the Thrift base */
/** Include the protocols */
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Protocol\TBinaryProtocolAccelerated;
use Thrift\Protocol\TCompactProtocol;
use Thrift\Protocol\TJSONProtocol;

/** Include the socket layer */
use Thrift\Transport\TSocket;
use Thrift\Transport\TSocketPool;

/** Include the socket layer */
use Thrift\Transport\TFramedTransport;
use Thrift\Transport\TBufferedTransport;

function makeProtocol($transport, $PROTO)
{
  if ($PROTO == 'binary') {
    return new TBinaryProtocol($transport);
  } else if ($PROTO == 'compact') {
    return new TCompactProtocol($transport);
  } else if ($PROTO == 'json') {
    return new TJSONProtocol($transport);
  } else if ($PROTO == 'accel') {
    if (!function_exists('thrift_protocol_write_binary')) {
      echo "Acceleration extension is not loaded\n";
      exit(1);
    }
    return new TBinaryProtocolAccelerated($transport);
  }

  echo "--protocol must be one of {binary|compact|json|accel}\n";
  exit(1);
}

$host = 'localhost';
$port = 9090;

if ($argc > 1) {
  $host = $argv[0];
}

if ($argc > 2) {
  $host = $argv[1];
}

foreach ($argv as $arg) {
  if (substr($arg, 0, 7) == '--port=') {
    $port = substr($arg, 7);
  } else if (substr($arg, 0, 12) == '--transport=') {
    $MODE = substr($arg, 12);
  } else if (substr($arg, 0, 11) == '--protocol=') {
    $PROTO = substr($arg, 11);
  }
}

$hosts = array('localhost');

$socket = new TSocket($host, $port);
$socket = new TSocketPool($hosts, $port);
$socket->setDebug(TRUE);

if ($MODE == 'inline') {
  $transport = $socket;
  $testClient = new \ThriftTest\ThriftTestClient($transport);
} else if ($MODE == 'framed') {
  $framedSocket = new TFramedTransport($socket);
  $transport = $framedSocket;
  $protocol = makeProtocol($transport, $PROTO);
  $testClient = new \ThriftTest\ThriftTestClient($protocol);
} else {
  $bufferedSocket = new TBufferedTransport($socket, 1024, 1024);
  $transport = $bufferedSocket;
  $protocol = makeProtocol($transport, $PROTO);
  $testClient = new \ThriftTest\ThriftTestClient($protocol);
}

$transport->open();

$start = microtime(true);

define('ERR_BASETYPES', 1);
define('ERR_STRUCTS', 2);
define('ERR_CONTAINERS', 4);
define('ERR_EXCEPTIONS', 8);
define('ERR_UNKNOWN', 64);
$exitcode = 0;
/**
 * VOID TEST
 */
print_r("testVoid()");
$testClient->testVoid();
print_r(" = void\n");

function roundtrip($testClient, $method, $value) {
  global $exitcode;
  print_r("$method($value)");
  $ret = $testClient->$method($value);
  print_r(" = \"$ret\"\n");
  if ($value !== $ret) {
    print_r("*** FAILED ***\n");
    $exitcode |= ERR_BASETYPES;
  }
}

/**
 * STRING TEST
 */
roundtrip($testClient, 'testString', "Test");

/**
 * BOOL TEST
 */
roundtrip($testClient, 'testBool', true);
roundtrip($testClient, 'testBool', false);

/**
 * BYTE TEST
 */
roundtrip($testClient, 'testByte', 1);
roundtrip($testClient, 'testByte', -1);
roundtrip($testClient, 'testByte', 127);
roundtrip($testClient, 'testByte', -128);

/**
 * I32 TEST
 */
roundtrip($testClient, 'testI32', -1);

/**
 * I64 TEST
 */
roundtrip($testClient, 'testI64', 0);
roundtrip($testClient, 'testI64', 1);
roundtrip($testClient, 'testI64', -1);
roundtrip($testClient, 'testI64', -34359738368);

/**
 * DOUBLE TEST
 */
roundtrip($testClient, 'testDouble', -852.234234234);

/**
 * BINARY TEST  --  TODO
 */

/**
 * UUID TEST
 */
print_r("testUuid('00000000-0000-0000-0000-000000000000')");
$uuid_in = '00000000-0000-0000-0000-000000000000';
$uuid_out = $testClient->testUuid($uuid_in);
print_r(" = \"$uuid_out\"\n");
if ($uuid_in !== $uuid_out) {
    echo "**FAILED**\n";
    $exitcode |= ERR_BASETYPES;
}

roundtrip($testClient, 'testUuid', '00000000-0000-0000-0000-000000000000');
roundtrip($testClient, 'testUuid', '550e8400-e29b-41d4-a716-446655440000');

/**
 * STRUCT TEST
 */
print_r("testStruct({\"Zero\", 1, -3, -5})");
$out = new \ThriftTest\Xtruct();
$out->string_thing = "Zero";
$out->byte_thing = 1;
$out->i32_thing = -3;
$out->i64_thing = -5;
$in = $testClient->testStruct($out);
print_r(" = {\"".$in->string_thing."\", ".
        $in->byte_thing.", ".
        $in->i32_thing.", ".
        $in->i64_thing."}\n");

if ($in != $out) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

/**
 * NESTED STRUCT TEST
 */
print_r("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
$out2 = new \ThriftTest\Xtruct2();
$out2->byte_thing = 1;
$out2->struct_thing = $out;
$out2->i32_thing = 5;
$in2 = $testClient->testNest($out2);
$in = $in2->struct_thing;
print_r(" = {".$in2->byte_thing.", {\"".
        $in->string_thing."\", ".
        $in->byte_thing.", ".
        $in->i32_thing.", ".
        $in->i64_thing."}, ".
        $in2->i32_thing."}\n");

if ($in2 != $out2) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

/**
 * MAP TEST
 */
$mapout = array();
for ($i = 0; $i < 5; ++$i) {
  $mapout[$i] = $i-10;
}
print_r("testMap({");
$first = true;
foreach ($mapout as $key => $val) {
  if ($first) {
    $first = false;
  } else {
    print_r(", ");
  }
  print_r("$key => $val");
}
print_r("})");

$mapin = $testClient->testMap($mapout);
print_r(" = {");
$first = true;
foreach ($mapin as $key => $val) {
  if ($first) {
    $first = false;
  } else {
    print_r(", ");
  }
  print_r("$key => $val");
}
print_r("}\n");

if ($mapin != $mapout) {
    echo "**FAILED**\n";
    $exitcode |= ERR_CONTAINERS;
}

$mapout = array();
for ($i = 0; $i < 10; $i++) {
    $mapout["key$i"] = "val$i";
}
print_r('testStringMap({');
$first = true;
foreach ($mapout as $key => $val) {
  if ($first) {
    $first = false;
  } else {
    print_r(", ");
  }
  print_r("\"$key\" => \"$val\"");
}
print_r("})");
$mapin = $testClient->testStringMap($mapout);
print_r(" = {");
$first = true;
foreach ($mapin as $key => $val) {
  if ($first) {
    $first = false;
  } else {
    print_r(", ");
  }
  print_r("\"$key\" => \"$val\"");
}
print_r("}\n");
ksort($mapin);
if ($mapin != $mapout) {
    echo "**FAILED**\n";
    $exitcode |= ERR_CONTAINERS;
}

/**
 * SET TEST
 */
$setout = array();;
for ($i = -2; $i < 3; ++$i) {
  $setout[$i]= true;
}
print_r("testSet({");
echo implode(',', array_keys($setout));
print_r("})");
$setin = $testClient->testSet($setout);
print_r(" = {");
echo implode(', ', array_keys($setin));
print_r("}\n");
// Order of keys in set does not matter
ksort($setin);
if ($setout !== $setin) {
    echo "**FAILED**\n";
    $exitcode |= ERR_CONTAINERS;
}
// Regression test for corrupted array
if ($setin[2] !== $setout[2] || is_int($setin[2])) {
    echo "**FAILED**\n";
    $exitcode |= ERR_CONTAINERS;
}

/**
 * LIST TEST
 */
$listout = array();
for ($i = -2; $i < 3; ++$i) {
  $listout []= $i;
}
print_r("testList({");
$first = true;
foreach ($listout as $val) {
  if ($first) {
    $first = false;
  } else {
    print_r(", ");
  }
  print_r($val);
}
print_r("})");
$listin = $testClient->testList($listout);
print_r(" = {");
$first = true;
foreach ($listin as $val) {
  if ($first) {
    $first = false;
  } else {
    print_r(", ");
  }
  print_r($val);
}
print_r("}\n");
if ($listin !== $listout) {
    echo "**FAILED**\n";
    $exitcode |= ERR_CONTAINERS;
}

/**
 * ENUM TEST
 */
print_r("testEnum(ONE)");
$ret = $testClient->testEnum(\ThriftTest\Numberz::ONE);
print_r(" = $ret\n");
if ($ret != \ThriftTest\Numberz::ONE) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

print_r("testEnum(TWO)");
$ret = $testClient->testEnum(\ThriftTest\Numberz::TWO);
print_r(" = $ret\n");
if ($ret != \ThriftTest\Numberz::TWO) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

print_r("testEnum(THREE)");
$ret = $testClient->testEnum(\ThriftTest\Numberz::THREE);
print_r(" = $ret\n");
if ($ret != \ThriftTest\Numberz::THREE) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

print_r("testEnum(FIVE)");
$ret = $testClient->testEnum(\ThriftTest\Numberz::FIVE);
print_r(" = $ret\n");
if ($ret != \ThriftTest\Numberz::FIVE) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

print_r("testEnum(EIGHT)");
$ret = $testClient->testEnum(\ThriftTest\Numberz::EIGHT);
print_r(" = $ret\n");
if ($ret != \ThriftTest\Numberz::EIGHT) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

/**
 * TYPEDEF TEST
 */
print_r("testTypedef(309858235082523)");
$uid = $testClient->testTypedef(309858235082523);
print_r(" = $uid\n");
if ($uid !== 309858235082523) {
    echo "**FAILED**\n";
    $exitcode |= ERR_STRUCTS;
}

/**
 * NESTED MAP TEST
 */
print_r("testMapMap(1)");
$mm = $testClient->testMapMap(1);
print_r(" = {");
foreach ($mm as $key => $val) {
  print_r("$key => {");
  foreach ($val as $k2 => $v2) {
    print_r("$k2 => $v2, ");
  }
  print_r("}, ");
}
print_r("}\n");
$expected_mm = [
  -4 => [-4 => -4, -3 => -3, -2 => -2, -1 => -1],
  4 => [4 => 4, 3 => 3, 2 => 2, 1 => 1],
];
if ($mm != $expected_mm) {
    echo "**FAILED**\n";
    $exitcode |= ERR_CONTAINERS;
}

/**
 * INSANITY TEST
 */
$insane = new \ThriftTest\Insanity();
$insane->userMap[\ThriftTest\Numberz::FIVE] = 5000;
$truck = new \ThriftTest\Xtruct();
$truck->string_thing = "Truck";
$truck->byte_thing = 8;
$truck->i32_thing = 8;
$truck->i64_thing = 8;
$insane->xtructs []= $truck;
print_r("testInsanity()");
$whoa = $testClient->testInsanity($insane);
print_r(" = {");
foreach ($whoa as $key => $val) {
  print_r("$key => {");
  foreach ($val as $k2 => $v2) {
    print_r("$k2 => {");
    $userMap = $v2->userMap;
    print_r("{");
    if (is_array($userMap)) {
      foreach ($userMap as $k3 => $v3) {
        print_r("$k3 => $v3, ");
      }
    }
    print_r("}, ");

    $xtructs = $v2->xtructs;
    print_r("{");
    if (is_array($xtructs)) {
      foreach ($xtructs as $x) {
        print_r("{\"".$x->string_thing."\", ".
                $x->byte_thing.", ".$x->i32_thing.", ".$x->i64_thing."}, ");
      }
    }
    print_r("}");

    print_r("}, ");
  }
  print_r("}, ");
}
print_r("}\n");

/**
 * EXCEPTION TEST
 */
print_r("testException('Xception')");
try {
  $testClient->testException('Xception');
  print_r("  void\nFAILURE\n");
  $exitcode |= ERR_EXCEPTIONS;
} catch (\ThriftTest\Xception $x) {
  print_r(' caught xception '.$x->errorCode.': '.$x->message."\n");
}

// Regression test for THRIFT-4263
print_r("testBinarySerializer_Deserialize('foo')");
try {
  \Thrift\Serializer\TBinarySerializer::deserialize(base64_decode('foo'), \ThriftTest\Xtruct2::class);
  echo "**FAILED**\n";
  $exitcode |= ERR_STRUCTS;
} catch (\Thrift\Exception\TTransportException $happy_exception) {
  // We expected this due to binary data of base64_decode('foo') is less then 4
  // bytes and it tries to find thrift version number in the transport by
  // reading i32() at the beginning.  Casting to string validates that
  // exception is still accessible in memory and not corrupted.  Without patch,
  // PHP will error log that the exception doesn't have any tostring method,
  // which is a lie due to corrupted memory.
  for($i=99; $i > 0; $i--) {
    (string)$happy_exception;
  }
  print_r("  SUCCESS\n");
}

/**
 * Normal tests done.
 */

$stop = microtime(true);
$elp = round(1000*($stop - $start), 0);
print_r("Total time: $elp ms\n");

/**
 * Extraneous "I don't trust PHP to pack/unpack integer" tests
 */

if ($protocol instanceof TBinaryProtocolAccelerated) {
    // Regression check: check that method name is not double-freed
    // Method name should not be an interned string.
    $method_name = "Void";
    $method_name = "test$method_name";

    $seqid = 0;
    $args = new \ThriftTest\ThriftTest_testVoid_args();
    thrift_protocol_write_binary($protocol, $method_name, \Thrift\Type\TMessageType::CALL, $args, $seqid, $protocol->isStrictWrite());
    $testClient->recv_testVoid();

}

// Max I32
$num = pow(2, 30) + (pow(2, 30) - 1);
roundtrip($testClient, 'testI32', $num);

// Min I32
$num = 0 - pow(2, 31);
roundtrip($testClient, 'testI32', $num);

// Max I64
$num = pow(2, 62) + (pow(2, 62) - 1);
roundtrip($testClient, 'testI64', $num);

// Min I64
$num = 0 - pow(2, 62) - pow(2, 62);
roundtrip($testClient, 'testI64', $num);

$transport->close();
exit($exitcode);
thrift-0.23.0/test/php/TestClassmap.php0000664000175000017500000000155515165535636020265 0ustar00buildbuild00000000000000/*
 * 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.
 */


thrift-0.23.0/test/php/test_php.ini0000664000175000017500000000010715170007142017446 0ustar00buildbuild00000000000000;extension=thrift_protocol.so
;extension=json.so
;extension=sockets.so
thrift-0.23.0/test/php/Makefile0000644000175000017500000004503115170007175016570 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/php/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#
# 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.
#

am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
subdir = test/php
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = /thrift/src/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/php
abs_srcdir = /thrift/src/test/php
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..
all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/php/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/php/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am dist-hook distclean \
	distclean-generic distclean-libtool distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: ../ThriftTest.thrift
	$(THRIFT) --gen php ../ThriftTest.thrift
	$(THRIFT) --gen php:inlined ../ThriftTest.thrift
	$(MKDIR_P) gen-php-classmap
	$(THRIFT) -out gen-php-classmap --gen php:classmap ../ThriftTest.thrift

php_ext_dir:
	mkdir -p php_ext_dir
	ln -s ../../../lib/php/src/ext/thrift_protocol/modules/thrift_protocol.so php_ext_dir/
	ln -s "$$(php-config --extension-dir)/json.so" php_ext_dir/
	ln -s "$$(php-config --extension-dir)/sockets.so" php_ext_dir/

precross: stubs php_ext_dir

check: stubs php_ext_dir

clean-local:
	$(RM) -r gen-*/
	$(RM) -r php_ext_dir

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

dist-hook:
	$(RM) -r $(distdir)/gen-*/
	$(RM) -r $(distdir)/php_ext_dir/

client: stubs php_ext_dir
	php TestClient.php

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/php/Makefile.in0000644000175000017500000004377115170007167017207 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/php
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/php/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/php/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am dist-hook distclean \
	distclean-generic distclean-libtool distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: ../ThriftTest.thrift
	$(THRIFT) --gen php ../ThriftTest.thrift
	$(THRIFT) --gen php:inlined ../ThriftTest.thrift
	$(MKDIR_P) gen-php-classmap
	$(THRIFT) -out gen-php-classmap --gen php:classmap ../ThriftTest.thrift

php_ext_dir:
	mkdir -p php_ext_dir
	ln -s ../../../lib/php/src/ext/thrift_protocol/modules/thrift_protocol.so php_ext_dir/
	ln -s "$$(php-config --extension-dir)/json.so" php_ext_dir/
	ln -s "$$(php-config --extension-dir)/sockets.so" php_ext_dir/

precross: stubs php_ext_dir

check: stubs php_ext_dir

clean-local:
	$(RM) -r gen-*/
	$(RM) -r php_ext_dir

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

dist-hook:
	$(RM) -r $(distdir)/gen-*/
	$(RM) -r $(distdir)/php_ext_dir/

client: stubs php_ext_dir
	php TestClient.php

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/php/Handler.php0000664000175000017500000000366415170007142017220 0ustar00buildbuild00000000000000 Main(string[] args)
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                try
                {
                    Console.SetBufferSize(Console.BufferWidth, 4096);
                }
                catch (Exception)
                {
                    Console.WriteLine("Failed to grow scroll-back buffer");
                }
            }

            // run whatever mode is choosen, default to test impl
            var argslist = new List(args);
            switch (argslist.FirstOrDefault())
            {
                case "client":  // crosstest wants to pass this, so just emit a hint and ignore
                    Console.WriteLine("Hint: The 'client' argument is no longer required.");
                    argslist.RemoveAt(0);
                    return await TestClient.Execute(argslist);
                case "--performance":
                case "--performance-test":
                    return await Tests.PerformanceTests.Execute();
                case "--help":
                    PrintHelp();
                    return 0;
                default:
                    return await TestClient.Execute(argslist);
            }
        }

        private static void PrintHelp()
        {
            Console.WriteLine("Usage:");
            Console.WriteLine("  Client  [options]");
            Console.WriteLine("  Client  --performance-test");
            Console.WriteLine("  Client  --help");
            Console.WriteLine("");

            TestClient.PrintOptionsHelp();
        }
    }
}
thrift-0.23.0/test/netstd/Client/Performance/0000775000175000017500000000000015165535636021334 5ustar00buildbuild00000000000000thrift-0.23.0/test/netstd/Client/Performance/PerformanceTests.cs0000664000175000017500000001310715165535636025151 0ustar00buildbuild00000000000000// 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 ThriftTest;
using Thrift.Collections;
using Thrift;
using Thrift.Protocol;
using System.Threading;
using Thrift.Transport.Client;
using System.Threading.Tasks;
using System.Diagnostics;
using Thrift.Transport;

namespace Client.Tests
{
    public class PerformanceTests
    {
        private CancellationTokenSource Cancel = new();
        private CrazyNesting? Testdata;
        private TMemoryBufferTransport? MemBuffer;
        private TTransport? Transport;
        private LayeredChoice Layered;
        private readonly TConfiguration Configuration = new();

        internal static async Task Execute()
        {
            var instance = new PerformanceTests();
            await instance.ProtocolPeformanceTestAsync();

            // debug only
            if (Debugger.IsAttached)
            {
                Console.Write("Hit ENTER ...");
                Console.ReadKey();
            }

            return 0;
        }

        public PerformanceTests()
        {
            Configuration.MaxFrameSize = Configuration.MaxMessageSize;  // default frame size is too small for this test
        }

        private async Task ProtocolPeformanceTestAsync()
        {
            Console.WriteLine("Setting up for ProtocolPeformanceTestAsync ...");
            Cancel = new CancellationTokenSource();
            Testdata = TestDataFactory.CreateCrazyNesting();

            foreach (var layered in Enum.GetValues(typeof(LayeredChoice)))
            {
                Layered = (LayeredChoice)layered;
                await RunTestAsync(async (bool b) => { return await GenericProtocolFactory(b); });
                await RunTestAsync(async (bool b) => { return await GenericProtocolFactory(b); });
                await RunTestAsync(async (bool b) => { return await GenericProtocolFactory(b); });
            }
        }

        private async Task GenericProtocolFactory(bool forWrite)
            where T : TProtocol
        {
            var oldTrans = Transport;
            try
            {
                Transport = null;

                // read happens after write here, so let's take over the written bytes
                if (forWrite)
                    MemBuffer = new TMemoryBufferTransport(Configuration);  
                else
                    MemBuffer = new TMemoryBufferTransport(MemBuffer?.GetBuffer(), Configuration);

                //  layered transports anyone?
                Transport = Layered switch
                {
                    LayeredChoice.None => MemBuffer,
                    LayeredChoice.Framed => new TFramedTransport(MemBuffer),
                    LayeredChoice.Buffered => new TBufferedTransport(MemBuffer),
                    _ => throw new Exception("Unhandled case " + Layered.ToString()),
                };
                ;

                if (!Transport.IsOpen)
                    await Transport.OpenAsync();

                if (Activator.CreateInstance(typeof(T), Transport) is T instance)
                    return instance;

                throw new Exception("Unexpected.");
            }
            finally
            {
                oldTrans?.Dispose();
            }
        }

        private string GetProtocolTransportName(TProtocol proto)
        {
            var name = Transport?.GetType().Name;
            var bufnm = MemBuffer?.GetType().Name;
            if ((name is null) || name.Equals(bufnm))
                name = string.Empty;
            else
                name = " + " + name;

            name = proto.GetType().Name + name;
            return name;
        }


        private async Task RunTestAsync(Func> factory)
        {
            var stop = new Stopwatch();

            if (Testdata is null)
                throw new Exception("unexpected internal state");

            var proto = await factory(true);
            if (Transport is null)
                throw new Exception("unexpected internal state");
            stop.Start();
            await Testdata.WriteAsync(proto, Cancel.Token);
            await Transport.FlushAsync(Cancel.Token);
            stop.Stop();
            Console.WriteLine("RunTestAsync({0}): write = {1} msec",
                GetProtocolTransportName(proto),
                stop.ElapsedMilliseconds);

            var restored = new CrazyNesting();
            proto = await factory(false);
            if (Transport is null)
                throw new Exception("unexpected internal state");
            stop.Start();
            await restored.ReadAsync(proto, Cancel.Token);
            stop.Stop();
            Console.WriteLine("RunTestAsync({0}): read = {1} msec",
                GetProtocolTransportName(proto),
                stop.ElapsedMilliseconds);
        }

    }
}
thrift-0.23.0/test/netstd/Client/Performance/TestDataFactory.cs0000664000175000017500000001275415165535636024735 0ustar00buildbuild00000000000000// 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 ThriftTest;
using Thrift.Collections;

namespace Client.Tests
{
    
    static class TestDataFactory
    {
        public static CrazyNesting? CreateCrazyNesting(int count = 10)
        {
            if (count <= 0)
                return null;

            return new CrazyNesting()
            {
                Binary_field = CreateBytesArray(count),
                List_field = CreateListField(count),
                Set_field = CreateSetField(count),
                String_field = string.Format("data level {0}", count)
            };
        }

        private static HashSet CreateSetField(int count)
        {
            var retval = new HashSet();
            for (var i = 0; i < count; ++i)
                retval.Add(CreateInsanity(count));
            return retval;
        }

        private static Insanity CreateInsanity(int count)
        {
            return new Insanity()
            {
                UserMap = CreateUserMap(count),
                Xtructs = CreateXtructs(count)
            };
        }

        private static List CreateXtructs(int count)
        {
            var retval = new List();
            for (var i = 0; i < count; ++i)
                retval.Add(CreateXtruct(count));
            return retval;
        }

        private static Xtruct CreateXtruct(int count)
        {
            return new Xtruct()
            {
                Byte_thing = (sbyte)(count % 128),
                I32_thing = count,
                I64_thing = count,
                String_thing = string.Format("data level {0}", count)
            };
        }

        private static Dictionary CreateUserMap(int count)
        {
            var retval = new Dictionary
            {
                { Numberz.ONE, count },
                { Numberz.TWO, count },
                { Numberz.THREE, count },
                { Numberz.FIVE, count },
                { Numberz.SIX, count },
                { Numberz.EIGHT, count }
            };
            return retval;
        }

        private static List, Dictionary>>>>> CreateListField(int count)
        {
            var retval = new List, Dictionary>>>>>();
            for (var i = 0; i < count; ++i)
                retval.Add(CreateListFieldData(count));
            return retval;
        }

        private static Dictionary, Dictionary>>>> CreateListFieldData(int count)
        {
            var retval = new Dictionary, Dictionary>>>>();
            for (var i = 0; i < count; ++i)
                retval.Add( CreateIntHashSet(count), CreateListFieldDataDict(count));
            return retval;
        }

        private static HashSet CreateIntHashSet(int count)
        {
            var retval = new HashSet();
            for (var i = 0; i < count; ++i)
                retval.Add(i);
            return retval;
        }

        private static Dictionary>>> CreateListFieldDataDict(int count)
        {
            var retval = new Dictionary>>>();
            for (var i = 0; i < count; ++i)
                retval.Add(i, CreateListFieldDataDictValue(count));
            return retval;
        }

        private static HashSet>> CreateListFieldDataDictValue(int count)
        {
            var retval = new HashSet>>();
            for (var i = 0; i < count; ++i)
                retval.Add( CreateListFieldDataDictValueList(count));
            return retval;
        }

        private static List> CreateListFieldDataDictValueList(int count)
        {
            var retval = new List>();
            for (var i = 0; i < count; ++i)
                retval.Add(CreateListFieldDataDictValueListDict(count));
            return retval;
        }

        private static Dictionary CreateListFieldDataDictValueListDict(int count)
        {
            return new Dictionary
            {
                { CreateInsanity(count), string.Format("data level {0}", count) }
            };
        }

        private static byte[] CreateBytesArray(int count)
        {
            var retval = new byte[count];
            for (var i = 0; i < count; ++i)
                retval[i] = (byte)(i % 0xFF);
            return retval;
        }
    }
}
thrift-0.23.0/test/netstd/Client/TestClient.cs0000664000175000017500000011247615165535636021513 0ustar00buildbuild00000000000000// 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.

#pragma warning disable IDE0066 // switch expression
#pragma warning disable IDE0057 // substring

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Thrift;
using Thrift.Collections;
using Thrift.Protocol;
using Thrift.Transport;
using Thrift.Transport.Client;

namespace ThriftTest
{
    internal enum ProtocolChoice
    {
        Binary,
        Compact,
        Json
    }

    // it does not make much sense to use buffered when we already use framed
    internal enum LayeredChoice
    {
        None,
        Buffered,
        Framed
    }

    internal enum TransportChoice
    {
        Socket,
        TlsSocket,
        Http,
        NamedPipe
    }

    public class TestClient
    {
        private class TestParams
        {
            public int numIterations = 1;
            public string host = "localhost";
            public int port = 9090;
            public int numThreads = 1;
            public string url = string.Empty;
            public string pipe = string.Empty;
            public LayeredChoice layered = LayeredChoice.None;
            public ProtocolChoice protocol = ProtocolChoice.Binary;
            public TransportChoice transport = TransportChoice.Socket;
            private readonly TConfiguration Configuration = new();

            internal void Parse(List args)
            {
                for (var i = 0; i < args.Count; ++i)
                {
                    if (args[i] == "-u")
                    {
                        url = args[++i];
                        transport = TransportChoice.Http;
                    }
                    else if (args[i] == "-n")
                    {
                        numIterations = Convert.ToInt32(args[++i]);
                    }
                    else if (args[i].StartsWith("--pipe="))
                    {
                        pipe = args[i].Substring(args[i].IndexOf('=') + 1);
                        transport = TransportChoice.NamedPipe;
                    }
                    else if (args[i].StartsWith("--host="))
                    {
                        // check there for ipaddress
                        host = args[i].Substring(args[i].IndexOf('=') + 1);
                        if (transport != TransportChoice.TlsSocket)
                            transport = TransportChoice.Socket;
                    }
                    else if (args[i].StartsWith("--port="))
                    {
                        port = int.Parse(args[i].Substring(args[i].IndexOf('=') + 1));
                        if (transport != TransportChoice.TlsSocket)
                            transport = TransportChoice.Socket;
                    }
                    else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
                    {
                        layered = LayeredChoice.Buffered;
                    }
                    else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
                    {
                        layered = LayeredChoice.Framed;
                    }
                    else if (args[i] == "-t")
                    {
                        numThreads = Convert.ToInt32(args[++i]);
                    }
                    else if (args[i] == "--binary" || args[i] == "--protocol=binary")
                    {
                        protocol = ProtocolChoice.Binary;
                    }
                    else if (args[i] == "--compact" || args[i] == "--protocol=compact")
                    {
                        protocol = ProtocolChoice.Compact;
                    }
                    else if (args[i] == "--json" || args[i] == "--protocol=json")
                    {
                        protocol = ProtocolChoice.Json;
                    }
                    else if (args[i] == "--ssl")
                    {
                        transport = TransportChoice.TlsSocket;
                    }
                    else if (args[i] == "--help")
                    {
                        PrintOptionsHelp();
                        return;
                    }
                    else
                    {
                        Console.WriteLine("Invalid argument: {0}", args[i]);
                        PrintOptionsHelp();
                        return;
                    }
                }

                switch (transport)
                {
                    case TransportChoice.Socket:
                        Console.WriteLine("Using socket transport");
                        break;
                    case TransportChoice.TlsSocket:
                        Console.WriteLine("Using encrypted transport");
                        break;
                    case TransportChoice.Http:
                        Console.WriteLine("Using HTTP transport");
                        break;
                    case TransportChoice.NamedPipe:
                        Console.WriteLine("Using named pipes transport");
                        break;
                    default:  // unhandled case
                        Debug.Assert(false);
                        break;
                }

                switch (layered)
                {
                    case LayeredChoice.Framed:
                        Console.WriteLine("Using framed transport");
                        break;
                    case LayeredChoice.Buffered:
                        Console.WriteLine("Using buffered transport");
                        break;
                    default:  // unhandled case?
                        Debug.Assert(layered == LayeredChoice.None);
                        break;
                }

                switch (protocol)
                {
                    case ProtocolChoice.Binary:
                        Console.WriteLine("Using binary protocol");
                        break;
                    case ProtocolChoice.Compact:
                        Console.WriteLine("Using compact protocol");
                        break;
                    case ProtocolChoice.Json:
                        Console.WriteLine("Using JSON protocol");
                        break;
                    default:  // unhandled case?
                        Debug.Assert(false);
                        break;
                }
            }

            private static X509Certificate2 GetClientCert()
            {
                var clientCertName = "client.p12";
                var possiblePaths = new List
                {
                    "../../../keys/",
                    "../../keys/",
                    "../keys/",
                    "keys/",
                };

                var existingPath = string.Empty;
                foreach (var possiblePath in possiblePaths)
                {
                    var path = Path.GetFullPath(possiblePath + clientCertName);
                    if (File.Exists(path))
                    {
                        existingPath = path;
                        break;
                    }
                }

                if (string.IsNullOrEmpty(existingPath))
                {
                    throw new FileNotFoundException($"Cannot find file: {clientCertName}");
                }

                //var cert = new X509Certificate2(existingPath, "thrift");
                var cert = X509CertificateLoader.LoadPkcs12FromFile(existingPath, "thrift");

                return cert;
            }

            public TTransport CreateTransport()
            {
                // endpoint transport
                TTransport trans;
                switch (transport)
                {
                    case TransportChoice.Http:
                        Debug.Assert(url != null);
                        trans = new THttpTransport(new Uri(url), Configuration);
                        break;

                    case TransportChoice.NamedPipe:
                        Debug.Assert(pipe != null);
                        trans = new TNamedPipeTransport(pipe,Configuration);
                        break;

                    case TransportChoice.TlsSocket:
                        var cert = GetClientCert();
                        if (cert == null || !cert.HasPrivateKey)
                        {
                            throw new InvalidOperationException("Certificate doesn't contain private key");
                        }

                        trans = new TTlsSocketTransport(host, port, Configuration, 0,
                            cert,
                            (sender, certificate, chain, errors) => true,
                            null);
                        break;

                    case TransportChoice.Socket:
                    default:
                        trans = new TSocketTransport(host, port, Configuration);
                        break;
                }


                // layered transport
                switch (layered)
                {
                    case LayeredChoice.Buffered:
                        trans = new TBufferedTransport(trans);
                        break;
                    case LayeredChoice.Framed:
                        trans = new TFramedTransport(trans);
                        break;
                    default:
                        Debug.Assert(layered == LayeredChoice.None);
                        break;
                }

                return trans;
            }

            public TProtocol CreateProtocol(TTransport transport)
            {
                switch (protocol)
                {
                    case ProtocolChoice.Compact:
                        return new TCompactProtocol(transport);
                    case ProtocolChoice.Json:
                        return new TJsonProtocol(transport);
                    case ProtocolChoice.Binary:
                    default:
                        return new TBinaryProtocol(transport);
                }
            }
        }


        private const int ErrorBaseTypes = 1;
        private const int ErrorStructs = 2;
        private const int ErrorContainers = 4;
        private const int ErrorExceptions = 8;
        private const int ErrorUnknown = 64;

        private class ClientTest
        {
            private readonly TTransport transport;
            private readonly ThriftTest.Client client;
            private readonly int numIterations;
            private bool done;

            public int ReturnCode { get; set; }

            public ClientTest(TestParams param)
            {
                transport = param.CreateTransport();
                client = new ThriftTest.Client(param.CreateProtocol(transport));
                numIterations = param.numIterations;
            }

            public async Task Execute()
            {
                if (done)
                {
                    Console.WriteLine("Execute called more than once");
                    throw new InvalidOperationException();
                }

                for (var i = 0; i < numIterations; i++)
                {
                    try
                    {
                        if (!transport.IsOpen)
                            await transport.OpenAsync(MakeTimeoutToken());
                    }
                    catch (TTransportException ex)
                    {
                        Console.WriteLine("*** FAILED ***");
                        Console.WriteLine("Connect failed: " + ex.Message);
                        ReturnCode |= ErrorUnknown;
                        Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
                        continue;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("*** FAILED ***");
                        Console.WriteLine("Connect failed: " + ex.Message);
                        ReturnCode |= ErrorUnknown;
                        Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
                        continue;
                    }

                    try
                    {
                        ReturnCode |= await ExecuteClientTest(client);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("*** FAILED ***");
                        Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
                        ReturnCode |= ErrorUnknown;
                    }
                }
                try
                {
                    transport.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error while closing transport");
                    Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
                }
                done = true;
            }
        }

        internal static void PrintOptionsHelp()
        {
            Console.WriteLine("Client options:");
            Console.WriteLine("  -u ");
            Console.WriteLine("  -t <# of threads to run>        default = 1");
            Console.WriteLine("  -n <# of iterations>            per thread");
            Console.WriteLine("  --pipe=");
            Console.WriteLine("  --host=");
            Console.WriteLine("  --port=");
            Console.WriteLine("  --transport=    one of buffered,framed  (defaults to none)");
            Console.WriteLine("  --protocol=      one of compact,json  (defaults to binary)");
            Console.WriteLine("  --ssl");
            Console.WriteLine();
        }

        public static Task Execute(List args)
        {
            try
            {
                var param = new TestParams();

                try
                {
                    param.Parse(args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("*** FAILED ***");
                    Console.WriteLine("Error while parsing arguments");
                    Console.WriteLine("{0} {1}\nStack:\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
                    return Task.FromResult(ErrorUnknown);
                }

                //issue tests on separate threads simultaneously
                var nThreads = Math.Max(param.numThreads, 1);
                Console.Write("Starting {0} test thread(s) ", nThreads);
                var tasks = new Task[nThreads];
                var start = DateTime.Now;
                var retcode = 0;
                for (var i = 0; i < tasks.Length; ++i)
                {
                    Console.Write('.');
                    tasks[i] = Task.Run(async () =>
                    {
                        var test = new ClientTest(param);
                        await test.Execute();
                        lock (tasks)
                            retcode |= test.ReturnCode;
                    });
                }
                Console.WriteLine(" OK");
                Task.WaitAll(tasks);
                Console.WriteLine("Total time: " + (DateTime.Now - start));
                Console.WriteLine();
                return Task.FromResult(retcode);
            }
            catch (Exception outerEx)
            {
                Console.WriteLine("*** FAILED ***");
                Console.WriteLine("Unexpected error");
                Console.WriteLine(outerEx.Message + "\n" + outerEx.StackTrace);
                return Task.FromResult(ErrorUnknown);
            }
        }

        public static string BytesToHex(byte[] data)
        {
            return Convert.ToHexString(data);
        }


        public enum BinaryTestSize
        {
            Empty,           // Edge case: the zero-length empty binary
            Normal,          // Fairly small array of usual size (256 bytes)
            Large,           // Large writes/reads may cause range check errors
            PipeWriteLimit,  // Windows Limit: Pipe write operations across a network are limited to 65,535 bytes per write.
            FifteenMB        // that's quite a bit of data
        };

        public static byte[] PrepareTestData(bool randomDist, BinaryTestSize testcase)
        {
            int amount;
            switch (testcase)
            {
                case BinaryTestSize.Empty:
                    amount = 0;
                    break;
                case BinaryTestSize.Normal:
                    amount = 0x100;
                    break;
                case BinaryTestSize.Large:
                    amount = 0x8000 + 128;
                    break;
                case BinaryTestSize.PipeWriteLimit:
                    amount = 0xFFFF + 128;
                    break;
                case BinaryTestSize.FifteenMB:
                    amount = 15 * 1024 * 1024;
                    break;
                default:
                    throw new ArgumentException("invalid argument",nameof(testcase));
            }

            var retval = new byte[amount];

            // linear distribution, unless random is requested
            if (!randomDist)
            {
                for (var i = 0; i < retval.Length; ++i)
                {
                    retval[i] = (byte)i;
                }
                return retval;
            }

            // random distribution
            var rnd = new Random();
            for (var i = 1; i < retval.Length; ++i)
            {
                retval[i] = (byte)rnd.Next(0x100);
            }
            return retval;
        }

        private static CancellationToken MakeTimeoutToken(int msec = 15_000)
        {
            var token = new CancellationTokenSource(msec);
            return token.Token;
        }

        public static async Task ExecuteClientTest(ThriftTest.Client client)
        {
            var returnCode = 0;

            Console.Write("testVoid()");
            await client.testVoid(MakeTimeoutToken());
            Console.WriteLine(" = void");

            Console.Write("testString(\"Test\")");
            var s = await client.testString("Test", MakeTimeoutToken());
            Console.WriteLine(" = \"" + s + "\"");
            if ("Test" != s)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }

            Console.Write("testBool(true)");
            var t = await client.testBool((bool)true, MakeTimeoutToken());
            Console.WriteLine(" = " + t);
            if (!t)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }
            Console.Write("testBool(false)");
            var f = await client.testBool((bool)false, MakeTimeoutToken());
            Console.WriteLine(" = " + f);
            if (f)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }

            Console.Write("testByte(1)");
            var i8 = await client.testByte((sbyte)1, MakeTimeoutToken());
            Console.WriteLine(" = " + i8);
            if (1 != i8)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }

            Console.Write("testI32(-1)");
            var i32 = await client.testI32(-1, MakeTimeoutToken());
            Console.WriteLine(" = " + i32);
            if (-1 != i32)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }

            Console.Write("testI64(-34359738368)");
            var i64 = await client.testI64(-34359738368, MakeTimeoutToken());
            Console.WriteLine(" = " + i64);
            if (-34359738368 != i64)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }

            // TODO: Validate received message
            Console.Write("testDouble(5.325098235)");
            var dub = await client.testDouble(5.325098235, MakeTimeoutToken());
            Console.WriteLine(" = " + dub);
            if (5.325098235 != dub)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }
            Console.Write("testDouble(-0.000341012439638598279)");
            dub = await client.testDouble(-0.000341012439638598279, MakeTimeoutToken());
            Console.WriteLine(" = " + dub);
            if (-0.000341012439638598279 != dub)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }

            // testUuid()
            var uuidOut = new Guid("{00112233-4455-6677-8899-AABBCCDDEEFF}");
            Console.Write("testUuid({0})", uuidOut);
            try
            {
                var uuidIn = await client.testUuid(uuidOut, MakeTimeoutToken());
                Console.WriteLine(" = {0}", uuidIn);
                if (!uuidIn.Equals(uuidOut))
                {
                    Console.WriteLine("*** FAILED ***");
                    returnCode |= ErrorBaseTypes;
                }
            }
            catch (Thrift.TApplicationException ex)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }

            // testBinary()
            foreach (BinaryTestSize binTestCase in Enum.GetValues(typeof(BinaryTestSize)))
            {
                var binOut = PrepareTestData(true, binTestCase);

                Console.Write("testBinary({0} bytes)", binOut.Length);
                try
                {
                    var binIn = await client.testBinary(binOut, MakeTimeoutToken());
                    Console.WriteLine(" = {0} bytes", binIn.Length);
                    if (binIn.Length != binOut.Length)
                    {
                        Console.WriteLine("*** FAILED ***");
                        returnCode |= ErrorBaseTypes;
                    }
                    for (var ofs = 0; ofs < Math.Min(binIn.Length, binOut.Length); ++ofs)
                    {
                        if (binIn[ofs] != binOut[ofs])
                        {
                            Console.WriteLine("*** FAILED ***");
                            returnCode |= ErrorBaseTypes;
                        }
                    }
                }
                catch (Thrift.TApplicationException ex)
                {
                    Console.WriteLine("*** FAILED ***");
                    returnCode |= ErrorBaseTypes;
                    Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
                }
            }

            // CrazyNesting
            Console.WriteLine("Test CrazyNesting");
            var one = new CrazyNesting();
            var two = new CrazyNesting();
            one.String_field = "crazy";
            two.String_field = "crazy";
            one.Binary_field = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF];
            two.Binary_field = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF];
            if (typeof(CrazyNesting).GetMethod("Equals")?.DeclaringType == typeof(CrazyNesting))
            {
                if (!one.Equals(two))
                {
                    Console.WriteLine("*** FAILED ***");
                    returnCode |= ErrorContainers;
                }
            }

            // TODO: Validate received message
            Console.Write("testStruct({\"Zero\", 1, -3, -5})");
            var o = new Xtruct
            {
                String_thing = "Zero",
                Byte_thing = (sbyte)1,
                I32_thing = -3,
                I64_thing = -5
            };
            var i = await client.testStruct(o, MakeTimeoutToken());
            Console.WriteLine(" = {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}");

            // TODO: Validate received message
            Console.Write("testNest({1, {\"Zero\", 1, -3, -5}, 5})");
            var o2 = new Xtruct2
            {
                Byte_thing = (sbyte)1,
                Struct_thing = o,
                I32_thing = 5
            };
            Xtruct2 i2 = await client.testNest(o2, MakeTimeoutToken());
            i = i2.Struct_thing;
            Console.WriteLine(" = {" + i2.Byte_thing + ", {\""
                            + (i?.String_thing ?? "") + "\", "
                            + (i?.Byte_thing ?? 0) + ", "
                            + (i?.I32_thing ?? 0) + ", "
                            + (i?.I64_thing ?? 0) + "}, "
                            + i2.I32_thing + "}");

            var mapout = new Dictionary();
            for (var j = 0; j < 5; j++)
            {
                mapout[j] = j - 10;
            }
            Console.Write("testMap({");
            Console.Write(string.Join(", ", mapout.Select((pair) => { return pair.Key + " => " + pair.Value; })));
            Console.Write("})");

            var mapin = await client.testMap(mapout, MakeTimeoutToken());

            Console.Write(" = {");
            Console.Write(string.Join(", ", mapin.Select((pair) => { return pair.Key + " => " + pair.Value; })));
            Console.WriteLine("}");

            // TODO: Validate received message
            var listout = new List();
            for (var j = -2; j < 3; j++)
            {
                listout.Add(j);
            }
            Console.Write("testList({");
            Console.Write(string.Join(", ", listout));
            Console.Write("})");

            var listin = await client.testList(listout, MakeTimeoutToken());

            Console.Write(" = {");
            Console.Write(string.Join(", ", listin));
            Console.WriteLine("}");

            //set
            // TODO: Validate received message
            var setout = new HashSet();
            for (var j = -2; j < 3; j++)
            {
                setout.Add(j);
            }
            Console.Write("testSet({");
            Console.Write(string.Join(", ", setout));
            Console.Write("})");

            var setin = await client.testSet(setout, MakeTimeoutToken());

            Console.Write(" = {");
            Console.Write(string.Join(", ", setin));
            Console.WriteLine("}");


            Console.Write("testEnum(ONE)");
            var ret = await client.testEnum(Numberz.ONE, MakeTimeoutToken());
            Console.WriteLine(" = " + ret);
            if (Numberz.ONE != ret)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorStructs;
            }

            Console.Write("testEnum(TWO)");
            ret = await client.testEnum(Numberz.TWO, MakeTimeoutToken());
            Console.WriteLine(" = " + ret);
            if (Numberz.TWO != ret)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorStructs;
            }

            Console.Write("testEnum(THREE)");
            ret = await client.testEnum(Numberz.THREE, MakeTimeoutToken());
            Console.WriteLine(" = " + ret);
            if (Numberz.THREE != ret)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorStructs;
            }

            Console.Write("testEnum(FIVE)");
            ret = await client.testEnum(Numberz.FIVE, MakeTimeoutToken());
            Console.WriteLine(" = " + ret);
            if (Numberz.FIVE != ret)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorStructs;
            }

            Console.Write("testEnum(EIGHT)");
            ret = await client.testEnum(Numberz.EIGHT, MakeTimeoutToken());
            Console.WriteLine(" = " + ret);
            if (Numberz.EIGHT != ret)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorStructs;
            }

            Console.Write("testTypedef(309858235082523)");
            var uid = await client.testTypedef(309858235082523L, MakeTimeoutToken());
            Console.WriteLine(" = " + uid);
            if (309858235082523L != uid)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorStructs;
            }

            // TODO: Validate received message
            Console.Write("testMapMap(1)");
            var mm = await client.testMapMap(1, MakeTimeoutToken());
            Console.Write(" = {");
            foreach (var key in mm.Keys)
            {
                Console.Write(key + " => {");
                var m2 = mm[key];
                foreach (var k2 in m2.Keys)
                {
                    Console.Write(k2 + " => " + m2[k2] + ", ");
                }
                Console.Write("}, ");
            }
            Console.WriteLine("}");

            // TODO: Validate received message
            var insane = new Insanity
            {
                UserMap = new Dictionary
                {
                    [Numberz.FIVE] = 5000L
                }
            };
            var truck = new Xtruct
            {
                String_thing = "Truck",
                Byte_thing = (sbyte)8,
                I32_thing = 8,
                I64_thing = 8
            };
            insane.Xtructs = [ truck ];
            Console.Write("testInsanity()");
            var whoa = await client.testInsanity(insane, MakeTimeoutToken());
            Console.Write(" = {");
            foreach (var key in whoa.Keys)
            {
                var val = whoa[key];
                Console.Write(key + " => {");

                foreach (var k2 in val.Keys)
                {
                    var v2 = val[k2];

                    Console.Write(k2 + " => {");
                    var userMap = v2.UserMap;

                    Console.Write("{");
                    if (userMap != null)
                    {
                        foreach (var k3 in userMap.Keys)
                        {
                            Console.Write(k3 + " => " + userMap[k3] + ", ");
                        }
                    }
                    else
                    {
                        Console.Write("null");
                    }
                    Console.Write("}, ");

                    var xtructs = v2.Xtructs;

                    Console.Write("{");
                    if (xtructs != null)
                    {
                        foreach (var x in xtructs)
                        {
                            Console.Write("{\"" + x.String_thing + "\", " + x.Byte_thing + ", " + x.I32_thing + ", " + x.I32_thing + "}, ");
                        }
                    }
                    else
                    {
                        Console.Write("null");
                    }
                    Console.Write("}");

                    Console.Write("}, ");
                }
                Console.Write("}, ");
            }
            Console.WriteLine("}");

            sbyte arg0 = 1;
            var arg1 = 2;
            var arg2 = long.MaxValue;
            var multiDict = new Dictionary
            {
                [1] = "one"
            };

            var tmpMultiDict = new List();
            foreach (var pair in multiDict)
                tmpMultiDict.Add(pair.Key +" => "+ pair.Value);

            var arg4 = Numberz.FIVE;
            long arg5 = 5000000;
            Console.Write("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + ",{" + string.Join(",", tmpMultiDict) + "}," + arg4 + "," + arg5 + ")");
            var multiResponse = await client.testMulti(arg0, arg1, arg2, multiDict, arg4, arg5, MakeTimeoutToken());
            Console.Write(" = Xtruct(byte_thing:" + multiResponse.Byte_thing + ",String_thing:" + multiResponse.String_thing
                          + ",i32_thing:" + multiResponse.I32_thing + ",i64_thing:" + multiResponse.I64_thing + ")\n");

            try
            {
                Console.WriteLine("testException(\"Xception\")");
                await client.testException("Xception", MakeTimeoutToken());
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
            }
            catch (Xception ex)
            {
                if (ex.ErrorCode != 1001 || ex.Message != "Xception")
                {
                    Console.WriteLine("*** FAILED ***");
                    returnCode |= ErrorExceptions;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }
            try
            {
                Console.WriteLine("testException(\"TException\")");
                await client.testException("TException", MakeTimeoutToken());
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
            }
            catch (Thrift.TException)
            {
                // OK
            }
            catch (Exception ex)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }
            try
            {
                Console.WriteLine("testException(\"ok\")");
                await client.testException("ok", MakeTimeoutToken());
                // OK
            }
            catch (Exception ex)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }

            try
            {
                Console.WriteLine("testMultiException(\"Xception\", ...)");
                await client.testMultiException("Xception", "ignore", MakeTimeoutToken());
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
            }
            catch (Xception ex)
            {
                if (ex.ErrorCode != 1001 || ex.Message != "This is an Xception")
                {
                    Console.WriteLine("*** FAILED ***");
                    returnCode |= ErrorExceptions;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }
            try
            {
                Console.WriteLine("testMultiException(\"Xception2\", ...)");
                await client.testMultiException("Xception2", "ignore", MakeTimeoutToken());
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
            }
            catch (Xception2 ex)
            {
                if (ex.ErrorCode != 2002 || ex.Struct_thing?.String_thing != "This is an Xception2")
                {
                    Console.WriteLine("*** FAILED ***");
                    returnCode |= ErrorExceptions;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }
            try
            {
                Console.WriteLine("testMultiException(\"success\", \"OK\")");
                if ("OK" != (await client.testMultiException("success", "OK", MakeTimeoutToken())).String_thing)
                {
                    Console.WriteLine("*** FAILED ***");
                    returnCode |= ErrorExceptions;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorExceptions;
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }

            Console.WriteLine("Test Oneway(1)");
            var sw = new Stopwatch();
            sw.Start();
            await client.testOneway(1, MakeTimeoutToken());
            sw.Stop();
            if (sw.ElapsedMilliseconds > 1000)
            {
                Console.WriteLine("*** FAILED ***");
                returnCode |= ErrorBaseTypes;
            }

            Console.Write("Test Calltime()");
            var times = 50;
            sw.Reset();
            sw.Start();
            var token = MakeTimeoutToken(20000);
            for (var k = 0; k < times; ++k)
                await client.testVoid(token);
            sw.Stop();
            Console.WriteLine(" = {0} ms a testVoid() call", sw.ElapsedMilliseconds / times);
            return returnCode;
        }
    }
}
thrift-0.23.0/test/netstd/Client/Client.csproj0000664000175000017500000000561415170007142021517 0ustar00buildbuild00000000000000
  

  
    net10.0
    latestMajor
    Client
    Client
    Exe
    0.23.0.0
    false
    false
    false
    false
    false
    false
    enable
  

  
    
    
    
    
  

  
    
  

  
    
      
    
    
    
    
  

thrift-0.23.0/test/netstd/build.cmd0000664000175000017500000000164115165535636017443 0ustar00buildbuild00000000000000@echo off
rem /*
rem  * Licensed to the Apache Software Foundation (ASF) under one
rem  * or more contributor license agreements. See the NOTICE file
rem  * distributed with this work for additional information
rem  * regarding copyright ownership. The ASF licenses this file
rem  * to you under the Apache License, Version 2.0 (the
rem  * "License"); you may not use this file except in compliance
rem  * with the License. You may obtain a copy of the License at
rem  *
rem  *   http://www.apache.org/licenses/LICENSE-2.0
rem  *
rem  * Unless required by applicable law or agreed to in writing,
rem  * software distributed under the License is distributed on an
rem  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
rem  * KIND, either express or implied. See the License for the
rem  * specific language governing permissions and limitations
rem  * under the License.
rem  */
setlocal

dotnet --info
dotnet build

:eof
thrift-0.23.0/test/netstd/build.sh0000664000175000017500000000154515165535636017315 0ustar00buildbuild00000000000000#!/usr/bin/env bash

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

#exit if any command fails
set -e

dotnet --info
dotnet build
thrift-0.23.0/test/netstd/ThriftTest.sln0000664000175000017500000002762415167543515020503 0ustar00buildbuild00000000000000
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.0.11205.157 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netstd\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{21039F25-6ED7-4E80-A545-EBC93472EBD1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{0C6E8685-F191-4479-9842-882A38961127}"
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.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
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift.Compile.net10", "..\..\lib\netstd\Tests\Thrift.Compile.Tests\Thrift.Compile.net10\Thrift.Compile.net10.csproj", "{62BFDEC2-D23A-8800-09F5-B2467B2006A3}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Debug|x64 = Debug|x64
		Debug|x86 = Debug|x86
		Release|Any CPU = Release|Any CPU
		Release|x64 = Release|x64
		Release|x86 = Release|x86
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.ActiveCfg = Debug|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.Build.0 = Debug|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.ActiveCfg = Debug|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.Build.0 = Debug|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.Build.0 = Release|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.ActiveCfg = Release|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.Build.0 = Release|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.ActiveCfg = Release|Any CPU
		{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.Build.0 = Release|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x64.ActiveCfg = Debug|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x64.Build.0 = Debug|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x86.ActiveCfg = Debug|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x86.Build.0 = Debug|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|Any CPU.Build.0 = Release|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x64.ActiveCfg = Release|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x64.Build.0 = Release|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x86.ActiveCfg = Release|Any CPU
		{21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x86.Build.0 = Release|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Debug|x64.ActiveCfg = Debug|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Debug|x64.Build.0 = Debug|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Debug|x86.ActiveCfg = Debug|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Debug|x86.Build.0 = Debug|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Release|Any CPU.Build.0 = Release|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Release|x64.ActiveCfg = Release|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Release|x64.Build.0 = Release|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Release|x86.ActiveCfg = Release|Any CPU
		{0C6E8685-F191-4479-9842-882A38961127}.Release|x86.Build.0 = Release|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x64.ActiveCfg = Debug|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x64.Build.0 = Debug|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x86.ActiveCfg = Debug|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x86.Build.0 = Debug|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|Any CPU.Build.0 = Release|Any CPU
		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x64.ActiveCfg = Release|Any CPU
		{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
		{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
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x64.Build.0 = Debug|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x86.ActiveCfg = Debug|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x86.Build.0 = Debug|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|Any CPU.Build.0 = Release|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x64.ActiveCfg = Release|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x64.Build.0 = Release|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x86.ActiveCfg = Release|Any CPU
		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x86.Build.0 = Release|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x64.ActiveCfg = Debug|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x64.Build.0 = Debug|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x86.ActiveCfg = Debug|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x86.Build.0 = Debug|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|Any CPU.Build.0 = Release|Any CPU
		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x64.ActiveCfg = Release|Any CPU
		{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
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Debug|x64.ActiveCfg = Debug|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Debug|x64.Build.0 = Debug|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Debug|x86.ActiveCfg = Debug|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Debug|x86.Build.0 = Debug|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Release|Any CPU.Build.0 = Release|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Release|x64.ActiveCfg = Release|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Release|x64.Build.0 = Release|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Release|x86.ActiveCfg = Release|Any CPU
		{62BFDEC2-D23A-8800-09F5-B2467B2006A3}.Release|x86.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {52CE9A12-F6CB-4F0C-BB42-0105612F5FF4}
	EndGlobalSection
EndGlobal
thrift-0.23.0/test/netstd/Server/0000775000175000017500000000000015170007142017101 5ustar00buildbuild00000000000000thrift-0.23.0/test/netstd/Server/Properties/0000775000175000017500000000000015165535636021257 5ustar00buildbuild00000000000000thrift-0.23.0/test/netstd/Server/Properties/AssemblyInfo.cs0000664000175000017500000000343015165535636024201 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.

[assembly: AssemblyTitle("Server")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("The Apache Software Foundation")]
[assembly: AssemblyProduct("Thrift")]
[assembly: AssemblyCopyright("The Apache Software Foundation")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.

[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM

[assembly: Guid("B0C13DA0-3117-4844-8AE8-B1775E46223D")]

thrift-0.23.0/test/netstd/Server/Server.csproj0000664000175000017500000000571715170007142021603 0ustar00buildbuild00000000000000
  

  
    net10.0
    latestMajor
    Server
    Server
    Exe
    0.23.0.0
    false
    false
    false
    false
    false
    false
    enable
  

  
    
    
    
    
  

  
    
  

  
    
      
    
    
    
    
  

thrift-0.23.0/test/netstd/Server/Program.cs0000664000175000017500000000454515165535636021071 0ustar00buildbuild00000000000000// 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.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using ThriftTest;
using System.Threading.Tasks;

namespace Server
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                try
                {
                    Console.SetBufferSize(Console.BufferWidth, 4096);
                }
                catch (Exception)
                {
                    Console.WriteLine("Failed to grow scroll-back buffer");
                }
            }

            // run whatever mode is choosen, default to test impl
            var argslist = new List(args);
            switch (argslist.FirstOrDefault())
            {
                case "server":  // crosstest wants to pass this, so just emit a hint and ignore
                    Console.WriteLine("Hint: The 'server' argument is no longer required.");
                    argslist.RemoveAt(0);
                    return await TestServer.Execute(argslist);
                case "--help":
                    PrintHelp();
                    return 0;
                default:
                    return await TestServer.Execute(argslist);
            }
        }

        private static void PrintHelp()
        {
            Console.WriteLine("Usage:");
            Console.WriteLine("  Server  [options]");
            Console.WriteLine("  Server  --help");
            Console.WriteLine("");

            ServerParam.PrintOptionsHelp();
        }
    }
}
thrift-0.23.0/test/netstd/Server/TestServer.cs0000664000175000017500000006414415165535636021571 0ustar00buildbuild00000000000000// 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.Reflection.Metadata.Ecma335;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Thrift;
using Thrift.Collections;
using Thrift.Processor;
using Thrift.Protocol;
using Thrift.Server;
using Thrift.Transport;
using Thrift.Transport.Server;

#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
{
    internal enum ProtocolChoice
    {
        Binary,
        Compact,
        Json
    }

    internal enum TransportChoice
    {
        Socket,
        TlsSocket,
        NamedPipe
    }

    internal enum BufferChoice
    {
        None,
        Buffered,
        Framed
    }

    internal enum ServerChoice
    {
        Simple,
        ThreadPool
    }


    internal class ServerParam
    {
        internal BufferChoice buffering = BufferChoice.None;
        internal ProtocolChoice protocol = ProtocolChoice.Binary;
        internal TransportChoice transport = TransportChoice.Socket;
        internal ServerChoice server = ServerChoice.Simple;
        internal int port = 9090;
        internal string pipe = string.Empty;

        internal void Parse(List args)
        {
            for (var i = 0; i < args.Count; i++)
            {
                if (args[i].StartsWith("--pipe="))
                {
                    pipe = args[i].Substring(args[i].IndexOf('=') + 1);
                    transport = TransportChoice.NamedPipe;
                }
                else if (args[i].StartsWith("--port="))
                {
                    port = int.Parse(args[i].Substring(args[i].IndexOf('=') + 1));
                    if(transport != TransportChoice.TlsSocket)
                        transport = TransportChoice.Socket;
                }
                else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
                {
                    buffering = BufferChoice.Buffered;
                }
                else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
                {
                    buffering = BufferChoice.Framed;
                }
                else if (args[i] == "--binary" || args[i] == "--protocol=binary")
                {
                    protocol = ProtocolChoice.Binary;
                }
                else if (args[i] == "--compact" || args[i] == "--protocol=compact")
                {
                    protocol = ProtocolChoice.Compact;
                }
                else if (args[i] == "--json" || args[i] == "--protocol=json")
                {
                    protocol = ProtocolChoice.Json;
                }
                else if (args[i] == "--server-type=simple")
                {
                    server = ServerChoice.Simple;
                }
                else if (args[i] == "--threaded" || args[i] == "--server-type=threaded")
                {
                    throw new NotImplementedException(args[i]);
                }
                else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool")
                {
                    server = ServerChoice.ThreadPool;
                }
                else if (args[i] == "--prototype" || args[i] == "--processor=prototype")
                {
                    throw new NotImplementedException(args[i]);
                }
                else if (args[i] == "--ssl")
                {
                    transport = TransportChoice.TlsSocket;
                }
                else if (args[i] == "--help")
                {
                    PrintOptionsHelp();
                    return;
                }
                else
                {
                    Console.WriteLine("Invalid argument: {0}", args[i]);
                    PrintOptionsHelp();
                    return;
                }
            }

        }

        internal static void PrintOptionsHelp()
        {
            Console.WriteLine("Server options:");
            Console.WriteLine("  --pipe=");
            Console.WriteLine("  --port=");
            Console.WriteLine("  --transport=    one of buffered,framed  (defaults to none)");
            Console.WriteLine("  --protocol=      one of compact,json  (defaults to binary)");
            Console.WriteLine("  --server-type=            one of threaded,threadpool  (defaults to simple)");
            Console.WriteLine("  --processor=");
            Console.WriteLine("  --ssl");
            Console.WriteLine();
        }
    }

    public class TestServer
    {
        private static int _clientID = -1;  // use with Interlocked only!
        public static int ClientID => Interlocked.Add(ref _clientID, 0);

        private static readonly TConfiguration Configuration = new(); 

        public delegate void TestLogDelegate(string msg, params object[] values);

        public class MyServerEventHandler : TServerEventHandler
        {
            public int callCount = 0;

            public Task PreServeAsync(CancellationToken cancellationToken)
            {
                callCount++;
                return Task.CompletedTask;
            }

            public Task CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken)
            {
                callCount++;
                return Task.FromResult(null);
            }

            public Task DeleteContextAsync(object serverContext, TProtocol input, TProtocol output, CancellationToken cancellationToken)
            {
                callCount++;
                return Task.CompletedTask;
            }

            public Task ProcessContextAsync(object serverContext, TTransport transport, CancellationToken cancellationToken)
            {
                callCount++;
                return Task.CompletedTask;
            }
        }

        public class TestHandlerAsync : ThriftTest.IAsync
        {
            //public TServer Server { get; set; }
            private readonly int handlerID;
            private readonly TestLogDelegate logger;

            public TestHandlerAsync()
            {
                handlerID = Interlocked.Increment(ref _clientID);
                logger += TestConsoleLogger;
                logger.Invoke("New TestHandler instance created");
            }

            public void TestConsoleLogger(string msg, params object[] values)
            {
                var sb = new StringBuilder();
                sb.AppendFormat("handler{0:D3}:", handlerID);
                sb.AppendFormat(msg, values);
                sb.AppendLine();
                lock (typeof(Console))
                    Console.Write(sb.ToString());
            }

            public Task testVoid(CancellationToken cancellationToken)
            {
                logger.Invoke("testVoid()");
                return Task.CompletedTask;
            }

            public Task testString(string? thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testString({0})", thing ?? "");
                return Task.FromResult(thing ?? string.Empty);
            }

            public Task testBool(bool thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testBool({0})", thing);
                return Task.FromResult(thing);
            }

            public Task testByte(sbyte thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testByte({0})", thing);
                return Task.FromResult(thing);
            }

            public Task testI32(int thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testI32({0})", thing);
                return Task.FromResult(thing);
            }

            public Task testI64(long thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testI64({0})", thing);
                return Task.FromResult(thing);
            }

            public Task testDouble(double thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testDouble({0})", thing);
                return Task.FromResult(thing);
            }

            public Task testBinary(byte[]? thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testBinary({0} bytes)", thing?.Length ?? 0);
                return Task.FromResult(thing ?? []);
            }

            public Task testUuid(Guid thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testUuid({0})", thing.ToString("B"));
                return Task.FromResult(thing);
            }

            public Task testStruct(Xtruct? thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing?.String_thing ?? "", thing?.Byte_thing ?? 0, thing?.I32_thing ?? 0, thing?.I64_thing ?? 0);
                return Task.FromResult(thing ?? new Xtruct());   // null returns are not allowed in Thrift
            }

            public Task testNest(Xtruct2? nest, CancellationToken cancellationToken)
            {
                var thing = nest?.Struct_thing;
                logger.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})",
                    nest?.Byte_thing ?? 0,
                    thing?.String_thing ?? "",
                    thing?.Byte_thing ?? 0,
                    thing?.I32_thing ?? 0,
                    thing?.I64_thing ?? 0,
                    nest?.I32_thing ?? 0);
                return Task.FromResult(nest ?? new Xtruct2());   // null returns are not allowed in Thrift
            }

            public Task> testMap(Dictionary? thing, CancellationToken cancellationToken)
            {
                var sb = new StringBuilder();
                sb.Append("testMap({{");
                if (thing != null)
                {
                    var first = true;
                    foreach (var key in thing.Keys)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            sb.Append(", ");
                        }
                        sb.AppendFormat("{0} => {1}", key, thing[key]);
                    }
                }
                sb.Append("}})");
                logger.Invoke(sb.ToString());
                return Task.FromResult(thing ?? []);   // null returns are not allowed in Thrift
            }

            public Task> testStringMap(Dictionary? thing, CancellationToken cancellationToken)
            {
                var sb = new StringBuilder();
                sb.Append("testStringMap({{");
                if (thing != null)
                {
                    var first = true;
                    foreach (var key in thing.Keys)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            sb.Append(", ");
                        }
                        sb.AppendFormat("{0} => {1}", key, thing[key]);
                    }
                }
                sb.Append("}})");
                logger.Invoke(sb.ToString());
                return Task.FromResult(thing ?? []);   // null returns are not allowed in Thrift
            }

            public Task> testSet(HashSet? thing, CancellationToken cancellationToken)
            {
                var sb = new StringBuilder();
                sb.Append("testSet({{");
                if (thing != null)
                {
                    var first = true;
                    foreach (int elem in thing)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            sb.Append(", ");
                        }
                        sb.AppendFormat("{0}", elem);
                    }
                }
                sb.Append("}})");
                logger.Invoke(sb.ToString());
                return Task.FromResult(thing ?? []);   // null returns are not allowed in Thrift
            }

            public Task> testList(List? thing, CancellationToken cancellationToken)
            {
                var sb = new StringBuilder();
                sb.Append("testList({{");
                if (thing != null)
                {
                    var first = true;
                    foreach (var elem in thing)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            sb.Append(", ");
                        }
                        sb.AppendFormat("{0}", elem);
                    }
                }
                sb.Append("}})");
                logger.Invoke(sb.ToString());
                return Task.FromResult(thing ?? []);   // null returns are not allowed in Thrift
            }

            public Task testEnum(Numberz thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testEnum({0})", thing);
                return Task.FromResult(thing);
            }

            public Task testTypedef(long thing, CancellationToken cancellationToken)
            {
                logger.Invoke("testTypedef({0})", thing);
                return Task.FromResult(thing);
            }

            public Task>> testMapMap(int hello, CancellationToken cancellationToken)
            {
                logger.Invoke("testMapMap({0})", hello);
                var mapmap = new Dictionary>();

                var pos = new Dictionary();
                var neg = new Dictionary();
                for (var i = 1; i < 5; i++)
                {
                    pos[i] = i;
                    neg[-i] = -i;
                }

                mapmap[4] = pos;
                mapmap[-4] = neg;

                return Task.FromResult(mapmap);
            }

            public Task>> testInsanity(Insanity? argument, CancellationToken cancellationToken)
            {
                logger.Invoke("testInsanity()");

                /** from ThriftTest.thrift:
                 * So you think you've got this all worked, out eh?
                 *
                 * Creates a the returned map with these values and prints it out:
                 *   { 1 => { 2 => argument,
                 *            3 => argument,
                 *          },
                 *     2 => { 6 => , },
                 *   }
                 * @return map> - a map with the above values
                 */

                var first_map = new Dictionary();
                var second_map = new Dictionary(); ;

                // null dict keys/values are not allowed in Thrift
                first_map[Numberz.TWO] = argument ?? new Insanity();
                first_map[Numberz.THREE] = argument ?? new Insanity();

                second_map[Numberz.SIX] = new Insanity();

                var insane = new Dictionary>
                {
                    [1] = first_map,
                    [2] = second_map
                };

                return Task.FromResult(insane);
            }

            public Task testMulti(sbyte arg0, int arg1, long arg2, Dictionary? arg3, Numberz arg4, long arg5,
                CancellationToken cancellationToken)
            {
                logger.Invoke("testMulti()");

                var hello = new Xtruct(); ;
                hello.String_thing = "Hello2";
                hello.Byte_thing = arg0;
                hello.I32_thing = arg1;
                hello.I64_thing = arg2;
                return Task.FromResult(hello);
            }

            public Task testException(string? arg, CancellationToken cancellationToken)
            {
                logger.Invoke("testException({0})", arg ?? "");
                if (arg == "Xception")
                {
                    var x = new Xception
                    {
                        ErrorCode = 1001,
                        Message = arg
                    };
                    throw x;
                }
                if (arg == "TException")
                {
                    throw new TException();
                }
                return Task.CompletedTask;
            }

            public Task testMultiException(string? arg0, string? arg1, CancellationToken cancellationToken)
            {
                logger.Invoke("testMultiException({0}, {1})", arg0 ?? "", arg1 ?? "");
                if (arg0 == "Xception")
                {
                    var x = new Xception
                    {
                        ErrorCode = 1001,
                        Message = "This is an Xception"
                    };
                    throw x;
                }

                if (arg0 == "Xception2")
                {
                    var x = new Xception2
                    {
                        ErrorCode = 2002,
                        Struct_thing = new Xtruct { String_thing = "This is an Xception2" }
                    };
                    throw x;
                }

                var result = new Xtruct { String_thing = arg1 };
                return Task.FromResult(result);
            }

            public async Task testOneway(int secondsToSleep, CancellationToken cancellationToken)
            {
                logger.Invoke("testOneway({0}), sleeping...", secondsToSleep);
                await Task.Delay(secondsToSleep * 1000, cancellationToken);
                logger.Invoke("testOneway finished");
            }
        }


        private static X509Certificate2 GetServerCert()
        {
            var serverCertName = "server.p12";
            var possiblePaths = new List
            {
                "../../../keys/",
                "../../keys/",
                "../keys/",
                "keys/",
            };
                        
            var existingPath = string.Empty;
            foreach (var possiblePath in possiblePaths)
            {
                var path = Path.GetFullPath(possiblePath + serverCertName);
                if (File.Exists(path))
                {
                    existingPath = path;
                    break;
                }
            }
                        
            if (string.IsNullOrEmpty(existingPath))
            {
                throw new FileNotFoundException($"Cannot find file: {serverCertName}");
            }

            //var cert = new X509Certificate2(existingPath, "thrift");
            var cert = X509CertificateLoader.LoadPkcs12FromFile(existingPath, "thrift");

            return cert;
        }

        public static async Task Execute(List args)
        {
            using (var loggerFactory = new LoggerFactory()) //.AddConsole().AddDebug();
            {
                var logger = loggerFactory.CreateLogger("Test");

                try
                {
                    var param = new ServerParam();

                    try
                    {
                        param.Parse(args);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("*** FAILED ***");
                        Console.WriteLine("Error while  parsing arguments");
                        Console.WriteLine("{0} {1}\nStack:\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
                        return 1;
                    }


                    // Endpoint transport (mandatory)
                    TServerTransport trans;
                    switch (param.transport)
                    {
                        case TransportChoice.NamedPipe:
                            Debug.Assert(param.pipe != null);
                            var numListen = (param.server == ServerChoice.Simple) ? 1 : 16;
                            trans = new TNamedPipeServerTransport(param.pipe, Configuration, NamedPipeServerFlags.OnlyLocalClients, numListen);
                            break;


                        case TransportChoice.TlsSocket:
                            var cert = GetServerCert();
                            if (cert == null || !cert.HasPrivateKey)
                            {
                                cert?.Dispose();
                                throw new InvalidOperationException("Certificate doesn't contain private key");
                            }

                            trans = new TTlsServerSocketTransport(param.port, Configuration,
                                cert,
                                (sender, certificate, chain, errors) => true,
                                null);
                            break;

                        case TransportChoice.Socket:
                        default:
                            trans = new TServerSocketTransport(param.port, Configuration);
                            break;
                    }

                    // Layered transport (mandatory)
                    TTransportFactory? transFactory;
                    switch (param.buffering)
                    {
                        case BufferChoice.Framed:
                            transFactory = new TFramedTransport.Factory();
                            break;
                        case BufferChoice.Buffered:
                            transFactory = new TBufferedTransport.Factory();
                            break;
                        default:
                            Debug.Assert(param.buffering == BufferChoice.None, "unhandled case");
                            transFactory = null;  // no layered transprt
                            break;
                    }

                    TProtocolFactory proto = param.protocol switch
                    {
                        ProtocolChoice.Compact => new TCompactProtocol.Factory(),
                        ProtocolChoice.Json => new TJsonProtocol.Factory(),
                        ProtocolChoice.Binary => new TBinaryProtocol.Factory(),
                        _ => new TBinaryProtocol.Factory(),
                    };

                    // Processor
                    var testHandler = new TestHandlerAsync();
                    var testProcessor = new ThriftTest.AsyncProcessor(testHandler);
                    var processorFactory = new TSingletonProcessorFactory(testProcessor);

                    var poolconfig = new TThreadPoolAsyncServer.Configuration();  // use platform defaults
                    TServer serverEngine = param.server switch
                    {
                        ServerChoice.Simple => new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger),
                        ServerChoice.ThreadPool => new TThreadPoolAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, poolconfig, logger),
                        _ => new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger)
                    };

                    //Server event handler
                    var serverEvents = new MyServerEventHandler();
                    serverEngine.SetEventHandler(serverEvents);

                    // Run it
                    var where = (!string.IsNullOrEmpty(param.pipe)) ? "pipe " + param.pipe : "port " + param.port;
                    Console.WriteLine("Running "+ serverEngine.GetType().Name +
                                      " at "+ where +
                                      " using "+ processorFactory.GetType().Name + " processor prototype factory " +
                                      (param.buffering == BufferChoice.Buffered ? " with buffered transport" : "") +
                                      (param.buffering == BufferChoice.Framed ? " with framed transport" : "") +
                                      (param.transport == TransportChoice.TlsSocket ? " with encryption" : "") +
                                      (param.protocol == ProtocolChoice.Compact ? " with compact protocol" : "") +
                                      (param.protocol == ProtocolChoice.Json ? " with json protocol" : "") +
                                      "...");
                    await serverEngine.ServeAsync(CancellationToken.None);
                    Console.ReadLine();
                }
                catch (Exception x)
                {
                    Console.Error.Write(x);
                    return 1;
                }

                Console.WriteLine("done.");
                return 0;
            }
        }
    }

}
thrift-0.23.0/test/netstd/README.md0000664000175000017500000000112315165535636017131 0ustar00buildbuild00000000000000# Apache Thrift net-core-lib tests

Tests for Thrift client library ported to Microsoft .NET Core 

# Content
- ThriftTest - tests for Thrift library 

# Reused components 
- NET Core SDK 3.1 (LTS)

# How to build on Windows
- Get Thrift IDL compiler executable, add to some folder and add path to this folder into PATH variable
- Open ThriftTest.sln in Visual Studio and build
or 
- Build with scripts

# How to build on Unix
- Ensure you have .NET Core 3.0 SDK installed or use the Ubuntu Xenial docker image
- Follow common build practice for Thrift: bootstrap, configure, and make precross

thrift-0.23.0/test/netstd/Makefile.in0000644000175000017500000005743515170007167017723 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/netstd
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
	ctags-recursive dvi-recursive html-recursive info-recursive \
	install-data-recursive install-dvi-recursive \
	install-exec-recursive install-html-recursive \
	install-info-recursive install-pdf-recursive \
	install-ps-recursive install-recursive installcheck-recursive \
	installdirs-recursive pdf-recursive ps-recursive \
	tags-recursive uninstall-recursive
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
  distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
  $(RECURSIVE_TARGETS) \
  $(RECURSIVE_CLEAN_TARGETS) \
  $(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
	distdir distdir-am
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates.  Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
  BEGIN { nonempty = 0; } \
  { items[$$0] = 1; nonempty = 1; } \
  END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique.  This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
  list='$(am__tagged_files)'; \
  unique=`for i in $$list; do \
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  done | $(am__uniquify_input)`
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in README.md
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
  dir0=`pwd`; \
  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
  sed_rest='s,^[^/]*/*,,'; \
  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
  sed_butlast='s,/*[^/]*$$,,'; \
  while test -n "$$dir1"; do \
    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
    if test "$$first" != "."; then \
      if test "$$first" = ".."; then \
        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
      else \
        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
        if test "$$first2" = "$$first"; then \
          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
        else \
          dir2="../$$dir2"; \
        fi; \
        dir0="$$dir0"/"$$first"; \
      fi; \
    fi; \
    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
  done; \
  reldir="$$dir2"
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = . 
EXTRA_DIST = \
	Client \
	README.md \
	Server \
	ThriftTest.sln \
	build.cmd \
	build.sh

all: all-recursive

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/netstd/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/netstd/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
#     (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
	@fail=; \
	if $(am__make_keepgoing); then \
	  failcom='fail=yes'; \
	else \
	  failcom='exit 1'; \
	fi; \
	dot_seen=no; \
	target=`echo $@ | sed s/-recursive//`; \
	case "$@" in \
	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
	  *) list='$(SUBDIRS)' ;; \
	esac; \
	for subdir in $$list; do \
	  echo "Making $$target in $$subdir"; \
	  if test "$$subdir" = "."; then \
	    dot_seen=yes; \
	    local_target="$$target-am"; \
	  else \
	    local_target="$$target"; \
	  fi; \
	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
	  || eval $$failcom; \
	done; \
	if test "$$dot_seen" = "no"; then \
	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
	fi; test -z "$$fail"
style-local: 

ID: $(am__tagged_files)
	$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags

tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	set x; \
	here=`pwd`; \
	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
	  include_option=--etags-include; \
	  empty_fix=.; \
	else \
	  include_option=--include; \
	  empty_fix=; \
	fi; \
	list='$(SUBDIRS)'; for subdir in $$list; do \
	  if test "$$subdir" = .; then :; else \
	    test ! -f $$subdir/TAGS || \
	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
	  fi; \
	done; \
	$(am__define_uniq_tagged_files); \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: ctags-recursive

CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	$(am__define_uniq_tagged_files); \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive

cscopelist-am: $(am__tagged_files)
	list='$(am__tagged_files)'; \
	case "$(srcdir)" in \
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
	  *) sdir=$(subdir)/$(srcdir) ;; \
	esac; \
	for i in $$list; do \
	  if test -f "$$i"; then \
	    echo "$(subdir)/$$i"; \
	  else \
	    echo "$$sdir/$$i"; \
	  fi; \
	done >> $(top_builddir)/cscope.files

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
	  if test "$$subdir" = .; then :; else \
	    $(am__make_dryrun) \
	      || test -d "$(distdir)/$$subdir" \
	      || $(MKDIR_P) "$(distdir)/$$subdir" \
	      || exit 1; \
	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
	    $(am__relativize); \
	    new_distdir=$$reldir; \
	    dir1=$$subdir; dir2="$(top_distdir)"; \
	    $(am__relativize); \
	    new_top_distdir=$$reldir; \
	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
	    ($(am__cd) $$subdir && \
	      $(MAKE) $(AM_MAKEFLAGS) \
	        top_distdir="$$new_top_distdir" \
	        distdir="$$new_distdir" \
		am__remove_distdir=: \
		am__skip_length_check=: \
		am__skip_mode_fix=: \
	        distdir) \
	      || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-recursive
all-am: Makefile all-local
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-recursive
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-recursive
	-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags

dvi: dvi-recursive

dvi-am:

html: html-recursive

html-am:

info: info-recursive

info-am:

install-data-am:

install-dvi: install-dvi-recursive

install-dvi-am:

install-exec-am:

install-html: install-html-recursive

install-html-am:

install-info: install-info-recursive

install-info-am:

install-man:

install-pdf: install-pdf-recursive

install-pdf-am:

install-ps: install-ps-recursive

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-recursive
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-recursive

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-recursive

pdf-am:

ps: ps-recursive

ps-am:

style: style-recursive

style-am: style-local

uninstall-am:

.MAKE: $(am__recursive_targets) install-am install-strip

.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \
	check check-am clean clean-generic clean-libtool clean-local \
	cscopelist-am ctags ctags-am distclean distclean-generic \
	distclean-libtool distclean-tags distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs installdirs-am maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags tags-am uninstall uninstall-am

.PRECIOUS: Makefile


all-local:
	$(DOTNETCORE) build -c Release

precross:
	$(DOTNETCORE) build -c Release

clean-local:
	$(RM) -r Client/bin
	$(RM) -r Server/bin
	$(RM) -r Client/obj
	$(RM) -r Server/obj
	$(RM) -r ThriftTest/ThriftTest

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/netstd/Makefile.am0000664000175000017500000000220015165535636017703 0ustar00buildbuild00000000000000#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

SUBDIRS = . 

all-local:
	$(DOTNETCORE) build -c Release

precross:
	$(DOTNETCORE) build -c Release

clean-local:
	$(RM) -r Client/bin
	$(RM) -r Server/bin
	$(RM) -r Client/obj
	$(RM) -r Server/obj
	$(RM) -r ThriftTest/ThriftTest

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	Client \
	README.md \
	Server \
	ThriftTest.sln \
	build.cmd \
	build.sh
thrift-0.23.0/test/Makefile.in0000644000175000017500000006705415170007167016420 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@WITH_C_GLIB_TRUE@am__append_1 = c_glib
@WITH_C_GLIB_TRUE@am__append_2 = precross-c_glib
@WITH_CL_TRUE@am__append_3 = cl
@WITH_CL_TRUE@am__append_4 = precross-cl
@WITH_CPP_TRUE@am__append_5 = cpp
@WITH_CPP_TRUE@am__append_6 = precross-cpp
@WITH_PERL_TRUE@am__append_7 = perl
@WITH_PERL_TRUE@am__append_8 = precross-perl
@WITH_PHP_TRUE@am__append_9 = php
@WITH_PHP_TRUE@am__append_10 = precross-php
@WITH_DART_TRUE@am__append_11 = dart
@WITH_DART_TRUE@am__append_12 = precross-dart
@WITH_PYTHON_TRUE@am__append_13 = py py.tornado
@WITH_PYTHON_TRUE@am__append_14 = precross-py
@WITH_PYTHON_TRUE@@WITH_TWISTED_TEST_TRUE@am__append_15 = py.twisted
@WITH_RUBY_TRUE@am__append_16 = rb
@WITH_RUBY_TRUE@am__append_17 = precross-rb
@WITH_HAXE_TRUE@am__append_18 = haxe
@WITH_DOTNET_TRUE@am__append_19 = netstd
@WITH_GO_TRUE@am__append_20 = go
@WITH_GO_TRUE@am__append_21 = precross-go
@WITH_ERLANG_TRUE@am__append_22 = erl
@WITH_ERLANG_TRUE@am__append_23 = precross-erl
@WITH_LUA_TRUE@am__append_24 = lua
@WITH_LUA_TRUE@am__append_25 = precross-lua
@WITH_RS_TRUE@am__append_26 = rs
@WITH_RS_TRUE@am__append_27 = precross-rs
@WITH_SWIFT_TRUE@am__append_28 = swift
@WITH_SWIFT_TRUE@am__append_29 = precross-swift
subdir = test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
	ctags-recursive dvi-recursive html-recursive info-recursive \
	install-data-recursive install-dvi-recursive \
	install-exec-recursive install-html-recursive \
	install-info-recursive install-pdf-recursive \
	install-ps-recursive install-recursive installcheck-recursive \
	installdirs-recursive pdf-recursive ps-recursive \
	tags-recursive uninstall-recursive
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
  distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
  $(RECURSIVE_TARGETS) \
  $(RECURSIVE_CLEAN_TARGETS) \
  $(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
	distdir distdir-am
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates.  Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
  BEGIN { nonempty = 0; } \
  { items[$$0] = 1; nonempty = 1; } \
  END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique.  This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
  list='$(am__tagged_files)'; \
  unique=`for i in $$list; do \
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  done | $(am__uniquify_input)`
DIST_SUBDIRS = features c_glib cl cpp perl php dart py py.tornado \
	py.twisted rb haxe netstd go erl lua rs swift
am__DIST_COMMON = $(srcdir)/Makefile.in README.md
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
  dir0=`pwd`; \
  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
  sed_rest='s,^[^/]*/*,,'; \
  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
  sed_butlast='s,/*[^/]*$$,,'; \
  while test -n "$$dir1"; do \
    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
    if test "$$first" != "."; then \
      if test "$$first" = ".."; then \
        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
      else \
        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
        if test "$$first2" = "$$first"; then \
          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
        else \
          dir2="../$$dir2"; \
        fi; \
        dir0="$$dir0"/"$$first"; \
      fi; \
    fi; \
    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
  done; \
  reldir="$$dir2"
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = features $(am__append_1) $(am__append_3) $(am__append_5) \
	$(am__append_7) $(am__append_9) $(am__append_11) \
	$(am__append_13) $(am__append_15) $(am__append_16) \
	$(am__append_18) $(am__append_19) $(am__append_20) \
	$(am__append_22) $(am__append_24) $(am__append_26) \
	$(am__append_28)
PRECROSS_TARGET = $(am__append_2) $(am__append_4) $(am__append_6) \
	$(am__append_8) $(am__append_10) $(am__append_12) \
	$(am__append_14) $(am__append_17) $(am__append_21) \
	$(am__append_23) $(am__append_25) $(am__append_27) \
	$(am__append_29)
EXTRA_DIST = \
	audit \
	c_glib \
	cl \
	cpp \
	crossrunner \
	dart \
	delphi \
	erl \
	keys \
	lua \
	ocaml \
	perl \
	php \
	py \
	py.tornado \
	py.twisted \
	rb \
	rs \
	swift \
	threads \
	partial \
	AnnotationTest.thrift \
	BrokenConstants.thrift \
	ConstantsDemo.thrift \
	DebugProtoTest.thrift \
	DenseLinkingTest.thrift \
	DocTest.thrift \
	DoubleConstantsTest.thrift \
	EnumContainersTest.thrift \
	EnumTest.thrift \
	ExceptionStruct.thrift \
	FullCamelTest.thrift \
	FuzzTest.thrift \
	Identifiers.thrift \
	Include.thrift \
	index.html \
	Int64Test.thrift \
	JsDeepConstructorTest.thrift \
	keys/keygen/.gitignore \
	known_failures_Linux.json \
	ManyOptionals.thrift \
	ManyTypedefs.thrift \
	NameConflictTest.thrift \
	OptionalRequiredTest.thrift \
	partial/thrift_test_schema.thrift \
	README.md \
	rebuild_known_failures.sh \
	Recursive.thrift \
	result.js \
	ReuseObjects.thrift \
	Service.thrift \
	SmallTest.thrift \
	SpecificNameTest.thrift \
	StressTest.thrift \
	test.py \
	tests.json \
	ThriftTest.thrift \
	TypedefTest.thrift \
	Types.thrift \
	UnsafeTypes.thrift \
	v0.16/ConstantsDemo.thrift \
	v0.16/DebugProtoTest.thrift \
	v0.16/FuzzTestNoUuid.thrift \
	v0.16/NameConflictTest.thrift \
	v0.16/ThriftTest.thrift \
	VoidMethExceptionsTest.thrift \
	valgrind.suppress

all: all-recursive

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
#     (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
	@fail=; \
	if $(am__make_keepgoing); then \
	  failcom='fail=yes'; \
	else \
	  failcom='exit 1'; \
	fi; \
	dot_seen=no; \
	target=`echo $@ | sed s/-recursive//`; \
	case "$@" in \
	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
	  *) list='$(SUBDIRS)' ;; \
	esac; \
	for subdir in $$list; do \
	  echo "Making $$target in $$subdir"; \
	  if test "$$subdir" = "."; then \
	    dot_seen=yes; \
	    local_target="$$target-am"; \
	  else \
	    local_target="$$target"; \
	  fi; \
	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
	  || eval $$failcom; \
	done; \
	if test "$$dot_seen" = "no"; then \
	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
	fi; test -z "$$fail"
style-local: 

ID: $(am__tagged_files)
	$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags

tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	set x; \
	here=`pwd`; \
	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
	  include_option=--etags-include; \
	  empty_fix=.; \
	else \
	  include_option=--include; \
	  empty_fix=; \
	fi; \
	list='$(SUBDIRS)'; for subdir in $$list; do \
	  if test "$$subdir" = .; then :; else \
	    test ! -f $$subdir/TAGS || \
	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
	  fi; \
	done; \
	$(am__define_uniq_tagged_files); \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: ctags-recursive

CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	$(am__define_uniq_tagged_files); \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive

cscopelist-am: $(am__tagged_files)
	list='$(am__tagged_files)'; \
	case "$(srcdir)" in \
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
	  *) sdir=$(subdir)/$(srcdir) ;; \
	esac; \
	for i in $$list; do \
	  if test -f "$$i"; then \
	    echo "$(subdir)/$$i"; \
	  else \
	    echo "$$sdir/$$i"; \
	  fi; \
	done >> $(top_builddir)/cscope.files

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
	  if test "$$subdir" = .; then :; else \
	    $(am__make_dryrun) \
	      || test -d "$(distdir)/$$subdir" \
	      || $(MKDIR_P) "$(distdir)/$$subdir" \
	      || exit 1; \
	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
	    $(am__relativize); \
	    new_distdir=$$reldir; \
	    dir1=$$subdir; dir2="$(top_distdir)"; \
	    $(am__relativize); \
	    new_top_distdir=$$reldir; \
	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
	    ($(am__cd) $$subdir && \
	      $(MAKE) $(AM_MAKEFLAGS) \
	        top_distdir="$$new_top_distdir" \
	        distdir="$$new_distdir" \
		am__remove_distdir=: \
		am__skip_length_check=: \
		am__skip_mode_fix=: \
	        distdir) \
	      || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
	$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-recursive
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-recursive
	-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags

dvi: dvi-recursive

dvi-am:

html: html-recursive

html-am:

info: info-recursive

info-am:

install-data-am:

install-dvi: install-dvi-recursive

install-dvi-am:

install-exec-am:

install-html: install-html-recursive

install-html-am:

install-info: install-info-recursive

install-info-am:

install-man:

install-pdf: install-pdf-recursive

install-pdf-am:

install-ps: install-ps-recursive

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-recursive
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-recursive

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-recursive

pdf-am:

ps: ps-recursive

ps-am:

style: style-recursive

style-am: style-local

uninstall-am:

.MAKE: $(am__recursive_targets) check-am install-am install-strip

.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
	check-am check-local clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags ctags-am dist-hook distclean \
	distclean-generic distclean-libtool distclean-tags distdir dvi \
	dvi-am html html-am info info-am install install-am \
	install-data install-data-am install-dvi install-dvi-am \
	install-exec install-exec-am install-html install-html-am \
	install-info install-info-am install-man install-pdf \
	install-pdf-am install-ps install-ps-am install-strip \
	installcheck installcheck-am installdirs installdirs-am \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags tags-am uninstall uninstall-am

.PRECIOUS: Makefile


#
# generate html for ThriftTest.thrift AND validate it!
#
@WITH_NODEJS_TRUE@check-local:
@WITH_NODEJS_TRUE@	$(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/test/ThriftTest.thrift
@WITH_NODEJS_TRUE@	$(top_builddir)/node_modules/.bin/html-validator --file=gen-html/index.html --verbose
@WITH_NODEJS_TRUE@	$(top_builddir)/node_modules/.bin/html-validator --file=gen-html/ThriftTest.html --verbose
@WITH_NODEJS_FALSE@check-local:
@WITH_NODEJS_FALSE@	$(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/test/ThriftTest.thrift

clean-local:
	$(RM) -r $(top_srcdir)/test/gen-html/
	find . -type d -name "__pycache__" | xargs rm -rf
	find . -type f -name "*.pyc" | xargs rm -f

dist-hook:
	$(RM) -r $(distdir)/gen-html/
	find $(distdir) -type d -name "__pycache__" | xargs rm -rf
	find $(distdir) -type f -name "*.pyc" | xargs rm -f

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

precross-%:
	$(MAKE) -C $* precross
precross: $(PRECROSS_TARGET)

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/test.py0000775000175000017500000002043515165535636015714 0ustar00buildbuild00000000000000#!/usr/bin/env python3
#
# 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.
#

#
# Apache Thrift - integration (cross) test suite
#
# tests different server-client, protocol and transport combinations
#
# This script requires python 3.x due to the improvements in
# subprocess management that are needed for reliability.
#

from itertools import chain
import json
import logging
import multiprocessing
import argparse
import os
import sys

import crossrunner

# 3.3 introduced subprocess timeouts on waiting for child
req_version = (3, 3)
cur_version = sys.version_info
assert (cur_version >= req_version), "Python 3.3 or later is required for proper operation."


ROOT_DIR = os.path.dirname(os.path.realpath(os.path.dirname(__file__)))
TEST_DIR_RELATIVE = 'test'
TEST_DIR = os.path.join(ROOT_DIR, TEST_DIR_RELATIVE)
FEATURE_DIR_RELATIVE = os.path.join(TEST_DIR_RELATIVE, 'features')
CONFIG_FILE = 'tests.json'


def run_cross_tests(server_match, client_match, jobs, skip_known_failures, only_known_failures, retry_count, regex):
    logger = multiprocessing.get_logger()
    logger.debug('Collecting tests')
    with open(os.path.join(TEST_DIR, CONFIG_FILE), 'r') as fp:
        j = json.load(fp)
    tests = crossrunner.collect_cross_tests(j, server_match, client_match, regex)
    if not tests:
        print('No test found that matches the criteria', file=sys.stderr)
        print('  servers: %s' % server_match, file=sys.stderr)
        print('  clients: %s' % client_match, file=sys.stderr)
        return False
    if only_known_failures:
        logger.debug('Only running known failures')
        known = crossrunner.load_known_failures(TEST_DIR)
        tests = list(filter(lambda t: crossrunner.test_name(**t) in known, tests))
    if skip_known_failures:
        logger.debug('Skipping known failures')
        known = crossrunner.load_known_failures(TEST_DIR)
        tests = list(filter(lambda t: crossrunner.test_name(**t) not in known, tests))

    dispatcher = crossrunner.TestDispatcher(TEST_DIR, ROOT_DIR, TEST_DIR_RELATIVE, jobs)
    logger.debug('Executing %d tests' % len(tests))
    try:
        for r in [dispatcher.dispatch(test, retry_count) for test in tests]:
            r.wait()
        logger.debug('Waiting for completion')
        return dispatcher.wait()
    except (KeyboardInterrupt, SystemExit):
        logger.debug('Interrupted, shutting down')
        dispatcher.terminate()
        return False


def run_feature_tests(server_match, feature_match, jobs, skip_known_failures, only_known_failures, retry_count, regex):
    basedir = os.path.join(ROOT_DIR, FEATURE_DIR_RELATIVE)
    logger = multiprocessing.get_logger()
    logger.debug('Collecting tests')
    with open(os.path.join(TEST_DIR, CONFIG_FILE), 'r') as fp:
        j = json.load(fp)
    with open(os.path.join(basedir, CONFIG_FILE), 'r') as fp:
        j2 = json.load(fp)
    tests = crossrunner.collect_feature_tests(j, j2, server_match, feature_match, regex)
    if not tests:
        print('No test found that matches the criteria', file=sys.stderr)
        print('  servers: %s' % server_match, file=sys.stderr)
        print('  features: %s' % feature_match, file=sys.stderr)
        return False
    if only_known_failures:
        logger.debug('Only running known failures')
        known = crossrunner.load_known_failures(basedir)
        tests = list(filter(lambda t: crossrunner.test_name(**t) in known, tests))
    if skip_known_failures:
        logger.debug('Skipping known failures')
        known = crossrunner.load_known_failures(basedir)
        tests = list(filter(lambda t: crossrunner.test_name(**t) not in known, tests))

    dispatcher = crossrunner.TestDispatcher(TEST_DIR, ROOT_DIR, FEATURE_DIR_RELATIVE, jobs)
    logger.debug('Executing %d tests' % len(tests))
    try:
        for r in [dispatcher.dispatch(test, retry_count) for test in tests]:
            r.wait()
        logger.debug('Waiting for completion')
        return dispatcher.wait()
    except (KeyboardInterrupt, SystemExit):
        logger.debug('Interrupted, shutting down')
        dispatcher.terminate()
        return False


def default_concurrency():
    try:
        return int(os.environ.get('THRIFT_CROSSTEST_CONCURRENCY'))
    except (TypeError, ValueError):
        # Since much time is spent sleeping, use many threads
        return int(multiprocessing.cpu_count() * 1.25) + 1


def main(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument('--server', default='', nargs='*',
                        help='list of servers to test')
    parser.add_argument('--client', default='', nargs='*',
                        help='list of clients to test')
    parser.add_argument('-F', '--features', nargs='*', default=None,
                        help='run server feature tests instead of cross language tests')
    parser.add_argument('-R', '--regex', help='test name pattern to run')
    parser.add_argument('-o', '--only-known_failures', action='store_true', dest='only_known_failures',
                        help='only execute tests that are known to fail')
    parser.add_argument('-s', '--skip-known-failures', action='store_true', dest='skip_known_failures',
                        help='do not execute tests that are known to fail')
    parser.add_argument('-r', '--retry-count', type=int,
                        default=0, help='maximum retry on failure')
    parser.add_argument('-j', '--jobs', type=int,
                        default=default_concurrency(),
                        help='number of concurrent test executions')

    g = parser.add_argument_group(title='Advanced')
    g.add_argument('-v', '--verbose', action='store_const',
                   dest='log_level', const=logging.DEBUG, default=logging.WARNING,
                   help='show debug output for test runner')
    g.add_argument('-P', '--print-expected-failures', choices=['merge', 'overwrite'],
                   dest='print_failures',
                   help="generate expected failures based on last result and print to stdout")
    g.add_argument('-U', '--update-expected-failures', choices=['merge', 'overwrite'],
                   dest='update_failures',
                   help="generate expected failures based on last result and save to default file location")
    options = parser.parse_args(argv)

    logger = multiprocessing.log_to_stderr()
    logger.setLevel(options.log_level)

    if options.features is not None and options.client:
        print('Cannot specify both --features and --client ', file=sys.stderr)
        return 1

    # Allow multiple args separated with ',' for backward compatibility
    server_match = list(chain(*[x.split(',') for x in options.server]))
    client_match = list(chain(*[x.split(',') for x in options.client]))

    if options.update_failures or options.print_failures:
        dire = os.path.join(ROOT_DIR, FEATURE_DIR_RELATIVE) if options.features is not None else TEST_DIR
        res = crossrunner.generate_known_failures(
            dire, options.update_failures == 'overwrite',
            options.update_failures, options.print_failures)
    elif options.features is not None:
        features = options.features or ['.*']
        res = run_feature_tests(server_match, features, options.jobs,
                                options.skip_known_failures, options.only_known_failures,
                                options.retry_count, options.regex)
    else:
        res = run_cross_tests(server_match, client_match, options.jobs,
                              options.skip_known_failures, options.only_known_failures,
                              options.retry_count, options.regex)
    return 0 if res else 1


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
thrift-0.23.0/test/Identifiers.thrift0000664000175000017500000000164715165535636020053 0ustar00buildbuild00000000000000/*
 * 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.
 */

// THRIFT-4953
struct NoFieldIdentifiersTest {
  string field_without_id1,
  string field_without_id2,
  1: string field_with_id
}thrift-0.23.0/test/haxe/0000755000175000017500000000000015170007201015251 5ustar00buildbuild00000000000000thrift-0.23.0/test/haxe/make_all.sh0000775000175000017500000000224615165535636017411 0ustar00buildbuild00000000000000#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

# invoke Thrift comnpiler
../../compiler/cpp/thrift -r -gen haxe  ../ThriftTest.thrift

# output folder
if [ ! -d bin ]; then
  mkdir  bin
fi

# invoke Haxe compiler
for target in *.hxml; do 
  echo --------------------------
  echo Building ${target} ...
  echo --------------------------
  if [ ! -d bin/${target} ]; then
    mkdir  bin/${target}
  fi
  haxe  --cwd .  ${target} 
done


#eof
thrift-0.23.0/test/haxe/cpp.hxml0000664000175000017500000000217515165535636016762 0ustar00buildbuild00000000000000#
# 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.
#
 
#integrate files to classpath
-cp src
-cp gen-haxe
-cp ../../lib/haxe/src

#this class wil be used as entry point for your app.
-main Main

#CPP target
-cpp bin

#To produce 64 bit binaries the file should define the HXCPP_M64 compile variable:
#-D HXCPP_M64

# libs
-lib uuid

#Add debug information
-debug

#dead code elimination : remove unused code
-dce fullthrift-0.23.0/test/haxe/src/0000775000175000017500000000000015165535636016070 5ustar00buildbuild00000000000000thrift-0.23.0/test/haxe/src/Arguments.hx0000664000175000017500000002601115165535636020376 0ustar00buildbuild00000000000000/*
 * 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;

import org.apache.thrift.*;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;
import haxe.io.Path;

using StringTools;


enum ProtocolType {
    binary;
    json;
    compact;
}

enum EndpointTransport {
    socket;
    http;
}

enum ServerType {
    simple;
    /*
    threadpool;
    threaded;
    nonblocking;
    */
}


class Arguments
{
    public var printHelpOnly(default,null) : Bool = false;

    public var server(default,null) : Bool = false;
    public var servertype(default,null) : ServerType = simple;

    public var host(default,null) : String = "localhost";
    public var port(default,null) : Int = 9090;

    public var protocol(default,null) : ProtocolType = binary;
    public var transport(default,null) : EndpointTransport = socket;
    public var framed(default,null) : Bool = false;
    public var buffered(default,null) : Bool = false;

    public var numIterations(default,null) : Int = 1;
    public var numThreads(default,null) : Int = 1;
    public var skipSpeedTest(default,null) : Bool = false;


    public function new() {
        #if sys
          #if !phpwebserver
          try {
              ParseArgs();
          } catch (e : String) {
            trace(GetHelp());
            throw e;
          }
          #else
            //forcing server
            server = true;
            transport = http;
          #end
        #else
        trace("WN: Platform does not support program arguments, using defaults.");
        #end
    }

    #if sys

    private static function GetHelp() : String {
        var sProg = Path.withoutDirectory( Sys.programPath());
        return "\n"
            +sProg+"  [client|server]  [options]\n"
            +"\n"
            +"Modus: Either client or server, the default is client.\n"
            +"\n"
            +"Common options:\n"
            +"  -h [ --help ]               produce help message\n"
            +"  --port arg (=9090)          Port number to listen / connect to\n"
            /* not supported yet
            +"  --domain-socket arg         Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)\n"
            +"  --pipe arg                  Windows Named Pipe (e.g. MyThriftPipe)\n"
            */
            +"  --protocol arg (=binary)    protocol: binary, compact, json\n"
            /* not supported yet
            +"  --ssl                       Encrypted Transport using SSL\n"
            */
            +"\n"
            +"Server only options:\n"
            +"  --transport arg (=sockets)  Transport: buffered, framed, http, anonpipe\n"
            /* not supported yet
            +"  --processor-events          processor-events\n"
            +"  --server-type arg (=simple) type of server, \"simple\", \"thread-pool\", \n"
            +"                              \"threaded\", or \"nonblocking\"\n"
            +"  -n [ --workers ] arg (=4)   Number of thread pools workers. Only valid for \n"
            +"                              thread-pool server type\n"
            */
            +"\n"
            +"Client only options:\n"
            +"  --host arg (=localhost)     Host to connect\n"
            +"  --transport arg (=sockets)  Transport: buffered, framed, http, evhttp\n"
            /* not supported yet
            +"  --anon-pipes hRead hWrite   Windows Anonymous Pipes pair (handles)\n"
            */
            +"  -n [ --testloops ] arg (=1) Number of Tests\n"
            +"  -t [ --threads ] arg (=1)   Number of Test threads\n"
            +"  --skip-speed-test           Skip the speed test\n"
            +"\n"
            +"All arguments are optional.\n"
            ;
    }


    private function ParseArgs() : Void {

        var args = Sys.args().copy();
        if( (args == null) || (args.length <= 0)) {
            server = false;
            numThreads = 1;
            return;
        }

        var arg = args.shift();
        if ( arg == "client") {
            server = false;
            numThreads = 1;
        }
        else if ( arg == "server") {
            server = true;
            numThreads = 4;
        }
        else if ( (arg == "-h") || (arg == "--help")) {
            // -h [ --help ]               produce help message
            Sys.println( GetHelp());
            printHelpOnly = true;
            return;
        }
        else {
            throw "First argument must be 'server' or 'client'";
        }


        while( args.length > 0) {
            arg = args.shift();

            if ( (arg == "-h") || (arg == "--help")) {
                // -h [ --help ]               produce help message
                Sys.println( GetHelp());
                printHelpOnly = true;
                return;
            }
            else if (arg == "--port") {
                // --port arg (=9090)          Port number to listen
                arg = args.shift();
                var tmp = Std.parseInt(arg);
                if( tmp != null) {
                    port = tmp;
                } else {
                    throw "Invalid port number "+arg;
                }
            }
            else if (arg == "--domain-socket") {
                //   --domain-socket arg         Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)
                throw "domain sockets not supported yet";
            }
            else if (arg == "--pipe") {
                //   --pipe arg                  Windows Named Pipe (e.g. MyThriftPipe)
                throw "named pipes not supported yet";
            }
            else if (arg == "--protocol") {
                // --protocol arg (=binary)    protocol: binary, compact, json
                arg = args.shift();
                if( arg == "binary") {
                    protocol = binary;
                } else if( arg == "compact") {
                    protocol = compact;
                } else if( arg == "json") {
                    protocol = json;
                } else {
                    InvalidArg(arg);
                }
            }
            else if (arg == "--ssl") {
                // --ssl                       Encrypted Transport using SSL
                throw "SSL not supported yet";
            }
            else {
                //Server only options:
                if( server) {
                    ParseServerArgument( arg, args);
                } else {
                    ParseClientArgument( arg, args);
                }
            }
        }
    }


    private function ParseServerArgument( arg : String, args : Array) : Void {
        if (arg == "--transport") {
            //  --transport arg (=sockets)  Transport: buffered, framed, http, anonpipe
            arg = args.shift();
            if( arg == "buffered") {
                buffered = true;
            } else if( arg == "framed") {
                framed = true;
            } else if( arg == "http") {
                transport = http;
            } else if( arg == "anonpipe") {
                throw "Anon pipes transport not supported yet";
            } else {
                InvalidArg(arg);
            }
        }
        else if (arg == "--processor-events") {
            throw "Processor events not supported yet";
        }
        else if (arg == "--server-type") {
            //  --server-type arg (=simple) type of server,
            // one of "simple", "thread-pool", "threaded", "nonblocking"
            arg = args.shift();
            if( arg == "simple") {
                servertype = simple;
            } else if( arg == "thread-pool") {
                throw arg+" server not supported yet";
            } else if( arg == "threaded") {
                throw arg+" server not supported yet";
            } else if( arg == "nonblocking") {
                throw arg+" server not supported yet";
            } else {
                InvalidArg(arg);
            }
        }
        else if ((arg == "-n") || (arg == "--workers")) {
            //  -n [ --workers ] arg (=4)   Number of thread pools workers. Only valid for
            //                              thread-pool server type
            arg = args.shift();
            var tmp = Std.parseInt(arg);
            if( tmp != null) {
                numThreads = tmp;
            } else{
                throw "Invalid number "+arg;
            }
        }
        else {
            InvalidArg(arg);
        }
    }


    private function ParseClientArgument( arg : String, args : Array) : Void {
        if (arg == "--host") {
            //  --host arg (=localhost)     Host to connect
            host = args.shift();
        }
        else if (arg == "--transport") {
            //  --transport arg (=sockets)  Transport: buffered, framed, http, evhttp
            arg = args.shift();
            if( arg == "buffered") {
                buffered = true;
            } else if( arg == "framed") {
                framed = true;
            } else if( arg == "http") {
                transport = http;
            } else if( arg == "evhttp") {
                throw "evhttp transport not supported yet";
            } else {
                InvalidArg(arg);
            }
        }
        else if (arg == "--anon-pipes") {
            //  --anon-pipes hRead hWrite   Windows Anonymous Pipes pair (handles)
            throw "Anon pipes transport not supported yet";
        }
        else if ((arg == "-n") || (arg == "--testloops")) {
            //  -n [ --testloops ] arg (=1) Number of Tests
            arg = args.shift();
            var tmp = Std.parseInt(arg);
            if( tmp != null) {
                numIterations = tmp;
            } else {
                throw "Invalid number "+arg;
            }
        }
        else if ((arg == "-t") || (arg == "--threads")) {
            //  -t [ --threads ] arg (=1)   Number of Test threads
            arg = args.shift();
            var tmp = Std.parseInt(arg);
            if( tmp != null) {
                numThreads = tmp;
            } else {
                throw "Invalid number "+arg;
            }
        }
        else if (arg == "--skip-speed-test") {
            //  --skip-speed-test              Skip the speed test
            skipSpeedTest = true;
        }
        else {
            InvalidArg(arg);
        }
    }


    #end


    private function InvalidArg( arg : String) : Void {
        throw 'Invalid argument $arg';
    }
}
thrift-0.23.0/test/haxe/src/TestServer.hx0000664000175000017500000001010415165535636020533 0ustar00buildbuild00000000000000/*
 * 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;

import org.apache.thrift.*;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;

import thrift.test.*;  // generated code


class TestServer
{
    public static function Execute(args : Arguments) :  Void
    {
        try
        {
            // Transport
            var transport : TServerTransport = null;
            switch( args.transport) {
            case socket:
                trace("- socket port "+args.port);
				#if (flash || html5 || js)
				throw "Transport not supported on this platform";
                #else
                transport = new TServerSocket( args.port);
				#end
            case http:
                trace("- http");
                #if phpwebserver
                transport = new TWrappingServerTransport( 
					new TStreamTransport(
						new TFileStream("php://input", Read),
						new TFileStream("php://output", Append),
						null
					)
				);
                #else
				throw "Transport not supported on this platform";
                //transport = new THttpServer( targetHost);
                #end
            default:
                throw "Unhandled transport";
            }

            // optional: layered transport
            var transfactory : TTransportFactory = null;
            if ( args.framed) {
                trace("- framed transport");
                transfactory = new TFramedTransportFactory();
            }
            if ( args.buffered) {
                trace("- buffered transport");
                transfactory = new TBufferedTransportFactory();
            }

            // protocol
            var protfactory : TProtocolFactory = null;
            switch( args.protocol)
            {
            case binary:
                trace("- binary protocol");
                protfactory = new TBinaryProtocolFactory();
            case json:
                trace("- json protocol");
                protfactory = new TJSONProtocolFactory();
            case compact:
                trace("- compact protocol");
                protfactory = new TCompactProtocolFactory();
            }


            // Processor
            var handler : ThriftTest_service = new TestServerHandler();
            var processor = new ThriftTestProcessor(handler);

            // Simple Server
            var server : TServer = null;
            switch( args.servertype)
            {
            case simple:
                var simpleServer = new TSimpleServer( processor, transport, transfactory, protfactory);
                #if phpwebserver
                simpleServer.runOnce = true;
                #end
                server = simpleServer;

            default:
                throw "Unhandled server type";
            }


            /*
            // Server event handler
            if( args.serverEvents) {
                var events = new TestServerEventHandler();
                server.setEventHandler(serverEvents);
                handler.server = serverEngine;
            }
            */

            // Run it
            server.Serve();
            trace("done.");

        }
        catch (x : TException)
        {
            trace('$x ${x.errorID} ${x.errorMsg}');
        }
        catch (x : Dynamic)
        {
            trace('$x');
        }
    }
}
thrift-0.23.0/test/haxe/src/TestServerEventHandler.hx0000664000175000017500000000311715165535636023041 0ustar00buildbuild00000000000000/*
 * 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;

import org.apache.thrift.*;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;

import thrift.test.*;  // generated code


class TestServerEventHandler : TServerEventHandler
{
    public int callCount = 0;
    public void preServe()
    {
        callCount++;
    }
    public Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
    {
        callCount++;
        return null;
    }
    public void deleteContext(Object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
    {
        callCount++;
    }
    public void processContext(Object serverContext, Thrift.Transport.TTransport transport)
    {
        callCount++;
    }
}

    thrift-0.23.0/test/haxe/src/TestMacro.hx0000664000175000017500000000256615165535636020343 0ustar00buildbuild00000000000000/*
 * 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 ;

import haxe.macro.Context;
import haxe.macro.Expr;

/****
 * If you call the Thrift compiler this way (e.g. by changing the prebuild command)
 *
 *     thrift -r -gen haxe:buildmacro=TestMacro.handle()   ../ThriftTest.thrift
 *
 * the TestMacro.handle() function implemented below is called for each generated class
 * and interface. Use "thrift --help" to get more info about other available options.
 */
class TestMacro
{
  public static function handle( ) : Array< Field> {
    trace('TestMacro called for ' + Context.getLocalType());
    return Context.getBuildFields();
  }

}
thrift-0.23.0/test/haxe/src/TestServerHandler.hx0000664000175000017500000003337315165535636022046 0ustar00buildbuild00000000000000/*
 * 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;

import org.apache.thrift.*;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;
import org.apache.thrift.helper.*;
import uuid.Uuid;

import haxe.Int32;
import haxe.Int64;
import haxe.io.Bytes;
import haxe.ds.IntMap;
import haxe.ds.StringMap;
import haxe.ds.ObjectMap;

import thrift.test.*;  // generated code


class TestServerHandler implements ThriftTest_service {

    public var server:TServer;

    public function new() {
    }

    /**
    * Prints "testVoid()" and returns nothing.
    */
    public function testVoid():Void
    {
        trace("testVoid()");
    }

    /**
    * Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false'
    * @param bool  thing - the bool data to print
    * @return bool  - returns the bool 'thing'
    *
    * @param thing
    */
    public function testBool(thing : Bool) : Bool
    {
        trace('testBool($thing)');
        return thing;
    }

    /**
    * Prints 'testString("%s")' with thing as '%s'
    * @param string thing - the string to print
    * @return string - returns the string 'thing'
    *
    * @param thing
    */
    public function testString(thing:String):String
    {
        trace("teststring(\"" + thing + "\")");
        return thing;
    }

    /**
    * Prints 'testByte("%d")' with thing as '%d'
    * @param byte thing - the byte to print
    * @return byte - returns the byte 'thing'
    *
    * @param thing
    */
    public function testByte(thing:haxe.Int32):haxe.Int32
    {
        trace("testByte(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testI32("%d")' with thing as '%d'
    * @param i32 thing - the i32 to print
    * @return i32 - returns the i32 'thing'
    *
    * @param thing
    */
    public function testI32(thing:haxe.Int32):haxe.Int32
    {
        trace("testI32(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testI64("%d")' with thing as '%d'
    * @param i64 thing - the i64 to print
    * @return i64 - returns the i64 'thing'
    *
    * @param thing
    */
    public function testI64(thing:haxe.Int64):haxe.Int64
    {
        trace("testI64(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testDouble("%f")' with thing as '%f'
    * @param double thing - the double to print
    * @return double - returns the double 'thing'
    *
    * @param thing
    */
    public function testDouble(thing:Float):Float
    {
        trace("testDouble(" + thing + ")");
        return thing;
    }

    /**
     * Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data
     * @param binary  thing - the binary data to print
     * @return binary  - returns the binary 'thing'
     *
     * @param thing
     */
    public function testBinary(thing : haxe.io.Bytes) : haxe.io.Bytes
    {
        var hex = "";
        for ( i in 0 ... thing.length) {
            hex += StringTools.hex( thing.get(i), 2);
        }
        trace('testBinary($hex)');
        return thing;
    }

    /**
     * Prints 'testUuid("%s")' 
     * @param Uuid  thing - the uuid to print
     * @return Uuid  - returns the uuid 'thing'
     *
     * @param thing
     */
    public function testUuid(thing : String) : String
    {
        trace('testUuid($thing)');
        return thing;
    }

    /**
    * Prints 'testStruct("{%s}")' where thing has been formatted
    *  into a string of comma separated values
    * @param Xtruct thing - the Xtruct to print
    * @return Xtruct - returns the Xtruct 'thing'
    *
    * @param thing
    */
    public function testStruct(thing:Xtruct):Xtruct
    {
        trace("testStruct({" +
                          "\"" + thing.string_thing + "\", " +
                          thing.byte_thing + ", " +
                          thing.i32_thing + ", " +
                          Int64.toStr(thing.i64_thing) + "})");
        return thing;
    }

    /**
    * Prints 'testNest("{%s}")' where thing has been formatted
    *  into a string of the nested struct
    * @param Xtruct2 thing - the Xtruct2 to print
    * @return Xtruct2 - returns the Xtruct2 'thing'
    *
    * @param thing
    */
    public function testNest(nest:Xtruct2):Xtruct2
    {
        var thing:Xtruct = nest.struct_thing;
        trace("testNest({" +
                          nest.byte_thing + ", {" +
                          "\"" + thing.string_thing + "\", " +
                          thing.byte_thing + ", " +
                          thing.i32_thing + ", " +
                          Int64.toStr(thing.i64_thing) + "}, " +
                          nest.i32_thing + "})");
        return nest;
    }

    /**
    * Prints 'testMap("{%s")' where thing has been formatted
    *  into a string of  'key => value' pairs
    *  separated by commas and new lines
    * @param map thing - the map to print
    * @return map - returns the map 'thing'
    *
    * @param thing
    */
    public function testMap(thing:IntMap):IntMap
    {
        trace("testMap({");
        var first:Bool = true;
        for (key in thing.keys()) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(key + " => " + thing.get(key));
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testStringMap("{%s}")' where thing has been formatted
    *  into a string of  'key => value' pairs
    *  separated by commas and new lines
    * @param map thing - the map to print
    * @return map - returns the map 'thing'
    *
    * @param thing
    */
    public function testStringMap(thing:StringMap):StringMap
    {
        trace("testStringMap({");
        var first:Bool = true;
        for (key in thing.keys()) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(key + " => " + thing.get(key));
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testSet("{%s}")' where thing has been formatted
    *  into a string of  values
    *  separated by commas and new lines
    * @param set thing - the set to print
    * @return set - returns the set 'thing'
    *
    * @param thing
    */
    public function testSet(thing:IntSet):IntSet
    {
        trace("testSet({");
        var first:Bool = true;
        for (elem in thing) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(elem);
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testList("{%s}")' where thing has been formatted
    *  into a string of  values
    *  separated by commas and new lines
    * @param list thing - the list to print
    * @return list - returns the list 'thing'
    *
    * @param thing
    */
    public function testList(thing:List):List
    {
        trace("testList({");
        var first:Bool = true;
        for (elem in thing) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(elem);
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testEnum("%d")' where thing has been formatted into it's numeric value
    * @param Numberz thing - the Numberz to print
    * @return Numberz - returns the Numberz 'thing'
    *
    * @param thing
    */
    public function testEnum(thing:Int):Int
    {
        trace("testEnum(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testTypedef("%d")' with thing as '%d'
    * @param UserId thing - the UserId to print
    * @return UserId - returns the UserId 'thing'
    *
    * @param thing
    */
    public function testTypedef(thing:haxe.Int64):haxe.Int64
    {
        trace("testTypedef(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testMapMap("%d")' with hello as '%d'
    * @param i32 hello - the i32 to print
    * @return map> - returns a dictionary with these values:
    *   {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, },
    *     4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, }
    *
    * @param hello
    */
    public function testMapMap(hello:haxe.Int32):IntMap>
    {
        trace("testMapMap(" + hello + ")");
        var mapmap = new IntMap>();
        var pos = new IntMap();
        var neg = new IntMap();
        for (i in 1 ... 5) {
            pos.set(i, i);
            neg.set(-i, -i);
        };
        mapmap.set(4, pos);
        mapmap.set(-4, neg);
        return mapmap;
    }

    /**
    * So you think you've got this all worked, out eh?
    *
    * Creates a the returned map with these values and prints it out:
    *   { 1 => { 2 => argument,
    *            3 => argument,
    *          },
    *     2 => { 6 => , },
    *   }
    * @return map> - a map with the above values
    *
    * @param argument
    */
    public function testInsanity(argument : Insanity) : Int64Map< IntMap< Insanity>>
    {
        trace("testInsanity()");

        var first_map = new IntMap< Insanity>();
        first_map.set(Numberz.TWO, argument);
        first_map.set(Numberz.THREE, argument);

        var second_map = new IntMap< Insanity>();
        var looney = new Insanity();
        second_map.set(Numberz.SIX, looney);

        var insane = new Int64Map< IntMap< Insanity>>();
        insane.set( Int64.make(0,1), first_map);
        insane.set( Int64.make(0,2), second_map);

        return insane;
    }

    /**
    * Prints 'testMulti()'
    * @param byte arg0 -
    * @param i32 arg1 -
    * @param i64 arg2 -
    * @param map arg3 -
    * @param Numberz arg4 -
    * @param UserId arg5 -
    * @return Xtruct - returns an Xtruct
    *    with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1
    *    and i64_thing = arg2
    *
    * @param arg0
    * @param arg1
    * @param arg2
    * @param arg3
    * @param arg4
    * @param arg5
    */
    public function testMulti(arg0:haxe.Int32, arg1:haxe.Int32, arg2:haxe.Int64,
        arg3:IntMap, arg4:Int, arg5:haxe.Int64):Xtruct
    {
        trace("testMulti()");
        var hello = new Xtruct();
        hello.string_thing = "Hello2";
        hello.byte_thing = arg0;
        hello.i32_thing = arg1;
        hello.i64_thing = arg2;
        return hello;
    }

    /**
    * Print 'testException(%s)' with arg as '%s'
    * @param string arg - a string indication what type of exception to throw
    * if arg == "Xception" throw Xception with errorCode = 1001 and message = arg
    * elsen if arg == "TException" throw TException
    * else do not throw anything
    *
    * @param arg
    */
    public function testException(arg:String):Void
    {
        trace("testException(" + arg + ")");
        if (arg == "Xception") {
            var x = new Xception();
            x.errorCode = 1001;
            x.message = arg;
            throw x;
        };
        if (arg == "TException") {
            throw new TException();
        };
        return;
    }

    /**
    * Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s'
    * @param string arg - a string indication what type of exception to throw
    * if arg0 == "Xception"
    * throw Xception with errorCode = 1001 and message = "This is an Xception"
    * else if arg0 == "Xception2"
    * throw Xception2 with errorCode = 2002 and message = "This is an Xception2"
    * else do not throw anything
    * @return Xtruct - an Xtruct with string_thing = arg1
    *
    * @param arg0
    * @param arg1
    */
    public function testMultiException(arg0:String, arg1:String):Xtruct
    {
        trace("testMultiException(" + arg0 + ", " + arg1 + ")");
        if (arg0 == "Xception") {
            var x = new Xception();
            x.errorCode = 1001;
            x.message = "This is an Xception";
            throw x;
        } else if (arg0 == "Xception2") {
            var x = new Xception2();
            x.errorCode = 2002;
            x.struct_thing = new Xtruct();
            x.struct_thing.string_thing = "This is an Xception2";
            throw x;
        };
        var result = new Xtruct();
        result.string_thing = arg1;
        return result;
    }

    /**
    * Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d'
    * sleep 'secondsToSleep'
    * Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d'
    * @param i32 secondsToSleep - the number of seconds to sleep
    *
    * @param secondsToSleep
    */
    public function testOneway(secondsToSleep:haxe.Int32):Void
    {
		#if sys
        trace("testOneway(" + secondsToSleep + "), sleeping...");
        Sys.sleep(secondsToSleep);
		#end
        trace("testOneway finished");
    }

    public function testStop():Void
    {
        if (server != null) {
            server.Stop();
        };
    }
}
thrift-0.23.0/test/haxe/src/Main.hx0000664000175000017500000000445015165535636017320 0ustar00buildbuild00000000000000/*
 * 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;

import org.apache.thrift.*;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;

import thrift.test.*;  // generated code

class Main
{
    static function main() {
        #if phpwebserver
        initPhpWebServer();
        //check method
        if(php.Web.getMethod() != 'POST') {
          Sys.println('http endpoint for thrift test server');
          return;
        }
        #end

        try {
            var args = new Arguments();

            if( args.printHelpOnly)
                return;

            if (args.server)
                TestServer.Execute(args);
            else
                TestClient.Execute(args);

            trace("Completed.");
        } catch (e : String) {
            trace(e);
        }
    }

    #if phpwebserver
    private static function initPhpWebServer()
    {
        //remap trace to error log
        haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos)
        {
          // handle trace
          var newValue : Dynamic;
          if (infos != null && infos.customParams!=null) {
            var extra:String = "";
            for( v in infos.customParams )
              extra += "," + v;
            newValue = v + extra;
          }
          else {
            newValue = v;
          }
          var msg = infos != null ? infos.fileName + ':' + infos.lineNumber + ': ' : '';
          Sys.stderr().writeString('${msg}${newValue}\n');
        }
    }
    #end

}
thrift-0.23.0/test/haxe/src/TestClient.hx0000664000175000017500000010156615165535636020520 0ustar00buildbuild00000000000000/*
 * 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;

import haxe.Int32;
import haxe.Int64;
import haxe.io.Bytes;
import haxe.Timer;
import haxe.ds.IntMap;
import haxe.ds.StringMap;
import haxe.ds.ObjectMap;

import uuid.Uuid;

import org.apache.thrift.*;
import org.apache.thrift.helper.*;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;

#if cpp
import sys.thread.Thread;
#else
// no thread support (yet)
#end

import thrift.test.*;  // generated code


using StringTools;

class TestResults {
    private var successCnt : Int = 0;
    private var errorCnt : Int = 0;
    private var failedTests : String = "";
    private var print_direct : Bool = false;

    public static var EXITCODE_SUCCESS            = 0x00;  // no errors bits set
    //
    public static var EXITCODE_FAILBIT_BASETYPES  = 0x01;
    public static var EXITCODE_FAILBIT_STRUCTS    = 0x02;
    public static var EXITCODE_FAILBIT_CONTAINERS = 0x04;
    public static var EXITCODE_FAILBIT_EXCEPTIONS = 0x08;
    //
    public static var EXITCODE_ALL_FAILBITS       = 0x0F;
    //
    private var testsExecuted : Int = 0;
    private var testsFailed : Int = 0;
    private var currentTest : Int = 0;


    public function new(direct : Bool) {
        print_direct = direct;
    }

    public function StartTestGroup( groupBit : Int) : Void {
        currentTest = groupBit;
        testsExecuted |= groupBit;
    }

    public function Expect( expr : Bool, msg : String) : Void {
        if ( expr) {
            ++successCnt;
        } else {
            ++errorCnt;
            testsFailed |= currentTest;
            failedTests += "\n  " + msg;
            if( print_direct) {
                trace('FAIL: $msg');
            }
        }
    }

    public function CalculateExitCode() : Int {
        var notExecuted : Int = EXITCODE_ALL_FAILBITS & (~testsExecuted);
        return testsFailed | notExecuted;
    }

    public function PrintSummary() : Void {
        var total = successCnt + errorCnt;
        var sp = Math.round((1000 * successCnt) / total) / 10;
        var ep = Math.round((1000 * errorCnt) / total) / 10;

        trace('===========================');
        trace('Tests executed    $total');
        trace('Tests succeeded   $successCnt ($sp%)');
        trace('Tests failed      $errorCnt ($ep%)');
        if ( errorCnt > 0)
        {
            trace('===========================');
            trace('FAILED TESTS: $failedTests');
        }
        trace('===========================');
    }
}


class TestClient {

    public static function Execute(args : Arguments) :  Void
    {
        var exitCode = 0xFF;
        try
        {
            var difft = Timer.stamp();

            if ( args.numThreads > 1) {
                #if cpp
                exitCode = MultiThreadClient(args);
                #else
                trace('Threads not supported/implemented for this platform.');
                exitCode = SingleThreadClient(args);
                #end
            } else {
                exitCode = SingleThreadClient(args);
            }

            difft = Math.round( 1000 * (Timer.stamp() - difft)) / 1000;
            trace('total test time: $difft seconds');
        }
        catch (e : TException)
        {
            trace('TException: $e');
            exitCode = 0xFF;
        }
        catch (e : Dynamic)
        {
            trace('Exception: $e');
            exitCode = 0xFF;
        }

        #if sys
        Sys.exit( exitCode);
        #end
    }


    public static function SingleThreadClient(args : Arguments) :  Int
    {
        var rslt = new TestResults(true);
        RunClient(args,rslt);
        rslt.PrintSummary();
        return rslt.CalculateExitCode();
    }


    #if cpp
    public static function MultiThreadClient(args : Arguments) :  Int
    {
        var threads = new List();
        for( test in 0 ... args.numThreads) {
            threads.add( StartThread( args));
        }
        var exitCode : Int = 0;
        for( thread in threads) {
            exitCode |= Thread.readMessage(true);
        }
        return exitCode;
    }
    #end

    #if cpp
    private static function StartThread(args : Arguments) : Thread {
        var thread = Thread.create(
            function() : Void {
                var rslt = new TestResults(false);
                var main : Thread = Thread.readMessage(true);
                try
                {
                    RunClient(args,rslt);
                }
                catch (e : TException)
                {
                    rslt.Expect( false, '$e');
                    trace('$e');
                }
                catch (e : Dynamic)
                {
                    rslt.Expect( false, '$e');
                    trace('$e');
                }
                main.sendMessage( rslt.CalculateExitCode());
            });

        thread.sendMessage(Thread.current());
        return thread;
    }
    #end


    public static function RunClient(args : Arguments, rslt : TestResults)
    {
        var transport : TTransport = null;
        switch (args.transport)
        {
            case socket:
                transport = new TSocket(args.host, args.port);
            case http:
                var uri = 'http://${args.host}:${args.port}';
                trace('- http client : ${uri}');
                transport = new THttpClient(uri);
            default:
                throw "Unhandled transport";
        }

        // optional: layered transport
        if ( args.framed) {
            trace("- framed transport");
            transport = new TFramedTransport(transport);
        }
        if ( args.buffered) {
            trace("- buffered transport");
            transport = new TBufferedTransport(transport);
        }

        // protocol
        var protocol : TProtocol = null;
        switch( args.protocol)
        {
        case binary:
            trace("- binary protocol");
            protocol = new TBinaryProtocol(transport);
        case json:
            trace("- json protocol");
            protocol = new TJSONProtocol(transport);
        case compact:
            trace("- compact protocol");
            protocol = new TCompactProtocol(transport);
        }

        // some quick and basic unit tests
        HaxeBasicsTest( args, rslt);
        ModuleUnitTests( args, rslt);

        // now run the test code
        trace('- ${args.numIterations} iterations');
        for( i in 0 ... args.numIterations) {
            ClientTest( transport, protocol, args, rslt);
        }
    }


    public static function HaxeBasicsTest( args : Arguments, rslt : TestResults) : Void
    {
        // We need to test a few basic things used in the ClientTest
        // Anything else beyond this scope should go into /lib/haxe/ instead
        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_BASETYPES);

        var map32 = new IntMap();
        var map64 = new Int64Map();

        rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map Test #1");
        rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map Test #2");
        rslt.Expect( map32.remove( 4711) == map64.remove( Int64.make(47,11)), "Int64Map Test #3");
        rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map Test #4");

        map32.set( 42, 815);
        map64.set( Int64.make(0,42), 815);
        map32.set( -517, 23);
        map64.set( Int64.neg(Int64.make(0,517)), 23);
        map32.set( 0, -123);
        map64.set( Int64.make(0,0), -123);

        //trace('map32 = $map32');
        //trace('map64 = $map64');

        rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map Test #10");
        rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map Test #11");
        rslt.Expect( map32.exists( -517) == map64.exists( Int64.neg(Int64.make(0,517))), "Int64Map Test #12");
        rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map Test #13");
        rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map Test #14");
        rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map Test #15");
        rslt.Expect( map32.get( -517) == map64.get( Int64.neg(Int64.make(0,517))), "Int64Map Test #16");
        rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map Test #Int64.make(-5,17)");
        rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map Test #18");
        rslt.Expect( map32.remove( 4711) == map64.remove( Int64.make(47,11)), "Int64Map Test #19");
        rslt.Expect( map32.remove( -517) == map64.remove( Int64.neg(Int64.make(0,517))), "Int64Map Test #20");
        rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map Test #21");
        rslt.Expect( map32.exists( -517) == map64.exists( Int64.neg(Int64.make(0,517))), "Int64Map Test #22");
        rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map Test #23");
        rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map Test #24");
        rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map Test #25");
        rslt.Expect( map32.get( -517) == map64.get( Int64.neg(Int64.make(0,517))), "Int64Map Test #26");
        rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map Test #27");
        rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map Test #28");

        map32.set( 42, 1);
        map64.set( Int64.make(0,42), 1);
        map32.set( -517, -2);
        map64.set( Int64.neg(Int64.make(0,517)), -2);
        map32.set( 0, 3);
        map64.set( Int64.make(0,0), 3);

        var c32 = 0;
        var ksum32 = 0;
        for (key in map32.keys()) {
            ++c32;
            ksum32 += key;
        }
        var c64 = 0;
        var ksum64 = Int64.make(0,0);
        for (key in map64.keys()) {
            ++c64;
            ksum64 = Int64.add( ksum64, key);
        }
        rslt.Expect( c32 == c64, "Int64Map Test #30");
        rslt.Expect( '$ksum64' == '$ksum32', '$ksum64 == $ksum32   Test #31');

        //compare without spaces because differ in php and cpp
        var s32 = map32.toString().replace(' ', '');
        var s64 = map64.toString().replace(' ', '');
        rslt.Expect( s32 == s64, "Int64Map.toString(): " + ' ("$s32" == "$s64") Test #32');

        map32.remove( 42);
        map64.remove( Int64.make(0,42));
        map32.remove( -517);
        map64.remove( Int64.neg(Int64.make(0,517)));
        map32.remove( 0);
        map64.remove( Int64.make(0,0));

        rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map Test #90");
        rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map Test #91");
        rslt.Expect( map32.exists( -517) == map64.exists( Int64.neg(Int64.make(0,517))), "Int64Map Test #92");
        rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map Test #93");
        rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map Test #94");
        rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map Test #95");
        rslt.Expect( map32.get( -517) == map64.get( Int64.make(-5,17)), "Int64Map Test #96");
        rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map Test #97");
        rslt.Expect( map32.get( 0) == map64.get( Int64.make(0, 0)), "Int64Map Test #98");
    }


    // core module unit tests
    public static function ModuleUnitTests( args : Arguments, rslt : TestResults) : Void {
        #if debug

        try {
            BitConverter.UnitTest();
            rslt.Expect( true, 'BitConverter.UnitTest  Test #100');
        }
        catch( e : Dynamic) {
            rslt.Expect( false, 'BitConverter.UnitTest: $e  Test #100');
        }

        try {
            ZigZag.UnitTest();
            rslt.Expect( true, 'ZigZag.UnitTest  Test #101');
        }
        catch( e : Dynamic) {
            rslt.Expect( false, 'ZigZag.UnitTest: $e  Test #101');
        }

        try {
            UuidHelper.UnitTest();
            rslt.Expect( true, 'UuidHelper.UnitTest  Test #102');
        }
        catch( e : Dynamic) {
            rslt.Expect( false, 'UuidHelper.UnitTest: $e  Test #102');
        }

        #end
    }


    public static function BytesToHex(data : Bytes) : String {
        var hex = "";
        for ( i in 0 ... data.length) {
            hex += StringTools.hex( data.get(i), 2);
        }
        return hex;
    }

    public static function PrepareTestData(randomDist : Bool) : Bytes    {
        var retval = Bytes.alloc(0x100);
        var initLen : Int = (retval.length > 0x100 ? 0x100 : retval.length);

        // linear distribution, unless random is requested
        if (!randomDist) {
            for (i in 0 ... initLen) {
                retval.set(i, i % 0x100);
            }
            return retval;
        }

        // random distribution
        for (i in 0 ... initLen) {
            retval.set(i, 0);
        }
        for (i in 1 ... initLen) {
            while( true) {
                var nextPos = Std.random(initLen);
                if (retval.get(nextPos) == 0) {
                    retval.set( nextPos, i % 0x100);
                    break;
                }
            }
        }
        return retval;
    }


    public static function ClientTest( transport : TTransport, protocol : TProtocol,
                                       args : Arguments, rslt : TestResults) : Void
    {
        var client = new ThriftTestImpl(protocol,protocol);
        try
        {
            if (!transport.isOpen())
            {
                transport.open();
            }
        }
        catch (e : TException)
        {
            rslt.Expect( false, 'unable to open transport: $e');
            return;
        }
        catch (e : Dynamic)
        {
            rslt.Expect( false, 'unable to open transport: $e');
            return;
        }

        var start = Date.now();

        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_EXCEPTIONS);

        // if arg == "Xception" throw Xception with errorCode = 1001 and message = arg
        trace('testException("Xception")');
        try {
            client.testException("Xception");
            rslt.Expect( false, 'testException("Xception") should throw');
        }
        catch (e : Xception)
        {
            rslt.Expect( e.message == "Xception", 'testException("Xception")  -  e.message == "Xception"');
            rslt.Expect( e.errorCode == 1001, 'testException("Xception")  -  e.errorCode == 1001');
        }
        catch (e : TException)
        {
            rslt.Expect( false, 'testException("Xception")  -  ${e} : ${e.errorMsg}');
        }
        catch (e : Dynamic)
        {
            rslt.Expect( false, 'testException("Xception")  -  $e');
        }

        // if arg == "TException" throw TException
        trace('testException("TException")');
        try {
            client.testException("TException");
            rslt.Expect( false, 'testException("TException") should throw');
        }
        catch (e : TException)
        {
            rslt.Expect( true, 'testException("TException")  -  $e : ${e.errorMsg}');
        }
        catch (e : Dynamic)
        {
            rslt.Expect( false, 'testException("TException")  -  $e');
        }

        // reopen the transport, just in case the server closed his end
        if (transport.isOpen())
            transport.close();
        transport.open();

        // else do not throw anything
        trace('testException("bla")');
        try {
            client.testException("bla");
            rslt.Expect( true, 'testException("bla") should not throw');
        }
        catch (e : TException)
        {
            rslt.Expect( false, 'testException("bla")  -  ${e} : ${e.errorMsg}');
        }
        catch (e : Dynamic)
        {
            rslt.Expect( false, 'testException("bla")  -  $e');
        }

        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_BASETYPES);

        trace('testVoid()');
        client.testVoid();
        trace(' = void');
        rslt.Expect(true,"testVoid()");  // bump counter

        trace('testBool(${true})');
        var b = client.testBool(true);
        trace(' = $b');
        rslt.Expect(b, '$b == "${true}"');
        trace('testBool(${false})');
        b = client.testBool(false);
        trace(' = $b');
        rslt.Expect( ! b, '$b == "${false}"');

        trace('testString("Test")');
        var s = client.testString("Test");
        trace(' = "$s"');
        rslt.Expect(s == "Test", '$s == "Test"');

        trace('testByte(1)');
        var i8 = client.testByte(1);
        trace(' = $i8');
        rslt.Expect(i8 == 1, '$i8 == 1');

        trace('testI32(-1)');
        var i32 = client.testI32(-1);
        trace(' = $i32');
        rslt.Expect(i32 == -1, '$i32 == -1');

        trace('testI64(-34359738368)');
        var i64 = client.testI64( Int64.make( 0xFFFFFFF8, 0x00000000)); // -34359738368
        trace(' = $i64');
        rslt.Expect( Int64.compare( i64, Int64.make( 0xFFFFFFF8, 0x00000000)) == 0,
                     Int64.toStr(i64) +" == "+Int64.toStr(Int64.make( 0xFFFFFFF8, 0x00000000)));

        // edge case: the largest negative Int64 has no positive Int64 equivalent
        trace('testI64(-9223372036854775808)');
        i64 = client.testI64( Int64.make( 0x80000000, 0x00000000)); // -9223372036854775808
        trace(' = $i64');
        rslt.Expect( Int64.compare( i64, Int64.make( 0x80000000, 0x00000000)) == 0,
                     Int64.toStr(i64) +" == "+Int64.toStr(Int64.make( 0x80000000, 0x00000000)));

        trace('testDouble(5.325098235)');
        var dub = client.testDouble(5.325098235);
        trace(' = $dub');
        rslt.Expect(dub == 5.325098235, '$dub == 5.325098235');


		var uuidOut : String = UuidHelper.CanonicalUuid("{00112233-4455-6677-8899-AABBCCDDEEFF}");
        trace('testUuid(${uuidOut}');
        try {
            var uuidIn = client.testUuid(uuidOut);
            trace('testUuid() = ${uuidIn}');
            rslt.Expect( uuidIn == uuidOut, '${uuidIn} == ${uuidOut}');
        }
        catch (e : TApplicationException) {
            trace('testUuid(${uuidOut}): '+e.errorMsg);  // may not be supported by the server
        }

        
        var binOut = PrepareTestData(true);
        trace('testBinary('+BytesToHex(binOut)+')');
        try {
            var binIn = client.testBinary(binOut);
            trace('testBinary() = '+BytesToHex(binIn));
            rslt.Expect( binIn.length == binOut.length, '${binIn.length} == ${binOut.length}');
            var len = ((binIn.length < binOut.length)  ?  binIn.length  : binOut.length);
            for (ofs in 0 ... len) {
                if (binIn.get(ofs) != binOut.get(ofs)) {
                    rslt.Expect( false, 'testBinary('+BytesToHex(binOut)+'): content mismatch at offset $ofs');
                }
            }
        }
        catch (e : TApplicationException) {
            trace('testBinary('+BytesToHex(binOut)+'): '+e.errorMsg);  // may not be supported by the server
        }


        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_STRUCTS);

        trace('testStruct({"Zero", 1, -3, -5})');
        var o = new Xtruct();
        o.string_thing = "Zero";
        o.byte_thing = 1;
        o.i32_thing = -3;
        o.i64_thing = Int64.make(0,-5);
        var i = client.testStruct(o);
        trace(' = {"' + i.string_thing + '", ' + i.byte_thing +', '
                      + i.i32_thing +', '+ Int64.toStr(i.i64_thing) + '}');
        rslt.Expect( i.string_thing == o.string_thing, "i.string_thing == o.string_thing");
        rslt.Expect( i.byte_thing == o.byte_thing, "i.byte_thing == o.byte_thing");
        rslt.Expect( i.i32_thing == o.i32_thing, "i.i64_thing == o.i64_thing");
        rslt.Expect( i.i32_thing == o.i32_thing, "i.i64_thing == o.i64_thing");

        trace('testNest({1, {\"Zero\", 1, -3, -5}, 5})');
        var o2 = new Xtruct2();
        o2.byte_thing = 1;
        o2.struct_thing = o;
        o2.i32_thing = 5;
        var i2 = client.testNest(o2);
        i = i2.struct_thing;
        trace(" = {" + i2.byte_thing + ", {\"" + i.string_thing + "\", "
              + i.byte_thing + ", " + i.i32_thing + ", " + Int64.toStr(i.i64_thing) + "}, "
              + i2.i32_thing + "}");
        rslt.Expect( i2.byte_thing == o2.byte_thing, "i2.byte_thing == o2.byte_thing");
        rslt.Expect( i2.i32_thing == o2.i32_thing, "i2.i32_thing == o2.i32_thing");
        rslt.Expect( i.string_thing == o.string_thing, "i.string_thing == o.string_thing");
        rslt.Expect( i.byte_thing == o.byte_thing, "i.byte_thing == o.byte_thing");
        rslt.Expect( i.i32_thing == o.i32_thing, "i.i32_thing == o.i32_thing");
        rslt.Expect( Int64.compare( i.i64_thing, o.i64_thing) == 0, "i.i64_thing == o.i64_thing");


        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_CONTAINERS);

        var mapout = new IntMap< haxe.Int32>();
        for ( j in 0 ... 5)
        {
            mapout.set(j, j - 10);
        }
        trace("testMap({");
        var first : Bool = true;
        for( key in mapout.keys())
        {
            if (first)
            {
                first = false;
            }
            else
            {
                trace(", ");
            }
            trace(key + " => " + mapout.get(key));
        }
        trace("})");

        var mapin = client.testMap(mapout);

        trace(" = {");
        first = true;
        for( key in mapin.keys())
        {
            if (first)
            {
                first = false;
            }
            else
            {
                trace(", ");
            }
            trace(key + " => " + mapin.get(key));
            rslt.Expect( mapin.get(key) == mapout.get(key), ' mapin.get($key) == mapout.get($key)');
        }
        trace("}");
        for( key in mapout.keys())
        {
            rslt.Expect(mapin.exists(key), 'mapin.exists($key)');
        }

        var listout = new List();
        for (j in -2 ... 3)
        {
            listout.add(j);
        }
        trace("testList({");
        first = true;
        for( j in listout)
        {
            if (first)
            {
                first = false;
            }
            else
            {
                trace(", ");
            }
            trace(j);
        }
        trace("})");

        var listin = client.testList(listout);

        trace(" = {");
        first = true;
        for( j in listin)
        {
            if (first)
            {
                first = false;
            }
            else
            {
                trace(", ");
            }
            trace(j);
        }
        trace("}");

        rslt.Expect(listin.length == listout.length, "listin.length == listout.length");
        var literout = listout.iterator();
        var literin = listin.iterator();
        while( literin.hasNext()) {
            rslt.Expect(literin.next() == literout.next(), "literin[i] == literout[i]");
        }

        //set
        var setout = new IntSet();
        for (j in -2 ... 3)
        {
            setout.add(j);
        }
        trace("testSet({");
        first = true;
        for( j in setout)
        {
            if (first)
            {
                first = false;
            }
            else
            {
                trace(", ");
            }
            trace(j);
        }
        trace("})");

        var setin = client.testSet(setout);

        trace(" = {");
        first = true;
        for( j in setin)
        {
            if (first)
            {
                first = false;
            }
            else
            {
                trace(", ");
            }
            trace(j);
            rslt.Expect(setout.contains(j), 'setout.contains($j)');
        }
        trace("}");
        rslt.Expect(setin.size == setout.size, "setin.length == setout.length");


        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_BASETYPES);

        trace("testEnum(ONE)");
        var ret = client.testEnum(Numberz.ONE);
        trace(" = " + ret);
        rslt.Expect(ret == Numberz.ONE, '$ret == Numberz.ONE');

        trace("testEnum(TWO)");
        ret = client.testEnum(Numberz.TWO);
        trace(" = " + ret);
        rslt.Expect(ret == Numberz.TWO, '$ret == Numberz.TWO');

        trace("testEnum(THREE)");
        ret = client.testEnum(Numberz.THREE);
        trace(" = " + ret);
        rslt.Expect(ret == Numberz.THREE, '$ret == Numberz.THREE');

        trace("testEnum(FIVE)");
        ret = client.testEnum(Numberz.FIVE);
        trace(" = " + ret);
        rslt.Expect(ret == Numberz.FIVE, '$ret == Numberz.FIVE');

        trace("testEnum(EIGHT)");
        ret = client.testEnum(Numberz.EIGHT);
        trace(" = " + ret);
        rslt.Expect(ret == Numberz.EIGHT, '$ret == Numberz.EIGHT');

        trace("testTypedef(309858235082523)");
        var uid = client.testTypedef( Int64.make( 0x119D0, 0x7E08671B));  // 309858235082523
        trace(" = " + uid);
        rslt.Expect( Int64.compare( uid, Int64.make( 0x119D0, 0x7E08671B)) == 0,
                     Int64.toStr(uid)+" == "+Int64.toStr(Int64.make( 0x119D0, 0x7E08671B)));


        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_CONTAINERS);

        trace("testMapMap(1)");
        var mm = client.testMapMap(1);
        trace(" = {");
        for( key in mm.keys())
        {
            trace(key + " => {");
            var m2 = mm.get(key);
            for( k2 in m2.keys())
            {
                trace(k2 + " => " + m2.get(k2) + ", ");
            }
            trace("}, ");
        }
        trace("}");

        var pos = mm.get(4);
        var neg = mm.get(-4);
        rslt.Expect( (pos != null) && (neg != null), "(pos != null) && (neg != null)");
        for (i in 1 ... 5) {
            rslt.Expect( pos.get(i) == i, 'pos.get($i) == $i');
            rslt.Expect( neg.get(-i) == -i, 'neg.get(-$i) == -$i');
        }
        rslt.Expect( ! pos.exists(0), '!pos.exists(0)');
        rslt.Expect( ! neg.exists(-0), '!neg.exists(-0)');
        rslt.Expect( ! pos.exists(42), '!pos.exists(42)');
        rslt.Expect( ! neg.exists(-42), '!neg.exists(-42)');


        rslt.StartTestGroup( TestResults.EXITCODE_FAILBIT_STRUCTS);

        var insane = new Insanity();
        insane.userMap = new IntMap< Int64>();
        insane.userMap.set( Numberz.FIVE, Int64.make(0,5000));
        var truck = new Xtruct();
        truck.string_thing = "Truck";
        truck.byte_thing = 8;
        truck.i32_thing = 8;
        truck.i64_thing = Int64.make(0,8);
        insane.xtructs = new List();
        insane.xtructs.add(truck);
        trace("testInsanity()");
        var whoa = client.testInsanity(insane);
        trace(" = {");
        for( key in whoa.keys())
        {
            var val = whoa.get(key);
            trace(key + " => {");

            for( k2 in val.keys())
            {
                var v2 = val.get(k2);

                trace(k2 + " => {");
                var userMap = v2.userMap;

                trace("{");
                if (userMap != null)
                {
                    for( k3 in userMap.keys())
                    {
                        trace(k3 + " => " + userMap.get(k3) + ", ");
                    }
                }
                else
                {
                    trace("null");
                }
                trace("}, ");

                var xtructs = v2.xtructs;

                trace("{");
                if (xtructs != null)
                {
                    for( x in xtructs)
                    {
                        trace("{\"" + x.string_thing + "\", "
                              + x.byte_thing + ", " + x.i32_thing + ", "
                              + x.i32_thing + "}, ");
                    }
                }
                else
                {
                    trace("null");
                }
                trace("}");

                trace("}, ");
            }
            trace("}, ");
        }
        trace("}");


		/**
		* So you think you've got this all worked, out eh?
		*
		* Creates a the returned map with these values and prints it out:
		*   { 1 => { 2 => argument,
		*            3 => argument,
		*          },
		*     2 => { 6 => , },
		*   }
		* @return map> - a map with the above values
		*/
		
        var first_map = whoa.get(Int64.make(0,1));
        var second_map = whoa.get(Int64.make(0,2));
        rslt.Expect( (first_map != null) && (second_map != null), "(first_map != null) && (second_map != null)");
        if ((first_map != null) && (second_map != null))
        {
            var crazy2 = first_map.get(Numberz.TWO);
            var crazy3 = first_map.get(Numberz.THREE);
            var looney = second_map.get(Numberz.SIX);
            rslt.Expect( (crazy2 != null) && (crazy3 != null) && (looney != null),
                        "(crazy2 != null) && (crazy3 != null) && (looney != null)");

            var crz2iter = crazy2.xtructs.iterator();
            var crz3iter = crazy3.xtructs.iterator();
            rslt.Expect( crz2iter.hasNext() && crz3iter.hasNext(), "crz2iter.hasNext() && crz3iter.hasNext()");
            var goodbye2 = crz2iter.next();
            var goodbye3 = crz3iter.next();
            rslt.Expect( ! (crz2iter.hasNext() || crz3iter.hasNext()), "! (crz2iter.hasNext() || crz3iter.hasNext())");

			rslt.Expect( Int64.compare( crazy2.userMap.get(Numberz.FIVE), insane.userMap.get(Numberz.FIVE)) == 0, "crazy2.userMap[5] == insane.userMap[5]");
			rslt.Expect( truck.string_thing == goodbye2.string_thing, "truck.string_thing == goodbye2.string_thing");
			rslt.Expect( truck.byte_thing  == goodbye2.byte_thing, "truck.byte_thing  == goodbye2.byte_thing");
			rslt.Expect( truck.i32_thing  == goodbye2.i32_thing, "truck.i32_thing  == goodbye2.i32_thing");
			rslt.Expect( Int64.compare( truck.i64_thing, goodbye2.i64_thing) == 0, "truck.i64_thing  == goodbye2.i64_thing");

			rslt.Expect( Int64.compare( crazy3.userMap.get(Numberz.FIVE), insane.userMap.get(Numberz.FIVE)) == 0, "crazy3.userMap[5] == insane.userMap[5]");
			rslt.Expect( truck.string_thing == goodbye3.string_thing, "truck.string_thing == goodbye3.string_thing");
			rslt.Expect( truck.byte_thing  == goodbye3.byte_thing, "truck.byte_thing  == goodbye3.byte_thing");
			rslt.Expect( truck.i32_thing  == goodbye3.i32_thing, "truck.i32_thing  == goodbye3.i32_thing");
			rslt.Expect( Int64.compare( truck.i64_thing, goodbye3.i64_thing) == 0, "truck.i64_thing  == goodbye3.i64_thing");
			
			rslt.Expect( ! looney.isSet(1), "! looney.isSet(1)");
			rslt.Expect( ! looney.isSet(2), "! looney.isSet(2)");
        }

        var arg0 = 1;
        var arg1 = 2;
        var arg2 = Int64.make( 0x7FFFFFFF,0xFFFFFFFF);
        var multiDict = new IntMap< String>();
        multiDict.set(1, "one");
        var arg4 = Numberz.FIVE;
        var arg5 = Int64.make(0,5000000);
        trace("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + "," + multiDict + "," + arg4 + "," + arg5 + ")");
        var multiResponse = client.testMulti(arg0, arg1, arg2, multiDict, arg4, arg5);
        trace(" = Xtruct(byte_thing:" + multiResponse.byte_thing + ",string_thing:" + multiResponse.string_thing
                    + ",i32_thing:" + multiResponse.i32_thing
                    + ",i64_thing:" + Int64.toStr(multiResponse.i64_thing) + ")");

        rslt.Expect( multiResponse.string_thing == "Hello2", 'multiResponse.String_thing == "Hello2"');
        rslt.Expect( multiResponse.byte_thing == arg0, 'multiResponse.Byte_thing == arg0');
        rslt.Expect( multiResponse.i32_thing == arg1, 'multiResponse.I32_thing == arg1');
        rslt.Expect( Int64.compare( multiResponse.i64_thing, arg2) == 0, 'multiResponse.I64_thing == arg2');


        rslt.StartTestGroup( 0);

        trace("Test Oneway(1)");
        client.testOneway(1);

        if( ! args.skipSpeedTest) {
            trace("Test Calltime()");
            var difft = Timer.stamp();
            for ( k in 0 ... 1000) {
                client.testVoid();
            }
            difft = Math.round( 1000 * (Timer.stamp() - difft)) / 1000;
            trace('$difft ms per testVoid() call');
        }
    }
}
thrift-0.23.0/test/haxe/php-web-server.hxml0000664000175000017500000000214115165535636021037 0ustar00buildbuild00000000000000#
# 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.
#
 
#integrate files to classpath
-cp src
-cp gen-haxe
-cp ../../lib/haxe/src

#this class wil be used as entry point for your app.
-main Main

#PHP target
-php bin/php-web-server
-D php-front=Main-debug.php

#defines
-D phpwebserver

# libs
-lib uuid

#Add debug information
-debug

#dead code elimination : remove unused code
-dce full
thrift-0.23.0/test/haxe/flash.hxml0000664000175000017500000000215715165535636017275 0ustar00buildbuild00000000000000#
# 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.
#
 
#integrate files to classpath
-cp src
-cp gen-haxe
-cp ../../lib/haxe/src

#this class wil be used as entry point for your app.
-main Main

#Flash target
-swf bin/ThriftTest.swf

# libs
-lib uuid

#Add debug information
-debug

# we need some goodies from sys.net
# --macro allowPackage("sys")

#dead code elimination : remove unused code
-dce fullthrift-0.23.0/test/haxe/javascript.hxml0000664000175000017500000000252315165535636020343 0ustar00buildbuild00000000000000#
# 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.
#
 
#integrate files to classpath
-cp src
-cp gen-haxe
-cp ../../lib/haxe/src

#this class wil be used as entry point for your app.
-main Main

#JavaScript target
-js bin/ThriftTest.js

#You can use -D source-map-content (requires Haxe 3.1+) to have the .hx 
#files directly embedded into the map file, this way you only have to 
#upload it, and it will be always in sync with the compiled .js even if 
#you modify your .hx files.
-D source-map-content

# libs
-lib uuid

#Generate source map and add debug information
-debug

#dead code elimination : remove unused code
-dce fullthrift-0.23.0/test/haxe/python.hxml0000664000175000017500000000205715165535636017520 0ustar00buildbuild00000000000000#
# 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.
#
 
#integrate files to classpath
-cp src
-cp gen-haxe
-cp ../../lib/haxe/src

#this class wil be used as entry point for your app.
-main Main

#Python target
-python bin/ThriftTest.py

# libs
-lib uuid

#Add debug information
-debug

#dead code elimination : remove unused code
-dce fullthrift-0.23.0/test/haxe/project.hide0000664000175000017500000000364715165535636017614 0ustar00buildbuild00000000000000{
     "type" : 0
    ,"target" : 4
    ,"name" : "Apache Thrift cross-platform test client/server"
    ,"main" : null
    ,"projectPackage" : ""
    ,"company" : "Apache Software Foundation (ASF)"
    ,"license" : "Apache License, Version 2.0"
    ,"url" : "http://www.apache.org/licenses/LICENSE-2.0"
    ,"targetData" : [
         {
             "pathToHxml" : "flash.hxml"
            ,"runActionType" : 1
            ,"runActionText" : "bin/Tutorial.swf"
        }
        ,{
             "pathToHxml" : "javascript.hxml"
            ,"runActionType" : 1
            ,"runActionText" : "bin\\index.html"
        }
        ,{
             "pathToHxml" : "neko.hxml"
            ,"runActionType" : 2
            ,"runActionText" : "neko bin/Tutorial.n"
        }
        ,{
             "pathToHxml" : "php.hxml"
        }
        ,{
             "pathToHxml" : "cpp.hxml"
            ,"runActionType" : 2
            ,"runActionText" : "bin/Main-debug.exe  client --protocol json"
        }
        ,{
             "pathToHxml" : "java.hxml"
        }
        ,{
             "pathToHxml" : "csharp.hxml"
        }
        ,{
             "pathToHxml" : "python.hxml"
            ,"runActionType" : 2
            ,"runActionText" : "python bin/Tutorial.py"
        }
    ]
    ,"files" : [
         {
             "path" : "src\\TestClient.hx"
            ,"useTabs" : true
            ,"indentSize" : 4
            ,"foldedRegions" : [

            ]
            ,"activeLine" : 188
        }
        ,{
             "path" : "src\\TestServer.hx"
            ,"useTabs" : true
            ,"indentSize" : 4
            ,"foldedRegions" : [

            ]
            ,"activeLine" : 88
        }
    ]
    ,"activeFile" : "src\\TestClient.hx"
    ,"openFLTarget" : null
    ,"openFLBuildMode" : "Debug"
    ,"runActionType" : null
    ,"runActionText" : null
    ,"buildActionCommand" : null
    ,"hiddenItems" : [

    ]
    ,"showHiddenItems" : false
}thrift-0.23.0/test/haxe/TestClientServer.hxproj0000664000175000017500000000406515165535636022007 0ustar00buildbuild00000000000000

  
  
    
    
    
    
    
    
    
    
    
    
  
  
  
    
    
    
  
  
  
    
  
  
    
  
  
  
    
  
  
  
    
    
    
    
    
    
    
    
    
    
    
    
    
  
  
  thrift -r -gen haxe  ../ThriftTest.thrift
  
  
  
  
    
  
  
thrift-0.23.0/test/haxe/make_all.bat0000664000175000017500000000354615165535636017546 0ustar00buildbuild00000000000000@echo off
rem /*
rem  * Licensed to the Apache Software Foundation (ASF) under one
rem  * or more contributor license agreements. See the NOTICE file
rem  * distributed with this work for additional information
rem  * regarding copyright ownership. The ASF licenses this file
rem  * to you under the Apache License, Version 2.0 (the
rem  * "License"); you may not use this file except in compliance
rem  * with the License. You may obtain a copy of the License at
rem  *
rem  *   http://www.apache.org/licenses/LICENSE-2.0
rem  *
rem  * Unless required by applicable law or agreed to in writing,
rem  * software distributed under the License is distributed on an
rem  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
rem  * KIND, either express or implied. See the License for the
rem  * specific language governing permissions and limitations
rem  * under the License.
rem  */

setlocal
if "%HOMEDRIVE%"=="" goto MISSINGVARS
if "%HOMEPATH%"=="" goto MISSINGVARS
if "%HAXEPATH%"=="" goto NOTINSTALLED

set path=%HAXEPATH%;%HAXEPATH%\..\neko;%path%

rem # invoke Thrift comnpiler
thrift -r -gen haxe   ..\ThriftTest.thrift
if errorlevel 1 goto STOP

rem # invoke Haxe compiler for all targets
rd .buildtemp /S /Q
for %%a in (*.hxml) do (
	echo --------------------------
	echo Building %%a ...
	echo --------------------------
	haxe  --cwd .  %%a
	if not exist ".buildtemp" mkdir ".buildtemp"
	move bin ".buildtemp\%%a"
	if errorlevel 1 pause
)

rd bin /S /Q
rename .buildtemp bin

echo.
echo done.
pause
goto eof

:NOTINSTALLED
echo FATAL: Either Haxe is not installed, or the HAXEPATH variable is not set.
pause
goto eof

:MISSINGVARS
echo FATAL: Unable to locate home folder.
echo.
echo Both HOMEDRIVE and HOMEPATH need to be set to point to your Home folder.
echo The current values are:
echo HOMEDRIVE=%HOMEDRIVE%
echo HOMEPATH=%HOMEPATH%
pause
goto eof

:STOP
pause
goto eof

:eof
thrift-0.23.0/test/haxe/router.php0000664000175000017500000000171415165535636017335 0ustar00buildbuild00000000000000&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/haxe
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
THRIFTCMD = $(THRIFT) --gen haxe -r
THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift
BIN_CPP = bin/Main-debug
BIN_PHP = bin/php/Main-debug.php
BIN_PHP_WEB = bin/php-web-server/Main-debug.php
EXTRA_DIST = \
	src \
	cpp.hxml \
	csharp.hxml \
	flash.hxml \
	java.hxml \
	javascript.hxml \
	neko.hxml \
	php.hxml \
	python.hxml \
	router.php \
	project.hide \
	php-web-server.hxml \
	TestClientServer.hxproj \
	make_all.bat \
	make_all.sh

all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/haxe/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/haxe/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile all-local
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am all-local check check-am clean clean-generic \
	clean-libtool clean-local cscopelist-am ctags-am distclean \
	distclean-generic distclean-libtool distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


gen-haxe/thrift/test/ThriftTest.hx: $(THRIFTTEST)
	$(THRIFTCMD) $(THRIFTTEST)

all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_PHP_WEB)

$(BIN_CPP): \
		src/*.hx \
		../../lib/haxe/src/org/apache/thrift/**/*.hx \
		gen-haxe/thrift/test/ThriftTest.hx
	$(HAXE) --cwd .  cpp.hxml

#	$(HAXE) --cwd .  csharp
#	$(HAXE) --cwd .  flash
#	$(HAXE) --cwd .  java
#	$(HAXE) --cwd .  javascript
#	$(HAXE) --cwd .  neko
#	$(HAXE) --cwd .  python

$(BIN_PHP): \
		src/*.hx \
		../../lib/haxe/src/org/apache/thrift/**/*.hx \
		gen-haxe/thrift/test/ThriftTest.hx
	$(HAXE) --cwd .  php.hxml

$(BIN_PHP_WEB): \
		src/*.hx \
		../../lib/haxe/src/org/apache/thrift/**/*.hx \
		gen-haxe/thrift/test/ThriftTest.hx
	$(HAXE) --cwd .  php-web-server.hxml

clean-local:
	$(RM) -r gen-haxe bin

.NOTPARALLEL:

check: check_cpp \
	check_php \
	check_php_web 

check_cpp: $(BIN_CPP) 
	timeout 20 $(BIN_CPP) server &
	sleep 1
	$(BIN_CPP) client
	sleep 10

check_php: $(BIN_PHP) 
	timeout 20 php -f $(BIN_PHP) server &
	sleep 1
	php -f $(BIN_PHP) client
	sleep 10

check_php_web: $(BIN_PHP_WEB) $(BIN_CPP)
	timeout 20 php -S 127.0.0.1:9090 router.php &
	sleep 1
	$(BIN_CPP) client --transport http
	sleep 10

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/haxe/php.hxml0000664000175000017500000000207415165535636016765 0ustar00buildbuild00000000000000#
# 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.
#
 
#integrate files to classpath
-cp src
-cp gen-haxe
-cp ../../lib/haxe/src

#this class wil be used as entry point for your app.
-main Main

#PHP target
-php bin/php
-D php-front=Main-debug.php

# libs
-lib uuid

#Add debug information
-debug

#dead code elimination : remove unused code
-dce full
thrift-0.23.0/test/haxe/Makefile.am0000664000175000017500000000461315165535636017341 0ustar00buildbuild00000000000000#
# 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.
#

THRIFTCMD = $(THRIFT) --gen haxe -r
THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift

BIN_CPP = bin/Main-debug
BIN_PHP = bin/php/Main-debug.php
BIN_PHP_WEB = bin/php-web-server/Main-debug.php

gen-haxe/thrift/test/ThriftTest.hx: $(THRIFTTEST)
	$(THRIFTCMD) $(THRIFTTEST)

all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_PHP_WEB)

$(BIN_CPP): \
		src/*.hx \
		../../lib/haxe/src/org/apache/thrift/**/*.hx \
		gen-haxe/thrift/test/ThriftTest.hx
	$(HAXE) --cwd .  cpp.hxml
	
#	$(HAXE) --cwd .  csharp
#	$(HAXE) --cwd .  flash
#	$(HAXE) --cwd .  java
#	$(HAXE) --cwd .  javascript
#	$(HAXE) --cwd .  neko
#	$(HAXE) --cwd .  python

$(BIN_PHP): \
		src/*.hx \
		../../lib/haxe/src/org/apache/thrift/**/*.hx \
		gen-haxe/thrift/test/ThriftTest.hx
	$(HAXE) --cwd .  php.hxml

$(BIN_PHP_WEB): \
		src/*.hx \
		../../lib/haxe/src/org/apache/thrift/**/*.hx \
		gen-haxe/thrift/test/ThriftTest.hx
	$(HAXE) --cwd .  php-web-server.hxml



clean-local:
	$(RM) -r gen-haxe bin

.NOTPARALLEL:

check: check_cpp \
	check_php \
	check_php_web 

check_cpp: $(BIN_CPP) 
	timeout 20 $(BIN_CPP) server &
	sleep 1
	$(BIN_CPP) client
	sleep 10

check_php: $(BIN_PHP) 
	timeout 20 php -f $(BIN_PHP) server &
	sleep 1
	php -f $(BIN_PHP) client
	sleep 10

check_php_web: $(BIN_PHP_WEB) $(BIN_CPP)
	timeout 20 php -S 127.0.0.1:9090 router.php &
	sleep 1
	$(BIN_CPP) client --transport http
	sleep 10


distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	src \
	cpp.hxml \
	csharp.hxml \
	flash.hxml \
	java.hxml \
	javascript.hxml \
	neko.hxml \
	php.hxml \
	python.hxml \
	router.php \
	project.hide \
	php-web-server.hxml \
	TestClientServer.hxproj \
	make_all.bat \
	make_all.sh
thrift-0.23.0/test/TypedefTest.thrift0000664000175000017500000000226215165535636020040 0ustar00buildbuild00000000000000/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * Contains some contributions under the Thrift Software License.
 * Please see doc/old-thrift-license.txt in the Thrift distribution for
 * details.
 */

namespace cpp thrift.test

typedef i32 MyInt32
typedef string MyString;

struct TypedefTestStruct {
  1: MyInt32 field_MyInt32;
  2: MyString field_MyString;
  3: i32 field_Int32;
  4: string field_String;
}

typedef TypedefTestStruct MyStruct,thrift-0.23.0/test/DebugProtoTest.thrift0000664000175000017500000002422715167543515020514 0ustar00buildbuild00000000000000/*
 * 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 c_glib TTest
namespace cpp thrift.test.debug
namespace java thrift.test
namespace rb Thrift.Test

struct Doubles {
 1: double nan,
 2: double inf,
 3: double neginf,
 4: double repeating,
 5: double big,
 6: double tiny,
 7: double zero,
 8: double negzero,
}

struct OneOfEach {
  1: bool im_true,
  2: bool im_false,
  3: i8 a_bite = 0x7f,
  4: i16 integer16 = 0x7fff,
  5: i32 integer32,
  6: i64 integer64 = 10000000000,
  7: double double_precision,
  8: string some_characters,
  9: string zomg_unicode,
  10: bool what_who,
  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,
  16: list rfc4122_uuid_list,
}

struct Bonk {
  1: i32 type,
  2: string message,
}

struct Nesting {
  1: Bonk my_bonk,
  2: OneOfEach my_ooe,
}

struct HolyMoley {
  1: list big,
  2: set (python.immutable = "")> contain,
  3: map> bonks,
}

struct Backwards {
  2: i32 first_tag2,
  1: i32 second_tag1,
}

struct Empty {
} (
  python.immutable = "",
)

struct Wrapper {
  1: Empty foo
} (
  python.immutable = "",
)

struct RandomStuff {
  1: i32 a,
  2: i32 b,
  3: i32 c,
  4: i32 d,
  5: list myintlist,
  6: map maps,
  7: i64 bigint,
  8: double triple,
}

struct Base64 {
  1: i32 a,
  2: binary b1,
  3: binary b2,
  4: binary b3,
  5: binary b4,
  6: binary b5,
  7: binary b6,
}

struct CompactProtoTestStruct {
  // primitive fields
  1: i8     a_byte;
  2: i16    a_i16;
  3: i32    a_i32;
  4: i64    a_i64;
  5: double a_double;
  6: string a_string;
  7: binary a_binary;
  8: bool   true_field;
  9: bool   false_field;
  10: Empty empty_struct_field;

  // primitives in lists
  11: list      byte_list;
  12: list     i16_list;
  13: list     i32_list;
  14: list     i64_list;
  15: list  double_list;
  16: list  string_list;
  17: list  binary_list;
  18: list    boolean_list;
  19: list   struct_list;

  // primitives in sets
  20: set       byte_set;
  21: set      i16_set;
  22: set      i32_set;
  23: set      i64_set;
  24: set   double_set;
  25: set   string_set;
  26: set   binary_set;
  27: set     boolean_set;
  28: set    struct_set;

  // maps
  // primitives as keys
  29: map               byte_byte_map;
  30: map              i16_byte_map;
  31: map              i32_byte_map;
  32: map              i64_byte_map;
  33: map           double_byte_map;
  34: map           string_byte_map;
  35: map           binary_byte_map;
  36: map             boolean_byte_map;
  // primitives as values
  37: map              byte_i16_map;
  38: map              byte_i32_map;
  39: map              byte_i64_map;
  40: map           byte_double_map;
  41: map           byte_string_map;
  42: map           byte_binary_map;
  43: map             byte_boolean_map;
  // collections as keys
  44: map (python.immutable = ""), i8>       list_byte_map;
  45: map (python.immutable = ""), i8>        set_byte_map;
  46: map (python.immutable = ""), i8>     map_byte_map;
  // collections as values
  47: map>     byte_map_map;
  48: map>        byte_set_map;
  49: map>       byte_list_map;
  
  // large field IDs
  500 : i64  field500;
  5000 : i64  field5000;
  20000 : i64  field20000;
}

// To be used to test the serialization of an empty map
struct SingleMapTestStruct {
  1: required map       i32_map;
}

const CompactProtoTestStruct COMPACT_TEST = {
  'a_byte'             : 127,
  'a_i16'              : 32000,
  'a_i32'              : 1000000000,
  'a_i64'              : 0xffffffffff,
  'a_double'           : 5.6789,
  'a_string'           : "my string",
//'a_binary,'
  'true_field'         : 1,
  'false_field'        : 0,
  'empty_struct_field' : {},
  'byte_list'          : [-127, -1, 0, 1, 127],
  'i16_list'           : [-1, 0, 1, 0x7fff],
  'i32_list'           : [-1, 0, 0xff, 0xffff, 0xffffff, 0x7fffffff],
  'i64_list'           : [-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff],
  'double_list'        : [0.1, 0.2, 0.3],
  'string_list'        : ["first", "second", "third"],
//'binary_list,'
  'boolean_list'       : [1, 1, 1, 0, 0, 0],
  'struct_list'        : [{}, {}],
  'byte_set'           : [-127, -1, 0, 1, 127],
  'i16_set'            : [-1, 0, 1, 0x7fff],
  'i32_set'            : [1, 2, 3],
  'i64_set'            : [-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff],
  'double_set'         : [0.1, 0.2, 0.3],
  'string_set'         : ["first", "second", "third"],
//'binary_set,'
  'boolean_set'        : [1, 0],
  'struct_set'         : [{}],
  'byte_byte_map'      : {1 : 2},
  'i16_byte_map'       : {1 : 1, -1 : 1, 0x7fff : 1},
  'i32_byte_map'       : {1 : 1, -1 : 1, 0x7fffffff : 1},
  'i64_byte_map'       : {0 : 1,  1 : 1, -1 : 1, 0x7fffffffffffffff : 1},
  'double_byte_map'    : {-1.1 : 1, 1.1 : 1},
  'string_byte_map'    : {"first" : 1, "second" : 2, "third" : 3, "" : 0},
//'binary_byte_map,'
  'boolean_byte_map'   : {1 : 1, 0 : 0},
  'byte_i16_map'       : {1 : 1, 2 : -1, 3 : 0x7fff},
  'byte_i32_map'       : {1 : 1, 2 : -1, 3 : 0x7fffffff},
  'byte_i64_map'       : {1 : 1, 2 : -1, 3 : 0x7fffffffffffffff},
  'byte_double_map'    : {1 : 0.1, 2 : -0.1, 3 : 1000000.1},
  'byte_string_map'    : {1 : "", 2 : "blah", 3 : "loooooooooooooong string"},
//'byte_binary_map,'
  'byte_boolean_map'   : {1 : 1, 2 : 0},
  'list_byte_map'      : {[1, 2, 3] : 1, [0, 1] : 2, [] : 0},
  'set_byte_map'       : {[1, 2, 3] : 1, [0, 1] : 2, [] : 0},
  'map_byte_map'       : {{1 : 1} : 1, {2 : 2} : 2, {} : 0},
  'byte_map_map'       : {0 : {}, 1 : {1 : 1}, 2 : {1 : 1, 2 : 2}},
  'byte_set_map'       : {0 : [], 1 : [1], 2 : [1, 2]},
  'byte_list_map'      : {0 : [], 1 : [1], 2 : [1, 2]},
  
  'field500'           : 500,
  'field5000'          : 5000,
  'field20000'         : 20000,
}


const i32 MYCONST = 2


exception ExceptionWithAMap {
  1: string blah;
  2: map map_field;
}

exception MutableException {
  1: string msg;
} (python.immutable = "false")

exception ExceptionWithoutFields {}

service ServiceForExceptionWithAMap {
  void methodThatThrowsAnException() throws (1: ExceptionWithAMap xwamap);
}

service Srv {
  i32 Janky(1: i32 arg);

  // return type only methods

  void voidMethod();
  i32 primitiveMethod();
  CompactProtoTestStruct structMethod();

  void methodWithDefaultArgs(1: i32 something = MYCONST);

  oneway void onewayMethod();

  bool declaredExceptionMethod(1: bool shouldThrow) throws (1: ExceptionWithAMap xwamap);
}

service Inherited extends Srv {
  i32 identity(1: i32 arg)
}

service EmptyService {}

// The only purpose of this thing is to increase the size of the generated code
// so that ZlibTest has more highly compressible data to play with.
struct BlowUp {
  1: map(python.immutable = ""),set (python.immutable = "")>> b1;
  2: map(python.immutable = ""),set (python.immutable = "")>> b2;
  3: map(python.immutable = ""),set (python.immutable = "")>> b3;
  4: map(python.immutable = ""),set (python.immutable = "")>> b4;
}


struct ReverseOrderStruct {
  4: string first;
  3: i16 second;
  2: i32 third;
  1: i64 fourth;
}

service ReverseOrderService {
  void myMethod(4: string first, 3: i16 second, 2: i32 third, 1: i64 fourth);
}

enum SomeEnum {
  ONE = 1
  TWO = 2
}

/** This is a docstring on a constant! */
const SomeEnum MY_SOME_ENUM = SomeEnum.ONE

const SomeEnum MY_SOME_ENUM_1 = 1
/*const SomeEnum MY_SOME_ENUM_2 = 7*/

const map MY_ENUM_MAP = {
  SomeEnum.ONE : SomeEnum.TWO
}

struct StructWithSomeEnum {
  1: SomeEnum blah;
}

const map EXTRA_CRAZY_MAP = {
  SomeEnum.ONE : {"blah" : SomeEnum.TWO}
}

union TestUnion {
  /**
   * A doc string
   */
  1: string string_field;
  2: i32 i32_field;
  3: OneOfEach struct_field;
  4: list struct_list;
  5: i32 other_i32_field;
  6: SomeEnum enum_field;
  7: set i32_set;
  8: map i32_map;
}

union TestUnionMinusStringField {
  2: i32 i32_field;
  3: OneOfEach struct_field;
  4: list struct_list;
  5: i32 other_i32_field;
  6: SomeEnum enum_field;
  7: set i32_set;
  8: map i32_map;
}

union ComparableUnion {
  1: string string_field;
  2: binary binary_field;
}

struct StructWithAUnion {
  1: TestUnion test_union;
}

struct PrimitiveThenStruct {
  1: i32 blah;
  2: i32 blah2;
  3: Backwards bw;
}

typedef map SomeMap

struct StructWithASomemap {
  1: required SomeMap somemap_field;
}

struct BigFieldIdStruct {
  1: string field1;
  45: string field2;
}

struct BreaksRubyCompactProtocol {
  1: string field1;
  2: BigFieldIdStruct field2;
  3: i32 field3;
}

struct TupleProtocolTestStruct {
  optional i32 field1;
  optional i32 field2;
  optional i32 field3;
  optional i32 field4;
  optional i32 field5;
  optional i32 field6;
  optional i32 field7;
  optional i32 field8;
  optional i32 field9;
  optional i32 field10;
  optional i32 field11;
  optional i32 field12;
}

struct ListDoublePerf {
  1: list field;
}
thrift-0.23.0/test/cpp/0000775000175000017500000000000015170007175015122 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/src/0000775000175000017500000000000015170007202015700 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/src/StressTest.cpp0000664000175000017500000004266115165535636020565 0ustar00buildbuild00000000000000/*
 * 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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "Service.h"
#include 
#include 
#include 
#include 
#include 
#if _WIN32
#include 
#endif

using namespace std;

using namespace apache::thrift;
using namespace apache::thrift::async;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using namespace apache::thrift::concurrency;

using namespace test::stress;

struct eqstr {
  bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) == 0; }
};

struct ltstr {
  bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; }
};

// typedef hash_map, eqstr> count_map;
typedef map count_map;

class Server : public ServiceIf {
public:
  Server() = default;

  void count(const char* method) {
    Guard m(lock_);
    int ct = counts_[method];
    counts_[method] = ++ct;
  }

  void echoVoid() override {
    count("echoVoid");
    return;
  }

  count_map getCount() {
    Guard m(lock_);
    return counts_;
  }

  int8_t echoByte(const int8_t arg) override { return arg; }
  int32_t echoI32(const int32_t arg) override { return arg; }
  int64_t echoI64(const int64_t arg) override { return arg; }
  void echoString(string& out, const string& arg) override {
    if (arg != "hello") {
      T_ERROR_ABORT("WRONG STRING (%s)!!!!", arg.c_str());
    }
    out = arg;
  }
  void echoList(vector& out, const vector& arg) override { out = arg; }
  void echoSet(set& out, const set& arg) override { out = arg; }
  void echoMap(map& out, const map& arg) override { out = arg; }

private:
  count_map counts_;
  Mutex lock_;
};

enum TransportOpenCloseBehavior {
  OpenAndCloseTransportInThread,
  DontOpenAndCloseTransportInThread
};
class ClientThread : public Runnable {
public:
  ClientThread(std::shared_ptr transport,
               std::shared_ptr client,
               Monitor& monitor,
               size_t& workerCount,
               size_t loopCount,
               TType loopType,
               TransportOpenCloseBehavior behavior)
    : _transport(transport),
      _client(client),
      _monitor(monitor),
      _workerCount(workerCount),
      _loopCount(loopCount),
      _loopType(loopType),
      _behavior(behavior) {}

  void run() override {

    // Wait for all worker threads to start

    {
      Synchronized s(_monitor);
      while (_workerCount == 0) {
        _monitor.wait();
      }
    }

    _startTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();
    if(_behavior == OpenAndCloseTransportInThread) {
      _transport->open();
    }

    switch (_loopType) {
    case T_VOID:
      loopEchoVoid();
      break;
    case T_BYTE:
      loopEchoByte();
      break;
    case T_I32:
      loopEchoI32();
      break;
    case T_I64:
      loopEchoI64();
      break;
    case T_STRING:
      loopEchoString();
      break;
    default:
      cerr << "Unexpected loop type" << _loopType << '\n';
      break;
    }

    _endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();

    if(_behavior == OpenAndCloseTransportInThread) {
      _transport->close();
    }

    _done = true;

    {
      Synchronized s(_monitor);

      _workerCount--;

      if (_workerCount == 0) {

        _monitor.notify();
      }
    }
  }

  void loopEchoVoid() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      _client->echoVoid();
    }
  }

  void loopEchoByte() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      int8_t arg = 1;
      int8_t result;
      result = _client->echoByte(arg);
      (void)result;
      assert(result == arg);
    }
  }

  void loopEchoI32() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      int32_t arg = 1;
      int32_t result;
      result = _client->echoI32(arg);
      (void)result;
      assert(result == arg);
    }
  }

  void loopEchoI64() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      int64_t arg = 1;
      int64_t result;
      result = _client->echoI64(arg);
      (void)result;
      assert(result == arg);
    }
  }

  void loopEchoString() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      string arg = "hello";
      string result;
      _client->echoString(result, arg);
      assert(result == arg);
    }
  }

  std::shared_ptr _transport;
  std::shared_ptr _client;
  Monitor& _monitor;
  size_t& _workerCount;
  size_t _loopCount;
  TType _loopType;
  int64_t _startTime;
  int64_t _endTime;
  bool _done;
  Monitor _sleep;
  TransportOpenCloseBehavior _behavior;
};

class TStartObserver : public apache::thrift::server::TServerEventHandler {
public:
  TStartObserver() : awake_(false) {}
  void preServe() override {
    apache::thrift::concurrency::Synchronized s(m_);
    awake_ = true;
    m_.notifyAll();
  }
  void waitForService() {
    apache::thrift::concurrency::Synchronized s(m_);
    while (!awake_)
      m_.waitForever();
  }

private:
  apache::thrift::concurrency::Monitor m_;
  bool awake_;
};

int main(int argc, char** argv) {
#if _WIN32
  transport::TWinsockSingleton::create();
#endif

  int port = 9091;
  string clientType = "regular";
  string serverType = "thread-pool";
  string protocolType = "binary";
  size_t workerCount = 8;
  size_t clientCount = 4;
  size_t loopCount = 50000;
  TType loopType = T_VOID;
  string callName = "echoVoid";
  bool runServer = true;
  bool logRequests = false;
  string requestLogPath = "./requestlog.tlog";
  bool replayRequests = false;

  ostringstream usage;

  usage << argv[0] << " [--port=] [--server] [--server-type=] "
                      "[--protocol-type=] [--workers=] "
                      "[--clients=] [--loop=] "
                      "[--client-type=]" << '\n'
        << "\tclients        Number of client threads to create - 0 implies no clients, i.e. "
                            "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'
        << "\tclient-type    Type of client, \"regular\" or \"concurrent\".  Default is " << clientType << '\n'
        << '\n';

  map args;

  for (int ix = 1; ix < argc; ix++) {

    string arg(argv[ix]);

    if (arg.compare(0, 2, "--") == 0) {

      size_t end = arg.find_first_of("=", 2);

      string key = string(arg, 2, end - 2);

      if (end != string::npos) {
        args[key] = string(arg, end + 1);
      } else {
        args[key] = "true";
      }
    } else {
      throw invalid_argument("Unexcepted command line token: " + arg);
    }
  }

  try {

    if (!args["clients"].empty()) {
      clientCount = atoi(args["clients"].c_str());
    }

    if (!args["help"].empty()) {
      cerr << usage.str();
      return 0;
    }

    if (!args["loop"].empty()) {
      loopCount = atoi(args["loop"].c_str());
    }

    if (!args["call"].empty()) {
      callName = args["call"];
    }

    if (!args["port"].empty()) {
      port = atoi(args["port"].c_str());
    }

    if (!args["server"].empty()) {
      runServer = args["server"] == "true";
    }

    if (!args["log-request"].empty()) {
      logRequests = args["log-request"] == "true";
    }

    if (!args["replay-request"].empty()) {
      replayRequests = args["replay-request"] == "true";
    }

    if (!args["server-type"].empty()) {
      serverType = args["server-type"];

      if (serverType == "simple") {

      } else if (serverType == "thread-pool") {

      } else if (serverType == "threaded") {

      } else {

        throw invalid_argument("Unknown server type " + serverType);
      }
    }
    if (!args["client-type"].empty()) {
      clientType = args["client-type"];

      if (clientType == "regular") {

      } else if (clientType == "concurrent") {

      } else {

        throw invalid_argument("Unknown client type " + clientType);
      }
    }
    if (!args["workers"].empty()) {
      workerCount = atoi(args["workers"].c_str());
    }

  } catch (std::exception& e) {
    cerr << e.what() << '\n';
    cerr << usage.str();
  }

  std::shared_ptr threadFactory
      = std::shared_ptr(new ThreadFactory());

  // Dispatcher
  std::shared_ptr serviceHandler(new Server());

  if (replayRequests) {
    std::shared_ptr serviceHandler(new Server());
    std::shared_ptr serviceProcessor(new ServiceProcessor(serviceHandler));

    // Transports
    std::shared_ptr fileTransport(new TFileTransport(requestLogPath));
    fileTransport->setChunkSize(2 * 1024 * 1024);
    fileTransport->setMaxEventSize(1024 * 16);
    fileTransport->seekToEnd();

    // Protocol Factory
    std::shared_ptr protocolFactory(new TBinaryProtocolFactory());

    TFileProcessor fileProcessor(serviceProcessor, protocolFactory, fileTransport);

    fileProcessor.process(0, true);
    exit(0);
  }

  if (runServer) {

    std::shared_ptr serviceProcessor(new ServiceProcessor(serviceHandler));

    // Transport
    std::shared_ptr serverSocket(new TServerSocket(port));

    // Transport Factory
    std::shared_ptr transportFactory(new TBufferedTransportFactory());

    // Protocol Factory
    std::shared_ptr protocolFactory(new TBinaryProtocolFactory());

    if (logRequests) {
      // initialize the log file
      std::shared_ptr fileTransport(new TFileTransport(requestLogPath));
      fileTransport->setChunkSize(2 * 1024 * 1024);
      fileTransport->setMaxEventSize(1024 * 16);

      transportFactory
          = std::shared_ptr(new TPipedTransportFactory(fileTransport));
    }

    std::shared_ptr server;

    if (serverType == "simple") {

      server.reset(
          new TSimpleServer(serviceProcessor, serverSocket, transportFactory, protocolFactory));

    } else if (serverType == "threaded") {

      server.reset(
          new TThreadedServer(serviceProcessor, serverSocket, transportFactory, protocolFactory));

    } else if (serverType == "thread-pool") {

      std::shared_ptr threadManager
          = ThreadManager::newSimpleThreadManager(workerCount);

      threadManager->threadFactory(threadFactory);
      threadManager->start();
      server.reset(new TThreadPoolServer(serviceProcessor,
                                         serverSocket,
                                         transportFactory,
                                         protocolFactory,
                                         threadManager));
    }

    std::shared_ptr observer(new TStartObserver);
    server->setServerEventHandler(observer);
    std::shared_ptr serverThread = threadFactory->newThread(server);

    cerr << "Starting the server on port " << port << '\n';

    serverThread->start();
    observer->waitForService();

    // If we aren't running clients, just wait forever for external clients
    if (clientCount == 0) {
      serverThread->join();
    }
  }

  if (clientCount > 0) { //FIXME: start here for client type?

    Monitor monitor;

    size_t threadCount = 0;

    set > clientThreads;

    if (callName == "echoVoid") {
      loopType = T_VOID;
    } else if (callName == "echoByte") {
      loopType = T_BYTE;
    } else if (callName == "echoI32") {
      loopType = T_I32;
    } else if (callName == "echoI64") {
      loopType = T_I64;
    } else if (callName == "echoString") {
      loopType = T_STRING;
    } else {
      throw invalid_argument("Unknown service call " + callName);
    }

    if(clientType == "regular") {
      for (size_t ix = 0; ix < clientCount; ix++) {

        std::shared_ptr socket(new TSocket("127.0.0.1", port));
        std::shared_ptr bufferedSocket(new TBufferedTransport(socket, 2048));
        std::shared_ptr protocol(new TBinaryProtocol(bufferedSocket));
        std::shared_ptr serviceClient(new ServiceClient(protocol));

        clientThreads.insert(threadFactory->newThread(std::shared_ptr(
            new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType, OpenAndCloseTransportInThread))));
      }
    } else if(clientType == "concurrent") {
      std::shared_ptr socket(new TSocket("127.0.0.1", port));
      std::shared_ptr bufferedSocket(new TBufferedTransport(socket, 2048));
      std::shared_ptr protocol(new TBinaryProtocol(bufferedSocket));
      auto sync = std::make_shared();
      std::shared_ptr serviceClient(new ServiceConcurrentClient(protocol, sync));
      socket->open();
      for (size_t ix = 0; ix < clientCount; ix++) {
        clientThreads.insert(threadFactory->newThread(std::shared_ptr(
            new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType, DontOpenAndCloseTransportInThread))));
      }
    }

    for (auto thread = clientThreads.begin();
         thread != clientThreads.end();
         thread++) {
      (*thread)->start();
    }

    int64_t time00;
    int64_t time01;

    {
      Synchronized s(monitor);
      threadCount = clientCount;

      cerr << "Launch " << clientCount << " " << clientType << " client threads" << '\n';

      time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();

      monitor.notifyAll();

      while (threadCount > 0) {
        monitor.wait();
      }

      time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();
    }

    int64_t firstTime = 9223372036854775807LL;
    int64_t lastTime = 0;

    double averageTime = 0;
    int64_t minTime = 9223372036854775807LL;
    int64_t maxTime = 0;

    for (auto ix = clientThreads.begin();
         ix != clientThreads.end();
         ix++) {

      std::shared_ptr client
          = std::dynamic_pointer_cast((*ix)->runnable());

      int64_t delta = client->_endTime - client->_startTime;

      assert(delta > 0);

      if (client->_startTime < firstTime) {
        firstTime = client->_startTime;
      }

      if (client->_endTime > lastTime) {
        lastTime = client->_endTime;
      }

      if (delta < minTime) {
        minTime = delta;
      }

      if (delta > maxTime) {
        maxTime = delta;
      }

      averageTime += delta;
    }

    averageTime /= clientCount;

    cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount
         << ", 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." << '\n';
  }

  return 0;
}
thrift-0.23.0/test/cpp/src/TestClient.cpp0000664000175000017500000012674015167543515020516 0ustar00buildbuild00000000000000/*
 * 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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  // 

#ifdef HAVE_STDINT_H
#include 
#endif
#ifdef HAVE_INTTYPES_H
#include 
#endif

#include 
#include 
#include 
#include 
#if _WIN32
#include 
#endif

#include "SecondService.h"
#include "ThriftTest.h"

using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::async;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace thrift::test;

//
// A pedantic protocol that checks to make sure the response sequence ID
// is the same as the sent sequence ID.  lib/cpp always sends zero for
// synchronous clients, so this bumps the number to make sure it gets
// returned properly from the remote server.  Any server that does not
// respond with the same sequence number is violating the sequence ID
// agreement between client and server.
//

template
class TPedanticProtocol : public Proto
{
    public:
        TPedanticProtocol(std::shared_ptr& transport)
          : Proto(transport), m_last_seqid((std::numeric_limits::max)() - 10) { }

        virtual uint32_t writeMessageBegin_virt(const std::string& name,
                                           const TMessageType messageType,
                                           const int32_t in_seqid) override
        {
            int32_t seqid = in_seqid;
            if (!seqid) { // this is typical for normal cpp generated code
                seqid = ++m_last_seqid;
            }

            return Proto::writeMessageBegin_virt(name, messageType, seqid);
        }

        virtual uint32_t readMessageBegin_virt(std::string& name,
                                          TMessageType& messageType,
                                          int32_t& seqid) override
        {
            uint32_t result = Proto::readMessageBegin_virt(name, messageType, seqid);
            if (seqid != m_last_seqid) {
                std::stringstream ss;
                ss << "ERROR: send request with seqid " << m_last_seqid << " and got reply with seqid " << seqid;
                throw std::logic_error(ss.str());
            } /* else {
                std::cout << "verified seqid " << m_last_seqid << " round trip OK" << '\n';
            } */
            return result;
        }

    private:
        int32_t m_last_seqid;
};

// Current time, microseconds since the epoch
uint64_t now() {
  int64_t ret;
  struct timeval tv;

  THRIFT_GETTIMEOFDAY(&tv, nullptr);
  ret = tv.tv_sec;
  ret = ret * 1000 * 1000 + tv.tv_usec;
  return ret;
}

static void testString_clientReturn(event_base* base,
                                    int testNr,
                                    ThriftTestCobClient* client) {
  try {
    string s;
    client->recv_testString(s);
    std::ostringstream os;
    os << "test" << testNr;
    const bool ok = (s == os.str());
    cout << "testString: " << s << " " << ((ok) ? "ok" : "failed") << '\n';
  } catch (TException& exn) {
    cout << "Error: " << exn.what() << '\n';
  }

  if (testNr == 9)
    event_base_loopbreak(base); // end test
}

static void testVoid_clientReturn(event_base* base, ThriftTestCobClient* client) {
  try {
    client->recv_testVoid();
    cout << "testVoid" << '\n';

    for (int testNr = 0; testNr < 10; ++testNr) {
      std::ostringstream os;
      os << "test" << testNr;
      client->testString(std::bind(testString_clientReturn,
                                    base,
                                    testNr,
                                    std::placeholders::_1),
                       os.str());
    }
  } catch (TException& exn) {
    cout << "Error: " << exn.what() << '\n';
  }
}

// Workaround for absense of C++11 "auto" keyword.
template 
bool print_eq(T expected, T actual) {
  cout << "(" << actual << ")" << '\n';
  if (expected != actual) {
    cout << "*** FAILED ***" << '\n' << "Expected: " << expected << " but got: " << actual << '\n';
    return false;
  }
  return true;
}

#define BASETYPE_IDENTITY_TEST(func, value)                                                        \
  cout << #func "(" << value << ") = ";                                                            \
  try {                                                                                            \
    if (!print_eq(value, testClient.func(value)))                                                  \
      return_code |= ERR_BASETYPES;                                                                \
  } catch (TTransportException&) {                                                                 \
    throw;                                                                                         \
  } catch (exception & ex) {                                                                       \
    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;                                                                  \
  }

int binary_test(ThriftTestClient& testClient, string::size_type siz);

BOOST_CONSTEXPR_OR_CONST int ERR_BASETYPES = 1;
BOOST_CONSTEXPR_OR_CONST int ERR_STRUCTS = 2;
BOOST_CONSTEXPR_OR_CONST int ERR_CONTAINERS = 4;
BOOST_CONSTEXPR_OR_CONST int ERR_EXCEPTIONS = 8;
BOOST_CONSTEXPR_OR_CONST int ERR_UNKNOWN = 64;

int main(int argc, char** argv) {
  cout.precision(19);

  string testDir  = boost::filesystem::system_complete(argv[0]).parent_path().parent_path().parent_path().string();
  string caPath   = testDir + "/keys/CA.pem";
  string certPath = testDir + "/keys/client.crt";
  string keyPath  = testDir + "/keys/client.key";

#if _WIN32
  transport::TWinsockSingleton::create();
#endif
  string host = "localhost";
  int port = 9090;
  int numTests = 1;
  bool ssl = false;
  bool zlib = false;
  string transport_type = "buffered";
  string protocol_type = "binary";
  string domain_socket = "";
  bool abstract_namespace = false;
  bool noinsane = false;

  int return_code = 0;

  boost::program_options::options_description desc("Allowed options");
  desc.add_options()
      ("help,h", "produce help message")
      ("host",
          boost::program_options::value(&host)->default_value(host),
          "Host to connect")
      ("port",
          boost::program_options::value(&port)->default_value(port),
          "Port number to connect")
      ("domain-socket",
          boost::program_options::value(&domain_socket)->default_value(domain_socket),
          "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")
      ("abstract-namespace",
          "Look for the domain socket in the Abstract Namespace"
          " (no connection with filesystem pathnames)")
      ("transport",
          boost::program_options::value(&transport_type)->default_value(transport_type),
          "Transport: buffered, framed, http, evhttp, zlib")
      ("protocol",
          boost::program_options::value(&protocol_type)->default_value(protocol_type),
          "Protocol: binary, compact, header, json, multi, multic, multih, multij")
      ("ssl",
          "Encrypted Transport using SSL")
      ("zlib",
          "Wrap Transport with Zlib")
      ("testloops,n",
          boost::program_options::value(&numTests)->default_value(numTests),
          "Number of Tests")
      ("noinsane",
          "Do not run insanity test");

  boost::program_options::variables_map vm;
  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
  boost::program_options::notify(vm);

  if (vm.count("help")) {
    cout << desc << '\n';
    return ERR_UNKNOWN;
  }

  try {
    if (!protocol_type.empty()) {
      if (protocol_type == "binary") {
      } else if (protocol_type == "compact") {
      } else if (protocol_type == "header") {
      } else if (protocol_type == "json") {
      } else if (protocol_type == "multi") {
      } else if (protocol_type == "multic") {
      } else if (protocol_type == "multih") {
      } else if (protocol_type == "multij") {
      } else {
        throw invalid_argument("Unknown protocol type " + protocol_type);
      }
    }

    if (!transport_type.empty()) {
      if (transport_type == "buffered") {
      } else if (transport_type == "framed") {
      } else if (transport_type == "http") {
      } else if (transport_type == "evhttp") {
      } else if (transport_type == "zlib") {
        // crosstest will pass zlib as a transport and as a flag right now..
      } else {
        throw invalid_argument("Unknown transport type " + transport_type);
      }
    }

  } catch (exception& e) {
    cerr << e.what() << '\n';
    cout << desc << '\n';
    return ERR_UNKNOWN;
  }

  if (vm.count("ssl")) {
    ssl = true;
  }

  if (vm.count("zlib")) {
    zlib = true;
  }

  if (vm.count("abstract-namespace")) {
    abstract_namespace = true;
  }

  if (vm.count("noinsane")) {
    noinsane = true;
  }

  // THRIFT-4164: The factory MUST outlive any sockets it creates for correct behavior!
  std::shared_ptr factory;
  std::shared_ptr socket;
  std::shared_ptr transport;
  std::shared_ptr protocol;
  std::shared_ptr protocol2;  // SecondService for multiplexed

  if (ssl) {
    auto fileExists = [](const std::string& path) {
      std::ifstream f(path.c_str());
      return f.good();
    };

    cout << "Client Path            : " << testDir  << '\n';
    cout << "Client Certificate File: " << certPath << " (" << std::boolalpha << fileExists(certPath) << ")"<< '\n';
    cout << "Client Key         File: " << keyPath  << " (" << std::boolalpha << fileExists(keyPath) << ")"<< '\n';
    cout << "CA                 File: " << caPath   << " (" << std::boolalpha << fileExists(caPath) << ")"<< '\n';

    factory = std::shared_ptr(new TSSLSocketFactory());
    factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
    factory->loadTrustedCertificates(caPath.c_str());
    factory->loadCertificate(certPath.c_str());
    factory->loadPrivateKey(keyPath.c_str());
    factory->authenticate(true);
    socket = factory->createSocket(host, port);
  } else {
    if (domain_socket != "") {
      if (abstract_namespace) {
        std::string abstract_socket("\0", 1);
        abstract_socket += domain_socket;
        socket = std::shared_ptr(new TSocket(abstract_socket));
      } else {
        socket = std::shared_ptr(new TSocket(domain_socket));
      }
      port = 0;
    } else {
      socket = std::shared_ptr(new TSocket(host, port));
    }
  }

  if (transport_type.compare("http") == 0) {
    transport = std::make_shared(socket, host, "/service");
  } else if (transport_type.compare("framed") == 0) {
    transport = std::make_shared(socket);
  } else {
    transport = std::make_shared(socket);
  }

  if (zlib) {
    transport = std::make_shared(transport);
  }

  if (protocol_type == "json" || protocol_type == "multij") {
    typedef TPedanticProtocol TPedanticJSONProtocol;
    protocol = std::make_shared(transport);
  } else if (protocol_type == "compact" || protocol_type == "multic") {
    typedef TPedanticProtocol TPedanticCompactProtocol;
    protocol = std::make_shared(transport);
  } else if (protocol_type == "header" || protocol_type == "multih") {
    typedef TPedanticProtocol TPedanticHeaderProtocol;
    protocol = std::make_shared(transport);
  } else {
    typedef TPedanticProtocol TPedanticBinaryProtocol;
    protocol = std::make_shared(transport);
  }

  if (boost::starts_with(protocol_type, "multi")) {
    protocol2 = std::make_shared(protocol, "SecondService");
    // we don't need access to the original protocol any more, so...
    protocol = std::make_shared(protocol, "ThriftTest");
  }

  // Connection info
  cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: ";
  if (abstract_namespace) {
    cout << '@';
  }
  cout << domain_socket;
  if (port != 0) {
    cout << host << ":" << port;
  }
  cout << '\n';

  if (transport_type.compare("evhttp") == 0) {
    event_base* base = event_base_new();
    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) << '\n';
#endif

    std::shared_ptr protocolFactory(new TBinaryProtocolFactory());

    std::shared_ptr channel(
        new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
    ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
    client->testVoid(std::bind(testVoid_clientReturn,
                                base,
                                std::placeholders::_1));

    event_base_loop(base, 0);
    return 0;
  }

  ThriftTestClient testClient(protocol);

  uint64_t time_min = 0;
  uint64_t time_max = 0;
  uint64_t time_tot = 0;

  int test = 0;
  for (test = 0; test < numTests; ++test) {

    try {
      transport->open();
    } catch (TTransportException& ex) {
      cout << "Connect failed: " << ex.what() << '\n';
      return ERR_UNKNOWN;
    }

    /**
     * CONNECT TEST
     */
    printf("Test #%d, connect %s:%d\n", test + 1, host.c_str(), port);

    uint64_t start = now();

    /**
     * VOID TEST
     */
    try {
      cout << "testVoid()" << flush;
      testClient.testVoid();
      cout << " = void" << '\n';
    } catch (TTransportException&) {
      // Stop here if transport got broken
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_BASETYPES;
    }

    /**
     * STRING TEST
     */
    cout << "testString(\"Test\")" << flush;
    string s;
    testClient.testString(s, "Test");
    cout << " = " << s << '\n';
    if (s != "Test") {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_BASETYPES;
    }

    //
    // Multiplexed protocol - call another service method
    // in the middle of the ThriftTest
    //
    if (boost::starts_with(protocol_type, "multi")) {
    SecondServiceClient ssc(protocol2);
    // transport is already open...

        try {
          cout << "secondService.secondTestString(\"foo\") => " << flush;
        std::string result;
      ssc.secondtestString(result, "foo");
      cout << "{" << result << "}" << '\n';
      } catch (std::exception& e) {
      cout << "  *** FAILED *** " << e.what() << '\n';
      return_code |= ERR_EXCEPTIONS;
    }
    }

    try {
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4566 )
#endif
      string 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, 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ú, 粵語");
#ifdef _MSC_VER
#pragma warning( pop )
#endif
      cout << "testString(" << str << ") = " << flush;
      testClient.testString(s, str);
      cout << s << '\n';
      if (s != str) {
        cout.imbue(locale("en_US.UTF8"));
        cout << "*** FAILED ***" << '\n' << "Expected string: " << str << " but got: " << s << '\n' << "CLEAR";
        return_code |= ERR_BASETYPES;
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_BASETYPES;
      return return_code;
    }
    try {
      string 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: !@#$%&()(&%$#{}{}<><><"
          " char-to-test-json-parsing: ]] \"]] \\\" }}}{ [[[ ");
      cout << "testString(" << str << ") = " << flush;
      testClient.testString(s, str);
      cout << s << '\n';
      if (s != str) {
        cout.imbue(locale("en_US.UTF8"));
        cout << "*** FAILED ***" << '\n'
             << "Expected string: " << str << " but got: " << s << '\n'
             << "CLEAR";
        ;
        return_code |= ERR_BASETYPES;
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_BASETYPES;
      return return_code;
    }

    /**
     * BOOL TEST
     */
    cout << boolalpha;
    BASETYPE_IDENTITY_TEST(testBool, true);
    BASETYPE_IDENTITY_TEST(testBool, false);

    /**
     * BYTE TEST
     */
    BASETYPE_IDENTITY_TEST(testByte, (int8_t)0);
    BASETYPE_IDENTITY_TEST(testByte, (int8_t)-1);
    BASETYPE_IDENTITY_TEST(testByte, (int8_t)42);
    BASETYPE_IDENTITY_TEST(testByte, (int8_t)-42);
    BASETYPE_IDENTITY_TEST(testByte, (int8_t)127);
    BASETYPE_IDENTITY_TEST(testByte, (int8_t)-128);

    /**
     * I32 TEST
     */
    BASETYPE_IDENTITY_TEST(testI32, 0);
    BASETYPE_IDENTITY_TEST(testI32, -1);
    BASETYPE_IDENTITY_TEST(testI32, 190000013);
    BASETYPE_IDENTITY_TEST(testI32, -190000013);
    BASETYPE_IDENTITY_TEST(testI32, (numeric_limits::max)());
    BASETYPE_IDENTITY_TEST(testI32, (numeric_limits::min)());

    /**
     * I64 TEST
     */
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)0);
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)-1);
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)7000000000000000123LL);
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)-7000000000000000123LL);
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast(2LL), 32));
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast(2LL), 32));
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast(2LL), 32) + 1);
    BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast(2LL), 32) - 1);
    BASETYPE_IDENTITY_TEST(testI64, (numeric_limits::max)());
    BASETYPE_IDENTITY_TEST(testI64, (numeric_limits::min)());

    /**
     * DOUBLE TEST
     */
    // Comparing double values with plain equality because Thrift handles full precision of double
    BASETYPE_IDENTITY_TEST(testDouble, 0.0);
    BASETYPE_IDENTITY_TEST(testDouble, -1.0);
    BASETYPE_IDENTITY_TEST(testDouble, -5.2098523);
    BASETYPE_IDENTITY_TEST(testDouble, -0.000341012439638598279);
    BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast(2), 32));
    BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast(2), 32) + 1);
    BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast(2), 53) - 1);
    BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast(2), 32));
    BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast(2), 32) - 1);
    BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast(2), 53) + 1);

    try {
      double expected = pow(static_cast(10), 307);
      cout << "testDouble(" << expected << ") = " << flush;
      double actual = testClient.testDouble(expected);
      cout << "(" << actual << ")" << '\n';
      if (expected - actual > pow(static_cast(10), 292)) {
        cout << "*** FAILED ***" << '\n'
             << "Expected: " << expected << " but got: " << actual << '\n';
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_BASETYPES;
    }

    try {
      double expected = pow(static_cast(10), -292);
      cout << "testDouble(" << expected << ") = " << flush;
      double actual = testClient.testDouble(expected);
      cout << "(" << actual << ")" << '\n';
      if (expected - actual > pow(static_cast(10), -307)) {
        cout << "*** FAILED ***" << '\n'
             << "Expected: " << expected << " but got: " << actual << '\n';
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_BASETYPES;
    }

    /**
     * BINARY TEST
     */
    for (string::size_type i = 0; i < 131073 && !return_code; ) {
      return_code |= binary_test(testClient, i);
      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
     */
    cout << "testStruct({\"Zero\", 1, -3, -5})" << flush;
    Xtruct out;
    out.string_thing = "Zero";
    out.byte_thing = 1;
    out.i32_thing = -3;
    out.i64_thing = -5;
    Xtruct in;
    testClient.testStruct(in, out);
    printf(" = {\"%s\", %d, %d, %" PRId64 "}\n",
           in.string_thing.c_str(),
           (int)in.byte_thing,
           in.i32_thing,
           in.i64_thing);
    if (in != out) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    /**
     * NESTED STRUCT TEST
     */
    cout << "testNest({1, {\"Zero\", 1, -3, -5}), 5}" << flush;
    Xtruct2 out2;
    out2.byte_thing = 1;
    out2.struct_thing = out;
    out2.i32_thing = 5;
    Xtruct2 in2;
    testClient.testNest(in2, out2);
    in = in2.struct_thing;
    printf(" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
           in2.byte_thing,
           in.string_thing.c_str(),
           (int)in.byte_thing,
           in.i32_thing,
           in.i64_thing,
           in2.i32_thing);
    if (in2 != out2) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    /**
     * MAP TEST
     */
    map mapout;
    for (int32_t i = 0; i < 5; ++i) {
      mapout.insert(make_pair(i, i - 10));
    }
    cout << "testMap({" << flush;
    map::const_iterator m_iter;
    bool first = true;
    for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
      if (first) {
        first = false;
      } else {
        cout << ",";
      }
      cout << m_iter->first << " => " << m_iter->second;
    }
    cout << "})";
    map mapin;
    testClient.testMap(mapin, mapout);
    cout << " = {";
    first = true;
    for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
      if (first) {
        first = false;
      } else {
        cout << ",";
      }
      cout << m_iter->first << " => " << m_iter->second;
    }
    cout << "}" << '\n';
    if (mapin != mapout) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_CONTAINERS;
    }

    /**
     * STRING MAP TEST
     */
    cout << "testStringMap({a => 2, b => blah, some => thing}) = {" << flush;
    map smapin;
    map smapout;
    smapin["a"] = "2";
    smapin["b"] = "blah";
    smapin["some"] = "thing";
    try {
      testClient.testStringMap(smapout, smapin);
      first = true;
      for (map::const_iterator it = smapout.begin(); it != smapout.end(); ++it) {
        if (first)
          cout << ",";
        else
          first = false;
        cout << it->first << " => " << it->second;
      }
      cout << "}" << '\n';
      if (smapin != smapout) {
        cout << "*** FAILED ***" << '\n';
        return_code |= ERR_CONTAINERS;
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_CONTAINERS;
    }

    /**
     * SET TEST
     */
    set setout;
    for (int32_t i = -2; i < 3; ++i) {
      setout.insert(i);
    }
    cout << "testSet({" << flush;
    set::const_iterator s_iter;
    first = true;
    for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
      if (first) {
        first = false;
      } else {
        cout << ",";
      }
      cout << *s_iter;
    }
    cout << "})";
    set setin;
    testClient.testSet(setin, setout);
    cout << " = {";
    first = true;
    for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
      if (first) {
        first = false;
      } else {
        cout << ",";
      }
      cout << *s_iter;
    }
    cout << "}" << '\n';
    if (setin != setout) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_CONTAINERS;
    }

    /**
     * LIST TEST
     */
    cout << "testList(empty)" << flush;
    try {
      vector listout;
      testClient.testList(listout, vector());
      if (!listout.empty()) {
        cout << "*** FAILED ***" << '\n';
        cout << "invalid length: " << listout.size() << '\n';
        return_code |= ERR_CONTAINERS;
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_CONTAINERS;
    }
    try {
      vector listout;
      for (int32_t i = -2; i < 3; ++i) {
        listout.push_back(i);
      }
      cout << "testList({" << flush;
      vector::const_iterator l_iter;
      first = true;
      for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
        if (first) {
          first = false;
        } else {
          cout << ",";
        }
        cout << *l_iter;
      }
      cout << "})";
      vector listin;
      testClient.testList(listin, listout);
      cout << " = {";
      first = true;
      for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
        if (first) {
          first = false;
        } else {
          cout << ",";
        }
        cout << *l_iter;
      }
      cout << "}" << '\n';
      if (listin != listout) {
        cout << "*** FAILED ***" << '\n';
        return_code |= ERR_CONTAINERS;
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_CONTAINERS;
    }

    /**
     * ENUM TEST
     */
    cout << "testEnum(ONE)" << flush;
    Numberz::type ret = testClient.testEnum(Numberz::ONE);
    cout << " = " << ret << '\n';
    if (ret != Numberz::ONE) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    cout << "testEnum(TWO)" << flush;
    ret = testClient.testEnum(Numberz::TWO);
    cout << " = " << ret << '\n';
    if (ret != Numberz::TWO) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    cout << "testEnum(THREE)" << flush;
    ret = testClient.testEnum(Numberz::THREE);
    cout << " = " << ret << '\n';
    if (ret != Numberz::THREE) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    cout << "testEnum(FIVE)" << flush;
    ret = testClient.testEnum(Numberz::FIVE);
    cout << " = " << ret << '\n';
    if (ret != Numberz::FIVE) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    cout << "testEnum(EIGHT)" << flush;
    ret = testClient.testEnum(Numberz::EIGHT);
    cout << " = " << ret << '\n';
    if (ret != Numberz::EIGHT) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    /**
     * TYPEDEF TEST
     */
    cout << "testTypedef(309858235082523)" << flush;
    UserId uid = testClient.testTypedef(309858235082523LL);
    cout << " = " << uid << '\n';
    if (uid != 309858235082523LL) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_STRUCTS;
    }

    /**
     * NESTED MAP TEST
     */
    cout << "testMapMap(1)" << flush;
    map > mm;
    testClient.testMapMap(mm, 1);
    cout << " = {";
    map >::const_iterator mi;
    for (mi = mm.begin(); mi != mm.end(); ++mi) {
      printf("%d => {", mi->first);
      map::const_iterator mi2;
      for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
        cout << mi2->first << " => " << mi2->second;
      }
      cout << "}, ";
    }
    cout << "}" << '\n';
    if (mm.size() != 2 ||
        mm[-4][-4] != -4 ||
        mm[-4][-3] != -3 ||
        mm[-4][-2] != -2 ||
        mm[-4][-1] != -1 ||
        mm[4][4] != 4 ||
        mm[4][3] != 3 ||
        mm[4][2] != 2 ||
        mm[4][1] != 1) {
      cout << "*** FAILED ***" << '\n';
      return_code |= ERR_CONTAINERS;
    }

    /**
     * INSANITY TEST
     */
    if (!noinsane) {
      Insanity insane;
      insane.userMap.insert(make_pair(Numberz::FIVE, 5));
      insane.userMap.insert(make_pair(Numberz::EIGHT, 8));
      Xtruct truck;
      truck.string_thing = "Goodbye4";
      truck.byte_thing = 4;
      truck.i32_thing = 4;
      truck.i64_thing = 4;
      Xtruct truck2;
      truck2.string_thing = "Hello2";
      truck2.byte_thing = 2;
      truck2.i32_thing = 2;
      truck2.i64_thing = 2;
      insane.xtructs.push_back(truck);
      insane.xtructs.push_back(truck2);
      cout << "testInsanity()" << flush;
      map > whoa;
      testClient.testInsanity(whoa, insane);
      cout << " = {";
      map >::const_iterator i_iter;
      for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
        printf("%" PRId64 " => {", i_iter->first);
        map::const_iterator i2_iter;
        for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
          printf("%d => {", i2_iter->first);
          map userMap = i2_iter->second.userMap;
          map::const_iterator um;
          cout << "{";
          for (um = userMap.begin(); um != userMap.end(); ++um) {
            cout << um->first << " => " << um->second;
          }
          cout << "}, ";

          vector xtructs = i2_iter->second.xtructs;
          vector::const_iterator x;
          cout << "{";
          for (x = xtructs.begin(); x != xtructs.end(); ++x) {
            printf("{\"%s\", %d, %d, %" PRId64 "}, ",
                   x->string_thing.c_str(),
                   (int)x->byte_thing,
                   x->i32_thing,
                   x->i64_thing);
          }
          cout << "}";

          cout << "}, ";
        }
        cout << "}, ";
      }
      cout << "}" << '\n';
      bool failed = false;
      map >::const_iterator it1 = whoa.find(UserId(1));
      if (whoa.size() != 2) {
        failed = true;
      }
      if (it1 == whoa.end()) {
        failed = true;
      } else {
        auto it12 = it1->second.find(Numberz::TWO);
        if (it12 == it1->second.end() || it12->second != insane) {
          failed = true;
        }
        auto it13 = it1->second.find(Numberz::THREE);
        if (it13 == it1->second.end() || it13->second != insane) {
          failed = true;
        }
      }
      map >::const_iterator it2 = whoa.find(UserId(2));
      if (it2 == whoa.end()) {
        failed = true;
      } else {
        auto it26 = it2->second.find(Numberz::SIX);
        if (it26 == it2->second.end() || it26->second != Insanity()) {
          failed = true;
        }
      }
      if (failed) {
        cout << "*** FAILED ***" << '\n';
        return_code |= ERR_STRUCTS;
      }
    }

    /**
     * MULTI TEST
     */
    cout << "testMulti()" << '\n';
    try {
      map mul_map;
      Xtruct mul_result;
      mul_map[1] = "blah";
      mul_map[2] = "thing";
      testClient.testMulti(mul_result, 42, 4242, 424242, mul_map, Numberz::EIGHT, UserId(24));
      Xtruct xxs;
      xxs.string_thing = "Hello2";
      xxs.byte_thing = 42;
      xxs.i32_thing = 4242;
      xxs.i64_thing = 424242;
      if (mul_result != xxs) {
        cout << "*** FAILED ***" << '\n';
        return_code |= ERR_STRUCTS;
      }
    } catch (TTransportException&) {
      throw;
    } catch (exception& ex) {
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_STRUCTS;
    }

    /* test exception */

    try {
      cout << "testClient.testException(\"Xception\") =>" << flush;
      testClient.testException("Xception");
      cout << "  void\n*** FAILED ***" << '\n';
      return_code |= ERR_EXCEPTIONS;

    } catch (Xception& e) {
      printf("  {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
    }

    try {
      cout << "testClient.testException(\"TException\") =>" << flush;
      testClient.testException("TException");
      cout << "  void\n*** FAILED ***" << '\n';
      return_code |= ERR_EXCEPTIONS;

    } catch (const TException&) {
      cout << "  Caught TException" << '\n';
    }

    try {
      cout << "testClient.testException(\"success\") =>" << flush;
      testClient.testException("success");
      cout << "  void" << '\n';
    } catch (exception & ex) {                                                                       \
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_EXCEPTIONS;
    }

    /* test multi exception */

    try {
      cout << "testClient.testMultiException(\"Xception\", \"test 1\") =>" << flush;
      Xtruct result;
      testClient.testMultiException(result, "Xception", "test 1");
      cout << "  result\n*** FAILED ***" << '\n';
      return_code |= ERR_EXCEPTIONS;
    } catch (Xception& e) {
      printf("  {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
    }

    try {
      cout << "testClient.testMultiException(\"Xception2\", \"test 2\") =>" << flush;
      Xtruct result;
      testClient.testMultiException(result, "Xception2", "test 2");
      cout << "  result\n*** FAILED ***" << '\n';
      return_code |= ERR_EXCEPTIONS;

    } catch (Xception2& e) {
      printf("  {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
    }

    try {
      cout << "testClient.testMultiException(\"success\", \"test 3\") =>" << flush;
      Xtruct result;
      testClient.testMultiException(result, "success", "test 3");
      printf("  {{\"%s\"}}\n", result.string_thing.c_str());
    } catch (exception & ex) {                                                                       \
      cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
      return_code |= ERR_EXCEPTIONS;
    }

    /* test oneway void */
    {
      cout << "testClient.testOneway(1) =>" << flush;
      uint64_t startOneway = now();
      testClient.testOneway(1);
      uint64_t elapsed = now() - startOneway;
      if (elapsed > 200 * 1000) { // 0.2 seconds
        printf("*** FAILED *** - took %.2f ms\n", (double)elapsed / 1000.0);
      return_code |= ERR_BASETYPES;
      } else {
        printf("  success - took %.2f ms\n", (double)elapsed / 1000.0);
      }
    }

    /**
     * redo a simple test after the oneway to make sure we aren't "off by one" --
     * if the server treated oneway void like normal void, this next test will
     * fail since it will get the void confirmation rather than the correct
     * result. In this circumstance, the client will throw the exception:
     *
     *   TApplicationException: Wrong method namea
     */
    /**
     * I32 TEST
     */
    cout << "re-test testI32(-1)" << flush;
    int i32 = testClient.testI32(-1);
    cout << " = " << i32 << '\n';
    if (i32 != -1)
      return_code |= ERR_BASETYPES;

    cout << '\n' << "All tests done." << '\n' << flush;

    uint64_t stop = now();
    uint64_t tot = stop - start;

    cout << "Total time: " << stop - start << " us" << '\n';

    time_tot += tot;
    if (time_min == 0 || tot < time_min) {
      time_min = tot;
    }
    if (tot > time_max) {
      time_max = tot;
    }

    cout << flush;
    transport->close();
  }


  uint64_t time_avg = time_tot / numTests;

  cout << "Min time: " << time_min << " us" << '\n';
  cout << "Max time: " << time_max << " us" << '\n';
  cout << "Avg time: " << time_avg << " us" << '\n';

  return return_code;
}

void binary_fill(std::string& str, string::size_type siz)
{
    static const signed char bin_data[256]
        = {-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114,
           -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99,
           -98,  -97,  -96,  -95,  -94,  -93,  -92,  -91,  -90,  -89,  -88,  -87,  -86,  -85,  -84,
           -83,  -82,  -81,  -80,  -79,  -78,  -77,  -76,  -75,  -74,  -73,  -72,  -71,  -70,  -69,
           -68,  -67,  -66,  -65,  -64,  -63,  -62,  -61,  -60,  -59,  -58,  -57,  -56,  -55,  -54,
           -53,  -52,  -51,  -50,  -49,  -48,  -47,  -46,  -45,  -44,  -43,  -42,  -41,  -40,  -39,
           -38,  -37,  -36,  -35,  -34,  -33,  -32,  -31,  -30,  -29,  -28,  -27,  -26,  -25,  -24,
           -23,  -22,  -21,  -20,  -19,  -18,  -17,  -16,  -15,  -14,  -13,  -12,  -11,  -10,  -9,
           -8,   -7,   -6,   -5,   -4,   -3,   -2,   -1,   0,    1,    2,    3,    4,    5,    6,
           7,    8,    9,    10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,
           22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
           37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
           52,   53,   54,   55,   56,   57,   58,   59,   60,   61,   62,   63,   64,   65,   66,
           67,   68,   69,   70,   71,   72,   73,   74,   75,   76,   77,   78,   79,   80,   81,
           82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,   95,   96,
           97,   98,   99,   100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,  111,
           112,  113,  114,  115,  116,  117,  118,  119,  120,  121,  122,  123,  124,  125,  126,
           127};

    str.resize(siz);
    char *ptr = &str[0];
    string::size_type pos = 0;
    for (string::size_type i = 0; i < siz; ++i)
    {
        if (pos == 255) { pos = 0; } else { ++pos; }
        *ptr++ = bin_data[pos];
    }
}

int binary_test(ThriftTestClient& testClient, string::size_type siz)
{
    string bin_request;
    string bin_result;

    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() << '\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) << '\n';
                return ERR_BASETYPES;
            }
        }
    } catch (TTransportException&) {
        throw;
    } catch (exception& ex) {
        cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
        return ERR_BASETYPES;
    }

    return 0;
}
thrift-0.23.0/test/cpp/src/TemplateStreamOpTest.cpp0000664000175000017500000003556215167543515022527 0ustar00buildbuild00000000000000/*
 * 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.
 */

/**
 * Test file to verify that template_streamop generated code compiles and works correctly.
 * This tests the templated operator<< and printTo with various stream types.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

// Include generated thrift types with template_streamop option
#include "ThriftTest_types.h"
#include 

using namespace thrift::test;

// Custom minimal stream implementation for testing and performance comparison
class MinimalStream {
private:
    static constexpr size_t STACK_BUFFER_SIZE = 2048;
    char stack_buffer_[STACK_BUFFER_SIZE];
    char* buffer_;
    size_t size_;
    size_t capacity_;
    bool on_heap_;
    
    void ensure_capacity(size_t additional) {
        size_t needed = size_ + additional;
        if (needed <= capacity_) return;
        
        size_t new_capacity = capacity_;
        while (new_capacity < needed) {
            new_capacity *= 2;
        }
        
        char* new_buffer = new char[new_capacity];
        if (size_ > 0) {
            std::memcpy(new_buffer, buffer_, size_);
        }
        
        if (on_heap_) {
            delete[] buffer_;
        }
        
        buffer_ = new_buffer;
        capacity_ = new_capacity;
        on_heap_ = true;
    }
    
    void append(const char* s, size_t len) {
        ensure_capacity(len);
        std::memcpy(buffer_ + size_, s, len);
        size_ += len;
    }
    
    // Helper to print integer directly to buffer
    template
    void print_integer(T value) {
        char temp[32];  // Enough for any 64-bit integer
        char* p = temp + sizeof(temp);
        bool negative = value < 0;
        
        if (negative) {
            value = -value;
        }
        
        do {
            *--p = '0' + (value % 10);
            value /= 10;
        } while (value > 0);
        
        if (negative) {
            *--p = '-';
        }
        
        append(p, temp + sizeof(temp) - p);
    }
    
    // Helper to print unsigned integer directly to buffer
    template
    void print_unsigned(T value) {
        char temp[32];
        char* p = temp + sizeof(temp);
        
        do {
            *--p = '0' + (value % 10);
            value /= 10;
        } while (value > 0);
        
        append(p, temp + sizeof(temp) - p);
    }
    
public:
    MinimalStream() 
        : buffer_(stack_buffer_), size_(0), capacity_(STACK_BUFFER_SIZE), on_heap_(false) {}
    
    ~MinimalStream() {
        if (on_heap_) {
            delete[] buffer_;
        }
    }
    
    MinimalStream& operator<<(const std::string& s) {
        append(s.c_str(), s.size());
        return *this;
    }
    
    MinimalStream& operator<<(const char* s) {
        append(s, std::strlen(s));
        return *this;
    }
    
    MinimalStream& operator<<(char c) {
        ensure_capacity(1);
        buffer_[size_++] = c;
        return *this;
    }
    
    MinimalStream& operator<<(int32_t i) {
        print_integer(i);
        return *this;
    }
    
    MinimalStream& operator<<(int64_t i) {
        print_integer(i);
        return *this;
    }
    
    MinimalStream& operator<<(uint32_t i) {
        print_unsigned(i);
        return *this;
    }
    
    MinimalStream& operator<<(uint64_t i) {
        print_unsigned(i);
        return *this;
    }
    
    MinimalStream& operator<<(double d) {
        // For doubles, we still need sprintf for proper formatting
        char temp[64];
        int len = std::snprintf(temp, sizeof(temp), "%g", d);
        if (len > 0) {
            append(temp, len);
        }
        return *this;
    }
    
    MinimalStream& operator<<(bool b) {
        if (b) {
            append("true", 4);
        } else {
            append("false", 5);
        }
        return *this;
    }
    
    std::string str() const {
        return std::string(buffer_, size_);
    }
    
    void clear() {
        if (on_heap_) {
            delete[] buffer_;
            buffer_ = stack_buffer_;
            capacity_ = STACK_BUFFER_SIZE;
            on_heap_ = false;
        }
        size_ = 0;
    }
};

int main() {
    std::cout << "Testing template_streamop with ThriftTest types..." << std::endl;
    
    // Test 1: Test with std::ostringstream
    {
        Xtruct x;
        x.__set_string_thing("test string");
        x.__set_byte_thing(42);
        x.__set_i32_thing(12345);
        x.__set_i64_thing(9876543210LL);
        
        std::ostringstream oss;
        oss << x;
        std::string result = oss.str();
        
        std::cout << "  Generated output: " << result << std::endl;
        
        assert(!result.empty());
        assert(result.find("test string") != std::string::npos);
        assert(result.find("42") != std::string::npos);
        assert(result.find("12345") != std::string::npos);
        std::cout << "  ✓ std::ostringstream works: " << result << std::endl;
    }
    
    // Test 2: Test with custom MinimalStream
    {
        Xtruct x;
        x.__set_string_thing("custom stream");
        x.__set_byte_thing(7);
        x.__set_i32_thing(999);
        x.__set_i64_thing(1234567890LL);
        
        MinimalStream ms;
        ms << x;
        std::string result = ms.str();
        
        assert(!result.empty());
        assert(result.find("custom stream") != std::string::npos);
        assert(result.find("7") != std::string::npos);
        assert(result.find("999") != std::string::npos);
        std::cout << "  ✓ MinimalStream works: " << result << std::endl;
    }
    
    // Test 3: Test nested structures
    {
        Xtruct x;
        x.__set_string_thing("inner");
        x.__set_i32_thing(100);
        
        Xtruct2 x2;
        x2.__set_byte_thing(5);
        x2.__set_struct_thing(x);
        x2.__set_i32_thing(200);
        
        std::ostringstream oss;
        oss << x2;
        std::string result = oss.str();
        
        assert(!result.empty());
        assert(result.find("inner") != std::string::npos);
        assert(result.find("100") != std::string::npos);
        assert(result.find("200") != std::string::npos);
        std::cout << "  ✓ Nested structures work" << std::endl;
    }
    
    // Test 4: Test optional fields
    {
        Bonk bonk;
        bonk.__set_message("test message");
        bonk.__set_type(42);
        
        std::ostringstream oss;
        oss << bonk;
        std::string result = oss.str();
        
        assert(!result.empty());
        assert(result.find("test message") != std::string::npos);
        assert(result.find("42") != std::string::npos);
        std::cout << "  ✓ Optional fields work" << std::endl;
    }
    
    // Test 5: Test structs with map/set/list/vector
    {
        std::cout << "\n  Testing collection types..." << std::endl;
        
        // Create an Insanity struct with map and list
        Insanity insanity;
        
        // Add items to the map
        std::map userMap;
        userMap[Numberz::ONE] = 1;
        userMap[Numberz::FIVE] = 5;
        insanity.__set_userMap(userMap);
        
        // Add items to the list
        std::vector xtructs;
        Xtruct x1;
        x1.__set_string_thing("first");
        x1.__set_i32_thing(111);
        xtructs.push_back(x1);
        
        Xtruct x2;
        x2.__set_string_thing("second");
        x2.__set_i32_thing(222);
        xtructs.push_back(x2);
        insanity.__set_xtructs(xtructs);
        
        // Test with std::ostringstream
        std::ostringstream oss;
        oss << insanity;
        std::string result = oss.str();
        
        std::cout << "    std::ostringstream output: " << result << std::endl;
        assert(!result.empty());
        assert(result.find("Insanity") != std::string::npos);
        assert(result.find("userMap") != std::string::npos);
        assert(result.find("xtructs") != std::string::npos);
        
        // Test with MinimalStream
        MinimalStream ms;
        ms << insanity;
        std::string ms_result = ms.str();
        
        std::cout << "    MinimalStream output: " << ms_result << std::endl;
        assert(!ms_result.empty());
        assert(ms_result.find("Insanity") != std::string::npos);
        
        std::cout << "  ✓ Map/List collections work with both streams" << std::endl;
    }
    
    // Test 6: Test to_string compatibility with collection structs
    {
        std::cout << "\n  Testing to_string with collection structs..." << std::endl;
        
        Insanity insanity;
        std::map userMap;
        userMap[Numberz::TWO] = 2;
        insanity.__set_userMap(userMap);
        
        std::vector xtructs;
        Xtruct x;
        x.__set_string_thing("test");
        x.__set_i32_thing(42);
        xtructs.push_back(x);
        insanity.__set_xtructs(xtructs);
        
        // to_string should work with the generated types
        std::string str_result = apache::thrift::to_string(insanity);
        
        std::cout << "    to_string output: " << str_result << std::endl;
        assert(!str_result.empty());
        assert(str_result.find("Insanity") != std::string::npos);
        
        std::cout << "  ✓ to_string works with collection structs" << std::endl;
    }
    
    // Test 7: Test enum output - should print by name
    {
        std::cout << "\n  Testing enum output..." << std::endl;
        
        // Create a struct with an enum field
        Insanity insanity;
        std::map userMap;
        userMap[Numberz::ONE] = 1;
        userMap[Numberz::FIVE] = 5;
        userMap[Numberz::TWO] = 2;
        insanity.__set_userMap(userMap);
        
        // Test with std::ostringstream
        std::ostringstream oss;
        oss << insanity;
        std::string result = oss.str();
        
        std::cout << "    std::ostringstream output: " << result << std::endl;
        assert(result.find("ONE") != std::string::npos || result.find("1") != std::string::npos);
        
        // Test with MinimalStream
        MinimalStream ms;
        ms << insanity;
        std::string ms_result = ms.str();
        
        std::cout << "    MinimalStream output: " << ms_result << std::endl;
        assert(!ms_result.empty());
        
        std::cout << "  ✓ Enum fields output correctly" << std::endl;
    }
    
    // Test 8: Test floating point types
    {
        std::cout << "\n  Testing floating point types..." << std::endl;
        
        // Note: ThriftTest doesn't have a struct with float/double fields
        // So we test directly with printTo
        float f = 3.14159f;
        double d = 2.71828;
        
        // Test with std::ostringstream
        std::ostringstream oss_f, oss_d;
        apache::thrift::printTo(oss_f, f);
        apache::thrift::printTo(oss_d, d);
        
        std::string f_result = oss_f.str();
        std::string d_result = oss_d.str();
        
        std::cout << "    float printTo: " << f_result << std::endl;
        std::cout << "    double printTo: " << d_result << std::endl;
        
        assert(!f_result.empty());
        assert(!d_result.empty());
        assert(f_result.find("3.14") != std::string::npos || f_result.find("3,14") != std::string::npos);
        assert(d_result.find("2.71") != std::string::npos || d_result.find("2,71") != std::string::npos);
        
        // Test with MinimalStream
        MinimalStream ms_f, ms_d;
        apache::thrift::printTo(ms_f, f);
        apache::thrift::printTo(ms_d, d);
        
        std::cout << "    MinimalStream float: " << ms_f.str() << std::endl;
        std::cout << "    MinimalStream double: " << ms_d.str() << std::endl;
        
        assert(!ms_f.str().empty());
        assert(!ms_d.str().empty());
        
        std::cout << "  ✓ Floating point types work correctly" << std::endl;
    }
    
    // Performance Test: Compare std::ostringstream vs MinimalStream
    {
        const int iterations = 10000;
        Xtruct x;
        x.__set_string_thing("performance test string");
        x.__set_byte_thing(123);
        x.__set_i32_thing(456789);
        x.__set_i64_thing(9876543210LL);
        
        // Test std::ostringstream performance
        auto start_oss = std::chrono::high_resolution_clock::now();
        std::string accumulated_result;  // Prevent optimization by accumulating results
        for (int i = 0; i < iterations; ++i) {
            std::ostringstream oss;
            oss << x;
            accumulated_result += oss.str();  // Use result to prevent optimization
        }
        auto end_oss = std::chrono::high_resolution_clock::now();
        auto duration_oss = std::chrono::duration_cast(end_oss - start_oss).count();
        
        // Test MinimalStream performance
        auto start_ms = std::chrono::high_resolution_clock::now();
        accumulated_result.clear();  // Reuse for MinimalStream test
        for (int i = 0; i < iterations; ++i) {
            MinimalStream ms;
            ms << x;
            accumulated_result += ms.str();  // Use result to prevent optimization
        }
        auto end_ms = std::chrono::high_resolution_clock::now();
        auto duration_ms = std::chrono::duration_cast(end_ms - start_ms).count();
        
        std::cout << "\n  Performance comparison (" << iterations << " iterations):" << std::endl;
        std::cout << "    std::ostringstream: " << duration_oss << " μs" << std::endl;
        std::cout << "    MinimalStream:      " << duration_ms << " μs" << std::endl;
        
        if (duration_ms < duration_oss) {
            double improvement = ((double)(duration_oss - duration_ms) / duration_oss) * 100.0;
            std::cout << "    MinimalStream is " << improvement << "% faster" << std::endl;
        } else {
            double difference = ((double)(duration_ms - duration_oss) / duration_oss) * 100.0;
            std::cout << "    std::ostringstream is " << difference << "% faster" << std::endl;
        }
        
        std::cout << "  ✓ Performance test completed" << std::endl;
    }
    
    std::cout << "\n✅ All template_streamop tests passed!" << std::endl;
    return 0;
}
thrift-0.23.0/test/cpp/src/EnumClassTest.cpp0000664000175000017500000001400315167543515021156 0ustar00buildbuild00000000000000/*
 * 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.
 */

/**
 * Test file to verify that pure_enums=enum_class generated code compiles and works correctly.
 * This exercises the enum_class option using ThriftTest types.
 */

#include 
#include 
#include 
#include 
#include 

// Include generated thrift types with enum_class option
#include "ThriftTest_types.h"

using namespace thrift::test;

int main() {
    std::cout << "Testing pure_enums=enum_class with ThriftTest types..." << std::endl;
    
    // Compile-time verification that Numberz is an enum class
    static_assert(std::is_enum::value, "Numberz should be an enum type");
    // enum class doesn't implicitly convert to int, which is a key characteristic
    static_assert(!std::is_convertible::value, 
                  "Numberz should be enum class (not implicitly convertible to int)");
    std::cout << "  ✓ Compile-time verification: Numberz is enum class" << std::endl;
    
    // Test 1: Verify enum class can be used with scoped names
    {
        Numberz num = Numberz::ONE;
        assert(static_cast(num) == 1);
        std::cout << "  ✓ Enum class scoped access works (Numberz::ONE)" << std::endl;
    }
    
    // Test 2: Verify different enum values
    {
        Numberz two = Numberz::TWO;
        Numberz five = Numberz::FIVE;
        assert(static_cast(two) == 2);
        assert(static_cast(five) == 5);
        std::cout << "  ✓ Multiple enum class values work" << std::endl;
    }
    
    // Test 3: Verify enum class comparison
    {
        Numberz a = Numberz::THREE;
        Numberz b = Numberz::THREE;
        Numberz c = Numberz::FIVE;
        assert(a == b);
        assert(a != c);
        std::cout << "  ✓ Enum class comparison works" << std::endl;
    }
    
    // Test 4: Verify enum class in switch statement
    {
        Numberz num = Numberz::EIGHT;
        bool found = false;
        switch(num) {
            case Numberz::ONE:
                break;
            case Numberz::TWO:
                break;
            case Numberz::EIGHT:
                found = true;
                break;
            default:
                break;
        }
        assert(found);
        std::cout << "  ✓ Enum class in switch statements works" << std::endl;
    }
    
    // Test 5: Verify to_string() works with enum class
    {
        Numberz one = Numberz::ONE;
        Numberz five = Numberz::FIVE;
        Numberz eight = Numberz::EIGHT;
        
        std::string str_one = to_string(one);
        std::string str_five = to_string(five);
        std::string str_eight = to_string(eight);
        
        assert(str_one == "ONE");
        assert(str_five == "FIVE");
        assert(str_eight == "EIGHT");
        std::cout << "  ✓ to_string() with enum class works (ONE, FIVE, EIGHT)" << std::endl;
    }
    
    // Test 6: Verify operator<< works with enum class
    {
        Numberz two = Numberz::TWO;
        Numberz three = Numberz::THREE;
        
        std::ostringstream oss;
        oss << two << " and " << three;
        
        std::string result = oss.str();
        assert(result == "TWO and THREE");
        std::cout << "  ✓ operator<< with enum class works (TWO and THREE)" << std::endl;
    }
    
    // Test 7: Verify to_string() for invalid/cast enum values
    {
        // Cast an invalid value to enum (edge case testing)
        Numberz invalid = static_cast(999);
        std::string str_invalid = to_string(invalid);
        
        // Should fall back to numeric representation
        assert(str_invalid == "999");
        std::cout << "  ✓ to_string() handles invalid enum values (999)" << std::endl;
    }
    
    // Test 8: Verify operator<< for invalid/cast enum values
    {
        Numberz invalid = static_cast(777);
        std::ostringstream oss;
        oss << invalid;
        
        std::string result = oss.str();
        assert(result == "777");
        std::cout << "  ✓ operator<< handles invalid enum values (777)" << std::endl;
    }
    
    // Test 9: Verify enum class with zero value
    {
        Numberz zero = static_cast(0);
        std::string str_zero = to_string(zero);
        
        std::ostringstream oss;
        oss << zero;
        
        // Both should output "0" since there's no named value
        assert(str_zero == "0");
        assert(oss.str() == "0");
        std::cout << "  ✓ to_string() and operator<< work with zero value" << std::endl;
    }
    
    // Test 10: Verify all Numberz enum values can be converted to string
    {
        std::ostringstream oss;
        oss << Numberz::ONE << ", "
            << Numberz::TWO << ", "
            << Numberz::THREE << ", "
            << Numberz::FIVE << ", "
            << Numberz::SIX << ", "
            << Numberz::EIGHT;
        
        std::string result = oss.str();
        assert(result == "ONE, TWO, THREE, FIVE, SIX, EIGHT");
        std::cout << "  ✓ All Numberz enum values stream correctly" << std::endl;
    }
    
    std::cout << "\n✅ All pure_enums=enum_class tests passed!" << std::endl;
    std::cout << "   Verified at compile-time: enum class properties enforced" << std::endl;
    std::cout << "   Verified at runtime: to_string(), operator<< work correctly" << std::endl;
    return 0;
}
thrift-0.23.0/test/cpp/src/ThriftTest_extras.cpp0000664000175000017500000000221415165535636022116 0ustar00buildbuild00000000000000/*
 * 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.
 */

// Extra functions required for ThriftTest_types to work

#include 
#include "gen-cpp/ThriftTest_types.h"

namespace thrift {
namespace test {

bool Insanity::operator<(thrift::test::Insanity const& other) const {
  using apache::thrift::ThriftDebugString;
  return ThriftDebugString(*this) < ThriftDebugString(other);
}
}
}
thrift-0.23.0/test/cpp/src/PrivateOptionalTest.cpp0000664000175000017500000001230515167543515022407 0ustar00buildbuild00000000000000/*
 * 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.
 */

/**
 * Test file to verify that private_optional generated code compiles and works correctly.
 * This exercises the private_optional option using ThriftTest types.
 */

#include 
#include 
#include 
#include 

// Include generated thrift types with private_optional option
#include "ThriftTest_types.h"

using namespace thrift::test;

// SFINAE test to check if a field is directly accessible
template
struct has_public_string_thing : std::false_type {};

template
struct has_public_string_thing().string_thing))> : std::true_type {};

// SFINAE test to check if optional field 'aa' is directly accessible
template
struct has_public_aa : std::false_type {};

template
struct has_public_aa().aa))> : std::true_type {};

// SFINAE test to check if required field 'ab' is directly accessible
template
struct has_public_ab : std::false_type {};

template
struct has_public_ab().ab))> : std::true_type {};

int main() {
    std::cout << "Testing private_optional with ThriftTest types..." << std::endl;
    
    // Compile-time verification: required fields should still be publicly accessible
    static_assert(has_public_string_thing::value,
                  "Required fields (like string_thing in Xtruct) should remain public");
    std::cout << "  ✓ Compile-time verification: Required fields are public (Xtruct)" << std::endl;
    
    // Compile-time verification for StructB: optional field 'aa' should be private
    static_assert(!has_public_aa::value,
                  "Optional field 'aa' in StructB should be private with private_optional");
    std::cout << "  ✓ Compile-time verification: Optional field 'aa' is private (StructB)" << std::endl;
    
    // Compile-time verification for StructB: required field 'ab' should be public
    static_assert(has_public_ab::value,
                  "Required field 'ab' in StructB should remain public");
    std::cout << "  ✓ Compile-time verification: Required field 'ab' is public (StructB)" << std::endl;
    
    // Test 1: Verify getters work for accessing fields
    {
        Xtruct x;
        x.__set_string_thing("test");
        const std::string& str = x.__get_string_thing();
        assert(str == "test");
        std::cout << "  ✓ Getter for string field works" << std::endl;
    }
    
    // Test 2: Verify setters work
    {
        Xtruct x;
        x.__set_i32_thing(42);
        x.__set_i64_thing(1234567890);
        assert(x.__get_i32_thing() == 42);
        assert(x.__get_i64_thing() == 1234567890);
        std::cout << "  ✓ Setters for primitive fields work" << std::endl;
    }
    
    // Test 3: Verify getters/setters for complex types
    {
        Xtruct2 x2;
        Xtruct x;
        x.__set_string_thing("nested");
        x.__set_i32_thing(99);
        x2.__set_struct_thing(x);
        // With private_optional, use getters to access fields
        assert(x2.__get_struct_thing().__get_string_thing() == "nested");
        assert(x2.__get_struct_thing().__get_i32_thing() == 99);
        std::cout << "  ✓ Getters/setters for struct fields work" << std::endl;
    }
    
    // Test 4: Verify direct access to required fields still works
    {
        Xtruct x;
        x.string_thing = "direct access";
        x.i32_thing = 123;
        assert(x.string_thing == "direct access");
        assert(x.i32_thing == 123);
        std::cout << "  ✓ Direct access to required fields works" << std::endl;
    }
    
    // Test 5: Test StructB with optional and required fields
    {
        StructB sb;
        StructA sa;
        sa.__set_s("test struct");
        
        // Set optional field 'aa' using setter (cannot access directly)
        sb.__set_aa(sa);
        
        // Set and access required field 'ab' directly (it's public)
        sb.ab = sa;
        
        // Verify using getters
        assert(sb.__get_aa().__get_s() == "test struct");
        assert(sb.ab.__get_s() == "test struct");
        std::cout << "  ✓ StructB: Optional field private, required field public" << std::endl;
    }
    
    std::cout << "\n✅ All private_optional tests passed!" << std::endl;
    std::cout << "   Verified at compile-time: Optional fields are private, required fields public" << std::endl;
    return 0;
}
thrift-0.23.0/test/cpp/src/TestServer.cpp0000664000175000017500000007430515167543515020545 0ustar00buildbuild00000000000000/*
 * 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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "SecondService.h"
#include "ThriftTest.h"

#ifdef HAVE_STDINT_H
#include 
#endif
#ifdef HAVE_INTTYPES_H
#include 
#endif
#ifdef HAVE_SIGNAL_H
#include 
#endif
#ifdef HAVE_SYS_SOCKET_H
#include 
#endif
#ifdef HAVE_SYS_UN_H
#include 
#endif

#include 
#include 
#include 
#include 

#include 
#include 
#include 

#if _WIN32
#include 
#endif

using namespace std;

using namespace apache::thrift;
using namespace apache::thrift::async;
using namespace apache::thrift::concurrency;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;

using namespace thrift::test;

// to handle a controlled shutdown, signal handling is mandatory
#ifdef HAVE_SIGNAL_H
apache::thrift::concurrency::Monitor gMonitor;
void signal_handler(int signum)
{
  if (signum == SIGINT) {
    gMonitor.notifyAll();
  }
}
#endif

class TestHandler : public ThriftTestIf {
public:
  TestHandler() = default;

  void testVoid() override { printf("testVoid()\n"); }

  void testString(string& out, const string& thing) override {
    printf("testString(\"%s\")\n", thing.c_str());
    out = thing;
  }

  bool testBool(const bool thing) override {
    printf("testBool(%s)\n", thing ? "true" : "false");
    return thing;
  }

  int8_t testByte(const int8_t thing) override {
    printf("testByte(%d)\n", (int)thing);
    return thing;
  }

  int32_t testI32(const int32_t thing) override {
    printf("testI32(%d)\n", thing);
    return thing;
  }

  int64_t testI64(const int64_t thing) override {
    printf("testI64(%" PRId64 ")\n", thing);
    return thing;
  }

  double testDouble(const double thing) override {
    printf("testDouble(%f)\n", thing);
    return thing;
  }

  void testBinary(std::string& _return, const std::string& thing) override {
    std::ostringstream hexstr;
    hexstr << std::hex << thing;
    printf("testBinary(%lu: %s)\n", safe_numeric_cast(thing.size()), hexstr.str().c_str());
    _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(),
           (int)thing.byte_thing,
           thing.i32_thing,
           thing.i64_thing);
    out = thing;
  }

  void testNest(Xtruct2& out, const Xtruct2& nest) override {
    const Xtruct& thing = nest.struct_thing;
    printf("testNest({%d, {\"%s\", %d, %d, %" PRId64 "}, %d})\n",
           (int)nest.byte_thing,
           thing.string_thing.c_str(),
           (int)thing.byte_thing,
           thing.i32_thing,
           thing.i64_thing,
           nest.i32_thing);
    out = nest;
  }

  void testMap(map& out, const map& thing) override {
    printf("testMap({");
    map::const_iterator m_iter;
    bool first = true;
    for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d => %d", m_iter->first, m_iter->second);
    }
    printf("})\n");
    out = thing;
  }

  void testStringMap(map& out,
                     const map& thing) override {
    printf("testMap({");
    map::const_iterator m_iter;
    bool first = true;
    for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%s => %s", (m_iter->first).c_str(), (m_iter->second).c_str());
    }
    printf("})\n");
    out = thing;
  }

  void testSet(set& out, const set& thing) override {
    printf("testSet({");
    set::const_iterator s_iter;
    bool first = true;
    for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d", *s_iter);
    }
    printf("})\n");
    out = thing;
  }

  void testList(vector& out, const vector& thing) override {
    printf("testList({");
    vector::const_iterator l_iter;
    bool first = true;
    for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d", *l_iter);
    }
    printf("})\n");
    out = thing;
  }

  Numberz::type testEnum(const Numberz::type thing) override {
    printf("testEnum(%d)\n", thing);
    return thing;
  }

  UserId testTypedef(const UserId thing) override {
    printf("testTypedef(%" PRId64 ")\n", thing);
    return thing;
  }

  void testMapMap(map >& mapmap, const int32_t hello) override {
    printf("testMapMap(%d)\n", hello);

    map pos;
    map neg;
    for (int i = 1; i < 5; i++) {
      pos.insert(make_pair(i, i));
      neg.insert(make_pair(-i, -i));
    }

    mapmap.insert(make_pair(4, pos));
    mapmap.insert(make_pair(-4, neg));
  }

  void testInsanity(map >& insane, const Insanity& argument) override {
    printf("testInsanity()\n");

    Insanity looney;
    map first_map;
    map second_map;

    first_map.insert(make_pair(Numberz::TWO, argument));
    first_map.insert(make_pair(Numberz::THREE, argument));

    second_map.insert(make_pair(Numberz::SIX, looney));

    insane.insert(make_pair(1, first_map));
    insane.insert(make_pair(2, second_map));

    printf("return");
    printf(" = {");
    map >::const_iterator i_iter;
    for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
      printf("%" PRId64 " => {", i_iter->first);
      map::const_iterator i2_iter;
      for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
        printf("%d => {", i2_iter->first);
        map userMap = i2_iter->second.userMap;
        map::const_iterator um;
        printf("{");
        for (um = userMap.begin(); um != userMap.end(); ++um) {
          printf("%d => %" PRId64 ", ", um->first, um->second);
        }
        printf("}, ");

        vector xtructs = i2_iter->second.xtructs;
        vector::const_iterator x;
        printf("{");
        for (x = xtructs.begin(); x != xtructs.end(); ++x) {
          printf("{\"%s\", %d, %d, %" PRId64 "}, ",
                 x->string_thing.c_str(),
                 (int)x->byte_thing,
                 x->i32_thing,
                 x->i64_thing);
        }
        printf("}");

        printf("}, ");
      }
      printf("}, ");
    }
    printf("}\n");
  }

  void testMulti(Xtruct& hello,
                 const int8_t arg0,
                 const int32_t arg1,
                 const int64_t arg2,
                 const std::map& arg3,
                 const Numberz::type arg4,
                 const UserId arg5) override {
    (void)arg3;
    (void)arg4;
    (void)arg5;

    printf("testMulti()\n");

    hello.string_thing = "Hello2";
    hello.byte_thing = arg0;
    hello.i32_thing = arg1;
    hello.i64_thing = (int64_t)arg2;
  }

  void testException(const std::string& arg) override {
    printf("testException(%s)\n", arg.c_str());
    if (arg.compare("Xception") == 0) {
      Xception e;
      e.errorCode = 1001;
      e.message = arg;
      throw e;
    } else if (arg.compare("TException") == 0) {
      apache::thrift::TException e;
      throw e;
    } else {
      Xtruct result;
      result.string_thing = arg;
      return;
    }
  }

  void testMultiException(Xtruct& result,
                          const std::string& arg0,
                          const std::string& arg1) override {

    printf("testMultiException(%s, %s)\n", arg0.c_str(), arg1.c_str());

    if (arg0.compare("Xception") == 0) {
      Xception e;
      e.errorCode = 1001;
      e.message = "This is an Xception";
      throw e;
    } else if (arg0.compare("Xception2") == 0) {
      Xception2 e;
      e.errorCode = 2002;
      e.struct_thing.string_thing = "This is an Xception2";
      throw e;
    } else {
      result.string_thing = arg1;
      return;
    }
  }

  void testOneway(const int32_t aNum) override {
    printf("testOneway(%d): call received\n", aNum);
  }
};

class SecondHandler : public SecondServiceIf
{
  public:
    void secondtestString(std::string& result, const std::string& thing) override
    { result = "testString(\"" + thing + "\")"; }
};

class TestProcessorEventHandler : public TProcessorEventHandler {
  void* getContext(const char* fn_name, void* serverContext) override {
    (void)serverContext;
    return new std::string(fn_name);
  }
  void freeContext(void* ctx, const char* fn_name) override {
    (void)fn_name;
    delete static_cast(ctx);
  }
  void preRead(void* ctx, const char* fn_name) override { communicate("preRead", ctx, fn_name); }
  void postRead(void* ctx, const char* fn_name, uint32_t bytes) override {
    (void)bytes;
    communicate("postRead", ctx, fn_name);
  }
  void preWrite(void* ctx, const char* fn_name) override { communicate("preWrite", ctx, fn_name); }
  void postWrite(void* ctx, const char* fn_name, uint32_t bytes) override {
    (void)bytes;
    communicate("postWrite", ctx, fn_name);
  }
  void asyncComplete(void* ctx, const char* fn_name) override {
    communicate("asyncComplete", ctx, fn_name);
  }
  void handlerError(void* ctx, const char* fn_name) override {
    communicate("handlerError", ctx, fn_name);
  }

  void communicate(const char* event, void* ctx, const char* fn_name) {
    std::cout << event << ": " << *static_cast(ctx) << " = " << fn_name << '\n';
  }
};

class TestHandlerAsync : public ThriftTestCobSvIf {
public:
  TestHandlerAsync(std::shared_ptr& handler) : _delegate(handler) {}
  ~TestHandlerAsync() override = default;

  void testVoid(std::function cob) override {
    _delegate->testVoid();
    cob();
  }

  void testString(std::function cob,
                          const std::string& thing) override {
    std::string res;
    _delegate->testString(res, thing);
    cob(res);
  }

  void testBool(std::function cob, const bool thing) override {
    bool res = _delegate->testBool(thing);
    cob(res);
  }

  void testByte(std::function cob, const int8_t thing) override {
    int8_t res = _delegate->testByte(thing);
    cob(res);
  }

  void testI32(std::function cob, const int32_t thing) override {
    int32_t res = _delegate->testI32(thing);
    cob(res);
  }

  void testI64(std::function cob, const int64_t thing) override {
    int64_t res = _delegate->testI64(thing);
    cob(res);
  }

  void testDouble(std::function cob, const double thing) override {
    double res = _delegate->testDouble(thing);
    cob(res);
  }

  void testBinary(std::function cob,
                          const std::string& thing) override {
    std::string res;
    _delegate->testBinary(res, thing);
    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);
    cob(res);
  }

  void testNest(std::function cob, const Xtruct2& thing) override {
    Xtruct2 res;
    _delegate->testNest(res, thing);
    cob(res);
  }

  void testMap(std::function const& _return)> cob,
                       const std::map& thing) override {
    std::map res;
    _delegate->testMap(res, thing);
    cob(res);
  }

  void testStringMap(
      std::function const& _return)> cob,
      const std::map& thing) override {
    std::map res;
    _delegate->testStringMap(res, thing);
    cob(res);
  }

  void testSet(std::function const& _return)> cob,
                       const std::set& thing) override {
    std::set res;
    _delegate->testSet(res, thing);
    cob(res);
  }

  void testList(std::function const& _return)> cob,
                        const std::vector& thing) override {
    std::vector res;
    _delegate->testList(res, thing);
    cob(res);
  }

  void testEnum(std::function cob,
                        const Numberz::type thing) override {
    Numberz::type res = _delegate->testEnum(thing);
    cob(res);
  }

  void testTypedef(std::function cob, const UserId thing) override {
    UserId res = _delegate->testTypedef(thing);
    cob(res);
  }

  void testMapMap(
      std::function > const& _return)> cob,
      const int32_t hello) override {
    std::map > res;
    _delegate->testMapMap(res, hello);
    cob(res);
  }

  void testInsanity(
      std::function > const& _return)> cob,
      const Insanity& argument) override {
    std::map > res;
    _delegate->testInsanity(res, argument);
    cob(res);
  }

  void testMulti(std::function cob,
                         const int8_t arg0,
                         const int32_t arg1,
                         const int64_t arg2,
                         const std::map& arg3,
                         const Numberz::type arg4,
                         const UserId arg5) override {
    Xtruct res;
    _delegate->testMulti(res, arg0, arg1, arg2, arg3, arg4, arg5);
    cob(res);
  }

  void testException(
      std::function cob,
      std::function exn_cob,
      const std::string& arg) override {
    try {
      _delegate->testException(arg);
    } catch (const apache::thrift::TException& e) {
      exn_cob(apache::thrift::TDelayedException::delayException(e));
      return;
    }
    cob();
  }

  void testMultiException(
      std::function cob,
      std::function exn_cob,
      const std::string& arg0,
      const std::string& arg1) override {
    Xtruct res;
    try {
      _delegate->testMultiException(res, arg0, arg1);
    } catch (const apache::thrift::TException& e) {
      exn_cob(apache::thrift::TDelayedException::delayException(e));
      return;
    }
    cob(res);
  }

  void testOneway(std::function cob, const int32_t secondsToSleep) override {
    _delegate->testOneway(secondsToSleep);
    cob();
  }

protected:
  std::shared_ptr _delegate;
};

struct DomainSocketFd {
  THRIFT_SOCKET socket_fd;
  std::string path;
  DomainSocketFd(const std::string& path) : path(path) {
#ifdef HAVE_SYS_UN_H
    unlink(path.c_str());
    socket_fd = socket(AF_UNIX, SOCK_STREAM, IPPROTO_IP);
    if (socket_fd == -1) {
      std::ostringstream os;
      os << "Cannot create domain socket: " << strerror(errno);
      throw std::runtime_error(os.str());
    }
    if (path.size() > sizeof(sockaddr_un::sun_path) - 1)
      throw std::runtime_error("Path size on domain socket too big");
    struct sockaddr_un sa;
    memset(&sa, 0, sizeof(sa));
    sa.sun_family = AF_UNIX;
    strcpy(sa.sun_path, path.c_str());
    int rv = ::bind(socket_fd, (struct sockaddr*)&sa, sizeof(sa));
    if (rv == -1) {
      std::ostringstream os;
      os << "Cannot bind domain socket: " << strerror(errno);
      throw std::runtime_error(os.str());
    }

    rv = ::listen(socket_fd, 16);
    if (rv == -1) {
      std::ostringstream os;
      os << "Cannot listen on domain socket: " << strerror(errno);
      throw std::runtime_error(os.str());
    }
#else
    throw std::runtime_error("Cannot create a domain socket without AF_UNIX");
#endif
  }
  ~DomainSocketFd() {
    ::THRIFT_CLOSESOCKET(socket_fd);
    unlink(path.c_str());
  }
};

namespace po = boost::program_options;

int main(int argc, char** argv) {

  string testDir = boost::filesystem::system_complete(argv[0]).parent_path().parent_path().parent_path().string();
  string certPath = testDir + "/keys/server.crt";
  string keyPath = testDir + "/keys/server.key";

#if _WIN32
  transport::TWinsockSingleton::create();
#endif
  int port = 9090;
  bool ssl = false;
  bool zlib = false;
  string transport_type = "buffered";
  string protocol_type = "binary";
  string server_type = "simple";
  string domain_socket = "";
  bool abstract_namespace = false;
  bool emulate_socketactivation = false;
  std::unique_ptr domain_socket_fd;
  size_t workers = 4;
  int string_limit = 0;
  int container_limit = 0;

  po::options_description desc("Allowed options");
  desc.add_options()
    ("help,h", "produce help message")
    ("port", po::value(&port)->default_value(port), "Port number to listen")
    ("domain-socket", po::value(&domain_socket) ->default_value(domain_socket), "Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)")
    ("abstract-namespace", "Create the domain socket in the Abstract Namespace (no connection with filesystem pathnames)")
    ("emulate-socketactivation","Open the socket from the tester program and pass the library an already open fd")
    ("server-type", po::value(&server_type)->default_value(server_type), "type of server, \"simple\", \"thread-pool\", \"threaded\", or \"nonblocking\"")
    ("transport", po::value(&transport_type)->default_value(transport_type), "transport: buffered, framed, http, websocket, zlib")
    ("protocol", po::value(&protocol_type)->default_value(protocol_type), "protocol: binary, compact, header, json, multi, multic, multih, multij")
    ("ssl", "Encrypted Transport using SSL")
    ("zlib", "Wrapped Transport using Zlib")
    ("processor-events", "processor-events")
    ("workers,n", po::value(&workers)->default_value(workers), "Number of thread pools workers. Only valid for thread-pool server type")
    ("string-limit", po::value(&string_limit))
    ("container-limit", po::value(&container_limit));

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm.count("help")) {
    cout << desc << "\n";
    return 1;
  }

  try {
    if (!server_type.empty()) {
      if (server_type == "simple") {
      } else if (server_type == "thread-pool") {
      } else if (server_type == "threaded") {
      } else if (server_type == "nonblocking") {
      } else {
        throw invalid_argument("Unknown server type " + server_type);
      }
    }

    if (!protocol_type.empty()) {
      if (protocol_type == "binary") {
      } else if (protocol_type == "compact") {
      } else if (protocol_type == "json") {
      } else if (protocol_type == "header") {
      } else if (protocol_type == "multi") {  // multiplexed binary
      } else if (protocol_type == "multic") { // multiplexed compact
      } else if (protocol_type == "multih") { // multiplexed header
      } else if (protocol_type == "multij") { // multiplexed json
      } else {
        throw invalid_argument("Unknown protocol type " + protocol_type);
      }
    }

    if (!transport_type.empty()) {
      if (transport_type == "buffered") {
      } else if (transport_type == "framed") {
      } else if (transport_type == "http") {
      } else if (transport_type == "websocket") {
      } else if (transport_type == "zlib") {
        // crosstester will pass zlib as a flag and a transport right now...
      } else {
        throw invalid_argument("Unknown transport type " + transport_type);
      }
    }

  } catch (std::exception& e) {
    cerr << e.what() << '\n';
    cout << desc << "\n";
    return 1;
  }

  if (vm.count("ssl")) {
    ssl = true;
  }

  if (vm.count("zlib")) {
    zlib = true;
  }

#if defined(HAVE_SIGNAL_H) && defined(SIGPIPE)
  if (ssl) {
    signal(SIGPIPE, SIG_IGN); // for OpenSSL, otherwise we end abruptly
  }
#endif

  if (vm.count("abstract-namespace")) {
    abstract_namespace = true;
  }
  if (vm.count("emulate-socketactivation")) {
    emulate_socketactivation = true;
  }

  // Dispatcher
  std::shared_ptr protocolFactory;
  if (protocol_type == "json" || protocol_type == "multij") {
    std::shared_ptr jsonProtocolFactory(new TJSONProtocolFactory());
    protocolFactory = jsonProtocolFactory;
  } else if (protocol_type == "compact" || protocol_type == "multic") {
    auto *compactProtocolFactory = new TCompactProtocolFactoryT();
    compactProtocolFactory->setContainerSizeLimit(container_limit);
    compactProtocolFactory->setStringSizeLimit(string_limit);
    protocolFactory.reset(compactProtocolFactory);
  } else if (protocol_type == "header" || protocol_type == "multih") {
    std::shared_ptr headerProtocolFactory(new THeaderProtocolFactory());
    protocolFactory = headerProtocolFactory;
  } else {
    auto* binaryProtocolFactory = new TBinaryProtocolFactoryT();
    binaryProtocolFactory->setContainerSizeLimit(container_limit);
    binaryProtocolFactory->setStringSizeLimit(string_limit);
    protocolFactory.reset(binaryProtocolFactory);
  }

  // Processors
  std::shared_ptr testHandler(new TestHandler());
  std::shared_ptr testProcessor(new ThriftTestProcessor(testHandler));

  if (vm.count("processor-events")) {
    testProcessor->setEventHandler(
        std::shared_ptr(new TestProcessorEventHandler()));
  }

  // Transport
  std::shared_ptr sslSocketFactory;
  std::shared_ptr serverSocket;

  if (ssl) {
    sslSocketFactory = std::shared_ptr(new TSSLSocketFactory());
    sslSocketFactory->loadCertificate(certPath.c_str());
    sslSocketFactory->loadPrivateKey(keyPath.c_str());
    sslSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
    if (server_type != "nonblocking") {
      serverSocket = std::shared_ptr(new TSSLServerSocket(port, sslSocketFactory));
    }
  } else {
    if (domain_socket != "") {
      if (abstract_namespace) {
        std::string abstract_socket("\0", 1);
        abstract_socket += domain_socket;
        serverSocket = std::shared_ptr(new TServerSocket(abstract_socket));
      } else {
        if (emulate_socketactivation) {
          unlink(domain_socket.c_str());
          // open and bind the socket
          domain_socket_fd.reset(new DomainSocketFd(domain_socket));
          serverSocket = std::shared_ptr(
              new TServerSocket(domain_socket_fd->socket_fd, SocketType::UNIX));
        } else {
          unlink(domain_socket.c_str());
          serverSocket = std::shared_ptr(new TServerSocket(domain_socket));
        }
      }
      port = 0;
    } else {
      serverSocket = std::shared_ptr(new TServerSocket(port));
    }
  }

  // Factory
  std::shared_ptr transportFactory;

  if (transport_type == "http" && server_type != "nonblocking") {
    transportFactory = std::make_shared();
  } else if (transport_type == "websocket" && server_type != "nonblocking") {
    if (protocol_type == "json" || protocol_type == "multij") {
      transportFactory = std::make_shared();
    } else {
      transportFactory = std::make_shared();
    }
  } else if (transport_type == "framed") {
    transportFactory = std::make_shared();
  } else {
    transportFactory = std::make_shared();
  }

  if (zlib) {
    // currently TZlibTransportFactory is the only factory than can wrap another:
    transportFactory = std::make_shared(transportFactory);
  }

  // Server Info
  cout << "Starting \"" << server_type << "\" server (" << transport_type << "/" << protocol_type
       << ") listen on: ";
  if (abstract_namespace) {
    cout << '@';
  }
  cout << domain_socket;
  if (port != 0) {
    cout << port;
  }
  cout << '\n';

  // Multiplexed Processor if needed
  if (boost::starts_with(protocol_type, "multi")) {
    std::shared_ptr secondHandler(new SecondHandler());
    std::shared_ptr secondProcessor(new SecondServiceProcessor(secondHandler));

    std::shared_ptr multiplexedProcessor(new TMultiplexedProcessor());
    multiplexedProcessor->registerDefault(testProcessor); // non-multi clients go to the default processor (multi:binary, multic:compact, ...)
    multiplexedProcessor->registerProcessor("ThriftTest", testProcessor);
    multiplexedProcessor->registerProcessor("SecondService", secondProcessor);
    testProcessor = std::dynamic_pointer_cast(multiplexedProcessor);
  }

  // Server
  std::shared_ptr server;

  if (server_type == "simple") {
    server.reset(new TSimpleServer(testProcessor, serverSocket, transportFactory, protocolFactory));
  } else if (server_type == "thread-pool") {

    std::shared_ptr threadFactory
        = std::shared_ptr(new ThreadFactory());

    std::shared_ptr threadManager = ThreadManager::newSimpleThreadManager(workers);
    threadManager->threadFactory(threadFactory);
    threadManager->start();

    server.reset(new TThreadPoolServer(testProcessor,
                                       serverSocket,
                                       transportFactory,
                                       protocolFactory,
                                       threadManager));
  } else if (server_type == "threaded") {
    server.reset(
        new TThreadedServer(testProcessor, serverSocket, transportFactory, protocolFactory));
  } else if (server_type == "nonblocking") {
    if (transport_type == "http") {
      std::shared_ptr testHandlerAsync(new TestHandlerAsync(testHandler));
      std::shared_ptr testProcessorAsync(
          new ThriftTestAsyncProcessor(testHandlerAsync));
      std::shared_ptr testBufferProcessor(
          new TAsyncProtocolProcessor(testProcessorAsync, protocolFactory));

      // not loading nonblockingServer into "server" because
      // TEvhttpServer doesn't inherit from TServer, and doesn't
      // provide a stop method.
      TEvhttpServer nonblockingServer(testBufferProcessor, port);
      nonblockingServer.serve();
    } else if (transport_type == "framed") {
      std::shared_ptr nbSocket;
      nbSocket.reset(
          ssl ? new transport::TNonblockingSSLServerSocket(port, sslSocketFactory)
              : new transport::TNonblockingServerSocket(port));
      server.reset(new TNonblockingServer(testProcessor, protocolFactory, nbSocket));
    } else {
      cerr << "server-type nonblocking requires transport of http or framed" << '\n';
      exit(1);
    }
  }

  if (server.get() != nullptr) {
    if (protocol_type == "header") {
      // Tell the server to use the same protocol for input / output
      // if using header
      server->setOutputProtocolFactory(std::shared_ptr());
    }

    apache::thrift::concurrency::ThreadFactory factory;
    factory.setDetached(false);
    std::shared_ptr serverThreadRunner(server);
    std::shared_ptr thread
        = factory.newThread(serverThreadRunner);

#ifdef HAVE_SIGNAL_H
    signal(SIGINT, signal_handler);
#endif

    thread->start();
    gMonitor.waitForever();         // wait for a shutdown signal

#ifdef HAVE_SIGNAL_H
    signal(SIGINT, SIG_DFL);
#endif

    server->stop();
    thread->join();
    server.reset();
  }

  cout << "done." << '\n';
  return 0;
}
thrift-0.23.0/test/cpp/src/PrivateOptionalTemplateStreamOpTest.cpp0000664000175000017500000001447615167543515025571 0ustar00buildbuild00000000000000/*
 * 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.
 */

/**
 * Test file to verify that generated code compiles and works correctly when
 * both private_optional and template_streamop options are enabled together.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

// Include generated thrift types with private_optional,template_streamop options
#include "ThriftTest_types.h"
#include 

using namespace thrift::test;

// SFINAE helpers to verify field accessibility at compile time.
// Each requires a separate template because C++ template parameters cannot be
// string literals, so each field name gets its own specialisation.
template
struct has_public_aa : std::false_type {};

template
struct has_public_aa().aa))> : std::true_type {};

// SFINAE test to check if required field 'ab' is directly accessible
template
struct has_public_ab : std::false_type {};

template
struct has_public_ab().ab))> : std::true_type {};

// Custom minimal stream - verifies that template_streamop works with non-std streams
class MinimalStream {
private:
    std::string buf_;
public:
    MinimalStream& operator<<(const std::string& s) { buf_ += s; return *this; }
    MinimalStream& operator<<(const char* s) { buf_ += s; return *this; }
    MinimalStream& operator<<(char c) { buf_ += c; return *this; }
    MinimalStream& operator<<(int32_t i) { buf_ += std::to_string(i); return *this; }
    MinimalStream& operator<<(int64_t i) { buf_ += std::to_string(i); return *this; }
    MinimalStream& operator<<(uint32_t i) { buf_ += std::to_string(i); return *this; }
    MinimalStream& operator<<(uint64_t i) { buf_ += std::to_string(i); return *this; }
    MinimalStream& operator<<(double d) {
        char tmp[64];
        std::snprintf(tmp, sizeof(tmp), "%g", d);
        buf_ += tmp;
        return *this;
    }
    MinimalStream& operator<<(bool b) { buf_ += (b ? "true" : "false"); return *this; }
    const std::string& str() const { return buf_; }
};

int main() {
    std::cout << "Testing private_optional + template_streamop combined..." << std::endl;

    // Compile-time: optional field 'aa' in StructB must be private
    static_assert(!has_public_aa::value,
                  "Optional field 'aa' in StructB should be private with private_optional");
    std::cout << "  ✓ Compile-time: optional field 'aa' is private in StructB" << std::endl;

    // Compile-time: required field 'ab' in StructB must remain public
    static_assert(has_public_ab::value,
                  "Required field 'ab' in StructB should remain public");
    std::cout << "  ✓ Compile-time: required field 'ab' is public in StructB" << std::endl;

    // Test 1: private_optional getters/setters work
    {
        Xtruct x;
        x.__set_string_thing("hello");
        x.__set_i32_thing(42);
        assert(x.__get_string_thing() == "hello");
        assert(x.__get_i32_thing() == 42);
        std::cout << "  ✓ private_optional getters/setters work on Xtruct" << std::endl;
    }

    // Test 2: template_streamop with std::ostringstream
    {
        Xtruct x;
        x.__set_string_thing("stream test");
        x.__set_i32_thing(99);

        std::ostringstream oss;
        oss << x;
        std::string result = oss.str();

        assert(!result.empty());
        assert(result.find("stream test") != std::string::npos);
        assert(result.find("99") != std::string::npos);
        std::cout << "  ✓ template_streamop works with std::ostringstream" << std::endl;
    }

    // Test 3: template_streamop with custom MinimalStream
    {
        Xtruct x;
        x.__set_string_thing("minimal stream");
        x.__set_i32_thing(7);

        MinimalStream ms;
        ms << x;
        std::string result = ms.str();

        assert(!result.empty());
        assert(result.find("minimal stream") != std::string::npos);
        assert(result.find("7") != std::string::npos);
        std::cout << "  ✓ template_streamop works with custom MinimalStream" << std::endl;
    }

    // Test 4: Stream a struct whose optional fields were set via setters (combines both options)
    {
        StructB sb;
        StructA sa;
        sa.__set_s("optional value");

        // private_optional: must use setter, not direct assignment
        sb.__set_aa(sa);
        // required field: direct access is still fine
        sb.ab = sa;

        // template_streamop: stream the struct to both stream types
        std::ostringstream oss;
        oss << sb;
        std::string oss_result = oss.str();

        MinimalStream ms;
        ms << sb;
        std::string ms_result = ms.str();

        assert(!oss_result.empty());
        assert(!ms_result.empty());
        assert(oss_result.find("optional value") != std::string::npos);
        assert(ms_result.find("optional value") != std::string::npos);
        std::cout << "  ✓ Combined: StructB with private optional fields streams correctly" << std::endl;
    }

    // Test 5: to_string works with combined options
    {
        Xtruct x;
        x.__set_string_thing("to_string test");
        x.__set_i32_thing(123);

        std::string s = apache::thrift::to_string(x);
        assert(!s.empty());
        assert(s.find("to_string test") != std::string::npos);
        std::cout << "  ✓ to_string works with combined options" << std::endl;
    }

    std::cout << "\n✅ All private_optional + template_streamop combined tests passed!" << std::endl;
    return 0;
}
thrift-0.23.0/test/cpp/src/SpecificNameTest.cpp0000664000175000017500000000200715165535636021616 0ustar00buildbuild00000000000000/*
 * 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.
 */

int main(int argc, char** argv) {
  
  //Empty in main function, 
  //because we just want to test  
  //whether the generated source code
  //(IDL file contains struct named as
  //'a' or 'b') can be compiled.

  return 0;
}
thrift-0.23.0/test/cpp/src/StressTestNonBlocking.cpp0000664000175000017500000003673615165535636022717 0ustar00buildbuild00000000000000/*
 * 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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "Service.h"

#include 
#include 
#include 
#include 
#include 
#if _WIN32
#include 
#endif

using namespace std;

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using namespace apache::thrift::concurrency;

using namespace test::stress;

struct eqstr {
  bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) == 0; }
};

struct ltstr {
  bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; }
};

// typedef hash_map, eqstr> count_map;
typedef map count_map;

class Server : public ServiceIf {
public:
  Server() = default;

  void count(const char* method) {
    Guard m(lock_);
    int ct = counts_[method];
    counts_[method] = ++ct;
  }

  void echoVoid() override {
    count("echoVoid");
    // Sleep to simulate work
    THRIFT_SLEEP_USEC(1);
    return;
  }

  count_map getCount() {
    Guard m(lock_);
    return counts_;
  }

  int8_t echoByte(const int8_t arg) override { return arg; }
  int32_t echoI32(const int32_t arg) override { return arg; }
  int64_t echoI64(const int64_t arg) override { return arg; }
  void echoString(string& out, const string& arg) override {
    if (arg != "hello") {
      T_ERROR_ABORT("WRONG STRING (%s)!!!!", arg.c_str());
    }
    out = arg;
  }
  void echoList(vector& out, const vector& arg) override { out = arg; }
  void echoSet(set& out, const set& arg) override { out = arg; }
  void echoMap(map& out, const map& arg) override { out = arg; }

private:
  count_map counts_;
  Mutex lock_;
};

class ClientThread : public Runnable {
public:
  ClientThread(std::shared_ptr transport,
               std::shared_ptr client,
               Monitor& monitor,
               size_t& workerCount,
               size_t loopCount,
               TType loopType)
    : _transport(transport),
      _client(client),
      _monitor(monitor),
      _workerCount(workerCount),
      _loopCount(loopCount),
      _loopType(loopType) {}

  void run() override {

    // Wait for all worker threads to start

    {
      Synchronized s(_monitor);
      while (_workerCount == 0) {
        _monitor.wait();
      }
    }

    _startTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();

    _transport->open();

    switch (_loopType) {
    case T_VOID:
      loopEchoVoid();
      break;
    case T_BYTE:
      loopEchoByte();
      break;
    case T_I32:
      loopEchoI32();
      break;
    case T_I64:
      loopEchoI64();
      break;
    case T_STRING:
      loopEchoString();
      break;
    default:
      cerr << "Unexpected loop type" << _loopType << '\n';
      break;
    }

    _endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();

    _transport->close();

    _done = true;

    {
      Synchronized s(_monitor);

      _workerCount--;

      if (_workerCount == 0) {

        _monitor.notify();
      }
    }
  }

  void loopEchoVoid() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      _client->echoVoid();
    }
  }

  void loopEchoByte() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      int8_t arg = 1;
      int8_t result;
      result = _client->echoByte(arg);
      (void)result;
      assert(result == arg);
    }
  }

  void loopEchoI32() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      int32_t arg = 1;
      int32_t result;
      result = _client->echoI32(arg);
      (void)result;
      assert(result == arg);
    }
  }

  void loopEchoI64() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      int64_t arg = 1;
      int64_t result;
      result = _client->echoI64(arg);
      (void)result;
      assert(result == arg);
    }
  }

  void loopEchoString() {
    for (size_t ix = 0; ix < _loopCount; ix++) {
      string arg = "hello";
      string result;
      _client->echoString(result, arg);
      assert(result == arg);
    }
  }

  std::shared_ptr _transport;
  std::shared_ptr _client;
  Monitor& _monitor;
  size_t& _workerCount;
  size_t _loopCount;
  TType _loopType;
  int64_t _startTime;
  int64_t _endTime;
  bool _done;
  Monitor _sleep;
};

int main(int argc, char** argv) {
#if _WIN32
  transport::TWinsockSingleton::create();
#endif

  int port = 9091;
  string serverType = "simple";
  string protocolType = "binary";
  uint32_t workerCount = 4;
  uint32_t clientCount = 20;
  uint32_t loopCount = 1000;
  TType loopType = T_VOID;
  string callName = "echoVoid";
  bool runServer = true;
  bool logRequests = false;
  string requestLogPath = "./requestlog.tlog";
  bool replayRequests = false;

  ostringstream usage;

  usage << argv[0] << " [--port=] [--server] [--server-type=] "
                      "[--protocol-type=] [--workers=] "
                      "[--clients=] [--loop=]" << '\n'
        << "\tclients        Number of client threads to create - 0 implies no clients, i.e. "
                            "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;

  for (int ix = 1; ix < argc; ix++) {

    string arg(argv[ix]);

    if (arg.compare(0, 2, "--") == 0) {

      size_t end = arg.find_first_of("=", 2);

      string key = string(arg, 2, end - 2);

      if (end != string::npos) {
        args[key] = string(arg, end + 1);
      } else {
        args[key] = "true";
      }
    } else {
      throw invalid_argument("Unexcepted command line token: " + arg);
    }
  }

  try {

    if (!args["clients"].empty()) {
      clientCount = atoi(args["clients"].c_str());
    }

    if (!args["help"].empty()) {
      cerr << usage.str();
      return 0;
    }

    if (!args["loop"].empty()) {
      loopCount = atoi(args["loop"].c_str());
    }

    if (!args["call"].empty()) {
      callName = args["call"];
    }

    if (!args["port"].empty()) {
      port = atoi(args["port"].c_str());
    }

    if (!args["server"].empty()) {
      runServer = args["server"] == "true";
    }

    if (!args["log-request"].empty()) {
      logRequests = args["log-request"] == "true";
    }

    if (!args["replay-request"].empty()) {
      replayRequests = args["replay-request"] == "true";
    }

    if (!args["server-type"].empty()) {
      serverType = args["server-type"];
    }

    if (!args["workers"].empty()) {
      workerCount = atoi(args["workers"].c_str());
    }

  } catch (std::exception& e) {
    cerr << e.what() << '\n';
    cerr << usage.str();
  }

  std::shared_ptr threadFactory
      = std::shared_ptr(new ThreadFactory());

  // Dispatcher
  std::shared_ptr serviceHandler(new Server());

  if (replayRequests) {
    std::shared_ptr serviceHandler(new Server());
    std::shared_ptr serviceProcessor(new ServiceProcessor(serviceHandler));

    // Transports
    std::shared_ptr fileTransport(new TFileTransport(requestLogPath));
    fileTransport->setChunkSize(2 * 1024 * 1024);
    fileTransport->setMaxEventSize(1024 * 16);
    fileTransport->seekToEnd();

    // Protocol Factory
    std::shared_ptr protocolFactory(new TBinaryProtocolFactory());

    TFileProcessor fileProcessor(serviceProcessor, protocolFactory, fileTransport);

    fileProcessor.process(0, true);
    exit(0);
  }

  if (runServer) {

    std::shared_ptr serviceProcessor(new ServiceProcessor(serviceHandler));

    // Protocol Factory
    std::shared_ptr protocolFactory(new TBinaryProtocolFactory());

    // Transport Factory
    std::shared_ptr transportFactory;

    if (logRequests) {
      // initialize the log file
      std::shared_ptr fileTransport(new TFileTransport(requestLogPath));
      fileTransport->setChunkSize(2 * 1024 * 1024);
      fileTransport->setMaxEventSize(1024 * 16);

      transportFactory
          = std::shared_ptr(new TPipedTransportFactory(fileTransport));
    }

    std::shared_ptr serverThread;
    std::shared_ptr serverThread2;
    std::shared_ptr nbSocket1;
    std::shared_ptr nbSocket2;

    if (serverType == "simple") {

      nbSocket1.reset(new transport::TNonblockingServerSocket(port));
      serverThread = threadFactory->newThread(std::shared_ptr(
          new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket1)));
      nbSocket2.reset(new transport::TNonblockingServerSocket(port + 1));
      serverThread2 = threadFactory->newThread(std::shared_ptr(
          new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket2)));

    } else if (serverType == "thread-pool") {

      std::shared_ptr threadManager
          = ThreadManager::newSimpleThreadManager(workerCount);

      threadManager->threadFactory(threadFactory);
      threadManager->start();
      nbSocket1.reset(new transport::TNonblockingServerSocket(port));
      serverThread = threadFactory->newThread(std::shared_ptr(
          new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket1, threadManager)));
      nbSocket2.reset(new transport::TNonblockingServerSocket(port + 1));
      serverThread2 = threadFactory->newThread(std::shared_ptr(
          new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket2, threadManager)));
    }

    cerr << "Starting the server on port " << port << " and " << (port + 1) << '\n';
    serverThread->start();
    serverThread2->start();

    // If we aren't running clients, just wait forever for external clients

    if (clientCount == 0) {
      serverThread->join();
      serverThread2->join();
    }
  }
  THRIFT_SLEEP_SEC(1);

  if (clientCount > 0) {

    Monitor monitor;

    size_t threadCount = 0;

    set > clientThreads;

    if (callName == "echoVoid") {
      loopType = T_VOID;
    } else if (callName == "echoByte") {
      loopType = T_BYTE;
    } else if (callName == "echoI32") {
      loopType = T_I32;
    } else if (callName == "echoI64") {
      loopType = T_I64;
    } else if (callName == "echoString") {
      loopType = T_STRING;
    } else {
      throw invalid_argument("Unknown service call " + callName);
    }

    for (uint32_t ix = 0; ix < clientCount; ix++) {

      std::shared_ptr socket(new TSocket("127.0.0.1", port + (ix % 2)));
      std::shared_ptr framedSocket(new TFramedTransport(socket));
      std::shared_ptr protocol(new TBinaryProtocol(framedSocket));
      std::shared_ptr serviceClient(new ServiceClient(protocol));

      clientThreads.insert(threadFactory->newThread(std::shared_ptr(
          new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
    }

    for (auto thread = clientThreads.begin();
         thread != clientThreads.end();
         thread++) {
      (*thread)->start();
    }

    int64_t time00;
    int64_t time01;

    {
      Synchronized s(monitor);
      threadCount = clientCount;

      cerr << "Launch " << clientCount << " client threads" << '\n';

      time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();

      monitor.notifyAll();

      while (threadCount > 0) {
        monitor.wait();
      }

      time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();
    }

    int64_t firstTime = 9223372036854775807LL;
    int64_t lastTime = 0;

    double averageTime = 0;
    int64_t minTime = 9223372036854775807LL;
    int64_t maxTime = 0;

    for (auto ix = clientThreads.begin();
         ix != clientThreads.end();
         ix++) {

      std::shared_ptr client
          = std::dynamic_pointer_cast((*ix)->runnable());

      int64_t delta = client->_endTime - client->_startTime;

      assert(delta > 0);

      if (client->_startTime < firstTime) {
        firstTime = client->_startTime;
      }

      if (client->_endTime > lastTime) {
        lastTime = client->_endTime;
      }

      if (delta < minTime) {
        minTime = delta;
      }

      if (delta > maxTime) {
        maxTime = delta;
      }

      averageTime += delta;
    }

    averageTime /= clientCount;

    cout << "workers :" << workerCount << ", client : " << clientCount << ", loops : " << loopCount
         << ", 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." << '\n';
  }

  return 0;
}
thrift-0.23.0/test/cpp/src/ForwardSetterTest.cpp0000664000175000017500000001044315167543515022063 0ustar00buildbuild00000000000000/*
 * 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.
 */

/**
 * Test file to verify that forward_setter generated code compiles and works correctly.
 * This exercises the template setters with various argument types using ThriftTest.thrift.
 */

#include 
#include 
#include 
#include 
#include 

// Include generated thrift types with forward_setter option
#include "ThriftTest_types.h"

using namespace thrift::test;

int main() {
    std::cout << "Testing forward_setter with ThriftTest types..." << std::endl;
    
    // Test 1: Test setting string fields with lvalues
    {
        Xtruct x;
        std::string str = "test string";
        x.__set_string_thing(str);  // lvalue reference
        assert(x.string_thing == "test string");
        std::cout << "  ✓ Lvalue string setter works" << std::endl;
    }
    
    // Test 2: Test setting string fields with rvalues (move semantics)
    {
        Xtruct x;
        std::string str = "moved string";
        x.__set_string_thing(std::move(str));  // rvalue reference (move)
        assert(x.string_thing == "moved string");
        // str may be empty now after move
        std::cout << "  ✓ Rvalue string setter (move) works" << std::endl;
    }
    
    // Test 3: Test setting fields with temporaries
    {
        Xtruct x;
        x.__set_string_thing(std::string("temporary string"));  // temporary
        assert(x.string_thing == "temporary string");
        std::cout << "  ✓ Temporary string setter works" << std::endl;
    }
    
    // Test 4: Test setting fields with string literals
    {
        Xtruct x;
        x.__set_string_thing("literal string");
        assert(x.string_thing == "literal string");
        std::cout << "  ✓ String literal setter works" << std::endl;
    }
    
    // Test 5: Test setting struct fields with lvalues
    {
        Xtruct2 x2;
        Xtruct x;
        x.__set_string_thing("inner struct");
        x.__set_i32_thing(42);
        x2.__set_struct_thing(x);  // lvalue struct
        assert(x2.struct_thing.string_thing == "inner struct");
        assert(x2.struct_thing.i32_thing == 42);
        std::cout << "  ✓ Lvalue struct setter works" << std::endl;
    }
    
    // Test 6: Test setting struct fields with rvalues (move semantics)
    {
        Xtruct2 x2;
        Xtruct x;
        x.__set_string_thing("moved struct");
        x.__set_i32_thing(99);
        x2.__set_struct_thing(std::move(x));  // rvalue struct (move)
        assert(x2.struct_thing.string_thing == "moved struct");
        assert(x2.struct_thing.i32_thing == 99);
        std::cout << "  ✓ Rvalue struct setter (move) works" << std::endl;
    }
    
    // Test 7: Test primitive types still use traditional setters
    {
        Xtruct x;
        x.__set_i32_thing(123);
        x.__set_i64_thing(456789);
        x.__set_byte_thing(7);
        assert(x.i32_thing == 123);
        assert(x.i64_thing == 456789);
        assert(x.byte_thing == 7);
        std::cout << "  ✓ Primitive type setters work" << std::endl;
    }
    
    // Test 8: Test map fields with forward semantics
    {
        Bonk bonk;
        bonk.__set_message("test bonk");
        bonk.__set_type(1);
        
        // Create a map
        std::map map1;
        map1["key1"] = bonk;
        
        // Note: We can't directly test map setters on ThriftTest types
        // as they don't have map fields, but the pattern is tested
        std::cout << "  ✓ Map handling works" << std::endl;
    }
    
    std::cout << "\n✅ All forward_setter tests passed!" << std::endl;
    return 0;
}
thrift-0.23.0/test/cpp/gen-cpp-templatestreamop/0000755000175000017500000000000015170007202022024 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/gen-cpp-enumclass/0000755000175000017500000000000015170007202020430 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/gen-cpp-forward/0000755000175000017500000000000015170007202020102 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/gen-cpp/0000755000175000017500000000000015170007202016440 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/CMakeLists.txt0000664000175000017500000003025115167543515017674 0ustar00buildbuild00000000000000#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

# The test executables still depend on Boost
include(BoostMacros)
REQUIRE_BOOST_HEADERS()
set(BOOST_COMPONENTS filesystem program_options random)
REQUIRE_BOOST_LIBRARIES(BOOST_COMPONENTS)

# Contains the thrift specific target_link_libraries
include(ThriftMacros)

find_package(OpenSSL REQUIRED)
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")

find_package(Libevent REQUIRED)  # Libevent comes with CMake support from upstream
include_directories(SYSTEM ${LIBEVENT_INCLUDE_DIRS})

find_package(ZLIB REQUIRED)
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})

#Make sure gen-cpp files can be included
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp")
include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")

set(crosstestgencpp_SOURCES
    gen-cpp/SecondService.cpp
    gen-cpp/ThriftTest.cpp
    gen-cpp/ThriftTest_types.cpp
    gen-cpp/ThriftTest_constants.cpp
    src/ThriftTest_extras.cpp
)
add_library(crosstestgencpp STATIC ${crosstestgencpp_SOURCES})
target_link_libraries(crosstestgencpp thrift)

set(crossstressgencpp_SOURCES
    gen-cpp/Service.cpp
)
add_library(crossstressgencpp STATIC ${crossstressgencpp_SOURCES})
target_link_libraries(crossstressgencpp thrift)

set(crossspecificnamegencpp_SOURCES
    gen-cpp/EchoService.cpp
    gen-cpp/SpecificNameTest_types.cpp
)
add_library(crossspecificnamegencpp STATIC ${crossspecificnamegencpp_SOURCES})
target_link_libraries(crossspecificnamegencpp thrift)

add_executable(TestServer src/TestServer.cpp)
target_link_libraries(TestServer crosstestgencpp ${Boost_LIBRARIES})
target_link_libraries(TestServer thriftnb)
target_link_libraries(TestServer thriftz)

add_executable(TestClient src/TestClient.cpp)
target_link_libraries(TestClient crosstestgencpp ${Boost_LIBRARIES})
target_link_libraries(TestClient thriftnb)
target_link_libraries(TestClient thriftz)

add_executable(StressTest src/StressTest.cpp)
target_link_libraries(StressTest crossstressgencpp ${Boost_LIBRARIES})
target_link_libraries(StressTest thriftnb)
add_test(NAME StressTest COMMAND StressTest)
add_test(NAME StressTestConcurrent COMMAND StressTest --client-type=concurrent)

# As of https://jira.apache.org/jira/browse/THRIFT-4282, StressTestNonBlocking
# is broken on Windows. Contributions welcome.
if (NOT WIN32 AND NOT CYGWIN)
    add_executable(StressTestNonBlocking src/StressTestNonBlocking.cpp)
    target_link_libraries(StressTestNonBlocking crossstressgencpp ${Boost_LIBRARIES})
    target_link_libraries(StressTestNonBlocking thriftnb)
    target_link_libraries(StressTestNonBlocking thriftz)
    add_test(NAME StressTestNonBlocking COMMAND StressTestNonBlocking)
endif()

add_executable(SpecificNameTest src/SpecificNameTest.cpp)
target_link_libraries(SpecificNameTest crossspecificnamegencpp ${Boost_LIBRARIES} ${LIBEVENT_LIB})
target_link_libraries(SpecificNameTest thrift)
target_link_libraries(SpecificNameTest thriftnb)
add_test(NAME SpecificNameTest COMMAND SpecificNameTest)

# ForwardSetterTest - tests the forward_setter option
set(forwardsettertestgencpp_SOURCES
    gen-cpp-forward/gen-cpp/ThriftTest_types.cpp
    gen-cpp-forward/gen-cpp/ThriftTest_constants.cpp
    src/ThriftTest_extras.cpp
)
add_library(forwardsettertestgencpp STATIC ${forwardsettertestgencpp_SOURCES})
target_include_directories(forwardsettertestgencpp BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward"
    "${CMAKE_CURRENT_BINARY_DIR}"
    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
)
target_link_libraries(forwardsettertestgencpp thrift)

add_executable(ForwardSetterTest src/ForwardSetterTest.cpp)
target_include_directories(ForwardSetterTest BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward/gen-cpp"
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward"
)
target_link_libraries(ForwardSetterTest forwardsettertestgencpp ${Boost_LIBRARIES})
target_link_libraries(ForwardSetterTest thrift)
add_test(NAME ForwardSetterTest COMMAND ForwardSetterTest)

# PrivateOptionalTest - tests the private_optional option
set(privateoptonaltestgencpp_SOURCES
    gen-cpp-private/gen-cpp/ThriftTest_types.cpp
    gen-cpp-private/gen-cpp/ThriftTest_constants.cpp
    src/ThriftTest_extras.cpp
)
add_library(privateoptonaltestgencpp STATIC ${privateoptonaltestgencpp_SOURCES})
target_include_directories(privateoptonaltestgencpp BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private"
    "${CMAKE_CURRENT_BINARY_DIR}"
    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
)
target_link_libraries(privateoptonaltestgencpp thrift)

add_executable(PrivateOptionalTest src/PrivateOptionalTest.cpp)
target_include_directories(PrivateOptionalTest BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private/gen-cpp"
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private"
)
target_link_libraries(PrivateOptionalTest privateoptonaltestgencpp ${Boost_LIBRARIES})
target_link_libraries(PrivateOptionalTest thrift)
add_test(NAME PrivateOptionalTest COMMAND PrivateOptionalTest)

# EnumClassTest - tests the pure_enums=enum_class option
set(enumclasstestgencpp_SOURCES
    gen-cpp-enumclass/gen-cpp/ThriftTest_types.cpp
    gen-cpp-enumclass/gen-cpp/ThriftTest_constants.cpp
    src/ThriftTest_extras.cpp
)
add_library(enumclasstestgencpp STATIC ${enumclasstestgencpp_SOURCES})
target_include_directories(enumclasstestgencpp BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass"
    "${CMAKE_CURRENT_BINARY_DIR}"
    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
)
target_link_libraries(enumclasstestgencpp thrift)

add_executable(EnumClassTest src/EnumClassTest.cpp)
target_include_directories(EnumClassTest BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass/gen-cpp"
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass"
)
target_link_libraries(EnumClassTest enumclasstestgencpp ${Boost_LIBRARIES})
target_link_libraries(EnumClassTest thrift)
add_test(NAME EnumClassTest COMMAND EnumClassTest)

# TemplateStreamOpTest - tests the template_streamop option
set(templatestreamoptestgencpp_SOURCES
    gen-cpp-templatestreamop/gen-cpp/ThriftTest_types.cpp
    gen-cpp-templatestreamop/gen-cpp/ThriftTest_constants.cpp
    src/ThriftTest_extras.cpp
)
add_library(templatestreamoptestgencpp STATIC ${templatestreamoptestgencpp_SOURCES})
target_include_directories(templatestreamoptestgencpp BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-templatestreamop"
    "${CMAKE_CURRENT_BINARY_DIR}"
    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
)
target_link_libraries(templatestreamoptestgencpp thrift)

add_executable(TemplateStreamOpTest src/TemplateStreamOpTest.cpp)
target_include_directories(TemplateStreamOpTest BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-templatestreamop/gen-cpp"
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-templatestreamop"
)
target_link_libraries(TemplateStreamOpTest templatestreamoptestgencpp ${Boost_LIBRARIES})
target_link_libraries(TemplateStreamOpTest thrift)
add_test(NAME TemplateStreamOpTest COMMAND TemplateStreamOpTest)

# PrivateOptionalTemplateStreamOpTest - tests private_optional and template_streamop together
set(privateopttemplstreamoptestgencpp_SOURCES
    gen-cpp-private-templatestreamop/gen-cpp/ThriftTest_types.cpp
    gen-cpp-private-templatestreamop/gen-cpp/ThriftTest_constants.cpp
    src/ThriftTest_extras.cpp
)
add_library(privateopttemplstreamoptestgencpp STATIC ${privateopttemplstreamoptestgencpp_SOURCES})
target_include_directories(privateopttemplstreamoptestgencpp BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private-templatestreamop"
    "${CMAKE_CURRENT_BINARY_DIR}"
    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
)
target_link_libraries(privateopttemplstreamoptestgencpp thrift)

add_executable(PrivateOptionalTemplateStreamOpTest src/PrivateOptionalTemplateStreamOpTest.cpp)
target_include_directories(PrivateOptionalTemplateStreamOpTest BEFORE PRIVATE 
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private-templatestreamop/gen-cpp"
    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private-templatestreamop"
)
target_link_libraries(PrivateOptionalTemplateStreamOpTest privateopttemplstreamoptestgencpp ${Boost_LIBRARIES})
target_link_libraries(PrivateOptionalTemplateStreamOpTest thrift)
add_test(NAME PrivateOptionalTemplateStreamOpTest COMMAND PrivateOptionalTemplateStreamOpTest)

#
# Common thrift code generation rules
#

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/ThriftTest.thrift
)

# Generate ThriftTest with forward_setter option for ForwardSetterTest
add_custom_command(OUTPUT gen-cpp-forward/gen-cpp/ThriftTest_types.cpp gen-cpp-forward/gen-cpp/ThriftTest_types.h gen-cpp-forward/gen-cpp/ThriftTest_types.tcc gen-cpp-forward/gen-cpp/ThriftTest_constants.cpp
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward
    COMMAND ${THRIFT_COMPILER} --gen cpp:moveable_types=forward_setter -o gen-cpp-forward ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# Generate ThriftTest with private_optional option for PrivateOptionalTest
add_custom_command(OUTPUT gen-cpp-private/gen-cpp/ThriftTest_types.cpp gen-cpp-private/gen-cpp/ThriftTest_types.h gen-cpp-private/gen-cpp/ThriftTest_constants.cpp
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private
    COMMAND ${THRIFT_COMPILER} --gen cpp:private_optional -o gen-cpp-private ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# Generate ThriftTest with pure_enums=enum_class option for EnumClassTest
add_custom_command(OUTPUT gen-cpp-enumclass/gen-cpp/ThriftTest_types.cpp gen-cpp-enumclass/gen-cpp/ThriftTest_types.h gen-cpp-enumclass/gen-cpp/ThriftTest_constants.cpp
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass
    COMMAND ${THRIFT_COMPILER} --gen cpp:pure_enums=enum_class -o gen-cpp-enumclass ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# Generate ThriftTest with template_streamop option for TemplateStreamOpTest
add_custom_command(OUTPUT gen-cpp-templatestreamop/gen-cpp/ThriftTest_types.cpp gen-cpp-templatestreamop/gen-cpp/ThriftTest_types.h gen-cpp-templatestreamop/gen-cpp/ThriftTest_constants.cpp
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-templatestreamop
    COMMAND ${THRIFT_COMPILER} --gen cpp:template_streamop -o gen-cpp-templatestreamop ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# Generate ThriftTest with private_optional,template_streamop options for PrivateOptionalTemplateStreamOpTest
add_custom_command(OUTPUT gen-cpp-private-templatestreamop/gen-cpp/ThriftTest_types.cpp gen-cpp-private-templatestreamop/gen-cpp/ThriftTest_types.h gen-cpp-private-templatestreamop/gen-cpp/ThriftTest_constants.cpp
    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private-templatestreamop
    COMMAND ${THRIFT_COMPILER} --gen cpp:private_optional,template_streamop -o gen-cpp-private-templatestreamop ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

add_custom_command(OUTPUT gen-cpp/Service.cpp
    COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/StressTest.thrift
)

add_custom_command(OUTPUT gen-cpp/EchoService.cpp gen-cpp/SpecificNameTest_types.cpp
    COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/SpecificNameTest.thrift
)
thrift-0.23.0/test/cpp/gen-cpp-private-templatestreamop/0000755000175000017500000000000015170007202023474 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/Makefile0000644000175000017500000020301515170007175016561 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/cpp/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.




am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
check_PROGRAMS = TestServer$(EXEEXT) TestClient$(EXEEXT) \
	StressTest$(EXEEXT) StressTestNonBlocking$(EXEEXT) \
	ForwardSetterTest$(EXEEXT) PrivateOptionalTest$(EXEEXT) \
	EnumClassTest$(EXEEXT) TemplateStreamOpTest$(EXEEXT) \
	PrivateOptionalTemplateStreamOpTest$(EXEEXT)
subdir = test/cpp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libenumclasstestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
am__dirstamp = $(am__leading_dot)dirstamp
nodist_libenumclasstestgencpp_la_OBJECTS =  \
	gen-cpp-enumclass/ThriftTest_types.lo \
	gen-cpp-enumclass/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libenumclasstestgencpp_la_OBJECTS =  \
	$(nodist_libenumclasstestgencpp_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
am__v_lt_1 = 
libforwardsettertestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libforwardsettertestgencpp_la_OBJECTS =  \
	gen-cpp-forward/ThriftTest_types.lo \
	gen-cpp-forward/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libforwardsettertestgencpp_la_OBJECTS =  \
	$(nodist_libforwardsettertestgencpp_la_OBJECTS)
libprivateoptonaltestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateoptonaltestgencpp_la_OBJECTS =  \
	gen-cpp-private/ThriftTest_types.lo \
	gen-cpp-private/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libprivateoptonaltestgencpp_la_OBJECTS =  \
	$(nodist_libprivateoptonaltestgencpp_la_OBJECTS)
libprivateopttemplstreamoptestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateopttemplstreamoptestgencpp_la_OBJECTS =  \
	gen-cpp-private-templatestreamop/ThriftTest_types.lo \
	gen-cpp-private-templatestreamop/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libprivateopttemplstreamoptestgencpp_la_OBJECTS =  \
	$(nodist_libprivateopttemplstreamoptestgencpp_la_OBJECTS)
libstresstestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libstresstestgencpp_la_OBJECTS = gen-cpp/Service.lo
libstresstestgencpp_la_OBJECTS =  \
	$(nodist_libstresstestgencpp_la_OBJECTS)
libtemplatestreamoptestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libtemplatestreamoptestgencpp_la_OBJECTS =  \
	gen-cpp-templatestreamop/ThriftTest_types.lo \
	gen-cpp-templatestreamop/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libtemplatestreamoptestgencpp_la_OBJECTS =  \
	$(nodist_libtemplatestreamoptestgencpp_la_OBJECTS)
libtestgencpp_la_DEPENDENCIES = $(top_builddir)/lib/cpp/libthrift.la
nodist_libtestgencpp_la_OBJECTS = gen-cpp/SecondService.lo \
	gen-cpp/ThriftTest_constants.lo gen-cpp/ThriftTest_types.lo \
	gen-cpp/ThriftTest.lo src/ThriftTest_extras.lo
libtestgencpp_la_OBJECTS = $(nodist_libtestgencpp_la_OBJECTS)
am_EnumClassTest_OBJECTS = src/EnumClassTest-EnumClassTest.$(OBJEXT)
EnumClassTest_OBJECTS = $(am_EnumClassTest_OBJECTS)
EnumClassTest_DEPENDENCIES = libenumclasstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_ForwardSetterTest_OBJECTS =  \
	src/ForwardSetterTest-ForwardSetterTest.$(OBJEXT)
ForwardSetterTest_OBJECTS = $(am_ForwardSetterTest_OBJECTS)
ForwardSetterTest_DEPENDENCIES = libforwardsettertestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_PrivateOptionalTemplateStreamOpTest_OBJECTS = src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.$(OBJEXT)
PrivateOptionalTemplateStreamOpTest_OBJECTS =  \
	$(am_PrivateOptionalTemplateStreamOpTest_OBJECTS)
PrivateOptionalTemplateStreamOpTest_DEPENDENCIES =  \
	libprivateopttemplstreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_PrivateOptionalTest_OBJECTS =  \
	src/PrivateOptionalTest-PrivateOptionalTest.$(OBJEXT)
PrivateOptionalTest_OBJECTS = $(am_PrivateOptionalTest_OBJECTS)
PrivateOptionalTest_DEPENDENCIES = libprivateoptonaltestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_StressTest_OBJECTS = src/StressTest.$(OBJEXT)
StressTest_OBJECTS = $(am_StressTest_OBJECTS)
StressTest_DEPENDENCIES = libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_StressTestNonBlocking_OBJECTS =  \
	src/StressTestNonBlocking.$(OBJEXT)
StressTestNonBlocking_OBJECTS = $(am_StressTestNonBlocking_OBJECTS)
StressTestNonBlocking_DEPENDENCIES = libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthriftnb.la
am_TemplateStreamOpTest_OBJECTS =  \
	src/TemplateStreamOpTest-TemplateStreamOpTest.$(OBJEXT)
TemplateStreamOpTest_OBJECTS = $(am_TemplateStreamOpTest_OBJECTS)
TemplateStreamOpTest_DEPENDENCIES = libtemplatestreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_TestClient_OBJECTS = src/TestClient.$(OBJEXT)
TestClient_OBJECTS = $(am_TestClient_OBJECTS)
am__DEPENDENCIES_1 =
TestClient_DEPENDENCIES = libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la $(am__DEPENDENCIES_1)
am_TestServer_OBJECTS = src/TestServer.$(OBJEXT)
TestServer_OBJECTS = $(am_TestServer_OBJECTS)
TestServer_DEPENDENCIES = libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la $(am__DEPENDENCIES_1)
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = 
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade =  \
	gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp/$(DEPDIR)/SecondService.Plo \
	gen-cpp/$(DEPDIR)/Service.Plo gen-cpp/$(DEPDIR)/ThriftTest.Plo \
	gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp/$(DEPDIR)/ThriftTest_types.Plo \
	src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po \
	src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po \
	src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po \
	src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po \
	src/$(DEPDIR)/StressTest.Po \
	src/$(DEPDIR)/StressTestNonBlocking.Po \
	src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po \
	src/$(DEPDIR)/TestClient.Po src/$(DEPDIR)/TestServer.Po \
	src/$(DEPDIR)/ThriftTest_extras.Plo
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_$(V))
am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
am__v_CXX_0 = @echo "  CXX     " $@;
am__v_CXX_1 = 
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_$(V))
am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
am__v_CXXLD_0 = @echo "  CXXLD   " $@;
am__v_CXXLD_1 = 
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_$(V))
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
am__v_CC_0 = @echo "  CC      " $@;
am__v_CC_1 = 
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_$(V))
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = $(nodist_libenumclasstestgencpp_la_SOURCES) \
	$(nodist_libforwardsettertestgencpp_la_SOURCES) \
	$(nodist_libprivateoptonaltestgencpp_la_SOURCES) \
	$(nodist_libprivateopttemplstreamoptestgencpp_la_SOURCES) \
	$(nodist_libstresstestgencpp_la_SOURCES) \
	$(nodist_libtemplatestreamoptestgencpp_la_SOURCES) \
	$(nodist_libtestgencpp_la_SOURCES) $(EnumClassTest_SOURCES) \
	$(ForwardSetterTest_SOURCES) \
	$(PrivateOptionalTemplateStreamOpTest_SOURCES) \
	$(PrivateOptionalTest_SOURCES) $(StressTest_SOURCES) \
	$(StressTestNonBlocking_SOURCES) \
	$(TemplateStreamOpTest_SOURCES) $(TestClient_SOURCES) \
	$(TestServer_SOURCES)
DIST_SOURCES = $(EnumClassTest_SOURCES) $(ForwardSetterTest_SOURCES) \
	$(PrivateOptionalTemplateStreamOpTest_SOURCES) \
	$(PrivateOptionalTest_SOURCES) $(StressTest_SOURCES) \
	$(StressTestNonBlocking_SOURCES) \
	$(TemplateStreamOpTest_SOURCES) $(TestClient_SOURCES) \
	$(TestServer_SOURCES)
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates.  Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
  BEGIN { nonempty = 0; } \
  { items[$$0] = 1; nonempty = 1; } \
  END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique.  This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
  list='$(am__tagged_files)'; \
  unique=`for i in $$list; do \
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  done | $(am__uniquify_input)`
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = /thrift/src/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/cpp
abs_srcdir = /thrift/src/test/cpp
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..

#
# 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.
#
AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
BUILT_SOURCES = gen-cpp/ThriftTest.cpp \
                gen-cpp/ThriftTest_types.cpp \
                gen-cpp/ThriftTest_constants.cpp \
                gen-cpp/SecondService.cpp \
                gen-cpp/Service.cpp \
                gen-cpp-forward/ThriftTest_types.cpp \
                gen-cpp-forward/ThriftTest_constants.cpp \
                gen-cpp-private/ThriftTest_types.cpp \
                gen-cpp-private/ThriftTest_constants.cpp \
                gen-cpp-enumclass/ThriftTest_types.cpp \
                gen-cpp-enumclass/ThriftTest_constants.cpp \
                gen-cpp-templatestreamop/ThriftTest_types.cpp \
                gen-cpp-templatestreamop/ThriftTest_types.tcc \
                gen-cpp-templatestreamop/ThriftTest_constants.cpp \
                gen-cpp-private-templatestreamop/ThriftTest_types.cpp \
                gen-cpp-private-templatestreamop/ThriftTest_types.tcc \
                gen-cpp-private-templatestreamop/ThriftTest_constants.cpp


# Libraries for option-specific tests
noinst_LTLIBRARIES = libtestgencpp.la libstresstestgencpp.la \
	libforwardsettertestgencpp.la libprivateoptonaltestgencpp.la \
	libenumclasstestgencpp.la libtemplatestreamoptestgencpp.la \
	libprivateopttemplstreamoptestgencpp.la
nodist_libtestgencpp_la_SOURCES = \
	gen-cpp/SecondService.cpp \
	gen-cpp/SecondService.h \
	gen-cpp/SecondService.tcc \
	gen-cpp/ThriftTest_constants.cpp \
	gen-cpp/ThriftTest_constants.h \
	gen-cpp/ThriftTest_types.cpp \
	gen-cpp/ThriftTest_types.h \
	gen-cpp/ThriftTest_types.tcc \
	gen-cpp/ThriftTest.cpp \
	gen-cpp/ThriftTest.h \
	gen-cpp/ThriftTest.tcc \
	src/ThriftTest_extras.cpp

libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libforwardsettertestgencpp_la_SOURCES = \
	gen-cpp-forward/ThriftTest_types.cpp \
	gen-cpp-forward/ThriftTest_types.h \
	gen-cpp-forward/ThriftTest_types.tcc \
	gen-cpp-forward/ThriftTest_constants.cpp \
	gen-cpp-forward/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libforwardsettertestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateoptonaltestgencpp_la_SOURCES = \
	gen-cpp-private/ThriftTest_types.cpp \
	gen-cpp-private/ThriftTest_types.h \
	gen-cpp-private/ThriftTest_constants.cpp \
	gen-cpp-private/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libprivateoptonaltestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libenumclasstestgencpp_la_SOURCES = \
	gen-cpp-enumclass/ThriftTest_types.cpp \
	gen-cpp-enumclass/ThriftTest_types.h \
	gen-cpp-enumclass/ThriftTest_constants.cpp \
	gen-cpp-enumclass/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libenumclasstestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libtemplatestreamoptestgencpp_la_SOURCES = \
	gen-cpp-templatestreamop/ThriftTest_types.cpp \
	gen-cpp-templatestreamop/ThriftTest_types.h \
	gen-cpp-templatestreamop/ThriftTest_types.tcc \
	gen-cpp-templatestreamop/ThriftTest_constants.cpp \
	gen-cpp-templatestreamop/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libtemplatestreamoptestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateopttemplstreamoptestgencpp_la_SOURCES = \
	gen-cpp-private-templatestreamop/ThriftTest_types.cpp \
	gen-cpp-private-templatestreamop/ThriftTest_types.h \
	gen-cpp-private-templatestreamop/ThriftTest_types.tcc \
	gen-cpp-private-templatestreamop/ThriftTest_constants.cpp \
	gen-cpp-private-templatestreamop/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libprivateopttemplstreamoptestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libstresstestgencpp_la_SOURCES = \
	gen-cpp/StressTest_types.h \
	gen-cpp/Service.cpp \
	gen-cpp/Service.h

libstresstestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

# we currently do not run the testsuite, stop c++ server issue
# TESTS = \
#	$(check_PROGRAMS)
TestServer_SOURCES = \
	src/TestServer.cpp

TestServer_LDADD = \
	libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent -lboost_program_options -lboost_system -lboost_filesystem $(ZLIB_LIBS)

TestClient_SOURCES = \
	src/TestClient.cpp

TestClient_LDADD = \
	libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent -lboost_program_options -lboost_system -lboost_filesystem $(ZLIB_LIBS)

StressTest_SOURCES = \
	src/StressTest.cpp

StressTest_LDADD = \
	libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

StressTestNonBlocking_SOURCES = \
	src/StressTestNonBlocking.cpp

StressTestNonBlocking_LDADD = \
	libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent

ForwardSetterTest_SOURCES = \
	src/ForwardSetterTest.cpp

ForwardSetterTest_CPPFLAGS = -Igen-cpp-forward $(AM_CPPFLAGS)
ForwardSetterTest_LDADD = \
	libforwardsettertestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

PrivateOptionalTest_SOURCES = \
	src/PrivateOptionalTest.cpp

PrivateOptionalTest_CPPFLAGS = -Igen-cpp-private $(AM_CPPFLAGS)
PrivateOptionalTest_LDADD = \
	libprivateoptonaltestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

EnumClassTest_SOURCES = \
	src/EnumClassTest.cpp

EnumClassTest_CPPFLAGS = -Igen-cpp-enumclass $(AM_CPPFLAGS)
EnumClassTest_LDADD = \
	libenumclasstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

TemplateStreamOpTest_SOURCES = \
	src/TemplateStreamOpTest.cpp

TemplateStreamOpTest_CPPFLAGS = -Igen-cpp-templatestreamop $(AM_CPPFLAGS)
TemplateStreamOpTest_LDADD = \
	libtemplatestreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

PrivateOptionalTemplateStreamOpTest_SOURCES = \
	src/PrivateOptionalTemplateStreamOpTest.cpp

PrivateOptionalTemplateStreamOpTest_CPPFLAGS = -Igen-cpp-private-templatestreamop $(AM_CPPFLAGS)
PrivateOptionalTemplateStreamOpTest_LDADD = \
	libprivateopttemplstreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp -I.
AM_CXXFLAGS = -Wall -Wextra -pedantic -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) $(ZLIB_LIBS)
EXTRA_DIST = \
	src/TestClient.cpp \
	src/TestServer.cpp \
	src/StressTest.cpp \
	src/StressTestNonBlocking.cpp \
	src/ForwardSetterTest.cpp \
	src/PrivateOptionalTest.cpp \
	src/EnumClassTest.cpp \
	src/TemplateStreamOpTest.cpp \
	src/PrivateOptionalTemplateStreamOpTest.cpp

all: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) all-am

.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/cpp/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/cpp/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

clean-checkPROGRAMS:
	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list

clean-noinstLTLIBRARIES:
	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
	@list='$(noinst_LTLIBRARIES)'; \
	locs=`for p in $$list; do echo $$p; done | \
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
	      sort -u`; \
	test -z "$$locs" || { \
	  echo rm -f $${locs}; \
	  rm -f $${locs}; \
	}
gen-cpp-enumclass/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-enumclass
	@: > gen-cpp-enumclass/$(am__dirstamp)
gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-enumclass/$(DEPDIR)
	@: > gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
gen-cpp-enumclass/ThriftTest_types.lo:  \
	gen-cpp-enumclass/$(am__dirstamp) \
	gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
gen-cpp-enumclass/ThriftTest_constants.lo:  \
	gen-cpp-enumclass/$(am__dirstamp) \
	gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
src/$(am__dirstamp):
	@$(MKDIR_P) src
	@: > src/$(am__dirstamp)
src/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) src/$(DEPDIR)
	@: > src/$(DEPDIR)/$(am__dirstamp)
src/ThriftTest_extras.lo: src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

libenumclasstestgencpp.la: $(libenumclasstestgencpp_la_OBJECTS) $(libenumclasstestgencpp_la_DEPENDENCIES) $(EXTRA_libenumclasstestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libenumclasstestgencpp_la_OBJECTS) $(libenumclasstestgencpp_la_LIBADD) $(LIBS)
gen-cpp-forward/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-forward
	@: > gen-cpp-forward/$(am__dirstamp)
gen-cpp-forward/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-forward/$(DEPDIR)
	@: > gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)
gen-cpp-forward/ThriftTest_types.lo: gen-cpp-forward/$(am__dirstamp) \
	gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)
gen-cpp-forward/ThriftTest_constants.lo:  \
	gen-cpp-forward/$(am__dirstamp) \
	gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)

libforwardsettertestgencpp.la: $(libforwardsettertestgencpp_la_OBJECTS) $(libforwardsettertestgencpp_la_DEPENDENCIES) $(EXTRA_libforwardsettertestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libforwardsettertestgencpp_la_OBJECTS) $(libforwardsettertestgencpp_la_LIBADD) $(LIBS)
gen-cpp-private/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private
	@: > gen-cpp-private/$(am__dirstamp)
gen-cpp-private/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private/$(DEPDIR)
	@: > gen-cpp-private/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private/ThriftTest_types.lo: gen-cpp-private/$(am__dirstamp) \
	gen-cpp-private/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private/ThriftTest_constants.lo:  \
	gen-cpp-private/$(am__dirstamp) \
	gen-cpp-private/$(DEPDIR)/$(am__dirstamp)

libprivateoptonaltestgencpp.la: $(libprivateoptonaltestgencpp_la_OBJECTS) $(libprivateoptonaltestgencpp_la_DEPENDENCIES) $(EXTRA_libprivateoptonaltestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libprivateoptonaltestgencpp_la_OBJECTS) $(libprivateoptonaltestgencpp_la_LIBADD) $(LIBS)
gen-cpp-private-templatestreamop/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private-templatestreamop
	@: > gen-cpp-private-templatestreamop/$(am__dirstamp)
gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private-templatestreamop/$(DEPDIR)
	@: > gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private-templatestreamop/ThriftTest_types.lo:  \
	gen-cpp-private-templatestreamop/$(am__dirstamp) \
	gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private-templatestreamop/ThriftTest_constants.lo:  \
	gen-cpp-private-templatestreamop/$(am__dirstamp) \
	gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)

libprivateopttemplstreamoptestgencpp.la: $(libprivateopttemplstreamoptestgencpp_la_OBJECTS) $(libprivateopttemplstreamoptestgencpp_la_DEPENDENCIES) $(EXTRA_libprivateopttemplstreamoptestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libprivateopttemplstreamoptestgencpp_la_OBJECTS) $(libprivateopttemplstreamoptestgencpp_la_LIBADD) $(LIBS)
gen-cpp/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp
	@: > gen-cpp/$(am__dirstamp)
gen-cpp/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp/$(DEPDIR)
	@: > gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/Service.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)

libstresstestgencpp.la: $(libstresstestgencpp_la_OBJECTS) $(libstresstestgencpp_la_DEPENDENCIES) $(EXTRA_libstresstestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libstresstestgencpp_la_OBJECTS) $(libstresstestgencpp_la_LIBADD) $(LIBS)
gen-cpp-templatestreamop/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-templatestreamop
	@: > gen-cpp-templatestreamop/$(am__dirstamp)
gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-templatestreamop/$(DEPDIR)
	@: > gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-templatestreamop/ThriftTest_types.lo:  \
	gen-cpp-templatestreamop/$(am__dirstamp) \
	gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-templatestreamop/ThriftTest_constants.lo:  \
	gen-cpp-templatestreamop/$(am__dirstamp) \
	gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)

libtemplatestreamoptestgencpp.la: $(libtemplatestreamoptestgencpp_la_OBJECTS) $(libtemplatestreamoptestgencpp_la_DEPENDENCIES) $(EXTRA_libtemplatestreamoptestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libtemplatestreamoptestgencpp_la_OBJECTS) $(libtemplatestreamoptestgencpp_la_LIBADD) $(LIBS)
gen-cpp/SecondService.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/ThriftTest_constants.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/ThriftTest_types.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/ThriftTest.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)

libtestgencpp.la: $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_DEPENDENCIES) $(EXTRA_libtestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_LIBADD) $(LIBS)
src/EnumClassTest-EnumClassTest.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

EnumClassTest$(EXEEXT): $(EnumClassTest_OBJECTS) $(EnumClassTest_DEPENDENCIES) $(EXTRA_EnumClassTest_DEPENDENCIES) 
	@rm -f EnumClassTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(EnumClassTest_OBJECTS) $(EnumClassTest_LDADD) $(LIBS)
src/ForwardSetterTest-ForwardSetterTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

ForwardSetterTest$(EXEEXT): $(ForwardSetterTest_OBJECTS) $(ForwardSetterTest_DEPENDENCIES) $(EXTRA_ForwardSetterTest_DEPENDENCIES) 
	@rm -f ForwardSetterTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(ForwardSetterTest_OBJECTS) $(ForwardSetterTest_LDADD) $(LIBS)
src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

PrivateOptionalTemplateStreamOpTest$(EXEEXT): $(PrivateOptionalTemplateStreamOpTest_OBJECTS) $(PrivateOptionalTemplateStreamOpTest_DEPENDENCIES) $(EXTRA_PrivateOptionalTemplateStreamOpTest_DEPENDENCIES) 
	@rm -f PrivateOptionalTemplateStreamOpTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(PrivateOptionalTemplateStreamOpTest_OBJECTS) $(PrivateOptionalTemplateStreamOpTest_LDADD) $(LIBS)
src/PrivateOptionalTest-PrivateOptionalTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

PrivateOptionalTest$(EXEEXT): $(PrivateOptionalTest_OBJECTS) $(PrivateOptionalTest_DEPENDENCIES) $(EXTRA_PrivateOptionalTest_DEPENDENCIES) 
	@rm -f PrivateOptionalTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(PrivateOptionalTest_OBJECTS) $(PrivateOptionalTest_LDADD) $(LIBS)
src/StressTest.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

StressTest$(EXEEXT): $(StressTest_OBJECTS) $(StressTest_DEPENDENCIES) $(EXTRA_StressTest_DEPENDENCIES) 
	@rm -f StressTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(StressTest_OBJECTS) $(StressTest_LDADD) $(LIBS)
src/StressTestNonBlocking.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

StressTestNonBlocking$(EXEEXT): $(StressTestNonBlocking_OBJECTS) $(StressTestNonBlocking_DEPENDENCIES) $(EXTRA_StressTestNonBlocking_DEPENDENCIES) 
	@rm -f StressTestNonBlocking$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(StressTestNonBlocking_OBJECTS) $(StressTestNonBlocking_LDADD) $(LIBS)
src/TemplateStreamOpTest-TemplateStreamOpTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

TemplateStreamOpTest$(EXEEXT): $(TemplateStreamOpTest_OBJECTS) $(TemplateStreamOpTest_DEPENDENCIES) $(EXTRA_TemplateStreamOpTest_DEPENDENCIES) 
	@rm -f TemplateStreamOpTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(TemplateStreamOpTest_OBJECTS) $(TemplateStreamOpTest_LDADD) $(LIBS)
src/TestClient.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

TestClient$(EXEEXT): $(TestClient_OBJECTS) $(TestClient_DEPENDENCIES) $(EXTRA_TestClient_DEPENDENCIES) 
	@rm -f TestClient$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(TestClient_OBJECTS) $(TestClient_LDADD) $(LIBS)
src/TestServer.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

TestServer$(EXEEXT): $(TestServer_OBJECTS) $(TestServer_DEPENDENCIES) $(EXTRA_TestServer_DEPENDENCIES) 
	@rm -f TestServer$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(TestServer_OBJECTS) $(TestServer_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)
	-rm -f gen-cpp-enumclass/*.$(OBJEXT)
	-rm -f gen-cpp-enumclass/*.lo
	-rm -f gen-cpp-forward/*.$(OBJEXT)
	-rm -f gen-cpp-forward/*.lo
	-rm -f gen-cpp-private-templatestreamop/*.$(OBJEXT)
	-rm -f gen-cpp-private-templatestreamop/*.lo
	-rm -f gen-cpp-private/*.$(OBJEXT)
	-rm -f gen-cpp-private/*.lo
	-rm -f gen-cpp-templatestreamop/*.$(OBJEXT)
	-rm -f gen-cpp-templatestreamop/*.lo
	-rm -f gen-cpp/*.$(OBJEXT)
	-rm -f gen-cpp/*.lo
	-rm -f src/*.$(OBJEXT)
	-rm -f src/*.lo

distclean-compile:
	-rm -f *.tab.c

include gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo # am--include-marker
include gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo # am--include-marker
include gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo # am--include-marker
include gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo # am--include-marker
include gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo # am--include-marker
include gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo # am--include-marker
include gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo # am--include-marker
include gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo # am--include-marker
include gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo # am--include-marker
include gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo # am--include-marker
include gen-cpp/$(DEPDIR)/SecondService.Plo # am--include-marker
include gen-cpp/$(DEPDIR)/Service.Plo # am--include-marker
include gen-cpp/$(DEPDIR)/ThriftTest.Plo # am--include-marker
include gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo # am--include-marker
include gen-cpp/$(DEPDIR)/ThriftTest_types.Plo # am--include-marker
include src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po # am--include-marker
include src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po # am--include-marker
include src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po # am--include-marker
include src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po # am--include-marker
include src/$(DEPDIR)/StressTest.Po # am--include-marker
include src/$(DEPDIR)/StressTestNonBlocking.Po # am--include-marker
include src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po # am--include-marker
include src/$(DEPDIR)/TestClient.Po # am--include-marker
include src/$(DEPDIR)/TestServer.Po # am--include-marker
include src/$(DEPDIR)/ThriftTest_extras.Plo # am--include-marker

$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

.cpp.o:
	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
	$(am__mv) $$depbase.Tpo $$depbase.Po
#	$(AM_V_CXX)source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ $<

.cpp.obj:
	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
	$(am__mv) $$depbase.Tpo $$depbase.Po
#	$(AM_V_CXX)source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`

.cpp.lo:
	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
	$(am__mv) $$depbase.Tpo $$depbase.Plo
#	$(AM_V_CXX)source='$<' object='$@' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(LTCXXCOMPILE) -c -o $@ $<

src/EnumClassTest-EnumClassTest.o: src/EnumClassTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/EnumClassTest-EnumClassTest.o -MD -MP -MF src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo -c -o src/EnumClassTest-EnumClassTest.o `test -f 'src/EnumClassTest.cpp' || echo '$(srcdir)/'`src/EnumClassTest.cpp
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
#	$(AM_V_CXX)source='src/EnumClassTest.cpp' object='src/EnumClassTest-EnumClassTest.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/EnumClassTest-EnumClassTest.o `test -f 'src/EnumClassTest.cpp' || echo '$(srcdir)/'`src/EnumClassTest.cpp

src/EnumClassTest-EnumClassTest.obj: src/EnumClassTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/EnumClassTest-EnumClassTest.obj -MD -MP -MF src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo -c -o src/EnumClassTest-EnumClassTest.obj `if test -f 'src/EnumClassTest.cpp'; then $(CYGPATH_W) 'src/EnumClassTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/EnumClassTest.cpp'; fi`
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
#	$(AM_V_CXX)source='src/EnumClassTest.cpp' object='src/EnumClassTest-EnumClassTest.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/EnumClassTest-EnumClassTest.obj `if test -f 'src/EnumClassTest.cpp'; then $(CYGPATH_W) 'src/EnumClassTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/EnumClassTest.cpp'; fi`

src/ForwardSetterTest-ForwardSetterTest.o: src/ForwardSetterTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/ForwardSetterTest-ForwardSetterTest.o -MD -MP -MF src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo -c -o src/ForwardSetterTest-ForwardSetterTest.o `test -f 'src/ForwardSetterTest.cpp' || echo '$(srcdir)/'`src/ForwardSetterTest.cpp
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
#	$(AM_V_CXX)source='src/ForwardSetterTest.cpp' object='src/ForwardSetterTest-ForwardSetterTest.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/ForwardSetterTest-ForwardSetterTest.o `test -f 'src/ForwardSetterTest.cpp' || echo '$(srcdir)/'`src/ForwardSetterTest.cpp

src/ForwardSetterTest-ForwardSetterTest.obj: src/ForwardSetterTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/ForwardSetterTest-ForwardSetterTest.obj -MD -MP -MF src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo -c -o src/ForwardSetterTest-ForwardSetterTest.obj `if test -f 'src/ForwardSetterTest.cpp'; then $(CYGPATH_W) 'src/ForwardSetterTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/ForwardSetterTest.cpp'; fi`
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
#	$(AM_V_CXX)source='src/ForwardSetterTest.cpp' object='src/ForwardSetterTest-ForwardSetterTest.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/ForwardSetterTest-ForwardSetterTest.obj `if test -f 'src/ForwardSetterTest.cpp'; then $(CYGPATH_W) 'src/ForwardSetterTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/ForwardSetterTest.cpp'; fi`

src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o: src/PrivateOptionalTemplateStreamOpTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o `test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTemplateStreamOpTest.cpp
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
#	$(AM_V_CXX)source='src/PrivateOptionalTemplateStreamOpTest.cpp' object='src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o `test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTemplateStreamOpTest.cpp

src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj: src/PrivateOptionalTemplateStreamOpTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj `if test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTemplateStreamOpTest.cpp'; fi`
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
#	$(AM_V_CXX)source='src/PrivateOptionalTemplateStreamOpTest.cpp' object='src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj `if test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTemplateStreamOpTest.cpp'; fi`

src/PrivateOptionalTest-PrivateOptionalTest.o: src/PrivateOptionalTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTest-PrivateOptionalTest.o -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo -c -o src/PrivateOptionalTest-PrivateOptionalTest.o `test -f 'src/PrivateOptionalTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTest.cpp
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
#	$(AM_V_CXX)source='src/PrivateOptionalTest.cpp' object='src/PrivateOptionalTest-PrivateOptionalTest.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTest-PrivateOptionalTest.o `test -f 'src/PrivateOptionalTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTest.cpp

src/PrivateOptionalTest-PrivateOptionalTest.obj: src/PrivateOptionalTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTest-PrivateOptionalTest.obj -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo -c -o src/PrivateOptionalTest-PrivateOptionalTest.obj `if test -f 'src/PrivateOptionalTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTest.cpp'; fi`
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
#	$(AM_V_CXX)source='src/PrivateOptionalTest.cpp' object='src/PrivateOptionalTest-PrivateOptionalTest.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTest-PrivateOptionalTest.obj `if test -f 'src/PrivateOptionalTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTest.cpp'; fi`

src/TemplateStreamOpTest-TemplateStreamOpTest.o: src/TemplateStreamOpTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/TemplateStreamOpTest-TemplateStreamOpTest.o -MD -MP -MF src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.o `test -f 'src/TemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/TemplateStreamOpTest.cpp
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
#	$(AM_V_CXX)source='src/TemplateStreamOpTest.cpp' object='src/TemplateStreamOpTest-TemplateStreamOpTest.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.o `test -f 'src/TemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/TemplateStreamOpTest.cpp

src/TemplateStreamOpTest-TemplateStreamOpTest.obj: src/TemplateStreamOpTest.cpp
	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/TemplateStreamOpTest-TemplateStreamOpTest.obj -MD -MP -MF src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.obj `if test -f 'src/TemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/TemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/TemplateStreamOpTest.cpp'; fi`
	$(AM_V_at)$(am__mv) src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
#	$(AM_V_CXX)source='src/TemplateStreamOpTest.cpp' object='src/TemplateStreamOpTest-TemplateStreamOpTest.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.obj `if test -f 'src/TemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/TemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/TemplateStreamOpTest.cpp'; fi`

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
	-rm -rf gen-cpp/.libs gen-cpp/_libs
	-rm -rf gen-cpp-enumclass/.libs gen-cpp-enumclass/_libs
	-rm -rf gen-cpp-forward/.libs gen-cpp-forward/_libs
	-rm -rf gen-cpp-private/.libs gen-cpp-private/_libs
	-rm -rf gen-cpp-private-templatestreamop/.libs gen-cpp-private-templatestreamop/_libs
	-rm -rf gen-cpp-templatestreamop/.libs gen-cpp-templatestreamop/_libs
	-rm -rf src/.libs src/_libs
style-local: 

ID: $(am__tagged_files)
	$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags

tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	set x; \
	here=`pwd`; \
	$(am__define_uniq_tagged_files); \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: ctags-am

CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	$(am__define_uniq_tagged_files); \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am

cscopelist-am: $(am__tagged_files)
	list='$(am__tagged_files)'; \
	case "$(srcdir)" in \
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
	  *) sdir=$(subdir)/$(srcdir) ;; \
	esac; \
	for i in $$list; do \
	  if test -f "$$i"; then \
	    echo "$(subdir)/$$i"; \
	  else \
	    echo "$$sdir/$$i"; \
	  fi; \
	done >> $(top_builddir)/cscope.files

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
check: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
	-rm -f gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-enumclass/$(am__dirstamp)
	-rm -f gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-forward/$(am__dirstamp)
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-private-templatestreamop/$(am__dirstamp)
	-rm -f gen-cpp-private/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-private/$(am__dirstamp)
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-templatestreamop/$(am__dirstamp)
	-rm -f gen-cpp/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp/$(am__dirstamp)
	-rm -f src/$(DEPDIR)/$(am__dirstamp)
	-rm -f src/$(am__dirstamp)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am

clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES mostlyclean-am

distclean: distclean-am
		-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp/$(DEPDIR)/SecondService.Plo
	-rm -f gen-cpp/$(DEPDIR)/Service.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
	-rm -f src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
	-rm -f src/$(DEPDIR)/StressTest.Po
	-rm -f src/$(DEPDIR)/StressTestNonBlocking.Po
	-rm -f src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/TestClient.Po
	-rm -f src/$(DEPDIR)/TestServer.Po
	-rm -f src/$(DEPDIR)/ThriftTest_extras.Plo
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp/$(DEPDIR)/SecondService.Plo
	-rm -f gen-cpp/$(DEPDIR)/Service.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
	-rm -f src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
	-rm -f src/$(DEPDIR)/StressTest.Po
	-rm -f src/$(DEPDIR)/StressTestNonBlocking.Po
	-rm -f src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/TestClient.Po
	-rm -f src/$(DEPDIR)/TestServer.Po
	-rm -f src/$(DEPDIR)/ThriftTest_extras.Plo
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: all check check-am install install-am install-exec \
	install-strip

.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
	clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \
	distclean-compile distclean-generic distclean-libtool \
	distclean-tags distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
	pdf pdf-am ps ps-am style-am style-local tags tags-am \
	uninstall uninstall-am

.PRECIOUS: Makefile


precross: TestServer TestClient

#
# Common thrift code generation rules
#
gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/SecondService.cpp gen-cpp/SecondService.h gen-cpp/SecondService.tcc: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(THRIFT) --gen cpp:templates,cob_style -r $<

# Generate ThriftTest with forward_setter option
gen-cpp-forward/ThriftTest_types.cpp gen-cpp-forward/ThriftTest_types.h gen-cpp-forward/ThriftTest_types.tcc gen-cpp-forward/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-forward
	$(THRIFT) --gen cpp:moveable_types=forward_setter -out gen-cpp-forward $<

# Generate ThriftTest with private_optional option
gen-cpp-private/ThriftTest_types.cpp gen-cpp-private/ThriftTest_types.h gen-cpp-private/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-private
	$(THRIFT) --gen cpp:private_optional -out gen-cpp-private $<

# Generate ThriftTest with enum_class option
gen-cpp-enumclass/ThriftTest_types.cpp gen-cpp-enumclass/ThriftTest_types.h gen-cpp-enumclass/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-enumclass
	$(THRIFT) --gen cpp:pure_enums=enum_class -out gen-cpp-enumclass $<

# Generate ThriftTest with template_streamop option
gen-cpp-templatestreamop/ThriftTest_types.cpp gen-cpp-templatestreamop/ThriftTest_types.h gen-cpp-templatestreamop/ThriftTest_types.tcc gen-cpp-templatestreamop/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-templatestreamop
	$(THRIFT) --gen cpp:template_streamop -out gen-cpp-templatestreamop $<

# Generate ThriftTest with private_optional,template_streamop options
gen-cpp-private-templatestreamop/ThriftTest_types.cpp gen-cpp-private-templatestreamop/ThriftTest_types.h gen-cpp-private-templatestreamop/ThriftTest_types.tcc gen-cpp-private-templatestreamop/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-private-templatestreamop
	$(THRIFT) --gen cpp:private_optional,template_streamop -out gen-cpp-private-templatestreamop $<

gen-cpp/Service.cpp: $(top_srcdir)/test/StressTest.thrift $(THRIFT)
	$(THRIFT) --gen cpp $<

gen-cpp/SpecificNameTest_types.cpp gen-cpp/EchoService.cpp: $(top_srcdir)/test/SpecificName.thrift $(THRIFT)
	$(THRIFT) --gen cpp $<

clean-local:
	$(RM) -r gen-cpp/ gen-cpp-forward/ gen-cpp-private/ gen-cpp-enumclass/ gen-cpp-templatestreamop/ gen-cpp-private-templatestreamop/

style-local:
	$(CPPSTYLE_CMD)

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/cpp/gen-cpp-private/0000755000175000017500000000000015170007202020110 5ustar00buildbuild00000000000000thrift-0.23.0/test/cpp/Makefile.in0000644000175000017500000021015415170007167017171 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
check_PROGRAMS = TestServer$(EXEEXT) TestClient$(EXEEXT) \
	StressTest$(EXEEXT) StressTestNonBlocking$(EXEEXT) \
	ForwardSetterTest$(EXEEXT) PrivateOptionalTest$(EXEEXT) \
	EnumClassTest$(EXEEXT) TemplateStreamOpTest$(EXEEXT) \
	PrivateOptionalTemplateStreamOpTest$(EXEEXT)
subdir = test/cpp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libenumclasstestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
am__dirstamp = $(am__leading_dot)dirstamp
nodist_libenumclasstestgencpp_la_OBJECTS =  \
	gen-cpp-enumclass/ThriftTest_types.lo \
	gen-cpp-enumclass/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libenumclasstestgencpp_la_OBJECTS =  \
	$(nodist_libenumclasstestgencpp_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 = 
libforwardsettertestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libforwardsettertestgencpp_la_OBJECTS =  \
	gen-cpp-forward/ThriftTest_types.lo \
	gen-cpp-forward/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libforwardsettertestgencpp_la_OBJECTS =  \
	$(nodist_libforwardsettertestgencpp_la_OBJECTS)
libprivateoptonaltestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateoptonaltestgencpp_la_OBJECTS =  \
	gen-cpp-private/ThriftTest_types.lo \
	gen-cpp-private/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libprivateoptonaltestgencpp_la_OBJECTS =  \
	$(nodist_libprivateoptonaltestgencpp_la_OBJECTS)
libprivateopttemplstreamoptestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateopttemplstreamoptestgencpp_la_OBJECTS =  \
	gen-cpp-private-templatestreamop/ThriftTest_types.lo \
	gen-cpp-private-templatestreamop/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libprivateopttemplstreamoptestgencpp_la_OBJECTS =  \
	$(nodist_libprivateopttemplstreamoptestgencpp_la_OBJECTS)
libstresstestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libstresstestgencpp_la_OBJECTS = gen-cpp/Service.lo
libstresstestgencpp_la_OBJECTS =  \
	$(nodist_libstresstestgencpp_la_OBJECTS)
libtemplatestreamoptestgencpp_la_DEPENDENCIES =  \
	$(top_builddir)/lib/cpp/libthrift.la
nodist_libtemplatestreamoptestgencpp_la_OBJECTS =  \
	gen-cpp-templatestreamop/ThriftTest_types.lo \
	gen-cpp-templatestreamop/ThriftTest_constants.lo \
	src/ThriftTest_extras.lo
libtemplatestreamoptestgencpp_la_OBJECTS =  \
	$(nodist_libtemplatestreamoptestgencpp_la_OBJECTS)
libtestgencpp_la_DEPENDENCIES = $(top_builddir)/lib/cpp/libthrift.la
nodist_libtestgencpp_la_OBJECTS = gen-cpp/SecondService.lo \
	gen-cpp/ThriftTest_constants.lo gen-cpp/ThriftTest_types.lo \
	gen-cpp/ThriftTest.lo src/ThriftTest_extras.lo
libtestgencpp_la_OBJECTS = $(nodist_libtestgencpp_la_OBJECTS)
am_EnumClassTest_OBJECTS = src/EnumClassTest-EnumClassTest.$(OBJEXT)
EnumClassTest_OBJECTS = $(am_EnumClassTest_OBJECTS)
EnumClassTest_DEPENDENCIES = libenumclasstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_ForwardSetterTest_OBJECTS =  \
	src/ForwardSetterTest-ForwardSetterTest.$(OBJEXT)
ForwardSetterTest_OBJECTS = $(am_ForwardSetterTest_OBJECTS)
ForwardSetterTest_DEPENDENCIES = libforwardsettertestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_PrivateOptionalTemplateStreamOpTest_OBJECTS = src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.$(OBJEXT)
PrivateOptionalTemplateStreamOpTest_OBJECTS =  \
	$(am_PrivateOptionalTemplateStreamOpTest_OBJECTS)
PrivateOptionalTemplateStreamOpTest_DEPENDENCIES =  \
	libprivateopttemplstreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_PrivateOptionalTest_OBJECTS =  \
	src/PrivateOptionalTest-PrivateOptionalTest.$(OBJEXT)
PrivateOptionalTest_OBJECTS = $(am_PrivateOptionalTest_OBJECTS)
PrivateOptionalTest_DEPENDENCIES = libprivateoptonaltestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_StressTest_OBJECTS = src/StressTest.$(OBJEXT)
StressTest_OBJECTS = $(am_StressTest_OBJECTS)
StressTest_DEPENDENCIES = libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_StressTestNonBlocking_OBJECTS =  \
	src/StressTestNonBlocking.$(OBJEXT)
StressTestNonBlocking_OBJECTS = $(am_StressTestNonBlocking_OBJECTS)
StressTestNonBlocking_DEPENDENCIES = libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthriftnb.la
am_TemplateStreamOpTest_OBJECTS =  \
	src/TemplateStreamOpTest-TemplateStreamOpTest.$(OBJEXT)
TemplateStreamOpTest_OBJECTS = $(am_TemplateStreamOpTest_OBJECTS)
TemplateStreamOpTest_DEPENDENCIES = libtemplatestreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la
am_TestClient_OBJECTS = src/TestClient.$(OBJEXT)
TestClient_OBJECTS = $(am_TestClient_OBJECTS)
am__DEPENDENCIES_1 =
TestClient_DEPENDENCIES = libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la $(am__DEPENDENCIES_1)
am_TestServer_OBJECTS = src/TestServer.$(OBJEXT)
TestServer_OBJECTS = $(am_TestServer_OBJECTS)
TestServer_DEPENDENCIES = libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la $(am__DEPENDENCIES_1)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = 
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade =  \
	gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo \
	gen-cpp/$(DEPDIR)/SecondService.Plo \
	gen-cpp/$(DEPDIR)/Service.Plo gen-cpp/$(DEPDIR)/ThriftTest.Plo \
	gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo \
	gen-cpp/$(DEPDIR)/ThriftTest_types.Plo \
	src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po \
	src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po \
	src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po \
	src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po \
	src/$(DEPDIR)/StressTest.Po \
	src/$(DEPDIR)/StressTestNonBlocking.Po \
	src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po \
	src/$(DEPDIR)/TestClient.Po src/$(DEPDIR)/TestServer.Po \
	src/$(DEPDIR)/ThriftTest_extras.Plo
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo "  CXX     " $@;
am__v_CXX_1 = 
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo "  CXXLD   " $@;
am__v_CXXLD_1 = 
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo "  CC      " $@;
am__v_CC_1 = 
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = $(nodist_libenumclasstestgencpp_la_SOURCES) \
	$(nodist_libforwardsettertestgencpp_la_SOURCES) \
	$(nodist_libprivateoptonaltestgencpp_la_SOURCES) \
	$(nodist_libprivateopttemplstreamoptestgencpp_la_SOURCES) \
	$(nodist_libstresstestgencpp_la_SOURCES) \
	$(nodist_libtemplatestreamoptestgencpp_la_SOURCES) \
	$(nodist_libtestgencpp_la_SOURCES) $(EnumClassTest_SOURCES) \
	$(ForwardSetterTest_SOURCES) \
	$(PrivateOptionalTemplateStreamOpTest_SOURCES) \
	$(PrivateOptionalTest_SOURCES) $(StressTest_SOURCES) \
	$(StressTestNonBlocking_SOURCES) \
	$(TemplateStreamOpTest_SOURCES) $(TestClient_SOURCES) \
	$(TestServer_SOURCES)
DIST_SOURCES = $(EnumClassTest_SOURCES) $(ForwardSetterTest_SOURCES) \
	$(PrivateOptionalTemplateStreamOpTest_SOURCES) \
	$(PrivateOptionalTest_SOURCES) $(StressTest_SOURCES) \
	$(StressTestNonBlocking_SOURCES) \
	$(TemplateStreamOpTest_SOURCES) $(TestClient_SOURCES) \
	$(TestServer_SOURCES)
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates.  Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
  BEGIN { nonempty = 0; } \
  { items[$$0] = 1; nonempty = 1; } \
  END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique.  This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
  list='$(am__tagged_files)'; \
  unique=`for i in $$list; do \
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  done | $(am__uniquify_input)`
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@

#
# 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.
#
AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
BUILT_SOURCES = gen-cpp/ThriftTest.cpp \
                gen-cpp/ThriftTest_types.cpp \
                gen-cpp/ThriftTest_constants.cpp \
                gen-cpp/SecondService.cpp \
                gen-cpp/Service.cpp \
                gen-cpp-forward/ThriftTest_types.cpp \
                gen-cpp-forward/ThriftTest_constants.cpp \
                gen-cpp-private/ThriftTest_types.cpp \
                gen-cpp-private/ThriftTest_constants.cpp \
                gen-cpp-enumclass/ThriftTest_types.cpp \
                gen-cpp-enumclass/ThriftTest_constants.cpp \
                gen-cpp-templatestreamop/ThriftTest_types.cpp \
                gen-cpp-templatestreamop/ThriftTest_types.tcc \
                gen-cpp-templatestreamop/ThriftTest_constants.cpp \
                gen-cpp-private-templatestreamop/ThriftTest_types.cpp \
                gen-cpp-private-templatestreamop/ThriftTest_types.tcc \
                gen-cpp-private-templatestreamop/ThriftTest_constants.cpp


# Libraries for option-specific tests
noinst_LTLIBRARIES = libtestgencpp.la libstresstestgencpp.la \
	libforwardsettertestgencpp.la libprivateoptonaltestgencpp.la \
	libenumclasstestgencpp.la libtemplatestreamoptestgencpp.la \
	libprivateopttemplstreamoptestgencpp.la
nodist_libtestgencpp_la_SOURCES = \
	gen-cpp/SecondService.cpp \
	gen-cpp/SecondService.h \
	gen-cpp/SecondService.tcc \
	gen-cpp/ThriftTest_constants.cpp \
	gen-cpp/ThriftTest_constants.h \
	gen-cpp/ThriftTest_types.cpp \
	gen-cpp/ThriftTest_types.h \
	gen-cpp/ThriftTest_types.tcc \
	gen-cpp/ThriftTest.cpp \
	gen-cpp/ThriftTest.h \
	gen-cpp/ThriftTest.tcc \
	src/ThriftTest_extras.cpp

libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libforwardsettertestgencpp_la_SOURCES = \
	gen-cpp-forward/ThriftTest_types.cpp \
	gen-cpp-forward/ThriftTest_types.h \
	gen-cpp-forward/ThriftTest_types.tcc \
	gen-cpp-forward/ThriftTest_constants.cpp \
	gen-cpp-forward/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libforwardsettertestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateoptonaltestgencpp_la_SOURCES = \
	gen-cpp-private/ThriftTest_types.cpp \
	gen-cpp-private/ThriftTest_types.h \
	gen-cpp-private/ThriftTest_constants.cpp \
	gen-cpp-private/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libprivateoptonaltestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libenumclasstestgencpp_la_SOURCES = \
	gen-cpp-enumclass/ThriftTest_types.cpp \
	gen-cpp-enumclass/ThriftTest_types.h \
	gen-cpp-enumclass/ThriftTest_constants.cpp \
	gen-cpp-enumclass/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libenumclasstestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libtemplatestreamoptestgencpp_la_SOURCES = \
	gen-cpp-templatestreamop/ThriftTest_types.cpp \
	gen-cpp-templatestreamop/ThriftTest_types.h \
	gen-cpp-templatestreamop/ThriftTest_types.tcc \
	gen-cpp-templatestreamop/ThriftTest_constants.cpp \
	gen-cpp-templatestreamop/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libtemplatestreamoptestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libprivateopttemplstreamoptestgencpp_la_SOURCES = \
	gen-cpp-private-templatestreamop/ThriftTest_types.cpp \
	gen-cpp-private-templatestreamop/ThriftTest_types.h \
	gen-cpp-private-templatestreamop/ThriftTest_types.tcc \
	gen-cpp-private-templatestreamop/ThriftTest_constants.cpp \
	gen-cpp-private-templatestreamop/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libprivateopttemplstreamoptestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
nodist_libstresstestgencpp_la_SOURCES = \
	gen-cpp/StressTest_types.h \
	gen-cpp/Service.cpp \
	gen-cpp/Service.h

libstresstestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

# we currently do not run the testsuite, stop c++ server issue
# TESTS = \
#	$(check_PROGRAMS)
TestServer_SOURCES = \
	src/TestServer.cpp

TestServer_LDADD = \
	libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent -lboost_program_options -lboost_system -lboost_filesystem $(ZLIB_LIBS)

TestClient_SOURCES = \
	src/TestClient.cpp

TestClient_LDADD = \
	libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent -lboost_program_options -lboost_system -lboost_filesystem $(ZLIB_LIBS)

StressTest_SOURCES = \
	src/StressTest.cpp

StressTest_LDADD = \
	libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

StressTestNonBlocking_SOURCES = \
	src/StressTestNonBlocking.cpp

StressTestNonBlocking_LDADD = \
	libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent

ForwardSetterTest_SOURCES = \
	src/ForwardSetterTest.cpp

ForwardSetterTest_CPPFLAGS = -Igen-cpp-forward $(AM_CPPFLAGS)
ForwardSetterTest_LDADD = \
	libforwardsettertestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

PrivateOptionalTest_SOURCES = \
	src/PrivateOptionalTest.cpp

PrivateOptionalTest_CPPFLAGS = -Igen-cpp-private $(AM_CPPFLAGS)
PrivateOptionalTest_LDADD = \
	libprivateoptonaltestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

EnumClassTest_SOURCES = \
	src/EnumClassTest.cpp

EnumClassTest_CPPFLAGS = -Igen-cpp-enumclass $(AM_CPPFLAGS)
EnumClassTest_LDADD = \
	libenumclasstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

TemplateStreamOpTest_SOURCES = \
	src/TemplateStreamOpTest.cpp

TemplateStreamOpTest_CPPFLAGS = -Igen-cpp-templatestreamop $(AM_CPPFLAGS)
TemplateStreamOpTest_LDADD = \
	libtemplatestreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

PrivateOptionalTemplateStreamOpTest_SOURCES = \
	src/PrivateOptionalTemplateStreamOpTest.cpp

PrivateOptionalTemplateStreamOpTest_CPPFLAGS = -Igen-cpp-private-templatestreamop $(AM_CPPFLAGS)
PrivateOptionalTemplateStreamOpTest_LDADD = \
	libprivateopttemplstreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp -I.
AM_CXXFLAGS = -Wall -Wextra -pedantic -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) $(ZLIB_LIBS)
EXTRA_DIST = \
	src/TestClient.cpp \
	src/TestServer.cpp \
	src/StressTest.cpp \
	src/StressTestNonBlocking.cpp \
	src/ForwardSetterTest.cpp \
	src/PrivateOptionalTest.cpp \
	src/EnumClassTest.cpp \
	src/TemplateStreamOpTest.cpp \
	src/PrivateOptionalTemplateStreamOpTest.cpp

all: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) all-am

.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/cpp/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/cpp/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

clean-checkPROGRAMS:
	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list

clean-noinstLTLIBRARIES:
	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
	@list='$(noinst_LTLIBRARIES)'; \
	locs=`for p in $$list; do echo $$p; done | \
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
	      sort -u`; \
	test -z "$$locs" || { \
	  echo rm -f $${locs}; \
	  rm -f $${locs}; \
	}
gen-cpp-enumclass/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-enumclass
	@: > gen-cpp-enumclass/$(am__dirstamp)
gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-enumclass/$(DEPDIR)
	@: > gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
gen-cpp-enumclass/ThriftTest_types.lo:  \
	gen-cpp-enumclass/$(am__dirstamp) \
	gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
gen-cpp-enumclass/ThriftTest_constants.lo:  \
	gen-cpp-enumclass/$(am__dirstamp) \
	gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
src/$(am__dirstamp):
	@$(MKDIR_P) src
	@: > src/$(am__dirstamp)
src/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) src/$(DEPDIR)
	@: > src/$(DEPDIR)/$(am__dirstamp)
src/ThriftTest_extras.lo: src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

libenumclasstestgencpp.la: $(libenumclasstestgencpp_la_OBJECTS) $(libenumclasstestgencpp_la_DEPENDENCIES) $(EXTRA_libenumclasstestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libenumclasstestgencpp_la_OBJECTS) $(libenumclasstestgencpp_la_LIBADD) $(LIBS)
gen-cpp-forward/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-forward
	@: > gen-cpp-forward/$(am__dirstamp)
gen-cpp-forward/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-forward/$(DEPDIR)
	@: > gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)
gen-cpp-forward/ThriftTest_types.lo: gen-cpp-forward/$(am__dirstamp) \
	gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)
gen-cpp-forward/ThriftTest_constants.lo:  \
	gen-cpp-forward/$(am__dirstamp) \
	gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)

libforwardsettertestgencpp.la: $(libforwardsettertestgencpp_la_OBJECTS) $(libforwardsettertestgencpp_la_DEPENDENCIES) $(EXTRA_libforwardsettertestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libforwardsettertestgencpp_la_OBJECTS) $(libforwardsettertestgencpp_la_LIBADD) $(LIBS)
gen-cpp-private/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private
	@: > gen-cpp-private/$(am__dirstamp)
gen-cpp-private/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private/$(DEPDIR)
	@: > gen-cpp-private/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private/ThriftTest_types.lo: gen-cpp-private/$(am__dirstamp) \
	gen-cpp-private/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private/ThriftTest_constants.lo:  \
	gen-cpp-private/$(am__dirstamp) \
	gen-cpp-private/$(DEPDIR)/$(am__dirstamp)

libprivateoptonaltestgencpp.la: $(libprivateoptonaltestgencpp_la_OBJECTS) $(libprivateoptonaltestgencpp_la_DEPENDENCIES) $(EXTRA_libprivateoptonaltestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libprivateoptonaltestgencpp_la_OBJECTS) $(libprivateoptonaltestgencpp_la_LIBADD) $(LIBS)
gen-cpp-private-templatestreamop/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private-templatestreamop
	@: > gen-cpp-private-templatestreamop/$(am__dirstamp)
gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-private-templatestreamop/$(DEPDIR)
	@: > gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private-templatestreamop/ThriftTest_types.lo:  \
	gen-cpp-private-templatestreamop/$(am__dirstamp) \
	gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-private-templatestreamop/ThriftTest_constants.lo:  \
	gen-cpp-private-templatestreamop/$(am__dirstamp) \
	gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)

libprivateopttemplstreamoptestgencpp.la: $(libprivateopttemplstreamoptestgencpp_la_OBJECTS) $(libprivateopttemplstreamoptestgencpp_la_DEPENDENCIES) $(EXTRA_libprivateopttemplstreamoptestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libprivateopttemplstreamoptestgencpp_la_OBJECTS) $(libprivateopttemplstreamoptestgencpp_la_LIBADD) $(LIBS)
gen-cpp/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp
	@: > gen-cpp/$(am__dirstamp)
gen-cpp/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp/$(DEPDIR)
	@: > gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/Service.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)

libstresstestgencpp.la: $(libstresstestgencpp_la_OBJECTS) $(libstresstestgencpp_la_DEPENDENCIES) $(EXTRA_libstresstestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libstresstestgencpp_la_OBJECTS) $(libstresstestgencpp_la_LIBADD) $(LIBS)
gen-cpp-templatestreamop/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-templatestreamop
	@: > gen-cpp-templatestreamop/$(am__dirstamp)
gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) gen-cpp-templatestreamop/$(DEPDIR)
	@: > gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-templatestreamop/ThriftTest_types.lo:  \
	gen-cpp-templatestreamop/$(am__dirstamp) \
	gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)
gen-cpp-templatestreamop/ThriftTest_constants.lo:  \
	gen-cpp-templatestreamop/$(am__dirstamp) \
	gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)

libtemplatestreamoptestgencpp.la: $(libtemplatestreamoptestgencpp_la_OBJECTS) $(libtemplatestreamoptestgencpp_la_DEPENDENCIES) $(EXTRA_libtemplatestreamoptestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libtemplatestreamoptestgencpp_la_OBJECTS) $(libtemplatestreamoptestgencpp_la_LIBADD) $(LIBS)
gen-cpp/SecondService.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/ThriftTest_constants.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/ThriftTest_types.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)
gen-cpp/ThriftTest.lo: gen-cpp/$(am__dirstamp) \
	gen-cpp/$(DEPDIR)/$(am__dirstamp)

libtestgencpp.la: $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_DEPENDENCIES) $(EXTRA_libtestgencpp_la_DEPENDENCIES) 
	$(AM_V_CXXLD)$(CXXLINK)  $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_LIBADD) $(LIBS)
src/EnumClassTest-EnumClassTest.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

EnumClassTest$(EXEEXT): $(EnumClassTest_OBJECTS) $(EnumClassTest_DEPENDENCIES) $(EXTRA_EnumClassTest_DEPENDENCIES) 
	@rm -f EnumClassTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(EnumClassTest_OBJECTS) $(EnumClassTest_LDADD) $(LIBS)
src/ForwardSetterTest-ForwardSetterTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

ForwardSetterTest$(EXEEXT): $(ForwardSetterTest_OBJECTS) $(ForwardSetterTest_DEPENDENCIES) $(EXTRA_ForwardSetterTest_DEPENDENCIES) 
	@rm -f ForwardSetterTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(ForwardSetterTest_OBJECTS) $(ForwardSetterTest_LDADD) $(LIBS)
src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

PrivateOptionalTemplateStreamOpTest$(EXEEXT): $(PrivateOptionalTemplateStreamOpTest_OBJECTS) $(PrivateOptionalTemplateStreamOpTest_DEPENDENCIES) $(EXTRA_PrivateOptionalTemplateStreamOpTest_DEPENDENCIES) 
	@rm -f PrivateOptionalTemplateStreamOpTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(PrivateOptionalTemplateStreamOpTest_OBJECTS) $(PrivateOptionalTemplateStreamOpTest_LDADD) $(LIBS)
src/PrivateOptionalTest-PrivateOptionalTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

PrivateOptionalTest$(EXEEXT): $(PrivateOptionalTest_OBJECTS) $(PrivateOptionalTest_DEPENDENCIES) $(EXTRA_PrivateOptionalTest_DEPENDENCIES) 
	@rm -f PrivateOptionalTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(PrivateOptionalTest_OBJECTS) $(PrivateOptionalTest_LDADD) $(LIBS)
src/StressTest.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

StressTest$(EXEEXT): $(StressTest_OBJECTS) $(StressTest_DEPENDENCIES) $(EXTRA_StressTest_DEPENDENCIES) 
	@rm -f StressTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(StressTest_OBJECTS) $(StressTest_LDADD) $(LIBS)
src/StressTestNonBlocking.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

StressTestNonBlocking$(EXEEXT): $(StressTestNonBlocking_OBJECTS) $(StressTestNonBlocking_DEPENDENCIES) $(EXTRA_StressTestNonBlocking_DEPENDENCIES) 
	@rm -f StressTestNonBlocking$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(StressTestNonBlocking_OBJECTS) $(StressTestNonBlocking_LDADD) $(LIBS)
src/TemplateStreamOpTest-TemplateStreamOpTest.$(OBJEXT):  \
	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)

TemplateStreamOpTest$(EXEEXT): $(TemplateStreamOpTest_OBJECTS) $(TemplateStreamOpTest_DEPENDENCIES) $(EXTRA_TemplateStreamOpTest_DEPENDENCIES) 
	@rm -f TemplateStreamOpTest$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(TemplateStreamOpTest_OBJECTS) $(TemplateStreamOpTest_LDADD) $(LIBS)
src/TestClient.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

TestClient$(EXEEXT): $(TestClient_OBJECTS) $(TestClient_DEPENDENCIES) $(EXTRA_TestClient_DEPENDENCIES) 
	@rm -f TestClient$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(TestClient_OBJECTS) $(TestClient_LDADD) $(LIBS)
src/TestServer.$(OBJEXT): src/$(am__dirstamp) \
	src/$(DEPDIR)/$(am__dirstamp)

TestServer$(EXEEXT): $(TestServer_OBJECTS) $(TestServer_DEPENDENCIES) $(EXTRA_TestServer_DEPENDENCIES) 
	@rm -f TestServer$(EXEEXT)
	$(AM_V_CXXLD)$(CXXLINK) $(TestServer_OBJECTS) $(TestServer_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)
	-rm -f gen-cpp-enumclass/*.$(OBJEXT)
	-rm -f gen-cpp-enumclass/*.lo
	-rm -f gen-cpp-forward/*.$(OBJEXT)
	-rm -f gen-cpp-forward/*.lo
	-rm -f gen-cpp-private-templatestreamop/*.$(OBJEXT)
	-rm -f gen-cpp-private-templatestreamop/*.lo
	-rm -f gen-cpp-private/*.$(OBJEXT)
	-rm -f gen-cpp-private/*.lo
	-rm -f gen-cpp-templatestreamop/*.$(OBJEXT)
	-rm -f gen-cpp-templatestreamop/*.lo
	-rm -f gen-cpp/*.$(OBJEXT)
	-rm -f gen-cpp/*.lo
	-rm -f src/*.$(OBJEXT)
	-rm -f src/*.lo

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/SecondService.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/Service.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/ThriftTest.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/ThriftTest_types.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/StressTest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/StressTestNonBlocking.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/TestClient.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/TestServer.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ThriftTest_extras.Plo@am__quote@ # am--include-marker

$(am__depfiles_remade):
	@$(MKDIR_P) $(@D)
	@echo '# dummy' >$@-t && $(am__mv) $@-t $@

am--depfiles: $(am__depfiles_remade)

.cpp.o:
@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<

.cpp.obj:
@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`

.cpp.lo:
@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<

src/EnumClassTest-EnumClassTest.o: src/EnumClassTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/EnumClassTest-EnumClassTest.o -MD -MP -MF src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo -c -o src/EnumClassTest-EnumClassTest.o `test -f 'src/EnumClassTest.cpp' || echo '$(srcdir)/'`src/EnumClassTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/EnumClassTest.cpp' object='src/EnumClassTest-EnumClassTest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/EnumClassTest-EnumClassTest.o `test -f 'src/EnumClassTest.cpp' || echo '$(srcdir)/'`src/EnumClassTest.cpp

src/EnumClassTest-EnumClassTest.obj: src/EnumClassTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/EnumClassTest-EnumClassTest.obj -MD -MP -MF src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo -c -o src/EnumClassTest-EnumClassTest.obj `if test -f 'src/EnumClassTest.cpp'; then $(CYGPATH_W) 'src/EnumClassTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/EnumClassTest.cpp'; fi`
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/EnumClassTest-EnumClassTest.Tpo src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/EnumClassTest.cpp' object='src/EnumClassTest-EnumClassTest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(EnumClassTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/EnumClassTest-EnumClassTest.obj `if test -f 'src/EnumClassTest.cpp'; then $(CYGPATH_W) 'src/EnumClassTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/EnumClassTest.cpp'; fi`

src/ForwardSetterTest-ForwardSetterTest.o: src/ForwardSetterTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/ForwardSetterTest-ForwardSetterTest.o -MD -MP -MF src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo -c -o src/ForwardSetterTest-ForwardSetterTest.o `test -f 'src/ForwardSetterTest.cpp' || echo '$(srcdir)/'`src/ForwardSetterTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/ForwardSetterTest.cpp' object='src/ForwardSetterTest-ForwardSetterTest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/ForwardSetterTest-ForwardSetterTest.o `test -f 'src/ForwardSetterTest.cpp' || echo '$(srcdir)/'`src/ForwardSetterTest.cpp

src/ForwardSetterTest-ForwardSetterTest.obj: src/ForwardSetterTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/ForwardSetterTest-ForwardSetterTest.obj -MD -MP -MF src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo -c -o src/ForwardSetterTest-ForwardSetterTest.obj `if test -f 'src/ForwardSetterTest.cpp'; then $(CYGPATH_W) 'src/ForwardSetterTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/ForwardSetterTest.cpp'; fi`
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Tpo src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/ForwardSetterTest.cpp' object='src/ForwardSetterTest-ForwardSetterTest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ForwardSetterTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/ForwardSetterTest-ForwardSetterTest.obj `if test -f 'src/ForwardSetterTest.cpp'; then $(CYGPATH_W) 'src/ForwardSetterTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/ForwardSetterTest.cpp'; fi`

src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o: src/PrivateOptionalTemplateStreamOpTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o `test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTemplateStreamOpTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/PrivateOptionalTemplateStreamOpTest.cpp' object='src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.o `test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTemplateStreamOpTest.cpp

src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj: src/PrivateOptionalTemplateStreamOpTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj `if test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTemplateStreamOpTest.cpp'; fi`
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Tpo src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/PrivateOptionalTemplateStreamOpTest.cpp' object='src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.obj `if test -f 'src/PrivateOptionalTemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTemplateStreamOpTest.cpp'; fi`

src/PrivateOptionalTest-PrivateOptionalTest.o: src/PrivateOptionalTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTest-PrivateOptionalTest.o -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo -c -o src/PrivateOptionalTest-PrivateOptionalTest.o `test -f 'src/PrivateOptionalTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/PrivateOptionalTest.cpp' object='src/PrivateOptionalTest-PrivateOptionalTest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTest-PrivateOptionalTest.o `test -f 'src/PrivateOptionalTest.cpp' || echo '$(srcdir)/'`src/PrivateOptionalTest.cpp

src/PrivateOptionalTest-PrivateOptionalTest.obj: src/PrivateOptionalTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/PrivateOptionalTest-PrivateOptionalTest.obj -MD -MP -MF src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo -c -o src/PrivateOptionalTest-PrivateOptionalTest.obj `if test -f 'src/PrivateOptionalTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTest.cpp'; fi`
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Tpo src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/PrivateOptionalTest.cpp' object='src/PrivateOptionalTest-PrivateOptionalTest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(PrivateOptionalTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/PrivateOptionalTest-PrivateOptionalTest.obj `if test -f 'src/PrivateOptionalTest.cpp'; then $(CYGPATH_W) 'src/PrivateOptionalTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/PrivateOptionalTest.cpp'; fi`

src/TemplateStreamOpTest-TemplateStreamOpTest.o: src/TemplateStreamOpTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/TemplateStreamOpTest-TemplateStreamOpTest.o -MD -MP -MF src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.o `test -f 'src/TemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/TemplateStreamOpTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/TemplateStreamOpTest.cpp' object='src/TemplateStreamOpTest-TemplateStreamOpTest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.o `test -f 'src/TemplateStreamOpTest.cpp' || echo '$(srcdir)/'`src/TemplateStreamOpTest.cpp

src/TemplateStreamOpTest-TemplateStreamOpTest.obj: src/TemplateStreamOpTest.cpp
@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/TemplateStreamOpTest-TemplateStreamOpTest.obj -MD -MP -MF src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.obj `if test -f 'src/TemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/TemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/TemplateStreamOpTest.cpp'; fi`
@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Tpo src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='src/TemplateStreamOpTest.cpp' object='src/TemplateStreamOpTest-TemplateStreamOpTest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TemplateStreamOpTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/TemplateStreamOpTest-TemplateStreamOpTest.obj `if test -f 'src/TemplateStreamOpTest.cpp'; then $(CYGPATH_W) 'src/TemplateStreamOpTest.cpp'; else $(CYGPATH_W) '$(srcdir)/src/TemplateStreamOpTest.cpp'; fi`

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
	-rm -rf gen-cpp/.libs gen-cpp/_libs
	-rm -rf gen-cpp-enumclass/.libs gen-cpp-enumclass/_libs
	-rm -rf gen-cpp-forward/.libs gen-cpp-forward/_libs
	-rm -rf gen-cpp-private/.libs gen-cpp-private/_libs
	-rm -rf gen-cpp-private-templatestreamop/.libs gen-cpp-private-templatestreamop/_libs
	-rm -rf gen-cpp-templatestreamop/.libs gen-cpp-templatestreamop/_libs
	-rm -rf src/.libs src/_libs
style-local: 

ID: $(am__tagged_files)
	$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags

tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	set x; \
	here=`pwd`; \
	$(am__define_uniq_tagged_files); \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: ctags-am

CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	$(am__define_uniq_tagged_files); \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am

cscopelist-am: $(am__tagged_files)
	list='$(am__tagged_files)'; \
	case "$(srcdir)" in \
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
	  *) sdir=$(subdir)/$(srcdir) ;; \
	esac; \
	for i in $$list; do \
	  if test -f "$$i"; then \
	    echo "$(subdir)/$$i"; \
	  else \
	    echo "$$sdir/$$i"; \
	  fi; \
	done >> $(top_builddir)/cscope.files

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
check: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: $(BUILT_SOURCES)
	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
	-rm -f gen-cpp-enumclass/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-enumclass/$(am__dirstamp)
	-rm -f gen-cpp-forward/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-forward/$(am__dirstamp)
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-private-templatestreamop/$(am__dirstamp)
	-rm -f gen-cpp-private/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-private/$(am__dirstamp)
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp-templatestreamop/$(am__dirstamp)
	-rm -f gen-cpp/$(DEPDIR)/$(am__dirstamp)
	-rm -f gen-cpp/$(am__dirstamp)
	-rm -f src/$(DEPDIR)/$(am__dirstamp)
	-rm -f src/$(am__dirstamp)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am

clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES mostlyclean-am

distclean: distclean-am
		-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp/$(DEPDIR)/SecondService.Plo
	-rm -f gen-cpp/$(DEPDIR)/Service.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
	-rm -f src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
	-rm -f src/$(DEPDIR)/StressTest.Po
	-rm -f src/$(DEPDIR)/StressTestNonBlocking.Po
	-rm -f src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/TestClient.Po
	-rm -f src/$(DEPDIR)/TestServer.Po
	-rm -f src/$(DEPDIR)/ThriftTest_extras.Plo
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
		-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-enumclass/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-forward/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-private/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp-templatestreamop/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f gen-cpp/$(DEPDIR)/SecondService.Plo
	-rm -f gen-cpp/$(DEPDIR)/Service.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo
	-rm -f gen-cpp/$(DEPDIR)/ThriftTest_types.Plo
	-rm -f src/$(DEPDIR)/EnumClassTest-EnumClassTest.Po
	-rm -f src/$(DEPDIR)/ForwardSetterTest-ForwardSetterTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTemplateStreamOpTest-PrivateOptionalTemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/PrivateOptionalTest-PrivateOptionalTest.Po
	-rm -f src/$(DEPDIR)/StressTest.Po
	-rm -f src/$(DEPDIR)/StressTestNonBlocking.Po
	-rm -f src/$(DEPDIR)/TemplateStreamOpTest-TemplateStreamOpTest.Po
	-rm -f src/$(DEPDIR)/TestClient.Po
	-rm -f src/$(DEPDIR)/TestServer.Po
	-rm -f src/$(DEPDIR)/ThriftTest_extras.Plo
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: all check check-am install install-am install-exec \
	install-strip

.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
	clean-checkPROGRAMS clean-generic clean-libtool clean-local \
	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \
	distclean-compile distclean-generic distclean-libtool \
	distclean-tags distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
	pdf pdf-am ps ps-am style-am style-local tags tags-am \
	uninstall uninstall-am

.PRECIOUS: Makefile


precross: TestServer TestClient

#
# Common thrift code generation rules
#
gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/SecondService.cpp gen-cpp/SecondService.h gen-cpp/SecondService.tcc: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(THRIFT) --gen cpp:templates,cob_style -r $<

# Generate ThriftTest with forward_setter option
gen-cpp-forward/ThriftTest_types.cpp gen-cpp-forward/ThriftTest_types.h gen-cpp-forward/ThriftTest_types.tcc gen-cpp-forward/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-forward
	$(THRIFT) --gen cpp:moveable_types=forward_setter -out gen-cpp-forward $<

# Generate ThriftTest with private_optional option
gen-cpp-private/ThriftTest_types.cpp gen-cpp-private/ThriftTest_types.h gen-cpp-private/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-private
	$(THRIFT) --gen cpp:private_optional -out gen-cpp-private $<

# Generate ThriftTest with enum_class option
gen-cpp-enumclass/ThriftTest_types.cpp gen-cpp-enumclass/ThriftTest_types.h gen-cpp-enumclass/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-enumclass
	$(THRIFT) --gen cpp:pure_enums=enum_class -out gen-cpp-enumclass $<

# Generate ThriftTest with template_streamop option
gen-cpp-templatestreamop/ThriftTest_types.cpp gen-cpp-templatestreamop/ThriftTest_types.h gen-cpp-templatestreamop/ThriftTest_types.tcc gen-cpp-templatestreamop/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-templatestreamop
	$(THRIFT) --gen cpp:template_streamop -out gen-cpp-templatestreamop $<

# Generate ThriftTest with private_optional,template_streamop options
gen-cpp-private-templatestreamop/ThriftTest_types.cpp gen-cpp-private-templatestreamop/ThriftTest_types.h gen-cpp-private-templatestreamop/ThriftTest_types.tcc gen-cpp-private-templatestreamop/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-private-templatestreamop
	$(THRIFT) --gen cpp:private_optional,template_streamop -out gen-cpp-private-templatestreamop $<

gen-cpp/Service.cpp: $(top_srcdir)/test/StressTest.thrift $(THRIFT)
	$(THRIFT) --gen cpp $<

gen-cpp/SpecificNameTest_types.cpp gen-cpp/EchoService.cpp: $(top_srcdir)/test/SpecificName.thrift $(THRIFT)
	$(THRIFT) --gen cpp $<

clean-local:
	$(RM) -r gen-cpp/ gen-cpp-forward/ gen-cpp-private/ gen-cpp-enumclass/ gen-cpp-templatestreamop/ gen-cpp-private-templatestreamop/

style-local:
	$(CPPSTYLE_CMD)

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/cpp/Makefile.am0000664000175000017500000002367315167543515017202 0ustar00buildbuild00000000000000#
# 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.
#
AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc

BUILT_SOURCES = gen-cpp/ThriftTest.cpp \
                gen-cpp/ThriftTest_types.cpp \
                gen-cpp/ThriftTest_constants.cpp \
                gen-cpp/SecondService.cpp \
                gen-cpp/Service.cpp \
                gen-cpp-forward/ThriftTest_types.cpp \
                gen-cpp-forward/ThriftTest_constants.cpp \
                gen-cpp-private/ThriftTest_types.cpp \
                gen-cpp-private/ThriftTest_constants.cpp \
                gen-cpp-enumclass/ThriftTest_types.cpp \
                gen-cpp-enumclass/ThriftTest_constants.cpp \
                gen-cpp-templatestreamop/ThriftTest_types.cpp \
                gen-cpp-templatestreamop/ThriftTest_types.tcc \
                gen-cpp-templatestreamop/ThriftTest_constants.cpp \
                gen-cpp-private-templatestreamop/ThriftTest_types.cpp \
                gen-cpp-private-templatestreamop/ThriftTest_types.tcc \
                gen-cpp-private-templatestreamop/ThriftTest_constants.cpp

noinst_LTLIBRARIES = libtestgencpp.la libstresstestgencpp.la
nodist_libtestgencpp_la_SOURCES = \
	gen-cpp/SecondService.cpp \
	gen-cpp/SecondService.h \
	gen-cpp/SecondService.tcc \
	gen-cpp/ThriftTest_constants.cpp \
	gen-cpp/ThriftTest_constants.h \
	gen-cpp/ThriftTest_types.cpp \
	gen-cpp/ThriftTest_types.h \
	gen-cpp/ThriftTest_types.tcc \
	gen-cpp/ThriftTest.cpp \
	gen-cpp/ThriftTest.h \
	gen-cpp/ThriftTest.tcc \
	src/ThriftTest_extras.cpp

libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

# Libraries for option-specific tests
noinst_LTLIBRARIES += \
	libforwardsettertestgencpp.la \
	libprivateoptonaltestgencpp.la \
	libenumclasstestgencpp.la \
	libtemplatestreamoptestgencpp.la \
	libprivateopttemplstreamoptestgencpp.la

nodist_libforwardsettertestgencpp_la_SOURCES = \
	gen-cpp-forward/ThriftTest_types.cpp \
	gen-cpp-forward/ThriftTest_types.h \
	gen-cpp-forward/ThriftTest_types.tcc \
	gen-cpp-forward/ThriftTest_constants.cpp \
	gen-cpp-forward/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libforwardsettertestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

nodist_libprivateoptonaltestgencpp_la_SOURCES = \
	gen-cpp-private/ThriftTest_types.cpp \
	gen-cpp-private/ThriftTest_types.h \
	gen-cpp-private/ThriftTest_constants.cpp \
	gen-cpp-private/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libprivateoptonaltestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

nodist_libenumclasstestgencpp_la_SOURCES = \
	gen-cpp-enumclass/ThriftTest_types.cpp \
	gen-cpp-enumclass/ThriftTest_types.h \
	gen-cpp-enumclass/ThriftTest_constants.cpp \
	gen-cpp-enumclass/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libenumclasstestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

nodist_libtemplatestreamoptestgencpp_la_SOURCES = \
	gen-cpp-templatestreamop/ThriftTest_types.cpp \
	gen-cpp-templatestreamop/ThriftTest_types.h \
	gen-cpp-templatestreamop/ThriftTest_types.tcc \
	gen-cpp-templatestreamop/ThriftTest_constants.cpp \
	gen-cpp-templatestreamop/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libtemplatestreamoptestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

nodist_libprivateopttemplstreamoptestgencpp_la_SOURCES = \
	gen-cpp-private-templatestreamop/ThriftTest_types.cpp \
	gen-cpp-private-templatestreamop/ThriftTest_types.h \
	gen-cpp-private-templatestreamop/ThriftTest_types.tcc \
	gen-cpp-private-templatestreamop/ThriftTest_constants.cpp \
	gen-cpp-private-templatestreamop/ThriftTest_constants.h \
	src/ThriftTest_extras.cpp

libprivateopttemplstreamoptestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

nodist_libstresstestgencpp_la_SOURCES = \
	gen-cpp/StressTest_types.h \
	gen-cpp/Service.cpp \
	gen-cpp/Service.h

libstresstestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la

precross: TestServer TestClient

check_PROGRAMS = \
	TestServer \
	TestClient \
	StressTest \
	StressTestNonBlocking \
	ForwardSetterTest \
	PrivateOptionalTest \
	EnumClassTest \
	TemplateStreamOpTest \
	PrivateOptionalTemplateStreamOpTest

# we currently do not run the testsuite, stop c++ server issue
# TESTS = \
#	$(check_PROGRAMS)

TestServer_SOURCES = \
	src/TestServer.cpp

TestServer_LDADD = \
	libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent -lboost_program_options -lboost_system -lboost_filesystem $(ZLIB_LIBS)

TestClient_SOURCES = \
	src/TestClient.cpp

TestClient_LDADD = \
	libtestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la \
	$(top_builddir)/lib/cpp/libthriftz.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent -lboost_program_options -lboost_system -lboost_filesystem $(ZLIB_LIBS)

StressTest_SOURCES = \
	src/StressTest.cpp

StressTest_LDADD = \
	libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

StressTestNonBlocking_SOURCES = \
	src/StressTestNonBlocking.cpp

StressTestNonBlocking_LDADD = \
	libstresstestgencpp.la \
	$(top_builddir)/lib/cpp/libthriftnb.la \
	-levent

ForwardSetterTest_SOURCES = \
	src/ForwardSetterTest.cpp

ForwardSetterTest_CPPFLAGS = -Igen-cpp-forward $(AM_CPPFLAGS)
ForwardSetterTest_LDADD = \
	libforwardsettertestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

PrivateOptionalTest_SOURCES = \
	src/PrivateOptionalTest.cpp

PrivateOptionalTest_CPPFLAGS = -Igen-cpp-private $(AM_CPPFLAGS)
PrivateOptionalTest_LDADD = \
	libprivateoptonaltestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

EnumClassTest_SOURCES = \
	src/EnumClassTest.cpp

EnumClassTest_CPPFLAGS = -Igen-cpp-enumclass $(AM_CPPFLAGS)
EnumClassTest_LDADD = \
	libenumclasstestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

TemplateStreamOpTest_SOURCES = \
	src/TemplateStreamOpTest.cpp

TemplateStreamOpTest_CPPFLAGS = -Igen-cpp-templatestreamop $(AM_CPPFLAGS)
TemplateStreamOpTest_LDADD = \
	libtemplatestreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

PrivateOptionalTemplateStreamOpTest_SOURCES = \
	src/PrivateOptionalTemplateStreamOpTest.cpp

PrivateOptionalTemplateStreamOpTest_CPPFLAGS = -Igen-cpp-private-templatestreamop $(AM_CPPFLAGS)
PrivateOptionalTemplateStreamOpTest_LDADD = \
	libprivateopttemplstreamoptestgencpp.la \
	$(top_builddir)/lib/cpp/libthrift.la

#
# Common thrift code generation rules
#
gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/SecondService.cpp gen-cpp/SecondService.h gen-cpp/SecondService.tcc: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(THRIFT) --gen cpp:templates,cob_style -r $<

# Generate ThriftTest with forward_setter option
gen-cpp-forward/ThriftTest_types.cpp gen-cpp-forward/ThriftTest_types.h gen-cpp-forward/ThriftTest_types.tcc gen-cpp-forward/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-forward
	$(THRIFT) --gen cpp:moveable_types=forward_setter -out gen-cpp-forward $<

# Generate ThriftTest with private_optional option
gen-cpp-private/ThriftTest_types.cpp gen-cpp-private/ThriftTest_types.h gen-cpp-private/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-private
	$(THRIFT) --gen cpp:private_optional -out gen-cpp-private $<

# Generate ThriftTest with enum_class option
gen-cpp-enumclass/ThriftTest_types.cpp gen-cpp-enumclass/ThriftTest_types.h gen-cpp-enumclass/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-enumclass
	$(THRIFT) --gen cpp:pure_enums=enum_class -out gen-cpp-enumclass $<

# Generate ThriftTest with template_streamop option
gen-cpp-templatestreamop/ThriftTest_types.cpp gen-cpp-templatestreamop/ThriftTest_types.h gen-cpp-templatestreamop/ThriftTest_types.tcc gen-cpp-templatestreamop/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-templatestreamop
	$(THRIFT) --gen cpp:template_streamop -out gen-cpp-templatestreamop $<

# Generate ThriftTest with private_optional,template_streamop options
gen-cpp-private-templatestreamop/ThriftTest_types.cpp gen-cpp-private-templatestreamop/ThriftTest_types.h gen-cpp-private-templatestreamop/ThriftTest_types.tcc gen-cpp-private-templatestreamop/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
	$(MKDIR_P) gen-cpp-private-templatestreamop
	$(THRIFT) --gen cpp:private_optional,template_streamop -out gen-cpp-private-templatestreamop $<

gen-cpp/Service.cpp: $(top_srcdir)/test/StressTest.thrift $(THRIFT)
	$(THRIFT) --gen cpp $<

gen-cpp/SpecificNameTest_types.cpp gen-cpp/EchoService.cpp: $(top_srcdir)/test/SpecificName.thrift $(THRIFT)
	$(THRIFT) --gen cpp $<

AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp -I.
AM_CXXFLAGS = -Wall -Wextra -pedantic -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) $(ZLIB_LIBS)

clean-local:
	$(RM) -r gen-cpp/ gen-cpp-forward/ gen-cpp-private/ gen-cpp-enumclass/ gen-cpp-templatestreamop/ gen-cpp-private-templatestreamop/

style-local:
	$(CPPSTYLE_CMD)

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	src/TestClient.cpp \
	src/TestServer.cpp \
	src/StressTest.cpp \
	src/StressTestNonBlocking.cpp \
	src/ForwardSetterTest.cpp \
	src/PrivateOptionalTest.cpp \
	src/EnumClassTest.cpp \
	src/TemplateStreamOpTest.cpp \
	src/PrivateOptionalTemplateStreamOpTest.cpp
thrift-0.23.0/test/Service.thrift0000664000175000017500000000174715167543515017204 0ustar00buildbuild00000000000000/*
 * 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 "Types.thrift"

service Service {
  Types.Type1 testEpisode(1:Types.Type1 arg)
}

service ExtendedService extends Types.BaseService {
  Types.Type1 testEpisodeExtend(1:Types.Type1 arg)
}thrift-0.23.0/test/rb/0000775000175000017500000000000015170007175014743 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/benchmarks/0000775000175000017500000000000015170007142017052 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/benchmarks/protocol_benchmark.rb0000664000175000017500000001356115170007142023260 0ustar00buildbuild00000000000000#
# 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.
#

$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. .. .. lib rb lib])
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. .. .. lib rb ext])

require 'thrift'

require 'benchmark'
require 'rubygems'
require 'set'
require 'pp'

# require 'ruby-debug'
# require 'ruby-prof'

require File.join(File.dirname(__FILE__), '../fixtures/structs')

transport1 = Thrift::MemoryBuffer.new
ruby_binary_protocol = Thrift::BinaryProtocol.new(transport1)

transport2 = Thrift::MemoryBuffer.new
c_fast_binary_protocol = Thrift::BinaryProtocolAccelerated.new(transport2)

transport3 = Thrift::MemoryBuffer.new
header_binary_protocol = Thrift::HeaderProtocol.new(transport3)

transport4 = Thrift::MemoryBuffer.new
header_compact_protocol = Thrift::HeaderProtocol.new(transport4, nil, Thrift::HeaderSubprotocolID::COMPACT)

transport5 = Thrift::MemoryBuffer.new
header_zlib_protocol = Thrift::HeaderProtocol.new(transport5)
header_zlib_protocol.add_transform(Thrift::HeaderTransformID::ZLIB)

ooe = Fixtures::Structs::OneOfEach.new
ooe.im_true   = true
ooe.im_false  = false
ooe.a_bite    = -42
ooe.integer16 = 27000
ooe.integer32 = 1<<24
ooe.integer64 = 6000 * 1000 * 1000
ooe.double_precision = Math::PI
ooe.some_characters  = "Debug THIS!"
ooe.zomg_unicode     = "\xd7\n\a\t"

n1 = Fixtures::Structs::Nested1.new
n1.a_list = []
n1.a_list << ooe << ooe << ooe << ooe
n1.i32_map = {}
n1.i32_map[1234] = ooe
n1.i32_map[46345] = ooe
n1.i32_map[-34264] = ooe
n1.i64_map = {}
n1.i64_map[43534986783945] = ooe
n1.i64_map[-32434639875122] = ooe
n1.dbl_map = {}
n1.dbl_map[324.65469834] = ooe
n1.dbl_map[-9458672340.4986798345112] = ooe
n1.str_map = {}
n1.str_map['sdoperuix'] = ooe
n1.str_map['pwoerxclmn'] = ooe

n2 = Fixtures::Structs::Nested2.new
n2.a_list = []
n2.a_list << n1 << n1 << n1 << n1 << n1
n2.i32_map = {}
n2.i32_map[398345] = n1
n2.i32_map[-2345] = n1
n2.i32_map[12312] = n1
n2.i64_map = {}
n2.i64_map[2349843765934] = n1
n2.i64_map[-123234985495] = n1
n2.i64_map[0] = n1
n2.dbl_map = {}
n2.dbl_map[23345345.38927834] = n1
n2.dbl_map[-1232349.5489345] = n1
n2.dbl_map[-234984574.23498725] = n1
n2.str_map = {}
n2.str_map[''] = n1
n2.str_map['sdflkertpioux'] = n1
n2.str_map['sdfwepwdcjpoi'] = n1

n3 = Fixtures::Structs::Nested3.new
n3.a_list = []
n3.a_list << n2 << n2 << n2 << n2 << n2
n3.i32_map = {}
n3.i32_map[398345] = n2
n3.i32_map[-2345] = n2
n3.i32_map[12312] = n2
n3.i64_map = {}
n3.i64_map[2349843765934] = n2
n3.i64_map[-123234985495] = n2
n3.i64_map[0] = n2
n3.dbl_map = {}
n3.dbl_map[23345345.38927834] = n2
n3.dbl_map[-1232349.5489345] = n2
n3.dbl_map[-234984574.23498725] = n2
n3.str_map = {}
n3.str_map[''] = n2
n3.str_map['sdflkertpioux'] = n2
n3.str_map['sdfwepwdcjpoi'] = n2

n4 = Fixtures::Structs::Nested4.new
n4.a_list = []
n4.a_list << n3
n4.i32_map = {}
n4.i32_map[-2345] = n3
n4.i64_map = {}
n4.i64_map[2349843765934] = n3
n4.dbl_map = {}
n4.dbl_map[-1232349.5489345] = n3
n4.str_map = {}
n4.str_map[''] = n3

# prof = RubyProf.profile do
#   n4.write(c_fast_binary_protocol)
#   Fixtures::Structs::Nested4.new.read(c_fast_binary_protocol)
# end
#
# printer = RubyProf::GraphHtmlPrinter.new(prof)
# printer.print(STDOUT, :min_percent=>0)

Benchmark.bmbm do |x|
  x.report("ruby write large (1MB) structure once") do
    n4.write(ruby_binary_protocol)
  end

  x.report("ruby read large (1MB) structure once") do
    Fixtures::Structs::Nested4.new.read(ruby_binary_protocol)
  end

  x.report("c write large (1MB) structure once") do
    n4.write(c_fast_binary_protocol)
  end

  x.report("c read large (1MB) structure once") do
    Fixtures::Structs::Nested4.new.read(c_fast_binary_protocol)
  end

  x.report("ruby write 10_000 small structures") do
    10_000.times do
      ooe.write(ruby_binary_protocol)
    end
  end

  x.report("ruby read 10_000 small structures") do
    10_000.times do
      Fixtures::Structs::OneOfEach.new.read(ruby_binary_protocol)
    end
  end

  x.report("c write 10_000 small structures") do
    10_000.times do
      ooe.write(c_fast_binary_protocol)
    end
  end

  x.report("c read 10_000 small structures") do
    10_000.times do
      Fixtures::Structs::OneOfEach.new.read(c_fast_binary_protocol)
    end
  end

  x.report("header (binary) write 10_000 small structures") do
    10_000.times do
      ooe.write(header_binary_protocol)
      header_binary_protocol.trans.flush
    end
  end

  x.report("header (binary) read 10_000 small structures") do
    10_000.times do
      Fixtures::Structs::OneOfEach.new.read(header_binary_protocol)
    end
  end

  x.report("header (compact) write 10_000 small structures") do
    10_000.times do
      ooe.write(header_compact_protocol)
      header_compact_protocol.trans.flush
    end
  end

  x.report("header (compact) read 10_000 small structures") do
    10_000.times do
      Fixtures::Structs::OneOfEach.new.read(header_compact_protocol)
    end
  end

  x.report("header (zlib) write 10_000 small structures") do
    10_000.times do
      ooe.write(header_zlib_protocol)
      header_zlib_protocol.trans.flush
    end
  end

  x.report("header (zlib) read 10_000 small structures") do
    10_000.times do
      Fixtures::Structs::OneOfEach.new.read(header_zlib_protocol)
    end
  end
end
thrift-0.23.0/test/rb/.rubocop.yml0000664000175000017500000000124015167543515017223 0ustar00buildbuild00000000000000plugins:
  - rubocop-performance
  - rubocop-rspec

AllCops:
  DisabledByDefault: true
  SuggestExtensions: false
  TargetRubyVersion: 2.7
  Exclude:
    - "**/vendor/**/*"

Layout/EmptyLines:
  Enabled: true

Layout/EmptyLinesAroundBlockBody:
  Enabled: true

Layout/ExtraSpacing:
  Enabled: true

Layout/IndentationConsistency:
  Enabled: true

Layout/LeadingCommentSpace:
  Enabled: true

Layout/LeadingEmptyLines:
  Enabled: true

Layout/SpaceAfterComma:
  Enabled: true

Layout/SpaceAroundEqualsInParameterDefault:
  Enabled: true

Layout/SpaceInsideBlockBraces:
  Enabled: true

Layout/TrailingEmptyLines:
  Enabled: true

Layout/TrailingWhitespace:
  Enabled: true
thrift-0.23.0/test/rb/fixtures/0000775000175000017500000000000015170007142016606 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/fixtures/structs.rb0000664000175000017500000002432715170007142020652 0ustar00buildbuild00000000000000#
# 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.
#

require 'thrift'

module Fixtures
  module Structs
    class OneBool
      include Thrift::Struct
      attr_accessor :bool
      FIELDS = {
        1 => {:type => Thrift::Types::BOOL, :name => 'bool'}
      }

      def validate
      end
    end

    class OneByte
      include Thrift::Struct
      attr_accessor :byte
      FIELDS = {
        1 => {:type => Thrift::Types::BYTE, :name => 'byte'}
      }

      def validate
      end
    end

    class OneI16
      include Thrift::Struct
      attr_accessor :i16
      FIELDS = {
        1 => {:type => Thrift::Types::I16, :name => 'i16'}
      }

      def validate
      end
    end

    class OneI32
      include Thrift::Struct
      attr_accessor :i32
      FIELDS = {
        1 => {:type => Thrift::Types::I32, :name => 'i32'}
      }

      def validate
      end
    end

    class OneI64
      include Thrift::Struct
      attr_accessor :i64
      FIELDS = {
        1 => {:type => Thrift::Types::I64, :name => 'i64'}
      }

      def validate
      end
    end

    class OneDouble
      include Thrift::Struct
      attr_accessor :double
      FIELDS = {
        1 => {:type => Thrift::Types::DOUBLE, :name => 'double'}
      }

      def validate
      end
    end

    class OneString
      include Thrift::Struct
      attr_accessor :string
      FIELDS = {
        1 => {:type => Thrift::Types::STRING, :name => 'string'}
      }

      def validate
      end
    end

    class OneMap
      include Thrift::Struct
      attr_accessor :map
      FIELDS = {
        1 => {:type => Thrift::Types::MAP, :name => 'map', :key => {:type => Thrift::Types::STRING}, :value => {:type => Thrift::Types::STRING}}
      }

      def validate
      end
    end

    class NestedMap
      include Thrift::Struct
      attr_accessor :map
      FIELDS = {
        0 => {:type => Thrift::Types::MAP, :name => 'map', :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::MAP, :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::I32}}}
      }

      def validate
      end
    end

    class OneList
      include Thrift::Struct
      attr_accessor :list
      FIELDS = {
        1 => {:type => Thrift::Types::LIST, :name => 'list', :element => {:type => Thrift::Types::STRING}}
      }

      def validate
      end
    end

    class NestedList
      include Thrift::Struct
      attr_accessor :list
      FIELDS = {
        0 => {:type => Thrift::Types::LIST, :name => 'list', :element => {:type => Thrift::Types::LIST, :element => { :type => Thrift::Types::I32 } } }
      }

      def validate
      end
    end

    class OneSet
      include Thrift::Struct
      attr_accessor :set
      FIELDS = {
        1 => {:type => Thrift::Types::SET, :name => 'set', :element => {:type => Thrift::Types::STRING}}
      }

      def validate
      end
    end

    class NestedSet
      include Thrift::Struct
      attr_accessor :set
      FIELDS = {
        1 => {:type => Thrift::Types::SET, :name => 'set', :element => {:type => Thrift::Types::SET, :element => { :type => Thrift::Types::STRING } }}
      }

      def validate
      end
    end

    # struct OneOfEach {
    #   1: bool im_true,
    #   2: bool im_false,
    #   3: byte a_bite,
    #   4: i16 integer16,
    #   5: i32 integer32,
    #   6: i64 integer64,
    #   7: double double_precision,
    #   8: string some_characters,
    #   9: string zomg_unicode,
    #   10: bool what_who,
    #   11: binary base64,
    # }
    class OneOfEach
      include Thrift::Struct
      attr_accessor :im_true, :im_false, :a_bite, :integer16, :integer32, :integer64, :double_precision, :some_characters, :zomg_unicode, :what_who, :base64
      FIELDS = {
        1 => {:type => Thrift::Types::BOOL, :name => 'im_true'},
        2 => {:type => Thrift::Types::BOOL, :name => 'im_false'},
        3 => {:type => Thrift::Types::BYTE, :name => 'a_bite'},
        4 => {:type => Thrift::Types::I16, :name => 'integer16'},
        5 => {:type => Thrift::Types::I32, :name => 'integer32'},
        6 => {:type => Thrift::Types::I64, :name => 'integer64'},
        7 => {:type => Thrift::Types::DOUBLE, :name => 'double_precision'},
        8 => {:type => Thrift::Types::STRING, :name => 'some_characters'},
        9 => {:type => Thrift::Types::STRING, :name => 'zomg_unicode'},
        10 => {:type => Thrift::Types::BOOL, :name => 'what_who'},
        11 => {:type => Thrift::Types::STRING, :name => 'base64'}
      }

      # Added for assert_equal
      def ==(other)
        [:im_true, :im_false, :a_bite, :integer16, :integer32, :integer64, :double_precision, :some_characters, :zomg_unicode, :what_who, :base64].each do |f|
          var = "@#{f}"
          return false if instance_variable_get(var) != other.instance_variable_get(var)
        end
        true
      end

      def validate
      end
    end

    # struct Nested1 {
    #   1: list a_list
    #   2: map i32_map
    #   3: map i64_map
    #   4: map dbl_map
    #   5: map str_map
    # }
    class Nested1
      include Thrift::Struct
      attr_accessor :a_list, :i32_map, :i64_map, :dbl_map, :str_map
      FIELDS = {
        1 => {:type => Thrift::Types::LIST, :name => 'a_list', :element => {:type => Thrift::Types::STRUCT, :class => OneOfEach}},
        2 => {:type => Thrift::Types::MAP, :name => 'i32_map', :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::STRUCT, :class => OneOfEach}},
        3 => {:type => Thrift::Types::MAP, :name => 'i64_map', :key => {:type => Thrift::Types::I64}, :value => {:type => Thrift::Types::STRUCT, :class => OneOfEach}},
        4 => {:type => Thrift::Types::MAP, :name => 'dbl_map', :key => {:type => Thrift::Types::DOUBLE}, :value => {:type => Thrift::Types::STRUCT, :class => OneOfEach}},
        5 => {:type => Thrift::Types::MAP, :name => 'str_map', :key => {:type => Thrift::Types::STRING}, :value => {:type => Thrift::Types::STRUCT, :class => OneOfEach}}
      }

      def validate
      end
    end

    # struct Nested2 {
    #   1: list a_list
    #   2: map i32_map
    #   3: map i64_map
    #   4: map dbl_map
    #   5: map str_map
    # }
    class Nested2
      include Thrift::Struct
      attr_accessor :a_list, :i32_map, :i64_map, :dbl_map, :str_map
      FIELDS = {
        1 => {:type => Thrift::Types::LIST, :name => 'a_list', :element => {:type => Thrift::Types::STRUCT, :class => Nested1}},
        2 => {:type => Thrift::Types::MAP, :name => 'i32_map', :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::STRUCT, :class => Nested1}},
        3 => {:type => Thrift::Types::MAP, :name => 'i64_map', :key => {:type => Thrift::Types::I64}, :value => {:type => Thrift::Types::STRUCT, :class => Nested1}},
        4 => {:type => Thrift::Types::MAP, :name => 'dbl_map', :key => {:type => Thrift::Types::DOUBLE}, :value => {:type => Thrift::Types::STRUCT, :class => Nested1}},
        5 => {:type => Thrift::Types::MAP, :name => 'str_map', :key => {:type => Thrift::Types::STRING}, :value => {:type => Thrift::Types::STRUCT, :class => Nested1}}
      }

      def validate
      end
    end

    # struct Nested3 {
    #   1: list a_list
    #   2: map i32_map
    #   3: map i64_map
    #   4: map dbl_map
    #   5: map str_map
    # }
    class Nested3
      include Thrift::Struct
      attr_accessor :a_list, :i32_map, :i64_map, :dbl_map, :str_map
      FIELDS = {
        1 => {:type => Thrift::Types::LIST, :name => 'a_list', :element => {:type => Thrift::Types::STRUCT, :class => Nested2}},
        2 => {:type => Thrift::Types::MAP, :name => 'i32_map', :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::STRUCT, :class => Nested2}},
        3 => {:type => Thrift::Types::MAP, :name => 'i64_map', :key => {:type => Thrift::Types::I64}, :value => {:type => Thrift::Types::STRUCT, :class => Nested2}},
        4 => {:type => Thrift::Types::MAP, :name => 'dbl_map', :key => {:type => Thrift::Types::DOUBLE}, :value => {:type => Thrift::Types::STRUCT, :class => Nested2}},
        5 => {:type => Thrift::Types::MAP, :name => 'str_map', :key => {:type => Thrift::Types::STRING}, :value => {:type => Thrift::Types::STRUCT, :class => Nested2}}
      }

      def validate
      end
    end

    # struct Nested4 {
    #   1: list a_list
    #   2: map i32_map
    #   3: map i64_map
    #   4: map dbl_map
    #   5: map str_map
    # }
    class Nested4
      include Thrift::Struct
      attr_accessor :a_list, :i32_map, :i64_map, :dbl_map, :str_map
      FIELDS = {
        1 => {:type => Thrift::Types::LIST, :name => 'a_list', :element => {:type => Thrift::Types::STRUCT, :class => Nested3}},
        2 => {:type => Thrift::Types::MAP, :name => 'i32_map', :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::STRUCT, :class => Nested3}},
        3 => {:type => Thrift::Types::MAP, :name => 'i64_map', :key => {:type => Thrift::Types::I64}, :value => {:type => Thrift::Types::STRUCT, :class => Nested3}},
        4 => {:type => Thrift::Types::MAP, :name => 'dbl_map', :key => {:type => Thrift::Types::DOUBLE}, :value => {:type => Thrift::Types::STRUCT, :class => Nested3}},
        5 => {:type => Thrift::Types::MAP, :name => 'str_map', :key => {:type => Thrift::Types::STRING}, :value => {:type => Thrift::Types::STRUCT, :class => Nested3}}
      }

      def validate
      end
    end
  end
end
thrift-0.23.0/test/rb/integration/0000775000175000017500000000000015167543515017277 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/integration/TestClient.rb0000775000175000017500000003121715167543515021711 0ustar00buildbuild00000000000000#!/usr/bin/env ruby
# encoding: utf-8

#
# 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.
#

$:.push File.dirname(__FILE__) + '/..'

require 'test_helper'
require 'thrift'
require 'thrift_test'

$domain_socket = nil
$host = "localhost"
$port = 9090
$protocolType = "binary"
$ssl = false
$transport = "buffered"

ARGV.each do|a|
  if a == "--help"
    puts "Allowed options:"
    puts "\t -h [ --help ] \t produce help message"
    puts "\t--domain-socket arg (=) \t Unix domain socket path"
    puts "\t--host arg (=localhost) \t Host to connect \t not valid with domain-socket"
    puts "\t--port arg (=9090) \t Port number to listen \t not valid with domain-socket"
    puts "\t--protocol arg (=binary) \t protocol: accel, binary, compact, json, header"
    puts "\t--ssl \t use ssl \t not valid with domain-socket"
    puts "\t--transport arg (=buffered) transport: buffered, framed, header, http"
    exit
  elsif a.start_with?("--domain-socket")
    $domain_socket = a.split("=")[1]
  elsif a.start_with?("--host")
    $host = a.split("=")[1]
  elsif a.start_with?("--protocol")
    $protocolType = a.split("=")[1]
  elsif a == "--ssl"
    $ssl = true
  elsif a.start_with?("--transport")
    $transport = a.split("=")[1]
  elsif a.start_with?("--port")
    $port = a.split("=")[1].to_i
  end
end

class SimpleClientTest < Test::Unit::TestCase
  def setup
    unless @socket
      if $domain_socket.to_s.strip.empty?
        if $ssl
          # the working directory for ruby crosstest is test/rb/gen-rb
          keysDir = File.join(File.dirname(File.dirname(Dir.pwd)), "keys")
          ctx = OpenSSL::SSL::SSLContext.new
          ctx.ca_file = File.join(keysDir, "CA.pem")
          ctx.cert = OpenSSL::X509::Certificate.new(File.open(File.join(keysDir, "client.crt")))
          ctx.cert_store = OpenSSL::X509::Store.new
          ctx.cert_store.add_file(File.join(keysDir, 'server.pem'))
          ctx.key = OpenSSL::PKey::RSA.new(File.open(File.join(keysDir, "client.key")))
          ctx.options = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
          ctx.ssl_version = :SSLv23
          ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
          @socket = Thrift::SSLSocket.new($host, $port, nil, ctx)
        else
          @socket = Thrift::Socket.new($host, $port)
        end
      else
        @socket = Thrift::UNIXSocket.new($domain_socket)
      end

      if $transport == "buffered"
        transportFactory = Thrift::BufferedTransport.new(@socket)
      elsif $transport == "framed"
        transportFactory = Thrift::FramedTransport.new(@socket)
      elsif $transport == "header"
        transportFactory = Thrift::HeaderTransport.new(@socket)
      else
        raise 'Unknown transport type'
      end

      if $protocolType == "binary"
        @protocol = Thrift::BinaryProtocol.new(transportFactory)
      elsif $protocolType == "compact"
        @protocol = Thrift::CompactProtocol.new(transportFactory)
      elsif $protocolType == "json"
        @protocol = Thrift::JsonProtocol.new(transportFactory)
      elsif $protocolType == "accel"
        @protocol = Thrift::BinaryProtocolAccelerated.new(transportFactory)
      elsif $protocolType == "header"
        # HeaderProtocol wraps its own transport, so pass the selected transport
        @protocol = Thrift::HeaderProtocol.new(transportFactory)
      else
        raise 'Unknown protocol type'
      end
      @client = Thrift::Test::ThriftTest::Client.new(@protocol)
      @socket.open
    end
  end

  def teardown
    @socket.close
  end

  def test_void
    p 'test_void'
    @client.testVoid()
  end

  def test_string
    p 'test_string'
    test_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: !@#$%&()(&%$#{}{}<><><' +
      ' char-to-test-json-parsing: ]] \"]] \\" }}}{ [[[ '
    test_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, 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ú, 粵語"

    result_string = @client.testString(test_string)
    assert_equal(test_string, result_string.force_encoding(Encoding::UTF_8))
  end

  def test_bool
    p 'test_bool'
    assert_equal(@client.testBool(true), true)
    assert_equal(@client.testBool(false), false)
  end

  def test_byte
    p 'test_byte'
    val = 120
    assert_equal(@client.testByte(val), val)
    assert_equal(@client.testByte(-val), -val)
  end

  def test_i32
    p 'test_i32'
    val = 2000000032
    assert_equal(@client.testI32(val), val)
    assert_equal(@client.testI32(-val), -val)
  end

  def test_i64
    p 'test_i64'
    val = 9000000000000000064
    assert_equal(@client.testI64(val), val)
    assert_equal(@client.testI64(-val), -val)
  end

  def test_double
    p 'test_double'
    val = 3.14159265358979323846
    assert_equal(@client.testDouble(val), val)
    assert_equal(@client.testDouble(-val), -val)
    assert_kind_of(Float, @client.testDouble(val))
  end

  def test_binary
    p 'test_binary'
    val = (0...256).reverse_each.to_a
    ret = @client.testBinary(val.pack('C*'))
    assert_equal(val, ret.bytes.to_a)
  end

  def test_map
    p 'test_map'
    val = {1 => 1, 2 => 2, 3 => 3}
    assert_equal(@client.testMap(val), val)
    assert_kind_of(Hash, @client.testMap(val))
  end

  def test_string_map
    p 'test_string_map'
    val = {'a' => '2', 'b' => 'blah', 'some' => 'thing'}
    ret = @client.testStringMap(val)
    assert_equal(val, ret)
    assert_kind_of(Hash, ret)
  end

  def test_list
    p 'test_list'
    val = [1, 2, 3, 4, 5]
    assert_equal(@client.testList(val), val)
    assert_kind_of(Array, @client.testList(val))
  end

  def test_enum
    p 'test_enum'
    val = Thrift::Test::Numberz::SIX
    ret = @client.testEnum(val)

    assert_equal(ret, 6)
    assert_kind_of(Integer, ret)
  end

  def test_typedef
    p 'test_typedef'
    # UserId  testTypedef(1: UserId thing),
    assert_equal(@client.testTypedef(309858235082523), 309858235082523)
    assert_kind_of(Integer, @client.testTypedef(309858235082523))
    true
  end

  def test_set
    p 'test_set'
    val = Set.new([1, 2, 3])
    assert_equal(@client.testSet(val), val)
    assert_kind_of(Set, @client.testSet(val))
  end

  def get_struct
    Thrift::Test::Xtruct.new({'string_thing' => 'hi!', 'i32_thing' => 4 })
  end

  def test_uuid
    p 'test_uuid'
    val = '00112233-4455-6677-8899-aabbccddeeff'
    ret = @client.testUuid(val)
    assert_equal(ret, val)
    assert_kind_of(String, ret)
  end

  def test_struct
    p 'test_struct'
    ret = @client.testStruct(get_struct)

    # TODO: not sure what unspecified "default" requiredness values should be
    assert(ret.byte_thing == nil || ret.byte_thing == 0)
    assert(ret.i64_thing == nil || ret.i64_thing == 0)

    assert_equal(ret.string_thing, 'hi!')
    assert_equal(ret.i32_thing, 4)
    assert_kind_of(Thrift::Test::Xtruct, ret)
  end

  def test_nest
    p 'test_nest'
    struct2 = Thrift::Test::Xtruct2.new({'struct_thing' => get_struct, 'i32_thing' => 10})

    ret = @client.testNest(struct2)

    # TODO: not sure what unspecified "default" requiredness values should be
    assert(ret.struct_thing.byte_thing == nil || ret.struct_thing.byte_thing == 0)
    assert(ret.struct_thing.i64_thing == nil || ret.struct_thing.i64_thing == 0)

    assert_equal(ret.struct_thing.string_thing, 'hi!')
    assert_equal(ret.struct_thing.i32_thing, 4)
    assert_equal(ret.i32_thing, 10)

    assert_kind_of(Thrift::Test::Xtruct, ret.struct_thing)
    assert_kind_of(Thrift::Test::Xtruct2, ret)
  end

  def test_insanity
    p 'test_insanity'
    insane = Thrift::Test::Insanity.new({
      'userMap' => {
        Thrift::Test::Numberz::FIVE => 5,
        Thrift::Test::Numberz::EIGHT => 8,
      },
      'xtructs' => [
        Thrift::Test::Xtruct.new({
          'string_thing' => 'Goodbye4',
          'byte_thing' => 4,
          'i32_thing' => 4,
          'i64_thing' => 4,
        }),
        Thrift::Test::Xtruct.new({
          'string_thing' => 'Hello2',
          'byte_thing' => 2,
          'i32_thing' => 2,
          'i64_thing' => 2,
        })
      ]
    })

    ret = @client.testInsanity(insane)

    assert_equal(insane, ret[1][2])
    assert_equal(insane, ret[1][3])

    assert(ret[2][6].userMap == nil || ret[2][6].userMap.length == 0)
    assert(ret[2][6].xtructs == nil || ret[2][6].xtructs.length == 0)
  end

  def test_map_map
    p 'test_map_map'
    ret = @client.testMapMap(4)
    assert_kind_of(Hash, ret)
    expected = {
      -4 => {
        -4 => -4,
        -3 => -3,
        -2 => -2,
        -1 => -1,
      },
      4 => {
        4 => 4,
        3 => 3,
        2 => 2,
        1 => 1,
      }
    }
    assert_equal(expected, ret)
  end

  def test_multi
    p 'test_multi'
    ret = @client.testMulti(42, 4242, 424242, {1 => 'blah', 2 => 'thing'}, Thrift::Test::Numberz::EIGHT, 24)
    expected = Thrift::Test::Xtruct.new({
      :string_thing => 'Hello2',
      :byte_thing =>   42,
      :i32_thing =>    4242,
      :i64_thing =>    424242
    })
    assert_equal(expected, ret)
  end

  def test_exception
    p 'test_exception'
    assert_raise Thrift::Test::Xception do
      @client.testException('Xception')
    end
    begin
      @client.testException('TException')
    rescue => e
      assert e.class.ancestors.include?(Thrift::Exception)
    end
    assert_nothing_raised do
      @client.testException('test')
    end
  end

  def test_multi_exception
    p 'test_multi_exception'
    assert_raise Thrift::Test::Xception do
      @client.testMultiException("Xception", "test 1")
    end
    assert_raise Thrift::Test::Xception2 do
      @client.testMultiException("Xception2", "test 2")
    end
    assert_equal( @client.testMultiException("Success", "test 3").string_thing, "test 3")
  end

  def test_oneway
    p 'test_oneway'
    time1 = Time.now.to_f
    @client.testOneway(1)
    time2 = Time.now.to_f
    assert_operator (time2-time1), :<, 0.1
  end

end
thrift-0.23.0/test/rb/integration/TestServer.rb0000775000175000017500000001617415167543515021746 0ustar00buildbuild00000000000000#!/usr/bin/env ruby

#
# 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.
#

$:.push File.dirname(__FILE__) + '/..'

require 'test_helper'
require 'thrift'
require 'thrift_test'
require 'thrift_test_types'
require 'logger'
require 'optparse'

class SimpleHandler
  [:testVoid, :testString, :testBool, :testByte, :testI32, :testI64, :testDouble, :testBinary,
   :testStruct, :testMap, :testStringMap, :testSet, :testList, :testNest, :testEnum, :testTypedef,
   :testEnum, :testTypedef, :testMultiException, :testUuid].each do |meth|
    define_method(meth) do |thing|
      p meth
      p thing
      thing
    end
  end

  def testVoid()
  end

  def testInsanity(thing)
    return {
      1 => {
        2 => thing,
        3 => thing
      },
      2 => {
        6 => Thrift::Test::Insanity::new()
      }
    }
  end

  def testMapMap(thing)
    return {
      -4 => {
        -4 => -4,
        -3 => -3,
        -2 => -2,
        -1 => -1,
      },
      4 => {
        4 => 4,
        3 => 3,
        2 => 2,
        1 => 1,
      }
    }
  end

  def testMulti(arg0, arg1, arg2, arg3, arg4, arg5)
    return Thrift::Test::Xtruct.new({
      'string_thing' => 'Hello2',
      'byte_thing' => arg0,
      'i32_thing' => arg1,
      'i64_thing' => arg2,
    })
  end

  def testException(thing)
    if thing == "Xception"
      raise Thrift::Test::Xception, :errorCode => 1001, :message => thing
    elsif thing == "TException"
      raise Thrift::Exception, :message => thing
    else
      # no-op
    end
  end

  def testMultiException(arg0, arg1)
    if arg0 == "Xception2"
      raise Thrift::Test::Xception2, :errorCode => 2002, :struct_thing => ::Thrift::Test::Xtruct.new({ :string_thing => 'This is an Xception2' })
    elsif arg0 == "Xception"
      raise Thrift::Test::Xception, :errorCode => 1001, :message => 'This is an Xception'
    else
      return ::Thrift::Test::Xtruct.new({'string_thing' => arg1})
    end
  end

  def testOneway(arg0)
    sleep(arg0)
  end

end

options = {
  domain_socket: nil,
  port: 9090,
  protocol: 'binary',
  ssl: false,
  transport: 'buffered',
  server_type: 'threaded',
  workers: nil,
}

server_type_map = {
  'simple' => 'simple',
  'threaded' => 'threaded',
  'thread-pool' => 'thread-pool',
  'thread_pool' => 'thread-pool',
  'threadpool' => 'thread-pool',
  'nonblocking' => 'nonblocking',
  'tsimpleserver' => 'simple',
  'tthreadedserver' => 'threaded',
  'tthreadpoolserver' => 'thread-pool',
  'tnonblockingserver' => 'nonblocking',
}

parser = OptionParser.new do |opts|
  opts.banner = "Allowed options:"
  opts.on('-h', '--help', 'produce help message') do
    puts opts
    exit 0
  end
  opts.on('--domain-socket=PATH', String, 'Unix domain socket path') { |v| options[:domain_socket] = v }
  opts.on('--port=PORT', Integer, 'Port number to listen (not valid with domain-socket)') { |v| options[:port] = v }
  opts.on('--protocol=PROTO', String, 'protocol: accel, binary, compact, json, header') { |v| options[:protocol] = v }
  opts.on('--ssl', 'use ssl (not valid with domain-socket)') { options[:ssl] = true }
  opts.on('--transport=TRANSPORT', String, 'transport: buffered, framed, header') { |v| options[:transport] = v }
  opts.on('--server-type=TYPE', String, 'type of server: simple, thread-pool, threaded, nonblocking') { |v| options[:server_type] = v }
  opts.on('-n', '--workers=N', Integer, 'Number of workers (thread-pool/nonblocking)') { |v| options[:workers] = v }
end

begin
  parser.parse!(ARGV)
  if ARGV.length > 1
    raise OptionParser::InvalidOption, "Only one positional server type may be specified"
  end
rescue OptionParser::ParseError => e
  warn e.message
  warn parser
  exit 1
end

# Accept Python-style server type positional arg for compatibility.
options[:server_type] = ARGV.first unless ARGV.empty?
normalized_server_type = server_type_map[options[:server_type].to_s.downcase]
if normalized_server_type.nil?
  warn "Unknown server type '#{options[:server_type]}'"
  warn parser
  exit 1
end

if options[:ssl] && !options[:domain_socket].to_s.strip.empty?
  warn '--ssl is not valid with --domain-socket'
  exit 1
end

protocol_factory = case options[:protocol].to_s.strip
when '', 'binary'
  Thrift::BinaryProtocolFactory.new
when 'compact'
  Thrift::CompactProtocolFactory.new
when 'json'
  Thrift::JsonProtocolFactory.new
when 'accel'
  Thrift::BinaryProtocolAcceleratedFactory.new
when 'header'
  Thrift::HeaderProtocolFactory.new
else
  raise "Unknown protocol type '#{options[:protocol]}'"
end

transport_factory = case options[:transport].to_s.strip
when '', 'buffered'
  Thrift::BufferedTransportFactory.new
when 'framed'
  Thrift::FramedTransportFactory.new
when 'header'
  Thrift::HeaderTransportFactory.new
else
  raise "Unknown transport type '#{options[:transport]}'"
end

if normalized_server_type == 'nonblocking' && options[:transport] != 'framed'
  raise 'server-type nonblocking requires transport of framed'
end

handler = SimpleHandler.new
processor = Thrift::Test::ThriftTest::Processor.new(handler)

transport = nil
if options[:domain_socket].to_s.strip.empty?
  if options[:ssl]
    # the working directory for ruby crosstest is test/rb/gen-rb
    keysDir = File.join(File.dirname(File.dirname(Dir.pwd)), "keys")
    ctx = OpenSSL::SSL::SSLContext.new
    ctx.ca_file = File.join(keysDir, "CA.pem")
    ctx.cert = OpenSSL::X509::Certificate.new(File.binread(File.join(keysDir, "server.crt")))
    ctx.cert_store = OpenSSL::X509::Store.new
    ctx.cert_store.add_file(File.join(keysDir, 'client.pem'))
    ctx.key = OpenSSL::PKey::RSA.new(File.binread(File.join(keysDir, "server.key")))
    ctx.min_version = :TLS1_2
    ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
    transport = Thrift::SSLServerSocket.new(nil, options[:port], ctx)
  else
    transport = Thrift::ServerSocket.new(options[:port])
  end
else
  transport = Thrift::UNIXServerSocket.new(options[:domain_socket])
end

workers = options[:workers] || 20
server = case normalized_server_type
when 'simple'
  Thrift::SimpleServer.new(processor, transport, transport_factory, protocol_factory)
when 'threaded'
  Thrift::ThreadedServer.new(processor, transport, transport_factory, protocol_factory)
when 'thread-pool'
  Thrift::ThreadPoolServer.new(processor, transport, transport_factory, protocol_factory, workers)
when 'nonblocking'
  logger = Logger.new(STDERR)
  logger.level = Logger::WARN
  Thrift::NonblockingServer.new(processor, transport, transport_factory, protocol_factory, workers, logger)
end

puts "Starting TestServer #{server.to_s}"
server.serve
puts "done."
thrift-0.23.0/test/rb/test_helper.rb0000664000175000017500000000232615167543515017622 0ustar00buildbuild00000000000000#
# 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.
#

$:.unshift File.dirname(__FILE__) + '/gen-rb'
$:.unshift File.join(File.dirname(__FILE__), '../../lib/rb/lib')
$:.unshift File.join(File.dirname(__FILE__), '../../lib/rb/ext')

require 'test/unit'

module Thrift
  module Struct
    def ==(other)
      return false unless other.is_a? self.class
      self.class.const_get(:FIELDS).collect { |fid, data| data[:name] }.all? do |field|
        send(field) == other.send(field)
      end
    end
  end
end
thrift-0.23.0/test/rb/core/0000775000175000017500000000000015167543515015704 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/core/test_backwards_compatability.rb0000664000175000017500000000202315167543515024147 0ustar00buildbuild00000000000000#
# 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.
#

require File.join(File.dirname(__FILE__), '../test_helper')

require 'thrift'

class TestThriftException < Test::Unit::TestCase
  def test_has_accessible_message
    msg = "hi there thrift"
    assert_equal msg, Thrift::Exception.new(msg).message
  end
end
thrift-0.23.0/test/rb/core/transport/0000775000175000017500000000000015167543515017740 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/core/transport/test_transport.rb0000664000175000017500000000351715167543515023366 0ustar00buildbuild00000000000000#
# 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.
#

require File.join(File.dirname(__FILE__), '../../test_helper')

require 'thrift'
require 'stringio'

class DummyTransport < Thrift::BaseTransport
  def initialize(data)
    @data = StringIO.new(data)
  end

  def read(size)
    @data.read(size)
  end
end

# TTransport is basically an abstract class, but isn't raising NotImplementedError
class TestThriftTransport < Test::Unit::TestCase
  def setup
    @trans = Thrift::BaseTransport.new
  end

  def test_open?
    assert_nil @trans.open?
  end

  def test_open
    assert_nil @trans.open
  end

  def test_close
    assert_nil @trans.close
  end

  # TODO:
  # This doesn't necessarily test he right thing.
  # It _looks_ like read isn't guaranteed to return the length
  # you ask for and read_all is. This means our test needs to check
  # for blocking. -- Kevin Clark 3/27/08
  def test_read_all
    # Implements read
    t = DummyTransport.new("hello")
    assert_equal "hello", t.read_all(5)
  end

  def test_write
    assert_nil @trans.write(5) # arbitrary value
  end

  def test_flush
    assert_nil @trans.flush
  end
end
thrift-0.23.0/test/rb/core/test_accelerated_binary_protocol.rb0000664000175000017500000000203615167543515025012 0ustar00buildbuild00000000000000#
# 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.
#

require File.join(File.dirname(__FILE__), '../test_helper')

require 'thrift'

class TestThriftTransport < Test::Unit::TestCase
  def test_accelerated_protocol
    return if ENV['SKIP_BUILD_EXT'] == '1'
    assert defined?(Thrift::BinaryProtocolAccelerated)
  end
end
thrift-0.23.0/test/rb/core/test_exceptions.rb0000664000175000017500000000201515167543515021447 0ustar00buildbuild00000000000000#
# 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.
#

require File.join(File.dirname(__FILE__), '../test_helper')

require 'thrift'

class TestException < Test::Unit::TestCase
  def test_has_accessible_message
    msg = "hi there thrift"
    assert_equal msg, Thrift::Exception.new(msg).message
  end
end
thrift-0.23.0/test/rb/core/protocol/0000775000175000017500000000000015167543515017545 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/core/protocol/test_json_protocol.rb0000664000175000017500000001605315167543515024030 0ustar00buildbuild00000000000000#!/usr/bin/env ruby
#
# 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.
#
require File.expand_path('../../test_helper', __dir__)
require 'thrift'
require 'thread'

class TestJsonProtocol < Test::Unit::TestCase
  def test_different_data_types
    port = (ARGV[0] || 7070).to_i
    server_ready = Queue.new

    server_thread = Thread.new do
      socket = Thrift::ServerSocket.new(port)
      transport = nil

      socket.listen
      server_ready << true
      client = socket.accept
      transport = Thrift::BufferedTransport.new(client)
      protocol = Thrift::JsonProtocol.new(transport)

      results = {}
      results[:acc_json_string]  = protocol.read_json_string
      results[:acc_json_base64]  = protocol.read_json_base64

      protocol.read_json_array_start
      results[:acc_json_integer] = protocol.read_json_integer
      protocol.read_json_array_end

      protocol.read_json_array_start
      results[:acc_json_double] = protocol.read_json_double
      protocol.read_json_array_end

      results[:acc_message] = protocol.read_message_begin
      protocol.read_message_end

      results[:acc_field] = protocol.read_field_begin
      protocol.read_field_end

      results[:acc_map] = protocol.read_map_begin
      protocol.read_map_end

      results[:acc_map2] = protocol.read_map_begin
      protocol.read_map_end

      results[:acc_list] = protocol.read_list_begin
      protocol.read_list_end

      results[:acc_set] = protocol.read_set_begin
      protocol.read_set_end

      protocol.read_json_object_start
      results[:acc_bool] = protocol.read_bool
      protocol.read_json_object_end

      protocol.read_json_object_start
      results[:acc_byte] = protocol.read_byte
      protocol.read_json_object_end

      protocol.read_json_object_start
      results[:acc_i16] = protocol.read_i16
      protocol.read_json_object_end

      protocol.read_json_object_start
      results[:acc_i32] = protocol.read_i32
      protocol.read_json_object_end

      protocol.read_json_object_start
      results[:acc_i64] = protocol.read_i64
      protocol.read_json_object_end

      protocol.read_json_object_start
      results[:acc_double] = protocol.read_double
      protocol.read_json_object_end

      protocol.read_json_object_start
      results[:acc_string] = protocol.read_string
      protocol.read_json_object_end

      protocol.read_json_object_start
      acc_binary = protocol.read_binary
      results[:acc_binary] = acc_binary.bytes.to_a
      protocol.read_json_object_end

      results
    ensure
      transport&.close
      socket&.close
    end

    server_ready.pop

    socket = Thrift::Socket.new('localhost', port)
    transport = Thrift::BufferedTransport.new(socket)
    transport.open
    protocol = Thrift::JsonProtocol.new(transport)

    # acc_json_string
    protocol.write_json_string('hello_world123!@#$%')
    transport.flush

    # acc_json_base64
    protocol.write_json_base64('hello_world12233!@#$%')
    transport.flush

    protocol.write_json_array_start
    # acc_json_integer
    protocol.write_json_integer(2553369689)
    protocol.write_json_array_end
    transport.flush

    protocol.write_json_array_start
    # acc_json_double
    protocol.write_json_double(3.1415926)
    protocol.write_json_array_end
    transport.flush

    # acc_message
    protocol.write_message_begin('hello_world', 4, 455536)
    protocol.write_message_end
    transport.flush

    # acc_field
    protocol.write_field_begin("hello_world", Thrift::Types::I16, 5)
    protocol.write_field_end
    transport.flush

    # acc_map
    protocol.write_map_begin(Thrift::Types::I16, Thrift::Types::I32, 12)
    protocol.write_map_end
    transport.flush

    # acc_map2
    protocol.write_map_begin(Thrift::Types::I16, Thrift::Types::I32, 0)
    protocol.write_map_end
    transport.flush

    # acc_list
    protocol.write_list_begin(Thrift::Types::I32, 12)
    protocol.write_list_end
    transport.flush

    # acc_set
    protocol.write_set_begin(Thrift::Types::I32, 5)
    protocol.write_set_end
    transport.flush

    protocol.write_json_object_start
    # acc_bool
    protocol.write_bool(true)
    protocol.write_json_object_end
    transport.flush

    protocol.write_json_object_start
    # acc_byte
    protocol.write_byte(123)
    protocol.write_json_object_end
    transport.flush

    protocol.write_json_object_start
    # acc_i16
    protocol.write_i16(4203)
    protocol.write_json_object_end
    transport.flush

    protocol.write_json_object_start
    # acc_i32
    protocol.write_i32(2000000032)
    protocol.write_json_object_end
    transport.flush

    protocol.write_json_object_start
    # acc_i64
    protocol.write_i64(1844674407370955161)
    protocol.write_json_object_end
    transport.flush

    protocol.write_json_object_start
    # acc_double
    protocol.write_double(3.1415926)
    protocol.write_json_object_end
    transport.flush

    protocol.write_json_object_start
    # acc_string
    protocol.write_string("hello_world123456789!@#$%&")
    protocol.write_json_object_end
    transport.flush

    protocol.write_json_object_start
    val = (0...256).reverse_each.to_a
    # acc_binary
    protocol.write_binary(val.pack('C*'))
    protocol.write_json_object_end
    transport.flush

    transport.close

    server_results = server_thread.value
    assert_equal('hello_world123!@#$%', server_results[:acc_json_string])
    assert_equal('hello_world12233!@#$%', server_results[:acc_json_base64])
    assert_equal(2553369689, server_results[:acc_json_integer])
    assert_equal(3.1415926, server_results[:acc_json_double])
    assert_equal("[\"hello_world\", 4, 455536]", "#{server_results[:acc_message]}")
    assert_equal([nil, 6, 5], server_results[:acc_field])
    assert_equal("[6, 8, 12]", "#{server_results[:acc_map]}")
    assert_equal("[6, 8, 0]", "#{server_results[:acc_map2]}")
    assert_equal("[8, 12]", "#{server_results[:acc_list]}")
    assert_equal("[8, 5]", "#{server_results[:acc_set]}")
    assert_equal(true, server_results[:acc_bool])
    assert_equal(123, server_results[:acc_byte])
    assert_equal(4203, server_results[:acc_i16])
    assert_equal(2000000032, server_results[:acc_i32])
    assert_equal(1844674407370955161, server_results[:acc_i64])
    assert_equal(3.1415926, server_results[:acc_double])
    assert_equal("hello_world123456789!@#$%&", server_results[:acc_string])
    assert_equal((0...256).reverse_each.to_a, server_results[:acc_binary])
  end
end
thrift-0.23.0/test/rb/core/protocol/test_compact_protocol.rb0000664000175000017500000001243415167543515024504 0ustar00buildbuild00000000000000#!/usr/bin/env ruby
#
# 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.
#

require File.expand_path('../../test_helper', __dir__)
require 'thrift'
require 'thread'

class TestCompactProtocol < Test::Unit::TestCase
  def test_different_data_types
    port = (ARGV[0] || 9090).to_i
    server_ready = Queue.new

    server_thread = Thread.new do
      socket = Thrift::ServerSocket.new(port)
      transport = nil

      socket.listen
      server_ready << true
      client = socket.accept
      transport = Thrift::BufferedTransport.new(client)
      protocol = Thrift::CompactProtocol.new(transport)

      results = {}
      results[:acc_bool]   = protocol.read_bool
      results[:acc_boolf]  = protocol.read_bool
      results[:acc_byte]   = protocol.read_byte
      results[:acc_i16]    = protocol.read_i16
      results[:acc_i32]    = protocol.read_i32
      results[:acc_i64]    = protocol.read_i64
      results[:acc_double] = protocol.read_double
      results[:acc_string] = protocol.read_string

      acc_binary = protocol.read_binary
      results[:acc_binary] = acc_binary.bytes.to_a

      results[:acc_message] = protocol.read_message_begin
      protocol.read_message_end

      results[:acc_list] = protocol.read_list_begin
      protocol.read_list_end

      results[:acc_map1] = protocol.read_map_begin
      protocol.read_map_end

      results[:acc_map2] = protocol.read_map_begin
      protocol.read_map_end

      results[:acc_set] = protocol.read_set_begin
      protocol.read_set_end

      results[:acc_field1] = protocol.read_field_begin
      protocol.read_field_end

      results[:acc_field2] = protocol.read_field_begin
      protocol.read_field_end

      results
    ensure
      transport&.close
      socket&.close
    end

    server_ready.pop

    socket = Thrift::Socket.new('localhost', port)
    transport = Thrift::BufferedTransport.new(socket)
    transport.open
    protocol = Thrift::CompactProtocol.new(transport)

    # acc_bool
    protocol.write_bool(true)
    transport.flush

    # acc_boolf
    protocol.write_bool(false)
    transport.flush

    # acc_byte
    protocol.write_byte(123)
    transport.flush

    # acc_i16
    protocol.write_i16(4203)
    transport.flush

    # acc_i32
    protocol.write_i32(2000000032)
    transport.flush

    # acc_i64
    protocol.write_i64(1844674407370955161)
    transport.flush

    # acc_double
    protocol.write_double(3.1415926)
    transport.flush

    # acc_string
    protocol.write_string("hello_world123456789!@#$%&")
    transport.flush

    val = (0...256).reverse_each.to_a
    # acc_binary
    protocol.write_binary(val.pack('C*'))
    transport.flush

    # acc_message
    protocol.write_message_begin("hello_world", 140, 455536)
    protocol.write_message_end
    transport.flush

    # acc_list
    protocol.write_list_begin(Thrift::Types::I32, 12)
    protocol.write_list_end
    transport.flush

    # acc_map1
    protocol.write_map_begin(Thrift::Types::I16, Thrift::Types::I32, 12)
    protocol.write_map_end
    transport.flush

    # acc_map2
    protocol.write_map_begin(Thrift::Types::I16, Thrift::Types::I32, 0)
    protocol.write_map_end
    transport.flush

    # acc_set
    protocol.write_set_begin(Thrift::Types::I32, 5)
    protocol.write_set_end
    transport.flush

    # acc_field1
    protocol.write_field_begin("hello_world", Thrift::Types::I16, 5)
    protocol.write_field_stop
    transport.flush

    # acc_field2
    protocol.write_field_begin("hello_world", Thrift::Types::BOOL, 5)
    protocol.write_field_stop
    transport.flush

    transport.close

    server_results = server_thread.value
    assert_equal(true, server_results[:acc_bool])
    assert_equal(false, server_results[:acc_boolf])
    assert_equal(123, server_results[:acc_byte])
    assert_equal(4203, server_results[:acc_i16])
    assert_equal(2000000032, server_results[:acc_i32])
    assert_equal(1844674407370955161, server_results[:acc_i64])
    assert_equal(3.1415926, server_results[:acc_double])
    assert_kind_of(Float, server_results[:acc_double])
    assert_equal("hello_world123456789!@#$%&", server_results[:acc_string])
    assert_equal((0...256).reverse_each.to_a, server_results[:acc_binary])
    assert_equal(["hello_world", 4, 455536], server_results[:acc_message])
    assert_equal("[8, 12]", "#{server_results[:acc_list]}")
    assert_equal("[6, 8, 12]", "#{server_results[:acc_map1]}")
    assert_equal("[0, 0, 0]", "#{server_results[:acc_map2]}")
    assert_equal("[8, 5]", "#{server_results[:acc_set]}")
    assert_equal("[nil, 6, 5]", "#{server_results[:acc_field1]}")
    assert_equal("[nil, 0, 0]", "#{server_results[:acc_field2]}")
  end
end
thrift-0.23.0/test/rb/core/protocol/test_binary_protocol.rb0000664000175000017500000001174715167543515024350 0ustar00buildbuild00000000000000#!/usr/bin/env ruby
#
# 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.
#

require File.expand_path('../../test_helper', __dir__)
require 'thrift'
require 'thread'

class TestBinaryProtocol < Test::Unit::TestCase
  def test_different_data_types
    port = (ARGV[0] || 9090).to_i
    server_ready = Queue.new

    server_thread = Thread.new do
      socket = Thrift::ServerSocket.new(port)
      transport = nil

      socket.listen
      server_ready << true
      client = socket.accept
      transport = Thrift::BufferedTransport.new(client)
      protocol = Thrift::BinaryProtocol.new(transport)

      results = {}
      results[:acc_bool]   = protocol.read_bool
      results[:acc_boolf]  = protocol.read_bool
      results[:acc_byte]   = protocol.read_byte
      results[:acc_i16]    = protocol.read_i16
      results[:acc_i32]    = protocol.read_i32
      results[:acc_i64]    = protocol.read_i64
      results[:acc_double] = protocol.read_double
      results[:acc_string] = protocol.read_string

      acc_binary = protocol.read_binary
      results[:acc_binary] = acc_binary.bytes.to_a

      results[:acc_message] = protocol.read_message_begin
      protocol.read_message_end

      results[:acc_field] = protocol.read_field_begin
      protocol.read_field_end

      results[:acc_map] = protocol.read_map_begin
      protocol.read_map_end

      results[:acc_map2] = protocol.read_map_begin
      protocol.read_map_end

      results[:acc_list] = protocol.read_list_begin
      protocol.read_list_end

      results[:acc_set] = protocol.read_set_begin
      protocol.read_set_end

      results
    ensure
      transport&.close
      socket&.close
    end

    server_ready.pop

    socket = Thrift::Socket.new('localhost', port)
    transport = Thrift::BufferedTransport.new(socket)
    transport.open
    protocol = Thrift::BinaryProtocol.new(transport)

    # acc_bool
    protocol.write_bool(true)
    transport.flush

    # acc_boolf
    protocol.write_bool(false)
    transport.flush

    # acc_byte
    protocol.write_byte(123)
    transport.flush

    # acc_i16
    protocol.write_i16(4203)
    transport.flush

    # acc_i32
    protocol.write_i32(2000000032)
    transport.flush

    # acc_i64
    protocol.write_i64(1844674407370955161)
    transport.flush

    # acc_double
    protocol.write_double(3.1415926)
    transport.flush

    # acc_string
    protocol.write_string("hello_world123456789!@#$%&")
    transport.flush

    val = (0...256).reverse_each.to_a
    # acc_binary
    protocol.write_binary(val.pack('C*'))
    transport.flush

    # acc_message
    protocol.write_message_begin("hello_world", 4, 455536)
    protocol.write_message_end
    transport.flush

    # acc_field
    protocol.write_field_begin("hello_world", Thrift::Types::I16, 5)
    protocol.write_field_end
    transport.flush

    # acc_map
    protocol.write_map_begin(Thrift::Types::I16, Thrift::Types::I32, 12)
    protocol.write_map_end
    transport.flush

    # acc_map2
    protocol.write_map_begin(Thrift::Types::I16, Thrift::Types::I32, 0)
    protocol.write_map_end
    transport.flush

    # acc_list
    protocol.write_list_begin(Thrift::Types::I32, 12)
    protocol.write_list_end
    transport.flush

    # acc_set
    protocol.write_set_begin(Thrift::Types::I32, 5)
    protocol.write_set_end
    transport.flush

    transport.close

    server_results = server_thread.value
    assert_equal(true, server_results[:acc_bool])
    assert_equal(false, server_results[:acc_boolf])
    assert_equal(123, server_results[:acc_byte])
    assert_equal(4203, server_results[:acc_i16])
    assert_equal(2000000032, server_results[:acc_i32])
    assert_equal(1844674407370955161, server_results[:acc_i64])
    assert_equal(3.1415926, server_results[:acc_double])
    assert_kind_of(Float, server_results[:acc_double])
    assert_equal("hello_world123456789!@#$%&", server_results[:acc_string])
    assert_equal((0...256).reverse_each.to_a, server_results[:acc_binary])
    assert_equal(["hello_world", 4, 455536], server_results[:acc_message])
    assert_equal([nil, 6, 5], server_results[:acc_field])
    assert_equal("[6, 8, 12]", "#{server_results[:acc_map]}")
    assert_equal("[6, 8, 0]", "#{server_results[:acc_map2]}")
    assert_equal("[8, 12]", "#{server_results[:acc_list]}")
    assert_equal("[8, 5]", "#{server_results[:acc_set]}")
  end
end
thrift-0.23.0/test/rb/Gemfile0000664000175000017500000000043115170007142016226 0ustar00buildbuild00000000000000source "https://rubygems.org"

# Make sure all dependencies are in sync with the main library.
gem 'thrift', path: '../../lib/rb'

gem 'rack', '~> 2.2', '>= 2.2.23'
gem 'thin', '~> 1.7', '>= 1.7.2'
gem 'test-unit', '~> 3.2', '>= 3.2.7'

eval_gemfile "../../lib/rb/Gemfile.linters"
thrift-0.23.0/test/rb/generation/0000775000175000017500000000000015167543515017107 5ustar00buildbuild00000000000000thrift-0.23.0/test/rb/generation/test_struct.rb0000664000175000017500000000302215167543515022014 0ustar00buildbuild00000000000000#
# 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.
#

require File.join(File.dirname(__FILE__), '../test_helper')
require 'small_service'

class TestStructGeneration < Test::Unit::TestCase

  def test_default_values
    hello = TestNamespace::Hello.new

    assert_kind_of(TestNamespace::Hello, hello)
    assert_nil(hello.complexer)

    assert_equal(hello.simple, 53)
    assert_equal(hello.words, 'words')

    assert_kind_of(TestNamespace::Goodbyez, hello.thinz)
    assert_equal(hello.thinz.val, 36632)

    assert_kind_of(Hash, hello.complex)
    assert_equal(hello.complex, { 6243 => 632, 2355 => 532, 23 => 532})

    bool_passer = TestNamespace::BoolPasser.new(:value => false)
    assert_equal false, bool_passer.value
  end

  def test_goodbyez
    assert_equal(TestNamespace::Goodbyez.new.val, 325)
  end

end
thrift-0.23.0/test/rb/generation/test_enum.rb0000664000175000017500000000237415167543515021445 0ustar00buildbuild00000000000000#
# 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.
#

require File.join(File.dirname(__FILE__), '../test_helper')
require 'thrift_test'

class TestEnumGeneration < Test::Unit::TestCase
  include Thrift::Test
  def test_enum_valid_values
    assert_equal(Numberz::VALID_VALUES, Set.new([Numberz::ONE, Numberz::TWO, Numberz::THREE, Numberz::FIVE, Numberz::SIX, Numberz::EIGHT]))
  end

  def test_enum_hash
    Numberz::VALID_VALUES.each do |value|
      assert_equal(Numberz.const_get(Numberz::VALUE_MAP[value].to_sym), value)
    end
  end
end
thrift-0.23.0/test/rb/generation/test_recursive.rb0000664000175000017500000000260515165535636022510 0ustar00buildbuild00000000000000#
# 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.
#

require File.join(File.dirname(__FILE__), '../test_helper')
require 'recursive_types'

class TestRecursiveGeneration < Test::Unit::TestCase
  CHILD_ITEM = "child item"
  PARENT_ITEM = "parent item"

  def test_can_create_recursive_tree

    child_tree = RecTree.new
    child_tree.item = CHILD_ITEM

    parent_tree = RecTree.new
    parent_tree.item = PARENT_ITEM
    parent_tree.children = [child_tree]

    assert_equal(PARENT_ITEM, parent_tree.item)
    assert_equal(1, parent_tree.children.length)
    assert_equal(CHILD_ITEM, parent_tree.children.first.item)
    assert_nil(parent_tree.children.first.children)
  end
end
thrift-0.23.0/test/rb/Makefile0000644000175000017500000004426115170007175016410 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/rb/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#
# 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.
#

am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
subdir = test/rb
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = /thrift/src/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/rb
abs_srcdir = /thrift/src/test/rb
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..
all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/rb/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/rb/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am dist-hook distclean \
	distclean-generic distclean-libtool distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: $(THRIFT) ../ThriftTest.thrift ../SmallTest.thrift
	$(THRIFT) --gen rb ../ThriftTest.thrift
	$(THRIFT) --gen rb ../SmallTest.thrift
	$(THRIFT) --gen rb ../Recursive.thrift

precross: stubs

check: stubs
	$(BUNDLER) install
	$(BUNDLER) exec $(RUBY) -I. test_suite.rb

clean-local:
	$(RM) -r gen-rb/

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

dist-hook:
	$(RM) -r $(distdir)/gen-rb/

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/rb/Makefile.in0000644000175000017500000004327215170007167017017 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/rb
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/rb/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/rb/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
	$(MAKE) $(AM_MAKEFLAGS) \
	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
	  dist-hook
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am dist-hook distclean \
	distclean-generic distclean-libtool distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am install-info \
	install-info-am install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-generic \
	mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \
	tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: $(THRIFT) ../ThriftTest.thrift ../SmallTest.thrift
	$(THRIFT) --gen rb ../ThriftTest.thrift
	$(THRIFT) --gen rb ../SmallTest.thrift
	$(THRIFT) --gen rb ../Recursive.thrift

precross: stubs

check: stubs
@HAVE_BUNDLER_TRUE@	$(BUNDLER) install
@HAVE_BUNDLER_TRUE@	$(BUNDLER) exec $(RUBY) -I. test_suite.rb

clean-local:
	$(RM) -r gen-rb/

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

dist-hook:
	$(RM) -r $(distdir)/gen-rb/

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/rb/Makefile.am0000664000175000017500000000226015167543515017010 0ustar00buildbuild00000000000000#
# 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.
#

stubs: $(THRIFT) ../ThriftTest.thrift ../SmallTest.thrift
	$(THRIFT) --gen rb ../ThriftTest.thrift
	$(THRIFT) --gen rb ../SmallTest.thrift
	$(THRIFT) --gen rb ../Recursive.thrift

precross: stubs

check: stubs
if HAVE_BUNDLER
	$(BUNDLER) install
	$(BUNDLER) exec $(RUBY) -I. test_suite.rb
endif

clean-local:
	$(RM) -r gen-rb/

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

dist-hook:
	$(RM) -r $(distdir)/gen-rb/
thrift-0.23.0/test/rb/Gemfile.lock0000664000175000017500000000321115170007142017154 0ustar00buildbuild00000000000000PATH
  remote: ../../lib/rb
  specs:
    thrift (0.23.0)
      logger

GEM
  remote: https://rubygems.org/
  specs:
    ast (2.4.3)
    daemons (1.4.1)
    eventmachine (1.2.7)
    json (2.18.1)
    language_server-protocol (3.17.0.5)
    lint_roller (1.1.0)
    logger (1.7.0)
    parallel (1.27.0)
    parser (3.3.10.1)
      ast (~> 2.4.1)
      racc
    power_assert (3.0.1)
    prism (1.9.0)
    racc (1.8.1)
    rack (2.2.23)
    rainbow (3.1.1)
    regexp_parser (2.11.3)
    rubocop (1.82.1)
      json (~> 2.3)
      language_server-protocol (~> 3.17.0.2)
      lint_roller (~> 1.1.0)
      parallel (~> 1.10)
      parser (>= 3.3.0.2)
      rainbow (>= 2.2.2, < 4.0)
      regexp_parser (>= 2.9.3, < 3.0)
      rubocop-ast (>= 1.48.0, < 2.0)
      ruby-progressbar (~> 1.7)
      unicode-display_width (>= 2.4.0, < 4.0)
    rubocop-ast (1.49.0)
      parser (>= 3.3.7.2)
      prism (~> 1.7)
    rubocop-performance (1.26.1)
      lint_roller (~> 1.1)
      rubocop (>= 1.75.0, < 2.0)
      rubocop-ast (>= 1.47.1, < 2.0)
    rubocop-rspec (3.8.0)
      lint_roller (~> 1.1)
      rubocop (~> 1.81)
    ruby-progressbar (1.13.0)
    test-unit (3.7.3)
      power_assert
    thin (1.8.2)
      daemons (~> 1.0, >= 1.0.9)
      eventmachine (~> 1.0, >= 1.0.4)
      rack (>= 1, < 3)
    unicode-display_width (3.2.0)
      unicode-emoji (~> 4.1)
    unicode-emoji (4.2.0)

PLATFORMS
  arm64-darwin
  arm64-linux
  ruby
  x86_64-darwin
  x86_64-linux

DEPENDENCIES
  rack (~> 2.2, >= 2.2.23)
  rubocop (~> 1.82.0)
  rubocop-performance (~> 1.26.1)
  rubocop-rspec (~> 3.8.0)
  test-unit (~> 3.2, >= 3.2.7)
  thin (~> 1.7, >= 1.7.2)
  thrift!

BUNDLED WITH
   2.2.34
thrift-0.23.0/test/rb/test_suite.rb0000664000175000017500000000151215167543515017470 0ustar00buildbuild00000000000000#
# 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.
#

Dir["{core,generation}/**/*.rb"].each { |f| require f }
thrift-0.23.0/test/rs/0000775000175000017500000000000015170007175014764 5ustar00buildbuild00000000000000thrift-0.23.0/test/rs/src/0000775000175000017500000000000015165535636015567 5ustar00buildbuild00000000000000thrift-0.23.0/test/rs/src/bin/0000775000175000017500000000000015165535636016337 5ustar00buildbuild00000000000000thrift-0.23.0/test/rs/src/bin/test_client.rs0000664000175000017500000005264415165535636021235 0ustar00buildbuild00000000000000// 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.

use clap::{clap_app, value_t};
use log::*;

use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Debug;
use std::net::{TcpStream, ToSocketAddrs};

#[cfg(unix)]
use std::os::unix::net::UnixStream;
#[cfg(unix)]
use std::path::Path;

use thrift::protocol::{
    TBinaryInputProtocol, TBinaryOutputProtocol, TCompactInputProtocol, TCompactOutputProtocol,
    TInputProtocol, TMultiplexedOutputProtocol, TOutputProtocol,
};
use thrift::transport::{
    TBufferedReadTransport, TBufferedWriteTransport, TFramedReadTransport, TFramedWriteTransport,
    TIoChannel, TReadTransport, TTcpChannel, TWriteTransport,
};
use thrift::OrderedFloat;
use thrift_test::*;

type ThriftClientPair = (
    ThriftTestSyncClient, Box>,
    Option, Box>>,
);

fn main() {
    env_logger::init();

    debug!("initialized logger - running cross-test client");

    match run() {
        Ok(()) => info!("cross-test client succeeded"),
        Err(e) => {
            info!("cross-test client failed with error {:?}", e);
            std::process::exit(1);
        }
    }
}

fn run() -> thrift::Result<()> {
    // unsupported options:
    // --pipe
    // --anon-pipes
    // --ssl
    // --threads
    let matches = clap_app!(rust_test_client =>
        (version: "1.0")
        (author: "Apache Thrift Developers ")
        (about: "Rust Thrift test client")
        (@arg host: --host +takes_value "Host on which the Thrift test server is located")
        (@arg port: --port +takes_value "Port on which the Thrift test server is listening")
        (@arg domain_socket: --("domain-socket") +takes_value "Unix Domain Socket on which the Thrift test server is listening")
        (@arg protocol: --protocol +takes_value "Thrift protocol implementation to use (\"binary\", \"compact\", \"multi\", \"multic\")")
        (@arg transport: --transport +takes_value "Thrift transport implementation to use (\"buffered\", \"framed\")")
        (@arg testloops: -n --testloops +takes_value "Number of times to run tests")
    )
        .get_matches();

    let host = matches.value_of("host").unwrap_or("127.0.0.1");
    let port = value_t!(matches, "port", u16).unwrap_or(9090);
    let domain_socket = matches.value_of("domain_socket");
    let protocol = matches.value_of("protocol").unwrap_or("binary");
    let transport = matches.value_of("transport").unwrap_or("buffered");
    let testloops = value_t!(matches, "testloops", u8).unwrap_or(1);

    let (mut thrift_test_client, mut second_service_client) = match domain_socket {
        None => {
            let listen_address = format!("{}:{}", host, port);
            info!(
                "Client binds to {} with {}+{} stack",
                listen_address, protocol, transport
            );
            bind(listen_address.as_str(), protocol, transport)?
        }
        Some(domain_socket) => {
            info!(
                "Client binds to {} (UDS) with {}+{} stack",
                domain_socket, protocol, transport
            );
            bind_uds(domain_socket, protocol, transport)?
        }
    };

    for _ in 0..testloops {
        make_thrift_calls(&mut thrift_test_client, &mut second_service_client)?
    }

    Ok(())
}

fn bind(
    listen_address: A,
    protocol: &str,
    transport: &str,
) -> Result {
    // create a TCPStream that will be shared by all Thrift clients
    // service calls from multiple Thrift clients will be interleaved over the same connection
    // this isn't a problem for us because we're single-threaded and all calls block to completion
    let shared_stream = TcpStream::connect(listen_address)?;

    let second_service_client = if protocol.starts_with("multi") {
        let shared_stream_clone = shared_stream.try_clone()?;
        let channel = TTcpChannel::with_stream(shared_stream_clone);
        let (i_prot, o_prot) = build(channel, transport, protocol, "SecondService")?;
        Some(SecondServiceSyncClient::new(i_prot, o_prot))
    } else {
        None
    };

    let thrift_test_client = {
        let channel = TTcpChannel::with_stream(shared_stream);
        let (i_prot, o_prot) = build(channel, transport, protocol, "ThriftTest")?;
        ThriftTestSyncClient::new(i_prot, o_prot)
    };

    Ok((thrift_test_client, second_service_client))
}

#[cfg(unix)]
fn bind_uds>(
    domain_socket: P,
    protocol: &str,
    transport: &str,
) -> Result {
    // create a UnixStream that will be shared by all Thrift clients
    // service calls from multiple Thrift clients will be interleaved over the same connection
    // this isn't a problem for us because we're single-threaded and all calls block to completion
    let shared_stream = UnixStream::connect(domain_socket)?;

    let second_service_client = if protocol.starts_with("multi") {
        let shared_stream_clone = shared_stream.try_clone()?;
        let (i_prot, o_prot) = build(shared_stream_clone, transport, protocol, "SecondService")?;
        Some(SecondServiceSyncClient::new(i_prot, o_prot))
    } else {
        None
    };

    let thrift_test_client = {
        let (i_prot, o_prot) = build(shared_stream, transport, protocol, "ThriftTest")?;
        ThriftTestSyncClient::new(i_prot, o_prot)
    };

    Ok((thrift_test_client, second_service_client))
}

fn build(
    channel: C,
    transport: &str,
    protocol: &str,
    service_name: &str,
) -> thrift::Result<(Box, Box)> {
    let (i_chan, o_chan) = channel.split()?;

    let (i_tran, o_tran): (Box, Box) = match transport {
        "buffered" => (
            Box::new(TBufferedReadTransport::new(i_chan)),
            Box::new(TBufferedWriteTransport::new(o_chan)),
        ),
        "framed" => (
            Box::new(TFramedReadTransport::new(i_chan)),
            Box::new(TFramedWriteTransport::new(o_chan)),
        ),
        unmatched => return Err(format!("unsupported transport {}", unmatched).into()),
    };

    let (i_prot, o_prot): (Box, Box) = match protocol {
        "binary" => (
            Box::new(TBinaryInputProtocol::new(i_tran, true)),
            Box::new(TBinaryOutputProtocol::new(o_tran, true)),
        ),
        "multi" => (
            Box::new(TBinaryInputProtocol::new(i_tran, true)),
            Box::new(TMultiplexedOutputProtocol::new(
                service_name,
                TBinaryOutputProtocol::new(o_tran, true),
            )),
        ),
        "compact" => (
            Box::new(TCompactInputProtocol::new(i_tran)),
            Box::new(TCompactOutputProtocol::new(o_tran)),
        ),
        "multic" => (
            Box::new(TCompactInputProtocol::new(i_tran)),
            Box::new(TMultiplexedOutputProtocol::new(
                service_name,
                TCompactOutputProtocol::new(o_tran),
            )),
        ),
        unmatched => return Err(format!("unsupported protocol {}", unmatched).into()),
    };

    Ok((i_prot, o_prot))
}

type BuildThriftTestClient =
    ThriftTestSyncClient, Box>;
type BuiltSecondServiceClient =
    SecondServiceSyncClient, Box>;

#[allow(clippy::cognitive_complexity)]
fn make_thrift_calls(
    thrift_test_client: &mut BuildThriftTestClient,
    second_service_client: &mut Option,
) -> Result<(), thrift::Error> {
    info!("testVoid");
    thrift_test_client.test_void()?;

    info!("testString");
    verify_expected_result(
        thrift_test_client.test_string("thing".to_owned()),
        "thing".to_owned(),
    )?;

    info!("testUuid");
    verify_expected_result(
        thrift_test_client.test_uuid(uuid::uuid!("00010203-0405-0607-0809-0a0b0c0d0e0f")),
        uuid::uuid!("00010203-0405-0607-0809-0a0b0c0d0e0f"),
    )?;

    info!("testBool");
    verify_expected_result(thrift_test_client.test_bool(true), true)?;

    info!("testBool");
    verify_expected_result(thrift_test_client.test_bool(false), false)?;

    info!("testByte");
    verify_expected_result(thrift_test_client.test_byte(42), 42)?;

    info!("testi32");
    verify_expected_result(thrift_test_client.test_i32(1_159_348_374), 1_159_348_374)?;

    info!("testi64");
    // try!(verify_expected_result(thrift_test_client.test_i64(-8651829879438294565),
    // -8651829879438294565));
    verify_expected_result(thrift_test_client.test_i64(i64::MIN), i64::MIN)?;

    info!("testDouble");
    verify_expected_result(
        thrift_test_client.test_double(OrderedFloat::from(42.42)),
        OrderedFloat::from(42.42),
    )?;

    info!("testTypedef");
    {
        let u_snd: UserId = 2348;
        let u_cmp: UserId = 2348;
        verify_expected_result(thrift_test_client.test_typedef(u_snd), u_cmp)?;
    }

    info!("testEnum");
    {
        verify_expected_result(thrift_test_client.test_enum(Numberz::TWO), Numberz::TWO)?;
    }

    info!("testBinary");
    {
        let b_snd = vec![0x77, 0x30, 0x30, 0x74, 0x21, 0x20, 0x52, 0x75, 0x73, 0x74];
        let b_cmp = vec![0x77, 0x30, 0x30, 0x74, 0x21, 0x20, 0x52, 0x75, 0x73, 0x74];
        verify_expected_result(thrift_test_client.test_binary(b_snd), b_cmp)?;
    }

    info!("testStruct");
    {
        let x_snd = Xtruct {
            string_thing: Some("foo".to_owned()),
            byte_thing: Some(12),
            i32_thing: Some(219_129),
            i64_thing: Some(12_938_492_818),
        };
        let x_cmp = Xtruct {
            string_thing: Some("foo".to_owned()),
            byte_thing: Some(12),
            i32_thing: Some(219_129),
            i64_thing: Some(12_938_492_818),
        };
        verify_expected_result(thrift_test_client.test_struct(x_snd), x_cmp)?;
    }

    // Xtruct again, with optional values
    // FIXME: apparently the erlang thrift server does not like opt-in-req-out
    // parameters that are undefined. Joy.
    // {
    // let x_snd = Xtruct { string_thing: Some("foo".to_owned()), byte_thing: None,
    // i32_thing: None, i64_thing: Some(12938492818) };
    // let x_cmp = Xtruct { string_thing: Some("foo".to_owned()), byte_thing:
    // Some(0), i32_thing: Some(0), i64_thing: Some(12938492818) }; // the C++
    // server is responding correctly
    // try!(verify_expected_result(thrift_test_client.test_struct(x_snd), x_cmp));
    // }
    //

    info!("testNest"); // (FIXME: try Xtruct2 with optional values)
    {
        let x_snd = Xtruct2 {
            byte_thing: Some(32),
            struct_thing: Some(Xtruct {
                string_thing: Some("foo".to_owned()),
                byte_thing: Some(1),
                i32_thing: Some(324_382_098),
                i64_thing: Some(12_938_492_818),
            }),
            i32_thing: Some(293_481_098),
        };
        let x_cmp = Xtruct2 {
            byte_thing: Some(32),
            struct_thing: Some(Xtruct {
                string_thing: Some("foo".to_owned()),
                byte_thing: Some(1),
                i32_thing: Some(324_382_098),
                i64_thing: Some(12_938_492_818),
            }),
            i32_thing: Some(293_481_098),
        };
        verify_expected_result(thrift_test_client.test_nest(x_snd), x_cmp)?;
    }

    // do the multiplexed calls while making the main ThriftTest calls
    if let Some(ref mut client) = second_service_client.as_mut() {
        info!("SecondService secondtestString");
        {
            verify_expected_result(
                client.secondtest_string("test_string".to_owned()),
                "testString(\"test_string\")".to_owned(),
            )?;
        }
    }

    info!("testList");
    {
        let v_snd: Vec = vec![29384, 238, 32498];

        let v_cmp: Vec = vec![29384, 238, 32498];

        verify_expected_result(thrift_test_client.test_list(v_snd), v_cmp)?;
    }

    info!("testSet");
    {
        let s_snd: BTreeSet = BTreeSet::from([293_481, 23, 3234]);

        let s_cmp: BTreeSet = BTreeSet::from([293_481, 23, 3234]);

        verify_expected_result(thrift_test_client.test_set(s_snd), s_cmp)?;
    }

    info!("testMap");
    {
        let m_snd: BTreeMap = BTreeMap::from([(2, 4), (4, 6), (8, 7)]);

        let m_cmp: BTreeMap = BTreeMap::from([(2, 4), (4, 6), (8, 7)]);

        verify_expected_result(thrift_test_client.test_map(m_snd), m_cmp)?;
    }

    info!("testStringMap");
    {
        let m_snd: BTreeMap = BTreeMap::from([
            ("2".to_owned(), "4_string".to_owned()),
            ("4".to_owned(), "6_string".to_owned()),
            ("8".to_owned(), "7_string".to_owned()),
        ]);

        let m_rcv: BTreeMap = BTreeMap::from([
            ("2".to_owned(), "4_string".to_owned()),
            ("4".to_owned(), "6_string".to_owned()),
            ("8".to_owned(), "7_string".to_owned()),
        ]);

        verify_expected_result(thrift_test_client.test_string_map(m_snd), m_rcv)?;
    }

    // nested map
    // expect : {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2
    // => 2, 3 => 3, 4 => 4, }, }
    info!("testMapMap");
    {
        let m_cmp_nested_0: BTreeMap = (-4..0).map(|i| (i, i)).collect();
        let m_cmp_nested_1: BTreeMap = (1..5).map(|i| (i, i)).collect();

        let m_cmp: BTreeMap> =
            BTreeMap::from([(-4, m_cmp_nested_0), (4, m_cmp_nested_1)]);

        verify_expected_result(thrift_test_client.test_map_map(42), m_cmp)?;
    }

    info!("testMulti");
    {
        let m_snd: BTreeMap =
            BTreeMap::from([(1298, "fizz".to_owned()), (-148, "buzz".to_owned())]);

        let s_cmp = Xtruct {
            string_thing: Some("Hello2".to_owned()),
            byte_thing: Some(1),
            i32_thing: Some(-123_948),
            i64_thing: Some(-19_234_123_981),
        };

        verify_expected_result(
            thrift_test_client.test_multi(1, -123_948, -19_234_123_981, m_snd, Numberz::EIGHT, 81),
            s_cmp,
        )?;
    }

    // Insanity
    // returns:
    // { 1 => { 2 => argument,
    //          3 => argument,
    //        },
    //   2 => { 6 => , },
    // }
    {
        let arg_map_usermap: BTreeMap =
            BTreeMap::from([(Numberz::ONE, 4289), (Numberz::EIGHT, 19)]);

        let arg_vec_xtructs: Vec = vec![
            Xtruct {
                string_thing: Some("foo".to_owned()),
                byte_thing: Some(8),
                i32_thing: Some(29),
                i64_thing: Some(92384),
            },
            Xtruct {
                string_thing: Some("bar".to_owned()),
                byte_thing: Some(28),
                i32_thing: Some(2),
                i64_thing: Some(-1281),
            },
            Xtruct {
                string_thing: Some("baz".to_owned()),
                byte_thing: Some(0),
                i32_thing: Some(3_948_539),
                i64_thing: Some(-12_938_492),
            },
        ];

        let insanity = Insanity {
            user_map: Some(arg_map_usermap),
            xtructs: Some(arg_vec_xtructs),
        };
        let s_cmp_nested_1: BTreeMap = BTreeMap::from([
            (Numberz::TWO, insanity.clone()),
            (Numberz::THREE, insanity.clone()),
        ]);

        let empty_insanity = Insanity {
            user_map: Some(BTreeMap::new()),
            xtructs: Some(Vec::new()),
        };
        let s_cmp_nested_2: BTreeMap =
            BTreeMap::from([(Numberz::SIX, empty_insanity)]);

        let s_cmp: BTreeMap> =
            BTreeMap::from([(1, s_cmp_nested_1), (2, s_cmp_nested_2)]);

        verify_expected_result(thrift_test_client.test_insanity(insanity), s_cmp)?;
    }

    info!("testException - remote throws Xception");
    {
        let r = thrift_test_client.test_exception("Xception".to_owned());
        let x = match r {
            Err(thrift::Error::User(ref e)) => match e.downcast_ref::() {
                Some(x) => Ok(x),
                None => Err(thrift::Error::User(
                    "did not get expected Xception struct".into(),
                )),
            },
            _ => Err(thrift::Error::User("did not get exception".into())),
        }?;

        let x_cmp = Xception {
            error_code: Some(1001),
            message: Some("Xception".to_owned()),
        };

        verify_expected_result(Ok(x), &x_cmp)?;
    }

    info!("testException - remote throws TApplicationException");
    {
        let r = thrift_test_client.test_exception("TException".to_owned());
        match r {
            Err(thrift::Error::Application(ref e)) => {
                info!("received an {:?}", e);
                Ok(())
            }
            _ => Err(thrift::Error::User("did not get exception".into())),
        }?;
    }

    info!("testException - remote succeeds");
    {
        let r = thrift_test_client.test_exception("foo".to_owned());
        match r {
            Ok(_) => Ok(()),
            _ => Err(thrift::Error::User("received an exception".into())),
        }?;
    }

    info!("testMultiException - remote throws Xception");
    {
        let r =
            thrift_test_client.test_multi_exception("Xception".to_owned(), "ignored".to_owned());
        let x = match r {
            Err(thrift::Error::User(ref e)) => match e.downcast_ref::() {
                Some(x) => Ok(x),
                None => Err(thrift::Error::User(
                    "did not get expected Xception struct".into(),
                )),
            },
            _ => Err(thrift::Error::User("did not get exception".into())),
        }?;

        let x_cmp = Xception {
            error_code: Some(1001),
            message: Some("This is an Xception".to_owned()),
        };

        verify_expected_result(Ok(x), &x_cmp)?;
    }

    info!("testMultiException - remote throws Xception2");
    {
        let r =
            thrift_test_client.test_multi_exception("Xception2".to_owned(), "ignored".to_owned());
        let x = match r {
            Err(thrift::Error::User(ref e)) => match e.downcast_ref::() {
                Some(x) => Ok(x),
                None => Err(thrift::Error::User(
                    "did not get expected Xception struct".into(),
                )),
            },
            _ => Err(thrift::Error::User("did not get exception".into())),
        }?;

        let x_cmp = Xception2 {
            error_code: Some(2002),
            struct_thing: Some(Xtruct {
                string_thing: Some("This is an Xception2".to_owned()),
                // since this is an OPT_IN_REQ_OUT field the sender sets a default
                byte_thing: Some(0),
                // since this is an OPT_IN_REQ_OUT field the sender sets a default
                i32_thing: Some(0),
                // since this is an OPT_IN_REQ_OUT field the sender sets a default
                i64_thing: Some(0),
            }),
        };

        verify_expected_result(Ok(x), &x_cmp)?;
    }

    info!("testMultiException - remote succeeds");
    {
        let r = thrift_test_client.test_multi_exception("haha".to_owned(), "RETURNED".to_owned());
        let x = match r {
            Err(e) => Err(thrift::Error::User(
                format!("received an unexpected exception {:?}", e).into(),
            )),
            _ => r,
        }?;

        let x_cmp = Xtruct {
            string_thing: Some("RETURNED".to_owned()),
            // since this is an OPT_IN_REQ_OUT field the sender sets a default
            byte_thing: Some(0),
            // since this is an OPT_IN_REQ_OUT field the sender sets a default
            i32_thing: Some(0),
            // since this is an OPT_IN_REQ_OUT field the sender sets a default
            i64_thing: Some(0),
        };

        verify_expected_result(Ok(x), x_cmp)?;
    }

    info!("testOneWay - remote sleeps for 1 second");
    {
        thrift_test_client.test_oneway(1)?;
    }

    // final test to verify that the connection is still writable after the one-way
    // call
    thrift_test_client.test_void()
}

fn verify_expected_result(
    actual: Result,
    expected: T,
) -> Result<(), thrift::Error> {
    info!("*** EXPECTED: Ok({:?})", expected);
    info!("*** ACTUAL  : {:?}", actual);
    match actual {
        Ok(v) => {
            if v == expected {
                info!("*** OK ***");
                Ok(())
            } else {
                info!("*** FAILED ***");
                Err(thrift::Error::User(
                    format!("expected {:?} but got {:?}", &expected, &v).into(),
                ))
            }
        }
        Err(e) => Err(e),
    }
}
thrift-0.23.0/test/rs/src/bin/test_server.rs0000664000175000017500000003253315165535636021260 0ustar00buildbuild00000000000000// 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.

use clap::{clap_app, value_t};
use log::*;

use std::collections::{BTreeMap, BTreeSet};
use std::thread;
use std::time::Duration;

use thrift::protocol::{
    TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory, TCompactInputProtocolFactory,
    TCompactOutputProtocolFactory, TInputProtocolFactory, TOutputProtocolFactory,
};
use thrift::server::{TMultiplexedProcessor, TServer};
use thrift::transport::{
    TBufferedReadTransportFactory, TBufferedWriteTransportFactory, TFramedReadTransportFactory,
    TFramedWriteTransportFactory, TReadTransportFactory, TWriteTransportFactory,
};
use thrift::OrderedFloat;
use thrift_test::*;

fn main() {
    env_logger::init();

    debug!("initialized logger - running cross-test server");

    match run() {
        Ok(()) => info!("cross-test server succeeded"),
        Err(e) => {
            info!("cross-test server failed with error {:?}", e);
            std::process::exit(1);
        }
    }
}

fn run() -> thrift::Result<()> {
    // unsupported options:
    // --pipe
    // --ssl
    let matches = clap_app!(rust_test_client =>
        (version: "1.0")
        (author: "Apache Thrift Developers ")
        (about: "Rust Thrift test server")
        (@arg port: --port +takes_value "port on which the test server listens")
        (@arg domain_socket: --("domain-socket") +takes_value "Unix Domain Socket on which the test server listens")
        (@arg transport: --transport +takes_value "transport implementation to use (\"buffered\", \"framed\")")
        (@arg protocol: --protocol +takes_value "protocol implementation to use (\"binary\", \"compact\")")
        (@arg server_type: --("server-type") +takes_value "type of server instantiated (\"simple\", \"thread-pool\")")
        (@arg workers: -n --workers +takes_value "number of thread-pool workers (\"4\")")
    )
        .get_matches();

    let port = value_t!(matches, "port", u16).unwrap_or(9090);
    let domain_socket = matches.value_of("domain_socket");
    let transport = matches.value_of("transport").unwrap_or("buffered");
    let protocol = matches.value_of("protocol").unwrap_or("binary");
    let server_type = matches.value_of("server_type").unwrap_or("thread-pool");
    let workers = value_t!(matches, "workers", usize).unwrap_or(4);
    let listen_address = format!("127.0.0.1:{}", port);

    match domain_socket {
        None => info!("Server is binding to {}", listen_address),
        Some(domain_socket) => info!("Server is binding to {} (UDS)", domain_socket),
    }

    let (i_transport_factory, o_transport_factory): (
        Box,
        Box,
    ) = match transport {
        "buffered" => (
            Box::new(TBufferedReadTransportFactory::new()),
            Box::new(TBufferedWriteTransportFactory::new()),
        ),
        "framed" => (
            Box::new(TFramedReadTransportFactory::new()),
            Box::new(TFramedWriteTransportFactory::new()),
        ),
        unknown => {
            return Err(format!("unsupported transport type {}", unknown).into());
        }
    };

    let (i_protocol_factory, o_protocol_factory): (
        Box,
        Box,
    ) = match protocol {
        "binary" | "multi" | "multi:binary" => (
            Box::new(TBinaryInputProtocolFactory::new()),
            Box::new(TBinaryOutputProtocolFactory::new()),
        ),
        "compact" | "multic" | "multi:compact" => (
            Box::new(TCompactInputProtocolFactory::new()),
            Box::new(TCompactOutputProtocolFactory::new()),
        ),
        unknown => {
            return Err(format!("unsupported transport type {}", unknown).into());
        }
    };

    let test_processor = ThriftTestSyncProcessor::new(ThriftTestSyncHandlerImpl {});

    match server_type {
        "simple" | "thread-pool" => {
            if protocol == "multi" || protocol == "multic" {
                let second_service_processor =
                    SecondServiceSyncProcessor::new(SecondServiceSyncHandlerImpl {});

                let mut multiplexed_processor = TMultiplexedProcessor::new();
                multiplexed_processor.register("ThriftTest", Box::new(test_processor), true)?;
                multiplexed_processor.register(
                    "SecondService",
                    Box::new(second_service_processor),
                    false,
                )?;

                let mut server = TServer::new(
                    i_transport_factory,
                    i_protocol_factory,
                    o_transport_factory,
                    o_protocol_factory,
                    multiplexed_processor,
                    workers,
                );

                match domain_socket {
                    None => server.listen(&listen_address),
                    Some(domain_socket) => server.listen_uds(domain_socket),
                }
            } else {
                let mut server = TServer::new(
                    i_transport_factory,
                    i_protocol_factory,
                    o_transport_factory,
                    o_protocol_factory,
                    test_processor,
                    workers,
                );

                match domain_socket {
                    None => server.listen(&listen_address),
                    Some(domain_socket) => server.listen_uds(domain_socket),
                }
            }
        }

        unknown => Err(format!("unsupported server type {}", unknown).into()),
    }
}

struct ThriftTestSyncHandlerImpl;
impl ThriftTestSyncHandler for ThriftTestSyncHandlerImpl {
    fn handle_test_void(&self) -> thrift::Result<()> {
        info!("testVoid()");
        Ok(())
    }

    fn handle_test_string(&self, thing: String) -> thrift::Result {
        info!("testString({})", &thing);
        Ok(thing)
    }

    fn handle_test_uuid(&self, thing: uuid::Uuid) -> thrift::Result {
        info!("testUUID({})", &thing);
        Ok(thing)
    }

    fn handle_test_bool(&self, thing: bool) -> thrift::Result {
        info!("testBool({})", thing);
        Ok(thing)
    }

    fn handle_test_byte(&self, thing: i8) -> thrift::Result {
        info!("testByte({})", thing);
        Ok(thing)
    }

    fn handle_test_i32(&self, thing: i32) -> thrift::Result {
        info!("testi32({})", thing);
        Ok(thing)
    }

    fn handle_test_i64(&self, thing: i64) -> thrift::Result {
        info!("testi64({})", thing);
        Ok(thing)
    }

    fn handle_test_double(&self, thing: OrderedFloat) -> thrift::Result> {
        info!("testDouble({})", thing);
        Ok(thing)
    }

    fn handle_test_binary(&self, thing: Vec) -> thrift::Result> {
        info!("testBinary({:?})", thing);
        Ok(thing)
    }

    fn handle_test_struct(&self, thing: Xtruct) -> thrift::Result {
        info!("testStruct({:?})", thing);
        Ok(thing)
    }

    fn handle_test_nest(&self, thing: Xtruct2) -> thrift::Result {
        info!("testNest({:?})", thing);
        Ok(thing)
    }

    fn handle_test_map(&self, thing: BTreeMap) -> thrift::Result> {
        info!("testMap({:?})", thing);
        Ok(thing)
    }

    fn handle_test_string_map(
        &self,
        thing: BTreeMap,
    ) -> thrift::Result> {
        info!("testStringMap({:?})", thing);
        Ok(thing)
    }

    fn handle_test_set(&self, thing: BTreeSet) -> thrift::Result> {
        info!("testSet({:?})", thing);
        Ok(thing)
    }

    fn handle_test_list(&self, thing: Vec) -> thrift::Result> {
        info!("testList({:?})", thing);
        Ok(thing)
    }

    fn handle_test_enum(&self, thing: Numberz) -> thrift::Result {
        info!("testEnum({:?})", thing);
        Ok(thing)
    }

    fn handle_test_typedef(&self, thing: UserId) -> thrift::Result {
        info!("testTypedef({})", thing);
        Ok(thing)
    }

    /// @return map> - returns a dictionary with these values:
    /// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 =>
    /// 2, 3 => 3, 4 => 4, }, }
    fn handle_test_map_map(&self, hello: i32) -> thrift::Result>> {
        info!("testMapMap({})", hello);

        let mut inner_map_0: BTreeMap = BTreeMap::new();
        for i in -4..0_i32 {
            inner_map_0.insert(i, i);
        }

        let mut inner_map_1: BTreeMap = BTreeMap::new();
        for i in 1..5 {
            inner_map_1.insert(i, i);
        }

        let mut ret_map: BTreeMap> = BTreeMap::new();
        ret_map.insert(-4, inner_map_0);
        ret_map.insert(4, inner_map_1);

        Ok(ret_map)
    }

    /// Creates a the returned map with these values and prints it out:
    ///     { 1 => { 2 => argument,
    ///              3 => argument,
    ///            },
    ///       2 => { 6 => , },
    ///     }
    /// return map> - a map with the above values
    fn handle_test_insanity(
        &self,
        argument: Insanity,
    ) -> thrift::Result>> {
        info!("testInsanity({:?})", argument);
        let mut map_0: BTreeMap = BTreeMap::new();
        map_0.insert(Numberz::TWO, argument.clone());
        map_0.insert(Numberz::THREE, argument);

        let mut map_1: BTreeMap = BTreeMap::new();
        let insanity = Insanity {
            user_map: None,
            xtructs: None,
        };
        map_1.insert(Numberz::SIX, insanity);

        let mut ret: BTreeMap> = BTreeMap::new();
        ret.insert(1, map_0);
        ret.insert(2, map_1);

        Ok(ret)
    }

    /// returns an Xtruct with:
    /// string_thing = "Hello2", byte_thing = arg0, i32_thing = arg1 and
    /// i64_thing = arg2
    fn handle_test_multi(
        &self,
        arg0: i8,
        arg1: i32,
        arg2: i64,
        _: BTreeMap,
        _: Numberz,
        _: UserId,
    ) -> thrift::Result {
        let x_ret = Xtruct {
            string_thing: Some("Hello2".to_owned()),
            byte_thing: Some(arg0),
            i32_thing: Some(arg1),
            i64_thing: Some(arg2),
        };

        Ok(x_ret)
    }

    /// if arg == "Xception" throw Xception with errorCode = 1001 and message =
    /// arg
    /// else if arg == "TException" throw TException
    /// else do not throw anything
    fn handle_test_exception(&self, arg: String) -> thrift::Result<()> {
        info!("testException({})", arg);

        match &*arg {
            "Xception" => Err((Xception {
                error_code: Some(1001),
                message: Some(arg),
            })
            .into()),
            "TException" => Err("this is a random error".into()),
            _ => Ok(()),
        }
    }

    /// if arg0 == "Xception":
    /// throw Xception with errorCode = 1001 and message = "This is an
    /// Xception"
    /// else if arg0 == "Xception2":
    /// throw Xception2 with errorCode = 2002 and struct_thing.string_thing =
    /// "This is an Xception2"
    // else:
    //   do not throw anything and return Xtruct with string_thing = arg1
    fn handle_test_multi_exception(&self, arg0: String, arg1: String) -> thrift::Result {
        match &*arg0 {
            "Xception" => Err((Xception {
                error_code: Some(1001),
                message: Some("This is an Xception".to_owned()),
            })
            .into()),
            "Xception2" => Err((Xception2 {
                error_code: Some(2002),
                struct_thing: Some(Xtruct {
                    string_thing: Some("This is an Xception2".to_owned()),
                    byte_thing: None,
                    i32_thing: None,
                    i64_thing: None,
                }),
            })
            .into()),
            _ => Ok(Xtruct {
                string_thing: Some(arg1),
                byte_thing: None,
                i32_thing: None,
                i64_thing: None,
            }),
        }
    }

    fn handle_test_oneway(&self, seconds_to_sleep: i32) -> thrift::Result<()> {
        thread::sleep(Duration::from_secs(seconds_to_sleep as u64));
        Ok(())
    }
}

struct SecondServiceSyncHandlerImpl;
impl SecondServiceSyncHandler for SecondServiceSyncHandlerImpl {
    fn handle_secondtest_string(&self, thing: String) -> thrift::Result {
        info!("(second)testString({})", &thing);
        let ret = format!("testString(\"{}\")", &thing);
        Ok(ret)
    }
}
thrift-0.23.0/test/rs/src/lib.rs0000664000175000017500000000176515165535636016714 0ustar00buildbuild00000000000000// 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.

// FIXME - need changes in gen before lifting this exception
#![allow(
    clippy::match_single_binding,
    clippy::unnecessary_wraps,
    clippy::derivable_impls
)]
mod thrift_test;
pub use crate::thrift_test::*;
thrift-0.23.0/test/rs/Cargo.toml0000664000175000017500000000046015165535636016730 0ustar00buildbuild00000000000000[package]
name = "thrift-test"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
authors = ["Apache Thrift Developers "]
publish = false

[dependencies]
clap = "~2.33"
bitflags = "=1.2"
env_logger = "0.8"
log = "0.4"
uuid = "1"

[dependencies.thrift]
path = "../../lib/rs"
thrift-0.23.0/test/rs/Makefile0000644000175000017500000004433015170007175016426 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# test/rs/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#
# 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.
#

am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/thrift
pkgincludedir = $(includedir)/thrift
pkglibdir = $(libdir)/thrift
pkglibexecdir = $(libexecdir)/thrift
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = x86_64-pc-linux-gnu
subdir = test/rs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
ANT = /usr/bin/ant
ANT_FLAGS = 
AR = ar
AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf
AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader
AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16
AWK = mawk
BISON = bison
BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a
BOOST_CPPFLAGS = -I/usr/include
BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a
BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu
BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu
BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a
BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a
BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a
BUNDLER = /usr/bin/bundle
CARGO = /home/build/.cargo/bin/cargo
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CLASSPATH = 
CPP = gcc -E
CPPFLAGS = 
CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;
CSCOPE = cscope
CTAGS = ctags
CXX = g++ -std=c++11
CXXCPP = g++ -E -std=c++11
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DART = /usr/lib/dart/bin/dart
DARTPUB = /usr/lib/dart/bin/pub
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DMD = dmd
DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent
DMD_OF_DIRSEP = /
DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto
DOTNETCORE = /usr/bin/dotnet
DOTNETCORE_VERSION = 10.0.105
DSYMUTIL = 
DUMPBIN = 
D_EVENT_LIB_NAME = libthriftd-event.a
D_IMPORT_PREFIX = ${prefix}/include/d2
D_LIB_NAME = libthriftd.a
D_SSL_LIB_NAME = libthriftd-ssl.a
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /usr/bin/grep -E
ENABLE_COVERAGE = 2
ERL = /usr/local/lib/otp/bin/erl
ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib
ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0
ERLANG_LIB_DIR = /usr/local/lib/otp/lib
ERLC = /usr/local/lib/otp/bin/erlc
ERLCFLAGS = 
ETAGS = etags
EXEEXT = 
FGREP = /usr/bin/grep -F
GCOV_CFLAGS = 
GCOV_CXXFLAGS = 
GCOV_LDFLAGS = 
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
GO = /usr/local/bin/go
GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0
GRADLE = /usr/local/bin/gradle
GRADLE_OPTS = 
GREP = /usr/bin/grep
GSETTINGS = /usr/bin/gsettings
HAVE_CXX11 = 1
HAXE = /opt/haxe/haxe
HAXE_VERSION = 4.2.1+bf9ff69
INSTALL = /usr/bin/install -c
INSTALLDIRS = vendor
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
JAVA_PREFIX = /usr/local/lib
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = 
LEX = flex
LEXLIB = 
LEX_OUTPUT_ROOT = lex.yy
LIBEVENT_CPPFLAGS = 
LIBEVENT_LDFLAGS = 
LIBEVENT_LIBS = -levent
LIBOBJS = 
LIBS = -lrt -lpthread 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
LT_SYS_LIBRARY_PATH = 
LUA = /usr/bin/lua
LUA_EXEC_PREFIX = ${exec_prefix}
LUA_INCLUDE = -I/usr/include/lua5.4
LUA_LIB = -llua5.4 
LUA_PLATFORM = unknown
LUA_PREFIX = ${prefix}
LUA_SHORT_VERSION = 54
LUA_VERSION = 5.4
MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo
MANIFEST_TOOL = :
MAYBE_CL = cl
MAYBE_CPP = cpp
MAYBE_C_GLIB = c_glib
MAYBE_D = d
MAYBE_DART = dart
MAYBE_ERLANG = erl
MAYBE_GO = go
MAYBE_JAVA = java
MAYBE_KOTLIN = kotlin
MAYBE_LUA = lua
MAYBE_NETSTD = netstd
MAYBE_NODEJS = nodejs
MAYBE_NODETS = nodets
MAYBE_PERL = perl
MAYBE_PHP = php
MAYBE_PY3 = py3
MAYBE_PYTHON = py
MAYBE_RS = rs
MAYBE_RUBY = rb
MAYBE_SWIFT = swift
MKDIR_P = /usr/bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT = 
NODEJS = /usr/bin/nodejs
NODETS = /usr/bin/node
NPM = /usr/bin/npm
OBJDUMP = objdump
OBJEXT = o
OPENSSL_INCLUDES = 
OPENSSL_LDFLAGS = 
OPENSSL_LIBS = -lssl -lcrypto
OTOOL = 
OTOOL64 = 
PACKAGE = thrift
PACKAGE_BUGREPORT = 
PACKAGE_NAME = thrift
PACKAGE_STRING = thrift 0.23.0
PACKAGE_TARNAME = thrift
PACKAGE_URL = 
PACKAGE_VERSION = 0.23.0
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PERL_PREFIX = /usr/local
PHP = /usr/bin/php
PHP_CONFIG = /usr/bin/php-config
PHP_CONFIG_PREFIX = /etc/php.d
PHP_PREFIX = /usr/lib/php
PKG_CONFIG = /usr/bin/pkg-config
PKG_CONFIG_LIBDIR = 
PKG_CONFIG_PATH = 
PYTHON = /usr/bin/python3
PYTHON3 = /usr/bin/python3
PYTHON_EXEC_PREFIX = ${exec_prefix}
PYTHON_PLATFORM = linux
PYTHON_PREFIX = ${prefix}
PYTHON_VERSION = 3.10
PY_PREFIX = /usr
QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5
QT5_LIBS = -lQt5Network -lQt5Core
QT5_MOC = /usr/bin/moc
RANLIB = ranlib
REBAR = /usr/local/bin/rebar3
RUBY = /usr/bin/ruby
RUBY_PREFIX = 
RUSTC = /home/build/.cargo/bin/rustc
SBCL = /usr/local/bin/sbcl
SED = /usr/bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = strip
SWIFT = /usr/share/swift/usr/bin/swift
THRIFT = /thrift/src/compiler/cpp/thrift
TRIAL = /usr/local/bin/trial
VERSION = 0.23.0
YACC = bison -y
YFLAGS = 
ZLIB_CPPFLAGS = 
ZLIB_LDFLAGS = 
ZLIB_LIBS = -lz
abs_builddir = /thrift/src/test/rs
abs_srcdir = /thrift/src/test/rs
abs_top_builddir = /thrift/src
abs_top_srcdir = /thrift/src
ac_ct_AR = ar
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir"
am__untar = tar -xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
golang_version = go version go1.25.0 linux/amd64
have_prog_bison = yes
host = x86_64-pc-linux-gnu
host_alias = 
host_cpu = x86_64
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /thrift/src/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
luadir = ${prefix}/share/lua/5.4
luaexecdir = ${exec_prefix}/lib/lua/5.4
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
pkgluadir = ${luadir}/thrift
pkgluaexecdir = ${luaexecdir}/thrift
pkgpyexecdir = ${pyexecdir}/thrift
pkgpythondir = ${pythondir}/thrift
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages
pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages
runstatedir = ${localstatedir}/run
rustc_version = rustc 1.83.0 (90b35a623 2024-11-26)
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs =  lib/php/src/ext/thrift_protocol
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..
EXTRA_DIST = \
	Cargo.toml \
	src/lib.rs \
	src/bin/test_server.rs \
	src/bin/test_client.rs

all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/rs/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/rs/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am distclean distclean-generic \
	distclean-libtool distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: ../ThriftTest.thrift
	$(THRIFT) -I ./thrifts -out src --gen rs ../ThriftTest.thrift

precross: stubs
	$(CARGO) build
	$(CARGO) fmt --all -- --check
	$(CARGO) clippy --all -- -D warnings
	[ -d bin ] || mkdir bin
	cp target/debug/test_server bin/test_server
	cp target/debug/test_client bin/test_client

clean-local:
	$(CARGO) clean
	-$(RM) Cargo.lock
	-$(RM) src/thrift_test.rs
	-$(RM) -r bin

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/rs/Makefile.in0000644000175000017500000004327315170007167017041 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2021 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@

#
# 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.
#
VPATH = @srcdir@
am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = test/rs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \
	$(top_srcdir)/aclocal/ax_boost_base.m4 \
	$(top_srcdir)/aclocal/ax_check_openssl.m4 \
	$(top_srcdir)/aclocal/ax_compare_version.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \
	$(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \
	$(top_srcdir)/aclocal/ax_dmd.m4 \
	$(top_srcdir)/aclocal/ax_javac_and_java.m4 \
	$(top_srcdir)/aclocal/ax_lib_event.m4 \
	$(top_srcdir)/aclocal/ax_lib_zlib.m4 \
	$(top_srcdir)/aclocal/ax_lua.m4 \
	$(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \
	$(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \
	$(top_srcdir)/aclocal/ax_signed_right_shift.m4 \
	$(top_srcdir)/aclocal/ax_thrift_internal.m4 \
	$(top_srcdir)/aclocal/libtool.m4 \
	$(top_srcdir)/aclocal/ltoptions.m4 \
	$(top_srcdir)/aclocal/ltsugar.m4 \
	$(top_srcdir)/aclocal/ltversion.m4 \
	$(top_srcdir)/aclocal/lt~obsolete.m4 \
	$(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h \
	$(top_builddir)/lib/cpp/src/thrift/config.h \
	$(top_builddir)/lib/c_glib/src/thrift/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 = 
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
am__extra_recursive_targets = style-recursive
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANT = @ANT@
ANT_FLAGS = @ANT_FLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BISON = @BISON@
BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_LIB_DIR = @BOOST_LIB_DIR@
BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@
BOOST_TEST_LDADD = @BOOST_TEST_LDADD@
BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@
BUNDLER = @BUNDLER@
CARGO = @CARGO@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CLASSPATH = @CLASSPATH@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPSTYLE_CMD = @CPPSTYLE_CMD@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DART = @DART@
DARTPUB = @DARTPUB@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DMD = @DMD@
DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@
DMD_OF_DIRSEP = @DMD_OF_DIRSEP@
DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@
DOTNETCORE = @DOTNETCORE@
DOTNETCORE_VERSION = @DOTNETCORE_VERSION@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@
D_IMPORT_PREFIX = @D_IMPORT_PREFIX@
D_LIB_NAME = @D_LIB_NAME@
D_SSL_LIB_NAME = @D_SSL_LIB_NAME@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_COVERAGE = @ENABLE_COVERAGE@
ERL = @ERL@
ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@
ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@
ERLANG_LIB_DIR = @ERLANG_LIB_DIR@
ERLC = @ERLC@
ERLCFLAGS = @ERLCFLAGS@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GCOV_CFLAGS = @GCOV_CFLAGS@
GCOV_CXXFLAGS = @GCOV_CXXFLAGS@
GCOV_LDFLAGS = @GCOV_LDFLAGS@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GO = @GO@
GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
GOBJECT_LIBS = @GOBJECT_LIBS@
GRADLE = @GRADLE@
GRADLE_OPTS = @GRADLE_OPTS@
GREP = @GREP@
GSETTINGS = @GSETTINGS@
HAVE_CXX11 = @HAVE_CXX11@
HAXE = @HAXE@
HAXE_VERSION = @HAXE_VERSION@
INSTALL = @INSTALL@
INSTALLDIRS = @INSTALLDIRS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_PREFIX = @JAVA_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@
LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@
LIBEVENT_LIBS = @LIBEVENT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
LUA = @LUA@
LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@
LUA_INCLUDE = @LUA_INCLUDE@
LUA_LIB = @LUA_LIB@
LUA_PLATFORM = @LUA_PLATFORM@
LUA_PREFIX = @LUA_PREFIX@
LUA_SHORT_VERSION = @LUA_SHORT_VERSION@
LUA_VERSION = @LUA_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAYBE_CL = @MAYBE_CL@
MAYBE_CPP = @MAYBE_CPP@
MAYBE_C_GLIB = @MAYBE_C_GLIB@
MAYBE_D = @MAYBE_D@
MAYBE_DART = @MAYBE_DART@
MAYBE_ERLANG = @MAYBE_ERLANG@
MAYBE_GO = @MAYBE_GO@
MAYBE_JAVA = @MAYBE_JAVA@
MAYBE_KOTLIN = @MAYBE_KOTLIN@
MAYBE_LUA = @MAYBE_LUA@
MAYBE_NETSTD = @MAYBE_NETSTD@
MAYBE_NODEJS = @MAYBE_NODEJS@
MAYBE_NODETS = @MAYBE_NODETS@
MAYBE_PERL = @MAYBE_PERL@
MAYBE_PHP = @MAYBE_PHP@
MAYBE_PY3 = @MAYBE_PY3@
MAYBE_PYTHON = @MAYBE_PYTHON@
MAYBE_RS = @MAYBE_RS@
MAYBE_RUBY = @MAYBE_RUBY@
MAYBE_SWIFT = @MAYBE_SWIFT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NODEJS = @NODEJS@
NODETS = @NODETS@
NPM = @NPM@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_PREFIX = @PERL_PREFIX@
PHP = @PHP@
PHP_CONFIG = @PHP_CONFIG@
PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@
PHP_PREFIX = @PHP_PREFIX@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PYTHON = @PYTHON@
PYTHON3 = @PYTHON3@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
PY_PREFIX = @PY_PREFIX@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QT5_MOC = @QT5_MOC@
RANLIB = @RANLIB@
REBAR = @REBAR@
RUBY = @RUBY@
RUBY_PREFIX = @RUBY_PREFIX@
RUSTC = @RUSTC@
SBCL = @SBCL@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIFT = @SWIFT@
THRIFT = @THRIFT@
TRIAL = @TRIAL@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@
ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
golang_version = @golang_version@
have_prog_bison = @have_prog_bison@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
luadir = @luadir@
luaexecdir = @luaexecdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgluadir = @pkgluadir@
pkgluaexecdir = @pkgluaexecdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
rustc_version = @rustc_version@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = \
	Cargo.toml \
	src/lib.rs \
	src/bin/test_server.rs \
	src/bin/test_client.rs

all: all-am

.SUFFIXES:
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/rs/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --foreign test/rs/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs
style-local: 
tags TAGS:

ctags CTAGS:

cscope cscopelist:


distdir-am: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-local mostlyclean-am

distclean: distclean-am
	-rm -f Makefile
distclean-am: clean-am distclean-generic

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-generic mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

style: style-am

style-am: style-local

uninstall-am:

.MAKE: install-am install-strip

.PHONY: all all-am check check-am clean clean-generic clean-libtool \
	clean-local cscopelist-am ctags-am distclean distclean-generic \
	distclean-libtool distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	style-am style-local tags-am uninstall uninstall-am

.PRECIOUS: Makefile


stubs: ../ThriftTest.thrift
	$(THRIFT) -I ./thrifts -out src --gen rs ../ThriftTest.thrift

precross: stubs
	$(CARGO) build
	$(CARGO) fmt --all -- --check
	$(CARGO) clippy --all -- -D warnings
	[ -d bin ] || mkdir bin
	cp target/debug/test_server bin/test_server
	cp target/debug/test_client bin/test_client

clean-local:
	$(CARGO) clean
	-$(RM) Cargo.lock
	-$(RM) src/thrift_test.rs
	-$(RM) -r bin

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
thrift-0.23.0/test/rs/Makefile.am0000664000175000017500000000245615165535636017043 0ustar00buildbuild00000000000000#
# 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.
#

stubs: ../ThriftTest.thrift
	$(THRIFT) -I ./thrifts -out src --gen rs ../ThriftTest.thrift

precross: stubs
	$(CARGO) build
	$(CARGO) fmt --all -- --check
	$(CARGO) clippy --all -- -D warnings
	[ -d bin ] || mkdir bin
	cp target/debug/test_server bin/test_server
	cp target/debug/test_client bin/test_client

clean-local:
	$(CARGO) clean
	-$(RM) Cargo.lock
	-$(RM) src/thrift_test.rs
	-$(RM) -r bin

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	Cargo.toml \
	src/lib.rs \
	src/bin/test_server.rs \
	src/bin/test_client.rs

thrift-0.23.0/test/Makefile.am0000664000175000017500000000766315170007142016402 0ustar00buildbuild00000000000000#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

SUBDIRS = features
PRECROSS_TARGET =

if WITH_C_GLIB
SUBDIRS += c_glib
PRECROSS_TARGET += precross-c_glib
endif

if WITH_CL
SUBDIRS += cl
PRECROSS_TARGET += precross-cl
endif

if WITH_CPP
SUBDIRS += cpp
PRECROSS_TARGET += precross-cpp
endif

if WITH_PERL
SUBDIRS += perl
PRECROSS_TARGET += precross-perl
endif

if WITH_PHP
SUBDIRS += php
PRECROSS_TARGET += precross-php
endif

if WITH_DART
SUBDIRS += dart
PRECROSS_TARGET += precross-dart
endif

if WITH_PYTHON
SUBDIRS += py
PRECROSS_TARGET += precross-py
SUBDIRS += py.tornado
if WITH_TWISTED_TEST
SUBDIRS += py.twisted
endif
endif

if WITH_RUBY
SUBDIRS += rb
PRECROSS_TARGET += precross-rb
endif

if WITH_HAXE
SUBDIRS += haxe
endif

if WITH_DOTNET
SUBDIRS += netstd
endif

if WITH_GO
SUBDIRS += go
PRECROSS_TARGET += precross-go
endif

if WITH_ERLANG
SUBDIRS += erl
PRECROSS_TARGET += precross-erl
endif

if WITH_LUA
SUBDIRS += lua
PRECROSS_TARGET += precross-lua
endif

if WITH_RS
SUBDIRS += rs
PRECROSS_TARGET += precross-rs
endif

if WITH_SWIFT
SUBDIRS += swift
PRECROSS_TARGET += precross-swift
endif

#
# generate html for ThriftTest.thrift AND validate it!
#
if WITH_NODEJS
check-local:
	$(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/test/ThriftTest.thrift
	$(top_builddir)/node_modules/.bin/html-validator --file=gen-html/index.html --verbose
	$(top_builddir)/node_modules/.bin/html-validator --file=gen-html/ThriftTest.html --verbose
else
check-local:
	$(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/test/ThriftTest.thrift
endif

clean-local:
	$(RM) -r $(top_srcdir)/test/gen-html/
	find . -type d -name "__pycache__" | xargs rm -rf
	find . -type f -name "*.pyc" | xargs rm -f

dist-hook:
	$(RM) -r $(distdir)/gen-html/
	find $(distdir) -type d -name "__pycache__" | xargs rm -rf
	find $(distdir) -type f -name "*.pyc" | xargs rm -f

distdir:
	$(MAKE) $(AM_MAKEFLAGS) distdir-am

EXTRA_DIST = \
	audit \
	c_glib \
	cl \
	cpp \
	crossrunner \
	dart \
	delphi \
	erl \
	keys \
	lua \
	ocaml \
	perl \
	php \
	py \
	py.tornado \
	py.twisted \
	rb \
	rs \
	swift \
	threads \
	partial \
	AnnotationTest.thrift \
	BrokenConstants.thrift \
	ConstantsDemo.thrift \
	DebugProtoTest.thrift \
	DenseLinkingTest.thrift \
	DocTest.thrift \
	DoubleConstantsTest.thrift \
	EnumContainersTest.thrift \
	EnumTest.thrift \
	ExceptionStruct.thrift \
	FullCamelTest.thrift \
	FuzzTest.thrift \
	Identifiers.thrift \
	Include.thrift \
	index.html \
	Int64Test.thrift \
	JsDeepConstructorTest.thrift \
	keys/keygen/.gitignore \
	known_failures_Linux.json \
	ManyOptionals.thrift \
	ManyTypedefs.thrift \
	NameConflictTest.thrift \
	OptionalRequiredTest.thrift \
	partial/thrift_test_schema.thrift \
	README.md \
	rebuild_known_failures.sh \
	Recursive.thrift \
	result.js \
	ReuseObjects.thrift \
	Service.thrift \
	SmallTest.thrift \
	SpecificNameTest.thrift \
	StressTest.thrift \
	test.py \
	tests.json \
	ThriftTest.thrift \
	TypedefTest.thrift \
	Types.thrift \
	UnsafeTypes.thrift \
	v0.16/ConstantsDemo.thrift \
	v0.16/DebugProtoTest.thrift \
	v0.16/FuzzTestNoUuid.thrift \
	v0.16/NameConflictTest.thrift \
	v0.16/ThriftTest.thrift \
	VoidMethExceptionsTest.thrift \
	valgrind.suppress

precross-%:
	$(MAKE) -C $* precross
precross: $(PRECROSS_TARGET)
thrift-0.23.0/test/ManyTypedefs.thrift0000664000175000017500000000323715165535636020213 0ustar00buildbuild00000000000000/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// This is to make sure you don't mess something up when you change typedef code.
// Generate it with the old and new thrift and make sure they are the same.
/*
rm -rf gen-* orig-*
mkdir old new
thrift --gen cpp --gen java --gen php --gen phpi --gen py --gen rb --gen xsd --gen perl --gen ocaml --gen erl --gen hs --strict ManyTypedefs.thrift
mv gen-* old
../compiler/cpp/thrift --gen cpp --gen java --gen php --gen phpi --gen py --gen rb --gen xsd --gen perl --gen ocaml --gen erl --gen hs --strict ManyTypedefs.thrift
mv gen-* new
diff -ur old new
rm -rf old new
# There should be no output.
*/

typedef i32 int32
typedef list> biglist

struct struct1 {
  1: int32 myint;
  2: biglist mylist;
}

exception exception1 {
  1: biglist alist;
  2: struct1 mystruct;
}

service AService {
  struct1 method1(1: int32 myint) throws (1: exception1 exn);
  biglist method2();
}
thrift-0.23.0/LICENSE0000664000175000017500000003701115167543515014401 0ustar00buildbuild00000000000000
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   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.

--------------------------------------------------
SOFTWARE DISTRIBUTED WITH THRIFT:

The Apache Thrift software includes a number of subcomponents with
separate copyright notices and license terms. Your use of the source
code for the these subcomponents is subject to the terms and
conditions of the following licenses.

--------------------------------------------------
Portions of the following files are licensed under the MIT License:

  lib/erl/src/Makefile.am

Please see doc/otp-base-license.txt for the full terms of this license.

--------------------------------------------------
For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components:

#   Copyright (c) 2007 Thomas Porschberg 
#
#   Copying and distribution of this file, with or without
#   modification, are permitted in any medium without royalty provided
#   the copyright notice and this notice are preserved.

--------------------------------------------------
For the lib/nodejs/lib/thrift/json_parse.js:

/*
    json_parse.js
    2015-05-02
    Public Domain.
    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

*/
(By Douglas Crockford )

--------------------------------------------------
For lib/cpp/src/thrift/windows/SocketPair.cpp

/* socketpair.c
 * Copyright 2007 by Nathan C. Myers ; some rights reserved.
 * This code is Free Software.  It may be copied freely, in original or
 * modified form, subject only to the restrictions that (1) the author is
 * relieved from all responsibilities for any use for any purpose, and (2)
 * this copyright notice must be retained, unchanged, in its entirety.  If
 * for any reason the author might be held responsible for any consequences
 * of copying or use, license is withheld.
 */


--------------------------------------------------
For lib/py/compat/win32/stdint.h

// ISO C9x  compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
//  Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//   3. The name of the author may be used to endorse or promote products
//      derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////


--------------------------------------------------
Codegen template in t_html_generator.h

* Bootstrap v2.0.3
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.

---------------------------------------------------
For t_cl_generator.cc

 * Copyright (c) 2008- Patrick Collison 
 * Copyright (c) 2006- Facebook

---------------------------------------------------

---------------------------------------------------
For compiler/cpp/src/thrift/generate/sha256.h

SHA-256 implementation by Brad Conte (brad AT bradconte.com).
Source: https://github.com/B-Con/crypto-algorithms
The author has placed this code in the public domain (no copyright claimed).
No algorithmic changes were made; the file was adapted to a C++ header-only
form for inclusion in the Thrift compiler.
thrift-0.23.0/package.json0000664000175000017500000000365015170007142015645 0ustar00buildbuild00000000000000{
  "name": "thrift",
  "description": "node.js bindings for the Apache Thrift RPC system",
  "homepage": "http://thrift.apache.org/",
  "repository": {
    "type": "git",
    "url": "https://github.com/apache/thrift.git"
  },
  "version": "0.23.0",
  "author": {
    "name": "Apache Thrift Developers",
    "email": "dev@thrift.apache.org",
    "url": "http://thrift.apache.org"
  },
  "license": "Apache-2.0",
  "licenses": [
    {
      "type": "Apache-2.0",
      "url": "http://www.apache.org/licenses/LICENSE-2.0"
    }
  ],
  "bugs": {
    "mail": "dev@thrift.apache.org",
    "url": "https://issues.apache.org/jira/browse/THRIFT"
  },
  "files": [
    "lib/nodejs/lib/thrift",
    "lib/nodejs/README.md"
  ],
  "directories": {
    "lib": "./lib/nodejs/lib/thrift"
  },
  "browser": "./lib/nodejs/lib/thrift/browser.js",
  "main": "./lib/nodejs/lib/thrift",
  "engines": {
    "node": ">= 10.18.0"
  },
  "dependencies": {
    "browser-or-node": "^1.2.1",
    "isomorphic-ws": "^4.0.1",
    "node-int64": "^0.4.0",
    "q": "^1.5.0",
    "uuid": "^13.0.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"
  },
  "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,mjs,ts}'",
    "lint": "eslint lib/nodejs",
    "lint-tests": "eslint lib/nodejs/test"
  }
}
thrift-0.23.0/sonar-project.properties0000664000175000017500000001037015170007142020260 0ustar00buildbuild00000000000000# Apache Thrift © The Apache Software Foundation
# http://www.apache.org/licenses/LICENSE-2.0
# SPDX-License-Identifier: Apache-2.0

# File: sonar-project.properties
# Apache Thrift configuration file for Sonar https://analysis.apache.org/
# Sonar is an open platform to manage code quality http://www.sonarsource.org/


# required metadata
sonar.projectKey=org.apache.thrift
sonar.projectName=Apache Thrift
sonar.projectDescription=
The Apache Thrift software framework, for scalable cross-language services
development, combines a software stack with a code generation engine to build
services that work efficiently and seamlessly between all major languages.

# Apache Thrift Version
sonar.projectVersion=0.23.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
#sonar.projectDate=yyyy-MM-dd

# TODO add website (sonar.projectUrl does not work)
#sonar.XXXX=http//thrift.apache.org

# Some properties that will be inherited by the modules
sonar.sources=src
sonar.language=java,js,c++,py,c
sonar.sourceEncoding=UTF-8

# scm
sonar.scm.url=scm:git:https://github.com/apache/thrift.git

# cppcheck -q --error-exitcode=0 --xml . 2> cppcheck-result.xml
sonar.cxx.cppcheck.reportPath=cppcheck-result.xml

# List of the module identifiers
sonar.modules=module1,module3,module4,module5,module6,module7,module8,module9,module10,module11,module12



# we need sonar-runner 2.1 for this, see http://jira.codehaus.org/browse/SONARPLUGINS-2421
#sonar.modules=module2

# delph plugin is broken
#sonar.modules=module13

# phpunit plugin is broken
#sonar.modules=module14

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.23.0.jar
module1.sonar.libraries=build/deps/*.jar
module1.sonar.language=java

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.23.0.jar
module2.sonar.language=java

module3.sonar.projectName=Apache Thrift - JavaScript Library
module3.sonar.projectBaseDir=lib/js
module3.sonar.sources=.
module3.sonar.exclusions=test/**/*
module3.sonar.language=js

module4.sonar.projectName=Apache Thrift - JavaScript Tutorial
module4.sonar.projectBaseDir=tutorial/js
module4.sonar.sources=.
module4.sonar.language=web

module5.sonar.projectName=Apache Thrift - C++ Library
module5.sonar.projectBaseDir=lib/cpp
module5.sonar.sources=src
module5.sonar.tests=test
module5.sonar.language=c++

module6.sonar.projectName=Apache Thrift - C++ Tutorial
module6.sonar.projectBaseDir=tutorial/cpp
module6.sonar.sources=.
module6.sonar.exclusions=gen-cpp/**/*
module6.sonar.language=c++

module7.sonar.projectName=Apache Thrift - C++ Cross Language Test
module7.sonar.projectBaseDir=test/cpp
module7.sonar.sources=src
module7.sonar.language=c++

module8.sonar.projectName=Apache Thrift - Compiler
module8.sonar.projectBaseDir=compiler/cpp
module8.sonar.sources=src
module8.sonar.language=c++

module9.sonar.projectName=Apache Thrift - Python Library
module9.sonar.projectBaseDir=lib/py
module9.sonar.sources=src
module9.sonar.language=py

module10.sonar.projectName=Apache Thrift - Python Tutorial
module10.sonar.projectBaseDir=tutorial/py
module10.sonar.sources=.
module10.sonar.exclusions=gen-py/**/*
module10.sonar.language=py

module11.sonar.projectName=Apache Thrift - Python Cross Language Test
module11.sonar.projectBaseDir=test/py
module11.sonar.sources=.
module11.sonar.exclusions=gen-*/**/*
module11.sonar.language=py

module12.sonar.projectName=Apache Thrift - c_glib Library
module12.sonar.projectBaseDir=lib/c_glib
module12.sonar.sources=src
module12.sonar.language=c

module13.sonar.projectName=Apache Thrift - Delphi Library
module13.sonar.projectBaseDir=lib/delphi
module13.sonar.sources=src
module13.sonar.tests=test
module13.sonar.language=delph

module14.sonar.projectName=Apache Thrift - PHP Library
module14.sonar.projectBaseDir=lib/php
module14.sonar.sources=src
module14.sonar.language=php

# TODO add some more languages here

thrift-0.23.0/AGENTS.md0000664000175000017500000001143515167543515014701 0ustar00buildbuild00000000000000# Apache Thrift — AI Contribution Guidelines

This file governs AI-assisted work on the Apache Thrift codebase.
It supplements but does **not** replace [`CONTRIBUTING.md`](CONTRIBUTING.md).

---

## 1. ASF Legal Compliance (Third-Party Code)

Apache Thrift is an [Apache Software Foundation (ASF)](https://www.apache.org/) project released under the **Apache License 2.0**.
The AI **must** actively enforce and monitor ASF licensing policy:

- **Proactively flag conflicts**: Before introducing any dependency, snippet, or code derived from an external source, verify its license is compatible with Apache 2.0.
  Incompatible licenses include (non-exhaustive): GPL, AGPL, SSPL, BUSL, CC-BY-NC.
  Compatible examples: MIT, BSD-2/3, Apache 2.0, ISC, MPL 2.0 (with caveats).
- **Category X / Category A**: Follow the [ASF Third-Party Licensing Policy](https://www.apache.org/legal/resolved.html).
  Category A licenses may be included; Category X licenses must **never** be introduced.
- **Update `LICENSE` and `NOTICE`**: When adding third-party code or binaries that require attribution, add the appropriate notices to `LICENSE` and/or `NOTICE` following the [ASF guide on licenses and notices](https://www.apache.org/dev/licensing-howto.html).
  If in doubt whether an entry is required, **add it and flag it in the PR description** for committer review.
- **Generative AI output**: The [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) applies. Be aware that AI-generated code may unintentionally reproduce copyrighted material. Flag any non-trivial generated blocks in commit messages or PR descriptions.

---

## 2. Issue Tracking

| Type | Tracker | Notes |
|---|---|---|
| Significant changes | [Apache JIRA — THRIFT project](https://issues.apache.org/jira/browse/THRIFT) | Required for all non-trivial PRs |
| Minor / quick fixes | GitHub Issues | Typos, trivial compiler warnings, etc. |

**JIRA integration with GitHub**: Including a JIRA ticket identifier at the start of a PR title automatically creates a link from JIRA to the PR.

- PR title format: `THRIFT-9999: Short description of the change`
- Commit message format (required for code changes):
  ```
  THRIFT-9999: Short description of the change
  Client: cpp,py,java   (comma-separated list of affected languages)
  ```

Example: [THRIFT-5929](https://issues.apache.org/jira/projects/THRIFT/issues/THRIFT-5929) → [PR #3350](https://github.com/apache/thrift/pull/3350).

---

## 3. Pull Request Requirements

Follow [`CONTRIBUTING.md`](CONTRIBUTING.md) in full. Key points:

- One commit per issue (squash before submitting).
- All significant changes need a JIRA ticket.
- Provide tests for every submitted change.
- Verify coding standards: `make style`.
- Branch name convention: use the JIRA ticket ID, e.g. `THRIFT-9999`.
- PRs go from your fork branch → `apache:master`.

---

## 4. AI-Generated Contributions

Per [`CONTRIBUTING.md § AI generated content`](CONTRIBUTING.md#ai-generated-content) and the [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html):

- **Always** label AI-assisted commits and PRs. Use one or both of:
  ```
  Co-Authored-By: 
  Generated-by: 
  ```
  Example:
  ```
  THRIFT-9999: Fix connection timeout handling in Go client
  Client: go

  Co-Authored-By: Claude Sonnet 4.6 
  ```
- Apply this label even when AI only generated a portion of the change.
- The human author remains responsible for reviewing, testing, and standing behind all submitted code.

---

## 5. Language-Specific Rules (`/lib`, `/test`, `/tutorial`)

- This file remains valid in all cases and must be used in addition to any additional language-specific rules.
- If a target-language directory under `/lib//` contains its own `CLAUDE.md` or `AGENTS.md`, those rules apply to all work in that language directory.
- Those language-specific rules extend **by implication** to the corresponding language code under `/test/` and `/tutorial/`.
- If `/test/` or `/tutorial/` themselves contain a `CLAUDE.md`/`AGENTS.md` for a given language, **combine** the rules: the file **closer to the code** (i.e., in the same directory) takes precedence on any conflict.

---

## 6. Quick Reference Checklist (before opening a PR)

- [ ] License of any new dependency checked against [ASF Category A/X list](https://www.apache.org/legal/resolved.html)
- [ ] `LICENSE` and/or `NOTICE` updated if third-party attribution is required
- [ ] JIRA ticket exists (unless truly trivial)
- [ ] PR title starts with `THRIFT-NNNN:` (if ticket exists)
- [ ] Commit message includes affected `Client:` languages
- [ ] Single squashed commit
- [ ] Tests added or updated
- [ ] `make style` passes
- [ ] AI authorship labelled with `Co-Authored-By:` / `Generated-by:` where applicable
thrift-0.23.0/config.h0000644000175000017500000003413315170005156014776 0ustar00buildbuild00000000000000/* config.h.  Generated from config.hin by configure.  */
/* config.hin.  Generated from configure.ac by autoheader.  */


#ifndef CONFIG_H
#define CONFIG_H


/* Define if the AI_ADDRCONFIG symbol is unavailable */
/* #undef AI_ADDRCONFIG */

/* Possible value for SIGNED_RIGHT_SHIFT_IS */
#define ARITHMETIC_RIGHT_SHIFT 1

/* Defines automake version */
#define AUTOMAKE_VERSION 1.16.5

/* Use *.h extension for parser header file */
/* #undef BISON_USE_PARSER_H_EXTENSION */

/* Defines bison version */
#define BISON_VERSION 3.8.2

/* Define to 1 if using 'alloca.c'. */
/* #undef C_ALLOCA */

/* Define to 1 if you have the `alarm' function. */
#define HAVE_ALARM 1

/* Define to 1 if you have 'alloca', as a function or macro. */
#define HAVE_ALLOCA 1

/* Define to 1 if  works. */
#define HAVE_ALLOCA_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_ARPA_INET_H 1

/* define if the Boost library is available */
#define HAVE_BOOST /**/

/* Define to 1 if you have the `bzero' function. */
#define HAVE_BZERO 1

/* Define to 1 if you have the `clock_gettime' function. */
#define HAVE_CLOCK_GETTIME 1

/* define if the compiler supports basic C++11 syntax */
#define HAVE_CXX11 1

/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
   don't. */
#define HAVE_DECL_STRERROR_R 1

/* Define to 1 if you have the  header file. */
#define HAVE_DLFCN_H 1

/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* #undef HAVE_DOPRNT */

/* Define to 1 if you have the  header file. */
#define HAVE_FCNTL_H 1

/* Define to 1 if you have the `fork' function. */
#define HAVE_FORK 1

/* Define to 1 if you have the `ftruncate' function. */
#define HAVE_FTRUNCATE 1

/* Define to 1 if you have the `gethostbyname' function. */
#define HAVE_GETHOSTBYNAME 1

/* Define to 1 if you have the `gethostbyname_r' function. */
#define HAVE_GETHOSTBYNAME_R 1

/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1

/* Define to 1 if you have the `inet_ntoa' function. */
#define HAVE_INET_NTOA 1

/* Define to 1 if you have the  header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_LAUXLIB_H 1

/* define if libevent is available */
#define HAVE_LIBEVENT /**/

/* Define to 1 if you have the  header file. */
#define HAVE_LIBINTL_H 1

/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1

/* Define to 1 if you have the `rt' library (-lrt). */
#define HAVE_LIBRT 1

/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */

/* Define to 1 if you have the  header file. */
#define HAVE_LIMITS_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_LUACONF_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_LUALIB_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_LUA_H 1

/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
   to 0 otherwise. */
#define HAVE_MALLOC 1

/* Define to 1 if you have the  header file. */
#define HAVE_MALLOC_H 1

/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1

/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1

/* Define to 1 if you have the `mkdir' function. */
#define HAVE_MKDIR 1

/* Define to 1 if you have the  header file. */
#define HAVE_NETDB_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_NETINET_IN_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_OPENSSL_RAND_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_OPENSSL_SSL_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_OPENSSL_X509V3_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_POLL_H 1

/* Define to 1 if you have the `pow' function. */
#define HAVE_POW 1

/* Define to 1 if you have the  header file. */
#define HAVE_PTHREAD_H 1

/* Define to 1 if the system has the type `ptrdiff_t'. */
#define HAVE_PTRDIFF_T 1

/* Define to 1 if your system has a GNU libc compatible `realloc' function,
   and to 0 otherwise. */
#define HAVE_REALLOC 1

/* Define to 1 if you have the `realpath' function. */
#define HAVE_REALPATH 1

/* Define to 1 if you have the `sched_get_priority_max' function. */
#define HAVE_SCHED_GET_PRIORITY_MAX 1

/* Define to 1 if you have the `sched_get_priority_min' function. */
#define HAVE_SCHED_GET_PRIORITY_MIN 1

/* Define to 1 if you have the  header file. */
#define HAVE_SCHED_H 1

/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1

/* Define to 1 if you have the `setlocale' function. */
#define HAVE_SETLOCALE 1

/* Define to 1 if you have the  header file. */
#define HAVE_SIGNAL_H 1

/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1

/* Define to 1 if you have the `sqrt' function. */
#define HAVE_SQRT 1

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */

/* Define to 1 if stdbool.h conforms to C99. */
#define HAVE_STDBOOL_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_STDDEF_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_STDIO_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1

/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1

/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1

/* Define if you have `strerror_r'. */
#define HAVE_STRERROR_R 1

/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1

/* Define to 1 if you have the  header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1

/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1

/* Define to 1 if you have the `strtoul' function. */
#define HAVE_STRTOUL 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_IOCTL_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_PARAM_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_POLL_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_RESOURCE_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_SELECT_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_SOCKET_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_TIME_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_SYS_UN_H 1

/* Define to 1 if you have  that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1

/* Define to 1 if you have the  header file. */
#define HAVE_UNISTD_H 1

/* Define to 1 if you have the `vfork' function. */
#define HAVE_VFORK 1

/* Define to 1 if you have the  header file. */
/* #undef HAVE_VFORK_H */

/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1

/* Define to 1 if you have the  header file. */
#define HAVE_WCHAR_H 1

/* Define to 1 if `fork' works. */
#define HAVE_WORKING_FORK 1

/* Define to 1 if `vfork' works. */
#define HAVE_WORKING_VFORK 1

/* define if zlib is available */
#define HAVE_ZLIB /**/

/* Define to 1 if the system has the type `_Bool'. */
/* #undef HAVE__BOOL */

/* Possible value for SIGNED_RIGHT_SHIFT_IS */
#define LOGICAL_RIGHT_SHIFT 2

/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
   slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1

/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"

/* Name of package */
#define PACKAGE "thrift"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""

/* Define to the full name of this package. */
#define PACKAGE_NAME "thrift"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "thrift 0.23.0"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "thrift"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "0.23.0"

/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void

/* Define to the type of arg 1 for `select'. */
#define SELECT_TYPE_ARG1 int

/* Define to the type of args 2, 3 and 4 for `select'. */
#define SELECT_TYPE_ARG234 (fd_set *)

/* Define to the type of arg 5 for `select'. */
#define SELECT_TYPE_ARG5 (struct timeval *)

/* Indicates the effect of the right shift operator on negative signed
   integers */
#define SIGNED_RIGHT_SHIFT_IS 1

/* If using the C implementation of alloca, define if you know the
   direction of stack growth for your system; otherwise it will be
   automatically deduced at runtime.
	STACK_DIRECTION > 0 => grows toward higher addresses
	STACK_DIRECTION < 0 => grows toward lower addresses
	STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */

/* Define to 1 if all of the C90 standard headers exist (not just the ones
   required in a freestanding environment). This macro is provided for
   backward compatibility; new code need not use it. */
#define STDC_HEADERS 1

/* Define to 1 if strerror_r returns char *. */
#define STRERROR_R_CHAR_P 1

/* Define to 1 if you can safely include both  and . This
   macro is obsolete. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your  declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Possible value for SIGNED_RIGHT_SHIFT_IS */
#define UNKNOWN_RIGHT_SHIFT 3

/* Version number of package */

/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
   `char[]'. */
#define YYTEXT_POINTER 1

/* Define for Solaris 2.5.1 so the uint32_t typedef from ,
   , or  is not used. If the typedef were allowed, the
   #define below would cause a syntax error. */
/* #undef _UINT32_T */

/* Define for Solaris 2.5.1 so the uint64_t typedef from ,
   , or  is not used. If the typedef were allowed, the
   #define below would cause a syntax error. */
/* #undef _UINT64_T */

/* Define for Solaris 2.5.1 so the uint8_t typedef from ,
   , or  is not used. If the typedef were allowed, the
   #define below would cause a syntax error. */
/* #undef _UINT8_T */

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
/* #undef inline */
#endif

/* Define to the type of a signed integer type of width exactly 16 bits if
   such a type exists and the standard includes do not define it. */
/* #undef int16_t */

/* Define to the type of a signed integer type of width exactly 32 bits if
   such a type exists and the standard includes do not define it. */
/* #undef int32_t */

/* Define to the type of a signed integer type of width exactly 64 bits if
   such a type exists and the standard includes do not define it. */
/* #undef int64_t */

/* Define to the type of a signed integer type of width exactly 8 bits if such
   a type exists and the standard includes do not define it. */
/* #undef int8_t */

/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */

/* Define to `int' if  does not define. */
/* #undef mode_t */

/* Define to `long int' if  does not define. */
/* #undef off_t */

/* Define as a signed integer type capable of holding a process identifier. */
/* #undef pid_t */

/* Define to rpl_realloc if the replacement function should be used. */
/* #undef realloc */

/* Define to the equivalent of the C99 'restrict' keyword, or to
   nothing if this is not supported.  Do not define if restrict is
   supported only directly.  */
#define restrict /**/
/* Work around a bug in older versions of Sun C++, which did not
   #define __restrict__ or support _Restrict or __restrict__
   even though the corresponding Sun C compiler ended up with
   "#define restrict _Restrict" or "#define restrict __restrict__"
   in the previous line.  This workaround can be removed once
   we assume Oracle Developer Studio 12.5 (2016) or later.  */
#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__
# define _Restrict
# define __restrict__
#endif

/* Define to `unsigned int' if  does not define. */
/* #undef size_t */

/* Define to `int' if  does not define. */
/* #undef ssize_t */

/* Define to the type of an unsigned integer type of width exactly 16 bits if
   such a type exists and the standard includes do not define it. */
/* #undef uint16_t */

/* Define to the type of an unsigned integer type of width exactly 32 bits if
   such a type exists and the standard includes do not define it. */
/* #undef uint32_t */

/* Define to the type of an unsigned integer type of width exactly 64 bits if
   such a type exists and the standard includes do not define it. */
/* #undef uint64_t */

/* Define to the type of an unsigned integer type of width exactly 8 bits if
   such a type exists and the standard includes do not define it. */
/* #undef uint8_t */

/* Define as `fork' if `vfork' does not work. */
/* #undef vfork */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */


#endif

thrift-0.23.0/Thrift.podspec0000664000175000017500000000171715170007142016200 0ustar00buildbuild00000000000000Pod::Spec.new do |s|
  s.name          = 'Thrift'
  s.version       = '0.23.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.
                    DESC
  s.homepage      = 'https://thrift.apache.org'
  s.license       = { :type => 'Apache License, Version 2.0', :url => 'https://www.apache.org/licenses/LICENSE-2.0' }
  s.author        = { 'Apache Thrift Developers' => 'dev@thrift.apache.org' }
  s.ios.deployment_target = '9.0'
  s.osx.deployment_target = '10.10'
  s.source        = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.23.0' }
  s.source_files  = 'lib/swift/Sources/*.swift'
end
thrift-0.23.0/Package.swift0000664000175000017500000000217015165535636016006 0ustar00buildbuild00000000000000// 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")
  ]
)
thrift-0.23.0/.github/0000755000175000017500000000000015170007200014704 5ustar00buildbuild00000000000000thrift-0.23.0/.github/dependabot.yml0000664000175000017500000000211715165535636017566 0ustar00buildbuild00000000000000#
# 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.
#

version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: monthly
  - package-ecosystem: "gradle"
    directory: "/lib/java"
    schedule:
      interval: monthly
  - package-ecosystem: "gradle"
    directory: "/lib/kotlin"
    schedule:
      interval: monthly
thrift-0.23.0/.github/stale.yml0000664000175000017500000000361215165535636016572 0ustar00buildbuild00000000000000# Configuration for probot-stale - https://github.com/probot/stale

# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60

# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7

# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
  - Do Not Merge
  - blocked
  - pinned
  - security
  - "[Status] Maybe Later"

# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false

# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false

# Label to use when marking as stale
staleLabel: wontfix

# Comment to post when marking as stale. Set to `false` to disable
markComment: >
  This issue has been automatically marked as stale because it has not had
  recent activity. It will be closed in 7 days if no further activity occurs.
  Thank you for your contributions.

# Comment to post when removing the stale label.
unmarkComment: >
  This issue is no longer stale.
  Thank you for your contributions.

# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
  This issue has been automatically closed due to inactivity.
  Thank you for your contributions.

# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30

# Limit to only `issues` or `pulls`
# only: issues

# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
#   daysUntilStale: 30
#   markComment: >
#     This pull request has been automatically marked as stale because it has not had
#     recent activity. It will be closed if no further activity occurs. Thank you
#     for your contributions.

# issues:
#   exemptLabels:
#     - confirmed
thrift-0.23.0/.github/pull_request_template.md0000664000175000017500000000170015165535636021674 0ustar00buildbuild00000000000000
  



- [ ] Did you create an [Apache Jira](https://issues.apache.org/jira/projects/THRIFT/issues/) ticket?  ([Request account here](https://selfserve.apache.org/jira-account.html), not required for trivial changes)
- [ ] If a ticket exists: Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"?
- [ ] Did you squash your changes to a single commit?  (not required, but preferred)
- [ ] Did you do your best to avoid breaking changes?  If one was needed, did you label the Jira ticket with "Breaking-Change"?
- [ ] If your change does not involve any code, include `[skip ci]` anywhere in the commit message to free up build resources.


thrift-0.23.0/.github/workflows/0000755000175000017500000000000015170007200016741 5ustar00buildbuild00000000000000thrift-0.23.0/.github/workflows/release_rust.yml0000664000175000017500000000303215167543515022205 0ustar00buildbuild00000000000000#
# 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.
#

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
    if: false   # currently broken and no maintainers around -> see THRIFT-5917        
    steps:
      - uses: actions/checkout@v6
      - 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 }}
thrift-0.23.0/.github/workflows/pypi.yml0000664000175000017500000000301215167543515020467 0ustar00buildbuild00000000000000#
# 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.
#

name: "PyPI publishing"

on:
  release:
    types: [published]

jobs:
  pypi-publish:
    name: Publish release to PyPI
    runs-on: ubuntu-latest
    # Specifying a GitHub environment is optional, but strongly encouraged
    environment: release
    permissions:
      # IMPORTANT: this permission is mandatory for trusted publishing
      id-token: write
    steps:
      - uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.8"

      - name: Build
        run: |
          cd lib/py
          python setup.py sdist

      - name: Publish package distributions to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          packages-dir: lib/py/dist/
thrift-0.23.0/.github/workflows/cmake.yml0000664000175000017500000000245515167543515020600 0ustar00buildbuild00000000000000name: 'Build with CMake'

on:
  push:
    branches: [ '*' ]
  pull_request:
    branches: [ '*' ]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  BUILD_DEPS: bison flex g++ libboost-all-dev libevent-dev libssl-dev make cmake

permissions:
  contents: read

jobs:
  compiler:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

      - name: Install dependencies
        timeout-minutes: 10
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends $BUILD_DEPS

      - name: Generate makefile using CMake
        timeout-minutes: 10
        run: |
          mkdir cmake_build
          cd cmake_build
          cmake .. -DBUILD_LIBRARIES=OFF

      - name: Run make
        timeout-minutes: 30
        run: |
          cd cmake_build
          cmake --build .

      - name: Run test
        timeout-minutes: 30
        run: |
          cd cmake_build
          ctest -j$(nproc --ignore=2)

      - name: Upload LastTest log
        if: always()
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        with:
          name: cmake-LastTest-log
          path: cmake_build/Testing/Temporary/LastTest.log
          if-no-files-found: warn
thrift-0.23.0/.github/workflows/build.yml0000664000175000017500000007504315170007142020603 0ustar00buildbuild00000000000000name: "Build"

on:
  push:
    branches: ["*"]
  pull_request:
    branches: ["*"]

env:
  BUILD_DEPS: automake bison flex git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config
  CONFIG_ARGS_FOR_LIBS: >
    --disable-debug
    --disable-dependency-tracking
    --without-cpp
    --without-c_glib
    --without-java
    --without-kotlin
    --without-python
    --without-py3
    --without-ruby
    --without-haxe
    --without-netstd
    --without-perl
    --without-php
    --without-php_extension
    --without-dart
    --without-erlang
    --without-go
    --without-d
    --without-nodejs
    --without-nodets
    --without-lua
    --without-rs
    --without-swift

permissions:
  contents: read

jobs:
  # TODO windows and macos
  compiler:
    strategy:
      matrix:
        os:
          - ubuntu-22.04
          - ubuntu-24.04
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends g++ $BUILD_DEPS

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: ./configure --disable-debug --disable-tests --disable-libs

      - name: Run make
        run: make -j$(nproc)

      - name: Run install
        run: make install

      - name: Run thrift version
        run: /usr/local/bin/thrift -version

      - name: Test Delphi UUIDv8 GUID determinism
        run: |
          # Run the Delphi generator twice on the same input and verify identical output.
          # Tests: cross-platform determinism, service inheritance, struct field-order.
          THRIFT=/usr/local/bin/thrift
          INPUT=test/delphi/UuidV8Test.thrift

          mkdir -p /tmp/delphi-guid-run1 /tmp/delphi-guid-run2
          $THRIFT --gen delphi --out /tmp/delphi-guid-run1 $INPUT
          $THRIFT --gen delphi --out /tmp/delphi-guid-run2 $INPUT
          diff -r /tmp/delphi-guid-run1 /tmp/delphi-guid-run2

          # Also verify GUIDs are non-empty (grep for the GUID attribute pattern)
          grep -qP "^\s+\['\{[0-9A-F]{8}-[0-9A-F]{4}-8[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\}'\]" \
            /tmp/delphi-guid-run1/UuidV8Test.pas \
            && echo "UUIDv8 GUIDs found in output" \
            || { echo "ERROR: No UUIDv8 GUIDs found in Delphi output"; exit 1; }

          # Verify that Point and PointReversed have DIFFERENT GUIDs (field-order sensitivity)
          POINT_GUID=$(grep -A1 "IPoint = interface" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | tr -d ' ')
          POINTREV_GUID=$(grep -A1 "IPointReversed = interface" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | tr -d ' ')
          [ "$POINT_GUID" != "$POINTREV_GUID" ] \
            && echo "Field-order sensitivity OK (Point vs PointReversed GUIDs differ)" \
            || { echo "ERROR: Point and PointReversed have the same GUID — field order not hashed"; exit 1; }

          # Verify that BaseService and ExtendedService have DIFFERENT GUIDs (parent hash included)
          BASE_GUID=$(grep -A1 "Iface = interface$" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | head -1 | tr -d ' ')
          EXT_GUID=$(grep -A1 "Iface = interface(.*Base" /tmp/delphi-guid-run1/UuidV8Test.pas | grep "^\s*\['" | head -1 | tr -d ' ')
          [ "$BASE_GUID" != "$EXT_GUID" ] \
            && echo "Parent-hash inclusion OK (BaseService vs ExtendedService GUIDs differ)" \
            || { echo "ERROR: BaseService and ExtendedService have the same GUID — parent not hashed"; exit 1; }

          echo "All Delphi UUIDv8 GUID determinism tests passed."

      # only upload while building ubuntu-24.04
      - name: Archive built thrift compiler
        if: matrix.os == 'ubuntu-24.04'
        uses: actions/upload-artifact@v7
        with:
          name: thrift-compiler
          path: compiler/cpp/thrift
          retention-days: 3

  compiler-macos:
    strategy:
      matrix:
        os: &macos_versions [macos-15-intel, macos-14, macos-15, macos-26]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          brew install automake bison flex boost libevent openssl libtool pkg-config
          echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: ./configure --disable-debug --disable-tests --disable-libs

      - name: Run make
        run: make -j$(sysctl -n hw.ncpu)

      - name: Run install
        run: sudo make install

      - name: Run thrift version
        run: /usr/local/bin/thrift -version

      - name: Archive built thrift compiler (macOS)
        uses: actions/upload-artifact@v7
        with:
          name: thrift-compiler-${{ matrix.os }}
          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, 8.4, 8.5]
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - 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@v8
        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-24.04
    strategy:
      matrix:
        go:
          - '1.25'
          - '1.26'
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-go@v6
        with:
          go-version: ${{ matrix.go }}

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends $BUILD_DEPS

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-go/with-go/')

      - uses: actions/download-artifact@v8
        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 go
        run: make -C lib/go

      - name: Run make check for lib/go
        run: make -C lib/go check

      - name: Run make check for test/go
        run: make -C test/go check

      - name: Run make precross for go test
        run: make -C test/go precross

      - name: Upload go precross artifacts
        if: matrix.go == '1.26'
        uses: actions/upload-artifact@v7
        with:
          name: go-precross
          if-no-files-found: error
          path: |
            test/go/bin/*
          retention-days: 3

  lib-java-kotlin:
    needs: compiler
    runs-on: ubuntu-24.04
    env:
      GRADLE_VERSION: "8.4"
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: 17
          cache: "gradle"

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends $BUILD_DEPS
          sudo apt-get install -y wget unzip ant maven

      - name: Setup gradle
        run: |
          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
          sudo mv /tmp/gradle-$GRADLE_VERSION /usr/local/gradle
          sudo ln -s /usr/local/gradle/bin/gradle /usr/local/bin
          gradle --version

      - name: Run spotlessCheck for Java
        run: |
          cd lib/java
          gradle spotlessCheck

      - name: Run ktfmtCheck for Kotlin
        run: |
          cd lib/kotlin
          gradle ktfmtCheck

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-java/with-java/' | sed 's/without-kotlin/with-kotlin/')

      - uses: actions/download-artifact@v8
        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 java
        run: make -C lib/java

      # this will invoke publishToMavenLocal and install locally
      - name: Run make install for java
        run: make -C lib/java install

      - name: Upload java libthrift artifacts
        uses: actions/upload-artifact@v7
        with:
          name: libthrift
          if-no-files-found: error
          path: ~/.m2/repository/org/apache/thrift

      - name: Run make check for java
        run: make -C lib/java check

      - name: Run make precross for java
        run: make -C lib/java precross

      - name: Upload java precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: java-precross
          if-no-files-found: error
          path: |
            lib/java/build/functionalTestJar/
            lib/java/build/runnonblockingclient
            lib/java/build/runclient
            lib/java/build/runnonblockingserver
            lib/java/build/runserver
            lib/java/build/runservletserver
          retention-days: 3

      - name: Run make for kotlin
        run: make -C lib/kotlin

      - name: Run make check for kotlin
        run: make -C lib/kotlin check

      - name: Run make precross for kotlin
        run: make -C lib/kotlin precross

      - name: Upload kotlin precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: kotlin-precross
          if-no-files-found: error
          path: |
            lib/kotlin/cross-test-client/build/install/TestClient/
            lib/kotlin/cross-test-server/build/install/TestServer/
          retention-days: 3

  lib-netstd:
    needs: compiler
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
    defaults:
      run:
        shell: bash  # required by net install script
    steps:
      - uses: actions/checkout@v6

      - 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

# This whole setup is getting worse: https://github.com/dotnet/core/discussions/9258
      - name: Set up .NET SDK (via install script)
        run: |
          # remove any existing install
          sudo apt remove dotnet*
          # install key
          sudo apt install gpg
          wget https://dot.net/v1/dotnet-install.asc
          gpg --import dotnet-install.asc
          # download and verify
          wget https://dot.net/v1/dotnet-install.sh
          wget https://dot.net/v1/dotnet-install.sig
          gpg --verify dotnet-install.sig dotnet-install.sh
          # run install script
          chmod +x dotnet-install.sh
          ./dotnet-install.sh --channel 10.0
          # export env vars
          export DOTNET_ROOT=$HOME/.dotnet
          export PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools
          dotnet --list-sdks

#      the sdk is installed by default, but keep this step for reference
#      especially newer versions are NOT always pre-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-10.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@v8
        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@v7
        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-24.04
    if: false                     # swift is currently broken and no maintainers around -> see THRIFT-5864
    steps:
      - uses: actions/checkout@v6

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-swift/with-swift/')

      - uses: actions/download-artifact@v8
        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 precross for swift
        run: make -C test/swift precross

      - name: Upload swift precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: swift-precross
          if-no-files-found: error
          path: |
            test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/TestServer
            test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/TestClient
          retention-days: 3

  lib-rust:
    needs: compiler
    runs-on: ubuntu-24.04
    if: false    # currently broken and no maintainers around -> see THRIFT-5917
    env:
      TOOLCHAIN_VERSION: 1.83.0
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends curl $BUILD_DEPS

      - name: Setup cargo
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
          rustup update
          rustup install $TOOLCHAIN_VERSION
          rustup default $TOOLCHAIN_VERSION
          rustup --version
          cargo --version
          rustc --version

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-rs/with-rs/')

      - uses: actions/download-artifact@v8
        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 rust
        run: make -C lib/rs

      - name: Run make check for rust
        run: make -C lib/rs check

      - name: Run make test for rust
        run: make -C lib/rs/test check

      - name: Run make precross for test rust
        run: make -C test/rs precross

      - name: Upload rust precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: rs-precross
          if-no-files-found: error
          path: |
            test/rs/bin/test_server
            test/rs/bin/test_client
          retention-days: 3

      - name: Run make test_recursive for rust
        run: make -C lib/rs/test_recursive check

  lib-python:
    needs: compiler
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: &python_versions ["3.10", "3.11", "3.12", "3.13", "3.14"]
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - 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

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}

      - name: Python setup
        run: |
          python -m pip install --upgrade pip setuptools wheel flake8 "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"
          python --version
          pip --version

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-py3/with-py3/')

      - uses: actions/download-artifact@v8
        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 python
        run: make -C lib/py

      - name: Run make install for python
        run: sudo make -C lib/py install

      - name: Run make check for python libs
        run: make -C lib/py check

      - name: Run make check for python code
        run: make -C test/py check

      - name: Run make precross for python
        if: matrix.python-version == '3.12'
        run: make -C test/py precross

      - name: Upload python precross artifacts
        if: matrix.python-version == '3.12'
        uses: actions/upload-artifact@v7
        with:
          name: py-precross
          if-no-files-found: error
          path: |
            lib/py/build/lib.*
            test/py/gen-py
            test/py/TestClient.py
            test/py/TestServer.py
            test/py/util.py
          retention-days: 3

  lib-python-macos:
    needs: compiler-macos
    strategy:
      matrix:
        os: *macos_versions
        python-version: *python_versions
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          brew install automake bison flex boost libevent openssl libtool pkg-config
          echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}

      - name: Python setup
        run: |
          python -m pip install --upgrade pip setuptools wheel flake8 "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"
          python --version
          pip --version

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-py3/with-py3/')

      - uses: actions/download-artifact@v8
        with:
          name: thrift-compiler-${{ matrix.os }}
          path: compiler/cpp

      - name: Run thrift-compiler
        run: |
          chmod a+x compiler/cpp/thrift
          compiler/cpp/thrift -version

      - name: Run make for python
        run: make -C lib/py

      - name: Run make install for python
        run: |
          sudo make -C lib/py install PY_PREFIX="$(python -c 'import sys; print(sys.prefix)')"

      - name: Run make for python libs
        run: make -C lib/py

      - name: Run make check for python libs
        run: make -C lib/py check

      - name: Run make check for python code
        run: make -C test/py check

  lib-nodejs:
    needs: compiler
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v6

      - 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@v8
        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

      - name: Run js precross
        run: make -C lib/nodejs precross

      - name: Run ts precross
        run: make -C lib/nodets precross

      - name: Upload nodejs precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: nodejs-precross
          if-no-files-found: error
          include-hidden-files: true
          path: |
            lib/nodejs/test/gen-nodejs
            lib/nodets/test/gen-nodejs
            lib/nodets/test-compiled
          retention-days: 3

  lib-cpp:
    needs: compiler
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v6

      - name: Install dependencies
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends g++ $BUILD_DEPS locales
          sudo locale-gen en_US.UTF-8
          sudo locale-gen de_DE.UTF-8
          sudo update-locale

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed -E 's/without-cpp/with-cpp/g')

      - uses: actions/download-artifact@v8
        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 cpp
        run: make -j$(nproc) -C lib/cpp

      - name: Run make check for lib/cpp
        run: make -j$(nproc) -C lib/cpp check

      - name: Run make check for test/cpp
        run: make -j$(nproc) -C test/cpp check

      - name: Run make precross for cpp test
        run: make -j$(nproc) -C test/cpp precross

      - name: Upload cpp precross artifacts
        uses: actions/upload-artifact@v7
        with:
          name: cpp-precross
          if-no-files-found: error
          include-hidden-files: true
          path: |
            test/cpp/TestClient
            test/cpp/TestServer
            test/cpp/.libs/TestClient
            test/cpp/.libs/TestServer
            lib/cpp/.libs/*.so
          retention-days: 3

      - name: Upload log files from failed test runs
        uses: actions/upload-artifact@v7
        if: failure()
        with:
          name: lib-cpp-test-log
          path: lib/cpp/test/*.xml
          retention-days: 3

  lib-ruby:
    needs: compiler
    runs-on: ubuntu-24.04
    name: lib-ruby (${{ matrix.ruby-version }}) ${{ matrix.skip-build-ext && 'noext' || '' }}
    strategy:
      matrix:
        ruby-version: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "4.0", "head"]
        skip-build-ext: [false]
        include:
          - ruby-version: "2.7"
            skip-build-ext: true
      fail-fast: false
    env:
      SKIP_BUILD_EXT: ${{ matrix.skip-build-ext && '1' || '' }}
    steps:
      - uses: actions/checkout@v6

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true
          working-directory: lib/rb

      - name: Run bootstrap
        run: ./bootstrap.sh

      - name: Run configure
        run: |
          ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-ruby/with-ruby/')

      - uses: actions/download-artifact@v8
        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 ruby
        run: make -C lib/rb

      - name: Run make check for lib/rb
        run: make -C lib/rb check

      - name: Run make check for test/rb
        run: make -C test/rb check

      - name: Run make precross for ruby test
        run: make -C test/rb precross

      - name: Upload ruby precross artifacts
        # has to match the version used in cross-test
        if: matrix.ruby-version == '2.7' && matrix.skip-build-ext == false
        uses: actions/upload-artifact@v7
        with:
          name: rb-precross
          if-no-files-found: error
          path: |
            test/rb/gen-rb/*
            lib/rb/ext/*.so
          retention-days: 3

  cross-test:
    needs:
      - lib-java-kotlin
      #- lib-swift                     # currently broken and no maintainers around -> see THRIFT-5864
      #- lib-rust                      # currently broken and no maintainers around -> see THRIFT-5917
      - lib-go
      - lib-python
      - lib-cpp
      - lib-ruby
      - lib-nodejs
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        # swift is currently broken and no maintainers around -> see THRIFT-5864
        # rust currently broken and no maintainers around -> see THRIFT-5917
        # kotlin cross test are failing -> see THRIFT-5879
        server_lang: ['java', 'go', 'cpp', 'py', 'rb', 'nodejs', 'nodets']
        # we always use comma join as many client langs as possible, to reduce the number of jobs
        client_lang: ['java,kotlin', 'go,cpp,py,nodejs,nodets', 'rb']
      fail-fast: false
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-python@v6
        with:
          python-version: "3.12"

      - name: Install Python test dependencies
        run: |
          python -m pip install --upgrade pip setuptools
          python -m pip install "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"

      - uses: actions/setup-java@v5
        with:
          distribution: temurin
          # here we intentionally use an older version so that we also verify Java 17 compiles to it
          java-version: 8
          cache: "gradle"

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: "2.7"
          bundler-cache: true
          working-directory: test/rb

      - name: Install openssl and certificates (for SSL tests)
        run: |
          sudo apt-get update -yq
          sudo apt-get install -y --no-install-recommends \
            openssl \
            ca-certificates \
            libboost-all-dev \
            libevent-dev

      - name: Download java precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: java-precross
          path: lib/java/build

      - name: Download kotlin precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: kotlin-precross
          path: lib/kotlin

      - name: Download swift precross artifacts
        uses: actions/download-artifact@v8
        if: false   # currently broken and no maintainers around -> see THRIFT-5864
        with:
          name: swift-precross
          path: test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug

      - name: Download rust precross artifacts
        uses: actions/download-artifact@v8
        if: false   # currently broken and no maintainers around -> see THRIFT-5917
        with:
          name: rs-precross
          path: test/rs/bin

      - name: Download go precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: go-precross
          path: test/go/bin

      - name: Download cpp precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: cpp-precross
          path: .

      - name: Download python precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: py-precross
          path: .

      - name: Download ruby precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: rb-precross
          path: .

      - name: Download nodejs and nodets precross artifacts
        uses: actions/download-artifact@v8
        with:
          name: nodejs-precross
          path: lib

      - name: Set back executable flags
        run: |
          chmod a+x lib/java/build/run*
          chmod a+x lib/kotlin/cross-test-client/build/install/TestClient/bin/*
          chmod a+x lib/kotlin/cross-test-server/build/install/TestServer/bin/*
          # THRIFT-5864  chmod a+x test/swift/CrossTests/.build/x86_64-unknown-linux-gnu/debug/*
          # THRIFT-5917  chmod a+x test/rs/bin/*
          chmod a+x test/go/bin/*
          chmod a+x test/cpp/*
          chmod a+x test/cpp/.libs/*
          chmod a+x lib/cpp/.libs/*.so
          chmod a+x test/py/*.py
          chmod a+x lib/rb/ext/*.so

      - name: Installs for nodets and nodejs
        run: |
          npm install .
          cd lib/nodejs/test/ && npm install .

      - name: Create tmp domain socket folder
        run: mkdir /tmp/v0.16

      - name: Run cross test
        env:
          THRIFT_CROSSTEST_CONCURRENCY: 4
        run: |
          python test/test.py \
            --retry-count 5 \
            --skip-known-failures \
            --server ${{ matrix.server_lang }} \
            --client ${{ matrix.client_lang }}

      - name: Upload log files from failed cross test runs
        uses: actions/upload-artifact@v7
        if: failure()
        with:
          name: cross-test-log_${{ matrix.server_lang }}-${{ matrix.client_lang }}
          path: test/log/
          retention-days: 3
thrift-0.23.0/FUZZING.md0000664000175000017500000000654415170003262015041 0ustar00buildbuild00000000000000# Fuzzing Apache Thrift

This document describes the fuzzing infrastructure and goals for Apache Thrift. 

We use [OSS-Fuzz](https://github.com/google/oss-fuzz) as our primary fuzzing platform to continuously test and improve the robustness of Thrift's hand-written and generated code.

## Goals

With fuzzing, we are focusing on testing the following key aspects across supported languages:

1. Security - Testing how the generated code handles malformed/malicious input
2. Serialization round-trip correctness - Ensuring that data stays identical if we serialize then deserialize it.

## Supported Languages

We currently maintain fuzzers for the following languages:

- Go
- c_glib (partially supported, needs round-trip support)
- C++
- Java/JVM (and other JVM languages)
- JavaScript
- Python
- Ruby
- Rust
- Swift

We are working on adding fuzzers for the following languages:

- netstd

## Fuzzer Types

For each supported language, we implement at minimum:

1. **Deserializer Fuzzer**
   - Takes raw fuzzer input and attempts to deserialize it into Thrift structures
   - Tests handling of malformed/unexpected input
   - Implemented for each supported protocol (Binary, Compact, JSON where available)

2. **Round-Trip Fuzzer** 
   - Deserializes fuzzer input, then re-serializes and verifies it matches
   - Ensures data integrity through serialization cycles
   - Tests both serialization and deserialization code paths

## Building and Running the Fuzzers

Each language has its own fuzzers under the `lib//test/fuzz` directory.
Build integration varies by language. C++, c_glib, Go, Rust, and Ruby wire fuzz code into their normal build systems so that code generation and build drift are caught early. Some languages also provide local runner targets or native fuzz binaries.

To ensure fuzzing can find issues as soon as possible, we will enable fuzzing support in CI once the fuzzers are stable.

Currently the only convenient, formally supported build with fuzzing support enabled is via the oss-fuzz workflow. For languages where local fuzzing is practical, documentation is provided alongside the fuzzers. For example, C++ builds libFuzzer binaries directly, while Ruby exposes `make` targets that wrap Ruzzy.

## OSS-Fuzz Integration

Our fuzzers run continuously on OSS-Fuzz. To view build status:

1. Visit the [OSS-Fuzz Status Dashboard](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
2. Look for the "thrift" project

The source code for the oss-fuzz build is [available upstream](https://github.com/google/oss-fuzz/tree/master/projects/thrift).

We aim to improve the fuzzers through viewing the fuzz introspector reports, available [here](https://introspector.oss-fuzz.com/project-profile?project=thrift).

*NB: The oss-fuzz integration will be significantly updated once all the language specific fuzzers are committed here.

## Contributing to the fuzzers

To contribute to the fuzzing effort - please look at https://issues.apache.org/jira/browse/THRIFT-5855 for the latest status and planned work. Once the ticket is closed,
we would still appreciate contributions that:

1. Add new fuzzers for unsupported languages
2. Improve existing fuzzers
3. Add test cases to corpus

If you do add or change a fuzzer, please remember to make corresponding changes to the oss-fuzz build script in case they are needed.

Please see CONTRIBUTING.md for general contribution guidelines.
thrift-0.23.0/bootstrap.sh0000775000175000017500000000361115165535636015752 0ustar00buildbuild00000000000000#!/bin/sh

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

echo -n "make distclean... "
make -k distclean >/dev/null 2>&1
echo "ok"

if test -d lib/php/src/ext/thrift_protocol ; then
    if phpize -v >/dev/null 2>/dev/null ; then
        (cd lib/php/src/ext/thrift_protocol && phpize)
    fi
fi

set -e

# libtoolize is called "glibtoolize" on OSX.
if libtoolize --version 1 >/dev/null 2>/dev/null; then
  LIBTOOLIZE=libtoolize
elif glibtoolize --version 1 >/dev/null 2>/dev/null; then
  LIBTOOLIZE=glibtoolize
else
  echo >&2 "Couldn't find libtoolize!"
  exit 1
fi

format_version () {
    printf "%03d%03d%03d%03d" $(echo $1 | tr '.' ' ');
}

# we require automake 1.13 or later
# check must happen externally due to use of newer macro
AUTOMAKE_VERSION=`automake --version | grep automake | egrep -o '([0-9]{1,}\.)+[0-9]{1,}'`
if  [ $(format_version $AUTOMAKE_VERSION) -lt $(format_version 1.13) ]; then
  echo >&2 "automake version $AUTOMAKE_VERSION is too old (need 1.13 or later)"
  exit 1
fi

set -e
autoscan
$LIBTOOLIZE --copy --automake
aclocal -I ./aclocal
autoheader
sed '/undef VERSION/d' config.hin > config.hin2
mv config.hin2 config.hin
autoconf
automake --copy --add-missing
thrift-0.23.0/appveyor.yml0000664000175000017500000001062615170007142015750 0ustar00buildbuild00000000000000#
# 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.
#

# build Apache Thrift on AppVeyor - https://ci.appveyor.com

version: '0.23.0.{build}'

shallow_clone: true

branches:
  only:
    - master
    - /^(release/)?\d+\.\d+\.\d+$/

# Note: We could abort all jobs on the first error, but then it
# becomes hard to learn from the other jobs results. Therefore disabled:
#matrix:
#  fast_finish: true

# See https://www.appveyor.com/docs/windows-images-software/ for available versions.

environment:
  matrix:
   # Python version test matrix (3.10-3.14) using MSVC2022
   - PROFILE: MSVC2022
     PROFILE_CLASS: MSVC
     APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
     PLATFORM: x64
     CONFIGURATION: Release
     BUILD_SHARED_LIBS: ON
     BOOST_VERSION: 1.89.0
     LIBEVENT_VERSION: 2.1.12
     PYTHON_VERSION: "3.10"
     QT_VERSION: 6.9.3
     ZLIB_VERSION: 1.3.1

   - PROFILE: MSVC2022
     PROFILE_CLASS: MSVC
     APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
     PLATFORM: x64
     CONFIGURATION: Release
     BUILD_SHARED_LIBS: ON
     BOOST_VERSION: 1.89.0
     LIBEVENT_VERSION: 2.1.12
     PYTHON_VERSION: "3.11"
     QT_VERSION: 6.9.3
     ZLIB_VERSION: 1.3.1

   - PROFILE: MSVC2022
     PROFILE_CLASS: MSVC
     APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
     PLATFORM: x64
     CONFIGURATION: Release
     BUILD_SHARED_LIBS: ON
     BOOST_VERSION: 1.89.0
     LIBEVENT_VERSION: 2.1.12
     PYTHON_VERSION: "3.12"
     QT_VERSION: 6.9.3
     ZLIB_VERSION: 1.3.1

   - PROFILE: MSVC2022
     PROFILE_CLASS: MSVC
     APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
     PLATFORM: x64
     CONFIGURATION: Release
     BUILD_SHARED_LIBS: ON
     BOOST_VERSION: 1.89.0
     LIBEVENT_VERSION: 2.1.12
     PYTHON_VERSION: "3.13"
     QT_VERSION: 6.9.3
     ZLIB_VERSION: 1.3.1

   - PROFILE: MSVC2022
     PROFILE_CLASS: MSVC
     APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
     PLATFORM: x64
     CONFIGURATION: Release
     BUILD_SHARED_LIBS: ON
     BOOST_VERSION: 1.89.0
     LIBEVENT_VERSION: 2.1.12
     PYTHON_VERSION: "3.14"
     QT_VERSION: 6.9.3
     ZLIB_VERSION: 1.3.1

   - PROFILE: MINGW
     PROFILE_CLASS: MINGW
     # Currently the the latest MSYS2 is in the following image:
     APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
     PLATFORM: x64
     CONFIGURATION: RelWithDebInfo
     DISABLED_TESTS: (StalenessCheckTest)

  # As of 2021.08.06, the Cygwin build is broken with a missing dll exception.
  # See for an example https://ci.appveyor.com/project/ApacheSoftwareFoundation/thrift/builds/40263513/job/a69xt6m4o0y9x1bw?fullLog=true
  # - PROFILE: CYGWIN
  #   PROFILE_CLASS: CYGWIN
  #   PLATFORM: x64
  #   CONFIGURATION: RelWithDebInfo
  #   DISABLED_TESTS: (ZlibTest|OpenSSLManualInitTest|TNonblockingServerTest)


build_script:
  - cd %APPVEYOR_BUILD_FOLDER%
  - call build\appveyor\%PROFILE_CLASS%-appveyor-full.bat


# artifact capture disabled as it might increase service cost for little gain:
#
# artifacts:
#  - path: local-thrift-inst
#    name: cmake installed content
#    type: zip
#
#  - path: local-thrift-build\Testing
#    name: ctest output
#    type: zip

# RDP support: use one or the other...
#
# enables RDP for each build job so you can inspect the environment at the beginning of the job:
# init:
#  - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
#
# enables RDP at the end of the build job so you can login and re-run
# commands to see why something failed...
# on_finish:
#   - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
#
# also need:
# environment:
#   APPVEYOR_RDP_PASSWORD: thr1FT2345$xyzZ
thrift-0.23.0/compile0000755000175000017500000001635015166015674014752 0ustar00buildbuild00000000000000#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.

scriptversion=2018-03-07.03; # UTC

# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# Written by Tom Tromey .
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

# This file is maintained in Automake, please report
# bugs to  or send patches to
# .

nl='
'

# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" ""	$nl"

file_conv=

# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
  file=$1
  case $file in
    / | /[!/]*) # absolute file, and not a UNC file
      if test -z "$file_conv"; then
	# lazily determine how to convert abs files
	case `uname -s` in
	  MINGW*)
	    file_conv=mingw
	    ;;
	  CYGWIN* | MSYS*)
	    file_conv=cygwin
	    ;;
	  *)
	    file_conv=wine
	    ;;
	esac
      fi
      case $file_conv/,$2, in
	*,$file_conv,*)
	  ;;
	mingw/*)
	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
	  ;;
	cygwin/* | msys/*)
	  file=`cygpath -m "$file" || echo "$file"`
	  ;;
	wine/*)
	  file=`winepath -w "$file" || echo "$file"`
	  ;;
      esac
      ;;
  esac
}

# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
  func_file_conv "$1"
  if test -z "$lib_path"; then
    lib_path=$file
  else
    lib_path="$lib_path;$file"
  fi
  linker_opts="$linker_opts -LIBPATH:$file"
}

# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
  lib=$1
  found=no
  save_IFS=$IFS
  IFS=';'
  for dir in $lib_path $LIB
  do
    IFS=$save_IFS
    if $shared && test -f "$dir/$lib.dll.lib"; then
      found=yes
      lib=$dir/$lib.dll.lib
      break
    fi
    if test -f "$dir/$lib.lib"; then
      found=yes
      lib=$dir/$lib.lib
      break
    fi
    if test -f "$dir/lib$lib.a"; then
      found=yes
      lib=$dir/lib$lib.a
      break
    fi
  done
  IFS=$save_IFS

  if test "$found" != yes; then
    lib=$lib.lib
  fi
}

# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
  # Assume a capable shell
  lib_path=
  shared=:
  linker_opts=
  for arg
  do
    if test -n "$eat"; then
      eat=
    else
      case $1 in
	-o)
	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
	  eat=1
	  case $2 in
	    *.o | *.[oO][bB][jJ])
	      func_file_conv "$2"
	      set x "$@" -Fo"$file"
	      shift
	      ;;
	    *)
	      func_file_conv "$2"
	      set x "$@" -Fe"$file"
	      shift
	      ;;
	  esac
	  ;;
	-I)
	  eat=1
	  func_file_conv "$2" mingw
	  set x "$@" -I"$file"
	  shift
	  ;;
	-I*)
	  func_file_conv "${1#-I}" mingw
	  set x "$@" -I"$file"
	  shift
	  ;;
	-l)
	  eat=1
	  func_cl_dashl "$2"
	  set x "$@" "$lib"
	  shift
	  ;;
	-l*)
	  func_cl_dashl "${1#-l}"
	  set x "$@" "$lib"
	  shift
	  ;;
	-L)
	  eat=1
	  func_cl_dashL "$2"
	  ;;
	-L*)
	  func_cl_dashL "${1#-L}"
	  ;;
	-static)
	  shared=false
	  ;;
	-Wl,*)
	  arg=${1#-Wl,}
	  save_ifs="$IFS"; IFS=','
	  for flag in $arg; do
	    IFS="$save_ifs"
	    linker_opts="$linker_opts $flag"
	  done
	  IFS="$save_ifs"
	  ;;
	-Xlinker)
	  eat=1
	  linker_opts="$linker_opts $2"
	  ;;
	-*)
	  set x "$@" "$1"
	  shift
	  ;;
	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
	  func_file_conv "$1"
	  set x "$@" -Tp"$file"
	  shift
	  ;;
	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
	  func_file_conv "$1" mingw
	  set x "$@" "$file"
	  shift
	  ;;
	*)
	  set x "$@" "$1"
	  shift
	  ;;
      esac
    fi
    shift
  done
  if test -n "$linker_opts"; then
    linker_opts="-link$linker_opts"
  fi
  exec "$@" $linker_opts
  exit 1
}

eat=

case $1 in
  '')
     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
     exit 1;
     ;;
  -h | --h*)
    cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]

Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.

If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.

Report bugs to .
EOF
    exit $?
    ;;
  -v | --v*)
    echo "compile $scriptversion"
    exit $?
    ;;
  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
    func_cl_wrapper "$@"      # Doesn't return...
    ;;
esac

ofile=
cfile=

for arg
do
  if test -n "$eat"; then
    eat=
  else
    case $1 in
      -o)
	# configure might choose to run compile as 'compile cc -o foo foo.c'.
	# So we strip '-o arg' only if arg is an object.
	eat=1
	case $2 in
	  *.o | *.obj)
	    ofile=$2
	    ;;
	  *)
	    set x "$@" -o "$2"
	    shift
	    ;;
	esac
	;;
      *.c)
	cfile=$1
	set x "$@" "$1"
	shift
	;;
      *)
	set x "$@" "$1"
	shift
	;;
    esac
  fi
  shift
done

if test -z "$ofile" || test -z "$cfile"; then
  # If no '-o' option was seen then we might have been invoked from a
  # pattern rule where we don't need one.  That is ok -- this is a
  # normal compilation that the losing compiler can handle.  If no
  # '.c' file was seen then we are probably linking.  That is also
  # ok.
  exec "$@"
fi

# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`

# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file.  Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
  if mkdir "$lockdir" >/dev/null 2>&1; then
    break
  fi
  sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15

# Run the compile.
"$@"
ret=$?

if test -f "$cofile"; then
  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi

rmdir "$lockdir"
exit $ret

# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
thrift-0.23.0/eslint.config.mjs0000664000175000017500000000171215165535636016653 0ustar00buildbuild00000000000000import 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",
    },
  },
];
thrift-0.23.0/aclocal.m40000644000175000017500000017607315170007166015235 0ustar00buildbuild00000000000000# generated automatically by aclocal 1.16.5 -*- Autoconf -*-

# Copyright (C) 1996-2021 Free Software Foundation, Inc.

# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],,
[m4_warning([this file was generated for autoconf 2.71.
You have another version of autoconf.  It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])

# pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
# serial 12 (pkg-config-0.29.2)

dnl Copyright © 2004 Scott James Remnant .
dnl Copyright © 2012-2015 Dan Nicholson 
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.

dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl     [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ

dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])

if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
	_pkg_min_version=m4_default([$1], [0.9.0])
	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
		AC_MSG_RESULT([yes])
	else
		AC_MSG_RESULT([no])
		PKG_CONFIG=""
	fi
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG

dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
  m4_default([$2], [:])
m4_ifvaln([$3], [else
  $3])dnl
fi])

dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
    pkg_cv_[]$1="$$1"
 elif test -n "$PKG_CONFIG"; then
    PKG_CHECK_EXISTS([$3],
                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
		      test "x$?" != "x0" && pkg_failed=yes ],
		     [pkg_failed=yes])
 else
    pkg_failed=untried
fi[]dnl
])dnl _PKG_CONFIG

dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
        _pkg_short_errors_supported=yes
else
        _pkg_short_errors_supported=no
fi[]dnl
])dnl _PKG_SHORT_ERRORS_SUPPORTED


dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl   [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl

pkg_failed=no
AC_MSG_CHECKING([for $2])

_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])

m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])

if test $pkg_failed = yes; then
        AC_MSG_RESULT([no])
        _PKG_SHORT_ERRORS_SUPPORTED
        if test $_pkg_short_errors_supported = yes; then
	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
        else
	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
        fi
	# Put the nasty error message in config.log where it belongs
	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD

	m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:

$$1_PKG_ERRORS

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

_PKG_TEXT])[]dnl
        ])
elif test $pkg_failed = untried; then
        AC_MSG_RESULT([no])
	m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old.  Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.

_PKG_TEXT

To get pkg-config, see .])[]dnl
        ])
else
	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
        AC_MSG_RESULT([yes])
	$3
fi[]dnl
])dnl PKG_CHECK_MODULES


dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl   [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC


dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
    [pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
    [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
    [with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_INSTALLDIR


dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
    [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
    [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
    [with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_NOARCH_INSTALLDIR


dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl

_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])

AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR

# Copyright (C) 2002-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version.  Point them to the right macro.
m4_if([$1], [1.16.5], [],
      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])

# _AM_AUTOCONF_VERSION(VERSION)
# -----------------------------
# aclocal traces this macro to find the Autoconf version.
# This is a private macro too.  Using m4_define simplifies
# the logic in aclocal, which can simply ignore this definition.
m4_define([_AM_AUTOCONF_VERSION], [])

# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.16.5])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])

# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-

# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory.  The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run.  This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
#    fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
#    fails if $ac_aux_dir is absolute,
#    fails when called from a subdirectory in a VPATH build with
#          a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir.  In an in-source build this is usually
# harmless because $srcdir is '.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
#   MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH.  The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.

AC_DEFUN([AM_AUX_DIR_EXPAND],
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
# Expand $ac_aux_dir to an absolute path.
am_aux_dir=`cd "$ac_aux_dir" && pwd`
])

# AM_CONDITIONAL                                            -*- Autoconf -*-

# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ([2.52])dnl
 m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
m4_define([_AM_COND_VALUE_$1], [$2])dnl
if $2; then
  $1_TRUE=
  $1_FALSE='#'
else
  $1_TRUE='#'
  $1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
  AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])

# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.


# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery.  Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...


# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl

m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],
      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
                    [depcc="$$1"   am_compiler_list=])

AC_CACHE_CHECK([dependency style of $depcc],
               [am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
  # We make a subdir and do the tests there.  Otherwise we can end up
  # making bogus files that we don't know about and never remove.  For
  # instance it was reported that on HP-UX the gcc test will end up
  # making a dummy file named 'D' -- because '-MD' means "put the output
  # in D".
  rm -rf conftest.dir
  mkdir conftest.dir
  # Copy depcomp to subdir because otherwise we won't find it if we're
  # using a relative directory.
  cp "$am_depcomp" conftest.dir
  cd conftest.dir
  # We will build objects and dependencies in a subdirectory because
  # it helps to detect inapplicable dependency modes.  For instance
  # both Tru64's cc and ICC support -MD to output dependencies as a
  # side effect of compilation, but ICC will put the dependencies in
  # the current directory while Tru64 will put them in the object
  # directory.
  mkdir sub

  am_cv_$1_dependencies_compiler_type=none
  if test "$am_compiler_list" = ""; then
     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
  fi
  am__universal=false
  m4_case([$1], [CC],
    [case " $depcc " in #(
     *\ -arch\ *\ -arch\ *) am__universal=true ;;
     esac],
    [CXX],
    [case " $depcc " in #(
     *\ -arch\ *\ -arch\ *) am__universal=true ;;
     esac])

  for depmode in $am_compiler_list; do
    # Setup a source with many dependencies, because some compilers
    # like to wrap large dependency lists on column 80 (with \), and
    # we should not choose a depcomp mode which is confused by this.
    #
    # We need to recreate these files for each test, as the compiler may
    # overwrite some of them when testing with obscure command lines.
    # This happens at least with the AIX C compiler.
    : > sub/conftest.c
    for i in 1 2 3 4 5 6; do
      echo '#include "conftst'$i'.h"' >> sub/conftest.c
      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
      # Solaris 10 /bin/sh.
      echo '/* dummy */' > sub/conftst$i.h
    done
    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf

    # We check with '-c' and '-o' for the sake of the "dashmstdout"
    # mode.  It turns out that the SunPro C++ compiler does not properly
    # handle '-M -o', and we need to detect this.  Also, some Intel
    # versions had trouble with output in subdirs.
    am__obj=sub/conftest.${OBJEXT-o}
    am__minus_obj="-o $am__obj"
    case $depmode in
    gcc)
      # This depmode causes a compiler race in universal mode.
      test "$am__universal" = false || continue
      ;;
    nosideeffect)
      # After this tag, mechanisms are not by side-effect, so they'll
      # only be used when explicitly requested.
      if test "x$enable_dependency_tracking" = xyes; then
	continue
      else
	break
      fi
      ;;
    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
      # This compiler won't grok '-c -o', but also, the minuso test has
      # not run yet.  These depmodes are late enough in the game, and
      # so weak that their functioning should not be impacted.
      am__obj=conftest.${OBJEXT-o}
      am__minus_obj=
      ;;
    none) break ;;
    esac
    if depmode=$depmode \
       source=sub/conftest.c object=$am__obj \
       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
         >/dev/null 2>conftest.err &&
       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
      # icc doesn't choke on unknown options, it will just issue warnings
      # or remarks (even with -Werror).  So we grep stderr for any message
      # that says an option was ignored or not supported.
      # When given -MP, icc 7.0 and 7.1 complain thusly:
      #   icc: Command line warning: ignoring option '-M'; no argument required
      # The diagnosis changed in icc 8.0:
      #   icc: Command line remark: option '-MP' not supported
      if (grep 'ignoring option' conftest.err ||
          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
        am_cv_$1_dependencies_compiler_type=$depmode
        break
      fi
    fi
  done

  cd ..
  rm -rf conftest.dir
else
  am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
  test "x$enable_dependency_tracking" != xno \
  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])


# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])


# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE([dependency-tracking], [dnl
AS_HELP_STRING(
  [--enable-dependency-tracking],
  [do not reject slow dependency extractors])
AS_HELP_STRING(
  [--disable-dependency-tracking],
  [speeds up one-time build])])
if test "x$enable_dependency_tracking" != xno; then
  am_depcomp="$ac_aux_dir/depcomp"
  AMDEPBACKSLASH='\'
  am__nodep='_no'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
AC_SUBST([am__nodep])dnl
_AM_SUBST_NOTMAKE([am__nodep])dnl
])

# Generate code to set up dependency tracking.              -*- Autoconf -*-

# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
  # Older Autoconf quotes --file arguments for eval, but not when files
  # are listed without --file.  Let's play safe and only enable the eval
  # if we detect the quoting.
  # TODO: see whether this extra hack can be removed once we start
  # requiring Autoconf 2.70 or later.
  AS_CASE([$CONFIG_FILES],
          [*\'*], [eval set x "$CONFIG_FILES"],
          [*], [set x $CONFIG_FILES])
  shift
  # Used to flag and report bootstrapping failures.
  am_rc=0
  for am_mf
  do
    # Strip MF so we end up with the name of the file.
    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
    # Check whether this is an Automake generated Makefile which includes
    # dependency-tracking related rules and includes.
    # Grep'ing the whole file directly is not great: AIX grep has a line
    # limit of 2048, but all sed's we know have understand at least 4000.
    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
      || continue
    am_dirpart=`AS_DIRNAME(["$am_mf"])`
    am_filepart=`AS_BASENAME(["$am_mf"])`
    AM_RUN_LOG([cd "$am_dirpart" \
      && sed -e '/# am--include-marker/d' "$am_filepart" \
        | $MAKE -f - am--depfiles]) || am_rc=$?
  done
  if test $am_rc -ne 0; then
    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
    for automatic dependency tracking.  If GNU make was not used, consider
    re-running the configure script with MAKE="gmake" (or whatever is
    necessary).  You can also try re-running configure with the
    '--disable-dependency-tracking' option to at least be able to build
    the package (albeit without support for automatic dependency tracking).])
  fi
  AS_UNSET([am_dirpart])
  AS_UNSET([am_filepart])
  AS_UNSET([am_mf])
  AS_UNSET([am_rc])
  rm -f conftest-deps.mk
}
])# _AM_OUTPUT_DEPENDENCY_COMMANDS


# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking is enabled.
# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
# order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])

# AM_EXTRA_RECURSIVE_TARGETS                                -*- Autoconf -*-

# Copyright (C) 2012-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_EXTRA_RECURSIVE_TARGETS
# --------------------------
# Define the list of user recursive targets.  This macro exists only to
# be traced by Automake, which will ensure that a proper definition of
# user-defined recursive targets (and associated rules) is propagated
# into all the generated Makefiles.
# TODO: We should really reject non-literal arguments here...
AC_DEFUN([AM_EXTRA_RECURSIVE_TARGETS], [])

# Do all the work for Automake.                             -*- Autoconf -*-

# Copyright (C) 1996-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This macro actually does too much.  Some checks are only needed if
# your package does certain things.  But this isn't really a big deal.

dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
m4_define([AC_PROG_CC],
m4_defn([AC_PROG_CC])
[_AM_PROG_CC_C_O
])

# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out.  PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition.  After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.65])dnl
m4_ifdef([_$0_ALREADY_INIT],
  [m4_fatal([$0 expanded multiple times
]m4_defn([_$0_ALREADY_INIT]))],
  [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl
dnl Autoconf wants to disallow AM_ names.  We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
if test "`cd $srcdir && pwd`" != "`pwd`"; then
  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
  # is not polluted with repeated "-I."
  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
  # test to see if srcdir already configured
  if test -f $srcdir/config.status; then
    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
  fi
fi

# test whether we have cygpath
if test -z "$CYGPATH_W"; then
  if (cygpath --version) >/dev/null 2>/dev/null; then
    CYGPATH_W='cygpath -w'
  else
    CYGPATH_W=echo
  fi
fi
AC_SUBST([CYGPATH_W])

# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[AC_DIAGNOSE([obsolete],
             [$0: two- and three-arguments forms are deprecated.])
m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
 AC_SUBST([PACKAGE], [$1])dnl
 AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(
  m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),
  [ok:ok],,
  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
 AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
 AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl

_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
 AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl

# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
AM_MISSING_PROG([AUTOCONF], [autoconf])
AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
AM_MISSING_PROG([AUTOHEADER], [autoheader])
AM_MISSING_PROG([MAKEINFO], [makeinfo])
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# For better backward compatibility.  To be removed once Automake 1.9.x
# dies out for good.  For more background, see:
# 
# 
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target (and possibly the TAP driver).  The
# system "awk" is bad on some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
			     [_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
		  [_AM_DEPENDENCIES([CC])],
		  [m4_define([AC_PROG_CC],
			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
		  [_AM_DEPENDENCIES([CXX])],
		  [m4_define([AC_PROG_CXX],
			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
		  [_AM_DEPENDENCIES([OBJC])],
		  [m4_define([AC_PROG_OBJC],
			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
		  [_AM_DEPENDENCIES([OBJCXX])],
		  [m4_define([AC_PROG_OBJCXX],
			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
# Variables for tags utilities; see am/tags.am
if test -z "$CTAGS"; then
  CTAGS=ctags
fi
AC_SUBST([CTAGS])
if test -z "$ETAGS"; then
  ETAGS=etags
fi
AC_SUBST([ETAGS])
if test -z "$CSCOPE"; then
  CSCOPE=cscope
fi
AC_SUBST([CSCOPE])

AC_REQUIRE([AM_SILENT_RULES])dnl
dnl The testsuite driver may need to know about EXEEXT, so add the
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl

# POSIX will say in a future version that running "rm -f" with no argument
# is OK; and we want to be able to make that assumption in our Makefile
# recipes.  So use an aggressive probe to check that the usage we want is
# actually supported "in the wild" to an acceptable degree.
# See automake bug#10828.
# To make any issue more visible, cause the running configure to be aborted
# by default if the 'rm' program in use doesn't match our expectations; the
# user can still override this though.
if rm -f && rm -fr && rm -rf; then : OK; else
  cat >&2 <<'END'
Oops!

Your 'rm' program seems unable to run without file operands specified
on the command line, even when the '-f' option is present.  This is contrary
to the behaviour of most rm programs out there, and not conforming with
the upcoming POSIX standard: 

Please tell bug-automake@gnu.org about your system, including the value
of your $PATH and any error possibly output before this message.  This
can help us improve future automake versions.

END
  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
    echo 'Configuration will proceed anyway, since you have set the' >&2
    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
    echo >&2
  else
    cat >&2 <<'END'
Aborting the configuration process, to ensure you take notice of the issue.

You can download and install GNU coreutils to get an 'rm' implementation
that behaves properly: .

If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
to "yes", and re-run configure.

END
    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
  fi
fi
dnl The trailing newline in this macro's definition is deliberate, for
dnl backward compatibility and to allow trailing 'dnl'-style comments
dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
])

dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])

# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated.  The stamp files are numbered to have different names.

# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_arg=$1
_am_stamp_count=1
for _am_header in $config_headers :; do
  case $_am_header in
    $_am_arg | $_am_arg:* )
      break ;;
    * )
      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
  esac
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])

# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
if test x"${install_sh+set}" != xset; then
  case $am_aux_dir in
  *\ * | *\	*)
    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
  *)
    install_sh="\${SHELL} $am_aux_dir/install-sh"
  esac
fi
AC_SUBST([install_sh])])

# Copyright (C) 2003-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# Check whether the underlying file-system supports filenames
# with a leading dot.  For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
  am__leading_dot=.
else
  am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])

# Copyright (C) 1998-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_PROG_LEX
# -----------
# Autoconf leaves LEX=: if lex or flex can't be found.  Change that to a
# "missing" invocation, for better error output.
AC_DEFUN([AM_PROG_LEX],
[AC_PREREQ([2.50])dnl
AC_REQUIRE([AM_MISSING_HAS_RUN])dnl
AC_REQUIRE([AC_PROG_LEX])dnl
if test "$LEX" = :; then
  LEX=${am_missing_run}flex
fi])

# Check to see how 'make' treats includes.	            -*- Autoconf -*-

# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_MAKE_INCLUDE()
# -----------------
# Check whether make has an 'include' directive that can support all
# the idioms we need for our automatic dependency tracking code.
AC_DEFUN([AM_MAKE_INCLUDE],
[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
cat > confinc.mk << 'END'
am__doit:
	@echo this is the am__doit target >confinc.out
.PHONY: am__doit
END
am__include="#"
am__quote=
# BSD make does it like this.
echo '.include "confinc.mk" # ignored' > confmf.BSD
# Other make implementations (GNU, Solaris 10, AIX) do it like this.
echo 'include confinc.mk # ignored' > confmf.GNU
_am_result=no
for s in GNU BSD; do
  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
  AS_CASE([$?:`cat confinc.out 2>/dev/null`],
      ['0:this is the am__doit target'],
      [AS_CASE([$s],
          [BSD], [am__include='.include' am__quote='"'],
          [am__include='include' am__quote=''])])
  if test "$am__include" != "#"; then
    _am_result="yes ($s style)"
    break
  fi
done
rm -f confinc.* confmf.*
AC_MSG_RESULT([${_am_result}])
AC_SUBST([am__include])])
AC_SUBST([am__quote])])

# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-

# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])

# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it is modern enough.
# If it is, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
if test x"${MISSING+set}" != xset; then
  MISSING="\${SHELL} '$am_aux_dir/missing'"
fi
# Use eval to expand $SHELL
if eval "$MISSING --is-lightweight"; then
  am_missing_run="$MISSING "
else
  am_missing_run=
  AC_MSG_WARN(['missing' script is too old or missing])
fi
])

# Helper functions for option handling.                     -*- Autoconf -*-

# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])

# _AM_SET_OPTION(NAME)
# --------------------
# Set option NAME.  Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), [1])])

# _AM_SET_OPTIONS(OPTIONS)
# ------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])

# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])

# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# _AM_PROG_CC_C_O
# ---------------
# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
# to automatically call this.
AC_DEFUN([_AM_PROG_CC_C_O],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([compile])dnl
AC_LANG_PUSH([C])dnl
AC_CACHE_CHECK(
  [whether $CC understands -c and -o together],
  [am_cv_prog_cc_c_o],
  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
  # Make sure it works both with $CC and with simple cc.
  # Following AC_PROG_CC_C_O, we do the test twice because some
  # compilers refuse to overwrite an existing .o file with -o,
  # though they will create one.
  am_cv_prog_cc_c_o=yes
  for am_i in 1 2; do
    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
         && test -f conftest2.$ac_objext; then
      : OK
    else
      am_cv_prog_cc_c_o=no
      break
    fi
  done
  rm -f core conftest*
  unset am_i])
if test "$am_cv_prog_cc_c_o" != yes; then
   # Losing compiler, so override with the script.
   # FIXME: It is wrong to rewrite CC.
   # But if we don't then we get into trouble of one sort or another.
   # A longer-term fix would be to have automake use am__CC in this case,
   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
   CC="$am_aux_dir/compile $CC"
fi
AC_LANG_POP([C])])

# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])

# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.


# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# ---------------------------------------------------------------------------
# Adds support for distributing Python modules and packages.  To
# install modules, copy them to $(pythondir), using the python_PYTHON
# automake variable.  To install a package with the same name as the
# automake package, install to $(pkgpythondir), or use the
# pkgpython_PYTHON automake variable.
#
# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
# locations to install python extension modules (shared libraries).
# Another macro is required to find the appropriate flags to compile
# extension modules.
#
# If your package is configured with a different prefix to python,
# users will have to add the install directory to the PYTHONPATH
# environment variable, or create a .pth file (see the python
# documentation for details).
#
# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
# cause an error if the version of python installed on the system
# doesn't meet the requirement.  MINIMUM-VERSION should consist of
# numbers and dots only.
AC_DEFUN([AM_PATH_PYTHON],
 [
  dnl Find a Python interpreter.  Python versions prior to 2.0 are not
  dnl supported. (2.0 was released on October 16, 2000).
  m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
[python python2 python3 dnl
 python3.11 python3.10 dnl
 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl
 python3.2 python3.1 python3.0 dnl
 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl
 python2.0])

  AC_ARG_VAR([PYTHON], [the Python interpreter])

  m4_if([$1],[],[
    dnl No version check is needed.
    # Find any Python interpreter.
    if test -z "$PYTHON"; then
      AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
    fi
    am_display_PYTHON=python
  ], [
    dnl A version check is needed.
    if test -n "$PYTHON"; then
      # If the user set $PYTHON, use it and don't search something else.
      AC_MSG_CHECKING([whether $PYTHON version is >= $1])
      AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
			      [AC_MSG_RESULT([yes])],
			      [AC_MSG_RESULT([no])
			       AC_MSG_ERROR([Python interpreter is too old])])
      am_display_PYTHON=$PYTHON
    else
      # Otherwise, try each interpreter until we find one that satisfies
      # VERSION.
      AC_CACHE_CHECK([for a Python interpreter with version >= $1],
	[am_cv_pathless_PYTHON],[
	for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
	  test "$am_cv_pathless_PYTHON" = none && break
	  AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
	done])
      # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
      if test "$am_cv_pathless_PYTHON" = none; then
	PYTHON=:
      else
        AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
      fi
      am_display_PYTHON=$am_cv_pathless_PYTHON
    fi
  ])

  if test "$PYTHON" = :; then
    dnl Run any user-specified action, or abort.
    m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
  else

  dnl Query Python for its version number.  Although site.py simply uses
  dnl sys.version[:3], printing that failed with Python 3.10, since the
  dnl trailing zero was eliminated. So now we output just the major
  dnl and minor version numbers, as numbers. Apparently the tertiary
  dnl version is not of interest.
  dnl
  AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
    [am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[[:2]])"`])
  AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])

  dnl At times, e.g., when building shared libraries, you may want
  dnl to know which OS platform Python thinks this is.
  dnl
  AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
    [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
  AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])

  dnl emacs-page
  dnl If --with-python-sys-prefix is given, use the values of sys.prefix
  dnl and sys.exec_prefix for the corresponding values of PYTHON_PREFIX
  dnl and PYTHON_EXEC_PREFIX. Otherwise, use the GNU ${prefix} and
  dnl ${exec_prefix} variables.
  dnl
  dnl The two are made distinct variables so they can be overridden if
  dnl need be, although general consensus is that you shouldn't need
  dnl this separation.
  dnl
  dnl Also allow directly setting the prefixes via configure options,
  dnl overriding any default.
  dnl
  if test "x$prefix" = xNONE; then
    am__usable_prefix=$ac_default_prefix
  else
    am__usable_prefix=$prefix
  fi

  # Allow user to request using sys.* values from Python,
  # instead of the GNU $prefix values.
  AC_ARG_WITH([python-sys-prefix],
  [AS_HELP_STRING([--with-python-sys-prefix],
                  [use Python's sys.prefix and sys.exec_prefix values])],
  [am_use_python_sys=:],
  [am_use_python_sys=false])

  # Allow user to override whatever the default Python prefix is.
  AC_ARG_WITH([python_prefix],
  [AS_HELP_STRING([--with-python_prefix],
                  [override the default PYTHON_PREFIX])],
  [am_python_prefix_subst=$withval
   am_cv_python_prefix=$withval
   AC_MSG_CHECKING([for explicit $am_display_PYTHON prefix])
   AC_MSG_RESULT([$am_cv_python_prefix])],
  [
   if $am_use_python_sys; then
     # using python sys.prefix value, not GNU
     AC_CACHE_CHECK([for python default $am_display_PYTHON prefix],
     [am_cv_python_prefix],
     [am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`])

     dnl If sys.prefix is a subdir of $prefix, replace the literal value of
     dnl $prefix with a variable reference so it can be overridden.
     case $am_cv_python_prefix in
     $am__usable_prefix*)
       am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'`
       am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"`
       ;;
     *)
       am_python_prefix_subst=$am_cv_python_prefix
       ;;
     esac
   else # using GNU prefix value, not python sys.prefix
     am_python_prefix_subst='${prefix}'
     am_python_prefix=$am_python_prefix_subst
     AC_MSG_CHECKING([for GNU default $am_display_PYTHON prefix])
     AC_MSG_RESULT([$am_python_prefix])
   fi])
  # Substituting python_prefix_subst value.
  AC_SUBST([PYTHON_PREFIX], [$am_python_prefix_subst])

  # emacs-page Now do it all over again for Python exec_prefix, but with yet
  # another conditional: fall back to regular prefix if that was specified.
  AC_ARG_WITH([python_exec_prefix],
  [AS_HELP_STRING([--with-python_exec_prefix],
                  [override the default PYTHON_EXEC_PREFIX])],
  [am_python_exec_prefix_subst=$withval
   am_cv_python_exec_prefix=$withval
   AC_MSG_CHECKING([for explicit $am_display_PYTHON exec_prefix])
   AC_MSG_RESULT([$am_cv_python_exec_prefix])],
  [
   # no explicit --with-python_exec_prefix, but if
   # --with-python_prefix was given, use its value for python_exec_prefix too.
   AS_IF([test -n "$with_python_prefix"],
   [am_python_exec_prefix_subst=$with_python_prefix
    am_cv_python_exec_prefix=$with_python_prefix
    AC_MSG_CHECKING([for python_prefix-given $am_display_PYTHON exec_prefix])
    AC_MSG_RESULT([$am_cv_python_exec_prefix])],
   [
    # Set am__usable_exec_prefix whether using GNU or Python values,
    # since we use that variable for pyexecdir.
    if test "x$exec_prefix" = xNONE; then
      am__usable_exec_prefix=$am__usable_prefix
    else
      am__usable_exec_prefix=$exec_prefix
    fi
    #
    if $am_use_python_sys; then # using python sys.exec_prefix, not GNU
      AC_CACHE_CHECK([for python default $am_display_PYTHON exec_prefix],
      [am_cv_python_exec_prefix],
      [am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`])
      dnl If sys.exec_prefix is a subdir of $exec_prefix, replace the
      dnl literal value of $exec_prefix with a variable reference so it can
      dnl be overridden.
      case $am_cv_python_exec_prefix in
      $am__usable_exec_prefix*)
        am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'`
        am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"`
        ;;
      *)
        am_python_exec_prefix_subst=$am_cv_python_exec_prefix
        ;;
     esac
   else # using GNU $exec_prefix, not python sys.exec_prefix
     am_python_exec_prefix_subst='${exec_prefix}'
     am_python_exec_prefix=$am_python_exec_prefix_subst
     AC_MSG_CHECKING([for GNU default $am_display_PYTHON exec_prefix])
     AC_MSG_RESULT([$am_python_exec_prefix])
   fi])])
  # Substituting python_exec_prefix_subst.
  AC_SUBST([PYTHON_EXEC_PREFIX], [$am_python_exec_prefix_subst])

  # Factor out some code duplication into this shell variable.
  am_python_setup_sysconfig="\
import sys
# Prefer sysconfig over distutils.sysconfig, for better compatibility
# with python 3.x.  See automake bug#10227.
try:
    import sysconfig
except ImportError:
    can_use_sysconfig = 0
else:
    can_use_sysconfig = 1
# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
# 
try:
    from platform import python_implementation
    if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
        can_use_sysconfig = 0
except ImportError:
    pass"

  dnl emacs-page Set up 4 directories:

  dnl 1. pythondir: where to install python scripts.  This is the
  dnl    site-packages directory, not the python standard library
  dnl    directory like in previous automake betas.  This behavior
  dnl    is more consistent with lispdir.m4 for example.
  dnl Query distutils for this directory.
  dnl
  AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)],
  [am_cv_python_pythondir],
  [if test "x$am_cv_python_prefix" = x; then
     am_py_prefix=$am__usable_prefix
   else
     am_py_prefix=$am_cv_python_prefix
   fi
   am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
  if hasattr(sysconfig, 'get_default_scheme'):
    scheme = sysconfig.get_default_scheme()
  else:
    scheme = sysconfig._get_default_scheme()
  if scheme == 'posix_local':
    # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
    scheme = 'posix_prefix'
  sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'})
else:
  from distutils import sysconfig
  sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
   #
   case $am_cv_python_pythondir in
   $am_py_prefix*)
     am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
     am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"`
     ;;
   *)
     case $am_py_prefix in
       /usr|/System*) ;;
       *) am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages"
          ;;
     esac
     ;;
   esac
  ])
  AC_SUBST([pythondir], [$am_cv_python_pythondir])

  dnl 2. pkgpythondir: $PACKAGE directory under pythondir.  Was
  dnl    PYTHON_SITE_PACKAGE in previous betas, but this naming is
  dnl    more consistent with the rest of automake.
  dnl
  AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])

  dnl 3. pyexecdir: directory for installing python extension modules
  dnl    (shared libraries).
  dnl Query distutils for this directory.
  dnl
  AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)],
  [am_cv_python_pyexecdir],
  [if test "x$am_cv_python_exec_prefix" = x; then
     am_py_exec_prefix=$am__usable_exec_prefix
   else
     am_py_exec_prefix=$am_cv_python_exec_prefix
   fi
   am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
  if hasattr(sysconfig, 'get_default_scheme'):
    scheme = sysconfig.get_default_scheme()
  else:
    scheme = sysconfig._get_default_scheme()
  if scheme == 'posix_local':
    # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
    scheme = 'posix_prefix'
  sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'})
else:
  from distutils import sysconfig
  sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix')
sys.stdout.write(sitedir)"`
   #
   case $am_cv_python_pyexecdir in
   $am_py_exec_prefix*)
     am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
     am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"`
     ;;
   *)
     case $am_py_exec_prefix in
       /usr|/System*) ;;
       *) am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages"
          ;;
     esac
     ;;
   esac
  ])
  AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])

  dnl 4. pkgpyexecdir: $(pyexecdir)/$(PACKAGE)
  dnl
  AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])

  dnl Run any user-specified action.
  $2
  fi
])


# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
# ---------------------------------------------------------------------------
# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
# Run ACTION-IF-FALSE otherwise.
# This test uses sys.hexversion instead of the string equivalent (first
# word of sys.version), in order to cope with versions such as 2.2c1.
# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
AC_DEFUN([AM_PYTHON_CHECK_VERSION],
 [prog="import sys
# split strings by '.' and convert to numeric.  Append some zeros
# because we need at least 4 digits for the hex conversion.
# map returns an iterator in Python 3.0 and a list in 2.x
minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
minverhex = 0
# xrange is not present in Python 3.0 and range returns an iterator
for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
sys.exit(sys.hexversion < minverhex)"
  AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])

# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_RUN_LOG(COMMAND)
# -------------------
# Run COMMAND, save the exit status in ac_status, and log it.
# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
AC_DEFUN([AM_RUN_LOG],
[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
   (exit $ac_status); }])

# Check to make sure that the build environment is sane.    -*- Autoconf -*-

# Copyright (C) 1996-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Reject unsafe characters in $srcdir or the absolute working directory
# name.  Accept space and tab only in the latter.
am_lf='
'
case `pwd` in
  *[[\\\"\#\$\&\'\`$am_lf]]*)
    AC_MSG_ERROR([unsafe absolute working directory name]);;
esac
case $srcdir in
  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
    AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
esac

# Do 'set' in a subshell so we don't clobber the current shell's
# arguments.  Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
   am_has_slept=no
   for am_try in 1 2; do
     echo "timestamp, slept: $am_has_slept" > conftest.file
     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
     if test "$[*]" = "X"; then
	# -L didn't work.
	set X `ls -t "$srcdir/configure" conftest.file`
     fi
     if test "$[*]" != "X $srcdir/configure conftest.file" \
	&& test "$[*]" != "X conftest.file $srcdir/configure"; then

	# If neither matched, then we have a broken ls.  This can happen
	# if, for instance, CONFIG_SHELL is bash and it inherits a
	# broken ls alias from the environment.  This has actually
	# happened.  Such a system could not be considered "sane".
	AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
  alias in your environment])
     fi
     if test "$[2]" = conftest.file || test $am_try -eq 2; then
       break
     fi
     # Just in case.
     sleep 1
     am_has_slept=yes
   done
   test "$[2]" = conftest.file
   )
then
   # Ok.
   :
else
   AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT([yes])
# If we didn't sleep, we still need to ensure time stamps of config.status and
# generated files are strictly newer.
am_sleep_pid=
if grep 'slept: no' conftest.file >/dev/null 2>&1; then
  ( sleep 1 ) &
  am_sleep_pid=$!
fi
AC_CONFIG_COMMANDS_PRE(
  [AC_MSG_CHECKING([that generated files are newer than configure])
   if test -n "$am_sleep_pid"; then
     # Hide warnings about reused PIDs.
     wait $am_sleep_pid 2>/dev/null
   fi
   AC_MSG_RESULT([done])])
rm -f conftest.file
])

# Copyright (C) 2009-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_SILENT_RULES([DEFAULT])
# --------------------------
# Enable less verbose build rules; with the default set to DEFAULT
# ("yes" being less verbose, "no" or empty being verbose).
AC_DEFUN([AM_SILENT_RULES],
[AC_ARG_ENABLE([silent-rules], [dnl
AS_HELP_STRING(
  [--enable-silent-rules],
  [less verbose build output (undo: "make V=1")])
AS_HELP_STRING(
  [--disable-silent-rules],
  [verbose build output (undo: "make V=0")])dnl
])
case $enable_silent_rules in @%:@ (((
  yes) AM_DEFAULT_VERBOSITY=0;;
   no) AM_DEFAULT_VERBOSITY=1;;
    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
esac
dnl
dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
dnl do not support nested variable expansions.
dnl See automake bug#9928 and bug#10237.
am_make=${MAKE-make}
AC_CACHE_CHECK([whether $am_make supports nested variables],
   [am_cv_make_support_nested_variables],
   [if AS_ECHO([['TRUE=$(BAR$(V))
BAR0=false
BAR1=true
V=1
am__doit:
	@$(TRUE)
.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
  am_cv_make_support_nested_variables=yes
else
  am_cv_make_support_nested_variables=no
fi])
if test $am_cv_make_support_nested_variables = yes; then
  dnl Using '$V' instead of '$(V)' breaks IRIX make.
  AM_V='$(V)'
  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
else
  AM_V=$AM_DEFAULT_VERBOSITY
  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
fi
AC_SUBST([AM_V])dnl
AM_SUBST_NOTMAKE([AM_V])dnl
AC_SUBST([AM_DEFAULT_V])dnl
AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
AM_BACKSLASH='\'
AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])

# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor 'install' (even GNU) is that you can't
# specify the program used to strip binaries.  This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in "make install-strip", and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using 'strip' when the user
# run "make install-strip".  However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the 'STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
if test "$cross_compiling" != no; then
  AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])

# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])

# AM_SUBST_NOTMAKE(VARIABLE)
# --------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])

m4_include([aclocal/ac_prog_bison.m4])
m4_include([aclocal/ax_boost_base.m4])
m4_include([aclocal/ax_check_openssl.m4])
m4_include([aclocal/ax_compare_version.m4])
m4_include([aclocal/ax_cxx_compile_stdcxx.m4])
m4_include([aclocal/ax_cxx_compile_stdcxx_11.m4])
m4_include([aclocal/ax_dmd.m4])
m4_include([aclocal/ax_javac_and_java.m4])
m4_include([aclocal/ax_lib_event.m4])
m4_include([aclocal/ax_lib_zlib.m4])
m4_include([aclocal/ax_lua.m4])
m4_include([aclocal/ax_prog_dotnetcore_version.m4])
m4_include([aclocal/ax_prog_haxe_version.m4])
m4_include([aclocal/ax_prog_perl_modules.m4])
m4_include([aclocal/ax_signed_right_shift.m4])
m4_include([aclocal/ax_thrift_internal.m4])
m4_include([aclocal/libtool.m4])
m4_include([aclocal/ltoptions.m4])
m4_include([aclocal/ltsugar.m4])
m4_include([aclocal/ltversion.m4])
m4_include([aclocal/lt~obsolete.m4])
m4_include([aclocal/tar.m4])
thrift-0.23.0/doap.rdf0000664000175000017500000002032515170007142014775 0ustar00buildbuild00000000000000



  
    2012-04-14
    
    Apache Thrift
    
    
    Apache Thrift software provides a framework for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages. 
    Apache Thrift allows you to define data types and service interfaces in a simple definition file. Taking that file as input, the compiler generates code to be used to easily build RPC clients and servers that communicate seamlessly across programming languages. Instead of writing a load of boilerplate code to serialize and transport your objects and invoke remote methods, you can get right down to business. 
    
    
    
    C
    C#
    C++
    D
    Dart
    Delphi
    Erlang
    Go
    Haxe
    Java
    JavaScript
    node.js
    OCaml
    Perl
    PHP
    Python
    Rust
    SmallTalk
    
    
    
    
    
      
        Apache Thrift
        2025-04-08
        0.23.0
      
      
        Apache Thrift
        2025-05-14
        0.22.0
      
      
        Apache Thrift
        2024-09-02
        0.21.0
      
      
        Apache Thrift
        2024-02-04
        0.20.0
      
      
        Apache Thrift
        2023-07-15
        0.19.0
      
      
        Apache Thrift
        2023-02-15
        0.18.1
      
      
        Apache Thrift
        2023-02-06
        0.18.0
      
      
        Apache Thrift
        2022-08-30
        0.17.0
      
      
        Apache Thrift
        2022-01-20
        0.16.0
      
      
        Apache Thrift
        2021-08-03
        0.15.0
      
      
        Apache Thrift
        2021-06-11
        0.14.2
      
      
        Apache Thrift
        2021-03-02
        0.14.1
      
      
        Apache Thrift
        2021-02-04
        0.14.0
      
      
        Apache Thrift
        2019-10-11
        0.13.0
      
      
        Apache Thrift
        2018-12-28
        0.12.0
      
      
        Apache Thrift
        2017-11-30
        0.11.0
      
      
        Apache Thrift
        2017-03-01
        0.10.0
      
      
        Apache Thrift
        2015-09-25
        0.9.3
      
      
        Apache Thrift
        2014-11-05
        0.9.2
      
      
        Apache Thrift
        2013-08-22
        0.9.1
      
      
        Apache Thrift
        2012-10-15
        0.9.0
      
      
        Apache Thrift
        2011-11-29
        0.8.0
      
      
        Apache Thrift
        2011-08-13
        0.7.0
      
      
        Apache Thrift
        2011-04-25
        0.6.1
      
      
        Apache Thrift
        2011-02-08
        0.6.0
      
      
        Apache Thrift (incubating)
        2010-10-07
        0.5.0
      
      
        Apache Thrift (incubating)
        2010-08-23
        0.4.0
      
      
        Apache Thrift (incubating)
        2010-08-04
        0.3.0
      
      
        Apache Thrift (incubating)
        2009-12-11
        0.2.0
      
    
    
      
        
        
      
    
    
      
        Apache Thrift PMC
          
      
    
  

thrift-0.23.0/CONTRIBUTING.md0000664000175000017500000001775615167543515015643 0ustar00buildbuild00000000000000# How to Contribute #

Thank you for your interest in contributing to the Apache Thrift project!  Information on why and how to contribute is available on the Apache Software Foundation (ASF) web site. In particular, we recommend the following to become acquainted with Apache Contributions:

 * [Contributors Tech Guide](http://www.apache.org/dev/contributors)
 * [Get involved!](http://www.apache.org/foundation/getinvolved.html)
 * [Legal aspects on Submission of Contributions (Patches)](http://www.apache.org/licenses/LICENSE-2.0.html#contributions)

## GitHub pull requests ##

This is the preferred method of submitting changes.  When you submit a pull request through github,
it activates the continuous integration (CI) build systems at Appveyor and Travis to build your changesxi
on a variety of Linux and Windows configurations and run all the test suites.  Follow these requirements 
for a successful pull request:

 1. All significant changes require an [Apache Jira THRIFT Issue](http://issues.apache.org/jira/browse/THRIFT) ticket.  Trivial changes such as fixing a typo or a compiler warning do not.

 1. All pull requests should contain a single commit per issue, or we will ask you to squash it.
 1. The pull request title must begin with the Jira THRIFT ticket identifier if it has an associated ticket, for example:

        THRIFT-9999: an example pull request title
        
 1. Commit messages must follow this pattern for code changes (deviations will not be merged):
        
        THRIFT-9999: [summary of fix, one line if possible]
        Client: [language(s) affected, comma separated, for example: "cpp,erl,perl"]

Instructions:

 1. Create a fork in your GitHub account of http://github.com/apache/thrift
 1. Clone the fork to your development system.
 1. Create a branch for your changes (best practice is issue as branch name, e.g. THRIFT-9999).
 1. Modify the source to include the improvement/bugfix, and:

    * Remember to provide *tests* for all submitted changes!
    * Use test-driven development (TDD): add a test that will isolate the bug *before* applying the change that fixes it.
    * Verify that you follow [Thrift Coding Standards](/docs/coding_standards) (you can run 'make style', which ensures proper format for some languages).
    * [*optional*] Verify that your change works on other platforms by adding a GitHub service hook to [Travis CI](http://docs.travis-ci.com/user/getting-started/#Step-one%3A-Sign-in) and [AppVeyor](http://www.appveyor.com/docs).  You can use this technique to run the Thrift CI jobs in your account to check your changes before they are made public.  Every GitHub pull request into Thrift will run the full CI build and test suite on your changes.

 1. Squash your changes to a single commit.  This maintains clean change history.
 1. Commit and push changes to your branch (please use issue name and description as commit title, e.g. "THRIFT-9999: make it perfect"), with the affected languages on the next line of the description.
 1. Use GitHub to create a pull request going from your branch to apache:master.  Ensure that the Jira ticket number is at the beginning of the title of your pull request, same as the commit title.
 1. Wait for other contributors or committers to review your new addition, and for a CI build to complete.
 1. Wait for a committer to commit your patch.  You can nudge the committers if necessary by sending a message to the [Apache Thrift mailing list](https://thrift.apache.org/mailing).

## If you want to build the project locally ##

For Windows systems, see our detailed instructions on the [CMake README](/build/cmake/README.md).

For Windows Native C++ builds, see our detailed instructions on the [WinCPP README](/build/wincpp/README.md).

For unix systems, see our detailed instructions on the [Docker README](/build/docker/README.md).

## If you want to review open issues... ##

 1. Review the [GitHub Pull Request Backlog](https://github.com/apache/thrift/pulls).  Code reviews are open to all.
 2. Review the [Jira issue tracker](http://issues.apache.org/jira/browse/THRIFT).  You can search for tickets relating to languages you are interested in or currently using with thrift, for example a Jira search (Issues -> Search For Issues) query of ``project = THRIFT AND component in ("Erlang - Library") and status not in (resolved, closed)`` will locate all the open Erlang Library issues.

## If you discovered a defect... ##

 1. Check to see if the issue is already in the [Jira issue tracker](http://issues.apache.org/jira/browse/THRIFT).
 1. If not, create a ticket describing the change you're proposing in the Jira issue tracker.
 1. Contribute your code changes using the GitHub pull request method:

## Contributing via Patch ##

To create a patch from changes in your local directory:

    git diff > ../THRIFT-NNNN.patch

then wait for contributors or committers to review your changes, and then for a committer to apply your patch.  This is not the preferred way to submit changes and incurs additional overhead for committers who must then create a pull request for you.

## GitHub recipes for Pull Requests ##

Sometimes commmitters may ask you to take actions in your pull requests.  Here are some recipes that will help you accomplish those requests.  These examples assume you are working on Jira issue THRIFT-9999.  You should also be familiar with the [upstream](https://help.github.com/articles/syncing-a-fork/) repository concept.

### Squash your changes ###

If you have not submitted a pull request yet, or if you have not yet rebased your existing pull request, you can squash all your commits down to a single commit.  This makes life easier for the committers.  If your pull request on GitHub has more than one commit, you should do this.

1. Use the command ``git log`` to identify how many commits you made since you began.
2. Use the command ``git rebase -i HEAD~N`` where N is the number of commits.
3. Leave "pull" in the first line.
4. Change all other lines from "pull" to "fixup".
5. All your changes are now in a single commit.

If you already have a pull request outstanding, you will need to do a "force push" to overwrite it since you changed your commit history:

    git push -u origin THRIFT-9999 --force

A more detailed walkthrough of a squash can be found at [Git Ready](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html).

### Rebase your pull request ###

If your pull request has a conflict with master, it needs to be rebased:

    git checkout THRIFT-9999
    git rebase upstream master
      (resolve any conflicts, make sure it builds)
    git push -u origin THRIFT-9999 --force

### Fix a bad merge ###

If your pull request contains commits that are not yours, then you should use the following technique to fix the bad merge in your branch:

    git checkout master
    git pull upstream master
    git checkout -b THRIFT-9999-take-2
    git cherry-pick ...
        (pick only your commits from your original pull request in ascending chronological order)
    squash your changes to a single commit if there is more than one (see above)
    git push -u origin THRIFT-9999-take-2:THRIFT-9999

This procedure will apply only your commits in order to the current master, then you will squash them to a single commit, and then you force push your local THRIFT-9999-take-2 into remote THRIFT-9999 which represents your pull request, replacing all the commits with the new one.

## AI generated content ##

The [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) serves as a great summary. It also outlines potential issues that come with generative tools. For the reasons set out in this document, but also to make it absolutely clear to the reviewers, we strongly recommend using either the `Generated-by:` (as recommended by the linked ASF source) or `Co-Authored-By:` clause (widely adopted common practice, e.g. [here](https://issues.apache.org/jira/browse/SPARK-25018) and [here](https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/CommitMessageConventions.html)) in commits and pull requests, if applicable.

----

 
thrift-0.23.0/CMakeLists.txt0000664000175000017500000000751315170007142016121 0ustar00buildbuild00000000000000#
# 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.
#

cmake_minimum_required(VERSION 3.16)

if(POLICY CMP0048)
  cmake_policy(SET CMP0048 NEW)  # package version behavior added in cmake 3.0
endif()
if(POLICY CMP0074)
  cmake_policy(SET CMP0074 NEW)  # find_package behavior added in cmake 3.12
endif()

# PACKAGE_VERSION is used by cpack scripts currently
# Both thrift_VERSION and PACKAGE_VERSION should be the same for now
set(thrift_VERSION "0.23.0")
set(PACKAGE_VERSION ${thrift_VERSION})

project("thrift" VERSION ${PACKAGE_VERSION})
message(STATUS "Configuring ${CMAKE_PROJECT_NAME} ${thrift_VERSION}")


list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")

# Some default settings
include(DefineCMakeDefaults)

# Build time options are defined here
include(DefineOptions)
include(DefineInstallationPaths)

# Based on the options set some platform specifics
include(DefinePlatformSpecifc)

# Add CMake targets for static code analysis
include(StaticCodeAnalysis)

# Generate the config.h file
include(ConfigureChecks)

# Generate the ThriftConfig.cmake module
include(GenerateConfigModule)

# Packaging
include(CPackConfig)

# Dependencies
include(BoostMacros)
find_package(Threads)
include(CTest)

if(BUILD_TESTING)
  message(STATUS "Building with unittests")

  enable_testing()
  # Define "make check" as alias for "make test"
  add_custom_target(check COMMAND ctest)
else ()
  message(STATUS "Building without tests")
endif ()

if(BUILD_COMPILER)
    if(NOT EXISTS ${THRIFT_COMPILER})
        set(THRIFT_COMPILER $)
    endif()
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/compiler/cpp)
elseif(EXISTS ${THRIFT_COMPILER})
    add_executable(thrift-compiler IMPORTED)
    set_property(TARGET thrift-compiler PROPERTY IMPORTED_LOCATION ${THRIFT_COMPILER})
endif()

if(BUILD_CPP)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/cpp)
    if(BUILD_TUTORIALS)
        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tutorial/cpp)
    endif()
    if(BUILD_TESTING)
        if(WITH_LIBEVENT AND WITH_ZLIB AND WITH_OPENSSL)
            add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/cpp)
        else()
            message(WARNING "libevent and/or ZLIB and/or OpenSSL not found or disabled; will not build some tests")
        endif()
    endif()
endif()

if(BUILD_C_GLIB)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/c_glib)
    if(BUILD_TESTING)
        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/c_glib)
    endif()
endif()

if(BUILD_JAVA)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/java)
endif()

if(BUILD_JAVASCRIPT)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/js)
endif()

if(BUILD_KOTLIN)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/kotlin)
endif()

if(BUILD_NODEJS)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/nodejs)
endif()

if(BUILD_PYTHON)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/py)
    if(BUILD_TESTING)
        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/py)
    endif()
endif()

# Create the uninstall target
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${PROJECT_SOURCE_DIR}/build/cmake/uninstall.cmake")

PRINT_CONFIG_SUMMARY()
thrift-0.23.0/package-lock.json0000664000175000017500000044710115170007142016576 0ustar00buildbuild00000000000000{
  "name": "thrift",
  "version": "0.23.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "thrift",
      "version": "0.23.0",
      "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",
        "uuid": "^13.0.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/@babel/code-frame": {
      "version": "7.22.13",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
      "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
      "dev": true,
      "dependencies": {
        "@babel/highlight": "^7.22.13",
        "chalk": "^2.4.2"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/core": {
      "version": "7.8.4",
      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz",
      "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.8.3",
        "@babel/generator": "^7.8.4",
        "@babel/helpers": "^7.8.4",
        "@babel/parser": "^7.8.4",
        "@babel/template": "^7.8.3",
        "@babel/traverse": "^7.8.4",
        "@babel/types": "^7.8.3",
        "convert-source-map": "^1.7.0",
        "debug": "^4.1.0",
        "gensync": "^1.0.0-beta.1",
        "json5": "^2.1.0",
        "lodash": "^4.17.13",
        "resolve": "^1.3.2",
        "semver": "^5.4.1",
        "source-map": "^0.5.0"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/babel"
      }
    },
    "node_modules/@babel/core/node_modules/debug": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
      "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)",
      "dev": true,
      "dependencies": {
        "ms": "^2.1.1"
      }
    },
    "node_modules/@babel/core/node_modules/ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
      "dev": true
    },
    "node_modules/@babel/core/node_modules/resolve": {
      "version": "1.15.1",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
      "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
      "dev": true,
      "dependencies": {
        "path-parse": "^1.0.6"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/@babel/core/node_modules/resolve/node_modules/path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
      "dev": true
    },
    "node_modules/@babel/core/node_modules/source-map": {
      "version": "0.5.7",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/@babel/generator": {
      "version": "7.23.0",
      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
      "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.23.0",
        "@jridgewell/gen-mapping": "^0.3.2",
        "@jridgewell/trace-mapping": "^0.3.17",
        "jsesc": "^2.5.1"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-environment-visitor": {
      "version": "7.22.20",
      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-function-name": {
      "version": "7.23.0",
      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
      "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
      "dev": true,
      "dependencies": {
        "@babel/template": "^7.22.15",
        "@babel/types": "^7.23.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-hoist-variables": {
      "version": "7.22.5",
      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
      "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.22.5"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-split-export-declaration": {
      "version": "7.22.6",
      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
      "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.22.5"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-string-parser": {
      "version": "7.22.5",
      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
      "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-validator-identifier": {
      "version": "7.22.20",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
      "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helpers": {
      "version": "7.8.4",
      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz",
      "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==",
      "dev": true,
      "dependencies": {
        "@babel/template": "^7.8.3",
        "@babel/traverse": "^7.8.4",
        "@babel/types": "^7.8.3"
      }
    },
    "node_modules/@babel/highlight": {
      "version": "7.22.20",
      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
      "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-validator-identifier": "^7.22.20",
        "chalk": "^2.4.2",
        "js-tokens": "^4.0.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/parser": {
      "version": "7.23.0",
      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
      "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
      "dev": true,
      "bin": {
        "parser": "bin/babel-parser.js"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/@babel/template": {
      "version": "7.22.15",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
      "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.22.13",
        "@babel/parser": "^7.22.15",
        "@babel/types": "^7.22.15"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/traverse": {
      "version": "7.23.2",
      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
      "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.22.13",
        "@babel/generator": "^7.23.0",
        "@babel/helper-environment-visitor": "^7.22.20",
        "@babel/helper-function-name": "^7.23.0",
        "@babel/helper-hoist-variables": "^7.22.5",
        "@babel/helper-split-export-declaration": "^7.22.6",
        "@babel/parser": "^7.23.0",
        "@babel/types": "^7.23.0",
        "debug": "^4.1.0",
        "globals": "^11.1.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/traverse/node_modules/debug": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
      "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)",
      "dev": true,
      "dependencies": {
        "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",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
      "dev": true
    },
    "node_modules/@babel/types": {
      "version": "7.23.0",
      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
      "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-string-parser": "^7.22.5",
        "@babel/helper-validator-identifier": "^7.22.20",
        "to-fast-properties": "^2.0.0"
      },
      "engines": {
        "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.1",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
      "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
      "dev": true,
      "license": "MIT",
      "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",
      "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==",
      "dev": true,
      "dependencies": {
        "camelcase": "^5.3.1",
        "find-up": "^4.1.0",
        "js-yaml": "^3.13.1",
        "resolve-from": "^5.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/@istanbuljs/schema": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
      "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/@jridgewell/gen-mapping": {
      "version": "0.3.3",
      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
      "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
      "dev": true,
      "dependencies": {
        "@jridgewell/set-array": "^1.0.1",
        "@jridgewell/sourcemap-codec": "^1.4.10",
        "@jridgewell/trace-mapping": "^0.3.9"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/@jridgewell/resolve-uri": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
      "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
      "dev": true,
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/@jridgewell/set-array": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
      "dev": true,
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/@jridgewell/sourcemap-codec": {
      "version": "1.4.15",
      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
      "dev": true
    },
    "node_modules/@jridgewell/trace-mapping": {
      "version": "0.3.20",
      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
      "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
      "dev": true,
      "dependencies": {
        "@jridgewell/resolve-uri": "^3.1.0",
        "@jridgewell/sourcemap-codec": "^1.4.14"
      }
    },
    "node_modules/@jsdoc/salty": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.5.tgz",
      "integrity": "sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==",
      "dev": true,
      "dependencies": {
        "lodash": "^4.17.21"
      },
      "engines": {
        "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",
      "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
      "dev": true
    },
    "node_modules/@types/markdown-it": {
      "version": "12.2.3",
      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
      "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
      "dev": true,
      "dependencies": {
        "@types/linkify-it": "*",
        "@types/mdurl": "*"
      }
    },
    "node_modules/@types/mdurl": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
      "dev": true
    },
    "node_modules/@types/node": {
      "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.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": "*"
      }
    },
    "node_modules/@types/q": {
      "version": "1.5.1",
      "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz",
      "integrity": "sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==",
      "dev": true
    },
    "node_modules/acorn": {
      "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"
      },
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/acorn-jsx": {
      "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 || ^7.0.0 || ^8.0.0"
      }
    },
    "node_modules/aggregate-error": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
      "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
      "dev": true,
      "dependencies": {
        "clean-stack": "^2.0.0",
        "indent-string": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "dependencies": {
        "fast-deep-equal": "^3.1.1",
        "fast-json-stable-stringify": "^2.0.0",
        "json-schema-traverse": "^0.4.1",
        "uri-js": "^4.2.2"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/ansi-styles": {
      "version": "3.2.1",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
      "dev": true,
      "dependencies": {
        "color-convert": "^1.9.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/append-transform": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
      "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
      "dev": true,
      "dependencies": {
        "default-require-extensions": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/archy": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
      "dev": true
    },
    "node_modules/argparse": {
      "version": "1.0.10",
      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
      "dev": true,
      "dependencies": {
        "sprintf-js": "~1.0.2"
      }
    },
    "node_modules/asn1": {
      "version": "0.2.6",
      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
      "dev": true,
      "dependencies": {
        "safer-buffer": "~2.1.0"
      }
    },
    "node_modules/assert-plus": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
      "dev": true,
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/async-limiter": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
    },
    "node_modules/asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
      "dev": true
    },
    "node_modules/aws-sign2": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
      "dev": true,
      "engines": {
        "node": "*"
      }
    },
    "node_modules/aws4": {
      "version": "1.12.0",
      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
      "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
      "dev": true
    },
    "node_modules/balanced-match": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
      "dev": true
    },
    "node_modules/bcrypt-pbkdf": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
      "dev": true,
      "dependencies": {
        "tweetnacl": "^0.14.3"
      }
    },
    "node_modules/bluebird": {
      "version": "3.7.2",
      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
      "dev": true
    },
    "node_modules/brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "dev": true,
      "dependencies": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "node_modules/browser-or-node": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.2.1.tgz",
      "integrity": "sha512-sVIA0cysIED0nbmNOm7sZzKfgN1rpFmrqvLZaFWspaBAftfQcezlC81G6j6U2RJf4Lh66zFxrCeOsvkUXIcPWg=="
    },
    "node_modules/buffer-equals": {
      "version": "1.0.4",
      "resolved": "http://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz",
      "integrity": "sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/caching-transform": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
      "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
      "dev": true,
      "dependencies": {
        "hasha": "^5.0.0",
        "make-dir": "^3.0.0",
        "package-hash": "^4.0.0",
        "write-file-atomic": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/call-bind-apply-helpers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0",
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/callsites": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/camelcase": {
      "version": "5.3.1",
      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/caseless": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
      "dev": true
    },
    "node_modules/catharsis": {
      "version": "0.9.0",
      "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
      "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
      "dev": true,
      "dependencies": {
        "lodash": "^4.17.15"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/chalk": {
      "version": "2.4.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^3.2.1",
        "escape-string-regexp": "^1.0.5",
        "supports-color": "^5.3.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/clean-stack": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/cliui": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
      "dev": true,
      "dependencies": {
        "string-width": "^4.2.0",
        "strip-ansi": "^6.0.0",
        "wrap-ansi": "^6.2.0"
      }
    },
    "node_modules/cliui/node_modules/ansi-regex": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/cliui/node_modules/is-fullwidth-code-point": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/cliui/node_modules/string-width": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
      "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
      "dev": true,
      "dependencies": {
        "emoji-regex": "^8.0.0",
        "is-fullwidth-code-point": "^3.0.0",
        "strip-ansi": "^6.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/cliui/node_modules/strip-ansi": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^5.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/color-convert": {
      "version": "1.9.3",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
      "dev": true,
      "dependencies": {
        "color-name": "1.1.3"
      }
    },
    "node_modules/color-name": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
      "dev": true
    },
    "node_modules/combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "dev": true,
      "dependencies": {
        "delayed-stream": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/commander": {
      "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",
      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
      "dev": true
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
      "dev": true
    },
    "node_modules/connect": {
      "version": "3.6.6",
      "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
      "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
      "dev": true,
      "dependencies": {
        "debug": "2.6.9",
        "finalhandler": "1.1.0",
        "parseurl": "~1.3.2",
        "utils-merge": "1.0.1"
      },
      "engines": {
        "node": ">= 0.10.0"
      }
    },
    "node_modules/convert-source-map": {
      "version": "1.7.0",
      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.1"
      }
    },
    "node_modules/core-util-is": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
      "dev": true
    },
    "node_modules/cross-spawn": {
      "version": "7.0.6",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
      "dev": true,
      "dependencies": {
        "path-key": "^3.1.0",
        "shebang-command": "^2.0.0",
        "which": "^2.0.1"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/dashdash": {
      "version": "1.14.1",
      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
      "dev": true,
      "dependencies": {
        "assert-plus": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10"
      }
    },
    "node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/decamelize": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/deep-equal": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
      "dev": true
    },
    "node_modules/deep-is": {
      "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": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
      "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
      "dev": true,
      "dependencies": {
        "strip-bom": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/define-properties": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
      "dev": true,
      "dependencies": {
        "object-keys": "^1.0.12"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/defined": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
      "dev": true
    },
    "node_modules/delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
      "dev": true,
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/dunder-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.1",
        "es-errors": "^1.3.0",
        "gopd": "^1.2.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/ecc-jsbn": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
      "dev": true,
      "dependencies": {
        "jsbn": "~0.1.0",
        "safer-buffer": "^2.1.0"
      }
    },
    "node_modules/ee-first": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
      "dev": true
    },
    "node_modules/emoji-regex": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
      "dev": true
    },
    "node_modules/encodeurl": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/entities": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
      "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
      "dev": true,
      "funding": {
        "url": "https://github.com/fb55/entities?sponsor=1"
      }
    },
    "node_modules/es-abstract": {
      "version": "1.12.0",
      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
      "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
      "dev": true,
      "dependencies": {
        "es-to-primitive": "^1.1.1",
        "function-bind": "^1.1.1",
        "has": "^1.0.1",
        "is-callable": "^1.1.3",
        "is-regex": "^1.0.4"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-define-property": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-errors": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-object-atoms": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-set-tostringtag": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0",
        "get-intrinsic": "^1.2.6",
        "has-tostringtag": "^1.0.2",
        "hasown": "^2.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-to-primitive": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
      "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
      "dev": true,
      "dependencies": {
        "is-callable": "^1.1.4",
        "is-date-object": "^1.0.1",
        "is-symbol": "^1.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es6-error": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
      "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
      "dev": true
    },
    "node_modules/escape-html": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
      "dev": true
    },
    "node_modules/escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
      "dev": true,
      "engines": {
        "node": ">=0.8.0"
      }
    },
    "node_modules/eslint": {
      "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",
        "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",
        "is-glob": "^4.0.0",
        "json-stable-stringify-without-jsonify": "^1.0.1",
        "lodash.merge": "^4.6.2",
        "minimatch": "^3.1.2",
        "natural-compare": "^1.4.0",
        "optionator": "^0.9.3"
      },
      "bin": {
        "eslint": "bin/eslint.js"
      },
      "engines": {
        "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": "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,
      "bin": {
        "eslint-config-prettier": "build/bin/cli.js"
      },
      "peerDependencies": {
        "eslint": ">=7.0.0"
      }
    },
    "node_modules/eslint-plugin-prettier": {
      "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",
        "synckit": "^0.9.1"
      },
      "engines": {
        "node": "^14.18.0 || >=16.0.0"
      },
      "funding": {
        "url": "https://opencollective.com/eslint-plugin-prettier"
      },
      "peerDependencies": {
        "@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/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": {
        "locate-path": "^6.0.0",
        "path-exists": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "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": {
        "p-locate": "^5.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "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": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "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": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "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": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/espree": {
      "version": "10.3.0",
      "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
      "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
      "dev": true,
      "dependencies": {
        "acorn": "^8.14.0",
        "acorn-jsx": "^5.3.2",
        "eslint-visitor-keys": "^4.2.0"
      },
      "engines": {
        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
      },
      "funding": {
        "url": "https://opencollective.com/eslint"
      }
    },
    "node_modules/esprima": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
      "dev": true,
      "bin": {
        "esparse": "bin/esparse.js",
        "esvalidate": "bin/esvalidate.js"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/esquery": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
      "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
      "dev": true,
      "dependencies": {
        "estraverse": "^5.1.0"
      },
      "engines": {
        "node": ">=0.10"
      }
    },
    "node_modules/esrecurse": {
      "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": "^5.2.0"
      },
      "engines": {
        "node": ">=4.0"
      }
    },
    "node_modules/estraverse": {
      "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": ">=4.0"
      }
    },
    "node_modules/esutils": {
      "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"
      }
    },
    "node_modules/extend": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
      "dev": true
    },
    "node_modules/extsprintf": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
      "dev": true,
      "engines": [
        "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",
      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
      "dev": true
    },
    "node_modules/fast-json-stable-stringify": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
      "dev": true
    },
    "node_modules/fast-levenshtein": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
      "dev": true
    },
    "node_modules/file-entry-cache": {
      "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": "^4.0.0"
      },
      "engines": {
        "node": ">=16.0.0"
      }
    },
    "node_modules/finalhandler": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
      "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
      "dev": true,
      "dependencies": {
        "debug": "2.6.9",
        "encodeurl": "~1.0.1",
        "escape-html": "~1.0.3",
        "on-finished": "~2.3.0",
        "parseurl": "~1.3.2",
        "statuses": "~1.3.1",
        "unpipe": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/find-cache-dir": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz",
      "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==",
      "dev": true,
      "dependencies": {
        "commondir": "^1.0.1",
        "make-dir": "^3.0.0",
        "pkg-dir": "^4.1.0"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
      }
    },
    "node_modules/find-up": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
      "dev": true,
      "dependencies": {
        "locate-path": "^5.0.0",
        "path-exists": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/flat-cache": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
      "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
      "dev": true,
      "dependencies": {
        "flatted": "^3.2.9",
        "keyv": "^4.5.4"
      },
      "engines": {
        "node": ">=16"
      }
    },
    "node_modules/flatted": {
      "version": "3.4.2",
      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
      "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
      "dev": true,
      "license": "ISC"
    },
    "node_modules/for-each": {
      "version": "0.3.3",
      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
      "dev": true,
      "dependencies": {
        "is-callable": "^1.1.3"
      }
    },
    "node_modules/foreground-child": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
      "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
      "dev": true,
      "dependencies": {
        "cross-spawn": "^7.0.0",
        "signal-exit": "^3.0.2"
      },
      "engines": {
        "node": ">=8.0.0"
      }
    },
    "node_modules/forever-agent": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
      "dev": true,
      "engines": {
        "node": "*"
      }
    },
    "node_modules/form-data": {
      "version": "4.0.5",
      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
      "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "es-set-tostringtag": "^2.1.0",
        "hasown": "^2.0.2",
        "mime-types": "^2.1.12"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/fromentries": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz",
      "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==",
      "dev": true
    },
    "node_modules/fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
      "dev": true
    },
    "node_modules/function-bind": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
      "dev": true,
      "license": "MIT",
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/gensync": {
      "version": "1.0.0-beta.1",
      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
      "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/get-caller-file": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
      "dev": true,
      "engines": {
        "node": "6.* || 8.* || >= 10.*"
      }
    },
    "node_modules/get-intrinsic": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.2",
        "es-define-property": "^1.0.1",
        "es-errors": "^1.3.0",
        "es-object-atoms": "^1.1.1",
        "function-bind": "^1.1.2",
        "get-proto": "^1.0.1",
        "gopd": "^1.2.0",
        "has-symbols": "^1.1.0",
        "hasown": "^2.0.2",
        "math-intrinsics": "^1.1.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "dunder-proto": "^1.0.1",
        "es-object-atoms": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/getpass": {
      "version": "0.1.7",
      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
      "dev": true,
      "dependencies": {
        "assert-plus": "^1.0.0"
      }
    },
    "node_modules/glob": {
      "version": "7.1.3",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
      "dev": true,
      "dependencies": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.0.4",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      },
      "engines": {
        "node": "*"
      }
    },
    "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": ">=10.13.0"
      }
    },
    "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,
      "engines": {
        "node": ">=18"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/gopd": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.1.11",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
      "dev": true,
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/har-schema": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
      "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/har-validator": {
      "version": "5.1.5",
      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
      "deprecated": "this library is no longer supported",
      "dev": true,
      "dependencies": {
        "ajv": "^6.12.3",
        "har-schema": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/has": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
      "dev": true,
      "dependencies": {
        "function-bind": "^1.1.1"
      },
      "engines": {
        "node": ">= 0.4.0"
      }
    },
    "node_modules/has-flag": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/has-symbols": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-tostringtag": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "has-symbols": "^1.0.3"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/hasha": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz",
      "integrity": "sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw==",
      "dev": true,
      "dependencies": {
        "is-stream": "^2.0.0",
        "type-fest": "^0.8.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/hasown": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/html-escaper": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz",
      "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==",
      "dev": true
    },
    "node_modules/html-validator": {
      "version": "0.0.8",
      "resolved": "https://registry.npmjs.org/html-validator/-/html-validator-0.0.8.tgz",
      "integrity": "sha512-7iL7tXUZ73BpRgb9n9dkLCIFbMLUu+liJVOmGwltrMjZf1eVwoIGfpBxnLLCSq9iefAoWb/I1DUiRJWUj9tbUA==",
      "dev": true,
      "dependencies": {
        "minimist": "^1.1.0",
        "request": "^2.42.0",
        "valid-url": "^1.0.9"
      },
      "bin": {
        "html-validator": "cli.js"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/html-validator-cli": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/html-validator-cli/-/html-validator-cli-2.0.0.tgz",
      "integrity": "sha512-bfWxpGvVdenUqpJrI4HSCiVP+QPtik86epTTnXGtUU1USAi2sGfJOHTf8cLFqPKsooF+9i0xcH8h7fILnFxEbA==",
      "dev": true,
      "dependencies": {
        "html-validator": "^0.0.8",
        "minimist": "^1.2.0"
      },
      "bin": {
        "html-validator": "index.js"
      },
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/http-signature": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
      "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
      "dev": true,
      "dependencies": {
        "assert-plus": "^1.0.0",
        "jsprim": "^1.2.2",
        "sshpk": "^1.7.0"
      },
      "engines": {
        "node": ">=0.8",
        "npm": ">=1.3.7"
      }
    },
    "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,
      "engines": {
        "node": ">= 4"
      }
    },
    "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": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/imurmurhash": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
      "dev": true,
      "engines": {
        "node": ">=0.8.19"
      }
    },
    "node_modules/indent-string": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
      "dev": true,
      "dependencies": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "node_modules/inherits": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
      "dev": true
    },
    "node_modules/is-callable": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
      "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
      "dev": true,
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/is-date-object": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
      "dev": true,
      "engines": {
        "node": ">= 0.4"
      }
    },
    "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,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "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": {
        "is-extglob": "^2.1.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-regex": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
      "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
      "dev": true,
      "dependencies": {
        "has": "^1.0.1"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/is-stream": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/is-symbol": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
      "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
      "dev": true,
      "dependencies": {
        "has-symbols": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/is-typedarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
      "dev": true
    },
    "node_modules/is-windows": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
      "dev": true
    },
    "node_modules/isomorphic-ws": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
      "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==",
      "peerDependencies": {
        "ws": "*"
      }
    },
    "node_modules/isstream": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
      "dev": true
    },
    "node_modules/istanbul-lib-coverage": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-hook": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
      "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
      "dev": true,
      "dependencies": {
        "append-transform": "^2.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-instrument": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz",
      "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==",
      "dev": true,
      "dependencies": {
        "@babel/core": "^7.7.5",
        "@babel/parser": "^7.7.5",
        "@babel/template": "^7.7.4",
        "@babel/traverse": "^7.7.4",
        "@istanbuljs/schema": "^0.1.2",
        "istanbul-lib-coverage": "^3.0.0",
        "semver": "^6.3.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-instrument/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/istanbul-lib-processinfo": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz",
      "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==",
      "dev": true,
      "dependencies": {
        "archy": "^1.0.0",
        "cross-spawn": "^7.0.0",
        "istanbul-lib-coverage": "^3.0.0-alpha.1",
        "make-dir": "^3.0.0",
        "p-map": "^3.0.0",
        "rimraf": "^3.0.0",
        "uuid": "^3.3.3"
      },
      "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",
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "dev": true,
      "dependencies": {
        "glob": "^7.1.3"
      },
      "bin": {
        "rimraf": "bin.js"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/istanbul-lib-processinfo/node_modules/uuid": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
      "dev": true,
      "license": "MIT",
      "bin": {
        "uuid": "bin/uuid"
      }
    },
    "node_modules/istanbul-lib-report": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
      "dev": true,
      "dependencies": {
        "istanbul-lib-coverage": "^3.0.0",
        "make-dir": "^3.0.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-report/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/istanbul-lib-report/node_modules/supports-color": {
      "version": "7.1.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
      "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
      "dev": true,
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-source-maps": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
      "dev": true,
      "dependencies": {
        "debug": "^4.1.1",
        "istanbul-lib-coverage": "^3.0.0",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-source-maps/node_modules/debug": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
      "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)",
      "dev": true,
      "dependencies": {
        "ms": "^2.1.1"
      }
    },
    "node_modules/istanbul-lib-source-maps/node_modules/ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
      "dev": true
    },
    "node_modules/istanbul-lib-source-maps/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/istanbul-reports": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
      "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==",
      "dev": true,
      "dependencies": {
        "html-escaper": "^2.0.0",
        "istanbul-lib-report": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/js-tokens": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
      "dev": true
    },
    "node_modules/js-yaml": {
      "version": "3.14.2",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
      "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "argparse": "^1.0.7",
        "esprima": "^4.0.0"
      },
      "bin": {
        "js-yaml": "bin/js-yaml.js"
      }
    },
    "node_modules/js2xmlparser": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
      "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
      "dev": true,
      "dependencies": {
        "xmlcreate": "^2.0.4"
      }
    },
    "node_modules/jsbn": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
      "dev": true
    },
    "node_modules/jsdoc": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz",
      "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==",
      "dev": true,
      "dependencies": {
        "@babel/parser": "^7.20.15",
        "@jsdoc/salty": "^0.2.1",
        "@types/markdown-it": "^12.2.3",
        "bluebird": "^3.7.2",
        "catharsis": "^0.9.0",
        "escape-string-regexp": "^2.0.0",
        "js2xmlparser": "^4.0.2",
        "klaw": "^3.0.0",
        "markdown-it": "^12.3.2",
        "markdown-it-anchor": "^8.4.1",
        "marked": "^4.0.10",
        "mkdirp": "^1.0.4",
        "requizzle": "^0.2.3",
        "strip-json-comments": "^3.1.0",
        "underscore": "~1.13.2"
      },
      "bin": {
        "jsdoc": "jsdoc.js"
      },
      "engines": {
        "node": ">=12.0.0"
      }
    },
    "node_modules/jsdoc/node_modules/escape-string-regexp": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
      "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/jsdoc/node_modules/mkdirp": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
      "dev": true,
      "bin": {
        "mkdirp": "bin/cmd.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/jsesc": {
      "version": "2.5.2",
      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
      "dev": true,
      "bin": {
        "jsesc": "bin/jsesc"
      },
      "engines": {
        "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",
      "integrity": "sha512-uGrIXtRehbksM17S2lJRLPljufK52KL2ewbJi0xgcRPONoRLXa4yAUIKAUxF69dbnqIoBu33fB28MAWSxupB8Q==",
      "dev": true,
      "dependencies": {
        "node-int64": "0.4.0"
      }
    },
    "node_modules/json-schema": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
      "dev": true
    },
    "node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/json-stable-stringify-without-jsonify": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
      "dev": true
    },
    "node_modules/json-stringify-safe": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
      "dev": true
    },
    "node_modules/json5": {
      "version": "2.2.3",
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
      "dev": true,
      "bin": {
        "json5": "lib/cli.js"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/jsprim": {
      "version": "1.4.2",
      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
      "dev": true,
      "dependencies": {
        "assert-plus": "1.0.0",
        "extsprintf": "1.3.0",
        "json-schema": "0.4.0",
        "verror": "1.10.0"
      },
      "engines": {
        "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",
      "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
      "dev": true,
      "dependencies": {
        "graceful-fs": "^4.1.9"
      }
    },
    "node_modules/levn": {
      "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.2.1",
        "type-check": "~0.4.0"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/linkify-it": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
      "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
      "dev": true,
      "dependencies": {
        "uc.micro": "^1.0.1"
      }
    },
    "node_modules/locate-path": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
      "dev": true,
      "dependencies": {
        "p-locate": "^4.1.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/lodash": {
      "version": "4.17.23",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
      "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
      "dev": true,
      "license": "MIT"
    },
    "node_modules/lodash.flattendeep": {
      "version": "4.4.0",
      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
      "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",
      "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
      "dev": true,
      "dependencies": {
        "semver": "^6.0.0"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/make-dir/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/markdown-it": {
      "version": "12.3.2",
      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
      "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
      "dev": true,
      "dependencies": {
        "argparse": "^2.0.1",
        "entities": "~2.1.0",
        "linkify-it": "^3.0.1",
        "mdurl": "^1.0.1",
        "uc.micro": "^1.0.5"
      },
      "bin": {
        "markdown-it": "bin/markdown-it.js"
      }
    },
    "node_modules/markdown-it-anchor": {
      "version": "8.6.5",
      "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.5.tgz",
      "integrity": "sha512-PI1qEHHkTNWT+X6Ip9w+paonfIQ+QZP9sCeMYi47oqhH+EsW8CrJ8J7CzV19QVOj6il8ATGbK2nTECj22ZHGvQ==",
      "dev": true,
      "peerDependencies": {
        "@types/markdown-it": "*",
        "markdown-it": "*"
      }
    },
    "node_modules/markdown-it/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/marked": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz",
      "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==",
      "dev": true,
      "bin": {
        "marked": "bin/marked.js"
      },
      "engines": {
        "node": ">= 12"
      }
    },
    "node_modules/math-intrinsics": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
      "dev": true,
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/mdurl": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
      "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
      "dev": true
    },
    "node_modules/mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
      "dev": true,
      "dependencies": {
        "mime-db": "1.52.0"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/minimatch": {
      "version": "3.1.5",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
      "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
      "dev": true,
      "license": "ISC",
      "dependencies": {
        "brace-expansion": "^1.1.7"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/minimist": {
      "version": "1.2.8",
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
      "dev": true,
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "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/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/node-gyp-build": {
      "version": "3.7.0",
      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz",
      "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==",
      "dev": true,
      "bin": {
        "node-gyp-build": "bin.js",
        "node-gyp-build-optional": "optional.js",
        "node-gyp-build-test": "build-test.js"
      }
    },
    "node_modules/node-int64": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
      "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs="
    },
    "node_modules/node-preload": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
      "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
      "dev": true,
      "dependencies": {
        "process-on-spawn": "^1.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/nyc": {
      "version": "15.0.0",
      "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.0.tgz",
      "integrity": "sha512-qcLBlNCKMDVuKb7d1fpxjPR8sHeMVX0CHarXAVzrVWoFrigCkYR8xcrjfXSPi5HXM7EU78L6ywO7w1c5rZNCNg==",
      "dev": true,
      "dependencies": {
        "@istanbuljs/load-nyc-config": "^1.0.0",
        "@istanbuljs/schema": "^0.1.2",
        "caching-transform": "^4.0.0",
        "convert-source-map": "^1.7.0",
        "decamelize": "^1.2.0",
        "find-cache-dir": "^3.2.0",
        "find-up": "^4.1.0",
        "foreground-child": "^2.0.0",
        "glob": "^7.1.6",
        "istanbul-lib-coverage": "^3.0.0",
        "istanbul-lib-hook": "^3.0.0",
        "istanbul-lib-instrument": "^4.0.0",
        "istanbul-lib-processinfo": "^2.0.2",
        "istanbul-lib-report": "^3.0.0",
        "istanbul-lib-source-maps": "^4.0.0",
        "istanbul-reports": "^3.0.0",
        "js-yaml": "^3.13.1",
        "make-dir": "^3.0.0",
        "node-preload": "^0.2.0",
        "p-map": "^3.0.0",
        "process-on-spawn": "^1.0.0",
        "resolve-from": "^5.0.0",
        "rimraf": "^3.0.0",
        "signal-exit": "^3.0.2",
        "spawn-wrap": "^2.0.0",
        "test-exclude": "^6.0.0",
        "uuid": "^3.3.3",
        "yargs": "^15.0.2"
      },
      "bin": {
        "nyc": "bin/nyc.js"
      },
      "engines": {
        "node": ">=8.9"
      }
    },
    "node_modules/nyc/node_modules/glob": {
      "version": "7.1.6",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
      "dev": true,
      "dependencies": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.0.4",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      },
      "engines": {
        "node": "*"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/nyc/node_modules/resolve-from": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/nyc/node_modules/rimraf": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "dev": true,
      "dependencies": {
        "glob": "^7.1.3"
      },
      "bin": {
        "rimraf": "bin.js"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/nyc/node_modules/uuid": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
      "dev": true,
      "license": "MIT",
      "bin": {
        "uuid": "bin/uuid"
      }
    },
    "node_modules/oauth-sign": {
      "version": "0.9.0",
      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
      "dev": true,
      "engines": {
        "node": "*"
      }
    },
    "node_modules/object-inspect": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
      "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==",
      "dev": true
    },
    "node_modules/object-keys": {
      "version": "1.0.12",
      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
      "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
      "dev": true,
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/on-finished": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
      "dev": true,
      "dependencies": {
        "ee-first": "1.1.1"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
      "dev": true,
      "dependencies": {
        "wrappy": "1"
      }
    },
    "node_modules/optionator": {
      "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.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/p-limit": {
      "version": "2.2.2",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
      "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
      "dev": true,
      "dependencies": {
        "p-try": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-locate": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
      "dev": true,
      "dependencies": {
        "p-limit": "^2.2.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/p-map": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
      "dev": true,
      "dependencies": {
        "aggregate-error": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/p-try": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/package-hash": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
      "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
      "dev": true,
      "dependencies": {
        "graceful-fs": "^4.1.15",
        "hasha": "^5.0.0",
        "lodash.flattendeep": "^4.4.0",
        "release-zalgo": "^1.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/package-hash/node_modules/graceful-fs": {
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
      "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",
      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/path-exists": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "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/performance-now": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
      "dev": true
    },
    "node_modules/pkg-dir": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
      "dev": true,
      "dependencies": {
        "find-up": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/prelude-ls": {
      "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": "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.cjs"
      },
      "engines": {
        "node": ">=14"
      },
      "funding": {
        "url": "https://github.com/prettier/prettier?sponsor=1"
      }
    },
    "node_modules/prettier-linter-helpers": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
      "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
      "dev": true,
      "dependencies": {
        "fast-diff": "^1.1.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/process-on-spawn": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
      "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
      "dev": true,
      "dependencies": {
        "fromentries": "^1.2.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/psl": {
      "version": "1.9.0",
      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
      "dev": true
    },
    "node_modules/punycode": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/q": {
      "version": "1.5.1",
      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
      "engines": {
        "node": ">=0.6.0",
        "teleport": ">=0.2.0"
      }
    },
    "node_modules/qs": {
      "version": "6.5.3",
      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
      "dev": true,
      "engines": {
        "node": ">=0.6"
      }
    },
    "node_modules/release-zalgo": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
      "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
      "dev": true,
      "dependencies": {
        "es6-error": "^4.0.1"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/request": {
      "version": "2.88.2",
      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
      "dev": true,
      "dependencies": {
        "aws-sign2": "~0.7.0",
        "aws4": "^1.8.0",
        "caseless": "~0.12.0",
        "combined-stream": "~1.0.6",
        "extend": "~3.0.2",
        "forever-agent": "~0.6.1",
        "form-data": ">=2.5.5",
        "har-validator": "~5.1.3",
        "http-signature": "~1.2.0",
        "is-typedarray": "~1.0.0",
        "isstream": "~0.1.2",
        "json-stringify-safe": "~5.0.1",
        "mime-types": "~2.1.19",
        "oauth-sign": "~0.9.0",
        "performance-now": "^2.1.0",
        "qs": "~6.5.2",
        "safe-buffer": "^5.1.2",
        "tough-cookie": "~2.5.0",
        "tunnel-agent": "^0.6.0",
        "uuid": "^3.3.2"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/request/node_modules/uuid": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
      "dev": true,
      "license": "MIT",
      "bin": {
        "uuid": "bin/uuid"
      }
    },
    "node_modules/require-directory": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/require-main-filename": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
      "dev": true
    },
    "node_modules/requizzle": {
      "version": "0.2.3",
      "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
      "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
      "dev": true,
      "dependencies": {
        "lodash": "^4.17.14"
      }
    },
    "node_modules/resolve-from": {
      "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,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/resumer": {
      "version": "0.0.0",
      "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
      "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
      "dev": true,
      "dependencies": {
        "through": "~2.3.4"
      }
    },
    "node_modules/safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
      "dev": true
    },
    "node_modules/safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "dev": true
    },
    "node_modules/semver": {
      "version": "5.6.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
      "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
      "dev": true,
      "bin": {
        "semver": "bin/semver"
      }
    },
    "node_modules/set-blocking": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
      "dev": true
    },
    "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/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/signal-exit": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
      "dev": true
    },
    "node_modules/spawn-wrap": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
      "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
      "dev": true,
      "dependencies": {
        "foreground-child": "^2.0.0",
        "is-windows": "^1.0.2",
        "make-dir": "^3.0.0",
        "rimraf": "^3.0.0",
        "signal-exit": "^3.0.2",
        "which": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/spawn-wrap/node_modules/rimraf": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "dev": true,
      "dependencies": {
        "glob": "^7.1.3"
      },
      "bin": {
        "rimraf": "bin.js"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/sprintf-js": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
      "dev": true
    },
    "node_modules/sshpk": {
      "version": "1.17.0",
      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
      "dev": true,
      "dependencies": {
        "asn1": "~0.2.3",
        "assert-plus": "^1.0.0",
        "bcrypt-pbkdf": "^1.0.0",
        "dashdash": "^1.12.0",
        "ecc-jsbn": "~0.1.1",
        "getpass": "^0.1.1",
        "jsbn": "~0.1.0",
        "safer-buffer": "^2.0.2",
        "tweetnacl": "~0.14.0"
      },
      "bin": {
        "sshpk-conv": "bin/sshpk-conv",
        "sshpk-sign": "bin/sshpk-sign",
        "sshpk-verify": "bin/sshpk-verify"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/statuses": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
      "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/string.prototype.trim": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
      "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
      "dev": true,
      "dependencies": {
        "define-properties": "^1.1.2",
        "es-abstract": "^1.5.0",
        "function-bind": "^1.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/strip-bom": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
      "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "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"
      }
    },
    "node_modules/supports-color": {
      "version": "5.5.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
      "dev": true,
      "dependencies": {
        "has-flag": "^3.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "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": {
        "@pkgr/core": "^0.1.0",
        "tslib": "^2.6.2"
      },
      "engines": {
        "node": "^14.18.0 || >=16.0.0"
      },
      "funding": {
        "url": "https://opencollective.com/unts"
      }
    },
    "node_modules/tape": {
      "version": "4.9.1",
      "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz",
      "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==",
      "dev": true,
      "dependencies": {
        "deep-equal": "~1.0.1",
        "defined": "~1.0.0",
        "for-each": "~0.3.3",
        "function-bind": "~1.1.1",
        "glob": "~7.1.2",
        "has": "~1.0.3",
        "inherits": "~2.0.3",
        "minimist": "~1.2.0",
        "object-inspect": "~1.6.0",
        "resolve": "~1.7.1",
        "resumer": "~0.0.0",
        "string.prototype.trim": "~1.1.2",
        "through": "~2.3.8"
      },
      "bin": {
        "tape": "bin/tape"
      }
    },
    "node_modules/tape/node_modules/resolve": {
      "version": "1.7.1",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
      "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
      "dev": true,
      "dependencies": {
        "path-parse": "^1.0.5"
      }
    },
    "node_modules/tape/node_modules/resolve/node_modules/path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
      "dev": true
    },
    "node_modules/test-exclude": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
      "dev": true,
      "dependencies": {
        "@istanbuljs/schema": "^0.1.2",
        "glob": "^7.1.4",
        "minimatch": "^3.0.4"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/test-exclude/node_modules/glob": {
      "version": "7.1.6",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
      "dev": true,
      "dependencies": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.0.4",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      },
      "engines": {
        "node": "*"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "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/to-fast-properties": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/tough-cookie": {
      "version": "2.5.0",
      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
      "dev": true,
      "dependencies": {
        "psl": "^1.1.28",
        "punycode": "^2.1.1"
      },
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/tslib": {
      "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": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "^5.0.1"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/tweetnacl": {
      "version": "0.14.5",
      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
      "dev": true
    },
    "node_modules/type-check": {
      "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.2.1"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/type-fest": {
      "version": "0.8.1",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/typedarray-to-buffer": {
      "version": "3.1.5",
      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
      "dev": true,
      "dependencies": {
        "is-typedarray": "^1.0.0"
      }
    },
    "node_modules/typescript": {
      "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": ">=14.17"
      }
    },
    "node_modules/uc.micro": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
      "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
      "dev": true
    },
    "node_modules/underscore": {
      "version": "1.13.6",
      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
      "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",
      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/uri-js": {
      "version": "4.2.2",
      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
      "dev": true,
      "dependencies": {
        "punycode": "^2.1.0"
      }
    },
    "node_modules/utf-8-validate": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz",
      "integrity": "sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw==",
      "dev": true,
      "hasInstallScript": true,
      "dependencies": {
        "node-gyp-build": "~3.7.0"
      }
    },
    "node_modules/utils-merge": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
      "dev": true,
      "engines": {
        "node": ">= 0.4.0"
      }
    },
    "node_modules/uuid": {
      "version": "13.0.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
      "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
      "funding": [
        "https://github.com/sponsors/broofa",
        "https://github.com/sponsors/ctavan"
      ],
      "license": "MIT",
      "bin": {
        "uuid": "dist-node/bin/uuid"
      }
    },
    "node_modules/valid-url": {
      "version": "1.0.9",
      "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
      "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==",
      "dev": true
    },
    "node_modules/verror": {
      "version": "1.10.0",
      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
      "dev": true,
      "engines": [
        "node >=0.6.0"
      ],
      "dependencies": {
        "assert-plus": "^1.0.0",
        "core-util-is": "1.0.2",
        "extsprintf": "^1.2.0"
      }
    },
    "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/which-module": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
      "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",
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^4.0.0",
        "string-width": "^4.1.0",
        "strip-ansi": "^6.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/wrap-ansi/node_modules/ansi-regex": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/wrap-ansi/node_modules/ansi-styles": {
      "version": "4.2.1",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
      "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
      "dev": true,
      "dependencies": {
        "@types/color-name": "^1.1.1",
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/wrap-ansi/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/wrap-ansi/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/wrap-ansi/node_modules/is-fullwidth-code-point": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/wrap-ansi/node_modules/string-width": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
      "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
      "dev": true,
      "dependencies": {
        "emoji-regex": "^8.0.0",
        "is-fullwidth-code-point": "^3.0.0",
        "strip-ansi": "^6.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/wrap-ansi/node_modules/strip-ansi": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
      "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^5.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
      "dev": true
    },
    "node_modules/write-file-atomic": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz",
      "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==",
      "dev": true,
      "dependencies": {
        "imurmurhash": "^0.1.4",
        "is-typedarray": "^1.0.0",
        "signal-exit": "^3.0.2",
        "typedarray-to-buffer": "^3.1.5"
      }
    },
    "node_modules/ws": {
      "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"
      }
    },
    "node_modules/xmlcreate": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
      "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
      "dev": true
    },
    "node_modules/y18n": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
      "dev": true
    },
    "node_modules/yargs": {
      "version": "15.4.1",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
      "dev": true,
      "dependencies": {
        "cliui": "^6.0.0",
        "decamelize": "^1.2.0",
        "find-up": "^4.1.0",
        "get-caller-file": "^2.0.1",
        "require-directory": "^2.1.1",
        "require-main-filename": "^2.0.0",
        "set-blocking": "^2.0.0",
        "string-width": "^4.2.0",
        "which-module": "^2.0.0",
        "y18n": "^4.0.0",
        "yargs-parser": "^18.1.2"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/yargs/node_modules/ansi-regex": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/yargs/node_modules/is-fullwidth-code-point": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/yargs/node_modules/string-width": {
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
      "dev": true,
      "dependencies": {
        "emoji-regex": "^8.0.0",
        "is-fullwidth-code-point": "^3.0.0",
        "strip-ansi": "^6.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/yargs/node_modules/strip-ansi": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^5.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/yargs/node_modules/yargs-parser": {
      "version": "18.1.3",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
      "dev": true,
      "dependencies": {
        "camelcase": "^5.0.0",
        "decamelize": "^1.2.0"
      },
      "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"
      }
    }
  }
}
thrift-0.23.0/install-sh0000755000175000017500000003577615166015674015415 0ustar00buildbuild00000000000000#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2020-11-14.01; # UTC

# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.

tab='	'
nl='
'
IFS=" $tab$nl"

# Set DOITPROG to "echo" to test this script.

doit=${DOITPROG-}
doit_exec=${doit:-exec}

# Put in absolute file names if you don't have them in your path;
# or use environment vars.

chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}

posix_mkdir=

# Desired mode of installed file.
mode=0755

# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22

backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=

src=
dst=
dir_arg=
dst_arg=

copy_on_change=false
is_target_a_directory=possibly

usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...

In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -p            pass -p to $cpprog.
  -s            $stripprog installed files.
  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG

By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.

If -S is not specified, no backups are attempted.

Email bug reports to bug-automake@gnu.org.
Automake home page: https://www.gnu.org/software/automake/
"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;

    -d) dir_arg=true;;

    -g) chgrpcmd="$chgrpprog $2"
        shift;;

    --help) echo "$usage"; exit $?;;

    -m) mode=$2
        case $mode in
          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
            echo "$0: invalid mode: $mode" >&2
            exit 1;;
        esac
        shift;;

    -o) chowncmd="$chownprog $2"
        shift;;

    -p) cpprog="$cpprog -p";;

    -s) stripcmd=$stripprog;;

    -S) backupsuffix="$2"
        shift;;

    -t)
        is_target_a_directory=always
        dst_arg=$2
        # Protect names problematic for 'test' and other utilities.
        case $dst_arg in
          -* | [=\(\)!]) dst_arg=./$dst_arg;;
        esac
        shift;;

    -T) is_target_a_directory=never;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --) shift
        break;;

    -*) echo "$0: invalid option: $1" >&2
        exit 1;;

    *)  break;;
  esac
  shift
done

# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.

if test -n "$dir_arg"; then
  if test -n "$dst_arg"; then
    echo "$0: target directory not allowed when installing a directory." >&2
    exit 1
  fi
fi

if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
    dst_arg=$arg
    # Protect names problematic for 'test' and other utilities.
    case $dst_arg in
      -* | [=\(\)!]) dst_arg=./$dst_arg;;
    esac
  done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call 'install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi

if test -z "$dir_arg"; then
  if test $# -gt 1 || test "$is_target_a_directory" = always; then
    if test ! -d "$dst_arg"; then
      echo "$0: $dst_arg: Is not a directory." >&2
      exit 1
    fi
  fi
fi

if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

    *[0-7])
      if test -z "$stripcmd"; then
        u_plus_rw=
      else
        u_plus_rw='% 200'
      fi
      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
        u_plus_rw=
      else
        u_plus_rw=,u+rw
      fi
      cp_umask=$mode$u_plus_rw;;
  esac
fi

for src
do
  # Protect names problematic for 'test' and other utilities.
  case $src in
    -* | [=\(\)!]) src=./$src;;
  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
    # Don't chown directories that already exist.
    if test $dstdir_status = 0; then
      chowncmd=""
    fi
  else

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2
      exit 1
    fi

    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi
    dst=$dst_arg

    # If destination is a directory, append the input filename.
    if test -d "$dst"; then
      if test "$is_target_a_directory" = never; then
        echo "$0: $dst_arg: Is a directory" >&2
        exit 1
      fi
      dstdir=$dst
      dstbase=`basename "$src"`
      case $dst in
	*/) dst=$dst$dstbase;;
	*)  dst=$dst/$dstbase;;
      esac
      dstdir_status=0
    else
      dstdir=`dirname "$dst"`
      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi

  case $dstdir in
    */) dstdirslash=$dstdir;;
    *)  dstdirslash=$dstdir/;;
  esac

  obsolete_mkdir_used=false

  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
        # With -d, create the new directory with the user-specified mode.
        # Otherwise, rely on $mkdir_umask.
        if test -n "$dir_arg"; then
          mkdir_mode=-m$mode
        else
          mkdir_mode=
        fi

        posix_mkdir=false
	# The $RANDOM variable is not portable (e.g., dash).  Use it
	# here however when possible just to lower collision chance.
	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$

	trap '
	  ret=$?
	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
	  exit $ret
	' 0

	# Because "mkdir -p" follows existing symlinks and we likely work
	# directly in world-writeable /tmp, make sure that the '$tmpdir'
	# directory is successfully created first before we actually test
	# 'mkdir -p'.
	if (umask $mkdir_umask &&
	    $mkdirprog $mkdir_mode "$tmpdir" &&
	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
	then
	  if test -z "$dir_arg" || {
	       # Check for POSIX incompatibilities with -m.
	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
	       # other-writable bit of parent directory when it shouldn't.
	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
	       test_tmpdir="$tmpdir/a"
	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
	       case $ls_ld_tmpdir in
		 d????-?r-*) different_mode=700;;
		 d????-?--*) different_mode=755;;
		 *) false;;
	       esac &&
	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
	       }
	     }
	  then posix_mkdir=:
	  fi
	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
	else
	  # Remove any dirs left behind by ancient mkdir implementations.
	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
	fi
	trap '' 0;;
    esac

    if
      $posix_mkdir && (
        umask $mkdir_umask &&
        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )
    then :
    else

      # mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.

      case $dstdir in
        /*) prefix='/';;
        [-=\(\)!]*) prefix='./';;
        *)  prefix='';;
      esac

      oIFS=$IFS
      IFS=/
      set -f
      set fnord $dstdir
      shift
      set +f
      IFS=$oIFS

      prefixes=

      for d
      do
        test X"$d" = X && continue

        prefix=$prefix$d
        if test -d "$prefix"; then
          prefixes=
        else
          if $posix_mkdir; then
            (umask $mkdir_umask &&
             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
            # Don't fail if two instances are running concurrently.
            test -d "$prefix" || exit 1
          else
            case $prefix in
              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
              *) qprefix=$prefix;;
            esac
            prefixes="$prefixes '$qprefix'"
          fi
        fi
        prefix=$prefix/
      done

      if test -n "$prefixes"; then
        # Don't fail if two instances are running concurrently.
        (umask $mkdir_umask &&
         eval "\$doit_exec \$mkdirprog $prefixes") ||
          test -d "$dstdir" || exit 1
        obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else

    # Make a couple of temp file names in the proper directory.
    dsttmp=${dstdirslash}_inst.$$_
    rmtmp=${dstdirslash}_rm.$$_

    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0

    # Copy the file name to the temp name.
    (umask $cp_umask &&
     { test -z "$stripcmd" || {
	 # Create $dsttmp read-write so that cp doesn't create it read-only,
	 # which would cause strip to fail.
	 if test -z "$doit"; then
	   : >"$dsttmp" # No need to fork-exec 'touch'.
	 else
	   $doit touch "$dsttmp"
	 fi
       }
     } &&
     $doit_exec $cpprog "$src" "$dsttmp") &&

    # and set any options; do chmod last to preserve setuid bits.
    #
    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
       set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       set +f &&
       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # If $backupsuffix is set, and the file being installed
      # already exists, attempt a backup.  Don't worry if it fails,
      # e.g., if mv doesn't support -f.
      if test -n "$backupsuffix" && test -f "$dst"; then
        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
      fi

      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
        # Now remove or move aside any old file at destination location.
        # We try this two ways since rm can't unlink itself on some
        # systems and the destination file might be busy for other
        # reasons.  In this case, the final cleanup might fail but the new
        # file should still install successfully.
        {
          test ! -f "$dst" ||
          $doit $rmcmd "$dst" 2>/dev/null ||
          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
          } ||
          { echo "$0: cannot unlink or rename $dst" >&2
            (exit 1); exit 1
          }
        } &&

        # Now rename the file to the real destination.
        $doit $mvcmd "$dsttmp" "$dst"
      }
    fi || exit 1

    trap '' 0
  fi
done

# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
thrift-0.23.0/NOTICE0000664000175000017500000000025615165535636014304 0ustar00buildbuild00000000000000Apache Thrift
Copyright (C) 2006 - 2019, The Apache Software Foundation

This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
thrift-0.23.0/.gitattributes0000664000175000017500000000001415165535636016263 0ustar00buildbuild00000000000000* text=auto
thrift-0.23.0/missing0000755000175000017500000001533615166015674014776 0ustar00buildbuild00000000000000#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.

scriptversion=2018-03-07.03; # UTC

# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard , 1996.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

if test $# -eq 0; then
  echo 1>&2 "Try '$0 --help' for more information"
  exit 1
fi

case $1 in

  --is-lightweight)
    # Used by our autoconf macros to check whether the available missing
    # script is modern enough.
    exit 0
    ;;

  --run)
    # Back-compat with the calling convention used by older automake.
    shift
    ;;

  -h|--h|--he|--hel|--help)
    echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...

Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.

Options:
  -h, --help      display this help and exit
  -v, --version   output version information and exit

Supported PROGRAM values:
  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
  bison     yacc      flex         lex       help2man

Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.

Send bug reports to ."
    exit $?
    ;;

  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
    echo "missing $scriptversion (GNU Automake)"
    exit $?
    ;;

  -*)
    echo 1>&2 "$0: unknown '$1' option"
    echo 1>&2 "Try '$0 --help' for more information"
    exit 1
    ;;

esac

# Run the given program, remember its exit status.
"$@"; st=$?

# If it succeeded, we are done.
test $st -eq 0 && exit 0

# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac

# Exit code 63 means version mismatch.  This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
  msg="probably too old"
elif test $st -eq 127; then
  # Program was missing.
  msg="missing on your system"
else
  # Program was found and executed, but failed.  Give up.
  exit $st
fi

perl_URL=https://www.perl.org/
flex_URL=https://github.com/westes/flex
gnu_software_URL=https://www.gnu.org/software

program_details ()
{
  case $1 in
    aclocal|automake)
      echo "The '$1' program is part of the GNU Automake package:"
      echo "<$gnu_software_URL/automake>"
      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
      echo "<$gnu_software_URL/autoconf>"
      echo "<$gnu_software_URL/m4/>"
      echo "<$perl_URL>"
      ;;
    autoconf|autom4te|autoheader)
      echo "The '$1' program is part of the GNU Autoconf package:"
      echo "<$gnu_software_URL/autoconf/>"
      echo "It also requires GNU m4 and Perl in order to run:"
      echo "<$gnu_software_URL/m4/>"
      echo "<$perl_URL>"
      ;;
  esac
}

give_advice ()
{
  # Normalize program name to check for.
  normalized_program=`echo "$1" | sed '
    s/^gnu-//; t
    s/^gnu//; t
    s/^g//; t'`

  printf '%s\n' "'$1' is $msg."

  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
  case $normalized_program in
    autoconf*)
      echo "You should only need it if you modified 'configure.ac',"
      echo "or m4 files included by it."
      program_details 'autoconf'
      ;;
    autoheader*)
      echo "You should only need it if you modified 'acconfig.h' or"
      echo "$configure_deps."
      program_details 'autoheader'
      ;;
    automake*)
      echo "You should only need it if you modified 'Makefile.am' or"
      echo "$configure_deps."
      program_details 'automake'
      ;;
    aclocal*)
      echo "You should only need it if you modified 'acinclude.m4' or"
      echo "$configure_deps."
      program_details 'aclocal'
      ;;
   autom4te*)
      echo "You might have modified some maintainer files that require"
      echo "the 'autom4te' program to be rebuilt."
      program_details 'autom4te'
      ;;
    bison*|yacc*)
      echo "You should only need it if you modified a '.y' file."
      echo "You may want to install the GNU Bison package:"
      echo "<$gnu_software_URL/bison/>"
      ;;
    lex*|flex*)
      echo "You should only need it if you modified a '.l' file."
      echo "You may want to install the Fast Lexical Analyzer package:"
      echo "<$flex_URL>"
      ;;
    help2man*)
      echo "You should only need it if you modified a dependency" \
           "of a man page."
      echo "You may want to install the GNU Help2man package:"
      echo "<$gnu_software_URL/help2man/>"
    ;;
    makeinfo*)
      echo "You should only need it if you modified a '.texi' file, or"
      echo "any other file indirectly affecting the aspect of the manual."
      echo "You might want to install the Texinfo package:"
      echo "<$gnu_software_URL/texinfo/>"
      echo "The spurious makeinfo call might also be the consequence of"
      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
      echo "want to install GNU make:"
      echo "<$gnu_software_URL/make/>"
      ;;
    *)
      echo "You might have modified some files without having the proper"
      echo "tools for further handling them.  Check the 'README' file, it"
      echo "often tells you about the needed prerequisites for installing"
      echo "this package.  You may also peek at any GNU archive site, in"
      echo "case some other package contains this missing '$1' program."
      ;;
  esac
}

give_advice "$1" | sed -e '1s/^/WARNING: /' \
                       -e '2,$s/^/         /' >&2

# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st

# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
thrift-0.23.0/README.md0000664000175000017500000001573715165535636014671 0ustar00buildbuild00000000000000Apache Thrift
=============

Introduction
============

Thrift is a lightweight, language-independent software stack for
point-to-point RPC implementation.
Thrift provides clean abstractions and implementations for data transport,
data serialization, and application level processing. The code generation
system takes a simple definition language as input and generates code
across programming languages that uses the abstracted stack to build
interoperable RPC clients and servers.

![Apache Thrift Layered Architecture](doc/images/thrift-layers.png)

Thrift makes it easy for programs written in different programming
languages to share data and call remote procedures.  With support
for [28 programming languages](LANGUAGES.md), chances are Thrift
supports the languages that you currently use.

Thrift is specifically designed to support non-atomic version changes
across client and server code.  This allows you to upgrade your
server while still being able to service older clients; or have newer
clients issue requests to older servers.  An excellent community-provided
write-up about thrift and compatibility when versioning an API can be
found in the [Thrift Missing Guide](https://diwakergupta.github.io/thrift-missing-guide/#_versioning_compatibility).

For more details on Thrift's design and implementation, see the Thrift
whitepaper included in this distribution, or at the README.md file
in your particular subdirectory of interest.

Status
======

| Branch | Travis | Appveyor | Coverity Scan | codecov.io | Website |
| :----- | :----- | :------- | :------------ | :--------- | :------ |
| [`master`](https://github.com/apache/thrift/tree/master) | [![Build Status](https://api.travis-ci.com/apache/thrift.svg?branch=master)](https://app.travis-ci.com/apache/thrift/branches) | [![Build status](https://ci.appveyor.com/api/projects/status/github/apache/thrift?branch=master&svg=true)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/thrift/history) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/1345/badge.svg)](https://scan.coverity.com/projects/thrift) | | [![Website](https://img.shields.io/badge/official-website-brightgreen.svg)](https://thrift.apache.org/) |
| [`0.17.0`](https://github.com/apache/thrift/tree/0.17.0) | [![Build Status](https://api.travis-ci.com/apache/thrift.svg?branch=0.17.0)](https://app.travis-ci.com/apache/thrift/branches) | | | | |

Releases
========

Thrift does not maintain a specific release calendar at this time.

We strive to release twice yearly.  Download the [current release](http://thrift.apache.org/download).

License
=======

Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.

Project Hierarchy
=================

thrift/

  compiler/

    Contains the Thrift compiler, implemented in C++.

  lib/

    Contains the Thrift software library implementation, subdivided by
    language of implementation.

    cpp/
    go/
    java/
    php/
    py/
    rb/
    ...

  test/

    Contains sample Thrift files and test code across the target programming
    languages.

  tutorial/

    Contains a basic tutorial that will teach you how to develop software
    using Thrift.

Development
===========

To build the same way Travis CI builds the project you should use docker.
We have [comprehensive building instructions for docker](build/docker/README.md).

Requirements
============

See http://thrift.apache.org/docs/install for a list of build requirements (may be stale).  Alternatively, see the docker build environments for a list of prerequisites.

Resources
=========

More information about Thrift can be obtained on the Thrift webpage at:

     http://thrift.apache.org

Acknowledgments
===============

Thrift was inspired by pillar, a lightweight RPC tool written by Adam D'Angelo,
and also by Google's protocol buffers.

Installation
============

If you are building from the first time out of the source repository, you will
need to generate the configure scripts.  (This is not necessary if you
downloaded a tarball.)  From the top directory, do:

    ./bootstrap.sh

Once the configure scripts are generated, thrift can be configured.
From the top directory, do:

    ./configure

You may need to specify the location of the boost files explicitly.
If you installed boost in `/usr/local`, you would run configure as follows:

    ./configure --with-boost=/usr/local

Note that by default the thrift C++ library is typically built with debugging
symbols included. If you want to customize these options you should use the
CXXFLAGS option in configure, as such:

    ./configure CXXFLAGS='-g -O2'
    ./configure CFLAGS='-g -O2'
    ./configure CPPFLAGS='-DDEBUG_MY_FEATURE'

To enable gcov required options -fprofile-arcs -ftest-coverage enable them:

    ./configure  --enable-coverage

Run ./configure --help to see other configuration options

Please be aware that the Python library will ignore the --prefix option
and just install wherever Python's distutils puts it (usually along
the lines of `/usr/lib/pythonX.Y/site-packages/`).  If you need to control
where the Python modules are installed, set the PY_PREFIX variable.
(DESTDIR is respected for Python and C++.)

Make thrift:

    make

From the top directory, become superuser and do:

    make install

Uninstall thrift:

    make uninstall

Note that some language packages must be installed manually using build tools
better suited to those languages (at the time of this writing, this applies
to Java, Ruby, PHP).

Look for the README.md file in the lib// folder for more details on the
installation of each language library package.

Package Managers
================

Apache Thrift is available via a number of package managers, a list which is
is steadily growing. A more detailed overview can be found
[at the Apache Thrift web site under "Libraries"](http://thrift.apache.org/lib/)
and/or in the respective READMEs for each language under /lib

Testing
=======

There are a large number of client library tests that can all be run
from the top-level directory.

    make -k check

This will make all of the libraries (as necessary), and run through
the unit tests defined in each of the client libraries. If a single
language fails, the make check will continue on and provide a synopsis
at the end.

To run the cross-language test suite, please run:

    make cross

This will run a set of tests that use different language clients and
servers.


thrift-0.23.0/ltmain.sh0000755000175000017500000117720315166015672015223 0ustar00buildbuild00000000000000#! /bin/sh
## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
##               by inline-source v2014-01-03.01

# libtool (GNU libtool) 2.4.6
# Provide generalized library-building support services.
# Written by Gordon Matzigkeit , 1996

# Copyright (C) 1996-2015 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.  There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# GNU Libtool is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# As a special exception to the GNU General Public License,
# if you distribute this file as part of a program or library that
# is built using GNU Libtool, you may include this file under the
# same distribution terms that you use for the rest of that program.
#
# GNU Libtool is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .


PROGRAM=libtool
PACKAGE=libtool
VERSION="2.4.6 Debian-2.4.6-15build2"
package_revision=2.4.6


## ------ ##
## Usage. ##
## ------ ##

# Run './libtool --help' for help with using this script from the
# command line.


## ------------------------------- ##
## User overridable command paths. ##
## ------------------------------- ##

# After configure completes, it has a better idea of some of the
# shell tools we need than the defaults used by the functions shared
# with bootstrap, so set those here where they can still be over-
# ridden by the user, but otherwise take precedence.

: ${AUTOCONF="autoconf"}
: ${AUTOMAKE="automake"}


## -------------------------- ##
## Source external libraries. ##
## -------------------------- ##

# Much of our low-level functionality needs to be sourced from external
# libraries, which are installed to $pkgauxdir.

# Set a version string for this script.
scriptversion=2015-01-20.17; # UTC

# General shell script boiler plate, and helper functions.
# Written by Gary V. Vaughan, 2004

# Copyright (C) 2004-2015 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.  There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.

# As a special exception to the GNU General Public License, if you distribute
# this file as part of a program or library that is built using GNU Libtool,
# you may include this file under the same distribution terms that you use
# for the rest of that program.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see .

# Please report bugs or propose patches to gary@gnu.org.


## ------ ##
## Usage. ##
## ------ ##

# Evaluate this file near the top of your script to gain access to
# the functions and variables defined here:
#
#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
#
# If you need to override any of the default environment variable
# settings, do that before evaluating this file.


## -------------------- ##
## Shell normalisation. ##
## -------------------- ##

# Some shells need a little help to be as Bourne compatible as possible.
# Before doing anything else, make sure all that help has been provided!

DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
fi

# NLS nuisances: We save the old values in case they are required later.
_G_user_locale=
_G_safe_locale=
for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
do
  eval "if test set = \"\${$_G_var+set}\"; then
          save_$_G_var=\$$_G_var
          $_G_var=C
	  export $_G_var
	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
	fi"
done

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

# Make sure IFS has a sensible default
sp=' '
nl='
'
IFS="$sp	$nl"

# There are apparently some retarded systems that use ';' as a PATH separator!
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi



## ------------------------- ##
## Locate command utilities. ##
## ------------------------- ##


# func_executable_p FILE
# ----------------------
# Check that FILE is an executable regular file.
func_executable_p ()
{
    test -f "$1" && test -x "$1"
}


# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
# --------------------------------------------
# Search for either a program that responds to --version with output
# containing "GNU", or else returned by CHECK_FUNC otherwise, by
# trying all the directories in PATH with each of the elements of
# PROGS_LIST.
#
# CHECK_FUNC should accept the path to a candidate program, and
# set $func_check_prog_result if it truncates its output less than
# $_G_path_prog_max characters.
func_path_progs ()
{
    _G_progs_list=$1
    _G_check_func=$2
    _G_PATH=${3-"$PATH"}

    _G_path_prog_max=0
    _G_path_prog_found=false
    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
    for _G_dir in $_G_PATH; do
      IFS=$_G_save_IFS
      test -z "$_G_dir" && _G_dir=.
      for _G_prog_name in $_G_progs_list; do
        for _exeext in '' .EXE; do
          _G_path_prog=$_G_dir/$_G_prog_name$_exeext
          func_executable_p "$_G_path_prog" || continue
          case `"$_G_path_prog" --version 2>&1` in
            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
            *)     $_G_check_func $_G_path_prog
		   func_path_progs_result=$func_check_prog_result
		   ;;
          esac
          $_G_path_prog_found && break 3
        done
      done
    done
    IFS=$_G_save_IFS
    test -z "$func_path_progs_result" && {
      echo "no acceptable sed could be found in \$PATH" >&2
      exit 1
    }
}


# We want to be able to use the functions in this file before configure
# has figured out where the best binaries are kept, which means we have
# to search for them ourselves - except when the results are already set
# where we skip the searches.

# Unless the user overrides by setting SED, search the path for either GNU
# sed, or the sed that truncates its output the least.
test -z "$SED" && {
  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
  for _G_i in 1 2 3 4 5 6 7; do
    _G_sed_script=$_G_sed_script$nl$_G_sed_script
  done
  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
  _G_sed_script=

  func_check_prog_sed ()
  {
    _G_path_prog=$1

    _G_count=0
    printf 0123456789 >conftest.in
    while :
    do
      cat conftest.in conftest.in >conftest.tmp
      mv conftest.tmp conftest.in
      cp conftest.in conftest.nl
      echo '' >> conftest.nl
      "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break
      diff conftest.out conftest.nl >/dev/null 2>&1 || break
      _G_count=`expr $_G_count + 1`
      if test "$_G_count" -gt "$_G_path_prog_max"; then
        # Best one so far, save it but keep looking for a better one
        func_check_prog_result=$_G_path_prog
        _G_path_prog_max=$_G_count
      fi
      # 10*(2^10) chars as input seems more than enough
      test 10 -lt "$_G_count" && break
    done
    rm -f conftest.in conftest.tmp conftest.nl conftest.out
  }

  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
  rm -f conftest.sed
  SED=$func_path_progs_result
}


# Unless the user overrides by setting GREP, search the path for either GNU
# grep, or the grep that truncates its output the least.
test -z "$GREP" && {
  func_check_prog_grep ()
  {
    _G_path_prog=$1

    _G_count=0
    _G_path_prog_max=0
    printf 0123456789 >conftest.in
    while :
    do
      cat conftest.in conftest.in >conftest.tmp
      mv conftest.tmp conftest.in
      cp conftest.in conftest.nl
      echo 'GREP' >> conftest.nl
      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break
      diff conftest.out conftest.nl >/dev/null 2>&1 || break
      _G_count=`expr $_G_count + 1`
      if test "$_G_count" -gt "$_G_path_prog_max"; then
        # Best one so far, save it but keep looking for a better one
        func_check_prog_result=$_G_path_prog
        _G_path_prog_max=$_G_count
      fi
      # 10*(2^10) chars as input seems more than enough
      test 10 -lt "$_G_count" && break
    done
    rm -f conftest.in conftest.tmp conftest.nl conftest.out
  }

  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
  GREP=$func_path_progs_result
}


## ------------------------------- ##
## User overridable command paths. ##
## ------------------------------- ##

# All uppercase variable names are used for environment variables.  These
# variables can be overridden by the user before calling a script that
# uses them if a suitable command of that name is not already available
# in the command search PATH.

: ${CP="cp -f"}
: ${ECHO="printf %s\n"}
: ${EGREP="$GREP -E"}
: ${FGREP="$GREP -F"}
: ${LN_S="ln -s"}
: ${MAKE="make"}
: ${MKDIR="mkdir"}
: ${MV="mv -f"}
: ${RM="rm -f"}
: ${SHELL="${CONFIG_SHELL-/bin/sh}"}


## -------------------- ##
## Useful sed snippets. ##
## -------------------- ##

sed_dirname='s|/[^/]*$||'
sed_basename='s|^.*/||'

# Sed substitution that helps us do robust quoting.  It backslashifies
# metacharacters that are still active within double-quoted strings.
sed_quote_subst='s|\([`"$\\]\)|\\\1|g'

# Same as above, but do not quote variable references.
sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'

# Sed substitution that turns a string into a regex matching for the
# string literally.
sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'

# Sed substitution that converts a w32 file name or path
# that contains forward slashes, into one that contains
# (escaped) backslashes.  A very naive implementation.
sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'

# Re-'\' parameter expansions in output of sed_double_quote_subst that
# were '\'-ed in input to the same.  If an odd number of '\' preceded a
# '$' in input to sed_double_quote_subst, that '$' was protected from
# expansion.  Since each input '\' is now two '\'s, look for any number
# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
_G_bs='\\'
_G_bs2='\\\\'
_G_bs4='\\\\\\\\'
_G_dollar='\$'
sed_double_backslash="\
  s/$_G_bs4/&\\
/g
  s/^$_G_bs2$_G_dollar/$_G_bs&/
  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
  s/\n//g"


## ----------------- ##
## Global variables. ##
## ----------------- ##

# Except for the global variables explicitly listed below, the following
# functions in the '^func_' namespace, and the '^require_' namespace
# variables initialised in the 'Resource management' section, sourcing
# this file will not pollute your global namespace with anything
# else. There's no portable way to scope variables in Bourne shell
# though, so actually running these functions will sometimes place
# results into a variable named after the function, and often use
# temporary variables in the '^_G_' namespace. If you are careful to
# avoid using those namespaces casually in your sourcing script, things
# should continue to work as you expect. And, of course, you can freely
# overwrite any of the functions or variables defined here before
# calling anything to customize them.

EXIT_SUCCESS=0
EXIT_FAILURE=1
EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.

# Allow overriding, eg assuming that you follow the convention of
# putting '$debug_cmd' at the start of all your functions, you can get
# bash to show function call trace with:
#
#    debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
debug_cmd=${debug_cmd-":"}
exit_cmd=:

# By convention, finish your script with:
#
#    exit $exit_status
#
# so that you can set exit_status to non-zero if you want to indicate
# something went wrong during execution without actually bailing out at
# the point of failure.
exit_status=$EXIT_SUCCESS

# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
# is ksh but when the shell is invoked as "sh" and the current value of
# the _XPG environment variable is not equal to 1 (one), the special
# positional parameter $0, within a function call, is the name of the
# function.
progpath=$0

# The name of this program.
progname=`$ECHO "$progpath" |$SED "$sed_basename"`

# Make sure we have an absolute progpath for reexecution:
case $progpath in
  [\\/]*|[A-Za-z]:\\*) ;;
  *[\\/]*)
     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
     progdir=`cd "$progdir" && pwd`
     progpath=$progdir/$progname
     ;;
  *)
     _G_IFS=$IFS
     IFS=${PATH_SEPARATOR-:}
     for progdir in $PATH; do
       IFS=$_G_IFS
       test -x "$progdir/$progname" && break
     done
     IFS=$_G_IFS
     test -n "$progdir" || progdir=`pwd`
     progpath=$progdir/$progname
     ;;
esac


## ----------------- ##
## Standard options. ##
## ----------------- ##

# The following options affect the operation of the functions defined
# below, and should be set appropriately depending on run-time para-
# meters passed on the command line.

opt_dry_run=false
opt_quiet=false
opt_verbose=false

# Categories 'all' and 'none' are always available.  Append any others
# you will pass as the first argument to func_warning from your own
# code.
warning_categories=

# By default, display warnings according to 'opt_warning_types'.  Set
# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
# treat the next displayed warning as a fatal error.
warning_func=func_warn_and_continue

# Set to 'all' to display all warnings, 'none' to suppress all
# warnings, or a space delimited list of some subset of
# 'warning_categories' to display only the listed warnings.
opt_warning_types=all


## -------------------- ##
## Resource management. ##
## -------------------- ##

# This section contains definitions for functions that each ensure a
# particular resource (a file, or a non-empty configuration variable for
# example) is available, and if appropriate to extract default values
# from pertinent package files. Call them using their associated
# 'require_*' variable to ensure that they are executed, at most, once.
#
# It's entirely deliberate that calling these functions can set
# variables that don't obey the namespace limitations obeyed by the rest
# of this file, in order that that they be as useful as possible to
# callers.


# require_term_colors
# -------------------
# Allow display of bold text on terminals that support it.
require_term_colors=func_require_term_colors
func_require_term_colors ()
{
    $debug_cmd

    test -t 1 && {
      # COLORTERM and USE_ANSI_COLORS environment variables take
      # precedence, because most terminfo databases neglect to describe
      # whether color sequences are supported.
      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}

      if test 1 = "$USE_ANSI_COLORS"; then
        # Standard ANSI escape sequences
        tc_reset=''
        tc_bold='';   tc_standout=''
        tc_red='';   tc_green=''
        tc_blue='';  tc_cyan=''
      else
        # Otherwise trust the terminfo database after all.
        test -n "`tput sgr0 2>/dev/null`" && {
          tc_reset=`tput sgr0`
          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
          tc_standout=$tc_bold
          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
        }
      fi
    }

    require_term_colors=:
}


## ----------------- ##
## Function library. ##
## ----------------- ##

# This section contains a variety of useful functions to call in your
# scripts. Take note of the portable wrappers for features provided by
# some modern shells, which will fall back to slower equivalents on
# less featureful shells.


# func_append VAR VALUE
# ---------------------
# Append VALUE onto the existing contents of VAR.

  # We should try to minimise forks, especially on Windows where they are
  # unreasonably slow, so skip the feature probes when bash or zsh are
  # being used:
  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
    : ${_G_HAVE_ARITH_OP="yes"}
    : ${_G_HAVE_XSI_OPS="yes"}
    # The += operator was introduced in bash 3.1
    case $BASH_VERSION in
      [12].* | 3.0 | 3.0*) ;;
      *)
        : ${_G_HAVE_PLUSEQ_OP="yes"}
        ;;
    esac
  fi

  # _G_HAVE_PLUSEQ_OP
  # Can be empty, in which case the shell is probed, "yes" if += is
  # useable or anything else if it does not work.
  test -z "$_G_HAVE_PLUSEQ_OP" \
    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
    && _G_HAVE_PLUSEQ_OP=yes

if test yes = "$_G_HAVE_PLUSEQ_OP"
then
  # This is an XSI compatible shell, allowing a faster implementation...
  eval 'func_append ()
  {
    $debug_cmd

    eval "$1+=\$2"
  }'
else
  # ...otherwise fall back to using expr, which is often a shell builtin.
  func_append ()
  {
    $debug_cmd

    eval "$1=\$$1\$2"
  }
fi


# func_append_quoted VAR VALUE
# ----------------------------
# Quote VALUE and append to the end of shell variable VAR, separated
# by a space.
if test yes = "$_G_HAVE_PLUSEQ_OP"; then
  eval 'func_append_quoted ()
  {
    $debug_cmd

    func_quote_for_eval "$2"
    eval "$1+=\\ \$func_quote_for_eval_result"
  }'
else
  func_append_quoted ()
  {
    $debug_cmd

    func_quote_for_eval "$2"
    eval "$1=\$$1\\ \$func_quote_for_eval_result"
  }
fi


# func_append_uniq VAR VALUE
# --------------------------
# Append unique VALUE onto the existing contents of VAR, assuming
# entries are delimited by the first character of VALUE.  For example:
#
#   func_append_uniq options " --another-option option-argument"
#
# will only append to $options if " --another-option option-argument "
# is not already present somewhere in $options already (note spaces at
# each end implied by leading space in second argument).
func_append_uniq ()
{
    $debug_cmd

    eval _G_current_value='`$ECHO $'$1'`'
    _G_delim=`expr "$2" : '\(.\)'`

    case $_G_delim$_G_current_value$_G_delim in
      *"$2$_G_delim"*) ;;
      *) func_append "$@" ;;
    esac
}


# func_arith TERM...
# ------------------
# Set func_arith_result to the result of evaluating TERMs.
  test -z "$_G_HAVE_ARITH_OP" \
    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
    && _G_HAVE_ARITH_OP=yes

if test yes = "$_G_HAVE_ARITH_OP"; then
  eval 'func_arith ()
  {
    $debug_cmd

    func_arith_result=$(( $* ))
  }'
else
  func_arith ()
  {
    $debug_cmd

    func_arith_result=`expr "$@"`
  }
fi


# func_basename FILE
# ------------------
# Set func_basename_result to FILE with everything up to and including
# the last / stripped.
if test yes = "$_G_HAVE_XSI_OPS"; then
  # If this shell supports suffix pattern removal, then use it to avoid
  # forking. Hide the definitions single quotes in case the shell chokes
  # on unsupported syntax...
  _b='func_basename_result=${1##*/}'
  _d='case $1 in
        */*) func_dirname_result=${1%/*}$2 ;;
        *  ) func_dirname_result=$3        ;;
      esac'

else
  # ...otherwise fall back to using sed.
  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
      if test "X$func_dirname_result" = "X$1"; then
        func_dirname_result=$3
      else
        func_append func_dirname_result "$2"
      fi'
fi

eval 'func_basename ()
{
    $debug_cmd

    '"$_b"'
}'


# func_dirname FILE APPEND NONDIR_REPLACEMENT
# -------------------------------------------
# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
# otherwise set result to NONDIR_REPLACEMENT.
eval 'func_dirname ()
{
    $debug_cmd

    '"$_d"'
}'


# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
# --------------------------------------------------------
# Perform func_basename and func_dirname in a single function
# call:
#   dirname:  Compute the dirname of FILE.  If nonempty,
#             add APPEND to the result, otherwise set result
#             to NONDIR_REPLACEMENT.
#             value returned in "$func_dirname_result"
#   basename: Compute filename of FILE.
#             value retuned in "$func_basename_result"
# For efficiency, we do not delegate to the functions above but instead
# duplicate the functionality here.
eval 'func_dirname_and_basename ()
{
    $debug_cmd

    '"$_b"'
    '"$_d"'
}'


# func_echo ARG...
# ----------------
# Echo program name prefixed message.
func_echo ()
{
    $debug_cmd

    _G_message=$*

    func_echo_IFS=$IFS
    IFS=$nl
    for _G_line in $_G_message; do
      IFS=$func_echo_IFS
      $ECHO "$progname: $_G_line"
    done
    IFS=$func_echo_IFS
}


# func_echo_all ARG...
# --------------------
# Invoke $ECHO with all args, space-separated.
func_echo_all ()
{
    $ECHO "$*"
}


# func_echo_infix_1 INFIX ARG...
# ------------------------------
# Echo program name, followed by INFIX on the first line, with any
# additional lines not showing INFIX.
func_echo_infix_1 ()
{
    $debug_cmd

    $require_term_colors

    _G_infix=$1; shift
    _G_indent=$_G_infix
    _G_prefix="$progname: $_G_infix: "
    _G_message=$*

    # Strip color escape sequences before counting printable length
    for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
    do
      test -n "$_G_tc" && {
        _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
        _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
      }
    done
    _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes

    func_echo_infix_1_IFS=$IFS
    IFS=$nl
    for _G_line in $_G_message; do
      IFS=$func_echo_infix_1_IFS
      $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
      _G_prefix=$_G_indent
    done
    IFS=$func_echo_infix_1_IFS
}


# func_error ARG...
# -----------------
# Echo program name prefixed message to standard error.
func_error ()
{
    $debug_cmd

    $require_term_colors

    func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2
}


# func_fatal_error ARG...
# -----------------------
# Echo program name prefixed message to standard error, and exit.
func_fatal_error ()
{
    $debug_cmd

    func_error "$*"
    exit $EXIT_FAILURE
}


# func_grep EXPRESSION FILENAME
# -----------------------------
# Check whether EXPRESSION matches any line of FILENAME, without output.
func_grep ()
{
    $debug_cmd

    $GREP "$1" "$2" >/dev/null 2>&1
}


# func_len STRING
# ---------------
# Set func_len_result to the length of STRING. STRING may not
# start with a hyphen.
  test -z "$_G_HAVE_XSI_OPS" \
    && (eval 'x=a/b/c;
      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
    && _G_HAVE_XSI_OPS=yes

if test yes = "$_G_HAVE_XSI_OPS"; then
  eval 'func_len ()
  {
    $debug_cmd

    func_len_result=${#1}
  }'
else
  func_len ()
  {
    $debug_cmd

    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
  }
fi


# func_mkdir_p DIRECTORY-PATH
# ---------------------------
# Make sure the entire path to DIRECTORY-PATH is available.
func_mkdir_p ()
{
    $debug_cmd

    _G_directory_path=$1
    _G_dir_list=

    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then

      # Protect directory names starting with '-'
      case $_G_directory_path in
        -*) _G_directory_path=./$_G_directory_path ;;
      esac

      # While some portion of DIR does not yet exist...
      while test ! -d "$_G_directory_path"; do
        # ...make a list in topmost first order.  Use a colon delimited
	# list incase some portion of path contains whitespace.
        _G_dir_list=$_G_directory_path:$_G_dir_list

        # If the last portion added has no slash in it, the list is done
        case $_G_directory_path in */*) ;; *) break ;; esac

        # ...otherwise throw away the child directory and loop
        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
      done
      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`

      func_mkdir_p_IFS=$IFS; IFS=:
      for _G_dir in $_G_dir_list; do
	IFS=$func_mkdir_p_IFS
        # mkdir can fail with a 'File exist' error if two processes
        # try to create one of the directories concurrently.  Don't
        # stop in that case!
        $MKDIR "$_G_dir" 2>/dev/null || :
      done
      IFS=$func_mkdir_p_IFS

      # Bail out if we (or some other process) failed to create a directory.
      test -d "$_G_directory_path" || \
        func_fatal_error "Failed to create '$1'"
    fi
}


# func_mktempdir [BASENAME]
# -------------------------
# Make a temporary directory that won't clash with other running
# libtool processes, and avoids race conditions if possible.  If
# given, BASENAME is the basename for that directory.
func_mktempdir ()
{
    $debug_cmd

    _G_template=${TMPDIR-/tmp}/${1-$progname}

    if test : = "$opt_dry_run"; then
      # Return a directory name, but don't create it in dry-run mode
      _G_tmpdir=$_G_template-$$
    else

      # If mktemp works, use that first and foremost
      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`

      if test ! -d "$_G_tmpdir"; then
        # Failing that, at least try and use $RANDOM to avoid a race
        _G_tmpdir=$_G_template-${RANDOM-0}$$

        func_mktempdir_umask=`umask`
        umask 0077
        $MKDIR "$_G_tmpdir"
        umask $func_mktempdir_umask
      fi

      # If we're not in dry-run mode, bomb out on failure
      test -d "$_G_tmpdir" || \
        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
    fi

    $ECHO "$_G_tmpdir"
}


# func_normal_abspath PATH
# ------------------------
# Remove doubled-up and trailing slashes, "." path components,
# and cancel out any ".." path components in PATH after making
# it an absolute path.
func_normal_abspath ()
{
    $debug_cmd

    # These SED scripts presuppose an absolute path with a trailing slash.
    _G_pathcar='s|^/\([^/]*\).*$|\1|'
    _G_pathcdr='s|^/[^/]*||'
    _G_removedotparts=':dotsl
		s|/\./|/|g
		t dotsl
		s|/\.$|/|'
    _G_collapseslashes='s|/\{1,\}|/|g'
    _G_finalslash='s|/*$|/|'

    # Start from root dir and reassemble the path.
    func_normal_abspath_result=
    func_normal_abspath_tpath=$1
    func_normal_abspath_altnamespace=
    case $func_normal_abspath_tpath in
      "")
        # Empty path, that just means $cwd.
        func_stripname '' '/' "`pwd`"
        func_normal_abspath_result=$func_stripname_result
        return
        ;;
      # The next three entries are used to spot a run of precisely
      # two leading slashes without using negated character classes;
      # we take advantage of case's first-match behaviour.
      ///*)
        # Unusual form of absolute path, do nothing.
        ;;
      //*)
        # Not necessarily an ordinary path; POSIX reserves leading '//'
        # and for example Cygwin uses it to access remote file shares
        # over CIFS/SMB, so we conserve a leading double slash if found.
        func_normal_abspath_altnamespace=/
        ;;
      /*)
        # Absolute path, do nothing.
        ;;
      *)
        # Relative path, prepend $cwd.
        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
        ;;
    esac

    # Cancel out all the simple stuff to save iterations.  We also want
    # the path to end with a slash for ease of parsing, so make sure
    # there is one (and only one) here.
    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
    while :; do
      # Processed it all yet?
      if test / = "$func_normal_abspath_tpath"; then
        # If we ascended to the root using ".." the result may be empty now.
        if test -z "$func_normal_abspath_result"; then
          func_normal_abspath_result=/
        fi
        break
      fi
      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
          -e "$_G_pathcar"`
      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
          -e "$_G_pathcdr"`
      # Figure out what to do with it
      case $func_normal_abspath_tcomponent in
        "")
          # Trailing empty path component, ignore it.
          ;;
        ..)
          # Parent dir; strip last assembled component from result.
          func_dirname "$func_normal_abspath_result"
          func_normal_abspath_result=$func_dirname_result
          ;;
        *)
          # Actual path component, append it.
          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
          ;;
      esac
    done
    # Restore leading double-slash if one was found on entry.
    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
}


# func_notquiet ARG...
# --------------------
# Echo program name prefixed message only when not in quiet mode.
func_notquiet ()
{
    $debug_cmd

    $opt_quiet || func_echo ${1+"$@"}

    # A bug in bash halts the script if the last line of a function
    # fails when set -e is in force, so we need another command to
    # work around that:
    :
}


# func_relative_path SRCDIR DSTDIR
# --------------------------------
# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
func_relative_path ()
{
    $debug_cmd

    func_relative_path_result=
    func_normal_abspath "$1"
    func_relative_path_tlibdir=$func_normal_abspath_result
    func_normal_abspath "$2"
    func_relative_path_tbindir=$func_normal_abspath_result

    # Ascend the tree starting from libdir
    while :; do
      # check if we have found a prefix of bindir
      case $func_relative_path_tbindir in
        $func_relative_path_tlibdir)
          # found an exact match
          func_relative_path_tcancelled=
          break
          ;;
        $func_relative_path_tlibdir*)
          # found a matching prefix
          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
          func_relative_path_tcancelled=$func_stripname_result
          if test -z "$func_relative_path_result"; then
            func_relative_path_result=.
          fi
          break
          ;;
        *)
          func_dirname $func_relative_path_tlibdir
          func_relative_path_tlibdir=$func_dirname_result
          if test -z "$func_relative_path_tlibdir"; then
            # Have to descend all the way to the root!
            func_relative_path_result=../$func_relative_path_result
            func_relative_path_tcancelled=$func_relative_path_tbindir
            break
          fi
          func_relative_path_result=../$func_relative_path_result
          ;;
      esac
    done

    # Now calculate path; take care to avoid doubling-up slashes.
    func_stripname '' '/' "$func_relative_path_result"
    func_relative_path_result=$func_stripname_result
    func_stripname '/' '/' "$func_relative_path_tcancelled"
    if test -n "$func_stripname_result"; then
      func_append func_relative_path_result "/$func_stripname_result"
    fi

    # Normalisation. If bindir is libdir, return '.' else relative path.
    if test -n "$func_relative_path_result"; then
      func_stripname './' '' "$func_relative_path_result"
      func_relative_path_result=$func_stripname_result
    fi

    test -n "$func_relative_path_result" || func_relative_path_result=.

    :
}


# func_quote_for_eval ARG...
# --------------------------
# Aesthetically quote ARGs to be evaled later.
# This function returns two values:
#   i) func_quote_for_eval_result
#      double-quoted, suitable for a subsequent eval
#  ii) func_quote_for_eval_unquoted_result
#      has all characters that are still active within double
#      quotes backslashified.
func_quote_for_eval ()
{
    $debug_cmd

    func_quote_for_eval_unquoted_result=
    func_quote_for_eval_result=
    while test 0 -lt $#; do
      case $1 in
        *[\\\`\"\$]*)
	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
        *)
          _G_unquoted_arg=$1 ;;
      esac
      if test -n "$func_quote_for_eval_unquoted_result"; then
	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
      else
        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
      fi

      case $_G_unquoted_arg in
        # Double-quote args containing shell metacharacters to delay
        # word splitting, command substitution and variable expansion
        # for a subsequent eval.
        # Many Bourne shells cannot handle close brackets correctly
        # in scan sets, so we specify it separately.
        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
          _G_quoted_arg=\"$_G_unquoted_arg\"
          ;;
        *)
          _G_quoted_arg=$_G_unquoted_arg
	  ;;
      esac

      if test -n "$func_quote_for_eval_result"; then
	func_append func_quote_for_eval_result " $_G_quoted_arg"
      else
        func_append func_quote_for_eval_result "$_G_quoted_arg"
      fi
      shift
    done
}


# func_quote_for_expand ARG
# -------------------------
# Aesthetically quote ARG to be evaled later; same as above,
# but do not quote variable references.
func_quote_for_expand ()
{
    $debug_cmd

    case $1 in
      *[\\\`\"]*)
	_G_arg=`$ECHO "$1" | $SED \
	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
      *)
        _G_arg=$1 ;;
    esac

    case $_G_arg in
      # Double-quote args containing shell metacharacters to delay
      # word splitting and command substitution for a subsequent eval.
      # Many Bourne shells cannot handle close brackets correctly
      # in scan sets, so we specify it separately.
      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
        _G_arg=\"$_G_arg\"
        ;;
    esac

    func_quote_for_expand_result=$_G_arg
}


# func_stripname PREFIX SUFFIX NAME
# ---------------------------------
# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
# PREFIX and SUFFIX must not contain globbing or regex special
# characters, hashes, percent signs, but SUFFIX may contain a leading
# dot (in which case that matches only a dot).
if test yes = "$_G_HAVE_XSI_OPS"; then
  eval 'func_stripname ()
  {
    $debug_cmd

    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
    # positional parameters, so assign one to ordinary variable first.
    func_stripname_result=$3
    func_stripname_result=${func_stripname_result#"$1"}
    func_stripname_result=${func_stripname_result%"$2"}
  }'
else
  func_stripname ()
  {
    $debug_cmd

    case $2 in
      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
    esac
  }
fi


# func_show_eval CMD [FAIL_EXP]
# -----------------------------
# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
# is given, then evaluate it.
func_show_eval ()
{
    $debug_cmd

    _G_cmd=$1
    _G_fail_exp=${2-':'}

    func_quote_for_expand "$_G_cmd"
    eval "func_notquiet $func_quote_for_expand_result"

    $opt_dry_run || {
      eval "$_G_cmd"
      _G_status=$?
      if test 0 -ne "$_G_status"; then
	eval "(exit $_G_status); $_G_fail_exp"
      fi
    }
}


# func_show_eval_locale CMD [FAIL_EXP]
# ------------------------------------
# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
# is given, then evaluate it.  Use the saved locale for evaluation.
func_show_eval_locale ()
{
    $debug_cmd

    _G_cmd=$1
    _G_fail_exp=${2-':'}

    $opt_quiet || {
      func_quote_for_expand "$_G_cmd"
      eval "func_echo $func_quote_for_expand_result"
    }

    $opt_dry_run || {
      eval "$_G_user_locale
	    $_G_cmd"
      _G_status=$?
      eval "$_G_safe_locale"
      if test 0 -ne "$_G_status"; then
	eval "(exit $_G_status); $_G_fail_exp"
      fi
    }
}


# func_tr_sh
# ----------
# Turn $1 into a string suitable for a shell variable name.
# Result is stored in $func_tr_sh_result.  All characters
# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
# if $1 begins with a digit, a '_' is prepended as well.
func_tr_sh ()
{
    $debug_cmd

    case $1 in
    [0-9]* | *[!a-zA-Z0-9_]*)
      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
      ;;
    * )
      func_tr_sh_result=$1
      ;;
    esac
}


# func_verbose ARG...
# -------------------
# Echo program name prefixed message in verbose mode only.
func_verbose ()
{
    $debug_cmd

    $opt_verbose && func_echo "$*"

    :
}


# func_warn_and_continue ARG...
# -----------------------------
# Echo program name prefixed warning message to standard error.
func_warn_and_continue ()
{
    $debug_cmd

    $require_term_colors

    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
}


# func_warning CATEGORY ARG...
# ----------------------------
# Echo program name prefixed warning message to standard error. Warning
# messages can be filtered according to CATEGORY, where this function
# elides messages where CATEGORY is not listed in the global variable
# 'opt_warning_types'.
func_warning ()
{
    $debug_cmd

    # CATEGORY must be in the warning_categories list!
    case " $warning_categories " in
      *" $1 "*) ;;
      *) func_internal_error "invalid warning category '$1'" ;;
    esac

    _G_category=$1
    shift

    case " $opt_warning_types " in
      *" $_G_category "*) $warning_func ${1+"$@"} ;;
    esac
}


# func_sort_ver VER1 VER2
# -----------------------
# 'sort -V' is not generally available.
# Note this deviates from the version comparison in automake
# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
# but this should suffice as we won't be specifying old
# version formats or redundant trailing .0 in bootstrap.conf.
# If we did want full compatibility then we should probably
# use m4_version_compare from autoconf.
func_sort_ver ()
{
    $debug_cmd

    printf '%s\n%s\n' "$1" "$2" \
      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
}

# func_lt_ver PREV CURR
# ---------------------
# Return true if PREV and CURR are in the correct order according to
# func_sort_ver, otherwise false.  Use it like this:
#
#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
func_lt_ver ()
{
    $debug_cmd

    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
}


# Local variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
# time-stamp-time-zone: "UTC"
# End:
#! /bin/sh

# Set a version string for this script.
scriptversion=2015-10-07.11; # UTC

# A portable, pluggable option parser for Bourne shell.
# Written by Gary V. Vaughan, 2010

# Copyright (C) 2010-2015 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.  There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .

# Please report bugs or propose patches to gary@gnu.org.


## ------ ##
## Usage. ##
## ------ ##

# This file is a library for parsing options in your shell scripts along
# with assorted other useful supporting features that you can make use
# of too.
#
# For the simplest scripts you might need only:
#
#   #!/bin/sh
#   . relative/path/to/funclib.sh
#   . relative/path/to/options-parser
#   scriptversion=1.0
#   func_options ${1+"$@"}
#   eval set dummy "$func_options_result"; shift
#   ...rest of your script...
#
# In order for the '--version' option to work, you will need to have a
# suitably formatted comment like the one at the top of this file
# starting with '# Written by ' and ending with '# warranty; '.
#
# For '-h' and '--help' to work, you will also need a one line
# description of your script's purpose in a comment directly above the
# '# Written by ' line, like the one at the top of this file.
#
# The default options also support '--debug', which will turn on shell
# execution tracing (see the comment above debug_cmd below for another
# use), and '--verbose' and the func_verbose function to allow your script
# to display verbose messages only when your user has specified
# '--verbose'.
#
# After sourcing this file, you can plug processing for additional
# options by amending the variables from the 'Configuration' section
# below, and following the instructions in the 'Option parsing'
# section further down.

## -------------- ##
## Configuration. ##
## -------------- ##

# You should override these variables in your script after sourcing this
# file so that they reflect the customisations you have added to the
# option parser.

# The usage line for option parsing errors and the start of '-h' and
# '--help' output messages. You can embed shell variables for delayed
# expansion at the time the message is displayed, but you will need to
# quote other shell meta-characters carefully to prevent them being
# expanded when the contents are evaled.
usage='$progpath [OPTION]...'

# Short help message in response to '-h' and '--help'.  Add to this or
# override it after sourcing this library to reflect the full set of
# options your script accepts.
usage_message="\
       --debug        enable verbose shell tracing
   -W, --warnings=CATEGORY
                      report the warnings falling in CATEGORY [all]
   -v, --verbose      verbosely report processing
       --version      print version information and exit
   -h, --help         print short or long help message and exit
"

# Additional text appended to 'usage_message' in response to '--help'.
long_help_message="
Warning categories include:
       'all'          show all warnings
       'none'         turn off all the warnings
       'error'        warnings are treated as fatal errors"

# Help message printed before fatal option parsing errors.
fatal_help="Try '\$progname --help' for more information."



## ------------------------- ##
## Hook function management. ##
## ------------------------- ##

# This section contains functions for adding, removing, and running hooks
# to the main code.  A hook is just a named list of of function, that can
# be run in order later on.

# func_hookable FUNC_NAME
# -----------------------
# Declare that FUNC_NAME will run hooks added with
# 'func_add_hook FUNC_NAME ...'.
func_hookable ()
{
    $debug_cmd

    func_append hookable_fns " $1"
}


# func_add_hook FUNC_NAME HOOK_FUNC
# ---------------------------------
# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
# first have been declared "hookable" by a call to 'func_hookable'.
func_add_hook ()
{
    $debug_cmd

    case " $hookable_fns " in
      *" $1 "*) ;;
      *) func_fatal_error "'$1' does not accept hook functions." ;;
    esac

    eval func_append ${1}_hooks '" $2"'
}


# func_remove_hook FUNC_NAME HOOK_FUNC
# ------------------------------------
# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
func_remove_hook ()
{
    $debug_cmd

    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
}


# func_run_hooks FUNC_NAME [ARG]...
# ---------------------------------
# Run all hook functions registered to FUNC_NAME.
# It is assumed that the list of hook functions contains nothing more
# than a whitespace-delimited list of legal shell function names, and
# no effort is wasted trying to catch shell meta-characters or preserve
# whitespace.
func_run_hooks ()
{
    $debug_cmd

    _G_rc_run_hooks=false

    case " $hookable_fns " in
      *" $1 "*) ;;
      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
    esac

    eval _G_hook_fns=\$$1_hooks; shift

    for _G_hook in $_G_hook_fns; do
      if eval $_G_hook '"$@"'; then
        # store returned options list back into positional
        # parameters for next 'cmd' execution.
        eval _G_hook_result=\$${_G_hook}_result
        eval set dummy "$_G_hook_result"; shift
        _G_rc_run_hooks=:
      fi
    done

    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
}



## --------------- ##
## Option parsing. ##
## --------------- ##

# In order to add your own option parsing hooks, you must accept the
# full positional parameter list in your hook function, you may remove/edit
# any options that you action, and then pass back the remaining unprocessed
# options in '_result', escaped suitably for
# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
# hook's caller know that it should pay attention to
# '_result'.  Returning $EXIT_FAILURE signalizes that
# arguments are left untouched by the hook and therefore caller will ignore the
# result variable.
#
# Like this:
#
#    my_options_prep ()
#    {
#        $debug_cmd
#
#        # Extend the existing usage message.
#        usage_message=$usage_message'
#      -s, --silent       don'\''t print informational messages
#    '
#        # No change in '$@' (ignored completely by this hook).  There is
#        # no need to do the equivalent (but slower) action:
#        # func_quote_for_eval ${1+"$@"}
#        # my_options_prep_result=$func_quote_for_eval_result
#        false
#    }
#    func_add_hook func_options_prep my_options_prep
#
#
#    my_silent_option ()
#    {
#        $debug_cmd
#
#        args_changed=false
#
#        # Note that for efficiency, we parse as many options as we can
#        # recognise in a loop before passing the remainder back to the
#        # caller on the first unrecognised argument we encounter.
#        while test $# -gt 0; do
#          opt=$1; shift
#          case $opt in
#            --silent|-s) opt_silent=:
#                         args_changed=:
#                         ;;
#            # Separate non-argument short options:
#            -s*)         func_split_short_opt "$_G_opt"
#                         set dummy "$func_split_short_opt_name" \
#                             "-$func_split_short_opt_arg" ${1+"$@"}
#                         shift
#                         args_changed=:
#                         ;;
#            *)           # Make sure the first unrecognised option "$_G_opt"
#                         # is added back to "$@", we could need that later
#                         # if $args_changed is true.
#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
#          esac
#        done
#
#        if $args_changed; then
#          func_quote_for_eval ${1+"$@"}
#          my_silent_option_result=$func_quote_for_eval_result
#        fi
#
#        $args_changed
#    }
#    func_add_hook func_parse_options my_silent_option
#
#
#    my_option_validation ()
#    {
#        $debug_cmd
#
#        $opt_silent && $opt_verbose && func_fatal_help "\
#    '--silent' and '--verbose' options are mutually exclusive."
#
#        false
#    }
#    func_add_hook func_validate_options my_option_validation
#
# You'll also need to manually amend $usage_message to reflect the extra
# options you parse.  It's preferable to append if you can, so that
# multiple option parsing hooks can be added safely.


# func_options_finish [ARG]...
# ----------------------------
# Finishing the option parse loop (call 'func_options' hooks ATM).
func_options_finish ()
{
    $debug_cmd

    _G_func_options_finish_exit=false
    if func_run_hooks func_options ${1+"$@"}; then
      func_options_finish_result=$func_run_hooks_result
      _G_func_options_finish_exit=:
    fi

    $_G_func_options_finish_exit
}


# func_options [ARG]...
# ---------------------
# All the functions called inside func_options are hookable. See the
# individual implementations for details.
func_hookable func_options
func_options ()
{
    $debug_cmd

    _G_rc_options=false

    for my_func in options_prep parse_options validate_options options_finish
    do
      if eval func_$my_func '${1+"$@"}'; then
        eval _G_res_var='$'"func_${my_func}_result"
        eval set dummy "$_G_res_var" ; shift
        _G_rc_options=:
      fi
    done

    # Save modified positional parameters for caller.  As a top-level
    # options-parser function we always need to set the 'func_options_result'
    # variable (regardless the $_G_rc_options value).
    if $_G_rc_options; then
      func_options_result=$_G_res_var
    else
      func_quote_for_eval ${1+"$@"}
      func_options_result=$func_quote_for_eval_result
    fi

    $_G_rc_options
}


# func_options_prep [ARG]...
# --------------------------
# All initialisations required before starting the option parse loop.
# Note that when calling hook functions, we pass through the list of
# positional parameters.  If a hook function modifies that list, and
# needs to propagate that back to rest of this script, then the complete
# modified list must be put in 'func_run_hooks_result' before
# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
func_hookable func_options_prep
func_options_prep ()
{
    $debug_cmd

    # Option defaults:
    opt_verbose=false
    opt_warning_types=

    _G_rc_options_prep=false
    if func_run_hooks func_options_prep ${1+"$@"}; then
      _G_rc_options_prep=:
      # save modified positional parameters for caller
      func_options_prep_result=$func_run_hooks_result
    fi

    $_G_rc_options_prep
}


# func_parse_options [ARG]...
# ---------------------------
# The main option parsing loop.
func_hookable func_parse_options
func_parse_options ()
{
    $debug_cmd

    func_parse_options_result=

    _G_rc_parse_options=false
    # this just eases exit handling
    while test $# -gt 0; do
      # Defer to hook functions for initial option parsing, so they
      # get priority in the event of reusing an option name.
      if func_run_hooks func_parse_options ${1+"$@"}; then
        eval set dummy "$func_run_hooks_result"; shift
        _G_rc_parse_options=:
      fi

      # Break out of the loop if we already parsed every option.
      test $# -gt 0 || break

      _G_match_parse_options=:
      _G_opt=$1
      shift
      case $_G_opt in
        --debug|-x)   debug_cmd='set -x'
                      func_echo "enabling shell trace mode"
                      $debug_cmd
                      ;;

        --no-warnings|--no-warning|--no-warn)
                      set dummy --warnings none ${1+"$@"}
                      shift
		      ;;

        --warnings|--warning|-W)
                      if test $# = 0 && func_missing_arg $_G_opt; then
                        _G_rc_parse_options=:
                        break
                      fi
                      case " $warning_categories $1" in
                        *" $1 "*)
                          # trailing space prevents matching last $1 above
                          func_append_uniq opt_warning_types " $1"
                          ;;
                        *all)
                          opt_warning_types=$warning_categories
                          ;;
                        *none)
                          opt_warning_types=none
                          warning_func=:
                          ;;
                        *error)
                          opt_warning_types=$warning_categories
                          warning_func=func_fatal_error
                          ;;
                        *)
                          func_fatal_error \
                             "unsupported warning category: '$1'"
                          ;;
                      esac
                      shift
                      ;;

        --verbose|-v) opt_verbose=: ;;
        --version)    func_version ;;
        -\?|-h)       func_usage ;;
        --help)       func_help ;;

	# Separate optargs to long options (plugins may need this):
	--*=*)        func_split_equals "$_G_opt"
	              set dummy "$func_split_equals_lhs" \
                          "$func_split_equals_rhs" ${1+"$@"}
                      shift
                      ;;

       # Separate optargs to short options:
        -W*)
                      func_split_short_opt "$_G_opt"
                      set dummy "$func_split_short_opt_name" \
                          "$func_split_short_opt_arg" ${1+"$@"}
                      shift
                      ;;

        # Separate non-argument short options:
        -\?*|-h*|-v*|-x*)
                      func_split_short_opt "$_G_opt"
                      set dummy "$func_split_short_opt_name" \
                          "-$func_split_short_opt_arg" ${1+"$@"}
                      shift
                      ;;

        --)           _G_rc_parse_options=: ; break ;;
        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
        *)            set dummy "$_G_opt" ${1+"$@"}; shift
                      _G_match_parse_options=false
                      break
                      ;;
      esac

      $_G_match_parse_options && _G_rc_parse_options=:
    done


    if $_G_rc_parse_options; then
      # save modified positional parameters for caller
      func_quote_for_eval ${1+"$@"}
      func_parse_options_result=$func_quote_for_eval_result
    fi

    $_G_rc_parse_options
}


# func_validate_options [ARG]...
# ------------------------------
# Perform any sanity checks on option settings and/or unconsumed
# arguments.
func_hookable func_validate_options
func_validate_options ()
{
    $debug_cmd

    _G_rc_validate_options=false

    # Display all warnings if -W was not given.
    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"

    if func_run_hooks func_validate_options ${1+"$@"}; then
      # save modified positional parameters for caller
      func_validate_options_result=$func_run_hooks_result
      _G_rc_validate_options=:
    fi

    # Bail if the options were screwed!
    $exit_cmd $EXIT_FAILURE

    $_G_rc_validate_options
}



## ----------------- ##
## Helper functions. ##
## ----------------- ##

# This section contains the helper functions used by the rest of the
# hookable option parser framework in ascii-betical order.


# func_fatal_help ARG...
# ----------------------
# Echo program name prefixed message to standard error, followed by
# a help hint, and exit.
func_fatal_help ()
{
    $debug_cmd

    eval \$ECHO \""Usage: $usage"\"
    eval \$ECHO \""$fatal_help"\"
    func_error ${1+"$@"}
    exit $EXIT_FAILURE
}


# func_help
# ---------
# Echo long help message to standard output and exit.
func_help ()
{
    $debug_cmd

    func_usage_message
    $ECHO "$long_help_message"
    exit 0
}


# func_missing_arg ARGNAME
# ------------------------
# Echo program name prefixed message to standard error and set global
# exit_cmd.
func_missing_arg ()
{
    $debug_cmd

    func_error "Missing argument for '$1'."
    exit_cmd=exit
}


# func_split_equals STRING
# ------------------------
# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
# splitting STRING at the '=' sign.
test -z "$_G_HAVE_XSI_OPS" \
    && (eval 'x=a/b/c;
      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
    && _G_HAVE_XSI_OPS=yes

if test yes = "$_G_HAVE_XSI_OPS"
then
  # This is an XSI compatible shell, allowing a faster implementation...
  eval 'func_split_equals ()
  {
      $debug_cmd

      func_split_equals_lhs=${1%%=*}
      func_split_equals_rhs=${1#*=}
      test "x$func_split_equals_lhs" = "x$1" \
        && func_split_equals_rhs=
  }'
else
  # ...otherwise fall back to using expr, which is often a shell builtin.
  func_split_equals ()
  {
      $debug_cmd

      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
      func_split_equals_rhs=
      test "x$func_split_equals_lhs" = "x$1" \
        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
  }
fi #func_split_equals


# func_split_short_opt SHORTOPT
# -----------------------------
# Set func_split_short_opt_name and func_split_short_opt_arg shell
# variables after splitting SHORTOPT after the 2nd character.
if test yes = "$_G_HAVE_XSI_OPS"
then
  # This is an XSI compatible shell, allowing a faster implementation...
  eval 'func_split_short_opt ()
  {
      $debug_cmd

      func_split_short_opt_arg=${1#??}
      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
  }'
else
  # ...otherwise fall back to using expr, which is often a shell builtin.
  func_split_short_opt ()
  {
      $debug_cmd

      func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
  }
fi #func_split_short_opt


# func_usage
# ----------
# Echo short help message to standard output and exit.
func_usage ()
{
    $debug_cmd

    func_usage_message
    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
    exit 0
}


# func_usage_message
# ------------------
# Echo short help message to standard output.
func_usage_message ()
{
    $debug_cmd

    eval \$ECHO \""Usage: $usage"\"
    echo
    $SED -n 's|^# ||
        /^Written by/{
          x;p;x
        }
	h
	/^Written by/q' < "$progpath"
    echo
    eval \$ECHO \""$usage_message"\"
}


# func_version
# ------------
# Echo version message to standard output and exit.
func_version ()
{
    $debug_cmd

    printf '%s\n' "$progname $scriptversion"
    $SED -n '
        /(C)/!b go
        :more
        /\./!{
          N
          s|\n# | |
          b more
        }
        :go
        /^# Written by /,/# warranty; / {
          s|^# ||
          s|^# *$||
          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
          p
        }
        /^# Written by / {
          s|^# ||
          p
        }
        /^warranty; /q' < "$progpath"

    exit $?
}


# Local variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
# time-stamp-time-zone: "UTC"
# End:

# Set a version string.
scriptversion='(GNU libtool) 2.4.6'


# func_echo ARG...
# ----------------
# Libtool also displays the current mode in messages, so override
# funclib.sh func_echo with this custom definition.
func_echo ()
{
    $debug_cmd

    _G_message=$*

    func_echo_IFS=$IFS
    IFS=$nl
    for _G_line in $_G_message; do
      IFS=$func_echo_IFS
      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
    done
    IFS=$func_echo_IFS
}


# func_warning ARG...
# -------------------
# Libtool warnings are not categorized, so override funclib.sh
# func_warning with this simpler definition.
func_warning ()
{
    $debug_cmd

    $warning_func ${1+"$@"}
}


## ---------------- ##
## Options parsing. ##
## ---------------- ##

# Hook in the functions to make sure our own options are parsed during
# the option parsing loop.

usage='$progpath [OPTION]... [MODE-ARG]...'

# Short help message in response to '-h'.
usage_message="Options:
       --config             show all configuration variables
       --debug              enable verbose shell tracing
   -n, --dry-run            display commands without modifying any files
       --features           display basic configuration information and exit
       --mode=MODE          use operation mode MODE
       --no-warnings        equivalent to '-Wnone'
       --preserve-dup-deps  don't remove duplicate dependency libraries
       --quiet, --silent    don't print informational messages
       --tag=TAG            use configuration variables from tag TAG
   -v, --verbose            print more informational messages than default
       --version            print version information
   -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
   -h, --help, --help-all   print short, long, or detailed help message
"

# Additional text appended to 'usage_message' in response to '--help'.
func_help ()
{
    $debug_cmd

    func_usage_message
    $ECHO "$long_help_message

MODE must be one of the following:

       clean           remove files from the build directory
       compile         compile a source file into a libtool object
       execute         automatically set library path, then run a program
       finish          complete the installation of libtool libraries
       install         install libraries or executables
       link            create a library or an executable
       uninstall       remove libraries from an installed directory

MODE-ARGS vary depending on the MODE.  When passed as first option,
'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
Try '$progname --help --mode=MODE' for a more detailed description of MODE.

When reporting a bug, please describe a test case to reproduce it and
include the following information:

       host-triplet:   $host
       shell:          $SHELL
       compiler:       $LTCC
       compiler flags: $LTCFLAGS
       linker:         $LD (gnu? $with_gnu_ld)
       version:        $progname $scriptversion Debian-2.4.6-15build2
       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`

Report bugs to .
GNU libtool home page: .
General help using GNU software: ."
    exit 0
}


# func_lo2o OBJECT-NAME
# ---------------------
# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
# object suffix.

lo2o=s/\\.lo\$/.$objext/
o2lo=s/\\.$objext\$/.lo/

if test yes = "$_G_HAVE_XSI_OPS"; then
  eval 'func_lo2o ()
  {
    case $1 in
      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
      *   ) func_lo2o_result=$1               ;;
    esac
  }'

  # func_xform LIBOBJ-OR-SOURCE
  # ---------------------------
  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
  # suffix to a '.lo' libtool-object suffix.
  eval 'func_xform ()
  {
    func_xform_result=${1%.*}.lo
  }'
else
  # ...otherwise fall back to using sed.
  func_lo2o ()
  {
    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
  }

  func_xform ()
  {
    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
  }
fi


# func_fatal_configuration ARG...
# -------------------------------
# Echo program name prefixed message to standard error, followed by
# a configuration failure hint, and exit.
func_fatal_configuration ()
{
    func__fatal_error ${1+"$@"} \
      "See the $PACKAGE documentation for more information." \
      "Fatal configuration error."
}


# func_config
# -----------
# Display the configuration for all the tags in this script.
func_config ()
{
    re_begincf='^# ### BEGIN LIBTOOL'
    re_endcf='^# ### END LIBTOOL'

    # Default configuration.
    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"

    # Now print the configurations for the tags.
    for tagname in $taglist; do
      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
    done

    exit $?
}


# func_features
# -------------
# Display the features supported by this script.
func_features ()
{
    echo "host: $host"
    if test yes = "$build_libtool_libs"; then
      echo "enable shared libraries"
    else
      echo "disable shared libraries"
    fi
    if test yes = "$build_old_libs"; then
      echo "enable static libraries"
    else
      echo "disable static libraries"
    fi

    exit $?
}


# func_enable_tag TAGNAME
# -----------------------
# Verify that TAGNAME is valid, and either flag an error and exit, or
# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
# variable here.
func_enable_tag ()
{
    # Global variable:
    tagname=$1

    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
    sed_extractcf=/$re_begincf/,/$re_endcf/p

    # Validate tagname.
    case $tagname in
      *[!-_A-Za-z0-9,/]*)
        func_fatal_error "invalid tag name: $tagname"
        ;;
    esac

    # Don't test for the "default" C tag, as we know it's
    # there but not specially marked.
    case $tagname in
        CC) ;;
    *)
        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
	  taglist="$taglist $tagname"

	  # Evaluate the configuration.  Be careful to quote the path
	  # and the sed script, to avoid splitting on whitespace, but
	  # also don't use non-portable quotes within backquotes within
	  # quotes we have to do it in 2 steps:
	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
	  eval "$extractedcf"
        else
	  func_error "ignoring unknown tag $tagname"
        fi
        ;;
    esac
}


# func_check_version_match
# ------------------------
# Ensure that we are using m4 macros, and libtool script from the same
# release of libtool.
func_check_version_match ()
{
    if test "$package_revision" != "$macro_revision"; then
      if test "$VERSION" != "$macro_version"; then
        if test -z "$macro_version"; then
          cat >&2 <<_LT_EOF
$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
$progname: definition of this LT_INIT comes from an older release.
$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
$progname: and run autoconf again.
_LT_EOF
        else
          cat >&2 <<_LT_EOF
$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
$progname: and run autoconf again.
_LT_EOF
        fi
      else
        cat >&2 <<_LT_EOF
$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
$progname: but the definition of this LT_INIT comes from revision $macro_revision.
$progname: You should recreate aclocal.m4 with macros from revision $package_revision
$progname: of $PACKAGE $VERSION and run autoconf again.
_LT_EOF
      fi

      exit $EXIT_MISMATCH
    fi
}


# libtool_options_prep [ARG]...
# -----------------------------
# Preparation for options parsed by libtool.
libtool_options_prep ()
{
    $debug_mode

    # Option defaults:
    opt_config=false
    opt_dlopen=
    opt_dry_run=false
    opt_help=false
    opt_mode=
    opt_preserve_dup_deps=false
    opt_quiet=false

    nonopt=
    preserve_args=

    _G_rc_lt_options_prep=:

    # Shorthand for --mode=foo, only valid as the first argument
    case $1 in
    clean|clea|cle|cl)
      shift; set dummy --mode clean ${1+"$@"}; shift
      ;;
    compile|compil|compi|comp|com|co|c)
      shift; set dummy --mode compile ${1+"$@"}; shift
      ;;
    execute|execut|execu|exec|exe|ex|e)
      shift; set dummy --mode execute ${1+"$@"}; shift
      ;;
    finish|finis|fini|fin|fi|f)
      shift; set dummy --mode finish ${1+"$@"}; shift
      ;;
    install|instal|insta|inst|ins|in|i)
      shift; set dummy --mode install ${1+"$@"}; shift
      ;;
    link|lin|li|l)
      shift; set dummy --mode link ${1+"$@"}; shift
      ;;
    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
      shift; set dummy --mode uninstall ${1+"$@"}; shift
      ;;
    *)
      _G_rc_lt_options_prep=false
      ;;
    esac

    if $_G_rc_lt_options_prep; then
      # Pass back the list of options.
      func_quote_for_eval ${1+"$@"}
      libtool_options_prep_result=$func_quote_for_eval_result
    fi

    $_G_rc_lt_options_prep
}
func_add_hook func_options_prep libtool_options_prep


# libtool_parse_options [ARG]...
# ---------------------------------
# Provide handling for libtool specific options.
libtool_parse_options ()
{
    $debug_cmd

    _G_rc_lt_parse_options=false

    # Perform our own loop to consume as many options as possible in
    # each iteration.
    while test $# -gt 0; do
      _G_match_lt_parse_options=:
      _G_opt=$1
      shift
      case $_G_opt in
        --dry-run|--dryrun|-n)
                        opt_dry_run=:
                        ;;

        --config)       func_config ;;

        --dlopen|-dlopen)
                        opt_dlopen="${opt_dlopen+$opt_dlopen
}$1"
                        shift
                        ;;

        --preserve-dup-deps)
                        opt_preserve_dup_deps=: ;;

        --features)     func_features ;;

        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;

        --help)         opt_help=: ;;

        --help-all)     opt_help=': help-all' ;;

        --mode)         test $# = 0 && func_missing_arg $_G_opt && break
                        opt_mode=$1
                        case $1 in
                          # Valid mode arguments:
                          clean|compile|execute|finish|install|link|relink|uninstall) ;;

                          # Catch anything else as an error
                          *) func_error "invalid argument for $_G_opt"
                             exit_cmd=exit
                             break
                             ;;
                        esac
                        shift
                        ;;

        --no-silent|--no-quiet)
                        opt_quiet=false
                        func_append preserve_args " $_G_opt"
                        ;;

        --no-warnings|--no-warning|--no-warn)
                        opt_warning=false
                        func_append preserve_args " $_G_opt"
                        ;;

        --no-verbose)
                        opt_verbose=false
                        func_append preserve_args " $_G_opt"
                        ;;

        --silent|--quiet)
                        opt_quiet=:
                        opt_verbose=false
                        func_append preserve_args " $_G_opt"
                        ;;

        --tag)          test $# = 0 && func_missing_arg $_G_opt && break
                        opt_tag=$1
                        func_append preserve_args " $_G_opt $1"
                        func_enable_tag "$1"
                        shift
                        ;;

        --verbose|-v)   opt_quiet=false
                        opt_verbose=:
                        func_append preserve_args " $_G_opt"
                        ;;

        # An option not handled by this hook function:
        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
                        _G_match_lt_parse_options=false
                        break
                        ;;
      esac
      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
    done

    if $_G_rc_lt_parse_options; then
      # save modified positional parameters for caller
      func_quote_for_eval ${1+"$@"}
      libtool_parse_options_result=$func_quote_for_eval_result
    fi

    $_G_rc_lt_parse_options
}
func_add_hook func_parse_options libtool_parse_options



# libtool_validate_options [ARG]...
# ---------------------------------
# Perform any sanity checks on option settings and/or unconsumed
# arguments.
libtool_validate_options ()
{
    # save first non-option argument
    if test 0 -lt $#; then
      nonopt=$1
      shift
    fi

    # preserve --debug
    test : = "$debug_cmd" || func_append preserve_args " --debug"

    case $host in
      # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
      # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
        # don't eliminate duplications in $postdeps and $predeps
        opt_duplicate_compiler_generated_deps=:
        ;;
      *)
        opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
        ;;
    esac

    $opt_help || {
      # Sanity checks first:
      func_check_version_match

      test yes != "$build_libtool_libs" \
        && test yes != "$build_old_libs" \
        && func_fatal_configuration "not configured to build any kind of library"

      # Darwin sucks
      eval std_shrext=\"$shrext_cmds\"

      # Only execute mode is allowed to have -dlopen flags.
      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
        func_error "unrecognized option '-dlopen'"
        $ECHO "$help" 1>&2
        exit $EXIT_FAILURE
      fi

      # Change the help message to a mode-specific one.
      generic_help=$help
      help="Try '$progname --help --mode=$opt_mode' for more information."
    }

    # Pass back the unparsed argument list
    func_quote_for_eval ${1+"$@"}
    libtool_validate_options_result=$func_quote_for_eval_result
}
func_add_hook func_validate_options libtool_validate_options


# Process options as early as possible so that --help and --version
# can return quickly.
func_options ${1+"$@"}
eval set dummy "$func_options_result"; shift



## ----------- ##
##    Main.    ##
## ----------- ##

magic='%%%MAGIC variable%%%'
magic_exe='%%%MAGIC EXE variable%%%'

# Global variables.
extracted_archives=
extracted_serial=0

# If this variable is set in any of the actions, the command in it
# will be execed at the end.  This prevents here-documents from being
# left over by shells.
exec_cmd=


# A function that is used when there is no print builtin or printf.
func_fallback_echo ()
{
  eval 'cat <<_LTECHO_EOF
$1
_LTECHO_EOF'
}

# func_generated_by_libtool
# True iff stdin has been generated by Libtool. This function is only
# a basic sanity check; it will hardly flush out determined imposters.
func_generated_by_libtool_p ()
{
  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
}

# func_lalib_p file
# True iff FILE is a libtool '.la' library or '.lo' object file.
# This function is only a basic sanity check; it will hardly flush out
# determined imposters.
func_lalib_p ()
{
    test -f "$1" &&
      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
}

# func_lalib_unsafe_p file
# True iff FILE is a libtool '.la' library or '.lo' object file.
# This function implements the same check as func_lalib_p without
# resorting to external programs.  To this end, it redirects stdin and
# closes it afterwards, without saving the original file descriptor.
# As a safety measure, use it only where a negative result would be
# fatal anyway.  Works if 'file' does not exist.
func_lalib_unsafe_p ()
{
    lalib_p=no
    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
	for lalib_p_l in 1 2 3 4
	do
	    read lalib_p_line
	    case $lalib_p_line in
		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
	    esac
	done
	exec 0<&5 5<&-
    fi
    test yes = "$lalib_p"
}

# func_ltwrapper_script_p file
# True iff FILE is a libtool wrapper script
# This function is only a basic sanity check; it will hardly flush out
# determined imposters.
func_ltwrapper_script_p ()
{
    test -f "$1" &&
      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
}

# func_ltwrapper_executable_p file
# True iff FILE is a libtool wrapper executable
# This function is only a basic sanity check; it will hardly flush out
# determined imposters.
func_ltwrapper_executable_p ()
{
    func_ltwrapper_exec_suffix=
    case $1 in
    *.exe) ;;
    *) func_ltwrapper_exec_suffix=.exe ;;
    esac
    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
}

# func_ltwrapper_scriptname file
# Assumes file is an ltwrapper_executable
# uses $file to determine the appropriate filename for a
# temporary ltwrapper_script.
func_ltwrapper_scriptname ()
{
    func_dirname_and_basename "$1" "" "."
    func_stripname '' '.exe' "$func_basename_result"
    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
}

# func_ltwrapper_p file
# True iff FILE is a libtool wrapper script or wrapper executable
# This function is only a basic sanity check; it will hardly flush out
# determined imposters.
func_ltwrapper_p ()
{
    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
}


# func_execute_cmds commands fail_cmd
# Execute tilde-delimited COMMANDS.
# If FAIL_CMD is given, eval that upon failure.
# FAIL_CMD may read-access the current command in variable CMD!
func_execute_cmds ()
{
    $debug_cmd

    save_ifs=$IFS; IFS='~'
    for cmd in $1; do
      IFS=$sp$nl
      eval cmd=\"$cmd\"
      IFS=$save_ifs
      func_show_eval "$cmd" "${2-:}"
    done
    IFS=$save_ifs
}


# func_source file
# Source FILE, adding directory component if necessary.
# Note that it is not necessary on cygwin/mingw to append a dot to
# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
# behavior happens only for exec(3), not for open(2)!  Also, sourcing
# 'FILE.' does not work on cygwin managed mounts.
func_source ()
{
    $debug_cmd

    case $1 in
    */* | *\\*)	. "$1" ;;
    *)		. "./$1" ;;
    esac
}


# func_resolve_sysroot PATH
# Replace a leading = in PATH with a sysroot.  Store the result into
# func_resolve_sysroot_result
func_resolve_sysroot ()
{
  func_resolve_sysroot_result=$1
  case $func_resolve_sysroot_result in
  =*)
    func_stripname '=' '' "$func_resolve_sysroot_result"
    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
    ;;
  esac
}

# func_replace_sysroot PATH
# If PATH begins with the sysroot, replace it with = and
# store the result into func_replace_sysroot_result.
func_replace_sysroot ()
{
  case $lt_sysroot:$1 in
  ?*:"$lt_sysroot"*)
    func_stripname "$lt_sysroot" '' "$1"
    func_replace_sysroot_result='='$func_stripname_result
    ;;
  *)
    # Including no sysroot.
    func_replace_sysroot_result=$1
    ;;
  esac
}

# func_infer_tag arg
# Infer tagged configuration to use if any are available and
# if one wasn't chosen via the "--tag" command line option.
# Only attempt this if the compiler in the base compile
# command doesn't match the default compiler.
# arg is usually of the form 'gcc ...'
func_infer_tag ()
{
    $debug_cmd

    if test -n "$available_tags" && test -z "$tagname"; then
      CC_quoted=
      for arg in $CC; do
	func_append_quoted CC_quoted "$arg"
      done
      CC_expanded=`func_echo_all $CC`
      CC_quoted_expanded=`func_echo_all $CC_quoted`
      case $@ in
      # Blanks in the command may have been stripped by the calling shell,
      # but not from the CC environment variable when configure was run.
      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
      # Blanks at the start of $base_compile will cause this to fail
      # if we don't check for them as well.
      *)
	for z in $available_tags; do
	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
	    # Evaluate the configuration.
	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
	    CC_quoted=
	    for arg in $CC; do
	      # Double-quote args containing other shell metacharacters.
	      func_append_quoted CC_quoted "$arg"
	    done
	    CC_expanded=`func_echo_all $CC`
	    CC_quoted_expanded=`func_echo_all $CC_quoted`
	    case "$@ " in
	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
	      # The compiler in the base compile command matches
	      # the one in the tagged configuration.
	      # Assume this is the tagged configuration we want.
	      tagname=$z
	      break
	      ;;
	    esac
	  fi
	done
	# If $tagname still isn't set, then no tagged configuration
	# was found and let the user know that the "--tag" command
	# line option must be used.
	if test -z "$tagname"; then
	  func_echo "unable to infer tagged configuration"
	  func_fatal_error "specify a tag with '--tag'"
#	else
#	  func_verbose "using $tagname tagged configuration"
	fi
	;;
      esac
    fi
}



# func_write_libtool_object output_name pic_name nonpic_name
# Create a libtool object file (analogous to a ".la" file),
# but don't create it if we're doing a dry run.
func_write_libtool_object ()
{
    write_libobj=$1
    if test yes = "$build_libtool_libs"; then
      write_lobj=\'$2\'
    else
      write_lobj=none
    fi

    if test yes = "$build_old_libs"; then
      write_oldobj=\'$3\'
    else
      write_oldobj=none
    fi

    $opt_dry_run || {
      cat >${write_libobj}T </dev/null`
    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
        $SED -e "$sed_naive_backslashify"`
    else
      func_convert_core_file_wine_to_w32_result=
    fi
  fi
}
# end: func_convert_core_file_wine_to_w32


# func_convert_core_path_wine_to_w32 ARG
# Helper function used by path conversion functions when $build is *nix, and
# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
# configured wine environment available, with the winepath program in $build's
# $PATH. Assumes ARG has no leading or trailing path separator characters.
#
# ARG is path to be converted from $build format to win32.
# Result is available in $func_convert_core_path_wine_to_w32_result.
# Unconvertible file (directory) names in ARG are skipped; if no directory names
# are convertible, then the result may be empty.
func_convert_core_path_wine_to_w32 ()
{
  $debug_cmd

  # unfortunately, winepath doesn't convert paths, only file names
  func_convert_core_path_wine_to_w32_result=
  if test -n "$1"; then
    oldIFS=$IFS
    IFS=:
    for func_convert_core_path_wine_to_w32_f in $1; do
      IFS=$oldIFS
      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
      if test -n "$func_convert_core_file_wine_to_w32_result"; then
        if test -z "$func_convert_core_path_wine_to_w32_result"; then
          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
        else
          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
        fi
      fi
    done
    IFS=$oldIFS
  fi
}
# end: func_convert_core_path_wine_to_w32


# func_cygpath ARGS...
# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
# (2), returns the Cygwin file name or path in func_cygpath_result (input
# file name or path is assumed to be in w32 format, as previously converted
# from $build's *nix or MSYS format). In case (3), returns the w32 file name
# or path in func_cygpath_result (input file name or path is assumed to be in
# Cygwin format). Returns an empty string on error.
#
# ARGS are passed to cygpath, with the last one being the file name or path to
# be converted.
#
# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
# environment variable; do not put it in $PATH.
func_cygpath ()
{
  $debug_cmd

  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
    if test "$?" -ne 0; then
      # on failure, ensure result is empty
      func_cygpath_result=
    fi
  else
    func_cygpath_result=
    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
  fi
}
#end: func_cygpath


# func_convert_core_msys_to_w32 ARG
# Convert file name or path ARG from MSYS format to w32 format.  Return
# result in func_convert_core_msys_to_w32_result.
func_convert_core_msys_to_w32 ()
{
  $debug_cmd

  # awkward: cmd appends spaces to result
  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
}
#end: func_convert_core_msys_to_w32


# func_convert_file_check ARG1 ARG2
# Verify that ARG1 (a file name in $build format) was converted to $host
# format in ARG2. Otherwise, emit an error message, but continue (resetting
# func_to_host_file_result to ARG1).
func_convert_file_check ()
{
  $debug_cmd

  if test -z "$2" && test -n "$1"; then
    func_error "Could not determine host file name corresponding to"
    func_error "  '$1'"
    func_error "Continuing, but uninstalled executables may not work."
    # Fallback:
    func_to_host_file_result=$1
  fi
}
# end func_convert_file_check


# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
# Verify that FROM_PATH (a path in $build format) was converted to $host
# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
# func_to_host_file_result to a simplistic fallback value (see below).
func_convert_path_check ()
{
  $debug_cmd

  if test -z "$4" && test -n "$3"; then
    func_error "Could not determine the host path corresponding to"
    func_error "  '$3'"
    func_error "Continuing, but uninstalled executables may not work."
    # Fallback.  This is a deliberately simplistic "conversion" and
    # should not be "improved".  See libtool.info.
    if test "x$1" != "x$2"; then
      lt_replace_pathsep_chars="s|$1|$2|g"
      func_to_host_path_result=`echo "$3" |
        $SED -e "$lt_replace_pathsep_chars"`
    else
      func_to_host_path_result=$3
    fi
  fi
}
# end func_convert_path_check


# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
# and appending REPL if ORIG matches BACKPAT.
func_convert_path_front_back_pathsep ()
{
  $debug_cmd

  case $4 in
  $1 ) func_to_host_path_result=$3$func_to_host_path_result
    ;;
  esac
  case $4 in
  $2 ) func_append func_to_host_path_result "$3"
    ;;
  esac
}
# end func_convert_path_front_back_pathsep


##################################################
# $build to $host FILE NAME CONVERSION FUNCTIONS #
##################################################
# invoked via '$to_host_file_cmd ARG'
#
# In each case, ARG is the path to be converted from $build to $host format.
# Result will be available in $func_to_host_file_result.


# func_to_host_file ARG
# Converts the file name ARG from $build format to $host format. Return result
# in func_to_host_file_result.
func_to_host_file ()
{
  $debug_cmd

  $to_host_file_cmd "$1"
}
# end func_to_host_file


# func_to_tool_file ARG LAZY
# converts the file name ARG from $build format to toolchain format. Return
# result in func_to_tool_file_result.  If the conversion in use is listed
# in (the comma separated) LAZY, no conversion takes place.
func_to_tool_file ()
{
  $debug_cmd

  case ,$2, in
    *,"$to_tool_file_cmd",*)
      func_to_tool_file_result=$1
      ;;
    *)
      $to_tool_file_cmd "$1"
      func_to_tool_file_result=$func_to_host_file_result
      ;;
  esac
}
# end func_to_tool_file


# func_convert_file_noop ARG
# Copy ARG to func_to_host_file_result.
func_convert_file_noop ()
{
  func_to_host_file_result=$1
}
# end func_convert_file_noop


# func_convert_file_msys_to_w32 ARG
# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
# conversion to w32 is not available inside the cwrapper.  Returns result in
# func_to_host_file_result.
func_convert_file_msys_to_w32 ()
{
  $debug_cmd

  func_to_host_file_result=$1
  if test -n "$1"; then
    func_convert_core_msys_to_w32 "$1"
    func_to_host_file_result=$func_convert_core_msys_to_w32_result
  fi
  func_convert_file_check "$1" "$func_to_host_file_result"
}
# end func_convert_file_msys_to_w32


# func_convert_file_cygwin_to_w32 ARG
# Convert file name ARG from Cygwin to w32 format.  Returns result in
# func_to_host_file_result.
func_convert_file_cygwin_to_w32 ()
{
  $debug_cmd

  func_to_host_file_result=$1
  if test -n "$1"; then
    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
    # LT_CYGPATH in this case.
    func_to_host_file_result=`cygpath -m "$1"`
  fi
  func_convert_file_check "$1" "$func_to_host_file_result"
}
# end func_convert_file_cygwin_to_w32


# func_convert_file_nix_to_w32 ARG
# Convert file name ARG from *nix to w32 format.  Requires a wine environment
# and a working winepath. Returns result in func_to_host_file_result.
func_convert_file_nix_to_w32 ()
{
  $debug_cmd

  func_to_host_file_result=$1
  if test -n "$1"; then
    func_convert_core_file_wine_to_w32 "$1"
    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
  fi
  func_convert_file_check "$1" "$func_to_host_file_result"
}
# end func_convert_file_nix_to_w32


# func_convert_file_msys_to_cygwin ARG
# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
# Returns result in func_to_host_file_result.
func_convert_file_msys_to_cygwin ()
{
  $debug_cmd

  func_to_host_file_result=$1
  if test -n "$1"; then
    func_convert_core_msys_to_w32 "$1"
    func_cygpath -u "$func_convert_core_msys_to_w32_result"
    func_to_host_file_result=$func_cygpath_result
  fi
  func_convert_file_check "$1" "$func_to_host_file_result"
}
# end func_convert_file_msys_to_cygwin


# func_convert_file_nix_to_cygwin ARG
# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
# in func_to_host_file_result.
func_convert_file_nix_to_cygwin ()
{
  $debug_cmd

  func_to_host_file_result=$1
  if test -n "$1"; then
    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
    func_convert_core_file_wine_to_w32 "$1"
    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
    func_to_host_file_result=$func_cygpath_result
  fi
  func_convert_file_check "$1" "$func_to_host_file_result"
}
# end func_convert_file_nix_to_cygwin


#############################################
# $build to $host PATH CONVERSION FUNCTIONS #
#############################################
# invoked via '$to_host_path_cmd ARG'
#
# In each case, ARG is the path to be converted from $build to $host format.
# The result will be available in $func_to_host_path_result.
#
# Path separators are also converted from $build format to $host format.  If
# ARG begins or ends with a path separator character, it is preserved (but
# converted to $host format) on output.
#
# All path conversion functions are named using the following convention:
#   file name conversion function    : func_convert_file_X_to_Y ()
#   path conversion function         : func_convert_path_X_to_Y ()
# where, for any given $build/$host combination the 'X_to_Y' value is the
# same.  If conversion functions are added for new $build/$host combinations,
# the two new functions must follow this pattern, or func_init_to_host_path_cmd
# will break.


# func_init_to_host_path_cmd
# Ensures that function "pointer" variable $to_host_path_cmd is set to the
# appropriate value, based on the value of $to_host_file_cmd.
to_host_path_cmd=
func_init_to_host_path_cmd ()
{
  $debug_cmd

  if test -z "$to_host_path_cmd"; then
    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
    to_host_path_cmd=func_convert_path_$func_stripname_result
  fi
}


# func_to_host_path ARG
# Converts the path ARG from $build format to $host format. Return result
# in func_to_host_path_result.
func_to_host_path ()
{
  $debug_cmd

  func_init_to_host_path_cmd
  $to_host_path_cmd "$1"
}
# end func_to_host_path


# func_convert_path_noop ARG
# Copy ARG to func_to_host_path_result.
func_convert_path_noop ()
{
  func_to_host_path_result=$1
}
# end func_convert_path_noop


# func_convert_path_msys_to_w32 ARG
# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
# conversion to w32 is not available inside the cwrapper.  Returns result in
# func_to_host_path_result.
func_convert_path_msys_to_w32 ()
{
  $debug_cmd

  func_to_host_path_result=$1
  if test -n "$1"; then
    # Remove leading and trailing path separator characters from ARG.  MSYS
    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
    # and winepath ignores them completely.
    func_stripname : : "$1"
    func_to_host_path_tmp1=$func_stripname_result
    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
    func_to_host_path_result=$func_convert_core_msys_to_w32_result
    func_convert_path_check : ";" \
      "$func_to_host_path_tmp1" "$func_to_host_path_result"
    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
  fi
}
# end func_convert_path_msys_to_w32


# func_convert_path_cygwin_to_w32 ARG
# Convert path ARG from Cygwin to w32 format.  Returns result in
# func_to_host_file_result.
func_convert_path_cygwin_to_w32 ()
{
  $debug_cmd

  func_to_host_path_result=$1
  if test -n "$1"; then
    # See func_convert_path_msys_to_w32:
    func_stripname : : "$1"
    func_to_host_path_tmp1=$func_stripname_result
    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
    func_convert_path_check : ";" \
      "$func_to_host_path_tmp1" "$func_to_host_path_result"
    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
  fi
}
# end func_convert_path_cygwin_to_w32


# func_convert_path_nix_to_w32 ARG
# Convert path ARG from *nix to w32 format.  Requires a wine environment and
# a working winepath.  Returns result in func_to_host_file_result.
func_convert_path_nix_to_w32 ()
{
  $debug_cmd

  func_to_host_path_result=$1
  if test -n "$1"; then
    # See func_convert_path_msys_to_w32:
    func_stripname : : "$1"
    func_to_host_path_tmp1=$func_stripname_result
    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
    func_convert_path_check : ";" \
      "$func_to_host_path_tmp1" "$func_to_host_path_result"
    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
  fi
}
# end func_convert_path_nix_to_w32


# func_convert_path_msys_to_cygwin ARG
# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
# Returns result in func_to_host_file_result.
func_convert_path_msys_to_cygwin ()
{
  $debug_cmd

  func_to_host_path_result=$1
  if test -n "$1"; then
    # See func_convert_path_msys_to_w32:
    func_stripname : : "$1"
    func_to_host_path_tmp1=$func_stripname_result
    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
    func_to_host_path_result=$func_cygpath_result
    func_convert_path_check : : \
      "$func_to_host_path_tmp1" "$func_to_host_path_result"
    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
  fi
}
# end func_convert_path_msys_to_cygwin


# func_convert_path_nix_to_cygwin ARG
# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
# func_to_host_file_result.
func_convert_path_nix_to_cygwin ()
{
  $debug_cmd

  func_to_host_path_result=$1
  if test -n "$1"; then
    # Remove leading and trailing path separator characters from
    # ARG. msys behavior is inconsistent here, cygpath turns them
    # into '.;' and ';.', and winepath ignores them completely.
    func_stripname : : "$1"
    func_to_host_path_tmp1=$func_stripname_result
    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
    func_to_host_path_result=$func_cygpath_result
    func_convert_path_check : : \
      "$func_to_host_path_tmp1" "$func_to_host_path_result"
    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
  fi
}
# end func_convert_path_nix_to_cygwin


# func_dll_def_p FILE
# True iff FILE is a Windows DLL '.def' file.
# Keep in sync with _LT_DLL_DEF_P in libtool.m4
func_dll_def_p ()
{
  $debug_cmd

  func_dll_def_p_tmp=`$SED -n \
    -e 's/^[	 ]*//' \
    -e '/^\(;.*\)*$/d' \
    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
    -e q \
    "$1"`
  test DEF = "$func_dll_def_p_tmp"
}


# func_mode_compile arg...
func_mode_compile ()
{
    $debug_cmd

    # Get the compilation command and the source file.
    base_compile=
    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
    suppress_opt=yes
    suppress_output=
    arg_mode=normal
    libobj=
    later=
    pie_flag=

    for arg
    do
      case $arg_mode in
      arg  )
	# do not "continue".  Instead, add this to base_compile
	lastarg=$arg
	arg_mode=normal
	;;

      target )
	libobj=$arg
	arg_mode=normal
	continue
	;;

      normal )
	# Accept any command-line options.
	case $arg in
	-o)
	  test -n "$libobj" && \
	    func_fatal_error "you cannot specify '-o' more than once"
	  arg_mode=target
	  continue
	  ;;

	-pie | -fpie | -fPIE)
          func_append pie_flag " $arg"
	  continue
	  ;;

	-shared | -static | -prefer-pic | -prefer-non-pic)
	  func_append later " $arg"
	  continue
	  ;;

	-no-suppress)
	  suppress_opt=no
	  continue
	  ;;

	-Xcompiler)
	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
	  continue      #  The current "srcfile" will either be retained or
	  ;;            #  replaced later.  I would guess that would be a bug.

	-Wc,*)
	  func_stripname '-Wc,' '' "$arg"
	  args=$func_stripname_result
	  lastarg=
	  save_ifs=$IFS; IFS=,
	  for arg in $args; do
	    IFS=$save_ifs
	    func_append_quoted lastarg "$arg"
	  done
	  IFS=$save_ifs
	  func_stripname ' ' '' "$lastarg"
	  lastarg=$func_stripname_result

	  # Add the arguments to base_compile.
	  func_append base_compile " $lastarg"
	  continue
	  ;;

	*)
	  # Accept the current argument as the source file.
	  # The previous "srcfile" becomes the current argument.
	  #
	  lastarg=$srcfile
	  srcfile=$arg
	  ;;
	esac  #  case $arg
	;;
      esac    #  case $arg_mode

      # Aesthetically quote the previous argument.
      func_append_quoted base_compile "$lastarg"
    done # for arg

    case $arg_mode in
    arg)
      func_fatal_error "you must specify an argument for -Xcompile"
      ;;
    target)
      func_fatal_error "you must specify a target with '-o'"
      ;;
    *)
      # Get the name of the library object.
      test -z "$libobj" && {
	func_basename "$srcfile"
	libobj=$func_basename_result
      }
      ;;
    esac

    # Recognize several different file suffixes.
    # If the user specifies -o file.o, it is replaced with file.lo
    case $libobj in
    *.[cCFSifmso] | \
    *.ada | *.adb | *.ads | *.asm | \
    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
      func_xform "$libobj"
      libobj=$func_xform_result
      ;;
    esac

    case $libobj in
    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
    *)
      func_fatal_error "cannot determine name of library object from '$libobj'"
      ;;
    esac

    func_infer_tag $base_compile

    for arg in $later; do
      case $arg in
      -shared)
	test yes = "$build_libtool_libs" \
	  || func_fatal_configuration "cannot build a shared library"
	build_old_libs=no
	continue
	;;

      -static)
	build_libtool_libs=no
	build_old_libs=yes
	continue
	;;

      -prefer-pic)
	pic_mode=yes
	continue
	;;

      -prefer-non-pic)
	pic_mode=no
	continue
	;;
      esac
    done

    func_quote_for_eval "$libobj"
    test "X$libobj" != "X$func_quote_for_eval_result" \
      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
      && func_warning "libobj name '$libobj' may not contain shell special characters."
    func_dirname_and_basename "$obj" "/" ""
    objname=$func_basename_result
    xdir=$func_dirname_result
    lobj=$xdir$objdir/$objname

    test -z "$base_compile" && \
      func_fatal_help "you must specify a compilation command"

    # Delete any leftover library objects.
    if test yes = "$build_old_libs"; then
      removelist="$obj $lobj $libobj ${libobj}T"
    else
      removelist="$lobj $libobj ${libobj}T"
    fi

    # On Cygwin there's no "real" PIC flag so we must build both object types
    case $host_os in
    cygwin* | mingw* | pw32* | os2* | cegcc*)
      pic_mode=default
      ;;
    esac
    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
      # non-PIC code in shared libraries is not supported
      pic_mode=default
    fi

    # Calculate the filename of the output object if compiler does
    # not support -o with -c
    if test no = "$compiler_c_o"; then
      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
      lockfile=$output_obj.lock
    else
      output_obj=
      need_locks=no
      lockfile=
    fi

    # Lock this critical section if it is needed
    # We use this script file to make the link, it avoids creating a new file
    if test yes = "$need_locks"; then
      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
	func_echo "Waiting for $lockfile to be removed"
	sleep 2
      done
    elif test warn = "$need_locks"; then
      if test -f "$lockfile"; then
	$ECHO "\
*** ERROR, $lockfile exists and contains:
`cat $lockfile 2>/dev/null`

This indicates that another process is trying to use the same
temporary object file, and libtool could not work around it because
your compiler does not support '-c' and '-o' together.  If you
repeat this compilation, it may succeed, by chance, but you had better
avoid parallel builds (make -j) in this platform, or get a better
compiler."

	$opt_dry_run || $RM $removelist
	exit $EXIT_FAILURE
      fi
      func_append removelist " $output_obj"
      $ECHO "$srcfile" > "$lockfile"
    fi

    $opt_dry_run || $RM $removelist
    func_append removelist " $lockfile"
    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15

    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
    srcfile=$func_to_tool_file_result
    func_quote_for_eval "$srcfile"
    qsrcfile=$func_quote_for_eval_result

    # Only build a PIC object if we are building libtool libraries.
    if test yes = "$build_libtool_libs"; then
      # Without this assignment, base_compile gets emptied.
      fbsd_hideous_sh_bug=$base_compile

      if test no != "$pic_mode"; then
	command="$base_compile $qsrcfile $pic_flag"
      else
	# Don't build PIC code
	command="$base_compile $qsrcfile"
      fi

      func_mkdir_p "$xdir$objdir"

      if test -z "$output_obj"; then
	# Place PIC objects in $objdir
	func_append command " -o $lobj"
      fi

      func_show_eval_locale "$command"	\
          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'

      if test warn = "$need_locks" &&
	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
	$ECHO "\
*** ERROR, $lockfile contains:
`cat $lockfile 2>/dev/null`

but it should contain:
$srcfile

This indicates that another process is trying to use the same
temporary object file, and libtool could not work around it because
your compiler does not support '-c' and '-o' together.  If you
repeat this compilation, it may succeed, by chance, but you had better
avoid parallel builds (make -j) in this platform, or get a better
compiler."

	$opt_dry_run || $RM $removelist
	exit $EXIT_FAILURE
      fi

      # Just move the object if needed, then go on to compile the next one
      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
	func_show_eval '$MV "$output_obj" "$lobj"' \
	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
      fi

      # Allow error messages only from the first compilation.
      if test yes = "$suppress_opt"; then
	suppress_output=' >/dev/null 2>&1'
      fi
    fi

    # Only build a position-dependent object if we build old libraries.
    if test yes = "$build_old_libs"; then
      if test yes != "$pic_mode"; then
	# Don't build PIC code
	command="$base_compile $qsrcfile$pie_flag"
      else
	command="$base_compile $qsrcfile $pic_flag"
      fi
      if test yes = "$compiler_c_o"; then
	func_append command " -o $obj"
      fi

      # Suppress compiler output if we already did a PIC compilation.
      func_append command "$suppress_output"
      func_show_eval_locale "$command" \
        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'

      if test warn = "$need_locks" &&
	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
	$ECHO "\
*** ERROR, $lockfile contains:
`cat $lockfile 2>/dev/null`

but it should contain:
$srcfile

This indicates that another process is trying to use the same
temporary object file, and libtool could not work around it because
your compiler does not support '-c' and '-o' together.  If you
repeat this compilation, it may succeed, by chance, but you had better
avoid parallel builds (make -j) in this platform, or get a better
compiler."

	$opt_dry_run || $RM $removelist
	exit $EXIT_FAILURE
      fi

      # Just move the object if needed
      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
	func_show_eval '$MV "$output_obj" "$obj"' \
	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
      fi
    fi

    $opt_dry_run || {
      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"

      # Unlock the critical section if it was locked
      if test no != "$need_locks"; then
	removelist=$lockfile
        $RM "$lockfile"
      fi
    }

    exit $EXIT_SUCCESS
}

$opt_help || {
  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
}

func_mode_help ()
{
    # We need to display help for each of the modes.
    case $opt_mode in
      "")
        # Generic help is extracted from the usage comments
        # at the start of this file.
        func_help
        ;;

      clean)
        $ECHO \
"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...

Remove files from the build directory.

RM is the name of the program to use to delete files associated with each FILE
(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
to RM.

If FILE is a libtool library, object or program, all the files associated
with it are deleted. Otherwise, only FILE itself is deleted using RM."
        ;;

      compile)
      $ECHO \
"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE

Compile a source file into a libtool library object.

This mode accepts the following additional options:

  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
  -no-suppress      do not suppress compiler output for multiple passes
  -prefer-pic       try to build PIC objects only
  -prefer-non-pic   try to build non-PIC objects only
  -shared           do not build a '.o' file suitable for static linking
  -static           only build a '.o' file suitable for static linking
  -Wc,FLAG          pass FLAG directly to the compiler

COMPILE-COMMAND is a command to be used in creating a 'standard' object file
from the given SOURCEFILE.

The output file name is determined by removing the directory component from
SOURCEFILE, then substituting the C source code suffix '.c' with the
library object suffix, '.lo'."
        ;;

      execute)
        $ECHO \
"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...

Automatically set library path, then run a program.

This mode accepts the following additional options:

  -dlopen FILE      add the directory containing FILE to the library path

This mode sets the library path environment variable according to '-dlopen'
flags.

If any of the ARGS are libtool executable wrappers, then they are translated
into their corresponding uninstalled binary, and any of their required library
directories are added to the library path.

Then, COMMAND is executed, with ARGS as arguments."
        ;;

      finish)
        $ECHO \
"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...

Complete the installation of libtool libraries.

Each LIBDIR is a directory that contains libtool libraries.

The commands that this mode executes may require superuser privileges.  Use
the '--dry-run' option if you just want to see what would be executed."
        ;;

      install)
        $ECHO \
"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...

Install executables or libraries.

INSTALL-COMMAND is the installation command.  The first component should be
either the 'install' or 'cp' program.

The following components of INSTALL-COMMAND are treated specially:

  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation

The rest of the components are interpreted as arguments to that command (only
BSD-compatible install options are recognized)."
        ;;

      link)
        $ECHO \
"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...

Link object files or libraries together to form another library, or to
create an executable program.

LINK-COMMAND is a command using the C compiler that you would use to create
a program from several object files.

The following components of LINK-COMMAND are treated specially:

  -all-static       do not do any dynamic linking at all
  -avoid-version    do not add a version suffix if possible
  -bindir BINDIR    specify path to binaries directory (for systems where
                    libraries must be found in the PATH setting at runtime)
  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
  -export-symbols SYMFILE
                    try to export only the symbols listed in SYMFILE
  -export-symbols-regex REGEX
                    try to export only the symbols matching REGEX
  -LLIBDIR          search LIBDIR for required installed libraries
  -lNAME            OUTPUT-FILE requires the installed library libNAME
  -module           build a library that can dlopened
  -no-fast-install  disable the fast-install mode
  -no-install       link a not-installable executable
  -no-undefined     declare that a library does not refer to external symbols
  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
  -objectlist FILE  use a list of object files found in FILE to specify objects
  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
  -precious-files-regex REGEX
                    don't remove output files matching REGEX
  -release RELEASE  specify package release information
  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
  -shared           only do dynamic linking of libtool libraries
  -shrext SUFFIX    override the standard shared library file extension
  -static           do not do any dynamic linking of uninstalled libtool libraries
  -static-libtool-libs
                    do not do any dynamic linking of libtool libraries
  -version-info CURRENT[:REVISION[:AGE]]
                    specify library version info [each variable defaults to 0]
  -weak LIBNAME     declare that the target provides the LIBNAME interface
  -Wc,FLAG
  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
  -Wl,FLAG
  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)

All other options (arguments beginning with '-') are ignored.

Every other argument is treated as a filename.  Files ending in '.la' are
treated as uninstalled libtool libraries, other files are standard or library
object files.

If the OUTPUT-FILE ends in '.la', then a libtool library is created,
only library objects ('.lo' files) may be specified, and '-rpath' is
required, except when creating a convenience library.

If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
using 'ar' and 'ranlib', or on Windows using 'lib'.

If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
is created, otherwise an executable program is created."
        ;;

      uninstall)
        $ECHO \
"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...

Remove libraries from an installation directory.

RM is the name of the program to use to delete files associated with each FILE
(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
to RM.

If FILE is a libtool library, all the files associated with it are deleted.
Otherwise, only FILE itself is deleted using RM."
        ;;

      *)
        func_fatal_help "invalid operation mode '$opt_mode'"
        ;;
    esac

    echo
    $ECHO "Try '$progname --help' for more information about other modes."
}

# Now that we've collected a possible --mode arg, show help if necessary
if $opt_help; then
  if test : = "$opt_help"; then
    func_mode_help
  else
    {
      func_help noexit
      for opt_mode in compile link execute install finish uninstall clean; do
	func_mode_help
      done
    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
    {
      func_help noexit
      for opt_mode in compile link execute install finish uninstall clean; do
	echo
	func_mode_help
      done
    } |
    $SED '1d
      /^When reporting/,/^Report/{
	H
	d
      }
      $x
      /information about other modes/d
      /more detailed .*MODE/d
      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
  fi
  exit $?
fi


# func_mode_execute arg...
func_mode_execute ()
{
    $debug_cmd

    # The first argument is the command name.
    cmd=$nonopt
    test -z "$cmd" && \
      func_fatal_help "you must specify a COMMAND"

    # Handle -dlopen flags immediately.
    for file in $opt_dlopen; do
      test -f "$file" \
	|| func_fatal_help "'$file' is not a file"

      dir=
      case $file in
      *.la)
	func_resolve_sysroot "$file"
	file=$func_resolve_sysroot_result

	# Check to see that this really is a libtool archive.
	func_lalib_unsafe_p "$file" \
	  || func_fatal_help "'$lib' is not a valid libtool archive"

	# Read the libtool library.
	dlname=
	library_names=
	func_source "$file"

	# Skip this library if it cannot be dlopened.
	if test -z "$dlname"; then
	  # Warn if it was a shared library.
	  test -n "$library_names" && \
	    func_warning "'$file' was not linked with '-export-dynamic'"
	  continue
	fi

	func_dirname "$file" "" "."
	dir=$func_dirname_result

	if test -f "$dir/$objdir/$dlname"; then
	  func_append dir "/$objdir"
	else
	  if test ! -f "$dir/$dlname"; then
	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
	  fi
	fi
	;;

      *.lo)
	# Just add the directory containing the .lo file.
	func_dirname "$file" "" "."
	dir=$func_dirname_result
	;;

      *)
	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
	continue
	;;
      esac

      # Get the absolute pathname.
      absdir=`cd "$dir" && pwd`
      test -n "$absdir" && dir=$absdir

      # Now add the directory to shlibpath_var.
      if eval "test -z \"\$$shlibpath_var\""; then
	eval "$shlibpath_var=\"\$dir\""
      else
	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
      fi
    done

    # This variable tells wrapper scripts just to set shlibpath_var
    # rather than running their programs.
    libtool_execute_magic=$magic

    # Check if any of the arguments is a wrapper script.
    args=
    for file
    do
      case $file in
      -* | *.la | *.lo ) ;;
      *)
	# Do a test to see if this is really a libtool program.
	if func_ltwrapper_script_p "$file"; then
	  func_source "$file"
	  # Transform arg to wrapped name.
	  file=$progdir/$program
	elif func_ltwrapper_executable_p "$file"; then
	  func_ltwrapper_scriptname "$file"
	  func_source "$func_ltwrapper_scriptname_result"
	  # Transform arg to wrapped name.
	  file=$progdir/$program
	fi
	;;
      esac
      # Quote arguments (to preserve shell metacharacters).
      func_append_quoted args "$file"
    done

    if $opt_dry_run; then
      # Display what would be done.
      if test -n "$shlibpath_var"; then
	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
	echo "export $shlibpath_var"
      fi
      $ECHO "$cmd$args"
      exit $EXIT_SUCCESS
    else
      if test -n "$shlibpath_var"; then
	# Export the shlibpath_var.
	eval "export $shlibpath_var"
      fi

      # Restore saved environment variables
      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
      do
	eval "if test \"\${save_$lt_var+set}\" = set; then
                $lt_var=\$save_$lt_var; export $lt_var
	      else
		$lt_unset $lt_var
	      fi"
      done

      # Now prepare to actually exec the command.
      exec_cmd=\$cmd$args
    fi
}

test execute = "$opt_mode" && func_mode_execute ${1+"$@"}


# func_mode_finish arg...
func_mode_finish ()
{
    $debug_cmd

    libs=
    libdirs=
    admincmds=

    for opt in "$nonopt" ${1+"$@"}
    do
      if test -d "$opt"; then
	func_append libdirs " $opt"

      elif test -f "$opt"; then
	if func_lalib_unsafe_p "$opt"; then
	  func_append libs " $opt"
	else
	  func_warning "'$opt' is not a valid libtool archive"
	fi

      else
	func_fatal_error "invalid argument '$opt'"
      fi
    done

    if test -n "$libs"; then
      if test -n "$lt_sysroot"; then
        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
      else
        sysroot_cmd=
      fi

      # Remove sysroot references
      if $opt_dry_run; then
        for lib in $libs; do
          echo "removing references to $lt_sysroot and '=' prefixes from $lib"
        done
      else
        tmpdir=`func_mktempdir`
        for lib in $libs; do
	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
	    > $tmpdir/tmp-la
	  mv -f $tmpdir/tmp-la $lib
	done
        ${RM}r "$tmpdir"
      fi
    fi

    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
      for libdir in $libdirs; do
	if test -n "$finish_cmds"; then
	  # Do each command in the finish commands.
	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
'"$cmd"'"'
	fi
	if test -n "$finish_eval"; then
	  # Do the single finish_eval.
	  eval cmds=\"$finish_eval\"
	  $opt_dry_run || eval "$cmds" || func_append admincmds "
       $cmds"
	fi
      done
    fi

    # Exit here if they wanted silent mode.
    $opt_quiet && exit $EXIT_SUCCESS

    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
      echo "----------------------------------------------------------------------"
      echo "Libraries have been installed in:"
      for libdir in $libdirs; do
	$ECHO "   $libdir"
      done
      echo
      echo "If you ever happen to want to link against installed libraries"
      echo "in a given directory, LIBDIR, you must either use libtool, and"
      echo "specify the full pathname of the library, or use the '-LLIBDIR'"
      echo "flag during linking and do at least one of the following:"
      if test -n "$shlibpath_var"; then
	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
	echo "     during execution"
      fi
      if test -n "$runpath_var"; then
	echo "   - add LIBDIR to the '$runpath_var' environment variable"
	echo "     during linking"
      fi
      if test -n "$hardcode_libdir_flag_spec"; then
	libdir=LIBDIR
	eval flag=\"$hardcode_libdir_flag_spec\"

	$ECHO "   - use the '$flag' linker flag"
      fi
      if test -n "$admincmds"; then
	$ECHO "   - have your system administrator run these commands:$admincmds"
      fi
      if test -f /etc/ld.so.conf; then
	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
      fi
      echo

      echo "See any operating system documentation about shared libraries for"
      case $host in
	solaris2.[6789]|solaris2.1[0-9])
	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
	  echo "pages."
	  ;;
	*)
	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
	  ;;
      esac
      echo "----------------------------------------------------------------------"
    fi
    exit $EXIT_SUCCESS
}

test finish = "$opt_mode" && func_mode_finish ${1+"$@"}


# func_mode_install arg...
func_mode_install ()
{
    $debug_cmd

    # There may be an optional sh(1) argument at the beginning of
    # install_prog (especially on Windows NT).
    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
       # Allow the use of GNU shtool's install command.
       case $nonopt in *shtool*) :;; *) false;; esac
    then
      # Aesthetically quote it.
      func_quote_for_eval "$nonopt"
      install_prog="$func_quote_for_eval_result "
      arg=$1
      shift
    else
      install_prog=
      arg=$nonopt
    fi

    # The real first argument should be the name of the installation program.
    # Aesthetically quote it.
    func_quote_for_eval "$arg"
    func_append install_prog "$func_quote_for_eval_result"
    install_shared_prog=$install_prog
    case " $install_prog " in
      *[\\\ /]cp\ *) install_cp=: ;;
      *) install_cp=false ;;
    esac

    # We need to accept at least all the BSD install flags.
    dest=
    files=
    opts=
    prev=
    install_type=
    isdir=false
    stripme=
    no_mode=:
    for arg
    do
      arg2=
      if test -n "$dest"; then
	func_append files " $dest"
	dest=$arg
	continue
      fi

      case $arg in
      -d) isdir=: ;;
      -f)
	if $install_cp; then :; else
	  prev=$arg
	fi
	;;
      -g | -m | -o)
	prev=$arg
	;;
      -s)
	stripme=" -s"
	continue
	;;
      -*)
	;;
      *)
	# If the previous option needed an argument, then skip it.
	if test -n "$prev"; then
	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
	    arg2=$install_override_mode
	    no_mode=false
	  fi
	  prev=
	else
	  dest=$arg
	  continue
	fi
	;;
      esac

      # Aesthetically quote the argument.
      func_quote_for_eval "$arg"
      func_append install_prog " $func_quote_for_eval_result"
      if test -n "$arg2"; then
	func_quote_for_eval "$arg2"
      fi
      func_append install_shared_prog " $func_quote_for_eval_result"
    done

    test -z "$install_prog" && \
      func_fatal_help "you must specify an install program"

    test -n "$prev" && \
      func_fatal_help "the '$prev' option requires an argument"

    if test -n "$install_override_mode" && $no_mode; then
      if $install_cp; then :; else
	func_quote_for_eval "$install_override_mode"
	func_append install_shared_prog " -m $func_quote_for_eval_result"
      fi
    fi

    if test -z "$files"; then
      if test -z "$dest"; then
	func_fatal_help "no file or destination specified"
      else
	func_fatal_help "you must specify a destination"
      fi
    fi

    # Strip any trailing slash from the destination.
    func_stripname '' '/' "$dest"
    dest=$func_stripname_result

    # Check to see that the destination is a directory.
    test -d "$dest" && isdir=:
    if $isdir; then
      destdir=$dest
      destname=
    else
      func_dirname_and_basename "$dest" "" "."
      destdir=$func_dirname_result
      destname=$func_basename_result

      # Not a directory, so check to see that there is only one file specified.
      set dummy $files; shift
      test "$#" -gt 1 && \
	func_fatal_help "'$dest' is not a directory"
    fi
    case $destdir in
    [\\/]* | [A-Za-z]:[\\/]*) ;;
    *)
      for file in $files; do
	case $file in
	*.lo) ;;
	*)
	  func_fatal_help "'$destdir' must be an absolute directory name"
	  ;;
	esac
      done
      ;;
    esac

    # This variable tells wrapper scripts just to set variables rather
    # than running their programs.
    libtool_install_magic=$magic

    staticlibs=
    future_libdirs=
    current_libdirs=
    for file in $files; do

      # Do each installation.
      case $file in
      *.$libext)
	# Do the static libraries later.
	func_append staticlibs " $file"
	;;

      *.la)
	func_resolve_sysroot "$file"
	file=$func_resolve_sysroot_result

	# Check to see that this really is a libtool archive.
	func_lalib_unsafe_p "$file" \
	  || func_fatal_help "'$file' is not a valid libtool archive"

	library_names=
	old_library=
	relink_command=
	func_source "$file"

	# Add the libdir to current_libdirs if it is the destination.
	if test "X$destdir" = "X$libdir"; then
	  case "$current_libdirs " in
	  *" $libdir "*) ;;
	  *) func_append current_libdirs " $libdir" ;;
	  esac
	else
	  # Note the libdir as a future libdir.
	  case "$future_libdirs " in
	  *" $libdir "*) ;;
	  *) func_append future_libdirs " $libdir" ;;
	  esac
	fi

	func_dirname "$file" "/" ""
	dir=$func_dirname_result
	func_append dir "$objdir"

	if test -n "$relink_command"; then
	  # Determine the prefix the user has applied to our future dir.
	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`

	  # Don't allow the user to place us outside of our expected
	  # location b/c this prevents finding dependent libraries that
	  # are installed to the same prefix.
	  # At present, this check doesn't affect windows .dll's that
	  # are installed into $libdir/../bin (currently, that works fine)
	  # but it's something to keep an eye on.
	  test "$inst_prefix_dir" = "$destdir" && \
	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"

	  if test -n "$inst_prefix_dir"; then
	    # Stick the inst_prefix_dir data into the link command.
	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
	  else
	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
	  fi

	  func_warning "relinking '$file'"
	  func_show_eval "$relink_command" \
	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
	fi

	# See the names of the shared library.
	set dummy $library_names; shift
	if test -n "$1"; then
	  realname=$1
	  shift

	  srcname=$realname
	  test -n "$relink_command" && srcname=${realname}T

	  # Install the shared library and build the symlinks.
	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
	      'exit $?'
	  tstripme=$stripme
	  case $host_os in
	  cygwin* | mingw* | pw32* | cegcc*)
	    case $realname in
	    *.dll.a)
	      tstripme=
	      ;;
	    esac
	    ;;
	  os2*)
	    case $realname in
	    *_dll.a)
	      tstripme=
	      ;;
	    esac
	    ;;
	  esac
	  if test -n "$tstripme" && test -n "$striplib"; then
	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
	  fi

	  if test "$#" -gt 0; then
	    # Delete the old symlinks, and create new ones.
	    # Try 'ln -sf' first, because the 'ln' binary might depend on
	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
	    # so we also need to try rm && ln -s.
	    for linkname
	    do
	      test "$linkname" != "$realname" \
		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
	    done
	  fi

	  # Do each command in the postinstall commands.
	  lib=$destdir/$realname
	  func_execute_cmds "$postinstall_cmds" 'exit $?'
	fi

	# Install the pseudo-library for information purposes.
	func_basename "$file"
	name=$func_basename_result
	instname=$dir/${name}i
	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'

	# Maybe install the static library, too.
	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
	;;

      *.lo)
	# Install (i.e. copy) a libtool object.

	# Figure out destination file name, if it wasn't already specified.
	if test -n "$destname"; then
	  destfile=$destdir/$destname
	else
	  func_basename "$file"
	  destfile=$func_basename_result
	  destfile=$destdir/$destfile
	fi

	# Deduce the name of the destination old-style object file.
	case $destfile in
	*.lo)
	  func_lo2o "$destfile"
	  staticdest=$func_lo2o_result
	  ;;
	*.$objext)
	  staticdest=$destfile
	  destfile=
	  ;;
	*)
	  func_fatal_help "cannot copy a libtool object to '$destfile'"
	  ;;
	esac

	# Install the libtool object if requested.
	test -n "$destfile" && \
	  func_show_eval "$install_prog $file $destfile" 'exit $?'

	# Install the old object if enabled.
	if test yes = "$build_old_libs"; then
	  # Deduce the name of the old-style object file.
	  func_lo2o "$file"
	  staticobj=$func_lo2o_result
	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
	fi
	exit $EXIT_SUCCESS
	;;

      *)
	# Figure out destination file name, if it wasn't already specified.
	if test -n "$destname"; then
	  destfile=$destdir/$destname
	else
	  func_basename "$file"
	  destfile=$func_basename_result
	  destfile=$destdir/$destfile
	fi

	# If the file is missing, and there is a .exe on the end, strip it
	# because it is most likely a libtool script we actually want to
	# install
	stripped_ext=
	case $file in
	  *.exe)
	    if test ! -f "$file"; then
	      func_stripname '' '.exe' "$file"
	      file=$func_stripname_result
	      stripped_ext=.exe
	    fi
	    ;;
	esac

	# Do a test to see if this is really a libtool program.
	case $host in
	*cygwin* | *mingw*)
	    if func_ltwrapper_executable_p "$file"; then
	      func_ltwrapper_scriptname "$file"
	      wrapper=$func_ltwrapper_scriptname_result
	    else
	      func_stripname '' '.exe' "$file"
	      wrapper=$func_stripname_result
	    fi
	    ;;
	*)
	    wrapper=$file
	    ;;
	esac
	if func_ltwrapper_script_p "$wrapper"; then
	  notinst_deplibs=
	  relink_command=

	  func_source "$wrapper"

	  # Check the variables that should have been set.
	  test -z "$generated_by_libtool_version" && \
	    func_fatal_error "invalid libtool wrapper script '$wrapper'"

	  finalize=:
	  for lib in $notinst_deplibs; do
	    # Check to see that each library is installed.
	    libdir=
	    if test -f "$lib"; then
	      func_source "$lib"
	    fi
	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
	    if test -n "$libdir" && test ! -f "$libfile"; then
	      func_warning "'$lib' has not been installed in '$libdir'"
	      finalize=false
	    fi
	  done

	  relink_command=
	  func_source "$wrapper"

	  outputname=
	  if test no = "$fast_install" && test -n "$relink_command"; then
	    $opt_dry_run || {
	      if $finalize; then
	        tmpdir=`func_mktempdir`
		func_basename "$file$stripped_ext"
		file=$func_basename_result
	        outputname=$tmpdir/$file
	        # Replace the output file specification.
	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`

	        $opt_quiet || {
	          func_quote_for_expand "$relink_command"
		  eval "func_echo $func_quote_for_expand_result"
	        }
	        if eval "$relink_command"; then :
	          else
		  func_error "error: relink '$file' with the above command before installing it"
		  $opt_dry_run || ${RM}r "$tmpdir"
		  continue
	        fi
	        file=$outputname
	      else
	        func_warning "cannot relink '$file'"
	      fi
	    }
	  else
	    # Install the binary that we compiled earlier.
	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
	  fi
	fi

	# remove .exe since cygwin /usr/bin/install will append another
	# one anyway
	case $install_prog,$host in
	*/usr/bin/install*,*cygwin*)
	  case $file:$destfile in
	  *.exe:*.exe)
	    # this is ok
	    ;;
	  *.exe:*)
	    destfile=$destfile.exe
	    ;;
	  *:*.exe)
	    func_stripname '' '.exe' "$destfile"
	    destfile=$func_stripname_result
	    ;;
	  esac
	  ;;
	esac
	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
	$opt_dry_run || if test -n "$outputname"; then
	  ${RM}r "$tmpdir"
	fi
	;;
      esac
    done

    for file in $staticlibs; do
      func_basename "$file"
      name=$func_basename_result

      # Set up the ranlib parameters.
      oldlib=$destdir/$name
      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
      tool_oldlib=$func_to_tool_file_result

      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'

      if test -n "$stripme" && test -n "$old_striplib"; then
	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
      fi

      # Do each command in the postinstall commands.
      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
    done

    test -n "$future_libdirs" && \
      func_warning "remember to run '$progname --finish$future_libdirs'"

    if test -n "$current_libdirs"; then
      # Maybe just do a dry run.
      $opt_dry_run && current_libdirs=" -n$current_libdirs"
      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
    else
      exit $EXIT_SUCCESS
    fi
}

test install = "$opt_mode" && func_mode_install ${1+"$@"}


# func_generate_dlsyms outputname originator pic_p
# Extract symbols from dlprefiles and create ${outputname}S.o with
# a dlpreopen symbol table.
func_generate_dlsyms ()
{
    $debug_cmd

    my_outputname=$1
    my_originator=$2
    my_pic_p=${3-false}
    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
    my_dlsyms=

    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
      if test -n "$NM" && test -n "$global_symbol_pipe"; then
	my_dlsyms=${my_outputname}S.c
      else
	func_error "not configured to extract global symbols from dlpreopened files"
      fi
    fi

    if test -n "$my_dlsyms"; then
      case $my_dlsyms in
      "") ;;
      *.c)
	# Discover the nlist of each of the dlfiles.
	nlist=$output_objdir/$my_outputname.nm

	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"

	# Parse the name list into a source file.
	func_verbose "creating $output_objdir/$my_dlsyms"

	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */

#ifdef __cplusplus
extern \"C\" {
#endif

#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
#endif

/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
/* DATA imports from DLLs on WIN32 can't be const, because runtime
   relocations are performed -- see ld's documentation on pseudo-relocs.  */
# define LT_DLSYM_CONST
#elif defined __osf__
/* This system does not cope well with relocations in const data.  */
# define LT_DLSYM_CONST
#else
# define LT_DLSYM_CONST const
#endif

#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)

/* External symbol declarations for the compiler. */\
"

	if test yes = "$dlself"; then
	  func_verbose "generating symbol list for '$output'"

	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"

	  # Add our own program objects to the symbol list.
	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
	  for progfile in $progfiles; do
	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
	  done

	  if test -n "$exclude_expsyms"; then
	    $opt_dry_run || {
	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
	      eval '$MV "$nlist"T "$nlist"'
	    }
	  fi

	  if test -n "$export_symbols_regex"; then
	    $opt_dry_run || {
	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
	      eval '$MV "$nlist"T "$nlist"'
	    }
	  fi

	  # Prepare the list of exported symbols
	  if test -z "$export_symbols"; then
	    export_symbols=$output_objdir/$outputname.exp
	    $opt_dry_run || {
	      $RM $export_symbols
	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
	      case $host in
	      *cygwin* | *mingw* | *cegcc* )
                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
	        ;;
	      esac
	    }
	  else
	    $opt_dry_run || {
	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
	      eval '$MV "$nlist"T "$nlist"'
	      case $host in
	        *cygwin* | *mingw* | *cegcc* )
	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
	          ;;
	      esac
	    }
	  fi
	fi

	for dlprefile in $dlprefiles; do
	  func_verbose "extracting global C symbols from '$dlprefile'"
	  func_basename "$dlprefile"
	  name=$func_basename_result
          case $host in
	    *cygwin* | *mingw* | *cegcc* )
	      # if an import library, we need to obtain dlname
	      if func_win32_import_lib_p "$dlprefile"; then
	        func_tr_sh "$dlprefile"
	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
	        dlprefile_dlbasename=
	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
	          # Use subshell, to avoid clobbering current variable values
	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
	          if test -n "$dlprefile_dlname"; then
	            func_basename "$dlprefile_dlname"
	            dlprefile_dlbasename=$func_basename_result
	          else
	            # no lafile. user explicitly requested -dlpreopen .
	            $sharedlib_from_linklib_cmd "$dlprefile"
	            dlprefile_dlbasename=$sharedlib_from_linklib_result
	          fi
	        fi
	        $opt_dry_run || {
	          if test -n "$dlprefile_dlbasename"; then
	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
	          else
	            func_warning "Could not compute DLL name from $name"
	            eval '$ECHO ": $name " >> "$nlist"'
	          fi
	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
	        }
	      else # not an import lib
	        $opt_dry_run || {
	          eval '$ECHO ": $name " >> "$nlist"'
	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
	        }
	      fi
	    ;;
	    *)
	      $opt_dry_run || {
	        eval '$ECHO ": $name " >> "$nlist"'
	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
	      }
	    ;;
          esac
	done

	$opt_dry_run || {
	  # Make sure we have at least an empty file.
	  test -f "$nlist" || : > "$nlist"

	  if test -n "$exclude_expsyms"; then
	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
	    $MV "$nlist"T "$nlist"
	  fi

	  # Try sorting and uniquifying the output.
	  if $GREP -v "^: " < "$nlist" |
	      if sort -k 3 /dev/null 2>&1; then
		sort -k 3
	      else
		sort +2
	      fi |
	      uniq > "$nlist"S; then
	    :
	  else
	    $GREP -v "^: " < "$nlist" > "$nlist"S
	  fi

	  if test -f "$nlist"S; then
	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
	  else
	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
	  fi

	  func_show_eval '$RM "${nlist}I"'
	  if test -n "$global_symbol_to_import"; then
	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
	  fi

	  echo >> "$output_objdir/$my_dlsyms" "\

/* The mapping between symbol names and symbols.  */
typedef struct {
  const char *name;
  void *address;
} lt_dlsymlist;
extern LT_DLSYM_CONST lt_dlsymlist
lt_${my_prefix}_LTX_preloaded_symbols[];\
"

	  if test -s "$nlist"I; then
	    echo >> "$output_objdir/$my_dlsyms" "\
static void lt_syminit(void)
{
  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
  for (; symbol->name; ++symbol)
    {"
	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
	    echo >> "$output_objdir/$my_dlsyms" "\
    }
}"
	  fi
	  echo >> "$output_objdir/$my_dlsyms" "\
LT_DLSYM_CONST lt_dlsymlist
lt_${my_prefix}_LTX_preloaded_symbols[] =
{ {\"$my_originator\", (void *) 0},"

	  if test -s "$nlist"I; then
	    echo >> "$output_objdir/$my_dlsyms" "\
  {\"@INIT@\", (void *) <_syminit},"
	  fi

	  case $need_lib_prefix in
	  no)
	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
	    ;;
	  *)
	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
	    ;;
	  esac
	  echo >> "$output_objdir/$my_dlsyms" "\
  {0, (void *) 0}
};

/* This works around a problem in FreeBSD linker */
#ifdef FREEBSD_WORKAROUND
static const void *lt_preloaded_setup() {
  return lt_${my_prefix}_LTX_preloaded_symbols;
}
#endif

#ifdef __cplusplus
}
#endif\
"
	} # !$opt_dry_run

	pic_flag_for_symtable=
	case "$compile_command " in
	*" -static "*) ;;
	*)
	  case $host in
	  # compiling the symbol table file with pic_flag works around
	  # a FreeBSD bug that causes programs to crash when -lm is
	  # linked before any other PIC object.  But we must not use
	  # pic_flag when linking with -static.  The problem exists in
	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
	  *-*-hpux*)
	    pic_flag_for_symtable=" $pic_flag"  ;;
	  *)
	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
	    ;;
	  esac
	  ;;
	esac
	symtab_cflags=
	for arg in $LTCFLAGS; do
	  case $arg in
	  -pie | -fpie | -fPIE) ;;
	  *) func_append symtab_cflags " $arg" ;;
	  esac
	done

	# Now compile the dynamic symbol file.
	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'

	# Clean up the generated files.
	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'

	# Transform the symbol file into the correct name.
	symfileobj=$output_objdir/${my_outputname}S.$objext
	case $host in
	*cygwin* | *mingw* | *cegcc* )
	  if test -f "$output_objdir/$my_outputname.def"; then
	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
	  else
	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
	  fi
	  ;;
	*)
	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
	  ;;
	esac
	;;
      *)
	func_fatal_error "unknown suffix for '$my_dlsyms'"
	;;
      esac
    else
      # We keep going just in case the user didn't refer to
      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
      # really was required.

      # Nullify the symbol file.
      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
    fi
}

# func_cygming_gnu_implib_p ARG
# This predicate returns with zero status (TRUE) if
# ARG is a GNU/binutils-style import library. Returns
# with nonzero status (FALSE) otherwise.
func_cygming_gnu_implib_p ()
{
  $debug_cmd

  func_to_tool_file "$1" func_convert_file_msys_to_w32
  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
  test -n "$func_cygming_gnu_implib_tmp"
}

# func_cygming_ms_implib_p ARG
# This predicate returns with zero status (TRUE) if
# ARG is an MS-style import library. Returns
# with nonzero status (FALSE) otherwise.
func_cygming_ms_implib_p ()
{
  $debug_cmd

  func_to_tool_file "$1" func_convert_file_msys_to_w32
  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
  test -n "$func_cygming_ms_implib_tmp"
}

# func_win32_libid arg
# return the library type of file 'arg'
#
# Need a lot of goo to handle *both* DLLs and import libs
# Has to be a shell function in order to 'eat' the argument
# that is supplied when $file_magic_command is called.
# Despite the name, also deal with 64 bit binaries.
func_win32_libid ()
{
  $debug_cmd

  win32_libid_type=unknown
  win32_fileres=`file -L $1 2>/dev/null`
  case $win32_fileres in
  *ar\ archive\ import\ library*) # definitely import
    win32_libid_type="x86 archive import"
    ;;
  *ar\ archive*) # could be an import, or static
    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
      case $nm_interface in
      "MS dumpbin")
	if func_cygming_ms_implib_p "$1" ||
	   func_cygming_gnu_implib_p "$1"
	then
	  win32_nmres=import
	else
	  win32_nmres=
	fi
	;;
      *)
	func_to_tool_file "$1" func_convert_file_msys_to_w32
	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
	  $SED -n -e '
	    1,100{
		/ I /{
		    s|.*|import|
		    p
		    q
		}
	    }'`
	;;
      esac
      case $win32_nmres in
      import*)  win32_libid_type="x86 archive import";;
      *)        win32_libid_type="x86 archive static";;
      esac
    fi
    ;;
  *DLL*)
    win32_libid_type="x86 DLL"
    ;;
  *executable*) # but shell scripts are "executable" too...
    case $win32_fileres in
    *MS\ Windows\ PE\ Intel*)
      win32_libid_type="x86 DLL"
      ;;
    esac
    ;;
  esac
  $ECHO "$win32_libid_type"
}

# func_cygming_dll_for_implib ARG
#
# Platform-specific function to extract the
# name of the DLL associated with the specified
# import library ARG.
# Invoked by eval'ing the libtool variable
#    $sharedlib_from_linklib_cmd
# Result is available in the variable
#    $sharedlib_from_linklib_result
func_cygming_dll_for_implib ()
{
  $debug_cmd

  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
}

# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
#
# The is the core of a fallback implementation of a
# platform-specific function to extract the name of the
# DLL associated with the specified import library LIBNAME.
#
# SECTION_NAME is either .idata$6 or .idata$7, depending
# on the platform and compiler that created the implib.
#
# Echos the name of the DLL associated with the
# specified import library.
func_cygming_dll_for_implib_fallback_core ()
{
  $debug_cmd

  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
    $SED '/^Contents of section '"$match_literal"':/{
      # Place marker at beginning of archive member dllname section
      s/.*/====MARK====/
      p
      d
    }
    # These lines can sometimes be longer than 43 characters, but
    # are always uninteresting
    /:[	 ]*file format pe[i]\{,1\}-/d
    /^In archive [^:]*:/d
    # Ensure marker is printed
    /^====MARK====/p
    # Remove all lines with less than 43 characters
    /^.\{43\}/!d
    # From remaining lines, remove first 43 characters
    s/^.\{43\}//' |
    $SED -n '
      # Join marker and all lines until next marker into a single line
      /^====MARK====/ b para
      H
      $ b para
      b
      :para
      x
      s/\n//g
      # Remove the marker
      s/^====MARK====//
      # Remove trailing dots and whitespace
      s/[\. \t]*$//
      # Print
      /./p' |
    # we now have a list, one entry per line, of the stringified
    # contents of the appropriate section of all members of the
    # archive that possess that section. Heuristic: eliminate
    # all those that have a first or second character that is
    # a '.' (that is, objdump's representation of an unprintable
    # character.) This should work for all archives with less than
    # 0x302f exports -- but will fail for DLLs whose name actually
    # begins with a literal '.' or a single character followed by
    # a '.'.
    #
    # Of those that remain, print the first one.
    $SED -e '/^\./d;/^.\./d;q'
}

# func_cygming_dll_for_implib_fallback ARG
# Platform-specific function to extract the
# name of the DLL associated with the specified
# import library ARG.
#
# This fallback implementation is for use when $DLLTOOL
# does not support the --identify-strict option.
# Invoked by eval'ing the libtool variable
#    $sharedlib_from_linklib_cmd
# Result is available in the variable
#    $sharedlib_from_linklib_result
func_cygming_dll_for_implib_fallback ()
{
  $debug_cmd

  if func_cygming_gnu_implib_p "$1"; then
    # binutils import library
    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
  elif func_cygming_ms_implib_p "$1"; then
    # ms-generated import library
    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
  else
    # unknown
    sharedlib_from_linklib_result=
  fi
}


# func_extract_an_archive dir oldlib
func_extract_an_archive ()
{
    $debug_cmd

    f_ex_an_ar_dir=$1; shift
    f_ex_an_ar_oldlib=$1
    if test yes = "$lock_old_archive_extraction"; then
      lockfile=$f_ex_an_ar_oldlib.lock
      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
	func_echo "Waiting for $lockfile to be removed"
	sleep 2
      done
    fi
    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
		   'stat=$?; rm -f "$lockfile"; exit $stat'
    if test yes = "$lock_old_archive_extraction"; then
      $opt_dry_run || rm -f "$lockfile"
    fi
    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
     :
    else
      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
    fi
}


# func_extract_archives gentop oldlib ...
func_extract_archives ()
{
    $debug_cmd

    my_gentop=$1; shift
    my_oldlibs=${1+"$@"}
    my_oldobjs=
    my_xlib=
    my_xabs=
    my_xdir=

    for my_xlib in $my_oldlibs; do
      # Extract the objects.
      case $my_xlib in
	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
	*) my_xabs=`pwd`"/$my_xlib" ;;
      esac
      func_basename "$my_xlib"
      my_xlib=$func_basename_result
      my_xlib_u=$my_xlib
      while :; do
        case " $extracted_archives " in
	*" $my_xlib_u "*)
	  func_arith $extracted_serial + 1
	  extracted_serial=$func_arith_result
	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
	*) break ;;
	esac
      done
      extracted_archives="$extracted_archives $my_xlib_u"
      my_xdir=$my_gentop/$my_xlib_u

      func_mkdir_p "$my_xdir"

      case $host in
      *-darwin*)
	func_verbose "Extracting $my_xabs"
	# Do not bother doing anything if just a dry run
	$opt_dry_run || {
	  darwin_orig_dir=`pwd`
	  cd $my_xdir || exit $?
	  darwin_archive=$my_xabs
	  darwin_curdir=`pwd`
	  func_basename "$darwin_archive"
	  darwin_base_archive=$func_basename_result
	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
	  if test -n "$darwin_arches"; then
	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
	    darwin_arch=
	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
	    for darwin_arch in  $darwin_arches; do
	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
	      cd "$darwin_curdir"
	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
	    done # $darwin_arches
            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
	    darwin_file=
	    darwin_files=
	    for darwin_file in $darwin_filelist; do
	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
	      $LIPO -create -output "$darwin_file" $darwin_files
	    done # $darwin_filelist
	    $RM -rf unfat-$$
	    cd "$darwin_orig_dir"
	  else
	    cd $darwin_orig_dir
	    func_extract_an_archive "$my_xdir" "$my_xabs"
	  fi # $darwin_arches
	} # !$opt_dry_run
	;;
      *)
        func_extract_an_archive "$my_xdir" "$my_xabs"
	;;
      esac
      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
    done

    func_extract_archives_result=$my_oldobjs
}


# func_emit_wrapper [arg=no]
#
# Emit a libtool wrapper script on stdout.
# Don't directly open a file because we may want to
# incorporate the script contents within a cygwin/mingw
# wrapper executable.  Must ONLY be called from within
# func_mode_link because it depends on a number of variables
# set therein.
#
# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
# variable will take.  If 'yes', then the emitted script
# will assume that the directory where it is stored is
# the $objdir directory.  This is a cygwin/mingw-specific
# behavior.
func_emit_wrapper ()
{
	func_emit_wrapper_arg1=${1-no}

	$ECHO "\
#! $SHELL

# $output - temporary wrapper script for $objdir/$outputname
# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
#
# The $output program cannot be directly executed until all the libtool
# libraries that it depends on are installed.
#
# This wrapper script should never be moved out of the build directory.
# If it is, it will not operate correctly.

# Sed substitution that helps us do robust quoting.  It backslashifies
# metacharacters that are still active within double-quoted strings.
sed_quote_subst='$sed_quote_subst'

# Be Bourne compatible
if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
  emulate sh
  NULLCMD=:
  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '\${1+\"\$@\"}'='\"\$@\"'
  setopt NO_GLOB_SUBST
else
  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
fi
BIN_SH=xpg4; export BIN_SH # for Tru64
DUALCASE=1; export DUALCASE # for MKS sh

# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

relink_command=\"$relink_command\"

# This environment variable determines our operation mode.
if test \"\$libtool_install_magic\" = \"$magic\"; then
  # install mode needs the following variables:
  generated_by_libtool_version='$macro_version'
  notinst_deplibs='$notinst_deplibs'
else
  # When we are sourced in execute mode, \$file and \$ECHO are already set.
  if test \"\$libtool_execute_magic\" != \"$magic\"; then
    file=\"\$0\""

    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
    $ECHO "\

# A function that is used when there is no print builtin or printf.
func_fallback_echo ()
{
  eval 'cat <<_LTECHO_EOF
\$1
_LTECHO_EOF'
}
    ECHO=\"$qECHO\"
  fi

# Very basic option parsing. These options are (a) specific to
# the libtool wrapper, (b) are identical between the wrapper
# /script/ and the wrapper /executable/ that is used only on
# windows platforms, and (c) all begin with the string "--lt-"
# (application programs are unlikely to have options that match
# this pattern).
#
# There are only two supported options: --lt-debug and
# --lt-dump-script. There is, deliberately, no --lt-help.
#
# The first argument to this parsing function should be the
# script's $0 value, followed by "$@".
lt_option_debug=
func_parse_lt_options ()
{
  lt_script_arg0=\$0
  shift
  for lt_opt
  do
    case \"\$lt_opt\" in
    --lt-debug) lt_option_debug=1 ;;
    --lt-dump-script)
        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
        cat \"\$lt_dump_D/\$lt_dump_F\"
        exit 0
      ;;
    --lt-*)
        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
        exit 1
      ;;
    esac
  done

  # Print the debug banner immediately:
  if test -n \"\$lt_option_debug\"; then
    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
  fi
}

# Used when --lt-debug. Prints its arguments to stdout
# (redirection is the responsibility of the caller)
func_lt_dump_args ()
{
  lt_dump_args_N=1;
  for lt_arg
  do
    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
  done
}

# Core function for launching the target application
func_exec_program_core ()
{
"
  case $host in
  # Backslashes separate directories on plain windows
  *-*-mingw | *-*-os2* | *-cegcc*)
    $ECHO "\
      if test -n \"\$lt_option_debug\"; then
        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
        func_lt_dump_args \${1+\"\$@\"} 1>&2
      fi
      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
"
    ;;

  *)
    $ECHO "\
      if test -n \"\$lt_option_debug\"; then
        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
        func_lt_dump_args \${1+\"\$@\"} 1>&2
      fi
      exec \"\$progdir/\$program\" \${1+\"\$@\"}
"
    ;;
  esac
  $ECHO "\
      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
      exit 1
}

# A function to encapsulate launching the target application
# Strips options in the --lt-* namespace from \$@ and
# launches target application with the remaining arguments.
func_exec_program ()
{
  case \" \$* \" in
  *\\ --lt-*)
    for lt_wr_arg
    do
      case \$lt_wr_arg in
      --lt-*) ;;
      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
      esac
      shift
    done ;;
  esac
  func_exec_program_core \${1+\"\$@\"}
}

  # Parse options
  func_parse_lt_options \"\$0\" \${1+\"\$@\"}

  # Find the directory that this script lives in.
  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
  test \"x\$thisdir\" = \"x\$file\" && thisdir=.

  # Follow symbolic links until we get to the real thisdir.
  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
  while test -n \"\$file\"; do
    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`

    # If there was a directory component, then change thisdir.
    if test \"x\$destdir\" != \"x\$file\"; then
      case \"\$destdir\" in
      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
      *) thisdir=\"\$thisdir/\$destdir\" ;;
      esac
    fi

    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
  done

  # Usually 'no', except on cygwin/mingw when embedded into
  # the cwrapper.
  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
    # special case for '.'
    if test \"\$thisdir\" = \".\"; then
      thisdir=\`pwd\`
    fi
    # remove .libs from thisdir
    case \"\$thisdir\" in
    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
    $objdir )   thisdir=. ;;
    esac
  fi

  # Try to get the absolute directory name.
  absdir=\`cd \"\$thisdir\" && pwd\`
  test -n \"\$absdir\" && thisdir=\"\$absdir\"
"

	if test yes = "$fast_install"; then
	  $ECHO "\
  program=lt-'$outputname'$exeext
  progdir=\"\$thisdir/$objdir\"

  if test ! -f \"\$progdir/\$program\" ||
     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
       test \"X\$file\" != \"X\$progdir/\$program\"; }; then

    file=\"\$\$-\$program\"

    if test ! -d \"\$progdir\"; then
      $MKDIR \"\$progdir\"
    else
      $RM \"\$progdir/\$file\"
    fi"

	  $ECHO "\

    # relink executable if necessary
    if test -n \"\$relink_command\"; then
      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
      else
	\$ECHO \"\$relink_command_output\" >&2
	$RM \"\$progdir/\$file\"
	exit 1
      fi
    fi

    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
    { $RM \"\$progdir/\$program\";
      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
    $RM \"\$progdir/\$file\"
  fi"
	else
	  $ECHO "\
  program='$outputname'
  progdir=\"\$thisdir/$objdir\"
"
	fi

	$ECHO "\

  if test -f \"\$progdir/\$program\"; then"

	# fixup the dll searchpath if we need to.
	#
	# Fix the DLL searchpath if we need to.  Do this before prepending
	# to shlibpath, because on Windows, both are PATH and uninstalled
	# libraries must come first.
	if test -n "$dllsearchpath"; then
	  $ECHO "\
    # Add the dll search path components to the executable PATH
    PATH=$dllsearchpath:\$PATH
"
	fi

	# Export our shlibpath_var if we have one.
	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
	  $ECHO "\
    # Add our own library path to $shlibpath_var
    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"

    # Some systems cannot cope with colon-terminated $shlibpath_var
    # The second colon is a workaround for a bug in BeOS R4 sed
    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`

    export $shlibpath_var
"
	fi

	$ECHO "\
    if test \"\$libtool_execute_magic\" != \"$magic\"; then
      # Run the actual program with our arguments.
      func_exec_program \${1+\"\$@\"}
    fi
  else
    # The program doesn't exist.
    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
    exit 1
  fi
fi\
"
}


# func_emit_cwrapperexe_src
# emit the source code for a wrapper executable on stdout
# Must ONLY be called from within func_mode_link because
# it depends on a number of variable set therein.
func_emit_cwrapperexe_src ()
{
	cat <
#include 
#ifdef _MSC_VER
# include 
# include 
# include 
#else
# include 
# include 
# ifdef __CYGWIN__
#  include 
# endif
#endif
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)

/* declarations of non-ANSI functions */
#if defined __MINGW32__
# ifdef __STRICT_ANSI__
int _putenv (const char *);
# endif
#elif defined __CYGWIN__
# ifdef __STRICT_ANSI__
char *realpath (const char *, char *);
int putenv (char *);
int setenv (const char *, const char *, int);
# endif
/* #elif defined other_platform || defined ... */
#endif

/* portability defines, excluding path handling macros */
#if defined _MSC_VER
# define setmode _setmode
# define stat    _stat
# define chmod   _chmod
# define getcwd  _getcwd
# define putenv  _putenv
# define S_IXUSR _S_IEXEC
#elif defined __MINGW32__
# define setmode _setmode
# define stat    _stat
# define chmod   _chmod
# define getcwd  _getcwd
# define putenv  _putenv
#elif defined __CYGWIN__
# define HAVE_SETENV
# define FOPEN_WB "wb"
/* #elif defined other platforms ... */
#endif

#if defined PATH_MAX
# define LT_PATHMAX PATH_MAX
#elif defined MAXPATHLEN
# define LT_PATHMAX MAXPATHLEN
#else
# define LT_PATHMAX 1024
#endif

#ifndef S_IXOTH
# define S_IXOTH 0
#endif
#ifndef S_IXGRP
# define S_IXGRP 0
#endif

/* path handling portability macros */
#ifndef DIR_SEPARATOR
# define DIR_SEPARATOR '/'
# define PATH_SEPARATOR ':'
#endif

#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
  defined __OS2__
# define HAVE_DOS_BASED_FILE_SYSTEM
# define FOPEN_WB "wb"
# ifndef DIR_SEPARATOR_2
#  define DIR_SEPARATOR_2 '\\'
# endif
# ifndef PATH_SEPARATOR_2
#  define PATH_SEPARATOR_2 ';'
# endif
#endif

#ifndef DIR_SEPARATOR_2
# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
#else /* DIR_SEPARATOR_2 */
# define IS_DIR_SEPARATOR(ch) \
	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
#endif /* DIR_SEPARATOR_2 */

#ifndef PATH_SEPARATOR_2
# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
#else /* PATH_SEPARATOR_2 */
# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
#endif /* PATH_SEPARATOR_2 */

#ifndef FOPEN_WB
# define FOPEN_WB "w"
#endif
#ifndef _O_BINARY
# define _O_BINARY 0
#endif

#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
#define XFREE(stale) do { \
  if (stale) { free (stale); stale = 0; } \
} while (0)

#if defined LT_DEBUGWRAPPER
static int lt_debug = 1;
#else
static int lt_debug = 0;
#endif

const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */

void *xmalloc (size_t num);
char *xstrdup (const char *string);
const char *base_name (const char *name);
char *find_executable (const char *wrapper);
char *chase_symlinks (const char *pathspec);
int make_executable (const char *path);
int check_executable (const char *path);
char *strendzap (char *str, const char *pat);
void lt_debugprintf (const char *file, int line, const char *fmt, ...);
void lt_fatal (const char *file, int line, const char *message, ...);
static const char *nonnull (const char *s);
static const char *nonempty (const char *s);
void lt_setenv (const char *name, const char *value);
char *lt_extend_str (const char *orig_value, const char *add, int to_end);
void lt_update_exe_path (const char *name, const char *value);
void lt_update_lib_path (const char *name, const char *value);
char **prepare_spawn (char **argv);
void lt_dump_script (FILE *f);
EOF

	    cat <= 0)
      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
    return 1;
  else
    return 0;
}

int
make_executable (const char *path)
{
  int rval = 0;
  struct stat st;

  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
                  nonempty (path));
  if ((!path) || (!*path))
    return 0;

  if (stat (path, &st) >= 0)
    {
      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
    }
  return rval;
}

/* Searches for the full path of the wrapper.  Returns
   newly allocated full path name if found, NULL otherwise
   Does not chase symlinks, even on platforms that support them.
*/
char *
find_executable (const char *wrapper)
{
  int has_slash = 0;
  const char *p;
  const char *p_next;
  /* static buffer for getcwd */
  char tmp[LT_PATHMAX + 1];
  size_t tmp_len;
  char *concat_name;

  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
                  nonempty (wrapper));

  if ((wrapper == NULL) || (*wrapper == '\0'))
    return NULL;

  /* Absolute path? */
#if defined HAVE_DOS_BASED_FILE_SYSTEM
  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
    {
      concat_name = xstrdup (wrapper);
      if (check_executable (concat_name))
	return concat_name;
      XFREE (concat_name);
    }
  else
    {
#endif
      if (IS_DIR_SEPARATOR (wrapper[0]))
	{
	  concat_name = xstrdup (wrapper);
	  if (check_executable (concat_name))
	    return concat_name;
	  XFREE (concat_name);
	}
#if defined HAVE_DOS_BASED_FILE_SYSTEM
    }
#endif

  for (p = wrapper; *p; p++)
    if (*p == '/')
      {
	has_slash = 1;
	break;
      }
  if (!has_slash)
    {
      /* no slashes; search PATH */
      const char *path = getenv ("PATH");
      if (path != NULL)
	{
	  for (p = path; *p; p = p_next)
	    {
	      const char *q;
	      size_t p_len;
	      for (q = p; *q; q++)
		if (IS_PATH_SEPARATOR (*q))
		  break;
	      p_len = (size_t) (q - p);
	      p_next = (*q == '\0' ? q : q + 1);
	      if (p_len == 0)
		{
		  /* empty path: current directory */
		  if (getcwd (tmp, LT_PATHMAX) == NULL)
		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
                              nonnull (strerror (errno)));
		  tmp_len = strlen (tmp);
		  concat_name =
		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
		  memcpy (concat_name, tmp, tmp_len);
		  concat_name[tmp_len] = '/';
		  strcpy (concat_name + tmp_len + 1, wrapper);
		}
	      else
		{
		  concat_name =
		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
		  memcpy (concat_name, p, p_len);
		  concat_name[p_len] = '/';
		  strcpy (concat_name + p_len + 1, wrapper);
		}
	      if (check_executable (concat_name))
		return concat_name;
	      XFREE (concat_name);
	    }
	}
      /* not found in PATH; assume curdir */
    }
  /* Relative path | not found in path: prepend cwd */
  if (getcwd (tmp, LT_PATHMAX) == NULL)
    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
              nonnull (strerror (errno)));
  tmp_len = strlen (tmp);
  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
  memcpy (concat_name, tmp, tmp_len);
  concat_name[tmp_len] = '/';
  strcpy (concat_name + tmp_len + 1, wrapper);

  if (check_executable (concat_name))
    return concat_name;
  XFREE (concat_name);
  return NULL;
}

char *
chase_symlinks (const char *pathspec)
{
#ifndef S_ISLNK
  return xstrdup (pathspec);
#else
  char buf[LT_PATHMAX];
  struct stat s;
  char *tmp_pathspec = xstrdup (pathspec);
  char *p;
  int has_symlinks = 0;
  while (strlen (tmp_pathspec) && !has_symlinks)
    {
      lt_debugprintf (__FILE__, __LINE__,
		      "checking path component for symlinks: %s\n",
		      tmp_pathspec);
      if (lstat (tmp_pathspec, &s) == 0)
	{
	  if (S_ISLNK (s.st_mode) != 0)
	    {
	      has_symlinks = 1;
	      break;
	    }

	  /* search backwards for last DIR_SEPARATOR */
	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
	    p--;
	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
	    {
	      /* no more DIR_SEPARATORS left */
	      break;
	    }
	  *p = '\0';
	}
      else
	{
	  lt_fatal (__FILE__, __LINE__,
		    "error accessing file \"%s\": %s",
		    tmp_pathspec, nonnull (strerror (errno)));
	}
    }
  XFREE (tmp_pathspec);

  if (!has_symlinks)
    {
      return xstrdup (pathspec);
    }

  tmp_pathspec = realpath (pathspec, buf);
  if (tmp_pathspec == 0)
    {
      lt_fatal (__FILE__, __LINE__,
		"could not follow symlinks for %s", pathspec);
    }
  return xstrdup (tmp_pathspec);
#endif
}

char *
strendzap (char *str, const char *pat)
{
  size_t len, patlen;

  assert (str != NULL);
  assert (pat != NULL);

  len = strlen (str);
  patlen = strlen (pat);

  if (patlen <= len)
    {
      str += len - patlen;
      if (STREQ (str, pat))
	*str = '\0';
    }
  return str;
}

void
lt_debugprintf (const char *file, int line, const char *fmt, ...)
{
  va_list args;
  if (lt_debug)
    {
      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
      va_start (args, fmt);
      (void) vfprintf (stderr, fmt, args);
      va_end (args);
    }
}

static void
lt_error_core (int exit_status, const char *file,
	       int line, const char *mode,
	       const char *message, va_list ap)
{
  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
  vfprintf (stderr, message, ap);
  fprintf (stderr, ".\n");

  if (exit_status >= 0)
    exit (exit_status);
}

void
lt_fatal (const char *file, int line, const char *message, ...)
{
  va_list ap;
  va_start (ap, message);
  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
  va_end (ap);
}

static const char *
nonnull (const char *s)
{
  return s ? s : "(null)";
}

static const char *
nonempty (const char *s)
{
  return (s && !*s) ? "(empty)" : nonnull (s);
}

void
lt_setenv (const char *name, const char *value)
{
  lt_debugprintf (__FILE__, __LINE__,
		  "(lt_setenv) setting '%s' to '%s'\n",
                  nonnull (name), nonnull (value));
  {
#ifdef HAVE_SETENV
    /* always make a copy, for consistency with !HAVE_SETENV */
    char *str = xstrdup (value);
    setenv (name, str, 1);
#else
    size_t len = strlen (name) + 1 + strlen (value) + 1;
    char *str = XMALLOC (char, len);
    sprintf (str, "%s=%s", name, value);
    if (putenv (str) != EXIT_SUCCESS)
      {
        XFREE (str);
      }
#endif
  }
}

char *
lt_extend_str (const char *orig_value, const char *add, int to_end)
{
  char *new_value;
  if (orig_value && *orig_value)
    {
      size_t orig_value_len = strlen (orig_value);
      size_t add_len = strlen (add);
      new_value = XMALLOC (char, add_len + orig_value_len + 1);
      if (to_end)
        {
          strcpy (new_value, orig_value);
          strcpy (new_value + orig_value_len, add);
        }
      else
        {
          strcpy (new_value, add);
          strcpy (new_value + add_len, orig_value);
        }
    }
  else
    {
      new_value = xstrdup (add);
    }
  return new_value;
}

void
lt_update_exe_path (const char *name, const char *value)
{
  lt_debugprintf (__FILE__, __LINE__,
		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
                  nonnull (name), nonnull (value));

  if (name && *name && value && *value)
    {
      char *new_value = lt_extend_str (getenv (name), value, 0);
      /* some systems can't cope with a ':'-terminated path #' */
      size_t len = strlen (new_value);
      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
        {
          new_value[--len] = '\0';
        }
      lt_setenv (name, new_value);
      XFREE (new_value);
    }
}

void
lt_update_lib_path (const char *name, const char *value)
{
  lt_debugprintf (__FILE__, __LINE__,
		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
                  nonnull (name), nonnull (value));

  if (name && *name && value && *value)
    {
      char *new_value = lt_extend_str (getenv (name), value, 0);
      lt_setenv (name, new_value);
      XFREE (new_value);
    }
}

EOF
	    case $host_os in
	      mingw*)
		cat <<"EOF"

/* Prepares an argument vector before calling spawn().
   Note that spawn() does not by itself call the command interpreter
     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
         GetVersionEx(&v);
         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
      }) ? "cmd.exe" : "command.com").
   Instead it simply concatenates the arguments, separated by ' ', and calls
   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
   special way:
   - Space and tab are interpreted as delimiters. They are not treated as
     delimiters if they are surrounded by double quotes: "...".
   - Unescaped double quotes are removed from the input. Their only effect is
     that within double quotes, space and tab are treated like normal
     characters.
   - Backslashes not followed by double quotes are not special.
   - But 2*n+1 backslashes followed by a double quote become
     n backslashes followed by a double quote (n >= 0):
       \" -> "
       \\\" -> \"
       \\\\\" -> \\"
 */
#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
char **
prepare_spawn (char **argv)
{
  size_t argc;
  char **new_argv;
  size_t i;

  /* Count number of arguments.  */
  for (argc = 0; argv[argc] != NULL; argc++)
    ;

  /* Allocate new argument vector.  */
  new_argv = XMALLOC (char *, argc + 1);

  /* Put quoted arguments into the new argument vector.  */
  for (i = 0; i < argc; i++)
    {
      const char *string = argv[i];

      if (string[0] == '\0')
	new_argv[i] = xstrdup ("\"\"");
      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
	{
	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
	  size_t length;
	  unsigned int backslashes;
	  const char *s;
	  char *quoted_string;
	  char *p;

	  length = 0;
	  backslashes = 0;
	  if (quote_around)
	    length++;
	  for (s = string; *s != '\0'; s++)
	    {
	      char c = *s;
	      if (c == '"')
		length += backslashes + 1;
	      length++;
	      if (c == '\\')
		backslashes++;
	      else
		backslashes = 0;
	    }
	  if (quote_around)
	    length += backslashes + 1;

	  quoted_string = XMALLOC (char, length + 1);

	  p = quoted_string;
	  backslashes = 0;
	  if (quote_around)
	    *p++ = '"';
	  for (s = string; *s != '\0'; s++)
	    {
	      char c = *s;
	      if (c == '"')
		{
		  unsigned int j;
		  for (j = backslashes + 1; j > 0; j--)
		    *p++ = '\\';
		}
	      *p++ = c;
	      if (c == '\\')
		backslashes++;
	      else
		backslashes = 0;
	    }
	  if (quote_around)
	    {
	      unsigned int j;
	      for (j = backslashes; j > 0; j--)
		*p++ = '\\';
	      *p++ = '"';
	    }
	  *p = '\0';

	  new_argv[i] = quoted_string;
	}
      else
	new_argv[i] = (char *) string;
    }
  new_argv[argc] = NULL;

  return new_argv;
}
EOF
		;;
	    esac

            cat <<"EOF"
void lt_dump_script (FILE* f)
{
EOF
	    func_emit_wrapper yes |
	      $SED -n -e '
s/^\(.\{79\}\)\(..*\)/\1\
\2/
h
s/\([\\"]\)/\\\1/g
s/$/\\n/
s/\([^\n]*\).*/  fputs ("\1", f);/p
g
D'
            cat <<"EOF"
}
EOF
}
# end: func_emit_cwrapperexe_src

# func_win32_import_lib_p ARG
# True if ARG is an import lib, as indicated by $file_magic_cmd
func_win32_import_lib_p ()
{
    $debug_cmd

    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
    *import*) : ;;
    *) false ;;
    esac
}

# func_suncc_cstd_abi
# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
# Several compiler flags select an ABI that is incompatible with the
# Cstd library. Avoid specifying it if any are in CXXFLAGS.
func_suncc_cstd_abi ()
{
    $debug_cmd

    case " $compile_command " in
    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
      suncc_use_cstd_abi=no
      ;;
    *)
      suncc_use_cstd_abi=yes
      ;;
    esac
}

# func_mode_link arg...
func_mode_link ()
{
    $debug_cmd

    case $host in
    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
      # It is impossible to link a dll without this setting, and
      # we shouldn't force the makefile maintainer to figure out
      # what system we are compiling for in order to pass an extra
      # flag for every libtool invocation.
      # allow_undefined=no

      # FIXME: Unfortunately, there are problems with the above when trying
      # to make a dll that has undefined symbols, in which case not
      # even a static library is built.  For now, we need to specify
      # -no-undefined on the libtool link line when we can be certain
      # that all symbols are satisfied, otherwise we get a static library.
      allow_undefined=yes
      ;;
    *)
      allow_undefined=yes
      ;;
    esac
    libtool_args=$nonopt
    base_compile="$nonopt $@"
    compile_command=$nonopt
    finalize_command=$nonopt

    compile_rpath=
    finalize_rpath=
    compile_shlibpath=
    finalize_shlibpath=
    convenience=
    old_convenience=
    deplibs=
    old_deplibs=
    compiler_flags=
    linker_flags=
    dllsearchpath=
    lib_search_path=`pwd`
    inst_prefix_dir=
    new_inherited_linker_flags=

    avoid_version=no
    bindir=
    dlfiles=
    dlprefiles=
    dlself=no
    export_dynamic=no
    export_symbols=
    export_symbols_regex=
    generated=
    libobjs=
    ltlibs=
    module=no
    no_install=no
    objs=
    os2dllname=
    non_pic_objects=
    precious_files_regex=
    prefer_static_libs=no
    preload=false
    prev=
    prevarg=
    release=
    rpath=
    xrpath=
    perm_rpath=
    temp_rpath=
    thread_safe=no
    vinfo=
    vinfo_number=no
    weak_libs=
    single_module=$wl-single_module
    func_infer_tag $base_compile

    # We need to know -static, to get the right output filenames.
    for arg
    do
      case $arg in
      -shared)
	test yes != "$build_libtool_libs" \
	  && func_fatal_configuration "cannot build a shared library"
	build_old_libs=no
	break
	;;
      -all-static | -static | -static-libtool-libs)
	case $arg in
	-all-static)
	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
	    func_warning "complete static linking is impossible in this configuration"
	  fi
	  if test -n "$link_static_flag"; then
	    dlopen_self=$dlopen_self_static
	  fi
	  prefer_static_libs=yes
	  ;;
	-static)
	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
	    dlopen_self=$dlopen_self_static
	  fi
	  prefer_static_libs=built
	  ;;
	-static-libtool-libs)
	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
	    dlopen_self=$dlopen_self_static
	  fi
	  prefer_static_libs=yes
	  ;;
	esac
	build_libtool_libs=no
	build_old_libs=yes
	break
	;;
      esac
    done

    # See if our shared archives depend on static archives.
    test -n "$old_archive_from_new_cmds" && build_old_libs=yes

    # Go through the arguments, transforming them on the way.
    while test "$#" -gt 0; do
      arg=$1
      shift
      func_quote_for_eval "$arg"
      qarg=$func_quote_for_eval_unquoted_result
      func_append libtool_args " $func_quote_for_eval_result"

      # If the previous option needs an argument, assign it.
      if test -n "$prev"; then
	case $prev in
	output)
	  func_append compile_command " @OUTPUT@"
	  func_append finalize_command " @OUTPUT@"
	  ;;
	esac

	case $prev in
	bindir)
	  bindir=$arg
	  prev=
	  continue
	  ;;
	dlfiles|dlprefiles)
	  $preload || {
	    # Add the symbol object into the linking commands.
	    func_append compile_command " @SYMFILE@"
	    func_append finalize_command " @SYMFILE@"
	    preload=:
	  }
	  case $arg in
	  *.la | *.lo) ;;  # We handle these cases below.
	  force)
	    if test no = "$dlself"; then
	      dlself=needless
	      export_dynamic=yes
	    fi
	    prev=
	    continue
	    ;;
	  self)
	    if test dlprefiles = "$prev"; then
	      dlself=yes
	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
	      dlself=yes
	    else
	      dlself=needless
	      export_dynamic=yes
	    fi
	    prev=
	    continue
	    ;;
	  *)
	    if test dlfiles = "$prev"; then
	      func_append dlfiles " $arg"
	    else
	      func_append dlprefiles " $arg"
	    fi
	    prev=
	    continue
	    ;;
	  esac
	  ;;
	expsyms)
	  export_symbols=$arg
	  test -f "$arg" \
	    || func_fatal_error "symbol file '$arg' does not exist"
	  prev=
	  continue
	  ;;
	expsyms_regex)
	  export_symbols_regex=$arg
	  prev=
	  continue
	  ;;
	framework)
	  case $host in
	    *-*-darwin*)
	      case "$deplibs " in
		*" $qarg.ltframework "*) ;;
		*) func_append deplibs " $qarg.ltframework" # this is fixed later
		   ;;
	      esac
	      ;;
	  esac
	  prev=
	  continue
	  ;;
	inst_prefix)
	  inst_prefix_dir=$arg
	  prev=
	  continue
	  ;;
	mllvm)
	  # Clang does not use LLVM to link, so we can simply discard any
	  # '-mllvm $arg' options when doing the link step.
	  prev=
	  continue
	  ;;
	objectlist)
	  if test -f "$arg"; then
	    save_arg=$arg
	    moreargs=
	    for fil in `cat "$save_arg"`
	    do
#	      func_append moreargs " $fil"
	      arg=$fil
	      # A libtool-controlled object.

	      # Check to see that this really is a libtool object.
	      if func_lalib_unsafe_p "$arg"; then
		pic_object=
		non_pic_object=

		# Read the .lo file
		func_source "$arg"

		if test -z "$pic_object" ||
		   test -z "$non_pic_object" ||
		   test none = "$pic_object" &&
		   test none = "$non_pic_object"; then
		  func_fatal_error "cannot find name of object for '$arg'"
		fi

		# Extract subdirectory from the argument.
		func_dirname "$arg" "/" ""
		xdir=$func_dirname_result

		if test none != "$pic_object"; then
		  # Prepend the subdirectory the object is found in.
		  pic_object=$xdir$pic_object

		  if test dlfiles = "$prev"; then
		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
		      func_append dlfiles " $pic_object"
		      prev=
		      continue
		    else
		      # If libtool objects are unsupported, then we need to preload.
		      prev=dlprefiles
		    fi
		  fi

		  # CHECK ME:  I think I busted this.  -Ossama
		  if test dlprefiles = "$prev"; then
		    # Preload the old-style object.
		    func_append dlprefiles " $pic_object"
		    prev=
		  fi

		  # A PIC object.
		  func_append libobjs " $pic_object"
		  arg=$pic_object
		fi

		# Non-PIC object.
		if test none != "$non_pic_object"; then
		  # Prepend the subdirectory the object is found in.
		  non_pic_object=$xdir$non_pic_object

		  # A standard non-PIC object
		  func_append non_pic_objects " $non_pic_object"
		  if test -z "$pic_object" || test none = "$pic_object"; then
		    arg=$non_pic_object
		  fi
		else
		  # If the PIC object exists, use it instead.
		  # $xdir was prepended to $pic_object above.
		  non_pic_object=$pic_object
		  func_append non_pic_objects " $non_pic_object"
		fi
	      else
		# Only an error if not doing a dry-run.
		if $opt_dry_run; then
		  # Extract subdirectory from the argument.
		  func_dirname "$arg" "/" ""
		  xdir=$func_dirname_result

		  func_lo2o "$arg"
		  pic_object=$xdir$objdir/$func_lo2o_result
		  non_pic_object=$xdir$func_lo2o_result
		  func_append libobjs " $pic_object"
		  func_append non_pic_objects " $non_pic_object"
	        else
		  func_fatal_error "'$arg' is not a valid libtool object"
		fi
	      fi
	    done
	  else
	    func_fatal_error "link input file '$arg' does not exist"
	  fi
	  arg=$save_arg
	  prev=
	  continue
	  ;;
	os2dllname)
	  os2dllname=$arg
	  prev=
	  continue
	  ;;
	precious_regex)
	  precious_files_regex=$arg
	  prev=
	  continue
	  ;;
	release)
	  release=-$arg
	  prev=
	  continue
	  ;;
	rpath | xrpath)
	  # We need an absolute path.
	  case $arg in
	  [\\/]* | [A-Za-z]:[\\/]*) ;;
	  *)
	    func_fatal_error "only absolute run-paths are allowed"
	    ;;
	  esac
	  if test rpath = "$prev"; then
	    case "$rpath " in
	    *" $arg "*) ;;
	    *) func_append rpath " $arg" ;;
	    esac
	  else
	    case "$xrpath " in
	    *" $arg "*) ;;
	    *) func_append xrpath " $arg" ;;
	    esac
	  fi
	  prev=
	  continue
	  ;;
	shrext)
	  shrext_cmds=$arg
	  prev=
	  continue
	  ;;
	weak)
	  func_append weak_libs " $arg"
	  prev=
	  continue
	  ;;
	xcclinker)
	  func_append linker_flags " $qarg"
	  func_append compiler_flags " $qarg"
	  prev=
	  func_append compile_command " $qarg"
	  func_append finalize_command " $qarg"
	  continue
	  ;;
	xcompiler)
	  func_append compiler_flags " $qarg"
	  prev=
	  func_append compile_command " $qarg"
	  func_append finalize_command " $qarg"
	  continue
	  ;;
	xlinker)
	  func_append linker_flags " $qarg"
	  func_append compiler_flags " $wl$qarg"
	  prev=
	  func_append compile_command " $wl$qarg"
	  func_append finalize_command " $wl$qarg"
	  continue
	  ;;
	*)
	  eval "$prev=\"\$arg\""
	  prev=
	  continue
	  ;;
	esac
      fi # test -n "$prev"

      prevarg=$arg

      case $arg in
      -all-static)
	if test -n "$link_static_flag"; then
	  # See comment for -static flag below, for more details.
	  func_append compile_command " $link_static_flag"
	  func_append finalize_command " $link_static_flag"
	fi
	continue
	;;

      -allow-undefined)
	# FIXME: remove this flag sometime in the future.
	func_fatal_error "'-allow-undefined' must not be used because it is the default"
	;;

      -avoid-version)
	avoid_version=yes
	continue
	;;

      -bindir)
	prev=bindir
	continue
	;;

      -dlopen)
	prev=dlfiles
	continue
	;;

      -dlpreopen)
	prev=dlprefiles
	continue
	;;

      -export-dynamic)
	export_dynamic=yes
	continue
	;;

      -export-symbols | -export-symbols-regex)
	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
	  func_fatal_error "more than one -exported-symbols argument is not allowed"
	fi
	if test X-export-symbols = "X$arg"; then
	  prev=expsyms
	else
	  prev=expsyms_regex
	fi
	continue
	;;

      -framework)
	prev=framework
	continue
	;;

      -inst-prefix-dir)
	prev=inst_prefix
	continue
	;;

      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
      # so, if we see these flags be careful not to treat them like -L
      -L[A-Z][A-Z]*:*)
	case $with_gcc/$host in
	no/*-*-irix* | /*-*-irix*)
	  func_append compile_command " $arg"
	  func_append finalize_command " $arg"
	  ;;
	esac
	continue
	;;

      -L*)
	func_stripname "-L" '' "$arg"
	if test -z "$func_stripname_result"; then
	  if test "$#" -gt 0; then
	    func_fatal_error "require no space between '-L' and '$1'"
	  else
	    func_fatal_error "need path for '-L' option"
	  fi
	fi
	func_resolve_sysroot "$func_stripname_result"
	dir=$func_resolve_sysroot_result
	# We need an absolute path.
	case $dir in
	[\\/]* | [A-Za-z]:[\\/]*) ;;
	*)
	  absdir=`cd "$dir" && pwd`
	  test -z "$absdir" && \
	    func_fatal_error "cannot determine absolute directory name of '$dir'"
	  dir=$absdir
	  ;;
	esac
	case "$deplibs " in
	*" -L$dir "* | *" $arg "*)
	  # Will only happen for absolute or sysroot arguments
	  ;;
	*)
	  # Preserve sysroot, but never include relative directories
	  case $dir in
	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
	    *) func_append deplibs " -L$dir" ;;
	  esac
	  func_append lib_search_path " $dir"
	  ;;
	esac
	case $host in
	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
	  case :$dllsearchpath: in
	  *":$dir:"*) ;;
	  ::) dllsearchpath=$dir;;
	  *) func_append dllsearchpath ":$dir";;
	  esac
	  case :$dllsearchpath: in
	  *":$testbindir:"*) ;;
	  ::) dllsearchpath=$testbindir;;
	  *) func_append dllsearchpath ":$testbindir";;
	  esac
	  ;;
	esac
	continue
	;;

      -l*)
	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
	  case $host in
	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
	    # These systems don't actually have a C or math library (as such)
	    continue
	    ;;
	  *-*-os2*)
	    # These systems don't actually have a C library (as such)
	    test X-lc = "X$arg" && continue
	    ;;
	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
	    # Do not include libc due to us having libc/libc_r.
	    test X-lc = "X$arg" && continue
	    ;;
	  *-*-rhapsody* | *-*-darwin1.[012])
	    # Rhapsody C and math libraries are in the System framework
	    func_append deplibs " System.ltframework"
	    continue
	    ;;
	  *-*-sco3.2v5* | *-*-sco5v6*)
	    # Causes problems with __ctype
	    test X-lc = "X$arg" && continue
	    ;;
	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
	    # Compiler inserts libc in the correct place for threads to work
	    test X-lc = "X$arg" && continue
	    ;;
	  esac
	elif test X-lc_r = "X$arg"; then
	 case $host in
	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
	   # Do not include libc_r directly, use -pthread flag.
	   continue
	   ;;
	 esac
	fi
	func_append deplibs " $arg"
	continue
	;;

      -mllvm)
	prev=mllvm
	continue
	;;

      -module)
	module=yes
	continue
	;;

      # Tru64 UNIX uses -model [arg] to determine the layout of C++
      # classes, name mangling, and exception handling.
      # Darwin uses the -arch flag to determine output architecture.
      -model|-arch|-isysroot|--sysroot)
	func_append compiler_flags " $arg"
	func_append compile_command " $arg"
	func_append finalize_command " $arg"
	prev=xcompiler
	continue
	;;

      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
	func_append compiler_flags " $arg"
	func_append compile_command " $arg"
	func_append finalize_command " $arg"
	case "$new_inherited_linker_flags " in
	    *" $arg "*) ;;
	    * ) func_append new_inherited_linker_flags " $arg" ;;
	esac
	continue
	;;

      -multi_module)
	single_module=$wl-multi_module
	continue
	;;

      -no-fast-install)
	fast_install=no
	continue
	;;

      -no-install)
	case $host in
	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
	  # The PATH hackery in wrapper scripts is required on Windows
	  # and Darwin in order for the loader to find any dlls it needs.
	  func_warning "'-no-install' is ignored for $host"
	  func_warning "assuming '-no-fast-install' instead"
	  fast_install=no
	  ;;
	*) no_install=yes ;;
	esac
	continue
	;;

      -no-undefined)
	allow_undefined=no
	continue
	;;

      -objectlist)
	prev=objectlist
	continue
	;;

      -os2dllname)
	prev=os2dllname
	continue
	;;

      -o) prev=output ;;

      -precious-files-regex)
	prev=precious_regex
	continue
	;;

      -release)
	prev=release
	continue
	;;

      -rpath)
	prev=rpath
	continue
	;;

      -R)
	prev=xrpath
	continue
	;;

      -R*)
	func_stripname '-R' '' "$arg"
	dir=$func_stripname_result
	# We need an absolute path.
	case $dir in
	[\\/]* | [A-Za-z]:[\\/]*) ;;
	=*)
	  func_stripname '=' '' "$dir"
	  dir=$lt_sysroot$func_stripname_result
	  ;;
	*)
	  func_fatal_error "only absolute run-paths are allowed"
	  ;;
	esac
	case "$xrpath " in
	*" $dir "*) ;;
	*) func_append xrpath " $dir" ;;
	esac
	continue
	;;

      -shared)
	# The effects of -shared are defined in a previous loop.
	continue
	;;

      -shrext)
	prev=shrext
	continue
	;;

      -static | -static-libtool-libs)
	# The effects of -static are defined in a previous loop.
	# We used to do the same as -all-static on platforms that
	# didn't have a PIC flag, but the assumption that the effects
	# would be equivalent was wrong.  It would break on at least
	# Digital Unix and AIX.
	continue
	;;

      -thread-safe)
	thread_safe=yes
	continue
	;;

      -version-info)
	prev=vinfo
	continue
	;;

      -version-number)
	prev=vinfo
	vinfo_number=yes
	continue
	;;

      -weak)
        prev=weak
	continue
	;;

      -Wc,*)
	func_stripname '-Wc,' '' "$arg"
	args=$func_stripname_result
	arg=
	save_ifs=$IFS; IFS=,
	for flag in $args; do
	  IFS=$save_ifs
          func_quote_for_eval "$flag"
	  func_append arg " $func_quote_for_eval_result"
	  func_append compiler_flags " $func_quote_for_eval_result"
	done
	IFS=$save_ifs
	func_stripname ' ' '' "$arg"
	arg=$func_stripname_result
	;;

      -Wl,*)
	func_stripname '-Wl,' '' "$arg"
	args=$func_stripname_result
	arg=
	save_ifs=$IFS; IFS=,
	for flag in $args; do
	  IFS=$save_ifs
          func_quote_for_eval "$flag"
	  func_append arg " $wl$func_quote_for_eval_result"
	  func_append compiler_flags " $wl$func_quote_for_eval_result"
	  func_append linker_flags " $func_quote_for_eval_result"
	done
	IFS=$save_ifs
	func_stripname ' ' '' "$arg"
	arg=$func_stripname_result
	;;

      -Xcompiler)
	prev=xcompiler
	continue
	;;

      -Xlinker)
	prev=xlinker
	continue
	;;

      -XCClinker)
	prev=xcclinker
	continue
	;;

      # -msg_* for osf cc
      -msg_*)
	func_quote_for_eval "$arg"
	arg=$func_quote_for_eval_result
	;;

      # Flags to be passed through unchanged, with rationale:
      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
      # -r[0-9][0-9]*        specify processor for the SGI compiler
      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
      # +DA*, +DD*           enable 64-bit mode for the HP compiler
      # -q*                  compiler args for the IBM compiler
      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
      # -F/path              path to uninstalled frameworks, gcc on darwin
      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
      # -fstack-protector*   stack protector flags for GCC
      # @file                GCC response files
      # -tp=*                Portland pgcc target processor selection
      # --sysroot=*          for sysroot support
      # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
      # -specs=*             GCC specs files
      # -stdlib=*            select c++ std lib with clang
      # -fsanitize=*         Clang/GCC memory and address sanitizer
      # -fuse-ld=*           Linker select flags for GCC
      # -static-*            direct GCC to link specific libraries statically
      # -fcilkplus           Cilk Plus language extension features for C/C++
      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
      -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
        func_quote_for_eval "$arg"
	arg=$func_quote_for_eval_result
        func_append compile_command " $arg"
        func_append finalize_command " $arg"
        func_append compiler_flags " $arg"
        continue
        ;;

      -Z*)
        if test os2 = "`expr $host : '.*\(os2\)'`"; then
          # OS/2 uses -Zxxx to specify OS/2-specific options
	  compiler_flags="$compiler_flags $arg"
	  func_append compile_command " $arg"
	  func_append finalize_command " $arg"
	  case $arg in
	  -Zlinker | -Zstack)
	    prev=xcompiler
	    ;;
	  esac
	  continue
        else
	  # Otherwise treat like 'Some other compiler flag' below
	  func_quote_for_eval "$arg"
	  arg=$func_quote_for_eval_result
        fi
	;;

      # Some other compiler flag.
      -* | +*)
        func_quote_for_eval "$arg"
	arg=$func_quote_for_eval_result
	;;

      *.$objext)
	# A standard object.
	func_append objs " $arg"
	;;

      *.lo)
	# A libtool-controlled object.

	# Check to see that this really is a libtool object.
	if func_lalib_unsafe_p "$arg"; then
	  pic_object=
	  non_pic_object=

	  # Read the .lo file
	  func_source "$arg"

	  if test -z "$pic_object" ||
	     test -z "$non_pic_object" ||
	     test none = "$pic_object" &&
	     test none = "$non_pic_object"; then
	    func_fatal_error "cannot find name of object for '$arg'"
	  fi

	  # Extract subdirectory from the argument.
	  func_dirname "$arg" "/" ""
	  xdir=$func_dirname_result

	  test none = "$pic_object" || {
	    # Prepend the subdirectory the object is found in.
	    pic_object=$xdir$pic_object

	    if test dlfiles = "$prev"; then
	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
		func_append dlfiles " $pic_object"
		prev=
		continue
	      else
		# If libtool objects are unsupported, then we need to preload.
		prev=dlprefiles
	      fi
	    fi

	    # CHECK ME:  I think I busted this.  -Ossama
	    if test dlprefiles = "$prev"; then
	      # Preload the old-style object.
	      func_append dlprefiles " $pic_object"
	      prev=
	    fi

	    # A PIC object.
	    func_append libobjs " $pic_object"
	    arg=$pic_object
	  }

	  # Non-PIC object.
	  if test none != "$non_pic_object"; then
	    # Prepend the subdirectory the object is found in.
	    non_pic_object=$xdir$non_pic_object

	    # A standard non-PIC object
	    func_append non_pic_objects " $non_pic_object"
	    if test -z "$pic_object" || test none = "$pic_object"; then
	      arg=$non_pic_object
	    fi
	  else
	    # If the PIC object exists, use it instead.
	    # $xdir was prepended to $pic_object above.
	    non_pic_object=$pic_object
	    func_append non_pic_objects " $non_pic_object"
	  fi
	else
	  # Only an error if not doing a dry-run.
	  if $opt_dry_run; then
	    # Extract subdirectory from the argument.
	    func_dirname "$arg" "/" ""
	    xdir=$func_dirname_result

	    func_lo2o "$arg"
	    pic_object=$xdir$objdir/$func_lo2o_result
	    non_pic_object=$xdir$func_lo2o_result
	    func_append libobjs " $pic_object"
	    func_append non_pic_objects " $non_pic_object"
	  else
	    func_fatal_error "'$arg' is not a valid libtool object"
	  fi
	fi
	;;

      *.$libext)
	# An archive.
	func_append deplibs " $arg"
	func_append old_deplibs " $arg"
	continue
	;;

      *.la)
	# A libtool-controlled library.

	func_resolve_sysroot "$arg"
	if test dlfiles = "$prev"; then
	  # This library was specified with -dlopen.
	  func_append dlfiles " $func_resolve_sysroot_result"
	  prev=
	elif test dlprefiles = "$prev"; then
	  # The library was specified with -dlpreopen.
	  func_append dlprefiles " $func_resolve_sysroot_result"
	  prev=
	else
	  func_append deplibs " $func_resolve_sysroot_result"
	fi
	continue
	;;

      # Some other compiler argument.
      *)
	# Unknown arguments in both finalize_command and compile_command need
	# to be aesthetically quoted because they are evaled later.
	func_quote_for_eval "$arg"
	arg=$func_quote_for_eval_result
	;;
      esac # arg

      # Now actually substitute the argument into the commands.
      if test -n "$arg"; then
	func_append compile_command " $arg"
	func_append finalize_command " $arg"
      fi
    done # argument parsing loop

    test -n "$prev" && \
      func_fatal_help "the '$prevarg' option requires an argument"

    if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
      eval arg=\"$export_dynamic_flag_spec\"
      func_append compile_command " $arg"
      func_append finalize_command " $arg"
    fi

    oldlibs=
    # calculate the name of the file, without its directory
    func_basename "$output"
    outputname=$func_basename_result
    libobjs_save=$libobjs

    if test -n "$shlibpath_var"; then
      # get the directories listed in $shlibpath_var
      eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
    else
      shlib_search_path=
    fi
    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"

    # Definition is injected by LT_CONFIG during libtool generation.
    func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"

    func_dirname "$output" "/" ""
    output_objdir=$func_dirname_result$objdir
    func_to_tool_file "$output_objdir/"
    tool_output_objdir=$func_to_tool_file_result
    # Create the object directory.
    func_mkdir_p "$output_objdir"

    # Determine the type of output
    case $output in
    "")
      func_fatal_help "you must specify an output file"
      ;;
    *.$libext) linkmode=oldlib ;;
    *.lo | *.$objext) linkmode=obj ;;
    *.la) linkmode=lib ;;
    *) linkmode=prog ;; # Anything else should be a program.
    esac

    specialdeplibs=

    libs=
    # Find all interdependent deplibs by searching for libraries
    # that are linked more than once (e.g. -la -lb -la)
    for deplib in $deplibs; do
      if $opt_preserve_dup_deps; then
	case "$libs " in
	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
	esac
      fi
      func_append libs " $deplib"
    done

    if test lib = "$linkmode"; then
      libs="$predeps $libs $compiler_lib_search_path $postdeps"

      # Compute libraries that are listed more than once in $predeps
      # $postdeps and mark them as special (i.e., whose duplicates are
      # not to be eliminated).
      pre_post_deps=
      if $opt_duplicate_compiler_generated_deps; then
	for pre_post_dep in $predeps $postdeps; do
	  case "$pre_post_deps " in
	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
	  esac
	  func_append pre_post_deps " $pre_post_dep"
	done
      fi
      pre_post_deps=
    fi

    deplibs=
    newdependency_libs=
    newlib_search_path=
    need_relink=no # whether we're linking any uninstalled libtool libraries
    notinst_deplibs= # not-installed libtool libraries
    notinst_path= # paths that contain not-installed libtool libraries

    case $linkmode in
    lib)
	passes="conv dlpreopen link"
	for file in $dlfiles $dlprefiles; do
	  case $file in
	  *.la) ;;
	  *)
	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
	    ;;
	  esac
	done
	;;
    prog)
	compile_deplibs=
	finalize_deplibs=
	alldeplibs=false
	newdlfiles=
	newdlprefiles=
	passes="conv scan dlopen dlpreopen link"
	;;
    *)  passes="conv"
	;;
    esac

    for pass in $passes; do
      # The preopen pass in lib mode reverses $deplibs; put it back here
      # so that -L comes before libs that need it for instance...
      if test lib,link = "$linkmode,$pass"; then
	## FIXME: Find the place where the list is rebuilt in the wrong
	##        order, and fix it there properly
        tmp_deplibs=
	for deplib in $deplibs; do
	  tmp_deplibs="$deplib $tmp_deplibs"
	done
	deplibs=$tmp_deplibs
      fi

      if test lib,link = "$linkmode,$pass" ||
	 test prog,scan = "$linkmode,$pass"; then
	libs=$deplibs
	deplibs=
      fi
      if test prog = "$linkmode"; then
	case $pass in
	dlopen) libs=$dlfiles ;;
	dlpreopen) libs=$dlprefiles ;;
	link)
	  libs="$deplibs %DEPLIBS%"
	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
	  ;;
	esac
      fi
      if test lib,dlpreopen = "$linkmode,$pass"; then
	# Collect and forward deplibs of preopened libtool libs
	for lib in $dlprefiles; do
	  # Ignore non-libtool-libs
	  dependency_libs=
	  func_resolve_sysroot "$lib"
	  case $lib in
	  *.la)	func_source "$func_resolve_sysroot_result" ;;
	  esac

	  # Collect preopened libtool deplibs, except any this library
	  # has declared as weak libs
	  for deplib in $dependency_libs; do
	    func_basename "$deplib"
            deplib_base=$func_basename_result
	    case " $weak_libs " in
	    *" $deplib_base "*) ;;
	    *) func_append deplibs " $deplib" ;;
	    esac
	  done
	done
	libs=$dlprefiles
      fi
      if test dlopen = "$pass"; then
	# Collect dlpreopened libraries
	save_deplibs=$deplibs
	deplibs=
      fi

      for deplib in $libs; do
	lib=
	found=false
	case $deplib in
	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
	  if test prog,link = "$linkmode,$pass"; then
	    compile_deplibs="$deplib $compile_deplibs"
	    finalize_deplibs="$deplib $finalize_deplibs"
	  else
	    func_append compiler_flags " $deplib"
	    if test lib = "$linkmode"; then
		case "$new_inherited_linker_flags " in
		    *" $deplib "*) ;;
		    * ) func_append new_inherited_linker_flags " $deplib" ;;
		esac
	    fi
	  fi
	  continue
	  ;;
	-l*)
	  if test lib != "$linkmode" && test prog != "$linkmode"; then
	    func_warning "'-l' is ignored for archives/objects"
	    continue
	  fi
	  func_stripname '-l' '' "$deplib"
	  name=$func_stripname_result
	  if test lib = "$linkmode"; then
	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
	  else
	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
	  fi
	  for searchdir in $searchdirs; do
	    for search_ext in .la $std_shrext .so .a; do
	      # Search the libtool library
	      lib=$searchdir/lib$name$search_ext
	      if test -f "$lib"; then
		if test .la = "$search_ext"; then
		  found=:
		else
		  found=false
		fi
		break 2
	      fi
	    done
	  done
	  if $found; then
	    # deplib is a libtool library
	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
	    # We need to do some special things here, and not later.
	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then
	      case " $predeps $postdeps " in
	      *" $deplib "*)
		if func_lalib_p "$lib"; then
		  library_names=
		  old_library=
		  func_source "$lib"
		  for l in $old_library $library_names; do
		    ll=$l
		  done
		  if test "X$ll" = "X$old_library"; then # only static version available
		    found=false
		    func_dirname "$lib" "" "."
		    ladir=$func_dirname_result
		    lib=$ladir/$old_library
		    if test prog,link = "$linkmode,$pass"; then
		      compile_deplibs="$deplib $compile_deplibs"
		      finalize_deplibs="$deplib $finalize_deplibs"
		    else
		      deplibs="$deplib $deplibs"
		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
		    fi
		    continue
		  fi
		fi
		;;
	      *) ;;
	      esac
	    fi
	  else
	    # deplib doesn't seem to be a libtool library
	    if test prog,link = "$linkmode,$pass"; then
	      compile_deplibs="$deplib $compile_deplibs"
	      finalize_deplibs="$deplib $finalize_deplibs"
	    else
	      deplibs="$deplib $deplibs"
	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
	    fi
	    continue
	  fi
	  ;; # -l
	*.ltframework)
	  if test prog,link = "$linkmode,$pass"; then
	    compile_deplibs="$deplib $compile_deplibs"
	    finalize_deplibs="$deplib $finalize_deplibs"
	  else
	    deplibs="$deplib $deplibs"
	    if test lib = "$linkmode"; then
		case "$new_inherited_linker_flags " in
		    *" $deplib "*) ;;
		    * ) func_append new_inherited_linker_flags " $deplib" ;;
		esac
	    fi
	  fi
	  continue
	  ;;
	-L*)
	  case $linkmode in
	  lib)
	    deplibs="$deplib $deplibs"
	    test conv = "$pass" && continue
	    newdependency_libs="$deplib $newdependency_libs"
	    func_stripname '-L' '' "$deplib"
	    func_resolve_sysroot "$func_stripname_result"
	    func_append newlib_search_path " $func_resolve_sysroot_result"
	    ;;
	  prog)
	    if test conv = "$pass"; then
	      deplibs="$deplib $deplibs"
	      continue
	    fi
	    if test scan = "$pass"; then
	      deplibs="$deplib $deplibs"
	    else
	      compile_deplibs="$deplib $compile_deplibs"
	      finalize_deplibs="$deplib $finalize_deplibs"
	    fi
	    func_stripname '-L' '' "$deplib"
	    func_resolve_sysroot "$func_stripname_result"
	    func_append newlib_search_path " $func_resolve_sysroot_result"
	    ;;
	  *)
	    func_warning "'-L' is ignored for archives/objects"
	    ;;
	  esac # linkmode
	  continue
	  ;; # -L
	-R*)
	  if test link = "$pass"; then
	    func_stripname '-R' '' "$deplib"
	    func_resolve_sysroot "$func_stripname_result"
	    dir=$func_resolve_sysroot_result
	    # Make sure the xrpath contains only unique directories.
	    case "$xrpath " in
	    *" $dir "*) ;;
	    *) func_append xrpath " $dir" ;;
	    esac
	  fi
	  deplibs="$deplib $deplibs"
	  continue
	  ;;
	*.la)
	  func_resolve_sysroot "$deplib"
	  lib=$func_resolve_sysroot_result
	  ;;
	*.$libext)
	  if test conv = "$pass"; then
	    deplibs="$deplib $deplibs"
	    continue
	  fi
	  case $linkmode in
	  lib)
	    # Linking convenience modules into shared libraries is allowed,
	    # but linking other static libraries is non-portable.
	    case " $dlpreconveniencelibs " in
	    *" $deplib "*) ;;
	    *)
	      valid_a_lib=false
	      case $deplibs_check_method in
		match_pattern*)
		  set dummy $deplibs_check_method; shift
		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
		    | $EGREP "$match_pattern_regex" > /dev/null; then
		    valid_a_lib=:
		  fi
		;;
		pass_all)
		  valid_a_lib=:
		;;
	      esac
	      if $valid_a_lib; then
		echo
		$ECHO "*** Warning: Linking the shared library $output against the"
		$ECHO "*** static library $deplib is not portable!"
		deplibs="$deplib $deplibs"
	      else
		echo
		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
		echo "*** I have the capability to make that library automatically link in when"
		echo "*** you link to this library.  But I can only do this if you have a"
		echo "*** shared version of the library, which you do not appear to have"
		echo "*** because the file extensions .$libext of this argument makes me believe"
		echo "*** that it is just a static archive that I should not use here."
	      fi
	      ;;
	    esac
	    continue
	    ;;
	  prog)
	    if test link != "$pass"; then
	      deplibs="$deplib $deplibs"
	    else
	      compile_deplibs="$deplib $compile_deplibs"
	      finalize_deplibs="$deplib $finalize_deplibs"
	    fi
	    continue
	    ;;
	  esac # linkmode
	  ;; # *.$libext
	*.lo | *.$objext)
	  if test conv = "$pass"; then
	    deplibs="$deplib $deplibs"
	  elif test prog = "$linkmode"; then
	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
	      # If there is no dlopen support or we're linking statically,
	      # we need to preload.
	      func_append newdlprefiles " $deplib"
	      compile_deplibs="$deplib $compile_deplibs"
	      finalize_deplibs="$deplib $finalize_deplibs"
	    else
	      func_append newdlfiles " $deplib"
	    fi
	  fi
	  continue
	  ;;
	%DEPLIBS%)
	  alldeplibs=:
	  continue
	  ;;
	esac # case $deplib

	$found || test -f "$lib" \
	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"

	# Check to see that this really is a libtool archive.
	func_lalib_unsafe_p "$lib" \
	  || func_fatal_error "'$lib' is not a valid libtool archive"

	func_dirname "$lib" "" "."
	ladir=$func_dirname_result

	dlname=
	dlopen=
	dlpreopen=
	libdir=
	library_names=
	old_library=
	inherited_linker_flags=
	# If the library was installed with an old release of libtool,
	# it will not redefine variables installed, or shouldnotlink
	installed=yes
	shouldnotlink=no
	avoidtemprpath=


	# Read the .la file
	func_source "$lib"

	# Convert "-framework foo" to "foo.ltframework"
	if test -n "$inherited_linker_flags"; then
	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
	    case " $new_inherited_linker_flags " in
	      *" $tmp_inherited_linker_flag "*) ;;
	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
	    esac
	  done
	fi
	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
	if test lib,link = "$linkmode,$pass" ||
	   test prog,scan = "$linkmode,$pass" ||
	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then
	  test -n "$dlopen" && func_append dlfiles " $dlopen"
	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
	fi

	if test conv = "$pass"; then
	  # Only check for convenience libraries
	  deplibs="$lib $deplibs"
	  if test -z "$libdir"; then
	    if test -z "$old_library"; then
	      func_fatal_error "cannot find name of link library for '$lib'"
	    fi
	    # It is a libtool convenience library, so add in its objects.
	    func_append convenience " $ladir/$objdir/$old_library"
	    func_append old_convenience " $ladir/$objdir/$old_library"
	    tmp_libs=
	    for deplib in $dependency_libs; do
	      deplibs="$deplib $deplibs"
	      if $opt_preserve_dup_deps; then
		case "$tmp_libs " in
		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
		esac
	      fi
	      func_append tmp_libs " $deplib"
	    done
	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
	    func_fatal_error "'$lib' is not a convenience library"
	  fi
	  continue
	fi # $pass = conv


	# Get the name of the library we link against.
	linklib=
	if test -n "$old_library" &&
	   { test yes = "$prefer_static_libs" ||
	     test built,no = "$prefer_static_libs,$installed"; }; then
	  linklib=$old_library
	else
	  for l in $old_library $library_names; do
	    linklib=$l
	  done
	fi
	if test -z "$linklib"; then
	  func_fatal_error "cannot find name of link library for '$lib'"
	fi

	# This library was specified with -dlopen.
	if test dlopen = "$pass"; then
	  test -z "$libdir" \
	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
	  if test -z "$dlname" ||
	     test yes != "$dlopen_support" ||
	     test no = "$build_libtool_libs"
	  then
	    # If there is no dlname, no dlopen support or we're linking
	    # statically, we need to preload.  We also need to preload any
	    # dependent libraries so libltdl's deplib preloader doesn't
	    # bomb out in the load deplibs phase.
	    func_append dlprefiles " $lib $dependency_libs"
	  else
	    func_append newdlfiles " $lib"
	  fi
	  continue
	fi # $pass = dlopen

	# We need an absolute path.
	case $ladir in
	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
	*)
	  abs_ladir=`cd "$ladir" && pwd`
	  if test -z "$abs_ladir"; then
	    func_warning "cannot determine absolute directory name of '$ladir'"
	    func_warning "passing it literally to the linker, although it might fail"
	    abs_ladir=$ladir
	  fi
	  ;;
	esac
	func_basename "$lib"
	laname=$func_basename_result

	# Find the relevant object directory and library name.
	if test yes = "$installed"; then
	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
	    func_warning "library '$lib' was moved."
	    dir=$ladir
	    absdir=$abs_ladir
	    libdir=$abs_ladir
	  else
	    dir=$lt_sysroot$libdir
	    absdir=$lt_sysroot$libdir
	  fi
	  test yes = "$hardcode_automatic" && avoidtemprpath=yes
	else
	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
	    dir=$ladir
	    absdir=$abs_ladir
	    # Remove this search path later
	    func_append notinst_path " $abs_ladir"
	  else
	    dir=$ladir/$objdir
	    absdir=$abs_ladir/$objdir
	    # Remove this search path later
	    func_append notinst_path " $abs_ladir"
	  fi
	fi # $installed = yes
	func_stripname 'lib' '.la' "$laname"
	name=$func_stripname_result

	# This library was specified with -dlpreopen.
	if test dlpreopen = "$pass"; then
	  if test -z "$libdir" && test prog = "$linkmode"; then
	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
	  fi
	  case $host in
	    # special handling for platforms with PE-DLLs.
	    *cygwin* | *mingw* | *cegcc* )
	      # Linker will automatically link against shared library if both
	      # static and shared are present.  Therefore, ensure we extract
	      # symbols from the import library if a shared library is present
	      # (otherwise, the dlopen module name will be incorrect).  We do
	      # this by putting the import library name into $newdlprefiles.
	      # We recover the dlopen module name by 'saving' the la file
	      # name in a special purpose variable, and (later) extracting the
	      # dlname from the la file.
	      if test -n "$dlname"; then
	        func_tr_sh "$dir/$linklib"
	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
	        func_append newdlprefiles " $dir/$linklib"
	      else
	        func_append newdlprefiles " $dir/$old_library"
	        # Keep a list of preopened convenience libraries to check
	        # that they are being used correctly in the link pass.
	        test -z "$libdir" && \
	          func_append dlpreconveniencelibs " $dir/$old_library"
	      fi
	    ;;
	    * )
	      # Prefer using a static library (so that no silly _DYNAMIC symbols
	      # are required to link).
	      if test -n "$old_library"; then
	        func_append newdlprefiles " $dir/$old_library"
	        # Keep a list of preopened convenience libraries to check
	        # that they are being used correctly in the link pass.
	        test -z "$libdir" && \
	          func_append dlpreconveniencelibs " $dir/$old_library"
	      # Otherwise, use the dlname, so that lt_dlopen finds it.
	      elif test -n "$dlname"; then
	        func_append newdlprefiles " $dir/$dlname"
	      else
	        func_append newdlprefiles " $dir/$linklib"
	      fi
	    ;;
	  esac
	fi # $pass = dlpreopen

	if test -z "$libdir"; then
	  # Link the convenience library
	  if test lib = "$linkmode"; then
	    deplibs="$dir/$old_library $deplibs"
	  elif test prog,link = "$linkmode,$pass"; then
	    compile_deplibs="$dir/$old_library $compile_deplibs"
	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
	  else
	    deplibs="$lib $deplibs" # used for prog,scan pass
	  fi
	  continue
	fi


	if test prog = "$linkmode" && test link != "$pass"; then
	  func_append newlib_search_path " $ladir"
	  deplibs="$lib $deplibs"

	  linkalldeplibs=false
	  if test no != "$link_all_deplibs" || test -z "$library_names" ||
	     test no = "$build_libtool_libs"; then
	    linkalldeplibs=:
	  fi

	  tmp_libs=
	  for deplib in $dependency_libs; do
	    case $deplib in
	    -L*) func_stripname '-L' '' "$deplib"
	         func_resolve_sysroot "$func_stripname_result"
	         func_append newlib_search_path " $func_resolve_sysroot_result"
		 ;;
	    esac
	    # Need to link against all dependency_libs?
	    if $linkalldeplibs; then
	      deplibs="$deplib $deplibs"
	    else
	      # Need to hardcode shared library paths
	      # or/and link against static libraries
	      newdependency_libs="$deplib $newdependency_libs"
	    fi
	    if $opt_preserve_dup_deps; then
	      case "$tmp_libs " in
	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
	      esac
	    fi
	    func_append tmp_libs " $deplib"
	  done # for deplib
	  continue
	fi # $linkmode = prog...

	if test prog,link = "$linkmode,$pass"; then
	  if test -n "$library_names" &&
	     { { test no = "$prefer_static_libs" ||
	         test built,yes = "$prefer_static_libs,$installed"; } ||
	       test -z "$old_library"; }; then
	    # We need to hardcode the library path
	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
	      # Make sure the rpath contains only unique directories.
	      case $temp_rpath: in
	      *"$absdir:"*) ;;
	      *) func_append temp_rpath "$absdir:" ;;
	      esac
	    fi

	    # Hardcode the library path.
	    # Skip directories that are in the system default run-time
	    # search path.
	    case " $sys_lib_dlsearch_path " in
	    *" $absdir "*) ;;
	    *)
	      case "$compile_rpath " in
	      *" $absdir "*) ;;
	      *) func_append compile_rpath " $absdir" ;;
	      esac
	      ;;
	    esac
	    case " $sys_lib_dlsearch_path " in
	    *" $libdir "*) ;;
	    *)
	      case "$finalize_rpath " in
	      *" $libdir "*) ;;
	      *) func_append finalize_rpath " $libdir" ;;
	      esac
	      ;;
	    esac
	  fi # $linkmode,$pass = prog,link...

	  if $alldeplibs &&
	     { test pass_all = "$deplibs_check_method" ||
	       { test yes = "$build_libtool_libs" &&
		 test -n "$library_names"; }; }; then
	    # We only need to search for static libraries
	    continue
	  fi
	fi

	link_static=no # Whether the deplib will be linked statically
	use_static_libs=$prefer_static_libs
	if test built = "$use_static_libs" && test yes = "$installed"; then
	  use_static_libs=no
	fi
	if test -n "$library_names" &&
	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
	  case $host in
	  *cygwin* | *mingw* | *cegcc* | *os2*)
	      # No point in relinking DLLs because paths are not encoded
	      func_append notinst_deplibs " $lib"
	      need_relink=no
	    ;;
	  *)
	    if test no = "$installed"; then
	      func_append notinst_deplibs " $lib"
	      need_relink=yes
	    fi
	    ;;
	  esac
	  # This is a shared library

	  # Warn about portability, can't link against -module's on some
	  # systems (darwin).  Don't bleat about dlopened modules though!
	  dlopenmodule=
	  for dlpremoduletest in $dlprefiles; do
	    if test "X$dlpremoduletest" = "X$lib"; then
	      dlopenmodule=$dlpremoduletest
	      break
	    fi
	  done
	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
	    echo
	    if test prog = "$linkmode"; then
	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
	    else
	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
	    fi
	    $ECHO "*** $linklib is not portable!"
	  fi
	  if test lib = "$linkmode" &&
	     test yes = "$hardcode_into_libs"; then
	    # Hardcode the library path.
	    # Skip directories that are in the system default run-time
	    # search path.
	    case " $sys_lib_dlsearch_path " in
	    *" $absdir "*) ;;
	    *)
	      case "$compile_rpath " in
	      *" $absdir "*) ;;
	      *) func_append compile_rpath " $absdir" ;;
	      esac
	      ;;
	    esac
	    case " $sys_lib_dlsearch_path " in
	    *" $libdir "*) ;;
	    *)
	      case "$finalize_rpath " in
	      *" $libdir "*) ;;
	      *) func_append finalize_rpath " $libdir" ;;
	      esac
	      ;;
	    esac
	  fi

	  if test -n "$old_archive_from_expsyms_cmds"; then
	    # figure out the soname
	    set dummy $library_names
	    shift
	    realname=$1
	    shift
	    libname=`eval "\\$ECHO \"$libname_spec\""`
	    # use dlname if we got it. it's perfectly good, no?
	    if test -n "$dlname"; then
	      soname=$dlname
	    elif test -n "$soname_spec"; then
	      # bleh windows
	      case $host in
	      *cygwin* | mingw* | *cegcc* | *os2*)
	        func_arith $current - $age
		major=$func_arith_result
		versuffix=-$major
		;;
	      esac
	      eval soname=\"$soname_spec\"
	    else
	      soname=$realname
	    fi

	    # Make a new name for the extract_expsyms_cmds to use
	    soroot=$soname
	    func_basename "$soroot"
	    soname=$func_basename_result
	    func_stripname 'lib' '.dll' "$soname"
	    newlib=libimp-$func_stripname_result.a

	    # If the library has no export list, then create one now
	    if test -f "$output_objdir/$soname-def"; then :
	    else
	      func_verbose "extracting exported symbol list from '$soname'"
	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
	    fi

	    # Create $newlib
	    if test -f "$output_objdir/$newlib"; then :; else
	      func_verbose "generating import library for '$soname'"
	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
	    fi
	    # make sure the library variables are pointing to the new library
	    dir=$output_objdir
	    linklib=$newlib
	  fi # test -n "$old_archive_from_expsyms_cmds"

	  if test prog = "$linkmode" || test relink != "$opt_mode"; then
	    add_shlibpath=
	    add_dir=
	    add=
	    lib_linked=yes
	    case $hardcode_action in
	    immediate | unsupported)
	      if test no = "$hardcode_direct"; then
		add=$dir/$linklib
		case $host in
		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
		    *-*-unixware7*) add_dir=-L$dir ;;
		  *-*-darwin* )
		    # if the lib is a (non-dlopened) module then we cannot
		    # link against it, someone is ignoring the earlier warnings
		    if /usr/bin/file -L $add 2> /dev/null |
			 $GREP ": [^:]* bundle" >/dev/null; then
		      if test "X$dlopenmodule" != "X$lib"; then
			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
			if test -z "$old_library"; then
			  echo
			  echo "*** And there doesn't seem to be a static archive available"
			  echo "*** The link will probably fail, sorry"
			else
			  add=$dir/$old_library
			fi
		      elif test -n "$old_library"; then
			add=$dir/$old_library
		      fi
		    fi
		esac
	      elif test no = "$hardcode_minus_L"; then
		case $host in
		*-*-sunos*) add_shlibpath=$dir ;;
		esac
		add_dir=-L$dir
		add=-l$name
	      elif test no = "$hardcode_shlibpath_var"; then
		add_shlibpath=$dir
		add=-l$name
	      else
		lib_linked=no
	      fi
	      ;;
	    relink)
	      if test yes = "$hardcode_direct" &&
	         test no = "$hardcode_direct_absolute"; then
		add=$dir/$linklib
	      elif test yes = "$hardcode_minus_L"; then
		add_dir=-L$absdir
		# Try looking first in the location we're being installed to.
		if test -n "$inst_prefix_dir"; then
		  case $libdir in
		    [\\/]*)
		      func_append add_dir " -L$inst_prefix_dir$libdir"
		      ;;
		  esac
		fi
		add=-l$name
	      elif test yes = "$hardcode_shlibpath_var"; then
		add_shlibpath=$dir
		add=-l$name
	      else
		lib_linked=no
	      fi
	      ;;
	    *) lib_linked=no ;;
	    esac

	    if test yes != "$lib_linked"; then
	      func_fatal_configuration "unsupported hardcode properties"
	    fi

	    if test -n "$add_shlibpath"; then
	      case :$compile_shlibpath: in
	      *":$add_shlibpath:"*) ;;
	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
	      esac
	    fi
	    if test prog = "$linkmode"; then
	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
	    else
	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
	      test -n "$add" && deplibs="$add $deplibs"
	      if test yes != "$hardcode_direct" &&
		 test yes != "$hardcode_minus_L" &&
		 test yes = "$hardcode_shlibpath_var"; then
		case :$finalize_shlibpath: in
		*":$libdir:"*) ;;
		*) func_append finalize_shlibpath "$libdir:" ;;
		esac
	      fi
	    fi
	  fi

	  if test prog = "$linkmode" || test relink = "$opt_mode"; then
	    add_shlibpath=
	    add_dir=
	    add=
	    # Finalize command for both is simple: just hardcode it.
	    if test yes = "$hardcode_direct" &&
	       test no = "$hardcode_direct_absolute"; then
	      add=$libdir/$linklib
	    elif test yes = "$hardcode_minus_L"; then
	      add_dir=-L$libdir
	      add=-l$name
	    elif test yes = "$hardcode_shlibpath_var"; then
	      case :$finalize_shlibpath: in
	      *":$libdir:"*) ;;
	      *) func_append finalize_shlibpath "$libdir:" ;;
	      esac
	      add=-l$name
	    elif test yes = "$hardcode_automatic"; then
	      if test -n "$inst_prefix_dir" &&
		 test -f "$inst_prefix_dir$libdir/$linklib"; then
		add=$inst_prefix_dir$libdir/$linklib
	      else
		add=$libdir/$linklib
	      fi
	    else
	      # We cannot seem to hardcode it, guess we'll fake it.
	      add_dir=-L$libdir
	      # Try looking first in the location we're being installed to.
	      if test -n "$inst_prefix_dir"; then
		case $libdir in
		  [\\/]*)
		    func_append add_dir " -L$inst_prefix_dir$libdir"
		    ;;
		esac
	      fi
	      add=-l$name
	    fi

	    if test prog = "$linkmode"; then
	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
	    else
	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
	      test -n "$add" && deplibs="$add $deplibs"
	    fi
	  fi
	elif test prog = "$linkmode"; then
	  # Here we assume that one of hardcode_direct or hardcode_minus_L
	  # is not unsupported.  This is valid on all known static and
	  # shared platforms.
	  if test unsupported != "$hardcode_direct"; then
	    test -n "$old_library" && linklib=$old_library
	    compile_deplibs="$dir/$linklib $compile_deplibs"
	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
	  else
	    compile_deplibs="-l$name -L$dir $compile_deplibs"
	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
	  fi
	elif test yes = "$build_libtool_libs"; then
	  # Not a shared library
	  if test pass_all != "$deplibs_check_method"; then
	    # We're trying link a shared library against a static one
	    # but the system doesn't support it.

	    # Just print a warning and add the library to dependency_libs so
	    # that the program can be linked against the static library.
	    echo
	    $ECHO "*** Warning: This system cannot link to static lib archive $lib."
	    echo "*** I have the capability to make that library automatically link in when"
	    echo "*** you link to this library.  But I can only do this if you have a"
	    echo "*** shared version of the library, which you do not appear to have."
	    if test yes = "$module"; then
	      echo "*** But as you try to build a module library, libtool will still create "
	      echo "*** a static module, that should work as long as the dlopening application"
	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
	      if test -z "$global_symbol_pipe"; then
		echo
		echo "*** However, this would only work if libtool was able to extract symbol"
		echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
		echo "*** not find such a program.  So, this module is probably useless."
		echo "*** 'nm' from GNU binutils and a full rebuild may help."
	      fi
	      if test no = "$build_old_libs"; then
		build_libtool_libs=module
		build_old_libs=yes
	      else
		build_libtool_libs=no
	      fi
	    fi
	  else
	    deplibs="$dir/$old_library $deplibs"
	    link_static=yes
	  fi
	fi # link shared/static library?

	if test lib = "$linkmode"; then
	  if test -n "$dependency_libs" &&
	     { test yes != "$hardcode_into_libs" ||
	       test yes = "$build_old_libs" ||
	       test yes = "$link_static"; }; then
	    # Extract -R from dependency_libs
	    temp_deplibs=
	    for libdir in $dependency_libs; do
	      case $libdir in
	      -R*) func_stripname '-R' '' "$libdir"
	           temp_xrpath=$func_stripname_result
		   case " $xrpath " in
		   *" $temp_xrpath "*) ;;
		   *) func_append xrpath " $temp_xrpath";;
		   esac;;
	      *) func_append temp_deplibs " $libdir";;
	      esac
	    done
	    dependency_libs=$temp_deplibs
	  fi

	  func_append newlib_search_path " $absdir"
	  # Link against this library
	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
	  # ... and its dependency_libs
	  tmp_libs=
	  for deplib in $dependency_libs; do
	    newdependency_libs="$deplib $newdependency_libs"
	    case $deplib in
              -L*) func_stripname '-L' '' "$deplib"
                   func_resolve_sysroot "$func_stripname_result";;
              *) func_resolve_sysroot "$deplib" ;;
            esac
	    if $opt_preserve_dup_deps; then
	      case "$tmp_libs " in
	      *" $func_resolve_sysroot_result "*)
                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
	      esac
	    fi
	    func_append tmp_libs " $func_resolve_sysroot_result"
	  done

	  if test no != "$link_all_deplibs"; then
	    # Add the search paths of all dependency libraries
	    for deplib in $dependency_libs; do
	      path=
	      case $deplib in
	      -L*) path=$deplib ;;
	      *.la)
	        func_resolve_sysroot "$deplib"
	        deplib=$func_resolve_sysroot_result
	        func_dirname "$deplib" "" "."
		dir=$func_dirname_result
		# We need an absolute path.
		case $dir in
		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
		*)
		  absdir=`cd "$dir" && pwd`
		  if test -z "$absdir"; then
		    func_warning "cannot determine absolute directory name of '$dir'"
		    absdir=$dir
		  fi
		  ;;
		esac
		if $GREP "^installed=no" $deplib > /dev/null; then
		case $host in
		*-*-darwin*)
		  depdepl=
		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
		  if test -n "$deplibrary_names"; then
		    for tmp in $deplibrary_names; do
		      depdepl=$tmp
		    done
		    if test -f "$absdir/$objdir/$depdepl"; then
		      depdepl=$absdir/$objdir/$depdepl
		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
                      if test -z "$darwin_install_name"; then
                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
                      fi
		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
		      path=
		    fi
		  fi
		  ;;
		*)
		  path=-L$absdir/$objdir
		  ;;
		esac
		else
		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
		  test -z "$libdir" && \
		    func_fatal_error "'$deplib' is not a valid libtool archive"
		  test "$absdir" != "$libdir" && \
		    func_warning "'$deplib' seems to be moved"

		  path=-L$absdir
		fi
		;;
	      esac
	      case " $deplibs " in
	      *" $path "*) ;;
	      *) deplibs="$path $deplibs" ;;
	      esac
	    done
	  fi # link_all_deplibs != no
	fi # linkmode = lib
      done # for deplib in $libs
      if test link = "$pass"; then
	if test prog = "$linkmode"; then
	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
	else
	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
	fi
      fi
      dependency_libs=$newdependency_libs
      if test dlpreopen = "$pass"; then
	# Link the dlpreopened libraries before other libraries
	for deplib in $save_deplibs; do
	  deplibs="$deplib $deplibs"
	done
      fi
      if test dlopen != "$pass"; then
	test conv = "$pass" || {
	  # Make sure lib_search_path contains only unique directories.
	  lib_search_path=
	  for dir in $newlib_search_path; do
	    case "$lib_search_path " in
	    *" $dir "*) ;;
	    *) func_append lib_search_path " $dir" ;;
	    esac
	  done
	  newlib_search_path=
	}

	if test prog,link = "$linkmode,$pass"; then
	  vars="compile_deplibs finalize_deplibs"
	else
	  vars=deplibs
	fi
	for var in $vars dependency_libs; do
	  # Add libraries to $var in reverse order
	  eval tmp_libs=\"\$$var\"
	  new_libs=
	  for deplib in $tmp_libs; do
	    # FIXME: Pedantically, this is the right thing to do, so
	    #        that some nasty dependency loop isn't accidentally
	    #        broken:
	    #new_libs="$deplib $new_libs"
	    # Pragmatically, this seems to cause very few problems in
	    # practice:
	    case $deplib in
	    -L*) new_libs="$deplib $new_libs" ;;
	    -R*) ;;
	    *)
	      # And here is the reason: when a library appears more
	      # than once as an explicit dependence of a library, or
	      # is implicitly linked in more than once by the
	      # compiler, it is considered special, and multiple
	      # occurrences thereof are not removed.  Compare this
	      # with having the same library being listed as a
	      # dependency of multiple other libraries: in this case,
	      # we know (pedantically, we assume) the library does not
	      # need to be listed more than once, so we keep only the
	      # last copy.  This is not always right, but it is rare
	      # enough that we require users that really mean to play
	      # such unportable linking tricks to link the library
	      # using -Wl,-lname, so that libtool does not consider it
	      # for duplicate removal.
	      case " $specialdeplibs " in
	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
	      *)
		case " $new_libs " in
		*" $deplib "*) ;;
		*) new_libs="$deplib $new_libs" ;;
		esac
		;;
	      esac
	      ;;
	    esac
	  done
	  tmp_libs=
	  for deplib in $new_libs; do
	    case $deplib in
	    -L*)
	      case " $tmp_libs " in
	      *" $deplib "*) ;;
	      *) func_append tmp_libs " $deplib" ;;
	      esac
	      ;;
	    *) func_append tmp_libs " $deplib" ;;
	    esac
	  done
	  eval $var=\"$tmp_libs\"
	done # for var
      fi

      # Add Sun CC postdeps if required:
      test CXX = "$tagname" && {
        case $host_os in
        linux*)
          case `$CC -V 2>&1 | sed 5q` in
          *Sun\ C*) # Sun C++ 5.9
            func_suncc_cstd_abi

            if test no != "$suncc_use_cstd_abi"; then
              func_append postdeps ' -library=Cstd -library=Crun'
            fi
            ;;
          esac
          ;;

        solaris*)
          func_cc_basename "$CC"
          case $func_cc_basename_result in
          CC* | sunCC*)
            func_suncc_cstd_abi

            if test no != "$suncc_use_cstd_abi"; then
              func_append postdeps ' -library=Cstd -library=Crun'
            fi
            ;;
          esac
          ;;
        esac
      }

      # Last step: remove runtime libs from dependency_libs
      # (they stay in deplibs)
      tmp_libs=
      for i in $dependency_libs; do
	case " $predeps $postdeps $compiler_lib_search_path " in
	*" $i "*)
	  i=
	  ;;
	esac
	if test -n "$i"; then
	  func_append tmp_libs " $i"
	fi
      done
      dependency_libs=$tmp_libs
    done # for pass
    if test prog = "$linkmode"; then
      dlfiles=$newdlfiles
    fi
    if test prog = "$linkmode" || test lib = "$linkmode"; then
      dlprefiles=$newdlprefiles
    fi

    case $linkmode in
    oldlib)
      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
	func_warning "'-dlopen' is ignored for archives"
      fi

      case " $deplibs" in
      *\ -l* | *\ -L*)
	func_warning "'-l' and '-L' are ignored for archives" ;;
      esac

      test -n "$rpath" && \
	func_warning "'-rpath' is ignored for archives"

      test -n "$xrpath" && \
	func_warning "'-R' is ignored for archives"

      test -n "$vinfo" && \
	func_warning "'-version-info/-version-number' is ignored for archives"

      test -n "$release" && \
	func_warning "'-release' is ignored for archives"

      test -n "$export_symbols$export_symbols_regex" && \
	func_warning "'-export-symbols' is ignored for archives"

      # Now set the variables for building old libraries.
      build_libtool_libs=no
      oldlibs=$output
      func_append objs "$old_deplibs"
      ;;

    lib)
      # Make sure we only generate libraries of the form 'libNAME.la'.
      case $outputname in
      lib*)
	func_stripname 'lib' '.la' "$outputname"
	name=$func_stripname_result
	eval shared_ext=\"$shrext_cmds\"
	eval libname=\"$libname_spec\"
	;;
      *)
	test no = "$module" \
	  && func_fatal_help "libtool library '$output' must begin with 'lib'"

	if test no != "$need_lib_prefix"; then
	  # Add the "lib" prefix for modules if required
	  func_stripname '' '.la' "$outputname"
	  name=$func_stripname_result
	  eval shared_ext=\"$shrext_cmds\"
	  eval libname=\"$libname_spec\"
	else
	  func_stripname '' '.la' "$outputname"
	  libname=$func_stripname_result
	fi
	;;
      esac

      if test -n "$objs"; then
	if test pass_all != "$deplibs_check_method"; then
	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
	else
	  echo
	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
	  $ECHO "*** objects $objs is not portable!"
	  func_append libobjs " $objs"
	fi
      fi

      test no = "$dlself" \
	|| func_warning "'-dlopen self' is ignored for libtool libraries"

      set dummy $rpath
      shift
      test 1 -lt "$#" \
	&& func_warning "ignoring multiple '-rpath's for a libtool library"

      install_libdir=$1

      oldlibs=
      if test -z "$rpath"; then
	if test yes = "$build_libtool_libs"; then
	  # Building a libtool convenience library.
	  # Some compilers have problems with a '.al' extension so
	  # convenience libraries should have the same extension an
	  # archive normally would.
	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
	  build_libtool_libs=convenience
	  build_old_libs=yes
	fi

	test -n "$vinfo" && \
	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"

	test -n "$release" && \
	  func_warning "'-release' is ignored for convenience libraries"
      else

	# Parse the version information argument.
	save_ifs=$IFS; IFS=:
	set dummy $vinfo 0 0 0
	shift
	IFS=$save_ifs

	test -n "$7" && \
	  func_fatal_help "too many parameters to '-version-info'"

	# convert absolute version numbers to libtool ages
	# this retains compatibility with .la files and attempts
	# to make the code below a bit more comprehensible

	case $vinfo_number in
	yes)
	  number_major=$1
	  number_minor=$2
	  number_revision=$3
	  #
	  # There are really only two kinds -- those that
	  # use the current revision as the major version
	  # and those that subtract age and use age as
	  # a minor version.  But, then there is irix
	  # that has an extra 1 added just for fun
	  #
	  case $version_type in
	  # correct linux to gnu/linux during the next big refactor
	  darwin|freebsd-elf|linux|osf|windows|none)
	    func_arith $number_major + $number_minor
	    current=$func_arith_result
	    age=$number_minor
	    revision=$number_revision
	    ;;
	  freebsd-aout|qnx|sunos)
	    current=$number_major
	    revision=$number_minor
	    age=0
	    ;;
	  irix|nonstopux)
	    func_arith $number_major + $number_minor
	    current=$func_arith_result
	    age=$number_minor
	    revision=$number_minor
	    lt_irix_increment=no
	    ;;
	  *)
	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
	    ;;
	  esac
	  ;;
	no)
	  current=$1
	  revision=$2
	  age=$3
	  ;;
	esac

	# Check that each of the things are valid numbers.
	case $current in
	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
	*)
	  func_error "CURRENT '$current' must be a nonnegative integer"
	  func_fatal_error "'$vinfo' is not valid version information"
	  ;;
	esac

	case $revision in
	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
	*)
	  func_error "REVISION '$revision' must be a nonnegative integer"
	  func_fatal_error "'$vinfo' is not valid version information"
	  ;;
	esac

	case $age in
	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
	*)
	  func_error "AGE '$age' must be a nonnegative integer"
	  func_fatal_error "'$vinfo' is not valid version information"
	  ;;
	esac

	if test "$age" -gt "$current"; then
	  func_error "AGE '$age' is greater than the current interface number '$current'"
	  func_fatal_error "'$vinfo' is not valid version information"
	fi

	# Calculate the version variables.
	major=
	versuffix=
	verstring=
	case $version_type in
	none) ;;

	darwin)
	  # Like Linux, but with the current version available in
	  # verstring for coding it into the library header
	  func_arith $current - $age
	  major=.$func_arith_result
	  versuffix=$major.$age.$revision
	  # Darwin ld doesn't like 0 for these options...
	  func_arith $current + 1
	  minor_current=$func_arith_result
	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
          # On Darwin other compilers
          case $CC in
              nagfor*)
                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
                  ;;
              *)
                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
                  ;;
          esac
	  ;;

	freebsd-aout)
	  major=.$current
	  versuffix=.$current.$revision
	  ;;

	freebsd-elf)
	  func_arith $current - $age
	  major=.$func_arith_result
	  versuffix=$major.$age.$revision
	  ;;

	irix | nonstopux)
	  if test no = "$lt_irix_increment"; then
	    func_arith $current - $age
	  else
	    func_arith $current - $age + 1
	  fi
	  major=$func_arith_result

	  case $version_type in
	    nonstopux) verstring_prefix=nonstopux ;;
	    *)         verstring_prefix=sgi ;;
	  esac
	  verstring=$verstring_prefix$major.$revision

	  # Add in all the interfaces that we are compatible with.
	  loop=$revision
	  while test 0 -ne "$loop"; do
	    func_arith $revision - $loop
	    iface=$func_arith_result
	    func_arith $loop - 1
	    loop=$func_arith_result
	    verstring=$verstring_prefix$major.$iface:$verstring
	  done

	  # Before this point, $major must not contain '.'.
	  major=.$major
	  versuffix=$major.$revision
	  ;;

	linux) # correct to gnu/linux during the next big refactor
	  func_arith $current - $age
	  major=.$func_arith_result
	  versuffix=$major.$age.$revision
	  ;;

	osf)
	  func_arith $current - $age
	  major=.$func_arith_result
	  versuffix=.$current.$age.$revision
	  verstring=$current.$age.$revision

	  # Add in all the interfaces that we are compatible with.
	  loop=$age
	  while test 0 -ne "$loop"; do
	    func_arith $current - $loop
	    iface=$func_arith_result
	    func_arith $loop - 1
	    loop=$func_arith_result
	    verstring=$verstring:$iface.0
	  done

	  # Make executables depend on our current version.
	  func_append verstring ":$current.0"
	  ;;

	qnx)
	  major=.$current
	  versuffix=.$current
	  ;;

	sco)
	  major=.$current
	  versuffix=.$current
	  ;;

	sunos)
	  major=.$current
	  versuffix=.$current.$revision
	  ;;

	windows)
	  # Use '-' rather than '.', since we only want one
	  # extension on DOS 8.3 file systems.
	  func_arith $current - $age
	  major=$func_arith_result
	  versuffix=-$major
	  ;;

	*)
	  func_fatal_configuration "unknown library version type '$version_type'"
	  ;;
	esac

	# Clear the version info if we defaulted, and they specified a release.
	if test -z "$vinfo" && test -n "$release"; then
	  major=
	  case $version_type in
	  darwin)
	    # we can't check for "0.0" in archive_cmds due to quoting
	    # problems, so we reset it completely
	    verstring=
	    ;;
	  *)
	    verstring=0.0
	    ;;
	  esac
	  if test no = "$need_version"; then
	    versuffix=
	  else
	    versuffix=.0.0
	  fi
	fi

	# Remove version info from name if versioning should be avoided
	if test yes,no = "$avoid_version,$need_version"; then
	  major=
	  versuffix=
	  verstring=
	fi

	# Check to see if the archive will have undefined symbols.
	if test yes = "$allow_undefined"; then
	  if test unsupported = "$allow_undefined_flag"; then
	    if test yes = "$build_old_libs"; then
	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"
	      build_libtool_libs=no
	    else
	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"
	    fi
	  fi
	else
	  # Don't allow undefined symbols.
	  allow_undefined_flag=$no_undefined_flag
	fi

      fi

      func_generate_dlsyms "$libname" "$libname" :
      func_append libobjs " $symfileobj"
      test " " = "$libobjs" && libobjs=

      if test relink != "$opt_mode"; then
	# Remove our outputs, but don't remove object files since they
	# may have been created when compiling PIC objects.
	removelist=
	tempremovelist=`$ECHO "$output_objdir/*"`
	for p in $tempremovelist; do
	  case $p in
	    *.$objext | *.gcno)
	       ;;
	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
	       if test -n "$precious_files_regex"; then
		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
		 then
		   continue
		 fi
	       fi
	       func_append removelist " $p"
	       ;;
	    *) ;;
	  esac
	done
	test -n "$removelist" && \
	  func_show_eval "${RM}r \$removelist"
      fi

      # Now set the variables for building old libraries.
      if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
	func_append oldlibs " $output_objdir/$libname.$libext"

	# Transform .lo files to .o files.
	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
      fi

      # Eliminate all temporary directories.
      #for path in $notinst_path; do
      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
      #done

      if test -n "$xrpath"; then
	# If the user specified any rpath flags, then add them.
	temp_xrpath=
	for libdir in $xrpath; do
	  func_replace_sysroot "$libdir"
	  func_append temp_xrpath " -R$func_replace_sysroot_result"
	  case "$finalize_rpath " in
	  *" $libdir "*) ;;
	  *) func_append finalize_rpath " $libdir" ;;
	  esac
	done
	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
	  dependency_libs="$temp_xrpath $dependency_libs"
	fi
      fi

      # Make sure dlfiles contains only unique files that won't be dlpreopened
      old_dlfiles=$dlfiles
      dlfiles=
      for lib in $old_dlfiles; do
	case " $dlprefiles $dlfiles " in
	*" $lib "*) ;;
	*) func_append dlfiles " $lib" ;;
	esac
      done

      # Make sure dlprefiles contains only unique files
      old_dlprefiles=$dlprefiles
      dlprefiles=
      for lib in $old_dlprefiles; do
	case "$dlprefiles " in
	*" $lib "*) ;;
	*) func_append dlprefiles " $lib" ;;
	esac
      done

      if test yes = "$build_libtool_libs"; then
	if test -n "$rpath"; then
	  case $host in
	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
	    # these systems don't actually have a c library (as such)!
	    ;;
	  *-*-rhapsody* | *-*-darwin1.[012])
	    # Rhapsody C library is in the System framework
	    func_append deplibs " System.ltframework"
	    ;;
	  *-*-netbsd*)
	    # Don't link with libc until the a.out ld.so is fixed.
	    ;;
	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
	    # Do not include libc due to us having libc/libc_r.
	    ;;
	  *-*-sco3.2v5* | *-*-sco5v6*)
	    # Causes problems with __ctype
	    ;;
	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
	    # Compiler inserts libc in the correct place for threads to work
	    ;;
	  *)
	    # Add libc to deplibs on all other systems if necessary.
	    if test yes = "$build_libtool_need_lc"; then
	      func_append deplibs " -lc"
	    fi
	    ;;
	  esac
	fi

	# Transform deplibs into only deplibs that can be linked in shared.
	name_save=$name
	libname_save=$libname
	release_save=$release
	versuffix_save=$versuffix
	major_save=$major
	# I'm not sure if I'm treating the release correctly.  I think
	# release should show up in the -l (ie -lgmp5) so we don't want to
	# add it in twice.  Is that correct?
	release=
	versuffix=
	major=
	newdeplibs=
	droppeddeps=no
	case $deplibs_check_method in
	pass_all)
	  # Don't check for shared/static.  Everything works.
	  # This might be a little naive.  We might want to check
	  # whether the library exists or not.  But this is on
	  # osf3 & osf4 and I'm not really sure... Just
	  # implementing what was already the behavior.
	  newdeplibs=$deplibs
	  ;;
	test_compile)
	  # This code stresses the "libraries are programs" paradigm to its
	  # limits. Maybe even breaks it.  We compile a program, linking it
	  # against the deplibs as a proxy for the library.  Then we can check
	  # whether they linked in statically or dynamically with ldd.
	  $opt_dry_run || $RM conftest.c
	  cat > conftest.c </dev/null`
		    $nocaseglob
		  else
		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
		  fi
		  for potent_lib in $potential_libs; do
		      # Follow soft links.
		      if ls -lLd "$potent_lib" 2>/dev/null |
			 $GREP " -> " >/dev/null; then
			continue
		      fi
		      # The statement above tries to avoid entering an
		      # endless loop below, in case of cyclic links.
		      # We might still enter an endless loop, since a link
		      # loop can be closed while we follow links,
		      # but so what?
		      potlib=$potent_lib
		      while test -h "$potlib" 2>/dev/null; do
			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
			case $potliblink in
			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
			esac
		      done
		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
			 $SED -e 10q |
			 $EGREP "$file_magic_regex" > /dev/null; then
			func_append newdeplibs " $a_deplib"
			a_deplib=
			break 2
		      fi
		  done
		done
	      fi
	      if test -n "$a_deplib"; then
		droppeddeps=yes
		echo
		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
		echo "*** I have the capability to make that library automatically link in when"
		echo "*** you link to this library.  But I can only do this if you have a"
		echo "*** shared version of the library, which you do not appear to have"
		echo "*** because I did check the linker path looking for a file starting"
		if test -z "$potlib"; then
		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
		else
		  $ECHO "*** with $libname and none of the candidates passed a file format test"
		  $ECHO "*** using a file magic. Last file checked: $potlib"
		fi
	      fi
	      ;;
	    *)
	      # Add a -L argument.
	      func_append newdeplibs " $a_deplib"
	      ;;
	    esac
	  done # Gone through all deplibs.
	  ;;
	match_pattern*)
	  set dummy $deplibs_check_method; shift
	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
	  for a_deplib in $deplibs; do
	    case $a_deplib in
	    -l*)
	      func_stripname -l '' "$a_deplib"
	      name=$func_stripname_result
	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
		case " $predeps $postdeps " in
		*" $a_deplib "*)
		  func_append newdeplibs " $a_deplib"
		  a_deplib=
		  ;;
		esac
	      fi
	      if test -n "$a_deplib"; then
		libname=`eval "\\$ECHO \"$libname_spec\""`
		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
		  for potent_lib in $potential_libs; do
		    potlib=$potent_lib # see symlink-check above in file_magic test
		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
		       $EGREP "$match_pattern_regex" > /dev/null; then
		      func_append newdeplibs " $a_deplib"
		      a_deplib=
		      break 2
		    fi
		  done
		done
	      fi
	      if test -n "$a_deplib"; then
		droppeddeps=yes
		echo
		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
		echo "*** I have the capability to make that library automatically link in when"
		echo "*** you link to this library.  But I can only do this if you have a"
		echo "*** shared version of the library, which you do not appear to have"
		echo "*** because I did check the linker path looking for a file starting"
		if test -z "$potlib"; then
		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
		else
		  $ECHO "*** with $libname and none of the candidates passed a file format test"
		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
		fi
	      fi
	      ;;
	    *)
	      # Add a -L argument.
	      func_append newdeplibs " $a_deplib"
	      ;;
	    esac
	  done # Gone through all deplibs.
	  ;;
	none | unknown | *)
	  newdeplibs=
	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
	    for i in $predeps $postdeps; do
	      # can't use Xsed below, because $i might contain '/'
	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
	    done
	  fi
	  case $tmp_deplibs in
	  *[!\	\ ]*)
	    echo
	    if test none = "$deplibs_check_method"; then
	      echo "*** Warning: inter-library dependencies are not supported in this platform."
	    else
	      echo "*** Warning: inter-library dependencies are not known to be supported."
	    fi
	    echo "*** All declared inter-library dependencies are being dropped."
	    droppeddeps=yes
	    ;;
	  esac
	  ;;
	esac
	versuffix=$versuffix_save
	major=$major_save
	release=$release_save
	libname=$libname_save
	name=$name_save

	case $host in
	*-*-rhapsody* | *-*-darwin1.[012])
	  # On Rhapsody replace the C library with the System framework
	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
	  ;;
	esac

	if test yes = "$droppeddeps"; then
	  if test yes = "$module"; then
	    echo
	    echo "*** Warning: libtool could not satisfy all declared inter-library"
	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
	    echo "*** a static module, that should work as long as the dlopening"
	    echo "*** application is linked with the -dlopen flag."
	    if test -z "$global_symbol_pipe"; then
	      echo
	      echo "*** However, this would only work if libtool was able to extract symbol"
	      echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
	      echo "*** not find such a program.  So, this module is probably useless."
	      echo "*** 'nm' from GNU binutils and a full rebuild may help."
	    fi
	    if test no = "$build_old_libs"; then
	      oldlibs=$output_objdir/$libname.$libext
	      build_libtool_libs=module
	      build_old_libs=yes
	    else
	      build_libtool_libs=no
	    fi
	  else
	    echo "*** The inter-library dependencies that have been dropped here will be"
	    echo "*** automatically added whenever a program is linked with this library"
	    echo "*** or is declared to -dlopen it."

	    if test no = "$allow_undefined"; then
	      echo
	      echo "*** Since this library must not contain undefined symbols,"
	      echo "*** because either the platform does not support them or"
	      echo "*** it was explicitly requested with -no-undefined,"
	      echo "*** libtool will only create a static version of it."
	      if test no = "$build_old_libs"; then
		oldlibs=$output_objdir/$libname.$libext
		build_libtool_libs=module
		build_old_libs=yes
	      else
		build_libtool_libs=no
	      fi
	    fi
	  fi
	fi
	# Done checking deplibs!
	deplibs=$newdeplibs
      fi
      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
      case $host in
	*-*-darwin*)
	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
	  ;;
      esac

      # move library search paths that coincide with paths to not yet
      # installed libraries to the beginning of the library search list
      new_libs=
      for path in $notinst_path; do
	case " $new_libs " in
	*" -L$path/$objdir "*) ;;
	*)
	  case " $deplibs " in
	  *" -L$path/$objdir "*)
	    func_append new_libs " -L$path/$objdir" ;;
	  esac
	  ;;
	esac
      done
      for deplib in $deplibs; do
	case $deplib in
	-L*)
	  case " $new_libs " in
	  *" $deplib "*) ;;
	  *) func_append new_libs " $deplib" ;;
	  esac
	  ;;
	*) func_append new_libs " $deplib" ;;
	esac
      done
      deplibs=$new_libs

      # All the library-specific variables (install_libdir is set above).
      library_names=
      old_library=
      dlname=

      # Test again, we may have decided not to build it any more
      if test yes = "$build_libtool_libs"; then
	# Remove $wl instances when linking with ld.
	# FIXME: should test the right _cmds variable.
	case $archive_cmds in
	  *\$LD\ *) wl= ;;
        esac
	if test yes = "$hardcode_into_libs"; then
	  # Hardcode the library paths
	  hardcode_libdirs=
	  dep_rpath=
	  rpath=$finalize_rpath
	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath
	  for libdir in $rpath; do
	    if test -n "$hardcode_libdir_flag_spec"; then
	      if test -n "$hardcode_libdir_separator"; then
		func_replace_sysroot "$libdir"
		libdir=$func_replace_sysroot_result
		if test -z "$hardcode_libdirs"; then
		  hardcode_libdirs=$libdir
		else
		  # Just accumulate the unique libdirs.
		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
		    ;;
		  *)
		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
		    ;;
		  esac
		fi
	      else
		eval flag=\"$hardcode_libdir_flag_spec\"
		func_append dep_rpath " $flag"
	      fi
	    elif test -n "$runpath_var"; then
	      case "$perm_rpath " in
	      *" $libdir "*) ;;
	      *) func_append perm_rpath " $libdir" ;;
	      esac
	    fi
	  done
	  # Substitute the hardcoded libdirs into the rpath.
	  if test -n "$hardcode_libdir_separator" &&
	     test -n "$hardcode_libdirs"; then
	    libdir=$hardcode_libdirs
	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
	  fi
	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
	    # We should set the runpath_var.
	    rpath=
	    for dir in $perm_rpath; do
	      func_append rpath "$dir:"
	    done
	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
	  fi
	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
	fi

	shlibpath=$finalize_shlibpath
	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
	if test -n "$shlibpath"; then
	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
	fi

	# Get the real and link names of the library.
	eval shared_ext=\"$shrext_cmds\"
	eval library_names=\"$library_names_spec\"
	set dummy $library_names
	shift
	realname=$1
	shift

	if test -n "$soname_spec"; then
	  eval soname=\"$soname_spec\"
	else
	  soname=$realname
	fi
	if test -z "$dlname"; then
	  dlname=$soname
	fi

	lib=$output_objdir/$realname
	linknames=
	for link
	do
	  func_append linknames " $link"
	done

	# Use standard objects if they are pic
	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
	test "X$libobjs" = "X " && libobjs=

	delfiles=
	if test -n "$export_symbols" && test -n "$include_expsyms"; then
	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
	  export_symbols=$output_objdir/$libname.uexp
	  func_append delfiles " $export_symbols"
	fi

	orig_export_symbols=
	case $host_os in
	cygwin* | mingw* | cegcc*)
	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
	    # exporting using user supplied symfile
	    func_dll_def_p "$export_symbols" || {
	      # and it's NOT already a .def file. Must figure out
	      # which of the given symbols are data symbols and tag
	      # them as such. So, trigger use of export_symbols_cmds.
	      # export_symbols gets reassigned inside the "prepare
	      # the list of exported symbols" if statement, so the
	      # include_expsyms logic still works.
	      orig_export_symbols=$export_symbols
	      export_symbols=
	      always_export_symbols=yes
	    }
	  fi
	  ;;
	esac

	# Prepare the list of exported symbols
	if test -z "$export_symbols"; then
	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
	    func_verbose "generating symbol list for '$libname.la'"
	    export_symbols=$output_objdir/$libname.exp
	    $opt_dry_run || $RM $export_symbols
	    cmds=$export_symbols_cmds
	    save_ifs=$IFS; IFS='~'
	    for cmd1 in $cmds; do
	      IFS=$save_ifs
	      # Take the normal branch if the nm_file_list_spec branch
	      # doesn't work or if tool conversion is not needed.
	      case $nm_file_list_spec~$to_tool_file_cmd in
		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
		  try_normal_branch=yes
		  eval cmd=\"$cmd1\"
		  func_len " $cmd"
		  len=$func_len_result
		  ;;
		*)
		  try_normal_branch=no
		  ;;
	      esac
	      if test yes = "$try_normal_branch" \
		 && { test "$len" -lt "$max_cmd_len" \
		      || test "$max_cmd_len" -le -1; }
	      then
		func_show_eval "$cmd" 'exit $?'
		skipped_export=false
	      elif test -n "$nm_file_list_spec"; then
		func_basename "$output"
		output_la=$func_basename_result
		save_libobjs=$libobjs
		save_output=$output
		output=$output_objdir/$output_la.nm
		func_to_tool_file "$output"
		libobjs=$nm_file_list_spec$func_to_tool_file_result
		func_append delfiles " $output"
		func_verbose "creating $NM input file list: $output"
		for obj in $save_libobjs; do
		  func_to_tool_file "$obj"
		  $ECHO "$func_to_tool_file_result"
		done > "$output"
		eval cmd=\"$cmd1\"
		func_show_eval "$cmd" 'exit $?'
		output=$save_output
		libobjs=$save_libobjs
		skipped_export=false
	      else
		# The command line is too long to execute in one step.
		func_verbose "using reloadable object file for export list..."
		skipped_export=:
		# Break out early, otherwise skipped_export may be
		# set to false by a later but shorter cmd.
		break
	      fi
	    done
	    IFS=$save_ifs
	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
	    fi
	  fi
	fi

	if test -n "$export_symbols" && test -n "$include_expsyms"; then
	  tmp_export_symbols=$export_symbols
	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
	fi

	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
	  # The given exports_symbols file has to be filtered, so filter it.
	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
	  # 's' commands, which not all seds can handle. GNU sed should be fine
	  # though. Also, the filter scales superlinearly with the number of
	  # global variables. join(1) would be nice here, but unfortunately
	  # isn't a blessed tool.
	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
	  export_symbols=$output_objdir/$libname.def
	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
	fi

	tmp_deplibs=
	for test_deplib in $deplibs; do
	  case " $convenience " in
	  *" $test_deplib "*) ;;
	  *)
	    func_append tmp_deplibs " $test_deplib"
	    ;;
	  esac
	done
	deplibs=$tmp_deplibs

	if test -n "$convenience"; then
	  if test -n "$whole_archive_flag_spec" &&
	    test yes = "$compiler_needs_object" &&
	    test -z "$libobjs"; then
	    # extract the archives, so we have objects to list.
	    # TODO: could optimize this to just extract one archive.
	    whole_archive_flag_spec=
	  fi
	  if test -n "$whole_archive_flag_spec"; then
	    save_libobjs=$libobjs
	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
	    test "X$libobjs" = "X " && libobjs=
	  else
	    gentop=$output_objdir/${outputname}x
	    func_append generated " $gentop"

	    func_extract_archives $gentop $convenience
	    func_append libobjs " $func_extract_archives_result"
	    test "X$libobjs" = "X " && libobjs=
	  fi
	fi

	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
	  eval flag=\"$thread_safe_flag_spec\"
	  func_append linker_flags " $flag"
	fi

	# Make a backup of the uninstalled library when relinking
	if test relink = "$opt_mode"; then
	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
	fi

	# Do each of the archive commands.
	if test yes = "$module" && test -n "$module_cmds"; then
	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
	    eval test_cmds=\"$module_expsym_cmds\"
	    cmds=$module_expsym_cmds
	  else
	    eval test_cmds=\"$module_cmds\"
	    cmds=$module_cmds
	  fi
	else
	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
	    eval test_cmds=\"$archive_expsym_cmds\"
	    cmds=$archive_expsym_cmds
	  else
	    eval test_cmds=\"$archive_cmds\"
	    cmds=$archive_cmds
	  fi
	fi

	if test : != "$skipped_export" &&
	   func_len " $test_cmds" &&
	   len=$func_len_result &&
	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
	  :
	else
	  # The command line is too long to link in one step, link piecewise
	  # or, if using GNU ld and skipped_export is not :, use a linker
	  # script.

	  # Save the value of $output and $libobjs because we want to
	  # use them later.  If we have whole_archive_flag_spec, we
	  # want to use save_libobjs as it was before
	  # whole_archive_flag_spec was expanded, because we can't
	  # assume the linker understands whole_archive_flag_spec.
	  # This may have to be revisited, in case too many
	  # convenience libraries get linked in and end up exceeding
	  # the spec.
	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
	    save_libobjs=$libobjs
	  fi
	  save_output=$output
	  func_basename "$output"
	  output_la=$func_basename_result

	  # Clear the reloadable object creation command queue and
	  # initialize k to one.
	  test_cmds=
	  concat_cmds=
	  objlist=
	  last_robj=
	  k=1

	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
	    output=$output_objdir/$output_la.lnkscript
	    func_verbose "creating GNU ld script: $output"
	    echo 'INPUT (' > $output
	    for obj in $save_libobjs
	    do
	      func_to_tool_file "$obj"
	      $ECHO "$func_to_tool_file_result" >> $output
	    done
	    echo ')' >> $output
	    func_append delfiles " $output"
	    func_to_tool_file "$output"
	    output=$func_to_tool_file_result
	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
	    output=$output_objdir/$output_la.lnk
	    func_verbose "creating linker input file list: $output"
	    : > $output
	    set x $save_libobjs
	    shift
	    firstobj=
	    if test yes = "$compiler_needs_object"; then
	      firstobj="$1 "
	      shift
	    fi
	    for obj
	    do
	      func_to_tool_file "$obj"
	      $ECHO "$func_to_tool_file_result" >> $output
	    done
	    func_append delfiles " $output"
	    func_to_tool_file "$output"
	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
	  else
	    if test -n "$save_libobjs"; then
	      func_verbose "creating reloadable object files..."
	      output=$output_objdir/$output_la-$k.$objext
	      eval test_cmds=\"$reload_cmds\"
	      func_len " $test_cmds"
	      len0=$func_len_result
	      len=$len0

	      # Loop over the list of objects to be linked.
	      for obj in $save_libobjs
	      do
		func_len " $obj"
		func_arith $len + $func_len_result
		len=$func_arith_result
		if test -z "$objlist" ||
		   test "$len" -lt "$max_cmd_len"; then
		  func_append objlist " $obj"
		else
		  # The command $test_cmds is almost too long, add a
		  # command to the queue.
		  if test 1 -eq "$k"; then
		    # The first file doesn't have a previous command to add.
		    reload_objs=$objlist
		    eval concat_cmds=\"$reload_cmds\"
		  else
		    # All subsequent reloadable object files will link in
		    # the last one created.
		    reload_objs="$objlist $last_robj"
		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
		  fi
		  last_robj=$output_objdir/$output_la-$k.$objext
		  func_arith $k + 1
		  k=$func_arith_result
		  output=$output_objdir/$output_la-$k.$objext
		  objlist=" $obj"
		  func_len " $last_robj"
		  func_arith $len0 + $func_len_result
		  len=$func_arith_result
		fi
	      done
	      # Handle the remaining objects by creating one last
	      # reloadable object file.  All subsequent reloadable object
	      # files will link in the last one created.
	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
	      reload_objs="$objlist $last_robj"
	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"
	      if test -n "$last_robj"; then
	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
	      fi
	      func_append delfiles " $output"

	    else
	      output=
	    fi

	    ${skipped_export-false} && {
	      func_verbose "generating symbol list for '$libname.la'"
	      export_symbols=$output_objdir/$libname.exp
	      $opt_dry_run || $RM $export_symbols
	      libobjs=$output
	      # Append the command to create the export file.
	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
	      if test -n "$last_robj"; then
		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
	      fi
	    }

	    test -n "$save_libobjs" &&
	      func_verbose "creating a temporary reloadable object file: $output"

	    # Loop through the commands generated above and execute them.
	    save_ifs=$IFS; IFS='~'
	    for cmd in $concat_cmds; do
	      IFS=$save_ifs
	      $opt_quiet || {
		  func_quote_for_expand "$cmd"
		  eval "func_echo $func_quote_for_expand_result"
	      }
	      $opt_dry_run || eval "$cmd" || {
		lt_exit=$?

		# Restore the uninstalled library and exit
		if test relink = "$opt_mode"; then
		  ( cd "$output_objdir" && \
		    $RM "${realname}T" && \
		    $MV "${realname}U" "$realname" )
		fi

		exit $lt_exit
	      }
	    done
	    IFS=$save_ifs

	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
	    fi
	  fi

          ${skipped_export-false} && {
	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
	      tmp_export_symbols=$export_symbols
	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
	    fi

	    if test -n "$orig_export_symbols"; then
	      # The given exports_symbols file has to be filtered, so filter it.
	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
	      # 's' commands, which not all seds can handle. GNU sed should be fine
	      # though. Also, the filter scales superlinearly with the number of
	      # global variables. join(1) would be nice here, but unfortunately
	      # isn't a blessed tool.
	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
	      export_symbols=$output_objdir/$libname.def
	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
	    fi
	  }

	  libobjs=$output
	  # Restore the value of output.
	  output=$save_output

	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
	    test "X$libobjs" = "X " && libobjs=
	  fi
	  # Expand the library linking commands again to reset the
	  # value of $libobjs for piecewise linking.

	  # Do each of the archive commands.
	  if test yes = "$module" && test -n "$module_cmds"; then
	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
	      cmds=$module_expsym_cmds
	    else
	      cmds=$module_cmds
	    fi
	  else
	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
	      cmds=$archive_expsym_cmds
	    else
	      cmds=$archive_cmds
	    fi
	  fi
	fi

	if test -n "$delfiles"; then
	  # Append the command to remove temporary files to $cmds.
	  eval cmds=\"\$cmds~\$RM $delfiles\"
	fi

	# Add any objects from preloaded convenience libraries
	if test -n "$dlprefiles"; then
	  gentop=$output_objdir/${outputname}x
	  func_append generated " $gentop"

	  func_extract_archives $gentop $dlprefiles
	  func_append libobjs " $func_extract_archives_result"
	  test "X$libobjs" = "X " && libobjs=
	fi

	save_ifs=$IFS; IFS='~'
	for cmd in $cmds; do
	  IFS=$sp$nl
	  eval cmd=\"$cmd\"
	  IFS=$save_ifs
	  $opt_quiet || {
	    func_quote_for_expand "$cmd"
	    eval "func_echo $func_quote_for_expand_result"
	  }
	  $opt_dry_run || eval "$cmd" || {
	    lt_exit=$?

	    # Restore the uninstalled library and exit
	    if test relink = "$opt_mode"; then
	      ( cd "$output_objdir" && \
	        $RM "${realname}T" && \
		$MV "${realname}U" "$realname" )
	    fi

	    exit $lt_exit
	  }
	done
	IFS=$save_ifs

	# Restore the uninstalled library and exit
	if test relink = "$opt_mode"; then
	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?

	  if test -n "$convenience"; then
	    if test -z "$whole_archive_flag_spec"; then
	      func_show_eval '${RM}r "$gentop"'
	    fi
	  fi

	  exit $EXIT_SUCCESS
	fi

	# Create links to the real library.
	for linkname in $linknames; do
	  if test "$realname" != "$linkname"; then
	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
	  fi
	done

	# If -module or -export-dynamic was specified, set the dlname.
	if test yes = "$module" || test yes = "$export_dynamic"; then
	  # On all known operating systems, these are identical.
	  dlname=$soname
	fi
      fi
      ;;

    obj)
      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
	func_warning "'-dlopen' is ignored for objects"
      fi

      case " $deplibs" in
      *\ -l* | *\ -L*)
	func_warning "'-l' and '-L' are ignored for objects" ;;
      esac

      test -n "$rpath" && \
	func_warning "'-rpath' is ignored for objects"

      test -n "$xrpath" && \
	func_warning "'-R' is ignored for objects"

      test -n "$vinfo" && \
	func_warning "'-version-info' is ignored for objects"

      test -n "$release" && \
	func_warning "'-release' is ignored for objects"

      case $output in
      *.lo)
	test -n "$objs$old_deplibs" && \
	  func_fatal_error "cannot build library object '$output' from non-libtool objects"

	libobj=$output
	func_lo2o "$libobj"
	obj=$func_lo2o_result
	;;
      *)
	libobj=
	obj=$output
	;;
      esac

      # Delete the old objects.
      $opt_dry_run || $RM $obj $libobj

      # Objects from convenience libraries.  This assumes
      # single-version convenience libraries.  Whenever we create
      # different ones for PIC/non-PIC, this we'll have to duplicate
      # the extraction.
      reload_conv_objs=
      gentop=
      # if reload_cmds runs $LD directly, get rid of -Wl from
      # whole_archive_flag_spec and hope we can get by with turning comma
      # into space.
      case $reload_cmds in
        *\$LD[\ \$]*) wl= ;;
      esac
      if test -n "$convenience"; then
	if test -n "$whole_archive_flag_spec"; then
	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
	else
	  gentop=$output_objdir/${obj}x
	  func_append generated " $gentop"

	  func_extract_archives $gentop $convenience
	  reload_conv_objs="$reload_objs $func_extract_archives_result"
	fi
      fi

      # If we're not building shared, we need to use non_pic_objs
      test yes = "$build_libtool_libs" || libobjs=$non_pic_objects

      # Create the old-style object.
      reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs

      output=$obj
      func_execute_cmds "$reload_cmds" 'exit $?'

      # Exit if we aren't doing a library object file.
      if test -z "$libobj"; then
	if test -n "$gentop"; then
	  func_show_eval '${RM}r "$gentop"'
	fi

	exit $EXIT_SUCCESS
      fi

      test yes = "$build_libtool_libs" || {
	if test -n "$gentop"; then
	  func_show_eval '${RM}r "$gentop"'
	fi

	# Create an invalid libtool object if no PIC, so that we don't
	# accidentally link it into a program.
	# $show "echo timestamp > $libobj"
	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
	exit $EXIT_SUCCESS
      }

      if test -n "$pic_flag" || test default != "$pic_mode"; then
	# Only do commands if we really have different PIC objects.
	reload_objs="$libobjs $reload_conv_objs"
	output=$libobj
	func_execute_cmds "$reload_cmds" 'exit $?'
      fi

      if test -n "$gentop"; then
	func_show_eval '${RM}r "$gentop"'
      fi

      exit $EXIT_SUCCESS
      ;;

    prog)
      case $host in
	*cygwin*) func_stripname '' '.exe' "$output"
	          output=$func_stripname_result.exe;;
      esac
      test -n "$vinfo" && \
	func_warning "'-version-info' is ignored for programs"

      test -n "$release" && \
	func_warning "'-release' is ignored for programs"

      $preload \
	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."

      case $host in
      *-*-rhapsody* | *-*-darwin1.[012])
	# On Rhapsody replace the C library is the System framework
	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
	;;
      esac

      case $host in
      *-*-darwin*)
	# Don't allow lazy linking, it breaks C++ global constructors
	# But is supposedly fixed on 10.4 or later (yay!).
	if test CXX = "$tagname"; then
	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
	    10.[0123])
	      func_append compile_command " $wl-bind_at_load"
	      func_append finalize_command " $wl-bind_at_load"
	    ;;
	  esac
	fi
	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
	;;
      esac


      # move library search paths that coincide with paths to not yet
      # installed libraries to the beginning of the library search list
      new_libs=
      for path in $notinst_path; do
	case " $new_libs " in
	*" -L$path/$objdir "*) ;;
	*)
	  case " $compile_deplibs " in
	  *" -L$path/$objdir "*)
	    func_append new_libs " -L$path/$objdir" ;;
	  esac
	  ;;
	esac
      done
      for deplib in $compile_deplibs; do
	case $deplib in
	-L*)
	  case " $new_libs " in
	  *" $deplib "*) ;;
	  *) func_append new_libs " $deplib" ;;
	  esac
	  ;;
	*) func_append new_libs " $deplib" ;;
	esac
      done
      compile_deplibs=$new_libs


      func_append compile_command " $compile_deplibs"
      func_append finalize_command " $finalize_deplibs"

      if test -n "$rpath$xrpath"; then
	# If the user specified any rpath flags, then add them.
	for libdir in $rpath $xrpath; do
	  # This is the magic to use -rpath.
	  case "$finalize_rpath " in
	  *" $libdir "*) ;;
	  *) func_append finalize_rpath " $libdir" ;;
	  esac
	done
      fi

      # Now hardcode the library paths
      rpath=
      hardcode_libdirs=
      for libdir in $compile_rpath $finalize_rpath; do
	if test -n "$hardcode_libdir_flag_spec"; then
	  if test -n "$hardcode_libdir_separator"; then
	    if test -z "$hardcode_libdirs"; then
	      hardcode_libdirs=$libdir
	    else
	      # Just accumulate the unique libdirs.
	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
		;;
	      *)
		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
		;;
	      esac
	    fi
	  else
	    eval flag=\"$hardcode_libdir_flag_spec\"
	    func_append rpath " $flag"
	  fi
	elif test -n "$runpath_var"; then
	  case "$perm_rpath " in
	  *" $libdir "*) ;;
	  *) func_append perm_rpath " $libdir" ;;
	  esac
	fi
	case $host in
	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
	  case :$dllsearchpath: in
	  *":$libdir:"*) ;;
	  ::) dllsearchpath=$libdir;;
	  *) func_append dllsearchpath ":$libdir";;
	  esac
	  case :$dllsearchpath: in
	  *":$testbindir:"*) ;;
	  ::) dllsearchpath=$testbindir;;
	  *) func_append dllsearchpath ":$testbindir";;
	  esac
	  ;;
	esac
      done
      # Substitute the hardcoded libdirs into the rpath.
      if test -n "$hardcode_libdir_separator" &&
	 test -n "$hardcode_libdirs"; then
	libdir=$hardcode_libdirs
	eval rpath=\" $hardcode_libdir_flag_spec\"
      fi
      compile_rpath=$rpath

      rpath=
      hardcode_libdirs=
      for libdir in $finalize_rpath; do
	if test -n "$hardcode_libdir_flag_spec"; then
	  if test -n "$hardcode_libdir_separator"; then
	    if test -z "$hardcode_libdirs"; then
	      hardcode_libdirs=$libdir
	    else
	      # Just accumulate the unique libdirs.
	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
		;;
	      *)
		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
		;;
	      esac
	    fi
	  else
	    eval flag=\"$hardcode_libdir_flag_spec\"
	    func_append rpath " $flag"
	  fi
	elif test -n "$runpath_var"; then
	  case "$finalize_perm_rpath " in
	  *" $libdir "*) ;;
	  *) func_append finalize_perm_rpath " $libdir" ;;
	  esac
	fi
      done
      # Substitute the hardcoded libdirs into the rpath.
      if test -n "$hardcode_libdir_separator" &&
	 test -n "$hardcode_libdirs"; then
	libdir=$hardcode_libdirs
	eval rpath=\" $hardcode_libdir_flag_spec\"
      fi
      finalize_rpath=$rpath

      if test -n "$libobjs" && test yes = "$build_old_libs"; then
	# Transform all the library objects into standard objects.
	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
      fi

      func_generate_dlsyms "$outputname" "@PROGRAM@" false

      # template prelinking step
      if test -n "$prelink_cmds"; then
	func_execute_cmds "$prelink_cmds" 'exit $?'
      fi

      wrappers_required=:
      case $host in
      *cegcc* | *mingw32ce*)
        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
        wrappers_required=false
        ;;
      *cygwin* | *mingw* )
        test yes = "$build_libtool_libs" || wrappers_required=false
        ;;
      *)
        if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
          wrappers_required=false
        fi
        ;;
      esac
      $wrappers_required || {
	# Replace the output file specification.
	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
	link_command=$compile_command$compile_rpath

	# We have no uninstalled library dependencies, so finalize right now.
	exit_status=0
	func_show_eval "$link_command" 'exit_status=$?'

	if test -n "$postlink_cmds"; then
	  func_to_tool_file "$output"
	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
	  func_execute_cmds "$postlink_cmds" 'exit $?'
	fi

	# Delete the generated files.
	if test -f "$output_objdir/${outputname}S.$objext"; then
	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
	fi

	exit $exit_status
      }

      if test -n "$compile_shlibpath$finalize_shlibpath"; then
	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
      fi
      if test -n "$finalize_shlibpath"; then
	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
      fi

      compile_var=
      finalize_var=
      if test -n "$runpath_var"; then
	if test -n "$perm_rpath"; then
	  # We should set the runpath_var.
	  rpath=
	  for dir in $perm_rpath; do
	    func_append rpath "$dir:"
	  done
	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
	fi
	if test -n "$finalize_perm_rpath"; then
	  # We should set the runpath_var.
	  rpath=
	  for dir in $finalize_perm_rpath; do
	    func_append rpath "$dir:"
	  done
	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
	fi
      fi

      if test yes = "$no_install"; then
	# We don't need to create a wrapper script.
	link_command=$compile_var$compile_command$compile_rpath
	# Replace the output file specification.
	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
	# Delete the old output file.
	$opt_dry_run || $RM $output
	# Link the executable and exit
	func_show_eval "$link_command" 'exit $?'

	if test -n "$postlink_cmds"; then
	  func_to_tool_file "$output"
	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
	  func_execute_cmds "$postlink_cmds" 'exit $?'
	fi

	exit $EXIT_SUCCESS
      fi

      case $hardcode_action,$fast_install in
        relink,*)
	  # Fast installation is not supported
	  link_command=$compile_var$compile_command$compile_rpath
	  relink_command=$finalize_var$finalize_command$finalize_rpath

	  func_warning "this platform does not like uninstalled shared libraries"
	  func_warning "'$output' will be relinked during installation"
	  ;;
        *,yes)
	  link_command=$finalize_var$compile_command$finalize_rpath
	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
          ;;
	*,no)
	  link_command=$compile_var$compile_command$compile_rpath
	  relink_command=$finalize_var$finalize_command$finalize_rpath
          ;;
	*,needless)
	  link_command=$finalize_var$compile_command$finalize_rpath
	  relink_command=
          ;;
      esac

      # Replace the output file specification.
      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`

      # Delete the old output files.
      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname

      func_show_eval "$link_command" 'exit $?'

      if test -n "$postlink_cmds"; then
	func_to_tool_file "$output_objdir/$outputname"
	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
	func_execute_cmds "$postlink_cmds" 'exit $?'
      fi

      # Now create the wrapper script.
      func_verbose "creating $output"

      # Quote the relink command for shipping.
      if test -n "$relink_command"; then
	# Preserve any variables that may affect compiler behavior
	for var in $variables_saved_for_relink; do
	  if eval test -z \"\${$var+set}\"; then
	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
	  elif eval var_value=\$$var; test -z "$var_value"; then
	    relink_command="$var=; export $var; $relink_command"
	  else
	    func_quote_for_eval "$var_value"
	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
	  fi
	done
	relink_command="(cd `pwd`; $relink_command)"
	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
      fi

      # Only actually do things if not in dry run mode.
      $opt_dry_run || {
	# win32 will think the script is a binary if it has
	# a .exe suffix, so we strip it off here.
	case $output in
	  *.exe) func_stripname '' '.exe' "$output"
	         output=$func_stripname_result ;;
	esac
	# test for cygwin because mv fails w/o .exe extensions
	case $host in
	  *cygwin*)
	    exeext=.exe
	    func_stripname '' '.exe' "$outputname"
	    outputname=$func_stripname_result ;;
	  *) exeext= ;;
	esac
	case $host in
	  *cygwin* | *mingw* )
	    func_dirname_and_basename "$output" "" "."
	    output_name=$func_basename_result
	    output_path=$func_dirname_result
	    cwrappersource=$output_path/$objdir/lt-$output_name.c
	    cwrapper=$output_path/$output_name.exe
	    $RM $cwrappersource $cwrapper
	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15

	    func_emit_cwrapperexe_src > $cwrappersource

	    # The wrapper executable is built using the $host compiler,
	    # because it contains $host paths and files. If cross-
	    # compiling, it, like the target executable, must be
	    # executed on the $host or under an emulation environment.
	    $opt_dry_run || {
	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
	      $STRIP $cwrapper
	    }

	    # Now, create the wrapper script for func_source use:
	    func_ltwrapper_scriptname $cwrapper
	    $RM $func_ltwrapper_scriptname_result
	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
	    $opt_dry_run || {
	      # note: this script will not be executed, so do not chmod.
	      if test "x$build" = "x$host"; then
		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
	      else
		func_emit_wrapper no > $func_ltwrapper_scriptname_result
	      fi
	    }
	  ;;
	  * )
	    $RM $output
	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15

	    func_emit_wrapper no > $output
	    chmod +x $output
	  ;;
	esac
      }
      exit $EXIT_SUCCESS
      ;;
    esac

    # See if we need to build an old-fashioned archive.
    for oldlib in $oldlibs; do

      case $build_libtool_libs in
        convenience)
	  oldobjs="$libobjs_save $symfileobj"
	  addlibs=$convenience
	  build_libtool_libs=no
	  ;;
	module)
	  oldobjs=$libobjs_save
	  addlibs=$old_convenience
	  build_libtool_libs=no
          ;;
	*)
	  oldobjs="$old_deplibs $non_pic_objects"
	  $preload && test -f "$symfileobj" \
	    && func_append oldobjs " $symfileobj"
	  addlibs=$old_convenience
	  ;;
      esac

      if test -n "$addlibs"; then
	gentop=$output_objdir/${outputname}x
	func_append generated " $gentop"

	func_extract_archives $gentop $addlibs
	func_append oldobjs " $func_extract_archives_result"
      fi

      # Do each command in the archive commands.
      if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
	cmds=$old_archive_from_new_cmds
      else

	# Add any objects from preloaded convenience libraries
	if test -n "$dlprefiles"; then
	  gentop=$output_objdir/${outputname}x
	  func_append generated " $gentop"

	  func_extract_archives $gentop $dlprefiles
	  func_append oldobjs " $func_extract_archives_result"
	fi

	# POSIX demands no paths to be encoded in archives.  We have
	# to avoid creating archives with duplicate basenames if we
	# might have to extract them afterwards, e.g., when creating a
	# static archive out of a convenience library, or when linking
	# the entirety of a libtool archive into another (currently
	# not supported by libtool).
	if (for obj in $oldobjs
	    do
	      func_basename "$obj"
	      $ECHO "$func_basename_result"
	    done | sort | sort -uc >/dev/null 2>&1); then
	  :
	else
	  echo "copying selected object files to avoid basename conflicts..."
	  gentop=$output_objdir/${outputname}x
	  func_append generated " $gentop"
	  func_mkdir_p "$gentop"
	  save_oldobjs=$oldobjs
	  oldobjs=
	  counter=1
	  for obj in $save_oldobjs
	  do
	    func_basename "$obj"
	    objbase=$func_basename_result
	    case " $oldobjs " in
	    " ") oldobjs=$obj ;;
	    *[\ /]"$objbase "*)
	      while :; do
		# Make sure we don't pick an alternate name that also
		# overlaps.
		newobj=lt$counter-$objbase
		func_arith $counter + 1
		counter=$func_arith_result
		case " $oldobjs " in
		*[\ /]"$newobj "*) ;;
		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
		esac
	      done
	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
	      func_append oldobjs " $gentop/$newobj"
	      ;;
	    *) func_append oldobjs " $obj" ;;
	    esac
	  done
	fi
	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
	tool_oldlib=$func_to_tool_file_result
	eval cmds=\"$old_archive_cmds\"

	func_len " $cmds"
	len=$func_len_result
	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
	  cmds=$old_archive_cmds
	elif test -n "$archiver_list_spec"; then
	  func_verbose "using command file archive linking..."
	  for obj in $oldobjs
	  do
	    func_to_tool_file "$obj"
	    $ECHO "$func_to_tool_file_result"
	  done > $output_objdir/$libname.libcmd
	  func_to_tool_file "$output_objdir/$libname.libcmd"
	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
	  cmds=$old_archive_cmds
	else
	  # the command line is too long to link in one step, link in parts
	  func_verbose "using piecewise archive linking..."
	  save_RANLIB=$RANLIB
	  RANLIB=:
	  objlist=
	  concat_cmds=
	  save_oldobjs=$oldobjs
	  oldobjs=
	  # Is there a better way of finding the last object in the list?
	  for obj in $save_oldobjs
	  do
	    last_oldobj=$obj
	  done
	  eval test_cmds=\"$old_archive_cmds\"
	  func_len " $test_cmds"
	  len0=$func_len_result
	  len=$len0
	  for obj in $save_oldobjs
	  do
	    func_len " $obj"
	    func_arith $len + $func_len_result
	    len=$func_arith_result
	    func_append objlist " $obj"
	    if test "$len" -lt "$max_cmd_len"; then
	      :
	    else
	      # the above command should be used before it gets too long
	      oldobjs=$objlist
	      if test "$obj" = "$last_oldobj"; then
		RANLIB=$save_RANLIB
	      fi
	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
	      objlist=
	      len=$len0
	    fi
	  done
	  RANLIB=$save_RANLIB
	  oldobjs=$objlist
	  if test -z "$oldobjs"; then
	    eval cmds=\"\$concat_cmds\"
	  else
	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
	  fi
	fi
      fi
      func_execute_cmds "$cmds" 'exit $?'
    done

    test -n "$generated" && \
      func_show_eval "${RM}r$generated"

    # Now create the libtool archive.
    case $output in
    *.la)
      old_library=
      test yes = "$build_old_libs" && old_library=$libname.$libext
      func_verbose "creating $output"

      # Preserve any variables that may affect compiler behavior
      for var in $variables_saved_for_relink; do
	if eval test -z \"\${$var+set}\"; then
	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
	elif eval var_value=\$$var; test -z "$var_value"; then
	  relink_command="$var=; export $var; $relink_command"
	else
	  func_quote_for_eval "$var_value"
	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
	fi
      done
      # Quote the link command for shipping.
      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
      if test yes = "$hardcode_automatic"; then
	relink_command=
      fi

      # Only create the output if not a dry run.
      $opt_dry_run || {
	for installed in no yes; do
	  if test yes = "$installed"; then
	    if test -z "$install_libdir"; then
	      break
	    fi
	    output=$output_objdir/${outputname}i
	    # Replace all uninstalled libtool libraries with the installed ones
	    newdependency_libs=
	    for deplib in $dependency_libs; do
	      case $deplib in
	      *.la)
		func_basename "$deplib"
		name=$func_basename_result
		func_resolve_sysroot "$deplib"
		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
		test -z "$libdir" && \
		  func_fatal_error "'$deplib' is not a valid libtool archive"
		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
		;;
	      -L*)
		func_stripname -L '' "$deplib"
		func_replace_sysroot "$func_stripname_result"
		func_append newdependency_libs " -L$func_replace_sysroot_result"
		;;
	      -R*)
		func_stripname -R '' "$deplib"
		func_replace_sysroot "$func_stripname_result"
		func_append newdependency_libs " -R$func_replace_sysroot_result"
		;;
	      *) func_append newdependency_libs " $deplib" ;;
	      esac
	    done
	    dependency_libs=$newdependency_libs
	    newdlfiles=

	    for lib in $dlfiles; do
	      case $lib in
	      *.la)
	        func_basename "$lib"
		name=$func_basename_result
		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
		test -z "$libdir" && \
		  func_fatal_error "'$lib' is not a valid libtool archive"
		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
		;;
	      *) func_append newdlfiles " $lib" ;;
	      esac
	    done
	    dlfiles=$newdlfiles
	    newdlprefiles=
	    for lib in $dlprefiles; do
	      case $lib in
	      *.la)
		# Only pass preopened files to the pseudo-archive (for
		# eventual linking with the app. that links it) if we
		# didn't already link the preopened objects directly into
		# the library:
		func_basename "$lib"
		name=$func_basename_result
		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
		test -z "$libdir" && \
		  func_fatal_error "'$lib' is not a valid libtool archive"
		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
		;;
	      esac
	    done
	    dlprefiles=$newdlprefiles
	  else
	    newdlfiles=
	    for lib in $dlfiles; do
	      case $lib in
		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
		*) abs=`pwd`"/$lib" ;;
	      esac
	      func_append newdlfiles " $abs"
	    done
	    dlfiles=$newdlfiles
	    newdlprefiles=
	    for lib in $dlprefiles; do
	      case $lib in
		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
		*) abs=`pwd`"/$lib" ;;
	      esac
	      func_append newdlprefiles " $abs"
	    done
	    dlprefiles=$newdlprefiles
	  fi
	  $RM $output
	  # place dlname in correct position for cygwin
	  # In fact, it would be nice if we could use this code for all target
	  # systems that can't hard-code library paths into their executables
	  # and that have no shared library path variable independent of PATH,
	  # but it turns out we can't easily determine that from inspecting
	  # libtool variables, so we have to hard-code the OSs to which it
	  # applies here; at the moment, that means platforms that use the PE
	  # object format with DLL files.  See the long comment at the top of
	  # tests/bindir.at for full details.
	  tdlname=$dlname
	  case $host,$output,$installed,$module,$dlname in
	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
	      # If a -bindir argument was supplied, place the dll there.
	      if test -n "$bindir"; then
		func_relative_path "$install_libdir" "$bindir"
		tdlname=$func_relative_path_result/$dlname
	      else
		# Otherwise fall back on heuristic.
		tdlname=../bin/$dlname
	      fi
	      ;;
	  esac
	  $ECHO > $output "\
# $outputname - a libtool library file
# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
#
# Please DO NOT delete this file!
# It is necessary for linking the library.

# The name that we can dlopen(3).
dlname='$tdlname'

# Names of this library.
library_names='$library_names'

# The name of the static archive.
old_library='$old_library'

# Linker flags that cannot go in dependency_libs.
inherited_linker_flags='$new_inherited_linker_flags'

# Libraries that this one depends upon.
dependency_libs='$dependency_libs'

# Names of additional weak libraries provided by this library
weak_library_names='$weak_libs'

# Version information for $libname.
current=$current
age=$age
revision=$revision

# Is this an already installed library?
installed=$installed

# Should we warn about portability when linking against -modules?
shouldnotlink=$module

# Files to dlopen/dlpreopen
dlopen='$dlfiles'
dlpreopen='$dlprefiles'

# Directory that this library needs to be installed in:
libdir='$install_libdir'"
	  if test no,yes = "$installed,$need_relink"; then
	    $ECHO >> $output "\
relink_command=\"$relink_command\""
	  fi
	done
      }

      # Do a symbolic link so that the libtool archive can be found in
      # LD_LIBRARY_PATH before the program is installed.
      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
      ;;
    esac
    exit $EXIT_SUCCESS
}

if test link = "$opt_mode" || test relink = "$opt_mode"; then
  func_mode_link ${1+"$@"}
fi


# func_mode_uninstall arg...
func_mode_uninstall ()
{
    $debug_cmd

    RM=$nonopt
    files=
    rmforce=false
    exit_status=0

    # This variable tells wrapper scripts just to set variables rather
    # than running their programs.
    libtool_install_magic=$magic

    for arg
    do
      case $arg in
      -f) func_append RM " $arg"; rmforce=: ;;
      -*) func_append RM " $arg" ;;
      *) func_append files " $arg" ;;
      esac
    done

    test -z "$RM" && \
      func_fatal_help "you must specify an RM program"

    rmdirs=

    for file in $files; do
      func_dirname "$file" "" "."
      dir=$func_dirname_result
      if test . = "$dir"; then
	odir=$objdir
      else
	odir=$dir/$objdir
      fi
      func_basename "$file"
      name=$func_basename_result
      test uninstall = "$opt_mode" && odir=$dir

      # Remember odir for removal later, being careful to avoid duplicates
      if test clean = "$opt_mode"; then
	case " $rmdirs " in
	  *" $odir "*) ;;
	  *) func_append rmdirs " $odir" ;;
	esac
      fi

      # Don't error if the file doesn't exist and rm -f was used.
      if { test -L "$file"; } >/dev/null 2>&1 ||
	 { test -h "$file"; } >/dev/null 2>&1 ||
	 test -f "$file"; then
	:
      elif test -d "$file"; then
	exit_status=1
	continue
      elif $rmforce; then
	continue
      fi

      rmfiles=$file

      case $name in
      *.la)
	# Possibly a libtool archive, so verify it.
	if func_lalib_p "$file"; then
	  func_source $dir/$name

	  # Delete the libtool libraries and symlinks.
	  for n in $library_names; do
	    func_append rmfiles " $odir/$n"
	  done
	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"

	  case $opt_mode in
	  clean)
	    case " $library_names " in
	    *" $dlname "*) ;;
	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
	    esac
	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
	    ;;
	  uninstall)
	    if test -n "$library_names"; then
	      # Do each command in the postuninstall commands.
	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
	    fi

	    if test -n "$old_library"; then
	      # Do each command in the old_postuninstall commands.
	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
	    fi
	    # FIXME: should reinstall the best remaining shared library.
	    ;;
	  esac
	fi
	;;

      *.lo)
	# Possibly a libtool object, so verify it.
	if func_lalib_p "$file"; then

	  # Read the .lo file
	  func_source $dir/$name

	  # Add PIC object to the list of files to remove.
	  if test -n "$pic_object" && test none != "$pic_object"; then
	    func_append rmfiles " $dir/$pic_object"
	  fi

	  # Add non-PIC object to the list of files to remove.
	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then
	    func_append rmfiles " $dir/$non_pic_object"
	  fi
	fi
	;;

      *)
	if test clean = "$opt_mode"; then
	  noexename=$name
	  case $file in
	  *.exe)
	    func_stripname '' '.exe' "$file"
	    file=$func_stripname_result
	    func_stripname '' '.exe' "$name"
	    noexename=$func_stripname_result
	    # $file with .exe has already been added to rmfiles,
	    # add $file without .exe
	    func_append rmfiles " $file"
	    ;;
	  esac
	  # Do a test to see if this is a libtool program.
	  if func_ltwrapper_p "$file"; then
	    if func_ltwrapper_executable_p "$file"; then
	      func_ltwrapper_scriptname "$file"
	      relink_command=
	      func_source $func_ltwrapper_scriptname_result
	      func_append rmfiles " $func_ltwrapper_scriptname_result"
	    else
	      relink_command=
	      func_source $dir/$noexename
	    fi

	    # note $name still contains .exe if it was in $file originally
	    # as does the version of $file that was added into $rmfiles
	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"
	    if test yes = "$fast_install" && test -n "$relink_command"; then
	      func_append rmfiles " $odir/lt-$name"
	    fi
	    if test "X$noexename" != "X$name"; then
	      func_append rmfiles " $odir/lt-$noexename.c"
	    fi
	  fi
	fi
	;;
      esac
      func_show_eval "$RM $rmfiles" 'exit_status=1'
    done

    # Try to remove the $objdir's in the directories where we deleted files
    for dir in $rmdirs; do
      if test -d "$dir"; then
	func_show_eval "rmdir $dir >/dev/null 2>&1"
      fi
    done

    exit $exit_status
}

if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
  func_mode_uninstall ${1+"$@"}
fi

test -z "$opt_mode" && {
  help=$generic_help
  func_fatal_help "you must specify a MODE"
}

test -z "$exec_cmd" && \
  func_fatal_help "invalid operation mode '$opt_mode'"

if test -n "$exec_cmd"; then
  eval exec "$exec_cmd"
  exit $EXIT_FAILURE
fi

exit $exit_status


# The TAGs below are defined such that we never get into a situation
# where we disable both kinds of libraries.  Given conflicting
# choices, we go for a static library, that is the most portable,
# since we can't tell whether shared libraries were disabled because
# the user asked for that or because the platform doesn't support
# them.  This is particularly important on AIX, because we don't
# support having both static and shared libraries enabled at the same
# time on that platform, so we default to a shared-only configuration.
# If a disable-shared tag is given, we'll fallback to a static-only
# configuration.  But we'll never go from static-only to shared-only.

# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
build_libtool_libs=no
build_old_libs=yes
# ### END LIBTOOL TAG CONFIG: disable-shared

# ### BEGIN LIBTOOL TAG CONFIG: disable-static
build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
# ### END LIBTOOL TAG CONFIG: disable-static

# Local Variables:
# mode:shell-script
# sh-indentation:2
# End:
thrift-0.23.0/config.guess0000755000175000017500000014051215166015674015712 0ustar00buildbuild00000000000000#! /bin/sh
# Attempt to guess a canonical system name.
#   Copyright 1992-2022 Free Software Foundation, Inc.

# shellcheck disable=SC2006,SC2268 # see below for rationale

timestamp='2022-01-09'

# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program.  This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
#
# Please send patches to .


# The "shellcheck disable" line above the timestamp inhibits complaints
# about features and limitations of the classic Bourne shell that were
# superseded or lifted in POSIX.  However, this script identifies a wide
# variety of pre-POSIX systems that do not have POSIX shells at all, and
# even some reasonably current systems (Solaris 10 as case-in-point) still
# have a pre-POSIX /bin/sh.


me=`echo "$0" | sed -e 's,.*/,,'`

usage="\
Usage: $0 [OPTION]

Output the configuration name of the system \`$me' is run on.

Options:
  -h, --help         print this help, then exit
  -t, --time-stamp   print date of last modification, then exit
  -v, --version      print version number, then exit

Report bugs and patches to ."

version="\
GNU config.guess ($timestamp)

Originally written by Per Bothner.
Copyright 1992-2022 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."

help="
Try \`$me --help' for more information."

# Parse command line
while test $# -gt 0 ; do
  case $1 in
    --time-stamp | --time* | -t )
       echo "$timestamp" ; exit ;;
    --version | -v )
       echo "$version" ; exit ;;
    --help | --h* | -h )
       echo "$usage"; exit ;;
    -- )     # Stop option processing
       shift; break ;;
    - )	# Use stdin as input.
       break ;;
    -* )
       echo "$me: invalid option $1$help" >&2
       exit 1 ;;
    * )
       break ;;
  esac
done

if test $# != 0; then
  echo "$me: too many arguments$help" >&2
  exit 1
fi

# Just in case it came from the environment.
GUESS=

# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.

# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.

# Portable tmp directory creation inspired by the Autoconf team.

tmp=
# shellcheck disable=SC2172
trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15

set_cc_for_build() {
    # prevent multiple calls if $tmp is already set
    test "$tmp" && return 0
    : "${TMPDIR=/tmp}"
    # shellcheck disable=SC2039,SC3028
    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
    dummy=$tmp/dummy
    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
	,,)    echo "int x;" > "$dummy.c"
	       for driver in cc gcc c89 c99 ; do
		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
		       CC_FOR_BUILD=$driver
		       break
		   fi
	       done
	       if test x"$CC_FOR_BUILD" = x ; then
		   CC_FOR_BUILD=no_compiler_found
	       fi
	       ;;
	,,*)   CC_FOR_BUILD=$CC ;;
	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
    esac
}

# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if test -f /.attbin/uname ; then
	PATH=$PATH:/.attbin ; export PATH
fi

UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown

case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
	LIBC=unknown

	set_cc_for_build
	cat <<-EOF > "$dummy.c"
	#include 
	#if defined(__UCLIBC__)
	LIBC=uclibc
	#elif defined(__dietlibc__)
	LIBC=dietlibc
	#elif defined(__GLIBC__)
	LIBC=gnu
	#else
	#include 
	/* First heuristic to detect musl libc.  */
	#ifdef __DEFINED_va_list
	LIBC=musl
	#endif
	#endif
	EOF
	cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
	eval "$cc_set_libc"

	# Second heuristic to detect musl libc.
	if [ "$LIBC" = unknown ] &&
	   command -v ldd >/dev/null &&
	   ldd --version 2>&1 | grep -q ^musl; then
		LIBC=musl
	fi

	# If the system lacks a compiler, then just pick glibc.
	# We could probably try harder.
	if [ "$LIBC" = unknown ]; then
		LIBC=gnu
	fi
	;;
esac

# Note: order is significant - the case branches are not exclusive.

case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
    *:NetBSD:*:*)
	# NetBSD (nbsd) targets should (where applicable) match one or
	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
	# switched to ELF, *-*-netbsd* would select the old
	# object file format.  This provides both forward
	# compatibility and a consistent mechanism for selecting the
	# object file format.
	#
	# Note: NetBSD doesn't particularly care about the vendor
	# portion of the name.  We always set it to "unknown".
	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
	    /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
	    /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
	    echo unknown)`
	case $UNAME_MACHINE_ARCH in
	    aarch64eb) machine=aarch64_be-unknown ;;
	    armeb) machine=armeb-unknown ;;
	    arm*) machine=arm-unknown ;;
	    sh3el) machine=shl-unknown ;;
	    sh3eb) machine=sh-unknown ;;
	    sh5el) machine=sh5le-unknown ;;
	    earmv*)
		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
		machine=${arch}${endian}-unknown
		;;
	    *) machine=$UNAME_MACHINE_ARCH-unknown ;;
	esac
	# The Operating System including object format, if it has switched
	# to ELF recently (or will in the future) and ABI.
	case $UNAME_MACHINE_ARCH in
	    earm*)
		os=netbsdelf
		;;
	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
		set_cc_for_build
		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
			| grep -q __ELF__
		then
		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
		    # Return netbsd for either.  FIX?
		    os=netbsd
		else
		    os=netbsdelf
		fi
		;;
	    *)
		os=netbsd
		;;
	esac
	# Determine ABI tags.
	case $UNAME_MACHINE_ARCH in
	    earm*)
		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
		;;
	esac
	# The OS release
	# Debian GNU/NetBSD machines have a different userland, and
	# thus, need a distinct triplet. However, they do not need
	# kernel version information, so it can be replaced with a
	# suitable tag, in the style of linux-gnu.
	case $UNAME_VERSION in
	    Debian*)
		release='-gnu'
		;;
	    *)
		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
		;;
	esac
	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
	# contains redundant information, the shorter form:
	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
	GUESS=$machine-${os}${release}${abi-}
	;;
    *:Bitrig:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
	GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
	;;
    *:OpenBSD:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
	GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
	;;
    *:SecBSD:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
	GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
	;;
    *:LibertyBSD:*:*)
	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
	GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
	;;
    *:MidnightBSD:*:*)
	GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
	;;
    *:ekkoBSD:*:*)
	GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
	;;
    *:SolidBSD:*:*)
	GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
	;;
    *:OS108:*:*)
	GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
	;;
    macppc:MirBSD:*:*)
	GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
	;;
    *:MirBSD:*:*)
	GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
	;;
    *:Sortix:*:*)
	GUESS=$UNAME_MACHINE-unknown-sortix
	;;
    *:Twizzler:*:*)
	GUESS=$UNAME_MACHINE-unknown-twizzler
	;;
    *:Redox:*:*)
	GUESS=$UNAME_MACHINE-unknown-redox
	;;
    mips:OSF1:*.*)
	GUESS=mips-dec-osf1
	;;
    alpha:OSF1:*:*)
	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
	trap '' 0
	case $UNAME_RELEASE in
	*4.0)
		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
		;;
	*5.*)
		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
		;;
	esac
	# According to Compaq, /usr/sbin/psrinfo has been available on
	# OSF/1 and Tru64 systems produced since 1995.  I hope that
	# covers most systems running today.  This code pipes the CPU
	# types through head -n 1, so we only detect the type of CPU 0.
	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
	case $ALPHA_CPU_TYPE in
	    "EV4 (21064)")
		UNAME_MACHINE=alpha ;;
	    "EV4.5 (21064)")
		UNAME_MACHINE=alpha ;;
	    "LCA4 (21066/21068)")
		UNAME_MACHINE=alpha ;;
	    "EV5 (21164)")
		UNAME_MACHINE=alphaev5 ;;
	    "EV5.6 (21164A)")
		UNAME_MACHINE=alphaev56 ;;
	    "EV5.6 (21164PC)")
		UNAME_MACHINE=alphapca56 ;;
	    "EV5.7 (21164PC)")
		UNAME_MACHINE=alphapca57 ;;
	    "EV6 (21264)")
		UNAME_MACHINE=alphaev6 ;;
	    "EV6.7 (21264A)")
		UNAME_MACHINE=alphaev67 ;;
	    "EV6.8CB (21264C)")
		UNAME_MACHINE=alphaev68 ;;
	    "EV6.8AL (21264B)")
		UNAME_MACHINE=alphaev68 ;;
	    "EV6.8CX (21264D)")
		UNAME_MACHINE=alphaev68 ;;
	    "EV6.9A (21264/EV69A)")
		UNAME_MACHINE=alphaev69 ;;
	    "EV7 (21364)")
		UNAME_MACHINE=alphaev7 ;;
	    "EV7.9 (21364A)")
		UNAME_MACHINE=alphaev79 ;;
	esac
	# A Pn.n version is a patched version.
	# A Vn.n version is a released version.
	# A Tn.n version is a released field test version.
	# A Xn.n version is an unreleased experimental baselevel.
	# 1.2 uses "1.2" for uname -r.
	OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
	GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
	;;
    Amiga*:UNIX_System_V:4.0:*)
	GUESS=m68k-unknown-sysv4
	;;
    *:[Aa]miga[Oo][Ss]:*:*)
	GUESS=$UNAME_MACHINE-unknown-amigaos
	;;
    *:[Mm]orph[Oo][Ss]:*:*)
	GUESS=$UNAME_MACHINE-unknown-morphos
	;;
    *:OS/390:*:*)
	GUESS=i370-ibm-openedition
	;;
    *:z/VM:*:*)
	GUESS=s390-ibm-zvmoe
	;;
    *:OS400:*:*)
	GUESS=powerpc-ibm-os400
	;;
    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
	GUESS=arm-acorn-riscix$UNAME_RELEASE
	;;
    arm*:riscos:*:*|arm*:RISCOS:*:*)
	GUESS=arm-unknown-riscos
	;;
    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
	GUESS=hppa1.1-hitachi-hiuxmpp
	;;
    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
	case `(/bin/universe) 2>/dev/null` in
	    att) GUESS=pyramid-pyramid-sysv3 ;;
	    *)   GUESS=pyramid-pyramid-bsd   ;;
	esac
	;;
    NILE*:*:*:dcosx)
	GUESS=pyramid-pyramid-svr4
	;;
    DRS?6000:unix:4.0:6*)
	GUESS=sparc-icl-nx6
	;;
    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
	case `/usr/bin/uname -p` in
	    sparc) GUESS=sparc-icl-nx7 ;;
	esac
	;;
    s390x:SunOS:*:*)
	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
	GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
	;;
    sun4H:SunOS:5.*:*)
	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
	GUESS=sparc-hal-solaris2$SUN_REL
	;;
    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
	GUESS=sparc-sun-solaris2$SUN_REL
	;;
    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
	GUESS=i386-pc-auroraux$UNAME_RELEASE
	;;
    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
	set_cc_for_build
	SUN_ARCH=i386
	# If there is a compiler, see if it is configured for 64-bit objects.
	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
	# This test works for both compilers.
	if test "$CC_FOR_BUILD" != no_compiler_found; then
	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
		(CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
		grep IS_64BIT_ARCH >/dev/null
	    then
		SUN_ARCH=x86_64
	    fi
	fi
	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
	GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
	;;
    sun4*:SunOS:6*:*)
	# According to config.sub, this is the proper way to canonicalize
	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
	# it's likely to be more like Solaris than SunOS4.
	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
	GUESS=sparc-sun-solaris3$SUN_REL
	;;
    sun4*:SunOS:*:*)
	case `/usr/bin/arch -k` in
	    Series*|S4*)
		UNAME_RELEASE=`uname -v`
		;;
	esac
	# Japanese Language versions have a version number like `4.1.3-JL'.
	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
	GUESS=sparc-sun-sunos$SUN_REL
	;;
    sun3*:SunOS:*:*)
	GUESS=m68k-sun-sunos$UNAME_RELEASE
	;;
    sun*:*:4.2BSD:*)
	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
	case `/bin/arch` in
	    sun3)
		GUESS=m68k-sun-sunos$UNAME_RELEASE
		;;
	    sun4)
		GUESS=sparc-sun-sunos$UNAME_RELEASE
		;;
	esac
	;;
    aushp:SunOS:*:*)
	GUESS=sparc-auspex-sunos$UNAME_RELEASE
	;;
    # The situation for MiNT is a little confusing.  The machine name
    # can be virtually everything (everything which is not
    # "atarist" or "atariste" at least should have a processor
    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
    # to the lowercase version "mint" (or "freemint").  Finally
    # the system name "TOS" denotes a system which is actually not
    # MiNT.  But MiNT is downward compatible to TOS, so this should
    # be no problem.
    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
	GUESS=m68k-atari-mint$UNAME_RELEASE
	;;
    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
	GUESS=m68k-atari-mint$UNAME_RELEASE
	;;
    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
	GUESS=m68k-atari-mint$UNAME_RELEASE
	;;
    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
	GUESS=m68k-milan-mint$UNAME_RELEASE
	;;
    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
	GUESS=m68k-hades-mint$UNAME_RELEASE
	;;
    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
	GUESS=m68k-unknown-mint$UNAME_RELEASE
	;;
    m68k:machten:*:*)
	GUESS=m68k-apple-machten$UNAME_RELEASE
	;;
    powerpc:machten:*:*)
	GUESS=powerpc-apple-machten$UNAME_RELEASE
	;;
    RISC*:Mach:*:*)
	GUESS=mips-dec-mach_bsd4.3
	;;
    RISC*:ULTRIX:*:*)
	GUESS=mips-dec-ultrix$UNAME_RELEASE
	;;
    VAX*:ULTRIX*:*:*)
	GUESS=vax-dec-ultrix$UNAME_RELEASE
	;;
    2020:CLIX:*:* | 2430:CLIX:*:*)
	GUESS=clipper-intergraph-clix$UNAME_RELEASE
	;;
    mips:*:*:UMIPS | mips:*:*:RISCos)
	set_cc_for_build
	sed 's/^	//' << EOF > "$dummy.c"
#ifdef __cplusplus
#include   /* for printf() prototype */
	int main (int argc, char *argv[]) {
#else
	int main (argc, argv) int argc; char *argv[]; {
#endif
	#if defined (host_mips) && defined (MIPSEB)
	#if defined (SYSTYPE_SYSV)
	  printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
	#endif
	#if defined (SYSTYPE_SVR4)
	  printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
	#endif
	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
	  printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
	#endif
	#endif
	  exit (-1);
	}
EOF
	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
	    { echo "$SYSTEM_NAME"; exit; }
	GUESS=mips-mips-riscos$UNAME_RELEASE
	;;
    Motorola:PowerMAX_OS:*:*)
	GUESS=powerpc-motorola-powermax
	;;
    Motorola:*:4.3:PL8-*)
	GUESS=powerpc-harris-powermax
	;;
    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
	GUESS=powerpc-harris-powermax
	;;
    Night_Hawk:Power_UNIX:*:*)
	GUESS=powerpc-harris-powerunix
	;;
    m88k:CX/UX:7*:*)
	GUESS=m88k-harris-cxux7
	;;
    m88k:*:4*:R4*)
	GUESS=m88k-motorola-sysv4
	;;
    m88k:*:3*:R3*)
	GUESS=m88k-motorola-sysv3
	;;
    AViiON:dgux:*:*)
	# DG/UX returns AViiON for all architectures
	UNAME_PROCESSOR=`/usr/bin/uname -p`
	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
	then
	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
	       test "$TARGET_BINARY_INTERFACE"x = x
	    then
		GUESS=m88k-dg-dgux$UNAME_RELEASE
	    else
		GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
	    fi
	else
	    GUESS=i586-dg-dgux$UNAME_RELEASE
	fi
	;;
    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
	GUESS=m88k-dolphin-sysv3
	;;
    M88*:*:R3*:*)
	# Delta 88k system running SVR3
	GUESS=m88k-motorola-sysv3
	;;
    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
	GUESS=m88k-tektronix-sysv3
	;;
    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
	GUESS=m68k-tektronix-bsd
	;;
    *:IRIX*:*:*)
	IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
	GUESS=mips-sgi-irix$IRIX_REL
	;;
    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
	GUESS=romp-ibm-aix    # uname -m gives an 8 hex-code CPU id
	;;                    # Note that: echo "'`uname -s`'" gives 'AIX '
    i*86:AIX:*:*)
	GUESS=i386-ibm-aix
	;;
    ia64:AIX:*:*)
	if test -x /usr/bin/oslevel ; then
		IBM_REV=`/usr/bin/oslevel`
	else
		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
	fi
	GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
	;;
    *:AIX:2:3)
	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
		set_cc_for_build
		sed 's/^		//' << EOF > "$dummy.c"
		#include 

		main()
			{
			if (!__power_pc())
				exit(1);
			puts("powerpc-ibm-aix3.2.5");
			exit(0);
			}
EOF
		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
		then
			GUESS=$SYSTEM_NAME
		else
			GUESS=rs6000-ibm-aix3.2.5
		fi
	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
		GUESS=rs6000-ibm-aix3.2.4
	else
		GUESS=rs6000-ibm-aix3.2
	fi
	;;
    *:AIX:*:[4567])
	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
		IBM_ARCH=rs6000
	else
		IBM_ARCH=powerpc
	fi
	if test -x /usr/bin/lslpp ; then
		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
	else
		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
	fi
	GUESS=$IBM_ARCH-ibm-aix$IBM_REV
	;;
    *:AIX:*:*)
	GUESS=rs6000-ibm-aix
	;;
    ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
	GUESS=romp-ibm-bsd4.4
	;;
    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
	GUESS=romp-ibm-bsd$UNAME_RELEASE    # 4.3 with uname added to
	;;                                  # report: romp-ibm BSD 4.3
    *:BOSX:*:*)
	GUESS=rs6000-bull-bosx
	;;
    DPX/2?00:B.O.S.:*:*)
	GUESS=m68k-bull-sysv3
	;;
    9000/[34]??:4.3bsd:1.*:*)
	GUESS=m68k-hp-bsd
	;;
    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
	GUESS=m68k-hp-bsd4.4
	;;
    9000/[34678]??:HP-UX:*:*)
	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
	case $UNAME_MACHINE in
	    9000/31?)            HP_ARCH=m68000 ;;
	    9000/[34]??)         HP_ARCH=m68k ;;
	    9000/[678][0-9][0-9])
		if test -x /usr/bin/getconf; then
		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
		    case $sc_cpu_version in
		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
		      532)                      # CPU_PA_RISC2_0
			case $sc_kernel_bits in
			  32) HP_ARCH=hppa2.0n ;;
			  64) HP_ARCH=hppa2.0w ;;
			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
			esac ;;
		    esac
		fi
		if test "$HP_ARCH" = ""; then
		    set_cc_for_build
		    sed 's/^		//' << EOF > "$dummy.c"

		#define _HPUX_SOURCE
		#include 
		#include 

		int main ()
		{
		#if defined(_SC_KERNEL_BITS)
		    long bits = sysconf(_SC_KERNEL_BITS);
		#endif
		    long cpu  = sysconf (_SC_CPU_VERSION);

		    switch (cpu)
			{
			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
			case CPU_PA_RISC2_0:
		#if defined(_SC_KERNEL_BITS)
			    switch (bits)
				{
				case 64: puts ("hppa2.0w"); break;
				case 32: puts ("hppa2.0n"); break;
				default: puts ("hppa2.0"); break;
				} break;
		#else  /* !defined(_SC_KERNEL_BITS) */
			    puts ("hppa2.0"); break;
		#endif
			default: puts ("hppa1.0"); break;
			}
		    exit (0);
		}
EOF
		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
		    test -z "$HP_ARCH" && HP_ARCH=hppa
		fi ;;
	esac
	if test "$HP_ARCH" = hppa2.0w
	then
	    set_cc_for_build

	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
	    # generating 64-bit code.  GNU and HP use different nomenclature:
	    #
	    # $ CC_FOR_BUILD=cc ./config.guess
	    # => hppa2.0w-hp-hpux11.23
	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
	    # => hppa64-hp-hpux11.23

	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
		grep -q __LP64__
	    then
		HP_ARCH=hppa2.0w
	    else
		HP_ARCH=hppa64
	    fi
	fi
	GUESS=$HP_ARCH-hp-hpux$HPUX_REV
	;;
    ia64:HP-UX:*:*)
	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
	GUESS=ia64-hp-hpux$HPUX_REV
	;;
    3050*:HI-UX:*:*)
	set_cc_for_build
	sed 's/^	//' << EOF > "$dummy.c"
	#include 
	int
	main ()
	{
	  long cpu = sysconf (_SC_CPU_VERSION);
	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
	     results, however.  */
	  if (CPU_IS_PA_RISC (cpu))
	    {
	      switch (cpu)
		{
		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
		  default: puts ("hppa-hitachi-hiuxwe2"); break;
		}
	    }
	  else if (CPU_IS_HP_MC68K (cpu))
	    puts ("m68k-hitachi-hiuxwe2");
	  else puts ("unknown-hitachi-hiuxwe2");
	  exit (0);
	}
EOF
	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
		{ echo "$SYSTEM_NAME"; exit; }
	GUESS=unknown-hitachi-hiuxwe2
	;;
    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
	GUESS=hppa1.1-hp-bsd
	;;
    9000/8??:4.3bsd:*:*)
	GUESS=hppa1.0-hp-bsd
	;;
    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
	GUESS=hppa1.0-hp-mpeix
	;;
    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
	GUESS=hppa1.1-hp-osf
	;;
    hp8??:OSF1:*:*)
	GUESS=hppa1.0-hp-osf
	;;
    i*86:OSF1:*:*)
	if test -x /usr/sbin/sysversion ; then
	    GUESS=$UNAME_MACHINE-unknown-osf1mk
	else
	    GUESS=$UNAME_MACHINE-unknown-osf1
	fi
	;;
    parisc*:Lites*:*:*)
	GUESS=hppa1.1-hp-lites
	;;
    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
	GUESS=c1-convex-bsd
	;;
    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
	if getsysinfo -f scalar_acc
	then echo c32-convex-bsd
	else echo c2-convex-bsd
	fi
	exit ;;
    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
	GUESS=c34-convex-bsd
	;;
    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
	GUESS=c38-convex-bsd
	;;
    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
	GUESS=c4-convex-bsd
	;;
    CRAY*Y-MP:*:*:*)
	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
	GUESS=ymp-cray-unicos$CRAY_REL
	;;
    CRAY*[A-Z]90:*:*:*)
	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
	      -e 's/\.[^.]*$/.X/'
	exit ;;
    CRAY*TS:*:*:*)
	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
	GUESS=t90-cray-unicos$CRAY_REL
	;;
    CRAY*T3E:*:*:*)
	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
	GUESS=alphaev5-cray-unicosmk$CRAY_REL
	;;
    CRAY*SV1:*:*:*)
	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
	GUESS=sv1-cray-unicos$CRAY_REL
	;;
    *:UNICOS/mp:*:*)
	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
	GUESS=craynv-cray-unicosmp$CRAY_REL
	;;
    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
	GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
	;;
    5000:UNIX_System_V:4.*:*)
	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
	GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
	;;
    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
	GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
	;;
    sparc*:BSD/OS:*:*)
	GUESS=sparc-unknown-bsdi$UNAME_RELEASE
	;;
    *:BSD/OS:*:*)
	GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
	;;
    arm:FreeBSD:*:*)
	UNAME_PROCESSOR=`uname -p`
	set_cc_for_build
	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
	    | grep -q __ARM_PCS_VFP
	then
	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
	else
	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
	fi
	;;
    *:FreeBSD:*:*)
	UNAME_PROCESSOR=`/usr/bin/uname -p`
	case $UNAME_PROCESSOR in
	    amd64)
		UNAME_PROCESSOR=x86_64 ;;
	    i386)
		UNAME_PROCESSOR=i586 ;;
	esac
	FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
	GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
	;;
    i*:CYGWIN*:*)
	GUESS=$UNAME_MACHINE-pc-cygwin
	;;
    *:MINGW64*:*)
	GUESS=$UNAME_MACHINE-pc-mingw64
	;;
    *:MINGW*:*)
	GUESS=$UNAME_MACHINE-pc-mingw32
	;;
    *:MSYS*:*)
	GUESS=$UNAME_MACHINE-pc-msys
	;;
    i*:PW*:*)
	GUESS=$UNAME_MACHINE-pc-pw32
	;;
    *:SerenityOS:*:*)
        GUESS=$UNAME_MACHINE-pc-serenity
        ;;
    *:Interix*:*)
	case $UNAME_MACHINE in
	    x86)
		GUESS=i586-pc-interix$UNAME_RELEASE
		;;
	    authenticamd | genuineintel | EM64T)
		GUESS=x86_64-unknown-interix$UNAME_RELEASE
		;;
	    IA64)
		GUESS=ia64-unknown-interix$UNAME_RELEASE
		;;
	esac ;;
    i*:UWIN*:*)
	GUESS=$UNAME_MACHINE-pc-uwin
	;;
    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
	GUESS=x86_64-pc-cygwin
	;;
    prep*:SunOS:5.*:*)
	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
	GUESS=powerpcle-unknown-solaris2$SUN_REL
	;;
    *:GNU:*:*)
	# the GNU system
	GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
	GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
	;;
    *:GNU/*:*:*)
	# other systems with GNU libc and userland
	GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
	GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
	;;
    *:Minix:*:*)
	GUESS=$UNAME_MACHINE-unknown-minix
	;;
    aarch64:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    aarch64_be:Linux:*:*)
	UNAME_MACHINE=aarch64_be
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    alpha:Linux:*:*)
	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
	  EV5)   UNAME_MACHINE=alphaev5 ;;
	  EV56)  UNAME_MACHINE=alphaev56 ;;
	  PCA56) UNAME_MACHINE=alphapca56 ;;
	  PCA57) UNAME_MACHINE=alphapca56 ;;
	  EV6)   UNAME_MACHINE=alphaev6 ;;
	  EV67)  UNAME_MACHINE=alphaev67 ;;
	  EV68*) UNAME_MACHINE=alphaev68 ;;
	esac
	objdump --private-headers /bin/sh | grep -q ld.so.1
	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    arm*:Linux:*:*)
	set_cc_for_build
	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
	    | grep -q __ARM_EABI__
	then
	    GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	else
	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
		| grep -q __ARM_PCS_VFP
	    then
		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
	    else
		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
	    fi
	fi
	;;
    avr32*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    cris:Linux:*:*)
	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
	;;
    crisv32:Linux:*:*)
	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
	;;
    e2k:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    frv:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    hexagon:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    i*86:Linux:*:*)
	GUESS=$UNAME_MACHINE-pc-linux-$LIBC
	;;
    ia64:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    k1om:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    m32r*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    m68*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    mips:Linux:*:* | mips64:Linux:*:*)
	set_cc_for_build
	IS_GLIBC=0
	test x"${LIBC}" = xgnu && IS_GLIBC=1
	sed 's/^	//' << EOF > "$dummy.c"
	#undef CPU
	#undef mips
	#undef mipsel
	#undef mips64
	#undef mips64el
	#if ${IS_GLIBC} && defined(_ABI64)
	LIBCABI=gnuabi64
	#else
	#if ${IS_GLIBC} && defined(_ABIN32)
	LIBCABI=gnuabin32
	#else
	LIBCABI=${LIBC}
	#endif
	#endif

	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
	CPU=mipsisa64r6
	#else
	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
	CPU=mipsisa32r6
	#else
	#if defined(__mips64)
	CPU=mips64
	#else
	CPU=mips
	#endif
	#endif
	#endif

	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
	MIPS_ENDIAN=el
	#else
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
	MIPS_ENDIAN=
	#else
	MIPS_ENDIAN=
	#endif
	#endif
EOF
	cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
	eval "$cc_set_vars"
	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
	;;
    mips64el:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    openrisc*:Linux:*:*)
	GUESS=or1k-unknown-linux-$LIBC
	;;
    or32:Linux:*:* | or1k*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    padre:Linux:*:*)
	GUESS=sparc-unknown-linux-$LIBC
	;;
    parisc64:Linux:*:* | hppa64:Linux:*:*)
	GUESS=hppa64-unknown-linux-$LIBC
	;;
    parisc:Linux:*:* | hppa:Linux:*:*)
	# Look for CPU level
	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
	  PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
	  PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
	  *)    GUESS=hppa-unknown-linux-$LIBC ;;
	esac
	;;
    ppc64:Linux:*:*)
	GUESS=powerpc64-unknown-linux-$LIBC
	;;
    ppc:Linux:*:*)
	GUESS=powerpc-unknown-linux-$LIBC
	;;
    ppc64le:Linux:*:*)
	GUESS=powerpc64le-unknown-linux-$LIBC
	;;
    ppcle:Linux:*:*)
	GUESS=powerpcle-unknown-linux-$LIBC
	;;
    riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    s390:Linux:*:* | s390x:Linux:*:*)
	GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
	;;
    sh64*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    sh*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    sparc:Linux:*:* | sparc64:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    tile*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    vax:Linux:*:*)
	GUESS=$UNAME_MACHINE-dec-linux-$LIBC
	;;
    x86_64:Linux:*:*)
	set_cc_for_build
	LIBCABI=$LIBC
	if test "$CC_FOR_BUILD" != no_compiler_found; then
	    if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
		grep IS_X32 >/dev/null
	    then
		LIBCABI=${LIBC}x32
	    fi
	fi
	GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
	;;
    xtensa*:Linux:*:*)
	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
	;;
    i*86:DYNIX/ptx:4*:*)
	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
	# earlier versions are messed up and put the nodename in both
	# sysname and nodename.
	GUESS=i386-sequent-sysv4
	;;
    i*86:UNIX_SV:4.2MP:2.*)
	# Unixware is an offshoot of SVR4, but it has its own version
	# number series starting with 2...
	# I am not positive that other SVR4 systems won't match this,
	# I just have to hope.  -- rms.
	# Use sysv4.2uw... so that sysv4* matches it.
	GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
	;;
    i*86:OS/2:*:*)
	# If we were able to find `uname', then EMX Unix compatibility
	# is probably installed.
	GUESS=$UNAME_MACHINE-pc-os2-emx
	;;
    i*86:XTS-300:*:STOP)
	GUESS=$UNAME_MACHINE-unknown-stop
	;;
    i*86:atheos:*:*)
	GUESS=$UNAME_MACHINE-unknown-atheos
	;;
    i*86:syllable:*:*)
	GUESS=$UNAME_MACHINE-pc-syllable
	;;
    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
	GUESS=i386-unknown-lynxos$UNAME_RELEASE
	;;
    i*86:*DOS:*:*)
	GUESS=$UNAME_MACHINE-pc-msdosdjgpp
	;;
    i*86:*:4.*:*)
	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
		GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
	else
		GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
	fi
	;;
    i*86:*:5:[678]*)
	# UnixWare 7.x, OpenUNIX and OpenServer 6.
	case `/bin/uname -X | grep "^Machine"` in
	    *486*)	     UNAME_MACHINE=i486 ;;
	    *Pentium)	     UNAME_MACHINE=i586 ;;
	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
	esac
	GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
	;;
    i*86:*:3.2:*)
	if test -f /usr/options/cb.name; then
		UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then
		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
			&& UNAME_MACHINE=i586
		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
			&& UNAME_MACHINE=i686
		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
			&& UNAME_MACHINE=i686
		GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
	else
		GUESS=$UNAME_MACHINE-pc-sysv32
	fi
	;;
    pc:*:*:*)
	# Left here for compatibility:
	# uname -m prints for DJGPP always 'pc', but it prints nothing about
	# the processor, so we play safe by assuming i586.
	# Note: whatever this is, it MUST be the same as what config.sub
	# prints for the "djgpp" host, or else GDB configure will decide that
	# this is a cross-build.
	GUESS=i586-pc-msdosdjgpp
	;;
    Intel:Mach:3*:*)
	GUESS=i386-pc-mach3
	;;
    paragon:*:*:*)
	GUESS=i860-intel-osf1
	;;
    i860:*:4.*:*) # i860-SVR4
	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
	  GUESS=i860-stardent-sysv$UNAME_RELEASE    # Stardent Vistra i860-SVR4
	else # Add other i860-SVR4 vendors below as they are discovered.
	  GUESS=i860-unknown-sysv$UNAME_RELEASE     # Unknown i860-SVR4
	fi
	;;
    mini*:CTIX:SYS*5:*)
	# "miniframe"
	GUESS=m68010-convergent-sysv
	;;
    mc68k:UNIX:SYSTEM5:3.51m)
	GUESS=m68k-convergent-sysv
	;;
    M680?0:D-NIX:5.3:*)
	GUESS=m68k-diab-dnix
	;;
    M68*:*:R3V[5678]*:*)
	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
	OS_REL=''
	test -r /etc/.relid \
	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
	  && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
	  && { echo i486-ncr-sysv4; exit; } ;;
    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
	OS_REL='.3'
	test -r /etc/.relid \
	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
	GUESS=m68k-unknown-lynxos$UNAME_RELEASE
	;;
    mc68030:UNIX_System_V:4.*:*)
	GUESS=m68k-atari-sysv4
	;;
    TSUNAMI:LynxOS:2.*:*)
	GUESS=sparc-unknown-lynxos$UNAME_RELEASE
	;;
    rs6000:LynxOS:2.*:*)
	GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
	;;
    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
	GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
	;;
    SM[BE]S:UNIX_SV:*:*)
	GUESS=mips-dde-sysv$UNAME_RELEASE
	;;
    RM*:ReliantUNIX-*:*:*)
	GUESS=mips-sni-sysv4
	;;
    RM*:SINIX-*:*:*)
	GUESS=mips-sni-sysv4
	;;
    *:SINIX-*:*:*)
	if uname -p 2>/dev/null >/dev/null ; then
		UNAME_MACHINE=`(uname -p) 2>/dev/null`
		GUESS=$UNAME_MACHINE-sni-sysv4
	else
		GUESS=ns32k-sni-sysv
	fi
	;;
    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
			# says 
	GUESS=i586-unisys-sysv4
	;;
    *:UNIX_System_V:4*:FTX*)
	# From Gerald Hewes .
	# How about differentiating between stratus architectures? -djm
	GUESS=hppa1.1-stratus-sysv4
	;;
    *:*:*:FTX*)
	# From seanf@swdc.stratus.com.
	GUESS=i860-stratus-sysv4
	;;
    i*86:VOS:*:*)
	# From Paul.Green@stratus.com.
	GUESS=$UNAME_MACHINE-stratus-vos
	;;
    *:VOS:*:*)
	# From Paul.Green@stratus.com.
	GUESS=hppa1.1-stratus-vos
	;;
    mc68*:A/UX:*:*)
	GUESS=m68k-apple-aux$UNAME_RELEASE
	;;
    news*:NEWS-OS:6*:*)
	GUESS=mips-sony-newsos6
	;;
    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
	if test -d /usr/nec; then
		GUESS=mips-nec-sysv$UNAME_RELEASE
	else
		GUESS=mips-unknown-sysv$UNAME_RELEASE
	fi
	;;
    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
	GUESS=powerpc-be-beos
	;;
    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
	GUESS=powerpc-apple-beos
	;;
    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
	GUESS=i586-pc-beos
	;;
    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
	GUESS=i586-pc-haiku
	;;
    x86_64:Haiku:*:*)
	GUESS=x86_64-unknown-haiku
	;;
    SX-4:SUPER-UX:*:*)
	GUESS=sx4-nec-superux$UNAME_RELEASE
	;;
    SX-5:SUPER-UX:*:*)
	GUESS=sx5-nec-superux$UNAME_RELEASE
	;;
    SX-6:SUPER-UX:*:*)
	GUESS=sx6-nec-superux$UNAME_RELEASE
	;;
    SX-7:SUPER-UX:*:*)
	GUESS=sx7-nec-superux$UNAME_RELEASE
	;;
    SX-8:SUPER-UX:*:*)
	GUESS=sx8-nec-superux$UNAME_RELEASE
	;;
    SX-8R:SUPER-UX:*:*)
	GUESS=sx8r-nec-superux$UNAME_RELEASE
	;;
    SX-ACE:SUPER-UX:*:*)
	GUESS=sxace-nec-superux$UNAME_RELEASE
	;;
    Power*:Rhapsody:*:*)
	GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
	;;
    *:Rhapsody:*:*)
	GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
	;;
    arm64:Darwin:*:*)
	GUESS=aarch64-apple-darwin$UNAME_RELEASE
	;;
    *:Darwin:*:*)
	UNAME_PROCESSOR=`uname -p`
	case $UNAME_PROCESSOR in
	    unknown) UNAME_PROCESSOR=powerpc ;;
	esac
	if command -v xcode-select > /dev/null 2> /dev/null && \
		! xcode-select --print-path > /dev/null 2> /dev/null ; then
	    # Avoid executing cc if there is no toolchain installed as
	    # cc will be a stub that puts up a graphical alert
	    # prompting the user to install developer tools.
	    CC_FOR_BUILD=no_compiler_found
	else
	    set_cc_for_build
	fi
	if test "$CC_FOR_BUILD" != no_compiler_found; then
	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
		   grep IS_64BIT_ARCH >/dev/null
	    then
		case $UNAME_PROCESSOR in
		    i386) UNAME_PROCESSOR=x86_64 ;;
		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
		esac
	    fi
	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
		   grep IS_PPC >/dev/null
	    then
		UNAME_PROCESSOR=powerpc
	    fi
	elif test "$UNAME_PROCESSOR" = i386 ; then
	    # uname -m returns i386 or x86_64
	    UNAME_PROCESSOR=$UNAME_MACHINE
	fi
	GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
	;;
    *:procnto*:*:* | *:QNX:[0123456789]*:*)
	UNAME_PROCESSOR=`uname -p`
	if test "$UNAME_PROCESSOR" = x86; then
		UNAME_PROCESSOR=i386
		UNAME_MACHINE=pc
	fi
	GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
	;;
    *:QNX:*:4*)
	GUESS=i386-pc-qnx
	;;
    NEO-*:NONSTOP_KERNEL:*:*)
	GUESS=neo-tandem-nsk$UNAME_RELEASE
	;;
    NSE-*:NONSTOP_KERNEL:*:*)
	GUESS=nse-tandem-nsk$UNAME_RELEASE
	;;
    NSR-*:NONSTOP_KERNEL:*:*)
	GUESS=nsr-tandem-nsk$UNAME_RELEASE
	;;
    NSV-*:NONSTOP_KERNEL:*:*)
	GUESS=nsv-tandem-nsk$UNAME_RELEASE
	;;
    NSX-*:NONSTOP_KERNEL:*:*)
	GUESS=nsx-tandem-nsk$UNAME_RELEASE
	;;
    *:NonStop-UX:*:*)
	GUESS=mips-compaq-nonstopux
	;;
    BS2000:POSIX*:*:*)
	GUESS=bs2000-siemens-sysv
	;;
    DS/*:UNIX_System_V:*:*)
	GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
	;;
    *:Plan9:*:*)
	# "uname -m" is not consistent, so use $cputype instead. 386
	# is converted to i386 for consistency with other x86
	# operating systems.
	if test "${cputype-}" = 386; then
	    UNAME_MACHINE=i386
	elif test "x${cputype-}" != x; then
	    UNAME_MACHINE=$cputype
	fi
	GUESS=$UNAME_MACHINE-unknown-plan9
	;;
    *:TOPS-10:*:*)
	GUESS=pdp10-unknown-tops10
	;;
    *:TENEX:*:*)
	GUESS=pdp10-unknown-tenex
	;;
    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
	GUESS=pdp10-dec-tops20
	;;
    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
	GUESS=pdp10-xkl-tops20
	;;
    *:TOPS-20:*:*)
	GUESS=pdp10-unknown-tops20
	;;
    *:ITS:*:*)
	GUESS=pdp10-unknown-its
	;;
    SEI:*:*:SEIUX)
	GUESS=mips-sei-seiux$UNAME_RELEASE
	;;
    *:DragonFly:*:*)
	DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
	GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
	;;
    *:*VMS:*:*)
	UNAME_MACHINE=`(uname -p) 2>/dev/null`
	case $UNAME_MACHINE in
	    A*) GUESS=alpha-dec-vms ;;
	    I*) GUESS=ia64-dec-vms ;;
	    V*) GUESS=vax-dec-vms ;;
	esac ;;
    *:XENIX:*:SysV)
	GUESS=i386-pc-xenix
	;;
    i*86:skyos:*:*)
	SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
	GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
	;;
    i*86:rdos:*:*)
	GUESS=$UNAME_MACHINE-pc-rdos
	;;
    i*86:Fiwix:*:*)
	GUESS=$UNAME_MACHINE-pc-fiwix
	;;
    *:AROS:*:*)
	GUESS=$UNAME_MACHINE-unknown-aros
	;;
    x86_64:VMkernel:*:*)
	GUESS=$UNAME_MACHINE-unknown-esx
	;;
    amd64:Isilon\ OneFS:*:*)
	GUESS=x86_64-unknown-onefs
	;;
    *:Unleashed:*:*)
	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
	;;
esac

# Do we have a guess based on uname results?
if test "x$GUESS" != x; then
    echo "$GUESS"
    exit
fi

# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <
#include 
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#include 
#if defined(_SIZE_T_) || defined(SIGLOST)
#include 
#endif
#endif
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
     I don't know....  */
  printf ("mips-sony-bsd\n"); exit (0);
#else
#include 
  printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
  "4"
#else
  ""
#endif
  ); exit (0);
#endif
#endif

#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
  int version;
  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
  if (version < 4)
    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
  else
    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
  exit (0);
#endif

#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
  printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
  printf ("ns32k-encore-mach\n"); exit (0);
#else
  printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif

#if defined (__386BSD__)
  printf ("i386-pc-bsd\n"); exit (0);
#endif

#if defined (sequent)
#if defined (i386)
  printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
  printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif

#if defined (_SEQUENT_)
  struct utsname un;

  uname(&un);
  if (strncmp(un.version, "V2", 2) == 0) {
    printf ("i386-sequent-ptx2\n"); exit (0);
  }
  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
    printf ("i386-sequent-ptx1\n"); exit (0);
  }
  printf ("i386-sequent-ptx\n"); exit (0);
#endif

#if defined (vax)
#if !defined (ultrix)
#include 
#if defined (BSD)
#if BSD == 43
  printf ("vax-dec-bsd4.3\n"); exit (0);
#else
#if BSD == 199006
  printf ("vax-dec-bsd4.3reno\n"); exit (0);
#else
  printf ("vax-dec-bsd\n"); exit (0);
#endif
#endif
#else
  printf ("vax-dec-bsd\n"); exit (0);
#endif
#else
#if defined(_SIZE_T_) || defined(SIGLOST)
  struct utsname un;
  uname (&un);
  printf ("vax-dec-ultrix%s\n", un.release); exit (0);
#else
  printf ("vax-dec-ultrix\n"); exit (0);
#endif
#endif
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#if defined(_SIZE_T_) || defined(SIGLOST)
  struct utsname *un;
  uname (&un);
  printf ("mips-dec-ultrix%s\n", un.release); exit (0);
#else
  printf ("mips-dec-ultrix\n"); exit (0);
#endif
#endif
#endif

#if defined (alliant) && defined (i860)
  printf ("i860-alliant-bsd\n"); exit (0);
#endif

  exit (1);
}
EOF

$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
	{ echo "$SYSTEM_NAME"; exit; }

# Apollos put the system type in the environment.
test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }

echo "$0: unable to guess system type" >&2

case $UNAME_MACHINE:$UNAME_SYSTEM in
    mips:Linux | mips64:Linux)
	# If we got here on MIPS GNU/Linux, output extra information.
	cat >&2 <&2 <&2 </dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`

/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`

hostinfo               = `(hostinfo) 2>/dev/null`
/bin/universe          = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch              = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`

UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
UNAME_SYSTEM  = "$UNAME_SYSTEM"
UNAME_VERSION = "$UNAME_VERSION"
EOF
fi

exit 1

# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
thrift-0.23.0/lib/0000755000175000017500000000000015170007201014113 5ustar00buildbuild00000000000000thrift-0.23.0/lib/ts/0000775000175000017500000000000015170007175014555 5ustar00buildbuild00000000000000thrift-0.23.0/lib/ts/dist/0000775000175000017500000000000015165535636015534 5ustar00buildbuild00000000000000thrift-0.23.0/lib/ts/dist/thrift.js0000664000175000017500000000000015165535636017360 0ustar00buildbuild00000000000000thrift-0.23.0/lib/ts/dist/thrift.min.js0000664000175000017500000000003115165535636020146 0ustar00buildbuild00000000000000/*! thrift 07-01-2019 */
thrift-0.23.0/lib/ts/tsconfig.json0000664000175000017500000000134215165535636017300 0ustar00buildbuild00000000000000{
    "compilerOptions": {
        "allowJs": false,
        "alwaysStrict": true,
        "baseUrl": ".",
        "declaration": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "module": "commonjs",
        "moduleResolution": "node",
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "preserveConstEnums": true,
        "removeComments": true,
        "strictFunctionTypes": true,
        "strictNullChecks": true,
        "target": "es6",
        "paths": {
            "*": [
                "*",
                "test/",
                "test/gen-js/*"

            ]
        },
    },
    "exclude": [
        "./test/gen-nodejs/",
        "./test/build/",
    ]
}
thrift-0.23.0/lib/ts/test/0000775000175000017500000000000015165535636015550 5ustar00buildbuild00000000000000thrift-0.23.0/lib/ts/test/server_http.js0000664000175000017500000000414515165535636020457 0ustar00buildbuild00000000000000/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

//  This HTTP server is designed to serve the test.html browser
//  based JavaScript test page (which must be in the current directory).
//  This server also supplies the Thrift based test service, which depends
//  on the standard ThriftTest.thrift IDL service (which must be compiled
//  for Node and browser based JavaScript in ./gen-nodejs and ./gen-js
//  respectively).
//
//  Using the command flag --es6, this server can be run using nodejs code built
//  for the es6 environment or for pre-es6 environment.
//

const thrift = require("../../nodejs/lib/thrift");
const es6Mode = process.argv.includes("--es6");
const genFolder = es6Mode ? "gen-nodejs-es6" : "gen-nodejs";
const ThriftTestSvc = require(`./${genFolder}/ThriftTest.js`);
const ThriftTestHandler = require("./test_handler").ThriftTestHandler;

const ThriftTestSvcOpt = {
  transport: thrift.TBufferedTransport,
  protocol: thrift.TJSONProtocol,
  processor: ThriftTestSvc,
  handler: ThriftTestHandler,
};

const ThriftWebServerOptions = {
  files: __dirname,
  services: {
    "/service": ThriftTestSvcOpt,
  },
};

const server = thrift.createWebServer(ThriftWebServerOptions);
const port = es6Mode ? 8088 : 8089;
server.listen(port);
console.log(`Serving files from: ${__dirname}`);
console.log(
  `Http/Thrift Server (ES6 mode ${es6Mode}) running on port: ${port}`,
);
thrift-0.23.0/lib/ts/test/phantom-client.ts0000664000175000017500000003226515165535636021052 0ustar00buildbuild00000000000000/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/* jshint -W100 */

import { ThriftTest } from "./gen-js/ThriftTest_types";
import "./gen-js/ThriftTest";
var Int64 = require("node-int64");
var phantom = require("phantom");

const int64_2_pow_60: typeof Int64 = new Int64("1000000000000000");
const int64_minus_2_pow_60: typeof Int64 = new Int64("f000000000000000");

(function () {
  "use strict";

  // Rudimentary test helper functions
  // TODO: Return error code based on kind of errors rather than throw
  var ok = function (t, msg) {
    if (!t) {
      console.log("*** FAILED ***");
      throw new Error(msg);
    }
  };
  var equal = function (a, b) {
    if (a !== b) {
      console.log("*** FAILED ***");
      throw new Error();
    }
  };
  var test = function (name, f) {
    console.log("TEST : " + name);
    f();
    console.log("OK\n");
  };

  var parseArgs = function (args) {
    var skips = ["--transport=http", "--protocol=json"];
    var opts = {
      port: "9090",
      // protocol: 'json',
    };
    var keys = {};
    for (var key in opts) {
      keys["--" + key + "="] = key;
    }
    for (var i in args) {
      var arg = args[i];
      if (skips.indexOf(arg) != -1) {
        continue;
      }
      var hit = false;
      for (var k in keys) {
        if (arg.slice(0, k.length) === k) {
          opts[keys[k]] = arg.slice(k.length);
          hit = true;
          break;
        }
      }
      if (!hit) {
        throw new Error("Unknown argument: " + arg);
      }
    }
    var portAsInt: number = parseInt(opts.port, 10);
    if (!opts.port || portAsInt < 1 || portAsInt > 65535) {
      throw new Error("Invalid port number");
    }
    return opts;
  };

  var execute = function () {
    console.log("### Apache Thrift Javascript standalone test client");
    console.log("------------------------------------------------------------");

    phantom.page.injectJs("thrift.js");
    phantom.page.injectJs("gen-js/ThriftTest_types.js");
    phantom.page.injectJs("gen-js/ThriftTest.js");

    var system = require("system");
    var opts = parseArgs(system.args.slice(1));
    var port = opts.port;
    var transport = new Thrift.Transport(
      "http://localhost:" + port + "/service",
    );
    var protocol = new Thrift.Protocol(transport);
    var client = new ThriftTest.ThriftTestClient(protocol);

    // TODO: Remove duplicate code with test.js.
    // all Languages in UTF-8
    var stringTest =
      "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, AzÉ™rbaycan, Башҡорт, Boarisch, ŽemaitÄ—Å¡ka, БеларуÑкаÑ, БеларуÑÐºÐ°Ñ (тарашкевіца), БългарÑки, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Ðохчийн, Cebuano, á£áŽ³áŽ©, ÄŒesky, СловѣÌньÑкъ / ⰔⰎⰑⰂⰡâ°â° â°”â°â°Ÿ, Чӑвашла, Cymraeg, Dansk, Zazaki, Þ‹Þ¨ÞˆÞ¬Þ€Þ¨Þ„Þ¦ÞÞ°, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, ÙØ§Ø±Ø³ÛŒ, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, Avañe'ẽ, ગà«àªœàª°àª¾àª¤à«€, Gaelg, עברית, हिनà¥à¤¦à¥€, Fiji Hindi, Hrvatski, Kreyòl ayisyen, Magyar, Õ€Õ¡ÕµÕ¥Ö€Õ¥Õ¶, Interlingua, Bahasa Indonesia, Ilokano, Ido, Ãslenska, Italiano, 日本語, Lojban, Basa Jawa, ქáƒáƒ áƒ—ული, Kongo, Kalaallisut, ಕನà³à²¨à²¡, 한국어, Къарачай-Малкъар, Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, LatvieÅ¡u, Basa Banyumasan, Malagasy, МакедонÑки, മലയാളം, मराठी, Bahasa Melayu, Ù…Ø§Ø²ÙØ±ÙˆÙ†ÛŒ, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪Norsk (nynorsk)‬, ‪Norsk (bokmÃ¥l)‬, Nouormand, Diné bizaad, Occitan, Иронау, Papiamentu, Deitsch, Norfuk / Pitkern, Polski, پنجابی, پښتو, Português, Runa Simi, Rumantsch, Romani, Română, РуÑÑкий, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple English, SlovenÄina, SlovenÅ¡Äina, СрпÑки / Srpski, Seeltersk, Svenska, Kiswahili, தமிழà¯, తెలà±à°—à±, Тоҷикӣ, ไทย, Türkmençe, Tagalog, Türkçe, Татарча/Tatarça, УкраїнÑька, اردو, Tiếng Việt, Volapük, Walon, Winaray, å´è¯­, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, Bân-lâm-gú, 粵語";

    function checkRecursively(map1, map2) {
      if (typeof map1 !== "function" && typeof map2 !== "function") {
        if (!map1 || typeof map1 !== "object") {
          equal(map1, map2);
        } else {
          for (var key in map1) {
            checkRecursively(map1[key], map2[key]);
          }
        }
      }
    }

    test("Void", function () {
      equal(client.testVoid(), undefined);
    });
    test("Binary (String)", function () {
      var binary: string = "";
      for (var v = 255; v >= 0; --v) {
        binary += String.fromCharCode(v);
      }
      equal(client.testBinary(binary), binary);
    });
    test("Binary (Uint8Array)", function () {
      var binary: string = "";
      for (var v = 255; v >= 0; --v) {
        binary += String.fromCharCode(v);
      }
      var arr = new Uint8Array(binary.length);
      for (var i = 0; i < binary.length; ++i) {
        arr[i] = binary[i].charCodeAt(0);
      }
      const hexEncodedString = Array.from(arr, function (byte) {
        return String.fromCharCode(byte);
      }).join("");
      equal(client.testBinary(hexEncodedString), binary);
    });
    test("String", function () {
      equal(client.testString(""), "");
      equal(client.testString(stringTest), stringTest);

      var specialCharacters =
        'quote: \" backslash:' +
        " forwardslash-escaped: \/ " +
        " backspace: \b formfeed: \f newline: \n return: \r tab: " +
        ' now-all-of-them-together: "\\\/\b\n\r\t' +
        " now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><";
      equal(client.testString(specialCharacters), specialCharacters);
    });
    test("Double", function () {
      equal(client.testDouble(0), 0);
      equal(client.testDouble(-1), -1);
      equal(client.testDouble(3.14), 3.14);
      equal(client.testDouble(Math.pow(2, 60)), Math.pow(2, 60));
    });
    test("Bool", function () {
      equal(client.testBool(true), true);
      equal(client.testBool(false), false);
    });
    test("I8", function () {
      equal(client.testByte(0), 0);
      equal(client.testByte(0x01), 0x01);
    });
    test("I32", function () {
      equal(client.testI32(0), 0);
      equal(client.testI32(Math.pow(2, 30)), Math.pow(2, 30));
      equal(client.testI32(-Math.pow(2, 30)), -Math.pow(2, 30));
    });
    test("I64", function () {
      equal(client.testI64(new Int64(0)), 0);
      equal(client.testI64(int64_2_pow_60), Math.pow(2, 52));
      equal(client.testI64(int64_minus_2_pow_60), -Math.pow(2, 52));
    });

    test("Struct", function () {
      var structTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct();
      structTestInput.string_thing = "worked";
      structTestInput.byte_thing = 0x01;
      structTestInput.i32_thing = Math.pow(2, 30);
      structTestInput.i64_thing = int64_2_pow_60;

      var structTestOutput: ThriftTest.Xtruct =
        client.testStruct(structTestInput);

      equal(structTestOutput.string_thing, structTestInput.string_thing);
      equal(structTestOutput.byte_thing, structTestInput.byte_thing);
      equal(structTestOutput.i32_thing, structTestInput.i32_thing);
      equal(structTestOutput.i64_thing, structTestInput.i64_thing);

      equal(JSON.stringify(structTestOutput), JSON.stringify(structTestInput));
    });

    test("Nest", function () {
      var xtrTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct();
      xtrTestInput.string_thing = "worked";
      xtrTestInput.byte_thing = 0x01;
      xtrTestInput.i32_thing = Math.pow(2, 30);
      xtrTestInput.i64_thing = int64_2_pow_60;

      var nestTestInput: ThriftTest.Xtruct2 = new ThriftTest.Xtruct2();
      nestTestInput.byte_thing = 0x02;
      nestTestInput.struct_thing = xtrTestInput;
      nestTestInput.i32_thing = Math.pow(2, 15);

      var nestTestOutput = client.testNest(nestTestInput);

      equal(nestTestOutput.byte_thing, nestTestInput.byte_thing);
      equal(
        nestTestOutput.struct_thing.string_thing,
        nestTestInput.struct_thing.string_thing,
      );
      equal(
        nestTestOutput.struct_thing.byte_thing,
        nestTestInput.struct_thing.byte_thing,
      );
      equal(
        nestTestOutput.struct_thing.i32_thing,
        nestTestInput.struct_thing.i32_thing,
      );
      equal(
        nestTestOutput.struct_thing.i64_thing,
        nestTestInput.struct_thing.i64_thing,
      );
      equal(nestTestOutput.i32_thing, nestTestInput.i32_thing);

      equal(JSON.stringify(nestTestOutput), JSON.stringify(nestTestInput));
    });

    test("Map", function () {
      var mapTestInput: { [k: number]: number } = { 7: 77, 8: 88, 9: 99 };

      var mapTestOutput: { [k: number]: number } = client.testMap(mapTestInput);

      for (var key in mapTestOutput) {
        equal(mapTestOutput[key], mapTestInput[key]);
      }
    });

    test("StringMap", function () {
      var mapTestInput: { [k: string]: string } = {
        a: "123",
        "a b": "with spaces ",
        same: "same",
        "0": "numeric key",
        longValue: stringTest,
        stringTest: "long key",
      };

      var mapTestOutput: { [k: string]: string } =
        client.testStringMap(mapTestInput);

      for (var key in mapTestOutput) {
        equal(mapTestOutput[key], mapTestInput[key]);
      }
    });

    test("Set", function () {
      var setTestInput: number[] = [1, 2, 3];
      ok(client.testSet(setTestInput), setTestInput);
    });

    test("List", function () {
      var listTestInput: number[] = [1, 2, 3];
      ok(client.testList(listTestInput), listTestInput);
    });

    test("Enum", function () {
      equal(client.testEnum(ThriftTest.Numberz.ONE), ThriftTest.Numberz.ONE);
    });

    test("TypeDef", function () {
      equal(client.testTypedef(new Int64(69)), 69);
    });

    test("MapMap", function () {
      var mapMapTestExpectedResult: { [K: number]: { [k: number]: number } } = {
        "4": { "1": 1, "2": 2, "3": 3, "4": 4 },
        "-4": { "-4": -4, "-3": -3, "-2": -2, "-1": -1 },
      };

      var mapMapTestOutput = client.testMapMap(1);

      for (var key in mapMapTestOutput) {
        for (var key2 in mapMapTestOutput[key]) {
          equal(
            mapMapTestOutput[key][key2],
            mapMapTestExpectedResult[key][key2],
          );
        }
      }

      checkRecursively(mapMapTestOutput, mapMapTestExpectedResult);
    });

    test("Xception", function () {
      try {
        client.testException("Xception");
        ok(false, "expected an exception but there was no exception");
      } catch (e) {
        equal(e.errorCode, 1001);
        equal(e.message, "Xception");
      }
    });

    test("no Exception", function () {
      try {
        client.testException("no Exception");
      } catch (e) {
        ok(false, "expected no exception but here was an exception");
      }
    });

    test("TException", function () {
      try {
        client.testException("TException");
        ok(false, "expected an exception but there was no exception");
      } catch (e) {
        ok(ok, "succesfully got exception");
      }
    });

    const crazy: ThriftTest.Insanity = {
      userMap: { "5": new Int64(5), "8": new Int64(8) },
      xtructs: [
        {
          string_thing: "Goodbye4",
          byte_thing: 4,
          i32_thing: 4,
          i64_thing: new Int64(4),
        },
        {
          string_thing: "Hello2",
          byte_thing: 2,
          i32_thing: 2,
          i64_thing: new Int64(2),
        },
      ],
    };
    test("Insanity", function () {
      const insanity: {
        [k: number]: ThriftTest.Insanity | { [k: number]: ThriftTest.Insanity };
      } = {
        "1": {
          "2": crazy,
          "3": crazy,
        },
        "2": { "6": new ThriftTest.Insanity() },
      };
      var res = client.testInsanity(new ThriftTest.Insanity(crazy));
      ok(res, JSON.stringify(res));
      ok(insanity, JSON.stringify(insanity));

      checkRecursively(res, insanity);
    });

    console.log("------------------------------------------------------------");
    console.log("### All tests succeeded.");
    return 0;
  };

  try {
    var ret = execute();
    phantom.exit(ret);
  } catch (err) {
    // Catch all and exit to avoid hang.
    console.error(err);
    phantom.exit(1);
  }
})();
thrift-0.23.0/lib/ts/test/test.html0000664000175000017500000000513715165535636017423 0ustar00buildbuild00000000000000



  
  Thrift Javascript Bindings: Unit Test

  
  
  
  
  
  

  
  
  

  
  


  

Thrift Javascript Bindings: Unit Test (ThriftTest.thrift)

thrift-0.23.0/lib/ts/test/test-int64.html0000664000175000017500000000372215165535636020363 0ustar00buildbuild00000000000000+ Int64 Constants in JS: Unit Test

Int64 Constants in JS: Unit Test

thrift-0.23.0/lib/ts/test/build.xml0000664000175000017500000002342415165535636017376 0ustar00buildbuild00000000000000 Java Script Test based on Thrift Java Library You need libthrift*.jar and libthrift*test.jar located at ${thrift.java.dir}/build/libs Did you compile Thrift Java library and its test suite by "ant compile-test"? Thrift compiler is missing ! check if Xvfb is available: check if phantomjs is available: Running Unit Tests with headless browser! check if gjslint is available: thrift-0.23.0/lib/ts/test/test.ts0000664000175000017500000003054615165535636017107 0ustar00buildbuild00000000000000import { ThriftTest } from "./gen-js/ThriftTest_types"; import "./gen-js/ThriftTest"; var Int64 = require("node-int64"); var JSONInt64 = require("json-int64"); var QUnit = require("./qunit"); const transport: Thrift.Transport = new Thrift.Transport("/service"); const protocol: Thrift.Protocol = new Thrift.Protocol(transport); const client: ThriftTest.ThriftTestClient = new ThriftTest.ThriftTestClient( protocol, ); const int64_2_pow_60: typeof Int64 = new Int64("1000000000000000"); const int64_minus_2_pow_60: typeof Int64 = new Int64("f000000000000000"); // Work around for old API used by QUnitAdapter of jsTestDriver if (typeof QUnit.log == "function") { // When using real QUnit (fron PhantomJS) log failures to console QUnit.log(function (details) { if (!details.result) { console.log("======== FAIL ========"); console.log("TestName: " + details.name); if (details.message) console.log(details.message); console.log("Expected: " + JSONInt64.stringify(details.expected)); console.log("Actual : " + JSONInt64.stringify(details.actual)); console.log("======================"); } }); } // all Languages in UTF-8 const stringTest: string = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, AzÉ™rbaycan, Башҡорт, Boarisch, ŽemaitÄ—Å¡ka, БеларуÑкаÑ, БеларуÑÐºÐ°Ñ (тарашкевіца), БългарÑки, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Ðохчийн, Cebuano, á£áŽ³áŽ©, ÄŒesky, СловѣÌньÑкъ / ⰔⰎⰑⰂⰡâ°â° â°”â°â°Ÿ, Чӑвашла, Cymraeg, Dansk, Zazaki, Þ‹Þ¨ÞˆÞ¬Þ€Þ¨Þ„Þ¦ÞÞ°, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, ÙØ§Ø±Ø³ÛŒ, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, Avañe'ẽ, ગà«àªœàª°àª¾àª¤à«€, Gaelg, עברית, हिनà¥à¤¦à¥€, Fiji Hindi, Hrvatski, Kreyòl ayisyen, Magyar, Õ€Õ¡ÕµÕ¥Ö€Õ¥Õ¶, Interlingua, Bahasa Indonesia, Ilokano, Ido, Ãslenska, Italiano, 日本語, Lojban, Basa Jawa, ქáƒáƒ áƒ—ული, Kongo, Kalaallisut, ಕನà³à²¨à²¡, 한국어, Къарачай-Малкъар, Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, LatvieÅ¡u, Basa Banyumasan, Malagasy, МакедонÑки, മലയാളം, मराठी, Bahasa Melayu, Ù…Ø§Ø²ÙØ±ÙˆÙ†ÛŒ, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪Norsk (nynorsk)‬, ‪Norsk (bokmÃ¥l)‬, Nouormand, Diné bizaad, Occitan, Иронау, Papiamentu, Deitsch, Norfuk / Pitkern, Polski, پنجابی, پښتو, Português, Runa Simi, Rumantsch, Romani, Română, РуÑÑкий, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple English, SlovenÄina, SlovenÅ¡Äina, СрпÑки / Srpski, Seeltersk, Svenska, Kiswahili, தமிழà¯, తెలà±à°—à±, Тоҷикӣ, ไทย, Türkmençe, Tagalog, Türkçe, Татарча/Tatarça, УкраїнÑька, اردو, Tiếng Việt, Volapük, Walon, Winaray, å´è¯­, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, Bân-lâm-gú, 粵語"; function checkRecursively(assert, map1: Object, map2: Object): void { if (typeof map1 !== "function" && typeof map2 !== "function") { if (!map1 || typeof map1 !== "object") { assert.equal(map1, map2); } else { for (let key in map1) { checkRecursively(assert, map1[key], map2[key]); } } } } QUnit.module("Base Types"); QUnit.test("Void", function (assert) { assert.equal(client.testVoid(), undefined); }); QUnit.test("Binary (String)", function (assert) { let binary: string = ""; for (let v = 255; v >= 0; --v) { binary += String.fromCharCode(v); } assert.equal(client.testBinary(binary), binary); }); QUnit.test("Binary (Uint8Array)", function (assert) { let binary: string = ""; for (let v = 255; v >= 0; --v) { binary += String.fromCharCode(v); } const arr: Uint8Array = new Uint8Array(binary.length); for (let i = 0; i < binary.length; ++i) { arr[i] = binary[i].charCodeAt(0); } const hexEncodedString = Array.from(arr, function (byte) { return String.fromCharCode(byte); }).join(""); assert.equal(client.testBinary(hexEncodedString), binary); }); QUnit.test("String", function (assert) { assert.equal(client.testString(""), ""); assert.equal(client.testString(stringTest), stringTest); const specialCharacters: string = 'quote: \" backslash:' + " forwardslash-escaped: \/ " + " backspace: \b formfeed: \f newline: \n return: \r tab: " + ' now-all-of-them-together: "\\\/\b\n\r\t' + " now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><"; assert.equal(client.testString(specialCharacters), specialCharacters); }); QUnit.test("Double", function (assert) { assert.equal(client.testDouble(0), 0); assert.equal(client.testDouble(-1), -1); assert.equal(client.testDouble(3.14), 3.14); assert.equal(client.testDouble(Math.pow(2, 60)), Math.pow(2, 60)); }); QUnit.test("Byte", function (assert) { assert.equal(client.testByte(0), 0); assert.equal(client.testByte(0x01), 0x01); }); QUnit.test("I32", function (assert) { assert.equal(client.testI32(0), 0); assert.equal(client.testI32(Math.pow(2, 30)), Math.pow(2, 30)); assert.equal(client.testI32(-Math.pow(2, 30)), -Math.pow(2, 30)); }); QUnit.test("I64", function (assert) { assert.equal(client.testI64(new Int64(0)), 0); let int64_2_pow_60_result: typeof Int64 = client.testI64(int64_2_pow_60); assert.ok(int64_2_pow_60.equals(int64_2_pow_60_result)); let int64_minus_2_pow_60_result: typeof Int64 = client.testI64(int64_minus_2_pow_60); assert.ok(int64_minus_2_pow_60.equals(int64_minus_2_pow_60_result)); }); QUnit.module("Structured Types"); QUnit.test("Struct", function (assert) { const structTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct(); structTestInput.string_thing = "worked"; structTestInput.byte_thing = 0x01; structTestInput.i32_thing = Math.pow(2, 30); structTestInput.i64_thing = int64_2_pow_60; const structTestOutput: ThriftTest.Xtruct = client.testStruct(structTestInput); assert.equal(structTestOutput.string_thing, structTestInput.string_thing); assert.equal(structTestOutput.byte_thing, structTestInput.byte_thing); assert.equal(structTestOutput.i32_thing, structTestInput.i32_thing); assert.ok(structTestOutput.i64_thing.equals(structTestInput.i64_thing)); assert.ok(structTestInput.i64_thing.equals(structTestOutput.i64_thing)); assert.equal( JSONInt64.stringify(structTestOutput), JSONInt64.stringify(structTestInput), ); }); QUnit.test("Nest", function (assert) { const xtrTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct(); xtrTestInput.string_thing = "worked"; xtrTestInput.byte_thing = 0x01; xtrTestInput.i32_thing = Math.pow(2, 30); xtrTestInput.i64_thing = int64_2_pow_60; const nestTestInput: ThriftTest.Xtruct2 = new ThriftTest.Xtruct2(); nestTestInput.byte_thing = 0x02; nestTestInput.struct_thing = xtrTestInput; nestTestInput.i32_thing = Math.pow(2, 15); const nestTestOutput: ThriftTest.Xtruct2 = client.testNest(nestTestInput); assert.equal(nestTestOutput.byte_thing, nestTestInput.byte_thing); assert.equal( nestTestOutput.struct_thing.string_thing, nestTestInput.struct_thing.string_thing, ); assert.equal( nestTestOutput.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing, ); assert.equal( nestTestOutput.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing, ); assert.ok( nestTestOutput.struct_thing.i64_thing.equals( nestTestInput.struct_thing.i64_thing, ), ); assert.equal(nestTestOutput.i32_thing, nestTestInput.i32_thing); assert.equal( JSONInt64.stringify(nestTestOutput), JSONInt64.stringify(nestTestInput), ); }); QUnit.test("Map", function (assert) { const mapTestInput: { [k: number]: number } = { 7: 77, 8: 88, 9: 99 }; const mapTestOutput: { [k: number]: number } = client.testMap(mapTestInput); for (let key in mapTestOutput) { assert.equal(mapTestOutput[key], mapTestInput[key]); } }); QUnit.test("StringMap", function (assert) { const mapTestInput: { [k: string]: string } = { a: "123", "a b": "with spaces ", same: "same", "0": "numeric key", longValue: stringTest, stringTest: "long key", }; const mapTestOutput: { [k: string]: string } = client.testStringMap(mapTestInput); for (let key in mapTestOutput) { assert.equal(mapTestOutput[key], mapTestInput[key]); } }); QUnit.test("Set", function (assert) { const setTestInput: number[] = [1, 2, 3]; assert.ok(client.testSet(setTestInput), setTestInput); }); QUnit.test("List", function (assert) { const listTestInput: number[] = [1, 2, 3]; assert.ok(client.testList(listTestInput), listTestInput); }); QUnit.test("Enum", function (assert) { assert.equal(client.testEnum(ThriftTest.Numberz.ONE), ThriftTest.Numberz.ONE); }); QUnit.test("TypeDef", function (assert) { assert.equal(client.testTypedef(new Int64(69)), 69); }); QUnit.module("deeper!"); QUnit.test("MapMap", function (assert) { const mapMapTestExpectedResult: { [K: number]: { [k: number]: number } } = { "4": { "1": 1, "2": 2, "3": 3, "4": 4 }, "-4": { "-4": -4, "-3": -3, "-2": -2, "-1": -1 }, }; const mapMapTestOutput = client.testMapMap(1); for (let key in mapMapTestOutput) { for (let key2 in mapMapTestOutput[key]) { assert.equal( mapMapTestOutput[key][key2], mapMapTestExpectedResult[key][key2], ); } } checkRecursively(assert, mapMapTestOutput, mapMapTestExpectedResult); }); QUnit.module("Exception"); QUnit.test("Xception", function (assert) { assert.expect(2); const done = assert.async(); try { client.testException("Xception"); assert.ok(false); } catch (e) { assert.equal(e.errorCode, 1001); assert.equal(e.message, "Xception"); done(); } }); QUnit.test("no Exception", function (assert) { assert.expect(1); try { client.testException("no Exception"); assert.ok(true); } catch (e) { assert.ok(false); } }); QUnit.test("TException", function (assert) { //ThriftTest does not list TException as a legal exception so it will // generate an exception on the server that does not propagate back to // the client. This test has been modified to equate to "no exception" assert.expect(1); try { client.testException("TException"); } catch (e) { //assert.ok(false); } assert.ok(true); }); QUnit.module("Insanity"); const crazy: ThriftTest.Insanity = { userMap: { "5": new Int64(5), "8": new Int64(8) }, xtructs: [ { string_thing: "Goodbye4", byte_thing: 4, i32_thing: 4, i64_thing: new Int64(4), }, { string_thing: "Hello2", byte_thing: 2, i32_thing: 2, i64_thing: new Int64(2), }, ], }; QUnit.test("testInsanity", function (assert) { const insanity: { [k: number]: ThriftTest.Insanity | { [k: number]: ThriftTest.Insanity }; } = { "1": { "2": crazy, "3": crazy, }, "2": { "6": new ThriftTest.Insanity() }, }; const res = client.testInsanity(new ThriftTest.Insanity(crazy)); assert.ok(res, JSONInt64.stringify(res)); assert.ok(insanity, JSONInt64.stringify(insanity)); checkRecursively(assert, res, insanity); }); ////////////////////////////////// //Run same tests asynchronously QUnit.module("Async"); QUnit.test("Double", function (assert) { assert.expect(1); const done = assert.async(); client.testDouble(3.14159265, function (result) { assert.equal(result, 3.14159265); done(); }); }); QUnit.test("Byte", function (assert) { assert.expect(1); const done = assert.async(); client.testByte(0x01, function (result) { assert.equal(result, 0x01); done(); }); }); QUnit.test("I32", function (assert) { assert.expect(2); const done = assert.async(2); client.testI32(Math.pow(2, 30), function (result) { assert.equal(result, Math.pow(2, 30)); done(); }); client.testI32(Math.pow(-2, 31), function (result) { assert.equal(result, Math.pow(-2, 31)); done(); }); }); QUnit.test("I64", function (assert) { assert.expect(2); const done = assert.async(2); client.testI64(int64_2_pow_60, function (result) { assert.ok(int64_2_pow_60.equals(result)); done(); }); client.testI64(int64_minus_2_pow_60, function (result) { assert.ok(int64_minus_2_pow_60.equals(result)); done(); }); }); thrift-0.23.0/lib/ts/test/test-int64.ts0000664000175000017500000000750215165535636020045 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ var Int64 = require("node-int64"); var JSONInt64 = require("json-int64"); import { Int64Test } from "./gen-js/Int64Test_types"; // Work around for old API used by QUnitAdapter of jsTestDriver if (typeof QUnit.log == "function") { // When using real QUnit (fron PhantomJS) log failures to console QUnit.log(function (details) { if (!details.result) { console.log("======== FAIL ========"); console.log("TestName: " + details.name); if (details.message) console.log(details.message); console.log("Expected: " + details.expected); console.log("Actual : " + details.actual); console.log("======================"); } }); } QUnit.module("Int64"); QUnit.test("Int64", function (assert) { console.log("Int64 test -- starts"); const EXPECTED_SMALL_INT64_AS_NUMBER: number = 42; const EXPECTED_SMALL_INT64: typeof Int64 = new Int64(42); const EXPECTED_MAX_JS_SAFE_INT64: typeof Int64 = new Int64( Number.MAX_SAFE_INTEGER, ); const EXPECTED_MIN_JS_SAFE_INT64: typeof Int64 = new Int64( Number.MIN_SAFE_INTEGER, ); const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64: typeof Int64 = new Int64( "0020000000000000", ); // hex-encoded const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64: typeof Int64 = new Int64( "ffe0000000000000", ); // hex-encoded 2's complement const EXPECTED_MAX_SIGNED_INT64: typeof Int64 = new Int64("7fffffffffffffff"); // hex-encoded const EXPECTED_MIN_SIGNED_INT64: typeof Int64 = new Int64("8000000000000000"); // hex-encoded 2's complement const EXPECTED_INT64_LIST = [ EXPECTED_SMALL_INT64, EXPECTED_MAX_JS_SAFE_INT64, EXPECTED_MIN_JS_SAFE_INT64, EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64, EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64, EXPECTED_MAX_SIGNED_INT64, EXPECTED_MIN_SIGNED_INT64, ]; assert.ok(EXPECTED_SMALL_INT64.equals(Int64Test.SMALL_INT64)); assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(Int64Test.MAX_JS_SAFE_INT64)); assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(Int64Test.MIN_JS_SAFE_INT64)); assert.ok( EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals( Int64Test.MAX_JS_SAFE_PLUS_ONE_INT64, ), ); assert.ok( EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals( Int64Test.MIN_JS_SAFE_MINUS_ONE_INT64, ), ); assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(Int64Test.MAX_SIGNED_INT64)); assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(Int64Test.MIN_SIGNED_INT64)); assert.equal( EXPECTED_SMALL_INT64_AS_NUMBER, Int64Test.SMALL_INT64.toNumber(), ); assert.equal(Number.MAX_SAFE_INTEGER, Int64Test.MAX_JS_SAFE_INT64.toNumber()); assert.equal(Number.MIN_SAFE_INTEGER, Int64Test.MIN_JS_SAFE_INT64.toNumber()); for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { assert.ok(EXPECTED_INT64_LIST[i].equals(Int64Test.INT64_LIST[i])); } for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { let int64Object = EXPECTED_INT64_LIST[i]; assert.ok( Int64Test.INT64_2_INT64_MAP[ JSONInt64.toDecimalString(int64Object) ].equals(int64Object), ); } console.log("Int64 test -- ends"); }); thrift-0.23.0/lib/ts/test/test_handler.js0000664000175000017500000001335315165535636020567 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * 'License'); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ //This is the server side Node test handler for the standard // Apache Thrift test service. const es6Mode = process.argv.includes("--es6"); const genFolder = es6Mode ? "gen-nodejs-es6" : "gen-nodejs"; const ttypes = require(`./${genFolder}/ThriftTest_types`); const TException = require("../../nodejs/lib/thrift").TException; const Int64 = require("node-int64"); exports.ThriftTestHandler = { testVoid: function (result) { console.log("testVoid()"); result(null); }, testString: function (thing, result) { console.log("testString('" + thing + "')"); result(null, thing); }, testByte: function (thing, result) { console.log("testByte(" + thing + ")"); result(null, thing); }, testI32: function (thing, result) { console.log("testI32(" + thing + ")"); result(null, thing); }, testI64: function (thing, result) { console.log("testI64(" + thing + ")"); result(null, thing); }, testDouble: function (thing, result) { console.log("testDouble(" + thing + ")"); result(null, thing); }, testBinary: function (thing, result) { console.log("testBinary('" + thing + "')"); result(null, thing); }, testStruct: function (thing, result) { console.log("testStruct("); console.log(thing); console.log(")"); result(null, thing); }, testNest: function (nest, result) { console.log("testNest("); console.log(nest); console.log(")"); result(null, nest); }, testMap: function (thing, result) { console.log("testMap("); console.log(thing); console.log(")"); result(null, thing); }, testStringMap: function (thing, result) { console.log("testStringMap("); console.log(thing); console.log(")"); result(null, thing); }, testSet: function (thing, result) { console.log("testSet("); console.log(thing); console.log(")"); result(null, thing); }, testList: function (thing, result) { console.log("testList("); console.log(thing); console.log(")"); result(null, thing); }, testEnum: function (thing, result) { console.log("testEnum(" + thing + ")"); result(null, thing); }, testTypedef: function (thing, result) { console.log("testTypedef(" + thing + ")"); result(null, thing); }, testMapMap: function (hello, result) { console.log("testMapMap(" + hello + ")"); const mapmap = []; const pos = []; const neg = []; for (let i = 1; i < 5; i++) { pos[i] = i; neg[-i] = -i; } mapmap[4] = pos; mapmap[-4] = neg; result(null, mapmap); }, testInsanity: function (argument, result) { console.log("testInsanity("); console.log(argument); console.log(")"); const hello = new ttypes.Xtruct(); hello.string_thing = "Hello2"; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = new Int64(2); const goodbye = new ttypes.Xtruct(); goodbye.string_thing = "Goodbye4"; goodbye.byte_thing = 4; goodbye.i32_thing = 4; goodbye.i64_thing = new Int64(4); const crazy = new ttypes.Insanity(); crazy.userMap = []; crazy.userMap[ttypes.Numberz.EIGHT] = 8; crazy.userMap[ttypes.Numberz.FIVE] = 5; crazy.xtructs = [goodbye, hello]; const first_map = []; const second_map = []; first_map[ttypes.Numberz.TWO] = crazy; first_map[ttypes.Numberz.THREE] = crazy; const looney = new ttypes.Insanity(); second_map[ttypes.Numberz.SIX] = looney; const insane = []; insane[1] = first_map; insane[2] = second_map; console.log("insane result:"); console.log(insane); result(null, insane); }, testMulti: function (arg0, arg1, arg2, arg3, arg4, arg5, result) { console.log("testMulti()"); const hello = new ttypes.Xtruct(); hello.string_thing = "Hello2"; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = arg2; result(null, hello); }, testException: function (arg, result) { console.log("testException(" + arg + ")"); if (arg === "Xception") { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; result(x); } else if (arg === "TException") { result(new TException(arg)); } else { result(null); } }, testMultiException: function (arg0, arg1, result) { console.log("testMultiException(" + arg0 + ", " + arg1 + ")"); if (arg0 === "Xception") { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = "This is an Xception"; result(x); } else if (arg0 === "Xception2") { const x2 = new ttypes.Xception2(); x2.errorCode = 2002; x2.struct_thing = new ttypes.Xtruct(); x2.struct_thing.string_thing = "This is an Xception2"; result(x2); } const res = new ttypes.Xtruct(); res.string_thing = arg1; result(null, res); }, testOneway: function (sleepFor, result) { console.log( "testOneway(" + sleepFor + ") => JavaScript (like Rust) never sleeps!", ); }, }; //ThriftTestSvcHandler thrift-0.23.0/lib/ts/coding_standards.md0000664000175000017500000000010315165535636020413 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/ts/Gruntfile.js0000664000175000017500000001274615167543515017075 0ustar00buildbuild00000000000000/* * 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. */ //To build dist/thrift.js, dist/thrift.min.js and doc/* //run grunt at the command line in this directory. //Prerequisites: // Node Setup - nodejs.org // Grunt Setup - npm install //reads the ./package.json and installs project dependencies // Run grunt - npx grunt // uses project-local installed version of grunt (from package.json) module.exports = function (grunt) { "use strict"; grunt.initConfig({ pkg: grunt.file.readJSON("package.json"), concat: { options: { separator: ";", }, dist: { src: ["src/**/*.js"], dest: "dist/<%= pkg.name %>.js", }, }, shell: { InstallThriftJS: { command: "mkdir -p test/build/ts/lib; cp ../js/src/thrift.js test/build/ts/thrift.js", }, InstallThriftNodeJSDep: { command: "cd ../..; npm install", }, InstallTestLibs: { command: "cd test; ant download_jslibs", }, ThriftGen: { command: [ "mkdir -p test/gen-js", "../../compiler/cpp/thrift -gen js:ts --out test/gen-js ../../test/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(" && "), }, ThriftGenInt64: { command: "../../compiler/cpp/thrift -gen js:ts -o test ../../test/Int64Test.thrift", }, ThriftTestServer: { options: { async: true, execOptions: { cwd: "./test", env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, }, }, command: "node server_http.js", }, BuildTS: { options: { execOptions: { cwd: "./test", }, }, command: "../node_modules/typescript/bin/tsc --listFiles --outDir build/ts", }, BrowserifyCompiledTS: { command: [ "./node_modules/browserify/bin/cmd.js test/build/ts/test.js -o test/build/ts/lib/test.js --standalone test", "./node_modules/browserify/bin/cmd.js test/build/ts/test-int64.js -o test/build/ts/lib/test-int64.js --standalone testInt64", ].join(" && "), }, InstallGeneratedCode: { command: [ "mkdir -p test/build/ts", "cp -r test/gen-js test/build/ts", ].join(" && "), }, }, qunit: { ThriftJS: { options: { urls: ["http://localhost:8089/test.html"], puppeteer: { headless: true, args: ["--no-sandbox"], }, }, }, ThriftJS_Int64: { options: { urls: ["http://localhost:8089/test-int64.html"], puppeteer: { headless: true, args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, }, }, }, jshint: { // The main Thrift library file. not es6 yet :( lib: { src: ["../js/src/**/*.js"], }, // The test files use es6 test: { src: ["Gruntfile.js", "test/*.js"], options: { esversion: 6, }, }, gen_js_code: { src: ["test/gen-js/*.js"], }, gen_node_code: { src: ["test/gen-nodejs/*.js"], options: { node: true, }, }, }, }); grunt.loadNpmTasks("grunt-contrib-jshint"); grunt.loadNpmTasks("grunt-contrib-qunit"); grunt.loadNpmTasks("grunt-shell-spawn"); grunt.registerTask( "wait", "Wait just one second for the server to start", function () { var done = this.async(); setTimeout(function () { done(true); }, 1000); }, ); grunt.registerTask("installAndGenerate", [ "shell:InstallThriftJS", "shell:InstallThriftNodeJSDep", "shell:ThriftGen", "shell:ThriftBrowserifyNodeInt64", "shell:ThriftGenInt64", "shell:InstallTestLibs", "shell:BuildTS", "shell:InstallGeneratedCode", "shell:BrowserifyCompiledTS", ]); grunt.registerTask("test", [ "installAndGenerate", "jshint", "shell:ThriftTestServer", "wait", "qunit:ThriftJS", "qunit:ThriftJS_Int64", "shell:ThriftTestServer:kill", ]); grunt.registerTask("default", ["test"]); }; thrift-0.23.0/lib/ts/package.json0000664000175000017500000000216315170007142017037 0ustar00buildbuild00000000000000{ "name": "thrift", "version": "0.23.0", "description": "Thrift is a software framework for scalable cross-language services development.", "author": { "name": "Apache Thrift Developers", "email": "dev@thrift.apache.org" }, "bugs": "https://issues.apache.org/jira/projects/THRIFT/summary", "homepage": "http://thrift.apache.org", "repository": "https://github.com/apache/thrift", "license": "Apache-2.0", "devDependencies": { "@types/node-int64": "^0.4.29", "@types/phantom": "^3.2.5", "@types/qunit": "^2.5.4", "browserify": "^16.2.3", "bufferutil": "^4.0.1", "grunt": "^1.4.1", "grunt-cli": "^1.4.3", "grunt-contrib-concat": "^1.0.1", "grunt-contrib-jshint": "^3.2.0", "grunt-contrib-qunit": "^3.1.0", "grunt-contrib-uglify": "^1.0.1", "grunt-jsdoc": "^2.4.1", "grunt-shell-spawn": "^0.3.12", "jslint": "^0.12.0", "node-int64": "^0.4.0", "phantom": "^6.0.3", "typescript": "^5.7.2" }, "dependencies": { "bufferutil": "^4.0.1", "jsdoc": "^3.6.7", "json-int64": "^1.0.0", "nopt": "^4.0.1" }, "types": "./thrift.d.ts" } thrift-0.23.0/lib/ts/package-lock.json0000664000175000017500000057376115170007142020006 0ustar00buildbuild00000000000000{ "name": "thrift", "version": "0.23.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "thrift", "version": "0.23.0", "license": "Apache-2.0", "dependencies": { "bufferutil": "^4.0.1", "jsdoc": "^3.6.7", "json-int64": "^1.0.0", "nopt": "^4.0.1" }, "devDependencies": { "@types/node-int64": "^0.4.29", "@types/phantom": "^3.2.5", "@types/qunit": "^2.5.4", "browserify": "^16.2.3", "bufferutil": "^4.0.1", "grunt": "^1.4.1", "grunt-cli": "^1.4.3", "grunt-contrib-concat": "^1.0.1", "grunt-contrib-jshint": "^3.2.0", "grunt-contrib-qunit": "^3.1.0", "grunt-contrib-uglify": "^1.0.1", "grunt-jsdoc": "^2.4.1", "grunt-shell-spawn": "^0.3.12", "jslint": "^0.12.0", "node-int64": "^0.4.0", "phantom": "^6.0.3", "typescript": "^5.7.2" } }, "node_modules/@babel/parser": { "version": "7.19.3", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "engines": { "node": ">=0.1.90" } }, "node_modules/@dabh/diagnostics": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", "dev": true, "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "node_modules/@types/linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==" }, "node_modules/@types/markdown-it": { "version": "12.2.3", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", "dependencies": { "@types/linkify-it": "*", "@types/mdurl": "*" } }, "node_modules/@types/mdurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" }, "node_modules/@types/node": { "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==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/phantom": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/@types/phantom/-/phantom-3.2.5.tgz", "integrity": "sha512-7m36DoKSvZgBGWp0xiJ74eHnuotyrpDyQ6m+lers5iMvW4QX+RvBENn7PCjNix7OVqPWlBM+7AqzYVIQ7NrKrA==", "dev": true }, "node_modules/@types/qunit": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/@types/qunit/-/qunit-2.5.4.tgz", "integrity": "sha512-VHi2lEd4/zp8OOouf43JXGJJ5ZxHvdLL1dU0Yakp6Iy73SjpuXl7yjwAwmh1qhTv8krDgHteSwaySr++uXX9YQ==", "dev": true }, "node_modules/@types/triple-beam": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==", "dev": true }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "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==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-dynamic-import": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", "deprecated": "This is probably built in to whatever tool you're using. If you still need it... idk", "dev": true, "peerDependencies": { "acorn": "^6.0.0" } }, "node_modules/acorn-node": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", "dev": true, "dependencies": { "acorn": "^6.0.2", "acorn-dynamic-import": "^4.0.0", "acorn-walk": "^6.1.0", "xtend": "^4.0.1" } }, "node_modules/acorn-walk": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "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/align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "dependencies": { "kind-of": "^3.0.2", "longest": "^1.0.1", "repeat-string": "^1.5.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/align-text/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "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/ansi-styles/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/ansi-styles/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/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/argparse/node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "node_modules/array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } }, "node_modules/asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "safer-buffer": "^2.1.0" } }, "node_modules/assert": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", "dev": true, "dependencies": { "util": "0.10.3" } }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, "engines": { "node": ">=0.8" } }, "node_modules/assert/node_modules/inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", "dev": true }, "node_modules/assert/node_modules/util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "dependencies": { "inherits": "2.0.1" } }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "dev": true }, "node_modules/async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "dev": true }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true, "engines": { "node": "*" } }, "node_modules/aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "node_modules/base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { "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.1.1" }, "engines": { "node": ">=8" } }, "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, "node_modules/browser-pack": { "version": "6.1.0", "resolved": "http://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", "dev": true, "dependencies": { "combine-source-map": "~0.8.0", "defined": "^1.0.0", "JSONStream": "^1.0.3", "safe-buffer": "^5.1.1", "through2": "^2.0.0", "umd": "^3.0.0" }, "bin": { "browser-pack": "bin/cmd.js" } }, "node_modules/browser-resolve": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", "dev": true, "dependencies": { "resolve": "1.1.7" } }, "node_modules/browser-resolve/node_modules/resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true }, "node_modules/browserify": { "version": "16.2.3", "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", "dev": true, "dependencies": { "assert": "^1.4.0", "browser-pack": "^6.0.1", "browser-resolve": "^1.11.0", "browserify-zlib": "~0.2.0", "buffer": "^5.0.2", "cached-path-relative": "^1.0.0", "concat-stream": "^1.6.0", "console-browserify": "^1.1.0", "constants-browserify": "~1.0.0", "crypto-browserify": "^3.0.0", "defined": "^1.0.0", "deps-sort": "^2.0.0", "domain-browser": "^1.2.0", "duplexer2": "~0.1.2", "events": "^2.0.0", "glob": "^7.1.0", "has": "^1.0.0", "htmlescape": "^1.1.0", "https-browserify": "^1.0.0", "inherits": "~2.0.1", "insert-module-globals": "^7.0.0", "JSONStream": "^1.0.3", "labeled-stream-splicer": "^2.0.0", "mkdirp": "^0.5.0", "module-deps": "^6.0.0", "os-browserify": "~0.3.0", "parents": "^1.0.1", "path-browserify": "~0.0.0", "process": "~0.11.0", "punycode": "^1.3.2", "querystring-es3": "~0.2.0", "read-only-stream": "^2.0.0", "readable-stream": "^2.0.2", "resolve": "^1.1.4", "shasum": "^1.0.0", "shell-quote": "^1.6.1", "stream-browserify": "^2.0.0", "stream-http": "^2.0.0", "string_decoder": "^1.1.1", "subarg": "^1.0.0", "syntax-error": "^1.1.1", "through2": "^2.0.0", "timers-browserify": "^1.0.1", "tty-browserify": "0.0.1", "url": "~0.11.0", "util": "~0.10.1", "vm-browserify": "^1.0.0", "xtend": "^4.0.0" }, "bin": { "browserify": "bin/cmd.js" }, "engines": { "node": ">= 0.8" } }, "node_modules/browserify-aes": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.3", "inherits": "^2.0.1", "safe-buffer": "^5.0.1" } }, "node_modules/browserify-cipher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "dependencies": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", "evp_bytestokey": "^1.0.0" } }, "node_modules/browserify-des": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, "dependencies": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, "node_modules/browserify-rsa": { "version": "4.1.0", "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "dependencies": { "bn.js": "^5.0.0", "randombytes": "^2.0.1" } }, "node_modules/browserify-rsa/node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", "dev": true }, "node_modules/browserify-sign": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", "dev": true, "dependencies": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "elliptic": "^6.5.4", "inherits": "^2.0.4", "parse-asn1": "^5.1.6", "readable-stream": "^3.6.2", "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 4" } }, "node_modules/browserify-sign/node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", "dev": true }, "node_modules/browserify-sign/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/browserify-sign/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/browserify-sign/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "dependencies": { "pako": "~1.0.5" } }, "node_modules/buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", "dev": true, "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" } }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true, "engines": { "node": "*" } }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "node_modules/buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", "dev": true }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, "node_modules/bufferutil": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", "dev": true, "hasInstallScript": true, "dependencies": { "node-gyp-build": "~3.7.0" } }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, "node_modules/cached-path-relative": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", "dev": true }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/call-bound": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/camelcase-keys": { "version": "2.1.0", "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "dependencies": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dependencies": { "lodash": "^4.17.15" }, "engines": { "node": ">= 10" } }, "node_modules/center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "dependencies": { "align-text": "^0.1.3", "lazy-cache": "^1.0.3" }, "engines": { "node": ">=0.10.0" } }, "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/cipher-base": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/cipher-base/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/cipher-base/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/cli": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", "integrity": "sha512-41U72MB56TfUMGndAKK8vJ78eooOD4Z5NOL4xEfjc0c23s+6EYKXlXsmACBVclLP1yOfWCgEganVzddVrSNoTg==", "dev": true, "dependencies": { "exit": "0.1.2", "glob": "^7.1.1" }, "engines": { "node": ">=0.2.5" } }, "node_modules/cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "dependencies": { "center-align": "^0.1.1", "right-align": "^0.1.1", "wordwrap": "0.0.2" } }, "node_modules/color": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "dev": true, "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" } }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "dev": true, "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "node_modules/colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true, "engines": { "node": ">=0.1.90" } }, "node_modules/colorspace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", "dev": true, "dependencies": { "color": "^3.1.3", "text-hex": "1.0.x" } }, "node_modules/combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "dev": true, "dependencies": { "convert-source-map": "~1.1.0", "inline-source-map": "~0.6.0", "lodash.memoize": "~3.0.3", "source-map": "~0.5.3" } }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "node_modules/concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "engines": [ "node >= 0.8" ], "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "node_modules/console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "dependencies": { "date-now": "^0.1.4" } }, "node_modules/constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, "node_modules/convert-source-map": { "version": "1.1.3", "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", "dev": true }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "node_modules/create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "dependencies": { "bn.js": "^4.1.0", "elliptic": "^6.0.0" } }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", "md5.js": "^1.3.4", "ripemd160": "^2.0.1", "sha.js": "^2.4.0" } }, "node_modules/create-hmac": { "version": "1.1.7", "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", "inherits": "^2.0.1", "ripemd160": "^2.0.0", "safe-buffer": "^5.0.1", "sha.js": "^2.4.8" } }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/cross-spawn/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/crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "dependencies": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", "create-ecdh": "^4.0.0", "create-hash": "^1.1.0", "create-hmac": "^1.1.0", "diffie-hellman": "^5.0.0", "inherits": "^2.0.1", "pbkdf2": "^3.0.3", "public-encrypt": "^4.0.0", "randombytes": "^2.0.0", "randomfill": "^1.0.3" }, "engines": { "node": "*" } }, "node_modules/currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "dependencies": { "array-find-index": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, "engines": { "node": ">=0.10" } }, "node_modules/date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true, "engines": { "node": "*" } }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/deps-sort": { "version": "2.0.0", "resolved": "http://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "dev": true, "dependencies": { "JSONStream": "^1.0.3", "shasum": "^1.0.0", "subarg": "^1.0.0", "through2": "^2.0.0" }, "bin": { "deps-sort": "bin/cmd.js" } }, "node_modules/des.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, "dependencies": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" } }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/detective": { "version": "5.1.0", "resolved": "http://registry.npmjs.org/detective/-/detective-5.1.0.tgz", "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==", "dev": true, "dependencies": { "acorn-node": "^1.3.0", "defined": "^1.0.0", "minimist": "^1.1.1" }, "bin": { "detective": "bin/detective.js" }, "engines": { "node": ">=0.8.0" } }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "dependencies": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" } }, "node_modules/dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, "dependencies": { "domelementtype": "^2.0.1", "entities": "^2.0.0" } }, "node_modules/dom-serializer/node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } ] }, "node_modules/dom-serializer/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true, "engines": { "node": ">=0.4", "npm": ">=1.2" } }, "node_modules/domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, "node_modules/domhandler": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", "dev": true, "dependencies": { "domelementtype": "1" } }, "node_modules/domutils": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", "dev": true, "dependencies": { "dom-serializer": "0", "domelementtype": "1" } }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "dependencies": { "readable-stream": "^2.0.2" } }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, "node_modules/elliptic": { "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", "hash.js": "^1.0.0", "hmac-drbg": "^1.0.1", "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" } }, "node_modules/elliptic/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, "node_modules/elliptic/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/enabled": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", "dev": true }, "node_modules/entities": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", "dev": true }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-set-tostringtag": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es6-promise": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", "dev": true }, "node_modules/es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "dependencies": { "es6-promise": "^4.0.3" } }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", "dev": true }, "node_modules/events": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", "dev": true, "engines": { "node": ">=0.4.x" } }, "node_modules/evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" } }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "dependencies": { "homedir-polyfill": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "node_modules/extract-zip": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", "dev": true, "dependencies": { "concat-stream": "^1.6.2", "debug": "^2.6.9", "mkdirp": "^0.5.4", "yauzl": "^2.10.0" }, "bin": { "extract-zip": "cli.js" } }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true, "engines": [ "node >=0.6.0" ] }, "node_modules/fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "dependencies": { "pend": "~1.2.0" } }, "node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", "dev": true }, "node_modules/figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fill-range": { "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" }, "engines": { "node": ">=8" } }, "node_modules/find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "dependencies": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/findup-sync": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", "dev": true, "dependencies": { "glob": "~5.0.0" }, "engines": { "node": ">= 0.6.0" } }, "node_modules/findup-sync/node_modules/glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "dependencies": { "inflight": "^1.0.4", "inherits": "2", "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" } }, "node_modules/fined": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, "dependencies": { "expand-tilde": "^2.0.2", "is-plain-object": "^2.0.3", "object.defaults": "^1.1.0", "object.pick": "^1.2.0", "parse-filepath": "^1.0.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/flagged-respawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true, "engines": { "node": ">= 0.10" } }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "dev": true }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/for-own": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "dependencies": { "for-in": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true, "engines": { "node": "*" } }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, "node_modules/fs-extra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0", "klaw": "^1.0.0" } }, "node_modules/fs-extra/node_modules/klaw": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.9" } }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-assigned-identifiers": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", "dev": true }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/getobject": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "dependencies": { "assert-plus": "^1.0.0" } }, "node_modules/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" } }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/global-prefix": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" }, "engines": { "node": ">=0.10.0" } }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, "node_modules/grunt": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "dev": true, "dependencies": { "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", "exit": "~0.1.2", "findup-sync": "~0.3.0", "glob": "~7.1.6", "grunt-cli": "~1.4.3", "grunt-known-options": "~2.0.0", "grunt-legacy-log": "~3.0.0", "grunt-legacy-util": "~2.0.1", "iconv-lite": "~0.4.13", "js-yaml": "~3.14.0", "minimatch": "~3.0.4", "mkdirp": "~1.0.4", "nopt": "~3.0.6", "rimraf": "~3.0.2" }, "bin": { "grunt": "bin/grunt" }, "engines": { "node": ">=8" } }, "node_modules/grunt-cli": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", "dev": true, "dependencies": { "grunt-known-options": "~2.0.0", "interpret": "~1.1.0", "liftup": "~3.0.1", "nopt": "~4.0.1", "v8flags": "~3.2.0" }, "bin": { "grunt": "bin/grunt" }, "engines": { "node": ">=10" } }, "node_modules/grunt-contrib-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz", "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=", "dev": true, "dependencies": { "chalk": "^1.0.0", "source-map": "^0.5.3" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { "grunt": ">=0.4.0" } }, "node_modules/grunt-contrib-concat/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-contrib-concat/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-contrib-concat/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/grunt-contrib-jshint": { "version": "3.2.0", "resolved": "http://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.2.0.tgz", "integrity": "sha512-pcXWCSZWfoMSvcV4BwH21TUtLtcX0Ms8IGuOPIcLeXK3fud9KclY7iqMKY94jFx8TxZzh028YYtpR+io8DiEaQ==", "dev": true, "dependencies": { "chalk": "~4.1.2", "hooker": "^0.2.3", "jshint": "~2.13.4" }, "engines": { "node": ">=10" } }, "node_modules/grunt-contrib-qunit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-3.1.0.tgz", "integrity": "sha512-mdk8UltH6mxCD63E0hTXMAts42DOi4z4bBBrY7qnuHiShflMF7IueSMYe0zWaZ2dO8mgujh57Zfny2EbigJhRg==", "dev": true, "dependencies": { "eventemitter2": "^5.0.1", "p-each-series": "^1.0.0", "puppeteer": "^1.11.0" }, "engines": { "node": ">=6" } }, "node_modules/grunt-contrib-qunit/node_modules/eventemitter2": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=", "dev": true }, "node_modules/grunt-contrib-uglify": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-1.0.2.tgz", "integrity": "sha1-rmekb5FT7dTLEYE6Vetpxw19svs=", "dev": true, "dependencies": { "chalk": "^1.0.0", "lodash": "^4.0.1", "maxmin": "^1.1.0", "uglify-js": "~2.6.2", "uri-path": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-contrib-uglify/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-contrib-uglify/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-contrib-uglify/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/grunt-jsdoc": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.4.1.tgz", "integrity": "sha512-S0zxU0wDewRu7z+vijEItOWe/UttxWVmvz0qz2ZVcAYR2GpXjsiski2CAVN0b18t2qeVLdmxZkJaEWCOsKzcAw==", "dev": true, "dependencies": { "cross-spawn": "^7.0.1", "jsdoc": "^3.6.3" }, "bin": { "grunt-jsdoc": "bin/grunt-jsdoc" }, "engines": { "node": ">= 8.12.0" } }, "node_modules/grunt-known-options": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-legacy-log": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", "dev": true, "dependencies": { "colors": "~1.1.2", "grunt-legacy-log-utils": "~2.1.0", "hooker": "~0.2.3", "lodash": "~4.17.19" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/grunt-legacy-log-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", "dev": true, "dependencies": { "chalk": "~4.1.0", "lodash": "~4.17.19" }, "engines": { "node": ">=10" } }, "node_modules/grunt-legacy-util": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", "dev": true, "dependencies": { "async": "~3.2.0", "exit": "~0.1.2", "getobject": "~1.0.0", "hooker": "~0.2.3", "lodash": "~4.17.21", "underscore.string": "~3.3.5", "which": "~2.0.2" }, "engines": { "node": ">=10" } }, "node_modules/grunt-legacy-util/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/grunt-shell-spawn": { "version": "0.3.12", "resolved": "https://registry.npmjs.org/grunt-shell-spawn/-/grunt-shell-spawn-0.3.12.tgz", "integrity": "sha512-TprZct92sQ4M2Q92piaeLsCrx4+gq/ageuxjZsRG6cglKt7x7rGA3YHt8D30+G789v+/pw4l0tDjEyrkMXx2tA==", "dev": true, "dependencies": { "grunt": ">=0.4.x" }, "bin": { "grunt-shell-spawn": "bin/grunt-shell-spawn" }, "engines": { "node": ">=0.12.0" } }, "node_modules/grunt/node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/grunt/node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/grunt/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" } }, "node_modules/grunt/node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/grunt/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gzip-size": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", "dev": true, "dependencies": { "browserify-zlib": "^0.1.4", "concat-stream": "^1.4.1" }, "bin": { "gzip-size": "cli.js" }, "engines": { "node": ">=0.10.0" } }, "node_modules/gzip-size/node_modules/browserify-zlib": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", "dev": true, "dependencies": { "pako": "~0.2.0" } }, "node_modules/gzip-size/node_modules/pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", "dev": true }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "deprecated": "this library is no longer supported", "dev": true, "dependencies": { "ajv": "^6.5.5", "har-schema": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { "function-bind": "^1.1.1" }, "engines": { "node": ">= 0.4.0" } }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "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/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hash-base": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" }, "engines": { "node": ">=4" } }, "node_modules/hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" } }, "node_modules/hasha": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", "dev": true, "dependencies": { "is-stream": "^1.0.1", "pinkie-promise": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.1" } }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "dependencies": { "parse-passwd": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true, "engines": { "node": "*" } }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/htmlescape": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", "dev": true, "engines": { "node": ">=0.10" } }, "node_modules/htmlparser2": { "version": "3.8.3", "resolved": "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", "dev": true, "dependencies": { "domelementtype": "1", "domhandler": "2.3", "domutils": "1.5", "entities": "1.0", "readable-stream": "1.1" } }, "node_modules/htmlparser2/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "node_modules/htmlparser2/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/htmlparser2/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "dev": true }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" }, "engines": { "node": ">=0.8", "npm": ">=1.3.7" } }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, "node_modules/https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "dependencies": { "agent-base": "^4.3.0", "debug": "^3.1.0" }, "engines": { "node": ">= 4.5.0" } }, "node_modules/https-proxy-agent/node_modules/agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "dependencies": { "es6-promisify": "^5.0.0" }, "engines": { "node": ">= 4.0.0" } }, "node_modules/https-proxy-agent/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/https-proxy-agent/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/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", "dev": true }, "node_modules/indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "dependencies": { "repeating": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "node_modules/inline-source-map": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "dev": true, "dependencies": { "source-map": "~0.5.3" } }, "node_modules/insert-module-globals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", "dev": true, "dependencies": { "acorn-node": "^1.5.2", "combine-source-map": "^0.8.0", "concat-stream": "^1.6.1", "is-buffer": "^1.1.0", "JSONStream": "^1.0.3", "path-is-absolute": "^1.0.1", "process": "~0.11.0", "through2": "^2.0.0", "undeclared-identifiers": "^1.1.2", "xtend": "^4.0.0" }, "bin": { "insert-module-globals": "bin/cmd.js" } }, "node_modules/interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, "node_modules/is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "node_modules/is-builtin-module": { "version": "1.0.0", "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "dependencies": { "builtin-modules": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "dependencies": { "has": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-finite": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "dependencies": { "number-is-nan": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "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": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "dependencies": { "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "dependencies": { "is-unc-path": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-typed-array": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, "node_modules/is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "dependencies": { "unc-path-regex": "^0.1.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "node_modules/js-yaml": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/js2xmlparser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "dependencies": { "xmlcreate": "^2.0.4" } }, "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, "node_modules/jsdoc": { "version": "3.6.11", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.11.tgz", "integrity": "sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==", "dependencies": { "@babel/parser": "^7.9.4", "@types/markdown-it": "^12.2.3", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", "markdown-it": "^12.3.2", "markdown-it-anchor": "^8.4.1", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", "underscore": "~1.13.2" }, "bin": { "jsdoc": "jsdoc.js" }, "engines": { "node": ">=12.0.0" } }, "node_modules/jsdoc/node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "engines": { "node": ">=8" } }, "node_modules/jsdoc/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "bin": { "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" } }, "node_modules/jshint": { "version": "2.13.5", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.5.tgz", "integrity": "sha512-dB2n1w3OaQ35PLcBGIWXlszjbPZwsgZoxsg6G8PtNf2cFMC1l0fObkYLUuXqTTdi6tKw4sAjfUseTdmDMHQRcg==", "dev": true, "dependencies": { "cli": "~1.0.0", "console-browserify": "1.1.x", "exit": "0.1.x", "htmlparser2": "3.8.x", "lodash": "~4.17.21", "minimatch": "~3.0.2", "strip-json-comments": "1.0.x" }, "bin": { "jshint": "bin/jshint" } }, "node_modules/jshint/node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/jshint/node_modules/strip-json-comments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", "integrity": "sha512-AOPG8EBc5wAikaG1/7uFCNFJwnKOuQwFTpYBdTW6OvWHeZBQBrAA/amefHGrEiOnCPcLFZK6FUPtWVKpQVIRgg==", "dev": true, "bin": { "strip-json-comments": "cli.js" }, "engines": { "node": ">=0.8.0" } }, "node_modules/jslint": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/jslint/-/jslint-0.12.0.tgz", "integrity": "sha512-RoCsyICcKA+6TFsbys9DpKTfPVaC71Mm5QSjvrWA0lDVN+LIvx6apa42FFisMqmCTvJ8DxkcoQGJ0j7m3kTVow==", "dev": true, "dependencies": { "exit": "~0.1.2", "glob": "~7.1.2", "nopt": "~3.0.1", "readable-stream": "~2.1.5" }, "bin": { "jslint": "bin/jslint.js" }, "engines": { "node": ">=0.8.0" } }, "node_modules/jslint/node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/jslint/node_modules/process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "node_modules/jslint/node_modules/readable-stream": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", "dev": true, "dependencies": { "buffer-shims": "^1.0.0", "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", "string_decoder": "~0.10.x", "util-deprecate": "~1.0.1" } }, "node_modules/jslint/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "node_modules/json-int64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-int64/-/json-int64-1.0.0.tgz", "integrity": "sha512-yrTg9swToElhEPETLMdZkEzDhbXLs+cxkw/b2rglMPOBlM1DE0utH1EReSMLcnpYJk5iUvD12r0fP2/xHitF5Q==", "dependencies": { "node-int64": "0.4.0" } }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "node_modules/json-stable-stringify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", "dev": true, "dependencies": { "jsonify": "~0.0.0" } }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true, "engines": { "node": "*" } }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true, "engines": [ "node >= 0.2.0" ] }, "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" }, "bin": { "JSONStream": "bin.js" }, "engines": { "node": "*" } }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.4.0", "verror": "1.10.0" }, "engines": { "node": ">=0.6.0" } }, "node_modules/jsprim/node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "node_modules/kew": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", "dev": true }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dependencies": { "graceful-fs": "^4.1.9" } }, "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", "dev": true }, "node_modules/labeled-stream-splicer": { "version": "2.0.1", "resolved": "http://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", "dev": true, "dependencies": { "inherits": "^2.0.1", "isarray": "^2.0.4", "stream-splicer": "^2.0.0" } }, "node_modules/labeled-stream-splicer/node_modules/isarray": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", "dev": true }, "node_modules/lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/liftup": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", "dev": true, "dependencies": { "extend": "^3.0.2", "findup-sync": "^4.0.0", "fined": "^1.2.0", "flagged-respawn": "^1.0.1", "is-plain-object": "^2.0.4", "object.map": "^1.0.1", "rechoir": "^0.7.0", "resolve": "^1.19.0" }, "engines": { "node": ">=10" } }, "node_modules/liftup/node_modules/findup-sync": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", "dev": true, "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.0", "micromatch": "^4.0.2", "resolve-dir": "^1.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/liftup/node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dependencies": { "uc.micro": "^1.0.1" } }, "node_modules/load-json-file": { "version": "1.1.0", "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/lodash": { "version": "4.17.23", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, "node_modules/lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", "dev": true }, "node_modules/logform": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz", "integrity": "sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==", "dev": true, "dependencies": { "@colors/colors": "1.5.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "node_modules/logform/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/longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "dependencies": { "currently-unhandled": "^0.4.1", "signal-exit": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "dependencies": { "kind-of": "^6.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/markdown-it": { "version": "12.3.2", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dependencies": { "argparse": "^2.0.1", "entities": "~2.1.0", "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, "bin": { "markdown-it": "bin/markdown-it.js" } }, "node_modules/markdown-it-anchor": { "version": "8.6.5", "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.5.tgz", "integrity": "sha512-PI1qEHHkTNWT+X6Ip9w+paonfIQ+QZP9sCeMYi47oqhH+EsW8CrJ8J7CzV19QVOj6il8ATGbK2nTECj22ZHGvQ==", "peerDependencies": { "@types/markdown-it": "*", "markdown-it": "*" } }, "node_modules/markdown-it/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==" }, "node_modules/markdown-it/node_modules/entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/marked": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", "bin": { "marked": "bin/marked.js" }, "engines": { "node": ">= 12" } }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/maxmin": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", "dev": true, "dependencies": { "chalk": "^1.0.0", "figures": "^1.0.1", "gzip-size": "^1.0.0", "pretty-bytes": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, "node_modules/meow": { "version": "3.7.0", "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "dependencies": { "camelcase-keys": "^2.0.0", "decamelize": "^1.1.2", "loud-rejection": "^1.0.0", "map-obj": "^1.0.1", "minimist": "^1.1.3", "normalize-package-data": "^2.3.4", "object-assign": "^4.0.1", "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { "braces": "^3.0.1", "picomatch": "^2.2.3" }, "engines": { "node": ">=8.6" } }, "node_modules/miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "brorand": "^1.0.1" }, "bin": { "miller-rabin": "bin/miller-rabin" } }, "node_modules/mime": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true, "bin": { "mime": "cli.js" }, "engines": { "node": ">=4.0.0" } }, "node_modules/mime-db": { "version": "1.37.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.21", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "dev": true, "dependencies": { "mime-db": "~1.37.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", "dev": true }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "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/module-deps": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", "dev": true, "dependencies": { "browser-resolve": "^1.7.0", "cached-path-relative": "^1.0.0", "concat-stream": "~1.6.0", "defined": "^1.0.0", "detective": "^5.0.2", "duplexer2": "^0.1.2", "inherits": "^2.0.1", "JSONStream": "^1.0.3", "parents": "^1.0.0", "readable-stream": "^2.0.2", "resolve": "^1.4.0", "stream-combiner2": "^1.1.1", "subarg": "^1.0.0", "through2": "^2.0.0", "xtend": "^4.0.0" }, "bin": { "module-deps": "bin/cmd.js" }, "engines": { "node": ">= 0.8.0" } }, "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/node-gyp-build": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", "dev": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, "node_modules/nopt": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dependencies": { "abbrev": "1", "osenv": "^0.1.4" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true, "engines": { "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.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "dev": true, "dependencies": { "array-each": "^1.0.1", "array-slice": "^1.0.0", "for-own": "^1.0.0", "isobject": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", "dev": true, "dependencies": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "dependencies": { "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "dependencies": { "wrappy": "1" } }, "node_modules/one-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", "dev": true, "dependencies": { "fn.name": "1.x.x" } }, "node_modules/os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "engines": { "node": ">=0.10.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=", "engines": { "node": ">=0.10.0" } }, "node_modules/osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" } }, "node_modules/p-each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", "dev": true, "dependencies": { "p-reduce": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/pako": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz", "integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==", "dev": true }, "node_modules/parents": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", "dev": true, "dependencies": { "path-platform": "~0.11.15" } }, "node_modules/parse-asn1": { "version": "5.1.6", "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "dependencies": { "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", "evp_bytestokey": "^1.0.0", "pbkdf2": "^3.0.3", "safe-buffer": "^5.1.1" } }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" }, "engines": { "node": ">=0.8" } }, "node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "dependencies": { "error-ex": "^1.2.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/path-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, "node_modules/path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "dependencies": { "pinkie-promise": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "engines": { "node": ">=0.10.0" } }, "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/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-platform": { "version": "0.11.15", "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "dependencies": { "path-root-regex": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/pbkdf2": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", "dev": true, "license": "MIT", "dependencies": { "create-hash": "~1.1.3", "create-hmac": "^1.1.7", "ripemd160": "=2.0.1", "safe-buffer": "^5.2.1", "sha.js": "^2.4.11", "to-buffer": "^1.2.0" }, "engines": { "node": ">=0.12" } }, "node_modules/pbkdf2/node_modules/create-hash": { "version": "1.1.3", "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", "dev": true, "license": "MIT", "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", "ripemd160": "^2.0.0", "sha.js": "^2.4.0" } }, "node_modules/pbkdf2/node_modules/hash-base": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.1" } }, "node_modules/pbkdf2/node_modules/ripemd160": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", "dev": true, "license": "MIT", "dependencies": { "hash-base": "^2.0.0", "inherits": "^2.0.1" } }, "node_modules/pbkdf2/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "node_modules/phantom": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/phantom/-/phantom-6.3.0.tgz", "integrity": "sha512-Ptlwjp5eJiBmr3KQzFr9V/ehhcC+PGyJB38q7mnxJiwrssOEtmIWDEzQ7gIsdOXlHoW0n0+KjdAdP9U89Cm9Pw==", "deprecated": "This package is no longer maintained", "dev": true, "dependencies": { "phantomjs-prebuilt": "^2.1.16", "split": "^1.0.1", "winston": "^3.2.1" }, "bin": { "phantom": "bin/phantom.js" }, "engines": { "node": ">=8" } }, "node_modules/phantomjs-prebuilt": { "version": "2.1.16", "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", "integrity": "sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ==", "deprecated": "this package is now deprecated", "dev": true, "hasInstallScript": true, "dependencies": { "es6-promise": "^4.0.3", "extract-zip": "^1.6.5", "fs-extra": "^1.0.0", "hasha": "^2.2.0", "kew": "^0.7.0", "progress": "^1.1.8", "request": "^2.81.0", "request-progress": "^2.0.1", "which": "^1.2.10" }, "bin": { "phantomjs": "bin/phantomjs" } }, "node_modules/phantomjs-prebuilt/node_modules/progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "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/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/pretty-bytes": { "version": "1.0.4", "resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "dev": true, "dependencies": { "get-stdin": "^4.0.1", "meow": "^3.1.0" }, "bin": { "pretty-bytes": "cli.js" }, "engines": { "node": ">=0.10.0" } }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true, "engines": { "node": ">= 0.6.0" } }, "node_modules/process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", "dev": true }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" } }, "node_modules/punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, "node_modules/puppeteer": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", "deprecated": "< 19.4.0 is no longer supported", "dev": true, "hasInstallScript": true, "dependencies": { "debug": "^4.1.0", "extract-zip": "^1.6.6", "https-proxy-agent": "^2.2.1", "mime": "^2.0.3", "progress": "^2.0.1", "proxy-from-env": "^1.0.0", "rimraf": "^2.6.1", "ws": "^6.1.0" }, "engines": { "node": ">=6.4.0" } }, "node_modules/puppeteer/node_modules/debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/puppeteer/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, "engines": { "node": ">=0.6" } }, "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "dev": true, "engines": { "node": ">=0.4.x" } }, "node_modules/querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true, "engines": { "node": ">=0.4.x" } }, "node_modules/randombytes": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/randomfill": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "dependencies": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" } }, "node_modules/read-only-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "dependencies": { "readable-stream": "^2.0.2" } }, "node_modules/read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "dependencies": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", "path-type": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "dependencies": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/readable-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, "dependencies": { "resolve": "^1.9.0" }, "engines": { "node": ">= 0.10" } }, "node_modules/redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "dependencies": { "indent-string": "^2.1.0", "strip-indent": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true, "engines": { "node": ">=0.10" } }, "node_modules/repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "dependencies": { "is-finite": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": ">=2.5.5", "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" }, "engines": { "node": ">= 6" } }, "node_modules/request-progress": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", "dev": true, "dependencies": { "throttleit": "^1.0.0" } }, "node_modules/requizzle": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", "dependencies": { "lodash": "^4.17.14" } }, "node_modules/resolve": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", "dev": true, "dependencies": { "path-parse": "^1.0.6" } }, "node_modules/resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "dependencies": { "align-text": "^0.1.1" }, "engines": { "node": ">=0.10.0" } }, "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/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "node_modules/safe-stable-stringify": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "node_modules/semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true, "bin": { "semver": "bin/semver" } }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/sha.js": { "version": "2.4.12", "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "dev": true, "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" }, "engines": { "node": ">= 0.10" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/sha.js/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/sha.js/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/shasum": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "dev": true, "dependencies": { "json-stable-stringify": "~0.0.0", "sha.js": "~2.4.4" } }, "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/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/shell-quote": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, "node_modules/signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "node_modules/simple-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", "dev": true }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "dev": true, "dependencies": { "is-arrayish": "^0.3.1" } }, "node_modules/simple-swizzle/node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", "dev": true }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-exceptions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", "dev": true }, "node_modules/split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "dependencies": { "through": "2" }, "engines": { "node": "*" } }, "node_modules/sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, "node_modules/sshpk": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz", "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==", "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", "dashdash": "^1.12.0", "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, "bin": { "sshpk-conv": "bin/sshpk-conv", "sshpk-sign": "bin/sshpk-sign", "sshpk-verify": "bin/sshpk-verify" }, "engines": { "node": ">=0.10.0" } }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", "dev": true, "engines": { "node": "*" } }, "node_modules/stream-browserify": { "version": "2.0.1", "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "dependencies": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" } }, "node_modules/stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true, "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, "node_modules/stream-http": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "dependencies": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.1", "readable-stream": "^2.3.6", "to-arraybuffer": "^1.0.0", "xtend": "^4.0.0" } }, "node_modules/stream-splicer": { "version": "2.0.0", "resolved": "http://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", "dev": true, "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.2" } }, "node_modules/string_decoder": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "dependencies": { "is-utf8": "^0.2.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "dependencies": { "get-stdin": "^4.0.1" }, "bin": { "strip-indent": "cli.js" }, "engines": { "node": ">=0.10.0" } }, "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==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "dev": true, "dependencies": { "minimist": "^1.1.0" } }, "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": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/syntax-error": { "version": "1.4.0", "resolved": "http://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "dev": true, "dependencies": { "acorn-node": "^1.2.0" } }, "node_modules/taffydb": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", "integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==" }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", "dev": true }, "node_modules/throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", "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/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "node_modules/timers-browserify": { "version": "1.4.2", "resolved": "http://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "dev": true, "dependencies": { "process": "~0.11.0" }, "engines": { "node": ">=0.6.0" } }, "node_modules/to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, "node_modules/to-buffer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", "dev": true, "license": "MIT", "dependencies": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", "typed-array-buffer": "^1.0.3" }, "engines": { "node": ">= 0.4" } }, "node_modules/to-buffer/node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, "node_modules/to-buffer/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" }, "engines": { "node": ">=0.8" } }, "node_modules/tough-cookie/node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/triple-beam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==", "dev": true }, "node_modules/tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", "dev": true }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, "engines": { "node": "*" } }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "node_modules/typescript": { "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": ">=14.17" } }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, "node_modules/uglify-js": { "version": "2.6.4", "resolved": "http://registry.npmjs.org/uglify-js/-/uglify-js-2.6.4.tgz", "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", "dev": true, "dependencies": { "async": "~0.2.6", "source-map": "~0.5.1", "uglify-to-browserify": "~1.0.0", "yargs": "~3.10.0" }, "bin": { "uglifyjs": "bin/uglifyjs" }, "engines": { "node": ">=0.8.0" } }, "node_modules/uglify-js/node_modules/async": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==", "dev": true }, "node_modules/uglify-to-browserify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true }, "node_modules/umd": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", "dev": true, "bin": { "umd": "bin/cli.js" } }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/undeclared-identifiers": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", "dev": true, "dependencies": { "acorn-node": "^1.3.0", "get-assigned-identifiers": "^1.2.0", "simple-concat": "^1.0.0", "xtend": "^4.0.1" }, "bin": { "undeclared-identifiers": "bin.js" } }, "node_modules/underscore": { "version": "1.13.8", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", "license": "MIT" }, "node_modules/underscore.string": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", "dev": true, "dependencies": { "sprintf-js": "^1.1.1", "util-deprecate": "^1.0.2" }, "engines": { "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", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "dependencies": { "punycode": "^2.1.0" } }, "node_modules/uri-js/node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/uri-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", "dev": true, "engines": { "node": ">= 0.10" } }, "node_modules/url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" } }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true }, "node_modules/util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "dev": true, "dependencies": { "inherits": "2.0.3" } }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "node_modules/uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" } }, "node_modules/v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", "dev": true, "dependencies": { "homedir-polyfill": "^1.0.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "engines": [ "node >=0.6.0" ], "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "node_modules/vm-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", "dev": true }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/which-typed-array": { "version": "1.1.19", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/winston": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.9.0.tgz", "integrity": "sha512-jW51iW/X95BCW6MMtZWr2jKQBP4hV5bIDq9QrIjfDk6Q9QuxvTKEAlpUNAzP+HYHFFCeENhph16s0zEunu4uuQ==", "dev": true, "dependencies": { "@colors/colors": "1.5.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.4.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.5.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/winston-transport": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", "dev": true, "dependencies": { "logform": "^2.3.2", "readable-stream": "^3.6.0", "triple-beam": "^1.3.0" }, "engines": { "node": ">= 6.4.0" } }, "node_modules/winston-transport/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/winston/node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/winston/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "node_modules/ws": { "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" } }, "node_modules/xmlcreate": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==" }, "node_modules/xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true, "engines": { "node": ">=0.4" } }, "node_modules/yargs": { "version": "3.10.0", "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "dependencies": { "camelcase": "^1.0.2", "cliui": "^2.1.0", "decamelize": "^1.0.0", "window-size": "0.1.0" } }, "node_modules/yargs/node_modules/camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } } } } thrift-0.23.0/lib/ts/Makefile0000644000175000017500000004507715170007175016230 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/ts/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/ts ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/ts abs_srcdir = /thrift/src/lib/ts abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ package.json \ package-lock.json \ thrift.d.ts \ tsconfig.json all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/ts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/ts/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook #check-local: check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-am check-local clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am dist-hook \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Make sure this doesn't fail if ant is not configured. # We call install twice to work around npm issues # prereq: $(NPM) install || $(NPM) install $(NPM) list check-local: prereq all ./node_modules/.bin/grunt doc: prereq ./node_modules/.bin/grunt jsdoc clean-local: $(RM) -r dist $(RM) -r doc $(RM) -r node_modules $(RM) -r test/build/ $(RM) -r test/gen-*/ dist-hook: $(RM) -r $(distdir)/dist/ $(RM) -r $(distdir)/doc/ $(RM) -r $(distdir)/node_modules/ $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/ts/Makefile.in0000644000175000017500000004423515170007167016631 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/ts ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ package.json \ package-lock.json \ thrift.d.ts \ tsconfig.json all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/ts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/ts/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook @HAVE_NPM_FALSE@check-local: check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-am check-local clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am dist-hook \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Make sure this doesn't fail if ant is not configured. # We call install twice to work around npm issues # @HAVE_NPM_TRUE@prereq: @HAVE_NPM_TRUE@ $(NPM) install || $(NPM) install @HAVE_NPM_TRUE@ $(NPM) list @HAVE_NPM_TRUE@check-local: prereq all @HAVE_NPM_TRUE@ ./node_modules/.bin/grunt @HAVE_NPM_TRUE@doc: prereq @HAVE_NPM_TRUE@ ./node_modules/.bin/grunt jsdoc clean-local: $(RM) -r dist $(RM) -r doc $(RM) -r node_modules $(RM) -r test/build/ $(RM) -r test/gen-*/ dist-hook: $(RM) -r $(distdir)/dist/ $(RM) -r $(distdir)/doc/ $(RM) -r $(distdir)/node_modules/ $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/ts/thrift.d.ts0000664000175000017500000005532315165535636016673 0ustar00buildbuild00000000000000/* * 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. */ declare module Thrift { /** * Thrift JavaScript library version. */ var Version: string; /** * Thrift IDL type string to Id mapping. * @property {number} STOP - End of a set of fields. * @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} DOUBLE - 64 bit IEEE 854 floating point. * @property {number} I16 - Signed 16 bit integer. * @property {number} I32 - Signed 32 bit integer. * @property {number} I64 - Signed 64 bit integer. * @property {number} STRING - Array of bytes representing a string of characters. * @property {number} UTF7 - Array of bytes representing a string of UTF7 encoded characters. * @property {number} STRUCT - A multifield type. * @property {number} MAP - A collection type (map/associative-array/dictionary). * @property {number} SET - A collection type (unordered and without repeated values). * @property {number} LIST - A collection type (unordered). * @property {number} UTF8 - Array of bytes representing a string of UTF8 encoded characters. * @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; } var Type: Type; /** * Thrift RPC message type string to Id mapping. * @property {number} CALL - RPC call sent from client to server. * @property {number} REPLY - RPC call normal response from server to client. * @property {number} EXCEPTION - RPC call exception response from server to client. * @property {number} ONEWAY - Oneway RPC call from client to server with no response. */ interface MessageType { CALL: number; REPLY: number; EXCEPTION: number; ONEWAY: number; } var MessageType: MessageType; /** * Utility function returning the count of an object's own properties. * @param {object} obj - Object to test. * @returns {number} number of object's own properties */ function objectLength(obj: Object): number; /** * Utility function to establish prototype inheritance. * @param {function} constructor - Contstructor function to set as derived. * @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; /** * TException is the base class for all Thrift exceptions types. */ class TException implements Error { name: string; message: string; /** * Initializes a Thrift TException instance. * @param {string} message - The TException message (distinct from the Error message). */ constructor(message: string); /** * Returns the message set on the exception. * @returns {string} exception message */ getMessage(): string; } /** * Thrift Application Exception type string to Id mapping. * @property {number} UNKNOWN - Unknown/undefined. * @property {number} UNKNOWN_METHOD - Client attempted to call a method unknown to the server. * @property {number} INVALID_MESSAGE_TYPE - Client passed an unknown/unsupported MessageType. * @property {number} WRONG_METHOD_NAME - Unused. * @property {number} BAD_SEQUENCE_ID - Unused in Thrift RPC, used to flag proprietary sequence number errors. * @property {number} MISSING_RESULT - Raised by a server processor if a handler fails to supply the required return result. * @property {number} INTERNAL_ERROR - Something bad happened. * @property {number} PROTOCOL_ERROR - The protocol layer failed to serialize or deserialize data. * @property {number} INVALID_TRANSFORM - Unused. * @property {number} INVALID_PROTOCOL - The protocol (or version) is not supported. * @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; } var TApplicationExceptionType: TApplicationExceptionType; /** * TApplicationException is the exception class used to propagate exceptions from an RPC server back to a calling client. */ class TApplicationException extends TException { message: string; code: number; /** * Initializes a Thrift TApplicationException instance. * @param {string} message - The TApplicationException message (distinct from the Error message). * @param {Thrift.TApplicationExceptionType} [code] - The TApplicationExceptionType code. */ constructor(message: string, code?: number); /** * Read a TApplicationException from the supplied protocol. * @param {object} input - The input protocol to read from. */ read(input: Object): void; /** * Write a TApplicationException to the supplied protocol. * @param {object} output - The output protocol to write to. */ write(output: Object): void; /** * Returns the application exception code set on the exception. * @returns {Thrift.TApplicationExceptionType} exception code */ getCode(): number; } /** * 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] * transport (see: node.js example server). */ class TXHRTransport { url: string; wpos: number; rpos: number; useCORS: any; send_buf: string; recv_buf: string; /** * If you do not specify a url then you must handle XHR operations on * your own. This type can also be constructed using the Transport alias * for backward compatibility. * @param {string} [url] - The URL to connect to. * @param {object} [options] - Options. */ constructor(url?: string, options?: Object); /** * Gets the browser specific XmlHttpRequest Object. * @returns {object} the browser XHR interface object */ getXmlHttpRequestObject(): Object; /** * 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 * send buffer is returned. * @param {object} async - If true the current send buffer is returned. * @param {function} callback - Optional async completion callback. * @returns {undefined|string} Nothing or the current send buffer. */ flush(async: any, callback?: Function): string; /** * Creates a jQuery XHR object to be used for a Thrift server call. * @param {object} client - The Thrift Service client object generated by the IDL compiler. * @param {object} postData - The message to send to the server. * @param {function} args - The function to call if the request succeeds. * @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; /** * Sets the buffer to use when receiving server responses. * @param {string} buf - The buffer to receive server responses. */ setRecvBuffer(buf: string): void; /** * Returns true if the transport is open, in browser based JavaScript * this function always returns true. * @returns {boolean} Always True. */ isOpen(): boolean; /** * Opens the transport connection, in browser based JavaScript * this function is a nop. */ open(): void; /** * Closes the transport connection, in browser based JavaScript * this function is a nop. */ close(): void; /** * Returns the specified number of characters from the response * buffer. * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ read(len: number): string; /** * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ readAll(): string; /** * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ write(buf: string): void; /** * Returns the send buffer. * @returns {string} The send buffer. */ getSendBuffer(): string; } /** * Old alias of the TXHRTransport for backwards compatibility. */ class Transport extends TXHRTransport {} /** * 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 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 /** * Constructor Function for the WebSocket transport. * @param {string } [url] - The URL to connect to. */ constructor(url: string); __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 * function parameter is required. * @param {object} async - Ignored. * @param {function} callback - The client completion callback. * @returns {undefined|string} Nothing (undefined) */ flush(async: any, callback: Function): string; __onOpen(): void; __onClose(): void; __onMessage(): void; __onError(): void; /** * Sets the buffer to use when receiving server responses. * @param {string} buf - The buffer to receive server responses. */ setRecvBuffer(buf: string): void; /** * Returns true if the transport is open * @returns {boolean} */ isOpen(): boolean; /** * Opens the transport connection */ open(): void; /** * Closes the transport connection */ close(): void; /** * Returns the specified number of characters from the response * buffer. * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ read(len: number): string; /** * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ readAll(): string; /** * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ write(buf: string): void; /** * Returns the send buffer. * @returns {string} The send buffer. */ getSendBuffer(): string; } /** * 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 { transport: Object; /** * Thrift IDL type Id to string mapping. * The mapping table looks as follows: * Thrift.Type.BOOL -> "tf": True/False integer. * Thrift.Type.BYTE -> "i8": Signed 8 bit integer. * Thrift.Type.I16 -> "i16": Signed 16 bit integer. * Thrift.Type.I32 -> "i32": Signed 32 bit integer. * Thrift.Type.I64 -> "i64": Signed 64 bit integer. * Thrift.Type.DOUBLE -> "dbl": 64 bit IEEE 854 floating point. * Thrift.Type.STRUCT -> "rec": A multifield type. * Thrift.Type.STRING -> "str": Array of bytes representing a string of characters. * Thrift.Type.MAP -> "map": A collection type (map/associative-array/dictionary). * Thrift.Type.LIST -> "lst": A collection type (unordered). * Thrift.Type.SET -> "set": A collection type (unordered and without repeated values). */ Type: { [k: number]: string }; /** * 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 * "dbl" -> Thrift.Type.DOUBLE * "rec" -> Thrift.Type.STRUCT * "str" -> Thrift.Type.STRING * "map" -> Thrift.Type.MAP * "lst" -> Thrift.Type.LIST * "set" -> Thrift.Type.SET */ RType: { [k: string]: number }; /** * The TJSONProtocol version number. */ Version: number; /** * Initializes a Thrift JSON protocol instance. * @param {Thrift.Transport} transport - The transport to serialize to/from. */ constructor(transport: Object); /** * Returns the underlying transport. * @returns {Thrift.Transport} The underlying transport. */ getTransport(): Object; /** * Serializes the beginning of a Thrift RPC message. * @param {string} name - The service method to call. * @param {Thrift.MessageType} messageType - The type of method call. * @param {number} seqid - The sequence number of this call (always 0 in Apache Thrift). */ writeMessageBegin(name: string, messageType: number, seqid: number): void; /** * Serializes the end of a Thrift RPC message. */ writeMessageEnd(): void; /** * Serializes the beginning of a struct. * @param {string} name - The name of the struct. */ writeStructBegin(name?: string): void; /** * Serializes the end of a struct. */ writeStructEnd(): void; /** * Serializes the beginning of a struct field. * @param {string} name - The name of the field. * @param {Thrift.Protocol.Type} fieldType - The data type of the field. * @param {number} fieldId - The field's unique identifier. */ writeFieldBegin(name: string, fieldType: number, fieldId: number): void; /** * Serializes the end of a field. */ writeFieldEnd(): void; /** * Serializes the end of the set of fields for a struct. */ writeFieldStop(): void; /** * Serializes the beginning of a map collection. * @param {Thrift.Type} keyType - The data type of the key. * @param {Thrift.Type} valType - The data type of the value. * @param {number} [size] - The number of elements in the map (ignored). */ writeMapBegin(keyType: number, valType: number, size?: number): void; /** * Serializes the end of a map. */ writeMapEnd(): void; /** * Serializes the beginning of a list collection. * @param {Thrift.Type} elemType - The data type of the elements. * @param {number} size - The number of elements in the list. */ writeListBegin(elemType: number, size: number): void; /** * Serializes the end of a list. */ writeListEnd(): void; /** * Serializes the beginning of a set collection. * @param {Thrift.Type} elemType - The data type of the elements. * @param {number} size - The number of elements in the list. */ writeSetBegin(elemType: number, size: number): void; /** * Serializes the end of a set. */ writeSetEnd(): void; /** Serializes a boolean */ writeBool(value: boolean): void; /** Serializes a number */ writeByte(i8: number): void; /** Serializes a number */ writeI16(i16: number): void; /** Serializes a number */ writeI32(i32: number): void; /** Serializes a number */ writeI64(i64: number): void; /** Serializes a number */ writeDouble(dbl: number): void; /** Serializes a string */ writeString(str: string): void; /** Serializes a string */ writeBinary(str: string): void; /** @class @name AnonReadMessageBeginReturn @property {string} fname - The name of the service method. @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. * @returns {AnonReadMessageBeginReturn} */ readMessageBegin(): { fname: string; mtype: number; rseqid: number }; /** Deserializes the end of a message. */ readMessageEnd(): void; /** * 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. */ readStructBegin(name?: string): { fname: string }; /** Deserializes the end of a struct. */ readStructEnd(): void; /** @class @name AnonReadFieldBeginReturn @property {string} fname - The name of the field (always ''). @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. * @returns {AnonReadFieldBeginReturn} */ readFieldBegin(): { fname: string; ftype: number; fid: number }; /** Deserializes the end of a field. */ readFieldEnd(): void; /** @class @name AnonReadMapBeginReturn @property {Thrift.Type} ktype - The data type of the key. @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. * @returns {AnonReadMapBeginReturn} */ readMapBegin(): { ktype: number; vtype: number; size: number }; /** Deserializes the end of a map. */ readMapEnd(): void; /** @class @name AnonReadColBeginReturn @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. * @returns {AnonReadColBeginReturn} */ readListBegin(): { etype: number; size: number }; /** Deserializes the end of a list. */ readListEnd(): void; /** * 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 }; /** 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 * is 1, in which case the value property is True. */ readBool(): Object; /** Returns an object with a value property set to the next value found in the protocol buffer. */ readByte(): Object; /** Returns an object with a value property set to the next value found in the protocol buffer. */ readI16(): Object; /** Returns an object with a value property set to the next value found in the protocol buffer. */ readI32(f?: any): Object; /** Returns an object with a value property set to the next value found in the protocol buffer. */ readI64(): Object; /** Returns an object with a value property set to the next value found in the protocol buffer. */ readDouble(): Object; /** Returns an object with a value property set to the next value found in the protocol buffer. */ readString(): Object; /** Returns an object with a value property set to the next value found in the protocol buffer. */ readBinary(): Object; /** * Method to arbitrarily skip over data (not implemented). */ skip(type: number): void; } /** * Old alias of the TXHRTransport for backwards compatibility. */ class Protocol extends TJSONProtocol {} class MultiplexProtocol extends TJSONProtocol { serviceName: string; /** * Initializes a MutilplexProtocol Implementation as a Wrapper for Thrift.Protocol. * @param {string} srvName * @param {Thrift.Transport} trans * @param {any} [strictRead] * @param {any} [strictWrite] */ constructor( srvName: string, trans: Object, strictRead?: any, strictWrite?: any, ); /** * Override writeMessageBegin method of prototype * Serializes the beginning of a Thrift RPC message. * @param {string} name - The service method to call. * @param {Thrift.MessageType} messageType - The type of method call. * @param {number} seqid - The sequence number of this call (always 0 in Apache Thrift). */ writeMessageBegin(name: string, type: number, seqid: number): void; } class Multiplexer { seqid: number; /** * Instantiates a multiplexed client for a specific service. * @param {String} serviceName - The transport to serialize to/from. * @param {Thrift.ServiceClient} SCl - The Service Client Class. * @param {Thrift.Transport} transport - Thrift.Transport instance which provides remote host:port. */ createClient(serviceName: string, SCl: any, transport: Object): any; } } thrift-0.23.0/lib/ts/Makefile.am0000664000175000017500000000277215165535636016635 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Make sure this doesn't fail if ant is not configured. # We call install twice to work around npm issues # if HAVE_NPM prereq: $(NPM) install || $(NPM) install $(NPM) list check-local: prereq all ./node_modules/.bin/grunt doc: prereq ./node_modules/.bin/grunt jsdoc endif clean-local: $(RM) -r dist $(RM) -r doc $(RM) -r node_modules $(RM) -r test/build/ $(RM) -r test/gen-*/ dist-hook: $(RM) -r $(distdir)/dist/ $(RM) -r $(distdir)/doc/ $(RM) -r $(distdir)/node_modules/ $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ package.json \ package-lock.json \ thrift.d.ts \ tsconfig.json thrift-0.23.0/lib/go/0000755000175000017500000000000015170007201014520 5ustar00buildbuild00000000000000thrift-0.23.0/lib/go/thrift/0000775000175000017500000000000015167543515016045 5ustar00buildbuild00000000000000thrift-0.23.0/lib/go/thrift/json_protocol.go0000664000175000017500000003603415165535636021277 0ustar00buildbuild00000000000000/* * 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 ( "context" "encoding/base64" "fmt" ) const ( THRIFT_JSON_PROTOCOL_VERSION = 1 ) // for references to _ParseContext see tsimplejson_protocol.go // JSON protocol implementation for thrift. // Utilizes Simple JSON protocol type TJSONProtocol struct { *TSimpleJSONProtocol } // Constructor func NewTJSONProtocol(t TTransport) *TJSONProtocol { v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)} v.parseContextStack.push(_CONTEXT_IN_TOPLEVEL) v.dumpContext.push(_CONTEXT_IN_TOPLEVEL) return v } // Factory type TJSONProtocolFactory struct{} func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { return NewTJSONProtocol(trans) } func NewTJSONProtocolFactory() *TJSONProtocolFactory { return &TJSONProtocolFactory{} } func (p *TJSONProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqId int32) error { p.resetContextStack() // THRIFT-3735 if e := p.OutputListBegin(); e != nil { return e } if e := p.WriteI32(ctx, THRIFT_JSON_PROTOCOL_VERSION); e != nil { return e } if e := p.WriteString(ctx, name); e != nil { return e } if e := p.WriteByte(ctx, int8(typeId)); e != nil { return e } if e := p.WriteI32(ctx, seqId); e != nil { return e } return nil } func (p *TJSONProtocol) WriteMessageEnd(ctx context.Context) error { return p.OutputListEnd() } func (p *TJSONProtocol) WriteStructBegin(ctx context.Context, name string) error { if e := p.OutputObjectBegin(); e != nil { return e } return nil } func (p *TJSONProtocol) WriteStructEnd(ctx context.Context) error { return p.OutputObjectEnd() } func (p *TJSONProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { if e := p.WriteI16(ctx, id); e != nil { return e } if e := p.OutputObjectBegin(); e != nil { return e } s, e1 := p.TypeIdToString(typeId) if e1 != nil { return e1 } if e := p.WriteString(ctx, s); e != nil { return e } return nil } func (p *TJSONProtocol) WriteFieldEnd(ctx context.Context) error { return p.OutputObjectEnd() } func (p *TJSONProtocol) WriteFieldStop(ctx context.Context) error { return nil } func (p *TJSONProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { if e := p.OutputListBegin(); e != nil { return e } s, e1 := p.TypeIdToString(keyType) if e1 != nil { return e1 } if e := p.WriteString(ctx, s); e != nil { return e } s, e1 = p.TypeIdToString(valueType) if e1 != nil { return e1 } if e := p.WriteString(ctx, s); e != nil { return e } if e := p.WriteI64(ctx, int64(size)); e != nil { return e } return p.OutputObjectBegin() } func (p *TJSONProtocol) WriteMapEnd(ctx context.Context) error { if e := p.OutputObjectEnd(); e != nil { return e } return p.OutputListEnd() } func (p *TJSONProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { return p.OutputElemListBegin(elemType, size) } func (p *TJSONProtocol) WriteListEnd(ctx context.Context) error { return p.OutputListEnd() } func (p *TJSONProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { return p.OutputElemListBegin(elemType, size) } func (p *TJSONProtocol) WriteSetEnd(ctx context.Context) error { return p.OutputListEnd() } func (p *TJSONProtocol) WriteBool(ctx context.Context, b bool) error { if b { return p.WriteI32(ctx, 1) } return p.WriteI32(ctx, 0) } func (p *TJSONProtocol) WriteByte(ctx context.Context, b int8) error { return p.WriteI32(ctx, int32(b)) } func (p *TJSONProtocol) WriteI16(ctx context.Context, v int16) error { return p.WriteI32(ctx, int32(v)) } func (p *TJSONProtocol) WriteI32(ctx context.Context, v int32) error { return p.OutputI64(int64(v)) } func (p *TJSONProtocol) WriteI64(ctx context.Context, v int64) error { return p.OutputI64(int64(v)) } func (p *TJSONProtocol) WriteDouble(ctx context.Context, v float64) error { return p.OutputF64(v) } func (p *TJSONProtocol) WriteString(ctx context.Context, v string) error { return p.OutputString(v) } func (p *TJSONProtocol) WriteBinary(ctx context.Context, v []byte) error { // JSON library only takes in a string, // not an arbitrary byte array, to ensure bytes are transmitted // efficiently we must convert this into a valid JSON string // therefore we use base64 encoding to avoid excessive escaping/quoting if e := p.OutputPreValue(); e != nil { return e } if _, e := p.write(JSON_QUOTE_BYTES); e != nil { return NewTProtocolException(e) } writer := base64.NewEncoder(base64.StdEncoding, p.writer) if _, e := writer.Write(v); e != nil { p.writer.Reset(p.trans) // THRIFT-3735 return NewTProtocolException(e) } if e := writer.Close(); e != nil { return NewTProtocolException(e) } if _, e := p.write(JSON_QUOTE_BYTES); e != nil { return NewTProtocolException(e) } return p.OutputPostValue() } // Reading methods. func (p *TJSONProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) { p.resetContextStack() // THRIFT-3735 if isNull, err := p.ParseListBegin(); isNull || err != nil { return name, typeId, seqId, err } version, err := p.ReadI32(ctx) if err != nil { return name, typeId, seqId, err } if version != THRIFT_JSON_PROTOCOL_VERSION { e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION) return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e) } if name, err = p.ReadString(ctx); err != nil { return name, typeId, seqId, err } bTypeId, err := p.ReadByte(ctx) typeId = TMessageType(bTypeId) if err != nil { return name, typeId, seqId, err } if seqId, err = p.ReadI32(ctx); err != nil { return name, typeId, seqId, err } return name, typeId, seqId, nil } func (p *TJSONProtocol) ReadMessageEnd(ctx context.Context) error { err := p.ParseListEnd() return err } func (p *TJSONProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { _, err = p.ParseObjectStart() return "", err } func (p *TJSONProtocol) ReadStructEnd(ctx context.Context) error { return p.ParseObjectEnd() } func (p *TJSONProtocol) ReadFieldBegin(ctx context.Context) (string, TType, int16, error) { b, _ := p.reader.Peek(1) if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] { return "", STOP, -1, nil } fieldId, err := p.ReadI16(ctx) if err != nil { return "", STOP, fieldId, err } if _, err = p.ParseObjectStart(); err != nil { return "", STOP, fieldId, err } sType, err := p.ReadString(ctx) if err != nil { return "", STOP, fieldId, err } fType, err := p.StringToTypeId(sType) return "", fType, fieldId, err } func (p *TJSONProtocol) ReadFieldEnd(ctx context.Context) error { return p.ParseObjectEnd() } func (p *TJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, e error) { if isNull, e := p.ParseListBegin(); isNull || e != nil { return VOID, VOID, 0, e } // read keyType sKeyType, e := p.ReadString(ctx) if e != nil { return keyType, valueType, size, e } keyType, e = p.StringToTypeId(sKeyType) if e != nil { return keyType, valueType, size, e } // read valueType sValueType, e := p.ReadString(ctx) if e != nil { return keyType, valueType, size, e } valueType, e = p.StringToTypeId(sValueType) if e != nil { return keyType, valueType, size, e } // read size iSize, err := p.ReadI64(ctx) if err != nil { return keyType, valueType, size, err } size = int(iSize) minElemSize := p.getMinSerializedSize(keyType) + p.getMinSerializedSize(valueType) totalMinSize := int32(iSize) * minElemSize err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return keyType, valueType, 0, err } _, e = p.ParseObjectStart() return keyType, valueType, size, e } func (p *TJSONProtocol) ReadMapEnd(ctx context.Context) error { e := p.ParseObjectEnd() if e != nil { return e } return p.ParseListEnd() } func (p *TJSONProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, e error) { return p.ParseElemListBegin() } func (p *TJSONProtocol) ReadListEnd(ctx context.Context) error { return p.ParseListEnd() } func (p *TJSONProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, e error) { return p.ParseElemListBegin() } func (p *TJSONProtocol) ReadSetEnd(ctx context.Context) error { return p.ParseListEnd() } func (p *TJSONProtocol) ReadBool(ctx context.Context) (bool, error) { value, err := p.ReadI32(ctx) return (value != 0), err } func (p *TJSONProtocol) ReadByte(ctx context.Context) (int8, error) { v, err := p.ReadI64(ctx) return int8(v), err } func (p *TJSONProtocol) ReadI16(ctx context.Context) (int16, error) { v, err := p.ReadI64(ctx) return int16(v), err } func (p *TJSONProtocol) ReadI32(ctx context.Context) (int32, error) { v, err := p.ReadI64(ctx) return int32(v), err } func (p *TJSONProtocol) ReadI64(ctx context.Context) (int64, error) { v, _, err := p.ParseI64() return v, err } func (p *TJSONProtocol) ReadDouble(ctx context.Context) (float64, error) { v, _, err := p.ParseF64() return v, err } func (p *TJSONProtocol) ReadString(ctx context.Context) (string, error) { var v string if err := p.ParsePreValue(); err != nil { return v, err } f, _ := p.reader.Peek(1) if len(f) > 0 && f[0] == JSON_QUOTE { p.reader.ReadByte() value, err := p.ParseStringBody() v = value if err != nil { return v, err } } else if len(f) > 0 && f[0] == JSON_NULL[0] { b := make([]byte, len(JSON_NULL)) _, err := p.reader.Read(b) if err != nil { return v, NewTProtocolException(err) } if string(b) != string(JSON_NULL) { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } } else { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } return v, p.ParsePostValue() } func (p *TJSONProtocol) ReadBinary(ctx context.Context) ([]byte, error) { var v []byte if err := p.ParsePreValue(); err != nil { return nil, err } f, _ := p.reader.Peek(1) if len(f) > 0 && f[0] == JSON_QUOTE { p.reader.ReadByte() value, err := p.ParseBase64EncodedBody() v = value if err != nil { return v, err } } else if len(f) > 0 && f[0] == JSON_NULL[0] { b := make([]byte, len(JSON_NULL)) _, err := p.reader.Read(b) if err != nil { return v, NewTProtocolException(err) } if string(b) != string(JSON_NULL) { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } } else { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } return v, p.ParsePostValue() } func (p *TJSONProtocol) Flush(ctx context.Context) (err error) { err = p.writer.Flush() if err == nil { err = p.trans.Flush(ctx) } return NewTProtocolException(err) } func (p *TJSONProtocol) Skip(ctx context.Context, fieldType TType) (err error) { return SkipDefaultDepth(ctx, p, fieldType) } func (p *TJSONProtocol) Transport() TTransport { return p.trans } func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error { if e := p.OutputListBegin(); e != nil { return e } s, e1 := p.TypeIdToString(elemType) if e1 != nil { return e1 } if e := p.OutputString(s); e != nil { return e } if e := p.OutputI64(int64(size)); e != nil { return e } return nil } func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { if isNull, e := p.ParseListBegin(); isNull || e != nil { return VOID, 0, e } // We don't really use the ctx in ReadString implementation, // so this is safe for now. // We might want to add context to ParseElemListBegin if we start to use // ctx in ReadString implementation in the future. sElemType, err := p.ReadString(context.Background()) if err != nil { return VOID, size, err } elemType, err = p.StringToTypeId(sElemType) if err != nil { return elemType, size, err } nSize, _, err := p.ParseI64() if err != nil { return elemType, 0, err } size = int(nSize) minElemSize := p.getMinSerializedSize(elemType) totalMinSize := int32(nSize) * minElemSize err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return elemType, 0, err } return elemType, size, nil } func (p *TJSONProtocol) TypeIdToString(fieldType TType) (string, error) { switch byte(fieldType) { case BOOL: return "tf", nil case BYTE: return "i8", nil case I16: return "i16", nil case I32: return "i32", nil case I64: return "i64", nil case DOUBLE: return "dbl", nil case STRING: return "str", nil case STRUCT: return "rec", nil case MAP: return "map", nil case SET: return "set", nil case LIST: return "lst", nil case UUID: return "uid", nil } e := fmt.Errorf("Unknown fieldType: %d", int(fieldType)) return "", NewTProtocolExceptionWithType(INVALID_DATA, e) } func (p *TJSONProtocol) StringToTypeId(fieldType string) (TType, error) { switch fieldType { case "tf": return TType(BOOL), nil case "i8": return TType(BYTE), nil case "i16": return TType(I16), nil case "i32": return TType(I32), nil case "i64": return TType(I64), nil case "dbl": return TType(DOUBLE), nil case "str": return TType(STRING), nil case "rec": return TType(STRUCT), nil case "map": return TType(MAP), nil case "set": return TType(SET), nil case "lst": return TType(LIST), nil case "uid": return TType(UUID), nil } e := fmt.Errorf("Unknown type identifier: %s", fieldType) return TType(STOP), NewTProtocolExceptionWithType(INVALID_DATA, e) } // Return the minimum number of bytes a type will consume on the wire func (p *TJSONProtocol) getMinSerializedSize(ttype TType) int32 { switch ttype { case STOP: return 1 // T_STOP needs to count itself case VOID: return 1 // T_VOID needs to count itself case BOOL: return 1 // written as int case BYTE: return 1 case DOUBLE: return 1 case I16: return 1 case I32: return 1 case I64: return 1 case STRING: return 2 // empty string case STRUCT: return 2 // empty struct case MAP: return 2 // empty map case SET: return 2 // empty set case LIST: return 2 // empty list case UUID: return 16 // empty UUID default: return 1 // unknown type } } var _ TConfigurationSetter = (*TJSONProtocol)(nil) thrift-0.23.0/lib/go/thrift/socket_conn.go0000664000175000017500000000703615165535636020712 0ustar00buildbuild00000000000000/* * 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 ( "errors" "net" "sync/atomic" ) // socketConn is a wrapped net.Conn that tries to do connectivity check. type socketConn struct { net.Conn buffer [1]byte closed atomic.Int32 } var _ net.Conn = (*socketConn)(nil) // createSocketConnFromReturn is a language sugar to help create socketConn from // return values of functions like net.Dial, tls.Dial, net.Listener.Accept, etc. func createSocketConnFromReturn(conn net.Conn, err error) (*socketConn, error) { if err != nil { return nil, err } return &socketConn{ Conn: conn, }, nil } // wrapSocketConn wraps an existing net.Conn into *socketConn. func wrapSocketConn(conn net.Conn) *socketConn { // In case conn is already wrapped, // return it as-is and avoid double wrapping. if sc, ok := conn.(*socketConn); ok { return sc } return &socketConn{ Conn: conn, } } // isValid checks whether there's a valid connection. // // It's nil safe, and returns false if sc itself is nil, or if the underlying // connection is nil. // // It's the same as the previous implementation of TSocket.IsOpen and // TSSLSocket.IsOpen before we added connectivity check. func (sc *socketConn) isValid() bool { return sc != nil && sc.Conn != nil && sc.closed.Load() == 0 } // IsOpen checks whether the connection is open. // // It's nil safe, and returns false if sc itself is nil, or if the underlying // connection is nil. // // Otherwise, it tries to do a connectivity check and returns the result. // // It also has the side effect of resetting the previously set read deadline on // the socket. As a result, it shouldn't be called between setting read deadline // and doing actual read. func (sc *socketConn) IsOpen() bool { if !sc.isValid() { return false } if err := sc.checkConn(); err != nil { if !errors.Is(err, net.ErrClosed) { // The connectivity check failed and the error is not // that the connection is already closed, we need to // close the connection explicitly here to avoid // connection leaks. sc.Close() } return false } return true } // Read implements io.Reader. // // On Windows, it behaves the same as the underlying net.Conn.Read. // // On non-Windows, it treats len(p) == 0 as a connectivity check instead of // readability check, which means instead of blocking until there's something to // read (readability check), or always return (0, nil) (the default behavior of // go's stdlib implementation on non-Windows), it never blocks, and will return // an error if the connection is lost. func (sc *socketConn) Read(p []byte) (n int, err error) { if len(p) == 0 { return 0, sc.read0() } return sc.Conn.Read(p) } func (sc *socketConn) Close() error { if !sc.isValid() { // Already closed return net.ErrClosed } sc.closed.Store(1) return sc.Conn.Close() } thrift-0.23.0/lib/go/thrift/debug_protocol.go0000664000175000017500000004204715165535636021415 0ustar00buildbuild00000000000000/* * 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 ( "context" "log/slog" ) type TDebugProtocol struct { // Required. The actual TProtocol to do the read/write. Delegate TProtocol // Optional. The logger and prefix to log all the args/return values // from Delegate TProtocol calls. // // If Logger is nil, StdLogger using stdlib log package with os.Stderr // will be used. If disable logging is desired, set Logger to NopLogger // explicitly instead of leaving it as nil/unset. // // Deprecated: TDebugProtocol always use slog at debug level now. // This field will be removed in a future version. Logger Logger LogPrefix string // Optional. An TProtocol to duplicate everything read/written from Delegate. // // A typical use case of this is to use TSimpleJSONProtocol wrapping // TMemoryBuffer in a middleware to json logging requests/responses. // // This feature is not available from TDebugProtocolFactory. In order to // use it you have to construct TDebugProtocol directly, or set DuplicateTo // field after getting a TDebugProtocol from the factory. // // Deprecated: Please use TDuplicateToProtocol instead. DuplicateTo TProtocol } type TDebugProtocolFactory struct { Underlying TProtocolFactory LogPrefix string Logger Logger } // NewTDebugProtocolFactory creates a TDebugProtocolFactory. // // Deprecated: Please use NewTDebugProtocolFactoryWithLogger or the struct // itself instead. This version will use the default logger from standard // library. func NewTDebugProtocolFactory(underlying TProtocolFactory, logPrefix string) *TDebugProtocolFactory { return &TDebugProtocolFactory{ Underlying: underlying, LogPrefix: logPrefix, Logger: StdLogger(nil), } } // NewTDebugProtocolFactoryWithLogger creates a TDebugProtocolFactory. func NewTDebugProtocolFactoryWithLogger(underlying TProtocolFactory, logPrefix string, logger Logger) *TDebugProtocolFactory { return &TDebugProtocolFactory{ Underlying: underlying, LogPrefix: logPrefix, Logger: logger, } } func (t *TDebugProtocolFactory) GetProtocol(trans TTransport) TProtocol { return &TDebugProtocol{ Delegate: t.Underlying.GetProtocol(trans), LogPrefix: t.LogPrefix, Logger: fallbackLogger(t.Logger), } } func (tdp *TDebugProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error { err := tdp.Delegate.WriteMessageBegin(ctx, name, typeId, seqid) slog.DebugContext( ctx, tdp.LogPrefix+"WriteMessageBegin", "name", name, "typeId", typeId, "seqid", seqid, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid) } return err } func (tdp *TDebugProtocol) WriteMessageEnd(ctx context.Context) error { err := tdp.Delegate.WriteMessageEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"WriteMessageEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMessageEnd(ctx) } return err } func (tdp *TDebugProtocol) WriteStructBegin(ctx context.Context, name string) error { err := tdp.Delegate.WriteStructBegin(ctx, name) slog.DebugContext( ctx, tdp.LogPrefix+"WriteStructBegin", "name", name, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteStructBegin(ctx, name) } return err } func (tdp *TDebugProtocol) WriteStructEnd(ctx context.Context) error { err := tdp.Delegate.WriteStructEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"WriteStructEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteStructEnd(ctx) } return err } func (tdp *TDebugProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { err := tdp.Delegate.WriteFieldBegin(ctx, name, typeId, id) slog.DebugContext( ctx, tdp.LogPrefix+"WriteFieldBegin", "name", name, "typeId", typeId, "id", id, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id) } return err } func (tdp *TDebugProtocol) WriteFieldEnd(ctx context.Context) error { err := tdp.Delegate.WriteFieldEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"WriteFieldEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteFieldEnd(ctx) } return err } func (tdp *TDebugProtocol) WriteFieldStop(ctx context.Context) error { err := tdp.Delegate.WriteFieldStop(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"WriteFieldStop", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteFieldStop(ctx) } return err } func (tdp *TDebugProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { err := tdp.Delegate.WriteMapBegin(ctx, keyType, valueType, size) slog.DebugContext( ctx, tdp.LogPrefix+"WriteMapBegin", "keyType", keyType, "valueType", valueType, "size", size, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size) } return err } func (tdp *TDebugProtocol) WriteMapEnd(ctx context.Context) error { err := tdp.Delegate.WriteMapEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"WriteMapEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMapEnd(ctx) } return err } func (tdp *TDebugProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { err := tdp.Delegate.WriteListBegin(ctx, elemType, size) slog.DebugContext( ctx, tdp.LogPrefix+"WriteListBegin", "elemType", elemType, "size", size, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteListBegin(ctx, elemType, size) } return err } func (tdp *TDebugProtocol) WriteListEnd(ctx context.Context) error { err := tdp.Delegate.WriteListEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"WriteListEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteListEnd(ctx) } return err } func (tdp *TDebugProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { err := tdp.Delegate.WriteSetBegin(ctx, elemType, size) slog.DebugContext( ctx, tdp.LogPrefix+"WriteSetBegin", "elemType", elemType, "size", size, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteSetBegin(ctx, elemType, size) } return err } func (tdp *TDebugProtocol) WriteSetEnd(ctx context.Context) error { err := tdp.Delegate.WriteSetEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"WriteSetEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteSetEnd(ctx) } return err } func (tdp *TDebugProtocol) WriteBool(ctx context.Context, value bool) error { err := tdp.Delegate.WriteBool(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteBool", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteBool(ctx, value) } return err } func (tdp *TDebugProtocol) WriteByte(ctx context.Context, value int8) error { err := tdp.Delegate.WriteByte(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteByte", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteByte(ctx, value) } return err } func (tdp *TDebugProtocol) WriteI16(ctx context.Context, value int16) error { err := tdp.Delegate.WriteI16(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteI16", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteI16(ctx, value) } return err } func (tdp *TDebugProtocol) WriteI32(ctx context.Context, value int32) error { err := tdp.Delegate.WriteI32(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteI32", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteI32(ctx, value) } return err } func (tdp *TDebugProtocol) WriteI64(ctx context.Context, value int64) error { err := tdp.Delegate.WriteI64(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteI64", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteI64(ctx, value) } return err } func (tdp *TDebugProtocol) WriteDouble(ctx context.Context, value float64) error { err := tdp.Delegate.WriteDouble(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteDouble", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteDouble(ctx, value) } return err } func (tdp *TDebugProtocol) WriteString(ctx context.Context, value string) error { err := tdp.Delegate.WriteString(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteString", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteString(ctx, value) } return err } func (tdp *TDebugProtocol) WriteBinary(ctx context.Context, value []byte) error { err := tdp.Delegate.WriteBinary(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteBinary", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteBinary(ctx, value) } return err } func (tdp *TDebugProtocol) WriteUUID(ctx context.Context, value Tuuid) error { err := tdp.Delegate.WriteUUID(ctx, value) slog.DebugContext( ctx, tdp.LogPrefix+"WriteUUID", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteUUID(ctx, value) } return err } func (tdp *TDebugProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) { name, typeId, seqid, err = tdp.Delegate.ReadMessageBegin(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadMessageBegin", "name", name, "typeId", typeId, "seqid", seqid, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid) } return } func (tdp *TDebugProtocol) ReadMessageEnd(ctx context.Context) (err error) { err = tdp.Delegate.ReadMessageEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadMessageEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMessageEnd(ctx) } return } func (tdp *TDebugProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { name, err = tdp.Delegate.ReadStructBegin(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadStructBegin", "name", name, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteStructBegin(ctx, name) } return } func (tdp *TDebugProtocol) ReadStructEnd(ctx context.Context) (err error) { err = tdp.Delegate.ReadStructEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadStructEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteStructEnd(ctx) } return } func (tdp *TDebugProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) { name, typeId, id, err = tdp.Delegate.ReadFieldBegin(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadFieldBegin", "name", name, "typeId", typeId, "id", id, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id) } return } func (tdp *TDebugProtocol) ReadFieldEnd(ctx context.Context) (err error) { err = tdp.Delegate.ReadFieldEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadFieldEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteFieldEnd(ctx) } return } func (tdp *TDebugProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) { keyType, valueType, size, err = tdp.Delegate.ReadMapBegin(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadMapBegin", "keyType", keyType, "valueType", valueType, "size", size, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size) } return } func (tdp *TDebugProtocol) ReadMapEnd(ctx context.Context) (err error) { err = tdp.Delegate.ReadMapEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadMapEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteMapEnd(ctx) } return } func (tdp *TDebugProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { elemType, size, err = tdp.Delegate.ReadListBegin(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadListBegin", "elemType", elemType, "size", size, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteListBegin(ctx, elemType, size) } return } func (tdp *TDebugProtocol) ReadListEnd(ctx context.Context) (err error) { err = tdp.Delegate.ReadListEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadListEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteListEnd(ctx) } return } func (tdp *TDebugProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { elemType, size, err = tdp.Delegate.ReadSetBegin(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadSetBegin", "elemType", elemType, "size", size, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteSetBegin(ctx, elemType, size) } return } func (tdp *TDebugProtocol) ReadSetEnd(ctx context.Context) (err error) { err = tdp.Delegate.ReadSetEnd(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadSetEnd", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteSetEnd(ctx) } return } func (tdp *TDebugProtocol) ReadBool(ctx context.Context) (value bool, err error) { value, err = tdp.Delegate.ReadBool(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadBool", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteBool(ctx, value) } return } func (tdp *TDebugProtocol) ReadByte(ctx context.Context) (value int8, err error) { value, err = tdp.Delegate.ReadByte(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadByte", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteByte(ctx, value) } return } func (tdp *TDebugProtocol) ReadI16(ctx context.Context) (value int16, err error) { value, err = tdp.Delegate.ReadI16(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadI16", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteI16(ctx, value) } return } func (tdp *TDebugProtocol) ReadI32(ctx context.Context) (value int32, err error) { value, err = tdp.Delegate.ReadI32(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadI32", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteI32(ctx, value) } return } func (tdp *TDebugProtocol) ReadI64(ctx context.Context) (value int64, err error) { value, err = tdp.Delegate.ReadI64(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadI64", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteI64(ctx, value) } return } func (tdp *TDebugProtocol) ReadDouble(ctx context.Context) (value float64, err error) { value, err = tdp.Delegate.ReadDouble(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadDouble", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteDouble(ctx, value) } return } func (tdp *TDebugProtocol) ReadString(ctx context.Context) (value string, err error) { value, err = tdp.Delegate.ReadString(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadString", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteString(ctx, value) } return } func (tdp *TDebugProtocol) ReadBinary(ctx context.Context) (value []byte, err error) { value, err = tdp.Delegate.ReadBinary(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadBinary", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteBinary(ctx, value) } return } func (tdp *TDebugProtocol) ReadUUID(ctx context.Context) (value Tuuid, err error) { value, err = tdp.Delegate.ReadUUID(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"ReadUUID", "value", value, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.WriteUUID(ctx, value) } return } func (tdp *TDebugProtocol) Skip(ctx context.Context, fieldType TType) (err error) { err = tdp.Delegate.Skip(ctx, fieldType) slog.DebugContext( ctx, tdp.LogPrefix+"Skip", "fieldType", fieldType, "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.Skip(ctx, fieldType) } return } func (tdp *TDebugProtocol) Flush(ctx context.Context) (err error) { err = tdp.Delegate.Flush(ctx) slog.DebugContext( ctx, tdp.LogPrefix+"Flush", "err", err, ) if tdp.DuplicateTo != nil { tdp.DuplicateTo.Flush(ctx) } return } func (tdp *TDebugProtocol) Transport() TTransport { return tdp.Delegate.Transport() } // SetTConfiguration implements TConfigurationSetter for propagation. func (tdp *TDebugProtocol) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(tdp.Delegate, conf) PropagateTConfiguration(tdp.DuplicateTo, conf) } var _ TConfigurationSetter = (*TDebugProtocol)(nil) thrift-0.23.0/lib/go/thrift/transport_test.go0000664000175000017500000001360315165535636021475 0ustar00buildbuild00000000000000/* * 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 ( "context" "io" "net" "strconv" "testing" ) const TRANSPORT_BINARY_DATA_SIZE = 4096 var ( transport_bdata []byte // test data for writing; same as data transport_header map[string]string ) func init() { transport_bdata = make([]byte, TRANSPORT_BINARY_DATA_SIZE) for i := range TRANSPORT_BINARY_DATA_SIZE { transport_bdata[i] = byte((i + 'a') % 255) } transport_header = map[string]string{"key": "User-Agent", "value": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"} } func TransportTest(t *testing.T, writeTrans TTransport, readTrans TTransport) { buf := make([]byte, TRANSPORT_BINARY_DATA_SIZE) if !writeTrans.IsOpen() { t.Fatalf("Transport %T not open: %s", writeTrans, writeTrans) } if !readTrans.IsOpen() { t.Fatalf("Transport %T not open: %s", readTrans, readTrans) } _, err := writeTrans.Write(transport_bdata) if err != nil { t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err) } err = writeTrans.Flush(context.Background()) if err != nil { t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err) } n, err := io.ReadFull(readTrans, buf) if err != nil { t.Errorf("Transport %T cannot read binary data of length %d: %s", readTrans, TRANSPORT_BINARY_DATA_SIZE, err) } if n != TRANSPORT_BINARY_DATA_SIZE { t.Errorf("Transport %T read only %d instead of %d bytes of binary data", readTrans, n, TRANSPORT_BINARY_DATA_SIZE) } for k, v := range buf { if v != transport_bdata[k] { t.Fatalf("Transport %T read %d instead of %d for index %d of binary data 2", readTrans, v, transport_bdata[k], k) } } _, err = writeTrans.Write(transport_bdata) if err != nil { t.Fatalf("Transport %T cannot write binary data 2 of length %d: %s", writeTrans, len(transport_bdata), err) } err = writeTrans.Flush(context.Background()) if err != nil { t.Fatalf("Transport %T cannot flush write binary data 2: %s", writeTrans, err) } buf = make([]byte, TRANSPORT_BINARY_DATA_SIZE) read := 1 for n = 0; n < TRANSPORT_BINARY_DATA_SIZE && read != 0; { read, err = readTrans.Read(buf[n:]) if err != nil { t.Errorf("Transport %T cannot read binary data 2 of total length %d from offset %d: %s", readTrans, TRANSPORT_BINARY_DATA_SIZE, n, err) } n += read } if n != TRANSPORT_BINARY_DATA_SIZE { t.Errorf("Transport %T read only %d instead of %d bytes of binary data 2", readTrans, n, TRANSPORT_BINARY_DATA_SIZE) } for k, v := range buf { if v != transport_bdata[k] { t.Fatalf("Transport %T read %d instead of %d for index %d of binary data 2", readTrans, v, transport_bdata[k], k) } } } func TransportHeaderTest(t *testing.T, writeTrans TTransport, readTrans TTransport) { buf := make([]byte, TRANSPORT_BINARY_DATA_SIZE) if !writeTrans.IsOpen() { t.Fatalf("Transport %T not open: %s", writeTrans, writeTrans) } if !readTrans.IsOpen() { t.Fatalf("Transport %T not open: %s", readTrans, readTrans) } // Need to assert type of TTransport to THttpClient to expose the Setter httpWPostTrans := writeTrans.(*THttpClient) httpWPostTrans.SetHeader(transport_header["key"], transport_header["value"]) _, err := writeTrans.Write(transport_bdata) if err != nil { t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err) } err = writeTrans.Flush(context.Background()) if err != nil { t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err) } // Need to assert type of TTransport to THttpClient to expose the Getter httpRPostTrans := readTrans.(*THttpClient) readHeader := httpRPostTrans.GetHeader(transport_header["key"]) if err != nil { t.Errorf("Transport %T cannot read HTTP Header Value", httpRPostTrans) } if transport_header["value"] != readHeader { t.Errorf("Expected HTTP Header Value %s, got %s", transport_header["value"], readHeader) } n, err := io.ReadFull(readTrans, buf) if err != nil { t.Errorf("Transport %T cannot read binary data of length %d: %s", readTrans, TRANSPORT_BINARY_DATA_SIZE, err) } if n != TRANSPORT_BINARY_DATA_SIZE { t.Errorf("Transport %T read only %d instead of %d bytes of binary data", readTrans, n, TRANSPORT_BINARY_DATA_SIZE) } for k, v := range buf { if v != transport_bdata[k] { t.Fatalf("Transport %T read %d instead of %d for index %d of binary data 2", readTrans, v, transport_bdata[k], k) } } } func CloseTransports(t *testing.T, readTrans TTransport, writeTrans TTransport) { err := readTrans.Close() if err != nil { t.Errorf("Transport %T cannot close read transport: %s", readTrans, err) } if writeTrans != readTrans { err = writeTrans.Close() if err != nil { t.Errorf("Transport %T cannot close write transport: %s", writeTrans, err) } } } func FindAvailableTCPServerPort(startPort int) (net.Addr, error) { for i := startPort; i < 65535; i++ { s := "127.0.0.1:" + strconv.Itoa(i) l, err := net.Listen("tcp", s) if err == nil { l.Close() return net.ResolveTCPAddr("tcp", s) } } return nil, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Could not find available server port") } thrift-0.23.0/lib/go/thrift/socket_non_aix_syscall.go0000664000175000017500000000177615167543515023144 0ustar00buildbuild00000000000000//go: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) } thrift-0.23.0/lib/go/thrift/header_transport.go0000664000175000017500000005701615167543515021751 0ustar00buildbuild00000000000000/* * 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 ( "bufio" "bytes" "compress/zlib" "context" "encoding/binary" "errors" "fmt" "io" "slices" ) // Size in bytes for 32-bit ints. const size32 = 4 type headerMeta struct { MagicFlags uint32 SequenceID int32 HeaderLength uint16 } const headerMetaSize = 10 type clientType int const ( clientUnknown clientType = iota clientHeaders clientFramedBinary clientUnframedBinary clientFramedCompact clientUnframedCompact ) // Constants defined in THeader format: // https://github.com/apache/thrift/blob/master/doc/specs/HeaderFormat.md const ( THeaderHeaderMagic uint32 = 0x0fff0000 THeaderHeaderMask uint32 = 0xffff0000 THeaderFlagsMask uint32 = 0x0000ffff THeaderMaxFrameSize uint32 = 0x3fffffff ) // THeaderMap is the type of the header map in THeader transport. type THeaderMap map[string]string // THeaderProtocolID is the wrapped protocol id used in THeader. type THeaderProtocolID int32 // Supported THeaderProtocolID values. const ( THeaderProtocolBinary THeaderProtocolID = 0x00 THeaderProtocolCompact THeaderProtocolID = 0x02 THeaderProtocolDefault = THeaderProtocolBinary ) // Declared globally to avoid repetitive allocations, not really used. var globalMemoryBuffer = NewTMemoryBuffer() // Validate checks whether the THeaderProtocolID is a valid/supported one. func (id THeaderProtocolID) Validate() error { _, err := id.GetProtocol(globalMemoryBuffer) return err } // GetProtocol gets the corresponding TProtocol from the wrapped protocol id. func (id THeaderProtocolID) GetProtocol(trans TTransport) (TProtocol, error) { switch id { default: return nil, NewTApplicationException( INVALID_PROTOCOL, fmt.Sprintf("THeader protocol id %d not supported", id), ) case THeaderProtocolBinary: return NewTBinaryProtocolTransport(trans), nil case THeaderProtocolCompact: return NewTCompactProtocol(trans), nil } } // THeaderTransformID defines the numeric id of the transform used. type THeaderTransformID int32 // THeaderTransformID values. // // Values not defined here are not currently supported, namely HMAC and Snappy. const ( TransformNone THeaderTransformID = iota // 0, no special handling TransformZlib // 1, zlib ) var supportedTransformIDs = map[THeaderTransformID]bool{ TransformNone: true, TransformZlib: true, } // TransformReader is an io.ReadCloser that handles transforms reading. type TransformReader struct { io.Reader closers []io.Closer } var _ io.ReadCloser = (*TransformReader)(nil) // NewTransformReaderWithCapacity initializes a TransformReader with expected // closers capacity. // // If you don't know the closers capacity beforehand, just use // // &TransformReader{Reader: baseReader} // // instead would be sufficient. func NewTransformReaderWithCapacity(baseReader io.Reader, capacity int) *TransformReader { return &TransformReader{ Reader: baseReader, closers: make([]io.Closer, 0, capacity), } } // Close calls the underlying closers in appropriate order, // stops at and returns the first error encountered. func (tr *TransformReader) Close() error { // Call closers in reversed order for i := len(tr.closers) - 1; i >= 0; i-- { if err := tr.closers[i].Close(); err != nil { return err } } return nil } // 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: return NewTApplicationException( INVALID_TRANSFORM, fmt.Sprintf("THeaderTransformID %d not supported", id), ) case TransformNone: // no-op case TransformZlib: readCloser, err := newZlibReader(tr.Reader) if err != nil { return err } tr.Reader = readCloser tr.closers = append(tr.closers, readCloser) } return nil } // TransformWriter is an io.WriteCloser that handles transforms writing. type TransformWriter struct { io.Writer closers []io.Closer } var _ io.WriteCloser = (*TransformWriter)(nil) // NewTransformWriter creates a new TransformWriter with base writer and transforms. func NewTransformWriter(baseWriter io.Writer, transforms []THeaderTransformID) (io.WriteCloser, error) { writer := &TransformWriter{ Writer: baseWriter, closers: make([]io.Closer, 0, len(transforms)), } for _, id := range transforms { if err := writer.AddTransform(id); err != nil { return nil, err } } return writer, nil } // Close calls the underlying closers in appropriate order, // stops at and returns the first error encountered. func (tw *TransformWriter) Close() error { // Call closers in reversed order for i := len(tw.closers) - 1; i >= 0; i-- { if err := tw.closers[i].Close(); err != nil { return err } } return nil } // AddTransform adds a transform. func (tw *TransformWriter) AddTransform(id THeaderTransformID) error { switch id { default: return NewTApplicationException( INVALID_TRANSFORM, fmt.Sprintf("THeaderTransformID %d not supported", id), ) case TransformNone: // no-op case TransformZlib: writer, closer, err := newZlibWriterCloserLevel(tw.Writer, zlib.DefaultCompression) if err != nil { return err } tw.Writer = writer tw.closers = append(tw.closers, closer) } return nil } // THeaderInfoType is the type id of the info headers. type THeaderInfoType int32 // Supported THeaderInfoType values. const ( _ THeaderInfoType = iota // Skip 0 InfoKeyValue // 1 // Rest of the info types are not supported. ) // THeaderTransport is a Transport mode that implements THeader. // // Note that THeaderTransport handles frame and zlib by itself, // so the underlying transport should be a raw socket transports (TSocket or TSSLSocket), // instead of rich transports like TZlibTransport or TFramedTransport. type THeaderTransport struct { SequenceID int32 Flags uint32 transport TTransport // THeaderMap for read and write readHeaders THeaderMap writeHeaders THeaderMap // Reading related variables. reader *bufio.Reader // When frame is detected, we read the frame fully into frameBuffer. frameBuffer *bytes.Buffer // When it's non-nil, Read should read from frameReader instead of // reader, and EOF error indicates end of frame instead of end of all // transport. frameReader io.ReadCloser // Writing related variables writeBuffer *bytes.Buffer writeTransforms []THeaderTransformID clientType clientType protocolID THeaderProtocolID cfg *TConfiguration // buffer is used in the following scenarios to avoid repetitive // allocations, while 4 is big enough for all those scenarios: // // * header padding (max size 4) // * write the frame size (size 4) buffer [4]byte } var _ TTransport = (*THeaderTransport)(nil) // Deprecated: Use NewTHeaderTransportConf instead. func NewTHeaderTransport(trans TTransport) *THeaderTransport { return NewTHeaderTransportConf(trans, &TConfiguration{ noPropagation: true, }) } // NewTHeaderTransportConf creates THeaderTransport from the // underlying transport, with given TConfiguration attached. // // If trans is already a *THeaderTransport, it will be returned as is, // but with TConfiguration overridden by the value passed in. // // The protocol ID in TConfiguration is only useful for client transports. // For servers, // the protocol ID will be overridden again to the one set by the client, // to ensure that servers always speak the same dialect as the client. func NewTHeaderTransportConf(trans TTransport, conf *TConfiguration) *THeaderTransport { if ht, ok := trans.(*THeaderTransport); ok { ht.SetTConfiguration(conf) return ht } PropagateTConfiguration(trans, conf) return &THeaderTransport{ transport: trans, reader: bufio.NewReader(trans), writeHeaders: make(THeaderMap), writeTransforms: conf.GetTHeaderTransforms(), protocolID: conf.GetTHeaderProtocolID(), cfg: conf, } } // Open calls the underlying transport's Open function. func (t *THeaderTransport) Open() error { return t.transport.Open() } // IsOpen calls the underlying transport's IsOpen function. func (t *THeaderTransport) IsOpen() bool { return t.transport.IsOpen() } // ReadFrame tries to read the frame header, guess the client type, and handle // unframed clients. func (t *THeaderTransport) ReadFrame(ctx context.Context) error { if !t.needReadFrame() { // No need to read frame, skipping. return nil } // Peek and handle the first 32 bits. // They could either be the length field of a framed message, // or the first bytes of an unframed message. var buf []byte var err error // This is also usually the first read from a connection, // so handle retries around socket timeouts. _, deadlineSet := ctx.Deadline() for { buf, err = t.reader.Peek(size32) if deadlineSet && isTimeoutError(err) && ctx.Err() == nil { // This is I/O timeout and we still have time, // continue trying continue } // For anything else, do not retry break } if err != nil { return err } frameSize := binary.BigEndian.Uint32(buf) if frameSize&VERSION_MASK == VERSION_1 { t.clientType = clientUnframedBinary return nil } if buf[0] == COMPACT_PROTOCOL_ID && buf[1]&COMPACT_VERSION_MASK == COMPACT_VERSION { t.clientType = clientUnframedCompact return nil } // At this point it should be a framed message, // sanity check on frameSize then discard the peeked part. if frameSize > THeaderMaxFrameSize || frameSize > uint32(t.cfg.GetMaxFrameSize()) { return NewTProtocolExceptionWithType( SIZE_LIMIT, errors.New("frame too large"), ) } t.reader.Discard(size32) // Read the frame fully into frameBuffer. if t.frameBuffer == nil { t.frameBuffer = bufPool.get() } _, err = io.CopyN(t.frameBuffer, t.reader, int64(frameSize)) if err != nil { return err } t.frameReader = io.NopCloser(t.frameBuffer) // Peek and handle the next 32 bits. buf = t.frameBuffer.Bytes()[:size32] version := binary.BigEndian.Uint32(buf) if version&THeaderHeaderMask == THeaderHeaderMagic { t.clientType = clientHeaders return t.parseHeaders(ctx, frameSize) } if version&VERSION_MASK == VERSION_1 { t.clientType = clientFramedBinary return nil } if buf[0] == COMPACT_PROTOCOL_ID && buf[1]&COMPACT_VERSION_MASK == COMPACT_VERSION { t.clientType = clientFramedCompact return nil } if err := t.endOfFrame(); err != nil { return err } return NewTProtocolExceptionWithType( NOT_IMPLEMENTED, errors.New("unsupported client transport type"), ) } // endOfFrame does end of frame handling. // // It closes frameReader, and also resets frame related states. func (t *THeaderTransport) endOfFrame() error { defer func() { bufPool.put(&t.frameBuffer) t.frameReader = nil }() return t.frameReader.Close() } func (t *THeaderTransport) parseHeaders(ctx context.Context, frameSize uint32) error { if t.clientType != clientHeaders { return nil } var err error var meta headerMeta if err = binary.Read(t.frameBuffer, binary.BigEndian, &meta); err != nil { return err } frameSize -= headerMetaSize t.Flags = meta.MagicFlags & THeaderFlagsMask t.SequenceID = meta.SequenceID headerLength := int64(meta.HeaderLength) * 4 if int64(frameSize) < headerLength { return NewTProtocolExceptionWithType( SIZE_LIMIT, errors.New("header size is larger than the whole frame"), ) } headerBuf := NewTMemoryBuffer() _, err = io.CopyN(headerBuf, t.frameBuffer, headerLength) if err != nil { return err } hp := NewTCompactProtocol(headerBuf) hp.SetTConfiguration(t.cfg) // At this point the header is already read into headerBuf, // and t.frameBuffer starts from the actual payload. protoID, err := hp.readVarint32() if err != nil { return err } 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 { return err } if transformCount > 0 { reader := NewTransformReaderWithCapacity( t.frameBuffer, int(transformCount), ) t.frameReader = reader transformIDs := make([]THeaderTransformID, transformCount) for i := range int(transformCount) { id, err := hp.readVarint32() if err != nil { return err } 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. for i := transformCount - 1; i >= 0; i-- { id := transformIDs[i] if err := reader.AddTransform(id); err != nil { return err } } } // The info part does not use the transforms yet, so it's // important to continue using headerBuf. headers := make(THeaderMap) for { infoType, err := hp.readVarint32() if errors.Is(err, io.EOF) { break } if err != nil { return err } if THeaderInfoType(infoType) == InfoKeyValue { count, err := hp.readVarint32() if err != nil { return err } for range int(count) { key, err := hp.ReadString(ctx) if err != nil { return err } value, err := hp.ReadString(ctx) if err != nil { return err } headers[key] = value } } else { // Skip reading info section on the first // unsupported info type. break } } t.readHeaders = headers return nil } func (t *THeaderTransport) needReadFrame() bool { if t.clientType == clientUnknown { // This is a new connection that's never read before. return true } if t.isFramed() && t.frameReader == nil { // We just finished the last frame. return true } return false } func (t *THeaderTransport) Read(p []byte) (read int, err error) { // Here using context.Background instead of a context passed in is safe. // First is that there's no way to pass context into this function. // Then, 99% of the case when calling this Read frame is already read // into frameReader. ReadFrame here is more of preventing bugs that // didn't call ReadFrame before calling Read. err = t.ReadFrame(context.Background()) if err != nil { return } if t.frameReader != nil { read, err = t.frameReader.Read(p) if err == nil && t.frameBuffer.Len() <= 0 { // the last Read finished the frame, do endOfFrame // handling here. err = t.endOfFrame() } else if errors.Is(err, io.EOF) { err = t.endOfFrame() if err != nil { return } if read == 0 { // Try to read the next frame when we hit EOF // (end of frame) immediately. // When we got here, it means the last read // finished the previous frame, but didn't // do endOfFrame handling yet. // We have to read the next frame here, // as otherwise we would return 0 and nil, // which is a case not handled well by most // protocol implementations. return t.Read(p) } } return } return t.reader.Read(p) } // Write writes data to the write buffer. // // You need to call Flush to actually write them to the transport. func (t *THeaderTransport) Write(p []byte) (int, error) { if t.writeBuffer == nil { t.writeBuffer = bufPool.get() } return t.writeBuffer.Write(p) } // Flush writes the appropriate header and the write buffer to the underlying transport. func (t *THeaderTransport) Flush(ctx context.Context) error { if t.writeBuffer == nil || t.writeBuffer.Len() == 0 { return nil } defer bufPool.put(&t.writeBuffer) switch t.clientType { default: fallthrough case clientUnknown: t.clientType = clientHeaders fallthrough case clientHeaders: headers := NewTMemoryBuffer() hp := NewTCompactProtocol(headers) hp.SetTConfiguration(t.cfg) if _, err := hp.writeVarint32(int32(t.protocolID)); err != nil { return NewTTransportExceptionFromError(err) } if _, err := hp.writeVarint32(int32(len(t.writeTransforms))); err != nil { return NewTTransportExceptionFromError(err) } for _, transform := range t.writeTransforms { if _, err := hp.writeVarint32(int32(transform)); err != nil { return NewTTransportExceptionFromError(err) } } if len(t.writeHeaders) > 0 { if _, err := hp.writeVarint32(int32(InfoKeyValue)); err != nil { return NewTTransportExceptionFromError(err) } if _, err := hp.writeVarint32(int32(len(t.writeHeaders))); err != nil { return NewTTransportExceptionFromError(err) } for key, value := range t.writeHeaders { if err := hp.WriteString(ctx, key); err != nil { return NewTTransportExceptionFromError(err) } if err := hp.WriteString(ctx, value); err != nil { return NewTTransportExceptionFromError(err) } } } padding := 4 - headers.Len()%4 if padding < 4 { buf := t.buffer[:padding] for i := range buf { buf[i] = 0 } if _, err := headers.Write(buf); err != nil { return NewTTransportExceptionFromError(err) } } payload := bufPool.get() defer bufPool.put(&payload) meta := headerMeta{ MagicFlags: THeaderHeaderMagic + t.Flags&THeaderFlagsMask, SequenceID: t.SequenceID, HeaderLength: uint16(headers.Len() / 4), } if err := binary.Write(payload, binary.BigEndian, meta); err != nil { return NewTTransportExceptionFromError(err) } if _, err := io.Copy(payload, headers); err != nil { return NewTTransportExceptionFromError(err) } writer, err := NewTransformWriter(payload, t.writeTransforms) if err != nil { return NewTTransportExceptionFromError(err) } if _, err := io.Copy(writer, t.writeBuffer); err != nil { return NewTTransportExceptionFromError(err) } if err := writer.Close(); err != nil { return NewTTransportExceptionFromError(err) } // First write frame length buf := t.buffer[:size32] binary.BigEndian.PutUint32(buf, uint32(payload.Len())) if _, err := t.transport.Write(buf); err != nil { return NewTTransportExceptionFromError(err) } // Then write the payload if _, err := io.Copy(t.transport, payload); err != nil { return NewTTransportExceptionFromError(err) } case clientFramedBinary, clientFramedCompact: buf := t.buffer[:size32] binary.BigEndian.PutUint32(buf, uint32(t.writeBuffer.Len())) if _, err := t.transport.Write(buf); err != nil { return NewTTransportExceptionFromError(err) } fallthrough case clientUnframedBinary, clientUnframedCompact: if _, err := io.Copy(t.transport, t.writeBuffer); err != nil { return NewTTransportExceptionFromError(err) } } select { default: case <-ctx.Done(): return NewTTransportExceptionFromError(ctx.Err()) } return t.transport.Flush(ctx) } // Close closes the transport, along with its underlying transport. func (t *THeaderTransport) Close() error { if err := t.Flush(context.Background()); err != nil { return err } return t.transport.Close() } // RemainingBytes calls underlying transport's RemainingBytes. // // Even in framed cases, because of all the possible compression transforms // involved, the remaining frame size is likely to be different from the actual // remaining readable bytes, so we don't bother to keep tracking the remaining // frame size by ourselves and just use the underlying transport's // RemainingBytes directly. func (t *THeaderTransport) RemainingBytes() uint64 { return t.transport.RemainingBytes() } // GetReadHeaders returns the THeaderMap read from transport. func (t *THeaderTransport) GetReadHeaders() THeaderMap { return t.readHeaders } // SetWriteHeader sets a header for write. func (t *THeaderTransport) SetWriteHeader(key, value string) { t.writeHeaders[key] = value } // ClearWriteHeaders clears all write headers previously set. func (t *THeaderTransport) ClearWriteHeaders() { t.writeHeaders = make(THeaderMap) } // 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( NOT_IMPLEMENTED, fmt.Errorf("THeaderTransformID %d not supported", transform), ) } t.writeTransforms = append(t.writeTransforms, transform) return nil } // Protocol returns the wrapped protocol id used in this THeaderTransport. func (t *THeaderTransport) Protocol() THeaderProtocolID { switch t.clientType { default: return t.protocolID case clientFramedBinary, clientUnframedBinary: return THeaderProtocolBinary case clientFramedCompact, clientUnframedCompact: return THeaderProtocolCompact } } func (t *THeaderTransport) isFramed() bool { switch t.clientType { default: return false case clientHeaders, clientFramedBinary, clientFramedCompact: return true } } // addWriteTransformsDedupe adds id to writeTransforms only if it's not already // there. func (t *THeaderTransport) addWriteTransformsDedupe(id THeaderTransformID) { if slices.Contains(t.writeTransforms, id) { return } t.writeTransforms = append(t.writeTransforms, id) } // SetTConfiguration implements TConfigurationSetter. func (t *THeaderTransport) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(t.transport, cfg) t.cfg = cfg } // THeaderTransportFactory is a TTransportFactory implementation to create // THeaderTransport. // // It also implements TConfigurationSetter. type THeaderTransportFactory struct { // The underlying factory, could be nil. Factory TTransportFactory cfg *TConfiguration } // Deprecated: Use NewTHeaderTransportFactoryConf instead. func NewTHeaderTransportFactory(factory TTransportFactory) TTransportFactory { return NewTHeaderTransportFactoryConf(factory, &TConfiguration{ noPropagation: true, }) } // NewTHeaderTransportFactoryConf creates a new *THeaderTransportFactory with // the given *TConfiguration. func NewTHeaderTransportFactoryConf(factory TTransportFactory, conf *TConfiguration) TTransportFactory { return &THeaderTransportFactory{ Factory: factory, cfg: conf, } } // GetTransport implements TTransportFactory. func (f *THeaderTransportFactory) GetTransport(trans TTransport) (TTransport, error) { if f.Factory != nil { t, err := f.Factory.GetTransport(trans) if err != nil { return nil, err } return NewTHeaderTransportConf(t, f.cfg), nil } return NewTHeaderTransportConf(trans, f.cfg), nil } // SetTConfiguration implements TConfigurationSetter. func (f *THeaderTransportFactory) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(f.Factory, f.cfg) f.cfg = cfg } var ( _ TConfigurationSetter = (*THeaderTransportFactory)(nil) _ TConfigurationSetter = (*THeaderTransport)(nil) ) thrift-0.23.0/lib/go/thrift/header_protocol_test.go0000664000175000017500000000333415165535636022612 0ustar00buildbuild00000000000000/* * 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 ( "testing" ) func TestReadWriteHeaderProtocol(t *testing.T) { t.Run( "default", func(t *testing.T) { ReadWriteProtocolTest(t, NewTHeaderProtocolFactory()) }, ) t.Run( "compact", func(t *testing.T) { ReadWriteProtocolTest(t, NewTHeaderProtocolFactoryConf(&TConfiguration{ THeaderProtocolID: THeaderProtocolIDPtrMust(THeaderProtocolCompact), })) }, ) 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}, })) }, ) } thrift-0.23.0/lib/go/thrift/ssl_socket.go0000664000175000017500000001567615165535636020567 0ustar00buildbuild00000000000000/* * 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 ( "context" "crypto/tls" "net" "time" ) type TSSLSocket struct { conn *socketConn // hostPort contains host:port (e.g. "asdf.com:12345"). The field is // only valid if addr is nil. hostPort string // addr is nil when hostPort is not "", and is only used when the // TSSLSocket is constructed from a net.Addr. addr net.Addr cfg *TConfiguration } // NewTSSLSocketConf creates a net.Conn-backed TTransport, given a host and port. // // Example: // // trans := thrift.NewTSSLSocketConf("localhost:9090", &TConfiguration{ // ConnectTimeout: time.Second, // Use 0 for no timeout // SocketTimeout: time.Second, // Use 0 for no timeout // // TLSConfig: &tls.Config{ // // Fill in tls config here. // } // }) func NewTSSLSocketConf(hostPort string, conf *TConfiguration) *TSSLSocket { if cfg := conf.GetTLSConfig(); cfg != nil && cfg.MinVersion == 0 { cfg.MinVersion = tls.VersionTLS10 } return &TSSLSocket{ hostPort: hostPort, cfg: conf, } } // Deprecated: Use NewTSSLSocketConf instead. func NewTSSLSocket(hostPort string, cfg *tls.Config) (*TSSLSocket, error) { return NewTSSLSocketConf(hostPort, &TConfiguration{ TLSConfig: cfg, noPropagation: true, }), nil } // Deprecated: Use NewTSSLSocketConf instead. func NewTSSLSocketTimeout(hostPort string, cfg *tls.Config, connectTimeout, socketTimeout time.Duration) (*TSSLSocket, error) { return NewTSSLSocketConf(hostPort, &TConfiguration{ ConnectTimeout: connectTimeout, SocketTimeout: socketTimeout, TLSConfig: cfg, noPropagation: true, }), nil } // NewTSSLSocketFromAddrConf creates a TSSLSocket from a net.Addr. func NewTSSLSocketFromAddrConf(addr net.Addr, conf *TConfiguration) *TSSLSocket { return &TSSLSocket{ addr: addr, cfg: conf, } } // Deprecated: Use NewTSSLSocketFromAddrConf instead. func NewTSSLSocketFromAddrTimeout(addr net.Addr, cfg *tls.Config, connectTimeout, socketTimeout time.Duration) *TSSLSocket { return NewTSSLSocketFromAddrConf(addr, &TConfiguration{ ConnectTimeout: connectTimeout, SocketTimeout: socketTimeout, TLSConfig: cfg, noPropagation: true, }) } // NewTSSLSocketFromConnConf creates a TSSLSocket from an existing net.Conn. func NewTSSLSocketFromConnConf(conn net.Conn, conf *TConfiguration) *TSSLSocket { return &TSSLSocket{ conn: wrapSocketConn(conn), addr: conn.RemoteAddr(), cfg: conf, } } // Deprecated: Use NewTSSLSocketFromConnConf instead. func NewTSSLSocketFromConnTimeout(conn net.Conn, cfg *tls.Config, socketTimeout time.Duration) *TSSLSocket { return NewTSSLSocketFromConnConf(conn, &TConfiguration{ SocketTimeout: socketTimeout, TLSConfig: cfg, noPropagation: true, }) } // SetTConfiguration implements TConfigurationSetter. // // It can be used to change connect and socket timeouts. func (p *TSSLSocket) SetTConfiguration(conf *TConfiguration) { p.cfg = conf } // Sets the connect timeout func (p *TSSLSocket) SetConnTimeout(timeout time.Duration) error { if p.cfg == nil { p.cfg = &TConfiguration{} } p.cfg.ConnectTimeout = timeout return nil } // Sets the socket timeout func (p *TSSLSocket) SetSocketTimeout(timeout time.Duration) error { if p.cfg == nil { p.cfg = &TConfiguration{} } p.cfg.SocketTimeout = timeout return nil } func (p *TSSLSocket) pushDeadline(read, write bool) { var t time.Time if timeout := p.cfg.GetSocketTimeout(); timeout > 0 { t = time.Now().Add(time.Duration(timeout)) } if read && write { p.conn.SetDeadline(t) } else if read { p.conn.SetReadDeadline(t) } else if write { p.conn.SetWriteDeadline(t) } } // Connects the socket, creating a new socket object if necessary. func (p *TSSLSocket) Open() error { var err error // If we have a hostname, we need to pass the hostname to tls.Dial for // certificate hostname checks. if p.hostPort != "" { if p.conn, err = createSocketConnFromReturn(tls.DialWithDialer( &net.Dialer{ Timeout: p.cfg.GetConnectTimeout(), }, "tcp", p.hostPort, p.cfg.GetTLSConfig(), )); err != nil { return &tTransportException{ typeId: NOT_OPEN, err: err, msg: err.Error(), } } } else { if p.conn.isValid() { return NewTTransportException(ALREADY_OPEN, "Socket already connected.") } if p.addr == nil { return NewTTransportException(NOT_OPEN, "Cannot open nil address.") } if len(p.addr.Network()) == 0 { return NewTTransportException(NOT_OPEN, "Cannot open bad network name.") } if len(p.addr.String()) == 0 { return NewTTransportException(NOT_OPEN, "Cannot open bad address.") } if p.conn, err = createSocketConnFromReturn(tls.DialWithDialer( &net.Dialer{ Timeout: p.cfg.GetConnectTimeout(), }, p.addr.Network(), p.addr.String(), p.cfg.GetTLSConfig(), )); err != nil { return &tTransportException{ typeId: NOT_OPEN, err: err, msg: err.Error(), } } } return nil } // Retrieve the underlying net.Conn func (p *TSSLSocket) Conn() net.Conn { return p.conn } // Returns true if the connection is open func (p *TSSLSocket) IsOpen() bool { return p.conn.IsOpen() } // Closes the socket. func (p *TSSLSocket) Close() error { return p.conn.Close() } func (p *TSSLSocket) Read(buf []byte) (int, error) { if !p.conn.isValid() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(true, false) // NOTE: Calling any of p.IsOpen, p.conn.read0, or p.conn.IsOpen between // p.pushDeadline and p.conn.Read could cause the deadline set inside // p.pushDeadline being reset, thus need to be avoided. n, err := p.conn.Read(buf) return n, NewTTransportExceptionFromError(err) } func (p *TSSLSocket) Write(buf []byte) (int, error) { if !p.conn.isValid() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(false, true) return p.conn.Write(buf) } func (p *TSSLSocket) Flush(ctx context.Context) error { return nil } func (p *TSSLSocket) Interrupt() error { if !p.conn.isValid() { return nil } return p.conn.Close() } func (p *TSSLSocket) RemainingBytes() (num_bytes uint64) { const maxSize = ^uint64(0) return maxSize // the truth is, we just don't know unless framed is used } var _ TConfigurationSetter = (*TSSLSocket)(nil) thrift-0.23.0/lib/go/thrift/socket.go0000664000175000017500000001414615165535636017675 0ustar00buildbuild00000000000000/* * 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 ( "context" "net" "time" ) type TSocket struct { conn *socketConn addr net.Addr cfg *TConfiguration } // tcpAddr is a naive implementation of net.Addr that does nothing extra. type tcpAddr string var _ net.Addr = tcpAddr("") func (ta tcpAddr) Network() string { return "tcp" } func (ta tcpAddr) String() string { return string(ta) } // Deprecated: Use NewTSocketConf instead. func NewTSocket(hostPort string) (*TSocket, error) { return NewTSocketConf(hostPort, &TConfiguration{ noPropagation: true, }), nil } // NewTSocketConf creates a net.Conn-backed TTransport, given a host and port. // // Example: // // trans := thrift.NewTSocketConf("localhost:9090", &TConfiguration{ // ConnectTimeout: time.Second, // Use 0 for no timeout // SocketTimeout: time.Second, // Use 0 for no timeout // }) func NewTSocketConf(hostPort string, conf *TConfiguration) *TSocket { return NewTSocketFromAddrConf(tcpAddr(hostPort), conf) } // Deprecated: Use NewTSocketConf instead. func NewTSocketTimeout(hostPort string, connTimeout time.Duration, soTimeout time.Duration) (*TSocket, error) { return NewTSocketConf(hostPort, &TConfiguration{ ConnectTimeout: connTimeout, SocketTimeout: soTimeout, noPropagation: true, }), nil } // NewTSocketFromAddrConf creates a TSocket from a net.Addr func NewTSocketFromAddrConf(addr net.Addr, conf *TConfiguration) *TSocket { return &TSocket{ addr: addr, cfg: conf, } } // Deprecated: Use NewTSocketFromAddrConf instead. func NewTSocketFromAddrTimeout(addr net.Addr, connTimeout time.Duration, soTimeout time.Duration) *TSocket { return NewTSocketFromAddrConf(addr, &TConfiguration{ ConnectTimeout: connTimeout, SocketTimeout: soTimeout, noPropagation: true, }) } // NewTSocketFromConnConf creates a TSocket from an existing net.Conn. func NewTSocketFromConnConf(conn net.Conn, conf *TConfiguration) *TSocket { return &TSocket{ conn: wrapSocketConn(conn), addr: conn.RemoteAddr(), cfg: conf, } } // Deprecated: Use NewTSocketFromConnConf instead. func NewTSocketFromConnTimeout(conn net.Conn, socketTimeout time.Duration) *TSocket { return NewTSocketFromConnConf(conn, &TConfiguration{ SocketTimeout: socketTimeout, noPropagation: true, }) } // SetTConfiguration implements TConfigurationSetter. // // It can be used to set connect and socket timeouts. func (p *TSocket) SetTConfiguration(conf *TConfiguration) { p.cfg = conf } // Sets the connect timeout func (p *TSocket) SetConnTimeout(timeout time.Duration) error { if p.cfg == nil { p.cfg = &TConfiguration{ noPropagation: true, } } p.cfg.ConnectTimeout = timeout return nil } // Sets the socket timeout func (p *TSocket) SetSocketTimeout(timeout time.Duration) error { if p.cfg == nil { p.cfg = &TConfiguration{ noPropagation: true, } } p.cfg.SocketTimeout = timeout return nil } func (p *TSocket) pushDeadline(read, write bool) { var t time.Time if timeout := p.cfg.GetSocketTimeout(); timeout > 0 { t = time.Now().Add(time.Duration(timeout)) } if read && write { p.conn.SetDeadline(t) } else if read { p.conn.SetReadDeadline(t) } else if write { p.conn.SetWriteDeadline(t) } } // Connects the socket, creating a new socket object if necessary. func (p *TSocket) Open() error { if p.conn.isValid() { return NewTTransportException(ALREADY_OPEN, "Socket already connected.") } if p.addr == nil { return NewTTransportException(NOT_OPEN, "Cannot open nil address.") } if len(p.addr.Network()) == 0 { return NewTTransportException(NOT_OPEN, "Cannot open bad network name.") } if len(p.addr.String()) == 0 { return NewTTransportException(NOT_OPEN, "Cannot open bad address.") } var err error if p.conn, err = createSocketConnFromReturn(net.DialTimeout( p.addr.Network(), p.addr.String(), p.cfg.GetConnectTimeout(), )); err != nil { return &tTransportException{ typeId: NOT_OPEN, err: err, msg: err.Error(), } } p.addr = p.conn.RemoteAddr() return nil } // Retrieve the underlying net.Conn func (p *TSocket) Conn() net.Conn { return p.conn } // Returns true if the connection is open func (p *TSocket) IsOpen() bool { return p.conn.IsOpen() } // Closes the socket. func (p *TSocket) Close() error { return p.conn.Close() } //Returns the remote address of the socket. func (p *TSocket) Addr() net.Addr { return p.addr } func (p *TSocket) Read(buf []byte) (int, error) { if !p.conn.isValid() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(true, false) // NOTE: Calling any of p.IsOpen, p.conn.read0, or p.conn.IsOpen between // p.pushDeadline and p.conn.Read could cause the deadline set inside // p.pushDeadline being reset, thus need to be avoided. n, err := p.conn.Read(buf) return n, NewTTransportExceptionFromError(err) } func (p *TSocket) Write(buf []byte) (int, error) { if !p.conn.isValid() { return 0, NewTTransportException(NOT_OPEN, "Connection not open") } p.pushDeadline(false, true) return p.conn.Write(buf) } func (p *TSocket) Flush(ctx context.Context) error { return nil } func (p *TSocket) Interrupt() error { if !p.conn.isValid() { return nil } return p.conn.Close() } func (p *TSocket) RemainingBytes() (num_bytes uint64) { const maxSize = ^uint64(0) return maxSize // the truth is, we just don't know unless framed is used } var _ TConfigurationSetter = (*TSocket)(nil) thrift-0.23.0/lib/go/thrift/iostream_transport.go0000664000175000017500000001314015165535636022335 0ustar00buildbuild00000000000000/* * 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 ( "bufio" "context" "io" ) // StreamTransport is a Transport made of an io.Reader and/or an io.Writer type StreamTransport struct { io.Reader io.Writer isReadWriter bool closed bool } type StreamTransportFactory struct { Reader io.Reader Writer io.Writer isReadWriter bool } func (p *StreamTransportFactory) GetTransport(trans TTransport) (TTransport, error) { if trans != nil { t, ok := trans.(*StreamTransport) if ok { if t.isReadWriter { return NewStreamTransportRW(t.Reader.(io.ReadWriter)), nil } if t.Reader != nil && t.Writer != nil { return NewStreamTransport(t.Reader, t.Writer), nil } if t.Reader != nil && t.Writer == nil { return NewStreamTransportR(t.Reader), nil } if t.Reader == nil && t.Writer != nil { return NewStreamTransportW(t.Writer), nil } return &StreamTransport{}, nil } } if p.isReadWriter { return NewStreamTransportRW(p.Reader.(io.ReadWriter)), nil } if p.Reader != nil && p.Writer != nil { return NewStreamTransport(p.Reader, p.Writer), nil } if p.Reader != nil && p.Writer == nil { return NewStreamTransportR(p.Reader), nil } if p.Reader == nil && p.Writer != nil { return NewStreamTransportW(p.Writer), nil } return &StreamTransport{}, nil } func NewStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *StreamTransportFactory { return &StreamTransportFactory{Reader: reader, Writer: writer, isReadWriter: isReadWriter} } func NewStreamTransport(r io.Reader, w io.Writer) *StreamTransport { return &StreamTransport{Reader: bufio.NewReader(r), Writer: bufio.NewWriter(w)} } func NewStreamTransportR(r io.Reader) *StreamTransport { return &StreamTransport{Reader: bufio.NewReader(r)} } func NewStreamTransportW(w io.Writer) *StreamTransport { return &StreamTransport{Writer: bufio.NewWriter(w)} } func NewStreamTransportRW(rw io.ReadWriter) *StreamTransport { bufrw := bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw)) return &StreamTransport{Reader: bufrw, Writer: bufrw, isReadWriter: true} } func (p *StreamTransport) IsOpen() bool { return !p.closed } // implicitly opened on creation, can't be reopened once closed func (p *StreamTransport) Open() error { if !p.closed { return NewTTransportException(ALREADY_OPEN, "StreamTransport already open.") } else { return NewTTransportException(NOT_OPEN, "cannot reopen StreamTransport.") } } // Closes both the input and output streams. func (p *StreamTransport) Close() error { if p.closed { return NewTTransportException(NOT_OPEN, "StreamTransport already closed.") } p.closed = true closedReader := false if p.Reader != nil { c, ok := p.Reader.(io.Closer) if ok { e := c.Close() closedReader = true if e != nil { return e } } p.Reader = nil } if p.Writer != nil && (!closedReader || !p.isReadWriter) { c, ok := p.Writer.(io.Closer) if ok { e := c.Close() if e != nil { return e } } p.Writer = nil } return nil } // Flushes the underlying output stream if not null. func (p *StreamTransport) Flush(ctx context.Context) error { if p.Writer == nil { return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream") } f, ok := p.Writer.(Flusher) if ok { err := f.Flush() if err != nil { return NewTTransportExceptionFromError(err) } } return nil } func (p *StreamTransport) Read(c []byte) (n int, err error) { n, err = p.Reader.Read(c) if err != nil { err = NewTTransportExceptionFromError(err) } return } func (p *StreamTransport) ReadByte() (c byte, err error) { f, ok := p.Reader.(io.ByteReader) if ok { c, err = f.ReadByte() } else { c, err = readByte(p.Reader) } if err != nil { err = NewTTransportExceptionFromError(err) } return } func (p *StreamTransport) Write(c []byte) (n int, err error) { n, err = p.Writer.Write(c) if err != nil { err = NewTTransportExceptionFromError(err) } return } func (p *StreamTransport) WriteByte(c byte) (err error) { f, ok := p.Writer.(io.ByteWriter) if ok { err = f.WriteByte(c) } else { err = writeByte(p.Writer, c) } if err != nil { err = NewTTransportExceptionFromError(err) } return } func (p *StreamTransport) WriteString(s string) (n int, err error) { f, ok := p.Writer.(stringWriter) if ok { n, err = f.WriteString(s) } else { n, err = p.Writer.Write([]byte(s)) } if err != nil { err = NewTTransportExceptionFromError(err) } return } func (p *StreamTransport) RemainingBytes() (num_bytes uint64) { const maxSize = ^uint64(0) return maxSize // the truth is, we just don't know unless framed is used } // SetTConfiguration implements TConfigurationSetter for propagation. func (p *StreamTransport) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(p.Reader, conf) PropagateTConfiguration(p.Writer, conf) } var _ TConfigurationSetter = (*StreamTransport)(nil) thrift-0.23.0/lib/go/thrift/server_test.go0000664000175000017500000000156015165535636020746 0ustar00buildbuild00000000000000/* * 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 ( "testing" ) func TestNothing(t *testing.T) { } thrift-0.23.0/lib/go/thrift/multiplexed_protocol_test.go0000664000175000017500000000273615165535636023723 0ustar00buildbuild00000000000000package thrift import ( "context" "strings" "testing" ) func TestMultiplexedProcessorMap(t *testing.T) { name := "test" processorName := "foo" processor := &TMultiplexedProcessor{} processor.RegisterDefault(&mockWrappableProcessor{ ProcessorFuncs: map[string]TProcessorFunction{ name: WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { return true, nil }, }, }, }) processor.RegisterProcessor(processorName, &mockWrappableProcessor{ ProcessorFuncs: map[string]TProcessorFunction{ name: WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { return true, nil }, }, }, }) processorMap := processor.ProcessorMap() if len(processorMap) != 2 { t.Fatalf("Wrong processor map size %#v", processorMap) } for k := range processorMap { components := strings.SplitN(k, MULTIPLEXED_SEPARATOR, 2) if len(components) == 1 { if components[0] != name { t.Fatalf("Wrong name for default processor func, expected %q, got %q", name, components[0]) } } else if len(components) == 2 { if components[0] != processorName { t.Errorf("Wrong processor name, expected %q, got %q", processorName, components[0]) } if components[1] != name { t.Errorf("Wrong name for processor func, expected %q, got %q", name, components[1]) } } else { t.Fatalf("Wrong number of components %#v", components) } } } thrift-0.23.0/lib/go/thrift/http_transport.go0000664000175000017500000000407515165535636021500 0ustar00buildbuild00000000000000/* * 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 ( "compress/gzip" "io" "net/http" "strings" ) // NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function func NewThriftHandlerFunc(processor TProcessor, inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { return gz(func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/x-thrift") transport := NewStreamTransport(r.Body, w) processor.Process(r.Context(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) }) } // gz transparently compresses the HTTP response if the client supports it. func gz(handler http.HandlerFunc) http.HandlerFunc { sp := newPool(func() *gzip.Writer { return gzip.NewWriter(nil) }, nil) return func(w http.ResponseWriter, r *http.Request) { if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { handler(w, r) return } w.Header().Set("Content-Encoding", "gzip") gz := sp.get() gz.Reset(w) defer func() { gz.Close() sp.put(&gz) }() gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w} handler(gzw, r) } } type gzipResponseWriter struct { io.Writer http.ResponseWriter } func (w gzipResponseWriter) Write(b []byte) (int, error) { return w.Writer.Write(b) } thrift-0.23.0/lib/go/thrift/uuid_test.go0000664000175000017500000001341415165535636020407 0ustar00buildbuild00000000000000/* * 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 ( "fmt" "testing" "testing/quick" ) func TestHexToByte(t *testing.T) { for _, c := range []struct { s string b byte fail bool }{ { s: "ff", b: 0xff, }, { s: "FF", b: 0xff, }, { s: "00", b: 0, }, { s: "77", b: 0x77, }, { s: "aC", b: 0xac, }, { s: "xx", fail: true, }, { s: "x0", fail: true, }, { s: "fx", fail: true, }, } { t.Run(c.s, func(t *testing.T) { b, ok := hexToByte(c.s[0], c.s[1]) if ok != !c.fail { t.Errorf("Want failure, got %x, %v", b, ok) } if !c.fail && b != c.b { t.Errorf("Want %x, got %x", c.b, b) } }) } } func TestUUIDString(t *testing.T) { for _, c := range []struct { uuid Tuuid want string }{ { uuid: Tuuid{}, want: "00000000-0000-0000-0000-000000000000", }, { uuid: Tuuid{ 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, }, want: "6ba7b810-9dad-11d1-80b4-00c04fd430c8", }, { uuid: Tuuid{ 0x6b, 0xa7, 0xB8, 0x11, 0x9d, 0xAd, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, }, want: "6ba7b811-9dad-11d1-80b4-00c04fd430c8", }, { uuid: Tuuid{ 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, }, want: "6ba7b812-9dad-11d1-80b4-00c04fd430c8", }, { uuid: Tuuid{ 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, }, want: "6ba7b814-9dad-11d1-80b4-00c04fd430c8", }, } { t.Run(fmt.Sprintf("% 02x", c.uuid[:]), func(t *testing.T) { got := c.uuid.String() if got != c.want { t.Errorf("got %q, want %q", got, c.want) } }) } } func TestUUIDParse(t *testing.T) { for _, c := range []struct { uuid string want Tuuid err bool }{ { uuid: "00000000-0000-0000-0000-000000000000", want: Tuuid{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, { uuid: "6BA7B810-9DAD-11D1-80B4-00C04FD430C8", want: Tuuid{ 0x6B, 0xA7, 0xB8, 0x10, 0x9D, 0xAD, 0x11, 0xD1, 0x80, 0xB4, 0x00, 0xC0, 0x4F, 0xD4, 0x30, 0xC8, }, }, { uuid: "6ba7B811-9dAd-11d1-80b4-00c04fd430c8", want: Tuuid{ 0x6b, 0xa7, 0xB8, 0x11, 0x9d, 0xAd, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, }, }, { uuid: "6ba7b812-9dad-11d1-80b4-00c04fd430c8", want: Tuuid{ 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, }, }, { uuid: "6ba7b814-9dad-11d1-80b4-00c04fd430c8", want: Tuuid{ 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, }, }, { uuid: "00000000000000000000000000000000", err: true, // not in canonical form }, { uuid: "6ba7b810-9d-ad11d1-80b4-00c04fd430c8", err: true, // wrong position of hyphens }, { uuid: "urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8", err: true, // urn form is not supported }, { uuid: "{6ba7b812-9dad-11d1-80b4-00c04fd430c8}", err: true, // guid with braces form is not supported }, { uuid: "6xa7b814-9dad-11d1-80b4-00c04fd430c8", err: true, // non-hex numbers }, } { t.Run(c.uuid, func(t *testing.T) { uuid, err := ParseTuuid(c.uuid) if c.err { if err == nil { t.Errorf("Got %v, want error", uuid) } } else { if err != nil { t.Errorf("Failed to parse: %v", err) } if uuid != c.want { t.Errorf("Got %v, want %v", uuid, c.want) } } }) } } func TestUUIDQuick(t *testing.T) { f := func(u Tuuid) bool { s := u.String() parsed, err := ParseTuuid(s) if err != nil { t.Error(err) } if parsed != u { t.Errorf("Parsed %v want %v", parsed, u) } return !t.Failed() } if err := quick.Check(f, nil); err != nil { t.Error(err) } } func BenchmarkUUIDParse(b *testing.B) { for _, s := range []string{ "00000000-0000-0000-0000-000000000000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "6ba7b811-9dad-11d1-80b4-00c04fd430c8", "6ba7b812-9dad-11d1-80b4-00c04fd430c8", "6ba7b814-9dad-11d1-80b4-00c04fd430c8", } { b.Run(s, func(b *testing.B) { b.ReportAllocs() if _, err := ParseTuuid(s); err != nil { b.Fatalf("Unable to parse %q: %v", s, err) } b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { ParseTuuid(s) } }) }) } } func BenchmarkUUIDString(b *testing.B) { for _, u := range []Tuuid{ {}, Must(ParseTuuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8")), Must(ParseTuuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8")), Must(ParseTuuid("6ba7b812-9dad-11d1-80b4-00c04fd430c8")), Must(ParseTuuid("6ba7b814-9dad-11d1-80b4-00c04fd430c8")), } { b.Run(u.String(), func(b *testing.B) { b.ReportAllocs() b.RunParallel(func(pb *testing.PB) { for pb.Next() { _ = u.String() } }) }) } } thrift-0.23.0/lib/go/thrift/zlib_transport.go0000664000175000017500000000753615165535636021466 0ustar00buildbuild00000000000000/* * 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 ( "compress/zlib" "context" "io" ) // TZlibTransportFactory is a factory for TZlibTransport instances type TZlibTransportFactory struct { level int factory TTransportFactory } // TZlibTransport is a TTransport implementation that makes use of zlib compression. type TZlibTransport struct { reader io.ReadCloser transport TTransport writer *zlib.Writer writeCloser io.Closer } // GetTransport constructs a new instance of NewTZlibTransport func (p *TZlibTransportFactory) GetTransport(trans TTransport) (TTransport, error) { if p.factory != nil { // wrap other factory var err error trans, err = p.factory.GetTransport(trans) if err != nil { return nil, err } } return NewTZlibTransport(trans, p.level) } // NewTZlibTransportFactory constructs a new instance of NewTZlibTransportFactory func NewTZlibTransportFactory(level int) *TZlibTransportFactory { return &TZlibTransportFactory{level: level, factory: nil} } // NewTZlibTransportFactoryWithFactory constructs a new instance of TZlibTransportFactory // as a wrapper over existing transport factory func NewTZlibTransportFactoryWithFactory(level int, factory TTransportFactory) *TZlibTransportFactory { return &TZlibTransportFactory{level: level, factory: factory} } // NewTZlibTransport constructs a new instance of TZlibTransport func NewTZlibTransport(trans TTransport, level int) (*TZlibTransport, error) { writer, closer, err := newZlibWriterCloserLevel(trans, level) if err != nil { return nil, err } return &TZlibTransport{ writer: writer, writeCloser: closer, transport: trans, }, nil } // Close closes the reader and writer (flushing any unwritten data) and closes // the underlying transport. func (z *TZlibTransport) Close() error { if z.reader != nil { if err := z.reader.Close(); err != nil { return err } } if err := z.writeCloser.Close(); err != nil { return err } return z.transport.Close() } // Flush flushes the writer and its underlying transport. func (z *TZlibTransport) Flush(ctx context.Context) error { if err := z.writer.Flush(); err != nil { return err } return z.transport.Flush(ctx) } // IsOpen returns true if the transport is open func (z *TZlibTransport) IsOpen() bool { return z.transport.IsOpen() } // Open opens the transport for communication func (z *TZlibTransport) Open() error { return z.transport.Open() } func (z *TZlibTransport) Read(p []byte) (int, error) { if z.reader == nil { r, err := newZlibReader(z.transport) if err != nil { return 0, NewTTransportExceptionFromError(err) } z.reader = r } return z.reader.Read(p) } // RemainingBytes returns the size in bytes of the data that is still to be // read. func (z *TZlibTransport) RemainingBytes() uint64 { return z.transport.RemainingBytes() } func (z *TZlibTransport) Write(p []byte) (int, error) { return z.writer.Write(p) } // SetTConfiguration implements TConfigurationSetter for propagation. func (z *TZlibTransport) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(z.transport, conf) } var _ TConfigurationSetter = (*TZlibTransport)(nil) thrift-0.23.0/lib/go/thrift/json_protocol_test.go0000664000175000017500000005374515167543515022343 0ustar00buildbuild00000000000000/* * 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 ( "context" "encoding/base64" "encoding/json" "fmt" "math" "strconv" "testing" ) func TestWriteJSONProtocolBool(t *testing.T) { thetype := "boolean" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) for _, value := range BOOL_VALUES { if e := p.WriteBool(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() expected := "" if value { expected = "1" } else { expected = "0" } if s != expected { t.Fatalf("Bad value for %s %v: %s expected", thetype, value, s) } v := -1 if err := json.Unmarshal([]byte(s), &v); err != nil || (v != 0) != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadJSONProtocolBool(t *testing.T) { thetype := "boolean" for _, value := range BOOL_VALUES { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) if value { trans.Write([]byte{'1'}) // not JSON_TRUE } else { trans.Write([]byte{'0'}) // not JSON_FALSE } trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBool(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } vv := -1 if err := json.Unmarshal([]byte(s), &vv); err != nil || (vv != 0) != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, vv) } trans.Reset() trans.Close() } } func TestWriteJSONProtocolByte(t *testing.T) { thetype := "byte" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) for _, value := range BYTE_VALUES { if e := p.WriteByte(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int8(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadJSONProtocolByte(t *testing.T) { thetype := "byte" for _, value := range BYTE_VALUES { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadByte(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestWriteJSONProtocolI16(t *testing.T) { thetype := "int16" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) for _, value := range INT16_VALUES { if e := p.WriteI16(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int16(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadJSONProtocolI16(t *testing.T) { thetype := "int16" for _, value := range INT16_VALUES { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI16(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestWriteJSONProtocolI32(t *testing.T) { thetype := "int32" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) for _, value := range INT32_VALUES { if e := p.WriteI32(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int32(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadJSONProtocolI32(t *testing.T) { thetype := "int32" for _, value := range INT32_VALUES { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI32(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestWriteJSONProtocolI64(t *testing.T) { thetype := "int64" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) for _, value := range INT64_VALUES { if e := p.WriteI64(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int64(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadJSONProtocolI64(t *testing.T) { thetype := "int64" for _, value := range INT64_VALUES { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.FormatInt(value, 10)) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI64(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestWriteJSONProtocolDouble(t *testing.T) { thetype := "double" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) for _, value := range DOUBLE_VALUES { if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if math.IsInf(value, 1) { if s != jsonQuote(JSON_INFINITY) { t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, jsonQuote(JSON_INFINITY)) } } else if math.IsInf(value, -1) { if s != jsonQuote(JSON_NEGATIVE_INFINITY) { t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, jsonQuote(JSON_NEGATIVE_INFINITY)) } } else if math.IsNaN(value) { if s != jsonQuote(JSON_NAN) { t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, jsonQuote(JSON_NAN)) } } else { if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := float64(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } } trans.Reset() } trans.Close() } func TestReadJSONProtocolDouble(t *testing.T) { thetype := "double" for _, value := range DOUBLE_VALUES { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) n := NewNumericFromDouble(value) trans.WriteString(n.String()) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadDouble(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if math.IsInf(value, 1) { if !math.IsInf(v, 1) { t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v) } } else if math.IsInf(value, -1) { if !math.IsInf(v, -1) { t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v) } } else if math.IsNaN(value) { if !math.IsNaN(v) { t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v) } } else { if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } } trans.Reset() trans.Close() } } func TestWriteJSONProtocolString(t *testing.T) { thetype := "string" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) for _, value := range STRING_VALUES { if e := p.WriteString(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s[0] != '"' || s[len(s)-1] != '"' { t.Fatalf("Bad value for %s '%v', wrote '%v', expected: %v", thetype, value, s, fmt.Sprint("\"", value, "\"")) } v := new(string) if err := json.Unmarshal([]byte(s), v); err != nil || *v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v) } trans.Reset() } trans.Close() } func TestReadJSONProtocolString(t *testing.T) { thetype := "string" for _, value := range STRING_VALUES { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(jsonQuote(value)) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadString(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } v1 := new(string) if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1) } trans.Reset() trans.Close() } } func TestWriteJSONProtocolBinary(t *testing.T) { thetype := "binary" value := protocol_bdata b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata))) base64.StdEncoding.Encode(b64value, value) b64String := string(b64value) trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) if e := p.WriteBinary(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() expectedString := fmt.Sprint("\"", b64String, "\"") if s != expectedString { t.Fatalf("Bad value for %s %v\n wrote: \"%v\"\nexpected: \"%v\"", thetype, value, s, expectedString) } v1, err := p.ReadBinary(context.Background()) if err != nil { t.Fatalf("Unable to read binary: %s", err.Error()) } if len(v1) != len(value) { t.Fatalf("Invalid value for binary\nexpected: \"%v\"\n read: \"%v\"", value, v1) } for k, v := range value { if v1[k] != v { t.Fatalf("Invalid value for binary at %v\nexpected: \"%v\"\n read: \"%v\"", k, v, v1[k]) } } trans.Close() } func TestReadJSONProtocolBinary(t *testing.T) { thetype := "binary" value := protocol_bdata b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata))) base64.StdEncoding.Encode(b64value, value) b64String := string(b64value) trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(jsonQuote(b64String)) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBinary(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } 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 := 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]) } } v1 := new(string) if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1) } trans.Reset() trans.Close() } func TestWriteJSONProtocolList(t *testing.T) { thetype := "list" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) p.WriteListBegin(context.Background(), TType(DOUBLE), len(DOUBLE_VALUES)) for _, value := range DOUBLE_VALUES { if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } } p.WriteListEnd(context.Background()) if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() str1 := new([]any) err := json.Unmarshal([]byte(str), str1) if err != nil { t.Fatalf("Unable to decode %s, wrote: %s", thetype, str) } l := *str1 if len(l) < 2 { t.Fatalf("List must be at least of length two to include metadata") } if l[0] != "dbl" { t.Fatal("Invalid type for list, expected: ", STRING, ", but was: ", l[0]) } if int(l[1].(float64)) != len(DOUBLE_VALUES) { t.Fatal("Invalid length for list, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1]) } for k, value := range DOUBLE_VALUES { s := l[k+2] if math.IsInf(value, 1) { if s.(string) != JSON_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_INFINITY), str) } } else if math.IsInf(value, 0) { if s.(string) != JSON_NEGATIVE_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NEGATIVE_INFINITY), str) } } else if math.IsNaN(value) { if s.(string) != JSON_NAN { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NAN), str) } } else { if s.(float64) != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s) } } trans.Reset() } trans.Close() } func TestWriteJSONProtocolSet(t *testing.T) { thetype := "set" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) p.WriteSetBegin(context.Background(), TType(DOUBLE), len(DOUBLE_VALUES)) for _, value := range DOUBLE_VALUES { if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } } p.WriteSetEnd(context.Background()) if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() str1 := new([]any) err := json.Unmarshal([]byte(str), str1) if err != nil { t.Fatalf("Unable to decode %s, wrote: %s", thetype, str) } l := *str1 if len(l) < 2 { t.Fatalf("Set must be at least of length two to include metadata") } if l[0] != "dbl" { t.Fatal("Invalid type for set, expected: ", DOUBLE, ", but was: ", l[0]) } if int(l[1].(float64)) != len(DOUBLE_VALUES) { t.Fatal("Invalid length for set, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1]) } for k, value := range DOUBLE_VALUES { s := l[k+2] if math.IsInf(value, 1) { if s.(string) != JSON_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_INFINITY), str) } } else if math.IsInf(value, 0) { if s.(string) != JSON_NEGATIVE_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NEGATIVE_INFINITY), str) } } else if math.IsNaN(value) { if s.(string) != JSON_NAN { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NAN), str) } } else { if s.(float64) != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s) } } trans.Reset() } trans.Close() } func TestWriteJSONProtocolMap(t *testing.T) { thetype := "map" trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) p.WriteMapBegin(context.Background(), TType(I32), TType(DOUBLE), len(DOUBLE_VALUES)) for k, value := range DOUBLE_VALUES { if e := p.WriteI32(context.Background(), int32(k)); e != nil { t.Fatalf("Unable to write %s key int32 value %v due to error: %s", thetype, k, e.Error()) } if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.Error()) } } p.WriteMapEnd(context.Background()) if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() if str[0] != '[' || str[len(str)-1] != ']' { t.Fatalf("Bad value for %s, wrote: %v, in go: %v", thetype, str, DOUBLE_VALUES) } expectedKeyType, expectedValueType, expectedSize, err := p.ReadMapBegin(context.Background()) if err != nil { t.Fatalf("Error while reading map begin: %s", err.Error()) } if expectedKeyType != I32 { t.Fatal("Expected map key type ", I32, ", but was ", expectedKeyType) } if expectedValueType != DOUBLE { t.Fatal("Expected map value type ", DOUBLE, ", but was ", expectedValueType) } if expectedSize != len(DOUBLE_VALUES) { t.Fatal("Expected map size of ", len(DOUBLE_VALUES), ", but was ", expectedSize) } for k, value := range DOUBLE_VALUES { ik, err := p.ReadI32(context.Background()) if err != nil { t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, ik, k, err.Error()) } if int(ik) != k { t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v", thetype, k, ik, k) } dv, err := p.ReadDouble(context.Background()) if err != nil { t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, dv, value, err.Error()) } s := strconv.FormatFloat(dv, 'g', 10, 64) if math.IsInf(value, 1) { if !math.IsInf(dv, 1) { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, jsonQuote(JSON_INFINITY)) } } else if math.IsInf(value, 0) { if !math.IsInf(dv, 0) { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, jsonQuote(JSON_NEGATIVE_INFINITY)) } } else if math.IsNaN(value) { if !math.IsNaN(dv) { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, jsonQuote(JSON_NAN)) } } else { expected := strconv.FormatFloat(value, 'g', 10, 64) if s != expected { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected %v", thetype, k, value, s, expected) } v := float64(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } } } err = p.ReadMapEnd(context.Background()) if err != nil { t.Fatalf("Error while reading map end: %s", err.Error()) } trans.Close() } func TestTJSONProtocolUnmatchedBeginEnd(t *testing.T) { UnmatchedBeginEndProtocolTest(t, NewTJSONProtocolFactory()) } thrift-0.23.0/lib/go/thrift/buffered_transport.go0000664000175000017500000000504015165535636022274 0ustar00buildbuild00000000000000/* * 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 ( "bufio" "context" ) type TBufferedTransportFactory struct { size int } type TBufferedTransport struct { bufio.ReadWriter tp TTransport } func (p *TBufferedTransportFactory) GetTransport(trans TTransport) (TTransport, error) { return NewTBufferedTransport(trans, p.size), nil } func NewTBufferedTransportFactory(bufferSize int) *TBufferedTransportFactory { return &TBufferedTransportFactory{size: bufferSize} } func NewTBufferedTransport(trans TTransport, bufferSize int) *TBufferedTransport { return &TBufferedTransport{ ReadWriter: bufio.ReadWriter{ Reader: bufio.NewReaderSize(trans, bufferSize), Writer: bufio.NewWriterSize(trans, bufferSize), }, tp: trans, } } func (p *TBufferedTransport) IsOpen() bool { return p.tp.IsOpen() } func (p *TBufferedTransport) Open() (err error) { return p.tp.Open() } func (p *TBufferedTransport) Close() (err error) { return p.tp.Close() } func (p *TBufferedTransport) Read(b []byte) (int, error) { n, err := p.ReadWriter.Read(b) if err != nil { p.ReadWriter.Reader.Reset(p.tp) } return n, err } func (p *TBufferedTransport) Write(b []byte) (int, error) { n, err := p.ReadWriter.Write(b) if err != nil { p.ReadWriter.Writer.Reset(p.tp) } return n, err } func (p *TBufferedTransport) Flush(ctx context.Context) error { if err := p.ReadWriter.Flush(); err != nil { p.ReadWriter.Writer.Reset(p.tp) return err } return p.tp.Flush(ctx) } func (p *TBufferedTransport) RemainingBytes() (num_bytes uint64) { return p.tp.RemainingBytes() } // SetTConfiguration implements TConfigurationSetter for propagation. func (p *TBufferedTransport) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(p.tp, conf) } var _ TConfigurationSetter = (*TBufferedTransport)(nil) thrift-0.23.0/lib/go/thrift/simple_json_protocol.go0000664000175000017500000010617115165535636022650 0ustar00buildbuild00000000000000/* * 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 ( "bufio" "bytes" "context" "encoding/base64" "encoding/json" "errors" "fmt" "io" "math" "strconv" "strings" ) type _ParseContext int const ( _CONTEXT_INVALID _ParseContext = iota _CONTEXT_IN_TOPLEVEL // 1 _CONTEXT_IN_LIST_FIRST // 2 _CONTEXT_IN_LIST // 3 _CONTEXT_IN_OBJECT_FIRST // 4 _CONTEXT_IN_OBJECT_NEXT_KEY // 5 _CONTEXT_IN_OBJECT_NEXT_VALUE // 6 ) func (p _ParseContext) String() string { switch p { case _CONTEXT_IN_TOPLEVEL: return "TOPLEVEL" case _CONTEXT_IN_LIST_FIRST: return "LIST-FIRST" case _CONTEXT_IN_LIST: return "LIST" case _CONTEXT_IN_OBJECT_FIRST: return "OBJECT-FIRST" case _CONTEXT_IN_OBJECT_NEXT_KEY: return "OBJECT-NEXT-KEY" case _CONTEXT_IN_OBJECT_NEXT_VALUE: return "OBJECT-NEXT-VALUE" } return "UNKNOWN-PARSE-CONTEXT" } type jsonContextStack []_ParseContext func (s *jsonContextStack) push(v _ParseContext) { *s = append(*s, v) } func (s jsonContextStack) peek() (v _ParseContext, ok bool) { l := len(s) if l <= 0 { return } return s[l-1], true } func (s *jsonContextStack) pop() (v _ParseContext, ok bool) { l := len(*s) if l <= 0 { return } v = (*s)[l-1] *s = (*s)[0 : l-1] return v, true } var errEmptyJSONContextStack = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Unexpected empty json protocol context stack")) // Simple JSON protocol implementation for thrift. // // This protocol produces/consumes a simple output format // suitable for parsing by scripting languages. It should not be // confused with the full-featured TJSONProtocol. type TSimpleJSONProtocol struct { trans TTransport cfg *TConfiguration parseContextStack jsonContextStack dumpContext jsonContextStack writer *bufio.Writer reader *bufio.Reader } // Deprecated: Use NewTSimpleJSONProtocolConf instead.: func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol { return NewTSimpleJSONProtocolConf(t, &TConfiguration{ noPropagation: true, }) } func NewTSimpleJSONProtocolConf(t TTransport, conf *TConfiguration) *TSimpleJSONProtocol { PropagateTConfiguration(t, conf) v := &TSimpleJSONProtocol{ trans: t, cfg: conf, writer: bufio.NewWriter(t), reader: bufio.NewReader(t), } v.resetContextStack() return v } // Factory type TSimpleJSONProtocolFactory struct { cfg *TConfiguration } func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { return NewTSimpleJSONProtocolConf(trans, p.cfg) } // SetTConfiguration implements TConfigurationSetter for propagation. func (p *TSimpleJSONProtocolFactory) SetTConfiguration(conf *TConfiguration) { p.cfg = conf } // Deprecated: Use NewTSimpleJSONProtocolFactoryConf instead. func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory { return &TSimpleJSONProtocolFactory{ cfg: &TConfiguration{ noPropagation: true, }, } } func NewTSimpleJSONProtocolFactoryConf(conf *TConfiguration) *TSimpleJSONProtocolFactory { return &TSimpleJSONProtocolFactory{ cfg: conf, } } var ( JSON_COMMA []byte JSON_COLON []byte JSON_LBRACE []byte JSON_RBRACE []byte JSON_LBRACKET []byte JSON_RBRACKET []byte JSON_QUOTE byte JSON_QUOTE_BYTES []byte JSON_NULL []byte JSON_TRUE []byte JSON_FALSE []byte JSON_INFINITY string JSON_NEGATIVE_INFINITY string JSON_NAN string JSON_INFINITY_BYTES []byte JSON_NEGATIVE_INFINITY_BYTES []byte JSON_NAN_BYTES []byte ) func init() { JSON_COMMA = []byte{','} JSON_COLON = []byte{':'} JSON_LBRACE = []byte{'{'} JSON_RBRACE = []byte{'}'} JSON_LBRACKET = []byte{'['} JSON_RBRACKET = []byte{']'} JSON_QUOTE = '"' JSON_QUOTE_BYTES = []byte{'"'} JSON_NULL = []byte{'n', 'u', 'l', 'l'} JSON_TRUE = []byte{'t', 'r', 'u', 'e'} JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'} JSON_INFINITY = "Infinity" JSON_NEGATIVE_INFINITY = "-Infinity" JSON_NAN = "NaN" JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'} JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'} JSON_NAN_BYTES = []byte{'N', 'a', 'N'} } func jsonQuote(s string) string { b, _ := json.Marshal(s) s1 := string(b) return s1 } func jsonUnquote(s string) (string, bool) { s1 := new(string) err := json.Unmarshal([]byte(s), s1) return *s1, err == nil } func mismatch(expected, actual string) error { return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual) } func (p *TSimpleJSONProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqId int32) error { p.resetContextStack() // THRIFT-3735 if e := p.OutputListBegin(); e != nil { return e } if e := p.WriteString(ctx, name); e != nil { return e } if e := p.WriteByte(ctx, int8(typeId)); e != nil { return e } if e := p.WriteI32(ctx, seqId); e != nil { return e } return nil } func (p *TSimpleJSONProtocol) WriteMessageEnd(ctx context.Context) error { return p.OutputListEnd() } func (p *TSimpleJSONProtocol) WriteStructBegin(ctx context.Context, name string) error { if e := p.OutputObjectBegin(); e != nil { return e } return nil } func (p *TSimpleJSONProtocol) WriteStructEnd(ctx context.Context) error { return p.OutputObjectEnd() } func (p *TSimpleJSONProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { if e := p.WriteString(ctx, name); e != nil { return e } return nil } func (p *TSimpleJSONProtocol) WriteFieldEnd(ctx context.Context) error { return nil } func (p *TSimpleJSONProtocol) WriteFieldStop(ctx context.Context) error { return nil } func (p *TSimpleJSONProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { if e := p.OutputListBegin(); e != nil { return e } if e := p.WriteByte(ctx, int8(keyType)); e != nil { return e } if e := p.WriteByte(ctx, int8(valueType)); e != nil { return e } return p.WriteI32(ctx, int32(size)) } func (p *TSimpleJSONProtocol) WriteMapEnd(ctx context.Context) error { return p.OutputListEnd() } func (p *TSimpleJSONProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { return p.OutputElemListBegin(elemType, size) } func (p *TSimpleJSONProtocol) WriteListEnd(ctx context.Context) error { return p.OutputListEnd() } func (p *TSimpleJSONProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { return p.OutputElemListBegin(elemType, size) } func (p *TSimpleJSONProtocol) WriteSetEnd(ctx context.Context) error { return p.OutputListEnd() } func (p *TSimpleJSONProtocol) WriteBool(ctx context.Context, b bool) error { return p.OutputBool(b) } func (p *TSimpleJSONProtocol) WriteByte(ctx context.Context, b int8) error { return p.WriteI32(ctx, int32(b)) } func (p *TSimpleJSONProtocol) WriteI16(ctx context.Context, v int16) error { return p.WriteI32(ctx, int32(v)) } func (p *TSimpleJSONProtocol) WriteI32(ctx context.Context, v int32) error { return p.OutputI64(int64(v)) } func (p *TSimpleJSONProtocol) WriteI64(ctx context.Context, v int64) error { return p.OutputI64(int64(v)) } func (p *TSimpleJSONProtocol) WriteDouble(ctx context.Context, v float64) error { return p.OutputF64(v) } func (p *TSimpleJSONProtocol) WriteString(ctx context.Context, v string) error { return p.OutputString(v) } func (p *TSimpleJSONProtocol) WriteBinary(ctx context.Context, v []byte) error { // JSON library only takes in a string, // not an arbitrary byte array, to ensure bytes are transmitted // efficiently we must convert this into a valid JSON string // therefore we use base64 encoding to avoid excessive escaping/quoting if e := p.OutputPreValue(); e != nil { return e } if _, e := p.write(JSON_QUOTE_BYTES); e != nil { return NewTProtocolException(e) } writer := base64.NewEncoder(base64.StdEncoding, p.writer) if _, e := writer.Write(v); e != nil { p.writer.Reset(p.trans) // THRIFT-3735 return NewTProtocolException(e) } if e := writer.Close(); e != nil { return NewTProtocolException(e) } if _, e := p.write(JSON_QUOTE_BYTES); e != nil { return NewTProtocolException(e) } return p.OutputPostValue() } func (p *TSimpleJSONProtocol) WriteUUID(ctx context.Context, v Tuuid) error { return p.OutputString(v.String()) } // Reading methods. func (p *TSimpleJSONProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) { p.resetContextStack() // THRIFT-3735 if isNull, err := p.ParseListBegin(); isNull || err != nil { return name, typeId, seqId, err } if name, err = p.ReadString(ctx); err != nil { return name, typeId, seqId, err } bTypeId, err := p.ReadByte(ctx) typeId = TMessageType(bTypeId) if err != nil { return name, typeId, seqId, err } if seqId, err = p.ReadI32(ctx); err != nil { return name, typeId, seqId, err } return name, typeId, seqId, nil } func (p *TSimpleJSONProtocol) ReadMessageEnd(ctx context.Context) error { return p.ParseListEnd() } func (p *TSimpleJSONProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { _, err = p.ParseObjectStart() return "", err } func (p *TSimpleJSONProtocol) ReadStructEnd(ctx context.Context) error { return p.ParseObjectEnd() } func (p *TSimpleJSONProtocol) ReadFieldBegin(ctx context.Context) (string, TType, int16, error) { if err := p.ParsePreValue(); err != nil { return "", STOP, 0, err } b, _ := p.reader.Peek(1) if len(b) > 0 { switch b[0] { case JSON_RBRACE[0]: return "", STOP, 0, nil case JSON_QUOTE: p.reader.ReadByte() name, err := p.ParseStringBody() // simplejson is not meant to be read back into thrift // - see http://wiki.apache.org/thrift/ThriftUsageJava // - use JSON instead if err != nil { return name, STOP, 0, err } return name, STOP, -1, p.ParsePostValue() } e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b)) return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e) } return "", STOP, 0, NewTProtocolException(io.EOF) } func (p *TSimpleJSONProtocol) ReadFieldEnd(ctx context.Context) error { return nil } func (p *TSimpleJSONProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, e error) { if isNull, e := p.ParseListBegin(); isNull || e != nil { return VOID, VOID, 0, e } // read keyType bKeyType, e := p.ReadByte(ctx) keyType = TType(bKeyType) if e != nil { return keyType, valueType, size, e } // read valueType bValueType, e := p.ReadByte(ctx) valueType = TType(bValueType) if e != nil { return keyType, valueType, size, e } // read size iSize, err := p.ReadI64(ctx) if err != nil { return keyType, valueType, 0, err } err = checkSizeForProtocol(int32(size), p.cfg) if err != nil { return keyType, valueType, 0, err } size = int(iSize) return keyType, valueType, size, err } func (p *TSimpleJSONProtocol) ReadMapEnd(ctx context.Context) error { return p.ParseListEnd() } func (p *TSimpleJSONProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, e error) { return p.ParseElemListBegin() } func (p *TSimpleJSONProtocol) ReadListEnd(ctx context.Context) error { return p.ParseListEnd() } func (p *TSimpleJSONProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, e error) { return p.ParseElemListBegin() } func (p *TSimpleJSONProtocol) ReadSetEnd(ctx context.Context) error { return p.ParseListEnd() } func (p *TSimpleJSONProtocol) ReadBool(ctx context.Context) (bool, error) { var value bool if err := p.ParsePreValue(); err != nil { return value, err } f, _ := p.reader.Peek(1) if len(f) > 0 { switch f[0] { case JSON_TRUE[0]: b := make([]byte, len(JSON_TRUE)) _, err := p.reader.Read(b) if err != nil { return false, NewTProtocolException(err) } if string(b) == string(JSON_TRUE) { value = true } else { e := fmt.Errorf("Expected \"true\" but found: %s", string(b)) return value, NewTProtocolExceptionWithType(INVALID_DATA, e) } case JSON_FALSE[0]: b := make([]byte, len(JSON_FALSE)) _, err := p.reader.Read(b) if err != nil { return false, NewTProtocolException(err) } if string(b) == string(JSON_FALSE) { value = false } else { e := fmt.Errorf("Expected \"false\" but found: %s", string(b)) return value, NewTProtocolExceptionWithType(INVALID_DATA, e) } case JSON_NULL[0]: b := make([]byte, len(JSON_NULL)) _, err := p.reader.Read(b) if err != nil { return false, NewTProtocolException(err) } if string(b) == string(JSON_NULL) { value = false } else { e := fmt.Errorf("Expected \"null\" but found: %s", string(b)) return value, NewTProtocolExceptionWithType(INVALID_DATA, e) } default: e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(f)) return value, NewTProtocolExceptionWithType(INVALID_DATA, e) } } return value, p.ParsePostValue() } func (p *TSimpleJSONProtocol) ReadByte(ctx context.Context) (int8, error) { v, err := p.ReadI64(ctx) return int8(v), err } func (p *TSimpleJSONProtocol) ReadI16(ctx context.Context) (int16, error) { v, err := p.ReadI64(ctx) return int16(v), err } func (p *TSimpleJSONProtocol) ReadI32(ctx context.Context) (int32, error) { v, err := p.ReadI64(ctx) return int32(v), err } func (p *TSimpleJSONProtocol) ReadI64(ctx context.Context) (int64, error) { v, _, err := p.ParseI64() return v, err } func (p *TSimpleJSONProtocol) ReadDouble(ctx context.Context) (float64, error) { v, _, err := p.ParseF64() return v, err } func (p *TSimpleJSONProtocol) ReadString(ctx context.Context) (string, error) { var v string if err := p.ParsePreValue(); err != nil { return v, err } f, _ := p.reader.Peek(1) if len(f) > 0 && f[0] == JSON_QUOTE { p.reader.ReadByte() value, err := p.ParseStringBody() v = value if err != nil { return v, err } } else if len(f) > 0 && f[0] == JSON_NULL[0] { b := make([]byte, len(JSON_NULL)) _, err := p.reader.Read(b) if err != nil { return v, NewTProtocolException(err) } if string(b) != string(JSON_NULL) { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } } else { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } return v, p.ParsePostValue() } func (p *TSimpleJSONProtocol) ReadBinary(ctx context.Context) ([]byte, error) { var v []byte if err := p.ParsePreValue(); err != nil { return nil, err } f, _ := p.reader.Peek(1) if len(f) > 0 && f[0] == JSON_QUOTE { p.reader.ReadByte() value, err := p.ParseBase64EncodedBody() v = value if err != nil { return v, err } } else if len(f) > 0 && f[0] == JSON_NULL[0] { b := make([]byte, len(JSON_NULL)) _, err := p.reader.Read(b) if err != nil { return v, NewTProtocolException(err) } if string(b) != string(JSON_NULL) { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } } else { e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) return v, NewTProtocolExceptionWithType(INVALID_DATA, e) } return v, p.ParsePostValue() } func (p *TSimpleJSONProtocol) ReadUUID(ctx context.Context) (v Tuuid, err error) { var s string s, err = p.ReadString(ctx) if err != nil { return v, err } v, err = ParseTuuid(s) return v, NewTProtocolExceptionWithType(INVALID_DATA, err) } func (p *TSimpleJSONProtocol) Flush(ctx context.Context) (err error) { return NewTProtocolException(p.writer.Flush()) } func (p *TSimpleJSONProtocol) Skip(ctx context.Context, fieldType TType) (err error) { return SkipDefaultDepth(ctx, p, fieldType) } func (p *TSimpleJSONProtocol) Transport() TTransport { return p.trans } func (p *TSimpleJSONProtocol) OutputPreValue() error { cxt, ok := p.dumpContext.peek() if !ok { return errEmptyJSONContextStack } switch cxt { case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY: if _, e := p.write(JSON_COMMA); e != nil { return NewTProtocolException(e) } case _CONTEXT_IN_OBJECT_NEXT_VALUE: if _, e := p.write(JSON_COLON); e != nil { return NewTProtocolException(e) } } return nil } func (p *TSimpleJSONProtocol) OutputPostValue() error { cxt, ok := p.dumpContext.peek() if !ok { return errEmptyJSONContextStack } switch cxt { case _CONTEXT_IN_LIST_FIRST: p.dumpContext.pop() p.dumpContext.push(_CONTEXT_IN_LIST) case _CONTEXT_IN_OBJECT_FIRST: p.dumpContext.pop() p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_VALUE) case _CONTEXT_IN_OBJECT_NEXT_KEY: p.dumpContext.pop() p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_VALUE) case _CONTEXT_IN_OBJECT_NEXT_VALUE: p.dumpContext.pop() p.dumpContext.push(_CONTEXT_IN_OBJECT_NEXT_KEY) } return nil } func (p *TSimpleJSONProtocol) OutputBool(value bool) error { if e := p.OutputPreValue(); e != nil { return e } var v string if value { v = string(JSON_TRUE) } else { v = string(JSON_FALSE) } cxt, ok := p.dumpContext.peek() if !ok { return errEmptyJSONContextStack } switch cxt { case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: v = jsonQuote(v) } if e := p.OutputStringData(v); e != nil { return e } return p.OutputPostValue() } func (p *TSimpleJSONProtocol) OutputNull() error { if e := p.OutputPreValue(); e != nil { return e } if _, e := p.write(JSON_NULL); e != nil { return NewTProtocolException(e) } return p.OutputPostValue() } func (p *TSimpleJSONProtocol) OutputF64(value float64) error { if e := p.OutputPreValue(); e != nil { return e } var v string if math.IsNaN(value) { v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE) } else if math.IsInf(value, 1) { v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE) } else if math.IsInf(value, -1) { v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE) } else { cxt, ok := p.dumpContext.peek() if !ok { return errEmptyJSONContextStack } v = strconv.FormatFloat(value, 'g', -1, 64) switch cxt { case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: v = string(JSON_QUOTE) + v + string(JSON_QUOTE) } } if e := p.OutputStringData(v); e != nil { return e } return p.OutputPostValue() } func (p *TSimpleJSONProtocol) OutputI64(value int64) error { if e := p.OutputPreValue(); e != nil { return e } cxt, ok := p.dumpContext.peek() if !ok { return errEmptyJSONContextStack } v := strconv.FormatInt(value, 10) switch cxt { case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: v = jsonQuote(v) } if e := p.OutputStringData(v); e != nil { return e } return p.OutputPostValue() } func (p *TSimpleJSONProtocol) OutputString(s string) error { if e := p.OutputPreValue(); e != nil { return e } if e := p.OutputStringData(jsonQuote(s)); e != nil { return e } return p.OutputPostValue() } func (p *TSimpleJSONProtocol) OutputStringData(s string) error { _, e := p.write([]byte(s)) return NewTProtocolException(e) } func (p *TSimpleJSONProtocol) OutputObjectBegin() error { if e := p.OutputPreValue(); e != nil { return e } if _, e := p.write(JSON_LBRACE); e != nil { return NewTProtocolException(e) } p.dumpContext.push(_CONTEXT_IN_OBJECT_FIRST) return nil } func (p *TSimpleJSONProtocol) OutputObjectEnd() error { if _, e := p.write(JSON_RBRACE); e != nil { return NewTProtocolException(e) } _, ok := p.dumpContext.pop() if !ok { return errEmptyJSONContextStack } if e := p.OutputPostValue(); e != nil { return e } return nil } func (p *TSimpleJSONProtocol) OutputListBegin() error { if e := p.OutputPreValue(); e != nil { return e } if _, e := p.write(JSON_LBRACKET); e != nil { return NewTProtocolException(e) } p.dumpContext.push(_CONTEXT_IN_LIST_FIRST) return nil } func (p *TSimpleJSONProtocol) OutputListEnd() error { if _, e := p.write(JSON_RBRACKET); e != nil { return NewTProtocolException(e) } _, ok := p.dumpContext.pop() if !ok { return errEmptyJSONContextStack } if e := p.OutputPostValue(); e != nil { return e } return nil } func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error { if e := p.OutputListBegin(); e != nil { return e } if e := p.OutputI64(int64(elemType)); e != nil { return e } if e := p.OutputI64(int64(size)); e != nil { return e } return nil } func (p *TSimpleJSONProtocol) ParsePreValue() error { if e := p.readNonSignificantWhitespace(); e != nil { return NewTProtocolException(e) } cxt, ok := p.parseContextStack.peek() if !ok { return errEmptyJSONContextStack } b, _ := p.reader.Peek(1) switch cxt { case _CONTEXT_IN_LIST: if len(b) > 0 { switch b[0] { case JSON_RBRACKET[0]: return nil case JSON_COMMA[0]: p.reader.ReadByte() if e := p.readNonSignificantWhitespace(); e != nil { return NewTProtocolException(e) } return nil default: e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b)) return NewTProtocolExceptionWithType(INVALID_DATA, e) } } case _CONTEXT_IN_OBJECT_NEXT_KEY: if len(b) > 0 { switch b[0] { case JSON_RBRACE[0]: return nil case JSON_COMMA[0]: p.reader.ReadByte() if e := p.readNonSignificantWhitespace(); e != nil { return NewTProtocolException(e) } return nil default: e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b)) return NewTProtocolExceptionWithType(INVALID_DATA, e) } } case _CONTEXT_IN_OBJECT_NEXT_VALUE: if len(b) > 0 { switch b[0] { case JSON_COLON[0]: p.reader.ReadByte() if e := p.readNonSignificantWhitespace(); e != nil { return NewTProtocolException(e) } return nil default: e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b)) return NewTProtocolExceptionWithType(INVALID_DATA, e) } } } return nil } func (p *TSimpleJSONProtocol) ParsePostValue() error { if e := p.readNonSignificantWhitespace(); e != nil { return NewTProtocolException(e) } cxt, ok := p.parseContextStack.peek() if !ok { return errEmptyJSONContextStack } switch cxt { case _CONTEXT_IN_LIST_FIRST: p.parseContextStack.pop() p.parseContextStack.push(_CONTEXT_IN_LIST) case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: p.parseContextStack.pop() p.parseContextStack.push(_CONTEXT_IN_OBJECT_NEXT_VALUE) case _CONTEXT_IN_OBJECT_NEXT_VALUE: p.parseContextStack.pop() p.parseContextStack.push(_CONTEXT_IN_OBJECT_NEXT_KEY) } return nil } func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() error { for { b, _ := p.reader.Peek(1) if len(b) < 1 { return nil } switch b[0] { case ' ', '\r', '\n', '\t': p.reader.ReadByte() continue } break } return nil } func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) { line, err := p.reader.ReadString(JSON_QUOTE) if err != nil { return "", NewTProtocolException(err) } if endsWithoutEscapedQuote(line) { v, ok := jsonUnquote(string(JSON_QUOTE) + line) if !ok { return "", NewTProtocolException(err) } return v, nil } s, err := p.ParseQuotedStringBody() if err != nil { return "", NewTProtocolException(err) } str := string(JSON_QUOTE) + line + s v, ok := jsonUnquote(str) if !ok { e := fmt.Errorf("Unable to parse as JSON string %s", str) return "", NewTProtocolExceptionWithType(INVALID_DATA, e) } return v, nil } func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) { 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 } } } func endsWithoutEscapedQuote(s string) bool { l := len(s) i := 1 for ; i < l; i++ { if s[l-i-1] != '\\' { break } } return i&0x01 == 1 } func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) { line, err := p.reader.ReadBytes(JSON_QUOTE) if err != nil { return line, NewTProtocolException(err) } line2 := line[0 : len(line)-1] l := len(line2) if (l % 4) != 0 { pad := 4 - (l % 4) fill := [...]byte{'=', '=', '='} line2 = append(line2, fill[:pad]...) l = len(line2) } output := make([]byte, base64.StdEncoding.DecodedLen(l)) n, err := base64.StdEncoding.Decode(output, line2) return output[0:n], NewTProtocolException(err) } func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) { if err := p.ParsePreValue(); err != nil { return 0, false, err } var value int64 var isnull bool if p.safePeekContains(JSON_NULL) { p.reader.Read(make([]byte, len(JSON_NULL))) isnull = true } else { num, err := p.readNumeric() isnull = (num == nil) if !isnull { value = num.Int64() } if err != nil { return value, isnull, err } } return value, isnull, p.ParsePostValue() } func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, error) { if err := p.ParsePreValue(); err != nil { return 0, false, err } var value float64 var isnull bool if p.safePeekContains(JSON_NULL) { p.reader.Read(make([]byte, len(JSON_NULL))) isnull = true } else { num, err := p.readNumeric() isnull = (num == nil) if !isnull { value = num.Float64() } if err != nil { return value, isnull, err } } return value, isnull, p.ParsePostValue() } func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, error) { if err := p.ParsePreValue(); err != nil { return false, err } var b []byte b, err := p.reader.Peek(1) if err != nil { return false, err } if len(b) > 0 && b[0] == JSON_LBRACE[0] { p.reader.ReadByte() p.parseContextStack.push(_CONTEXT_IN_OBJECT_FIRST) return false, nil } else if p.safePeekContains(JSON_NULL) { return true, nil } e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b)) return false, NewTProtocolExceptionWithType(INVALID_DATA, e) } func (p *TSimpleJSONProtocol) ParseObjectEnd() error { if isNull, err := p.readIfNull(); isNull || err != nil { return err } cxt, _ := p.parseContextStack.peek() if (cxt != _CONTEXT_IN_OBJECT_FIRST) && (cxt != _CONTEXT_IN_OBJECT_NEXT_KEY) { e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context (%d)", cxt) return NewTProtocolExceptionWithType(INVALID_DATA, e) } line, err := p.reader.ReadString(JSON_RBRACE[0]) if err != nil { return NewTProtocolException(err) } for _, char := range line { switch char { default: e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line) return NewTProtocolExceptionWithType(INVALID_DATA, e) case ' ', '\n', '\r', '\t', '}': // do nothing } } p.parseContextStack.pop() return p.ParsePostValue() } func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) { if e := p.ParsePreValue(); e != nil { return false, e } var b []byte b, err = p.reader.Peek(1) if err != nil { return false, err } if len(b) >= 1 && b[0] == JSON_LBRACKET[0] { p.parseContextStack.push(_CONTEXT_IN_LIST_FIRST) p.reader.ReadByte() isNull = false } else if p.safePeekContains(JSON_NULL) { isNull = true } else { err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b) } return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err) } func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { if isNull, e := p.ParseListBegin(); isNull || e != nil { return VOID, 0, e } bElemType, _, err := p.ParseI64() elemType = TType(bElemType) if err != nil { return elemType, size, err } nSize, _, err := p.ParseI64() if err != nil { return elemType, 0, err } err = checkSizeForProtocol(int32(nSize), p.cfg) if err != nil { return elemType, 0, err } size = int(nSize) return elemType, size, nil } func (p *TSimpleJSONProtocol) ParseListEnd() error { if isNull, err := p.readIfNull(); isNull || err != nil { return err } cxt, _ := p.parseContextStack.peek() if cxt != _CONTEXT_IN_LIST { e := fmt.Errorf("Expected to be in the List Context, but not in List Context (%d)", cxt) return NewTProtocolExceptionWithType(INVALID_DATA, e) } line, err := p.reader.ReadString(JSON_RBRACKET[0]) if err != nil { return NewTProtocolException(err) } for _, char := range line { switch char { default: e := fmt.Errorf("Expecting end of list \"]\", but found: \"%v\"", line) return NewTProtocolExceptionWithType(INVALID_DATA, e) case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]): // do nothing } } p.parseContextStack.pop() if cxt, ok := p.parseContextStack.peek(); !ok { return errEmptyJSONContextStack } else if cxt == _CONTEXT_IN_TOPLEVEL { return nil } return p.ParsePostValue() } func (p *TSimpleJSONProtocol) readIfNull() (bool, error) { cont := true for cont { b, _ := p.reader.Peek(1) if len(b) < 1 { return false, nil } switch b[0] { default: return false, nil case JSON_NULL[0]: cont = false case ' ', '\n', '\r', '\t': p.reader.ReadByte() } } if p.safePeekContains(JSON_NULL) { p.reader.Read(make([]byte, len(JSON_NULL))) return true, nil } return false, nil } func (p *TSimpleJSONProtocol) readQuoteIfNext() { b, _ := p.reader.Peek(1) if len(b) > 0 && b[0] == JSON_QUOTE { p.reader.ReadByte() } } func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) { isNull, err := p.readIfNull() if isNull || err != nil { return NUMERIC_NULL, err } hasDecimalPoint := false nextCanBeSign := true hasE := false MAX_LEN := 40 buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN)) continueFor := true inQuotes := false for continueFor { c, err := p.reader.ReadByte() if err != nil { if errors.Is(err, io.EOF) { break } return NUMERIC_NULL, NewTProtocolException(err) } switch c { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': buf.WriteByte(c) nextCanBeSign = false case '.': if hasDecimalPoint { e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String()) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } if hasE { e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String()) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } buf.WriteByte(c) hasDecimalPoint, nextCanBeSign = true, false case 'e', 'E': if hasE { e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } buf.WriteByte(c) hasE, nextCanBeSign = true, true case '-', '+': if !nextCanBeSign { e := fmt.Errorf("Negative sign within number") return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } buf.WriteByte(c) nextCanBeSign = false case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]: p.reader.UnreadByte() continueFor = false case JSON_NAN[0]: if buf.Len() == 0 { buffer := make([]byte, len(JSON_NAN)) buffer[0] = c _, e := p.reader.Read(buffer[1:]) if e != nil { return NUMERIC_NULL, NewTProtocolException(e) } if JSON_NAN != string(buffer) { e := mismatch(JSON_NAN, string(buffer)) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } if inQuotes { p.readQuoteIfNext() } return NAN, nil } else { e := fmt.Errorf("Unable to parse number starting with character '%c'", c) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } case JSON_INFINITY[0]: if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') { buffer := make([]byte, len(JSON_INFINITY)) buffer[0] = c _, e := p.reader.Read(buffer[1:]) if e != nil { return NUMERIC_NULL, NewTProtocolException(e) } if JSON_INFINITY != string(buffer) { e := mismatch(JSON_INFINITY, string(buffer)) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } if inQuotes { p.readQuoteIfNext() } return INFINITY, nil } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] { buffer := make([]byte, len(JSON_NEGATIVE_INFINITY)) buffer[0] = JSON_NEGATIVE_INFINITY[0] buffer[1] = c _, e := p.reader.Read(buffer[2:]) if e != nil { return NUMERIC_NULL, NewTProtocolException(e) } if JSON_NEGATIVE_INFINITY != string(buffer) { e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer)) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } if inQuotes { p.readQuoteIfNext() } return NEGATIVE_INFINITY, nil } else { e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String()) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } case JSON_QUOTE: if !inQuotes { inQuotes = true } default: e := fmt.Errorf("Unable to parse number starting with character '%c'", c) return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } } if buf.Len() == 0 { e := fmt.Errorf("Unable to parse number from empty string ''") return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) } return NewNumericFromJSONString(buf.String(), false), nil } // Safely peeks into the buffer, reading only what is necessary func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool { for i := range b { a, _ := p.reader.Peek(i + 1) if len(a) < (i+1) || a[i] != b[i] { return false } } return true } // Reset the context stack to its initial state. func (p *TSimpleJSONProtocol) resetContextStack() { p.parseContextStack = jsonContextStack{_CONTEXT_IN_TOPLEVEL} p.dumpContext = jsonContextStack{_CONTEXT_IN_TOPLEVEL} } func (p *TSimpleJSONProtocol) write(b []byte) (int, error) { n, err := p.writer.Write(b) if err != nil { p.writer.Reset(p.trans) // THRIFT-3735 } return n, err } // SetTConfiguration implements TConfigurationSetter for propagation. func (p *TSimpleJSONProtocol) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(p.trans, conf) p.cfg = conf } // Reset resets this protocol's internal state. // // It's useful when a single protocol instance is reused after errors, to make // sure the next use will not be in a bad state to begin with. An example is // when it's used in serializer/deserializer pools. func (p *TSimpleJSONProtocol) Reset() { p.resetContextStack() p.writer.Reset(p.trans) p.reader.Reset(p.trans) } var ( _ TConfigurationSetter = (*TSimpleJSONProtocol)(nil) _ TConfigurationSetter = (*TSimpleJSONProtocolFactory)(nil) ) thrift-0.23.0/lib/go/thrift/exception.go0000664000175000017500000001051315165535636020375 0ustar00buildbuild00000000000000/* * 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 ( "errors" "reflect" ) // Generic Thrift exception type TException interface { error TExceptionType() TExceptionType } // Prepends additional information to an error without losing the Thrift exception interface func PrependError(prepend string, err error) error { msg := prepend + err.Error() var te TException if errors.As(err, &te) { switch te.TExceptionType() { case TExceptionTypeTransport: if t, ok := err.(TTransportException); ok { return prependTTransportException(prepend, t) } case TExceptionTypeProtocol: if t, ok := err.(TProtocolException); ok { return prependTProtocolException(prepend, t) } case TExceptionTypeApplication: var t TApplicationException if errors.As(err, &t) { return NewTApplicationException(t.TypeId(), msg) } } return wrappedTException{ err: err, msg: msg, tExceptionType: te.TExceptionType(), } } return errors.New(msg) } // TExceptionType is an enum type to categorize different "subclasses" of TExceptions. type TExceptionType byte // TExceptionType values const ( TExceptionTypeUnknown TExceptionType = iota TExceptionTypeCompiled // TExceptions defined in thrift files and generated by thrift compiler TExceptionTypeApplication // TApplicationExceptions TExceptionTypeProtocol // TProtocolExceptions TExceptionTypeTransport // TTransportExceptions ) // WrapTException wraps an error into TException. // // If err is nil or already TException, it's returned as-is. // Otherwise it will be wraped into TException with TExceptionType() returning // TExceptionTypeUnknown, and Unwrap() returning the original error. func WrapTException(err error) TException { if err == nil { return nil } if te, ok := err.(TException); ok { return te } return wrappedTException{ err: err, msg: err.Error(), tExceptionType: TExceptionTypeUnknown, } } type wrappedTException struct { err error msg string tExceptionType TExceptionType } func (w wrappedTException) Error() string { return w.msg } func (w wrappedTException) TExceptionType() TExceptionType { return w.tExceptionType } func (w wrappedTException) Unwrap() error { return w.err } var _ TException = wrappedTException{} // ExtractExceptionFromResult extracts exceptions defined in thrift IDL from // result TStruct used in TClient.Call. // // For a endpoint defined in thrift IDL like this: // // 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"` // } // // And this function extracts the first non-nil exception out of // *MyServiceFooResult. func ExtractExceptionFromResult(result TStruct) error { v := reflect.Indirect(reflect.ValueOf(result)) if v.Kind() != reflect.Struct { return nil } typ := v.Type() for i := range v.NumField() { if typ.Field(i).Name == "Success" { continue } field := v.Field(i) if field.IsZero() { continue } tExc, ok := field.Interface().(TException) if ok && tExc != nil && tExc.TExceptionType() == TExceptionTypeCompiled { return tExc } } return nil } thrift-0.23.0/lib/go/thrift/example_processor_middleware_test.go0000664000175000017500000000336615165535636025375 0ustar00buildbuild00000000000000/* * 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 ( "context" "log" ) func SimpleProcessorLoggingMiddleware(name string, next TProcessorFunction) TProcessorFunction { return WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { log.Printf("Before: %q", name) success, err := next.Process(ctx, seqId, in, out) log.Printf("After: %q", name) log.Printf("Success: %v", success) if err != nil { log.Printf("Error: %v", err) } return success, err }, } } // This example demonstrates how to define and use a simple logging middleware // to your thrift server/processor. func ExampleProcessorMiddleware() { var ( processor TProcessor trans TServerTransport transFactory TTransportFactory protoFactory TProtocolFactory ) processor = WrapProcessor(processor, SimpleProcessorLoggingMiddleware) server := NewTSimpleServer4(processor, trans, transFactory, protoFactory) log.Fatal(server.Serve()) } thrift-0.23.0/lib/go/thrift/configuration_test.go0000664000175000017500000002434615165535636022316 0ustar00buildbuild00000000000000/* * 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 ( "crypto/tls" "testing" "time" ) func TestTConfiguration(t *testing.T) { invalidProtoID := THeaderProtocolID(-1) if invalidProtoID.Validate() == nil { t.Fatalf("Expected %v to be an invalid THeaderProtocolID, it passes the validation", invalidProtoID) } tlsConfig := &tls.Config{ Time: time.Now, } for _, c := range []struct { label string cfg *TConfiguration expectedMessageSize int32 expectedFrameSize int32 expectedConnectTimeout time.Duration expectedSocketTimeout time.Duration expectedTLSConfig *tls.Config expectedBinaryRead bool expectedBinaryWrite bool expectedProtoID THeaderProtocolID }{ { label: "nil", cfg: nil, expectedMessageSize: DEFAULT_MAX_MESSAGE_SIZE, expectedFrameSize: DEFAULT_MAX_FRAME_SIZE, expectedConnectTimeout: DEFAULT_CONNECT_TIMEOUT, expectedSocketTimeout: DEFAULT_SOCKET_TIMEOUT, expectedTLSConfig: nil, expectedBinaryRead: DEFAULT_TBINARY_STRICT_READ, expectedBinaryWrite: DEFAULT_TBINARY_STRICT_WRITE, expectedProtoID: THeaderProtocolDefault, }, { label: "empty", cfg: &TConfiguration{}, expectedMessageSize: DEFAULT_MAX_MESSAGE_SIZE, expectedFrameSize: DEFAULT_MAX_FRAME_SIZE, expectedConnectTimeout: DEFAULT_CONNECT_TIMEOUT, expectedSocketTimeout: DEFAULT_SOCKET_TIMEOUT, expectedTLSConfig: nil, expectedBinaryRead: DEFAULT_TBINARY_STRICT_READ, expectedBinaryWrite: DEFAULT_TBINARY_STRICT_WRITE, expectedProtoID: THeaderProtocolDefault, }, { label: "normal", cfg: &TConfiguration{ MaxMessageSize: 1024, MaxFrameSize: 1024, ConnectTimeout: time.Millisecond, SocketTimeout: time.Millisecond * 2, TLSConfig: tlsConfig, TBinaryStrictRead: BoolPtr(true), TBinaryStrictWrite: BoolPtr(false), THeaderProtocolID: THeaderProtocolIDPtrMust(THeaderProtocolCompact), }, expectedMessageSize: 1024, expectedFrameSize: 1024, expectedConnectTimeout: time.Millisecond, expectedSocketTimeout: time.Millisecond * 2, expectedTLSConfig: tlsConfig, expectedBinaryRead: true, expectedBinaryWrite: false, expectedProtoID: THeaderProtocolCompact, }, { label: "message pool var zlibWriterPools map[int]*pool[zlib.Writer] = func() map[int]*pool[zlib.Writer] { m := make(map[int]*pool[zlib.Writer]) for level := zlib.HuffmanOnly; level <= zlib.BestCompression; level++ { // force a panic at init if we have an invalid level here newZlibWriterLevelMust(level) m[level] = newPool( func() *zlib.Writer { return newZlibWriterLevelMust(level) }, nil, ) } return m }() type zlibWriterPoolCloser struct { writer *zlib.Writer pool *pool[zlib.Writer] } func (z *zlibWriterPoolCloser) Close() error { defer func() { z.writer.Reset(nil) z.pool.put(&z.writer) }() return z.writer.Close() } func newZlibWriterCloserLevel(w io.Writer, level int) (*zlib.Writer, io.Closer, error) { pool, ok := zlibWriterPools[level] if !ok { // not pooled writer, err := zlib.NewWriterLevel(w, level) if err != nil { return nil, nil, err } return writer, writer, nil } writer := pool.get() writer.Reset(w) return writer, &zlibWriterPoolCloser{writer: writer, pool: pool}, nil } thrift-0.23.0/lib/go/thrift/transport_factory.go0000664000175000017500000000263015165535636022163 0ustar00buildbuild00000000000000/* * 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 // Factory class used to create wrapped instance of Transports. // This is used primarily in servers, which get Transports from // a ServerTransport and then may want to mutate them (i.e. create // a BufferedTransport from the underlying base transport) type TTransportFactory interface { GetTransport(trans TTransport) (TTransport, error) } type tTransportFactory struct{} // Return a wrapped instance of the base Transport. func (p *tTransportFactory) GetTransport(trans TTransport) (TTransport, error) { return trans, nil } func NewTTransportFactory() TTransportFactory { return &tTransportFactory{} } thrift-0.23.0/lib/go/thrift/rich_transport_test.go0000664000175000017500000000510415165535636022477 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "errors" "io" "reflect" "testing" ) func TestEnsureTransportsAreRich(t *testing.T) { buf := bytes.NewBuffer(make([]byte, 0, 1024)) transports := []TTransportFactory{ NewTMemoryBufferTransportFactory(1024), NewStreamTransportFactory(buf, buf, true), NewTFramedTransportFactory(NewTMemoryBufferTransportFactory(1024)), NewTHttpPostClientTransportFactory("http://127.0.0.1"), } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } _, ok := trans.(TRichTransport) if !ok { t.Errorf("Transport %s does not implement TRichTransport interface", reflect.ValueOf(trans)) } } } // TestReadByte tests whether readByte handles error cases correctly. func TestReadByte(t *testing.T) { for i, test := range readByteTests { v, err := readByte(test.r) if v != test.v { t.Fatalf("TestReadByte %d: value differs. Expected %d, got %d", i, test.v, test.r.v) } if err != test.err { t.Fatalf("TestReadByte %d: error differs. Expected %s, got %s", i, test.err, test.r.err) } } } var errSomeError = errors.New("Some error") var readByteTests = []struct { r *mockReader v byte err error }{ {&mockReader{0, 55, io.EOF}, 0, io.EOF}, // reader sends EOF w/o data {&mockReader{0, 55, errSomeError}, 0, errSomeError}, // reader sends some other error {&mockReader{1, 55, nil}, 55, nil}, // reader sends data w/o error {&mockReader{1, 55, io.EOF}, 55, nil}, // reader sends data with EOF {&mockReader{1, 55, errSomeError}, 55, errSomeError}, // reader sends data withsome error } type mockReader struct { n int v byte err error } func (r *mockReader) Read(p []byte) (n int, err error) { if r.n > 0 { p[0] = r.v } return r.n, r.err } thrift-0.23.0/lib/go/thrift/binary_protocol.go0000664000175000017500000003555115167543515021612 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "context" "encoding/binary" "fmt" "io" "math" ) type TBinaryProtocol struct { trans TRichTransport origTransport TTransport cfg *TConfiguration buffer [64]byte } type TBinaryProtocolFactory struct { cfg *TConfiguration } // Deprecated: Use NewTBinaryProtocolConf instead. func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol { return NewTBinaryProtocolConf(t, &TConfiguration{ noPropagation: true, }) } // Deprecated: Use NewTBinaryProtocolConf instead. func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol { return NewTBinaryProtocolConf(t, &TConfiguration{ TBinaryStrictRead: &strictRead, TBinaryStrictWrite: &strictWrite, noPropagation: true, }) } func NewTBinaryProtocolConf(t TTransport, conf *TConfiguration) *TBinaryProtocol { PropagateTConfiguration(t, conf) p := &TBinaryProtocol{ origTransport: t, cfg: conf, } if et, ok := t.(TRichTransport); ok { p.trans = et } else { p.trans = NewTRichTransport(t) } return p } // Deprecated: Use NewTBinaryProtocolFactoryConf instead. func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory { return NewTBinaryProtocolFactoryConf(&TConfiguration{ noPropagation: true, }) } // Deprecated: Use NewTBinaryProtocolFactoryConf instead. func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory { return NewTBinaryProtocolFactoryConf(&TConfiguration{ TBinaryStrictRead: &strictRead, TBinaryStrictWrite: &strictWrite, noPropagation: true, }) } func NewTBinaryProtocolFactoryConf(conf *TConfiguration) *TBinaryProtocolFactory { return &TBinaryProtocolFactory{ cfg: conf, } } func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol { return NewTBinaryProtocolConf(t, p.cfg) } func (p *TBinaryProtocolFactory) SetTConfiguration(conf *TConfiguration) { p.cfg = conf } /** * Writing Methods */ func (p *TBinaryProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqId int32) error { if p.cfg.GetTBinaryStrictWrite() { version := uint32(VERSION_1) | uint32(typeId) e := p.WriteI32(ctx, int32(version)) if e != nil { return e } e = p.WriteString(ctx, name) if e != nil { return e } e = p.WriteI32(ctx, seqId) return e } else { e := p.WriteString(ctx, name) if e != nil { return e } e = p.WriteByte(ctx, int8(typeId)) if e != nil { return e } e = p.WriteI32(ctx, seqId) return e } } func (p *TBinaryProtocol) WriteMessageEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) WriteStructBegin(ctx context.Context, name string) error { return nil } func (p *TBinaryProtocol) WriteStructEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { e := p.WriteByte(ctx, int8(typeId)) if e != nil { return e } e = p.WriteI16(ctx, id) return e } func (p *TBinaryProtocol) WriteFieldEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) WriteFieldStop(ctx context.Context) error { e := p.WriteByte(ctx, STOP) return e } func (p *TBinaryProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { e := p.WriteByte(ctx, int8(keyType)) if e != nil { return e } e = p.WriteByte(ctx, int8(valueType)) if e != nil { return e } e = p.WriteI32(ctx, int32(size)) return e } func (p *TBinaryProtocol) WriteMapEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { e := p.WriteByte(ctx, int8(elemType)) if e != nil { return e } e = p.WriteI32(ctx, int32(size)) return e } func (p *TBinaryProtocol) WriteListEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { e := p.WriteByte(ctx, int8(elemType)) if e != nil { return e } e = p.WriteI32(ctx, int32(size)) return e } func (p *TBinaryProtocol) WriteSetEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) WriteBool(ctx context.Context, value bool) error { if value { return p.WriteByte(ctx, 1) } return p.WriteByte(ctx, 0) } func (p *TBinaryProtocol) WriteByte(ctx context.Context, value int8) error { e := p.trans.WriteByte(byte(value)) return NewTProtocolException(e) } func (p *TBinaryProtocol) WriteI16(ctx context.Context, value int16) error { v := p.buffer[0:2] binary.BigEndian.PutUint16(v, uint16(value)) _, e := p.trans.Write(v) return NewTProtocolException(e) } func (p *TBinaryProtocol) WriteI32(ctx context.Context, value int32) error { v := p.buffer[0:4] binary.BigEndian.PutUint32(v, uint32(value)) _, e := p.trans.Write(v) return NewTProtocolException(e) } func (p *TBinaryProtocol) WriteI64(ctx context.Context, value int64) error { v := p.buffer[0:8] binary.BigEndian.PutUint64(v, uint64(value)) _, err := p.trans.Write(v) return NewTProtocolException(err) } func (p *TBinaryProtocol) WriteDouble(ctx context.Context, value float64) error { return p.WriteI64(ctx, int64(math.Float64bits(value))) } func (p *TBinaryProtocol) WriteString(ctx context.Context, value string) error { e := p.WriteI32(ctx, int32(len(value))) if e != nil { return e } _, err := p.trans.WriteString(value) return NewTProtocolException(err) } func (p *TBinaryProtocol) WriteBinary(ctx context.Context, value []byte) error { e := p.WriteI32(ctx, int32(len(value))) if e != nil { return e } _, err := p.trans.Write(value) return NewTProtocolException(err) } func (p *TBinaryProtocol) WriteUUID(ctx context.Context, value Tuuid) error { _, err := p.trans.Write(value[:]) return NewTProtocolException(err) } /** * Reading methods */ func (p *TBinaryProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) { size, e := p.ReadI32(ctx) if e != nil { return "", typeId, 0, NewTProtocolException(e) } if size < 0 { typeId = TMessageType(size & 0x0ff) version := int64(int64(size) & VERSION_MASK) if version != VERSION_1 { return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Bad version in ReadMessageBegin")) } name, e = p.ReadString(ctx) if e != nil { return name, typeId, seqId, NewTProtocolException(e) } seqId, e = p.ReadI32(ctx) if e != nil { return name, typeId, seqId, NewTProtocolException(e) } return name, typeId, seqId, nil } if p.cfg.GetTBinaryStrictRead() { return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Missing version in ReadMessageBegin")) } name, e2 := p.readStringBody(size) if e2 != nil { return name, typeId, seqId, e2 } b, e3 := p.ReadByte(ctx) if e3 != nil { return name, typeId, seqId, e3 } typeId = TMessageType(b) seqId, e4 := p.ReadI32(ctx) if e4 != nil { return name, typeId, seqId, e4 } return name, typeId, seqId, nil } func (p *TBinaryProtocol) ReadMessageEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { return } func (p *TBinaryProtocol) ReadStructEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, seqId int16, err error) { t, err := p.ReadByte(ctx) typeId = TType(t) if err != nil { return name, typeId, seqId, err } if t != STOP { seqId, err = p.ReadI16(ctx) } return name, typeId, seqId, err } func (p *TBinaryProtocol) ReadFieldEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) ReadMapBegin(ctx context.Context) (kType, vType TType, size int, err error) { k, e := p.ReadByte(ctx) if e != nil { err = NewTProtocolException(e) return } kType = TType(k) v, e := p.ReadByte(ctx) if e != nil { err = NewTProtocolException(e) return } vType = TType(v) size32, e := p.ReadI32(ctx) if e != nil { err = NewTProtocolException(e) return } minElemSize := p.getMinSerializedSize(kType) + p.getMinSerializedSize(vType) totalMinSize := size32 * minElemSize err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } size = int(size32) return kType, vType, size, nil } func (p *TBinaryProtocol) ReadMapEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { b, e := p.ReadByte(ctx) if e != nil { err = NewTProtocolException(e) return } elemType = TType(b) size32, e := p.ReadI32(ctx) if e != nil { err = NewTProtocolException(e) return } minElemSize := p.getMinSerializedSize(elemType) totalMinSize := size32 * minElemSize err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } size = int(size32) return } func (p *TBinaryProtocol) ReadListEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { b, e := p.ReadByte(ctx) if e != nil { err = NewTProtocolException(e) return } elemType = TType(b) size32, e := p.ReadI32(ctx) if e != nil { err = NewTProtocolException(e) return } minElemSize := p.getMinSerializedSize(elemType) totalMinSize := size32 * minElemSize err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } size = int(size32) return elemType, size, nil } func (p *TBinaryProtocol) ReadSetEnd(ctx context.Context) error { return nil } func (p *TBinaryProtocol) ReadBool(ctx context.Context) (bool, error) { b, e := p.ReadByte(ctx) v := true if b != 1 { v = false } return v, e } func (p *TBinaryProtocol) ReadByte(ctx context.Context) (int8, error) { v, err := p.trans.ReadByte() return int8(v), err } func (p *TBinaryProtocol) ReadI16(ctx context.Context) (value int16, err error) { buf := p.buffer[0:2] err = p.readAll(ctx, buf) value = int16(binary.BigEndian.Uint16(buf)) return value, err } func (p *TBinaryProtocol) ReadI32(ctx context.Context) (value int32, err error) { buf := p.buffer[0:4] err = p.readAll(ctx, buf) value = int32(binary.BigEndian.Uint32(buf)) return value, err } func (p *TBinaryProtocol) ReadI64(ctx context.Context) (value int64, err error) { buf := p.buffer[0:8] err = p.readAll(ctx, buf) value = int64(binary.BigEndian.Uint64(buf)) return value, err } func (p *TBinaryProtocol) ReadDouble(ctx context.Context) (value float64, err error) { buf := p.buffer[0:8] err = p.readAll(ctx, buf) value = math.Float64frombits(binary.BigEndian.Uint64(buf)) return value, err } func (p *TBinaryProtocol) ReadString(ctx context.Context) (value string, err error) { size, e := p.ReadI32(ctx) if e != nil { return "", e } err = checkSizeForProtocol(size, p.cfg) if err != nil { return } if size == 0 { return "", nil } if size < int32(len(p.buffer)) { // Avoid allocation on small reads buf := p.buffer[:size] read, e := io.ReadFull(p.trans, buf) return string(buf[:read]), NewTProtocolException(e) } return p.readStringBody(size) } func (p *TBinaryProtocol) ReadBinary(ctx context.Context) ([]byte, error) { size, e := p.ReadI32(ctx) if e != nil { return nil, e } if err := checkSizeForProtocol(size, p.cfg); err != nil { return nil, err } buf, err := safeReadBytes(size, p.trans) return buf, NewTProtocolException(err) } func (p *TBinaryProtocol) ReadUUID(ctx context.Context) (value Tuuid, err error) { buf := p.buffer[0:16] err = p.readAll(ctx, buf) if err == nil { copy(value[:], buf) } return value, err } func (p *TBinaryProtocol) Flush(ctx context.Context) (err error) { return NewTProtocolException(p.trans.Flush(ctx)) } func (p *TBinaryProtocol) Skip(ctx context.Context, fieldType TType) (err error) { return SkipDefaultDepth(ctx, p, fieldType) } func (p *TBinaryProtocol) Transport() TTransport { return p.origTransport } func (p *TBinaryProtocol) readAll(ctx context.Context, buf []byte) (err error) { var read int _, deadlineSet := ctx.Deadline() for { read, err = io.ReadFull(p.trans, buf) if deadlineSet && read == 0 && isTimeoutError(err) && ctx.Err() == nil { // This is I/O timeout without anything read, // and we still have time left, keep retrying. continue } // For anything else, don't retry break } return NewTProtocolException(err) } func (p *TBinaryProtocol) readStringBody(size int32) (value string, err error) { buf, err := safeReadBytes(size, p.trans) return string(buf), NewTProtocolException(err) } func (p *TBinaryProtocol) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(p.trans, conf) PropagateTConfiguration(p.origTransport, conf) p.cfg = conf } var ( _ TConfigurationSetter = (*TBinaryProtocolFactory)(nil) _ TConfigurationSetter = (*TBinaryProtocol)(nil) ) // Return the minimum number of bytes a type will consume on the wire func (p *TBinaryProtocol) getMinSerializedSize(ttype TType) int32 { switch ttype { case STOP: return 1 // T_STOP needs to count itself case VOID: return 1 // T_VOID needs to count itsel∂ case BOOL: return 1 // sizeof(int8) case BYTE: return 1 // sizeof(int8) case DOUBLE: return 8 // sizeof(double) case I16: return 2 // sizeof(short) case I32: return 4 // sizeof(int) case I64: return 8 // sizeof(long) case STRING: return 4 // string length case STRUCT: return 1 // empty struct needs at least 1 byte for the T_STOP case MAP: return 4 // element count case SET: return 4 // element count case LIST: return 4 // element count case UUID: return 16 // 16 bytes default: return 1 // unknown type } } // This function is shared between TBinaryProtocol and TCompactProtocol. // // It tries to read size bytes from trans, in a way that prevents large // allocations when size is insanely large (mostly caused by malformed message), // or smaller than bytes.MinRead. func safeReadBytes(size int32, trans io.Reader) ([]byte, error) { if size < 0 { return nil, nil } if size > bytes.MinRead { // Use bytes.Buffer to prevent allocating size bytes when size is very large buf := new(bytes.Buffer) _, err := io.CopyN(buf, trans, int64(size)) return buf.Bytes(), err } // Allocate size bytes b := make([]byte, size) n, err := io.ReadFull(trans, b) return b[:n], err } thrift-0.23.0/lib/go/thrift/serializer_test.go0000664000175000017500000001762415167543515021616 0ustar00buildbuild00000000000000/* * 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 ( "context" "errors" "fmt" "sync" "sync/atomic" "testing" "testing/quick" ) type ProtocolFactory interface { GetProtocol(t TTransport) TProtocol } func compareStructs(m, m1 MyTestStruct) error { switch { case m.On != m1.On: return errors.New("Boolean not equal") case m.B != m1.B: return errors.New("Byte not equal") case m.Int16 != m1.Int16: return errors.New("Int16 not equal") case m.Int32 != m1.Int32: return errors.New("Int32 not equal") case m.Int64 != m1.Int64: return errors.New("Int64 not equal") case m.D != m1.D: return errors.New("Double not equal") case m.St != m1.St: return errors.New("String not equal") case len(m.Bin) != len(m1.Bin): return errors.New("Binary size not equal") case len(m.Bin) == len(m1.Bin): for i := range m.Bin { if m.Bin[i] != m1.Bin[i] { return errors.New("Binary not equal") } } case len(m.StringMap) != len(m1.StringMap): return errors.New("StringMap size not equal") case len(m.StringList) != len(m1.StringList): return errors.New("StringList size not equal") case len(m.StringSet) != len(m1.StringSet): return errors.New("StringSet size not equal") case m.E != m1.E: return errors.New("MyTestEnum not equal") default: return nil } return nil } type serializer interface { WriteString(context.Context, TStruct) (string, error) } type deserializer interface { ReadString(context.Context, TStruct, string) error } func plainSerializer(pf ProtocolFactory) serializer { t := NewTSerializer() t.Protocol = pf.GetProtocol(t.Transport) return t } func poolSerializer(pf ProtocolFactory) serializer { return NewTSerializerPool( func() *TSerializer { return plainSerializer(pf).(*TSerializer) }, ) } func plainDeserializer(pf ProtocolFactory) deserializer { d := NewTDeserializer() d.Protocol = pf.GetProtocol(d.Transport) return d } func poolDeserializer(pf ProtocolFactory) deserializer { return NewTDeserializerPool( func() *TDeserializer { return plainDeserializer(pf).(*TDeserializer) }, ) } type constructors struct { Label string Serializer func(pf ProtocolFactory) serializer Deserializer func(pf ProtocolFactory) deserializer } var implementations = []constructors{ { Label: "plain", Serializer: plainSerializer, Deserializer: plainDeserializer, }, { Label: "pool", Serializer: poolSerializer, Deserializer: poolDeserializer, }, } func ProtocolTest1(t *testing.T, pf ProtocolFactory) { for _, impl := range implementations { t.Run( impl.Label, func(test *testing.T) { t := impl.Serializer(pf) var m = MyTestStruct{} m.On = true m.B = int8(0) m.Int16 = 1 m.Int32 = 2 m.Int64 = 3 m.D = 4.1 m.St = "Test" m.Bin = make([]byte, 10) m.StringMap = make(map[string]string, 5) m.StringList = make([]string, 5) m.StringSet = make(map[string]struct{}, 5) m.E = 2 s, err := t.WriteString(context.Background(), &m) if err != nil { test.Fatalf("Unable to Serialize struct: %v", err) } t1 := impl.Deserializer(pf) var m1 MyTestStruct if err = t1.ReadString(context.Background(), &m1, s); err != nil { test.Fatalf("Unable to Deserialize struct: %v", err) } if err := compareStructs(m, m1); err != nil { test.Error(err) } }, ) } } func ProtocolTest2(t *testing.T, pf ProtocolFactory) { for _, impl := range implementations { t.Run( impl.Label, func(test *testing.T) { t := impl.Serializer(pf) var m = MyTestStruct{} m.On = false m.B = int8(0) m.Int16 = 1 m.Int32 = 2 m.Int64 = 3 m.D = 4.1 m.St = "Test" m.Bin = make([]byte, 10) m.StringMap = make(map[string]string, 5) m.StringList = make([]string, 5) m.StringSet = make(map[string]struct{}, 5) m.E = 2 s, err := t.WriteString(context.Background(), &m) if err != nil { test.Fatalf("Unable to Serialize struct: %v", err) } t1 := impl.Deserializer(pf) var m1 MyTestStruct if err = t1.ReadString(context.Background(), &m1, s); err != nil { test.Fatalf("Unable to Deserialize struct: %v", err) } if err := compareStructs(m, m1); err != nil { test.Error(err) } }, ) } } func TestSerializer(t *testing.T) { protocolFactories := make(map[string]ProtocolFactory) protocolFactories["Binary"] = NewTBinaryProtocolFactoryDefault() protocolFactories["Compact"] = NewTCompactProtocolFactory() //protocolFactories["SimpleJSON"] = NewTSimpleJSONProtocolFactory() - write only, can't be read back by design protocolFactories["JSON"] = NewTJSONProtocolFactory() tests := make(map[string]func(*testing.T, ProtocolFactory)) tests["Test 1"] = ProtocolTest1 tests["Test 2"] = ProtocolTest2 //tests["Test 3"] = ProtocolTest3 // Example of how to add additional tests for name, pf := range protocolFactories { t.Run( name, func(t *testing.T) { for label, f := range tests { t.Run( label, func(t *testing.T) { f(t, pf) }, ) } }, ) } } func TestSerializerPoolAsync(t *testing.T) { var wg sync.WaitGroup var counter atomic.Int64 s := NewTSerializerPool(NewTSerializer) d := NewTDeserializerPool(NewTDeserializer) f := func(i int64) bool { wg.Go(func() { t.Run( fmt.Sprintf("#%d-%d", counter.Add(1), i), func(t *testing.T) { m := MyTestStruct{ Int64: i, } str, err := s.WriteString(context.Background(), &m) if err != nil { t.Error("serialize:", err) return } var m1 MyTestStruct if err = d.ReadString(context.Background(), &m1, str); err != nil { t.Error("deserialize:", err) return } if err := compareStructs(m, m1); err != nil { t.Error(err) } }, ) }) return true } quick.Check(f, nil) wg.Wait() } func BenchmarkSerializer(b *testing.B) { sharedSerializer := NewTSerializer() poolSerializer := NewTSerializerPool(NewTSerializer) sharedDeserializer := NewTDeserializer() poolDeserializer := NewTDeserializerPool(NewTDeserializer) cases := []struct { Label string Serializer func() serializer Deserializer func() deserializer }{ { // Baseline uses shared plain serializer/deserializer Label: "baseline", Serializer: func() serializer { return sharedSerializer }, Deserializer: func() deserializer { return sharedDeserializer }, }, { // Plain creates new serializer/deserializer on every run, // as that's how it's used in real world Label: "plain", Serializer: func() serializer { return NewTSerializer() }, Deserializer: func() deserializer { return NewTDeserializer() }, }, { // Pool uses the shared pool serializer/deserializer Label: "pool", Serializer: func() serializer { return poolSerializer }, Deserializer: func() deserializer { return poolDeserializer }, }, } for _, c := range cases { b.Run( c.Label, func(b *testing.B) { for range b.N { s := c.Serializer() m := MyTestStruct{} str, _ := s.WriteString(context.Background(), &m) var m1 MyTestStruct d := c.Deserializer() d.ReadString(context.Background(), &m1, str) } }, ) } } thrift-0.23.0/lib/go/thrift/duplicate_protocol_test.go0000664000175000017500000000233115165535636023330 0ustar00buildbuild00000000000000package 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) } } thrift-0.23.0/lib/go/thrift/header_protocol.go0000664000175000017500000002560215165535636021555 0ustar00buildbuild00000000000000/* * 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 ( "context" "errors" ) // THeaderProtocol is a thrift protocol that implements THeader: // https://github.com/apache/thrift/blob/master/doc/specs/HeaderFormat.md // // It supports either binary or compact protocol as the wrapped protocol. // // Most of the THeader handlings are happening inside THeaderTransport. type THeaderProtocol struct { transport *THeaderTransport // Will be initialized on first read/write. protocol TProtocol cfg *TConfiguration } // Deprecated: Use NewTHeaderProtocolConf instead. func NewTHeaderProtocol(trans TTransport) *THeaderProtocol { return newTHeaderProtocolConf(trans, &TConfiguration{ noPropagation: true, }) } // NewTHeaderProtocolConf creates a new THeaderProtocol from the underlying // transport with given TConfiguration. // // The passed in transport will be wrapped with THeaderTransport. // // Note that THeaderTransport handles frame and zlib by itself, // so the underlying transport should be a raw socket transports (TSocket or TSSLSocket), // instead of rich transports like TZlibTransport or TFramedTransport. func NewTHeaderProtocolConf(trans TTransport, conf *TConfiguration) *THeaderProtocol { return newTHeaderProtocolConf(trans, conf) } func newTHeaderProtocolConf(trans TTransport, cfg *TConfiguration) *THeaderProtocol { t := NewTHeaderTransportConf(trans, cfg) p, _ := t.cfg.GetTHeaderProtocolID().GetProtocol(t) PropagateTConfiguration(p, cfg) return &THeaderProtocol{ transport: t, protocol: p, cfg: cfg, } } type tHeaderProtocolFactory struct { cfg *TConfiguration } func (f tHeaderProtocolFactory) GetProtocol(trans TTransport) TProtocol { return newTHeaderProtocolConf(trans, f.cfg) } func (f *tHeaderProtocolFactory) SetTConfiguration(cfg *TConfiguration) { f.cfg = cfg } // Deprecated: Use NewTHeaderProtocolFactoryConf instead. func NewTHeaderProtocolFactory() TProtocolFactory { return NewTHeaderProtocolFactoryConf(&TConfiguration{ noPropagation: true, }) } // NewTHeaderProtocolFactoryConf creates a factory for THeader with given // TConfiguration. func NewTHeaderProtocolFactoryConf(conf *TConfiguration) TProtocolFactory { return tHeaderProtocolFactory{ cfg: conf, } } // Transport returns the underlying transport. // // It's guaranteed to be of type *THeaderTransport. func (p *THeaderProtocol) Transport() TTransport { return p.transport } // GetReadHeaders returns the THeaderMap read from transport. func (p *THeaderProtocol) GetReadHeaders() THeaderMap { return p.transport.GetReadHeaders() } // SetWriteHeader sets a header for write. func (p *THeaderProtocol) SetWriteHeader(key, value string) { p.transport.SetWriteHeader(key, value) } // ClearWriteHeaders clears all write headers previously set. func (p *THeaderProtocol) ClearWriteHeaders() { p.transport.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) } func (p *THeaderProtocol) Flush(ctx context.Context) error { return p.transport.Flush(ctx) } func (p *THeaderProtocol) WriteMessageBegin(ctx context.Context, name string, typeID TMessageType, seqID int32) error { newProto, err := p.transport.Protocol().GetProtocol(p.transport) if err != nil { return err } PropagateTConfiguration(newProto, p.cfg) p.protocol = newProto p.transport.SequenceID = seqID return p.protocol.WriteMessageBegin(ctx, name, typeID, seqID) } func (p *THeaderProtocol) WriteMessageEnd(ctx context.Context) error { if err := p.protocol.WriteMessageEnd(ctx); err != nil { return err } return p.transport.Flush(ctx) } func (p *THeaderProtocol) WriteStructBegin(ctx context.Context, name string) error { return p.protocol.WriteStructBegin(ctx, name) } func (p *THeaderProtocol) WriteStructEnd(ctx context.Context) error { return p.protocol.WriteStructEnd(ctx) } func (p *THeaderProtocol) WriteFieldBegin(ctx context.Context, name string, typeID TType, id int16) error { return p.protocol.WriteFieldBegin(ctx, name, typeID, id) } func (p *THeaderProtocol) WriteFieldEnd(ctx context.Context) error { return p.protocol.WriteFieldEnd(ctx) } func (p *THeaderProtocol) WriteFieldStop(ctx context.Context) error { return p.protocol.WriteFieldStop(ctx) } func (p *THeaderProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { return p.protocol.WriteMapBegin(ctx, keyType, valueType, size) } func (p *THeaderProtocol) WriteMapEnd(ctx context.Context) error { return p.protocol.WriteMapEnd(ctx) } func (p *THeaderProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { return p.protocol.WriteListBegin(ctx, elemType, size) } func (p *THeaderProtocol) WriteListEnd(ctx context.Context) error { return p.protocol.WriteListEnd(ctx) } func (p *THeaderProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { return p.protocol.WriteSetBegin(ctx, elemType, size) } func (p *THeaderProtocol) WriteSetEnd(ctx context.Context) error { return p.protocol.WriteSetEnd(ctx) } func (p *THeaderProtocol) WriteBool(ctx context.Context, value bool) error { return p.protocol.WriteBool(ctx, value) } func (p *THeaderProtocol) WriteByte(ctx context.Context, value int8) error { return p.protocol.WriteByte(ctx, value) } func (p *THeaderProtocol) WriteI16(ctx context.Context, value int16) error { return p.protocol.WriteI16(ctx, value) } func (p *THeaderProtocol) WriteI32(ctx context.Context, value int32) error { return p.protocol.WriteI32(ctx, value) } func (p *THeaderProtocol) WriteI64(ctx context.Context, value int64) error { return p.protocol.WriteI64(ctx, value) } func (p *THeaderProtocol) WriteDouble(ctx context.Context, value float64) error { return p.protocol.WriteDouble(ctx, value) } func (p *THeaderProtocol) WriteString(ctx context.Context, value string) error { return p.protocol.WriteString(ctx, value) } func (p *THeaderProtocol) WriteBinary(ctx context.Context, value []byte) error { return p.protocol.WriteBinary(ctx, value) } func (p *THeaderProtocol) WriteUUID(ctx context.Context, value Tuuid) error { return p.protocol.WriteUUID(ctx, value) } // ReadFrame calls underlying THeaderTransport's ReadFrame function. func (p *THeaderProtocol) ReadFrame(ctx context.Context) error { return p.transport.ReadFrame(ctx) } func (p *THeaderProtocol) ReadMessageBegin(ctx context.Context) (name string, typeID TMessageType, seqID int32, err error) { if err = p.transport.ReadFrame(ctx); err != nil { return } var newProto TProtocol newProto, err = p.transport.Protocol().GetProtocol(p.transport) if err != nil { var tAppExc TApplicationException if !errors.As(err, &tAppExc) { return } if e := p.protocol.WriteMessageBegin(ctx, "", EXCEPTION, seqID); e != nil { return } if e := tAppExc.Write(ctx, p.protocol); e != nil { return } if e := p.protocol.WriteMessageEnd(ctx); e != nil { return } if e := p.transport.Flush(ctx); e != nil { return } return } PropagateTConfiguration(newProto, p.cfg) p.protocol = newProto return p.protocol.ReadMessageBegin(ctx) } func (p *THeaderProtocol) ReadMessageEnd(ctx context.Context) error { return p.protocol.ReadMessageEnd(ctx) } func (p *THeaderProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { return p.protocol.ReadStructBegin(ctx) } func (p *THeaderProtocol) ReadStructEnd(ctx context.Context) error { return p.protocol.ReadStructEnd(ctx) } func (p *THeaderProtocol) ReadFieldBegin(ctx context.Context) (name string, typeID TType, id int16, err error) { return p.protocol.ReadFieldBegin(ctx) } func (p *THeaderProtocol) ReadFieldEnd(ctx context.Context) error { return p.protocol.ReadFieldEnd(ctx) } func (p *THeaderProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) { return p.protocol.ReadMapBegin(ctx) } func (p *THeaderProtocol) ReadMapEnd(ctx context.Context) error { return p.protocol.ReadMapEnd(ctx) } func (p *THeaderProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { return p.protocol.ReadListBegin(ctx) } func (p *THeaderProtocol) ReadListEnd(ctx context.Context) error { return p.protocol.ReadListEnd(ctx) } func (p *THeaderProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { return p.protocol.ReadSetBegin(ctx) } func (p *THeaderProtocol) ReadSetEnd(ctx context.Context) error { return p.protocol.ReadSetEnd(ctx) } func (p *THeaderProtocol) ReadBool(ctx context.Context) (value bool, err error) { return p.protocol.ReadBool(ctx) } func (p *THeaderProtocol) ReadByte(ctx context.Context) (value int8, err error) { return p.protocol.ReadByte(ctx) } func (p *THeaderProtocol) ReadI16(ctx context.Context) (value int16, err error) { return p.protocol.ReadI16(ctx) } func (p *THeaderProtocol) ReadI32(ctx context.Context) (value int32, err error) { return p.protocol.ReadI32(ctx) } func (p *THeaderProtocol) ReadI64(ctx context.Context) (value int64, err error) { return p.protocol.ReadI64(ctx) } func (p *THeaderProtocol) ReadDouble(ctx context.Context) (value float64, err error) { return p.protocol.ReadDouble(ctx) } func (p *THeaderProtocol) ReadString(ctx context.Context) (value string, err error) { return p.protocol.ReadString(ctx) } func (p *THeaderProtocol) ReadBinary(ctx context.Context) (value []byte, err error) { return p.protocol.ReadBinary(ctx) } func (p *THeaderProtocol) ReadUUID(ctx context.Context) (value Tuuid, err error) { return p.protocol.ReadUUID(ctx) } func (p *THeaderProtocol) Skip(ctx context.Context, fieldType TType) error { return p.protocol.Skip(ctx, fieldType) } // SetTConfiguration implements TConfigurationSetter. func (p *THeaderProtocol) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(p.transport, cfg) PropagateTConfiguration(p.protocol, cfg) p.cfg = cfg } var ( _ TConfigurationSetter = (*tHeaderProtocolFactory)(nil) _ TConfigurationSetter = (*THeaderProtocol)(nil) ) thrift-0.23.0/lib/go/thrift/simple_json_protocol_test.go0000664000175000017500000006331715167543515023710 0ustar00buildbuild00000000000000/* * 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 ( "context" "encoding/base64" "encoding/json" "fmt" "math" "strconv" "strings" "testing" ) func TestWriteSimpleJSONProtocolBool(t *testing.T) { thetype := "boolean" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) for _, value := range BOOL_VALUES { if e := p.WriteBool(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := false if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadSimpleJSONProtocolBool(t *testing.T) { thetype := "boolean" for _, value := range BOOL_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) if value { trans.Write(JSON_TRUE) } else { trans.Write(JSON_FALSE) } trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBool(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestWriteSimpleJSONProtocolByte(t *testing.T) { thetype := "byte" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) for _, value := range BYTE_VALUES { if e := p.WriteByte(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int8(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadSimpleJSONProtocolByte(t *testing.T) { thetype := "byte" for _, value := range BYTE_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadByte(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestWriteSimpleJSONProtocolI16(t *testing.T) { thetype := "int16" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) for _, value := range INT16_VALUES { if e := p.WriteI16(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int16(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadSimpleJSONProtocolI16(t *testing.T) { thetype := "int16" for _, value := range INT16_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI16(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestWriteSimpleJSONProtocolI32(t *testing.T) { thetype := "int32" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) for _, value := range INT32_VALUES { if e := p.WriteI32(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int32(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadSimpleJSONProtocolI32(t *testing.T) { thetype := "int32" for _, value := range INT32_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI32(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestReadSimpleJSONProtocolI32Null(t *testing.T) { thetype := "int32" value := "null" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI32(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != 0 { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } trans.Reset() trans.Close() } func TestWriteSimpleJSONProtocolI64(t *testing.T) { thetype := "int64" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) for _, value := range INT64_VALUES { if e := p.WriteI64(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := int64(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() } trans.Close() } func TestReadSimpleJSONProtocolI64(t *testing.T) { thetype := "int64" for _, value := range INT64_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.FormatInt(value, 10)) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI64(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } trans.Reset() trans.Close() } } func TestReadSimpleJSONProtocolI64Null(t *testing.T) { thetype := "int32" value := "null" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI64(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != 0 { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } trans.Reset() trans.Close() } func TestWriteSimpleJSONProtocolDouble(t *testing.T) { thetype := "double" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) for _, value := range DOUBLE_VALUES { if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if math.IsInf(value, 1) { if s != jsonQuote(JSON_INFINITY) { t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, jsonQuote(JSON_INFINITY)) } } else if math.IsInf(value, -1) { if s != jsonQuote(JSON_NEGATIVE_INFINITY) { t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, jsonQuote(JSON_NEGATIVE_INFINITY)) } } else if math.IsNaN(value) { if s != jsonQuote(JSON_NAN) { t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, jsonQuote(JSON_NAN)) } } else { if s != fmt.Sprint(value) { t.Fatalf("Bad value for %s %v: %s", thetype, value, s) } v := float64(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } } trans.Reset() } trans.Close() } func TestReadSimpleJSONProtocolDouble(t *testing.T) { thetype := "double" for _, value := range DOUBLE_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) n := NewNumericFromDouble(value) trans.WriteString(n.String()) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadDouble(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if math.IsInf(value, 1) { if !math.IsInf(v, 1) { t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v) } } else if math.IsInf(value, -1) { if !math.IsInf(v, -1) { t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v) } } else if math.IsNaN(value) { if !math.IsNaN(v) { t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v) } } else { if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } } trans.Reset() trans.Close() } } func TestWriteSimpleJSONProtocolString(t *testing.T) { thetype := "string" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) for _, value := range STRING_VALUES { if e := p.WriteString(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s[0] != '"' || s[len(s)-1] != '"' { t.Fatalf("Bad value for %s '%v', wrote '%v', expected: %v", thetype, value, s, fmt.Sprint("\"", value, "\"")) } v := new(string) if err := json.Unmarshal([]byte(s), v); err != nil || *v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v) } trans.Reset() } trans.Close() } func TestReadSimpleJSONProtocolString(t *testing.T) { thetype := "string" for _, value := range STRING_VALUES { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(jsonQuote(value)) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadString(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != value { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } v1 := new(string) if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1) } trans.Reset() trans.Close() } } func TestReadSimpleJSONProtocolStringNull(t *testing.T) { thetype := "string" value := "null" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadString(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != "" { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } trans.Reset() trans.Close() } func TestWriteSimpleJSONProtocolBinary(t *testing.T) { thetype := "binary" value := protocol_bdata b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata))) base64.StdEncoding.Encode(b64value, value) b64String := string(b64value) trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) if e := p.WriteBinary(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() if s != fmt.Sprint("\"", b64String, "\"") { t.Fatalf("Bad value for %s %v\n wrote: %v\nexpected: %v", thetype, value, s, "\""+b64String+"\"") } v1 := new(string) if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1) } trans.Close() } func TestReadSimpleJSONProtocolBinary(t *testing.T) { thetype := "binary" value := protocol_bdata b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata))) base64.StdEncoding.Encode(b64value, value) b64String := string(b64value) trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(jsonQuote(b64String)) trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBinary(context.Background()) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } 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 := 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]) } } v1 := new(string) if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1) } trans.Reset() trans.Close() } func TestReadSimpleJSONProtocolBinaryNull(t *testing.T) { thetype := "binary" value := "null" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) trans.Flush(context.Background()) s := trans.String() b, e := p.ReadBinary(context.Background()) v := string(b) if e != nil { t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.Error()) } if v != "" { t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v) } trans.Reset() trans.Close() } func TestWriteSimpleJSONProtocolList(t *testing.T) { thetype := "list" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) p.WriteListBegin(context.Background(), TType(DOUBLE), len(DOUBLE_VALUES)) for _, value := range DOUBLE_VALUES { if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } } p.WriteListEnd(context.Background()) if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() str1 := new([]any) err := json.Unmarshal([]byte(str), str1) if err != nil { t.Fatalf("Unable to decode %s, wrote: %s", thetype, str) } l := *str1 if len(l) < 2 { t.Fatalf("List must be at least of length two to include metadata") } if int(l[0].(float64)) != DOUBLE { t.Fatal("Invalid type for list, expected: ", DOUBLE, ", but was: ", l[0]) } if int(l[1].(float64)) != len(DOUBLE_VALUES) { t.Fatal("Invalid length for list, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1]) } for k, value := range DOUBLE_VALUES { s := l[k+2] if math.IsInf(value, 1) { if s.(string) != JSON_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_INFINITY), str) } } else if math.IsInf(value, 0) { if s.(string) != JSON_NEGATIVE_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NEGATIVE_INFINITY), str) } } else if math.IsNaN(value) { if s.(string) != JSON_NAN { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NAN), str) } } else { if s.(float64) != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s) } } trans.Reset() } trans.Close() } func TestWriteSimpleJSONProtocolSet(t *testing.T) { thetype := "set" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) p.WriteSetBegin(context.Background(), TType(DOUBLE), len(DOUBLE_VALUES)) for _, value := range DOUBLE_VALUES { if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } } p.WriteSetEnd(context.Background()) if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() str1 := new([]any) err := json.Unmarshal([]byte(str), str1) if err != nil { t.Fatalf("Unable to decode %s, wrote: %s", thetype, str) } l := *str1 if len(l) < 2 { t.Fatalf("Set must be at least of length two to include metadata") } if int(l[0].(float64)) != DOUBLE { t.Fatal("Invalid type for set, expected: ", DOUBLE, ", but was: ", l[0]) } if int(l[1].(float64)) != len(DOUBLE_VALUES) { t.Fatal("Invalid length for set, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1]) } for k, value := range DOUBLE_VALUES { s := l[k+2] if math.IsInf(value, 1) { if s.(string) != JSON_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_INFINITY), str) } } else if math.IsInf(value, 0) { if s.(string) != JSON_NEGATIVE_INFINITY { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NEGATIVE_INFINITY), str) } } else if math.IsNaN(value) { if s.(string) != JSON_NAN { t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, jsonQuote(JSON_NAN), str) } } else { if s.(float64) != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s) } } trans.Reset() } trans.Close() } func TestWriteSimpleJSONProtocolMap(t *testing.T) { thetype := "map" trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) p.WriteMapBegin(context.Background(), TType(I32), TType(DOUBLE), len(DOUBLE_VALUES)) for k, value := range DOUBLE_VALUES { if e := p.WriteI32(context.Background(), int32(k)); e != nil { t.Fatalf("Unable to write %s key int32 value %v due to error: %s", thetype, k, e.Error()) } if e := p.WriteDouble(context.Background(), value); e != nil { t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.Error()) } } p.WriteMapEnd(context.Background()) if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() if str[0] != '[' || str[len(str)-1] != ']' { t.Fatalf("Bad value for %s, wrote: %v, in go: %v", thetype, str, DOUBLE_VALUES) } l := strings.Split(str[1:len(str)-1], ",") if len(l) < 3 { t.Fatal("Expected list of at least length 3 for map for metadata, but was of length ", len(l)) } expectedKeyType, _ := strconv.Atoi(l[0]) expectedValueType, _ := strconv.Atoi(l[1]) expectedSize, _ := strconv.Atoi(l[2]) if expectedKeyType != I32 { t.Fatal("Expected map key type ", I32, ", but was ", l[0]) } if expectedValueType != DOUBLE { t.Fatal("Expected map value type ", DOUBLE, ", but was ", l[1]) } if expectedSize != len(DOUBLE_VALUES) { t.Fatal("Expected map size of ", len(DOUBLE_VALUES), ", but was ", l[2]) } for k, value := range DOUBLE_VALUES { strk := l[k*2+3] strv := l[k*2+4] ik, err := strconv.Atoi(strk) if err != nil { t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, strk, k, err.Error()) } if ik != k { t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v", thetype, k, strk, k) } s := strv if math.IsInf(value, 1) { if s != jsonQuote(JSON_INFINITY) { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, jsonQuote(JSON_INFINITY)) } } else if math.IsInf(value, 0) { if s != jsonQuote(JSON_NEGATIVE_INFINITY) { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, jsonQuote(JSON_NEGATIVE_INFINITY)) } } else if math.IsNaN(value) { if s != jsonQuote(JSON_NAN) { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, jsonQuote(JSON_NAN)) } } else { expected := strconv.FormatFloat(value, 'g', 10, 64) if s != expected { t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected %v", thetype, k, value, s, expected) } v := float64(0) if err := json.Unmarshal([]byte(s), &v); err != nil || v != value { t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v) } } trans.Reset() } trans.Close() } func TestWriteSimpleJSONProtocolSafePeek(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.Write([]byte{'a', 'b'}) trans.Flush(context.Background()) test1 := p.safePeekContains([]byte{'a', 'b'}) if !test1 { t.Fatalf("Should match at test 1") } test2 := p.safePeekContains([]byte{'a', 'b', 'c', 'd'}) if test2 { t.Fatalf("Should not match at test 2") } test3 := p.safePeekContains([]byte{'x', 'y'}) if test3 { t.Fatalf("Should not match at test 3") } } func TestJSONContextStack(t *testing.T) { var stack jsonContextStack t.Run("empty-peek", func(t *testing.T) { v, ok := stack.peek() if ok { t.Error("peek() on empty should return ok: false") } expected := _CONTEXT_INVALID if v != expected { t.Errorf("Expected value from peek() to be %v(%d), got %v(%d)", expected, expected, v, v) } }) t.Run("empty-pop", func(t *testing.T) { v, ok := stack.pop() if ok { t.Error("pop() on empty should return ok: false") } expected := _CONTEXT_INVALID if v != expected { t.Errorf("Expected value from pop() to be %v(%d), got %v(%d)", expected, expected, v, v) } }) t.Run("push-peek-pop", func(t *testing.T) { expected := _CONTEXT_INVALID stack.push(expected) if len(stack) != 1 { t.Errorf("Expected stack to be as size 1 after push, got %#v", stack) } v, ok := stack.peek() if !ok { t.Error("peek() on non-empty should return ok: true") } if v != expected { t.Errorf("Expected value from peek() to be %v(%d), got %v(%d)", expected, expected, v, v) } if len(stack) != 1 { t.Errorf("Expected peek() to be read-only, got %#v", stack) } v, ok = stack.pop() if !ok { t.Error("pop() on non-empty should return ok: true") } if v != expected { t.Errorf("Expected value from pop() to be %v(%d), got %v(%d)", expected, expected, v, v) } if len(stack) != 0 { t.Errorf("Expected pop() to empty the stack, got %#v", stack) } }) } func TestTSimpleJSONProtocolUnmatchedBeginEnd(t *testing.T) { UnmatchedBeginEndProtocolTest(t, NewTSimpleJSONProtocolFactory()) } thrift-0.23.0/lib/go/thrift/socket_non_unix_conn.go0000664000175000017500000000217215167543515022620 0ustar00buildbuild00000000000000//go:build 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 func (sc *socketConn) read0() error { // On non-unix platforms, we fallback to the default behavior of reading 0 bytes. var p []byte _, err := sc.Conn.Read(p) return err } func (sc *socketConn) checkConn() error { // On non-unix platforms, we always return nil for this check. return nil } thrift-0.23.0/lib/go/thrift/pointerize.go0000664000175000017500000000446215165535636020575 0ustar00buildbuild00000000000000/* * 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 // Pointer is the generic (type parameter) version of the helper function that // converts types to pointer types. func Pointer[T any](v T) *T { return &v } /////////////////////////////////////////////////////////////////////////////// // This file is home to helpers that convert from various base types to // respective pointer types. This is necessary because Go does not permit // references to constants, nor can a pointer type to base type be allocated // and initialized in a single expression. // // E.g., this is not allowed: // // var ip *int = &5 // // But this *is* allowed: // // func IntPtr(i int) *int { return &i } // var ip *int = IntPtr(5) // // Since pointers to base types are commonplace as [optional] fields in // exported thrift structs, we factor such helpers here. /////////////////////////////////////////////////////////////////////////////// func Float32Ptr(v float32) *float32 { return &v } func Float64Ptr(v float64) *float64 { return &v } func IntPtr(v int) *int { return &v } func Int8Ptr(v int8) *int8 { return &v } func Int16Ptr(v int16) *int16 { return &v } func Int32Ptr(v int32) *int32 { return &v } func Int64Ptr(v int64) *int64 { return &v } func StringPtr(v string) *string { return &v } func Uint32Ptr(v uint32) *uint32 { return &v } func Uint64Ptr(v uint64) *uint64 { return &v } func BoolPtr(v bool) *bool { return &v } func ByteSlicePtr(v []byte) *[]byte { return &v } func TuuidPtr(v Tuuid) *Tuuid { return &v } thrift-0.23.0/lib/go/thrift/http_client.go0000664000175000017500000001741115165535636020720 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "context" "errors" "io" "net/http" "net/url" "strconv" ) // Default to using the shared http client. Library users are // free to change this global client or specify one through // THttpClientOptions. var DefaultHttpClient *http.Client = http.DefaultClient type THttpClient struct { client *http.Client response *http.Response url *url.URL requestBuffer *bytes.Buffer header http.Header } type THttpClientTransportFactory struct { options THttpClientOptions url string } func (p *THttpClientTransportFactory) GetTransport(trans TTransport) (TTransport, error) { if trans != nil { t, ok := trans.(*THttpClient) if ok && t.url != nil { return NewTHttpClientWithOptions(t.url.String(), p.options) } } return NewTHttpClientWithOptions(p.url, p.options) } type THttpClientOptions struct { // If nil, DefaultHttpClient is used Client *http.Client } func NewTHttpClientTransportFactory(url string) *THttpClientTransportFactory { return NewTHttpClientTransportFactoryWithOptions(url, THttpClientOptions{}) } func NewTHttpClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory { return &THttpClientTransportFactory{url: url, options: options} } func NewTHttpClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) { parsedURL, err := url.Parse(urlstr) if err != nil { return nil, err } buf := make([]byte, 0, 1024) client := options.Client if client == nil { client = DefaultHttpClient } httpHeader := map[string][]string{"Content-Type": {"application/x-thrift"}} return &THttpClient{client: client, url: parsedURL, requestBuffer: bytes.NewBuffer(buf), header: httpHeader}, nil } func NewTHttpClient(urlstr string) (TTransport, error) { return NewTHttpClientWithOptions(urlstr, THttpClientOptions{}) } // Set the HTTP Header for this specific Thrift Transport // It is important that you first assert the TTransport as a THttpClient type // like so: // // httpTrans := trans.(THttpClient) // httpTrans.SetHeader("User-Agent","Thrift Client 1.0") func (p *THttpClient) SetHeader(key string, value string) { p.header.Add(key, value) } // Get the HTTP Header represented by the supplied Header Key for this specific Thrift Transport // It is important that you first assert the TTransport as a THttpClient type // like so: // // httpTrans := trans.(THttpClient) // hdrValue := httpTrans.GetHeader("User-Agent") func (p *THttpClient) GetHeader(key string) string { return p.header.Get(key) } // Deletes the HTTP Header given a Header Key for this specific Thrift Transport // It is important that you first assert the TTransport as a THttpClient type // like so: // // httpTrans := trans.(THttpClient) // httpTrans.DelHeader("User-Agent") func (p *THttpClient) DelHeader(key string) { p.header.Del(key) } func (p *THttpClient) Open() error { // do nothing return nil } func (p *THttpClient) IsOpen() bool { return p.response != nil || p.requestBuffer != nil } func (p *THttpClient) closeResponse() error { var err error if p.response != nil && p.response.Body != nil { // The docs specify that if keepalive is enabled and the response body is not // read to completion the connection will never be returned to the pool and // reused. Errors are being ignored here because if the connection is invalid // and this fails for some reason, the Close() method will do any remaining // cleanup. io.Copy(io.Discard, p.response.Body) err = p.response.Body.Close() } p.response = nil return err } func (p *THttpClient) Close() error { if p.requestBuffer != nil { p.requestBuffer.Reset() p.requestBuffer = nil } return p.closeResponse() } func (p *THttpClient) Read(buf []byte) (int, error) { if p.response == nil { return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.") } n, err := p.response.Body.Read(buf) if n > 0 && (err == nil || errors.Is(err, io.EOF)) { return n, nil } return n, NewTTransportExceptionFromError(err) } func (p *THttpClient) ReadByte() (c byte, err error) { if p.response == nil { return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.") } return readByte(p.response.Body) } func (p *THttpClient) Write(buf []byte) (int, error) { if p.requestBuffer == nil { return 0, NewTTransportException(NOT_OPEN, "Request buffer is nil, connection may have been closed.") } return p.requestBuffer.Write(buf) } func (p *THttpClient) WriteByte(c byte) error { if p.requestBuffer == nil { return NewTTransportException(NOT_OPEN, "Request buffer is nil, connection may have been closed.") } return p.requestBuffer.WriteByte(c) } func (p *THttpClient) WriteString(s string) (n int, err error) { if p.requestBuffer == nil { return 0, NewTTransportException(NOT_OPEN, "Request buffer is nil, connection may have been closed.") } return p.requestBuffer.WriteString(s) } func (p *THttpClient) Flush(ctx context.Context) error { // Close any previous response body to avoid leaking connections. p.closeResponse() // Give up the ownership of the current request buffer to http request, // and create a new buffer for the next request. buf := p.requestBuffer p.requestBuffer = new(bytes.Buffer) req, err := http.NewRequest("POST", p.url.String(), buf) if err != nil { return NewTTransportExceptionFromError(err) } req.Header = p.header if ctx != nil { req = req.WithContext(ctx) } response, err := p.client.Do(req) if err != nil { return NewTTransportExceptionFromError(err) } if response.StatusCode != http.StatusOK { // Close the response to avoid leaking file descriptors. closeResponse does // more than just call Close(), so temporarily assign it and reuse the logic. p.response = response p.closeResponse() // TODO(pomack) log bad response return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "HTTP Response code: "+strconv.Itoa(response.StatusCode)) } p.response = response return nil } func (p *THttpClient) RemainingBytes() (num_bytes uint64) { len := p.response.ContentLength if len >= 0 { return uint64(len) } const maxSize = ^uint64(0) return maxSize // the truth is, we just don't know unless framed is used } // Deprecated: Use NewTHttpClientTransportFactory instead. func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory { return NewTHttpClientTransportFactoryWithOptions(url, THttpClientOptions{}) } // Deprecated: Use NewTHttpClientTransportFactoryWithOptions instead. func NewTHttpPostClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory { return NewTHttpClientTransportFactoryWithOptions(url, options) } // Deprecated: Use NewTHttpClientWithOptions instead. func NewTHttpPostClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) { return NewTHttpClientWithOptions(urlstr, options) } // Deprecated: Use NewTHttpClient instead. func NewTHttpPostClient(urlstr string) (TTransport, error) { return NewTHttpClientWithOptions(urlstr, THttpClientOptions{}) } thrift-0.23.0/lib/go/thrift/duplicate_protocol.go0000664000175000017500000002466315165535636022305 0ustar00buildbuild00000000000000/* * 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 ( "context" ) type TDuplicateToProtocol struct { // Required. The actual TProtocol to do the read/write. Delegate TProtocol // Required. An TProtocol to duplicate everything read/written from Delegate. // // A typical use case of this is to use TSimpleJSONProtocol wrapping // TMemoryBuffer in a middleware to json logging requests/responses, // or wrapping a TTransport that counts bytes written to get the payload // sizes. // // DuplicateTo will be used as write only. For read calls on // TDuplicateToProtocol, the result read from Delegate will be written // to DuplicateTo. DuplicateTo TProtocol } func (tdtp *TDuplicateToProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error { err := tdtp.Delegate.WriteMessageBegin(ctx, name, typeId, seqid) tdtp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid) return err } func (tdtp *TDuplicateToProtocol) WriteMessageEnd(ctx context.Context) error { err := tdtp.Delegate.WriteMessageEnd(ctx) tdtp.DuplicateTo.WriteMessageEnd(ctx) return err } func (tdtp *TDuplicateToProtocol) WriteStructBegin(ctx context.Context, name string) error { err := tdtp.Delegate.WriteStructBegin(ctx, name) tdtp.DuplicateTo.WriteStructBegin(ctx, name) return err } func (tdtp *TDuplicateToProtocol) WriteStructEnd(ctx context.Context) error { err := tdtp.Delegate.WriteStructEnd(ctx) tdtp.DuplicateTo.WriteStructEnd(ctx) return err } func (tdtp *TDuplicateToProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { err := tdtp.Delegate.WriteFieldBegin(ctx, name, typeId, id) tdtp.DuplicateTo.WriteFieldBegin(ctx, name, typeId, id) return err } func (tdtp *TDuplicateToProtocol) WriteFieldEnd(ctx context.Context) error { err := tdtp.Delegate.WriteFieldEnd(ctx) tdtp.DuplicateTo.WriteFieldEnd(ctx) return err } func (tdtp *TDuplicateToProtocol) WriteFieldStop(ctx context.Context) error { err := tdtp.Delegate.WriteFieldStop(ctx) tdtp.DuplicateTo.WriteFieldStop(ctx) return err } func (tdtp *TDuplicateToProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { err := tdtp.Delegate.WriteMapBegin(ctx, keyType, valueType, size) tdtp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size) return err } func (tdtp *TDuplicateToProtocol) WriteMapEnd(ctx context.Context) error { err := tdtp.Delegate.WriteMapEnd(ctx) tdtp.DuplicateTo.WriteMapEnd(ctx) return err } func (tdtp *TDuplicateToProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { err := tdtp.Delegate.WriteListBegin(ctx, elemType, size) tdtp.DuplicateTo.WriteListBegin(ctx, elemType, size) return err } func (tdtp *TDuplicateToProtocol) WriteListEnd(ctx context.Context) error { err := tdtp.Delegate.WriteListEnd(ctx) tdtp.DuplicateTo.WriteListEnd(ctx) return err } func (tdtp *TDuplicateToProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { err := tdtp.Delegate.WriteSetBegin(ctx, elemType, size) tdtp.DuplicateTo.WriteSetBegin(ctx, elemType, size) return err } func (tdtp *TDuplicateToProtocol) WriteSetEnd(ctx context.Context) error { err := tdtp.Delegate.WriteSetEnd(ctx) tdtp.DuplicateTo.WriteSetEnd(ctx) return err } func (tdtp *TDuplicateToProtocol) WriteBool(ctx context.Context, value bool) error { err := tdtp.Delegate.WriteBool(ctx, value) tdtp.DuplicateTo.WriteBool(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteByte(ctx context.Context, value int8) error { err := tdtp.Delegate.WriteByte(ctx, value) tdtp.DuplicateTo.WriteByte(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteI16(ctx context.Context, value int16) error { err := tdtp.Delegate.WriteI16(ctx, value) tdtp.DuplicateTo.WriteI16(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteI32(ctx context.Context, value int32) error { err := tdtp.Delegate.WriteI32(ctx, value) tdtp.DuplicateTo.WriteI32(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteI64(ctx context.Context, value int64) error { err := tdtp.Delegate.WriteI64(ctx, value) tdtp.DuplicateTo.WriteI64(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteDouble(ctx context.Context, value float64) error { err := tdtp.Delegate.WriteDouble(ctx, value) tdtp.DuplicateTo.WriteDouble(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteString(ctx context.Context, value string) error { err := tdtp.Delegate.WriteString(ctx, value) tdtp.DuplicateTo.WriteString(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteBinary(ctx context.Context, value []byte) error { err := tdtp.Delegate.WriteBinary(ctx, value) tdtp.DuplicateTo.WriteBinary(ctx, value) return err } func (tdtp *TDuplicateToProtocol) WriteUUID(ctx context.Context, value Tuuid) error { err := tdtp.Delegate.WriteUUID(ctx, value) tdtp.DuplicateTo.WriteUUID(ctx, value) return err } func (tdtp *TDuplicateToProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) { name, typeId, seqid, err = tdtp.Delegate.ReadMessageBegin(ctx) tdtp.DuplicateTo.WriteMessageBegin(ctx, name, typeId, seqid) return } func (tdtp *TDuplicateToProtocol) ReadMessageEnd(ctx context.Context) (err error) { err = tdtp.Delegate.ReadMessageEnd(ctx) tdtp.DuplicateTo.WriteMessageEnd(ctx) return } func (tdtp *TDuplicateToProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { name, err = tdtp.Delegate.ReadStructBegin(ctx) tdtp.DuplicateTo.WriteStructBegin(ctx, name) return } func (tdtp *TDuplicateToProtocol) ReadStructEnd(ctx context.Context) (err error) { err = tdtp.Delegate.ReadStructEnd(ctx) tdtp.DuplicateTo.WriteStructEnd(ctx) return } 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 } func (tdtp *TDuplicateToProtocol) ReadFieldEnd(ctx context.Context) (err error) { err = tdtp.Delegate.ReadFieldEnd(ctx) tdtp.DuplicateTo.WriteFieldEnd(ctx) return } func (tdtp *TDuplicateToProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) { keyType, valueType, size, err = tdtp.Delegate.ReadMapBegin(ctx) tdtp.DuplicateTo.WriteMapBegin(ctx, keyType, valueType, size) return } func (tdtp *TDuplicateToProtocol) ReadMapEnd(ctx context.Context) (err error) { err = tdtp.Delegate.ReadMapEnd(ctx) tdtp.DuplicateTo.WriteMapEnd(ctx) return } func (tdtp *TDuplicateToProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { elemType, size, err = tdtp.Delegate.ReadListBegin(ctx) tdtp.DuplicateTo.WriteListBegin(ctx, elemType, size) return } func (tdtp *TDuplicateToProtocol) ReadListEnd(ctx context.Context) (err error) { err = tdtp.Delegate.ReadListEnd(ctx) tdtp.DuplicateTo.WriteListEnd(ctx) return } func (tdtp *TDuplicateToProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { elemType, size, err = tdtp.Delegate.ReadSetBegin(ctx) tdtp.DuplicateTo.WriteSetBegin(ctx, elemType, size) return } func (tdtp *TDuplicateToProtocol) ReadSetEnd(ctx context.Context) (err error) { err = tdtp.Delegate.ReadSetEnd(ctx) tdtp.DuplicateTo.WriteSetEnd(ctx) return } func (tdtp *TDuplicateToProtocol) ReadBool(ctx context.Context) (value bool, err error) { value, err = tdtp.Delegate.ReadBool(ctx) tdtp.DuplicateTo.WriteBool(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadByte(ctx context.Context) (value int8, err error) { value, err = tdtp.Delegate.ReadByte(ctx) tdtp.DuplicateTo.WriteByte(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadI16(ctx context.Context) (value int16, err error) { value, err = tdtp.Delegate.ReadI16(ctx) tdtp.DuplicateTo.WriteI16(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadI32(ctx context.Context) (value int32, err error) { value, err = tdtp.Delegate.ReadI32(ctx) tdtp.DuplicateTo.WriteI32(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadI64(ctx context.Context) (value int64, err error) { value, err = tdtp.Delegate.ReadI64(ctx) tdtp.DuplicateTo.WriteI64(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadDouble(ctx context.Context) (value float64, err error) { value, err = tdtp.Delegate.ReadDouble(ctx) tdtp.DuplicateTo.WriteDouble(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadString(ctx context.Context) (value string, err error) { value, err = tdtp.Delegate.ReadString(ctx) tdtp.DuplicateTo.WriteString(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadBinary(ctx context.Context) (value []byte, err error) { value, err = tdtp.Delegate.ReadBinary(ctx) tdtp.DuplicateTo.WriteBinary(ctx, value) return } func (tdtp *TDuplicateToProtocol) ReadUUID(ctx context.Context) (value Tuuid, err error) { value, err = tdtp.Delegate.ReadUUID(ctx) tdtp.DuplicateTo.WriteUUID(ctx, value) return } func (tdtp *TDuplicateToProtocol) Skip(ctx context.Context, fieldType TType) (err error) { err = tdtp.Delegate.Skip(ctx, fieldType) tdtp.DuplicateTo.Skip(ctx, fieldType) return } func (tdtp *TDuplicateToProtocol) Flush(ctx context.Context) (err error) { err = tdtp.Delegate.Flush(ctx) tdtp.DuplicateTo.Flush(ctx) return } func (tdtp *TDuplicateToProtocol) Transport() TTransport { return tdtp.Delegate.Transport() } // SetTConfiguration implements TConfigurationSetter for propagation. func (tdtp *TDuplicateToProtocol) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(tdtp.Delegate, conf) PropagateTConfiguration(tdtp.DuplicateTo, conf) } var _ TConfigurationSetter = (*TDuplicateToProtocol)(nil) thrift-0.23.0/lib/go/thrift/processor_factory.go0000664000175000017500000000742715165535636022157 0ustar00buildbuild00000000000000/* * 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 ( "context" "fmt" "strings" ) // A processor is a generic object which operates upon an input stream and // writes to some output stream. type TProcessor interface { Process(ctx context.Context, in, out TProtocol) (bool, TException) // ProcessorMap returns a map of thrift method names to TProcessorFunctions. ProcessorMap() map[string]TProcessorFunction // AddToProcessorMap adds the given TProcessorFunction to the internal // processor map at the given key. // // If one is already set at the given key, it will be replaced with the new // TProcessorFunction. AddToProcessorMap(string, TProcessorFunction) } type TProcessorFunction interface { Process(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) } // The default processor factory just returns a singleton // instance. type TProcessorFactory interface { GetProcessor(trans TTransport) TProcessor } type tProcessorFactory struct { processor TProcessor } func NewTProcessorFactory(p TProcessor) TProcessorFactory { return &tProcessorFactory{processor: p} } func (p *tProcessorFactory) GetProcessor(trans TTransport) TProcessor { return p.processor } /** * The default processor factory just returns a singleton * instance. */ type TProcessorFunctionFactory interface { GetProcessorFunction(trans TTransport) TProcessorFunction } type tProcessorFunctionFactory struct { processor TProcessorFunction } func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactory { return &tProcessorFunctionFactory{processor: p} } 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) ) thrift-0.23.0/lib/go/thrift/http_client_test.go0000664000175000017500000000757615165535636021772 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "context" "net/http" "testing" ) func TestHttpClient(t *testing.T) { l, addr := HttpClientSetupForTest(t) if l != nil { defer l.Close() } trans, err := NewTHttpPostClient("http://" + addr.String()) if err != nil { l.Close() t.Fatalf("Unable to connect to %s: %v", addr.String(), err) } TransportTest(t, trans, trans) t.Run("nilBuffer", func(t *testing.T) { _ = trans.Close() if _, err = trans.Write([]byte{1, 2, 3, 4}); err == nil { t.Fatal("writing to a closed transport did not result in an error") } }) } func TestHttpClientHeaders(t *testing.T) { l, addr := HttpClientSetupForTest(t) if l != nil { defer l.Close() } trans, err := NewTHttpPostClient("http://" + addr.String()) if err != nil { l.Close() t.Fatalf("Unable to connect to %s: %v", addr.String(), err) } TransportHeaderTest(t, trans, trans) } func TestHttpCustomClient(t *testing.T) { l, addr := HttpClientSetupForTest(t) if l != nil { defer l.Close() } httpTransport := &customHttpTransport{} trans, err := NewTHttpPostClientWithOptions("http://"+addr.String(), THttpClientOptions{ Client: &http.Client{ Transport: httpTransport, }, }) if err != nil { l.Close() t.Fatalf("Unable to connect to %s: %v", addr.String(), err) } TransportHeaderTest(t, trans, trans) if !httpTransport.hit { t.Fatalf("Custom client was not used") } } func TestHttpCustomClientPackageScope(t *testing.T) { l, addr := HttpClientSetupForTest(t) if l != nil { defer l.Close() } httpTransport := &customHttpTransport{} DefaultHttpClient = &http.Client{ Transport: httpTransport, } trans, err := NewTHttpPostClient("http://" + addr.String()) if err != nil { l.Close() t.Fatalf("Unable to connect to %s: %v", addr.String(), err) } TransportHeaderTest(t, trans, trans) if !httpTransport.hit { t.Fatalf("Custom client was not used") } } func TestHTTPClientFlushesRequestBufferOnErrors(t *testing.T) { var ( write1 = []byte("write 1") write2 = []byte("write 2") ) l, addr := HttpClientSetupForTest(t) if l != nil { defer l.Close() } trans, err := NewTHttpPostClient("http://" + addr.String()) if err != nil { t.Fatalf("Unable to connect to %s: %v", addr.String(), err) } defer trans.Close() _, err = trans.Write(write1) if err != nil { t.Fatalf("Failed to write to transport: %v", err) } ctx, cancel := context.WithCancel(context.Background()) cancel() err = trans.Flush(ctx) if err == nil { t.Fatal("Expected flush error") } _, err = trans.Write(write2) if err != nil { t.Fatalf("Failed to write to transport: %v", err) } err = trans.Flush(context.Background()) if err != nil { t.Fatalf("Failed to flush: %v", err) } data := make([]byte, 1024) n, err := trans.Read(data) if err != nil { t.Fatalf("Failed to read: %v", err) } data = data[:n] if !bytes.Equal(data, write2) { t.Fatalf("Received unexpected data: %q, expected: %q", data, write2) } } type customHttpTransport struct { hit bool } func (c *customHttpTransport) RoundTrip(req *http.Request) (*http.Response, error) { c.hit = true return http.DefaultTransport.RoundTrip(req) } thrift-0.23.0/lib/go/thrift/multiplexed_protocol.go0000664000175000017500000002003215167543515022646 0ustar00buildbuild00000000000000/* * 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 ( "context" "fmt" "maps" "strings" ) /* TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift client to communicate with a multiplexing Thrift server, by prepending the service name to the function name during function calls. NOTE: THIS IS NOT USED BY SERVERS. On the server, use TMultiplexedProcessor to handle request from a multiplexing client. This example uses a single socket transport to invoke two services: socket := thrift.NewTSocketFromAddrTimeout(addr, TIMEOUT) transport := thrift.NewTFramedTransport(socket) protocol := thrift.NewTBinaryProtocolTransport(transport) mp := thrift.NewTMultiplexedProtocol(protocol, "Calculator") service := Calculator.NewCalculatorClient(mp) mp2 := thrift.NewTMultiplexedProtocol(protocol, "WeatherReport") service2 := WeatherReport.NewWeatherReportClient(mp2) err := transport.Open() if err != nil { t.Fatal("Unable to open client socket", err) } fmt.Println(service.Add(2,2)) fmt.Println(service2.GetTemperature()) */ type TMultiplexedProtocol struct { TProtocol serviceName string } const MULTIPLEXED_SEPARATOR = ":" func NewTMultiplexedProtocol(protocol TProtocol, serviceName string) *TMultiplexedProtocol { return &TMultiplexedProtocol{ TProtocol: protocol, serviceName: serviceName, } } func (t *TMultiplexedProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error { if typeId == CALL || typeId == ONEWAY { return t.TProtocol.WriteMessageBegin(ctx, t.serviceName+MULTIPLEXED_SEPARATOR+name, typeId, seqid) } else { return t.TProtocol.WriteMessageBegin(ctx, name, typeId, seqid) } } /* TMultiplexedProcessor is a TProcessor allowing a single TServer to provide multiple services. To do so, you instantiate the processor and then register additional processors with it, as shown in the following example: var processor = thrift.NewTMultiplexedProcessor() firstProcessor := processor.RegisterProcessor("FirstService", firstProcessor) processor.registerProcessor( "Calculator", Calculator.NewCalculatorProcessor(&CalculatorHandler{}), ) processor.registerProcessor( "WeatherReport", WeatherReport.NewWeatherReportProcessor(&WeatherReportHandler{}), ) serverTransport, err := thrift.NewTServerSocketTimeout(addr, TIMEOUT) if err != nil { t.Fatal("Unable to create server socket", err) } server := thrift.NewTSimpleServer2(processor, serverTransport) server.Serve(); */ type TMultiplexedProcessor struct { serviceProcessorMap map[string]TProcessor DefaultProcessor TProcessor } func NewTMultiplexedProcessor() *TMultiplexedProcessor { return &TMultiplexedProcessor{ serviceProcessorMap: make(map[string]TProcessor), } } // ProcessorMap returns a mapping of "{ProcessorName}{MULTIPLEXED_SEPARATOR}{FunctionName}" // to TProcessorFunction for any registered processors. If there is also a // DefaultProcessor, the keys for the methods on that processor will simply be // "{FunctionName}". If the TMultiplexedProcessor has both a DefaultProcessor and // other registered processors, then the keys will be a mix of both formats. // // The implementation differs with other TProcessors in that the map returned is // a new map, while most TProcessors just return their internal mapping directly. // This means that edits to the map returned by this implementation of ProcessorMap // will not affect the underlying mapping within the TMultiplexedProcessor. func (t *TMultiplexedProcessor) ProcessorMap() map[string]TProcessorFunction { processorFuncMap := make(map[string]TProcessorFunction) for name, processor := range t.serviceProcessorMap { for method, processorFunc := range processor.ProcessorMap() { processorFuncName := name + MULTIPLEXED_SEPARATOR + method processorFuncMap[processorFuncName] = processorFunc } } if t.DefaultProcessor != nil { maps.Copy(processorFuncMap, t.DefaultProcessor.ProcessorMap()) } return processorFuncMap } // AddToProcessorMap updates the underlying TProcessor ProccessorMaps depending on // the format of "name". // // If "name" is in the format "{ProcessorName}{MULTIPLEXED_SEPARATOR}{FunctionName}", // then it sets the given TProcessorFunction on the inner TProcessor with the // ProcessorName component using the FunctionName component. // // If "name" is just in the format "{FunctionName}", that is to say there is no // MULTIPLEXED_SEPARATOR, and the TMultiplexedProcessor has a DefaultProcessor // configured, then it will set the given TProcessorFunction on the DefaultProcessor // using the given name. // // If there is not a TProcessor available for the given name, then this function // does nothing. This can happen when there is no TProcessor registered for // the given ProcessorName or if all that is given is the FunctionName and there // is no DefaultProcessor set. func (t *TMultiplexedProcessor) AddToProcessorMap(name string, processorFunc TProcessorFunction) { components := strings.SplitN(name, MULTIPLEXED_SEPARATOR, 2) if len(components) != 2 { if t.DefaultProcessor != nil && len(components) == 1 { t.DefaultProcessor.AddToProcessorMap(components[0], processorFunc) } return } processorName := components[0] funcName := components[1] if processor, ok := t.serviceProcessorMap[processorName]; ok { processor.AddToProcessorMap(funcName, processorFunc) } } // verify that TMultiplexedProcessor implements TProcessor var _ TProcessor = (*TMultiplexedProcessor)(nil) func (t *TMultiplexedProcessor) RegisterDefault(processor TProcessor) { t.DefaultProcessor = processor } func (t *TMultiplexedProcessor) RegisterProcessor(name string, processor TProcessor) { if t.serviceProcessorMap == nil { t.serviceProcessorMap = make(map[string]TProcessor) } t.serviceProcessorMap[name] = processor } func (t *TMultiplexedProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { name, typeId, seqid, err := in.ReadMessageBegin(ctx) if err != nil { return false, NewTProtocolException(err) } if typeId != CALL && typeId != ONEWAY { return false, NewTProtocolException(fmt.Errorf("Unexpected message type %v", typeId)) } //extract the service name v := strings.SplitN(name, MULTIPLEXED_SEPARATOR, 2) if len(v) != 2 { if t.DefaultProcessor != nil { smb := NewStoredMessageProtocol(in, name, typeId, seqid) return t.DefaultProcessor.Process(ctx, smb, out) } return false, NewTProtocolException(fmt.Errorf( "Service name not found in message name: %s. Did you forget to use a TMultiplexProtocol in your client?", name, )) } actualProcessor, ok := t.serviceProcessorMap[v[0]] if !ok { return false, NewTProtocolException(fmt.Errorf( "Service name not found: %s. Did you forget to call registerProcessor()?", v[0], )) } smb := NewStoredMessageProtocol(in, v[1], typeId, seqid) return actualProcessor.Process(ctx, smb, out) } // Protocol that use stored message for ReadMessageBegin type storedMessageProtocol struct { TProtocol name string typeId TMessageType seqid int32 } func NewStoredMessageProtocol(protocol TProtocol, name string, typeId TMessageType, seqid int32) *storedMessageProtocol { return &storedMessageProtocol{protocol, name, typeId, seqid} } func (s *storedMessageProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) { return s.name, s.typeId, s.seqid, nil } thrift-0.23.0/lib/go/thrift/common_test.go0000664000175000017500000000701015165535636020724 0ustar00buildbuild00000000000000/* * 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 ( "context" "fmt" ) type mockProcessor struct { ProcessFunc func(in, out TProtocol) (bool, TException) } func (m *mockProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { return m.ProcessFunc(in, out) } func (m *mockProcessor) ProcessorMap() map[string]TProcessorFunction { return map[string]TProcessorFunction{ "mock": WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { return m.ProcessFunc(in, out) }, }, } } func (m *mockProcessor) AddToProcessorMap(name string, processorFunc TProcessorFunction) {} type mockWrappedProcessorContextKey int const ( processorName mockWrappedProcessorContextKey = iota ) // setMockWrappableProcessorName sets the "name" of the TProcessorFunction to // call on a mockWrappableProcessor when calling Process. // // In a normal TProcessor, the request name is read from the request itself // which happens in TProcessor.Process, so it is not passed into the call to // Process itself, to get around this in testing, mockWrappableProcessor calls // getMockWrappableProcessorName to get the name to use from the context // object. func setMockWrappableProcessorName(ctx context.Context, name string) context.Context { return context.WithValue(ctx, processorName, name) } // getMockWrappableProcessorName gets the "name" of the TProcessorFunction to // call on a mockWrappableProcessor when calling Process. func getMockWrappableProcessorName(ctx context.Context) (string, bool) { val, ok := ctx.Value(processorName).(string) return val, ok } // mockWrappableProcessor can be used to create a mock object that fufills the // TProcessor interface in testing. type mockWrappableProcessor struct { ProcessorFuncs map[string]TProcessorFunction } // Process calls the TProcessorFunction assigned to the "name" set on the // context object by setMockWrappableProcessorName. // // If no name is set on the context or there is no TProcessorFunction mapped to // that name, the call will panic. func (p *mockWrappableProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { name, ok := getMockWrappableProcessorName(ctx) if !ok { panic("MockWrappableProcessorName not set on context") } processor, ok := p.ProcessorMap()[name] if !ok { panic(fmt.Sprintf("No processor set for name %q", name)) } return processor.Process(ctx, 0, in, out) } func (p *mockWrappableProcessor) ProcessorMap() map[string]TProcessorFunction { return p.ProcessorFuncs } func (p *mockWrappableProcessor) AddToProcessorMap(name string, processorFunc TProcessorFunction) { p.ProcessorFuncs[name] = processorFunc } var ( _ TProcessor = (*mockProcessor)(nil) _ TProcessor = (*mockWrappableProcessor)(nil) ) thrift-0.23.0/lib/go/thrift/application_exception.go0000664000175000017500000001270715165535636022767 0ustar00buildbuild00000000000000/* * 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 ( "context" "strings" ) const ( UNKNOWN_APPLICATION_EXCEPTION = 0 UNKNOWN_METHOD = 1 INVALID_MESSAGE_TYPE_EXCEPTION = 2 WRONG_METHOD_NAME = 3 BAD_SEQUENCE_ID = 4 MISSING_RESULT = 5 INTERNAL_ERROR = 6 PROTOCOL_ERROR = 7 INVALID_TRANSFORM = 8 INVALID_PROTOCOL = 9 UNSUPPORTED_CLIENT_TYPE = 10 VALIDATION_FAILED = 11 ) var defaultApplicationExceptionMessage = map[int32]string{ UNKNOWN_APPLICATION_EXCEPTION: "unknown application exception", UNKNOWN_METHOD: "unknown method", INVALID_MESSAGE_TYPE_EXCEPTION: "invalid message type", WRONG_METHOD_NAME: "wrong method name", BAD_SEQUENCE_ID: "bad sequence ID", MISSING_RESULT: "missing result", INTERNAL_ERROR: "unknown internal error", PROTOCOL_ERROR: "unknown protocol error", INVALID_TRANSFORM: "Invalid transform", INVALID_PROTOCOL: "Invalid protocol", UNSUPPORTED_CLIENT_TYPE: "Unsupported client type", VALIDATION_FAILED: "validation failed", } // Application level Thrift exception type TApplicationException interface { TException TypeId() int32 Read(ctx context.Context, iprot TProtocol) error Write(ctx context.Context, oprot TProtocol) error } type ValidationError struct { message string check string fieldSymbol string } func (e *ValidationError) Check() string { return e.check } func (e *ValidationError) TypeName() string { return strings.Split(e.fieldSymbol, ".")[0] } func (e *ValidationError) Field() string { if fs := strings.Split(e.fieldSymbol, "."); len(fs) > 1 { return fs[1] } return e.fieldSymbol } func (e *ValidationError) FieldSymbol() string { return e.fieldSymbol } func (e ValidationError) Error() string { return e.message } type tApplicationException struct { message string type_ int32 err error } var _ TApplicationException = (*tApplicationException)(nil) func (tApplicationException) TExceptionType() TExceptionType { return TExceptionTypeApplication } func (e tApplicationException) Error() string { if e.message != "" { return e.message } return defaultApplicationExceptionMessage[e.type_] } func (e tApplicationException) Unwrap() error { return e.err } func NewTApplicationException(type_ int32, message string) TApplicationException { return &tApplicationException{message, type_, nil} } func NewValidationException(type_ int32, check string, field string, message string) TApplicationException { return &tApplicationException{ type_: type_, message: message, err: &ValidationError{message: message, check: check, fieldSymbol: field}, } } func (p *tApplicationException) TypeId() int32 { return p.type_ } func (p *tApplicationException) Read(ctx context.Context, iprot TProtocol) error { // TODO: this should really be generated by the compiler _, err := iprot.ReadStructBegin(ctx) if err != nil { return err } message := "" type_ := int32(UNKNOWN_APPLICATION_EXCEPTION) for { _, ttype, id, err := iprot.ReadFieldBegin(ctx) if err != nil { return err } if ttype == STOP { break } switch id { case 1: if ttype == STRING { if message, err = iprot.ReadString(ctx); err != nil { return err } } else { if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil { return err } } case 2: if ttype == I32 { if type_, err = iprot.ReadI32(ctx); err != nil { return err } } else { if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil { return err } } default: if err = SkipDefaultDepth(ctx, iprot, ttype); err != nil { return err } } if err = iprot.ReadFieldEnd(ctx); err != nil { return err } } if err := iprot.ReadStructEnd(ctx); err != nil { return err } p.message = message p.type_ = type_ return nil } func (p *tApplicationException) Write(ctx context.Context, oprot TProtocol) (err error) { err = oprot.WriteStructBegin(ctx, "TApplicationException") if err != nil { return } if len(p.Error()) > 0 { err = oprot.WriteFieldBegin(ctx, "message", STRING, 1) if err != nil { return } err = oprot.WriteString(ctx, p.Error()) if err != nil { return } err = oprot.WriteFieldEnd(ctx) if err != nil { return } } err = oprot.WriteFieldBegin(ctx, "type", I32, 2) if err != nil { return } err = oprot.WriteI32(ctx, p.type_) if err != nil { return } err = oprot.WriteFieldEnd(ctx) if err != nil { return } err = oprot.WriteFieldStop(ctx) if err != nil { return } err = oprot.WriteStructEnd(ctx) return } thrift-0.23.0/lib/go/thrift/serializer_types_test.go0000664000175000017500000004360215165535636023040 0ustar00buildbuild00000000000000/* * 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 // Autogenerated by Thrift Compiler (FIXME) // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING /* THE FOLLOWING THRIFT FILE WAS USED TO CREATE THIS enum MyTestEnum { FIRST = 1, SECOND = 2, THIRD = 3, FOURTH = 4, } struct MyTestStruct { 1: bool on, 2: byte b, 3: i16 int16, 4: i32 int32, 5: i64 int64, 6: double d, 7: string st, 8: binary bin, 9: map stringMap, 10: list stringList, 11: set stringSet, 12: MyTestEnum e, } */ import ( "context" "fmt" ) // (needed to ensure safety because of naive import list construction.) var _ = ZERO var _ = fmt.Printf var GoUnusedProtection__ int type MyTestEnum int64 const ( MyTestEnum_FIRST MyTestEnum = 1 MyTestEnum_SECOND MyTestEnum = 2 MyTestEnum_THIRD MyTestEnum = 3 MyTestEnum_FOURTH MyTestEnum = 4 ) func (p MyTestEnum) String() string { switch p { case MyTestEnum_FIRST: return "FIRST" case MyTestEnum_SECOND: return "SECOND" case MyTestEnum_THIRD: return "THIRD" case MyTestEnum_FOURTH: return "FOURTH" } return "" } func MyTestEnumFromString(s string) (MyTestEnum, error) { switch s { case "FIRST": return MyTestEnum_FIRST, nil case "SECOND": return MyTestEnum_SECOND, nil case "THIRD": return MyTestEnum_THIRD, nil case "FOURTH": return MyTestEnum_FOURTH, nil } return MyTestEnum(0), fmt.Errorf("not a valid MyTestEnum string") } func MyTestEnumPtr(v MyTestEnum) *MyTestEnum { return &v } type MyTestStruct struct { On bool `thrift:"on,1" json:"on"` B int8 `thrift:"b,2" json:"b"` Int16 int16 `thrift:"int16,3" json:"int16"` Int32 int32 `thrift:"int32,4" json:"int32"` Int64 int64 `thrift:"int64,5" json:"int64"` D float64 `thrift:"d,6" json:"d"` St string `thrift:"st,7" json:"st"` Bin []byte `thrift:"bin,8" json:"bin"` StringMap map[string]string `thrift:"stringMap,9" json:"stringMap"` StringList []string `thrift:"stringList,10" json:"stringList"` StringSet map[string]struct{} `thrift:"stringSet,11" json:"stringSet"` E MyTestEnum `thrift:"e,12" json:"e"` } func NewMyTestStruct() *MyTestStruct { return &MyTestStruct{} } func (p *MyTestStruct) GetOn() bool { return p.On } func (p *MyTestStruct) GetB() int8 { return p.B } func (p *MyTestStruct) GetInt16() int16 { return p.Int16 } func (p *MyTestStruct) GetInt32() int32 { return p.Int32 } func (p *MyTestStruct) GetInt64() int64 { return p.Int64 } func (p *MyTestStruct) GetD() float64 { return p.D } func (p *MyTestStruct) GetSt() string { return p.St } func (p *MyTestStruct) GetBin() []byte { return p.Bin } func (p *MyTestStruct) GetStringMap() map[string]string { return p.StringMap } func (p *MyTestStruct) GetStringList() []string { return p.StringList } func (p *MyTestStruct) GetStringSet() map[string]struct{} { return p.StringSet } func (p *MyTestStruct) GetE() MyTestEnum { return p.E } func (p *MyTestStruct) Read(ctx context.Context, iprot TProtocol) error { if _, err := iprot.ReadStructBegin(ctx); err != nil { return PrependError(fmt.Sprintf("%T read error: ", p), err) } for { _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin(ctx) if err != nil { return PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) } if fieldTypeId == STOP { break } switch fieldId { case 1: if err := p.readField1(ctx, iprot); err != nil { return err } case 2: if err := p.readField2(ctx, iprot); err != nil { return err } case 3: if err := p.readField3(ctx, iprot); err != nil { return err } case 4: if err := p.readField4(ctx, iprot); err != nil { return err } case 5: if err := p.readField5(ctx, iprot); err != nil { return err } case 6: if err := p.readField6(ctx, iprot); err != nil { return err } case 7: if err := p.readField7(ctx, iprot); err != nil { return err } case 8: if err := p.readField8(ctx, iprot); err != nil { return err } case 9: if err := p.readField9(ctx, iprot); err != nil { return err } case 10: if err := p.readField10(ctx, iprot); err != nil { return err } case 11: if err := p.readField11(ctx, iprot); err != nil { return err } case 12: if err := p.readField12(ctx, iprot); err != nil { return err } default: if err := iprot.Skip(ctx, fieldTypeId); err != nil { return err } } if err := iprot.ReadFieldEnd(ctx); err != nil { return err } } if err := iprot.ReadStructEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T read struct end error: ", p), err) } return nil } func (p *MyTestStruct) readField1(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadBool(ctx); err != nil { return PrependError("error reading field 1: ", err) } else { p.On = v } return nil } func (p *MyTestStruct) readField2(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadByte(ctx); err != nil { return PrependError("error reading field 2: ", err) } else { temp := int8(v) p.B = temp } return nil } func (p *MyTestStruct) readField3(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadI16(ctx); err != nil { return PrependError("error reading field 3: ", err) } else { p.Int16 = v } return nil } func (p *MyTestStruct) readField4(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadI32(ctx); err != nil { return PrependError("error reading field 4: ", err) } else { p.Int32 = v } return nil } func (p *MyTestStruct) readField5(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadI64(ctx); err != nil { return PrependError("error reading field 5: ", err) } else { p.Int64 = v } return nil } func (p *MyTestStruct) readField6(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadDouble(ctx); err != nil { return PrependError("error reading field 6: ", err) } else { p.D = v } return nil } func (p *MyTestStruct) readField7(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 7: ", err) } else { p.St = v } return nil } func (p *MyTestStruct) readField8(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadBinary(ctx); err != nil { return PrependError("error reading field 8: ", err) } else { p.Bin = v } return nil } func (p *MyTestStruct) readField9(ctx context.Context, iprot TProtocol) error { _, _, size, err := iprot.ReadMapBegin(ctx) if err != nil { return PrependError("error reading map begin: ", err) } tMap := make(map[string]string, size) p.StringMap = tMap for range size { var _key0 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) } else { _key0 = v } var _val1 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) } else { _val1 = v } p.StringMap[_key0] = _val1 } if err := iprot.ReadMapEnd(ctx); err != nil { return PrependError("error reading map end: ", err) } return nil } func (p *MyTestStruct) readField10(ctx context.Context, iprot TProtocol) error { _, size, err := iprot.ReadListBegin(ctx) if err != nil { return PrependError("error reading list begin: ", err) } tSlice := make([]string, 0, size) p.StringList = tSlice for range size { var _elem2 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) } else { _elem2 = v } p.StringList = append(p.StringList, _elem2) } if err := iprot.ReadListEnd(ctx); err != nil { return PrependError("error reading list end: ", err) } return nil } func (p *MyTestStruct) readField11(ctx context.Context, iprot TProtocol) error { _, size, err := iprot.ReadSetBegin(ctx) if err != nil { return PrependError("error reading set begin: ", err) } tSet := make(map[string]struct{}, size) p.StringSet = tSet for range size { var _elem3 string if v, err := iprot.ReadString(ctx); err != nil { return PrependError("error reading field 0: ", err) } else { _elem3 = v } p.StringSet[_elem3] = struct{}{} } if err := iprot.ReadSetEnd(ctx); err != nil { return PrependError("error reading set end: ", err) } return nil } func (p *MyTestStruct) readField12(ctx context.Context, iprot TProtocol) error { if v, err := iprot.ReadI32(ctx); err != nil { return PrependError("error reading field 12: ", err) } else { temp := MyTestEnum(v) p.E = temp } return nil } func (p *MyTestStruct) Write(ctx context.Context, oprot TProtocol) error { if err := oprot.WriteStructBegin(ctx, "MyTestStruct"); err != nil { return PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) } if err := p.writeField1(ctx, oprot); err != nil { return err } if err := p.writeField2(ctx, oprot); err != nil { return err } if err := p.writeField3(ctx, oprot); err != nil { return err } if err := p.writeField4(ctx, oprot); err != nil { return err } if err := p.writeField5(ctx, oprot); err != nil { return err } if err := p.writeField6(ctx, oprot); err != nil { return err } if err := p.writeField7(ctx, oprot); err != nil { return err } if err := p.writeField8(ctx, oprot); err != nil { return err } if err := p.writeField9(ctx, oprot); err != nil { return err } if err := p.writeField10(ctx, oprot); err != nil { return err } if err := p.writeField11(ctx, oprot); err != nil { return err } if err := p.writeField12(ctx, oprot); err != nil { return err } if err := oprot.WriteFieldStop(ctx); err != nil { return PrependError("write field stop error: ", err) } if err := oprot.WriteStructEnd(ctx); err != nil { return PrependError("write struct stop error: ", err) } return nil } func (p *MyTestStruct) writeField1(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "on", BOOL, 1); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 1:on: ", p), err) } if err := oprot.WriteBool(ctx, bool(p.On)); err != nil { return PrependError(fmt.Sprintf("%T.on (1) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 1:on: ", p), err) } return err } func (p *MyTestStruct) writeField2(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "b", BYTE, 2); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 2:b: ", p), err) } if err := oprot.WriteByte(ctx, int8(p.B)); err != nil { return PrependError(fmt.Sprintf("%T.b (2) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 2:b: ", p), err) } return err } func (p *MyTestStruct) writeField3(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "int16", I16, 3); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 3:int16: ", p), err) } if err := oprot.WriteI16(ctx, int16(p.Int16)); err != nil { return PrependError(fmt.Sprintf("%T.int16 (3) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 3:int16: ", p), err) } return err } func (p *MyTestStruct) writeField4(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "int32", I32, 4); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 4:int32: ", p), err) } if err := oprot.WriteI32(ctx, int32(p.Int32)); err != nil { return PrependError(fmt.Sprintf("%T.int32 (4) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 4:int32: ", p), err) } return err } func (p *MyTestStruct) writeField5(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "int64", I64, 5); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 5:int64: ", p), err) } if err := oprot.WriteI64(ctx, int64(p.Int64)); err != nil { return PrependError(fmt.Sprintf("%T.int64 (5) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 5:int64: ", p), err) } return err } func (p *MyTestStruct) writeField6(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "d", DOUBLE, 6); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 6:d: ", p), err) } if err := oprot.WriteDouble(ctx, float64(p.D)); err != nil { return PrependError(fmt.Sprintf("%T.d (6) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 6:d: ", p), err) } return err } func (p *MyTestStruct) writeField7(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "st", STRING, 7); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 7:st: ", p), err) } if err := oprot.WriteString(ctx, string(p.St)); err != nil { return PrependError(fmt.Sprintf("%T.st (7) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 7:st: ", p), err) } return err } func (p *MyTestStruct) writeField8(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "bin", STRING, 8); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 8:bin: ", p), err) } if err := oprot.WriteBinary(ctx, p.Bin); err != nil { return PrependError(fmt.Sprintf("%T.bin (8) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 8:bin: ", p), err) } return err } func (p *MyTestStruct) writeField9(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "stringMap", MAP, 9); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 9:stringMap: ", p), err) } if err := oprot.WriteMapBegin(ctx, STRING, STRING, len(p.StringMap)); err != nil { return PrependError("error writing map begin: ", err) } for k, v := range p.StringMap { if err := oprot.WriteString(ctx, string(k)); err != nil { return PrependError(fmt.Sprintf("%T. (0) field write error: ", p), err) } if err := oprot.WriteString(ctx, string(v)); err != nil { return PrependError(fmt.Sprintf("%T. (0) field write error: ", p), err) } } if err := oprot.WriteMapEnd(ctx); err != nil { return PrependError("error writing map end: ", err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 9:stringMap: ", p), err) } return err } func (p *MyTestStruct) writeField10(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "stringList", LIST, 10); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 10:stringList: ", p), err) } if err := oprot.WriteListBegin(ctx, STRING, len(p.StringList)); err != nil { return PrependError("error writing list begin: ", err) } for _, v := range p.StringList { if err := oprot.WriteString(ctx, string(v)); err != nil { return PrependError(fmt.Sprintf("%T. (0) field write error: ", p), err) } } if err := oprot.WriteListEnd(ctx); err != nil { return PrependError("error writing list end: ", err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 10:stringList: ", p), err) } return err } func (p *MyTestStruct) writeField11(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "stringSet", SET, 11); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 11:stringSet: ", p), err) } if err := oprot.WriteSetBegin(ctx, STRING, len(p.StringSet)); err != nil { return PrependError("error writing set begin: ", err) } for v := range p.StringSet { if err := oprot.WriteString(ctx, string(v)); err != nil { return PrependError(fmt.Sprintf("%T. (0) field write error: ", p), err) } } if err := oprot.WriteSetEnd(ctx); err != nil { return PrependError("error writing set end: ", err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 11:stringSet: ", p), err) } return err } func (p *MyTestStruct) writeField12(ctx context.Context, oprot TProtocol) (err error) { if err := oprot.WriteFieldBegin(ctx, "e", I32, 12); err != nil { return PrependError(fmt.Sprintf("%T write field begin error 12:e: ", p), err) } if err := oprot.WriteI32(ctx, int32(p.E)); err != nil { return PrependError(fmt.Sprintf("%T.e (12) field write error: ", p), err) } if err := oprot.WriteFieldEnd(ctx); err != nil { return PrependError(fmt.Sprintf("%T write field end error 12:e: ", p), err) } return err } func (p *MyTestStruct) String() string { if p == nil { return "" } return fmt.Sprintf("MyTestStruct(%+v)", *p) } thrift-0.23.0/lib/go/thrift/simple_server.go0000664000175000017500000002742215167543515021262 0ustar00buildbuild00000000000000/* * 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 ( "context" "errors" "io" "log/slog" "sync" "sync/atomic" "time" ) // ServerConnectivityCheckInterval defines the ticker interval used by // connectivity check in thrift compiled TProcessorFunc implementations. // // It's defined as a variable instead of constant, so that thrift server // implementations can change its value to control the behavior. // // If it's changed to <=0, the feature will be disabled. var ServerConnectivityCheckInterval = time.Millisecond * 5 // ServerStopTimeout defines max stop wait duration used by // server stop to avoid hanging too long to wait for all client connections to be closed gracefully. // // It's defined as a variable instead of constant, so that thrift server // implementations can change its value to control the behavior. // // If it's set to <=0, the feature will be disabled(by default), and the server will wait for // for all the client connections to be closed gracefully. var ServerStopTimeout = time.Duration(0) /* * This is not a typical TSimpleServer as it is not blocked after accept a socket. * It is more like a TThreadedServer that can handle different connections in different goroutines. * This will work if golang user implements a conn-pool like thing in client side. */ type TSimpleServer struct { closed atomic.Int32 wg sync.WaitGroup mu sync.Mutex stopChan chan struct{} processorFactory TProcessorFactory serverTransport TServerTransport inputTransportFactory TTransportFactory outputTransportFactory TTransportFactory inputProtocolFactory TProtocolFactory outputProtocolFactory TProtocolFactory // Headers to auto forward in THeaderProtocol forwardHeaders []string logContext atomic.Pointer[context.Context] } func NewTSimpleServer2(processor TProcessor, serverTransport TServerTransport) *TSimpleServer { return NewTSimpleServerFactory2(NewTProcessorFactory(processor), serverTransport) } func NewTSimpleServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer { return NewTSimpleServerFactory4(NewTProcessorFactory(processor), serverTransport, transportFactory, protocolFactory, ) } func NewTSimpleServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer { return NewTSimpleServerFactory6(NewTProcessorFactory(processor), serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, ) } func NewTSimpleServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TSimpleServer { return NewTSimpleServerFactory6(processorFactory, serverTransport, NewTTransportFactory(), NewTTransportFactory(), NewTBinaryProtocolFactoryDefault(), NewTBinaryProtocolFactoryDefault(), ) } func NewTSimpleServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer { return NewTSimpleServerFactory6(processorFactory, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, ) } func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer { return &TSimpleServer{ processorFactory: processorFactory, serverTransport: serverTransport, inputTransportFactory: inputTransportFactory, outputTransportFactory: outputTransportFactory, inputProtocolFactory: inputProtocolFactory, outputProtocolFactory: outputProtocolFactory, stopChan: make(chan struct{}), } } func (p *TSimpleServer) ProcessorFactory() TProcessorFactory { return p.processorFactory } func (p *TSimpleServer) ServerTransport() TServerTransport { return p.serverTransport } func (p *TSimpleServer) InputTransportFactory() TTransportFactory { return p.inputTransportFactory } func (p *TSimpleServer) OutputTransportFactory() TTransportFactory { return p.outputTransportFactory } func (p *TSimpleServer) InputProtocolFactory() TProtocolFactory { return p.inputProtocolFactory } func (p *TSimpleServer) OutputProtocolFactory() TProtocolFactory { return p.outputProtocolFactory } func (p *TSimpleServer) Listen() error { return p.serverTransport.Listen() } // SetForwardHeaders sets the list of header keys that will be auto forwarded // while using THeaderProtocol. // // "forward" means that when the server is also a client to other upstream // thrift servers, the context object user gets in the processor functions will // have both read and write headers set, with write headers being forwarded. // Users can always override the write headers by calling SetWriteHeaderList // before calling thrift client functions. func (p *TSimpleServer) SetForwardHeaders(headers []string) { size := len(headers) if size == 0 { p.forwardHeaders = nil return } keys := make([]string, size) copy(keys, headers) p.forwardHeaders = keys } // SetLogger sets the logger used by this TSimpleServer. // // If no logger was set before Serve is called, a default logger using standard // log library will be used. // // Deprecated: The logging inside TSimpleServer is now done via slog on error // level, this does nothing now. It will be removed in a future version. func (p *TSimpleServer) SetLogger(_ Logger) {} // SetLogContext sets the context to be used when logging errors inside // TSimpleServer. // // If this is not called before calling Serve, context.Background() will be // used. func (p *TSimpleServer) SetLogContext(ctx context.Context) { p.logContext.Store(&ctx) } func (p *TSimpleServer) innerAccept() (int32, error) { client, err := p.serverTransport.Accept() p.mu.Lock() defer p.mu.Unlock() closed := p.closed.Load() if closed != 0 { return closed, nil } if err != nil { return 0, err } if client != nil { ctx, cancel := context.WithCancel(context.Background()) p.wg.Add(2) go func() { defer p.wg.Done() defer cancel() defer client.Close() if err := p.processRequests(client); err != nil { ctx := p.logContext.Load() slog.ErrorContext(*ctx, "error processing request", "err", err) } }() go func() { defer p.wg.Done() select { case <-ctx.Done(): // client exited, do nothing case <-p.stopChan: // TSimpleServer.Close called, close the client connection client.Close() } }() } return 0, nil } func (p *TSimpleServer) AcceptLoop() error { for { closed, err := p.innerAccept() if err != nil { return err } if closed != 0 { return nil } } } func (p *TSimpleServer) Serve() error { p.logContext.CompareAndSwap(nil, Pointer(context.Background())) err := p.Listen() if err != nil { return err } p.AcceptLoop() return nil } func (p *TSimpleServer) Stop() error { p.mu.Lock() defer p.mu.Unlock() if !p.closed.CompareAndSwap(0, 1) { // Already closed return nil } p.serverTransport.Interrupt() ctx, cancel := context.WithCancel(context.Background()) go func() { defer cancel() p.wg.Wait() }() if ServerStopTimeout > 0 { timer := time.NewTimer(ServerStopTimeout) select { case <-timer.C: case <-ctx.Done(): } close(p.stopChan) timer.Stop() } <-ctx.Done() p.stopChan = make(chan struct{}) return nil } // If err is actually EOF or NOT_OPEN, return nil, otherwise return err as-is. func treatEOFErrorsAsNil(err error) error { if err == nil { return nil } if errors.Is(err, io.EOF) { return nil } var te TTransportException // NOT_OPEN returned by processor.Process is usually caused by client // abandoning the connection (e.g. client side time out, or just client // closes connections from the pool because of shutting down). // Those logs will be very noisy, so suppress those logs as well. if errors.As(err, &te) && (te.TypeId() == END_OF_FILE || te.TypeId() == NOT_OPEN) { return nil } return err } func (p *TSimpleServer) processRequests(client TTransport) (err error) { defer func() { err = treatEOFErrorsAsNil(err) }() processor := p.processorFactory.GetProcessor(client) inputTransport, err := p.inputTransportFactory.GetTransport(client) if err != nil { return err } inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport) var outputTransport TTransport var outputProtocol TProtocol // for THeaderProtocol, we must use the same protocol instance for // input and output so that the response is in the same dialect that // the server detected the request was in. headerProtocol, ok := inputProtocol.(*THeaderProtocol) if ok { outputProtocol = inputProtocol } else { oTrans, err := p.outputTransportFactory.GetTransport(client) if err != nil { return err } outputTransport = oTrans outputProtocol = p.outputProtocolFactory.GetProtocol(outputTransport) } if inputTransport != nil { defer inputTransport.Close() } if outputTransport != nil { defer outputTransport.Close() } for { if p.closed.Load() != 0 { return nil } ctx := SetResponseHelper( defaultCtx, TResponseHelper{ THeaderResponseHelper: NewTHeaderResponseHelper(outputProtocol), }, ) if headerProtocol != nil { // We need to call ReadFrame here, otherwise we won't // get any headers on the AddReadTHeaderToContext call. // // ReadFrame is safe to be called multiple times so it // won't break when it's called again later when we // actually start to read the message. if err := headerProtocol.ReadFrame(ctx); err != nil { return err } ctx = AddReadTHeaderToContext(ctx, headerProtocol.GetReadHeaders()) ctx = SetWriteHeaderList(ctx, p.forwardHeaders) } ok, err := processor.Process(ctx, inputProtocol, outputProtocol) if errors.Is(err, ErrAbandonRequest) { return nil } if errors.As(err, new(TTransportException)) && err != nil { return err } var tae TApplicationException if errors.As(err, &tae) && tae.TypeId() == UNKNOWN_METHOD { continue } if !ok { break } } return nil } // ErrAbandonRequest is a special error that server handler implementations can // return to indicate that the request has been abandoned. // // TSimpleServer and compiler generated Process functions will check for this // error, and close the client connection instead of trying to write the error // back to the client. // // It shall only be used when the server handler implementation know that the // client already abandoned the request (by checking that the passed in context // is already canceled, for example). // // It also implements the interface defined by errors.Unwrap and always unwrap // to context.Canceled error. var ErrAbandonRequest = abandonRequestError{} type abandonRequestError struct{} func (abandonRequestError) Error() string { return "request abandoned" } func (abandonRequestError) Unwrap() error { return context.Canceled } thrift-0.23.0/lib/go/thrift/serializer.go0000664000175000017500000000655115165535636020557 0ustar00buildbuild00000000000000/* * 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 ( "context" ) type TSerializer struct { Transport *TMemoryBuffer Protocol TProtocol } type TStruct interface { Write(ctx context.Context, p TProtocol) error Read(ctx context.Context, p TProtocol) error } func NewTSerializer() *TSerializer { transport := NewTMemoryBufferLen(1024) protocol := NewTBinaryProtocolTransport(transport) return &TSerializer{ Transport: transport, Protocol: protocol, } } func (t *TSerializer) WriteString(ctx context.Context, msg TStruct) (s string, err error) { t.Transport.Reset() if r, ok := t.Protocol.(reseter); ok { r.Reset() } if err = msg.Write(ctx, t.Protocol); err != nil { return } if err = t.Protocol.Flush(ctx); err != nil { return } if err = t.Transport.Flush(ctx); err != nil { return } return t.Transport.String(), nil } func (t *TSerializer) Write(ctx context.Context, msg TStruct) (b []byte, err error) { t.Transport.Reset() if r, ok := t.Protocol.(reseter); ok { r.Reset() } if err = msg.Write(ctx, t.Protocol); err != nil { return } if err = t.Protocol.Flush(ctx); err != nil { return } if err = t.Transport.Flush(ctx); err != nil { return } b = append(b, t.Transport.Bytes()...) return } // TSerializerPool is the thread-safe version of TSerializer, it uses resource // pool of TSerializer under the hood. // // It must be initialized with either NewTSerializerPool or // NewTSerializerPoolSizeFactory. type TSerializerPool struct { pool *pool[TSerializer] } // NewTSerializerPool creates a new TSerializerPool. // // NewTSerializer can be used as the arg here. func NewTSerializerPool(f func() *TSerializer) *TSerializerPool { return &TSerializerPool{ pool: newPool(f, nil), } } // NewTSerializerPoolSizeFactory creates a new TSerializerPool with the given // size and protocol factory. // // Note that the size is not the limit. The TMemoryBuffer underneath can grow // larger than that. It just dictates the initial size. func NewTSerializerPoolSizeFactory(size int, factory TProtocolFactory) *TSerializerPool { return &TSerializerPool{ pool: newPool(func() *TSerializer { transport := NewTMemoryBufferLen(size) protocol := factory.GetProtocol(transport) return &TSerializer{ Transport: transport, Protocol: protocol, } }, nil), } } func (t *TSerializerPool) WriteString(ctx context.Context, msg TStruct) (string, error) { s := t.pool.get() defer t.pool.put(&s) return s.WriteString(ctx, msg) } func (t *TSerializerPool) Write(ctx context.Context, msg TStruct) ([]byte, error) { s := t.pool.get() defer t.pool.put(&s) return s.Write(ctx, msg) } thrift-0.23.0/lib/go/thrift/iostream_transport_test.go0000664000175000017500000000323115165535636023374 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "testing" ) func TestStreamTransport(t *testing.T) { trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024))) TransportTest(t, trans, trans) } func TestStreamTransportOpenClose(t *testing.T) { trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024))) if !trans.IsOpen() { t.Fatal("StreamTransport should be already open") } if trans.Open() == nil { t.Fatal("StreamTransport should return error when open twice") } if trans.Close() != nil { t.Fatal("StreamTransport should not return error when closing open transport") } if trans.IsOpen() { t.Fatal("StreamTransport should not be open after close") } if trans.Close() == nil { t.Fatal("StreamTransport should return error when closing a non open transport") } if trans.Open() == nil { t.Fatal("StreamTransport should not be able to reopen") } } thrift-0.23.0/lib/go/thrift/socket_unix_conn.go0000664000175000017500000000412515167543515021746 0ustar00buildbuild00000000000000//go:build !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 ( "errors" "io" "syscall" "time" ) // We rely on this variable to be the zero time, // but define it as global variable to avoid repetitive allocations. // Please DO NOT mutate this variable in any way. var zeroTime time.Time func (sc *socketConn) read0() error { return sc.checkConn() } func (sc *socketConn) checkConn() error { syscallConn, ok := sc.Conn.(syscall.Conn) if !ok { // No way to check, return nil return nil } // The reading about to be done here is non-blocking so we don't really // need a read deadline. We just need to clear the previously set read // deadline, if any. sc.Conn.SetReadDeadline(zeroTime) rc, err := syscallConn.SyscallConn() if err != nil { return err } var n int if readErr := rc.Read(func(fd uintptr) bool { n, _, err = peekNonblocking(int(fd), sc.buffer[:]) return true }); readErr != nil { return readErr } if n > 0 { // We got something, which means we are good return nil } if errors.Is(err, syscall.EAGAIN) || errors.Is(err, syscall.EWOULDBLOCK) { // This means the connection is still open but we don't have // anything to read right now. return nil } if err != nil { return err } // At this point, it means the other side already closed the connection. return io.EOF } thrift-0.23.0/lib/go/thrift/rich_transport.go0000664000175000017500000000340015165535636021435 0ustar00buildbuild00000000000000/* * 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 ( "errors" "io" ) type RichTransport struct { TTransport } // Wraps Transport to provide TRichTransport interface func NewTRichTransport(trans TTransport) *RichTransport { return &RichTransport{trans} } func (r *RichTransport) ReadByte() (c byte, err error) { return readByte(r.TTransport) } func (r *RichTransport) WriteByte(c byte) error { return writeByte(r.TTransport, c) } func (r *RichTransport) WriteString(s string) (n int, err error) { return r.Write([]byte(s)) } func (r *RichTransport) RemainingBytes() (num_bytes uint64) { return r.TTransport.RemainingBytes() } func readByte(r io.Reader) (c byte, err error) { v := [1]byte{0} n, err := r.Read(v[0:1]) if n > 0 && (err == nil || errors.Is(err, io.EOF)) { return v[0], nil } if n > 0 && err != nil { return v[0], err } if err != nil { return 0, err } return v[0], nil } func writeByte(w io.Writer, c byte) error { v := [1]byte{c} _, err := w.Write(v[0:1]) return err } thrift-0.23.0/lib/go/thrift/logger.go0000664000175000017500000000465615165535636017671 0ustar00buildbuild00000000000000/* * 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 ( "log" "os" "testing" ) // Logger is a simple wrapper of a logging function. // // In reality the users might actually use different logging libraries, and they // are not always compatible with each other. // // Logger is meant to be a simple common ground that it's easy to wrap whatever // logging library they use into. // // See https://issues.apache.org/jira/browse/THRIFT-4985 for the design // discussion behind it. // // Deprecated: This is no longer used by any thrift go library code, // will be removed in the future version. type Logger func(msg string) // NopLogger is a Logger implementation that does nothing. // // Deprecated: This is no longer used by any thrift go library code, // will be removed in the future version. func NopLogger(msg string) {} // StdLogger wraps stdlib log package into a Logger. // // If logger passed in is nil, it will fallback to use stderr and default flags. // // Deprecated: This is no longer used by any thrift go library code, // will be removed in the future version. func StdLogger(logger *log.Logger) Logger { if logger == nil { logger = log.New(os.Stderr, "", log.LstdFlags) } return func(msg string) { logger.Print(msg) } } // TestLogger is a Logger implementation can be used in test codes. // // It fails the test when being called. // // Deprecated: This is no longer used by any thrift go library code, // will be removed in the future version. func TestLogger(tb testing.TB) Logger { return func(msg string) { tb.Errorf("logger called with msg: %q", msg) } } func fallbackLogger(logger Logger) Logger { if logger == nil { return StdLogger(nil) } return logger } thrift-0.23.0/lib/go/thrift/lowlevel_benchmarks_test.go0000664000175000017500000002573515165535636023500 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "testing" ) var binaryProtoF = NewTBinaryProtocolFactoryDefault() var compactProtoF = NewTCompactProtocolFactory() var buf = bytes.NewBuffer(make([]byte, 0, 1024)) var tfv = []TTransportFactory{ NewTMemoryBufferTransportFactory(1024), NewStreamTransportFactory(buf, buf, true), NewTFramedTransportFactory(NewTMemoryBufferTransportFactory(1024)), } func BenchmarkBinaryBool_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteBool(b, p, trans) } } func BenchmarkBinaryByte_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteByte(b, p, trans) } } func BenchmarkBinaryI16_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI16(b, p, trans) } } func BenchmarkBinaryI32_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI32(b, p, trans) } } func BenchmarkBinaryI64_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI64(b, p, trans) } } func BenchmarkBinaryDouble_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteDouble(b, p, trans) } } func BenchmarkBinaryString_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteString(b, p, trans) } } func BenchmarkBinaryBinary_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteBinary(b, p, trans) } } func BenchmarkBinaryBool_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteBool(b, p, trans) } } func BenchmarkBinaryByte_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteByte(b, p, trans) } } func BenchmarkBinaryI16_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI16(b, p, trans) } } func BenchmarkBinaryI32_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI32(b, p, trans) } } func BenchmarkBinaryI64_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI64(b, p, trans) } } func BenchmarkBinaryDouble_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteDouble(b, p, trans) } } func BenchmarkBinaryString_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteString(b, p, trans) } } func BenchmarkBinaryBinary_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteBinary(b, p, trans) } } func BenchmarkBinaryBool_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteBool(b, p, trans) } } func BenchmarkBinaryByte_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteByte(b, p, trans) } } func BenchmarkBinaryI16_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI16(b, p, trans) } } func BenchmarkBinaryI32_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI32(b, p, trans) } } func BenchmarkBinaryI64_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteI64(b, p, trans) } } func BenchmarkBinaryDouble_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteDouble(b, p, trans) } } func BenchmarkBinaryString_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteString(b, p, trans) } } func BenchmarkBinaryBinary_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := binaryProtoF.GetProtocol(trans) for range b.N { ReadWriteBinary(b, p, trans) } } func BenchmarkCompactBool_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteBool(b, p, trans) } } func BenchmarkCompactByte_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteByte(b, p, trans) } } func BenchmarkCompactI16_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI16(b, p, trans) } } func BenchmarkCompactI32_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI32(b, p, trans) } } func BenchmarkCompactI64_0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI64(b, p, trans) } } func BenchmarkCompactDouble0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteDouble(b, p, trans) } } func BenchmarkCompactString0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteString(b, p, trans) } } func BenchmarkCompactBinary0(b *testing.B) { trans, err := tfv[0].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteBinary(b, p, trans) } } func BenchmarkCompactBool_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteBool(b, p, trans) } } func BenchmarkCompactByte_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteByte(b, p, trans) } } func BenchmarkCompactI16_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI16(b, p, trans) } } func BenchmarkCompactI32_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI32(b, p, trans) } } func BenchmarkCompactI64_1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI64(b, p, trans) } } func BenchmarkCompactDouble1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteDouble(b, p, trans) } } func BenchmarkCompactString1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteString(b, p, trans) } } func BenchmarkCompactBinary1(b *testing.B) { trans, err := tfv[1].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteBinary(b, p, trans) } } func BenchmarkCompactBool_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteBool(b, p, trans) } } func BenchmarkCompactByte_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteByte(b, p, trans) } } func BenchmarkCompactI16_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI16(b, p, trans) } } func BenchmarkCompactI32_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI32(b, p, trans) } } func BenchmarkCompactI64_2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteI64(b, p, trans) } } func BenchmarkCompactDouble2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteDouble(b, p, trans) } } func BenchmarkCompactString2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteString(b, p, trans) } } func BenchmarkCompactBinary2(b *testing.B) { trans, err := tfv[2].GetTransport(nil) if err != nil { b.Fatal(err) } p := compactProtoF.GetProtocol(trans) for range b.N { ReadWriteBinary(b, p, trans) } } thrift-0.23.0/lib/go/thrift/transport.go0000664000175000017500000000340015165535636020430 0ustar00buildbuild00000000000000/* * 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 ( "context" "errors" "io" ) var errTransportInterrupted = errors.New("Transport Interrupted") type Flusher interface { Flush() (err error) } type ContextFlusher interface { Flush(ctx context.Context) (err error) } type ReadSizeProvider interface { RemainingBytes() (num_bytes uint64) } // Encapsulates the I/O layer type TTransport interface { io.ReadWriteCloser ContextFlusher ReadSizeProvider // Opens the transport for communication Open() error // Returns true if the transport is open IsOpen() bool } type stringWriter interface { WriteString(s string) (n int, err error) } // This is "enchanced" transport with extra capabilities. You need to use one of these // to construct protocol. // Notably, TSocket does not implement this interface, and it is always a mistake to use // TSocket directly in protocol. type TRichTransport interface { io.ReadWriter io.ByteReader io.ByteWriter stringWriter ContextFlusher ReadSizeProvider } thrift-0.23.0/lib/go/thrift/framed_transport_test.go0000664000175000017500000000534715165535636023021 0ustar00buildbuild00000000000000/* * 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 ( "context" "io" "strings" "testing" "testing/iotest" ) func TestFramedTransport(t *testing.T) { trans := NewTFramedTransport(NewTMemoryBuffer()) TransportTest(t, trans, trans) } func TestTFramedTransportReuseTransport(t *testing.T) { const ( content = "Hello, world!" n = 10 ) trans := NewTMemoryBuffer() reader := NewTFramedTransport(trans) writer := NewTFramedTransport(trans) t.Run("pair", func(t *testing.T) { 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) } if err := writer.Flush(context.Background()); err != nil { t.Fatalf("Failed to flush on #%d: %v", i, err) } // read read, err := io.ReadAll(iotest.OneByteReader(reader)) if err != nil { t.Errorf("Failed to read on #%d: %v", i, err) } if string(read) != content { t.Errorf("Read #%d: want %q, got %q", i, content, read) } } }) t.Run("batched", func(t *testing.T) { // write for i := range n { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) } if err := writer.Flush(context.Background()); err != nil { t.Fatalf("Failed to flush on #%d: %v", i, err) } } // read for i := range n { const ( size = len(content) ) var buf []byte var err error if i%2 == 0 { // on even calls, use OneByteReader to make // sure that small reads are fine buf, err = io.ReadAll(io.LimitReader(iotest.OneByteReader(reader), int64(size))) } else { // on odd calls, make sure that we don't read // more than written per frame buf = make([]byte, size*2) var n int n, err = reader.Read(buf) buf = buf[:n] } if err != nil { t.Errorf("Failed to read on #%d: %v", i, err) } if string(buf) != content { t.Errorf("Read #%d: want %q, got %q", i, content, buf) } } }) } thrift-0.23.0/lib/go/thrift/compact_protocol.go0000664000175000017500000006231215165535636021752 0ustar00buildbuild00000000000000/* * 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 ( "context" "encoding/binary" "errors" "fmt" "io" "math" ) const ( COMPACT_PROTOCOL_ID = 0x082 COMPACT_VERSION = 1 COMPACT_VERSION_MASK = 0x1f COMPACT_TYPE_MASK = 0x0E0 COMPACT_TYPE_BITS = 0x07 COMPACT_TYPE_SHIFT_AMOUNT = 5 ) type tCompactType byte const ( COMPACT_BOOLEAN_TRUE = 0x01 COMPACT_BOOLEAN_FALSE = 0x02 COMPACT_BYTE = 0x03 COMPACT_I16 = 0x04 COMPACT_I32 = 0x05 COMPACT_I64 = 0x06 COMPACT_DOUBLE = 0x07 COMPACT_BINARY = 0x08 COMPACT_LIST = 0x09 COMPACT_SET = 0x0A COMPACT_MAP = 0x0B COMPACT_STRUCT = 0x0C COMPACT_UUID = 0x0D ) var ( ttypeToCompactType map[TType]tCompactType ) func init() { ttypeToCompactType = map[TType]tCompactType{ STOP: STOP, BOOL: COMPACT_BOOLEAN_TRUE, BYTE: COMPACT_BYTE, I16: COMPACT_I16, I32: COMPACT_I32, I64: COMPACT_I64, DOUBLE: COMPACT_DOUBLE, STRING: COMPACT_BINARY, LIST: COMPACT_LIST, SET: COMPACT_SET, MAP: COMPACT_MAP, STRUCT: COMPACT_STRUCT, UUID: COMPACT_UUID, } } type TCompactProtocolFactory struct { cfg *TConfiguration } // Deprecated: Use NewTCompactProtocolFactoryConf instead. func NewTCompactProtocolFactory() *TCompactProtocolFactory { return NewTCompactProtocolFactoryConf(&TConfiguration{ noPropagation: true, }) } func NewTCompactProtocolFactoryConf(conf *TConfiguration) *TCompactProtocolFactory { return &TCompactProtocolFactory{ cfg: conf, } } func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol { return NewTCompactProtocolConf(trans, p.cfg) } func (p *TCompactProtocolFactory) SetTConfiguration(conf *TConfiguration) { p.cfg = conf } type TCompactProtocol struct { trans TRichTransport origTransport TTransport cfg *TConfiguration // Used to keep track of the last field for the current and previous structs, // so we can do the delta stuff. lastField []int lastFieldId int // If we encounter a boolean field begin, save the TField here so it can // have the value incorporated. booleanFieldName string booleanFieldId int16 booleanFieldPending bool // If we read a field header, and it's a boolean field, save the boolean // value here so that readBool can use it. boolValue bool boolValueIsNotNull bool buffer [64]byte } // Deprecated: Use NewTCompactProtocolConf instead. func NewTCompactProtocol(trans TTransport) *TCompactProtocol { return NewTCompactProtocolConf(trans, &TConfiguration{ noPropagation: true, }) } func NewTCompactProtocolConf(trans TTransport, conf *TConfiguration) *TCompactProtocol { PropagateTConfiguration(trans, conf) p := &TCompactProtocol{ origTransport: trans, cfg: conf, } if et, ok := trans.(TRichTransport); ok { p.trans = et } else { p.trans = NewTRichTransport(trans) } return p } // // Public Writing methods. // // Write a message header to the wire. Compact Protocol messages contain the // protocol version so we can migrate forwards in the future if need be. func (p *TCompactProtocol) WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error { err := p.writeByteDirect(COMPACT_PROTOCOL_ID) if err != nil { return NewTProtocolException(err) } err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK)) if err != nil { return NewTProtocolException(err) } _, err = p.writeVarint32(seqid) if err != nil { return NewTProtocolException(err) } e := p.WriteString(ctx, name) return e } func (p *TCompactProtocol) WriteMessageEnd(ctx context.Context) error { return nil } // Write a struct begin. This doesn't actually put anything on the wire. We // use it as an opportunity to put special placeholder markers on the field // stack so we can get the field id deltas correct. func (p *TCompactProtocol) WriteStructBegin(ctx context.Context, name string) error { p.lastField = append(p.lastField, p.lastFieldId) p.lastFieldId = 0 return nil } // Write a struct end. This doesn't actually put anything on the wire. We use // this as an opportunity to pop the last field from the current struct off // of the field stack. func (p *TCompactProtocol) WriteStructEnd(ctx context.Context) error { if len(p.lastField) <= 0 { return NewTProtocolExceptionWithType(INVALID_DATA, errors.New("WriteStructEnd called without matching WriteStructBegin call before")) } p.lastFieldId = p.lastField[len(p.lastField)-1] p.lastField = p.lastField[:len(p.lastField)-1] return nil } func (p *TCompactProtocol) WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error { if typeId == BOOL { // we want to possibly include the value, so we'll wait. p.booleanFieldName, p.booleanFieldId, p.booleanFieldPending = name, id, true return nil } _, err := p.writeFieldBeginInternal(ctx, name, typeId, id, 0xFF) return NewTProtocolException(err) } // The workhorse of writeFieldBegin. It has the option of doing a // 'type override' of the type header. This is used specifically in the // boolean field case. func (p *TCompactProtocol) writeFieldBeginInternal(ctx context.Context, name string, typeId TType, id int16, typeOverride byte) (int, error) { // short lastField = lastField_.pop(); // if there's a type override, use that. var typeToWrite byte if typeOverride == 0xFF { typeToWrite = byte(p.getCompactType(typeId)) } else { typeToWrite = typeOverride } // check if we can use delta encoding for the field id fieldId := int(id) written := 0 if fieldId > p.lastFieldId && fieldId-p.lastFieldId <= 15 { // write them together err := p.writeByteDirect(byte((fieldId-p.lastFieldId)<<4) | typeToWrite) if err != nil { return 0, err } } else { // write them separate err := p.writeByteDirect(typeToWrite) if err != nil { return 0, err } err = p.WriteI16(ctx, id) written = 1 + 2 if err != nil { return 0, err } } p.lastFieldId = fieldId return written, nil } func (p *TCompactProtocol) WriteFieldEnd(ctx context.Context) error { return nil } func (p *TCompactProtocol) WriteFieldStop(ctx context.Context) error { err := p.writeByteDirect(STOP) return NewTProtocolException(err) } func (p *TCompactProtocol) WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error { if size == 0 { err := p.writeByteDirect(0) return NewTProtocolException(err) } _, err := p.writeVarint32(int32(size)) if err != nil { return NewTProtocolException(err) } err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType))) return NewTProtocolException(err) } func (p *TCompactProtocol) WriteMapEnd(ctx context.Context) error { return nil } // Write a list header. func (p *TCompactProtocol) WriteListBegin(ctx context.Context, elemType TType, size int) error { _, err := p.writeCollectionBegin(elemType, size) return NewTProtocolException(err) } func (p *TCompactProtocol) WriteListEnd(ctx context.Context) error { return nil } // Write a set header. func (p *TCompactProtocol) WriteSetBegin(ctx context.Context, elemType TType, size int) error { _, err := p.writeCollectionBegin(elemType, size) return NewTProtocolException(err) } func (p *TCompactProtocol) WriteSetEnd(ctx context.Context) error { return nil } func (p *TCompactProtocol) WriteBool(ctx context.Context, value bool) error { v := byte(COMPACT_BOOLEAN_FALSE) if value { v = byte(COMPACT_BOOLEAN_TRUE) } if p.booleanFieldPending { // we haven't written the field header yet _, err := p.writeFieldBeginInternal(ctx, p.booleanFieldName, BOOL, p.booleanFieldId, v) p.booleanFieldPending = false return NewTProtocolException(err) } // we're not part of a field, so just write the value. err := p.writeByteDirect(v) return NewTProtocolException(err) } // Write a byte. Nothing to see here! func (p *TCompactProtocol) WriteByte(ctx context.Context, value int8) error { err := p.writeByteDirect(byte(value)) return NewTProtocolException(err) } // Write an I16 as a zigzag varint. func (p *TCompactProtocol) WriteI16(ctx context.Context, value int16) error { _, err := p.writeVarint32(p.int32ToZigzag(int32(value))) return NewTProtocolException(err) } // Write an i32 as a zigzag varint. func (p *TCompactProtocol) WriteI32(ctx context.Context, value int32) error { _, err := p.writeVarint32(p.int32ToZigzag(value)) return NewTProtocolException(err) } // Write an i64 as a zigzag varint. func (p *TCompactProtocol) WriteI64(ctx context.Context, value int64) error { _, err := p.writeVarint64(p.int64ToZigzag(value)) return NewTProtocolException(err) } // Write a double to the wire as 8 bytes. func (p *TCompactProtocol) WriteDouble(ctx context.Context, value float64) error { buf := p.buffer[0:8] binary.LittleEndian.PutUint64(buf, math.Float64bits(value)) _, err := p.trans.Write(buf) return NewTProtocolException(err) } // Write a string to the wire with a varint size preceding. func (p *TCompactProtocol) WriteString(ctx context.Context, value string) error { _, e := p.writeVarint32(int32(len(value))) if e != nil { return NewTProtocolException(e) } if len(value) == 0 { return nil } _, e = p.trans.WriteString(value) return e } // Write a byte array, using a varint for the size. func (p *TCompactProtocol) WriteBinary(ctx context.Context, bin []byte) error { _, e := p.writeVarint32(int32(len(bin))) if e != nil { return NewTProtocolException(e) } if len(bin) > 0 { _, e = p.trans.Write(bin) return NewTProtocolException(e) } return nil } // Write a Tuuid to the wire as 16 bytes. func (p *TCompactProtocol) WriteUUID(ctx context.Context, value Tuuid) error { _, err := p.trans.Write(value[:]) return NewTProtocolException(err) } // // Reading methods. // // Read a message header. func (p *TCompactProtocol) ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqId int32, err error) { var protocolId byte _, deadlineSet := ctx.Deadline() for { protocolId, err = p.readByteDirect() if deadlineSet && isTimeoutError(err) && ctx.Err() == nil { // keep retrying I/O timeout errors since we still have // time left continue } // For anything else, don't retry break } if err != nil { return } if protocolId != COMPACT_PROTOCOL_ID { e := fmt.Errorf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId) return "", typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, e) } versionAndType, err := p.readByteDirect() if err != nil { return } version := versionAndType & COMPACT_VERSION_MASK typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS) if version != COMPACT_VERSION { e := fmt.Errorf("Expected version %02x but got %02x", COMPACT_VERSION, version) err = NewTProtocolExceptionWithType(BAD_VERSION, e) return } seqId, e := p.readVarint32() if e != nil { err = NewTProtocolException(e) return } name, err = p.ReadString(ctx) return } func (p *TCompactProtocol) ReadMessageEnd(ctx context.Context) error { return nil } // Read a struct begin. There's nothing on the wire for this, but it is our // opportunity to push a new struct begin marker onto the field stack. func (p *TCompactProtocol) ReadStructBegin(ctx context.Context) (name string, err error) { p.lastField = append(p.lastField, p.lastFieldId) p.lastFieldId = 0 return } // Doesn't actually consume any wire data, just removes the last field for // this struct from the field stack. func (p *TCompactProtocol) ReadStructEnd(ctx context.Context) error { // consume the last field we read off the wire. if len(p.lastField) <= 0 { return NewTProtocolExceptionWithType(INVALID_DATA, errors.New("ReadStructEnd called without matching ReadStructBegin call before")) } p.lastFieldId = p.lastField[len(p.lastField)-1] p.lastField = p.lastField[:len(p.lastField)-1] return nil } // Read a field header off the wire. func (p *TCompactProtocol) ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) { t, err := p.readByteDirect() if err != nil { return } // if it's a stop, then we can return immediately, as the struct is over. if (t & 0x0f) == STOP { return "", STOP, 0, nil } // mask off the 4 MSB of the type header. it could contain a field id delta. modifier := int16((t & 0xf0) >> 4) if modifier == 0 { // not a delta. look ahead for the zigzag varint field id. id, err = p.ReadI16(ctx) if err != nil { return } } else { // has a delta. add the delta to the last read field id. id = int16(p.lastFieldId) + modifier } typeId, e := p.getTType(tCompactType(t & 0x0f)) if e != nil { err = NewTProtocolException(e) return } // if this happens to be a boolean field, the value is encoded in the type if p.isBoolType(t) { // save the boolean value in a special instance variable. p.boolValue = (byte(t)&0x0f == COMPACT_BOOLEAN_TRUE) p.boolValueIsNotNull = true } // push the new field onto the field stack so we can keep the deltas going. p.lastFieldId = int(id) return } func (p *TCompactProtocol) ReadFieldEnd(ctx context.Context) error { return nil } // Read a map header off the wire. If the size is zero, skip reading the key // and value type. This means that 0-length maps will yield TMaps without the // "correct" types. func (p *TCompactProtocol) ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) { size32, e := p.readVarint32() if e != nil { err = NewTProtocolException(e) return } size = int(size32) keyAndValueType := byte(STOP) if size != 0 { keyAndValueType, err = p.readByteDirect() if err != nil { return } } keyType, _ = p.getTType(tCompactType(keyAndValueType >> 4)) valueType, _ = p.getTType(tCompactType(keyAndValueType & 0xf)) minElemSize := p.getMinSerializedSize(keyType) + p.getMinSerializedSize(valueType) totalMinSize := size32 * minElemSize err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } return } func (p *TCompactProtocol) ReadMapEnd(ctx context.Context) error { return nil } // Read a list header off the wire. If the list size is 0-14, the size will // be packed into the element type header. If it's a longer list, the 4 MSB // of the element type header will be 0xF, and a varint will follow with the // true size. func (p *TCompactProtocol) ReadListBegin(ctx context.Context) (elemType TType, size int, err error) { size_and_type, err := p.readByteDirect() if err != nil { return } size = int((size_and_type >> 4) & 0x0f) if size == 15 { size2, e := p.readVarint32() if e != nil { err = NewTProtocolException(e) return } size = int(size2) } elemType, e := p.getTType(tCompactType(size_and_type)) if e != nil { err = NewTProtocolException(e) return } minElemSize := p.getMinSerializedSize(elemType) totalMinSize := int32(size) * minElemSize err = checkSizeForProtocol(totalMinSize, p.cfg) if err != nil { return } return } func (p *TCompactProtocol) ReadListEnd(ctx context.Context) error { return nil } // Read a set header off the wire. If the set size is 0-14, the size will // be packed into the element type header. If it's a longer set, the 4 MSB // of the element type header will be 0xF, and a varint will follow with the // true size. func (p *TCompactProtocol) ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) { return p.ReadListBegin(ctx) } func (p *TCompactProtocol) ReadSetEnd(ctx context.Context) error { return nil } // Read a boolean off the wire. If this is a boolean field, the value should // already have been read during readFieldBegin, so we'll just consume the // pre-stored value. Otherwise, read a byte. func (p *TCompactProtocol) ReadBool(ctx context.Context) (value bool, err error) { if p.boolValueIsNotNull { p.boolValueIsNotNull = false return p.boolValue, nil } v, err := p.readByteDirect() return v == COMPACT_BOOLEAN_TRUE, err } // Read a single byte off the wire. Nothing interesting here. func (p *TCompactProtocol) ReadByte(ctx context.Context) (int8, error) { v, err := p.readByteDirect() if err != nil { return 0, NewTProtocolException(err) } return int8(v), err } // Read an i16 from the wire as a zigzag varint. func (p *TCompactProtocol) ReadI16(ctx context.Context) (value int16, err error) { v, err := p.ReadI32(ctx) return int16(v), err } // Read an i32 from the wire as a zigzag varint. func (p *TCompactProtocol) ReadI32(ctx context.Context) (value int32, err error) { v, e := p.readVarint32() if e != nil { return 0, NewTProtocolException(e) } value = p.zigzagToInt32(v) return value, nil } // Read an i64 from the wire as a zigzag varint. func (p *TCompactProtocol) ReadI64(ctx context.Context) (value int64, err error) { v, e := p.readVarint64() if e != nil { return 0, NewTProtocolException(e) } value = p.zigzagToInt64(v) return value, nil } // No magic here - just read a double off the wire. func (p *TCompactProtocol) ReadDouble(ctx context.Context) (value float64, err error) { longBits := p.buffer[0:8] _, e := io.ReadFull(p.trans, longBits) if e != nil { return 0.0, NewTProtocolException(e) } return math.Float64frombits(p.bytesToUint64(longBits)), nil } // Reads a []byte (via readBinary), and then UTF-8 decodes it. func (p *TCompactProtocol) ReadString(ctx context.Context) (value string, err error) { length, e := p.readVarint32() if e != nil { return "", NewTProtocolException(e) } err = checkSizeForProtocol(length, p.cfg) if err != nil { return } if length == 0 { return "", nil } if length < int32(len(p.buffer)) { // Avoid allocation on small reads buf := p.buffer[:length] read, e := io.ReadFull(p.trans, buf) return string(buf[:read]), NewTProtocolException(e) } buf, e := safeReadBytes(length, p.trans) return string(buf), NewTProtocolException(e) } // Read a []byte from the wire. func (p *TCompactProtocol) ReadBinary(ctx context.Context) (value []byte, err error) { length, e := p.readVarint32() if e != nil { return nil, NewTProtocolException(e) } err = checkSizeForProtocol(length, p.cfg) if err != nil { return } if length == 0 { return []byte{}, nil } buf, e := safeReadBytes(length, p.trans) return buf, NewTProtocolException(e) } // Read fixed 16 bytes as UUID. func (p *TCompactProtocol) ReadUUID(ctx context.Context) (value Tuuid, err error) { buf := p.buffer[0:16] _, e := io.ReadFull(p.trans, buf) if e == nil { copy(value[:], buf) } return value, NewTProtocolException(e) } func (p *TCompactProtocol) Flush(ctx context.Context) (err error) { return NewTProtocolException(p.trans.Flush(ctx)) } func (p *TCompactProtocol) Skip(ctx context.Context, fieldType TType) (err error) { return SkipDefaultDepth(ctx, p, fieldType) } func (p *TCompactProtocol) Transport() TTransport { return p.origTransport } // // Internal writing methods // // Abstract method for writing the start of lists and sets. List and sets on // the wire differ only by the type indicator. func (p *TCompactProtocol) writeCollectionBegin(elemType TType, size int) (int, error) { if size <= 14 { return 1, p.writeByteDirect(byte(int32(size<<4) | int32(p.getCompactType(elemType)))) } err := p.writeByteDirect(0xf0 | byte(p.getCompactType(elemType))) if err != nil { return 0, err } m, err := p.writeVarint32(int32(size)) return 1 + m, err } // Write an i32 as a varint. Results in 1-5 bytes on the wire. // TODO(pomack): make a permanent buffer like writeVarint64? func (p *TCompactProtocol) writeVarint32(n int32) (int, error) { i32buf := p.buffer[0:5] idx := 0 for { if (n & ^0x7F) == 0 { i32buf[idx] = byte(n) idx++ // p.writeByteDirect(byte(n)); break // return; } else { i32buf[idx] = byte((n & 0x7F) | 0x80) idx++ // p.writeByteDirect(byte(((n & 0x7F) | 0x80))); u := uint32(n) n = int32(u >> 7) } } return p.trans.Write(i32buf[0:idx]) } // Write an i64 as a varint. Results in 1-10 bytes on the wire. func (p *TCompactProtocol) writeVarint64(n int64) (int, error) { varint64out := p.buffer[0:10] idx := 0 for { if (n & ^0x7F) == 0 { varint64out[idx] = byte(n) idx++ break } else { varint64out[idx] = byte((n & 0x7F) | 0x80) idx++ u := uint64(n) n = int64(u >> 7) } } return p.trans.Write(varint64out[0:idx]) } // Convert l into a zigzag long. This allows negative numbers to be // represented compactly as a varint. func (p *TCompactProtocol) int64ToZigzag(l int64) int64 { return (l << 1) ^ (l >> 63) } // Convert l into a zigzag long. This allows negative numbers to be // represented compactly as a varint. func (p *TCompactProtocol) int32ToZigzag(n int32) int32 { return (n << 1) ^ (n >> 31) } // Writes a byte without any possibility of all that field header nonsense. // Used internally by other writing methods that know they need to write a byte. func (p *TCompactProtocol) writeByteDirect(b byte) error { return p.trans.WriteByte(b) } // // Internal reading methods // // 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. func (p *TCompactProtocol) readVarint32() (int32, error) { // if the wire contains the right stuff, this will just truncate the i64 we // read and get us the right sign. v, err := p.readVarint64() return int32(v), err } // 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. func (p *TCompactProtocol) readVarint64() (int64, error) { shift := uint(0) result := int64(0) for { b, err := p.readByteDirect() if err != nil { return 0, err } result |= int64(b&0x7f) << shift if (b & 0x80) != 0x80 { break } shift += 7 } return result, nil } // Read a byte, unlike ReadByte that reads Thrift-byte that is i8. func (p *TCompactProtocol) readByteDirect() (byte, error) { return p.trans.ReadByte() } // // encoding helpers // // Convert from zigzag int to int. func (p *TCompactProtocol) zigzagToInt32(n int32) int32 { u := uint32(n) return int32(u>>1) ^ -(n & 1) } // Convert from zigzag long to long. func (p *TCompactProtocol) zigzagToInt64(n int64) int64 { u := uint64(n) return int64(u>>1) ^ -(n & 1) } // Note that it's important that the mask bytes are long literals, // otherwise they'll default to ints, and when you shift an int left 56 bits, // you just get a messed up int. func (p *TCompactProtocol) bytesToUint64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) } // // type testing and converting // func (p *TCompactProtocol) isBoolType(b byte) bool { return (b&0x0f) == COMPACT_BOOLEAN_TRUE || (b&0x0f) == COMPACT_BOOLEAN_FALSE } // Given a tCompactType constant, convert it to its corresponding // TType value. func (p *TCompactProtocol) getTType(t tCompactType) (TType, error) { switch byte(t) & 0x0f { case STOP: return STOP, nil case COMPACT_BOOLEAN_FALSE, COMPACT_BOOLEAN_TRUE: return BOOL, nil case COMPACT_BYTE: return BYTE, nil case COMPACT_I16: return I16, nil case COMPACT_I32: return I32, nil case COMPACT_I64: return I64, nil case COMPACT_DOUBLE: return DOUBLE, nil case COMPACT_BINARY: return STRING, nil case COMPACT_LIST: return LIST, nil case COMPACT_SET: return SET, nil case COMPACT_MAP: return MAP, nil case COMPACT_STRUCT: return STRUCT, nil case COMPACT_UUID: return UUID, nil } return STOP, NewTProtocolException(fmt.Errorf("don't know what type: %v", t&0x0f)) } // Given a TType value, find the appropriate TCompactProtocol.Types constant. func (p *TCompactProtocol) getCompactType(t TType) tCompactType { return ttypeToCompactType[t] } func (p *TCompactProtocol) SetTConfiguration(conf *TConfiguration) { PropagateTConfiguration(p.trans, conf) PropagateTConfiguration(p.origTransport, conf) p.cfg = conf } // Return the minimum number of bytes a type will consume on the wire func (p *TCompactProtocol) getMinSerializedSize(ttype TType) int32 { switch ttype { case STOP: return 1 // T_STOP needs to count itself case VOID: return 1 // T_VOID needs to count itself case BOOL: return 1 // sizeof(int8) case BYTE: return 1 // sizeof(int8) case DOUBLE: return 8 // uses PutUint64() which always writes 8 bytes case I16: return 1 // zigzag case I32: return 1 // zigzag case I64: return 1 // zigzag case STRING: return 1 // string length case STRUCT: return 1 // empty struct needs at least 1 byte for the T_STOP case MAP: return 1 // element count case SET: return 1 // element count case LIST: return 1 // element count case UUID: return 16 // 16 bytes default: return 1 // unknown type } } var ( _ TConfigurationSetter = (*TCompactProtocolFactory)(nil) _ TConfigurationSetter = (*TCompactProtocol)(nil) ) thrift-0.23.0/lib/go/thrift/zlib_pool_test.go0000664000175000017500000000264315165535636021434 0ustar00buildbuild00000000000000/* * 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 ( "compress/zlib" "fmt" "maps" "slices" "testing" ) func TestZlibWriterPools(t *testing.T) { // make sure we have the writer pools created at the given levels for _, level := range []int{ zlib.HuffmanOnly, zlib.DefaultCompression, zlib.NoCompression, zlib.BestSpeed, zlib.BestCompression, } { t.Run(fmt.Sprintf("%d", level), func(t *testing.T) { _, ok := zlibWriterPools[level] if !ok { t.Errorf("level %d does not exist in the writer pools", level) } }) } if t.Failed() { levels := slices.Collect(maps.Keys(zlibWriterPools)) slices.Sort(levels) t.Log("zlib writer pools:", levels) } } thrift-0.23.0/lib/go/thrift/memory_buffer.go0000664000175000017500000000403215165535636021237 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "context" ) // Memory buffer-based implementation of the TTransport interface. type TMemoryBuffer struct { *bytes.Buffer size int } type TMemoryBufferTransportFactory struct { size int } func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) (TTransport, error) { if trans != nil { t, ok := trans.(*TMemoryBuffer) if ok && t.size > 0 { return NewTMemoryBufferLen(t.size), nil } } return NewTMemoryBufferLen(p.size), nil } func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory { return &TMemoryBufferTransportFactory{size: size} } func NewTMemoryBuffer() *TMemoryBuffer { return &TMemoryBuffer{Buffer: &bytes.Buffer{}, size: 0} } func NewTMemoryBufferLen(size int) *TMemoryBuffer { buf := make([]byte, 0, size) return &TMemoryBuffer{Buffer: bytes.NewBuffer(buf), size: size} } func (p *TMemoryBuffer) IsOpen() bool { return true } func (p *TMemoryBuffer) Open() error { return nil } func (p *TMemoryBuffer) Close() error { p.Buffer.Reset() return nil } // Flushing a memory buffer is a no-op func (p *TMemoryBuffer) Flush(ctx context.Context) error { return nil } func (p *TMemoryBuffer) RemainingBytes() (num_bytes uint64) { return uint64(p.Buffer.Len()) } thrift-0.23.0/lib/go/thrift/numeric.go0000664000175000017500000000760515165535636020051 0ustar00buildbuild00000000000000/* * 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 ( "math" "strconv" ) type Numeric interface { Int64() int64 Int32() int32 Int16() int16 Byte() byte Int() int Float64() float64 Float32() float32 String() string isNull() bool } type numeric struct { iValue int64 dValue float64 sValue string isNil bool } var ( INFINITY Numeric NEGATIVE_INFINITY Numeric NAN Numeric ZERO Numeric NUMERIC_NULL Numeric ) func NewNumericFromDouble(dValue float64) Numeric { if math.IsInf(dValue, 1) { return INFINITY } if math.IsInf(dValue, -1) { return NEGATIVE_INFINITY } if math.IsNaN(dValue) { return NAN } iValue := int64(dValue) sValue := strconv.FormatFloat(dValue, 'g', 10, 64) isNil := false return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} } func NewNumericFromI64(iValue int64) Numeric { dValue := float64(iValue) sValue := strconv.FormatInt(iValue, 10) isNil := false return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} } func NewNumericFromI32(iValue int32) Numeric { dValue := float64(iValue) sValue := strconv.FormatInt(int64(iValue), 10) isNil := false return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil} } func NewNumericFromString(sValue string) Numeric { if sValue == INFINITY.String() { return INFINITY } if sValue == NEGATIVE_INFINITY.String() { return NEGATIVE_INFINITY } if sValue == NAN.String() { return NAN } iValue, _ := strconv.ParseInt(sValue, 10, 64) dValue, _ := strconv.ParseFloat(sValue, 64) isNil := len(sValue) == 0 return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} } func NewNumericFromJSONString(sValue string, isNull bool) Numeric { if isNull { return NewNullNumeric() } if sValue == JSON_INFINITY { return INFINITY } if sValue == JSON_NEGATIVE_INFINITY { return NEGATIVE_INFINITY } if sValue == JSON_NAN { return NAN } iValue, _ := strconv.ParseInt(sValue, 10, 64) dValue, _ := strconv.ParseFloat(sValue, 64) return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNull} } func NewNullNumeric() Numeric { return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true} } func (p *numeric) Int64() int64 { return p.iValue } func (p *numeric) Int32() int32 { return int32(p.iValue) } func (p *numeric) Int16() int16 { return int16(p.iValue) } func (p *numeric) Byte() byte { return byte(p.iValue) } func (p *numeric) Int() int { return int(p.iValue) } func (p *numeric) Float64() float64 { return p.dValue } func (p *numeric) Float32() float32 { return float32(p.dValue) } func (p *numeric) String() string { return p.sValue } func (p *numeric) isNull() bool { return p.isNil } func init() { INFINITY = &numeric{iValue: 0, dValue: math.Inf(1), sValue: "Infinity", isNil: false} NEGATIVE_INFINITY = &numeric{iValue: 0, dValue: math.Inf(-1), sValue: "-Infinity", isNil: false} NAN = &numeric{iValue: 0, dValue: math.NaN(), sValue: "NaN", isNil: false} ZERO = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: false} NUMERIC_NULL = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: true} } thrift-0.23.0/lib/go/thrift/server.go0000664000175000017500000000237015165535636017707 0ustar00buildbuild00000000000000/* * 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 type TServer interface { ProcessorFactory() TProcessorFactory ServerTransport() TServerTransport InputTransportFactory() TTransportFactory OutputTransportFactory() TTransportFactory InputProtocolFactory() TProtocolFactory OutputProtocolFactory() TProtocolFactory // Starts the server Serve() error // Stops the server. This is optional on a per-implementation basis. Not // all servers are required to be cleanly stoppable. Stop() error } thrift-0.23.0/lib/go/thrift/messagetype.go0000664000175000017500000000212215165535636020722 0ustar00buildbuild00000000000000/* * 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 // Message type constants in the Thrift protocol. type TMessageType int32 const ( INVALID_TMESSAGE_TYPE TMessageType = 0 CALL TMessageType = 1 REPLY TMessageType = 2 EXCEPTION TMessageType = 3 ONEWAY TMessageType = 4 ) thrift-0.23.0/lib/go/thrift/response_helper_test.go0000664000175000017500000000647615165535636022650 0ustar00buildbuild00000000000000/* * 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 ( "context" "testing" ) func TestResponseHelperContext(t *testing.T) { ctx := context.Background() t.Run( "empty-noop", func(t *testing.T) { helper, ok := GetResponseHelper(ctx) if ok { t.Error("GetResponseHelper expected ok == false") } // Just make sure those function calls does not panic helper.SetHeader("foo", "bar") helper.ClearHeaders() }, ) t.Run( "set-get", func(t *testing.T) { trans := NewTHeaderTransport(NewTMemoryBuffer()) proto := NewTHeaderProtocol(trans) ctx = SetResponseHelper( ctx, TResponseHelper{ THeaderResponseHelper: NewTHeaderResponseHelper(proto), }, ) helper, ok := GetResponseHelper(ctx) if !ok { t.Error("GetResponseHelper expected ok == true") } if helper.THeaderResponseHelper == nil { t.Error("GetResponseHelper expected THeaderResponseHelper to be non-nil") } }, ) } func TestHeaderHelper(t *testing.T) { t.Run( "THeaderProtocol", func(t *testing.T) { trans := NewTHeaderTransport(NewTMemoryBuffer()) proto := NewTHeaderProtocol(trans) helper := NewTHeaderResponseHelper(proto) const ( key = "key" value = "value" ) helper.SetHeader(key, value) if len(trans.writeHeaders) != 1 { t.Errorf( "Expected THeaderTransport.writeHeaders to be with size of 1, got %+v", trans.writeHeaders, ) } actual := trans.writeHeaders[key] if actual != value { t.Errorf( "Expected THeaderTransport.writeHeaders to have %q:%q, got %+v", key, value, trans.writeHeaders, ) } helper.ClearHeaders() if len(trans.writeHeaders) != 0 { t.Errorf( "Expected THeaderTransport.writeHeaders to be empty after ClearHeaders call, got %+v", trans.writeHeaders, ) } }, ) t.Run( "other-protocol", func(t *testing.T) { trans := NewTMemoryBuffer() proto := NewTCompactProtocol(trans) helper := NewTHeaderResponseHelper(proto) // We only need to make sure that functions in helper // don't panic here. helper.SetHeader("foo", "bar") helper.ClearHeaders() }, ) t.Run( "zero-value", func(t *testing.T) { var helper *THeaderResponseHelper // We only need to make sure that functions in helper // don't panic here. helper.SetHeader("foo", "bar") helper.ClearHeaders() }, ) } func TestTResponseHelperZeroValue(t *testing.T) { var helper THeaderResponseHelper // We only need to make sure that functions in helper // don't panic here. helper.SetHeader("foo", "bar") helper.ClearHeaders() } thrift-0.23.0/lib/go/thrift/transport_exception_test.go0000664000175000017500000000560515165535636023556 0ustar00buildbuild00000000000000/* * 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 ( "errors" "fmt" "io" "testing" ) type timeout struct{ timedout bool } func (t *timeout) Timeout() bool { return t.timedout } func (t *timeout) Error() string { return fmt.Sprintf("Timeout: %v", t.timedout) } func TestTExceptionTimeout(t *testing.T) { timeout := &timeout{true} exception := NewTTransportExceptionFromError(timeout) if timeout.Error() != exception.Error() { t.Errorf("Error did not match: expected %q, got %q", timeout.Error(), exception.Error()) } if exception.TypeId() != TIMED_OUT { t.Errorf("TypeId was not TIMED_OUT: expected %v, got %v", TIMED_OUT, exception.TypeId()) } if unwrapped := errors.Unwrap(exception); unwrapped != timeout { t.Errorf("Unwrapped exception did not match: expected %v, got %v", timeout, unwrapped) } } func TestTExceptionEOF(t *testing.T) { exception := NewTTransportExceptionFromError(io.EOF) if io.EOF.Error() != exception.Error() { t.Errorf("Error did not match: expected %q, got %q", io.EOF.Error(), exception.Error()) } if exception.TypeId() != END_OF_FILE { t.Errorf("TypeId was not END_OF_FILE: expected %v, got %v", END_OF_FILE, exception.TypeId()) } if unwrapped := errors.Unwrap(exception); unwrapped != io.EOF { t.Errorf("Unwrapped exception did not match: expected %v, got %v", io.EOF, unwrapped) } } func TestIsTimeoutError(t *testing.T) { te := &timeout{true} if !isTimeoutError(te) { t.Error("isTimeoutError expected true, got false") } e := NewTTransportExceptionFromError(te) if !isTimeoutError(e) { t.Error("isTimeoutError on wrapped TTransportException expected true, got false") } te = &timeout{false} if isTimeoutError(te) { t.Error("isTimeoutError expected false, got true") } e = NewTTransportExceptionFromError(te) if isTimeoutError(e) { t.Error("isTimeoutError on wrapped TTransportException expected false, got true") } err := errors.New("foo") if isTimeoutError(err) { t.Error("isTimeoutError expected false, got true") } e = NewTTransportExceptionFromError(err) if isTimeoutError(e) { t.Error("isTimeoutError on wrapped TTransportException expected false, got true") } } thrift-0.23.0/lib/go/thrift/slog.go0000664000175000017500000000325615165535636017351 0ustar00buildbuild00000000000000/* * 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 ( "encoding/json" "fmt" "strings" ) // SlogTStructWrapper is a wrapper used by the compiler to wrap TStruct and // TException to be better logged by slog. type SlogTStructWrapper struct { Type string `json:"type"` Value TStruct `json:"value"` } var ( _ fmt.Stringer = SlogTStructWrapper{} _ json.Marshaler = SlogTStructWrapper{} ) func (w SlogTStructWrapper) MarshalJSON() ([]byte, error) { // Use an alias to avoid infinite recursion type alias SlogTStructWrapper return json.Marshal(alias(w)) } func (w SlogTStructWrapper) String() string { var sb strings.Builder sb.WriteString(w.Type) if err := json.NewEncoder(&sb).Encode(w.Value); err != nil { // Should not happen, but just in case return fmt.Sprintf("%s: %v", w.Type, w.Value) } // json encoder will write an additional \n at the end, get rid of it return strings.TrimSuffix(sb.String(), "\n") } thrift-0.23.0/lib/go/thrift/application_exception_test.go0000664000175000017500000000305215165535636024017 0ustar00buildbuild00000000000000/* * 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 ( "testing" ) func TestTApplicationException(t *testing.T) { exc := NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "") if exc.Error() != defaultApplicationExceptionMessage[UNKNOWN_APPLICATION_EXCEPTION] { t.Fatalf("Expected empty string for exception but found '%s'", exc.Error()) } if exc.TypeId() != UNKNOWN_APPLICATION_EXCEPTION { t.Fatalf("Expected type UNKNOWN for exception but found '%v'", exc.TypeId()) } exc = NewTApplicationException(WRONG_METHOD_NAME, "junk_method") if exc.Error() != "junk_method" { t.Fatalf("Expected 'junk_method' for exception but found '%s'", exc.Error()) } if exc.TypeId() != WRONG_METHOD_NAME { t.Fatalf("Expected type WRONG_METHOD_NAME for exception but found '%v'", exc.TypeId()) } } thrift-0.23.0/lib/go/thrift/ssl_server_socket.go0000664000175000017500000000563515165535636022147 0ustar00buildbuild00000000000000/* * 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 ( "crypto/tls" "net" "time" ) type TSSLServerSocket struct { listener net.Listener addr net.Addr clientTimeout time.Duration interrupted bool cfg *tls.Config } func NewTSSLServerSocket(listenAddr string, cfg *tls.Config) (*TSSLServerSocket, error) { return NewTSSLServerSocketTimeout(listenAddr, cfg, 0) } func NewTSSLServerSocketTimeout(listenAddr string, cfg *tls.Config, clientTimeout time.Duration) (*TSSLServerSocket, error) { if cfg.MinVersion == 0 { cfg.MinVersion = tls.VersionTLS10 } addr, err := net.ResolveTCPAddr("tcp", listenAddr) if err != nil { return nil, err } return &TSSLServerSocket{addr: addr, clientTimeout: clientTimeout, cfg: cfg}, nil } func (p *TSSLServerSocket) Listen() error { if p.IsListening() { return nil } l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg) if err != nil { return err } p.listener = l return nil } func (p *TSSLServerSocket) Accept() (TTransport, error) { if p.interrupted { return nil, errTransportInterrupted } if p.listener == nil { return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") } conn, err := p.listener.Accept() if err != nil { return nil, NewTTransportExceptionFromError(err) } return NewTSSLSocketFromConnTimeout(conn, p.cfg, p.clientTimeout), nil } // Checks whether the socket is listening. func (p *TSSLServerSocket) IsListening() bool { return p.listener != nil } // Connects the socket, creating a new socket object if necessary. func (p *TSSLServerSocket) Open() error { if p.IsListening() { return NewTTransportException(ALREADY_OPEN, "Server socket already open") } if l, err := tls.Listen(p.addr.Network(), p.addr.String(), p.cfg); err != nil { return err } else { p.listener = l } return nil } func (p *TSSLServerSocket) Addr() net.Addr { if p.listener != nil { return p.listener.Addr() } return p.addr } func (p *TSSLServerSocket) Close() error { defer func() { p.listener = nil }() if p.IsListening() { return p.listener.Close() } return nil } func (p *TSSLServerSocket) Interrupt() error { p.interrupted = true return nil } thrift-0.23.0/lib/go/thrift/server_socket_test.go0000664000175000017500000000317115165535636022316 0ustar00buildbuild00000000000000/* * 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 ( "fmt" "testing" ) func TestSocketIsntListeningAfterInterrupt(t *testing.T) { host := "127.0.0.1" port := 9090 addr := fmt.Sprintf("%s:%d", host, port) socket := CreateServerSocket(t, addr) socket.Listen() socket.Interrupt() newSocket := CreateServerSocket(t, addr) err := newSocket.Listen() defer newSocket.Interrupt() if err != nil { t.Fatalf("Failed to rebinds: %s", err) } } func TestSocketConcurrency(t *testing.T) { host := "127.0.0.1" port := 9090 addr := fmt.Sprintf("%s:%d", host, port) socket := CreateServerSocket(t, addr) go func() { socket.Listen() }() go func() { socket.Interrupt() }() } func CreateServerSocket(t *testing.T, addr string) *TServerSocket { socket, err := NewTServerSocket(addr) if err != nil { t.Fatalf("Failed to create server socket: %s", err) } return socket } thrift-0.23.0/lib/go/thrift/uuid.go0000664000175000017500000000701415165535636017347 0ustar00buildbuild00000000000000/* * 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 ( "encoding/hex" "fmt" ) // Tuuid is a minimal implementation of UUID for thrift's read/write operations. // // This implementation only covers read/write in various thrift protocols. // If you need to generate/manipulate/etc. an UUID, // you likely would need a third party UUID library instead. // // This type should be directly cast-able with most popular third party UUID // libraries. // For example, assuming you are using // https://pkg.go.dev/github.com/google/uuid to generate a v4 UUID for an // optional thrift field: // // id, err := uuid.NewRandom() // if err != nil { // // TODO: handle errors // } // myRequest.Uuid = thrift.Pointer(thrift.Tuuid(id)) type Tuuid [16]byte // String generates the canonical form string for an Tuuid. // // This string is suitable for writing with TJSONProtocol. func (u Tuuid) String() string { var buf [36]byte hex.Encode(buf[0:], u[:4]) buf[8] = '-' hex.Encode(buf[9:], u[4:6]) buf[13] = '-' hex.Encode(buf[14:], u[6:8]) buf[18] = '-' hex.Encode(buf[19:], u[8:10]) buf[23] = '-' hex.Encode(buf[24:], u[10:]) return string(buf[:]) } func hexToDec(b byte) (byte, bool) { switch { case b >= '0' && b <= '9': return b - '0', true case b >= 'a' && b <= 'f': return b - 'a' + 10, true case b >= 'A' && b <= 'F': return b - 'A' + 10, true default: return 0, false } } func hexToByte(b1, b2 byte) (b byte, ok bool) { b1, ok = hexToDec(b1) if !ok { return 0, ok } b2, ok = hexToDec(b2) if !ok { return 0, ok } return b1<<4 + b2, true } // ParseTuuid parses a canonical form UUID string into Tuuid. // // Note that this function only supports case insensitive canonical form // (8-4-4-4-12/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx), // and rejects any other forms. // For a more flexible UUID string parser, // please use third party UUID libraries. // // This function is suitable for reading with TJSONProtocol. func ParseTuuid(s string) (u Tuuid, err error) { if len(s) != 36 || s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { return u, fmt.Errorf("malformed Tuuid string: %q", s) } var ok bool for i, j := range []int{ 0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34, } { u[i], ok = hexToByte(s[j], s[j+1]) if !ok { return u, fmt.Errorf("malformed Tuuid string: %q", s) } } return u, nil } // Must is a sugar to be used in places that error handling is impossible (for // example, global variable declarations) and also errors are not in general // expected. // // This is an example to use Must with ParseTuuid to declare a global special // uuid: // // var NameSpaceDNSUUID = thrift.Must(thrift.ParseTuuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) func Must[T any](v T, err error) T { if err != nil { panic(err) } return v } thrift-0.23.0/lib/go/thrift/middleware.go0000664000175000017500000001240515165535636020516 0ustar00buildbuild00000000000000/* * 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 ( "context" ) // ProcessorMiddleware is a function that can be passed to WrapProcessor to wrap the // TProcessorFunctions for that TProcessor. // // Middlewares are passed in the name of the function as set in the processor // map of the TProcessor. type ProcessorMiddleware func(name string, next TProcessorFunction) TProcessorFunction // WrapProcessor takes an existing TProcessor and wraps each of its inner // TProcessorFunctions with the middlewares passed in and returns it. // // Middlewares will be called in the order that they are defined: // // 1. Middlewares[0] // 2. Middlewares[1] // ... // N. Middlewares[n] func WrapProcessor(processor TProcessor, middlewares ...ProcessorMiddleware) TProcessor { for name, processorFunc := range processor.ProcessorMap() { wrapped := processorFunc // Add middlewares in reverse so the first in the list is the outermost. for i := len(middlewares) - 1; i >= 0; i-- { wrapped = middlewares[i](name, wrapped) } processor.AddToProcessorMap(name, wrapped) } return processor } // WrappedTProcessorFunction is a convenience struct that implements the // TProcessorFunction interface that can be used when implementing custom // Middleware. type WrappedTProcessorFunction struct { // Wrapped is called by WrappedTProcessorFunction.Process and should be a // "wrapped" call to a base TProcessorFunc.Process call. Wrapped func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) } // Process implements the TProcessorFunction interface using p.Wrapped. func (p WrappedTProcessorFunction) Process(ctx context.Context, seqID int32, in, out TProtocol) (bool, TException) { return p.Wrapped(ctx, seqID, in, out) } // verify that WrappedTProcessorFunction implements TProcessorFunction var ( _ TProcessorFunction = WrappedTProcessorFunction{} _ TProcessorFunction = (*WrappedTProcessorFunction)(nil) ) // ClientMiddleware can be passed to WrapClient in order to wrap TClient calls // with custom middleware. type ClientMiddleware func(TClient) TClient // WrappedTClient is a convenience struct that implements the TClient interface // using inner Wrapped function. // // This is provided to aid in developing ClientMiddleware. type WrappedTClient struct { Wrapped func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) } // Call implements the TClient interface by calling and returning c.Wrapped. func (c WrappedTClient) Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { return c.Wrapped(ctx, method, args, result) } // verify that WrappedTClient implements TClient var ( _ TClient = WrappedTClient{} _ TClient = (*WrappedTClient)(nil) ) // WrapClient wraps the given TClient in the given middlewares. // // Middlewares will be called in the order that they are defined: // // 1. Middlewares[0] // 2. Middlewares[1] // ... // N. Middlewares[n] func WrapClient(client TClient, middlewares ...ClientMiddleware) TClient { // Add middlewares in reverse so the first in the list is the outermost. for i := len(middlewares) - 1; i >= 0; i-- { client = middlewares[i](client) } return client } // ExtractIDLExceptionClientMiddleware is a ClientMiddleware implementation that // extracts exceptions defined in thrift IDL into the error return of // TClient.Call. It uses ExtractExceptionFromResult under the hood. // // By default if a client call gets an exception defined in the thrift IDL, for // example: // // service MyService { // FooResponse foo(1: FooRequest request) throws ( // 1: Exception1 error1, // 2: Exception2 error2, // ) // } // // Exception1 or Exception2 will not be in the err return of TClient.Call, // but in the result TStruct instead, and there's no easy access to them. // If you have a ClientMiddleware that would need to access them, // you can add this middleware into your client middleware chain, // *after* your other middlewares need them, // then your other middlewares will have access to those exceptions from the err // return. // // Alternatively you can also just use ExtractExceptionFromResult in your client // middleware directly to access those exceptions. func ExtractIDLExceptionClientMiddleware(next TClient) TClient { return WrappedTClient{ Wrapped: func(ctx context.Context, method string, args, result TStruct) (_ ResponseMeta, err error) { defer func() { if err == nil { err = ExtractExceptionFromResult(result) } }() return next.Call(ctx, method, args, result) }, } } thrift-0.23.0/lib/go/thrift/staticcheck.conf0000664000175000017500000000017415165535636021206 0ustar00buildbuild00000000000000checks = [ "inherit", "-ST1005", # To be consistent with other language libraries we need capitalized error messages. ] thrift-0.23.0/lib/go/thrift/socket_unix_conn_test.go0000664000175000017500000000461115165535636023010 0ustar00buildbuild00000000000000// +build !windows /* * 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 ( "io" "net" "testing" "time" ) func TestSocketConnUnix(t *testing.T) { const ( interval = time.Millisecond * 10 first = "hello" second = "world" ) ln, err := serverSocketConn( t, func(tb testing.TB, sc *socketConn) { defer sc.Close() time.Sleep(interval) if !writeFully(tb, sc, first) { return } time.Sleep(interval) writeFully(tb, sc, second) }, ) if err != nil { t.Fatal(err) } defer ln.Close() sc, err := createSocketConnFromReturn(net.Dial("tcp", ln.Addr().String())) if err != nil { t.Fatal(err) } buf := make([]byte, 1024) if !sc.IsOpen() { t.Error("Expected sc to report open, got false") } n, err := sc.Read(buf) if err != nil { t.Fatal(err) } read := string(buf[:n]) if read != first { t.Errorf("Expected read %q, got %q", first, read) } if !sc.IsOpen() { t.Error("Expected sc to report open, got false") } // Do connection check again twice after server already wrote new data, // make sure we don't cause any data loss with the check. time.Sleep(interval * 10) if !sc.IsOpen() { t.Error("Expected sc to report open, got false") } if !sc.IsOpen() { t.Error("Expected sc to report open, got false") } n, err = sc.Read(buf) if err != nil { t.Fatal(err) } read = string(buf[:n]) if read != second { t.Errorf("Expected read %q, got %q", second, read) } // Now it's supposed to be closed on the server side if err := sc.read0(); err != io.EOF { t.Errorf("Expected to get EOF on read0, got %v", err) } if sc.IsOpen() { t.Error("Expected sc to report not open, got true") } } thrift-0.23.0/lib/go/thrift/middleware_test.go0000664000175000017500000000741515165535636021562 0ustar00buildbuild00000000000000/* * 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 ( "context" "testing" ) type counter struct { count int } func (c *counter) incr() { c.count++ } func newCounter(t *testing.T) *counter { c := counter{} if c.count != 0 { t.Fatal("Unexpected initial count.") } return &c } func testProcessorMiddleware(c *counter) ProcessorMiddleware { return func(name string, next TProcessorFunction) TProcessorFunction { return WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { c.incr() return next.Process(ctx, seqId, in, out) }, } } } func testClientMiddleware(c *counter) ClientMiddleware { return func(next TClient) TClient { return WrappedTClient{ Wrapped: func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { c.incr() return next.Call(ctx, method, args, result) }, } } } func TestWrapProcessor(t *testing.T) { name := "test" processor := &mockWrappableProcessor{ ProcessorFuncs: map[string]TProcessorFunction{ name: WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { return true, nil }, }, }, } c := newCounter(t) ctx := setMockWrappableProcessorName(context.Background(), name) wrapped := WrapProcessor(processor, testProcessorMiddleware(c)) wrapped.Process(ctx, nil, nil) if c.count != 1 { t.Fatalf("Unexpected count value %v", c.count) } } func TestWrapTMultiplexedProcessor(t *testing.T) { name := "test" processorName := "foo" c := newCounter(t) processor := &TMultiplexedProcessor{} processor.RegisterDefault(&mockWrappableProcessor{ ProcessorFuncs: map[string]TProcessorFunction{ name: WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { return true, nil }, }, }, }) processor.RegisterProcessor(processorName, &mockWrappableProcessor{ ProcessorFuncs: map[string]TProcessorFunction{ name: WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) { return true, nil }, }, }, }) wrapped := WrapProcessor(processor, testProcessorMiddleware(c)) ctx := setMockWrappableProcessorName(context.Background(), name) in := NewStoredMessageProtocol(nil, name, 1, 1) wrapped.Process(ctx, in, nil) if c.count != 1 { t.Fatalf("Unexpected count value %v", c.count) } in = NewStoredMessageProtocol(nil, processorName+MULTIPLEXED_SEPARATOR+name, 1, 1) wrapped.Process(ctx, in, nil) if c.count != 2 { t.Fatalf("Unexpected count value %v", c.count) } } func TestWrapClient(t *testing.T) { client := WrappedTClient{ Wrapped: func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { return ResponseMeta{}, nil }, } c := newCounter(t) wrapped := WrapClient(client, testClientMiddleware(c)) wrapped.Call(context.Background(), "test", nil, nil) if c.count != 1 { t.Fatalf("Unexpected count value %v", c.count) } } thrift-0.23.0/lib/go/thrift/pool_test.go0000664000175000017500000000252015165535636020406 0ustar00buildbuild00000000000000/* * 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 ( "testing" "testing/quick" ) type poolTest int func TestPoolReset(t *testing.T) { p := newPool(nil, func(elem *poolTest) { *elem = 0 }) f := func(i int) (passed bool) { pt := p.get() defer func() { p.put(&pt) if pt != nil { t.Errorf("Expected pt to be nil after put, got %#v", pt) passed = false } }() if *pt != 0 { t.Errorf("Expected *pt to be reset to 0 after get, got %d", *pt) } *pt = poolTest(i) return !t.Failed() } if err := quick.Check(f, nil); err != nil { t.Error(err) } } thrift-0.23.0/lib/go/thrift/buffered_transport_test.go0000664000175000017500000000172415165535636023340 0ustar00buildbuild00000000000000/* * 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 ( "testing" ) func TestBufferedTransport(t *testing.T) { trans := NewTBufferedTransport(NewTMemoryBuffer(), 10240) TransportTest(t, trans, trans) } thrift-0.23.0/lib/go/thrift/header_transport_test.go0000664000175000017500000002323515165535636023007 0ustar00buildbuild00000000000000/* * 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 ( "context" "fmt" "io" "strings" "testing" "testing/iotest" "testing/quick" ) func testTHeaderHeadersReadWriteProtocolID(t *testing.T, protoID THeaderProtocolID) { trans := NewTMemoryBuffer() reader := NewTHeaderTransport(trans) writer := NewTHeaderTransportConf(trans, &TConfiguration{ THeaderProtocolID: &protoID, }) const key1 = "key1" const value1 = "value1" const key2 = "key2" const value2 = "value2" const payload1 = "hello, world1\n" const payload2 = "hello, world2\n" // Write if err := writer.AddTransform(TransformZlib); err != nil { t.Fatalf( "writer.AddTransform(TransformZlib) returned error: %v", err, ) } // Use double zlib to make sure that we close them in the right order. if err := writer.AddTransform(TransformZlib); err != nil { t.Fatalf( "writer.AddTransform(TransformZlib) returned error: %v", err, ) } if err := writer.AddTransform(TransformNone); err != nil { t.Fatalf( "writer.AddTransform(TransformNone) returned error: %v", err, ) } writer.SetWriteHeader(key1, value1) writer.SetWriteHeader(key2, value2) if _, err := writer.Write([]byte(payload1)); err != nil { t.Errorf("writer.Write returned error: %v", err) } if err := writer.Flush(context.Background()); err != nil { t.Errorf("writer.Flush returned error: %v", err) } if _, err := writer.Write([]byte(payload2)); err != nil { t.Errorf("writer.Write returned error: %v", err) } if err := writer.Flush(context.Background()); err != nil { t.Errorf("writer.Flush returned error: %v", err) } // Read // Make sure multiple calls to ReadFrame is fine. if err := reader.ReadFrame(context.Background()); err != nil { t.Errorf("reader.ReadFrame returned error: %v", err) } if err := reader.ReadFrame(context.Background()); err != nil { t.Errorf("reader.ReadFrame returned error: %v", err) } read, err := io.ReadAll(reader) if err != nil { t.Errorf("Read returned error: %v", err) } if err := reader.ReadFrame(context.Background()); err != nil && err != io.EOF { t.Errorf("reader.ReadFrame returned error: %v", err) } if string(read) != payload1+payload2 { t.Errorf( "Read content expected %q, got %q", payload1+payload2, read, ) } if prot := reader.Protocol(); prot != protoID { t.Errorf( "reader.Protocol() expected %d, got %d", protoID, prot, ) } if reader.clientType != clientHeaders { t.Errorf( "reader.clientType expected %d, got %d", clientHeaders, reader.clientType, ) } headers := reader.GetReadHeaders() if len(headers) != 2 || headers[key1] != value1 || headers[key2] != value2 { t.Errorf( "reader.GetReadHeaders() expected size 2, actual content: %+v", headers, ) } } func TestTHeaderHeadersReadWrite(t *testing.T) { for label, id := range map[string]THeaderProtocolID{ "default": THeaderProtocolDefault, "binary": THeaderProtocolBinary, "compact": THeaderProtocolCompact, } { t.Run(label, func(t *testing.T) { testTHeaderHeadersReadWriteProtocolID(t, id) }) } } func TestTHeaderTransportNoDoubleWrapping(t *testing.T) { trans := NewTMemoryBuffer() orig := NewTHeaderTransport(trans) wrapped := NewTHeaderTransport(orig) if wrapped != orig { t.Errorf("NewTHeaderTransport double wrapped THeaderTransport") } } func TestTHeaderTransportNoReadBeyondFrame(t *testing.T) { trans := NewTMemoryBuffer() writeContent := func(writer TTransport, content string) error { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { return err } if err := writer.Flush(context.Background()); err != nil { return err } return nil } f := func(content string) bool { trans.Reset() if len(content) == 0 { return true } reader := NewTHeaderTransport(trans) writer := NewTHeaderTransport(trans) // Write content twice if err := writeContent(writer, content); err != nil { t.Error(err) } if err := writeContent(writer, content); err != nil { t.Error(err) } // buf is big enough to read both content out, // but it shouldn't read beyond the first one in a single Read call. buf := make([]byte, len(content)*3) read, err := reader.Read(buf) if err != nil { t.Error(err) } if read == 0 || read > len(content) { t.Errorf( "Expected read in no more than %d:%q, got %d:%q", len(content), content, read, buf[:read], ) } // Check for endOfFrame handling if !reader.needReadFrame() { t.Error("Expected needReadFrame to be true after read the frame fully, got false") } return !t.Failed() } if err := quick.Check(f, nil); err != nil { t.Error(err) } } func TestTHeaderTransportEndOfFrameHandling(t *testing.T) { trans := NewTMemoryBuffer() writeContent := func(writer TTransport, content string) error { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { return err } if err := writer.Flush(context.Background()); err != nil { return err } return nil } readFully := func(content string) bool { trans.Reset() if len(content) == 0 { return true } reader := NewTHeaderTransport(trans) writer := NewTHeaderTransport(trans) // Write content if err := writeContent(writer, content); err != nil { t.Error(err) } buf := make([]byte, len(content)) _, err := reader.Read(buf) if err != nil { t.Error(err) } if !reader.needReadFrame() { t.Error("Expected needReadFrame to be true after read the frame fully, got false") } return !t.Failed() } if err := quick.Check(readFully, nil); err != nil { t.Error(err) } readPartially := func(content string) bool { trans.Reset() if len(content) < 1 { return true } reader := NewTHeaderTransport(trans) writer := NewTHeaderTransport(trans) // Write content if err := writeContent(writer, content); err != nil { t.Error(err) } // Make the buf smaller so it can't read fully buf := make([]byte, len(content)-1) _, err := reader.Read(buf) if err != nil { t.Error(err) } if reader.needReadFrame() { t.Error("Expected needReadFrame to be false before read the frame fully, got true") } return !t.Failed() } if err := quick.Check(readPartially, nil); err != nil { t.Error(err) } } func BenchmarkTHeaderProtocolIDValidate(b *testing.B) { for _, c := range []THeaderProtocolID{ THeaderProtocolBinary, THeaderProtocolCompact, -1, } { b.Run(fmt.Sprintf("%2v", c), func(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { c.Validate() } }) }) } } func TestSetTHeaderTransportProtocolID(t *testing.T) { const expected = THeaderProtocolCompact factory := NewTHeaderTransportFactoryConf(nil, &TConfiguration{ THeaderProtocolID: THeaderProtocolIDPtrMust(expected), }) buf := NewTMemoryBuffer() trans, err := factory.GetTransport(buf) if err != nil { t.Fatalf("Failed to get transport from factory: %v", err) } ht, ok := trans.(*THeaderTransport) if !ok { t.Fatalf("Transport is not *THeaderTransport: %#v", trans) } if actual := ht.Protocol(); actual != expected { t.Errorf("Expected protocol id %v, got %v", expected, actual) } ht.SetTConfiguration(&TConfiguration{}) if actual := ht.Protocol(); actual != expected { t.Errorf("Expected protocol id %v, got %v", expected, actual) } } func TestTHeaderTransportReuseTransport(t *testing.T) { const ( content = "Hello, world!" n = 10 ) trans := NewTMemoryBuffer() reader := NewTHeaderTransport(trans) writer := NewTHeaderTransport(trans) t.Run("pair", func(t *testing.T) { 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) } if err := writer.Flush(context.Background()); err != nil { t.Fatalf("Failed to flush on #%d: %v", i, err) } // read read, err := io.ReadAll(iotest.OneByteReader(reader)) if err != nil { t.Errorf("Failed to read on #%d: %v", i, err) } if string(read) != content { t.Errorf("Read #%d: want %q, got %q", i, content, read) } } }) t.Run("batched", func(t *testing.T) { // write for i := range n { if _, err := io.Copy(writer, strings.NewReader(content)); err != nil { t.Fatalf("Failed to write on #%d: %v", i, err) } if err := writer.Flush(context.Background()); err != nil { t.Fatalf("Failed to flush on #%d: %v", i, err) } } // read for i := range n { const ( size = len(content) ) var buf []byte var err error if i%2 == 0 { // on even calls, use OneByteReader to make // sure that small reads are fine buf, err = io.ReadAll(io.LimitReader(iotest.OneByteReader(reader), int64(size))) } else { // on odd calls, make sure that we don't read // more than written per frame buf = make([]byte, size*2) var n int n, err = reader.Read(buf) buf = buf[:n] } if err != nil { t.Errorf("Failed to read on #%d: %v", i, err) } if string(buf) != content { t.Errorf("Read #%d: want %q, got %q", i, content, buf) } } }) } thrift-0.23.0/lib/go/thrift/header_context.go0000664000175000017500000000565615165535636021407 0ustar00buildbuild00000000000000/* * 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 ( "context" ) // See https://godoc.org/context#WithValue on why do we need the unexported typedefs. type ( headerKey string headerKeyList int ) // Values for headerKeyList. const ( headerKeyListRead headerKeyList = iota headerKeyListWrite ) // SetHeader sets a header in the context. func SetHeader(ctx context.Context, key, value string) context.Context { return context.WithValue( ctx, headerKey(key), value, ) } // UnsetHeader unsets a previously set header in the context. func UnsetHeader(ctx context.Context, key string) context.Context { return context.WithValue( ctx, headerKey(key), nil, ) } // GetHeader returns a value of the given header from the context. func GetHeader(ctx context.Context, key string) (value string, ok bool) { if v := ctx.Value(headerKey(key)); v != nil { value, ok = v.(string) } return } // SetReadHeaderList sets the key list of read THeaders in the context. func SetReadHeaderList(ctx context.Context, keys []string) context.Context { return context.WithValue( ctx, headerKeyListRead, keys, ) } // GetReadHeaderList returns the key list of read THeaders from the context. func GetReadHeaderList(ctx context.Context) []string { if v := ctx.Value(headerKeyListRead); v != nil { if value, ok := v.([]string); ok { return value } } return nil } // SetWriteHeaderList sets the key list of THeaders to write in the context. func SetWriteHeaderList(ctx context.Context, keys []string) context.Context { return context.WithValue( ctx, headerKeyListWrite, keys, ) } // GetWriteHeaderList returns the key list of THeaders to write from the context. func GetWriteHeaderList(ctx context.Context) []string { if v := ctx.Value(headerKeyListWrite); v != nil { if value, ok := v.([]string); ok { return value } } return nil } // AddReadTHeaderToContext adds the whole THeader headers into context. func AddReadTHeaderToContext(ctx context.Context, headers THeaderMap) context.Context { keys := make([]string, 0, len(headers)) for key, value := range headers { ctx = SetHeader(ctx, key, value) keys = append(keys, key) } return SetReadHeaderList(ctx, keys) } thrift-0.23.0/lib/go/thrift/transport_exception.go0000664000175000017500000000536415165535636022521 0ustar00buildbuild00000000000000/* * 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 ( "errors" "io" ) type timeoutable interface { Timeout() bool } // Thrift Transport exception type TTransportException interface { TException TypeId() int Err() error } const ( UNKNOWN_TRANSPORT_EXCEPTION = 0 NOT_OPEN = 1 ALREADY_OPEN = 2 TIMED_OUT = 3 END_OF_FILE = 4 ) type tTransportException struct { typeId int err error msg string } var _ TTransportException = (*tTransportException)(nil) func (tTransportException) TExceptionType() TExceptionType { return TExceptionTypeTransport } func (p *tTransportException) TypeId() int { return p.typeId } func (p *tTransportException) Error() string { return p.msg } func (p *tTransportException) Err() error { return p.err } func (p *tTransportException) Unwrap() error { return p.err } func (p *tTransportException) Timeout() bool { return p.typeId == TIMED_OUT || isTimeoutError(p.err) } func NewTTransportException(t int, e string) TTransportException { return &tTransportException{ typeId: t, err: errors.New(e), msg: e, } } func NewTTransportExceptionFromError(e error) TTransportException { if e == nil { return nil } if t, ok := e.(TTransportException); ok { return t } te := &tTransportException{ typeId: UNKNOWN_TRANSPORT_EXCEPTION, err: e, msg: e.Error(), } if isTimeoutError(e) { te.typeId = TIMED_OUT return te } if errors.Is(e, io.EOF) { te.typeId = END_OF_FILE return te } return te } func prependTTransportException(prepend string, e TTransportException) TTransportException { return &tTransportException{ typeId: e.TypeId(), err: e, msg: prepend + e.Error(), } } // isTimeoutError returns true when err is an error caused by timeout. // // Note that this also includes TTransportException wrapped timeout errors. func isTimeoutError(err error) bool { var t timeoutable if errors.As(err, &t) { return t.Timeout() } return false } thrift-0.23.0/lib/go/thrift/zlib_transport_test.go0000664000175000017500000000337115165535636022516 0ustar00buildbuild00000000000000/* * 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 ( "compress/zlib" "testing" ) func TestZlibTransport(t *testing.T) { trans, err := NewTZlibTransport(NewTMemoryBuffer(), zlib.BestCompression) if err != nil { t.Fatal(err) } TransportTest(t, trans, trans) } type DummyTransportFactory struct{} func (p *DummyTransportFactory) GetTransport(trans TTransport) (TTransport, error) { return NewTMemoryBuffer(), nil } func TestZlibFactoryTransportWithFactory(t *testing.T) { factory := NewTZlibTransportFactoryWithFactory( zlib.BestCompression, &DummyTransportFactory{}, ) buffer := NewTMemoryBuffer() trans, err := factory.GetTransport(buffer) if err != nil { t.Fatal(err) } TransportTest(t, trans, trans) } func TestZlibFactoryTransportWithoutFactory(t *testing.T) { factory := NewTZlibTransportFactoryWithFactory(zlib.BestCompression, nil) buffer := NewTMemoryBuffer() trans, err := factory.GetTransport(buffer) if err != nil { t.Fatal(err) } TransportTest(t, trans, trans) } thrift-0.23.0/lib/go/thrift/memory_buffer_test.go0000664000175000017500000000167015165535636022303 0ustar00buildbuild00000000000000/* * 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 ( "testing" ) func TestMemoryBuffer(t *testing.T) { trans := NewTMemoryBufferLen(1024) TransportTest(t, trans, trans) } thrift-0.23.0/lib/go/thrift/compact_protocol_test.go0000664000175000017500000000414615165535636023012 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "testing" ) func TestReadWriteCompactProtocol(t *testing.T) { ReadWriteProtocolTest(t, NewTCompactProtocolFactory()) transports := []TTransport{ NewTMemoryBuffer(), NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 16384))), NewTFramedTransport(NewTMemoryBuffer()), } newTZlibTransport := func(trans TTransport, level int) *TZlibTransport { t.Helper() zlibTrans, err := NewTZlibTransport(trans, level) if err != nil { t.Fatalf("NewTZlibTransport returned error: %v", err) } return zlibTrans } zlib0 := newTZlibTransport(NewTMemoryBuffer(), 0) zlib6 := newTZlibTransport(NewTMemoryBuffer(), 6) zlib9 := newTZlibTransport(NewTFramedTransport(NewTMemoryBuffer()), 9) transports = append(transports, zlib0, zlib6, zlib9) for _, trans := range transports { p := NewTCompactProtocol(trans) ReadWriteBool(t, p, trans) p = NewTCompactProtocol(trans) ReadWriteByte(t, p, trans) p = NewTCompactProtocol(trans) ReadWriteI16(t, p, trans) p = NewTCompactProtocol(trans) ReadWriteI32(t, p, trans) p = NewTCompactProtocol(trans) ReadWriteI64(t, p, trans) p = NewTCompactProtocol(trans) ReadWriteDouble(t, p, trans) p = NewTCompactProtocol(trans) ReadWriteString(t, p, trans) p = NewTCompactProtocol(trans) ReadWriteBinary(t, p, trans) trans.Close() } } thrift-0.23.0/lib/go/thrift/protocol_exception.go0000664000175000017500000000455615165535636022330 0ustar00buildbuild00000000000000/* * 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 ( "encoding/base64" "errors" ) // Thrift Protocol exception type TProtocolException interface { TException TypeId() int } const ( UNKNOWN_PROTOCOL_EXCEPTION = 0 INVALID_DATA = 1 NEGATIVE_SIZE = 2 SIZE_LIMIT = 3 BAD_VERSION = 4 NOT_IMPLEMENTED = 5 DEPTH_LIMIT = 6 ) type tProtocolException struct { typeId int err error msg string } var _ TProtocolException = (*tProtocolException)(nil) func (tProtocolException) TExceptionType() TExceptionType { return TExceptionTypeProtocol } func (p *tProtocolException) TypeId() int { return p.typeId } func (p *tProtocolException) String() string { return p.msg } func (p *tProtocolException) Error() string { return p.msg } func (p *tProtocolException) Unwrap() error { return p.err } func NewTProtocolException(err error) TProtocolException { if err == nil { return nil } if e, ok := err.(TProtocolException); ok { return e } if errors.As(err, new(base64.CorruptInputError)) { return NewTProtocolExceptionWithType(INVALID_DATA, err) } return NewTProtocolExceptionWithType(UNKNOWN_PROTOCOL_EXCEPTION, err) } func NewTProtocolExceptionWithType(errType int, err error) TProtocolException { if err == nil { return nil } return &tProtocolException{ typeId: errType, err: err, msg: err.Error(), } } func prependTProtocolException(prepend string, err TProtocolException) TProtocolException { return &tProtocolException{ typeId: err.TypeId(), err: err, msg: prepend + err.Error(), } } thrift-0.23.0/lib/go/thrift/server_transport.go0000664000175000017500000000244615165535636022027 0ustar00buildbuild00000000000000/* * 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 // Server transport. Object which provides client transports. type TServerTransport interface { Listen() error Accept() (TTransport, error) Close() error // Optional method implementation. This signals to the server transport // that it should break out of any accept() or listen() that it is currently // blocked on. This method, if implemented, MUST be thread safe, as it may // be called from a different thread context than the other TServerTransport // methods. Interrupt() error } thrift-0.23.0/lib/go/thrift/header_context_test.go0000664000175000017500000000573615165535636022445 0ustar00buildbuild00000000000000/* * 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 ( "context" "reflect" "testing" ) func TestSetGetUnsetHeader(t *testing.T) { const ( key = "foo" value = "bar" ) ctx := context.Background() ctx = SetHeader(ctx, key, value) checkGet := func(t *testing.T, ctx context.Context) { t.Helper() got, ok := GetHeader(ctx, key) if !ok { t.Fatalf("Cannot get header %q back after setting it.", key) } if got != value { t.Fatalf("Header value expected %q, got %q instead", value, got) } } checkGet(t, ctx) t.Run( "NoConflicts", func(t *testing.T) { type otherType string const otherValue = "bar2" ctx = context.WithValue(ctx, otherType(key), otherValue) checkGet(t, ctx) }, ) t.Run( "GetHeaderOnNonExistKey", func(t *testing.T) { const otherKey = "foo2" if _, ok := GetHeader(ctx, otherKey); ok { t.Errorf("GetHeader returned ok on non-existing key %q", otherKey) } }, ) t.Run( "Unset", func(t *testing.T) { ctx := UnsetHeader(ctx, key) if _, ok := GetHeader(ctx, key); ok { t.Errorf("GetHeader returned ok on unset key %q", key) } }, ) } func TestReadKeyList(t *testing.T) { headers := THeaderMap{ "key1": "value1", "key2": "value2", } ctx := context.Background() ctx = AddReadTHeaderToContext(ctx, headers) got := make(THeaderMap) keys := GetReadHeaderList(ctx) t.Logf("keys: %+v", keys) for _, key := range keys { value, ok := GetHeader(ctx, key) if ok { got[key] = value } else { t.Errorf("Cannot get key %q from context", key) } } if !reflect.DeepEqual(headers, got) { t.Errorf("Expected header map %+v, got %+v", headers, got) } writtenKeys := GetWriteHeaderList(ctx) if len(writtenKeys) > 0 { t.Errorf( "Expected empty GetWriteHeaderList() result, got %+v", writtenKeys, ) } } func TestWriteKeyList(t *testing.T) { keys := []string{ "key1", "key2", } ctx := context.Background() ctx = SetWriteHeaderList(ctx, keys) got := GetWriteHeaderList(ctx) if !reflect.DeepEqual(keys, got) { t.Errorf("Expected header keys %+v, got %+v", keys, got) } readKeys := GetReadHeaderList(ctx) if len(readKeys) > 0 { t.Errorf( "Expected empty GetReadHeaderList() result, got %+v", readKeys, ) } } thrift-0.23.0/lib/go/thrift/protocol.go0000664000175000017500000001333315165535636020243 0ustar00buildbuild00000000000000/* * 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 ( "context" "errors" "fmt" ) const ( VERSION_MASK = 0xffff0000 VERSION_1 = 0x80010000 ) type TProtocol interface { WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error WriteMessageEnd(ctx context.Context) error WriteStructBegin(ctx context.Context, name string) error WriteStructEnd(ctx context.Context) error WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error WriteFieldEnd(ctx context.Context) error WriteFieldStop(ctx context.Context) error WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error WriteMapEnd(ctx context.Context) error WriteListBegin(ctx context.Context, elemType TType, size int) error WriteListEnd(ctx context.Context) error WriteSetBegin(ctx context.Context, elemType TType, size int) error WriteSetEnd(ctx context.Context) error WriteBool(ctx context.Context, value bool) error WriteByte(ctx context.Context, value int8) error WriteI16(ctx context.Context, value int16) error WriteI32(ctx context.Context, value int32) error WriteI64(ctx context.Context, value int64) error WriteDouble(ctx context.Context, value float64) error WriteString(ctx context.Context, value string) error WriteBinary(ctx context.Context, value []byte) error WriteUUID(ctx context.Context, value Tuuid) error ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) ReadMessageEnd(ctx context.Context) error ReadStructBegin(ctx context.Context) (name string, err error) ReadStructEnd(ctx context.Context) error ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) ReadFieldEnd(ctx context.Context) error ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) ReadMapEnd(ctx context.Context) error ReadListBegin(ctx context.Context) (elemType TType, size int, err error) ReadListEnd(ctx context.Context) error ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) ReadSetEnd(ctx context.Context) error ReadBool(ctx context.Context) (value bool, err error) ReadByte(ctx context.Context) (value int8, err error) ReadI16(ctx context.Context) (value int16, err error) ReadI32(ctx context.Context) (value int32, err error) ReadI64(ctx context.Context) (value int64, err error) ReadDouble(ctx context.Context) (value float64, err error) ReadString(ctx context.Context) (value string, err error) ReadBinary(ctx context.Context) (value []byte, err error) ReadUUID(ctx context.Context) (value Tuuid, err error) Skip(ctx context.Context, fieldType TType) (err error) Flush(ctx context.Context) (err error) Transport() TTransport } // The maximum recursive depth the skip() function will traverse const DEFAULT_RECURSION_DEPTH = 64 // Skips over the next data element from the provided input TProtocol object. func SkipDefaultDepth(ctx context.Context, prot TProtocol, typeId TType) (err error) { return Skip(ctx, prot, typeId, DEFAULT_RECURSION_DEPTH) } // Skips over the next data element from the provided input TProtocol object. func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (err error) { if maxDepth <= 0 { return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded")) } switch fieldType { case BOOL: _, err = self.ReadBool(ctx) return case BYTE: _, err = self.ReadByte(ctx) return case I16: _, err = self.ReadI16(ctx) return case I32: _, err = self.ReadI32(ctx) return case I64: _, err = self.ReadI64(ctx) return case DOUBLE: _, err = self.ReadDouble(ctx) return case STRING: _, err = self.ReadString(ctx) return case UUID: _, err = self.ReadUUID(ctx) return case STRUCT: if _, err = self.ReadStructBegin(ctx); err != nil { return err } for { _, typeId, _, err := self.ReadFieldBegin(ctx) if err != nil { return err } if typeId == STOP { break } err = Skip(ctx, self, typeId, maxDepth-1) if err != nil { return err } self.ReadFieldEnd(ctx) } return self.ReadStructEnd(ctx) case MAP: keyType, valueType, size, err := self.ReadMapBegin(ctx) if err != nil { return err } for range size { err := Skip(ctx, self, keyType, maxDepth-1) if err != nil { return err } err = Skip(ctx, self, valueType, maxDepth-1) if err != nil { return err } } return self.ReadMapEnd(ctx) case SET: elemType, size, err := self.ReadSetBegin(ctx) if err != nil { return err } for range size { err := Skip(ctx, self, elemType, maxDepth-1) if err != nil { return err } } return self.ReadSetEnd(ctx) case LIST: elemType, size, err := self.ReadListBegin(ctx) if err != nil { return err } for range size { err := Skip(ctx, self, elemType, maxDepth-1) if err != nil { return err } } return self.ReadListEnd(ctx) default: return NewTProtocolExceptionWithType(INVALID_DATA, fmt.Errorf("Unknown data type %d", fieldType)) } } thrift-0.23.0/lib/go/thrift/example_client_middleware_test.go0000664000175000017500000000444715165535636024635 0ustar00buildbuild00000000000000/* * 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 ( "context" "log" ) // BEGIN THRIFT GENERATED CODE SECTION // // In real code this section should be from thrift generated code instead, // but for this example we just define some placeholders here. type MyEndpointRequest struct{} type MyEndpointResponse struct{} type MyService interface { MyEndpoint(ctx context.Context, req *MyEndpointRequest) (*MyEndpointResponse, error) } func NewMyServiceClient(_ TClient) MyService { // In real code this certainly won't return nil. return nil } // END THRIFT GENERATED CODE SECTION func simpleClientLoggingMiddleware(next TClient) TClient { return WrappedTClient{ Wrapped: func(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { log.Printf("Before: %q", method) log.Printf("Args: %#v", args) headers, err := next.Call(ctx, method, args, result) log.Printf("After: %q", method) log.Printf("Result: %#v", result) if err != nil { log.Printf("Error: %v", err) } return headers, err }, } } // This example demonstrates how to define and use a simple logging middleware // to your thrift client. func ExampleClientMiddleware() { var ( trans TTransport protoFactory TProtocolFactory ) var client TClient client = NewTStandardClient( protoFactory.GetProtocol(trans), protoFactory.GetProtocol(trans), ) client = WrapClient(client, simpleClientLoggingMiddleware) myServiceClient := NewMyServiceClient(client) myServiceClient.MyEndpoint(context.Background(), &MyEndpointRequest{}) } thrift-0.23.0/lib/go/thrift/socket_conn_test.go0000664000175000017500000000526115165535636021747 0ustar00buildbuild00000000000000/* * 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 ( "io" "net" "strings" "testing" "time" ) type serverSocketConnCallback func(testing.TB, *socketConn) func serverSocketConn(tb testing.TB, f serverSocketConnCallback) (net.Listener, error) { tb.Helper() ln, err := net.Listen("tcp", "localhost:0") if err != nil { return nil, err } go func() { for { sc, err := createSocketConnFromReturn(ln.Accept()) if err != nil { // This is usually caused by Listener being // closed, not really an error. return } go f(tb, sc) } }() return ln, nil } func writeFully(tb testing.TB, w io.Writer, s string) bool { tb.Helper() n, err := io.Copy(w, strings.NewReader(s)) if err != nil { tb.Errorf("Failed to write %q: %v", s, err) return false } if int(n) < len(s) { tb.Errorf("Only wrote %d out of %q", n, s) return false } return true } func TestSocketConn(t *testing.T) { const ( interval = time.Millisecond * 10 first = "hello" second = "world" ) ln, err := serverSocketConn( t, func(tb testing.TB, sc *socketConn) { defer sc.Close() if !writeFully(tb, sc, first) { return } time.Sleep(interval) writeFully(tb, sc, second) }, ) if err != nil { t.Fatal(err) } defer ln.Close() sc, err := createSocketConnFromReturn(net.Dial("tcp", ln.Addr().String())) if err != nil { t.Fatal(err) } buf := make([]byte, 1024) n, err := sc.Read(buf) if err != nil { t.Fatal(err) } read := string(buf[:n]) if read != first { t.Errorf("Expected read %q, got %q", first, read) } n, err = sc.Read(buf) if err != nil { t.Fatal(err) } read = string(buf[:n]) if read != second { t.Errorf("Expected read %q, got %q", second, read) } } func TestSocketConnNilSafe(t *testing.T) { sc := (*socketConn)(nil) if sc.isValid() { t.Error("Expected false for nil.isValid(), got true") } if sc.IsOpen() { t.Error("Expected false for nil.IsOpen(), got true") } } thrift-0.23.0/lib/go/thrift/server_socket.go0000664000175000017500000000635715167543515021265 0ustar00buildbuild00000000000000/* * 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 ( "net" "sync" "time" ) type TServerSocket struct { addr net.Addr clientTimeout time.Duration // Protects the listener and interrupted fields to make them thread safe. mu sync.RWMutex listener net.Listener interrupted bool } func NewTServerSocket(listenAddr string) (*TServerSocket, error) { return NewTServerSocketTimeout(listenAddr, 0) } func NewTServerSocketTimeout(listenAddr string, clientTimeout time.Duration) (*TServerSocket, error) { addr, err := net.ResolveTCPAddr("tcp", listenAddr) if err != nil { return nil, err } return &TServerSocket{addr: addr, clientTimeout: clientTimeout}, nil } // Creates a TServerSocket from a net.Addr func NewTServerSocketFromAddrTimeout(addr net.Addr, clientTimeout time.Duration) *TServerSocket { return &TServerSocket{addr: addr, clientTimeout: clientTimeout} } func (p *TServerSocket) Listen() error { p.mu.Lock() defer p.mu.Unlock() if p.IsListening() { return nil } l, err := net.Listen(p.addr.Network(), p.addr.String()) if err != nil { return err } p.listener = l return nil } func (p *TServerSocket) Accept() (TTransport, error) { p.mu.RLock() interrupted := p.interrupted listener := p.listener p.mu.RUnlock() if interrupted { return nil, errTransportInterrupted } if listener == nil { return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") } conn, err := listener.Accept() if err != nil { return nil, NewTTransportExceptionFromError(err) } return NewTSocketFromConnTimeout(conn, p.clientTimeout), nil } // Checks whether the socket is listening. func (p *TServerSocket) IsListening() bool { return p.listener != nil } // Connects the socket, creating a new socket object if necessary. func (p *TServerSocket) Open() error { p.mu.Lock() defer p.mu.Unlock() if p.IsListening() { return NewTTransportException(ALREADY_OPEN, "Server socket already open") } if l, err := net.Listen(p.addr.Network(), p.addr.String()); err != nil { return err } else { p.listener = l } return nil } func (p *TServerSocket) Addr() net.Addr { p.mu.RLock() defer p.mu.RUnlock() if p.IsListening() { return p.listener.Addr() } return p.addr } func (p *TServerSocket) Close() error { var err error p.mu.Lock() if p.IsListening() { err = p.listener.Close() p.listener = nil } p.mu.Unlock() return err } func (p *TServerSocket) Interrupt() error { p.mu.Lock() p.interrupted = true p.mu.Unlock() p.Close() return nil } thrift-0.23.0/lib/go/thrift/protocol_factory.go0000664000175000017500000000167415165535636021777 0ustar00buildbuild00000000000000/* * 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 // Factory interface for constructing protocol instances. type TProtocolFactory interface { GetProtocol(trans TTransport) TProtocol } thrift-0.23.0/lib/go/thrift/response_helper.go0000664000175000017500000000575315165535636021606 0ustar00buildbuild00000000000000/* * 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 ( "context" ) // See https://godoc.org/context#WithValue on why do we need the unexported typedefs. type responseHelperKey struct{} // TResponseHelper defines a object with a set of helper functions that can be // retrieved from the context object passed into server handler functions. // // Use GetResponseHelper to retrieve the injected TResponseHelper implementation // from the context object. // // The zero value of TResponseHelper is valid with all helper functions being // no-op. type TResponseHelper struct { // THeader related functions *THeaderResponseHelper } // THeaderResponseHelper defines THeader related TResponseHelper functions. // // The zero value of *THeaderResponseHelper is valid with all helper functions // being no-op. type THeaderResponseHelper struct { proto *THeaderProtocol } // NewTHeaderResponseHelper creates a new THeaderResponseHelper from the // underlying TProtocol. func NewTHeaderResponseHelper(proto TProtocol) *THeaderResponseHelper { if hp, ok := proto.(*THeaderProtocol); ok { return &THeaderResponseHelper{ proto: hp, } } return nil } // SetHeader sets a response header. // // It's no-op if the underlying protocol/transport does not support THeader. func (h *THeaderResponseHelper) SetHeader(key, value string) { if h != nil && h.proto != nil { h.proto.SetWriteHeader(key, value) } } // ClearHeaders clears all the response headers previously set. // // It's no-op if the underlying protocol/transport does not support THeader. func (h *THeaderResponseHelper) ClearHeaders() { if h != nil && h.proto != nil { h.proto.ClearWriteHeaders() } } // GetResponseHelper retrieves the TResponseHelper implementation injected into // the context object. // // If no helper was found in the context object, a nop helper with ok == false // will be returned. func GetResponseHelper(ctx context.Context) (helper TResponseHelper, ok bool) { if v := ctx.Value(responseHelperKey{}); v != nil { helper, ok = v.(TResponseHelper) } return } // SetResponseHelper injects TResponseHelper into the context object. func SetResponseHelper(ctx context.Context, helper TResponseHelper) context.Context { return context.WithValue(ctx, responseHelperKey{}, helper) } thrift-0.23.0/lib/go/thrift/context.go0000664000175000017500000000155515165535636020071 0ustar00buildbuild00000000000000/* * 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 "context" var defaultCtx = context.Background() thrift-0.23.0/lib/go/thrift/client.go0000664000175000017500000000555415165535636017666 0ustar00buildbuild00000000000000package thrift import ( "context" "fmt" ) // ResponseMeta represents the metadata attached to the response. type ResponseMeta struct { // The headers in the response, if any. // If the underlying transport/protocol is not THeader, this will always be nil. Headers THeaderMap } type TClient interface { Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) } type TStandardClient struct { seqId int32 iprot, oprot TProtocol } // TStandardClient implements TClient, and uses the standard message format for Thrift. // It is not safe for concurrent use. func NewTStandardClient(inputProtocol, outputProtocol TProtocol) *TStandardClient { return &TStandardClient{ iprot: inputProtocol, oprot: outputProtocol, } } func (p *TStandardClient) Send(ctx context.Context, oprot TProtocol, seqId int32, method string, args TStruct) error { // Set headers from context object on THeaderProtocol if headerProt, ok := oprot.(*THeaderProtocol); ok { headerProt.ClearWriteHeaders() for _, key := range GetWriteHeaderList(ctx) { if value, ok := GetHeader(ctx, key); ok { headerProt.SetWriteHeader(key, value) } } } if err := oprot.WriteMessageBegin(ctx, method, CALL, seqId); err != nil { return err } if err := args.Write(ctx, oprot); err != nil { return err } if err := oprot.WriteMessageEnd(ctx); err != nil { return err } return oprot.Flush(ctx) } func (p *TStandardClient) Recv(ctx context.Context, iprot TProtocol, seqId int32, method string, result TStruct) error { rMethod, rTypeId, rSeqId, err := iprot.ReadMessageBegin(ctx) if err != nil { return err } if method != rMethod { return NewTApplicationException(WRONG_METHOD_NAME, fmt.Sprintf("%s: wrong method name", method)) } else if seqId != rSeqId { return NewTApplicationException(BAD_SEQUENCE_ID, fmt.Sprintf("%s: out of order sequence response", method)) } else if rTypeId == EXCEPTION { var exception tApplicationException if err := exception.Read(ctx, iprot); err != nil { return err } if err := iprot.ReadMessageEnd(ctx); err != nil { return err } return &exception } else if rTypeId != REPLY { return NewTApplicationException(INVALID_MESSAGE_TYPE_EXCEPTION, fmt.Sprintf("%s: invalid message type", method)) } if err := result.Read(ctx, iprot); err != nil { return err } return iprot.ReadMessageEnd(ctx) } func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) (ResponseMeta, error) { p.seqId++ seqId := p.seqId if err := p.Send(ctx, p.oprot, seqId, method, args); err != nil { return ResponseMeta{}, err } // method is oneway if result == nil { return ResponseMeta{}, nil } err := p.Recv(ctx, p.iprot, seqId, method, result) var headers THeaderMap if hp, ok := p.iprot.(*THeaderProtocol); ok { headers = hp.transport.readHeaders } return ResponseMeta{ Headers: headers, }, err } thrift-0.23.0/lib/go/thrift/pool.go0000664000175000017500000000315615165535636017355 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "sync" ) // pool is a generic sync.Pool wrapper with bells and whistles. type pool[T any] struct { pool sync.Pool reset func(*T) } // newPool creates a new pool. // // Both generate and reset are optional. // Default generate is just new(T), // When reset is nil we don't do any additional resetting when calling get. func newPool[T any](generate func() *T, reset func(*T)) *pool[T] { if generate == nil { generate = func() *T { return new(T) } } return &pool[T]{ pool: sync.Pool{ New: func() any { return generate() }, }, reset: reset, } } func (p *pool[T]) get() *T { r := p.pool.Get().(*T) if p.reset != nil { p.reset(r) } return r } func (p *pool[T]) put(r **T) { p.pool.Put(*r) *r = nil } var bufPool = newPool(nil, func(buf *bytes.Buffer) { buf.Reset() }) thrift-0.23.0/lib/go/thrift/slog_test.go0000664000175000017500000000233415165535636020404 0ustar00buildbuild00000000000000/* * 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 ( "encoding/json" "strings" "testing" ) func TestSlogTStructWrapperJSON(t *testing.T) { // This test just ensures that we don't have infinite recursion when // json encoding it. More comprehensive tests are under lib/go/test. v := SlogTStructWrapper{Type: "foo"} var sb strings.Builder if err := json.NewEncoder(&sb).Encode(v); err != nil { t.Fatal(err) } t.Log(strings.TrimSuffix(sb.String(), "\n")) } thrift-0.23.0/lib/go/thrift/exception_test.go0000664000175000017500000000416015165535636021435 0ustar00buildbuild00000000000000/* * 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 ( "errors" "testing" ) func TestPrependError(t *testing.T) { err := NewTApplicationException(INTERNAL_ERROR, "original error") err2, ok := PrependError("Prepend: ", err).(TApplicationException) if !ok { t.Fatal("Couldn't cast error TApplicationException") } if err2.Error() != "Prepend: original error" { t.Fatal("Unexpected error string") } if err2.TypeId() != INTERNAL_ERROR { t.Fatal("Unexpected type error") } err3 := NewTProtocolExceptionWithType(INVALID_DATA, errors.New("original error")) err4, ok := PrependError("Prepend: ", err3).(TProtocolException) if !ok { t.Fatal("Couldn't cast error TProtocolException") } if err4.Error() != "Prepend: original error" { t.Fatal("Unexpected error string") } if err4.TypeId() != INVALID_DATA { t.Fatal("Unexpected type error") } err5 := NewTTransportException(TIMED_OUT, "original error") err6, ok := PrependError("Prepend: ", err5).(TTransportException) if !ok { t.Fatal("Couldn't cast error TTransportException") } if err6.Error() != "Prepend: original error" { t.Fatal("Unexpected error string") } if err6.TypeId() != TIMED_OUT { t.Fatal("Unexpected type error") } err7 := errors.New("original error") err8 := PrependError("Prepend: ", err7) if err8.Error() != "Prepend: original error" { t.Fatal("Unexpected error string") } } thrift-0.23.0/lib/go/thrift/protocol_test.go0000664000175000017500000005050015165535636021277 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "context" "io" "math" "net" "net/http" "testing" ) const PROTOCOL_BINARY_DATA_SIZE = 155 var ( protocol_bdata []byte // test data for writing; same as data BOOL_VALUES []bool BYTE_VALUES []int8 INT16_VALUES []int16 INT32_VALUES []int32 INT64_VALUES []int64 DOUBLE_VALUES []float64 STRING_VALUES []string UUID_VALUES []Tuuid ) func init() { protocol_bdata = make([]byte, PROTOCOL_BINARY_DATA_SIZE) for i := range PROTOCOL_BINARY_DATA_SIZE { protocol_bdata[i] = byte((i + 'a') % 255) } BOOL_VALUES = []bool{false, true, false, false, true} BYTE_VALUES = []int8{117, 0, 1, 32, 127, -128, -1} INT16_VALUES = []int16{459, 0, 1, -1, -128, 127, 32767, -32768} INT32_VALUES = []int32{459, 0, 1, -1, -128, 127, 32767, 2147483647, -2147483535} INT64_VALUES = []int64{459, 0, 1, -1, -128, 127, 32767, 2147483647, -2147483535, 34359738481, -35184372088719, -9223372036854775808, 9223372036854775807} DOUBLE_VALUES = []float64{459.3, 0.0, -1.0, 1.0, 0.5, 0.3333, 3.14159, 1.537e-38, 1.673e25, 6.02214179e23, -6.02214179e23, INFINITY.Float64(), NEGATIVE_INFINITY.Float64(), NAN.Float64()} STRING_VALUES = []string{"", "a", "st[uf]f", "st,u:ff with spaces", "stuff\twith\nescape\\characters'...\"lots{of}fun"} UUID_VALUES = []Tuuid{ {}, Must(ParseTuuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8")), Must(ParseTuuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8")), Must(ParseTuuid("6ba7b812-9dad-11d1-80b4-00c04fd430c8")), Must(ParseTuuid("6ba7b814-9dad-11d1-80b4-00c04fd430c8")), } } type HTTPEchoServer struct{} type HTTPHeaderEchoServer struct{} func (p *HTTPEchoServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { buf, err := io.ReadAll(req.Body) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write(buf) } else { w.WriteHeader(http.StatusOK) w.Write(buf) } } func (p *HTTPHeaderEchoServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { buf, err := io.ReadAll(req.Body) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write(buf) } else { w.WriteHeader(http.StatusOK) w.Write(buf) } } func HttpClientSetupForTest(t *testing.T) (net.Listener, net.Addr) { addr, err := FindAvailableTCPServerPort(40000) if err != nil { t.Fatalf("Unable to find available tcp port addr: %s", err) return nil, addr } l, err := net.Listen(addr.Network(), addr.String()) if err != nil { t.Fatalf("Unable to setup tcp listener on %s: %s", addr.String(), err) return l, addr } go http.Serve(l, &HTTPEchoServer{}) return l, addr } func HttpClientSetupForHeaderTest(t *testing.T) (net.Listener, net.Addr) { addr, err := FindAvailableTCPServerPort(40000) if err != nil { t.Fatalf("Unable to find available tcp port addr: %s", err) return nil, addr } l, err := net.Listen(addr.Network(), addr.String()) if err != nil { t.Fatalf("Unable to setup tcp listener on %s: %s", addr.String(), err) return l, addr } go http.Serve(l, &HTTPHeaderEchoServer{}) return l, addr } func ReadWriteProtocolTest(t *testing.T, protocolFactory TProtocolFactory) { buf := bytes.NewBuffer(make([]byte, 0, 1024)) l, addr := HttpClientSetupForTest(t) defer l.Close() transports := []TTransportFactory{ NewTMemoryBufferTransportFactory(1024), NewStreamTransportFactory(buf, buf, true), NewTFramedTransportFactory(NewTMemoryBufferTransportFactory(1024)), NewTZlibTransportFactoryWithFactory(0, NewTMemoryBufferTransportFactory(1024)), NewTZlibTransportFactoryWithFactory(6, NewTMemoryBufferTransportFactory(1024)), NewTZlibTransportFactoryWithFactory(9, NewTFramedTransportFactory(NewTMemoryBufferTransportFactory(1024))), NewTHttpPostClientTransportFactory("http://" + addr.String()), } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteBool(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteByte(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteI16(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteI32(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteI64(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteDouble(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteString(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteBinary(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteUUID(t, p, trans) trans.Close() } for _, tf := range transports { trans, err := tf.GetTransport(nil) if err != nil { t.Error(err) continue } p := protocolFactory.GetProtocol(trans) ReadWriteI64(t, p, trans) ReadWriteDouble(t, p, trans) ReadWriteBinary(t, p, trans) ReadWriteByte(t, p, trans) ReadWriteUUID(t, p, trans) trans.Close() } t.Run("UnmatchedBeginEnd", func(t *testing.T) { UnmatchedBeginEndProtocolTest(t, protocolFactory) }) } func ReadWriteBool(t testing.TB, p TProtocol, trans TTransport) { thetype := TType(BOOL) thelen := len(BOOL_VALUES) err := p.WriteListBegin(context.Background(), thetype, thelen) if err != nil { t.Errorf("%s: %T %T %q Error writing list begin: %q", "ReadWriteBool", p, trans, err, thetype) } for k, v := range BOOL_VALUES { err = p.WriteBool(context.Background(), v) if err != nil { t.Errorf("%s: %T %T %v Error writing bool in list at index %v: %v", "ReadWriteBool", p, trans, err, k, v) } } p.WriteListEnd(context.Background()) if err != nil { t.Errorf("%s: %T %T %v Error writing list end: %v", "ReadWriteBool", p, trans, err, BOOL_VALUES) } p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin(context.Background()) if err != nil { t.Errorf("%s: %T %T %v Error reading list: %v", "ReadWriteBool", p, trans, err, BOOL_VALUES) } _, ok := p.(*TSimpleJSONProtocol) if !ok { if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteBool", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteBool", p, trans, thelen, thelen2) } } for k, v := range BOOL_VALUES { value, err := p.ReadBool(context.Background()) if err != nil { t.Errorf("%s: %T %T %v Error reading bool at index %v: %v", "ReadWriteBool", p, trans, err, k, v) } if v != value { t.Errorf("%s: index %v %v %v %v != %v", "ReadWriteBool", k, p, trans, v, value) } } err = p.ReadListEnd(context.Background()) if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteBool", p, trans, err) } } func ReadWriteByte(t testing.TB, p TProtocol, trans TTransport) { thetype := TType(BYTE) thelen := len(BYTE_VALUES) err := p.WriteListBegin(context.Background(), thetype, thelen) if err != nil { t.Errorf("%s: %T %T %q Error writing list begin: %q", "ReadWriteByte", p, trans, err, thetype) } for k, v := range BYTE_VALUES { err = p.WriteByte(context.Background(), v) if err != nil { t.Errorf("%s: %T %T %q Error writing byte in list at index %d: %q", "ReadWriteByte", p, trans, err, k, v) } } err = p.WriteListEnd(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES) } err = p.Flush(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error flushing list of bytes: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES) } thetype2, thelen2, err := p.ReadListBegin(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES) } _, ok := p.(*TSimpleJSONProtocol) if !ok { if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteByte", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteByte", p, trans, thelen, thelen2) } } for k, v := range BYTE_VALUES { value, err := p.ReadByte(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading byte at index %d: %q", "ReadWriteByte", p, trans, err, k, v) } if v != value { t.Errorf("%s: %T %T %d != %d", "ReadWriteByte", p, trans, v, value) } } err = p.ReadListEnd(context.Background()) if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteByte", p, trans, err) } } func ReadWriteI16(t testing.TB, p TProtocol, trans TTransport) { thetype := TType(I16) thelen := len(INT16_VALUES) p.WriteListBegin(context.Background(), thetype, thelen) for _, v := range INT16_VALUES { p.WriteI16(context.Background(), v) } p.WriteListEnd(context.Background()) p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI16", p, trans, err, INT16_VALUES) } _, ok := p.(*TSimpleJSONProtocol) if !ok { if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI16", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteI16", p, trans, thelen, thelen2) } } for k, v := range INT16_VALUES { value, err := p.ReadI16(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading int16 at index %d: %q", "ReadWriteI16", p, trans, err, k, v) } if v != value { t.Errorf("%s: %T %T %d != %d", "ReadWriteI16", p, trans, v, value) } } err = p.ReadListEnd(context.Background()) if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI16", p, trans, err) } } func ReadWriteI32(t testing.TB, p TProtocol, trans TTransport) { thetype := TType(I32) thelen := len(INT32_VALUES) p.WriteListBegin(context.Background(), thetype, thelen) for _, v := range INT32_VALUES { p.WriteI32(context.Background(), v) } p.WriteListEnd(context.Background()) p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI32", p, trans, err, INT32_VALUES) } _, ok := p.(*TSimpleJSONProtocol) if !ok { if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI32", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteI32", p, trans, thelen, thelen2) } } for k, v := range INT32_VALUES { value, err := p.ReadI32(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading int32 at index %d: %q", "ReadWriteI32", p, trans, err, k, v) } if v != value { t.Errorf("%s: %T %T %d != %d", "ReadWriteI32", p, trans, v, value) } } if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI32", p, trans, err) } } func ReadWriteI64(t testing.TB, p TProtocol, trans TTransport) { thetype := TType(I64) thelen := len(INT64_VALUES) p.WriteListBegin(context.Background(), thetype, thelen) for _, v := range INT64_VALUES { p.WriteI64(context.Background(), v) } p.WriteListEnd(context.Background()) p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI64", p, trans, err, INT64_VALUES) } _, ok := p.(*TSimpleJSONProtocol) if !ok { if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI64", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteI64", p, trans, thelen, thelen2) } } for k, v := range INT64_VALUES { value, err := p.ReadI64(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading int64 at index %d: %q", "ReadWriteI64", p, trans, err, k, v) } if v != value { t.Errorf("%s: %T %T %q != %q", "ReadWriteI64", p, trans, v, value) } } if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI64", p, trans, err) } } func ReadWriteDouble(t testing.TB, p TProtocol, trans TTransport) { thetype := TType(DOUBLE) thelen := len(DOUBLE_VALUES) p.WriteListBegin(context.Background(), thetype, thelen) for _, v := range DOUBLE_VALUES { p.WriteDouble(context.Background(), v) } p.WriteListEnd(context.Background()) p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin(context.Background()) if err != nil { t.Errorf("%s: %T %T %v Error reading list: %v", "ReadWriteDouble", p, trans, err, DOUBLE_VALUES) } if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteDouble", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteDouble", p, trans, thelen, thelen2) } for k, v := range DOUBLE_VALUES { value, err := p.ReadDouble(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading double at index %d: %v", "ReadWriteDouble", p, trans, err, k, v) } if math.IsNaN(v) { if !math.IsNaN(value) { t.Errorf("%s: %T %T math.IsNaN(%v) != math.IsNaN(%v)", "ReadWriteDouble", p, trans, v, value) } } else if v != value { t.Errorf("%s: %T %T %v != %v", "ReadWriteDouble", p, trans, v, value) } } err = p.ReadListEnd(context.Background()) if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteDouble", p, trans, err) } } func ReadWriteString(t testing.TB, p TProtocol, trans TTransport) { thetype := TType(STRING) thelen := len(STRING_VALUES) p.WriteListBegin(context.Background(), thetype, thelen) for _, v := range STRING_VALUES { p.WriteString(context.Background(), v) } p.WriteListEnd(context.Background()) p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteString", p, trans, err, STRING_VALUES) } _, ok := p.(*TSimpleJSONProtocol) if !ok { if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteString", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteString", p, trans, thelen, thelen2) } } for k, v := range STRING_VALUES { value, err := p.ReadString(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error reading string at index %d: %q", "ReadWriteString", p, trans, err, k, v) } if v != value { t.Errorf("%s: %T %T %v != %v", "ReadWriteString", p, trans, v, value) } } if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteString", p, trans, err) } } func ReadWriteBinary(t testing.TB, p TProtocol, trans TTransport) { v := protocol_bdata p.WriteBinary(context.Background(), v) p.Flush(context.Background()) value, err := p.ReadBinary(context.Background()) if err != nil { t.Errorf("%s: %T %T Unable to read binary: %s", "ReadWriteBinary", p, trans, err.Error()) } 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 := range v { if v[i] != value[i] { t.Errorf("%s: %T %T %s != %s", "ReadWriteBinary", p, trans, v, value) } } } } func ReadWriteUUID(t testing.TB, p TProtocol, trans TTransport) { ctx := context.Background() thetype := TType(UUID) thelen := len(UUID_VALUES) p.WriteListBegin(ctx, thetype, thelen) for _, v := range UUID_VALUES { p.WriteUUID(ctx, v) } p.WriteListEnd(ctx) p.Flush(ctx) thetype2, thelen2, err := p.ReadListBegin(ctx) if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteUUID", p, trans, err, STRING_VALUES) } _, ok := p.(*TSimpleJSONProtocol) if !ok { if thetype != thetype2 { t.Errorf("%s: %T %T type %s != type %s", "ReadWriteUUID", p, trans, thetype, thetype2) } if thelen != thelen2 { t.Errorf("%s: %T %T len %v != len %v", "ReadWriteUUID", p, trans, thelen, thelen2) } } for k, v := range UUID_VALUES { value, err := p.ReadUUID(ctx) if err != nil { t.Errorf("%s: %T %T %q Error reading UUID at index %d: %q", "ReadWriteUUID", p, trans, err, k, v) } if v != value { t.Errorf("%s: %T %T %v != %v", "ReadWriteUUID", p, trans, v, value) } } if err != nil { t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteUUID", p, trans, err) } } func UnmatchedBeginEndProtocolTest(t *testing.T, protocolFactory TProtocolFactory) { // NOTE: not all protocol implementations do strict state check to // return an error on unmatched Begin/End calls. // This test is only meant to make sure that those unmatched Begin/End // calls won't cause panic. There's no real "test" here. trans := NewTMemoryBuffer() t.Run("Read", func(t *testing.T) { t.Run("Message", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.ReadMessageEnd(context.Background()) p.ReadMessageEnd(context.Background()) }) t.Run("Struct", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.ReadStructEnd(context.Background()) p.ReadStructEnd(context.Background()) }) t.Run("Field", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.ReadFieldEnd(context.Background()) p.ReadFieldEnd(context.Background()) }) t.Run("Map", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.ReadMapEnd(context.Background()) p.ReadMapEnd(context.Background()) }) t.Run("List", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.ReadListEnd(context.Background()) p.ReadListEnd(context.Background()) }) t.Run("Set", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.ReadSetEnd(context.Background()) p.ReadSetEnd(context.Background()) }) }) t.Run("Write", func(t *testing.T) { t.Run("Message", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.WriteMessageEnd(context.Background()) p.WriteMessageEnd(context.Background()) }) t.Run("Struct", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.WriteStructEnd(context.Background()) p.WriteStructEnd(context.Background()) }) t.Run("Field", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.WriteFieldEnd(context.Background()) p.WriteFieldEnd(context.Background()) }) t.Run("Map", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.WriteMapEnd(context.Background()) p.WriteMapEnd(context.Background()) }) t.Run("List", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.WriteListEnd(context.Background()) p.WriteListEnd(context.Background()) }) t.Run("Set", func(t *testing.T) { trans.Reset() p := protocolFactory.GetProtocol(trans) p.WriteSetEnd(context.Background()) p.WriteSetEnd(context.Background()) }) }) trans.Close() } thrift-0.23.0/lib/go/thrift/socket_aix_syscall.go0000664000175000017500000000175015167543515022262 0ustar00buildbuild00000000000000//go: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) } thrift-0.23.0/lib/go/thrift/framed_transport.go0000664000175000017500000001514215167543515021751 0ustar00buildbuild00000000000000/* * 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 ( "bufio" "bytes" "context" "encoding/binary" "fmt" "io" "math" ) // Deprecated: Use DEFAULT_MAX_FRAME_SIZE instead. const DEFAULT_MAX_LENGTH = 16384000 type TFramedTransport struct { transport TTransport cfg *TConfiguration writeBuf *bytes.Buffer reader *bufio.Reader readBuf *bytes.Buffer buffer [4]byte } type tFramedTransportFactory struct { factory TTransportFactory cfg *TConfiguration } // Deprecated: Use NewTFramedTransportFactoryConf instead. func NewTFramedTransportFactory(factory TTransportFactory) TTransportFactory { return NewTFramedTransportFactoryConf(factory, &TConfiguration{ MaxFrameSize: DEFAULT_MAX_LENGTH, noPropagation: true, }) } // Deprecated: Use NewTFramedTransportFactoryConf instead. func NewTFramedTransportFactoryMaxLength(factory TTransportFactory, maxLength uint32) TTransportFactory { safeMax := maxLength if safeMax > math.MaxInt32 { safeMax = math.MaxInt32 } return NewTFramedTransportFactoryConf(factory, &TConfiguration{ MaxFrameSize: int32(safeMax), noPropagation: true, }) } func NewTFramedTransportFactoryConf(factory TTransportFactory, conf *TConfiguration) TTransportFactory { PropagateTConfiguration(factory, conf) return &tFramedTransportFactory{ factory: factory, cfg: conf, } } func (p *tFramedTransportFactory) GetTransport(base TTransport) (TTransport, error) { PropagateTConfiguration(base, p.cfg) tt, err := p.factory.GetTransport(base) if err != nil { return nil, err } return NewTFramedTransportConf(tt, p.cfg), nil } func (p *tFramedTransportFactory) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(p.factory, cfg) p.cfg = cfg } // Deprecated: Use NewTFramedTransportConf instead. func NewTFramedTransport(transport TTransport) *TFramedTransport { return NewTFramedTransportConf(transport, &TConfiguration{ MaxFrameSize: DEFAULT_MAX_LENGTH, noPropagation: true, }) } // Deprecated: Use NewTFramedTransportConf instead. func NewTFramedTransportMaxLength(transport TTransport, maxLength uint32) *TFramedTransport { return NewTFramedTransportConf(transport, &TConfiguration{ MaxFrameSize: int32(maxLength), noPropagation: true, }) } func NewTFramedTransportConf(transport TTransport, conf *TConfiguration) *TFramedTransport { PropagateTConfiguration(transport, conf) return &TFramedTransport{ transport: transport, reader: bufio.NewReader(transport), cfg: conf, } } func (p *TFramedTransport) Open() error { return p.transport.Open() } func (p *TFramedTransport) IsOpen() bool { return p.transport.IsOpen() } func (p *TFramedTransport) Close() error { return p.transport.Close() } func (p *TFramedTransport) Read(buf []byte) (read int, err error) { defer func() { // Make sure we return the read buffer back to pool // after we finished reading from it. if p.readBuf != nil && p.readBuf.Len() == 0 { bufPool.put(&p.readBuf) } }() if p.readBuf != nil { read, err = p.readBuf.Read(buf) if err != io.EOF { return } // For bytes.Buffer.Read, EOF would only happen when read is zero, // but still, do a sanity check, // in case that behavior is changed in a future version of go stdlib. // When that happens, just return nil error, // and let the caller call Read again to read the next frame. if read > 0 { return read, nil } } // Reaching here means that the last Read finished the last frame, // so we need to read the next frame into readBuf now. if err = p.readFrame(); err != nil { return read, err } newRead, err := p.Read(buf[read:]) return read + newRead, err } func (p *TFramedTransport) ReadByte() (c byte, err error) { buf := p.buffer[:1] _, err = p.Read(buf) if err != nil { return } c = buf[0] return } func (p *TFramedTransport) ensureWriteBufferBeforeWrite() { if p.writeBuf == nil { p.writeBuf = bufPool.get() } } func (p *TFramedTransport) Write(buf []byte) (int, error) { p.ensureWriteBufferBeforeWrite() n, err := p.writeBuf.Write(buf) return n, NewTTransportExceptionFromError(err) } func (p *TFramedTransport) WriteByte(c byte) error { p.ensureWriteBufferBeforeWrite() return p.writeBuf.WriteByte(c) } func (p *TFramedTransport) WriteString(s string) (n int, err error) { p.ensureWriteBufferBeforeWrite() return p.writeBuf.WriteString(s) } func (p *TFramedTransport) Flush(ctx context.Context) error { size := p.writeBuf.Len() if size > math.MaxUint32 { return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, fmt.Sprintf("frame too large: %d bytes exceeds uint32 max",size)) } defer bufPool.put(&p.writeBuf) buf := p.buffer[:4] binary.BigEndian.PutUint32(buf, uint32(size)) _, err := p.transport.Write(buf) if err != nil { return NewTTransportExceptionFromError(err) } if size > 0 { if _, err := io.Copy(p.transport, p.writeBuf); err != nil { return NewTTransportExceptionFromError(err) } } err = p.transport.Flush(ctx) return NewTTransportExceptionFromError(err) } func (p *TFramedTransport) readFrame() error { if p.readBuf != nil { bufPool.put(&p.readBuf) } p.readBuf = bufPool.get() buf := p.buffer[:4] if _, err := io.ReadFull(p.reader, buf); err != nil { return err } size := binary.BigEndian.Uint32(buf) if size > uint32(p.cfg.GetMaxFrameSize()) { return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, fmt.Sprintf("Incorrect frame size (%d)", size)) } _, err := io.CopyN(p.readBuf, p.reader, int64(size)) return NewTTransportExceptionFromError(err) } func (p *TFramedTransport) RemainingBytes() (num_bytes uint64) { if p.readBuf == nil { return 0 } return uint64(p.readBuf.Len()) } // SetTConfiguration implements TConfigurationSetter. func (p *TFramedTransport) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(p.transport, cfg) p.cfg = cfg } var ( _ TConfigurationSetter = (*tFramedTransportFactory)(nil) _ TConfigurationSetter = (*TFramedTransport)(nil) ) thrift-0.23.0/lib/go/thrift/simple_server_test.go0000664000175000017500000001545015165535636022322 0ustar00buildbuild00000000000000/* * 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 ( "context" "errors" "net" "runtime" "sync" "testing" "time" ) const networkWaitDuration = 10 * time.Millisecond type mockServerTransport struct { ListenFunc func() error AcceptFunc func() (TTransport, error) CloseFunc func() error InterruptFunc func() error } func (m *mockServerTransport) Listen() error { return m.ListenFunc() } func (m *mockServerTransport) Accept() (TTransport, error) { return m.AcceptFunc() } func (m *mockServerTransport) Close() error { return m.CloseFunc() } func (m *mockServerTransport) Interrupt() error { return m.InterruptFunc() } type mockTTransport struct { TTransport } func (m *mockTTransport) Close() error { return nil } func TestMultipleStop(t *testing.T) { proc := &mockProcessor{ ProcessFunc: func(in, out TProtocol) (bool, TException) { return false, nil }, } var interruptCalled bool c := make(chan struct{}) trans := &mockServerTransport{ ListenFunc: func() error { return nil }, AcceptFunc: func() (TTransport, error) { <-c return nil, nil }, CloseFunc: func() error { c <- struct{}{} return nil }, InterruptFunc: func() error { interruptCalled = true return nil }, } serv := NewTSimpleServer2(proc, trans) go serv.Serve() serv.Stop() if !interruptCalled { t.Error("first server transport should have been interrupted") } serv = NewTSimpleServer2(proc, trans) interruptCalled = false go serv.Serve() serv.Stop() if !interruptCalled { t.Error("second server transport should have been interrupted") } } func TestWaitRace(t *testing.T) { proc := &mockProcessor{ ProcessFunc: func(in, out TProtocol) (bool, TException) { return false, nil }, } trans := &mockServerTransport{ ListenFunc: func() error { return nil }, AcceptFunc: func() (TTransport, error) { return &mockTTransport{}, nil }, CloseFunc: func() error { return nil }, InterruptFunc: func() error { return nil }, } serv := NewTSimpleServer2(proc, trans) go serv.Serve() runtime.Gosched() serv.Stop() } func TestNoHangDuringStopFromDanglingLockAcquireDuringAcceptLoop(t *testing.T) { proc := &mockProcessor{ ProcessFunc: func(in, out TProtocol) (bool, TException) { return false, nil }, } trans := &mockServerTransport{ ListenFunc: func() error { return nil }, AcceptFunc: func() (TTransport, error) { return nil, errors.New("no sir") }, CloseFunc: func() error { return nil }, InterruptFunc: func() error { return nil }, } serv := NewTSimpleServer2(proc, trans) go serv.Serve() runtime.Gosched() serv.Stop() } func TestNoHangDuringStopFromClientNoDataSendDuringAcceptLoop(t *testing.T) { ln, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to listen: %v", err) } proc := &mockProcessor{ ProcessFunc: func(in, out TProtocol) (bool, TException) { in.ReadMessageBegin(context.Background()) return false, nil }, } trans := &mockServerTransport{ ListenFunc: func() error { return nil }, AcceptFunc: func() (TTransport, error) { conn, err := ln.Accept() if err != nil { return nil, err } return NewTSocketFromConnConf(conn, nil), nil }, CloseFunc: func() error { return nil }, InterruptFunc: func() error { return ln.Close() }, } serv := NewTSimpleServer2(proc, trans) go serv.Serve() time.Sleep(networkWaitDuration) netConn, err := net.Dial("tcp", ln.Addr().String()) if err != nil || netConn == nil { t.Fatalf("error when dial server: %v", err) } time.Sleep(networkWaitDuration) const serverStopTimeout = 50 * time.Millisecond backupServerStopTimeout := ServerStopTimeout t.Cleanup(func() { ServerStopTimeout = backupServerStopTimeout }) ServerStopTimeout = serverStopTimeout st := time.Now() if err := serv.Stop(); err != nil { t.Errorf("error when stop server:%v", err) } if elapsed := time.Since(st); elapsed < serverStopTimeout { t.Errorf("stop cost less time than server stop timeout, server stop timeout:%v,cost time:%v", serverStopTimeout, elapsed) } } func TestStopTimeoutWithSocketTimeout(t *testing.T) { ln, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to listen: %v", err) } proc := &mockProcessor{ ProcessFunc: func(in, out TProtocol) (bool, TException) { in.ReadMessageBegin(context.Background()) return false, nil }, } conf := &TConfiguration{SocketTimeout: 5 * time.Millisecond} wg := &sync.WaitGroup{} trans := &mockServerTransport{ ListenFunc: func() error { return nil }, AcceptFunc: func() (TTransport, error) { conn, err := ln.Accept() if err != nil { return nil, err } defer wg.Done() return NewTSocketFromConnConf(conn, conf), nil }, CloseFunc: func() error { return nil }, InterruptFunc: func() error { return ln.Close() }, } serv := NewTSimpleServer2(proc, trans) go serv.Serve() time.Sleep(networkWaitDuration) wg.Add(1) netConn, err := net.Dial("tcp", ln.Addr().String()) if err != nil || netConn == nil { t.Fatal("error when dial server") } wg.Wait() expectedStopTimeout := time.Second backupServerStopTimeout := ServerStopTimeout t.Cleanup(func() { ServerStopTimeout = backupServerStopTimeout }) ServerStopTimeout = expectedStopTimeout st := time.Now() err = serv.Stop() if elapsed := time.Since(st); elapsed > expectedStopTimeout/2 { t.Errorf("stop cost more time than socket timeout, socket timeout:%v,server stop timeout:%v,cost time:%v", conf.SocketTimeout, ServerStopTimeout, elapsed) } if err != nil { t.Fatalf("error when stop server:%v", err) } } func TestErrAbandonRequest(t *testing.T) { if !errors.Is(ErrAbandonRequest, ErrAbandonRequest) { t.Error("errors.Is(ErrAbandonRequest, ErrAbandonRequest) returned false") } 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") } } thrift-0.23.0/lib/go/thrift/configuration.go0000664000175000017500000003042115167543515021243 0ustar00buildbuild00000000000000/* * 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 ( "crypto/tls" "fmt" "time" ) // Default TConfiguration values. const ( DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024 DEFAULT_MAX_FRAME_SIZE = 16384000 DEFAULT_TBINARY_STRICT_READ = false DEFAULT_TBINARY_STRICT_WRITE = true DEFAULT_CONNECT_TIMEOUT = 0 DEFAULT_SOCKET_TIMEOUT = 0 ) // TConfiguration defines some configurations shared between TTransport, // TProtocol, TTransportFactory, TProtocolFactory, and other implementations. // // When constructing TConfiguration, you only need to specify the non-default // fields. All zero values have sane default values. // // Not all configurations defined are applicable to all implementations. // Implementations are free to ignore the configurations not applicable to them. // // All functions attached to this type are nil-safe. // // See [1] for spec. // // NOTE: When using TConfiguration, fill in all the configurations you want to // set across the stack, not only the ones you want to set in the immediate // TTransport/TProtocol. // // For example, say you want to migrate this old code into using TConfiguration: // // 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 // 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, // // MaxFrameSize: 1024 * 1024 * 256, // // 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 { // If <= 0, DEFAULT_MAX_MESSAGE_SIZE will be used instead. MaxMessageSize int32 // If <= 0, DEFAULT_MAX_FRAME_SIZE will be used instead. // // Also if MaxMessageSize < MaxFrameSize, // MaxMessageSize will be used instead. MaxFrameSize int32 // Connect and socket timeouts to be used by TSocket and TSSLSocket. // // 0 means no timeout. // // If <0, DEFAULT_CONNECT_TIMEOUT and DEFAULT_SOCKET_TIMEOUT will be // used. ConnectTimeout time.Duration SocketTimeout time.Duration // TLS config to be used by TSSLSocket. TLSConfig *tls.Config // Strict read/write configurations for TBinaryProtocol. // // BoolPtr helper function is available to use literal values. TBinaryStrictRead *bool TBinaryStrictWrite *bool // The wrapped protocol id to be used in THeader transport/protocol. // // 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. // // For external users this is always false. noPropagation bool } // GetMaxMessageSize returns the max message size an implementation should // follow. // // It's nil-safe. DEFAULT_MAX_MESSAGE_SIZE will be returned if tc is nil. func (tc *TConfiguration) GetMaxMessageSize() int32 { if tc == nil || tc.MaxMessageSize <= 0 { return DEFAULT_MAX_MESSAGE_SIZE } return tc.MaxMessageSize } // GetMaxFrameSize returns the max frame size an implementation should follow. // // It's nil-safe. DEFAULT_MAX_FRAME_SIZE will be returned if tc is nil. // // If the configured max message size is smaller than the configured max frame // size, the smaller one will be returned instead. func (tc *TConfiguration) GetMaxFrameSize() int32 { if tc == nil { return DEFAULT_MAX_FRAME_SIZE } maxFrameSize := tc.MaxFrameSize if maxFrameSize <= 0 { maxFrameSize = DEFAULT_MAX_FRAME_SIZE } if maxMessageSize := tc.GetMaxMessageSize(); maxMessageSize < maxFrameSize { return maxMessageSize } return maxFrameSize } // GetConnectTimeout returns the connect timeout should be used by TSocket and // TSSLSocket. // // It's nil-safe. If tc is nil, DEFAULT_CONNECT_TIMEOUT will be returned instead. func (tc *TConfiguration) GetConnectTimeout() time.Duration { if tc == nil || tc.ConnectTimeout < 0 { return DEFAULT_CONNECT_TIMEOUT } return tc.ConnectTimeout } // GetSocketTimeout returns the socket timeout should be used by TSocket and // TSSLSocket. // // It's nil-safe. If tc is nil, DEFAULT_SOCKET_TIMEOUT will be returned instead. func (tc *TConfiguration) GetSocketTimeout() time.Duration { if tc == nil || tc.SocketTimeout < 0 { return DEFAULT_SOCKET_TIMEOUT } return tc.SocketTimeout } // GetTLSConfig returns the tls config should be used by TSSLSocket. // // It's nil-safe. If tc is nil, nil will be returned instead. func (tc *TConfiguration) GetTLSConfig() *tls.Config { if tc == nil { return nil } return tc.TLSConfig } // GetTBinaryStrictRead returns the strict read configuration TBinaryProtocol // should follow. // // It's nil-safe. DEFAULT_TBINARY_STRICT_READ will be returned if either tc or // tc.TBinaryStrictRead is nil. func (tc *TConfiguration) GetTBinaryStrictRead() bool { if tc == nil || tc.TBinaryStrictRead == nil { return DEFAULT_TBINARY_STRICT_READ } return *tc.TBinaryStrictRead } // GetTBinaryStrictWrite returns the strict read configuration TBinaryProtocol // should follow. // // It's nil-safe. DEFAULT_TBINARY_STRICT_WRITE will be returned if either tc or // tc.TBinaryStrictWrite is nil. func (tc *TConfiguration) GetTBinaryStrictWrite() bool { if tc == nil || tc.TBinaryStrictWrite == nil { return DEFAULT_TBINARY_STRICT_WRITE } return *tc.TBinaryStrictWrite } // GetTHeaderProtocolID returns the THeaderProtocolID should be used by // THeaderProtocol clients (for servers, they always use the same one as the // client instead). // // It's nil-safe. If either tc or tc.THeaderProtocolID is nil, // THeaderProtocolDefault will be returned instead. // THeaderProtocolDefault will also be returned if configured value is invalid. func (tc *TConfiguration) GetTHeaderProtocolID() THeaderProtocolID { if tc == nil || tc.THeaderProtocolID == nil { return THeaderProtocolDefault } protoID := *tc.THeaderProtocolID if err := protoID.Validate(); err != nil { return THeaderProtocolDefault } 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 // and the validation error will be returned. func THeaderProtocolIDPtr(id THeaderProtocolID) (*THeaderProtocolID, error) { err := id.Validate() if err != nil { id = THeaderProtocolDefault } return &id, err } // THeaderProtocolIDPtrMust validates and returns the pointer to id. // // It's similar to THeaderProtocolIDPtr, but it panics on validation errors // instead of returning them. func THeaderProtocolIDPtrMust(id THeaderProtocolID) *THeaderProtocolID { ptr, err := THeaderProtocolIDPtr(id) if err != nil { panic(err) } return ptr } // TConfigurationSetter is an optional interface TProtocol, TTransport, // TProtocolFactory, TTransportFactory, and other implementations can implement. // // It's intended to be called during intializations. // The behavior of calling SetTConfiguration on a TTransport/TProtocol in the // middle of a message is undefined: // It may or may not change the behavior of the current processing message, // and it may even cause the current message to fail. // // Note for implementations: SetTConfiguration might be called multiple times // with the same value in quick successions due to the implementation of the // propagation. Implementations should make SetTConfiguration as simple as // possible (usually just overwrite the stored configuration and propagate it to // the wrapped TTransports/TProtocols). type TConfigurationSetter interface { SetTConfiguration(*TConfiguration) } // PropagateTConfiguration propagates cfg to impl if impl implements // TConfigurationSetter and cfg is non-nil, otherwise it does nothing. // // NOTE: nil cfg is not propagated. If you want to propagate a TConfiguration // with everything being default value, use &TConfiguration{} explicitly instead. func PropagateTConfiguration(impl any, cfg *TConfiguration) { if cfg == nil || cfg.noPropagation { return } if setter, ok := impl.(TConfigurationSetter); ok { setter.SetTConfiguration(cfg) } } func checkSizeForProtocol(size int32, cfg *TConfiguration) error { if size < 0 { return NewTProtocolExceptionWithType( NEGATIVE_SIZE, fmt.Errorf("negative size: %d", size), ) } if size > cfg.GetMaxMessageSize() { return NewTProtocolExceptionWithType( SIZE_LIMIT, fmt.Errorf("size exceeded max allowed: %d", size), ) } return nil } type tTransportFactoryConf struct { delegate TTransportFactory cfg *TConfiguration } func (f *tTransportFactoryConf) GetTransport(orig TTransport) (TTransport, error) { trans, err := f.delegate.GetTransport(orig) if err == nil { PropagateTConfiguration(orig, f.cfg) PropagateTConfiguration(trans, f.cfg) } return trans, err } func (f *tTransportFactoryConf) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(f.delegate, f.cfg) f.cfg = cfg } // TTransportFactoryConf wraps a TTransportFactory to propagate // TConfiguration on the factory's GetTransport calls. func TTransportFactoryConf(delegate TTransportFactory, conf *TConfiguration) TTransportFactory { return &tTransportFactoryConf{ delegate: delegate, cfg: conf, } } type tProtocolFactoryConf struct { delegate TProtocolFactory cfg *TConfiguration } func (f *tProtocolFactoryConf) GetProtocol(trans TTransport) TProtocol { proto := f.delegate.GetProtocol(trans) PropagateTConfiguration(trans, f.cfg) PropagateTConfiguration(proto, f.cfg) return proto } func (f *tProtocolFactoryConf) SetTConfiguration(cfg *TConfiguration) { PropagateTConfiguration(f.delegate, f.cfg) f.cfg = cfg } // TProtocolFactoryConf wraps a TProtocolFactory to propagate // TConfiguration on the factory's GetProtocol calls. func TProtocolFactoryConf(delegate TProtocolFactory, conf *TConfiguration) TProtocolFactory { return &tProtocolFactoryConf{ delegate: delegate, cfg: conf, } } var ( _ TConfigurationSetter = (*tTransportFactoryConf)(nil) _ TConfigurationSetter = (*tProtocolFactoryConf)(nil) ) thrift-0.23.0/lib/go/thrift/binary_protocol_test.go0000664000175000017500000001255215167543515022645 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "math" "strings" "testing" ) func TestReadWriteBinaryProtocol(t *testing.T) { ReadWriteProtocolTest(t, NewTBinaryProtocolFactoryDefault()) } const ( safeReadBytesSource = ` Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet tincidunt nibh. Phasellus vel convallis libero, sit amet posuere quam. Nullam blandit velit at nibh fringilla, sed egestas erat dapibus. Sed hendrerit tincidunt accumsan. Curabitur consectetur bibendum dui nec hendrerit. Fusce quis turpis nec magna efficitur volutpat a ut nibh. Vestibulum odio risus, tristique a nisi et, congue mattis mi. Vivamus a nunc justo. Mauris molestie sagittis magna, hendrerit auctor lectus egestas non. Phasellus pretium, odio sit amet bibendum feugiat, velit nunc luctus erat, ac bibendum mi dui molestie nulla. Nullam fermentum magna eu elit vehicula tincidunt. Etiam ornare laoreet dignissim. Ut sed nunc ac neque vulputate fermentum. Morbi volutpat dapibus magna, at porttitor quam facilisis a. Donec eget fermentum risus. Aliquam erat volutpat. Phasellus molestie id ante vel iaculis. Fusce eget quam nec quam viverra laoreet vitae a dui. Mauris blandit blandit dui, iaculis interdum diam mollis at. Morbi vel sem et. ` safeReadBytesSourceLen = len(safeReadBytesSource) ) func TestSafeReadBytes(t *testing.T) { srcData := []byte(safeReadBytesSource) for _, c := range []struct { label string askedSize int32 dataSize int }{ { label: "tiny", askedSize: 8, dataSize: 8, }, { label: "normal", askedSize: 100, dataSize: 100, }, { label: "max-askedSize", askedSize: math.MaxInt32, dataSize: safeReadBytesSourceLen, }, } { t.Run(c.label, func(t *testing.T) { data := bytes.NewReader(srcData[:c.dataSize]) buf, err := safeReadBytes(c.askedSize, data) if len(buf) != c.dataSize { t.Errorf( "Expected to read %d bytes, got %d", c.dataSize, len(buf), ) } if c.dataSize < bytes.MinRead && cap(buf) != c.dataSize { t.Errorf("Expected to allocate %d bytes for read, allocated %d", c.dataSize, cap(buf)) } if !strings.HasPrefix(safeReadBytesSource, string(buf)) { t.Errorf("Unexpected read data: %q", buf) } if int32(c.dataSize) < c.askedSize { // We expect error in this case if err == nil { t.Errorf( "Expected error when dataSize %d < askedSize %d, got nil", c.dataSize, c.askedSize, ) } } else { // We expect no error in this case if err != nil { t.Errorf( "Expected no error when dataSize %d >= askedSize %d, got: %v", c.dataSize, c.askedSize, err, ) } } }) } } func generateSafeReadBytesBenchmark(askedSize int32, dataSize int) func(b *testing.B) { return func(b *testing.B) { data := make([]byte, dataSize) b.ResetTimer() for range b.N { safeReadBytes(askedSize, bytes.NewReader(data)) } } } func TestSafeReadBytesAlloc(t *testing.T) { if testing.Short() { // NOTE: Since this test runs a benchmark test, it takes at // least 1 second. // // In general we try to avoid unit tests taking that long to run, // but it's to verify a security issue so we made an exception // here: // https://issues.apache.org/jira/browse/THRIFT-5322 t.Skip("skipping test in short mode.") } const ( askedSize = int32(math.MaxInt32) dataSize = 4096 ) // The purpose of this test is that in the case a string header says // that it has a string askedSize bytes long, the implementation should // not just allocate askedSize bytes upfront. So when there're actually // not enough data to be read (dataSize), the actual allocated bytes // should be somewhere between dataSize and askedSize. // // Different approachs could have different memory overheads, so this // target is arbitrary in nature. But when dataSize is small enough // compare to askedSize, half the askedSize is a good and safe target. const target = int64(askedSize) / 2 bm := testing.Benchmark(generateSafeReadBytesBenchmark(askedSize, dataSize)) actual := bm.AllocedBytesPerOp() if actual > target { t.Errorf( "Expected allocated bytes per op to be <= %d, got %d", target, actual, ) } else { t.Logf("Allocated bytes: %d B/op", actual) } } func BenchmarkSafeReadBytes(b *testing.B) { for _, c := range []struct { label string askedSize int32 dataSize int }{ { label: "normal", askedSize: 100, dataSize: 100, }, { label: "max-askedSize", askedSize: math.MaxInt32, dataSize: 4096, }, } { b.Run(c.label, generateSafeReadBytesBenchmark(c.askedSize, c.dataSize)) } } thrift-0.23.0/lib/go/thrift/type.go0000664000175000017500000000267415165535636017371 0ustar00buildbuild00000000000000/* * 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 // Type constants in the Thrift protocol type TType byte const ( STOP = 0 VOID = 1 BOOL = 2 BYTE = 3 I08 = 3 DOUBLE = 4 I16 = 6 I32 = 8 I64 = 10 STRING = 11 UTF7 = 11 STRUCT = 12 MAP = 13 SET = 14 LIST = 15 UUID = 16 ) var typeNames = map[int]string{ STOP: "STOP", VOID: "VOID", BOOL: "BOOL", BYTE: "BYTE", DOUBLE: "DOUBLE", I16: "I16", I32: "I32", I64: "I64", STRING: "STRING", STRUCT: "STRUCT", MAP: "MAP", SET: "SET", LIST: "LIST", UUID: "UUID", } func (p TType) String() string { if s, ok := typeNames[int(p)]; ok { return s } return "Unknown" } thrift-0.23.0/lib/go/test/0000755000175000017500000000000015170007201015477 5ustar00buildbuild00000000000000thrift-0.23.0/lib/go/test/ConflictNamespaceTestE.thrift0000664000175000017500000000152215165535636023274 0ustar00buildbuild00000000000000# # 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 go conflicte.driver struct ThingE { 1: bool value } thrift-0.23.0/lib/go/test/IgnoreInitialismsTest.thrift0000664000175000017500000000161615165535636023246 0ustar00buildbuild00000000000000# # 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 IgnoreInitialismsTest { 1: i64 id, 2: i64 my_id, 3: i64 num_cpu, 4: i64 num_gpu, 5: i64 my_ID, } thrift-0.23.0/lib/go/test/UnionDefaultValueTest.thrift0000664000175000017500000000174115165535636023206 0ustar00buildbuild00000000000000# # 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 Option1 { } struct Option2 { 1: optional string name } union Descendant { 1: Option1 option1 2: Option2 option2 } struct TestStruct { 1: optional Descendant descendant = { "option1": {}} } thrift-0.23.0/lib/go/test/UnionBinaryTest.thrift0000664000175000017500000000166315165535636022054 0ustar00buildbuild00000000000000# # 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. # # See https://issues.apache.org/jira/browse/THRIFT-4573 union Sample { 1: map u1, 2: binary u2, 3: list u3, 4: set u4, } thrift-0.23.0/lib/go/test/EqualsTest.thrift0000664000175000017500000001170515165535636021047 0ustar00buildbuild00000000000000/* * 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. */ typedef i8 mybyte typedef string mystr typedef binary mybin typedef uuid myuuid enum EnumFoo { e1 e2 } struct BasicEqualsFoo { 1: bool BoolFoo, 2: optional bool OptBoolFoo, 3: i8 I8Foo, 4: optional i8 OptI8Foo, 5: i16 I16Foo, 6: optional i16 OptI16Foo, 7: i32 I32Foo, 8: optional i32 OptI32Foo, 9: i64 I64Foo, 10: optional i64 OptI64Foo, 11: double DoubleFoo, 12: optional double OptDoubleFoo, 13: string StrFoo, 14: optional string OptStrFoo, 15: binary BinFoo, 16: optional binary OptBinFoo, 17: EnumFoo EnumFoo, 18: optional EnumFoo OptEnumFoo, 19: mybyte MyByteFoo, 20: optional mybyte OptMyByteFoo, 21: mystr MyStrFoo, 22: optional mystr OptMyStrFoo, 23: mybin MyBinFoo, 24: optional mybin OptMyBinFoo, 25: uuid UUIDFoo, 26: optional uuid OptUUIDFoo, 27: myuuid MyUUIDFoo, 28: optional myuuid OptMyUUIDFoo, } struct StructEqualsFoo { 1: BasicEqualsFoo StructFoo, 2: optional BasicEqualsFoo OptStructFoo, } struct ListEqualsFoo { 1: list I64ListFoo, 2: optional list OptI64ListFoo, 3: list StrListFoo, 4: optional list OptStrListFoo, 5: list BinListFoo, 6: optional list OptBinListFoo, 7: list StructListFoo, 8: optional list OptStructListFoo, 9: list> I64ListListFoo, 10: optional list> OptI64ListListFoo, 11: list> I64SetListFoo, 12: optional list> OptI64SetListFoo, 13: list> I64StringMapListFoo, 14: optional list> OptI64StringMapListFoo, 15: list MyByteListFoo, 16: optional list OptMyByteListFoo, 17: list MyStrListFoo, 18: optional list OptMyStrListFoo, 19: list MyBinListFoo, 20: optional list OptMyBinListFoo, 21: list UUIDListFoo, 22: optional list OptUUIDListFoo, 23: list MyUUIDListFoo, 24: optional list OptMyUUIDListFoo, } struct SetEqualsFoo { 1: set I64SetFoo, 2: optional set OptI64SetFoo, 3: set StrSetFoo, 4: optional set OptStrSetFoo, 5: set BinSetFoo, 6: optional set OptBinSetFoo, 7: set StructSetFoo, 8: optional set OptStructSetFoo, 9: set> I64ListSetFoo, 10: optional set> OptI64ListSetFoo, 11: set> I64SetSetFoo, 12: optional set> OptI64SetSetFoo, 13: set> I64StringMapSetFoo, 14: optional set> OptI64StringMapSetFoo, 15: set MyByteSetFoo, 16: optional set OptMyByteSetFoo, 17: set MyStrSetFoo, 18: optional set OptMyStrSetFoo, 19: set MyBinSetFoo, 20: optional set OptMyBinSetFoo, 21: set UUIDSetFoo, 22: optional set OptUUIDSetFoo, 23: set MyUUIDSetFoo, 24: optional set OptMyUUIDSetFoo, } struct MapEqualsFoo { 1: map I64StrMapFoo, 2: optional map OptI64StrMapFoo, 3: map StrI64MapFoo, 4: optional map OptStrI64MapFoo, 5: map StructBinMapFoo, 6: optional map OptStructBinMapFoo, 7: map BinStructMapFoo, 8: optional map OptBinStructMapFoo, 9: map> I64I64ListMapFoo, 10: optional map> OptI64I64ListMapFoo, 11: map> I64I64SetMapFoo, 12: optional map> OptI64I64SetMapFoo, 13: map> I64I64StringMapMapFoo, 14: optional map> OptI64I64StringMapMapFoo, 15: map MyStrMyBinMapFoo, 16: optional map OptMyStrMyBinMapFoo, 17: map Int64MyByteMapFoo, 18: optional map OptInt64MyByteMapFoo, 19: map MyByteInt64MapFoo, 20: optional map OptMyByteInt64MapFoo, 21: map UUIDMapFoo, 22: optional map OptUUIDMapFoo, 23: map MyUUIDMapFoo, 24: optional map OptMyUUIDMapFoo, } thrift-0.23.0/lib/go/test/ConflictNamespaceTestB.thrift0000664000175000017500000000152215165535636023271 0ustar00buildbuild00000000000000# # 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 go conflictb.common struct ThingB { 1: bool value } thrift-0.23.0/lib/go/test/ServicesTest.thrift0000664000175000017500000001235515165535636021402 0ustar00buildbuild00000000000000# # 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. # # We are only testing that generated code compiles, no correctness checking is done exception moderate_disaster { 1: i32 errorCode, 2: string message } exception total_disaster { 1: string message 2: optional bool president_was_woken_up = false } struct struct_a { 1: required i64 whatever } service a_serv { void voidfunc(), void void_with_1ex() throws(1: moderate_disaster err1) void void_with_2ex() throws(1: moderate_disaster err1, 2:total_disaster err2) string stringfunc() string stringfunc_1ex() throws(1: moderate_disaster err1) string stringfunc_2ex() throws(1: moderate_disaster err1, 2:total_disaster err2) i64 i64func() i64 i64func_1ex() throws(1: moderate_disaster err1) i64 i64func_2ex() throws(1: moderate_disaster err1, 2:total_disaster err2) list list_of_strings_func() list list_of_strings_func_1ex() throws(1: moderate_disaster err1) list list_of_strings_func_2ex() throws(1: moderate_disaster err1, 2:total_disaster err2) map map_func() map map_func_1ex() throws(1: moderate_disaster err1) map map_func_2ex() throws(1: moderate_disaster err1, 2:total_disaster err2) struct_a struct_a_func() struct_a struct_a_func_1ex() throws(1: moderate_disaster err1) struct_a struct_a_func_2ex() throws(1: moderate_disaster err1, 2:total_disaster err2) void voidfunc_1int(1: i64 i), void void_with_1ex_1int(1: i64 i) throws(1: moderate_disaster err1) void void_with_2ex_1int(1: i64 i) throws(1: moderate_disaster err1, 2:total_disaster err2) string stringfunc_1int(1: i64 i) string stringfunc_1ex_1int(1: i64 i) throws(1: moderate_disaster err1) string stringfunc_2ex_1int(1: i64 i) throws(1: moderate_disaster err1, 2:total_disaster err2) i64 i64func_1int(1: i64 i) i64 i64func_1ex_1int(1: i64 i) throws(1: moderate_disaster err1) i64 i64func_2ex_1int(1: i64 i) throws(1: moderate_disaster err1, 2:total_disaster err2) list list_of_strings_func_1int(1: i64 i) list list_of_strings_func_1ex_1int(1: i64 i) throws(1: moderate_disaster err1) list list_of_strings_func_2ex_1int(1: i64 i) throws(1: moderate_disaster err1, 2:total_disaster err2) map map_func_1int(1: i64 i) map map_func_1ex_1int(1: i64 i) throws(1: moderate_disaster err1) map map_func_2ex_1int(1: i64 i) throws(1: moderate_disaster err1, 2:total_disaster err2) struct_a struct_a_func_1int(1: i64 i) struct_a struct_a_func_1ex_1int(1: i64 i) throws(1: moderate_disaster err1) struct_a struct_a_func_2ex_1int(1: i64 i) throws(1: moderate_disaster err1, 2:total_disaster err2) void voidfunc_1int_1s(1: i64 i, 2: string s), void void_with_1ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1) void void_with_2ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1, 2:total_disaster err2) string stringfunc_1int_1s(1: i64 i, 2: string s) string stringfunc_1ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1) string stringfunc_2ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1, 2:total_disaster err2) i64 i64func_1int_1s(1: i64 i, 2: string s) i64 i64func_1ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1) i64 i64func_2ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1, 2:total_disaster err2) list list_of_strings_func_1int_1s(1: i64 i, 2: string s) list list_of_strings_func_1ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1) list list_of_strings_func_2ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1, 2:total_disaster err2) map map_func_1int_1s(1: i64 i, 2: string s) map map_func_1ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1) map map_func_2ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1, 2:total_disaster err2) struct_a struct_a_func_1int_1s(1: i64 i, 2: string s) struct_a struct_a_func_1ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1) struct_a struct_a_func_2ex_1int_1s(1: i64 i, 2: string s) throws(1: moderate_disaster err1, 2:total_disaster err2) struct_a struct_a_func_1struct_a(1: struct_a st) } service container_test_parent { void parent_only_func(1: set s) } service container_test extends container_test_parent { void child_only_func(1: set s) } thrift-0.23.0/lib/go/test/BinaryKeyTest.thrift0000664000175000017500000000162715165535636021514 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Make sure that thrift produce compilable code for binary key struct testStruct { 1: required map bin_to_string } thrift-0.23.0/lib/go/test/RequiredFieldTest.thrift0000664000175000017500000000160715165535636022341 0ustar00buildbuild00000000000000/* * 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 RequiredField { 1: required string name } struct OtherThing { 1: required i16 value } thrift-0.23.0/lib/go/test/ConflictNamespaceTestSuperThing.thrift0000664000175000017500000000262715165535636025207 0ustar00buildbuild00000000000000# # 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 go conflict.super include "ConflictNamespaceTestA.thrift" include "ConflictNamespaceTestB.thrift" include "ConflictNamespaceTestC.thrift" include "ConflictNamespaceTestD.thrift" include "ConflictNamespaceTestE.thrift" include "ConflictNamespaceTestF.thrift" struct SuperThing { 1: ConflictNamespaceTestA.ThingA thing_a 2: ConflictNamespaceTestB.ThingB thing_b 3: ConflictNamespaceTestC.ThingC thing_c 4: ConflictNamespaceTestD.ThingD thing_d 5: ConflictNamespaceTestE.ThingE thing_e 6: ConflictNamespaceTestF.ThingF thing_f } // Define an enum to force the import of database/sql/driver enum Enum { One = 1 Two = 2 } thrift-0.23.0/lib/go/test/ForwardType.thrift0000664000175000017500000000206615165535636021223 0ustar00buildbuild00000000000000/* * 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. */ // https://issues.apache.org/jira/browse/THRIFT-5685 namespace go forwardtypetest struct Struct { 1: optional Exc foo } // 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 } thrift-0.23.0/lib/go/test/GoTagTest.thrift0000664000175000017500000000174315165535636020617 0ustar00buildbuild00000000000000# # 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 tagged { 1: string string_thing, 2: i64 int_thing (go.tag = "json:\"custom_thing\" mykey:\"myvalue\""), 3: optional i64 optional_int_thing 4: optional bool optional_bool_thing = false } thrift-0.23.0/lib/go/test/IncludesTest.thrift0000664000175000017500000000363615165535636021367 0ustar00buildbuild00000000000000# # 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 "ThriftTest.thrift" include "NamespacedTest.thrift" const ThriftTest.UserId USERID = 42 const NamespacedTest.UserId USERID1 = 41 const ThriftTest.MapType MAPCONSTANT = {'hello':{}, 'goodnight':{}} const i32 TWO = NamespacedTest.Stuff.TWO const i32 THREE = NamespacedTest.THREE struct testStruct { 1: list listNumbers } struct TestStruct2 { 1: testStruct blah, 2: ThriftTest.UserId id, 3: NamespacedTest.Stuff stuff, } service testService extends ThriftTest.SecondService { ThriftTest.CrazyNesting getCrazyNesting( 1: ThriftTest.StructA a, 2: ThriftTest.Numberz numbers ) throws(1: ThriftTest.Xception err1), void getSomeValue_DO_NOT_CALL(), } service ExtendedService extends testService { void extendedMethod(), NamespacedTest.StuffStruct extendedMethod2(), } service Extended2Service extends NamespacedTest.NamespacedService { void extendedMethod3(), } typedef map > > ComplexMapType struct ComplexMapStruct { 1: ComplexMapType complex, } service ComplexMapService { ComplexMapStruct transformMap(1: ComplexMapStruct input), } thrift-0.23.0/lib/go/test/ValidateTest.thrift0000664000175000017500000001711515165535636021347 0ustar00buildbuild00000000000000/* * 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 go validatetest enum EnumFoo { e1 e2 } struct Foo { 1: bool Bool } struct BasicTest { 1: bool Bool0 = true (vt.const = "true") 2: optional bool Bool1 (vt.const = "true") 3: i8 Byte0 = 1 (vt.lt = "2", vt.le = "2", vt.gt = "0", vt.ge = "0", vt.in = "[0, 1, 2]", vt.not_in = "[3, 4, 5]") 4: optional i8 Byte1 (vt.lt = "1", vt.le = "1", vt.gt = "-1", vt.ge = "-1", vt.in = "[-1, 0, 1]", vt.not_in = "[1, 2, 3]") 5: double Double0 = 1.0 (vt.lt = "2.0", vt.le = "2.0", vt.gt = "0", vt.ge = "0", vt.in = "[0, 1.0, 2.0]", vt.not_in = "[3.0, 4.0, 5.0]") 6: optional double Double1 (vt.lt = "2.0", vt.le = "2.0", vt.gt = "0", vt.ge = "0", vt.in = "[0, 1.0, 2.0]", vt.not_in = "[3.0, 4.0, 5.0]") 7: string String0 = "my const string" (vt.const = "my const string", vt.min_size = "0", vt.max_size = "100", vt.pattern = ".*", vt.prefix = "my", vt.suffix = "string", vt.contains = "const", vt.not_contains = "oh") 8: optional string String1 (vt.const = "my const string", vt.min_size = "0", vt.max_size = "100", vt.pattern = ".*", vt.prefix = "my", vt.suffix = "string", vt.contains = "const", vt.not_contains = "oh") 9: binary Binary0 = "my const string" (vt.const = "my const string", vt.min_size = "0", vt.max_size = "100", vt.pattern = ".*", vt.prefix = "my", vt.suffix = "string", vt.contains = "const", vt.not_contains = "oh") 10: optional binary Binary1 = "my const string" (vt.const = "my const string", vt.min_size = "0", vt.max_size = "100", vt.pattern = ".*", vt.prefix = "my", vt.suffix = "string", vt.contains = "const", vt.not_contains = "oh") 11: map Map0 (vt.min_size = "0", vt.max_size = "10", vt.key.min_size = "0", vt.key.max_size = "10", vt.value.min_size = "0", vt.value.max_size = "10") 12: optional map Map1 (vt.min_size = "0", vt.max_size = "10", vt.key.min_size = "0", vt.key.max_size = "10", vt.value.min_size = "0", vt.value.max_size = "10") 13: set Set0 (vt.min_size = "0", vt.max_size = "10", vt.elem.min_size = "5") 14: optional set Set1 (vt.min_size = "0", vt.max_size = "10", vt.elem.min_size = "5") 15: EnumFoo Enum0 = EnumFoo.e2 (vt.in = "[EnumFoo.e2]", vt.defined_only = "true") 16: optional EnumFoo Enum1 (vt.in = "[EnumFoo.e1]", vt.defined_only = "true") 17: Foo Struct0 (vt.skip = "true") 18: optional Foo Struct1 (vt.skip = "true") 19: i8 Byte2 = 1 (vt.in = "1", vt.not_in = "2") 20: double Double2 = 3.0 (vt.in = "3.0", vt.not_in = "4.0") 21: EnumFoo Enum2 = EnumFoo.e2 (vt.in = "EnumFoo.e2", vt.not_in = "EnumFoo.e1") } struct FieldReferenceTest { 1: bool Bool0 (vt.const = "$Bool2") 2: optional bool Bool1 (vt.const = "$Bool2") 3: i8 Byte0 = 10 (vt.lt = "$Byte4", vt.le = "$Byte4", vt.gt = "$Byte2", vt.ge = "$Byte2", vt.in = "[$Byte2, $Byte3, $Byte4]", vt.not_in = "[$Byte2, $Byte4]") 4: optional i8 Byte1 (vt.lt = "$Byte4", vt.le = "$Byte4", vt.gt = "$Byte2", vt.ge = "$Byte2", vt.in = "[$Byte2, $Byte3, $Byte4]", vt.not_in = "[$Byte2, $Byte4]") 5: double Double0 = 10.0 (vt.lt = "$Double4", vt.le = "$Double4", vt.gt = "$Double2", vt.ge = "$Double2", vt.in = "[$Double2, $Double3, $Double4]", vt.not_in = "[$Double2, $Double4]") 6: optional double Double1 (vt.lt = "$Double4", vt.le = "$Double4", vt.gt = "$Double2", vt.ge = "$Double2", vt.in = "[$Double2, $Double3, $Double4]", vt.not_in = "[$Double2, $Double4]") 7: string String0 = "my string" (vt.const = "$String2", vt.min_size = "$Byte2", vt.max_size = "$Byte3", vt.pattern = "$String4", vt.prefix = "$String2", vt.suffix = "$String2", vt.contains = "$String2", vt.not_contains = "$String3") 8: optional string String1 (vt.const = "$String2", vt.min_size = "$Byte2", vt.max_size = "$Byte3", vt.pattern = "$String4", vt.prefix = "$String2", vt.suffix = "$String2", vt.contains = "$String2", vt.not_contains = "$String3") 9: binary Binary0 = "my binary" (vt.const = "$Binary2", vt.min_size = "$Byte2", vt.max_size = "$Byte3", vt.pattern = "$Binary4", vt.prefix = "$Binary2", vt.suffix = "$Binary2", vt.contains = "$Binary2", vt.not_contains = "$Binary3") 10: optional binary Binary1 = "my binary" (vt.const = "$Binary2", vt.min_size = "$Byte2", vt.max_size = "$Byte3", vt.pattern = "$Binary4", vt.prefix = "$Binary2", vt.suffix = "$Binary2", vt.contains = "$Binary2", vt.not_contains = "$Binary3") 11: map Map0 (vt.min_size = "$Byte2", vt.max_size = "$MaxSize", vt.key.min_size = "$Byte2", vt.key.max_size = "$MaxSize", vt.value.min_size = "$Byte2", vt.value.max_size = "$MaxSize") 12: optional map Map1 (vt.min_size = "$Byte2", vt.max_size = "$MaxSize", vt.key.min_size = "$Byte2", vt.key.max_size = "$MaxSize", vt.value.min_size = "$Byte2", vt.value.max_size = "$MaxSize") 13: list List0 (vt.min_size = "$Byte2", vt.max_size = "$MaxSize", vt.elem.min_size = "$Byte2", vt.elem.max_size = "$MaxSize") 14: optional list List1 (vt.min_size = "$Byte2", vt.max_size = "$MaxSize", vt.elem.min_size = "$Byte2", vt.elem.max_size = "$MaxSize") 15: set Set0 (vt.min_size = "$Byte2", vt.max_size = "$MaxSize", vt.elem.min_size = "$Byte2", vt.elem.max_size = "$MaxSize") 16: optional set Set1 (vt.min_size = "$Byte2", vt.max_size = "$MaxSize", vt.elem.min_size = "$Byte2", vt.elem.max_size = "$MaxSize") 17: bool Bool2 = false 18: i8 Byte2 = 0 19: i8 Byte3 = 10 20: i8 Byte4 = 20 21: double Double2 = 0 22: double Double3 = 10.0 23: double Double4 = 20.0 24: string String2 = "my string" 25: string String3 = "other string" 26: string String4 = ".*" 27: binary Binary2 = "my binary" 28: binary Binary3 = "other binary" 29: binary Binary4 = ".*" 30: i64 MaxSize = 10 } struct ValidationFunctionTest { 1: string StringFoo 2: i64 StringLength (vt.in = "[@len($StringFoo)]") } struct AnnotationCompatibleTest { 1: bool Bool0 = true (vt.const = "true", go.tag = 'json:"bool1"') 2: i8 Byte0 = 1 (vt.lt = "2", go.tag = 'json:"byte1"') 3: double Double0 = 1.0 (vt.lt = "2.0", go.tag = 'json:"double1"') 4: string String0 = "my const string" (vt.const = "my const string", go.tag = 'json:"string1"') 5: binary Binary0 = "my const string" (vt.const = "my const string", go.tag = 'json:"binary1"') 6: map Map0 (vt.max_size = "2", go.tag = 'json:"map1"') 7: set Set0 (vt.max_size = "2", go.tag = 'json:"set1"') 8: list List0 (vt.max_size = "2", go.tag = 'json:"list1"') 9: EnumFoo Enum0 = EnumFoo.e2 (vt.in = "[EnumFoo.e2]", go.tag = 'json:"enum1"') 10: Foo Struct0 (vt.skip = "true", go.tag = 'json:"struct1"') } thrift-0.23.0/lib/go/test/dontexportrwtest/0000775000175000017500000000000015165535636021206 5ustar00buildbuild00000000000000thrift-0.23.0/lib/go/test/dontexportrwtest/compile_test.go0000664000175000017500000000222615165535636024226 0ustar00buildbuild00000000000000/* * 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 dontexportrwtest import ( "testing" ) // Make sure that thrift generates non-exported read/write methods if // read_write_private option is specified func TestReadWriteMethodsArePrivate(t *testing.T) { // This will only compile if read/write methods exist s := NewTestStruct() _ = s.read _ = s.write is := NewInnerStruct() _ = is.read _ = is.write } thrift-0.23.0/lib/go/test/TypedefFieldTest.thrift0000664000175000017500000000224615165535636022161 0ustar00buildbuild00000000000000# # 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. # # We are only testing that generated code compiles, no correctness checking is done enum Details { Everything = 0 StateOnly = 1 StateAndOptions = 2 SomethingElse = 3 } typedef list< Details> DetailsWanted struct BaseRequest { 1 : optional string RequestID } struct GetMyDetails { 1 : required BaseRequest base_ 2 : required string ObjectID 3 : optional DetailsWanted DetailsWanted } thrift-0.23.0/lib/go/test/DuplicateImportsTest.thrift0000664000175000017500000000156615165535636023111 0ustar00buildbuild00000000000000/* * 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 "common/a.thrift" include "common/b.thrift" typedef a.A A typedef b.B B thrift-0.23.0/lib/go/test/ClientMiddlewareExceptionTest.thrift0000664000175000017500000000241415165535636024705 0ustar00buildbuild00000000000000/* * 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. */ exception Exception1 { } exception Exception2 { } // This is a special case, we want to make sure that the middleware don't // accidentally pull result as error. struct/*exception*/ FooResponse { // returning an exception by any means other than "throws" is illegal } service ClientMiddlewareExceptionTest { FooResponse foo() throws( // returning an exception by any means other than "throws" is illegal 1: Exception1 error1, 2: Exception2 error2, ) } thrift-0.23.0/lib/go/test/ConflictArgNamesTest.thrift0000664000175000017500000000222115165535636022765 0ustar00buildbuild00000000000000/* * 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. */ service ConflictArgNamesTest { /** * Use some names that could conflict with the compiler code as args * to make sure that the compiler handled them correctly. */ void testNameConflicts( // 1: string args, // args is already a reserved keyword in thrift compiler 2: string result, 3: string meta, 4: string r, 5: string err, ) } thrift-0.23.0/lib/go/test/MultiplexedProtocolTest.thrift0000664000175000017500000000154315165535636023632 0ustar00buildbuild00000000000000# # 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. # service First { i64 returnOne(); } service Second { i64 returnTwo(); } thrift-0.23.0/lib/go/test/ConflictNamespaceTestC.thrift0000664000175000017500000000151015165535636023267 0ustar00buildbuild00000000000000# # 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 go common struct ThingC { 1: bool value } thrift-0.23.0/lib/go/test/OnewayTest.thrift0000664000175000017500000000160315165535636021053 0ustar00buildbuild00000000000000# # 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. # service OneWay { oneway void hi(1: i64 i, 2: string s) void emptyfunc() i64 echo_int(1: i64 param) } thrift-0.23.0/lib/go/test/NamespacedTest.thrift0000664000175000017500000000202215165535636021645 0ustar00buildbuild00000000000000# # 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 "ThriftTest.thrift" namespace go lib.go.test.namespacedtest enum Stuff { ONE = 1, TWO = 2, } const i32 THREE = 3; typedef i64 UserId struct StuffStruct { 2: Stuff stuff, } service NamespacedService { ThriftTest.UserId getUserID(), } thrift-0.23.0/lib/go/test/DontExportRWTest.thrift0000664000175000017500000000162015165535636022167 0ustar00buildbuild00000000000000# # 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 InnerStruct { 1: required string id } struct TestStruct { 1: required string id 2: required InnerStruct inner } thrift-0.23.0/lib/go/test/ConstOptionalFieldImport.thrift0000664000175000017500000000212615165535636023705 0ustar00buildbuild00000000000000/* * 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 go constoptionalfielda enum Foo { One = 1, Two = 2, } typedef Foo TypedefAFoo typedef bool TypedefABool typedef i8 TypedefAI8 typedef i16 TypedefAI16 typedef i32 TypedefAI32 typedef i64 TypedefAI64 typedef double TypedefADouble typedef string TypedefAString typedef binary TypedefABinary thrift-0.23.0/lib/go/test/fuzz/0000755000175000017500000000000015170007201016475 5ustar00buildbuild00000000000000thrift-0.23.0/lib/go/test/fuzz/fuzz_test.go0000664000175000017500000000163315165535636021114 0ustar00buildbuild00000000000000// +build gofuzz /* * 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 fuzz import ( "testing" ) func TestFuzz(t *testing.T) { FuzzTutorial([]byte{1, 2, 3}) } thrift-0.23.0/lib/go/test/fuzz/fuzz.go0000664000175000017500000002342415165535636020057 0ustar00buildbuild00000000000000//go:build gofuzz // +build gofuzz /* * 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 fuzz import ( "context" "fmt" "strconv" "github.com/apache/thrift/lib/go/test/fuzz/gen-go/shared" "github.com/apache/thrift/lib/go/test/fuzz/gen-go/tutorial" "github.com/apache/thrift/lib/go/test/fuzz/gen-go/fuzztest" "github.com/apache/thrift/lib/go/thrift" ) const nbFuzzedProtocols = 2 // 10MB message size limit to prevent over-allocation during fuzzing const FUZZ_MAX_MESSAGE_SIZE = 10 * 1024 * 1024 func fuzzChooseProtocol(d byte, t thrift.TTransport) thrift.TProtocol { switch d % nbFuzzedProtocols { default: fallthrough case 0: return thrift.NewTBinaryProtocolFactoryConf(nil).GetProtocol(t) case 1: return thrift.NewTCompactProtocolFactoryConf(nil).GetProtocol(t) case 2: return thrift.NewTJSONProtocolFactory().GetProtocol(t) } } func FuzzTutorial(data []byte) int { if len(data) < 2 { return 0 } inputTransport := thrift.NewTMemoryBuffer() inputTransport.Buffer.Write(data[2:]) outputTransport := thrift.NewTMemoryBuffer() outputProtocol := fuzzChooseProtocol(data[0], outputTransport) inputProtocol := fuzzChooseProtocol(data[1], inputTransport) ctx := thrift.SetResponseHelper( context.Background(), thrift.TResponseHelper{ THeaderResponseHelper: thrift.NewTHeaderResponseHelper(outputProtocol), }, ) handler := NewCalculatorHandler() processor := tutorial.NewCalculatorProcessor(handler) ok := true var err error for ok { ok, err = processor.Process(ctx, inputProtocol, outputProtocol) if err != nil { // Handle parse error return 0 } res := make([]byte, 1024) n, err := outputTransport.Buffer.Read(res) fmt.Printf("lol %d %s %v\n", n, err, res) } return 1 } type CalculatorHandler struct { log map[int]*shared.SharedStruct } func NewCalculatorHandler() *CalculatorHandler { return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)} } func (p *CalculatorHandler) Ping(ctx context.Context) (err error) { fmt.Print("ping()\n") return nil } func (p *CalculatorHandler) Add(ctx context.Context, num1 int32, num2 int32) (retval17 int32, err error) { fmt.Print("add(", num1, ",", num2, ")\n") return num1 + num2, nil } func (p *CalculatorHandler) Calculate(ctx context.Context, logid int32, w *tutorial.Work) (val int32, err error) { fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n") switch w.Op { case tutorial.Operation_ADD: val = w.Num1 + w.Num2 break case tutorial.Operation_SUBTRACT: val = w.Num1 - w.Num2 break case tutorial.Operation_MULTIPLY: val = w.Num1 * w.Num2 break case tutorial.Operation_DIVIDE: if w.Num2 == 0 { ouch := tutorial.NewInvalidOperation() ouch.WhatOp = int32(w.Op) ouch.Why = "Cannot divide by 0" err = ouch return } val = w.Num1 / w.Num2 break default: ouch := tutorial.NewInvalidOperation() ouch.WhatOp = int32(w.Op) ouch.Why = "Unknown operation" err = ouch return } entry := shared.NewSharedStruct() entry.Key = logid entry.Value = strconv.Itoa(int(val)) k := int(logid) p.log[k] = entry return val, err } func (p *CalculatorHandler) GetStruct(ctx context.Context, key int32) (*shared.SharedStruct, error) { fmt.Print("getStruct(", key, ")\n") v, _ := p.log[int(key)] return v, nil } func (p *CalculatorHandler) Zip(ctx context.Context) (err error) { fmt.Print("zip()\n") return nil } func FuzzParseBinary(data []byte) int { // Skip if input is too small if len(data) < 1 { return 0 } // Create transport and protocol transport := thrift.NewTMemoryBufferLen(len(data)) defer func() { transport.Close() // Reset the buffer to release memory transport.Buffer.Reset() }() transport.Write(data) config := &thrift.TConfiguration{ MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, } protocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(transport) // Try to read the FuzzTest structure fuzzTest := fuzztest.NewFuzzTest() err := fuzzTest.Read(context.Background(), protocol) if err != nil { // Invalid input, but not a crash return 0 } // Successfully parsed return 1 } func FuzzParseCompact(data []byte) int { // Skip if input is too small if len(data) < 1 { return 0 } // Create transport and protocol transport := thrift.NewTMemoryBufferLen(len(data)) defer func() { transport.Close() // Reset the buffer to release memory transport.Buffer.Reset() }() transport.Write(data) config := &thrift.TConfiguration{ MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, } protocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(transport) // Try to read the FuzzTest structure fuzzTest := fuzztest.NewFuzzTest() err := fuzzTest.Read(context.Background(), protocol) if err != nil { // Invalid input, but not a crash return 0 } // Successfully parsed return 1 } func FuzzParseJson(data []byte) int { // Skip if input is too small if len(data) < 1 { return 0 } // Create transport and protocol transport := thrift.NewTMemoryBufferLen(len(data)) defer func() { transport.Close() // Reset the buffer to release memory transport.Buffer.Reset() }() transport.Write(data) protocol := thrift.NewTJSONProtocolFactory().GetProtocol(transport) // Try to read the FuzzTest structure fuzzTest := fuzztest.NewFuzzTest() err := fuzzTest.Read(context.Background(), protocol) if err != nil { // Invalid input, but not a crash return 0 } // Successfully parsed return 1 } func FuzzRoundtripBinary(data []byte) int { // Skip if input is too small if len(data) < 1 { return 0 } config := &thrift.TConfiguration{ MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, } // First parse transport := thrift.NewTMemoryBufferLen(len(data)) transport.Write(data) protocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(transport) // Try to read the FuzzTest structure test1 := fuzztest.NewFuzzTest() err := test1.Read(context.Background(), protocol) if err != nil { // Invalid input, but not a crash return 0 } // Serialize back outTransport := thrift.NewTMemoryBuffer() outProtocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(outTransport) err = test1.Write(context.Background(), outProtocol) if err != nil { return 0 } // Get serialized data and deserialize again serialized := outTransport.Bytes() reTransport := thrift.NewTMemoryBufferLen(len(serialized)) reTransport.Write(serialized) reProtocol := thrift.NewTBinaryProtocolFactoryConf(config).GetProtocol(reTransport) test2 := fuzztest.NewFuzzTest() err = test2.Read(context.Background(), reProtocol) if err != nil { return 0 } // Verify equality if !test1.Equals(test2) { panic("Roundtrip failed: objects not equal after deserialization") } return 1 } func FuzzRoundtripCompact(data []byte) int { // Skip if input is too small if len(data) < 1 { return 0 } config := &thrift.TConfiguration{ MaxMessageSize: FUZZ_MAX_MESSAGE_SIZE, } // First parse transport := thrift.NewTMemoryBufferLen(len(data)) transport.Write(data) protocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(transport) // Try to read the FuzzTest structure test1 := fuzztest.NewFuzzTest() err := test1.Read(context.Background(), protocol) if err != nil { // Invalid input, but not a crash return 0 } // Serialize back outTransport := thrift.NewTMemoryBuffer() outProtocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(outTransport) err = test1.Write(context.Background(), outProtocol) if err != nil { return 0 } // Get serialized data and deserialize again serialized := outTransport.Bytes() reTransport := thrift.NewTMemoryBufferLen(len(serialized)) reTransport.Write(serialized) reProtocol := thrift.NewTCompactProtocolFactoryConf(config).GetProtocol(reTransport) test2 := fuzztest.NewFuzzTest() err = test2.Read(context.Background(), reProtocol) if err != nil { return 0 } // Verify equality if !test1.Equals(test2) { panic("Roundtrip failed: objects not equal after deserialization") } return 1 } func FuzzRoundtripJson(data []byte) int { // Skip if input is too small if len(data) < 1 { return 0 } // First parse transport := thrift.NewTMemoryBufferLen(len(data)) transport.Write(data) protocol := thrift.NewTJSONProtocolFactory().GetProtocol(transport) // Try to read the FuzzTest structure test1 := fuzztest.NewFuzzTest() err := test1.Read(context.Background(), protocol) if err != nil { // Invalid input, but not a crash return 0 } // Serialize back outTransport := thrift.NewTMemoryBuffer() outProtocol := thrift.NewTJSONProtocolFactory().GetProtocol(outTransport) err = test1.Write(context.Background(), outProtocol) if err != nil { return 0 } // Get serialized data and deserialize again serialized := outTransport.Bytes() reTransport := thrift.NewTMemoryBufferLen(len(serialized)) reTransport.Write(serialized) reProtocol := thrift.NewTJSONProtocolFactory().GetProtocol(reTransport) test2 := fuzztest.NewFuzzTest() err = test2.Read(context.Background(), reProtocol) if err != nil { return 0 } // Verify equality if !test1.Equals(test2) { panic("Roundtrip failed: objects not equal after deserialization") } return 1 } thrift-0.23.0/lib/go/test/fuzz/README.md0000664000175000017500000000147115165535636020007 0ustar00buildbuild00000000000000# Go fuzzing README To build the fuzz targets, simply run `make check` in this directory To reproduce a bug, update the code in the fuzz_test.go file, pass the right input buffer in there and update the code to call the relevant function. We currently have the following fuzz targets: * FuzzTutorial -- a fuzzer which spins up an mini server and fuzzes it with random data, following the tutorial example * FuzzParseCompact -- fuzzes the deserialization of the Compact protocol * FuzzParseBinary -- fuzzes the deserialization of the Binary protocol * FuzzParseJson -- fuzzes the deserialization of the JSON protocol * FuzzRoundtripCompact -- fuzzes the roundtrip of the Compact protocol * FuzzRoundtripBinary -- fuzzes the roundtrip of the Binary protocol * FuzzRoundtripJson -- fuzzes the roundtrip of the JSON protocol thrift-0.23.0/lib/go/test/fuzz/Makefile.in0000644000175000017500000004346415170007167020570 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/go/test/fuzz ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ fuzz.go \ fuzz_test.go \ go.mod all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/go/test/fuzz/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/go/test/fuzz/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile gopathfuzz: $(THRIFT) fuzz.go $(THRIFT) -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/fuzz/gen-go/$(COMPILER_EXTRAFLAG) ../../../../tutorial/tutorial.thrift $(THRIFT) -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/fuzz/gen-go/$(COMPILER_EXTRAFLAG) ../../../../test/FuzzTest.thrift touch gopathfuzz check: gopathfuzz go test -tags gofuzz clean-local: $(RM) -rf gopathfuzz gen-go distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/go/test/fuzz/go.mod0000664000175000017500000000026115167543515017627 0ustar00buildbuild00000000000000module github.com/apache/thrift/lib/go/test/fuzz go 1.25 require github.com/apache/thrift v0.0.0-00010101000000-000000000000 replace github.com/apache/thrift => ../../../../ thrift-0.23.0/lib/go/test/fuzz/Makefile.am0000664000175000017500000000260115165535636020560 0ustar00buildbuild00000000000000# # 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. # gopathfuzz: $(THRIFT) fuzz.go $(THRIFT) -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/fuzz/gen-go/$(COMPILER_EXTRAFLAG) ../../../../tutorial/tutorial.thrift $(THRIFT) -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/fuzz/gen-go/$(COMPILER_EXTRAFLAG) ../../../../test/FuzzTest.thrift touch gopathfuzz check: gopathfuzz go test -tags gofuzz clean-local: $(RM) -rf gopathfuzz gen-go distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ fuzz.go \ fuzz_test.go \ go.mod thrift-0.23.0/lib/go/test/OptionalFieldsTest.thrift0000664000175000017500000000263715165535636022535 0ustar00buildbuild00000000000000# # 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 structA { 1: required i64 sa_i } struct all_optional { 1: optional string s = "DEFAULT", 2: optional i64 i = 42, 3: optional bool b = false, 4: optional string s2, 5: optional i64 i2, 6: optional bool b2, 7: optional structA aa, 9: optional list l, 10: optional list l2 = [1, 2], 11: optional map m, 12: optional map m2 = {1:2, 3:4}, 13: optional binary bin, 14: optional binary bin2 = "asdf", } struct structB { 1: required structA required_struct_thing 2: optional structA optional_struct_thing } struct structC { 1: string s, 2: required i32 i, 3: optional bool b, 4: required string s2, } thrift-0.23.0/lib/go/test/ConflictNamespaceTestD.thrift0000664000175000017500000000152315165535636023274 0ustar00buildbuild00000000000000# # 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 go conflictd.context struct ThingD { 1: bool value } thrift-0.23.0/lib/go/test/ConflictNamespaceServiceTest.thrift0000664000175000017500000000164315165535636024514 0ustar00buildbuild00000000000000# # 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 go conflict.context include "ConflictNamespaceTestD.thrift" service ConflictService { ConflictNamespaceTestD.ThingD thingFunc() } thrift-0.23.0/lib/go/test/ConflictNamespaceTestF.thrift0000664000175000017500000000152215165535636023275 0ustar00buildbuild00000000000000# # 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 go conflictf.thrift struct ThingF { 1: bool value } thrift-0.23.0/lib/go/test/ProcessorMiddlewareTest.thrift0000664000175000017500000000206115165535636023565 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ exception Error { 1: optional string foo, } service Service { void ping() throws ( 1: Error error, ); } thrift-0.23.0/lib/go/test/common/0000775000175000017500000000000015165535636017017 5ustar00buildbuild00000000000000thrift-0.23.0/lib/go/test/common/a.thrift0000664000175000017500000000154015165535636020461 0ustar00buildbuild00000000000000/* * 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 go common struct A { 1: optional string a } thrift-0.23.0/lib/go/test/common/b.thrift0000664000175000017500000000154015165535636020462 0ustar00buildbuild00000000000000/* * 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 go common struct B { 1: optional string b } thrift-0.23.0/lib/go/test/RefAnnotationFieldsTest.thrift0000664000175000017500000000420015165535636023503 0ustar00buildbuild00000000000000# # 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 structA { 1: required i64 sa_i } struct all_referenced { 1: optional string s = "DEFAULT" (cpp.ref = ""), 2: optional i64 i = 42 (cpp.ref = ""), 3: optional bool b = false (cpp.ref = ""), 4: optional string s2 (cpp.ref = ""), 5: optional i64 i2 (cpp.ref = ""), 6: optional bool b2 (cpp.ref = ""), 7: optional structA aa (cpp.ref = ""), 9: optional list l (cpp.ref = ""), 10: optional list l2 = [1, 2] (cpp.ref = ""), 11: optional map m (cpp.ref = ""), 12: optional map m2 = {1:2, 3:4} (cpp.ref = ""), 13: optional binary bin (cpp.ref = ""), 14: optional binary bin2 = "asdf" (cpp.ref = ""), 15: required string ref_s = "DEFAULT" (cpp.ref = ""), 16: required i64 ref_i = 42 (cpp.ref = ""), 17: required bool ref_b = false (cpp.ref = ""), 18: required string ref_s2 (cpp.ref = ""), 19: required i64 ref_i2 (cpp.ref = ""), 20: required bool ref_b2 (cpp.ref = ""), 21: required structA ref_aa (cpp.ref = ""), 22: required list ref_l (cpp.ref = ""), 23: required list ref_l2 = [1, 2] (cpp.ref = ""), 24: required map ref_m (cpp.ref = ""), 25: required map ref_m2 = {1:2, 3:4} (cpp.ref = ""), 26: required binary ref_bin (cpp.ref = ""), 27: required binary ref_bin2 = "asdf" (cpp.ref = ""), } struct structB { 1: required structA required_struct_thing 2: optional structA optional_struct_thing } thrift-0.23.0/lib/go/test/StringParseAllocationTest.thrift0000664000175000017500000000153215165535636024061 0ustar00buildbuild00000000000000/* * 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 } thrift-0.23.0/lib/go/test/ConflictNamespaceTestA.thrift0000664000175000017500000000152215165535636023270 0ustar00buildbuild00000000000000# # 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 go conflicta.common struct ThingA { 1: bool value } thrift-0.23.0/lib/go/test/go.sum0000664000175000017500000000473115165535636016667 0ustar00buildbuild00000000000000github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= thrift-0.23.0/lib/go/test/Makefile.in0000644000175000017500000005566615170007167017601 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/go/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ GOBUILDEXTRA = -buildvcs=false THRIFT_GO_ARGS_BASE = thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/gopath/src/ THRIFTARGS = -out gopath/src/ --gen go:$(THRIFT_GO_ARGS_BASE)$(COMPILER_EXTRAFLAG) THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift THRIFTARGS_SKIP_REMOTE = -out gopath/src/ --gen go:skip_remote,$(THRIFT_GO_ARGS_BASE)$(COMPILER_EXTRAFLAG) EXTRA_DIST = \ dontexportrwtest \ tests \ common \ go.mod \ go.sum \ BinaryKeyTest.thrift \ ClientMiddlewareExceptionTest.thrift \ ConflictArgNamesTest.thrift \ ConflictNamespaceServiceTest.thrift \ ConflictNamespaceTestA.thrift \ ConflictNamespaceTestB.thrift \ ConflictNamespaceTestC.thrift \ ConflictNamespaceTestD.thrift \ ConflictNamespaceTestE.thrift \ ConflictNamespaceTestF.thrift \ ConflictNamespaceTestSuperThing.thrift \ ConstOptionalField.thrift \ ConstOptionalFieldImport.thrift \ DontExportRWTest.thrift \ DuplicateImportsTest.thrift \ ErrorTest.thrift \ EqualsTest.thrift \ ForwardType.thrift \ GoTagTest.thrift \ IgnoreInitialismsTest.thrift \ IncludesTest.thrift \ InitialismsTest.thrift \ MultiplexedProtocolTest.thrift \ NamespacedTest.thrift \ NamesTest.thrift \ OnewayTest.thrift \ OptionalFieldsTest.thrift \ ProcessorMiddlewareTest.thrift \ RefAnnotationFieldsTest.thrift \ RequiredFieldTest.thrift \ ServicesTest.thrift \ StringParseAllocationTest.thrift \ TypedefFieldTest.thrift \ UnionBinaryTest.thrift \ UnionDefaultValueTest.thrift \ ValidateTest.thrift all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/go/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/go/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile # Thrift for GO has problems with complex map keys: THRIFT-2063 gopath: $(THRIFT) $(THRIFTTEST) \ IncludesTest.thrift \ NamespacedTest.thrift \ MultiplexedProtocolTest.thrift \ OnewayTest.thrift \ OptionalFieldsTest.thrift \ RequiredFieldTest.thrift \ ServicesTest.thrift \ GoTagTest.thrift \ TypedefFieldTest.thrift \ RefAnnotationFieldsTest.thrift \ UnionDefaultValueTest.thrift \ UnionBinaryTest.thrift \ ErrorTest.thrift \ NamesTest.thrift \ InitialismsTest.thrift \ DontExportRWTest.thrift \ dontexportrwtest/compile_test.go \ IgnoreInitialismsTest.thrift \ ConflictNamespaceTestA.thrift \ ConflictNamespaceTestB.thrift \ ConflictNamespaceTestC.thrift \ ConflictNamespaceTestD.thrift \ ConflictNamespaceTestE.thrift \ ConflictNamespaceTestF.thrift \ ConflictNamespaceTestSuperThing.thrift \ ConflictNamespaceServiceTest.thrift \ DuplicateImportsTest.thrift \ EqualsTest.thrift \ ConflictArgNamesTest.thrift \ ConstOptionalFieldImport.thrift \ ConstOptionalField.thrift \ ProcessorMiddlewareTest.thrift \ ClientMiddlewareExceptionTest.thrift \ ValidateTest.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 $(THRIFT) $(THRIFTARGS) BinaryKeyTest.thrift $(THRIFT) $(THRIFTARGS) MultiplexedProtocolTest.thrift $(THRIFT) $(THRIFTARGS) OnewayTest.thrift $(THRIFT) $(THRIFTARGS) OptionalFieldsTest.thrift $(THRIFT) $(THRIFTARGS) RequiredFieldTest.thrift $(THRIFT) $(THRIFTARGS) ServicesTest.thrift $(THRIFT) $(THRIFTARGS) GoTagTest.thrift $(THRIFT) $(THRIFTARGS) TypedefFieldTest.thrift $(THRIFT) $(THRIFTARGS) RefAnnotationFieldsTest.thrift $(THRIFT) $(THRIFTARGS) UnionDefaultValueTest.thrift $(THRIFT) $(THRIFTARGS) UnionBinaryTest.thrift $(THRIFT) $(THRIFTARGS) ErrorTest.thrift $(THRIFT) $(THRIFTARGS) NamesTest.thrift $(THRIFT) $(THRIFTARGS) InitialismsTest.thrift $(THRIFT) $(THRIFTARGS),read_write_private DontExportRWTest.thrift $(THRIFT) $(THRIFTARGS),ignore_initialisms IgnoreInitialismsTest.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestA.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestB.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestC.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestD.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestE.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestF.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestSuperThing.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceServiceTest.thrift $(THRIFT) $(THRIFTARGS) -r DuplicateImportsTest.thrift $(THRIFT) $(THRIFTARGS) EqualsTest.thrift $(THRIFT) $(THRIFTARGS) ConflictArgNamesTest.thrift $(THRIFT) $(THRIFTARGS) -r ConstOptionalField.thrift $(THRIFT) $(THRIFTARGS_SKIP_REMOTE) ProcessorMiddlewareTest.thrift $(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 check: gopath $(GO) build $(GOBUILDEXTRA) \ ./gopath/src/includestest \ ./gopath/src/binarykeytest \ ./gopath/src/servicestest \ ./gopath/src/typedeffieldtest \ ./gopath/src/refannotationfieldstest \ ./gopath/src/errortest \ ./gopath/src/namestest \ ./gopath/src/initialismstest \ ./gopath/src/dontexportrwtest \ ./gopath/src/ignoreinitialismstest \ ./gopath/src/unionbinarytest \ ./gopath/src/conflict/super \ ./gopath/src/conflict/context/conflict_service-remote \ ./gopath/src/servicestest/container_test-remote \ ./gopath/src/duplicateimportstest \ ./gopath/src/equalstest \ ./gopath/src/conflictargnamestest \ ./gopath/src/processormiddlewaretest \ ./gopath/src/clientmiddlewareexceptiontest \ ./gopath/src/validatetest \ ./gopath/src/forwardtypetest $(GO) test github.com/apache/thrift/lib/go/thrift $(GO) test ./gopath/src/tests ./gopath/src/dontexportrwtest clean-local: $(RM) -r gopath ThriftTest.thrift gen-go client: stubs $(GO) run TestClient.go distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/go/test/tests/0000775000175000017500000000000015167543515016666 5ustar00buildbuild00000000000000thrift-0.23.0/lib/go/test/tests/protocols_test.go0000664000175000017500000000667715165535636022323 0ustar00buildbuild00000000000000/* * 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 ( "testing" "github.com/apache/thrift/lib/go/test/gopath/src/thrifttest" "github.com/apache/thrift/lib/go/thrift" ) func RunSocketTestSuite( t *testing.T, protocolFactory thrift.TProtocolFactory, transportFactory thrift.TTransportFactory, ) { // server var err error addr = FindAvailableTCPServerPort() serverTransport, err := thrift.NewTServerSocketTimeout(addr.String(), TIMEOUT) if err != nil { t.Fatal("Unable to create server socket", err) } processor := thrifttest.NewThriftTestProcessor(NewThriftTestHandler()) server = thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) server.Listen() go server.Serve() // client cfg := &thrift.TConfiguration{ ConnectTimeout: TIMEOUT, SocketTimeout: TIMEOUT, } thrift.PropagateTConfiguration(transportFactory, cfg) var transport thrift.TTransport = thrift.NewTSocketFromAddrConf(addr, cfg) transport, err = transportFactory.GetTransport(transport) if err != nil { t.Fatal(err) } var protocol thrift.TProtocol = protocolFactory.GetProtocol(transport) thriftTestClient := thrifttest.NewThriftTestClient(thrift.NewTStandardClient(protocol, protocol)) err = transport.Open() if err != nil { t.Fatal("Unable to open client socket", err) } driver := NewThriftTestDriver(t, thriftTestClient) driver.Start() } // Run test suite using TJSONProtocol func TestTJSONProtocol(t *testing.T) { RunSocketTestSuite( t, thrift.NewTJSONProtocolFactory(), thrift.NewTTransportFactory(), ) RunSocketTestSuite( t, thrift.NewTJSONProtocolFactory(), thrift.NewTBufferedTransportFactory(8912), ) RunSocketTestSuite( t, thrift.NewTJSONProtocolFactory(), thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), nil), ) } // Run test suite using TBinaryProtocol func TestTBinaryProtocol(t *testing.T) { RunSocketTestSuite( t, thrift.NewTBinaryProtocolFactoryConf(nil), thrift.NewTTransportFactory(), ) RunSocketTestSuite( t, thrift.NewTBinaryProtocolFactoryConf(nil), thrift.NewTBufferedTransportFactory(8912), ) RunSocketTestSuite( t, thrift.NewTBinaryProtocolFactoryConf(nil), thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), nil), ) } // Run test suite using TCompactBinaryProtocol func TestTCompactProtocol(t *testing.T) { RunSocketTestSuite( t, thrift.NewTCompactProtocolFactoryConf(nil), thrift.NewTTransportFactory(), ) RunSocketTestSuite( t, thrift.NewTCompactProtocolFactoryConf(nil), thrift.NewTBufferedTransportFactory(8912), ) RunSocketTestSuite( t, thrift.NewTCompactProtocolFactoryConf(nil), thrift.NewTFramedTransportFactoryConf(thrift.NewTTransportFactory(), nil), ) } thrift-0.23.0/lib/go/test/tests/string_parse_allocation_test.go0000664000175000017500000000373215165535636025171 0ustar00buildbuild00000000000000/* * 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() } } thrift-0.23.0/lib/go/test/tests/initialisms_test.go0000664000175000017500000000242715167543515022606 0ustar00buildbuild00000000000000/* * 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 ( "reflect" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/initialismstest" ) func TestThatCommonInitialismsAreFixed(t *testing.T) { st := reflect.TypeFor[initialismstest.InitialismsTest]() _, ok := st.FieldByName("UserID") if !ok { t.Error("UserID attribute is missing!") } _, ok = st.FieldByName("ServerURL") if !ok { t.Error("ServerURL attribute is missing!") } _, ok = st.FieldByName("ID") if !ok { t.Error("ID attribute is missing!") } } thrift-0.23.0/lib/go/test/tests/union_default_value_test.go0000664000175000017500000000210215165535636024302 0ustar00buildbuild00000000000000/* * 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 ( "testing" "github.com/apache/thrift/lib/go/test/gopath/src/uniondefaultvaluetest" ) func TestUnionDefaultValue(t *testing.T) { s := uniondefaultvaluetest.NewTestStruct() d := s.GetDescendant() if d == nil { t.Error("Default Union value not set!") } } thrift-0.23.0/lib/go/test/tests/multiplexed_protocol_test.go0000664000175000017500000001464115165535636024542 0ustar00buildbuild00000000000000/* * 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" "net" "testing" "time" "github.com/apache/thrift/lib/go/test/gopath/src/multiplexedprotocoltest" "github.com/apache/thrift/lib/go/thrift" ) func FindAvailableTCPServerPort() net.Addr { if l, err := net.Listen("tcp", "127.0.0.1:0"); err != nil { panic("Could not find available server port") } else { defer l.Close() return l.Addr() } } type FirstImpl struct{} func (f *FirstImpl) ReturnOne(ctx context.Context) (r int64, err error) { return 1, nil } type SecondImpl struct{} func (s *SecondImpl) ReturnTwo(ctx context.Context) (r int64, err error) { return 2, nil } func createTransport(addr net.Addr) (thrift.TTransport, error) { cfg := &thrift.TConfiguration{ ConnectTimeout: TIMEOUT, SocketTimeout: TIMEOUT, } socket := thrift.NewTSocketFromAddrConf(addr, cfg) transport := thrift.NewTFramedTransportConf(socket, cfg) err := transport.Open() if err != nil { return nil, err } return transport, nil } func TestMultiplexedProtocolFirst(t *testing.T) { processor := thrift.NewTMultiplexedProcessor() protocolFactory := thrift.NewTBinaryProtocolFactoryConf(nil) transportFactory := thrift.NewTTransportFactory() transportFactory = thrift.NewTFramedTransportFactoryConf(transportFactory, nil) addr := FindAvailableTCPServerPort() serverTransport, err := thrift.NewTServerSocketTimeout(addr.String(), TIMEOUT) if err != nil { t.Fatal("Unable to create server socket", err) } server = thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) firstProcessor := multiplexedprotocoltest.NewFirstProcessor(&FirstImpl{}) processor.RegisterProcessor("FirstService", firstProcessor) secondProcessor := multiplexedprotocoltest.NewSecondProcessor(&SecondImpl{}) processor.RegisterProcessor("SecondService", secondProcessor) defer server.Stop() go server.Serve() time.Sleep(10 * time.Millisecond) transport, err := createTransport(addr) if err != nil { t.Fatal(err) } defer transport.Close() protocol := thrift.NewTMultiplexedProtocol(thrift.NewTBinaryProtocolConf(transport, nil), "FirstService") client := multiplexedprotocoltest.NewFirstClient(thrift.NewTStandardClient(protocol, protocol)) ret, err := client.ReturnOne(defaultCtx) if err != nil { t.Fatal("Unable to call first server:", err) } else if ret != 1 { t.Fatal("Unexpected result from server: ", ret) } } func TestMultiplexedProtocolSecond(t *testing.T) { processor := thrift.NewTMultiplexedProcessor() protocolFactory := thrift.NewTBinaryProtocolFactoryConf(nil) transportFactory := thrift.NewTTransportFactory() transportFactory = thrift.NewTFramedTransportFactoryConf(transportFactory, nil) addr := FindAvailableTCPServerPort() serverTransport, err := thrift.NewTServerSocketTimeout(addr.String(), TIMEOUT) if err != nil { t.Fatal("Unable to create server socket", err) } server = thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) firstProcessor := multiplexedprotocoltest.NewFirstProcessor(&FirstImpl{}) processor.RegisterProcessor("FirstService", firstProcessor) secondProcessor := multiplexedprotocoltest.NewSecondProcessor(&SecondImpl{}) processor.RegisterProcessor("SecondService", secondProcessor) defer server.Stop() go server.Serve() time.Sleep(10 * time.Millisecond) transport, err := createTransport(addr) if err != nil { t.Fatal(err) } defer transport.Close() protocol := thrift.NewTMultiplexedProtocol(thrift.NewTBinaryProtocolConf(transport, nil), "SecondService") client := multiplexedprotocoltest.NewSecondClient(thrift.NewTStandardClient(protocol, protocol)) ret, err := client.ReturnTwo(defaultCtx) if err != nil { t.Fatal("Unable to call second server:", err) } else if ret != 2 { t.Fatal("Unexpected result from server: ", ret) } } func TestMultiplexedProtocolLegacy(t *testing.T) { processor := thrift.NewTMultiplexedProcessor() protocolFactory := thrift.NewTBinaryProtocolFactoryConf(nil) transportFactory := thrift.NewTTransportFactory() transportFactory = thrift.NewTFramedTransportFactoryConf(transportFactory, nil) addr := FindAvailableTCPServerPort() serverTransport, err := thrift.NewTServerSocketTimeout(addr.String(), TIMEOUT) if err != nil { t.Fatal("Unable to create server socket", err) } server = thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) firstProcessor := multiplexedprotocoltest.NewFirstProcessor(&FirstImpl{}) processor.RegisterProcessor("FirstService", firstProcessor) secondProcessor := multiplexedprotocoltest.NewSecondProcessor(&SecondImpl{}) processor.RegisterProcessor("SecondService", secondProcessor) defer server.Stop() go server.Serve() time.Sleep(10 * time.Millisecond) transport, err := createTransport(addr) if err != nil { t.Error(err) return } defer transport.Close() protocol := thrift.NewTBinaryProtocolConf(transport, nil) client := multiplexedprotocoltest.NewSecondClient(thrift.NewTStandardClient(protocol, protocol)) _, err = client.ReturnTwo(defaultCtx) //expect error since default processor is not registered if err == nil { t.Fatal("Expecting error") } //register default processor and call again processor.RegisterDefault(multiplexedprotocoltest.NewSecondProcessor(&SecondImpl{})) transport, err = createTransport(addr) if err != nil { t.Error(err) return } defer transport.Close() protocol = thrift.NewTBinaryProtocolConf(transport, nil) client = multiplexedprotocoltest.NewSecondClient(thrift.NewTStandardClient(protocol, protocol)) ret, err := client.ReturnTwo(defaultCtx) if err != nil { t.Fatal("Unable to call legacy server:", err) } if ret != 2 { t.Fatal("Unexpected result from server: ", ret) } } thrift-0.23.0/lib/go/test/tests/write_texception_test.go0000664000175000017500000000455715165535636023666 0ustar00buildbuild00000000000000/* * 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) } } thrift-0.23.0/lib/go/test/tests/optional_fields_test.go0000664000175000017500000002253715165535636023443 0ustar00buildbuild00000000000000/* * 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 ( "bytes" "context" "testing" "github.com/golang/mock/gomock" "github.com/apache/thrift/lib/go/test/gopath/src/optionalfieldstest" "github.com/apache/thrift/lib/go/thrift" ) func TestIsSetReturnFalseOnCreation(t *testing.T) { ao := optionalfieldstest.NewAllOptional() if ao.IsSetS() { t.Errorf("Optional field S is set on initialization") } if ao.IsSetI() { t.Errorf("Optional field I is set on initialization") } if ao.IsSetB() { t.Errorf("Optional field B is set on initialization") } if ao.IsSetS2() { t.Errorf("Optional field S2 is set on initialization") } if ao.IsSetI2() { t.Errorf("Optional field I2 is set on initialization") } if ao.IsSetB2() { t.Errorf("Optional field B2 is set on initialization") } if ao.IsSetAa() { t.Errorf("Optional field Aa is set on initialization") } if ao.IsSetL() { t.Errorf("Optional field L is set on initialization") } if ao.IsSetL2() { t.Errorf("Optional field L2 is set on initialization") } if ao.IsSetM() { t.Errorf("Optional field M is set on initialization") } if ao.IsSetM2() { t.Errorf("Optional field M2 is set on initialization") } if ao.IsSetBin() { t.Errorf("Optional field Bin is set on initialization") } if ao.IsSetBin2() { t.Errorf("Optional field Bin2 is set on initialization") } } func TestDefaultValuesOnCreation(t *testing.T) { ao := optionalfieldstest.NewAllOptional() if ao.GetS() != "DEFAULT" { t.Errorf("Unexpected default value %#v for field S", ao.GetS()) } if ao.GetI() != 42 { t.Errorf("Unexpected default value %#v for field I", ao.GetI()) } if ao.GetB() != false { t.Errorf("Unexpected default value %#v for field B", ao.GetB()) } if ao.GetS2() != "" { t.Errorf("Unexpected default value %#v for field S2", ao.GetS2()) } if ao.GetI2() != 0 { t.Errorf("Unexpected default value %#v for field I2", ao.GetI2()) } if ao.GetB2() != false { t.Errorf("Unexpected default value %#v for field B2", ao.GetB2()) } if l := ao.GetL(); len(l) != 0 { t.Errorf("Unexpected default value %#v for field L", l) } if l := ao.GetL2(); len(l) != 2 || l[0] != 1 || l[1] != 2 { t.Errorf("Unexpected default value %#v for field L2", l) } //FIXME: should we return empty map here? if m := ao.GetM(); m != nil { t.Errorf("Unexpected default value %#v for field M", m) } if m := ao.GetM2(); len(m) != 2 || m[1] != 2 || m[3] != 4 { t.Errorf("Unexpected default value %#v for field M2", m) } if bv := ao.GetBin(); bv != nil { t.Errorf("Unexpected default value %#v for field Bin", bv) } if bv := ao.GetBin2(); !bytes.Equal(bv, []byte("asdf")) { t.Errorf("Unexpected default value %#v for field Bin2", bv) } } func TestInitialValuesOnCreation(t *testing.T) { ao := optionalfieldstest.NewAllOptional() if ao.S != "DEFAULT" { t.Errorf("Unexpected initial value %#v for field S", ao.S) } if ao.I != 42 { t.Errorf("Unexpected initial value %#v for field I", ao.I) } if ao.B != false { t.Errorf("Unexpected initial value %#v for field B", ao.B) } if ao.S2 != nil { t.Errorf("Unexpected initial value %#v for field S2", ao.S2) } if ao.I2 != nil { t.Errorf("Unexpected initial value %#v for field I2", ao.I2) } if ao.B2 != nil { t.Errorf("Unexpected initial value %#v for field B2", ao.B2) } if ao.L != nil || len(ao.L) != 0 { t.Errorf("Unexpected initial value %#v for field L", ao.L) } if ao.L2 != nil { t.Errorf("Unexpected initial value %#v for field L2", ao.L2) } if ao.M != nil { t.Errorf("Unexpected initial value %#v for field M", ao.M) } if ao.M2 != nil { t.Errorf("Unexpected initial value %#v for field M2", ao.M2) } if ao.Bin != nil || len(ao.Bin) != 0 { t.Errorf("Unexpected initial value %#v for field Bin", ao.Bin) } if !bytes.Equal(ao.Bin2, []byte("asdf")) { t.Errorf("Unexpected initial value %#v for field Bin2", ao.Bin2) } } func TestIsSetReturnTrueAfterUpdate(t *testing.T) { ao := optionalfieldstest.NewAllOptional() ao.S = "somevalue" ao.I = 123 ao.B = true ao.Aa = optionalfieldstest.NewStructA() if !ao.IsSetS() { t.Errorf("Field S should be set") } if !ao.IsSetI() { t.Errorf("Field I should be set") } if !ao.IsSetB() { t.Errorf("Field B should be set") } if !ao.IsSetAa() { t.Errorf("Field aa should be set") } } func TestListNotEmpty(t *testing.T) { ao := optionalfieldstest.NewAllOptional() ao.L = []int64{1, 2, 3} if !ao.IsSetL() { t.Errorf("Field L should be set") } } //Make sure that optional fields are not being serialized func TestNoOptionalUnsetFieldsOnWire(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() proto := NewMockTProtocol(mockCtrl) gomock.InOrder( proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil), proto.EXPECT().WriteFieldStop(context.Background()).Return(nil), proto.EXPECT().WriteStructEnd(context.Background()).Return(nil), ) ao := optionalfieldstest.NewAllOptional() ao.Write(context.Background(), proto) } func TestNoSetToDefaultFieldsOnWire(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() proto := NewMockTProtocol(mockCtrl) gomock.InOrder( proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil), proto.EXPECT().WriteFieldStop(context.Background()).Return(nil), proto.EXPECT().WriteStructEnd(context.Background()).Return(nil), ) ao := optionalfieldstest.NewAllOptional() ao.I = 42 ao.Write(context.Background(), proto) } //Make sure that only one field is being serialized when set to non-default func TestOneISetFieldOnWire(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() proto := NewMockTProtocol(mockCtrl) gomock.InOrder( proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil), proto.EXPECT().WriteFieldBegin(context.Background(), "i", thrift.TType(thrift.I64), int16(2)).Return(nil), proto.EXPECT().WriteI64(context.Background(), int64(123)).Return(nil), proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil), proto.EXPECT().WriteFieldStop(context.Background()).Return(nil), proto.EXPECT().WriteStructEnd(context.Background()).Return(nil), ) ao := optionalfieldstest.NewAllOptional() ao.I = 123 ao.Write(context.Background(), proto) } func TestOneLSetFieldOnWire(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() proto := NewMockTProtocol(mockCtrl) gomock.InOrder( proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil), proto.EXPECT().WriteFieldBegin(context.Background(), "l", thrift.TType(thrift.LIST), int16(9)).Return(nil), proto.EXPECT().WriteListBegin(context.Background(), thrift.TType(thrift.I64), 2).Return(nil), proto.EXPECT().WriteI64(context.Background(), int64(1)).Return(nil), proto.EXPECT().WriteI64(context.Background(), int64(2)).Return(nil), proto.EXPECT().WriteListEnd(context.Background()).Return(nil), proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil), proto.EXPECT().WriteFieldStop(context.Background()).Return(nil), proto.EXPECT().WriteStructEnd(context.Background()).Return(nil), ) ao := optionalfieldstest.NewAllOptional() ao.L = []int64{1, 2} ao.Write(context.Background(), proto) } func TestOneBinSetFieldOnWire(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() proto := NewMockTProtocol(mockCtrl) gomock.InOrder( proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil), proto.EXPECT().WriteFieldBegin(context.Background(), "bin", thrift.TType(thrift.STRING), int16(13)).Return(nil), proto.EXPECT().WriteBinary(context.Background(), []byte("somebytestring")).Return(nil), proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil), proto.EXPECT().WriteFieldStop(context.Background()).Return(nil), proto.EXPECT().WriteStructEnd(context.Background()).Return(nil), ) ao := optionalfieldstest.NewAllOptional() ao.Bin = []byte("somebytestring") ao.Write(context.Background(), proto) } func TestOneEmptyBinSetFieldOnWire(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() proto := NewMockTProtocol(mockCtrl) gomock.InOrder( proto.EXPECT().WriteStructBegin(context.Background(), "all_optional").Return(nil), proto.EXPECT().WriteFieldBegin(context.Background(), "bin", thrift.TType(thrift.STRING), int16(13)).Return(nil), proto.EXPECT().WriteBinary(context.Background(), []byte{}).Return(nil), proto.EXPECT().WriteFieldEnd(context.Background()).Return(nil), proto.EXPECT().WriteFieldStop(context.Background()).Return(nil), proto.EXPECT().WriteStructEnd(context.Background()).Return(nil), ) ao := optionalfieldstest.NewAllOptional() ao.Bin = []byte{} ao.Write(context.Background(), proto) } thrift-0.23.0/lib/go/test/tests/forwardtype_test.go0000664000175000017500000000240415165535636022625 0ustar00buildbuild00000000000000/* * 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 ( "testing" "github.com/apache/thrift/lib/go/test/gopath/src/forwardtypetest" "github.com/apache/thrift/lib/go/thrift" ) func TestForwardType(t *testing.T) { // See https://issues.apache.org/jira/browse/THRIFT-5685 const code = int32(1) foo := &forwardtypetest.Struct{ Foo: &forwardtypetest.Exc{ Code: thrift.Pointer(code), }, } if got, want := foo.GetFoo().GetCode(), code; got != want { t.Errorf("code got %v want %v", got, want) } } thrift-0.23.0/lib/go/test/tests/struct_args_rets_test.go0000664000175000017500000000235015165535636023654 0ustar00buildbuild00000000000000/* * 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 ( st "github.com/apache/thrift/lib/go/test/gopath/src/servicestest" ) // This function is never called, it will fail to compile if check is failed // //lint:ignore U1000 see above ^ func staticCheckStructArgsResults() { //Check that struct args and results are passed by reference var sa *st.StructA = &st.StructA{} var iface st.AServ var err error sa, err = iface.StructAFunc_1structA(defaultCtx, sa) _ = err _ = sa } thrift-0.23.0/lib/go/test/tests/thrifttest_handler.go0000664000175000017500000001433415165535636023122 0ustar00buildbuild00000000000000/* * 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" "time" "github.com/apache/thrift/lib/go/test/gopath/src/thrifttest" "github.com/apache/thrift/lib/go/thrift" ) type SecondServiceHandler struct { } func NewSecondServiceHandler() *SecondServiceHandler { return &SecondServiceHandler{} } func (p *SecondServiceHandler) BlahBlah(ctx context.Context) (err error) { return nil } func (p *SecondServiceHandler) SecondtestString(ctx context.Context, thing string) (r string, err error) { return thing, nil } type ThriftTestHandler struct { } func NewThriftTestHandler() *ThriftTestHandler { return &ThriftTestHandler{} } func (p *ThriftTestHandler) TestVoid(ctx context.Context) (err error) { return nil } func (p *ThriftTestHandler) TestString(ctx context.Context, thing string) (r string, err error) { return thing, nil } func (p *ThriftTestHandler) TestBool(ctx context.Context, thing bool) (r bool, err error) { return thing, nil } func (p *ThriftTestHandler) TestByte(ctx context.Context, thing int8) (r int8, err error) { return thing, nil } func (p *ThriftTestHandler) TestI32(ctx context.Context, thing int32) (r int32, err error) { return thing, nil } func (p *ThriftTestHandler) TestI64(ctx context.Context, thing int64) (r int64, err error) { return thing, nil } func (p *ThriftTestHandler) TestDouble(ctx context.Context, thing float64) (r float64, err error) { return thing, nil } func (p *ThriftTestHandler) TestBinary(ctx context.Context, thing []byte) (r []byte, err error) { return thing, nil } func (p *ThriftTestHandler) TestUuid(ctx context.Context, thing thrift.Tuuid) (r thrift.Tuuid, err error) { return thing, nil } func (p *ThriftTestHandler) TestStruct(ctx context.Context, thing *thrifttest.Xtruct) (r *thrifttest.Xtruct, err error) { return thing, nil } func (p *ThriftTestHandler) TestNest(ctx context.Context, thing *thrifttest.Xtruct2) (r *thrifttest.Xtruct2, err error) { return thing, nil } func (p *ThriftTestHandler) TestMap(ctx context.Context, thing map[int32]int32) (r map[int32]int32, err error) { return thing, nil } func (p *ThriftTestHandler) TestStringMap(ctx context.Context, thing map[string]string) (r map[string]string, err error) { return thing, nil } func (p *ThriftTestHandler) TestSet(ctx context.Context, thing []int32) (r []int32, err error) { return thing, nil } func (p *ThriftTestHandler) TestList(ctx context.Context, thing []int32) (r []int32, err error) { return thing, nil } func (p *ThriftTestHandler) TestEnum(ctx context.Context, thing thrifttest.Numberz) (r thrifttest.Numberz, err error) { return thing, nil } func (p *ThriftTestHandler) TestTypedef(ctx context.Context, thing thrifttest.UserId) (r thrifttest.UserId, err error) { return thing, nil } func (p *ThriftTestHandler) TestMapMap(ctx context.Context, hello int32) (r map[int32]map[int32]int32, err error) { r = make(map[int32]map[int32]int32) pos := make(map[int32]int32) neg := make(map[int32]int32) for i := int32(1); i < 5; i++ { pos[i] = i neg[-i] = -i } r[4] = pos r[-4] = neg return r, nil } func (p *ThriftTestHandler) TestInsanity(ctx context.Context, argument *thrifttest.Insanity) (r map[thrifttest.UserId]map[thrifttest.Numberz]*thrifttest.Insanity, err error) { hello := thrifttest.NewXtruct() hello.StringThing = "Hello2" hello.ByteThing = 2 hello.I32Thing = 2 hello.I64Thing = 2 goodbye := thrifttest.NewXtruct() goodbye.StringThing = "Goodbye4" goodbye.ByteThing = 4 goodbye.I32Thing = 4 goodbye.I64Thing = 4 crazy := thrifttest.NewInsanity() crazy.UserMap = make(map[thrifttest.Numberz]thrifttest.UserId) crazy.UserMap[thrifttest.Numberz_EIGHT] = 8 crazy.UserMap[thrifttest.Numberz_FIVE] = 5 crazy.Xtructs = []*thrifttest.Xtruct{goodbye, hello} first_map := make(map[thrifttest.Numberz]*thrifttest.Insanity) second_map := make(map[thrifttest.Numberz]*thrifttest.Insanity) first_map[thrifttest.Numberz_TWO] = crazy first_map[thrifttest.Numberz_THREE] = crazy looney := thrifttest.NewInsanity() second_map[thrifttest.Numberz_SIX] = looney var insane = make(map[thrifttest.UserId]map[thrifttest.Numberz]*thrifttest.Insanity) insane[1] = first_map insane[2] = second_map return insane, nil } func (p *ThriftTestHandler) TestMulti(ctx context.Context, arg0 int8, arg1 int32, arg2 int64, arg3 map[int16]string, arg4 thrifttest.Numberz, arg5 thrifttest.UserId) (r *thrifttest.Xtruct, err error) { r = thrifttest.NewXtruct() r.StringThing = "Hello2" r.ByteThing = arg0 r.I32Thing = arg1 r.I64Thing = arg2 return r, nil } func (p *ThriftTestHandler) TestException(ctx context.Context, arg string) (err error) { if arg == "Xception" { x := thrifttest.NewXception() x.ErrorCode = 1001 x.Message = arg return x } else if arg == "TException" { return thrift.WrapTException(errors.New(arg)) } else { return nil } } func (p *ThriftTestHandler) TestMultiException(ctx context.Context, arg0 string, arg1 string) (r *thrifttest.Xtruct, err error) { if arg0 == "Xception" { x := thrifttest.NewXception() x.ErrorCode = 1001 x.Message = "This is an Xception" return nil, x } else if arg0 == "Xception2" { x2 := thrifttest.NewXception2() x2.ErrorCode = 2002 x2.StructThing = thrifttest.NewXtruct() x2.StructThing.StringThing = "This is an Xception2" return nil, x2 } res := thrifttest.NewXtruct() res.StringThing = arg1 return res, nil } func (p *ThriftTestHandler) TestOneway(ctx context.Context, secondsToSleep int32) (err error) { time.Sleep(time.Second * time.Duration(secondsToSleep)) return nil } thrift-0.23.0/lib/go/test/tests/union_binary_test.go0000664000175000017500000000223515165535636022755 0ustar00buildbuild00000000000000/* * 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 ( "testing" "github.com/apache/thrift/lib/go/test/gopath/src/unionbinarytest" ) // See https://issues.apache.org/jira/browse/THRIFT-4573 func TestUnionBinary(t *testing.T) { s := unionbinarytest.NewSample() s.U1 = map[string]string{} s.U2 = []byte{} if n := s.CountSetFieldsSample(); n != 2 { t.Errorf("Expected 2 set fields, got %d!", n) } } thrift-0.23.0/lib/go/test/tests/binary_key_test.go0000664000175000017500000000213015165535636022407 0ustar00buildbuild00000000000000/* * 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 ( "testing" "github.com/apache/thrift/lib/go/test/gopath/src/binarykeytest" ) func TestBinaryMapKeyGeneratesString(t *testing.T) { s := binarykeytest.NewTestStruct() //This will only compile if BinToString has type of map[string]string s.BinToString = make(map[string]string) } thrift-0.23.0/lib/go/test/tests/encoding_json_test.go0000664000175000017500000000432415165535636023101 0ustar00buildbuild00000000000000/* * 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 ( "encoding" "encoding/json" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/thrifttest" ) func TestEnumIsTextMarshaller(t *testing.T) { one := thrifttest.Numberz_ONE var tm encoding.TextMarshaler = one b, err := tm.MarshalText() if err != nil { t.Fatalf("Unexpected error from MarshalText: %s", err) } if string(b) != one.String() { t.Errorf("MarshalText(%s) = %s, expected = %s", one, b, one) } } func TestEnumIsTextUnmarshaller(t *testing.T) { var tm encoding.TextUnmarshaler = thrifttest.NumberzPtr(thrifttest.Numberz_TWO) err := tm.UnmarshalText([]byte("TWO")) if err != nil { t.Fatalf("Unexpected error from UnmarshalText(TWO): %s", err) } if *(tm.(*thrifttest.Numberz)) != thrifttest.Numberz_TWO { t.Errorf("UnmarshalText(TWO) = %s", tm) } err = tm.UnmarshalText([]byte("NAN")) if err == nil { t.Errorf("Error from UnmarshalText(NAN)") } } func TestJSONMarshalUnmarshal(t *testing.T) { s1 := thrifttest.StructB{ Aa: &thrifttest.StructA{S: "Aa"}, Ab: &thrifttest.StructA{S: "Ab"}, } b, err := json.Marshal(s1) if err != nil { t.Fatalf("Unexpected error from json.Marshal: %s", err) } s2 := thrifttest.StructB{} err = json.Unmarshal(b, &s2) if err != nil { t.Fatalf("Unexpected error from json.Unmarshal: %s", err) } if *s1.Aa != *s2.Aa || *s1.Ab != *s2.Ab { t.Logf("s1 = %+v", s1) t.Logf("s2 = %+v", s2) t.Errorf("json: Unmarshal(Marshal(s)) != s") } } thrift-0.23.0/lib/go/test/tests/client_error_test.go0000664000175000017500000007044615165535636022761 0ustar00buildbuild00000000000000/* * 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/golang/mock/gomock" "github.com/apache/thrift/lib/go/test/gopath/src/errortest" "github.com/apache/thrift/lib/go/thrift" ) // TestCase: Comprehensive call and reply workflow in the client. // Setup mock to fail at a certain position. Return true if position exists otherwise false. func prepareClientCallReply(protocol *MockTProtocol, failAt int, failWith error) bool { // NOTE: here the number 50 is the same as the last number at the end of // this function. If more function calls are added in the future, this // number needs to be increased accordingly. // // It's needed for go 1.14+. Before go 1.14 we only call gomock // controller's Finish function when this function returns true. // Starting from go 1.14 the gomock will take advantage of // testing.T.Cleanup interface, which means the Finish function will // always be called by t.Cleanup, even if we return false here. // As a result, in the case we need to return false by this function, // we must return before calling any of the // protocol.EXPECT().* functions. const lastFailAt = 50 if failAt > lastFailAt { return false } var err error = nil if failAt == 0 { err = failWith } last := protocol.EXPECT().WriteMessageBegin(context.Background(), "testStruct", thrift.CALL, int32(1)).Return(err) if failAt == 0 { return true } if failAt == 1 { err = failWith } last = protocol.EXPECT().WriteStructBegin(context.Background(), "testStruct_args").Return(err).After(last) if failAt == 1 { return true } if failAt == 2 { err = failWith } last = protocol.EXPECT().WriteFieldBegin(context.Background(), "thing", thrift.TType(thrift.STRUCT), int16(1)).Return(err).After(last) if failAt == 2 { return true } if failAt == 3 { err = failWith } last = protocol.EXPECT().WriteStructBegin(context.Background(), "TestStruct").Return(err).After(last) if failAt == 3 { return true } if failAt == 4 { err = failWith } last = protocol.EXPECT().WriteFieldBegin(context.Background(), "m", thrift.TType(thrift.MAP), int16(1)).Return(err).After(last) if failAt == 4 { return true } if failAt == 5 { err = failWith } last = protocol.EXPECT().WriteMapBegin(context.Background(), thrift.TType(thrift.STRING), thrift.TType(thrift.STRING), 0).Return(err).After(last) if failAt == 5 { return true } if failAt == 6 { err = failWith } last = protocol.EXPECT().WriteMapEnd(context.Background()).Return(err).After(last) if failAt == 6 { return true } if failAt == 7 { err = failWith } last = protocol.EXPECT().WriteFieldEnd(context.Background()).Return(err).After(last) if failAt == 7 { return true } if failAt == 8 { err = failWith } last = protocol.EXPECT().WriteFieldBegin(context.Background(), "l", thrift.TType(thrift.LIST), int16(2)).Return(err).After(last) if failAt == 8 { return true } if failAt == 9 { err = failWith } last = protocol.EXPECT().WriteListBegin(context.Background(), thrift.TType(thrift.STRING), 0).Return(err).After(last) if failAt == 9 { return true } if failAt == 10 { err = failWith } last = protocol.EXPECT().WriteListEnd(context.Background()).Return(err).After(last) if failAt == 10 { return true } if failAt == 11 { err = failWith } last = protocol.EXPECT().WriteFieldEnd(context.Background()).Return(err).After(last) if failAt == 11 { return true } if failAt == 12 { err = failWith } last = protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.SET), int16(3)).Return(err).After(last) if failAt == 12 { return true } if failAt == 13 { err = failWith } last = protocol.EXPECT().WriteSetBegin(context.Background(), thrift.TType(thrift.STRING), 0).Return(err).After(last) if failAt == 13 { return true } if failAt == 14 { err = failWith } last = protocol.EXPECT().WriteSetEnd(context.Background()).Return(err).After(last) if failAt == 14 { return true } if failAt == 15 { err = failWith } last = protocol.EXPECT().WriteFieldEnd(context.Background()).Return(err).After(last) if failAt == 15 { return true } if failAt == 16 { err = failWith } last = protocol.EXPECT().WriteFieldBegin(context.Background(), "i", thrift.TType(thrift.I32), int16(4)).Return(err).After(last) if failAt == 16 { return true } if failAt == 17 { err = failWith } last = protocol.EXPECT().WriteI32(context.Background(), int32(3)).Return(err).After(last) if failAt == 17 { return true } if failAt == 18 { err = failWith } last = protocol.EXPECT().WriteFieldEnd(context.Background()).Return(err).After(last) if failAt == 18 { return true } if failAt == 19 { err = failWith } last = protocol.EXPECT().WriteFieldStop(context.Background()).Return(err).After(last) if failAt == 19 { return true } if failAt == 20 { err = failWith } last = protocol.EXPECT().WriteStructEnd(context.Background()).Return(err).After(last) if failAt == 20 { return true } if failAt == 21 { err = failWith } last = protocol.EXPECT().WriteFieldEnd(context.Background()).Return(err).After(last) if failAt == 21 { return true } if failAt == 22 { err = failWith } last = protocol.EXPECT().WriteFieldStop(context.Background()).Return(err).After(last) if failAt == 22 { return true } if failAt == 23 { err = failWith } last = protocol.EXPECT().WriteStructEnd(context.Background()).Return(err).After(last) if failAt == 23 { return true } if failAt == 24 { err = failWith } last = protocol.EXPECT().WriteMessageEnd(context.Background()).Return(err).After(last) if failAt == 24 { return true } if failAt == 25 { err = failWith } last = protocol.EXPECT().Flush(context.Background()).Return(err).After(last) if failAt == 25 { return true } if failAt == 26 { err = failWith } last = protocol.EXPECT().ReadMessageBegin(context.Background()).Return("testStruct", thrift.REPLY, int32(1), err).After(last) if failAt == 26 { return true } if failAt == 27 { err = failWith } last = protocol.EXPECT().ReadStructBegin(context.Background()).Return("testStruct_args", err).After(last) if failAt == 27 { return true } if failAt == 28 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("_", thrift.TType(thrift.STRUCT), int16(0), err).After(last) if failAt == 28 { return true } if failAt == 29 { err = failWith } last = protocol.EXPECT().ReadStructBegin(context.Background()).Return("TestStruct", err).After(last) if failAt == 29 { return true } if failAt == 30 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("m", thrift.TType(thrift.MAP), int16(1), err).After(last) if failAt == 30 { return true } if failAt == 31 { err = failWith } last = protocol.EXPECT().ReadMapBegin(context.Background()).Return(thrift.TType(thrift.STRING), thrift.TType(thrift.STRING), 0, err).After(last) if failAt == 31 { return true } if failAt == 32 { err = failWith } last = protocol.EXPECT().ReadMapEnd(context.Background()).Return(err).After(last) if failAt == 32 { return true } if failAt == 33 { err = failWith } last = protocol.EXPECT().ReadFieldEnd(context.Background()).Return(err).After(last) if failAt == 33 { return true } if failAt == 34 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("l", thrift.TType(thrift.LIST), int16(2), err).After(last) if failAt == 34 { return true } if failAt == 35 { err = failWith } last = protocol.EXPECT().ReadListBegin(context.Background()).Return(thrift.TType(thrift.STRING), 0, err).After(last) if failAt == 35 { return true } if failAt == 36 { err = failWith } last = protocol.EXPECT().ReadListEnd(context.Background()).Return(err).After(last) if failAt == 36 { return true } if failAt == 37 { err = failWith } last = protocol.EXPECT().ReadFieldEnd(context.Background()).Return(err).After(last) if failAt == 37 { return true } if failAt == 38 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("s", thrift.TType(thrift.SET), int16(3), err).After(last) if failAt == 38 { return true } if failAt == 39 { err = failWith } last = protocol.EXPECT().ReadSetBegin(context.Background()).Return(thrift.TType(thrift.STRING), 0, err).After(last) if failAt == 39 { return true } if failAt == 40 { err = failWith } last = protocol.EXPECT().ReadSetEnd(context.Background()).Return(err).After(last) if failAt == 40 { return true } if failAt == 41 { err = failWith } last = protocol.EXPECT().ReadFieldEnd(context.Background()).Return(err).After(last) if failAt == 41 { return true } if failAt == 42 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("i", thrift.TType(thrift.I32), int16(4), err).After(last) if failAt == 42 { return true } if failAt == 43 { err = failWith } last = protocol.EXPECT().ReadI32(context.Background()).Return(int32(3), err).After(last) if failAt == 43 { return true } if failAt == 44 { err = failWith } last = protocol.EXPECT().ReadFieldEnd(context.Background()).Return(err).After(last) if failAt == 44 { return true } if failAt == 45 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("_", thrift.TType(thrift.STOP), int16(5), err).After(last) if failAt == 45 { return true } if failAt == 46 { err = failWith } last = protocol.EXPECT().ReadStructEnd(context.Background()).Return(err).After(last) if failAt == 46 { return true } if failAt == 47 { err = failWith } last = protocol.EXPECT().ReadFieldEnd(context.Background()).Return(err).After(last) if failAt == 47 { return true } if failAt == 48 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("_", thrift.TType(thrift.STOP), int16(1), err).After(last) if failAt == 48 { return true } if failAt == 49 { err = failWith } last = protocol.EXPECT().ReadStructEnd(context.Background()).Return(err).After(last) if failAt == 49 { return true } if failAt == 50 { err = failWith } //lint:ignore SA4006 to keep it consistent with other checks above last = protocol.EXPECT().ReadMessageEnd(context.Background()).Return(err).After(last) //lint:ignore S1008 to keep it consistent with other checks above if failAt == 50 { return true } return false } // TestCase: Comprehensive call and reply workflow in the client. // Expecting TTransportError on fail. func TestClientReportTTransportErrors(t *testing.T) { mockCtrl := gomock.NewController(t) thing := errortest.NewTestStruct() thing.M = make(map[string]string) thing.L = make([]string, 0) thing.S = make([]string, 0) thing.I = 3 err := thrift.NewTTransportException(thrift.TIMED_OUT, "test") for i := 0; ; i++ { protocol := NewMockTProtocol(mockCtrl) if !prepareClientCallReply(protocol, i, err) { return } client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol)) _, retErr := client.TestStruct(defaultCtx, thing) mockCtrl.Finish() mockCtrl = gomock.NewController(t) err2, ok := retErr.(thrift.TTransportException) if !ok { t.Fatal("Expected a TTrasportException") } if err2.TypeId() != thrift.TIMED_OUT { t.Fatal("Expected TIMED_OUT error") } } } // TestCase: Comprehensive call and reply workflow in the client. // Expecting TTransportError on fail. // Similar to TestClientReportTTransportErrors, but using legacy client constructor. func TestClientReportTTransportErrorsLegacy(t *testing.T) { mockCtrl := gomock.NewController(t) transport := thrift.NewTMemoryBuffer() thing := errortest.NewTestStruct() thing.M = make(map[string]string) thing.L = make([]string, 0) thing.S = make([]string, 0) thing.I = 3 err := thrift.NewTTransportException(thrift.TIMED_OUT, "test") for i := 0; ; i++ { protocol := NewMockTProtocol(mockCtrl) if !prepareClientCallReply(protocol, i, err) { return } client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol) _, retErr := client.TestStruct(defaultCtx, thing) mockCtrl.Finish() mockCtrl = gomock.NewController(t) err2, ok := retErr.(thrift.TTransportException) if !ok { t.Fatal("Expected a TTrasportException") } if err2.TypeId() != thrift.TIMED_OUT { t.Fatal("Expected TIMED_OUT error") } } } // TestCase: Comprehensive call and reply workflow in the client. // Expecting TTProtocolErrors on fail. func TestClientReportTProtocolErrors(t *testing.T) { mockCtrl := gomock.NewController(t) thing := errortest.NewTestStruct() thing.M = make(map[string]string) thing.L = make([]string, 0) thing.S = make([]string, 0) thing.I = 3 err := thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, errors.New("test")) for i := 0; ; i++ { protocol := NewMockTProtocol(mockCtrl) if !prepareClientCallReply(protocol, i, err) { return } client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol)) _, retErr := client.TestStruct(defaultCtx, thing) mockCtrl.Finish() mockCtrl = gomock.NewController(t) err2, ok := retErr.(thrift.TProtocolException) if !ok { t.Fatal("Expected a TProtocolException") } if err2.TypeId() != thrift.INVALID_DATA { t.Fatal("Expected INVALID_DATA error") } } } // TestCase: Comprehensive call and reply workflow in the client. // Expecting TTProtocolErrors on fail. // Similar to TestClientReportTProtocolErrors, but using legacy client constructor. func TestClientReportTProtocolErrorsLegacy(t *testing.T) { mockCtrl := gomock.NewController(t) transport := thrift.NewTMemoryBuffer() thing := errortest.NewTestStruct() thing.M = make(map[string]string) thing.L = make([]string, 0) thing.S = make([]string, 0) thing.I = 3 err := thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, errors.New("test")) for i := 0; ; i++ { protocol := NewMockTProtocol(mockCtrl) if !prepareClientCallReply(protocol, i, err) { return } client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol) _, retErr := client.TestStruct(defaultCtx, thing) mockCtrl.Finish() mockCtrl = gomock.NewController(t) err2, ok := retErr.(thrift.TProtocolException) if !ok { t.Fatal("Expected a TProtocolException") } if err2.TypeId() != thrift.INVALID_DATA { t.Fatal("Expected INVALID_DATA error") } } } // TestCase: call and reply with exception workflow in the client. // Setup mock to fail at a certain position. Return true if position exists otherwise false. func prepareClientCallException(protocol *MockTProtocol, failAt int, failWith error) bool { var err error = nil // No need to test failure in this block, because it is covered in other test cases last := protocol.EXPECT().WriteMessageBegin(context.Background(), "testString", thrift.CALL, int32(1)) last = protocol.EXPECT().WriteStructBegin(context.Background(), "testString_args").After(last) last = protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.STRING), int16(1)).After(last) last = protocol.EXPECT().WriteString(context.Background(), "test").After(last) last = protocol.EXPECT().WriteFieldEnd(context.Background()).After(last) last = protocol.EXPECT().WriteFieldStop(context.Background()).After(last) last = protocol.EXPECT().WriteStructEnd(context.Background()).After(last) last = protocol.EXPECT().WriteMessageEnd(context.Background()).After(last) last = protocol.EXPECT().Flush(context.Background()).After(last) // Reading the exception, might fail. if failAt == 0 { err = failWith } last = protocol.EXPECT().ReadMessageBegin(context.Background()).Return("testString", thrift.EXCEPTION, int32(1), err).After(last) if failAt == 0 { return true } if failAt == 1 { err = failWith } last = protocol.EXPECT().ReadStructBegin(context.Background()).Return("TApplicationException", err).After(last) if failAt == 1 { return true } if failAt == 2 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("message", thrift.TType(thrift.STRING), int16(1), err).After(last) if failAt == 2 { return true } if failAt == 3 { err = failWith } last = protocol.EXPECT().ReadString(context.Background()).Return("test", err).After(last) if failAt == 3 { return true } if failAt == 4 { err = failWith } last = protocol.EXPECT().ReadFieldEnd(context.Background()).Return(err).After(last) if failAt == 4 { return true } if failAt == 5 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("type", thrift.TType(thrift.I32), int16(2), err).After(last) if failAt == 5 { return true } if failAt == 6 { err = failWith } last = protocol.EXPECT().ReadI32(context.Background()).Return(int32(thrift.PROTOCOL_ERROR), err).After(last) if failAt == 6 { return true } if failAt == 7 { err = failWith } last = protocol.EXPECT().ReadFieldEnd(context.Background()).Return(err).After(last) if failAt == 7 { return true } if failAt == 8 { err = failWith } last = protocol.EXPECT().ReadFieldBegin(context.Background()).Return("_", thrift.TType(thrift.STOP), int16(2), err).After(last) if failAt == 8 { return true } if failAt == 9 { err = failWith } last = protocol.EXPECT().ReadStructEnd(context.Background()).Return(err).After(last) if failAt == 9 { return true } if failAt == 10 { err = failWith } //lint:ignore SA4006 to keep it consistent with other checks above last = protocol.EXPECT().ReadMessageEnd(context.Background()).Return(err).After(last) //lint:ignore S1008 to keep it consistent with other checks above if failAt == 10 { return true } return false } // TestCase: call and reply with exception workflow in the client. func TestClientCallException(t *testing.T) { mockCtrl := gomock.NewController(t) err := thrift.NewTTransportException(thrift.TIMED_OUT, "test") for i := 0; ; i++ { protocol := NewMockTProtocol(mockCtrl) willComplete := !prepareClientCallException(protocol, i, err) client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol)) _, retErr := client.TestString(defaultCtx, "test") mockCtrl.Finish() mockCtrl = gomock.NewController(t) if !willComplete { err2, ok := retErr.(thrift.TTransportException) if !ok { t.Fatal("Expected a TTransportException") } if err2.TypeId() != thrift.TIMED_OUT { t.Fatal("Expected TIMED_OUT error") } } else { err2, ok := retErr.(thrift.TApplicationException) if !ok { t.Fatal("Expected a TApplicationException") } if err2.TypeId() != thrift.PROTOCOL_ERROR { t.Fatal("Expected PROTOCOL_ERROR error") } break } } } // TestCase: call and reply with exception workflow in the client. // Similar to TestClientCallException, but using legacy client constructor. func TestClientCallExceptionLegacy(t *testing.T) { mockCtrl := gomock.NewController(t) transport := thrift.NewTMemoryBuffer() err := thrift.NewTTransportException(thrift.TIMED_OUT, "test") for i := 0; ; i++ { protocol := NewMockTProtocol(mockCtrl) willComplete := !prepareClientCallException(protocol, i, err) client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol) _, retErr := client.TestString(defaultCtx, "test") mockCtrl.Finish() mockCtrl = gomock.NewController(t) if !willComplete { err2, ok := retErr.(thrift.TTransportException) if !ok { t.Fatal("Expected a TTransportException") } if err2.TypeId() != thrift.TIMED_OUT { t.Fatal("Expected TIMED_OUT error") } } else { err2, ok := retErr.(thrift.TApplicationException) if !ok { t.Fatal("Expected a TApplicationException") } if err2.TypeId() != thrift.PROTOCOL_ERROR { t.Fatal("Expected PROTOCOL_ERROR error") } break } } } // TestCase: Mismatching sequence id has been received in the client. func TestClientSeqIdMismatch(t *testing.T) { mockCtrl := gomock.NewController(t) protocol := NewMockTProtocol(mockCtrl) gomock.InOrder( protocol.EXPECT().WriteMessageBegin(context.Background(), "testString", thrift.CALL, int32(1)), protocol.EXPECT().WriteStructBegin(context.Background(), "testString_args"), protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.STRING), int16(1)), protocol.EXPECT().WriteString(context.Background(), "test"), protocol.EXPECT().WriteFieldEnd(context.Background()), protocol.EXPECT().WriteFieldStop(context.Background()), protocol.EXPECT().WriteStructEnd(context.Background()), protocol.EXPECT().WriteMessageEnd(context.Background()), protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin(context.Background()).Return("testString", thrift.REPLY, int32(2), nil), ) client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol)) _, err := client.TestString(defaultCtx, "test") mockCtrl.Finish() appErr, ok := err.(thrift.TApplicationException) if !ok { t.Fatal("Expected TApplicationException") } if appErr.TypeId() != thrift.BAD_SEQUENCE_ID { t.Fatal("Expected BAD_SEQUENCE_ID error") } } // TestCase: Mismatching sequence id has been received in the client. // Similar to TestClientSeqIdMismatch, but using legacy client constructor. func TestClientSeqIdMismatchLegeacy(t *testing.T) { mockCtrl := gomock.NewController(t) transport := thrift.NewTMemoryBuffer() protocol := NewMockTProtocol(mockCtrl) gomock.InOrder( protocol.EXPECT().WriteMessageBegin(context.Background(), "testString", thrift.CALL, int32(1)), protocol.EXPECT().WriteStructBegin(context.Background(), "testString_args"), protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.STRING), int16(1)), protocol.EXPECT().WriteString(context.Background(), "test"), protocol.EXPECT().WriteFieldEnd(context.Background()), protocol.EXPECT().WriteFieldStop(context.Background()), protocol.EXPECT().WriteStructEnd(context.Background()), protocol.EXPECT().WriteMessageEnd(context.Background()), protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin(context.Background()).Return("testString", thrift.REPLY, int32(2), nil), ) client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol) _, err := client.TestString(defaultCtx, "test") mockCtrl.Finish() appErr, ok := err.(thrift.TApplicationException) if !ok { t.Fatal("Expected TApplicationException") } if appErr.TypeId() != thrift.BAD_SEQUENCE_ID { t.Fatal("Expected BAD_SEQUENCE_ID error") } } // TestCase: Wrong method name has been received in the client. func TestClientWrongMethodName(t *testing.T) { mockCtrl := gomock.NewController(t) protocol := NewMockTProtocol(mockCtrl) gomock.InOrder( protocol.EXPECT().WriteMessageBegin(context.Background(), "testString", thrift.CALL, int32(1)), protocol.EXPECT().WriteStructBegin(context.Background(), "testString_args"), protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.STRING), int16(1)), protocol.EXPECT().WriteString(context.Background(), "test"), protocol.EXPECT().WriteFieldEnd(context.Background()), protocol.EXPECT().WriteFieldStop(context.Background()), protocol.EXPECT().WriteStructEnd(context.Background()), protocol.EXPECT().WriteMessageEnd(context.Background()), protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin(context.Background()).Return("unknown", thrift.REPLY, int32(1), nil), ) client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol)) _, err := client.TestString(defaultCtx, "test") mockCtrl.Finish() appErr, ok := err.(thrift.TApplicationException) if !ok { t.Fatal("Expected TApplicationException") } if appErr.TypeId() != thrift.WRONG_METHOD_NAME { t.Fatal("Expected WRONG_METHOD_NAME error") } } // TestCase: Wrong method name has been received in the client. // Similar to TestClientWrongMethodName, but using legacy client constructor. func TestClientWrongMethodNameLegacy(t *testing.T) { mockCtrl := gomock.NewController(t) transport := thrift.NewTMemoryBuffer() protocol := NewMockTProtocol(mockCtrl) gomock.InOrder( protocol.EXPECT().WriteMessageBegin(context.Background(), "testString", thrift.CALL, int32(1)), protocol.EXPECT().WriteStructBegin(context.Background(), "testString_args"), protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.STRING), int16(1)), protocol.EXPECT().WriteString(context.Background(), "test"), protocol.EXPECT().WriteFieldEnd(context.Background()), protocol.EXPECT().WriteFieldStop(context.Background()), protocol.EXPECT().WriteStructEnd(context.Background()), protocol.EXPECT().WriteMessageEnd(context.Background()), protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin(context.Background()).Return("unknown", thrift.REPLY, int32(1), nil), ) client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol) _, err := client.TestString(defaultCtx, "test") mockCtrl.Finish() appErr, ok := err.(thrift.TApplicationException) if !ok { t.Fatal("Expected TApplicationException") } if appErr.TypeId() != thrift.WRONG_METHOD_NAME { t.Fatal("Expected WRONG_METHOD_NAME error") } } // TestCase: Wrong message type has been received in the client. func TestClientWrongMessageType(t *testing.T) { mockCtrl := gomock.NewController(t) protocol := NewMockTProtocol(mockCtrl) gomock.InOrder( protocol.EXPECT().WriteMessageBegin(context.Background(), "testString", thrift.CALL, int32(1)), protocol.EXPECT().WriteStructBegin(context.Background(), "testString_args"), protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.STRING), int16(1)), protocol.EXPECT().WriteString(context.Background(), "test"), protocol.EXPECT().WriteFieldEnd(context.Background()), protocol.EXPECT().WriteFieldStop(context.Background()), protocol.EXPECT().WriteStructEnd(context.Background()), protocol.EXPECT().WriteMessageEnd(context.Background()), protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin(context.Background()).Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil), ) client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol)) _, err := client.TestString(defaultCtx, "test") mockCtrl.Finish() appErr, ok := err.(thrift.TApplicationException) if !ok { t.Fatal("Expected TApplicationException") } if appErr.TypeId() != thrift.INVALID_MESSAGE_TYPE_EXCEPTION { t.Fatal("Expected INVALID_MESSAGE_TYPE_EXCEPTION error") } } // TestCase: Wrong message type has been received in the client. // Similar to TestClientWrongMessageType, but using legacy client constructor. func TestClientWrongMessageTypeLegacy(t *testing.T) { mockCtrl := gomock.NewController(t) transport := thrift.NewTMemoryBuffer() protocol := NewMockTProtocol(mockCtrl) gomock.InOrder( protocol.EXPECT().WriteMessageBegin(context.Background(), "testString", thrift.CALL, int32(1)), protocol.EXPECT().WriteStructBegin(context.Background(), "testString_args"), protocol.EXPECT().WriteFieldBegin(context.Background(), "s", thrift.TType(thrift.STRING), int16(1)), protocol.EXPECT().WriteString(context.Background(), "test"), protocol.EXPECT().WriteFieldEnd(context.Background()), protocol.EXPECT().WriteFieldStop(context.Background()), protocol.EXPECT().WriteStructEnd(context.Background()), protocol.EXPECT().WriteMessageEnd(context.Background()), protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin(context.Background()).Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil), ) client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol) _, err := client.TestString(defaultCtx, "test") mockCtrl.Finish() appErr, ok := err.(thrift.TApplicationException) if !ok { t.Fatal("Expected TApplicationException") } if appErr.TypeId() != thrift.INVALID_MESSAGE_TYPE_EXCEPTION { t.Fatal("Expected INVALID_MESSAGE_TYPE_EXCEPTION error") } } thrift-0.23.0/lib/go/test/tests/const_optional_field_test.go0000664000175000017500000001136015165535636024456 0ustar00buildbuild00000000000000/* * 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 ( "testing" "github.com/apache/thrift/lib/go/test/gopath/src/constoptionalfielda" "github.com/apache/thrift/lib/go/test/gopath/src/constoptionalfieldb" ) func TestConstOptionalField(t *testing.T) { c := constoptionalfieldb.CONSTANTS[0] t.Run("foo", func(t *testing.T) { const expected = constoptionalfielda.Foo_One if *c.OptFoo != expected { t.Errorf("Expected %v, got %v", expected, *c.OptFoo) } if *c.AFoo != constoptionalfielda.TypedefAFoo(expected) { t.Errorf("Typedef a expected %v, got %v", expected, *c.AFoo) } if *c.BFoo != constoptionalfieldb.TypedefBFoo(expected) { t.Errorf("Typedef b expected %v, got %v", expected, *c.BFoo) } }) t.Run("bool", func(t *testing.T) { const expected = true if *c.OptBool != expected { t.Errorf("Expected %v, got %v", expected, *c.OptBool) } if *c.ABool != constoptionalfielda.TypedefABool(expected) { t.Errorf("Typedef a expected %v, got %v", expected, *c.ABool) } if *c.BBool != constoptionalfieldb.TypedefBBool(expected) { t.Errorf("Typedef b expected %v, got %v", expected, *c.BBool) } }) t.Run("i8", func(t *testing.T) { const expected = 8 if *c.OptI8 != expected { t.Errorf("Expected %v, got %v", expected, *c.OptI8) } if *c.AI8 != constoptionalfielda.TypedefAI8(expected) { t.Errorf("Typedef a expected %v, got %v", expected, *c.AI8) } if *c.BI8 != constoptionalfieldb.TypedefBI8(expected) { t.Errorf("Typedef b expected %v, got %v", expected, *c.BI8) } }) t.Run("i16", func(t *testing.T) { const expected = 16 if *c.OptI16 != expected { t.Errorf("Expected %v, got %v", expected, *c.OptI16) } if *c.AI16 != constoptionalfielda.TypedefAI16(expected) { t.Errorf("Typedef a expected %v, got %v", expected, *c.AI16) } if *c.BI16 != constoptionalfieldb.TypedefBI16(expected) { t.Errorf("Typedef b expected %v, got %v", expected, *c.BI16) } }) t.Run("i32", func(t *testing.T) { const expected = 32 if *c.OptI32 != expected { t.Errorf("Expected %v, got %v", expected, *c.OptI32) } if *c.AI32 != constoptionalfielda.TypedefAI32(expected) { t.Errorf("Typedef a expected %v, got %v", expected, *c.AI32) } if *c.BI32 != constoptionalfieldb.TypedefBI32(expected) { t.Errorf("Typedef b expected %v, got %v", expected, *c.BI32) } }) t.Run("i64", func(t *testing.T) { const expected = 64 if *c.OptI64 != expected { t.Errorf("Expected %v, got %v", expected, *c.OptI64) } if *c.AI64 != constoptionalfielda.TypedefAI64(expected) { t.Errorf("Typedef a expected %v, got %v", expected, *c.AI64) } if *c.BI64 != constoptionalfieldb.TypedefBI64(expected) { t.Errorf("Typedef b expected %v, got %v", expected, *c.BI64) } }) t.Run("double", func(t *testing.T) { // To avoid the annoyance of comparing float numbers, // we convert all floats to int in this test. const expected = 1234 if int(*c.OptDouble) != expected { t.Errorf("Expected %v, got %v", expected, *c.OptDouble) } if int(*c.ADouble) != expected { t.Errorf("Typedef a expected %v, got %v", expected, *c.ADouble) } if int(*c.BDouble) != expected { t.Errorf("Typedef b expected %v, got %v", expected, *c.BDouble) } }) t.Run("string", func(t *testing.T) { const expected = "string" if *c.OptString != expected { t.Errorf("Expected %q, got %q", expected, *c.OptString) } if *c.AString != constoptionalfielda.TypedefAString(expected) { t.Errorf("Typedef a expected %q, got %q", expected, *c.AString) } if *c.BString != constoptionalfieldb.TypedefBString(expected) { t.Errorf("Typedef b expected %q, got %q", expected, *c.BString) } }) t.Run("binary", func(t *testing.T) { const expected = "binary" if string(c.OptBinary) != expected { t.Errorf("Expected %q, got %q", expected, c.OptBinary) } if string(c.ABinary) != expected { t.Errorf("Typedef a expected %q, got %q", expected, c.ABinary) } if string(c.BBinary) != expected { t.Errorf("Typedef b expected %q, got %q", expected, c.BBinary) } }) } thrift-0.23.0/lib/go/test/tests/processor_middleware_test.go0000664000175000017500000000665115167543515024500 0ustar00buildbuild00000000000000/* * 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" "sync" "testing" "time" "github.com/apache/thrift/lib/go/test/gopath/src/processormiddlewaretest" "github.com/apache/thrift/lib/go/thrift" ) const errorMessage = "foo error" type serviceImpl struct { sleepTime time.Duration } func (s serviceImpl) Ping(_ context.Context) (err error) { time.Sleep(s.sleepTime) return &processormiddlewaretest.Error{ Foo: thrift.StringPtr(errorMessage), } } func middleware(t *testing.T) thrift.ProcessorMiddleware { return func(name string, next thrift.TProcessorFunction) thrift.TProcessorFunction { return thrift.WrappedTProcessorFunction{ Wrapped: func(ctx context.Context, seqId int32, in, out thrift.TProtocol) (_ bool, err thrift.TException) { defer func() { checkError(t, err) }() return next.Process(ctx, seqId, in, out) }, } } } func checkError(tb testing.TB, err error) { tb.Helper() var idlErr *processormiddlewaretest.Error if !errors.As(err, &idlErr) { tb.Errorf("expected error to be of type *processormiddlewaretest.Error, actual %T, %#v", err, err) return } if actual := idlErr.GetFoo(); actual != errorMessage { tb.Errorf("expected error message to be %q, actual %q", errorMessage, actual) } } func TestProcessorMiddleware(t *testing.T) { const ( sleepTime = 10 * time.Millisecond timeout = sleepTime / 5 ) 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) } server := thrift.NewTSimpleServer4( thrift.WrapProcessor(processor, middleware(t)), serverTransport, thrift.NewTHeaderTransportFactoryConf(nil, nil), thrift.NewTHeaderProtocolFactoryConf(nil), ) t.Cleanup(func() { server.Stop() }) var wg sync.WaitGroup wg.Go(func() { server.Serve() }) time.Sleep(10 * time.Millisecond) cfg := &thrift.TConfiguration{ ConnectTimeout: timeout, SocketTimeout: timeout, } transport := thrift.NewTSocketFromAddrConf(serverTransport.Addr(), cfg) if err := transport.Open(); err != nil { t.Fatalf("Could not open client transport: %v", err) } defer transport.Close() protocol := thrift.NewTHeaderProtocolConf(transport, nil) client := processormiddlewaretest.NewServiceClient(thrift.NewTStandardClient(protocol, protocol)) 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) }) } } thrift-0.23.0/lib/go/test/tests/enum_values_test.go0000664000175000017500000000254715165535636022612 0ustar00buildbuild00000000000000/* * 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) } } } thrift-0.23.0/lib/go/test/tests/json_protocol_deserializer_test.go0000664000175000017500000000374215165535636025721 0ustar00buildbuild00000000000000/* * 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" "testing" "testing/quick" "github.com/apache/thrift/lib/go/test/gopath/src/thrifttest" "github.com/apache/thrift/lib/go/thrift" ) func TestDeserializerPoolJSONProtocol(t *testing.T) { ctx := context.Background() serializerPool := thrift.NewTSerializerPoolSizeFactory(1024, thrift.NewTJSONProtocolFactory()) msg := &thrifttest.Bonk{ Message: "foo", Type: 42, } valid, err := serializerPool.WriteString(ctx, msg) if err != nil { t.Fatal(err) } invalid := valid[:len(valid)-2] deserializerPool := thrift.NewTDeserializerPoolSizeFactory(1024, thrift.NewTJSONProtocolFactory()) msg = new(thrifttest.Bonk) if err := deserializerPool.ReadString(ctx, msg, invalid); err == nil { t.Fatalf("Deserializing %q did not fail", invalid) } f := func() bool { msg := new(thrifttest.Bonk) if err := deserializerPool.ReadString(ctx, msg, valid); err != nil { t.Errorf("Deserializing string %q failed with %v", valid, err) } if err := deserializerPool.Read(ctx, msg, []byte(valid)); err != nil { t.Errorf("Deserializing bytes %q failed with %v", valid, err) } return !t.Failed() } if err := quick.Check(f, nil); err != nil { t.Error(err) } } thrift-0.23.0/lib/go/test/tests/protocol_mock.go0000664000175000017500000006235415165535636022104 0ustar00buildbuild00000000000000// Code generated by MockGen. DO NOT EDIT. // Source: github.com/apache/thrift/lib/go/thrift (interfaces: TProtocol) // Package tests is a generated GoMock package. package tests import ( context "context" reflect "reflect" thrift "github.com/apache/thrift/lib/go/thrift" gomock "github.com/golang/mock/gomock" ) // MockTProtocol is a mock of TProtocol interface. type MockTProtocol struct { ctrl *gomock.Controller recorder *MockTProtocolMockRecorder } // MockTProtocolMockRecorder is the mock recorder for MockTProtocol. type MockTProtocolMockRecorder struct { mock *MockTProtocol } // NewMockTProtocol creates a new mock instance. func NewMockTProtocol(ctrl *gomock.Controller) *MockTProtocol { mock := &MockTProtocol{ctrl: ctrl} mock.recorder = &MockTProtocolMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. func (m *MockTProtocol) EXPECT() *MockTProtocolMockRecorder { return m.recorder } // Flush mocks base method. func (m *MockTProtocol) Flush(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Flush", arg0) ret0, _ := ret[0].(error) return ret0 } // Flush indicates an expected call of Flush. func (mr *MockTProtocolMockRecorder) Flush(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Flush", reflect.TypeOf((*MockTProtocol)(nil).Flush), arg0) } // ReadBinary mocks base method. func (m *MockTProtocol) ReadBinary(arg0 context.Context) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadBinary", arg0) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadBinary indicates an expected call of ReadBinary. func (mr *MockTProtocolMockRecorder) ReadBinary(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadBinary", reflect.TypeOf((*MockTProtocol)(nil).ReadBinary), arg0) } // ReadBool mocks base method. func (m *MockTProtocol) ReadBool(arg0 context.Context) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadBool", arg0) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadBool indicates an expected call of ReadBool. func (mr *MockTProtocolMockRecorder) ReadBool(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadBool", reflect.TypeOf((*MockTProtocol)(nil).ReadBool), arg0) } // ReadByte mocks base method. func (m *MockTProtocol) ReadByte(arg0 context.Context) (int8, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadByte", arg0) ret0, _ := ret[0].(int8) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadByte indicates an expected call of ReadByte. func (mr *MockTProtocolMockRecorder) ReadByte(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadByte", reflect.TypeOf((*MockTProtocol)(nil).ReadByte), arg0) } // ReadDouble mocks base method. func (m *MockTProtocol) ReadDouble(arg0 context.Context) (float64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadDouble", arg0) ret0, _ := ret[0].(float64) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadDouble indicates an expected call of ReadDouble. func (mr *MockTProtocolMockRecorder) ReadDouble(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDouble", reflect.TypeOf((*MockTProtocol)(nil).ReadDouble), arg0) } // ReadFieldBegin mocks base method. func (m *MockTProtocol) ReadFieldBegin(arg0 context.Context) (string, thrift.TType, int16, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadFieldBegin", arg0) ret0, _ := ret[0].(string) ret1, _ := ret[1].(thrift.TType) ret2, _ := ret[2].(int16) ret3, _ := ret[3].(error) return ret0, ret1, ret2, ret3 } // ReadFieldBegin indicates an expected call of ReadFieldBegin. func (mr *MockTProtocolMockRecorder) ReadFieldBegin(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFieldBegin", reflect.TypeOf((*MockTProtocol)(nil).ReadFieldBegin), arg0) } // ReadFieldEnd mocks base method. func (m *MockTProtocol) ReadFieldEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadFieldEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // ReadFieldEnd indicates an expected call of ReadFieldEnd. func (mr *MockTProtocolMockRecorder) ReadFieldEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadFieldEnd", reflect.TypeOf((*MockTProtocol)(nil).ReadFieldEnd), arg0) } // ReadI16 mocks base method. func (m *MockTProtocol) ReadI16(arg0 context.Context) (int16, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadI16", arg0) ret0, _ := ret[0].(int16) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadI16 indicates an expected call of ReadI16. func (mr *MockTProtocolMockRecorder) ReadI16(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadI16", reflect.TypeOf((*MockTProtocol)(nil).ReadI16), arg0) } // ReadI32 mocks base method. func (m *MockTProtocol) ReadI32(arg0 context.Context) (int32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadI32", arg0) ret0, _ := ret[0].(int32) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadI32 indicates an expected call of ReadI32. func (mr *MockTProtocolMockRecorder) ReadI32(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadI32", reflect.TypeOf((*MockTProtocol)(nil).ReadI32), arg0) } // ReadI64 mocks base method. func (m *MockTProtocol) ReadI64(arg0 context.Context) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadI64", arg0) ret0, _ := ret[0].(int64) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadI64 indicates an expected call of ReadI64. func (mr *MockTProtocolMockRecorder) ReadI64(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadI64", reflect.TypeOf((*MockTProtocol)(nil).ReadI64), arg0) } // ReadListBegin mocks base method. func (m *MockTProtocol) ReadListBegin(arg0 context.Context) (thrift.TType, int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadListBegin", arg0) ret0, _ := ret[0].(thrift.TType) ret1, _ := ret[1].(int) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } // ReadListBegin indicates an expected call of ReadListBegin. func (mr *MockTProtocolMockRecorder) ReadListBegin(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadListBegin", reflect.TypeOf((*MockTProtocol)(nil).ReadListBegin), arg0) } // ReadListEnd mocks base method. func (m *MockTProtocol) ReadListEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadListEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // ReadListEnd indicates an expected call of ReadListEnd. func (mr *MockTProtocolMockRecorder) ReadListEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadListEnd", reflect.TypeOf((*MockTProtocol)(nil).ReadListEnd), arg0) } // ReadMapBegin mocks base method. func (m *MockTProtocol) ReadMapBegin(arg0 context.Context) (thrift.TType, thrift.TType, int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadMapBegin", arg0) ret0, _ := ret[0].(thrift.TType) ret1, _ := ret[1].(thrift.TType) ret2, _ := ret[2].(int) ret3, _ := ret[3].(error) return ret0, ret1, ret2, ret3 } // ReadMapBegin indicates an expected call of ReadMapBegin. func (mr *MockTProtocolMockRecorder) ReadMapBegin(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadMapBegin", reflect.TypeOf((*MockTProtocol)(nil).ReadMapBegin), arg0) } // ReadMapEnd mocks base method. func (m *MockTProtocol) ReadMapEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadMapEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // ReadMapEnd indicates an expected call of ReadMapEnd. func (mr *MockTProtocolMockRecorder) ReadMapEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadMapEnd", reflect.TypeOf((*MockTProtocol)(nil).ReadMapEnd), arg0) } // ReadMessageBegin mocks base method. func (m *MockTProtocol) ReadMessageBegin(arg0 context.Context) (string, thrift.TMessageType, int32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadMessageBegin", arg0) ret0, _ := ret[0].(string) ret1, _ := ret[1].(thrift.TMessageType) ret2, _ := ret[2].(int32) ret3, _ := ret[3].(error) return ret0, ret1, ret2, ret3 } // ReadMessageBegin indicates an expected call of ReadMessageBegin. func (mr *MockTProtocolMockRecorder) ReadMessageBegin(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadMessageBegin", reflect.TypeOf((*MockTProtocol)(nil).ReadMessageBegin), arg0) } // ReadMessageEnd mocks base method. func (m *MockTProtocol) ReadMessageEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadMessageEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // ReadMessageEnd indicates an expected call of ReadMessageEnd. func (mr *MockTProtocolMockRecorder) ReadMessageEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadMessageEnd", reflect.TypeOf((*MockTProtocol)(nil).ReadMessageEnd), arg0) } // ReadSetBegin mocks base method. func (m *MockTProtocol) ReadSetBegin(arg0 context.Context) (thrift.TType, int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadSetBegin", arg0) ret0, _ := ret[0].(thrift.TType) ret1, _ := ret[1].(int) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } // ReadSetBegin indicates an expected call of ReadSetBegin. func (mr *MockTProtocolMockRecorder) ReadSetBegin(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadSetBegin", reflect.TypeOf((*MockTProtocol)(nil).ReadSetBegin), arg0) } // ReadSetEnd mocks base method. func (m *MockTProtocol) ReadSetEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadSetEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // ReadSetEnd indicates an expected call of ReadSetEnd. func (mr *MockTProtocolMockRecorder) ReadSetEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadSetEnd", reflect.TypeOf((*MockTProtocol)(nil).ReadSetEnd), arg0) } // ReadString mocks base method. func (m *MockTProtocol) ReadString(arg0 context.Context) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadString", arg0) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadString indicates an expected call of ReadString. func (mr *MockTProtocolMockRecorder) ReadString(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadString", reflect.TypeOf((*MockTProtocol)(nil).ReadString), arg0) } // ReadStructBegin mocks base method. func (m *MockTProtocol) ReadStructBegin(arg0 context.Context) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadStructBegin", arg0) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadStructBegin indicates an expected call of ReadStructBegin. func (mr *MockTProtocolMockRecorder) ReadStructBegin(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadStructBegin", reflect.TypeOf((*MockTProtocol)(nil).ReadStructBegin), arg0) } // ReadStructEnd mocks base method. func (m *MockTProtocol) ReadStructEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadStructEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // ReadStructEnd indicates an expected call of ReadStructEnd. func (mr *MockTProtocolMockRecorder) ReadStructEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadStructEnd", reflect.TypeOf((*MockTProtocol)(nil).ReadStructEnd), arg0) } // ReadUUID mocks base method. func (m *MockTProtocol) ReadUUID(arg0 context.Context) (thrift.Tuuid, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ReadUUID", arg0) ret0, _ := ret[0].(thrift.Tuuid) ret1, _ := ret[1].(error) return ret0, ret1 } // ReadUUID indicates an expected call of ReadUUID. func (mr *MockTProtocolMockRecorder) ReadUUID(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadUUID", reflect.TypeOf((*MockTProtocol)(nil).ReadUUID), arg0) } // Skip mocks base method. func (m *MockTProtocol) Skip(arg0 context.Context, arg1 thrift.TType) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Skip", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // Skip indicates an expected call of Skip. func (mr *MockTProtocolMockRecorder) Skip(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Skip", reflect.TypeOf((*MockTProtocol)(nil).Skip), arg0, arg1) } // Transport mocks base method. func (m *MockTProtocol) Transport() thrift.TTransport { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Transport") ret0, _ := ret[0].(thrift.TTransport) return ret0 } // Transport indicates an expected call of Transport. func (mr *MockTProtocolMockRecorder) Transport() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transport", reflect.TypeOf((*MockTProtocol)(nil).Transport)) } // WriteBinary mocks base method. func (m *MockTProtocol) WriteBinary(arg0 context.Context, arg1 []byte) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteBinary", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteBinary indicates an expected call of WriteBinary. func (mr *MockTProtocolMockRecorder) WriteBinary(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteBinary", reflect.TypeOf((*MockTProtocol)(nil).WriteBinary), arg0, arg1) } // WriteBool mocks base method. func (m *MockTProtocol) WriteBool(arg0 context.Context, arg1 bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteBool", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteBool indicates an expected call of WriteBool. func (mr *MockTProtocolMockRecorder) WriteBool(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteBool", reflect.TypeOf((*MockTProtocol)(nil).WriteBool), arg0, arg1) } // WriteByte mocks base method. func (m *MockTProtocol) WriteByte(arg0 context.Context, arg1 int8) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteByte", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteByte indicates an expected call of WriteByte. func (mr *MockTProtocolMockRecorder) WriteByte(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteByte", reflect.TypeOf((*MockTProtocol)(nil).WriteByte), arg0, arg1) } // WriteDouble mocks base method. func (m *MockTProtocol) WriteDouble(arg0 context.Context, arg1 float64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteDouble", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteDouble indicates an expected call of WriteDouble. func (mr *MockTProtocolMockRecorder) WriteDouble(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteDouble", reflect.TypeOf((*MockTProtocol)(nil).WriteDouble), arg0, arg1) } // WriteFieldBegin mocks base method. func (m *MockTProtocol) WriteFieldBegin(arg0 context.Context, arg1 string, arg2 thrift.TType, arg3 int16) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteFieldBegin", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // WriteFieldBegin indicates an expected call of WriteFieldBegin. func (mr *MockTProtocolMockRecorder) WriteFieldBegin(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteFieldBegin", reflect.TypeOf((*MockTProtocol)(nil).WriteFieldBegin), arg0, arg1, arg2, arg3) } // WriteFieldEnd mocks base method. func (m *MockTProtocol) WriteFieldEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteFieldEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // WriteFieldEnd indicates an expected call of WriteFieldEnd. func (mr *MockTProtocolMockRecorder) WriteFieldEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteFieldEnd", reflect.TypeOf((*MockTProtocol)(nil).WriteFieldEnd), arg0) } // WriteFieldStop mocks base method. func (m *MockTProtocol) WriteFieldStop(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteFieldStop", arg0) ret0, _ := ret[0].(error) return ret0 } // WriteFieldStop indicates an expected call of WriteFieldStop. func (mr *MockTProtocolMockRecorder) WriteFieldStop(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteFieldStop", reflect.TypeOf((*MockTProtocol)(nil).WriteFieldStop), arg0) } // WriteI16 mocks base method. func (m *MockTProtocol) WriteI16(arg0 context.Context, arg1 int16) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteI16", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteI16 indicates an expected call of WriteI16. func (mr *MockTProtocolMockRecorder) WriteI16(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteI16", reflect.TypeOf((*MockTProtocol)(nil).WriteI16), arg0, arg1) } // WriteI32 mocks base method. func (m *MockTProtocol) WriteI32(arg0 context.Context, arg1 int32) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteI32", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteI32 indicates an expected call of WriteI32. func (mr *MockTProtocolMockRecorder) WriteI32(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteI32", reflect.TypeOf((*MockTProtocol)(nil).WriteI32), arg0, arg1) } // WriteI64 mocks base method. func (m *MockTProtocol) WriteI64(arg0 context.Context, arg1 int64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteI64", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteI64 indicates an expected call of WriteI64. func (mr *MockTProtocolMockRecorder) WriteI64(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteI64", reflect.TypeOf((*MockTProtocol)(nil).WriteI64), arg0, arg1) } // WriteListBegin mocks base method. func (m *MockTProtocol) WriteListBegin(arg0 context.Context, arg1 thrift.TType, arg2 int) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteListBegin", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // WriteListBegin indicates an expected call of WriteListBegin. func (mr *MockTProtocolMockRecorder) WriteListBegin(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteListBegin", reflect.TypeOf((*MockTProtocol)(nil).WriteListBegin), arg0, arg1, arg2) } // WriteListEnd mocks base method. func (m *MockTProtocol) WriteListEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteListEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // WriteListEnd indicates an expected call of WriteListEnd. func (mr *MockTProtocolMockRecorder) WriteListEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteListEnd", reflect.TypeOf((*MockTProtocol)(nil).WriteListEnd), arg0) } // WriteMapBegin mocks base method. func (m *MockTProtocol) WriteMapBegin(arg0 context.Context, arg1, arg2 thrift.TType, arg3 int) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteMapBegin", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // WriteMapBegin indicates an expected call of WriteMapBegin. func (mr *MockTProtocolMockRecorder) WriteMapBegin(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteMapBegin", reflect.TypeOf((*MockTProtocol)(nil).WriteMapBegin), arg0, arg1, arg2, arg3) } // WriteMapEnd mocks base method. func (m *MockTProtocol) WriteMapEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteMapEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // WriteMapEnd indicates an expected call of WriteMapEnd. func (mr *MockTProtocolMockRecorder) WriteMapEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteMapEnd", reflect.TypeOf((*MockTProtocol)(nil).WriteMapEnd), arg0) } // WriteMessageBegin mocks base method. func (m *MockTProtocol) WriteMessageBegin(arg0 context.Context, arg1 string, arg2 thrift.TMessageType, arg3 int32) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteMessageBegin", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // WriteMessageBegin indicates an expected call of WriteMessageBegin. func (mr *MockTProtocolMockRecorder) WriteMessageBegin(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteMessageBegin", reflect.TypeOf((*MockTProtocol)(nil).WriteMessageBegin), arg0, arg1, arg2, arg3) } // WriteMessageEnd mocks base method. func (m *MockTProtocol) WriteMessageEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteMessageEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // WriteMessageEnd indicates an expected call of WriteMessageEnd. func (mr *MockTProtocolMockRecorder) WriteMessageEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteMessageEnd", reflect.TypeOf((*MockTProtocol)(nil).WriteMessageEnd), arg0) } // WriteSetBegin mocks base method. func (m *MockTProtocol) WriteSetBegin(arg0 context.Context, arg1 thrift.TType, arg2 int) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteSetBegin", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // WriteSetBegin indicates an expected call of WriteSetBegin. func (mr *MockTProtocolMockRecorder) WriteSetBegin(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteSetBegin", reflect.TypeOf((*MockTProtocol)(nil).WriteSetBegin), arg0, arg1, arg2) } // WriteSetEnd mocks base method. func (m *MockTProtocol) WriteSetEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteSetEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // WriteSetEnd indicates an expected call of WriteSetEnd. func (mr *MockTProtocolMockRecorder) WriteSetEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteSetEnd", reflect.TypeOf((*MockTProtocol)(nil).WriteSetEnd), arg0) } // WriteString mocks base method. func (m *MockTProtocol) WriteString(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteString", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteString indicates an expected call of WriteString. func (mr *MockTProtocolMockRecorder) WriteString(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteString", reflect.TypeOf((*MockTProtocol)(nil).WriteString), arg0, arg1) } // WriteStructBegin mocks base method. func (m *MockTProtocol) WriteStructBegin(arg0 context.Context, arg1 string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteStructBegin", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteStructBegin indicates an expected call of WriteStructBegin. func (mr *MockTProtocolMockRecorder) WriteStructBegin(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteStructBegin", reflect.TypeOf((*MockTProtocol)(nil).WriteStructBegin), arg0, arg1) } // WriteStructEnd mocks base method. func (m *MockTProtocol) WriteStructEnd(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteStructEnd", arg0) ret0, _ := ret[0].(error) return ret0 } // WriteStructEnd indicates an expected call of WriteStructEnd. func (mr *MockTProtocolMockRecorder) WriteStructEnd(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteStructEnd", reflect.TypeOf((*MockTProtocol)(nil).WriteStructEnd), arg0) } // WriteUUID mocks base method. func (m *MockTProtocol) WriteUUID(arg0 context.Context, arg1 thrift.Tuuid) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteUUID", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // WriteUUID indicates an expected call of WriteUUID. func (mr *MockTProtocolMockRecorder) WriteUUID(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteUUID", reflect.TypeOf((*MockTProtocol)(nil).WriteUUID), arg0, arg1) } thrift-0.23.0/lib/go/test/tests/equals_test.go0000664000175000017500000003440515165535636021557 0ustar00buildbuild00000000000000/* * 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 ( "strconv" "testing" "github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/test/gopath/src/equalstest" ) var ( equalstestUUID1 = thrift.Must(thrift.ParseTuuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) equalstestUUID2 = thrift.Must(thrift.ParseTuuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) ) func TestEquals(t *testing.T) { // test basic field basicTgt, basicSrc := genBasicFoo(), genBasicFoo() if !basicTgt.Equals(basicSrc) { t.Error("BasicEqualsFoo.Equals() test failed") } basicSrc.EnumFoo = equalstest.EnumFoo_e2 if basicTgt.Equals(basicSrc) { t.Error("BasicEqualsFoo.Equals() test failed") } basicSrc = genBasicFoo() basicSrc.OptBoolFoo = nil if basicTgt.Equals(basicSrc) || basicSrc.Equals(basicTgt) { t.Error("BasicEqualsFoo.Equals() test failed") } if !(&equalstest.BasicEqualsFoo{}).Equals(&equalstest.BasicEqualsFoo{}) { t.Error("BasicEqualsFoo.Equals() test failed") } // test struct field structTgt, structSrc := genStructFoo(), genStructFoo() if !structTgt.Equals(structSrc) { t.Error("StructEqualsFoo.Equals() test failed") } structSrc.OptStructFoo.EnumFoo = equalstest.EnumFoo_e2 if structTgt.Equals(structSrc) { t.Error("StructEqualsFoo.Equals() test failed") } structSrc = genStructFoo() structSrc.OptStructFoo = nil if structTgt.Equals(structSrc) || structSrc.Equals(structTgt) { t.Error("StructEqualsFoo.Equals() test failed") } if !(&equalstest.StructEqualsFoo{}).Equals(&equalstest.StructEqualsFoo{}) { t.Error("StructEqualsFoo.Equals() test failed") } // test list field listTgt, listSrc := genListFoo(), genListFoo() if !listTgt.Equals(listSrc) { t.Error("ListEqualsFoo.Equals() test failed") } listSrc.OptI64StringMapListFoo[0][1] = "0" if listTgt.Equals(listSrc) { t.Error("ListEqualsFoo.Equals() test failed") } listSrc = genListFoo() listSrc.OptI64StringMapListFoo = nil if listTgt.Equals(listSrc) || listSrc.Equals(listTgt) { t.Error("ListEqualsFoo.Equals() test failed") } if !(&equalstest.ListEqualsFoo{}).Equals(&equalstest.ListEqualsFoo{}) { t.Error("ListEqualsFoo.Equals() test failed") } // test set field setTgt, setSrc := genSetFoo(), genSetFoo() if !setTgt.Equals(setSrc) { t.Error("SetEqualsFoo.Equals() test failed") } setSrc.OptI64StringMapSetFoo[0][1] = "0" if setTgt.Equals(setSrc) { t.Error("SetEqualsFoo.Equals() test failed") } setSrc = genSetFoo() setSrc.OptI64StringMapSetFoo = nil if setTgt.Equals(setSrc) || setSrc.Equals(setTgt) { t.Error("SetEqualsFoo.Equals() test failed") } if !(&equalstest.SetEqualsFoo{}).Equals(&equalstest.SetEqualsFoo{}) { t.Error("SetEqualsFoo.Equals() test failed") } // test map field mapTgt, mapSrc := genMapFoo(), genMapFoo() if !mapTgt.Equals(mapSrc) { t.Error("MapEqualsFoo.Equals() test failed") } mapSrc.OptI64I64StringMapMapFoo[1][1] = "0" if mapTgt.Equals(mapSrc) { t.Error("MapEqualsFoo.Equals() test failed") } mapSrc = genMapFoo() mapSrc.OptI64I64StringMapMapFoo = nil if mapTgt.Equals(mapSrc) || mapSrc.Equals(mapTgt) { t.Error("MapEqualsFoo.Equals() test failed") } if !(&equalstest.MapEqualsFoo{}).Equals(&equalstest.MapEqualsFoo{}) { t.Error("MapEqualsFoo.Equals() test failed") } } func genBasicFoo() *equalstest.BasicEqualsFoo { return &equalstest.BasicEqualsFoo{ BoolFoo: true, OptBoolFoo: thrift.BoolPtr(true), I8Foo: 1, OptI8Foo: thrift.Int8Ptr(1), I16Foo: 2, OptI16Foo: thrift.Int16Ptr(2), I32Foo: 3, OptI32Foo: thrift.Int32Ptr(3), I64Foo: 4, OptI64Foo: thrift.Int64Ptr(4), DoubleFoo: 5, OptDoubleFoo: thrift.Float64Ptr(6), StrFoo: "6", OptStrFoo: thrift.StringPtr("6"), BinFoo: []byte("7"), OptBinFoo: []byte("7"), EnumFoo: equalstest.EnumFoo_e1, OptEnumFoo: equalstest.EnumFooPtr(equalstest.EnumFoo_e1), MyByteFoo: equalstest.Mybyte(8), OptMyByteFoo: equalstest.MybytePtr(8), MyStrFoo: equalstest.Mystr("9"), OptMyStrFoo: equalstest.MystrPtr(equalstest.Mystr("9")), MyBinFoo: equalstest.Mybin("10"), OptMyBinFoo: equalstest.Mybin("10"), UUIDFoo: equalstestUUID1, OptUUIDFoo: thrift.TuuidPtr(equalstestUUID1), MyUUIDFoo: equalstest.Myuuid(equalstestUUID1), OptMyUUIDFoo: equalstest.MyuuidPtr(equalstest.Myuuid(equalstestUUID1)), } } func genStructFoo() *equalstest.StructEqualsFoo { return &equalstest.StructEqualsFoo{ StructFoo: genBasicFoo(), OptStructFoo: genBasicFoo(), } } func genListFoo() *equalstest.ListEqualsFoo { return &equalstest.ListEqualsFoo{ I64ListFoo: genInt64Slice(6), OptI64ListFoo: genInt64Slice(6), StrListFoo: genStringSlice(6), OptStrListFoo: genStringSlice(6), BinListFoo: genBytesSlice(6), OptBinListFoo: genBytesSlice(6), StructListFoo: []*equalstest.BasicEqualsFoo{genBasicFoo(), {}}, OptStructListFoo: []*equalstest.BasicEqualsFoo{genBasicFoo(), {}}, I64ListListFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, OptI64ListListFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, I64SetListFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, OptI64SetListFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, I64StringMapListFoo: []map[int64]string{{6: "6"}, {5: "5"}, {4: "4"}, {3: "3"}, {2: "2"}, {1: "1"}}, OptI64StringMapListFoo: []map[int64]string{{6: "6"}, {5: "5"}, {4: "4"}, {3: "3"}, {2: "2"}, {1: "1"}}, MyByteListFoo: []equalstest.Mybyte{6, 5, 4, 3, 2, 1}, OptMyByteListFoo: []equalstest.Mybyte{6, 5, 4, 3, 2, 1}, MyStrListFoo: []equalstest.Mystr{equalstest.Mystr("6"), equalstest.Mystr("5"), equalstest.Mystr("4"), equalstest.Mystr("3"), equalstest.Mystr("2"), equalstest.Mystr("1")}, OptMyStrListFoo: []equalstest.Mystr{equalstest.Mystr("6"), equalstest.Mystr("5"), equalstest.Mystr("4"), equalstest.Mystr("3"), equalstest.Mystr("2"), equalstest.Mystr("1")}, MyBinListFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")}, OptMyBinListFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")}, UUIDListFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2}, OptUUIDListFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2}, MyUUIDListFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)}, OptMyUUIDListFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)}, } } func genSetFoo() *equalstest.SetEqualsFoo { return &equalstest.SetEqualsFoo{ I64SetFoo: genInt64Slice(6), OptI64SetFoo: genInt64Slice(6), StrSetFoo: genStringSlice(6), OptStrSetFoo: genStringSlice(6), BinSetFoo: genBytesSlice(6), OptBinSetFoo: genBytesSlice(6), StructSetFoo: []*equalstest.BasicEqualsFoo{genBasicFoo(), {}}, OptStructSetFoo: []*equalstest.BasicEqualsFoo{genBasicFoo(), {}}, I64ListSetFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, OptI64ListSetFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, I64SetSetFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, OptI64SetSetFoo: [][]int64{genInt64Slice(6), genInt64Slice(5), genInt64Slice(4), genInt64Slice(3), genInt64Slice(2), genInt64Slice(1)}, I64StringMapSetFoo: []map[int64]string{{6: "6"}, {5: "5"}, {4: "4"}, {3: "3"}, {2: "2"}, {1: "1"}}, OptI64StringMapSetFoo: []map[int64]string{{6: "6"}, {5: "5"}, {4: "4"}, {3: "3"}, {2: "2"}, {1: "1"}}, MyByteSetFoo: []equalstest.Mybyte{6, 5, 4, 3, 2, 1}, OptMyByteSetFoo: []equalstest.Mybyte{6, 5, 4, 3, 2, 1}, MyStrSetFoo: []equalstest.Mystr{equalstest.Mystr("6"), equalstest.Mystr("5"), equalstest.Mystr("4"), equalstest.Mystr("3"), equalstest.Mystr("2"), equalstest.Mystr("1")}, OptMyStrSetFoo: []equalstest.Mystr{equalstest.Mystr("6"), equalstest.Mystr("5"), equalstest.Mystr("4"), equalstest.Mystr("3"), equalstest.Mystr("2"), equalstest.Mystr("1")}, MyBinSetFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")}, OptMyBinSetFoo: []equalstest.Mybin{equalstest.Mybin("6"), equalstest.Mybin("5"), equalstest.Mybin("4"), equalstest.Mybin("3"), equalstest.Mybin("2"), equalstest.Mybin("1")}, UUIDSetFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2}, OptUUIDSetFoo: []thrift.Tuuid{equalstestUUID1, equalstestUUID2}, MyUUIDSetFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)}, OptMyUUIDSetFoo: []equalstest.Myuuid{equalstest.Myuuid(equalstestUUID1), equalstest.Myuuid(equalstestUUID2)}, } } var ( structMapKey0 = genBasicFoo() structMapKey1 = &equalstest.BasicEqualsFoo{} ) func genMapFoo() *equalstest.MapEqualsFoo { return &equalstest.MapEqualsFoo{ I64StrMapFoo: genInt64StringMap(6), OptI64StrMapFoo: genInt64StringMap(6), StrI64MapFoo: map[string]int64{"6": 6, "5": 5, "4": 4, "3": 3, "2": 2, "1": 1}, OptStrI64MapFoo: map[string]int64{"6": 6, "5": 5, "4": 4, "3": 3, "2": 2, "1": 1}, StructBinMapFoo: map[*equalstest.BasicEqualsFoo][]byte{structMapKey0: []byte("0"), structMapKey1: []byte("1")}, OptStructBinMapFoo: map[*equalstest.BasicEqualsFoo][]byte{structMapKey0: []byte("0"), structMapKey1: []byte("1")}, BinStructMapFoo: map[string]*equalstest.BasicEqualsFoo{"1": genBasicFoo(), "0": {}}, OptBinStructMapFoo: map[string]*equalstest.BasicEqualsFoo{"1": genBasicFoo(), "0": {}}, I64I64ListMapFoo: map[int64][]int64{6: genInt64Slice(6), 5: genInt64Slice(5), 4: genInt64Slice(4), 3: genInt64Slice(3), 2: genInt64Slice(2), 1: genInt64Slice(1)}, OptI64I64ListMapFoo: map[int64][]int64{6: genInt64Slice(6), 5: genInt64Slice(5), 4: genInt64Slice(4), 3: genInt64Slice(3), 2: genInt64Slice(2), 1: genInt64Slice(1)}, I64I64SetMapFoo: map[int64][]int64{6: genInt64Slice(6), 5: genInt64Slice(5), 4: genInt64Slice(4), 3: genInt64Slice(3), 2: genInt64Slice(2), 1: genInt64Slice(1)}, OptI64I64SetMapFoo: map[int64][]int64{6: genInt64Slice(6), 5: genInt64Slice(5), 4: genInt64Slice(4), 3: genInt64Slice(3), 2: genInt64Slice(2), 1: genInt64Slice(1)}, I64I64StringMapMapFoo: map[int64]map[int64]string{6: genInt64StringMap(6), 5: genInt64StringMap(5), 4: genInt64StringMap(4), 3: genInt64StringMap(3), 2: genInt64StringMap(2), 1: genInt64StringMap(1)}, OptI64I64StringMapMapFoo: map[int64]map[int64]string{6: genInt64StringMap(6), 5: genInt64StringMap(5), 4: genInt64StringMap(4), 3: genInt64StringMap(3), 2: genInt64StringMap(2), 1: genInt64StringMap(1)}, MyStrMyBinMapFoo: map[equalstest.Mystr]equalstest.Mybin{equalstest.Mystr("1"): equalstest.Mybin("1"), equalstest.Mystr("0"): equalstest.Mybin("0")}, OptMyStrMyBinMapFoo: map[equalstest.Mystr]equalstest.Mybin{equalstest.Mystr("1"): equalstest.Mybin("1"), equalstest.Mystr("0"): equalstest.Mybin("0")}, Int64MyByteMapFoo: map[int64]equalstest.Mybyte{6: equalstest.Mybyte(6), 5: equalstest.Mybyte(5), 4: equalstest.Mybyte(4), 3: equalstest.Mybyte(3), 2: equalstest.Mybyte(2), 1: equalstest.Mybyte(1)}, OptInt64MyByteMapFoo: map[int64]equalstest.Mybyte{6: equalstest.Mybyte(6), 5: equalstest.Mybyte(5), 4: equalstest.Mybyte(4), 3: equalstest.Mybyte(3), 2: equalstest.Mybyte(2), 1: equalstest.Mybyte(1)}, MyByteInt64MapFoo: map[equalstest.Mybyte]int64{equalstest.Mybyte(6): 6, equalstest.Mybyte(5): 5, equalstest.Mybyte(4): 4, equalstest.Mybyte(3): 3, equalstest.Mybyte(2): 2, equalstest.Mybyte(1): 1}, OptMyByteInt64MapFoo: map[equalstest.Mybyte]int64{equalstest.Mybyte(6): 6, equalstest.Mybyte(5): 5, equalstest.Mybyte(4): 4, equalstest.Mybyte(3): 3, equalstest.Mybyte(2): 2, equalstest.Mybyte(1): 1}, UUIDMapFoo: map[int64]thrift.Tuuid{1: equalstestUUID1, 2: equalstestUUID2}, OptUUIDMapFoo: map[int64]thrift.Tuuid{1: equalstestUUID1, 2: equalstestUUID2}, MyUUIDMapFoo: map[int64]equalstest.Myuuid{1: equalstest.Myuuid(equalstestUUID1), 2: equalstest.Myuuid(equalstestUUID2)}, OptMyUUIDMapFoo: map[int64]equalstest.Myuuid{1: equalstest.Myuuid(equalstestUUID1), 2: equalstest.Myuuid(equalstestUUID2)}, } } func genInt64Slice(length int) []int64 { ret := make([]int64, length) for i := range ret { ret[i] = int64(length - i) } return ret } func genStringSlice(length int) []string { ret := make([]string, length) for i := range ret { ret[i] = strconv.Itoa(length - i) } return ret } func genBytesSlice(length int) [][]byte { ret := make([][]byte, length) for i := range ret { ret[i] = []byte(strconv.Itoa(length - i)) } return ret } func genInt64StringMap(length int) map[int64]string { ret := make(map[int64]string, length) for i := range length { ret[int64(i)] = strconv.Itoa(i) } return ret } thrift-0.23.0/lib/go/test/tests/server_connectivity_check_test.go0000664000175000017500000000557715165535636025536 0ustar00buildbuild00000000000000/* * 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" "runtime/debug" "testing" "time" "github.com/apache/thrift/lib/go/test/gopath/src/clientmiddlewareexceptiontest" "github.com/apache/thrift/lib/go/thrift" ) func TestServerConnectivityCheck(t *testing.T) { const ( // Server will sleep for longer than client is willing to wait // so client will close the connection. serverSleep = 50 * time.Millisecond clientSocketTimeout = time.Millisecond ) serverSocket, err := thrift.NewTServerSocket(":0") if err != nil { t.Fatalf("failed to create server socket: %v", err) } processor := clientmiddlewareexceptiontest.NewClientMiddlewareExceptionTestProcessor(fakeClientMiddlewareExceptionTestHandler( func(ctx context.Context) (*clientmiddlewareexceptiontest.FooResponse, error) { time.Sleep(serverSleep) err := ctx.Err() if err == nil { t.Error("Expected server ctx to be cancelled, did not happen") return new(clientmiddlewareexceptiontest.FooResponse), nil } return nil, err }, )) server := thrift.NewTSimpleServer2(processor, serverSocket) if err := server.Listen(); err != nil { t.Fatalf("failed to listen server: %v", err) } server.SetLogger(func(msg string) { t.Errorf("Server logger called with %q", msg) t.Errorf("Server logger callstack:\n%s", debug.Stack()) }) addr := serverSocket.Addr().String() go server.Serve() t.Cleanup(func() { server.Stop() }) cfg := &thrift.TConfiguration{ SocketTimeout: clientSocketTimeout, } socket := thrift.NewTSocketConf(addr, cfg) if err := socket.Open(); err != nil { t.Fatalf("failed to create client connection: %v", err) } t.Cleanup(func() { socket.Close() }) inProtocol := thrift.NewTBinaryProtocolConf(socket, cfg) outProtocol := thrift.NewTBinaryProtocolConf(socket, cfg) client := thrift.NewTStandardClient(inProtocol, outProtocol) ctx, cancel := context.WithTimeout(context.Background(), clientSocketTimeout) defer cancel() _, err = clientmiddlewareexceptiontest.NewClientMiddlewareExceptionTestClient(client).Foo(ctx) socket.Close() if err == nil { t.Error("Expected client to time out, did not happen") } } thrift-0.23.0/lib/go/test/tests/slog_tstruct_wrapper_test.go0000664000175000017500000000662615165535636024565 0ustar00buildbuild00000000000000/* * 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 ( "log/slog" "strings" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/forwardtypetest" "github.com/apache/thrift/lib/go/thrift" ) func dropTime(groups []string, a slog.Attr) slog.Attr { if len(groups) == 0 && a.Key == slog.TimeKey { return slog.Attr{} } return a } func TestSlogTStructWrapperJSON(t *testing.T) { for _, c := range []struct { label string value thrift.TStruct want string }{ { label: "struct", value: &forwardtypetest.Struct{ Foo: &forwardtypetest.Exc{ Code: thrift.Int32Ptr(10), }, }, want: `{"level":"INFO","msg":"bar","struct":{"type":"*forwardtypetest.Struct","value":{"foo":{"code":10}}}}`, }, { label: "exception", value: &forwardtypetest.Exc{ Code: thrift.Int32Ptr(10), }, want: `{"level":"INFO","msg":"bar","struct":{"type":"*forwardtypetest.Exc","value":{"code":10}}}`, }, { label: "nil-struct", value: (*forwardtypetest.Struct)(nil), want: `{"level":"INFO","msg":"bar","struct":null}`, }, { label: "nil-exception", value: (*forwardtypetest.Exc)(nil), want: `{"level":"INFO","msg":"bar","struct":null}`, }, } { t.Run(c.label, func(t *testing.T) { var sb strings.Builder logger := slog.New(slog.NewJSONHandler(&sb, &slog.HandlerOptions{ AddSource: false, ReplaceAttr: dropTime, })) logger.Info("bar", "struct", c.value) if got := strings.TrimSuffix(sb.String(), "\n"); got != c.want { t.Errorf("got %q want %q", got, c.want) } }) } } func TestSlogTStructWrapperText(t *testing.T) { for _, c := range []struct { label string value thrift.TStruct want string }{ { label: "struct", value: &forwardtypetest.Struct{ Foo: &forwardtypetest.Exc{ Code: thrift.Int32Ptr(10), }, }, want: `level=INFO msg=bar struct="*forwardtypetest.Struct{\"foo\":{\"code\":10}}"`, }, { label: "exception", value: &forwardtypetest.Exc{ Code: thrift.Int32Ptr(10), }, want: `level=INFO msg=bar struct="*forwardtypetest.Exc{\"code\":10}"`, }, { label: "nil-struct", value: (*forwardtypetest.Struct)(nil), want: `level=INFO msg=bar struct=`, }, { label: "nil-exception", value: (*forwardtypetest.Exc)(nil), want: `level=INFO msg=bar struct=`, }, } { t.Run(c.label, func(t *testing.T) { var sb strings.Builder logger := slog.New(slog.NewTextHandler(&sb, &slog.HandlerOptions{ AddSource: false, ReplaceAttr: dropTime, })) logger.Info("bar", "struct", c.value) if got := strings.TrimSuffix(sb.String(), "\n"); got != c.want { t.Errorf("got %q want %q", got, c.want) } }) } } thrift-0.23.0/lib/go/test/tests/thrifttest_driver.go0000664000175000017500000002162715167543515023000 0ustar00buildbuild00000000000000/* * 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 ( "reflect" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/thrifttest" ) type ThriftTestDriver struct { client thrifttest.ThriftTest t *testing.T } func NewThriftTestDriver(t *testing.T, client thrifttest.ThriftTest) *ThriftTestDriver { return &ThriftTestDriver{client, t} } func (p *ThriftTestDriver) Start() { client := p.client t := p.t if client.TestVoid(defaultCtx) != nil { t.Fatal("TestVoid failed") } if r, err := client.TestString(defaultCtx, "Test"); r != "Test" || err != nil { t.Fatal("TestString with simple text failed") } if r, err := client.TestString(defaultCtx, ""); r != "" || err != nil { t.Fatal("TestString with empty text failed") } 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 " + //lint:ignore ST1018 intentionally use unicode characters here "Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪" + //lint:ignore ST1018 intentionally use unicode characters here "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ú, 粵語" if r, err := client.TestString(defaultCtx, stringTest); r != stringTest || err != nil { t.Fatal("TestString with all languages failed") } specialCharacters := "quote: \" backslash:" + " 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: ]] \"]] \\\" }}}{ [[[ " if r, err := client.TestString(defaultCtx, specialCharacters); r != specialCharacters || err != nil { t.Fatal("TestString with specialCharacters failed") } if r, err := client.TestByte(defaultCtx, 1); r != 1 || err != nil { t.Fatal("TestByte(1) failed") } if r, err := client.TestByte(defaultCtx, 0); r != 0 || err != nil { t.Fatal("TestByte(0) failed") } if r, err := client.TestByte(defaultCtx, -1); r != -1 || err != nil { t.Fatal("TestByte(-1) failed") } if r, err := client.TestByte(defaultCtx, -127); r != -127 || err != nil { t.Fatal("TestByte(-127) failed") } if r, err := client.TestI32(defaultCtx, -1); r != -1 || err != nil { t.Fatal("TestI32(-1) failed") } if r, err := client.TestI32(defaultCtx, 1); r != 1 || err != nil { t.Fatal("TestI32(1) failed") } if r, err := client.TestI64(defaultCtx, -5); r != -5 || err != nil { t.Fatal("TestI64(-5) failed") } if r, err := client.TestI64(defaultCtx, 5); r != 5 || err != nil { t.Fatal("TestI64(5) failed") } if r, err := client.TestI64(defaultCtx, -34359738368); r != -34359738368 || err != nil { t.Fatal("TestI64(-34359738368) failed") } if r, err := client.TestDouble(defaultCtx, -5.2098523); r != -5.2098523 || err != nil { t.Fatal("TestDouble(-5.2098523) failed") } if r, err := client.TestDouble(defaultCtx, -7.012052175215044); r != -7.012052175215044 || err != nil { t.Fatal("TestDouble(-7.012052175215044) failed") } // TODO: add testBinary() call out := thrifttest.NewXtruct() out.StringThing = "Zero" out.ByteThing = 1 out.I32Thing = -3 out.I64Thing = 1000000 if r, err := client.TestStruct(defaultCtx, out); !reflect.DeepEqual(r, out) || err != nil { t.Fatal("TestStruct failed") } out2 := thrifttest.NewXtruct2() out2.ByteThing = 1 out2.StructThing = out out2.I32Thing = 5 if r, err := client.TestNest(defaultCtx, out2); !reflect.DeepEqual(r, out2) || err != nil { t.Fatal("TestNest failed") } mapout := make(map[int32]int32) for i := range int32(5) { mapout[i] = i - 10 } if r, err := client.TestMap(defaultCtx, mapout); !reflect.DeepEqual(r, mapout) || err != nil { t.Fatal("TestMap failed") } mapTestInput := map[string]string{ "a": "123", "a b": "with spaces ", "same": "same", "0": "numeric key", "longValue": stringTest, stringTest: "long key", } if r, err := client.TestStringMap(defaultCtx, mapTestInput); !reflect.DeepEqual(r, mapTestInput) || err != nil { t.Fatal("TestStringMap failed") } setTestInput := []int32{1, 2, 3} if r, err := client.TestSet(defaultCtx, setTestInput); !reflect.DeepEqual(r, setTestInput) || err != nil { t.Fatal("TestSet failed") } listTest := []int32{1, 2, 3} if r, err := client.TestList(defaultCtx, listTest); !reflect.DeepEqual(r, listTest) || err != nil { t.Fatal("TestList failed") } if r, err := client.TestEnum(defaultCtx, thrifttest.Numberz_ONE); r != thrifttest.Numberz_ONE || err != nil { t.Fatal("TestEnum failed") } if r, err := client.TestTypedef(defaultCtx, 69); r != 69 || err != nil { t.Fatal("TestTypedef failed") } mapMapTest := map[int32]map[int32]int32{ 4: {1: 1, 2: 2, 3: 3, 4: 4}, -4: {-4: -4, -3: -3, -2: -2, -1: -1}, } if r, err := client.TestMapMap(defaultCtx, 1); !reflect.DeepEqual(r, mapMapTest) || err != nil { t.Fatal("TestMapMap failed") } crazyX1 := thrifttest.NewXtruct() crazyX1.StringThing = "Goodbye4" crazyX1.ByteThing = 4 crazyX1.I32Thing = 4 crazyX1.I64Thing = 4 crazyX2 := thrifttest.NewXtruct() crazyX2.StringThing = "Hello2" crazyX2.ByteThing = 2 crazyX2.I32Thing = 2 crazyX2.I64Thing = 2 crazy := thrifttest.NewInsanity() crazy.UserMap = map[thrifttest.Numberz]thrifttest.UserId{5: 5, 8: 8} crazy.Xtructs = []*thrifttest.Xtruct{crazyX1, crazyX2} crazyEmpty := thrifttest.NewInsanity() crazyEmpty.UserMap = map[thrifttest.Numberz]thrifttest.UserId{} crazyEmpty.Xtructs = []*thrifttest.Xtruct{} insanity := map[thrifttest.UserId]map[thrifttest.Numberz]*thrifttest.Insanity{ 1: {thrifttest.Numberz_TWO: crazy, thrifttest.Numberz_THREE: crazy}, 2: {thrifttest.Numberz_SIX: crazyEmpty}, } if r, err := client.TestInsanity(defaultCtx, crazy); !reflect.DeepEqual(r, insanity) || err != nil { t.Fatal("TestInsanity failed:", err) } if err := client.TestException(defaultCtx, "TException"); err == nil { t.Fatal("TestException TException failed:", err) } err := client.TestException(defaultCtx, "Xception") if e, ok := err.(*thrifttest.Xception); !ok || e == nil { t.Fatal("TestException Xception failed:", err) } else if e.ErrorCode != 1001 || e.Message != "Xception" { t.Fatal("TestException Xception failed:", e) } if err := client.TestException(defaultCtx, "no Exception"); err != nil { t.Fatal("TestException no Exception failed:", err) } if err := client.TestOneway(defaultCtx, 0); err != nil { t.Fatal("TestOneway failed:", err) } } thrift-0.23.0/lib/go/test/tests/header_zlib_test.go0000664000175000017500000001372315165535636022535 0ustar00buildbuild00000000000000/* * 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) } } thrift-0.23.0/lib/go/test/tests/client_middleware_exception_test.go0000664000175000017500000001447715165535636026025 0ustar00buildbuild00000000000000/* * 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/clientmiddlewareexceptiontest" "github.com/apache/thrift/lib/go/thrift" ) type fakeClientMiddlewareExceptionTestHandler func(ctx context.Context) (*clientmiddlewareexceptiontest.FooResponse, error) func (f fakeClientMiddlewareExceptionTestHandler) Foo(ctx context.Context) (*clientmiddlewareexceptiontest.FooResponse, error) { return f(ctx) } type clientMiddlewareErrorChecker func(err error) error var clientMiddlewareExceptionCases = []struct { label string handler fakeClientMiddlewareExceptionTestHandler checker clientMiddlewareErrorChecker }{ { label: "no-error", handler: func(_ context.Context) (*clientmiddlewareexceptiontest.FooResponse, error) { return new(clientmiddlewareexceptiontest.FooResponse), nil }, checker: func(err error) error { if err != nil { return errors.New("expected err to be nil") } return nil }, }, { label: "exception-1", handler: func(_ context.Context) (*clientmiddlewareexceptiontest.FooResponse, error) { return nil, new(clientmiddlewareexceptiontest.Exception1) }, checker: func(err error) error { if !errors.As(err, new(*clientmiddlewareexceptiontest.Exception1)) { return errors.New("expected err to be of type *clientmiddlewareexceptiontest.Exception1") } return nil }, }, { label: "no-error", handler: func(_ context.Context) (*clientmiddlewareexceptiontest.FooResponse, error) { return nil, new(clientmiddlewareexceptiontest.Exception2) }, checker: func(err error) error { if !errors.As(err, new(*clientmiddlewareexceptiontest.Exception2)) { return errors.New("expected err to be of type *clientmiddlewareexceptiontest.Exception2") } return nil }, }, } func TestClientMiddlewareException(t *testing.T) { for _, c := range clientMiddlewareExceptionCases { t.Run(c.label, func(t *testing.T) { serverSocket, err := thrift.NewTServerSocket(":0") if err != nil { t.Fatalf("failed to create server socket: %v", err) } processor := clientmiddlewareexceptiontest.NewClientMiddlewareExceptionTestProcessor(c.handler) server := thrift.NewTSimpleServer2(processor, serverSocket) if err := server.Listen(); err != nil { t.Fatalf("failed to listen server: %v", err) } addr := serverSocket.Addr().String() go server.Serve() t.Cleanup(func() { server.Stop() }) var cfg *thrift.TConfiguration socket := thrift.NewTSocketConf(addr, cfg) if err := socket.Open(); err != nil { t.Fatalf("failed to create client connection: %v", err) } t.Cleanup(func() { socket.Close() }) inProtocol := thrift.NewTBinaryProtocolConf(socket, cfg) outProtocol := thrift.NewTBinaryProtocolConf(socket, cfg) middleware := func(next thrift.TClient) thrift.TClient { return thrift.WrappedTClient{ Wrapped: func(ctx context.Context, method string, args, result thrift.TStruct) (_ thrift.ResponseMeta, err error) { defer func() { if checkErr := c.checker(err); checkErr != nil { t.Errorf("middleware result unexpected: %v (result=%#v, err=%#v)", checkErr, result, err) } }() return next.Call(ctx, method, args, result) }, } } client := thrift.WrapClient( thrift.NewTStandardClient(inProtocol, outProtocol), middleware, thrift.ExtractIDLExceptionClientMiddleware, ) result, err := clientmiddlewareexceptiontest.NewClientMiddlewareExceptionTestClient(client).Foo(context.Background()) if checkErr := c.checker(err); checkErr != nil { t.Errorf("final result unexpected: %v (result=%#v, err=%#v)", checkErr, result, err) } }) } } func TestExtractExceptionFromResult(t *testing.T) { for _, c := range clientMiddlewareExceptionCases { t.Run(c.label, func(t *testing.T) { serverSocket, err := thrift.NewTServerSocket(":0") if err != nil { t.Fatalf("failed to create server socket: %v", err) } processor := clientmiddlewareexceptiontest.NewClientMiddlewareExceptionTestProcessor(c.handler) server := thrift.NewTSimpleServer2(processor, serverSocket) if err := server.Listen(); err != nil { t.Fatalf("failed to listen server: %v", err) } addr := serverSocket.Addr().String() go server.Serve() t.Cleanup(func() { server.Stop() }) var cfg *thrift.TConfiguration socket := thrift.NewTSocketConf(addr, cfg) if err := socket.Open(); err != nil { t.Fatalf("failed to create client connection: %v", err) } t.Cleanup(func() { socket.Close() }) inProtocol := thrift.NewTBinaryProtocolConf(socket, cfg) outProtocol := thrift.NewTBinaryProtocolConf(socket, cfg) middleware := func(next thrift.TClient) thrift.TClient { return thrift.WrappedTClient{ Wrapped: func(ctx context.Context, method string, args, result thrift.TStruct) (_ thrift.ResponseMeta, err error) { defer func() { if err == nil { err = thrift.ExtractExceptionFromResult(result) } if checkErr := c.checker(err); checkErr != nil { t.Errorf("middleware result unexpected: %v (result=%#v, err=%#v)", checkErr, result, err) } }() return next.Call(ctx, method, args, result) }, } } client := thrift.WrapClient( thrift.NewTStandardClient(inProtocol, outProtocol), middleware, ) result, err := clientmiddlewareexceptiontest.NewClientMiddlewareExceptionTestClient(client).Foo(context.Background()) if checkErr := c.checker(err); checkErr != nil { t.Errorf("final result unexpected: %v (result=%#v, err=%#v)", checkErr, result, err) } }) } } thrift-0.23.0/lib/go/test/tests/names_test.go0000664000175000017500000000213415167543515021357 0ustar00buildbuild00000000000000/* * 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 ( "reflect" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/namestest" ) func TestThatAttributeNameSubstituionDoesNotOccur(t *testing.T) { st := reflect.TypeFor[namestest.NamesTest]() _, ok := st.FieldByName("Type") if !ok { t.Error("Type attribute is missing!") } } thrift-0.23.0/lib/go/test/tests/ignoreinitialisms_test.go0000664000175000017500000000272115167543515024007 0ustar00buildbuild00000000000000/* * 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 ( "reflect" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/ignoreinitialismstest" ) func TestIgnoreInitialismsFlagIsHonoured(t *testing.T) { st := reflect.TypeFor[ignoreinitialismstest.IgnoreInitialismsTest]() _, ok := st.FieldByName("Id") if !ok { t.Error("Id attribute is missing!") } _, ok = st.FieldByName("MyId") if !ok { t.Error("MyId attribute is missing!") } _, ok = st.FieldByName("NumCpu") if !ok { t.Error("NumCpu attribute is missing!") } _, ok = st.FieldByName("NumGpu") if !ok { t.Error("NumGpu attribute is missing!") } _, ok = st.FieldByName("My_ID") if !ok { t.Error("My_ID attribute is missing!") } } thrift-0.23.0/lib/go/test/tests/required_fields_test.go0000664000175000017500000001171715165535636023434 0ustar00buildbuild00000000000000/* * 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" "testing" "github.com/golang/mock/gomock" "github.com/apache/thrift/lib/go/test/gopath/src/optionalfieldstest" "github.com/apache/thrift/lib/go/test/gopath/src/requiredfieldtest" "github.com/apache/thrift/lib/go/thrift" ) func TestRequiredField_SucecssWhenSet(t *testing.T) { // create a new RequiredField instance with the required field set source := &requiredfieldtest.RequiredField{Name: "this is a test"} sourceData, err := thrift.NewTSerializer().Write(context.Background(), source) if err != nil { t.Fatalf("failed to serialize %T: %v", source, err) } d := thrift.NewTDeserializer() err = d.Read(context.Background(), &requiredfieldtest.RequiredField{}, sourceData) if err != nil { t.Fatalf("Did not expect an error when trying to deserialize the requiredfieldtest.RequiredField: %v", err) } } func TestRequiredField_ErrorWhenMissing(t *testing.T) { // create a new OtherThing instance, without setting the required field source := &requiredfieldtest.OtherThing{} sourceData, err := thrift.NewTSerializer().Write(context.Background(), source) if err != nil { t.Fatalf("failed to serialize %T: %v", source, err) } // attempt to deserialize into a different type (which should fail) d := thrift.NewTDeserializer() err = d.Read(context.Background(), &requiredfieldtest.RequiredField{}, sourceData) if err == nil { t.Fatal("Expected an error when trying to deserialize an object which is missing a required field") } } func TestStructReadRequiredFields(t *testing.T) { mockCtrl := gomock.NewController(t) protocol := NewMockTProtocol(mockCtrl) testStruct := optionalfieldstest.NewStructC() // None of required fields are set gomock.InOrder( protocol.EXPECT().ReadStructBegin(context.Background()).Return("StructC", nil), protocol.EXPECT().ReadFieldBegin(context.Background()).Return("_", thrift.TType(thrift.STOP), int16(1), nil), protocol.EXPECT().ReadStructEnd(context.Background()).Return(nil), ) err := testStruct.Read(context.Background(), protocol) mockCtrl.Finish() mockCtrl = gomock.NewController(t) if err == nil { t.Fatal("Expected read to fail") } err2, ok := err.(thrift.TProtocolException) if !ok { t.Fatal("Expected a TProtocolException") } if err2.TypeId() != thrift.INVALID_DATA { t.Fatal("Expected INVALID_DATA TProtocolException") } // One of the required fields is set gomock.InOrder( protocol.EXPECT().ReadStructBegin(context.Background()).Return("StructC", nil), protocol.EXPECT().ReadFieldBegin(context.Background()).Return("I", thrift.TType(thrift.I32), int16(2), nil), protocol.EXPECT().ReadI32(context.Background()).Return(int32(1), nil), protocol.EXPECT().ReadFieldEnd(context.Background()).Return(nil), protocol.EXPECT().ReadFieldBegin(context.Background()).Return("_", thrift.TType(thrift.STOP), int16(1), nil), protocol.EXPECT().ReadStructEnd(context.Background()).Return(nil), ) err = testStruct.Read(context.Background(), protocol) mockCtrl.Finish() mockCtrl = gomock.NewController(t) if err == nil { t.Fatal("Expected read to fail") } err2, ok = err.(thrift.TProtocolException) if !ok { t.Fatal("Expected a TProtocolException") } if err2.TypeId() != thrift.INVALID_DATA { t.Fatal("Expected INVALID_DATA TProtocolException") } // Both of the required fields are set gomock.InOrder( protocol.EXPECT().ReadStructBegin(context.Background()).Return("StructC", nil), protocol.EXPECT().ReadFieldBegin(context.Background()).Return("i", thrift.TType(thrift.I32), int16(2), nil), protocol.EXPECT().ReadI32(context.Background()).Return(int32(1), nil), protocol.EXPECT().ReadFieldEnd(context.Background()).Return(nil), protocol.EXPECT().ReadFieldBegin(context.Background()).Return("s2", thrift.TType(thrift.STRING), int16(4), nil), protocol.EXPECT().ReadString(context.Background()).Return("test", nil), protocol.EXPECT().ReadFieldEnd(context.Background()).Return(nil), protocol.EXPECT().ReadFieldBegin(context.Background()).Return("_", thrift.TType(thrift.STOP), int16(1), nil), protocol.EXPECT().ReadStructEnd(context.Background()).Return(nil), ) err = testStruct.Read(context.Background(), protocol) mockCtrl.Finish() if err != nil { t.Fatal("Expected read to succeed") } } thrift-0.23.0/lib/go/test/tests/conflict_namespace_test.go0000664000175000017500000000176015165535636024100 0ustar00buildbuild00000000000000/* * 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 ( "github.com/apache/thrift/lib/go/test/gopath/src/conflict/super" ) // We just want to make sure that the compiler generated package compiles. var _ = super.GoUnusedProtection__ thrift-0.23.0/lib/go/test/tests/conflict_arg_names_test.go0000664000175000017500000000200715165535636024073 0ustar00buildbuild00000000000000/* * 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 ( "github.com/apache/thrift/lib/go/test/gopath/src/conflictargnamestest" ) // We just want to make sure that the conflictargnamestest package compiles. var _ = conflictargnamestest.GoUnusedProtection__ thrift-0.23.0/lib/go/test/tests/gotag_test.go0000664000175000017500000000407515167543515021363 0ustar00buildbuild00000000000000/* * 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 ( "reflect" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/gotagtest" ) func TestDefaultTag(t *testing.T) { st := reflect.TypeFor[gotagtest.Tagged]() field, ok := st.FieldByName("StringThing") if !ok || field.Tag.Get("json") != "string_thing" { t.Error("Unexpected default tag value") } } func TestCustomTag(t *testing.T) { st := reflect.TypeFor[gotagtest.Tagged]() field, ok := st.FieldByName("IntThing") if !ok { t.Error("Missing field IntThing") return } if v := field.Tag.Get("json"); v != "custom_thing" { t.Errorf("Expected custom_thing for tag json, got %s", v) } if v := field.Tag.Get("mykey"); v != "myvalue" { t.Errorf("Expected myvalue for tag mykey, got %s", v) } } func TestOptionalTag(t *testing.T) { st := reflect.TypeFor[gotagtest.Tagged]() field, ok := st.FieldByName("OptionalIntThing") if !ok || field.Tag.Get("json") != "optional_int_thing,omitempty" { t.Error("Unexpected default tag value for optional field") } } func TestOptionalTagWithDefaultValue(t *testing.T) { st := reflect.TypeFor[gotagtest.Tagged]() field, ok := st.FieldByName("OptionalBoolThing") if !ok || field.Tag.Get("json") != "optional_bool_thing" { t.Error("Unexpected default tag value for optional field that has a default value") } } thrift-0.23.0/lib/go/test/tests/context.go0000664000175000017500000000156115165535636020707 0ustar00buildbuild00000000000000/* * 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" ) var defaultCtx = context.Background() thrift-0.23.0/lib/go/test/tests/one_way_test.go0000664000175000017500000000543115165535636021723 0ustar00buildbuild00000000000000/* * 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" "net" "testing" "time" "github.com/apache/thrift/lib/go/test/gopath/src/onewaytest" "github.com/apache/thrift/lib/go/thrift" ) func findPort() net.Addr { if l, err := net.Listen("tcp", "127.0.0.1:0"); err != nil { panic("Could not find available server port") } else { defer l.Close() return l.Addr() } } type impl struct{} func (i *impl) Hi(ctx context.Context, in int64, s string) (err error) { fmt.Println("Hi!"); return } func (i *impl) Emptyfunc(ctx context.Context) (err error) { return } func (i *impl) EchoInt(ctx context.Context, param int64) (r int64, err error) { return param, nil } const TIMEOUT = time.Second var addr net.Addr var server *thrift.TSimpleServer var client *onewaytest.OneWayClient func TestInitOneway(t *testing.T) { var err error addr = findPort() serverTransport, err := thrift.NewTServerSocketTimeout(addr.String(), TIMEOUT) if err != nil { t.Fatal("Unable to create server socket", err) } processor := onewaytest.NewOneWayProcessor(&impl{}) server = thrift.NewTSimpleServer2(processor, serverTransport) go server.Serve() time.Sleep(10 * time.Millisecond) } func TestInitOnewayClient(t *testing.T) { cfg := &thrift.TConfiguration{ ConnectTimeout: TIMEOUT, SocketTimeout: TIMEOUT, } transport := thrift.NewTSocketFromAddrConf(addr, cfg) protocol := thrift.NewTBinaryProtocolConf(transport, cfg) client = onewaytest.NewOneWayClient(thrift.NewTStandardClient(protocol, protocol)) err := transport.Open() if err != nil { t.Fatal("Unable to open client socket", err) } } func TestCallOnewayServer(t *testing.T) { //call oneway function err := client.Hi(defaultCtx, 1, "") if err != nil { t.Fatal("Unexpected error: ", err) } //There is no way to detect protocol problems with single oneway call so we call it second time i, err := client.EchoInt(defaultCtx, 42) if err != nil { t.Fatal("Unexpected error: ", err) } if i != 42 { t.Fatal("Unexpected returned value: ", i) } } thrift-0.23.0/lib/go/test/tests/validate_test.go0000664000175000017500000003776415167543515022066 0ustar00buildbuild00000000000000/* * 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 ( "encoding/json" "errors" "strconv" "testing" "github.com/apache/thrift/lib/go/test/gopath/src/validatetest" thrift "github.com/apache/thrift/lib/go/thrift" ) func TestBasicValidator(t *testing.T) { bt := validatetest.NewBasicTest() if err := bt.Validate(); err != nil { t.Error(err) } var ve *thrift.ValidationError bt = validatetest.NewBasicTest() bt.Bool1 = thrift.BoolPtr(false) if err := bt.Validate(); err == nil { t.Error("Expected vt.const error for Bool1") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "Bool1" { t.Errorf("Expected error for Bool1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() bt.Byte1 = thrift.Int8Ptr(3) if err := bt.Validate(); err == nil { t.Errorf("Expected vt.lt error for Byte1") } else if errors.As(err, &ve) { if ve.Check() != "vt.lt" { t.Errorf("Expected vt.lt check error, but got %v", ve.Check()) } if ve.Field() != "Byte1" { t.Errorf("Expected error for Byte1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() bt.Double1 = thrift.Float64Ptr(3.0) if err := bt.Validate(); err == nil { t.Errorf("Expected vt.lt error for Double1") } else if errors.As(err, &ve) { if ve.Check() != "vt.lt" { t.Errorf("Expected vt.lt check error, but got %v", ve.Check()) } if ve.Field() != "Double1" { t.Errorf("Expected error for Double1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() bt.String1 = thrift.StringPtr("other string") if err := bt.Validate(); err == nil { t.Errorf("Expected vt.const error for String1") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "String1" { t.Errorf("Expected error for String1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() bt.Binary1 = []byte("other binary") if err := bt.Validate(); err == nil { t.Errorf("Expected vt.const error for Binary1") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "Binary1" { t.Errorf("Expected error for Binary1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() bt.Map1 = make(map[string]string) for i := range 11 { bt.Map1[strconv.Itoa(i)] = strconv.Itoa(i) } if err := bt.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Map1") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Map1" { t.Errorf("Expected error for Map1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt.Map1 = map[string]string{"012345678910": "0"} if err := bt.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Map1") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Map1" { t.Errorf("Expected error for Map1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt.Map1 = map[string]string{"0": "012345678910"} if err := bt.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Map1") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Map1" { t.Errorf("Expected error for Map1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() for range 11 { bt.Set1 = append(bt.Set1, "0") } if err := bt.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Set1") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Set1" { t.Errorf("Expected error for Set1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt.Set1 = []string{"0"} if err := bt.Validate(); err == nil { t.Errorf("Expected vt.min_size error for Set1") } else if errors.As(err, &ve) { if ve.Check() != "vt.min_size" { t.Errorf("Expected vt.min_size check error, but got %v", ve.Check()) } if ve.Field() != "Set1" { t.Errorf("Expected error for Set1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } bt = validatetest.NewBasicTest() bt.Enum1 = (*validatetest.EnumFoo)(thrift.Int64Ptr(int64(validatetest.EnumFoo_e2))) if err := bt.Validate(); err == nil { t.Errorf("Expected vt.in error for Enum1") } else if errors.As(err, &ve) { if ve.Check() != "vt.in" { t.Errorf("Expected vt.in check error, but got %v", ve.Check()) } if ve.Field() != "Enum1" { t.Errorf("Expected error for Enum1, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } } func TestFieldReference(t *testing.T) { frt := validatetest.NewFieldReferenceTest() if err := frt.Validate(); err != nil { t.Error(err) } var ve *thrift.ValidationError frt = validatetest.NewFieldReferenceTest() frt.Bool2 = true if err := frt.Validate(); err == nil { t.Errorf("Expected vt.const error for Bool0") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "Bool0" { t.Errorf("Expected error for Bool0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } frt = validatetest.NewFieldReferenceTest() frt.Byte4 = 9 if err := frt.Validate(); err == nil { t.Errorf("Expected vt.lt error for Byte0") } else if errors.As(err, &ve) { if ve.Check() != "vt.lt" { t.Errorf("Expected vt.lt check error, but got %v", ve.Check()) } if ve.Field() != "Byte0" { t.Errorf("Expected error for Byte0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } frt = validatetest.NewFieldReferenceTest() frt.Double4 = 9 if err := frt.Validate(); err == nil { t.Errorf("Expected vt.lt error for Double0") } else if errors.As(err, &ve) { if ve.Check() != "vt.lt" { t.Errorf("Expected vt.lt check error, but got %v", ve.Check()) } if ve.Field() != "Double0" { t.Errorf("Expected error for Double0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } frt = validatetest.NewFieldReferenceTest() frt.String2 = "other string" if err := frt.Validate(); err == nil { t.Errorf("Expected vt.const error for String0") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "String0" { t.Errorf("Expected error for String0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } frt = validatetest.NewFieldReferenceTest() frt.Binary2 = []byte("other string") if err := frt.Validate(); err == nil { t.Errorf("Expected vt.const error for Binary0") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "Binary0" { t.Errorf("Expected error for Binary0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 frt.Map0 = make(map[string]string) for i := range 9 { frt.Map0[strconv.Itoa(i)] = strconv.Itoa(i) } if err := frt.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Map0") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Map0" { t.Errorf("Expected error for Map0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 for range 9 { frt.List0 = append(frt.List0, "0") } if err := frt.Validate(); err == nil { t.Errorf("Expected vt.max_size error for List0") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "List0" { t.Errorf("Expected error for List0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } frt = validatetest.NewFieldReferenceTest() frt.MaxSize = 8 for range 9 { frt.Set0 = append(frt.Set0, "0") } if err := frt.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Set0") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Set0" { t.Errorf("Expected error for Set0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } } func TestValidationFunction(t *testing.T) { vft := validatetest.NewValidationFunctionTest() if err := vft.Validate(); err != nil { t.Error(err) } var ve *thrift.ValidationError vft = validatetest.NewValidationFunctionTest() vft.StringFoo = "some string" if err := vft.Validate(); err == nil { t.Errorf("Expected vt.in error for StringLength") } else if errors.As(err, &ve) { if ve.Check() != "vt.in" { t.Errorf("Expected vt.in check error, but got %v", ve.Check()) } if ve.Field() != "StringLength" { t.Errorf("Expected error for StringLength, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } } func TestAnnotationCompatibleTest(t *testing.T) { act := validatetest.NewAnnotationCompatibleTest() if err := act.Validate(); err != nil { t.Error(err) } var ve *thrift.ValidationError act = validatetest.NewAnnotationCompatibleTest() act.Bool0 = false if err := act.Validate(); err == nil { t.Errorf("Expected vt.const error for Bool0") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "Bool0" { t.Errorf("Expected error for Bool0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.Byte0 = 3 if err := act.Validate(); err == nil { t.Errorf("Expected vt.lt error for Byte0") } else if errors.As(err, &ve) { if ve.Check() != "vt.lt" { t.Errorf("Expected vt.lt check error, but got %v", ve.Check()) } if ve.Field() != "Byte0" { t.Errorf("Expected error for Byte0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.Double0 = 3 if err := act.Validate(); err == nil { t.Errorf("Expected vt.lt error for Double0") } else if errors.As(err, &ve) { if ve.Check() != "vt.lt" { t.Errorf("Expected vt.lt check error, but got %v", ve.Check()) } if ve.Field() != "Double0" { t.Errorf("Expected error for Double0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.String0 = "other string" if err := act.Validate(); err == nil { t.Errorf("Expected vt.const error for String0") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "String0" { t.Errorf("Expected error for String0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.Binary0 = []byte("other string") if err := act.Validate(); err == nil { t.Errorf("Expected vt.const error for Binary0") } else if errors.As(err, &ve) { if ve.Check() != "vt.const" { t.Errorf("Expected vt.const check error, but got %v", ve.Check()) } if ve.Field() != "Binary0" { t.Errorf("Expected error for Binary0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.Map0 = map[string]string{"0": "0", "1": "1", "2": "2"} if err := act.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Map0") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Map0" { t.Errorf("Expected error for Map0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.Set0 = []string{"0", "1", "2"} if err := act.Validate(); err == nil { t.Errorf("Expected vt.max_size error for Set0") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "Set0" { t.Errorf("Expected error for Set0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.List0 = []string{"0", "1", "2"} if err := act.Validate(); err == nil { t.Errorf("Expected vt.max_size error for List0") } else if errors.As(err, &ve) { if ve.Check() != "vt.max_size" { t.Errorf("Expected vt.max_size check error, but got %v", ve.Check()) } if ve.Field() != "List0" { t.Errorf("Expected error for List0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } act = validatetest.NewAnnotationCompatibleTest() act.Enum0 = validatetest.EnumFoo_e1 if err := act.Validate(); err == nil { t.Errorf("Expected vt.in error for Enum0") } else if errors.As(err, &ve) { if ve.Check() != "vt.in" { t.Errorf("Expected vt.in check error, but got %v", ve.Check()) } if ve.Field() != "Enum0" { t.Errorf("Expected error for Enum0, but got %v", ve.Field()) } } else { t.Errorf("Error cannot be unwrapped into *ValidationError: %v", err) } fields := []string{"bool1", "byte1", "double1", "string1", "binary1", "enum1", "struct1", "list1", "set1", "map1"} b, err := json.Marshal(act) if err != nil { t.Error(err) } jsonMap := make(map[string]any) if err = json.Unmarshal(b, &jsonMap); err != nil { t.Error(err) } for _, field := range fields { if _, ok := jsonMap[field]; !ok { t.Errorf("Expected field %s in JSON, but not found", field) } } } thrift-0.23.0/lib/go/test/InitialismsTest.thrift0000664000175000017500000000156115165535636022101 0ustar00buildbuild00000000000000# # 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 InitialismsTest { 1: string user_id, 2: string server_url, 3: string id, } thrift-0.23.0/lib/go/test/ConstOptionalField.thrift0000664000175000017500000000562015165535636022514 0ustar00buildbuild00000000000000/* * 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 go constoptionalfieldb include "ConstOptionalFieldImport.thrift" typedef ConstOptionalFieldImport.Foo TypedefBFoo typedef bool TypedefBBool typedef i8 TypedefBI8 typedef i16 TypedefBI16 typedef i32 TypedefBI32 typedef i64 TypedefBI64 typedef double TypedefBDouble typedef string TypedefBString typedef binary TypedefBBinary struct Bar { 1: optional ConstOptionalFieldImport.Foo optFoo, 2: optional ConstOptionalFieldImport.TypedefAFoo aFoo, 3: optional TypedefBFoo bFoo, 4: optional bool optBool, 5: optional ConstOptionalFieldImport.TypedefABool aBool, 6: optional TypedefBBool bBool, 7: optional i8 optI8, 8: optional ConstOptionalFieldImport.TypedefAI8 aI8, 9: optional TypedefBI8 bI8, 10: optional i16 optI16, 11: optional ConstOptionalFieldImport.TypedefAI16 aI16, 12: optional TypedefBI16 bI16, 13: optional i32 optI32, 14: optional ConstOptionalFieldImport.TypedefAI32 aI32, 15: optional TypedefBI32 bI32, 16: optional i64 optI64, 17: optional ConstOptionalFieldImport.TypedefAI64 aI64, 18: optional TypedefBI64 bI64, 19: optional double optDouble, 20: optional ConstOptionalFieldImport.TypedefADouble aDouble, 21: optional TypedefBDouble bDouble, 22: optional string optString, 23: optional ConstOptionalFieldImport.TypedefAString aString, 24: optional TypedefBString bString, 25: optional binary optBinary, 26: optional ConstOptionalFieldImport.TypedefABinary aBinary, 27: optional TypedefBBinary bBinary, } const list CONSTANTS = [ { "optFoo": ConstOptionalFieldImport.Foo.One, "aFoo": ConstOptionalFieldImport.Foo.One, "bFoo": ConstOptionalFieldImport.Foo.One, "optBool": true, "aBool": true, "bBool": true, "optI8": 8, "aI8": 8, "bI8": 8, "optI16": 16, "aI16": 16, "bI16": 16, "optI32": 32, "aI32": 32, "bI32": 32, "optI64": 64, "aI64": 64, "bI64": 64, "optDouble": 1234, "aDouble": 1234, "bDouble": 1234, "optString": "string", "aString": "string", "bString": "string", "optBinary": "binary", "aBinary": "binary", "bBinary": "binary", }, ] thrift-0.23.0/lib/go/test/go.mod0000664000175000017500000000031515167543515016631 0ustar00buildbuild00000000000000module github.com/apache/thrift/lib/go/test go 1.25 require ( github.com/apache/thrift v0.0.0-00010101000000-000000000000 github.com/golang/mock v1.6.0 ) replace github.com/apache/thrift => ../../../ thrift-0.23.0/lib/go/test/NamesTest.thrift0000664000175000017500000000164715165535636020664 0ustar00buildbuild00000000000000# # 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 NamesTest { 1: required string type } service NameCollisionOne { void blahBlah() } service NameCollisionTwo { void blahBlah() } thrift-0.23.0/lib/go/test/Makefile.am0000664000175000017500000001504015165535636017563 0ustar00buildbuild00000000000000# # 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. # GOBUILDEXTRA = -buildvcs=false THRIFT_GO_ARGS_BASE = thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/gopath/src/ THRIFTARGS = -out gopath/src/ --gen go:$(THRIFT_GO_ARGS_BASE)$(COMPILER_EXTRAFLAG) THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift THRIFTARGS_SKIP_REMOTE = -out gopath/src/ --gen go:skip_remote,$(THRIFT_GO_ARGS_BASE)$(COMPILER_EXTRAFLAG) # Thrift for GO has problems with complex map keys: THRIFT-2063 gopath: $(THRIFT) $(THRIFTTEST) \ IncludesTest.thrift \ NamespacedTest.thrift \ MultiplexedProtocolTest.thrift \ OnewayTest.thrift \ OptionalFieldsTest.thrift \ RequiredFieldTest.thrift \ ServicesTest.thrift \ GoTagTest.thrift \ TypedefFieldTest.thrift \ RefAnnotationFieldsTest.thrift \ UnionDefaultValueTest.thrift \ UnionBinaryTest.thrift \ ErrorTest.thrift \ NamesTest.thrift \ InitialismsTest.thrift \ DontExportRWTest.thrift \ dontexportrwtest/compile_test.go \ IgnoreInitialismsTest.thrift \ ConflictNamespaceTestA.thrift \ ConflictNamespaceTestB.thrift \ ConflictNamespaceTestC.thrift \ ConflictNamespaceTestD.thrift \ ConflictNamespaceTestE.thrift \ ConflictNamespaceTestF.thrift \ ConflictNamespaceTestSuperThing.thrift \ ConflictNamespaceServiceTest.thrift \ DuplicateImportsTest.thrift \ EqualsTest.thrift \ ConflictArgNamesTest.thrift \ ConstOptionalFieldImport.thrift \ ConstOptionalField.thrift \ ProcessorMiddlewareTest.thrift \ ClientMiddlewareExceptionTest.thrift \ ValidateTest.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 $(THRIFT) $(THRIFTARGS) BinaryKeyTest.thrift $(THRIFT) $(THRIFTARGS) MultiplexedProtocolTest.thrift $(THRIFT) $(THRIFTARGS) OnewayTest.thrift $(THRIFT) $(THRIFTARGS) OptionalFieldsTest.thrift $(THRIFT) $(THRIFTARGS) RequiredFieldTest.thrift $(THRIFT) $(THRIFTARGS) ServicesTest.thrift $(THRIFT) $(THRIFTARGS) GoTagTest.thrift $(THRIFT) $(THRIFTARGS) TypedefFieldTest.thrift $(THRIFT) $(THRIFTARGS) RefAnnotationFieldsTest.thrift $(THRIFT) $(THRIFTARGS) UnionDefaultValueTest.thrift $(THRIFT) $(THRIFTARGS) UnionBinaryTest.thrift $(THRIFT) $(THRIFTARGS) ErrorTest.thrift $(THRIFT) $(THRIFTARGS) NamesTest.thrift $(THRIFT) $(THRIFTARGS) InitialismsTest.thrift $(THRIFT) $(THRIFTARGS),read_write_private DontExportRWTest.thrift $(THRIFT) $(THRIFTARGS),ignore_initialisms IgnoreInitialismsTest.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestA.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestB.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestC.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestD.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestE.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestF.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceTestSuperThing.thrift $(THRIFT) $(THRIFTARGS) ConflictNamespaceServiceTest.thrift $(THRIFT) $(THRIFTARGS) -r DuplicateImportsTest.thrift $(THRIFT) $(THRIFTARGS) EqualsTest.thrift $(THRIFT) $(THRIFTARGS) ConflictArgNamesTest.thrift $(THRIFT) $(THRIFTARGS) -r ConstOptionalField.thrift $(THRIFT) $(THRIFTARGS_SKIP_REMOTE) ProcessorMiddlewareTest.thrift $(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 check: gopath $(GO) build $(GOBUILDEXTRA) \ ./gopath/src/includestest \ ./gopath/src/binarykeytest \ ./gopath/src/servicestest \ ./gopath/src/typedeffieldtest \ ./gopath/src/refannotationfieldstest \ ./gopath/src/errortest \ ./gopath/src/namestest \ ./gopath/src/initialismstest \ ./gopath/src/dontexportrwtest \ ./gopath/src/ignoreinitialismstest \ ./gopath/src/unionbinarytest \ ./gopath/src/conflict/super \ ./gopath/src/conflict/context/conflict_service-remote \ ./gopath/src/servicestest/container_test-remote \ ./gopath/src/duplicateimportstest \ ./gopath/src/equalstest \ ./gopath/src/conflictargnamestest \ ./gopath/src/processormiddlewaretest \ ./gopath/src/clientmiddlewareexceptiontest \ ./gopath/src/validatetest \ ./gopath/src/forwardtypetest $(GO) test github.com/apache/thrift/lib/go/thrift $(GO) test ./gopath/src/tests ./gopath/src/dontexportrwtest clean-local: $(RM) -r gopath ThriftTest.thrift gen-go client: stubs $(GO) run TestClient.go distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ dontexportrwtest \ tests \ common \ go.mod \ go.sum \ BinaryKeyTest.thrift \ ClientMiddlewareExceptionTest.thrift \ ConflictArgNamesTest.thrift \ ConflictNamespaceServiceTest.thrift \ ConflictNamespaceTestA.thrift \ ConflictNamespaceTestB.thrift \ ConflictNamespaceTestC.thrift \ ConflictNamespaceTestD.thrift \ ConflictNamespaceTestE.thrift \ ConflictNamespaceTestF.thrift \ ConflictNamespaceTestSuperThing.thrift \ ConstOptionalField.thrift \ ConstOptionalFieldImport.thrift \ DontExportRWTest.thrift \ DuplicateImportsTest.thrift \ ErrorTest.thrift \ EqualsTest.thrift \ ForwardType.thrift \ GoTagTest.thrift \ IgnoreInitialismsTest.thrift \ IncludesTest.thrift \ InitialismsTest.thrift \ MultiplexedProtocolTest.thrift \ NamespacedTest.thrift \ NamesTest.thrift \ OnewayTest.thrift \ OptionalFieldsTest.thrift \ ProcessorMiddlewareTest.thrift \ RefAnnotationFieldsTest.thrift \ RequiredFieldTest.thrift \ ServicesTest.thrift \ StringParseAllocationTest.thrift \ TypedefFieldTest.thrift \ UnionBinaryTest.thrift \ UnionDefaultValueTest.thrift \ ValidateTest.thrift thrift-0.23.0/lib/go/test/ErrorTest.thrift0000664000175000017500000000223615165535636020705 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ struct TestStruct { 1: map m, 2: list l, 3: set s, 4: i32 i } service ErrorTest { TestStruct testStruct(1: TestStruct thing) string testString(1: string s) } thrift-0.23.0/lib/go/coding_standards.md0000664000175000017500000000010315165535636020372 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/go/README.md0000664000175000017500000001401015165535636016023 0ustar00buildbuild00000000000000Thrift Go Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Suppored Go releases ==================== Following the [official Go release policy](https://golang.org/doc/devel/release#policy), we support the latest two Go releases at the time of the Thrift release. For example, at the time of Thrift v0.14.0 release, the latest two Go releases are go1.15 and go1.14, and those are the two Go releases supported by Thrift v0.14.* (including v0.14.1 and v0.14.2 patch releases). Because of Go's backward compatibility guarantee, older Thrift libraries usually works with newer Go releases (e.g. Thrift v0.14.* works with go1.16, although it's not officially supported), but newer Thrift releases might use new APIs introduced in Go releases and no longer work with older Go releases. For example, Thrift v0.14.0 used APIs introduced in go1.13, and as a result no longer works on go1.12. Using Thrift with Go ==================== Thrift supports the currently officially supported Go releases (the latest 2). After initializing the go modules file in your project, use the following command to add the most recent version of the package: $ go get github.com/apache/thrift A note about optional fields ============================ The thrift-to-Go compiler tries to represent thrift IDL structs as Go structs. We must be able to distinguish between optional fields that are set to their default value and optional values which are actually unset, so the generated code represents optional fields via pointers. This is generally intuitive and works well much of the time, but Go does not have a syntax for creating a pointer to a constant in a single expression. That is, given a struct like struct SomeIDLType { OptionalField *int32 } , the following will not compile: x := &SomeIDLType{ OptionalField: &(3), } (Nor is there any other syntax that's built in to the language) As such, we provide some helpers that do just this under lib/go/thrift/. E.g., x := &SomeIDLType{ OptionalField: thrift.Int32Ptr(3), } And so on. The code generator also creates analogous helpers for user-defined typedefs and enums. Adding custom tags to generated Thrift structs ============================================== You can add tags to the auto-generated thrift structs using the following format: struct foo { 1: required string Bar (go.tag = "some_tag:\"some_tag_value\"") } which will generate: type Foo struct { Bar string `thrift:"bar,1,required" some_tag:"some_tag_value"` } A note about server handler implementations =========================================== The context object passed into the server handler function will be canceled when the client closes the connection (this is a best effort check, not a guarantee -- there's no guarantee that the context object is always canceled when client closes the connection, but when it's canceled you can always assume the client closed the connection). The cause of the cancellation (via `context.Cause(ctx)`) would also be set to `thrift.ErrAbandonRequest`. When implementing Go Thrift server, you can take advantage of that to abandon requests that's no longer needed by returning `thrift.ErrAbandonRequest`: func MyEndpoint(ctx context.Context, req *thriftRequestType) (*thriftResponseType, error) { ... if ctx.Err() == context.Canceled { return nil, thrift.ErrAbandonRequest // Or just return ctx.Err(), compiler generated processor code will // handle it for you automatically: // return nil, ctx.Err() } ... } This feature would add roughly 1 millisecond of latency overhead to the server handlers (along with roughly 2 goroutines per request). If that is unacceptable, it can be disabled by having this line early in your main function: thrift.ServerConnectivityCheckInterval = 0 Please be advised that due to a [Go runtime bug](https://github.com/golang/go/issues/27707), currently if this interval is set to a value too low (for example, 1ms), it might cause excessive cpu overhead. This feature is also only enabled on non-oneway endpoints. A note about server stop implementations ======================================== [TSimpleServer.Stop](https://pkg.go.dev/github.com/apache/thrift/lib/go/thrift#TSimpleServer.Stop) will wait for all client connections to be closed after the last received request to be handled, as the time spent by Stop may sometimes be too long: * When socket timeout is not set, server might be hanged before all active clients to finish handling the last received request. * When the socket timeout is too long (e.g one hour), server will hang for that duration before all active clients to finish handling the last received request. To prevent Stop from hanging for too long, you can set thrift.ServerStopTimeout in your main or init function: thrift.ServerStopTimeout = If it's set to <=0, the feature will be disabled (by default), and server will wait for all the client connections to be closed gracefully with zero err time. Otherwise, the stop will wait for all the client connections to be closed gracefully util thrift.ServerStopTimeout is reached, and client connections that are not closed after thrift.ServerStopTimeout will be closed abruptly which may cause some client errors. thrift-0.23.0/lib/go/Makefile.in0000644000175000017500000006061015170007167016603 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_TESTS_TRUE@am__append_1 = test test/fuzz subdir = lib/go ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = . test test/fuzz am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . $(am__append_1) @GOVERSION_GE_118_FALSE@GOBUILDEXTRA = @GOVERSION_GE_118_TRUE@GOBUILDEXTRA = -buildvcs=false EXTRA_DIST = \ thrift \ coding_standards.md \ README.md all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/go/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/go/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile install: @echo '##############################################################' @echo '##############################################################' @echo 'The Go client library should be installed via "go get", please see /lib/go/README.md' @echo '##############################################################' @echo '##############################################################' # NOTE: We have to disable stdmethods in go vet until # https://github.com/golang/go/issues/52445 is fixed. check-local: $(GO) vet -stdmethods=false github.com/apache/thrift/lib/go/thrift $(GO) test -race ./thrift clean-local: $(RM) -rf pkg all-local: $(GO) build $(GOBUILDEXTRA) ./thrift distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/go/Makefile.am0000664000175000017500000000326515165535636016612 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . if WITH_TESTS SUBDIRS += test test/fuzz endif if GOVERSION_GE_118 GOBUILDEXTRA = -buildvcs=false else GOBUILDEXTRA = endif install: @echo '##############################################################' @echo '##############################################################' @echo 'The Go client library should be installed via "go get", please see /lib/go/README.md' @echo '##############################################################' @echo '##############################################################' # NOTE: We have to disable stdmethods in go vet until # https://github.com/golang/go/issues/52445 is fixed. check-local: $(GO) vet -stdmethods=false github.com/apache/thrift/lib/go/thrift $(GO) test -race ./thrift clean-local: $(RM) -rf pkg all-local: $(GO) build $(GOBUILDEXTRA) ./thrift distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ thrift \ coding_standards.md \ README.md thrift-0.23.0/lib/erl/0000755000175000017500000000000015170007201014675 5ustar00buildbuild00000000000000thrift-0.23.0/lib/erl/src/0000775000175000017500000000000015170007142015472 5ustar00buildbuild00000000000000thrift-0.23.0/lib/erl/src/thrift_binary_protocol.erl0000664000175000017500000002551415165535636023014 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_binary_protocol). -behaviour(thrift_protocol). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). -export([ new/1, new/2, read/2, write/2, flush_transport/1, close_transport/1, new_protocol_factory/2 ]). -record(binary_protocol, { transport :: term(), strict_read = true :: boolean(), strict_write = true :: boolean() }). -define(VERSION_MASK, 16#FFFF0000). -define(VERSION_1, 16#80010000). -define(TYPE_MASK, 16#000000ff). new(Transport) -> new(Transport, _Options = []). new(Transport, Options) -> State = #binary_protocol{transport = Transport}, State1 = parse_options(Options, State), thrift_protocol:new(?MODULE, State1). parse_options([], State) -> State; parse_options([{strict_read, Bool} | Rest], State) when is_boolean(Bool) -> parse_options(Rest, State#binary_protocol{strict_read = Bool}); parse_options([{strict_write, Bool} | Rest], State) when is_boolean(Bool) -> parse_options(Rest, State#binary_protocol{strict_write = Bool}). flush_transport(This = #binary_protocol{transport = Transport}) -> {NewTransport, Result} = thrift_transport:flush(Transport), {This#binary_protocol{transport = NewTransport}, Result}. close_transport(This = #binary_protocol{transport = Transport}) -> {NewTransport, Result} = thrift_transport:close(Transport), {This#binary_protocol{transport = NewTransport}, Result}. %%% %%% instance methods %%% write(This0, #protocol_message_begin{ name = Name, type = Type, seqid = Seqid }) -> case This0#binary_protocol.strict_write of true -> {This1, ok} = write(This0, {i32, ?VERSION_1 bor Type}), {This2, ok} = write(This1, {string, Name}), {This3, ok} = write(This2, {i32, Seqid}), {This3, ok}; false -> {This1, ok} = write(This0, {string, Name}), {This2, ok} = write(This1, {byte, Type}), {This3, ok} = write(This2, {i32, Seqid}), {This3, ok} end; write(This, message_end) -> {This, ok}; write(This0, #protocol_field_begin{ name = _Name, type = Type, id = Id }) -> {This1, ok} = write(This0, {byte, Type}), {This2, ok} = write(This1, {i16, Id}), {This2, ok}; write(This, field_stop) -> write(This, {byte, ?tType_STOP}); write(This, field_end) -> {This, ok}; write(This0, #protocol_map_begin{ ktype = Ktype, vtype = Vtype, size = Size }) -> {This1, ok} = write(This0, {byte, Ktype}), {This2, ok} = write(This1, {byte, Vtype}), {This3, ok} = write(This2, {i32, Size}), {This3, ok}; write(This, map_end) -> {This, ok}; write(This0, #protocol_list_begin{ etype = Etype, size = Size }) -> {This1, ok} = write(This0, {byte, Etype}), {This2, ok} = write(This1, {i32, Size}), {This2, ok}; write(This, list_end) -> {This, ok}; write(This0, #protocol_set_begin{ etype = Etype, size = Size }) -> {This1, ok} = write(This0, {byte, Etype}), {This2, ok} = write(This1, {i32, Size}), {This2, ok}; write(This, set_end) -> {This, ok}; write(This, #protocol_struct_begin{}) -> {This, ok}; write(This, struct_end) -> {This, ok}; write(This, {bool, true}) -> write(This, {byte, 1}); write(This, {bool, false}) -> write(This, {byte, 0}); write(This, {byte, Byte}) -> write(This, <>); write(This, {i16, I16}) -> write(This, <>); write(This, {i32, I32}) -> write(This, <>); write(This, {i64, I64}) -> write(This, <>); write(This, {double, Double}) -> write(This, <>); write(This0, {string, Str}) when is_list(Str) -> {This1, ok} = write(This0, {i32, length(Str)}), {This2, ok} = write(This1, list_to_binary(Str)), {This2, ok}; write(This0, {string, Bin}) when is_binary(Bin) -> {This1, ok} = write(This0, {i32, size(Bin)}), {This2, ok} = write(This1, Bin), {This2, ok}; %% Data :: iolist() write(This = #binary_protocol{transport = Trans}, Data) -> {NewTransport, Result} = thrift_transport:write(Trans, Data), {This#binary_protocol{transport = NewTransport}, Result}. %% read(This0, message_begin) -> {This1, Initial} = read(This0, ui32), case Initial of {ok, Sz} when Sz band ?VERSION_MASK =:= ?VERSION_1 -> %% we're at version 1 {This2, {ok, Name}} = read(This1, string), {This3, {ok, SeqId}} = read(This2, i32), Type = Sz band ?TYPE_MASK, {This3, #protocol_message_begin{ name = binary_to_list(Name), type = Type, seqid = SeqId }}; {ok, Sz} when Sz < 0 -> %% there's a version number but it's unexpected {This1, {error, {bad_binary_protocol_version, Sz}}}; {ok, _Sz} when This1#binary_protocol.strict_read =:= true -> %% strict_read is true and there's no version header; that's an error {This1, {error, no_binary_protocol_version}}; {ok, Sz} when This1#binary_protocol.strict_read =:= false -> %% strict_read is false, so just read the old way {This2, {ok, Name}} = read_data(This1, Sz), {This3, {ok, Type}} = read(This2, byte), {This4, {ok, SeqId}} = read(This3, i32), {This4, #protocol_message_begin{ name = binary_to_list(Name), type = Type, seqid = SeqId }}; Else -> {This1, Else} end; read(This, message_end) -> {This, ok}; read(This, struct_begin) -> {This, ok}; read(This, struct_end) -> {This, ok}; read(This0, field_begin) -> {This1, Result} = read(This0, byte), case Result of {ok, Type = ?tType_STOP} -> {This1, #protocol_field_begin{type = Type}}; {ok, Type} -> {This2, {ok, Id}} = read(This1, i16), {This2, #protocol_field_begin{ type = Type, id = Id }} end; read(This, field_end) -> {This, ok}; read(This0, map_begin) -> {This1, {ok, Ktype}} = read(This0, byte), {This2, {ok, Vtype}} = read(This1, byte), {This3, {ok, Size}} = read(This2, i32), {This3, #protocol_map_begin{ ktype = Ktype, vtype = Vtype, size = Size }}; read(This, map_end) -> {This, ok}; read(This0, list_begin) -> {This1, {ok, Etype}} = read(This0, byte), {This2, {ok, Size}} = read(This1, i32), {This2, #protocol_list_begin{ etype = Etype, size = Size }}; read(This, list_end) -> {This, ok}; read(This0, set_begin) -> {This1, {ok, Etype}} = read(This0, byte), {This2, {ok, Size}} = read(This1, i32), {This2, #protocol_set_begin{ etype = Etype, size = Size }}; read(This, set_end) -> {This, ok}; read(This0, field_stop) -> {This1, {ok, ?tType_STOP}} = read(This0, byte), {This1, ok}; %% read(This0, bool) -> {This1, Result} = read(This0, byte), case Result of {ok, Byte} -> {This1, {ok, Byte /= 0}}; Else -> {This1, Else} end; read(This0, byte) -> {This1, Bytes} = read_data(This0, 1), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; read(This0, i16) -> {This1, Bytes} = read_data(This0, 2), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; read(This0, i32) -> {This1, Bytes} = read_data(This0, 4), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; %% unsigned ints aren't used by thrift itself, but it's used for the parsing %% of the packet version header. Without this special function BEAM works fine %% but hipe thinks it received a bad version header. read(This0, ui32) -> {This1, Bytes} = read_data(This0, 4), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; read(This0, i64) -> {This1, Bytes} = read_data(This0, 8), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; read(This0, double) -> {This1, Bytes} = read_data(This0, 8), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; % returns a binary directly, call binary_to_list if necessary read(This0, string) -> {This1, {ok, Sz}} = read(This0, i32), read_data(This1, Sz). -spec read_data(#binary_protocol{}, non_neg_integer()) -> {#binary_protocol{}, {ok, binary()} | {error, _Reason}}. read_data(This, 0) -> {This, {ok, <<>>}}; read_data(This = #binary_protocol{transport = Trans}, Len) when is_integer(Len) andalso Len > 0 -> {NewTransport, Result} = thrift_transport:read(Trans, Len), {This#binary_protocol{transport = NewTransport}, Result}. %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -record(tbp_opts, { strict_read = true :: boolean(), strict_write = true :: boolean() }). parse_factory_options([], Opts) -> Opts; parse_factory_options([{strict_read, Bool} | Rest], Opts) when is_boolean(Bool) -> parse_factory_options(Rest, Opts#tbp_opts{strict_read = Bool}); parse_factory_options([{strict_write, Bool} | Rest], Opts) when is_boolean(Bool) -> parse_factory_options(Rest, Opts#tbp_opts{strict_write = Bool}). %% returns a (fun() -> thrift_protocol()) new_protocol_factory(TransportFactory, Options) -> ParsedOpts = parse_factory_options(Options, #tbp_opts{}), F = fun() -> case TransportFactory() of {ok, Transport} -> thrift_binary_protocol:new( Transport, [ {strict_read, ParsedOpts#tbp_opts.strict_read}, {strict_write, ParsedOpts#tbp_opts.strict_write} ] ); {error, Error} -> {error, Error} end end, {ok, F}. thrift-0.23.0/lib/erl/src/thrift_service.erl0000664000175000017500000000210215165535636021233 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_service). %%%========================================================================= %%% API %%%========================================================================= %% TODO Replace response with type -callback function_info(atom(), atom()) -> {struct, term()}. thrift-0.23.0/lib/erl/src/thrift_client_util.erl0000664000175000017500000001104415165535636022113 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_client_util). -export([new/4]). -export([new_multiplexed/3, new_multiplexed/4]). -type service_name() :: nonempty_string(). -type service_module() :: atom(). -type multiplexed_service_map() :: [ {ServiceName :: service_name(), ServiceModule :: service_module()} ]. %% %% Splits client options into client, protocol, and transport options %% %% split_options([Options...]) -> {ProtocolOptions, TransportOptions} %% split_options(Options) -> split_options(Options, [], []). split_options([], ProtoIn, TransIn) -> {ProtoIn, TransIn}; split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when OptKey =:= strict_read; OptKey =:= strict_write; OptKey =:= protocol -> split_options(Rest, [Opt | ProtoIn], TransIn); split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when OptKey =:= framed; OptKey =:= connect_timeout; OptKey =:= recv_timeout; OptKey =:= sockopts; OptKey =:= ssltransport; OptKey =:= ssloptions -> split_options(Rest, ProtoIn, [Opt | TransIn]). %% Client constructor for the common-case of socket transports new(Host, Port, Service, Options) when is_integer(Port), is_atom(Service), is_list(Options) -> {ProtoOpts, TransOpts0} = split_options(Options), {TransportModule, TransOpts2} = case lists:keytake(ssltransport, 1, TransOpts0) of {value, {_, true}, TransOpts1} -> {thrift_sslsocket_transport, TransOpts1}; false -> {thrift_socket_transport, TransOpts0} end, {ProtocolModule, ProtoOpts1} = case lists:keytake(protocol, 1, ProtoOpts) of {value, {_, compact}, Opts} -> {thrift_compact_protocol, Opts}; {value, {_, json}, Opts} -> {thrift_json_protocol, Opts}; {value, {_, binary}, Opts} -> {thrift_binary_protocol, Opts}; false -> {thrift_binary_protocol, ProtoOpts} end, {ok, TransportFactory} = TransportModule:new_transport_factory(Host, Port, TransOpts2), {ok, ProtocolFactory} = ProtocolModule:new_protocol_factory( TransportFactory, ProtoOpts1 ), case ProtocolFactory() of {ok, Protocol} -> thrift_client:new(Protocol, Service); {error, Error} -> {error, Error} end. -spec new_multiplexed(Host, Port, Services, Options) -> {ok, ServiceThriftClientList} when Host :: nonempty_string(), Port :: non_neg_integer(), Services :: multiplexed_service_map(), Options :: list(), ServiceThriftClientList :: [{ServiceName :: list(), ThriftClient :: term()}]. new_multiplexed(Host, Port, Services, Options) when is_integer(Port), is_list(Services), is_list(Options) -> new_multiplexed( thrift_socket_transport:new_transport_factory(Host, Port, Options), Services, Options ). -spec new_multiplexed(TransportFactoryTuple, Services, Options) -> {ok, ServiceThriftClientList} when TransportFactoryTuple :: {ok, TransportFactory :: term()}, Services :: multiplexed_service_map(), Options :: list(), ServiceThriftClientList :: [{ServiceName :: service_name(), ThriftClient :: term()}]. new_multiplexed(TransportFactoryTuple, Services, Options) when is_list(Services), is_list(Options), is_tuple(TransportFactoryTuple) -> {ProtoOpts, _} = split_options(Options), {ok, TransportFactory} = TransportFactoryTuple, {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory( TransportFactory, ProtoOpts ), {ok, Protocol} = ProtocolFactory(), {ok, [ {ServiceName, element( 2, thrift_client:new( element(2, thrift_multiplexed_protocol:new(Protocol, ServiceName)), Service ) )} || {ServiceName, Service} <- Services ]}. thrift-0.23.0/lib/erl/src/thrift_protocol.erl0000664000175000017500000003662215165535636021452 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_protocol). -export([ new/2, write/2, read/2, read/3, skip/2, flush_transport/1, close_transport/1, typeid_to_atom/1 ]). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). -record(protocol, { module :: module(), data :: term() }). %%%========================================================================= %%% API %%%========================================================================= -type state() :: term(). -export_type([state/0]). -type reason() :: term(). -export_type([reason/0]). %% NOTE: keep this in sync with read/2 spec -callback read (state(), {struct, _Info}) -> {state(), {ok, tuple()} | {error, reason()}}; (state(), tprot_cont_tag()) -> {state(), {ok, any()} | {error, reason()}}; (state(), tprot_empty_tag()) -> {state(), ok | {error, reason()}}; (state(), tprot_header_tag()) -> {state(), tprot_header_val() | {error, reason()}}; (state(), tprot_data_tag()) -> {state(), {ok, any()} | {error, reason()}}. -callback write(state(), any()) -> {state(), ok | {error, reason()}}. -callback flush_transport(state()) -> {state(), ok | {error, reason()}}. -callback close_transport(state()) -> {state(), ok | {error, reason()}}. new(Module, Data) when is_atom(Module) -> {ok, #protocol{ module = Module, data = Data }}. -spec flush_transport(#protocol{}) -> {#protocol{}, ok}. flush_transport( Proto = #protocol{ module = Module, data = Data } ) -> {NewData, Result} = Module:flush_transport(Data), {Proto#protocol{data = NewData}, Result}. -spec close_transport(#protocol{}) -> ok. close_transport(#protocol{ module = Module, data = Data }) -> Module:close_transport(Data). typeid_to_atom(?tType_STOP) -> field_stop; typeid_to_atom(?tType_VOID) -> void; typeid_to_atom(?tType_BOOL) -> bool; typeid_to_atom(?tType_DOUBLE) -> double; typeid_to_atom(?tType_I8) -> byte; typeid_to_atom(?tType_I16) -> i16; typeid_to_atom(?tType_I32) -> i32; typeid_to_atom(?tType_I64) -> i64; typeid_to_atom(?tType_STRING) -> string; typeid_to_atom(?tType_STRUCT) -> struct; typeid_to_atom(?tType_MAP) -> map; typeid_to_atom(?tType_SET) -> set; typeid_to_atom(?tType_LIST) -> list. term_to_typeid(void) -> ?tType_VOID; term_to_typeid(bool) -> ?tType_BOOL; term_to_typeid(byte) -> ?tType_I8; term_to_typeid(double) -> ?tType_DOUBLE; term_to_typeid(i8) -> ?tType_I8; term_to_typeid(i16) -> ?tType_I16; term_to_typeid(i32) -> ?tType_I32; term_to_typeid(i64) -> ?tType_I64; term_to_typeid(string) -> ?tType_STRING; term_to_typeid({struct, _}) -> ?tType_STRUCT; term_to_typeid({map, _, _}) -> ?tType_MAP; term_to_typeid({set, _}) -> ?tType_SET; term_to_typeid({list, _}) -> ?tType_LIST. %% Structure is like: %% [{Fid, Type}, ...] -spec read(#protocol{}, {struct, _StructDef}, atom()) -> {#protocol{}, {ok, tuple()}}. read(IProto0, {struct, Structure}, Tag) when is_list(Structure), is_atom(Tag) -> % If we want a tagged tuple, we need to offset all the tuple indices % by 1 to avoid overwriting the tag. Offset = if Tag =/= undefined -> 1; true -> 0 end, IndexList = case length(Structure) of N when N > 0 -> lists:seq(1 + Offset, N + Offset); _ -> [] end, SWithIndices = [ {Fid, {Type, Index}} || {{Fid, Type}, Index} <- lists:zip(Structure, IndexList) ], % Fid -> {Type, Index} SDict = dict:from_list(SWithIndices), {IProto1, ok} = read(IProto0, struct_begin), RTuple0 = erlang:make_tuple(length(Structure) + Offset, undefined), RTuple1 = if Tag =/= undefined -> setelement(1, RTuple0, Tag); true -> RTuple0 end, {IProto2, RTuple2} = read_struct_loop(IProto1, SDict, RTuple1), {IProto2, {ok, RTuple2}}. %% NOTE: Keep this in sync with read callback -spec read (#protocol{}, {struct, _Info}) -> {#protocol{}, {ok, tuple()} | {error, _Reason}}; (#protocol{}, tprot_cont_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}}; (#protocol{}, tprot_empty_tag()) -> {#protocol{}, ok | {error, _Reason}}; (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}}; (#protocol{}, tprot_data_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}}. read(IProto, {struct, {Module, StructureName}}) when is_atom(Module), is_atom(StructureName) -> read(IProto, Module:struct_info(StructureName), StructureName); read(IProto, S = {struct, Structure}) when is_list(Structure) -> read(IProto, S, undefined); read(IProto0, {list, Type}) -> {IProto1, #protocol_list_begin{etype = EType, size = Size}} = read(IProto0, list_begin), {EType, EType} = {term_to_typeid(Type), EType}, {List, IProto2} = lists:mapfoldl( fun(_, ProtoS0) -> {ProtoS1, {ok, Item}} = read(ProtoS0, Type), {Item, ProtoS1} end, IProto1, lists:duplicate(Size, 0) ), {IProto3, ok} = read(IProto2, list_end), {IProto3, {ok, List}}; read(IProto0, {map, KeyType, ValType}) -> {IProto1, #protocol_map_begin{size = Size, ktype = KType, vtype = VType}} = read(IProto0, map_begin), _ = case Size of 0 -> 0; _ -> {KType, KType} = {term_to_typeid(KeyType), KType}, {VType, VType} = {term_to_typeid(ValType), VType} end, {List, IProto2} = lists:mapfoldl( fun(_, ProtoS0) -> {ProtoS1, {ok, Key}} = read(ProtoS0, KeyType), {ProtoS2, {ok, Val}} = read(ProtoS1, ValType), {{Key, Val}, ProtoS2} end, IProto1, lists:duplicate(Size, 0) ), {IProto3, ok} = read(IProto2, map_end), {IProto3, {ok, dict:from_list(List)}}; read(IProto0, {set, Type}) -> {IProto1, #protocol_set_begin{etype = EType, size = Size}} = read(IProto0, set_begin), {EType, EType} = {term_to_typeid(Type), EType}, {List, IProto2} = lists:mapfoldl( fun(_, ProtoS0) -> {ProtoS1, {ok, Item}} = read(ProtoS0, Type), {Item, ProtoS1} end, IProto1, lists:duplicate(Size, 0) ), {IProto3, ok} = read(IProto2, set_end), {IProto3, {ok, sets:from_list(List)}}; read(Protocol, ProtocolType) -> read_specific(Protocol, ProtocolType). %% NOTE: Keep this in sync with read/2 spec -spec read_specific (#protocol{}, {struct, _Info}) -> {#protocol{}, {ok, tuple()} | {error, _Reason}}; (#protocol{}, tprot_cont_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}}; (#protocol{}, tprot_empty_tag()) -> {#protocol{}, ok | {error, _Reason}}; (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}}; (#protocol{}, tprot_data_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}}. read_specific( Proto = #protocol{ module = Module, data = ModuleData }, ProtocolType ) -> {NewData, Result} = Module:read(ModuleData, ProtocolType), {Proto#protocol{data = NewData}, Result}. read_struct_loop(IProto0, SDict, RTuple) -> {IProto1, #protocol_field_begin{type = FType, id = Fid}} = thrift_protocol:read(IProto0, field_begin), case {FType, Fid} of {?tType_STOP, _} -> {IProto2, ok} = read(IProto1, struct_end), {IProto2, RTuple}; _Else -> case dict:find(Fid, SDict) of {ok, {Type, Index}} -> case term_to_typeid(Type) of FType -> {IProto2, {ok, Val}} = read(IProto1, Type), {IProto3, ok} = thrift_protocol:read(IProto2, field_end), NewRTuple = setelement(Index, RTuple, Val), read_struct_loop(IProto3, SDict, NewRTuple); Expected -> error_logger:info_msg( "Skipping field ~p with wrong type (~p != ~p)~n", [Fid, FType, Expected] ), skip_field(FType, IProto1, SDict, RTuple) end; _Else2 -> skip_field(FType, IProto1, SDict, RTuple) end end. skip_field(FType, IProto0, SDict, RTuple) -> {IProto1, ok} = skip(IProto0, typeid_to_atom(FType)), {IProto2, ok} = read(IProto1, field_end), read_struct_loop(IProto2, SDict, RTuple). -spec skip(#protocol{}, atom()) -> {#protocol{}, ok}. skip(Proto0, struct) -> {Proto1, ok} = read(Proto0, struct_begin), {Proto2, ok} = skip_struct_loop(Proto1), {Proto3, ok} = read(Proto2, struct_end), {Proto3, ok}; skip(Proto0, map) -> {Proto1, Map} = read(Proto0, map_begin), {Proto2, ok} = skip_map_loop(Proto1, Map), {Proto3, ok} = read(Proto2, map_end), {Proto3, ok}; skip(Proto0, set) -> {Proto1, Set} = read(Proto0, set_begin), {Proto2, ok} = skip_set_loop(Proto1, Set), {Proto3, ok} = read(Proto2, set_end), {Proto3, ok}; skip(Proto0, list) -> {Proto1, List} = read(Proto0, list_begin), {Proto2, ok} = skip_list_loop(Proto1, List), {Proto3, ok} = read(Proto2, list_end), {Proto3, ok}; skip(Proto0, Type) when is_atom(Type) -> {Proto1, _Ignore} = read(Proto0, Type), {Proto1, ok}. skip_struct_loop(Proto0) -> {Proto1, #protocol_field_begin{type = Type}} = read(Proto0, field_begin), case Type of ?tType_STOP -> {Proto1, ok}; _Else -> {Proto2, ok} = skip(Proto1, typeid_to_atom(Type)), {Proto3, ok} = read(Proto2, field_end), skip_struct_loop(Proto3) end. skip_map_loop( Proto0, Map = #protocol_map_begin{ ktype = Ktype, vtype = Vtype, size = Size } ) -> case Size of N when N > 0 -> {Proto1, ok} = skip(Proto0, typeid_to_atom(Ktype)), {Proto2, ok} = skip(Proto1, typeid_to_atom(Vtype)), skip_map_loop( Proto2, Map#protocol_map_begin{size = Size - 1} ); 0 -> {Proto0, ok} end. skip_set_loop( Proto0, Map = #protocol_set_begin{ etype = Etype, size = Size } ) -> case Size of N when N > 0 -> {Proto1, ok} = skip(Proto0, typeid_to_atom(Etype)), skip_set_loop( Proto1, Map#protocol_set_begin{size = Size - 1} ); 0 -> {Proto0, ok} end. skip_list_loop( Proto0, Map = #protocol_list_begin{ etype = Etype, size = Size } ) -> case Size of N when N > 0 -> {Proto1, ok} = skip(Proto0, typeid_to_atom(Etype)), skip_list_loop( Proto1, Map#protocol_list_begin{size = Size - 1} ); 0 -> {Proto0, ok} end. %%-------------------------------------------------------------------- %% Function: write(OProto, {Type, Data}) -> ok %% %% Type = {struct, StructDef} | %% {list, Type} | %% {map, KeyType, ValType} | %% {set, Type} | %% BaseType %% %% Data = %% tuple() -- for struct %% | list() -- for list %% | dictionary() -- for map %% | set() -- for set %% | any() -- for base types %% %% Description: %%-------------------------------------------------------------------- -spec write(#protocol{}, any()) -> {#protocol{}, ok | {error, _Reason}}. write(Proto0, {{struct, StructDef}, Data}) when is_list(StructDef), is_tuple(Data), length(StructDef) == size(Data) - 1 -> [StructName | Elems] = tuple_to_list(Data), {Proto1, ok} = write(Proto0, #protocol_struct_begin{name = StructName}), {Proto2, ok} = struct_write_loop(Proto1, StructDef, Elems), {Proto3, ok} = write(Proto2, struct_end), {Proto3, ok}; write(Proto, {{struct, {Module, StructureName}}, Data}) when is_atom(Module), is_atom(StructureName), element(1, Data) =:= StructureName -> write(Proto, {Module:struct_info(StructureName), Data}); write(_, {{struct, {Module, StructureName}}, Data}) when is_atom(Module), is_atom(StructureName) -> erlang:error(struct_unmatched, {{provided, element(1, Data)}, {expected, StructureName}}); write(Proto0, {{list, Type}, Data}) when is_list(Data) -> {Proto1, ok} = write( Proto0, #protocol_list_begin{ etype = term_to_typeid(Type), size = length(Data) } ), Proto2 = lists:foldl( fun(Elem, ProtoIn) -> {ProtoOut, ok} = write(ProtoIn, {Type, Elem}), ProtoOut end, Proto1, Data ), {Proto3, ok} = write(Proto2, list_end), {Proto3, ok}; write(Proto0, {{map, KeyType, ValType}, Data}) -> {Proto1, ok} = write( Proto0, #protocol_map_begin{ ktype = term_to_typeid(KeyType), vtype = term_to_typeid(ValType), size = dict:size(Data) } ), Proto2 = dict:fold( fun(KeyData, ValData, ProtoS0) -> {ProtoS1, ok} = write(ProtoS0, {KeyType, KeyData}), {ProtoS2, ok} = write(ProtoS1, {ValType, ValData}), ProtoS2 end, Proto1, Data ), {Proto3, ok} = write(Proto2, map_end), {Proto3, ok}; write(Proto0, {{set, Type}, Data}) -> true = sets:is_set(Data), {Proto1, ok} = write( Proto0, #protocol_set_begin{ etype = term_to_typeid(Type), size = sets:size(Data) } ), Proto2 = sets:fold( fun(Elem, ProtoIn) -> {ProtoOut, ok} = write(ProtoIn, {Type, Elem}), ProtoOut end, Proto1, Data ), {Proto3, ok} = write(Proto2, set_end), {Proto3, ok}; write( Proto = #protocol{ module = Module, data = ModuleData }, Data ) -> {NewData, Result} = Module:write(ModuleData, Data), {Proto#protocol{data = NewData}, Result}. struct_write_loop(Proto0, [{Fid, Type} | RestStructDef], [Data | RestData]) -> NewProto = case Data of undefined -> % null fields are skipped in response Proto0; _ -> {Proto1, ok} = write( Proto0, #protocol_field_begin{ type = term_to_typeid(Type), id = Fid } ), {Proto2, ok} = write(Proto1, {Type, Data}), {Proto3, ok} = write(Proto2, field_end), Proto3 end, struct_write_loop(NewProto, RestStructDef, RestData); struct_write_loop(Proto, [], []) -> write(Proto, field_stop). thrift-0.23.0/lib/erl/src/thrift_processor.erl0000664000175000017500000002310215165535636021615 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_processor). -export([init/1]). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). -record(thrift_processor, { handler :: module() | thrift_multiplexed_map_wrapper:service_handler_map(), protocol :: term(), service :: atom() | thrift_multiplexed_map_wrapper:service_handler_map() }). init({_Server, ProtoGen, Service, Handler}) when is_function(ProtoGen, 0) -> {ok, Proto} = ProtoGen(), loop(#thrift_processor{ protocol = Proto, service = Service, handler = Handler }). loop( State0 = #thrift_processor{ protocol = Proto0, handler = Handler, service = Service } ) -> {Proto1, MessageBegin} = thrift_protocol:read(Proto0, message_begin), State1 = State0#thrift_processor{protocol = Proto1}, ErrorHandler = fun (HandlerModules) when is_list(HandlerModules) -> thrift_multiplexed_map_wrapper:fetch(?MULTIPLEXED_ERROR_HANDLER_KEY, HandlerModules); (HandlerModule) -> HandlerModule end, case MessageBegin of #protocol_message_begin{ name = Function, type = Type, seqid = Seqid } when Type =:= ?tMessageType_CALL; Type =:= ?tMessageType_ONEWAY -> case string:tokens(Function, ?MULTIPLEXED_SERVICE_SEPARATOR) of [ServiceName, FunctionName] -> ServiceModule = thrift_multiplexed_map_wrapper:fetch(ServiceName, Service), ServiceHandler = thrift_multiplexed_map_wrapper:fetch(ServiceName, Handler), case handle_function( State1#thrift_processor{ service = ServiceModule, handler = ServiceHandler }, list_to_existing_atom(FunctionName), Seqid ) of {State2, ok} -> loop(State2#thrift_processor{service = Service, handler = Handler}); {_State2, {error, Reason}} -> apply(ErrorHandler(Handler), handle_error, [ list_to_existing_atom(Function), Reason ]), thrift_protocol:close_transport(Proto1), ok end; _ -> case handle_function(State1, list_to_existing_atom(Function), Seqid) of {State2, ok} -> loop(State2); {_State2, {error, Reason}} -> apply(ErrorHandler(Handler), handle_error, [ list_to_existing_atom(Function), Reason ]), thrift_protocol:close_transport(Proto1), ok end end; {error, timeout = Reason} -> apply(ErrorHandler(Handler), handle_error, [undefined, Reason]), thrift_protocol:close_transport(Proto1), ok; {error, closed = Reason} -> %% error_logger:info_msg("Client disconnected~n"), apply(ErrorHandler(Handler), handle_error, [undefined, Reason]), thrift_protocol:close_transport(Proto1), exit(shutdown); {error, Reason} -> apply(ErrorHandler(Handler), handle_error, [undefined, Reason]), thrift_protocol:close_transport(Proto1), exit(shutdown) end. handle_function( State0 = #thrift_processor{ protocol = Proto0, handler = Handler, service = Service }, Function, Seqid ) -> InParams = Service:function_info(Function, params_type), {Proto1, {ok, Params}} = thrift_protocol:read(Proto0, InParams), State1 = State0#thrift_processor{protocol = Proto1}, try Result = Handler:handle_function(Function, Params), %% {Micro, Result} = better_timer(Handler, handle_function, [Function, Params]), %% error_logger:info_msg("Processed ~p(~p) in ~.4fms~n", %% [Function, Params, Micro/1000.0]), handle_success(State1, Function, Result, Seqid) catch Type:Data:Stack when Type =:= throw orelse Type =:= error -> handle_function_catch(State1, Function, Type, Data, Seqid, Stack) end. handle_function_catch( State = #thrift_processor{service = Service}, Function, ErrType, ErrData, Seqid, Stack ) -> IsOneway = Service:function_info(Function, reply_type) =:= oneway_void, case {ErrType, ErrData} of _ when IsOneway -> error_logger:warning_msg( "oneway void ~p threw error which must be ignored: ~p", [Function, {ErrType, ErrData, Stack}] ), {State, ok}; {throw, Exception} when is_tuple(Exception), size(Exception) > 0 -> %error_logger:warning_msg("~p threw exception: ~p~n", [Function, Exception]), handle_exception(State, Function, Exception, Seqid, Stack); % we still want to accept more requests from this client {error, Error} -> handle_error(State, Function, Error, Seqid, Stack) end. handle_success( State = #thrift_processor{service = Service}, Function, Result, Seqid ) -> ReplyType = Service:function_info(Function, reply_type), StructName = atom_to_list(Function) ++ "_result", case Result of {reply, ReplyData} -> Reply = {{struct, [{0, ReplyType}]}, {StructName, ReplyData}}, send_reply(State, Function, ?tMessageType_REPLY, Reply, Seqid); ok when ReplyType == {struct, []} -> send_reply(State, Function, ?tMessageType_REPLY, {ReplyType, {StructName}}, Seqid); ok when ReplyType == oneway_void -> %% no reply for oneway void {State, ok} end. handle_exception( State = #thrift_processor{service = Service}, Function, Exception, Seqid, Stack ) -> ExceptionType = element(1, Exception), %% Fetch a structure like {struct, [{-2, {struct, {Module, Type}}}, %% {-3, {struct, {Module, Type}}}]} ReplySpec = Service:function_info(Function, exceptions), {struct, XInfo} = ReplySpec, true = is_list(XInfo), %% Assuming we had a type1 exception, we'd get: [undefined, Exception, undefined] %% e.g.: [{-1, type0}, {-2, type1}, {-3, type2}] ExceptionList = [ case Type of ExceptionType -> Exception; _ -> undefined end || {_Fid, {struct, {_Module, Type}}} <- XInfo ], ExceptionTuple = list_to_tuple([Function | ExceptionList]), % Make sure we got at least one defined case lists:all(fun(X) -> X =:= undefined end, ExceptionList) of true -> handle_unknown_exception(State, Function, Exception, Seqid, Stack); false -> send_reply(State, Function, ?tMessageType_REPLY, {ReplySpec, ExceptionTuple}, Seqid) end. %% %% Called when an exception has been explicitly thrown by the service, but it was %% not one of the exceptions that was defined for the function. %% handle_unknown_exception(State, Function, Exception, Seqid, Stack) -> handle_error(State, Function, {exception_not_declared_as_thrown, Exception}, Seqid, Stack). handle_error(State, Function, Error, Seqid, Stack) -> error_logger:error_msg("~p had an error: ~p~n", [Function, {Error, Stack}]), Message = case application:get_env(thrift, exceptions_include_traces) of {ok, true} -> lists:flatten( io_lib:format( "An error occurred: ~p~n", [{Error, Stack}] ) ); _ -> "An unknown handler error occurred." end, Reply = {?TApplicationException_Structure, #'TApplicationException'{ message = Message, type = ?TApplicationException_UNKNOWN }}, send_reply(State, Function, ?tMessageType_EXCEPTION, Reply, Seqid). send_reply(State = #thrift_processor{protocol = Proto0}, Function, ReplyMessageType, Reply, Seqid) -> try {Proto1, ok} = thrift_protocol:write(Proto0, #protocol_message_begin{ name = atom_to_list(Function), type = ReplyMessageType, seqid = Seqid }), {Proto2, ok} = thrift_protocol:write(Proto1, Reply), {Proto3, ok} = thrift_protocol:write(Proto2, message_end), {Proto4, ok} = thrift_protocol:flush_transport(Proto3), {State#thrift_processor{protocol = Proto4}, ok} catch error:{badmatch, {_, {error, _} = Error}} -> {State, Error} end. thrift-0.23.0/lib/erl/src/thrift_file_transport.erl0000664000175000017500000000627315165535636022643 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_file_transport). -behaviour(thrift_transport). %% constructors -export([new/1, new/2]). %% protocol callbacks -export([read/2, read_exact/2, write/2, flush/1, close/1]). %% legacy api -export([new_reader/1]). -record(t_file, { device :: file:io_device(), should_close = true :: boolean(), mode = write :: file:mode() }). -spec new(Device :: file:io_device()) -> {ok, thrift_transport:t_transport()}. new(Device) -> new(Device, []). -spec new(Device :: file:io_device(), Opts :: list()) -> {ok, thrift_transport:t_transport()}. %% Device should be opened in raw and binary mode. new(Device, Opts) when is_list(Opts) -> State = parse_opts(Opts, #t_file{device = Device}), thrift_transport:new(?MODULE, State). parse_opts([{should_close, Bool} | Rest], State) when is_boolean(Bool) -> parse_opts(Rest, State#t_file{should_close = Bool}); parse_opts([{mode, Mode} | Rest], State) when Mode =:= write; Mode =:= read -> parse_opts(Rest, State#t_file{mode = Mode}); parse_opts([], State) -> State. read(State = #t_file{device = Device, mode = read}, Len) when is_integer(Len), Len >= 0 -> case file:read(Device, Len) of eof -> {State, {error, eof}}; {ok, Result} -> {State, {ok, iolist_to_binary(Result)}} end; read(State, _) -> {State, {error, write_mode}}. read_exact(State = #t_file{device = Device, mode = read}, Len) when is_integer(Len), Len >= 0 -> case file:read(Device, Len) of eof -> {State, {error, eof}}; {ok, Result} -> case iolist_size(Result) of X when X < Len -> {State, {error, eof}}; _ -> {State, {ok, iolist_to_binary(Result)}} end end; read_exact(State, _) -> {State, {error, write_mode}}. write(State = #t_file{device = Device, mode = write}, Data) -> {State, file:write(Device, Data)}; write(State, _) -> {State, {error, read_mode}}. flush(State = #t_file{device = Device, mode = write}) -> {State, file:sync(Device)}. close(State = #t_file{device = Device, should_close = SC}) -> case SC of true -> {State, file:close(Device)}; false -> {State, ok} end. %% legacy api. left for compatibility new_reader(Filename) -> case file:open(Filename, [read, binary, {read_ahead, 1024 * 1024}]) of {ok, IODevice} -> new(IODevice, [{should_close, true}, {mode, read}]); Error -> Error end. thrift-0.23.0/lib/erl/src/thrift_multiplexed_map_wrapper.erl0000664000175000017500000000351215165535636024532 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_multiplexed_map_wrapper). -export([ new/0, store/3, find/2, fetch/2 ]). -type service_handler() :: nonempty_string(). -type service_handler_map() :: orddict:orddict(service_handler(), [module()]). -export_type([service_handler_map/0]). -spec new() -> service_handler_map(). new() -> orddict:new(). -spec store(ServiceHandler, Module, Map) -> NewMap when ServiceHandler :: service_handler(), Module :: module(), Map :: service_handler_map(), NewMap :: service_handler_map(). store(ServiceHandler, Module, Map) -> orddict:store(ServiceHandler, Module, Map). -spec find(ServiceHandler, Map) -> {ok, Module} | error when ServiceHandler :: service_handler(), Module :: module(), Map :: service_handler_map(). find(ServiceHandler, Map) -> orddict:find(ServiceHandler, Map). -spec fetch(ServiceHandler, Map) -> Module when ServiceHandler :: service_handler(), Module :: module(), Map :: service_handler_map(). fetch(ServiceHandler, Map) -> orddict:fetch(ServiceHandler, Map). thrift-0.23.0/lib/erl/src/thrift_base64_transport.erl0000664000175000017500000000423215165535636023001 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_base64_transport). -behaviour(thrift_transport). %% API -export([new/1, new_transport_factory/1]). %% thrift_transport callbacks -export([write/2, read/2, flush/1, close/1]). %% State -record(b64_transport, { wrapped :: thrift_transport:t_transport() }). new(Wrapped) -> State = #b64_transport{wrapped = Wrapped}, thrift_transport:new(?MODULE, State). write(This = #b64_transport{wrapped = Wrapped}, Data) -> {NewWrapped, Result} = thrift_transport:write(Wrapped, base64:encode(iolist_to_binary(Data))), {This#b64_transport{wrapped = NewWrapped}, Result}. %% base64 doesn't support reading quite yet since it would involve %% nasty buffering and such read(This = #b64_transport{}, _Data) -> {This, {error, no_reads_allowed}}. flush(This = #b64_transport{wrapped = Wrapped0}) -> {Wrapped1, ok} = thrift_transport:write(Wrapped0, <<"\n">>), {Wrapped2, ok} = thrift_transport:flush(Wrapped1), {This#b64_transport{wrapped = Wrapped2}, ok}. close(This0) -> {This1 = #b64_transport{wrapped = Wrapped}, ok} = flush(This0), {NewWrapped, ok} = thrift_transport:close(Wrapped), {This1#b64_transport{wrapped = NewWrapped}, ok}. %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% new_transport_factory(WrapFactory) -> F = fun() -> {ok, Wrapped} = WrapFactory(), new(Wrapped) end, {ok, F}. thrift-0.23.0/lib/erl/src/thrift_buffered_transport.erl0000664000175000017500000000564615165535636023511 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_buffered_transport). -behaviour(thrift_transport). %% constructor -export([new/1]). %% protocol callbacks -export([read/2, read_exact/2, write/2, flush/1, close/1]). %% legacy api -export([new_transport_factory/1]). -record(t_buffered, { wrapped :: thrift_transport:t_transport(), write_buffer :: iodata() }). -spec new(Transport :: thrift_transport:t_transport()) -> {ok, thrift_transport:t_transport()}. new(Wrapped) -> State = #t_buffered{ wrapped = Wrapped, write_buffer = [] }, thrift_transport:new(?MODULE, State). %% reads data through from the wrapped transport read(State = #t_buffered{wrapped = Wrapped}, Len) when is_integer(Len), Len >= 0 -> {NewState, Response} = thrift_transport:read(Wrapped, Len), {State#t_buffered{wrapped = NewState}, Response}. %% reads data through from the wrapped transport read_exact(State = #t_buffered{wrapped = Wrapped}, Len) when is_integer(Len), Len >= 0 -> {NewState, Response} = thrift_transport:read_exact(Wrapped, Len), {State#t_buffered{wrapped = NewState}, Response}. write(State = #t_buffered{write_buffer = Buffer}, Data) -> {State#t_buffered{write_buffer = [Buffer, Data]}, ok}. flush(State = #t_buffered{wrapped = Wrapped, write_buffer = Buffer}) -> case iolist_size(Buffer) of %% if write buffer is empty, do nothing 0 -> {State, ok}; _ -> {Written, Response} = thrift_transport:write(Wrapped, Buffer), {Flushed, ok} = thrift_transport:flush(Written), {State#t_buffered{wrapped = Flushed, write_buffer = []}, Response} end. close(State = #t_buffered{wrapped = Wrapped}) -> {Closed, Result} = thrift_transport:close(Wrapped), {State#t_buffered{wrapped = Closed}, Result}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% new_transport_factory(WrapFactory) -> F = fun() -> {ok, Wrapped} = WrapFactory(), new(Wrapped) end, {ok, F}. thrift-0.23.0/lib/erl/src/thrift_json_parser.erl0000664000175000017500000004657015165535636022141 0ustar00buildbuild00000000000000%% Licensed to the Apache Software Foundation (ASF) under one %% or more contributor license agreements. See the NOTICE file %% distributed with this work for additional information %% regarding copyright ownership. The ASF licenses this file %% to you under the Apache License, Version 2.0 (the %% "License"); you may not use this file except in compliance %% with the License. You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% %% The json parser implementation was created by %% alisdair sullivan based on %% the jsx json library -module(thrift_json_parser). -export([parser/0, handle_event/2]). -record(config, {strict_utf8 = false :: boolean()}). parser() -> fun(JSON) -> start(JSON, {?MODULE, []}, [], #config{}) end. handle_event(Event, {Handler, State}, _Config) -> {Handler, Handler:handle_event(Event, State)}. handle_event(end_json, State) -> lists:reverse([end_json] ++ State); handle_event(Event, State) -> [Event] ++ State. %% whitespace -define(space, 16#20). -define(tab, 16#09). -define(cr, 16#0D). -define(newline, 16#0A). %% object delimiters -define(start_object, 16#7B). -define(end_object, 16#7D). %% array delimiters -define(start_array, 16#5B). -define(end_array, 16#5D). %% kv seperator -define(comma, 16#2C). -define(doublequote, 16#22). -define(singlequote, 16#27). -define(colon, 16#3A). %% string escape sequences -define(rsolidus, 16#5C). -define(solidus, 16#2F). %% math -define(zero, 16#30). -define(decimalpoint, 16#2E). -define(negative, 16#2D). -define(positive, 16#2B). %% comments -define(star, 16#2A). %% some useful guards -define(is_hex(Symbol), (Symbol >= $a andalso Symbol =< $f) orelse (Symbol >= $A andalso Symbol =< $F) orelse (Symbol >= $0 andalso Symbol =< $9) ). -define(is_nonzero(Symbol), Symbol >= $1 andalso Symbol =< $9 ). -define(is_whitespace(Symbol), Symbol =:= ?space; Symbol =:= ?tab; Symbol =:= ?cr; Symbol =:= ?newline ). %% lists are benchmarked to be faster (tho higher in memory usage) than binaries new_seq() -> []. new_seq(C) -> [C]. acc_seq(Seq, C) when is_list(C) -> lists:reverse(C) ++ Seq; acc_seq(Seq, C) -> [C] ++ Seq. end_seq(Seq) -> unicode:characters_to_binary(lists:reverse(Seq)). end_seq(Seq, _) -> end_seq(Seq). start(<<16#ef, 16#bb, 16#bf, Rest/binary>>, Handler, Stack, Config) -> value(Rest, Handler, Stack, Config); start(Bin, Handler, Stack, Config) -> value(Bin, Handler, Stack, Config). value(<>, Handler, Stack, Config) -> string(Rest, Handler, new_seq(), Stack, Config); value(<<$t, Rest/binary>>, Handler, Stack, Config) -> true(Rest, Handler, Stack, Config); value(<<$f, Rest/binary>>, Handler, Stack, Config) -> false(Rest, Handler, Stack, Config); value(<<$n, Rest/binary>>, Handler, Stack, Config) -> null(Rest, Handler, Stack, Config); value(<>, Handler, Stack, Config) -> negative(Rest, Handler, new_seq($-), Stack, Config); value(<>, Handler, Stack, Config) -> zero(Rest, Handler, new_seq($0), Stack, Config); value(<>, Handler, Stack, Config) when ?is_nonzero(S) -> integer(Rest, Handler, new_seq(S), Stack, Config); value(<>, Handler, Stack, Config) -> object(Rest, handle_event(start_object, Handler, Config), [key | Stack], Config); value(<>, Handler, Stack, Config) -> array(Rest, handle_event(start_array, Handler, Config), [array | Stack], Config); value(<>, Handler, Stack, Config) when ?is_whitespace(S) -> value(Rest, Handler, Stack, Config); value(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). object(<>, Handler, Stack, Config) -> string(Rest, Handler, new_seq(), Stack, Config); object(<>, Handler, [key | Stack], Config) -> maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config); object(<>, Handler, Stack, Config) when ?is_whitespace(S) -> object(Rest, Handler, Stack, Config); object(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). array(<>, Handler, [array | Stack], Config) -> maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config); array(<>, Handler, Stack, Config) when ?is_whitespace(S) -> array(Rest, Handler, Stack, Config); array(Bin, Handler, Stack, Config) -> value(Bin, Handler, Stack, Config). colon(<>, Handler, [key | Stack], Config) -> value(Rest, Handler, [object | Stack], Config); colon(<>, Handler, Stack, Config) when ?is_whitespace(S) -> colon(Rest, Handler, Stack, Config); colon(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). key(<>, Handler, Stack, Config) -> string(Rest, Handler, new_seq(), Stack, Config); key(<>, Handler, Stack, Config) when ?is_whitespace(S) -> key(Rest, Handler, Stack, Config); key(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). %% note that if you encounter an error from string and you can't find the clause that %% caused it here, it might be in unescape below string(<>, Handler, Acc, Stack, Config) -> doublequote(Rest, Handler, Acc, Stack, Config); string(<>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, ?solidus), Stack, Config); string(<>, Handler, Acc, Stack, Config) -> unescape(Rest, Handler, Acc, Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#20, X < 16#2028 -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X == 16#2028; X == 16#2029 -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X > 16#2029, X < 16#d800 -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X > 16#dfff, X < 16#fdd0 -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X > 16#fdef, X < 16#fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#10000, X < 16#1fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#20000, X < 16#2fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#30000, X < 16#3fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#40000, X < 16#4fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#50000, X < 16#5fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#60000, X < 16#6fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#70000, X < 16#7fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#80000, X < 16#8fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#90000, X < 16#9fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#a0000, X < 16#afffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#b0000, X < 16#bfffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#c0000, X < 16#cfffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#d0000, X < 16#dfffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#e0000, X < 16#efffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#f0000, X < 16#ffffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); string(<>, Handler, Acc, Stack, Config) when X >= 16#100000, X < 16#10fffe -> string(Rest, Handler, acc_seq(Acc, X), Stack, Config); %% surrogates string(<<237, X, _, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when X >= 160 -> string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config); %% u+xfffe, u+xffff, control codes and other noncharacters string(<<_/utf8, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) -> string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config); %% u+fffe and u+ffff for R14BXX (subsequent runtimes will happily match the %% preceding clause string( <<239, 191, X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false} ) when X == 190; X == 191 -> string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config); %% overlong encodings and missing continuations of a 2 byte sequence string(<>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when X >= 192, X =< 223 -> strip_continuations(Rest, Handler, Acc, Stack, Config, 1); %% overlong encodings and missing continuations of a 3 byte sequence string(<>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when X >= 224, X =< 239 -> strip_continuations(Rest, Handler, Acc, Stack, Config, 2); %% overlong encodings and missing continuations of a 4 byte sequence string(<>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when X >= 240, X =< 247 -> strip_continuations(Rest, Handler, Acc, Stack, Config, 3); %% incompletes and unexpected bytes, including orphan continuations string(<<_, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) -> string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config); string(_Bin, _Handler, _Acc, _Stack, _Config) -> erlang:error(badarg). doublequote(Rest, Handler, Acc, [key | _] = Stack, Config) -> colon(Rest, handle_event({key, end_seq(Acc, Config)}, Handler, Config), Stack, Config); doublequote(Rest, Handler, Acc, Stack, Config) -> maybe_done(Rest, handle_event({string, end_seq(Acc, Config)}, Handler, Config), Stack, Config). %% strips continuation bytes after bad utf bytes, guards against both too short %% and overlong sequences. N is the maximum number of bytes to strip strip_continuations(<>, Handler, Acc, Stack, Config, 0) -> string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config); strip_continuations(<>, Handler, Acc, Stack, Config, N) when X >= 128, X =< 191 -> strip_continuations(Rest, Handler, Acc, Stack, Config, N - 1); %% not a continuation byte, insert a replacement character for sequence thus %% far and dispatch back to string strip_continuations(<>, Handler, Acc, Stack, Config, _) -> string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config). %% this all gets really gross and should probably eventually be folded into %% but for now it fakes being part of string on incompletes and errors unescape(<<$b, Rest/binary>>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $\b), Stack, Config); unescape(<<$f, Rest/binary>>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $\f), Stack, Config); unescape(<<$n, Rest/binary>>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $\n), Stack, Config); unescape(<<$r, Rest/binary>>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $\r), Stack, Config); unescape(<<$t, Rest/binary>>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $\t), Stack, Config); unescape(<>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $\"), Stack, Config); unescape(<>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $\\), Stack, Config); unescape(<>, Handler, Acc, Stack, Config) -> string(Rest, Handler, acc_seq(Acc, $/), Stack, Config); unescape( <<$u, $d, A, B, C, ?rsolidus, $u, $d, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config ) when (A == $8 orelse A == $9 orelse A == $a orelse A == $b), (X == $c orelse X == $d orelse X == $e orelse X == $f), ?is_hex(B), ?is_hex(C), ?is_hex(Y), ?is_hex(Z) -> High = erlang:list_to_integer([$d, A, B, C], 16), Low = erlang:list_to_integer([$d, X, Y, Z], 16), Codepoint = (High - 16#d800) * 16#400 + (Low - 16#dc00) + 16#10000, string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config); unescape( <<$u, $d, A, B, C, ?rsolidus, $u, W, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config ) when (A == $8 orelse A == $9 orelse A == $a orelse A == $b), ?is_hex(B), ?is_hex(C), ?is_hex(W), ?is_hex(X), ?is_hex(Y), ?is_hex(Z) -> string(Rest, Handler, acc_seq(Acc, [16#fffd, 16#fffd]), Stack, Config); unescape(<<$u, A, B, C, D, Rest/binary>>, Handler, Acc, Stack, Config) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) -> case erlang:list_to_integer([A, B, C, D], 16) of Codepoint when Codepoint < 16#d800; Codepoint > 16#dfff -> string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config); _ -> string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config) end; unescape(_Bin, _Handler, _Acc, _Stack, _Config) -> erlang:error(badarg). %% like in strings, there's some pseudo states in here that will never %% show up in errors or incompletes. some show up in value, some show %% up in integer, decimal or exp negative(<<$0, Rest/binary>>, Handler, Acc, Stack, Config) -> zero(Rest, Handler, acc_seq(Acc, $0), Stack, Config); negative(<>, Handler, Acc, Stack, Config) when ?is_nonzero(S) -> integer(Rest, Handler, acc_seq(Acc, S), Stack, Config); negative(_Bin, _Handler, _Acc, _Stack, _Config) -> erlang:error(badarg). zero(<>, Handler, Acc, Stack, Config) -> decimal(Rest, Handler, acc_seq(Acc, ?decimalpoint), Stack, Config); zero(<>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E -> e(Rest, Handler, acc_seq(Acc, ".0e"), Stack, Config); zero(Bin, Handler, Acc, Stack, Config) -> finish_number(Bin, Handler, {zero, Acc}, Stack, Config). integer(<>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) -> integer(Rest, Handler, acc_seq(Acc, S), Stack, Config); integer(<>, Handler, Acc, Stack, Config) -> initialdecimal(Rest, Handler, acc_seq(Acc, ?decimalpoint), Stack, Config); integer(<>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E -> e(Rest, Handler, acc_seq(Acc, ".0e"), Stack, Config); integer(Bin, Handler, Acc, Stack, Config) -> finish_number(Bin, Handler, {integer, Acc}, Stack, Config). initialdecimal(<>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) -> decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config); initialdecimal(_Bin, _Handler, _Acc, _Stack, _Config) -> erlang:error(badarg). decimal(<>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) -> decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config); decimal(<>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E -> e(Rest, Handler, acc_seq(Acc, $e), Stack, Config); decimal(Bin, Handler, Acc, Stack, Config) -> finish_number(Bin, Handler, {decimal, Acc}, Stack, Config). e(<>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) -> exp(Rest, Handler, acc_seq(Acc, S), Stack, Config); e(<>, Handler, Acc, Stack, Config) when Sign =:= ?positive; Sign =:= ?negative -> ex(Rest, Handler, acc_seq(Acc, Sign), Stack, Config); e(_Bin, _Handler, _Acc, _Stack, _Config) -> erlang:error(badarg). ex(<>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) -> exp(Rest, Handler, acc_seq(Acc, S), Stack, Config); ex(_Bin, _Handler, _Acc, _Stack, _Config) -> erlang:error(badarg). exp(<>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) -> exp(Rest, Handler, acc_seq(Acc, S), Stack, Config); exp(Bin, Handler, Acc, Stack, Config) -> finish_number(Bin, Handler, {exp, Acc}, Stack, Config). finish_number(Rest, Handler, Acc, [], Config) -> maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), [], Config); finish_number(Rest, Handler, Acc, Stack, Config) -> maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config). format_number({zero, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))}; format_number({integer, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))}; format_number({decimal, Acc}) -> {float, list_to_float(lists:reverse(Acc))}; format_number({exp, Acc}) -> {float, list_to_float(lists:reverse(Acc))}. true(<<$r, $u, $e, Rest/binary>>, Handler, Stack, Config) -> maybe_done(Rest, handle_event({literal, true}, Handler, Config), Stack, Config); true(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). false(<<$a, $l, $s, $e, Rest/binary>>, Handler, Stack, Config) -> maybe_done(Rest, handle_event({literal, false}, Handler, Config), Stack, Config); false(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). null(<<$u, $l, $l, Rest/binary>>, Handler, Stack, Config) -> maybe_done(Rest, handle_event({literal, null}, Handler, Config), Stack, Config); null(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). maybe_done(<>, Handler, [], Config) -> done(Rest, handle_event(end_json, Handler, Config), [], Config); maybe_done(<>, Handler, [object | Stack], Config) -> maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config); maybe_done(<>, Handler, [array | Stack], Config) -> maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config); maybe_done(<>, Handler, [object | Stack], Config) -> key(Rest, Handler, [key | Stack], Config); maybe_done(<>, Handler, [array | _] = Stack, Config) -> value(Rest, Handler, Stack, Config); maybe_done(<>, Handler, Stack, Config) when ?is_whitespace(S) -> maybe_done(Rest, Handler, Stack, Config); maybe_done(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). done(<>, Handler, [], Config) when ?is_whitespace(S) -> done(Rest, Handler, [], Config); done(<<>>, {_Handler, State}, [], _Config) -> State; done(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg). thrift-0.23.0/lib/erl/src/thrift_sslsocket_transport.erl0000664000175000017500000001400515165535636023726 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_sslsocket_transport). -behaviour(thrift_transport). -export([ new/3, write/2, read/2, flush/1, close/1, new_transport_factory/3 ]). %% Export only for the transport factory -export([new/2]). -record(data, { socket :: ssl:sslsocket(), recv_timeout = infinity :: infinity | timeout() }). -type data() :: #data{}. -type reason() :: thrift_transport:reason(). %% The following "local" record is filled in by parse_factory_options/2 %% below. These options can be passed to new_protocol_factory/3 in a %% proplists-style option list. They're parsed like this so it is an O(n) %% operation instead of O(n^2) -record(factory_opts, { connect_timeout = infinity :: infinity | timeout(), sockopts = [] :: [inet:inet_backend() | gen_tcp:connect_option()], framed = false :: boolean(), ssloptions = [] :: [ssl:tls_client_option()] }). parse_factory_options([], Opts) -> Opts; parse_factory_options([{framed, Bool} | Rest], Opts) when is_boolean(Bool) -> parse_factory_options(Rest, Opts#factory_opts{framed = Bool}); parse_factory_options([{sockopts, OptList} | Rest], Opts) when is_list(OptList) -> parse_factory_options(Rest, Opts#factory_opts{sockopts = OptList}); parse_factory_options([{connect_timeout, TO} | Rest], Opts) when TO =:= infinity; is_integer(TO) -> parse_factory_options(Rest, Opts#factory_opts{connect_timeout = TO}); parse_factory_options([{ssloptions, SslOptions} | Rest], Opts) when is_list(SslOptions) -> parse_factory_options(Rest, Opts#factory_opts{ssloptions = SslOptions}). new(Socket, SockOpts, SslOptions) when is_list(SockOpts), is_list(SslOptions) -> %% => prevent the ssl handshake messages get lost ok = inet:setopts(Socket, [{active, false}]), %% upgrade to an ssl socket % infinite timeout case catch ssl:handshake(Socket, SslOptions) of {ok, SslSocket} -> new(SslSocket, SockOpts); {error, Reason} -> exit({error, Reason}); Other -> error_logger:error_report( [ {application, thrift}, "SSL accept failed error", lists:flatten(io_lib:format("~p", [Other])) ] ), exit({error, ssl_accept_failed}) end. new(SslSocket, SockOpts) -> State = case lists:keysearch(recv_timeout, 1, SockOpts) of {value, {recv_timeout, Timeout}} when is_integer(Timeout), Timeout > 0 -> #data{socket = SslSocket, recv_timeout = Timeout}; _ -> #data{socket = SslSocket} end, thrift_transport:new(?MODULE, State). %% Data :: iolist() -spec write(data(), iolist()) -> {data(), ok | {error, reason()}}. write(This = #data{socket = Socket}, Data) -> {This, ssl:send(Socket, Data)}. read(This = #data{socket = Socket, recv_timeout = Timeout}, Len) when is_integer(Len), Len >= 0 -> case ssl:recv(Socket, Len, Timeout) of Err = {error, timeout} -> ok = ssl:close(Socket), {This, Err}; Data -> {This, Data} end. %% We can't really flush - everything is flushed when we write flush(This) -> {This, ok}. close(This = #data{socket = Socket}) -> {This, ssl:close(Socket)}. %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Generates a "transport factory" function - a fun which returns a thrift_transport() %% instance. %% This can be passed into a protocol factory to generate a connection to a %% thrift server over a socket. %% new_transport_factory(Host, Port, Options) -> ParsedOpts = parse_factory_options(Options, #factory_opts{}), F = fun() -> SockOpts = [ binary, {packet, 0}, {active, false}, {nodelay, true} | ParsedOpts#factory_opts.sockopts ], case catch gen_tcp:connect( Host, Port, SockOpts, ParsedOpts#factory_opts.connect_timeout ) of {ok, Sock} -> SslSock = case catch ssl:connect( Sock, ParsedOpts#factory_opts.ssloptions, ParsedOpts#factory_opts.connect_timeout ) of {ok, SslSocket} -> SslSocket; Other -> error_logger:info_msg( "error while connecting over ssl - reason: ~p~n", [Other] ), catch gen_tcp:close(Sock), exit(error) end, {ok, Transport} = thrift_sslsocket_transport:new(SslSock, SockOpts), {ok, BufTransport} = case ParsedOpts#factory_opts.framed of true -> thrift_framed_transport:new(Transport); false -> thrift_buffered_transport:new(Transport) end, {ok, BufTransport}; Error -> Error end end, {ok, F}. thrift-0.23.0/lib/erl/src/thrift_json_protocol.erl0000664000175000017500000004422015165535636022474 0ustar00buildbuild00000000000000%% %% Licensed to the Apache Software Foundation (ASF) under one %% or more contributor license agreements. See the NOTICE file %% distributed with this work for additional information %% regarding copyright ownership. The ASF licenses this file %% to you under the Apache License, Version 2.0 (the %% "License"); you may not use this file except in compliance %% with the License. You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% %% The JSON protocol implementation was created by %% Peter Neumark based on %% the binary protocol implementation. -module(thrift_json_protocol). -behaviour(thrift_protocol). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). -export([ new/1, new/2, read/2, write/2, flush_transport/1, close_transport/1, new_protocol_factory/2 ]). -record(json_context, { % the type of json_context: array or object type :: undefined | array | object, % fields read or written fields_processed = 0 :: non_neg_integer() }). -type json_context() :: #json_context{}. -type jsx_type() :: atom() | {atom(), atom() | string()}. -type jsx() :: {event, jsx_type(), [jsx_type()]}. -record(json_protocol, { transport :: term(), context_stack = [] :: [json_context()], jsx :: undefined | jsx() }). -define(VERSION_1, 1). -define(JSON_DOUBLE_PRECISION, 16). typeid_to_json(?tType_BOOL) -> "tf"; typeid_to_json(?tType_DOUBLE) -> "dbl"; % NOTE: ?tType_BYTE also match here typeid_to_json(?tType_I8) -> "i8"; typeid_to_json(?tType_I16) -> "i16"; typeid_to_json(?tType_I32) -> "i32"; typeid_to_json(?tType_I64) -> "i64"; typeid_to_json(?tType_STRING) -> "str"; typeid_to_json(?tType_STRUCT) -> "rec"; typeid_to_json(?tType_MAP) -> "map"; typeid_to_json(?tType_SET) -> "set"; typeid_to_json(?tType_LIST) -> "lst". json_to_typeid("tf") -> ?tType_BOOL; json_to_typeid("dbl") -> ?tType_DOUBLE; json_to_typeid("i8") -> ?tType_I8; json_to_typeid("i16") -> ?tType_I16; json_to_typeid("i32") -> ?tType_I32; json_to_typeid("i64") -> ?tType_I64; json_to_typeid("str") -> ?tType_STRING; json_to_typeid("rec") -> ?tType_STRUCT; json_to_typeid("map") -> ?tType_MAP; json_to_typeid("set") -> ?tType_SET; json_to_typeid("lst") -> ?tType_LIST. start_context(object) -> "{"; start_context(array) -> "[". end_context(object) -> "}"; end_context(array) -> "]". new(Transport) -> new(Transport, _Options = []). new(Transport, _Options) -> State = #json_protocol{transport = Transport}, thrift_protocol:new(?MODULE, State). flush_transport(This = #json_protocol{transport = Transport}) -> {NewTransport, Result} = thrift_transport:flush(Transport), { This#json_protocol{ transport = NewTransport, context_stack = [] }, Result }. close_transport(This = #json_protocol{transport = Transport}) -> {NewTransport, Result} = thrift_transport:close(Transport), { This#json_protocol{ transport = NewTransport, context_stack = [], jsx = undefined }, Result }. %%% %%% instance methods %%% % places a new context on the stack: write(#json_protocol{context_stack = Stack} = State0, {enter_context, Type}) -> {State1, ok} = write_values(State0, [{context_pre_item, false}]), State2 = State1#json_protocol{ context_stack = [ #json_context{type = Type} | Stack ] }, write_values(State2, [list_to_binary(start_context(Type))]); % removes the topmost context from stack write(#json_protocol{context_stack = [CurrCtxt | Stack]} = State0, {exit_context}) -> Type = CurrCtxt#json_context.type, State1 = State0#json_protocol{context_stack = Stack}, write_values(State1, [ list_to_binary(end_context(Type)), {context_post_item, false} ]); % writes necessary prelude to field or container depending on current context write( #json_protocol{context_stack = []} = This0, {context_pre_item, _} ) -> {This0, ok}; write( #json_protocol{context_stack = [Context | _CtxtTail]} = This0, {context_pre_item, MayNeedQuotes} ) -> FieldNo = Context#json_context.fields_processed, CtxtType = Context#json_context.type, Rem = FieldNo rem 2, case {CtxtType, FieldNo, Rem, MayNeedQuotes} of % array element (not first) {array, N, _, _} when N > 0 -> write(This0, <<",">>); % non-string object key (first) {object, 0, _, true} -> write(This0, <<"\"">>); % non-string object key (not first) {object, N, 0, true} when N > 0 -> write(This0, <<",\"">>); % string object key (not first) {object, N, 0, false} when N > 0 -> write(This0, <<",">>); % no pre-field necessary _ -> {This0, ok} end; % writes necessary postlude to field or container depending on current context write( #json_protocol{context_stack = []} = This0, {context_post_item, _} ) -> {This0, ok}; write( #json_protocol{context_stack = [Context | CtxtTail]} = This0, {context_post_item, MayNeedQuotes} ) -> FieldNo = Context#json_context.fields_processed, CtxtType = Context#json_context.type, Rem = FieldNo rem 2, {This1, ok} = case {CtxtType, Rem, MayNeedQuotes} of % non-string object key {object, 0, true} -> write(This0, <<"\":">>); % string object key {object, 0, false} -> write(This0, <<":">>); % no pre-field necessary _ -> {This0, ok} end, NewContext = Context#json_context{fields_processed = FieldNo + 1}, {This1#json_protocol{context_stack = [NewContext | CtxtTail]}, ok}; write(This0, #protocol_message_begin{ name = Name, type = Type, seqid = Seqid }) -> write_values(This0, [ {enter_context, array}, {i32, ?VERSION_1}, {string, Name}, {i32, Type}, {i32, Seqid} ]); write(This, message_end) -> write_values(This, [{exit_context}]); % Example field expression: "1":{"dbl":3.14} write(This0, #protocol_field_begin{ name = _Name, type = Type, id = Id }) -> write_values(This0, [ % entering 'outer' object {i16, Id}, % entering 'outer' object {enter_context, object}, {string, typeid_to_json(Type)} ]); write(This, field_stop) -> {This, ok}; write(This, field_end) -> write_values(This, [{exit_context}]); % Example message with map: [1,"testMap",1,0,{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}] write(This0, #protocol_map_begin{ ktype = Ktype, vtype = Vtype, size = Size }) -> write_values(This0, [ {enter_context, array}, {string, typeid_to_json(Ktype)}, {string, typeid_to_json(Vtype)}, {i32, Size}, {enter_context, object} ]); write(This, map_end) -> write_values(This, [ {exit_context}, {exit_context} ]); write(This0, #protocol_list_begin{ etype = Etype, size = Size }) -> write_values(This0, [ {enter_context, array}, {string, typeid_to_json(Etype)}, {i32, Size} ]); write(This, list_end) -> write_values(This, [ {exit_context} ]); % example message with set: [1,"testSet",1,0,{"1":{"set":["i32",3,1,2,3]}}] write(This0, #protocol_set_begin{ etype = Etype, size = Size }) -> write_values(This0, [ {enter_context, array}, {string, typeid_to_json(Etype)}, {i32, Size} ]); write(This, set_end) -> write_values(This, [ {exit_context} ]); % example message with struct: [1,"testStruct",1,0,{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}}}] write(This, #protocol_struct_begin{}) -> write_values(This, [ {enter_context, object} ]); write(This, struct_end) -> write_values(This, [ {exit_context} ]); write(This, {bool, true}) -> write_values(This, [ {context_pre_item, true}, <<"true">>, {context_post_item, true} ]); write(This, {bool, false}) -> write_values(This, [ {context_pre_item, true}, <<"false">>, {context_post_item, true} ]); write(This, {byte, Byte}) -> write_values(This, [ {context_pre_item, true}, list_to_binary(integer_to_list(Byte)), {context_post_item, true} ]); write(This, {i16, I16}) -> write(This, {byte, I16}); write(This, {i32, I32}) -> write(This, {byte, I32}); write(This, {i64, I64}) -> write(This, {byte, I64}); write(This, {double, Double}) -> write_values(This, [ {context_pre_item, true}, list_to_binary(io_lib:format("~.*f", [?JSON_DOUBLE_PRECISION, Double])), {context_post_item, true} ]); write(This0, {string, Str}) -> write_values(This0, [ {context_pre_item, false}, case is_binary(Str) of true -> Str; false -> <<"\"", (list_to_binary(Str))/binary, "\"">> end, {context_post_item, false} ]); %% TODO: binary fields should be base64 encoded? %% Data :: iolist() write(This = #json_protocol{transport = Trans}, Data) -> %io:format("Data ~p Ctxt ~p~n~n", [Data, This#json_protocol.context_stack]), {NewTransport, Result} = thrift_transport:write(Trans, Data), {This#json_protocol{transport = NewTransport}, Result}. write_values(This0, ValueList) -> FinalState = lists:foldl( fun(Val, ThisIn) -> {ThisOut, ok} = write(ThisIn, Val), ThisOut end, This0, ValueList ), {FinalState, ok}. %% I wish the erlang version of the transport interface included a %% read_all function (like eg. the java implementation). Since it doesn't, %% here's my version (even though it probably shouldn't be in this file). %% %% The resulting binary is immediately send to the JSX stream parser. %% Subsequent calls to read actually operate on the events returned by JSX. read_all(#json_protocol{transport = Transport0} = State) -> {Transport1, Bin} = read_all_1(Transport0, []), P = thrift_json_parser:parser(), [First | Rest] = P(Bin), State#json_protocol{ transport = Transport1, jsx = {event, First, Rest} }. read_all_1(Transport0, IoList) -> {Transport1, Result} = thrift_transport:read(Transport0, 1), case Result of % nothing read: assume we're done {ok, <<>>} -> {Transport1, iolist_to_binary(lists:reverse(IoList))}; % character successfully read; read more {ok, Data} -> read_all_1(Transport1, [Data | IoList]); % we're done {error, 'EOF'} -> {Transport1, iolist_to_binary(lists:reverse(IoList))} end. % Expect reads an event from the JSX event stream. It receives an event or data % type as input. Comparing the read event from the one is was passed, it % returns an error if something other than the expected value is encountered. % Expect also maintains the context stack in #json_protocol. expect(#json_protocol{jsx = {event, {Type, Data} = Ev, [Next | Rest]}} = State, ExpectedType) -> NextState = State#json_protocol{jsx = {event, Next, Rest}}, case Type == ExpectedType of true -> {NextState, {ok, convert_data(Type, Data)}}; false -> {NextState, {error, {unexpected_json_event, Ev}}} end; expect(#json_protocol{jsx = {event, Event, Next}} = State, ExpectedEvent) -> expect(State#json_protocol{jsx = {event, {Event, none}, Next}}, ExpectedEvent). convert_data(integer, I) -> list_to_integer(I); convert_data(float, F) -> list_to_float(F); convert_data(_, D) -> D. expect_many(State, ExpectedList) -> expect_many_1(State, ExpectedList, [], ok). expect_many_1(State, [], ResultList, Status) -> {State, {Status, lists:reverse(ResultList)}}; expect_many_1(State, [Expected | ExpTail], ResultList, _PrevStatus) -> {State1, {Status, Data}} = expect(State, Expected), NewResultList = [Data | ResultList], case Status of % in case of error, end prematurely error -> expect_many_1(State1, [], NewResultList, Status); ok -> expect_many_1(State1, ExpTail, NewResultList, Status) end. % wrapper around expect to make life easier for container opening/closing functions expect_nodata(This, ExpectedList) -> case expect_many(This, ExpectedList) of {State, {ok, _}} -> {State, ok}; Error -> Error end. read_field(#json_protocol{jsx = {event, Field, [Next | Rest]}} = State) -> NewState = State#json_protocol{jsx = {event, Next, Rest}}, {NewState, Field}. read(This0, message_begin) -> % call read_all to get the contents of the transport buffer into JSX. This1 = read_all(This0), case expect_many( This1, [start_array, integer, string, integer, integer] ) of {This2, {ok, [_, Version, Name, Type, SeqId]}} -> case Version =:= ?VERSION_1 of true -> {This2, #protocol_message_begin{ name = Name, type = Type, seqid = SeqId }}; false -> {This2, {error, no_json_protocol_version}} end; Other -> Other end; read(This, message_end) -> expect_nodata(This, [end_array]); read(This, struct_begin) -> expect_nodata(This, [start_object]); read(This, struct_end) -> expect_nodata(This, [end_object]); read(This0, field_begin) -> {This1, Read} = expect_many( This0, %field id [ key, % {} surrounding field start_object, % type of field key ] ), case Read of {ok, [FieldIdStr, _, FieldType]} -> {This1, #protocol_field_begin{ type = json_to_typeid(FieldType), % TODO: do we need to wrap this in a try/catch? id = list_to_integer(FieldIdStr) }}; {error, [{unexpected_json_event, {end_object, none}}]} -> {This1, #protocol_field_begin{type = ?tType_STOP}}; Other -> io:format("**** OTHER branch selected ****"), {This1, Other} end; read(This, field_end) -> expect_nodata(This, [end_object]); % Example message with map: [1,"testMap",1,0,{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}] read(This0, map_begin) -> case expect_many( This0, [ start_array, % key type string, % value type string, % size integer, % the following object contains the map start_object ] ) of {This1, {ok, [_, Ktype, Vtype, Size, _]}} -> {This1, #protocol_map_begin{ ktype = Ktype, vtype = Vtype, size = Size }}; Other -> Other end; read(This, map_end) -> expect_nodata(This, [end_object, end_array]); read(This0, list_begin) -> case expect_many( This0, [ start_array, % element type string, % size integer ] ) of {This1, {ok, [_, Etype, Size]}} -> {This1, #protocol_list_begin{ etype = Etype, size = Size }}; Other -> Other end; read(This, list_end) -> expect_nodata(This, [end_array]); % example message with set: [1,"testSet",1,0,{"1":{"set":["i32",3,1,2,3]}}] read(This0, set_begin) -> case expect_many( This0, [ start_array, % element type string, % size integer ] ) of {This1, {ok, [_, Etype, Size]}} -> {This1, #protocol_set_begin{ etype = Etype, size = Size }}; Other -> Other end; read(This, set_end) -> expect_nodata(This, [end_array]); read(This0, field_stop) -> {This0, ok}; %% read(This0, bool) -> {This1, Field} = read_field(This0), Value = case Field of {literal, I} -> {ok, I}; _Other -> {error, unexpected_event_for_boolean} end, {This1, Value}; read(This0, byte) -> {This1, Field} = read_field(This0), Value = case Field of {key, K} -> {ok, list_to_integer(K)}; {integer, I} -> {ok, list_to_integer(I)}; _Other -> {error, unexpected_event_for_integer} end, {This1, Value}; read(This0, i16) -> read(This0, byte); read(This0, i32) -> read(This0, byte); read(This0, i64) -> read(This0, byte); read(This0, double) -> {This1, Field} = read_field(This0), Value = case Field of {float, I} -> {ok, list_to_float(I)}; _Other -> {error, unexpected_event_for_double} end, {This1, Value}; % returns a binary directly, call binary_to_list if necessary read(This0, string) -> {This1, Field} = read_field(This0), Value = case Field of {string, I} -> {ok, I}; {key, J} -> {ok, J}; _Other -> {error, unexpected_event_for_string} end, {This1, Value}. %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% returns a (fun() -> thrift_protocol()) new_protocol_factory(TransportFactory, _Options) -> % Only strice read/write are implemented F = fun() -> {ok, Transport} = TransportFactory(), thrift_json_protocol:new(Transport, []) end, {ok, F}. thrift-0.23.0/lib/erl/src/thrift_socket_server.erl0000664000175000017500000003302015165535636022454 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_socket_server). -behaviour(gen_server). -include("thrift_constants.hrl"). -export([start/1, stop/1]). -export([ init/1, handle_call/3, handle_cast/2, terminate/2, code_change/3, handle_info/2 ]). -export([acceptor_loop/1]). -ifdef(TEST). -export([parse_options/1]). -endif. -type protocol() :: compact | {compact, term()} | json | {json, term()} | binary | {binary | term()} | {custom, module(), term()}. -type socket_opts() :: [inet:inet_backend() | gen_tcp:listen_option()]. -type ssl_opts() :: [ssl:tls_server_option()]. -record(thrift_socket_server, { port :: inet:port_number(), service :: thrift_multiplexed_map_wrapper:service_handler_map(), handler :: thrift_multiplexed_map_wrapper:service_handler_map(), acceptors_left :: non_neg_integer(), listen :: gen_tcp:socket(), acceptor :: undefined | pid(), socket_opts :: socket_opts(), protocol :: protocol(), framed :: boolean(), ssltransport :: boolean(), ssloptions :: ssl_opts() }). start(Options) -> start_server(parse_options(Options)). stop(Name) when is_atom(Name) -> gen_server:cast(Name, stop); stop(Pid) when is_pid(Pid) -> gen_server:cast(Pid, stop); stop({local, Name}) -> stop(Name); stop({global, Name}) -> stop(Name); stop(Options) -> #{name := Name} = parse_options(Options), stop(Name). %% Internal API parse_options(Options) -> parse_options(Options, #{}). parse_options([], State) -> State; parse_options([{name, L} | Rest], State) when is_list(L) -> Name = {local, list_to_atom(L)}, parse_options(Rest, State#{name => Name}); parse_options([{name, A} | Rest], State) when is_atom(A) -> Name = {local, A}, parse_options(Rest, State#{name => Name}); parse_options([{name, Name} | Rest], State) -> parse_options(Rest, State#{name => Name}); parse_options([{port, L} | Rest], State) when is_list(L) -> Port = list_to_integer(L), parse_options(Rest, State#{port => Port}); parse_options([{port, Port} | Rest], State) when is_integer(Port), Port >= 0, Port =< 65535 -> parse_options(Rest, State#{port => Port}); parse_options([{ip, Ip} | Rest], State) -> case Ip of any -> parse_options(Rest, State); Ip when is_tuple(Ip) -> parse_options(Rest, State#{ip => Ip}); Ip when is_list(Ip) -> {ok, IpTuple} = inet_parse:address(Ip), parse_options(Rest, State#{ip => IpTuple}) end; parse_options([{socket_opts, L} | Rest], State) when is_list(L), length(L) > 0 -> parse_options(Rest, State#{socket_opts => L}); parse_options([{handler, []} | _Rest], _State) -> throw("At least an error handler must be defined."); parse_options([{handler, ServiceHandlerPropertyList} | Rest], State) when is_list(ServiceHandlerPropertyList) -> ServiceHandlerMap = case maps:get(handler, State, undefined) of undefined -> lists:foldl( fun ({ServiceName, ServiceHandler}, Acc) when is_list(ServiceName), is_atom(ServiceHandler) -> thrift_multiplexed_map_wrapper:store(ServiceName, ServiceHandler, Acc); (_, _Acc) -> throw( "The handler option is not properly configured for multiplexed services. It should be a kind of [{\"error_handler\", Module::atom()}, {SericeName::list(), Module::atom()}, ...]" ) end, thrift_multiplexed_map_wrapper:new(), ServiceHandlerPropertyList ); _ -> throw("Error while parsing the handler option.") end, case thrift_multiplexed_map_wrapper:find(?MULTIPLEXED_ERROR_HANDLER_KEY, ServiceHandlerMap) of {ok, _ErrorHandler} -> parse_options(Rest, State#{handler => ServiceHandlerMap}); error -> throw( "The handler option is not properly configured for multiplexed services. It should be a kind of [{\"error_handler\", Module::atom()}, {SericeName::list(), Module::atom()}, ...]" ) end; parse_options([{handler, Handler} | Rest], State) when not is_map_key(handler, State), is_atom(Handler) -> parse_options(Rest, State#{handler => Handler}); parse_options([{service, []} | _Rest], _State) -> throw("At least one service module must be defined."); parse_options([{service, ServiceModulePropertyList} | Rest], State) when is_list(ServiceModulePropertyList) -> ServiceModuleMap = case maps:get(service, State, undefined) of undefined -> lists:foldl( fun ({ServiceName, ServiceModule}, Acc) when is_list(ServiceName), is_atom(ServiceModule) -> thrift_multiplexed_map_wrapper:store(ServiceName, ServiceModule, Acc); (_, _Acc) -> throw( "The service option is not properly configured for multiplexed services. It should be a kind of [{SericeName::list(), ServiceModule::atom()}, ...]" ) end, thrift_multiplexed_map_wrapper:new(), ServiceModulePropertyList ); _ -> throw("Error while parsing the service option.") end, parse_options(Rest, State#{service => ServiceModuleMap}); parse_options([{service, Service} | Rest], State) when not is_map_key(service, State), is_atom(Service) -> parse_options(Rest, State#{service => Service}); parse_options([{max, Max} | Rest], State) when is_integer(Max), Max > 0 -> parse_options(Rest, State#{max => Max}); parse_options([{protocol, Proto} | Rest], State) when is_atom(Proto) -> parse_options(Rest, State#{protocol => Proto}); parse_options([{framed, Framed} | Rest], State) when is_boolean(Framed) -> parse_options(Rest, State#{framed => Framed}); parse_options([{ssltransport, SSLTransport} | Rest], State) when is_boolean(SSLTransport) -> parse_options(Rest, State#{ssltransport => SSLTransport}); parse_options([{ssloptions, SSLOptions} | Rest], State) when is_list(SSLOptions) -> parse_options(Rest, State#{ssloptions => SSLOptions}). start_server(Options = #{name := Name}) -> case Name of undefined -> gen_server:start_link(?MODULE, Options, []); _ -> gen_server:start_link(Name, ?MODULE, Options, []) end. init(State = #{port := Port}) -> process_flag(trap_exit, true), BaseOpts = [ binary, {reuseaddr, true}, {packet, 0}, {backlog, 4096}, {recbuf, 8192}, {active, false} ], Opts = case maps:get(ip, State, undefined) of undefined -> BaseOpts; Ip -> [{ip, Ip} | BaseOpts] end, case gen_tcp:listen(Port, Opts) of {ok, Listen} -> {ok, ListenPort} = inet:port(Listen), {ok, new_acceptor(#thrift_socket_server{ acceptors_left = maps:get(max, State, 2048), listen = Listen, port = ListenPort, service = maps:get(service, State), handler = maps:get(handler, State), socket_opts = maps:get(socket_opts, State, [{recv_timeout, 500}]), framed = maps:get(framed, State, false), protocol = maps:get(protocol, State, binary), ssltransport = maps:get(ssltransport, State, false), ssloptions = maps:get(ssloptions, State, []) })}; {error, Reason} -> {stop, Reason} end. new_acceptor(State = #thrift_socket_server{acceptors_left = 0}) -> error_logger:error_msg("Not accepting new connections"), State#thrift_socket_server{acceptor = undefined}; new_acceptor( State = #thrift_socket_server{ listen = Listen, service = Service, handler = Handler, socket_opts = Opts, framed = Framed, protocol = Proto, ssltransport = SslTransport, ssloptions = SslOptions } ) -> Pid = proc_lib:spawn_link( ?MODULE, acceptor_loop, [{self(), Listen, Service, Handler, Opts, Framed, SslTransport, SslOptions, Proto}] ), State#thrift_socket_server{acceptor = Pid}. acceptor_loop( {Server, Listen, Service, Handler, SocketOpts, Framed, SslTransport, SslOptions, Proto} ) when is_pid(Server), is_list(SocketOpts) -> % infinite timeout case catch gen_tcp:accept(Listen) of {ok, Socket} -> gen_server:cast(Server, {accepted, self()}), ProtoGen = fun() -> {ok, SocketTransport} = case SslTransport of true -> thrift_sslsocket_transport:new(Socket, SocketOpts, SslOptions); false -> thrift_socket_transport:new(Socket, SocketOpts) end, {ok, Transport} = case Framed of true -> thrift_framed_transport:new(SocketTransport); false -> thrift_buffered_transport:new(SocketTransport) end, {ok, Protocol} = case Proto of compact -> thrift_compact_protocol:new(Transport); {compact, Options} -> thrift_compact_protocol:new(Transport, Options); json -> thrift_json_protocol:new(Transport); {json, Options} -> thrift_json_protocol:new(Transport, Options); binary -> thrift_binary_protocol:new(Transport); {binary, Options} -> thrift_binary_protocol:new(Transport, Options); {custom, Module, Options} -> case erlang:function_exported(Module, new, 2) of true -> Module:new(Transport, Options); false -> throw("Could not instantiate custom protocol") end end, {ok, Protocol} end, thrift_processor:init({Server, ProtoGen, Service, Handler}); {error, closed} -> exit({error, closed}); Other -> error_logger:error_report( [ {application, thrift}, "Accept failed error", lists:flatten(io_lib:format("~p", [Other])) ] ), exit({error, accept_failed}) end. handle_call({get, port}, _From, State = #thrift_socket_server{port = Port}) -> {reply, Port, State}; handle_call(_Message, _From, State) -> Res = error, {reply, Res, State}. handle_cast( {accepted, Pid}, State = #thrift_socket_server{acceptor = Pid, acceptors_left = Max} ) -> % io:format("accepted ~p~n", [Pid]), State1 = State#thrift_socket_server{acceptors_left = Max - 1}, {noreply, new_acceptor(State1)}; handle_cast(stop, State) -> {stop, normal, State}. terminate(Reason, #thrift_socket_server{listen = Listen}) -> gen_tcp:close(Listen), case Reason of normal -> ok; shutdown -> ok; _ -> {backtrace, Bt} = erlang:process_info(self(), backtrace), error_logger:error_report({?MODULE, ?LINE, {child_error, Reason, Bt}}) end. code_change(_OldVsn, State, _Extra) -> State. handle_info( {'EXIT', Pid, normal}, State = #thrift_socket_server{acceptor = Pid} ) -> {noreply, new_acceptor(State)}; handle_info( {'EXIT', Pid, Reason}, State = #thrift_socket_server{acceptor = Pid} ) -> error_logger:error_report({?MODULE, ?LINE, {acceptor_error, Reason}}), timer:sleep(100), {noreply, new_acceptor(State)}; handle_info( {'EXIT', _LoopPid, Reason}, State = #thrift_socket_server{acceptor = Pid, acceptors_left = AcceptorsLeft} ) -> case Reason of normal -> ok; shutdown -> ok; _ -> error_logger:error_report({?MODULE, ?LINE, {child_error, Reason}}) end, State1 = State#thrift_socket_server{acceptors_left = AcceptorsLeft + 1}, State2 = case Pid of undefined -> new_acceptor(State1); _ -> State1 end, {noreply, State2}; handle_info(Info, State) -> error_logger:info_report([{'INFO', Info}, {'State', State}]), {noreply, State}. thrift-0.23.0/lib/erl/src/thrift_membuffer_transport.erl0000664000175000017500000000442415165535636023670 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_membuffer_transport). -behaviour(thrift_transport). %% constructors -export([new/0, new/1, new/2]). %% protocol callbacks -export([read/2, read_exact/2, write/2, flush/1, close/1]). -record(t_membuffer, { buffer = [] :: iodata() }). -spec new() -> {ok, thrift_transport:t_transport()}. new() -> new([]). -spec new(Buf :: iodata()) -> {ok, thrift_transport:t_transport()}. new(Buf) -> new(Buf, []). new(Buf, _Opts) when is_list(Buf) -> State = #t_membuffer{buffer = Buf}, thrift_transport:new(?MODULE, State); new(Buf, _Opts) when is_binary(Buf) -> State = #t_membuffer{buffer = [Buf]}, thrift_transport:new(?MODULE, State). read(State = #t_membuffer{buffer = Buf}, Len) when is_integer(Len), Len >= 0 -> Binary = iolist_to_binary(Buf), Give = min(iolist_size(Binary), Len), {Result, Remaining} = split_binary(Binary, Give), {State#t_membuffer{buffer = Remaining}, {ok, Result}}. read_exact(State = #t_membuffer{buffer = Buf}, Len) when is_integer(Len), Len >= 0 -> Binary = iolist_to_binary(Buf), case iolist_size(Binary) of X when X >= Len -> {Result, Remaining} = split_binary(Binary, Len), {State#t_membuffer{buffer = Remaining}, {ok, Result}}; _ -> {State, {error, eof}} end. write(State = #t_membuffer{buffer = Buf}, Data) when is_list(Data); is_binary(Data) -> {State#t_membuffer{buffer = [Buf, Data]}, ok}. flush(State) -> {State, ok}. close(State) -> {State, ok}. thrift-0.23.0/lib/erl/src/thrift_memory_buffer.erl0000664000175000017500000000273115165535636022444 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_memory_buffer). -behaviour(thrift_transport). %% constructors -export([new/0, new/1]). %% protocol callbacks -export([read/2, write/2, flush/1, close/1]). %% legacy api -export([new_transport_factory/0]). %% wrapper around thrift_membuffer_transport for legacy reasons new() -> thrift_membuffer_transport:new(). new(State) -> thrift_membuffer_transport:new(State). new_transport_factory() -> {ok, fun() -> new() end}. write(State, Data) -> thrift_membuffer_transport:write(State, Data). read(State, Data) -> thrift_membuffer_transport:read(State, Data). flush(State) -> thrift_membuffer_transport:flush(State). close(State) -> thrift_membuffer_transport:close(State). thrift-0.23.0/lib/erl/src/thrift_reconnecting_client.erl0000664000175000017500000002200015165535636023606 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_reconnecting_client). -behaviour(gen_server). %% API -export([ call/3, get_stats/1, get_and_reset_stats/1 ]). -export([start_link/6]). %% gen_server callbacks -export([ init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3 ]). -record(state, { client = nil :: 'nil' | thrift_client:tclient(), host :: inet:socket_address() | inet:hostname(), port :: inet:port_number(), thrift_svc :: atom(), thrift_opts :: list(), reconn_min :: integer(), reconn_max :: integer(), reconn_time = 0 :: integer(), op_cnt_dict :: dict:dict(), op_time_dict :: dict:dict() }). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link( Host, Port, ThriftSvc, ThriftOpts, ReconnMin, ReconnMax ) -> gen_server:start_link( ?MODULE, [ Host, Port, ThriftSvc, ThriftOpts, ReconnMin, ReconnMax ], [] ). call(Pid, Op, Args) -> gen_server:call(Pid, {call, Op, Args}). get_stats(Pid) -> gen_server:call(Pid, get_stats). get_and_reset_stats(Pid) -> gen_server:call(Pid, get_and_reset_stats). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Start the server. %%-------------------------------------------------------------------- init([Host, Port, TSvc, TOpts, ReconnMin, ReconnMax]) -> process_flag(trap_exit, true), State = #state{ host = Host, port = Port, thrift_svc = TSvc, thrift_opts = TOpts, reconn_min = ReconnMin, reconn_max = ReconnMax, op_cnt_dict = dict:new(), op_time_dict = dict:new() }, {ok, try_connect(State)}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call( {call, Op, _}, _From, State = #state{client = nil} ) -> {reply, {error, noconn}, incr_stats(Op, "failfast", 1, State)}; handle_call( {call, Op, Args}, _From, State = #state{client = Client} ) -> Timer = timer_fun(), Result = (catch thrift_client:call(Client, Op, Args)), Time = Timer(), case Result of {C, {ok, Reply}} -> S = incr_stats(Op, "success", Time, State#state{client = C}), {reply, {ok, Reply}, S}; {_, {E, Msg}} when E == error; E == exception -> S = incr_stats(Op, "error", Time, try_connect(State)), {reply, {E, Msg}, S}; Other -> S = incr_stats(Op, "error", Time, try_connect(State)), {reply, Other, S} end; handle_call( get_stats, _From, State = #state{} ) -> {reply, stats(State), State}; handle_call( get_and_reset_stats, _From, State = #state{} ) -> {reply, stats(State), reset_stats(State)}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(try_connect, State) -> {noreply, try_connect(State)}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, #state{client = Client}) -> thrift_client:close(Client), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- try_connect( State = #state{ client = OldClient, host = Host, port = Port, thrift_svc = TSvc, thrift_opts = TOpts } ) -> case OldClient of nil -> ok; _ -> (catch thrift_client:close(OldClient)) end, case catch thrift_client_util:new(Host, Port, TSvc, TOpts) of {ok, Client} -> State#state{client = Client, reconn_time = 0}; {E, Msg} when E == error; E == exception -> ReconnTime = reconn_time(State), error_logger:error_msg( "[~w] ~w connect failed (~w), trying again in ~w ms~n", [self(), TSvc, Msg, ReconnTime] ), erlang:send_after(ReconnTime, self(), try_connect), State#state{client = nil, reconn_time = ReconnTime} end. reconn_time(#state{reconn_min = ReconnMin, reconn_time = 0}) -> ReconnMin; reconn_time(#state{reconn_max = ReconnMax, reconn_time = ReconnMax}) -> ReconnMax; reconn_time(#state{reconn_max = ReconnMax, reconn_time = R}) -> Backoff = 2 * R, case Backoff > ReconnMax of true -> ReconnMax; false -> Backoff end. -ifdef(time_correction). timer_fun() -> T1 = erlang:monotonic_time(), fun() -> T2 = erlang:monotonic_time(), erlang:convert_time_unit(T2 - T1, native, micro_seconds) end. -else. timer_fun() -> T1 = erlang:timestamp(), fun() -> T2 = erlang:timestamp(), timer:now_diff(T2, T1) end. -endif. incr_stats( Op, Result, Time, State = #state{ op_cnt_dict = OpCntDict, op_time_dict = OpTimeDict } ) -> Key = lists:flatten([atom_to_list(Op), ["_" | Result]]), State#state{ op_cnt_dict = dict:update_counter(Key, 1, OpCntDict), op_time_dict = dict:update_counter(Key, Time, OpTimeDict) }. stats(#state{ thrift_svc = TSvc, op_cnt_dict = OpCntDict, op_time_dict = OpTimeDict }) -> Svc = atom_to_list(TSvc), F = fun(Key, Count, Stats) -> Name = lists:flatten([Svc, ["_" | Key]]), Micros = dict:fetch(Key, OpTimeDict), [{Name, Count, Micros} | Stats] end, dict:fold(F, [], OpCntDict). reset_stats(State = #state{}) -> State#state{op_cnt_dict = dict:new(), op_time_dict = dict:new()}. thrift-0.23.0/lib/erl/src/thrift_disk_log_transport.erl0000664000175000017500000001011015165535636023500 0ustar00buildbuild00000000000000%% %% 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. %% %%% Todo: this might be better off as a gen_server type of transport %%% that handles stuff like group commit, similar to TFileTransport %%% in cpp land -module(thrift_disk_log_transport). -behaviour(thrift_transport). %% API -export([new/2, new_transport_factory/2, new_transport_factory/3]). %% thrift_transport callbacks -export([read/2, write/2, force_flush/1, flush/1, close/1]). %% state -record(dl_transport, { %% Keep in sync with disk_log:log/0 type log :: term(), close_on_close = false :: boolean(), sync_every = infinity :: undefined | timeout(), sync_tref :: undefined | timer:tref() }). %% Create a transport attached to an already open log. %% If you'd like this transport to close the disk_log using disk_log:lclose() %% when the transport is closed, pass a {close_on_close, true} tuple in the %% Opts list. new(LogName, Opts) when is_atom(LogName), is_list(Opts) -> State = parse_opts(Opts, #dl_transport{log = LogName}), State2 = case State#dl_transport.sync_every of N when is_integer(N), N > 0 -> {ok, TRef} = timer:apply_interval(N, ?MODULE, force_flush, [State]), State#dl_transport{sync_tref = TRef}; _ -> State end, thrift_transport:new(?MODULE, State2). parse_opts([], State) -> State; parse_opts([{close_on_close, Bool} | Rest], State) when is_boolean(Bool) -> parse_opts(Rest, State#dl_transport{close_on_close = Bool}); parse_opts([{sync_every, Int} | Rest], State) when is_integer(Int), Int > 0 -> parse_opts(Rest, State#dl_transport{sync_every = Int}). %%%% TRANSPORT IMPLENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% disk_log_transport is write-only read(State, _Len) -> {State, {error, no_read_from_disk_log}}. write(This = #dl_transport{log = Log}, Data) -> {This, disk_log:balog(Log, erlang:iolist_to_binary(Data))}. force_flush(#dl_transport{log = Log}) -> error_logger:info_msg("~p syncing~n", [?MODULE]), disk_log:sync(Log). flush(This = #dl_transport{log = Log, sync_every = SE}) -> case SE of % no time-based sync undefined -> ok = disk_log:sync(Log); % sync will happen automagically _Else -> ok end, {This, ok}. %% On close, close the underlying log if we're configured to do so. close(This = #dl_transport{close_on_close = false}) -> {This, ok}; close(This = #dl_transport{log = Log}) -> {This, disk_log:close(Log)}. %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% new_transport_factory(Name, ExtraLogOpts) -> new_transport_factory(Name, ExtraLogOpts, [ {close_on_close, true}, {sync_every, 500} ]). new_transport_factory(Name, ExtraLogOpts, TransportOpts) -> F = fun() -> factory_impl(Name, ExtraLogOpts, TransportOpts) end, {ok, F}. factory_impl(Name, ExtraLogOpts, TransportOpts) -> LogOpts = [ {name, Name}, {format, external}, {type, wrap} | ExtraLogOpts ], Log = case disk_log:open(LogOpts) of {ok, LogS} -> LogS; {repaired, LogS, Info1, Info2} -> error_logger:info_msg("Disk log ~p repaired: ~p, ~p~n", [LogS, Info1, Info2]), LogS end, new(Log, TransportOpts). thrift-0.23.0/lib/erl/src/thrift_framed_transport.erl0000664000175000017500000001025315165535636023153 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_framed_transport). -behaviour(thrift_transport). %% constructor -export([new/1]). %% protocol callbacks -export([read/2, read_exact/2, write/2, flush/1, close/1]). -record(t_framed, { wrapped :: thrift_transport:t_transport(), read_buffer :: iodata(), write_buffer :: iodata() }). -spec new(Transport :: thrift_transport:t_transport()) -> {ok, thrift_transport:t_transport()}. new(Wrapped) -> State = #t_framed{ wrapped = Wrapped, read_buffer = [], write_buffer = [] }, thrift_transport:new(?MODULE, State). read(State = #t_framed{wrapped = Wrapped, read_buffer = Buffer}, Len) when is_integer(Len), Len >= 0 -> Binary = iolist_to_binary(Buffer), case Binary of <<>> when Len > 0 -> case next_frame(Wrapped) of {NewState, {ok, Frame}} -> NewBinary = iolist_to_binary([Binary, Frame]), Give = min(iolist_size(NewBinary), Len), {Result, Remaining} = split_binary(NewBinary, Give), {State#t_framed{wrapped = NewState, read_buffer = Remaining}, {ok, Result}}; {NewState, Error} -> {State#t_framed{wrapped = NewState}, Error} end; %% read of zero bytes <<>> -> {State, {ok, <<>>}}; %% read buffer is nonempty _ -> Give = min(iolist_size(Binary), Len), {Result, Remaining} = split_binary(Binary, Give), {State#t_framed{read_buffer = Remaining}, {ok, Result}} end. read_exact(State = #t_framed{wrapped = Wrapped, read_buffer = Buffer}, Len) when is_integer(Len), Len >= 0 -> Binary = iolist_to_binary(Buffer), case iolist_size(Binary) of %% read buffer is larger than requested read size X when X >= Len -> {Result, Remaining} = split_binary(Binary, Len), {State#t_framed{read_buffer = Remaining}, {ok, Result}}; %% read buffer is insufficient for requested read size _ -> case next_frame(Wrapped) of {NewState, {ok, Frame}} -> read_exact( State#t_framed{wrapped = NewState, read_buffer = [Buffer, Frame]}, Len ); {NewState, Error} -> {State#t_framed{wrapped = NewState}, Error} end end. next_frame(Transport) -> case thrift_transport:read_exact(Transport, 4) of {NewState, {ok, <>}} -> thrift_transport:read_exact(NewState, FrameLength); Error -> Error end. write(State = #t_framed{write_buffer = Buffer}, Data) -> {State#t_framed{write_buffer = [Buffer, Data]}, ok}. flush(State = #t_framed{write_buffer = Buffer, wrapped = Wrapped}) -> case iolist_size(Buffer) of %% if write buffer is empty, do nothing 0 -> {State, ok}; FrameLen -> Data = [<>, Buffer], {Written, Response} = thrift_transport:write(Wrapped, Data), {Flushed, ok} = thrift_transport:flush(Written), {State#t_framed{wrapped = Flushed, write_buffer = []}, Response} end. close(State = #t_framed{wrapped = Wrapped}) -> {Closed, Result} = thrift_transport:close(Wrapped), {State#t_framed{wrapped = Closed}, Result}. thrift-0.23.0/lib/erl/src/thrift_transport.erl0000664000175000017500000001050015165535636021630 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_transport). %% constructors -export([new/1, new/2]). %% transport callbacks -export([read/2, read_exact/2, write/2, flush/1, close/1]). -record(t_transport, { module :: module(), state :: term() }). -type t_transport() :: #t_transport{}. -export_type([t_transport/0]). %%%========================================================================= %%% API %%%========================================================================= -type state() :: term(). -export_type([state/0]). -type reason() :: term(). -export_type([reason/0]). -callback write(state(), iolist() | binary()) -> {state(), ok | {error, reason()}}. -callback read(state(), non_neg_integer()) -> {state(), {ok, binary()} | {error, reason()}}. -callback flush(state()) -> {state(), ok | {error, reason()}}. -callback close(state()) -> {state(), ok | {error, reason()}}. -ifdef(transport_wrapper_module). -define(debug_wrap(Transport), case Transport#t_transport.module of ?transport_wrapper_module -> Transport; _Else -> {ok, Result} = ?transport_wrapper_module:new(Transport), Result end ). -else. -define(debug_wrap(Transport), Transport). -endif. -type wrappable() :: binary() | list() | {membuffer, binary() | list()} | {membuffer, binary() | list(), list()} | {tcp, port()} | {tcp, port(), list()} | {file, file:io_device()} | {file, file:io_device(), list()} | {file, file:filename()} | {file, file:filename(), list()}. -spec new(wrappable()) -> {ok, #t_transport{}}. new({membuffer, Membuffer}) -> new({membuffer, Membuffer, []}); new({membuffer, Membuffer, Opts}) when is_binary(Membuffer); is_list(Membuffer) -> thrift_membuffer_transport:new(Membuffer, Opts); new({tcp, Socket}) when is_port(Socket) -> new({tcp, Socket, []}); new({tcp, Socket, Opts}) when is_port(Socket) -> thrift_socket_transport:new(Socket, Opts); new({file, Filename}) when is_list(Filename); is_binary(Filename) -> new({file, Filename, []}); new({file, Filename, Opts}) when is_list(Filename); is_binary(Filename) -> {ok, File} = file:open(Filename, [raw, binary]), new({file, File, Opts}); new({file, File, Opts}) -> thrift_file_transport:new(File, Opts). -spec new(Module :: module(), State :: any()) -> {ok, t_transport()}. new(Module, State) when is_atom(Module) -> {ok, ?debug_wrap(#t_transport{module = Module, state = State})}. read(Transport = #t_transport{module = Module}, Len) when is_integer(Len), Len >= 0 -> {NewState, Result} = Module:read(Transport#t_transport.state, Len), {Transport#t_transport{state = NewState}, Result}. read_exact(Transport = #t_transport{module = Module}, Len) when is_integer(Len), Len >= 0 -> case lists:keyfind(read_exact, 1, Module:module_info(exports)) of {read_exact, 2} -> {NewState, Result} = Module:read_exact(Transport#t_transport.state, Len), {Transport#t_transport{state = NewState}, Result}; _ -> read(Transport, Len) end. write(Transport = #t_transport{module = Module}, Data) -> {NewState, Result} = Module:write(Transport#t_transport.state, Data), {Transport#t_transport{state = NewState}, Result}. flush(Transport = #t_transport{module = Module}) -> {NewState, Result} = Module:flush(Transport#t_transport.state), {Transport#t_transport{state = NewState}, Result}. close(Transport = #t_transport{module = Module}) -> {NewState, Result} = Module:close(Transport#t_transport.state), {Transport#t_transport{state = NewState}, Result}. thrift-0.23.0/lib/erl/src/thrift.app.src0000664000175000017500000000375515170007142020274 0ustar00buildbuild00000000000000%% %% 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. %% %%% -*- mode:erlang -*- {application, thrift, [ % A quick description of the application. {description, "Thrift bindings"}, % The version of the applicaton {vsn, "0.23.0"}, % All modules used by the application. {modules, []}, % All of the registered names the application uses. This can be ignored. {registered, []}, % Applications that are to be started prior to this one. This can be ignored % leave it alone unless you understand it well and let the .rel files in % your release handle this. {applications, [kernel, stdlib]}, % OTP application loader will load, but not start, included apps. Again % this can be ignored as well. To load but not start an application it % is easier to include it in the .rel file followed by the atom 'none' {included_applications, []}, % configuration parameters similar to those in the config file specified % on the command line. can be fetched with gas:get_env {env, [ % If an error/crash occurs during processing of a function, % should the TApplicationException serialized back to the client % include the erlang backtrace? {exceptions_include_traces, true} ]} ]}. thrift-0.23.0/lib/erl/src/thrift_server.erl0000664000175000017500000001705015165535636021111 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_server). -behaviour(gen_server). %% API -export([start_link/3, stop/1, take_socket/2]). %% gen_server callbacks -export([ init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3 ]). -define(SERVER, ?MODULE). -record(state, { listen_socket :: gen_tcp:socket(), acceptor_ref :: term(), service :: module(), handler :: module() }). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Port, Service, HandlerModule) when is_integer(Port), is_atom(HandlerModule) -> gen_server:start_link({local, ?SERVER}, ?MODULE, {Port, Service, HandlerModule}, []). %%-------------------------------------------------------------------- %% Function: stop(Pid) -> ok, {error, Reason} %% Description: Stops the server. %%-------------------------------------------------------------------- stop(Pid) when is_pid(Pid) -> gen_server:call(Pid, stop). take_socket(Server, Socket) -> gen_server:call(Server, {take_socket, Socket}). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init({Port, Service, Handler}) -> {ok, Socket} = gen_tcp:listen( Port, [ binary, {packet, 0}, {active, false}, {nodelay, true}, {reuseaddr, true} ] ), {ok, Ref} = prim_inet:async_accept(Socket, -1), {ok, #state{ listen_socket = Socket, acceptor_ref = Ref, service = Service, handler = Handler }}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(stop, _From, State) -> {stop, stopped, ok, State}; handle_call({take_socket, Socket}, {FromPid, _Tag}, State) -> Result = gen_tcp:controlling_process(Socket, FromPid), {reply, Result, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info( {inet_async, ListenSocket, Ref, {ok, ClientSocket}}, State = #state{ listen_socket = ListenSocket, acceptor_ref = Ref, service = Service, handler = Handler } ) -> case set_sockopt(ListenSocket, ClientSocket) of ok -> %% New client connected - start processor start_processor(ClientSocket, Service, Handler), {ok, NewRef} = prim_inet:async_accept(ListenSocket, -1), {noreply, State#state{acceptor_ref = NewRef}}; {error, Reason} -> error_logger:error_msg( "Couldn't set socket opts: ~p~n", [Reason] ), {stop, Reason, State} end; handle_info({inet_async, _ListenSocket, _Ref, Error}, State) -> error_logger:error_msg("Error in acceptor: ~p~n", [Error]), {stop, Error, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- set_sockopt(ListenSocket, ClientSocket) -> true = inet_db:register_socket(ClientSocket, inet_tcp), case prim_inet:getopts( ListenSocket, [active, nodelay, keepalive, delay_send, priority, tos] ) of {ok, Opts} -> case prim_inet:setopts(ClientSocket, Opts) of ok -> ok; Error -> gen_tcp:close(ClientSocket), Error end; Error -> gen_tcp:close(ClientSocket), Error end. start_processor(Socket, Service, Handler) -> Server = self(), ProtoGen = fun() -> % Become the controlling process ok = take_socket(Server, Socket), {ok, SocketTransport} = thrift_socket_transport:new(Socket), {ok, BufferedTransport} = thrift_buffered_transport:new(SocketTransport), {ok, Protocol} = thrift_binary_protocol:new(BufferedTransport), {ok, Protocol} end, spawn(thrift_processor, init, [{Server, ProtoGen, Service, Handler}]). thrift-0.23.0/lib/erl/src/thrift_multiplexed_protocol.erl0000664000175000017500000000705615165535636024065 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_multiplexed_protocol). -behaviour(thrift_protocol). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). -export([ new/2, read/2, write/2, flush_transport/1, close_transport/1 ]). -record(protocol, { module :: module(), data :: term() }). -type protocol() :: #protocol{}. -record(multiplexed_protocol, { protocol_module_to_decorate :: atom(), protocol_data_to_decorate :: term(), service_name :: nonempty_string() }). -spec new(ProtocolToDecorate :: protocol(), ServiceName :: nonempty_string()) -> {ok, Protocol :: protocol()}. new(ProtocolToDecorate, ServiceName) when is_record(ProtocolToDecorate, protocol), is_list(ServiceName) -> State = #multiplexed_protocol{ protocol_module_to_decorate = ProtocolToDecorate#protocol.module, protocol_data_to_decorate = ProtocolToDecorate#protocol.data, service_name = ServiceName }, thrift_protocol:new(?MODULE, State). flush_transport( State = #multiplexed_protocol{ protocol_module_to_decorate = ProtocolModuleToDecorate, protocol_data_to_decorate = State0 } ) -> {State1, ok} = ProtocolModuleToDecorate:flush_transport(State0), {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok}. close_transport( State = #multiplexed_protocol{ protocol_module_to_decorate = ProtocolModuleToDecorate, protocol_data_to_decorate = State0 } ) -> {State1, ok} = ProtocolModuleToDecorate:close_transport(State0), {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok}. write( State = #multiplexed_protocol{ protocol_module_to_decorate = ProtocolModuleToDecorate, protocol_data_to_decorate = State0, service_name = ServiceName }, Message = #protocol_message_begin{name = Name} ) -> {State1, ok} = ProtocolModuleToDecorate:write( State0, Message#protocol_message_begin{ name = ServiceName ++ ?MULTIPLEXED_SERVICE_SEPARATOR ++ Name } ), {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok}; write( State = #multiplexed_protocol{ protocol_module_to_decorate = ProtocolModuleToDecorate, protocol_data_to_decorate = State0 }, Message ) -> {State1, ok} = ProtocolModuleToDecorate:write(State0, Message), {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok}. read( State = #multiplexed_protocol{ protocol_module_to_decorate = ProtocolModuleToDecorate, protocol_data_to_decorate = State0 }, Message ) -> {State1, Result} = ProtocolModuleToDecorate:read(State0, Message), {State#multiplexed_protocol{protocol_data_to_decorate = State1}, Result}. thrift-0.23.0/lib/erl/src/thrift_compact_protocol.erl0000664000175000017500000003205315165535636023152 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_compact_protocol). -behaviour(thrift_protocol). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). -export([ new/1, new/2, read/2, write/2, flush_transport/1, close_transport/1, new_protocol_factory/2 ]). -define(ID_NONE, 16#10000). -define(CBOOL_NONE, 0). -define(CBOOL_TRUE, 1). -define(CBOOL_FALSE, 2). -type cbool() :: ?CBOOL_NONE | ?CBOOL_TRUE | ?CBOOL_FALSE. -record(t_compact, { transport :: term(), % state for pending boolean fields read_stack = [] :: iodata(), read_value = ?CBOOL_NONE :: cbool(), write_stack = [] :: iodata(), write_id = ?ID_NONE :: non_neg_integer() }). -type t_compact() :: #t_compact{}. -define(PROTOCOL_ID, 16#82). -define(VERSION_MASK, 16#1f). -define(VERSION_1, 16#01). -define(TYPE_MASK, 16#E0). -define(TYPE_BITS, 16#07). -define(TYPE_SHIFT_AMOUNT, 5). typeid_to_compact(?tType_STOP) -> 16#0; typeid_to_compact(?tType_BOOL) -> 16#2; typeid_to_compact(?tType_I8) -> 16#3; typeid_to_compact(?tType_I16) -> 16#4; typeid_to_compact(?tType_I32) -> 16#5; typeid_to_compact(?tType_I64) -> 16#6; typeid_to_compact(?tType_DOUBLE) -> 16#7; typeid_to_compact(?tType_STRING) -> 16#8; typeid_to_compact(?tType_STRUCT) -> 16#C; typeid_to_compact(?tType_MAP) -> 16#B; typeid_to_compact(?tType_SET) -> 16#A; typeid_to_compact(?tType_LIST) -> 16#9. compact_to_typeid(16#0) -> ?tType_STOP; compact_to_typeid(?CBOOL_FALSE) -> ?tType_BOOL; compact_to_typeid(?CBOOL_TRUE) -> ?tType_BOOL; compact_to_typeid(16#7) -> ?tType_DOUBLE; compact_to_typeid(16#3) -> ?tType_I8; compact_to_typeid(16#4) -> ?tType_I16; compact_to_typeid(16#5) -> ?tType_I32; compact_to_typeid(16#6) -> ?tType_I64; compact_to_typeid(16#8) -> ?tType_STRING; compact_to_typeid(16#C) -> ?tType_STRUCT; compact_to_typeid(16#B) -> ?tType_MAP; compact_to_typeid(16#A) -> ?tType_SET; compact_to_typeid(16#9) -> ?tType_LIST. bool_to_cbool(Value) when Value -> ?CBOOL_TRUE; bool_to_cbool(_) -> ?CBOOL_FALSE. cbool_to_bool(Value) -> Value =:= ?CBOOL_TRUE. new(Transport) -> new(Transport, _Options = []). new(Transport, _Options) -> State = #t_compact{transport = Transport}, thrift_protocol:new(?MODULE, State). flush_transport(This = #t_compact{transport = Transport}) -> {NewTransport, Result} = thrift_transport:flush(Transport), {This#t_compact{transport = NewTransport}, Result}. close_transport(This = #t_compact{transport = Transport}) -> {NewTransport, Result} = thrift_transport:close(Transport), {This#t_compact{transport = NewTransport}, Result}. %%% %%% instance methods %%% write_field_begin(This0 = #t_compact{write_stack = [LastId | T]}, CompactType, Id) -> IdDiff = Id - LastId, This1 = This0#t_compact{write_stack = [Id | T]}, case (IdDiff > 0) and (IdDiff < 16) of true -> write(This1, {byte, (IdDiff bsl 4) bor CompactType}); false -> {This2, ok} = write(This1, {byte, CompactType}), write(This2, {i16, Id}) end. -spec to_zigzag(integer()) -> non_neg_integer(). to_zigzag(Value) -> 16#FFFFFFFFFFFFFFFF band ((Value bsl 1) bxor (Value bsr 63)). -spec from_zigzag(non_neg_integer()) -> integer(). from_zigzag(Value) -> (Value bsr 1) bxor -(Value band 1). -spec to_varint(non_neg_integer(), iolist()) -> iolist(). to_varint(Value, Acc) when (Value < 16#80) -> [Acc, Value]; to_varint(Value, Acc) -> to_varint(Value bsr 7, [Acc, ((Value band 16#7F) bor 16#80)]). -spec read_varint(t_compact(), non_neg_integer(), non_neg_integer()) -> {t_compact(), {'ok', integer()}}. read_varint(This0, Acc, Count) -> {This1, {ok, Byte}} = read(This0, byte), case (Byte band 16#80) of 0 -> {This1, {ok, (Byte bsl (7 * Count)) + Acc}}; _ -> read_varint(This1, ((Byte band 16#7f) bsl (7 * Count)) + Acc, Count + 1) end. write(This0, #protocol_message_begin{ name = Name, type = Type, seqid = Seqid }) -> {This1, ok} = write(This0, {byte, ?PROTOCOL_ID}), {This2, ok} = write( This1, {byte, (?VERSION_1 band ?VERSION_MASK) bor (Type bsl ?TYPE_SHIFT_AMOUNT)} ), {This3, ok} = write(This2, {ui32, Seqid}), {This4, ok} = write(This3, {string, Name}), {This4, ok}; write(This, message_end) -> {This, ok}; write(This0, #protocol_field_begin{ name = _Name, type = Type, id = Id }) when (Type =:= ?tType_BOOL) -> {This0#t_compact{write_id = Id}, ok}; write(This0, #protocol_field_begin{ name = _Name, type = Type, id = Id }) -> write_field_begin(This0, typeid_to_compact(Type), Id); write(This, field_stop) -> write(This, {byte, ?tType_STOP}); write(This, field_end) -> {This, ok}; write(This0, #protocol_map_begin{ ktype = _Ktype, vtype = _Vtype, size = Size }) when Size =:= 0 -> write(This0, {byte, 0}); write(This0, #protocol_map_begin{ ktype = Ktype, vtype = Vtype, size = Size }) -> {This1, ok} = write(This0, {ui32, Size}), write(This1, {byte, (typeid_to_compact(Ktype) bsl 4) bor typeid_to_compact(Vtype)}); write(This, map_end) -> {This, ok}; write(This0, #protocol_list_begin{ etype = Etype, size = Size }) when Size < 16#f -> write(This0, {byte, (Size bsl 4) bor typeid_to_compact(Etype)}); write(This0, #protocol_list_begin{ etype = Etype, size = Size }) -> {This1, ok} = write(This0, {byte, 16#f0 bor typeid_to_compact(Etype)}), write(This1, {ui32, Size}); write(This, list_end) -> {This, ok}; write(This0, #protocol_set_begin{ etype = Etype, size = Size }) -> write(This0, #protocol_list_begin{etype = Etype, size = Size}); write(This, set_end) -> {This, ok}; write(This = #t_compact{write_stack = Stack}, #protocol_struct_begin{}) -> {This#t_compact{write_stack = [0 | Stack]}, ok}; write(This = #t_compact{write_stack = [_ | T]}, struct_end) -> {This#t_compact{write_stack = T}, ok}; write(This = #t_compact{write_id = ?ID_NONE}, {bool, Value}) -> write(This, {byte, bool_to_cbool(Value)}); write(This0 = #t_compact{write_id = Id}, {bool, Value}) -> {This1, ok} = write_field_begin(This0, bool_to_cbool(Value), Id), {This1#t_compact{write_id = ?ID_NONE}, ok}; write(This, {byte, Value}) when is_integer(Value) -> write(This, <>); write(This, {i16, Value}) when is_integer(Value) -> write(This, to_varint(to_zigzag(Value), [])); write(This, {ui32, Value}) when is_integer(Value) -> write(This, to_varint(Value, [])); write(This, {i32, Value}) when is_integer(Value) -> write(This, to_varint(to_zigzag(Value), [])); write(This, {i64, Value}) when is_integer(Value) -> write(This, to_varint(to_zigzag(Value), [])); write(This, {double, Double}) -> write(This, <>); write(This0, {string, Str}) when is_list(Str) -> % TODO: limit length {This1, ok} = write(This0, {ui32, length(Str)}), {This2, ok} = write(This1, list_to_binary(Str)), {This2, ok}; write(This0, {string, Bin}) when is_binary(Bin) -> % TODO: limit length {This1, ok} = write(This0, {ui32, size(Bin)}), {This2, ok} = write(This1, Bin), {This2, ok}; %% Data :: iolist() write(This = #t_compact{transport = Trans}, Data) -> {NewTransport, Result} = thrift_transport:write(Trans, Data), {This#t_compact{transport = NewTransport}, Result}. %% %% read(This0, message_begin) -> {This1, {ok, ?PROTOCOL_ID}} = read(This0, ubyte), {This2, {ok, VerAndType}} = read(This1, ubyte), ?VERSION_1 = VerAndType band ?VERSION_MASK, {This3, {ok, SeqId}} = read(This2, ui32), {This4, {ok, Name}} = read(This3, string), {This4, #protocol_message_begin{ name = binary_to_list(Name), type = (VerAndType bsr ?TYPE_SHIFT_AMOUNT) band ?TYPE_BITS, seqid = SeqId }}; read(This, message_end) -> {This, ok}; read(This = #t_compact{read_stack = Stack}, struct_begin) -> {This#t_compact{read_stack = [0 | Stack]}, ok}; read(This = #t_compact{read_stack = [_H | T]}, struct_end) -> {This#t_compact{read_stack = T}, ok}; read(This0 = #t_compact{read_stack = [LastId | T]}, field_begin) -> {This1, {ok, Byte}} = read(This0, ubyte), case Byte band 16#f of CompactType = ?tType_STOP -> {This1, #protocol_field_begin{type = CompactType}}; CompactType -> {This2, {ok, Id}} = case Byte bsr 4 of 0 -> read(This1, i16); IdDiff -> {This1, {ok, LastId + IdDiff}} end, case compact_to_typeid(CompactType) of ?tType_BOOL -> { This2#t_compact{ read_stack = [Id | T], read_value = CompactType }, #protocol_field_begin{type = ?tType_BOOL, id = Id} }; Type -> {This2#t_compact{read_stack = [Id | T]}, #protocol_field_begin{ type = Type, id = Id }} end end; read(This, field_end) -> {This, ok}; read(This0, map_begin) -> {This1, {ok, Size}} = read(This0, ui32), {This2, {ok, KV}} = case Size of 0 -> {This1, {ok, 0}}; _ -> read(This1, ubyte) end, {This2, #protocol_map_begin{ ktype = compact_to_typeid(KV bsr 4), vtype = compact_to_typeid(KV band 16#f), size = Size }}; read(This, map_end) -> {This, ok}; read(This0, list_begin) -> {This1, {ok, SizeAndType}} = read(This0, ubyte), {This2, {ok, Size}} = case (SizeAndType bsr 4) band 16#f of 16#f -> read(This1, ui32); Else -> {This1, {ok, Else}} end, {This2, #protocol_list_begin{ etype = compact_to_typeid(SizeAndType band 16#f), size = Size }}; read(This, list_end) -> {This, ok}; read(This0, set_begin) -> {This1, {ok, SizeAndType}} = read(This0, ubyte), {This2, {ok, Size}} = case (SizeAndType bsr 4) band 16#f of 16#f -> read(This1, ui32); Else -> {This1, {ok, Else}} end, {This2, #protocol_set_begin{ etype = compact_to_typeid(SizeAndType band 16#f), size = Size }}; read(This, set_end) -> {This, ok}; read(This0, field_stop) -> {This1, {ok, ?tType_STOP}} = read(This0, ubyte), {This1, ok}; %% read(This0 = #t_compact{read_value = ?CBOOL_NONE}, bool) -> {This1, {ok, Byte}} = read(This0, ubyte), {This1, {ok, cbool_to_bool(Byte)}}; read(This0 = #t_compact{read_value = Bool}, bool) -> {This0#t_compact{read_value = ?CBOOL_NONE}, {ok, cbool_to_bool(Bool)}}; read(This0, ubyte) -> {This1, {ok, <>}} = read_data(This0, 1), {This1, {ok, Val}}; read(This0, byte) -> {This1, Bytes} = read_data(This0, 1), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; read(This0, i16) -> {This1, {ok, Zigzag}} = read_varint(This0, 0, 0), {This1, {ok, from_zigzag(Zigzag)}}; read(This0, ui32) -> read_varint(This0, 0, 0); read(This0, i32) -> {This1, {ok, Zigzag}} = read_varint(This0, 0, 0), {This1, {ok, from_zigzag(Zigzag)}}; read(This0, i64) -> {This1, {ok, Zigzag}} = read_varint(This0, 0, 0), {This1, {ok, from_zigzag(Zigzag)}}; read(This0, double) -> {This1, Bytes} = read_data(This0, 8), case Bytes of {ok, <>} -> {This1, {ok, Val}}; Else -> {This1, Else} end; % returns a binary directly, call binary_to_list if necessary read(This0, string) -> {This1, {ok, Sz}} = read(This0, ui32), read_data(This1, Sz). -spec read_data(#t_compact{}, non_neg_integer()) -> {#t_compact{}, {ok, binary()} | {error, _Reason}}. read_data(This, 0) -> {This, {ok, <<>>}}; read_data(This = #t_compact{transport = Trans}, Len) when is_integer(Len) andalso Len > 0 -> {NewTransport, Result} = thrift_transport:read(Trans, Len), {This#t_compact{transport = NewTransport}, Result}. %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% returns a (fun() -> thrift_protocol()) new_protocol_factory(TransportFactory, _Options) -> F = fun() -> case TransportFactory() of {ok, Transport} -> thrift_compact_protocol:new( Transport, [] ); {error, Error} -> {error, Error} end end, {ok, F}. thrift-0.23.0/lib/erl/src/thrift_transport_state_test.erl0000664000175000017500000000755015165535636024102 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_transport_state_test). -behaviour(gen_server). -behaviour(thrift_transport). %% API -export([new/1]). %% gen_server callbacks -export([ init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3 ]). %% thrift_transport callbacks -export([write/2, read/2, flush/1, close/1]). % #thrift_transport{} -record(trans, { wrapped :: thrift_transport:t_transport(), version :: integer(), counter :: pid() }). -record(state, {cversion :: integer()}). new(WrappedTransport) -> case gen_server:start_link(?MODULE, [], []) of {ok, Pid} -> Trans = #trans{ wrapped = WrappedTransport, version = 0, counter = Pid }, thrift_transport:new(?MODULE, Trans); Else -> Else end. %%==================================================================== %% thrift_transport callbacks %%==================================================================== write(Transport0 = #trans{wrapped = Wrapped0}, Data) -> Transport1 = check_version(Transport0), {Wrapped1, Result} = thrift_transport:write(Wrapped0, Data), Transport2 = Transport1#trans{wrapped = Wrapped1}, {Transport2, Result}. flush(Transport0 = #trans{wrapped = Wrapped0}) -> Transport1 = check_version(Transport0), {Wrapped1, Result} = thrift_transport:flush(Wrapped0), Transport2 = Transport1#trans{wrapped = Wrapped1}, {Transport2, Result}. close(Transport0 = #trans{wrapped = Wrapped0}) -> Transport1 = check_version(Transport0), shutdown_counter(Transport1), {Wrapped1, Result} = thrift_transport:close(Wrapped0), Transport2 = Transport1#trans{wrapped = Wrapped1}, {Transport2, Result}. read(Transport0 = #trans{wrapped = Wrapped0}, Len) -> Transport1 = check_version(Transport0), {Wrapped1, Result} = thrift_transport:read(Wrapped0, Len), Transport2 = Transport1#trans{wrapped = Wrapped1}, {Transport2, Result}. %%==================================================================== %% gen_server callbacks %%==================================================================== init([]) -> {ok, #state{cversion = 0}}. handle_call(check_version, _From, State = #state{cversion = Version}) -> {reply, Version, State#state{cversion = Version + 1}}. handle_cast(shutdown, State) -> {stop, normal, State}. handle_info(_Info, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Internal functions %%-------------------------------------------------------------------- check_version(Transport = #trans{version = Version, counter = Counter}) -> case gen_server:call(Counter, check_version) of Version -> Transport#trans{version = Version + 1}; _Else -> % State wasn't propagated properly. Die. erlang:error(state_not_propagated) end. shutdown_counter(#trans{counter = Counter}) -> gen_server:cast(Counter, shutdown). thrift-0.23.0/lib/erl/src/thrift_client.erl0000664000175000017500000001521515165535636021062 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_client). %% API -export([new/2, call/3, send_call/3, close/1]). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). -record(tclient, { service :: module(), protocol :: thrift_protocol:state(), seqid :: non_neg_integer() }). -type tclient() :: #tclient{}. -export_type([tclient/0]). new(Protocol, Service) when is_atom(Service) -> {ok, #tclient{ protocol = Protocol, service = Service, seqid = 0 }}. -spec call(#tclient{}, atom(), list()) -> {#tclient{}, {ok, any()} | {error, any()}}. call(Client = #tclient{}, Function, Args) when is_atom(Function), is_list(Args) -> case send_function_call(Client, Function, Args) of {ok, Client1} -> receive_function_result(Client1, Function); {{error, X}, Client1} -> {Client1, {error, X}} end. %% Sends a function call but does not read the result. This is useful %% if you're trying to log non-oneway function calls to write-only %% transports like thrift_disk_log_transport. -spec send_call(#tclient{}, atom(), list()) -> {#tclient{}, ok}. send_call(Client = #tclient{}, Function, Args) when is_atom(Function), is_list(Args) -> case send_function_call(Client, Function, Args) of {ok, Client1} -> {Client1, ok}; Else -> Else end. -spec close(#tclient{}) -> ok. close(#tclient{protocol = Protocol}) -> thrift_protocol:close_transport(Protocol). %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- -spec send_function_call(#tclient{}, atom(), list()) -> {ok | {error, any()}, #tclient{}}. send_function_call(Client = #tclient{service = Service}, Function, Args) -> {Params, Reply} = try { Service:function_info(Function, params_type), Service:function_info(Function, reply_type) } catch error:function_clause -> {no_function, 0} end, MsgType = case Reply of oneway_void -> ?tMessageType_ONEWAY; _ -> ?tMessageType_CALL end, case Params of no_function -> {{error, {no_function, Function}}, Client}; {struct, PList} when length(PList) =/= length(Args) -> {{error, {bad_args, Function, Args}}, Client}; {struct, _PList} -> write_message(Client, Function, Args, Params, MsgType) end. -spec write_message(#tclient{}, atom(), list(), {struct, list()}, integer()) -> {ok | {error, any()}, #tclient{}}. write_message(Client = #tclient{protocol = P0, seqid = Seq}, Function, Args, Params, MsgType) -> try {P1, ok} = thrift_protocol:write(P0, #protocol_message_begin{ name = atom_to_list(Function), type = MsgType, seqid = Seq }), {P2, ok} = thrift_protocol:write(P1, {Params, list_to_tuple([Function | Args])}), {P3, ok} = thrift_protocol:write(P2, message_end), {P4, ok} = thrift_protocol:flush_transport(P3), {ok, Client#tclient{protocol = P4}} catch error:{badmatch, {_, {error, _} = Error}} -> {Error, Client} end. -spec receive_function_result(#tclient{}, atom()) -> {#tclient{}, {ok, any()} | {error, any()}}. receive_function_result(Client = #tclient{service = Service}, Function) -> ResultType = Service:function_info(Function, reply_type), read_result(Client, Function, ResultType). read_result(Client, _Function, oneway_void) -> {Client, {ok, ok}}; read_result( Client = #tclient{ protocol = Proto0, seqid = SeqId }, Function, ReplyType ) -> case thrift_protocol:read(Proto0, message_begin) of {Proto1, {error, Reason}} -> NewClient = Client#tclient{protocol = Proto1}, {NewClient, {error, Reason}}; {Proto1, MessageBegin} -> NewClient = Client#tclient{protocol = Proto1}, case MessageBegin of #protocol_message_begin{seqid = RetSeqId} when RetSeqId =/= SeqId -> {NewClient, {error, {bad_seq_id, SeqId}}}; #protocol_message_begin{type = ?tMessageType_EXCEPTION} -> handle_application_exception(NewClient); #protocol_message_begin{type = ?tMessageType_REPLY} -> handle_reply(NewClient, Function, ReplyType) end end. handle_reply( Client = #tclient{ protocol = Proto0, service = Service }, Function, ReplyType ) -> {struct, ExceptionFields} = Service:function_info(Function, exceptions), ReplyStructDef = {struct, [{0, ReplyType}] ++ ExceptionFields}, {Proto1, {ok, Reply}} = thrift_protocol:read(Proto0, ReplyStructDef), {Proto2, ok} = thrift_protocol:read(Proto1, message_end), NewClient = Client#tclient{protocol = Proto2}, ReplyList = tuple_to_list(Reply), true = length(ReplyList) == length(ExceptionFields) + 1, ExceptionVals = tl(ReplyList), Thrown = [ X || X <- ExceptionVals, X =/= undefined ], case Thrown of [] when ReplyType == {struct, []} -> {NewClient, {ok, ok}}; [] -> {NewClient, {ok, hd(ReplyList)}}; [Exception] -> throw({NewClient, {exception, Exception}}) end. -spec handle_application_exception(tclient()) -> no_return(). handle_application_exception(Client = #tclient{protocol = Proto0}) -> {Proto1, {ok, Exception}} = thrift_protocol:read(Proto0, ?TApplicationException_Structure), {Proto2, ok} = thrift_protocol:read(Proto1, message_end), XRecord = list_to_tuple( ['TApplicationException' | tuple_to_list(Exception)] ), error_logger:error_msg("X: ~p~n", [XRecord]), true = is_record(XRecord, 'TApplicationException'), NewClient = Client#tclient{protocol = Proto2}, throw({NewClient, {exception, XRecord}}). thrift-0.23.0/lib/erl/src/thrift_socket_transport.erl0000664000175000017500000001435615165535636023215 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_socket_transport). -behaviour(thrift_transport). %% constructors -export([new/1, new/2]). %% transport callbacks -export([read/2, read_exact/2, write/2, flush/1, close/1]). %% legacy api -export([new_transport_factory/3]). -record(t_socket, { socket :: gen_tcp:socket(), recv_timeout = 60000 :: timeout(), buffer = [] :: iodata() }). -spec new(Socket :: any()) -> {ok, thrift_transport:t_transport()}. new(Socket) -> new(Socket, []). -spec new(Socket :: any(), Opts :: list()) -> {ok, thrift_transport:t_transport()}. new(Socket, Opts) when is_list(Opts) -> State = parse_opts(Opts, #t_socket{socket = Socket}), thrift_transport:new(?MODULE, State). parse_opts([{recv_timeout, Timeout} | Rest], State) when is_integer(Timeout), Timeout > 0 -> parse_opts(Rest, State#t_socket{recv_timeout = Timeout}); parse_opts([{recv_timeout, infinity} | Rest], State) -> parse_opts(Rest, State#t_socket{recv_timeout = infinity}); parse_opts([], State) -> State. read(State = #t_socket{buffer = Buf}, Len) when is_integer(Len), Len >= 0 -> Binary = iolist_to_binary(Buf), case iolist_size(Binary) of X when X >= Len -> {Result, Remaining} = split_binary(Binary, Len), {State#t_socket{buffer = Remaining}, {ok, Result}}; _ -> loop_recv(State, Len, Len) end. loop_recv(State = #t_socket{buffer = Buf}, ReadLen, NextReadLen) when NextReadLen =< 0 -> {Result, Remaining} = split_binary(Buf, ReadLen), {State#t_socket{buffer = Remaining}, {ok, Result}}; loop_recv(State = #t_socket{socket = Socket, buffer = Buf}, ReadLen, NextReadLen) when NextReadLen > 0 -> case gen_tcp:recv(Socket, 0, State#t_socket.recv_timeout) of {error, Error} -> gen_tcp:close(Socket), {State, {error, Error}}; {ok, Data} -> Binary = iolist_to_binary([Buf, Data]), Give = min(iolist_size(Binary), ReadLen), loop_recv(State#t_socket{buffer = Binary}, ReadLen, ReadLen - Give) end. read_exact(State = #t_socket{buffer = Buf}, Len) when is_integer(Len), Len >= 0 -> Binary = iolist_to_binary(Buf), case iolist_size(Binary) of X when X >= Len -> read(State, Len); X -> case gen_tcp:recv(State#t_socket.socket, Len - X, State#t_socket.recv_timeout) of {error, Error} -> gen_tcp:close(State#t_socket.socket), {State, {error, Error}}; {ok, Data} -> {State#t_socket{buffer = []}, {ok, <>}} end end. write(State = #t_socket{socket = Socket}, Data) -> case gen_tcp:send(Socket, Data) of {error, Error} -> gen_tcp:close(Socket), {State, {error, Error}}; ok -> {State, ok} end. flush(State) -> {State#t_socket{buffer = []}, ok}. close(State = #t_socket{socket = Socket}) -> {State, gen_tcp:close(Socket)}. %% legacy api. left for compatibility %% The following "local" record is filled in by parse_factory_options/2 %% below. These options can be passed to new_protocol_factory/3 in a %% proplists-style option list. They're parsed like this so it is an O(n) %% operation instead of O(n^2) -record(factory_opts, { connect_timeout = infinity :: timeout(), sockopts = [] :: [inet:inet_backend() | gen_tcp:connect_option()], framed = false :: boolean() }). parse_factory_options([], FactoryOpts, TransOpts) -> {FactoryOpts, TransOpts}; parse_factory_options([{framed, Bool} | Rest], FactoryOpts, TransOpts) when is_boolean(Bool) -> parse_factory_options(Rest, FactoryOpts#factory_opts{framed = Bool}, TransOpts); parse_factory_options([{sockopts, OptList} | Rest], FactoryOpts, TransOpts) when is_list(OptList) -> parse_factory_options(Rest, FactoryOpts#factory_opts{sockopts = OptList}, TransOpts); parse_factory_options([{connect_timeout, TO} | Rest], FactoryOpts, TransOpts) when TO =:= infinity; is_integer(TO) -> parse_factory_options(Rest, FactoryOpts#factory_opts{connect_timeout = TO}, TransOpts); parse_factory_options([{recv_timeout, TO} | Rest], FactoryOpts, TransOpts) when TO =:= infinity; is_integer(TO) -> parse_factory_options(Rest, FactoryOpts, [{recv_timeout, TO}] ++ TransOpts). %% Generates a "transport factory" function - a fun which returns a thrift_transport() %% instance. %% State can be passed into a protocol factory to generate a connection to a %% thrift server over a socket. new_transport_factory(Host, Port, Options) -> {FactoryOpts, TransOpts} = parse_factory_options(Options, #factory_opts{}, []), {ok, fun() -> SockOpts = [ binary, {packet, 0}, {active, false}, {nodelay, true} | FactoryOpts#factory_opts.sockopts ], case catch gen_tcp:connect( Host, Port, SockOpts, FactoryOpts#factory_opts.connect_timeout ) of {ok, Sock} -> {ok, Transport} = thrift_socket_transport:new(Sock, TransOpts), {ok, BufTransport} = case FactoryOpts#factory_opts.framed of true -> thrift_framed_transport:new(Transport); false -> thrift_buffered_transport:new(Transport) end, {ok, BufTransport}; Error -> Error end end}. thrift-0.23.0/lib/erl/src/thrift_http_transport.erl0000664000175000017500000001005315165535636022672 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_http_transport). -behaviour(thrift_transport). %% API -export([new/2, new/3]). %% thrift_transport callbacks -export([write/2, read/2, flush/1, close/1]). % string() -record(http_transport, { host :: string(), path :: string(), read_buffer :: iodata(), write_buffer :: iodata(), % see httpc(3) http_options :: [{atom(), term()}], extra_headers :: [{string(), string()}] }). new(Host, Path) -> new(Host, Path, _Options = []). %%-------------------------------------------------------------------- %% Options include: %% {http_options, HttpOptions} = See http(3) %% {extra_headers, ExtraHeaders} = List of extra HTTP headers %%-------------------------------------------------------------------- new(Host, Path, Options) -> State1 = #http_transport{ host = Host, path = Path, read_buffer = [], write_buffer = [], http_options = [], extra_headers = [] }, ApplyOption = fun ({http_options, HttpOpts}, State = #http_transport{}) -> State#http_transport{http_options = HttpOpts}; ({extra_headers, ExtraHeaders}, State = #http_transport{}) -> State#http_transport{extra_headers = ExtraHeaders}; (Other, #http_transport{}) -> {invalid_option, Other}; (_, Error) -> Error end, case lists:foldl(ApplyOption, State1, Options) of State2 = #http_transport{} -> thrift_transport:new(?MODULE, State2); Else -> {error, Else} end. %% Writes data into the buffer write(State = #http_transport{write_buffer = WBuf}, Data) -> {State#http_transport{write_buffer = [WBuf, Data]}, ok}. %% Flushes the buffer, making a request flush( State = #http_transport{ host = Host, path = Path, read_buffer = Rbuf, write_buffer = Wbuf, http_options = HttpOptions, extra_headers = ExtraHeaders } ) -> case iolist_to_binary(Wbuf) of <<>> -> %% Don't bother flushing empty buffers. {State, ok}; WBinary -> {ok, {{_Version, 200, _ReasonPhrase}, _Headers, Body}} = httpc:request( post, { "http://" ++ Host ++ Path, [{"User-Agent", "Erlang/thrift_http_transport"} | ExtraHeaders], "application/x-thrift", WBinary }, HttpOptions, [{body_format, binary}] ), State1 = State#http_transport{ read_buffer = [Rbuf, Body], write_buffer = [] }, {State1, ok} end. close(State) -> {State, ok}. read(State = #http_transport{read_buffer = RBuf}, Len) when is_integer(Len) -> %% Pull off Give bytes, return them to the user, leave the rest in the buffer. Give = min(iolist_size(RBuf), Len), case iolist_to_binary(RBuf) of <> -> Response = {ok, Data}, State1 = State#http_transport{read_buffer = RBuf1}, {State1, Response}; _ -> {State, {error, 'EOF'}} end. thrift-0.23.0/lib/erl/rebar.config.script0000664000175000017500000000041615165535636020513 0ustar00buildbuild00000000000000Def0 = case not erlang:is_builtin(erlang, monotonic_time, 0) of true -> []; false -> [{d, time_correction}] end, Defs = Def0, lists:keystore(erl_opts, 1, CONFIG, {erl_opts, proplists:get_value(erl_opts, CONFIG, []) ++ Defs}). thrift-0.23.0/lib/erl/test/0000775000175000017500000000000015165535636015704 5ustar00buildbuild00000000000000thrift-0.23.0/lib/erl/test/test_thrift_compact_protocol.erl0000664000175000017500000002146115165535636024402 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_compact_protocol). -include_lib("eunit/include/eunit.hrl"). -include("thrift_constants.hrl"). -include("thrift_protocol.hrl"). new(Transport) -> thrift_compact_protocol:new(Transport). new() -> {ok, Transport} = thrift_membuffer_transport:new(), thrift_compact_protocol:new(Transport). new_test() -> new(thrift_membuffer_transport:new()). write(This, Value) -> thrift_protocol:write(This, Value). read(This, Type) -> thrift_protocol:read(This, Type). str(This0, Value0) -> {This1, ok} = write(This0, {string, Value0}), {This2, {ok, Value1}} = read(This1, string), ?assertEqual(Value0, binary_to_list(Value1)), {This2, ok}. string_test() -> {ok, This0} = new(), {This1, ok} = str(This0, "aaa"), {This2, ok} = str(This1, ""), {This2, ok}. round_trip(This0, Type, Value0) -> {This1, ok} = write(This0, {Type, Value0}), {This2, {ok, Value1}} = read(This1, Type), ?assertEqual(Value0, Value1), {This2, ok}. bool_test() -> {ok, This0} = new(), {This1, ok} = round_trip(This0, bool, true), {This2, ok} = round_trip(This1, bool, false), {This2, ok}. byte(This0, Value0) -> round_trip(This0, byte, Value0). byte_test() -> {ok, This0} = new(), {This1, ok} = byte(This0, 0), {This2, ok} = byte(This1, 42), {This3, ok} = byte(This2, -1), {This4, ok} = byte(This3, -128), {This4, ok}. i16(This0, Value0) -> round_trip(This0, i16, Value0). i16_test() -> {ok, This0} = new(), {This1, ok} = i16(This0, 0), {This2, ok} = i16(This1, 42), {This3, ok} = i16(This2, 30000), {This4, ok} = i16(This3, -1), {This5, ok} = i16(This4, -128), {This6, ok} = i16(This5, -30000), {This6, ok}. i32(This0, Value0) -> round_trip(This0, i32, Value0). i32_test() -> {ok, This0} = new(), {This1, ok} = i32(This0, 0), {This2, ok} = i32(This1, 42), {This3, ok} = i32(This2, 30000), {This4, ok} = i32(This3, 2000000002), {This5, ok} = i32(This4, -1), {This6, ok} = i32(This5, -128), {This7, ok} = i32(This6, -30000), {This8, ok} = i32(This7, -2000000002), {This8, ok}. i64(This0, Value0) -> round_trip(This0, i64, Value0). i64_test() -> {ok, This0} = new(), {This1, ok} = i64(This0, 0), {This2, ok} = i64(This1, 42), {This3, ok} = i64(This2, 30000), {This4, ok} = i64(This3, 2000000002), {This5, ok} = i64(This4, 100000000000000064), {This6, ok} = i64(This5, -1), {This7, ok} = i64(This6, -128), {This8, ok} = i64(This7, -30000), {This9, ok} = i64(This8, -2000000002), {This10, ok} = i64(This9, -100000000000000064), {This10, ok}. struct_test() -> {ok, P0} = new(), {P1, ok} = write(P0, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}), {P2, ok} = write(P1, #protocol_struct_begin{}), {P3, ok} = write(P2, #protocol_field_begin{name = "field1", type = ?tType_I8, id = 1}), {P4, ok} = write(P3, {byte, 42}), {P5, ok} = write(P4, field_end), {P6, ok} = write(P5, #protocol_field_begin{name = "field2", type = ?tType_I8, id = 14}), {P7, ok} = write(P6, {byte, 3}), {P8, ok} = write(P7, field_end), {P9, ok} = write(P8, #protocol_field_begin{name = "field3", type = ?tType_I8, id = 42}), {P10, ok} = write(P9, {byte, 8}), {P11, ok} = write(P10, field_end), {P12, ok} = write(P11, field_stop), {P13, ok} = write(P12, struct_end), {P14, ok} = write(P13, message_end), {P15, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}} = read( P14, message_begin ), {P16, ok} = read(P15, struct_begin), {P17, #protocol_field_begin{type = ?tType_I8, id = 1}} = read(P16, field_begin), {P18, {ok, 42}} = read(P17, byte), {P19, ok} = read(P18, field_end), {P20, #protocol_field_begin{type = ?tType_I8, id = 14}} = read(P19, field_begin), {P21, {ok, 3}} = read(P20, byte), {P22, ok} = read(P21, field_end), {P23, #protocol_field_begin{type = ?tType_I8, id = 42}} = read(P22, field_begin), {P24, {ok, 8}} = read(P23, byte), {P25, ok} = read(P24, field_end), {P26, #protocol_field_begin{type = ?tType_STOP}} = read(P25, field_begin), {P27, ok} = read(P26, struct_end), {P28, ok} = read(P27, message_end), {P28, ok}. bool_field_test() -> {ok, P0} = new(), {P1, ok} = write(P0, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}), {P2, ok} = write(P1, #protocol_struct_begin{}), {P3, ok} = write(P2, #protocol_field_begin{name = "field1", type = ?tType_BOOL, id = 1}), {P4, ok} = write(P3, {bool, true}), {P5, ok} = write(P4, field_end), {P6, ok} = write(P5, #protocol_field_begin{name = "field2", type = ?tType_BOOL, id = 14}), {P7, ok} = write(P6, {bool, false}), {P8, ok} = write(P7, field_end), {P9, ok} = write(P8, #protocol_field_begin{name = "field3", type = ?tType_BOOL, id = 42}), {P10, ok} = write(P9, {bool, true}), {P11, ok} = write(P10, field_end), {P12, ok} = write(P11, field_stop), {P13, ok} = write(P12, struct_end), {P14, ok} = write(P13, message_end), {P15, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}} = read( P14, message_begin ), {P16, ok} = read(P15, struct_begin), {P17, #protocol_field_begin{type = ?tType_BOOL, id = 1}} = read(P16, field_begin), {P18, {ok, true}} = read(P17, bool), {P19, ok} = read(P18, field_end), {P20, #protocol_field_begin{type = ?tType_BOOL, id = 14}} = read(P19, field_begin), {P21, {ok, false}} = read(P20, bool), {P22, ok} = read(P21, field_end), {P23, #protocol_field_begin{type = ?tType_BOOL, id = 42}} = read(P22, field_begin), {P24, {ok, true}} = read(P23, bool), {P25, ok} = read(P24, field_end), {P26, #protocol_field_begin{type = ?tType_STOP}} = read(P25, field_begin), {P27, ok} = read(P26, struct_end), {P28, ok} = read(P27, message_end), {P28, ok}. nesting_test() -> {ok, P0} = new(), {P1, ok} = write(P0, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}), {P2, ok} = write(P1, #protocol_struct_begin{}), {P3, ok} = write(P2, #protocol_field_begin{name = "field1", type = ?tType_BOOL, id = 14}), {P4, ok} = write(P3, {bool, true}), {P5, ok} = write(P4, field_end), {P6, ok} = write(P5, #protocol_field_begin{name = "field2", type = ?tType_STRUCT, id = 28}), {P7, ok} = write(P6, #protocol_struct_begin{}), {P8, ok} = write(P7, #protocol_field_begin{name = "field2_1", type = ?tType_BOOL, id = 30000}), {P9, ok} = write(P8, {bool, false}), {P10, ok} = write(P9, field_end), {P11, ok} = write(P10, field_stop), {P12, ok} = write(P11, struct_end), {P13, ok} = write(P12, field_end), {P14, ok} = write(P13, #protocol_field_begin{name = "field3", type = ?tType_BOOL, id = 42}), {P15, ok} = write(P14, {bool, true}), {P16, ok} = write(P15, field_end), {P17, ok} = write(P16, field_stop), {P18, ok} = write(P17, struct_end), {P19, ok} = write(P18, message_end), {P20, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}} = read( P19, message_begin ), {P21, ok} = read(P20, struct_begin), {P22, #protocol_field_begin{type = ?tType_BOOL, id = 14}} = read(P21, field_begin), {P23, {ok, true}} = read(P22, bool), {P24, ok} = read(P23, field_end), {P25, #protocol_field_begin{type = ?tType_STRUCT, id = 28}} = read(P24, field_begin), {P26, ok} = read(P25, struct_begin), {P27, #protocol_field_begin{type = ?tType_BOOL, id = 30000}} = read(P26, field_begin), {P28, {ok, false}} = read(P27, bool), {P29, ok} = read(P28, field_end), {P30, #protocol_field_begin{type = ?tType_STOP}} = read(P29, field_begin), {P31, ok} = read(P30, struct_end), {P32, ok} = read(P31, field_end), {P33, #protocol_field_begin{type = ?tType_BOOL, id = 42}} = read(P32, field_begin), {P34, {ok, true}} = read(P33, bool), {P35, ok} = read(P34, field_end), {P36, #protocol_field_begin{type = ?tType_STOP}} = read(P35, field_begin), {P37, ok} = read(P36, struct_end), {P38, ok} = read(P37, message_end), {P38, ok}. thrift-0.23.0/lib/erl/test/test_disklog.erl0000664000175000017500000000672715165535636021117 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_disklog). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). disklog_test() -> {ok, TransportFactory} = thrift_disk_log_transport:new_transport_factory( test_disklog, [ {file, "./test_log"}, {size, {1024 * 1024, 10}} ] ), {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(TransportFactory, []), {ok, Proto} = ProtocolFactory(), {ok, Client0} = thrift_client:new(Proto, thrift_test_thrift), io:format("Client started~n"), % We have to make oneway calls into this client only since otherwise it % will try to read from the disklog and go boom. {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]), io:format("Call written~n"), % Use the send_call method to write a non-oneway call into the log {Client2, ok} = thrift_client:send_call(Client1, testString, [<<"hello world">>]), io:format("Non-oneway call sent~n"), {_Client3, ok} = thrift_client:close(Client2), io:format("Client closed~n"), lists:foreach(fun(File) -> file:delete(File) end, [ "./test_log.1", "./test_log.idx", "./test_log.siz" ]), io:format("Cleaning up test files~n"), ok. disklog_base64_test() -> {ok, TransportFactory} = thrift_disk_log_transport:new_transport_factory( test_disklog, [ {file, "./test_b64_log"}, {size, {1024 * 1024, 10}} ] ), {ok, B64Factory} = thrift_base64_transport:new_transport_factory(TransportFactory), {ok, BufFactory} = thrift_buffered_transport:new_transport_factory(B64Factory), {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(BufFactory, []), {ok, Proto} = ProtocolFactory(), {ok, Client0} = thrift_client:new(Proto, thrift_test_thrift), io:format("Client started~n"), % We have to make oneway calls into this client only since otherwise % it will try to read from the disklog and go boom. {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]), io:format("Call written~n"), % Use the send_call method to write a non-oneway call into the log {Client2, ok} = thrift_client:send_call(Client1, testString, [<<"hello world">>]), io:format("Non-oneway call sent~n"), {_Client3, ok} = thrift_client:close(Client2), io:format("Client closed~n"), lists:foreach(fun(File) -> file:delete(File) end, [ "./test_b64_log.1", "./test_b64_log.idx", "./test_b64_log.siz" ]), io:format("Cleaning up test files~n"), ok. -endif. thrift-0.23.0/lib/erl/test/test_thrift_socket_transport.erl0000664000175000017500000002102415165535636024432 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_socket_transport). -include_lib("eunit/include/eunit.hrl"). new(Socket) -> thrift_socket_transport:new(Socket). new(Socket, Opts) -> thrift_socket_transport:new(Socket, Opts). new_test_() -> [ {"new socket", ?_assertMatch( {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 60000, []}}}, new(a_fake_socket) )}, {"new socket with no options", ?_assertMatch( {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 60000, []}}}, new(a_fake_socket, []) )}, {"new socket with integer timeout", ?_assertMatch( {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 5000, []}}}, new(a_fake_socket, [{recv_timeout, 5000}]) )}, {"new socket with infinity timeout", ?_assertMatch( {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, infinity, []}}}, new(a_fake_socket, [{recv_timeout, infinity}]) )} ]. read(Socket, Bytes) -> thrift_socket_transport:read(Socket, Bytes). read_test_() -> {setup, fun() -> meck:new(gen_tcp, [unstick, passthrough]), meck:expect(gen_tcp, recv, fun(Bin, 0, _) -> case Bin of <<"empty">> -> {error, timeout}; _ -> {ok, Bin} end end), meck:expect(gen_tcp, close, fun(_) -> ok end) end, fun(_) -> meck:unload(gen_tcp) end, [ {"read zero bytes from empty socket", ?_assertMatch( {_, {ok, <<>>}}, read({t_socket, <<>>, 60000, []}, 0) )}, {"read 1 byte from empty socket", ?_assertMatch( {_, {error, timeout}}, read({t_socket, <<"empty">>, 60000, []}, 1) )}, {"read zero bytes from nonempty socket", ?_assertMatch( {{t_socket, _, _, _}, {ok, <<>>}}, read({t_socket, <<"hallo world">>, 60000, []}, 0) )}, {"read 1 byte from nonempty socket", ?_assertMatch( {{t_socket, _, _, <<"allo world">>}, {ok, <<"h">>}}, read({t_socket, <<"hallo world">>, 60000, []}, 1) )}, {"read a zillion bytes from nonempty socket", ?_assertMatch( {{t_socket, _, _, <<"ld">>}, {ok, <<"hallo world world world world wor">>}}, read({t_socket, <<"hallo world world world world world">>, 60000, []}, 33) )}, {"read 1 byte from previously buffered socket", ?_assertMatch( {{t_socket, _, _, <<"allo">>}, {ok, <<"h">>}}, read({t_socket, <<" world">>, 60000, <<"hallo">>}, 1) )}, {"read 6 byte from previously buffered socket", ?_assertMatch( {{t_socket, _, _, <<"world">>}, {ok, <<"hallo ">>}}, read({t_socket, <<" world">>, 60000, <<"hallo">>}, 6) )}, {"read a zillion bytes from previously buffered socket", ?_assertMatch( {{t_socket, _, _, <<"ld">>}, {ok, <<"hallo world world world world wor">>}}, read({t_socket, <<" world">>, 60000, <<"hallo">>}, 33) )} ]}. read_exact(Socket, Bytes) -> thrift_socket_transport:read_exact(Socket, Bytes). read_exact_test_() -> {setup, fun() -> meck:new(gen_tcp, [unstick, passthrough]), meck:expect(gen_tcp, recv, fun(Bin, N, _) -> case N of 0 -> {ok, Bin}; 1 -> {ok, <<"h">>}; N when N > 2 -> {error, timeout} end end), meck:expect(gen_tcp, close, fun(_) -> ok end) end, fun(_) -> meck:unload(gen_tcp) end, [ {"read_exact zero bytes from empty socket", ?_assertMatch( {_, {ok, <<>>}}, read_exact({t_socket, <<>>, 60000, []}, 0) )}, {"read_exact zero bytes from nonempty socket", ?_assertMatch( {{t_socket, _, _, _}, {ok, <<>>}}, read_exact({t_socket, <<"hallo world">>, 60000, []}, 0) )}, {"read_exact 1 byte from nonempty socket", ?_assertMatch( {{t_socket, _, _, []}, {ok, <<"h">>}}, read_exact({t_socket, <<"hallo world">>, 60000, []}, 1) )}, {"read_exact a zillion bytes from nonempty socket", ?_assertMatch( {{t_socket, _, _, []}, {error, timeout}}, read_exact({t_socket, <<"hallo world">>, 60000, []}, 65536) )}, {"read_exact 1 byte from previously buffered socket", ?_assertMatch( {{t_socket, _, _, <<"allo">>}, {ok, <<"h">>}}, read_exact({t_socket, <<" world">>, 60000, <<"hallo">>}, 1) )}, {"read_exact 6 byte from previously buffered socket", ?_assertMatch( {{t_socket, _, _, []}, {ok, <<"more h">>}}, read_exact({t_socket, <<"hallo">>, 60000, <<"more ">>}, 6) )}, {"read_exact a zillion bytes from previously buffered socket", ?_assertMatch( {{t_socket, _, _, <<"hallo">>}, {error, timeout}}, read_exact({t_socket, <<" world">>, 60000, <<"hallo">>}, 65536) )} ]}. write(Socket, Data) -> thrift_socket_transport:write(Socket, Data). write_test_() -> {setup, fun() -> meck:new(gen_tcp, [unstick, passthrough]), meck:expect(gen_tcp, send, fun(_, _) -> ok end) end, fun(_) -> meck:unload(gen_tcp) end, [ {"write empty list to socket", ?_assertMatch( {{t_socket, a_fake_socket, 60000, []}, ok}, write({t_socket, a_fake_socket, 60000, []}, []) )}, {"write empty binary to socket", ?_assertMatch( {{t_socket, a_fake_socket, 60000, []}, ok}, write({t_socket, a_fake_socket, 60000, []}, <<>>) )}, {"write a list to socket", ?_assertMatch( {{t_socket, a_fake_socket, 60000, []}, ok}, write({t_socket, a_fake_socket, 60000, []}, "hallo world") )}, {"write a binary to socket", ?_assertMatch( {{t_socket, a_fake_socket, 60000, []}, ok}, write({t_socket, a_fake_socket, 60000, []}, <<"hallo world">>) )} ]}. flush(Transport) -> thrift_socket_transport:flush(Transport). flush_test_() -> [ {"flush socket", ?_assertMatch( {{t_socket, a_fake_socket, 60000, []}, ok}, flush({t_socket, a_fake_socket, 60000, []}) )} ]. close(Transport) -> thrift_socket_transport:close(Transport). close_test_() -> {setup, fun() -> meck:new(gen_tcp, [unstick, passthrough]), meck:expect(gen_tcp, close, fun(_) -> ok end) end, fun(_) -> meck:unload(gen_tcp) end, [ {"close membuffer", ?_assertMatch( {{t_socket, a_fake_socket, 60000, []}, ok}, close({t_socket, a_fake_socket, 60000, []}) )} ]}. thrift-0.23.0/lib/erl/test/test_thrift_file_transport.erl0000664000175000017500000002044515165535636024067 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_file_transport). -include_lib("eunit/include/eunit.hrl"). new(File) -> thrift_file_transport:new(File). new(File, Opts) -> thrift_file_transport:new(File, Opts). new_test_() -> [ {"new file", ?_assertMatch( {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}}, new(a_fake_file) )}, {"new file in read mode", ?_assertMatch( {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, read}}}, new(a_fake_file, [{mode, read}]) )}, {"new file in write mode", ?_assertMatch( {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}}, new(a_fake_file, [{mode, write}]) )}, {"new file in should_close true mode", ?_assertMatch( {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}}, new(a_fake_file, [{should_close, true}]) )}, {"new file in should_close false mode", ?_assertMatch( {ok, {_, thrift_file_transport, {t_file, a_fake_file, false, write}}}, new(a_fake_file, [{should_close, false}]) )} ]. read(File, Bytes) -> thrift_file_transport:read(File, Bytes). read_test_() -> {setup, fun() -> meck:new(file, [unstick, passthrough]), meck:expect(file, read, fun(Bin, N) -> {Result, _} = split_binary(Bin, min(iolist_size(Bin), N)), {ok, Result} end) end, fun(_) -> meck:unload(file) end, [ {"read zero bytes from empty file", ?_assertMatch( {_, {ok, <<>>}}, read({t_file, <<>>, true, read}, 0) )}, {"read 1 byte from empty file", ?_assertMatch( {_, {ok, <<>>}}, read({t_file, <<>>, true, read}, 1) )}, {"read zero bytes from nonempty file", ?_assertMatch( {_, {ok, <<>>}}, read({t_file, <<"hallo world">>, true, read}, 0) )}, {"read 1 byte from nonempty file", ?_assertMatch( {_, {ok, <<"h">>}}, read({t_file, <<"hallo world">>, true, read}, 1) )}, {"read a zillion bytes from nonempty file", ?_assertMatch( {_, {ok, <<"hallo world">>}}, read({t_file, <<"hallo world">>, true, read}, 65536) )}, {"read 0 byte from file in write mode", ?_assertMatch( {_, {error, write_mode}}, read({t_file, <<>>, true, write}, 0) )}, {"read 1 byte from file in write mode", ?_assertMatch( {_, {error, write_mode}}, read({t_file, <<>>, true, write}, 1) )} ]}. read_exact(File, Bytes) -> thrift_file_transport:read_exact(File, Bytes). read_exact_test_() -> {setup, fun() -> meck:new(file, [unstick, passthrough]), meck:expect(file, read, fun(Bin, N) -> {Result, _} = split_binary(Bin, min(iolist_size(Bin), N)), {ok, Result} end) end, fun(_) -> meck:unload(file) end, [ {"read exactly zero bytes from empty file", ?_assertMatch( {_, {ok, <<>>}}, read_exact({t_file, <<>>, true, read}, 0) )}, {"read exactly 1 byte from empty file", ?_assertMatch( {_, {error, eof}}, read_exact({t_file, <<>>, true, read}, 1) )}, {"read exactly zero bytes from nonempty file", ?_assertMatch( {_, {ok, <<>>}}, read_exact({t_file, <<"hallo world">>, true, read}, 0) )}, {"read exactly 1 byte from nonempty file", ?_assertMatch( {_, {ok, <<"h">>}}, read_exact({t_file, <<"hallo world">>, true, read}, 1) )}, {"read exactly a zillion bytes from nonempty file", ?_assertMatch( {_, {error, eof}}, read_exact({t_file, <<"hallo world">>, true, read}, 65536) )}, {"read exactly 0 byte from file in write mode", ?_assertMatch( {_, {error, write_mode}}, read_exact({t_file, <<>>, true, write}, 0) )}, {"read exactly 1 byte from file in write mode", ?_assertMatch( {_, {error, write_mode}}, read_exact({t_file, <<>>, true, write}, 1) )} ]}. write(File, Data) -> thrift_file_transport:write(File, Data). write_test_() -> {setup, fun() -> meck:new(file, [unstick, passthrough]), meck:expect(file, write, fun(_, _) -> ok end) end, fun(_) -> meck:unload(file) end, [ {"write empty list to file", ?_assertMatch( {{t_file, a_fake_file, true, write}, ok}, write({t_file, a_fake_file, true, write}, []) )}, {"write empty binary to file", ?_assertMatch( {{t_file, a_fake_file, true, write}, ok}, write({t_file, a_fake_file, true, write}, <<>>) )}, {"write a list to file", ?_assertMatch( {{t_file, a_fake_file, true, write}, ok}, write({t_file, a_fake_file, true, write}, "hallo world") )}, {"write a binary to file", ?_assertMatch( {{t_file, a_fake_file, true, write}, ok}, write({t_file, a_fake_file, true, write}, <<"hallo world">>) )}, {"write a binary to file in read mode", ?_assertMatch( {_, {error, read_mode}}, write({t_file, a_fake_file, true, read}, <<"hallo world">>) )}, {"write a list to file in read mode", ?_assertMatch( {_, {error, read_mode}}, write({t_file, a_fake_file, true, read}, "hallo world") )} ]}. flush(Transport) -> thrift_file_transport:flush(Transport). flush_test_() -> {setup, fun() -> meck:new(file, [unstick, passthrough]), meck:expect(file, sync, fun(_File) -> ok end) end, fun(_) -> meck:unload(file) end, [ {"flush file", ?_assertMatch( {{t_file, a_fake_file, true, write}, ok}, flush({t_file, a_fake_file, true, write}) )} ]}. close(Transport) -> thrift_file_transport:close(Transport). close_test_() -> {setup, fun() -> meck:new(file, [unstick, passthrough]), meck:expect(file, close, fun(_) -> ok end) end, fun(_) -> meck:unload(file) end, [ {"close file", ?_assertMatch( {{t_file, a_fake_file, true, write}, ok}, close({t_file, a_fake_file, true, write}) )} ]}. thrift-0.23.0/lib/erl/test/test_thrift_framed_transport.erl0000664000175000017500000002667215165535636024416 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_framed_transport). -include_lib("eunit/include/eunit.hrl"). new(Transport) -> thrift_framed_transport:new(Transport). new_test_() -> [ {"new framed membuffer", ?_assertMatch( {ok, {t_transport, thrift_framed_transport, {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, []}}, [], []}}}, new({t_transport, thrift_membuffer_transport, {t_membuffer, []}}) )} ]. read(Frame, Bytes) -> thrift_framed_transport:read(Frame, Bytes). read_test_() -> [ {"read zero bytes from an empty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, {ok, <<>>} }, read( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, 0 ) )}, {"read 1 byte from an empty framed membuffer", ?_assertMatch( {_, {error, eof}}, read( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, 1 ) )}, {"read zero bytes from nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, [], []}, {ok, <<>>} }, read( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, [], []}, 0 ) )}, {"read 1 byte from nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<"allo world">>, []}, {ok, <<"h">>} }, read( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, [], []}, 1 ) )}, {"read 1 byte from nonempty buffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<"allo world">>, []}, {ok, <<"h">>} }, read( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<"hallo world">>, []}, 1 ) )}, {"read a zillion bytes from nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<>>, []}, {ok, <<"hallo world">>} }, read( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, [], []}, 65536 ) )} ]. read_exact(Frame, Bytes) -> thrift_framed_transport:read_exact(Frame, Bytes). read_exact_test_() -> [ {"read exactly zero bytes from an empty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<>>, []}, {ok, <<>>} }, read_exact( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, 0 ) )}, {"read exactly 1 byte from an empty framed membuffer", ?_assertMatch( {_, {error, eof}}, read_exact( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, 1 ) )}, {"read exactly zero bytes from nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, <<>>, []}, {ok, <<>>} }, read_exact( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, [], []}, 0 ) )}, {"read exactly 1 byte from nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<"allo world">>, []}, {ok, <<"h">>} }, read_exact( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, [], []}, 1 ) )}, {"read exactly 1 byte from nonempty buffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<"allo world">>, []}, {ok, <<"h">>} }, read_exact( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<"hallo world">>, []}, 1 ) )}, {"read exactly a zillion bytes from nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [[], <<"hallo world">>], []}, {error, eof} }, read_exact( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<0, 0, 0, 11, "hallo world">>}}, [], []}, 65536 ) )} ]. write(Framed, Data) -> thrift_framed_transport:write(Framed, Data). write_test_() -> [ {"write empty list to empty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [ [], [] ]}, ok }, write( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, [] ) )}, {"write empty list to nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [ ["hallo world"], [] ]}, ok }, write( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [ "hallo world" ]}, [] ) )}, {"write empty binary to empty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [ [], <<>> ]}, ok }, write( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, <<>> ) )}, {"write empty binary to nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [ ["hallo world"], <<>> ]}, ok }, write( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [ "hallo world" ]}, <<>> ) )} ]. flush(Transport) -> thrift_framed_transport:flush(Transport). flush_test_() -> [ {"flush empty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, ok }, flush( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []} ) )}, {"flush nonempty framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, [<<>>, [<<0, 0, 0, 11>>, <<"hallo world">>]]}}, [], []}, ok }, flush( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], <<"hallo world">>} ) )} ]. close(Transport) -> thrift_framed_transport:close(Transport). close_test_() -> {"close framed membuffer", ?_assertMatch( { {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}, ok }, close( {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []} ) )}. thrift-0.23.0/lib/erl/test/stress_server.erl0000664000175000017500000000264315165535636021326 0ustar00buildbuild00000000000000%% %% 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. %% -module(stress_server). -export([ start_link/1, handle_function/2, echoVoid/0, echoByte/1, echoI32/1, echoI64/1, echoString/1, echoList/1, echoSet/1, echoMap/1 ]). start_link(Port) -> thrift_server:start_link(Port, service_thrift, ?MODULE). handle_function(Function, Args) -> case apply(?MODULE, Function, tuple_to_list(Args)) of ok -> ok; Else -> {reply, Else} end. echoVoid() -> ok. echoByte(X) -> X. echoI32(X) -> X. echoI64(X) -> X. echoString(X) -> X. echoList(X) -> X. echoSet(X) -> X. echoMap(X) -> X. thrift-0.23.0/lib/erl/test/test_thrift_1151.erl0000664000175000017500000000325715165535636021425 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_1151). -include("gen-erl/thrift1151_types.hrl"). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). unmatched_struct_test() -> S1 = #'StructC'{x = #'StructB'{x = 1}}, {ok, Transport} = thrift_memory_buffer:new(), {ok, Protocol} = thrift_binary_protocol:new(Transport), ?assertException( error, struct_unmatched, thrift_protocol:write( Protocol, {{struct, element(2, thrift1151_types:struct_info('StructC'))}, S1} ) ). badarg_test() -> S2 = #'StructC'{x = #'StructA'{x = "1"}}, {ok, Transport} = thrift_memory_buffer:new(), {ok, Protocol} = thrift_binary_protocol:new(Transport), ?assertException( error, badarg, thrift_protocol:write( Protocol, {{struct, element(2, thrift1151_types:struct_info('StructC'))}, S2} ) ). -endif. thrift-0.23.0/lib/erl/test/Thrift1475.thrift0000664000175000017500000000302015165535636020702 0ustar00buildbuild00000000000000/* * 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 StructB { 1: string x } struct StructA { 1: string a, 2: binary b, 3: optional string c, 4: optional binary d, 5: required string e, 6: required binary f, 7: string g = "foo", 8: i32 h, 9: optional i32 i, 10: required i32 j, 11: required i32 k = 5, 12: double l, 13: optional double m, 14: required double n, 15: double o = 3.14159, 16: list string_list, 17: list byte_list = [1, 2, 3], 18: required list rsl, 19: optional list osl, 20: set string_set, 21: required set rss, 22: optional set oss, 23: map string_map, 24: required map rsm, 25: optional map osm, 26: StructB structb } thrift-0.23.0/lib/erl/test/multiplexing_test.erl0000664000175000017500000000533015165535636022171 0ustar00buildbuild00000000000000%% %% 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. %% -module(multiplexing_test). -include_lib("eunit/include/eunit.hrl"). -export([ handle_function/2, handle_error/2 ]). start_multiplexed_server_test() -> Port = 9090, Services = [ {"Multiplexing_Calculator", multiplexing__calculator_thrift}, {"Multiplexing_WeatherReport", multiplexing__weather_report_thrift} ], {ok, Pid} = thrift_socket_server:start([ {ip, "127.0.0.1"}, {port, Port}, {name, ?MODULE}, {service, Services}, {handler, [ {"error_handler", ?MODULE}, {"Multiplexing_Calculator", ?MODULE}, {"Multiplexing_WeatherReport", ?MODULE} ]} ]), {ok, [ {"Multiplexing_Calculator", CalculatorClient0}, {"Multiplexing_WeatherReport", WeatherReportClient0} ]} = thrift_client_util:new_multiplexed("127.0.0.1", Port, Services, []), ?assertMatch( {_, {error, {bad_args, _, _}}}, thrift_client:call(WeatherReportClient0, getTemperature, [1]) ), ?assertMatch({_, {error, {bad_args, _, _}}}, thrift_client:call(CalculatorClient0, add, [1])), ?assertMatch( {_, {error, {bad_args, _, _}}}, thrift_client:call(CalculatorClient0, add, [1, 1, 1]) ), ?assertMatch( {_, {error, {no_function, _}}}, thrift_client:call(CalculatorClient0, getTemperature, []) ), ?assertMatch( {_, {error, {no_function, _}}}, thrift_client:call(WeatherReportClient0, add, [41, 1]) ), ?assertMatch({_, {ok, 42}}, thrift_client:call(CalculatorClient0, add, [41, 1])), ?assertMatch({_, {ok, 42.0}}, thrift_client:call(WeatherReportClient0, getTemperature, [])), thrift_socket_server:stop(Pid). %% HANDLE FUNCTIONS %% Calculator handles handle_function(add, {X, Y}) -> {reply, X + Y}; %% WeatherReport handles handle_function(getTemperature, {}) -> {reply, 42.0}. handle_error(_F, _Reason) -> %% ?debugHere, ?debugVal({_F, _Reason}), ok. thrift-0.23.0/lib/erl/test/legacy_names_test.erl0000664000175000017500000000516615165535636022106 0ustar00buildbuild00000000000000%% %% 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. %% -module(legacy_names_test). -include_lib("eunit/include/eunit.hrl"). -include("gen-erl/legacyNames_constants.hrl"). record_generation_test_() -> [ {"capitalizedStruct record", ?_assertMatch( {capitalizedStruct, _, _}, #capitalizedStruct{id = null, message = null} )} ]. struct_info_test_() -> [ {"capitalizedStruct extended definition", ?_assertEqual( {struct, [ {1, undefined, i32, 'id', undefined}, {2, undefined, string, 'message', undefined} ]}, legacyNames_types:struct_info_ext(capitalizedStruct) )}, {"listCapitalizedStructs extended definition", ?_assertEqual( {struct, [ {1, undefined, {list, {struct, {'legacyNames_types', 'capitalizedStruct'}}}, 'structs', []} ]}, legacyNames_types:struct_info_ext(listCapitalizedStructs) )} ]. service_info_test_() -> [ {"names params", ?_assertEqual( {struct, [ {1, {struct, {'legacyNames_types', 'capitalizedStruct'}}}, {2, {struct, {'legacyNames_types', 'capitalizedStruct'}}} ]}, legacyNames_thrift:function_info(names, params_type) )}, {"names reply", ?_assertEqual( {struct, {'legacyNames_types', 'listCapitalizedStructs'}}, legacyNames_thrift:function_info(names, reply_type) )}, {"names exceptions", ?_assertEqual( {struct, [{1, {struct, {'legacyNames_types', 'xception'}}}]}, legacyNames_thrift:function_info(names, exceptions) )} ]. thrift-0.23.0/lib/erl/test/name_conflict_test.erl0000664000175000017500000003245615165535636022262 0ustar00buildbuild00000000000000%% %% 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. %% -module(name_conflict_test). -include_lib("eunit/include/eunit.hrl"). -include("gen-erl/name_conflict_test_constants.hrl"). record_generation_test_() -> [ {"using record", ?_assertMatch( {using, _, _}, #using{single = null, integer = null} )}, {"delegate record", ?_assertMatch( {delegate, _, _}, #delegate{partial = null, delegate = null} )}, {"get record", ?_assertMatch( {get, _}, #get{sbyte = null} )}, {"partial record", ?_assertMatch( {partial, _, _, _}, #partial{using = null} )}, {"ClassAndProp record", ?_assertMatch( {'ClassAndProp', _, _, _, _}, #'ClassAndProp'{ 'ClassAndProp' = null, 'ClassAndProp_' = null, 'ClassAndProp__' = null, 'ClassAndProper' = null } )}, {"second_chance record", ?_assertMatch( {second_chance, _, _, _, _}, #second_chance{ 'SECOND_CHANCE' = null, 'SECOND_CHANCE_' = null, 'SECOND_CHANCE__' = null, 'SECOND_CHANCES' = null } )}, {"NOW_EAT_THIS record", ?_assertMatch( {'NOW_EAT_THIS', _, _, _, _}, #'NOW_EAT_THIS'{ now_eat_this = null, now_eat_this_ = null, now_eat_this__ = null, now_eat_this_and_this = null } )}, {"TheEdgeCase record", ?_assertMatch( {'TheEdgeCase', _, _, _, _, _, _}, #'TheEdgeCase'{ theEdgeCase = null, theEdgeCase_ = null, theEdgeCase__ = null, 'TheEdgeCase' = null, 'TheEdgeCase_' = null, 'TheEdgeCase__' = null } )}, {"Tricky_ record", ?_assertMatch( {'Tricky_', _, _}, #'Tricky_'{tricky = null, 'Tricky' = null} )}, {"Nested record", ?_assertMatch( {'Nested', _, _, _, _, _, _}, #'Nested'{ 'ClassAndProp' = null, second_chance = null, 'NOW_EAT_THIS' = null, 'TheEdgeCase' = null, 'Tricky_' = null, 'Nested' = null } )}, {"Problem_ record", ?_assertMatch( {'Problem_', _, _}, #'Problem_'{problem = null, 'Problem' = null} )} ]. struct_info_test_() -> [ {"using definition", ?_assertEqual( {struct, [{1, double}, {2, double}]}, name_conflict_test_types:struct_info(using) )}, {"delegate definition", ?_assertEqual( {struct, [ {1, string}, {2, {struct, {name_conflict_test_types, delegate}}} ]}, name_conflict_test_types:struct_info(delegate) )}, {"get definition", ?_assertEqual( {struct, [{1, bool}]}, name_conflict_test_types:struct_info(get) )}, {"partial definition", ?_assertEqual( {struct, [ {1, {struct, {name_conflict_test_types, using}}}, {2, bool}, {3, bool} ]}, name_conflict_test_types:struct_info(partial) )}, {"ClassAndProp definition", ?_assertEqual( {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}]}, name_conflict_test_types:struct_info('ClassAndProp') )}, {"second_chance definition", ?_assertEqual( {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}]}, name_conflict_test_types:struct_info(second_chance) )}, {"NOW_EAT_THIS definition", ?_assertEqual( {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}]}, name_conflict_test_types:struct_info('NOW_EAT_THIS') )}, {"TheEdgeCase definition", ?_assertEqual( {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}, {5, bool}, {6, bool}]}, name_conflict_test_types:struct_info('TheEdgeCase') )}, {"Tricky_ definition", ?_assertEqual( {struct, [{1, bool}, {2, bool}]}, name_conflict_test_types:struct_info('Tricky_') )}, {"Nested definition", ?_assertEqual( {struct, [ {1, {struct, {name_conflict_test_types, 'ClassAndProp'}}}, {2, {struct, {name_conflict_test_types, second_chance}}}, {3, {struct, {name_conflict_test_types, 'NOW_EAT_THIS'}}}, {4, {struct, {name_conflict_test_types, 'TheEdgeCase'}}}, {5, {struct, {name_conflict_test_types, 'Tricky_'}}}, {6, {struct, {name_conflict_test_types, 'Nested'}}} ]}, name_conflict_test_types:struct_info('Nested') )}, {"Problem_ definition", ?_assertEqual( {struct, [{1, bool}, {2, bool}]}, name_conflict_test_types:struct_info('Problem_') )}, {"using extended definition", ?_assertEqual( {struct, [ {1, undefined, double, single, undefined}, {2, undefined, double, integer, undefined} ]}, name_conflict_test_types:struct_info_ext(using) )}, {"delegate extended definition", ?_assertEqual( {struct, [ {1, undefined, string, partial, undefined}, {2, undefined, {struct, {name_conflict_test_types, delegate}}, delegate, undefined} ]}, name_conflict_test_types:struct_info_ext(delegate) )}, {"get extended definition", ?_assertEqual( {struct, [{1, undefined, bool, sbyte, undefined}]}, name_conflict_test_types:struct_info_ext(get) )}, {"partial extended definition", ?_assertEqual( {struct, [ {1, undefined, {struct, {name_conflict_test_types, using}}, using, #using{}}, {2, undefined, bool, read, undefined}, {3, undefined, bool, write, undefined} ]}, name_conflict_test_types:struct_info_ext(partial) )}, {"ClassAndProp extended definition", ?_assertEqual( {struct, [ {1, undefined, bool, 'ClassAndProp', undefined}, {2, undefined, bool, 'ClassAndProp_', undefined}, {3, undefined, bool, 'ClassAndProp__', undefined}, {4, undefined, bool, 'ClassAndProper', undefined} ]}, name_conflict_test_types:struct_info_ext('ClassAndProp') )}, {"second_chance extended definition", ?_assertEqual( {struct, [ {1, undefined, bool, 'SECOND_CHANCE', undefined}, {2, undefined, bool, 'SECOND_CHANCE_', undefined}, {3, undefined, bool, 'SECOND_CHANCE__', undefined}, {4, undefined, bool, 'SECOND_CHANCES', undefined} ]}, name_conflict_test_types:struct_info_ext(second_chance) )}, {"NOW_EAT_THIS extended definition", ?_assertEqual( {struct, [ {1, undefined, bool, now_eat_this, undefined}, {2, undefined, bool, now_eat_this_, undefined}, {3, undefined, bool, now_eat_this__, undefined}, {4, undefined, bool, now_eat_this_and_this, undefined} ]}, name_conflict_test_types:struct_info_ext('NOW_EAT_THIS') )}, {"TheEdgeCase extended definition", ?_assertEqual( {struct, [ {1, undefined, bool, theEdgeCase, undefined}, {2, undefined, bool, theEdgeCase_, undefined}, {3, undefined, bool, theEdgeCase__, undefined}, {4, undefined, bool, 'TheEdgeCase', undefined}, {5, undefined, bool, 'TheEdgeCase_', undefined}, {6, undefined, bool, 'TheEdgeCase__', undefined} ]}, name_conflict_test_types:struct_info_ext('TheEdgeCase') )}, {"Tricky_ extended definition", ?_assertEqual( {struct, [ {1, undefined, bool, tricky, undefined}, {2, undefined, bool, 'Tricky', undefined} ]}, name_conflict_test_types:struct_info_ext('Tricky_') )}, {"Nested extended definition", ?_assertEqual( {struct, [ {1, undefined, {struct, { name_conflict_test_types, 'ClassAndProp' }}, 'ClassAndProp', #'ClassAndProp'{}}, {2, undefined, {struct, { name_conflict_test_types, second_chance }}, second_chance, #second_chance{}}, {3, undefined, {struct, { name_conflict_test_types, 'NOW_EAT_THIS' }}, 'NOW_EAT_THIS', #'NOW_EAT_THIS'{}}, {4, undefined, {struct, { name_conflict_test_types, 'TheEdgeCase' }}, 'TheEdgeCase', #'TheEdgeCase'{}}, {5, undefined, {struct, { name_conflict_test_types, 'Tricky_' }}, 'Tricky_', #'Tricky_'{}}, {6, undefined, {struct, { name_conflict_test_types, 'Nested' }}, 'Nested', undefined} ]}, name_conflict_test_types:struct_info_ext('Nested') )}, {"Problem_ extended definition", ?_assertEqual( {struct, [ {1, undefined, bool, problem, undefined}, {2, undefined, bool, 'Problem', undefined} ]}, name_conflict_test_types:struct_info_ext('Problem_') )} ]. service_info_test_() -> [ {"event params", ?_assertEqual( {struct, [{1, {struct, {name_conflict_test_types, partial}}}]}, extern_thrift:function_info(event, params_type) )}, {"event reply", ?_assertEqual( {struct, {name_conflict_test_types, delegate}}, extern_thrift:function_info(event, reply_type) )}, {"event exceptions", ?_assertEqual( {struct, []}, extern_thrift:function_info(event, exceptions) )}, {"Foo params", ?_assertEqual( {struct, [{1, {struct, {name_conflict_test_types, 'Nested'}}}]}, extern_thrift:function_info('Foo', params_type) )}, {"Foo reply", ?_assertEqual( {struct, []}, extern_thrift:function_info('Foo', reply_type) )}, {"Foo exceptions", ?_assertEqual( {struct, [{1, {struct, {name_conflict_test_types, 'Problem_'}}}]}, extern_thrift:function_info('Foo', exceptions) )} ]. thrift-0.23.0/lib/erl/test/test_thrift_buffered_transport.erl0000664000175000017500000002610115165535636024725 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_buffered_transport). -include_lib("eunit/include/eunit.hrl"). new(Transport) -> thrift_buffered_transport:new(Transport). new_test_() -> [ {"new buffered membuffer", ?_assertMatch( {ok, {t_transport, thrift_buffered_transport, {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, []}}, []}}}, new({t_transport, thrift_membuffer_transport, {t_membuffer, []}}) )} ]. read(Frame, Bytes) -> thrift_buffered_transport:read(Frame, Bytes). read_test_() -> [ {"read zero bytes from an empty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, {ok, <<>>} }, read( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, 0 ) )}, {"read 1 byte from an empty buffered membuffer", ?_assertMatch( {_, {ok, <<>>}}, read( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, 1 ) )}, {"read zero bytes from nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, {ok, <<>>} }, read( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 0 ) )}, {"read 1 byte from nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}}, []}, {ok, <<"h">>} }, read( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 1 ) )}, {"read 1 byte from nonempty buffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}}, []}, {ok, <<"h">>} }, read( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 1 ) )}, {"read a zillion bytes from nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, {ok, <<"hallo world">>} }, read( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 65536 ) )} ]. read_exact(Frame, Bytes) -> thrift_buffered_transport:read_exact(Frame, Bytes). read_exact_test_() -> [ {"read exactly zero bytes from an empty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, {ok, <<>>} }, read_exact( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, 0 ) )}, {"read exactly 1 byte from an empty buffered membuffer", ?_assertMatch( {_, {error, eof}}, read_exact( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, 1 ) )}, {"read exactly zero bytes from nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, {ok, <<>>} }, read_exact( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 0 ) )}, {"read exactly 1 byte from nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}}, []}, {ok, <<"h">>} }, read_exact( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 1 ) )}, {"read exactly 1 byte from nonempty buffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}}, []}, {ok, <<"h">>} }, read_exact( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 1 ) )}, {"read exactly a zillion bytes from nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, {error, eof} }, read_exact( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}}, []}, 65536 ) )} ]. write(Framed, Data) -> thrift_buffered_transport:write(Framed, Data). write_test_() -> [ {"write empty list to empty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [ [], [] ]}, ok }, write( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, [] ) )}, {"write empty list to nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [ ["hallo world"], [] ]}, ok }, write( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [ "hallo world" ]}, [] ) )}, {"write empty binary to empty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [ [], <<>> ]}, ok }, write( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, <<>> ) )}, {"write empty binary to nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [ ["hallo world"], <<>> ]}, ok }, write( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [ "hallo world" ]}, <<>> ) )} ]. flush(Transport) -> thrift_buffered_transport:flush(Transport). flush_test_() -> [ {"flush empty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, ok }, flush( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []} ) )}, {"flush nonempty buffered membuffer", ?_assertMatch( { {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, [<<>>, <<"hallo world">>]}}, []}, ok }, flush( {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<"hallo world">>} ) )} ]. close(Transport) -> thrift_buffered_transport:close(Transport). close_test_() -> {"close buffered membuffer", ?_assertMatch( {{t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, ok}, close({t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}) )}. thrift-0.23.0/lib/erl/test/test_thrift_membuffer_transport.erl0000664000175000017500000001473715165535636025127 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_membuffer_transport). -include_lib("eunit/include/eunit.hrl"). new() -> thrift_membuffer_transport:new(). new(Data) -> thrift_membuffer_transport:new(Data). new_test_() -> [ {"new empty membuffer", ?_assertMatch( {ok, {_, _, {t_membuffer, []}}}, new() )}, {"new membuffer with <<>>", ?_assertMatch( {ok, {_, _, {t_membuffer, [<<>>]}}}, new(<<>>) )}, {"new membuffer with []", ?_assertMatch( {ok, {_, _, {t_membuffer, []}}}, new([]) )}, {"new membuffer with <<\"hallo world\">>", ?_assertMatch( {ok, {_, _, {t_membuffer, [<<"hallo world">>]}}}, new(<<"hallo world">>) )}, {"new membuffer with \"hallo world\"", ?_assertMatch( {ok, {_, _, {t_membuffer, "hallo world"}}}, new("hallo world") )} ]. read(Membuffer, Bytes) -> thrift_membuffer_transport:read(Membuffer, Bytes). read_test_() -> [ {"read zero bytes from an empty membuffer", ?_assertMatch( {_, {ok, <<>>}}, read({t_membuffer, []}, 0) )}, {"read 1 byte from an empty membuffer", ?_assertMatch( {_, {ok, <<>>}}, read({t_membuffer, []}, 1) )}, {"read zero bytes from nonempty membuffer", ?_assertMatch( {{t_membuffer, <<"hallo world">>}, {ok, <<>>}}, read({t_membuffer, [["hallo", " "], "world"]}, 0) )}, {"read 1 byte from nonempty membuffer", ?_assertMatch( {{t_membuffer, <<"allo world">>}, {ok, <<"h">>}}, read({t_membuffer, [["hallo", " "], "world"]}, 1) )}, {"read a zillion bytes from nonempty buffer", ?_assertMatch( {{t_membuffer, <<>>}, {ok, <<"hallo world">>}}, read({t_membuffer, [["hallo", " "], "world"]}, 65536) )} ]. read_exact(Membuffer, Bytes) -> thrift_membuffer_transport:read_exact(Membuffer, Bytes). read_exact_test_() -> [ {"read exactly zero bytes from an empty membuffer", ?_assertMatch( {_, {ok, <<>>}}, read_exact({t_membuffer, []}, 0) )}, {"read exactly 1 byte from an empty membuffer", ?_assertMatch( {_, {error, eof}}, read_exact({t_membuffer, []}, 1) )}, {"read exactly zero bytes from nonempty membuffer", ?_assertMatch( {{t_membuffer, <<"hallo world">>}, {ok, <<>>}}, read_exact({t_membuffer, [["hallo", " "], "world"]}, 0) )}, {"read exactly 1 byte from nonempty membuffer", ?_assertMatch( {{t_membuffer, <<"allo world">>}, {ok, <<"h">>}}, read_exact({t_membuffer, [["hallo", " "], "world"]}, 1) )}, {"read exactly a zillion bytes from nonempty buffer", ?_assertMatch( {{t_membuffer, [["hallo", " "], "world"]}, {error, eof}}, read_exact({t_membuffer, [["hallo", " "], "world"]}, 65536) )} ]. write(Membuffer, Data) -> thrift_membuffer_transport:write(Membuffer, Data). write_test_() -> [ {"write empty list to empty membuffer", ?_assertMatch( {{t_membuffer, [[], []]}, ok}, write({t_membuffer, []}, []) )}, {"write empty list to nonempty membuffer", ?_assertMatch( {{t_membuffer, ["hallo world", []]}, ok}, write({t_membuffer, "hallo world"}, []) )}, {"write empty binary to empty membuffer", ?_assertMatch( {{t_membuffer, [[], <<>>]}, ok}, write({t_membuffer, []}, <<>>) )}, {"write empty binary to nonempty membuffer", ?_assertMatch( {{t_membuffer, ["hallo world", <<>>]}, ok}, write({t_membuffer, "hallo world"}, <<>>) )}, {"write a list to empty membuffer", ?_assertMatch( {{t_membuffer, [[], "hallo world"]}, ok}, write({t_membuffer, []}, "hallo world") )}, {"write a list to nonempty membuffer", ?_assertMatch( {{t_membuffer, [["hallo", " "], "world"]}, ok}, write({t_membuffer, ["hallo", " "]}, "world") )}, {"write a binary to empty membuffer", ?_assertMatch( {{t_membuffer, [[], <<"hallo world">>]}, ok}, write({t_membuffer, []}, <<"hallo world">>) )}, {"write a binary to nonempty membuffer", ?_assertMatch( {{t_membuffer, [["hallo", " "], <<"world">>]}, ok}, write({t_membuffer, ["hallo", " "]}, <<"world">>) )} ]. flush(Transport) -> thrift_membuffer_transport:flush(Transport). flush_test_() -> [ {"flush empty membuffer", ?_assertMatch( {{t_membuffer, []}, ok}, flush({t_membuffer, []}) )}, {"flush nonempty membuffer", ?_assertMatch( {{t_membuffer, [<<"hallo world">>]}, ok}, flush({t_membuffer, [<<"hallo world">>]}) )} ]. close(Transport) -> thrift_membuffer_transport:close(Transport). close_test_() -> {"close membuffer", ?_assertMatch( {{t_membuffer, _}, ok}, close({t_membuffer, []}) )}. thrift-0.23.0/lib/erl/test/thrift_socket_server_test.erl0000664000175000017500000001260315165535636023707 0ustar00buildbuild00000000000000%% %% 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. %% -module(thrift_socket_server_test). -include_lib("eunit/include/eunit.hrl"). -include("thrift_constants.hrl"). parse_handler_options_test_() -> CorrectServiceHandlerOptionList = [ {?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {"Service1", ?MODULE}, {"Service2", ?MODULE} ], MissingErrorHandlerOptionList = [{"Service1", ?MODULE}, {"Service2", ?MODULE}], WrongService2HandlerOptionList = [ {?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {"Service1", ?MODULE}, {"Service2", "Module"} ], WrongServiceKeyOptionList = [ {?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {'service1', ?MODULE}, {"Service2", ?MODULE} ], CorrectHandlerTestFunction = fun() -> ?assertMatch( #{}, thrift_socket_server:parse_options([{handler, CorrectServiceHandlerOptionList}]) ), #{handler := HandlerList} = thrift_socket_server:parse_options( [ {handler, CorrectServiceHandlerOptionList} ] ), lists:foreach( fun({ServiceName, HandlerModule}) -> ?assertMatch( {ok, HandlerModule} when is_atom(HandlerModule), thrift_multiplexed_map_wrapper:find(ServiceName, HandlerList) ) end, CorrectServiceHandlerOptionList ) end, [ {"Bad argument for the handler option", ?_assertThrow(_, thrift_socket_server:parse_options([{handler, []}]))}, {"Try to parse the handler option twice", ?_assertThrow( _, thrift_socket_server:parse_options([ {handler, ?MODULE}, {handler, CorrectServiceHandlerOptionList} ]) )}, {"Parse the handler option as a non multiplexed service handler", ?_assertMatch( #{handler := ?MODULE}, thrift_socket_server:parse_options([{handler, ?MODULE}]) )}, {"No error handler was defined", ?_assertThrow( _, thrift_socket_server:parse_options([{handler, MissingErrorHandlerOptionList}]) )}, {"Bad handler module for Service2", ?_assertThrow( _, thrift_socket_server:parse_options([{handler, WrongService2HandlerOptionList}]) )}, {"Bad service key for Service1", ?_assertThrow( _, thrift_socket_server:parse_options([{handler, WrongServiceKeyOptionList}]) )}, {"Try to parse a correct handler option list", CorrectHandlerTestFunction} ]. parse_service_options_test_() -> CorrectServiceModuleOptionList = [{"Service1", ?MODULE}, {"Service2", ?MODULE}], WrongService2ModuleOptionList = [{"Service1", ?MODULE}, {"Service2", "thrift_service_module"}], WrongServiceKeyOptionList = [{'service1', ?MODULE}, {"Service2", ?MODULE}], CorrectServiceModuleTestFunction = fun() -> ?assertMatch( #{}, thrift_socket_server:parse_options([{service, CorrectServiceModuleOptionList}]) ), #{service := ServiceModuleList} = thrift_socket_server:parse_options( [{service, CorrectServiceModuleOptionList}] ), lists:foreach( fun({ServiceName, ServiceModule}) -> ?assertMatch( {ok, ServiceModule} when is_atom(ServiceModule), thrift_multiplexed_map_wrapper:find(ServiceName, ServiceModuleList) ) end, CorrectServiceModuleOptionList ) end, [ {"Bad argument for the service option", ?_assertThrow(_, thrift_socket_server:parse_options([{service, []}]))}, {"Try to parse the service option twice", ?_assertThrow( _, thrift_socket_server:parse_options([ {service, ?MODULE}, {service, CorrectServiceModuleOptionList} ]) )}, {"Parse a service module for a non multiplexed service", ?_assertMatch( #{service := ?MODULE}, thrift_socket_server:parse_options([{service, ?MODULE}]) )}, {"Bad service module for Service2", ?_assertThrow( _, thrift_socket_server:parse_options([{service, WrongService2ModuleOptionList}]) )}, {"Bad service key for Service1", ?_assertThrow( _, thrift_socket_server:parse_options([{service, WrongServiceKeyOptionList}]) )}, {"Try to parse a correct service option list", CorrectServiceModuleTestFunction} ]. thrift-0.23.0/lib/erl/test/thrift_test_test.erl0000664000175000017500000007512115165535636022014 0ustar00buildbuild00000000000000%% %% 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. %% % don't rename this thrift_test, it clobbers generated files -module(thrift_test_test). -include_lib("eunit/include/eunit.hrl"). -include("gen-erl/thrift_test_constants.hrl"). constant_test_() -> [ {"myNumberz equals 1", ?_assertEqual(1, ?THRIFT_TEST_MYNUMBERZ)} ]. record_generation_test_() -> [ {"Bonk record", ?_assertMatch( {'thrift.test.Bonk', _, _}, #'thrift.test.Bonk'{message = null, type = null} )}, {"Bools record", ?_assertMatch( {'thrift.test.Bools', _, _}, #'thrift.test.Bools'{im_true = null, im_false = null} )}, {"Xtruct record", ?_assertMatch( {'thrift.test.Xtruct', _, _, _, _}, #'thrift.test.Xtruct'{ string_thing = null, byte_thing = null, i32_thing = null, i64_thing = null } )}, {"Xtruct2 record", ?_assertMatch( {'thrift.test.Xtruct2', _, _, _}, #'thrift.test.Xtruct2'{byte_thing = null, struct_thing = null, i32_thing = null} )}, {"Xtruct3 record", ?_assertMatch( {'thrift.test.Xtruct3', _, _, _, _}, #'thrift.test.Xtruct3'{ string_thing = null, changed = null, i32_thing = null, i64_thing = null } )}, {"Insanity record", ?_assertMatch( {'thrift.test.Insanity', _, _}, #'thrift.test.Insanity'{userMap = null, xtructs = null} )}, {"CrazyNesting record", ?_assertMatch( {'thrift.test.CrazyNesting', _, _, _, _}, #'thrift.test.CrazyNesting'{ string_field = null, set_field = null, list_field = null, binary_field = null } )}, {"Xception record", ?_assertMatch( {'thrift.test.Xception', _, _}, #'thrift.test.Xception'{errorCode = null, message = null} )}, {"Xception2 record", ?_assertMatch( {'thrift.test.Xception2', _, _}, #'thrift.test.Xception2'{errorCode = null, struct_thing = null} )}, {"EmptyStruct record", ?_assertMatch({'thrift.test.EmptyStruct'}, #'thrift.test.EmptyStruct'{})}, {"OneField record", ?_assertMatch({'thrift.test.OneField', _}, #'thrift.test.OneField'{field = null})}, {"VersioningTestV1 record", ?_assertMatch( {'thrift.test.VersioningTestV1', _, _, _}, #'thrift.test.VersioningTestV1'{ begin_in_both = null, old_string = null, end_in_both = null } )}, {"VersioningTestV2 record", ?_assertMatch( {'thrift.test.VersioningTestV2', _, _, _, _, _, _, _, _, _, _, _, _}, #'thrift.test.VersioningTestV2'{ begin_in_both = null, newint = null, newbyte = null, newshort = null, newlong = null, newdouble = null, newstruct = null, newlist = null, newset = null, newmap = null, newstring = null, end_in_both = null } )}, {"ListTypeVersioningV1 record", ?_assertMatch( {'thrift.test.ListTypeVersioningV1', _, _}, #'thrift.test.ListTypeVersioningV1'{myints = null, hello = null} )}, {"ListTypeVersioningV2 record", ?_assertMatch( {'thrift.test.ListTypeVersioningV2', _, _}, #'thrift.test.ListTypeVersioningV2'{strings = null, hello = null} )}, {"GuessProtocolStruct record", ?_assertMatch( {'thrift.test.GuessProtocolStruct', _}, #'thrift.test.GuessProtocolStruct'{map_field = null} )}, {"LargeDeltas record", ?_assertMatch( {'thrift.test.LargeDeltas', _, _, _, _, _, _, _, _, _, _}, #'thrift.test.LargeDeltas'{ b1 = null, b10 = null, b100 = null, check_true = null, b1000 = null, check_false = null, vertwo2000 = null, a_set2500 = null, vertwo3000 = null, big_numbers = null } )}, {"NestedListsI32x2 record", ?_assertMatch( {'thrift.test.NestedListsI32x2', _}, #'thrift.test.NestedListsI32x2'{integerlist = null} )}, {"NestedListsI32x3 record", ?_assertMatch( {'thrift.test.NestedListsI32x3', _}, #'thrift.test.NestedListsI32x3'{integerlist = null} )}, {"NestedMixedx2 record", ?_assertMatch( {'thrift.test.NestedMixedx2', _, _, _}, #'thrift.test.NestedMixedx2'{ int_set_list = null, map_int_strset = null, map_int_strset_list = null } )}, {"ListBonks record", ?_assertMatch({'thrift.test.ListBonks', _}, #'thrift.test.ListBonks'{bonk = null})}, {"NestedListsBonk record", ?_assertMatch( {'thrift.test.NestedListsBonk', _}, #'thrift.test.NestedListsBonk'{bonk = null} )}, {"BoolTest record", ?_assertMatch( {'thrift.test.BoolTest', _, _}, #'thrift.test.BoolTest'{b = null, s = null} )}, {"StructA record", ?_assertMatch({'thrift.test.StructA', _}, #'thrift.test.StructA'{s = null})}, {"StructB record", ?_assertMatch( {'thrift.test.StructB', _, _}, #'thrift.test.StructB'{aa = null, ab = null} )} ]. struct_info_test_() -> [ {"Bonk definition (short version)", ?_assertEqual( {struct, [{1, string}, {2, i32}]}, thrift_test_types:struct_info('thrift.test.Bonk') )}, {"Bonk definition", ?_assertEqual( {struct, [ {1, undefined, string, message, undefined}, {2, undefined, i32, type, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.Bonk') )}, {"Bools definition", ?_assertEqual( {struct, [ {1, undefined, bool, im_true, undefined}, {2, undefined, bool, im_false, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.Bools') )}, {"Xtruct definition", ?_assertEqual( {struct, [ {1, undefined, string, string_thing, undefined}, {4, undefined, byte, byte_thing, undefined}, {9, undefined, i32, i32_thing, undefined}, {11, undefined, i64, i64_thing, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.Xtruct') )}, {"Xtruct2 definition", ?_assertEqual( {struct, [ {1, undefined, byte, byte_thing, undefined}, {2, undefined, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}}, struct_thing, #'thrift.test.Xtruct'{}}, {3, undefined, i32, i32_thing, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.Xtruct2') )}, {"Xtruct3 definition", ?_assertEqual( {struct, [ {1, undefined, string, string_thing, undefined}, {4, undefined, i32, changed, undefined}, {9, undefined, i32, i32_thing, undefined}, {11, undefined, i64, i64_thing, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.Xtruct3') )}, {"Insanity definition", ?_assertEqual( {struct, [ {1, undefined, {map, i32, i64}, userMap, dict:new()}, {2, undefined, {list, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}}}, xtructs, []} ]}, thrift_test_types:struct_info_ext('thrift.test.Insanity') )}, {"CrazyNesting definition", ?_assertEqual( {struct, [ {1, undefined, string, string_field, undefined}, {2, optional, {set, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}}, set_field, sets:new()}, {3, required, {list, {map, {set, i32}, {map, i32, {set, {list, {map, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}, string}}}}}}, list_field, []}, {4, undefined, string, binary_field, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.CrazyNesting') )}, {"Xception definition", ?_assertEqual( {struct, [ {1, undefined, i32, errorCode, undefined}, {2, undefined, string, message, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.Xception') )}, {"Xception2 definition", ?_assertEqual( {struct, [ {1, undefined, i32, errorCode, undefined}, {2, undefined, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}}, struct_thing, #'thrift.test.Xtruct'{}} ]}, thrift_test_types:struct_info_ext('thrift.test.Xception2') )}, {"EmptyStruct definition", ?_assertEqual( {struct, []}, thrift_test_types:struct_info_ext('thrift.test.EmptyStruct') )}, {"OneField definition", ?_assertEqual( {struct, [ {1, undefined, {struct, {'thrift_test_types', 'thrift.test.EmptyStruct'}}, field, #'thrift.test.EmptyStruct'{}} ]}, thrift_test_types:struct_info_ext('thrift.test.OneField') )}, {"VersioningTestV1 definition", ?_assertEqual( {struct, [ {1, undefined, i32, begin_in_both, undefined}, {3, undefined, string, old_string, undefined}, {12, undefined, i32, end_in_both, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.VersioningTestV1') )}, {"VersioningTestV2 definition", ?_assertEqual( {struct, [ {1, undefined, i32, begin_in_both, undefined}, {2, undefined, i32, newint, undefined}, {3, undefined, byte, newbyte, undefined}, {4, undefined, i16, newshort, undefined}, {5, undefined, i64, newlong, undefined}, {6, undefined, double, newdouble, undefined}, {7, undefined, {struct, {thrift_test_types, 'thrift.test.Bonk'}}, newstruct, #'thrift.test.Bonk'{}}, {8, undefined, {list, i32}, newlist, []}, {9, undefined, {set, i32}, newset, sets:new()}, {10, undefined, {map, i32, i32}, newmap, dict:new()}, {11, undefined, string, newstring, undefined}, {12, undefined, i32, end_in_both, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.VersioningTestV2') )}, {"ListTypeVersioningV1 definition", ?_assertEqual( {struct, [ {1, undefined, {list, i32}, myints, []}, {2, undefined, string, hello, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.ListTypeVersioningV1') )}, {"ListTypeVersioningV2 definition", ?_assertEqual( {struct, [ {1, undefined, {list, string}, strings, []}, {2, undefined, string, hello, undefined} ]}, thrift_test_types:struct_info_ext('thrift.test.ListTypeVersioningV2') )}, {"GuessProtocolStruct definition", ?_assertEqual( {struct, [ {7, undefined, {map, string, string}, map_field, dict:new()} ]}, thrift_test_types:struct_info_ext('thrift.test.GuessProtocolStruct') )}, {"LargeDeltas definition", ?_assertEqual( {struct, [ {1, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b1, #'thrift.test.Bools'{}}, {10, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b10, #'thrift.test.Bools'{}}, {100, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b100, #'thrift.test.Bools'{}}, {500, undefined, bool, check_true, undefined}, {1000, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b1000, #'thrift.test.Bools'{}}, {1500, undefined, bool, check_false, undefined}, {2000, undefined, {struct, {thrift_test_types, 'thrift.test.VersioningTestV2'}}, vertwo2000, #'thrift.test.VersioningTestV2'{}}, {2500, undefined, {set, string}, a_set2500, sets:new()}, {3000, undefined, {struct, {thrift_test_types, 'thrift.test.VersioningTestV2'}}, vertwo3000, #'thrift.test.VersioningTestV2'{}}, {4000, undefined, {list, i32}, big_numbers, []} ]}, thrift_test_types:struct_info_ext('thrift.test.LargeDeltas') )}, {"NestedListsI32x2 definition", ?_assertEqual( {struct, [ {1, undefined, {list, {list, i32}}, integerlist, []} ]}, thrift_test_types:struct_info_ext('thrift.test.NestedListsI32x2') )}, {"NestedListsI32x3 definition", ?_assertEqual( {struct, [ {1, undefined, {list, {list, {list, i32}}}, integerlist, []} ]}, thrift_test_types:struct_info_ext('thrift.test.NestedListsI32x3') )}, {"NestedMixedx2 definition", ?_assertEqual( {struct, [ {1, undefined, {list, {set, i32}}, int_set_list, []}, {2, undefined, {map, i32, {set, string}}, map_int_strset, dict:new()}, {3, undefined, {list, {map, i32, {set, string}}}, map_int_strset_list, []} ]}, thrift_test_types:struct_info_ext('thrift.test.NestedMixedx2') )}, {"ListBonks definition", ?_assertEqual( {struct, [ {1, undefined, {list, {struct, {thrift_test_types, 'thrift.test.Bonk'}}}, bonk, []} ]}, thrift_test_types:struct_info_ext('thrift.test.ListBonks') )}, {"NestedListsBonk definition", ?_assertEqual( {struct, [ {1, undefined, {list, {list, {list, {struct, {thrift_test_types, 'thrift.test.Bonk'}}}}}, bonk, []} ]}, thrift_test_types:struct_info_ext('thrift.test.NestedListsBonk') )}, {"BoolTest definition", ?_assertEqual( {struct, [ {1, optional, bool, b, true}, {2, optional, string, s, "true"} ]}, thrift_test_types:struct_info_ext('thrift.test.BoolTest') )}, {"StructA definition", ?_assertEqual( {struct, [{1, required, string, s, undefined}]}, thrift_test_types:struct_info_ext('thrift.test.StructA') )}, {"StructB definition", ?_assertEqual( {struct, [ {1, optional, {struct, {thrift_test_types, 'thrift.test.StructA'}}, aa, #'thrift.test.StructA'{}}, {2, required, {struct, {thrift_test_types, 'thrift.test.StructA'}}, ab, #'thrift.test.StructA'{}} ]}, thrift_test_types:struct_info_ext('thrift.test.StructB') )} ]. service_info_test_() -> [ {"testVoid params", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testVoid, params_type) )}, {"testVoid reply", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testVoid, reply_type) )}, {"testVoid exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testVoid, exceptions) )}, {"testString params", ?_assertEqual( {struct, [{1, string}]}, thrift_test_thrift:function_info(testString, params_type) )}, {"testString reply", ?_assertEqual( string, thrift_test_thrift:function_info(testString, reply_type) )}, {"testString exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testString, exceptions) )}, {"testByte params", ?_assertEqual( {struct, [{1, byte}]}, thrift_test_thrift:function_info(testByte, params_type) )}, {"testByte reply", ?_assertEqual( byte, thrift_test_thrift:function_info(testByte, reply_type) )}, {"testByte exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testByte, exceptions) )}, {"testI32 params", ?_assertEqual( {struct, [{1, i32}]}, thrift_test_thrift:function_info(testI32, params_type) )}, {"testI32 reply", ?_assertEqual( i32, thrift_test_thrift:function_info(testI32, reply_type) )}, {"testI32 exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testI32, exceptions) )}, {"testI64 params", ?_assertEqual( {struct, [{1, i64}]}, thrift_test_thrift:function_info(testI64, params_type) )}, {"testI64 reply", ?_assertEqual( i64, thrift_test_thrift:function_info(testI64, reply_type) )}, {"testI64 exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testI64, exceptions) )}, {"testDouble params", ?_assertEqual( {struct, [{1, double}]}, thrift_test_thrift:function_info(testDouble, params_type) )}, {"testDouble reply", ?_assertEqual( double, thrift_test_thrift:function_info(testDouble, reply_type) )}, {"testDouble exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testDouble, exceptions) )}, {"testStruct params", ?_assertEqual( {struct, [ {1, {struct, {thrift_test_types, 'thrift.test.Xtruct'}}} ]}, thrift_test_thrift:function_info(testStruct, params_type) )}, {"testStruct reply", ?_assertEqual( {struct, {thrift_test_types, 'thrift.test.Xtruct'}}, thrift_test_thrift:function_info(testStruct, reply_type) )}, {"testStruct exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testStruct, exceptions) )}, {"testNest params", ?_assertEqual( {struct, [ {1, {struct, {thrift_test_types, 'thrift.test.Xtruct2'}}} ]}, thrift_test_thrift:function_info(testNest, params_type) )}, {"testNest reply", ?_assertEqual( {struct, {thrift_test_types, 'thrift.test.Xtruct2'}}, thrift_test_thrift:function_info(testNest, reply_type) )}, {"testNest exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testNest, exceptions) )}, {"testMap params", ?_assertEqual( {struct, [ {1, {map, i32, i32}} ]}, thrift_test_thrift:function_info(testMap, params_type) )}, {"testMap reply", ?_assertEqual( {map, i32, i32}, thrift_test_thrift:function_info(testMap, reply_type) )}, {"testMap exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testMap, exceptions) )}, {"testStringMap params", ?_assertEqual( {struct, [ {1, {map, string, string}} ]}, thrift_test_thrift:function_info(testStringMap, params_type) )}, {"testStringMap reply", ?_assertEqual( {map, string, string}, thrift_test_thrift:function_info(testStringMap, reply_type) )}, {"testStringMap exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testStringMap, exceptions) )}, {"testSet params", ?_assertEqual( {struct, [ {1, {set, i32}} ]}, thrift_test_thrift:function_info(testSet, params_type) )}, {"testSet reply", ?_assertEqual( {set, i32}, thrift_test_thrift:function_info(testSet, reply_type) )}, {"testSet exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testSet, exceptions) )}, {"testList params", ?_assertEqual( {struct, [ {1, {list, i32}} ]}, thrift_test_thrift:function_info(testList, params_type) )}, {"testList reply", ?_assertEqual( {list, i32}, thrift_test_thrift:function_info(testList, reply_type) )}, {"testList exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testList, exceptions) )}, {"testEnum params", ?_assertEqual( {struct, [ {1, i32} ]}, thrift_test_thrift:function_info(testEnum, params_type) )}, {"testEnum reply", ?_assertEqual( i32, thrift_test_thrift:function_info(testEnum, reply_type) )}, {"testEnum exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testEnum, exceptions) )}, {"testTypedef params", ?_assertEqual( {struct, [{1, i64}]}, thrift_test_thrift:function_info(testTypedef, params_type) )}, {"testTypedef reply", ?_assertEqual( i64, thrift_test_thrift:function_info(testTypedef, reply_type) )}, {"testTypedef exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testTypedef, exceptions) )}, {"testMapMap params", ?_assertEqual( {struct, [ {1, i32} ]}, thrift_test_thrift:function_info(testMapMap, params_type) )}, {"testMapMap reply", ?_assertEqual( {map, i32, {map, i32, i32}}, thrift_test_thrift:function_info(testMapMap, reply_type) )}, {"testMapMap exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testMapMap, exceptions) )}, {"testInsanity params", ?_assertEqual( {struct, [ {1, {struct, {thrift_test_types, 'thrift.test.Insanity'}}} ]}, thrift_test_thrift:function_info(testInsanity, params_type) )}, {"testInsanity reply", ?_assertEqual( {map, i64, {map, i32, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}}}, thrift_test_thrift:function_info(testInsanity, reply_type) )}, {"testInsanity exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testInsanity, exceptions) )}, {"testMulti params", ?_assertEqual( {struct, [ {1, byte}, {2, i32}, {3, i64}, {4, {map, i16, string}}, {5, i32}, {6, i64} ]}, thrift_test_thrift:function_info(testMulti, params_type) )}, {"testMulti reply", ?_assertEqual( {struct, {thrift_test_types, 'thrift.test.Xtruct'}}, thrift_test_thrift:function_info(testMulti, reply_type) )}, {"testMulti exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testMulti, exceptions) )}, {"testException params", ?_assertEqual( {struct, [{1, string}]}, thrift_test_thrift:function_info(testException, params_type) )}, {"testException reply", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testException, reply_type) )}, {"testException exceptions", ?_assertEqual( {struct, [ {1, {struct, {thrift_test_types, 'thrift.test.Xception'}}} ]}, thrift_test_thrift:function_info(testException, exceptions) )}, {"testMultiException params", ?_assertEqual( {struct, [{1, string}, {2, string}]}, thrift_test_thrift:function_info(testMultiException, params_type) )}, {"testMultiException reply", ?_assertEqual( {struct, {thrift_test_types, 'thrift.test.Xtruct'}}, thrift_test_thrift:function_info(testMultiException, reply_type) )}, {"testMultiException exceptions", ?_assertEqual( {struct, [ {1, {struct, {thrift_test_types, 'thrift.test.Xception'}}}, {2, {struct, {thrift_test_types, 'thrift.test.Xception2'}}} ]}, thrift_test_thrift:function_info(testMultiException, exceptions) )}, {"testOneway params", ?_assertEqual( {struct, [{1, i32}]}, thrift_test_thrift:function_info(testOneway, params_type) )}, {"testOneway reply", ?_assertEqual( oneway_void, thrift_test_thrift:function_info(testOneway, reply_type) )}, {"testOneway exceptions", ?_assertEqual( {struct, []}, thrift_test_thrift:function_info(testOneway, exceptions) )}, {"secondtestString params", ?_assertEqual( {struct, [{1, string}]}, second_service_thrift:function_info(secondtestString, params_type) )}, {"secondtestString reply", ?_assertEqual( string, second_service_thrift:function_info(secondtestString, reply_type) )}, {"secondtestString exceptions", ?_assertEqual( {struct, []}, second_service_thrift:function_info(secondtestString, exceptions) )} ]. thrift-0.23.0/lib/erl/test/test_omit.erl0000664000175000017500000001005515165535636020420 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_omit). -include("gen-erl/thrift_omit_with_types.hrl"). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). omit_struct1_test() -> %% In this test, the field that is deleted is a basic type (an i32). A = #test1{one = 1, three = 3}, B = #test1{one = 1, two = 2, three = 3}, {ok, Transport} = thrift_membuffer_transport:new(), {ok, P0} = thrift_binary_protocol:new(Transport), {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}), {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}), ?assertEqual(element(1, A), element(1, O0)), ?assertEqual(element(2, A), element(2, O0)), ?assertEqual(element(4, A), element(3, O0)), {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}), {_P4, {ok, O1}} = thrift_protocol:read( P3, {struct, {thrift_omit_without_types, element(1, A)}} ), ?assertEqual(element(1, A), element(1, O1)), ?assertEqual(element(2, A), element(2, O1)), ?assertEqual(element(4, A), element(3, O1)), ok. omit_struct2_test() -> %% In this test, the field that is deleted is a struct. A = #test2{one = 1, two = #test2{one = 10, three = 30}, three = 3}, B = #test2{one = 1, two = #test2{one = 10, two = #test2{one = 100}, three = 30}, three = 3}, {ok, Transport} = thrift_membuffer_transport:new(), {ok, P0} = thrift_binary_protocol:new(Transport), {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}), {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}), ?assertEqual(element(1, A), element(1, O0)), ?assertEqual(element(2, A), element(2, O0)), ?assertEqual(element(4, A), element(3, O0)), {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}), {_P4, {ok, O1}} = thrift_protocol:read( P3, {struct, {thrift_omit_without_types, element(1, A)}} ), ?assertEqual(element(1, A), element(1, O1)), ?assertEqual(element(2, A), element(2, O1)), ?assertEqual(element(4, A), element(3, O1)), ok. omit_list_test() -> %% In this test, the field that is deleted is a list. A = #test1{one = 1, two = 2, three = 3}, B = #test3{one = 1, two = [A]}, {ok, Transport} = thrift_membuffer_transport:new(), {ok, P0} = thrift_binary_protocol:new(Transport), {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}), {_P2, {ok, O0}} = thrift_protocol:read( P1, {struct, {thrift_omit_without_types, element(1, B)}} ), ?assertEqual(element(2, B), element(2, O0)), ok. omit_map_test() -> %% In this test, the field that is deleted is a map. A = #test1{one = 1, two = 2, three = 3}, B = #test4{one = 1, two = dict:from_list([{2, A}])}, {ok, Transport} = thrift_membuffer_transport:new(), {ok, P0} = thrift_binary_protocol:new(Transport), {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}), {_P2, {ok, O0}} = thrift_protocol:read( P1, {struct, {thrift_omit_without_types, element(1, B)}} ), ?assertEqual(element(2, B), element(2, O0)), ok. %% TEST -endif. thrift-0.23.0/lib/erl/test/flags/0000775000175000017500000000000015165535636017000 5ustar00buildbuild00000000000000thrift-0.23.0/lib/erl/test/flags/Thrift3214.thrift0000664000175000017500000000155115165535636021776 0ustar00buildbuild00000000000000/* * 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 StringMap { 1: map data = {1: "a", 2: "b"}; } thrift-0.23.0/lib/erl/test/flags/LegacyNames.thrift0000664000175000017500000000234615165535636022417 0ustar00buildbuild00000000000000/* * 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. */ enum Numberz { ONE = 1, TWO, THREE, FIVE = 5, SIX, EIGHT = 8 } const Numberz myNumberz = Numberz.ONE; struct CapitalizedStruct { 1: i32 Id, 2: binary message } struct ListCapitalizedStructs { 1: list structs } exception Xception { 1: i32 errorCode, 2: binary message } service LegacyNames { ListCapitalizedStructs Names(1: CapitalizedStruct foo, 2: CapitalizedStruct bar) throws(1: Xception err) }thrift-0.23.0/lib/erl/test/test_thrift_3214.erl0000664000175000017500000000371515165535636021426 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_thrift_3214). -include("gen-erl/thrift3214_types.hrl"). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). record_generation_test_() -> [ {"StringMap record", ?_assertMatch( {'StringMap', _}, #'StringMap'{data = #{50 => "foo"}} )}, {"StringMap record defaults", ?_assertEqual( {'StringMap', #{1 => "a", 2 => "b"}}, #'StringMap'{} )}, {"StringMap record dict from list", ?_assertNotEqual( {'StringMap', dict:from_list([{1, "a"}, {2, "b"}])}, #'StringMap'{} )}, {"StringMap record map from list", ?_assertEqual( {'StringMap', maps:from_list([{1, "a"}, {2, "b"}])}, #'StringMap'{} )} ]. struct_info_test_() -> [ {"StringMap extended definition", ?_assertEqual( {struct, [ {1, undefined, {map, i32, string}, 'data', #{1 => "a", 2 => "b"}} ]}, thrift3214_types:struct_info_ext('StringMap') )} ]. -endif. thrift-0.23.0/lib/erl/test/test_const.erl0000664000175000017500000000416415165535636020602 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_const). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -include("gen-erl/constants_demo_types.hrl"). namespace_test() -> %% Verify that records produced by ConstantsDemo.thrift have the right namespace. io:format(user, "in namespace_test()\n", []), {struct, _} = constants_demo_types:struct_info('consts_thing'), {struct, _} = constants_demo_types:struct_info('consts_Blah'), ok. const_map_test() -> ?assertEqual(233, constants_demo_constants:gen_map(35532)), ?assertError(function_clause, constants_demo_constants:gen_map(0)), ?assertEqual(853, constants_demo_constants:gen_map(43523, default)), ?assertEqual(default, constants_demo_constants:gen_map(10110, default)), ?assertEqual(98325, constants_demo_constants:gen_map2("lkjsdf")), ?assertError(function_clause, constants_demo_constants:gen_map2("nonexist")), ?assertEqual(233, constants_demo_constants:gen_map2("hello", 321)), ?assertEqual(321, constants_demo_constants:gen_map2("goodbye", 321)). const_list_test() -> ?assertEqual(23598352, constants_demo_constants:gen_list(2)), ?assertError(function_clause, constants_demo_constants:gen_list(0)), ?assertEqual(3253523, constants_demo_constants:gen_list(3, default)), ?assertEqual(default, constants_demo_constants:gen_list(10, default)). %% TEST -endif. thrift-0.23.0/lib/erl/test/Thrift1151.thrift0000664000175000017500000000160015165535636020673 0ustar00buildbuild00000000000000/* * 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 StructA { 1: i16 x; } struct StructB { 1: i32 x; } struct StructC { 1: StructA x; } thrift-0.23.0/lib/erl/test/multiplexing.thrift0000664000175000017500000000165515165535636021656 0ustar00buildbuild00000000000000/* * 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. */ service Multiplexing_Calculator { i32 add(1: i32 x, 2: i32 y) } service Multiplexing_WeatherReport { double getTemperature() } thrift-0.23.0/lib/erl/test/Thrift_omit_with.thrift0000664000175000017500000000213715165535636022454 0ustar00buildbuild00000000000000/* * 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 test1 { 1: i32 one 2: i32 two // omit 3: i32 three } struct test2 { 1: i32 one 2: test2 two // omit 3: i32 three } struct test3 { 1: i32 one 2: list two // omit } struct test4 { 1: i32 one 2: map two // omit } thrift-0.23.0/lib/erl/test/test_rendered_double_constants.erl0000664000175000017500000001202015165535636024660 0ustar00buildbuild00000000000000%% %% 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. %% -module(test_rendered_double_constants). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -include("gen-erl/double_constants_test_constants.hrl"). -define(EPSILON, 0.0000001). rendered_double_constants_test() -> ?assert(abs(1.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST) =< ?EPSILON), ?assert( abs(-100.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST) =< ?EPSILON ), ?assert( abs( 9223372036854775807.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST ) =< ?EPSILON ), ?assert( abs( -9223372036854775807.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST ) =< ?EPSILON ), ?assert( abs( 3.14159265359 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST ) =< ?EPSILON ), ?assert( abs(1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON ), ?assert( abs(-1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON ), ?assert( abs(1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST) =< ?EPSILON ), ?assert( abs( 9223372036854775816.43 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST ) =< ?EPSILON ), ?assert( abs(-1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST) =< ?EPSILON ), ?assert( abs( -9223372036854775816.43 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST ) =< ?EPSILON ), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST)), ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST)), ?assert( is_float( ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST ) ). rendered_double_list_test() -> ?assertEqual(12, length(?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)), ?assert(abs(1.0 - lists:nth(1, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert(abs(-100.0 - lists:nth(2, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert(abs(100.0 - lists:nth(3, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert( abs(9223372036854775807.0 - lists:nth(4, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON ), ?assert( abs(-9223372036854775807.0 - lists:nth(5, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON ), ?assert(abs(3.14159265359 - lists:nth(6, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert(abs(1000000.1 - lists:nth(7, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert(abs(-1000000.1 - lists:nth(8, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert(abs(1.7e+308 - lists:nth(9, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert(abs(-1.7e+308 - lists:nth(10, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON), ?assert( abs(9223372036854775816.43 - lists:nth(11, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON ), ?assert( abs(-9223372036854775816.43 - lists:nth(12, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON ). %% TEST -endif. thrift-0.23.0/lib/erl/coding_standards.md0000664000175000017500000000031515165535636020554 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) Particularly for Erlang please follow the Erlang [Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml). thrift-0.23.0/lib/erl/README.md0000664000175000017500000000332715165535636016211 0ustar00buildbuild00000000000000# Thrift Erlang Software Library # ## License ## Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ## Release Notes ## ### 0.9.2 ### as of 0.9.2 struct and function naming conventions have changed. to retain the old naming conventions (for backwards compatibility) use the compiler option `legacynames` ## Example ## Example session using thrift_client: ```erl 1> {ok, C0} = thrift_client_util:new("localhost", 9090, thrift_test_thrift, []), ok. ok 2> {C1, R1} = thrift_client:call(C0, testVoid, []), R1. {ok,ok} 3> {C2, R2} = thrift_client:call(C1, testVoid, [asdf]), R2. {error,{bad_args,testVoid,[asdf]}} 4> {C3, R3} = thrift_client:call(C2, testI32, [123]), R3. {ok,123} 5> {C4, R4} = thrift_client:call(C3, testOneway, [1]), R4. {ok,ok} 6> {C5, R5} = thrift_client:call(C4, testXception, ["foo"]), R5. {error,{no_function,testXception}} 7> {C6, R6} = thrift_client:call(C5, testException, ["foo"]), R6. {ok,ok} 8> {C7, R7} = (catch thrift_client:call(C6, testException, ["Xception"])), R7. {exception,{xception,1001,<<"Xception">>}} ``` thrift-0.23.0/lib/erl/Makefile.in0000644000175000017500000004624515170007167016770 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/erl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = ../../compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ THRIFT_OMIT_FILE = test/Thrift_omit_without.thrift THRIFT_FILES = $(wildcard test/*.thrift) \ $(THRIFT_OMIT_FILE) \ ../../test/v0.16/ConstantsDemo.thrift \ ../../test/v0.16/NameConflictTest.thrift \ ../../test/DoubleConstantsTest.thrift \ ../../test/v0.16/ThriftTest.thrift ERL_FLAG = erl ERL_FLAG_LEGACY = erl:legacynames ERL_FLAG_MAPS = erl:maps EXTRA_DIST = \ include \ src \ coding_standards.md \ rebar.config \ rebar.config.script \ test \ README.md MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/erl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/erl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install-exec: install-exec-am install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am dist-hook distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic maintainer-clean-local mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile $(THRIFT_OMIT_FILE): test/Thrift_omit_with.thrift grep -v omit $< >$@ .generated: $(THRIFT) $(THRIFT_FILES) for f in $(THRIFT_FILES) ; do \ $(THRIFT) --gen $(ERL_FLAG) -o test $$f ; \ done $(THRIFT) --gen $(ERL_FLAG_LEGACY) -o test test/flags/LegacyNames.thrift $(THRIFT) --gen $(ERL_FLAG_MAPS) -o test test/flags/Thrift3214.thrift touch .generated all: .generated $(REBAR) compile check: .generated $(REBAR) eunit install: all mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift) ; \ mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/ebin ; \ mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/include ; \ mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/src ; \ for p in ebin/*.app* ebin/*.beam include/*.hrl src/*.erl ; \ do $(INSTALL) $$p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/$$p ; \ done uninstall: $(RM) -rf $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift) clean-local: $(REBAR) clean $(RM) .generated $(RM) -r .rebar/ $(RM) -r _build/ $(RM) -r test/gen-erl/ $(RM) $(THRIFT_OMIT_FILE) maintainer-clean-local: $(RM) -r ebin/ dist-hook: $(RM) $(distdir)/.generated $(RM) -r $(distdir)/.rebar/ $(RM) -r $(distdir)/_build/ $(RM) -r $(distdir)/ebin/ $(RM) -r $(distdir)/test/gen-erl/ $(RM) $(distdir)/$(THRIFT_OMIT_FILE) distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/erl/rebar.config0000664000175000017500000000200515165535636017204 0ustar00buildbuild00000000000000%% Common project erlang options. {erl_opts, [ % mandatory debug_info, warn_export_all, warn_untyped_record, warn_export_vars, % by default warn_unused_record, warn_bif_clash, warn_obsolete_guard, warn_unused_vars, warn_shadow_vars, warn_unused_import, warn_unused_function, warn_deprecated_function ]}. %% XRef checks {xref_checks, [ deprecated_functions_calls, deprecated_functions ]}. %% Dialyzer static analyzing {dialyzer, [ {warnings, [ % mandatory unmatched_returns, error_handling, unknown % hardcore mode % overspecs, % underspecs ]}, {plt_extra_apps, [ssl, inets, public_key]} ]}. {plugins, [ {erlfmt, "1.5.0"} ]}. {erlfmt, [ {print_width, 100}, {files, "{src,include,test}/*.{hrl,erl,app.src}"} ]}. {profiles, [ {test, [ {deps, [{meck, "0.9.2"}]}, {eunit_tests, [ {dir, "test"}, {dir, "test/gen-erl"} ]} ]} ]}. thrift-0.23.0/lib/erl/Makefile.am0000664000175000017500000000515315165535636016765 0ustar00buildbuild00000000000000# # 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. # THRIFT = ../../compiler/cpp/thrift THRIFT_OMIT_FILE = test/Thrift_omit_without.thrift THRIFT_FILES = $(wildcard test/*.thrift) \ $(THRIFT_OMIT_FILE) \ ../../test/v0.16/ConstantsDemo.thrift \ ../../test/v0.16/NameConflictTest.thrift \ ../../test/DoubleConstantsTest.thrift \ ../../test/v0.16/ThriftTest.thrift ERL_FLAG = erl ERL_FLAG_LEGACY = erl:legacynames ERL_FLAG_MAPS = erl:maps $(THRIFT_OMIT_FILE): test/Thrift_omit_with.thrift grep -v omit $< >$@ .generated: $(THRIFT) $(THRIFT_FILES) for f in $(THRIFT_FILES) ; do \ $(THRIFT) --gen $(ERL_FLAG) -o test $$f ; \ done $(THRIFT) --gen $(ERL_FLAG_LEGACY) -o test test/flags/LegacyNames.thrift $(THRIFT) --gen $(ERL_FLAG_MAPS) -o test test/flags/Thrift3214.thrift touch .generated all: .generated $(REBAR) compile check: .generated $(REBAR) eunit install: all mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift) ; \ mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/ebin ; \ mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/include ; \ mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/src ; \ for p in ebin/*.app* ebin/*.beam include/*.hrl src/*.erl ; \ do $(INSTALL) $$p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)/$$p ; \ done uninstall: $(RM) -rf $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift) clean-local: $(REBAR) clean $(RM) .generated $(RM) -r .rebar/ $(RM) -r _build/ $(RM) -r test/gen-erl/ $(RM) $(THRIFT_OMIT_FILE) maintainer-clean-local: $(RM) -r ebin/ dist-hook: $(RM) $(distdir)/.generated $(RM) -r $(distdir)/.rebar/ $(RM) -r $(distdir)/_build/ $(RM) -r $(distdir)/ebin/ $(RM) -r $(distdir)/test/gen-erl/ $(RM) $(distdir)/$(THRIFT_OMIT_FILE) distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ include \ src \ coding_standards.md \ rebar.config \ rebar.config.script \ test \ README.md MAINTAINERCLEANFILES = Makefile.in thrift-0.23.0/lib/erl/include/0000775000175000017500000000000015165535636016350 5ustar00buildbuild00000000000000thrift-0.23.0/lib/erl/include/thrift_constants.hrl0000664000175000017500000000421615165535636022456 0ustar00buildbuild00000000000000%% %% 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. %% %% TType -define(tType_STOP, 0). -define(tType_VOID, 1). -define(tType_BOOL, 2). -define(tType_BYTE, 3). -define(tType_I8, 3). -define(tType_DOUBLE, 4). -define(tType_I16, 6). -define(tType_I32, 8). -define(tType_I64, 10). -define(tType_STRING, 11). -define(tType_STRUCT, 12). -define(tType_MAP, 13). -define(tType_SET, 14). -define(tType_LIST, 15). % TMessageType -define(tMessageType_CALL, 1). -define(tMessageType_REPLY, 2). -define(tMessageType_EXCEPTION, 3). -define(tMessageType_ONEWAY, 4). % TApplicationException -define(TApplicationException_Structure, {struct, [ {1, string}, {2, i32} ]} ). -record('TApplicationException', { message :: string(), type :: integer() }). -define(TApplicationException_UNKNOWN, 0). -define(TApplicationException_UNKNOWN_METHOD, 1). -define(TApplicationException_INVALID_MESSAGE_TYPE, 2). -define(TApplicationException_WRONG_METHOD_NAME, 3). -define(TApplicationException_BAD_SEQUENCE_ID, 4). -define(TApplicationException_MISSING_RESULT, 5). -define(TApplicationException_INTERNAL_ERROR, 6). -define(TApplicationException_PROTOCOL_ERROR, 7). -define(TApplicationException_INVALID_TRANSFORM, 8). -define(TApplicationException_INVALID_PROTOCOL, 9). -define(TApplicationException_UNSUPPORTED_CLIENT_TYPE, 10). -define(MULTIPLEXED_SERVICE_SEPARATOR, ":"). -define(MULTIPLEXED_ERROR_HANDLER_KEY, "error_handler"). thrift-0.23.0/lib/erl/include/thrift_protocol.hrl0000664000175000017500000000401315165535636022276 0ustar00buildbuild00000000000000%% %% 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_PROTOCOL_INCLUDED). -define(THRIFT_PROTOCOL_INCLUDED, true). -record(protocol_message_begin, {name :: string(), type :: integer(), seqid :: integer()}). -record(protocol_struct_begin, {name :: undefined | string()}). -record(protocol_field_begin, { name :: undefined | string(), type :: integer(), id :: undefined | integer() }). -record(protocol_map_begin, {ktype :: integer(), vtype :: integer(), size :: integer()}). -record(protocol_list_begin, {etype :: integer(), size :: integer()}). -record(protocol_set_begin, {etype :: integer(), size :: integer()}). -type tprot_header_val() :: #protocol_message_begin{} | #protocol_struct_begin{} | #protocol_field_begin{} | #protocol_map_begin{} | #protocol_list_begin{} | #protocol_set_begin{}. -type tprot_empty_tag() :: message_end | struct_begin | struct_end | field_end | map_end | list_end | set_end. -type tprot_header_tag() :: message_begin | field_begin | map_begin | list_begin | set_begin. -type tprot_data_tag() :: ui32 | bool | byte | i16 | i32 | i64 | double | string. -type tprot_cont_tag() :: {list, _Type} | {map, _KType, _VType} | {set, _Type}. -endif. thrift-0.23.0/lib/kotlin/0000755000175000017500000000000015170007200015412 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/0000775000175000017500000000000015167543515021022 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/0000775000175000017500000000000015165535636021614 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/0000775000175000017500000000000015165535636022540 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/kotlin/0000775000175000017500000000000015165535636024040 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/kotlin/org/0000775000175000017500000000000015165535636024627 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/0000775000175000017500000000000015165535636026050 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/thrift/0000775000175000017500000000000015165535636027350 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/thrift/test/0000775000175000017500000000000015167543515030324 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/kotlin/org/apache/thrift/test/TestClient.kt0000664000175000017500000007031015167543515032743 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.parameters.options.default import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.enum import com.github.ajalt.clikt.parameters.types.int import java.nio.ByteBuffer import kotlin.math.abs import kotlin.system.exitProcess import kotlinx.coroutines.runBlocking import org.apache.thrift.TApplicationException import org.apache.thrift.TException import org.apache.thrift.TSerializer import org.apache.thrift.async.TAsyncClientManager import org.apache.thrift.protocol.TBinaryProtocol import org.apache.thrift.protocol.TCompactProtocol import org.apache.thrift.protocol.TJSONProtocol import org.apache.thrift.protocol.TProtocol import org.apache.thrift.protocol.TSimpleJSONProtocol import org.apache.thrift.transport.TNonblockingSocket import org.apache.thrift.transport.TNonblockingTransport import org.apache.thrift.transport.TSSLTransportFactory import org.apache.thrift.transport.TTransport import thrift.test.Insanity import thrift.test.Numberz import thrift.test.SecondServiceClient import thrift.test.ThriftTestClient import thrift.test.Xception import thrift.test.Xception2 import thrift.test.Xtruct import thrift.test.Xtruct2 /** * Test Java client for thrift. Essentially just a copy of the C++ version, this makes a variety of * requests to enable testing for both performance and correctness of the output. */ const val ERR_BASETYPES = 1 const val ERR_STRUCTS = 2 const val ERR_CONTAINERS = 4 const val ERR_EXCEPTIONS = 8 const val ERR_PROTOCOLS = 16 const val ERR_UNKNOWN = 64 enum class ProtocolType(val key: String) { Binary("binary"), Multi("multi"), Json("json"), MultiJson("multij"), Compact("compact"), MultiCompact("multic"), } enum class TransportType(val key: String) { Buffered("buffered"), Framed("framed"), FastFramed("fastframed"), Http("http"), } class TestClient : CliktCommand() { private val host: String by option(help = "The cross test host to connect to").default("localhost") private val port: Int by option(help = "The cross test port to connect to").int().default(9090) private val numTests: Int by option("--testloops", "--n", help = "Number of runs in this test").int().default(1) private val protocolType: ProtocolType by option("--protocol", help = "Protocol type") .enum { it.key } .default(ProtocolType.Binary) private val transportType: TransportType by option("--transport", help = "Transport type") .enum { it.key } .default(TransportType.Buffered) private val useHttpClient: Boolean by option("--client", help = "Use http client").flag(default = false) private val useSSL: Boolean by option("--ssl", help = "Use SSL for encrypted transport").flag(default = false) private val useZlib: Boolean by option("--zlib", help = "Use zlib wrapper for compressed transport").flag(default = false) private val socketTimeout: Int by option("--timeout", help = "Socket timeout").int().default(1000) private fun createProtocol(transport: TTransport): TProtocol = when (protocolType) { ProtocolType.Binary, ProtocolType.Multi -> TBinaryProtocol(transport) ProtocolType.Compact, ProtocolType.MultiCompact -> TCompactProtocol(transport) ProtocolType.Json, ProtocolType.MultiJson -> TJSONProtocol(transport) } private fun createTransport(): TNonblockingTransport = when (transportType) { TransportType.Framed -> if (useSSL) TSSLTransportFactory.getNonblockingClientSocket(host, port, socketTimeout) else TNonblockingSocket(host, port, socketTimeout) else -> throw UnsupportedOperationException( "only frame transport type is supported for now, got $transportType" ) } private val clientManager = TAsyncClientManager() private fun createClient(): ThriftTestClient = ThriftTestClient({ createProtocol(it) }, clientManager, createTransport()) private fun createSecondServiceClient(): SecondServiceClient = SecondServiceClient({ createProtocol(it) }, clientManager, createTransport()) override fun run() = runBlocking { var testClient = createClient() val insane = Insanity() var timeMin: Long = 0 var timeMax: Long = 0 var timeTot: Long = 0 var returnCode = 0 for (test in 0 until numTests) { try { /** CONNECT TEST */ /** CONNECT TEST */ // if (!transport.isOpen) { // try { // transport.open() // } catch (ttx: TTransportException) { // ttx.printStackTrace() // println("Connect failed: " + ttx.message) // exitProcess(ERR_UNKNOWN) // } // } println("Test #${test + 1}, connect $host:$port") val start = System.nanoTime() /** VOID TEST */ /** VOID TEST */ returnCode = testClient.voidTest(returnCode) /** STRING TEST */ /** STRING TEST */ returnCode = testClient.stringTest(returnCode) /** Multiplexed test */ /** Multiplexed test */ returnCode = multiplexTest(returnCode) /** BYTE TEST */ /** BYTE TEST */ returnCode = testClient.byteTest(returnCode) /** I32 TEST */ /** I32 TEST */ returnCode = testClient.i32Test(returnCode) /** I64 TEST */ /** I64 TEST */ returnCode = testClient.i64Test(returnCode) /** DOUBLE TEST */ /** DOUBLE TEST */ returnCode = testClient.doubleTest(returnCode) /** BINARY TEST */ /** BINARY TEST */ returnCode = testClient.binaryTest(returnCode) /** STRUCT TEST */ /** STRUCT TEST */ val pair = testClient.structTest(returnCode) val out = pair.first returnCode = pair.second /** NESTED STRUCT TEST */ /** NESTED STRUCT TEST */ returnCode = testClient.nestedStructTest(out, returnCode) /** MAP TEST */ /** MAP TEST */ val testMapParam = (0..4).associateBy { 10 - it } printMap(testMapParam) val testMapResult: Map = testClient.testMap(testMapParam) printMap(testMapResult) if (testMapParam != testMapResult) { returnCode = returnCode or ERR_CONTAINERS println("*** FAILURE ***\n") } /** STRING MAP TEST */ /** STRING MAP TEST */ returnCode = testClient.stringMapTest(returnCode) /** SET TEST */ /** SET TEST */ val setout: MutableSet = HashSet() for (i in -2..2) { setout.add(i) } val setin: Set = testClient.testSet(setout) if (setout != setin) { returnCode = returnCode or ERR_CONTAINERS println("*** FAILURE ***\n") } /** LIST TEST */ /** LIST TEST */ val listout: MutableList = ArrayList() for (i in -2..2) { listout.add(i) } val listin: List = testClient.testList(listout) if (listout != listin) { returnCode = returnCode or ERR_CONTAINERS println("*** FAILURE ***\n") } /** ENUM TEST */ /** ENUM TEST */ returnCode = testClient.enumTest(returnCode) /** TYPEDEF TEST */ /** TYPEDEF TEST */ returnCode = testClient.typedefTest(returnCode) /** NESTED MAP TEST */ /** NESTED MAP TEST */ returnCode = testClient.nestedMapTest(returnCode) /** INSANITY TEST */ /** INSANITY TEST */ var insanityFailed = true try { val hello = Xtruct() hello.string_thing = "Hello2" hello.byte_thing = 2 hello.i32_thing = 2 hello.i64_thing = 2 val goodbye = Xtruct() goodbye.string_thing = "Goodbye4" goodbye.byte_thing = 4.toByte() goodbye.i32_thing = 4 goodbye.i64_thing = 4L insane.userMap = HashMap().apply { put(Numberz.EIGHT, 8L) put(Numberz.FIVE, 5L) } insane.xtructs = ArrayList().apply { add(goodbye) add(hello) } print("testInsanity()") val whoa: Map> = testClient.testInsanity(insane) print(" = {") for (key in whoa.keys) { val `val` = whoa[key]!! print("$key => {") for (k2 in `val`.keys) { val v2 = `val`[k2] print("$k2 => {") val userMap = v2!!.userMap print("{") if (userMap != null) { for (k3 in userMap.keys) { print(k3.toString() + " => " + userMap[k3] + ", ") } } print("}, ") val xtructs = v2.xtructs print("{") if (xtructs != null) { for ((string_thing, byte_thing, i32_thing, i64_thing) in xtructs) { print( "{\"$string_thing\", $byte_thing, $i32_thing, $i64_thing}, " ) } } print("}") print("}, ") } print("}, ") } print("}\n") if (whoa.size == 2 && whoa.containsKey(1L) && whoa.containsKey(2L)) { val firstMap = whoa[1L]!! val secondMap = whoa[2L]!! if ( firstMap.size == 2 && firstMap.containsKey(Numberz.TWO) && firstMap.containsKey(Numberz.THREE) && secondMap.size == 1 && secondMap.containsKey(Numberz.SIX) && insane == firstMap[Numberz.TWO] && insane == firstMap[Numberz.THREE] ) { val six = secondMap[Numberz.SIX]!! // Cannot use "new Insanity().equals(six)" because as of now, // struct/container // fields with default requiredness have isset=false for local instances // and // yet // received empty values from other languages like C++ have isset=true . if ((six.userMap?.size ?: 0) == 0 && (six.xtructs?.size ?: 0) == 0) { // OK insanityFailed = false } } } } catch (ex: Exception) { returnCode = returnCode or ERR_STRUCTS println("*** FAILURE ***\n") ex.printStackTrace(System.out) insanityFailed = false } if (insanityFailed) { returnCode = returnCode or ERR_STRUCTS println("*** FAILURE ***\n") } /** EXECPTION TEST */ /** EXECPTION TEST */ val pair2 = exceptionTest(testClient, returnCode) returnCode = pair2.first testClient = pair2.second /** MULTI EXCEPTION TEST */ /** MULTI EXCEPTION TEST */ val pair3 = multiExceptionTest(testClient, returnCode) returnCode = pair3.first testClient = pair3.second /** ONEWAY TEST */ /** ONEWAY TEST */ returnCode = testClient.onewayTest(returnCode) val stop = System.nanoTime() val tot = stop - start println("Total time: " + tot / 1000 + "us") if (timeMin == 0L || tot < timeMin) { timeMin = tot } if (tot > timeMax) { timeMax = tot } timeTot += tot // transport.close() } catch (x: Exception) { System.out.printf("*** FAILURE ***\n") x.printStackTrace() returnCode = returnCode or ERR_UNKNOWN } } val timeAvg = timeTot / numTests println("Min time: " + timeMin / 1000 + "us") println("Max time: " + timeMax / 1000 + "us") println("Avg time: " + timeAvg / 1000 + "us") try { val json = TSerializer(TSimpleJSONProtocol.Factory()).toString(insane) println("\nSample TSimpleJSONProtocol output:\n$json") } catch (x: TException) { println("*** FAILURE ***") x.printStackTrace() returnCode = returnCode or ERR_BASETYPES } exitProcess(returnCode) } private suspend fun multiplexTest(returnCode: Int): Int { var code = returnCode if ( protocolType == ProtocolType.Multi || protocolType == ProtocolType.MultiJson || protocolType == ProtocolType.MultiCompact ) { val secondClient: SecondServiceClient = createSecondServiceClient() print("secondtestString(\"Test2\")") val s = secondClient.secondtestString("Test2") print(" = \"$s\"\n") if (s != "testString(\"Test2\")") { code = code or ERR_PROTOCOLS println("*** FAILURE ***\n") } } return code } private suspend fun ThriftTestClient.enumTest(returnCode: Int): Int { var returnCode1 = returnCode print("testEnum(ONE)") var ret: Numberz = testEnum(Numberz.ONE) print(" = $ret\n") if (ret !== Numberz.ONE) { returnCode1 = returnCode1 or ERR_STRUCTS println("*** FAILURE ***\n") } print("testEnum(TWO)") ret = testEnum(Numberz.TWO) print(" = $ret\n") if (ret !== Numberz.TWO) { returnCode1 = returnCode1 or ERR_STRUCTS println("*** FAILURE ***\n") } print("testEnum(THREE)") ret = testEnum(Numberz.THREE) print(" = $ret\n") if (ret !== Numberz.THREE) { returnCode1 = returnCode1 or ERR_STRUCTS println("*** FAILURE ***\n") } print("testEnum(FIVE)") ret = testEnum(Numberz.FIVE) print(" = $ret\n") if (ret !== Numberz.FIVE) { returnCode1 = returnCode1 or ERR_STRUCTS println("*** FAILURE ***\n") } print("testEnum(EIGHT)") ret = testEnum(Numberz.EIGHT) print(" = $ret\n") if (ret !== Numberz.EIGHT) { returnCode1 = returnCode1 or ERR_STRUCTS println("*** FAILURE ***\n") } return returnCode1 } private fun printMap(testMapParam: Map) { print("testMap({") var first = true for (key in testMapParam.keys) { if (first) { first = false } else { print(", ") } print(key.toString() + " => " + testMapParam[key]) } print("})") } private suspend fun exceptionTest( testClient: ThriftTestClient, returnCode: Int, ): Pair { var client = testClient var code = returnCode try { print("testClient.testException(\"Xception\") =>") client.testException("Xception") print(" void\n*** FAILURE ***\n") code = code or ERR_EXCEPTIONS } catch (e: Xception) { System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message) client = createClient() } try { print("testClient.testException(\"TException\") =>") client.testException("TException") print(" void\n*** FAILURE ***\n") code = code or ERR_EXCEPTIONS } catch (e: TException) { System.out.printf(" {\"%s\"}\n", e.message) client = createClient() } try { print("testClient.testException(\"success\") =>") client.testException("success") print(" void\n") } catch (e: Exception) { System.out.printf(" exception\n*** FAILURE ***\n") code = code or ERR_EXCEPTIONS } return code to client } private suspend fun multiExceptionTest( testClient: ThriftTestClient, returnCode: Int, ): Pair { var client = testClient var code = returnCode try { System.out.printf("testClient.testMultiException(\"Xception\", \"test 1\") =>") client.testMultiException("Xception", "test 1") print(" result\n*** FAILURE ***\n") code = code or ERR_EXCEPTIONS } catch (e: Xception) { System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message) client = createClient() } try { System.out.printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>") client.testMultiException("Xception2", "test 2") print(" result\n*** FAILURE ***\n") code = code or ERR_EXCEPTIONS } catch (e: Xception2) { System.out.printf(" {%d, {\"%s\"}}\n", e.errorCode, e.struct_thing!!.string_thing) client = createClient() } try { print("testClient.testMultiException(\"success\", \"test 3\") =>") val result: Xtruct = client.testMultiException("success", "test 3") System.out.printf(" {{\"%s\"}}\n", result.string_thing) } catch (e: Exception) { System.out.printf(" exception\n*** FAILURE ***\n") code = code or ERR_EXCEPTIONS } return code to client } } private suspend fun ThriftTestClient.typedefTest(returnCode: Int): Int { var returnCode1 = returnCode print("testTypedef(309858235082523)") val uid: Long = testTypedef(309858235082523L) print(" = $uid\n") if (uid != 309858235082523L) { returnCode1 = returnCode1 or ERR_BASETYPES println("*** FAILURE ***\n") } return returnCode1 } private suspend fun ThriftTestClient.structTest(returnCode: Int): Pair { var code = returnCode print("testStruct({\"Zero\", 1, -3, -5})") val out = Xtruct() out.string_thing = "Zero" out.byte_thing = 1.toByte() out.i32_thing = -3 out.i64_thing = -5 val input: Xtruct = testStruct(out) print( """ = {"${input.string_thing}",${input.byte_thing}, ${input.i32_thing}, ${input.i64_thing}}""" ) if (input != out) { code = code or ERR_STRUCTS println("*** FAILURE ***\n") } return out to code } private suspend fun ThriftTestClient.onewayTest(returnCode: Int): Int { var returnCode1 = returnCode print("testOneway(3)...") val startOneway = System.nanoTime() testOneway(3) val onewayElapsedMillis = (System.nanoTime() - startOneway) / 1000000 if (onewayElapsedMillis > 200) { println("Oneway test took too long to execute failed: took " + onewayElapsedMillis + "ms") println("oneway calls are 'fire and forget' and therefore should not cause blocking.") println("Some transports (HTTP) have a required response, and typically this failure") println("means the transport response was delayed until after the execution") println("of the RPC. The server should post the transport response immediately and") println("before executing the RPC.") println("*** FAILURE ***") returnCode1 = returnCode1 or ERR_BASETYPES } else { println("Success - fire and forget only took " + onewayElapsedMillis + "ms") } return returnCode1 } private suspend fun ThriftTestClient.nestedMapTest(returnCode: Int): Int { var returnCode1 = returnCode print("testMapMap(1)") val mm: Map> = testMapMap(1) print(" = {") for (key in mm.keys) { print("$key => {") val m2 = mm[key]!! for (k2 in m2.keys) { print(k2.toString() + " => " + m2[k2] + ", ") } print("}, ") } print("}\n") if (mm.size != 2 || !mm.containsKey(4) || !mm.containsKey(-4)) { returnCode1 = returnCode1 or ERR_CONTAINERS println("*** FAILURE ***\n") } else { val m1 = mm[4]!! val m2 = mm[-4]!! if ( m1[1] != 1 || m1[2] != 2 || m1[3] != 3 || m1[4] != 4 || m2[-1] != -1 || m2[-2] != -2 || m2[-3] != -3 || m2[-4] != -4 ) { returnCode1 = returnCode1 or ERR_CONTAINERS println("*** FAILURE ***\n") } } return returnCode1 } private suspend fun ThriftTestClient.stringMapTest(returnCode: Int): Int { var returnCode1 = returnCode try { val smapout: MutableMap = HashMap() smapout["a"] = "2" smapout["b"] = "blah" smapout["some"] = "thing" var first = true for (key in smapout.keys) { if (first) { first = false } else { print(", ") } print(key + " => " + smapout[key]) } print("})") val smapin: Map = testStringMap(smapout) print(" = {") first = true for (key in smapin.keys) { if (first) { first = false } else { print(", ") } print(key + " => " + smapout[key]) } print("}\n") if (smapout != smapin) { returnCode1 = returnCode1 or ERR_CONTAINERS println("*** FAILURE ***\n") } } catch (ex: Exception) { returnCode1 = returnCode1 or ERR_CONTAINERS println("*** FAILURE ***\n") ex.printStackTrace(System.out) } return returnCode1 } private suspend fun ThriftTestClient.nestedStructTest(out: Xtruct, returnCode: Int): Int { var code = returnCode print("testNest({1, {\"Zero\", 1, -3, -5}), 5}") val out2 = Xtruct2() out2.byte_thing = 1.toShort().toByte() out2.struct_thing = out out2.i32_thing = 5 val xstruct2: Xtruct2 = testNest(out2) val input = xstruct2.struct_thing!! print( """ = {${xstruct2.byte_thing}, {"${input.string_thing}", ${input.byte_thing}, ${input.i32_thing}, ${input.i64_thing}}, ${xstruct2.i32_thing}} """ ) if (xstruct2 != out2) { code = code or ERR_STRUCTS println("*** FAILURE ***\n") } return code } private suspend fun ThriftTestClient.binaryTest(returnCode: Int): Int { var returnCode1 = returnCode try { print("testBinary(-128...127) = ") val data = testByteArray val bin: ByteBuffer = ByteBuffer.wrap(testBinary(data)) bin.mark() val bytes = ByteArray(bin.limit() - bin.position()) bin[bytes] bin.reset() print("{") var first = true for (i in bytes.indices) { if (first) first = false else print(", ") print(bytes[i]) } println("}") if (ByteBuffer.wrap(data) != bin) { returnCode1 = returnCode1 or ERR_BASETYPES println("*** FAILURE ***\n") } } catch (ex: Exception) { returnCode1 = returnCode1 or ERR_BASETYPES println("\n*** FAILURE ***\n") ex.printStackTrace(System.out) } return returnCode1 } private suspend fun ThriftTestClient.doubleTest(returnCode: Int): Int { var returnCode1 = returnCode print("testDouble(-5.325098235)") val dub: Double = testDouble(-5.325098235) print(" = $dub\n") if (abs(dub - -5.325098235) > 0.001) { returnCode1 = returnCode1 or ERR_BASETYPES println("*** FAILURE ***\n") } return returnCode1 } private suspend fun ThriftTestClient.i64Test(returnCode: Int): Int { var returnCode1 = returnCode print("testI64(-34359738368)") val i64: Long = testI64(-34359738368L) print(" = $i64\n") if (i64 != -34359738368L) { returnCode1 = returnCode1 or ERR_BASETYPES println("*** FAILURE ***\n") } return returnCode1 } private suspend fun ThriftTestClient.i32Test(returnCode: Int): Int { var returnCode1 = returnCode print("testI32(-1)") val i32: Int = testI32(-1) print(" = $i32\n") if (i32 != -1) { returnCode1 = returnCode1 or ERR_BASETYPES println("*** FAILURE ***\n") } return returnCode1 } private suspend fun ThriftTestClient.byteTest(returnCode: Int): Int { var returnCode1 = returnCode print("testByte(1)") val i8: Byte = testByte(1.toByte()) print(" = $i8\n") if (i8.toInt() != 1) { returnCode1 = returnCode1 or ERR_BASETYPES println("*** FAILURE ***\n") } return returnCode1 } private suspend fun ThriftTestClient.stringTest(returnCode: Int): Int { var returnCode1 = returnCode print("testString(\"Test\")") val s: String = testString("Test") print(" = \"$s\"\n") if (s != "Test") { returnCode1 = returnCode1 or ERR_BASETYPES println("*** FAILURE ***\n") } return returnCode1 } private suspend fun ThriftTestClient.voidTest(returnCode: Int): Int { var returnCode1 = returnCode try { print("testVoid()") testVoid() print(" = void\n") } catch (tax: TApplicationException) { tax.printStackTrace() returnCode1 = returnCode1 or ERR_BASETYPES } return returnCode1 } fun main(args: Array) { TestClient().main(args) } private val testByteArray = (-128..127).map { it.toByte() }.toByteArray() thrift-0.23.0/lib/kotlin/cross-test-client/src/main/resources/0000775000175000017500000000000015165535636024552 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-client/src/main/resources/logback.xml0000664000175000017500000000237415165535636026704 0ustar00buildbuild00000000000000 %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n thrift-0.23.0/lib/kotlin/cross-test-client/build.gradle.kts0000664000175000017500000000763015167543515024107 0ustar00buildbuild00000000000000/* * 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 org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") java application id("com.ncorti.ktfmt.gradle") } repositories { mavenCentral() } val slf4jVersion: String by project val httpclientVersion: String by project val httpcoreVersion: String by project val logbackVersion: String by project val kotlinxCoroutinesJdk8Version: String by project val cliktVersion: String by project dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") // clikt is used to drive command line parsing and validation implementation("com.github.ajalt.clikt:clikt:$cliktVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$kotlinxCoroutinesJdk8Version") implementation("org.apache.thrift:libthrift:INCLUDED") implementation("org.slf4j:slf4j-api:$slf4jVersion") implementation("org.apache.httpcomponents:httpclient:$httpclientVersion") implementation("org.apache.httpcomponents:httpcore:$httpcoreVersion") implementation("ch.qos.logback:logback-classic:$logbackVersion") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") } 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") } } val keyStore: String = file("$projectDir/../../java/src/crossTest/resources/.clientkeystore").canonicalPath val trustStore: String = file("$projectDir/../../java/src/crossTest/resources/.truststore").canonicalPath tasks { application { applicationName = "TestClient" mainClass.set("org.apache.thrift.test.TestClientKt") applicationDefaultJvmArgs = listOf( "-Djavax.net.ssl.keyStore=$keyStore", "-Djavax.net.ssl.keyStorePassword=thrift", "-Djavax.net.ssl.trustStore=$trustStore", "-Djavax.net.ssl.trustStorePassword=thrift", ) } if (JavaVersion.current().isJava11Compatible) { ktfmt { kotlinLangStyle() } } task("compileThrift") { val thriftBin = if (hasProperty("thrift.compiler")) { file(property("thrift.compiler")!!) } else { project.rootDir.resolve("../../compiler/cpp/thrift") } val outputDir = layout.buildDirectory.dir("generated-sources") doFirst { mkdir(outputDir) } commandLine = listOf( thriftBin.absolutePath, "-gen", "kotlin", "-out", outputDir.get().toString(), project.rootDir.resolve("../../test/ThriftTest.thrift").absolutePath, ) group = LifecycleBasePlugin.BUILD_GROUP } compileKotlin { dependsOn("compileThrift") } } sourceSets["main"].java { srcDir(layout.buildDirectory.dir("generated-sources")) } thrift-0.23.0/lib/kotlin/src/0000775000175000017500000000000015165535636016232 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/src/test/0000775000175000017500000000000015165535636017211 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/src/test/kotlin/0000775000175000017500000000000015165535636020511 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/src/test/kotlin/org/0000775000175000017500000000000015165535636021300 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/src/test/kotlin/org/apache/0000775000175000017500000000000015165535636022521 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/src/test/kotlin/org/apache/thrift/0000775000175000017500000000000015165535636024021 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/src/test/kotlin/org/apache/thrift/MetaDataTest.kt0000664000175000017500000000260315165535636026702 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift import kotlin.test.assertEquals import org.apache.thrift.kotlin.annotation.test.Person import org.apache.thrift.meta_data.FieldMetaData import org.junit.jupiter.api.Test internal class MetaDataTest { @Test internal fun testAnnotation() { val personMetadata = FieldMetaData.getStructMetaDataMap(Person::class.java) assertEquals(3, personMetadata.size) val idField = personMetadata[Person._Fields.ID]!! assertEquals("id", idField.fieldName) assertEquals(mapOf("max" to "100000", "min" to "1"), idField.fieldAnnotations) } } thrift-0.23.0/lib/kotlin/src/test/resources/0000775000175000017500000000000015165535636021223 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/src/test/resources/AnnotationTest.thrift0000664000175000017500000000173015165535636025420 0ustar00buildbuild00000000000000/* * 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 java org.apache.thrift.kotlin.annotation.test struct Person { 1: required i64 id (min="1", max="100000") 2: required string name 3: optional string phoneNumber } thrift-0.23.0/lib/kotlin/settings.gradle.kts0000664000175000017500000000204215167543515021256 0ustar00buildbuild00000000000000/* * 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. */ pluginManagement { plugins { kotlin("jvm") version "2.3.20" id("com.ncorti.ktfmt.gradle") version "0.26.0" } } rootProject.name = "libthrift-kotlin" include("cross-test-client", "cross-test-server") includeBuild("../java") thrift-0.23.0/lib/kotlin/CMakeLists.txt0000664000175000017500000000157115165535636020207 0ustar00buildbuild00000000000000# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. file(GLOB_RECURSE THRIFTKOTLIN_SOURCES LIST_DIRECTORIES false "${CMAKE_CURRENT_SOURCE_DIR}/src/*") thrift-0.23.0/lib/kotlin/gradle.properties0000664000175000017500000000165415165535636021025 0ustar00buildbuild00000000000000# # 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. # slf4jVersion=1.7.35 httpcoreVersion=4.4.15 httpclientVersion=4.5.13 logbackVersion=1.3.0-alpha14 kotlinxCoroutinesJdk8Version=1.6.1 cliktVersion=3.4.2 thrift-0.23.0/lib/kotlin/README.md0000664000175000017500000000244115165535636016723 0ustar00buildbuild00000000000000# Test Only Library for Kotlin This directory (`/lib/kotlin`) contains test only library code for Kotlin code gen. Because Kotlin code gen produces code that works on top of libthrift (i.e. Java library), the purpose of this library is to encode the cross test server and client to make sure it conforms to the thrift specifications. The output artifact in this library is _not_ published to Maven central. Unlike the Java library where: 1. source code is put under `main` sources set i.e. `src/main`, 2. unit test code is put under `test` sources set i.e. `src/test`, 3. cross test code is put under `crossTest` sources set, i.e. `src/crossTest` directory which, unlike the default `main` and `test`, is created and configured on demand; this kotlin library uses a multi-module project setup for separation of concern: 1. root module for configuring unit tests, 2. `cross-test-client` module for bundling a standalone test client, 3. `cross-test-server` module for bundling a standalone test server ## How to compile This library is managed using Gradle 6.9.2, run the following command (requires C++ thrift compiler): ```bash gradle build ``` ```bash gradle installDist ``` ## How to run cross test server / client ```bash gradle :cross-test-server:run ``` ```bash gradle :cross-test-client:run ``` thrift-0.23.0/lib/kotlin/Makefile.in0000644000175000017500000004372515170007167017506 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/kotlin ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ build.gradle.kts \ CMakeLists.txt \ cross-test-client \ cross-test-server \ gradle.properties \ README.md \ settings.gradle.kts \ src all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/kotlin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/kotlin/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile export CLASSPATH all-local: $(GRADLE) $(GRADLE_OPTS) assemble \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain clean-local: $(GRADLE) $(GRADLE_OPTS) clean --console=plain precross: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) installDist \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain check-local: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) test \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/kotlin/cross-test-server/0000775000175000017500000000000015167543515021052 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/0000775000175000017500000000000015165535636021644 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/0000775000175000017500000000000015165535636022570 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/kotlin/0000775000175000017500000000000015165535636024070 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/kotlin/org/0000775000175000017500000000000015165535636024657 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/0000775000175000017500000000000015165535636026100 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/0000775000175000017500000000000015165535636027400 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/0000775000175000017500000000000015165535636030357 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestServer.kt0000664000175000017500000003062515165535636033033 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.parameters.options.default import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.enum import com.github.ajalt.clikt.parameters.types.int import com.github.ajalt.clikt.parameters.types.long import kotlinx.coroutines.GlobalScope import org.apache.thrift.TException import org.apache.thrift.TMultiplexedProcessor import org.apache.thrift.protocol.TBinaryProtocol import org.apache.thrift.protocol.TCompactProtocol import org.apache.thrift.protocol.TJSONProtocol import org.apache.thrift.protocol.TProtocol import org.apache.thrift.protocol.TProtocolFactory import org.apache.thrift.server.ServerContext import org.apache.thrift.server.TNonblockingServer import org.apache.thrift.server.TServer import org.apache.thrift.server.TServerEventHandler import org.apache.thrift.server.TSimpleServer import org.apache.thrift.server.TThreadPoolServer import org.apache.thrift.server.TThreadedSelectorServer import org.apache.thrift.transport.TNonblockingServerSocket import org.apache.thrift.transport.TNonblockingServerSocket.NonblockingAbstractServerSocketArgs import org.apache.thrift.transport.TSSLTransportFactory import org.apache.thrift.transport.TServerSocket import org.apache.thrift.transport.TServerSocket.ServerSocketTransportArgs import org.apache.thrift.transport.TTransport import org.apache.thrift.transport.TTransportFactory import org.apache.thrift.transport.TZlibTransport import org.apache.thrift.transport.layered.TFastFramedTransport import org.apache.thrift.transport.layered.TFramedTransport import thrift.test.SecondService import thrift.test.SecondServiceProcessor import thrift.test.ThriftTestProcessor object TestServer { // Multiplexed Protocol Support Details: // // For multiplexed testing we always use binary protocol underneath. // // "ThriftTest" named service implements "ThriftTest" from ThriftTest.thrift // "SecondService" named service implements "SecondService" from ThriftTest.thrift // In addition, to support older non-multiplexed clients using the same concrete protocol // the multiplexed processor is taught to use "ThriftTest" if the incoming request has no // multiplexed call name decoration. internal class SecondHandler : SecondService { @Throws(TException::class) override suspend fun secondtestString(thing: String): String { return "testString(\"$thing\")" } } internal class TestServerContext(var connectionId: Int) : ServerContext { override fun unwrap(iface: Class): T { try { return if (isWrapperFor(iface)) { iface.cast(this) } else { throw RuntimeException("The context is not a wrapper for " + iface.name) } } catch (e: Exception) { throw RuntimeException( "The context is not a wrapper and does not implement the interface" ) } } override fun isWrapperFor(iface: Class<*>): Boolean { return iface.isInstance(this) } } internal class TestServerEventHandler() : TServerEventHandler { private var nextConnectionId = 1 override fun preServe() { println( "TServerEventHandler.preServe - called only once before server starts accepting connections" ) } override fun createContext(input: TProtocol, output: TProtocol): ServerContext { // we can create some connection level data which is stored while connection is alive & // served val ctx = TestServerContext(nextConnectionId++) println( "TServerEventHandler.createContext - connection #" + ctx.connectionId + " established" ) return ctx } override fun deleteContext( serverContext: ServerContext, input: TProtocol, output: TProtocol, ) { val ctx = serverContext.unwrap(TestServerContext::class.java) println( "TServerEventHandler.deleteContext - connection #" + ctx.connectionId + " terminated" ) } override fun processContext( serverContext: ServerContext, inputTransport: TTransport, outputTransport: TTransport, ) { val ctx = serverContext.unwrap(TestServerContext::class.java) println( "TServerEventHandler.processContext - connection #" + ctx.connectionId + " is ready to process next request" ) } } } enum class ServerType(val key: String) { Simple("simple"), ThreadPool("thread-pool"), NonBlocking("nonblocking"), ThreadedSelector("threaded-selector"), } enum class ProtocolType(val key: String) { Binary("binary"), Multi("multi"), Json("json"), MultiJson("multij"), Compact("compact"), MultiCompact("multic"), } enum class TransportType(val key: String) { Buffered("buffered"), FastFramed("fastframed"), Framed("framed"), Zlib("zlib"), } class TestServerCommand : CliktCommand() { private val port: Int by option(help = "The cross test port to connect to").int().default(9090) private val protocolType: ProtocolType by option("--protocol", help = "Protocol type") .enum { it.key } .default(ProtocolType.Binary) private val transportType: TransportType by option("--transport", help = "Transport type") .enum { it.key } .default(TransportType.Buffered) private val serverType: ServerType by option("--server-type").enum { it.key }.default(ServerType.NonBlocking) private val useSSL: Boolean by option("--ssl", help = "Use SSL for encrypted transport").flag(default = false) private val stringLimit: Long by option("--string-limit").long().default(-1) private val containerLimit: Long by option("--container-limit").long().default(-1) @Suppress("OPT_IN_USAGE") override fun run() { val testHandler = TestHandler() val testProcessor = ThriftTestProcessor(testHandler, scope = GlobalScope) val secondHandler = TestServer.SecondHandler() val secondProcessor = SecondServiceProcessor(secondHandler, scope = GlobalScope) val serverEngine: TServer = getServerEngine( testProcessor, secondProcessor, serverType, port, protocolType, getProtocolFactory(), getTransportFactory(), useSSL, ) // Set server event handler serverEngine.setServerEventHandler(TestServer.TestServerEventHandler()) // Run it println( "Starting the ${if (useSSL) "ssl server" else "server"} [$protocolType/$transportType/$serverType] on port $port" ) serverEngine.serve() } private fun getTransportFactory(): TTransportFactory = when (transportType) { TransportType.Framed -> { TFramedTransport.Factory() } TransportType.FastFramed -> { TFastFramedTransport.Factory() } TransportType.Zlib -> { TZlibTransport.Factory() } TransportType.Buffered -> { TTransportFactory() } } private fun getProtocolFactory(): TProtocolFactory = when (protocolType) { ProtocolType.Json, ProtocolType.MultiJson -> TJSONProtocol.Factory() ProtocolType.Compact, ProtocolType.MultiCompact -> TCompactProtocol.Factory(stringLimit, containerLimit) ProtocolType.Binary, ProtocolType.Multi -> TBinaryProtocol.Factory(stringLimit, containerLimit) } } fun main(args: Array) { TestServerCommand().main(args) } private fun getServerEngine( testProcessor: ThriftTestProcessor, secondProcessor: SecondServiceProcessor, serverType: ServerType, port: Int, protocolType: ProtocolType, tProtocolFactory: TProtocolFactory, tTransportFactory: TTransportFactory, ssl: Boolean, ): TServer { val isMulti = protocolType == ProtocolType.Multi || protocolType == ProtocolType.MultiCompact || protocolType == ProtocolType.MultiJson // If we are multiplexing services in one server... val multiplexedProcessor = TMultiplexedProcessor() multiplexedProcessor.registerDefault(testProcessor) multiplexedProcessor.registerProcessor("ThriftTest", testProcessor) multiplexedProcessor.registerProcessor("SecondService", secondProcessor) when (serverType) { ServerType.NonBlocking, ServerType.ThreadedSelector -> { val tNonblockingServerSocket = TNonblockingServerSocket(NonblockingAbstractServerSocketArgs().port(port)) when (serverType) { ServerType.NonBlocking -> { val tNonblockingServerArgs = TNonblockingServer.Args(tNonblockingServerSocket) tNonblockingServerArgs.processor( if (isMulti) multiplexedProcessor else testProcessor ) tNonblockingServerArgs.protocolFactory(tProtocolFactory) tNonblockingServerArgs.transportFactory(tTransportFactory) return TNonblockingServer(tNonblockingServerArgs) } else -> { val tThreadedSelectorServerArgs = TThreadedSelectorServer.Args(tNonblockingServerSocket) tThreadedSelectorServerArgs.processor( if (isMulti) multiplexedProcessor else testProcessor ) tThreadedSelectorServerArgs.protocolFactory(tProtocolFactory) tThreadedSelectorServerArgs.transportFactory(tTransportFactory) return TThreadedSelectorServer(tThreadedSelectorServerArgs) } } } ServerType.Simple, ServerType.ThreadPool -> { // SSL socket val tServerSocket: TServerSocket = if (ssl) { TSSLTransportFactory.getServerSocket(port, 0) } else { TServerSocket(ServerSocketTransportArgs().port(port)) } when (serverType) { ServerType.Simple -> { val tServerArgs = TServer.Args(tServerSocket) tServerArgs.processor(if (isMulti) multiplexedProcessor else testProcessor) tServerArgs.protocolFactory(tProtocolFactory) tServerArgs.transportFactory(tTransportFactory) return TSimpleServer(tServerArgs) } else -> { val tThreadPoolServerArgs = TThreadPoolServer.Args(tServerSocket) tThreadPoolServerArgs.processor( if (isMulti) multiplexedProcessor else testProcessor ) tThreadPoolServerArgs.protocolFactory(tProtocolFactory) tThreadPoolServerArgs.transportFactory(tTransportFactory) return TThreadPoolServer(tThreadPoolServerArgs) } } } } } thrift-0.23.0/lib/kotlin/cross-test-server/src/main/kotlin/org/apache/thrift/test/TestHandler.kt0000664000175000017500000002040215165535636033132 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test import java.nio.ByteBuffer import java.util.* import kotlin.collections.HashMap import kotlinx.coroutines.delay import org.apache.thrift.TException import org.slf4j.Logger import org.slf4j.LoggerFactory import thrift.test.Insanity import thrift.test.Numberz import thrift.test.ThriftTest import thrift.test.Xception import thrift.test.Xception2 import thrift.test.Xtruct import thrift.test.Xtruct2 class TestHandler : ThriftTest { companion object { private val logger: Logger = LoggerFactory.getLogger(TestHandler::class.java) } override suspend fun testVoid() { logger.info("testVoid()\n") } override suspend fun testString(thing: String): String { logger.info("testString(\"$thing\")\n") return thing } override suspend fun testBool(thing: Boolean): Boolean { logger.info("testBool($thing)\n") return thing } override suspend fun testByte(thing: Byte): Byte { logger.info("testByte($thing)\n") return thing } override suspend fun testI32(thing: Int): Int { logger.info("testI32($thing)\n") return thing } override suspend fun testI64(thing: Long): Long { logger.info("testI64($thing)\n") return thing } override suspend fun testDouble(thing: Double): Double { logger.info("testDouble($thing)\n") return thing } override suspend fun testBinary(thing: ByteArray): ByteArray { val buffer = ByteBuffer.wrap(thing) val sb = StringBuilder(buffer.remaining() * 3) buffer.mark() var limit = 0 // limit output to keep the log size sane while (buffer.remaining() > 0 && ++limit < 1024) { sb.append(String.format("%02X ", buffer.get())) } if (buffer.remaining() > 0) { sb.append("...") // indicate we have more date } logger.info("testBinary($sb)\n") buffer.reset() return buffer.array() } override suspend fun testUuid(thing: UUID): UUID { logger.info("testUuid($thing)\n") return thing } override suspend fun testStruct(thing: Xtruct): Xtruct { logger.info( """testStruct({"${thing.string_thing}", ${thing.byte_thing}, ${thing.i32_thing}, ${thing.i64_thing}})""" ) return thing } 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() ) return thing } override suspend fun testMap(thing: Map): Map { logger.info("testMap({") logger.info("{}", thing) logger.info("})\n") return thing } override suspend fun testStringMap(thing: Map): Map { logger.info("testStringMap({") logger.info("{}", thing) logger.info("})\n") return thing } override suspend fun testSet(thing: Set): Set { logger.info("testSet({") var first = true for (elem in thing) { if (first) { first = false } else { logger.info(", ") } logger.info("{}", elem) } logger.info("})\n") return thing } override suspend fun testList(thing: List): List { logger.info("testList({") var first = true for (elem in thing) { if (first) { first = false } else { logger.info(", ") } logger.info("{}", elem) } logger.info("})\n") return thing } override suspend fun testEnum(thing: Numberz): Numberz { logger.info("testEnum($thing)\n") return thing } override suspend fun testTypedef(thing: Long): Long { logger.info("testTypedef($thing)\n") return thing } override suspend fun testMapMap(hello: Int): Map> { logger.info("testMapMap($hello)\n") val mapmap: MutableMap> = HashMap() val pos = HashMap() val neg = HashMap() for (i in 1..4) { pos[i] = i neg[-i] = -i } mapmap[4] = pos mapmap[-4] = neg return mapmap } override suspend fun testInsanity(argument: Insanity): Map> { logger.info("testInsanity()\n") val firstMap = mutableMapOf() val secondMap = mutableMapOf() firstMap[Numberz.TWO] = argument firstMap[Numberz.THREE] = argument val looney = Insanity().apply { userMap = HashMap() xtructs = listOf() } secondMap[Numberz.SIX] = looney val insane: MutableMap> = HashMap() insane[1L] = firstMap insane[2L] = secondMap return insane } override suspend fun testMulti( arg0: Byte, arg1: Int, arg2: Long, arg3: Map, arg4: Numberz, arg5: Long, ): Xtruct { logger.info("testMulti()\n") val hello = Xtruct() hello.string_thing = "Hello2" hello.byte_thing = arg0 hello.i32_thing = arg1 hello.i64_thing = arg2 return hello } @Throws(Xception::class, TException::class) override suspend fun testException(arg: String) { logger.info("testException($arg)\n") when (arg) { "Xception" -> { val x = Xception() x.errorCode = 1001 x.setFieldValue(Xception._Fields.MESSAGE, arg) throw x } "TException" -> { // Unspecified exception should yield a TApplicationException on client side throw RuntimeException(arg) } else -> { val result = Xtruct() result.string_thing = arg } } return } @Throws(Xception::class, Xception2::class) override suspend fun testMultiException(arg0: String, arg1: String): Xtruct { logger.info("testMultiException($arg0, $arg1)\n") if (arg0 == "Xception") { val x = Xception() x.errorCode = 1001 x.setFieldValue(Xception._Fields.MESSAGE, "This is an Xception") throw x } else if (arg0 == "Xception2") { val x = Xception2() x.errorCode = 2002 x.struct_thing = Xtruct().apply { string_thing = "This is an Xception2" byte_thing = 0 i32_thing = 0 i64_thing = 0 } throw x } val result = Xtruct() result.string_thing = arg1 result.byte_thing = 0 result.i32_thing = 0 result.i64_thing = 0 return result } override suspend fun testOneway(secondsToSleep: Int) { logger.info("testOneway($secondsToSleep) => sleeping...") try { delay(secondsToSleep * 1000L) logger.info("Done sleeping!") } catch (ie: InterruptedException) { throw RuntimeException(ie) } } } thrift-0.23.0/lib/kotlin/cross-test-server/src/main/resources/0000775000175000017500000000000015165535636024602 5ustar00buildbuild00000000000000thrift-0.23.0/lib/kotlin/cross-test-server/src/main/resources/logback.xml0000664000175000017500000000237315165535636026733 0ustar00buildbuild00000000000000 %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n thrift-0.23.0/lib/kotlin/cross-test-server/build.gradle.kts0000664000175000017500000000564315167543515024141 0ustar00buildbuild00000000000000/* * 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. */ plugins { kotlin("jvm") java application id("com.ncorti.ktfmt.gradle") } repositories { mavenCentral() } val slf4jVersion: String by project val httpcoreVersion: String by project val logbackVersion: String by project val kotlinxCoroutinesJdk8Version: String by project val cliktVersion: String by project dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") // clikt is used to drive command line parsing and validation implementation("com.github.ajalt.clikt:clikt:$cliktVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$kotlinxCoroutinesJdk8Version") implementation("org.apache.thrift:libthrift:INCLUDED") implementation("org.slf4j:slf4j-api:$slf4jVersion") implementation("org.apache.httpcomponents:httpcore:$httpcoreVersion") implementation("ch.qos.logback:logback-classic:$logbackVersion") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") } tasks { application { applicationName = "TestServer" mainClass.set("org.apache.thrift.test.TestServerKt") } if (JavaVersion.current().isJava11Compatible) { ktfmt { kotlinLangStyle() } } task("compileThrift") { val thriftBin = if (hasProperty("thrift.compiler")) { file(property("thrift.compiler")!!) } else { project.rootDir.resolve("../../compiler/cpp/thrift") } val outputDir = layout.buildDirectory.dir("generated-sources") doFirst { mkdir(outputDir) } commandLine = listOf( thriftBin.absolutePath, "-gen", "kotlin", "-out", outputDir.get().toString(), project.rootDir.resolve("../../test/ThriftTest.thrift").absolutePath, ) group = LifecycleBasePlugin.BUILD_GROUP } compileKotlin { dependsOn("compileThrift") } } sourceSets["main"].java { srcDir(layout.buildDirectory.dir("generated-sources")) } thrift-0.23.0/lib/kotlin/Makefile.am0000664000175000017500000000274315165535636017505 0ustar00buildbuild00000000000000# # 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. # export CLASSPATH all-local: $(GRADLE) $(GRADLE_OPTS) assemble \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain clean-local: $(GRADLE) $(GRADLE_OPTS) clean --console=plain precross: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) installDist \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain check-local: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) test \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ build.gradle.kts \ CMakeLists.txt \ cross-test-client \ cross-test-server \ gradle.properties \ README.md \ settings.gradle.kts \ src thrift-0.23.0/lib/kotlin/build.gradle.kts0000664000175000017500000000530415167543515020521 0ustar00buildbuild00000000000000/* * 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 org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") id("com.ncorti.ktfmt.gradle") } repositories { mavenCentral() } dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.10.2") implementation("org.apache.thrift:libthrift:INCLUDED") testImplementation(kotlin("test")) } kotlin { jvmToolchain { languageVersion.set(JavaLanguageVersion.of(17)) } } 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 { if (JavaVersion.current().isJava11Compatible) { ktfmt { kotlinLangStyle() } } test { useJUnitPlatform() } task("compileThrift") { val thriftBin = if (hasProperty("thrift.compiler")) { file(property("thrift.compiler")!!) } else { project.rootDir.resolve("../../compiler/cpp/thrift") } val outputDir = layout.buildDirectory.dir("generated-sources") doFirst { mkdir(outputDir) } commandLine = listOf( thriftBin.absolutePath, "-gen", "kotlin", "-out", outputDir.get().toString(), layout.projectDirectory .file("src/test/resources/AnnotationTest.thrift") .asFile .absolutePath, ) group = LifecycleBasePlugin.BUILD_GROUP } compileKotlin { dependsOn("compileThrift") } } sourceSets["main"].java { srcDir(layout.buildDirectory.dir("generated-sources")) } thrift-0.23.0/lib/swift/0000755000175000017500000000000015170007201015247 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/0000775000175000017500000000000015165535636017573 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Package.swift0000664000175000017500000000572715165535636022217 0ustar00buildbuild00000000000000// swift-tools-version:5.5 // 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: "ThriftFuzzTesting", dependencies: [ .package(name: "Thrift", path: "../") ], targets: [ // Generated code from Thrift definitions .target( name: "Fuzz", dependencies: ["Thrift"], path: "Sources/Fuzz" ), // Common utilities for fuzzing .target( name: "FuzzCommon", dependencies: ["Thrift", "Fuzz"], path: "Sources/FuzzCommon" ), .executableTarget( name: "FuzzParseBinary", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzParseBinary", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzRoundtripBinary", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzRoundtripBinary", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzParseCompact", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzParseCompact", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzRoundtripCompact", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzRoundtripCompact", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzParseJSON", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzParseJSON", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ), .executableTarget( name: "FuzzRoundtripJSON", dependencies: ["FuzzCommon", "Thrift", "Fuzz"], path: "Sources/FuzzRoundtripJSON", linkerSettings: [ .unsafeFlags(["-sanitize=fuzzer"]) ] ) ] ) thrift-0.23.0/lib/swift/FuzzTesting/README.md0000664000175000017500000000122215165535636021047 0ustar00buildbuild00000000000000# Swift Fuzzing README The Swift Thrift implementation uses LLVM's libFuzzer for fuzzing. ## Fuzzer Structure We currently have several fuzz targets that test different aspects of the Thrift implementation: * FuzzParseBinary -- Tries to deserialize the code-generated FuzzTest struct from arbitrary input data using the binary protocol * FuzzRoundtripBinary -- Tries to deserialize a FuzzTest struct and then tests roundtrip serialization/deserialization with the binary protocol * FuzzParseCompact * FuzzRoundtripCompact * FuzzParseJSON * FuzzRoundtripJSON The fuzzers need a dummy main() to ensure that compilation in non-fuzzer modes doesn't regress.thrift-0.23.0/lib/swift/FuzzTesting/Sources/0000775000175000017500000000000015165535636021216 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzParseBinary/0000775000175000017500000000000015165535636024314 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzParseBinary/main.swift0000664000175000017500000000224215165535636026316 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { _ = parseObjectWithProtocol(start: start, count: count, protocolType: TBinaryProtocol.self) return 0 } @main public struct FuzzParseBinary { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } }thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzRoundtripJSON/0000775000175000017500000000000015165535636024555 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzRoundtripJSON/main.swift0000664000175000017500000000226615165535636026565 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { return roundtripWithProtocol( start: start, count: count, protocolType: TJSONProtocol.self ) } @main public struct FuzzRoundtripJSON { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } } thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzRoundtripBinary/0000775000175000017500000000000015165535636025230 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzRoundtripBinary/main.swift0000664000175000017500000000227015165535636027233 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { return roundtripWithProtocol( start: start, count: count, protocolType: TBinaryProtocol.self ) } @main public struct FuzzRoundtripBinary { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } }thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzRoundtripCompact/0000775000175000017500000000000015165535636025372 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzRoundtripCompact/main.swift0000664000175000017500000000227215165535636027377 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { return roundtripWithProtocol( start: start, count: count, protocolType: TCompactProtocol.self ) } @main public struct FuzzRoundtripCompact { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } }thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzParseJSON/0000775000175000017500000000000015165535636023641 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzParseJSON/main.swift0000664000175000017500000000223715165535636025647 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { _ = parseObjectWithProtocol(start: start, count: count, protocolType: TJSONProtocol.self) return 0 } @main public struct FuzzParseJSON { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } } thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzCommon/0000775000175000017500000000000015165535636023325 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzCommon/FuzzUtils.swift0000664000175000017500000001011115165535636026354 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. import Foundation import Thrift import Fuzz /// Generic parser that returns a parsed object from binary data - for use as a converter public func parseObjectWithProtocol( start: UnsafeRawPointer, count: Int, protocolType: P.Type) -> Fuzz.FuzzTest? { let data = Data(bytes: start, count: count) let transport = TMemoryBufferTransport(readBuffer: data) let proto = P(on: transport) do { return try Fuzz.FuzzTest.read(from: proto) } catch { return nil } } /// Test roundtrip serialization/deserialization with the specified protocol and conversion function public func roundtripWithProtocol( start: UnsafeRawPointer, count: Int, protocolType: P.Type ) -> Int32 { // Try to convert data to a test object guard let testObj = parseObjectWithProtocol(start: start, count: count, protocolType: protocolType) else { return 0 } // Now do a roundtrip test with the converted object do { // Serialize let writeTransport = TMemoryBufferTransport() let writeProto = P(on: writeTransport) try testObj.write(to: writeProto) try writeTransport.flush() // Deserialize let readTransport = TMemoryBufferTransport(readBuffer: writeTransport.writeBuffer) let readProto = P(on: readTransport) let deserialized = try Fuzz.FuzzTest.read(from: readProto) // This should always be true, but we check just to be sure guard deserialized == testObj else { fatalError("Roundtrip test failed: objects not equal after serialization/deserialization") } } catch { // Catch expected exceptions } return 0 } /// Typedef for the fuzzer function signature required by libFuzzer public typealias FuzzTarget = @convention(c) (UnsafeRawPointer, Int) -> Int32 // Import the libFuzzer driver function @_silgen_name("LLVMFuzzerRunDriver") public func LLVMFuzzerRunDriver( _ argc: UnsafeMutablePointer, _ argv: UnsafeMutablePointer>>, _ userCb: @escaping @convention(c) (UnsafeRawPointer, Int) -> Int32) -> Int32 // Run the libFuzzer driver with the given test function // We use this to get around swift compilation issues, which create main functions that otherwise // conflict with the libfuzzer main. // See more documentation here: https://llvm.org/docs/LibFuzzer.html#using-libfuzzer-as-a-library public func runLibFuzzerDriver(testOneInput: @escaping FuzzTarget) -> Never { // Create C-style arguments to pass to LLVMFuzzerRunDriver var args = CommandLine.arguments.map { strdup($0) } var argc = Int32(args.count) var argv = args.map { UnsafeMutablePointer($0!) } let argvPtr = UnsafeMutablePointer>.allocate(capacity: args.count) argvPtr.initialize(from: &argv, count: args.count) let argvPtrPtr = UnsafeMutablePointer>>.allocate(capacity: 1) argvPtrPtr.pointee = argvPtr // Start the fuzzer engine with our test function let result = LLVMFuzzerRunDriver(&argc, argvPtrPtr, testOneInput) // Clean up argvPtrPtr.deallocate() argvPtr.deallocate() exit(Int32(result)) } thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzParseCompact/0000775000175000017500000000000015165535636024456 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/FuzzTesting/Sources/FuzzParseCompact/main.swift0000664000175000017500000000224515165535636026463 0ustar00buildbuild00000000000000// 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 FuzzCommon import Thrift @_cdecl("LLVMFuzzerTestOneInput") public func testOneInput(_ start: UnsafeRawPointer, _ count: Int) -> Int32 { _ = parseObjectWithProtocol(start: start, count: count, protocolType: TCompactProtocol.self) return 0 } @main public struct FuzzParseCompact { public static func main() { runLibFuzzerDriver(testOneInput: testOneInput) } } thrift-0.23.0/lib/swift/Tests/0000775000175000017500000000000015167543515016376 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/Tests/ThriftTests/0000775000175000017500000000000015170007142020642 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/Tests/ThriftTests/TFramedTransportTests.swift0000664000175000017500000001327715165535636026236 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift /// Testig TFramedTransport /// class TFramedTransportTests: XCTestCase { var underlyingTransport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TBinaryProtocol! var transport: TFramedTransport! override func setUp() { super.setUp() transport = TFramedTransport(transport:underlyingTransport) proto = TBinaryProtocol(on: transport) underlyingTransport.reset() } override func tearDown() { super.tearDown() underlyingTransport.reset() } func testInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String! do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try? transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readVal.message) got \(writeVal.message)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testUnsafeBitcastUpdate() { let value: Double = 3.14159 let val: Int64 = 31415926 let uval: UInt64 = 31415926 let i64 = Int64(bitPattern: value.bitPattern) let ubc = unsafeBitCast(value, to: Int64.self) XCTAssertEqual(i64, ubc, "Bitcast Double-> i64 Values don't match") let dbl = Double(bitPattern: UInt64(val)) let ubdb = unsafeBitCast(val, to: Double.self) XCTAssertEqual(dbl, ubdb, "Bitcast i64 -> Double Values don't match") let db2 = Double(bitPattern: uval) let usbc2 = unsafeBitCast(uval, to: Double.self) XCTAssertEqual(db2, usbc2, "Bitcast u64 -> Double Values don't match") } static var allTests : [(String, (TFramedTransportTests) -> () throws -> Void)] { return [ ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testDataWriteRead", testDataWriteRead), ("testStructWriteRead", testStructWriteRead), ("testUnsafeBitcastUpdate", testUnsafeBitcastUpdate) ] } } thrift-0.23.0/lib/swift/Tests/ThriftTests/TSocketServerTests.swift0000664000175000017500000000335515165535636025536 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift private protocol CalculatorService { } private class Calculator: CalculatorService { } private class CalculatorProcessor: TProcessor { private let service: CalculatorService init(service: CalculatorService) { self.service = service } var processCalled = false func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { processCalled = true } } class TSocketServerTests: XCTestCase { func testInit() throws { let service: CalculatorService = Calculator() let processor: CalculatorProcessor = CalculatorProcessor(service: service) let _: TSocketServer = try TSocketServer(port: 9090, inProtocol: TBinaryProtocol.self, outProtocol: TBinaryProtocol.self, processor: processor) } static var allTests : [(String, (TSocketServerTests) -> () throws -> Void)] { return [ ("testInit", testInit), ] } } thrift-0.23.0/lib/swift/Tests/ThriftTests/TMultiplexedProcessorTests.swift0000664000175000017500000001321215165535636027304 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift private protocol CalculatorService { } private class Calculator: CalculatorService { } private class CalculatorProcessor: TProcessor { private let service: CalculatorService init(service: CalculatorService) { self.service = service } var processCalled = false func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { processCalled = true } } class TMultiplexedProcessorTests: XCTestCase { let sut = MultiplexedProcessor() var transport: TMemoryBufferTransport = TMemoryBufferTransport { $0.reset(readBuffer: $1) } lazy var proto = TMultiplexedProtocol(on: transport) override func setUp() { super.setUp() transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testExceptionMessageThrowsError() throws { try proto.writeMessageBegin(name: "message", type: .exception, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.incompatibleMessageType(let type) = error else { XCTFail() return } XCTAssertEqual(type, .exception) } } func testReplyMessageThrowsError() throws { try proto.writeMessageBegin(name: "message", type: .reply, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.incompatibleMessageType(let type) = error else { XCTFail() return } XCTAssertEqual(type, .reply) } } func testMissingDefaultProcessorThrowsError() throws { try proto.writeMessageBegin(name: "message", type: .call, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.missingDefaultProcessor = error else { XCTFail() return } } } func testUsesDefaultProcessorForNonMultiplexedMessage() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(defaultProcessor: calculatorProcessor) try proto.writeMessageBegin(name: "message", type: .call, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) XCTAssertTrue(calculatorProcessor.processCalled) } func testUsesProcessorForMultiplexedMessage() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(processor: calculatorProcessor, for: "Calculator") try proto.writeMessageBegin(name: "Calculator:message", type: .call, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) XCTAssertTrue(calculatorProcessor.processCalled) } func testMissingProcessorForMultiplexedMessageThrowsError() throws { try proto.writeMessageBegin(name: "Calculator:message", type: .call, sequenceID: 1) try transport.flush() XCTAssertThrowsError(try sut.process(on: proto, outProtocol: proto)) { error in guard case MultiplexedProcessor.Error.missingProcessor(let serviceName) = error else { XCTFail() return } XCTAssertEqual(serviceName, "Calculator") } } func testCallMessageDoesNotThrowError() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(defaultProcessor: calculatorProcessor) try proto.writeMessageBegin(name: "message", type: .call, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) } func testOneWayMessageDoesNotThrowError() throws { let calculator = Calculator() let calculatorProcessor = CalculatorProcessor(service: calculator) sut.register(defaultProcessor: calculatorProcessor) try proto.writeMessageBegin(name: "message", type: .oneway, sequenceID: 1) try transport.flush() try sut.process(on: proto, outProtocol: proto) } static var allTests : [(String, (TMultiplexedProcessorTests) -> () throws -> Void)] { return [ ("testExceptionMessageThrowsError", testExceptionMessageThrowsError), ("testReplyMessageThrowsError", testReplyMessageThrowsError), ("testMissingDefaultProcessorThrowsError", testMissingDefaultProcessorThrowsError), ("testUsesDefaultProcessorForNonMultiplexedMessage", testUsesDefaultProcessorForNonMultiplexedMessage), ("testUsesProcessorForMultiplexedMessage", testUsesProcessorForMultiplexedMessage), ("testMissingProcessorForMultiplexedMessageThrowsError", testMissingProcessorForMultiplexedMessageThrowsError), ("testCallMessageDoesNotThrowError", testCallMessageDoesNotThrowError), ("testOneWayMessageDoesNotThrowError", testOneWayMessageDoesNotThrowError) ] } } thrift-0.23.0/lib/swift/Tests/ThriftTests/ThriftTests.swift0000664000175000017500000000207515170007142024207 0ustar00buildbuild00000000000000/* * 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 XCTest @testable import Thrift class ThriftTests: XCTestCase { func testVersion() { XCTAssertEqual(Thrift().version, "0.23.0") } static var allTests : [(String, (ThriftTests) -> () throws -> Void)] { return [ ("testVersion", testVersion), ] } } thrift-0.23.0/lib/swift/Tests/ThriftTests/TJSONProtocolTests.swift0000664000175000017500000001724615165535636025416 0ustar00buildbuild00000000000000/* * 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 XCTest import Foundation @testable import Thrift class TJSONProtocolTests: XCTestCase { var transport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TJSONProtocol! override func setUp() { super.setUp() proto = TJSONProtocol(on: transport) transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testUInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt8WriteRead() { let writeVal: Int8 = -120 try? proto.write(writeVal) try? transport.flush() let readVal: Int8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead2() { let writeVal: String = "你好世界 means hello world!" try? proto.write(writeVal) try? transport.flush() let readVal: String do { print(writeVal) readVal = try proto.read() print(readVal) } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testUUIDWriteRead() { let writeVal: UUID = UUID() try? proto.write(writeVal) try? transport.flush() let newUuid = UUID() let readVal: UUID = (try? proto.read()) ?? newUuid XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try? transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal: TApplicationError = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") let readValMessage = readVal.message ?? "", writeValMessage = writeVal.message ?? "" XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readValMessage) got \(writeValMessage)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testBase64WriteRead() { let writeText = "!testing base64 read and write ..." let writeData = writeText.data(using: .utf8)! let writeVal = [UInt8](writeData) try? proto.writeJsonBase64(bytes: writeVal) try? transport.flush() var data = Data() if let readVal = try? proto.readJsonBase64() { data = Data(bytes: readVal, count: readVal.count) } let readText = String(decoding: data, as: UTF8.self) XCTAssertEqual(readText, writeText, "Error message mismatch, expected \(readText) got \(writeText)") } func testBase64WriteRead2() { let writeText = "你好世界 means hello world!" let writeData = writeText.data(using: .utf8)! let writeVal = [UInt8](writeData) try? proto.writeJsonBase64(bytes: writeVal) try? transport.flush() var data = Data() if let readVal = try? proto.readJsonBase64() { data = Data(bytes: readVal, count: readVal.count) } let readText = String(decoding: data, as: UTF8.self) XCTAssertEqual(readText, writeText, "Error message mismatch, expected \(readText) got \(writeText)") } static var allTests : [(String, (TJSONProtocolTests) -> () throws -> Void)] { return [ ("testUInt8WriteRead", testUInt8WriteRead), ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testStringWriteRead2", testStringWriteRead2), ("testDataWriteRead", testDataWriteRead), ("testUUIDWriteRead", testUUIDWriteRead), ("testStructWriteRead", testStructWriteRead), ("testBase64WriteRead", testBase64WriteRead), ("testBase64WriteRead2", testBase64WriteRead2) ] } } thrift-0.23.0/lib/swift/Tests/ThriftTests/TBinaryProtocolTests.swift0000664000175000017500000001347315167543515026064 0ustar00buildbuild00000000000000/* * 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. */ // // TBinaryProtocolTests.swift // Thrift // // Created by Christopher Simpson on 8/18/16. // // import XCTest import Foundation @testable import Thrift /// Testing Binary protocol read/write against itself /// Uses separate read/write transport/protocols class TBinaryProtocolTests: XCTestCase { var transport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TBinaryProtocol! override func setUp() { super.setUp() proto = TBinaryProtocol(on: transport) transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String! do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try? transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readVal.message) got \(writeVal.message)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testUnsafeBitcastUpdate() { let value: Double = 3.14159 let val: Int64 = 31415926 let uval: UInt64 = 31415926 let i64 = Int64(bitPattern: value.bitPattern) let ubc = unsafeBitCast(value, to: Int64.self) XCTAssertEqual(i64, ubc, "Bitcast Double-> i64 Values don't match") let dbl = Double(bitPattern: UInt64(val)) let ubdb = unsafeBitCast(val, to: Double.self) XCTAssertEqual(dbl, ubdb, "Bitcast i64 -> Double Values don't match") let db2 = Double(bitPattern: uval) let usbc2 = unsafeBitCast(uval, to: Double.self) XCTAssertEqual(db2, usbc2, "Bitcast u64 -> Double Values don't match") } static var allTests : [(String, (TBinaryProtocolTests) -> () throws -> Void)] { return [ ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testDataWriteRead", testDataWriteRead), ("testStructWriteRead", testStructWriteRead), ("testUnsafeBitcastUpdate", testUnsafeBitcastUpdate) ] } } thrift-0.23.0/lib/swift/Tests/ThriftTests/TCompactProtocolTests.swift0000664000175000017500000001775215167543515026232 0ustar00buildbuild00000000000000/* * 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. */ // // TCompactProtocolTests.swift // Thrift // // Created by Christopher Simpson on 8/19/16. // // import XCTest import Foundation @testable import Thrift /// Testing Binary protocol read/write against itself /// Uses separate read/write transport/protocols class TCompactProtocolTests: XCTestCase { var transport: TMemoryBufferTransport = TMemoryBufferTransport(flushHandler: { $0.reset(readBuffer: $1) }) var proto: TCompactProtocol! override func setUp() { super.setUp() proto = TCompactProtocol(on: transport) transport.reset() } override func tearDown() { super.tearDown() transport.reset() } func testInt8WriteRead() { let writeVal: UInt8 = 250 try? proto.write(writeVal) try? transport.flush() let readVal: UInt8 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with UInt8, wrote \(writeVal) but read \(readVal)") } func testInt16WriteRead() { let writeVal: Int16 = 12312 try? proto.write(writeVal) try? transport.flush() let readVal: Int16 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int16, wrote \(writeVal) but read \(readVal)") } func testInt32WriteRead() { let writeVal: Int32 = 2029234 try? proto.write(writeVal) try? transport.flush() let readVal: Int32 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int32, wrote \(writeVal) but read \(readVal)") } func testInt64WriteRead() { let writeVal: Int64 = 234234981374134 try? proto.write(writeVal) try? transport.flush() let readVal: Int64 = (try? proto.read()) ?? 0 XCTAssertEqual(writeVal, readVal, "Error with Int64, wrote \(writeVal) but read \(readVal)") } func testDoubleWriteRead() { let writeVal: Double = 3.1415926 try? proto.write(writeVal) try? transport.flush() let readVal: Double = (try? proto.read()) ?? 0.0 XCTAssertEqual(writeVal, readVal, "Error with Double, wrote \(writeVal) but read \(readVal)") } func testBoolWriteRead() { let writeVal: Bool = true try? proto.write(writeVal) try? transport.flush() let readVal: Bool = (try? proto.read()) ?? false XCTAssertEqual(writeVal, readVal, "Error with Bool, wrote \(writeVal) but read \(readVal)") } func testStringWriteRead() { let writeVal: String = "Hello World" try? proto.write(writeVal) try? transport.flush() let readVal: String! do { readVal = try proto.read() } catch let error { XCTAssertFalse(true, "Error reading \(error)") return } XCTAssertEqual(writeVal, readVal, "Error with String, wrote \(writeVal) but read \(readVal)") } func testDataWriteRead() { let writeVal: Data = "Data World".data(using: .utf8)! try? proto.write(writeVal) try? transport.flush() let readVal: Data = (try? proto.read()) ?? "Goodbye World".data(using: .utf8)! XCTAssertEqual(writeVal, readVal, "Error with Data, wrote \(writeVal) but read \(readVal)") } func testStructWriteRead() { let msg = "Test Protocol Error" let writeVal = TApplicationError(error: .protocolError, message: msg) do { try writeVal.write(to: proto) try transport.flush() } catch let error { XCTAssertFalse(true, "Caught Error attempting to write \(error)") } do { let readVal = try TApplicationError.read(from: proto) XCTAssertEqual(readVal.error.thriftErrorCode, writeVal.error.thriftErrorCode, "Error case mismatch, expected \(readVal.error) got \(writeVal.error)") XCTAssertEqual(readVal.message, writeVal.message, "Error message mismatch, expected \(readVal.message) got \(writeVal.message)") } catch let error { XCTAssertFalse(true, "Caught Error attempting to read \(error)") } } func testInt32ZigZag() { let zero: Int32 = 0 let one: Int32 = 1 let nOne: Int32 = -1 let two: Int32 = 2 let nTwo: Int32 = -2 let max = Int32.max let min = Int32.min XCTAssertEqual(proto.i32ToZigZag(zero), UInt32(0), "Error 32bit zigzag on \(zero)") XCTAssertEqual(proto.zigZagToi32(0), zero, "Error 32bit zigzag on \(zero)") XCTAssertEqual(proto.i32ToZigZag(nOne), UInt32(1), "Error 32bit zigzag on \(nOne)") XCTAssertEqual(proto.zigZagToi32(1), nOne, "Error 32bit zigzag on \(nOne)") XCTAssertEqual(proto.i32ToZigZag(one), UInt32(2), "Error 32bit zigzag on \(one)") XCTAssertEqual(proto.zigZagToi32(2), one, "Error 32bit zigzag on \(one)") XCTAssertEqual(proto.i32ToZigZag(nTwo), UInt32(3), "Error 32bit zigzag on \(nTwo)") XCTAssertEqual(proto.zigZagToi32(3), nTwo, "Error 32bit zigzag on \(nTwo)") XCTAssertEqual(proto.i32ToZigZag(two), UInt32(4), "Error 32bit zigzag on \(two)") XCTAssertEqual(proto.zigZagToi32(4), two, "Error 32bit zigzag on \(two)") let uMaxMinusOne: UInt32 = UInt32.max - 1 XCTAssertEqual(proto.i32ToZigZag(max), uMaxMinusOne, "Error 32bit zigzag on \(max)") XCTAssertEqual(proto.zigZagToi32(uMaxMinusOne), max, "Error 32bit zigzag on \(max)") XCTAssertEqual(proto.i32ToZigZag(min), UInt32.max, "Error 32bit zigzag on \(min)") XCTAssertEqual(proto.zigZagToi32(UInt32.max), min, "Error 32bit zigzag on \(min)") } func testInt64ZigZag() { let zero: Int64 = 0 let one: Int64 = 1 let nOne: Int64 = -1 let two: Int64 = 2 let nTwo: Int64 = -2 let max = Int64.max let min = Int64.min XCTAssertEqual(proto.i64ToZigZag(zero), UInt64(0), "Error 64bit zigzag on \(zero)") XCTAssertEqual(proto.zigZagToi64(0), zero, "Error 64bit zigzag on \(zero)") XCTAssertEqual(proto.i64ToZigZag(nOne), UInt64(1), "Error 64bit zigzag on \(nOne)") XCTAssertEqual(proto.zigZagToi64(1), nOne, "Error 64bit zigzag on \(nOne)") XCTAssertEqual(proto.i64ToZigZag(one), UInt64(2), "Error 64bit zigzag on \(one)") XCTAssertEqual(proto.zigZagToi64(2), one, "Error 64bit zigzag on \(one)") XCTAssertEqual(proto.i64ToZigZag(nTwo), UInt64(3), "Error 64bit zigzag on \(nTwo)") XCTAssertEqual(proto.zigZagToi64(3), nTwo, "Error 64bit zigzag on \(nTwo)") XCTAssertEqual(proto.i64ToZigZag(two), UInt64(4), "Error 64bit zigzag on \(two)") XCTAssertEqual(proto.zigZagToi64(4), two, "Error 64bit zigzag on \(two)") let uMaxMinusOne: UInt64 = UInt64.max - 1 XCTAssertEqual(proto.i64ToZigZag(max), uMaxMinusOne, "Error 64bit zigzag on \(max)") XCTAssertEqual(proto.zigZagToi64(uMaxMinusOne), max, "Error 64bit zigzag on \(max)") XCTAssertEqual(proto.i64ToZigZag(min), UInt64.max, "Error 64bit zigzag on \(min)") XCTAssertEqual(proto.zigZagToi64(UInt64.max), min, "Error 64bit zigzag on \(min)") } static var allTests : [(String, (TCompactProtocolTests) -> () throws -> Void)] { return [ ("testInt8WriteRead", testInt8WriteRead), ("testInt16WriteRead", testInt16WriteRead), ("testInt32WriteRead", testInt32WriteRead), ("testInt64WriteRead", testInt64WriteRead), ("testDoubleWriteRead", testDoubleWriteRead), ("testBoolWriteRead", testBoolWriteRead), ("testStringWriteRead", testStringWriteRead), ("testDataWriteRead", testDataWriteRead), ("testStructWriteRead", testStructWriteRead), ("testInt32ZigZag", testInt32ZigZag), ("testInt64ZigZag", testInt64ZigZag) ] } } thrift-0.23.0/lib/swift/Tests/LinuxMain.swift0000664000175000017500000000174015167543515021362 0ustar00buildbuild00000000000000/* * 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 XCTest @testable import ThriftTests XCTMain([ testCase(ThriftTests.allTests), testCase(TBinaryProtocolTests.allTests), testCase(TCompactProtocolTests.allTests), ]) thrift-0.23.0/lib/swift/Package.swift0000664000175000017500000000211115165535636017703 0ustar00buildbuild00000000000000// 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: "Sources"), .testTarget(name: "ThriftTests", dependencies: ["Thrift"]) ] ) thrift-0.23.0/lib/swift/README.md0000664000175000017500000002034615165535636016563 0ustar00buildbuild00000000000000Thrift Swift Library ========================= License ------- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ## Build swift build ## Test swift test ## Install Library ##### Cocoapods Add the following to your podfile ```ruby pod 'Thrift-swift3', :git => 'git@github.com:apache/thrift.git', :branch => 'master' ``` ##### SPM Unfortunately due to some limitations in SPM, the Package manifest and Sources directory must be at the root of the project. To get around that for the time being, you can use this mirrored repo. Add the following to your Package.swift ```swift dependencies: [ .Package(url: "https://github.com/apocolipse/Thrift-Swift.git", majorVersion: 1) ] ``` ## Thrift Compiler You can compile IDL sources for Swift 3 with the following command: thrift --gen swift thrift_file ## Client Example ```swift let transport = TSocketTransport(hostname: "localhost", port: 9090)! // var proto = TCompactProtocol(transport: transport) let proto = TBinaryProtocol(on: transport) // var client = HermesClient(inoutProtocol: proto) let client = ThriftTestClient(inoutProtocol: proto) do { try client.testVoid() } catch let error { print("\(error)") } ``` ## Library Notes - Eliminated Protocol Factories, They were only used in async clients and server implementations, where Generics provide a better alternative. - Swifty Errors, All `TError` types have a nested `ErrorCode` Enum as well as some extra flavor where needed. - Value typed everything. `TTransport` operates on value typed `Data` rather than reference typed `NSData` or `UnsafeBufferPointer`s - Swift 3 Named protocols. Swift 3 naming conventions suggest the elimination of redundant words that can be inferred from variable/function signatures. This renaming is applied throughout the Swift 3 library converting most naming conventions used in the Swift2/Cocoa library to Swift 3-esque naming conventions. eg. ```swift func readString() throws -> String func writeString(_ val: String) throws ``` have been renamed to eliminate redundant words: ```swift func read() throws -> String func write(_ val: String) throws ``` - Eliminated `THTTPTransport` that uses `NSURLConnection` due to it being deprecated and not available at all in Swift 3 for Linux. `THTTPSessionTransport` from the Swift2/Cocoa library that uses `NSURLSession` has been renamed to `THTTPTransport` for this library and leverages `URLSession`, providing both synchronous (with semaphores) and asynchronous behavior. - Probably some More things I've missed here. ## Generator Notes #### Generator Flags | Flag | Description | | ------------- |:-------------:| | async_clients | Generate clients which invoke asynchronously via block syntax. Asynchronous classes are appended with `_Async` | | no_strict* | Generates non-strict structs | | debug_descriptions | Allow use of debugDescription so the app can add description via a cateogory/extension | | log_unexpected | Log every time an unexpected field ID or type is encountered. | | safe_enums | Generate enum types with an unknown case to handle unspecified values rather than throw a serialization error | *Most thrift libraries allow empty initialization of Structs, initializing `required` fields with nil/null/None (Python and Node generators). Swift on the other hand requires initializers to initialize all non-Optional fields, and thus the Swift 3 generator does not provide default values (unlike the Swift 2/Cocoa generator). In other languages, this allows the sending of NULL values in fields that are marked `required`, and thus will throw an error in Swift clients attempting to validate fields. The `no_strict` option here will ignore the validation check, as well as behave similar to the Swift2/Cocoa generator and initialize required fields with empty initializers (where possible). ## Whats implemented #### Library ##### Transports - [x] TSocketTransport - CFSocket and PosixSocket variants available. CFSocket variant only currently available for Darwin platforms - [x] THTTPTransport - Currently only available for Darwin platforms, Swift Foundation URLSession implementation needs completion on linux. - [x] TSocketServer - Uses CFSockets only for binding, should be working on linux - [x] TFramedTransport - [x] TMemoryBufferTransport - [x] TFileTransport - A few variants using File handles and file descriptors. - [x] TStreamTransport - Fully functional in Darwin, Foundation backing not yet completed in Linux (This limits TCFSocketTransport to Darwin) - [ ] HTTPServer - Currently there is no lightweight HTTPServer implementation the Swift Standard Library, so other 3rd party alternatives are required and out of scope for the Thrift library. Examples using Perfect will be provided. - [ ] Other (gz, etc) ##### Protocols - [x] TBinaryProtocol - [x] TCompactProtocol - [x] TJSONProtocol ##### Generator - [x] Code Complete Generator - [x] Async clients - [x] Documentation Generation - Generator will transplant IDL docs to Swift code for easy lookup in Xcode - [ ] Default Values - TODO - [ ] no_strict mode - TODO - [ ] Namespacing - Still haven't nailed down a good paradigm for namespacing. It will likely involve creating subdirectories for different namespaces and expecting the developer to import each subdirectory as separate modules. It could extend to creating SPM Package manifests with sub-modules within the generated module ## Example HTTP Server with Perfect ```swift import PerfectLib import PerfectHTTP import PerfectHTTPServer import Dispatch let logQueue = DispatchQueue(label: "log", qos: .background, attributes: .concurrent) let pQueue = DispatchQueue(label: "log", qos: .userInitiated, attributes: .concurrent) class TPerfectServer { private var server = HTTPServer() private var processor: TProcessor init(address: String? = nil, path: String? = nil, port: Int, processor: TProcessor, inProtocol: InProtocol.Type, outProtocol: OutProtocol.Type) throws { self.processor = processor if let address = address { server.serverAddress = address } server.serverPort = UInt16(port) var routes = Routes() var uri = "/" if let path = path { uri += path } routes.add(method: .post, uri: uri) { request, response in pQueue.async { response.setHeader(.contentType, value: "application/x-thrift") let itrans = TMemoryBufferTransport() if let bytes = request.postBodyBytes { let data = Data(bytes: bytes) itrans.reset(readBuffer: data) } let otrans = TMemoryBufferTransport(flushHandler: { trans, buff in let array = buff.withUnsafeBytes { Array(UnsafeBufferPointer(start: $0, count: buff.count)) } response.status = .ok response.setBody(bytes: array) response.completed() }) let inproto = InProtocol(on: itrans) let outproto = OutProtocol(on: otrans) do { try processor.process(on: inproto, outProtocol: outproto) try otrans.flush() } catch { response.status = .badRequest response.completed() } } } server.addRoutes(routes) } func serve() throws { try server.start() } } ``` #### Example Usage ```swift class ServiceHandler : Service { ... } let server = try? TPerfectServer(port: 9090, processor: ServiceProcessor(service: ServiceHandler()), inProtocol: TBinaryProtocol.self, outProtocol: TBinaryProtocol.self) try? server?.serve() ``` thrift-0.23.0/lib/swift/Sources/0000775000175000017500000000000015170007142016700 5ustar00buildbuild00000000000000thrift-0.23.0/lib/swift/Sources/TSocketTransport.swift0000664000175000017500000001566315165535636023304 0ustar00buildbuild00000000000000 /* * 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. */ #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc import Dispatch #endif import Foundation import CoreFoundation #if !swift(>=4.2) // Swift 3/4 compatibility fileprivate extension RunLoopMode { static let `default` = defaultRunLoopMode } #endif private struct Sys { #if os(Linux) static let read = Glibc.read static let write = Glibc.write static let close = Glibc.close #else static let read = Darwin.read static let write = Darwin.write static let close = Darwin.close #endif } extension in_addr { public init?(hostent: hostent?) { guard let host = hostent, host.h_addr_list != nil, host.h_addr_list.pointee != nil else { return nil } self.init() memcpy(&self, host.h_addr_list.pointee!, Int(host.h_length)) } } #if os(Linux) /// TCFSocketTransport currently unavailable /// remove comments and build to see why/fix /// currently CF[Read|Write]Stream's can't cast to [Input|Output]Streams which breaks thigns #else extension Stream.PropertyKey { static let SSLPeerTrust = Stream.PropertyKey(kCFStreamPropertySSLPeerTrust as String) } /// TCFSocketTransport, uses CFSockets and (NS)Stream's public class TCFSocketTransport: TStreamTransport { public init?(hostname: String, port: Int, secure: Bool = false) { var inputStream: InputStream var outputStream: OutputStream var readStream: Unmanaged? var writeStream: Unmanaged? CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostname as CFString, UInt32(port), &readStream, &writeStream) if let readStream = readStream?.takeRetainedValue(), let writeStream = writeStream?.takeRetainedValue() { CFReadStreamSetProperty(readStream, .shouldCloseNativeSocket, kCFBooleanTrue) CFWriteStreamSetProperty(writeStream, .shouldCloseNativeSocket, kCFBooleanTrue) if secure { CFReadStreamSetProperty(readStream, .socketSecurityLevel, StreamSocketSecurityLevel.negotiatedSSL.rawValue as CFString) CFWriteStreamSetProperty(writeStream, .socketSecurityLevel, StreamSocketSecurityLevel.negotiatedSSL.rawValue as CFString) } inputStream = readStream as InputStream inputStream.schedule(in: .current, forMode: .default) inputStream.open() outputStream = writeStream as OutputStream outputStream.schedule(in: .current, forMode: .default) outputStream.open() } else { if readStream != nil { readStream?.release() } if writeStream != nil { writeStream?.release() } super.init(inputStream: nil, outputStream: nil) return nil } super.init(inputStream: inputStream, outputStream: outputStream) self.input?.delegate = self self.output?.delegate = self } } extension TCFSocketTransport: StreamDelegate { } #endif /// TSocketTransport, posix sockets. Supports IPv4 only for now public class TSocketTransport : TTransport { public var socketDescriptor: Int32 /// Initialize from an already set up socketDescriptor. /// Expects socket thats already bound/connected (i.e. from listening) /// /// - parameter socketDescriptor: posix socket descriptor (Int32) public init(socketDescriptor: Int32) { self.socketDescriptor = socketDescriptor } public convenience init(hostname: String, port: Int) throws { guard let hp = gethostbyname(hostname.cString(using: .utf8)!)?.pointee, let hostAddr = in_addr(hostent: hp) else { throw TTransportError(error: .unknown, message: "Invalid address: \(hostname)") } #if os(Linux) let sock = socket(AF_INET, Int32(SOCK_STREAM.rawValue), 0) var addr = sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: in_port_t(htons(UInt16(port))), sin_addr: hostAddr, sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #else let sock = socket(AF_INET, SOCK_STREAM, 0) var addr = sockaddr_in(sin_len: UInt8(MemoryLayout.size), sin_family: sa_family_t(AF_INET), sin_port: in_port_t(htons(UInt16(port))), sin_addr: hostAddr, sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #endif let addrPtr = withUnsafePointer(to: &addr){ UnsafePointer(OpaquePointer($0)) } let connected = connect(sock, addrPtr, UInt32(MemoryLayout.size)) if connected != 0 { throw TTransportError(error: .notOpen, message: "Error binding to host: \(hostname) \(port)") } self.init(socketDescriptor: sock) } public convenience init(path: String) throws { let socket = UnixSocket(path: path) let errno = socket.connect() guard errno == 0 else { throw TTransportError(error: .notOpen, message: "Error binding to socket at path: \(path). Errno: \(errno)") } self.init(socketDescriptor: socket.fd) } deinit { close() } public func readAll(size: Int) throws -> Data { var out = Data() while out.count < size { out.append(try self.read(size: size)) } return out } public func read(size: Int) throws -> Data { var buff = Array.init(repeating: 0, count: size) let readBytes = Sys.read(socketDescriptor, &buff, size) return Data(buff[0.. 0 { let written = writeBuffer.withUnsafeBytes { Sys.write(socketDescriptor, $0.baseAddress!, writeBuffer.count) } writeBuffer = writeBuffer.subdata(in: written ..< writeBuffer.count) bytesToWrite -= written } } public func flush() throws { // nothing to do } public func close() { shutdown(socketDescriptor, Int32(SHUT_RDWR)) _ = Sys.close(socketDescriptor) } } thrift-0.23.0/lib/swift/Sources/TJSONProtocol.swift0000664000175000017500000011363715165535636022432 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation /** JSON protocol implementation for thrift. This is a full-feature protocol supporting Write and Read. Please see the C++ class header for a detailed description of the protocol's wire format Adapted from netstd C# version */ public class TJSONProtocol: TProtocol { static let Version: Int = 1 public var transport: TTransport // Temporary buffer used by several methods private var tempBuffer: [UInt8] = [0,0,0,0] private var contextStack: JSONContextStack = JSONContextStack() private var currentContext: JSONBaseContext? private var context: JSONBaseContext { get throws { if (currentContext != nil) { return currentContext! } throw TProtocolError(error: .depthLimit, message: "Current context is nil") } } /** Reader that manages a 1-byte buffer */ private var optionalReader: LookaheadReader? private var reader: LookaheadReader { get throws { if (optionalReader != nil) { return optionalReader! } throw TProtocolError(error: .depthLimit, message: "Lookahead reader is nil") } } // MARK: TJSONProtocol Constructor public required init(on transport: TTransport) { self.transport = transport currentContext = JSONBaseContext(on: self) optionalReader = LookaheadReader(on: self) } // MARK: TJSONProtocol helpers /** Push a new JSON context onto the context stack */ func pushContext(_ context: JSONBaseContext) { contextStack.push(context) currentContext = context } /** Pop current JSON context from the context stack */ func popContext() { _ = contextStack.pop() currentContext = contextStack.isEmpty() ? JSONBaseContext(on: self) : contextStack.peek() } /** Reset context stack to pristine state. Allows for reusal of the protocol even in cases where the protocol instance was in an undefined state due to dangling/stale/obsolete contexts */ func resetContext() { contextStack.clear() currentContext = JSONBaseContext(on: self) } /** Read a byte that must match bytes[0]; otherwise an exception is thrown. - bytes: Input bytes array */ func readJsonSyntaxChar(bytes: [UInt8]) throws { let ch: UInt8 = try reader.read() if (ch != bytes[0]) { throw TProtocolError(error: .invalidData, message: "Unexpected character: \(ch.asCharacter())") } } /** Write the bytes in array buffer as a JSON characters, escaping as needed */ func writeJsonString(bytes: [UInt8]) throws { try context.writeConditionalDelimiter() try transport.writeJSONQuote() let len: Int = bytes.count for i in 0..= 0x30) { if (bytes[i] == TJSONProtocolConstants.Backslash[0]) { try transport.writeJSONBackslash() try transport.writeJSONBackslash() } else { try transport.write(data: Data(bytes: [bytes[i]], count: 1)) } } else { tempBuffer[0] = TJSONProtocolConstants.JsonCharTable[Int(bytes[i])] if (tempBuffer[0] == 1) { try transport.write(data: Data(bytes: [bytes[i]], count: 1)) } else if (tempBuffer[0] > 1) { try transport.writeJSONBackslash() try transport.write(data: Data(bytes: [tempBuffer[0]], count: 1)) } else { try transport.writeJSONEscSequences() tempBuffer[0] = (bytes[i] >> 4).toHexChar() tempBuffer[1] = (bytes[i]).toHexChar() try transport.write(data: Data(bytes: [tempBuffer[0], tempBuffer[1]], count:2)) } } } try transport.writeJSONQuote() } /** Write out number as a JSON value. If the context dicates so, it will be wrapped in quotes to output as a JSON string. */ func writeJsonInteger(num: Int64) throws { try context.writeConditionalDelimiter() let str: String = String(num) let escapeNum: Bool = try context.escapeNumbers() if (escapeNum) { try transport.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count)) } let strData: Data = str.data(using: .utf8)! try transport.write(data: strData) if (escapeNum) { try transport.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count)) } } /** Write out a double as a JSON value. If it is Nan or Infinity or if the context dictates escaping, write out as JSON string. */ func writeJsonDouble(num: Double) throws { try context.writeConditionalDelimiter() let str = String(num) var special = false switch(str[0]) { case "N", "I": // Nan or Infinity special = true case "-": if (str[1] == "I") { // -Infinity special = true } default: special = false } let escapeNum = try context.escapeNumbers() let escapeNumOrSpecial = special || escapeNum if (escapeNumOrSpecial) { try transport.writeJSONQuote() } if let strData = str.data(using: .utf8) { try transport.write(data: strData) } else { throw TProtocolError(error: .invalidData, message: "Cannot convert double number to data bytes") } if (escapeNumOrSpecial) { try transport.writeJSONQuote() } } /** Write out contents of byte array as a JSON string with base-64 encoded data */ func writeJsonBase64(bytes: [UInt8]) throws { try context.writeConditionalDelimiter() try transport.writeJSONQuote() var len = bytes.count var off = 0 while (len >= 3) { // Encode 3 bytes at a time TBase64Utils.encode(src: bytes, srcOff: off, len: 3, dst: &tempBuffer, dstOff: 0) try transport.write(data: Data(bytes: tempBuffer, count: 4)) off += 3 len -= 3 } if (len > 0) { // Encode remainder TBase64Utils.encode(src: bytes, srcOff: off, len: len, dst: &tempBuffer, dstOff: 0) try transport.write(data: Data(bytes: tempBuffer, count: len + 1)) } try transport.writeJSONQuote() } func writeJsonObjectStart() throws { try context.writeConditionalDelimiter() try transport.writeJSONLeftBrace() pushContext(JSONPairContext(on: self)) } func writeJsonObjectEnd() throws { popContext() try transport.writeJSONRightBrace() } func writeJsonArrayStart() throws { try context.writeConditionalDelimiter() try transport.writeJSONLeftBracket() pushContext(JSONListContext(on: self)) } func writeJsonArrayEnd() throws { popContext() try transport.writeJSONRightBracket() } /** Read in a JSON string, unescaping as appropriate. Skip reading from the context if skipContext is true. */ func readJsonString(skipContext: Bool) throws -> [UInt8] { var codeunits: [Character] = [] if (!skipContext) { try context.readConditionalDelimiter() } try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) var dataBuffer = Data() while (true) { var ch: UInt8 = try reader.read() if (ch == TJSONProtocolConstants.Quote[0]) { break } // Escaped? if (ch != TJSONProtocolConstants.EscSequences[0]) { dataBuffer.append([ch], count: 1) continue } // distinguish between \uXXXX and \? ch = try reader.read() if (ch != TJSONProtocolConstants.EscSequences[1]) { // control chars like \n guard let off: Int = TJSONProtocolConstants.EscSequences.firstIndex(of: ch) else { throw TProtocolError(error: .invalidData, message: "Expected control char") } ch = TJSONProtocolConstants.EscapeCharValues[off] dataBuffer.append([ch], count: 1) continue } // It's \uXXXX let tempData: Data = try transport.readAll(size: 4) let wch = Int16( ((tempData[0]).toHexChar() << 12) + ((tempData[1]).toHexChar() << 8) + ((tempData[2]).toHexChar() << 4) + ((tempData[3]).toHexChar()) ) guard let wchScalar = UnicodeScalar(Int(wch)) else { throw TProtocolError(error: .invalidData, message: "Expected Unicode character") } if (try wch.magnitude.isHighSurrogate()) { if (codeunits.count > 0) { throw TProtocolError(error: .invalidData, message: "Exptected low surrogate char") } codeunits.append(Character(wchScalar)) } else if (try wch.magnitude.isLowSurrogate()) { if (codeunits.count == 0) { throw TProtocolError(error: .invalidData, message: "Exptected high surrogate char") } codeunits.append(Character(wchScalar)) guard let codeunitsData = String(codeunits).data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Codeunits cannot be converted to string bytes") } dataBuffer.append(codeunitsData) codeunits.removeAll() } else { let bytesArray: [UInt8] = withUnsafeBytes(of: wch.bigEndian, Array.init) dataBuffer.append(Data(bytes: bytesArray, count: bytesArray.count)) } } if (codeunits.count > 0) { throw TProtocolError(error: .invalidData, message: "Expected low surrogate char") } let bytesResult: [UInt8] = dataBuffer.map { $0 } return bytesResult } /** Read in a sequence of characters that are all valid in JSON numbers. Does not do a complete regex check to validate that this is actually a number. */ func readJsonNumericChars() throws -> String { var str = "" while(true) { // TODO: Workaround for primitive types with TJSONProtocol: think - how to rewrite into more easy from without exception do { let ch: UInt8 = try reader.peek() if (!ch.isJsonNumeric()) { break } let c = try reader.read() str.append(c.asCharacter()) } catch is TTransportError { break } catch let error { throw error } } return str } /** Read in a JSON number. If the context dictates, read in enclosing quotes. */ func readJsonInteger() throws -> Int64 { try context.readConditionalDelimiter() let escapeNum = try context.escapeNumbers() if (escapeNum) { try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) } let str: String = try readJsonNumericChars() if (escapeNum) { try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) } guard let result = Int64(str) else { throw TProtocolError(error: .invalidData, message: "Cannot convert \(str) to Int64") } return result } /** Read in a JSON double value. Throw if the value is not wrapped in quotes when expected or if wrapped in quotes when not expected. */ func readJsonDouble() throws -> Double { try context.readConditionalDelimiter() let escapeNum = try context.escapeNumbers() if (try reader.peek() == TJSONProtocolConstants.Quote[0]) { let arr: [UInt8] = try readJsonString(skipContext: true) if let str: String = String(data: Data(arr), encoding: .utf8), let dub = Double(str) { if (!escapeNum && !dub.isNaN && !dub.isInfinite) { throw TProtocolError(error: .invalidData, message: "Numeric data unexpectedly quoted") } return dub } else { throw TProtocolError(error: .invalidData, message: "Numeric data convertion to double failed") } } if (escapeNum) { try readJsonSyntaxChar(bytes: TJSONProtocolConstants.Quote) } let str: String = try readJsonNumericChars() if let dub = Double(str) { return dub } else { throw TProtocolError(error: .invalidData, message: "Numeric data convertion to double failed") } } /** Read in a JSON string containing base-64 encoded data and decode it. */ func readJsonBase64() throws -> [UInt8] { var b = try readJsonString(skipContext: false) var len = b.count var off = 0 var size = 0 // Reduce len to ignore fill bytes while( (len > 0) && (b[len - 1] == "=".asciiBytes()[0]) ) { len -= 1 } // Read & decode full byte triplets = 4 source bytes while (len > 4) { // Decode 4 bytes at a time TBase64Utils.decode(src: b, srcOff: off, len: 4, dst: &b, dstOff: size) // Nb: decode in place off += 4 len -= 4 size += 3 } // Don't decode if we hit the end or got a single leftover byte // (invalid base64 but legal for skip of reqular string exType) if (len > 1) { // Decode remainder TBase64Utils.decode(src: b, srcOff: off, len: len, dst: &b, dstOff: size) // NB: decode in place size += len - 1 } let result: [UInt8] = Array(b[0.. (String, TMessageType, Int32) { resetContext() try readJsonArrayStart() let version = try readJsonInteger() if (version != TJSONProtocol.Version) { throw TProtocolError(error: .badVersion(expected: "\(TJSONProtocol.Version)", got: "\(version)"), message: "Bad version") } let buf = try readJsonString(skipContext: false) guard let name = String(bytes: buf, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Invalid message name") } guard let type = TMessageType(rawValue: Int32(try readJsonInteger())) else { throw TProtocolError(error: .invalidData, message: "Invalid message type") } let seqID = try readJsonInteger() return (name, type, Int32(seqID)) } public func readMessageEnd() throws { try readJsonArrayEnd() } public func readStructBegin() throws -> String { try readJsonObjectStart() return "" } public func readStructEnd() throws { try readJsonObjectEnd() } public func readFieldBegin() throws -> (String, TType, Int32) { let ch = try reader.peek() if (ch == TJSONProtocolConstants.RightBrace[0]) { return ("", TType.stop, 0) } let fieldID = try readJsonInteger() try readJsonObjectStart() let fieldName: [UInt8] = try readJsonString(skipContext: false) let fieldType: TType = try TType.getTypeIdForTypeName(fieldName) guard let name = String(bytes: fieldName, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Invalid field name") } return (name, fieldType, Int32(fieldID)) } public func readFieldEnd() throws { try readJsonObjectEnd() } public func readMapBegin() throws -> (TType, TType, Int32) { try readJsonArrayStart() let keyTypeName = try readJsonString(skipContext: false) let keyType = try TType.getTypeIdForTypeName(keyTypeName) let valueTypeName = try readJsonString(skipContext: false) let valueType = try TType.getTypeIdForTypeName(valueTypeName) let count = try readJsonInteger() try checkReadBytesAvailable(keyType: keyType, valueType: valueType, count: Int32(count)) try readJsonObjectStart() return (keyType, valueType, Int32(count)) } public func readMapEnd() throws { try readJsonObjectEnd() try readJsonArrayEnd() } public func readSetBegin() throws -> (TType, Int32) { try readJsonArrayStart() let elementTypeName = try readJsonString(skipContext: false) let elementType = try TType.getTypeIdForTypeName(elementTypeName) let count = try readJsonInteger() try checkReadBytesAvailable(elementType, Int32(count)) return (elementType, Int32(count)) } public func readSetEnd() throws { try readJsonArrayEnd() } public func readListBegin() throws -> (TType, Int32) { try readJsonArrayStart() let elementTypeName = try readJsonString(skipContext: false) let elementType = try TType.getTypeIdForTypeName(elementTypeName) let count = try readJsonInteger() try checkReadBytesAvailable(elementType, Int32(count)) return (elementType, Int32(count)) } public func readListEnd() throws { try readJsonArrayEnd() } public func read() throws -> String { let buf = try readJsonString(skipContext: false) guard let str = String(bytes: buf, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert bytes to string") } return str } public func read() throws -> Bool { let intValue = try readJsonInteger() return intValue == 0 ? false : true } public func read() throws -> UInt8 { return UInt8(try readJsonInteger()) } public func read() throws -> Int8 { return Int8(try readJsonInteger()) } public func read() throws -> Int16 { return Int16(try readJsonInteger()) } public func read() throws -> Int32 { return Int32(try readJsonInteger()) } public func read() throws -> Int64 { return try readJsonInteger() } public func read() throws -> Double { return try readJsonDouble() } public func read() throws -> Data { let base64Bytes = try readJsonBase64() return Data(bytes: base64Bytes, count: base64Bytes.count) } public func read() throws -> UUID { let buf = try readJsonString(skipContext: false) guard let id = String(bytes: buf, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert bytes to string") } guard let uuid = UUID(uuidString: id) else { throw TProtocolError(error: .invalidData, message: "Cannot convert string to uuid") } return uuid } public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { resetContext() try writeJsonArrayStart() try writeJsonInteger(num: Int64(TJSONProtocol.Version)) guard let nameData = name.data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert message name to bytes data") } try writeJsonString(bytes: [UInt8] (nameData)) try writeJsonInteger(num: Int64(messageType.rawValue)) try writeJsonInteger(num: Int64(sequenceID)) } public func writeMessageEnd() throws { try writeJsonArrayEnd() } public func writeStructBegin(name: String) throws { try writeJsonObjectStart() } public func writeStructEnd() throws { try writeJsonObjectEnd() } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try writeJsonInteger(num: Int64(fieldID)) try writeJsonObjectStart() let fieldTypeName = try fieldType.getTypeNameForTypeId() try writeJsonString(bytes: fieldTypeName) } public func writeFieldStop() throws { // Nop } public func writeFieldEnd() throws { try writeJsonObjectEnd() } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try writeJsonArrayStart() let mapKeyTypeName = try keyType.getTypeNameForTypeId() try writeJsonString(bytes: mapKeyTypeName) let mapValueTypeName = try valueType.getTypeNameForTypeId() try writeJsonString(bytes: mapValueTypeName) try writeJsonInteger(num: Int64(size)) try writeJsonObjectStart() } public func writeMapEnd() throws { try writeJsonObjectEnd() try writeJsonArrayEnd() } public func writeSetBegin(elementType: TType, size: Int32) throws { try writeJsonArrayStart() let elementTypeName = try elementType.getTypeNameForTypeId() try writeJsonString(bytes: elementTypeName) try writeJsonInteger(num: Int64(size)) } public func writeSetEnd() throws { try writeJsonArrayEnd() } public func writeListBegin(elementType: TType, size: Int32) throws { try writeJsonArrayStart() let elementTypeName = try elementType.getTypeNameForTypeId() try writeJsonString(bytes: elementTypeName) try writeJsonInteger(num: Int64(size)) } public func writeListEnd() throws { try writeJsonArrayEnd() } public func write(_ value: String) throws { guard let strData = value.data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert string value to bytes data") } try writeJsonString(bytes: [UInt8](strData)) } public func write(_ value: Bool) throws { try writeJsonInteger(num: value ? 1 : 0) } public func write(_ value: UInt8) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int8) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int16) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int32) throws { try writeJsonInteger(num: Int64(value)) } public func write(_ value: Int64) throws { try writeJsonInteger(num: value) } public func write(_ value: Double) throws { try writeJsonDouble(num: value) } public func write(_ value: Data) throws { try writeJsonBase64(bytes: [UInt8](value)) } public func write(_ value: UUID) throws { guard let strData = value.uuidString.data(using: .utf8) else { throw TProtocolError(error: .invalidData, message: "Cannot convert UUID value to bytes data") } try writeJsonString(bytes: [UInt8](strData)) } // MARK: - Private functions private func checkReadBytesAvailable(keyType: TType, valueType: TType, count: Int32) throws { let elmSize = try getMinSerializedSize(keyType) + getMinSerializedSize(valueType) _ = count * elmSize // TODO: implement checkReadBytesAvailable in TTransport // transport.checkReadBytesAvailable(size: count * elmSize) } private func checkReadBytesAvailable(_ elementType: TType, _ count: Int32) throws { let elmSize = try getMinSerializedSize(elementType) _ = count * elmSize // TODO: implement checkReadBytesAvailable in TTransport // transport.checkReadBytesAvailable(size: count * elmSize) } private func getMinSerializedSize(_ type: TType) throws -> Int32 { switch(type) { case .stop, .void: return 0 case .bool, .i8, .i16, .i32, .i64, .double: return 1 case .string, .struct, .map, .set, .list: return 2 // empty object default: throw TProtocolError(error: .invalidData, message: "Invalid TType") } } // MARK: - TJSONProtocol inner classes /* Base class for tracking JSON contexts that may require inserting/reading additional JSON syntax characters This base context does nothing */ class JSONBaseContext { var proto: TJSONProtocol init(on proto: TJSONProtocol) { self.proto = proto } func writeConditionalDelimiter() throws { } func readConditionalDelimiter() throws { } func escapeNumbers() -> Bool { return false } } /* Context for JSON lists. will insert/read commas before each item except for the first one */ class JSONListContext: JSONBaseContext { private var first: Bool = true override init(on proto: TJSONProtocol) { super.init(on: proto) } override func writeConditionalDelimiter() throws { if (first) { first = false } else { try proto.transport.writeJSONComma() } } override func readConditionalDelimiter() throws { if (first) { first = false } else { try proto.readJsonSyntaxChar(bytes: TJSONProtocolConstants.Comma) } } } /* Context for JSON records. Will insert/read colons before the value portion of each record pair, and commas before each key except the first. In addition, will indicate that numbers in the key position need to be escaped in quotes (since JSON keys must be strings). */ class JSONPairContext : JSONBaseContext { private var colon: Bool = true private var first: Bool = true override init(on proto: TJSONProtocol) { super.init(on: proto) } override func writeConditionalDelimiter() throws { if (first) { first = false colon = true } else { if (colon) { try proto.transport.writeJSONColon() } else { try proto.transport.writeJSONComma() } self.colon = !self.colon } } override func readConditionalDelimiter() throws { if (first) { first = false colon = true } else { try proto.readJsonSyntaxChar(bytes: colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma) self.colon = !self.colon } } override func escapeNumbers() -> Bool { return colon } } class JSONContextStack { private var items: [JSONBaseContext] = [] func peek() -> JSONBaseContext { guard let topElement = items.first else { fatalError("This stack is empty.") } return topElement } func pop() -> JSONBaseContext { return items.removeFirst() } func push(_ element: JSONBaseContext) { items.insert(element, at: 0) } func clear() { items.removeAll() } func isEmpty() -> Bool { return items.count == 0 } } class LookaheadReader { private var byteData: UInt8? private var hasData: Bool = false var proto: TJSONProtocol init(on proto: TJSONProtocol) { self.proto = proto } func read() throws -> UInt8 { if (hasData) { hasData = false } else { let data = try proto.transport.readAll(size: 1) byteData = Array(data)[0] } if let byte = byteData { return byte } throw TProtocolError(error: .invalidData, message: "Reader does not have data to read") } func peek() throws -> UInt8 { if (!hasData) { let data = try proto.transport.readAll(size: 1) byteData = Array(data)[0] hasData = true } if let byte = byteData { return byte } throw TProtocolError(error: .invalidData, message: "Reader does not have data to peek") } } } // MARK: TJSONProtocolConstants /** TJSONProtocol Constants properties/fields */ public struct TJSONProtocolConstants { public static let Comma: [UInt8] = ",".asciiBytes() public static let Colon: [UInt8] = ":".asciiBytes() public static let LeftBrace: [UInt8] = "{".asciiBytes() public static let RightBrace: [UInt8] = "}".asciiBytes() public static let LeftBracket: [UInt8] = "[".asciiBytes() public static let RightBracket: [UInt8] = "]".asciiBytes() public static let Quote: [UInt8] = "\"".asciiBytes() public static let Backslash: [UInt8] = "\\".asciiBytes() public static let JsonCharTable: [UInt8] = [ 0, 0, 0, 0, 0, 0, 0, 0, b, t, n, 0, f, r, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, qt, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] // \b -> \u{0008} // \f -> \u{000C} public static let EscapeChars: [Character] = ["\"", "\\", "/", "\u{0008}", "\u{000C}", "\n", "\r", "\t" ] public static let EscapeCharValues: [UInt8] = "\"\\/\u{0008}\u{000C}\n\r\t".asciiBytes() public static let EscSequences: [UInt8] = "\\u00".asciiBytes() public struct TypeNames { public static let NameBool: [UInt8] = "tf".asciiBytes() public static let NameByte: [UInt8] = "i8".asciiBytes() public static let NameI16: [UInt8] = "i16".asciiBytes() public static let NameI32: [UInt8] = "i32".asciiBytes() public static let NameI64: [UInt8] = "i64".asciiBytes() public static let NameDouble: [UInt8] = "dbl".asciiBytes() public static let NameStruct: [UInt8] = "rec".asciiBytes() public static let NameString: [UInt8] = "str".asciiBytes() public static let NameMap: [UInt8] = "map".asciiBytes() public static let NameList: [UInt8] = "lst".asciiBytes() public static let NameSet: [UInt8] = "set".asciiBytes() } // MARK: private fields helpers private static let b: UInt8 = "b".asciiBytes()[0] private static let t: UInt8 = "t".asciiBytes()[0] private static let n: UInt8 = "n".asciiBytes()[0] private static let f: UInt8 = "f".asciiBytes()[0] private static let r: UInt8 = "r".asciiBytes()[0] private static let qt: UInt8 = "\"".asciiBytes()[0] } // MARK: Extensions extension String { public func asciiBytes() -> [UInt8] { var result: [UInt8] = [] for char in self { result.append(char.asciiValue!) } return result } subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] } } extension Character { public func asciiByte() -> UInt8 { return self.asciiValue! } } extension UInt8 { /** Convert a byte containing a hex value to its corresponding hex character */ public func toHexChar() -> UInt8 { var value = self & 0x0F if (value < 10) { let zeroChar = Character("0").asciiValue! return value + zeroChar } value -= 10 let aChar = Character("a").asciiValue! return value + aChar } public func isJsonNumeric() -> Bool { let numberBytes = "+-.0123456789Ee".asciiBytes() if (numberBytes.contains(self)) { return true } return false } public func asCharacter() -> Character { let scalar = UnicodeScalar(self) return Character(scalar) } } extension UInt16 { public func isHighSurrogate() throws -> Bool { let wch = self if let d800 = UInt16("D800", radix: 16), let dbff = UInt16("DBFF", radix: 16) { return wch >= d800 && wch <= dbff } else { throw TProtocolError(error: .invalidData, message: "isHighSurrogate failed") } } public func isLowSurrogate() throws -> Bool{ let wch = self if let dc00 = UInt16("DC00", radix: 16), let dfff = UInt16("DFFF", radix: 16) { return wch >= dc00 && wch <= dfff } else { throw TProtocolError(error: .invalidData, message: "isLowSurrogate failed") } } } extension TType { public static func getTypeIdForTypeName(_ name: [UInt8]) throws -> TType { var result = TType.stop if (name.count > 1) { switch(name[0]) { case "t".asciiBytes()[0]: result = TType.bool case "i".asciiBytes()[0]: switch(name[1]) { case "8".asciiBytes()[0]: result = TType.i8 case "1".asciiBytes()[0]: result = TType.i16 case "3".asciiBytes()[0]: result = TType.i32 case "6".asciiBytes()[0]: result = TType.i64 default: result = TType.stop } case "d".asciiBytes()[0]: result = TType.double case "l".asciiBytes()[0]: result = TType.list case "m".asciiBytes()[0]: result = TType.map case "r".asciiBytes()[0]: result = TType.struct case "s".asciiBytes()[0]: if (name[1] == "t".asciiBytes()[0]) { result = TType.string } else if (name[1] == "e".asciiBytes()[0]) { result = TType.set } default: result = TType.stop } } if (result == TType.stop) { throw TProtocolError(error: .notImplemented, message: "Unrecognized exType") } return result } public func getTypeNameForTypeId() throws -> [UInt8] { let typeId = self switch(typeId) { case .bool: return TJSONProtocolConstants.TypeNames.NameBool case .i8: return TJSONProtocolConstants.TypeNames.NameByte case .i16: return TJSONProtocolConstants.TypeNames.NameI16 case .i32: return TJSONProtocolConstants.TypeNames.NameI32 case .i64: return TJSONProtocolConstants.TypeNames.NameI64 case .double: return TJSONProtocolConstants.TypeNames.NameDouble case .string: return TJSONProtocolConstants.TypeNames.NameString case .struct: return TJSONProtocolConstants.TypeNames.NameStruct case .map: return TJSONProtocolConstants.TypeNames.NameMap case .set: return TJSONProtocolConstants.TypeNames.NameSet case .list: return TJSONProtocolConstants.TypeNames.NameList default: throw TProtocolError(error: .invalidData, message: "TypeId: \(typeId) does not have mapping Name") } } } extension TTransport { func writeJSONColon() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Colon, count: TJSONProtocolConstants.Colon.count)) } func writeJSONComma() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Comma, count: TJSONProtocolConstants.Comma.count)) } func writeJSONQuote() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Quote, count: TJSONProtocolConstants.Quote.count)) } func writeJSONBackslash() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.Backslash, count: TJSONProtocolConstants.Backslash.count)) } func writeJSONEscSequences() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.EscSequences, count: TJSONProtocolConstants.EscSequences.count)) } func writeJSONLeftBrace() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.LeftBrace, count: TJSONProtocolConstants.LeftBrace.count)) } func writeJSONRightBrace() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.RightBrace, count: TJSONProtocolConstants.RightBrace.count)) } func writeJSONLeftBracket() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.LeftBracket, count: TJSONProtocolConstants.LeftBracket.count)) } func writeJSONRightBracket() throws { try self.write(data: Data(bytes: TJSONProtocolConstants.RightBracket, count: TJSONProtocolConstants.RightBracket.count)) } } thrift-0.23.0/lib/swift/Sources/TProtocol.swift0000664000175000017500000001372415170007142021712 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public enum TMessageType: Int32 { case call = 1 case reply = 2 case exception = 3 case oneway = 4 } public enum TType: Int32 { case stop = 0 case void = 1 case bool = 2 case i8 = 3 case double = 4 case i16 = 6 case i32 = 8 case i64 = 10 case string = 11 case `struct` = 12 case map = 13 case set = 14 case list = 15 case uuid = 16 } public protocol TProtocol { var transport: TTransport { get set } init(on transport: TTransport) // Reading Methods func readMessageBegin() throws -> (String, TMessageType, Int32) func readMessageEnd() throws func readStructBegin() throws -> String func readStructEnd() throws func readFieldBegin() throws -> (String, TType, Int32) func readFieldEnd() throws func readMapBegin() throws -> (TType, TType, Int32) func readMapEnd() throws func readSetBegin() throws -> (TType, Int32) func readSetEnd() throws func readListBegin() throws -> (TType, Int32) func readListEnd() throws func read() throws -> String func read() throws -> Bool func read() throws -> UInt8 func read() throws -> Int8 func read() throws -> Int16 func read() throws -> Int32 func read() throws -> Int64 func read() throws -> Double func read() throws -> Data func read() throws -> UUID // Writing methods func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws func writeMessageEnd() throws func writeStructBegin(name: String) throws func writeStructEnd() throws func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws func writeFieldStop() throws func writeFieldEnd() throws func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws func writeMapEnd() throws func writeSetBegin(elementType: TType, size: Int32) throws func writeSetEnd() throws func writeListBegin(elementType: TType, size: Int32) throws func writeListEnd() throws func write(_ value: String) throws func write(_ value: Bool) throws func write(_ value: UInt8) throws func write(_ value: Int8) throws func write(_ value: Int16) throws func write(_ value: Int32) throws func write(_ value: Int64) throws func write(_ value: Double) throws func write(_ value: Data) throws func write(_ value: UUID) throws } public extension TProtocol { func writeFieldValue(_ value: TSerializable, name: String, type: TType, id: Int32) throws { try writeFieldBegin(name: name, type: type, fieldID: id) try value.write(to: self) try writeFieldEnd() } func validateValue(_ value: Any?, named name: String) throws { if value == nil { throw TProtocolError(error: .unknown, message: "Missing required value for field: \(name)") } } func readResultMessageBegin() throws { let (_, type, _) = try readMessageBegin(); if type == .exception { let x = try readException() throw x } return } func readException() throws -> TApplicationError { return try TApplicationError.read(from: self) } func writeException(messageName name: String, sequenceID: Int32, ex: TApplicationError) throws { try writeMessageBegin(name: name, type: .exception, sequenceID: sequenceID) try ex.write(to: self) try writeMessageEnd() } func skip(type: TType) throws { try skip(type: type, depth: 0) } private func skip(type: TType, depth: Int) throws { let nextDepth = depth + 1 if nextDepth > 64 { throw TProtocolError(error: .depthLimit, message: "Maximum skip depth exceeded") } switch type { case .bool: _ = try read() as Bool case .i8: _ = try read() as Int8 case .i16: _ = try read() as Int16 case .i32: _ = try read() as Int32 case .i64: _ = try read() as Int64 case .double: _ = try read() as Double case .string: _ = try read() as String case .uuid: _ = try read() as UUID case .struct: _ = try readStructBegin() while true { let (_, fieldType, _) = try readFieldBegin() if fieldType == .stop { break } try skip(type: fieldType, depth: nextDepth) try readFieldEnd() } try readStructEnd() case .map: let (keyType, valueType, size) = try readMapBegin() if size < 0 { throw TProtocolError(error: .negativeSize, message: "Negative map size: \(size)") } for _ in 0..=4.2) // Swift 3/4 compatibility fileprivate extension RunLoopMode { static let `default` = defaultRunLoopMode } #endif #if os(Linux) public class TSSLSocketTransport { init(hostname: String, port: UInt16) { // FIXME! assert(false, "Security not available in Linux, TSSLSocketTransport Unavilable for now") } } #else let isLittleEndian = Int(OSHostByteOrder()) == OSLittleEndian let htons = isLittleEndian ? _OSSwapInt16 : { $0 } let htonl = isLittleEndian ? _OSSwapInt32 : { $0 } public class TSSLSocketTransport: TStreamTransport { var sslHostname: String var sd: Int32 = 0 public init(hostname: String, port: UInt16) throws { sslHostname = hostname var readStream: Unmanaged? var writeStream: Unmanaged? /* create a socket structure */ var pin: sockaddr_in = sockaddr_in() var hp: UnsafeMutablePointer? = nil for i in 0..<10 { hp = gethostbyname(hostname.cString(using: String.Encoding.utf8)!) if hp == nil { print("failed to resolve hostname \(hostname)") herror("resolv") if i == 9 { super.init(inputStream: nil, outputStream: nil) // have to init before throwing throw TSSLSocketTransportError(error: .hostanameResolution(hostname: hostname)) } Thread.sleep(forTimeInterval: 0.2) } else { break } } pin.sin_family = UInt8(AF_INET) pin.sin_addr = in_addr(s_addr: UInt32((hp?.pointee.h_addr_list.pointee?.pointee)!)) // Is there a better way to get this??? pin.sin_port = htons(port) /* create the socket */ sd = socket(Int32(AF_INET), Int32(SOCK_STREAM), Int32(IPPROTO_TCP)) if sd == -1 { super.init(inputStream: nil, outputStream: nil) // have to init before throwing throw TSSLSocketTransportError(error: .socketCreate(port: Int(port))) } /* open a connection */ // need a non-self ref to sd, otherwise the j complains let sd_local = sd let connectResult = withUnsafePointer(to: &pin) { connect(sd_local, UnsafePointer(OpaquePointer($0)), socklen_t(MemoryLayout.size)) } if connectResult == -1 { super.init(inputStream: nil, outputStream: nil) // have to init before throwing throw TSSLSocketTransportError(error: .connect) } CFStreamCreatePairWithSocket(kCFAllocatorDefault, sd, &readStream, &writeStream) CFReadStreamSetProperty(readStream?.takeRetainedValue(), .socketNativeHandle, kCFBooleanTrue) CFWriteStreamSetProperty(writeStream?.takeRetainedValue(), .socketNativeHandle, kCFBooleanTrue) var inputStream: InputStream? = nil var outputStream: OutputStream? = nil if readStream != nil && writeStream != nil { CFReadStreamSetProperty(readStream?.takeRetainedValue(), .socketSecurityLevel, kCFStreamSocketSecurityLevelTLSv1) let settings: [String: Bool] = [kCFStreamSSLValidatesCertificateChain as String: true] CFReadStreamSetProperty(readStream?.takeRetainedValue(), .SSLSettings, settings as CFTypeRef) CFWriteStreamSetProperty(writeStream?.takeRetainedValue(), .SSLSettings, settings as CFTypeRef) inputStream = readStream!.takeRetainedValue() inputStream?.schedule(in: .current, forMode: .default) inputStream?.open() outputStream = writeStream!.takeRetainedValue() outputStream?.schedule(in: .current, forMode: .default) outputStream?.open() readStream?.release() writeStream?.release() } super.init(inputStream: inputStream, outputStream: outputStream) self.input?.delegate = self self.output?.delegate = self } func recoverFromTrustFailure(_ myTrust: SecTrust, lastTrustResult: SecTrustResultType) -> Bool { let trustTime = SecTrustGetVerifyTime(myTrust) let currentTime = CFAbsoluteTimeGetCurrent() let timeIncrement = 31536000 // from TSSLSocketTransport.m let newTime = currentTime - Double(timeIncrement) if trustTime - newTime != 0 { let newDate = CFDateCreate(nil, newTime) SecTrustSetVerifyDate(myTrust, newDate!) var tr = lastTrustResult let success = withUnsafeMutablePointer(to: &tr) { trPtr -> Bool in if SecTrustEvaluate(myTrust, trPtr) != errSecSuccess { return false } return true } if !success { return false } } if lastTrustResult == .proceed || lastTrustResult == .unspecified { return false } print("TSSLSocketTransport: Unable to recover certificate trust failure") return true } public func isOpen() -> Bool { return sd > 0 } } extension TSSLSocketTransport: StreamDelegate { public func stream(_ aStream: Stream, handle eventCode: Stream.Event) { switch eventCode { case Stream.Event(): break case Stream.Event.hasBytesAvailable: break case Stream.Event.openCompleted: break case Stream.Event.hasSpaceAvailable: var proceed = false var trustResult: SecTrustResultType = .invalid var newPolicies: CFMutableArray? repeat { let trust: SecTrust = aStream.property(forKey: .SSLPeerTrust) as! SecTrust // Add new policy to current list of policies let policy = SecPolicyCreateSSL(false, sslHostname as CFString?) var ppolicy = policy // mutable for pointer let policies: UnsafeMutablePointer? = nil if SecTrustCopyPolicies(trust, policies!) != errSecSuccess { break } withUnsafeMutablePointer(to: &ppolicy) { ptr in newPolicies = CFArrayCreateMutableCopy(nil, 0, policies?.pointee) CFArrayAppendValue(newPolicies, ptr) } // update trust policies if SecTrustSetPolicies(trust, newPolicies!) != errSecSuccess { break } // Evaluate the trust chain let success = withUnsafeMutablePointer(to: &trustResult) { trustPtr -> Bool in if SecTrustEvaluate(trust, trustPtr) != errSecSuccess { return false } return true } if !success { break } switch trustResult { case .proceed: proceed = true case .unspecified: proceed = true case .recoverableTrustFailure: proceed = self.recoverFromTrustFailure(trust, lastTrustResult: trustResult) case .deny: break case .fatalTrustFailure: break case .otherError: break case .invalid: break default: break } } while false if !proceed { print("TSSLSocketTransport: Cannot trust certificate. Result: \(trustResult)") aStream.close() } case Stream.Event.errorOccurred: break case Stream.Event.endEncountered: break default: break } } } #endif thrift-0.23.0/lib/swift/Sources/TCompactProtocol.swift0000664000175000017500000004332415170007142023220 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import CoreFoundation public enum TCType: UInt8 { case stop = 0x00 case boolean_TRUE = 0x01 case boolean_FALSE = 0x02 case i8 = 0x03 case i16 = 0x04 case i32 = 0x05 case i64 = 0x06 case double = 0x07 case binary = 0x08 case list = 0x09 case set = 0x0A case map = 0x0B case `struct` = 0x0C case uuid = 0x0D public static let typeMask: UInt8 = 0xE0 // 1110 0000 public static let typeBits: UInt8 = 0x07 // 0000 0111 public static let typeShiftAmount = 5 } public class TCompactProtocol: TProtocol { public static let protocolID: UInt8 = 0x82 public static let version: UInt8 = 1 public static let versionMask: UInt8 = 0x1F // 0001 1111 public var transport: TTransport var lastField: [UInt8] = [] var lastFieldId: UInt8 = 0 var boolFieldName: String? var boolFieldType: TType? var boolFieldId: Int32? var booleanValue: Bool? var currentMessageName: String? public required init(on transport: TTransport) { self.transport = transport } /// Mark: - TCompactProtocol helpers func writebyteDirect(_ byte: UInt8) throws { let byte = Data([byte]) try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: byte) } } func writeVarint32(_ val: UInt32) throws { var val = val var i32buf = [UInt8](repeating: 0, count: 5) var idx = 0 while true { if (val & ~0x7F) == 0 { i32buf[idx] = UInt8(val) idx += 1 break } else { i32buf[idx] = UInt8((val & 0x7F) | 0x80) idx += 1 val >>= 7 } } try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: Data(i32buf[0..>= 7 } } try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: Data(varint64out[0.. Data { var result = Data() if size != 0 { try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { result = try self.transport.readAll(size: size) } } return result } func readVarint32() throws -> UInt32 { var result: UInt32 = 0 var shift: UInt32 = 0 while true { let byte: UInt8 = try read() result |= UInt32(byte & 0x7F) << shift if (byte & 0x80) == 0 { break } shift += 7 } return result } func readVarint64() throws -> UInt64 { var result: UInt64 = 0 var shift: UInt64 = 0 while true { let byte: UInt8 = try read() result |= UInt64(byte & 0x7F) << shift if (byte & 0x80) == 0 { break } shift += 7 } return result } func ttype(_ compactTypeVal: UInt8) throws -> TType { guard let compactType = TCType(rawValue: compactTypeVal) else { throw TProtocolError(message: "Unknown TCType value: \(compactTypeVal)") } switch compactType { case .stop: return .stop; case .boolean_FALSE, .boolean_TRUE: return .bool; case .i8: return .i8; case .i16: return .i16; case .i32: return .i32; case .i64: return .i64; case .double: return .double; case .binary: return .string; case .list: return .list; case .set: return .set; case .map: return .map; case .struct: return .struct; case .uuid: return .uuid; } } func compactType(_ ttype: TType) -> TCType { switch ttype { case .stop: return .stop case .void: return .i8 case .bool: return .boolean_FALSE case .i8: return .i8 case .double: return .double case .i16: return .i16 case .i32: return .i32 case .i64: return .i64 case .string: return .binary case .struct: return .struct case .map: return .map case .set: return .set case .list: return .list case .uuid: return .uuid } } /// ZigZag encoding maps signed integers to unsigned integers so that /// numbers with a small absolute value (for instance, -1) have /// a small varint encoded value too. It does this in a way that /// "zig-zags" back and forth through the positive and negative integers, /// so that -1 is encoded as 1, 1 is encoded as 2, -2 is encoded as 3, and so /// /// - parameter n: number to zigzag /// /// - returns: zigzaged UInt32 func i32ToZigZag(_ n : Int32) -> UInt32 { return UInt32(bitPattern: Int32(n << 1) ^ Int32(n >> 31)) } func i64ToZigZag(_ n : Int64) -> UInt64 { return UInt64(bitPattern: Int64(n << 1) ^ Int64(n >> 63)) } func zigZagToi32(_ n: UInt32) -> Int32 { return Int32(n >> 1) ^ (-Int32(n & 1)) } func zigZagToi64(_ n: UInt64) -> Int64 { return Int64(n >> 1) ^ (-Int64(n & 1)) } /// Mark: - TProtocol public func readMessageBegin() throws -> (String, TMessageType, Int32) { let protocolId: UInt8 = try read() if protocolId != TCompactProtocol.protocolID { let expected = String(format:"%2X", TCompactProtocol.protocolID) let got = String(format:"%2X", protocolId) throw TProtocolError(message: "Wrong Protocol ID \(got)", extendedError: .mismatchedProtocol(expected: expected, got: got)) } let versionAndType: UInt8 = try read() let version: UInt8 = versionAndType & TCompactProtocol.versionMask if version != TCompactProtocol.version { throw TProtocolError(error: .badVersion(expected: "\(TCompactProtocol.version)", got:"\(version)")) } let type = (versionAndType >> UInt8(TCType.typeShiftAmount)) & TCType.typeBits guard let mtype = TMessageType(rawValue: Int32(type)) else { throw TProtocolError(message: "Unknown TMessageType value: \(type)") } let varint = zigZagToi32(try readVarint32()) let sequenceId = Int32(varint) let name: String = try read() return (name, mtype, Int32(sequenceId)) } public func readMessageEnd() throws { } public func readStructBegin() throws -> String { lastField.append(lastFieldId) lastFieldId = 0 return "" } public func readStructEnd() throws { lastFieldId = lastField.last ?? 0 lastField.removeLast() } public func readFieldBegin() throws -> (String, TType, Int32) { let byte: UInt8 = try read() guard let type = TCType(rawValue: byte & 0x0F) else { throw TProtocolError(message: "Unknown TCType \(byte & 0x0F)") } // if it's a stop, then we can return immediately, as the struct is over if type == .stop { return ("", .stop, 0) } var fieldId: Int16 = 0 // mask off the 4MSB of the type header. it could contain a field id delta let modifier = (byte & 0xF0) >> 4 if modifier == 0 { // not a delta. look ahead for the zigzag varint field id fieldId = try read() } else { // has a delta. add the delta to the last Read field id. fieldId = Int16(lastFieldId + modifier) } let fieldType = try ttype(type.rawValue) // if this happens to be a boolean field, the value is encoded in the type if type == .boolean_TRUE || type == .boolean_FALSE { // save the boolean value in a special instance variable booleanValue = type == .boolean_TRUE } guard fieldId >= 0 && fieldId <= Int16(UInt8.max) else { throw TProtocolError(error: .invalidData, message: "Field id out of range: \(fieldId)") } // push the new field onto the field stack so we can keep the deltas going lastFieldId = UInt8(fieldId) return ("", fieldType, Int32(fieldId)) } public func readFieldEnd() throws { } public func read() throws -> String { let length = try readVarint32() var result: String if length != 0 { let data = try readBinary(Int(length)) result = String(data: data, encoding: String.Encoding.utf8) ?? "" } else { result = "" } return result } public func read() throws -> Bool { if let val = booleanValue { self.booleanValue = nil return val } else { let result = try read() as UInt8 return TCType(rawValue: result) == .boolean_TRUE } } public func read() throws -> UInt8 { var buff: UInt8 = 0 try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1)[0] } return buff } public func read() throws -> Int8 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1) } return buff.withUnsafeBytes { pntr in return pntr.load(as: Int8.self) } } public func read() throws -> Int16 { let v = try readVarint32() return Int16(zigZagToi32(v)) } public func read() throws -> Int32 { let v = try readVarint32() return zigZagToi32(v) } public func read() throws -> Int64 { let v = try readVarint64() return zigZagToi64(v) } public func read() throws -> Double { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 8) } let i64: UInt64 = buff.withUnsafeBytes { $0.load(as: UInt64.self) } let bits = CFSwapInt64LittleToHost(i64) return Double(bitPattern: bits) } public func read() throws -> Data { let length = try readVarint32() return try readBinary(Int(length)) } public func read() throws -> UUID { let data = try self.transport.readAll(size: 16) let lsb = data[0.. (TType, TType, Int32) { var keyAndValueType: UInt8 = 8 let size = try readVarint32() if size != 0 { keyAndValueType = try read() } let keyType = try ttype(keyAndValueType >> 4) let valueType = try ttype(keyAndValueType & 0xF) return (keyType, valueType, Int32(size)) } public func readMapEnd() throws { } public func readSetBegin() throws -> (TType, Int32) { return try readListBegin() } public func readSetEnd() throws { } public func readListBegin() throws -> (TType, Int32) { let sizeAndType: UInt8 = try read() var size: UInt32 = UInt32(sizeAndType >> 4) & 0x0f if size == 15 { size = try readVarint32() } let elementType = try ttype(sizeAndType & 0x0F) return (elementType, Int32(size)) } public func readListEnd() throws { } public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { try writebyteDirect(TCompactProtocol.protocolID) let nextByte: UInt8 = (TCompactProtocol.version & TCompactProtocol.versionMask) | (UInt8((UInt32(messageType.rawValue) << UInt32(TCType.typeShiftAmount))) & TCType.typeMask) try writebyteDirect(nextByte) try writeVarint32(i32ToZigZag(sequenceID)) try write(name) currentMessageName = name } public func writeMessageEnd() throws { currentMessageName = nil } public func writeStructBegin(name: String) throws { lastField.append(lastFieldId) lastFieldId = 0 } public func writeStructEnd() throws { lastFieldId = lastField.last ?? 0 lastField.removeLast() } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { if fieldType == .bool { boolFieldName = name boolFieldType = fieldType boolFieldId = fieldID return } else { try writeFieldBeginInternal(name: name, type: fieldType, fieldID: fieldID, typeOverride: 0xFF) } } func writeFieldBeginInternal(name: String, type fieldType: TType, fieldID: Int32, typeOverride: UInt8) throws { let typeToWrite = typeOverride == 0xFF ? compactType(fieldType).rawValue : typeOverride // check if we can use delta encoding for the field id let diff = UInt8(fieldID) - lastFieldId if (UInt8(fieldID) > lastFieldId) && (diff <= 15) { // Write them together try writebyteDirect((UInt8(fieldID) - lastFieldId) << 4 | typeToWrite) } else { // Write them separate try writebyteDirect(typeToWrite) try write(Int16(fieldID)) } lastFieldId = UInt8(fieldID) } public func writeFieldStop() throws { try writebyteDirect(TCType.stop.rawValue) } public func writeFieldEnd() throws { } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { if size == 0 { try writebyteDirect(0) } else { try writeVarint32(UInt32(size)) let compactedTypes = compactType(keyType).rawValue << 4 | compactType(valueType).rawValue try writebyteDirect(compactedTypes) } } public func writeMapEnd() throws { } public func writeSetBegin(elementType: TType, size: Int32) throws { try writeCollectionBegin(elementType, size: size) } public func writeSetEnd() throws { } public func writeListBegin(elementType: TType, size: Int32) throws { try writeCollectionBegin(elementType, size: size) } public func writeListEnd() throws { } public func write(_ value: String) throws { try write(value.data(using: String.Encoding.utf8)!) } public func write(_ value: Bool) throws { if let boolFieldId = boolFieldId, let boolFieldType = boolFieldType, let boolFieldName = boolFieldName { // we haven't written the field header yet let compactType: TCType = value ? .boolean_TRUE : .boolean_FALSE try writeFieldBeginInternal(name: boolFieldName, type: boolFieldType, fieldID: boolFieldId, typeOverride: compactType.rawValue) self.boolFieldId = nil self.boolFieldType = nil self.boolFieldName = nil } else { // we're not part of a field, so just write the value. try writebyteDirect(value ? TCType.boolean_TRUE.rawValue : TCType.boolean_FALSE.rawValue) } } public func write(_ value: UInt8) throws { try writebyteDirect(value) } public func write(_ value: Int8) throws { var value = value let buff = Data(bytes: &value, count: MemoryLayout.size(ofValue: value)) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int16) throws { try writeVarint32(i32ToZigZag(Int32(value))) } public func write(_ value: Int32) throws { try writeVarint32(i32ToZigZag(value)) } public func write(_ value: Int64) throws { try writeVarint64(i64ToZigZag(value)) } public func write(_ value: Double) throws { var bits = CFSwapInt64HostToLittle(value.bitPattern) let data = withUnsafePointer(to: &bits) { return Data(bytes: UnsafePointer(OpaquePointer($0)), count: MemoryLayout.size) } try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: data) } } public func write(_ data: Data) throws { try writeVarint32(UInt32(data.count)) try ProtocolTransportTry(error: TProtocolError(message: "Transport Write Failed")) { try self.transport.write(data: data) } } public func write(_ value: UUID) throws { let data = withUnsafePointer(to: value.uuid) { Data(bytes: $0, count: MemoryLayout.size(ofValue: value.uuid)) } let msb = data[0.. ()) throws { // Need mutable copy var error = error do { try block() } catch let err as TError { var message = error.message ?? "" message += "\nFile: \(sourceFile)\n" message += "Line: \(sourceLine)\n" message += "Method: \(sourceMethod)" message += "\nOriginal Error:\n" + err.description error.message = message throw error } } thrift-0.23.0/lib/swift/Sources/TError.swift0000664000175000017500000000460015165535636021215 0ustar00buildbuild00000000000000/* * 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. */ /// TErrorCode /// /// Protocol for TError conformers' enum's to conform to. /// Generic Int Thrift error code to allow error cases to have /// associated values. public protocol TErrorCode : CustomStringConvertible { var thriftErrorCode: Int { get } } /// TError /// /// Base protocol for all Thrift Error(Exception) types to conform to public protocol TError : Error, CustomStringConvertible { /// Enum for error cases. Can be typealiased to any conforming enum /// or defined nested. associatedtype Code: TErrorCode /// Error Case, value from internal enum var error: Code { get set } /// Optional additional message var message: String? { get set } /// Default error case for the error type, used for generic init() static var defaultCase: Code { get } init() } extension TError { /// Human readable description of error. Default provided for you in the /// format \(Self.self): \(error.errorDescription) \n message /// eg: /// /// TApplicationError (1): Invalid Message Type /// An unknown Error has occured. public var description: String { var out = "\(Self.self) (\(error.thriftErrorCode)): " + error.description + "\n" if let message = message { out += "Message: \(message)" } return out } /// Simple default Initializer for TError's /// /// - parameter error: ErrorCode value. Default: defaultCase /// - parameter message: Custom message with error. Optional /// /// - returns: <#return value description#> public init(error: Code, message: String? = nil) { self.init() self.error = error self.message = message } } thrift-0.23.0/lib/swift/Sources/TStruct.swift0000664000175000017500000000661215165535636021415 0ustar00buildbuild00000000000000/* * 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. */ /// Protocol for Generated Structs to conform to /// Dictionary maps field names to internal IDs and uses Reflection /// to iterate through all fields. /// `writeFieldValue(_:name:type:id:)` calls `TSerializable.write(to:)` internally /// giving a nice recursive behavior for nested TStructs, TLists, TMaps, and TSets public protocol TStruct : TSerializable { static var fieldIds: [String: Int32] { get } static var structName: String { get } } public extension TStruct { static var fieldIds: [String: (id: Int32, type: TType)] { return [:] } static var thriftType: TType { return .struct } func write(to proto: TProtocol) throws { // Write struct name first try proto.writeStructBegin(name: Self.structName) try self.forEach { name, value, id in // Write to protocol try proto.writeFieldValue(value, name: name, type: value.thriftType, id: id) } try proto.writeFieldStop() try proto.writeStructEnd() } /// Provides a block for handling each (available) thrift property using reflection /// Caveat: Skips over optional values /// Provides a block for handling each (available) thrift property using reflection /// /// - parameter block: block for handling property /// /// - throws: rethrows any Error thrown in block private func forEach(_ block: (_ name: String, _ value: TSerializable, _ id: Int32) throws -> Void) rethrows { // Mirror the object, getting (name: String?, value: Any) for every property let mirror = Mirror(reflecting: self) // Iterate through all children, ignore empty property names for (propName, propValue) in mirror.children { guard let propName = propName else { continue } if let tval = unwrap(any: propValue, parent: mirror) as? TSerializable, let id = Self.fieldIds[propName] { try block(propName, tval, id) } } } /// Any can mysteriously be an Optional at the same time, /// this checks and always returns Optional without double wrapping /// we then try to bind value as TSerializable to ignore any extension properties /// and the like and verify the property exists and grab the Thrift /// property ID at the same time /// /// - parameter any: Any instance to attempt to unwrap /// /// - returns: Unwrapped Any as Optional private func unwrap(any: Any, parent: Mirror) -> Any? { let mi = Mirror(reflecting: any) if parent.displayStyle != .enum && mi.displayStyle != .optional { return any } if mi.children.count == 0 { return nil } let (_, some) = mi.children.first! return some } } thrift-0.23.0/lib/swift/Sources/Thrift.swift0000664000175000017500000000151615170007142021221 0ustar00buildbuild00000000000000/* * 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. */ class Thrift { let version = "0.23.0" } thrift-0.23.0/lib/swift/Sources/TBinary.swift0000664000175000017500000000212415165535636021347 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation extension Data : TSerializable { public static var thriftType: TType { return .string } public static func read(from proto: TProtocol) throws -> Data { return try proto.read() as Data } public func write(to proto: TProtocol) throws { try proto.write(self) } } thrift-0.23.0/lib/swift/Sources/TMultiplexedProtocol.swift0000664000175000017500000000432215165535636024143 0ustar00buildbuild00000000000000/* * 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. */ extension String { static let multiplexSeparator = ":" } /** `TMultiplexedProtocol` is a protocol-independent concrete decorator that allows a Thrift client to communicate with a multiplexing Thrift server, by prepending the service name to the function name during function calls. - Note: THIS IS NOT USED BY SERVERS. On the server, use `TMultiplexedProcessor` to handle request from a multiplexing client. */ public class TMultiplexedProtocol: TWrappedProtocol { public var serviceName = "" public convenience init(on transport: TTransport, serviceName: String) { self.init(on: transport) self.serviceName = serviceName } override public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { switch messageType { case .call, .oneway: var serviceFunction = serviceName serviceFunction += serviceName == "" ? "" : .multiplexSeparator serviceFunction += name return try super.writeMessageBegin(name: serviceFunction, type: messageType, sequenceID: sequenceID) default: return try super.writeMessageBegin(name: name, type: messageType, sequenceID: sequenceID) } } } thrift-0.23.0/lib/swift/Sources/TBinaryProtocol.swift0000664000175000017500000003045615165535636023102 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public struct TBinaryProtocolVersion { static let version1 = Int32(bitPattern: 0x80010000) static let versionMask = Int32(bitPattern: 0xffff0000) } public class TBinaryProtocol: TProtocol { public var messageSizeLimit: UInt32 = 0 public var transport: TTransport // class level properties for setting global config (useful for server in lieu of Factory design) public static var strictRead: Bool = false public static var strictWrite: Bool = true private var strictRead: Bool private var strictWrite: Bool var currentMessageName: String? var currentFieldName: String? public convenience init(transport: TTransport, strictRead: Bool, strictWrite: Bool) { self.init(on: transport) self.strictRead = strictRead self.strictWrite = strictWrite } public required init(on transport: TTransport) { self.transport = transport self.strictWrite = TBinaryProtocol.strictWrite self.strictRead = TBinaryProtocol.strictRead } func readStringBody(_ size: Int) throws -> String { var data = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport read failed")) { data = try self.transport.readAll(size: size) } return String(data: data, encoding: String.Encoding.utf8) ?? "" } /// Mark: - TProtocol public func readMessageBegin() throws -> (String, TMessageType, Int32) { let size: Int32 = try read() var messageName = "" var type = TMessageType.exception if size < 0 { let version = size & TBinaryProtocolVersion.versionMask if version != TBinaryProtocolVersion.version1 { throw TProtocolError(error: .badVersion(expected: "\(TBinaryProtocolVersion.version1)", got: "\(version)")) } type = TMessageType(rawValue: Int32(size) & 0x00FF) ?? type messageName = try read() } else { if strictRead { let errorMessage = "Missing message version, old client? Message Name: \(currentMessageName ?? "")" throw TProtocolError(error: .invalidData, message: errorMessage) } if messageSizeLimit > 0 && size > Int32(messageSizeLimit) { throw TProtocolError(error: .sizeLimit(limit: Int(messageSizeLimit), got: Int(size))) } messageName = try readStringBody(Int(size)) type = TMessageType(rawValue: Int32(try read() as UInt8)) ?? type } let seqID: Int32 = try read() return (messageName, type, seqID) } public func readMessageEnd() throws { return } public func readStructBegin() throws -> String { return "" } public func readStructEnd() throws { return } public func readFieldBegin() throws -> (String, TType, Int32) { let fieldType = TType(rawValue: Int32(try read() as UInt8)) ?? TType.stop var fieldID: Int32 = 0 if fieldType != .stop { fieldID = Int32(try read() as Int16) } return ("", fieldType, fieldID) } public func readFieldEnd() throws { return } public func readMapBegin() throws -> (TType, TType, Int32) { var raw = Int32(try read() as UInt8) guard let keyType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for keyType TType: \(raw)") } raw = Int32(try read() as UInt8) guard let valueType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for valueType TType: \(raw)") } let size: Int32 = try read() return (keyType, valueType, size) } public func readMapEnd() throws { return } public func readSetBegin() throws -> (TType, Int32) { let raw = Int32(try read() as UInt8) guard let elementType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for elementType TType: \(raw)") } let size: Int32 = try read() return (elementType, size) } public func readSetEnd() throws { return } public func readListBegin() throws -> (TType, Int32) { let raw = Int32(try read() as UInt8) guard let elementType = TType(rawValue: raw) else { throw TProtocolError(message: "Unknown value for elementType TType: \(raw)") } let size: Int32 = try read() return (elementType, size) } public func readListEnd() throws { return } public func read() throws -> String { let data: Data = try read() guard let str = String.init(data: data, encoding: .utf8) else { throw TProtocolError(error: .invalidData, message: "Couldn't encode UTF-8 from data read") } return str } public func read() throws -> Bool { return (try read() as UInt8) == 1 } public func read() throws -> UInt8 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1) } return buff[0] } public func read() throws -> Int8 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 1) } return buff.withUnsafeBytes { pntr in return pntr.load(as: Int8.self) } } public func read() throws -> Int16 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 2) } var ret = Int16(buff[0] & 0xff) << 8 ret |= Int16(buff[1] & 0xff) return ret } public func read() throws -> Int32 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 4) } var ret = Int32(buff[0] & 0xff) << 24 ret |= Int32(buff[1] & 0xff) << 16 ret |= Int32(buff[2] & 0xff) << 8 ret |= Int32(buff[3] & 0xff) return ret } public func read() throws -> Int64 { var buff = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { buff = try self.transport.readAll(size: 8) } var ret = Int64(buff[0] & 0xff) << 56 ret |= Int64(buff[1] & 0xff) << 48 ret |= Int64(buff[2] & 0xff) << 40 ret |= Int64(buff[3] & 0xff) << 32 ret |= Int64(buff[4] & 0xff) << 24 ret |= Int64(buff[5] & 0xff) << 16 ret |= Int64(buff[6] & 0xff) << 8 ret |= Int64(buff[7] & 0xff) return ret } public func read() throws -> Double { let val = try read() as Int64 return Double(bitPattern: UInt64(bitPattern: val)) } public func read() throws -> Data { let size = Int(try read() as Int32) var data = Data() try ProtocolTransportTry(error: TProtocolError(message: "Transport Read Failed")) { data = try self.transport.readAll(size: size) } return data } public func read() throws -> UUID { let data = try self.transport.readAll(size: 16) let lsb = data[0..<8] let msb = data[8..<16] var id = UUID().uuid withUnsafeMutableBytes(of: &id) { pntr in var copyData = msb copyData.append(lsb) copyData.copyBytes(to: pntr) } return UUID(uuid: id) } // Write methods public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { if strictWrite { let version = TBinaryProtocolVersion.version1 | Int32(messageType.rawValue) try write(version) try write(name) try write(sequenceID) } else { try write(name) try write(UInt8(messageType.rawValue)) try write(sequenceID) } currentMessageName = name } public func writeMessageEnd() throws { currentMessageName = nil } public func writeStructBegin(name: String) throws { return } public func writeStructEnd() throws { return } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try write(UInt8(fieldType.rawValue)) try write(Int16(fieldID)) } public func writeFieldStop() throws { try write(UInt8(TType.stop.rawValue)) } public func writeFieldEnd() throws { return } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try write(UInt8(keyType.rawValue)) try write(UInt8(valueType.rawValue)) try write(size) } public func writeMapEnd() throws { return } public func writeSetBegin(elementType: TType, size: Int32) throws { try write(UInt8(elementType.rawValue)) try write(size) } public func writeSetEnd() throws { return } public func writeListBegin(elementType: TType, size: Int32) throws { try write(UInt8(elementType.rawValue)) try write(size) } public func writeListEnd() throws { return } public func write(_ value: String) throws { try write(value.data(using: .utf8)!) } public func write(_ value: Bool) throws { let byteVal: UInt8 = value ? 1 : 0 try write(byteVal) } public func write(_ value: UInt8) throws { let buff = Data([value]) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int8) throws { var value = value let buff = Data(bytes: &value, count: MemoryLayout.size(ofValue: value)) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int16) throws { var buff = Data() buff.append(Data([UInt8(0xff & (value >> 8))])) buff.append(Data([UInt8(0xff & (value))])) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int32) throws { var buff = Data() buff.append(Data([UInt8(0xff & (value >> 24))])) buff.append(Data([UInt8(0xff & (value >> 16))])) buff.append(Data([UInt8(0xff & (value >> 8))])) buff.append(Data([UInt8(0xff & (value))])) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Int64) throws { var buff = Data() buff.append(Data([UInt8(0xff & (value >> 56))])) buff.append(Data([UInt8(0xff & (value >> 48))])) buff.append(Data([UInt8(0xff & (value >> 40))])) buff.append(Data([UInt8(0xff & (value >> 32))])) buff.append(Data([UInt8(0xff & (value >> 24))])) buff.append(Data([UInt8(0xff & (value >> 16))])) buff.append(Data([UInt8(0xff & (value >> 8))])) buff.append(Data([UInt8(0xff & (value))])) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: buff) } } public func write(_ value: Double) throws { // Notably unsafe, since Double and Int64 are the same size, this should work fine try self.write(Int64(bitPattern: value.bitPattern)) } public func write(_ data: Data) throws { try write(Int32(data.count)) try ProtocolTransportTry(error: TProtocolError(message: "Transport write failed")) { try self.transport.write(data: data) } } public func write(_ value: UUID) throws { let data = withUnsafePointer(to: value.uuid) { Data(bytes: $0, count: MemoryLayout.size(ofValue: value.uuid)) } let msb = data[0..<8] let lsb = data[8..<16] var buff = Data() buff.append(lsb) buff.append(msb) try self.transport.write(data: buff) } } thrift-0.23.0/lib/swift/Sources/TMultiplexedProcessor.swift0000664000175000017500000000651015165535636024322 0ustar00buildbuild00000000000000/* * 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. */ /** `TMultiplexedProcessor` is a `TProcessor` allowing a single `TServer` to provide multiple services. To do so, you instantiate the processor and then register additional processors with it, as shown in the following example: let processor = MultiplexedProcessor() processor.register(CalculatorProcessor(service: CalculatorService()), for: "Calculator") processor.register(WeatherProcessor(service: CalculatorService()), for: "Weather") let server = TPerfectServer(port: 9090, processor: processor, TCompactProtocol.self, TCompactProtocol.self) try server.start() */ public class MultiplexedProcessor: TProcessor { enum Error: Swift.Error { case incompatibleMessageType(TMessageType) case missingProcessor(String) case missingDefaultProcessor } private var processors = [String: TProcessor]() private var defaultProcessor: TProcessor? public init(defaultProcessor: TProcessor? = nil) { self.defaultProcessor = defaultProcessor } public func register(defaultProcessor processor: TProcessor) { defaultProcessor = processor } public func register(processor: TProcessor, for service: String) { processors[service] = processor } public func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws { let message = try inProtocol.readMessageBegin() guard message.1 == .call || message.1 == .oneway else { throw Error.incompatibleMessageType(message.1) } if let separatorIndex = message.0.firstIndex(of: Character(.multiplexSeparator)) { let serviceName = String(message.0.prefix(upTo: separatorIndex)) let messageName = String(message.0.suffix(from: message.0.index(after: separatorIndex))) guard let processor = processors[serviceName] else { throw Error.missingProcessor(serviceName)} let storedMessage = StoredMessage(message: (messageName, message.1, message.2), proto: inProtocol) try processor.process(on: storedMessage, outProtocol: outProtocol) } else { guard let processor = defaultProcessor else { throw Error.missingDefaultProcessor } try processor.process(on: inProtocol, outProtocol: outProtocol) } } } private final class StoredMessage: TProtocolDecorator { private let message: (String, TMessageType, Int32) init(message: (String, TMessageType, Int32), proto: TProtocol) { self.message = message super.init(proto: proto) } required init(on transport: TTransport) { fatalError("init(on:) has not been implemented") } override func readMessageBegin() throws -> (String, TMessageType, Int32) { return message } } thrift-0.23.0/lib/swift/Sources/TFileTransport.swift0000664000175000017500000000531615165535636022725 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc #endif /// TFileTransport /// Foundation-less Swift File transport. /// Uses C fopen/fread/fwrite, /// provided by Glibc in linux and Darwin on OSX/iOS public class TFileTransport: TTransport { var fileHandle: UnsafeMutablePointer? = nil public init (fileHandle: UnsafeMutablePointer) { self.fileHandle = fileHandle } public convenience init(filename: String) throws { var fileHandle: UnsafeMutablePointer? filename.withCString({ cFilename in "rw".withCString({ cMode in fileHandle = fopen(cFilename, cMode) }) }) if let fileHandle = fileHandle { self.init(fileHandle: fileHandle) } else { throw TTransportError(error: .notOpen) } } deinit { fclose(self.fileHandle) } public func readAll(size: Int) throws -> Data { let read = try self.read(size: size) if read.count != size { throw TTransportError(error: .endOfFile) } return read } public func read(size: Int) throws -> Data { // set up read buffer, position 0 var read = Data(capacity: size) var position = 0 // read character buffer var nextChar: UInt8 = 0 // continue until we've read size bytes while read.count < size { if fread(&nextChar, 1, 1, self.fileHandle) == 1 { read[position] = nextChar // Increment output byte pointer position += 1 } else { throw TTransportError(error: .endOfFile) } } return read } public func write(data: Data) throws { let bytesWritten = data.withUnsafeBytes { fwrite($0.baseAddress!, 1, data.count, self.fileHandle) } if bytesWritten != data.count { throw TTransportError(error: .unknown) } } public func flush() throws { return } } thrift-0.23.0/lib/swift/Sources/TList.swift0000664000175000017500000000735515165535636021051 0ustar00buildbuild00000000000000/* * 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. */ public struct TList : RandomAccessCollection, MutableCollection, ExpressibleByArrayLiteral, TSerializable, Hashable { public typealias Storage = Array public typealias Indices = Storage.Indices internal var storage = Storage() public init() { } public init(arrayLiteral elements: Element...) { self.storage = Storage(elements) } public init(_ sequence: Source) where Source.Iterator.Element == Element { storage = Storage(sequence) } /// Mark: Hashable public func hash(into hasher: inout Hasher) { hasher.combine(storage) } /// Mark: TSerializable public static var thriftType : TType { return .list } public static func read(from proto: TProtocol) throws -> TList { let (elementType, size) = try proto.readListBegin() if elementType != Element.thriftType { throw TProtocolError(error: .invalidData, extendedError: .unexpectedType(type: elementType)) } var list = TList() for _ in 0.. Element { get { return storage[position] } set { storage[position] = newValue } } public subscript(range: Range) -> SubSequence { get { return storage[range] } set { storage[range] = newValue } } public var startIndex: Index { return storage.startIndex } public var endIndex: Index { return storage.endIndex } public func formIndex(after i: inout Index) { storage.formIndex(after: &i) } public func formIndex(before i: inout Int) { storage.formIndex(before: &i) } public func index(after i: Index) -> Index { return storage.index(after: i) } public func index(before i: Int) -> Int { return storage.index(before: i) } } extension TList : RangeReplaceableCollection { public mutating func replaceSubrange(_ subrange: Range, with newElements: C) where C.Iterator.Element == Element { storage.replaceSubrange(subrange, with: newElements) } } extension TList : CustomStringConvertible, CustomDebugStringConvertible { public var description : String { return storage.description } public var debugDescription : String { return storage.debugDescription } } public func ==(lhs: TList, rhs: TList) -> Bool { return lhs.storage.elementsEqual(rhs.storage) { $0 == $1 } } thrift-0.23.0/lib/swift/Sources/TSet.swift0000664000175000017500000001267415165535636020671 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public struct TSet : SetAlgebra, Hashable, Collection, ExpressibleByArrayLiteral, TSerializable { /// Typealias for Storage type public typealias Storage = Set /// Internal Storage used for TSet (Set\) internal var storage : Storage /// Mark: Collection public typealias Element = Storage.Element public typealias Indices = Storage.Indices public typealias Index = Storage.Index public typealias IndexDistance = Int public typealias SubSequence = Storage.SubSequence public var indices: Indices { return storage.indices } // Must implement isEmpty even though both SetAlgebra and Collection provide it due to their conflciting default implementations public var isEmpty: Bool { return storage.isEmpty } public func distance(from start: Index, to end: Index) -> IndexDistance { return storage.distance(from: start, to: end) } public func index(_ i: Index, offsetBy n: IndexDistance) -> Index { return storage.index(i, offsetBy: n) } public func index(_ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index) -> Index? { return storage.index(i, offsetBy: n, limitedBy: limit) } #if swift(>=3.2) public subscript (position: Storage.Index) -> Element { return storage[position] } #else public subscript (position: Storage.Index) -> Element? { return storage[position] } #endif /// Mark: SetAlgebra internal init(storage: Set) { self.storage = storage } public func contains(_ member: Element) -> Bool { return storage.contains(member) } public mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element) { return storage.insert(newMember) } public mutating func remove(_ member: Element) -> Element? { return storage.remove(member) } public func union(_ other: TSet) -> TSet { return TSet(storage: storage.union(other.storage)) } public mutating func formIntersection(_ other: TSet) { return storage.formIntersection(other.storage) } public mutating func formSymmetricDifference(_ other: TSet) { return storage.formSymmetricDifference(other.storage) } public mutating func formUnion(_ other: TSet) { return storage.formUnion(other.storage) } public func intersection(_ other: TSet) -> TSet { return TSet(storage: storage.intersection(other.storage)) } public func symmetricDifference(_ other: TSet) -> TSet { return TSet(storage: storage.symmetricDifference(other.storage)) } public mutating func update(with newMember: Element) -> Element? { return storage.update(with: newMember) } /// Mark: IndexableBase public var startIndex: Index { return storage.startIndex } public var endIndex: Index { return storage.endIndex } public func index(after i: Index) -> Index { return storage.index(after: i) } public func formIndex(after i: inout Storage.Index) { storage.formIndex(after: &i) } public subscript(bounds: Range) -> SubSequence { return storage[bounds] } /// Mark: Hashable public func hash(into hasher: inout Hasher) { hasher.combine(storage) } /// Mark: TSerializable public static var thriftType : TType { return .set } public init() { storage = Storage() } public init(arrayLiteral elements: Element...) { self.storage = Storage(elements) } public init(_ sequence: Source) where Source.Iterator.Element == Element { storage = Storage(sequence) } public static func read(from proto: TProtocol) throws -> TSet { let (elementType, size) = try proto.readSetBegin() if elementType != Element.thriftType { throw TProtocolError(error: .invalidData, extendedError: .unexpectedType(type: elementType)) } var set = TSet() for _ in 0..(lhs: TSet, rhs: TSet) -> Bool { return lhs.storage == rhs.storage } thrift-0.23.0/lib/swift/Sources/TApplicationError.swift0000664000175000017500000001331715165535636023406 0ustar00buildbuild00000000000000/* * 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. */ public struct TApplicationError : TError { public enum Code : TErrorCode { case unknown case unknownMethod(methodName: String?) case invalidMessageType case wrongMethodName(methodName: String?) case badSequenceId case missingResult(methodName: String?) case internalError case protocolError case invalidTransform case invalidProtocol case unsupportedClientType /// Initialize a TApplicationError with a Thrift error code /// Normally this would be achieved with RawRepresentable however /// by doing this we can allow for associated properties on enum cases for /// case specific context data in a Swifty, type-safe manner. /// /// - parameter thriftErrorCode: Integer TApplicationError(exception) error code. /// Default to 0 (.unknown) public init(thriftErrorCode: Int) { switch thriftErrorCode { case 1: self = .unknownMethod(methodName: nil) case 2: self = .invalidMessageType case 3: self = .wrongMethodName(methodName: nil) case 4: self = .badSequenceId case 5: self = .missingResult(methodName: nil) case 6: self = .internalError case 7: self = .protocolError case 8: self = .invalidProtocol case 9: self = .invalidTransform case 10: self = .unsupportedClientType default: self = .unknown } } public var thriftErrorCode: Int { switch self { case .unknown: return 0 case .unknownMethod: return 1 case .invalidMessageType: return 2 case .wrongMethodName: return 3 case .badSequenceId: return 4 case .missingResult: return 5 case .internalError: return 6 case .protocolError: return 7 case .invalidProtocol: return 8 case .invalidTransform: return 9 case .unsupportedClientType: return 10 } } public var description: String { /// Output "for #methodName" if method is not nil else empty let methodUnwrap: (String?) -> String = { method in return "\(method == nil ? "" : " for \(method ?? "")")" } switch self { case .unknown: return "Unknown TApplicationError" case .unknownMethod(let method): return "Unknown Method\(methodUnwrap(method))" case .invalidMessageType: return "Invalid Message Type" case .wrongMethodName(let method): return "Wrong Method Name\(methodUnwrap(method))" case .badSequenceId: return "Bad Sequence ID" case .missingResult(let method): return "Missing Result\(methodUnwrap(method))" case .internalError: return "Internal Error" case .protocolError: return "Protocol Error" case .invalidProtocol: return "Invalid Protocol" case .invalidTransform: return "Invalid Transform" case .unsupportedClientType: return "Unsupported Client Type" } } } public init() { } public init(thriftErrorCode code: Int, message: String? = nil) { self.error = Code(thriftErrorCode: code) self.message = message } public var error: Code = .unknown public var message: String? = nil public static var defaultCase: Code { return .unknown } } extension TApplicationError : TSerializable { public static var thriftType: TType { return .struct } public static func read(from proto: TProtocol) throws -> TApplicationError { var errorCode: Int = 0 var message: String? = nil _ = try proto.readStructBegin() fields: while true { let (_, fieldType, fieldID) = try proto.readFieldBegin() switch (fieldID, fieldType) { case (_, .stop): break fields case (1, .string): message = try proto.read() case (2, .i32): errorCode = Int(try proto.read() as Int32) case let (_, unknownType): try proto.skip(type: unknownType) } try proto.readFieldEnd() } try proto.readStructEnd() return TApplicationError(thriftErrorCode: errorCode, message: message) } public func write(to proto: TProtocol) throws { try proto.writeStructBegin(name: "TApplicationException") try proto.writeFieldBegin(name: "message", type: .string, fieldID: 1) try proto.write(message ?? "") try proto.writeFieldEnd() try proto.writeFieldBegin(name: "type", type: .i32, fieldID: 2) let val = Int32(error.thriftErrorCode) try proto.write(val) try proto.writeFieldEnd() try proto.writeFieldStop() try proto.writeStructEnd() } } extension TApplicationError: Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(error.thriftErrorCode) hasher.combine(message) } } public func ==(lhs: TApplicationError, rhs: TApplicationError) -> Bool { return lhs.error.thriftErrorCode == rhs.error.thriftErrorCode && lhs.message == rhs.message } thrift-0.23.0/lib/swift/Sources/TWrappedProtocol.swift0000664000175000017500000001354515165535636023260 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation // For (NS)Data /// Generic protocol, implementes TProtocol and wraps a concrete protocol. /// Useful for generically subclassing protocols to override specific methods /// (i.e. TMultiplexedProtocol) open class TWrappedProtocol : TProtocol { var concreteProtocol: Protocol public var transport: TTransport { get { return concreteProtocol.transport } set { concreteProtocol.transport = newValue } } public required init(on transport: TTransport) { self.concreteProtocol = Protocol(on: transport) } // Read methods public func readMessageBegin() throws -> (String, TMessageType, Int32) { return try concreteProtocol.readMessageBegin() } public func readMessageEnd() throws { try concreteProtocol.readMessageEnd() } public func readStructBegin() throws -> String { return try concreteProtocol.readStructBegin() } public func readStructEnd() throws { try concreteProtocol.readStructEnd() } public func readFieldBegin() throws -> (String, TType, Int32) { return try concreteProtocol.readFieldBegin() } public func readFieldEnd() throws { try concreteProtocol.readFieldEnd() } public func readMapBegin() throws -> (TType, TType, Int32) { return try concreteProtocol.readMapBegin() } public func readMapEnd() throws { try concreteProtocol.readMapEnd() } public func readSetBegin() throws -> (TType, Int32) { return try concreteProtocol.readSetBegin() } public func readSetEnd() throws { try concreteProtocol.readSetEnd() } public func readListBegin() throws -> (TType, Int32) { return try concreteProtocol.readListBegin() } public func readListEnd() throws { try concreteProtocol.readListEnd() } public func read() throws -> String { return try concreteProtocol.read() } public func read() throws -> Bool { return try concreteProtocol.read() } public func read() throws -> UInt8 { return try concreteProtocol.read() } public func read() throws -> Int8 { return try concreteProtocol.read() } public func read() throws -> Int16 { return try concreteProtocol.read() } public func read() throws -> Int32 { return try concreteProtocol.read() } public func read() throws -> Int64 { return try concreteProtocol.read() } public func read() throws -> Double { return try concreteProtocol.read() } public func read() throws -> Data { return try concreteProtocol.read() } public func read() throws -> UUID { return try concreteProtocol.read() } // Write methods public func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { return try concreteProtocol.writeMessageBegin(name: name, type: messageType, sequenceID: sequenceID) } public func writeMessageEnd() throws { try concreteProtocol.writeMessageEnd() } public func writeStructBegin(name: String) throws { try concreteProtocol.writeStructBegin(name: name) } public func writeStructEnd() throws { try concreteProtocol.writeStructEnd() } public func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try concreteProtocol.writeFieldBegin(name: name, type: fieldType, fieldID: fieldID) } public func writeFieldStop() throws { try concreteProtocol.writeFieldStop() } public func writeFieldEnd() throws { try concreteProtocol.writeFieldEnd() } public func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try concreteProtocol.writeMapBegin(keyType: keyType, valueType: valueType, size: size) } public func writeMapEnd() throws { try concreteProtocol.writeMapEnd() } public func writeSetBegin(elementType: TType, size: Int32) throws { try concreteProtocol.writeSetBegin(elementType: elementType, size: size) } public func writeSetEnd() throws { try concreteProtocol.writeSetEnd() } public func writeListBegin(elementType: TType, size: Int32) throws { try concreteProtocol.writeListBegin(elementType: elementType, size: size) } public func writeListEnd() throws { try concreteProtocol.writeListEnd() } public func write(_ value: String) throws { try concreteProtocol.write(value) } public func write(_ value: Bool) throws { try concreteProtocol.write(value) } public func write(_ value: UInt8) throws { try concreteProtocol.write(value) } public func write(_ value: Int8) throws { try concreteProtocol.write(value) } public func write(_ value: Int16) throws { try concreteProtocol.write(value) } public func write(_ value: Int32) throws { try concreteProtocol.write(value) } public func write(_ value: Int64) throws { try concreteProtocol.write(value) } public func write(_ value: Double) throws { try concreteProtocol.write(value) } public func write(_ data: Data) throws { try concreteProtocol.write(data) } public func write(_ value: UUID) throws { try concreteProtocol.write(value) } } thrift-0.23.0/lib/swift/Sources/TFramedTransport.swift0000664000175000017500000000632715165535636023247 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TFramedTransport: TTransport { public static let headerSize = 4 public static let initFrameSize = 1024 private static let defaultMaxLength = 16384000 public var transport: TTransport private var writeBuffer = Data() private var maxSize = TFramedTransport.defaultMaxLength private var remainingBytes = 0 public init(transport: TTransport, maxSize: Int) { self.transport = transport self.maxSize = maxSize } public convenience init(transport: TTransport) { self.init(transport: transport, maxSize: TFramedTransport.defaultMaxLength) } func readHeader() throws { let read = try transport.readAll(size: TFramedTransport.headerSize) remainingBytes = Int(decodeFrameSize(data: read)) } /// Mark: - TTransport public func read(size: Int) throws -> Data { while (remainingBytes <= 0) { try readHeader() } let toRead = min(size, remainingBytes) if toRead < 0 { try close() throw TTransportError(error: .negativeSize, message: "Read a negative frame size (\(toRead))!") } if toRead > maxSize { try close() throw TTransportError(error: .sizeLimit(limit: maxSize, got: toRead)) } let data = try transport.readAll(size: toRead) remainingBytes -= data.count return data } public func flush() throws { // copy buffer and reset let buff = writeBuffer writeBuffer = Data() let frameSize = encodeFrameSize(size: UInt32(buff.count)) try transport.write(data: frameSize) try transport.write(data: buff) try transport.flush() } public func write(data: Data) throws { writeBuffer.append(data) } private func encodeFrameSize(size: UInt32) -> Data { var data = Data() data.append(Data([UInt8(0xff & (size >> 24))])) data.append(Data([UInt8(0xff & (size >> 16))])) data.append(Data([UInt8(0xff & (size >> 8))])) data.append(Data([UInt8(0xff & (size))])) return data } private func decodeFrameSize(data: Data) -> UInt32 { var size: UInt32 size = (UInt32(data[0] & 0xff) << 24) size |= (UInt32(data[1] & 0xff) << 16) size |= (UInt32(data[2] & 0xff) << 8) size |= (UInt32(data[3] & 0xff)) return size } public func close() throws { try transport.close() } public func open() throws { try transport.open() } public func isOpen() throws -> Bool { return try transport.isOpen() } } thrift-0.23.0/lib/swift/Sources/TClient.swift0000664000175000017500000000254715165535636021352 0ustar00buildbuild00000000000000/* * 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. */ open class TClient { public let inProtocol: TProtocol public let outProtocol: TProtocol required public init(inoutProtocol: TProtocol) { self.inProtocol = inoutProtocol self.outProtocol = inoutProtocol } required public init(inProtocol: TProtocol, outProtocol: TProtocol) { self.inProtocol = inProtocol self.outProtocol = outProtocol } } open class TAsyncClient { public var factory: Factory public init(with protocol: Protocol.Type, factory: Factory) { self.factory = factory } } thrift-0.23.0/lib/swift/Sources/THTTPSessionTransport.swift0000664000175000017500000001335015165535636024166 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation // Conditional import for URLRequest // It was moved from Foundation to FoundationNetworking in 5.1, but // not on Darwin. See https://stackoverflow.com/a/58606520 #if canImport(FoundationNetworking) import FoundationNetworking #endif import Dispatch public class THTTPSessionTransport: TAsyncTransport { public class Factory : TAsyncTransportFactory { public var responseValidate: ((HTTPURLResponse?, Data?) throws -> Void)? var session: URLSession var url: URL public class func setupDefaultsForSessionConfiguration(_ config: URLSessionConfiguration, withProtocolName protocolName: String?) { var thriftContentType = "application/x-thrift" if let protocolName = protocolName { thriftContentType += "; p=\(protocolName)" } config.requestCachePolicy = .reloadIgnoringLocalCacheData config.urlCache = nil config.httpShouldUsePipelining = true config.httpShouldSetCookies = true config.httpAdditionalHeaders = ["Content-Type": thriftContentType, "Accept": thriftContentType, "User-Agent": "Thrift/Swift (Session)"] } public init(session: URLSession, url: URL) { self.session = session self.url = url } public func newTransport() -> THTTPSessionTransport { return THTTPSessionTransport(factory: self) } func validateResponse(_ response: HTTPURLResponse?, data: Data?) throws { try responseValidate?(response, data) } func taskWithRequest(_ request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> ()) throws -> URLSessionTask { let newTask: URLSessionTask? = session.dataTask(with: request, completionHandler: completionHandler) if let newTask = newTask { return newTask } else { throw TTransportError(error: .unknown, message: "Failed to create session data task") } } } var factory: Factory var requestData = Data() var responseData = Data() var responseDataOffset: Int = 0 init(factory: Factory) { self.factory = factory } public func readAll(size: Int) throws -> Data { let read = try self.read(size: size) if read.count != size { throw TTransportError(error: .endOfFile) } return read } public func read(size: Int) throws -> Data { let avail = responseData.count - responseDataOffset let (start, stop) = (responseDataOffset, responseDataOffset + min(size, avail)) let read = responseData.subdata(in: start.. Void) { var error: Error? var task: URLSessionTask? var request = URLRequest(url: factory.url) request.httpMethod = "POST" request.httpBody = requestData requestData = Data() do { task = try factory.taskWithRequest(request, completionHandler: { (data, response, taskError) in // Check if there was an error with the network if taskError != nil { error = TTransportError(error: .timedOut) completed(self, error) return } // Check response type if taskError == nil && !(response is HTTPURLResponse) { error = THTTPTransportError(error: .invalidResponse) completed(self, error) return } // Check status code if let httpResponse = response as? HTTPURLResponse { if taskError == nil && httpResponse.statusCode != 200 { if httpResponse.statusCode == 401 { error = THTTPTransportError(error: .authentication) } else { error = THTTPTransportError(error: .invalidStatus(statusCode: httpResponse.statusCode)) } } // Allow factory to check if error != nil { do { try self.factory.validateResponse(httpResponse, data: data) } catch let validateError { error = validateError } } self.responseDataOffset = 0 if error != nil { self.responseData = Data() } else { self.responseData = data ?? Data() } completed(self, error) } }) } catch let taskError { error = taskError } if let error = error, task == nil { completed(self, error) } task?.resume() } public func flush() throws { let completed = DispatchSemaphore(value: 0) var internalError: Error? flush() { _, error in internalError = error completed.signal() } _ = completed.wait(timeout: DispatchTime.distantFuture) if let error = internalError { throw error } } } thrift-0.23.0/lib/swift/Sources/UnixSocket.swift0000664000175000017500000000535215165535636022101 0ustar00buildbuild00000000000000/* * 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. */ #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc import Dispatch #endif import Foundation private struct Sys { #if os(Linux) static let read = Glibc.read static let write = Glibc.write static let close = Glibc.close static let socket = Glibc.socket static let connect = Glibc.connect static let bind = Glibc.bind static let recv = Glibc.recv #else static let read = Darwin.read static let write = Darwin.write static let close = Darwin.close static let socket = Darwin.socket static let connect = Darwin.connect static let bind = Darwin.bind static let recv = Darwin.recv #endif } public class UnixSocket { public var fd: Int32 private var socketAddress: sockaddr_un public init(path: String) { socketAddress = sockaddr_un() socketAddress.sun_family = sa_family_t(AF_UNIX) let lengthOfPath = path.withCString { Int(strlen($0)) } guard lengthOfPath < MemoryLayout.size(ofValue: socketAddress.sun_path) else { fatalError() } _ = withUnsafeMutablePointer(to: &socketAddress.sun_path.0) { ptr in path.withCString { strncpy(ptr, $0, lengthOfPath) } } #if os(Linux) fd = Sys.socket(AF_UNIX, 1 /*SOCK_STREAM*/, 0); #else fd = Sys.socket(AF_UNIX, SOCK_STREAM, 0); #endif } public func connect() -> 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))) } } thrift-0.23.0/lib/swift/Sources/LinuxHelper.swift0000664000175000017500000000304015165535636022234 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import CoreFoundation #if os(Linux) /// Extensions for Linux for incomplete Foundation API's. /// swift-corelibs-foundation is not yet 1:1 with OSX/iOS Foundation extension UInt { public static func &(lhs: UInt, rhs: Int) -> UInt { let cast = UInt(bitPattern: rhs) return lhs & cast } } #else extension CFStreamPropertyKey { static let shouldCloseNativeSocket = CFStreamPropertyKey(kCFStreamPropertyShouldCloseNativeSocket) // Exists as Stream.PropertyKey.socketSecuritylevelKey but doesn't work with CFReadStreamSetProperty static let socketSecurityLevel = CFStreamPropertyKey(kCFStreamPropertySocketSecurityLevel) static let SSLSettings = CFStreamPropertyKey(kCFStreamPropertySSLSettings) } #endif thrift-0.23.0/lib/swift/Sources/TSerializable.swift0000664000175000017500000000710715165535636022537 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public protocol TSerializable { /// TType for instance static var thriftType: TType { get } /// Read TSerializable instance from Protocol static func read(from proto: TProtocol) throws -> Self /// Write TSerializable instance to Protocol func write(to proto: TProtocol) throws } extension TSerializable { public static func write(_ value: Self, to proto: TProtocol) throws { try value.write(to: proto) } /// convenience for member access public var thriftType: TType { return Self.thriftType } } /// Default read/write for primitave Thrift types: /// Bool, Int8 (byte), Int16, Int32, Int64, Double, String extension Bool : TSerializable { public static var thriftType: TType { return .bool } public static func read(from proto: TProtocol) throws -> Bool { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Int8 : TSerializable { public static var thriftType: TType { return .i8 } public static func read(from proto: TProtocol) throws -> Int8 { return try proto.read() as Int8 } public func write(to proto: TProtocol) throws { try proto.write(Int8(self)) } } extension Int16 : TSerializable { public static var thriftType: TType { return .i16 } public static func read(from proto: TProtocol) throws -> Int16 { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Int32 : TSerializable { public static var thriftType: TType { return .i32 } public static func read(from proto: TProtocol) throws -> Int32 { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Int64 : TSerializable { public static var thriftType: TType { return .i64 } public static func read(from proto: TProtocol) throws -> Int64 { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension Double : TSerializable { public static var thriftType: TType { return .double } public static func read(from proto: TProtocol) throws -> Double { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension String : TSerializable { public static var thriftType: TType { return .string } public static func read(from proto: TProtocol) throws -> String { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } extension UUID : TSerializable { public static var thriftType: TType { .uuid } public static func read(from proto: TProtocol) throws -> UUID { return try proto.read() } public func write(to proto: TProtocol) throws { try proto.write(self) } } thrift-0.23.0/lib/swift/Sources/TSocketServer.swift0000664000175000017500000001711215165535636022545 0ustar00buildbuild00000000000000/* * 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. */ #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) import Darwin #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) import Glibc import Dispatch #endif import Foundation import CoreFoundation public let TSocketServerClientConnectionFinished = "TSocketServerClientConnectionFinished" public let TSocketServerProcessorKey = "TSocketServerProcessor" public let TSocketServerTransportKey = "TSocketServerTransport" open class TSocketServer { var socketFileHandle: FileHandle var processingQueue = DispatchQueue(label: "TSocketServer.processing", qos: .background, attributes: .concurrent) let processor: Processor public init(port: Int, inProtocol: InProtocol.Type, outProtocol: OutProtocol.Type, processor: Processor) throws { self.processor = processor // create a socket var fd: Int32 = -1 #if os(Linux) let sock = CFSocketCreate(kCFAllocatorDefault, PF_INET, Int32(SOCK_STREAM.rawValue), Int32(IPPROTO_TCP), 0, nil, nil) #else let sock = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, 0, nil, nil) #endif if sock != nil { CFSocketSetSocketFlags(sock, CFSocketGetSocketFlags(sock) & ~CFOptionFlags(kCFSocketCloseOnInvalidate)) fd = CFSocketGetNative(sock) var yes = 1 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, UInt32(MemoryLayout.size)) let inPort = in_port_t(UInt16(truncatingIfNeeded: port).bigEndian) #if os(Linux) var addr = sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: inPort, sin_addr: in_addr(s_addr: in_addr_t(0)), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #else var addr = sockaddr_in(sin_len: UInt8(MemoryLayout.size), sin_family: sa_family_t(AF_INET), sin_port: inPort, sin_addr: in_addr(s_addr: in_addr_t(0)), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) #endif let ptr = withUnsafePointer(to: &addr) { return UnsafePointer(OpaquePointer($0)) } let address = Data(bytes: ptr, count: MemoryLayout.size) let cfaddr = address.withUnsafeBytes { CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, $0.bindMemory(to: UInt8.self).baseAddress!, address.count, kCFAllocatorNull) } if CFSocketSetAddress(sock, cfaddr) != CFSocketError.success { //kCFSocketSuccess { CFSocketInvalidate(sock) print("TSocketServer: Could not bind to address") throw TTransportError(error: .notOpen, message: "Could not bind to address") } } else { print("TSocketServer: No server socket") throw TTransportError(error: .notOpen, message: "Could not create socket") } // wrap it in a file handle so we can get messages from it socketFileHandle = FileHandle(fileDescriptor: fd, closeOnDealloc: true) // throw away our socket CFSocketInvalidate(sock) print("TSocketServer: Listening on TCP port \(port)") // tell socket to listen acceptConnectionInBackgroundAndNotify(handle: socketFileHandle) } public init(path: String, inProtocol: InProtocol.Type, outProtocol: OutProtocol.Type, processor: Processor) throws { self.processor = processor // create a socket let socket = UnixSocket(path: path) let fd = socket.fd if fd == -1 { print("TSocketServer: No server socket") throw TTransportError(error: .notOpen, message: "Could not create socket") } // wrap it in a file handle so we can get messages from it socketFileHandle = FileHandle(fileDescriptor: fd, closeOnDealloc: true) // register for notifications of accepted incoming connections _ = NotificationCenter.default.addObserver(forName: .NSFileHandleConnectionAccepted, object: nil, queue: nil) { [weak self] notification in guard let strongSelf = self else { return } guard let clientSocket = notification.userInfo?[NSFileHandleNotificationFileHandleItem] as? FileHandle else { return } strongSelf.connectionAccepted(clientSocket) } let bindRes = socket.bind() guard bindRes == 0 else { print("TServerSocket: bind failed") throw TTransportError(error: .notOpen, message: "Could not create socket") } let listenRes = listen(fd, 1024) guard listenRes == 0 else { print("TServerSocket: listen failed") throw TTransportError(error: .notOpen, message: "Could not create socket") } // tell socket to listen acceptConnectionInBackgroundAndNotify(handle: socketFileHandle) print("TSocketServer: Listening on unix path \(path)") } private func acceptConnectionInBackgroundAndNotify(handle: FileHandle) { DispatchQueue(label: "TSocketServer.connectionAccept").async { let acceptedFD = accept(handle.fileDescriptor, nil, nil) DispatchQueue.main.async { self.connectionAccepted(FileHandle(fileDescriptor: acceptedFD)) } } } func connectionAccepted(_ clientSocket: FileHandle) { // Now that we have a client connected, handle the request on queue processingQueue.async { self.handleClientConnection(clientSocket) } // continue accepting connections acceptConnectionInBackgroundAndNotify(handle: socketFileHandle) } open func createTransport(fileHandle: FileHandle) -> TTransport { return TFileHandleTransport(fileHandle: fileHandle) } func handleClientConnection(_ clientSocket: FileHandle) { let transport = createTransport(fileHandle: clientSocket) let inProtocol = InProtocol(on: transport) let outProtocol = OutProtocol(on: transport) do { while true { try processor.process(on: inProtocol, outProtocol: outProtocol) } } catch let error { print("Error processing request: \(error)") } DispatchQueue.main.async { NotificationCenter.default .post(name: Notification.Name(rawValue: TSocketServerClientConnectionFinished), object: nil, userInfo: [TSocketServerProcessorKey: self.processor, TSocketServerTransportKey: transport]) } } } public class TFramedSocketServer: TSocketServer { open override func createTransport(fileHandle: FileHandle) -> TTransport { return TFramedTransport(transport: super.createTransport(fileHandle: fileHandle)) } } thrift-0.23.0/lib/swift/Sources/TProtocolDecorator.swift0000664000175000017500000001130015165535636023563 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation class TProtocolDecorator: TProtocol { private let proto: TProtocol var transport: TTransport init(proto: TProtocol) { self.proto = proto self.transport = proto.transport } required init(on transport: TTransport) { fatalError("init(on:) has not been implemented") } func readMessageBegin() throws -> (String, TMessageType, Int32) { return try proto.readMessageBegin() } func readMessageEnd() throws { try proto.readMessageEnd() } func readStructBegin() throws -> String { return try proto.readStructBegin() } func readStructEnd() throws { try proto.readStructEnd() } func readFieldBegin() throws -> (String, TType, Int32) { return try proto.readFieldBegin() } func readFieldEnd() throws { try proto.readFieldEnd() } func readMapBegin() throws -> (TType, TType, Int32) { return try proto.readMapBegin() } func readMapEnd() throws { try proto.readMapEnd() } func readSetBegin() throws -> (TType, Int32) { return try proto.readSetBegin() } func readSetEnd() throws { try proto.readSetEnd() } func readListBegin() throws -> (TType, Int32) { return try proto.readListBegin() } func readListEnd() throws { try proto.readListEnd() } func read() throws -> String { return try proto.read() } func read() throws -> Bool { return try proto.read() } func read() throws -> UInt8 { return try proto.read() } func read() throws -> Int8 { return try proto.read() } func read() throws -> Int16 { return try proto.read() } func read() throws -> Int32 { return try proto.read() } func read() throws -> Int64 { return try proto.read() } func read() throws -> Double { return try proto.read() } func read() throws -> Data { return try proto.read() } func read() throws -> UUID { return try proto.read() } func writeMessageBegin(name: String, type messageType: TMessageType, sequenceID: Int32) throws { try proto.writeMessageBegin(name: name, type: messageType, sequenceID: sequenceID) } func writeMessageEnd() throws { try proto.writeMessageEnd() } func writeStructBegin(name: String) throws { try proto.writeStructBegin(name: name) } func writeStructEnd() throws { try proto.writeStructEnd() } func writeFieldBegin(name: String, type fieldType: TType, fieldID: Int32) throws { try proto.writeFieldBegin(name: name, type: fieldType, fieldID: fieldID) } func writeFieldStop() throws { try proto.writeFieldStop() } func writeFieldEnd() throws { try proto.writeFieldEnd() } func writeMapBegin(keyType: TType, valueType: TType, size: Int32) throws { try proto.writeMapBegin(keyType: keyType, valueType: valueType, size: size) } func writeMapEnd() throws { try proto.writeMapEnd() } func writeSetBegin(elementType: TType, size: Int32) throws { try proto.writeSetBegin(elementType: elementType, size: size) } func writeSetEnd() throws { try proto.writeSetEnd() } func writeListBegin(elementType: TType, size: Int32) throws { try proto.writeListBegin(elementType: elementType, size: size) } func writeListEnd() throws { try proto.writeListEnd() } func write(_ value: String) throws { try proto.write(value) } func write(_ value: Bool) throws { try proto.write(value) } func write(_ value: UInt8) throws { try proto.write(value) } func write(_ value: Int8) throws { try proto.write(value) } func write(_ value: Int16) throws { try proto.write(value) } func write(_ value: Int32) throws { try proto.write(value) } func write(_ value: Int64) throws { try proto.write(value) } func write(_ value: Double) throws { try proto.write(value) } func write(_ value: Data) throws { try proto.write(value) } func write(_ value: UUID) throws { try proto.write(value) } } thrift-0.23.0/lib/swift/Sources/TBase64Utils.swift0000664000175000017500000000770215165535636022177 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TBase64Utils { private static let EncodeTable: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" private static let NA: UInt8 = UInt8(255) private static let DecodeTable: [UInt8] = [ NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 62, NA, NA, NA, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NA, NA, NA, NA, NA, NA, NA, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NA, NA, NA, NA, NA, NA, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ] static func encode(src: [UInt8], srcOff: Int, len: Int, dst: inout [UInt8], dstOff: Int) { if (src.count == 0) { return } var index: UInt8 = 0 index = src[srcOff] >> 2 & 0x3F dst[dstOff] = EncodeTable[Int(index)].asciiValue! if (len == 3) { index = ((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F) dst[dstOff + 1] = EncodeTable[Int(index)].asciiValue! index = ((src[srcOff + 1] << 2) & 0x3C) | ((src[srcOff + 2] >> 6) & 0x03) dst[dstOff + 2] = EncodeTable[Int(index)].asciiValue! index = (src[srcOff + 2] & 0x3F) dst[dstOff + 3] = EncodeTable[Int(index)].asciiValue! } else if (len == 2) { index = ((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F) dst[dstOff + 1] = EncodeTable[Int(index)].asciiValue! index = ((src[srcOff + 1] << 2) & 0x3C) dst[dstOff + 2] = EncodeTable[Int(index)].asciiValue! } else { // len == 1 index = ((src[srcOff] << 4) & 0x30) dst[dstOff + 1] = EncodeTable[Int(index)].asciiValue! } } static func decode(src: [UInt8], srcOff: Int, len: Int, dst: inout [UInt8], dstOff: Int) { if (src.count == 0) { return } dst[dstOff] = (DecodeTable[Int(src[srcOff] & 0x0FF)] << 2) | (DecodeTable[Int(src[srcOff + 1] & 0x0FF)] >> 4) if (len > 2) { dst[dstOff + 1] = ((DecodeTable[Int(src[srcOff + 1] & 0x0FF)] << 4) & 0xF0) | (DecodeTable[Int(src[srcOff + 2] & 0x0FF)] >> 2) if (len > 3) { dst[dstOff + 2] = ((DecodeTable[Int(src[srcOff + 2] & 0x0FF)] << 6) & 0xC0) | (DecodeTable[Int(src[srcOff + 3] & 0x0FF)]) } } } } thrift-0.23.0/lib/swift/Sources/TFileHandleTransport.swift0000664000175000017500000000314015165535636024032 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TFileHandleTransport: TTransport { var inputFileHandle: FileHandle var outputFileHandle: FileHandle public init(inputFileHandle: FileHandle, outputFileHandle: FileHandle) { self.inputFileHandle = inputFileHandle self.outputFileHandle = outputFileHandle } public convenience init(fileHandle: FileHandle) { self.init(inputFileHandle: fileHandle, outputFileHandle: fileHandle) } public func read(size: Int) throws -> Data { var data = Data() while data.count < size { let read = inputFileHandle.readData(ofLength: size - data.count) data.append(read) if read.count == 0 { break } } return data } public func write(data: Data) throws { outputFileHandle.write(data) } public func flush() throws { return } } thrift-0.23.0/lib/swift/Sources/TMap.swift0000664000175000017500000001220615165535636020642 0ustar00buildbuild00000000000000/* * 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. */ public struct TMap: Collection, ExpressibleByDictionaryLiteral, Hashable, TSerializable { public typealias Storage = Dictionary public typealias Element = Storage.Element public typealias Index = Storage.Index public typealias IndexDistance = Int public typealias Indices = Storage.Indices public typealias SubSequence = Storage.SubSequence internal var storage = Storage() /// Mark: Be Like Dictionary public func indexForKey(_ key: Key) -> Index? { return storage.index(forKey: key) } public mutating func updateValue(_ value: Value, forKey key: Key) -> Value? { return storage.updateValue(value, forKey: key) } public mutating func removeValueForKey(_ key: Key) -> Value? { return storage.removeValue(forKey: key) } public init(minimumCapacity: Int) { storage = Storage(minimumCapacity: minimumCapacity) } /// init from Dictionary public init(_ dict: [Key: Value]) { storage = dict } /// read only access to storage if needed as Dictionary public var dictionary: [Key: Value] { return storage } public subscript (key: Key) -> Value? { get { return storage[key] } set { storage[key] = newValue } } /// Mark: Collection public var indices: Indices { return storage.indices } public func distance(from start: Index, to end: Index) -> IndexDistance { return storage.distance(from: start, to: end) } public func index(_ i: Index, offsetBy n: IndexDistance) -> Index { return storage.index(i, offsetBy: n) } public func index(_ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index) -> Index? { return storage.index(i, offsetBy: n, limitedBy: limit) } public subscript(position: Index) -> Element { return storage[position] } /// Mark: IndexableBase public var startIndex: Index { return storage.startIndex } public var endIndex: Index { return storage.endIndex } public func index(after i: Index) -> Index { return storage.index(after: i) } public func formIndex(after i: inout Index) { storage.formIndex(after: &i) } public subscript(bounds: Range) -> SubSequence { return storage[bounds] } /// Mark: DictionaryLiteralConvertible public init(dictionaryLiteral elements: (Key, Value)...) { storage = Storage() for (key, value) in elements { storage[key] = value } } /// Mark: Hashable public func hash(into hasher: inout Hasher) { hasher.combine(storage) } /// Mark: TSerializable public static var thriftType : TType { return .map } public init() { storage = Storage() } public static func read(from proto: TProtocol) throws -> TMap { let (keyType, valueType, size) = try proto.readMapBegin() if size > 0 { if keyType != Key.thriftType { throw TProtocolError(error: .invalidData, message: "Unexpected TMap Key Type", extendedError: .unexpectedType(type: keyType)) } if valueType != Value.thriftType { throw TProtocolError(error: .invalidData, message: "Unexpected TMap Value Type", extendedError: .unexpectedType(type: valueType)) } } var map = TMap() for _ in 0..(lhs: TMap, rhs: TMap) -> Bool { if lhs.count != rhs.count { return false } return lhs.storage == rhs.storage } thrift-0.23.0/lib/swift/Sources/TStreamTransport.swift0000664000175000017500000001042715165535636023300 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation import CoreFoundation #if !swift(>=4.2) // Swift 3/4 compatibility fileprivate extension RunLoopMode { static let `default` = defaultRunLoopMode } #endif #if os(Linux) /// Currently unavailable in Linux /// Remove comments and build to fix /// Currently kConstants for CFSockets don't exist in linux and not all have been moved /// to property structs yet #else // Must inherit NSObject for NSStreamDelegate conformance public class TStreamTransport : NSObject, TTransport { public var input: InputStream? = nil public var output: OutputStream? = nil public init(inputStream: InputStream?, outputStream: OutputStream?) { input = inputStream output = outputStream } public convenience init(inputStream: InputStream?) { self.init(inputStream: inputStream, outputStream: nil) } public convenience init(outputStream: OutputStream?) { self.init(inputStream: nil, outputStream: outputStream) } deinit { close() } public func readAll(size: Int) throws -> Data { guard let input = input else { throw TTransportError(error: .unknown) } var read = Data() while read.count < size { var buffer = Array(repeating: 0, count: size - read.count) let bytesRead = buffer.withUnsafeMutableBufferPointer { bufferPtr in return input.read(bufferPtr.baseAddress!, maxLength: size - read.count) } if bytesRead <= 0 { throw TTransportError(error: .notOpen) } read.append(Data(buffer)) } return read } public func read(size: Int) throws -> Data { guard let input = input else { throw TTransportError(error: .unknown) } var read = Data() while read.count < size { var buffer = Array(repeating: 0, count: size - read.count) let bytesRead = buffer.withUnsafeMutableBufferPointer { input.read($0.baseAddress!, maxLength: size - read.count) } if bytesRead <= 0 { break } read.append(Data(buffer)) } return read } public func write(data: Data) throws { guard let output = output else { throw TTransportError(error: .unknown) } var bytesWritten = 0 while bytesWritten < data.count { bytesWritten = data.withUnsafeBytes { output.write($0.bindMemory(to: UInt8.self).baseAddress!, maxLength: data.count) } if bytesWritten == -1 { throw TTransportError(error: .notOpen) } else if bytesWritten == 0 { throw TTransportError(error: .endOfFile) } } } public func flush() throws { return } public func close() { if input != nil { // Close and reset inputstream if let cf: CFReadStream = input { CFReadStreamSetProperty(cf, .shouldCloseNativeSocket, kCFBooleanTrue) } input?.delegate = nil input?.close() input?.remove(from: .current, forMode: .default) input = nil } if output != nil { // Close and reset output stream if let cf: CFWriteStream = output { CFWriteStreamSetProperty(cf, .shouldCloseNativeSocket, kCFBooleanTrue) } output?.delegate = nil output?.close() output?.remove(from: .current, forMode: .default) output = nil } } } #endif thrift-0.23.0/lib/swift/Sources/TMemoryBufferTransport.swift0000664000175000017500000000426315165535636024450 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public class TMemoryBufferTransport : TTransport { public private(set) var readBuffer = Data() public private(set) var writeBuffer = Data() public private(set) var position = 0 public var bytesRemainingInBuffer: Int { return readBuffer.count - position } public func consumeBuffer(size: Int) { position += size } public func clear() { readBuffer = Data() writeBuffer = Data() } private var flushHandler: ((TMemoryBufferTransport, Data) -> ())? public init(flushHandler: ((TMemoryBufferTransport, Data) -> ())? = nil) { self.flushHandler = flushHandler } public convenience init(readBuffer: Data, flushHandler: ((TMemoryBufferTransport, Data) -> ())? = nil) { self.init() self.readBuffer = readBuffer } public func reset(readBuffer: Data = Data(), writeBuffer: Data = Data()) { self.readBuffer = readBuffer self.writeBuffer = writeBuffer } public func read(size: Int) throws -> Data { let amountToRead = min(bytesRemainingInBuffer, size) if amountToRead > 0 { let ret = readBuffer.subdata(in: Range(uncheckedBounds: (lower: position, upper: position + amountToRead))) position += ret.count return ret } return Data() } public func write(data: Data) throws { writeBuffer.append(data) } public func flush() throws { flushHandler?(self, writeBuffer) } } thrift-0.23.0/lib/swift/Sources/TTransport.swift0000664000175000017500000000341515165535636022123 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public protocol TTransport { // Required func read(size: Int) throws -> Data func write(data: Data) throws func flush() throws // Optional (default provided) func readAll(size: Int) throws -> Data func isOpen() throws -> Bool func open() throws func close() throws } public extension TTransport { func isOpen() throws -> Bool { return true } func open() throws { } func close() throws { } func readAll(size: Int) throws -> Data { var buff = Data() var have = 0 while have < size { let chunk = try self.read(size: size - have) have += chunk.count buff.append(chunk) if chunk.count == 0 { throw TTransportError(error: .endOfFile) } } return buff } } public protocol TAsyncTransport : TTransport { // Factory func flush(_ completion: @escaping (TAsyncTransport, Error?) ->()) } public protocol TAsyncTransportFactory { associatedtype Transport : TAsyncTransport func newTransport() -> Transport } thrift-0.23.0/lib/swift/Sources/TProcessor.swift0000664000175000017500000000157315165535636022111 0ustar00buildbuild00000000000000/* * 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. */ public protocol TProcessor { func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws } thrift-0.23.0/lib/swift/Makefile.in0000644000175000017500000006066215170007167017341 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/swift ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . EXTRA_DIST = \ Package.swift \ Sources \ Tests \ FuzzTesting \ README.md MAINTAINERCLEANFILES = \ Makefile \ Makefile.in all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/swift/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/swift/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-exec-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile all-local: swift build --configuration release install-exec-hook: swift install clean-local: swift package clean rm -rf .build rm -rf FuzzTesting/.build rm -rf FuzzTesting/Sources/Fuzz/* precross: swift build check-local: swift test FuzzTesting/Sources/Fuzz: mkdir -p FuzzTesting/Sources/Fuzz fuzz-gen: FuzzTesting/Sources/Fuzz $(top_builddir)/compiler/cpp/thrift --gen swift -r -out FuzzTesting/Sources/Fuzz $(top_srcdir)/test/FuzzTest.thrift fuzz-local: fuzz-gen cd FuzzTesting && swift build --configuration release ${SWIFTFLAGS} fuzz: all-local fuzz-local @echo "Built fuzzers successfully" distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/swift/Makefile.am0000664000175000017500000000306615165535636017340 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . all-local: swift build --configuration release install-exec-hook: swift install clean-local: swift package clean rm -rf .build rm -rf FuzzTesting/.build rm -rf FuzzTesting/Sources/Fuzz/* precross: swift build check-local: swift test FuzzTesting/Sources/Fuzz: mkdir -p FuzzTesting/Sources/Fuzz fuzz-gen: FuzzTesting/Sources/Fuzz $(top_builddir)/compiler/cpp/thrift --gen swift -r -out FuzzTesting/Sources/Fuzz $(top_srcdir)/test/FuzzTest.thrift fuzz-local: fuzz-gen cd FuzzTesting && swift build --configuration release ${SWIFTFLAGS} fuzz: all-local fuzz-local @echo "Built fuzzers successfully" distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ Package.swift \ Sources \ Tests \ FuzzTesting \ README.md MAINTAINERCLEANFILES = \ Makefile \ Makefile.in thrift-0.23.0/lib/perl/0000755000175000017500000000000015170007201015055 5ustar00buildbuild00000000000000thrift-0.23.0/lib/perl/test.pl0000664000175000017500000000152215165535636016421 0ustar00buildbuild00000000000000# # 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. # use strict; use warnings; use Test::Harness; runtests(@ARGV); thrift-0.23.0/lib/perl/Makefile.PL0000664000175000017500000000347315165535636017066 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( ABSTRACT => 'Apache Thrift is a software framework for scalable cross-language services development.', AUTHOR => 'Apache Thrift ', LICENSE => 'apache_2_0', MIN_PERL_VERSION => '5.010000', NAME => 'Thrift', NEEDS_LINKING => 0, PREREQ_PM => { 'Bit::Vector' => 0, 'Class::Accessor' => 0 }, # SIGN => 1, TEST_REQUIRES => { 'Test::Exception' => 0, }, VERSION_FROM => 'lib/Thrift.pm' ); # THRIFT-4691 package MY; # so that "SUPER" works right sub test { # Adds gen-perl and gen-perl2 to the test execution as include paths # Could not find anything in MakeMaker that would do this... my @result; for (@result = shift->SUPER::test(@_)) { s/\$\(TEST_FILES\)/-Igen-perl -Igen-perl2 \$(TEST_FILES)/ig; } @result; } thrift-0.23.0/lib/perl/coding_standards.md0000664000175000017500000000025215165535636020734 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md). Additional perl coding standards can be found in [perlstyle](http://perldoc.perl.org/perlstyle.html). thrift-0.23.0/lib/perl/t/0000755000175000017500000000000015170007201015320 5ustar00buildbuild00000000000000thrift-0.23.0/lib/perl/t/processor.t0000664000175000017500000000554015165535636017560 0ustar00buildbuild00000000000000# # 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. # use Test::More tests => 2; use strict; use warnings; use Thrift::BinaryProtocol; use Thrift::MemoryBuffer; use Thrift::MessageType; use ThriftTest::ThriftTest; use ThriftTest::Types; use Data::Dumper; my $buffer = Thrift::MemoryBuffer->new(1024); my $protocol = Thrift::BinaryProtocol->new($buffer); my $client = ThriftTest::ThriftTestClient->new($protocol); $buffer->open(); $client->send_testString("foo"); $client->{seqid}++; $client->send_testString("bar"); my $client_command_binary = $buffer->getBuffer; $buffer->resetBuffer; # Process by server my $server_output_binary; { my $protocol_factory = Thrift::BinaryProtocolFactory->new(); my $input_buffer = Thrift::MemoryBuffer->new(); $input_buffer->write($client_command_binary); my $input_protocol = $protocol_factory->getProtocol($input_buffer); my $output_buffer = Thrift::MemoryBuffer->new(); my $output_protocol = $protocol_factory->getProtocol($output_buffer); my $processor = ThriftTest::ThriftTestProcessor->new( My::ThriftTest->new() ); my $result = $processor->process($input_protocol, $output_protocol); print "process resulted in $result\n"; $result = $processor->process($input_protocol, $output_protocol); print "process resulted in $result\n"; $server_output_binary = $output_buffer->getBuffer(); } $buffer->write($server_output_binary); foreach my $val (("got foo","got bar")){ my ($function_name, $message_type, $sequence_id); $protocol->readMessageBegin(\$function_name, \$message_type, \$sequence_id); print " $function_name, $message_type, $sequence_id\n"; if ($message_type == Thrift::TMessageType::EXCEPTION) { die; } my $result = ThriftTest::ThriftTest_testString_result->new(); $result->read($protocol); $protocol->readMessageEnd(); is($result->success(),$val); } package My::ThriftTest; use strict; use warnings; use Data::Dumper; sub new { my $class = shift; return bless {}, $class; } sub testString { my ($self, $string) = @_; print __PACKAGE__ . "->testString()\n"; return "got ".$string; } thrift-0.23.0/lib/perl/t/memory_buffer.t0000664000175000017500000000311315165535636020374 0ustar00buildbuild00000000000000# # 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. # use Test::More tests => 7; use Test::Exception; use strict; use warnings; use Data::Dumper; use Thrift::BinaryProtocol; use Thrift::MemoryBuffer; use ThriftTest::Types; my $transport = Thrift::MemoryBuffer->new(); my $protocol = Thrift::BinaryProtocol->new($transport); throws_ok { $protocol->readByte } 'Thrift::TTransportException'; my $a = ThriftTest::Xtruct->new(); $a->i32_thing(10); $a->i64_thing(30); $a->string_thing('Hello, world!'); $a->write($protocol); my $b = ThriftTest::Xtruct->new(); $b->read($protocol); is($b->i32_thing, $a->i32_thing); is($b->i64_thing, $a->i64_thing); is($b->string_thing, $a->string_thing); $b->write($protocol); my $c = ThriftTest::Xtruct->new(); $c->read($protocol); is($c->i32_thing, $a->i32_thing); is($c->i64_thing, $a->i64_thing); is($c->string_thing, $a->string_thing); thrift-0.23.0/lib/perl/t/multiplex.t0000664000175000017500000001175515165535636017571 0ustar00buildbuild00000000000000# # 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. # use Test::More tests => 6; use strict; use warnings; use Thrift::BinaryProtocol; use Thrift::FramedTransport; use Thrift::MemoryBuffer; use Thrift::MessageType; use Thrift::MultiplexedProcessor; use Thrift::Server; use Thrift::Socket; use BenchmarkService; use Aggr; use constant NAME_BENCHMARKSERVICE => 'BenchmarkService'; use constant NAME_AGGR => 'Aggr'; my $buffer = Thrift::MemoryBuffer->new(1024); my $aggr_protocol = Thrift::MultiplexedProtocol->new(Thrift::BinaryProtocol->new($buffer), NAME_AGGR); my $aggr_client = AggrClient->new($aggr_protocol); my $benchmark_protocol = Thrift::MultiplexedProtocol->new(Thrift::BinaryProtocol->new($buffer), NAME_BENCHMARKSERVICE); my $benchmark_client = BenchmarkServiceClient->new($benchmark_protocol); $buffer->open(); for(my $i = 1; $i <= 5; $i++) { $aggr_client->send_addValue($i); $aggr_client->{seqid}++; } $aggr_client->send_getValues(); for(my $i = 1; $i <= 5; $i++) { $benchmark_client->send_fibonacci($i); $benchmark_client->{seqid}++; } $benchmark_client->{seqid}--; my $client_command_binary = $buffer->getBuffer; $buffer->resetBuffer; # Process by server my $server_output_binary; { my $benchmark_handler = My::BenchmarkService->new(); my $benchmark_processor = BenchmarkServiceProcessor->new($benchmark_handler); my $aggr_handler = My::Aggr->new(); my $aggr_processor = AggrProcessor->new($aggr_handler); my $protocol_factory = Thrift::BinaryProtocolFactory->new(); my $input_buffer = Thrift::MemoryBuffer->new(); $input_buffer->write($client_command_binary); my $input_protocol = $protocol_factory->getProtocol($input_buffer); my $output_buffer = Thrift::MemoryBuffer->new(); my $output_protocol = $protocol_factory->getProtocol($output_buffer); my $processor = Thrift::MultiplexedProcessor->new(); $processor->registerProcessor(NAME_BENCHMARKSERVICE, $benchmark_processor); $processor->registerProcessor(NAME_AGGR, $aggr_processor); my $result; for(my $i = 1; $i <= 11; $i++) { $result = $processor->process($input_protocol, $output_protocol); print "process resulted in $result\n"; } $server_output_binary = $output_buffer->getBuffer(); } $buffer->write($server_output_binary); for(my $i = 1; $i <= 5; $i++) { my ($function_name, $message_type, $sequence_id); $aggr_protocol->readMessageBegin(\$function_name, \$message_type, \$sequence_id); if ($message_type == Thrift::TMessageType::EXCEPTION) { die; } my $aggr_result = Aggr_addValue_result->new(); $aggr_result->read($aggr_protocol); $aggr_protocol->readMessageEnd(); } my ($function_name, $message_type, $sequence_id); $aggr_protocol->readMessageBegin(\$function_name, \$message_type, \$sequence_id); if ($message_type == Thrift::TMessageType::EXCEPTION) { die; } my $aggr_result = Aggr_getValues_result->new(); $aggr_result->read($aggr_protocol); $aggr_protocol->readMessageEnd(); is_deeply($aggr_result->success(), [1,2,3,4,5]); foreach my $val((1,2,3,5,8)) { my ($function_name, $message_type, $sequence_id); $benchmark_protocol->readMessageBegin(\$function_name, \$message_type, \$sequence_id); if ($message_type == Thrift::TMessageType::EXCEPTION) { die; } my $benchmark_result = BenchmarkService_fibonacci_result->new(); $benchmark_result->read($benchmark_protocol); $benchmark_protocol->readMessageEnd(); is($benchmark_result->success(), $val); } package My::Aggr; use base qw(AggrIf); use strict; use warnings; sub new { my $classname = shift; my $self = {}; $self->{values} = (); return bless($self,$classname); } sub addValue{ my $self = shift; my $value = shift; push (@{$self->{values}}, $value); } sub getValues{ my $self = shift; return $self->{values}; } package My::BenchmarkService; use base qw(BenchmarkServiceIf); use strict; use warnings; sub new { my $class = shift; return bless {}, $class; } sub fibonacci { my ($self, $n) = @_; my $prev = 0; my $next; my $result = 1; while ($n > 0) { $next = $result + $prev; $prev = $result; $result = $next; --$n; } return $result; } thrift-0.23.0/lib/perl/t/Makefile.in0000644000175000017500000004236315170007167017410 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/perl/t ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = memory_buffer.t processor.t multiplex.t all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/perl/t/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/perl/t/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/perl/t/Makefile.am0000664000175000017500000000156515165535636017413 0ustar00buildbuild00000000000000# # 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. # distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = memory_buffer.t processor.t multiplex.t thrift-0.23.0/lib/perl/build-cpan-dist.sh0000775000175000017500000000236315165535636020427 0ustar00buildbuild00000000000000#!/bin/bash # # This script is intended to be used after tagging the repository and updating # the version files for a release. It will create a CPAN archive. Run this # from inside a docker image like ubuntu-focal. # set -e rm -f MANIFEST rm -rf Thrift-* # setup cpan without a prompt echo | cpan cpan install HTTP::Date Log::Log4perl cpan install CPAN cpan install CPAN::Meta ExtUtils::MakeMaker JSON::PP # cpan install Module::Signature perl Makefile.PL rm MYMETA.yml make manifest make dist # # We unpack the archive so we can add version metadata for CPAN # so that it properly indexes Thrift and remove unnecessary files. # echo '-----------------------------------------------------------' set -x DISTFILE=$(ls Thrift*.gz) NEWFILE=${DISTFILE/t-v/t-} if [[ "$DISTFILE" != "$NEWFILE" ]]; then mv $DISTFILE $NEWFILE DISTFILE="$NEWFILE" fi tar xzf $DISTFILE rm $DISTFILE DISTDIR=$(ls -d Thrift*) # cpan doesn't like "Thrift-v0.nn.0 as a directory name # needs to be Thrift-0.nn.0 NEWDIR=${DISTDIR/t-v/t-} if [[ "$DISTDIR" != "$NEWDIR" ]]; then mv $DISTDIR $NEWDIR DISTDIR="$NEWDIR" fi cd $DISTDIR cp -p ../Makefile.PL . cp -pr ../gen-perl . cp -pr ../gen-perl2 . perl ../tools/FixupDist.pl cd .. tar cvzf $DISTFILE $DISTDIR rm -r $DISTDIR thrift-0.23.0/lib/perl/MANIFEST.SKIP0000664000175000017500000000026615165535636017007 0ustar00buildbuild00000000000000blib/.*$ build-cpan-dist.sh FixupDist.pl MANIFEST.bak MANIFEST.SKIP MYMETA.json Makefile Makefile.am Makefile.in pm_to_blib t/Makefile t/Makefile.am t/Makefile.in tools/FixupDist.pl thrift-0.23.0/lib/perl/README.md0000664000175000017500000001050115165535636016361 0ustar00buildbuild00000000000000Thrift Perl Software Library # Summary Apache Thrift is a software framework for scalable cross-language services development. It combines a software stack with a code generation engine to build services that work efficiently and seamlessly between many programming languages. A language-neutral IDL is used to generate functioning client libraries and server-side handling frameworks. # License Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. # For More Information See the [Apache Thrift Web Site](http://thrift.apache.org/) for more information. # Using Thrift with Perl Thrift requires Perl >= 5.10.0 Unexpected exceptions in a service handler are converted to TApplicationException with type INTERNAL ERROR and the string of the exception is delivered as the message. On the client side, exceptions are thrown with die, so be sure to wrap eval{} statments around any code that contains exceptions. Please see tutoral and test dirs for examples. The Perl ForkingServer ignores SIGCHLD allowing the forks to be reaped by the operating system naturally when they exit. This means one cannot use a custom SIGCHLD handler in the consuming perl implementation that calls serve(). It is acceptable to use a custom SIGCHLD handler within a thrift handler implementation as the ForkingServer resets the forked child process to use default signal handling. # Dependencies The following modules are not provided by Perl 5.10.0 but are required to use Thrift. ## Runtime * Bit::Vector * Class::Accessor ## Test This is only required when running tests: * Test::Exception ### HttpClient Transport These are only required if using Thrift::HttpClient: * HTTP::Request * IO::String * LWP::UserAgent ### SSL/TLS These are only required if using Thrift::SSLSocket or Thrift::SSLServerSocket: * IO::Socket::SSL # Breaking Changes ## 0.10.0 The socket classes were refactored in 0.10.0 so that there is one package per file. This means `use Socket;` no longer defines SSLSocket. You can use this technique to make your application run against 0.10.0 as well as earlier versions: `eval { require Thrift::SSLSocket; } or do { require Thrift::Socket; }` ## 0.11.0 * Namespaces of packages that were not scoped within Thrift have been fixed. ** TApplicationException is now Thrift::TApplicationException ** TException is now Thrift::TException ** TMessageType is now Thrift::TMessageType ** TProtocolException is now Thrift::TProtocolException ** TProtocolFactory is now Thrift::TProtocolFactory ** TTransportException is now Thrift::TTransportException ** TType is now Thrift::TType If you need a single version of your code to work with both older and newer thrift namespace changes, you can make the new, correct namespaces behave like the old ones in your files with this technique to create an alias, which will allow you code to run against either version of the perl runtime for thrift: `BEGIN {*TType:: = *Thrift::TType::}` * Packages found in Thrift.pm were moved into the Thrift/ directory in separate files: ** Thrift::TApplicationException is now in Thrift/Exception.pm ** Thrift::TException is now in Thrift/Exception.pm ** Thrift::TMessageType is now in Thrift/MessageType.pm ** Thrift::TType is now in Thrift/Type.pm If you need to modify your code to work against both older or newer thrift versions, you can deal with these changes in a backwards compatible way in your projects using eval: `eval { require Thrift::Exception; require Thrift::MessageType; require Thrift::Type; } or do { require Thrift; }` # Deprecations ## 0.11.0 Thrift::HttpClient setRecvTimeout() and setSendTimeout() are deprecated. Use setTimeout instead. thrift-0.23.0/lib/perl/lib/0000755000175000017500000000000015170007201015623 5ustar00buildbuild00000000000000thrift-0.23.0/lib/perl/lib/Thrift.pm0000664000175000017500000000217015170007142017427 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; # # Versioning # # Every perl module for Thrift will have the same version # declaration. For a production build, change it below to # something like "v0.11.0" and all of the packages in all # of the files will pick it up from here. # package Thrift; use version 0.77; our $VERSION = version->declare("v0.23.0"); 1; thrift-0.23.0/lib/perl/lib/Thrift/0000755000175000017500000000000015170007201017063 5ustar00buildbuild00000000000000thrift-0.23.0/lib/perl/lib/Thrift/MultiplexedProcessor.pm0000664000175000017500000000743315165535636023654 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::MessageType; use Thrift::MultiplexedProtocol; use Thrift::Protocol; use Thrift::ProtocolDecorator; package Thrift::StoredMessageProtocol; use base qw(Thrift::ProtocolDecorator); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $protocol = shift; my $fname = shift; my $mtype = shift; my $rseqid = shift; my $self = $classname->SUPER::new($protocol); $self->{fname} = $fname; $self->{mtype} = $mtype; $self->{rseqid} = $rseqid; return bless($self,$classname); } sub readMessageBegin { my $self = shift; my $name = shift; my $type = shift; my $seqid = shift; $$name = $self->{fname}; $$type = $self->{mtype}; $$seqid = $self->{rseqid}; } package Thrift::MultiplexedProcessor; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = {}; $self->{serviceProcessorMap} = {}; $self->{defaultProcessor} = undef; return bless($self,$classname); } sub defaultProcessor { my $self = shift; my $processor = shift; $self->{defaultProcessor} = $processor; } sub registerProcessor { my $self = shift; my $serviceName = shift; my $processor = shift; $self->{serviceProcessorMap}->{$serviceName} = $processor; } sub process { my $self = shift; my $input = shift; my $output = shift; # # Use the actual underlying protocol (e.g. BinaryProtocol) to read the # message header. This pulls the message "off the wire", which we'll # deal with at the end of this method. # my ($fname, $mtype, $rseqid); $input->readMessageBegin(\$fname, \$mtype, \$rseqid); if ($mtype ne Thrift::TMessageType::CALL && $mtype ne Thrift::TMessageType::ONEWAY) { die Thrift::TException->new('This should not have happened!?'); } # Extract the service name and the new Message name. if (index($fname, Thrift::MultiplexedProtocol::SEPARATOR) == -1) { if (defined $self->{defaultProcessor}) { return $self->{defaultProcessor}->process( Thrift::StoredMessageProtocol->new($input, $fname, $mtype, $rseqid), $output ); } else { die Thrift::TException->new("Service name not found in message name: {$fname} and no default processor defined. Did you " . 'forget to use a MultiplexProtocol in your client?'); } } (my $serviceName, my $messageName) = split(':', $fname, 2); if (!exists($self->{serviceProcessorMap}->{$serviceName})) { die Thrift::TException->new("Service name not found: {$serviceName}. Did you forget " . 'to call registerProcessor()?'); } # Dispatch processing to the stored processor my $processor = $self->{serviceProcessorMap}->{$serviceName}; return $processor->process( Thrift::StoredMessageProtocol->new($input, $messageName, $mtype, $rseqid), $output ); } 1; thrift-0.23.0/lib/perl/lib/Thrift/Exception.pm0000664000175000017500000000760515165535636021417 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Type; package Thrift::TException; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use overload '""' => sub { return sprintf '%s error: %s (code %s)', ref( $_[0] ), ( $_[0]->{message} || 'empty message' ), ( defined $_[0]->{code} ? $_[0]->{code} : 'undefined' ); }; sub new { my $classname = shift; my $self = {message => shift, code => shift || 0}; return bless($self,$classname); } package Thrift::TApplicationException; use parent -norequire, 'Thrift::TException'; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use constant UNKNOWN => 0; use constant UNKNOWN_METHOD => 1; use constant INVALID_MESSAGE_TYPE => 2; use constant WRONG_METHOD_NAME => 3; use constant BAD_SEQUENCE_ID => 4; use constant MISSING_RESULT => 5; use constant INTERNAL_ERROR => 6; use constant PROTOCOL_ERROR => 7; use constant INVALID_TRANSFORM => 8; use constant INVALID_PROTOCOL => 9; use constant UNSUPPORTED_CLIENT_TYPE => 10; sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); return bless($self,$classname); } sub read { my $self = shift; my $input = shift; my $xfer = 0; my $fname = undef; my $ftype = 0; my $fid = 0; $xfer += $input->readStructBegin(\$fname); while (1) { $xfer += $input->readFieldBegin(\$fname, \$ftype, \$fid); if ($ftype == Thrift::TType::STOP) { last; next; } SWITCH: for($fid) { /1/ && do{ if ($ftype == Thrift::TType::STRING) { $xfer += $input->readString(\$self->{message}); } else { $xfer += $input->skip($ftype); } last; }; /2/ && do{ if ($ftype == Thrift::TType::I32) { $xfer += $input->readI32(\$self->{code}); } else { $xfer += $input->skip($ftype); } last; }; $xfer += $input->skip($ftype); } $xfer += $input->readFieldEnd(); } $xfer += $input->readStructEnd(); return $xfer; } sub write { my $self = shift; my $output = shift; my $xfer = 0; $xfer += $output->writeStructBegin('TApplicationException'); if ($self->getMessage()) { $xfer += $output->writeFieldBegin('message', Thrift::TType::STRING, 1); $xfer += $output->writeString($self->getMessage()); $xfer += $output->writeFieldEnd(); } if ($self->getCode()) { $xfer += $output->writeFieldBegin('type', Thrift::TType::I32, 2); $xfer += $output->writeI32($self->getCode()); $xfer += $output->writeFieldEnd(); } $xfer += $output->writeFieldStop(); $xfer += $output->writeStructEnd(); return $xfer; } sub getMessage { my $self = shift; return $self->{message}; } sub getCode { my $self = shift; return $self->{code}; } 1; thrift-0.23.0/lib/perl/lib/Thrift/FramedTransport.pm0000664000175000017500000000767015165535636022576 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Transport; # # Framed transport. Writes and reads data in chunks that are stamped with # their length. # # @package thrift.transport # package Thrift::FramedTransport; use base('Thrift::Transport'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $transport = shift; my $read = shift || 1; my $write = shift || 1; my $self = { transport => $transport, read => $read, write => $write, wBuf => '', rBuf => '', }; return bless($self,$classname); } sub isOpen { my $self = shift; return $self->{transport}->isOpen(); } sub open { my $self = shift; $self->{transport}->open(); } sub close { my $self = shift; if (defined $self->{transport}) { $self->{transport}->close(); } } # # Reads from the buffer. When more data is required reads another entire # chunk and serves future reads out of that. # # @param int $len How much data # sub read { my $self = shift; my $len = shift; if (!$self->{read}) { return $self->{transport}->read($len); } if (length($self->{rBuf}) == 0) { $self->_readFrame(); } # Just return full buff if ($len > length($self->{rBuf})) { my $out = $self->{rBuf}; $self->{rBuf} = ''; return $out; } # Return substr my $out = substr($self->{rBuf}, 0, $len); $self->{rBuf} = substr($self->{rBuf}, $len); return $out; } # # Reads a chunk of data into the internal read buffer. # (private) sub _readFrame { my $self = shift; my $buf = $self->{transport}->readAll(4); my @val = unpack('N', $buf); my $sz = $val[0]; $self->{rBuf} = $self->{transport}->readAll($sz); } # # Writes some data to the pending output buffer. # # @param string $buf The data # @param int $len Limit of bytes to write # sub write { my $self = shift; my $buf = shift; my $len = shift; unless($self->{write}) { return $self->{transport}->write($buf, $len); } if ( defined $len && $len < length($buf)) { $buf = substr($buf, 0, $len); } $self->{wBuf} .= $buf; } # # Writes the output buffer to the stream in the format of a 4-byte length # followed by the actual data. # sub flush { my $self = shift; unless ($self->{write}) { return $self->{transport}->flush(); } my $out = pack('N', length($self->{wBuf})); $out .= $self->{wBuf}; $self->{transport}->write($out); $self->{transport}->flush(); $self->{wBuf} = ''; } # # FramedTransport factory creates framed transport objects from transports # package Thrift::FramedTransportFactory; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = {}; return bless($self, $classname); } # # Build a framed transport from the base transport # # @return Thrift::FramedTransport transport # sub getTransport { my $self = shift; my $trans = shift; my $buffered = Thrift::FramedTransport->new($trans); return $buffered; } 1; thrift-0.23.0/lib/perl/lib/Thrift/MemoryBuffer.pm0000664000175000017500000000525515165535636022062 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Transport; package Thrift::MemoryBuffer; use base('Thrift::Transport'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $bufferSize= shift || 1024; my $self = { buffer => '', bufferSize => $bufferSize, wPos => 0, rPos => 0, }; return bless($self,$classname); } sub isOpen { return 1; } sub open { } sub close { } sub peek { my $self = shift; return($self->{rPos} < $self->{wPos}); } sub getBuffer { my $self = shift; return $self->{buffer}; } sub resetBuffer { my $self = shift; my $new_buffer = shift || ''; $self->{buffer} = $new_buffer; $self->{bufferSize} = length($new_buffer); $self->{wPos} = length($new_buffer); $self->{rPos} = 0; } sub available { my $self = shift; return ($self->{wPos} - $self->{rPos}); } sub read { my $self = shift; my $len = shift; my $ret; my $avail = ($self->{wPos} - $self->{rPos}); return '' if $avail == 0; #how much to give my $give = $len; $give = $avail if $avail < $len; $ret = substr($self->{buffer},$self->{rPos},$give); $self->{rPos} += $give; return $ret; } sub readAll { my $self = shift; my $len = shift; my $avail = ($self->{wPos} - $self->{rPos}); if ($avail < $len) { die Thrift::TTransportException->new("Attempt to readAll($len) found only $avail available", Thrift::TTransportException::END_OF_FILE); } my $data = ''; my $got = 0; while (($got = length($data)) < $len) { $data .= $self->read($len - $got); } return $data; } sub write { my $self = shift; my $buf = shift; $self->{buffer} .= $buf; $self->{wPos} += length($buf); } sub flush { } 1; thrift-0.23.0/lib/perl/lib/Thrift/Type.pm0000664000175000017500000000263115165535636020374 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; # # Data types that can be sent via Thrift # package Thrift::TType; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use constant STOP => 0; use constant VOID => 1; use constant BOOL => 2; use constant BYTE => 3; use constant I08 => 3; use constant DOUBLE => 4; use constant I16 => 6; use constant I32 => 8; use constant I64 => 10; use constant STRING => 11; use constant UTF7 => 11; use constant STRUCT => 12; use constant MAP => 13; use constant SET => 14; use constant LIST => 15; use constant UTF8 => 16; use constant UTF16 => 17; 1; thrift-0.23.0/lib/perl/lib/Thrift/BinaryProtocol.pm0000664000175000017500000002117615165535636022426 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Bit::Vector; use Encode; use Thrift; use Thrift::Exception; use Thrift::MessageType; use Thrift::Protocol; use Thrift::Type; use utf8; # # Binary implementation of the Thrift protocol. # package Thrift::BinaryProtocol; use base('Thrift::Protocol'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use constant VERSION_MASK => 0xffff0000; use constant VERSION_1 => 0x80010000; use constant IS_BIG_ENDIAN => unpack('h*', pack('s', 1)) =~ m/01/; sub new { my $classname = shift; my $trans = shift; my $self = $classname->SUPER::new($trans); return bless($self,$classname); } sub writeMessageBegin { my $self = shift; my ($name, $type, $seqid) = @_; return $self->writeI32(VERSION_1 | $type) + $self->writeString($name) + $self->writeI32($seqid); } sub writeMessageEnd { my $self = shift; return 0; } sub writeStructBegin { my $self = shift; my $name = shift; return 0; } sub writeStructEnd { my $self = shift; return 0; } sub writeFieldBegin { my $self = shift; my ($fieldName, $fieldType, $fieldId) = @_; return $self->writeByte($fieldType) + $self->writeI16($fieldId); } sub writeFieldEnd { my $self = shift; return 0; } sub writeFieldStop { my $self = shift; return $self->writeByte(Thrift::TType::STOP); } sub writeMapBegin { my $self = shift; my ($keyType, $valType, $size) = @_; return $self->writeByte($keyType) + $self->writeByte($valType) + $self->writeI32($size); } sub writeMapEnd { my $self = shift; return 0; } sub writeListBegin { my $self = shift; my ($elemType, $size) = @_; return $self->writeByte($elemType) + $self->writeI32($size); } sub writeListEnd { my $self = shift; return 0; } sub writeSetBegin { my $self = shift; my ($elemType, $size) = @_; return $self->writeByte($elemType) + $self->writeI32($size); } sub writeSetEnd { my $self = shift; return 0; } sub writeBool { my $self = shift; my $value = shift; my $data = pack('c', $value ? 1 : 0); $self->{trans}->write($data, 1); return 1; } sub writeByte { my $self = shift; my $value= shift; my $data = pack('c', $value); $self->{trans}->write($data, 1); return 1; } sub writeI16 { my $self = shift; my $value= shift; my $data = pack('n', $value); $self->{trans}->write($data, 2); return 2; } sub writeI32 { my $self = shift; my $value= shift; my $data = pack('N', $value); $self->{trans}->write($data, 4); return 4; } sub writeI64 { my $self = shift; my $value= shift; my $data; my $vec; #stop annoying error $vec = Bit::Vector->new_Dec(64, $value); $data = pack 'NN', $vec->Chunk_Read(32, 32), $vec->Chunk_Read(32, 0); $self->{trans}->write($data, 8); return 8; } sub writeDouble { my $self = shift; my $value= shift; my $data = pack('d', $value); if (IS_BIG_ENDIAN) { $self->{trans}->write($data, 8); } else { $self->{trans}->write(scalar reverse($data), 8); } return 8; } sub writeString{ my $self = shift; my $value= shift; if( utf8::is_utf8($value) ){ $value = Encode::encode_utf8($value); } my $len = length($value); my $result = $self->writeI32($len); if ($len) { $self->{trans}->write($value,$len); } return $result + $len; } # #All references # sub readMessageBegin { my $self = shift; my ($name, $type, $seqid) = @_; my $version = 0; my $result = $self->readI32(\$version); if (($version & VERSION_MASK) > 0) { if (($version & VERSION_MASK) != VERSION_1) { die Thrift::TProtocolException->new('Missing version identifier', Thrift::TProtocolException::BAD_VERSION); } $$type = $version & 0x000000ff; return $result + $self->readString($name) + $self->readI32($seqid); } else { # old client support code return $result + $self->readStringBody($name, $version) + # version here holds the size of the string $self->readByte($type) + $self->readI32($seqid); } } sub readMessageEnd { my $self = shift; return 0; } sub readStructBegin { my $self = shift; my $name = shift; $$name = ''; return 0; } sub readStructEnd { my $self = shift; return 0; } sub readFieldBegin { my $self = shift; my ($name, $fieldType, $fieldId) = @_; my $result = $self->readByte($fieldType); if ($$fieldType == Thrift::TType::STOP) { $$fieldId = 0; return $result; } $result += $self->readI16($fieldId); return $result; } sub readFieldEnd() { my $self = shift; return 0; } sub readMapBegin { my $self = shift; my ($keyType, $valType, $size) = @_; return $self->readByte($keyType) + $self->readByte($valType) + $self->readI32($size); } sub readMapEnd() { my $self = shift; return 0; } sub readListBegin { my $self = shift; my ($elemType, $size) = @_; return $self->readByte($elemType) + $self->readI32($size); } sub readListEnd { my $self = shift; return 0; } sub readSetBegin { my $self = shift; my ($elemType, $size) = @_; return $self->readByte($elemType) + $self->readI32($size); } sub readSetEnd { my $self = shift; return 0; } sub readBool { my $self = shift; my $value = shift; my $data = $self->{trans}->readAll(1); my @arr = unpack('c', $data); $$value = $arr[0] == 1; return 1; } sub readByte { my $self = shift; my $value = shift; my $data = $self->{trans}->readAll(1); my @arr = unpack('c', $data); $$value = $arr[0]; return 1; } sub readI16 { my $self = shift; my $value = shift; my $data = $self->{trans}->readAll(2); my @arr = unpack('n', $data); $$value = $arr[0]; if ($$value > 0x7fff) { $$value = 0 - (($$value - 1) ^ 0xffff); } return 2; } sub readI32 { my $self = shift; my $value= shift; my $data = $self->{trans}->readAll(4); my @arr = unpack('N', $data); $$value = $arr[0]; if ($$value > 0x7fffffff) { $$value = 0 - (($$value - 1) ^ 0xffffffff); } return 4; } sub readI64 { my $self = shift; my $value = shift; my $data = $self->{trans}->readAll(8); my ($hi,$lo)=unpack('NN',$data); my $vec = Bit::Vector->new(64); $vec->Chunk_Store(32,32,$hi); $vec->Chunk_Store(32,0,$lo); $$value = $vec->to_Dec(); return 8; } sub readDouble { my $self = shift; my $value = shift; my $data; if (IS_BIG_ENDIAN) { $data = $self->{trans}->readAll(8); } else { $data = scalar reverse($self->{trans}->readAll(8)); } my @arr = unpack('d', $data); $$value = $arr[0]; return 8; } sub readString { my $self = shift; my $value = shift; my $len; my $result = $self->readI32(\$len); if ($len) { $$value = $self->{trans}->readAll($len); } else { $$value = ''; } return $result + $len; } sub readStringBody { my $self = shift; my $value = shift; my $len = shift; if ($len) { $$value = $self->{trans}->readAll($len); } else { $$value = ''; } return $len; } # # Binary Protocol Factory # package Thrift::BinaryProtocolFactory; use base('Thrift::TProtocolFactory'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = $classname->SUPER::new(); return bless($self,$classname); } sub getProtocol{ my $self = shift; my $trans = shift; return Thrift::BinaryProtocol->new($trans); } 1; thrift-0.23.0/lib/perl/lib/Thrift/Transport.pm0000664000175000017500000000630515165535636021451 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Exception; # # Transport exceptions # package Thrift::TTransportException; use base('Thrift::TException'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use constant UNKNOWN => 0; use constant NOT_OPEN => 1; use constant ALREADY_OPEN => 2; use constant TIMED_OUT => 3; use constant END_OF_FILE => 4; sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); return bless($self,$classname); } package Thrift::Transport; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # Whether this transport is open. # # @return boolean true if open # sub isOpen { die 'abstract'; } # # Open the transport for reading/writing # # @throws TTransportException if cannot open # sub open { die 'abstract'; } # # Close the transport. # sub close { die 'abstract'; } # # Read some data into the array. # # @param int $len How much to read # @return string The data that has been read # @throws TTransportException if cannot read any more data # sub read { die 'abstract'; } # # Guarantees that the full amount of data is read. # # @return string The data, of exact length # @throws TTransportException if cannot read data # sub readAll { my $self = shift; my $len = shift; my $data = ''; my $got = 0; while (($got = length($data)) < $len) { $data .= $self->read($len - $got); } return $data; } # # Writes the given data out. # # @param string $buf The data to write # @throws TTransportException if writing fails # sub write { die 'abstract'; } # # Flushes any pending data out of a buffer # # @throws TTransportException if a writing error occurs # sub flush {} # # TransportFactory creates transport objects from transports # package Thrift::TransportFactory; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = {}; return bless($self,$classname); } # # Build a transport from the base transport # # @return Thrift::Transport transport # sub getTransport { my $self = shift; my $trans = shift; return $trans; } # # ServerTransport base class module # package Thrift::ServerTransport; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub listen { die 'abstract'; } sub accept { die 'abstract'; } sub close { die 'abstract'; } 1; thrift-0.23.0/lib/perl/lib/Thrift/SSLSocket.pm0000664000175000017500000000705115165535636021266 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Socket; use IO::Socket::SSL; package Thrift::SSLSocket; use base qw( Thrift::Socket ); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # Construction and usage # # my $opts = {} # my $socket = Thrift::SSLSocket->new(\%opts); # # options: # # Any option from Socket.pm is valid, and then: # # ca => certificate authority file (PEM file) to authenticate the # server against; if not specified then the server is not # authenticated # cert => certificate to use as the client; if not specified then # the client does not present one but still connects using # secure protocol # ciphers => allowed cipher list # (see http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS) # key => certificate key for "cert" option # version => acceptable SSL/TLS versions - if not specified then the # default is to use SSLv23 handshake but only negotiate # at TLSv1.0 or later # sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); return bless($self, $classname); } sub __open { my $self = shift; my $opts = {PeerAddr => $self->{host}, PeerPort => $self->{port}, Proto => 'tcp', Timeout => $self->{sendTimeout} / 1000}; my $verify = IO::Socket::SSL::SSL_VERIFY_PEER | IO::Socket::SSL::SSL_VERIFY_FAIL_IF_NO_PEER_CERT | IO::Socket::SSL::SSL_VERIFY_CLIENT_ONCE; $opts->{SSL_ca_file} = $self->{ca} if defined $self->{ca}; $opts->{SSL_cert_file} = $self->{cert} if defined $self->{cert}; $opts->{SSL_cipher_list} = $self->{ciphers} if defined $self->{ciphers}; $opts->{SSL_key_file} = $self->{key} if defined $self->{key}; $opts->{SSL_use_cert} = (defined $self->{cert}) ? 1 : 0; $opts->{SSL_verify_mode} = (defined $self->{ca}) ? $verify : IO::Socket::SSL::SSL_VERIFY_NONE; $opts->{SSL_version} = (defined $self->{version}) ? $self->{version} : 'SSLv23:!SSLv3:!SSLv2'; return IO::Socket::SSL->new(%$opts); } sub __close { my $self = shift; my $sock = ($self->{handle}->handles())[0]; if ($sock) { $sock->close(SSL_no_shutdown => 1); } } sub __recv { my $self = shift; my $sock = shift; my $len = shift; my $buf = undef; if ($sock) { sysread($sock, $buf, $len); } return $buf; } sub __send { my $self = shift; my $sock = shift; my $buf = shift; return syswrite($sock, $buf); } sub __wait { my $self = shift; my $sock = ($self->{handle}->handles())[0]; if ($sock and $sock->pending() eq 0) { return $self->SUPER::__wait(); } return $sock; } 1; thrift-0.23.0/lib/perl/lib/Thrift/Protocol.pm0000664000175000017500000002500215165535636021251 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Exception; use Thrift::Type; # # Protocol exceptions # package Thrift::TProtocolException; use base('Thrift::TException'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use constant UNKNOWN => 0; use constant INVALID_DATA => 1; use constant NEGATIVE_SIZE => 2; use constant SIZE_LIMIT => 3; use constant BAD_VERSION => 4; use constant NOT_IMPLEMENTED => 5; use constant DEPTH_LIMIT => 6; sub new { my $classname = shift; my $self = $classname->SUPER::new(); return bless($self,$classname); } # # Protocol base class module. # package Thrift::Protocol; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = {}; my $trans = shift; $self->{trans}= $trans; return bless($self,$classname); } sub getTransport { my $self = shift; return $self->{trans}; } # # Writes the message header # # @param string $name Function name # @param int $type message type TMessageType::CALL or TMessageType::REPLY # @param int $seqid The sequence id of this message # sub writeMessageBegin { my ($name, $type, $seqid); die 'abstract'; } # # Close the message # sub writeMessageEnd { die 'abstract'; } # # Writes a struct header. # # @param string $name Struct name # @throws TProtocolException on write error # @return int How many bytes written # sub writeStructBegin { my ($name); die 'abstract'; } # # Close a struct. # # @throws TProtocolException on write error # @return int How many bytes written # sub writeStructEnd { die 'abstract'; } # # Starts a field. # # @param string $name Field name # @param int $type Field type # @param int $fid Field id # @throws TProtocolException on write error # @return int How many bytes written # sub writeFieldBegin { my ($fieldName, $fieldType, $fieldId); die 'abstract'; } sub writeFieldEnd { die 'abstract'; } sub writeFieldStop { die 'abstract'; } sub writeMapBegin { my ($keyType, $valType, $size); die 'abstract'; } sub writeMapEnd { die 'abstract'; } sub writeListBegin { my ($elemType, $size); die 'abstract'; } sub writeListEnd { die 'abstract'; } sub writeSetBegin { my ($elemType, $size); die 'abstract'; } sub writeSetEnd { die 'abstract'; } sub writeBool { my ($bool); die 'abstract'; } sub writeByte { my ($byte); die 'abstract'; } sub writeI16 { my ($i16); die 'abstract'; } sub writeI32 { my ($i32); die 'abstract'; } sub writeI64 { my ($i64); die 'abstract'; } sub writeDouble { my ($dub); die 'abstract'; } sub writeString { my ($str); die 'abstract'; } # # Reads the message header # # @param string $name Function name # @param int $type message type TMessageType::CALL or TMessageType::REPLY # @parem int $seqid The sequence id of this message # sub readMessageBegin { my ($name, $type, $seqid); die 'abstract'; } # # Read the close of message # sub readMessageEnd { die 'abstract'; } sub readStructBegin { my($name); die 'abstract'; } sub readStructEnd { die 'abstract'; } sub readFieldBegin { my ($name, $fieldType, $fieldId); die 'abstract'; } sub readFieldEnd { die 'abstract'; } sub readMapBegin { my ($keyType, $valType, $size); die 'abstract'; } sub readMapEnd { die 'abstract'; } sub readListBegin { my ($elemType, $size); die 'abstract'; } sub readListEnd { die 'abstract'; } sub readSetBegin { my ($elemType, $size); die 'abstract'; } sub readSetEnd { die 'abstract'; } sub readBool { my ($bool); die 'abstract'; } sub readByte { my ($byte); die 'abstract'; } sub readI16 { my ($i16); die 'abstract'; } sub readI32 { my ($i32); die 'abstract'; } sub readI64 { my ($i64); die 'abstract'; } sub readDouble { my ($dub); die 'abstract'; } sub readString { my ($str); die 'abstract'; } # # The skip function is a utility to parse over unrecognized data without # causing corruption. # # @param TType $type What type is it # sub skip { my $self = shift; my $type = shift; my $ref; my $result; my $i; if($type == Thrift::TType::BOOL) { return $self->readBool(\$ref); } elsif($type == Thrift::TType::BYTE){ return $self->readByte(\$ref); } elsif($type == Thrift::TType::I16){ return $self->readI16(\$ref); } elsif($type == Thrift::TType::I32){ return $self->readI32(\$ref); } elsif($type == Thrift::TType::I64){ return $self->readI64(\$ref); } elsif($type == Thrift::TType::DOUBLE){ return $self->readDouble(\$ref); } elsif($type == Thrift::TType::STRING) { return $self->readString(\$ref); } elsif($type == Thrift::TType::STRUCT) { $result = $self->readStructBegin(\$ref); while (1) { my ($ftype,$fid); $result += $self->readFieldBegin(\$ref, \$ftype, \$fid); if ($ftype == Thrift::TType::STOP) { last; } $result += $self->skip($ftype); $result += $self->readFieldEnd(); } $result += $self->readStructEnd(); return $result; } elsif($type == Thrift::TType::MAP) { my($keyType,$valType,$size); $result = $self->readMapBegin(\$keyType, \$valType, \$size); for ($i = 0; $i < $size; $i++) { $result += $self->skip($keyType); $result += $self->skip($valType); } $result += $self->readMapEnd(); return $result; } elsif($type == Thrift::TType::SET) { my ($elemType,$size); $result = $self->readSetBegin(\$elemType, \$size); for ($i = 0; $i < $size; $i++) { $result += $self->skip($elemType); } $result += $self->readSetEnd(); return $result; } elsif($type == Thrift::TType::LIST) { my ($elemType,$size); $result = $self->readListBegin(\$elemType, \$size); for ($i = 0; $i < $size; $i++) { $result += $self->skip($elemType); } $result += $self->readListEnd(); return $result; } die Thrift::TProtocolException->new("Type $type not recognized --- corrupt data?", Thrift::TProtocolException::INVALID_DATA); } # # Utility for skipping binary data # # @param TTransport $itrans TTransport object # @param int $type Field type # sub skipBinary { my $self = shift; my $itrans = shift; my $type = shift; if($type == Thrift::TType::BOOL) { return $itrans->readAll(1); } elsif($type == Thrift::TType::BYTE) { return $itrans->readAll(1); } elsif($type == Thrift::TType::I16) { return $itrans->readAll(2); } elsif($type == Thrift::TType::I32) { return $itrans->readAll(4); } elsif($type == Thrift::TType::I64) { return $itrans->readAll(8); } elsif($type == Thrift::TType::DOUBLE) { return $itrans->readAll(8); } elsif( $type == Thrift::TType::STRING ) { my @len = unpack('N', $itrans->readAll(4)); my $len = $len[0]; if ($len > 0x7fffffff) { $len = 0 - (($len - 1) ^ 0xffffffff); } return 4 + $itrans->readAll($len); } elsif( $type == Thrift::TType::STRUCT ) { my $result = 0; while (1) { my $ftype = 0; my $fid = 0; my $data = $itrans->readAll(1); my @arr = unpack('c', $data); $ftype = $arr[0]; if ($ftype == Thrift::TType::STOP) { last; } # I16 field id $result += $itrans->readAll(2); $result += $self->skipBinary($itrans, $ftype); } return $result; } elsif($type == Thrift::TType::MAP) { # Ktype my $data = $itrans->readAll(1); my @arr = unpack('c', $data); my $ktype = $arr[0]; # Vtype $data = $itrans->readAll(1); @arr = unpack('c', $data); my $vtype = $arr[0]; # Size $data = $itrans->readAll(4); @arr = unpack('N', $data); my $size = $arr[0]; if ($size > 0x7fffffff) { $size = 0 - (($size - 1) ^ 0xffffffff); } my $result = 6; for (my $i = 0; $i < $size; $i++) { $result += $self->skipBinary($itrans, $ktype); $result += $self->skipBinary($itrans, $vtype); } return $result; } elsif($type == Thrift::TType::SET || $type == Thrift::TType::LIST) { # Vtype my $data = $itrans->readAll(1); my @arr = unpack('c', $data); my $vtype = $arr[0]; # Size $data = $itrans->readAll(4); @arr = unpack('N', $data); my $size = $arr[0]; if ($size > 0x7fffffff) { $size = 0 - (($size - 1) ^ 0xffffffff); } my $result = 5; for (my $i = 0; $i < $size; $i++) { $result += $self->skipBinary($itrans, $vtype); } return $result; } die Thrift::TProtocolException->new("Type $type not recognized --- corrupt data?", Thrift::TProtocolException::INVALID_DATA); } # # Protocol factory creates protocol objects from transports # package Thrift::TProtocolFactory; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = {}; return bless($self,$classname); } # # Build a protocol from the base transport # # @return TProtcol protocol # sub getProtocol { my ($trans); die 'interface'; } 1; thrift-0.23.0/lib/perl/lib/Thrift/BufferedTransport.pm0000664000175000017500000000542615165535636023117 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Exception; use Thrift::Transport; package Thrift::BufferedTransport; use base('Thrift::Transport'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $transport = shift; my $rBufSize = shift || 512; my $wBufSize = shift || 512; my $self = { transport => $transport, rBufSize => $rBufSize, wBufSize => $wBufSize, wBuf => '', rBuf => '', }; return bless($self,$classname); } sub isOpen { my $self = shift; return $self->{transport}->isOpen(); } sub open { my $self = shift; $self->{transport}->open(); } sub close() { my $self = shift; $self->{transport}->close(); } sub readAll { my $self = shift; my $len = shift; return $self->{transport}->readAll($len); } sub read { my $self = shift; my $len = shift; my $ret; # Methinks Perl is already buffering these for us return $self->{transport}->read($len); } sub write { my $self = shift; my $buf = shift; $self->{wBuf} .= $buf; if (length($self->{wBuf}) >= $self->{wBufSize}) { $self->{transport}->write($self->{wBuf}); $self->{wBuf} = ''; } } sub flush { my $self = shift; if (length($self->{wBuf}) > 0) { $self->{transport}->write($self->{wBuf}); $self->{wBuf} = ''; } $self->{transport}->flush(); } # # BufferedTransport factory creates buffered transport objects from transports # package Thrift::BufferedTransportFactory; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = {}; return bless($self,$classname); } # # Build a buffered transport from the base transport # # @return Thrift::BufferedTransport transport # sub getTransport { my $self = shift; my $trans = shift; my $buffered = Thrift::BufferedTransport->new($trans); return $buffered; } 1; thrift-0.23.0/lib/perl/lib/Thrift/ServerSocket.pm0000664000175000017500000000603615165535636022075 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use IO::Socket::INET; use IO::Select; use Thrift; use Thrift::Transport; use Thrift::Socket; package Thrift::ServerSocket; use base qw( Thrift::ServerTransport ); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # Constructor. # Legacy construction takes one argument, port number. # New construction takes a hash: # @param[in] host host interface to listen on (undef = all interfaces) # @param[in] port port number to listen on (required) # @param[in] queue the listen queue size (default if not specified is 128) # @example my $serversock = Thrift::ServerSocket->new(host => undef, port => port) # sub new { my $classname = shift; my $args = shift; my $self; # Support both old-style "port number" construction and newer... if (ref($args) eq 'HASH') { $self = $args; } else { $self = { port => $args }; } if (not defined $self->{queue}) { $self->{queue} = 128; } return bless($self, $classname); } sub listen { my $self = shift; my $sock = $self->__listen() || do { my $error = ref($self) . ': Could not bind to ' . '*:' . $self->{port} . ' (' . $! . ')'; if ($self->{debug}) { $self->{debugHandler}->($error); } die Thrift::TTransportException->new($error, Thrift::TTransportException::NOT_OPEN); }; $self->{handle} = $sock; } sub accept { my $self = shift; if ( exists $self->{handle} and defined $self->{handle} ) { my $client = $self->{handle}->accept(); my $result = $self->__client(); $result->{handle} = IO::Select->new($client); return $result; } return undef; } sub close { my $self = shift; if ( exists $self->{handle} and defined $self->{handle} ) { $self->{handle}->close(); } } ### ### Overridable methods ### sub __client { return Thrift::Socket->new(); } sub __listen { my $self = shift; return IO::Socket::INET->new(LocalAddr => $self->{host}, LocalPort => $self->{port}, Proto => 'tcp', Listen => $self->{queue}, ReuseAddr => 1); } 1; thrift-0.23.0/lib/perl/lib/Thrift/UnixServerSocket.pm0000664000175000017500000000453615165535636022744 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::ServerSocket; use Thrift::UnixSocket; use IO::Socket::UNIX; package Thrift::UnixServerSocket; use base qw( Thrift::ServerSocket ); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # Constructor. # If a single argument is given that is not a hash, that is the unix domain socket path. # If a single argument is given that is a hash: # @param[in] path unix domain socket file name # @param[in] queue the listen queue size (default is not specified is supplied by ServerSocket) # @example my $serversock = Thrift::UnixServerSocket->new($path); # @example my $serversock = Thrift::UnixServerSocket->new(path => "somepath", queue => 64); # sub new { my $classname = shift; my $args = shift; my $self; if (ref($args) eq 'HASH') { $self = $classname->SUPER::new($args); } else { $self = $classname->SUPER::new(); $self->{path} = $args; } return bless($self, $classname); } sub __client { return Thrift::UnixSocket->new(); } sub __listen { my $self = shift; my $sock = IO::Socket::UNIX->new( Type => IO::Socket::SOCK_STREAM, Local => $self->{path}, Listen => $self->{queue}) || do { my $error = 'UnixServerSocket: Could not bind to ' . $self->{path} . ' (' . $! . ')'; if ($self->{debug}) { $self->{debugHandler}->($error); } die Thrift::TTransportException->new($error, Thrift::TTransportException::NOT_OPEN); }; return $sock; } 1; thrift-0.23.0/lib/perl/lib/Thrift/MultiplexedProtocol.pm0000664000175000017500000000371315165535636023473 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::MessageType; use Thrift::Protocol; use Thrift::ProtocolDecorator; package Thrift::MultiplexedProtocol; use base qw(Thrift::ProtocolDecorator); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use constant SEPARATOR => ':'; sub new { my $classname = shift; my $protocol = shift; my $serviceName = shift; my $self = $classname->SUPER::new($protocol); $self->{serviceName} = $serviceName; return bless($self,$classname); } # # Writes the message header. # Prepends the service name to the function name, separated by MultiplexedProtocol::SEPARATOR. # # @param string $name Function name. # @param int $type Message type. # @param int $seqid The sequence id of this message. # sub writeMessageBegin { my $self = shift; my ($name, $type, $seqid) = @_; if ($type == Thrift::TMessageType::CALL || $type == Thrift::TMessageType::ONEWAY) { my $nameWithService = $self->{serviceName}.SEPARATOR.$name; $self->SUPER::writeMessageBegin($nameWithService, $type, $seqid); } else { $self->SUPER::writeMessageBegin($name, $type, $seqid); } } 1; thrift-0.23.0/lib/perl/lib/Thrift/Socket.pm0000664000175000017500000001516715165535636020713 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Exception; use Thrift::Transport; use IO::Socket::INET; use IO::Select; package Thrift::Socket; use base qw( Thrift::Transport ); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # Construction and usage # # my $opts = {} # my $socket = Thrift::Socket->new(\%opts); # # options: # # host => host to connect to # port => port to connect to # sendTimeout => timeout used for send and for connect # recvTimeout => timeout used for recv # sub new { my $classname = shift; my $opts = shift; # default settings: my $self = { host => 'localhost', port => 9090, recvTimeout => 10000, sendTimeout => 10000, proto => 'tcp', handle => undef }; if (defined $opts and ref $opts eq ref {}) { # argument is a hash of options so override the defaults $self->{$_} = $opts->{$_} for keys %$opts; } else { # older style constructor takes 3 arguments, none of which are required $self->{host} = $opts || 'localhost'; $self->{port} = shift || 9090; } return bless($self,$classname); } sub setSendTimeout { my $self = shift; my $timeout = shift; $self->{sendTimeout} = $timeout; } sub setRecvTimeout { my $self = shift; my $timeout = shift; $self->{recvTimeout} = $timeout; } # # Tests whether this is open # # @return bool true if the socket is open # sub isOpen { my $self = shift; if( defined $self->{handle} ){ return ($self->{handle}->handles())[0]->connected; } return 0; } # # Connects the socket. # sub open { my $self = shift; my $sock = $self->__open() || do { my $error = ref($self).': Could not connect to '.$self->{host}.':'.$self->{port}.' ('.$!.')'; die Thrift::TTransportException->new($error, Thrift::TTransportException::NOT_OPEN); }; $self->{handle} = IO::Select->new( $sock ); } # # Closes the socket. # sub close { my $self = shift; if( defined $self->{handle} ) { $self->__close(); } } # # Uses stream get contents to do the reading # # @param int $len How many bytes # @return string Binary data # sub readAll { my $self = shift; my $len = shift; return unless defined $self->{handle}; my $pre = ""; while (1) { my $sock = $self->__wait(); my $buf = $self->__recv($sock, $len); if (!defined $buf || $buf eq '') { die Thrift::TTransportException->new(ref($self).': Could not read '.$len.' bytes from '. $self->{host}.':'.$self->{port}, Thrift::TTransportException::END_OF_FILE); } elsif ((my $sz = length($buf)) < $len) { $pre .= $buf; $len -= $sz; } else { return $pre.$buf; } } } # # Read from the socket # # @param int $len How many bytes # @return string Binary data # sub read { my $self = shift; my $len = shift; return unless defined $self->{handle}; my $sock = $self->__wait(); my $buf = $self->__recv($sock, $len); if (!defined $buf || $buf eq '') { die Thrift::TTransportException->new(ref($self).': Could not read '.$len.' bytes from '. $self->{host}.':'.$self->{port}, Thrift::TTransportException::END_OF_FILE); } return $buf; } # # Write to the socket. # # @param string $buf The data to write # sub write { my $self = shift; my $buf = shift; return unless defined $self->{handle}; while (length($buf) > 0) { #check for timeout my @sockets = $self->{handle}->can_write( $self->{sendTimeout} / 1000 ); if(@sockets == 0){ die Thrift::TTransportException->new(ref($self).': timed out writing to bytes from '. $self->{host}.':'.$self->{port}, Thrift::TTransportException::TIMED_OUT); } my $sent = $self->__send($sockets[0], $buf); if (!defined $sent || $sent == 0 ) { die Thrift::TTransportException->new(ref($self).': Could not write '.length($buf).' bytes '. $self->{host}.':'.$self->{host}, Thrift::TTransportException::END_OF_FILE); } $buf = substr($buf, $sent); } } # # Flush output to the socket. # sub flush { my $self = shift; return unless defined $self->{handle}; my $ret = ($self->{handle}->handles())[0]->flush; } ### ### Overridable methods ### # # Open a connection to a server. # sub __open { my $self = shift; return IO::Socket::INET->new(PeerAddr => $self->{host}, PeerPort => $self->{port}, Proto => $self->{proto}, Timeout => $self->{sendTimeout} / 1000); } # # Close the connection # sub __close { my $self = shift; CORE::close(($self->{handle}->handles())[0]); } # # Read data # # @param[in] $sock the socket # @param[in] $len the length to read # @returns the data buffer that was read # sub __recv { my $self = shift; my $sock = shift; my $len = shift; my $buf = undef; $sock->recv($buf, $len); return $buf; } # # Send data # # @param[in] $sock the socket # @param[in] $buf the data buffer # @returns the number of bytes written # sub __send { my $self = shift; my $sock = shift; my $buf = shift; return $sock->send($buf); } # # Wait for data to be readable # # @returns a socket that can be read # sub __wait { my $self = shift; my @sockets = $self->{handle}->can_read( $self->{recvTimeout} / 1000 ); if (@sockets == 0) { die Thrift::TTransportException->new(ref($self).': timed out reading from '. $self->{host}.':'.$self->{port}, Thrift::TTransportException::TIMED_OUT); } return $sockets[0]; } 1; thrift-0.23.0/lib/perl/lib/Thrift/UnixSocket.pm0000664000175000017500000000347415165535636021555 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Socket; use IO::Socket::UNIX; package Thrift::UnixSocket; use base qw( Thrift::Socket ); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # Constructor. # Takes a unix domain socket filename. # See Thrift::Socket for base class parameters. # @param[in] path path to unix socket file # @example my $sock = Thrift::UnixSocket->new($path); # sub new { my $classname = shift; my $self = $classname->SUPER::new(); $self->{path} = shift; return bless($self, $classname); } sub __open { my $self = shift; my $sock = IO::Socket::UNIX->new( Type => IO::Socket::SOCK_STREAM, Peer => $self->{path}) || do { my $error = 'UnixSocket: Could not connect to ' . $self->{path} . ' (' . $! . ')'; if ($self->{debug}) { $self->{debugHandler}->($error); } die Thrift::TTransportException->new($error, Thrift::TTransportException::NOT_OPEN); }; return $sock; } 1; thrift-0.23.0/lib/perl/lib/Thrift/HttpClient.pm0000664000175000017500000001070415165535636021531 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use HTTP::Request; use IO::String; use LWP::UserAgent; use Thrift; use Thrift::Exception; use Thrift::Transport; package Thrift::HttpClient; use base('Thrift::Transport'); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $url = shift || 'http://localhost:9090'; my $out = IO::String->new; binmode($out); my $self = { url => $url, out => $out, timeout => 100, handle => undef, headers => {}, }; return bless($self,$classname); } sub setTimeout { my $self = shift; my $timeout = shift; $self->{timeout} = $timeout; } sub setRecvTimeout { warn 'setRecvTimeout is deprecated - use setTimeout instead'; # note: recvTimeout was never used so we do not need to do anything here } sub setSendTimeout { my $self = shift; my $timeout = shift; warn 'setSendTimeout is deprecated - use setTimeout instead'; $self->setTimeout($timeout); } sub setHeader { my $self = shift; my ($name, $value) = @_; $self->{headers}->{$name} = $value; } # # Tests whether this is open # # @return bool true if the socket is open # sub isOpen { return 1; } sub open {} # # Cleans up the buffer. # sub close { my $self = shift; if (defined($self->{io})) { close($self->{io}); $self->{io} = undef; } } # # Guarantees that the full amount of data is read. # # @return string The data, of exact length # @throws TTransportException if cannot read data # sub readAll { my $self = shift; my $len = shift; my $buf = $self->read($len); if (!defined($buf)) { die Thrift::TTransportException->new("TSocket: Could not read $len bytes from input buffer", Thrift::TTransportException::END_OF_FILE); } return $buf; } # # Read and return string # sub read { my $self = shift; my $len = shift; my $buf; my $in = $self->{in}; if (!defined($in)) { die Thrift::TTransportException->new('Response buffer is empty, no request.', Thrift::TTransportException::END_OF_FILE); } eval { my $ret = sysread($in, $buf, $len); if (! defined($ret)) { die Thrift::TTransportException->new('No more data available.', Thrift::TTransportException::TIMED_OUT); } }; if($@){ die Thrift::TTransportException->new("$@", Thrift::TTransportException::UNKNOWN); } return $buf; } # # Write string # sub write { my $self = shift; my $buf = shift; $self->{out}->print($buf); } # # Flush output (do the actual HTTP/HTTPS request) # sub flush { my $self = shift; my $ua = LWP::UserAgent->new( 'timeout' => ($self->{timeout} / 1000), 'agent' => 'Perl/THttpClient' ); $ua->default_header('Accept' => 'application/x-thrift'); $ua->default_header('Content-Type' => 'application/x-thrift'); $ua->cookie_jar({}); # hash to remember cookies between redirects my $out = $self->{out}; $out->setpos(0); # rewind my $buf = join('', <$out>); my $request = HTTP::Request->new(POST => $self->{url}, undef, $buf); map { $request->header($_ => $self->{headers}->{$_}) } keys %{$self->{headers}}; my $response = $ua->request($request); my $content_ref = $response->content_ref; my $in = IO::String->new($content_ref); binmode($in); $self->{in} = $in; $in->setpos(0); # rewind # reset write buffer $out = IO::String->new; binmode($out); $self->{out} = $out; } 1; thrift-0.23.0/lib/perl/lib/Thrift/Server.pm0000664000175000017500000001665215165535636020731 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::BinaryProtocol; use Thrift::BufferedTransport; use Thrift::Exception; # # Server base class module # package Thrift::Server; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # 3 possible constructors: # 1. (processor, serverTransport) # Uses a BufferedTransportFactory and a BinaryProtocolFactory. # 2. (processor, serverTransport, transportFactory, protocolFactory) # Uses the same factory for input and output of each type. # 3. (processor, serverTransport, # inputTransportFactory, outputTransportFactory, # inputProtocolFactory, outputProtocolFactory) # sub new { my $classname = shift; my @args = @_; my $self; if (scalar @args == 2) { $self = _init($args[0], $args[1], Thrift::BufferedTransportFactory->new(), Thrift::BufferedTransportFactory->new(), Thrift::BinaryProtocolFactory->new(), Thrift::BinaryProtocolFactory->new()); } elsif (scalar @args == 4) { $self = _init($args[0], $args[1], $args[2], $args[2], $args[3], $args[3]); } elsif (scalar @args == 6) { $self = _init($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); } else { die Thrift::TException->new('Thrift::Server expects exactly 2, 4, or 6 args'); } return bless($self,$classname); } sub _init { my $processor = shift; my $serverTransport = shift; my $inputTransportFactory = shift; my $outputTransportFactory = shift; my $inputProtocolFactory = shift; my $outputProtocolFactory = shift; my $self = { processor => $processor, serverTransport => $serverTransport, inputTransportFactory => $inputTransportFactory, outputTransportFactory => $outputTransportFactory, inputProtocolFactory => $inputProtocolFactory, outputProtocolFactory => $outputProtocolFactory, }; } sub serve { die 'abstract'; } sub _clientBegin { my $self = shift; my $iprot = shift; my $oprot = shift; if (exists $self->{serverEventHandler} and defined $self->{serverEventHandler}) { $self->{serverEventHandler}->clientBegin($iprot, $oprot); } } sub _handleException { my $self = shift; my $e = shift; if ($e->isa('Thrift::TException') and exists $e->{message}) { my $message = $e->{message}; my $code = $e->{code}; my $out = $code . ':' . $message; $message =~ m/TTransportException/ and die $out; if ($message =~ m/Socket/) { # suppress Socket messages } else { warn $out; } } else { warn $e; } } # # SimpleServer from the Server base class that handles one connection at a time # package Thrift::SimpleServer; use parent -norequire, 'Thrift::Server'; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); return bless($self,$classname); } sub serve { my $self = shift; my $stop = 0; $self->{serverTransport}->listen(); while (!$stop) { my $client = $self->{serverTransport}->accept(); if (defined $client) { my $itrans = $self->{inputTransportFactory}->getTransport($client); my $otrans = $self->{outputTransportFactory}->getTransport($client); my $iprot = $self->{inputProtocolFactory}->getProtocol($itrans); my $oprot = $self->{outputProtocolFactory}->getProtocol($otrans); eval { $self->_clientBegin($iprot, $oprot); while (1) { $self->{processor}->process($iprot, $oprot); } }; if($@) { $self->_handleException($@); } $itrans->close(); $otrans->close(); } else { $stop = 1; } } } # # ForkingServer that forks a new process for each request # package Thrift::ForkingServer; use parent -norequire, 'Thrift::Server'; use POSIX ':sys_wait_h'; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my @args = @_; my $self = $classname->SUPER::new(@args); return bless($self,$classname); } sub serve { my $self = shift; # THRIFT-3848: without ignoring SIGCHLD, perl ForkingServer goes into a tight loop $SIG{CHLD} = 'IGNORE'; $self->{serverTransport}->listen(); while (1) { my $client = $self->{serverTransport}->accept(); $self->_client($client); } } sub _client { my $self = shift; my $client = shift; eval { my $itrans = $self->{inputTransportFactory}->getTransport($client); my $otrans = $self->{outputTransportFactory}->getTransport($client); my $iprot = $self->{inputProtocolFactory}->getProtocol($itrans); my $oprot = $self->{outputProtocolFactory}->getProtocol($otrans); $self->_clientBegin($iprot, $oprot); my $pid = fork(); if ($pid) { $self->_parent($pid, $itrans, $otrans); } else { $self->_child($itrans, $otrans, $iprot, $oprot); } }; if($@) { $self->_handleException($@); } } sub _parent { my $self = shift; my $pid = shift; my $itrans = shift; my $otrans = shift; # Parent must close socket or the connection may not get closed promptly $self->tryClose($itrans); $self->tryClose($otrans); } sub _child { my $self = shift; my $itrans = shift; my $otrans = shift; my $iprot = shift; my $oprot = shift; my $ecode = 0; eval { # THRIFT-4065 ensure child process has normal signal handling in case thrift handler uses it $SIG{CHLD} = 'DEFAULT'; while (1) { $self->{processor}->process($iprot, $oprot); } }; if($@) { $ecode = 1; $self->_handleException($@); } $self->tryClose($itrans); $self->tryClose($otrans); exit($ecode); } sub tryClose { my $self = shift; my $file = shift; eval { if (defined $file) { $file->close(); } }; if($@) { if ($@->isa('Thrift::TException') and exists $@->{message}) { my $message = $@->{message}; my $code = $@->{code}; my $out = $code . ':' . $message; warn $out; } else { warn $@; } } } 1; thrift-0.23.0/lib/perl/lib/Thrift/MessageType.pm0000664000175000017500000000210015165535636021670 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; # # Message types for RPC # package Thrift::TMessageType; use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); use constant CALL => 1; use constant REPLY => 2; use constant EXCEPTION => 3; use constant ONEWAY => 4; 1; thrift-0.23.0/lib/perl/lib/Thrift/SSLServerSocket.pm0000664000175000017500000000503615165535636022456 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::SSLSocket; use Thrift::ServerSocket; use IO::Socket::SSL; package Thrift::SSLServerSocket; use base qw( Thrift::ServerSocket ); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); # # Constructor. # Takes a hash: # See Thrift::Socket for base class parameters. # @param[in] ca certificate authority filename - not required # @param[in] cert certificate filename; may contain key in which case key is not required # @param[in] key private key filename for the certificate if it is not inside the cert file # sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); return bless($self, $classname); } sub __client { return Thrift::SSLSocket->new(); } sub __listen { my $self = shift; my $opts = {Listen => $self->{queue}, LocalAddr => $self->{host}, LocalPort => $self->{port}, Proto => 'tcp', ReuseAddr => 1}; my $verify = IO::Socket::SSL::SSL_VERIFY_PEER | IO::Socket::SSL::SSL_VERIFY_FAIL_IF_NO_PEER_CERT | IO::Socket::SSL::SSL_VERIFY_CLIENT_ONCE; $opts->{SSL_ca_file} = $self->{ca} if defined $self->{ca}; $opts->{SSL_cert_file} = $self->{cert} if defined $self->{cert}; $opts->{SSL_cipher_list} = $self->{ciphers} if defined $self->{ciphers}; $opts->{SSL_key_file} = $self->{key} if defined $self->{key}; $opts->{SSL_use_cert} = (defined $self->{cert}) ? 1 : 0; $opts->{SSL_verify_mode} = (defined $self->{ca}) ? $verify : IO::Socket::SSL::SSL_VERIFY_NONE; $opts->{SSL_version} = (defined $self->{version}) ? $self->{version} : 'SSLv23:!SSLv3:!SSLv2'; return IO::Socket::SSL->new(%$opts); } 1; thrift-0.23.0/lib/perl/lib/Thrift/ProtocolDecorator.pm0000664000175000017500000001544215165535636023123 0ustar00buildbuild00000000000000# # 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. # use 5.10.0; use strict; use warnings; use Thrift; use Thrift::Protocol; package Thrift::ProtocolDecorator; use base qw(Thrift::Protocol); use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); sub new { my $classname = shift; my $protocol = shift; my $self = $classname->SUPER::new($protocol->getTransport()); $self->{concreteProtocol} = $protocol; return bless($self,$classname); } # # Writes the message header # # @param string $name Function name # @param int $type message type TMessageType::CALL or TMessageType::REPLY # @param int $seqid The sequence id of this message # sub writeMessageBegin { my $self = shift; my ($name, $type, $seqid) = @_; return $self->{concreteProtocol}->writeMessageBegin($name, $type, $seqid); } # # Close the message # sub writeMessageEnd { my $self = shift; return $self->{concreteProtocol}->writeMessageEnd(); } # # Writes a struct header. # # @param string $name Struct name # @throws TException on write error # @return int How many bytes written # sub writeStructBegin { my $self = shift; my ($name) = @_; return $self->{concreteProtocol}->writeStructBegin($name); } # # Close a struct. # # @throws TException on write error # @return int How many bytes written # sub writeStructEnd { my $self = shift; return $self->{concreteProtocol}->writeStructEnd(); } # # Starts a field. # # @param string $name Field name # @param int $type Field type # @param int $fid Field id # @throws TException on write error # @return int How many bytes written # sub writeFieldBegin { my $self = shift; my ($fieldName, $fieldType, $fieldId) = @_; return $self->{concreteProtocol}->writeFieldBegin($fieldName, $fieldType, $fieldId); } sub writeFieldEnd { my $self = shift; return $self->{concreteProtocol}->writeFieldEnd(); } sub writeFieldStop { my $self = shift; return $self->{concreteProtocol}->writeFieldStop(); } sub writeMapBegin { my $self = shift; my ($keyType, $valType, $size) = @_; return $self->{concreteProtocol}->writeMapBegin($keyType, $valType, $size); } sub writeMapEnd { my $self = shift; return $self->{concreteProtocol}->writeMapEnd(); } sub writeListBegin { my $self = shift; my ($elemType, $size) = @_; return $self->{concreteProtocol}->writeListBegin($elemType, $size); } sub writeListEnd { my $self = shift; return $self->{concreteProtocol}->writeListEnd(); } sub writeSetBegin { my $self = shift; my ($elemType, $size) = @_; return $self->{concreteProtocol}->writeSetBegin($elemType, $size); } sub writeSetEnd { my $self = shift; return $self->{concreteProtocol}->writeListEnd(); } sub writeBool { my $self = shift; my $bool = shift; return $self->{concreteProtocol}->writeBool($bool); } sub writeByte { my $self = shift; my $byte = shift; return $self->{concreteProtocol}->writeByte($byte); } sub writeI16 { my $self = shift; my $i16 = shift; return $self->{concreteProtocol}->writeI16($i16); } sub writeI32 { my $self = shift; my ($i32) = @_; return $self->{concreteProtocol}->writeI32($i32); } sub writeI64 { my $self = shift; my $i64 = shift; return $self->{concreteProtocol}->writeI64($i64); } sub writeDouble { my $self = shift; my $dub = shift; return $self->{concreteProtocol}->writeDouble($dub); } sub writeString { my $self = shift; my $str = shift; return $self->{concreteProtocol}->writeString($str); } # # Reads the message header # # @param string $name Function name # @param int $type message type TMessageType::CALL or TMessageType::REPLY # @parem int $seqid The sequence id of this message # sub readMessageBegin { my $self = shift; my ($name, $type, $seqid) = @_; return $self->{concreteProtocol}->readMessageBegin($name, $type, $seqid); } # # Read the close of message # sub readMessageEnd { my $self = shift; return $self->{concreteProtocol}->readMessageEnd(); } sub readStructBegin { my $self = shift; my $name = shift; return $self->{concreteProtocol}->readStructBegin($name); } sub readStructEnd { my $self = shift; return $self->{concreteProtocol}->readStructEnd(); } sub readFieldBegin { my $self = shift; my ($name, $fieldType, $fieldId) = @_; return $self->{concreteProtocol}->readFieldBegin($name, $fieldType, $fieldId); } sub readFieldEnd { my $self = shift; return $self->{concreteProtocol}->readFieldEnd(); } sub readMapBegin { my $self = shift; my ($keyType, $valType, $size) = @_; return $self->{concreteProtocol}->readMapBegin($keyType, $valType, $size); } sub readMapEnd { my $self = shift; return $self->{concreteProtocol}->readMapEnd(); } sub readListBegin { my $self = shift; my ($elemType, $size) = @_; return $self->{concreteProtocol}->readListBegin($elemType, $size); } sub readListEnd { my $self = shift; return $self->{concreteProtocol}->readListEnd(); } sub readSetBegin { my $self = shift; my ($elemType, $size) = @_; return $self->{concreteProtocol}->readSetBegin($elemType, $size); } sub readSetEnd { my $self = shift; return $self->{concreteProtocol}->readSetEnd(); } sub readBool { my $self = shift; my $bool = shift; return $self->{concreteProtocol}->readBool($bool); } sub readByte { my $self = shift; my $byte = shift; return $self->{concreteProtocol}->readByte($byte); } sub readI16 { my $self = shift; my $i16 = shift; return $self->{concreteProtocol}->readI16($i16); } sub readI32 { my $self = shift; my $i32 = shift; return $self->{concreteProtocol}->readI32($i32); } sub readI64 { my $self = shift; my $i64 = shift; return $self->{concreteProtocol}->readI64($i64); } sub readDouble { my $self = shift; my $dub = shift; return $self->{concreteProtocol}->readDouble($dub); } sub readString { my $self = shift; my $str = shift; return $self->{concreteProtocol}->readString($str); } 1; thrift-0.23.0/lib/perl/tools/0000755000175000017500000000000015170007201016215 5ustar00buildbuild00000000000000thrift-0.23.0/lib/perl/tools/FixupDist.pl0000664000175000017500000000214415165535636020522 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # This will fix up the distribution so that CPAN properly # indexes Thrift. # use 5.10.0; use strict; use warnings; use utf8; use Data::Dumper; use CPAN::Meta; my $meta = CPAN::Meta->load_file('META.json'); $meta->{'provides'} = { 'Thrift' => { 'file' => 'lib/Thrift.pm', 'version' => $meta->version() } }; $meta->save('META.json'); thrift-0.23.0/lib/perl/Makefile.in0000644000175000017500000006403715170007167017147 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/perl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @top_builddir@/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = t EXTRA_DIST = \ coding_standards.md \ build-cpan-dist.sh \ Makefile.PL \ MANIFEST.SKIP \ test.pl \ lib/Thrift.pm \ lib/Thrift.pm \ lib/Thrift/BinaryProtocol.pm \ lib/Thrift/BufferedTransport.pm \ lib/Thrift/Exception.pm \ lib/Thrift/FramedTransport.pm \ lib/Thrift/HttpClient.pm \ lib/Thrift/MemoryBuffer.pm \ lib/Thrift/MessageType.pm \ lib/Thrift/MultiplexedProcessor.pm \ lib/Thrift/MultiplexedProtocol.pm \ lib/Thrift/Protocol.pm \ lib/Thrift/ProtocolDecorator.pm \ lib/Thrift/Server.pm \ lib/Thrift/ServerSocket.pm \ lib/Thrift/Socket.pm \ lib/Thrift/SSLSocket.pm \ lib/Thrift/SSLServerSocket.pm \ lib/Thrift/UnixServerSocket.pm \ lib/Thrift/UnixSocket.pm \ lib/Thrift/Type.pm \ lib/Thrift/Transport.pm \ tools/FixupDist.pl \ README.md THRIFT_IF = @top_srcdir@/test/v0.16/ThriftTest.thrift NAME_BENCHMARKSERVICE = @top_srcdir@/lib/rb/benchmark/Benchmark.thrift NAME_AGGR = @top_srcdir@/contrib/async-test/aggr.thrift THRIFTTEST_GEN = \ gen-perl/ThriftTest/Constants.pm \ gen-perl/ThriftTest/SecondService.pm \ gen-perl/ThriftTest/ThriftTest.pm \ gen-perl/ThriftTest/Types.pm BENCHMARK_GEN = \ gen-perl/BenchmarkService.pm \ gen-perl/Constants.pm \ gen-perl/Types.pm AGGR_GEN = \ gen-perl2/Aggr.pm \ gen-perl2/Constants.pm \ gen-perl2/Types.pm PERL_GEN = \ $(THRIFTTEST_GEN) \ $(BENCHMARK_GEN) \ $(AGGR_GEN) BUILT_SOURCES = $(PERL_GEN) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/perl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/perl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) all check check-am install install-am \ install-exec install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile Makefile-perl.mk : Makefile.PL $(PERL) Makefile.PL MAKEFILE=Makefile-perl.mk INSTALLDIRS=$(INSTALLDIRS) INSTALL_BASE=$(PERL_PREFIX) all-local: Makefile-perl.mk $(MAKE) -f $< find blib -name 'Makefile*' -exec rm -f {} \; install-exec-local: Makefile-perl.mk $(MAKE) -f $< install DESTDIR=$(DESTDIR)/ clean-local: if test -f Makefile-perl.mk ; then \ $(MAKE) -f Makefile-perl.mk clean ; \ fi $(RM) Makefile-perl.mk.old $(RM) -r gen-perl gen-perl2 distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am check-local: $(PERL_GEN) $(PERL) -Iblib/lib -I@abs_srcdir@ -I@builddir@/gen-perl2 -I@builddir@/gen-perl \ @abs_srcdir@/test.pl @abs_srcdir@/t/*.t $(THRIFTTEST_GEN): $(THRIFT_IF) $(THRIFT) $(THRIFT) --gen perl $< $(BENCHMARK_GEN): $(NAME_BENCHMARKSERVICE) $(THRIFT) $(THRIFT) --gen perl $< $(AGGR_GEN): $(NAME_AGGR) $(THRIFT) $(MKDIR_P) gen-perl2 $(THRIFT) -out gen-perl2 --gen perl $< # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/perl/Makefile.am0000664000175000017500000000607415165535636017150 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = t Makefile-perl.mk : Makefile.PL $(PERL) Makefile.PL MAKEFILE=Makefile-perl.mk INSTALLDIRS=$(INSTALLDIRS) INSTALL_BASE=$(PERL_PREFIX) all-local: Makefile-perl.mk $(MAKE) -f $< find blib -name 'Makefile*' -exec rm -f {} \; install-exec-local: Makefile-perl.mk $(MAKE) -f $< install DESTDIR=$(DESTDIR)/ clean-local: if test -f Makefile-perl.mk ; then \ $(MAKE) -f Makefile-perl.mk clean ; \ fi $(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 \ Makefile.PL \ MANIFEST.SKIP \ test.pl \ lib/Thrift.pm \ lib/Thrift.pm \ lib/Thrift/BinaryProtocol.pm \ lib/Thrift/BufferedTransport.pm \ lib/Thrift/Exception.pm \ lib/Thrift/FramedTransport.pm \ lib/Thrift/HttpClient.pm \ lib/Thrift/MemoryBuffer.pm \ lib/Thrift/MessageType.pm \ lib/Thrift/MultiplexedProcessor.pm \ lib/Thrift/MultiplexedProtocol.pm \ lib/Thrift/Protocol.pm \ lib/Thrift/ProtocolDecorator.pm \ lib/Thrift/Server.pm \ lib/Thrift/ServerSocket.pm \ lib/Thrift/Socket.pm \ lib/Thrift/SSLSocket.pm \ lib/Thrift/SSLServerSocket.pm \ lib/Thrift/UnixServerSocket.pm \ lib/Thrift/UnixSocket.pm \ lib/Thrift/Type.pm \ lib/Thrift/Transport.pm \ tools/FixupDist.pl \ README.md THRIFT = @top_builddir@/compiler/cpp/thrift THRIFT_IF = @top_srcdir@/test/v0.16/ThriftTest.thrift NAME_BENCHMARKSERVICE = @top_srcdir@/lib/rb/benchmark/Benchmark.thrift NAME_AGGR = @top_srcdir@/contrib/async-test/aggr.thrift THRIFTTEST_GEN = \ gen-perl/ThriftTest/Constants.pm \ gen-perl/ThriftTest/SecondService.pm \ gen-perl/ThriftTest/ThriftTest.pm \ gen-perl/ThriftTest/Types.pm BENCHMARK_GEN = \ gen-perl/BenchmarkService.pm \ gen-perl/Constants.pm \ gen-perl/Types.pm AGGR_GEN = \ gen-perl2/Aggr.pm \ gen-perl2/Constants.pm \ gen-perl2/Types.pm PERL_GEN = \ $(THRIFTTEST_GEN) \ $(BENCHMARK_GEN) \ $(AGGR_GEN) BUILT_SOURCES = $(PERL_GEN) check-local: $(PERL_GEN) $(PERL) -Iblib/lib -I@abs_srcdir@ -I@builddir@/gen-perl2 -I@builddir@/gen-perl \ @abs_srcdir@/test.pl @abs_srcdir@/t/*.t $(THRIFTTEST_GEN): $(THRIFT_IF) $(THRIFT) $(THRIFT) --gen perl $< $(BENCHMARK_GEN): $(NAME_BENCHMARKSERVICE) $(THRIFT) $(THRIFT) --gen perl $< $(AGGR_GEN): $(NAME_AGGR) $(THRIFT) $(MKDIR_P) gen-perl2 $(THRIFT) -out gen-perl2 --gen perl $< thrift-0.23.0/lib/st/0000775000175000017500000000000015170007142014547 5ustar00buildbuild00000000000000thrift-0.23.0/lib/st/package.xml0000664000175000017500000000167515170007142016675 0ustar00buildbuild00000000000000 libthrift-st thrift.st thrift.st thrift-0.23.0/lib/st/coding_standards.md0000664000175000017500000000010315165535636020413 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/st/thrift.st0000664000175000017500000005464015165535636016452 0ustar00buildbuild00000000000000" Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Contains some contributions under the Thrift Software License. Please see doc/old-thrift-license.txt in the Thrift distribution for details. " SystemOrganization addCategory: #Thrift! SystemOrganization addCategory: #'Thrift-Protocol'! SystemOrganization addCategory: #'Thrift-Transport'! Error subclass: #TError instanceVariableNames: 'code' classVariableNames: '' poolDictionaries: '' category: 'Thrift'! !TError class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:28'! signalWithCode: anInteger self new code: anInteger; signal! ! !TError methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:28'! code ^ code! ! !TError methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:28'! code: anInteger code := anInteger! ! TError subclass: #TProtocolError instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! !TProtocolError class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 18:39'! badVersion ^ 4! ! !TProtocolError class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 18:39'! invalidData ^ 1! ! !TProtocolError class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 18:39'! negativeSize ^ 2! ! !TProtocolError class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 18:40'! sizeLimit ^ 3! ! !TProtocolError class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 18:40'! unknown ^ 0! ! TError subclass: #TTransportError instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Transport'! TTransportError subclass: #TTransportClosedError instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Transport'! Object subclass: #TClient instanceVariableNames: 'iprot oprot seqid remoteSeqid' classVariableNames: '' poolDictionaries: '' category: 'Thrift'! !TClient class methodsFor: 'as yet unclassified' stamp: 'pc 11/7/2007 06:00'! binaryOnHost: aString port: anInteger | sock | sock := TSocket new host: aString; port: anInteger; open; yourself. ^ self new inProtocol: (TBinaryProtocol new transport: sock); yourself! ! !TClient methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 23:03'! inProtocol: aProtocol iprot := aProtocol. oprot ifNil: [oprot := aProtocol]! ! !TClient methodsFor: 'as yet unclassified' stamp: 'pc 10/26/2007 04:28'! nextSeqid ^ seqid ifNil: [seqid := 0] ifNotNil: [seqid := seqid + 1]! ! !TClient methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:51'! outProtocol: aProtocol oprot := aProtocol! ! !TClient methodsFor: 'as yet unclassified' stamp: 'pc 10/28/2007 15:32'! validateRemoteMessage: aMsg remoteSeqid ifNil: [remoteSeqid := aMsg seqid] ifNotNil: [(remoteSeqid + 1) = aMsg seqid ifFalse: [TProtocolError signal: 'Bad seqid: ', aMsg seqid asString, '; wanted: ', remoteSeqid asString]. remoteSeqid := aMsg seqid]! ! Object subclass: #TField instanceVariableNames: 'name type id' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! !TField methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:05'! id ^ id ifNil: [0]! ! !TField methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:44'! id: anInteger id := anInteger! ! !TField methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:04'! name ^ name ifNil: ['']! ! !TField methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:44'! name: anObject name := anObject! ! !TField methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:05'! type ^ type ifNil: [TType stop]! ! !TField methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:44'! type: anInteger type := anInteger! ! Object subclass: #TMessage instanceVariableNames: 'name seqid type' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! TMessage subclass: #TCallMessage instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! !TCallMessage methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:53'! type ^ 1! ! !TMessage methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:05'! name ^ name ifNil: ['']! ! !TMessage methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:35'! name: aString name := aString! ! !TMessage methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:05'! seqid ^ seqid ifNil: [0]! ! !TMessage methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:35'! seqid: anInteger seqid := anInteger! ! !TMessage methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:06'! type ^ type ifNil: [0]! ! !TMessage methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:35'! type: anInteger type := anInteger! ! Object subclass: #TProtocol instanceVariableNames: 'transport' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! TProtocol subclass: #TBinaryProtocol instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 11/1/2007 04:24'! intFromByteArray: buf | vals | vals := Array new: buf size. 1 to: buf size do: [:n | vals at: n put: ((buf at: n) bitShift: (buf size - n) * 8)]. ^ vals sum! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 18:46'! readBool ^ self readByte isZero not! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/25/2007 00:02'! readByte ^ (self transport read: 1) first! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/28/2007 16:24'! readDouble | val | val := Float new: 2. ^ val basicAt: 1 put: (self readRawInt: 4); basicAt: 2 put: (self readRawInt: 4); yourself! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 20:02'! readFieldBegin | field | field := TField new type: self readByte. ^ field type = TType stop ifTrue: [field] ifFalse: [field id: self readI16; yourself]! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:15'! readI16 ^ self readInt: 2! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:20'! readI32 ^ self readInt: 4! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:20'! readI64 ^ self readInt: 8! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 11/1/2007 02:35'! readInt: size | buf val | buf := transport read: size. val := self intFromByteArray: buf. ^ buf first > 16r7F ifTrue: [self unsignedInt: val size: size] ifFalse: [val]! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:57'! readListBegin ^ TList new elemType: self readByte; size: self readI32! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:58'! readMapBegin ^ TMap new keyType: self readByte; valueType: self readByte; size: self readI32! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 11/1/2007 04:22'! readMessageBegin | version | version := self readI32. (version bitAnd: self versionMask) = self version1 ifFalse: [TProtocolError signalWithCode: TProtocolError badVersion]. ^ TMessage new type: (version bitAnd: 16r000000FF); name: self readString; seqid: self readI32! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 10/28/2007 16:24'! readRawInt: size ^ self intFromByteArray: (transport read: size)! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 11/1/2007 00:59'! readSetBegin "element type, size" ^ TSet new elemType: self readByte; size: self readI32! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 02/07/2009 19:00'! readString | sz | sz := self readI32. ^ sz > 0 ifTrue: [(transport read: sz) asString] ifFalse: ['']! ! !TBinaryProtocol methodsFor: 'reading' stamp: 'pc 11/1/2007 04:22'! unsignedInt: val size: size ^ 0 - ((val - 1) bitXor: ((2 raisedTo: (size * 8)) - 1))! ! !TBinaryProtocol methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:13'! version1 ^ 16r80010000 ! ! !TBinaryProtocol methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 18:01'! versionMask ^ 16rFFFF0000! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 18:35'! write: aString transport write: aString! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:23'! writeBool: bool bool ifTrue: [self writeByte: 1] ifFalse: [self writeByte: 0]! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/26/2007 09:31'! writeByte: aNumber aNumber > 16rFF ifTrue: [TError signal: 'writeByte too big']. transport write: (Array with: aNumber)! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/28/2007 16:16'! writeDouble: aDouble self writeI32: (aDouble basicAt: 1); writeI32: (aDouble basicAt: 2)! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:56'! writeField: aField self writeByte: aField type; writeI16: aField id! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/25/2007 00:01'! writeFieldBegin: aField self writeByte: aField type. self writeI16: aField id! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 18:04'! writeFieldStop self writeByte: TType stop! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 11/1/2007 02:06'! writeI16: i16 self writeInt: i16 size: 2! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 11/1/2007 02:06'! writeI32: i32 self writeInt: i32 size: 4! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 11/1/2007 02:06'! writeI64: i64 self writeInt: i64 size: 8! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 11/1/2007 04:23'! writeInt: val size: size 1 to: size do: [:n | self writeByte: ((val bitShift: (size negated + n) * 8) bitAnd: 16rFF)]! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 11/1/2007 00:48'! writeListBegin: aList self writeByte: aList elemType; writeI32: aList size! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:55'! writeMapBegin: aMap self writeByte: aMap keyType; writeByte: aMap valueType; writeI32: aMap size! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 20:36'! writeMessageBegin: msg self writeI32: (self version1 bitOr: msg type); writeString: msg name; writeI32: msg seqid! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 11/1/2007 00:56'! writeSetBegin: aSet self writeByte: aSet elemType; writeI32: aSet size! ! !TBinaryProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 18:35'! writeString: aString self writeI32: aString size; write: aString! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readBool! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readByte! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readDouble! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readFieldBegin! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readFieldEnd! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readI16! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readI32! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readI64! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readListBegin! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readListEnd! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readMapBegin! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readMapEnd! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:39'! readMessageBegin! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:39'! readMessageEnd! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readSetBegin! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readSetEnd! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/25/2007 16:10'! readSimpleType: aType aType = TType bool ifTrue: [^ self readBool]. aType = TType byte ifTrue: [^ self readByte]. aType = TType double ifTrue: [^ self readDouble]. aType = TType i16 ifTrue: [^ self readI16]. aType = TType i32 ifTrue: [^ self readI32]. aType = TType i64 ifTrue: [^ self readI64]. aType = TType list ifTrue: [^ self readBool].! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readString! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readStructBegin ! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/24/2007 19:40'! readStructEnd! ! !TProtocol methodsFor: 'reading' stamp: 'pc 10/26/2007 21:34'! skip: aType aType = TType stop ifTrue: [^ self]. aType = TType bool ifTrue: [^ self readBool]. aType = TType byte ifTrue: [^ self readByte]. aType = TType i16 ifTrue: [^ self readI16]. aType = TType i32 ifTrue: [^ self readI32]. aType = TType i64 ifTrue: [^ self readI64]. aType = TType string ifTrue: [^ self readString]. aType = TType double ifTrue: [^ self readDouble]. aType = TType struct ifTrue: [| field | self readStructBegin. [(field := self readFieldBegin) type = TType stop] whileFalse: [self skip: field type. self readFieldEnd]. ^ self readStructEnd]. aType = TType map ifTrue: [| map | map := self readMapBegin. map size timesRepeat: [self skip: map keyType. self skip: map valueType]. ^ self readMapEnd]. aType = TType list ifTrue: [| list | list := self readListBegin. list size timesRepeat: [self skip: list elemType]. ^ self readListEnd]. aType = TType set ifTrue: [| set | set := self readSetBegin. set size timesRepeat: [self skip: set elemType]. ^ self readSetEnd]. self error: 'Unknown type'! ! !TProtocol methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 23:02'! transport ^ transport! ! !TProtocol methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:28'! transport: aTransport transport := aTransport! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeBool: aBool! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeByte: aByte! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:38'! writeDouble: aFloat! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:38'! writeFieldBegin: aField! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeFieldEnd! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeFieldStop! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeI16: i16! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeI32: i32! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeI64: i64! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:39'! writeListBegin: aList! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeListEnd! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:39'! writeMapBegin: aMap! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeMapEnd! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:36'! writeMessageBegin! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:36'! writeMessageEnd! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:39'! writeSetBegin: aSet! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeSetEnd! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:38'! writeString: aString! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:38'! writeStructBegin: aStruct! ! !TProtocol methodsFor: 'writing' stamp: 'pc 10/24/2007 19:37'! writeStructEnd! ! Object subclass: #TResult instanceVariableNames: 'success oprot iprot exception' classVariableNames: '' poolDictionaries: '' category: 'Thrift'! !TResult methodsFor: 'as yet unclassified' stamp: 'pc 10/26/2007 21:35'! exception ^ exception! ! !TResult methodsFor: 'as yet unclassified' stamp: 'pc 10/26/2007 21:35'! exception: anError exception := anError! ! !TResult methodsFor: 'as yet unclassified' stamp: 'pc 10/26/2007 14:43'! success ^ success! ! !TResult methodsFor: 'as yet unclassified' stamp: 'pc 10/26/2007 14:43'! success: anObject success := anObject! ! Object subclass: #TSizedObject instanceVariableNames: 'size' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! TSizedObject subclass: #TList instanceVariableNames: 'elemType' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! !TList methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:04'! elemType ^ elemType ifNil: [TType stop]! ! !TList methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:42'! elemType: anInteger elemType := anInteger! ! TList subclass: #TSet instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! TSizedObject subclass: #TMap instanceVariableNames: 'keyType valueType' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! !TMap methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:04'! keyType ^ keyType ifNil: [TType stop]! ! !TMap methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:45'! keyType: anInteger keyType := anInteger! ! !TMap methodsFor: 'accessing' stamp: 'pc 10/24/2007 20:04'! valueType ^ valueType ifNil: [TType stop]! ! !TMap methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:45'! valueType: anInteger valueType := anInteger! ! !TSizedObject methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 20:03'! size ^ size ifNil: [0]! ! !TSizedObject methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 20:06'! size: anInteger size := anInteger! ! Object subclass: #TSocket instanceVariableNames: 'host port stream' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Transport'! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:34'! close self isOpen ifTrue: [stream close]! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:23'! connect ^ (self socketStream openConnectionToHost: (NetNameResolver addressForName: host) port: port) timeout: 180; binary; yourself! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 20:35'! flush stream flush! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:08'! host: aString host := aString! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 20:34'! isOpen ^ stream isNil not and: [stream socket isConnected] and: [stream socket isOtherEndClosed not]! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:22'! open stream := self connect! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:09'! port: anInteger port := anInteger! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:17'! read: size | data | [data := stream next: size. data isEmpty ifTrue: [TTransportError signal: 'Could not read ', size asString, ' bytes']. ^ data] on: ConnectionClosed do: [TTransportClosedError signal]! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:18'! socketStream ^ Smalltalk at: #FastSocketStream ifAbsent: [SocketStream] ! ! !TSocket methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 22:17'! write: aCollection [stream nextPutAll: aCollection] on: ConnectionClosed do: [TTransportClosedError signal]! ! Object subclass: #TStruct instanceVariableNames: 'name' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Protocol'! !TStruct methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:47'! name ^ name! ! !TStruct methodsFor: 'accessing' stamp: 'pc 10/24/2007 19:47'! name: aString name := aString! ! Object subclass: #TTransport instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift-Transport'! !TTransport methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:18'! close self subclassResponsibility! ! !TTransport methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:22'! flush self subclassResponsibility! ! !TTransport methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:18'! isOpen self subclassResponsibility! ! !TTransport methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:18'! open self subclassResponsibility! ! !TTransport methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:18'! read: anInteger self subclassResponsibility! ! !TTransport methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:22'! readAll: anInteger ^ String streamContents: [:str | [str size < anInteger] whileTrue: [str nextPutAll: (self read: anInteger - str size)]]! ! !TTransport methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:22'! write: aString self subclassResponsibility! ! Object subclass: #TType instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Thrift'! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:03'! bool ^ 2! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:03'! byte ^ 3! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/25/2007 15:55'! codeOf: aTypeName self typeMap do: [:each | each first = aTypeName ifTrue: [^ each second]]. ^ nil! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:03'! double ^ 4! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! i16 ^ 6! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! i32 ^ 8! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! i64 ^ 10! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! list ^ 15! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! map ^ 13! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/25/2007 15:56'! nameOf: aTypeCode self typeMap do: [:each | each second = aTypeCode ifTrue: [^ each first]]. ^ nil! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! set ^ 14! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:03'! stop ^ 0! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! string ^ 11! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:04'! struct ^ 12! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/25/2007 15:51'! typeMap ^ #((bool 2) (byte 3) (double 4) (i16 6) (i32 8) (i64 10) (list 15) (map 13) (set 15) (stop 0) (string 11) (struct 12) (void 1))! ! !TType class methodsFor: 'as yet unclassified' stamp: 'pc 10/24/2007 17:03'! void ^ 1! ! thrift-0.23.0/lib/st/README.md0000664000175000017500000000240315165535636016047 0ustar00buildbuild00000000000000Thrift SmallTalk Software Library Last updated Nov 2007 License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Contains some contributions under the Thrift Software License. Please see doc/old-thrift-license.txt in the Thrift distribution for details. Library ======= To get started, just file in thrift.st with Squeak, run thrift -st on the tutorial .thrift files (and file in the resulting code), and then: calc := CalculatorClient binaryOnHost: 'localhost' port: '9090' calc addNum1: 10 num2: 15 Tested in Squeak 3.7, but should work fine with anything later. thrift-0.23.0/lib/lua/0000755000175000017500000000000015170007201014674 5ustar00buildbuild00000000000000thrift-0.23.0/lib/lua/TJsonProtocol.lua0000664000175000017500000004504315165535636020214 0ustar00buildbuild00000000000000-- -- 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. -- require 'TProtocol' local libluabpack = require 'libluabpack' local libluabitwise = require 'libluabitwise' local liblualongnumber = require 'liblualongnumber' TJSONProtocol = __TObject.new(TProtocolBase, { __type = 'TJSONProtocol', THRIFT_JSON_PROTOCOL_VERSION = 1, jsonContext = {}, jsonContextVal = {first = true, colon = true, ttype = 2, null = true}, jsonContextIndex = 1, hasReadByte = "" }) TTypeToString = {} TTypeToString[TType.BOOL] = "tf" TTypeToString[TType.BYTE] = "i8" TTypeToString[TType.I16] = "i16" TTypeToString[TType.I32] = "i32" TTypeToString[TType.I64] = "i64" TTypeToString[TType.DOUBLE] = "dbl" TTypeToString[TType.STRING] = "str" TTypeToString[TType.STRUCT] = "rec" TTypeToString[TType.LIST] = "lst" TTypeToString[TType.SET] = "set" TTypeToString[TType.MAP] = "map" TTypeToString[TType.UUID] = "uid" StringToTType = { tf = TType.BOOL, i8 = TType.BYTE, i16 = TType.I16, i32 = TType.I32, i64 = TType.I64, dbl = TType.DOUBLE, str = TType.STRING, rec = TType.STRUCT, map = TType.MAP, set = TType.SET, lst = TType.LIST, uid = TType.UUID, } JSONNode = { ObjectBegin = '{', ObjectEnd = '}', ArrayBegin = '[', ArrayEnd = ']', PairSeparator = ':', ElemSeparator = ',', Backslash = '\\', StringDelimiter = '"', ZeroChar = '0', EscapeChar = 'u', Nan = 'NaN', Infinity = 'Infinity', NegativeInfinity = '-Infinity', EscapeChars = "\"\\bfnrt", EscapePrefix = "\\u00" } EscapeCharVals = { '"', '\\', '\b', '\f', '\n', '\r', '\t' } JSONCharTable = { --0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 0, 0, 0, 0, 0, 0, 0, 98,116,110, 0,102,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, } -- character table string local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' -- encoding function base64_encode(data) return ((data:gsub('.', function(x) local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end return r; end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) if (#x < 6) then return '' end local c=0 for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end return b:sub(c+1,c+1) end)..({ '', '==', '=' })[#data%3+1]) end -- decoding function base64_decode(data) data = string.gsub(data, '[^'..b..'=]', '') return (data:gsub('.', function(x) if (x == '=') then return '' end local r,f='',(b:find(x)-1) for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end return r; end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x) if (#x ~= 8) then return '' end local c=0 for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end return string.char(c) end)) end function TJSONProtocol:resetContext() self.jsonContext = {} self.jsonContextVal = {first = true, colon = true, ttype = 2, null = true} self.jsonContextIndex = 1 end function TJSONProtocol:contextPush(context) self.jsonContextIndex = self.jsonContextIndex + 1 self.jsonContext[self.jsonContextIndex] = self.jsonContextVal self.jsonContextVal = context end function TJSONProtocol:contextPop() self.jsonContextVal = self.jsonContext[self.jsonContextIndex] self.jsonContextIndex = self.jsonContextIndex - 1 end function TJSONProtocol:escapeNum() if self.jsonContextVal.ttype == 1 then return self.jsonContextVal.colon else return false end end function TJSONProtocol:writeElemSeparator() if self.jsonContextVal.null then return end if self.jsonContextVal.first then self.jsonContextVal.first = false else if self.jsonContextVal.ttype == 1 then if self.jsonContextVal.colon then self.trans:write(JSONNode.PairSeparator) self.jsonContextVal.colon = false else self.trans:write(JSONNode.ElemSeparator) self.jsonContextVal.colon = true end else self.trans:write(JSONNode.ElemSeparator) end end end function TJSONProtocol:hexChar(val) val = libluabitwise.band(val, 0x0f) if val < 10 then return val + 48 else return val + 87 end end function TJSONProtocol:writeJSONEscapeChar(ch) self.trans:write(JSONNode.EscapePrefix) local outCh = hexChar(libluabitwise.shiftr(ch, 4)) local buff = libluabpack.bpack('c', outCh) self.trans:write(buff) outCh = hexChar(ch) buff = libluabpack.bpack('c', outCh) self.trans:write(buff) end function TJSONProtocol:writeJSONChar(byte) ch = string.byte(byte) if ch >= 0x30 then if ch == JSONNode.Backslash then self.trans:write(JSONNode.Backslash) self.trans:write(JSONNode.Backslash) else self.trans:write(byte) end else local outCh = JSONCharTable[ch+1] if outCh == 1 then self.trans:write(byte) elseif outCh > 1 then self.trans:write(JSONNode.Backslash) local buff = libluabpack.bpack('c', outCh) self.trans:write(buff) else self:writeJSONEscapeChar(ch) end end end function TJSONProtocol:writeJSONString(str) self:writeElemSeparator() self.trans:write(JSONNode.StringDelimiter) -- TODO escape special characters local length = string.len(str) local ii = 1 while ii <= length do self:writeJSONChar(string.sub(str, ii, ii)) ii = ii + 1 end self.trans:write(JSONNode.StringDelimiter) end function TJSONProtocol:writeJSONBase64(str) self:writeElemSeparator() self.trans:write(JSONNode.StringDelimiter) local length = string.len(str) local offset = 1 while length >= 3 do -- Encode 3 bytes at a time local bytes = base64_encode(string.sub(str, offset, offset+3)) self.trans:write(bytes) length = length - 3 offset = offset + 3 end if length > 0 then local bytes = base64_encode(string.sub(str, offset, offset+length)) self.trans:write(bytes) end self.trans:write(JSONNode.StringDelimiter) end function TJSONProtocol:writeJSONInteger(num) self:writeElemSeparator() if self:escapeNum() then self.trans:write(JSONNode.StringDelimiter) end local numstr = "" .. num numstr = string.sub(numstr, string.find(numstr, "^[+-]?%d+")) self.trans:write(numstr) if self:escapeNum() then self.trans:write(JSONNode.StringDelimiter) end end function TJSONProtocol:writeJSONDouble(dub) self:writeElemSeparator() local val = "" .. dub local prefix = string.sub(val, 1, 1) local special = false if prefix == 'N' or prefix == 'n' then val = JSONNode.Nan special = true elseif prefix == 'I' or prefix == 'i' then val = JSONNode.Infinity special = true elseif prefix == '-' then local secondByte = string.sub(val, 2, 2) if secondByte == 'I' or secondByte == 'i' then val = JSONNode.NegativeInfinity special = true end end if special or self:escapeNum() then self.trans:write(JSONNode.StringDelimiter) end self.trans:write(val) if special or self:escapeNum() then self.trans:write(JSONNode.StringDelimiter) end end function TJSONProtocol:writeJSONObjectBegin() self:writeElemSeparator() self.trans:write(JSONNode.ObjectBegin) self:contextPush({first = true, colon = true, ttype = 1, null = false}) end function TJSONProtocol:writeJSONObjectEnd() self:contextPop() self.trans:write(JSONNode.ObjectEnd) end function TJSONProtocol:writeJSONArrayBegin() self:writeElemSeparator() self.trans:write(JSONNode.ArrayBegin) self:contextPush({first = true, colon = true, ttype = 2, null = false}) end function TJSONProtocol:writeJSONArrayEnd() self:contextPop() self.trans:write(JSONNode.ArrayEnd) end function TJSONProtocol:writeMessageBegin(name, ttype, seqid) self:resetContext() self:writeJSONArrayBegin() self:writeJSONInteger(TJSONProtocol.THRIFT_JSON_PROTOCOL_VERSION) self:writeJSONString(name) self:writeJSONInteger(ttype) self:writeJSONInteger(seqid) end function TJSONProtocol:writeMessageEnd() self:writeJSONArrayEnd() end function TJSONProtocol:writeStructBegin(name) self:writeJSONObjectBegin() end function TJSONProtocol:writeStructEnd() self:writeJSONObjectEnd() end function TJSONProtocol:writeFieldBegin(name, ttype, id) self:writeJSONInteger(id) self:writeJSONObjectBegin() self:writeJSONString(TTypeToString[ttype]) end function TJSONProtocol:writeFieldEnd() self:writeJSONObjectEnd() end function TJSONProtocol:writeFieldStop() end function TJSONProtocol:writeMapBegin(ktype, vtype, size) self:writeJSONArrayBegin() self:writeJSONString(TTypeToString[ktype]) self:writeJSONString(TTypeToString[vtype]) self:writeJSONInteger(size) return self:writeJSONObjectBegin() end function TJSONProtocol:writeMapEnd() self:writeJSONObjectEnd() self:writeJSONArrayEnd() end function TJSONProtocol:writeListBegin(etype, size) self:writeJSONArrayBegin() self:writeJSONString(TTypeToString[etype]) self:writeJSONInteger(size) end function TJSONProtocol:writeListEnd() self:writeJSONArrayEnd() end function TJSONProtocol:writeSetBegin(etype, size) self:writeJSONArrayBegin() self:writeJSONString(TTypeToString[etype]) self:writeJSONInteger(size) end function TJSONProtocol:writeSetEnd() self:writeJSONArrayEnd() end function TJSONProtocol:writeBool(bool) if bool then self:writeJSONInteger(1) else self:writeJSONInteger(0) end end function TJSONProtocol:writeByte(byte) local buff = libluabpack.bpack('c', byte) local val = libluabpack.bunpack('c', buff) self:writeJSONInteger(val) end function TJSONProtocol:writeI16(i16) local buff = libluabpack.bpack('s', i16) local val = libluabpack.bunpack('s', buff) self:writeJSONInteger(val) end function TJSONProtocol:writeI32(i32) local buff = libluabpack.bpack('i', i32) local val = libluabpack.bunpack('i', buff) self:writeJSONInteger(val) end function TJSONProtocol:writeI64(i64) local buff = libluabpack.bpack('l', i64) local val = libluabpack.bunpack('l', buff) self:writeJSONInteger(tostring(val)) end function TJSONProtocol:writeDouble(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) end function TJSONProtocol:readJSONSyntaxChar(ch) local ch2 = "" if self.hasReadByte ~= "" then ch2 = self.hasReadByte self.hasReadByte = "" else ch2 = self.trans:readAll(1) end if ch2 ~= ch then terror(TProtocolException:new{message = "Expected ".. ch .. ", got " .. ch2}) end end function TJSONProtocol:readElemSeparator() if self.jsonContextVal.null then return end if self.jsonContextVal.first then self.jsonContextVal.first = false else if self.jsonContextVal.ttype == 1 then if self.jsonContextVal.colon then self:readJSONSyntaxChar(JSONNode.PairSeparator) self.jsonContextVal.colon = false else self:readJSONSyntaxChar(JSONNode.ElemSeparator) self.jsonContextVal.colon = true end else self:readJSONSyntaxChar(JSONNode.ElemSeparator) end end end function TJSONProtocol:hexVal(ch) local val = string.byte(ch) if val >= 48 and val <= 57 then return val - 48 elseif val >= 97 and val <= 102 then return val - 87 else terror(TProtocolException:new{message = "Expected hex val ([0-9a-f]); got " .. ch}) end end function TJSONProtocol:readJSONEscapeChar(ch) self:readJSONSyntaxChar(JSONNode.ZeroChar) self:readJSONSyntaxChar(JSONNode.ZeroChar) local b1 = self.trans:readAll(1) local b2 = self.trans:readAll(1) return libluabitwise.shiftl(self:hexVal(b1), 4) + self:hexVal(b2) end function TJSONProtocol:readJSONString() self:readElemSeparator() self:readJSONSyntaxChar(JSONNode.StringDelimiter) local result = "" while true do local ch = self.trans:readAll(1) if ch == JSONNode.StringDelimiter then break end if ch == JSONNode.Backslash then ch = self.trans:readAll(1) if ch == JSONNode.EscapeChar then self:readJSONEscapeChar(ch) else local pos, _ = string.find(JSONNode.EscapeChars, ch) if pos == nil then terror(TProtocolException:new{message = "Expected control char, got " .. ch}) end ch = EscapeCharVals[pos] end end result = result .. ch end return result end function TJSONProtocol:readJSONBase64() local result = self:readJSONString() local length = string.len(result) local str = "" local offset = 1 while length >= 4 do local bytes = string.sub(result, offset, offset+4) str = str .. base64_decode(bytes) offset = offset + 4 length = length - 4 end if length >= 0 then str = str .. base64_decode(string.sub(result, offset, offset + length)) end return str end function TJSONProtocol:readJSONNumericChars() local result = "" while true do local ch = self.trans:readAll(1) if string.find(ch, '[-+0-9.Ee]') then result = result .. ch else self.hasReadByte = ch break end end return result end function TJSONProtocol:readJSONLongInteger() self:readElemSeparator() if self:escapeNum() then self:readJSONSyntaxChar(JSONNode.StringDelimiter) end local result = self:readJSONNumericChars() if self:escapeNum() then self:readJSONSyntaxChar(JSONNode.StringDelimiter) end return result end function TJSONProtocol:readJSONInteger() return tonumber(self:readJSONLongInteger()) end function TJSONProtocol:readJSONDouble() self:readElemSeparator() local delimiter = self.trans:readAll(1) local num = 0.0 if delimiter == JSONNode.StringDelimiter then local str = self:readJSONString() if str == JSONNode.Nan then num = 1.0 elseif str == JSONNode.Infinity then num = math.maxinteger elseif str == JSONNode.NegativeInfinity then num = math.mininteger else num = tonumber(str) end else if self:escapeNum() then self:readJSONSyntaxChar(JSONNode.StringDelimiter) end local result = self:readJSONNumericChars() num = tonumber(delimiter.. result) end return num end function TJSONProtocol:readJSONObjectBegin() self:readElemSeparator() self:readJSONSyntaxChar(JSONNode.ObjectBegin) self:contextPush({first = true, colon = true, ttype = 1, null = false}) end function TJSONProtocol:readJSONObjectEnd() self:readJSONSyntaxChar(JSONNode.ObjectEnd) self:contextPop() end function TJSONProtocol:readJSONArrayBegin() self:readElemSeparator() self:readJSONSyntaxChar(JSONNode.ArrayBegin) self:contextPush({first = true, colon = true, ttype = 2, null = false}) end function TJSONProtocol:readJSONArrayEnd() self:readJSONSyntaxChar(JSONNode.ArrayEnd) self:contextPop() end function TJSONProtocol:readMessageBegin() self:resetContext() self:readJSONArrayBegin() local version = self:readJSONInteger() if version ~= self.THRIFT_JSON_PROTOCOL_VERSION then terror(TProtocolException:new{message = "Message contained bad version."}) end local name = self:readJSONString() local ttype = self:readJSONInteger() local seqid = self:readJSONInteger() return name, ttype, seqid end function TJSONProtocol:readMessageEnd() self:readJSONArrayEnd() end function TJSONProtocol:readStructBegin() self:readJSONObjectBegin() return nil end function TJSONProtocol:readStructEnd() self:readJSONObjectEnd() end function TJSONProtocol:readFieldBegin() local ttype = TType.STOP local id = 0 local ch = self.trans:readAll(1) self.hasReadByte = ch if ch ~= JSONNode.ObjectEnd then id = self:readJSONInteger() self:readJSONObjectBegin() local typeName = self:readJSONString() ttype = StringToTType[typeName] end return nil, ttype, id end function TJSONProtocol:readFieldEnd() self:readJSONObjectEnd() end function TJSONProtocol:readMapBegin() self:readJSONArrayBegin() local typeName = self:readJSONString() local ktype = StringToTType[typeName] typeName = self:readJSONString() local vtype = StringToTType[typeName] local size = self:readJSONInteger() self:readJSONObjectBegin() return ktype, vtype, size end function TJSONProtocol:readMapEnd() self:readJSONObjectEnd() self:readJSONArrayEnd() end function TJSONProtocol:readListBegin() self:readJSONArrayBegin() local typeName = self:readJSONString() local etype = StringToTType[typeName] local size = self:readJSONInteger() return etype, size end function TJSONProtocol:readListEnd() return self:readJSONArrayEnd() end function TJSONProtocol:readSetBegin() return self:readListBegin() end function TJSONProtocol:readSetEnd() return self:readJSONArrayEnd() end function TJSONProtocol:readBool() local result = self:readJSONInteger() if result == 1 then return true else return false end end function TJSONProtocol:readByte() local result = self:readJSONInteger() if result >= 256 then terror(TProtocolException:new{message = "UnExpected Byte " .. result}) end return result end function TJSONProtocol:readI16() return self:readJSONInteger() end function TJSONProtocol:readI32() return self:readJSONInteger() end function TJSONProtocol:readI64() local long = liblualongnumber.new return long(self:readJSONLongInteger()) end function TJSONProtocol:readDouble() return self:readJSONDouble() end function TJSONProtocol:readString() return self:readJSONString() end function TJSONProtocol:readUuid() return TUUIDfromString(self:readJSONString()) end function TJSONProtocol:readBinary() return self:readJSONBase64() end TJSONProtocolFactory = TProtocolFactory:new{ __type = 'TJSONProtocolFactory', } function TJSONProtocolFactory:getProtocol(trans) -- TODO Enforce that this must be a transport class (ie not a bool) if not trans then terror(TProtocolException:new{ message = 'Must supply a transport to ' .. ttype(self) }) end return TJSONProtocol:new{ trans = trans } end thrift-0.23.0/lib/lua/TTransport.lua0000664000175000017500000000551515165535636017555 0ustar00buildbuild00000000000000-- -- 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. -- require 'Thrift' TTransportException = TException:new { UNKNOWN = 0, NOT_OPEN = 1, ALREADY_OPEN = 2, TIMED_OUT = 3, END_OF_FILE = 4, INVALID_FRAME_SIZE = 5, INVALID_TRANSFORM = 6, INVALID_CLIENT_TYPE = 7, errorCode = 0, __type = 'TTransportException' } function TTransportException:__errorCodeToString() if self.errorCode == self.NOT_OPEN then return 'Transport not open' elseif self.errorCode == self.ALREADY_OPEN then return 'Transport already open' elseif self.errorCode == self.TIMED_OUT then return 'Transport timed out' elseif self.errorCode == self.END_OF_FILE then return 'End of file' elseif self.errorCode == self.INVALID_FRAME_SIZE then return 'Invalid frame size' elseif self.errorCode == self.INVALID_TRANSFORM then return 'Invalid transform' elseif self.errorCode == self.INVALID_CLIENT_TYPE then return 'Invalid client type' else return 'Default (unknown)' end end TTransportBase = __TObject:new{ __type = 'TTransportBase' } function TTransportBase:isOpen() end function TTransportBase:open() end function TTransportBase:close() end function TTransportBase:read(len) end function TTransportBase:readAll(len) local buf, have, chunk = '', 0 while have < len do chunk = self:read(len - have) have = have + string.len(chunk) buf = buf .. chunk if string.len(chunk) == 0 then terror(TTransportException:new{ errorCode = TTransportException.END_OF_FILE }) end end 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{ __type = 'TServerTransportBase' } function TServerTransportBase:listen() end function TServerTransportBase:accept() end function TServerTransportBase:close() end TTransportFactoryBase = __TObject:new{ __type = 'TTransportFactoryBase' } function TTransportFactoryBase:getTransport(trans) return trans end thrift-0.23.0/lib/lua/TServer.lua0000664000175000017500000001012515165535636017020 0ustar00buildbuild00000000000000-- -- 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. -- require 'Thrift' require 'TFramedTransport' require 'TBinaryProtocol' -- TServer TServer = __TObject:new{ __type = 'TServer' } -- 2 possible constructors -- 1. {processor, serverTransport} -- 2. {processor, serverTransport, transportFactory, protocolFactory} function TServer:new(args) if ttype(args) ~= 'table' then error('TServer must be initialized with a table') end if args.processor == nil then terror('You must provide ' .. ttype(self) .. ' with a processor') end if args.serverTransport == nil then terror('You must provide ' .. ttype(self) .. ' with a serverTransport') end -- Create the object local obj = __TObject.new(self, args) if obj.transportFactory then obj.inputTransportFactory = obj.transportFactory obj.outputTransportFactory = obj.transportFactory obj.transportFactory = nil else obj.inputTransportFactory = TFramedTransportFactory:new{} obj.outputTransportFactory = obj.inputTransportFactory end if obj.protocolFactory then obj.inputProtocolFactory = obj.protocolFactory obj.outputProtocolFactory = obj.protocolFactory obj.protocolFactory = nil else obj.inputProtocolFactory = TBinaryProtocolFactory:new{} obj.outputProtocolFactory = obj.inputProtocolFactory end -- Set the __server variable in the handler so we can stop the server obj.processor.handler.__server = self return obj end function TServer:setServerEventHandler(handler) self.serverEventHandler = handler end function TServer:_clientBegin(content, iprot, oprot) if self.serverEventHandler and type(self.serverEventHandler.clientBegin) == 'function' then self.serverEventHandler:clientBegin(iprot, oprot) end end function TServer:_preServe() if self.serverEventHandler and type(self.serverEventHandler.preServe) == 'function' then self.serverEventHandler:preServe(self.serverTransport:getSocketInfo()) end end function TServer:setExceptionHandler(exceptionHandler) self.exceptionHandler = exceptionHandler end function TServer:_handleException(err) if string.find(err, 'TTransportException') == nil then if self.exceptionHandler then self.exceptionHandler(err) else print(err) end end end function TServer:serve() end function TServer:handle(client) local itrans, otrans = self.inputTransportFactory:getTransport(client), self.outputTransportFactory:getTransport(client) local iprot, oprot = self.inputProtocolFactory:getProtocol(itrans), self.outputProtocolFactory:getProtocol(otrans) self:_clientBegin(iprot, oprot) while true do local ret, err = pcall(self.processor.process, self.processor, iprot, oprot) if ret == false and err then if not string.find(err, "TTransportException") then self:_handleException(err) end break end end itrans:close() otrans:close() end function TServer:close() self.serverTransport:close() end -- TSimpleServer -- Single threaded server that handles one transport (connection) TSimpleServer = __TObject:new(TServer, { __type = 'TSimpleServer', __stop = false }) function TSimpleServer:serve() self.serverTransport:listen() self:_preServe() while not self.__stop do client = self.serverTransport:accept() self:handle(client) end self:close() end function TSimpleServer:stop() self.__stop = true end thrift-0.23.0/lib/lua/src/0000755000175000017500000000000015170007201015463 5ustar00buildbuild00000000000000thrift-0.23.0/lib/lua/src/luabitwise.c0000664000175000017500000000624615165535636020037 0ustar00buildbuild00000000000000// // 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 static int l_not(lua_State *L) { int a = luaL_checkinteger(L, 1); a = ~a; lua_pushnumber(L, a); 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); a ^= b; lua_pushnumber(L, a); 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); a &= b; lua_pushnumber(L, a); 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); a |= b; lua_pushnumber(L, a); 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); a = a >> b; lua_pushnumber(L, a); 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); a = a << b; lua_pushnumber(L, a); 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; } thrift-0.23.0/lib/lua/src/usocket.c0000664000175000017500000002601215165535636017335 0ustar00buildbuild00000000000000// // 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 #include #include #include #include // TODO REMOVE #include "socket.h" //////////////////////////////////////////////////////////////////////////////// // Private // Num seconds since Jan 1 1970 (UTC) #ifdef _WIN32 // SOL #else double __gettime() { struct timeval v; gettimeofday(&v, (struct timezone*) NULL); return v.tv_sec + v.tv_usec/1.0e6; } #endif #define WAIT_MODE_R 1 #define WAIT_MODE_W 2 #define WAIT_MODE_C (WAIT_MODE_R|WAIT_MODE_W) T_ERRCODE socket_wait(p_socket sock, int mode, int timeout) { int ret = 0; fd_set rfds, wfds; struct timeval tv; double end, t; if (!timeout) { return TIMEOUT; } end = __gettime() + timeout/1000; do { FD_ZERO(&rfds); FD_ZERO(&wfds); // Specify what I/O operations we care about if (mode & WAIT_MODE_R) { FD_SET(*sock, &rfds); } if (mode & WAIT_MODE_W) { FD_SET(*sock, &wfds); } // Check for timeout t = end - __gettime(); if (t < 0.0) { break; } // Wait tv.tv_sec = (int)t; tv.tv_usec = (int)((t - tv.tv_sec) * 1.0e6); ret = select(*sock+1, &rfds, &wfds, NULL, &tv); } while (ret == -1 && errno == EINTR); if (ret == -1) { return errno; } // Check for timeout if (ret == 0) { return TIMEOUT; } return SUCCESS; } //////////////////////////////////////////////////////////////////////////////// // General T_ERRCODE socket_create(p_socket sock, int domain, int type, int protocol) { *sock = socket(domain, type, protocol); if (*sock > 0) { return SUCCESS; } else { return errno; } } T_ERRCODE socket_destroy(p_socket sock) { // TODO Figure out if I should be free-ing this if (*sock > 0) { (void)socket_setblocking(sock); close(*sock); *sock = -1; } return SUCCESS; } T_ERRCODE socket_bind(p_socket sock, p_sa addr, int addr_len) { int ret = socket_setblocking(sock); if (ret != SUCCESS) { return ret; } if (bind(*sock, addr, addr_len)) { ret = errno; } int ret2 = socket_setnonblocking(sock); return ret == SUCCESS ? ret2 : ret; } T_ERRCODE socket_get_info(p_socket sock, short *port, char *buf, size_t len) { struct sockaddr_storage sa; memset(&sa, 0, sizeof(sa)); socklen_t addrlen = sizeof(sa); int rc = getsockname(*sock, (struct sockaddr*)&sa, &addrlen); if (!rc) { if (sa.ss_family == AF_INET6) { struct sockaddr_in6* sin = (struct sockaddr_in6*)(&sa); if (!inet_ntop(AF_INET6, &sin->sin6_addr, buf, len)) { return errno; } *port = ntohs(sin->sin6_port); } else { struct sockaddr_in* sin = (struct sockaddr_in*)(&sa); if (!inet_ntop(AF_INET, &sin->sin_addr, buf, len)) { return errno; } *port = ntohs(sin->sin_port); } return SUCCESS; } return errno; } //////////////////////////////////////////////////////////////////////////////// // Server T_ERRCODE socket_accept(p_socket sock, p_socket client, p_sa addr, socklen_t *addrlen, int timeout) { int err; if (*sock < 0) { return CLOSED; } do { *client = accept(*sock, addr, addrlen); if (*client > 0) { return SUCCESS; } } while ((err = errno) == EINTR); if (err == EAGAIN || err == ECONNABORTED) { return socket_wait(sock, WAIT_MODE_R, timeout); } return err; } T_ERRCODE socket_listen(p_socket sock, int backlog) { int ret = socket_setblocking(sock); if (ret != SUCCESS) { return ret; } if (listen(*sock, backlog)) { ret = errno; } int ret2 = socket_setnonblocking(sock); return ret == SUCCESS ? ret2 : ret; } //////////////////////////////////////////////////////////////////////////////// // Client T_ERRCODE socket_connect(p_socket sock, p_sa addr, int addr_len, int timeout) { int err; if (*sock < 0) { return CLOSED; } do { if (connect(*sock, addr, addr_len) == 0) { return SUCCESS; } } while ((err = errno) == EINTR); if (err != EINPROGRESS && err != EAGAIN) { return err; } 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; } 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) { 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; } T_ERRCODE socket_recv( p_socket sock, char *data, size_t len, int timeout, int *received) { int err, got = 0; if (*sock < 0) { return CLOSED; } *received = 0; do { got = recv(*sock, data, len, 0); if (got > 0) { *received = got; return SUCCESS; } err = errno; // Connection has been closed by peer if (got == 0) { return CLOSED; } } while (err == EINTR); if (err == EAGAIN) { return socket_wait(sock, WAIT_MODE_R, timeout); } return err; } //////////////////////////////////////////////////////////////////////////////// // Util T_ERRCODE socket_setnonblocking(p_socket sock) { int flags = fcntl(*sock, F_GETFL, 0); flags |= O_NONBLOCK; return fcntl(*sock, F_SETFL, flags) != -1 ? SUCCESS : errno; } T_ERRCODE socket_setblocking(p_socket sock) { int flags = fcntl(*sock, F_GETFL, 0); flags &= (~(O_NONBLOCK)); return fcntl(*sock, F_SETFL, flags) != -1 ? SUCCESS : errno; } //////////////////////////////////////////////////////////////////////////////// // TCP #define ERRORSTR_RETURN(err) \ if (err == SUCCESS) { \ return NULL; \ } else if (err == TIMEOUT) { \ return TIMEOUT_MSG; \ } else if (err == CLOSED) { \ return CLOSED_MSG; \ } \ return strerror(err) const char * tcp_create(p_socket sock) { // TODO support IPv6 int err = socket_create(sock, AF_INET, SOCK_STREAM, 0); ERRORSTR_RETURN(err); } const char * tcp_destroy(p_socket sock) { int err = socket_destroy(sock); ERRORSTR_RETURN(err); } const char * tcp_bind(p_socket sock, const char *host, unsigned short port) { // TODO support IPv6 int err; struct hostent *h; struct sockaddr_in local; memset(&local, 0, sizeof(local)); local.sin_family = AF_INET; local.sin_addr.s_addr = htonl(INADDR_ANY); local.sin_port = htons(port); if (strcmp(host, "*") && !inet_aton(host, &local.sin_addr)) { h = gethostbyname(host); if (!h) { return hstrerror(h_errno); } memcpy(&local.sin_addr, (struct in_addr *)h->h_addr_list[0], sizeof(struct in_addr)); } err = socket_bind(sock, (p_sa) &local, sizeof(local)); ERRORSTR_RETURN(err); } const char * tcp_listen(p_socket sock, int backlog) { int err = socket_listen(sock, backlog); ERRORSTR_RETURN(err); } const char * tcp_accept(p_socket sock, p_socket client, int timeout) { int err = socket_accept(sock, client, NULL, NULL, timeout); ERRORSTR_RETURN(err); } const char * tcp_connect(p_socket sock, const char *host, unsigned short port, int timeout) { // TODO support IPv6 int err; struct hostent *h; struct sockaddr_in remote; memset(&remote, 0, sizeof(remote)); remote.sin_family = AF_INET; remote.sin_port = htons(port); if (strcmp(host, "*") && !inet_aton(host, &remote.sin_addr)) { h = gethostbyname(host); if (!h) { return hstrerror(h_errno); } memcpy(&remote.sin_addr, (struct in_addr *)h->h_addr_list[0], sizeof(struct in_addr)); } err = socket_connect(sock, (p_sa) &remote, sizeof(remote), timeout); ERRORSTR_RETURN(err); } const char * tcp_create_and_connect(p_socket sock, const char *host, unsigned short port, int timeout) { int err; struct sockaddr_in sa4; struct sockaddr_in6 sa6; memset(&sa4, 0, sizeof(sa4)); sa4.sin_family = AF_INET; sa4.sin_port = htons(port); memset(&sa6, 0, sizeof(sa6)); sa6.sin6_family = AF_INET6; sa6.sin6_port = htons(port); if (inet_pton(AF_INET, host, &sa4.sin_addr)) { socket_create(sock, AF_INET, SOCK_STREAM, 0); err = socket_connect(sock, (p_sa) &sa4, sizeof(sa4), timeout); ERRORSTR_RETURN(err); } else if (inet_pton(AF_INET6, host, &sa6.sin6_addr)) { socket_create(sock, AF_INET6, SOCK_STREAM, 0); err = socket_connect(sock, (p_sa) &sa6, sizeof(sa6), timeout); ERRORSTR_RETURN(err); } else { struct addrinfo hints, *servinfo, *rp; char portStr[6]; int rv; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; sprintf(portStr, "%u", port); if ((rv = getaddrinfo(host, portStr, &hints, &servinfo)) != 0) { return gai_strerror(rv); } err = TIMEOUT; for (rp = servinfo; rp != NULL; rp = rp->ai_next) { err = socket_create(sock, rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (err != SUCCESS) { continue; } err = socket_connect(sock, (p_sa) rp->ai_addr, rp->ai_addrlen, timeout); if (err == SUCCESS) { break; } close(*sock); } freeaddrinfo(servinfo); if (rp == NULL) { *sock = -1; return "Failed to connect"; } else { ERRORSTR_RETURN(err); } } } #define WRITE_STEP 8192 const char * tcp_send( p_socket sock, const char * data, size_t w_len, int timeout) { int err; size_t put = 0, step; if (!w_len) { return NULL; } do { step = (WRITE_STEP < w_len - put ? WRITE_STEP : w_len - put); err = socket_send(sock, data + put, step, timeout); put += step; } while (err == SUCCESS && put < w_len); ERRORSTR_RETURN(err); } const char * tcp_raw_receive( p_socket sock, char * data, size_t r_len, int timeout, int *received) { int err = socket_recv(sock, data, r_len, timeout, received); ERRORSTR_RETURN(err); } thrift-0.23.0/lib/lua/src/socket.h0000664000175000017500000000551115165535636017156 0ustar00buildbuild00000000000000// // 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 LUA_THRIFT_SOCKET_H #define LUA_THRIFT_SOCKET_H #include #ifdef _WIN32 // SOL #else typedef int t_socket; typedef t_socket* p_socket; #endif // Error Codes enum { SUCCESS = 0, TIMEOUT = -1, CLOSED = -2, }; typedef int T_ERRCODE; static const char * TIMEOUT_MSG = "Timeout"; static const char * CLOSED_MSG = "Connection Closed"; typedef struct sockaddr t_sa; typedef t_sa * p_sa; T_ERRCODE socket_create(p_socket sock, int domain, int type, int protocol); T_ERRCODE socket_destroy(p_socket sock); T_ERRCODE socket_bind(p_socket sock, p_sa addr, int addr_len); T_ERRCODE socket_get_info(p_socket sock, short *port, char *buf, size_t len); T_ERRCODE socket_send(p_socket sock, const char *data, size_t len, int timeout); T_ERRCODE socket_recv(p_socket sock, char *data, size_t len, int timeout, int *received); T_ERRCODE socket_setblocking(p_socket sock); T_ERRCODE socket_setnonblocking(p_socket sock); T_ERRCODE socket_accept(p_socket sock, p_socket sibling, p_sa addr, socklen_t *addr_len, int timeout); T_ERRCODE socket_listen(p_socket sock, int backlog); T_ERRCODE socket_connect(p_socket sock, p_sa addr, int addr_len, int timeout); const char * tcp_create(p_socket sock); const char * tcp_destroy(p_socket sock); const char * tcp_bind(p_socket sock, const char *host, unsigned short port); const char * tcp_send(p_socket sock, const char *data, size_t w_len, int timeout); const char * tcp_receive(p_socket sock, char *data, size_t r_len, int timeout); const char * tcp_raw_receive(p_socket sock, char * data, size_t r_len, int timeout, int *received); const char * tcp_listen(p_socket sock, int backlog); const char * tcp_accept(p_socket sock, p_socket client, int timeout); const char * tcp_connect(p_socket sock, const char *host, unsigned short port, int timeout); const char * tcp_create_and_connect(p_socket sock, const char *host, unsigned short port, int timeout); #endif thrift-0.23.0/lib/lua/src/luabpack.c0000664000175000017500000002106015165535636017440 0ustar00buildbuild00000000000000// // 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 extern int64_t lualongnumber_checklong(lua_State *L, int index); extern int64_t lualongnumber_pushlong(lua_State *L, int64_t *val); // host order to network order (64-bit) static int64_t T_htonll(uint64_t data) { uint32_t d1 = htonl((uint32_t)data); uint32_t d2 = htonl((uint32_t)(data >> 32)); return ((uint64_t)d1 << 32) + (uint64_t)d2; } // network order to host order (64-bit) static int64_t T_ntohll(uint64_t data) { uint32_t d1 = ntohl((uint32_t)data); uint32_t d2 = ntohl((uint32_t)(data >> 32)); return ((uint64_t)d1 << 32) + (uint64_t)d2; } /** * bpack(type, data) * c - Signed Byte * s - Signed Short * i - Signed Int * I - Unsigned Int * l - Signed Long * d - Double */ static int l_bpack(lua_State *L) { const char *code = luaL_checkstring(L, 1); luaL_argcheck(L, code[1] == '\0', 0, "Format code must be one character."); luaL_Buffer buf; luaL_buffinit(L, &buf); switch (code[0]) { case 'c': { int8_t data = luaL_checknumber(L, 2); luaL_addlstring(&buf, (void*)&data, sizeof(data)); break; } case 's': { int16_t data = luaL_checknumber(L, 2); data = (int16_t)htons(data); luaL_addlstring(&buf, (void*)&data, sizeof(data)); break; } case 'i': { int32_t data = luaL_checkinteger(L, 2); data = (int32_t)htonl(data); 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); luaL_addlstring(&buf, (void*)&data, sizeof(data)); break; } case 'd': { double data = luaL_checknumber(L, 2); luaL_addlstring(&buf, (void*)&data, sizeof(data)); break; } default: luaL_argcheck(L, 0, 0, "Invalid format code."); } luaL_pushresult(&buf); return 1; } /** * bunpack(type, data) * c - Signed Byte * C - Unsigned Byte * s - Signed Short * i - Signed Int * I - Unsigned Int * l - Signed Long * d - Double */ static int l_bunpack(lua_State *L) { const char *code = luaL_checkstring(L, 1); luaL_argcheck(L, code[1] == '\0', 0, "Format code must be one character."); const char *data = luaL_checkstring(L, 2); #if LUA_VERSION_NUM >= 502 size_t len = lua_rawlen(L, 2); #else size_t len = lua_objlen(L, 2); #endif switch (code[0]) { case 'c': { int8_t val; luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size."); memcpy(&val, data, sizeof(val)); lua_pushnumber(L, val); break; } /** * unpack unsigned Byte. */ case 'C': { uint8_t val; luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size."); memcpy(&val, data, sizeof(val)); lua_pushnumber(L, val); break; } case 's': { int16_t val; luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size."); memcpy(&val, data, sizeof(val)); val = (int16_t)ntohs(val); lua_pushnumber(L, val); break; } case 'i': { int32_t val; luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size."); memcpy(&val, data, sizeof(val)); val = (int32_t)ntohl(val); 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."); memcpy(&val, data, sizeof(val)); val = (int64_t)T_ntohll(val); lualongnumber_pushlong(L, &val); break; } case 'd': { double val; luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size."); memcpy(&val, data, sizeof(val)); lua_pushnumber(L, val); break; } default: luaL_argcheck(L, 0, 0, "Invalid format code."); } return 1; } /** * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ static int l_i64ToZigzag(lua_State *L) { int64_t n = lualongnumber_checklong(L, 1); int64_t result = (n << 1) ^ (n >> 63); lualongnumber_pushlong(L, &result); return 1; } /** * Convert n into a zigzag int. This allows negative numbers to be * represented compactly as a varint. */ static int l_i32ToZigzag(lua_State *L) { int32_t n = luaL_checkinteger(L, 1); uint32_t result = (uint32_t)(n << 1) ^ (n >> 31); lua_pushnumber(L, result); return 1; } /** * Convert from zigzag int to int. */ static int l_zigzagToI32(lua_State *L) { uint32_t n = luaL_checkinteger(L, 1); int32_t result = (int32_t)(n >> 1) ^ (uint32_t)(-(int32_t)(n & 1)); lua_pushnumber(L, result); return 1; } /** * Convert from zigzag long to long. */ static int l_zigzagToI64(lua_State *L) { int64_t n = lualongnumber_checklong(L, 1); int64_t result = (int64_t)(n >> 1) ^ (uint64_t)(-(int64_t)(n & 1)); lualongnumber_pushlong(L, &result); return 1; } /** * Convert an i32 to a varint. Results in 1-5 bytes on the buffer. */ static int l_toVarint32(lua_State *L) { uint8_t buf[5]; uint32_t n = luaL_checkinteger(L, 1); uint32_t wsize = 0; while (1) { if ((n & ~0x7F) == 0) { buf[wsize++] = (int8_t)n; break; } else { buf[wsize++] = (int8_t)((n & 0x7F) | 0x80); n >>= 7; } } lua_pushlstring(L, buf, wsize); return 1; } /** * Convert an i64 to a varint. Results in 1-10 bytes on the buffer. */ static int l_toVarint64(lua_State *L) { uint8_t data[10]; uint64_t n = lualongnumber_checklong(L, 1); uint32_t wsize = 0; luaL_Buffer buf; luaL_buffinit(L, &buf); while (1) { if ((n & ~0x7FL) == 0) { data[wsize++] = (int8_t)n; break; } else { data[wsize++] = (int8_t)((n & 0x7F) | 0x80); n >>= 7; } } luaL_addlstring(&buf, (void*)&data, wsize); luaL_pushresult(&buf); return 1; } /** * Convert a varint to i64. */ static int l_fromVarint64(lua_State *L) { int64_t result; uint8_t byte = luaL_checknumber(L, 1); int32_t shift = luaL_checknumber(L, 2); uint64_t n = (uint64_t)lualongnumber_checklong(L, 3); n |= (uint64_t)(byte & 0x7f) << shift; if (!(byte & 0x80)) { result = (int64_t)(n >> 1) ^ (uint64_t)(-(int64_t)(n & 1)); lua_pushnumber(L, 0); } else { result = n; lua_pushnumber(L, 1); } lualongnumber_pushlong(L, &result); return 2; } /** * To pack message type of compact protocol. */ static int l_packMesgType(lua_State *L) { int32_t version_n = luaL_checkinteger(L, 1); int32_t version_mask = luaL_checkinteger(L, 2); int32_t messagetype = luaL_checkinteger(L, 3); int32_t type_shift_amount = luaL_checkinteger(L, 4); int32_t type_mask = luaL_checkinteger(L, 5); int32_t to_mesg_type = (version_n & version_mask) | (((int32_t)messagetype << type_shift_amount) & type_mask); lua_pushnumber(L, to_mesg_type); return 1; } static const struct luaL_Reg lua_bpack[] = { {"bpack", l_bpack}, {"bunpack", l_bunpack}, {"i32ToZigzag", l_i32ToZigzag}, {"i64ToZigzag", l_i64ToZigzag}, {"zigzagToI32", l_zigzagToI32}, {"zigzagToI64", l_zigzagToI64}, {"toVarint32", l_toVarint32}, {"toVarint64", l_toVarint64}, {"fromVarint64", l_fromVarint64}, {"packMesgType", l_packMesgType}, {NULL, NULL} }; 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; } thrift-0.23.0/lib/lua/src/lualongnumber.c0000664000175000017500000001277715165535636020547 0ustar00buildbuild00000000000000// // 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 #include extern const char * LONG_NUM_TYPE; extern int64_t lualongnumber_checklong(lua_State *L, int index); extern int64_t lualongnumber_pushlong(lua_State *L, int64_t *val); //////////////////////////////////////////////////////////////////////////////// static void l_serialize(char *buf, int len, int64_t val) { snprintf(buf, len, "%"PRId64, val); } static int64_t l_deserialize(const char *buf) { int64_t data; int rv; // Support hex prefixed with '0x' if (strstr(buf, "0x") == buf) { rv = sscanf(buf, "%"PRIx64, &data); } else { rv = sscanf(buf, "%"PRId64, &data); } if (rv == 1) { return data; } return 0; // Failed } //////////////////////////////////////////////////////////////////////////////// static int l_new(lua_State *L) { int64_t val; const char *str = NULL; if (lua_type(L, 1) == LUA_TSTRING) { str = lua_tostring(L, 1); val = l_deserialize(str); } else if (lua_type(L, 1) == LUA_TNUMBER) { val = (int64_t)lua_tonumber(L, 1); str = (const char *)1; } lualongnumber_pushlong(L, (str ? &val : NULL)); return 1; } //////////////////////////////////////////////////////////////////////////////// // a + b static int l_add(lua_State *L) { int64_t a, b, c; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); c = a + b; lualongnumber_pushlong(L, &c); return 1; } // a / b static int l_div(lua_State *L) { int64_t a, b, c; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); c = a / b; lualongnumber_pushlong(L, &c); return 1; } // a == b (both a and b are lualongnumber's) static int l_eq(lua_State *L) { int64_t a, b; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); lua_pushboolean(L, (a == b ? 1 : 0)); return 1; } // garbage collection static int l_gc(lua_State *L) { lua_pushnil(L); lua_setmetatable(L, 1); return 0; } // a < b static int l_lt(lua_State *L) { int64_t a, b; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); lua_pushboolean(L, (a < b ? 1 : 0)); return 1; } // a <= b static int l_le(lua_State *L) { int64_t a, b; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); lua_pushboolean(L, (a <= b ? 1 : 0)); return 1; } // a % b static int l_mod(lua_State *L) { int64_t a, b, c; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); c = a % b; lualongnumber_pushlong(L, &c); return 1; } // a * b static int l_mul(lua_State *L) { int64_t a, b, c; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); c = a * b; lualongnumber_pushlong(L, &c); return 1; } // a ^ b static int l_pow(lua_State *L) { long double a, b; int64_t c; a = (long double)lualongnumber_checklong(L, 1); b = (long double)lualongnumber_checklong(L, 2); c = (int64_t)pow(a, b); lualongnumber_pushlong(L, &c); return 1; } // a - b static int l_sub(lua_State *L) { int64_t a, b, c; a = lualongnumber_checklong(L, 1); b = lualongnumber_checklong(L, 2); c = a - b; lualongnumber_pushlong(L, &c); return 1; } // tostring() static int l_tostring(lua_State *L) { int64_t a; char str[256]; l_serialize(str, 256, lualongnumber_checklong(L, 1)); lua_pushstring(L, str); return 1; } // -a static int l_unm(lua_State *L) { int64_t a, c; a = lualongnumber_checklong(L, 1); c = -a; lualongnumber_pushlong(L, &c); return 1; } //////////////////////////////////////////////////////////////////////////////// static const luaL_Reg methods[] = { {"__add", l_add}, {"__div", l_div}, {"__eq", l_eq}, {"__gc", l_gc}, {"__lt", l_lt}, {"__le", l_le}, {"__mod", l_mod}, {"__mul", l_mul}, {"__pow", l_pow}, {"__sub", l_sub}, {"__tostring", l_tostring}, {"__unm", l_unm}, {NULL, NULL}, }; static const luaL_Reg funcs[] = { {"new", l_new}, {NULL, NULL} }; //////////////////////////////////////////////////////////////////////////////// static void set_methods(lua_State *L, const char *metatablename, const struct luaL_Reg *methods) { luaL_getmetatable(L, metatablename); // mt // No need for a __index table since everything is __* for (; methods->name; methods++) { lua_pushstring(L, methods->name); // mt, "name" lua_pushcfunction(L, methods->func); // mt, "name", func lua_rawset(L, -3); // mt } lua_pop(L, 1); } LUALIB_API int luaopen_liblualongnumber(lua_State *L) { luaL_newmetatable(L, LONG_NUM_TYPE); 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; } thrift-0.23.0/lib/lua/src/luasocket.c0000664000175000017500000002615315165535636017660 0ustar00buildbuild00000000000000// // 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 "string.h" #include "socket.h" //////////////////////////////////////////////////////////////////////////////// static const char *SOCKET_ANY = "__thrift_socket_any"; static const char *SOCKET_CONN = "__thrift_socket_connected"; static const char *SOCKET_GENERIC = "__thrift_socket_generic"; static const char *SOCKET_CLIENT = "__thrift_socket_client"; static const char *SOCKET_SERVER = "__thrift_socket_server"; static const char *DEFAULT_HOST = "localhost"; typedef struct __t_tcp { t_socket sock; int timeout; // Milliseconds } t_tcp; typedef t_tcp *p_tcp; //////////////////////////////////////////////////////////////////////////////// // Util static void throw_argerror(lua_State *L, int index, const char *expected) { char msg[256]; sprintf(msg, "%s expected, got %s", expected, luaL_typename(L, index)); luaL_argerror(L, index, msg); } static void *checkgroup(lua_State *L, int index, const char *groupname) { if (!lua_getmetatable(L, index)) { throw_argerror(L, index, groupname); } lua_pushstring(L, groupname); lua_rawget(L, -2); if (lua_isnil(L, -1)) { lua_pop(L, 2); throw_argerror(L, index, groupname); } else { lua_pop(L, 2); return lua_touserdata(L, index); } return NULL; // Not reachable } static void *checktype(lua_State *L, int index, const char *typename) { if (strcmp(typename, SOCKET_ANY) == 0 || strcmp(typename, SOCKET_CONN) == 0) { return checkgroup(L, index, typename); } else { return luaL_checkudata(L, index, typename); } } static void settype(lua_State *L, int index, const char *typename) { luaL_getmetatable(L, typename); lua_setmetatable(L, index); } #define LUA_SUCCESS_RETURN(L) \ lua_pushnumber(L, 1); \ return 1 #define LUA_CHECK_RETURN(L, err) \ if (err) { \ lua_pushnil(L); \ lua_pushstring(L, err); \ return 2; \ } \ LUA_SUCCESS_RETURN(L) //////////////////////////////////////////////////////////////////////////////// static int l_socket_create(lua_State *L); static int l_socket_destroy(lua_State *L); static int l_socket_settimeout(lua_State *L); static int l_socket_getsockinfo(lua_State *L); static int l_socket_accept(lua_State *L); static int l_socket_listen(lua_State *L); static int l_socket_create_and_connect(lua_State *L); static int l_socket_connect(lua_State *L); static int l_socket_send(lua_State *L); static int l_socket_receive(lua_State *L); //////////////////////////////////////////////////////////////////////////////// static const struct luaL_Reg methods_generic[] = { {"destroy", l_socket_destroy}, {"settimeout", l_socket_settimeout}, {"getsockinfo", l_socket_getsockinfo}, {"listen", l_socket_listen}, {"connect", l_socket_connect}, {NULL, NULL} }; static const struct luaL_Reg methods_server[] = { {"destroy", l_socket_destroy}, {"getsockinfo", l_socket_getsockinfo}, {"accept", l_socket_accept}, {"send", l_socket_send}, {"receive", l_socket_receive}, {NULL, NULL} }; static const struct luaL_Reg methods_client[] = { {"destroy", l_socket_destroy}, {"settimeout", l_socket_settimeout}, {"getsockinfo", l_socket_getsockinfo}, {"send", l_socket_send}, {"receive", l_socket_receive}, {NULL, NULL} }; static const struct luaL_Reg funcs_luasocket[] = { {"create", l_socket_create}, {"create_and_connect", l_socket_create_and_connect}, {NULL, NULL} }; //////////////////////////////////////////////////////////////////////////////// // Check/enforce inheritance static void add_to_group(lua_State *L, const char *metatablename, const char *groupname) { luaL_getmetatable(L, metatablename); // mt lua_pushstring(L, groupname); // mt, "name" lua_pushboolean(L, 1); // mt, "name", true lua_rawset(L, -3); // mt lua_pop(L, 1); } static void set_methods(lua_State *L, const char *metatablename, const struct luaL_Reg *methods) { luaL_getmetatable(L, metatablename); // mt // Create the __index table lua_pushstring(L, "__index"); // mt, "__index" lua_newtable(L); // mt, "__index", t for (; methods->name; methods++) { lua_pushstring(L, methods->name); // mt, "__index", t, "name" lua_pushcfunction(L, methods->func); // mt, "__index", t, "name", func lua_rawset(L, -3); // mt, "__index", t } lua_rawset(L, -3); // mt lua_pop(L, 1); } int luaopen_libluasocket(lua_State *L) { luaL_newmetatable(L, SOCKET_GENERIC); luaL_newmetatable(L, SOCKET_CLIENT); luaL_newmetatable(L, SOCKET_SERVER); lua_pop(L, 3); add_to_group(L, SOCKET_GENERIC, SOCKET_ANY); add_to_group(L, SOCKET_CLIENT, SOCKET_ANY); add_to_group(L, SOCKET_SERVER, SOCKET_ANY); add_to_group(L, SOCKET_CLIENT, SOCKET_CONN); add_to_group(L, SOCKET_SERVER, SOCKET_CONN); 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; } //////////////////////////////////////////////////////////////////////////////// // General // sock,err create(bind_host, bind_port) // sock,err create(bind_host) -> any port // sock,err create() -> any port on localhost static int l_socket_create(lua_State *L) { const char *err; t_socket sock; const char *addr = lua_tostring(L, 1); if (!addr) { addr = DEFAULT_HOST; } unsigned short port = lua_tonumber(L, 2); err = tcp_create(&sock); if (!err) { err = tcp_bind(&sock, addr, port); // bind on create if (err) { tcp_destroy(&sock); } else { p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); settype(L, -2, SOCKET_GENERIC); socket_setnonblocking(&sock); tcp->sock = sock; tcp->timeout = 0; return 1; // Return userdata } } LUA_CHECK_RETURN(L, err); } // destroy() static int l_socket_destroy(lua_State *L) { p_tcp tcp = (p_tcp) checktype(L, 1, SOCKET_ANY); const char *err = tcp_destroy(&tcp->sock); LUA_CHECK_RETURN(L, err); } // send(socket, data) static int l_socket_send(lua_State *L) { p_tcp self = (p_tcp) checktype(L, 1, SOCKET_CONN); p_tcp tcp = (p_tcp) checktype(L, 2, SOCKET_CONN); size_t len; const char *data = luaL_checklstring(L, 3, &len); const char *err = tcp_send(&tcp->sock, data, len, tcp->timeout); LUA_CHECK_RETURN(L, err); } #define LUA_READ_STEP 8192 static int l_socket_receive(lua_State *L) { p_tcp self = (p_tcp) checktype(L, 1, SOCKET_CONN); p_tcp handle = (p_tcp) checktype(L, 2, SOCKET_CONN); size_t len = luaL_checknumber(L, 3); char buf[LUA_READ_STEP]; const char *err = NULL; int received; size_t got = 0, step = 0; luaL_Buffer b; luaL_buffinit(L, &b); do { step = (LUA_READ_STEP < len - got ? LUA_READ_STEP : len - got); err = tcp_raw_receive(&handle->sock, buf, step, self->timeout, &received); if (err == NULL) { luaL_addlstring(&b, buf, received); got += received; } } while (err == NULL && got < len); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } luaL_pushresult(&b); return 1; } // settimeout(timeout) static int l_socket_settimeout(lua_State *L) { p_tcp self = (p_tcp) checktype(L, 1, SOCKET_ANY); int timeout = luaL_checknumber(L, 2); self->timeout = timeout; LUA_SUCCESS_RETURN(L); } // table getsockinfo() static int l_socket_getsockinfo(lua_State *L) { char buf[256]; short port = 0; p_tcp tcp = (p_tcp) checktype(L, 1, SOCKET_ANY); if (socket_get_info(&tcp->sock, &port, buf, 256) == SUCCESS) { lua_newtable(L); // t lua_pushstring(L, "host"); // t, "host" lua_pushstring(L, buf); // t, "host", buf lua_rawset(L, -3); // t lua_pushstring(L, "port"); // t, "port" lua_pushnumber(L, port); // t, "port", port lua_rawset(L, -3); // t return 1; } return 0; } //////////////////////////////////////////////////////////////////////////////// // Server // accept() static int l_socket_accept(lua_State *L) { const char *err; p_tcp self = (p_tcp) checktype(L, 1, SOCKET_SERVER); t_socket sock; err = tcp_accept(&self->sock, &sock, self->timeout); if (!err) { // Success // Create a reference to the client p_tcp client = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); settype(L, 2, SOCKET_CLIENT); socket_setnonblocking(&sock); client->sock = sock; client->timeout = self->timeout; return 1; } LUA_CHECK_RETURN(L, err); } static int l_socket_listen(lua_State *L) { const char* err; p_tcp tcp = (p_tcp) checktype(L, 1, SOCKET_GENERIC); int backlog = 10; err = tcp_listen(&tcp->sock, backlog); if (!err) { // Set the current as a server settype(L, 1, SOCKET_SERVER); // Now a server } LUA_CHECK_RETURN(L, err); } //////////////////////////////////////////////////////////////////////////////// // Client // create_and_connect(host, port, timeout) extern double __gettime(); static int l_socket_create_and_connect(lua_State *L) { const char* err = NULL; double end; t_socket sock; const char *host = luaL_checkstring(L, 1); unsigned short port = luaL_checknumber(L, 2); int timeout = luaL_checknumber(L, 3); // Create and connect loop for timeout milliseconds end = __gettime() + timeout/1000; do { // Create and connect the socket err = tcp_create_and_connect(&sock, host, port, timeout); if (err) { tcp_destroy(&sock); usleep(100000); // sleep for 100ms } else { p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); settype(L, -2, SOCKET_CLIENT); socket_setnonblocking(&sock); tcp->sock = sock; tcp->timeout = timeout; return 1; // Return userdata } } while (err && __gettime() < end); LUA_CHECK_RETURN(L, err); } // connect(host, port) static int l_socket_connect(lua_State *L) { const char *err; p_tcp tcp = (p_tcp) checktype(L, 1, SOCKET_GENERIC); const char *host = luaL_checkstring(L, 2); unsigned short port = luaL_checknumber(L, 3); err = tcp_connect(&tcp->sock, host, port, tcp->timeout); if (!err) { settype(L, 1, SOCKET_CLIENT); // Now a client } LUA_CHECK_RETURN(L, err); } thrift-0.23.0/lib/lua/src/longnumberutils.c0000664000175000017500000000317415165535636021115 0ustar00buildbuild00000000000000// // 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 const char * LONG_NUM_TYPE = "__thrift_longnumber"; int64_t lualongnumber_checklong(lua_State *L, int index) { switch (lua_type(L, index)) { case LUA_TNUMBER: return (int64_t)lua_tonumber(L, index); case LUA_TSTRING: return atoll(lua_tostring(L, index)); default: return *((int64_t *)luaL_checkudata(L, index, LONG_NUM_TYPE)); } } // Creates a new longnumber and pushes it onto the statck int64_t * lualongnumber_pushlong(lua_State *L, int64_t *val) { int64_t *data = (int64_t *)lua_newuserdata(L, sizeof(int64_t)); // longnum luaL_getmetatable(L, LONG_NUM_TYPE); // longnum, mt lua_setmetatable(L, -2); // longnum if (val) { *data = *val; } return data; } thrift-0.23.0/lib/lua/TCompactProtocol.lua0000664000175000017500000003325715165535636020675 0ustar00buildbuild00000000000000-- -- 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. -- require 'TProtocol' local libluabpack = require 'libluabpack' local libluabitwise = require 'libluabitwise' local liblualongnumber = require 'liblualongnumber' TCompactProtocol = __TObject.new(TProtocolBase, { __type = 'TCompactProtocol', COMPACT_PROTOCOL_ID = 0x82, COMPACT_VERSION = 1, COMPACT_VERSION_MASK = 0x1f, COMPACT_TYPE_MASK = 0xE0, COMPACT_TYPE_BITS = 0x07, COMPACT_TYPE_SHIFT_AMOUNT = 5, -- Used to keep track of the last field for the current and previous structs, -- so we can do the delta stuff. lastField = {}, lastFieldId = 0, lastFieldIndex = 1, -- If we encounter a boolean field begin, save the TField here so it can -- have the value incorporated. booleanFieldName = "", booleanFieldId = 0, booleanFieldPending = false, -- If we read a field header, and it's a boolean field, save the boolean -- value here so that readBool can use it. boolValue = false, boolValueIsNotNull = false, }) TCompactType = { COMPACT_BOOLEAN_TRUE = 0x01, COMPACT_BOOLEAN_FALSE = 0x02, COMPACT_BYTE = 0x03, COMPACT_I16 = 0x04, COMPACT_I32 = 0x05, COMPACT_I64 = 0x06, COMPACT_DOUBLE = 0x07, COMPACT_BINARY = 0x08, COMPACT_LIST = 0x09, COMPACT_SET = 0x0A, COMPACT_MAP = 0x0B, COMPACT_STRUCT = 0x0C, COMPACT_UUID = 0x0D, } TTypeToCompactType = {} TTypeToCompactType[TType.STOP] = TType.STOP TTypeToCompactType[TType.BOOL] = TCompactType.COMPACT_BOOLEAN_TRUE TTypeToCompactType[TType.BYTE] = TCompactType.COMPACT_BYTE TTypeToCompactType[TType.I16] = TCompactType.COMPACT_I16 TTypeToCompactType[TType.I32] = TCompactType.COMPACT_I32 TTypeToCompactType[TType.I64] = TCompactType.COMPACT_I64 TTypeToCompactType[TType.DOUBLE] = TCompactType.COMPACT_DOUBLE TTypeToCompactType[TType.STRING] = TCompactType.COMPACT_BINARY 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[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_UUID] = TType.UUID function TCompactProtocol:resetLastField() self.lastField = {} self.lastFieldId = 0 self.lastFieldIndex = 1 end function TCompactProtocol:packCompactType(ktype, vtype) return libluabitwise.bor(libluabitwise.shiftl(ktype, 4), vtype) end function TCompactProtocol:writeMessageBegin(name, ttype, seqid) self:writeByte(TCompactProtocol.COMPACT_PROTOCOL_ID) self:writeByte(libluabpack.packMesgType(TCompactProtocol.COMPACT_VERSION, TCompactProtocol.COMPACT_VERSION_MASK,ttype, TCompactProtocol.COMPACT_TYPE_SHIFT_AMOUNT, TCompactProtocol.COMPACT_TYPE_MASK)) self:writeVarint32(seqid) self:writeString(name) self:resetLastField() end function TCompactProtocol:writeMessageEnd() end function TCompactProtocol:writeStructBegin(name) self.lastField[self.lastFieldIndex] = self.lastFieldId self.lastFieldIndex = self.lastFieldIndex + 1 self.lastFieldId = 0 end function TCompactProtocol:writeStructEnd() self.lastFieldIndex = self.lastFieldIndex - 1 self.lastFieldId = self.lastField[self.lastFieldIndex] end function TCompactProtocol:writeFieldBegin(name, ttype, id) if ttype == TType.BOOL then self.booleanFieldName = name self.booleanFieldId = id self.booleanFieldPending = true else self:writeFieldBeginInternal(name, ttype, id, -1) end end function TCompactProtocol:writeFieldEnd() end function TCompactProtocol:writeFieldStop() self:writeByte(TType.STOP); end function TCompactProtocol:writeMapBegin(ktype, vtype, size) if size == 0 then self:writeByte(0) else self:writeVarint32(size) self:writeByte(self:packCompactType(TTypeToCompactType[ktype], TTypeToCompactType[vtype])) end end function TCompactProtocol:writeMapEnd() end function TCompactProtocol:writeListBegin(etype, size) self:writeCollectionBegin(etype, size) end function TCompactProtocol:writeListEnd() end function TCompactProtocol:writeSetBegin(etype, size) self:writeCollectionBegin(etype, size) end function TCompactProtocol:writeSetEnd() end function TCompactProtocol:writeBool(bool) local value = TCompactType.COMPACT_BOOLEAN_FALSE if bool then value = TCompactType.COMPACT_BOOLEAN_TRUE end if self.booleanFieldPending then self:writeFieldBeginInternal(self.booleanFieldName, TType.BOOL, self.booleanFieldId, value) self.booleanFieldPending = false else self:writeByte(value) end end function TCompactProtocol:writeByte(byte) local buff = libluabpack.bpack('c', byte) self.trans:write(buff) end function TCompactProtocol:writeI16(i16) self:writeVarint32(libluabpack.i32ToZigzag(i16)) end 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 function TCompactProtocol:writeDouble(dub) local buff = libluabpack.bpack('d', dub) self.trans:write(buff) end function TCompactProtocol:writeString(str) -- Should be utf-8 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)) self.trans:write(str) end function TCompactProtocol:writeFieldBeginInternal(name, ttype, id, typeOverride) if typeOverride == -1 then typeOverride = TTypeToCompactType[ttype] end local offset = id - self.lastFieldId if id > self.lastFieldId and offset <= 15 then self:writeByte(libluabitwise.bor(libluabitwise.shiftl(offset, 4), typeOverride)) else self:writeByte(typeOverride) self:writeI16(id) end self.lastFieldId = id end function TCompactProtocol:writeCollectionBegin(etype, size) if size <= 14 then self:writeByte(libluabitwise.bor(libluabitwise.shiftl(size, 4), TTypeToCompactType[etype])) else self:writeByte(libluabitwise.bor(0xf0, TTypeToCompactType[etype])) self:writeVarint32(size) end end function TCompactProtocol:writeVarint32(i32) -- Should be utf-8 local str = libluabpack.toVarint32(i32) self.trans:write(str) end function TCompactProtocol:writeVarint64(i64) -- Should be utf-8 local str = libluabpack.toVarint64(i64) self.trans:write(str) end function TCompactProtocol:readMessageBegin() local protocolId = self:readSignByte() if protocolId ~= self.COMPACT_PROTOCOL_ID then terror(TProtocolException:new{ message = "Expected protocol id " .. self.COMPACT_PROTOCOL_ID .. " but got " .. protocolId}) end local versionAndType = self:readSignByte() local version = libluabitwise.band(versionAndType, self.COMPACT_VERSION_MASK) local ttype = libluabitwise.band(libluabitwise.shiftr(versionAndType, self.COMPACT_TYPE_SHIFT_AMOUNT), self.COMPACT_TYPE_BITS) if version ~= self.COMPACT_VERSION then terror(TProtocolException:new{ message = "Expected version " .. self.COMPACT_VERSION .. " but got " .. version}) end local seqid = self:readVarint32() local name = self:readString() return name, ttype, seqid end function TCompactProtocol:readMessageEnd() end function TCompactProtocol:readStructBegin() self.lastField[self.lastFieldIndex] = self.lastFieldId self.lastFieldIndex = self.lastFieldIndex + 1 self.lastFieldId = 0 return nil end function TCompactProtocol:readStructEnd() self.lastFieldIndex = self.lastFieldIndex - 1 self.lastFieldId = self.lastField[self.lastFieldIndex] end function TCompactProtocol:readFieldBegin() local field_and_ttype = self:readSignByte() local ttype = self:getTType(field_and_ttype) if ttype == TType.STOP then return nil, ttype, 0 end local modifier = libluabitwise.shiftr(field_and_ttype, 4) local id = 0 if modifier == 0 then id = self:readI16() else id = self.lastFieldId + modifier end local type = libluabitwise.band(field_and_ttype, 0x0f) if type == TCompactType.COMPACT_BOOLEAN_TRUE then self.boolValue = true self.boolValueIsNotNull = true elseif type == TCompactType.COMPACT_BOOLEAN_FALSE then self.boolValue = false self.boolValueIsNotNull = true end self.lastFieldId = id return nil, ttype, id end function TCompactProtocol:readFieldEnd() end function TCompactProtocol:readMapBegin() local size = self:readVarint32() local kvtype = 0 if size > 0 then kvtype = self:readSignByte() end local ktype = self:getTType(libluabitwise.shiftr(kvtype, 4)) local vtype = self:getTType(kvtype) return ktype, vtype, size end function TCompactProtocol:readMapEnd() end function TCompactProtocol:readListBegin() local size_and_type = self:readSignByte() local size = libluabitwise.band(libluabitwise.shiftr(size_and_type, 4), 0x0f) if size == 15 then size = self:readVarint32() end if size < 0 then return nil,nil end local etype = self:getTType(libluabitwise.band(size_and_type, 0x0f)) return etype, size end function TCompactProtocol:readListEnd() end function TCompactProtocol:readSetBegin() return self:readListBegin() end function TCompactProtocol:readSetEnd() end function TCompactProtocol:readBool() if self.boolValueIsNotNull then self.boolValueIsNotNull = false return self.boolValue end local val = self:readSignByte() if val == TCompactType.COMPACT_BOOLEAN_TRUE then return true end return false end function TCompactProtocol:readByte() local buff = self.trans:readAll(1) local val = libluabpack.bunpack('c', buff) return val end function TCompactProtocol:readSignByte() local buff = self.trans:readAll(1) local val = libluabpack.bunpack('C', buff) return val end function TCompactProtocol:readI16() return self:readI32() end function TCompactProtocol:readI32() local v = self:readVarint32() local value = libluabpack.zigzagToI32(v) 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 end function TCompactProtocol:readDouble() local buff = self.trans:readAll(8) local val = libluabpack.bunpack('d', buff) return val end 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 return "" end return self.trans:readAll(size) end function TCompactProtocol:readVarint32() local shiftl = 0 local result = 0 while true do b = self:readByte() result = libluabitwise.bor(result, libluabitwise.shiftl(libluabitwise.band(b, 0x7f), shiftl)) if libluabitwise.band(b, 0x80) ~= 0x80 then break end shiftl = shiftl + 7 end return result end function TCompactProtocol:readVarint64() local result = liblualongnumber.new local data = result(0) local shiftl = 0 while true do b = self:readSignByte() endFlag, data = libluabpack.fromVarint64(b, shiftl, data) shiftl = shiftl + 7 if endFlag == 0 then break end end return data end function TCompactProtocol:getTType(ctype) return CompactTypeToTType[libluabitwise.band(ctype, 0x0f)] end TCompactProtocolFactory = TProtocolFactory:new{ __type = 'TCompactProtocolFactory', } function TCompactProtocolFactory:getProtocol(trans) -- TODO Enforce that this must be a transport class (ie not a bool) if not trans then terror(TProtocolException:new{ message = 'Must supply a transport to ' .. ttype(self) }) end return TCompactProtocol:new{ trans = trans } end thrift-0.23.0/lib/lua/TSocket.lua0000664000175000017500000000570615165535636017013 0ustar00buildbuild00000000000000---- 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. -- require 'TTransport' local luasocket = require 'libluasocket' -- TSocketBase TSocketBase = TTransportBase:new{ __type = 'TSocketBase', timeout = 1000, host = 'localhost', port = 9090, handle } function TSocketBase:close() if self.handle then self.handle:destroy() self.handle = nil end end -- Returns a table with the fields host and port function TSocketBase:getSocketInfo() if self.handle then return self.handle:getsockinfo() end terror(TTransportException:new{errorCode = TTransportException.NOT_OPEN}) end function TSocketBase:setTimeout(timeout) if timeout and ttype(timeout) == 'number' then if self.handle then self.handle:settimeout(timeout) end self.timeout = timeout end end -- TSocket TSocket = TSocketBase:new{ __type = 'TSocket', host = 'localhost', port = 9090 } function TSocket:isOpen() if self.handle then return true end return false end function TSocket:open() if self.handle then self:close() end -- Create local handle local sock, err = luasocket.create_and_connect( self.host, self.port, self.timeout) if err == nil then self.handle = sock end if err then terror(TTransportException:new{ message = 'Could not connect to ' .. self.host .. ':' .. self.port .. ' (' .. err .. ')' }) end end function TSocket:read(len) local buf = self.handle:receive(self.handle, len) if not buf or string.len(buf) ~= len then terror(TTransportException:new{errorCode = TTransportException.UNKNOWN}) end return buf end function TSocket:write(buf) self.handle:send(self.handle, buf) end function TSocket:flush() end -- TServerSocket TServerSocket = TSocketBase:new{ __type = 'TServerSocket', host = 'localhost', port = 9090 } function TServerSocket:listen() if self.handle then self:close() end local sock, err = luasocket.create(self.host, self.port) if not err then self.handle = sock else terror(err) end self.handle:settimeout(self.timeout) self.handle:listen() end function TServerSocket:accept() local client, err = self.handle:accept() if err then terror(err) end return TSocket:new({handle = client}) end thrift-0.23.0/lib/lua/coding_standards.md0000664000175000017500000000010315165535636020546 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/lua/TMemoryBuffer.lua0000664000175000017500000000433215165535636020157 0ustar00buildbuild00000000000000-- -- 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. -- require 'TTransport' TMemoryBuffer = TTransportBase:new{ __type = 'TMemoryBuffer', buffer = '', bufferSize = 1024, wPos = 0, rPos = 0 } function TMemoryBuffer:isOpen() return 1 end function TMemoryBuffer:open() end function TMemoryBuffer:close() end function TMemoryBuffer:peak() return self.rPos < self.wPos end function TMemoryBuffer:getBuffer() return self.buffer end function TMemoryBuffer:resetBuffer(buf) if buf then self.buffer = buf self.bufferSize = string.len(buf) else self.buffer = '' self.bufferSize = 1024 end self.wPos = string.len(buf) self.rPos = 0 end function TMemoryBuffer:available() return self.wPos - self.rPos end function TMemoryBuffer:read(len) local avail = self:available() if avail == 0 then return '' end if avail < len then len = avail end local val = string.sub(self.buffer, self.rPos + 1, self.rPos + len) self.rPos = self.rPos + len return val end function TMemoryBuffer:readAll(len) local avail = self:available() if avail < len then local msg = string.format('Attempt to readAll(%d) found only %d available', len, avail) terror(TTransportException:new{message = msg}) end -- read should block so we don't need a loop here return self:read(len) end function TMemoryBuffer:write(buf) self.buffer = self.buffer .. buf self.wPos = self.wPos + string.len(buf) end function TMemoryBuffer:flush() end thrift-0.23.0/lib/lua/TBinaryProtocol.lua0000664000175000017500000001524515165535636020530 0ustar00buildbuild00000000000000-- -- 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. -- require 'TProtocol' local libluabpack = require 'libluabpack' local libluabitwise = require 'libluabitwise' TBinaryProtocol = __TObject.new(TProtocolBase, { __type = 'TBinaryProtocol', VERSION_MASK = -65536, -- 0xffff0000 VERSION_1 = -2147418112, -- 0x80010000 TYPE_MASK = 0x000000ff, strictRead = false, strictWrite = true }) function TBinaryProtocol:writeMessageBegin(name, ttype, seqid) if self.strictWrite then self:writeI32(libluabitwise.bor(TBinaryProtocol.VERSION_1, ttype)) self:writeString(name) self:writeI32(seqid) else self:writeString(name) self:writeByte(ttype) self:writeI32(seqid) end end function TBinaryProtocol:writeMessageEnd() end function TBinaryProtocol:writeStructBegin(name) end function TBinaryProtocol:writeStructEnd() end function TBinaryProtocol:writeFieldBegin(name, ttype, id) self:writeByte(ttype) self:writeI16(id) end function TBinaryProtocol:writeFieldEnd() end function TBinaryProtocol:writeFieldStop() self:writeByte(TType.STOP); end function TBinaryProtocol:writeMapBegin(ktype, vtype, size) self:writeByte(ktype) self:writeByte(vtype) self:writeI32(size) end function TBinaryProtocol:writeMapEnd() end function TBinaryProtocol:writeListBegin(etype, size) self:writeByte(etype) self:writeI32(size) end function TBinaryProtocol:writeListEnd() end function TBinaryProtocol:writeSetBegin(etype, size) self:writeByte(etype) self:writeI32(size) end function TBinaryProtocol:writeSetEnd() end function TBinaryProtocol:writeBool(bool) if bool then self:writeByte(1) else self:writeByte(0) end end function TBinaryProtocol:writeByte(byte) local buff = libluabpack.bpack('c', byte) self.trans:write(buff) end function TBinaryProtocol:writeI16(i16) local buff = libluabpack.bpack('s', i16) self.trans:write(buff) end function TBinaryProtocol:writeI32(i32) local buff = libluabpack.bpack('i', 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) end function TBinaryProtocol:writeDouble(dub) local buff = libluabpack.bpack('d', dub) self.trans:write(buff) end function TBinaryProtocol:writeString(str) -- Should be utf-8 self:writeI32(string.len(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 local version = libluabitwise.band(sz, TBinaryProtocol.VERSION_MASK) if version ~= TBinaryProtocol.VERSION_1 then terror(TProtocolException:new{ message = 'Bad version in readMessageBegin: ' .. sz }) end ttype = libluabitwise.band(sz, TBinaryProtocol.TYPE_MASK) name = self:readString() seqid = self:readI32() else if self.strictRead then terror(TProtocolException:new{message = 'No protocol version header'}) end name = self.trans:readAll(sz) ttype = self:readByte() seqid = self:readI32() end return name, ttype, seqid end function TBinaryProtocol:readMessageEnd() end function TBinaryProtocol:readStructBegin() return nil end function TBinaryProtocol:readStructEnd() end function TBinaryProtocol:readFieldBegin() local ttype = self:readByte() if ttype == TType.STOP then return nil, ttype, 0 end local id = self:readI16() return nil, ttype, id end function TBinaryProtocol:readFieldEnd() end function TBinaryProtocol:readMapBegin() local ktype = self:readByte() local vtype = self:readByte() local size = self:readI32() return ktype, vtype, size end function TBinaryProtocol:readMapEnd() end function TBinaryProtocol:readListBegin() local etype = self:readByte() local size = self:readI32() return etype, size end function TBinaryProtocol:readListEnd() end function TBinaryProtocol:readSetBegin() local etype = self:readByte() local size = self:readI32() return etype, size end function TBinaryProtocol:readSetEnd() end function TBinaryProtocol:readBool() local byte = self:readByte() if byte == 0 then return false end return true end function TBinaryProtocol:readByte() local buff = self.trans:readAll(1) local val = libluabpack.bunpack('c', buff) return val end function TBinaryProtocol:readI16() local buff = self.trans:readAll(2) local val = libluabpack.bunpack('s', buff) return val end function TBinaryProtocol:readI32() local buff = self.trans:readAll(4) local val = libluabpack.bunpack('i', buff) 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) return val end function TBinaryProtocol:readDouble() local buff = self.trans:readAll(8) local val = libluabpack.bunpack('d', buff) return val end function TBinaryProtocol:readString() local len = self:readI32() local str = self.trans:readAll(len) 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 } function TBinaryProtocolFactory:getProtocol(trans) -- TODO Enforce that this must be a transport class (ie not a bool) if not trans then terror(TProtocolException:new{ message = 'Must supply a transport to ' .. ttype(self) }) end return TBinaryProtocol:new{ trans = trans, strictRead = self.strictRead, strictWrite = true } end thrift-0.23.0/lib/lua/THttpTransport.lua0000664000175000017500000001214515167543515020407 0ustar00buildbuild00000000000000-- -- 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. -- require 'TTransport' THttpTransport = TTransportBase:new{ __type = 'THttpTransport', path = '/', wBuf = '', rBuf = '', CRLF = '\r\n', VERSION = version, isServer = true } function THttpTransport:new(obj) if ttype(obj) ~= 'table' then error(ttype(self) .. 'must be initialized with a table') end -- Ensure a transport is provided if not obj.trans then error('You must provide ' .. ttype(self) .. ' with a trans') end return TTransportBase.new(self, obj) end local function THttpHeaders() local data = {} return setmetatable({}, { __index = function(_, key) return data[string.lower(key)] end, __newindex = function(_, key, value) data[string.lower(key)] = value end, __pairs = function() return pairs(data) end }) end function THttpTransport:isOpen() return self.trans:isOpen() end function THttpTransport:open() return self.trans:open() end function THttpTransport:close() return self.trans:close() end function THttpTransport:readAll(len) return self:read(len) end function THttpTransport:read(len) if string.len(self.rBuf) == 0 then self:_readMsg() end if len > string.len(self.rBuf) then local val = self.rBuf self.rBuf = '' return val end local val = string.sub(self.rBuf, 0, len) self.rBuf = string.sub(self.rBuf, len+1) return val end function THttpTransport:_readMsg() while true do self.rBuf = self.rBuf .. self.trans:read(4) if string.find(self.rBuf, self.CRLF .. self.CRLF) then break end end if not self.rBuf then self.rBuf = "" return end self:getLine() local headers = self:_parseHeaders() if not headers then self.rBuf = "" return end local length = tonumber(headers["Content-Length"]) if length then length = length - string.len(self.rBuf) self.rBuf = self.rBuf .. self.trans:readAll(length) end if self.rBuf == nil then self.rBuf = "" end end function THttpTransport:getLine() local a,b = string.find(self.rBuf, self.CRLF) local line = "" if a and b then line = string.sub(self.rBuf, 0, a-1) self.rBuf = string.sub(self.rBuf, b+1) end return line end function THttpTransport:_parseHeaders() local headers = THttpHeaders() repeat local line = self:getLine() for key, val in string.gmatch(line, "([%w%-]+)%s*:%s*(.+)") do if headers[key] then local delimiter = ", " if key == "Set-Cookie" then delimiter = "; " end headers[key] = headers[key] .. delimiter .. tostring(val) else headers[key] = tostring(val) end end until string.find(line, "^%s*$") return headers end function THttpTransport:write(buf, len) if len and len < string.len(buf) then buf = string.sub(buf, 0, len) end self.wBuf = self.wBuf .. buf end function THttpTransport:writeHttpHeader(content_len) if self.isServer then local header = "HTTP/1.1 200 OK" .. self.CRLF .. "Server: Thrift/" .. self.VERSION .. self.CRLF .. "Access-Control-Allow-Origin: *" .. self.CRLF .. "Content-Type: application/x-thrift" .. self.CRLF .. "Content-Length: " .. content_len .. self.CRLF .. "Connection: Keep-Alive" .. self.CRLF .. self.CRLF self.trans:write(header) else local header = "POST " .. self.path .. " HTTP/1.1" .. self.CRLF .. "Host: " .. self.trans.host .. self.CRLF .. "Content-Type: application/x-thrift" .. self.CRLF .. "Content-Length: " .. content_len .. self.CRLF .. "Accept: application/x-thrift " .. self.CRLF .. "User-Agent: Thrift/" .. self.VERSION .. " (Lua/THttpClient)" .. self.CRLF .. self.CRLF self.trans:write(header) 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 = '' local dataLen = string.len(tmp) self:writeHttpHeader(dataLen) if dataLen > 0 then self.trans:write(tmp) end self.trans:flush() end THttpTransportFactory = TTransportFactoryBase:new{ __type = 'THttpTransportFactory' } function THttpTransportFactory:getTransport(trans) if not trans then terror(TProtocolException:new{ message = 'Must supply a transport to ' .. ttype(self) }) end return THttpTransport:new{trans = trans} end thrift-0.23.0/lib/lua/Thrift.lua0000664000175000017500000001715715170007142016660 0ustar00buildbuild00000000000000-- -- Licensed to the Apache Software Foundation (ASF) under one -- or more contributor license agreements. See the NOTICE file -- distributed with this work for additional information -- regarding copyright ownership. The ASF licenses this file -- to you under the Apache License, Version 2.0 (the -- "License"); you may not use this file except in compliance -- with the License. You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, -- software distributed under the License is distributed on an -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -- KIND, either express or implied. See the License for the -- specific language governing permissions and limitations -- under the License. -- ---- namespace thrift --thrift = {} --setmetatable(thrift, {__index = _G}) --> perf hit for accessing global methods --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 type(obj.__type) == 'string' then return obj.__type end return type(obj) end function terror(e) if e and e.__tostring then error(e:__tostring()) return end error(e) end function ttable_size(t) local count = 0 for k, v in pairs(t) do count = count + 1 end return count end version = '0.23.0' TType = { STOP = 0, VOID = 1, BOOL = 2, BYTE = 3, I08 = 3, DOUBLE = 4, I16 = 6, I32 = 8, I64 = 10, STRING = 11, UTF7 = 11, STRUCT = 12, MAP = 13, SET = 14, LIST = 15, UUID = 16 } TMessageType = { CALL = 1, REPLY = 2, EXCEPTION = 3, ONEWAY = 4 } -- Recursive __index function to achieve inheritance function __tobj_index(self, key) local v = rawget(self, key) if v ~= nil then return v end local p = rawget(self, '__parent') if p then return __tobj_index(p, key) end return nil end -- Basic Thrift-Lua Object __TObject = { __type = '__TObject', __mt = { __index = __tobj_index } } function __TObject:new(init_obj) local obj = {} if ttype(obj) == 'table' then obj = init_obj end -- Use the __parent key and the __index function to achieve inheritance obj.__parent = self setmetatable(obj, __TObject.__mt) return obj end -- Return a string representation of any lua variable function thrift_print_r(t) local ret = '' local ltype = type(t) if (ltype == 'table') then ret = ret .. '{ ' for key,value in pairs(t) do ret = ret .. tostring(key) .. '=' .. thrift_print_r(value) .. ' ' end ret = ret .. '}' elseif ltype == 'string' then ret = ret .. "'" .. tostring(t) .. "'" else ret = ret .. tostring(t) end return ret end -- Basic Exception TException = __TObject:new{ message, errorCode, __type = 'TException' } function TException:__tostring() if self.message then return string.format('%s: %s', self.__type, self.message) else local message if self.errorCode and self.__errorCodeToString then message = string.format('%d: %s', self.errorCode, self:__errorCodeToString()) else message = thrift_print_r(self) end return string.format('%s:%s', self.__type, message) end end TApplicationException = TException:new{ UNKNOWN = 0, UNKNOWN_METHOD = 1, INVALID_MESSAGE_TYPE = 2, WRONG_METHOD_NAME = 3, BAD_SEQUENCE_ID = 4, MISSING_RESULT = 5, INTERNAL_ERROR = 6, PROTOCOL_ERROR = 7, INVALID_TRANSFORM = 8, INVALID_PROTOCOL = 9, UNSUPPORTED_CLIENT_TYPE = 10, errorCode = 0, __type = 'TApplicationException' } function TApplicationException:__errorCodeToString() if self.errorCode == self.UNKNOWN_METHOD then return 'Unknown method' elseif self.errorCode == self.INVALID_MESSAGE_TYPE then return 'Invalid message type' elseif self.errorCode == self.WRONG_METHOD_NAME then return 'Wrong method name' elseif self.errorCode == self.BAD_SEQUENCE_ID then return 'Bad sequence ID' elseif self.errorCode == self.MISSING_RESULT then return 'Missing result' elseif self.errorCode == self.INTERNAL_ERROR then return 'Internal error' elseif self.errorCode == self.PROTOCOL_ERROR then return 'Protocol error' elseif self.errorCode == self.INVALID_TRANSFORM then return 'Invalid transform' elseif self.errorCode == self.INVALID_PROTOCOL then return 'Invalid protocol' elseif self.errorCode == self.UNSUPPORTED_CLIENT_TYPE then return 'Unsupported client type' else return 'Default (unknown)' end end function TException:read(iprot) iprot:readStructBegin() while true do local fname, ftype, fid = iprot:readFieldBegin() if ftype == TType.STOP then break elseif fid == 1 then if ftype == TType.STRING then self.message = iprot:readString() else iprot:skip(ftype) end elseif fid == 2 then if ftype == TType.I32 then self.errorCode = iprot:readI32() else iprot:skip(ftype) end else iprot:skip(ftype) end iprot:readFieldEnd() end iprot:readStructEnd() end function TException:write(oprot) oprot:writeStructBegin('TApplicationException') if self.message then oprot:writeFieldBegin('message', TType.STRING, 1) oprot:writeString(self.message) oprot:writeFieldEnd() end if self.errorCode then oprot:writeFieldBegin('type', TType.I32, 2) oprot:writeI32(self.errorCode) oprot:writeFieldEnd() end oprot:writeFieldStop() 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', _seqid = 0 } function __TClient:new(obj) if ttype(obj) ~= 'table' then error('TClient must be initialized with a table') end -- Set iprot & oprot if obj.protocol then obj.iprot = obj.protocol obj.oprot = obj.protocol obj.protocol = nil elseif not obj.iprot then error('You must provide ' .. ttype(self) .. ' with an iprot') end if not obj.oprot then obj.oprot = obj.iprot end return __TObject.new(self, obj) end function __TClient:close() self.iprot.trans:close() self.oprot.trans:close() end -- Basic Processor (used in generated lua code) __TProcessor = __TObject:new{ __type = '__TProcessor' } function __TProcessor:new(obj) if ttype(obj) ~= 'table' then error('TProcessor must be initialized with a table') end -- Ensure a handler is provided if not obj.handler then error('You must provide ' .. ttype(self) .. ' with a handler') end return __TObject.new(self, obj) end thrift-0.23.0/lib/lua/TBufferedTransport.lua0000664000175000017500000000436615165535636021223 0ustar00buildbuild00000000000000-- -- 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. -- require 'TTransport' TBufferedTransport = TTransportBase:new{ __type = 'TBufferedTransport', rBufSize = 2048, wBufSize = 2048, wBuf = '', rBuf = '' } function TBufferedTransport:new(obj) if ttype(obj) ~= 'table' then error(ttype(self) .. 'must be initialized with a table') end -- Ensure a transport is provided if not obj.trans then error('You must provide ' .. ttype(self) .. ' with a trans') end return TTransportBase.new(self, obj) end function TBufferedTransport:isOpen() return self.trans:isOpen() end function TBufferedTransport:open() return self.trans:open() end function TBufferedTransport:close() return self.trans:close() end function TBufferedTransport:read(len) return self.trans:read(len) end function TBufferedTransport:readAll(len) return self.trans:readAll(len) end function TBufferedTransport:write(buf) self.wBuf = self.wBuf .. buf if string.len(self.wBuf) >= self.wBufSize then self.trans:write(self.wBuf) self.wBuf = '' end end function TBufferedTransport:flush() if string.len(self.wBuf) > 0 then self.trans:write(self.wBuf) self.wBuf = '' end end TBufferedTransportFactory = TTransportFactoryBase:new{ __type = 'TBufferedTransportFactory' } function TBufferedTransportFactory:getTransport(trans) if not trans then terror(TTransportException:new{ message = 'Must supply a transport to ' .. ttype(self) }) end return TBufferedTransport:new{ trans = trans } end thrift-0.23.0/lib/lua/TProtocol.lua0000664000175000017500000001225215165535636017356 0ustar00buildbuild00000000000000-- -- 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. -- require 'Thrift' TProtocolException = TException:new { UNKNOWN = 0, INVALID_DATA = 1, NEGATIVE_SIZE = 2, SIZE_LIMIT = 3, BAD_VERSION = 4, INVALID_PROTOCOL = 5, DEPTH_LIMIT = 6, errorCode = 0, __type = 'TProtocolException' } function TProtocolException:__errorCodeToString() if self.errorCode == self.INVALID_DATA then return 'Invalid data' elseif self.errorCode == self.NEGATIVE_SIZE then return 'Negative size' elseif self.errorCode == self.SIZE_LIMIT then return 'Size limit' elseif self.errorCode == self.BAD_VERSION then return 'Bad version' elseif self.errorCode == self.INVALID_PROTOCOL then return 'Invalid protocol' elseif self.errorCode == self.DEPTH_LIMIT then return 'Exceeded size limit' else return 'Default (unknown)' end end TProtocolBase = __TObject:new{ __type = 'TProtocolBase', trans } function TProtocolBase:new(obj) if ttype(obj) ~= 'table' then error(ttype(self) .. 'must be initialized with a table') end -- Ensure a transport is provided if not obj.trans then error('You must provide ' .. ttype(self) .. ' with a trans') end return __TObject.new(self, obj) end function TProtocolBase:writeMessageBegin(name, ttype, seqid) end function TProtocolBase:writeMessageEnd() end function TProtocolBase:writeStructBegin(name) end function TProtocolBase:writeStructEnd() end function TProtocolBase:writeFieldBegin(name, ttype, id) end function TProtocolBase:writeFieldEnd() end function TProtocolBase:writeFieldStop() end function TProtocolBase:writeMapBegin(ktype, vtype, size) end function TProtocolBase:writeMapEnd() end function TProtocolBase:writeListBegin(ttype, size) end function TProtocolBase:writeListEnd() end function TProtocolBase:writeSetBegin(ttype, size) end function TProtocolBase:writeSetEnd() end function TProtocolBase:writeBool(bool) end function TProtocolBase:writeByte(byte) end function TProtocolBase:writeI16(i16) end 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 function TProtocolBase:readStructEnd() end function TProtocolBase:readFieldBegin() end function TProtocolBase:readFieldEnd() end function TProtocolBase:readMapBegin() end function TProtocolBase:readMapEnd() end function TProtocolBase:readListBegin() end function TProtocolBase:readListEnd() end function TProtocolBase:readSetBegin() end function TProtocolBase:readSetEnd() end function TProtocolBase:readBool() end function TProtocolBase:readByte() end function TProtocolBase:readI16() end 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 self:readBool() elseif ttype == TType.BYTE then self:readByte() elseif ttype == TType.I16 then self:readI16() elseif ttype == TType.I32 then self:readI32() elseif ttype == TType.I64 then self:readI64() elseif ttype == TType.DOUBLE then self:readDouble() elseif ttype == TType.STRING then self:readString() elseif ttype == TType.STRUCT then local name = self:readStructBegin() while true do local name, ttype, id = self:readFieldBegin() if ttype == TType.STOP then break end self:skip(ttype) self:readFieldEnd() end self:readStructEnd() elseif ttype == TType.MAP then local kttype, vttype, size = self:readMapBegin() for i = 1, size, 1 do self:skip(kttype) self:skip(vttype) end self:readMapEnd() elseif ttype == TType.SET then local ettype, size = self:readSetBegin() for i = 1, size, 1 do self:skip(ettype) end self:readSetEnd() elseif ttype == TType.LIST then local ettype, size = self:readListBegin() for i = 1, size, 1 do self:skip(ettype) end self:readListEnd() elseif ttype == TType.UUID then self:readUuid() else terror(TProtocolException:new{ message = 'Invalid data' }) end end TProtocolFactory = __TObject:new{ __type = 'TProtocolFactory', } function TProtocolFactory:getProtocol(trans) end thrift-0.23.0/lib/lua/Makefile.in0000644000175000017500000012743115170007167016764 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/lua ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libluabitwise_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__dirstamp = $(am__leading_dot)dirstamp am_libluabitwise_la_OBJECTS = src/libluabitwise_la-luabitwise.lo libluabitwise_la_OBJECTS = $(am_libluabitwise_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libluabitwise_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libluabitwise_la_LDFLAGS) $(LDFLAGS) \ -o $@ libluabpack_la_DEPENDENCIES = liblualongnumber.la \ $(am__DEPENDENCIES_1) am_libluabpack_la_OBJECTS = src/libluabpack_la-luabpack.lo libluabpack_la_OBJECTS = $(am_libluabpack_la_OBJECTS) libluabpack_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libluabpack_la_LDFLAGS) $(LDFLAGS) -o \ $@ liblualongnumber_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_liblualongnumber_la_OBJECTS = \ src/liblualongnumber_la-lualongnumber.lo \ src/liblualongnumber_la-longnumberutils.lo liblualongnumber_la_OBJECTS = $(am_liblualongnumber_la_OBJECTS) liblualongnumber_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(liblualongnumber_la_LDFLAGS) \ $(LDFLAGS) -o $@ libluasocket_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libluasocket_la_OBJECTS = src/libluasocket_la-luasocket.lo \ src/libluasocket_la-usocket.lo libluasocket_la_OBJECTS = $(am_libluasocket_la_OBJECTS) libluasocket_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libluasocket_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = src/$(DEPDIR)/libluabitwise_la-luabitwise.Plo \ src/$(DEPDIR)/libluabpack_la-luabpack.Plo \ src/$(DEPDIR)/liblualongnumber_la-longnumberutils.Plo \ src/$(DEPDIR)/liblualongnumber_la-lualongnumber.Plo \ src/$(DEPDIR)/libluasocket_la-luasocket.Plo \ src/$(DEPDIR)/libluasocket_la-usocket.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libluabitwise_la_SOURCES) $(libluabpack_la_SOURCES) \ $(liblualongnumber_la_SOURCES) $(libluasocket_la_SOURCES) DIST_SOURCES = $(libluabitwise_la_SOURCES) $(libluabpack_la_SOURCES) \ $(liblualongnumber_la_SOURCES) $(libluasocket_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(nobase_include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = subdir-objects nostdinc SUBDIRS = . lib_LTLIBRARIES = \ libluasocket.la \ liblualongnumber.la \ libluabpack.la \ libluabitwise.la libluasocket_la_SOURCES = \ src/luasocket.c \ src/usocket.c nobase_include_HEADERS = src/socket.h libluasocket_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE libluasocket_la_LDFLAGS = $(AM_LDFLAGS) libluasocket_la_LIBADD = $(LUA_LIB) -lm libluabpack_la_SOURCES = src/luabpack.c libluabpack_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE libluabpack_la_LDFLAGS = $(AM_LDFLAGS) libluabpack_la_LIBADD = liblualongnumber.la $(LUA_LIB) -lm libluabitwise_la_SOURCES = src/luabitwise.c libluabitwise_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE libluabitwise_la_LDFLAGS = $(AM_LDFLAGS) libluabitwise_la_LIBADD = $(LUA_LIB) -lm liblualongnumber_la_SOURCES = \ src/lualongnumber.c \ src/longnumberutils.c liblualongnumber_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE liblualongnumber_la_LDFLAGS = $(AM_LDFLAGS) liblualongnumber_la_LIBADD = $(LUA_LIB) -lm EXTRA_DIST = \ coding_standards.md \ TBinaryProtocol.lua \ TBufferedTransport.lua \ TCompactProtocol.lua \ TFramedTransport.lua \ Thrift.lua \ THttpTransport.lua \ TJsonProtocol.lua \ TMemoryBuffer.lua \ TProtocol.lua \ TServer.lua \ TSocket.lua \ TTransport.lua all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/lua/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/lua/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } src/$(am__dirstamp): @$(MKDIR_P) src @: > src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/$(DEPDIR) @: > src/$(DEPDIR)/$(am__dirstamp) src/libluabitwise_la-luabitwise.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) libluabitwise.la: $(libluabitwise_la_OBJECTS) $(libluabitwise_la_DEPENDENCIES) $(EXTRA_libluabitwise_la_DEPENDENCIES) $(AM_V_CCLD)$(libluabitwise_la_LINK) -rpath $(libdir) $(libluabitwise_la_OBJECTS) $(libluabitwise_la_LIBADD) $(LIBS) src/libluabpack_la-luabpack.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) libluabpack.la: $(libluabpack_la_OBJECTS) $(libluabpack_la_DEPENDENCIES) $(EXTRA_libluabpack_la_DEPENDENCIES) $(AM_V_CCLD)$(libluabpack_la_LINK) -rpath $(libdir) $(libluabpack_la_OBJECTS) $(libluabpack_la_LIBADD) $(LIBS) src/liblualongnumber_la-lualongnumber.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/liblualongnumber_la-longnumberutils.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) liblualongnumber.la: $(liblualongnumber_la_OBJECTS) $(liblualongnumber_la_DEPENDENCIES) $(EXTRA_liblualongnumber_la_DEPENDENCIES) $(AM_V_CCLD)$(liblualongnumber_la_LINK) -rpath $(libdir) $(liblualongnumber_la_OBJECTS) $(liblualongnumber_la_LIBADD) $(LIBS) src/libluasocket_la-luasocket.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/libluasocket_la-usocket.lo: src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) libluasocket.la: $(libluasocket_la_OBJECTS) $(libluasocket_la_DEPENDENCIES) $(EXTRA_libluasocket_la_DEPENDENCIES) $(AM_V_CCLD)$(libluasocket_la_LINK) -rpath $(libdir) $(libluasocket_la_OBJECTS) $(libluasocket_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f src/*.$(OBJEXT) -rm -f src/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libluabitwise_la-luabitwise.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libluabpack_la-luabpack.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/liblualongnumber_la-longnumberutils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/liblualongnumber_la-lualongnumber.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libluasocket_la-luasocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libluasocket_la-usocket.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< src/libluabitwise_la-luabitwise.lo: src/luabitwise.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluabitwise_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libluabitwise_la-luabitwise.lo -MD -MP -MF src/$(DEPDIR)/libluabitwise_la-luabitwise.Tpo -c -o src/libluabitwise_la-luabitwise.lo `test -f 'src/luabitwise.c' || echo '$(srcdir)/'`src/luabitwise.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libluabitwise_la-luabitwise.Tpo src/$(DEPDIR)/libluabitwise_la-luabitwise.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/luabitwise.c' object='src/libluabitwise_la-luabitwise.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluabitwise_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libluabitwise_la-luabitwise.lo `test -f 'src/luabitwise.c' || echo '$(srcdir)/'`src/luabitwise.c src/libluabpack_la-luabpack.lo: src/luabpack.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluabpack_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libluabpack_la-luabpack.lo -MD -MP -MF src/$(DEPDIR)/libluabpack_la-luabpack.Tpo -c -o src/libluabpack_la-luabpack.lo `test -f 'src/luabpack.c' || echo '$(srcdir)/'`src/luabpack.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libluabpack_la-luabpack.Tpo src/$(DEPDIR)/libluabpack_la-luabpack.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/luabpack.c' object='src/libluabpack_la-luabpack.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluabpack_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libluabpack_la-luabpack.lo `test -f 'src/luabpack.c' || echo '$(srcdir)/'`src/luabpack.c src/liblualongnumber_la-lualongnumber.lo: src/lualongnumber.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblualongnumber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/liblualongnumber_la-lualongnumber.lo -MD -MP -MF src/$(DEPDIR)/liblualongnumber_la-lualongnumber.Tpo -c -o src/liblualongnumber_la-lualongnumber.lo `test -f 'src/lualongnumber.c' || echo '$(srcdir)/'`src/lualongnumber.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/liblualongnumber_la-lualongnumber.Tpo src/$(DEPDIR)/liblualongnumber_la-lualongnumber.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lualongnumber.c' object='src/liblualongnumber_la-lualongnumber.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblualongnumber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/liblualongnumber_la-lualongnumber.lo `test -f 'src/lualongnumber.c' || echo '$(srcdir)/'`src/lualongnumber.c src/liblualongnumber_la-longnumberutils.lo: src/longnumberutils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblualongnumber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/liblualongnumber_la-longnumberutils.lo -MD -MP -MF src/$(DEPDIR)/liblualongnumber_la-longnumberutils.Tpo -c -o src/liblualongnumber_la-longnumberutils.lo `test -f 'src/longnumberutils.c' || echo '$(srcdir)/'`src/longnumberutils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/liblualongnumber_la-longnumberutils.Tpo src/$(DEPDIR)/liblualongnumber_la-longnumberutils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/longnumberutils.c' object='src/liblualongnumber_la-longnumberutils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblualongnumber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/liblualongnumber_la-longnumberutils.lo `test -f 'src/longnumberutils.c' || echo '$(srcdir)/'`src/longnumberutils.c src/libluasocket_la-luasocket.lo: src/luasocket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluasocket_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libluasocket_la-luasocket.lo -MD -MP -MF src/$(DEPDIR)/libluasocket_la-luasocket.Tpo -c -o src/libluasocket_la-luasocket.lo `test -f 'src/luasocket.c' || echo '$(srcdir)/'`src/luasocket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libluasocket_la-luasocket.Tpo src/$(DEPDIR)/libluasocket_la-luasocket.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/luasocket.c' object='src/libluasocket_la-luasocket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluasocket_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libluasocket_la-luasocket.lo `test -f 'src/luasocket.c' || echo '$(srcdir)/'`src/luasocket.c src/libluasocket_la-usocket.lo: src/usocket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluasocket_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/libluasocket_la-usocket.lo -MD -MP -MF src/$(DEPDIR)/libluasocket_la-usocket.Tpo -c -o src/libluasocket_la-usocket.lo `test -f 'src/usocket.c' || echo '$(srcdir)/'`src/usocket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libluasocket_la-usocket.Tpo src/$(DEPDIR)/libluasocket_la-usocket.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/usocket.c' object='src/libluasocket_la-usocket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libluasocket_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/libluasocket_la-usocket.lo `test -f 'src/usocket.c' || echo '$(srcdir)/'`src/usocket.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf src/.libs src/_libs install-nobase_includeHEADERS: $(nobase_include_HEADERS) @$(NORMAL_INSTALL) @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ done uninstall-nobase_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f src/$(DEPDIR)/$(am__dirstamp) -rm -f src/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -f src/$(DEPDIR)/libluabitwise_la-luabitwise.Plo -rm -f src/$(DEPDIR)/libluabpack_la-luabpack.Plo -rm -f src/$(DEPDIR)/liblualongnumber_la-longnumberutils.Plo -rm -f src/$(DEPDIR)/liblualongnumber_la-lualongnumber.Plo -rm -f src/$(DEPDIR)/libluasocket_la-luasocket.Plo -rm -f src/$(DEPDIR)/libluasocket_la-usocket.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-nobase_includeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f src/$(DEPDIR)/libluabitwise_la-luabitwise.Plo -rm -f src/$(DEPDIR)/libluabpack_la-luabpack.Plo -rm -f src/$(DEPDIR)/liblualongnumber_la-longnumberutils.Plo -rm -f src/$(DEPDIR)/liblualongnumber_la-lualongnumber.Plo -rm -f src/$(DEPDIR)/libluasocket_la-luasocket.Plo -rm -f src/$(DEPDIR)/libluasocket_la-usocket.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: uninstall-libLTLIBRARIES uninstall-nobase_includeHEADERS .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man \ install-nobase_includeHEADERS install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am \ uninstall-libLTLIBRARIES uninstall-nobase_includeHEADERS .PRECIOUS: Makefile distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/lua/TFramedTransport.lua0000664000175000017500000000563415165535636020676 0ustar00buildbuild00000000000000-- -- 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. -- require 'TTransport' local libluabpack = require 'libluabpack' TFramedTransport = TTransportBase:new{ __type = 'TFramedTransport', doRead = true, doWrite = true, wBuf = '', rBuf = '' } function TFramedTransport:new(obj) if ttype(obj) ~= 'table' then error(ttype(self) .. 'must be initialized with a table') end -- Ensure a transport is provided if not obj.trans then error('You must provide ' .. ttype(self) .. ' with a trans') end return TTransportBase.new(self, obj) end function TFramedTransport:isOpen() return self.trans:isOpen() end function TFramedTransport:open() return self.trans:open() end function TFramedTransport:close() return self.trans:close() end function TFramedTransport:read(len) if string.len(self.rBuf) == 0 then self:__readFrame() end if self.doRead == false then return self.trans:read(len) end if len > string.len(self.rBuf) then local val = self.rBuf self.rBuf = '' return val end local val = string.sub(self.rBuf, 0, len) self.rBuf = string.sub(self.rBuf, len+1) return val end function TFramedTransport:__readFrame() local buf = self.trans:readAll(4) local frame_len = libluabpack.bunpack('i', buf) self.rBuf = self.trans:readAll(frame_len) end function TFramedTransport:write(buf, len) if self.doWrite == false then return self.trans:write(buf, len) end if len and len < string.len(buf) then buf = string.sub(buf, 0, len) end self.wBuf = self.wBuf .. buf end function TFramedTransport:flush() if self.doWrite == false then return self.trans:flush() end -- If the write fails we still want wBuf to be clear local tmp = self.wBuf self.wBuf = '' local frame_len_buf = libluabpack.bpack("i", string.len(tmp)) tmp = frame_len_buf .. tmp self.trans:write(tmp) self.trans:flush() end TFramedTransportFactory = TTransportFactoryBase:new{ __type = 'TFramedTransportFactory' } function TFramedTransportFactory:getTransport(trans) if not trans then terror(TProtocolException:new{ message = 'Must supply a transport to ' .. ttype(self) }) end return TFramedTransport:new{trans = trans} end thrift-0.23.0/lib/lua/Makefile.am0000664000175000017500000000425615165535636016767 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects nostdinc SUBDIRS = . lib_LTLIBRARIES = \ libluasocket.la \ liblualongnumber.la \ libluabpack.la \ libluabitwise.la libluasocket_la_SOURCES = \ src/luasocket.c \ src/usocket.c nobase_include_HEADERS = src/socket.h libluasocket_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE libluasocket_la_LDFLAGS = $(AM_LDFLAGS) libluasocket_la_LIBADD = $(LUA_LIB) -lm libluabpack_la_SOURCES = src/luabpack.c libluabpack_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE libluabpack_la_LDFLAGS = $(AM_LDFLAGS) libluabpack_la_LIBADD = liblualongnumber.la $(LUA_LIB) -lm libluabitwise_la_SOURCES = src/luabitwise.c libluabitwise_la_CPPFLAGS = $(AM_CPPFLAGS) $(LUA_INCLUDE) -DLUA_COMPAT_MODULE libluabitwise_la_LDFLAGS = $(AM_LDFLAGS) libluabitwise_la_LIBADD = $(LUA_LIB) -lm liblualongnumber_la_SOURCES = \ src/lualongnumber.c \ src/longnumberutils.c 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 \ TBufferedTransport.lua \ TCompactProtocol.lua \ TFramedTransport.lua \ Thrift.lua \ THttpTransport.lua \ TJsonProtocol.lua \ TMemoryBuffer.lua \ TProtocol.lua \ TServer.lua \ TSocket.lua \ TTransport.lua thrift-0.23.0/lib/nodets/0000755000175000017500000000000015170007201015407 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodets/test/0000775000175000017500000000000015167543515016413 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodets/test/test-cases.ts0000664000175000017500000001075715167543515021050 0ustar00buildbuild00000000000000"use strict"; import ttypes = require("./gen-nodejs/ThriftTest_types"); import Int64 = require("node-int64"); import { v4 as uuidv4, v7 as uuidv7 } from 'uuid'; //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ú, 粵語"; /*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 mapTestInput = { 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], ["testUuid", "00112233-4455-6677-8899-aabbccddeeff"], ["testUuid", uuidv4()], ["testUuid", uuidv7()], ]; export var simpleLoose = [ ["testI64", 5], ["testI64", -5], ["testI64", 734359738368], ["testI64", -34359738368], ["testI64", -734359738368], ["testTypedef", 69], ]; var mapout: { [key: number]: number } = {}; for (var i = 0; i < 5; ++i) { 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], ]; export var out = new ttypes.Xtruct({ string_thing: "Zero", byte_thing: 1, i32_thing: -3, i64_thing: new Int64(1000000), }); export var out2 = new ttypes.Xtruct2(); out2.byte_thing = 1; 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), }), ], }); export var insanity: any = { "1": { "2": crazy, "3": crazy }, "2": { "6": { userMap: {}, xtructs: [] } }, }; thrift-0.23.0/lib/nodets/test/testAll.sh0000775000175000017500000000212115167543515020356 0ustar00buildbuild00000000000000#! /bin/sh DIR="$( cd "$( dirname "$0" )" && pwd )" mkdir -p $DIR/../test-compiled COMPILEDDIR="$(cd $DIR && cd ../test-compiled && pwd)" export NODE_PATH="${DIR}:${DIR}/../../nodejs/lib:${NODE_PATH}" compile() { #generating thrift code ${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift ${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node,ts ${DIR}/../../../test/Int64Test.thrift ${DIR}/../../../compiler/cpp/thrift -o ${COMPILEDDIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift ${DIR}/../../../compiler/cpp/thrift -o ${COMPILEDDIR} --gen js:node,ts ${DIR}/../../../test/Int64Test.thrift tsc --outDir $COMPILEDDIR --project $DIR/tsconfig.json } compile testServer() { echo "start server $1" RET=0 node ${COMPILEDDIR}/server.js $1 & SERVERPID=$! sleep 1 echo "start client $1" node ${COMPILEDDIR}/client.js $1 || RET=1 kill -2 $SERVERPID || RET=1 return $RET } node ${COMPILEDDIR}/int64.test.js || TESTOK=1 #integration tests testServer || TESTOK=1 testServer --promise || TESTOK=1 exit $TESTOK thrift-0.23.0/lib/nodets/test/server.ts0000664000175000017500000000175415167543515020300 0ustar00buildbuild00000000000000import thrift = require("thrift"); import { program } from 'commander'; import ThriftTest = require('./gen-nodejs/ThriftTest'); import test_handler = require('./test_handler'); program .option('--port ', 'Set thrift server port', (v) => parseInt(v, 10), 9090) .option('--promise', 'test with promise style functions') .option('--protocol ', '"Set thrift protocol (binary) [protocol]"') .option('--transport ', '"Set thrift transport (buffered) [transport]"') .parse(process.argv); var opts = program.opts(); var port: number = opts.port; var options: thrift.ServerOptions = { transport: thrift.TBufferedTransport, protocol: thrift.TBinaryProtocol, }; var server: thrift.Server; 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.listen(port); thrift-0.23.0/lib/nodets/test/tsconfig.json0000664000175000017500000000112415165535636021123 0ustar00buildbuild00000000000000{ "compilerOptions": { "allowJs": false, "alwaysStrict": true, "baseUrl": ".", "declaration": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "module": "commonjs", "moduleResolution": "node", "noImplicitThis": true, "noUnusedLocals": true, "preserveConstEnums": true, "removeComments": true, "strictFunctionTypes": true, "strictNullChecks": true, "target": "es6", "paths": { "thrift": ["../../nodejs/lib/thrift"] } } } thrift-0.23.0/lib/nodets/test/test_handler.ts0000664000175000017500000002363015167543515021443 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * 'License'); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ //This is the server side Node test handler for the standard // Apache Thrift test service. import ttypes = require("./gen-nodejs/ThriftTest_types"); import thrift = require("thrift"); import Thrift = thrift.Thrift; import Q = require("q"); import Int64 = require("node-int64"); import { v4 as uuid } from "uuid"; type uuid = string; export class SyncThriftTestHandler { testVoid(): Q.IPromise { //console.log('testVoid()'); return Q.resolve(undefined); } testMapMap(hello: number) { //console.log('testMapMap(' + hello + ')'); 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; } mapmap[4] = pos; mapmap[-4] = neg; 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 } = []; 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 } = []; 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, ) { var hello = new ttypes.Xtruct(); 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") { var x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; throw x; } else if (arg === "TException") { throw new Thrift.TException(arg); } else { return Q.resolve(); } } testMultiException(arg0: string, arg1: string) { if (arg0 === "Xception") { var x = new ttypes.Xception(); x.errorCode = 1001; x.message = "This is an Xception"; throw x; } 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"; throw x2; } var res = new ttypes.Xtruct(); res.string_thing = arg1; return Q.resolve(res); } testOneway(sleepFor: number) {} testString(thing: string) { return Q.resolve(thing); } testBool(thing: boolean) { return Q.resolve(thing); } testByte(thing: number) { return Q.resolve(thing); } testI32(thing: number) { return Q.resolve(thing); } testI64(thing: number) { return Q.resolve(thing); } testDouble(thing: number) { return Q.resolve(thing); } testBinary(thing: Buffer) { return Q.resolve(thing); } testUuid(thing: uuid) { return Q.resolve(thing); } testStruct(thing: ttypes.Xtruct) { return Q.resolve(thing); } testNest(thing: ttypes.Xtruct2) { return Q.resolve(thing); } testMap(thing: { [k: number]: number }) { return Q.resolve(thing); } testStringMap(thing: { [k: string]: string }) { return Q.resolve(thing); } testSet(thing: number[]) { return Q.resolve(thing); } testList(thing: number[]) { return Q.resolve(thing); } testEnum(thing: ttypes.Numberz) { return Q.resolve(thing); } testTypedef(thing: number) { return Q.resolve(thing); } } export class AsyncThriftTestHandler { private syncHandler: SyncThriftTestHandler; constructor() { this.syncHandler = new SyncThriftTestHandler(); } testVoid(callback: (result: void) => void): Q.IPromise { 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 } = []; for (var i = 1; i < 5; i++) { pos[i] = i; neg[-i] = -i; } mapmap[4] = pos; mapmap[-4] = neg; 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 } = []; 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 } = []; insane[1] = first_map; insane[2] = second_map; 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 { var hello = this.syncHandler.testMulti(arg0, arg1, arg2, arg3, arg4, arg5); hello.then((hello) => result(null, hello)); return Q.resolve(); } testException(arg: string, result: (err: any) => void): Q.IPromise { if (arg === "Xception") { var x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; result(x); } 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") { var x = new ttypes.Xception(); x.errorCode = 1001; x.message = "This is an Xception"; result(x); } 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"; result(x2); } else { var res = new ttypes.Xtruct(); res.string_thing = arg1; result(null, res); } return Q.resolve(); } testOneway(sleepFor: number, result: Function) { this.syncHandler.testOneway(sleepFor); } 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 { callback(null, thing); return Q.resolve(); } 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 { callback(null, thing); return Q.resolve(); } 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 { callback(null, thing); return Q.resolve(); } testBinary( thing: Buffer, callback: (err: any, result: Buffer) => void, ): Q.IPromise { callback(null, thing); return Q.resolve(); } testUuid( thing: uuid, callback: (err: any, result: uuid) => void, ): Q.IPromise { callback(null, thing); return Q.resolve(); } 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 { callback(null, thing); return Q.resolve(); } 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 }> { callback(null, thing); return Q.resolve(); } 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 { callback(null, thing); return Q.resolve(); } 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 { callback(null, thing); return Q.resolve(); } } thrift-0.23.0/lib/nodets/test/runClient.sh0000775000175000017500000000076715167543515020727 0ustar00buildbuild00000000000000#! /bin/sh DIR="$( cd "$( dirname "$0" )" && pwd )" mkdir -p $DIR/../test-compiled COMPILEDDIR="$(cd $DIR && cd ../test-compiled && pwd)" export NODE_PATH="${DIR}:${DIR}/../../nodejs/lib:${NODE_PATH}" compile() { #generating thrift code ${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift ${DIR}/../../../compiler/cpp/thrift -o ${COMPILEDDIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift } compile node ${COMPILEDDIR}/client.js $* thrift-0.23.0/lib/nodets/test/test_driver.ts0000664000175000017500000002301215165535636021316 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * 'License'); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // This is the 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"); import ThriftTest = require("./gen-nodejs/ThriftTest"); import thrift = require("thrift"); import Q = thrift.Q; 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) { var checkRecursively = makeRecursiveCheck(assert); function makeAsserter(assertionFn: (a: any, b: any, msg?: string) => void) { return function (c: (string | any)[]) { var fnName = c[0]; var expected = c[1]; (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.deep.forEach(makeAsserter(assert.deepEqual)); 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 }, }; assert.error(err, "testMapMap: no callback error"); assert.deepEqual(expected, response, "testMapMap"); }); 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) { assert.error(err, "testNest: no callback error"); checkRecursively(testCases.out2, response, "testNest"); }); 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("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.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) { 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) { var checkRecursively = makeRecursiveCheck(assert); function fail(msg: string) { 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)[]) { var fnName = c[0]; var expected = c[1]; (client) [fnName](expected) .then(function (actual: any) { assertionFn(actual, expected, fnName); }) .fail(fail("fnName")); }; } testCases.simple.forEach(makeAsserter(assert.equal)); 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) { checkRecursively(testCases.out, response, "testStruct"); }) .fail(fail("testStruct")); Q.resolve(client.testNest(testCases.out2)) .then(function (response) { checkRecursively(testCases.out2, response, "testNest"); }) .fail(fail("testNest")); Q.resolve(client.testInsanity(testCases.crazy)) .then(function (response) { checkRecursively(testCases.insanity, response, "testInsanity"); }) .fail(fail("testInsanity")); Q.resolve(client.testException("TException")) .then(function (response) { fail("testException: TException"); }) .fail(function (err) { assert.ok(err instanceof TException); }); Q.resolve(client.testException("Xception")) .then(function (response) { fail("testException: Xception"); }) .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) { assert.equal(undefined, response); //void }) .fail(fail("testException")); client.testOneway(0, fail("testOneway: should not answer")); checkOffByOne(function (done) { Q.resolve(client.testI32(-1)) .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; var equal = checkRecursively(map1, map2); assert.ok(equal, msg); // deepEqual doesn't work with fields using node-int64 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 ) { var n = new Int64(map2.buffer); return map1 === n.toNumber(); } else { return map1 == map2; } } else { return Object.keys(map1).every(function (key) { return checkRecursively(map1[key], map2[key]); }); } } }; } function checkOffByOne( done: (callback: () => void) => void, callback: (message: string) => void, ) { var retry_limit = 30; var retry_interval = 100; var test_complete = false; var retrys = 0; /** * redo a simple test after the oneway to make sure we aren't "off by one" -- * if the server treated oneway void like normal void, this next test will * fail since it will get the void confirmation rather than the correct * result. In this circumstance, the client will throw the exception: * * 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 () { test_complete = true; }); //We wait up to retry_limit * retry_interval for the test suite to complete function TestForCompletion() { 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", ); } } } setTimeout(TestForCompletion, retry_interval); } thrift-0.23.0/lib/nodets/test/int64.test.ts0000664000175000017500000000672615165535636020723 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Int64 = require("node-int64"); import JSONInt64 = require("json-int64"); import i64types = require("./gen-nodejs/Int64Test_types"); import test = require("tape"); const cases = { "should correctly generate Int64 constants": function (assert) { const EXPECTED_SMALL_INT64_AS_NUMBER: number = 42; const EXPECTED_SMALL_INT64: Int64 = new Int64(42); const EXPECTED_MAX_JS_SAFE_INT64: Int64 = new Int64( Number.MAX_SAFE_INTEGER, ); const EXPECTED_MIN_JS_SAFE_INT64: Int64 = new Int64( Number.MIN_SAFE_INTEGER, ); const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64: Int64 = new Int64( "0020000000000000", ); // hex-encoded const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64: Int64 = new Int64( "ffe0000000000000", ); // hex-encoded 2's complement const EXPECTED_MAX_SIGNED_INT64: Int64 = new Int64("7fffffffffffffff"); // hex-encoded const EXPECTED_MIN_SIGNED_INT64: Int64 = new Int64("8000000000000000"); // hex-encoded 2's complement const EXPECTED_INT64_LIST: Int64[] = [ EXPECTED_SMALL_INT64, EXPECTED_MAX_JS_SAFE_INT64, EXPECTED_MIN_JS_SAFE_INT64, EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64, EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64, EXPECTED_MAX_SIGNED_INT64, EXPECTED_MIN_SIGNED_INT64, ]; assert.ok(EXPECTED_SMALL_INT64.equals(i64types.SMALL_INT64)); assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(i64types.MAX_JS_SAFE_INT64)); assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(i64types.MIN_JS_SAFE_INT64)); assert.ok( EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals( i64types.MAX_JS_SAFE_PLUS_ONE_INT64, ), ); assert.ok( EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals( i64types.MIN_JS_SAFE_MINUS_ONE_INT64, ), ); assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(i64types.MAX_SIGNED_INT64)); assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(i64types.MIN_SIGNED_INT64)); assert.equal( EXPECTED_SMALL_INT64_AS_NUMBER, i64types.SMALL_INT64.toNumber(), ); assert.equal( Number.MAX_SAFE_INTEGER, i64types.MAX_JS_SAFE_INT64.toNumber(), ); assert.equal( Number.MIN_SAFE_INTEGER, i64types.MIN_JS_SAFE_INT64.toNumber(), ); for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { assert.ok(EXPECTED_INT64_LIST[i].equals(i64types.INT64_LIST[i])); } for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { let int64Object = EXPECTED_INT64_LIST[i]; assert.ok( i64types.INT64_2_INT64_MAP[ JSONInt64.toDecimalString(int64Object) ].equals(int64Object), ); } assert.end(); }, }; Object.keys(cases).forEach(function (caseName) { test(caseName, cases[caseName]); }); thrift-0.23.0/lib/nodets/test/client.ts0000664000175000017500000000420215167543515020237 0ustar00buildbuild00000000000000/* * 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 assert = require("assert"); import thrift = require("thrift"); import Thrift = thrift.Thrift; import ThriftTest = require("./gen-nodejs/ThriftTest"); import test_driver = require("./test_driver"); import ThriftTestDriver = test_driver.ThriftTestDriver; import ThriftTestDriverPromise = test_driver.ThriftTestDriverPromise; import { program } from "commander"; program .option("--port ", "Set thrift server port number to connect", (v) => parseInt(v, 10), 9090) .option("--promise", "test with promise style functions") .option('--protocol ', '"Set thrift protocol (binary) [protocol]"') .option('--transport ', '"Set thrift transport (buffered) [transport]"') .parse(process.argv); var opts = program.opts(); var port: number = opts.port; var promise = opts.promise; var options = { transport: Thrift.TBufferedTransport, protocol: Thrift.TBinaryProtocol, }; var testDriver = promise ? ThriftTestDriverPromise : ThriftTestDriver; var connection = thrift.createConnection("localhost", port, options); connection.on("error", function (err: string) { assert(false, err); }); var client = thrift.createClient(ThriftTest.Client, connection); runTests(); function runTests() { testDriver(client, function (status: string) { console.log(status); process.exit(0); }); } exports.expressoTest = function () {}; thrift-0.23.0/lib/nodets/test/runServer.sh0000775000175000017500000000077115167543515020752 0ustar00buildbuild00000000000000#! /bin/sh DIR="$( cd "$( dirname "$0" )" && pwd )" mkdir -p $DIR/../test-compiled COMPILEDDIR="$(cd $DIR && cd ../test-compiled && pwd)" export NODE_PATH="${DIR}:${DIR}/../../nodejs/lib:${NODE_PATH}" compile() { #generating thrift code ${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift ${DIR}/../../../compiler/cpp/thrift -o ${COMPILEDDIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift } compile node ${COMPILEDDIR}/server.js $* thrift-0.23.0/lib/nodets/coding_standards.md0000664000175000017500000000010315165535636021261 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/nodets/Makefile.in0000644000175000017500000004424015170007167017473 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # 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. # We call npm twice to work around npm issues VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/nodets ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ test \ coding_standards.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/nodets/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/nodets/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: $(top_srcdir)/test/ThriftTest.thrift mkdir -p test-compiled $(THRIFT) --gen js:node,ts -o test/ $(top_srcdir)/test/ThriftTest.thrift && $(THRIFT) --gen js:node,ts -o test-compiled $(top_srcdir)/test/ThriftTest.thrift $(THRIFT) --gen js:node,ts -o test/ $(top_srcdir)/test/Int64Test.thrift && $(THRIFT) --gen js:node,ts -o test-compiled $(top_srcdir)/test/Int64Test.thrift ts-compile: stubs mkdir -p test-compiled ../../node_modules/typescript/bin/tsc --outDir test-compiled/ --project test/tsconfig.json deps: $(top_srcdir)/package.json $(NPM) install $(top_srcdir)/ || $(NPM) install $(top_srcdir)/ all-local: deps ts-compile precross: deps stubs ts-compile check: deps ts-compile cd $(top_srcdir) && $(NPM) run test-ts && cd lib/nodets clean-local: $(RM) -r test/gen-nodejs $(RM) -r $(top_srcdir)/node_modules $(RM) -r test-compiled distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/nodets/Makefile.am0000664000175000017500000000336215167543515017474 0ustar00buildbuild00000000000000# 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. # We call npm twice to work around npm issues stubs: $(top_srcdir)/test/ThriftTest.thrift mkdir -p test-compiled $(THRIFT) --gen js:node,ts -o test/ $(top_srcdir)/test/ThriftTest.thrift && $(THRIFT) --gen js:node,ts -o test-compiled $(top_srcdir)/test/ThriftTest.thrift $(THRIFT) --gen js:node,ts -o test/ $(top_srcdir)/test/Int64Test.thrift && $(THRIFT) --gen js:node,ts -o test-compiled $(top_srcdir)/test/Int64Test.thrift ts-compile: stubs mkdir -p test-compiled ../../node_modules/typescript/bin/tsc --outDir test-compiled/ --project test/tsconfig.json deps: $(top_srcdir)/package.json $(NPM) install $(top_srcdir)/ || $(NPM) install $(top_srcdir)/ all-local: deps ts-compile precross: deps stubs ts-compile check: deps ts-compile cd $(top_srcdir) && $(NPM) run test-ts && cd lib/nodets clean-local: $(RM) -r test/gen-nodejs $(RM) -r $(top_srcdir)/node_modules $(RM) -r test-compiled distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ test \ coding_standards.md thrift-0.23.0/lib/dart/0000775000175000017500000000000015170007175015061 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/test/0000775000175000017500000000000015167543515016051 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/test/serializer/0000775000175000017500000000000015167543515020222 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/test/serializer/serializer_test.dart0000664000175000017500000000671515167543515024317 0ustar00buildbuild00000000000000/* * 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. */ library thrift.test.serializer.serializer_test; import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; import 'serializer_test_data.dart'; void main() { var serializer = () { TDeserializer deserializer = TDeserializer(); TSerializer serializer = TSerializer(); TestTObject testTObject = TestTObject(); setUp(() { serializer = TSerializer(); deserializer = TDeserializer(); testTObject = TestTObject(); testTObject.b = true; testTObject.s = "TEST"; testTObject.d = 15.25; testTObject.i = 10; var testList = []; testList.add("TEST 1"); testList.add("TEST 2"); testTObject.l = testList; }); assertNewObjectEqualsTObject(TestTObject newObject) { expect(newObject.l, equals(testTObject.l)); expect(newObject.b, equals(testTObject.b)); expect(newObject.i, equals(testTObject.i)); expect(newObject.d, equals(testTObject.d)); expect(newObject.s, equals(testTObject.s)); } runWriteStringTest() { var s = serializer.writeString(testTObject); var newObject = TestTObject(); deserializer.readString(newObject, s); assertNewObjectEqualsTObject(newObject); } runWriteTest() { var s = serializer.write(testTObject); var newObject = TestTObject(); deserializer.read(newObject, s); assertNewObjectEqualsTObject(newObject); } test('JSON Protocol String', () { serializer.protocol = TJsonProtocol(serializer.transport); deserializer.protocol = TJsonProtocol(deserializer.transport); runWriteStringTest(); }); test('JSON Protocol', () { serializer.protocol = TJsonProtocol(serializer.transport); deserializer.protocol = TJsonProtocol(deserializer.transport); runWriteTest(); }); test('Binary Protocol String', () { serializer.protocol = TBinaryProtocol(serializer.transport); deserializer.protocol = TBinaryProtocol(deserializer.transport); runWriteStringTest(); }); test('Binary Protocol', () { serializer.protocol = TBinaryProtocol(serializer.transport); deserializer.protocol = TBinaryProtocol(deserializer.transport); runWriteTest(); }); test('Compact Protocol String', () { serializer.protocol = TCompactProtocol(serializer.transport); deserializer.protocol = TCompactProtocol(deserializer.transport); runWriteStringTest(); }); test('Compact Protocol', () { serializer.protocol = TCompactProtocol(serializer.transport); deserializer.protocol = TCompactProtocol(deserializer.transport); runWriteTest(); }); }; group('Serializer', serializer); } thrift-0.23.0/lib/dart/test/serializer/serializer_test_data.dart0000664000175000017500000001703715167543515025307 0ustar00buildbuild00000000000000/* * 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. */ library thrift.test.serializer.serializer_test; import 'package:thrift/thrift.dart'; /// TestTObject is a simple test struct class TestTObject implements TBase { static final TStruct _STRUCT_DESC = TStruct("TestTObject"); static final TField _I_FIELD_DESC = TField("i", TType.I32, 1); static final TField _D_FIELD_DESC = TField("d", TType.DOUBLE, 2); static final TField _S_FIELD_DESC = TField("s", TType.STRING, 3); static final TField _L_FIELD_DESC = TField("l", TType.LIST, 4); static final TField _B_FIELD_DESC = TField("b", TType.BOOL, 5); int? _i; static const int I = 1; double? _d; static const int D = 2; String? _s; static const int S = 3; List? _l; static const int L = 4; bool? _b; static const int B = 5; bool __isset_i = false; bool __isset_d = false; bool __isset_b = false; TestTObject(); // i int? get i => this._i; set i(int? i) { this._i = i; this.__isset_i = true; } bool isSetI() => this.__isset_i; unsetI() { this.__isset_i = false; } // d double? get d => this._d; set d(double? d) { this._d = d; this.__isset_d = true; } bool isSetD() => this.__isset_d; unsetD() { this.__isset_d = false; } // s String? get s => this._s; set s(String? s) { this._s = s; } bool isSetS() => this.s != null; unsetS() { this.s = null; } // l List? get l => this._l; set l(List? l) { this._l = l; } bool isSetL() => this.l != null; unsetL() { this.l = null; } // b bool? get b => this._b; set b(bool? b) { this._b = b; this.__isset_b = true; } bool isSetB() => this.__isset_b; unsetB() { this.__isset_b = false; } @override getFieldValue(int fieldID) { switch (fieldID) { case I: return this.i; case D: return this.d; case S: return this.s; case L: return this.l; case B: return this.b; default: throw ArgumentError("Field $fieldID doesn't exist!"); } } @override setFieldValue(int fieldID, Object? value) { switch (fieldID) { case I: if (value == null) { unsetI(); } else { this.i = value as int; } break; case D: if (value == null) { unsetD(); } else { this.d = value as double; } break; case S: if (value == null) { unsetS(); } else { this.s = value as String; } break; case L: if (value == null) { unsetL(); } else { this.l = value as List; } break; case B: if (value == null) { unsetB(); } else { this.b = value as bool; } break; default: throw ArgumentError("Field $fieldID doesn't exist!"); } } // Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise @override bool isSet(int fieldID) { switch (fieldID) { case I: return isSetI(); case D: return isSetD(); case S: return isSetS(); case L: return isSetL(); case B: return isSetB(); default: throw ArgumentError("Field $fieldID doesn't exist!"); } } @override read(TProtocol iprot) { TField field; iprot.readStructBegin(); while (true) { field = iprot.readFieldBegin(); if (field.type == TType.STOP) { break; } switch (field.id) { case I: if (field.type == TType.I32) { this.i = iprot.readI32(); this.__isset_i = true; } else { TProtocolUtil.skip(iprot, field.type); } break; case D: if (field.type == TType.DOUBLE) { this.d = iprot.readDouble(); this.__isset_d = true; } else { TProtocolUtil.skip(iprot, field.type); } break; case S: if (field.type == TType.STRING) { this.s = iprot.readString(); } else { TProtocolUtil.skip(iprot, field.type); } break; case L: if (field.type == TType.LIST) { { TList _list74 = iprot.readListBegin(); this.l = []; for (int _i75 = 0; _i75 < _list74.length; ++_i75) { String _elem76; _elem76 = iprot.readString(); this.l?.add(_elem76); } iprot.readListEnd(); } } else { TProtocolUtil.skip(iprot, field.type); } break; case B: if (field.type == TType.BOOL) { this.b = iprot.readBool(); this.__isset_b = true; } else { TProtocolUtil.skip(iprot, field.type); } break; default: TProtocolUtil.skip(iprot, field.type); break; } iprot.readFieldEnd(); } iprot.readStructEnd(); // check for required fields of primitive type, which can't be checked in the validate method validate(); } @override write(TProtocol oprot) { validate(); oprot.writeStructBegin(_STRUCT_DESC); oprot.writeFieldBegin(_I_FIELD_DESC); oprot.writeI32(this.i!); oprot.writeFieldEnd(); oprot.writeFieldBegin(_D_FIELD_DESC); oprot.writeDouble(this.d!); oprot.writeFieldEnd(); if (this.s != null) { oprot.writeFieldBegin(_S_FIELD_DESC); oprot.writeString(this.s!); oprot.writeFieldEnd(); } if (this.l != null) { oprot.writeFieldBegin(_L_FIELD_DESC); { oprot.writeListBegin(TList(TType.STRING, this.l!.length)); for (var elem77 in this.l!) { oprot.writeString(elem77); } oprot.writeListEnd(); } oprot.writeFieldEnd(); } oprot.writeFieldBegin(_B_FIELD_DESC); oprot.writeBool(this.b!); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } @override String toString() { StringBuffer ret = StringBuffer("TestTObject("); ret.write("i:"); ret.write(this.i); ret.write(", "); ret.write("d:"); ret.write(this.d); ret.write(", "); ret.write("s:"); if (this.s == null) { ret.write("null"); } else { ret.write(this.s); } ret.write(", "); ret.write("l:"); if (this.l == null) { ret.write("null"); } else { ret.write(this.l); } ret.write(", "); ret.write("b:"); ret.write(this.b); ret.write(")"); return ret.toString(); } validate() { // check for required fields // check that fields of type enum have valid values } } thrift-0.23.0/lib/dart/test/transport/0000775000175000017500000000000015167543515020105 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/test/transport/t_framed_transport_test.dart0000664000175000017500000001322215167543515025715 0ustar00buildbuild00000000000000// 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. library thrift.test.transport.t_framed_transport_test; import 'dart:async'; import 'dart:convert' show utf8; import 'dart:typed_data' show Uint8List; import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; void main() { group('TFramedTransport partial reads', () { final flushAwaitDuration = Duration(seconds: 10); late FakeReadOnlySocket socket; late TSocketTransport socketTransport; late TFramedTransport transport; late bool messageAvailable; setUp(() { socket = FakeReadOnlySocket(); socketTransport = TClientSocketTransport(socket); transport = TFramedTransport(socketTransport); messageAvailable = false; }); expectNoReadableBytes() { var readBuffer = Uint8List(128); var readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes); expect(readBytes, 0); expect(messageAvailable, false); } test( 'Test transport reads messages where header and body are sent separately', () async { // buffer into which we'll read var readBuffer = Uint8List(10); var readBytes; // registers for readable bytes var flushFuture = transport.flush().timeout(flushAwaitDuration); flushFuture.then((_) { messageAvailable = true; }); // write header bytes socket.messageController .add(Uint8List.fromList([0x00, 0x00, 0x00, 0x06])); // you shouldn't be able to get any bytes from the read, // because the header has been consumed internally expectNoReadableBytes(); // write first batch of body socket.messageController.add(Uint8List.fromList(utf8.encode("He"))); // you shouldn't be able to get any bytes from the read, // because the frame has been consumed internally expectNoReadableBytes(); // write second batch of body socket.messageController.add(Uint8List.fromList(utf8.encode("llo!"))); // have to wait for the flush to complete, // because it's only then that the frame is available for reading await flushFuture; expect(messageAvailable, true); // at this point the frame is complete, so we expect the read to complete readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes); expect(readBytes, 6); expect(readBuffer.sublist(0, 6), utf8.encode("Hello!")); }); test( 'Test transport reads messages where header is sent in pieces ' 'and body is also sent in pieces', () async { // buffer into which we'll read var readBuffer = Uint8List(10); var readBytes; // registers for readable bytes var flushFuture = transport.flush().timeout(flushAwaitDuration); flushFuture.then((_) { messageAvailable = true; }); // write first part of header bytes socket.messageController.add(Uint8List.fromList([0x00, 0x00])); // you shouldn't be able to get any bytes from the read expectNoReadableBytes(); // write second part of header bytes socket.messageController.add(Uint8List.fromList([0x00, 0x03])); // you shouldn't be able to get any bytes from the read again // because only the header was read, and there's no frame body readBytes = expectNoReadableBytes(); // write first batch of body socket.messageController.add(Uint8List.fromList(utf8.encode("H"))); // you shouldn't be able to get any bytes from the read, // because the frame has been consumed internally expectNoReadableBytes(); // write second batch of body socket.messageController.add(Uint8List.fromList(utf8.encode("i!"))); // have to wait for the flush to complete, // because it's only then that the frame is available for reading await flushFuture; expect(messageAvailable, true); // at this point the frame is complete, so we expect the read to complete readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes); expect(readBytes, 3); expect(readBuffer.sublist(0, 3), utf8.encode("Hi!")); }); }); } class FakeReadOnlySocket extends TSocket { StreamController messageController = StreamController(sync: true); StreamController errorController = StreamController(); StreamController stateController = StreamController(); @override Future close() async { messageController.close(); errorController.close(); stateController.close(); } @override bool get isClosed => false; @override bool get isOpen => true; @override Stream get onError => errorController.stream; @override Stream get onMessage => messageController.stream; @override Stream get onState => stateController.stream; @override Future open() async { // noop } @override void send(Uint8List data) { // noop } } thrift-0.23.0/lib/dart/test/transport/t_http_transport_test.dart0000664000175000017500000001242215167543515025437 0ustar00buildbuild00000000000000// 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. library thrift.test.transport.t_socket_transport_test; import 'dart:async'; import 'dart:convert' show Encoding; import 'dart:convert' show Utf8Codec; import 'dart:convert' show base64; import 'dart:typed_data' show Uint8List; import 'package:http/http.dart' show BaseRequest; import 'package:http/http.dart' show Client; import 'package:http/http.dart' show Response; import 'package:http/http.dart' show StreamedResponse; import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; void main() { const utf8Codec = Utf8Codec(); group('THttpClientTransport', () { late FakeHttpClient client; late THttpClientTransport transport; setUp(() { client = FakeHttpClient(sync: false); var config = THttpConfig(Uri.parse('http://localhost'), {}); transport = THttpClientTransport(client, config); }); test('Test transport sends body', () async { var expectedText = 'my request'; transport.writeAll(utf8Codec.encode(expectedText)); expect(client.postRequest, isEmpty); await transport.flush(); expect(client.postRequest, isNotEmpty); var requestText = utf8Codec.decode(base64.decode(client.postRequest)); expect(requestText, expectedText); }); test('Test transport receives response', () async { var expectedText = 'my response'; var expectedBytes = utf8Codec.encode(expectedText); client.postResponse = base64.encode(expectedBytes); transport.writeAll(utf8Codec.encode('my request')); expect(transport.hasReadData, isFalse); await transport.flush(); expect(transport.hasReadData, isTrue); var buffer = Uint8List(expectedBytes.length); transport.readAll(buffer, 0, expectedBytes.length); var bufferText = utf8Codec.decode(buffer); expect(bufferText, expectedText); }); }); group('THttpClientTransport with multiple messages', () { late FakeHttpClient client; late THttpClientTransport transport; setUp(() { client = FakeHttpClient(sync: true); var config = THttpConfig(Uri.parse('http://localhost'), {}); transport = THttpClientTransport(client, config); }); test('Test read correct buffer after flush', () async { String bufferText= ""; var expectedText = 'response 1'; var expectedBytes = utf8Codec.encode(expectedText); // prepare a response transport.writeAll(utf8Codec.encode('request 1')); client.postResponse = base64.encode(expectedBytes); Future responseReady = transport.flush().then((_) { var buffer = Uint8List(expectedBytes.length); transport.readAll(buffer, 0, expectedBytes.length); bufferText = utf8Codec.decode(buffer); }); // prepare a second response transport.writeAll(utf8Codec.encode('request 2')); var response2Bytes = utf8Codec.encode('response 2'); client.postResponse = base64.encode(response2Bytes); await transport.flush(); await responseReady; expect(bufferText, expectedText); }); }); } class FakeHttpClient implements Client { String postResponse = ''; String postRequest = ''; final bool sync; FakeHttpClient({this.sync = false}); @override Future post(url, {Map? headers, body, Encoding? encoding}) { postRequest = body.toString(); var response = Response(postResponse, 200); if (sync) { return Future.sync(() => response); } else { return Future.value(response); } } @override Future head(url, {Map? headers}) => throw UnimplementedError(); @override Future get(url, {Map? headers}) => throw UnimplementedError(); @override Future put(url, {Map? headers, body, Encoding? encoding}) => throw UnimplementedError(); @override Future patch(url, {Map? headers, body, Encoding? encoding}) => throw UnimplementedError(); @override Future delete(Uri url, {Map? headers, Object? body, Encoding? encoding}) => throw UnimplementedError(); @override Future read(url, {Map? headers}) => throw UnimplementedError(); @override Future readBytes(url, {Map? headers}) => throw UnimplementedError(); @override Future send(BaseRequest request) => throw UnimplementedError(); @override void close() => throw UnimplementedError(); } thrift-0.23.0/lib/dart/test/transport/t_socket_transport_test.dart0000664000175000017500000002304215167543515025750 0ustar00buildbuild00000000000000// 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. library thrift.test.transport.t_socket_transport_test; import 'dart:async'; import 'dart:convert' show Utf8Codec, base64; import 'dart:typed_data' show Uint8List; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; void main() { const utf8Codec = Utf8Codec(); final requestText = 'my test request'; final requestBytes = Uint8List.fromList(utf8Codec.encode(requestText)); final requestBase64 = base64.encode(requestBytes); final responseText = 'response 1'; final responseBytes = Uint8List.fromList(utf8Codec.encode(responseText)); final responseBase64 = base64.encode(responseBytes); final framedResponseBase64 = base64.encode(_getFramedResponse(responseBytes)); group('TClientSocketTransport', () { late FakeSocket socket; late TTransport transport; setUp(() async { socket = FakeSocket(sync: false); await socket.open(); transport = TClientSocketTransport(socket); await transport.open(); transport.writeAll(requestBytes); }); test('Test client sending data over transport', () async { expect(socket.sendPayload, isNull); Future responseReady = transport.flush(); // allow microtask events to finish await Future.value(); expect(socket.sendPayload, isNotNull); expect(socket.sendPayload, requestBytes); // simulate a response socket.receiveFakeMessage(responseBase64); await responseReady; var buffer = Uint8List(responseBytes.length); transport.readAll(buffer, 0, responseBytes.length); var bufferText = utf8Codec.decode(buffer); expect(bufferText, responseText); }); }, timeout: Timeout(Duration(seconds: 1))); group('TClientSocketTransport with FramedTransport', () { late FakeSocket socket; late TTransport transport; setUp(() async { socket = FakeSocket(sync: true); await socket.open(); transport = TFramedTransport(TClientSocketTransport(socket)); await transport.open(); transport.writeAll(requestBytes); }); test('Test client sending data over framed transport', () async { String bufferText = ""; Future responseReady = transport.flush().then((_) { var buffer = Uint8List(responseBytes.length); transport.readAll(buffer, 0, responseBytes.length); bufferText = utf8Codec.decode(buffer); }); // simulate a response socket.receiveFakeMessage(framedResponseBase64); await responseReady; expect(bufferText, responseText); }); }, timeout: Timeout(Duration(seconds: 1))); group('TAsyncClientSocketTransport', () { late FakeSocket socket; late FakeProtocolFactory protocolFactory; late TTransport transport; setUp(() async { socket = FakeSocket(sync: true); await socket.open(); protocolFactory = FakeProtocolFactory(); protocolFactory.message = TMessage('foo', TMessageType.CALL, 123); transport = TAsyncClientSocketTransport( socket, TMessageReader(protocolFactory), responseTimeout: Duration.zero); await transport.open(); transport.writeAll(requestBytes); }); test('Test response correlates to correct request', () async { String bufferText = ""; Future responseReady = transport.flush().then((_) { var buffer = Uint8List(responseBytes.length); transport.readAll(buffer, 0, responseBytes.length); bufferText = utf8Codec.decode(buffer); }); // simulate a response protocolFactory.message = TMessage('foo', TMessageType.REPLY, 123); socket.receiveFakeMessage(responseBase64); // simulate a second response var response2Text = 'response 2'; var response2Bytes = Uint8List.fromList(utf8Codec.encode(response2Text)); var response2Base64 = base64.encode(response2Bytes); protocolFactory.message = TMessage('foo2', TMessageType.REPLY, 124); socket.receiveFakeMessage(response2Base64); await responseReady; expect(bufferText, responseText); }); test('Test response timeout', () async { Future responseReady = transport.flush(); expect(responseReady, throwsA(isA())); }); }, timeout: Timeout(Duration(seconds: 1))); group('TAsyncClientSocketTransport with TFramedTransport', () { late FakeSocket socket; late FakeProtocolFactory protocolFactory; late TTransport transport; setUp(() async { socket = FakeSocket(sync: true); await socket.open(); protocolFactory = FakeProtocolFactory(); protocolFactory.message = TMessage('foo', TMessageType.CALL, 123); var messageReader = TMessageReader(protocolFactory, byteOffset: TFramedTransport.headerByteCount); transport = TFramedTransport(TAsyncClientSocketTransport( socket, messageReader, responseTimeout: Duration.zero)); await transport.open(); transport.writeAll(requestBytes); }); test('Test async client sending data over framed transport', () async { String bufferText = ""; Future responseReady = transport.flush().then((_) { var buffer = Uint8List(responseBytes.length); transport.readAll(buffer, 0, responseBytes.length); bufferText = utf8Codec.decode(buffer); }); // simulate a response protocolFactory.message = TMessage('foo', TMessageType.REPLY, 123); socket.receiveFakeMessage(framedResponseBase64); await responseReady; expect(bufferText, responseText); }); }, timeout: Timeout(Duration(seconds: 1))); group('TServerTransport', () { test('Test server transport listens to socket', () async { var socket = FakeSocket(); await socket.open(); expect(socket.isOpen, isTrue); var transport = TServerSocketTransport(socket); expect(transport.hasReadData, isFalse); socket.receiveFakeMessage(requestBase64); // allow microtask events to finish await Future.value(); expect(transport.hasReadData, isTrue); var buffer = Uint8List(requestBytes.length); transport.readAll(buffer, 0, requestBytes.length); var bufferText = utf8Codec.decode(buffer); expect(bufferText, requestText); }); test('Test server sending data over transport', () async { var socket = FakeSocket(); await socket.open(); var transport = TServerSocketTransport(socket); transport.writeAll(responseBytes); expect(socket.sendPayload, isNull); transport.flush(); // allow microtask events to finish await Future.value(); expect(socket.sendPayload, isNotNull); expect(socket.sendPayload, responseBytes); }); }, timeout: Timeout(Duration(seconds: 1))); } class FakeSocket extends TSocket { final StreamController _onStateController; @override Stream get onState => _onStateController.stream; final StreamController _onErrorController; @override Stream get onError => _onErrorController.stream; final StreamController _onMessageController; @override Stream get onMessage => _onMessageController.stream; FakeSocket({bool sync = false}) : _onStateController = StreamController.broadcast(sync: sync), _onErrorController = StreamController.broadcast(sync: sync), _onMessageController = StreamController.broadcast(sync: sync); bool _isOpen = false; @override bool get isOpen => _isOpen; @override bool get isClosed => !isOpen; @override Future open() async { _isOpen = true; _onStateController.add(TSocketState.OPEN); } @override Future close() async { _isOpen = false; _onStateController.add(TSocketState.CLOSED); } Uint8List? _sendPayload; Uint8List? get sendPayload => _sendPayload; @override void send(Uint8List data) { if (!isOpen) throw StateError('The socket is not open'); _sendPayload = data; } void receiveFakeMessage(String base64text) { if (!isOpen) throw StateError('The socket is not open'); var message = Uint8List.fromList(base64.decode(base64text)); _onMessageController.add(message); } } class FakeProtocolFactory implements TProtocolFactory { FakeProtocolFactory(); TMessage message = TMessage("", TMessageType.CALL, 0 /* seqid */); @override getProtocol(TTransport transport) => FakeProtocol(message); } class FakeProtocol extends Mock implements TProtocol { FakeProtocol(this._message); TMessage _message; @override readMessageBegin() => _message; } Uint8List _getFramedResponse(Uint8List responseBytes) { var byteOffset = TFramedTransport.headerByteCount; var response = Uint8List(byteOffset + responseBytes.length); response.buffer.asByteData().setInt32(0, responseBytes.length); response.setAll(byteOffset, responseBytes); return response; } thrift-0.23.0/lib/dart/test/transport/t_transport_test.dart0000664000175000017500000000270415167543515024402 0ustar00buildbuild00000000000000// 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. library thrift.test.transport.t_socket_transport_test; import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; /// Common transport tests void main() { group('TTransportFactory', () { test('transport is returned from base factory', () async { TTransport result; TTransport? transport; var factory = TTransportFactory(); try { result = await factory.getTransport(transport!); expect(result, isNull); } catch (e) { expect(e, isA()); } transport = TBufferedTransport()..open(); result = await factory.getTransport(transport); expect(result, transport); }); }); } thrift-0.23.0/lib/dart/test/t_application_error_test.dart0000664000175000017500000000276515167543515024035 0ustar00buildbuild00000000000000// 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. library thrift.test.t_application_error_test; import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; void main() { late TProtocol protocol; setUp(() { protocol = TBinaryProtocol(TBufferedTransport()); }); test('Write and read an application error', () { var expectedType = TApplicationErrorType.INTERNAL_ERROR; var expectedMessage = 'test error message'; TApplicationError error = TApplicationError(expectedType, expectedMessage); error.write(protocol); protocol.transport.flush(); TApplicationError subject = TApplicationError.read(protocol); expect(subject, isNotNull); expect(subject.type, expectedType); expect(subject.message, expectedMessage); }); } thrift-0.23.0/lib/dart/test/protocol/0000775000175000017500000000000015167543515017712 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/test/protocol/t_protocol_test.dart0000664000175000017500000002631015167543515024013 0ustar00buildbuild00000000000000// 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. library thrift.test.transport.t_json_protocol_test; import 'dart:async'; import 'dart:convert' show utf8; import 'dart:typed_data' show Uint8List; import 'package:test/test.dart'; import 'package:thrift/thrift.dart'; void main() { final message = TMessage('my message', TMessageType.ONEWAY, 123); late TProtocol protocol; Primitive getPrimitive(int tType) { switch (tType) { case TType.BOOL: return Primitive(protocol.readBool, protocol.writeBool, false); case TType.BYTE: return Primitive(protocol.readByte, protocol.writeByte, 0); case TType.I16: return Primitive(protocol.readI16, protocol.writeI16, 0); case TType.I32: return Primitive(protocol.readI32, protocol.writeI32, 0); case TType.I64: return Primitive(protocol.readI64, protocol.writeI64, 0); case TType.DOUBLE: return Primitive(protocol.readDouble, protocol.writeDouble, 0); case TType.STRING: return Primitive(protocol.readString, protocol.writeString, ''); default: throw UnsupportedError("Unsupported TType $tType"); } } Future primitiveTest(Primitive primitive, input) async { primitive.write(input); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = primitive.read(); expect(output, input); } /*Future primitiveNullTest(Primitive primitive) async { primitive.write(null); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = primitive.read(); expect(output, primitive.defaultValue); }*/ var sharedTests = () { test('Test message', () async { protocol.writeMessageEnd(); await protocol.transport.flush(); var subject = protocol.readMessageBegin(); expect(subject.name, message.name); expect(subject.type, message.type); expect(subject.seqid, message.seqid); }); test('Test struct', () async { var input = TStruct(); protocol.writeStructBegin(input); protocol.writeStructEnd(); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = protocol.readStructBegin(); // name is not serialized, see C# version for reference expect(output, isNotNull); }); test('Test field', () async { var input = TField('my field', TType.MAP, 123); protocol.writeFieldBegin(input); protocol.writeFieldEnd(); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = protocol.readFieldBegin(); // name is not serialized, see C# version for reference expect(output.type, input.type); expect(output.id, input.id); }); test('Test map', () async { var input = TMap(TType.STRING, TType.STRUCT, 123); protocol.writeMapBegin(input); protocol.writeMapEnd(); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = protocol.readMapBegin(); expect(output.keyType, input.keyType); expect(output.valueType, input.valueType); expect(output.length, input.length); }); test('Test list', () async { var input = TList(TType.STRING, 123); protocol.writeListBegin(input); protocol.writeListEnd(); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = protocol.readListBegin(); expect(output.elementType, input.elementType); expect(output.length, input.length); }); test('Test set', () async { var input = TSet(TType.STRING, 123); protocol.writeSetBegin(input); protocol.writeSetEnd(); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = protocol.readListBegin(); expect(output.elementType, input.elementType); expect(output.length, input.length); }); test('Test bool', () async { await primitiveTest(getPrimitive(TType.BOOL), true); }); /* test('Test bool null', () async { await primitiveNullTest(getPrimitive(TType.BOOL)); }); */ test('Test byte', () async { await primitiveTest(getPrimitive(TType.BYTE), 64); }); /* test('Test byte null', () async { await primitiveNullTest(getPrimitive(TType.BYTE)); }); */ test('Test I16', () async { await primitiveTest(getPrimitive(TType.I16), 32767); }); /* test('Test I16 null', () async { await primitiveNullTest(getPrimitive(TType.I16)); }); */ test('Test I32', () async { await primitiveTest(getPrimitive(TType.I32), 2147483647); }); /* test('Test I32 null', () async { await primitiveNullTest(getPrimitive(TType.I32)); }); */ test('Test I64', () async { await primitiveTest(getPrimitive(TType.I64), 9223372036854775807); }); /* test('Test I64 null', () async { await primitiveNullTest(getPrimitive(TType.I64)); }); */ test('Test double', () async { await primitiveTest(getPrimitive(TType.DOUBLE), 3.1415926); }); /* test('Test double null', () async { await primitiveNullTest(getPrimitive(TType.DOUBLE)); }); */ test('Test string', () async { var input = 'There are only two hard things in computer science: ' 'cache invalidation, naming things, and off-by-one errors.'; await primitiveTest(getPrimitive(TType.STRING), input); }); /* test('Test string null', () async { await primitiveNullTest(getPrimitive(TType.STRING)); }); */ test('Test binary', () async { var input = Uint8List.fromList(List.filled(100, 123)); protocol.writeBinary(input); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); var output = protocol.readBinary(); expect(output.length, input.length); expect(output.every((i) => i == 123), isTrue); }); test('Test complex struct', () async { // {1: {10: 20}, 2: {30: 40}} protocol.writeStructBegin(TStruct()); protocol.writeFieldBegin(TField('success', TType.MAP, 0)); protocol.writeMapBegin(TMap(TType.I32, TType.MAP, 2)); protocol.writeI32(1); // key protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1)); protocol.writeI32(10); // key protocol.writeI32(20); // value protocol.writeMapEnd(); protocol.writeI32(2); // key protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1)); protocol.writeI32(30); // key protocol.writeI32(40); // value protocol.writeMapEnd(); protocol.writeMapEnd(); protocol.writeFieldEnd(); protocol.writeFieldStop(); protocol.writeStructEnd(); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); protocol.readStructBegin(); expect(protocol.readFieldBegin().type, TType.MAP); expect(protocol.readMapBegin().length, 2); expect(protocol.readI32(), 1); // key expect(protocol.readMapBegin().length, 1); expect(protocol.readI32(), 10); // key expect(protocol.readI32(), 20); // value protocol.readMapEnd(); expect(protocol.readI32(), 2); // key expect(protocol.readMapBegin().length, 1); expect(protocol.readI32(), 30); // key expect(protocol.readI32(), 40); // value protocol.readMapEnd(); protocol.readMapEnd(); protocol.readFieldEnd(); protocol.readStructEnd(); protocol.readMessageEnd(); }); test('Test nested maps and lists', () async { // {1: [{10: 20}], 2: [{30: 40}]} protocol.writeMapBegin(TMap(TType.I32, TType.LIST, 2)); protocol.writeI32(1); // key protocol.writeListBegin(TList(TType.MAP, 1)); protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1)); protocol.writeI32(10); // key protocol.writeI32(20); // value protocol.writeMapEnd(); protocol.writeListEnd(); protocol.writeI32(2); // key protocol.writeListBegin(TList(TType.MAP, 1)); protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1)); protocol.writeI32(30); // key protocol.writeI32(40); // value protocol.writeMapEnd(); protocol.writeListEnd(); protocol.writeMapEnd(); protocol.writeMessageEnd(); await protocol.transport.flush(); protocol.readMessageBegin(); expect(protocol.readMapBegin().length, 2); expect(protocol.readI32(), 1); // key expect(protocol.readListBegin().length, 1); expect(protocol.readMapBegin().length, 1); expect(protocol.readI32(), 10); // key expect(protocol.readI32(), 20); // value protocol.readMapEnd(); protocol.readListEnd(); expect(protocol.readI32(), 2); // key expect(protocol.readListBegin().length, 1); expect(protocol.readMapBegin().length, 1); expect(protocol.readI32(), 30); // key expect(protocol.readI32(), 40); // value protocol.readMapEnd(); protocol.readListEnd(); protocol.readMapEnd(); protocol.readMessageEnd(); }); }; group('JSON', () { setUp(() { protocol = TJsonProtocol(TBufferedTransport()); protocol.writeMessageBegin(message); }); test('Test escaped unicode', () async { /* KOR_KAI UTF-8: 0xE0 0xB8 0x81 UTF-16: 0x0E01 G clef: UTF-8: 0xF0 0x9D 0x84 0x9E UTF-16: 0xD834 0xDD1E */ var buffer = utf8.encode(r'"\u0001\u0e01 \ud834\udd1e"'); var transport = TBufferedTransport(); transport.writeAll(buffer); var protocol = TJsonProtocol(transport); await protocol.transport.flush(); var subject = protocol.readString(); expect(subject, utf8.decode([0x01, 0xE0, 0xB8, 0x81, 0x20, 0xF0, 0x9D, 0x84, 0x9E])); }); group('shared tests', sharedTests); }); group('binary', () { setUp(() { protocol = TBinaryProtocol(TBufferedTransport()); protocol.writeMessageBegin(message); }); group('shared tests', sharedTests); }); group('compact', () { setUp(() { protocol = TCompactProtocol(TBufferedTransport()); protocol.writeMessageBegin(message); }); group('shared tests', sharedTests); }); } class Primitive { final Function read; final Function write; final defaultValue; Primitive(this.read, this.write, this.defaultValue); } thrift-0.23.0/lib/dart/coding_standards.md0000664000175000017500000000037315165535636020730 0ustar00buildbuild00000000000000# Dart Coding Standards ### Please follow: * [Thrift General Coding Standards](/doc/coding_standards.md) * [Use dartfmt](https://www.dartlang.org/tools/dartfmt/) and follow the [Dart Style Guide](https://www.dartlang.org/articles/style-guide/) thrift-0.23.0/lib/dart/LICENSE0000664000175000017500000000135515165535636016106 0ustar00buildbuild00000000000000Licensed 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. thrift-0.23.0/lib/dart/analysis_options.yaml0000664000175000017500000000150415165535636021357 0ustar00buildbuild00000000000000# # 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: package:workiva_analysis_options/v1.yaml thrift-0.23.0/lib/dart/README.md0000664000175000017500000000154415165535636016360 0ustar00buildbuild00000000000000Thrift Dart Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Thrift with Dart ==================== Dart 1.24.3 or newer is required thrift-0.23.0/lib/dart/lib/0000775000175000017500000000000015165535636015643 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/lib/src/0000775000175000017500000000000015167543515016427 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/lib/src/serializer/0000775000175000017500000000000015167543515020600 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/lib/src/serializer/t_serializer.dart0000664000175000017500000000273615167543515024160 0ustar00buildbuild00000000000000/// 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. part of thrift; class TSerializer { final message = TMessage('Serializer', TMessageType.ONEWAY, 1); late TBufferedTransport transport; late TProtocol protocol; TSerializer({TProtocolFactory? protocolFactory}) { this.transport = TBufferedTransport(); if (protocolFactory == null) { protocolFactory = TBinaryProtocolFactory(); } this.protocol = protocolFactory.getProtocol(this.transport); } Uint8List write(TBase base) { base.write(protocol); return transport.consumeWriteBuffer(); } String writeString(TBase base) { base.write(protocol); Uint8List bytes = transport.consumeWriteBuffer(); return base64.encode(bytes); } } thrift-0.23.0/lib/dart/lib/src/serializer/t_deserializer.dart0000664000175000017500000000275515167543515024472 0ustar00buildbuild00000000000000/// 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. part of thrift; class TDeserializer { final message = TMessage('Deserializer', TMessageType.ONEWAY, 1); late TBufferedTransport transport; late TProtocol protocol; TDeserializer({TProtocolFactory? protocolFactory}) { this.transport = TBufferedTransport(); if (protocolFactory == null) { protocolFactory = TBinaryProtocolFactory(); } this.protocol = protocolFactory.getProtocol(this.transport); } void read(TBase base, Uint8List data) { transport.writeAll(data); transport.flush(); base.read(protocol); } void readString(TBase base, String data) { transport.writeAll(base64.decode(data)); transport.flush(); base.read(protocol); } } thrift-0.23.0/lib/dart/lib/src/t_application_error.dart0000664000175000017500000000573215167543515023351 0ustar00buildbuild00000000000000/// 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. part of thrift; class TApplicationErrorType { static const int UNKNOWN = 0; static const int UNKNOWN_METHOD = 1; static const int INVALID_MESSAGE_TYPE = 2; static const int WRONG_METHOD_NAME = 3; static const int BAD_SEQUENCE_ID = 4; static const int MISSING_RESULT = 5; static const int INTERNAL_ERROR = 6; static const int PROTOCOL_ERROR = 7; static const int INVALID_TRANSFORM = 8; static const int INVALID_PROTOCOL = 9; static const int UNSUPPORTED_CLIENT_TYPE = 10; } class TApplicationError extends TError { static final TStruct _struct = TStruct("TApplicationError"); static const int MESSAGE = 1; static final TField _messageField = TField("message", TType.STRING, MESSAGE); static const int TYPE = 2; static final TField _typeField = TField("type", TType.I32, TYPE); TApplicationError( [int type = TApplicationErrorType.UNKNOWN, String message = ""]) : super(type, message); static TApplicationError read(TProtocol iprot) { TField field; String message = ""; int type = TApplicationErrorType.UNKNOWN; iprot.readStructBegin(); while (true) { field = iprot.readFieldBegin(); if (field.type == TType.STOP) { break; } switch (field.id) { case MESSAGE: if (field.type == TType.STRING) { message = iprot.readString(); } else { TProtocolUtil.skip(iprot, field.type); } break; case TYPE: if (field.type == TType.I32) { type = iprot.readI32(); } else { TProtocolUtil.skip(iprot, field.type); } break; default: TProtocolUtil.skip(iprot, field.type); break; } iprot.readFieldEnd(); } iprot.readStructEnd(); return TApplicationError(type, message); } write(TProtocol oprot) { oprot.writeStructBegin(_struct); if (message.isNotEmpty) { oprot.writeFieldBegin(_messageField); oprot.writeString(message); oprot.writeFieldEnd(); } oprot.writeFieldBegin(_typeField); oprot.writeI32(type); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } } thrift-0.23.0/lib/dart/lib/src/t_error.dart0000664000175000017500000000177215165535636020771 0ustar00buildbuild00000000000000/// 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. part of thrift; class TError extends Error { final String message; final int type; TError(this.type, this.message); @override String toString() => ""; } thrift-0.23.0/lib/dart/lib/src/console/0000775000175000017500000000000015167543515020071 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/lib/src/console/t_tcp_socket.dart0000664000175000017500000000477515167543515023443 0ustar00buildbuild00000000000000/// 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. library thrift.src.console.t_tcp_socket; import 'dart:async'; import 'dart:io'; import 'dart:typed_data' show Uint8List; import 'package:thrift/thrift.dart'; /// A [TSocket] backed by a [Socket] from dart:io class TTcpSocket implements TSocket { final StreamController _onStateController; @override Stream get onState => _onStateController.stream; final StreamController _onErrorController; @override Stream get onError => _onErrorController.stream; final StreamController _onMessageController; @override Stream get onMessage => _onMessageController.stream; TTcpSocket(Socket? socket) : _onStateController = StreamController.broadcast(), _onErrorController = StreamController.broadcast(), _onMessageController = StreamController.broadcast() { if (socket == null) { throw ArgumentError.notNull('socket'); } _socket = socket; _socket!.listen(_onMessage, onError: _onError, onDone: close); } Socket? _socket; @override bool get isOpen => _socket != null; @override bool get isClosed => _socket == null; @override Future open() async { _onStateController.add(TSocketState.OPEN); } @override Future close() async { if (_socket != null) { await _socket!.close(); _socket = null; } _onStateController.add(TSocketState.CLOSED); } @override void send(Uint8List data) { if (_socket != null) { _socket!.add(data); } } void _onMessage(List message) { Uint8List data = Uint8List.fromList(message); _onMessageController.add(data); } void _onError(Object error) { close(); _onErrorController.add('$error'); } } thrift-0.23.0/lib/dart/lib/src/console/t_web_socket.dart0000664000175000017500000000555215167543515023424 0ustar00buildbuild00000000000000/// 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. library thrift.src.console.t_web_socket; import 'dart:async'; import 'dart:convert' show base64; import 'dart:io'; import 'dart:typed_data' show Uint8List; import 'package:thrift/thrift.dart'; /// A [TSocket] backed by a [WebSocket] from dart:io class TWebSocket implements TSocket { final StreamController _onStateController; @override Stream get onState => _onStateController.stream; final StreamController _onErrorController; @override Stream get onError => _onErrorController.stream; final StreamController _onMessageController; @override Stream get onMessage => _onMessageController.stream; TWebSocket(WebSocket? socket) : _onStateController = StreamController.broadcast(), _onErrorController = StreamController.broadcast(), _onMessageController = StreamController.broadcast() { if (socket == null) { throw ArgumentError.notNull('socket'); } _socket = socket; _socket!.listen((dynamic message) => _onMessage(message as String), onError: (dynamic error) => _onError(error), onDone: () => close(),); } WebSocket? _socket; @override bool get isOpen => _socket != null; @override bool get isClosed => _socket == null; @override Future open() async { _onStateController.add(TSocketState.OPEN); } @override Future close() async { if (_socket != null) { await _socket!.close(); _socket = null; } _onStateController.add(TSocketState.CLOSED); } @override void send(Uint8List data) { if (_socket != null) { _socket!.add(base64.encode(data)); } } void _onMessage(String message) { try { Uint8List data = Uint8List.fromList(base64.decode(message)); _onMessageController.add(data); } on FormatException catch (_) { var error = TProtocolError(TProtocolErrorType.INVALID_DATA, "Expected a Base 64 encoded string."); _onErrorController.add(error); } } void _onError(Object error) { close(); _onErrorController.add('$error'); } } thrift-0.23.0/lib/dart/lib/src/t_base.dart0000664000175000017500000000262615165535636020551 0ustar00buildbuild00000000000000/// 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. part of thrift; abstract class TBase { /// Reads the TObject from the given input protocol. void read(TProtocol iprot); /// Writes the objects out to the [oprot] protocol. void write(TProtocol oprot); /// Check if a field is currently set or unset, using the [fieldId]. bool isSet(int fieldId); /// Get a field's value by [fieldId]. Primitive types will be wrapped in the /// appropriate "boxed" types. getFieldValue(int fieldId); /// Set a field's value by [fieldId]. Primitive types must be "boxed" in the /// appropriate object wrapper type. setFieldValue(int fieldId, Object value); } thrift-0.23.0/lib/dart/lib/src/transport/0000775000175000017500000000000015167543515020463 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/lib/src/transport/t_transport_factory.dart0000664000175000017500000000210615165535636025447 0ustar00buildbuild00000000000000/// 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. part of thrift; /// Factory class used to create wrapped instance of a [TTransport]. This is /// used primarily in servers. /// /// Adapted from the Java version. class TTransportFactory { Future getTransport(TTransport transport) => Future.value(transport); } thrift-0.23.0/lib/dart/lib/src/transport/t_http_transport.dart0000664000175000017500000000554015167543515024761 0ustar00buildbuild00000000000000/// 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. part of thrift; /// HTTP implementation of [TTransport]. /// /// For example: /// /// var transport = new THttpClientTransport(new BrowserClient(), /// new THttpConfig(url, {'X-My-Custom-Header': 'my value'})); /// var protocol = new TJsonProtocol(transport); /// var client = new MyThriftServiceClient(protocol); /// var result = client.myMethod(); /// /// Adapted from the JS XHR HTTP transport. class THttpClientTransport extends TBufferedTransport { final Client httpClient; final THttpConfig config; THttpClientTransport(this.httpClient, this.config) { /*if (httpClient == null) { throw ArgumentError.notNull("httpClient"); }*/ } @override Future close() async { _reset(isOpen: false); httpClient.close(); } @override Future flush() { var requestBody = base64.encode(consumeWriteBuffer()); // Use a sync completer to ensure that the buffer can be read immediately // after the read buffer is set, and avoid a race condition where another // response could overwrite the read buffer. var completer = Completer.sync(); httpClient .post(config.url, headers: config.headers, body: requestBody) .then((response) { Uint8List data; try { data = Uint8List.fromList(base64.decode(response.body)); } on FormatException catch (_) { throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Expected a Base 64 encoded string."); } _setReadBuffer(data); completer.complete(); }); return completer.future; } } class THttpConfig { final Uri url; late Map _headers; Map get headers => _headers; THttpConfig(this.url, Map headers) { if (!url.hasAuthority) { throw ArgumentError("Invalid url"); } _initHeaders(headers); } void _initHeaders(Map initial) { var h = {}; h.addAll(initial); h['Content-Type'] = 'application/x-thrift'; h['Accept'] = 'application/x-thrift'; _headers = Map.unmodifiable(h); } } thrift-0.23.0/lib/dart/lib/src/transport/t_message_reader.dart0000664000175000017500000000562615167543515024641 0ustar00buildbuild00000000000000/// 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. part of thrift; /// [TMessageReader] extracts a [TMessage] from bytes. This is used to allow a /// transport to inspect the message seqid and map responses to requests. class TMessageReader { final TProtocolFactory protocolFactory; final int byteOffset; final _TMessageReaderTransport _transport; /// Construct a [MessageReader]. The optional [byteOffset] specifies the /// number of bytes to skip before reading the [TMessage]. TMessageReader(this.protocolFactory, {int byteOffset = 0}) : _transport = _TMessageReaderTransport(), this.byteOffset = byteOffset; TMessage readMessage(Uint8List bytes) { _transport.reset(bytes, byteOffset); TProtocol protocol = protocolFactory.getProtocol(_transport); TMessage message = protocol.readMessageBegin(); _transport.reset(null); return message; } } /// An internal class used to support [TMessageReader]. class _TMessageReaderTransport extends TTransport { _TMessageReaderTransport(); Iterator? _readIterator; void reset(Uint8List? bytes, [int offset = 0]) { if (bytes == null) { _readIterator = null; return; } if (offset > bytes.length) { throw ArgumentError("The offset exceeds the bytes length"); } _readIterator = bytes.skip(offset).iterator; } @override get isOpen => true; @override Future open() => throw UnsupportedError("Unsupported in MessageReader"); @override Future close() => throw UnsupportedError("Unsupported in MessageReader"); @override int read(Uint8List buffer, int offset, int length) { if (offset + length > buffer.length) { throw ArgumentError("The range exceeds the buffer length"); } if (_readIterator == null || length <= 0) { return 0; } int i = 0; while (i < length && _readIterator!.moveNext()) { buffer[offset + i] = _readIterator!.current; i++; } return i; } @override void write(Uint8List buffer, int offset, int length) => throw UnsupportedError("Unsupported in MessageReader"); @override Future flush() => throw UnsupportedError("Unsupported in MessageReader"); } thrift-0.23.0/lib/dart/lib/src/transport/t_buffered_transport.dart0000664000175000017500000000500315167543515025556 0ustar00buildbuild00000000000000/// 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. part of thrift; /// Buffered implementation of [TTransport]. class TBufferedTransport extends TTransport { final List _writeBuffer = []; Iterator? _readIterator; Uint8List consumeWriteBuffer() { Uint8List buffer = Uint8List.fromList(_writeBuffer); _writeBuffer.clear(); return buffer; } void _setReadBuffer(Uint8List readBuffer) { _readIterator = readBuffer.iterator; } void _reset({bool isOpen = false}) { _isOpen = isOpen; _writeBuffer.clear(); _readIterator = null; } bool get hasReadData => _readIterator != null; bool _isOpen = false; @override bool get isOpen => _isOpen; @override Future open() async { _reset(isOpen: true); } @override Future close() async { _reset(isOpen: false); } @override int read(Uint8List buffer, int offset, int length) { if (offset + length > buffer.length) { throw ArgumentError("The range exceeds the buffer length"); } if (_readIterator == null || length <= 0) { return 0; } int i = 0; bool hasData = true; while (i < length && hasData) { hasData = _readIterator!.moveNext(); if (hasData) { buffer[offset + i] = _readIterator!.current; i++; } } // cleanup iterator when we've reached the end if (!hasData) { _readIterator = null; } return i; } @override void write(Uint8List buffer, int offset, int length) { if (offset + length > buffer.length) { throw ArgumentError("The range exceeds the buffer length"); } _writeBuffer.addAll(buffer.sublist(offset, offset + length)); } @override Future flush() { _readIterator = consumeWriteBuffer().iterator; return Future.value(); } } thrift-0.23.0/lib/dart/lib/src/transport/t_framed_transport.dart0000664000175000017500000001051415167543515025235 0ustar00buildbuild00000000000000/// 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. part of thrift; /// Framed [TTransport]. /// /// Adapted from the Java Framed transport. class TFramedTransport extends TBufferedTransport { static const int headerByteCount = 4; final TTransport _transport; final Uint8List _headerBytes = Uint8List(headerByteCount); int _receivedHeaderBytes = 0; int _bodySize = 0; Uint8List? _body; int _receivedBodyBytes = 0; Completer? _frameCompleter; TFramedTransport(TTransport transport) : _transport = transport; @override bool get isOpen => _transport.isOpen; @override Future open() { _reset(isOpen: true); return _transport.open(); } @override Future close() { _reset(isOpen: false); return _transport.close(); } @override int read(Uint8List buffer, int offset, int length) { if (hasReadData) { int got = super.read(buffer, offset, length); if (got > 0) return got; } // IMPORTANT: by the time you've got here, // an entire frame is available for reading return super.read(buffer, offset, length); } void _readFrame() { if (_body == null) { bool gotFullHeader = _readFrameHeader(); if (!gotFullHeader) { return; } } _readFrameBody(); } bool _readFrameHeader() { var remainingHeaderBytes = headerByteCount - _receivedHeaderBytes; int got = _transport.read( _headerBytes, _receivedHeaderBytes, remainingHeaderBytes); if (got < 0) { throw TTransportError(TTransportErrorType.UNKNOWN, "Socket closed during frame header read"); } _receivedHeaderBytes += got; if (_receivedHeaderBytes == headerByteCount) { int size = _headerBytes.buffer.asByteData().getUint32(0); _receivedHeaderBytes = 0; if (size < 0) { throw TTransportError( TTransportErrorType.UNKNOWN, "Read a negative frame size: $size"); } _bodySize = size; _body = Uint8List(_bodySize); _receivedBodyBytes = 0; return true; } else { _registerForReadableBytes(); return false; } } void _readFrameBody() { var remainingBodyBytes = _bodySize - _receivedBodyBytes; int got = _transport.read(_body!, _receivedBodyBytes, remainingBodyBytes); if (got < 0) { throw TTransportError( TTransportErrorType.UNKNOWN, "Socket closed during frame body read"); } _receivedBodyBytes += got; if (_receivedBodyBytes == _bodySize) { var body = _body!; _bodySize = 0; _body = null; _receivedBodyBytes = 0; _setReadBuffer(body); var completer = _frameCompleter; _frameCompleter = null; if (completer != null) { completer.complete(Uint8List(0)); } } else { _registerForReadableBytes(); } } @override Future flush() { if (_frameCompleter == null) { Uint8List buffer = consumeWriteBuffer(); int length = buffer.length; _headerBytes.buffer.asByteData().setUint32(0, length); _transport.write(_headerBytes, 0, headerByteCount); _transport.write(buffer, 0, length); _frameCompleter = Completer(); _registerForReadableBytes(); } return _frameCompleter!.future; } void _registerForReadableBytes() { _transport.flush().then((_) { _readFrame(); }).catchError((e) { var completer = _frameCompleter; _receivedHeaderBytes = 0; _bodySize = 0; _body = null; _receivedBodyBytes = 0; _frameCompleter = null; if (completer != null) { completer.completeError(e); } }); } } thrift-0.23.0/lib/dart/lib/src/transport/t_transport.dart0000664000175000017500000000501115165535636023716 0ustar00buildbuild00000000000000/// 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. part of thrift; abstract class TTransport { /// Queries whether the transport is open. /// Returns [true] if the transport is open. bool get isOpen; /// Opens the transport for reading/writing. /// Throws [TTransportError] if the transport could not be opened. Future open(); /// Closes the transport. Future close(); /// Reads up to [length] bytes into [buffer], starting at [offset]. /// Returns the number of bytes actually read. /// Throws [TTransportError] if there was an error reading data int read(Uint8List buffer, int offset, int length); /// Guarantees that all of [length] bytes are actually read off the transport. /// Returns the number of bytes actually read, which must be equal to /// [length]. /// Throws [TTransportError] if there was an error reading data int readAll(Uint8List buffer, int offset, int length) { int got = 0; int ret = 0; while (got < length) { ret = read(buffer, offset + got, length - got); if (ret <= 0) { throw TTransportError( TTransportErrorType.UNKNOWN, "Cannot read. Remote side has closed. Tried to read $length " "bytes, but only got $got bytes."); } got += ret; } return got; } /// Writes up to [len] bytes from the buffer. /// Throws [TTransportError] if there was an error writing data void write(Uint8List buffer, int offset, int length); /// Writes the [bytes] to the output. /// Throws [TTransportError] if there was an error writing data void writeAll(Uint8List buffer) { write(buffer, 0, buffer.length); } /// Flush any pending data out of a transport buffer. /// Throws [TTransportError] if there was an error writing out data. Future flush(); } thrift-0.23.0/lib/dart/lib/src/transport/t_socket.dart0000664000175000017500000000212015165535636023150 0ustar00buildbuild00000000000000/// 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. part of thrift; enum TSocketState { CLOSED, OPEN } abstract class TSocket { Stream get onState; Stream get onError; Stream get onMessage; bool get isOpen; bool get isClosed; Future open(); Future close(); void send(Uint8List data); } thrift-0.23.0/lib/dart/lib/src/transport/t_socket_transport.dart0000664000175000017500000001270615167543515025274 0ustar00buildbuild00000000000000/// 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. part of thrift; /// Socket implementation of [TTransport]. /// /// For example: /// /// var transport = new TClientSocketTransport(new TWebSocket(url)); /// var protocol = new TBinaryProtocol(transport); /// var client = new MyThriftServiceClient(protocol); /// var result = client.myMethod(); /// /// Adapted from the JS WebSocket transport. abstract class TSocketTransport extends TBufferedTransport { final Logger logger = Logger('thrift.TSocketTransport'); final TSocket socket; /// A transport using the provided [socket]. TSocketTransport(this.socket) { socket.onError.listen((e) => logger.warning(e)); socket.onMessage.listen(handleIncomingMessage); } @override bool get isOpen => socket.isOpen; @override Future open() { _reset(isOpen: true); return socket.open(); } @override Future close() { _reset(isOpen: false); return socket.close(); } /// Make an incoming message available to read from the transport. void handleIncomingMessage(Uint8List messageBytes) { _setReadBuffer(messageBytes); } } /// [TClientSocketTransport] is a basic client socket transport. It sends /// outgoing messages and expects a response. /// /// NOTE: This transport expects a single threaded server, as it will process /// responses in FIFO order. class TClientSocketTransport extends TSocketTransport { final List> _completers = []; TClientSocketTransport(TSocket socket) : super(socket); @override Future flush() { Uint8List bytes = consumeWriteBuffer(); // Use a sync completer to ensure that the buffer can be read immediately // after the read buffer is set, and avoid a race condition where another // response could overwrite the read buffer. var completer = Completer.sync(); _completers.add(completer); if (bytes.lengthInBytes > 0) { socket.send(bytes); } return completer.future; } @override void handleIncomingMessage(Uint8List messageBytes) { super.handleIncomingMessage(messageBytes); if (_completers.isNotEmpty) { var completer = _completers.removeAt(0); completer.complete(Uint8List(0)); } } } /// [TAsyncClientSocketTransport] sends outgoing messages and expects an /// asynchronous response. /// /// NOTE: This transport uses a [MessageReader] to read a [TMessage] when an /// incoming message arrives to correlate a response to a request, using the /// seqid. class TAsyncClientSocketTransport extends TSocketTransport { static const defaultTimeout = Duration(seconds: 30); final Map> _completers = {}; final TMessageReader messageReader; final Duration responseTimeout; TAsyncClientSocketTransport(TSocket socket, TMessageReader messageReader, {Duration responseTimeout = defaultTimeout}) : this.messageReader = messageReader, this.responseTimeout = responseTimeout, super(socket); @override Future flush() { Uint8List bytes = consumeWriteBuffer(); TMessage message = messageReader.readMessage(bytes); int seqid = message.seqid; // Use a sync completer to ensure that the buffer can be read immediately // after the read buffer is set, and avoid a race condition where another // response could overwrite the read buffer. var completer = Completer.sync(); _completers[seqid] = completer; Future.delayed(responseTimeout, () { var completer = _completers.remove(seqid); if (completer != null) { completer.completeError( TimeoutException("Response timed out.", responseTimeout)); } }); socket.send(bytes); return completer.future; } @override void handleIncomingMessage(Uint8List messageBytes) { super.handleIncomingMessage(messageBytes); TMessage message = messageReader.readMessage(messageBytes); var completer = _completers.remove(message.seqid); if (completer != null) { completer.complete(Uint8List(0)); } } } /// [TServerSocketTransport] listens for incoming messages. When it sends a /// response, it does not expect an acknowledgement. class TServerSocketTransport extends TSocketTransport { final StreamController _onIncomingMessageController; Stream get onIncomingMessage => _onIncomingMessageController.stream; TServerSocketTransport(TSocket socket) : _onIncomingMessageController = StreamController.broadcast(), super(socket); @override Future flush() async { Uint8List message = consumeWriteBuffer(); socket.send(message); } @override void handleIncomingMessage(Uint8List messageBytes) { super.handleIncomingMessage(messageBytes); _onIncomingMessageController.add(null); } } thrift-0.23.0/lib/dart/lib/src/transport/t_transport_error.dart0000664000175000017500000000224015165535636025130 0ustar00buildbuild00000000000000/// 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. part of thrift; class TTransportErrorType { static const int UNKNOWN = 0; static const int NOT_OPEN = 1; static const int ALREADY_OPEN = 2; static const int TIMED_OUT = 3; static const int END_OF_FILE = 4; } class TTransportError extends TError { TTransportError([int type = TTransportErrorType.UNKNOWN, String message = ""]) : super(type, message); } thrift-0.23.0/lib/dart/lib/src/protocol/0000775000175000017500000000000015167543515020270 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/lib/src/protocol/t_struct.dart0000664000175000017500000000160215165535636023015 0ustar00buildbuild00000000000000/// 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. part of thrift; class TStruct { final String name; TStruct([this.name = ""]); } thrift-0.23.0/lib/dart/lib/src/protocol/t_compact_protocol.dart0000664000175000017500000003001415167543515025034 0ustar00buildbuild00000000000000/// 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. part of thrift; class TCompactProtocolFactory implements TProtocolFactory { TCompactProtocolFactory(); @override TCompactProtocol getProtocol(TTransport transport) { return TCompactProtocol(transport); } } /// Compact protocol implementation for Thrift. /// /// Use of fixnum library is required due to bugs like /// https://github.com/dart-lang/sdk/issues/15361 /// /// Adapted from the Java version. class TCompactProtocol extends TProtocol { static const int PROTOCOL_ID = 0x82; static const int VERSION = 1; static const int VERSION_MASK = 0x1f; static const int TYPE_MASK = 0xE0; static const int TYPE_BITS = 0x07; static const int TYPE_SHIFT_AMOUNT = 5; static final TField TSTOP = TField("", TType.STOP, 0); static const int TYPE_BOOLEAN_TRUE = 0x01; static const int TYPE_BOOLEAN_FALSE = 0x02; static const int TYPE_BYTE = 0x03; static const int TYPE_I16 = 0x04; static const int TYPE_I32 = 0x05; static const int TYPE_I64 = 0x06; static const int TYPE_DOUBLE = 0x07; static const int TYPE_BINARY = 0x08; static const int TYPE_LIST = 0x09; static const int TYPE_SET = 0x0A; static const int TYPE_MAP = 0x0B; static const int TYPE_STRUCT = 0x0C; static final List _typeMap = List.unmodifiable( List.filled(16, 0) ..[TType.STOP] = TType.STOP ..[TType.BOOL] = TYPE_BOOLEAN_TRUE ..[TType.BYTE] = TYPE_BYTE ..[TType.I16] = TYPE_I16 ..[TType.I32] = TYPE_I32 ..[TType.I64] = TYPE_I64 ..[TType.DOUBLE] = TYPE_DOUBLE ..[TType.STRING] = TYPE_BINARY ..[TType.LIST] = TYPE_LIST ..[TType.SET] = TYPE_SET ..[TType.MAP] = TYPE_MAP ..[TType.STRUCT] = TYPE_STRUCT, ); static const Utf8Codec _utf8Codec = Utf8Codec(); // Pretend this is a stack DoubleLinkedQueue _lastField = DoubleLinkedQueue(); int _lastFieldId = 0; TField? _booleanField; bool? _boolValue; final Uint8List tempList = Uint8List(10); final ByteData tempBD = ByteData(10); TCompactProtocol(TTransport transport) : super(transport); /// Write @override void writeMessageBegin(TMessage message) { writeByte(PROTOCOL_ID); writeByte((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); _writeVarInt32(Int32(message.seqid)); writeString(message.name); } @override void writeMessageEnd() {} @override void writeStructBegin(TStruct struct) { _lastField.addLast(_lastFieldId); _lastFieldId = 0; } @override void writeStructEnd() { _lastFieldId = _lastField.removeLast(); } @override void writeFieldBegin(TField field) { if (field.type == TType.BOOL) { _booleanField = field; } else { _writeFieldBegin(field, -1); } } void _writeFieldBegin(TField field, int typeOverride) { int typeToWrite = typeOverride == -1 ? _getCompactType(field.type) : typeOverride; if (field.id > _lastFieldId && field.id - _lastFieldId <= 15) { writeByte((field.id - _lastFieldId) << 4 | typeToWrite); } else { writeByte(typeToWrite); writeI16(field.id); } _lastFieldId = field.id; } @override void writeFieldEnd() {} @override void writeFieldStop() { writeByte(TType.STOP); } @override void writeMapBegin(TMap map) { if (map.length == 0) { writeByte(0); } else { _writeVarInt32(Int32(map.length)); writeByte( _getCompactType(map.keyType) << 4 | _getCompactType(map.valueType)); } } @override void writeMapEnd() {} @override void writeListBegin(TList list) { _writeCollectionBegin(list.elementType, list.length); } @override void writeListEnd() {} @override void writeSetBegin(TSet set) { _writeCollectionBegin(set.elementType, set.length); } @override void writeSetEnd() {} @override void writeBool(bool b) { if (_booleanField != null) { _writeFieldBegin( _booleanField!, b ? TYPE_BOOLEAN_TRUE : TYPE_BOOLEAN_FALSE); _booleanField = null; } else { writeByte(b ? TYPE_BOOLEAN_TRUE : TYPE_BOOLEAN_FALSE); } } @override void writeByte(int b) { tempList[0] = b; transport.write(tempList, 0, 1); } @override void writeI16(int i16) { _writeVarInt32(_int32ToZigZag(Int32(i16))); } @override void writeI32(int i32) { _writeVarInt32(_int32ToZigZag(Int32(i32))); } @override void writeI64(int i64) { _writeVarInt64(_int64ToZigZag(Int64(i64))); } @override void writeDouble(double d) { tempBD.setFloat64(0, d, Endian.little); transport.write(tempBD.buffer.asUint8List(), 0, 8); } @override void writeString(String str) { Uint8List bytes = _utf8Codec.encode(str); writeBinary(bytes); } @override void writeBinary(Uint8List bytes) { _writeVarInt32(Int32(bytes.length)); transport.write(bytes, 0, bytes.length); } void _writeVarInt32(Int32 n) { int idx = 0; while (true) { if ((n & ~0x7F) == 0) { tempList[idx++] = (n & 0xFF).toInt(); break; } else { tempList[idx++] = (((n & 0x7F) | 0x80) & 0xFF).toInt(); n = n.shiftRightUnsigned(7); } } transport.write(tempList, 0, idx); } void _writeVarInt64(Int64 n) { int idx = 0; while (true) { if ((n & ~0x7F) == 0) { tempList[idx++] = (n & 0xFF).toInt(); break; } else { tempList[idx++] = (((n & 0x7F) | 0x80) & 0xFF).toInt(); n = n.shiftRightUnsigned(7); } } transport.write(tempList, 0, idx); } void _writeCollectionBegin(int elemType, int length) { if (length <= 14) { writeByte(length << 4 | _getCompactType(elemType)); } else { writeByte(0xF0 | _getCompactType(elemType)); _writeVarInt32(Int32(length)); } } Int32 _int32ToZigZag(Int32 n) { return (n << 1) ^ (n >> 31); } Int64 _int64ToZigZag(Int64 n) { return (n << 1) ^ (n >> 63); } // Read @override TMessage readMessageBegin() { int protocolId = readByte(); if (protocolId != PROTOCOL_ID) { throw TProtocolError(TProtocolErrorType.BAD_VERSION, 'Expected protocol id $PROTOCOL_ID but got $protocolId'); } int versionAndType = readByte(); int version = versionAndType & VERSION_MASK; if (version != VERSION) { throw TProtocolError(TProtocolErrorType.BAD_VERSION, 'Expected version $VERSION but got $version'); } int type = (versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS; int seqId = _readVarInt32().toInt(); String messageName = readString(); return TMessage(messageName, type, seqId); } @override void readMessageEnd() {} @override TStruct readStructBegin() { _lastField.addLast(_lastFieldId); _lastFieldId = 0; // TODO make this a constant? return TStruct(); } @override void readStructEnd() { _lastFieldId = _lastField.removeLast(); } @override TField readFieldBegin() { int type = readByte(); if (type == TType.STOP) { return TSTOP; } int fieldId; int modifier = (type & 0xF0) >> 4; if (modifier == 0) { fieldId = readI16(); } else { fieldId = _lastFieldId + modifier; } TField field = TField('', _getTType(type & 0x0F), fieldId); if (_isBoolType(type)) { _boolValue = (type & 0x0F) == TYPE_BOOLEAN_TRUE; } _lastFieldId = field.id; return field; } @override void readFieldEnd() {} @override TMap readMapBegin() { int length = _readVarInt32().toInt(); _checkNegReadLength(length); int keyAndValueType = length == 0 ? 0 : readByte(); int keyType = _getTType(keyAndValueType >> 4); int valueType = _getTType(keyAndValueType & 0x0F); return TMap(keyType, valueType, length); } @override void readMapEnd() {} @override TList readListBegin() { int lengthAndType = readByte(); int length = (lengthAndType >> 4) & 0x0F; if (length == 15) { length = _readVarInt32().toInt(); } _checkNegReadLength(length); int type = _getTType(lengthAndType); return TList(type, length); } @override void readListEnd() {} @override TSet readSetBegin() { TList tlist = readListBegin(); return TSet(tlist.elementType, tlist.length); } @override void readSetEnd() {} @override bool readBool() { if (_boolValue != null) { bool result = _boolValue!; _boolValue = null; return result; } return readByte() == TYPE_BOOLEAN_TRUE; } @override int readByte() { transport.readAll(tempList, 0, 1); return tempList.buffer.asByteData().getUint8(0); } @override int readI16() { return _zigzagToInt32(_readVarInt32()).toInt(); } @override int readI32() { return _zigzagToInt32(_readVarInt32()).toInt(); } @override int readI64() { return _zigzagToInt64(_readVarInt64()).toInt(); } @override double readDouble() { transport.readAll(tempList, 0, 8); return tempList.buffer.asByteData().getFloat64(0, Endian.little); } @override String readString() { int length = _readVarInt32().toInt(); _checkNegReadLength(length); // TODO look at using temp for small strings? Uint8List buff = Uint8List(length); transport.readAll(buff, 0, length); return _utf8Codec.decode(buff); } @override Uint8List readBinary() { int length = _readVarInt32().toInt(); _checkNegReadLength(length); Uint8List buff = Uint8List(length); transport.readAll(buff, 0, length); return buff; } Int32 _readVarInt32() { Int32 result = Int32.ZERO; int shift = 0; while (true) { Int32 b = Int32(readByte()); result |= (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; } return result; } Int64 _readVarInt64() { Int64 result = Int64.ZERO; int shift = 0; while (true) { Int64 b = Int64(readByte()); result |= (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; } return result; } Int32 _zigzagToInt32(Int32 n) { return (n.shiftRightUnsigned(1)) ^ -(n & 1); } Int64 _zigzagToInt64(Int64 n) { return (n.shiftRightUnsigned(1)) ^ -(n & 1); } void _checkNegReadLength(int length) { if (length < 0) { throw TProtocolError( TProtocolErrorType.NEGATIVE_SIZE, 'Negative length: $length'); } } int _getCompactType(int ttype) { return _typeMap[ttype]; } int _getTType(int type) { switch (type & 0x0F) { case TType.STOP: return TType.STOP; case TYPE_BOOLEAN_FALSE: case TYPE_BOOLEAN_TRUE: return TType.BOOL; case TYPE_BYTE: return TType.BYTE; case TYPE_I16: return TType.I16; case TYPE_I32: return TType.I32; case TYPE_I64: return TType.I64; case TYPE_DOUBLE: return TType.DOUBLE; case TYPE_BINARY: return TType.STRING; case TYPE_LIST: return TType.LIST; case TYPE_SET: return TType.SET; case TYPE_MAP: return TType.MAP; case TYPE_STRUCT: return TType.STRUCT; default: throw TProtocolError( TProtocolErrorType.INVALID_DATA, "Unknown type: ${type & 0x0F}"); } } bool _isBoolType(int b) { int lowerNibble = b & 0x0F; return lowerNibble == TYPE_BOOLEAN_TRUE || lowerNibble == TYPE_BOOLEAN_FALSE; } } thrift-0.23.0/lib/dart/lib/src/protocol/t_set.dart0000664000175000017500000000164115165535636022267 0ustar00buildbuild00000000000000/// 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. part of thrift; class TSet { final int elementType; final int length; TSet(this.elementType, this.length); } thrift-0.23.0/lib/dart/lib/src/protocol/t_list.dart0000664000175000017500000000164315165535636022451 0ustar00buildbuild00000000000000/// 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. part of thrift; class TList { final int elementType; final int length; TList(this.elementType, this.length); } thrift-0.23.0/lib/dart/lib/src/protocol/t_protocol_util.dart0000664000175000017500000000562015165535636024373 0ustar00buildbuild00000000000000/// 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. part of thrift; class TProtocolUtil { // equal to JavaScript Number.MAX_SAFE_INTEGER, 2^53 - 1 static const int defaultRecursionLimit = 9007199254740991; static int maxRecursionLimit = defaultRecursionLimit; static skip(TProtocol prot, int type) { _skip(prot, type, maxRecursionLimit); } static _skip(TProtocol prot, int type, int recursionLimit) { if (recursionLimit <= 0) { throw TProtocolError( TProtocolErrorType.DEPTH_LIMIT, "Depth limit exceeded"); } switch (type) { case TType.BOOL: prot.readBool(); break; case TType.BYTE: prot.readByte(); break; case TType.I16: prot.readI16(); break; case TType.I32: prot.readI32(); break; case TType.I64: prot.readI64(); break; case TType.DOUBLE: prot.readDouble(); break; case TType.STRING: prot.readBinary(); break; case TType.STRUCT: prot.readStructBegin(); while (true) { TField field = prot.readFieldBegin(); if (field.type == TType.STOP) { break; } _skip(prot, field.type, recursionLimit - 1); prot.readFieldEnd(); } prot.readStructEnd(); break; case TType.MAP: TMap map = prot.readMapBegin(); for (int i = 0; i < map.length; i++) { _skip(prot, map.keyType, recursionLimit - 1); _skip(prot, map.valueType, recursionLimit - 1); } prot.readMapEnd(); break; case TType.SET: TSet set = prot.readSetBegin(); for (int i = 0; i < set.length; i++) { _skip(prot, set.elementType, recursionLimit - 1); } prot.readSetEnd(); break; case TType.LIST: TList list = prot.readListBegin(); for (int i = 0; i < list.length; i++) { _skip(prot, list.elementType, recursionLimit - 1); } prot.readListEnd(); break; default: throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Invalid data"); } } } thrift-0.23.0/lib/dart/lib/src/protocol/t_type.dart0000664000175000017500000000231515165535636022454 0ustar00buildbuild00000000000000/// 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. part of thrift; class TType { static const int STOP = 0; static const int VOID = 1; static const int BOOL = 2; static const int BYTE = 3; static const int DOUBLE = 4; static const int I16 = 6; static const int I32 = 8; static const int I64 = 10; static const int STRING = 11; static const int STRUCT = 12; static const int MAP = 13; static const int SET = 14; static const int LIST = 15; } thrift-0.23.0/lib/dart/lib/src/protocol/t_protocol_decorator.dart0000664000175000017500000000774515165535636025412 0ustar00buildbuild00000000000000/// 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. part of thrift; /// Forward all operations to the wrapped protocol. Used as a base class. /// /// Adapted from the C# version. class TProtocolDecorator extends TProtocol { final TProtocol _protocol; TProtocolDecorator(TProtocol protocol) : _protocol = protocol, super(protocol.transport); /// Write @override void writeMessageBegin(TMessage message) { _protocol.writeMessageBegin(message); } @override void writeMessageEnd() { _protocol.writeMessageEnd(); } @override void writeStructBegin(TStruct struct) { _protocol.writeStructBegin(struct); } @override void writeStructEnd() { _protocol.writeStructEnd(); } @override void writeFieldBegin(TField field) { _protocol.writeFieldBegin(field); } @override void writeFieldEnd() { _protocol.writeFieldEnd(); } @override void writeFieldStop() { _protocol.writeFieldStop(); } @override void writeMapBegin(TMap map) { _protocol.writeMapBegin(map); } @override void writeMapEnd() { _protocol.writeMapEnd(); } @override void writeListBegin(TList list) { _protocol.writeListBegin(list); } @override void writeListEnd() { _protocol.writeListEnd(); } @override void writeSetBegin(TSet set) { _protocol.writeSetBegin(set); } @override void writeSetEnd() { _protocol.writeSetEnd(); } @override void writeBool(bool b) { _protocol.writeBool(b); } @override void writeByte(int b) { _protocol.writeByte(b); } @override void writeI16(int i16) { _protocol.writeI16(i16); } @override void writeI32(int i32) { _protocol.writeI32(i32); } @override void writeI64(int i64) { _protocol.writeI64(i64); } @override void writeDouble(double d) { _protocol.writeDouble(d); } @override void writeString(String str) { _protocol.writeString(str); } @override void writeBinary(Uint8List bytes) { _protocol.writeBinary(bytes); } /// Read @override TMessage readMessageBegin() => _protocol.readMessageBegin(); @override void readMessageEnd() => _protocol.readMessageEnd(); @override TStruct readStructBegin() => _protocol.readStructBegin(); @override void readStructEnd() => _protocol.readStructEnd(); @override TField readFieldBegin() => _protocol.readFieldBegin(); @override void readFieldEnd() => _protocol.readFieldEnd(); @override TMap readMapBegin() => _protocol.readMapBegin(); @override void readMapEnd() => _protocol.readMapEnd(); @override TList readListBegin() => _protocol.readListBegin(); @override void readListEnd() => _protocol.readListEnd(); @override TSet readSetBegin() => _protocol.readSetBegin(); @override void readSetEnd() => _protocol.readSetEnd(); @override bool readBool() => _protocol.readBool(); @override int readByte() => _protocol.readByte(); @override int readI16() => _protocol.readI16(); @override int readI32() => _protocol.readI32(); @override int readI64() => _protocol.readI64(); @override double readDouble() => _protocol.readDouble(); @override String readString() => _protocol.readString(); @override Uint8List readBinary() => _protocol.readBinary(); } thrift-0.23.0/lib/dart/lib/src/protocol/t_protocol_error.dart0000664000175000017500000000235615165535636024552 0ustar00buildbuild00000000000000/// 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. part of thrift; class TProtocolErrorType { static const int UNKNOWN = 0; static const int INVALID_DATA = 1; static const int NEGATIVE_SIZE = 2; static const int SIZE_LIMIT = 3; static const int BAD_VERSION = 4; static const int NOT_IMPLEMENTED = 5; static const int DEPTH_LIMIT = 6; } class TProtocolError extends TError { TProtocolError([int type = TProtocolErrorType.UNKNOWN, String message = ""]) : super(type, message); } thrift-0.23.0/lib/dart/lib/src/protocol/t_field.dart0000664000175000017500000000165715165535636022566 0ustar00buildbuild00000000000000/// 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. part of thrift; class TField { final String name; final int type; final int id; TField(this.name, this.type, this.id); } thrift-0.23.0/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart0000664000175000017500000000262415167543515025750 0ustar00buildbuild00000000000000/// 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. part of thrift; /// Adapted from the C# version. class TMultiplexedProtocol extends TProtocolDecorator { static const SEPARATOR = ':'; final String _serviceName; TMultiplexedProtocol(TProtocol protocol, String serviceName) : _serviceName = serviceName, super(protocol); @override void writeMessageBegin(TMessage message) { if (message.type == TMessageType.CALL || message.type == TMessageType.ONEWAY) { String name = _serviceName + SEPARATOR + message.name; message = TMessage(name, message.type, message.seqid); } super.writeMessageBegin(message); } } thrift-0.23.0/lib/dart/lib/src/protocol/t_message.dart0000664000175000017500000000224715165535636023123 0ustar00buildbuild00000000000000/// 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. part of thrift; class TMessageType { static const int CALL = 1; static const int REPLY = 2; static const int EXCEPTION = 3; static const int ONEWAY = 4; } class TMessage { final String name; final int type; final int seqid; TMessage(this.name, this.type, this.seqid); @override String toString() => ""; } thrift-0.23.0/lib/dart/lib/src/protocol/t_binary_protocol.dart0000664000175000017500000001577715167543515024715 0ustar00buildbuild00000000000000/// 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. part of thrift; class TBinaryProtocolFactory implements TProtocolFactory { TBinaryProtocolFactory({this.strictRead = false, this.strictWrite = true}); final bool strictRead; final bool strictWrite; @override TBinaryProtocol getProtocol(TTransport transport) { return TBinaryProtocol(transport, strictRead: strictRead, strictWrite: strictWrite); } } /// Binary protocol implementation for Thrift. /// /// Adapted from the C# version. class TBinaryProtocol extends TProtocol { static const int VERSION_MASK = 0xffff0000; static const int VERSION_1 = 0x80010000; static const Utf8Codec _utf8Codec = Utf8Codec(); final bool strictRead; final bool strictWrite; TBinaryProtocol(TTransport transport, {this.strictRead = false, this.strictWrite = true}) : super(transport); /// write @override void writeMessageBegin(TMessage message) { if (strictWrite) { int version = VERSION_1 | message.type; writeI32(version); writeString(message.name); writeI32(message.seqid); } else { writeString(message.name); writeByte(message.type); writeI32(message.seqid); } } @override void writeMessageEnd() {} @override void writeStructBegin(TStruct struct) {} @override void writeStructEnd() {} @override void writeFieldBegin(TField field) { writeByte(field.type); writeI16(field.id); } @override void writeFieldEnd() {} @override void writeFieldStop() { writeByte(TType.STOP); } @override void writeMapBegin(TMap map) { writeByte(map.keyType); writeByte(map.valueType); writeI32(map.length); } @override void writeMapEnd() {} @override void writeListBegin(TList list) { writeByte(list.elementType); writeI32(list.length); } @override void writeListEnd() {} @override void writeSetBegin(TSet set) { writeByte(set.elementType); writeI32(set.length); } @override void writeSetEnd() {} @override void writeBool(bool b) { writeByte(b ? 1 : 0); } final ByteData _byteOut = ByteData(1); @override void writeByte(int byte) { _byteOut.setUint8(0, byte); transport.write(_byteOut.buffer.asUint8List(), 0, 1); } final ByteData _i16Out = ByteData(2); @override void writeI16(int i16) { _i16Out.setInt16(0, i16); transport.write(_i16Out.buffer.asUint8List(), 0, 2); } final ByteData _i32Out = ByteData(4); @override void writeI32(int i32) { _i32Out.setInt32(0, i32); transport.write(_i32Out.buffer.asUint8List(), 0, 4); } final Uint8List _i64Out = Uint8List(8); @override void writeI64(int i64) { var i = Int64(i64); var bts = i.toBytes(); for (var j = 0; j < 8; j++) { _i64Out[j] = bts[8 - j - 1]; } transport.write(_i64Out, 0, 8); } @override void writeString(String s) { var bytes = _utf8Codec.encode(s); writeI32(bytes.length); transport.write(bytes, 0, bytes.length); } final ByteData _doubleOut = ByteData(8); @override void writeDouble(double d) { _doubleOut.setFloat64(0, d); transport.write(_doubleOut.buffer.asUint8List(), 0, 8); } @override void writeBinary(Uint8List bytes) { var length = bytes.length; writeI32(length); transport.write(bytes, 0, length); } /// read @override TMessage readMessageBegin() { String name; int type; int seqid; int size = readI32(); if (size < 0) { int version = size & VERSION_MASK; if (version != VERSION_1) { throw TProtocolError(TProtocolErrorType.BAD_VERSION, "Bad version in readMessageBegin: $version"); } type = size & 0x000000ff; name = readString(); seqid = readI32(); } else { if (strictRead) { throw TProtocolError(TProtocolErrorType.BAD_VERSION, "Missing version in readMessageBegin"); } name = _readString(size); type = readByte(); seqid = readI32(); } return TMessage(name, type, seqid); } @override void readMessageEnd() {} @override TStruct readStructBegin() { return TStruct(); } @override void readStructEnd() {} @override TField readFieldBegin() { String name = ""; int type = readByte(); int id = type != TType.STOP ? readI16() : 0; return TField(name, type, id); } @override void readFieldEnd() {} @override TMap readMapBegin() { int keyType = readByte(); int valueType = readByte(); int length = readI32(); return TMap(keyType, valueType, length); } @override void readMapEnd() {} @override TList readListBegin() { int elementType = readByte(); int length = readI32(); return TList(elementType, length); } @override void readListEnd() {} @override TSet readSetBegin() { int elementType = readByte(); int length = readI32(); return TSet(elementType, length); } @override void readSetEnd() {} @override bool readBool() => readByte() == 1; final Uint8List _byteIn = Uint8List(1); @override int readByte() { transport.readAll(_byteIn, 0, 1); return _byteIn.buffer.asByteData().getUint8(0); } final Uint8List _i16In = Uint8List(2); @override int readI16() { transport.readAll(_i16In, 0, 2); return _i16In.buffer.asByteData().getInt16(0); } final Uint8List _i32In = Uint8List(4); @override int readI32() { transport.readAll(_i32In, 0, 4); return _i32In.buffer.asByteData().getInt32(0); } final Uint8List _i64In = Uint8List(8); @override int readI64() { transport.readAll(_i64In, 0, 8); var i = Int64.fromBytesBigEndian(_i64In); return i.toInt(); } final Uint8List _doubleIn = Uint8List(8); @override double readDouble() { transport.readAll(_doubleIn, 0, 8); return _doubleIn.buffer.asByteData().getFloat64(0); } @override String readString() { int size = readI32(); return _readString(size); } String _readString(int size) { Uint8List stringIn = Uint8List(size); transport.readAll(stringIn, 0, size); return _utf8Codec.decode(stringIn); } @override Uint8List readBinary() { int length = readI32(); Uint8List binaryIn = Uint8List(length); transport.readAll(binaryIn, 0, length); return binaryIn; } } thrift-0.23.0/lib/dart/lib/src/protocol/t_json_protocol.dart0000664000175000017500000005117115167543515024366 0ustar00buildbuild00000000000000/// 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. part of thrift; class TJsonProtocolFactory implements TProtocolFactory { @override TJsonProtocol getProtocol(TTransport transport) { return TJsonProtocol(transport); } } /// JSON protocol implementation for Thrift. /// /// Adapted from the C# version. class TJsonProtocol extends TProtocol { static const int VERSION_1 = 1; static const Utf8Codec utf8Codec = Utf8Codec(); late _BaseContext _context; late _BaseContext _rootContext; late _LookaheadReader _reader; final List<_BaseContext> _contextStack = []; final Uint8List _tempBuffer = Uint8List(4); TJsonProtocol(TTransport transport) : super(transport) { _rootContext = _BaseContext(this); _context = _rootContext; _reader = _LookaheadReader(this); _resetContext(); } void _pushContext(_BaseContext c) { _contextStack.add(c); _context = c; } void _popContext() { _contextStack.removeLast(); _context = _contextStack.isEmpty ? _rootContext : _contextStack.last; } void _resetContext() { _contextStack.clear(); _context = _rootContext; } /// Read a byte that must match [char]; otherwise throw a [TProtocolError]. void _readJsonSyntaxChar(int charByte) { int byte = _reader.read(); if (byte != charByte) { throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Expected character ${String.fromCharCode(charByte)} but found: ${String.fromCharCode(byte)}"); } } int _hexVal(int byte) { if (byte >= _Constants.HEX_0_BYTES[0] && byte <= _Constants.HEX_9_BYTES[0]) { return byte - _Constants.HEX_0_BYTES[0]; } else if (byte >= _Constants.HEX_A_BYTES[0] && byte <= _Constants.HEX_F_BYTES[0]) { byte += 10; return byte - _Constants.HEX_A_BYTES[0]; } else { throw TProtocolError( TProtocolErrorType.INVALID_DATA, "Expected hex character"); } } int _hexChar(int byte) => byte.toRadixString(16).codeUnitAt(0); /// write /// Write the [bytes] as JSON characters, escaping as needed. void _writeJsonString(Uint8List bytes) { _context.write(); transport.writeAll(_Constants.QUOTE_BYTES); int length = bytes.length; for (int i = 0; i < length; i++) { int byte = bytes[i]; if ((byte & 0x00FF) >= 0x30) { if (byte == _Constants.BACKSLASH_BYTES[0]) { transport.writeAll(_Constants.BACKSLASH_BYTES); transport.writeAll(_Constants.BACKSLASH_BYTES); } else { transport.write(bytes, i, 1); } } else { _tempBuffer[0] = _Constants.JSON_CHAR_TABLE[byte]; if (_tempBuffer[0] == 1) { transport.write(bytes, i, 1); } else if (_tempBuffer[0] > 1) { transport.writeAll(_Constants.BACKSLASH_BYTES); transport.write(_tempBuffer, 0, 1); } else { transport.writeAll(_Constants.ESCSEQ_BYTES); _tempBuffer[0] = _hexChar(byte >> 4); _tempBuffer[1] = _hexChar(byte); transport.write(_tempBuffer, 0, 2); } } } transport.writeAll(_Constants.QUOTE_BYTES); } void _writeJsonInteger(int i) { _context.write(); String str = i.toString(); if (_context.escapeNumbers) { transport.writeAll(_Constants.QUOTE_BYTES); } transport.writeAll(utf8Codec.encode(str)); if (_context.escapeNumbers) { transport.writeAll(_Constants.QUOTE_BYTES); } } void _writeJsonDouble(double d) { _context.write(); String str = d.toString(); bool escapeNumbers = d.isNaN || d.isInfinite || _context.escapeNumbers; if (escapeNumbers) { transport.writeAll(_Constants.QUOTE_BYTES); } transport.writeAll(utf8Codec.encode(str)); if (escapeNumbers) { transport.writeAll(_Constants.QUOTE_BYTES); } } void _writeJsonBase64(Uint8List bytes) { _context.write(); transport.writeAll(_Constants.QUOTE_BYTES); String base64text = base64.encode(bytes); transport.writeAll(utf8Codec.encode(base64text)); transport.writeAll(_Constants.QUOTE_BYTES); } void _writeJsonObjectStart() { _context.write(); transport.writeAll(_Constants.LBRACE_BYTES); _pushContext(_PairContext(this)); } void _writeJsonObjectEnd() { _popContext(); transport.writeAll(_Constants.RBRACE_BYTES); } void _writeJsonArrayStart() { _context.write(); transport.writeAll(_Constants.LBRACKET_BYTES); _pushContext(_ListContext(this)); } void _writeJsonArrayEnd() { _popContext(); transport.writeAll(_Constants.RBRACKET_BYTES); } @override void writeMessageBegin(TMessage message) { _resetContext(); _writeJsonArrayStart(); _writeJsonInteger(VERSION_1); _writeJsonString(utf8Codec.encode(message.name)); _writeJsonInteger(message.type); _writeJsonInteger(message.seqid); } @override void writeMessageEnd() { _writeJsonArrayEnd(); } @override void writeStructBegin(TStruct struct) { _writeJsonObjectStart(); } @override void writeStructEnd() { _writeJsonObjectEnd(); } @override void writeFieldBegin(TField field) { _writeJsonInteger(field.id); _writeJsonObjectStart(); _writeJsonString(_Constants.getTypeNameBytesForTypeId(field.type)); } @override void writeFieldEnd() { _writeJsonObjectEnd(); } @override void writeFieldStop() {} @override void writeMapBegin(TMap map) { _writeJsonArrayStart(); _writeJsonString(_Constants.getTypeNameBytesForTypeId(map.keyType)); _writeJsonString(_Constants.getTypeNameBytesForTypeId(map.valueType)); _writeJsonInteger(map.length); _writeJsonObjectStart(); } @override void writeMapEnd() { _writeJsonObjectEnd(); _writeJsonArrayEnd(); } @override void writeListBegin(TList list) { _writeJsonArrayStart(); _writeJsonString(_Constants.getTypeNameBytesForTypeId(list.elementType)); _writeJsonInteger(list.length); } @override void writeListEnd() { _writeJsonArrayEnd(); } @override void writeSetBegin(TSet set) { _writeJsonArrayStart(); _writeJsonString(_Constants.getTypeNameBytesForTypeId(set.elementType)); _writeJsonInteger(set.length); } @override void writeSetEnd() { _writeJsonArrayEnd(); } @override void writeBool(bool b) { _writeJsonInteger(b ? 1 : 0); } @override void writeByte(int b) { _writeJsonInteger(b); } @override void writeI16(int i16) { _writeJsonInteger(i16); } @override void writeI32(int i32) { _writeJsonInteger(i32); } @override void writeI64(int i64) { _writeJsonInteger(i64); } @override void writeDouble(double d) { _writeJsonDouble(d); } @override void writeString(String s) { var bytes = utf8Codec.encode(s); _writeJsonString(bytes); } @override void writeBinary(Uint8List bytes) { _writeJsonBase64(bytes); } bool _isHighSurrogate(int b) => b >= 0xD800 && b <= 0xDBFF; bool _isLowSurrogate(int b) => b >= 0xDC00 && b <= 0xDFFF; /// read Uint8List _readJsonString({bool skipContext = false}) { List bytes = []; List codeunits = []; if (!skipContext) { _context.read(); } _readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]); while (true) { int byte = _reader.read(); if (byte == _Constants.QUOTE_BYTES[0]) { break; } // escaped? if (byte != _Constants.ESCSEQ_BYTES[0]) { bytes.add(byte); continue; } byte = _reader.read(); // distinguish between \uXXXX and control chars like \n if (byte != _Constants.ESCSEQ_BYTES[1]) { String char = String.fromCharCode(byte); int offset = _Constants.ESCAPE_CHARS.indexOf(char); if (offset == -1) { throw TProtocolError( TProtocolErrorType.INVALID_DATA, "Expected control char"); } byte = _Constants.ESCAPE_CHAR_VALS.codeUnitAt(offset); bytes.add(byte); continue; } // it's \uXXXX transport.readAll(_tempBuffer, 0, 4); byte = (_hexVal(_tempBuffer[0]) << 12) + (_hexVal(_tempBuffer[1]) << 8) + (_hexVal(_tempBuffer[2]) << 4) + _hexVal(_tempBuffer[3]); if (_isHighSurrogate(byte)) { if (codeunits.isNotEmpty) { throw TProtocolError( TProtocolErrorType.INVALID_DATA, "Expected low surrogate"); } codeunits.add(byte); } else if (_isLowSurrogate(byte)) { if (codeunits.isEmpty) { throw TProtocolError( TProtocolErrorType.INVALID_DATA, "Expected high surrogate"); } codeunits.add(byte); bytes.addAll(utf8Codec.encode(String.fromCharCodes(codeunits))); codeunits.clear(); } else { bytes.addAll(utf8Codec.encode(String.fromCharCode(byte))); } } if (codeunits.isNotEmpty) { throw TProtocolError( TProtocolErrorType.INVALID_DATA, "Expected low surrogate"); } return Uint8List.fromList(bytes); } String _readJsonNumericChars() { StringBuffer buffer = StringBuffer(); while (true) { if (!_Constants.isJsonNumeric(_reader.peek())) { break; } buffer.write(String.fromCharCode(_reader.read())); } return buffer.toString(); } int _readJsonInteger() { _context.read(); if (_context.escapeNumbers) { _readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]); } String str = _readJsonNumericChars(); if (_context.escapeNumbers) { _readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]); } try { return int.parse(str); } on FormatException catch (_) { throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Bad data encounted in numeric data"); } } double _readJsonDouble() { _context.read(); if (_reader.peek() == _Constants.QUOTE_BYTES[0]) { Uint8List bytes = _readJsonString(skipContext: true); double d; try { d = double.parse(utf8Codec.decode(bytes)); } catch (_) { throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Bad data encounted in numeric data"); } if (!_context.escapeNumbers && !d.isNaN && !d.isInfinite) { throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Numeric data unexpectedly quoted"); } return d; } else { if (_context.escapeNumbers) { // This will throw - we should have had a quote if escapeNumbers == true _readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]); } try { return double.parse(_readJsonNumericChars()); } on FormatException catch (_) { throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Bad data encounted in numeric data"); } } } Uint8List _readJsonBase64() { // convert UTF-8 bytes of a Base 64 encoded string to binary bytes Uint8List base64Bytes = _readJsonString(); String base64text = utf8Codec.decode(base64Bytes); return Uint8List.fromList(base64.decode(base64text)); } void _readJsonObjectStart() { _context.read(); _readJsonSyntaxChar(_Constants.LBRACE_BYTES[0]); _pushContext(_PairContext(this)); } void _readJsonObjectEnd() { _readJsonSyntaxChar(_Constants.RBRACE_BYTES[0]); _popContext(); } void _readJsonArrayStart() { _context.read(); _readJsonSyntaxChar(_Constants.LBRACKET_BYTES[0]); _pushContext(_ListContext(this)); } void _readJsonArrayEnd() { _readJsonSyntaxChar(_Constants.RBRACKET_BYTES[0]); _popContext(); } @override TMessage readMessageBegin() { _resetContext(); _readJsonArrayStart(); if (_readJsonInteger() != VERSION_1) { throw TProtocolError( TProtocolErrorType.BAD_VERSION, "Message contained bad version."); } Uint8List buffer = _readJsonString(); String name = utf8Codec.decode(buffer); int type = _readJsonInteger(); int seqid = _readJsonInteger(); return TMessage(name, type, seqid); } @override void readMessageEnd() { _readJsonArrayEnd(); } @override TStruct readStructBegin() { _readJsonObjectStart(); return TStruct(); } @override void readStructEnd() { _readJsonObjectEnd(); } @override TField readFieldBegin() { String name = ""; int type = TType.STOP; int id = 0; if (_reader.peek() != _Constants.RBRACE_BYTES[0]) { id = _readJsonInteger(); _readJsonObjectStart(); type = _Constants.getTypeIdForTypeName(_readJsonString()); } return TField(name, type, id); } @override void readFieldEnd() { _readJsonObjectEnd(); } @override TMap readMapBegin() { _readJsonArrayStart(); int keyType = _Constants.getTypeIdForTypeName(_readJsonString()); int valueType = _Constants.getTypeIdForTypeName(_readJsonString()); int length = _readJsonInteger(); _readJsonObjectStart(); return TMap(keyType, valueType, length); } @override void readMapEnd() { _readJsonObjectEnd(); _readJsonArrayEnd(); } @override TList readListBegin() { _readJsonArrayStart(); int elementType = _Constants.getTypeIdForTypeName(_readJsonString()); int length = _readJsonInteger(); return TList(elementType, length); } @override void readListEnd() { _readJsonArrayEnd(); } @override TSet readSetBegin() { _readJsonArrayStart(); int elementType = _Constants.getTypeIdForTypeName(_readJsonString()); int length = _readJsonInteger(); return TSet(elementType, length); } @override void readSetEnd() { _readJsonArrayEnd(); } @override bool readBool() { return _readJsonInteger() == 0 ? false : true; } @override int readByte() { return _readJsonInteger(); } @override int readI16() { return _readJsonInteger(); } @override int readI32() { return _readJsonInteger(); } @override int readI64() { return _readJsonInteger(); } @override double readDouble() { return _readJsonDouble(); } @override String readString() { return utf8Codec.decode(_readJsonString()); } @override Uint8List readBinary() { return Uint8List.fromList(_readJsonBase64()); } } class _Constants { static const utf8codec = Utf8Codec(); static final Uint8List HEX_0_BYTES = Uint8List.fromList('0'.codeUnits); static final Uint8List HEX_9_BYTES = Uint8List.fromList('9'.codeUnits); static final Uint8List HEX_A_BYTES = Uint8List.fromList('a'.codeUnits); static final Uint8List HEX_F_BYTES = Uint8List.fromList('f'.codeUnits); static final Uint8List COMMA_BYTES = Uint8List.fromList(','.codeUnits); static final Uint8List COLON_BYTES = Uint8List.fromList(':'.codeUnits); static final Uint8List LBRACE_BYTES = Uint8List.fromList('{'.codeUnits); static final Uint8List RBRACE_BYTES = Uint8List.fromList('}'.codeUnits); static final Uint8List LBRACKET_BYTES = Uint8List.fromList('['.codeUnits); static final Uint8List RBRACKET_BYTES = Uint8List.fromList(']'.codeUnits); static final Uint8List QUOTE_BYTES = Uint8List.fromList('"'.codeUnits); static final Uint8List BACKSLASH_BYTES = Uint8List.fromList(r'\'.codeUnits); static final ESCSEQ_BYTES = Uint8List.fromList(r'\u00'.codeUnits); static final Uint8List JSON_CHAR_TABLE = Uint8List.fromList([ 0, 0, 0, 0, 0, 0, 0, 0, // 8 bytes 'b'.codeUnitAt(0), 't'.codeUnitAt(0), 'n'.codeUnitAt(0), 0, // 4 bytes 'f'.codeUnitAt(0), 'r'.codeUnitAt(0), 0, 0, // 4 bytes 0, 0, 0, 0, 0, 0, 0, 0, // 8 bytes 0, 0, 0, 0, 0, 0, 0, 0, // 8 bytes 1, 1, '"'.codeUnitAt(0), 1, 1, 1, 1, 1, // 8 bytes 1, 1, 1, 1, 1, 1, 1, 1 // 8 bytes ]); static const String ESCAPE_CHARS = r'"\/bfnrt'; static const String ESCAPE_CHAR_VALS = '"\\/\b\f\n\r\t'; static const String NAME_BOOL = 'tf'; static const String NAME_BYTE = 'i8'; static const String NAME_I16 = 'i16'; static const String NAME_I32 = 'i32'; static const String NAME_I64 = 'i64'; static const String NAME_DOUBLE = 'dbl'; static const String NAME_STRUCT = 'rec'; static const String NAME_STRING = 'str'; static const String NAME_MAP = 'map'; static const String NAME_LIST = 'lst'; static const String NAME_SET = 'set'; static final Map _TYPE_ID_TO_NAME_BYTES = Map.unmodifiable({ TType.BOOL: Uint8List.fromList(NAME_BOOL.codeUnits), TType.BYTE: Uint8List.fromList(NAME_BYTE.codeUnits), TType.I16: Uint8List.fromList(NAME_I16.codeUnits), TType.I32: Uint8List.fromList(NAME_I32.codeUnits), TType.I64: Uint8List.fromList(NAME_I64.codeUnits), TType.DOUBLE: Uint8List.fromList(NAME_DOUBLE.codeUnits), TType.STRING: Uint8List.fromList(NAME_STRING.codeUnits), TType.STRUCT: Uint8List.fromList(NAME_STRUCT.codeUnits), TType.MAP: Uint8List.fromList(NAME_MAP.codeUnits), TType.SET: Uint8List.fromList(NAME_SET.codeUnits), TType.LIST: Uint8List.fromList(NAME_LIST.codeUnits) }); static Uint8List getTypeNameBytesForTypeId(int typeId) { if (!_TYPE_ID_TO_NAME_BYTES.containsKey(typeId)) { throw TProtocolError( TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type"); } return _TYPE_ID_TO_NAME_BYTES[typeId]!; } static final Map _NAME_TO_TYPE_ID = Map.unmodifiable({ NAME_BOOL: TType.BOOL, NAME_BYTE: TType.BYTE, NAME_I16: TType.I16, NAME_I32: TType.I32, NAME_I64: TType.I64, NAME_DOUBLE: TType.DOUBLE, NAME_STRING: TType.STRING, NAME_STRUCT: TType.STRUCT, NAME_MAP: TType.MAP, NAME_SET: TType.SET, NAME_LIST: TType.LIST }); static int getTypeIdForTypeName(Uint8List bytes) { String name = utf8codec.decode(bytes); if (!_NAME_TO_TYPE_ID.containsKey(name)) { throw TProtocolError( TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type"); } return _NAME_TO_TYPE_ID[name]!; } static final Set _JSON_NUMERICS = Set.from([ '+'.codeUnitAt(0), '-'.codeUnitAt(0), '.'.codeUnitAt(0), '0'.codeUnitAt(0), '1'.codeUnitAt(0), '2'.codeUnitAt(0), '3'.codeUnitAt(0), '4'.codeUnitAt(0), '5'.codeUnitAt(0), '6'.codeUnitAt(0), '7'.codeUnitAt(0), '8'.codeUnitAt(0), '9'.codeUnitAt(0), 'E'.codeUnitAt(0), 'e'.codeUnitAt(0) ]); static bool isJsonNumeric(int byte) { return _JSON_NUMERICS.contains(byte); } } class _LookaheadReader { final TJsonProtocol protocol; _LookaheadReader(this.protocol); bool _hasData = false; final Uint8List _data = Uint8List(1); int read() { if (_hasData) { _hasData = false; } else { protocol.transport.readAll(_data, 0, 1); } return _data[0]; } int peek() { if (!_hasData) { protocol.transport.readAll(_data, 0, 1); } _hasData = true; return _data[0]; } } class _BaseContext { final TJsonProtocol protocol; _BaseContext(this.protocol); void write() {} void read() {} bool get escapeNumbers => false; @override String toString() => 'BaseContext'; } class _ListContext extends _BaseContext { _ListContext(TJsonProtocol protocol) : super(protocol); bool _first = true; @override void write() { if (_first) { _first = false; } else { protocol.transport.writeAll(_Constants.COMMA_BYTES); } } @override void read() { if (_first) { _first = false; } else { protocol._readJsonSyntaxChar(_Constants.COMMA_BYTES[0]); } } @override String toString() => 'ListContext'; } class _PairContext extends _BaseContext { _PairContext(TJsonProtocol protocol) : super(protocol); bool _first = true; bool _colon = true; Uint8List get symbolBytes => _colon ? _Constants.COLON_BYTES : _Constants.COMMA_BYTES; @override void write() { if (_first) { _first = false; _colon = true; } else { protocol.transport.writeAll(symbolBytes); _colon = !_colon; } } @override void read() { if (_first) { _first = false; _colon = true; } else { protocol._readJsonSyntaxChar(symbolBytes[0]); _colon = !_colon; } } @override bool get escapeNumbers => _colon; @override String toString() => 'PairContext'; } thrift-0.23.0/lib/dart/lib/src/protocol/t_protocol_factory.dart0000664000175000017500000000163515165535636025067 0ustar00buildbuild00000000000000/// 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. part of thrift; abstract class TProtocolFactory { T getProtocol(TTransport transport); } thrift-0.23.0/lib/dart/lib/src/protocol/t_protocol.dart0000664000175000017500000000377015165535636023342 0ustar00buildbuild00000000000000/// 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. part of thrift; abstract class TProtocol { final TTransport transport; TProtocol(this.transport); /// Write void writeMessageBegin(TMessage message); void writeMessageEnd(); void writeStructBegin(TStruct struct); void writeStructEnd(); void writeFieldBegin(TField field); void writeFieldEnd(); void writeFieldStop(); void writeMapBegin(TMap map); void writeMapEnd(); void writeListBegin(TList list); void writeListEnd(); void writeSetBegin(TSet set); void writeSetEnd(); void writeBool(bool b); void writeByte(int b); void writeI16(int i16); void writeI32(int i32); void writeI64(int i64); void writeDouble(double d); void writeString(String str); void writeBinary(Uint8List bytes); /// Read TMessage readMessageBegin(); void readMessageEnd(); TStruct readStructBegin(); void readStructEnd(); TField readFieldBegin(); void readFieldEnd(); TMap readMapBegin(); void readMapEnd(); TList readListBegin(); void readListEnd(); TSet readSetBegin(); void readSetEnd(); bool readBool(); int readByte(); int readI16(); int readI32(); int readI64(); double readDouble(); String readString(); Uint8List readBinary(); } thrift-0.23.0/lib/dart/lib/src/protocol/t_map.dart0000664000175000017500000000170015165535636022245 0ustar00buildbuild00000000000000/// 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. part of thrift; class TMap { final int keyType; final int valueType; final int length; TMap(this.keyType, this.valueType, this.length); } thrift-0.23.0/lib/dart/lib/src/browser/0000775000175000017500000000000015167543515020112 5ustar00buildbuild00000000000000thrift-0.23.0/lib/dart/lib/src/browser/t_web_socket.dart0000664000175000017500000000741615167543515023446 0ustar00buildbuild00000000000000/// 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. library thrift.src.browser; import 'dart:async'; import 'dart:convert' show base64; import 'dart:html' show CloseEvent; import 'dart:html' show Event; import 'dart:html' show MessageEvent; import 'dart:html' show WebSocket; import 'dart:typed_data' show Uint8List; import 'package:thrift/thrift.dart'; /// A [TSocket] backed by a [WebSocket] from dart:html class TWebSocket implements TSocket { final Uri url; final StreamController _onStateController; @override Stream get onState => _onStateController.stream; final StreamController _onErrorController; @override Stream get onError => _onErrorController.stream; final StreamController _onMessageController; @override Stream get onMessage => _onMessageController.stream; final List _requests = []; TWebSocket(this.url) : _onStateController = StreamController.broadcast(), _onErrorController = StreamController.broadcast(), _onMessageController = StreamController.broadcast() { if (!url.hasAuthority || !url.hasPort) { throw ArgumentError('Invalid url'); } } WebSocket? _socket; @override bool get isOpen => _socket != null && _socket!.readyState == WebSocket.OPEN; @override bool get isClosed => _socket == null ||_socket!.readyState == WebSocket.CLOSED; @override Future open() { if (!isClosed) { throw TTransportError( TTransportErrorType.ALREADY_OPEN, 'Socket already connected'); } _socket = WebSocket(url.toString()); _socket!.onError.listen(_onError); _socket!.onOpen.listen(_onOpen); _socket!.onClose.listen(_onClose); _socket!.onMessage.listen(_onMessage); return _socket!.onOpen.first; } @override Future close() { if (_socket != null) { _socket!.close(); return _socket!.onClose.first; } else { return Future.value(); } } @override void send(Uint8List data) { _requests.add(data); _sendRequests(); } void _sendRequests() { while (isOpen && _requests.isNotEmpty) { Uint8List data = _requests.removeAt(0); _socket!.sendString(base64.encode(data)); } } void _onOpen(Event event) { _onStateController.add(TSocketState.OPEN); _sendRequests(); } void _onClose(CloseEvent event) { _socket = null; if (_requests.isNotEmpty) { _onErrorController .add(StateError('Socket was closed with pending requests')); } _requests.clear(); _onStateController.add(TSocketState.CLOSED); } void _onMessage(MessageEvent message) { try { Uint8List data = Uint8List.fromList(base64.decode(message.data)); _onMessageController.add(data); } on FormatException catch (_) { var error = TProtocolError(TProtocolErrorType.INVALID_DATA, "Expected a Base 64 encoded string."); _onErrorController.add(error); } } void _onError(Event event) { close(); _onErrorController.add(event.toString()); } } thrift-0.23.0/lib/dart/lib/src/t_processor.dart0000664000175000017500000000177415165535636021661 0ustar00buildbuild00000000000000/// 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. part of thrift; /// A processor is a generic object which operates upon an input stream and /// writes to some output stream. abstract class TProcessor { bool process(TProtocol input, TProtocol output); } thrift-0.23.0/lib/dart/lib/thrift_console.dart0000664000175000017500000000177215165535636021550 0ustar00buildbuild00000000000000/// 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. library thrift_console; /// Classes that are only supported in console applications go here export 'src/console/t_tcp_socket.dart' show TTcpSocket; export 'src/console/t_web_socket.dart' show TWebSocket; thrift-0.23.0/lib/dart/lib/thrift.dart0000664000175000017500000000443215165535636020022 0ustar00buildbuild00000000000000/// 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. library thrift; import 'dart:async'; import 'dart:collection'; import 'dart:convert' show Utf8Codec, base64; import 'dart:typed_data' show ByteData, Uint8List, Endian; import 'package:fixnum/fixnum.dart'; import 'package:http/http.dart' show Client; import 'package:logging/logging.dart'; part 'src/t_application_error.dart'; part 'src/t_base.dart'; part 'src/t_error.dart'; part 'src/t_processor.dart'; part 'src/protocol/t_binary_protocol.dart'; part 'src/protocol/t_compact_protocol.dart'; part 'src/protocol/t_field.dart'; part 'src/protocol/t_json_protocol.dart'; part 'src/protocol/t_list.dart'; part 'src/protocol/t_map.dart'; part 'src/protocol/t_message.dart'; part 'src/protocol/t_multiplexed_protocol.dart'; part 'src/protocol/t_protocol.dart'; part 'src/protocol/t_protocol_decorator.dart'; part 'src/protocol/t_protocol_error.dart'; part 'src/protocol/t_protocol_factory.dart'; part 'src/protocol/t_protocol_util.dart'; part 'src/protocol/t_set.dart'; part 'src/protocol/t_struct.dart'; part 'src/protocol/t_type.dart'; part 'src/serializer/t_deserializer.dart'; part 'src/serializer/t_serializer.dart'; part 'src/transport/t_buffered_transport.dart'; part 'src/transport/t_framed_transport.dart'; part 'src/transport/t_http_transport.dart'; part 'src/transport/t_message_reader.dart'; part 'src/transport/t_socket.dart'; part 'src/transport/t_transport.dart'; part 'src/transport/t_transport_error.dart'; part 'src/transport/t_transport_factory.dart'; part 'src/transport/t_socket_transport.dart'; thrift-0.23.0/lib/dart/lib/thrift_browser.dart0000664000175000017500000000170215165535636021562 0ustar00buildbuild00000000000000/// 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. library thrift_browser; /// Classes that are only supported in browser applications go here export 'src/browser/t_web_socket.dart' show TWebSocket; thrift-0.23.0/lib/dart/Makefile0000644000175000017500000004456515170007175016535 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/dart/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/dart ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart # Dart build command DARTPUB = dart pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/dart abs_srcdir = /thrift/src/lib/dart abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/dart/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/dart/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ dist-hook distclean distclean-generic distclean-libtool \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile all-local: $(DARTPUB) get clean-local: $(RM) -r .pub find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type d -name "packages" | xargs $(RM) -r 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 find $(distdir) -type f -name ".packages" | xargs $(RM) find $(distdir) -type d -name "packages" | xargs $(RM) -r # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/dart/pubspec.yaml0000664000175000017500000000254415170007142017405 0ustar00buildbuild00000000000000# 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. name: thrift version: 0.23.0 description: > A Dart library for Apache Thrift author: Apache Thrift Developers homepage: http://thrift.apache.org documentation: http://thrift.apache.org environment: sdk: ">=2.12.0 <4.0.0" dependencies: fixnum: ">=0.10.2 <2.0.0" http: "^1.2.0" logging: ">=0.11.0 <2.0.0" dev_dependencies: build_runner: ">=1.7.1 <3.0.0" build_test: ">=0.10.9 <3.0.0" build_vm_compilers: ^1.0.13 build_web_compilers: ^3.2.7 dart_dev: ^4.1.0 dart_style: ^2.3.0 mockito: ">=4.1.1 <6.0.0" test: ^1.9.1 workiva_analysis_options: ^1.0.0thrift-0.23.0/lib/dart/Makefile.in0000644000175000017500000004354115170007167017134 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/dart ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ # Dart build command DARTPUB = dart pub DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/dart/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/dart/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ dist-hook distclean distclean-generic distclean-libtool \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile all-local: $(DARTPUB) get clean-local: $(RM) -r .pub find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type d -name "packages" | xargs $(RM) -r 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 find $(distdir) -type f -name ".packages" | xargs $(RM) find $(distdir) -type d -name "packages" | xargs $(RM) -r # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/dart/Makefile.am0000664000175000017500000000244115167543515017127 0ustar00buildbuild00000000000000# # 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. # # Dart build command DARTPUB = dart pub all-local: $(DARTPUB) get clean-local: $(RM) -r .pub find . -type d -name ".dart_tool" | xargs $(RM) -r find . -type f -name ".packages" | xargs $(RM) find . -type d -name "packages" | xargs $(RM) -r 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 find $(distdir) -type f -name ".packages" | xargs $(RM) find $(distdir) -type d -name "packages" | xargs $(RM) -r thrift-0.23.0/lib/ocaml/0000775000175000017500000000000015170007142015214 5ustar00buildbuild00000000000000thrift-0.23.0/lib/ocaml/TODO0000664000175000017500000000016215165535636015725 0ustar00buildbuild00000000000000Write interfaces Clean up the code generator Avoid capture properly instead of relying on the user not to use _ thrift-0.23.0/lib/ocaml/opam0000664000175000017500000000024315165535636016114 0ustar00buildbuild00000000000000opam-version: "1" maintainer: "XXX(FILL ME IN WITH EMAIL)" build: [ [make] [make "install"] ] remove: [["ocamlfind" "remove" "thrift"]] depends: ["ocamlfind"] thrift-0.23.0/lib/ocaml/_oasis0000664000175000017500000000105415170007142016414 0ustar00buildbuild00000000000000Name: libthrift-ocaml Version: 0.23.0 OASISFormat: 0.3 Synopsis: OCaml bindings for the Apache Thrift RPC system Authors: Apache Thrift Developers License: Apache-2.0 Homepage: http://thrift.apache.org BuildTools: ocamlbuild Plugins: META (0.3), DevFiles (0.3) Library "libthrift-ocaml" Path: src FindlibName: thrift buildTools: ocamlbuild BuildDepends: threads Modules: Thrift,TBinaryProtocol,TSocket,TFramedTransport,TChannelTransport,TServer,TSimpleServer,TServerSocket,TThreadedServer XMETARequires: threads thrift-0.23.0/lib/ocaml/src/0000775000175000017500000000000015165535636016025 5ustar00buildbuild00000000000000thrift-0.23.0/lib/ocaml/src/TBinaryProtocol.ml0000664000175000017500000001170515165535636021455 0ustar00buildbuild00000000000000(* 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. *) open Thrift module P = Protocol let get_byte i b = 255 land (i lsr (8*b)) let get_byte32 i b = 255 land (Int32.to_int (Int32.shift_right i (8*b))) let get_byte64 i b = 255 land (Int64.to_int (Int64.shift_right i (8*b))) let tv = P.t_type_to_i let vt = P.t_type_of_i let comp_int b n = let s = ref 0l in let sb = 32 - 8*n in for i=0 to (n-1) do s:= Int32.logor !s (Int32.shift_left (Int32.of_int (int_of_char b.[i])) (8*(n-1-i))) done; Int32.shift_right (Int32.shift_left !s sb) sb let comp_int64 b n = let s = ref 0L in for i=0 to (n-1) do s:=Int64.logor !s (Int64.shift_left (Int64.of_int (int_of_char b.[i])) (8*(n-1-i))) done; !s let version_mask = 0xffff0000l let version_1 = 0x80010000l class t trans = object (self) inherit P.t trans val ibyte = String.create 8 method writeBool b = ibyte.[0] <- char_of_int (if b then 1 else 0); trans#write ibyte 0 1 method writeByte i = ibyte.[0] <- char_of_int (get_byte i 0); trans#write ibyte 0 1 method writeI16 i = let gb = get_byte i in ibyte.[1] <- char_of_int (gb 0); ibyte.[0] <- char_of_int (gb 1); trans#write ibyte 0 2 method writeI32 i = let gb = get_byte32 i in for i=0 to 3 do ibyte.[3-i] <- char_of_int (gb i) done; trans#write ibyte 0 4 method writeI64 i= let gb = get_byte64 i in for i=0 to 7 do ibyte.[7-i] <- char_of_int (gb i) done; trans#write ibyte 0 8 method writeDouble d = self#writeI64 (Int64.bits_of_float d) method writeString s= let n = String.length s in self#writeI32 (Int32.of_int n); trans#write s 0 n method writeBinary a = self#writeString a method writeMessageBegin (n,t,s) = self#writeI32 (Int32.logor version_1 (Int32.of_int (P.message_type_to_i t))); self#writeString n; self#writeI32 (Int32.of_int s) method writeMessageEnd = () method writeStructBegin s = () method writeStructEnd = () method writeFieldBegin (n,t,i) = self#writeByte (tv t); self#writeI16 i method writeFieldEnd = () method writeFieldStop = self#writeByte (tv (P.T_STOP)) method writeMapBegin (k,v,s) = self#writeByte (tv k); self#writeByte (tv v); self#writeI32 (Int32.of_int s) method writeMapEnd = () method writeListBegin (t,s) = self#writeByte (tv t); self#writeI32 (Int32.of_int s) method writeListEnd = () method writeSetBegin (t,s) = self#writeByte (tv t); self#writeI32 (Int32.of_int s) method writeSetEnd = () method readByte = ignore (trans#readAll ibyte 0 1); Int32.to_int (comp_int ibyte 1) method readI16 = ignore (trans#readAll ibyte 0 2); Int32.to_int (comp_int ibyte 2) method readI32 = ignore (trans#readAll ibyte 0 4); comp_int ibyte 4 method readI64 = ignore (trans#readAll ibyte 0 8); comp_int64 ibyte 8 method readDouble = Int64.float_of_bits (self#readI64) method readBool = self#readByte = 1 method readString = let sz = Int32.to_int (self#readI32) in let buf = String.create sz in ignore (trans#readAll buf 0 sz); buf method readBinary = self#readString method readMessageBegin = let ver = self#readI32 in if Int32.compare (Int32.logand ver version_mask) version_1 != 0 then raise (P.E (P.BAD_VERSION, "Missing version identifier")) else let s = self#readString in let mt = P.message_type_of_i (Int32.to_int (Int32.logand ver 0xFFl)) in (s,mt, Int32.to_int self#readI32) method readMessageEnd = () method readStructBegin = "" method readStructEnd = () method readFieldBegin = let t = (vt (self#readByte)) in if t != P.T_STOP then ("",t,self#readI16) else ("",t,0); method readFieldEnd = () method readMapBegin = let kt = vt (self#readByte) in let vt = vt (self#readByte) in (kt,vt, Int32.to_int self#readI32) method readMapEnd = () method readListBegin = let t = vt (self#readByte) in (t, Int32.to_int self#readI32) method readListEnd = () method readSetBegin = let t = vt (self#readByte) in (t, Int32.to_int self#readI32); method readSetEnd = () end class factory = object inherit P.factory method getProtocol tr = new t tr end thrift-0.23.0/lib/ocaml/src/Thrift.ml0000664000175000017500000002452515165535636017627 0ustar00buildbuild00000000000000(* 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. *) exception Break;; exception Thrift_error;; exception Field_empty of string;; class t_exn = object val mutable message = "" method get_message = message method set_message s = message <- s end;; module Transport = struct type exn_type = | UNKNOWN | NOT_OPEN | ALREADY_OPEN | TIMED_OUT | END_OF_FILE;; exception E of exn_type * string class virtual t = object (self) method virtual isOpen : bool method virtual opn : unit method virtual close : unit method virtual read : string -> int -> int -> int method readAll buf off len = let got = ref 0 in let ret = ref 0 in while !got < len do ret := self#read buf (off+(!got)) (len - (!got)); if !ret <= 0 then raise (E (UNKNOWN, "Cannot read. Remote side has closed.")); got := !got + !ret done; !got method virtual write : string -> int -> int -> unit method virtual flush : unit end class factory = object method getTransport (t : t) = t end class virtual server_t = object (self) method virtual listen : unit method accept = self#acceptImpl method virtual close : unit method virtual acceptImpl : t end end;; module Protocol = struct type t_type = | T_STOP | T_VOID | T_BOOL | T_BYTE | T_I08 | T_I16 | T_I32 | T_U64 | T_I64 | T_DOUBLE | T_STRING | T_UTF7 | T_STRUCT | T_MAP | T_SET | T_LIST | T_UTF8 | T_UTF16 let t_type_to_i = function T_STOP -> 0 | T_VOID -> 1 | T_BOOL -> 2 | T_BYTE -> 3 | T_I08 -> 3 | T_I16 -> 6 | T_I32 -> 8 | T_U64 -> 9 | T_I64 -> 10 | T_DOUBLE -> 4 | T_STRING -> 11 | T_UTF7 -> 11 | T_STRUCT -> 12 | T_MAP -> 13 | T_SET -> 14 | T_LIST -> 15 | T_UTF8 -> 16 | T_UTF16 -> 17 let t_type_of_i = function 0 -> T_STOP | 1 -> T_VOID | 2 -> T_BOOL | 3 -> T_BYTE | 6-> T_I16 | 8 -> T_I32 | 9 -> T_U64 | 10 -> T_I64 | 4 -> T_DOUBLE | 11 -> T_STRING | 12 -> T_STRUCT | 13 -> T_MAP | 14 -> T_SET | 15 -> T_LIST | 16 -> T_UTF8 | 17 -> T_UTF16 | _ -> raise Thrift_error type message_type = | CALL | REPLY | EXCEPTION | ONEWAY let message_type_to_i = function | CALL -> 1 | REPLY -> 2 | EXCEPTION -> 3 | ONEWAY -> 4 let message_type_of_i = function | 1 -> CALL | 2 -> REPLY | 3 -> EXCEPTION | 4 -> ONEWAY | _ -> raise Thrift_error class virtual t (trans: Transport.t) = object (self) val mutable trans_ = trans method getTransport = trans_ (* writing methods *) method virtual writeMessageBegin : string * message_type * int -> unit method virtual writeMessageEnd : unit method virtual writeStructBegin : string -> unit method virtual writeStructEnd : unit method virtual writeFieldBegin : string * t_type * int -> unit method virtual writeFieldEnd : unit method virtual writeFieldStop : unit method virtual writeMapBegin : t_type * t_type * int -> unit method virtual writeMapEnd : unit method virtual writeListBegin : t_type * int -> unit method virtual writeListEnd : unit method virtual writeSetBegin : t_type * int -> unit method virtual writeSetEnd : unit method virtual writeBool : bool -> unit method virtual writeByte : int -> unit method virtual writeI16 : int -> unit method virtual writeI32 : Int32.t -> unit method virtual writeI64 : Int64.t -> unit method virtual writeDouble : float -> unit method virtual writeString : string -> unit method virtual writeBinary : string -> unit (* reading methods *) method virtual readMessageBegin : string * message_type * int method virtual readMessageEnd : unit method virtual readStructBegin : string method virtual readStructEnd : unit method virtual readFieldBegin : string * t_type * int method virtual readFieldEnd : unit method virtual readMapBegin : t_type * t_type * int method virtual readMapEnd : unit method virtual readListBegin : t_type * int method virtual readListEnd : unit method virtual readSetBegin : t_type * int method virtual readSetEnd : unit method virtual readBool : bool method virtual readByte : int method virtual readI16 : int method virtual readI32: Int32.t method virtual readI64 : Int64.t method virtual readDouble : float method virtual readString : string method virtual readBinary : string (* skippage *) method skip typ = match typ with | T_BOOL -> ignore self#readBool | T_BYTE | T_I08 -> ignore self#readByte | T_I16 -> ignore self#readI16 | T_I32 -> ignore self#readI32 | T_U64 | T_I64 -> ignore self#readI64 | T_DOUBLE -> ignore self#readDouble | T_STRING -> ignore self#readString | T_UTF7 -> () | T_STRUCT -> ignore ((ignore self#readStructBegin); (try while true do let (_,t,_) = self#readFieldBegin in if t = T_STOP then raise Break else (self#skip t; self#readFieldEnd) done with Break -> ()); self#readStructEnd) | T_MAP -> ignore (let (k,v,s) = self#readMapBegin in for i=0 to s do self#skip k; self#skip v; done; self#readMapEnd) | T_SET -> ignore (let (t,s) = self#readSetBegin in for i=0 to s do self#skip t done; self#readSetEnd) | T_LIST -> ignore (let (t,s) = self#readListBegin in for i=0 to s do self#skip t done; self#readListEnd) | T_UTF8 -> () | T_UTF16 -> () | _ -> raise (Protocol.E (Protocol.INVALID_DATA, "Invalid data")) end class virtual factory = object method virtual getProtocol : Transport.t -> t end type exn_type = | UNKNOWN | INVALID_DATA | NEGATIVE_SIZE | SIZE_LIMIT | BAD_VERSION | NOT_IMPLEMENTED | DEPTH_LIMIT exception E of exn_type * string;; end;; module Processor = struct class virtual t = object method virtual process : Protocol.t -> Protocol.t -> bool end;; class factory (processor : t) = object val processor_ = processor method getProcessor (trans : Transport.t) = processor_ end;; end (* Ugly *) module Application_Exn = struct type typ= | UNKNOWN | UNKNOWN_METHOD | INVALID_MESSAGE_TYPE | WRONG_METHOD_NAME | BAD_SEQUENCE_ID | MISSING_RESULT | INTERNAL_ERROR | PROTOCOL_ERROR | INVALID_TRANSFORM | INVALID_PROTOCOL | UNSUPPORTED_CLIENT_TYPE let typ_of_i = function 0l -> UNKNOWN | 1l -> UNKNOWN_METHOD | 2l -> INVALID_MESSAGE_TYPE | 3l -> WRONG_METHOD_NAME | 4l -> BAD_SEQUENCE_ID | 5l -> MISSING_RESULT | 6l -> INTERNAL_ERROR | 7l -> PROTOCOL_ERROR | 8l -> INVALID_TRANSFORM | 9l -> INVALID_PROTOCOL | 10l -> UNSUPPORTED_CLIENT_TYPE | _ -> raise Thrift_error;; let typ_to_i = function | UNKNOWN -> 0l | UNKNOWN_METHOD -> 1l | INVALID_MESSAGE_TYPE -> 2l | WRONG_METHOD_NAME -> 3l | BAD_SEQUENCE_ID -> 4l | MISSING_RESULT -> 5l | INTERNAL_ERROR -> 6l | PROTOCOL_ERROR -> 7l | INVALID_TRANSFORM -> 8l | INVALID_PROTOCOL -> 9l | UNSUPPORTED_CLIENT_TYPE -> 10l class t = object (self) inherit t_exn val mutable typ = UNKNOWN method get_type = typ method set_type t = typ <- t method write (oprot : Protocol.t) = oprot#writeStructBegin "TApplicationExeception"; if self#get_message != "" then (oprot#writeFieldBegin ("message",Protocol.T_STRING, 1); oprot#writeString self#get_message; oprot#writeFieldEnd) else (); oprot#writeFieldBegin ("type",Protocol.T_I32,2); oprot#writeI32 (typ_to_i typ); oprot#writeFieldEnd; oprot#writeFieldStop; oprot#writeStructEnd end;; let create typ msg = let e = new t in e#set_type typ; e#set_message msg; e let read (iprot : Protocol.t) = let msg = ref "" in let typ = ref 0l in ignore iprot#readStructBegin; (try while true do let (name,ft,id) =iprot#readFieldBegin in if ft = Protocol.T_STOP then raise Break else (); (match id with | 1 -> (if ft = Protocol.T_STRING then msg := (iprot#readString) else iprot#skip ft) | 2 -> (if ft = Protocol.T_I32 then typ := iprot#readI32 else iprot#skip ft) | _ -> iprot#skip ft); iprot#readFieldEnd done with Break -> ()); iprot#readStructEnd; let e = new t in e#set_type (typ_of_i !typ); e#set_message !msg; e;; exception E of t end;; thrift-0.23.0/lib/ocaml/src/TSocket.ml0000664000175000017500000000451415165535636017737 0ustar00buildbuild00000000000000(* 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. *) open Thrift module T = Transport class t host port= object (self) inherit T.t val mutable chans = None method isOpen = chans != None method opn = try let addr = (let {Unix.h_addr_list=x} = Unix.gethostbyname host in x.(0)) in chans <- Some(Unix.open_connection (Unix.ADDR_INET (addr,port))) with Unix.Unix_error (e,fn,_) -> raise (T.E (T.NOT_OPEN, ("TSocket: Could not connect to "^host^":"^(string_of_int port)^" because: "^fn^":"^(Unix.error_message e)))) | _ -> raise (T.E (T.NOT_OPEN, ("TSocket: Could not connect to "^host^":"^(string_of_int port)))) method close = match chans with None -> () | Some(inc,out) -> (Unix.shutdown_connection inc; close_in inc; chans <- None) method read buf off len = match chans with None -> raise (T.E (T.NOT_OPEN, "TSocket: Socket not open")) | Some(i,o) -> try really_input i buf off len; len with Unix.Unix_error (e,fn,_) -> raise (T.E (T.UNKNOWN, ("TSocket: Could not read "^(string_of_int len)^" from "^host^":"^(string_of_int port)^" because: "^fn^":"^(Unix.error_message e)))) | _ -> raise (T.E (T.UNKNOWN, ("TSocket: Could not read "^(string_of_int len)^" from "^host^":"^(string_of_int port)))) method write buf off len = match chans with None -> raise (T.E (T.NOT_OPEN, "TSocket: Socket not open")) | Some(i,o) -> output o buf off len method flush = match chans with None -> raise (T.E (T.NOT_OPEN, "TSocket: Socket not open")) | Some(i,o) -> flush o end thrift-0.23.0/lib/ocaml/src/TServerSocket.ml0000664000175000017500000000272515165535636021130 0ustar00buildbuild00000000000000(* 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. *) open Thrift class t port = object inherit Transport.server_t val mutable sock = None method listen = let s = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in sock <- Some s; Unix.bind s (Unix.ADDR_INET (Unix.inet_addr_any, port)); Unix.listen s 256 method close = match sock with Some s -> Unix.shutdown s Unix.SHUTDOWN_ALL; Unix.close s; sock <- None | _ -> () method acceptImpl = match sock with Some s -> let (fd,_) = Unix.accept s in new TChannelTransport.t (Unix.in_channel_of_descr fd,Unix.out_channel_of_descr fd) | _ -> raise (Transport.E (Transport.NOT_OPEN,"TServerSocket: Not listening but tried to accept")) end thrift-0.23.0/lib/ocaml/src/TThreadedServer.ml0000664000175000017500000000251315165535636021413 0ustar00buildbuild00000000000000(* 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. *) open Thrift class t (pf : Processor.t) (st : Transport.server_t) (tf : Transport.factory) (ipf : Protocol.factory) (opf : Protocol.factory)= object inherit TServer.t pf st tf ipf opf method serve = st#listen; while true do let tr = tf#getTransport (st#accept) in ignore (Thread.create (fun _ -> let ip = ipf#getProtocol tr in let op = opf#getProtocol tr in try while pf#process ip op do () done with _ -> ()) ()) done end thrift-0.23.0/lib/ocaml/src/TServer.ml0000664000175000017500000000264715165535636017762 0ustar00buildbuild00000000000000(* 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. *) open Thrift class virtual t (pf : Processor.t) (st : Transport.server_t) (tf : Transport.factory) (ipf : Protocol.factory) (opf : Protocol.factory)= object method virtual serve : unit end;; let run_basic_server proc port = Unix.establish_server (fun inp -> fun out -> let trans = new TChannelTransport.t (inp,out) in let proto = new TBinaryProtocol.t (trans :> Transport.t) in try while proc#process proto proto do () done; () with e -> ()) (Unix.ADDR_INET (Unix.inet_addr_of_string "127.0.0.1",port)) thrift-0.23.0/lib/ocaml/src/TSimpleServer.ml0000664000175000017500000000233715165535636021130 0ustar00buildbuild00000000000000(* 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. *) open Thrift module S = TServer class t pf st tf ipf opf = object inherit S.t pf st tf ipf opf method serve = try st#listen; while true do let c = st#accept in let trans = tf#getTransport c in let inp = ipf#getProtocol trans in let op = opf#getProtocol trans in try while (pf#process inp op) do () done; trans#close with e -> trans#close; raise e done with _ -> () end thrift-0.23.0/lib/ocaml/src/Makefile0000664000175000017500000000211115165535636017460 0ustar00buildbuild00000000000000# # 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. # SOURCES = Thrift.ml TBinaryProtocol.ml TSocket.ml TFramedTransport.ml TChannelTransport.ml TServer.ml TSimpleServer.ml TServerSocket.ml TThreadedServer.ml RESULT = thrift LIBS = unix threads THREADS = yes all: native-code-library debug-code-library top OCAMLMAKEFILE = ../OCamlMakefile include $(OCAMLMAKEFILE) thrift-0.23.0/lib/ocaml/src/TChannelTransport.ml0000664000175000017500000000246315165535636021775 0ustar00buildbuild00000000000000(* 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. *) open Thrift module T = Transport class t (i,o) = object (self) val mutable opened = true inherit Transport.t method isOpen = opened method opn = () method close = close_in i; opened <- false method read buf off len = if opened then try really_input i buf off len; len with _ -> raise (T.E (T.UNKNOWN, ("TChannelTransport: Could not read "^(string_of_int len)))) else raise (T.E (T.NOT_OPEN, "TChannelTransport: Channel was closed")) method write buf off len = output o buf off len method flush = flush o end thrift-0.23.0/lib/ocaml/src/TFramedTransport.ml0000664000175000017500000000511515165535636021620 0ustar00buildbuild00000000000000open Thrift module T = Transport let c_0xff_32 = Int32.of_string "0xff" (* Copied from OCamlnet rtypes.ml *) let encode_frame_size x = let s = String.create 4 in let n3 = Int32.to_int (Int32.shift_right_logical x 24) land 0xff in let n2 = Int32.to_int (Int32.shift_right_logical x 16) land 0xff in let n1 = Int32.to_int (Int32.shift_right_logical x 8) land 0xff in let n0 = Int32.to_int (Int32.logand x c_0xff_32) in String.unsafe_set s 0 (Char.unsafe_chr n3); String.unsafe_set s 1 (Char.unsafe_chr n2); String.unsafe_set s 2 (Char.unsafe_chr n1); String.unsafe_set s 3 (Char.unsafe_chr n0); s let decode_frame_size s = let n3 = Int32.of_int (Char.code s.[0]) in let n2 = Int32.of_int (Char.code s.[1]) in let n1 = Int32.of_int (Char.code s.[2]) in let n0 = Int32.of_int (Char.code s.[3]) in Int32.logor (Int32.shift_left n3 24) (Int32.logor (Int32.shift_left n2 16) (Int32.logor (Int32.shift_left n1 8) n0)) class t ?(max_length=Sys.max_string_length) (transport: T.t) = object (self) inherit T.t method isOpen = transport#isOpen method opn = transport#opn method close = transport#close val mutable read_buf = None val mutable read_buf_offset = 0 val mutable write_buf = "" method private read_frame = let len_buf = String.create 4 in assert (transport#readAll len_buf 0 4 = 4); let size = Int32.to_int (decode_frame_size len_buf) in (if size < 0 then failwith (Printf.sprintf "Read a negative frame size (%i)!" size)); (if size > max_length then failwith (Printf.sprintf "Frame size (%i) larger than max length (%i)!" size max_length)); let buf = String.create size in assert (transport#readAll buf 0 size = size); read_buf <- Some buf; read_buf_offset <- 0 method private read_from_frame frame buf off len = let to_copy = min len ((String.length frame) - read_buf_offset) in String.blit frame read_buf_offset buf off to_copy; read_buf_offset <- read_buf_offset + to_copy; to_copy method read buf off len = match read_buf with | Some frame -> let i = self#read_from_frame frame buf off len in if i > 0 then i else begin self#read_frame; self#read_from_frame frame buf off len end | None -> self#read_frame; self#read buf off len method write buf off len = write_buf <- write_buf ^ (String.sub buf off len) method flush = let encoded_size = encode_frame_size (Int32.of_int (String.length write_buf)) in transport#write encoded_size 0 (String.length encoded_size); transport#write write_buf 0 (String.length write_buf); transport#flush; write_buf <- "" end thrift-0.23.0/lib/ocaml/coding_standards.md0000664000175000017500000000010315165535636021060 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/ocaml/descr0000664000175000017500000000006015165535636016255 0ustar00buildbuild00000000000000OCaml bindings for the Apache Thrift RPC system thrift-0.23.0/lib/ocaml/DEVELOPMENT0000664000175000017500000000405215165535636016744 0ustar00buildbuild00000000000000Thrift OCaml Development ======================== Prerequisites ------------- In order to build this library, you must have the following installed: * The OCaml compiler, preferably >4.00 * The Oasis build tool In addition you may want to install OPAM, which will allow you to setup an OCaml development environment that's isolated from your system installation, much like virutalenv for Python or the myriad systems available for Ruby. If you have OPAM installed, then installing Oasis is as simple as running: $ opam install oasis Building -------- Once all the prerequisites have been installed, run the following commands: $ oasis setup $ ./configure $ make The `oasis setup` command will generate the configure script and Makefile, along with other files that opam will use to create an installable library. The cofigure script will ensure that all build dependencies are installed, and make will actually build the library. To remove files that the compiler geneates, run: $ make clean To remove those files _as well as_ files that the setup and configure process generates, run: $ rm `cat .gitignore` Installing ---------- If you're using opam, simply run the following command: $ make install While development, you may want to install your latest build on the system to test against other libraries or programs. To do this, use: $ make reinstall Distribution ------------ The de facto preferred method for distributing OCaml libraries is through the OPAM package repository. To publish the latest package, issue a pull request against the following github repository: https://github.com/ocaml/opam-repository The pull requestion should add the following directory structure and files: package |__thrift |__thrift. |__ descr |__ opam |__ url Templates for the following files can be found in the opam/ subdirectory of this library's root, with XXX(...) indicating fields that need to be filled out. You can find further documentation here: http://opam.ocaml.org/doc/Packaging.html thrift-0.23.0/lib/ocaml/README.md0000664000175000017500000000554415165535636016525 0ustar00buildbuild00000000000000Thrift OCaml Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Library ======= The library abstract classes, exceptions, and general use functions are mostly jammed in Thrift.ml (an exception being TServer). Generally, classes are used, however they are often put in their own module along with other relevant types and functions. The classes often called t, exceptions are called E. Implementations live in their own files. There is TBinaryProtocol, TSocket, TThreadedServer, TSimpleServer, and TServerSocket. A note on making the library: Running make should create native, debug code libraries, and a toplevel. Struct format ------------- Structs are turned into classes. The fields are all option types and are initially None. Write is a method, but reading is done by a separate function (since there is no such thing as a static class). The class type is t and is in a module with the name of the struct. enum format ----------- Enums are put in their own module along with functions to_i and of_i which convert the ocaml types into ints. For example: enum Numberz { ONE = 1, TWO, THREE, FIVE = 5, SIX, EIGHT = 8 } ==> module Numberz = struct type t = | ONE | TWO | THREE | FIVE | SIX | EIGHT let of_i = ... let to_i = ... end typedef format -------------- Typedef turns into the type declaration: typedef i64 UserId ==> type userid Int64.t exception format ---------------- The same as structs except that the module also has an exception type E of t that is raised/caught. For example, with an exception Xception, raise (Xception.E (new Xception.t)) and try ... with Xception.E e -> ... list format ----------- Lists are turned into OCaml native lists. Map/Set formats --------------- These are both turned into Hashtbl.t's. Set values are bool. Services -------- The client is a class "client" parametrized on input and output protocols. The processor is a class parametrized on a handler. A handler is a class inheriting the iface abstract class. Unlike other implementations, client does not implement iface since iface functions must take option arguments so as to deal with the case where a client does not send all the arguments. thrift-0.23.0/lib/ocaml/url0000664000175000017500000000011115165535636015754 0ustar00buildbuild00000000000000archive: "XXX(FILL ME IN WITH URL)" checksum: "XXX(FILL ME IN WITH MD5)" thrift-0.23.0/lib/cl/0000755000175000017500000000000015170007201014511 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cl/test/0000775000175000017500000000000015165535636015520 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cl/test/make-test-binary.lisp0000664000175000017500000000273015165535636021567 0ustar00buildbuild00000000000000;;;; 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. ;;;; This file is used to build the binary that runs all self-tests. The ;;;; binary is then meant to be hooked up to Thrift's `make check` facility, ;;;; but can easily be run on its own as well. (in-package #:cl-user) (require "asdf") (load (merge-pathnames "../load-locally.lisp" *load-truename*)) (asdf:load-asd (merge-pathnames "../lib/de.setf.thrift-backport-update/test/thrift-test.asd" *load-truename*)) (asdf:load-system :thrift-test) (require "sb-grovel") ;; necessary for :net.didierverna.clon.termio (asdf:load-asd (first (directory (merge-pathnames "../externals/software/clon-*/termio/net.didierverna.clon.termio.asd" *load-truename*)))) (asdf:load-system :net.didierverna.clon) (net.didierverna.clon:nickname-package) (defun main () (let ((result (if (fiasco:run-tests 'thrift-test) 0 -1))) (clon:exit result))) (clon:dump "run-tests" main) thrift-0.23.0/lib/cl/README.md0000664000175000017500000002366215165535636016031 0ustar00buildbuild00000000000000Thrift Common Lisp Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Thrift with Common Lisp ============================ Thrift is a protocol and library for language-independent communication between cooperating processes. The communication takes the form of request and response messages, of which the forms are specified in advance throufh a shared interface definition. A Thrift definition file is translated into Lisp source files, which comprise several definitions: * Three packages, one for the namespace of the implementation operators, and one each for request and response operators. * Various type definitions as implementations for Thrift typedef and enum definitions. * DEF-STRUCT and DEF-EXCEPTION forms for Thrift struct and exception definitions. * DEF-SERVICE forms for thrift service definitions. Each service definition expands in a collection of generic function definitions. For each `op` in the service definition, two functions are defined * `op`-request is defined for use by a client. It accepts an additional initial `protocol` argument, to act as the client proxy for the operation and mediate the interaction with a remote process through a Thrift-encoded transport stream. * `op`-response is defined for use by a server. It accepts a single `protocol` argument. A server uses it to decode the request message, invoke the base `op` function with the message arguments, encode and send the the result as a response, and handles exceptions. The client interface is one operator * `with-client (variable location) . body` : creates a connection in a dynamic context and closes it upon exit. The variable is bound to a client proxy stream/protocol instance, which wraps the base i/o stream - socket, file, etc, with an operators which implement the Thrift protocol and transport mechanisms. The server interface combines server and service objects * `serve (location service)` : accepts connections on the designated port and responds to requests of the service's operations. Building -------- The Thrift Common Lisp library is packaged as the ASDF[[1]] system `thrift`. It depends on the systems * puri[[2]] : for the thrift uri class * closer-mop[[3]] : for class metadata * trivial-utf-8[[4]] : for string codecs * usocket[[5]] : for the socket transport * ieee-floats[[6]] : for conversion between ints and floats * trivial-gray-streams[[7]] : an abstraction layer for gray streams * alexandria[[8]] : handy utilities The dependencies are bundled for local builds of tests and tutorial binaries - it is possible to use those bundles to load the library, too. In order to build it, register those systems with ASDF and evaluate: (asdf:load-system :thrift) This will compile and load the Lisp compiler for Thrift definition files, the transport and protocol implementations, and the client and server interface functions. In order to use Thrift in an application, one must also author and/or load the interface definitions for the remote service.[[9]] If one is implementing a service, one must also define the actual functions to which Thrift is to act as the proxy interface. The remainder of this document follows the Thrift tutorial to illustrate how to perform the steps * implement the service * translate the Thrift IDL * load the Lisp service interfaces * run a server for the service * use a client to access the service remotely Note that, if one is to implement a new service, one will also need to author the IDL files, as there is no facility to generate them from a service implementation. Implement the Service --------------------- The tutorial comprises serveral functions: `add`, `ping`, `zip`, and `calculate`. Each translated IDL file generates three packages for every service. In the case of the tutorial file, the relevant packages are: * tutorial.calculator * tutorial.calculator-implementation * tutorial.calculator-response This is to separate the request (generated), response (generated) and implementation (meant to be implemented by the programmer) functions for defined Thrift methods. It is suggested to work in the `tutorial-implementation` package while implementing the services - it imports the `common-lisp` package, while the service-specific ones don't (to avoid conflicts between Thrift method names and function names in `common-lisp`). ;; define the base operations (in-package :tutorial-implementation) (defun tutorial.calculator-implementation:add (num1 num2) (format t "~&Asked to add ~A and ~A." num1 num2) (+ num1 num2)) (defun tutorial.calculator-implementation:ping () (print :ping)) (defun tutorial.calculator-implementation:zip () (print :zip)) (defun tutorial.calculator-implementation:calculate (logid task) (calculate-op (work-op task) (work-num1 task) (work-num2 task))) (defgeneric calculate-op (op arg1 arg2) (:method :around (op arg1 arg2) (let ((result (call-next-method))) (format t "~&Asked to calculate: ~d on ~A and ~A = ~d." op arg1 arg2 result) result)) (:method ((op (eql operation.add)) arg1 arg2) (+ arg1 arg2)) (:method ((op (eql operation.subtract)) arg1 arg2) (- arg1 arg2)) (:method ((op (eql operation.multiply)) arg1 arg2) (* arg1 arg2)) (:method ((op (eql operation.divide)) arg1 arg2) (/ arg1 arg2))) (defun zip () (print 'zip)) Translate the Thrift IDL ------------------------ IDL files employ the file extension `thrift`. In this case, there are two files to translate * `tutorial.thrift` * `shared.thrift` As the former includes the latter, one uses it to generate the interfaces: $THRIFT/bin/thrift -r --gen cl $THRIFT/tutorial/tutorial.thrift `-r` stands for recursion, while `--gen` lets one choose the language to translate to. Load the Lisp translated service interfaces ------------------------------------------- The translator generates three files for each IDL file. For example `tutorial-types.lisp`, `tutorial-vars.lisp` and an `.asd` file that can be used to load them both and pull in other includes (like `shared` within the tutorial) as dependencies. Run a Server for the Service ---------------------------- The actual service name, as specified in the `def-service` form in `tutorial.lisp`, is `calculator`. Each service definition defines a global variable with the service name and binds it to a service instance whch describes the operations. In order to start a service, specify a location and the service instance. (in-package :tutorial) (serve #u"thrift://127.0.0.1:9091" calculator) Use a Client to Access the Service Remotely ------------------------------------------- [in some other process] run the client (in-package :cl-user) (macrolet ((show (form) `(format *trace-output* "~%~s =>~{ ~s~}" ',form (multiple-value-list (ignore-errors ,form))))) (with-client (protocol #u"thrift://127.0.0.1:9091") (show (tutorial.calculator:ping protocol)) (show (tutorial.calculator:add protocol 1 2)) (show (tutorial.calculator:add protocol 1 4)) (let ((task (make-instance 'tutorial:work :op operation.subtract :num1 15 :num2 10))) (show (tutorial.calculator:calculate protocol 1 task)) (setf (tutorial:work-op task) operation.divide (tutorial:work-num1 task) 1 (tutorial:work-num2 task) 0) (show (tutorial.calculator:calculate protocol 1 task))) (show (shared.shared-service:get-struct protocol 1)) (show (zip protocol)))) Issues ------ ### optional fields Where the IDL declares a field options, the def-struct form includes no initform for the slot and the encoding operator skips an unbound slot. This leave some ambiguity with bool fields. ### instantiation protocol : struct classes are standard classes and exception classes are whatever the implementation prescribes. decoders apply make-struct to an initargs list. particularly at the service end, there are advantages to resourcing structs and decoding with direct side-effects on slot-values ### maps: Maps are now represented as hash tables. As data through the call/reply interface is all statically typed, it is not necessary for the objects to themselves indicate the coding form. Association lists would be sufficient. As the key type is arbitrary, property lists offer no additional convenience: as `getf` operates with `eq` a new access interface would be necessary and they would not be available for function application. [1]: www.common-lisp.net/asdf [2]: http://github.com/lisp/com.b9.puri.ppcre [3]: www.common-lisp.net/closer-mop [4]: trivial-utf-8 [5]: https://github.com/usocket/usocket [6]: https://github.com/marijnh/ieee-floats [7]: https://github.com/trivial-gray-streams/trivial-gray-streams [8]: https://gitlab.common-lisp.net/alexandria/alexandria [9]: http://wiki.apache.org/thrift/ThriftGeneration * usocket[[5]] : for the socket transport * ieee-floats[[6]] : for conversion between ints and floats * trivial-gray-streams[[7]] : an abstraction layer for gray streams * alexandria[[8]] : handy utilities thrift-0.23.0/lib/cl/Makefile.in0000644000175000017500000004323615170007166016600 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ README.md \ READMES \ load-locally.lisp \ test \ ensure-externals.sh all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/cl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/cl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile all-local: bash ensure-externals.sh run-tests: test/make-test-binary.lisp $(SBCL) --script test/make-test-binary.lisp check-local: run-tests ./run-tests clean-local: $(RM) run-tests quicklisp.lisp backport-update.zip $(RM) -rf lib externals quicklisp distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/cl/ensure-externals.sh0000775000175000017500000000131715165535636020406 0ustar00buildbuild00000000000000#!/bin/bash set -e if [[ ! -e quicklisp.lisp ]]; then curl -O https://beta.quicklisp.org/quicklisp.lisp; fi sbcl --load quicklisp.lisp \ --eval "(ignore-errors (quicklisp-quickstart:install :path \"quicklisp/\"))" \ --eval "(load \"quicklisp/setup.lisp\")" \ --eval "(quicklisp:bundle-systems '(#:puri #:usocket #:closer-mop #:trivial-utf-8 #:ieee-floats #:trivial-gray-streams #:alexandria #:bordeaux-threads #:cl-ppcre #:fiasco #:net.didierverna.clon) :to \"externals/\")" \ --eval "(quit)" \ --no-userinit if [[ ! -e backport-update.zip ]]; then curl -O -L https://github.com/TurtleWarePL/de.setf.thrift/archive/backport-update.zip; fi mkdir -p lib unzip -u backport-update.zip -d lib thrift-0.23.0/lib/cl/READMES/0000775000175000017500000000000015165535636015621 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cl/READMES/readme-cassandra.lisp0000664000175000017500000000523015165535636021704 0ustar00buildbuild00000000000000(in-package :cl-user) #+(or ccl sbcl) /development/source/library/ (load "build-init.lisp") ;;; ! first, select the api version in the cassandra system definition ;;; as only one should be loaded at a time. (asdf:load-system :de.setf.cassandra) (in-package :de.setf.cassandra) (defparameter *c-location* ;; remote ;; #u"thrift://ec2-174-129-66-148.compute-1.amazonaws.com:9160" ;; local #u"thrift://127.0.0.1:9160" "A cassandra service location - either the local one or a remote service - always a 'thrift' uri.") (defparameter *c* (thrift:client *c-location*)) (cassandra:describe-keyspaces *c*) ;; => ("Keyspace1" "system") (cassandra:describe-cluster-name *c*) ;; =>"Test Cluster" (cassandra:describe-version *c*) ;; => "2.1.0" (loop for space in (cassandra:describe-keyspaces *c*) collect (loop for key being each hash-key of (cassandra:describe-keyspace *c* space) using (hash-value value) collect (cons key (loop for key being each hash-key of value using (hash-value value) collect (cons key value))))) (close *c*) (defun describe-cassandra (location &optional (stream *standard-output*)) "Print the first-order store metadata for a cassandra LOCATION." (thrift:with-client (cassandra location) (let* ((keyspace-names (cassandra:describe-keyspaces cassandra)) (cluster (cassandra:describe-cluster-name cassandra)) (version (cassandra:describe-version cassandra)) (keyspace-descriptions (loop for space in keyspace-names collect (cons space (loop for key being each hash-key of (cassandra:describe-keyspace cassandra space) using (hash-value value) collect (cons key (loop for key being each hash-key of value using (hash-value value) collect (cons key value)))))))) (format stream "~&connection to : ~a" cassandra) (format stream "~&version : ~a" version) (format stream "~&cluster : ~a" cluster) (format stream "~&keyspaces~{~{~%~%space: ~a~@{~% ~{~a :~@{~20t~:w~^~%~}~}~}~}~}" keyspace-descriptions)))) ;;; (describe-cassandra *c-location*) thrift-0.23.0/lib/cl/Makefile.am0000664000175000017500000000231315165535636016574 0ustar00buildbuild00000000000000# # 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. # THRIFT = $(top_builddir)/compiler/cpp/thrift all-local: bash ensure-externals.sh run-tests: test/make-test-binary.lisp $(SBCL) --script test/make-test-binary.lisp check-local: run-tests ./run-tests 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 \ load-locally.lisp \ test \ ensure-externals.sh thrift-0.23.0/lib/cl/load-locally.lisp0000664000175000017500000000172215165535636020010 0ustar00buildbuild00000000000000(in-package #:cl-user) ;;;; 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. ;;;; Just a script for loading the library itself, using bundled dependencies. ;;;; This is here for when we want to build the self-test and cross-test ;;;; binaries. (require "asdf") (load (merge-pathnames "externals/bundle.lisp" *load-truename*)) (asdf:load-asd (merge-pathnames "lib/de.setf.thrift-backport-update/thrift.asd" *load-truename*)) (asdf:load-system :thrift) thrift-0.23.0/lib/c_glib/0000755000175000017500000000000015170007200015331 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/0000755000175000017500000000000015170007200016120 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/thrift/0000755000175000017500000000000015170007200017420 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/thrift/c_glib/0000755000175000017500000000000015170007200020637 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift_application_exception.h0000664000175000017500000000624415165535636027010 0ustar00buildbuild00000000000000/* * 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_APPLICATION_EXCEPTION_H #define _THRIFT_APPLICATION_EXCEPTION_H #include #include "thrift_struct.h" G_BEGIN_DECLS /*! \file thrift_application_exception.h * \brief C Implementation of a TApplicationException. */ /* type macros */ #define THRIFT_TYPE_APPLICATION_EXCEPTION (thrift_application_exception_get_type ()) #define THRIFT_APPLICATION_EXCEPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_APPLICATION_EXCEPTION, ThriftApplicationException)) #define THRIFT_IS_APPLICATION_EXCEPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_APPLICATION_EXCEPTION)) #define THRIFT_APPLICATION_EXCEPTION_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_APPLICATION_EXCEPTION, ThriftApplicationExceptionClass)) #define THRIFT_IS_APPLICATION_EXCEPTION_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_APPLICATION_EXCEPTION)) #define THRIFT_APPLICATION_EXCEPTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_APPLICATION_EXCEPTION, ThriftApplicationExceptionClass)) typedef struct _ThriftApplicationException ThriftApplicationException; struct _ThriftApplicationException { ThriftStruct parent; /* private */ gint32 type; gboolean __isset_type; gchar *message; gboolean __isset_message; }; typedef struct _ThriftApplicationExceptionClass ThriftApplicationExceptionClass; struct _ThriftApplicationExceptionClass { ThriftStructClass parent; }; GType thrift_application_exception_get_type (void); /* gerror codes */ typedef enum { THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN, THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD, THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE, THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME, THRIFT_APPLICATION_EXCEPTION_ERROR_BAD_SEQUENCE_ID, THRIFT_APPLICATION_EXCEPTION_ERROR_MISSING_RESULT, THRIFT_APPLICATION_EXCEPTION_ERROR_INTERNAL_ERROR, THRIFT_APPLICATION_EXCEPTION_ERROR_PROTOCOL_ERROR, THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_TRANSFORM, THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_PROTOCOL, THRIFT_APPLICATION_EXCEPTION_ERROR_UNSUPPORTED_CLIENT_TYPE, THRIFT_APPLICATION_EXCEPTION_ERROR_N } ThriftApplicationExceptionError; /* define error domain for GError */ GQuark thrift_application_exception_error_quark (void); #define THRIFT_APPLICATION_EXCEPTION_ERROR (thrift_application_exception_error_quark ()) G_END_DECLS #endif /* _THRIFT_APPLICATION_EXCEPTION_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift.h0000664000175000017500000000313415165535636022342 0ustar00buildbuild00000000000000/* * 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_H #define _THRIFT_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* this macro is called to satisfy -Wall hardcore compilation */ #ifndef THRIFT_UNUSED_VAR # define THRIFT_UNUSED_VAR(x) ((void) x) #endif void thrift_hash_table_get_keys (gpointer key, gpointer value, gpointer user_data); void thrift_safe_hash_table_destroy(GHashTable* hash_table); guint thrift_boolean_hash(gconstpointer v); gboolean thrift_boolean_equal(gconstpointer a, gconstpointer b); guint thrift_int8_hash(gconstpointer v); gboolean thrift_int8_equal(gconstpointer a, gconstpointer b); guint thrift_int16_hash(gconstpointer v); gboolean thrift_int16_equal(gconstpointer a, gconstpointer b); void thrift_string_free (gpointer str); #endif /* #ifndef _THRIFT_THRIFT_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift_application_exception.c0000664000175000017500000002072615165535636027004 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "thrift_application_exception.h" #include /* object properties */ enum _ThriftApplicationExceptionProperties { PROP_0, PROP_THRIFT_APPLICATION_EXCEPTION_TYPE, PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE }; G_DEFINE_TYPE(ThriftApplicationException, thrift_application_exception, THRIFT_TYPE_STRUCT) gint32 thrift_application_exception_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error) { gint32 ret; gint32 xfer = 0; gchar *name; ThriftType ftype; gint16 fid; ThriftApplicationException *this = THRIFT_APPLICATION_EXCEPTION (object); /* read the struct begin marker */ if ((ret = thrift_protocol_read_struct_begin (protocol, &name, error)) < 0) { if (name) g_free (name); return -1; } xfer += ret; if (name) g_free (name); while (1) { if ((ret = thrift_protocol_read_field_begin (protocol, &name, &ftype, &fid, error)) < 0) { if (name) g_free (name); return -1; } xfer += ret; if (name) g_free (name); /* break if we get a STOP field */ if (ftype == T_STOP) { break; } switch (fid) { case 1: if (ftype == T_STRING) { if ((ret = thrift_protocol_read_string (protocol, &this->message, error)) < 0) return -1; xfer += ret; this->__isset_message = TRUE; } else { if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0) return -1; xfer += ret; } break; case 2: if (ftype == T_I32) { if ((ret = thrift_protocol_read_i32 (protocol, &this->type, error)) < 0) return -1; xfer += ret; this->__isset_type = TRUE; } else { if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0) return -1; xfer += ret; } break; default: if ((ret = thrift_protocol_skip (protocol, ftype, error)) < 0) return -1; xfer += ret; break; } if ((ret = thrift_protocol_read_field_end (protocol, error)) < 0) return -1; xfer += ret; } if ((ret = thrift_protocol_read_struct_end (protocol, error)) < 0) return -1; xfer += ret; return xfer; } gint32 thrift_application_exception_write (ThriftStruct *object, ThriftProtocol *protocol, GError **error) { gint32 ret; gint32 xfer = 0; ThriftApplicationException *this = THRIFT_APPLICATION_EXCEPTION (object); if ((ret = thrift_protocol_write_struct_begin (protocol, "TApplicationException", error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_field_begin (protocol, "message", T_STRING, 1, error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_string (protocol, this->message, error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_field_begin (protocol, "type", T_I32, 2, error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_i32 (protocol, this->type, error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_field_end (protocol, error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_field_stop (protocol, error)) < 0) return -1; xfer += ret; if ((ret = thrift_protocol_write_struct_end (protocol, error)) < 0) return -1; xfer += ret; return xfer; } /* GError domain */ #define THRIFT_APPLICATION_EXCEPTION_ERROR_DOMAIN "thrift-application-exception-error-quark" GQuark thrift_application_exception_error_quark (void) { return g_quark_from_static_string (THRIFT_APPLICATION_EXCEPTION_ERROR_DOMAIN); } static void thrift_application_exception_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftApplicationException *tae = THRIFT_APPLICATION_EXCEPTION (object); switch (property_id) { case PROP_THRIFT_APPLICATION_EXCEPTION_TYPE: g_value_set_int (value, tae->type); break; case PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE: g_value_set_string (value, tae->message); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void thrift_application_exception_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftApplicationException *tae = THRIFT_APPLICATION_EXCEPTION (object); switch (property_id) { case PROP_THRIFT_APPLICATION_EXCEPTION_TYPE: tae->type = g_value_get_int (value); tae->__isset_type = TRUE; break; case PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE: if (tae->message != NULL) g_free (tae->message); tae->message = g_value_dup_string (value); tae->__isset_message = TRUE; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } void thrift_application_exception_init (ThriftApplicationException *object) { object->type = 0; object->__isset_type = FALSE; object->message = NULL; object->__isset_message = FALSE; } void thrift_application_exception_finalize (GObject *object) { ThriftApplicationException *tae = THRIFT_APPLICATION_EXCEPTION (object); if (tae->__isset_message) { g_free(tae->message); } } void thrift_application_exception_class_init (ThriftApplicationExceptionClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS(class); ThriftStructClass *cls = THRIFT_STRUCT_CLASS(class); GParamSpec *param_spec; cls->read = thrift_application_exception_read; cls->write = thrift_application_exception_write; gobject_class->finalize = thrift_application_exception_finalize; gobject_class->get_property = thrift_application_exception_get_property; gobject_class->set_property = thrift_application_exception_set_property; param_spec = g_param_spec_int ("type", "Exception type", "The type of the exception, one of the " "values defined by the " "ThriftApplicationExceptionError " "enumeration.", 0, THRIFT_APPLICATION_EXCEPTION_ERROR_N - 1, 0, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_APPLICATION_EXCEPTION_TYPE, param_spec); param_spec = g_param_spec_string ("message", "Exception message", "A string describing the exception that " "occurred.", NULL, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_APPLICATION_EXCEPTION_MESSAGE, param_spec); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift_configuration.h0000664000175000017500000000434215165535636025273 0ustar00buildbuild00000000000000/* * 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_CONFIGURATION_H #define _THRIFT_CONFIGURATION_H #include G_BEGIN_DECLS /* type macros */ #define THRIFT_TYPE_CONFIGURATION (thrift_configuration_get_type ()) #define THRIFT_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_CONFIGURATION, ThriftConfiguration)) #define THRIFT_IS_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_CONFIGURATION)) #define THRIFT_CONFIGURATTION_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_CONFIGURATION, ThriftConfigurationClass)) #define THRIFT_IS_CONFIGURATION_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_CONFIGURATION)) #define THRIFT_CONFIGURATION_GET_CLASS(obj) (G_TYPE_INSTAANCE_GET_CLASS ((obj), THRIFT_TYPE_CONFIGURATION, ThriftconfigurationClass)) typedef struct _ThriftConfiguration ThriftConfiguration; /*! * Thrift Configuration object */ struct _ThriftConfiguration { GObject parent; /* private */ int maxMessageSize_; int maxFrameSize_; int recursionLimit_; }; typedef struct _ThriftConfigurationClass ThriftConfigurationClass; /*! * Thrift Configuration class */ struct _ThriftConfigurationClass { GObjectClass parent; }; /* used by THRIFT_TYPE_CONFIGURATION */ GType thrift_configuration_get_type(void); #define DEFAULT_MAX_MESSAGE_SIZE (100 * 1024 * 1024) #define DEFAULT_MAX_FRAME_SIZE (16384000) #define DEFAULT_RECURSION_DEPTH (64) G_END_DECLS #endif /* #ifndef _THRIFT_CONFIGURATION_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/processor/0000755000175000017500000000000015170007200022656 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.h0000664000175000017500000000464015165535636026463 0ustar00buildbuild00000000000000/* * 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_PROCESSOR_H #define _THRIFT_PROCESSOR_H #include #include G_BEGIN_DECLS /*! \file thrift_processor.h * \brief Abstract class for Thrift processors. */ /* type macros */ #define THRIFT_TYPE_PROCESSOR (thrift_processor_get_type ()) #define THRIFT_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROCESSOR, ThriftProcessor)) #define THRIFT_IS_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROCESSOR)) #define THRIFT_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROCESSOR, ThriftProcessorClass)) #define THRIFT_IS_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROCESSOR)) #define THRIFT_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROCESSOR, ThriftProcessorClass)) /*! * Thrift Processorobject */ struct _ThriftProcessor { GObject parent; }; typedef struct _ThriftProcessor ThriftProcessor; /*! * Thrift Processor class */ struct _ThriftProcessorClass { GObjectClass parent; /* vtable */ gboolean (*process) (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error); }; typedef struct _ThriftProcessorClass ThriftProcessorClass; /* used by THRIFT_TYPE_PROCESSOR */ GType thrift_processor_get_type (void); /*! * Processes the request. * \public \memberof ThriftProcessorClass */ gboolean thrift_processor_process (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error); G_END_DECLS #endif /* _THRIFT_PROCESSOR_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.c0000664000175000017500000001177315165535636030342 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_ABSTRACT_TYPE (ThriftDispatchProcessor, thrift_dispatch_processor, THRIFT_TYPE_PROCESSOR) gboolean thrift_dispatch_processor_process (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error) { gchar *fname; ThriftMessageType mtype; gint32 seqid; ThriftDispatchProcessor *dispatch_processor = THRIFT_DISPATCH_PROCESSOR (processor); /* Read the start of the message, which we expect to be a method call */ if (thrift_protocol_read_message_begin (in, &fname, &mtype, &seqid, error) < 0) { g_warning ("error reading start of message: %s", (error != NULL) ? (*error)->message : "(null)"); return FALSE; } else if (mtype != T_CALL && mtype != T_ONEWAY) { g_warning ("received invalid message type %d from client", mtype); return FALSE; } /* Dispatch the method call */ return THRIFT_DISPATCH_PROCESSOR_GET_CLASS (dispatch_processor) ->dispatch_call (dispatch_processor, in, out, fname, seqid, error); } static gboolean thrift_dispatch_processor_real_dispatch_call (ThriftDispatchProcessor *self, ThriftProtocol *in, ThriftProtocol *out, gchar *fname, gint32 seqid, GError **error) { ThriftTransport *transport; ThriftApplicationException *xception; gchar *message; gint32 result; gboolean dispatch_result = FALSE; THRIFT_UNUSED_VAR (self); /* By default, return an application exception to the client indicating the method name is not recognized. */ if ((thrift_protocol_skip (in, T_STRUCT, error) < 0) || (thrift_protocol_read_message_end (in, error) < 0)) return FALSE; g_object_get (in, "transport", &transport, NULL); result = thrift_transport_read_end (transport, error); g_object_unref (transport); if (result < 0) return FALSE; if (thrift_protocol_write_message_begin (out, fname, T_EXCEPTION, seqid, error) < 0) return FALSE; message = g_strconcat ("Invalid method name: '", fname, "'", NULL); g_free (fname); xception = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, "type", THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD, "message", message, NULL); g_free (message); result = thrift_struct_write (THRIFT_STRUCT (xception), out, error); g_object_unref (xception); if ((result < 0) || (thrift_protocol_write_message_end (out, error) < 0)) return FALSE; g_object_get (out, "transport", &transport, NULL); dispatch_result = ((thrift_transport_write_end (transport, error) >= 0) && (thrift_transport_flush (transport, error) >= 0)); g_object_unref (transport); return dispatch_result; } static void thrift_dispatch_processor_init (ThriftDispatchProcessor *self) { THRIFT_UNUSED_VAR (self); } static void thrift_dispatch_processor_class_init (ThriftDispatchProcessorClass *klass) { ThriftProcessorClass *processor_class = THRIFT_PROCESSOR_CLASS (klass); /* Implement ThriftProcessor's process method */ processor_class->process = thrift_dispatch_processor_process; /* Provide a default implement for dispatch_call, which returns an exception to the client indicating the method name was not recognized */ klass->dispatch_call = thrift_dispatch_processor_real_dispatch_call; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c0000664000175000017500000002543415165535636031076 0ustar00buildbuild00000000000000/* * 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 #include #include #include G_DEFINE_TYPE(ThriftMultiplexedProcessor, thrift_multiplexed_processor, THRIFT_TYPE_PROCESSOR) enum { PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME = 1, PROP_THRIFT_MULTIPLEXED_PROCESSOR_END }; static GParamSpec *thrift_multiplexed_processor_obj_properties[PROP_THRIFT_MULTIPLEXED_PROCESSOR_END] = { NULL, }; static gboolean thrift_multiplexed_processor_register_processor_impl(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error) { THRIFT_UNUSED_VAR (error); ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(processor); g_hash_table_replace(self->multiplexed_services, g_strdup(multiplexed_processor_name), g_object_ref (multiplexed_processor)); /* Make first registered become default */ if(!self->default_processor_name){ self->default_processor_name = g_strdup(multiplexed_processor_name); } return TRUE; } static gboolean thrift_multiplexed_processor_process_impl (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error) { gboolean retval = FALSE; gboolean token_error = FALSE; ThriftApplicationException *xception; ThriftStoredMessageProtocol *stored_message_protocol = NULL; ThriftMessageType message_type; ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(processor); ThriftProcessor *multiplexed_processor = NULL; ThriftTransport *transport; char *token=NULL; int token_index=0; char *state=NULL; gchar *fname=NULL; gint32 seqid, result; /* FIXME It seems that previous processor is not managing error correctly */ if(*error!=NULL) { g_debug ("thrift_multiplexed_processor: last error not removed: %s", *error != NULL ? (*error)->message : "(null)"); g_clear_error (error); } THRIFT_PROTOCOL_GET_CLASS(in)->read_message_begin(in, &fname, &message_type, &seqid, error); if(!(message_type == T_CALL || message_type == T_ONEWAY)) { g_set_error (error, THRIFT_MULTIPLEXED_PROCESSOR_ERROR, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_TYPE, "message type invalid for this processor"); }else{ /* Split by the token */ for (token = strtok_r(fname, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, &state), token_index=0; token != NULL && !token_error; token = strtok_r(NULL, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, &state), token_index++) { switch(token_index){ case 0: /* It should be the service name */ multiplexed_processor = g_hash_table_lookup(self->multiplexed_services, token); if(multiplexed_processor==NULL){ token_error=TRUE; } break; case 1: /* It should be the function name */ stored_message_protocol = g_object_new (THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, "protocol", in, "name", token, "type", message_type, "seqid", seqid, NULL); break; default: g_set_error (error, THRIFT_MULTIPLEXED_PROCESSOR_ERROR, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_WRONGLY_MULTIPLEXED, "the message has more tokens than expected!"); token_error=TRUE; break; } } /* Set default */ if(!stored_message_protocol && !multiplexed_processor && token_index==1 && self->default_processor_name){ /* It should be the service name */ multiplexed_processor = g_hash_table_lookup(self->multiplexed_services, self->default_processor_name); if(multiplexed_processor==NULL){ g_set_error (error, THRIFT_MULTIPLEXED_PROCESSOR_ERROR, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE, "service %s not available on this processor", self->default_processor_name); }else{ /* Set the message name to the original name */ stored_message_protocol = g_object_new (THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, "protocol", in, "name", fname, "type", message_type, "seqid", seqid, NULL); } } if(stored_message_protocol!=NULL && multiplexed_processor!=NULL){ retval = THRIFT_PROCESSOR_GET_CLASS (multiplexed_processor)->process (multiplexed_processor, (ThriftProtocol *) stored_message_protocol, out, error) ; }else{ if(!error) g_set_error (error, THRIFT_MULTIPLEXED_PROCESSOR_ERROR, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE, "service %s is not multiplexed in this processor", fname); } } if(!retval){ /* By default, return an application exception to the client indicating the method name is not recognized. */ /* Copied from dispach processor */ if ((thrift_protocol_skip (in, T_STRUCT, error) < 0) || (thrift_protocol_read_message_end (in, error) < 0)) return retval; g_object_get (in, "transport", &transport, NULL); result = thrift_transport_read_end (transport, error); g_object_unref (transport); if (result < 0) { /* We must free fname */ g_free(fname); return retval; } if (thrift_protocol_write_message_begin (out, fname, T_EXCEPTION, seqid, error) < 0){ /* We must free fname */ g_free(fname); return retval; } xception = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, "type", THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD, "message", (*error)->message, NULL); result = thrift_struct_write (THRIFT_STRUCT (xception), out, error); g_object_unref (xception); if ((result < 0) || (thrift_protocol_write_message_end (out, error) < 0)) return retval; g_object_get (out, "transport", &transport, NULL); retval = ((thrift_transport_write_end (transport, error) >= 0) && (thrift_transport_flush (transport, error) >= 0)); g_object_unref (transport); }else{ /* The protocol now has a copy we can free it */ g_free(fname); } if (stored_message_protocol != NULL) { g_object_unref (stored_message_protocol); } return retval; } /* define the GError domain for Thrift transports */ GQuark thrift_multiplexed_processor_error_quark (void) { return g_quark_from_static_string (THRIFT_MULTIPLEXED_PROCESSOR_ERROR_DOMAIN); } static void thrift_multiplexed_processor_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR (object); switch (property_id) { case PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME: self->default_processor_name = g_value_dup_string (value); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void thrift_multiplexed_processor_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR (object); switch (property_id) { case PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME: g_value_set_string (value, self->default_processor_name); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* destructor */ static void thrift_multiplexed_processor_finalize (GObject *object) { ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(object); /* Free our multiplexed hash table */ g_hash_table_unref (self->multiplexed_services); self->multiplexed_services = NULL; if(self->default_processor_name){ g_free(self->default_processor_name); self->default_processor_name=NULL; } /* Chain up to parent */ if (G_OBJECT_CLASS (thrift_multiplexed_processor_parent_class)->finalize) (*G_OBJECT_CLASS (thrift_multiplexed_processor_parent_class)->finalize) (object); } /* class initializer for ThriftMultiplexedProcessor */ static void thrift_multiplexed_processor_class_init (ThriftMultiplexedProcessorClass *cls) { /* Override */ THRIFT_PROCESSOR_CLASS(cls)->process = thrift_multiplexed_processor_process_impl; GObjectClass *gobject_class = G_OBJECT_CLASS (cls); /* Object methods */ gobject_class->set_property = thrift_multiplexed_processor_set_property; gobject_class->get_property = thrift_multiplexed_processor_get_property; gobject_class->finalize = thrift_multiplexed_processor_finalize; /* Class methods */ cls->register_processor = thrift_multiplexed_processor_register_processor_impl; thrift_multiplexed_processor_obj_properties[PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME] = g_param_spec_string ("default", "Default service name the protocol points to where no multiplexed client used", "Set the default service name", NULL, (G_PARAM_READWRITE)); g_object_class_install_properties (gobject_class, PROP_THRIFT_MULTIPLEXED_PROCESSOR_END, thrift_multiplexed_processor_obj_properties); } static void thrift_multiplexed_processor_init (ThriftMultiplexedProcessor *self) { /* Create our multiplexed services hash table */ self->multiplexed_services = g_hash_table_new_full ( g_str_hash, g_str_equal, g_free, g_object_unref); self->default_processor_name = NULL; } gboolean thrift_multiplexed_processor_register_processor(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error) { return THRIFT_MULTIPLEXED_PROCESSOR_GET_CLASS(processor)->register_processor(processor, multiplexed_processor_name, multiplexed_processor, error); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/processor/thrift_processor.c0000664000175000017500000000300215165535636026445 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_ABSTRACT_TYPE(ThriftProcessor, thrift_processor, G_TYPE_OBJECT) gboolean thrift_processor_process (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error) { return THRIFT_PROCESSOR_GET_CLASS (processor)->process (processor, in, out, error); } /* class initializer for ThriftProcessor */ static void thrift_processor_class_init (ThriftProcessorClass *cls) { /* set these as virtual methods to be implemented by a subclass */ cls->process = thrift_processor_process; } static void thrift_processor_init (ThriftProcessor *processor) { THRIFT_UNUSED_VAR (processor); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/processor/thrift_dispatch_processor.h0000664000175000017500000000671015165535636030342 0ustar00buildbuild00000000000000/* * 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_DISPATCH_PROCESSOR_H #define _THRIFT_DISPATCH_PROCESSOR_H #include #include G_BEGIN_DECLS /*! \file thrift_dispatch_processor.h * \brief Parses a method-call message header and invokes a function * to dispatch the call by function name. * * ThriftDispatchProcessor is an abstract helper class that parses the * header of a method-call message and invokes a member function, * dispatch_call, with the method's name. * * Subclasses must implement dispatch_call to dispatch the method call * to the implementing function. */ /* Type macros */ #define THRIFT_TYPE_DISPATCH_PROCESSOR (thrift_dispatch_processor_get_type ()) #define THRIFT_DISPATCH_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_DISPATCH_PROCESSOR, ThriftDispatchProcessor)) #define THRIFT_IS_DISPATCH_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_DISPATCH_PROCESSOR)) #define THRIFT_DISPATCH_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_DISPATCH_PROCESSOR, ThriftDispatchProcessorClass)) #define THRIFT_IS_DISPATCH_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_DISPATCH_PROCESSOR)) #define THRIFT_DISPATCH_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_DISPATCH_PROCESSOR, ThriftDispatchProcessorClass)) /*! * Thrift Dispatch Processor object */ struct _ThriftDispatchProcessor { ThriftProcessor parent; }; typedef struct _ThriftDispatchProcessor ThriftDispatchProcessor; /*! * Thrift Dispatch Processor class */ struct _ThriftDispatchProcessorClass { ThriftProcessorClass parent; /* public */ gboolean (*process) (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error); /* protected */ gboolean (*dispatch_call) (ThriftDispatchProcessor *self, ThriftProtocol *in, ThriftProtocol *out, gchar *fname, gint32 seqid, GError **error); }; typedef struct _ThriftDispatchProcessorClass ThriftDispatchProcessorClass; /* Used by THRIFT_TYPE_DISPATCH_PROCESSOR */ GType thrift_dispatch_processor_get_type (void); /*! * Processes a request. * \public \memberof ThriftDispatchProcessorClass */ gboolean thrift_dispatch_processor_process (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error); G_END_DECLS #endif /* _THRIFT_DISPATCH_PROCESSOR_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h0000664000175000017500000000761215165535636031101 0ustar00buildbuild00000000000000/* * thrift_multiplexed_processor.h * * Created on: 14 sept. 2017 * Author: gaguilar */ #ifndef _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_ #define _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_ #include #include G_BEGIN_DECLS /*! \file thrift_multiplexed_processor.h * \brief The multiplexed processor for c_glib. */ /* type macros */ #define THRIFT_TYPE_MULTIPLEXED_PROCESSOR (thrift_multiplexed_processor_get_type ()) #define THRIFT_MULTIPLEXED_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessor)) #define THRIFT_IS_MULTIPLEXED_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR)) #define THRIFT_MULTIPLEXED_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessorClass)) #define THRIFT_IS_MULTIPLEXED_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MULTIPLEXED_PROCESSOR)) #define THRIFT_MULTIPLEXED_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessorClass)) /* define the GError domain string */ #define THRIFT_MULTIPLEXED_PROCESSOR_ERROR_DOMAIN "thrift-multiplexed-processor-error-quark" /*! * Thrift MultiplexedProcessor object */ struct _ThriftMultiplexedProcessor { ThriftProcessor parent; /* private */ gchar * default_processor_name; GHashTable *multiplexed_services; }; typedef struct _ThriftMultiplexedProcessor ThriftMultiplexedProcessor; /*! * Thrift MultiplexedProcessor class */ struct _ThriftMultiplexedProcessorClass { ThriftProcessorClass parent; gboolean (* register_processor) (ThriftProcessor *self, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error); }; typedef struct _ThriftMultiplexedProcessorClass ThriftMultiplexedProcessorClass; /* used by THRIFT_TYPE_MULTIPLEXED_PROCESSOR */ GType thrift_multiplexed_processor_get_type (void); /*! * Processes the request. * \public \memberof ThriftMultiplexedProcessorClass */ gboolean thrift_multiplexed_processor_process (ThriftMultiplexedProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error); /* Public API */ /** * @brief Registers a processor in the multiplexed processor under its name. It * will take a reference to the processor so refcount will be incremented. * It will also be decremented on object destruction. * * The first registered processor becomes default. But you can override it with * "default" property. * * It returns a compliant error if it cannot be registered. * * @param processor Pointer to the multiplexed processor. * @param multiplexed_processor_name Name of the processor you want to register * @param multiplexed_processor Pointer to implemented processor you want multiplex. * @param error Error object where we should store errors. * * @see https://developer.gnome.org/glib/stable/glib-Error-Reporting.html#g-set-error */ gboolean thrift_multiplexed_processor_register_processor(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error); /* define error/exception types */ typedef enum { THRIFT_MULTIPLEXED_PROCESSOR_ERROR_UNKNOWN, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_TYPE, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_WRONGLY_MULTIPLEXED, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SEND, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_RECEIVE, THRIFT_MULTIPLEXED_PROCESSOR_ERROR_CLOSE } ThriftMultiplexedProcessorError; GQuark thrift_multiplexed_processor_error_quark (void); #define THRIFT_MULTIPLEXED_PROCESSOR_ERROR (thrift_multiplexed_processor_error_quark ()) G_END_DECLS #endif /* _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_ */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift_struct.c0000664000175000017500000000317715165535636023750 0ustar00buildbuild00000000000000/* * 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 "thrift_struct.h" G_DEFINE_ABSTRACT_TYPE(ThriftStruct, thrift_struct, G_TYPE_OBJECT) gint32 thrift_struct_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error) { g_return_val_if_fail (THRIFT_IS_STRUCT (object), -1); return THRIFT_STRUCT_GET_CLASS (object)->read (object, protocol, error); } gint32 thrift_struct_write (ThriftStruct *object, ThriftProtocol *protocol, GError **error) { g_return_val_if_fail (THRIFT_IS_STRUCT (object), -1); return THRIFT_STRUCT_GET_CLASS (object)->write (object, protocol, error); } static void thrift_struct_class_init (ThriftStructClass *cls) { cls->read = thrift_struct_read; cls->write = thrift_struct_write; } static void thrift_struct_init (ThriftStruct *structure) { THRIFT_UNUSED_VAR (structure); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/server/0000755000175000017500000000000015170007200022145 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.c0000664000175000017500000001233215165535636026602 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_TYPE(ThriftSimpleServer, thrift_simple_server, THRIFT_TYPE_SERVER) gboolean thrift_simple_server_serve (ThriftServer *server, GError **error) { ThriftTransport *t = NULL; ThriftTransport *input_transport = NULL, *output_transport = NULL; ThriftProtocol *input_protocol = NULL, *output_protocol = NULL; ThriftSimpleServer *tss = THRIFT_SIMPLE_SERVER(server); GError *process_error = NULL; g_return_val_if_fail (THRIFT_IS_SIMPLE_SERVER (server), FALSE); if (thrift_server_transport_listen (server->server_transport, error)) { tss->running = TRUE; while (tss->running == TRUE) { t = thrift_server_transport_accept (server->server_transport, error); if (t != NULL && tss->running) { input_transport = THRIFT_TRANSPORT_FACTORY_GET_CLASS (server->input_transport_factory) ->get_transport (server->input_transport_factory, t); output_transport = THRIFT_TRANSPORT_FACTORY_GET_CLASS (server->output_transport_factory) ->get_transport (server->output_transport_factory, t); input_protocol = THRIFT_PROTOCOL_FACTORY_GET_CLASS (server->input_protocol_factory) ->get_protocol (server->input_protocol_factory, input_transport); output_protocol = THRIFT_PROTOCOL_FACTORY_GET_CLASS (server->output_protocol_factory) ->get_protocol (server->output_protocol_factory, output_transport); while (THRIFT_PROCESSOR_GET_CLASS (server->processor) ->process (server->processor, input_protocol, output_protocol, &process_error) && thrift_transport_peek (input_transport, &process_error)) { } if (process_error != NULL) { g_message ("thrift_simple_server_serve: %s", process_error->message); g_clear_error (&process_error); /* Note we do not propagate processing errors to the caller as they * normally are transient and not fatal to the server */ } /* TODO: handle exceptions */ THRIFT_TRANSPORT_GET_CLASS (input_transport)->close (input_transport, NULL); THRIFT_TRANSPORT_GET_CLASS (output_transport)->close (output_transport, NULL); g_object_unref (input_transport); g_object_unref (output_transport); g_object_unref (input_protocol); g_object_unref (output_protocol); } if ((*error) != NULL) { g_message ("thrift_simple_server_serve : %s", (*error)->message); g_clear_error (error); } if (t != NULL) { g_object_unref (t); } } /* attempt to shutdown */ THRIFT_SERVER_TRANSPORT_GET_CLASS (server->server_transport) ->close (server->server_transport, NULL); } /* Since this method is designed to run forever, it can only ever return on * error */ return FALSE; } void thrift_simple_server_stop (ThriftServer *server) { g_return_if_fail (THRIFT_IS_SIMPLE_SERVER (server)); (THRIFT_SIMPLE_SERVER (server))->running = FALSE; } static void thrift_simple_server_init (ThriftSimpleServer *tss) { ThriftServer *server = THRIFT_SERVER(tss); tss->running = FALSE; if (server->input_transport_factory == NULL) { server->input_transport_factory = g_object_new (THRIFT_TYPE_TRANSPORT_FACTORY, NULL); } if (server->output_transport_factory == NULL) { server->output_transport_factory = g_object_new (THRIFT_TYPE_TRANSPORT_FACTORY, NULL); } if (server->input_protocol_factory == NULL) { server->input_protocol_factory = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, NULL); } if (server->output_protocol_factory == NULL) { server->output_protocol_factory = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, NULL); } } /* initialize the class */ static void thrift_simple_server_class_init (ThriftSimpleServerClass *class) { ThriftServerClass *cls = THRIFT_SERVER_CLASS(class); cls->serve = thrift_simple_server_serve; cls->stop = thrift_simple_server_stop; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/server/thrift_server.c0000664000175000017500000001652215165535636025236 0ustar00buildbuild00000000000000/* * 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 "thrift_server.h" /* object properties */ enum _ThriftServerProperties { PROP_0, PROP_THRIFT_SERVER_PROCESSOR, PROP_THRIFT_SERVER_SERVER_TRANSPORT, PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY, PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY, PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY, PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY }; G_DEFINE_ABSTRACT_TYPE(ThriftServer, thrift_server, G_TYPE_OBJECT) void thrift_server_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftServer *server = THRIFT_SERVER (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SERVER_PROCESSOR: g_value_set_object (value, server->processor); break; case PROP_THRIFT_SERVER_SERVER_TRANSPORT: g_value_set_object (value, server->server_transport); break; case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY: g_value_set_object (value, server->input_transport_factory); break; case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY: g_value_set_object (value, server->output_transport_factory); break; case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY: g_value_set_object (value, server->input_protocol_factory); break; case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY: g_value_set_object (value, server->output_protocol_factory); break; } } void thrift_server_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftServer *server = THRIFT_SERVER (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SERVER_PROCESSOR: g_clear_object (&server->processor); server->processor = g_value_dup_object (value); break; case PROP_THRIFT_SERVER_SERVER_TRANSPORT: g_clear_object (&server->server_transport); server->server_transport = g_value_dup_object (value); break; case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY: g_clear_object (&server->input_transport_factory); server->input_transport_factory = g_value_dup_object (value); break; case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY: g_clear_object (&server->output_transport_factory); server->output_transport_factory = g_value_dup_object (value); break; case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY: g_clear_object (&server->input_protocol_factory); server->input_protocol_factory = g_value_dup_object (value); break; case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY: g_clear_object (&server->output_protocol_factory); server->output_protocol_factory = g_value_dup_object (value); break; } } gboolean thrift_server_serve (ThriftServer *server, GError **error) { return THRIFT_SERVER_GET_CLASS (server)->serve (server, error); } void thrift_server_stop (ThriftServer *server) { THRIFT_SERVER_GET_CLASS (server)->stop (server); } /* instance initializer for Thrift Server */ static void thrift_server_init (ThriftServer *server) { server->processor = NULL; server->server_transport = NULL; server->input_transport_factory = NULL; server->output_transport_factory = NULL; server->input_protocol_factory = NULL; server->output_protocol_factory = NULL; } static void thrift_server_dispose (GObject *gobject) { ThriftServer *self = THRIFT_SERVER (gobject); g_clear_object(&self->output_protocol_factory); g_clear_object(&self->input_protocol_factory); g_clear_object(&self->output_transport_factory); g_clear_object(&self->input_transport_factory); g_clear_object(&self->server_transport); g_clear_object(&self->processor); /* Always chain up to the parent class; there is no need to check if * the parent class implements the dispose() virtual function: it is * always guaranteed to do so */ G_OBJECT_CLASS (thrift_server_parent_class)->dispose(gobject); } /* * class initializer for ThriftServer * TODO: implement ServerEventHandler as a GClosure */ static void thrift_server_class_init (ThriftServerClass *cls) { GObjectClass *gobject_class = G_OBJECT_CLASS (cls); gobject_class->get_property = thrift_server_get_property; gobject_class->set_property = thrift_server_set_property; gobject_class->dispose = thrift_server_dispose; g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_PROCESSOR, g_param_spec_object ("processor", "Processor", "Thrift Processor", THRIFT_TYPE_PROCESSOR, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_SERVER_TRANSPORT, g_param_spec_object ("server_transport", "Server Transport", "Thrift Server Transport", THRIFT_TYPE_SERVER_TRANSPORT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY, g_param_spec_object ("input_transport_factory", "Input Transport Factory", "Thrift Server Input Transport Factory", THRIFT_TYPE_TRANSPORT_FACTORY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY, g_param_spec_object ("output_transport_factory", "Output Transport Factory", "Thrift Server Output Transport Factory", THRIFT_TYPE_TRANSPORT_FACTORY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY, g_param_spec_object ("input_protocol_factory", "Input Protocol Factory", "Thrift Server Input Protocol Factory", THRIFT_TYPE_PROTOCOL_FACTORY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY, g_param_spec_object ("output_protocol_factory", "Output Protocol Factory", "Thrift Server Output Protocol Factory", THRIFT_TYPE_PROTOCOL_FACTORY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /* set these as virtual methods to be implemented by a subclass */ cls->serve = thrift_server_serve; cls->stop = thrift_server_stop; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/server/thrift_server.h0000664000175000017500000000533715165535636025245 0ustar00buildbuild00000000000000/* * 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_SERVER_H #define _THRIFT_SERVER_H #include #include #include #include #include G_BEGIN_DECLS /*! \file thrift_server.h * \brief Abstract class for Thrift servers. */ /* type macros */ #define THRIFT_TYPE_SERVER (thrift_server_get_type ()) #define THRIFT_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SERVER, ThriftServer)) #define THRIFT_IS_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SERVER)) #define THRIFT_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SERVER, ThriftServerClass)) #define THRIFT_IS_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SERVER)) #define THRIFT_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SERVER, ThriftServerClass)) typedef struct _ThriftServer ThriftServer; /*! * Thrift Server object */ struct _ThriftServer { GObject parent; /* protected */ ThriftProcessor *processor; ThriftServerTransport *server_transport; ThriftTransportFactory *input_transport_factory; ThriftTransportFactory *output_transport_factory; ThriftProtocolFactory *input_protocol_factory; ThriftProtocolFactory *output_protocol_factory; }; typedef struct _ThriftServerClass ThriftServerClass; /*! * Thrift Server class */ struct _ThriftServerClass { GObjectClass parent; /* vtable */ gboolean (*serve) (ThriftServer *server, GError **error); void (*stop) (ThriftServer *server); }; /* used by THRIFT_TYPE_SERVER */ GType thrift_server_get_type (void); /*! * Processes the request. * \public \memberof ThriftServerClass */ gboolean thrift_server_serve (ThriftServer *server, GError **error); /*! * Stop handling requests. */ void thrift_server_stop (ThriftServer *server); G_END_DECLS #endif /* _THRIFT_SERVER_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/server/thrift_simple_server.h0000664000175000017500000000425115165535636026610 0ustar00buildbuild00000000000000/* * 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_SIMPLE_SERVER_H #define _THRIFT_SIMPLE_SERVER_H #include #include G_BEGIN_DECLS /*! \file thrift_simple_server.h * \brief A simple Thrift server, single-threaded. */ /* type macros */ #define THRIFT_TYPE_SIMPLE_SERVER (thrift_simple_server_get_type ()) #define THRIFT_SIMPLE_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SIMPLE_SERVER, ThriftSimpleServer)) #define THRIFT_IS_SIMPLE_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SIMPLE_SERVER)) #define THRIFT_SIMPLE_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c) THRIFT_TYPE_SIMPLE_SERVER, ThriftSimpleServerClass)) #define THRIFT_IS_SIMPLE_SERVER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SIMPLE_SERVER)) #define THRIFT_SIMPLE_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SIMPLE_SERVER, ThriftSimpleServerClass)) typedef struct _ThriftSimpleServer ThriftSimpleServer; /** * Thrift Simple Server instance. */ struct _ThriftSimpleServer { ThriftServer parent; /* private */ volatile gboolean running; }; typedef struct _ThriftSimpleServerClass ThriftSimpleServerClass; /** * Thrift Simple Server class. */ struct _ThriftSimpleServerClass { ThriftServerClass parent; }; /* used by THRIFT_TYPE_SIMPLE_SERVER */ GType thrift_simple_server_get_type (void); G_END_DECLS #endif /* _THRIFT_SIMPLE_SERVER_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift_struct.h0000664000175000017500000000427415165535636023754 0ustar00buildbuild00000000000000/* * 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_STRUCT_H #define THRIFT_STRUCT_H #include #include G_BEGIN_DECLS #define THRIFT_TYPE_STRUCT (thrift_struct_get_type ()) #define THRIFT_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_STRUCT, ThriftStruct)) #define THRIFT_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_STRUCT, ThriftStructClass)) #define THRIFT_IS_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_STRUCT)) #define THRIFT_IS_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_STRUCT)) #define THRIFT_STRUCT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_STRUCT, ThriftStructClass)) typedef struct _ThriftStruct ThriftStruct; /* struct */ struct _ThriftStruct { GObject parent; /* private */ }; typedef struct _ThriftStructClass ThriftStructClass; struct _ThriftStructClass { GObjectClass parent; /* public */ gint32 (*read) (ThriftStruct *object, ThriftProtocol *protocol, GError **error); gint32 (*write) (ThriftStruct *object, ThriftProtocol *protocol, GError **error); }; GType thrift_struct_get_type (void); gint32 thrift_struct_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error); gint32 thrift_struct_write (ThriftStruct *object, ThriftProtocol *protocol, GError **error); G_END_DECLS #endif thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/0000755000175000017500000000000015170007200022673 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.c0000664000175000017500000002136715165535636030103 0ustar00buildbuild00000000000000/* * 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 /* object properties */ enum _ThriftServerTransportProperties { PROP_0, PROP_THRIFT_SERVER_TRANSPORT_CONFIGURATION, PROP_THRIFT_SERVER_TRANSPORT_REMAINING_MESSAGE_SIZE, PROP_THRIFT_SERVER_TRANSPORT_KNOW_MESSAGE_SIZE }; G_DEFINE_ABSTRACT_TYPE(ThriftServerTransport, thrift_server_transport, G_TYPE_OBJECT) gboolean thrift_server_transport_updateKnownMessageSize(ThriftServerTransport *transport, glong size, GError **error) { gboolean boolean = TRUE; ThriftServerTransport *tst = THRIFT_SERVER_TRANSPORT (transport); ThriftServerTransportClass *tstc = THRIFT_SERVER_TRANSPORT_GET_CLASS (transport); glong consumed = tst->knowMessageSize_ - tst->remainingMessageSize_; if(!tstc->resetConsumedMessageSize (transport, size, error)) { boolean = FALSE; } if(!tstc->countConsumedMessageBytes (transport, consumed, error)) { boolean = FALSE; } return boolean; } gboolean thrift_server_transport_checkReadBytesAvailable(ThriftServerTransport *transport, glong numBytes, GError **error) { gboolean boolean = TRUE; ThriftServerTransport *tst = THRIFT_SERVER_TRANSPORT (transport); if(tst->remainingMessageSize_ < numBytes) { g_set_error(error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED, "MaxMessageSize reached"); boolean = FALSE; } return boolean; } gboolean thrift_server_transport_resetConsumedMessageSize(ThriftServerTransport *transport, glong newSize, GError **error) { ThriftServerTransport *tst = THRIFT_SERVER_TRANSPORT (transport); if(newSize < 0) { if(tst->configuration != NULL) { tst->knowMessageSize_ = tst->configuration->maxMessageSize_; tst->remainingMessageSize_ = tst->configuration->maxMessageSize_; } else { tst->knowMessageSize_ = DEFAULT_MAX_MESSAGE_SIZE; tst->remainingMessageSize_ = DEFAULT_MAX_MESSAGE_SIZE; } return TRUE; } /* update only: message size can shrink, but not grow */ if(newSize > tst->knowMessageSize_) { g_set_error(error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED, "MaxMessageSize reached"); return FALSE; } tst->knowMessageSize_ = newSize; tst->remainingMessageSize_ = newSize; return TRUE; } gboolean thrift_server_transport_countConsumedMessageBytes(ThriftServerTransport *transport, glong numBytes, GError **error) { ThriftServerTransport *tst = THRIFT_SERVER_TRANSPORT (transport); if(tst->remainingMessageSize_ > numBytes) { tst->remainingMessageSize_ -= numBytes; } else { tst->remainingMessageSize_ = 0; if(*error == NULL) { g_set_error(error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED, "MaxMessageSize reached"); } return FALSE; } return TRUE; } /* property accesor */ void thrift_server_transport_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftServerTransport *transport = THRIFT_SERVER_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SERVER_TRANSPORT_CONFIGURATION: g_value_set_object (value, transport->configuration); break; case PROP_THRIFT_SERVER_TRANSPORT_REMAINING_MESSAGE_SIZE: g_value_set_long (value, transport->remainingMessageSize_); break; case PROP_THRIFT_SERVER_TRANSPORT_KNOW_MESSAGE_SIZE: g_value_set_long (value, transport->knowMessageSize_); break; } } /* property mutator */ void thrift_server_transport_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftServerTransport *transport = THRIFT_SERVER_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SERVER_TRANSPORT_CONFIGURATION: transport->configuration = g_value_dup_object (value); break; case PROP_THRIFT_SERVER_TRANSPORT_REMAINING_MESSAGE_SIZE: transport->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_SERVER_TRANSPORT_KNOW_MESSAGE_SIZE: transport->knowMessageSize_ = g_value_get_long (value); break; } } /* base initializer for the server transport interface */ static void thrift_server_transport_class_init (ThriftServerTransportClass *c) { GObjectClass *gobject_class = G_OBJECT_CLASS (c); ThriftServerTransportClass *tstc = THRIFT_SERVER_TRANSPORT_CLASS (c); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_server_transport_get_property; gobject_class->set_property = thrift_server_transport_set_property; param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_TRANSPORT_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_TRANSPORT_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_TRANSPORT_KNOW_MESSAGE_SIZE, param_spec); c->listen = thrift_server_transport_listen; c->accept = thrift_server_transport_accept; c->close = thrift_server_transport_close; tstc->updateKnownMessageSize = thrift_server_transport_updateKnownMessageSize; tstc->checkReadBytesAvailable = thrift_server_transport_checkReadBytesAvailable; tstc->resetConsumedMessageSize = thrift_server_transport_resetConsumedMessageSize; tstc->countConsumedMessageBytes = thrift_server_transport_countConsumedMessageBytes; } static void thrift_server_transport_init (ThriftServerTransport *transport) { THRIFT_UNUSED_VAR (transport); } gboolean thrift_server_transport_listen (ThriftServerTransport *transport, GError **error) { return THRIFT_SERVER_TRANSPORT_GET_CLASS (transport)->listen (transport, error); } ThriftTransport * thrift_server_transport_accept (ThriftServerTransport *transport, GError **error) { return THRIFT_SERVER_TRANSPORT_GET_CLASS (transport)->accept (transport, error); } gboolean thrift_server_transport_close (ThriftServerTransport *transport, GError **error) { return THRIFT_SERVER_TRANSPORT_GET_CLASS (transport)->close (transport, error); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h0000664000175000017500000001546415165535636026640 0ustar00buildbuild00000000000000/* * 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_SSL_SOCKET_H #define _THRIFT_SSL_SOCKET_H #include #include #include #include #include #include #include #include #include #include G_BEGIN_DECLS /*! \file thrift_ssl_socket.h * \brief SSL Socket implementation of a Thrift transport. Subclasses the * ThriftSocket class. Based on plain openssl. * In the future we should take a look to https://issues.apache.org/jira/browse/THRIFT-1016 */ /* type macros */ #define THRIFT_TYPE_SSL_SOCKET (thrift_ssl_socket_get_type ()) #define THRIFT_SSL_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SSL_SOCKET, ThriftSSLSocket)) #define THRIFT_IS_SSL_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SSL_SOCKET)) #define THRIFT_SSL_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SSL_SOCKET, ThriftSSLSocketClass)) #define THRIFT_IS_SSL_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SSL_SOCKET)) #define THRIFT_SSL_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SSL_SOCKET, ThriftSSLSocketClass)) /* define error/exception types */ typedef enum { THRIFT_SSL_SOCKET_ERROR_TRANSPORT=7, THRIFT_SSL_SOCKET_ERROR_CONNECT_BIND, THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE, THRIFT_SSL_SOCKET_ERROR_SSL, THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED } ThriftSSLSocketError; typedef struct _ThriftSSLSocket ThriftSSLSocket; /*! * Thrift SSL Socket instance. */ struct _ThriftSSLSocket { ThriftSocket parent; /* private */ SSL *ssl; SSL_CTX* ctx; gboolean server; gboolean allow_selfsigned; }; typedef struct _ThriftSSLSocketClass ThriftSSLSocketClass; typedef gboolean (* AUTHORIZATION_MANAGER_CALLBACK) (ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error); /*! * Thrift Socket class. */ struct _ThriftSSLSocketClass { ThriftSocketClass parent; gboolean (* handle_handshake) (ThriftTransport * transport, GError **error); gboolean (* create_ssl_context) (ThriftTransport * transport, GError **error); gboolean (* authorize_peer) (ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error); /* Padding to allow adding up to 12 new virtual functions without * breaking ABI. */ gpointer padding[12]; }; enum _ThriftSSLSocketProtocol { SSLTLS = 0, /* Supports SSLv2 and SSLv3 handshake but only negotiates at TLSv1_0 or later. */ /*SSLv2 = 1, HORRIBLY INSECURE! */ SSLv3 = 2, /* Supports SSLv3 only - also horribly insecure! */ TLSv1_0 = 3, /* Supports TLSv1_0 or later. */ TLSv1_1 = 4, /* Supports TLSv1_1 or later. */ TLSv1_2 = 5, /* Supports TLSv1_2 or later. */ LATEST = TLSv1_2 }; typedef enum _ThriftSSLSocketProtocol ThriftSSLSocketProtocol; /* Internal functions */ SSL_CTX* thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GError **error); /* used by THRIFT_TYPE_SSL_SOCKET */ GType thrift_ssl_socket_get_type (void); /* Public API */ /** * @brief Set a pinning manager instead of the default one. * * The pinning manager will be used during the SSL handshake to check certificate * and pinning parameters. * * @param ssl_socket SSL Socket to operate on. * @param callback function that will take the control while validating pinning * */ void thrift_ssl_socket_set_manager(ThriftSSLSocket *ssl_socket, AUTHORIZATION_MANAGER_CALLBACK callback); /* This is the SSL API */ /** * Convenience function to create a new SSL context with the protocol specified * and assign this new context to the created ThriftSSLSocket with specified host:port. * @param ssl_protocol * @param hostname * @param port * @param error * @return */ ThriftSSLSocket* thrift_ssl_socket_new_with_host(ThriftSSLSocketProtocol ssl_protocol, gchar *hostname, guint port, GError **error); /** * Convenience function to create a new SSL context with the protocol specified * and assign this new context to the created ThriftSSLSocket. * @param ssl_protocol * @param error * @return */ ThriftSSLSocket* thrift_ssl_socket_new(ThriftSSLSocketProtocol ssl_protocol, GError **error); /** * Load a certificate chain from a PEM file. * @param ssl_socket The ssl socket * @param file_name The file name of the PEM certificate chain * @return */ gboolean thrift_ssl_load_cert_from_file(ThriftSSLSocket *ssl_socket, const char *file_name); /** * Load a certificate chain from memory * @param ssl_socket the ssl socket * @param chain_certs the buffer to load PEM from * @return */ gboolean thrift_ssl_load_cert_from_buffer(ThriftSSLSocket *ssl_socket, const char chain_certs[]); /** * Check if the ssl socket is open and ready to send and receive * @param transport * @return true if open */ gboolean thrift_ssl_socket_is_open (ThriftTransport *transport); /** * Open connection if required and set the socket to be ready to send and receive * @param transport * @param error * @return true if operation was correct */ gboolean thrift_ssl_socket_open (ThriftTransport *transport, GError **error); /** * Close connection if required * @param transport * @param error * @return true if operation was correct */ gboolean thrift_ssl_socket_close (ThriftTransport *transport, GError **error); /** * @brief Initialization function * * It will initialize OpenSSL function. This initialization will be done app * wide. So if you want to initialize it by yourself you should not call it. * But it means you must handle OpenSSL initialization and handle locking. * * It should be called before anything else. * * */ void thrift_ssl_socket_initialize_openssl(void); /** * @brief Finalization function * * It clears all resources initialized in initialize function. * * It should be called after anything else. * * */ void thrift_ssl_socket_finalize_openssl(void); gboolean thrift_ssl_socket_authorize(ThriftTransport * transport, GError **error); G_END_DECLS #endif thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h0000664000175000017500000001462615165535636026522 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_H #define _THRIFT_TRANSPORT_H #include #include G_BEGIN_DECLS /*! \file thrift_transport.h * \brief Abstract class for Thrift transports. * * An abstract class is used instead of an interface because: * - interfaces can't seem to be used as properties. ThriftProtocol has * a ThriftTransport as an object property. * - if a method needs to be added that all subclasses can use, a class * is necessary. */ /* type macros */ #define THRIFT_TYPE_TRANSPORT (thrift_transport_get_type ()) #define THRIFT_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_TRANSPORT, ThriftTransport)) #define THRIFT_IS_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_TRANSPORT)) #define THRIFT_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_TRANSPORT, ThriftTransportClass)) #define THRIFT_IS_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_TRANSPORT)) #define THRIFT_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_TRANSPORT, ThriftTransportClass)) typedef struct _ThriftTransport ThriftTransport; /*! * Thrift Protocol object */ struct _ThriftTransport { GObject parent; /* protected */ ThriftConfiguration *configuration; glong remainingMessageSize_; glong knowMessageSize_; }; typedef struct _ThriftTransportClass ThriftTransportClass; /*! * Thrift Transport class */ struct _ThriftTransportClass { GObjectClass parent; /* vtable */ gboolean (*is_open) (ThriftTransport *transport); gboolean (*peek) (ThriftTransport *transport, GError **error); gboolean (*open) (ThriftTransport *transport, GError **error); gboolean (*close) (ThriftTransport *transport, GError **error); gint32 (*read) (ThriftTransport *transport, gpointer buf, guint32 len, GError **error); gboolean (*read_end) (ThriftTransport *transport, GError **error); gboolean (*write) (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error); gboolean (*write_end) (ThriftTransport *transport, GError **error); gboolean (*flush) (ThriftTransport *transport, GError **error); gint32 (*read_all) (ThriftTransport *transport, gpointer buf, guint32 len, GError **error); gboolean (*updateKnownMessageSize) (ThriftTransport *transport, glong size, GError **error); gboolean (*checkReadBytesAvailable) (ThriftTransport *transport, glong numBytes, GError **error); gboolean (*resetConsumedMessageSize) (ThriftTransport *transport, glong newSize, GError **error); gboolean (*countConsumedMessageBytes) (ThriftTransport *transport, glong numBytes, GError **error); }; /* used by THRIFT_TYPE_TRANSPORT */ GType thrift_transport_get_type (void); /* virtual public methods */ /*! * Checks if this transport is opened. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_is_open (ThriftTransport *transport); /*! * Open the transport for reading and writing. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_open (ThriftTransport *transport, GError **error); /*! * Tests whether there is more data to read or if the remote side is still * open. By default this is true whenever the transport is open, but * implementations should add logic to test for this condition where possible * (i.e. on a socket). * * This is used by a server to check if it should listen for another request. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_peek (ThriftTransport *transport, GError **error); /*! * Close the transport. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_close (ThriftTransport *transport, GError **error); /*! * Read some data into the buffer buf. * \public \memberof ThriftTransportInterface */ gint32 thrift_transport_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error); /*! * Called when read is completed. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_read_end (ThriftTransport *transport, GError **error); /*! * Writes data from a buffer to the transport. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error); /*! * Called when write is completed. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_write_end (ThriftTransport *transport, GError **error); /*! * Flushes any pending data to be written. Typically used with buffered * transport mechanisms. * \public \memberof ThriftTransportInterface */ gboolean thrift_transport_flush (ThriftTransport *transport, GError **error); /*! * Read len bytes of data into the buffer buf. * \public \memberof ThriftTransportInterface */ gint32 thrift_transport_read_all (ThriftTransport *transport, gpointer buf, guint32 len, GError **error); /* define error/exception types */ typedef enum { THRIFT_TRANSPORT_ERROR_UNKNOWN, THRIFT_TRANSPORT_ERROR_HOST, THRIFT_TRANSPORT_ERROR_SOCKET, THRIFT_TRANSPORT_ERROR_CONNECT, THRIFT_TRANSPORT_ERROR_SEND, THRIFT_TRANSPORT_ERROR_RECEIVE, THRIFT_TRANSPORT_ERROR_CLOSE, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED } ThriftTransportError; /* define an error domain for GError to use */ GQuark thrift_transport_error_quark (void); #define THRIFT_TRANSPORT_ERROR (thrift_transport_error_quark ()) /* define macro for invalid socket */ #define THRIFT_INVALID_SOCKET (-1) G_END_DECLS #endif /* _THRIFT_TRANSPORT_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.h0000664000175000017500000000650315165535636031264 0ustar00buildbuild00000000000000/* * 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_ZLIB_TRANSPORT_FACTORY_H #define _THRIFT_ZLIB_TRANSPORT_FACTORY_H #include #include #include G_BEGIN_DECLS /*! \file thrift_zlib_transport_factory.h * \brief Wraps a transport with a ThriffZlibTransport. */ /* type macros */ #define THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY (thrift_zlib_transport_factory_get_type()) #define THRIFT_ZLIB_TRANSPORT_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY, \ ThriftZlibTransportFactory)) #define THRIFT_IS_ZLIB_TRANSPORT_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY)) #define THRIFT_ZLIB_TRANSPORT_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), \ THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY, \ ThriftZlibTransportFactoryClass)) #define THRIFT_IS_ZLIB_TRANSPORT_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), \ THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY) #define THRIFT_ZLIB_TRANSPORT_FACTORY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY, \ ThriftZlibTransportFactoryClass)) typedef struct _ThriftZlibTransportFactory ThriftZlibTransportFactory; /* Thrift Zlib-Transport Factory instance */ struct _ThriftZlibTransportFactory { ThriftTransportFactory parent; }; typedef struct _ThriftZlibTransportFactoryClass ThriftZlibTransportFactoryClass; /* Thrift Zlib-Transport Factory class */ struct _ThriftZlibTransportFactoryClass { ThriftTransportFactoryClass parent; /* vtable */ ThriftTransport *(*get_transport) (ThriftTransportFactory *factory, ThriftTransport *transport); }; /* USED BY THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY */ GType thrift_zlib_transport_factory_get_type (void); /* virtual public methods */ ThriftTransport * thrift_zlib_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport); G_END_DECLS #endif /* _THRIFT_ZLIB_TANSPORT_FACTORY_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.h0000664000175000017500000000523715165535636030247 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_FACTORY_H #define _THRIFT_TRANSPORT_FACTORY_H #include #include "thrift_transport.h" G_BEGIN_DECLS /*! \file thrift_transport_factory.h * \brief Base class for Thrift Transport Factories. Used by Thrift Servers * to obtain a client transport from an existing transport. The default * implementation simply clones the provided transport. */ /* type macros */ #define THRIFT_TYPE_TRANSPORT_FACTORY (thrift_transport_factory_get_type ()) #define THRIFT_TRANSPORT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_TRANSPORT_FACTORY, ThriftTransportFactory)) #define THRIFT_IS_TRANSPORT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_TRANSPORT_FACTORY)) #define THRIFT_TRANSPORT_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_TRANSPORT_FACTORY, ThriftTransportFactoryClass)) #define THRIFT_IS_TRANSPORT_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_TRANSPORT_FACTORY)) #define THRIFT_TRANSPORT_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_TRANSPORT_FACTORY, ThriftTransportFactoryClass)) typedef struct _ThriftTransportFactory ThriftTransportFactory; /* Thrift Transport Factory instance */ struct _ThriftTransportFactory { GObject parent; }; typedef struct _ThriftTransportFactoryClass ThriftTransportFactoryClass; /* Thrift Transport Factory class */ struct _ThriftTransportFactoryClass { GObjectClass parent; /* vtable */ ThriftTransport *(*get_transport) (ThriftTransportFactory *factory, ThriftTransport *transport); }; /* used by THRIFT_TYPE_TRANSPORT_FACTORY */ GType thrift_transport_factory_get_type (void); /* virtual public methods */ ThriftTransport *thrift_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport); G_END_DECLS #endif /* _THRIFT_TRANSPORT_FACTORY_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h0000664000175000017500000001020415165535636027646 0ustar00buildbuild00000000000000/* * 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. */ /* clang-format off */ #ifndef _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ # define _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ #ifdef _WIN32 # define THRIFT_GET_SOCKET_ERROR ::WSAGetLastError() # define THRIFT_ERRNO (*_errno()) # define THRIFT_EINPROGRESS WSAEINPROGRESS # define THRIFT_EAGAIN WSAEWOULDBLOCK # define THRIFT_EINTR WSAEINTR # define THRIFT_ECONNRESET WSAECONNRESET # define THRIFT_ENOTCONN WSAENOTCONN # define THRIFT_ETIMEDOUT WSAETIMEDOUT # define THRIFT_EWOULDBLOCK WSAEWOULDBLOCK # define THRIFT_EPIPE WSAECONNRESET # define THRIFT_NO_SOCKET_CACHING SO_EXCLUSIVEADDRUSE # define THRIFT_INVALID_SOCKET INVALID_SOCKET # define THRIFT_SOCKETPAIR thrift_socketpair # define THRIFT_FCNTL thrift_fcntl # define THRIFT_O_NONBLOCK 1 # define THRIFT_F_GETFL 0 # define THRIFT_F_SETFL 1 # define THRIFT_GETTIMEOFDAY thrift_gettimeofday # define THRIFT_CLOSESOCKET closesocket # define THRIFT_CLOSE _close # define THRIFT_OPEN _open # define THRIFT_FTRUNCATE _chsize_s # define THRIFT_FSYNC _commit # define THRIFT_LSEEK _lseek # define THRIFT_WRITE _write # define THRIFT_READ _read # define THRIFT_FSTAT _fstat # define THRIFT_STAT _stat # ifdef _WIN32_WCE # define THRIFT_GAI_STRERROR(...) thrift_wstr2str(gai_strerrorW(__VA_ARGS__)) # else # define THRIFT_GAI_STRERROR gai_strerrorA # endif # define THRIFT_SSIZET ptrdiff_t # define THRIFT_SNPRINTF _snprintf # define THRIFT_SLEEP_SEC thrift_sleep # define THRIFT_SLEEP_USEC thrift_usleep # define THRIFT_TIMESPEC thrift_timespec # define THRIFT_CTIME_R thrift_ctime_r # define THRIFT_POLL thrift_poll # if WINVER <= 0x0502 /* XP, Server2003 */ # define THRIFT_POLLFD thrift_pollfd # define THRIFT_POLLIN 0x0300 # define THRIFT_POLLOUT 0x0010 # else /* Vista, Win7... */ # define THRIFT_POLLFD pollfd # define THRIFT_POLLIN POLLIN # define THRIFT_POLLOUT POLLOUT # endif /* WINVER */ # define THRIFT_SHUT_RDWR SD_BOTH #else /* not _WIN32 */ # include # define THRIFT_GET_SOCKET_ERROR errno # define THRIFT_ERRNO errno # define THRIFT_EINTR EINTR # define THRIFT_EINPROGRESS EINPROGRESS # define THRIFT_ECONNRESET ECONNRESET # define THRIFT_ENOTCONN ENOTCONN # define THRIFT_ETIMEDOUT ETIMEDOUT # define THRIFT_EWOULDBLOCK EWOULDBLOCK # define THRIFT_EAGAIN EAGAIN # define THRIFT_EPIPE EPIPE # define THRIFT_NO_SOCKET_CACHING SO_REUSEADDR # define THRIFT_INVALID_SOCKET (-1) # define THRIFT_SOCKETPAIR socketpair # define THRIFT_FCNTL fcntl # define THRIFT_O_NONBLOCK O_NONBLOCK # define THRIFT_F_GETFL F_GETFL # define THRIFT_F_SETFL F_SETFL # define THRIFT_GETTIMEOFDAY gettimeofday # define THRIFT_CLOSESOCKET close # define THRIFT_CLOSE close # define THRIFT_OPEN open # define THRIFT_FTRUNCATE ftruncate # define THRIFT_FSYNC fsync # define THRIFT_LSEEK lseek # define THRIFT_WRITE write # define THRIFT_READ read # define THRIFT_STAT stat # define THRIFT_FSTAT fstat # define THRIFT_GAI_STRERROR gai_strerror # define THRIFT_SSIZET ssize_t # define THRIFT_SNPRINTF snprintf # define THRIFT_SLEEP_SEC sleep # define THRIFT_SLEEP_USEC usleep # define THRIFT_TIMESPEC timespec # define THRIFT_CTIME_R ctime_r # define THRIFT_POLL poll # define THRIFT_POLLFD pollfd # define THRIFT_POLLIN POLLIN # define THRIFT_POLLOUT POLLOUT # define THRIFT_SHUT_RDWR SHUT_RDWR #endif #endif /* _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.h0000664000175000017500000000427215165535636027167 0ustar00buildbuild00000000000000/* * 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_FD_TRANSPORT_H #define _THRIFT_FD_TRANSPORT_H #include #include "thrift_transport.h" G_BEGIN_DECLS /*! \file thrift_fd_transport.h * \brief Class for Thrift file descriptor transports. */ /* type macros */ #define THRIFT_TYPE_FD_TRANSPORT (thrift_fd_transport_get_type ()) #define THRIFT_FD_TRANSPORT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_FD_TRANSPORT, \ ThriftFDTransport)) #define THRIFT_IS_FD_TRANSPORT(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_FD_TRANSPORT)) #define THRIFT_FD_TRANSPORT_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_FD_TRANSPORT, \ ThriftFDTransportClass)) #define THRIFT_IS_FD_TRANSPORT_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_FD_TRANSPORT)) #define THRIFT_FD_TRANSPORT_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_FD_TRANSPORT, \ ThriftFDTransportClass)) typedef struct _ThriftFDTransport ThriftFDTransport; struct _ThriftFDTransport { ThriftTransport parent; /* protected */ gint fd; }; typedef struct _ThriftFDTransportClass ThriftFDTransportClass; /*! * Thrift Transport class */ struct _ThriftFDTransportClass { ThriftTransportClass parent; }; /* used by THRIFT_TYPE_FD_TRANSPORT */ GType thrift_fd_transport_get_type (void); G_END_DECLS #endif /* _THRIFT_FD_TRANSPORT_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h0000664000175000017500000000466315165535636030040 0ustar00buildbuild00000000000000/* * 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_FRAMED_TRANSPORT_H #define _THRIFT_FRAMED_TRANSPORT_H #include #include #include G_BEGIN_DECLS /*! \file thrift_framed_transport.h * \brief Implementation of a Thrift framed transport. Subclasses * the ThriftTransport class. */ /* type macros */ #define THRIFT_TYPE_FRAMED_TRANSPORT (thrift_framed_transport_get_type ()) #define THRIFT_FRAMED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransport)) #define THRIFT_IS_FRAMED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_FRAMED_TRANSPORT)) #define THRIFT_FRAMED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransportClass)) #define THRIFT_IS_FRAMED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_FRAMED_TRANSPORT)) #define THRIFT_FRAMED_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransportClass)) typedef struct _ThriftFramedTransport ThriftFramedTransport; /*! * ThriftFramedTransport instance. */ struct _ThriftFramedTransport { ThriftTransport parent; /* protected */ ThriftTransport *transport; /* private */ guint32 max_frame_size; GByteArray *r_buf; GByteArray *w_buf; guint32 r_buf_size; guint32 w_buf_size; }; typedef struct _ThriftFramedTransportClass ThriftFramedTransportClass; /*! * ThriftFramedTransport class. */ struct _ThriftFramedTransportClass { ThriftTransportClass parent; }; /* used by THRIFT_TYPE_FRAMED_TRANSPORT */ GType thrift_framed_transport_get_type (void); G_END_DECLS #endif thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.h0000664000175000017500000000537115165535636027341 0ustar00buildbuild00000000000000/* * 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_SERVER_SOCKET_H #define _THRIFT_SERVER_SOCKET_H #include #include "thrift_server_transport.h" G_BEGIN_DECLS /*! \file thrift_server_socket.h * \brief Socket implementation of a Thrift server transport. Implements the * ThriftServerTransport class. */ /* type macros */ #define THRIFT_TYPE_SERVER_SOCKET (thrift_server_socket_get_type ()) #define THRIFT_SERVER_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SERVER_SOCKET, ThriftServerSocket)) #define THRIFT_IS_SERVER_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SERVER_SOCKET)) #define THRIFT_SERVER_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SERVER_SOCKET, ThriftServerSocketClass)) #define THRIFT_IS_SERVER_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SERVER_SOCKET)) #define THRIFT_SERVER_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SERVER_SOCKET, ThriftServerSocketClass)) typedef struct _ThriftServerSocket ThriftServerSocket; /*! * Thrift ServerSocket instance. */ struct _ThriftServerSocket { ThriftServerTransport parent; /* private */ guint port; gchar *path; gshort backlog; int sd; guint8 *buf; guint32 buf_size; guint32 buf_len; }; typedef struct _ThriftServerSocketClass ThriftServerSocketClass; /*! * Thrift ServerSocket class. */ struct _ThriftServerSocketClass { ThriftServerTransportClass parent; }; /* used by THRIFT_TYPE_SERVER_SOCKET */ GType thrift_server_socket_get_type (void); /* define error/exception types */ typedef enum { THRIFT_SERVER_SOCKET_ERROR_SOCKET, THRIFT_SERVER_SOCKET_ERROR_SETSOCKOPT, THRIFT_SERVER_SOCKET_ERROR_BIND, THRIFT_SERVER_SOCKET_ERROR_LISTEN, THRIFT_SERVER_SOCKET_ERROR_ACCEPT, THRIFT_SERVER_SOCKET_ERROR_CLOSE } ThriftServerSocketError; /* define a error domain for GError to use */ GQuark thrift_server_socket_error_quark (void); #define THRIFT_SERVER_SOCKET_ERROR (thrift_server_socket_error_quark ()) G_END_DECLS #endif thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c0000664000175000017500000006512415167543515026626 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include #include #include #include #include #if defined(WIN32) #define MUTEX_TYPE HANDLE #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL) #define MUTEX_CLEANUP(x) CloseHandle(x) #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) #define MUTEX_UNLOCK(x) ReleaseMutex(x) #else #define MUTEX_TYPE pthread_mutex_t #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) #endif #define OPENSSL_VERSION_NO_THREAD_ID 0x10000000L /* object properties */ enum _ThriftSSLSocketProperties { PROP_THRIFT_SSL_SOCKET_CONTEXT = 3, PROP_THRIFT_SSL_SELF_SIGNED, PROP_THRIFT_SSL_SOCKET_CONFIGURATION, PROP_THRIFT_SSL_SOCKET_REMAINING_MESSAGE_SIZE, PROP_THRIFT_SSL_SOCKET_KNOW_MESSAGE_SIZE, }; /* To hold a global state management of openssl for all instances */ static gboolean thrift_ssl_socket_openssl_initialized=FALSE; /* This array will store all of the mutexes available to OpenSSL. */ static MUTEX_TYPE *thrift_ssl_socket_global_mutex_buf=NULL; gboolean thrift_ssl_socket_authorize(ThriftTransport * transport, GError **error); /** * OpenSSL uniq id function. * * @return thread id */ static unsigned long thrift_ssl_socket_static_id_function(void) { #if defined(WIN32) return GetCurrentThreadId(); #else return ((unsigned long) pthread_self()); #endif } static void thrift_ssl_socket_static_locking_callback(int mode, int n, const char* unk, int id) { THRIFT_UNUSED_VAR (unk); THRIFT_UNUSED_VAR (id); if (mode & CRYPTO_LOCK) MUTEX_LOCK(thrift_ssl_socket_global_mutex_buf[n]); else MUTEX_UNLOCK(thrift_ssl_socket_global_mutex_buf[n]); } static int thrift_ssl_socket_static_thread_setup(void) { int i; thrift_ssl_socket_global_mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); if (!thrift_ssl_socket_global_mutex_buf) return 0; for (i = 0; i < CRYPTO_num_locks( ); i++) MUTEX_SETUP(thrift_ssl_socket_global_mutex_buf[i]); CRYPTO_set_id_callback(thrift_ssl_socket_static_id_function); CRYPTO_set_locking_callback(thrift_ssl_socket_static_locking_callback); return 1; } static int thrift_ssl_socket_static_thread_cleanup(void) { int i; if (!thrift_ssl_socket_global_mutex_buf) return 0; CRYPTO_set_id_callback(NULL); CRYPTO_set_locking_callback(NULL); for (i = 0; i < CRYPTO_num_locks( ); i++) MUTEX_CLEANUP(thrift_ssl_socket_global_mutex_buf[i]); free(thrift_ssl_socket_global_mutex_buf); thrift_ssl_socket_global_mutex_buf = NULL; return 1; } /* static void* thrift_ssl_socket_dyn_lock_create_callback(const char* unk, int id) { g_print("We should create a lock\n"); return NULL; } static void thrift_ssl_socket_dyn_lock_callback(int mode, void* lock, const char* unk, int id) { if (lock != NULL) { if (mode & CRYPTO_LOCK) { g_printf("We should lock thread %d\n"); } else { g_printf("We should unlock thread %d\n"); } } } static void thrift_ssl_socket_dyn_lock_destroy_callback(void* lock, const char* unk, int id) { g_printf("We must destroy the lock\n"); } */ G_DEFINE_TYPE(ThriftSSLSocket, thrift_ssl_socket, THRIFT_TYPE_SOCKET) /** * When there's a thread context attached, we pass the SSL socket context so it * can check if the error is outside SSL, on I/O for example * @param socket * @param error_msg * @param thrift_error_no * @param ssl_error * @param error */ static void thrift_ssl_socket_get_ssl_error(ThriftSSLSocket *socket, const gchar *error_msg, guint thrift_error_no, int ssl_error, GError **error) { unsigned long error_code; GString *message = g_string_new (""); gboolean first_error = TRUE; int ssl_error_type = SSL_get_error(socket->ssl, ssl_error); if(ssl_error_type>0){ switch(ssl_error_type){ case SSL_ERROR_SSL: g_string_append_printf (message, "SSL %s: ", error_msg); while ((error_code = ERR_get_error()) != 0) { const char* reason = ERR_reason_error_string(error_code); if(reason!=NULL){ if(!first_error) { g_string_append (message, "\n\t"); } g_string_append_printf (message, "%lX(%s) -> %s", error_code, reason, SSL_state_string(socket->ssl)); first_error = FALSE; } } break; case SSL_ERROR_SYSCALL: g_string_append_printf (message, "%s: ", error_msg); g_string_append_printf (message, "%X -> %s", errno, strerror(errno)); break; case SSL_ERROR_WANT_READ: g_string_append_printf (message, "%s: ", error_msg); g_string_append_printf (message, "%X -> %s", ssl_error_type, "Error while reading from underlaying layer"); break; case SSL_ERROR_WANT_WRITE: g_string_append_printf (message, "%s: ", error_msg); g_string_append_printf (message, "%X -> %s", ssl_error_type, "Error while writting to underlaying layer"); break; } g_set_error (error, THRIFT_TRANSPORT_ERROR, thrift_error_no, "%s", message->str); } g_string_free (message, TRUE); } /** * For global SSL errors * @param error_msg * @param thrift_error_no * @param error */ static void thrift_ssl_socket_get_error(const gchar *error_msg, guint thrift_error_no, GError **error) { unsigned long error_code; while ((error_code = ERR_get_error()) != 0) { const char* reason = ERR_reason_error_string(error_code); if (reason == NULL) { g_set_error (error, THRIFT_TRANSPORT_ERROR, thrift_error_no, "SSL error %lX: %s", error_code, error_msg); }else{ g_set_error (error, THRIFT_TRANSPORT_ERROR, thrift_error_no, "SSL error %lX %s: %s", error_code,reason, error_msg); } } } /* implements thrift_transport_is_open */ gboolean thrift_ssl_socket_is_open (ThriftTransport *transport) { return thrift_socket_is_open(transport); } /* overrides thrift_transport_peek */ gboolean thrift_ssl_socket_peek (ThriftTransport *transport, GError **error) { gboolean retval = FALSE; ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport); if (thrift_ssl_socket_is_open (transport)) { int rc; gchar byte; rc = SSL_peek(ssl_socket->ssl, &byte, 1); if (rc < 0) { thrift_ssl_socket_get_ssl_error(ssl_socket, (const guchar*)"Check socket data", THRIFT_SSL_SOCKET_ERROR_SSL, rc, error); } if (rc == 0) { ERR_clear_error(); } retval = (rc > 0); } return retval; } /* implements thrift_transport_open */ gboolean thrift_ssl_socket_open (ThriftTransport *transport, GError **error) { ERR_clear_error(); if (!thrift_socket_open(transport, error)) { return FALSE; } if (!THRIFT_SSL_SOCKET_GET_CLASS(transport)->handle_handshake(transport, error)) { thrift_ssl_socket_close(transport, NULL); return FALSE; } return TRUE; } /* implements thrift_transport_close */ gboolean thrift_ssl_socket_close (ThriftTransport *transport, GError **error) { ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET(transport); if(ssl_socket!=NULL && ssl_socket->ssl) { SSL_shutdown(ssl_socket->ssl); SSL_free(ssl_socket->ssl); ssl_socket->ssl = NULL; ERR_remove_state(0); } return thrift_socket_close(transport, error); } /* implements thrift_transport_read */ gint32 thrift_ssl_socket_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { guint maxRecvRetries_ = 10; ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport); gint32 bytes = 0; guint retries = 0; ThriftSocket *socket = THRIFT_SOCKET (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->checkReadBytesAvailable (transport, len, error)) { return -1; } g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE); for (retries=0; retries < maxRecvRetries_; retries++) { bytes = SSL_read(ssl_socket->ssl, buf, len); if (bytes >= 0) break; int errno_copy = THRIFT_GET_SOCKET_ERROR; if (SSL_get_error(ssl_socket->ssl, bytes) == SSL_ERROR_SYSCALL) { if (ERR_get_error() == 0 && errno_copy == THRIFT_EINTR) { continue; } }else{ thrift_ssl_socket_get_ssl_error(ssl_socket, (const guchar*)"Receive error", THRIFT_SSL_SOCKET_ERROR_SSL, bytes, error); } return -1; } return bytes; } /* implements thrift_transport_read_end * called when write is complete. nothing to do on our end. */ gboolean thrift_ssl_socket_read_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_write */ gboolean thrift_ssl_socket_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport); gint ret = 0; guint sent = 0; ThriftSocket *socket = THRIFT_SOCKET (transport); g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE); while (sent < len) { ret = SSL_write (ssl_socket->ssl, (guint8 *)buf + sent, len - sent); if (ret < 0) { thrift_ssl_socket_get_ssl_error(ssl_socket, (const guchar*)"Send error", THRIFT_SSL_SOCKET_ERROR_SSL, ret, error); return FALSE; } sent += ret; } return sent==len; } /* implements thrift_transport_write_end * called when write is complete. nothing to do on our end. */ gboolean thrift_ssl_socket_write_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_flush * flush pending data. since we are not buffered, this is a no-op */ gboolean thrift_ssl_socket_flush (ThriftTransport *transport, GError **error) { ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport); ThriftSocket *socket = THRIFT_SOCKET (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->resetConsumedMessageSize(transport, -1, error)) { return FALSE; } g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE); BIO* bio = SSL_get_wbio(ssl_socket->ssl); if (bio == NULL) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "failed to flush, wbio returned null"); return FALSE; } if (BIO_flush(bio) != 1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "failed to flush it returned error"); return FALSE; } return TRUE; } gboolean thrift_ssl_socket_handle_handshake(ThriftTransport * transport, GError **error) { ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport); ThriftSocket *socket = THRIFT_SOCKET (transport); g_return_val_if_fail (thrift_transport_is_open (transport), FALSE); if(THRIFT_SSL_SOCKET_GET_CLASS(ssl_socket)->create_ssl_context(transport, error)){ /*Context created*/ SSL_set_fd(ssl_socket->ssl, socket->sd); int rc; if(ssl_socket->server){ rc = SSL_accept(ssl_socket->ssl); }else{ rc = SSL_connect(ssl_socket->ssl); } if (rc <= 0) { thrift_ssl_socket_get_ssl_error(ssl_socket, (const guchar*)"Error while connect/bind", THRIFT_SSL_SOCKET_ERROR_CONNECT_BIND, rc, error); return FALSE; } }else return FALSE; return thrift_ssl_socket_authorize(transport, error); } gboolean thrift_ssl_socket_create_ssl_context(ThriftTransport * transport, GError **error) { ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (transport); if(socket->ctx!=NULL){ if(socket->ssl!=NULL) { return TRUE; } socket->ssl = SSL_new(socket->ctx); if (socket->ssl == NULL) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_SSL_SOCKET_ERROR_TRANSPORT, "Unable to create default SSL context"); return FALSE; } } return TRUE; } gboolean thrift_ssl_load_cert_from_file(ThriftSSLSocket *ssl_socket, const char *file_name) { char error_buffer[255]; if (!thrift_ssl_socket_openssl_initialized) { g_error("OpenSSL is not initialized yet"); return FALSE; } int rc = SSL_CTX_load_verify_locations(ssl_socket->ctx, file_name, NULL); if (rc != 1) { /*verify authentication result*/ ERR_error_string_n(ERR_get_error(), error_buffer, 254); g_warning("Load of certificates failed: %s!", error_buffer); return FALSE; } return TRUE; } gboolean thrift_ssl_load_cert_from_buffer(ThriftSSLSocket *ssl_socket, const char chain_certs[]) { gboolean retval = FALSE; /* Load chain of certs*/ X509 *cacert=NULL; BIO *mem = BIO_new_mem_buf(chain_certs,strlen(chain_certs)); X509_STORE *cert_store = SSL_CTX_get_cert_store(ssl_socket->ctx); if(cert_store!=NULL){ int index = 0; while ((cacert = PEM_read_bio_X509(mem, NULL, 0, NULL))!=NULL) { if(cacert) { X509_STORE_add_cert(cert_store, cacert); X509_free(cacert); cacert=NULL; } /* Free immediately */ index++; } retval=TRUE; } BIO_free(mem); return retval; } gboolean thrift_ssl_socket_authorize(ThriftTransport * transport, GError **error) { ThriftSocket *socket = THRIFT_SOCKET (transport); ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport); ThriftSSLSocketClass *cls = THRIFT_SSL_SOCKET_GET_CLASS(ssl_socket); gboolean authorization_result = FALSE; if(cls!=NULL && ssl_socket->ssl!=NULL){ int rc = SSL_get_verify_result(ssl_socket->ssl); if (rc != X509_V_OK) { /* verify authentication result */ if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && ssl_socket->allow_selfsigned) { g_debug("The certificate is a self-signed certificate and configuration allows it"); } else { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED, "The certificate verification failed: %s (%d)", X509_verify_cert_error_string(rc), rc); return FALSE; } } X509* cert = SSL_get_peer_certificate(ssl_socket->ssl); if (cert == NULL) { if (SSL_get_verify_mode(ssl_socket->ssl) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED, "No certificate present. Are you connecting SSL server?"); return FALSE; } g_debug("No certificate required"); return TRUE; } /* certificate is present, since we don't support access manager we are done */ if (cls->authorize_peer == NULL) { X509_free(cert); g_debug("Certificate presented but we're not checking it"); return TRUE; } else { /* both certificate and access manager are present */ struct sockaddr_storage sa; socklen_t saLength = sizeof(struct sockaddr_storage); if (getpeername(socket->sd, (struct sockaddr*)&sa, &saLength) != 0) { sa.ss_family = AF_UNSPEC; } authorization_result = cls->authorize_peer(transport, cert, &sa, error); } if(cert != NULL) { X509_free(cert); } } return authorization_result; } /* initializes the instance */ static void thrift_ssl_socket_init (ThriftSSLSocket *socket) { GError *error = NULL; socket->ssl = NULL; socket->ctx = thrift_ssl_socket_context_initialize(SSLTLS, &error); if(socket->ctx == NULL) { g_info("The SSL context was not automatically initialized with protocol %d", SSLTLS); if(error!=NULL){ g_info("Reported reason %s", error->message); g_error_free (error); } } socket->server = FALSE; socket->allow_selfsigned = FALSE; } /* destructor */ static void thrift_ssl_socket_finalize (GObject *object) { ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (object); GError *error=NULL; if(socket!=NULL){ g_debug("Instance %p destroyed", (void *)socket); if(socket->ssl != NULL) { thrift_ssl_socket_close(THRIFT_TRANSPORT(object), &error); socket->ssl=NULL; } if(socket->ctx!=NULL){ g_debug("Freeing the context for the instance"); SSL_CTX_free(socket->ctx); socket->ctx=NULL; } } if (G_OBJECT_CLASS (thrift_ssl_socket_parent_class)->finalize) (*G_OBJECT_CLASS (thrift_ssl_socket_parent_class)->finalize) (object); } /* property accessor */ void thrift_ssl_socket_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SSL_SOCKET_CONTEXT: g_value_set_pointer (value, socket->ctx); break; case PROP_THRIFT_SSL_SOCKET_CONFIGURATION: g_value_set_object (value, tt->configuration); break; case PROP_THRIFT_SSL_SOCKET_REMAINING_MESSAGE_SIZE: g_value_set_long (value, tt->remainingMessageSize_); break; case PROP_THRIFT_SSL_SOCKET_KNOW_MESSAGE_SIZE: g_value_set_long (value, tt->knowMessageSize_); break; } } /* property mutator */ void thrift_ssl_socket_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftSSLSocket *socket = THRIFT_SSL_SOCKET (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SSL_SOCKET_CONTEXT: if(socket->ctx!=NULL){ g_debug("Freeing the context since we are setting a new one"); SSL_CTX_free(socket->ctx); } socket->ctx = g_value_get_pointer(value); /* We copy the context */ break; case PROP_THRIFT_SSL_SELF_SIGNED: socket->allow_selfsigned = g_value_get_boolean(value); break; case PROP_THRIFT_SSL_SOCKET_CONFIGURATION: tt->configuration = g_value_dup_object (value); break; case PROP_THRIFT_SSL_SOCKET_REMAINING_MESSAGE_SIZE: tt->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_SSL_SOCKET_KNOW_MESSAGE_SIZE: tt->knowMessageSize_ = g_value_get_long (value); break; default: g_warning("Trying to set property %i that doesn't exists!", property_id); /* thrift_socket_set_property(object, property_id, value, pspec); */ break; } } void thrift_ssl_socket_initialize_openssl(void) { if(thrift_ssl_socket_openssl_initialized){ return; } thrift_ssl_socket_openssl_initialized=TRUE; SSL_library_init(); ERR_load_crypto_strings(); SSL_load_error_strings(); ERR_load_BIO_strings(); /* Setup locking */ g_debug("We setup %d threads locks", thrift_ssl_socket_static_thread_setup()); /* dynamic locking CRYPTO_set_dynlock_create_callback(thrift_ssl_socket_dyn_lock_create_callback); CRYPTO_set_dynlock_lock_callback(thrift_ssl_socket_dyn_lock_callback); CRYPTO_set_dynlock_destroy_callback(thrift_ssl_socket_dyn_lock_destroy_callback); */ } void thrift_ssl_socket_finalize_openssl(void) { if (!thrift_ssl_socket_openssl_initialized) { return; } thrift_ssl_socket_openssl_initialized = FALSE; g_debug("We cleared %d threads locks", thrift_ssl_socket_static_thread_cleanup()); /* Not supported CRYPTO_set_locking_callback(NULL); CRYPTO_set_dynlock_create_callback(NULL); CRYPTO_set_dynlock_lock_callback(NULL); CRYPTO_set_dynlock_destroy_callback(NULL); */ ERR_free_strings(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); } /* initializes the class */ static void thrift_ssl_socket_class_init (ThriftSSLSocketClass *cls) { ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls); GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; g_debug("Initialization of ThriftSSLSocketClass"); /* setup accessors and mutators */ gobject_class->get_property = thrift_ssl_socket_get_property; gobject_class->set_property = thrift_ssl_socket_set_property; param_spec = g_param_spec_pointer ("ssl_context", "SSLContext", "Set the SSL context for handshake with the remote host", G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SSL_SOCKET_CONTEXT, param_spec); param_spec = g_param_spec_boolean ("ssl_accept_selfsigned", "Accept Self Signed", "Whether or not accept self signed certificate", FALSE, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SSL_SELF_SIGNED, param_spec); param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Set the conguration of the transport", THRIFT_TYPE_CONFIGURATION, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SSL_SOCKET_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SSL_SOCKET_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SSL_SOCKET_KNOW_MESSAGE_SIZE, param_spec); /* Class methods */ cls->handle_handshake = thrift_ssl_socket_handle_handshake; cls->create_ssl_context = thrift_ssl_socket_create_ssl_context; /* Override */ gobject_class->finalize = thrift_ssl_socket_finalize; ttc->is_open = thrift_ssl_socket_is_open; ttc->peek = thrift_ssl_socket_peek; ttc->open = thrift_ssl_socket_open; ttc->close = thrift_ssl_socket_close; ttc->read = thrift_ssl_socket_read; ttc->read_end = thrift_ssl_socket_read_end; ttc->write = thrift_ssl_socket_write; ttc->write_end = thrift_ssl_socket_write_end; ttc->flush = thrift_ssl_socket_flush; } /* * Public API */ ThriftSSLSocket* thrift_ssl_socket_new(ThriftSSLSocketProtocol ssl_protocol, GError **error) { ThriftSSLSocket *thriftSSLSocket = NULL; SSL_CTX *ssl_context = NULL; /* Create the context */ if((ssl_context=thrift_ssl_socket_context_initialize(ssl_protocol, error))==NULL){ g_warning("We cannot initialize context for protocol %d", ssl_protocol); return thriftSSLSocket; } /* FIXME if the protocol is different? */ thriftSSLSocket = g_object_new (THRIFT_TYPE_SSL_SOCKET, "ssl_context", ssl_context, NULL); return thriftSSLSocket; } ThriftSSLSocket* thrift_ssl_socket_new_with_host(ThriftSSLSocketProtocol ssl_protocol, gchar *hostname, guint port, GError **error) { ThriftSSLSocket *thriftSSLSocket = NULL; SSL_CTX *ssl_context = NULL; /* Create the context */ if((ssl_context=thrift_ssl_socket_context_initialize(ssl_protocol, error))==NULL){ /* FIXME Do error control */ return thriftSSLSocket; } /* FIXME if the protocol is different? */ thriftSSLSocket = g_object_new (THRIFT_TYPE_SSL_SOCKET, "ssl_context", ssl_context, "hostname", hostname, "port", port, NULL); return thriftSSLSocket; } void thrift_ssl_socket_set_manager(ThriftSSLSocket *ssl_socket, AUTHORIZATION_MANAGER_CALLBACK callback) { ThriftSSLSocketClass *sslSocketClass = THRIFT_SSL_SOCKET_GET_CLASS (ssl_socket); if(sslSocketClass){ sslSocketClass->authorize_peer = callback; } } SSL_CTX* thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GError **error) { SSL_CTX* context = NULL; switch(ssl_protocol){ case SSLTLS: context = SSL_CTX_new(SSLv23_method()); break; #ifndef OPENSSL_NO_SSL3 case SSLv3: context = SSL_CTX_new(SSLv3_method()); break; #endif case TLSv1_0: context = SSL_CTX_new(TLSv1_method()); break; case TLSv1_1: context = SSL_CTX_new(TLSv1_1_method()); break; case TLSv1_2: context = SSL_CTX_new(TLSv1_2_method()); break; default: g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE, "The SSL protocol is unknown for %d", ssl_protocol); return NULL; break; } if (context == NULL) { thrift_ssl_socket_get_error((const guchar*)"No cipher overlay", THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE, error); return NULL; } SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY); /* Disable horribly insecure SSLv2 and SSLv3 protocols but allow a handshake with older clients so they get a graceful denial. */ if (ssl_protocol == SSLTLS) { SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); /* THRIFT-3164 */ } return context; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.c0000664000175000017500000006504515165535636027536 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include #define DEFAULT_URBUF_SIZE 128 #define DEFAULT_CRBUF_SIZE 1024 #define DEFAULT_UWBUF_SIZE 128 #define DEFAULT_CWBUF_SIZE 1024 #define MIN_DIRECT_DEFLATE_SIZE 32 /* object properties */ enum _ThriftZlibTransportProperties { PROP_0, PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT, PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE, PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE, PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE, PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE, PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL, PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION, PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE, PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE }; G_DEFINE_TYPE (ThriftZlibTransport, thrift_zlib_transport, THRIFT_TYPE_TRANSPORT) /*! READING STRATEGY * We have two buffers for reading: one containing the compressed data (crbuf) * and one containing the uncompressed data (urbuf). When read is called, * we repeat the following steps until we have satisfied the request: * - Copy data from urbuf into the caller's buffer. * - If we had enough, return. * - If urbuf is empty, read some data into it from the underlying transport. * - Inflate data from crbuf into urbuf. * * In standalone object, we set input_end to true when inflate returns * Z_STREAM_END. This allows to make sure that a checksum was verified. */ int thrift_zlib_transport_read_avail (ThriftTransport *transport) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); return t->urbuf_size - t->rstream->avail_out - t->urpos; } /* overrides thrift_transport_is_open */ gboolean thrift_zlib_transport_is_open (ThriftTransport *transport) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); return (thrift_zlib_transport_read_avail (transport) > 0) || \ (t->rstream->avail_in > 0) || THRIFT_TRANSPORT_GET_CLASS (t->transport)->is_open (t->transport); } /* overrides thrift_transport_peek */ gboolean thrift_zlib_transport_peek (ThriftTransport *transport, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); return (thrift_zlib_transport_read_avail (transport) > 0) || \ (t->rstream->avail_in > 0) || THRIFT_TRANSPORT_GET_CLASS (t->transport)->peek (t->transport, error); } /* implements thrift_transport_open */ gboolean thrift_zlib_transport_open (ThriftTransport *transport, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->open (t->transport, error); } /* implements thrift_transport_close */ gboolean thrift_zlib_transport_close (ThriftTransport *transport, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->close (t->transport, error); } gint32 thrift_zlib_transport_read_from_zlib(ThriftTransport *transport, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); gint32 got = 0; int zlib_rv = Z_OK; if (t->input_ended) { /* If input end return error */ return -1; } /* If we don't have any more compressed data available, * read some from the underlying transport. */ got = THRIFT_TRANSPORT_GET_CLASS(t->transport)->read (t->transport, t->crbuf, 1, error); if (got < 0) { return -1; } t->rstream->next_in = t->crbuf; t->rstream->avail_in = got; /* We have some compressed data now. Uncompress it. */ zlib_rv = inflate (t->rstream, Z_SYNC_FLUSH); if (zlib_rv == Z_STREAM_END) { t->input_ended = TRUE; inflateEnd(t->rstream); return 0; } else { if (zlib_rv != Z_OK) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "zlib error: %d (status = %s)", zlib_rv, t->rstream->msg); /* It must to return error */ return -1; } else { return 1; } } /* return 1 to continue to read */ return 1; } /* implements thrift_transport_read */ gint32 thrift_zlib_transport_read_slow (ThriftTransport *transport, gpointer buf, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); gint *buf_tmp = buf; gint32 need = 1; gint give; gint32 ret = 0; while(TRUE) { if ((guint32)thrift_zlib_transport_read_avail (transport) < 1) { give = thrift_zlib_transport_read_avail (transport); } else { give = need; } memcpy (buf_tmp, t->urbuf+t->urpos, give); if (give > need) { need = 0; } else { need -= give; } buf_tmp += give; t->urpos += give; /* If they were satisfied, we are done. */ if (need == 0) { return 1; } /* If we will need to read from the underlying transport to get more data, * but we already have some data available, return it now. Reading from * the underlying transport may block, and read() is only allowed to block * when no data is available. */ if (need < 1 && t->rstream->avail_in == 0) { return give; } /* If we get to this point, we need to get some more data. */ /* If zlib has reported the end of a stream, we can't really do any more. */ if (t->input_ended) { return 1; } /* The uncompressed read buffer is empty, so reset the stream fields. */ t->rstream->next_out = t->urbuf; t->rstream->avail_out = t->urbuf_size; t->urpos = 0; /* Call inflate() to uncompress some more data. */ if ((ret = thrift_zlib_transport_read_from_zlib(transport, error)) == 0) { /* no data available from underlying transport */ return 1; } else { if (ret < 0) { return -1; } } } /* Okay. The read buffer should have whatever we can give it now. */ /* Loop back to the start and try to give some more. */ } gint32 thrift_zlib_transport_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); guint32 i; gint32 ret; if (!ttc->checkReadBytesAvailable (transport, len, error)){ return -1; } for (i=0; i < len; i=i+ret) { if ((ret = thrift_zlib_transport_read_slow (transport, ((char*)buf)+i, error)) < 0) { return ret; } if (t->input_ended) break; } return len; } /* implements thrift_transport_read_end * called when read is complete. nothing to do on our end. */ gboolean thrift_zlib_transport_read_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (error); THRIFT_UNUSED_VAR (transport); return TRUE; } gboolean thrift_zlib_transport_flush_to_zlib (ThriftTransport *transport, const gint8* buf, gint len, gint flush, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); t->wstream->next_in = (guchar*)buf; t->wstream->avail_in = len; while (TRUE) { if ((flush == Z_NO_FLUSH || flush == Z_BLOCK) && t->wstream->avail_in == 0) { break; } /* If our output buffer is full, flush to the underlying transport. */ if (t->wstream->avail_out == 0) { THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, t->cwbuf, t->cwbuf_size, error); t->wstream->next_out = t->cwbuf; t->wstream->avail_out = t->cwbuf_size; break; } int zlib_rv = deflate(t->wstream, flush); if (flush == Z_FINISH && zlib_rv == Z_STREAM_END) { if (t->wstream->avail_in != 0) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "wstream->avail_in != 0"); return FALSE; } deflateEnd(t->wstream); t->output_finished = TRUE; break; } if (zlib_rv != Z_OK) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "zlib error: %d (status = %s)", zlib_rv, t->wstream->msg); return FALSE; } if ((flush == Z_SYNC_FLUSH || flush == Z_FULL_FLUSH) && t->wstream->avail_in ==0 && t->wstream->avail_out != 0) { break; } } return TRUE; } /* implements thrift_transport_write * WRITING STRATEGY * We buffer up small writes before sending them to zlib, so our logic is: * - Is the write big? * - Send the buffer to zlib. * - Send this data to zlib. * - Is the write small? * - Is there insufficient space in the buffer for it? * - Send the buffer to zlib. * - Copy the data to the buffer. * * We have two buffers for writing also: the uncompressed buffer (mentioned * above) and the compressed buffer. When sending data to zlib we loop over * the following until the source (uncompressed buffer or big write) is empty: * - Is there no more space in the compressed buffer? * - Write the compressed buffer to the underkying transport. * - Deflate from the source into the compressed buffer. */ gboolean thrift_zlib_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); if (t->output_finished) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "write() called after write_end(): %s", strerror(errno)); return FALSE; } /* zlib's "deflate" function has enough logic in it that I think * we're better off (performance-wise) buffering up small writes. */ if (len > MIN_DIRECT_DEFLATE_SIZE) { if (!thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, Z_NO_FLUSH, error)) { return FALSE; } t->uwpos = 0; if (!thrift_zlib_transport_flush_to_zlib (transport, buf, len, Z_NO_FLUSH, error)) { return FALSE; } return TRUE; } else if (len > 0) { if ((guint32)(t->uwbuf_size - t->uwpos) < len) { if (!thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, Z_NO_FLUSH, error)) { return FALSE; } t->uwpos = 0; } memcpy (t->uwbuf + t->uwpos, buf, len); t->uwpos += len; return TRUE; } return FALSE; } gboolean thrift_zlib_transport_flush_to_transport (ThriftTransport *transport, gint flush, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); /* write pending data in uwbuf to zlib */ if (!thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, flush, error)) { return FALSE; } t->uwpos = 0; /* write all available data from zlib to the transport */ if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, t->cwbuf, (t->cwbuf_size - t->wstream->avail_out), error)) { return FALSE; } t->wstream->next_out = t->cwbuf; t->wstream->avail_out = t->cwbuf_size; /* flush the transport */ if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush(t->transport, error)) { return FALSE; } return TRUE; } /* implements thrift_transport_write_end * called when write is complete. nothing to do on our end. */ gboolean thrift_zlib_transport_write_end (ThriftTransport *transport, GError **error) { THRIFT_UNUSED_VAR (error); THRIFT_UNUSED_VAR (transport); return TRUE; } /* implements thrift_transport_flush */ gboolean thrift_zlib_transport_flush (ThriftTransport *transport, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if (t->output_finished) { return FALSE; } thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, Z_NO_FLUSH, error); t->uwpos = 0; if (t->wstream->avail_out < 6) { if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write(t->transport, t->cwbuf, t->cwbuf_size - t->wstream->avail_out, error)) { return FALSE; } t->wstream->next_out = t->cwbuf; t->wstream->avail_out = t->cwbuf_size; } if (!thrift_zlib_transport_flush_to_transport (transport, Z_FULL_FLUSH, error)) { return FALSE; } if (!ttc->resetConsumedMessageSize (transport, -1, error)) { return FALSE; } return TRUE; } gboolean thrift_zlib_transport_verify_checksum(ThriftTransport *transport, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); /* If zlib has already reported the end of the stream, * it has verified the checksum. */ if (t->input_ended) { return TRUE; } /* This should only be called when reading is complete. * If the caller still has unread data, throw an exception. */ if (thrift_zlib_transport_read_avail (transport) > 0) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "thrift_zlib_transport_verify_checksum() called bufore end of zlib stream."); return FALSE; } /* Reset the rsteam fields, in case avail_out is 0. * (Since thrift_zlib_transport_read_avail() is 0, we know there is no unread data in urbuf) */ t->rstream->next_out = t->urbuf; t->rstream->avail_out = t->urbuf_size; t->urpos = 0; /* Call inflate() * This will set the error if the checksum is bad. */ gboolean performed_inflate = thrift_zlib_transport_read_from_zlib (transport, error); if (!performed_inflate) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "checksum not available yet in thrift_zlib_transport_verify_checksum ()"); return FALSE; } /* If input_ended is TRUE now, the checksum has been verified */ if (t->input_ended) { return TRUE; } /* The caller invoked us before the actual end of the data stream */ if (t->rstream->avail_out < (guint)t->urbuf_size) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "rstream->avail_out >= urbuf_size"); return FALSE; } g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "thrift_zlib_transport_verify_checksum() called bufore end of zlib stream."); return FALSE; } gboolean thrift_zlib_transport_finish(ThriftTransport *transport, GError **error) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport); if (t->output_finished) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "finish() called more than once"); return FALSE; } if (!thrift_zlib_transport_flush_to_transport (transport, Z_FINISH, error)) { return FALSE; } return TRUE; } /* initializes the instance */ static void thrift_zlib_transport_init (ThriftZlibTransport *transport) { transport->transport = NULL; transport->urpos = 0; transport->uwpos = 0; transport->input_ended = FALSE; transport->output_finished = FALSE; transport->rstream = g_new0 (struct z_stream_s, 1); transport->wstream = g_new0 (struct z_stream_s, 1); transport->rstream->zalloc = Z_NULL; transport->wstream->zalloc = Z_NULL; transport->rstream->zfree = Z_NULL; transport->wstream->zfree = Z_NULL; transport->rstream->opaque = Z_NULL; transport->wstream->opaque = Z_NULL; transport->rstream->avail_in = 0; transport->wstream->avail_in = 0; } /* destructor */ static void thrift_zlib_transport_finalize (GObject *object) { ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (object); inflateEnd (t->rstream); deflateEnd (t->wstream); if (t->urbuf != NULL) { g_free (t->urbuf); } if (t->crbuf != NULL) { g_free (t->crbuf); } if (t->uwbuf != NULL) { g_free (t->uwbuf); } if (t->cwbuf != NULL) { g_free (t->cwbuf); } if (t->rstream != NULL) { g_free (t->rstream); } if (t->wstream != NULL) { g_free (t->wstream); } } /* property accessor */ void thrift_zlib_transport_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftZlibTransport *transport = NULL; ThriftTransport *tt = NULL; THRIFT_UNUSED_VAR (pspec); transport = THRIFT_ZLIB_TRANSPORT (object); tt = THRIFT_TRANSPORT (object); switch (property_id) { case PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT: g_value_set_object (value, transport->transport); break; case PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE: g_value_set_int (value, transport->urbuf_size); break; case PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE: g_value_set_int (value, transport->crbuf_size); break; case PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE: g_value_set_int (value, transport->uwbuf_size); break; case PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE: g_value_set_int (value, transport->cwbuf_size); break; case PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL: g_value_set_int (value, transport->comp_level); break; case PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION: g_value_set_object (value, tt->configuration); break; case PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE: g_value_set_long (value, tt->remainingMessageSize_); break; case PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE: g_value_set_long (value, tt->knowMessageSize_); break; default: break; } } /* property mutator */ void thrift_zlib_transport_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftZlibTransport *transport = NULL; ThriftTransport *tt = NULL; THRIFT_UNUSED_VAR (pspec); transport = THRIFT_ZLIB_TRANSPORT (object); tt = THRIFT_TRANSPORT (object); switch (property_id) { case PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT: transport->transport = g_value_get_object (value); break; case PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE: transport->urbuf_size = g_value_get_int (value); transport->urbuf = g_new0 (guint8, transport->urbuf_size); transport->rstream->next_out = transport->urbuf; transport->rstream->avail_out = transport->urbuf_size; break; case PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE: transport->crbuf_size = g_value_get_int (value); transport->crbuf = g_new0 (guint8, transport->crbuf_size); transport->rstream->next_in = transport->crbuf; break; case PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE: transport->uwbuf_size = g_value_get_int (value); transport->uwbuf = g_new0 (guint8, transport->uwbuf_size); transport->wstream->next_in = transport->uwbuf; break; case PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE: transport->cwbuf_size = g_value_get_int (value); transport->cwbuf = g_new0 (guint8, transport->cwbuf_size); transport->wstream->next_out = transport->cwbuf; transport->wstream->avail_out = transport->cwbuf_size; break; case PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL: transport->comp_level = g_value_get_int (value); if(inflateInit(transport->rstream) != Z_OK) { printf("inflate_init fail \n"); return; } if(deflateInit (transport->wstream, transport->comp_level) != Z_OK) { printf("deflate init fail\n"); return; } break; case PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION: tt->configuration = g_value_dup_object (value); break; case PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE: tt->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE: tt->knowMessageSize_ = g_value_get_long (value); break; default: break; } } /* initialize the class */ static void thrift_zlib_transport_class_init (ThriftZlibTransportClass *cls) { ThriftTransportClass *ttc; GObjectClass *gobject_class; GParamSpec *param_spec; ttc = THRIFT_TRANSPORT_CLASS (cls); gobject_class = G_OBJECT_CLASS (cls); param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_zlib_transport_get_property; gobject_class->set_property = thrift_zlib_transport_set_property; param_spec = g_param_spec_object ("transport", "transport (construct)", "Thrift transport", THRIFT_TYPE_TRANSPORT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT, param_spec); param_spec = g_param_spec_int ("urbuf_size", "urbuf_size (construct)", "Uncompressed buffer size for reading", 0, /* min */ G_MAXINT, /* max */ DEFAULT_URBUF_SIZE, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE, param_spec); param_spec = g_param_spec_int ("crbuf_size", "crbuf_size (construct)", "Compressed buffer size for reading", 0, /* min */ G_MAXINT, /* max */ DEFAULT_CRBUF_SIZE, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE, param_spec); param_spec = g_param_spec_int ("uwbuf_size", "uwbuf_size (construct)", "Uncompressed buffer size for writing", MIN_DIRECT_DEFLATE_SIZE, /* min */ G_MAXINT, /* max */ DEFAULT_UWBUF_SIZE, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE, param_spec); param_spec = g_param_spec_int ("cwbuf_size", "cwbuf_size (construct)", "Compressed buffer size of writing", 0, /* min */ G_MAXINT, /* max */ DEFAULT_CWBUF_SIZE, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE, param_spec); param_spec = g_param_spec_int ("comp_level", "comp_level (construct)", "Compression level (0=none[fast], 6=default, 9=max[slow])", Z_DEFAULT_COMPRESSION, /* min */ Z_BEST_COMPRESSION, /* max */ Z_DEFAULT_COMPRESSION, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL, param_spec); param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the size of the remaining message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the size of the know message", G_MININT, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE, param_spec); gobject_class->finalize = thrift_zlib_transport_finalize; ttc->is_open = thrift_zlib_transport_is_open; ttc->peek = thrift_zlib_transport_peek; ttc->open = thrift_zlib_transport_open; ttc->close = thrift_zlib_transport_close; ttc->read = thrift_zlib_transport_read; ttc->read_end = thrift_zlib_transport_read_end; ttc->write = thrift_zlib_transport_write; ttc->write_end = thrift_zlib_transport_write_end; ttc->flush = thrift_zlib_transport_flush; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c0000664000175000017500000003656415167543515025753 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include /* object properties */ enum _ThriftSocketProperties { PROP_0, PROP_THRIFT_SOCKET_HOSTNAME, PROP_THRIFT_SOCKET_PORT, PROP_THRIFT_SOCKET_PATH, PROP_THRIFT_SOCKET_CONFIGURATION, PROP_THRIFT_SOCKET_REMAINING_MESSAGE_SIZE, PROP_THRIFT_SOCKET_KNOW_MESSAGE_SIZE }; G_DEFINE_TYPE(ThriftSocket, thrift_socket, THRIFT_TYPE_TRANSPORT) static gboolean thrift_socket_path_fits_unix_addr (const gchar *path, GError **error) { const size_t path_len = strlen (path); const size_t sun_path_len = sizeof (((struct sockaddr_un *) 0)->sun_path); if (path_len >= sun_path_len) { if (error != NULL) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET, "unix socket path is too long (%zu bytes, max %zu)", path_len, sun_path_len - 1); } return FALSE; } return TRUE; } /* implements thrift_transport_is_open */ gboolean thrift_socket_is_open (ThriftTransport *transport) { ThriftSocket *socket = THRIFT_SOCKET (transport); return socket->sd != THRIFT_INVALID_SOCKET; } /* overrides thrift_transport_peek */ gboolean thrift_socket_peek (ThriftTransport *transport, GError **error) { gboolean result = FALSE; guint8 buf; int r; int errno_copy; ThriftSocket *socket = THRIFT_SOCKET (transport); if (thrift_socket_is_open (transport)) { r = recv (socket->sd, &buf, 1, MSG_PEEK); if (r == -1) { errno_copy = errno; #if defined __FreeBSD__ || defined __MACH__ /* FreeBSD returns -1 and ECONNRESET if the socket was closed by the other side */ if (errno_copy == ECONNRESET) { thrift_socket_close (transport, error); } else { #endif g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET, "failed to peek at socket - %s", strerror (errno_copy)); #if defined __FreeBSD__ || defined __MACH__ } #endif } else if (r > 0) { result = TRUE; } } return result; } /* implements thrift_transport_close */ gboolean thrift_socket_close (ThriftTransport *transport, GError **error) { ThriftSocket *socket = THRIFT_SOCKET (transport); if (close (socket->sd) == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CLOSE, "unable to close socket - %s", strerror(errno)); return FALSE; } socket->sd = THRIFT_INVALID_SOCKET; return TRUE; } /* implements thrift_transport_open */ gboolean thrift_socket_open (ThriftTransport *transport, GError **error) { struct hostent *hp = NULL; struct sockaddr_in pin; int err; int errno_copy; #if defined(HAVE_GETHOSTBYNAME_R) struct hostent he; char buf[1024]; #endif ThriftSocket *tsocket = THRIFT_SOCKET (transport); g_return_val_if_fail (tsocket->sd == THRIFT_INVALID_SOCKET, FALSE); if (tsocket->path) { if (!thrift_socket_path_fits_unix_addr (tsocket->path, error)) { return FALSE; } /* create a socket structure */ struct sockaddr_un pin; memset (&pin, 0, sizeof(pin)); pin.sun_family = AF_UNIX; memcpy(pin.sun_path, tsocket->path, strlen(tsocket->path) + 1); /* create the socket */ if ((tsocket->sd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET, "failed to create socket for path %s: - %s", tsocket->path, strerror(errno)); return FALSE; } /* open a connection */ if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1) { errno_copy = errno; thrift_socket_close(transport, NULL); g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT, "failed to connect to path %s: - %s", tsocket->path, strerror(errno_copy)); return FALSE; } return TRUE; } /* lookup the destination host */ #if defined(HAVE_GETHOSTBYNAME_R) if (gethostbyname_r (tsocket->hostname, &he, buf, 1024, &hp, &err) != 0 || hp == NULL) #else if ((hp = gethostbyname (tsocket->hostname)) == NULL && (err = h_errno)) #endif { /* host lookup failed, bail out with an error */ g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_HOST, "host lookup failed for %s:%d - %s", tsocket->hostname, tsocket->port, hstrerror (err)); return FALSE; } /* create a socket structure */ memset (&pin, 0, sizeof(pin)); pin.sin_family = AF_INET; pin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr_list[0]))->s_addr; pin.sin_port = htons (tsocket->port); /* create the socket */ if ((tsocket->sd = socket (AF_INET, SOCK_STREAM, 0)) == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET, "failed to create socket for host %s:%d - %s", tsocket->hostname, tsocket->port, strerror(errno)); return FALSE; } /* open a connection */ if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1) { errno_copy = errno; thrift_socket_close(transport, NULL); g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT, "failed to connect to host %s:%d - %s", tsocket->hostname, tsocket->port, strerror(errno_copy)); return FALSE; } return TRUE; } /* implements thrift_transport_read */ gint32 thrift_socket_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { gint ret = 0; guint got = 0; ThriftSocket *socket = THRIFT_SOCKET (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->checkReadBytesAvailable (transport, len, error)) { return -1; } while (got < len) { ret = recv (socket->sd, (guint8 *)buf + got, len-got, 0); if (ret <= 0) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "failed to read %d bytes - %s", len, strerror(errno)); return -1; } got += ret; } return got; } /* implements thrift_transport_read_end * called when write is complete. nothing to do on our end. */ gboolean thrift_socket_read_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_write */ gboolean thrift_socket_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { gint ret = 0; guint sent = 0; ThriftSocket *socket = THRIFT_SOCKET (transport); g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET, FALSE); while (sent < len) { ret = send (socket->sd, (guint8 *)buf + sent, len - sent, 0); if (ret < 0) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "failed to send %d bytes - %s", len, strerror(errno)); return FALSE; } sent += ret; } return TRUE; } /* implements thrift_transport_write_end * called when write is complete. nothing to do on our end. */ gboolean thrift_socket_write_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_flush * flush pending data. since we are not buffered, this is a no-op */ gboolean thrift_socket_flush (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* initializes the instance */ static void thrift_socket_init (ThriftSocket *socket) { socket->sd = THRIFT_INVALID_SOCKET; } /* destructor */ static void thrift_socket_finalize (GObject *object) { ThriftSocket *socket = THRIFT_SOCKET (object); if (socket->hostname != NULL) { g_free (socket->hostname); } socket->hostname = NULL; if (socket->path != NULL) { g_free (socket->path); } if (socket->sd != THRIFT_INVALID_SOCKET) { close (socket->sd); } socket->sd = THRIFT_INVALID_SOCKET; } /* property accessor */ void thrift_socket_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftSocket *socket = THRIFT_SOCKET (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SOCKET_HOSTNAME: g_value_set_string (value, socket->hostname); break; case PROP_THRIFT_SOCKET_PORT: g_value_set_uint (value, socket->port); break; case PROP_THRIFT_SOCKET_PATH: g_value_set_string (value, socket->path); break; case PROP_THRIFT_SOCKET_CONFIGURATION: g_value_set_object (value, tt->configuration); break; case PROP_THRIFT_SOCKET_REMAINING_MESSAGE_SIZE: g_value_set_long (value, tt->remainingMessageSize_); break; case PROP_THRIFT_SOCKET_KNOW_MESSAGE_SIZE: g_value_set_long (value, tt->knowMessageSize_); break; } } /* property mutator */ void thrift_socket_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftSocket *socket = THRIFT_SOCKET (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_SOCKET_HOSTNAME: if (socket->hostname) { g_free(socket->hostname); } socket->hostname = g_strdup (g_value_get_string (value)); break; case PROP_THRIFT_SOCKET_PORT: socket->port = g_value_get_uint (value); break; case PROP_THRIFT_SOCKET_PATH: if (socket->path) { g_free(socket->path); } socket->path = g_strdup (g_value_get_string (value)); break; case PROP_THRIFT_SOCKET_CONFIGURATION: tt->configuration = g_value_dup_object (value); break; case PROP_THRIFT_SOCKET_REMAINING_MESSAGE_SIZE: tt->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_SOCKET_KNOW_MESSAGE_SIZE: tt->knowMessageSize_ = g_value_get_long (value); } } /* initializes the class */ static void thrift_socket_class_init (ThriftSocketClass *cls) { ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls); GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_socket_get_property; gobject_class->set_property = thrift_socket_set_property; param_spec = g_param_spec_string ("hostname", "hostname (construct)", "Set the hostname of the remote host", "localhost", /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_HOSTNAME, param_spec); param_spec = g_param_spec_uint ("port", "port (construct)", "Set the port of the remote host", 0u, /* min */ 65535u, /* max */ 9090, /* default by convention */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_PORT, param_spec); param_spec = g_param_spec_string ("path", "path (construct)", "Set the path of the remote host", NULL, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_PATH, param_spec); param_spec = g_param_spec_object ("configuration", "configuration", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SOCKET_KNOW_MESSAGE_SIZE, param_spec); gobject_class->finalize = thrift_socket_finalize; ttc->is_open = thrift_socket_is_open; ttc->peek = thrift_socket_peek; ttc->open = thrift_socket_open; ttc->close = thrift_socket_close; ttc->read = thrift_socket_read; ttc->read_end = thrift_socket_read_end; ttc->write = thrift_socket_write; ttc->write_end = thrift_socket_write_end; ttc->flush = thrift_socket_flush; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h0000664000175000017500000000431415165535636027320 0ustar00buildbuild00000000000000/* * 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_MEMORY_BUFFER_H #define _THRIFT_MEMORY_BUFFER_H #include #include #include G_BEGIN_DECLS /*! \file thrift_memory_buffer.h * \brief Implementation of a Thrift memory buffer transport. */ /* type macros */ #define THRIFT_TYPE_MEMORY_BUFFER (thrift_memory_buffer_get_type ()) #define THRIFT_MEMORY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBuffer)) #define THRIFT_IS_MEMORY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MEMORY_BUFFER)) #define THRIFT_MEMORY_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBufferClass)) #define THRIFT_IS_MEMORY_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MEMORY_BUFFER)) #define THRIFT_MEMORY_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBufferClass)) typedef struct _ThriftMemoryBuffer ThriftMemoryBuffer; /*! * ThriftMemoryBuffer instance. */ struct _ThriftMemoryBuffer { ThriftTransport parent; /* private */ GByteArray *buf; guint32 buf_size; gboolean owner; }; typedef struct _ThriftMemoryBufferClass ThriftMemoryBufferClass; /*! * ThriftMemoryBuffer class. */ struct _ThriftMemoryBufferClass { ThriftTransportClass parent; }; /* used by THRIFT_TYPE_MEMORY_BUFFER */ GType thrift_memory_buffer_get_type (void); G_END_DECLS #endif thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_fd_transport.c0000664000175000017500000002416615165535636027166 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include /* object properties */ enum _ThriftFDTransportProperties { PROP_0, PROP_THRIFT_FD_TRANSPORT_FD, PROP_THRIFT_FD_TRANSPORT_CONFIGURATION, PROP_THRIFT_FD_TRANSPORT_REMAINING_MESSAGE_SIZE, PROP_THRIFT_FD_TRANSPORT_KNOW_MESSAGE_SIZE, }; G_DEFINE_TYPE (ThriftFDTransport, thrift_fd_transport, THRIFT_TYPE_TRANSPORT) /* implements thrift_transport_is_open */ gboolean thrift_fd_transport_is_open (ThriftTransport *transport) { ThriftFDTransport *t; t = THRIFT_FD_TRANSPORT (transport); return t->fd >= 0 && ! (fcntl (t->fd, F_GETFL) == -1 && errno == EBADF); } /* implements thrift_transport_open */ gboolean thrift_fd_transport_open (ThriftTransport *transport, GError **error) { THRIFT_UNUSED_VAR (error); return thrift_fd_transport_is_open (transport); } /* implements thrift_transport_close */ gboolean thrift_fd_transport_close (ThriftTransport *transport, GError **error) { ThriftFDTransport *t; t = THRIFT_FD_TRANSPORT (transport); #if GLIB_CHECK_VERSION (2, 36, 0) return g_close (t->fd, error); #else if (close (t->fd) == 0) { g_clear_error (error); return TRUE; } else { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CLOSE, strerror (errno)); return FALSE; } #endif } /* implements thrift_transport_read */ gint32 thrift_fd_transport_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftFDTransport *t; ssize_t n; t = THRIFT_FD_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->checkReadBytesAvailable(transport, len, error)) { return -1; } n = read (t->fd, (guint8 *) buf, len); if (n == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "Failed to read from fd: %s", strerror (errno)); return -1; } return n; } /* implements thrift_transport_read_end * called when write is complete. nothing to do on our end. */ gboolean thrift_fd_transport_read_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_write */ gboolean thrift_fd_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { ThriftFDTransport *t; guint8 *_buf; guint32 _len; ssize_t n; t = THRIFT_FD_TRANSPORT (transport); _buf = (guint8 *) buf; _len = len; while (_len > 0) { n = write (t->fd, _buf, _len); if (n == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "Failed to write from fd: %s", strerror (errno)); return FALSE; } else { _buf += n; _len -= n; } } return TRUE; } /* implements thrift_transport_write_end * called when write is complete. nothing to do on our end. */ gboolean thrift_fd_transport_write_end (ThriftTransport *transport, GError **error) { THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_flush */ gboolean thrift_fd_transport_flush (ThriftTransport *transport, GError **error) { ThriftFDTransport *t; t = THRIFT_FD_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->resetConsumedMessageSize (transport, -1, error)) { return FALSE; } if (fsync (t->fd) == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_UNKNOWN, "Failed to flush fd: %s", strerror (errno)); return FALSE; } else { return TRUE; } } /* initializes the instance */ static void thrift_fd_transport_init (ThriftFDTransport *transport) { transport->fd = -1; } /* destructor */ static void thrift_fd_transport_finalize (GObject *object) { THRIFT_UNUSED_VAR (object); } /* property accessor */ void thrift_fd_transport_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftFDTransport *t; THRIFT_UNUSED_VAR (pspec); t = THRIFT_FD_TRANSPORT (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); switch (property_id) { case PROP_THRIFT_FD_TRANSPORT_FD: g_value_set_int (value, t->fd); break; case PROP_THRIFT_FD_TRANSPORT_CONFIGURATION: g_value_set_object (value, tt->configuration); break; case PROP_THRIFT_FD_TRANSPORT_REMAINING_MESSAGE_SIZE: g_value_set_long (value, tt->remainingMessageSize_); break; case PROP_THRIFT_FD_TRANSPORT_KNOW_MESSAGE_SIZE: g_value_set_long (value, tt->knowMessageSize_); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* property mutator */ void thrift_fd_transport_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftFDTransport *t; THRIFT_UNUSED_VAR (pspec); t = THRIFT_FD_TRANSPORT (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); switch (property_id) { case PROP_THRIFT_FD_TRANSPORT_FD: t->fd = g_value_get_int (value); break; case PROP_THRIFT_FD_TRANSPORT_CONFIGURATION: tt->configuration = g_value_dup_object (value); break; case PROP_THRIFT_FD_TRANSPORT_REMAINING_MESSAGE_SIZE: tt->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_FD_TRANSPORT_KNOW_MESSAGE_SIZE: tt->knowMessageSize_ = g_value_get_long (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* initializes the class */ static void thrift_fd_transport_class_init (ThriftFDTransportClass *cls) { ThriftTransportClass *ttc; GObjectClass *gobject_class; GParamSpec *param_spec; ttc = THRIFT_TRANSPORT_CLASS (cls); gobject_class = G_OBJECT_CLASS (cls); param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_fd_transport_get_property; gobject_class->set_property = thrift_fd_transport_set_property; param_spec = g_param_spec_int ("fd", "file descriptor (construct)", "Set the file descriptor", INT_MIN, /* min */ INT_MAX, /* max, 1024*1024 */ -1, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_FD_TRANSPORT_FD, param_spec); param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_FD_TRANSPORT_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_FD_TRANSPORT_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_FD_TRANSPORT_KNOW_MESSAGE_SIZE, param_spec); gobject_class->finalize = thrift_fd_transport_finalize; ttc->is_open = thrift_fd_transport_is_open; ttc->open = thrift_fd_transport_open; ttc->close = thrift_fd_transport_close; ttc->read = thrift_fd_transport_read; ttc->read_end = thrift_fd_transport_read_end; ttc->write = thrift_fd_transport_write; ttc->write_end = thrift_fd_transport_write_end; ttc->flush = thrift_fd_transport_flush; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h0000664000175000017500000000522115165535636025745 0ustar00buildbuild00000000000000/* * 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_SOCKET_H #define _THRIFT_SOCKET_H #include #include G_BEGIN_DECLS /*! \file thrift_socket.h * \brief Socket implementation of a Thrift transport. Subclasses the * ThriftTransport class. */ /* type macros */ #define THRIFT_TYPE_SOCKET (thrift_socket_get_type ()) #define THRIFT_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SOCKET, ThriftSocket)) #define THRIFT_IS_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SOCKET)) #define THRIFT_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SOCKET, ThriftSocketClass)) #define THRIFT_IS_SOCKET_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SOCKET)) #define THRIFT_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SOCKET, ThriftSocketClass)) typedef struct _ThriftSocket ThriftSocket; /*! * Thrift Socket instance. */ struct _ThriftSocket { ThriftTransport parent; /* private */ gchar *hostname; guint port; gchar *path; int sd; }; typedef struct _ThriftSocketClass ThriftSocketClass; /*! * Thrift Socket class. */ struct _ThriftSocketClass { ThriftTransportClass parent; }; /* used by THRIFT_TYPE_SOCKET */ GType thrift_socket_get_type (void); /** * Check if the socket is open and ready to send and receive * @param transport * @return true if open */ gboolean thrift_socket_is_open (ThriftTransport *transport); /** * Open connection if required and set the socket to be ready to send and receive * @param transport * @param error * @return true if operation was correct */ gboolean thrift_socket_open (ThriftTransport *transport, GError **error); /** * Close connection if required * @param transport * @param error * @return true if operation was correct */ gboolean thrift_socket_close (ThriftTransport *transport, GError **error); G_END_DECLS #endif thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.h0000664000175000017500000000574215165535636027541 0ustar00buildbuild00000000000000/* * 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_ZLIB_TRANSPORT_H #define _THRIFT_ZLIB_TRANSPORT_H #include #include #include #include "thrift_transport.h" G_BEGIN_DECLS /*! \file thrift_zlib_transport.h * \brief Class for Thrift file descriptor transports. */ /* type macros */ #define THRIFT_TYPE_ZLIB_TRANSPORT (thrift_zlib_transport_get_type ()) #define THRIFT_ZLIB_TRANSPORT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_ZLIB_TRANSPORT, \ ThriftZlibTransport)) #define THRIFT_IS_ZLIB_TRANSPORT(obj) \ (G_TYPE_CHECK_CLASS_TYPE ((obj), THRIFT_TYPE_ZLIB_TRANSPORT)) #define THRIFT_ZLIB_TRANSPORT_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_ZLIB_TRANSPORT, \ ThriftZlibTransportClass)) #define THRIFT_IS_ZLIB_TRANSPORT_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_ZLIB_TRANSPORT)) #define THRIFT_ZLIB_TRANSPORT_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_ZLIB_TRANSPORT, \ ThriftZlibTransportClass)) typedef struct _ThriftZlibTransport ThriftZlibTransport;\ struct _ThriftZlibTransport { ThriftTransport parent; /* protected */ ThriftTransport *transport; gint urbuf_size; gint crbuf_size; gint uwbuf_size; gint cwbuf_size; gint comp_level; ThriftConfiguration *configuration; glong remainingMessageSize_; glong knowMessageSize_; /* private */ gint urpos; gint uwpos; gboolean input_ended; /* TRUE iff zlib has reached the end of the input stream*/ gboolean output_finished; /* TRUE iff we have finished the ouput stream*/ guint8* urbuf; guint8* crbuf; guint8* uwbuf; guint8* cwbuf; struct z_stream_s* rstream; struct z_stream_s* wstream; }; typedef struct _ThriftZlibTransportClass ThriftZlibTransportClass; /*! * Thrift Transport class */ struct _ThriftZlibTransportClass { ThriftTransportClass parent; }; /* used by THRIFT_TYPE_ZLIB_TRANSPORT */ GType thrift_zlib_transport_get_type (void); gboolean thrift_zlib_transport_verify_checksum(ThriftTransport *transport, GError **error); gboolean thrift_zlib_transport_finish(ThriftTransport *transport, GError **error); G_END_DECLS #endif /* _THRIFT_ZLIB_TRANSPORT_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.h0000664000175000017500000000674715165535636032120 0ustar00buildbuild00000000000000/* * 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_BUFFERED_TRANSPORT_FACTORY_H #define _THRIFT_BUFFERED_TRANSPORT_FACTORY_H #include #include #include G_BEGIN_DECLS /*! \file thrift_buffered_transport_factory.h * \brief Wraps a transport with a ThriftBufferedTransport. */ /* type macros */ #define THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY \ (thrift_buffered_transport_factory_get_type ()) #define THRIFT_BUFFERED_TRANSPORT_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, \ ThriftBufferedTransportFactory)) #define THRIFT_IS_BUFFERED_TRANSPORT_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY)) #define THRIFT_BUFFERED_TRANSPORT_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), \ THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, \ ThriftBufferedTransportFactoryClass)) #define THRIFT_IS_BUFFERED_TRANSPORT_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), \ THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY)) #define THRIFT_BUFFERED_TRANSPORT_FACTORY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, \ ThriftBufferedTransportFactoryClass)) typedef struct _ThriftBufferedTransportFactory ThriftBufferedTransportFactory; /* Thrift Buffered-Transport Factory instance */ struct _ThriftBufferedTransportFactory { ThriftTransportFactory parent; }; typedef struct _ThriftBufferedTransportFactoryClass ThriftBufferedTransportFactoryClass; /* Thrift Buffered-Transport Factory class */ struct _ThriftBufferedTransportFactoryClass { ThriftTransportFactoryClass parent; /* vtable */ ThriftTransport *(*get_transport) (ThriftTransportFactory *factory, ThriftTransport *transport); }; /* used by THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY */ GType thrift_buffered_transport_factory_get_type (void); /* virtual public methods */ ThriftTransport * thrift_buffered_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport); G_END_DECLS #endif /* _THRIFT_BUFFERED_TRANSPORT_FACTORY_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c0000664000175000017500000003152215170007142027307 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include #include /* object properties */ enum _ThriftServerSocketProperties { PROP_0, PROP_THRIFT_SERVER_SOCKET_PORT, PROP_THRIFT_SERVER_SOCKET_PATH, PROP_THRIFT_SERVER_SOCKET_BACKLOG, PROP_THRIFT_SERVER_SOCKET_CONFIGURATION, PROP_THRIFT_SERVER_SOCKET_REMAINING_MESSAGE_SIZE, PROP_THRIFT_SERVER_SOCKET_KNOW_MESSAGE_SIZE }; /* define the GError domain string */ #define THRIFT_SERVER_SOCKET_ERROR_DOMAIN "thrift-server-socket-error-quark" G_DEFINE_TYPE(ThriftServerSocket, thrift_server_socket, THRIFT_TYPE_SERVER_TRANSPORT) gboolean thrift_server_socket_listen (ThriftServerTransport *transport, GError **error) { int enabled = 1; /* for setsockopt() */ ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport); const int socket_domain = tsocket->path ? PF_UNIX : AF_INET; /* create a socket */ if ((tsocket->sd = socket (socket_domain, SOCK_STREAM, 0)) == -1) { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_SOCKET, "failed to create socket - %s", strerror (errno)); return FALSE; } if (setsockopt(tsocket->sd, SOL_SOCKET, SO_REUSEADDR, &enabled, sizeof(enabled)) == -1) { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_SETSOCKOPT, "unable to set SO_REUSEADDR - %s", strerror(errno)); close (tsocket->sd); tsocket->sd = THRIFT_INVALID_SOCKET; return FALSE; } /* bind to the socket */ if (tsocket->path) { /* create a socket structure */ struct sockaddr_un pin; memset (&pin, 0, sizeof(pin)); pin.sun_family = AF_UNIX; memcpy(pin.sun_path, tsocket->path, strlen(tsocket->path) + 1); if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1) { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_BIND, "failed to bind to path %s: - %s", tsocket->path, strerror(errno)); close (tsocket->sd); tsocket->sd = THRIFT_INVALID_SOCKET; return FALSE; } } else { /* create a address structure */ struct sockaddr_in pin; memset (&pin, 0, sizeof(pin)); pin.sin_family = AF_INET; pin.sin_addr.s_addr = INADDR_ANY; pin.sin_port = htons(tsocket->port); if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1) { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_BIND, "failed to bind to port %d - %s", tsocket->port, strerror(errno)); close (tsocket->sd); tsocket->sd = THRIFT_INVALID_SOCKET; return FALSE; } } if (listen(tsocket->sd, tsocket->backlog) == -1) { if (tsocket->path) { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_BIND, "failed to listen to path %s: - %s", tsocket->path, strerror(errno)); } else { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_LISTEN, "failed to listen to port %d - %s", tsocket->port, strerror(errno)); } close (tsocket->sd); tsocket->sd = THRIFT_INVALID_SOCKET; return FALSE; } return TRUE; } ThriftTransport * thrift_server_socket_accept (ThriftServerTransport *transport, GError **error) { int sd = THRIFT_INVALID_SOCKET; guint addrlen = 0; struct sockaddr_in address; ThriftSocket *socket = NULL; ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport); ThriftServerTransport *tst = THRIFT_SERVER_TRANSPORT (transport); if ((sd = accept(tsocket->sd, (struct sockaddr *) &address, &addrlen)) == -1) { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_ACCEPT, "failed to accept connection - %s", strerror(errno)); return NULL; } if(tst->configuration != NULL) { socket = g_object_new (THRIFT_TYPE_SOCKET, "configuration", tst->configuration, "remainingmessagesize", tst->configuration->maxMessageSize_, "knowmessagesize", tst->configuration->maxMessageSize_, NULL); } else { socket = g_object_new (THRIFT_TYPE_SOCKET, NULL); } socket->sd = sd; return THRIFT_TRANSPORT(socket); } gboolean thrift_server_socket_close (ThriftServerTransport *transport, GError **error) { ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport); if (close (tsocket->sd) == -1) { g_set_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_CLOSE, "unable to close socket - %s", strerror(errno)); return FALSE; } tsocket->sd = THRIFT_INVALID_SOCKET; return TRUE; } /* define the GError domain for this implementation */ GQuark thrift_server_socket_error_quark (void) { return g_quark_from_static_string(THRIFT_SERVER_SOCKET_ERROR_DOMAIN); } /* initializes the instance */ static void thrift_server_socket_init (ThriftServerSocket *socket) { socket->sd = THRIFT_INVALID_SOCKET; } /* destructor */ static void thrift_server_socket_finalize (GObject *object) { ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object); if (socket->sd != THRIFT_INVALID_SOCKET) { close (socket->sd); } socket->sd = THRIFT_INVALID_SOCKET; } /* property accessor */ void thrift_server_socket_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object); ThriftServerTransport *transport = THRIFT_SERVER_TRANSPORT (object); switch (property_id) { case PROP_THRIFT_SERVER_SOCKET_PORT: g_value_set_uint (value, socket->port); break; case PROP_THRIFT_SERVER_SOCKET_PATH: g_value_set_string (value, socket->path); break; case PROP_THRIFT_SERVER_SOCKET_BACKLOG: g_value_set_uint (value, socket->backlog); break; case PROP_THRIFT_SERVER_SOCKET_CONFIGURATION: g_value_set_object (value, transport->configuration); break; case PROP_THRIFT_SERVER_SOCKET_REMAINING_MESSAGE_SIZE: g_value_set_long (value, transport->remainingMessageSize_); break; case PROP_THRIFT_SERVER_SOCKET_KNOW_MESSAGE_SIZE: g_value_set_long (value, transport->knowMessageSize_); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* property mutator */ void thrift_server_socket_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object); ThriftServerTransport *transport = THRIFT_SERVER_TRANSPORT (object); switch (property_id) { case PROP_THRIFT_SERVER_SOCKET_PORT: socket->port = g_value_get_uint (value); break; case PROP_THRIFT_SERVER_SOCKET_PATH: if (socket->path) { g_free(socket->path); } socket->path = g_strdup (g_value_get_string (value)); break; case PROP_THRIFT_SERVER_SOCKET_BACKLOG: socket->backlog = g_value_get_uint (value); break; case PROP_THRIFT_SERVER_SOCKET_CONFIGURATION: transport->configuration = g_value_dup_object (value); break; case PROP_THRIFT_SERVER_SOCKET_REMAINING_MESSAGE_SIZE: transport->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_SERVER_SOCKET_KNOW_MESSAGE_SIZE: transport->knowMessageSize_ = g_value_get_long (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* initializes the class */ static void thrift_server_socket_class_init (ThriftServerSocketClass *cls) { ThriftServerTransportClass *tstc = THRIFT_SERVER_TRANSPORT_CLASS (cls); GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_server_socket_get_property; gobject_class->set_property = thrift_server_socket_set_property; param_spec = g_param_spec_uint ("port", "port (construct)", "Set the port to listen to", 0, /* min */ 65535, /* max */ 9090, /* default by convention */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_SOCKET_PORT, param_spec); param_spec = g_param_spec_string ("path", "path (construct)", "Set the path to listen to", NULL, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_SOCKET_PATH, param_spec); param_spec = g_param_spec_uint ("backlog", "backlog (construct)", "Set the accept backlog", 0, /* max */ 65534, /* max */ 1024, /* default */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_SOCKET_BACKLOG, param_spec); param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thtift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_SOCKET_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_SOCKET_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_SERVER_SOCKET_KNOW_MESSAGE_SIZE, param_spec); gobject_class->finalize = thrift_server_socket_finalize; tstc->listen = thrift_server_socket_listen; tstc->accept = thrift_server_socket_accept; tstc->close = thrift_server_socket_close; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport_factory.c0000664000175000017500000000372315165535636032102 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_TYPE (ThriftBufferedTransportFactory, thrift_buffered_transport_factory, THRIFT_TYPE_TRANSPORT_FACTORY) /* Wraps a transport with a ThriftBufferedTransport. */ ThriftTransport * thrift_buffered_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport) { THRIFT_UNUSED_VAR (factory); return THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", transport, NULL)); } static void thrift_buffered_transport_factory_init (ThriftBufferedTransportFactory *self) { THRIFT_UNUSED_VAR (self); } static void thrift_buffered_transport_factory_class_init (ThriftBufferedTransportFactoryClass *klass) { ThriftTransportFactoryClass *base_class = THRIFT_TRANSPORT_FACTORY_CLASS (klass); base_class->get_transport = klass->get_transport = thrift_buffered_transport_factory_get_transport; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.c0000664000175000017500000002703515165535636027320 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include /* object properties */ enum _ThriftMemoryBufferProperties { PROP_0, PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE, PROP_THRIFT_MEMORY_BUFFER_BUFFER, PROP_THRIFT_MEMORY_BUFFER_OWNER, PROP_THRIFT_MEMORY_BUFFER_CONFIGURATION, PROP_THRIFT_MEMORY_BUFFER_REMAINING_MESSAGE_SIZE, PROP_THRIFT_MEMORY_BUFFER_KNOW_MESSAGE_SIZE }; G_DEFINE_TYPE(ThriftMemoryBuffer, thrift_memory_buffer, THRIFT_TYPE_TRANSPORT) /* implements thrift_transport_is_open */ gboolean thrift_memory_buffer_is_open (ThriftTransport *transport) { THRIFT_UNUSED_VAR (transport); return TRUE; } /* implements thrift_transport_open */ gboolean thrift_memory_buffer_open (ThriftTransport *transport, GError **error) { THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_close */ gboolean thrift_memory_buffer_close (ThriftTransport *transport, GError **error) { THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_read */ gint32 thrift_memory_buffer_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); guint32 give = len; if(!ttc->checkReadBytesAvailable (transport, len, error)) { return -1; } /* if the requested bytes are more than what we have available, * just give all that we have the buffer */ if (t->buf->len < len) { give = t->buf->len; } if (give == 0) { return -1; } memcpy (buf, t->buf->data, give); g_byte_array_remove_range (t->buf, 0, give); return give; } /* implements thrift_transport_read_end * called when read is complete. nothing to do on our end. */ gboolean thrift_memory_buffer_read_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_write */ gboolean thrift_memory_buffer_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (transport); THRIFT_UNUSED_VAR (error); /* return an exception if the buffer doesn't have enough space. */ if (len > t->buf_size - t->buf->len) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "unable to write %d bytes to buffer of length %d", len, t->buf_size); return FALSE; } else { t->buf = g_byte_array_append (t->buf, buf, len); return TRUE; } } /* implements thrift_transport_write_end * called when write is complete. nothing to do on our end. */ gboolean thrift_memory_buffer_write_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_flush */ gboolean thrift_memory_buffer_flush (ThriftTransport *transport, GError **error) { THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* initializes class before constructor properties are set */ static void thrift_memory_buffer_init (ThriftMemoryBuffer *t) { THRIFT_UNUSED_VAR (t); } /* destructor */ static void thrift_memory_buffer_finalize (GObject *object) { ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); if (t->owner && t->buf != NULL) { g_byte_array_unref (t->buf); } t->buf = NULL; } /* property accessor */ void thrift_memory_buffer_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE: g_value_set_uint (value, t->buf_size); break; case PROP_THRIFT_MEMORY_BUFFER_BUFFER: g_value_set_pointer (value, (gpointer) (t->buf)); break; case PROP_THRIFT_MEMORY_BUFFER_OWNER: g_value_set_boolean (value, t->owner); break; case PROP_THRIFT_MEMORY_BUFFER_CONFIGURATION: g_value_set_object (value, tt->configuration); break; case PROP_THRIFT_MEMORY_BUFFER_REMAINING_MESSAGE_SIZE: g_value_set_long (value, tt->remainingMessageSize_); break; case PROP_THRIFT_MEMORY_BUFFER_KNOW_MESSAGE_SIZE: g_value_set_long (value, tt->knowMessageSize_); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* property mutator */ void thrift_memory_buffer_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE: t->buf_size = g_value_get_uint (value); break; case PROP_THRIFT_MEMORY_BUFFER_BUFFER: t->buf = (GByteArray*) g_value_get_pointer (value); break; case PROP_THRIFT_MEMORY_BUFFER_OWNER: t->owner = g_value_get_boolean (value); break; case PROP_THRIFT_MEMORY_BUFFER_CONFIGURATION: tt->configuration = g_value_dup_object (value); break; case PROP_THRIFT_MEMORY_BUFFER_REMAINING_MESSAGE_SIZE: tt->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_MEMORY_BUFFER_KNOW_MESSAGE_SIZE: tt->knowMessageSize_ = g_value_get_long (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* initializes class after constructor properties are set */ static void thrift_memory_buffer_constructed (GObject *object) { ThriftMemoryBuffer *t = THRIFT_MEMORY_BUFFER (object); if (t->buf == NULL) { t->buf = g_byte_array_new (); } G_OBJECT_CLASS (thrift_memory_buffer_parent_class)->constructed (object); } /* initializes the class */ static void thrift_memory_buffer_class_init (ThriftMemoryBufferClass *cls) { ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls); GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_memory_buffer_get_property; gobject_class->set_property = thrift_memory_buffer_set_property; param_spec = g_param_spec_uint ("buf_size", "buffer size (construct)", "Set the read/write buffer size limit", 0, /* min */ G_MAXUINT32, /* max */ G_MAXUINT32, /* default */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE, param_spec); param_spec = g_param_spec_pointer ("buf", "internal buffer (GByteArray)", "Set the internal buffer (GByteArray)", G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_MEMORY_BUFFER_BUFFER, param_spec); param_spec = g_param_spec_boolean ("owner", "internal buffer memory management policy", "Set whether internal buffer should be" " unreferenced when thrift_memory_buffer" " is finalized", TRUE, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_MEMORY_BUFFER_OWNER, param_spec); param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_MEMORY_BUFFER_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_MEMORY_BUFFER_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_MEMORY_BUFFER_KNOW_MESSAGE_SIZE, param_spec); gobject_class->constructed = thrift_memory_buffer_constructed; gobject_class->finalize = thrift_memory_buffer_finalize; ttc->is_open = thrift_memory_buffer_is_open; ttc->open = thrift_memory_buffer_open; ttc->close = thrift_memory_buffer_close; ttc->read = thrift_memory_buffer_read; ttc->read_end = thrift_memory_buffer_read_end; ttc->write = thrift_memory_buffer_write; ttc->write_end = thrift_memory_buffer_write_end; ttc->flush = thrift_memory_buffer_flush; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c0000664000175000017500000002677115165535636026521 0ustar00buildbuild00000000000000/* * 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 /* object properties */ enum _ThriftTransportProperties { PROP_0, PROP_THRIFT_TRANSPORT_CONFIGURATION, PROP_THRIFT_TRANSPORT_REMAINING_MESSAGE_SIZE, PROP_THRIFT_TRANSPORT_KNOW_MESSAGE_SIZE }; /* define the GError domain string */ #define THRIFT_TRANSPORT_ERROR_DOMAIN "thrift-transport-error-quark" G_DEFINE_ABSTRACT_TYPE(ThriftTransport, thrift_transport, G_TYPE_OBJECT) gboolean thrift_transport_is_open (ThriftTransport *transport) { return THRIFT_TRANSPORT_GET_CLASS (transport)->is_open (transport); } gboolean thrift_transport_peek (ThriftTransport *transport, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->peek (transport, error); } gboolean thrift_transport_open (ThriftTransport *transport, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->open (transport, error); } gboolean thrift_transport_close (ThriftTransport *transport, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->close (transport, error); } gint32 thrift_transport_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->read (transport, buf, len, error); } gboolean thrift_transport_read_end (ThriftTransport *transport, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->read_end (transport, error); } gboolean thrift_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->write (transport, buf, len, error); } gboolean thrift_transport_write_end (ThriftTransport *transport, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->write_end (transport, error); } gboolean thrift_transport_flush (ThriftTransport *transport, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->flush (transport, error); } gint32 thrift_transport_read_all (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { return THRIFT_TRANSPORT_GET_CLASS (transport)->read_all (transport, buf, len, error); } /* by default, peek returns true if and only if the transport is open */ static gboolean thrift_transport_real_peek (ThriftTransport *transport, GError **error) { THRIFT_UNUSED_VAR (error); return THRIFT_TRANSPORT_GET_CLASS (transport)->is_open (transport); } static gint32 thrift_transport_real_read_all (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftTransportClass *ttc; guint32 have; gint32 ret; gint8 *bytes; THRIFT_UNUSED_VAR (error); ttc = THRIFT_TRANSPORT_GET_CLASS (transport); have = 0; ret = 0; bytes = (gint8*) buf; while (have < len) { if ((ret = ttc->read (transport, (gpointer) (bytes + have), len - have, error)) < 0) { return ret; } have += ret; } return have; } gboolean thrift_transport_updateKnownMessageSize(ThriftTransport *transport, glong size, GError **error) { gboolean boolean = TRUE; ThriftTransport *tt = THRIFT_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); glong consumed = tt->knowMessageSize_ - tt->remainingMessageSize_; if(!ttc->resetConsumedMessageSize (transport, size, error)) { boolean = FALSE; } if(!ttc->countConsumedMessageBytes (transport, consumed, error)) { boolean = FALSE; } return boolean; } gboolean thrift_transport_checkReadBytesAvailable(ThriftTransport *transport, glong numBytes, GError **error) { gboolean boolean = TRUE; ThriftTransport *tt = THRIFT_TRANSPORT (transport); if(tt->remainingMessageSize_ < numBytes || numBytes < 0) { g_set_error(error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED, "MaxMessageSize reached"); boolean = FALSE; } return boolean; } gboolean thrift_transport_resetConsumedMessageSize(ThriftTransport *transport, glong newSize, GError **error) { ThriftTransport *tt = THRIFT_TRANSPORT (transport); if(newSize < 0) { if(tt->configuration != NULL) { tt->knowMessageSize_ = tt->configuration->maxMessageSize_; tt->remainingMessageSize_ = tt->configuration->maxMessageSize_; } else { tt->knowMessageSize_ = DEFAULT_MAX_MESSAGE_SIZE; tt->remainingMessageSize_ = DEFAULT_MAX_MESSAGE_SIZE; } return TRUE; } /* update only: message size can shrink, but not grow */ if(newSize > tt->knowMessageSize_) { g_set_error(error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED, "MaxMessageSize reached"); return FALSE; } tt->knowMessageSize_ = newSize; tt->remainingMessageSize_ = newSize; return TRUE; } gboolean thrift_transport_countConsumedMessageBytes(ThriftTransport *transport, glong numBytes, GError **error) { ThriftTransport *tt = THRIFT_TRANSPORT (transport); if(tt->remainingMessageSize_ > numBytes) { tt->remainingMessageSize_ -= numBytes; } else { tt->remainingMessageSize_ = 0; g_set_error(error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED, "MaxMessageSize reached"); return FALSE; } return TRUE; } /* property accesor */ void thrift_transport_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftTransport *transport = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_TRANSPORT_CONFIGURATION: g_value_set_object (value, transport->configuration); break; case PROP_THRIFT_TRANSPORT_REMAINING_MESSAGE_SIZE: g_value_set_long (value, transport->remainingMessageSize_); break; case PROP_THRIFT_TRANSPORT_KNOW_MESSAGE_SIZE: g_value_set_long (value, transport->knowMessageSize_); break; } } /* property mutator */ void thrift_transport_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftTransport *transport = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_TRANSPORT_CONFIGURATION: transport->configuration = g_value_get_object (value); break; case PROP_THRIFT_TRANSPORT_REMAINING_MESSAGE_SIZE: transport->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_TRANSPORT_KNOW_MESSAGE_SIZE: transport->knowMessageSize_ = g_value_get_long (value); break; } } /* define the GError domain for Thrift transports */ GQuark thrift_transport_error_quark (void) { return g_quark_from_static_string (THRIFT_TRANSPORT_ERROR_DOMAIN); } static void thrift_transport_dispose (GObject *gobject) { ThriftTransport *self = THRIFT_TRANSPORT (gobject); if(self->configuration != NULL) g_clear_object (&self->configuration); /* Always chain up to the parent class; there is no need to check if * the parent class implements the dispose() virtual function: it is * always guaranteed to do so */ G_OBJECT_CLASS (thrift_transport_parent_class)->dispose (gobject); } /* class initializer for ThriftTransport */ static void thrift_transport_class_init (ThriftTransportClass *cls) { GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_transport_get_property; gobject_class->set_property = thrift_transport_set_property; gobject_class->dispose = thrift_transport_dispose; param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_TRANSPORT_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_TRANSPORT_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_TRANSPORT_KNOW_MESSAGE_SIZE, param_spec); /* set these as virtual methods to be implemented by a subclass */ cls->is_open = thrift_transport_is_open; cls->open = thrift_transport_open; cls->close = thrift_transport_close; cls->read = thrift_transport_read; cls->read_end = thrift_transport_read_end; cls->write = thrift_transport_write; cls->write_end = thrift_transport_write_end; cls->flush = thrift_transport_flush; /* provide a default implementation for the peek and read_all methods */ cls->peek = thrift_transport_real_peek; cls->read_all = thrift_transport_real_read_all; cls->updateKnownMessageSize = thrift_transport_updateKnownMessageSize; cls->checkReadBytesAvailable = thrift_transport_checkReadBytesAvailable; cls->resetConsumedMessageSize = thrift_transport_resetConsumedMessageSize; cls->countConsumedMessageBytes = thrift_transport_countConsumedMessageBytes; } static void thrift_transport_init (ThriftTransport *transport) { THRIFT_UNUSED_VAR (transport); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.h0000664000175000017500000000666115165535636031567 0ustar00buildbuild00000000000000/* * 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_FRAMED_TRANSPORT_FACTORY_H #define _THRIFT_FRAMED_TRANSPORT_FACTORY_H #include #include #include G_BEGIN_DECLS /*! \file thrift_framed_transport_factory.h * \brief Wraps a transport with a ThriftFramedTransport. */ /* type macros */ #define THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY \ (thrift_framed_transport_factory_get_type ()) #define THRIFT_FRAMED_TRANSPORT_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY, \ ThriftFramedTransportFactory)) #define THRIFT_IS_FRAMED_TRANSPORT_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY)) #define THRIFT_FRAMED_TRANSPORT_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), \ THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY, \ ThriftFramedTransportFactoryClass)) #define THRIFT_IS_FRAMED_TRANSPORT_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), \ THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY)) #define THRIFT_FRAMED_TRANSPORT_FACTORY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY, \ ThriftFramedTransportFactoryClass)) typedef struct _ThriftFramedTransportFactory ThriftFramedTransportFactory; /* Thrift Framed-Transport Factory instance */ struct _ThriftFramedTransportFactory { ThriftTransportFactory parent; }; typedef struct _ThriftFramedTransportFactoryClass ThriftFramedTransportFactoryClass; /* Thrift Framed-Transport Factory class */ struct _ThriftFramedTransportFactoryClass { ThriftTransportFactoryClass parent; /* vtable */ ThriftTransport *(*get_transport) (ThriftTransportFactory *factory, ThriftTransport *transport); }; /* used by THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY */ GType thrift_framed_transport_factory_get_type (void); /* virtual public methods */ ThriftTransport * thrift_framed_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport); G_END_DECLS #endif /* _THRIFT_FRAMED_TRANSPORT_FACTORY_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h0000664000175000017500000000472415165535636030362 0ustar00buildbuild00000000000000/* * 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_BUFFERED_TRANSPORT_H #define _THRIFT_BUFFERED_TRANSPORT_H #include #include #include G_BEGIN_DECLS /*! \file thrift_buffered_transport.h * \brief Implementation of a Thrift buffered transport. Subclasses * the ThriftTransport class. */ /* type macros */ #define THRIFT_TYPE_BUFFERED_TRANSPORT (thrift_buffered_transport_get_type ()) #define THRIFT_BUFFERED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransport)) #define THRIFT_IS_BUFFERED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT)) #define THRIFT_BUFFERED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransportClass)) #define THRIFT_IS_BUFFERED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BUFFERED_TRANSPORT)) #define THRIFT_BUFFERED_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransportClass)) typedef struct _ThriftBufferedTransport ThriftBufferedTransport; /*! * ThriftBufferedTransport instance. */ struct _ThriftBufferedTransport { ThriftTransport parent; /* protected */ ThriftTransport *transport; /* private */ GByteArray *r_buf; GByteArray *w_buf; guint32 r_buf_size; guint32 w_buf_size; }; typedef struct _ThriftBufferedTransportClass ThriftBufferedTransportClass; /*! * ThriftBufferedTransport class. */ struct _ThriftBufferedTransportClass { ThriftTransportClass parent; }; /* used by THRIFT_TYPE_BUFFERED_TRANSPORT */ GType thrift_buffered_transport_get_type (void); G_END_DECLS #endif thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.c0000664000175000017500000004064715165535636030361 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include /* object properties */ enum _ThriftBufferedTransportProperties { PROP_0, PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT, PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE, PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE, PROP_THRIFT_BUFFERED_TRANSPORT_CONFIGURATION, PROP_THRIFT_BUFFERED_TRANSPORT_REMAINING_MESSAGE_SIZE, PROP_THRIFT_BUFFERED_TRANSPORT_KNOW_MESSAGE_SIZE }; G_DEFINE_TYPE(ThriftBufferedTransport, thrift_buffered_transport, THRIFT_TYPE_TRANSPORT) /* implements thrift_transport_is_open */ gboolean thrift_buffered_transport_is_open (ThriftTransport *transport) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->is_open (t->transport); } /* overrides thrift_transport_peek */ gboolean thrift_buffered_transport_peek (ThriftTransport *transport, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); return (t->r_buf->len > 0) || thrift_transport_peek (t->transport, error); } /* implements thrift_transport_open */ gboolean thrift_buffered_transport_open (ThriftTransport *transport, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->open (t->transport, error); } /* implements thrift_transport_close */ gboolean thrift_buffered_transport_close (ThriftTransport *transport, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->close (t->transport, error); } /* the actual read is "slow" because it calls the underlying transport */ gint32 thrift_buffered_transport_read_slow (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); gint ret = 0; guint32 want = len; guint32 got = 0; guchar *tmpdata = g_new0 (guchar, len); guint32 have = t->r_buf->len; /* we shouldn't hit this unless the buffer doesn't have enough to read */ g_assert (t->r_buf->len < want); /* first copy what we have in our buffer. */ if (have > 0) { memcpy (buf, t->r_buf, t->r_buf->len); want -= t->r_buf->len; t->r_buf = g_byte_array_remove_range (t->r_buf, 0, t->r_buf->len); } /* if the buffer is still smaller than what we want to read, then just * read it directly. otherwise, fill the buffer and then give out * enough to satisfy the read. */ if (t->r_buf_size < want) { if ((ret = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport, tmpdata, want, error)) < 0) { g_free (tmpdata); return ret; } got += ret; /* copy the data starting from where we left off */ memcpy ((guint8 *)buf + have, tmpdata, got); g_free (tmpdata); return got + have; } else { guint32 give; if ((ret = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport, tmpdata, want, error)) < 0) { g_free (tmpdata); return ret; } got += ret; t->r_buf = g_byte_array_append (t->r_buf, tmpdata, got); g_free (tmpdata); /* hand over what we have up to what the caller wants */ give = want < t->r_buf->len ? want : t->r_buf->len; memcpy ((guint8 *)buf + len - want, t->r_buf->data, give); t->r_buf = g_byte_array_remove_range (t->r_buf, 0, give); want -= give; return (len - want); } } /* implements thrift_transport_read */ gint32 thrift_buffered_transport_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->checkReadBytesAvailable (transport, len, error)) { return -1; } /* if we have enough buffer data to fulfill the read, just use * a memcpy */ if (len <= t->r_buf->len) { memcpy (buf, t->r_buf->data, len); g_byte_array_remove_range (t->r_buf, 0, len); return len; } return thrift_buffered_transport_read_slow (transport, buf, len, error); } /* implements thrift_transport_read_end * called when write is complete. nothing to do on our end. */ gboolean thrift_buffered_transport_read_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } gboolean thrift_buffered_transport_write_slow (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); guint32 have_bytes = t->w_buf->len; guint32 space = t->w_buf_size - t->w_buf->len; /* we need two syscalls because the buffered data plus the buffer itself * is too big. */ if ((have_bytes + len >= 2*t->w_buf_size) || (have_bytes == 0)) { if (have_bytes > 0) { if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, t->w_buf->data, have_bytes, error)) { return FALSE; } t->w_buf = g_byte_array_remove_range (t->w_buf, 0, have_bytes); } if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, buf, len, error)) { return FALSE; } return TRUE; } t->w_buf = g_byte_array_append (t->w_buf, buf, space); if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, t->w_buf->data, t->w_buf->len, error)) { return FALSE; } t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len); t->w_buf = g_byte_array_append (t->w_buf, (guint8 *)buf + space, len-space); return TRUE; } /* implements thrift_transport_write */ gboolean thrift_buffered_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); /* the length of the current buffer plus the length of the data being read */ if (t->w_buf->len + len <= t->w_buf_size) { t->w_buf = g_byte_array_append (t->w_buf, buf, len); return len; } return thrift_buffered_transport_write_slow (transport, buf, len, error); } /* implements thrift_transport_write_end * called when write is complete. nothing to do on our end. */ gboolean thrift_buffered_transport_write_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_flush */ gboolean thrift_buffered_transport_flush (ThriftTransport *transport, GError **error) { ThriftBufferedTransport *t = THRIFT_BUFFERED_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->resetConsumedMessageSize (transport, -1, error)) { return FALSE; } if (t->w_buf != NULL && t->w_buf->len > 0) { /* write the buffer and then empty it */ if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, t->w_buf->data, t->w_buf->len, error)) { return FALSE; } t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len); } THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush (t->transport, error); return TRUE; } /* initializes the instance */ static void thrift_buffered_transport_init (ThriftBufferedTransport *transport) { transport->transport = NULL; transport->r_buf = g_byte_array_new (); transport->w_buf = g_byte_array_new (); } /* destructor */ static void thrift_buffered_transport_finalize (GObject *object) { ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object); if (transport->r_buf != NULL) { g_byte_array_free (transport->r_buf, TRUE); } transport->r_buf = NULL; if (transport->w_buf != NULL) { g_byte_array_free (transport->w_buf, TRUE); } transport->w_buf = NULL; } /* property accessor */ void thrift_buffered_transport_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT: g_value_set_object (value, transport->transport); break; case PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE: g_value_set_uint (value, transport->r_buf_size); break; case PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE: g_value_set_uint (value, transport->w_buf_size); break; case PROP_THRIFT_BUFFERED_TRANSPORT_CONFIGURATION: g_value_set_object (value, tt->configuration); break; case PROP_THRIFT_BUFFERED_TRANSPORT_REMAINING_MESSAGE_SIZE: g_value_set_long (value, tt->remainingMessageSize_); break; case PROP_THRIFT_BUFFERED_TRANSPORT_KNOW_MESSAGE_SIZE: g_value_set_long (value, tt->knowMessageSize_); break; } } /* property mutator */ void thrift_buffered_transport_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftBufferedTransport *transport = THRIFT_BUFFERED_TRANSPORT (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT: transport->transport = g_value_get_object (value); break; case PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE: transport->r_buf_size = g_value_get_uint (value); break; case PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE: transport->w_buf_size = g_value_get_uint (value); break; case PROP_THRIFT_BUFFERED_TRANSPORT_CONFIGURATION: tt->configuration = g_value_dup_object (value); break; case PROP_THRIFT_BUFFERED_TRANSPORT_REMAINING_MESSAGE_SIZE: tt->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_BUFFERED_TRANSPORT_KNOW_MESSAGE_SIZE: tt->knowMessageSize_ = g_value_get_long (value); break; } } /* initializes the class */ static void thrift_buffered_transport_class_init (ThriftBufferedTransportClass *cls) { ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls); GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_buffered_transport_get_property; gobject_class->set_property = thrift_buffered_transport_set_property; param_spec = g_param_spec_object ("transport", "transport (construct)", "Thrift transport", THRIFT_TYPE_TRANSPORT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_BUFFERED_TRANSPORT_TRANSPORT, param_spec); param_spec = g_param_spec_uint ("r_buf_size", "read buffer size (construct)", "Set the read buffer size", 0, /* min */ 1048576, /* max, 1024*1024 */ 512, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_BUFFERED_TRANSPORT_READ_BUFFER_SIZE, param_spec); param_spec = g_param_spec_uint ("w_buf_size", "write buffer size (construct)", "Set the write buffer size", 0, /* min */ 1048576, /* max, 1024*1024 */ 512, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_BUFFERED_TRANSPORT_WRITE_BUFFER_SIZE, param_spec); param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_BUFFERED_TRANSPORT_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_BUFFERED_TRANSPORT_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_BUFFERED_TRANSPORT_KNOW_MESSAGE_SIZE, param_spec); gobject_class->finalize = thrift_buffered_transport_finalize; ttc->is_open = thrift_buffered_transport_is_open; ttc->peek = thrift_buffered_transport_peek; ttc->open = thrift_buffered_transport_open; ttc->close = thrift_buffered_transport_close; ttc->read = thrift_buffered_transport_read; ttc->read_end = thrift_buffered_transport_read_end; ttc->write = thrift_buffered_transport_write; ttc->write_end = thrift_buffered_transport_write_end; ttc->flush = thrift_buffered_transport_flush; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c0000664000175000017500000003731515165535636030033 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include /* object properties */ enum _ThriftFramedTransportProperties { PROP_0, PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT, PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE, PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE, PROP_THRIFT_FRAMED_TRANSPORT_REMAINING_MESSAGE_SIZE, PROP_THRIFT_FRAMED_TRANSPORT_KNOW_MESSAGE_SIZE, PROP_THRIFT_FRAMED_TRANSPORT_CONFIGURATION }; G_DEFINE_TYPE(ThriftFramedTransport, thrift_framed_transport, THRIFT_TYPE_TRANSPORT) /* implements thrift_transport_is_open */ gboolean thrift_framed_transport_is_open (ThriftTransport *transport) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->is_open (t->transport); } /* overrides thrift_transport_peek */ gboolean thrift_framed_transport_peek (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); return (t->r_buf->len > 0) || thrift_transport_peek (t->transport, error); } /* implements thrift_transport_open */ gboolean thrift_framed_transport_open (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->open (t->transport, error); } /* implements thrift_transport_close */ gboolean thrift_framed_transport_close (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); return THRIFT_TRANSPORT_GET_CLASS (t->transport)->close (t->transport, error); } /* reads a frame and puts it into the buffer */ gboolean thrift_framed_transport_read_frame (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); guint32 sz; gint32 bytes; gboolean result = FALSE; /* read the size */ if (thrift_transport_read (t->transport, &sz, sizeof (sz), error) == sizeof (sz)) { guchar *tmpdata; sz = ntohl (sz); if (sz > t->max_frame_size) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_MAX_MESSAGE_SIZE_REACHED, "Recived an oversized frame,"); return result; } /* create a buffer to hold the data and read that much data */ tmpdata = g_new0 (guchar, sz); bytes = thrift_transport_read (t->transport, tmpdata, sz, error); if (bytes > 0 && (error == NULL || *error == NULL)) { /* add the data to the buffer */ g_byte_array_append (t->r_buf, tmpdata, bytes); result = TRUE; } g_free (tmpdata); } return result; } /* the actual read is "slow" because it calls the underlying transport */ gint32 thrift_framed_transport_read_slow (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); guint32 want = len; guint32 have = t->r_buf->len; gint32 result = -1; /* we shouldn't hit this unless the buffer doesn't have enough to read */ g_assert (t->r_buf->len < want); /* first copy what we have in our buffer, if there is anything left */ if (have > 0) { memcpy (buf, t->r_buf, t->r_buf->len); want -= t->r_buf->len; t->r_buf = g_byte_array_remove_range (t->r_buf, 0, t->r_buf->len); } /* read a frame of input and buffer it */ if (thrift_framed_transport_read_frame (transport, error) == TRUE) { /* hand over what we have up to what the caller wants */ guint32 give = want < t->r_buf->len ? want : t->r_buf->len; /* copy the data into the buffer */ memcpy ((guint8 *)buf + len - want, t->r_buf->data, give); t->r_buf = g_byte_array_remove_range (t->r_buf, 0, give); want -= give; result = len - want; } return result; } /* implements thrift_transport_read */ gint32 thrift_framed_transport_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); if(!ttc->checkReadBytesAvailable (transport, len, error)) { return -1; } /* if we have enough buffer data to fulfill the read, just use * a memcpy from the buffer */ if (len <= t->r_buf->len) { memcpy (buf, t->r_buf->data, len); g_byte_array_remove_range (t->r_buf, 0, len); return len; } return thrift_framed_transport_read_slow (transport, buf, len, error); } /* implements thrift_transport_read_end * called when read is complete. nothing to do on our end. */ gboolean thrift_framed_transport_read_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } gboolean thrift_framed_transport_write_slow (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); THRIFT_UNUSED_VAR (error); /* append the data to the buffer and we're done */ g_byte_array_append (t->w_buf, buf, len); return TRUE; } /* implements thrift_transport_write */ gboolean thrift_framed_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); /* the length of the current buffer plus the length of the data being read */ if (t->w_buf->len + len <= t->w_buf_size) { t->w_buf = g_byte_array_append (t->w_buf, buf, len); return TRUE; } return thrift_framed_transport_write_slow (transport, buf, len, error); } /* implements thrift_transport_write_end * called when write is complete. nothing to do on our end. */ gboolean thrift_framed_transport_write_end (ThriftTransport *transport, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (transport); THRIFT_UNUSED_VAR (error); return TRUE; } /* implements thrift_transport_flush */ gboolean thrift_framed_transport_flush (ThriftTransport *transport, GError **error) { ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport); gint32 sz_hbo, sz_nbo; guchar *tmpdata; if(!ttc->resetConsumedMessageSize (transport, -1, error)) { return FALSE; } /* get the size of the frame in host and network byte order */ sz_hbo = t->w_buf->len + sizeof(sz_nbo); sz_nbo = (gint32) htonl ((guint32) t->w_buf->len); /* copy the size of the frame and then the frame itself */ tmpdata = g_new0 (guchar, sz_hbo); memcpy (tmpdata, (guint8 *) &sz_nbo, sizeof (sz_nbo)); if (t->w_buf->len > 0) { memcpy (tmpdata + sizeof (sz_nbo), t->w_buf->data, t->w_buf->len); t->w_buf = g_byte_array_remove_range (t->w_buf, 0, t->w_buf->len); } /* write the buffer and then empty it */ THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport, tmpdata, sz_hbo, error); THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush (t->transport, error); g_free (tmpdata); return TRUE; } /* initializes the instance */ static void thrift_framed_transport_init (ThriftFramedTransport *transport) { transport->transport = NULL; transport->r_buf = g_byte_array_new (); transport->w_buf = g_byte_array_new (); transport->max_frame_size = DEFAULT_MAX_FRAME_SIZE; } /* destructor */ static void thrift_framed_transport_finalize (GObject *object) { ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object); if (transport->r_buf != NULL) { g_byte_array_free (transport->r_buf, TRUE); } transport->r_buf = NULL; if (transport->w_buf != NULL) { g_byte_array_free (transport->w_buf, TRUE); } transport->w_buf = NULL; } /* property accessor */ void thrift_framed_transport_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT: g_value_set_object (value, transport->transport); break; case PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE: g_value_set_uint (value, transport->r_buf_size); break; case PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE: g_value_set_uint (value, transport->w_buf_size); break; case PROP_THRIFT_FRAMED_TRANSPORT_CONFIGURATION: g_value_set_object (value, tt->configuration); break; case PROP_THRIFT_FRAMED_TRANSPORT_REMAINING_MESSAGE_SIZE: g_value_set_long (value, tt->remainingMessageSize_); break; case PROP_THRIFT_FRAMED_TRANSPORT_KNOW_MESSAGE_SIZE: g_value_set_long (value, tt->knowMessageSize_); break; } } /* property mutator */ void thrift_framed_transport_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftFramedTransport *transport = THRIFT_FRAMED_TRANSPORT (object); ThriftTransport *tt = THRIFT_TRANSPORT (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT: transport->transport = g_value_get_object (value); break; case PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE: transport->r_buf_size = g_value_get_uint (value); break; case PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE: transport->w_buf_size = g_value_get_uint (value); break; case PROP_THRIFT_FRAMED_TRANSPORT_CONFIGURATION: tt->configuration = g_value_dup_object (value); if (tt->configuration != NULL) { transport->max_frame_size = tt->configuration->maxFrameSize_; } break; case PROP_THRIFT_FRAMED_TRANSPORT_REMAINING_MESSAGE_SIZE: tt->remainingMessageSize_ = g_value_get_long (value); break; case PROP_THRIFT_FRAMED_TRANSPORT_KNOW_MESSAGE_SIZE: tt->knowMessageSize_ = g_value_get_long (value); break; } } /* initializes the class */ static void thrift_framed_transport_class_init (ThriftFramedTransportClass *cls) { ThriftTransportClass *ttc = THRIFT_TRANSPORT_CLASS (cls); GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_framed_transport_get_property; gobject_class->set_property = thrift_framed_transport_set_property; param_spec = g_param_spec_object ("transport", "transport (construct)", "Thrift transport", THRIFT_TYPE_TRANSPORT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_FRAMED_TRANSPORT_TRANSPORT, param_spec); param_spec = g_param_spec_uint ("r_buf_size", "read buffer size (construct)", "Set the read buffer size", 0, /* min */ 1048576, /* max, 1024*1024 */ 512, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_FRAMED_TRANSPORT_READ_BUFFER_SIZE, param_spec); param_spec = g_param_spec_uint ("w_buf_size", "write buffer size (construct)", "Set the write buffer size", 0, /* min */ 1048576, /* max, 1024*1024 */ 512, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_FRAMED_TRANSPORT_WRITE_BUFFER_SIZE, param_spec); param_spec = g_param_spec_object ("configuration", "configuration (construct)", "Thrift Configuration", THRIFT_TYPE_CONFIGURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_FRAMED_TRANSPORT_CONFIGURATION, param_spec); param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)", "Set the remaining message size", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_FRAMED_TRANSPORT_REMAINING_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)", "Set the known size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_THRIFT_FRAMED_TRANSPORT_KNOW_MESSAGE_SIZE, param_spec); gobject_class->finalize = thrift_framed_transport_finalize; ttc->is_open = thrift_framed_transport_is_open; ttc->peek = thrift_framed_transport_peek; ttc->open = thrift_framed_transport_open; ttc->close = thrift_framed_transport_close; ttc->read = thrift_framed_transport_read; ttc->read_end = thrift_framed_transport_read_end; ttc->write = thrift_framed_transport_write; ttc->write_end = thrift_framed_transport_write_end; ttc->flush = thrift_framed_transport_flush; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_server_transport.h0000664000175000017500000000677015165535636030111 0ustar00buildbuild00000000000000/* * 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_SERVER_TRANSPORT_H #define _THRIFT_SERVER_TRANSPORT_H #include #include "thrift_transport.h" G_BEGIN_DECLS /*! \file thrift_server_transport.h * \brief Abstract class for Thrift server transports. */ /* type macros */ #define THRIFT_TYPE_SERVER_TRANSPORT (thrift_server_transport_get_type ()) #define THRIFT_SERVER_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_SERVER_TRANSPORT, ThriftServerTransport)) #define THRIFT_IS_SERVER_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_SERVER_TRANSPORT)) #define THRIFT_SERVER_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_SERVER_TRANSPORT, ThriftServerTransportClass)) #define THRIFT_IS_SERVER_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_SERVER_TRANSPORT)) #define THRIFT_SERVER_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_SERVER_TRANSPORT, ThriftServerTransportClass)) typedef struct _ThriftServerTransport ThriftServerTransport; struct _ThriftServerTransport { GObject parent; /* protected */ ThriftConfiguration *configuration; glong remainingMessageSize_; glong knowMessageSize_; }; typedef struct _ThriftServerTransportClass ThriftServerTransportClass; /*! * Thrift Transport class */ struct _ThriftServerTransportClass { GObjectClass parent; /* vtable */ gboolean (*listen) (ThriftServerTransport *transport, GError **error); ThriftTransport *(*accept) (ThriftServerTransport *transport, GError **error); gboolean (*close) (ThriftServerTransport *transport, GError **error); gboolean (*updateKnownMessageSize) (ThriftServerTransport *transport, glong size, GError **error); gboolean (*checkReadBytesAvailable) (ThriftServerTransport *transport, glong numBytes, GError **error); gboolean (*resetConsumedMessageSize) (ThriftServerTransport *transport, glong newSize, GError **error); gboolean (*countConsumedMessageBytes) (ThriftServerTransport *transport, glong numBytes, GError **error); }; /* used by THRIFT_TYPE_SERVER_TRANSPORT */ GType thrift_server_transport_get_type (void); /*! * Listen for new connections. * \public \memberof ThriftServerTransportClass */ gboolean thrift_server_transport_listen (ThriftServerTransport *transport, GError **error); /*! * Accept a connection. * \public \memberof ThriftServerTransportClass */ ThriftTransport *thrift_server_transport_accept (ThriftServerTransport *transport, GError **error); /*! * Close the transport. * \public \memberof ThriftServerTransportClass */ gboolean thrift_server_transport_close (ThriftServerTransport *transport, GError **error); G_END_DECLS #endif /* _THRIFT_SERVER_TRANSPORT_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_transport_factory.c0000664000175000017500000000274515165535636030243 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_TYPE(ThriftTransportFactory, thrift_transport_factory, G_TYPE_OBJECT) /* builds a transport from the base transport. */ ThriftTransport * thrift_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport) { THRIFT_UNUSED_VAR (factory); return transport; } static void thrift_transport_factory_class_init (ThriftTransportFactoryClass *cls) { cls->get_transport = thrift_transport_factory_get_transport; } static void thrift_transport_factory_init (ThriftTransportFactory *factory) { THRIFT_UNUSED_VAR (factory); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.c0000664000175000017500000000364215165535636031260 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_TYPE (ThriftZlibTransportFactory, thrift_zlib_transport_factory, THRIFT_TYPE_TRANSPORT_FACTORY) /* Wraps a transport with a ThriftZlibTransport. */ ThriftTransport * thrift_zlib_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport) { THRIFT_UNUSED_VAR (factory); return THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, "transport", transport, NULL)); } static void thrift_zlib_transport_factory_init (ThriftZlibTransportFactory *self) { THRIFT_UNUSED_VAR (self); } static void thrift_zlib_transport_factory_class_init (ThriftZlibTransportFactoryClass *klass) { ThriftTransportFactoryClass *base_class = THRIFT_TRANSPORT_FACTORY_CLASS (klass); base_class->get_transport = klass->get_transport = thrift_zlib_transport_factory_get_transport; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport_factory.c0000664000175000017500000000367115165535636031560 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_TYPE (ThriftFramedTransportFactory, thrift_framed_transport_factory, THRIFT_TYPE_TRANSPORT_FACTORY) /* Wraps a transport with a ThriftFramedTransport. */ ThriftTransport * thrift_framed_transport_factory_get_transport (ThriftTransportFactory *factory, ThriftTransport *transport) { THRIFT_UNUSED_VAR (factory); return THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", transport, NULL)); } static void thrift_framed_transport_factory_init (ThriftFramedTransportFactory *self) { THRIFT_UNUSED_VAR (self); } static void thrift_framed_transport_factory_class_init (ThriftFramedTransportFactoryClass *klass) { ThriftTransportFactoryClass *base_class = THRIFT_TRANSPORT_FACTORY_CLASS (klass); base_class->get_transport = klass->get_transport = thrift_framed_transport_factory_get_transport; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/0000755000175000017500000000000015170007200022500 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.c0000664000175000017500000005476415165535636026136 0ustar00buildbuild00000000000000/* * 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 /* define the GError domain string */ #define THRIFT_PROTOCOL_ERROR_DOMAIN "thrift-protocol-error-quark" /* object properties */ enum _ThriftProtocolProperties { PROP_0, PROP_THRIFT_PROTOCOL_TRANSPORT }; G_DEFINE_ABSTRACT_TYPE(ThriftProtocol, thrift_protocol, G_TYPE_OBJECT) void thrift_protocol_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftProtocol *protocol = THRIFT_PROTOCOL (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_PROTOCOL_TRANSPORT: g_value_set_object (value, protocol->transport); break; } } void thrift_protocol_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftProtocol *protocol = THRIFT_PROTOCOL (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_PROTOCOL_TRANSPORT: protocol->transport = g_value_dup_object (value); break; } } gint32 thrift_protocol_write_message_begin (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_message_begin (protocol, name, message_type, seqid, error); } gint32 thrift_protocol_write_message_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_message_end (protocol, error); } gint32 thrift_protocol_write_struct_begin (ThriftProtocol *protocol, const gchar *name, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_struct_begin (protocol, name, error); } gint32 thrift_protocol_write_struct_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_struct_end (protocol, error); } gint32 thrift_protocol_write_field_begin (ThriftProtocol *protocol, const gchar *name, const ThriftType field_type, const gint16 field_id, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_begin (protocol, name, field_type, field_id, error); } gint32 thrift_protocol_write_field_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_end (protocol, error); } gint32 thrift_protocol_write_field_stop (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_field_stop (protocol, error); } gint32 thrift_protocol_write_map_begin (ThriftProtocol *protocol, const ThriftType key_type, const ThriftType value_type, const guint32 size, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_map_begin (protocol, key_type, value_type, size, error); } gint32 thrift_protocol_write_map_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_map_end (protocol, error); } gint32 thrift_protocol_write_list_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_list_begin (protocol, element_type, size, error); } gint32 thrift_protocol_write_list_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_list_end (protocol, error); } gint32 thrift_protocol_write_set_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_set_begin (protocol, element_type, size, error); } gint32 thrift_protocol_write_set_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_set_end (protocol, error); } gint32 thrift_protocol_write_bool (ThriftProtocol *protocol, const gboolean value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_bool (protocol, value, error); } gint32 thrift_protocol_write_byte (ThriftProtocol *protocol, const gint8 value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_byte (protocol, value, error); } gint32 thrift_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i16 (protocol, value, error); } gint32 thrift_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i32 (protocol, value, error); } gint32 thrift_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_i64 (protocol, value, error); } gint32 thrift_protocol_write_double (ThriftProtocol *protocol, const gdouble value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_double (protocol, value, error); } gint32 thrift_protocol_write_string (ThriftProtocol *protocol, const gchar *str, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_string (protocol, str, error); } gint32 thrift_protocol_write_binary (ThriftProtocol *protocol, const gpointer buf, const guint32 len, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->write_binary (protocol, buf, len, error); } gint32 thrift_protocol_read_message_begin (ThriftProtocol *protocol, gchar **name, ThriftMessageType *message_type, gint32 *seqid, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_message_begin (protocol, name, message_type, seqid, error); } gint32 thrift_protocol_read_message_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_message_end (protocol, error); } gint32 thrift_protocol_read_struct_begin (ThriftProtocol *protocol, gchar **name, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_struct_begin (protocol, name, error); } gint32 thrift_protocol_read_struct_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_struct_end (protocol, error); } gint32 thrift_protocol_read_field_begin (ThriftProtocol *protocol, gchar **name, ThriftType *field_type, gint16 *field_id, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_field_begin (protocol, name, field_type, field_id, error); } gint32 thrift_protocol_read_field_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_field_end (protocol, error); } gint32 thrift_protocol_read_map_begin (ThriftProtocol *protocol, ThriftType *key_type, ThriftType *value_type, guint32 *size, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_map_begin (protocol, key_type, value_type, size, error); } gint32 thrift_protocol_read_map_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_map_end (protocol, error); } gint32 thrift_protocol_read_list_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_list_begin (protocol, element_type, size, error); } gint32 thrift_protocol_read_list_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_list_end (protocol, error); } gint32 thrift_protocol_read_set_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_set_begin (protocol, element_type, size, error); } gint32 thrift_protocol_read_set_end (ThriftProtocol *protocol, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_set_end (protocol, error); } gint32 thrift_protocol_read_bool (ThriftProtocol *protocol, gboolean *value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_bool (protocol, value, error); } gint32 thrift_protocol_read_byte (ThriftProtocol *protocol, gint8 *value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_byte (protocol, value, error); } gint32 thrift_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i16 (protocol, value, error); } gint32 thrift_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i32 (protocol, value, error); } gint32 thrift_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_i64 (protocol, value, error); } gint32 thrift_protocol_read_double (ThriftProtocol *protocol, gdouble *value, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_double (protocol, value, error); } gint32 thrift_protocol_read_string (ThriftProtocol *protocol, gchar **str, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_string (protocol, str, error); } gint32 thrift_protocol_read_binary (ThriftProtocol *protocol, gpointer *buf, guint32 *len, GError **error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->read_binary (protocol, buf, len, error); } gint thrift_protocol_get_min_serialized_size (ThriftProtocol *protocol, ThriftType type, GError ** error) { return THRIFT_PROTOCOL_GET_CLASS (protocol)->get_min_serialized_size (protocol, type, error); } #define THRIFT_SKIP_RESULT_OR_RETURN(_RES, _CALL) \ { \ gint32 _x = (_CALL); \ if (_x < 0) { return _x; } \ (_RES) += _x; \ } gint32 thrift_protocol_skip (ThriftProtocol *protocol, ThriftType type, GError **error) { switch (type) { case T_BOOL: { gboolean boolv; return thrift_protocol_read_bool (protocol, &boolv, error); } case T_BYTE: { gint8 bytev; return thrift_protocol_read_byte (protocol, &bytev, error); } case T_I16: { gint16 i16; return thrift_protocol_read_i16 (protocol, &i16, error); } case T_I32: { gint32 i32; return thrift_protocol_read_i32 (protocol, &i32, error); } case T_I64: { gint64 i64; return thrift_protocol_read_i64 (protocol, &i64, error); } case T_DOUBLE: { gdouble dub; return thrift_protocol_read_double (protocol, &dub, error); } case T_STRING: { gpointer data = NULL; guint32 len; gint32 ret = thrift_protocol_read_binary (protocol, &data, &len, error); if (data) { g_free (data); } return ret; } case T_STRUCT: { gint32 result = 0; gchar *name; gint16 fid; ThriftType ftype; THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_struct_begin (protocol, &name, error)) while (1) { THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_field_begin (protocol, &name, &ftype, &fid, error)) if (ftype == T_STOP) { break; } THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_skip (protocol, ftype, error)) THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_field_end (protocol, error)) } THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_struct_end (protocol, error)) return result; } case T_SET: { gint32 result = 0; ThriftType elem_type; guint32 i, size; THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_set_begin (protocol, &elem_type, &size, error)) for (i = 0; i < size; i++) { THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_skip (protocol, elem_type, error)) } THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_set_end (protocol, error)) return result; } case T_MAP: { gint32 result = 0; ThriftType elem_type; ThriftType key_type; guint32 i, size; THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_map_begin (protocol, &key_type, &elem_type, &size, error)) for (i = 0; i < size; i++) { THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_skip (protocol, key_type, error)) THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_skip (protocol, elem_type, error)) } THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_map_end (protocol, error)) return result; } case T_LIST: { gint32 result = 0; ThriftType elem_type; guint32 i, size; THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_list_begin (protocol, &elem_type, &size, error)) for (i = 0; i < size; i++) { THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_skip (protocol, elem_type, error)) } THRIFT_SKIP_RESULT_OR_RETURN(result, thrift_protocol_read_list_end (protocol, error)) return result; } default: break; } g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_INVALID_DATA, "unrecognized type"); return -1; } /* define the GError domain for Thrift protocols */ GQuark thrift_protocol_error_quark (void) { return g_quark_from_static_string (THRIFT_PROTOCOL_ERROR_DOMAIN); } static void thrift_protocol_init (ThriftProtocol *protocol) { protocol->transport = NULL; } static void thrift_protocol_dispose (GObject *gobject) { ThriftProtocol *self = THRIFT_PROTOCOL (gobject); g_clear_object(&self->transport); /* Always chain up to the parent class; there is no need to check if * the parent class implements the dispose() virtual function: it is * always guaranteed to do so */ G_OBJECT_CLASS (thrift_protocol_parent_class)->dispose(gobject); } static void thrift_protocol_class_init (ThriftProtocolClass *cls) { GObjectClass *gobject_class = G_OBJECT_CLASS (cls); gobject_class->get_property = thrift_protocol_get_property; gobject_class->set_property = thrift_protocol_set_property; gobject_class->dispose = thrift_protocol_dispose; g_object_class_install_property (gobject_class, PROP_THRIFT_PROTOCOL_TRANSPORT, g_param_spec_object ("transport", "Transport", "Thrift Transport", THRIFT_TYPE_TRANSPORT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); cls->write_message_begin = thrift_protocol_write_message_begin; cls->write_message_end = thrift_protocol_write_message_end; cls->write_struct_begin = thrift_protocol_write_struct_begin; cls->write_struct_end = thrift_protocol_write_struct_end; cls->write_field_begin = thrift_protocol_write_field_begin; cls->write_field_end = thrift_protocol_write_field_end; cls->write_field_stop = thrift_protocol_write_field_stop; cls->write_map_begin = thrift_protocol_write_map_begin; cls->write_map_end = thrift_protocol_write_map_end; cls->write_list_begin = thrift_protocol_write_list_begin; cls->write_list_end = thrift_protocol_write_list_end; cls->write_set_begin = thrift_protocol_write_set_begin; cls->write_set_end = thrift_protocol_write_set_end; cls->write_bool = thrift_protocol_write_bool; cls->write_byte = thrift_protocol_write_byte; cls->write_i16 = thrift_protocol_write_i16; cls->write_i32 = thrift_protocol_write_i32; cls->write_i64 = thrift_protocol_write_i64; cls->write_double = thrift_protocol_write_double; cls->write_string = thrift_protocol_write_string; cls->write_binary = thrift_protocol_write_binary; cls->read_message_begin = thrift_protocol_read_message_begin; cls->read_message_end = thrift_protocol_read_message_end; cls->read_struct_begin = thrift_protocol_read_struct_begin; cls->read_struct_end = thrift_protocol_read_struct_end; cls->read_field_begin = thrift_protocol_read_field_begin; cls->read_field_end = thrift_protocol_read_field_end; cls->read_map_begin = thrift_protocol_read_map_begin; cls->read_map_end = thrift_protocol_read_map_end; cls->read_list_begin = thrift_protocol_read_list_begin; cls->read_set_begin = thrift_protocol_read_set_begin; cls->read_set_end = thrift_protocol_read_set_end; cls->read_bool = thrift_protocol_read_bool; cls->read_byte = thrift_protocol_read_byte; cls->read_i16 = thrift_protocol_read_i16; cls->read_i32 = thrift_protocol_read_i32; cls->read_i64 = thrift_protocol_read_i64; cls->read_double = thrift_protocol_read_double; cls->read_string = thrift_protocol_read_string; cls->read_binary = thrift_protocol_read_binary; cls->get_min_serialized_size = thrift_protocol_get_min_serialized_size; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.h0000664000175000017500000000515315165535636027473 0ustar00buildbuild00000000000000/* * 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_BINARY_PROTOCOL_H #define _THRIFT_BINARY_PROTOCOL_H #include #include #include G_BEGIN_DECLS /*! \file thrift_binary_protocol.h * \brief Binary protocol implementation of a Thrift protocol. Implements the * ThriftProtocol interface. */ /* type macros */ #define THRIFT_TYPE_BINARY_PROTOCOL (thrift_binary_protocol_get_type ()) #define THRIFT_BINARY_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_BINARY_PROTOCOL, ThriftBinaryProtocol)) #define THRIFT_IS_BINARY_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_BINARY_PROTOCOL)) #define THRIFT_BINARY_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_BINARY_PROTOCOL, ThriftBinaryProtocolClass)) #define THRIFT_IS_BINARY_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BINARY_PROTOCOL)) #define THRIFT_BINARY_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_BINARY_PROTOCOL, ThriftBinaryProtocolClass)) /* version numbers */ #define THRIFT_BINARY_PROTOCOL_VERSION_1 0x80010000 #define THRIFT_BINARY_PROTOCOL_VERSION_MASK 0xffff0000 typedef struct _ThriftBinaryProtocol ThriftBinaryProtocol; /*! * Thrift Binary Protocol instance. */ struct _ThriftBinaryProtocol { ThriftProtocol parent; /* protected */ gint32 string_limit; gint32 container_limit; }; typedef struct _ThriftBinaryProtocolClass ThriftBinaryProtocolClass; /*! * Thrift Binary Protocol class. */ struct _ThriftBinaryProtocolClass { ThriftProtocolClass parent; }; /* used by THRIFT_TYPE_BINARY_PROTOCOL */ GType thrift_binary_protocol_get_type (void); gint thrift_binary_protocol_get_min_serialized_size(ThriftProtocol *protocol, ThriftType type, GError **error); G_END_DECLS #endif /* _THRIFT_BINARY_PROTOCOL_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h0000664000175000017500000000435115165535636031221 0ustar00buildbuild00000000000000/* * 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_BINARY_PROTOCOL_FACTORY_H #define _THRIFT_BINARY_PROTOCOL_FACTORY_H #include #include G_BEGIN_DECLS /* type macros */ #define THRIFT_TYPE_BINARY_PROTOCOL_FACTORY (thrift_binary_protocol_factory_get_type ()) #define THRIFT_BINARY_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, ThriftBinaryProtocolFactory)) #define THRIFT_IS_BINARY_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY)) #define THRIFT_BINARY_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, ThriftBinaryProtocolFactoryClass)) #define THRIFT_IS_BINARY_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY)) #define THRIFT_BINARY_PROTOCOL_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, ThriftBinaryProtocolFactoryClass)) typedef struct _ThriftBinaryProtocolFactory ThriftBinaryProtocolFactory; struct _ThriftBinaryProtocolFactory { ThriftProtocolFactory parent; }; typedef struct _ThriftBinaryProtocolFactoryClass ThriftBinaryProtocolFactoryClass; struct _ThriftBinaryProtocolFactoryClass { ThriftProtocolFactoryClass parent; }; /* used by THRIFT_TYPE_BINARY_PROTOCOL_FACTORY */ GType thrift_binary_protocol_factory_get_type (void); G_END_DECLS #endif /* _THRIFT_BINARY_PROTOCOL_FACTORY_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h0000664000175000017500000000517615165535636030550 0ustar00buildbuild00000000000000/* * 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_MULTIPLEXED_PROTOCOL_H #define _THRIFT_MULTIPLEXED_PROTOCOL_H #include #include #include #include G_BEGIN_DECLS /*! \file thrift_multiplexed_protocol.h * \brief Multiplexed protocol implementation of a Thrift protocol. Implements the * ThriftProtocol interface. */ /* type macros */ #define THRIFT_TYPE_MULTIPLEXED_PROTOCOL (thrift_multiplexed_protocol_get_type ()) #define THRIFT_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocol)) #define THRIFT_IS_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL)) #define THRIFT_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass)) #define THRIFT_IS_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL)) #define THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass)) /* constant */ #define THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR ":" typedef struct _ThriftMultiplexedProtocol ThriftMultiplexedProtocol; /*! * Thrift Multiplexed Protocol instance. */ struct _ThriftMultiplexedProtocol { ThriftProtocolDecorator parent; gchar *service_name; }; typedef struct _ThriftMultiplexedProtocolClass ThriftMultiplexedProtocolClass; /*! * Thrift Multiplexed Protocol class. */ struct _ThriftMultiplexedProtocolClass { ThriftProtocolDecoratorClass parent; }; /* used by THRIFT_TYPE_MULTIPLEXED_PROTOCOL */ GType thrift_multiplexed_protocol_get_type (void); G_END_DECLS #endif /* _THRIFT_MULTIPLEXED_PROTOCOL_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.c0000664000175000017500000000302315165535636027643 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_ABSTRACT_TYPE(ThriftProtocolFactory, thrift_protocol_factory, G_TYPE_OBJECT) ThriftProtocol * thrift_protocol_factory_get_protocol(ThriftProtocolFactory *factory, ThriftTransport *transport) { return THRIFT_PROTOCOL_FACTORY_GET_CLASS (factory)->get_protocol (factory, transport); } static void thrift_protocol_factory_init (ThriftProtocolFactory *factory) { THRIFT_UNUSED_VAR (factory); } static void thrift_protocol_factory_class_init (ThriftProtocolFactoryClass *cls) { cls->get_protocol = thrift_protocol_factory_get_protocol; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c0000664000175000017500000013300615165535636027627 0ustar00buildbuild00000000000000/* * 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 #include /* * *_to_zigzag depend on the fact that the right shift * operator on a signed integer is an arithmetic (sign-extending) shift. * If this is not the case, the current implementation will not work. */ #if !defined(SIGNED_RIGHT_SHIFT_IS) || !defined(ARITHMETIC_RIGHT_SHIFT) # error "Unable to determine the behavior of a signed right shift" #endif #if SIGNED_RIGHT_SHIFT_IS != ARITHMETIC_RIGHT_SHIFT # error "thrift_compact_protocol only works if signed right shift is arithmetic" #endif /* object properties */ enum _ThriftCompactProtocolProperties { PROP_0, PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT, PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT }; G_DEFINE_TYPE (ThriftCompactProtocol, thrift_compact_protocol, THRIFT_TYPE_PROTOCOL) static const gint8 PROTOCOL_ID = (gint8)0x82u; static const gint8 VERSION_N = 1; static const gint8 VERSION_MASK = 0x1f; /* 0001 1111 */ static const gint8 TYPE_MASK = (gint8)0xe0u; /* 1110 0000 */ static const gint8 TYPE_BITS = 0x07; /* 0000 0111 */ static const gint32 TYPE_SHIFT_AMOUNT = 5; enum 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 }; static const gint8 TTypeToCType[16] = { CT_STOP, /* T_STOP */ 0, /* unused */ CT_BOOLEAN_TRUE, /* T_BOOL */ CT_BYTE, /* T_BYTE */ CT_DOUBLE, /* T_DOUBLE */ 0, /* unused */ CT_I16, /* T_I16 */ 0, /* unused */ CT_I32, /* T_I32 */ 0, /* unused */ CT_I64, /* T_I64 */ CT_BINARY, /* T_STRING */ CT_STRUCT, /* T_STRUCT */ CT_MAP, /* T_MAP */ CT_SET, /* T_SET */ CT_LIST, /* T_LIST */ }; static guint64 thrift_bitwise_cast_guint64 (const gdouble v) { union { gdouble from; guint64 to; } u; u.from = v; return u.to; } static gdouble thrift_bitwise_cast_gdouble (const guint64 v) { union { guint64 from; gdouble to; } u; u.from = v; return u.to; } /** * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ static guint64 i64_to_zigzag (const gint64 l) { return (((guint64)l) << 1) ^ (l >> 63); } /** * Convert n into a zigzag int. This allows negative numbers to be * represented compactly as a varint. */ static guint32 i32_to_zigzag (const gint32 n) { return (((guint32)n) << 1) ^ (n >> 31); } /** * Convert from zigzag int to int. */ static gint32 zigzag_to_i32 (guint32 n) { return (n >> 1) ^ (guint32) (-(gint32) (n & 1)); } /** * Convert from zigzag long to long. */ static gint64 zigzag_to_i64 (guint64 n) { return (n >> 1) ^ (guint64) (-(gint64) (n & 1)); } ThriftType thrift_compact_protocol_get_ttype (ThriftCompactProtocol *protocol, const gint8 type, GError **error) { THRIFT_UNUSED_VAR (protocol); switch (type) { case T_STOP: return T_STOP; case CT_BOOLEAN_FALSE: case CT_BOOLEAN_TRUE: return T_BOOL; case CT_BYTE: return T_BYTE; case CT_I16: return T_I16; case CT_I32: return T_I32; case CT_I64: return T_I64; case CT_DOUBLE: return T_DOUBLE; case CT_BINARY: return T_STRING; case CT_LIST: return T_LIST; case CT_SET: return T_SET; case CT_MAP: return T_MAP; case CT_STRUCT: return T_STRUCT; default: g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_INVALID_DATA, "unrecognized type"); return -1; } } /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. */ gint32 thrift_compact_protocol_write_varint32 (ThriftCompactProtocol *protocol, const guint32 n, GError **error) { guint8 buf[5]; gint32 xfer; guint32 m; THRIFT_UNUSED_VAR (error); xfer = 0; m = n; while (TRUE) { if ((m & ~0x7F) == 0) { buf[xfer++] = (gint8)m; break; } else { buf[xfer++] = (gint8)((m & 0x7F) | 0x80); m >>= 7; } } if (thrift_transport_write (THRIFT_PROTOCOL (protocol)->transport, (const gpointer) buf, xfer, error)) { return xfer; } else { return -1; } } /** * Write an i64 as a varint. Results in 1-10 bytes on the wire. */ gint32 thrift_compact_protocol_write_varint64 (ThriftCompactProtocol *protocol, const guint64 n, GError **error) { guint8 buf[10]; gint32 xfer; guint64 m; THRIFT_UNUSED_VAR (error); xfer = 0; m = n; while (TRUE) { if ((m & ~0x7FL) == 0) { buf[xfer++] = (gint8)m; break; } else { buf[xfer++] = (gint8)((m & 0x7F) | 0x80); m >>= 7; } } if (thrift_transport_write (THRIFT_PROTOCOL (protocol)->transport, (const gpointer) buf, xfer, error)) { return xfer; } else { return -1; } } /** * 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. */ gint32 thrift_compact_protocol_read_varint64 (ThriftCompactProtocol *protocol, gint64 *i64, GError **error) { ThriftProtocol *tp; gint32 ret; gint32 xfer; guint64 val; gint shift; guint8 byte; tp = THRIFT_PROTOCOL (protocol); xfer = 0; val = 0; shift = 0; byte = 0; while (TRUE) { if ((ret = thrift_transport_read_all (tp->transport, (gpointer) &byte, 1, error)) < 0) { return -1; } ++xfer; val |= (guint64)(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { *i64 = (gint64) val; return xfer; } if (G_UNLIKELY (xfer == 10)) { /* 7 * 9 < 64 < 7 * 10 */ g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_INVALID_DATA, "variable-length int over 10 bytes"); return -1; } } } /** * 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. */ gint32 thrift_compact_protocol_read_varint32 (ThriftCompactProtocol *protocol, gint32 *i32, GError **error) { gint64 val; gint32 ret; gint32 xfer; xfer = 0; if ((ret = thrift_compact_protocol_read_varint64 (protocol, &val, error)) < 0) { return -1; } xfer += ret; *i32 = (gint32)val; return xfer; } gint32 thrift_compact_protocol_write_field_begin_internal (ThriftCompactProtocol *protocol, const gchar *name, const ThriftType field_type, const gint16 field_id, const gint8 type_override, GError **error) { gint32 ret; gint32 xfer; gint8 type_to_write; THRIFT_UNUSED_VAR (name); xfer = 0; /* if there's a type override, use that. */ type_to_write = (type_override == -1 ? TTypeToCType[field_type] : type_override); /* check if we can use delta encoding for the field id */ if (field_id > protocol->_last_field_id && field_id - protocol->_last_field_id <= 15) { /* write them together */ if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol), (gint8) ((field_id - protocol->_last_field_id) << 4 | type_to_write), error)) < 0) { return -1; } xfer += ret; } else { /* write them separate */ if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol), type_to_write, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_i16 (THRIFT_PROTOCOL (protocol), field_id, error)) < 0) { return -1; } xfer += ret; } protocol->_last_field_id = field_id; return xfer; } /** * Method for writing the start of lists and sets. List and sets on * the wire differ only by the type indicator. */ gint32 thrift_compact_protocol_write_collection_begin (ThriftCompactProtocol *protocol, const ThriftType elem_type, guint32 size, GError **error) { gint32 ret; gint32 xfer; xfer = 0; if (size <= 14) { if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol), (gint8) (size << 4 | TTypeToCType[elem_type]), error)) < 0) { return -1; } xfer += ret; } else { if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol), (gint8) (0xf0 | TTypeToCType[elem_type]), error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_compact_protocol_write_varint32 (protocol, (guint32) size, error)) < 0) { return -1; } xfer += ret; } return xfer; } /* * public methods */ gint32 thrift_compact_protocol_write_message_begin (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error) { gint8 version; gint32 ret; gint32 xfer; ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); version = (VERSION_N & VERSION_MASK) | (((gint32) message_type << TYPE_SHIFT_AMOUNT) & TYPE_MASK); xfer = 0; if ((ret = thrift_protocol_write_byte (protocol, PROTOCOL_ID, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_byte (protocol, version, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_compact_protocol_write_varint32 (cp, (guint32) seqid, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_string (protocol, name, error)) < 0) { return -1; } xfer += ret; return xfer; } gint32 thrift_compact_protocol_write_message_end (ThriftProtocol *protocol, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_write_struct_begin (ThriftProtocol *protocol, const gchar *name, GError **error) { ThriftCompactProtocol *cp; GQueue *q; /* satisfy -Wall */ THRIFT_UNUSED_VAR (name); THRIFT_UNUSED_VAR (error); g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); q = &(cp->_last_field); g_queue_push_tail (q, GINT_TO_POINTER ((gint) cp->_last_field_id)); cp->_last_field_id = 0; return 0; } gint32 thrift_compact_protocol_write_struct_end (ThriftProtocol *protocol, GError **error) { ThriftCompactProtocol *cp; GQueue *q; /* satisfy -Wall */ THRIFT_UNUSED_VAR (error); cp = THRIFT_COMPACT_PROTOCOL (protocol); q = &(cp->_last_field); g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp->_last_field_id = (gint16) GPOINTER_TO_INT (g_queue_pop_tail (q)); return 0; } gint32 thrift_compact_protocol_write_field_begin (ThriftProtocol *protocol, const gchar *name, const ThriftType field_type, const gint16 field_id, GError **error) { ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); if (field_type == T_BOOL) { cp->_bool_field_name = name; cp->_bool_field_type = field_type; cp->_bool_field_id = field_id; return 0; } else { return thrift_compact_protocol_write_field_begin_internal (cp, name, field_type, field_id, -1, error); } } gint32 thrift_compact_protocol_write_field_end (ThriftProtocol *protocol, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_write_field_stop (ThriftProtocol *protocol, GError **error) { g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); return thrift_protocol_write_byte (protocol, (gint8) T_STOP, error); } gint32 thrift_compact_protocol_write_map_begin (ThriftProtocol *protocol, const ThriftType key_type, const ThriftType value_type, const guint32 size, GError **error) { gint32 ret; gint32 xfer; ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if ((ret = thrift_compact_protocol_write_varint32 (cp, (guint32) size, error)) < 0) { return -1; } xfer += ret; if (size > 0) { if ((ret = thrift_protocol_write_byte (protocol, (gint8) (TTypeToCType[key_type] << 4 | TTypeToCType[value_type]), error)) < 0) { return -1; } xfer += ret; } return xfer; } gint32 thrift_compact_protocol_write_map_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_write_list_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); return thrift_compact_protocol_write_collection_begin (cp, element_type, size, error); } gint32 thrift_compact_protocol_write_list_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_write_set_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); return thrift_compact_protocol_write_collection_begin (cp, element_type, size, error); } gint32 thrift_compact_protocol_write_set_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_write_bool (ThriftProtocol *protocol, const gboolean value, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 xfer; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if (cp->_bool_field_name != NULL) { /* we haven't written the field header yet */ if ((ret = thrift_compact_protocol_write_field_begin_internal (cp, cp->_bool_field_name, cp->_bool_field_type, cp->_bool_field_id, (gint8) (value ? CT_BOOLEAN_TRUE : CT_BOOLEAN_FALSE), error)) < 0) { return -1; } xfer += ret; cp->_bool_field_name = NULL; } else { /* we're not part of a field, so just write the value */ if ((ret = thrift_protocol_write_byte (protocol, (gint8) (value ? CT_BOOLEAN_TRUE : CT_BOOLEAN_FALSE), error)) < 0) { return -1; } xfer += ret; } return xfer; } gint32 thrift_compact_protocol_write_byte (ThriftProtocol *protocol, const gint8 value, GError **error) { g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); if (thrift_transport_write (protocol->transport, (const gpointer) &value, 1, error)) { return 1; } else { return -1; } } gint32 thrift_compact_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value, GError **error) { ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); return thrift_compact_protocol_write_varint32 (cp, i32_to_zigzag ((gint32) value), error); } gint32 thrift_compact_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value, GError **error) { ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); return thrift_compact_protocol_write_varint32 (cp, i32_to_zigzag (value), error); } gint32 thrift_compact_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value, GError **error) { ThriftCompactProtocol *cp; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); return thrift_compact_protocol_write_varint64 (cp, i64_to_zigzag (value), error); } gint32 thrift_compact_protocol_write_double (ThriftProtocol *protocol, const gdouble value, GError **error) { guint64 bits; g_assert (sizeof (gdouble) == sizeof (guint64)); g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); bits = GUINT64_TO_LE (thrift_bitwise_cast_guint64 (value)); if (thrift_transport_write (protocol->transport, (const gpointer) &bits, 8, error)) { return 8; } else { return -1; } } gint32 thrift_compact_protocol_write_string (ThriftProtocol *protocol, const gchar *str, GError **error) { size_t len; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); len = str != NULL ? strlen (str) : 0; if (len > G_MAXINT32) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "string size (guess: %lu) is too large", (unsigned long) len); return -1; } /* write the string length + 1 which includes the null terminator */ return thrift_protocol_write_binary (protocol, (const gpointer) str, (const guint32) len, error); } gint32 thrift_compact_protocol_write_binary (ThriftProtocol *protocol, const gpointer buf, const guint32 len, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 xfer; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if ((ret = thrift_compact_protocol_write_varint32 (cp, len, error)) < 0) { return -1; } xfer += ret; if (len > 0) { /* checking len + xfer > uint_max, but we don't want to overflow while * checking for overflows. transforming to len > uint_max - xfer. */ if (len > (guint32) (G_MAXINT32 - xfer)) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "size %d + %d is too large", len, xfer); return -1; } if (thrift_transport_write (protocol->transport, (const gpointer) buf, len, error) == FALSE) { return -1; } xfer += len; } return xfer; } gint32 thrift_compact_protocol_read_message_begin (ThriftProtocol *protocol, gchar **name, ThriftMessageType *message_type, gint32 *seqid, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 xfer; gint8 protocol_id, version_and_type, version; xfer = 0; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); if ((ret = thrift_protocol_read_byte (protocol, &protocol_id, error)) < 0) { return -1; } xfer += ret; if (protocol_id != PROTOCOL_ID) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_BAD_VERSION, "bad protocol id"); return -1; } if ((ret = thrift_protocol_read_byte (protocol, &version_and_type, error)) < 0) { return -1; } xfer += ret; version = (gint8)(version_and_type & VERSION_MASK); if (version != VERSION_N) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_BAD_VERSION, "bad version and/or type"); return -1; } *message_type = (ThriftMessageType)((version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); if ((ret = thrift_compact_protocol_read_varint32 (cp, seqid, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_read_string (protocol, name, error)) < 0) { return -1; } xfer += ret; return xfer; } gint32 thrift_compact_protocol_read_message_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_read_struct_begin (ThriftProtocol *protocol, gchar **name, GError **error) { ThriftCompactProtocol *cp; GQueue *q; THRIFT_UNUSED_VAR (error); g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); q = &(cp->_last_field); *name = NULL; g_queue_push_tail (q, GINT_TO_POINTER ((gint) cp->_last_field_id)); cp->_last_field_id = 0; return 0; } gint32 thrift_compact_protocol_read_struct_end (ThriftProtocol *protocol, GError **error) { ThriftCompactProtocol *cp; GQueue *q; THRIFT_UNUSED_VAR (error); g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); q = &(cp->_last_field); cp->_last_field_id = (gint16) GPOINTER_TO_INT (g_queue_pop_tail (q)); return 0; } gint32 thrift_compact_protocol_read_field_begin (ThriftProtocol *protocol, gchar **name, ThriftType *field_type, gint16 *field_id, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 xfer; gint16 modifier; gint8 byte; gint8 type; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); THRIFT_UNUSED_VAR (name); xfer = 0; if ((ret = thrift_protocol_read_byte (protocol, &byte, error)) < 0) { return -1; } xfer += ret; type = (byte & 0x0f); /* if it's a stop, then we can return immediately, as the struct is over. */ if (type == T_STOP) { *field_type = T_STOP; *field_id = 0; return xfer; } /* mask off the 4 MSB of the type header. * it could contain a field id delta. */ modifier = (gint16)(((guint8)byte & 0xf0) >> 4); if (modifier == 0) { /* not a delta, look ahead for the zigzag varint field id. */ if ((ret = thrift_protocol_read_i16 (protocol, field_id, error)) < 0) { return -1; } xfer += ret; } else { *field_id = (gint16)(cp->_last_field_id + modifier); } if ((ret = thrift_compact_protocol_get_ttype (cp, type, error)) < 0) { return -1; } *field_type = ret; /* if this happens to be a boolean field, the value is encoded in the type */ if (type == CT_BOOLEAN_TRUE || type == CT_BOOLEAN_FALSE) { /* save the boolean value in a special instance variable. */ cp->_has_bool_value = TRUE; cp->_bool_value = (type == CT_BOOLEAN_TRUE ? TRUE : FALSE); } /* push the new field onto the field stack so we can keep the deltas going. */ cp->_last_field_id = *field_id; return xfer; } gint32 thrift_compact_protocol_read_field_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_read_map_begin (ThriftProtocol *protocol, ThriftType *key_type, ThriftType *value_type, guint32 *size, GError **error) { gint32 ret; gint32 xfer; gint8 kv_type; gint32 msize; ThriftCompactProtocol *cp; ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); kv_type = 0; msize = 0; cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if ((ret = thrift_compact_protocol_read_varint32 (cp, &msize, error)) <0) { return -1; } xfer += ret; /* still read the kv byte if negative size */ if (msize != 0) { if ((ret = thrift_protocol_read_byte (protocol, &kv_type, error)) < 0) { return -1; } xfer += ret; } if (cp->container_limit > 0 && msize > cp->container_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", msize, cp->container_limit); return -1; } else if (msize > 0) { if ((ret = thrift_compact_protocol_get_ttype (cp, (gint8)((guint8)kv_type >> 4), error)) < 0) { return -1; } *key_type = ret; if ((ret = thrift_compact_protocol_get_ttype (cp, (gint8)((guint8)kv_type & 0xf), error)) < 0) { return -1; } *value_type = ret; *size = (guint32) msize; } else if (msize == 0) { *key_type = 0; *value_type = 0; *size = 0; } else { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", msize); return -1; } if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), msize * thrift_protocol_get_min_serialized_size (protocol, *key_type, error) + msize * thrift_protocol_get_min_serialized_size (protocol, *value_type, error), error)) { return -1; } return xfer; } gint32 thrift_compact_protocol_read_map_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_read_list_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { ThriftCompactProtocol *cp; ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); gint32 ret; gint32 xfer; gint8 size_and_type; gint32 lsize; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); size_and_type = 0; xfer = 0; if ((ret = thrift_protocol_read_byte (protocol, &size_and_type, error)) < 0) { return -1; } xfer += ret; lsize = ((guint8)size_and_type >> 4) & 0x0f; if (lsize == 15) { if ((ret = thrift_compact_protocol_read_varint32 (cp, &lsize, error)) < 0) { return -1; } xfer += ret; } if (lsize < 0) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", lsize); return -1; } else if (cp->container_limit > 0 && lsize > cp->container_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", lsize, cp->container_limit); return -1; } if ((ret = thrift_compact_protocol_get_ttype (cp, (gint8)(size_and_type & 0x0f), error)) < 0) { return -1; } *element_type = ret; *size = (guint32) lsize; if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), (lsize * thrift_protocol_get_min_serialized_size (protocol, *element_type, error)), error)) { return -1; } return xfer; } gint32 thrift_compact_protocol_read_list_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_read_set_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); return thrift_protocol_read_list_begin (protocol, element_type, size, error); } gint32 thrift_compact_protocol_read_set_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_compact_protocol_read_bool (ThriftProtocol *protocol, gboolean *value, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 xfer; gint8 val; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if (cp->_has_bool_value == TRUE) { *value = cp->_bool_value; cp->_has_bool_value = FALSE; return 0; } else { if ((ret = thrift_protocol_read_byte (protocol, &val, error)) < 0) { return -1; } xfer += ret; *value = (val == CT_BOOLEAN_TRUE); return xfer; } } gint32 thrift_compact_protocol_read_byte (ThriftProtocol *protocol, gint8 *value, GError **error) { gint32 ret; gpointer b[1]; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b, 1, error)) < 0) { return -1; } *value = *(gint8 *) b; return ret; } gint32 thrift_compact_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 val; gint32 xfer; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if ((ret = thrift_compact_protocol_read_varint32 (cp, &val, error)) < 0) { return -1; } xfer += ret; *value = (gint16) zigzag_to_i32 ((guint32) val); return xfer; } gint32 thrift_compact_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 val; gint32 xfer; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if ((ret = thrift_compact_protocol_read_varint32 (cp, &val, error)) < 0) { return -1; } xfer += ret; *value = zigzag_to_i32 ((guint32) val); return xfer; } gint32 thrift_compact_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint64 val; gint32 xfer; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; if ((ret = thrift_compact_protocol_read_varint64 (cp, &val, error)) < 0) { return -1; } xfer += ret; *value = zigzag_to_i64 ((guint64) val); return xfer; } gint32 thrift_compact_protocol_read_double (ThriftProtocol *protocol, gdouble *value, GError **error) { gint32 ret; union { guint64 bits; guint8 b[8]; } u; g_assert (sizeof (gdouble) == sizeof (guint64)); g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, u.b, 8, error)) < 0) { return -1; } u.bits = GUINT64_FROM_LE (u.bits); *value = thrift_bitwise_cast_gdouble (u.bits); return ret; } gint32 thrift_compact_protocol_read_string (ThriftProtocol *protocol, gchar **str, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 xfer; gint32 read_len; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; read_len = 0; /* read the length into read_len */ if ((ret = thrift_compact_protocol_read_varint32 (cp, &read_len, error)) < 0) { return -1; } xfer += ret; if (cp->string_limit > 0 && read_len > cp->string_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", read_len, cp->string_limit); *str = NULL; return -1; } if (read_len < 0) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", read_len); *str = NULL; return -1; } ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); if (read_len > 0 && !ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), read_len, error)) { *str = NULL; return -1; } /* allocate the memory as an array of unsigned char for binary data */ *str = g_new0 (gchar, read_len + 1); if (read_len > 0) { if ((ret = thrift_transport_read_all (protocol->transport, *str, read_len, error)) < 0) { g_free (*str); *str = NULL; return -1; } xfer += ret; } else { **str = 0; } return xfer; } gint32 thrift_compact_protocol_read_binary (ThriftProtocol *protocol, gpointer *buf, guint32 *len, GError **error) { ThriftCompactProtocol *cp; gint32 ret; gint32 xfer; gint32 read_len; g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1); cp = THRIFT_COMPACT_PROTOCOL (protocol); xfer = 0; read_len = 0; /* read the length into read_len */ if ((ret = thrift_compact_protocol_read_varint32 (cp, &read_len, error)) < 0) { return -1; } xfer += ret; if (cp->string_limit > 0 && read_len > cp->string_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", read_len, cp->string_limit); *buf = NULL; *len = 0; return -1; } if (read_len > 0) { ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); if (!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), read_len, error)) { *buf = NULL; *len = 0; return -1; } /* allocate the memory as an array of unsigned char for binary data */ *len = (guint32) read_len; *buf = g_new (guchar, *len); if ((ret = thrift_transport_read_all (protocol->transport, *buf, *len, error)) < 0) { g_free (*buf); *buf = NULL; *len = 0; return -1; } xfer += ret; } else if (read_len == 0) { *len = (guint32) read_len; *buf = NULL; } else { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", read_len); *buf = NULL; *len = 0; return -1; } return xfer; } gint thrift_compact_protocol_get_min_serialized_size (ThriftProtocol *protocol, ThriftType type, GError **error) { THRIFT_UNUSED_VAR (protocol); switch (type) { case T_STOP: return 1; /* T_STOP needs to count itself */ case T_VOID: return 1; /* T_VOID needs to count itself */ case T_BOOL: return sizeof(gint8); case T_DOUBLE: return 8; case T_BYTE: return sizeof(gint8); case T_I16: return sizeof(gint8); case T_I32: return sizeof(gint8); case T_I64: return sizeof(gint8); case T_STRING: return sizeof(gint8); case T_STRUCT: return 1; /* empty struct needs at least 1 byte for the T_STOP */ case T_MAP: return sizeof(gint8); case T_SET: return sizeof(gint8); case T_LIST: return sizeof(gint8); default: g_set_error(error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_INVALID_DATA, "unrecognized type"); return -1; } } /* property accessor */ void thrift_compact_protocol_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftCompactProtocol *tc; THRIFT_UNUSED_VAR (pspec); tc = THRIFT_COMPACT_PROTOCOL (object); switch (property_id) { case PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT: g_value_set_int (value, tc->string_limit); break; case PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT: g_value_set_int (value, tc->container_limit); break; } } /* property mutator */ void thrift_compact_protocol_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftCompactProtocol *tc; THRIFT_UNUSED_VAR (pspec); tc = THRIFT_COMPACT_PROTOCOL (object); switch (property_id) { case PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT: tc->string_limit = g_value_get_int (value); break; case PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT: tc->container_limit = g_value_get_int (value); break; } } /* initialize the class */ static void thrift_compact_protocol_class_init (ThriftCompactProtocolClass *klass) { ThriftProtocolClass *cls; GObjectClass *gobject_class; GParamSpec *param_spec; cls = THRIFT_PROTOCOL_CLASS (klass); gobject_class = G_OBJECT_CLASS (klass); param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_compact_protocol_get_property; gobject_class->set_property = thrift_compact_protocol_set_property; param_spec = g_param_spec_int ("string_limit", "Max allowed string size", "Set the max string limit", 0, /* min */ G_MAXINT32, /* max */ 0, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT, param_spec); param_spec = g_param_spec_int ("container_limit", "Max allowed container size", "Set the max container limit", 0, /* min */ G_MAXINT32, /* max */ 0, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT, param_spec); cls->write_message_begin = thrift_compact_protocol_write_message_begin; cls->write_message_end = thrift_compact_protocol_write_message_end; cls->write_struct_begin = thrift_compact_protocol_write_struct_begin; cls->write_struct_end = thrift_compact_protocol_write_struct_end; cls->write_field_begin = thrift_compact_protocol_write_field_begin; cls->write_field_end = thrift_compact_protocol_write_field_end; cls->write_field_stop = thrift_compact_protocol_write_field_stop; cls->write_map_begin = thrift_compact_protocol_write_map_begin; cls->write_map_end = thrift_compact_protocol_write_map_end; cls->write_list_begin = thrift_compact_protocol_write_list_begin; cls->write_list_end = thrift_compact_protocol_write_list_end; cls->write_set_begin = thrift_compact_protocol_write_set_begin; cls->write_set_end = thrift_compact_protocol_write_set_end; cls->write_bool = thrift_compact_protocol_write_bool; cls->write_byte = thrift_compact_protocol_write_byte; cls->write_i16 = thrift_compact_protocol_write_i16; cls->write_i32 = thrift_compact_protocol_write_i32; cls->write_i64 = thrift_compact_protocol_write_i64; cls->write_double = thrift_compact_protocol_write_double; cls->write_string = thrift_compact_protocol_write_string; cls->write_binary = thrift_compact_protocol_write_binary; cls->read_message_begin = thrift_compact_protocol_read_message_begin; cls->read_message_end = thrift_compact_protocol_read_message_end; cls->read_struct_begin = thrift_compact_protocol_read_struct_begin; cls->read_struct_end = thrift_compact_protocol_read_struct_end; cls->read_field_begin = thrift_compact_protocol_read_field_begin; cls->read_field_end = thrift_compact_protocol_read_field_end; cls->read_map_begin = thrift_compact_protocol_read_map_begin; cls->read_map_end = thrift_compact_protocol_read_map_end; cls->read_list_begin = thrift_compact_protocol_read_list_begin; cls->read_list_end = thrift_compact_protocol_read_list_end; cls->read_set_begin = thrift_compact_protocol_read_set_begin; cls->read_set_end = thrift_compact_protocol_read_set_end; cls->read_bool = thrift_compact_protocol_read_bool; cls->read_byte = thrift_compact_protocol_read_byte; cls->read_i16 = thrift_compact_protocol_read_i16; cls->read_i32 = thrift_compact_protocol_read_i32; cls->read_i64 = thrift_compact_protocol_read_i64; cls->read_double = thrift_compact_protocol_read_double; cls->read_string = thrift_compact_protocol_read_string; cls->read_binary = thrift_compact_protocol_read_binary; cls->get_min_serialized_size = thrift_compact_protocol_get_min_serialized_size; } static void thrift_compact_protocol_init (ThriftCompactProtocol *self) { g_queue_init (&(self->_last_field)); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c0000664000175000017500000001444715165535636031214 0ustar00buildbuild00000000000000/* * 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 #include #include #include enum { PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME = 1, PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE, PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID, PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT, /* TODO ugly hack */ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END }; G_DEFINE_TYPE(ThriftStoredMessageProtocol, thrift_stored_message_protocol, THRIFT_TYPE_PROTOCOL_DECORATOR) static GParamSpec *thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END] = { NULL, }; gint32 thrift_stored_message_protocol_read_message_begin (ThriftProtocol *protocol, gchar **name, ThriftMessageType *message_type, gint32 *seqid, GError **error) { gint32 ret = 0; g_return_val_if_fail (THRIFT_IS_STORED_MESSAGE_PROTOCOL (protocol), -1); THRIFT_UNUSED_VAR (error); ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (protocol); /* We return the stored values on construction */ *name = g_strdup (self->name); *message_type = self->mtype; *seqid = self->seqid; return ret; } static void thrift_stored_message_protocol_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (object); switch (property_id) { case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME: self->name = g_value_dup_string (value); break; case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE: self->mtype = g_value_get_int (value); break; case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID: self->seqid = g_value_get_int (value); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void thrift_stored_message_protocol_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (object); ThriftProtocolDecorator *decorator = THRIFT_PROTOCOL_DECORATOR (object); ThriftTransport *transport=NULL; switch (property_id) { case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME: g_value_set_string (value, self->name); break; case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT: /* FIXME Since we don't override properties in the decorator as it should we just override the properties that we know are used */ g_object_get(decorator->concrete_protocol,pspec->name, &transport, NULL); g_value_set_pointer (value, transport); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void thrift_stored_message_protocol_init (ThriftStoredMessageProtocol *protocol) { protocol->name = NULL; } static void thrift_stored_message_protocol_finalize (GObject *gobject) { ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (gobject); if (self->name) { g_free(self->name); self->name = NULL; } /* Always chain up to the parent class; as with dispose(), finalize() * is guaranteed to exist on the parent's class virtual function table */ G_OBJECT_CLASS (thrift_stored_message_protocol_parent_class)->finalize(gobject); } /* initialize the class */ static void thrift_stored_message_protocol_class_init (ThriftStoredMessageProtocolClass *klass) { ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); cls->read_message_begin = thrift_stored_message_protocol_read_message_begin; object_class->set_property = thrift_stored_message_protocol_set_property; object_class->get_property = thrift_stored_message_protocol_get_property; object_class->finalize = thrift_stored_message_protocol_finalize; thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME] = g_param_spec_string ("name", "Service name the protocol points to", "Set the service name", NULL, (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE] = g_param_spec_int ("type", "Message type in the wire", "Set the message type in the wire", T_CALL, T_ONEWAY, T_CALL, (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID] = g_param_spec_int ("seqid", "Sequence id type in the wire", "Set the Sequence id in the wire", G_MININT, G_MAXINT, 0, (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); /* TODO Ugly hack, in theory we must override all properties from underlaying protocol */ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT] = g_param_spec_pointer ("transport", "Transport on the underlaying implementation", "Transport of decorated protocol", G_PARAM_READABLE); g_object_class_install_properties (object_class, PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END, thrift_stored_message_protocol_obj_properties); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c0000664000175000017500000000347615165535636031223 0ustar00buildbuild00000000000000/* * 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 G_DEFINE_TYPE(ThriftBinaryProtocolFactory, thrift_binary_protocol_factory, THRIFT_TYPE_PROTOCOL_FACTORY) ThriftProtocol * thrift_binary_protocol_factory_get_protocol (ThriftProtocolFactory *factory, ThriftTransport *transport) { ThriftBinaryProtocol *tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL); THRIFT_UNUSED_VAR (factory); return THRIFT_PROTOCOL (tb); } static void thrift_binary_protocol_factory_class_init (ThriftBinaryProtocolFactoryClass *cls) { ThriftProtocolFactoryClass *protocol_factory_class = THRIFT_PROTOCOL_FACTORY_CLASS (cls); protocol_factory_class->get_protocol = thrift_binary_protocol_factory_get_protocol; } static void thrift_binary_protocol_factory_init (ThriftBinaryProtocolFactory *factory) { THRIFT_UNUSED_VAR (factory); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h0000664000175000017500000000541015165535636031207 0ustar00buildbuild00000000000000/* * 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_STORED_MESSAGE_PROTOCOL_H #define _THRIFT_STORED_MESSAGE_PROTOCOL_H #include #include #include #include G_BEGIN_DECLS /*! \file thrift_stored_message_protocol.h * \brief StoredMessage protocol implementation of a pre-stored message header * on Thrift protocol. Implements the ThriftProtocol interface. */ /* type macros */ #define THRIFT_TYPE_STORED_MESSAGE_PROTOCOL (thrift_stored_message_protocol_get_type ()) #define THRIFT_STORED_MESSAGE_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocol)) #define THRIFT_IS_STORED_MESSAGE_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL)) #define THRIFT_STORED_MESSAGE_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocolClass)) #define THRIFT_IS_STORED_MESSAGE_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL)) #define THRIFT_STORED_MESSAGE_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocolClass)) /* constant */ #define THRIFT_STORED_MESSAGE_PROTOCOL_DEFAULT_SEPARATOR ":" typedef struct _ThriftStoredMessageProtocol ThriftStoredMessageProtocol; /*! * Thrift StoredMessage Protocol instance. */ struct _ThriftStoredMessageProtocol { ThriftProtocolDecorator parent; gchar *name; ThriftMessageType mtype; gint32 seqid; }; typedef struct _ThriftStoredMessageProtocolClass ThriftStoredMessageProtocolClass; /*! * Thrift StoredMessage Protocol class. */ struct _ThriftStoredMessageProtocolClass { ThriftProtocolDecoratorClass parent; }; /* used by THRIFT_TYPE_STORED_MESSAGE_PROTOCOL */ GType thrift_stored_message_protocol_get_type (void); G_END_DECLS #endif /* _THRIFT_STORED_MESSAGE_PROTOCOL_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h0000664000175000017500000000456015165535636031365 0ustar00buildbuild00000000000000/* * 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_COMPACT_PROTOCOL_FACTORY_H #define _THRIFT_COMPACT_PROTOCOL_FACTORY_H #include #include G_BEGIN_DECLS /* type macros */ #define THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY \ (thrift_compact_protocol_factory_get_type ()) #define THRIFT_COMPACT_PROTOCOL_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY, \ ThriftCompactProtocolFactory)) #define THRIFT_IS_COMPACT_PROTOCOL_FACTORY(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY)) #define THRIFT_COMPACT_PROTOCOL_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY, \ ThriftCompactProtocolFactoryClass)) #define THRIFT_IS_COMPACT_PROTOCOL_FACTORY_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY)) #define THRIFT_COMPACT_PROTOCOL_FACTORY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY, \ ThriftCompactProtocolFactoryClass)) typedef struct _ThriftCompactProtocolFactory ThriftCompactProtocolFactory; struct _ThriftCompactProtocolFactory { ThriftProtocolFactory parent; /* protected */ gint32 string_limit; gint32 container_limit; }; typedef struct _ThriftCompactProtocolFactoryClass ThriftCompactProtocolFactoryClass; struct _ThriftCompactProtocolFactoryClass { ThriftProtocolFactoryClass parent; }; /* used by THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY */ GType thrift_compact_protocol_factory_get_type (void); G_END_DECLS #endif /* _THRIFT_COMPACT_PROTOCOL_FACTORY_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_factory.h0000664000175000017500000000504515165535636027656 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_FACTORY_H #define _THRIFT_PROTOCOL_FACTORY_H #include #include #include G_BEGIN_DECLS /*! \file thrift_protocol_factory.h * \brief Abstract class for Thrift protocol factory implementations. */ /* type macros */ #define THRIFT_TYPE_PROTOCOL_FACTORY (thrift_protocol_factory_get_type ()) #define THRIFT_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL_FACTORY, ThriftProtocolFactory)) #define THRIFT_IS_PROTOCOL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL_FACTORY)) #define THRIFT_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL_FACTORY, ThriftProtocolFactoryClass)) #define THRIFT_IS_PROTOCOL_FACTORY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL_FACTORY)) #define THRIFT_PROTOCOL_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL_FACTORY, ThriftProtocolFactoryClass)) typedef struct _ThriftProtocolFactory ThriftProtocolFactory; /*! * Thrift Protocol Factory object */ struct _ThriftProtocolFactory { GObject parent; }; typedef struct _ThriftProtocolFactoryClass ThriftProtocolFactoryClass; /*! * Thrift Protocol Factory class */ struct _ThriftProtocolFactoryClass { GObjectClass parent; ThriftProtocol *(*get_protocol) (ThriftProtocolFactory *factory, ThriftTransport *transport); }; /* used by THRIFT_TYPE_PROTOCOL_FACTORY */ GType thrift_protocol_factory_get_type (void); /* virtual public methods */ ThriftProtocol *thrift_protocol_factory_get_protocol(ThriftProtocolFactory *factory, ThriftTransport *transport); G_END_DECLS #endif /* _THRIFT_PROTOCOL_FACTORY_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c0000664000175000017500000001143215165535636030533 0ustar00buildbuild00000000000000/* * 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 #include #include #include enum { PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME = 1, PROP_THRIFT_MULTIPLEXED_PROTOCOL_END }; G_DEFINE_TYPE(ThriftMultiplexedProtocol, thrift_multiplexed_protocol, THRIFT_TYPE_PROTOCOL_DECORATOR) static GParamSpec *thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_END] = { NULL, }; gint32 thrift_multiplexed_protocol_write_message_begin (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error) { gint32 ret; gchar *service_name = NULL; g_return_val_if_fail (THRIFT_IS_MULTIPLEXED_PROTOCOL (protocol), -1); ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (protocol); if( (message_type == T_CALL || message_type == T_ONEWAY) && self->service_name != NULL) { service_name = g_strdup_printf("%s%s%s", self->service_name, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, name); }else{ service_name = g_strdup(name); } /* relay to the protocol_decorator */ ret = thrift_protocol_decorator_write_message_begin(protocol, service_name, message_type, seqid, error); g_free(service_name); return ret; } static void thrift_multiplexed_protocol_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object); switch (property_id) { case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME: g_free(self->service_name); self->service_name = g_value_dup_string (value); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void thrift_multiplexed_protocol_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object); switch (property_id) { case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME: g_value_set_string (value, self->service_name); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void thrift_multiplexed_protocol_init (ThriftMultiplexedProtocol *protocol) { protocol->service_name = NULL; } static void thrift_multiplexed_protocol_finalize (GObject *gobject) { ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (gobject); if (self->service_name) { g_free(self->service_name); self->service_name = NULL; } /* Always chain up to the parent class; as with dispose(), finalize() * is guaranteed to exist on the parent's class virtual function table */ G_OBJECT_CLASS (thrift_multiplexed_protocol_parent_class)->finalize(gobject); } /* initialize the class */ static void thrift_multiplexed_protocol_class_init (ThriftMultiplexedProtocolClass *klass) { ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); cls->write_message_begin = thrift_multiplexed_protocol_write_message_begin; object_class->set_property = thrift_multiplexed_protocol_set_property; object_class->get_property = thrift_multiplexed_protocol_get_property; object_class->finalize = thrift_multiplexed_protocol_finalize; thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME] = g_param_spec_string ("service-name", "Service name the protocol points to", "Set the service name", NULL, (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); g_object_class_install_properties (object_class, PROP_THRIFT_MULTIPLEXED_PROTOCOL_END, thrift_multiplexed_protocol_obj_properties); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c0000664000175000017500000007354415165535636027477 0ustar00buildbuild00000000000000/* * 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 #include /* object properties */ enum _ThriftBinaryProtocolProperties { PROP_0, PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT, PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT }; G_DEFINE_TYPE(ThriftBinaryProtocol, thrift_binary_protocol, THRIFT_TYPE_PROTOCOL) static guint64 thrift_bitwise_cast_guint64 (gdouble v) { union { gdouble from; guint64 to; } u; u.from = v; return u.to; } static gdouble thrift_bitwise_cast_gdouble (guint64 v) { union { guint64 from; gdouble to; } u; u.from = v; return u.to; } gint32 thrift_binary_protocol_write_message_begin (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error) { gint32 version = (THRIFT_BINARY_PROTOCOL_VERSION_1) | ((gint32) message_type); gint32 ret; gint32 xfer = 0; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_protocol_write_i32 (protocol, version, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_string (protocol, name, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_i32 (protocol, seqid, error)) < 0) { return -1; } xfer += ret; return xfer; } gint32 thrift_binary_protocol_write_message_end (ThriftProtocol *protocol, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_write_struct_begin (ThriftProtocol *protocol, const gchar *name, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (name); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_write_struct_end (ThriftProtocol *protocol, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_write_field_begin (ThriftProtocol *protocol, const gchar *name, const ThriftType field_type, const gint16 field_id, GError **error) { gint32 ret; gint32 xfer = 0; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); THRIFT_UNUSED_VAR (name); if ((ret = thrift_protocol_write_byte (protocol, (gint8) field_type, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_i16 (protocol, field_id, error)) < 0) { return -1; } xfer += ret; return xfer; } gint32 thrift_binary_protocol_write_field_end (ThriftProtocol *protocol, GError **error) { /* satisfy -Wall */ THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_write_field_stop (ThriftProtocol *protocol, GError **error) { g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); return thrift_protocol_write_byte (protocol, (gint8) T_STOP, error); } gint32 thrift_binary_protocol_write_map_begin (ThriftProtocol *protocol, const ThriftType key_type, const ThriftType value_type, const guint32 size, GError **error) { gint32 ret; gint32 xfer = 0; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_protocol_write_byte (protocol, (gint8) key_type, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_byte (protocol, (gint8) value_type, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_i32 (protocol, (gint32) size, error)) < 0) { return -1; } xfer += ret; return xfer; } gint32 thrift_binary_protocol_write_map_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_write_list_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { gint32 ret; gint32 xfer = 0; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_protocol_write_byte (protocol, (gint8) element_type, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_write_i32 (protocol, (gint32) size, error)) < 0) { return -1; } xfer += ret; return xfer; } gint32 thrift_binary_protocol_write_list_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_write_set_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); return thrift_protocol_write_list_begin (protocol, element_type, size, error); } gint32 thrift_binary_protocol_write_set_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_write_bool (ThriftProtocol *protocol, const gboolean value, GError **error) { guint8 tmp; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); tmp = value ? 1 : 0; return thrift_protocol_write_byte (protocol, tmp, error); } gint32 thrift_binary_protocol_write_byte (ThriftProtocol *protocol, const gint8 value, GError **error) { g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if (thrift_transport_write (protocol->transport, (const gpointer) &value, 1, error)) { return 1; } else { return -1; } } gint32 thrift_binary_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value, GError **error) { gint16 net; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); net = g_htons (value); if (thrift_transport_write (protocol->transport, (const gpointer) &net, 2, error)) { return 2; } else { return -1; } } gint32 thrift_binary_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value, GError **error) { gint32 net; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); net = g_htonl (value); if (thrift_transport_write (protocol->transport, (const gpointer) &net, 4, error)) { return 4; } else { return -1; } } gint32 thrift_binary_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value, GError **error) { gint64 net; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); net = GUINT64_TO_BE (value); if (thrift_transport_write (protocol->transport, (const gpointer) &net, 8, error)) { return 8; } else { return -1; } } gint32 thrift_binary_protocol_write_double (ThriftProtocol *protocol, const gdouble value, GError **error) { guint64 bits; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); bits = GUINT64_FROM_BE (thrift_bitwise_cast_guint64 (value)); if (thrift_transport_write (protocol->transport, (const gpointer) &bits, 8, error)) { return 8; } else { return -1; } } gint32 thrift_binary_protocol_write_string (ThriftProtocol *protocol, const gchar *str, GError **error) { guint32 len; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); len = str != NULL ? strlen (str) : 0; /* write the string length + 1 which includes the null terminator */ return thrift_protocol_write_binary (protocol, (const gpointer) str, len, error); } gint32 thrift_binary_protocol_write_binary (ThriftProtocol *protocol, const gpointer buf, const guint32 len, GError **error) { gint32 ret; gint32 xfer = 0; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_protocol_write_i32 (protocol, len, error)) < 0) { return -1; } xfer += ret; if (len > 0) { if (thrift_transport_write (protocol->transport, (const gpointer) buf, len, error) == FALSE) { return -1; } xfer += len; } return xfer; } gint32 thrift_binary_protocol_read_message_begin (ThriftProtocol *protocol, gchar **name, ThriftMessageType *message_type, gint32 *seqid, GError **error) { gint32 ret; gint32 xfer = 0; gint32 sz; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_protocol_read_i32 (protocol, &sz, error)) < 0) { return -1; } xfer += ret; if (sz < 0) { /* check for version */ guint32 version = sz & THRIFT_BINARY_PROTOCOL_VERSION_MASK; if (version != THRIFT_BINARY_PROTOCOL_VERSION_1) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_BAD_VERSION, "expected version %d, got %d", THRIFT_BINARY_PROTOCOL_VERSION_1, version); return -1; } *message_type = (ThriftMessageType) (sz & 0x000000ff); if ((ret = thrift_protocol_read_string (protocol, name, error)) < 0) { return -1; } xfer += ret; if ((ret = thrift_protocol_read_i32 (protocol, seqid, error)) < 0) { return -1; } xfer += ret; } return xfer; } gint32 thrift_binary_protocol_read_message_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_read_struct_begin (ThriftProtocol *protocol, gchar **name, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); *name = NULL; return 0; } gint32 thrift_binary_protocol_read_struct_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_read_field_begin (ThriftProtocol *protocol, gchar **name, ThriftType *field_type, gint16 *field_id, GError **error) { gint32 ret; gint32 xfer = 0; gint8 type; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); THRIFT_UNUSED_VAR (name); if ((ret = thrift_protocol_read_byte (protocol, &type, error)) < 0) { return -1; } xfer += ret; *field_type = (ThriftType) type; if (*field_type == T_STOP) { *field_id = 0; return xfer; } if ((ret = thrift_protocol_read_i16 (protocol, field_id, error)) < 0) { return -1; } xfer += ret; return xfer; } gint32 thrift_binary_protocol_read_field_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_read_map_begin (ThriftProtocol *protocol, ThriftType *key_type, ThriftType *value_type, guint32 *size, GError **error) { gint32 ret; gint32 xfer = 0; gint8 k, v; gint32 sizei; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); if ((ret = thrift_protocol_read_byte (protocol, &k, error)) < 0) { return -1; } xfer += ret; *key_type = (ThriftType) k; if ((ret = thrift_protocol_read_byte (protocol, &v, error)) < 0) { return -1; } xfer += ret; *value_type = (ThriftType) v; if ((ret = thrift_protocol_read_i32 (protocol, &sizei, error)) <0) { return -1; } xfer += ret; if (sizei < 0) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", sizei); return -1; } ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); if (bp->container_limit > 0 && sizei > bp->container_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", sizei, bp->container_limit); return -1; } if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), sizei * thrift_binary_protocol_get_min_serialized_size(protocol, k, error) + sizei * thrift_binary_protocol_get_min_serialized_size(protocol, v, error), error)) { return -1; } *size = (guint32) sizei; return xfer; } gint32 thrift_binary_protocol_read_map_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_read_list_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { gint32 ret; gint32 xfer = 0; gint8 e; gint32 sizei; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); if ((ret = thrift_protocol_read_byte (protocol, &e, error)) < 0) { return -1; } xfer += ret; *element_type = (ThriftType) e; if ((ret = thrift_protocol_read_i32 (protocol, &sizei, error)) < 0) { return -1; } xfer += ret; if (sizei < 0) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", sizei); return -1; } ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); if (bp->container_limit > 0 && sizei > bp->container_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", sizei, bp->container_limit); return -1; } if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), (sizei * thrift_binary_protocol_get_min_serialized_size(protocol, e, error)), error)) { return -1; } *size = (guint32) sizei; return xfer; } gint32 thrift_binary_protocol_read_list_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_read_set_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); return thrift_protocol_read_list_begin (protocol, element_type, size, error); } gint32 thrift_binary_protocol_read_set_end (ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_binary_protocol_read_bool (ThriftProtocol *protocol, gboolean *value, GError **error) { gint32 ret; gpointer b[1]; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b, 1, error)) < 0) { return -1; } *value = *(gint8 *) b != 0; return ret; } gint32 thrift_binary_protocol_read_byte (ThriftProtocol *protocol, gint8 *value, GError **error) { gint32 ret; gpointer b[1]; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b, 1, error)) < 0) { return -1; } *value = *(gint8 *) b; return ret; } gint32 thrift_binary_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value, GError **error) { gint32 ret; union { gint8 byte_array[2]; gint16 int16; } b; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b.byte_array, 2, error)) < 0) { return -1; } *value = g_ntohs (b.int16); return ret; } gint32 thrift_binary_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value, GError **error) { gint32 ret; union { gint8 byte_array[4]; gint32 int32; } b; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b.byte_array, 4, error)) < 0) { return -1; } *value = g_ntohl (b.int32); return ret; } gint32 thrift_binary_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value, GError **error) { gint32 ret; union { gint8 byte_array[8]; gint64 int64; } b; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b.byte_array, 8, error)) < 0) { return -1; } *value = GUINT64_FROM_BE (b.int64); return ret; } gint32 thrift_binary_protocol_read_double (ThriftProtocol *protocol, gdouble *value, GError **error) { gint32 ret; union { gint8 byte_array[8]; guint64 uint64; } b; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b.byte_array, 8, error)) < 0) { return -1; } *value = thrift_bitwise_cast_gdouble (GUINT64_FROM_BE (b.uint64)); return ret; } gint32 thrift_binary_protocol_read_string (ThriftProtocol *protocol, gchar **str, GError **error) { guint32 len; gint32 ret; gint32 xfer = 0; gint32 read_len = 0; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); /* read the length into read_len */ if ((ret = thrift_protocol_read_i32 (protocol, &read_len, error)) < 0) { return -1; } xfer += ret; if (read_len < 0) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", read_len); *str = NULL; return -1; } ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); if (bp->string_limit > 0 && read_len > bp->string_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", read_len, bp->string_limit); *str = NULL; return -1; } ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), read_len, error)) { *str = NULL; return -1; } /* allocate the memory for the string */ len = (guint32) read_len + 1; /* space for null terminator */ *str = g_new0 (gchar, len); if (read_len > 0) { if ((ret = thrift_transport_read_all (protocol->transport, *str, read_len, error)) < 0) { g_free (*str); *str = NULL; len = 0; return -1; } xfer += ret; } else { **str = 0; } return xfer; } gint32 thrift_binary_protocol_read_binary (ThriftProtocol *protocol, gpointer *buf, guint32 *len, GError **error) { gint32 ret; gint32 xfer = 0; gint32 read_len = 0; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); /* read the length into read_len */ if ((ret = thrift_protocol_read_i32 (protocol, &read_len, error)) < 0) { return -1; } xfer += ret; if (read_len < 0) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, "got negative size of %d", read_len); *buf = NULL; *len = 0; return -1; } ThriftBinaryProtocol *bp = THRIFT_BINARY_PROTOCOL (protocol); if (bp->string_limit > 0 && read_len > bp->string_limit) { g_set_error (error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, "got size over limit (%d > %d)", read_len, bp->string_limit); *buf = NULL; *len = 0; return -1; } if (read_len > 0) { ThriftProtocol *tp = THRIFT_PROTOCOL (protocol); ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport); if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), read_len, error)) { *buf = NULL; *len = 0; return -1; } /* allocate the memory as an array of unsigned char for binary data */ *len = (guint32) read_len; *buf = g_new (guchar, *len); if ((ret = thrift_transport_read_all (protocol->transport, *buf, *len, error)) < 0) { g_free (*buf); *buf = NULL; *len = 0; return -1; } xfer += ret; } else { *len = (guint32) read_len; *buf = NULL; } return xfer; } gint thrift_binary_protocol_get_min_serialized_size(ThriftProtocol *protocol, ThriftType type, GError **error) { THRIFT_UNUSED_VAR (protocol); switch (type) { case T_STOP: return 1; /* T_STOP needs to count itself */ case T_VOID: return 1; /* T_VOID needs to count itself */ case T_BOOL: return sizeof(gint8); case T_BYTE: return sizeof(gint8); case T_DOUBLE: return sizeof(double); case T_I16: return sizeof(short); case T_I32: return sizeof(int); case T_I64: return sizeof(long); case T_STRING: return sizeof(int); case T_STRUCT: return 1; /* empty struct needs at least 1 byte for the T_STOP */ case T_MAP: return sizeof(int); case T_SET: return sizeof(int); case T_LIST: return sizeof(int); default: g_set_error(error, THRIFT_PROTOCOL_ERROR, THRIFT_PROTOCOL_ERROR_INVALID_DATA, "unrecognized type"); return -1; } } /* property accessor */ void thrift_binary_protocol_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftBinaryProtocol *tb; THRIFT_UNUSED_VAR (pspec); tb = THRIFT_BINARY_PROTOCOL (object); switch (property_id) { case PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT: g_value_set_int (value, tb->string_limit); break; case PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT: g_value_set_int (value, tb->container_limit); break; } } /* property mutator */ void thrift_binary_protocol_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftBinaryProtocol *tb; THRIFT_UNUSED_VAR (pspec); tb = THRIFT_BINARY_PROTOCOL (object); switch (property_id) { case PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT: tb->string_limit = g_value_get_int (value); break; case PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT: tb->container_limit = g_value_get_int (value); break; } } static void thrift_binary_protocol_init (ThriftBinaryProtocol *protocol) { THRIFT_UNUSED_VAR (protocol); } /* initialize the class */ static void thrift_binary_protocol_class_init (ThriftBinaryProtocolClass *klass) { ThriftProtocolClass *cls; GObjectClass *gobject_class; GParamSpec *param_spec; cls = THRIFT_PROTOCOL_CLASS (klass); gobject_class = G_OBJECT_CLASS (klass); param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_binary_protocol_get_property; gobject_class->set_property = thrift_binary_protocol_set_property; param_spec = g_param_spec_int ("string_limit", "Max allowed string size", "Set the max string limit", 0, /* min */ G_MAXINT32, /* max */ 0, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_BINARY_PROTOCOL_STRING_LIMIT, param_spec); param_spec = g_param_spec_int ("container_limit", "Max allowed container size", "Set the max container limit", 0, /* min */ G_MAXINT32, /* max */ 0, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_BINARY_PROTOCOL_CONTAINER_LIMIT, param_spec); cls->write_message_begin = thrift_binary_protocol_write_message_begin; cls->write_message_end = thrift_binary_protocol_write_message_end; cls->write_struct_begin = thrift_binary_protocol_write_struct_begin; cls->write_struct_end = thrift_binary_protocol_write_struct_end; cls->write_field_begin = thrift_binary_protocol_write_field_begin; cls->write_field_end = thrift_binary_protocol_write_field_end; cls->write_field_stop = thrift_binary_protocol_write_field_stop; cls->write_map_begin = thrift_binary_protocol_write_map_begin; cls->write_map_end = thrift_binary_protocol_write_map_end; cls->write_list_begin = thrift_binary_protocol_write_list_begin; cls->write_list_end = thrift_binary_protocol_write_list_end; cls->write_set_begin = thrift_binary_protocol_write_set_begin; cls->write_set_end = thrift_binary_protocol_write_set_end; cls->write_bool = thrift_binary_protocol_write_bool; cls->write_byte = thrift_binary_protocol_write_byte; cls->write_i16 = thrift_binary_protocol_write_i16; cls->write_i32 = thrift_binary_protocol_write_i32; cls->write_i64 = thrift_binary_protocol_write_i64; cls->write_double = thrift_binary_protocol_write_double; cls->write_string = thrift_binary_protocol_write_string; cls->write_binary = thrift_binary_protocol_write_binary; cls->read_message_begin = thrift_binary_protocol_read_message_begin; cls->read_message_end = thrift_binary_protocol_read_message_end; cls->read_struct_begin = thrift_binary_protocol_read_struct_begin; cls->read_struct_end = thrift_binary_protocol_read_struct_end; cls->read_field_begin = thrift_binary_protocol_read_field_begin; cls->read_field_end = thrift_binary_protocol_read_field_end; cls->read_map_begin = thrift_binary_protocol_read_map_begin; cls->read_map_end = thrift_binary_protocol_read_map_end; cls->read_list_begin = thrift_binary_protocol_read_list_begin; cls->read_list_end = thrift_binary_protocol_read_list_end; cls->read_set_begin = thrift_binary_protocol_read_set_begin; cls->read_set_end = thrift_binary_protocol_read_set_end; cls->read_bool = thrift_binary_protocol_read_bool; cls->read_byte = thrift_binary_protocol_read_byte; cls->read_i16 = thrift_binary_protocol_read_i16; cls->read_i32 = thrift_binary_protocol_read_i32; cls->read_i64 = thrift_binary_protocol_read_i64; cls->read_double = thrift_binary_protocol_read_double; cls->read_string = thrift_binary_protocol_read_string; cls->read_binary = thrift_binary_protocol_read_binary; cls->get_min_serialized_size = thrift_binary_protocol_get_min_serialized_size; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h0000664000175000017500000000532615165535636030173 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_DECORATOR_H #define _THRIFT_PROTOCOL_DECORATOR_H #include #include #include G_BEGIN_DECLS /*! \file thrift_protocol_decorator.h * \brief Multiplexed protocol implementation of a Thrift protocol. Implements the * ThriftProtocol interface. */ /* type macros */ #define THRIFT_TYPE_PROTOCOL_DECORATOR (thrift_protocol_decorator_get_type ()) #define THRIFT_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecorator)) #define THRIFT_IS_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR)) #define THRIFT_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass)) #define THRIFT_IS_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL_DECORATOR)) #define THRIFT_PROTOCOL_DECORATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass)) typedef struct _ThriftProtocolDecorator ThriftProtocolDecorator; /*! * Thrift Protocol Decorator instance. */ struct _ThriftProtocolDecorator { ThriftProtocol parent; ThriftProtocol *concrete_protocol; }; typedef struct _ThriftProtocolDecoratorClass ThriftProtocolDecoratorClass; /*! * Thrift Protocol Decorator class. */ struct _ThriftProtocolDecoratorClass { ThriftProtocolClass parent; }; /* used by THRIFT_TYPE_PROTOCOL_DECORATOR */ GType thrift_protocol_decorator_get_type (void); gint32 thrift_protocol_decorator_write_message_begin (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error); G_END_DECLS #endif /* _THRIFT_PROTOCOL_DECORATOR_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c0000664000175000017500000001155215165535636031357 0ustar00buildbuild00000000000000/* * 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 /* object properties */ enum _ThriftCompactProtocolFactoryProperties { PROP_0, PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT, PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT }; G_DEFINE_TYPE (ThriftCompactProtocolFactory, thrift_compact_protocol_factory, THRIFT_TYPE_PROTOCOL_FACTORY) ThriftProtocol * thrift_compact_protocol_factory_get_protocol (ThriftProtocolFactory *factory, ThriftTransport *transport) { ThriftCompactProtocolFactory *tcf; ThriftCompactProtocol *tc; tcf = THRIFT_COMPACT_PROTOCOL_FACTORY (factory); tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", transport, "string_limit", tcf->string_limit, "container_limit", tcf->container_limit, NULL); return THRIFT_PROTOCOL (tc); } /* property accessor */ void thrift_compact_protocol_factory_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftCompactProtocolFactory *tcf; THRIFT_UNUSED_VAR (pspec); tcf = THRIFT_COMPACT_PROTOCOL_FACTORY (object); switch (property_id) { case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT: g_value_set_int (value, tcf->string_limit); break; case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT: g_value_set_int (value, tcf->container_limit); break; } } /* property mutator */ void thrift_compact_protocol_factory_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftCompactProtocolFactory *tcf; THRIFT_UNUSED_VAR (pspec); tcf = THRIFT_COMPACT_PROTOCOL_FACTORY (object); switch (property_id) { case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT: tcf->string_limit = g_value_get_int (value); break; case PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT: tcf->container_limit = g_value_get_int (value); break; } } static void thrift_compact_protocol_factory_class_init (ThriftCompactProtocolFactoryClass *klass) { ThriftProtocolFactoryClass *cls; GObjectClass *gobject_class; GParamSpec *param_spec; cls = THRIFT_PROTOCOL_FACTORY_CLASS (klass); gobject_class = G_OBJECT_CLASS (klass); param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_compact_protocol_factory_get_property; gobject_class->set_property = thrift_compact_protocol_factory_set_property; param_spec = g_param_spec_int ("string_limit", "Max allowed string size", "Set the max string limit", 0, /* min */ G_MAXINT32, /* max */ 0, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_STRING_LIMIT, param_spec); param_spec = g_param_spec_int ("container_limit", "Max allowed container size", "Set the max container limit", 0, /* min */ G_MAXINT32, /* max */ 0, /* default value */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_COMPACT_PROTOCOL_FACTORY_CONTAINER_LIMIT, param_spec); cls->get_protocol = thrift_compact_protocol_factory_get_protocol; } static void thrift_compact_protocol_factory_init (ThriftCompactProtocolFactory *factory) { THRIFT_UNUSED_VAR (factory); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c0000664000175000017500000006041615165535636030167 0ustar00buildbuild00000000000000/* * 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 #include #include #include G_DEFINE_TYPE(ThriftProtocolDecorator, thrift_protocol_decorator, THRIFT_TYPE_PROTOCOL) enum { PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL = 1, PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END }; static GParamSpec *thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END] = { NULL, }; gint32 thrift_protocol_decorator_write_message_begin (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); ThriftProtocolClass *proto = THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol); g_debug("Concrete protocol %p | %p", (void *)self->concrete_protocol, (void *)proto); return proto->write_message_begin (self->concrete_protocol, name, message_type, seqid, error); } gint32 thrift_protocol_decorator_write_message_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_message_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_write_struct_begin (ThriftProtocol *protocol, const gchar *name, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_begin (self->concrete_protocol, name, error); } gint32 thrift_protocol_decorator_write_struct_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_write_field_begin (ThriftProtocol *protocol, const gchar *name, const ThriftType field_type, const gint16 field_id, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_begin (self->concrete_protocol, name, field_type, field_id, error); } gint32 thrift_protocol_decorator_write_field_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_write_field_stop (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_stop (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_write_map_begin (ThriftProtocol *protocol, const ThriftType key_type, const ThriftType value_type, const guint32 size, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_begin (self->concrete_protocol, key_type, value_type, size, error); } gint32 thrift_protocol_decorator_write_map_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_write_list_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_begin (self->concrete_protocol, element_type, size, error); } gint32 thrift_protocol_decorator_write_list_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_write_set_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_begin (self->concrete_protocol, element_type, size, error); } gint32 thrift_protocol_decorator_write_set_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_write_bool (ThriftProtocol *protocol, const gboolean value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_bool (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_write_byte (ThriftProtocol *protocol, const gint8 value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_byte (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_write_i16 (ThriftProtocol *protocol, const gint16 value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i16 (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_write_i32 (ThriftProtocol *protocol, const gint32 value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i32 (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_write_i64 (ThriftProtocol *protocol, const gint64 value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i64 (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_write_double (ThriftProtocol *protocol, const gdouble value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_double (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_write_string (ThriftProtocol *protocol, const gchar *str, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_string (self->concrete_protocol, str, error); } gint32 thrift_protocol_decorator_write_binary (ThriftProtocol *protocol, const gpointer buf, const guint32 len, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_binary (self->concrete_protocol, buf, len, error); } gint32 thrift_protocol_decorator_read_message_begin (ThriftProtocol *protocol, gchar **name, ThriftMessageType *message_type, gint32 *seqid, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_begin (self->concrete_protocol, name, message_type, seqid, error); } gint32 thrift_protocol_decorator_read_message_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_read_struct_begin (ThriftProtocol *protocol, gchar **name, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_begin (self->concrete_protocol, name, error); } gint32 thrift_protocol_decorator_read_struct_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_read_field_begin (ThriftProtocol *protocol, gchar **name, ThriftType *field_type, gint16 *field_id, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_begin (self->concrete_protocol, name, field_type, field_id, error); } gint32 thrift_protocol_decorator_read_field_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_read_map_begin (ThriftProtocol *protocol, ThriftType *key_type, ThriftType *value_type, guint32 *size, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_begin (self->concrete_protocol, key_type, value_type, size, error); } gint32 thrift_protocol_decorator_read_map_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_read_list_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_begin (self->concrete_protocol, element_type, size, error); } gint32 thrift_protocol_decorator_read_list_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_read_set_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_begin (self->concrete_protocol, element_type, size, error); } gint32 thrift_protocol_decorator_read_set_end (ThriftProtocol *protocol, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_end (self->concrete_protocol, error); } gint32 thrift_protocol_decorator_read_bool (ThriftProtocol *protocol, gboolean *value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_bool (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_read_byte (ThriftProtocol *protocol, gint8 *value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_byte (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_read_i16 (ThriftProtocol *protocol, gint16 *value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i16 (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_read_i32 (ThriftProtocol *protocol, gint32 *value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i32 (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_read_i64 (ThriftProtocol *protocol, gint64 *value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i64 (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_read_double (ThriftProtocol *protocol, gdouble *value, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_double (self->concrete_protocol, value, error); } gint32 thrift_protocol_decorator_read_string (ThriftProtocol *protocol, gchar **str, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_string (self->concrete_protocol, str, error); } gint32 thrift_protocol_decorator_read_binary (ThriftProtocol *protocol, gpointer *buf, guint32 *len, GError **error) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_binary (self->concrete_protocol, buf, len, error); } static void thrift_protocol_decorator_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object); switch (property_id) { case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL: self->concrete_protocol = g_value_dup_object (value); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void thrift_protocol_decorator_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object); switch (property_id) { case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL: g_value_set_object (value, self->concrete_protocol); break; default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } ThriftProtocol * thrift_protocol_decorator_get_concrete_protocol(ThriftProtocolDecorator *protocol) { ThriftProtocol *retval = NULL; if(!THRIFT_IS_PROTOCOL_DECORATOR(protocol)){ g_warning("The type is not protocol decorator"); return NULL; } ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR(protocol); g_debug("Getting concrete protocol from %p -> %p", (void *)self, (void *)self->concrete_protocol); return retval; } static void thrift_protocol_decorator_init (ThriftProtocolDecorator *protocol) { protocol->concrete_protocol = NULL; } static void thrift_protocol_decorator_dispose (GObject *gobject) { ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (gobject); g_clear_object(&self->concrete_protocol); /* Always chain up to the parent class; there is no need to check if * the parent class implements the dispose() virtual function: it is * always guaranteed to do so */ G_OBJECT_CLASS (thrift_protocol_decorator_parent_class)->dispose(gobject); } /* initialize the class */ static void thrift_protocol_decorator_class_init (ThriftProtocolDecoratorClass *klass) { ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = thrift_protocol_decorator_set_property; object_class->get_property = thrift_protocol_decorator_get_property; object_class->dispose = thrift_protocol_decorator_dispose; thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL] = g_param_spec_object ("protocol", "Protocol", "Set the protocol to be implemented", THRIFT_TYPE_PROTOCOL, (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); g_object_class_install_properties (object_class, PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END, thrift_protocol_decorator_obj_properties); g_debug("Current decorator write_message_begin addr %p, new %p", cls->write_message_begin, thrift_protocol_decorator_write_message_begin); cls->write_message_begin = thrift_protocol_decorator_write_message_begin; cls->write_message_end = thrift_protocol_decorator_write_message_end; cls->write_struct_begin = thrift_protocol_decorator_write_struct_begin; cls->write_struct_end = thrift_protocol_decorator_write_struct_end; cls->write_field_begin = thrift_protocol_decorator_write_field_begin; cls->write_field_end = thrift_protocol_decorator_write_field_end; cls->write_field_stop = thrift_protocol_decorator_write_field_stop; cls->write_map_begin = thrift_protocol_decorator_write_map_begin; cls->write_map_end = thrift_protocol_decorator_write_map_end; cls->write_list_begin = thrift_protocol_decorator_write_list_begin; cls->write_list_end = thrift_protocol_decorator_write_list_end; cls->write_set_begin = thrift_protocol_decorator_write_set_begin; cls->write_set_end = thrift_protocol_decorator_write_set_end; cls->write_bool = thrift_protocol_decorator_write_bool; cls->write_byte = thrift_protocol_decorator_write_byte; cls->write_i16 = thrift_protocol_decorator_write_i16; cls->write_i32 = thrift_protocol_decorator_write_i32; cls->write_i64 = thrift_protocol_decorator_write_i64; cls->write_double = thrift_protocol_decorator_write_double; cls->write_string = thrift_protocol_decorator_write_string; cls->write_binary = thrift_protocol_decorator_write_binary; cls->read_message_begin = thrift_protocol_decorator_read_message_begin; cls->read_message_end = thrift_protocol_decorator_read_message_end; cls->read_struct_begin = thrift_protocol_decorator_read_struct_begin; cls->read_struct_end = thrift_protocol_decorator_read_struct_end; cls->read_field_begin = thrift_protocol_decorator_read_field_begin; cls->read_field_end = thrift_protocol_decorator_read_field_end; cls->read_map_begin = thrift_protocol_decorator_read_map_begin; cls->read_map_end = thrift_protocol_decorator_read_map_end; cls->read_list_begin = thrift_protocol_decorator_read_list_begin; cls->read_list_end = thrift_protocol_decorator_read_list_end; cls->read_set_begin = thrift_protocol_decorator_read_set_begin; cls->read_set_end = thrift_protocol_decorator_read_set_end; cls->read_bool = thrift_protocol_decorator_read_bool; cls->read_byte = thrift_protocol_decorator_read_byte; cls->read_i16 = thrift_protocol_decorator_read_i16; cls->read_i32 = thrift_protocol_decorator_read_i32; cls->read_i64 = thrift_protocol_decorator_read_i64; cls->read_double = thrift_protocol_decorator_read_double; cls->read_string = thrift_protocol_decorator_read_string; cls->read_binary = thrift_protocol_decorator_read_binary; } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol.h0000664000175000017500000003506015165535636026127 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_H #define _THRIFT_PROTOCOL_H #include #include G_BEGIN_DECLS /*! \file thrift_protocol.h * \brief Abstract class for Thrift protocol implementations. */ /** * Enumerated definition of the types that the Thrift protocol supports. * Take special note of the T_END type which is used specifically to mark * the end of a sequence of fields. */ typedef enum { T_STOP = 0, T_VOID = 1, T_BOOL = 2, T_BYTE = 3, T_I08 = 3, T_I16 = 6, T_I32 = 8, T_U64 = 9, T_I64 = 10, T_DOUBLE = 4, T_STRING = 11, T_UTF7 = 11, T_STRUCT = 12, T_MAP = 13, T_SET = 14, T_LIST = 15, T_UTF8 = 16, T_UTF16 = 17 } ThriftType; /** * Enumerated definition of the message types that the Thrift protocol * supports. */ typedef enum { T_CALL = 1, T_REPLY = 2, T_EXCEPTION = 3, T_ONEWAY = 4 } ThriftMessageType; /* type macros */ #define THRIFT_TYPE_PROTOCOL (thrift_protocol_get_type ()) #define THRIFT_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL, ThriftProtocol)) #define THRIFT_IS_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL)) #define THRIFT_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL, ThriftProtocolClass)) #define THRIFT_IS_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL)) #define THRIFT_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL, ThriftProtocolClass)) typedef struct _ThriftProtocol ThriftProtocol; /*! * Thrift Protocol object */ struct _ThriftProtocol { GObject parent; /* protected */ ThriftTransport *transport; }; typedef struct _ThriftProtocolClass ThriftProtocolClass; /*! * Thrift Protocol class */ struct _ThriftProtocolClass { GObjectClass parent; gint32 (*write_message_begin) (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error); gint32 (*write_message_end) (ThriftProtocol *protocol, GError **error); gint32 (*write_struct_begin) (ThriftProtocol *protocol, const gchar *name, GError **error); gint32 (*write_struct_end) (ThriftProtocol *protocol, GError **error); gint32 (*write_field_begin) (ThriftProtocol *protocol, const gchar *name, const ThriftType field_type, const gint16 field_id, GError **error); gint32 (*write_field_end) (ThriftProtocol *protocol, GError **error); gint32 (*write_field_stop) (ThriftProtocol *protocol, GError **error); gint32 (*write_map_begin) (ThriftProtocol *protocol, const ThriftType key_type, const ThriftType value_type, const guint32 size, GError **error); gint32 (*write_map_end) (ThriftProtocol *protocol, GError **error); gint32 (*write_list_begin) (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error); gint32 (*write_list_end) (ThriftProtocol *protocol, GError **error); gint32 (*write_set_begin) (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error); gint32 (*write_set_end) (ThriftProtocol *protocol, GError **error); gint32 (*write_bool) (ThriftProtocol *protocol, const gboolean value, GError **error); gint32 (*write_byte) (ThriftProtocol *protocol, const gint8 value, GError **error); gint32 (*write_i16) (ThriftProtocol *protocol, const gint16 value, GError **error); gint32 (*write_i32) (ThriftProtocol *protocol, const gint32 value, GError **error); gint32 (*write_i64) (ThriftProtocol *protocol, const gint64 value, GError **error); gint32 (*write_double) (ThriftProtocol *protocol, const gdouble value, GError **error); gint32 (*write_string) (ThriftProtocol *protocol, const gchar *str, GError **error); gint32 (*write_binary) (ThriftProtocol *protocol, const gpointer buf, const guint32 len, GError **error); gint32 (*read_message_begin) (ThriftProtocol *thrift_protocol, gchar **name, ThriftMessageType *message_type, gint32 *seqid, GError **error); gint32 (*read_message_end) (ThriftProtocol *protocol, GError **error); gint32 (*read_struct_begin) (ThriftProtocol *protocol, gchar **name, GError **error); gint32 (*read_struct_end) (ThriftProtocol *protocol, GError **error); gint32 (*read_field_begin) (ThriftProtocol *protocol, gchar **name, ThriftType *field_type, gint16 *field_id, GError **error); gint32 (*read_field_end) (ThriftProtocol *protocol, GError **error); gint32 (*read_map_begin) (ThriftProtocol *protocol, ThriftType *key_type, ThriftType *value_type, guint32 *size, GError **error); gint32 (*read_map_end) (ThriftProtocol *protocol, GError **error); gint32 (*read_list_begin) (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error); gint32 (*read_list_end) (ThriftProtocol *protocol, GError **error); gint32 (*read_set_begin) (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error); gint32 (*read_set_end) (ThriftProtocol *protocol, GError **error); gint32 (*read_bool) (ThriftProtocol *protocol, gboolean *value, GError **error); gint32 (*read_byte) (ThriftProtocol *protocol, gint8 *value, GError **error); gint32 (*read_i16) (ThriftProtocol *protocol, gint16 *value, GError **error); gint32 (*read_i32) (ThriftProtocol *protocol, gint32 *value, GError **error); gint32 (*read_i64) (ThriftProtocol *protocol, gint64 *value, GError **error); gint32 (*read_double) (ThriftProtocol *protocol, gdouble *value, GError **error); gint32 (*read_string) (ThriftProtocol *protocol, gchar **str, GError **error); gint32 (*read_binary) (ThriftProtocol *protocol, gpointer *buf, guint32 *len, GError **error); gint (*get_min_serialized_size) (ThriftProtocol *protocol, ThriftType type, GError **error); }; /* used by THRIFT_TYPE_PROTOCOL */ GType thrift_protocol_get_type (void); /* virtual public methods */ gint32 thrift_protocol_write_message_begin (ThriftProtocol *protocol, const gchar *name, const ThriftMessageType message_type, const gint32 seqid, GError **error); gint32 thrift_protocol_write_message_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_write_struct_begin (ThriftProtocol *protocol, const gchar *name, GError **error); gint32 thrift_protocol_write_struct_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_write_field_begin (ThriftProtocol *protocol, const gchar *name, const ThriftType field_type, const gint16 field_id, GError **error); gint32 thrift_protocol_write_field_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_write_field_stop (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_write_map_begin (ThriftProtocol *protocol, const ThriftType key_type, const ThriftType value_type, const guint32 size, GError **error); gint32 thrift_protocol_write_map_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_write_list_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error); gint32 thrift_protocol_write_list_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_write_set_begin (ThriftProtocol *protocol, const ThriftType element_type, const guint32 size, GError **error); gint32 thrift_protocol_write_set_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_write_bool (ThriftProtocol *protocol, const gboolean value, GError **error); gint32 thrift_protocol_write_byte (ThriftProtocol *protocol, const gint8 value, GError **error); gint32 thrift_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value, GError **error); gint32 thrift_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value, GError **error); gint32 thrift_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value, GError **error); gint32 thrift_protocol_write_double (ThriftProtocol *protocol, const gdouble value, GError **error); gint32 thrift_protocol_write_string (ThriftProtocol *protocol, const gchar *str, GError **error); gint32 thrift_protocol_write_binary (ThriftProtocol *protocol, const gpointer buf, const guint32 len, GError **error); gint32 thrift_protocol_read_message_begin (ThriftProtocol *thrift_protocol, gchar **name, ThriftMessageType *message_type, gint32 *seqid, GError **error); gint32 thrift_protocol_read_message_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_read_struct_begin (ThriftProtocol *protocol, gchar **name, GError **error); gint32 thrift_protocol_read_struct_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_read_field_begin (ThriftProtocol *protocol, gchar **name, ThriftType *field_type, gint16 *field_id, GError **error); gint32 thrift_protocol_read_field_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_read_map_begin (ThriftProtocol *protocol, ThriftType *key_type, ThriftType *value_type, guint32 *size, GError **error); gint32 thrift_protocol_read_map_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_read_list_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error); gint32 thrift_protocol_read_list_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_read_set_begin (ThriftProtocol *protocol, ThriftType *element_type, guint32 *size, GError **error); gint32 thrift_protocol_read_set_end (ThriftProtocol *protocol, GError **error); gint32 thrift_protocol_read_bool (ThriftProtocol *protocol, gboolean *value, GError **error); gint32 thrift_protocol_read_byte (ThriftProtocol *protocol, gint8 *value, GError **error); gint32 thrift_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value, GError **error); gint32 thrift_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value, GError **error); gint32 thrift_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value, GError **error); gint32 thrift_protocol_read_double (ThriftProtocol *protocol, gdouble *value, GError **error); gint32 thrift_protocol_read_string (ThriftProtocol *protocol, gchar **str, GError **error); gint32 thrift_protocol_read_binary (ThriftProtocol *protocol, gpointer *buf, guint32 *len, GError **error); gint thrift_protocol_get_min_serialized_size (ThriftProtocol *protocol, ThriftType type, GError **error); gint32 thrift_protocol_skip (ThriftProtocol *protocol, ThriftType type, GError **error); /* define error types */ typedef enum { THRIFT_PROTOCOL_ERROR_UNKNOWN, THRIFT_PROTOCOL_ERROR_INVALID_DATA, THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE, THRIFT_PROTOCOL_ERROR_SIZE_LIMIT, THRIFT_PROTOCOL_ERROR_BAD_VERSION, THRIFT_PROTOCOL_ERROR_NOT_IMPLEMENTED, THRIFT_PROTOCOL_ERROR_DEPTH_LIMIT } ThriftProtocolError; /* define an error domain for GError to use */ GQuark thrift_protocol_error_quark (void); #define THRIFT_PROTOCOL_ERROR (thrift_protocol_error_quark ()) G_END_DECLS #endif /* _THRIFT_PROTOCOL_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.h0000664000175000017500000000605615165535636027640 0ustar00buildbuild00000000000000/* * 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_COMPACT_PROTOCOL_H #define _THRIFT_COMPACT_PROTOCOL_H #include #include #include #include G_BEGIN_DECLS /*! \file thrift_compact_protocol.h * \brief Compact protocol implementation of a Thrift protocol. Implements the * ThriftProtocol interface. */ /* type macros */ #define THRIFT_TYPE_COMPACT_PROTOCOL (thrift_compact_protocol_get_type ()) #define THRIFT_COMPACT_PROTOCOL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_COMPACT_PROTOCOL, \ ThriftCompactProtocol)) #define THRIFT_IS_COMPACT_PROTOCOL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_COMPACT_PROTOCOL)) #define THRIFT_COMPACT_PROTOCOL_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_COMPACT_PROTOCOL, \ ThriftCompactProtocolClass)) #define THRIFT_IS_COMPACT_PROTOCOL_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_COMPACT_PROTOCOL)) #define THRIFT_COMPACT_PROTOCOL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_COMPACT_PROTOCOL, \ ThriftCompactProtocolClass)) typedef struct _ThriftCompactProtocol ThriftCompactProtocol; /*! * Thrift Compact Protocol instance. */ struct _ThriftCompactProtocol { ThriftProtocol parent; /* protected */ gint32 string_limit; gint32 container_limit; /* private */ /** * (Writing) If we encounter a boolean field begin, save the TField here * so it can have the value incorporated. */ const gchar* _bool_field_name; ThriftType _bool_field_type; gint16 _bool_field_id; /** * (Reading) If we read a field header, and it's a boolean field, save * the boolean value here so that read_bool can use it. */ gboolean _has_bool_value; gboolean _bool_value; /** * Used to keep track of the last field for the current and previous structs, * so we can do the delta stuff. */ GQueue _last_field; gint16 _last_field_id; }; typedef struct _ThriftCompactProtocolClass ThriftCompactProtocolClass; /*! * Thrift Compact Protocol class. */ struct _ThriftCompactProtocolClass { ThriftProtocolClass parent; }; /* used by THRIFT_TYPE_COMPACT_PROTOCOL */ GType thrift_compact_protocol_get_type (void); G_END_DECLS #endif /* _THRIFT_COMPACT_PROTOCOL_H */ thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift.c0000664000175000017500000000426415165535636022342 0ustar00buildbuild00000000000000/* * 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 /** * GHashTable callback to add keys to a GList. */ void thrift_hash_table_get_keys (gpointer key, gpointer value, gpointer user_data) { GList **list = (GList **) user_data; THRIFT_UNUSED_VAR (value); *list = g_list_append (*list, key); } void thrift_safe_hash_table_destroy(GHashTable* hash_table) { if (hash_table) { g_hash_table_destroy(hash_table); } } guint thrift_boolean_hash(gconstpointer v) { const gboolean* p = v; return p && *p ? 1 : 0; } gboolean thrift_boolean_equal(gconstpointer a, gconstpointer b) { if (a == b) { return TRUE; } if (!a || !b) { return FALSE; } const gboolean* pa = a; const gboolean* pb = b; return *pa == *pb; } guint thrift_int8_hash(gconstpointer v) { const gint8* p = v; return p ? *p : 0; } gboolean thrift_int8_equal(gconstpointer a, gconstpointer b) { if (a == b) { return TRUE; } if (!a || !b) { return FALSE; } const gint8* pa = a; const gint8* pb = b; return *pa == *pb; } guint thrift_int16_hash(gconstpointer v) { const gint16* p = v; return p ? *p : 0; } gboolean thrift_int16_equal(gconstpointer a, gconstpointer b) { if (a == b) { return TRUE; } if (!a || !b) { return FALSE; } const gint16* pa = a; const gint16* pb = b; return *pa == *pb; } void thrift_string_free (gpointer str) { GByteArray* ptr = str; g_byte_array_unref(ptr); } thrift-0.23.0/lib/c_glib/src/thrift/c_glib/thrift_configuration.c0000664000175000017500000001136715165535636025273 0ustar00buildbuild00000000000000/* * 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 distuributed 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 "thrift_configuration.h" /* object properties */ enum _ThriftConfigurationProperties { PROP_0, PROP_THRIFT_CONFIGURATION_MAX_MESSAGE_SIZE, PROP_THRIFT_CONFIGURATION_MAX_FRAME_SIZE, PROP_THRIFT_CONFIGURATION_RECURSION_LIMIT }; G_DEFINE_TYPE(ThriftConfiguration, thrift_configuration, G_TYPE_OBJECT) /* property accessor */ void thrift_configuration_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { ThriftConfiguration *configuration = THRIFT_CONFIGURATION(object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_CONFIGURATION_MAX_MESSAGE_SIZE: g_value_set_int(value, configuration->maxMessageSize_); break; case PROP_THRIFT_CONFIGURATION_MAX_FRAME_SIZE: g_value_set_int(value, configuration->maxFrameSize_); break; case PROP_THRIFT_CONFIGURATION_RECURSION_LIMIT: g_value_set_int(value, configuration->recursionLimit_); break; } } /* property mutator */ void thrift_configuration_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { ThriftConfiguration *configuration = THRIFT_CONFIGURATION (object); THRIFT_UNUSED_VAR (pspec); switch (property_id) { case PROP_THRIFT_CONFIGURATION_MAX_MESSAGE_SIZE: configuration->maxMessageSize_ = g_value_get_int (value); break; case PROP_THRIFT_CONFIGURATION_MAX_FRAME_SIZE: configuration->maxFrameSize_ = g_value_get_int (value); break; case PROP_THRIFT_CONFIGURATION_RECURSION_LIMIT: configuration->recursionLimit_ = g_value_get_int (value); break; } } static void thrift_configuration_class_init (ThriftConfigurationClass *cls) { GObjectClass *gobject_class = G_OBJECT_CLASS (cls); GParamSpec *param_spec = NULL; /* setup accessors and mutators */ gobject_class->get_property = thrift_configuration_get_property; gobject_class->set_property = thrift_configuration_set_property; param_spec = g_param_spec_int ("max_message_size", "max_message_size (construct)", "Set the max size of the message", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_MESSAGE_SIZE, /* default by convention */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_CONFIGURATION_MAX_MESSAGE_SIZE, param_spec); param_spec = g_param_spec_int ("max_frame_size", "max_frame_size (construct)", "Set the max size of the frame", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_MAX_FRAME_SIZE, /* default by convention */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_CONFIGURATION_MAX_FRAME_SIZE, param_spec); param_spec = g_param_spec_int ("recursion_limit", "recursion_limit (construct)", "Set the limit of the resursion", 0, /* min */ G_MAXINT32, /* max */ DEFAULT_RECURSION_DEPTH, /* default by convention */ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_THRIFT_CONFIGURATION_RECURSION_LIMIT, param_spec); } static void thrift_configuration_init (ThriftConfiguration *configuration) { THRIFT_UNUSED_VAR (configuration); } thrift-0.23.0/lib/c_glib/thrift_c_glib.pc.in0000664000175000017500000000177015165535636021117 0ustar00buildbuild00000000000000# # 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. # prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Thrift Description: Thrift C API Version: @VERSION@ Requires: glib-2.0 gobject-2.0 Libs: -L${libdir} -lthrift_c_glib Cflags: -I${includedir} thrift-0.23.0/lib/c_glib/test/0000755000175000017500000000000015170007200016310 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/test/teststruct.c0000664000175000017500000000636115165535636020737 0ustar00buildbuild00000000000000/* * 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 "../src/thrift/c_glib/thrift_struct.c" /* tests to ensure we can extend a ThriftStruct */ struct _ThriftTestStruct { ThriftStruct parent; }; typedef struct _ThriftTestStruct ThriftTestStruct; struct _ThriftTestStructClass { ThriftStructClass parent; }; typedef struct _ThriftTestStructClass ThriftTestStructClass; GType thrift_test_struct_get_type (void); #define THRIFT_TYPE_TEST_STRUCT (thrift_test_struct_get_type ()) #define THRIFT_TEST_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_TEST_STRUCT, ThriftTestStruct)) #define THRIFT_TEST_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_TEST_STRUCT, ThriftTestStructClass)) #define THRIFT_IS_TEST_STRUCT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_TEST_STRUCT)) #define THRIFT_IS_TEST_STRUCT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_TEST_STRUCT)) #define THRIFT_TEST_STRUCT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_TEST_STRUCT, ThriftTestStructClass)) G_DEFINE_TYPE(ThriftTestStruct, thrift_test_struct, THRIFT_TYPE_STRUCT) gint32 thrift_test_struct_read (ThriftStruct *object, ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (object); THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } gint32 thrift_test_struct_write (ThriftStruct *object, ThriftProtocol *protocol, GError **error) { THRIFT_UNUSED_VAR (object); THRIFT_UNUSED_VAR (protocol); THRIFT_UNUSED_VAR (error); return 0; } static void thrift_test_struct_class_init (ThriftTestStructClass *cls) { ThriftStructClass *ts_cls = THRIFT_STRUCT_CLASS (cls); ts_cls->read = thrift_test_struct_read; ts_cls->write = thrift_test_struct_write; } static void thrift_test_struct_init (ThriftTestStruct *s) { THRIFT_UNUSED_VAR (s); } static void test_initialize_object (void) { ThriftTestStruct *t = NULL; t = g_object_new (THRIFT_TYPE_TEST_STRUCT, NULL); g_assert ( THRIFT_IS_STRUCT (t)); thrift_struct_read (THRIFT_STRUCT (t), NULL, NULL); thrift_struct_write (THRIFT_STRUCT (t), NULL, NULL); thrift_test_struct_read (THRIFT_STRUCT (t), NULL, NULL); thrift_test_struct_write (THRIFT_STRUCT (t), NULL, NULL); g_object_unref (t); } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init(); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/teststruct/InitializeObject", test_initialize_object); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testbufferedtransport.c0000664000175000017500000002330015165535636023142 0ustar00buildbuild00000000000000/* * 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 #include #include #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } #include "../src/thrift/c_glib/transport/thrift_buffered_transport.c" static void thrift_server (const int port); static void thrift_socket_server_open (const int port, int times); /* test object creation and destruction */ static void test_create_and_destroy(void) { ThriftTransport *transport = NULL; guint r_buf_size = 0; guint w_buf_size = 0; GObject *object = NULL; object = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, NULL); g_assert (object != NULL); g_object_get (G_OBJECT (object), "transport", &transport, "r_buf_size", &r_buf_size, "w_buf_size", &w_buf_size, NULL); g_object_unref (object); } static void test_open_and_close(void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; GError *err = NULL; pid_t pid; int port = 51199; int status; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_socket_server_open (port,1); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); /* this shouldn't work */ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE); g_assert (thrift_buffered_transport_is_open (transport) == TRUE); g_assert (thrift_buffered_transport_close (transport, NULL) == TRUE); g_object_unref (transport); g_object_unref (tsocket); /* try and underlying socket failure */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken", NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); g_assert (thrift_buffered_transport_open (transport, &err) == FALSE); g_object_unref (transport); g_object_unref (tsocket); g_error_free (err); err = NULL; g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void test_read_and_write(void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; int port = 51199; guchar buf[10] = TEST_DATA; /* a buffer */ pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_server (port); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), "w_buf_size", 4, NULL); g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE); g_assert (thrift_buffered_transport_is_open (transport)); /* write 10 bytes */ thrift_buffered_transport_write (transport, buf, 10, NULL); /* write 1 byte at a time */ thrift_buffered_transport_write (transport, buf, 1, NULL); thrift_buffered_transport_write (transport, buf, 1, NULL); thrift_buffered_transport_write (transport, buf, 1, NULL); /* overflow the buffer */ thrift_buffered_transport_write (transport, buf, 2, NULL); thrift_buffered_transport_write (transport, buf, 1, NULL); thrift_buffered_transport_flush (transport, NULL); /* write 1 byte and flush */ thrift_buffered_transport_write (transport, buf, 1, NULL); thrift_buffered_transport_flush (transport, NULL); /* write and overflow buffer with 2 system calls */ thrift_buffered_transport_write (transport, buf, 1, NULL); thrift_buffered_transport_write (transport, buf, 3, NULL); /* write 10 bytes */ thrift_buffered_transport_write (transport, buf, 10, NULL); thrift_buffered_transport_write_end (transport, NULL); thrift_buffered_transport_flush (transport, NULL); thrift_buffered_transport_close (transport, NULL); g_object_unref (transport); g_object_unref (tsocket); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void thrift_socket_server_open (const int port, int times) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; int i; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); for(i=0;i= 0 ); if ( pid == 0 ) { /* child listens */ ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); /* wrap the client in a BufferedTransport */ client = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", thrift_server_transport_accept (transport, NULL), "r_buf_size", 5, NULL); g_assert (client != NULL); /* just close socket */ thrift_buffered_transport_close (client, NULL); g_object_unref (client); g_object_unref (tsocket); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), "w_buf_size", 4, NULL); g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE); g_assert (thrift_buffered_transport_is_open (transport)); /* recognize disconnection */ sleep(1); g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == TRUE); g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE); /* write and overflow buffer */ g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE); /* write 1 and flush */ g_assert (thrift_buffered_transport_write (transport, buf, 1, NULL) == TRUE); g_assert (thrift_buffered_transport_flush (transport, NULL) == FALSE); thrift_buffered_transport_close (transport, NULL); g_object_unref (transport); g_object_unref (tsocket); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init(); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testbufferedtransport/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testbufferedtransport/OpenAndClose", test_open_and_close); g_test_add_func ("/testbufferedtransport/ReadAndWrite", test_read_and_write); g_test_add_func ("/testbufferedtransport/WriteFail", test_write_fail); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testtransportsocket.c0000664000175000017500000002557015170007142022641 0ustar00buildbuild00000000000000/* * 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 #include #include #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } /* substituted functions to test failures of system and library calls */ static int socket_error = 0; int my_socket(int domain, int type, int protocol) { if (socket_error == 0) { return socket (domain, type, protocol); } return -1; } static int recv_error = 0; ssize_t my_recv(int socket, void *buffer, size_t length, int flags) { if (recv_error == 0) { return recv (socket, buffer, length, flags); } return -1; } static int send_error = 0; ssize_t my_send(int socket, const void *buffer, size_t length, int flags) { if (send_error == 0) { return send (socket, buffer, length, flags); } return -1; } #define socket my_socket #define recv my_recv #define send my_send #include "../src/thrift/c_glib/transport/thrift_socket.c" #undef socket #undef recv #undef send static void thrift_socket_server (const int port); static void thrift_socket_server_open (const int port, int times); static gchar * make_too_long_unix_socket_path (void) { struct sockaddr_un addr; const size_t path_len = sizeof (addr.sun_path) + 1; gchar *path = g_malloc (path_len + 1); memset (path, 'a', path_len); path[path_len] = '\0'; return path; } /* test object creation and destruction */ static void test_create_and_destroy(void) { gchar *hostname = NULL; guint port = 0; GObject *object = NULL; object = g_object_new (THRIFT_TYPE_SOCKET, NULL); g_assert (object != NULL); g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL); g_free (hostname); g_object_unref (object); } static void test_open_and_close(void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; GError *err = NULL; int port = 51199; pid_t pid; int status; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_socket_server_open (port, 1); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* open a connection and close it */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = THRIFT_TRANSPORT (tsocket); thrift_socket_open (transport, NULL); g_assert (thrift_socket_is_open (transport) == TRUE); thrift_socket_close (transport, NULL); g_assert (thrift_socket_is_open (transport) == FALSE); /* test close failure */ tsocket->sd = -1; thrift_socket_close (transport, NULL); g_object_unref (tsocket); /* try a hostname lookup failure */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken", NULL); transport = THRIFT_TRANSPORT (tsocket); g_assert (thrift_socket_open (transport, &err) == FALSE); g_object_unref (tsocket); g_error_free (err); err = NULL; /* try an error call to socket() */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", NULL); transport = THRIFT_TRANSPORT (tsocket); socket_error = 1; g_assert (thrift_socket_open (transport, &err) == FALSE); socket_error = 0; g_object_unref (tsocket); g_error_free (err); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void test_read_and_write(void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; pid_t pid; int port = 51199; int status; guchar buf[10] = TEST_DATA; /* a buffer */ pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_socket_server (port); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = THRIFT_TRANSPORT (tsocket); g_assert (thrift_socket_open (transport, NULL) == TRUE); g_assert (thrift_socket_is_open (transport)); thrift_socket_write (transport, buf, 10, NULL); /* write fail */ send_error = 1; thrift_socket_write (transport, buf, 1, NULL); send_error = 0; thrift_socket_write_end (transport, NULL); thrift_socket_flush (transport, NULL); thrift_socket_close (transport, NULL); g_object_unref (tsocket); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } /* test ThriftSocket's peek() implementation */ static void test_peek(void) { gint status; pid_t pid; guint port = 51199; gchar data = 'A'; ThriftTransport *client_transport; GError *error = NULL; client_transport = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); /* thrift_transport_peek returns FALSE when the socket is closed */ g_assert (thrift_transport_is_open (client_transport) == FALSE); g_assert (thrift_transport_peek (client_transport, &error) == FALSE); g_assert (error == NULL); pid = fork (); g_assert (pid >= 0); if (pid == 0) { ThriftServerTransport *server_transport = NULL; g_object_unref (client_transport); /* child listens */ server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); g_assert (server_transport != NULL); thrift_server_transport_listen (server_transport, &error); g_assert (error == NULL); client_transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", thrift_server_transport_accept (server_transport, &error), "r_buf_size", 0, "w_buf_size", sizeof data, NULL); g_assert (error == NULL); g_assert (client_transport != NULL); /* write exactly one character to the client */ g_assert (thrift_transport_write (client_transport, &data, sizeof data, &error) == TRUE); thrift_transport_flush (client_transport, &error); thrift_transport_write_end (client_transport, &error); thrift_transport_close (client_transport, &error); g_object_unref (client_transport); g_object_unref (server_transport); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* connect to the child */ thrift_transport_open (client_transport, &error); g_assert (error == NULL); g_assert (thrift_transport_is_open (client_transport) == TRUE); /* thrift_transport_peek returns TRUE when the socket is open and there is data available to be read */ g_assert (thrift_transport_peek (client_transport, &error) == TRUE); g_assert (error == NULL); /* read exactly one character from the server */ g_assert_cmpint (thrift_transport_read (client_transport, &data, sizeof data, &error), ==, sizeof data); /* thrift_transport_peek returns FALSE when the socket is open but there is no (more) data available to be read */ g_assert (thrift_transport_is_open (client_transport) == TRUE); g_assert (thrift_transport_peek (client_transport, &error) == FALSE); g_assert (error == NULL); thrift_transport_read_end (client_transport, &error); thrift_transport_close (client_transport, &error); g_object_unref (client_transport); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void test_open_rejects_too_long_unix_path (void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; GError *error = NULL; gchar *path = make_too_long_unix_socket_path (); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "path", path, NULL); transport = THRIFT_TRANSPORT (tsocket); g_assert (thrift_socket_open (transport, &error) == FALSE); g_assert_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET); g_clear_error (&error); g_assert (thrift_socket_is_open (transport) == FALSE); g_object_unref (tsocket); g_free (path); } static void thrift_socket_server_open (const int port, int times) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; int i; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); for(i=0;i #include #include #include #include #include "gen-c_glib/t_test_optional_required_test_types.h" #include "gen-c_glib/t_test_optional_required_test_types.c" static void write_to_read (ThriftStruct *w, ThriftStruct *r, GError **write_error, GError **read_error) { ThriftMemoryBuffer *tbuffer = NULL; ThriftProtocol *protocol = NULL; tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL); protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", tbuffer, NULL); thrift_struct_write (w, protocol, write_error); thrift_struct_read (r, protocol, read_error); g_object_unref (protocol); g_object_unref (tbuffer); } static void test_old_school1 (void) { TTestOldSchool *o = NULL; o = g_object_new (T_TEST_TYPE_OLD_SCHOOL, NULL); o->im_int = 10; o->im_str = g_strdup ("test"); o->im_big = g_ptr_array_new (); g_ptr_array_free (o->im_big, TRUE); o->im_big = NULL; g_free (o->im_str); o->im_str = NULL; g_object_unref (o); } /** * Write to read with optional fields */ static void test_simple (void) { TTestSimple *s1 = NULL, *s2 = NULL, *s3 = NULL; s1 = g_object_new (T_TEST_TYPE_SIMPLE, NULL); s2 = g_object_new (T_TEST_TYPE_SIMPLE, NULL); s3 = g_object_new (T_TEST_TYPE_SIMPLE, NULL); /* write-to-read with optional fields */ s1->im_optional = 10; g_assert (s1->__isset_im_default == FALSE); g_assert (s1->__isset_im_optional == FALSE); write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s2), NULL, NULL); g_assert (s2->__isset_im_default == TRUE); g_assert (s2->__isset_im_optional == FALSE); g_assert (s2->im_optional == 0); s1->__isset_im_optional = TRUE; write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s3), NULL, NULL); g_assert (s3->__isset_im_default == TRUE); g_assert (s3->__isset_im_optional == TRUE); g_assert (s3->im_optional == 10); g_object_unref (s1); g_object_unref (s2); } /** * Writing between optional and default */ static void test_tricky1 (void) { TTestTricky1 *t1 = NULL; TTestTricky2 *t2 = NULL; t1 = g_object_new (T_TEST_TYPE_TRICKY1, NULL); t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL); t2->im_optional = 10; write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t1), NULL, NULL); write_to_read (THRIFT_STRUCT (t1), THRIFT_STRUCT (t2), NULL, NULL); g_assert (t1->__isset_im_default == FALSE); g_assert (t2->__isset_im_optional == TRUE); g_assert (t1->im_default == t2->im_optional); g_assert (t1->im_default == 0); g_object_unref (t1); g_object_unref (t2); } /** * Writing between default and required. */ static void test_tricky2 (void) { TTestTricky1 *t1 = NULL; TTestTricky3 *t3 = NULL; t1 = g_object_new (T_TEST_TYPE_TRICKY1, NULL); t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL); write_to_read (THRIFT_STRUCT (t1), THRIFT_STRUCT (t3), NULL, NULL); write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t1), NULL, NULL); g_assert (t1->__isset_im_default == TRUE); g_object_unref (t1); g_object_unref (t3); } /** * Writing between optional and required. */ static void test_tricky3 (void) { TTestTricky2 *t2 = NULL; TTestTricky3 *t3 = NULL; t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL); t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL); t2->__isset_im_optional = TRUE; write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t3), NULL, NULL); write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t2), NULL, NULL); g_object_unref (t2); g_object_unref (t3); } /** * Catch an optional not set exception. To quote the * C++ test, "Mu-hu-ha-ha-ha!" */ static void test_tricky4 (void) { TTestTricky2 *t2 = NULL; TTestTricky3 *t3 = NULL; GError *read_error = NULL; t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL); t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL); /* throws protocol exception */ write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t3), NULL, &read_error); g_assert (read_error != NULL); g_error_free (read_error); write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t2), NULL, NULL); g_assert (t2->__isset_im_optional); g_object_unref (t2); g_object_unref (t3); } static void test_non_set_binary (void) { TTestBinaries *b1 = NULL; TTestBinaries *b2 = NULL; GError *error = NULL; b1 = g_object_new (T_TEST_TYPE_BINARIES, NULL); b2 = g_object_new (T_TEST_TYPE_BINARIES, NULL); write_to_read (THRIFT_STRUCT (b1), THRIFT_STRUCT (b2), NULL, &error); g_assert(!error); write_to_read (THRIFT_STRUCT (b2), THRIFT_STRUCT (b1), NULL, &error); g_assert(!error); /* OK. No segfault */ g_object_unref (b1); g_object_unref (b2); } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init(); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testoptionalrequired/OldSchool", test_old_school1); g_test_add_func ("/testoptionalrequired/Simple", test_simple); g_test_add_func ("/testoptionalrequired/Tricky1", test_tricky1); g_test_add_func ("/testoptionalrequired/Tricky2", test_tricky2); g_test_add_func ("/testoptionalrequired/Tricky3", test_tricky3); g_test_add_func ("/testoptionalrequired/Tricky4", test_tricky4); g_test_add_func ("/testoptionalrequired/Binary", test_non_set_binary); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testthriftfdreadcheck.c0000664000175000017500000001244215165535636023054 0ustar00buildbuild00000000000000/* * 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 #include #include #include #define MAX_MESSAGE_SIZE 2 static const gchar TEST_DATA[12] = "abcde01234!"; static void test_open_and_close (void) { ThriftConfiguration *configuration; ThriftTransport *transport; ThriftTransportClass *klass; GError *error; gint fd; gchar *filename; error = NULL; filename = NULL; fd = g_file_open_tmp (NULL, &filename, &error); g_assert (fd >= 0); configuration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "configuration", configuration, "fd", fd, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); /* open is no-op */ g_assert (klass->is_open (transport)); g_assert (klass->peek (transport, &error)); g_assert (klass->open (transport, &error)); g_assert (klass->is_open (transport)); g_assert (klass->peek (transport, &error)); g_assert (klass->close (transport, &error)); g_assert (! klass->open (transport, &error)); g_assert (! klass->is_open (transport)); g_assert (! klass->peek (transport, &error)); /* already closed */ g_assert (close (fd) != 0); g_assert (errno == EBADF); g_object_unref (transport); g_object_unref (configuration); g_remove (filename); g_free (filename); /* test bad fd */ transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", -1, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); g_assert (! klass->is_open (transport)); error = NULL; g_assert (! klass->peek (transport, &error)); error = NULL; g_assert (! klass->open (transport, &error)); error = NULL; g_assert (! klass->close (transport, &error)); g_object_unref (transport); } static void test_read_and_write (void) { gchar out_buf[8]; gchar *b; gint want, got; ThriftConfiguration *configuration; ThriftTransport *transport; ThriftTransportClass *klass; GError *error; gint fd; gchar *filename; error = NULL; filename = NULL; fd = g_file_open_tmp (NULL, &filename, &error); g_assert (fd >= 0); configuration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); /* write */ transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "configuration", configuration, "fd", fd, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); g_assert (klass->is_open (transport)); g_assert (klass->write (transport, (gpointer) TEST_DATA, 11, &error)); g_assert (klass->flush (transport, &error)); g_assert (klass->close (transport, &error)); g_object_unref (transport); /* read */ fd = open(filename, O_RDONLY, S_IRUSR | S_IWUSR); g_assert (fd >= 0); transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "configuration", configuration, "remainingmessagesize", MAX_MESSAGE_SIZE, "fd", fd, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); memset(out_buf, 0, 8); b = out_buf; want = 2; while (want > 0) { got = klass->read (transport, (gpointer) b, want, &error); g_assert (got > 0 && got <= want); b += got; want -= got; } g_assert (memcmp (out_buf, TEST_DATA, 2) == 0); memset(out_buf, 0, 8); b = out_buf; want = 4; got = klass->read (transport, (gpointer) b, want, &error); g_assert (got < 0); g_assert (klass->close (transport, &error)); g_object_unref (transport); g_object_unref (configuration); /* clean up */ g_remove (filename); g_free (filename); } int main (int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testfdtransport/OpenAndClose", test_open_and_close); g_test_add_func ("/testfdtransport/ReadAndWrite", test_read_and_write); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testfdtransport.c0000664000175000017500000001171015165535636021753 0ustar00buildbuild00000000000000/* * 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 #include #include #include static const gchar TEST_DATA[12] = "abcde01234!"; static void test_create_and_destroy (void) { GObject *object; object = g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", -1, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_open_and_close (void) { ThriftTransport *transport; ThriftTransportClass *klass; GError *error; gint fd; gchar *filename; error = NULL; filename = NULL; fd = g_file_open_tmp (NULL, &filename, &error); g_assert (fd >= 0); transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", fd, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); /* open is no-op */ g_assert (klass->is_open (transport)); g_assert (klass->peek (transport, &error)); g_assert (klass->open (transport, &error)); g_assert (klass->is_open (transport)); g_assert (klass->peek (transport, &error)); g_assert (klass->close (transport, &error)); g_assert (! klass->open (transport, &error)); g_assert (! klass->is_open (transport)); g_assert (! klass->peek (transport, &error)); /* already closed */ g_assert (close (fd) != 0); g_assert (errno == EBADF); g_object_unref (transport); g_remove (filename); g_free (filename); /* test bad fd */ transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", -1, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); g_assert (! klass->is_open (transport)); error = NULL; g_assert (! klass->peek (transport, &error)); error = NULL; g_assert (! klass->open (transport, &error)); error = NULL; g_assert (! klass->close (transport, &error)); g_object_unref (transport); } static void test_read_and_write (void) { gchar out_buf[8]; gchar *b; gint want, got; ThriftTransport *transport; ThriftTransportClass *klass; GError *error; gint fd; gchar *filename; error = NULL; filename = NULL; fd = g_file_open_tmp (NULL, &filename, &error); g_assert (fd >= 0); /* write */ transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", fd, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); g_assert (klass->is_open (transport)); g_assert (klass->write (transport, (gpointer) TEST_DATA, 11, &error)); g_assert (klass->flush (transport, &error)); g_assert (klass->close (transport, &error)); g_object_unref (transport); /* read */ fd = open(filename, O_RDONLY, S_IRUSR | S_IWUSR); g_assert (fd >= 0); transport = THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_FD_TRANSPORT, "fd", fd, NULL)); klass = THRIFT_TRANSPORT_GET_CLASS (transport); memset(out_buf, 0, 8); b = out_buf; want = 7; while (want > 0) { got = klass->read (transport, (gpointer) b, want, &error); g_assert (got > 0 && got <= want); b += got; want -= got; } g_assert (memcmp (out_buf, TEST_DATA, 7) == 0); memset(out_buf, 0, 8); b = out_buf; want = 4; while (want > 0) { got = klass->read (transport, (gpointer) b, want, &error); g_assert (got > 0 && got <= want); b += got; want -= got; } g_assert (memcmp (out_buf, TEST_DATA + 7, 4) == 0); g_assert (klass->close (transport, &error)); g_object_unref (transport); /* clean up */ g_remove (filename); g_free (filename); } int main (int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testfdtransport/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testfdtransport/OpenAndClose", test_open_and_close); g_test_add_func ("/testfdtransport/ReadAndWrite", test_read_and_write); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/glib.suppress0000664000175000017500000000150515165535636021065 0ustar00buildbuild00000000000000{ g_type_init_1 Memcheck:Leak fun:malloc ... fun:g_type_init_with_debug_flags } { g_type_init_2 Memcheck:Leak fun:calloc ... fun:g_type_init_with_debug_flags } { g_type_init_3 Memcheck:Leak fun:realloc ... fun:g_type_init_with_debug_flags } { g_type_register_static_1 Memcheck:Leak fun:realloc ... fun:g_type_register_static } { g_type_register_statuc_2 Memcheck:Leak fun:malloc fun:realloc fun:g_realloc ... fun:g_type_register_static } { type_class_init_Wm1 Memcheck:Leak fun:calloc fun:g_malloc0 fun:type_class_init_Wm fun:g_type_class_ref ... fun:g_object_newv } { type_class_init_Wm2 Memcheck:Leak fun:calloc fun:g_malloc0 fun:type_class_init_Wm fun:g_type_class_ref ... fun:type_class_init_Wm } thrift-0.23.0/lib/c_glib/test/testsimpleserver.c0000664000175000017500000000607115165535636022131 0ustar00buildbuild00000000000000/* * 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 #include #include #include #define TEST_PORT 51199 #include /* create a rudimentary processor */ #define TEST_PROCESSOR_TYPE (test_processor_get_type ()) struct _TestProcessor { ThriftProcessor parent; }; typedef struct _TestProcessor TestProcessor; struct _TestProcessorClass { ThriftProcessorClass parent; }; typedef struct _TestProcessorClass TestProcessorClass; G_DEFINE_TYPE(TestProcessor, test_processor, THRIFT_TYPE_PROCESSOR) gboolean test_processor_process (ThriftProcessor *processor, ThriftProtocol *in, ThriftProtocol *out, GError **error) { THRIFT_UNUSED_VAR (processor); THRIFT_UNUSED_VAR (in); THRIFT_UNUSED_VAR (out); THRIFT_UNUSED_VAR (error); return FALSE; } static void test_processor_init (TestProcessor *p) { THRIFT_UNUSED_VAR (p); } static void test_processor_class_init (TestProcessorClass *proc) { (THRIFT_PROCESSOR_CLASS(proc))->process = test_processor_process; } static void test_server (void) { int status; pid_t pid; TestProcessor *p = NULL; ThriftServerSocket *tss = NULL; ThriftSimpleServer *ss = NULL; p = g_object_new (TEST_PROCESSOR_TYPE, NULL); tss = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", TEST_PORT, NULL); ss = g_object_new (THRIFT_TYPE_SIMPLE_SERVER, "processor", p, "server_transport", THRIFT_SERVER_TRANSPORT (tss), NULL); /* run the server in a child process */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { THRIFT_SERVER_GET_CLASS (THRIFT_SERVER (ss))->serve (THRIFT_SERVER (ss), NULL); exit (0); } else { sleep (5); kill (pid, SIGINT); g_object_unref (ss); g_object_unref (tss); g_object_unref (p); g_assert (wait (&status) == pid); g_assert (status == SIGINT); } } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init(); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testsimpleserver/SimpleServer", test_server); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testframedtransport.c0000664000175000017500000002243415165535636022625 0ustar00buildbuild00000000000000/* * 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 #include #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } #include "../src/thrift/c_glib/transport/thrift_framed_transport.c" static void thrift_server (const int port); static void thrift_socket_server_open (const int port, int times); /* test object creation and destruction */ static void test_create_and_destroy(void) { ThriftTransport *transport = NULL; guint r_buf_size = 0; guint w_buf_size = 0; GObject *object = NULL; object = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, NULL); g_assert (object != NULL); g_object_get (G_OBJECT (object), "transport", &transport, "r_buf_size", &r_buf_size, "w_buf_size", &w_buf_size, NULL); g_object_unref (object); } static void test_open_and_close(void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; GError *err = NULL; pid_t pid; int port = 51199; int status; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_socket_server_open (port,1); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); /* this shouldn't work */ g_assert (thrift_framed_transport_open (transport, NULL) == TRUE); g_assert (thrift_framed_transport_is_open (transport) == TRUE); g_assert (thrift_framed_transport_close (transport, NULL) == TRUE); g_object_unref (transport); g_object_unref (tsocket); /* try and underlying socket failure */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken", NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); g_assert (thrift_framed_transport_open (transport, &err) == FALSE); g_object_unref (transport); g_object_unref (tsocket); g_error_free (err); err = NULL; g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void test_read_and_write(void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; int port = 51199; guchar buf[10] = TEST_DATA; /* a buffer */ pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_server (port); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), "w_buf_size", 4, NULL); g_assert (thrift_framed_transport_open (transport, NULL) == TRUE); g_assert (thrift_framed_transport_is_open (transport)); /* write 10 bytes */ thrift_framed_transport_write (transport, buf, 10, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_write (transport, buf, 1, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_write (transport, buf, 10, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_write (transport, buf, 10, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_write_end (transport, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_close (transport, NULL); g_object_unref (transport); g_object_unref (tsocket); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } /* test reading from the transport after the peer has unexpectedly closed the connection */ static void test_read_after_peer_close(void) { int status; pid_t pid; int port = 51199; GError *err = NULL; pid = fork (); g_assert (pid >= 0); if (pid == 0) { ThriftServerTransport *server_transport = NULL; ThriftTransport *client_transport = NULL; /* child listens */ server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); g_assert (server_transport != NULL); thrift_server_transport_listen (server_transport, &err); g_assert (err == NULL); /* wrap the client transport in a ThriftFramedTransport */ client_transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", thrift_server_transport_accept (server_transport, &err), "r_buf_size", 0, NULL); g_assert (err == NULL); g_assert (client_transport != NULL); /* close the connection immediately after the client connects */ thrift_transport_close (client_transport, NULL); g_object_unref (client_transport); g_object_unref (server_transport); exit (0); } else { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; guchar buf[10]; /* a buffer */ /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), "w_buf_size", 0, NULL); g_assert (thrift_transport_open (transport, NULL) == TRUE); g_assert (thrift_transport_is_open (transport)); /* attempting to read from the transport after the peer has closed the connection fails gracefully without generating a critical warning or segmentation fault */ thrift_transport_read (transport, buf, 10, &err); g_assert (err != NULL); g_error_free (err); err = NULL; thrift_transport_read_end (transport, &err); g_assert (err == NULL); thrift_transport_close (transport, &err); g_assert (err == NULL); g_object_unref (transport); g_object_unref (tsocket); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void thrift_socket_server_open (const int port, int times) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; int i; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); for(i=0;i #endif #ifdef __GLIBC__ #define __NO_STRING_INLINES 1 #endif #include #include #include #include #include #include #include #include #include #include #define TEST_BOOL TRUE #define TEST_BYTE 123 #define TEST_I16 12345 #define TEST_I32 1234567890 #define TEST_I64 123456789012345 #define TEST_NI16 (-12345) #define TEST_NI32 (-1234567890) #define TEST_NI64 (-123456789012345) #define TEST_DOUBLE 1234567890.123 #define TEST_STRING "this is a test string 1234567890!@#$%^&*()" #define TEST_PORT 51199 static int transport_read_count = 0; static int transport_read_error = 0; static int transport_read_error_at = -1; gint32 my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { if (transport_read_count != transport_read_error_at && transport_read_error == 0) { transport_read_count++; return thrift_transport_read_all (transport, buf, len, error); } return -1; } static int transport_write_count = 0; static int transport_write_error = 0; static int transport_write_error_at = -1; gboolean my_thrift_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { if (transport_write_count != transport_write_error_at && transport_write_error == 0) { transport_write_count++; return thrift_transport_write (transport, buf, len, error); } return FALSE; } #define thrift_transport_read_all my_thrift_transport_read_all #define thrift_transport_write my_thrift_transport_write #include "../src/thrift/c_glib/protocol/thrift_compact_protocol.c" #undef thrift_transport_read_all #undef thrift_transport_write static void thrift_server_primitives (const int port); static void thrift_server_complex_types (const int port); static void thrift_server_many_frames (const int port); static void test_create_and_destroy (void) { GObject *object = NULL; /* create an object and then destroy it */ object = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_initialize (void) { ThriftSocket *tsocket = NULL; ThriftCompactProtocol *protocol = NULL; ThriftSocket *temp = NULL; /* create a ThriftTransport */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", 51188, NULL); g_assert (tsocket != NULL); /* create a ThriftCompactProtocol using the Transport */ protocol = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", tsocket, NULL); g_assert (protocol != NULL); /* fetch the properties */ g_object_get (G_OBJECT (protocol), "transport", &temp, NULL); g_object_unref (temp); /* clean up memory */ g_object_unref (protocol); g_object_unref (tsocket); } static void test_read_and_write_primitives (void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftCompactProtocol *tc = NULL; ThriftProtocol *protocol = NULL; gpointer binary = (gpointer *) TEST_STRING; guint32 len = strlen (TEST_STRING); int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_primitives (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = THRIFT_TRANSPORT (tsocket); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a ThriftCompactTransport */ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", tsocket, NULL); protocol = THRIFT_PROTOCOL (tc); g_assert (protocol != NULL); /* write a bunch of primitives */ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0); g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) > 0); g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) > 0); g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) > 0); g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16, NULL) > 0); g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32, NULL) > 0); g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64, NULL) > 0); g_assert (thrift_compact_protocol_write_i16 (protocol, 2, NULL) > 0); g_assert (thrift_compact_protocol_write_i32 (protocol, 2, NULL) > 0); g_assert (thrift_compact_protocol_write_i64 (protocol, 2, NULL) > 0); g_assert (thrift_compact_protocol_write_i16 (protocol, -2, NULL) > 0); g_assert (thrift_compact_protocol_write_i32 (protocol, -2, NULL) > 0); g_assert (thrift_compact_protocol_write_i64 (protocol, -2, NULL) > 0); g_assert (thrift_compact_protocol_write_double (protocol, TEST_DOUBLE, NULL) > 0); g_assert (thrift_compact_protocol_write_string (protocol, TEST_STRING, NULL) > 0); g_assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0); g_assert (thrift_compact_protocol_write_binary (protocol, binary, len, NULL) > 0); g_assert (thrift_compact_protocol_write_binary (protocol, NULL, 0, NULL) > 0); g_assert (thrift_compact_protocol_write_binary (protocol, binary, len, NULL) > 0); /* test write errors */ transport_write_error = 1; g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE, NULL) == -1); g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) == -1); g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) == -1); g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) == -1); g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16, NULL) == -1); g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32, NULL) == -1); g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64, NULL) == -1); g_assert (thrift_compact_protocol_write_double (protocol, TEST_DOUBLE, NULL) == -1); g_assert (thrift_compact_protocol_write_binary (protocol, binary, len, NULL) == -1); transport_write_error = 0; /* test binary partial failure */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_compact_protocol_write_binary (protocol, binary, len, NULL) == -1); transport_write_error_at = -1; /* clean up */ thrift_transport_close (transport, NULL); g_object_unref (tsocket); g_object_unref (protocol); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void test_read_and_write_complex_types (void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftCompactProtocol *tc = NULL; ThriftProtocol *protocol = NULL; int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_complex_types (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = THRIFT_TRANSPORT (tsocket); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a ThriftCompactTransport */ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", tsocket, NULL); protocol = THRIFT_PROTOCOL (tc); g_assert (protocol != NULL); /* test structures */ g_assert (thrift_compact_protocol_write_struct_begin (protocol, NULL, NULL) == 0); g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0); /* test field state w.r.t. deltas */ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 1, NULL) == 1); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 16, NULL) == 1); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 17, NULL) == 1); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 15, NULL) > 1); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 30, NULL) == 1); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 46, NULL) > 1); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 47, NULL) == 1); /* test fields */ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 1, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); /* test field state w.r.t. structs */ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 1, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 16, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_struct_begin (protocol, NULL, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 17, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_struct_begin (protocol, NULL, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 18, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 19, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 18, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 25, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 17, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); /* test field state w.r.t. bools */ /* deltas */ /* non-bool field -> bool field -> non-bool field */ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 18, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL, 19, NULL) == 0); g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 20, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); /* bool -> bool field -> bool */ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL, 21, NULL) == 0); g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) == 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); /* no deltas */ /* non-bool field -> bool field -> non-bool field */ g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 1, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL, 1, NULL) == 0); g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 1, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); /* bool -> bool field -> bool */ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL, 1, NULL) == 0); g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 1); g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); /* test write error */ transport_write_error = 1; g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 1, NULL) == -1); transport_write_error = 0; /* test 2nd write error */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_DOUBLE, 1, NULL) == -1); transport_write_error_at = -1; /* test 2nd read failure on a field */ thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL); /* test write_field_stop */ g_assert (thrift_compact_protocol_write_field_stop (protocol, NULL) > 0); /* write a map */ g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE, T_DOUBLE, 1, NULL) > 0); g_assert (thrift_compact_protocol_write_map_end (protocol, NULL) == 0); /* test 1st read failure on map---nothing to do on our side */ /* test 2nd read failure on a map */ thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL); /* test 1st write failure on a map */ transport_write_error = 1; g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE, T_DOUBLE, 1, NULL) == -1); transport_write_error = 0; /* test 2nd write failure on a map */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE, T_DOUBLE, 1, NULL) == -1); transport_write_error_at = -1; /* test negative map size */ thrift_compact_protocol_write_varint32 (tc, -10, NULL); thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL); /* test list operations */ g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE, 15, NULL) > 0); g_assert (thrift_compact_protocol_write_list_end (protocol, NULL) == 0); /* test 1st read failure on a small list---nothing to do on our end */ /* test 1st read failure on a big list---nothing to do on our end */ /* test 2nd read failure on a big list */ thrift_compact_protocol_write_byte (protocol, (gint8) 0xf0, NULL); /* test negative list size */ thrift_compact_protocol_write_byte (protocol, (gint8) 0xf0, NULL); thrift_compact_protocol_write_varint32 (tc, -10, NULL); /* test first write error on a small list */ transport_write_error = 1; g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE, 14, NULL) == -1); transport_write_error = 0; /* test first write error on a big list */ transport_write_error = 1; g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE, 15, NULL) == -1); transport_write_error = 0; /* test 2nd write error on a big list */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE, 15, NULL) == -1); transport_write_error_at = -1; /* test set operation s*/ g_assert (thrift_compact_protocol_write_set_begin (protocol, T_DOUBLE, 1, NULL) > 0); g_assert (thrift_compact_protocol_write_set_end (protocol, NULL) == 0); /* invalid protocol */ g_assert (thrift_compact_protocol_write_byte (protocol, 0, NULL) > 0); /* invalid version */ g_assert (thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL) > 0); g_assert (thrift_compact_protocol_write_byte (protocol, 0, NULL) > 0); /* send a valid message */ g_assert (thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL) > 0); g_assert (thrift_compact_protocol_write_byte (protocol, 0x01u, NULL) > 0); thrift_compact_protocol_write_varint32 (tc, 1, NULL); thrift_compact_protocol_write_string (protocol, "test", NULL); /* broken 2nd read */ thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL); /* send a broken 3rd read */ thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL); thrift_compact_protocol_write_byte (protocol, 0x01u, NULL); /* send a broken 4th read */ thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL); thrift_compact_protocol_write_byte (protocol, 0x01u, NULL); thrift_compact_protocol_write_varint32 (tc, 1, NULL); /* send a valid message */ g_assert (thrift_compact_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) > 0); g_assert (thrift_compact_protocol_write_message_end (protocol, NULL) == 0); /* send broken writes */ transport_write_error = 1; g_assert (thrift_compact_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) == -1); transport_write_error = 0; transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_compact_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) == -1); transport_write_error_at = -1; transport_write_count = 0; transport_write_error_at = 2; g_assert (thrift_compact_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) == -1); transport_write_error_at = -1; transport_write_count = 0; transport_write_error_at = 3; g_assert (thrift_compact_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) == -1); transport_write_error_at = -1; /* clean up */ thrift_transport_close (transport, NULL); g_object_unref (tsocket); g_object_unref (protocol); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void test_read_and_write_many_frames (void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftFramedTransport *ft = NULL; ThriftCompactProtocol *tc = NULL; ThriftProtocol *protocol = NULL; gpointer binary = (gpointer *) TEST_STRING; const guint32 len = strlen (TEST_STRING); int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_many_frames (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); g_assert (tsocket != NULL); transport = THRIFT_TRANSPORT (tsocket); /* wrap in a framed transport */ ft = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", transport, "w_buf_size", 1, NULL); g_assert (ft != NULL); transport = THRIFT_TRANSPORT (ft); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a compact protocol */ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", transport, NULL); protocol = THRIFT_PROTOCOL (tc); g_assert (protocol != NULL); /* write a bunch of primitives */ g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i16 (protocol, 2, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i32 (protocol, 2, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i64 (protocol, 2, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i16 (protocol, -2, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i32 (protocol, -2, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_i64 (protocol, -2, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_double (protocol, TEST_DOUBLE, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_string (protocol, TEST_STRING, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_binary (protocol, binary, len, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_binary (protocol, NULL, 0, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_compact_protocol_write_binary (protocol, binary, len, NULL) > 0); thrift_transport_flush (transport, NULL); /* clean up */ thrift_transport_write_end (transport, NULL); thrift_transport_close (transport, NULL); g_object_unref (ft); g_object_unref (tsocket); g_object_unref (tc); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void thrift_server_primitives (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftCompactProtocol *tc = NULL; ThriftProtocol *protocol = NULL; gboolean value_boolean = FALSE; gint8 value_byte = 0, zigzag_p16 = 0, zigzag_p32 = 0, zigzag_p64 = 0, zigzag_n16 = 0, zigzag_n32 = 0, zigzag_n64 = 0; gint16 value_16 = 0; gint32 value_32 = 0; gint64 value_64 = 0; gint16 value_n16 = 0; gint32 value_n32 = 0; gint64 value_n64 = 0; gdouble value_double = 0; gchar *string = NULL; gchar *empty_string = NULL; gpointer binary = NULL; guint32 len = 0; void *comparator = (void *) TEST_STRING; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); client = thrift_server_transport_accept (transport, NULL); g_assert (client != NULL); tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL (tc); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &value_byte, NULL) > 0); g_assert (thrift_compact_protocol_read_i16 (protocol, &value_16, NULL) > 0); g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) > 0); g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) > 0); g_assert (thrift_compact_protocol_read_i16 (protocol, &value_n16, NULL) > 0); g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) > 0); g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p16, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p32, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p64, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n16, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n32, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n64, NULL) > 0); g_assert (thrift_compact_protocol_read_double (protocol, &value_double, NULL) > 0); g_assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0); g_assert (thrift_compact_protocol_read_string (protocol, &empty_string, NULL) > 0); g_assert (thrift_compact_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (value_boolean == TEST_BOOL); g_assert (value_byte == TEST_BYTE); g_assert (value_16 == TEST_I16); g_assert (value_32 == TEST_I32); g_assert (value_64 == TEST_I64); g_assert (value_n16 == TEST_NI16); g_assert (value_n32 == TEST_NI32); g_assert (value_n64 == TEST_NI64); g_assert (zigzag_p16 == 4); g_assert (zigzag_p32 == 4); g_assert (zigzag_p64 == 4); g_assert (zigzag_n16 == 3); g_assert (zigzag_n32 == 3); g_assert (zigzag_n64 == 3); g_assert (value_double == TEST_DOUBLE); g_assert (strcmp (TEST_STRING, string) == 0); g_assert (strcmp ("", empty_string) == 0); g_assert (memcmp (comparator, binary, len) == 0); g_free (string); g_free (empty_string); g_free (binary); g_assert (thrift_compact_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (binary == NULL); g_assert (len == 0); g_free (binary); transport_read_count = 0; transport_read_error_at = 0; g_assert (thrift_compact_protocol_read_binary (protocol, &binary, &len, NULL) == -1); transport_read_error_at = -1; transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_compact_protocol_read_binary (protocol, &binary, &len, NULL) == -1); transport_read_error_at = -1; transport_read_error = 1; g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) == -1); g_assert (thrift_compact_protocol_read_byte (protocol, &value_byte, NULL) == -1); g_assert (thrift_compact_protocol_read_i16 (protocol, &value_16, NULL) == -1); g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) == -1); g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) == -1); g_assert (thrift_compact_protocol_read_i16 (protocol, &value_n16, NULL) == -1); g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) == -1); g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) == -1); g_assert (thrift_compact_protocol_read_double (protocol, &value_double, NULL) == -1); transport_read_error = 0; /* test partial write failure */ thrift_protocol_read_i32 (protocol, &value_32, NULL); thrift_transport_read_end (client, NULL); thrift_transport_close (client, NULL); g_object_unref (tc); g_object_unref (client); g_object_unref (tsocket); } static void thrift_server_complex_types (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftCompactProtocol *tc = NULL; ThriftProtocol *protocol = NULL; gchar *struct_name = NULL; gchar *field_name = NULL; gchar *message_name = NULL; ThriftType element_type, key_type, value_type, field_type; ThriftMessageType message_type; gboolean value_boolean = ! TEST_BOOL; gint8 value = 0; gint16 field_id = 0; guint32 size = 0; gint32 seqid = 0; gint8 version_and_type = 0; gint8 protocol_id = 0; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); client = thrift_server_transport_accept (transport, NULL); g_assert (client != NULL); tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL (tc); /* test struct operations */ thrift_compact_protocol_read_struct_begin (protocol, &struct_name, NULL); thrift_compact_protocol_read_struct_end (protocol, NULL); /* test field state w.r.t. deltas */ field_id = 0; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 1); field_id = 0; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 16); field_id = 0; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 17); field_id = 0; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); g_assert (field_id == 15); field_id = 0; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 30); field_id = 0; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); g_assert (field_id == 46); field_id = 0; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 47); field_id = 0; /* test field operations */ thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL); thrift_compact_protocol_read_field_end (protocol, NULL); /* test field state w.r.t. structs */ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); g_assert (field_id == 1); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 16); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_struct_begin (protocol, &struct_name, NULL) == 0); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); g_assert (field_id == 17); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_struct_begin (protocol, &struct_name, NULL) == 0); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); g_assert (field_id == 18); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 19); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_struct_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 18); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 25); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_struct_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_id == 17); field_id = 0; thrift_compact_protocol_read_field_end (protocol, NULL); /* test field state w.r.t. bools */ /* deltas */ /* non-bool field -> bool field -> non-bool field */ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_type == T_BOOL); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) == 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); thrift_compact_protocol_read_field_end (protocol, NULL); /* bool -> bool field -> bool */ g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == 1); g_assert (field_type == T_BOOL); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) == 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; /* no deltas */ /* non-bool field -> bool field -> non-bool field */ g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); g_assert (field_type == T_BOOL); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) == 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); thrift_compact_protocol_read_field_end (protocol, NULL); /* bool -> bool field -> bool */ g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) > 1); g_assert (field_type == T_BOOL); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) == 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; thrift_compact_protocol_read_field_end (protocol, NULL); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (value_boolean == TEST_BOOL); value_boolean = ! TEST_BOOL; /* test first read error on a field */ transport_read_error = 1; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == -1); transport_read_error = 0; /* test 2nd write failure */ thrift_compact_protocol_read_byte (protocol, &value, NULL); /* test 2nd read failure on a field */ transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == -1); transport_read_error_at = -1; /* test field stop */ thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL); /* test map operations */ thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL); thrift_compact_protocol_read_map_end (protocol, NULL); /* test 1st read failure on a map */ transport_read_count = 0; transport_read_error_at = 0; g_assert (thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); transport_read_error_at = -1; /* test 2nd read failure on a map */ transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); transport_read_error_at = -1; /* test 1st write failure on map---nothing to do on our side */ /* test 2nd write failure */ thrift_compact_protocol_read_byte (protocol, &value, NULL); /* test negative map size */ g_assert (thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); /* test list operations */ thrift_compact_protocol_read_list_begin (protocol, &element_type, &size, NULL); thrift_compact_protocol_read_list_end (protocol, NULL); /* test small list 1st read failure */ transport_read_error = 1; g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type, &size, NULL) == -1); transport_read_error = 0; /* test big list 1st read failure */ transport_read_error = 1; g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type, &size, NULL) == -1); transport_read_error = 0; /* test big list 2nd read failure */ transport_read_count = 0; transport_read_error_at = 1; thrift_compact_protocol_read_list_begin (protocol, &element_type, &size, NULL); transport_read_error_at = -1; /* test negative list size failure */ thrift_compact_protocol_read_list_begin (protocol, &element_type, &size, NULL); /* test small list 1st write failure---nothing to do on our end */ /* test big list 1st write failure---nothing to do on our end */ /* test big list 2nd write failure */ thrift_compact_protocol_read_byte (protocol, &value, NULL); /* test set operations */ thrift_compact_protocol_read_set_begin (protocol, &element_type, &size, NULL); thrift_compact_protocol_read_set_end (protocol, NULL); /* broken read */ transport_read_error = 1; g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); transport_read_error = 0; /* invalid protocol */ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); /* invalid version */ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); /* read a valid message */ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) > 0); g_free (message_name); /* broken 2nd read on a message */ transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); transport_read_error_at = -1; /* broken 3rd read on a message */ transport_read_count = 0; transport_read_error_at = 2; g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); transport_read_error_at = -1; /* broken 4th read on a message */ transport_read_count = 0; transport_read_error_at = 3; g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); transport_read_error_at = -1; /* read a valid message */ g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) > 0); g_free (message_name); g_assert (thrift_compact_protocol_read_message_end (protocol, NULL) == 0); /* handle 2nd write failure on a message */ thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL); /* handle 3rd write failure on a message */ thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL); thrift_compact_protocol_read_byte (protocol, &version_and_type, NULL); /* handle 4th write failure on a message */ thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL); thrift_compact_protocol_read_byte (protocol, &version_and_type, NULL); thrift_compact_protocol_read_varint32 (tc, &seqid, NULL); g_object_unref (client); g_object_unref (tsocket); } static void thrift_server_many_frames (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftCompactProtocol *tcp = NULL; ThriftProtocol *protocol = NULL; ThriftServerSocket *tsocket = NULL; gboolean value_boolean = FALSE; gint8 value_byte = 0, zigzag_p16 = 0, zigzag_p32 = 0, zigzag_p64 = 0, zigzag_n16 = 0, zigzag_n32 = 0, zigzag_n64 = 0; gint16 value_16 = 0; gint32 value_32 = 0; gint64 value_64 = 0; gint16 value_n16 = 0; gint32 value_n32 = 0; gint64 value_n64 = 0; gdouble value_double = 0; gchar *string = NULL; gchar *empty_string = NULL; gpointer binary = NULL; guint32 len = 0; void *comparator = (void *) TEST_STRING; tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); /* wrap the client in a framed transport */ client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", thrift_server_transport_accept (transport, NULL), "r_buf_size", 1, NULL); g_assert (client != NULL); tcp = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL (tcp); g_assert (thrift_compact_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &value_byte, NULL) > 0); g_assert (thrift_compact_protocol_read_i16 (protocol, &value_16, NULL) > 0); g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) > 0); g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) > 0); g_assert (thrift_compact_protocol_read_i16 (protocol, &value_n16, NULL) > 0); g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) > 0); g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p16, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p32, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p64, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n16, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n32, NULL) > 0); g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n64, NULL) > 0); g_assert (thrift_compact_protocol_read_double (protocol, &value_double, NULL) > 0); g_assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0); g_assert (thrift_compact_protocol_read_string (protocol, &empty_string, NULL) > 0); g_assert (thrift_compact_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (value_boolean == TEST_BOOL); g_assert (value_byte == TEST_BYTE); g_assert (value_16 == TEST_I16); g_assert (value_32 == TEST_I32); g_assert (value_64 == TEST_I64); g_assert (value_n16 == TEST_NI16); g_assert (value_n32 == TEST_NI32); g_assert (value_n64 == TEST_NI64); g_assert (zigzag_p16 == 4); g_assert (zigzag_p32 == 4); g_assert (zigzag_p64 == 4); g_assert (zigzag_n16 == 3); g_assert (zigzag_n32 == 3); g_assert (zigzag_n64 == 3); g_assert (value_double == TEST_DOUBLE); g_assert (strcmp (TEST_STRING, string) == 0); g_assert (strcmp ("", empty_string) == 0); g_assert (memcmp (comparator, binary, len) == 0); g_free (string); g_free (empty_string); g_free (binary); g_assert (thrift_compact_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (binary == NULL); g_assert (len == 0); g_free (binary); thrift_transport_read_end (client, NULL); thrift_transport_close (client, NULL); g_object_unref (tcp); g_object_unref (client); g_object_unref (tsocket); } int main (int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testcompactprotocol/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testcompactprotocol/Initialize", test_initialize); g_test_add_func ("/testcompactprotocol/ReadAndWritePrimitives", test_read_and_write_primitives); g_test_add_func ("/testcompactprotocol/ReadAndWriteComplexTypes", test_read_and_write_complex_types); g_test_add_func ("/testcompactprotocol/ReadAndWriteManyFrames", test_read_and_write_many_frames); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testthriftbufferedreadcheck.c0000664000175000017500000001616115165535636024247 0ustar00buildbuild00000000000000/* * 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 #include #include #define TEST_DATA { 'a', 'b', 'c' } #define MAX_MESSAGE_SIZE 3 #include "../src/thrift/c_glib/transport/thrift_buffered_transport.c" static void thrift_server (const int port); static void thrift_socket_server_open (const int port, int times); static void test_open_and_close(void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; GError *err = NULL; pid_t pid; int port = 51199; int status; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_socket_server_open (port,1); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); /* this shouldn't work */ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE); g_assert (thrift_buffered_transport_is_open (transport) == TRUE); g_assert (thrift_buffered_transport_close (transport, NULL) == TRUE); g_object_unref (transport); g_object_unref (tsocket); /* try and underlying socket failure */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken", NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); g_assert (thrift_buffered_transport_open (transport, &err) == FALSE); g_object_unref (transport); g_object_unref (tsocket); g_error_free (err); err = NULL; g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void test_read_and_write(void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; int port = 51199; guchar buf[3] = TEST_DATA; /* a buffer */ pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_server (port); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), "w_buf_size", 4, NULL); g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE); g_assert (thrift_buffered_transport_is_open (transport)); /* write 3 bytes */ thrift_buffered_transport_write (transport, buf, 3, NULL); /* write 4 bytes */ thrift_buffered_transport_write (transport, buf, 4, NULL); thrift_buffered_transport_write_end (transport, NULL); thrift_buffered_transport_flush (transport, NULL); thrift_buffered_transport_close (transport, NULL); g_object_unref (transport); g_object_unref (tsocket); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void thrift_socket_server_open (const int port, int times) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; int i; ThriftConfiguration *tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, "configuration", tconfiguration, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); THRIFT_SERVER_TRANSPORT_GET_CLASS (tsocket)->resetConsumedMessageSize(transport, -1, NULL); thrift_server_transport_listen (transport, NULL); for(i=0;i #include #include #include #include static const gchar TEST_DATA[11] = "abcdefghij"; #include "../src/thrift/c_glib/transport/thrift_memory_buffer.c" /* test object creation and destruction */ static void test_create_and_destroy (void) { GObject *object = NULL; object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 10, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_create_and_destroy_large (void) { GObject *object = NULL; object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 10 * 1024 * 1024, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_create_and_destroy_default (void) { GObject *object = NULL; object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_create_and_destroy_external (void) { GObject *object = NULL; GByteArray *buf = g_byte_array_new (); g_assert (buf != NULL); object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf", buf, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_create_and_destroy_unowned (void) { GObject *object = NULL; GValue val = G_VALUE_INIT; GByteArray *buf; object = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "owner", FALSE, NULL); g_assert (object != NULL); g_value_init (&val, G_TYPE_POINTER); g_object_get_property (object, "buf", &val); buf = (GByteArray*) g_value_get_pointer (&val); g_assert (buf != NULL); g_byte_array_unref (buf); g_value_unset (&val); g_object_unref (object); } static void test_open_and_close (void) { ThriftMemoryBuffer *tbuffer = NULL; /* create a ThriftMemoryBuffer */ tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL); /* no-ops */ g_assert (thrift_memory_buffer_open (THRIFT_TRANSPORT (tbuffer), NULL) == TRUE); g_assert (thrift_memory_buffer_is_open (THRIFT_TRANSPORT (tbuffer)) == TRUE); g_assert (thrift_memory_buffer_close (THRIFT_TRANSPORT (tbuffer), NULL) == TRUE); g_object_unref (tbuffer); } static void test_read_and_write (void) { ThriftMemoryBuffer *tbuffer = NULL; gint got, want; gchar read[10]; gchar *b; GError *error = NULL; tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 5, NULL); g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer), (gpointer) TEST_DATA, 10, &error) == FALSE); g_assert (error != NULL); g_error_free (error); error = NULL; g_object_unref (tbuffer); tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 15, NULL); g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer), (gpointer) TEST_DATA, 10, &error) == TRUE); g_assert (error == NULL); memset(read, 0, 10); b = read; want = 10; while (want > 0) { got = thrift_memory_buffer_read (THRIFT_TRANSPORT (tbuffer), (gpointer) b, want, &error); g_assert (got > 0 && got <= want); g_assert (error == NULL); b += got; want -= got; } g_assert (memcmp (read, TEST_DATA, 10) == 0); g_object_unref (tbuffer); } static void test_read_and_write_default (void) { ThriftMemoryBuffer *tbuffer = NULL; gint got, want, i; gchar read[10]; gchar *b; GError *error = NULL; tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL); for (i = 0; i < 100; ++i) { g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer), (gpointer) TEST_DATA, 10, &error) == TRUE); g_assert (error == NULL); } for (i = 0; i < 100; ++i) { memset(read, 0, 10); b = read; want = 10; while (want > 0) { got = thrift_memory_buffer_read (THRIFT_TRANSPORT (tbuffer), (gpointer) b, want, &error); g_assert (got > 0 && got <= want); g_assert (error == NULL); b += got; want -= got; } g_assert (memcmp (read, TEST_DATA, 10) == 0); } g_object_unref (tbuffer); } static void test_read_and_write_external (void) { ThriftMemoryBuffer *tbuffer = NULL; GError *error = NULL; GByteArray *buf = g_byte_array_new (); g_assert (buf != NULL); tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf", buf, NULL); g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer), (gpointer) TEST_DATA, 10, &error) == TRUE); g_assert (error == NULL); g_assert (memcmp (buf->data, TEST_DATA, 10) == 0); g_object_unref (tbuffer); } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testmemorybuffer/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testmemorybuffer/CreateAndDestroyLarge", test_create_and_destroy_large); g_test_add_func ("/testmemorybuffer/CreateAndDestroyUnlimited", test_create_and_destroy_default); g_test_add_func ("/testmemorybuffer/CreateAndDestroyExternal", test_create_and_destroy_external); g_test_add_func ("/testmemorybuffer/CreateAndDestroyUnowned", test_create_and_destroy_unowned); g_test_add_func ("/testmemorybuffer/OpenAndClose", test_open_and_close); g_test_add_func ("/testmemorybuffer/ReadAndWrite", test_read_and_write); g_test_add_func ("/testmemorybuffer/ReadAndWriteUnlimited", test_read_and_write_default); g_test_add_func ("/testmemorybuffer/ReadAndWriteExternal", test_read_and_write_external); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testthriftcompactreadcheck.c0000664000175000017500000002272615165535636024117 0ustar00buildbuild00000000000000/* * 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. */ /* Disable string-function optimizations when glibc is used, as these produce compiler warnings about string length when a string function is used inside a call to g_assert () */ #if !defined(__APPLE__) && !defined(__FreeBSD__) && \ !defined(__OpenBSD__) && !defined(__NetBSD__) #include #endif #ifdef __GLIBC__ #define __NO_STRING_INLINES 1 #endif #include #include #include #include #include #include #include #include #include #include #define TEST_BOOL TRUE #define TEST_BYTE 123 #define TEST_I16 12345 #define TEST_I32 1234567890 #define TEST_I64 123456789012345 #define TEST_NI16 (-12345) #define TEST_NI32 (-1234567890) #define TEST_NI64 (-123456789012345) #define TEST_DOUBLE 1234567890.123 #define TEST_STRING "this is a test string 1234567890!@#$%^&*()" #define TEST_PORT 51199 #define MAX_MESSAGE_SIZE 2 static int transport_read_count = 0; static int transport_read_error = 0; static int transport_read_error_at = -1; gint32 my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { if (transport_read_count != transport_read_error_at && transport_read_error == 0) { transport_read_count++; return thrift_transport_read_all (transport, buf, len, error); } return -1; } static int transport_write_count = 0; static int transport_write_error = 0; static int transport_write_error_at = -1; gboolean my_thrift_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { if (transport_write_count != transport_write_error_at && transport_write_error == 0) { transport_write_count++; return thrift_transport_write (transport, buf, len, error); } return FALSE; } #define thrift_transport_read_all my_thrift_transport_read_all #define thrift_transport_write my_thrift_transport_write #include "../src/thrift/c_glib/protocol/thrift_compact_protocol.c" #undef thrift_transport_read_all #undef thrift_transport_write static void thrift_server_complex_types (const int port); static void test_create_and_destroy (void) { GObject *object = NULL; /* create an object and then destroy it */ object = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_initialize (void) { ThriftSocket *tsocket = NULL; ThriftCompactProtocol *protocol = NULL; ThriftSocket *temp = NULL; ThriftConfiguration *tconfiguration = NULL; ThriftConfiguration *tempconf = NULL; glong tempsize = 0; /* create a ThriftConfiguration */ tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); /* create a ThriftTransport */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", 51188, "configuration", tconfiguration, "remainingmessagesize", MAX_MESSAGE_SIZE, NULL); g_assert (tsocket != NULL); /* fetch the properties */ g_object_get (G_OBJECT (tconfiguration), "max_message_size", &tempsize, NULL); g_assert (tempsize == MAX_MESSAGE_SIZE); /* fetch the properties */ g_object_get (G_OBJECT (tsocket), "remainingmessagesize", &tempsize, NULL); g_assert (tempsize == MAX_MESSAGE_SIZE); /* fetch the properties */ g_object_get (G_OBJECT (tsocket), "configuration", &tempconf, NULL); g_object_unref (tempconf); /* create a ThriftCompactProtocol using the Transport */ protocol = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", tsocket, NULL); g_assert (protocol != NULL); /* fetch the properties */ g_object_get (G_OBJECT (protocol), "transport", &temp, NULL); g_object_unref (temp); /* clean up memory */ g_object_unref (protocol); g_object_unref (tsocket); } static void test_read_and_write_complex_types (void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftCompactProtocol *tc = NULL; ThriftProtocol *protocol = NULL; int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_complex_types (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = THRIFT_TRANSPORT (tsocket); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a ThriftCompactTransport */ tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", tsocket, NULL); protocol = THRIFT_PROTOCOL (tc); g_assert (protocol != NULL); g_assert (thrift_compact_protocol_write_map_begin (protocol, T_VOID, T_BYTE, 1, NULL) > 0); g_assert (thrift_compact_protocol_write_map_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_map_begin (protocol, T_VOID, T_BYTE, 3, NULL) > 0); g_assert (thrift_compact_protocol_write_map_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_list_begin (protocol, T_BYTE, 1, NULL) > 0); g_assert (thrift_compact_protocol_write_list_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_write_list_begin (protocol, T_I32, 3, NULL) > 0); g_assert (thrift_compact_protocol_write_list_end (protocol, NULL) == 0); /* clean up */ thrift_transport_close (transport, NULL); g_object_unref (tsocket); g_object_unref (protocol); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void thrift_server_complex_types (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftCompactProtocol *tc = NULL; ThriftProtocol *protocol = NULL; ThriftType element_type, key_type, value_type; guint32 size = 0; ThriftConfiguration *tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, "configuration", tconfiguration, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); THRIFT_SERVER_TRANSPORT_GET_CLASS (tsocket)->resetConsumedMessageSize(transport, -1, NULL); thrift_server_transport_listen (transport, NULL); client = thrift_server_transport_accept (transport, NULL); g_assert (client != NULL); tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL (tc); g_assert (thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) > 0); g_assert (thrift_compact_protocol_read_map_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); g_assert (thrift_compact_protocol_read_map_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type, &size, NULL) > 0); g_assert (thrift_compact_protocol_read_list_end (protocol, NULL) == 0); g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type, &size, NULL) == -1); g_assert (thrift_compact_protocol_read_list_end (protocol, NULL) == 0); g_object_unref (client); g_object_unref (tsocket); g_object_unref (tconfiguration); } int main (int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testthriftcompactreadcheck/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testthriftcompactreadcheck/Initialize", test_initialize); g_test_add_func ("/testthriftcompactreadcheck/ReadAndWriteComplexTypes", test_read_and_write_complex_types); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testzlibtransport.c0000664000175000017500000001623415165535636022330 0ustar00buildbuild00000000000000/* * 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 #include #include #define TEST_DATA \ { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', \ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', \ 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', \ '5', '6', '7', '8', '9', '0' } #include "../src/thrift/c_glib/transport/thrift_zlib_transport.c" static void thrift_server (const int port); static void thrift_socket_server_open (const int port, int times); /* test object creation and destruction */ static void test_create_and_destroy(void) { ThriftTransport *transport = NULL; gint urbuf_size = 0; gint crbuf_size = 0; gint uwbuf_size = 0; gint cwbuf_size = 0; gint comp_level = 0; GObject *object = NULL; object = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, NULL); g_assert (object != NULL); g_object_get (G_OBJECT (object), "transport", &transport, "urbuf_size", &urbuf_size, "crbuf_size", &crbuf_size, "uwbuf_size", &uwbuf_size, "cwbuf_size", &cwbuf_size, "comp_level", &comp_level, NULL); g_object_unref (object); } static void test_open_and_close(void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; GError *err = NULL; pid_t pid; int port = 51199; int status; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_socket_server_open (port,1); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); /* create a ZlibTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); /* this shouldn't work */ g_assert (thrift_zlib_transport_open (transport, NULL) == TRUE); g_assert (thrift_zlib_transport_is_open (transport) == TRUE); g_assert (thrift_zlib_transport_close (transport, NULL) == TRUE); g_object_unref (transport); g_object_unref (tsocket); /* try and underlying socket failure */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost_broken", NULL); /* create a ZlibTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); g_assert (thrift_zlib_transport_open (transport, &err) == FALSE); g_object_unref (transport); g_object_unref (tsocket); g_error_free (err); err = NULL; g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void test_read_and_write(void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; int port = 51199; gchar buf[36] = TEST_DATA; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_server (port); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); g_assert (thrift_zlib_transport_open (transport, NULL) == TRUE); g_assert (thrift_zlib_transport_is_open (transport)); thrift_zlib_transport_write (transport, buf, 36, NULL); thrift_zlib_transport_flush (transport, NULL); thrift_zlib_transport_write_end (transport, NULL); g_object_unref (transport); g_object_unref (tsocket); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void thrift_socket_server_open (const int port, int times) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; int i; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); for(i=0;i #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TEST_SERVER_HOSTNAME "localhost" #define TEST_SERVER_PORT 9090 /* -------------------------------------------------------------------------- The ContainerService handler we'll use for testing */ G_BEGIN_DECLS GType test_container_service_handler_get_type (void); #define TYPE_TEST_CONTAINER_SERVICE_HANDLER \ (test_container_service_handler_get_type ()) #define TEST_CONTAINER_SERVICE_HANDLER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ TYPE_TEST_CONTAINER_SERVICE_HANDLER, \ TestContainerServiceHandler)) #define TEST_CONTAINER_SERVICE_HANDLER_CLASS(c) \ (G_TYPE_CHECK_CLASS_CAST ((c), \ TYPE_TEST_CONTAINER_SERVICE_HANDLER, \ TestContainerServiceHandlerClass)) #define IS_TEST_CONTAINER_SERVICE_HANDLER(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ TYPE_TEST_CONTAINER_SERVICE_HANDLER)) #define IS_TEST_CONTAINER_SERVICE_HANDLER_CLASS(c) \ (G_TYPE_CHECK_CLASS_TYPE ((c), \ TYPE_TEST_CONTAINER_SERVICE_HANDLER)) #define TEST_CONTAINER_SERVICE_HANDLER_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ TYPE_TEST_CONTAINER_SERVICE_HANDLER, \ TestContainerServiceHandlerClass)) struct _TestContainerServiceHandler { TTestContainerServiceHandler parent_instance; /* private */ GPtrArray *string_list; }; typedef struct _TestContainerServiceHandler TestContainerServiceHandler; struct _TestContainerServiceHandlerClass { TTestContainerServiceHandlerClass parent_class; }; typedef struct _TestContainerServiceHandlerClass TestContainerServiceHandlerClass; G_END_DECLS /* -------------------------------------------------------------------------- */ G_DEFINE_TYPE (TestContainerServiceHandler, test_container_service_handler, T_TEST_TYPE_CONTAINER_SERVICE_HANDLER) /* A helper function used to append copies of strings to a string list */ static void append_string_to_ptr_array (gpointer element, gpointer ptr_array) { g_ptr_array_add ((GPtrArray *)ptr_array, g_strdup ((gchar *)element)); } /* Accept a string list from the client and append its contents to our internal list */ static gboolean test_container_service_handler_receive_string_list (TTestContainerServiceIf *iface, const GPtrArray *stringList, GError **error) { TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface); /* Append the client's strings to our own internal string list */ g_ptr_array_foreach ((GPtrArray *)stringList, append_string_to_ptr_array, self->string_list); g_clear_error (error); return TRUE; } /* Return the contents of our internal string list to the client */ static gboolean test_container_service_handler_return_string_list (TTestContainerServiceIf *iface, GPtrArray **_return, GError **error) { TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface); /* Return (copies of) the strings contained in our list */ g_ptr_array_foreach (self->string_list, append_string_to_ptr_array, *_return); g_clear_error (error); return TRUE; } static gboolean test_container_service_handler_return_list_string_list (TTestContainerServiceIf *iface, GPtrArray **_return, GError **error) { TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface); GPtrArray *nested_list; /* Return a list containing our list of strings */ nested_list = g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref); g_ptr_array_add (nested_list, self->string_list); g_ptr_array_ref (self->string_list); g_ptr_array_add (*_return, nested_list); g_clear_error (error); return TRUE; } static gboolean test_container_service_handler_return_typedefd_list_string_list (TTestContainerServiceIf *iface, TTestListStringList **_return, GError **error) { TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (iface); TTestStringList *nested_list; /* Return a list containing our list of strings */ nested_list = g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref); g_ptr_array_add (nested_list, self->string_list); g_ptr_array_ref (self->string_list); g_ptr_array_add (*_return, nested_list); g_clear_error (error); return TRUE; } static void test_container_service_handler_finalize (GObject *object) { TestContainerServiceHandler *self = TEST_CONTAINER_SERVICE_HANDLER (object); /* Destroy our internal containers */ g_ptr_array_unref (self->string_list); self->string_list = NULL; G_OBJECT_CLASS (test_container_service_handler_parent_class)-> finalize (object); } static void test_container_service_handler_init (TestContainerServiceHandler *self) { /* Create our internal containers */ self->string_list = g_ptr_array_new_with_free_func (g_free); } static void test_container_service_handler_class_init (TestContainerServiceHandlerClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); TTestContainerServiceHandlerClass *parent_class = T_TEST_CONTAINER_SERVICE_HANDLER_CLASS (klass); gobject_class->finalize = test_container_service_handler_finalize; parent_class->receive_string_list = test_container_service_handler_receive_string_list; parent_class->return_string_list = test_container_service_handler_return_string_list; parent_class->return_list_string_list = test_container_service_handler_return_list_string_list; parent_class->return_typedefd_list_string_list = test_container_service_handler_return_typedefd_list_string_list; } /* -------------------------------------------------------------------------- */ /* Our test server, declared globally so we can access it within a signal handler */ ThriftServer *server = NULL; /* A signal handler used to detect when the child process (the test suite) has exited so we know to shut down the server and terminate ourselves */ static void sigchld_handler (int signal_number) { THRIFT_UNUSED_VAR (signal_number); /* The child process (the tests) has exited or been terminated; shut down the server gracefully */ if (server != NULL) thrift_server_stop (server); } /* A helper function that executes a test case against a newly constructed service client */ static void execute_with_service_client (void (*test_case)(TTestContainerServiceIf *, GError **)) { ThriftSocket *socket; ThriftTransport *transport; ThriftProtocol *protocol; TTestContainerServiceIf *client; GError *error = NULL; /* Create a client with which to access the server */ socket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", TEST_SERVER_HOSTNAME, "port", TEST_SERVER_PORT, NULL); transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport", socket, NULL); protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL); thrift_transport_open (transport, &error); g_assert_no_error (error); client = g_object_new (T_TEST_TYPE_CONTAINER_SERVICE_CLIENT, "input_protocol", protocol, "output_protocol", protocol, NULL); /* Execute the test against this client */ (*test_case)(client, &error); g_assert_no_error (error); /* Clean up and exit */ thrift_transport_close (transport, NULL); g_object_unref (client); g_object_unref (protocol); g_object_unref (transport); g_object_unref (socket); } static void test_containers_with_default_values (void) { TTestContainersWithDefaultValues *default_values; GPtrArray *string_list; /* Fetch a new ContainersWithDefaultValues struct and its StringList member */ default_values = g_object_new (T_TEST_TYPE_CONTAINERS_WITH_DEFAULT_VALUES, NULL); g_object_get (default_values, "StringList", &string_list, NULL); /* Make sure the list has been populated with its default values */ g_assert_cmpint (string_list->len, ==, 2); g_assert_cmpstr (((gchar **)string_list->pdata)[0], ==, "Apache"); g_assert_cmpstr (((gchar **)string_list->pdata)[1], ==, "Thrift"); g_ptr_array_unref (string_list); g_object_unref (default_values); } static void test_container_service_string_list_inner (TTestContainerServiceIf *client, GError **error) { gchar *test_data[] = { "one", "two", "three" }; GPtrArray *outgoing_string_list; GPtrArray *incoming_string_list; guint index; g_clear_error (error); /* Prepare our test data (our string list to send) */ outgoing_string_list = g_ptr_array_new (); for (index = 0; index < 3; index += 1) g_ptr_array_add (outgoing_string_list, &test_data[index]); /* Send our data to the server and make sure we get the same data back on retrieve */ g_assert (t_test_container_service_client_receive_string_list (client, outgoing_string_list, error) && *error == NULL); incoming_string_list = g_ptr_array_new (); g_assert (t_test_container_service_client_return_string_list (client, &incoming_string_list, error) && *error == NULL); /* Make sure the two lists are equivalent */ g_assert_cmpint (incoming_string_list->len, ==, outgoing_string_list->len); for (index = 0; index < incoming_string_list->len; index += 1) g_assert_cmpstr (((gchar **)incoming_string_list->pdata)[index], ==, ((gchar **)outgoing_string_list->pdata)[index]); /* Clean up and exit */ g_ptr_array_unref (incoming_string_list); g_ptr_array_unref (outgoing_string_list); } static void test_container_service_string_list (void) { execute_with_service_client (test_container_service_string_list_inner); } static void test_container_service_list_string_list_inner (TTestContainerServiceIf *client, GError **error) { GPtrArray *incoming_list; GPtrArray *nested_list; g_clear_error (error); /* Receive a list of string lists from the server */ incoming_list = g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref); g_assert (t_test_container_service_client_return_list_string_list (client, &incoming_list, error) && *error == NULL); /* Make sure the list and its contents are valid */ g_assert_cmpint (incoming_list->len, >, 0); nested_list = (GPtrArray *)g_ptr_array_index (incoming_list, 0); g_assert (nested_list != NULL); g_assert_cmpint (nested_list->len, >=, 0); /* Clean up and exit */ g_ptr_array_unref (incoming_list); } static void test_container_service_list_string_list (void) { execute_with_service_client (test_container_service_list_string_list_inner); } static void test_container_service_typedefd_list_string_list_inner (TTestContainerServiceIf *client, GError **error) { TTestListStringList *incoming_list; TTestStringList *nested_list; g_clear_error (error); /* Receive a list of string lists from the server */ incoming_list = g_ptr_array_new_with_free_func ((GDestroyNotify)g_ptr_array_unref); g_assert (t_test_container_service_client_return_list_string_list (client, &incoming_list, error) && *error == NULL); /* Make sure the list and its contents are valid */ g_assert_cmpint (incoming_list->len, >, 0); nested_list = (TTestStringList *)g_ptr_array_index (incoming_list, 0); g_assert (nested_list != NULL); g_assert_cmpint (nested_list->len, >=, 0); /* Clean up and exit */ g_ptr_array_unref (incoming_list); } static void test_container_service_typedefd_list_string_list (void) { execute_with_service_client (test_container_service_typedefd_list_string_list_inner); } int main(int argc, char *argv[]) { pid_t pid; int status; #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif /* Fork to run our test suite in a child process */ pid = fork (); g_assert_cmpint (pid, >=, 0); if (pid == 0) { /* The child process */ /* Wait a moment for the server to finish starting */ sleep (1); g_test_init (&argc, &argv, NULL); g_test_add_func ("/testcontainertest/ContainerTest/Structs/ContainersWithDefaultValues", test_containers_with_default_values); g_test_add_func ("/testcontainertest/ContainerTest/Services/ContainerService/StringList", test_container_service_string_list); g_test_add_func ("/testcontainertest/ContainerTest/Services/ContainerService/ListStringList", test_container_service_list_string_list); g_test_add_func ("/testcontainertest/ContainerTest/Services/ContainerService/TypedefdListStringList", test_container_service_typedefd_list_string_list); /* Run the tests and make the result available to our parent process */ _exit (g_test_run ()); } else { TTestContainerServiceHandler *handler; TTestContainerServiceProcessor *processor; ThriftServerTransport *server_transport; ThriftTransportFactory *transport_factory; ThriftProtocolFactory *protocol_factory; struct sigaction sigchld_action; GError *error = NULL; int exit_status = 1; /* Trap the event of the child process terminating so we know to stop the server and exit */ memset (&sigchld_action, 0, sizeof (sigchld_action)); sigchld_action.sa_handler = sigchld_handler; sigchld_action.sa_flags = SA_RESETHAND; sigaction (SIGCHLD, &sigchld_action, NULL); /* Create our test server */ handler = g_object_new (TYPE_TEST_CONTAINER_SERVICE_HANDLER, NULL); processor = g_object_new (T_TEST_TYPE_CONTAINER_SERVICE_PROCESSOR, "handler", handler, NULL); server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", TEST_SERVER_PORT, NULL); transport_factory = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY, NULL); protocol_factory = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY, NULL); server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER, "processor", processor, "server_transport", server_transport, "input_transport_factory", transport_factory, "output_transport_factory", transport_factory, "input_protocol_factory", protocol_factory, "output_protocol_factory", protocol_factory, NULL); /* Start the server */ thrift_server_serve (server, &error); /* Make sure the server stopped only because it was interrupted (by the child process terminating) */ g_assert(!error || g_error_matches(error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_ACCEPT)); /* Free our resources */ g_clear_object (&server); g_clear_object (&protocol_factory); g_clear_object (&transport_factory); g_clear_object (&server_transport); g_clear_object (&processor); g_clear_object (&handler); /* Wait for the child process to complete and return its exit status */ g_assert (wait (&status) == pid); if (WIFEXITED (status)) exit_status = WEXITSTATUS (status); return exit_status; } } thrift-0.23.0/lib/c_glib/test/testserialization.c0000664000175000017500000000674315165535636022274 0ustar00buildbuild00000000000000#include #include #include #include #include "gen-c_glib/t_test_debug_proto_test_types.h" #include "gen-c_glib/t_test_enum_test_types.h" static void enum_constants_read_write() { GError* error = NULL; ThriftTransport* transport = THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 1024, NULL)); ThriftProtocol* protocol = THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL)); TTestEnumTestStruct* src = T_TEST_ENUM_TEST; TTestEnumTestStruct* dst = g_object_new(T_TEST_TYPE_ENUM_TEST_STRUCT, NULL); TTestEnumTestStructClass* cls = T_TEST_ENUM_TEST_STRUCT_GET_CLASS(src); int write_len; int read_len; write_len = THRIFT_STRUCT_CLASS(cls)->write(THRIFT_STRUCT(src), protocol, &error); g_assert(!error); g_assert(write_len > 0); read_len = THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(dst), protocol, &error); g_assert(!error); g_assert_cmpint(write_len, ==, read_len); g_object_unref(dst); g_object_unref(protocol); g_object_unref(transport); } static void struct_constants_read_write() { GError* error = NULL; ThriftTransport* transport = THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 4096, NULL)); ThriftProtocol* protocol = THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL)); TTestCompactProtoTestStruct* src = T_TEST_COMPACT_TEST; TTestCompactProtoTestStruct* dst = g_object_new(T_TEST_TYPE_COMPACT_PROTO_TEST_STRUCT, NULL); TTestCompactProtoTestStructClass* cls = T_TEST_COMPACT_PROTO_TEST_STRUCT_GET_CLASS(src); int write_len; int read_len; write_len = THRIFT_STRUCT_CLASS(cls)->write(THRIFT_STRUCT(src), protocol, &error); g_assert(!error); g_assert(write_len > 0); read_len = THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(dst), protocol, &error); g_assert(!error); g_assert_cmpint(write_len, ==, read_len); g_object_unref(dst); g_object_unref(protocol); g_object_unref(transport); } static void struct_read_write_length_should_equal() { GError* error = NULL; ThriftTransport* transport = THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 2048, NULL)); ThriftProtocol* protocol = THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL)); TTestBonk* src = g_object_new(T_TEST_TYPE_BONK, NULL); TTestBonk* dst = g_object_new(T_TEST_TYPE_BONK, NULL); TTestBonkClass* cls = T_TEST_BONK_GET_CLASS(src); int write_len; int read_len; write_len = THRIFT_STRUCT_CLASS(cls)->write(THRIFT_STRUCT(src), protocol, &error); g_assert(!error); g_assert(write_len > 0); read_len = THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(dst), protocol, &error); g_assert(!error); g_assert_cmpint(write_len, ==, read_len); g_object_unref(dst); g_object_unref(src); g_object_unref(protocol); g_object_unref(transport); } int main(int argc, char* argv[]) { #if (!GLIB_CHECK_VERSION(2, 36, 0)) g_type_init(); #endif g_test_init(&argc, &argv, NULL); g_test_add_func("/testserialization/StructReadWriteLengthShouldEqual", struct_read_write_length_should_equal); g_test_add_func("/testserialization/StructConstants", struct_constants_read_write); g_test_add_func("/testserialization/EnumConstants", enum_constants_read_write); return g_test_run(); } thrift-0.23.0/lib/c_glib/test/ContainerTest.thrift0000664000175000017500000000227215165535636022350 0ustar00buildbuild00000000000000/* * 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 c_glib TTest typedef list StringList typedef list ListStringList struct ContainersWithDefaultValues { 1: list StringList = [ "Apache", "Thrift" ]; } service ContainerService { void receiveStringList(1: list stringList); list returnStringList(); list> returnListStringList(); ListStringList returnTypedefdListStringList(); } thrift-0.23.0/lib/c_glib/test/fuzz/0000755000175000017500000000000015170007200017306 5ustar00buildbuild00000000000000thrift-0.23.0/lib/c_glib/test/fuzz/fuzz_parse_compact.c0000664000175000017500000000554215165535636023407 0ustar00buildbuild00000000000000/* * 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 #include #include "gen-c_glib/fuzz_test_no_uuid_types.h" #include // 10MB message size limit to prevent over-allocation during fuzzing #define FUZZ_MAX_MESSAGE_SIZE (10 * 1024 * 1024) int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { GError* error = NULL; // Create a GByteArray with the fuzz data GByteArray* byte_array = g_byte_array_new(); g_byte_array_append(byte_array, data, size); // Create a ThriftConfiguration with message size limits ThriftConfiguration* tconfiguration = g_object_new(THRIFT_TYPE_CONFIGURATION, "max_message_size", FUZZ_MAX_MESSAGE_SIZE, "max_frame_size", FUZZ_MAX_MESSAGE_SIZE, NULL); // Create a memory buffer transport with the byte array and configuration ThriftTransport* transport = THRIFT_TRANSPORT( g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf", byte_array, "buf_size", size, "configuration", tconfiguration, NULL)); // Create a compact protocol ThriftProtocol* protocol = THRIFT_PROTOCOL( g_object_new(THRIFT_TYPE_COMPACT_PROTOCOL, "transport", transport, NULL)); // // Create a FuzzTest struct to read into FuzzTest* test_struct = g_object_new(TYPE_FUZZ_TEST, NULL); FuzzTestClass* cls = FUZZ_TEST_GET_CLASS(test_struct); // Try to read the struct from the fuzz data THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(test_struct), protocol, &error); // Clean up g_object_unref(test_struct); g_object_unref(protocol); g_object_unref(transport); g_object_unref(tconfiguration); if (error) { g_error_free(error); } return 0; } thrift-0.23.0/lib/c_glib/test/fuzz/fuzz_parse_binary.c0000664000175000017500000000553415165535636023246 0ustar00buildbuild00000000000000/* * 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 #include #include "gen-c_glib/fuzz_test_no_uuid_types.h" #include // 10MB message size limit to prevent over-allocation during fuzzing #define FUZZ_MAX_MESSAGE_SIZE (10 * 1024 * 1024) int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { GError* error = NULL; // Create a GByteArray with the fuzz data GByteArray* byte_array = g_byte_array_new(); g_byte_array_append(byte_array, data, size); // Create a ThriftConfiguration with message size limits ThriftConfiguration* tconfiguration = g_object_new(THRIFT_TYPE_CONFIGURATION, "max_message_size", FUZZ_MAX_MESSAGE_SIZE, "max_frame_size", FUZZ_MAX_MESSAGE_SIZE, NULL); // Create a memory buffer transport with the byte array and configuration ThriftTransport* transport = THRIFT_TRANSPORT( g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf", byte_array, "buf_size", size, "configuration", tconfiguration, NULL)); // Create a binary protocol ThriftProtocol* protocol = THRIFT_PROTOCOL( g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL)); // Create a FuzzTest struct to read into FuzzTest* test_struct = g_object_new(TYPE_FUZZ_TEST, NULL); FuzzTestClass* cls = FUZZ_TEST_GET_CLASS(test_struct); // Try to read the struct from the fuzz data THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(test_struct), protocol, &error); // Clean up g_object_unref(test_struct); g_object_unref(protocol); g_object_unref(transport); g_object_unref(tconfiguration); if (error) { g_error_free(error); } return 0; } thrift-0.23.0/lib/c_glib/test/fuzz/README.md0000664000175000017500000000206315165535636020617 0ustar00buildbuild00000000000000# C GLib Fuzzing README To build the fuzz targets, run `make check` in this directory. The build system uses LLVM's libFuzzer for fuzzing the C GLib Thrift implementation. These are standard libFuzzer targets, so you can run them using the standard libFuzzer interface. After building, you can run a fuzzer using: ```bash ./ ``` We currently have two fuzz targets: * fuzz_parse_binary -- fuzzes the deserialization of the Binary protocol * fuzz_parse_compact -- fuzzes the deserialization of the Compact protocol * TODO: Add round trip fuzzers, similar to other languages. The fuzzers use libFuzzer's built-in mutation engine to generate test cases. Each fuzzer implements the standard `LLVMFuzzerTestOneInput` interface. For more information about libFuzzer and its options, see the [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html). You can also use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these C GLib fuzzers, since the wire formats are identical between implementations. thrift-0.23.0/lib/c_glib/test/fuzz/Makefile.in0000644000175000017500000006766515170007166021412 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USING_CLANG_TRUE@am__append_1 = -fsanitize=fuzzer check_PROGRAMS = fuzz_parse_compact$(EXEEXT) \ fuzz_parse_binary$(EXEEXT) subdir = lib/c_glib/test/fuzz ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libtestgencfuzz_la_DEPENDENCIES = \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la am__dirstamp = $(am__leading_dot)dirstamp nodist_libtestgencfuzz_la_OBJECTS = \ gen-c_glib/fuzz_test_no_uuid_types.lo libtestgencfuzz_la_OBJECTS = $(nodist_libtestgencfuzz_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_fuzz_parse_binary_OBJECTS = fuzz_parse_binary.$(OBJEXT) fuzz_parse_binary_OBJECTS = $(am_fuzz_parse_binary_OBJECTS) fuzz_parse_binary_DEPENDENCIES = libtestgencfuzz.la \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_fuzz_parse_compact_OBJECTS = fuzz_parse_compact.$(OBJEXT) fuzz_parse_compact_OBJECTS = $(am_fuzz_parse_compact_OBJECTS) fuzz_parse_compact_DEPENDENCIES = libtestgencfuzz.la \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/fuzz_parse_binary.Po \ ./$(DEPDIR)/fuzz_parse_compact.Po \ gen-c_glib/$(DEPDIR)/fuzz_test_no_uuid_types.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist_libtestgencfuzz_la_SOURCES) \ $(fuzz_parse_binary_SOURCES) $(fuzz_parse_compact_SOURCES) DIST_SOURCES = $(fuzz_parse_binary_SOURCES) \ $(fuzz_parse_compact_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc noinst_LTLIBRARIES = libtestgencfuzz.la nodist_libtestgencfuzz_la_SOURCES = \ gen-c_glib/fuzz_test_no_uuid_types.c \ gen-c_glib/fuzz_test_no_uuid_types.h libtestgencfuzz_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir) AM_CFLAGS = -g $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir) AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(am__append_1) fuzz_parse_compact_SOURCES = fuzz_parse_compact.c fuzz_parse_compact_LDADD = \ libtestgencfuzz.la \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o fuzz_parse_binary_SOURCES = fuzz_parse_binary.c fuzz_parse_binary_LDADD = \ libtestgencfuzz.la \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/c_glib/test/fuzz/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/c_glib/test/fuzz/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gen-c_glib/$(am__dirstamp): @$(MKDIR_P) gen-c_glib @: > gen-c_glib/$(am__dirstamp) gen-c_glib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gen-c_glib/$(DEPDIR) @: > gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/fuzz_test_no_uuid_types.lo: gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) libtestgencfuzz.la: $(libtestgencfuzz_la_OBJECTS) $(libtestgencfuzz_la_DEPENDENCIES) $(EXTRA_libtestgencfuzz_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libtestgencfuzz_la_OBJECTS) $(libtestgencfuzz_la_LIBADD) $(LIBS) fuzz_parse_binary$(EXEEXT): $(fuzz_parse_binary_OBJECTS) $(fuzz_parse_binary_DEPENDENCIES) $(EXTRA_fuzz_parse_binary_DEPENDENCIES) @rm -f fuzz_parse_binary$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fuzz_parse_binary_OBJECTS) $(fuzz_parse_binary_LDADD) $(LIBS) fuzz_parse_compact$(EXEEXT): $(fuzz_parse_compact_OBJECTS) $(fuzz_parse_compact_DEPENDENCIES) $(EXTRA_fuzz_parse_compact_DEPENDENCIES) @rm -f fuzz_parse_compact$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fuzz_parse_compact_OBJECTS) $(fuzz_parse_compact_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f gen-c_glib/*.$(OBJEXT) -rm -f gen-c_glib/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzz_parse_binary.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fuzz_parse_compact.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/fuzz_test_no_uuid_types.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf gen-c_glib/.libs gen-c_glib/_libs style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f gen-c_glib/$(DEPDIR)/$(am__dirstamp) -rm -f gen-c_glib/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/fuzz_parse_binary.Po -rm -f ./$(DEPDIR)/fuzz_parse_compact.Po -rm -f gen-c_glib/$(DEPDIR)/fuzz_test_no_uuid_types.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/fuzz_parse_binary.Po -rm -f ./$(DEPDIR)/fuzz_parse_compact.Po -rm -f gen-c_glib/$(DEPDIR)/fuzz_test_no_uuid_types.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am style-am style-local tags tags-am \ uninstall uninstall-am .PRECIOUS: Makefile # # Common thrift code generation rules # gen-c_glib/fuzz_test_no_uuid_types.c gen-c_glib/fuzz_test_no_uuid_types.h: $(top_srcdir)/test/v0.16/FuzzTestNoUuid.thrift $(THRIFT) --gen c_glib -r $< # Ensure generated headers exist before compiling sources that include them fuzz_parse_compact.$(OBJEXT): gen-c_glib/fuzz_test_no_uuid_types.h fuzz_parse_binary.$(OBJEXT): gen-c_glib/fuzz_test_no_uuid_types.h clean-local: $(RM) -r gen-c_glib/ $(RM) *.o $(RM) libtestgencfuzz.la # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/c_glib/test/fuzz/Makefile.am0000664000175000017500000000523615170007142021357 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc noinst_LTLIBRARIES = libtestgencfuzz.la nodist_libtestgencfuzz_la_SOURCES = \ gen-c_glib/fuzz_test_no_uuid_types.c \ gen-c_glib/fuzz_test_no_uuid_types.h libtestgencfuzz_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir) AM_CFLAGS = -g $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir) AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) if USING_CLANG AM_LDFLAGS += -fsanitize=fuzzer endif check_PROGRAMS = fuzz_parse_compact fuzz_parse_binary fuzz_parse_compact_SOURCES = fuzz_parse_compact.c fuzz_parse_compact_LDADD = \ libtestgencfuzz.la \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o fuzz_parse_binary_SOURCES = fuzz_parse_binary.c fuzz_parse_binary_LDADD = \ libtestgencfuzz.la \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o # # Common thrift code generation rules # gen-c_glib/fuzz_test_no_uuid_types.c gen-c_glib/fuzz_test_no_uuid_types.h: $(top_srcdir)/test/v0.16/FuzzTestNoUuid.thrift $(THRIFT) --gen c_glib -r $< # Ensure generated headers exist before compiling sources that include them fuzz_parse_compact.$(OBJEXT): gen-c_glib/fuzz_test_no_uuid_types.h fuzz_parse_binary.$(OBJEXT): gen-c_glib/fuzz_test_no_uuid_types.h clean-local: $(RM) -r gen-c_glib/ $(RM) *.o $(RM) libtestgencfuzz.la thrift-0.23.0/lib/c_glib/test/testthriftbinaryreadcheck.c0000664000175000017500000002407115165535636023750 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifdef __GLIBC__ #include #define __NO_STRING_INLINES 1 #endif #include #include #include #include #include #include #include #include #include #include #define TEST_BOOL TRUE #define TEST_BYTE 123 #define TEST_I16 12345 #define TEST_I32 1234567890 #define TEST_I64 G_GINT64_CONSTANT (123456789012345) #define TEST_DOUBLE 1234567890.123 #define TEST_STRING "this is a test string 1234567890!@#$%^&*()" #define TEST_PORT 51199 #define MAX_MESSAGE_SIZE 4 static int transport_read_count = 0; static int transport_read_error = 0; static int transport_read_error_at = -1; gint32 my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { if (transport_read_count != transport_read_error_at && transport_read_error == 0) { transport_read_count++; return thrift_transport_read_all (transport, buf, len, error); } return -1; } static int transport_write_count = 0; static int transport_write_error = 0; static int transport_write_error_at = -1; gboolean my_thrift_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { if (transport_write_count != transport_write_error_at && transport_write_error == 0) { transport_write_count++; return thrift_transport_write (transport, buf, len, error); } return FALSE; } #define thrift_transport_read_all my_thrift_transport_read_all #define thrift_transport_write my_thrift_transport_write #include "../src/thrift/c_glib/protocol/thrift_binary_protocol.c" #undef thrift_transport_read_all #undef thrift_transport_write static void thrift_server_complex_types (const int port); static void test_create_and_destroy (void) { GObject *object = NULL; /* create an object and then destroy it */ object = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, NULL); g_assert (object !=NULL); g_object_unref (object); } static void test_initialize (void) { ThriftConfiguration *tconfiguration = NULL; ThriftSocket *tsocket = NULL; ThriftBinaryProtocol *bprotocol = NULL; ThriftSocket *temp = NULL; ThriftConfiguration *tempconf = NULL; glong tempsize = 0; /* create a ThriftConfiguration */ tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); g_assert (tconfiguration != NULL); /* create a ThriftTransport */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", 51188, "path", NULL, "configuration", tconfiguration, "remainingmessagesize", tconfiguration->maxMessageSize_, NULL); g_assert (tsocket != NULL); /* fetch the properties */ g_object_get (G_OBJECT (tconfiguration), "max_message_size", &tempsize, NULL); g_assert (tempsize == MAX_MESSAGE_SIZE); /* fetch the properties */ g_object_get (G_OBJECT (tsocket), "remainingmessagesize", &tempsize, NULL); g_assert (tempsize == MAX_MESSAGE_SIZE); /* fetch the properties */ g_object_get (G_OBJECT (tsocket), "configuration", &tempconf, NULL); g_object_unref (tempconf); /* create a ThriftBinaryProtocol using Transport */ bprotocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", tsocket, NULL); g_assert (bprotocol != NULL); /* fetch the properties */ g_object_get (G_OBJECT (bprotocol), "transport", &temp, NULL); g_object_unref (temp); /* clean up memory */ g_object_unref (bprotocol); g_object_unref (tsocket); g_object_unref (tconfiguration); } void test_read_and_wirte_complex_types (void) { int status; pid_t pid; ThriftConfiguration *tconfiguration = NULL; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftBinaryProtocol *tb = NULL; ThriftProtocol *protocol = NULL; int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_complex_types (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftConfiguration */ tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); g_assert (tconfiguration != NULL); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, "path", NULL, "configuration", tconfiguration, NULL); transport = THRIFT_TRANSPORT (tsocket); THRIFT_TRANSPORT_GET_CLASS (tsocket)->resetConsumedMessageSize(THRIFT_TRANSPORT (tsocket), -1, NULL); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a ThriftBinaryTransport */ tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", tsocket, NULL); protocol = THRIFT_PROTOCOL (tb); g_assert (protocol != NULL); /* test 1st write failure on a map */ g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_BYTE, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_map_end (protocol, NULL) == 0); g_assert (thrift_binary_protocol_write_map_begin (protocol, T_I32, T_BYTE, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_map_end (protocol, NULL) == 0); /* test list operations */ g_assert (thrift_binary_protocol_write_list_begin (protocol, T_BYTE, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_list_end (protocol, NULL) == 0); g_assert (thrift_binary_protocol_write_list_begin (protocol, T_I32, 10, NULL) > 0); g_assert (thrift_binary_protocol_write_list_end (protocol, NULL) == 0); /* clean up */ thrift_transport_close (transport, NULL); g_object_unref (tsocket); g_object_unref (protocol); g_object_unref (tconfiguration); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void thrift_server_complex_types (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftBinaryProtocol *tbp = NULL; ThriftProtocol *protocol = NULL; ThriftType element_type = T_VOID, key_type = T_VOID, value_type = T_VOID; guint32 size = 0; ThriftConfiguration *tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, "configuration", tconfiguration, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); THRIFT_SERVER_TRANSPORT_GET_CLASS (tsocket)->resetConsumedMessageSize(transport, -1, NULL); thrift_server_transport_listen (transport, NULL); client = thrift_server_transport_accept (transport, NULL); g_assert (client != NULL); tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL(tbp); g_assert (thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) > 0); g_assert (thrift_binary_protocol_read_map_end (protocol, NULL) == 0); g_assert (thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); g_assert (thrift_binary_protocol_read_map_end (protocol, NULL) == 0); /* test read failure */ g_assert (thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL) > 0); g_assert (thrift_binary_protocol_read_list_end(protocol, NULL) == 0); g_assert (thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL) == -1); g_assert (thrift_binary_protocol_read_list_end(protocol, NULL) == 0); g_object_unref (client); /* TODO: investigate g_object_unref (tbp); */ g_object_unref (tsocket); g_object_unref (tconfiguration); } int main (int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testthriftbinaryreadcheck/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testthriftbinaryreadcheck/Initialize", test_initialize); g_test_add_func ("/testthriftbinaryreadcheck/test_read_and_write_complex_types", test_read_and_wirte_complex_types); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testthriftframedreadcheck.c0000664000175000017500000001626615165535636023731 0ustar00buildbuild00000000000000/* * 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 #include #define TEST_DATA { 'a', 'b' } #define MAX_MESSAGE_SIZE 2 #include "../src/thrift/c_glib/transport/thrift_framed_transport.c" static void thrift_server (const int port); static void thrift_socket_server_open (const int port, int times); static void test_open_and_close(void) { ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; GError *err = NULL; pid_t pid; int port = 51199; int status; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_socket_server_open (port,1); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); /* this shouldn't work */ g_assert (thrift_framed_transport_open (transport, NULL) == TRUE); g_assert (thrift_framed_transport_is_open (transport) == TRUE); g_assert (thrift_framed_transport_close (transport, NULL) == TRUE); g_object_unref (transport); g_object_unref (tsocket); /* try and underlying socket failure */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken", NULL); /* create a BufferedTransport wrapper of the Socket */ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), NULL); g_assert (thrift_framed_transport_open (transport, &err) == FALSE); g_object_unref (transport); g_object_unref (tsocket); g_error_free (err); err = NULL; g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void test_read_and_write(void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; int port = 51199; guchar buf[10] = TEST_DATA; /* a buffer */ pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ thrift_server (port); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", THRIFT_TRANSPORT (tsocket), "w_buf_size", 4, NULL); g_assert (thrift_framed_transport_open (transport, NULL) == TRUE); g_assert (thrift_framed_transport_is_open (transport)); /* write 2 bytes */ thrift_framed_transport_write (transport, buf, 2, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_write (transport, buf, 3, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_write_end (transport, NULL); thrift_framed_transport_flush (transport, NULL); thrift_framed_transport_close (transport, NULL); g_object_unref (transport); g_object_unref (tsocket); g_assert ( wait (&status) == pid ); g_assert ( status == 0 ); } } static void thrift_socket_server_open (const int port, int times) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; int i; ThriftConfiguration *tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, "configuration", tconfiguration, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); for(i=0;i #define __NO_STRING_INLINES 1 #endif #include #include #include #include #include #include #include #include #include #include #define TEST_BOOL TRUE #define TEST_BYTE 123 #define TEST_I16 12345 #define TEST_I32 1234567890 #define TEST_I64 G_GINT64_CONSTANT (123456789012345) #define TEST_DOUBLE 1234567890.123 #define TEST_STRING "this is a test string 1234567890!@#$%^&*()" #define TEST_PORT 51199 static int transport_read_count = 0; static int transport_read_error = 0; static int transport_read_error_at = -1; gint32 my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { if (transport_read_count != transport_read_error_at && transport_read_error == 0) { transport_read_count++; return thrift_transport_read_all (transport, buf, len, error); } return -1; } static int transport_write_count = 0; static int transport_write_error = 0; static int transport_write_error_at = -1; gboolean my_thrift_transport_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { if (transport_write_count != transport_write_error_at && transport_write_error == 0) { transport_write_count++; return thrift_transport_write (transport, buf, len, error); } return FALSE; } #define thrift_transport_read_all my_thrift_transport_read_all #define thrift_transport_write my_thrift_transport_write #include "../src/thrift/c_glib/protocol/thrift_binary_protocol.c" #undef thrift_transport_read_all #undef thrift_transport_write static void thrift_server_primitives (const int port); static void thrift_server_complex_types (const int port); static void thrift_server_many_frames (const int port); static void test_create_and_destroy(void) { GObject *object = NULL; /* create an object and then destroy it */ object = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, NULL); g_assert (object != NULL); g_object_unref (object); } static void test_initialize(void) { ThriftSocket *tsocket = NULL; ThriftBinaryProtocol *protocol = NULL; ThriftSocket *temp = NULL; /* create a ThriftTransport */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", 51188, NULL); g_assert (tsocket != NULL); /* create a ThriftBinaryProtocol using the Transport */ protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", tsocket, NULL); g_assert (protocol != NULL); /* fetch the properties */ g_object_get (G_OBJECT(protocol), "transport", &temp, NULL); g_object_unref (temp); /* clean up memory */ g_object_unref (protocol); g_object_unref (tsocket); } static void test_read_and_write_primitives(void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftBinaryProtocol *tb = NULL; ThriftProtocol *protocol = NULL; gpointer binary = (gpointer *) TEST_STRING; guint32 len = strlen (TEST_STRING); int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_primitives (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = THRIFT_TRANSPORT (tsocket); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a ThriftBinaryTransport */ tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", tsocket, NULL); protocol = THRIFT_PROTOCOL (tb); g_assert (protocol != NULL); /* write a bunch of primitives */ g_assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0); g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0); g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0); g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0); g_assert (thrift_binary_protocol_write_double (protocol, TEST_DOUBLE, NULL) > 0); g_assert (thrift_binary_protocol_write_string (protocol, TEST_STRING, NULL) > 0); g_assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0); g_assert (thrift_binary_protocol_write_binary (protocol, binary, len, NULL) > 0); g_assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0); g_assert (thrift_binary_protocol_write_binary (protocol, binary, len, NULL) > 0); /* test write errors */ transport_write_error = 1; g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) == -1); g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) == -1); g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) == -1); g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) == -1); g_assert (thrift_binary_protocol_write_double (protocol, TEST_DOUBLE, NULL) == -1); g_assert (thrift_binary_protocol_write_binary (protocol, binary, len, NULL) == -1); transport_write_error = 0; /* test binary partial failure */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_binary_protocol_write_binary (protocol, binary, len, NULL) == -1); transport_write_error_at = -1; /* clean up */ thrift_transport_close (transport, NULL); g_object_unref (tsocket); g_object_unref (protocol); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void test_read_and_write_complex_types (void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftBinaryProtocol *tb = NULL; ThriftProtocol *protocol = NULL; int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_complex_types (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); transport = THRIFT_TRANSPORT (tsocket); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a ThriftBinaryTransport */ tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", tsocket, NULL); protocol = THRIFT_PROTOCOL (tb); g_assert (protocol != NULL); /* test structures */ g_assert (thrift_binary_protocol_write_struct_begin (protocol, NULL, NULL) == 0); g_assert (thrift_binary_protocol_write_struct_end (protocol, NULL) == 0); g_assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_field_end (protocol, NULL) == 0); /* test write error */ transport_write_error = 1; g_assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID, 1, NULL) == -1); transport_write_error = 0; /* test 2nd write error */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID, 1, NULL) == -1); transport_write_error_at = -1; /* test 2nd read failure on a field */ thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); /* test write_field_stop */ g_assert (thrift_binary_protocol_write_field_stop (protocol, NULL) > 0); /* write a map */ g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_map_end (protocol, NULL) == 0); /* test 2nd read failure on a map */ thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); /* test 3rd read failure on a map */ thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); /* test 1st write failure on a map */ transport_write_error = 1; g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID, 1, NULL) == -1); transport_write_error = 0; /* test 2nd write failure on a map */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID, 1, NULL) == -1); transport_write_error_at = -1; /* test 3rd write failure on a map */ transport_write_count = 0; transport_write_error_at = 2; g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID, 1, NULL) == -1); transport_write_error_at = -1; /* test negative map size */ thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); thrift_binary_protocol_write_i32 (protocol, -10, NULL); /* test list operations */ g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_list_end (protocol, NULL) == 0); /* test 2nd read failure on a list */ thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); /* test negative list size */ thrift_binary_protocol_write_byte (protocol, T_VOID, NULL); thrift_binary_protocol_write_i32 (protocol, -10, NULL); /* test first write error on a list */ transport_write_error = 1; g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID, 1, NULL) == -1); transport_write_error = 0; /* test 2nd write error on a list */ transport_write_count = 0; transport_write_error_at = 1; g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID, 1, NULL) == -1); transport_write_error_at = -1; /* test set operation s*/ g_assert (thrift_binary_protocol_write_set_begin (protocol, T_VOID, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_set_end (protocol, NULL) == 0); /* invalid version */ g_assert (thrift_binary_protocol_write_i32 (protocol, -1, NULL) > 0); /* sz > 0 for a message */ g_assert (thrift_binary_protocol_write_i32 (protocol, 1, NULL) > 0); /* send a valid message */ thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL); thrift_binary_protocol_write_string (protocol, "test", NULL); thrift_binary_protocol_write_i32 (protocol, 1, NULL); /* broken 2nd read */ thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL); /* send a broken 3rd read */ thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL); thrift_binary_protocol_write_string (protocol, "test", NULL); /* send a valid message */ g_assert (thrift_binary_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) > 0); g_assert (thrift_binary_protocol_write_message_end (protocol, NULL) == 0); /* send broken writes */ transport_write_error = 1; g_assert (thrift_binary_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) == -1); transport_write_error = 0; transport_write_count = 0; transport_write_error_at = 2; g_assert (thrift_binary_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) == -1); transport_write_error_at = -1; transport_write_count = 0; transport_write_error_at = 3; g_assert (thrift_binary_protocol_write_message_begin (protocol, "test", T_CALL, 1, NULL) == -1); transport_write_error_at = -1; /* clean up */ thrift_transport_close (transport, NULL); g_object_unref (tsocket); g_object_unref (protocol); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void test_read_and_write_many_frames (void) { int status; pid_t pid; ThriftSocket *tsocket = NULL; ThriftTransport *transport = NULL; ThriftFramedTransport *ft = NULL; ThriftBinaryProtocol *tb = NULL; ThriftProtocol *protocol = NULL; gpointer binary = (gpointer *) TEST_STRING; const guint32 len = strlen (TEST_STRING); int port = TEST_PORT; /* fork a server from the client */ pid = fork (); g_assert (pid >= 0); if (pid == 0) { /* child listens */ thrift_server_many_frames (port); exit (0); } else { /* parent. wait a bit for the socket to be created. */ sleep (1); /* create a ThriftSocket */ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", port, NULL); g_assert (tsocket != NULL); transport = THRIFT_TRANSPORT (tsocket); /* wrap in a framed transport */ ft = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", transport, "w_buf_size", 1, NULL); g_assert (ft != NULL); transport = THRIFT_TRANSPORT (ft); thrift_transport_open (transport, NULL); g_assert (thrift_transport_is_open (transport)); /* create a binary protocol */ tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL); protocol = THRIFT_PROTOCOL (tb); g_assert (protocol != NULL); /* write a bunch of primitives */ g_assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_double (protocol, TEST_DOUBLE, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_string (protocol, TEST_STRING, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_binary (protocol, binary, len, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0); thrift_transport_flush (transport, NULL); g_assert (thrift_binary_protocol_write_binary (protocol, binary, len, NULL) > 0); thrift_transport_flush (transport, NULL); /* clean up */ thrift_transport_write_end (transport, NULL); thrift_transport_close (transport, NULL); g_object_unref (ft); g_object_unref (tsocket); g_object_unref (tb); g_assert (wait (&status) == pid); g_assert (status == 0); } } static void thrift_server_primitives (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftBinaryProtocol *tbp = NULL; ThriftProtocol *protocol = NULL; gboolean value_boolean = FALSE; gint8 value_byte = 0; gint16 value_16 = 0; gint32 value_32 = 0; gint64 value_64 = 0; gdouble value_double = 0; gchar *string = NULL; gchar *empty_string = NULL; gpointer binary = NULL; guint32 len = 0; void *comparator = (void *) TEST_STRING; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); client = thrift_server_transport_accept (transport, NULL); g_assert (client != NULL); tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL (tbp); g_assert (thrift_binary_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0); g_assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0); g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0); g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0); g_assert (thrift_binary_protocol_read_double (protocol, &value_double, NULL) > 0); g_assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0); g_assert (thrift_binary_protocol_read_string (protocol, &empty_string, NULL) > 0); g_assert (thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (value_boolean == TEST_BOOL); g_assert (value_byte == TEST_BYTE); g_assert (value_16 == TEST_I16); g_assert (value_32 == TEST_I32); g_assert (value_64 == TEST_I64); g_assert (value_double == TEST_DOUBLE); g_assert (strcmp (TEST_STRING, string) == 0); g_assert (strcmp ("", empty_string) == 0); g_assert (memcmp (comparator, binary, len) == 0); g_free (string); g_free (empty_string); g_free (binary); g_assert (thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (binary == NULL); g_assert (len == 0); g_free (binary); transport_read_count = 0; transport_read_error_at = 0; g_assert (thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL) == -1); transport_read_error_at = -1; transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL) == -1); transport_read_error_at = -1; transport_read_error = 1; g_assert (thrift_binary_protocol_read_bool (protocol, &value_boolean, NULL) == -1); g_assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) == -1); g_assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) == -1); g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) == -1); g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) == -1); g_assert (thrift_binary_protocol_read_double (protocol, &value_double, NULL) == -1); transport_read_error = 0; /* test partial write failure */ thrift_protocol_read_i32 (protocol, &value_32, NULL); thrift_transport_read_end (client, NULL); thrift_transport_close (client, NULL); g_object_unref (tbp); g_object_unref (client); g_object_unref (tsocket); } static void thrift_server_complex_types (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftBinaryProtocol *tbp = NULL; ThriftProtocol *protocol = NULL; gchar *struct_name = NULL; gchar *field_name = NULL; gchar *message_name = NULL; ThriftType element_type, key_type, value_type, field_type; ThriftMessageType message_type; gint8 value = 0; gint16 field_id = 0; guint32 size = 0; gint32 seqid = 0; gint32 version = 0; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); client = thrift_server_transport_accept (transport, NULL); g_assert (client != NULL); tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL (tbp); thrift_binary_protocol_read_struct_begin (protocol, &struct_name, NULL); thrift_binary_protocol_read_struct_end (protocol, NULL); thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL); thrift_binary_protocol_read_field_end (protocol, NULL); /* test first read error on a field */ transport_read_error = 1; g_assert (thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == -1); transport_read_error = 0; /* test 2nd write failure */ thrift_binary_protocol_read_byte (protocol, &value, NULL); /* test 2nd read failure on a field */ transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL) == -1); transport_read_error_at = -1; /* test field stop */ thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type, &field_id, NULL); thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL); thrift_binary_protocol_read_map_end (protocol, NULL); /* test read failure on a map */ transport_read_count = 0; transport_read_error_at = 0; g_assert (thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); transport_read_error_at = -1; /* test 2nd read failure on a map */ transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); transport_read_error_at = -1; /* test 3rd read failure on a map */ transport_read_count = 0; transport_read_error_at = 2; g_assert (thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); transport_read_error_at = -1; /* test 2nd write failure */ thrift_binary_protocol_read_byte (protocol, &value, NULL); /* test 3rd write failure */ thrift_binary_protocol_read_byte (protocol, &value, NULL); thrift_binary_protocol_read_byte (protocol, &value, NULL); /* test negative map size */ g_assert (thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type, &size, NULL) == -1); /* test list operations */ thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL); thrift_binary_protocol_read_list_end (protocol, NULL); /* test read failure */ transport_read_error = 1; g_assert (thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL) == -1); transport_read_error = 0; /* test 2nd read failure */ transport_read_count = 0; transport_read_error_at = 1; thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL); transport_read_error_at = -1; /* test negative list size failure */ thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL); /* test 2nd write failure */ thrift_binary_protocol_read_byte (protocol, &value, NULL); /* test set operations */ thrift_binary_protocol_read_set_begin (protocol, &element_type, &size, NULL); thrift_binary_protocol_read_set_end (protocol, NULL); /* broken read */ transport_read_error = 1; g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); transport_read_error = 0; /* invalid protocol version */ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); /* sz > 0 */ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) > 0); /* read a valid message */ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) > 0); g_free (message_name); /* broken 2nd read on a message */ transport_read_count = 0; transport_read_error_at = 1; g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); transport_read_error_at = -1; /* broken 3rd read on a message */ transport_read_count = 0; transport_read_error_at = 3; /* read_string does two reads */ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) == -1); g_free (message_name); transport_read_error_at = -1; /* read a valid message */ g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name, &message_type, &seqid, NULL) > 0); g_free (message_name); g_assert (thrift_binary_protocol_read_message_end (protocol, NULL) == 0); /* handle 2nd write failure on a message */ thrift_binary_protocol_read_i32 (protocol, &version, NULL); /* handle 2nd write failure on a message */ thrift_binary_protocol_read_i32 (protocol, &version, NULL); thrift_binary_protocol_read_string (protocol, &message_name, NULL); g_object_unref (client); /* TODO: investigate g_object_unref (tbp); */ g_object_unref (tsocket); } static void thrift_server_many_frames (const int port) { ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; ThriftBinaryProtocol *tbp = NULL; ThriftProtocol *protocol = NULL; ThriftServerSocket *tsocket = NULL; gboolean value_boolean = FALSE; gint8 value_byte = 0; gint16 value_16 = 0; gint32 value_32 = 0; gint64 value_64 = 0; gdouble value_double = 0; gchar *string = NULL; gchar *empty_string = NULL; gpointer binary = NULL; guint32 len = 0; void *comparator = (void *) TEST_STRING; tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); /* wrap the client in a framed transport */ client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", thrift_server_transport_accept (transport, NULL), "r_buf_size", 1, NULL); g_assert (client != NULL); tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", client, NULL); protocol = THRIFT_PROTOCOL (tbp); g_assert (thrift_binary_protocol_read_bool (protocol, &value_boolean, NULL) > 0); g_assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0); g_assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0); g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0); g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0); g_assert (thrift_binary_protocol_read_double (protocol, &value_double, NULL) > 0); g_assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0); g_assert (thrift_binary_protocol_read_string (protocol, &empty_string, NULL) > 0); g_assert (thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (value_boolean == TEST_BOOL); g_assert (value_byte == TEST_BYTE); g_assert (value_16 == TEST_I16); g_assert (value_32 == TEST_I32); g_assert (value_64 == TEST_I64); g_assert (value_double == TEST_DOUBLE); g_assert (strcmp (TEST_STRING, string) == 0); g_assert (strcmp ("", empty_string) == 0); g_assert (memcmp (comparator, binary, len) == 0); g_free (string); g_free (empty_string); g_free (binary); g_assert (thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL) > 0); g_assert (binary == NULL); g_assert (len == 0); g_free (binary); thrift_transport_read_end (client, NULL); thrift_transport_close (client, NULL); g_object_unref (tbp); g_object_unref (client); g_object_unref (tsocket); } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init(); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testbinaryprotocol/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testbinaryprotocol/Initialize", test_initialize); g_test_add_func ("/testbinaryprotocol/ReadAndWritePrimitives", test_read_and_write_primitives); g_test_add_func ("/testbinaryprotocol/ReadAndWriteComplexTypes", test_read_and_write_complex_types); g_test_add_func ("/testbinaryprotocol/ReadAndWriteManyFrames", test_read_and_write_many_frames); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testapplicationexception.c0000664000175000017500000001427715165535636023642 0ustar00buildbuild00000000000000/* * 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 static void test_create_and_destroy (void) { GObject *object = NULL; /* A ThriftApplicationException can be created... */ object = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, NULL); g_assert (object != NULL); g_assert (THRIFT_IS_APPLICATION_EXCEPTION (object)); /* ...and destroyed */ g_object_unref (object); } static void test_initialize (void) { ThriftApplicationException *xception = NULL; gint32 type = THRIFT_APPLICATION_EXCEPTION_ERROR_INTERNAL_ERROR; gchar *message = "Exception message"; gint32 retrieved_type = 0; gchar *retrieved_message = NULL; /* A ThriftApplicationException has "type" and "message" properties that can be initialized at object creation */ xception = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, "type", type, "message", message, NULL); g_assert (xception != NULL); /* A ThriftApplicationException's properties can be retrieved */ g_object_get (xception, "type", &retrieved_type, "message", &retrieved_message, NULL); g_assert (retrieved_type == type); g_assert (retrieved_message != NULL); g_assert_cmpstr (retrieved_message, ==, message); g_free (retrieved_message); g_object_unref (xception); } static void test_properties_test (void) { ThriftApplicationException *xception = NULL; gint32 retrieved_type; xception = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, NULL); #define TEST_TYPE_VALUE(_type) \ retrieved_type = -1; \ g_object_set (xception, "type", _type, NULL); \ g_object_get (xception, "type", &retrieved_type, NULL); \ g_assert_cmpint (retrieved_type, ==, _type); /* The "type" property can be set to any valid Thrift exception type */ TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_MESSAGE_TYPE); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_WRONG_METHOD_NAME); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_BAD_SEQUENCE_ID); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_MISSING_RESULT); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INTERNAL_ERROR); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_PROTOCOL_ERROR); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_TRANSFORM); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_INVALID_PROTOCOL); TEST_TYPE_VALUE (THRIFT_APPLICATION_EXCEPTION_ERROR_UNSUPPORTED_CLIENT_TYPE); /* "g_test_expect_message" is required for the property range tests below but is not present in GLib before version 2.34 */ #if (GLIB_CHECK_VERSION (2, 34, 0)) g_object_set (xception, "type", THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN, NULL); /* The "type" property cannot be set to a value too low (less than zero) */ g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "value*out of range*type*"); g_object_set (xception, "type", -1, NULL); g_test_assert_expected_messages (); g_object_get (xception, "type", &retrieved_type, NULL); g_assert_cmpint (retrieved_type, !=, -1); g_assert_cmpint (retrieved_type, ==, THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN); /* The "type" property cannot be set to a value too high (greater than the highest defined exception-type value) */ g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "value*out of range*type*"); g_object_set (xception, "type", THRIFT_APPLICATION_EXCEPTION_ERROR_N, NULL); g_test_assert_expected_messages (); g_object_get (xception, "type", &retrieved_type, NULL); g_assert_cmpint (retrieved_type, !=, THRIFT_APPLICATION_EXCEPTION_ERROR_N); g_assert_cmpint (retrieved_type, ==, THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN); #endif g_object_unref (xception); } static void test_properties_message (void) { ThriftApplicationException *xception = NULL; gchar *message = "Exception message"; gchar *retrieved_message; xception = g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION, NULL); /* The "message" property can be set to NULL */ g_object_set (xception, "message", NULL, NULL); g_object_get (xception, "message", &retrieved_message, NULL); g_assert (retrieved_message == NULL); /* The "message" property can be set to a valid string */ g_object_set (xception, "message", message, NULL); g_object_get (xception, "message", &retrieved_message, NULL); g_assert_cmpint (strcmp (retrieved_message, message), ==, 0); g_free (retrieved_message); g_object_unref (xception); } int main (int argc, char **argv) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testapplicationexception/CreateAndDestroy", test_create_and_destroy); g_test_add_func ("/testapplicationexception/Initialize", test_initialize); g_test_add_func ("/testapplicationexception/Properties/test", test_properties_test); g_test_add_func ("/testapplicationexception/Properties/message", test_properties_message); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testthrifttestzlibclient.cpp0000664000175000017500000005245215165535636024235 0ustar00buildbuild00000000000000/* * 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. */ /* test a C client with a C++ server (that makes sense...) */ #include #include #include #include #include #include #include #include #include #include "ThriftTest.h" #include "ThriftTest_types.h" #include #include #include #include #include using namespace apache::thrift; using namespace apache::thrift::concurrency; using namespace apache::thrift::protocol; using namespace apache::thrift::server; using namespace apache::thrift::transport; using namespace thrift::test; using std::cout; using std::fixed; using std::make_pair; using std::map; using std::set; using std::string; using std::vector; #define TEST_PORT 9980 // Extra functions required for ThriftTest_types to work namespace thrift { namespace test { bool Insanity::operator<(thrift::test::Insanity const& other) const { using apache::thrift::ThriftDebugString; return ThriftDebugString(*this) < ThriftDebugString(other); } }} class TestHandler : public ThriftTestIf { public: TestHandler() = default; void testVoid() override { cout << "[C -> C++] testVoid()" << '\n'; } void testString(string& out, const string &thing) override { cout << "[C -> C++] testString(\"" << thing << "\")" << '\n'; out = thing; } bool testBool(const bool thing) override { cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << '\n'; return thing; } int8_t testByte(const int8_t thing) override { cout << "[C -> C++] testByte(" << (int)thing << ")" << '\n'; return thing; } int32_t testI32(const int32_t thing) override { cout << "[C -> C++] testI32(" << thing << ")" << '\n'; return thing; } int64_t testI64(const int64_t thing) override { cout << "[C -> C++] testI64(" << thing << ")" << '\n'; return thing; } double testDouble(const double thing) override { cout.precision(6); cout << "[C -> C++] testDouble(" << fixed << thing << ")" << '\n'; return thing; } void testBinary(string& out, const string &thing) override { 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 << "})" << '\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 << "})" << '\n'; out = nest; } void testMap(map &out, const map &thing) override { cout << "[C -> C++] testMap({"; map::const_iterator m_iter; bool first = true; for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) { if (first) { first = false; } else { cout << ", "; } cout << m_iter->first << " => " << m_iter->second; } cout << "})" << '\n'; out = thing; } void testStringMap(map &out, const map &thing) override { cout << "[C -> C++] testStringMap({"; map::const_iterator m_iter; bool first = true; for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) { if (first) { first = false; } else { cout << ", "; } cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\""; } cout << "})" << '\n'; out = thing; } void testSet(set &out, const set &thing) override { cout << "[C -> C++] testSet({"; set::const_iterator s_iter; bool first = true; for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) { if (first) { first = false; } else { cout << ", "; } cout << *s_iter; } cout << "})" << '\n'; out = thing; } void testList(vector &out, const vector &thing) override { cout << "[C -> C++] testList({"; vector::const_iterator l_iter; bool first = true; for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) { if (first) { first = false; } else { cout << ", "; } cout << *l_iter; } cout << "})" << '\n'; out = thing; } Numberz::type testEnum(const Numberz::type thing) override { cout << "[C -> C++] testEnum(" << thing << ")" << '\n'; return thing; } UserId testTypedef(const UserId thing) override { cout << "[C -> C++] testTypedef(" << thing << ")" << '\n'; return thing; } void testMapMap(map > &mapmap, const int32_t hello) override { cout << "[C -> C++] testMapMap(" << hello << ")" << '\n'; map pos; map neg; for (int i = 1; i < 5; i++) { pos.insert(make_pair(i,i)); neg.insert(make_pair(-i,-i)); } mapmap.insert(make_pair(4, pos)); mapmap.insert(make_pair(-4, neg)); } void testInsanity(map > &insane, const Insanity &argument) override { THRIFT_UNUSED_VARIABLE (argument); cout << "[C -> C++] testInsanity()" << '\n'; Xtruct hello; hello.string_thing = "Hello2"; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = 2; Xtruct goodbye; goodbye.string_thing = "Goodbye4"; goodbye.byte_thing = 4; goodbye.i32_thing = 4; goodbye.i64_thing = 4; Insanity crazy; crazy.userMap.insert(make_pair(Numberz::EIGHT, 8)); crazy.xtructs.push_back(goodbye); Insanity looney; crazy.userMap.insert(make_pair(Numberz::FIVE, 5)); crazy.xtructs.push_back(hello); map first_map; map second_map; first_map.insert(make_pair(Numberz::TWO, crazy)); first_map.insert(make_pair(Numberz::THREE, crazy)); second_map.insert(make_pair(Numberz::SIX, looney)); insane.insert(make_pair(1, first_map)); insane.insert(make_pair(2, second_map)); cout << "return = {"; map >::const_iterator i_iter; for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) { cout << i_iter->first << " => {"; map::const_iterator i2_iter; for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) { cout << i2_iter->first << " => {"; map userMap = i2_iter->second.userMap; map::const_iterator um; cout << "{"; for (um = userMap.begin(); um != userMap.end(); ++um) { cout << um->first << " => " << um->second << ", "; } cout << "}, "; vector xtructs = i2_iter->second.xtructs; vector::const_iterator x; cout << "{"; for (x = xtructs.begin(); x != xtructs.end(); ++x) { cout << "{\"" << x->string_thing << "\", " << (int)x->byte_thing << ", " << x->i32_thing << ", " << x->i64_thing << "}, "; } cout << "}"; cout << "}, "; } cout << "}, "; } cout << "}" << '\n'; } void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map &arg3, const Numberz::type arg4, const UserId arg5) override { THRIFT_UNUSED_VARIABLE (arg3); THRIFT_UNUSED_VARIABLE (arg4); THRIFT_UNUSED_VARIABLE (arg5); cout << "[C -> C++] testMulti()" << '\n'; hello.string_thing = "Hello2"; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = (int64_t)arg2; } void testException(const std::string &arg) noexcept(false) override { cout << "[C -> C++] testException(" << arg << ")" << '\n'; if (arg.compare("Xception") == 0) { Xception e; e.errorCode = 1001; e.message = arg; throw e; } else if (arg.compare("ApplicationException") == 0) { apache::thrift::TException e; throw e; } else { Xtruct result; result.string_thing = arg; return; } } void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override { cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << '\n'; if (arg0.compare("Xception") == 0) { Xception e; e.errorCode = 1001; e.message = "This is an Xception"; throw e; } else if (arg0.compare("Xception2") == 0) { Xception2 e; e.errorCode = 2002; e.struct_thing.string_thing = "This is an Xception2"; throw e; } else { result.string_thing = arg1; return; } } void testOneway(int sleepFor) override { cout << "testOneway(" << sleepFor << "): Sleeping..." << '\n'; sleep(sleepFor); cout << "testOneway(" << sleepFor << "): done sleeping!" << '\n'; } }; // C CLIENT extern "C" { #undef THRIFT_SOCKET /* from lib/cpp */ #include "t_test_thrift_test.h" #include "t_test_thrift_test_types.h" #include #include #include #include static void test_thrift_client (void) { ThriftSocket *tsocket = nullptr; ThriftBinaryProtocol *protocol = nullptr; ThriftZlibTransport *transport = nullptr; TTestThriftTestClient *client = nullptr; TTestThriftTestIf *iface = nullptr; GError *error = nullptr; gchar *string = nullptr; gint8 byte = 0; gint16 i16 = 0; gint32 i32 = 0, another_i32 = 56789; gint64 i64 = 0; double dbl = 0.0; TTestXtruct *xtruct_in, *xtruct_out; TTestXtruct2 *xtruct2_in, *xtruct2_out; GHashTable *map_in = nullptr, *map_out = nullptr; GHashTable *set_in = nullptr, *set_out = nullptr; GArray *list_in = nullptr, *list_out = nullptr; TTestNumberz enum_in, enum_out; TTestUserId user_id_in, user_id_out; GHashTable *insanity_in = nullptr; TTestXtruct *xtruct1, *xtruct2; TTestInsanity *insanity_out = nullptr; TTestXtruct *multi_in = nullptr; GHashTable *multi_map_out = nullptr; TTestXception *xception = nullptr; TTestXception2 *xception2 = nullptr; #if (!GLIB_CHECK_VERSION (2, 36, 0)) // initialize gobject g_type_init (); #endif // create a C client tsocket = (ThriftSocket *) g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", TEST_PORT, nullptr); transport = (ThriftZlibTransport *) g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, "transport", tsocket, nullptr); protocol = (ThriftBinaryProtocol *) g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, nullptr); client = (TTestThriftTestClient *) g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT, "input_protocol", protocol, "output_protocol", protocol, nullptr); iface = T_TEST_THRIFT_TEST_IF (client); // open and send thrift_transport_open (THRIFT_TRANSPORT(transport), nullptr); assert (t_test_thrift_test_client_test_void (iface, &error) == TRUE); assert (error == nullptr); assert (t_test_thrift_test_client_test_string (iface, &string, "test123", &error) == TRUE); assert (strcmp (string, "test123") == 0); g_free (string); assert (error == nullptr); assert (t_test_thrift_test_client_test_byte (iface, &byte, (gint8) 5, &error) == TRUE); assert (byte == 5); assert (error == nullptr); assert (t_test_thrift_test_client_test_i32 (iface, &i32, 123, &error) == TRUE); assert (i32 == 123); assert (error == nullptr); assert (t_test_thrift_test_client_test_i64 (iface, &i64, 12345, &error) == TRUE); assert (i64 == 12345); assert (error == nullptr); assert (t_test_thrift_test_client_test_double (iface, &dbl, 5.6, &error) == TRUE); assert (dbl == 5.6); assert (error == nullptr); xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); xtruct_out->byte_thing = 1; xtruct_out->__isset_byte_thing = TRUE; xtruct_out->i32_thing = 15; xtruct_out->__isset_i32_thing = TRUE; xtruct_out->i64_thing = 151; xtruct_out->__isset_i64_thing = TRUE; xtruct_out->string_thing = g_strdup ("abc123"); xtruct_out->__isset_string_thing = TRUE; xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE); assert (error == nullptr); xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr); xtruct2_out->byte_thing = 1; xtruct2_out->__isset_byte_thing = TRUE; if (xtruct2_out->struct_thing != nullptr) g_object_unref(xtruct2_out->struct_thing); xtruct2_out->struct_thing = xtruct_out; xtruct2_out->__isset_struct_thing = TRUE; xtruct2_out->i32_thing = 123; xtruct2_out->__isset_i32_thing = TRUE; xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr); assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE); assert (error == nullptr); g_object_unref (xtruct2_out); g_object_unref (xtruct2_in); g_object_unref (xtruct_in); map_out = g_hash_table_new (nullptr, nullptr); map_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (map_out, &i32, &i32); assert (t_test_thrift_test_client_test_map (iface, &map_in, map_out, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (map_out); g_hash_table_destroy (map_in); map_out = g_hash_table_new (nullptr, nullptr); map_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (map_out, g_strdup ("a"), g_strdup ("123")); g_hash_table_insert (map_out, g_strdup ("a b"), g_strdup ("with spaces ")); g_hash_table_insert (map_out, g_strdup ("same"), g_strdup ("same")); g_hash_table_insert (map_out, g_strdup ("0"), g_strdup ("numeric key")); assert (t_test_thrift_test_client_test_string_map (iface, &map_in, map_out, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (map_out); g_hash_table_destroy (map_in); set_out = g_hash_table_new (nullptr, nullptr); set_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (set_out, &i32, &i32); assert (t_test_thrift_test_client_test_set (iface, &set_in, set_out, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (set_out); g_hash_table_destroy (set_in); list_out = g_array_new(TRUE, TRUE, sizeof(gint32)); list_in = g_array_new(TRUE, TRUE, sizeof(gint32)); another_i32 = 456; g_array_append_val (list_out, i32); g_array_append_val (list_out, another_i32); assert (t_test_thrift_test_client_test_list (iface, &list_in, list_out, &error) == TRUE); assert (error == nullptr); g_array_free (list_out, TRUE); g_array_free (list_in, TRUE); enum_out = T_TEST_NUMBERZ_ONE; assert (t_test_thrift_test_client_test_enum (iface, &enum_in, enum_out, &error) == TRUE); assert (enum_in == enum_out); assert (error == nullptr); user_id_out = 12345; assert (t_test_thrift_test_client_test_typedef (iface, &user_id_in, user_id_out, &error) == TRUE); assert (user_id_in == user_id_out); assert (error == nullptr); map_in = g_hash_table_new (nullptr, nullptr); assert (t_test_thrift_test_client_test_map_map (iface, &map_in, i32, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (map_in); // insanity insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, nullptr); insanity_out->userMap = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (insanity_out->userMap, GINT_TO_POINTER (enum_out), &user_id_out); xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); xtruct1->byte_thing = 1; xtruct1->__isset_byte_thing = TRUE; xtruct1->i32_thing = 15; xtruct1->__isset_i32_thing = TRUE; xtruct1->i64_thing = 151; xtruct1->__isset_i64_thing = TRUE; xtruct1->string_thing = g_strdup ("abc123"); xtruct1->__isset_string_thing = TRUE; xtruct2 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); xtruct2->byte_thing = 1; xtruct2->__isset_byte_thing = TRUE; xtruct2->i32_thing = 15; xtruct2->__isset_i32_thing = TRUE; xtruct2->i64_thing = 151; xtruct2->__isset_i64_thing = TRUE; xtruct2->string_thing = g_strdup ("abc123"); xtruct2->__isset_string_thing = TRUE; insanity_in = g_hash_table_new (nullptr, nullptr); g_ptr_array_add (insanity_out->xtructs, xtruct1); g_ptr_array_add (insanity_out->xtructs, xtruct2); assert (t_test_thrift_test_client_test_insanity (iface, &insanity_in, insanity_out, &error) == TRUE); g_hash_table_unref (insanity_in); g_ptr_array_free (insanity_out->xtructs, TRUE); multi_map_out = g_hash_table_new (nullptr, nullptr); string = g_strdup ("abc123"); g_hash_table_insert (multi_map_out, &i16, string); multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi (iface, &multi_in, byte, i32, i64, multi_map_out, enum_out, user_id_out, &error) == TRUE); assert (multi_in->i32_thing == i32); assert (multi_in->i64_thing == i64); g_object_unref (multi_in); g_hash_table_unref (multi_map_out); g_free (string); assert (t_test_thrift_test_client_test_exception (iface, "Xception", &xception, &error) == FALSE); assert (xception->errorCode == 1001); g_error_free (error); error = nullptr; g_object_unref (xception); xception = nullptr; assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE); g_error_free (error); error = nullptr; assert (xception == nullptr); assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE); assert (error == nullptr); multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", nullptr, &xception, &xception2, &error) == FALSE); assert (xception->errorCode == 1001); assert (xception2 == nullptr); g_error_free (error); error = nullptr; g_object_unref (xception); g_object_unref (multi_in); xception = nullptr; multi_in = nullptr; multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", nullptr, &xception, &xception2, &error) == FALSE); assert (xception2->errorCode == 2002); assert (xception == nullptr); g_error_free (error); error = nullptr; g_object_unref (xception2); g_object_unref (multi_in); xception2 = nullptr; multi_in = nullptr; multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, nullptr , nullptr, &xception, &xception2, &error) == TRUE); assert (error == nullptr); g_object_unref(multi_in); multi_in = nullptr; assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE); assert (error == nullptr); /* sleep to let the oneway call go through */ sleep (5); thrift_transport_close (THRIFT_TRANSPORT(tsocket), nullptr); g_object_unref (client); g_object_unref (protocol); g_object_unref (tsocket); } } /* extern "C" */ static void bailout (int signum) { THRIFT_UNUSED_VARIABLE (signum); exit (1); } int main (void) { int status; int pid = fork (); assert (pid >= 0); if (pid == 0) /* child */ { std::shared_ptr protocolFactory(new TBinaryProtocolFactory()); std::shared_ptr testHandler(new TestHandler()); std::shared_ptr testProcessor(new ThriftTestProcessor(testHandler)); std::shared_ptr serverSocket(new TServerSocket(TEST_PORT)); std::shared_ptr transportFactory(new TZlibTransportFactory()); //std::shared_ptr transportFactory(new TBufferedTransportFactory()); TSimpleServer simpleServer(testProcessor, serverSocket, transportFactory, protocolFactory); signal (SIGALRM, bailout); alarm (60); simpleServer.serve(); } else { sleep (1); test_thrift_client (); kill (pid, SIGINT); assert (wait (&status) == pid); } return 0; } thrift-0.23.0/lib/c_glib/test/Makefile.in0000644000175000017500000037437615170007166020414 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = testserialization$(EXEEXT) \ testapplicationexception$(EXEEXT) testcontainertest$(EXEEXT) \ testtransportsocket$(EXEEXT) testtransportsslsocket$(EXEEXT) \ testbinaryprotocol$(EXEEXT) testcompactprotocol$(EXEEXT) \ testbufferedtransport$(EXEEXT) testframedtransport$(EXEEXT) \ testzlibtransport$(EXEEXT) testfdtransport$(EXEEXT) \ testmemorybuffer$(EXEEXT) teststruct$(EXEEXT) \ testsimpleserver$(EXEEXT) testdebugproto$(EXEEXT) \ testoptionalrequired$(EXEEXT) testthrifttest$(EXEEXT) \ testthriftbinaryreadcheck$(EXEEXT) \ testthriftcompactreadcheck$(EXEEXT) \ testthriftbufferedreadcheck$(EXEEXT) \ testthriftfdreadcheck$(EXEEXT) \ testthriftframedreadcheck$(EXEEXT) \ testthriftmemorybufferreadcheck$(EXEEXT) $(am__EXEEXT_1) @WITH_CPP_TRUE@am__append_1 = gen-cpp/ThriftTest_types.cpp @WITH_CPP_TRUE@am__append_2 = testthrifttestclient \ @WITH_CPP_TRUE@ testthrifttestzlibclient @WITH_CPP_TRUE@am__append_3 = libtestgencpp.la TESTS = $(check_PROGRAMS) subdir = lib/c_glib/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @WITH_CPP_TRUE@am__EXEEXT_1 = testthrifttestclient$(EXEEXT) \ @WITH_CPP_TRUE@ testthrifttestzlibclient$(EXEEXT) libtestgenc_la_DEPENDENCIES = \ $(top_builddir)/lib/c_glib/libthrift_c_glib.la am__dirstamp = $(am__leading_dot)dirstamp nodist_libtestgenc_la_OBJECTS = \ gen-c_glib/libtestgenc_la-t_test_container_test_types.lo \ gen-c_glib/libtestgenc_la-t_test_debug_proto_test_types.lo \ gen-c_glib/libtestgenc_la-t_test_enum_test_types.lo \ gen-c_glib/libtestgenc_la-t_test_enum_test_service.lo \ gen-c_glib/libtestgenc_la-t_test_empty_service.lo \ gen-c_glib/libtestgenc_la-t_test_inherited.lo \ gen-c_glib/libtestgenc_la-t_test_optional_required_test_types.lo \ gen-c_glib/libtestgenc_la-t_test_reverse_order_service.lo \ gen-c_glib/libtestgenc_la-t_test_second_service.lo \ gen-c_glib/libtestgenc_la-t_test_service_for_exception_with_a_map.lo \ gen-c_glib/libtestgenc_la-t_test_srv.lo \ gen-c_glib/libtestgenc_la-t_test_container_service.lo \ gen-c_glib/libtestgenc_la-t_test_thrift_test.lo \ gen-c_glib/libtestgenc_la-t_test_thrift_test_types.lo libtestgenc_la_OBJECTS = $(nodist_libtestgenc_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libtestgencpp_la_LIBADD = nodist_libtestgencpp_la_OBJECTS = \ gen-cpp/libtestgencpp_la-ThriftTest.lo \ gen-cpp/libtestgencpp_la-ThriftTest_constants.lo \ gen-cpp/libtestgencpp_la-ThriftTest_types.lo libtestgencpp_la_OBJECTS = $(nodist_libtestgencpp_la_OBJECTS) @WITH_CPP_TRUE@am_libtestgencpp_la_rpath = am_testapplicationexception_OBJECTS = \ testapplicationexception.$(OBJEXT) testapplicationexception_OBJECTS = \ $(am_testapplicationexception_OBJECTS) testapplicationexception_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testbinaryprotocol_OBJECTS = testbinaryprotocol.$(OBJEXT) testbinaryprotocol_OBJECTS = $(am_testbinaryprotocol_OBJECTS) testbinaryprotocol_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testbufferedtransport_OBJECTS = testbufferedtransport.$(OBJEXT) testbufferedtransport_OBJECTS = $(am_testbufferedtransport_OBJECTS) testbufferedtransport_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testcompactprotocol_OBJECTS = testcompactprotocol.$(OBJEXT) testcompactprotocol_OBJECTS = $(am_testcompactprotocol_OBJECTS) testcompactprotocol_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testcontainertest_OBJECTS = testcontainertest.$(OBJEXT) testcontainertest_OBJECTS = $(am_testcontainertest_OBJECTS) testcontainertest_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la am_testdebugproto_OBJECTS = testdebugproto.$(OBJEXT) testdebugproto_OBJECTS = $(am_testdebugproto_OBJECTS) testdebugproto_DEPENDENCIES = libtestgenc.la am_testfdtransport_OBJECTS = testfdtransport.$(OBJEXT) testfdtransport_OBJECTS = $(am_testfdtransport_OBJECTS) testfdtransport_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testframedtransport_OBJECTS = testframedtransport.$(OBJEXT) testframedtransport_OBJECTS = $(am_testframedtransport_OBJECTS) testframedtransport_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testmemorybuffer_OBJECTS = testmemorybuffer.$(OBJEXT) testmemorybuffer_OBJECTS = $(am_testmemorybuffer_OBJECTS) testmemorybuffer_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testoptionalrequired_OBJECTS = testoptionalrequired.$(OBJEXT) testoptionalrequired_OBJECTS = $(am_testoptionalrequired_OBJECTS) testoptionalrequired_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la am_testserialization_OBJECTS = testserialization.$(OBJEXT) testserialization_OBJECTS = $(am_testserialization_OBJECTS) testserialization_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la am_testsimpleserver_OBJECTS = testsimpleserver.$(OBJEXT) testsimpleserver_OBJECTS = $(am_testsimpleserver_OBJECTS) testsimpleserver_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_teststruct_OBJECTS = teststruct.$(OBJEXT) teststruct_OBJECTS = $(am_teststruct_OBJECTS) teststruct_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testthriftbinaryreadcheck_OBJECTS = \ testthriftbinaryreadcheck.$(OBJEXT) testthriftbinaryreadcheck_OBJECTS = \ $(am_testthriftbinaryreadcheck_OBJECTS) testthriftbinaryreadcheck_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testthriftbufferedreadcheck_OBJECTS = \ testthriftbufferedreadcheck.$(OBJEXT) testthriftbufferedreadcheck_OBJECTS = \ $(am_testthriftbufferedreadcheck_OBJECTS) testthriftbufferedreadcheck_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testthriftcompactreadcheck_OBJECTS = \ testthriftcompactreadcheck.$(OBJEXT) testthriftcompactreadcheck_OBJECTS = \ $(am_testthriftcompactreadcheck_OBJECTS) testthriftcompactreadcheck_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testthriftfdreadcheck_OBJECTS = testthriftfdreadcheck.$(OBJEXT) testthriftfdreadcheck_OBJECTS = $(am_testthriftfdreadcheck_OBJECTS) testthriftfdreadcheck_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testthriftframedreadcheck_OBJECTS = \ testthriftframedreadcheck.$(OBJEXT) testthriftframedreadcheck_OBJECTS = \ $(am_testthriftframedreadcheck_OBJECTS) testthriftframedreadcheck_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testthriftmemorybufferreadcheck_OBJECTS = \ testthriftmemorybufferreadcheck.$(OBJEXT) testthriftmemorybufferreadcheck_OBJECTS = \ $(am_testthriftmemorybufferreadcheck_OBJECTS) testthriftmemorybufferreadcheck_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testthrifttest_OBJECTS = testthrifttest-testthrifttest.$(OBJEXT) testthrifttest_OBJECTS = $(am_testthrifttest_OBJECTS) testthrifttest_DEPENDENCIES = libtestgenc.la \ $(top_builddir)/test/c_glib/src/thrift_test_handler.o testthrifttest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(testthrifttest_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ am_testthrifttestclient_OBJECTS = \ testthrifttestclient-testthrifttestclient.$(OBJEXT) testthrifttestclient_OBJECTS = $(am_testthrifttestclient_OBJECTS) testthrifttestclient_DEPENDENCIES = ../../cpp/.libs/libthrift.la \ ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la testthrifttestclient_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(testthrifttestclient_LDFLAGS) \ $(LDFLAGS) -o $@ am_testthrifttestzlibclient_OBJECTS = \ testthrifttestzlibclient-testthrifttestzlibclient.$(OBJEXT) testthrifttestzlibclient_OBJECTS = \ $(am_testthrifttestzlibclient_OBJECTS) testthrifttestzlibclient_DEPENDENCIES = ../../cpp/.libs/libthrift.la \ ../../cpp/.libs/libthriftz.la ../libthrift_c_glib.la \ libtestgenc.la libtestgencpp.la testthrifttestzlibclient_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(testthrifttestzlibclient_LDFLAGS) \ $(LDFLAGS) -o $@ am_testtransportsocket_OBJECTS = testtransportsocket.$(OBJEXT) testtransportsocket_OBJECTS = $(am_testtransportsocket_OBJECTS) testtransportsocket_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testtransportsslsocket_OBJECTS = testtransportsslsocket.$(OBJEXT) testtransportsslsocket_OBJECTS = $(am_testtransportsslsocket_OBJECTS) testtransportsslsocket_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o am_testzlibtransport_OBJECTS = testzlibtransport.$(OBJEXT) testzlibtransport_OBJECTS = $(am_testzlibtransport_OBJECTS) testzlibtransport_DEPENDENCIES = $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/testapplicationexception.Po \ ./$(DEPDIR)/testbinaryprotocol.Po \ ./$(DEPDIR)/testbufferedtransport.Po \ ./$(DEPDIR)/testcompactprotocol.Po \ ./$(DEPDIR)/testcontainertest.Po ./$(DEPDIR)/testdebugproto.Po \ ./$(DEPDIR)/testfdtransport.Po \ ./$(DEPDIR)/testframedtransport.Po \ ./$(DEPDIR)/testmemorybuffer.Po \ ./$(DEPDIR)/testoptionalrequired.Po \ ./$(DEPDIR)/testserialization.Po \ ./$(DEPDIR)/testsimpleserver.Po ./$(DEPDIR)/teststruct.Po \ ./$(DEPDIR)/testthriftbinaryreadcheck.Po \ ./$(DEPDIR)/testthriftbufferedreadcheck.Po \ ./$(DEPDIR)/testthriftcompactreadcheck.Po \ ./$(DEPDIR)/testthriftfdreadcheck.Po \ ./$(DEPDIR)/testthriftframedreadcheck.Po \ ./$(DEPDIR)/testthriftmemorybufferreadcheck.Po \ ./$(DEPDIR)/testthrifttest-testthrifttest.Po \ ./$(DEPDIR)/testthrifttestclient-testthrifttestclient.Po \ ./$(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Po \ ./$(DEPDIR)/testtransportsocket.Po \ ./$(DEPDIR)/testtransportsslsocket.Po \ ./$(DEPDIR)/testzlibtransport.Po \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_service.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_test_types.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_debug_proto_test_types.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_empty_service.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_service.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_types.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_inherited.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_optional_required_test_types.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_reverse_order_service.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_second_service.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_service_for_exception_with_a_map.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_srv.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test.Plo \ gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test_types.Plo \ gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest.Plo \ gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_constants.Plo \ gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_types.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(nodist_libtestgenc_la_SOURCES) \ $(nodist_libtestgencpp_la_SOURCES) \ $(testapplicationexception_SOURCES) \ $(testbinaryprotocol_SOURCES) $(testbufferedtransport_SOURCES) \ $(testcompactprotocol_SOURCES) $(testcontainertest_SOURCES) \ $(testdebugproto_SOURCES) $(testfdtransport_SOURCES) \ $(testframedtransport_SOURCES) $(testmemorybuffer_SOURCES) \ $(testoptionalrequired_SOURCES) $(testserialization_SOURCES) \ $(testsimpleserver_SOURCES) $(teststruct_SOURCES) \ $(testthriftbinaryreadcheck_SOURCES) \ $(testthriftbufferedreadcheck_SOURCES) \ $(testthriftcompactreadcheck_SOURCES) \ $(testthriftfdreadcheck_SOURCES) \ $(testthriftframedreadcheck_SOURCES) \ $(testthriftmemorybufferreadcheck_SOURCES) \ $(testthrifttest_SOURCES) $(testthrifttestclient_SOURCES) \ $(testthrifttestzlibclient_SOURCES) \ $(testtransportsocket_SOURCES) \ $(testtransportsslsocket_SOURCES) $(testzlibtransport_SOURCES) DIST_SOURCES = $(testapplicationexception_SOURCES) \ $(testbinaryprotocol_SOURCES) $(testbufferedtransport_SOURCES) \ $(testcompactprotocol_SOURCES) $(testcontainertest_SOURCES) \ $(testdebugproto_SOURCES) $(testfdtransport_SOURCES) \ $(testframedtransport_SOURCES) $(testmemorybuffer_SOURCES) \ $(testoptionalrequired_SOURCES) $(testserialization_SOURCES) \ $(testsimpleserver_SOURCES) $(teststruct_SOURCES) \ $(testthriftbinaryreadcheck_SOURCES) \ $(testthriftbufferedreadcheck_SOURCES) \ $(testthriftcompactreadcheck_SOURCES) \ $(testthriftfdreadcheck_SOURCES) \ $(testthriftframedreadcheck_SOURCES) \ $(testthriftmemorybufferreadcheck_SOURCES) \ $(testthrifttest_SOURCES) $(testthrifttestclient_SOURCES) \ $(testthrifttestzlibclient_SOURCES) \ $(testtransportsocket_SOURCES) \ $(testtransportsslsocket_SOURCES) $(testzlibtransport_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc SUBDIRS = fuzz BUILT_SOURCES = gen-c_glib/t_test_container_test_types.c \ gen-c_glib/t_test_container_test_types.h \ gen-c_glib/t_test_debug_proto_test_types.h \ gen-c_glib/t_test_empty_service.h \ gen-c_glib/t_test_inherited.h \ gen-c_glib/t_test_optional_required_test_types.h \ gen-c_glib/t_test_reverse_order_service.h \ gen-c_glib/t_test_second_service.h \ gen-c_glib/t_test_service_for_exception_with_a_map.h \ gen-c_glib/t_test_container_service.c \ gen-c_glib/t_test_container_service.h gen-c_glib/t_test_srv.h \ gen-c_glib/t_test_thrift_test.h \ gen-c_glib/t_test_thrift_test_types.h \ gen-c_glib/t_test_enum_test_types.h $(am__append_1) AM_CPPFLAGS = -I../src -I./gen-c_glib -I$(top_builddir)/lib/c_glib/src/thrift AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) \ @GCOV_CFLAGS@ AM_CXXFLAGS = $(AM_CFLAGS) AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LIBS) $(ZLIB_LIBS) @GCOV_LDFLAGS@ testserialization_SOURCES = testserialization.c testserialization_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la testapplicationexception_SOURCES = testapplicationexception.c testapplicationexception_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testcontainertest_SOURCES = testcontainertest.c testcontainertest_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la testtransportsocket_SOURCES = testtransportsocket.c testtransportsocket_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testtransportsslsocket_SOURCES = testtransportsslsocket.c testtransportsslsocket_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testbinaryprotocol_SOURCES = testbinaryprotocol.c testbinaryprotocol_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testcompactprotocol_SOURCES = testcompactprotocol.c testcompactprotocol_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testbufferedtransport_SOURCES = testbufferedtransport.c testbufferedtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testframedtransport_SOURCES = testframedtransport.c testframedtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testzlibtransport_SOURCES = testzlibtransport.c testzlibtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testfdtransport_SOURCES = testfdtransport.c testfdtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testmemorybuffer_SOURCES = testmemorybuffer.c testmemorybuffer_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o teststruct_SOURCES = teststruct.c teststruct_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testsimpleserver_SOURCES = testsimpleserver.c testsimpleserver_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testdebugproto_SOURCES = testdebugproto.c testdebugproto_LDADD = libtestgenc.la testoptionalrequired_SOURCES = testoptionalrequired.c testoptionalrequired_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la testthrifttest_SOURCES = testthrifttest.c testthrifttest_LDADD = libtestgenc.la \ $(top_builddir)/test/c_glib/src/thrift_test_handler.o testthrifttest_CFLAGS = -I$(top_srcdir)/test/c_glib/src -I./gen-c_glib $(GLIB_CFLAGS) testthriftbinaryreadcheck_SOURCES = testthriftbinaryreadcheck.c testthriftbinaryreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftcompactreadcheck_SOURCES = testthriftcompactreadcheck.c testthriftcompactreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftbufferedreadcheck_SOURCES = testthriftbufferedreadcheck.c testthriftbufferedreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftfdreadcheck_SOURCES = testthriftfdreadcheck.c testthriftfdreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftframedreadcheck_SOURCES = testthriftframedreadcheck.c testthriftframedreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftmemorybufferreadcheck_SOURCES = testthriftmemorybufferreadcheck.c testthriftmemorybufferreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthrifttestclient_SOURCES = testthrifttestclient.cpp testthrifttestclient_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp -I../src -I./gen-c_glib $(GLIB_CFLAGS) testthrifttestclient_LDADD = ../../cpp/.libs/libthrift.la ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la testthrifttestclient_LDFLAGS = -L../.libs -L../../cpp/.libs $(GLIB_LIBS) $(GOBJECT_LIBS) testthrifttestzlibclient_SOURCES = testthrifttestzlibclient.cpp testthrifttestzlibclient_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp -I../src -I./gen-c_glib $(GLIB_CFLAGS) testthrifttestzlibclient_LDADD = ../../cpp/.libs/libthrift.la ../../cpp/.libs/libthriftz.la ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la testthrifttestzlibclient_LDFLAGS = -L../.libs -L../../cpp/.libs $(GLIB_LIBS) $(GOBJECT_LIBS) check_LTLIBRARIES = libtestgenc.la $(am__append_3) nodist_libtestgenc_la_SOURCES = \ gen-c_glib/t_test_container_test_types.c \ gen-c_glib/t_test_debug_proto_test_types.c \ gen-c_glib/t_test_enum_test_types.c \ gen-c_glib/t_test_enum_test_service.c \ gen-c_glib/t_test_empty_service.c \ gen-c_glib/t_test_inherited.c \ gen-c_glib/t_test_optional_required_test_types.c \ gen-c_glib/t_test_reverse_order_service.c \ gen-c_glib/t_test_second_service.c \ gen-c_glib/t_test_service_for_exception_with_a_map.c \ gen-c_glib/t_test_srv.c \ gen-c_glib/t_test_container_service.c \ gen-c_glib/t_test_thrift_test.c \ gen-c_glib/t_test_thrift_test_types.c \ gen-c_glib/t_test_container_test_types.h \ gen-c_glib/t_test_debug_proto_test_types.h \ gen-c_glib/t_test_enum_test_types.h \ gen-c_glib/t_test_enum_test_service.h \ gen-c_glib/t_test_empty_service.h \ gen-c_glib/t_test_inherited.h \ gen-c_glib/t_test_optional_required_test_types.h \ gen-c_glib/t_test_reverse_order_service.h \ gen-c_glib/t_test_second_service.h \ gen-c_glib/t_test_service_for_exception_with_a_map.h \ gen-c_glib/t_test_srv.h \ gen-c_glib/t_test_container_service.h \ gen-c_glib/t_test_thrift_test.h \ gen-c_glib/t_test_thrift_test_types.h libtestgenc_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la libtestgenc_la_CPPFLAGS = $(AM_CPPFLAGS) -Wno-unused-function nodist_libtestgencpp_la_SOURCES = \ gen-cpp/ThriftTest.cpp \ gen-cpp/ThriftTest_constants.cpp \ gen-cpp/ThriftTest_types.cpp \ gen-cpp/ThriftTest.h \ gen-cpp/ThriftTest_constants.h \ gen-cpp/ThriftTest_types.h libtestgencpp_la_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp # globally added to all instances of valgrind calls # VALGRIND_OPTS = --suppressions=glib.suppress VALGRIND_OPTS = # globally added to all memcheck calls VALGRIND_MEM_OPTS = --tool=memcheck \ --num-callers=10 \ ${myextravalgrindmemopts} # globally added to all leakcheck calls VALGRIND_LEAK_OPTS = --tool=memcheck \ --num-callers=10 \ --leak-check=full \ --leak-resolution=high \ ${myextravalgrindleakopts} CLEANFILES = \ *.bb \ *.bbg \ *.da \ *.gcno \ *.gcda \ *.gcov EXTRA_DIST = \ CMakeLists.txt \ ContainerTest.thrift all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/c_glib/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/c_glib/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gen-c_glib/$(am__dirstamp): @$(MKDIR_P) gen-c_glib @: > gen-c_glib/$(am__dirstamp) gen-c_glib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gen-c_glib/$(DEPDIR) @: > gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_container_test_types.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_debug_proto_test_types.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_enum_test_types.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_enum_test_service.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_empty_service.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_inherited.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_optional_required_test_types.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_reverse_order_service.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_second_service.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_service_for_exception_with_a_map.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_srv.lo: gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_container_service.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_thrift_test.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) gen-c_glib/libtestgenc_la-t_test_thrift_test_types.lo: \ gen-c_glib/$(am__dirstamp) \ gen-c_glib/$(DEPDIR)/$(am__dirstamp) libtestgenc.la: $(libtestgenc_la_OBJECTS) $(libtestgenc_la_DEPENDENCIES) $(EXTRA_libtestgenc_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libtestgenc_la_OBJECTS) $(libtestgenc_la_LIBADD) $(LIBS) gen-cpp/$(am__dirstamp): @$(MKDIR_P) gen-cpp @: > gen-cpp/$(am__dirstamp) gen-cpp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gen-cpp/$(DEPDIR) @: > gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/libtestgencpp_la-ThriftTest.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/libtestgencpp_la-ThriftTest_constants.lo: \ gen-cpp/$(am__dirstamp) gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/libtestgencpp_la-ThriftTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) libtestgencpp.la: $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_DEPENDENCIES) $(EXTRA_libtestgencpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(am_libtestgencpp_la_rpath) $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_LIBADD) $(LIBS) testapplicationexception$(EXEEXT): $(testapplicationexception_OBJECTS) $(testapplicationexception_DEPENDENCIES) $(EXTRA_testapplicationexception_DEPENDENCIES) @rm -f testapplicationexception$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testapplicationexception_OBJECTS) $(testapplicationexception_LDADD) $(LIBS) testbinaryprotocol$(EXEEXT): $(testbinaryprotocol_OBJECTS) $(testbinaryprotocol_DEPENDENCIES) $(EXTRA_testbinaryprotocol_DEPENDENCIES) @rm -f testbinaryprotocol$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testbinaryprotocol_OBJECTS) $(testbinaryprotocol_LDADD) $(LIBS) testbufferedtransport$(EXEEXT): $(testbufferedtransport_OBJECTS) $(testbufferedtransport_DEPENDENCIES) $(EXTRA_testbufferedtransport_DEPENDENCIES) @rm -f testbufferedtransport$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testbufferedtransport_OBJECTS) $(testbufferedtransport_LDADD) $(LIBS) testcompactprotocol$(EXEEXT): $(testcompactprotocol_OBJECTS) $(testcompactprotocol_DEPENDENCIES) $(EXTRA_testcompactprotocol_DEPENDENCIES) @rm -f testcompactprotocol$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testcompactprotocol_OBJECTS) $(testcompactprotocol_LDADD) $(LIBS) testcontainertest$(EXEEXT): $(testcontainertest_OBJECTS) $(testcontainertest_DEPENDENCIES) $(EXTRA_testcontainertest_DEPENDENCIES) @rm -f testcontainertest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testcontainertest_OBJECTS) $(testcontainertest_LDADD) $(LIBS) testdebugproto$(EXEEXT): $(testdebugproto_OBJECTS) $(testdebugproto_DEPENDENCIES) $(EXTRA_testdebugproto_DEPENDENCIES) @rm -f testdebugproto$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testdebugproto_OBJECTS) $(testdebugproto_LDADD) $(LIBS) testfdtransport$(EXEEXT): $(testfdtransport_OBJECTS) $(testfdtransport_DEPENDENCIES) $(EXTRA_testfdtransport_DEPENDENCIES) @rm -f testfdtransport$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testfdtransport_OBJECTS) $(testfdtransport_LDADD) $(LIBS) testframedtransport$(EXEEXT): $(testframedtransport_OBJECTS) $(testframedtransport_DEPENDENCIES) $(EXTRA_testframedtransport_DEPENDENCIES) @rm -f testframedtransport$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testframedtransport_OBJECTS) $(testframedtransport_LDADD) $(LIBS) testmemorybuffer$(EXEEXT): $(testmemorybuffer_OBJECTS) $(testmemorybuffer_DEPENDENCIES) $(EXTRA_testmemorybuffer_DEPENDENCIES) @rm -f testmemorybuffer$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testmemorybuffer_OBJECTS) $(testmemorybuffer_LDADD) $(LIBS) testoptionalrequired$(EXEEXT): $(testoptionalrequired_OBJECTS) $(testoptionalrequired_DEPENDENCIES) $(EXTRA_testoptionalrequired_DEPENDENCIES) @rm -f testoptionalrequired$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testoptionalrequired_OBJECTS) $(testoptionalrequired_LDADD) $(LIBS) testserialization$(EXEEXT): $(testserialization_OBJECTS) $(testserialization_DEPENDENCIES) $(EXTRA_testserialization_DEPENDENCIES) @rm -f testserialization$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testserialization_OBJECTS) $(testserialization_LDADD) $(LIBS) testsimpleserver$(EXEEXT): $(testsimpleserver_OBJECTS) $(testsimpleserver_DEPENDENCIES) $(EXTRA_testsimpleserver_DEPENDENCIES) @rm -f testsimpleserver$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testsimpleserver_OBJECTS) $(testsimpleserver_LDADD) $(LIBS) teststruct$(EXEEXT): $(teststruct_OBJECTS) $(teststruct_DEPENDENCIES) $(EXTRA_teststruct_DEPENDENCIES) @rm -f teststruct$(EXEEXT) $(AM_V_CCLD)$(LINK) $(teststruct_OBJECTS) $(teststruct_LDADD) $(LIBS) testthriftbinaryreadcheck$(EXEEXT): $(testthriftbinaryreadcheck_OBJECTS) $(testthriftbinaryreadcheck_DEPENDENCIES) $(EXTRA_testthriftbinaryreadcheck_DEPENDENCIES) @rm -f testthriftbinaryreadcheck$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testthriftbinaryreadcheck_OBJECTS) $(testthriftbinaryreadcheck_LDADD) $(LIBS) testthriftbufferedreadcheck$(EXEEXT): $(testthriftbufferedreadcheck_OBJECTS) $(testthriftbufferedreadcheck_DEPENDENCIES) $(EXTRA_testthriftbufferedreadcheck_DEPENDENCIES) @rm -f testthriftbufferedreadcheck$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testthriftbufferedreadcheck_OBJECTS) $(testthriftbufferedreadcheck_LDADD) $(LIBS) testthriftcompactreadcheck$(EXEEXT): $(testthriftcompactreadcheck_OBJECTS) $(testthriftcompactreadcheck_DEPENDENCIES) $(EXTRA_testthriftcompactreadcheck_DEPENDENCIES) @rm -f testthriftcompactreadcheck$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testthriftcompactreadcheck_OBJECTS) $(testthriftcompactreadcheck_LDADD) $(LIBS) testthriftfdreadcheck$(EXEEXT): $(testthriftfdreadcheck_OBJECTS) $(testthriftfdreadcheck_DEPENDENCIES) $(EXTRA_testthriftfdreadcheck_DEPENDENCIES) @rm -f testthriftfdreadcheck$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testthriftfdreadcheck_OBJECTS) $(testthriftfdreadcheck_LDADD) $(LIBS) testthriftframedreadcheck$(EXEEXT): $(testthriftframedreadcheck_OBJECTS) $(testthriftframedreadcheck_DEPENDENCIES) $(EXTRA_testthriftframedreadcheck_DEPENDENCIES) @rm -f testthriftframedreadcheck$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testthriftframedreadcheck_OBJECTS) $(testthriftframedreadcheck_LDADD) $(LIBS) testthriftmemorybufferreadcheck$(EXEEXT): $(testthriftmemorybufferreadcheck_OBJECTS) $(testthriftmemorybufferreadcheck_DEPENDENCIES) $(EXTRA_testthriftmemorybufferreadcheck_DEPENDENCIES) @rm -f testthriftmemorybufferreadcheck$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testthriftmemorybufferreadcheck_OBJECTS) $(testthriftmemorybufferreadcheck_LDADD) $(LIBS) testthrifttest$(EXEEXT): $(testthrifttest_OBJECTS) $(testthrifttest_DEPENDENCIES) $(EXTRA_testthrifttest_DEPENDENCIES) @rm -f testthrifttest$(EXEEXT) $(AM_V_CCLD)$(testthrifttest_LINK) $(testthrifttest_OBJECTS) $(testthrifttest_LDADD) $(LIBS) testthrifttestclient$(EXEEXT): $(testthrifttestclient_OBJECTS) $(testthrifttestclient_DEPENDENCIES) $(EXTRA_testthrifttestclient_DEPENDENCIES) @rm -f testthrifttestclient$(EXEEXT) $(AM_V_CXXLD)$(testthrifttestclient_LINK) $(testthrifttestclient_OBJECTS) $(testthrifttestclient_LDADD) $(LIBS) testthrifttestzlibclient$(EXEEXT): $(testthrifttestzlibclient_OBJECTS) $(testthrifttestzlibclient_DEPENDENCIES) $(EXTRA_testthrifttestzlibclient_DEPENDENCIES) @rm -f testthrifttestzlibclient$(EXEEXT) $(AM_V_CXXLD)$(testthrifttestzlibclient_LINK) $(testthrifttestzlibclient_OBJECTS) $(testthrifttestzlibclient_LDADD) $(LIBS) testtransportsocket$(EXEEXT): $(testtransportsocket_OBJECTS) $(testtransportsocket_DEPENDENCIES) $(EXTRA_testtransportsocket_DEPENDENCIES) @rm -f testtransportsocket$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testtransportsocket_OBJECTS) $(testtransportsocket_LDADD) $(LIBS) testtransportsslsocket$(EXEEXT): $(testtransportsslsocket_OBJECTS) $(testtransportsslsocket_DEPENDENCIES) $(EXTRA_testtransportsslsocket_DEPENDENCIES) @rm -f testtransportsslsocket$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testtransportsslsocket_OBJECTS) $(testtransportsslsocket_LDADD) $(LIBS) testzlibtransport$(EXEEXT): $(testzlibtransport_OBJECTS) $(testzlibtransport_DEPENDENCIES) $(EXTRA_testzlibtransport_DEPENDENCIES) @rm -f testzlibtransport$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testzlibtransport_OBJECTS) $(testzlibtransport_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f gen-c_glib/*.$(OBJEXT) -rm -f gen-c_glib/*.lo -rm -f gen-cpp/*.$(OBJEXT) -rm -f gen-cpp/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testapplicationexception.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbinaryprotocol.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbufferedtransport.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcompactprotocol.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcontainertest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testdebugproto.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfdtransport.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testframedtransport.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmemorybuffer.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testoptionalrequired.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testserialization.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsimpleserver.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/teststruct.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthriftbinaryreadcheck.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthriftbufferedreadcheck.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthriftcompactreadcheck.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthriftfdreadcheck.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthriftframedreadcheck.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthriftmemorybufferreadcheck.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthrifttest-testthrifttest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthrifttestclient-testthrifttestclient.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testtransportsocket.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testtransportsslsocket.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testzlibtransport.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_service.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_test_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_debug_proto_test_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_empty_service.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_service.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_inherited.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_optional_required_test_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_reverse_order_service.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_second_service.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_service_for_exception_with_a_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_srv.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_constants.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_types.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< gen-c_glib/libtestgenc_la-t_test_container_test_types.lo: gen-c_glib/t_test_container_test_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_container_test_types.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_test_types.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_container_test_types.lo `test -f 'gen-c_glib/t_test_container_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_container_test_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_test_types.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_test_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_container_test_types.c' object='gen-c_glib/libtestgenc_la-t_test_container_test_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_container_test_types.lo `test -f 'gen-c_glib/t_test_container_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_container_test_types.c gen-c_glib/libtestgenc_la-t_test_debug_proto_test_types.lo: gen-c_glib/t_test_debug_proto_test_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_debug_proto_test_types.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_debug_proto_test_types.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_debug_proto_test_types.lo `test -f 'gen-c_glib/t_test_debug_proto_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_debug_proto_test_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_debug_proto_test_types.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_debug_proto_test_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_debug_proto_test_types.c' object='gen-c_glib/libtestgenc_la-t_test_debug_proto_test_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_debug_proto_test_types.lo `test -f 'gen-c_glib/t_test_debug_proto_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_debug_proto_test_types.c gen-c_glib/libtestgenc_la-t_test_enum_test_types.lo: gen-c_glib/t_test_enum_test_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_enum_test_types.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_types.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_enum_test_types.lo `test -f 'gen-c_glib/t_test_enum_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_enum_test_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_types.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_enum_test_types.c' object='gen-c_glib/libtestgenc_la-t_test_enum_test_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_enum_test_types.lo `test -f 'gen-c_glib/t_test_enum_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_enum_test_types.c gen-c_glib/libtestgenc_la-t_test_enum_test_service.lo: gen-c_glib/t_test_enum_test_service.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_enum_test_service.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_service.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_enum_test_service.lo `test -f 'gen-c_glib/t_test_enum_test_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_enum_test_service.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_service.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_service.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_enum_test_service.c' object='gen-c_glib/libtestgenc_la-t_test_enum_test_service.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_enum_test_service.lo `test -f 'gen-c_glib/t_test_enum_test_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_enum_test_service.c gen-c_glib/libtestgenc_la-t_test_empty_service.lo: gen-c_glib/t_test_empty_service.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_empty_service.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_empty_service.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_empty_service.lo `test -f 'gen-c_glib/t_test_empty_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_empty_service.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_empty_service.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_empty_service.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_empty_service.c' object='gen-c_glib/libtestgenc_la-t_test_empty_service.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_empty_service.lo `test -f 'gen-c_glib/t_test_empty_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_empty_service.c gen-c_glib/libtestgenc_la-t_test_inherited.lo: gen-c_glib/t_test_inherited.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_inherited.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_inherited.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_inherited.lo `test -f 'gen-c_glib/t_test_inherited.c' || echo '$(srcdir)/'`gen-c_glib/t_test_inherited.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_inherited.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_inherited.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_inherited.c' object='gen-c_glib/libtestgenc_la-t_test_inherited.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_inherited.lo `test -f 'gen-c_glib/t_test_inherited.c' || echo '$(srcdir)/'`gen-c_glib/t_test_inherited.c gen-c_glib/libtestgenc_la-t_test_optional_required_test_types.lo: gen-c_glib/t_test_optional_required_test_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_optional_required_test_types.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_optional_required_test_types.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_optional_required_test_types.lo `test -f 'gen-c_glib/t_test_optional_required_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_optional_required_test_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_optional_required_test_types.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_optional_required_test_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_optional_required_test_types.c' object='gen-c_glib/libtestgenc_la-t_test_optional_required_test_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_optional_required_test_types.lo `test -f 'gen-c_glib/t_test_optional_required_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_optional_required_test_types.c gen-c_glib/libtestgenc_la-t_test_reverse_order_service.lo: gen-c_glib/t_test_reverse_order_service.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_reverse_order_service.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_reverse_order_service.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_reverse_order_service.lo `test -f 'gen-c_glib/t_test_reverse_order_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_reverse_order_service.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_reverse_order_service.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_reverse_order_service.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_reverse_order_service.c' object='gen-c_glib/libtestgenc_la-t_test_reverse_order_service.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_reverse_order_service.lo `test -f 'gen-c_glib/t_test_reverse_order_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_reverse_order_service.c gen-c_glib/libtestgenc_la-t_test_second_service.lo: gen-c_glib/t_test_second_service.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_second_service.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_second_service.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_second_service.lo `test -f 'gen-c_glib/t_test_second_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_second_service.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_second_service.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_second_service.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_second_service.c' object='gen-c_glib/libtestgenc_la-t_test_second_service.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_second_service.lo `test -f 'gen-c_glib/t_test_second_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_second_service.c gen-c_glib/libtestgenc_la-t_test_service_for_exception_with_a_map.lo: gen-c_glib/t_test_service_for_exception_with_a_map.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_service_for_exception_with_a_map.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_service_for_exception_with_a_map.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_service_for_exception_with_a_map.lo `test -f 'gen-c_glib/t_test_service_for_exception_with_a_map.c' || echo '$(srcdir)/'`gen-c_glib/t_test_service_for_exception_with_a_map.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_service_for_exception_with_a_map.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_service_for_exception_with_a_map.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_service_for_exception_with_a_map.c' object='gen-c_glib/libtestgenc_la-t_test_service_for_exception_with_a_map.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_service_for_exception_with_a_map.lo `test -f 'gen-c_glib/t_test_service_for_exception_with_a_map.c' || echo '$(srcdir)/'`gen-c_glib/t_test_service_for_exception_with_a_map.c gen-c_glib/libtestgenc_la-t_test_srv.lo: gen-c_glib/t_test_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_srv.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_srv.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_srv.lo `test -f 'gen-c_glib/t_test_srv.c' || echo '$(srcdir)/'`gen-c_glib/t_test_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_srv.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_srv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_srv.c' object='gen-c_glib/libtestgenc_la-t_test_srv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_srv.lo `test -f 'gen-c_glib/t_test_srv.c' || echo '$(srcdir)/'`gen-c_glib/t_test_srv.c gen-c_glib/libtestgenc_la-t_test_container_service.lo: gen-c_glib/t_test_container_service.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_container_service.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_service.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_container_service.lo `test -f 'gen-c_glib/t_test_container_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_container_service.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_service.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_service.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_container_service.c' object='gen-c_glib/libtestgenc_la-t_test_container_service.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_container_service.lo `test -f 'gen-c_glib/t_test_container_service.c' || echo '$(srcdir)/'`gen-c_glib/t_test_container_service.c gen-c_glib/libtestgenc_la-t_test_thrift_test.lo: gen-c_glib/t_test_thrift_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_thrift_test.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_thrift_test.lo `test -f 'gen-c_glib/t_test_thrift_test.c' || echo '$(srcdir)/'`gen-c_glib/t_test_thrift_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_thrift_test.c' object='gen-c_glib/libtestgenc_la-t_test_thrift_test.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_thrift_test.lo `test -f 'gen-c_glib/t_test_thrift_test.c' || echo '$(srcdir)/'`gen-c_glib/t_test_thrift_test.c gen-c_glib/libtestgenc_la-t_test_thrift_test_types.lo: gen-c_glib/t_test_thrift_test_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gen-c_glib/libtestgenc_la-t_test_thrift_test_types.lo -MD -MP -MF gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test_types.Tpo -c -o gen-c_glib/libtestgenc_la-t_test_thrift_test_types.lo `test -f 'gen-c_glib/t_test_thrift_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_thrift_test_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test_types.Tpo gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-c_glib/t_test_thrift_test_types.c' object='gen-c_glib/libtestgenc_la-t_test_thrift_test_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgenc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gen-c_glib/libtestgenc_la-t_test_thrift_test_types.lo `test -f 'gen-c_glib/t_test_thrift_test_types.c' || echo '$(srcdir)/'`gen-c_glib/t_test_thrift_test_types.c testthrifttest-testthrifttest.o: testthrifttest.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testthrifttest_CFLAGS) $(CFLAGS) -MT testthrifttest-testthrifttest.o -MD -MP -MF $(DEPDIR)/testthrifttest-testthrifttest.Tpo -c -o testthrifttest-testthrifttest.o `test -f 'testthrifttest.c' || echo '$(srcdir)/'`testthrifttest.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testthrifttest-testthrifttest.Tpo $(DEPDIR)/testthrifttest-testthrifttest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testthrifttest.c' object='testthrifttest-testthrifttest.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testthrifttest_CFLAGS) $(CFLAGS) -c -o testthrifttest-testthrifttest.o `test -f 'testthrifttest.c' || echo '$(srcdir)/'`testthrifttest.c testthrifttest-testthrifttest.obj: testthrifttest.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testthrifttest_CFLAGS) $(CFLAGS) -MT testthrifttest-testthrifttest.obj -MD -MP -MF $(DEPDIR)/testthrifttest-testthrifttest.Tpo -c -o testthrifttest-testthrifttest.obj `if test -f 'testthrifttest.c'; then $(CYGPATH_W) 'testthrifttest.c'; else $(CYGPATH_W) '$(srcdir)/testthrifttest.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testthrifttest-testthrifttest.Tpo $(DEPDIR)/testthrifttest-testthrifttest.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testthrifttest.c' object='testthrifttest-testthrifttest.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testthrifttest_CFLAGS) $(CFLAGS) -c -o testthrifttest-testthrifttest.obj `if test -f 'testthrifttest.c'; then $(CYGPATH_W) 'testthrifttest.c'; else $(CYGPATH_W) '$(srcdir)/testthrifttest.c'; fi` .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< gen-cpp/libtestgencpp_la-ThriftTest.lo: gen-cpp/ThriftTest.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgencpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gen-cpp/libtestgencpp_la-ThriftTest.lo -MD -MP -MF gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest.Tpo -c -o gen-cpp/libtestgencpp_la-ThriftTest.lo `test -f 'gen-cpp/ThriftTest.cpp' || echo '$(srcdir)/'`gen-cpp/ThriftTest.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest.Tpo gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gen-cpp/ThriftTest.cpp' object='gen-cpp/libtestgencpp_la-ThriftTest.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgencpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gen-cpp/libtestgencpp_la-ThriftTest.lo `test -f 'gen-cpp/ThriftTest.cpp' || echo '$(srcdir)/'`gen-cpp/ThriftTest.cpp gen-cpp/libtestgencpp_la-ThriftTest_constants.lo: gen-cpp/ThriftTest_constants.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgencpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gen-cpp/libtestgencpp_la-ThriftTest_constants.lo -MD -MP -MF gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_constants.Tpo -c -o gen-cpp/libtestgencpp_la-ThriftTest_constants.lo `test -f 'gen-cpp/ThriftTest_constants.cpp' || echo '$(srcdir)/'`gen-cpp/ThriftTest_constants.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_constants.Tpo gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_constants.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gen-cpp/ThriftTest_constants.cpp' object='gen-cpp/libtestgencpp_la-ThriftTest_constants.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgencpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gen-cpp/libtestgencpp_la-ThriftTest_constants.lo `test -f 'gen-cpp/ThriftTest_constants.cpp' || echo '$(srcdir)/'`gen-cpp/ThriftTest_constants.cpp gen-cpp/libtestgencpp_la-ThriftTest_types.lo: gen-cpp/ThriftTest_types.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgencpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gen-cpp/libtestgencpp_la-ThriftTest_types.lo -MD -MP -MF gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_types.Tpo -c -o gen-cpp/libtestgencpp_la-ThriftTest_types.lo `test -f 'gen-cpp/ThriftTest_types.cpp' || echo '$(srcdir)/'`gen-cpp/ThriftTest_types.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_types.Tpo gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_types.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gen-cpp/ThriftTest_types.cpp' object='gen-cpp/libtestgencpp_la-ThriftTest_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestgencpp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gen-cpp/libtestgencpp_la-ThriftTest_types.lo `test -f 'gen-cpp/ThriftTest_types.cpp' || echo '$(srcdir)/'`gen-cpp/ThriftTest_types.cpp testthrifttestclient-testthrifttestclient.o: testthrifttestclient.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT testthrifttestclient-testthrifttestclient.o -MD -MP -MF $(DEPDIR)/testthrifttestclient-testthrifttestclient.Tpo -c -o testthrifttestclient-testthrifttestclient.o `test -f 'testthrifttestclient.cpp' || echo '$(srcdir)/'`testthrifttestclient.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testthrifttestclient-testthrifttestclient.Tpo $(DEPDIR)/testthrifttestclient-testthrifttestclient.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='testthrifttestclient.cpp' object='testthrifttestclient-testthrifttestclient.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o testthrifttestclient-testthrifttestclient.o `test -f 'testthrifttestclient.cpp' || echo '$(srcdir)/'`testthrifttestclient.cpp testthrifttestclient-testthrifttestclient.obj: testthrifttestclient.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT testthrifttestclient-testthrifttestclient.obj -MD -MP -MF $(DEPDIR)/testthrifttestclient-testthrifttestclient.Tpo -c -o testthrifttestclient-testthrifttestclient.obj `if test -f 'testthrifttestclient.cpp'; then $(CYGPATH_W) 'testthrifttestclient.cpp'; else $(CYGPATH_W) '$(srcdir)/testthrifttestclient.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testthrifttestclient-testthrifttestclient.Tpo $(DEPDIR)/testthrifttestclient-testthrifttestclient.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='testthrifttestclient.cpp' object='testthrifttestclient-testthrifttestclient.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o testthrifttestclient-testthrifttestclient.obj `if test -f 'testthrifttestclient.cpp'; then $(CYGPATH_W) 'testthrifttestclient.cpp'; else $(CYGPATH_W) '$(srcdir)/testthrifttestclient.cpp'; fi` testthrifttestzlibclient-testthrifttestzlibclient.o: testthrifttestzlibclient.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestzlibclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT testthrifttestzlibclient-testthrifttestzlibclient.o -MD -MP -MF $(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Tpo -c -o testthrifttestzlibclient-testthrifttestzlibclient.o `test -f 'testthrifttestzlibclient.cpp' || echo '$(srcdir)/'`testthrifttestzlibclient.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Tpo $(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='testthrifttestzlibclient.cpp' object='testthrifttestzlibclient-testthrifttestzlibclient.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestzlibclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o testthrifttestzlibclient-testthrifttestzlibclient.o `test -f 'testthrifttestzlibclient.cpp' || echo '$(srcdir)/'`testthrifttestzlibclient.cpp testthrifttestzlibclient-testthrifttestzlibclient.obj: testthrifttestzlibclient.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestzlibclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT testthrifttestzlibclient-testthrifttestzlibclient.obj -MD -MP -MF $(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Tpo -c -o testthrifttestzlibclient-testthrifttestzlibclient.obj `if test -f 'testthrifttestzlibclient.cpp'; then $(CYGPATH_W) 'testthrifttestzlibclient.cpp'; else $(CYGPATH_W) '$(srcdir)/testthrifttestzlibclient.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Tpo $(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='testthrifttestzlibclient.cpp' object='testthrifttestzlibclient-testthrifttestzlibclient.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testthrifttestzlibclient_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o testthrifttestzlibclient-testthrifttestzlibclient.obj `if test -f 'testthrifttestzlibclient.cpp'; then $(CYGPATH_W) 'testthrifttestzlibclient.cpp'; else $(CYGPATH_W) '$(srcdir)/testthrifttestzlibclient.cpp'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf gen-c_glib/.libs gen-c_glib/_libs -rm -rf gen-cpp/.libs gen-cpp/_libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_LTLIBRARIES) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f gen-c_glib/$(DEPDIR)/$(am__dirstamp) -rm -f gen-c_glib/$(am__dirstamp) -rm -f gen-cpp/$(DEPDIR)/$(am__dirstamp) -rm -f gen-cpp/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/testapplicationexception.Po -rm -f ./$(DEPDIR)/testbinaryprotocol.Po -rm -f ./$(DEPDIR)/testbufferedtransport.Po -rm -f ./$(DEPDIR)/testcompactprotocol.Po -rm -f ./$(DEPDIR)/testcontainertest.Po -rm -f ./$(DEPDIR)/testdebugproto.Po -rm -f ./$(DEPDIR)/testfdtransport.Po -rm -f ./$(DEPDIR)/testframedtransport.Po -rm -f ./$(DEPDIR)/testmemorybuffer.Po -rm -f ./$(DEPDIR)/testoptionalrequired.Po -rm -f ./$(DEPDIR)/testserialization.Po -rm -f ./$(DEPDIR)/testsimpleserver.Po -rm -f ./$(DEPDIR)/teststruct.Po -rm -f ./$(DEPDIR)/testthriftbinaryreadcheck.Po -rm -f ./$(DEPDIR)/testthriftbufferedreadcheck.Po -rm -f ./$(DEPDIR)/testthriftcompactreadcheck.Po -rm -f ./$(DEPDIR)/testthriftfdreadcheck.Po -rm -f ./$(DEPDIR)/testthriftframedreadcheck.Po -rm -f ./$(DEPDIR)/testthriftmemorybufferreadcheck.Po -rm -f ./$(DEPDIR)/testthrifttest-testthrifttest.Po -rm -f ./$(DEPDIR)/testthrifttestclient-testthrifttestclient.Po -rm -f ./$(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Po -rm -f ./$(DEPDIR)/testtransportsocket.Po -rm -f ./$(DEPDIR)/testtransportsslsocket.Po -rm -f ./$(DEPDIR)/testzlibtransport.Po -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_debug_proto_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_empty_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_inherited.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_optional_required_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_reverse_order_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_second_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_service_for_exception_with_a_map.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_srv.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test_types.Plo -rm -f gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest.Plo -rm -f gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_constants.Plo -rm -f gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_types.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/testapplicationexception.Po -rm -f ./$(DEPDIR)/testbinaryprotocol.Po -rm -f ./$(DEPDIR)/testbufferedtransport.Po -rm -f ./$(DEPDIR)/testcompactprotocol.Po -rm -f ./$(DEPDIR)/testcontainertest.Po -rm -f ./$(DEPDIR)/testdebugproto.Po -rm -f ./$(DEPDIR)/testfdtransport.Po -rm -f ./$(DEPDIR)/testframedtransport.Po -rm -f ./$(DEPDIR)/testmemorybuffer.Po -rm -f ./$(DEPDIR)/testoptionalrequired.Po -rm -f ./$(DEPDIR)/testserialization.Po -rm -f ./$(DEPDIR)/testsimpleserver.Po -rm -f ./$(DEPDIR)/teststruct.Po -rm -f ./$(DEPDIR)/testthriftbinaryreadcheck.Po -rm -f ./$(DEPDIR)/testthriftbufferedreadcheck.Po -rm -f ./$(DEPDIR)/testthriftcompactreadcheck.Po -rm -f ./$(DEPDIR)/testthriftfdreadcheck.Po -rm -f ./$(DEPDIR)/testthriftframedreadcheck.Po -rm -f ./$(DEPDIR)/testthriftmemorybufferreadcheck.Po -rm -f ./$(DEPDIR)/testthrifttest-testthrifttest.Po -rm -f ./$(DEPDIR)/testthrifttestclient-testthrifttestclient.Po -rm -f ./$(DEPDIR)/testthrifttestzlibclient-testthrifttestzlibclient.Po -rm -f ./$(DEPDIR)/testtransportsocket.Po -rm -f ./$(DEPDIR)/testtransportsslsocket.Po -rm -f ./$(DEPDIR)/testzlibtransport.Po -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_container_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_debug_proto_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_empty_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_enum_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_inherited.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_optional_required_test_types.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_reverse_order_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_second_service.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_service_for_exception_with_a_map.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_srv.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test.Plo -rm -f gen-c_glib/$(DEPDIR)/libtestgenc_la-t_test_thrift_test_types.Plo -rm -f gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest.Plo -rm -f gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_constants.Plo -rm -f gen-cpp/$(DEPDIR)/libtestgencpp_la-ThriftTest_types.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) all check check-am install install-am \ install-exec install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-TESTS check-am clean \ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool clean-local cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-c_glib/t_test_container_test_types.c gen-c_glib/t_test_container_test_types.h gen-c_glib/t_test_container_service.c gen-c_glib/t_test_container_service.h: ContainerTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< gen-c_glib/t_test_debug_proto_test_types.c gen-c_glib/t_test_debug_proto_test_types.h gen-c_glib/t_test_empty_service.c gen-c_glib/t_test_empty_service.h gen-c_glib/t_test_inherited.c gen-c_glib/t_test_inherited.h gen-c_glib/t_test_reverse_order_service.c gen-c_glib/t_test_reverse_order_service.h gen-c_glib/t_test_service_for_exception_with_a_map.c gen-c_glib/t_test_service_for_exception_with_a_map.h gen-c_glib/t_test_srv.c gen-c_glib/t_test_srv.h: ../../../test/v0.16/DebugProtoTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< gen-c_glib/t_test_enum_test_types.c gen-c_glib/t_test_enum_test_types.h gen-c_glib/t_test_enum_test_service.c gen-c_glib/t_test_enum_test_service.h : ../../../test/EnumTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< gen-c_glib/t_test_optional_required_test_types.c gen-c_glib/t_test_optional_required_test_types.h: ../../../test/OptionalRequiredTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< 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/ThriftTest.thrift $(THRIFT) $(THRIFT) --gen cpp $< memcheck: $(check_PROGRAMS) @for x in $(check_PROGRAMS); \ do \ $(MAKE) memcheck-$$x; \ done leakcheck: $(check_PROGRAMS) @for x in $(check_PROGRAMS); \ do \ $(MAKE) leakcheck-$$x; \ done memcheck-%: % @echo "*****************************************"; \ echo "MEMCHECK: $<"; \ echo "ARGS: ${VALGRIND_OPTS} ${VALGRIND_MEM_OPTS} ${$<_VALGRIND_MEM_OPTS}"; \ $(LIBTOOL) --mode=execute \ valgrind \ ${VALGRIND_OPTS} \ ${VALGRIND_MEM_OPTS} \ ${$<_VALGRIND_MEM_OPTS} ./$< leakcheck-%: % @echo "*****************************************"; \ echo "LEAKCHECK: $<"; \ echo "ARGS: ${VALGRIND_OPTS} ${VALGRIND_LEAK_OPTS} ${$<_VALGRIND_LEAK_OPTS}"; \ G_SLICE=always-malloc $(LIBTOOL) --mode=execute \ valgrind \ ${VALGRIND_OPTS} \ ${VALGRIND_LEAK_OPTS} \ ${$<_VALGRIND_LEAK_OPTS} ./$< clean-local: $(RM) gen-c_glib/* gen-cpp/* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/c_glib/test/testthriftmemorybufferreadcheck.c0000664000175000017500000000643615165535636025173 0ustar00buildbuild00000000000000/* * 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 static const gchar TEST_DATA[11] = "abcdefghij"; #include "../src/thrift/c_glib/transport/thrift_memory_buffer.c" #define MAX_MESSAGE_SIZE 2 static void test_open_and_close (void) { ThriftMemoryBuffer *tbuffer = NULL; ThriftConfiguration *tconfiguration = NULL; /* create a ThriftConfiguration */ tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, "max_frame_size", MAX_MESSAGE_SIZE, NULL); /* create a ThriftMemoryBuffer */ tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "configuration", tconfiguration, NULL); /* no-ops */ g_assert (thrift_memory_buffer_open (THRIFT_TRANSPORT (tbuffer), NULL) == TRUE); g_assert (thrift_memory_buffer_is_open (THRIFT_TRANSPORT (tbuffer)) == TRUE); g_assert (thrift_memory_buffer_close (THRIFT_TRANSPORT (tbuffer), NULL) == TRUE); g_object_unref (tbuffer); g_object_unref (tconfiguration); } static void test_read_and_write (void) { ThriftConfiguration *tconfiguration = NULL; ThriftMemoryBuffer *tbuffer = NULL; gint got, want; gchar read[10]; gchar *b; GError *error = NULL; tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, NULL); tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 15, "configuration", tconfiguration, NULL); THRIFT_TRANSPORT_GET_CLASS (tbuffer)->resetConsumedMessageSize(THRIFT_TRANSPORT(tbuffer), -1, NULL); g_assert (thrift_memory_buffer_write (THRIFT_TRANSPORT (tbuffer), (gpointer) TEST_DATA, 10, &error) == TRUE); g_assert (error == NULL); memset(read, 0, 10); b = read; want = 10; got = thrift_memory_buffer_read (THRIFT_TRANSPORT (tbuffer), (gpointer) b, want, &error); g_assert (got < 0); g_object_unref (tbuffer); g_object_unref (tconfiguration); } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testthriftmemorybufferreadcheck/OpenAndClose", test_open_and_close); g_test_add_func ("/testthriftmemorybufferreadcheck/ReadAndWrite", test_read_and_write); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testtransportsslsocket.c0000664000175000017500000003527515165535636023410 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define _POSIX_C_SOURCE 200112L /* https://stackoverflow.com/questions/37541985/storage-size-of-addrinfo-isnt-known */ #include #include #include #include #include #include #include #include #include #include /* #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } */ #define TEST_DATA { "GET / HTTP/1.1\n\n" } /* substituted functions to test failures of system and library calls */ static int socket_error = 0; int my_socket(int domain, int type, int protocol) { if (socket_error == 0) { return socket (domain, type, protocol); } return -1; } static int recv_error = 0; ssize_t my_recv(int socket, void *buffer, size_t length, int flags) { if (recv_error == 0) { return recv (socket, buffer, length, flags); } return -1; } static int send_error = 0; ssize_t my_send(int socket, const void *buffer, size_t length, int flags) { if (send_error == 0) { return send (socket, buffer, length, flags); } return -1; } #define socket my_socket #define recv my_recv #define send my_send #include "../src/thrift/c_glib/transport/thrift_ssl_socket.c" #undef socket #undef recv #undef send static void thrift_socket_server (const int port); /* test object creation and destruction */ static void test_ssl_create_and_destroy(void) { gchar *hostname = NULL; guint port = 0; GObject *object = NULL; object = g_object_new (THRIFT_TYPE_SSL_SOCKET, NULL); g_assert (object != NULL); g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL); g_free (hostname); g_object_unref (object); } static void test_ssl_create_and_set_properties(void) { gchar *hostname = NULL; guint port = 0; SSL_CTX* ssl_ctx= NULL; GError *error=NULL; GObject *object = NULL; object = (GObject *)thrift_ssl_socket_new(SSLTLS, &error); g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, "ssl_context", &ssl_ctx, NULL); g_assert (ssl_ctx!=NULL); g_free (hostname); g_object_unref (object); } static void test_ssl_open_and_close_non_ssl_server(void) { ThriftSSLSocket *tSSLSocket = NULL; ThriftTransport *transport = NULL; GError *error=NULL; pid_t pid; int non_ssl_port = 51198; char errormsg[255]; pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { /* child listens */ /* This is a non SSL server */ thrift_socket_server (non_ssl_port); exit (0); } else { /* parent connects, wait a bit for the socket to be created */ sleep (1); /* open a connection and close it */ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", non_ssl_port, &error); transport = THRIFT_TRANSPORT (tSSLSocket); g_assert (thrift_ssl_socket_open (transport, &error) == FALSE); g_assert_cmpstr(error->message, == ,"Error while connect/bind: 68 -> Connection reset by peer"); g_clear_error (&error); g_assert (thrift_ssl_socket_is_open (transport) == FALSE); thrift_ssl_socket_close (transport, NULL); g_assert (thrift_ssl_socket_is_open (transport) == FALSE); /* test close failure */ THRIFT_SOCKET(tSSLSocket)->sd = -1; thrift_ssl_socket_close (transport, NULL); g_object_unref (tSSLSocket); /* try a hostname lookup failure */ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost.broken", non_ssl_port, &error); transport = THRIFT_TRANSPORT (tSSLSocket); g_assert (thrift_ssl_socket_open (transport, &error) == FALSE); snprintf(errormsg, 255, "host lookup failed for localhost.broken:%d - Unknown host", non_ssl_port); g_assert_cmpstr(error->message, ==, errormsg); g_clear_error (&error); g_object_unref (tSSLSocket); error = NULL; /* try an error call to socket() */ /* tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error); transport = THRIFT_TRANSPORT (tSSLSocket); socket_error = 1; assert (thrift_ssl_socket_open (transport, &error) == FALSE); socket_error = 0; g_object_unref (tSSLSocket); g_error_free (error); */ } } static void test_ssl_write_invalid_socket(void) { ThriftSSLSocket *tSSLSocket = NULL; ThriftTransport *transport = NULL; GError *error=NULL; /* open a connection and close it */ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188+1, &error); transport = THRIFT_TRANSPORT (tSSLSocket); g_assert (thrift_ssl_socket_open (transport, NULL) == FALSE); g_assert (thrift_ssl_socket_is_open (transport) == FALSE); /* FIXME This must be tested but since the assertion inside thrift_ssl_socket_write breaks the test unit it's disabled. They idea is to disable trap/coredump during this test g_assert (thrift_ssl_socket_write(transport, buffer, sizeof(buffer), &error) == FALSE); g_message ("write_failed_with_error: %s", error != NULL ? error->message : "No"); g_clear_error (&error); */ thrift_ssl_socket_close (transport, NULL); g_assert (thrift_ssl_socket_is_open (transport) == FALSE); /* test close failure */ THRIFT_SOCKET(tSSLSocket)->sd = -1; thrift_ssl_socket_close (transport, NULL); g_object_unref (tSSLSocket); } /** * Print the common name of certificate */ unsigned char * get_cn_name(X509_NAME* const name) { int idx = -1; unsigned char *utf8 = NULL; do { if(!name) break; /* failed */ idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1); if(!(idx > -1)) break; /* failed */ X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx); if(!entry) break; /* failed */ ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry); if(!data) break; /* failed */ int length = ASN1_STRING_to_UTF8(&utf8, data); if(!utf8 || !(length > 0)) break; /* failed */ } while (0); return utf8; } /* * Handle IPV4 and IPV6 addr */ void *get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) return &(((struct sockaddr_in*)sa)->sin_addr); return &(((struct sockaddr_in6*)sa)->sin6_addr); } int verify_ip(char * hostname, struct sockaddr_storage *addr) { struct addrinfo *addr_info,*p; struct addrinfo hints; int res; int retval = 0; memset(&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; /* use AF_INET6 to force IPv6 */ hints.ai_socktype = SOCK_STREAM; if ( (res = getaddrinfo(hostname, NULL, &hints, &addr_info) ) != 0) { /* get the host info */ g_error("Cannot get the host address"); return retval; } /* loop through all the results and connect to the first we can */ char dnshost[INET6_ADDRSTRLEN]; /* bigger addr supported IPV6 */ char socket_ip[INET6_ADDRSTRLEN]; if(inet_ntop(addr->ss_family, get_in_addr((struct sockaddr*)addr), socket_ip, INET6_ADDRSTRLEN)==socket_ip){ g_debug("We are connected to host %s checking against certificate...", socket_ip); int sizeip = socket_ip!=NULL ? strlen(socket_ip) : 0; for(p = addr_info; p != NULL; p = p->ai_next) { if(inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), dnshost, INET6_ADDRSTRLEN)==dnshost){ if(dnshost!=NULL){ g_info("DNS address [%i -> %s]", ((guint32)(p->ai_addrlen)), dnshost); if(!strncmp(dnshost, socket_ip, sizeip)){ retval=1; break; /* if we get here, we must have connected successfully */ } } } } } if(addr_info) freeaddrinfo(addr_info); return retval; } static void read_from_file(char *buffer, long size, const char *file_name) { char ch; long index=0; FILE *fp; fp = fopen(file_name,"r"); /* read mode */ if( fp == NULL ) { perror("Error while opening the file.\n"); exit(EXIT_FAILURE); } printf("The contents of %s file are :\n", file_name); while(index= len) { g_warn(stderr, "buffer length shorter than serial number\n"); BN_free(bn); OPENSSL_free(tmp); return EXIT_FAILURE; } */ if(!strncmp((const char*)serial_number, tmp, strlen((const char*)serial_number))){ retval=TRUE; }else{ g_warning("Serial number is not valid"); } BN_free(bn); OPENSSL_free(tmp); return retval; } gboolean my_access_manager(ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error) { ThriftSSLSocket *sslSocket = THRIFT_SSL_SOCKET (transport); THRIFT_UNUSED_VAR (error); THRIFT_UNUSED_VAR (sslSocket); g_info("Processing access to the server"); X509_NAME* iname = cert ? X509_get_issuer_name(cert) : NULL; X509_NAME* sname = cert ? X509_get_subject_name(cert) : NULL; /* Issuer is the authority we trust that warrants nothing useful */ const unsigned char * issuer = get_cn_name(iname); if(issuer){ gboolean valid = TRUE; g_info("Issuer (cn) %s", issuer); /* Issuer pinning */ if(strncmp(ISSUER_CN_PINNING, (const char*)issuer, strlen(ISSUER_CN_PINNING))){ g_warning("The Issuer of the certificate is not valid"); valid=FALSE; } OPENSSL_free((void*)issuer); if(!valid) return valid; } /* Subject is who the certificate is issued to by the authority */ const unsigned char * subject = get_cn_name(sname); if(subject){ g_info("Subject (cn) %s", subject); gboolean valid = TRUE; /* Subject pinning */ if(strncmp(SUBJECT_CN_PINNING, (const char*)subject, strlen(SUBJECT_CN_PINNING))){ g_warning("The subject of the certificate is not valid"); valid=FALSE; } if(!valid) return valid; /* Host pinning */ if(verify_ip((char*)subject, addr)){ g_info("Verified subject"); }else{ g_info("Cannot verify subject"); valid=FALSE; } OPENSSL_free((void*)subject); if(!valid) return valid; } if(!verify_certificate_sn(cert, (const unsigned char*)CERT_SERIAL_NUMBER)){ return FALSE; }else{ g_info("Verified serial number"); } return TRUE; } #ifdef BUILD_SERVER static void test_ssl_authorization_manager(void) { int status=0; pid_t pid; ThriftSSLSocket *tSSLsocket = NULL; ThriftTransport *transport = NULL; /* int port = 51199; */ int port = 443; GError *error=NULL; guchar buf[17] = TEST_DATA; /* a buffer */ /* pid = fork (); g_assert ( pid >= 0 ); if ( pid == 0 ) { thrift_ssl_socket_server (port); exit (0); } else { */ /* parent connects, wait a bit for the socket to be created */ sleep (1); /* Test against level2 owncloud certificate */ tSSLsocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error); thrift_ssl_socket_set_manager(tSSLsocket, my_access_manager); /* Install pinning manager */ /* thrift_ssl_load_cert_from_file(tSSLsocket, "./owncloud.level2crm.pem"); */ unsigned char cert_buffer[65534]; read_from_file(cert_buffer, 65534, "../../keys/client.pem"); if(!thrift_ssl_load_cert_from_buffer(tSSLsocket, cert_buffer)){ g_warning("Certificates cannot be loaded!"); } transport = THRIFT_TRANSPORT (tSSLsocket); g_assert (thrift_ssl_socket_open (transport, NULL) == TRUE); g_assert (thrift_ssl_socket_is_open (transport)); thrift_ssl_socket_write (transport, buf, 17, NULL); /* write fail */ send_error = 1; /* thrift_ssl_socket_write (transport, buf, 1, NULL); send_error = 0; thrift_ssl_socket_write_end (transport, NULL); thrift_ssl_socket_flush (transport, NULL); */ thrift_ssl_socket_close (transport, NULL); g_object_unref (tSSLsocket); /* g_assert ( wait (&status) == pid ); */ g_assert ( status == 0 ); /* } */ } #endif static void thrift_socket_server (const int port) { int bytes = 0; ThriftServerTransport *transport = NULL; ThriftTransport *client = NULL; guchar buf[10]; /* a buffer */ guchar match[] = TEST_DATA; ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL); transport = THRIFT_SERVER_TRANSPORT (tsocket); thrift_server_transport_listen (transport, NULL); client = thrift_server_transport_accept (transport, NULL); g_assert (client != NULL); /* read 10 bytes */ bytes = thrift_ssl_socket_read (client, buf, 10, NULL); g_assert (bytes == 10); /* make sure we've read 10 bytes */ g_assert ( memcmp(buf, match, 10) == 0 ); /* make sure what we got matches */ /* failed read */ recv_error = 1; thrift_ssl_socket_read (client, buf, 1, NULL); recv_error = 0; thrift_ssl_socket_read_end (client, NULL); thrift_ssl_socket_close (client, NULL); g_object_unref (tsocket); g_object_unref (client); } int main(int argc, char *argv[]) { int retval; #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init(); #endif g_test_init (&argc, &argv, NULL); thrift_ssl_socket_initialize_openssl(); g_test_add_func ("/testtransportsslsocket/CreateAndDestroy", test_ssl_create_and_destroy); g_test_add_func ("/testtransportsslsocket/CreateAndSetProperties", test_ssl_create_and_set_properties); g_test_add_func ("/testtransportsslsocket/OpenAndCloseNonSSLServer", test_ssl_open_and_close_non_ssl_server); g_test_add_func ("/testtransportsslsocket/OpenAndWriteInvalidSocket", test_ssl_write_invalid_socket); retval = g_test_run (); thrift_ssl_socket_finalize_openssl(); return retval; } thrift-0.23.0/lib/c_glib/test/testdebugproto.c0000664000175000017500000006551015165535636021566 0ustar00buildbuild00000000000000/* * 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 #ifndef M_PI #define M_PI 3.1415926535897932385 #endif #include #include #include "gen-c_glib/t_test_debug_proto_test_types.h" #include "gen-c_glib/t_test_srv.h" #include "gen-c_glib/t_test_inherited.h" static void test_structs_doubles_create_and_destroy (void) { GObject *object = NULL; /* A Doubles structure can be created... */ object = g_object_new (T_TEST_TYPE_DOUBLES, NULL); g_assert (object != NULL); g_assert (T_TEST_IS_DOUBLES (object)); /* ...and destroyed */ g_object_unref (object); } static void test_structs_doubles_initialize (void) { TTestDoubles *doubles = NULL; gdouble nan; gdouble inf; gdouble neginf; gdouble repeating; gdouble big; gdouble tiny; gdouble zero; gdouble negzero; /* Note there seems to be no way to get not-a-number ("NAN") values past GObject's range-checking, so that portion of the test has been commented out below. */ /* A Doubles structure's members are available as GObject properties that can be initialized at construction... */ doubles = g_object_new (T_TEST_TYPE_DOUBLES, /* "nan", 0 * INFINITY, */ "inf", INFINITY, "neginf", -INFINITY, "repeating", 1.0 / 3, "big", G_MAXDOUBLE, "tiny", 10E-101, "zero", 1.0 * 0, "negzero", -1.0 * 0, NULL); g_assert (doubles != NULL); /* ...and later retrieved */ g_object_get (doubles, "nan", &nan, "inf", &inf, "neginf", &neginf, "repeating", &repeating, "big", &big, "tiny", &tiny, "zero", &zero, "negzero", &negzero, NULL); /* g_assert_cmpint (isnan (nan), !=, 0); */ g_assert_cmpint (isinf (inf), ==, 1); g_assert_cmpint (isinf (neginf), ==, -1); g_assert_cmpfloat (repeating, ==, 1.0 / 3); g_assert_cmpfloat (big, ==, G_MAXDOUBLE); g_assert_cmpfloat (tiny, ==, 10E-101); g_assert_cmpfloat (zero, ==, 1.0 * 0); g_assert_cmpfloat (negzero, ==, -1.0 * 0); g_object_unref (doubles); } static void test_structs_one_of_each_create_and_destroy (void) { GObject *object = NULL; /* A OneOfEach structure can be created... */ object = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL); g_assert (object != NULL); g_assert (T_TEST_IS_ONE_OF_EACH (object)); /* ...and destroyed */ g_object_unref (object); } static void test_structs_one_of_each_initialize_default_values (void) { TTestOneOfEach *one_of_each = NULL; gint a_bite; gint integer16; gint64 integer64; GArray *byte_list; GArray *i16_list; GArray *i64_list; /* A OneOfEach structure created with no explicit property values will hold the default values specified in the .thrift file */ one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL); g_object_get (one_of_each, "a_bite", &a_bite, "integer16", &integer16, "integer64", &integer64, "byte_list", &byte_list, "i16_list", &i16_list, "i64_list", &i64_list, NULL); g_assert_cmpint (a_bite, ==, 0x7f); g_assert_cmpint (integer16, ==, 0x7fff); g_assert_cmpint (integer64, ==, G_GINT64_CONSTANT (10000000000)); g_assert (byte_list != NULL); g_assert_cmpint (byte_list->len, ==, 3); g_assert_cmpint (g_array_index (byte_list, gint8, 0), ==, 1); g_assert_cmpint (g_array_index (byte_list, gint8, 1), ==, 2); g_assert_cmpint (g_array_index (byte_list, gint8, 2), ==, 3); g_assert (i16_list != NULL); g_assert_cmpint (i16_list->len, ==, 3); g_assert_cmpint (g_array_index (i16_list, gint16, 0), ==, 1); g_assert_cmpint (g_array_index (i16_list, gint16, 1), ==, 2); g_assert_cmpint (g_array_index (i16_list, gint16, 2), ==, 3); g_assert (i64_list != NULL); g_assert_cmpint (i64_list->len, ==, 3); g_assert_cmpint (g_array_index (i64_list, gint64, 0), ==, 1); g_assert_cmpint (g_array_index (i64_list, gint64, 1), ==, 2); g_assert_cmpint (g_array_index (i64_list, gint64, 2), ==, 3); g_array_unref (i64_list); g_array_unref (i16_list); g_array_unref (byte_list); g_object_unref (one_of_each); } static void test_structs_one_of_each_initialize_specified_values (void) { static const gint8 initial_byte_list[5] = { 13, 21, 34, 55, 89 }; static const gint16 initial_i16_list[5] = { 4181, 6765, 10946, 17711, 28657 }; static const gint64 initial_i64_list[5] = { G_GINT64_CONSTANT (1100087778366101931), G_GINT64_CONSTANT (1779979416004714189), G_GINT64_CONSTANT (2880067194370816120), G_GINT64_CONSTANT (4660046610375530309), G_GINT64_CONSTANT (7540113804746346429) }; static const guint8 initial_base64[8] = { 0x56, 0x47, 0x68, 0x79, 0x61, 0x57, 0x5a, 0x30 }; TTestOneOfEach *one_of_each; gboolean im_true; gboolean im_false; gint a_bite; gint integer16; gint integer32; gint64 integer64; double double_precision; gchar *some_characters; gchar *zomg_unicode; gboolean what_who; GByteArray *base64; GArray *byte_list; GArray *i16_list; GArray *i64_list; base64 = g_byte_array_new (); g_byte_array_append (base64, initial_base64, 8); byte_list = g_array_new (FALSE, FALSE, sizeof (gint8)); g_array_append_vals (byte_list, initial_byte_list, 5); i16_list = g_array_new (FALSE, FALSE, sizeof (gint16)); g_array_append_vals (i16_list, initial_i16_list, 5); i64_list = g_array_new (FALSE, FALSE, sizeof (gint64)); g_array_append_vals (i64_list, initial_i64_list, 5); /* All of OneOfEach's properties can be set at construction... */ one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, "im_true", TRUE, "im_false", FALSE, "a_bite", 0x50, "integer16", 0x7e57, "integer32", 0xdeadbeef, "integer64", G_GINT64_CONSTANT (0xfa15efacade15bad), "double_precision", M_PI, "some_characters", "Debug THIS!", "zomg_unicode", "\xd7\n\a\t", "what_who", TRUE, "base64", base64, "byte_list", byte_list, "i16_list", i16_list, "i64_list", i64_list, NULL); g_assert (one_of_each != NULL); g_array_unref (i64_list); i64_list = NULL; g_array_unref (i16_list); i16_list = NULL; g_array_unref (byte_list); byte_list = NULL; g_byte_array_unref (base64); base64 = NULL; /* ...and later retrieved */ g_object_get (one_of_each, "im_true", &im_true, "im_false", &im_false, "a_bite", &a_bite, "integer16", &integer16, "integer32", &integer32, "integer64", &integer64, "double_precision", &double_precision, "some_characters", &some_characters, "zomg_unicode", &zomg_unicode, "what_who", &what_who, "base64", &base64, "byte_list", &byte_list, "i16_list", &i16_list, "i64_list", &i64_list, NULL); g_assert (im_true == TRUE); g_assert (im_false == FALSE); g_assert_cmphex (a_bite, ==, 0x50); g_assert_cmphex (integer16, ==, 0x7e57); g_assert_cmphex (integer32, ==, (gint32)0xdeadbeef); g_assert_cmphex (integer64, ==, G_GINT64_CONSTANT (0xfa15efacade15bad)); g_assert_cmpfloat (double_precision, ==, M_PI); g_assert_cmpstr (some_characters, ==, "Debug THIS!"); g_assert_cmpstr (zomg_unicode, ==, "\xd7\n\a\t"); g_assert (what_who == TRUE); g_assert_cmpint (base64->len, ==, 8); g_assert_cmpint (memcmp (base64->data, initial_base64, 8 * sizeof (guint8)), ==, 0); g_assert_cmpint (byte_list->len, ==, 5); g_assert_cmpint (memcmp (byte_list->data, initial_byte_list, 5 * sizeof (gint8)), ==, 0); g_assert_cmpint (i16_list->len, ==, 5); g_assert_cmpint (memcmp (i16_list->data, initial_i16_list, 5 * sizeof (gint16)), ==, 0); g_assert_cmpint (i64_list->len, ==, 5); g_assert_cmpint (memcmp (i64_list->data, initial_i64_list, 5 * sizeof (gint64)), ==, 0); g_array_unref (i64_list); g_array_unref (i16_list); g_array_unref (byte_list); g_byte_array_unref (base64); g_object_unref (one_of_each); } static void test_structs_one_of_each_properties_byte_list (void) { TTestOneOfEach *one_of_each; GArray *byte_list = NULL; one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL); /* OneOfEach's "byte_list" member is a list that holds eight-bit-wide integer values */ g_object_get (one_of_each, "byte_list", &byte_list, NULL); g_assert (byte_list != NULL); g_assert_cmpint (g_array_get_element_size (byte_list), ==, sizeof (gint8)); g_array_unref (byte_list); g_object_unref (one_of_each); } static void test_structs_one_of_each_properties_i16_list (void) { TTestOneOfEach *one_of_each; GArray *i16_list = NULL; one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL); /* OneOfEach's "i16_list" member is a list that holds sixteen-bit-wide integer values */ g_object_get (one_of_each, "i16_list", &i16_list, NULL); g_assert (i16_list != NULL); g_assert_cmpint (g_array_get_element_size (i16_list), ==, sizeof (gint16)); g_array_unref (i16_list); g_object_unref (one_of_each); } static void test_structs_one_of_each_properties_i64_list (void) { TTestOneOfEach *one_of_each; GArray *i64_list = NULL; one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL); /* OneOfEach's "i64_list" member is a list that holds sixty-four-bit-wide integer values */ g_object_get (one_of_each, "i64_list", &i64_list, NULL); g_assert (i64_list != NULL); g_assert_cmpint (g_array_get_element_size (i64_list), ==, sizeof (gint64)); g_array_unref (i64_list); g_object_unref (one_of_each); } static void test_structs_nesting_create_and_destroy (void) { GObject *object = NULL; /* A Nesting structure can be created... */ object = g_object_new (T_TEST_TYPE_NESTING, NULL); g_assert (object != NULL); g_assert (T_TEST_IS_NESTING (object)); /* ...and destroyed */ g_object_unref (object); } static void test_structs_nesting_properties_my_bonk (void) { TTestNesting *nesting; TTestBonk *bonk = NULL; gint type; gchar *message; nesting = g_object_new (T_TEST_TYPE_NESTING, NULL); /* Nesting's "my_bonk" member is initialized with a new, default Bonk object during construction */ g_object_get (nesting, "my_bonk", &bonk, NULL); g_assert (bonk != NULL); g_assert (T_TEST_IS_BONK (bonk)); g_object_get (bonk, "type", &type, "message", &message, NULL); g_assert_cmpint (type, ==, 0); g_assert (message == NULL); g_object_unref (bonk); bonk = NULL; /* It can be replaced... */ bonk = g_object_new (T_TEST_TYPE_BONK, "type", 100, "message", "Replacement Bonk", NULL); g_object_set (nesting, "my_bonk", bonk, NULL); g_object_unref (bonk); bonk = NULL; g_object_get (nesting, "my_bonk", &bonk, NULL); g_assert (bonk != NULL); g_assert (T_TEST_IS_BONK (bonk)); g_object_get (bonk, "type", &type, "message", &message, NULL); g_assert_cmpint (type, ==, 100); g_assert_cmpstr (message, ==, "Replacement Bonk"); g_free (message); g_object_unref (bonk); bonk = NULL; /* ...or set to null */ g_object_set (nesting, "my_bonk", NULL, NULL); g_object_get (nesting, "my_bonk", &bonk, NULL); g_assert (bonk == NULL); g_object_unref (nesting); } static void test_structs_nesting_properties_my_ooe (void) { TTestNesting *nesting; TTestOneOfEach *one_of_each = NULL; gint a_bite; gint integer16; nesting = g_object_new (T_TEST_TYPE_NESTING, NULL); /* Nesting's "my_ooe" member is initialized with a new, default OneOfEach object during construction */ g_object_get (nesting, "my_ooe", &one_of_each, NULL); g_assert (one_of_each != NULL); g_assert (T_TEST_IS_ONE_OF_EACH (one_of_each)); g_object_get (one_of_each, "a_bite", &a_bite, "integer16", &integer16, NULL); g_assert_cmphex (a_bite, ==, 0x7f); g_assert_cmphex (integer16, ==, 0x7fff); g_object_unref (one_of_each); one_of_each = NULL; /* It can be replaced... */ one_of_each = g_object_new (T_TEST_TYPE_ONE_OF_EACH, "a_bite", 0x50, "integer16", 0x5050, NULL); g_object_set (nesting, "my_ooe", one_of_each, NULL); g_object_unref (one_of_each); one_of_each = NULL; g_object_get (nesting, "my_ooe", &one_of_each, NULL); g_assert (one_of_each != NULL); g_assert (T_TEST_IS_ONE_OF_EACH (one_of_each)); g_object_get (one_of_each, "a_bite", &a_bite, "integer16", &integer16, NULL); g_assert_cmphex (a_bite, ==, 0x50); g_assert_cmphex (integer16, ==, 0x5050); g_object_unref (one_of_each); one_of_each = NULL; /* ...or set to null */ g_object_set (nesting, "my_ooe", NULL, NULL); g_object_get (nesting, "my_ooe", &one_of_each, NULL); g_assert (one_of_each == NULL); g_object_unref (nesting); } static void test_structs_holy_moley_create_and_destroy (void) { GObject *object = NULL; /* A HolyMoley structure can be created... */ object = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL); g_assert (object != NULL); g_assert (T_TEST_IS_HOLY_MOLEY (object)); /* ...and destroyed */ g_object_unref (object); } static void test_structs_holy_moley_properties_big (void) { TTestHolyMoley *holy_moley; GPtrArray *big = NULL; gint a_bite = 0; gint integer16 = 0; holy_moley = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL); /* A HolyMoley's "big" member is is initialized on construction */ g_object_get (holy_moley, "big", &big, NULL); g_assert (big != NULL); g_assert_cmpint (big->len, ==, 0); /* It can be modified... */ g_ptr_array_add (big, g_object_new (T_TEST_TYPE_ONE_OF_EACH, "a_bite", 0x50, "integer16", 0x5050, NULL)); g_ptr_array_unref (big); big = NULL; g_object_get (holy_moley, "big", &big, NULL); g_assert_cmpint (big->len, ==, 1); g_object_get (g_ptr_array_index (big, 0), "a_bite", &a_bite, "integer16", &integer16, NULL); g_assert_cmphex (a_bite, ==, 0x50); g_assert_cmphex (integer16, ==, 0x5050); g_ptr_array_unref (big); big = NULL; /* ...replaced... */ big = g_ptr_array_new_with_free_func (g_object_unref); g_ptr_array_add (big, g_object_new (T_TEST_TYPE_ONE_OF_EACH, "a_bite", 0x64, "integer16", 0x1541, NULL)); g_object_set (holy_moley, "big", big, NULL); g_ptr_array_unref (big); big = NULL; g_object_get (holy_moley, "big", &big, NULL); g_assert_cmpint (big->len, ==, 1); g_object_get (g_ptr_array_index (big, 0), "a_bite", &a_bite, "integer16", &integer16, NULL); g_assert_cmphex (a_bite, ==, 0x64); g_assert_cmphex (integer16, ==, 0x1541); g_ptr_array_unref (big); big = NULL; /* ...or set to NULL */ g_object_set (holy_moley, "big", NULL, NULL); g_object_get (holy_moley, "big", &big, NULL); g_assert (big == NULL); g_object_unref (holy_moley); } static void test_structs_holy_moley_properties_contain (void) { static gchar *strings[2] = { "Apache", "Thrift" }; TTestHolyMoley *holy_moley; GHashTable *contain = NULL; GPtrArray *string_list; GList *key_list; holy_moley = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL); /* A HolyMoley's "contain" member is initialized on construction */ g_object_get (holy_moley, "contain", &contain, NULL); g_assert (contain != NULL); g_assert_cmpint (g_hash_table_size (contain), ==, 0); /* It can be modified... */ string_list = g_ptr_array_new (); g_ptr_array_add (string_list, strings[0]); g_ptr_array_add (string_list, strings[1]); g_hash_table_insert (contain, string_list, NULL); string_list = NULL; g_hash_table_unref (contain); contain = NULL; g_object_get (holy_moley, "contain", &contain, NULL); g_assert_cmpint (g_hash_table_size (contain), ==, 1); key_list = g_hash_table_get_keys (contain); string_list = g_list_nth_data (key_list, 0); g_assert_cmpint (string_list->len, ==, 2); g_assert_cmpstr (g_ptr_array_index (string_list, 0), ==, "Apache"); g_assert_cmpstr (g_ptr_array_index (string_list, 1), ==, "Thrift"); g_list_free (key_list); g_hash_table_unref (contain); contain = NULL; /* ...replaced... */ contain = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) g_ptr_array_unref, NULL); g_object_set (holy_moley, "contain", contain, NULL); g_hash_table_unref (contain); contain = NULL; g_object_get (holy_moley, "contain", &contain, NULL); g_assert_cmpint (g_hash_table_size (contain), ==, 0); g_hash_table_unref (contain); contain = NULL; /* ...or set to NULL */ g_object_set (holy_moley, "contain", NULL, NULL); g_object_get (holy_moley, "contain", &contain, NULL); g_assert (contain == NULL); g_object_unref (holy_moley); } static void test_structs_holy_moley_properties_bonks (void) { TTestHolyMoley *holy_moley; GHashTable *bonks = NULL; GPtrArray *bonk_list = NULL; TTestBonk *bonk = NULL; gint type; gchar *message; GList *key_list; holy_moley = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL); /* A HolyMoley's "bonks" member is initialized on construction */ g_object_get (holy_moley, "bonks", &bonks, NULL); g_assert (bonks != NULL); g_assert_cmpint (g_hash_table_size (bonks), ==, 0); /* It can be modified... */ bonk = g_object_new (T_TEST_TYPE_BONK, "type", 100, "message", "Sample Bonk", NULL); bonk_list = g_ptr_array_new_with_free_func (g_object_unref); g_ptr_array_add (bonk_list, bonk); bonk = NULL; g_hash_table_insert (bonks, g_strdup ("Sample Bonks"), bonk_list); bonk_list = NULL; g_hash_table_unref (bonks); bonks = NULL; g_object_get (holy_moley, "bonks", &bonks, NULL); g_assert_cmpint (g_hash_table_size (bonks), ==, 1); key_list = g_hash_table_get_keys (bonks); bonk_list = g_hash_table_lookup (bonks, g_list_nth_data (key_list, 0)); g_assert_cmpint (bonk_list->len, ==, 1); bonk = (g_ptr_array_index (bonk_list, 0)); g_object_get (bonk, "type", &type, "message", &message, NULL); g_assert_cmpint (type, ==, 100); g_assert_cmpstr (message, ==, "Sample Bonk"); bonk = NULL; g_free (message); g_list_free (key_list); g_hash_table_unref (bonks); bonks = NULL; /* ...replaced... */ bonks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); g_object_set (holy_moley, "bonks", bonks, NULL); g_hash_table_unref (bonks); bonks = NULL; g_object_get (holy_moley, "bonks", &bonks, NULL); g_assert_cmpint (g_hash_table_size (bonks), ==, 0); g_hash_table_unref (bonks); bonks = NULL; /* ...or set to NULL */ g_object_set (holy_moley, "bonks", NULL, NULL); g_object_get (holy_moley, "bonks", &bonks, NULL); g_assert (bonks == NULL); g_object_unref (holy_moley); } static void test_structs_empty (void) { GObject *object = NULL; GParamSpec **properties; guint property_count; /* An Empty structure can be created */ object = g_object_new (T_TEST_TYPE_EMPTY, NULL); g_assert (object != NULL); g_assert (T_TEST_IS_EMPTY (object)); /* An Empty structure has no members and thus no properties */ properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &property_count); g_assert_cmpint (property_count, ==, 0); g_free (properties); /* An Empty structure can be destroyed */ g_object_unref (object); } static void test_structs_wrapper_create_and_destroy (void) { GObject *object = NULL; /* A Wrapper structure can be created... */ object = g_object_new (T_TEST_TYPE_EMPTY, NULL); g_assert (object != NULL); g_assert (T_TEST_IS_EMPTY (object)); /* ...and destroyed */ g_object_unref (object); } static void test_structs_wrapper_properties_foo (void) { TTestWrapper *wrapper; TTestEmpty *foo; wrapper = g_object_new (T_TEST_TYPE_WRAPPER, NULL); /* A Wrapper structure has one member, "foo", which is an Empty structure initialized during construction */ g_object_get (wrapper, "foo", &foo, NULL); g_assert (foo != NULL); g_assert (T_TEST_IS_EMPTY (foo)); g_object_unref (foo); foo = NULL; /* A Wrapper's foo property can be replaced... */ foo = g_object_new (T_TEST_TYPE_EMPTY, NULL); g_object_set (wrapper, "foo", foo, NULL); g_object_unref (foo); foo = NULL; g_object_get (wrapper, "foo", &foo, NULL); g_assert (foo != NULL); g_assert (T_TEST_IS_EMPTY (foo)); g_object_unref (foo); foo = NULL; /* ...or set to NULL */ g_object_set (wrapper, "foo", NULL, NULL); g_object_get (wrapper, "foo", &foo, NULL); g_assert (foo == NULL); g_object_unref (wrapper); } static void test_services_inherited (void) { ThriftProtocol *protocol; TTestInheritedClient *inherited_client; GObject *input_protocol, *output_protocol; protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, NULL); inherited_client = g_object_new (T_TEST_TYPE_INHERITED_CLIENT, NULL); /* TTestInheritedClient inherits from TTestSrvClient */ g_assert (g_type_is_a (T_TEST_TYPE_INHERITED_CLIENT, T_TEST_TYPE_SRV_CLIENT)); /* TTestInheritedClient implements TTestSrvClient's interface */ g_assert (g_type_is_a (T_TEST_TYPE_INHERITED_CLIENT, T_TEST_TYPE_SRV_IF)); /* TTestInheritedClient's inherited properties can be set and retrieved */ g_object_set (inherited_client, "input_protocol", protocol, "output_protocol", protocol, NULL); g_object_get (inherited_client, "input_protocol", &input_protocol, "output_protocol", &output_protocol, NULL); g_assert (input_protocol == G_OBJECT(protocol)); g_assert (output_protocol == G_OBJECT(protocol)); g_object_unref (output_protocol); g_object_unref (input_protocol); g_object_unref (inherited_client); g_object_unref (protocol); } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testdebugproto/DebugProto/Structs/Doubles/CreateAndDestroy", test_structs_doubles_create_and_destroy); g_test_add_func ("/testdebugproto/DebugProto/Structs/Doubles/Initialize", test_structs_doubles_initialize); g_test_add_func ("/testdebugproto/DebugProto/Structs/OneOfEach/CreateAndDestroy", test_structs_one_of_each_create_and_destroy); g_test_add_func ("/testdebugproto/DebugProto/Structs/OneOfEach/Initialize/DefaultValues", test_structs_one_of_each_initialize_default_values); g_test_add_func ("/testdebugproto/DebugProto/Structs/OneOfEach/Initialize/SpecifiedValues", test_structs_one_of_each_initialize_specified_values); g_test_add_func ("/testdebugproto/DebugProto/Structs/OneOfEach/Properties/byte_list", test_structs_one_of_each_properties_byte_list); g_test_add_func ("/testdebugproto/DebugProto/Structs/OneOfEach/Properties/i16_list", test_structs_one_of_each_properties_i16_list); g_test_add_func ("/testdebugproto/DebugProto/Structs/OneOfEach/Properties/i64_list", test_structs_one_of_each_properties_i64_list); g_test_add_func ("/testdebugproto/DebugProto/Structs/Nesting/CreateAndDestroy", test_structs_nesting_create_and_destroy); g_test_add_func ("/testdebugproto/DebugProto/Structs/Nesting/Properties/my_bonk", test_structs_nesting_properties_my_bonk); g_test_add_func ("/testdebugproto/DebugProto/Structs/Nesting/Properties/my_ooe", test_structs_nesting_properties_my_ooe); g_test_add_func ("/testdebugproto/DebugProto/Structs/HolyMoley/CreateAndDestroy", test_structs_holy_moley_create_and_destroy); g_test_add_func ("/testdebugproto/DebugProto/Structs/HolyMoley/Properties/big", test_structs_holy_moley_properties_big); g_test_add_func ("/testdebugproto/DebugProto/Structs/HolyMoley/Properties/contain", test_structs_holy_moley_properties_contain); g_test_add_func ("/testdebugproto/DebugProto/Structs/HolyMoley/Properties/bonks", test_structs_holy_moley_properties_bonks); g_test_add_func ("/testdebugproto/DebugProto/Structs/Empty", test_structs_empty); g_test_add_func ("/testdebugproto/DebugProto/Structs/Wrapper/CreateAndDestroy", test_structs_wrapper_create_and_destroy); g_test_add_func ("/testdebugproto/DebugProto/Structs/Wrapper/Properties/foo", test_structs_wrapper_properties_foo); g_test_add_func ("/testdebugproto/DebugProto/Services/Inherited", test_services_inherited); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/testthrifttest.c0000664000175000017500000000602415165535636021607 0ustar00buildbuild00000000000000#include #include #include #include #include "t_test_thrift_test_types.h" #include "thrift_test_handler.h" static const char TEST_ADDRESS[] = "localhost"; static const int TEST_PORT = 64444; static void test_thrift_server (void) { ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", TEST_PORT, NULL); g_object_unref (tsocket); } static void set_indicator (gpointer data, GObject *where_the_object_was) { THRIFT_UNUSED_VAR(where_the_object_was); *(gboolean *) data = TRUE; } static void test_thrift_handler (void) { GError *error; GHashTable *_return; TTestInsanity *argument; gboolean indicator; TTestXtruct *xtruct, *xtruct2; TTestNumberz numberz; TTestNumberz numberz2; TTestUserId user_id, *user_id_ptr, *user_id_ptr2; GHashTable *user_map; GPtrArray *xtructs; error = NULL; indicator = FALSE; user_map = NULL; xtructs = NULL; argument = g_object_new (T_TEST_TYPE_INSANITY, NULL); g_object_get (argument, "userMap", &user_map, "xtructs", &xtructs, NULL); numberz = T_TEST_NUMBERZ_FIVE; numberz2 = T_TEST_NUMBERZ_EIGHT; user_id_ptr = g_malloc (sizeof *user_id_ptr); *user_id_ptr = 5; user_id_ptr2 = g_malloc (sizeof *user_id_ptr); *user_id_ptr2 = 8; g_hash_table_insert (user_map, (gpointer)numberz, user_id_ptr); g_hash_table_insert (user_map, (gpointer)numberz2, user_id_ptr2); g_hash_table_unref (user_map); xtruct = g_object_new (T_TEST_TYPE_XTRUCT, "string_thing", "Hello2", "byte_thing", 2, "i32_thing", 2, "i64_thing", 2LL, NULL); xtruct2 = g_object_new (T_TEST_TYPE_XTRUCT, "string_thing", "Goodbye4", "byte_thing", 4, "i32_thing", 4, "i64_thing", 4LL, NULL); g_ptr_array_add (xtructs, xtruct2); g_ptr_array_add (xtructs, xtruct); g_ptr_array_unref (xtructs); _return = g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, (GDestroyNotify)g_hash_table_unref); g_object_weak_ref (G_OBJECT (argument), set_indicator, (gpointer) &indicator); g_assert (thrift_test_handler_test_insanity (NULL, &_return, argument, &error)); g_assert (! indicator); g_hash_table_unref (_return); g_assert (! indicator); g_object_unref (argument); g_assert (indicator); } int main(int argc, char *argv[]) { #if (!GLIB_CHECK_VERSION (2, 36, 0)) g_type_init(); #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/testthrift/Server", test_thrift_server); g_test_add_func ("/testthrift/Handler", test_thrift_handler); return g_test_run (); } thrift-0.23.0/lib/c_glib/test/Makefile.am0000664000175000017500000005521715165535636020407 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc SUBDIRS = fuzz BUILT_SOURCES = \ gen-c_glib/t_test_container_test_types.c \ gen-c_glib/t_test_container_test_types.h \ gen-c_glib/t_test_debug_proto_test_types.h \ gen-c_glib/t_test_empty_service.h \ gen-c_glib/t_test_inherited.h \ gen-c_glib/t_test_optional_required_test_types.h \ gen-c_glib/t_test_reverse_order_service.h \ gen-c_glib/t_test_second_service.h \ gen-c_glib/t_test_service_for_exception_with_a_map.h \ gen-c_glib/t_test_container_service.c \ gen-c_glib/t_test_container_service.h \ gen-c_glib/t_test_srv.h \ gen-c_glib/t_test_thrift_test.h \ gen-c_glib/t_test_thrift_test_types.h \ gen-c_glib/t_test_enum_test_types.h AM_CPPFLAGS = -I../src -I./gen-c_glib -I$(top_builddir)/lib/c_glib/src/thrift AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) \ @GCOV_CFLAGS@ AM_CXXFLAGS = $(AM_CFLAGS) AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LIBS) $(ZLIB_LIBS) @GCOV_LDFLAGS@ check_PROGRAMS = \ testserialization \ testapplicationexception \ testcontainertest \ testtransportsocket \ testtransportsslsocket \ testbinaryprotocol \ testcompactprotocol \ testbufferedtransport \ testframedtransport \ testzlibtransport \ testfdtransport \ testmemorybuffer \ teststruct \ testsimpleserver \ testdebugproto \ testoptionalrequired \ testthrifttest \ testthriftbinaryreadcheck \ testthriftcompactreadcheck \ testthriftbufferedreadcheck \ testthriftfdreadcheck \ testthriftframedreadcheck \ testthriftmemorybufferreadcheck if WITH_CPP BUILT_SOURCES += gen-cpp/ThriftTest_types.cpp check_PROGRAMS += testthrifttestclient \ testthrifttestzlibclient endif testserialization_SOURCES = testserialization.c testserialization_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la testapplicationexception_SOURCES = testapplicationexception.c testapplicationexception_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testcontainertest_SOURCES = testcontainertest.c testcontainertest_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la testtransportsocket_SOURCES = testtransportsocket.c testtransportsocket_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testtransportsslsocket_SOURCES = testtransportsslsocket.c testtransportsslsocket_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testbinaryprotocol_SOURCES = testbinaryprotocol.c testbinaryprotocol_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testcompactprotocol_SOURCES = testcompactprotocol.c testcompactprotocol_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testbufferedtransport_SOURCES = testbufferedtransport.c testbufferedtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testframedtransport_SOURCES = testframedtransport.c testframedtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testzlibtransport_SOURCES = testzlibtransport.c testzlibtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testfdtransport_SOURCES = testfdtransport.c testfdtransport_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testmemorybuffer_SOURCES = testmemorybuffer.c testmemorybuffer_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o teststruct_SOURCES = teststruct.c teststruct_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testsimpleserver_SOURCES = testsimpleserver.c testsimpleserver_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testdebugproto_SOURCES = testdebugproto.c testdebugproto_LDADD = libtestgenc.la testoptionalrequired_SOURCES = testoptionalrequired.c testoptionalrequired_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o \ libtestgenc.la testthrifttest_SOURCES = testthrifttest.c testthrifttest_LDADD = libtestgenc.la \ $(top_builddir)/test/c_glib/src/thrift_test_handler.o testthrifttest_CFLAGS = -I$(top_srcdir)/test/c_glib/src -I./gen-c_glib $(GLIB_CFLAGS) testthriftbinaryreadcheck_SOURCES = testthriftbinaryreadcheck.c testthriftbinaryreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftcompactreadcheck_SOURCES = testthriftcompactreadcheck.c testthriftcompactreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftbufferedreadcheck_SOURCES = testthriftbufferedreadcheck.c testthriftbufferedreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftfdreadcheck_SOURCES = testthriftfdreadcheck.c testthriftfdreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftframedreadcheck_SOURCES = testthriftframedreadcheck.c testthriftframedreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthriftmemorybufferreadcheck_SOURCES = testthriftmemorybufferreadcheck.c testthriftmemorybufferreadcheck_LDADD = \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \ $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o testthrifttestclient_SOURCES = testthrifttestclient.cpp testthrifttestclient_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp -I../src -I./gen-c_glib $(GLIB_CFLAGS) testthrifttestclient_LDADD = ../../cpp/.libs/libthrift.la ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la testthrifttestclient_LDFLAGS = -L../.libs -L../../cpp/.libs $(GLIB_LIBS) $(GOBJECT_LIBS) testthrifttestzlibclient_SOURCES = testthrifttestzlibclient.cpp testthrifttestzlibclient_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp -I../src -I./gen-c_glib $(GLIB_CFLAGS) testthrifttestzlibclient_LDADD = ../../cpp/.libs/libthrift.la ../../cpp/.libs/libthriftz.la ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la testthrifttestzlibclient_LDFLAGS = -L../.libs -L../../cpp/.libs $(GLIB_LIBS) $(GOBJECT_LIBS) check_LTLIBRARIES = libtestgenc.la if WITH_CPP check_LTLIBRARIES += libtestgencpp.la endif nodist_libtestgenc_la_SOURCES = \ gen-c_glib/t_test_container_test_types.c \ gen-c_glib/t_test_debug_proto_test_types.c \ gen-c_glib/t_test_enum_test_types.c \ gen-c_glib/t_test_enum_test_service.c \ gen-c_glib/t_test_empty_service.c \ gen-c_glib/t_test_inherited.c \ gen-c_glib/t_test_optional_required_test_types.c \ gen-c_glib/t_test_reverse_order_service.c \ gen-c_glib/t_test_second_service.c \ gen-c_glib/t_test_service_for_exception_with_a_map.c \ gen-c_glib/t_test_srv.c \ gen-c_glib/t_test_container_service.c \ gen-c_glib/t_test_thrift_test.c \ gen-c_glib/t_test_thrift_test_types.c \ gen-c_glib/t_test_container_test_types.h \ gen-c_glib/t_test_debug_proto_test_types.h \ gen-c_glib/t_test_enum_test_types.h \ gen-c_glib/t_test_enum_test_service.h \ gen-c_glib/t_test_empty_service.h \ gen-c_glib/t_test_inherited.h \ gen-c_glib/t_test_optional_required_test_types.h \ gen-c_glib/t_test_reverse_order_service.h \ gen-c_glib/t_test_second_service.h \ gen-c_glib/t_test_service_for_exception_with_a_map.h \ gen-c_glib/t_test_srv.h \ gen-c_glib/t_test_container_service.h \ gen-c_glib/t_test_thrift_test.h \ gen-c_glib/t_test_thrift_test_types.h libtestgenc_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la libtestgenc_la_CPPFLAGS = $(AM_CPPFLAGS) -Wno-unused-function nodist_libtestgencpp_la_SOURCES = \ gen-cpp/ThriftTest.cpp \ gen-cpp/ThriftTest_constants.cpp \ gen-cpp/ThriftTest_types.cpp \ gen-cpp/ThriftTest.h \ gen-cpp/ThriftTest_constants.h \ gen-cpp/ThriftTest_types.h libtestgencpp_la_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp gen-c_glib/t_test_container_test_types.c gen-c_glib/t_test_container_test_types.h gen-c_glib/t_test_container_service.c gen-c_glib/t_test_container_service.h: ContainerTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< gen-c_glib/t_test_debug_proto_test_types.c gen-c_glib/t_test_debug_proto_test_types.h gen-c_glib/t_test_empty_service.c gen-c_glib/t_test_empty_service.h gen-c_glib/t_test_inherited.c gen-c_glib/t_test_inherited.h gen-c_glib/t_test_reverse_order_service.c gen-c_glib/t_test_reverse_order_service.h gen-c_glib/t_test_service_for_exception_with_a_map.c gen-c_glib/t_test_service_for_exception_with_a_map.h gen-c_glib/t_test_srv.c gen-c_glib/t_test_srv.h: ../../../test/v0.16/DebugProtoTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< gen-c_glib/t_test_enum_test_types.c gen-c_glib/t_test_enum_test_types.h gen-c_glib/t_test_enum_test_service.c gen-c_glib/t_test_enum_test_service.h : ../../../test/EnumTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< gen-c_glib/t_test_optional_required_test_types.c gen-c_glib/t_test_optional_required_test_types.h: ../../../test/OptionalRequiredTest.thrift $(THRIFT) $(THRIFT) --gen c_glib $< 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/ThriftTest.thrift $(THRIFT) $(THRIFT) --gen cpp $< TESTS = \ $(check_PROGRAMS) \ $(check_SCRIPTS) # globally added to all instances of valgrind calls # VALGRIND_OPTS = --suppressions=glib.suppress VALGRIND_OPTS = # globally added to all memcheck calls VALGRIND_MEM_OPTS = --tool=memcheck \ --num-callers=10 \ ${myextravalgrindmemopts} # globally added to all leakcheck calls VALGRIND_LEAK_OPTS = --tool=memcheck \ --num-callers=10 \ --leak-check=full \ --leak-resolution=high \ ${myextravalgrindleakopts} memcheck: $(check_PROGRAMS) @for x in $(check_PROGRAMS); \ do \ $(MAKE) memcheck-$$x; \ done leakcheck: $(check_PROGRAMS) @for x in $(check_PROGRAMS); \ do \ $(MAKE) leakcheck-$$x; \ done memcheck-%: % @echo "*****************************************"; \ echo "MEMCHECK: $<"; \ echo "ARGS: ${VALGRIND_OPTS} ${VALGRIND_MEM_OPTS} ${$<_VALGRIND_MEM_OPTS}"; \ $(LIBTOOL) --mode=execute \ valgrind \ ${VALGRIND_OPTS} \ ${VALGRIND_MEM_OPTS} \ ${$<_VALGRIND_MEM_OPTS} ./$< leakcheck-%: % @echo "*****************************************"; \ echo "LEAKCHECK: $<"; \ echo "ARGS: ${VALGRIND_OPTS} ${VALGRIND_LEAK_OPTS} ${$<_VALGRIND_LEAK_OPTS}"; \ G_SLICE=always-malloc $(LIBTOOL) --mode=execute \ valgrind \ ${VALGRIND_OPTS} \ ${VALGRIND_LEAK_OPTS} \ ${$<_VALGRIND_LEAK_OPTS} ./$< clean-local: $(RM) gen-c_glib/* gen-cpp/* CLEANFILES = \ *.bb \ *.bbg \ *.da \ *.gcno \ *.gcda \ *.gcov distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ CMakeLists.txt \ ContainerTest.thrift thrift-0.23.0/lib/c_glib/test/testthrifttestclient.cpp0000664000175000017500000005176015165535636023355 0ustar00buildbuild00000000000000/* * 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. */ /* test a C client with a C++ server (that makes sense...) */ #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include #include "ThriftTest.h" #include "ThriftTest_types.h" #include #include #include #include #include using namespace apache::thrift; using namespace apache::thrift::concurrency; using namespace apache::thrift::protocol; using namespace apache::thrift::server; using namespace apache::thrift::transport; using namespace thrift::test; using std::cout; using std::fixed; using std::make_pair; using std::map; using std::set; using std::string; using std::vector; #define TEST_PORT 9980 // Extra functions required for ThriftTest_types to work namespace thrift { namespace test { bool Insanity::operator<(thrift::test::Insanity const& other) const { using apache::thrift::ThriftDebugString; return ThriftDebugString(*this) < ThriftDebugString(other); } }} class TestHandler : public ThriftTestIf { public: TestHandler() = default; void testVoid() override { cout << "[C -> C++] testVoid()" << '\n'; } void testString(string& out, const string &thing) override { cout << "[C -> C++] testString(\"" << thing << "\")" << '\n'; out = thing; } bool testBool(const bool thing) override { cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << '\n'; return thing; } int8_t testByte(const int8_t thing) override { cout << "[C -> C++] testByte(" << (int)thing << ")" << '\n'; return thing; } int32_t testI32(const int32_t thing) override { cout << "[C -> C++] testI32(" << thing << ")" << '\n'; return thing; } int64_t testI64(const int64_t thing) override { cout << "[C -> C++] testI64(" << thing << ")" << '\n'; return thing; } double testDouble(const double thing) override { cout.precision(6); cout << "[C -> C++] testDouble(" << fixed << thing << ")" << '\n'; return thing; } void testBinary(string& out, const string &thing) override { 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 << "})" << '\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 << "})" << '\n'; out = nest; } void testMap(map &out, const map &thing) override { cout << "[C -> C++] testMap({"; map::const_iterator m_iter; bool first = true; for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) { if (first) { first = false; } else { cout << ", "; } cout << m_iter->first << " => " << m_iter->second; } cout << "})" << '\n'; out = thing; } void testStringMap(map &out, const map &thing) override { cout << "[C -> C++] testStringMap({"; map::const_iterator m_iter; bool first = true; for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) { if (first) { first = false; } else { cout << ", "; } cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\""; } cout << "})" << '\n'; out = thing; } void testSet(set &out, const set &thing) override { cout << "[C -> C++] testSet({"; set::const_iterator s_iter; bool first = true; for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) { if (first) { first = false; } else { cout << ", "; } cout << *s_iter; } cout << "})" << '\n'; out = thing; } void testList(vector &out, const vector &thing) override { cout << "[C -> C++] testList({"; vector::const_iterator l_iter; bool first = true; for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) { if (first) { first = false; } else { cout << ", "; } cout << *l_iter; } cout << "})" << '\n'; out = thing; } Numberz::type testEnum(const Numberz::type thing) override { cout << "[C -> C++] testEnum(" << thing << ")" << '\n'; return thing; } UserId testTypedef(const UserId thing) override { cout << "[C -> C++] testTypedef(" << thing << ")" << '\n'; return thing; } void testMapMap(map > &mapmap, const int32_t hello) override { cout << "[C -> C++] testMapMap(" << hello << ")" << '\n'; map pos; map neg; for (int i = 1; i < 5; i++) { pos.insert(make_pair(i,i)); neg.insert(make_pair(-i,-i)); } mapmap.insert(make_pair(4, pos)); mapmap.insert(make_pair(-4, neg)); } void testInsanity(map > &insane, const Insanity &argument) override { THRIFT_UNUSED_VARIABLE (argument); cout << "[C -> C++] testInsanity()" << '\n'; Xtruct hello; hello.string_thing = "Hello2"; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = 2; Xtruct goodbye; goodbye.string_thing = "Goodbye4"; goodbye.byte_thing = 4; goodbye.i32_thing = 4; goodbye.i64_thing = 4; Insanity crazy; crazy.userMap.insert(make_pair(Numberz::EIGHT, 8)); crazy.xtructs.push_back(goodbye); Insanity looney; crazy.userMap.insert(make_pair(Numberz::FIVE, 5)); crazy.xtructs.push_back(hello); map first_map; map second_map; first_map.insert(make_pair(Numberz::TWO, crazy)); first_map.insert(make_pair(Numberz::THREE, crazy)); second_map.insert(make_pair(Numberz::SIX, looney)); insane.insert(make_pair(1, first_map)); insane.insert(make_pair(2, second_map)); cout << "return = {"; map >::const_iterator i_iter; for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) { cout << i_iter->first << " => {"; map::const_iterator i2_iter; for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) { cout << i2_iter->first << " => {"; map userMap = i2_iter->second.userMap; map::const_iterator um; cout << "{"; for (um = userMap.begin(); um != userMap.end(); ++um) { cout << um->first << " => " << um->second << ", "; } cout << "}, "; vector xtructs = i2_iter->second.xtructs; vector::const_iterator x; cout << "{"; for (x = xtructs.begin(); x != xtructs.end(); ++x) { cout << "{\"" << x->string_thing << "\", " << (int)x->byte_thing << ", " << x->i32_thing << ", " << x->i64_thing << "}, "; } cout << "}"; cout << "}, "; } cout << "}, "; } cout << "}" << '\n'; } void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map &arg3, const Numberz::type arg4, const UserId arg5) override { THRIFT_UNUSED_VARIABLE (arg3); THRIFT_UNUSED_VARIABLE (arg4); THRIFT_UNUSED_VARIABLE (arg5); cout << "[C -> C++] testMulti()" << '\n'; hello.string_thing = "Hello2"; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = (int64_t)arg2; } void testException(const std::string &arg) noexcept(false) override { cout << "[C -> C++] testException(" << arg << ")" << '\n'; if (arg.compare("Xception") == 0) { Xception e; e.errorCode = 1001; e.message = arg; throw e; } else if (arg.compare("ApplicationException") == 0) { apache::thrift::TException e; throw e; } else { Xtruct result; result.string_thing = arg; return; } } void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override { cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << '\n'; if (arg0.compare("Xception") == 0) { Xception e; e.errorCode = 1001; e.message = "This is an Xception"; throw e; } else if (arg0.compare("Xception2") == 0) { Xception2 e; e.errorCode = 2002; e.struct_thing.string_thing = "This is an Xception2"; throw e; } else { result.string_thing = arg1; return; } } void testOneway(int sleepFor) override { cout << "testOneway(" << sleepFor << "): Sleeping..." << '\n'; sleep(sleepFor); cout << "testOneway(" << sleepFor << "): done sleeping!" << '\n'; } }; // C CLIENT extern "C" { #undef THRIFT_SOCKET /* from lib/cpp */ #include "t_test_thrift_test.h" #include "t_test_thrift_test_types.h" #include #include #include static void test_thrift_client (void) { ThriftSocket *tsocket = nullptr; ThriftBinaryProtocol *protocol = nullptr; TTestThriftTestClient *client = nullptr; TTestThriftTestIf *iface = nullptr; GError *error = nullptr; gchar *string = nullptr; gint8 byte = 0; gint16 i16 = 0; gint32 i32 = 0, another_i32 = 56789; gint64 i64 = 0; double dbl = 0.0; TTestXtruct *xtruct_in, *xtruct_out; TTestXtruct2 *xtruct2_in, *xtruct2_out; GHashTable *map_in = nullptr, *map_out = nullptr; GHashTable *set_in = nullptr, *set_out = nullptr; GArray *list_in = nullptr, *list_out = nullptr; TTestNumberz enum_in, enum_out; TTestUserId user_id_in, user_id_out; GHashTable *insanity_in = nullptr; TTestXtruct *xtruct1, *xtruct2; TTestInsanity *insanity_out = nullptr; TTestXtruct *multi_in = nullptr; GHashTable *multi_map_out = nullptr; TTestXception *xception = nullptr; TTestXception2 *xception2 = nullptr; #if (!GLIB_CHECK_VERSION (2, 36, 0)) // initialize gobject g_type_init (); #endif // create a C client tsocket = (ThriftSocket *) g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", "port", TEST_PORT, nullptr); protocol = (ThriftBinaryProtocol *) g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport", tsocket, nullptr); client = (TTestThriftTestClient *) g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT, "input_protocol", protocol, "output_protocol", protocol, nullptr); iface = T_TEST_THRIFT_TEST_IF (client); // open and send thrift_transport_open (THRIFT_TRANSPORT(tsocket), nullptr); assert (t_test_thrift_test_client_test_void (iface, &error) == TRUE); assert (error == nullptr); assert (t_test_thrift_test_client_test_string (iface, &string, "test123", &error) == TRUE); assert (strcmp (string, "test123") == 0); g_free (string); assert (error == nullptr); assert (t_test_thrift_test_client_test_byte (iface, &byte, (gint8) 5, &error) == TRUE); assert (byte == 5); assert (error == nullptr); assert (t_test_thrift_test_client_test_i32 (iface, &i32, 123, &error) == TRUE); assert (i32 == 123); assert (error == nullptr); assert (t_test_thrift_test_client_test_i64 (iface, &i64, 12345, &error) == TRUE); assert (i64 == 12345); assert (error == nullptr); assert (t_test_thrift_test_client_test_double (iface, &dbl, 5.6, &error) == TRUE); assert (dbl == 5.6); assert (error == nullptr); xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); xtruct_out->byte_thing = 1; xtruct_out->__isset_byte_thing = TRUE; xtruct_out->i32_thing = 15; xtruct_out->__isset_i32_thing = TRUE; xtruct_out->i64_thing = 151; xtruct_out->__isset_i64_thing = TRUE; xtruct_out->string_thing = g_strdup ("abc123"); xtruct_out->__isset_string_thing = TRUE; xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE); assert (error == nullptr); xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr); xtruct2_out->byte_thing = 1; xtruct2_out->__isset_byte_thing = TRUE; if (xtruct2_out->struct_thing != nullptr) g_object_unref(xtruct2_out->struct_thing); xtruct2_out->struct_thing = xtruct_out; xtruct2_out->__isset_struct_thing = TRUE; xtruct2_out->i32_thing = 123; xtruct2_out->__isset_i32_thing = TRUE; xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr); assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE); assert (error == nullptr); g_object_unref (xtruct2_out); g_object_unref (xtruct2_in); g_object_unref (xtruct_in); map_out = g_hash_table_new (nullptr, nullptr); map_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (map_out, &i32, &i32); assert (t_test_thrift_test_client_test_map (iface, &map_in, map_out, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (map_out); g_hash_table_destroy (map_in); map_out = g_hash_table_new (nullptr, nullptr); map_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (map_out, g_strdup ("a"), g_strdup ("123")); g_hash_table_insert (map_out, g_strdup ("a b"), g_strdup ("with spaces ")); g_hash_table_insert (map_out, g_strdup ("same"), g_strdup ("same")); g_hash_table_insert (map_out, g_strdup ("0"), g_strdup ("numeric key")); assert (t_test_thrift_test_client_test_string_map (iface, &map_in, map_out, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (map_out); g_hash_table_destroy (map_in); set_out = g_hash_table_new (nullptr, nullptr); set_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (set_out, &i32, &i32); assert (t_test_thrift_test_client_test_set (iface, &set_in, set_out, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (set_out); g_hash_table_destroy (set_in); list_out = g_array_new(TRUE, TRUE, sizeof(gint32)); list_in = g_array_new(TRUE, TRUE, sizeof(gint32)); another_i32 = 456; g_array_append_val (list_out, i32); g_array_append_val (list_out, another_i32); assert (t_test_thrift_test_client_test_list (iface, &list_in, list_out, &error) == TRUE); assert (error == nullptr); g_array_free (list_out, TRUE); g_array_free (list_in, TRUE); enum_out = T_TEST_NUMBERZ_ONE; assert (t_test_thrift_test_client_test_enum (iface, &enum_in, enum_out, &error) == TRUE); assert (enum_in == enum_out); assert (error == nullptr); user_id_out = 12345; assert (t_test_thrift_test_client_test_typedef (iface, &user_id_in, user_id_out, &error) == TRUE); assert (user_id_in == user_id_out); assert (error == nullptr); map_in = g_hash_table_new (nullptr, nullptr); assert (t_test_thrift_test_client_test_map_map (iface, &map_in, i32, &error) == TRUE); assert (error == nullptr); g_hash_table_destroy (map_in); // insanity insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, nullptr); insanity_out->userMap = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (insanity_out->userMap, GINT_TO_POINTER (enum_out), &user_id_out); xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); xtruct1->byte_thing = 1; xtruct1->__isset_byte_thing = TRUE; xtruct1->i32_thing = 15; xtruct1->__isset_i32_thing = TRUE; xtruct1->i64_thing = 151; xtruct1->__isset_i64_thing = TRUE; xtruct1->string_thing = g_strdup ("abc123"); xtruct1->__isset_string_thing = TRUE; xtruct2 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); xtruct2->byte_thing = 1; xtruct2->__isset_byte_thing = TRUE; xtruct2->i32_thing = 15; xtruct2->__isset_i32_thing = TRUE; xtruct2->i64_thing = 151; xtruct2->__isset_i64_thing = TRUE; xtruct2->string_thing = g_strdup ("abc123"); xtruct2->__isset_string_thing = TRUE; insanity_in = g_hash_table_new (nullptr, nullptr); g_ptr_array_add (insanity_out->xtructs, xtruct1); g_ptr_array_add (insanity_out->xtructs, xtruct2); assert (t_test_thrift_test_client_test_insanity (iface, &insanity_in, insanity_out, &error) == TRUE); g_hash_table_unref (insanity_in); g_ptr_array_free (insanity_out->xtructs, TRUE); multi_map_out = g_hash_table_new (nullptr, nullptr); string = g_strdup ("abc123"); g_hash_table_insert (multi_map_out, &i16, string); multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi (iface, &multi_in, byte, i32, i64, multi_map_out, enum_out, user_id_out, &error) == TRUE); assert (multi_in->i32_thing == i32); assert (multi_in->i64_thing == i64); g_object_unref (multi_in); g_hash_table_unref (multi_map_out); g_free (string); assert (t_test_thrift_test_client_test_exception (iface, "Xception", &xception, &error) == FALSE); assert (xception->errorCode == 1001); g_error_free (error); error = nullptr; g_object_unref (xception); xception = nullptr; assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE); g_error_free (error); error = nullptr; assert (xception == nullptr); assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE); assert (error == nullptr); multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", nullptr, &xception, &xception2, &error) == FALSE); assert (xception->errorCode == 1001); assert (xception2 == nullptr); g_error_free (error); error = nullptr; g_object_unref (xception); g_object_unref (multi_in); xception = nullptr; multi_in = nullptr; multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", nullptr, &xception, &xception2, &error) == FALSE); assert (xception2->errorCode == 2002); assert (xception == nullptr); g_error_free (error); error = nullptr; g_object_unref (xception2); g_object_unref (multi_in); xception2 = nullptr; multi_in = nullptr; multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr); assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, nullptr , nullptr, &xception, &xception2, &error) == TRUE); assert (error == nullptr); g_object_unref(multi_in); multi_in = nullptr; assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE); assert (error == nullptr); /* sleep to let the oneway call go through */ sleep (5); thrift_transport_close (THRIFT_TRANSPORT(tsocket), nullptr); g_object_unref (client); g_object_unref (protocol); g_object_unref (tsocket); } } /* extern "C" */ static void bailout (int signum) { THRIFT_UNUSED_VARIABLE (signum); exit (1); } int main (void) { int status; int pid = fork (); assert (pid >= 0); if (pid == 0) /* child */ { std::shared_ptr protocolFactory(new TBinaryProtocolFactory()); std::shared_ptr testHandler(new TestHandler()); std::shared_ptr testProcessor(new ThriftTestProcessor(testHandler)); std::shared_ptr serverSocket(new TServerSocket(TEST_PORT)); std::shared_ptr transportFactory(new TBufferedTransportFactory()); TSimpleServer simpleServer(testProcessor, serverSocket, transportFactory, protocolFactory); signal (SIGALRM, bailout); alarm (60); simpleServer.serve(); } else { sleep (1); test_thrift_client (); kill (pid, SIGINT); assert (wait (&status) == pid); } return 0; } thrift-0.23.0/lib/c_glib/coding_standards.md0000664000175000017500000000032715165535636021214 0ustar00buildbuild00000000000000## C Glib Coding Standards Please follow: * [Thrift General Coding Standards](/doc/coding_standards.md) * [GNOME C Coding Style](https://help.gnome.org/users/programming-guidelines/stable/c-coding-style.html.en) thrift-0.23.0/lib/c_glib/CMakeLists.txt0000664000175000017500000001125515165535636020126 0ustar00buildbuild00000000000000# # 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. # # Find required packages find_package(GLIB REQUIRED COMPONENTS gobject) include_directories(${GLIB_INCLUDE_DIRS}) include_directories(src) # SYSLIBS contains libraries that need to be linked to all lib targets list(APPEND SYSLIBS ${GLIB_LIBRARIES} ${GLIB_GOBJECT_LIBRARIES}) # Create the thrift C glib library set(thrift_c_glib_SOURCES src/thrift/c_glib/thrift.c src/thrift/c_glib/thrift_struct.c src/thrift/c_glib/thrift_application_exception.c src/thrift/c_glib/thrift_configuration.c src/thrift/c_glib/processor/thrift_processor.c src/thrift/c_glib/processor/thrift_dispatch_processor.c src/thrift/c_glib/processor/thrift_multiplexed_processor.c src/thrift/c_glib/protocol/thrift_protocol.c src/thrift/c_glib/protocol/thrift_protocol_factory.c src/thrift/c_glib/protocol/thrift_protocol_decorator.c src/thrift/c_glib/protocol/thrift_binary_protocol.c src/thrift/c_glib/protocol/thrift_stored_message_protocol.c src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c src/thrift/c_glib/protocol/thrift_compact_protocol.c src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c src/thrift/c_glib/transport/thrift_transport.c src/thrift/c_glib/transport/thrift_transport_factory.c src/thrift/c_glib/transport/thrift_buffered_transport_factory.c src/thrift/c_glib/transport/thrift_framed_transport_factory.c src/thrift/c_glib/transport/thrift_socket.c src/thrift/c_glib/transport/thrift_server_transport.c src/thrift/c_glib/transport/thrift_server_socket.c src/thrift/c_glib/transport/thrift_buffered_transport.c src/thrift/c_glib/transport/thrift_fd_transport.c src/thrift/c_glib/transport/thrift_framed_transport.c src/thrift/c_glib/transport/thrift_memory_buffer.c src/thrift/c_glib/server/thrift_server.c src/thrift/c_glib/server/thrift_simple_server.c ) set(thrift_c_glib_zlib_SOURCES src/thrift/c_glib/thrift.c src/thrift/c_glib/thrift_struct.c src/thrift/c_glib/thrift_application_exception.c src/thrift/c_glib/thrift_configuration.c src/thrift/c_glib/transport/thrift_transport.c src/thrift/c_glib/transport/thrift_transport_factory.c src/thrift/c_glib/transport/thrift_zlib_transport.c src/thrift/c_glib/transport/thrift_zlib_transport_factory.c ) # If OpenSSL is not found just ignore the OpenSSL stuff if(OPENSSL_FOUND AND WITH_OPENSSL) list(APPEND thrift_c_glib_SOURCES src/thrift/c_glib/transport/thrift_ssl_socket.c ) if(TARGET OpenSSL::SSL OR TARGET OpenSSL::Crypto) if(TARGET OpenSSL::SSL) list(APPEND SYSLIBS OpenSSL::SSL) endif() if(TARGET OpenSSL::Crypto) list(APPEND SYSLIBS OpenSSL::Crypto) endif() else() include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") list(APPEND SYSLIBS "${OPENSSL_LIBRARIES}") endif() endif() # Contains the thrift specific ADD_LIBRARY_THRIFT macro include(ThriftMacros) ADD_LIBRARY_THRIFT(thrift_c_glib ${thrift_c_glib_SOURCES}) target_link_libraries(thrift_c_glib PUBLIC ${SYSLIBS}) # If Zlib is not found just ignore the Zlib stuff if(WITH_ZLIB) ADD_LIBRARY_THRIFT(thrift_c_glib_zlib ${thrift_c_glib_zlib_SOURCES}) target_link_libraries(thrift_c_glib_zlib PUBLIC ${SYSLIBS}) target_link_libraries(thrift_c_glib_zlib PUBLIC thrift_c_glib) if(TARGET ZLIB::ZLIB) target_link_libraries(thrift_c_glib_zlib PUBLIC ZLIB::ZLIB) else() include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS}) target_link_libraries(thrift_c_glib_zlib PUBLIC ${ZLIB_LIBRARIES}) endif() endif() # Install the headers install(DIRECTORY "src/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}" FILES_MATCHING PATTERN "*.h") # Copy config.h file install(DIRECTORY "${CMAKE_BINARY_DIR}/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}" FILES_MATCHING PATTERN "*.h") if(BUILD_TESTING) add_subdirectory(test) endif() thrift-0.23.0/lib/c_glib/README.md0000664000175000017500000000304515165535636016643 0ustar00buildbuild00000000000000Thrift C Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Thrift with C =================== The Thrift C libraries are built using the GNU tools. Follow the instructions in the top-level README in order to generate the Makefiles. Dependencies ============ GLib http://www.gtk.org/ Breaking Changes ================ 0.12.0 ------ The compiler's handling of namespaces when generating the name of types, functions and header files has been improved. This means code written to use classes generated by previous versions of the compiler may need to be updated to reflect the proper convention for class names, which is - A lowercase, [snake-case](https://en.wikipedia.org/wiki/Snake_case) representation of the class' namespace, followed by - An underscore and - A lowercase, snake-case representation of the class' name. thrift-0.23.0/lib/c_glib/Makefile.in0000644000175000017500000035744315170007166017431 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/c_glib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(include_processor_HEADERS) \ $(include_protocol_HEADERS) $(include_server_HEADERS) \ $(include_thrift_HEADERS) $(include_transport_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = thrift_c_glib.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(include_processordir)" \ "$(DESTDIR)$(include_protocoldir)" \ "$(DESTDIR)$(include_serverdir)" \ "$(DESTDIR)$(include_thriftdir)" \ "$(DESTDIR)$(include_transportdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libthrift_c_glib_la_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp am_libthrift_c_glib_la_OBJECTS = \ src/thrift/c_glib/libthrift_c_glib_la-thrift.lo \ src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.lo \ src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.lo \ src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.lo \ src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.lo \ src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_dispatch_processor.lo \ src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_multiplexed_processor.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_decorator.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_stored_message_protocol.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_multiplexed_protocol.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol.lo \ src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol_factory.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport_factory.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport_factory.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport_factory.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_ssl_socket.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport.lo \ src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_memory_buffer.lo \ src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.lo \ src/thrift/c_glib/server/libthrift_c_glib_la-thrift_simple_server.lo libthrift_c_glib_la_OBJECTS = $(am_libthrift_c_glib_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libthrift_c_glib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) \ $(libthrift_c_glib_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = \ src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift.Plo \ src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_application_exception.Plo \ src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_configuration.Plo \ src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_struct.Plo \ src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_dispatch_processor.Plo \ src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_processor.Plo \ src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_processor.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol_factory.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol_factory.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_protocol.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_decorator.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_factory.Plo \ src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_stored_message_protocol.Plo \ src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_server.Plo \ src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_simple_server.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport_factory.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_fd_transport.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport_factory.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_memory_buffer.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_socket.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_transport.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_socket.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_ssl_socket.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport_factory.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport.Plo \ src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport_factory.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libthrift_c_glib_la_SOURCES) DIST_SOURCES = $(libthrift_c_glib_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(pkgconfig_DATA) HEADERS = $(include_processor_HEADERS) $(include_protocol_HEADERS) \ $(include_server_HEADERS) $(include_thrift_HEADERS) \ $(include_transport_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/thrift_c_glib.pc.in \ $(top_srcdir)/depcomp README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # 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. # AUTOMAKE_OPTIONS = serial-tests nostdinc SUBDIRS = . test pkgconfigdir = $(libdir)/pkgconfig lib_LTLIBRARIES = libthrift_c_glib.la pkgconfig_DATA = thrift_c_glib.pc AM_CPPFLAGS = -Isrc -I src/thrift/c_glib AM_CFLAGS = -Wall -Wextra -pedantic # Define the source files for the module libthrift_c_glib_la_SOURCES = src/thrift/c_glib/thrift.c \ src/thrift/c_glib/thrift_struct.c \ src/thrift/c_glib/thrift_application_exception.c \ src/thrift/c_glib/thrift_configuration.c \ src/thrift/c_glib/processor/thrift_processor.c \ src/thrift/c_glib/processor/thrift_dispatch_processor.c \ src/thrift/c_glib/processor/thrift_multiplexed_processor.c \ src/thrift/c_glib/protocol/thrift_protocol.c \ src/thrift/c_glib/protocol/thrift_protocol_decorator.c \ src/thrift/c_glib/protocol/thrift_protocol_factory.c \ src/thrift/c_glib/protocol/thrift_binary_protocol.c \ src/thrift/c_glib/protocol/thrift_stored_message_protocol.c \ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c \ src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c \ src/thrift/c_glib/protocol/thrift_compact_protocol.c \ src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c \ src/thrift/c_glib/transport/thrift_transport.c \ src/thrift/c_glib/transport/thrift_transport_factory.c \ src/thrift/c_glib/transport/thrift_buffered_transport_factory.c \ src/thrift/c_glib/transport/thrift_framed_transport_factory.c \ src/thrift/c_glib/transport/thrift_zlib_transport_factory.c \ src/thrift/c_glib/transport/thrift_socket.c \ src/thrift/c_glib/transport/thrift_ssl_socket.c \ src/thrift/c_glib/transport/thrift_server_transport.c \ src/thrift/c_glib/transport/thrift_server_socket.c \ src/thrift/c_glib/transport/thrift_buffered_transport.c \ src/thrift/c_glib/transport/thrift_fd_transport.c \ src/thrift/c_glib/transport/thrift_framed_transport.c \ src/thrift/c_glib/transport/thrift_zlib_transport.c \ src/thrift/c_glib/transport/thrift_memory_buffer.c \ src/thrift/c_glib/server/thrift_server.c \ src/thrift/c_glib/server/thrift_simple_server.c libthrift_c_glib_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) -I$(top_builddir)/lib/c_glib/src/thrift libthrift_c_glib_la_LDFLAGS = $(AM_LDFLAGS) $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) $(ZLIB_LDFLAGS) $(ZLIB_LIBS) include_thriftdir = $(includedir)/thrift/c_glib include_thrift_HEADERS = \ $(top_builddir)/config.h \ src/thrift/c_glib/thrift.h \ src/thrift/c_glib/thrift_application_exception.h \ src/thrift/c_glib/thrift_struct.h \ src/thrift/c_glib/thrift_configuration.h include_protocoldir = $(include_thriftdir)/protocol include_protocol_HEADERS = src/thrift/c_glib/protocol/thrift_protocol.h \ src/thrift/c_glib/protocol/thrift_protocol_decorator.h \ src/thrift/c_glib/protocol/thrift_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_binary_protocol.h \ src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_compact_protocol.h \ src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h \ src/thrift/c_glib/protocol/thrift_stored_message_protocol.h include_transportdir = $(include_thriftdir)/transport include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \ src/thrift/c_glib/transport/thrift_fd_transport.h \ src/thrift/c_glib/transport/thrift_framed_transport.h \ src/thrift/c_glib/transport/thrift_zlib_transport.h \ src/thrift/c_glib/transport/thrift_memory_buffer.h \ src/thrift/c_glib/transport/thrift_server_socket.h \ src/thrift/c_glib/transport/thrift_server_transport.h \ src/thrift/c_glib/transport/thrift_socket.h \ src/thrift/c_glib/transport/thrift_platform_socket.h \ src/thrift/c_glib/transport/thrift_ssl_socket.h \ src/thrift/c_glib/transport/thrift_transport.h \ src/thrift/c_glib/transport/thrift_transport_factory.h \ src/thrift/c_glib/transport/thrift_buffered_transport_factory.h \ src/thrift/c_glib/transport/thrift_framed_transport_factory.h \ src/thrift/c_glib/transport/thrift_zlib_transport_factory.h include_serverdir = $(include_thriftdir)/server include_server_HEADERS = src/thrift/c_glib/server/thrift_server.h \ src/thrift/c_glib/server/thrift_simple_server.h include_processordir = $(include_thriftdir)/processor include_processor_HEADERS = src/thrift/c_glib/processor/thrift_processor.h \ src/thrift/c_glib/processor/thrift_dispatch_processor.h \ src/thrift/c_glib/processor/thrift_multiplexed_processor.h EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ README.md \ test/glib.suppress \ thrift_c_glib.pc.in CLEANFILES = \ *.gcno \ *.gcda all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/c_glib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/c_glib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): thrift_c_glib.pc: $(top_builddir)/config.status $(srcdir)/thrift_c_glib.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } src/thrift/c_glib/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib @: > src/thrift/c_glib/$(am__dirstamp) src/thrift/c_glib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/$(DEPDIR) @: > src/thrift/c_glib/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/libthrift_c_glib_la-thrift.lo: \ src/thrift/c_glib/$(am__dirstamp) \ src/thrift/c_glib/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.lo: \ src/thrift/c_glib/$(am__dirstamp) \ src/thrift/c_glib/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.lo: \ src/thrift/c_glib/$(am__dirstamp) \ src/thrift/c_glib/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.lo: \ src/thrift/c_glib/$(am__dirstamp) \ src/thrift/c_glib/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/processor/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/processor @: > src/thrift/c_glib/processor/$(am__dirstamp) src/thrift/c_glib/processor/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/processor/$(DEPDIR) @: > src/thrift/c_glib/processor/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.lo: \ src/thrift/c_glib/processor/$(am__dirstamp) \ src/thrift/c_glib/processor/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_dispatch_processor.lo: \ src/thrift/c_glib/processor/$(am__dirstamp) \ src/thrift/c_glib/processor/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_multiplexed_processor.lo: \ src/thrift/c_glib/processor/$(am__dirstamp) \ src/thrift/c_glib/processor/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/protocol @: > src/thrift/c_glib/protocol/$(am__dirstamp) src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/protocol/$(DEPDIR) @: > src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_decorator.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_stored_message_protocol.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_multiplexed_protocol.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol_factory.lo: \ src/thrift/c_glib/protocol/$(am__dirstamp) \ src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/transport @: > src/thrift/c_glib/transport/$(am__dirstamp) src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/transport/$(DEPDIR) @: > src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport_factory.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport_factory.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport_factory.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_ssl_socket.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_memory_buffer.lo: \ src/thrift/c_glib/transport/$(am__dirstamp) \ src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/server/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/server @: > src/thrift/c_glib/server/$(am__dirstamp) src/thrift/c_glib/server/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/c_glib/server/$(DEPDIR) @: > src/thrift/c_glib/server/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.lo: \ src/thrift/c_glib/server/$(am__dirstamp) \ src/thrift/c_glib/server/$(DEPDIR)/$(am__dirstamp) src/thrift/c_glib/server/libthrift_c_glib_la-thrift_simple_server.lo: \ src/thrift/c_glib/server/$(am__dirstamp) \ src/thrift/c_glib/server/$(DEPDIR)/$(am__dirstamp) libthrift_c_glib.la: $(libthrift_c_glib_la_OBJECTS) $(libthrift_c_glib_la_DEPENDENCIES) $(EXTRA_libthrift_c_glib_la_DEPENDENCIES) $(AM_V_CCLD)$(libthrift_c_glib_la_LINK) -rpath $(libdir) $(libthrift_c_glib_la_OBJECTS) $(libthrift_c_glib_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f src/thrift/c_glib/*.$(OBJEXT) -rm -f src/thrift/c_glib/*.lo -rm -f src/thrift/c_glib/processor/*.$(OBJEXT) -rm -f src/thrift/c_glib/processor/*.lo -rm -f src/thrift/c_glib/protocol/*.$(OBJEXT) -rm -f src/thrift/c_glib/protocol/*.lo -rm -f src/thrift/c_glib/server/*.$(OBJEXT) -rm -f src/thrift/c_glib/server/*.lo -rm -f src/thrift/c_glib/transport/*.$(OBJEXT) -rm -f src/thrift/c_glib/transport/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_application_exception.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_configuration.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_struct.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_dispatch_processor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_processor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_processor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol_factory.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol_factory.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_protocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_decorator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_factory.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_stored_message_protocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_server.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_simple_server.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport_factory.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_fd_transport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport_factory.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_memory_buffer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_socket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_transport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_socket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_ssl_socket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport_factory.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport_factory.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< src/thrift/c_glib/libthrift_c_glib_la-thrift.lo: src/thrift/c_glib/thrift.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/libthrift_c_glib_la-thrift.lo -MD -MP -MF src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift.Tpo -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift.lo `test -f 'src/thrift/c_glib/thrift.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift.Tpo src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/thrift.c' object='src/thrift/c_glib/libthrift_c_glib_la-thrift.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift.lo `test -f 'src/thrift/c_glib/thrift.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift.c src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.lo: src/thrift/c_glib/thrift_struct.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.lo -MD -MP -MF src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_struct.Tpo -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.lo `test -f 'src/thrift/c_glib/thrift_struct.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift_struct.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_struct.Tpo src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_struct.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/thrift_struct.c' object='src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift_struct.lo `test -f 'src/thrift/c_glib/thrift_struct.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift_struct.c src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.lo: src/thrift/c_glib/thrift_application_exception.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.lo -MD -MP -MF src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_application_exception.Tpo -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.lo `test -f 'src/thrift/c_glib/thrift_application_exception.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift_application_exception.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_application_exception.Tpo src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_application_exception.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/thrift_application_exception.c' object='src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift_application_exception.lo `test -f 'src/thrift/c_glib/thrift_application_exception.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift_application_exception.c src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.lo: src/thrift/c_glib/thrift_configuration.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.lo -MD -MP -MF src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_configuration.Tpo -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.lo `test -f 'src/thrift/c_glib/thrift_configuration.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift_configuration.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_configuration.Tpo src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_configuration.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/thrift_configuration.c' object='src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.lo `test -f 'src/thrift/c_glib/thrift_configuration.c' || echo '$(srcdir)/'`src/thrift/c_glib/thrift_configuration.c src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.lo: src/thrift/c_glib/processor/thrift_processor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.lo -MD -MP -MF src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_processor.Tpo -c -o src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.lo `test -f 'src/thrift/c_glib/processor/thrift_processor.c' || echo '$(srcdir)/'`src/thrift/c_glib/processor/thrift_processor.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_processor.Tpo src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_processor.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/processor/thrift_processor.c' object='src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_processor.lo `test -f 'src/thrift/c_glib/processor/thrift_processor.c' || echo '$(srcdir)/'`src/thrift/c_glib/processor/thrift_processor.c src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_dispatch_processor.lo: src/thrift/c_glib/processor/thrift_dispatch_processor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_dispatch_processor.lo -MD -MP -MF src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_dispatch_processor.Tpo -c -o src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_dispatch_processor.lo `test -f 'src/thrift/c_glib/processor/thrift_dispatch_processor.c' || echo '$(srcdir)/'`src/thrift/c_glib/processor/thrift_dispatch_processor.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_dispatch_processor.Tpo src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_dispatch_processor.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/processor/thrift_dispatch_processor.c' object='src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_dispatch_processor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_dispatch_processor.lo `test -f 'src/thrift/c_glib/processor/thrift_dispatch_processor.c' || echo '$(srcdir)/'`src/thrift/c_glib/processor/thrift_dispatch_processor.c src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_multiplexed_processor.lo: src/thrift/c_glib/processor/thrift_multiplexed_processor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_multiplexed_processor.lo -MD -MP -MF src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_processor.Tpo -c -o src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_multiplexed_processor.lo `test -f 'src/thrift/c_glib/processor/thrift_multiplexed_processor.c' || echo '$(srcdir)/'`src/thrift/c_glib/processor/thrift_multiplexed_processor.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_processor.Tpo src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_processor.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/processor/thrift_multiplexed_processor.c' object='src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_multiplexed_processor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/processor/libthrift_c_glib_la-thrift_multiplexed_processor.lo `test -f 'src/thrift/c_glib/processor/thrift_multiplexed_processor.c' || echo '$(srcdir)/'`src/thrift/c_glib/processor/thrift_multiplexed_processor.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.lo: src/thrift/c_glib/protocol/thrift_protocol.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_protocol.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_protocol.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_protocol.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_decorator.lo: src/thrift/c_glib/protocol/thrift_protocol_decorator.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_decorator.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_decorator.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_decorator.lo `test -f 'src/thrift/c_glib/protocol/thrift_protocol_decorator.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_protocol_decorator.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_decorator.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_decorator.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_protocol_decorator.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_decorator.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_decorator.lo `test -f 'src/thrift/c_glib/protocol/thrift_protocol_decorator.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_protocol_decorator.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.lo: src/thrift/c_glib/protocol/thrift_protocol_factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_factory.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.lo `test -f 'src/thrift/c_glib/protocol/thrift_protocol_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_protocol_factory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_factory.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_factory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_protocol_factory.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol_factory.lo `test -f 'src/thrift/c_glib/protocol/thrift_protocol_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_protocol_factory.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.lo: src/thrift/c_glib/protocol/thrift_binary_protocol.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_binary_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_binary_protocol.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_binary_protocol.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_binary_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_binary_protocol.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_stored_message_protocol.lo: src/thrift/c_glib/protocol/thrift_stored_message_protocol.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_stored_message_protocol.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_stored_message_protocol.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_stored_message_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_stored_message_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_stored_message_protocol.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_stored_message_protocol.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_stored_message_protocol.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_stored_message_protocol.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_stored_message_protocol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_stored_message_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_stored_message_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_stored_message_protocol.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_multiplexed_protocol.lo: src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_multiplexed_protocol.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_protocol.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_multiplexed_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_protocol.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_protocol.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_multiplexed_protocol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_multiplexed_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.lo: src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol_factory.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.lo `test -f 'src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol_factory.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol_factory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_binary_protocol_factory.lo `test -f 'src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol.lo: src/thrift/c_glib/protocol/thrift_compact_protocol.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_compact_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_compact_protocol.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_compact_protocol.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol.lo `test -f 'src/thrift/c_glib/protocol/thrift_compact_protocol.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_compact_protocol.c src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol_factory.lo: src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol_factory.lo -MD -MP -MF src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol_factory.Tpo -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol_factory.lo `test -f 'src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol_factory.Tpo src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol_factory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c' object='src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_compact_protocol_factory.lo `test -f 'src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.lo: src/thrift/c_glib/transport/thrift_transport.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_transport.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_transport.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_transport.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.lo: src/thrift/c_glib/transport/thrift_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport_factory.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport_factory.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport_factory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_transport_factory.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_transport_factory.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport_factory.lo: src/thrift/c_glib/transport/thrift_buffered_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport_factory.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport_factory.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_buffered_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_buffered_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport_factory.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport_factory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_buffered_transport_factory.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_buffered_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_buffered_transport_factory.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport_factory.lo: src/thrift/c_glib/transport/thrift_framed_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport_factory.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport_factory.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_framed_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_framed_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport_factory.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport_factory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_framed_transport_factory.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_framed_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_framed_transport_factory.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport_factory.lo: src/thrift/c_glib/transport/thrift_zlib_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport_factory.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport_factory.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_zlib_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_zlib_transport_factory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport_factory.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport_factory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_zlib_transport_factory.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport_factory.lo `test -f 'src/thrift/c_glib/transport/thrift_zlib_transport_factory.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_zlib_transport_factory.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.lo: src/thrift/c_glib/transport/thrift_socket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_socket.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.lo `test -f 'src/thrift/c_glib/transport/thrift_socket.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_socket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_socket.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_socket.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_socket.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.lo `test -f 'src/thrift/c_glib/transport/thrift_socket.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_socket.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_ssl_socket.lo: src/thrift/c_glib/transport/thrift_ssl_socket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_ssl_socket.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_ssl_socket.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_ssl_socket.lo `test -f 'src/thrift/c_glib/transport/thrift_ssl_socket.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_ssl_socket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_ssl_socket.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_ssl_socket.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_ssl_socket.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_ssl_socket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_ssl_socket.lo `test -f 'src/thrift/c_glib/transport/thrift_ssl_socket.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_ssl_socket.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.lo: src/thrift/c_glib/transport/thrift_server_transport.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_transport.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_server_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_server_transport.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_transport.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_transport.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_server_transport.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_server_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_server_transport.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.lo: src/thrift/c_glib/transport/thrift_server_socket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_socket.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.lo `test -f 'src/thrift/c_glib/transport/thrift_server_socket.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_server_socket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_socket.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_socket.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_server_socket.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.lo `test -f 'src/thrift/c_glib/transport/thrift_server_socket.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_server_socket.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.lo: src/thrift/c_glib/transport/thrift_buffered_transport.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_buffered_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_buffered_transport.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_buffered_transport.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_buffered_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_buffered_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_buffered_transport.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.lo: src/thrift/c_glib/transport/thrift_fd_transport.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_fd_transport.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_fd_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_fd_transport.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_fd_transport.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_fd_transport.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_fd_transport.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_fd_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_fd_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_fd_transport.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.lo: src/thrift/c_glib/transport/thrift_framed_transport.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_framed_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_framed_transport.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_framed_transport.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_framed_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_framed_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_framed_transport.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport.lo: src/thrift/c_glib/transport/thrift_zlib_transport.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_zlib_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_zlib_transport.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_zlib_transport.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_zlib_transport.lo `test -f 'src/thrift/c_glib/transport/thrift_zlib_transport.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_zlib_transport.c src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_memory_buffer.lo: src/thrift/c_glib/transport/thrift_memory_buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_memory_buffer.lo -MD -MP -MF src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_memory_buffer.Tpo -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_memory_buffer.lo `test -f 'src/thrift/c_glib/transport/thrift_memory_buffer.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_memory_buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_memory_buffer.Tpo src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_memory_buffer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/transport/thrift_memory_buffer.c' object='src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_memory_buffer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_memory_buffer.lo `test -f 'src/thrift/c_glib/transport/thrift_memory_buffer.c' || echo '$(srcdir)/'`src/thrift/c_glib/transport/thrift_memory_buffer.c src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.lo: src/thrift/c_glib/server/thrift_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.lo -MD -MP -MF src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_server.Tpo -c -o src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.lo `test -f 'src/thrift/c_glib/server/thrift_server.c' || echo '$(srcdir)/'`src/thrift/c_glib/server/thrift_server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_server.Tpo src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_server.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/server/thrift_server.c' object='src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/server/libthrift_c_glib_la-thrift_server.lo `test -f 'src/thrift/c_glib/server/thrift_server.c' || echo '$(srcdir)/'`src/thrift/c_glib/server/thrift_server.c src/thrift/c_glib/server/libthrift_c_glib_la-thrift_simple_server.lo: src/thrift/c_glib/server/thrift_simple_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -MT src/thrift/c_glib/server/libthrift_c_glib_la-thrift_simple_server.lo -MD -MP -MF src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_simple_server.Tpo -c -o src/thrift/c_glib/server/libthrift_c_glib_la-thrift_simple_server.lo `test -f 'src/thrift/c_glib/server/thrift_simple_server.c' || echo '$(srcdir)/'`src/thrift/c_glib/server/thrift_simple_server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_simple_server.Tpo src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_simple_server.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/thrift/c_glib/server/thrift_simple_server.c' object='src/thrift/c_glib/server/libthrift_c_glib_la-thrift_simple_server.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libthrift_c_glib_la_CFLAGS) $(CFLAGS) -c -o src/thrift/c_glib/server/libthrift_c_glib_la-thrift_simple_server.lo `test -f 'src/thrift/c_glib/server/thrift_simple_server.c' || echo '$(srcdir)/'`src/thrift/c_glib/server/thrift_simple_server.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf src/thrift/c_glib/.libs src/thrift/c_glib/_libs -rm -rf src/thrift/c_glib/processor/.libs src/thrift/c_glib/processor/_libs -rm -rf src/thrift/c_glib/protocol/.libs src/thrift/c_glib/protocol/_libs -rm -rf src/thrift/c_glib/server/.libs src/thrift/c_glib/server/_libs -rm -rf src/thrift/c_glib/transport/.libs src/thrift/c_glib/transport/_libs install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-include_processorHEADERS: $(include_processor_HEADERS) @$(NORMAL_INSTALL) @list='$(include_processor_HEADERS)'; test -n "$(include_processordir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_processordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_processordir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_processordir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_processordir)" || exit $$?; \ done uninstall-include_processorHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_processor_HEADERS)'; test -n "$(include_processordir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_processordir)'; $(am__uninstall_files_from_dir) install-include_protocolHEADERS: $(include_protocol_HEADERS) @$(NORMAL_INSTALL) @list='$(include_protocol_HEADERS)'; test -n "$(include_protocoldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_protocoldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_protocoldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_protocoldir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_protocoldir)" || exit $$?; \ done uninstall-include_protocolHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_protocol_HEADERS)'; test -n "$(include_protocoldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_protocoldir)'; $(am__uninstall_files_from_dir) install-include_serverHEADERS: $(include_server_HEADERS) @$(NORMAL_INSTALL) @list='$(include_server_HEADERS)'; test -n "$(include_serverdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_serverdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_serverdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_serverdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_serverdir)" || exit $$?; \ done uninstall-include_serverHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_server_HEADERS)'; test -n "$(include_serverdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_serverdir)'; $(am__uninstall_files_from_dir) install-include_thriftHEADERS: $(include_thrift_HEADERS) @$(NORMAL_INSTALL) @list='$(include_thrift_HEADERS)'; test -n "$(include_thriftdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_thriftdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_thriftdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_thriftdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_thriftdir)" || exit $$?; \ done uninstall-include_thriftHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_thrift_HEADERS)'; test -n "$(include_thriftdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_thriftdir)'; $(am__uninstall_files_from_dir) install-include_transportHEADERS: $(include_transport_HEADERS) @$(NORMAL_INSTALL) @list='$(include_transport_HEADERS)'; test -n "$(include_transportdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_transportdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_transportdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_transportdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_transportdir)" || exit $$?; \ done uninstall-include_transportHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_transport_HEADERS)'; test -n "$(include_transportdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_transportdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(include_processordir)" "$(DESTDIR)$(include_protocoldir)" "$(DESTDIR)$(include_serverdir)" "$(DESTDIR)$(include_thriftdir)" "$(DESTDIR)$(include_transportdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f src/thrift/c_glib/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/c_glib/$(am__dirstamp) -rm -f src/thrift/c_glib/processor/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/c_glib/processor/$(am__dirstamp) -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/c_glib/protocol/$(am__dirstamp) -rm -f src/thrift/c_glib/server/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/c_glib/server/$(am__dirstamp) -rm -f src/thrift/c_glib/transport/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/c_glib/transport/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift.Plo -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_application_exception.Plo -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_configuration.Plo -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_struct.Plo -rm -f src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_dispatch_processor.Plo -rm -f src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_processor.Plo -rm -f src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_processor.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol_factory.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol_factory.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_decorator.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_factory.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_stored_message_protocol.Plo -rm -f src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_server.Plo -rm -f src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_simple_server.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport_factory.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_fd_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport_factory.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_memory_buffer.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_socket.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_socket.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_ssl_socket.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport_factory.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport_factory.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-include_processorHEADERS \ install-include_protocolHEADERS install-include_serverHEADERS \ install-include_thriftHEADERS install-include_transportHEADERS \ install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift.Plo -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_application_exception.Plo -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_configuration.Plo -rm -f src/thrift/c_glib/$(DEPDIR)/libthrift_c_glib_la-thrift_struct.Plo -rm -f src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_dispatch_processor.Plo -rm -f src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_processor.Plo -rm -f src/thrift/c_glib/processor/$(DEPDIR)/libthrift_c_glib_la-thrift_processor.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_binary_protocol_factory.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_compact_protocol_factory.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_multiplexed_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_decorator.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_protocol_factory.Plo -rm -f src/thrift/c_glib/protocol/$(DEPDIR)/libthrift_c_glib_la-thrift_stored_message_protocol.Plo -rm -f src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_server.Plo -rm -f src/thrift/c_glib/server/$(DEPDIR)/libthrift_c_glib_la-thrift_simple_server.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_buffered_transport_factory.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_fd_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_framed_transport_factory.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_memory_buffer.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_socket.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_server_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_socket.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_ssl_socket.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_transport_factory.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport.Plo -rm -f src/thrift/c_glib/transport/$(DEPDIR)/libthrift_c_glib_la-thrift_zlib_transport_factory.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: uninstall-include_processorHEADERS \ uninstall-include_protocolHEADERS \ uninstall-include_serverHEADERS \ uninstall-include_thriftHEADERS \ uninstall-include_transportHEADERS uninstall-libLTLIBRARIES \ uninstall-pkgconfigDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am \ install-include_processorHEADERS \ install-include_protocolHEADERS install-include_serverHEADERS \ install-include_thriftHEADERS install-include_transportHEADERS \ install-info install-info-am install-libLTLIBRARIES \ install-man install-pdf install-pdf-am install-pkgconfigDATA \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am \ uninstall-include_processorHEADERS \ uninstall-include_protocolHEADERS \ uninstall-include_serverHEADERS \ uninstall-include_thriftHEADERS \ uninstall-include_transportHEADERS uninstall-libLTLIBRARIES \ uninstall-pkgconfigDATA .PRECIOUS: Makefile distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/c_glib/Makefile.am0000664000175000017500000001622115165535636017420 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = serial-tests nostdinc SUBDIRS = . test pkgconfigdir = $(libdir)/pkgconfig lib_LTLIBRARIES = libthrift_c_glib.la pkgconfig_DATA = thrift_c_glib.pc AM_CPPFLAGS = -Isrc -I src/thrift/c_glib AM_CFLAGS = -Wall -Wextra -pedantic # Define the source files for the module libthrift_c_glib_la_SOURCES = src/thrift/c_glib/thrift.c \ src/thrift/c_glib/thrift_struct.c \ src/thrift/c_glib/thrift_application_exception.c \ src/thrift/c_glib/thrift_configuration.c \ src/thrift/c_glib/processor/thrift_processor.c \ src/thrift/c_glib/processor/thrift_dispatch_processor.c \ src/thrift/c_glib/processor/thrift_multiplexed_processor.c \ src/thrift/c_glib/protocol/thrift_protocol.c \ src/thrift/c_glib/protocol/thrift_protocol_decorator.c \ src/thrift/c_glib/protocol/thrift_protocol_factory.c \ src/thrift/c_glib/protocol/thrift_binary_protocol.c \ src/thrift/c_glib/protocol/thrift_stored_message_protocol.c \ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c \ src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c \ src/thrift/c_glib/protocol/thrift_compact_protocol.c \ src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c \ src/thrift/c_glib/transport/thrift_transport.c \ src/thrift/c_glib/transport/thrift_transport_factory.c \ src/thrift/c_glib/transport/thrift_buffered_transport_factory.c \ src/thrift/c_glib/transport/thrift_framed_transport_factory.c \ src/thrift/c_glib/transport/thrift_zlib_transport_factory.c \ src/thrift/c_glib/transport/thrift_socket.c \ src/thrift/c_glib/transport/thrift_ssl_socket.c \ src/thrift/c_glib/transport/thrift_server_transport.c \ src/thrift/c_glib/transport/thrift_server_socket.c \ src/thrift/c_glib/transport/thrift_buffered_transport.c \ src/thrift/c_glib/transport/thrift_fd_transport.c \ src/thrift/c_glib/transport/thrift_framed_transport.c \ src/thrift/c_glib/transport/thrift_zlib_transport.c \ src/thrift/c_glib/transport/thrift_memory_buffer.c \ src/thrift/c_glib/server/thrift_server.c \ src/thrift/c_glib/server/thrift_simple_server.c libthrift_c_glib_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) -I$(top_builddir)/lib/c_glib/src/thrift libthrift_c_glib_la_LDFLAGS = $(AM_LDFLAGS) $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) $(ZLIB_LDFLAGS) $(ZLIB_LIBS) include_thriftdir = $(includedir)/thrift/c_glib include_thrift_HEADERS = \ $(top_builddir)/config.h \ src/thrift/c_glib/thrift.h \ src/thrift/c_glib/thrift_application_exception.h \ src/thrift/c_glib/thrift_struct.h \ src/thrift/c_glib/thrift_configuration.h include_protocoldir = $(include_thriftdir)/protocol include_protocol_HEADERS = src/thrift/c_glib/protocol/thrift_protocol.h \ src/thrift/c_glib/protocol/thrift_protocol_decorator.h \ src/thrift/c_glib/protocol/thrift_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_binary_protocol.h \ src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_compact_protocol.h \ src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h \ src/thrift/c_glib/protocol/thrift_stored_message_protocol.h include_transportdir = $(include_thriftdir)/transport include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \ src/thrift/c_glib/transport/thrift_fd_transport.h \ src/thrift/c_glib/transport/thrift_framed_transport.h \ src/thrift/c_glib/transport/thrift_zlib_transport.h \ src/thrift/c_glib/transport/thrift_memory_buffer.h \ src/thrift/c_glib/transport/thrift_server_socket.h \ src/thrift/c_glib/transport/thrift_server_transport.h \ src/thrift/c_glib/transport/thrift_socket.h \ src/thrift/c_glib/transport/thrift_platform_socket.h \ src/thrift/c_glib/transport/thrift_ssl_socket.h \ src/thrift/c_glib/transport/thrift_transport.h \ src/thrift/c_glib/transport/thrift_transport_factory.h \ src/thrift/c_glib/transport/thrift_buffered_transport_factory.h \ src/thrift/c_glib/transport/thrift_framed_transport_factory.h \ src/thrift/c_glib/transport/thrift_zlib_transport_factory.h include_serverdir = $(include_thriftdir)/server include_server_HEADERS = src/thrift/c_glib/server/thrift_server.h \ src/thrift/c_glib/server/thrift_simple_server.h include_processordir = $(include_thriftdir)/processor include_processor_HEADERS = src/thrift/c_glib/processor/thrift_processor.h \ src/thrift/c_glib/processor/thrift_dispatch_processor.h \ src/thrift/c_glib/processor/thrift_multiplexed_processor.h distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ README.md \ test/glib.suppress \ thrift_c_glib.pc.in CLEANFILES = \ *.gcno \ *.gcda thrift-0.23.0/lib/java/0000755000175000017500000000000015170007200015033 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/0000775000175000017500000000000015165535636015653 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/0000775000175000017500000000000015165535636017644 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/resources/0000775000175000017500000000000015167543515021653 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/resources/.serverkeystore0000664000175000017500000001113615167543515024752 0ustar00buildbuild000000000000000‚Z0‚ *†H†÷  ‚õ‚ñ0‚í0‚ $ *†H†÷  ‚ ‚ 0‚ 0‚  *†H†÷   ‚ À0‚ ¼0f *†H†÷  0Y08 *†H†÷  0+º¬¡óÑÌ}ò°¾Ò«!¼m†…Ú' 0 *†H†÷  0 `†He*ƒ¸hL½>Ç禮76áM΂ PoYœ†Îpº5Õà•ºrœ¬ óx îïêB¥ü‰~CLJCg°X}€J^P¼¼v R±on?C“Y—H>mÜ>óGÍè½K µÎLI÷,¯Cн”E ój>\…©YWÙ‹<±QÙœ9÷¾hƒßÏ·ãŒÉ0_Ø_Î~ÓëpŽÃ³?×` O¤¦ÔÖj_'®`æ}ÕƒÂÝÍ'©Ð«z/mÿ&–FÆn±zÇð‚¢8£ìfЏÊ\>RÖµbÔž.Fà|ëúñ 'GêÕïòB;uJü,¼µ)ȤyùÛF]za4+ú¸Ÿ«L³>÷_œ4ûn—ªÂõ+8—¹×M³nxÀ >züpÿ̺´ä læé‹C„H‚Û'°œÒ=H:n€b=o”3ìNž9ðòàä¥9°a†•XÄ£­0OÒ*êÞµ"4Àü°¤;»âîðc^¾Æí¶Äšwþ{ΙÆ ‡”öû¥# Q¢-áf=QÐd yÍO² N}±ªÀ‚ü;¸rs*?¾P÷iŒž¥Ý^ܳÂzy:‹ˆËÇ]^ü§Ú–êÜîíµ˜&¾š ¿?Ãù¹K«ßptÙ4<œ`#5k= N4Ðë/'rºÁÎ4 wÖ¹|â y?šïÌû¯ó©‡˜xË‘ïñ| á8•Úøæ'"öž\œòHž=B•tðo)ž•‚DÑEÎ<Û«XW ƒW+·Lã†"yÒÌæ.š¼)ÕŹucÚW,ßùˆŒÉÆG¶ùrÅ!Øn·>nŸ‘|¨½C8èðóë§Gu0$ÄŒYv+ãÅzïd{HÀCùz7–D ‘¤“<±´ÕÌ‘¹°Ñ>è±aó‹\ƒ©[[ö#¼'¶œôÕA–÷ýfix”½ï0áÎ7`Óƒ Ñ'Ϋè“ùEÑøœ'ïy¼…Ÿð94ôÖ°[†sÚ@»™%Üeô O»ˆ8-SÙ–ÈoÒ| ÷Óœ#abÝ{çŽûä1™Eïúc?_J'Ÿ C²¡¶9ÞSÉ_R]ƒÅðÝ?Á?ÕD>&Ȉ¼~.13®Böd|õ¡± µVÛ›ßRú”êèmu)àR¤ÙYjyV>. „´Â¨i~g²Ú„ƒ1€„¹š+IÔ¼¹P!­T,µ[¿Æ—çµ4gÅŸ1 ÄR?Q}@PÔ·ßËbK¤f$-{œôéí6‚±ÈºlÙ’ò}CNŸÂ~†s—¯ª'Y>=Æ„*û;Ðò+®ˆÅ-#i”´õ¾Ô, aPt››£PyÏä0è²OÏÝÜð‚?‹Ö MhûÀxÚÝL?¤²°ž3ôoƶ 2°Õ¸)5´ô5EîSra"ym6YŠ“yÀJW¡Çèœ/%Xs–Ø.Dú[aÆ‘¢m‹¸›ìq£ ù”ÝÅ‘µ’3úˆ-æûQm=:Éx äÿ½cW˜€£è†ÿÌܺ¶­·^nªÈÃmÅ·OžF§Rõµ$© Y–ö<"XòÊ,/ͤ‘UK¸Ž®[>W-Fn¨ËÎCéÑëâ2~G-š~žÌ76öØáXìò¤j’ÎåqR°éÖñ-'£>±5æ ·ÒÇ VÏwí6Â`‡F¥Ð‹\ ·ó´Í&uœ6Ý´q1¨»žDÇ»=޾ØÇ(•˜ …‹®*›s&âÆ(ñëeæ®&Ö‚S•k>O%Ì€ëÑÐý=ñ@@ãØý¦œ Ж[‚îb㣙øþjØ´];yNã*2Ò;†t Ý™’Ê‚ÆG…(2»Ííô|£"L¶îEýsÄ8&ÖUžÜ€B[Õ;»†kPÀä\nshѲ¹OÒâ"àYlËm4fÄÿê ÀŠ=1vvl’D ýq_®çžˆ½ÇP+Í?:ÀB ˆ¡þö)&×3•åu «n_ÂÂEEê¬oMîZ¶ËþwG0ŸÖ¸–æ¨õ³vU »Ç:f?èÖ¼{W2V?|Éæô×@ðI*3’Ý”tq5jü–ÑÝ|§~¹¦Ð•x\>Üð³ëšð×søüšw}†Šz¥f{\‡>Ɖs¬¸ ”XP·¬5õ’"4ðê+KÊ´ê,ë§Í5©*ÔÓžïYÔ œè‹>ÈkájAÓC>×[ìÂö®Þš EKŽj¸Î/³óß¡²Usù€=Y{^¸Ð.ÉÑ8ðjðÓA>˱'!¢DöÒöÒ¼ÀE3F¢sO‡:öXÜêg‹M™i[óÐËLk£‹x_¹9Ý´ÑzÇaFéáÚªŸ²vÌ@˜4ýTÕæ¾•¢¸eº9‹ðEâ` #-Xâq“½Ø€wU˜Ot[x¨)da‰€)Åt¥1tc‹Ü>6ÔA‚8™¤Æ°”©Û×N‘³1=“)KÝ/…¹T_Råž ø‰‚öpôšÛS•@3nZ£ãÝð *gWm¼§^˜ͰÈ86"0¶¬½®–ȶ‹¿[eZ_àÁïX`z4 !f°1}[[l$õ8ñˆ “‡¹ }ÿ²âeŽ«g¡h“BÍ`z|y¡F¶+¾R°©³.E0´k¯Zâž¯Ž‹S0.cCýAÀjiÛ‚ÆÉï& ÐH°+‹}̳±‰Ûòl[nmèý­`Ý}må%/ÌÕyš’ªÑo—ýQ'yØèX/O'ɯ7µó´.9d¸¤Á˜Z"ÀNTÈ@6@Ù1ËsY»š3H%œ;Èݼ;USª½%ß¼ô¶†˜Lª2&s2Ïòes]ÓóQ6ã?Lµ•Ç160 *†H†÷  110! *†H†÷  1Time 17639189920430‚Á *†H†÷  ‚²0‚®0‚§ *†H†÷ 0f *†H†÷  0Y08 *†H†÷  0+mÃ\é:²èëW¾Æ&“©D®Ñµ' 0 *†H†÷  0 `†He*ßuëàhPЖ‚˜…t¼b€‚0ôxmÊŸ+H„9¥Ê/OQ³l¡†¡/©Ÿ5ýÈpEÜÓyL>7Ð}0lòˆ³Fï\¦j8Õˆ—¾k­ô¹‚[Elž,×ߥ«'ÀóCÏþŸ 6ê„8"¸°ô<}XÆê+ÂZkI½˘-/^;0ÏrÙØ}xâj‡Ö:Y“ÇÆñAÿß÷ÝâéG%ëïcèú«EäØÁ“öž®Ö©nI¨w³µ&i®w[Ø#i­\8…A~Š~ ™B›9¹O¢Òmµ¾SŽõ¶7:['Ú+®{HmãëƒÜðÚyRL‚“s¨˜4•aˆB6›òâtäã6ðt¡D|H™Û QÇ‹&®²;iÌ!~(|M&;ÏÉ„ðá>*Aw-Ö=¼¾th}r-nô‰ PïU÷¶ïw˜-*š%_ãdªêòОŽXk Ï7?f_£½®Æy™aÙ4_Ä.$±OYëªw?§]xiVc‰taˆ»¾Ø_Y1YîÀîß5Sé›ÊƒÕF €FB-„ÏúHË8>V‰TIÀØ ÀéDÛžçÚᑹ^ƒŠU†t„>ÜÅÍUHvè¯-ÎìõáÄ×JàŠçÆÓ™áÅ7 9ÝÞØ~ñøÃŸíW™´â|õb>s=:¥œ¿ñBñ¥xÆ6˜8d¿ŸUAT!Y*)*”[õ~nçÇÕ«--QªÀMω&}ñ>ãw™ñT‘OñQ\I$FÏj«,Ó¢wp5~‡cI·Bú_•ªê©Í·¿»{ù‰¡ì͈íÙÅ 3×4«ª´ÓP*0"Ðö;ÉÉ \ݯ?0HÙ4EyÝŽlQ™f­ë%D¬á¹òMá¥ßÌW†ZÄëV1z@¢êJÿxdù3I#§ºu»äôžÃâC)›ò"®›ÈECÆéX(èß+Ï9'‚hÇ1» q×VcÏ–iêÄjøÌÓ›Åiwqúô$iyùé’ók”d¹k¼(jÊ5|E@äGØwšášR•çà/R5‘()7Ì\f°0Ï\K׉­Ð®¹âý¸AŽÄDÝDR±Åëîû¶æð‘ßHR £>"‹»¬êZE´ZÐ`N.\ß— ­Ý–êmœÐ·d AÄQˆËÂÝn;pž1DŽÓ†`ƒìº®…Œâ î)?1@ Ûé“ÿ~×|+ /¶ÜnâܸöÎN‚)ë%áC,ƒXó(ƒ‡Û  _†%§Ì5ëdf`Ì¢‘׋(İÜD>ë&¼^Ðm‡T T.¯ûƒ4“'pA$üó6°lÿæú-)±‘"‡*Ü’rH̉tá²1¿û%@ðº(3äT­ƒ"‹#ЦqøÜ}Õ½çèT2ì\ÝÅ¥÷0ð¼ç@%ƒh­B~Ga͇¹°j°?GÞê5c„!›Ú¼ùRL¢“f$ã ÁÌ:æz²Æd2Ëû„¤@QÍTç•i:xÜØ'ÄNcõµB“LšÐ·,c×õ•ýŒ¶-.sV÷¤+Æn3‰ Ž¿4h< ó.aÐD@ð[J´šõÚ6K× o±zÖÅ™.äsÝóØåF8` uþe¯A³x$[©•¿7¿œ±£æ§ ÀSna»èj´êfÏ{<ëÂÁàÿE3)bôÒØ¸âÆòìâùÀ6ëá"“À-pÔêjõé×cure¦)ZCå—îod®ƒj‹aG€ÑúN÷¼Ó6î‚jy˜WÈF”Ë¢‘¦Ö”èÔé÷¸¼*pL¨k˪Ûù*£©›ù”gIøä3OøLÊÔ#Œ<çܤKw¿åêfIH:w9uäbŒ—;³ç,Á´t°‘þX#†ƒ ¾ ÁùD÷ 3<©îóIHùtë: õ m+|(Óft17R²±…X… OWƒ‚B´\js¡»”þ4ÎkU(9j¦Ç[{‹´¦pEKzËǨ.ßz·•§g)\ ,a\± Ç]UògܩǛý¡ÈŒÜm¤¥fá‹ø¼]E÷,=/c]g:>¾¢X‡?wnjpMR·ÑÖŽŒ”g“ÕáâFÓþ 8˜ƒuçX9øòÕœ-àA×ÙHgʘÕé‘J’Ýê¡¢ý\\A5Î@XùØ:57ç¹,Ô•²ï’ç7ò/ÛLùBæÎbº ¡×p¥[w)”á@¢à¢:Kvè©“t¯™_„UaæKg1 ¥«"w‘ž‹¬8¤ «8 XQ ù½Ó³;ÝÊøÌ¥R*¯_4Q™ë_È/wú‚ÔgsŸK³12к3¡¡zþöñɶ ‡lgðbÆ4㾑½„t² 7 >'Ïôòå9Q£úËï€ýƒ–ŒÞ3pÙÊøQ/ÐÿÏ&.-ÁOh]Ýö L¢âžüN0M010  `†He ÍËN'I Ÿ ±8U>°òkž‚›tvñìˆes]uNäÇH]*†¶âSâDœ'thrift-0.23.0/lib/java/src/crossTest/resources/.clientkeystore0000664000175000017500000000577615167543515024737 0ustar00buildbuild000000000000000‚ ú0‚ ¤ *†H†÷  ‚ •‚ ‘0‚ 0‚¤ *†H†÷  ‚•‚‘0‚0‚‰ *†H†÷   ‚@0‚<0f *†H†÷  0Y08 *†H†÷  0+Oçä‹Àz‹A[ÏFÊ’¹>(e' 0 *†H†÷  0 `†He*N@2‘õM½IÔ1™Í ™‚ЗÙòYkŠã(%j?b\Šf‘$}cØ ©Cr)c;ÆÜ‡–F 6.6•ôÜWŒó=ˆCgáD’Ú!h|·â„«­>bòcÒ8€Àº2‡–ê#!02ë—>ÑÉ)c0¸äÀà](0Lû?›òŒ@8ò^PÔ…ÅMÈUâ_¤§xd÷º»Â5ßù-ÉO³]®n{Îÿ%¹ú€”bZ¡ÅôÔ%V)ù㋊7 ë!þð\Q^á Õ ½[ ðöÛËÙbÎnWÞq¶è…™EóÚ¿³¥•}yUxùüÇZ”6Òæã¿@WBF Õn®ä%o8ªÆsüÑÄGˆX’Tlæߣý«fɨ-M^î”÷6o<¢Ê<‰°ã#É®Y˜S3»Œ£Íç;2=ÖPö!@åI =6ÿm47#ç5."½šz¶ªé¬GþÕt²}8åwžÔØq² ×WPû»lÇ.²z)<—Ë_&‚ ‡æó4(¥ö“Ïð!Ï—°e¿©´@´J€Ã™è¼³–Y®’¾,˦v§BGh•£41&+?Òóa´v*ÇöU´)é5ýf» ·\ÈÀæÕìk {=GVžŒjÓŽ”ÖÜ)W8´}[ô¶•ìGqQìcÙ–Ü÷¿M±fNSù’pŸÔÛ¸ÖqØCOÿñˆº¿”](˜?¥d/.ýJh` µè¼þÆò½"ë%î™tì½\¶£Iéi}×äµD[Åî™è™t·­u¡fk§àºW•Éû?ʸSºJ%x¶E†>ä 7ú×¶å-g–ÊE$šÕ@««Ñ‡Ãßá‚ó¿ùp}ïçH½†îœgàŒtEÈ¢ÔqŠ˜b"„ÁÖê¨=x§.3)ß;uúœWvÉÄ· ~Íï¡3l X±éQÆ•Ãú5¼¿ûI®`k¤£k 2Þô‚W5MÇÚ¡|Õš ã ßÛ@¦/ËuëÕĹòz™ÒáWVœpÜœ Ö(†TCÑØ^›x)beDK“N0;è[–hzìoÊeBd–xHvø©;²%ìZN¼½ý"'qDeæØÁü%i`›TD(ƒ_Ÿ‹Sð‚©e±…ú{ ´r vùÌ’’Ú ¬ | ÕŽZ?SÂmãCoŹ*L^š‘ÁI#¦Þ¯Y|ŠmúN¼ {¥küÓ«ÔïŸÉ¨v¢Wþ7èÇçôµËzîXS”aвèa1™Ý‡Hóþ¶àÊž®ê©C|t‘ Õ\õA¤¨TøjS­ ø<ƒ+/€0TØ%;È\ ¸X@[%<tÿª¢/õ!ûoö¶}óEi¯©7üuº£†¼2üÿ”s»†Ô¿úþáŠíE08pÔÓ’‹Wr"ã˺Hië–o‰èì`j×ÃL;Û1ôºOЀ Cpæ³±ˆŽ5Cój,œîˆ§4V2¥Á¨ËÏÔ1Íj௶$—ê(r‰ß‘’â]à=ôø%}tl90OfªšÛƒàå¸{AæX’‚5 ³+N¡>ŒbYÅGb"Q¢i×ÈN<Á160 *†H†÷  110! *†H†÷  1Time 17639189774660‚á *†H†÷  ‚Ò0‚Î0‚Ç *†H†÷ 0f *†H†÷  0Y08 *†H†÷  0+äès¿ îBüÛo é°çl' 0 *†H†÷  0 `†He*9˨Âiqëí<§ eF¬^¢€‚PRÞÛ¡Æ9Ï寂ÇíñŒ&~~FÊuÓV·34l5•Ì€ ‡#?+8™u»B|õäà:ÖþÇÅÆÕm4Ñâkú,‰ØÚÜ¥¶]kæý¾ØÎýn…Ó|{[²˜uÌzr‡t 루ÚŸd7³È‘ `Î-ƒuÃ×Oy ƒäf‘˜M—_ô˜”‚•Kd×”9”~Ð$ZÌÊ X}m£qõZ4ßé†åF«´ÿ–O+v¾Ò8Ïpë­®€øv¡ÏŸ ©ø€„³´½Èz·Ù±ñÕdÆÄ:VpA-9çGE@õoyRª¨Ÿ€!jê±h p¨ú  #Àd”'aµ#{H¡k–)}~¨³&ÌF"uács‚‘,ºejÙç;¯ Öb?­[/7´Ça}y†@qƒcî<ùóò¯""Á xãÄ#¿Y“Û°§ª3Iñ;G\qrÏlØú ¯°ƒj}ÊïËC?ŽcÂ¥úÂ)¥%Î(ú¬ ”N§§—­}аùMMY+JZß•„^ê;t•ÍMÌ•9ðEÕLêI:M“þ>„²n|¨Y¾J«0մ޹#ÂÌN¸Äy?YBfÞÒu'f\ÌœÔBx7ÝÈ8Ǭ͉wà÷4O&mF›g­éX¥'ö©§µqª˜–'ªC8Sî{¶Pšÿ¯y)V“aiÖwÆôê°În–Ñ­ðú[t‰zëøëçæ(éÿò˜Pòq ¼]´ñV£•r­>ʯ§52ü6'×;ˆn\Ät†Ê¨ô6|C¡uñ¨ÐpNÙrélw¤práÑlÖ/¾#Þš¡¤­Ÿùþט÷xZ_¯ðpùGšÞÄ<µ:Ñ·¼‹œàëÄ«ð5“½öu‘ͶÞqè d=ƒun¿á†áø€x¶Z%Žùzœ–Ò'SIdƒcçUƒ‚ŸéŽ·ÛAÍ|Næ±Øà‰”ÒbÎzÞ‹6ØÊOQM”B™¬ÆÎ+»úpÚ¡"<¶~ ¾Rƒ3»c$9g?ñ 4óÑ£´ÕÔÓ¾ ûÓ3Ñïô6Ãöñ´äAe3òôÏÀtï´ˆÛ¹¢%ŽõÙ&Ć Ýg>ƒ¿(N©›(¨I²Ôw¯¨™}qB7*…=7¢ ¹:íß°N¸PîGOëØŸ;9¹ä…AM1U]r„›E§Åwã½Ù §ÿÜ,&“Õ?(ºéŽÖZLJ¿*É姸w‚m ?je Ã–ÜæIÙ|2i¿²Ñ¢þ|fžÑ*Íà,¼g‹«j•ÊN=0M010  `†He eÀr€‰î—)UcØíŒ>[É)§WÈ›å>œ¦Dç[lTt-°Mш÷ÕÇaQpŽùˆ‡ä¥'thrift-0.23.0/lib/java/src/crossTest/resources/.truststore0000664000175000017500000000337715167543515024124 0ustar00buildbuild00000000000000þíþí localhostš±¿RÜX.509½0‚¹0‚¡  o„ q5W®G]ZÜF@Ú¶ß0  *†H†÷  0±10U localhost1$0" *†H†÷  dev@thrift.apache.org10U Apache Thrift1'0%U The Apache Software Foundation10U Forest Hill10U Maryland1 0 UUS0 220630223728Z 300916223728Z0±10U localhost1$0" *†H†÷  dev@thrift.apache.org10U Apache Thrift1'0%U The Apache Software Foundation10U Forest Hill10U Maryland1 0 UUS0‚"0  *†H†÷ ‚0‚ ‚ÏîjmÁ^24Ǩ_v§kàÛˆ0;ž ü1(iÊ fv“»¹à÷X+dðƒ—´ÿë«u?v4Žæ ™ÀæJÿE¼û–<6r£“r›Ñùí|¡Y‰«vñç¹±±ÔŒ¯mVü¬aèœvïÖ²Ë@S©}pÚK›w¦]*eL¬-æ{b|ó>¨` Å5±_yà"&6.¼‡éZeßð¿Lâó6Du¤’×{Î=´«NÙ¾‚‚ðçÔL„ˆ1•-9 }çÒš™d8‚½‡åÚ>Ú‘s*Š&âð«È¨üÕò\ÿQQ&È·ýr¿6W³ ü>Å]÷àè¦iŠVÄ8D“ÉY`’ÀƒÙ ¨v°‘þ¼ªŠ°91ü¥_¼$¯ºÎD³H0S ÖHØ‚1$[<îeirï´Ÿë¸ókÝÂÅx„ÞŠ@÷Ó®ZÙ2Ø—ÒLÖ®6"Íâ=7…E)JìQv¹mÊ®`ù+Ö…rq©‡Õð^Ø$S ì¤îG{TA>"îÄ„ž…|¤it€µ©q„g^ÑÿxÑIù‘¶º%).ó ²•íd"?‚«$1Íæ™5Ÿ%U¹T\ëêðnŒëê«’ö³¡¤$\«Ÿå=(-¿-®(“ÂQK2ïW®—Å›nñ:2¬½bêɃÿ¤W‘² (á[þŽ £Æ0Ã0U¨á$pZíœÄ8cÍçøyI”Ú0U#0€¨á$pZíœÄ8cÍçøyI”Ú0Uÿ0ÿ0Uÿæ0U%0++0>U705‡‡‡ÿÿ‚ localhost0  *†H†÷  ‚‹%â4ÒÙÖë·°’¶üÿž6†¨êãáÍ …X-÷&AñY«%¸ìù…¬A‡ ßúÄö&2dÜÀ<÷žsRWãd«k#Ë!ÕåT¨ø3÷’tÇJ.ó·x ›8²); ¢XˆKŠÀ^fuϪxá< á1‹¼HWŒe'ÌùuºiáݲJ)$Ý⪳Èï°1ìÊo˽ý½+0cB½£5z×6Zß?d—k"À|Y Ê”›n!LàfxR'Øy€Šò:‡ãmFê|^Ì&ÐÓ©2áª't_“ì„v-Äx]ÛdÆ×SU°)Ã6ÜŽ—m~úS¨O«–\2“Â"KÁ××LtÁ©¥Vò·Ï?T±l§Ã1¿^ÓçÚÊ(†!¶e•EŠ8æ› ÂñÛØg3 æÂ­ˆ˜oj¯=ÂOÉC³p#çÂÃ’Ûi`N¡ Üå®hwõ‚<¦óC‡ëtJB¼6e›Š?„„$#%ªÊx"@§ËNvL·aþ÷ÁB4±¬ÜB$™§ŠŽÊ ow34!ÓÙPÑ~)ŒûÒå'&‹ttEIÇàJefÈç«R Œ˜‰°2‚í*çD•³åµÜRIª²a—hv›UnÙÞwÍgR,Ñà³XgºM}ð!GcÿõvÕãW5w-}ïvm ïäƒ Xè·å~p}e†2tŽ?T¡>Œ'Ô}…=Z1Ïthrift-0.23.0/lib/java/src/crossTest/java/0000775000175000017500000000000015165535636020565 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/java/org/0000775000175000017500000000000015165535636021354 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/java/org/apache/0000775000175000017500000000000015165535636022575 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/java/org/apache/thrift/0000775000175000017500000000000015165535636024075 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/java/org/apache/thrift/test/0000775000175000017500000000000015167543515025051 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/crossTest/java/org/apache/thrift/test/TestClient.java0000664000175000017500000007143015167543515027777 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.stream.IntStream; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.thrift.TApplicationException; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TMultiplexedProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TSimpleJSONProtocol; import org.apache.thrift.transport.THttpClient; import org.apache.thrift.transport.TSSLTransportFactory; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.TZlibTransport; import org.apache.thrift.transport.layered.TFastFramedTransport; import org.apache.thrift.transport.layered.TFramedTransport; import thrift.test.Insanity; import thrift.test.Numberz; import thrift.test.SecondService; import thrift.test.ThriftTest; import thrift.test.Xception; import thrift.test.Xception2; import thrift.test.Xtruct; import thrift.test.Xtruct2; /** * Test Java client for thrift. Essentially just a copy of the C++ version, this makes a variety of * requests to enable testing for both performance and correctness of the output. */ public class TestClient { static int ERR_BASETYPES = 1; static int ERR_STRUCTS = 2; static int ERR_CONTAINERS = 4; static int ERR_EXCEPTIONS = 8; static int ERR_PROTOCOLS = 16; static int ERR_UNKNOWN = 64; public static void main(String[] args) { String host = "localhost"; int port = 9090; int numTests = 1; String protocol_type = "binary"; String transport_type = "buffered"; boolean ssl = false; boolean zlib = false; boolean http_client = false; int socketTimeout = 1000; try { for (int i = 0; i < args.length; ++i) { if (args[i].startsWith("--host")) { host = args[i].split("=")[1]; host.trim(); } else if (args[i].startsWith("--port")) { port = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].startsWith("--n") || args[i].startsWith("--testloops")) { numTests = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].equals("--timeout")) { socketTimeout = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].startsWith("--protocol")) { protocol_type = args[i].split("=")[1]; protocol_type.trim(); } else if (args[i].startsWith("--transport")) { transport_type = args[i].split("=")[1]; transport_type.trim(); } else if (args[i].equals("--ssl")) { ssl = true; } else if (args[i].equals("--zlib")) { zlib = true; } else if (args[i].equals("--client")) { http_client = true; } else if (args[i].equals("--help")) { System.out.println("Allowed options:"); System.out.println(" --help\t\t\tProduce help message"); System.out.println(" --host=arg (=" + host + ")\tHost to connect"); System.out.println(" --port=arg (=" + port + ")\tPort number to connect"); System.out.println( " --transport=arg (=" + transport_type + ")\n\t\t\t\tTransport: buffered, framed, fastframed, http, zlib"); System.out.println( " --protocol=arg (=" + protocol_type + ")\tProtocol: binary, compact, json, multi, multic, multij"); System.out.println(" --ssl\t\t\tEncrypted Transport using SSL"); System.out.println(" --zlib\t\t\tCompressed Transport using Zlib"); System.out.println(" --testloops[--n]=arg (=" + numTests + ")\tNumber of Tests"); System.exit(0); } } } catch (Exception x) { System.err.println("Can not parse arguments! See --help"); System.exit(ERR_UNKNOWN); } try { if (protocol_type.equals("binary")) { } else if (protocol_type.equals("compact")) { } else if (protocol_type.equals("json")) { } else if (protocol_type.equals("multi")) { } else if (protocol_type.equals("multic")) { } else if (protocol_type.equals("multij")) { } else { throw new Exception("Unknown protocol type! " + protocol_type); } if (transport_type.equals("buffered")) { } else if (transport_type.equals("framed")) { } else if (transport_type.equals("fastframed")) { } else if (transport_type.equals("http")) { } else if (transport_type.equals("zlib")) { } else { throw new Exception("Unknown transport type! " + transport_type); } if (transport_type.equals("http") && ssl == true) { throw new Exception("SSL is not supported over http."); } } catch (Exception e) { System.err.println("Error: " + e.getMessage()); System.exit(ERR_UNKNOWN); } TTransport transport = null; try { if (transport_type.equals("http")) { String url = "http://" + host + ":" + port + "/test/service"; if (http_client == true) { transport = new THttpClient(url, HttpClients.createDefault()); } else { transport = new THttpClient(url); } } else { TSocket socket = null; if (ssl == true) { socket = TSSLTransportFactory.getClientSocket(host, port, 0); } else { socket = new TSocket(host, port); } socket.setTimeout(socketTimeout); transport = socket; if (transport_type.equals("zlib")) { transport = new TZlibTransport(transport); } else { if (transport_type.equals("buffered")) { } else if (transport_type.equals("framed")) { transport = new TFramedTransport(transport); } else if (transport_type.equals("fastframed")) { transport = new TFastFramedTransport(transport); } if (zlib) { transport = new TZlibTransport(transport); } } } } catch (Exception x) { x.printStackTrace(); System.exit(ERR_UNKNOWN); } TProtocol tProtocol = null; TProtocol tProtocol2 = null; if (protocol_type.equals("json") || protocol_type.equals("multij")) { tProtocol = new TJSONProtocol(transport); } else if (protocol_type.equals("compact") || protocol_type.equals("multic")) { tProtocol = new TCompactProtocol(transport); } else { tProtocol = new TBinaryProtocol(transport); } if (protocol_type.startsWith("multi")) { tProtocol2 = new TMultiplexedProtocol(tProtocol, "SecondService"); tProtocol = new TMultiplexedProtocol(tProtocol, "ThriftTest"); } ThriftTest.Client testClient = new ThriftTest.Client(tProtocol); Insanity insane = new Insanity(); long timeMin = 0; long timeMax = 0; long timeTot = 0; int returnCode = 0; for (int test = 0; test < numTests; ++test) { try { /** CONNECT TEST */ System.out.println("Test #" + (test + 1) + ", " + "connect " + host + ":" + port); if (transport.isOpen() == false) { try { transport.open(); } catch (TTransportException ttx) { ttx.printStackTrace(); System.out.println("Connect failed: " + ttx.getMessage()); System.exit(ERR_UNKNOWN); } } long start = System.nanoTime(); /** VOID TEST */ try { System.out.print("testVoid()"); testClient.testVoid(); System.out.print(" = void\n"); } catch (TApplicationException tax) { tax.printStackTrace(); returnCode |= ERR_BASETYPES; } /** STRING TEST */ System.out.print("testString(\"Test\")"); String s = testClient.testString("Test"); System.out.print(" = \"" + s + "\"\n"); if (!s.equals("Test")) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } /** UUID TEST */ System.out.println("testUuid(\"00112233-4455-6677-8899-aabbccddeeff\")"); UUID uuid = testClient.testUuid(UUID.fromString("00112233-4455-6677-8899-aabbccddeeff")); System.out.print(" = \"" + uuid + "\"\n"); if (!uuid.equals(UUID.fromString("00112233-4455-6677-8899-aabbccddeeff"))) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } /** Multiplexed test */ if (protocol_type.startsWith("multi")) { SecondService.Client secondClient = new SecondService.Client(tProtocol2); System.out.print("secondtestString(\"Test2\")"); s = secondClient.secondtestString("Test2"); System.out.print(" = \"" + s + "\"\n"); if (!s.equals("testString(\"Test2\")")) { returnCode |= ERR_PROTOCOLS; System.out.println("*** FAILURE ***\n"); } } /** BYTE TEST */ System.out.print("testByte(1)"); byte i8 = testClient.testByte((byte) 1); System.out.print(" = " + i8 + "\n"); if (i8 != 1) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } /** I32 TEST */ System.out.print("testI32(-1)"); int i32 = testClient.testI32(-1); System.out.print(" = " + i32 + "\n"); if (i32 != -1) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } /** I64 TEST */ System.out.print("testI64(-34359738368)"); long i64 = testClient.testI64(-34359738368L); System.out.print(" = " + i64 + "\n"); if (i64 != -34359738368L) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } /** DOUBLE TEST */ System.out.print("testDouble(-5.325098235)"); double dub = testClient.testDouble(-5.325098235); System.out.print(" = " + dub + "\n"); if (Math.abs(dub - (-5.325098235)) > 0.001) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } /** BINARY TEST */ try { System.out.print("testBinary(-128...127) = "); byte[] data = getBytesData(); ByteBuffer bin = testClient.testBinary(ByteBuffer.wrap(data)); bin.mark(); byte[] bytes = new byte[bin.limit() - bin.position()]; bin.get(bytes); bin.reset(); System.out.print("{"); boolean first = true; for (int i = 0; i < bytes.length; ++i) { if (first) first = false; else System.out.print(", "); System.out.print(bytes[i]); } System.out.println("}"); if (!ByteBuffer.wrap(data).equals(bin)) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } } catch (Exception ex) { returnCode |= ERR_BASETYPES; System.out.println("\n*** FAILURE ***\n"); ex.printStackTrace(System.out); } /** STRUCT TEST */ System.out.print("testStruct({\"Zero\", 1, -3, -5})"); Xtruct out = new Xtruct(); out.string_thing = "Zero"; out.byte_thing = (byte) 1; out.i32_thing = -3; out.i64_thing = -5; Xtruct in = testClient.testStruct(out); System.out.print( " = {" + "\"" + in.string_thing + "\"," + in.byte_thing + ", " + in.i32_thing + ", " + in.i64_thing + "}\n"); if (!in.equals(out)) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } /** NESTED STRUCT TEST */ System.out.print("testNest({1, {\"Zero\", 1, -3, -5}), 5}"); Xtruct2 out2 = new Xtruct2(); out2.byte_thing = (short) 1; out2.struct_thing = out; out2.i32_thing = 5; Xtruct2 in2 = testClient.testNest(out2); in = in2.struct_thing; System.out.print( " = {" + in2.byte_thing + ", {" + "\"" + in.string_thing + "\", " + in.byte_thing + ", " + in.i32_thing + ", " + in.i64_thing + "}, " + in2.i32_thing + "}\n"); if (!in2.equals(out2)) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } /** MAP TEST */ Map mapout = new HashMap(); for (int i = 0; i < 5; ++i) { mapout.put(i, i - 10); } System.out.print("testMap({"); boolean first = true; for (int key : mapout.keySet()) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(key + " => " + mapout.get(key)); } System.out.print("})"); Map mapin = testClient.testMap(mapout); System.out.print(" = {"); first = true; for (int key : mapin.keySet()) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(key + " => " + mapout.get(key)); } System.out.print("}\n"); if (!mapout.equals(mapin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } /** STRING MAP TEST */ try { Map smapout = new HashMap(); smapout.put("a", "2"); smapout.put("b", "blah"); smapout.put("some", "thing"); for (String key : smapout.keySet()) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(key + " => " + smapout.get(key)); } System.out.print("})"); Map smapin = testClient.testStringMap(smapout); System.out.print(" = {"); first = true; for (String key : smapin.keySet()) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(key + " => " + smapout.get(key)); } System.out.print("}\n"); if (!smapout.equals(smapin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } } catch (Exception ex) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); ex.printStackTrace(System.out); } /** SET TEST */ Set setout = new HashSet(); for (int i = -2; i < 3; ++i) { setout.add(i); } System.out.print("testSet({"); first = true; for (int elem : setout) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})"); Set setin = testClient.testSet(setout); System.out.print(" = {"); first = true; for (int elem : setin) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("}\n"); if (!setout.equals(setin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } /** LIST TEST */ List listout = new ArrayList(); for (int i = -2; i < 3; ++i) { listout.add(i); } System.out.print("testList({"); first = true; for (int elem : listout) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})"); List listin = testClient.testList(listout); System.out.print(" = {"); first = true; for (int elem : listin) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("}\n"); if (!listout.equals(listin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } /** ENUM TEST */ System.out.print("testEnum(ONE)"); Numberz ret = testClient.testEnum(Numberz.ONE); System.out.print(" = " + ret + "\n"); if (ret != Numberz.ONE) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } System.out.print("testEnum(TWO)"); ret = testClient.testEnum(Numberz.TWO); System.out.print(" = " + ret + "\n"); if (ret != Numberz.TWO) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } System.out.print("testEnum(THREE)"); ret = testClient.testEnum(Numberz.THREE); System.out.print(" = " + ret + "\n"); if (ret != Numberz.THREE) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } System.out.print("testEnum(FIVE)"); ret = testClient.testEnum(Numberz.FIVE); System.out.print(" = " + ret + "\n"); if (ret != Numberz.FIVE) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } System.out.print("testEnum(EIGHT)"); ret = testClient.testEnum(Numberz.EIGHT); System.out.print(" = " + ret + "\n"); if (ret != Numberz.EIGHT) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } /** TYPEDEF TEST */ System.out.print("testTypedef(309858235082523)"); long uid = testClient.testTypedef(309858235082523L); System.out.print(" = " + uid + "\n"); if (uid != 309858235082523L) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } /** NESTED MAP TEST */ System.out.print("testMapMap(1)"); Map> mm = testClient.testMapMap(1); System.out.print(" = {"); for (int key : mm.keySet()) { System.out.print(key + " => {"); Map m2 = mm.get(key); for (int k2 : m2.keySet()) { System.out.print(k2 + " => " + m2.get(k2) + ", "); } System.out.print("}, "); } System.out.print("}\n"); if (mm.size() != 2 || !mm.containsKey(4) || !mm.containsKey(-4)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } else { Map m1 = mm.get(4); Map m2 = mm.get(-4); if (m1.get(1) != 1 || m1.get(2) != 2 || m1.get(3) != 3 || m1.get(4) != 4 || m2.get(-1) != -1 || m2.get(-2) != -2 || m2.get(-3) != -3 || m2.get(-4) != -4) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } } /** INSANITY TEST */ boolean insanityFailed = true; try { Xtruct hello = new Xtruct(); hello.string_thing = "Hello2"; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = 2; Xtruct goodbye = new Xtruct(); goodbye.string_thing = "Goodbye4"; goodbye.byte_thing = (byte) 4; goodbye.i32_thing = 4; goodbye.i64_thing = (long) 4; insane.userMap = new HashMap(); insane.userMap.put(Numberz.EIGHT, (long) 8); insane.userMap.put(Numberz.FIVE, (long) 5); insane.xtructs = new ArrayList(); insane.xtructs.add(goodbye); insane.xtructs.add(hello); System.out.print("testInsanity()"); Map> whoa = testClient.testInsanity(insane); System.out.print(" = {"); for (long key : whoa.keySet()) { Map val = whoa.get(key); System.out.print(key + " => {"); for (Numberz k2 : val.keySet()) { Insanity v2 = val.get(k2); System.out.print(k2 + " => {"); Map userMap = v2.userMap; System.out.print("{"); if (userMap != null) { for (Numberz k3 : userMap.keySet()) { System.out.print(k3 + " => " + userMap.get(k3) + ", "); } } System.out.print("}, "); List xtructs = v2.xtructs; System.out.print("{"); if (xtructs != null) { for (Xtruct x : xtructs) { System.out.print( "{" + "\"" + x.string_thing + "\", " + x.byte_thing + ", " + x.i32_thing + ", " + x.i64_thing + "}, "); } } System.out.print("}"); System.out.print("}, "); } System.out.print("}, "); } System.out.print("}\n"); if (whoa.size() == 2 && whoa.containsKey(1L) && whoa.containsKey(2L)) { Map first_map = whoa.get(1L); Map second_map = whoa.get(2L); if (first_map.size() == 2 && first_map.containsKey(Numberz.TWO) && first_map.containsKey(Numberz.THREE) && second_map.size() == 1 && second_map.containsKey(Numberz.SIX) && insane.equals(first_map.get(Numberz.TWO)) && insane.equals(first_map.get(Numberz.THREE))) { Insanity six = second_map.get(Numberz.SIX); // Cannot use "new Insanity().equals(six)" because as of now, struct/container // fields with default requiredness have isset=false for local instances and yet // received empty values from other languages like C++ have isset=true . if (six.getUserMapSize() == 0 && six.getXtructsSize() == 0) { // OK insanityFailed = false; } } } } catch (Exception ex) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); ex.printStackTrace(System.out); insanityFailed = false; } if (insanityFailed) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } /** EXECPTION TEST */ try { System.out.print("testClient.testException(\"Xception\") =>"); testClient.testException("Xception"); System.out.print(" void\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; } catch (Xception e) { System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message); } try { System.out.print("testClient.testException(\"TException\") =>"); testClient.testException("TException"); System.out.print(" void\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; } catch (TException e) { System.out.printf(" {\"%s\"}\n", e.getMessage()); } try { System.out.print("testClient.testException(\"success\") =>"); testClient.testException("success"); System.out.print(" void\n"); } catch (Exception e) { System.out.printf(" exception\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; } /** MULTI EXCEPTION TEST */ try { System.out.printf("testClient.testMultiException(\"Xception\", \"test 1\") =>"); testClient.testMultiException("Xception", "test 1"); System.out.print(" result\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; } catch (Xception e) { System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message); } try { System.out.printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>"); testClient.testMultiException("Xception2", "test 2"); System.out.print(" result\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; } catch (Xception2 e) { System.out.printf(" {%d, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing); } try { System.out.print("testClient.testMultiException(\"success\", \"test 3\") =>"); Xtruct result; result = testClient.testMultiException("success", "test 3"); System.out.printf(" {{\"%s\"}}\n", result.string_thing); } catch (Exception e) { System.out.printf(" exception\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; } /** ONEWAY TEST */ System.out.print("testOneway(3)..."); long startOneway = System.nanoTime(); testClient.testOneway(3); long onewayElapsedMillis = (System.nanoTime() - startOneway) / 1000000; if (onewayElapsedMillis > 200) { System.out.println( "Oneway test took too long to execute failed: took " + onewayElapsedMillis + "ms"); System.out.println( "oneway calls are 'fire and forget' and therefore should not cause blocking."); System.out.println( "Some transports (HTTP) have a required response, and typically this failure"); System.out.println("means the transport response was delayed until after the execution"); System.out.println( "of the RPC. The server should post the transport response immediately and"); System.out.println("before executing the RPC."); System.out.println("*** FAILURE ***"); returnCode |= ERR_BASETYPES; } else { System.out.println("Success - fire and forget only took " + onewayElapsedMillis + "ms"); } long stop = System.nanoTime(); long tot = stop - start; System.out.println("Total time: " + tot / 1000 + "us"); if (timeMin == 0 || tot < timeMin) { timeMin = tot; } if (tot > timeMax) { timeMax = tot; } timeTot += tot; transport.close(); } catch (Exception x) { System.out.printf("*** FAILURE ***\n"); x.printStackTrace(); returnCode |= ERR_UNKNOWN; } } long timeAvg = timeTot / numTests; System.out.println("Min time: " + timeMin / 1000 + "us"); System.out.println("Max time: " + timeMax / 1000 + "us"); System.out.println("Avg time: " + timeAvg / 1000 + "us"); try { String json = (new TSerializer(new TSimpleJSONProtocol.Factory())).toString(insane); System.out.println("\nSample TSimpleJSONProtocol output:\n" + json); } catch (TException x) { System.out.println("*** FAILURE ***"); x.printStackTrace(); returnCode |= ERR_BASETYPES; } System.exit(returnCode); } static byte[] getBytesData() { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(256); IntStream.range(-128, 128).forEach(byteArrayOutputStream::write); return byteArrayOutputStream.toByteArray(); } } thrift-0.23.0/lib/java/src/crossTest/java/org/apache/thrift/test/TestServer.java0000664000175000017500000003447515165535636030042 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import org.apache.thrift.TMultiplexedProcessor; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerContext; import org.apache.thrift.server.ServerTestBase.TestHandler; import org.apache.thrift.server.TNonblockingServer; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TServerEventHandler; import org.apache.thrift.server.TSimpleServer; import org.apache.thrift.server.TThreadPoolServer; import org.apache.thrift.server.TThreadedSelectorServer; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TSSLTransportFactory; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportFactory; import org.apache.thrift.transport.TZlibTransport; import org.apache.thrift.transport.layered.TFastFramedTransport; import org.apache.thrift.transport.layered.TFramedTransport; import thrift.test.SecondService; import thrift.test.ThriftTest; public class TestServer { // Multiplexed Protocol Support Details: // // For multiplexed testing we always use binary protocol underneath. // // "ThriftTest" named service implements "ThriftTest" from ThriftTest.thrift // "SecondService" named service implements "SecondService" from ThriftTest.thrift // In addition, to support older non-multiplexed clients using the same concrete protocol // the multiplexed processor is taught to use "ThriftTest" if the incoming request has no // multiplexed call name decoration. static class SecondHandler implements thrift.test.SecondService.Iface { @Override public java.lang.String secondtestString(java.lang.String thing) throws org.apache.thrift.TException { return "testString(\"" + thing + "\")"; } } static class TestServerContext implements ServerContext { int connectionId; public TestServerContext(int connectionId) { this.connectionId = connectionId; } public int getConnectionId() { return connectionId; } public void setConnectionId(int connectionId) { this.connectionId = connectionId; } @Override public T unwrap(Class iface) { try { if (isWrapperFor(iface)) { return iface.cast(this); } else { throw new RuntimeException("The context is not a wrapper for " + iface.getName()); } } catch (Exception e) { throw new RuntimeException( "The context is not a wrapper and does not implement the interface"); } } @Override public boolean isWrapperFor(Class iface) { return iface.isInstance(this); } } static class TestServerEventHandler implements TServerEventHandler { private int nextConnectionId = 1; public void preServe() { System.out.println( "TServerEventHandler.preServe - called only once before server starts accepting connections"); } public ServerContext createContext(TProtocol input, TProtocol output) { // we can create some connection level data which is stored while connection is alive & served TestServerContext ctx = new TestServerContext(nextConnectionId++); System.out.println( "TServerEventHandler.createContext - connection #" + ctx.getConnectionId() + " established"); return ctx; } public void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output) { TestServerContext ctx = serverContext.unwrap(TestServerContext.class); System.out.println( "TServerEventHandler.deleteContext - connection #" + ctx.getConnectionId() + " terminated"); } public void processContext( ServerContext serverContext, TTransport inputTransport, TTransport outputTransport) { TestServerContext ctx = serverContext.unwrap(TestServerContext.class); System.out.println( "TServerEventHandler.processContext - connection #" + ctx.getConnectionId() + " is ready to process next request"); } } public static void main(String[] args) { try { int port = 9090; boolean ssl = false; boolean zlib = false; String transport_type = "buffered"; String protocol_type = "binary"; String server_type = "thread-pool"; String domain_socket = ""; int string_limit = -1; int container_limit = -1; try { for (int i = 0; i < args.length; i++) { if (args[i].startsWith("--port")) { port = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].startsWith("--server-type")) { server_type = args[i].split("=")[1]; server_type.trim(); } else if (args[i].startsWith("--port")) { port = Integer.parseInt(args[i].split("=")[1]); } else if (args[i].startsWith("--protocol")) { protocol_type = args[i].split("=")[1]; protocol_type.trim(); } else if (args[i].startsWith("--transport")) { transport_type = args[i].split("=")[1]; transport_type.trim(); } else if (args[i].equals("--ssl")) { ssl = true; } else if (args[i].equals("--zlib")) { zlib = true; } else if (args[i].startsWith("--string-limit")) { string_limit = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].startsWith("--container-limit")) { container_limit = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].equals("--help")) { System.out.println("Allowed options:"); System.out.println(" --help\t\t\tProduce help message"); System.out.println(" --port=arg (=" + port + ")\tPort number to connect"); System.out.println( " --transport=arg (=" + transport_type + ")\n\t\t\t\tTransport: buffered, framed, fastframed, zlib"); System.out.println( " --protocol=arg (=" + protocol_type + ")\tProtocol: binary, compact, json, multi, multic, multij"); System.out.println(" --ssl\t\t\tEncrypted Transport using SSL"); System.out.println(" --zlib\t\t\tCompressed Transport using Zlib"); System.out.println( " --server-type=arg (=" + server_type + ")\n\t\t\t\tType of server: simple, thread-pool, nonblocking, threaded-selector"); System.out.println( " --string-limit=arg (=" + string_limit + ")\tString read length limit"); System.out.println( " --container-limit=arg (=" + container_limit + ")\tContainer read length limit"); System.exit(0); } } } catch (Exception e) { System.err.println("Can not parse arguments! See --help"); System.exit(1); } try { if (server_type.equals("simple")) { } else if (server_type.equals("thread-pool")) { } else if (server_type.equals("nonblocking")) { if (ssl == true) { throw new Exception("SSL is not supported over nonblocking servers!"); } } else if (server_type.equals("threaded-selector")) { if (ssl == true) { throw new Exception("SSL is not supported over nonblocking servers!"); } } else { throw new Exception("Unknown server type! " + server_type); } if (protocol_type.equals("binary")) { } else if (protocol_type.equals("compact")) { } else if (protocol_type.equals("json")) { } else if (protocol_type.equals("multi")) { } else if (protocol_type.equals("multic")) { } else if (protocol_type.equals("multij")) { } else { throw new Exception("Unknown protocol type! " + protocol_type); } if (transport_type.equals("buffered")) { } else if (transport_type.equals("framed")) { } else if (transport_type.equals("fastframed")) { } else if (transport_type.equals("zlib")) { } else { throw new Exception("Unknown transport type! " + transport_type); } } catch (Exception e) { System.err.println("Error: " + e.getMessage()); System.exit(1); } // Processors TestHandler testHandler = new TestHandler(); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); SecondHandler secondHandler = new SecondHandler(); SecondService.Processor secondProcessor = new SecondService.Processor(secondHandler); // Protocol factory TProtocolFactory tProtocolFactory = null; if (protocol_type.equals("json") || protocol_type.equals("multij")) { tProtocolFactory = new TJSONProtocol.Factory(); } else if (protocol_type.equals("compact") || protocol_type.equals("multic")) { tProtocolFactory = new TCompactProtocol.Factory(string_limit, container_limit); } else { // also covers multi tProtocolFactory = new TBinaryProtocol.Factory(string_limit, container_limit); } TTransportFactory tTransportFactory = null; if (transport_type.equals("framed")) { tTransportFactory = new TFramedTransport.Factory(); } else if (transport_type.equals("fastframed")) { tTransportFactory = new TFastFramedTransport.Factory(); } else if (transport_type.equals("zlib")) { tTransportFactory = new TZlibTransport.Factory(); } else { // .equals("buffered") => default value tTransportFactory = new TTransportFactory(); } TServer serverEngine = null; // If we are multiplexing services in one server... TMultiplexedProcessor multiplexedProcessor = new TMultiplexedProcessor(); multiplexedProcessor.registerDefault(testProcessor); multiplexedProcessor.registerProcessor("ThriftTest", testProcessor); multiplexedProcessor.registerProcessor("SecondService", secondProcessor); if (server_type.equals("nonblocking") || server_type.equals("threaded-selector")) { // Nonblocking servers TNonblockingServerSocket tNonblockingServerSocket = new TNonblockingServerSocket( new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs().port(port)); if (server_type.contains("nonblocking")) { // Nonblocking Server TNonblockingServer.Args tNonblockingServerArgs = new TNonblockingServer.Args(tNonblockingServerSocket); tNonblockingServerArgs.processor( protocol_type.startsWith("multi") ? multiplexedProcessor : testProcessor); tNonblockingServerArgs.protocolFactory(tProtocolFactory); tNonblockingServerArgs.transportFactory(tTransportFactory); serverEngine = new TNonblockingServer(tNonblockingServerArgs); } else { // server_type.equals("threaded-selector") // ThreadedSelector Server TThreadedSelectorServer.Args tThreadedSelectorServerArgs = new TThreadedSelectorServer.Args(tNonblockingServerSocket); tThreadedSelectorServerArgs.processor( protocol_type.startsWith("multi") ? multiplexedProcessor : testProcessor); tThreadedSelectorServerArgs.protocolFactory(tProtocolFactory); tThreadedSelectorServerArgs.transportFactory(tTransportFactory); serverEngine = new TThreadedSelectorServer(tThreadedSelectorServerArgs); } } else { // Blocking servers // SSL socket TServerSocket tServerSocket = null; if (ssl) { tServerSocket = TSSLTransportFactory.getServerSocket(port, 0); } else { tServerSocket = new TServerSocket(new TServerSocket.ServerSocketTransportArgs().port(port)); } if (server_type.equals("simple")) { // Simple Server TServer.Args tServerArgs = new TServer.Args(tServerSocket); tServerArgs.processor( protocol_type.startsWith("multi") ? multiplexedProcessor : testProcessor); tServerArgs.protocolFactory(tProtocolFactory); tServerArgs.transportFactory(tTransportFactory); serverEngine = new TSimpleServer(tServerArgs); } else { // server_type.equals("threadpool") // ThreadPool Server TThreadPoolServer.Args tThreadPoolServerArgs = new TThreadPoolServer.Args(tServerSocket); tThreadPoolServerArgs.processor( protocol_type.startsWith("multi") ? multiplexedProcessor : testProcessor); tThreadPoolServerArgs.protocolFactory(tProtocolFactory); tThreadPoolServerArgs.transportFactory(tTransportFactory); serverEngine = new TThreadPoolServer(tThreadPoolServerArgs); } } // Set server event handler serverEngine.setServerEventHandler(new TestServerEventHandler()); // Run it System.out.println( "Starting the " + (ssl ? "ssl server" : "server") + " [" + protocol_type + "/" + transport_type + "/" + server_type + "] on " + ((domain_socket == "") ? ("port " + port) : ("unix socket " + domain_socket))); serverEngine.serve(); } catch (Exception x) { x.printStackTrace(); } System.out.println("done."); } } thrift-0.23.0/lib/java/src/crossTest/java/org/apache/thrift/test/TestNonblockingClient.java0000664000175000017500000011320715167543515032162 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.CountDownLatch; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.async.AsyncMethodCallback; import org.apache.thrift.async.TAsyncClientManager; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.protocol.TSimpleJSONProtocol; import org.apache.thrift.transport.TNonblockingSocket; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TSSLTransportFactory; import thrift.test.Insanity; import thrift.test.Numberz; import thrift.test.SecondService; import thrift.test.ThriftTest; import thrift.test.Xception; import thrift.test.Xception2; import thrift.test.Xtruct; import thrift.test.Xtruct2; public class TestNonblockingClient extends TestClient { private static String host = "localhost"; private static int port = 9090; private static int socketTimeout = 1000; private static String protocol_type = "binary"; private static boolean ssl = false; private static CountDownLatch latch; private static int returnCode = 0; private static ThriftTest.AsyncClient testClient; private static TAsyncClientManager clientManager; public static void main(String[] args) { int numTests = 1; try { for (int i = 0; i < args.length; ++i) { if (args[i].startsWith("--host")) { host = args[i].split("=")[1]; host.trim(); } else if (args[i].startsWith("--port")) { port = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].startsWith("--n") || args[i].startsWith("--testloops")) { numTests = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].equals("--timeout")) { socketTimeout = Integer.valueOf(args[i].split("=")[1]); } else if (args[i].startsWith("--protocol")) { protocol_type = args[i].split("=")[1]; protocol_type.trim(); } else if (args[i].equals("--ssl")) { ssl = true; } else if (args[i].equals("--help")) { System.out.println("Allowed options:"); System.out.println(" --help\t\t\tProduce help message"); System.out.println(" --host=arg (=" + host + ")\tHost to connect"); System.out.println(" --port=arg (=" + port + ")\tPort number to connect"); System.out.println( " --protocol=arg (=" + protocol_type + ")\tProtocol: binary, compact, json"); System.out.println(" --ssl\t\t\tEncrypted Transport using SSL"); System.out.println(" --testloops[--n]=arg (=" + numTests + ")\tNumber of Tests"); System.exit(0); } } } catch (Exception x) { System.err.println("Can not parse arguments! See --help"); System.exit(ERR_UNKNOWN); } try { if (protocol_type.equals("binary")) { } else if (protocol_type.equals("compact")) { } else if (protocol_type.equals("json")) { } else if (protocol_type.equals("multi")) { } else if (protocol_type.equals("multic")) { } else if (protocol_type.equals("multij")) { } else { throw new Exception("Unknown protocol type! " + protocol_type); } } catch (Exception e) { System.err.println("Error: " + e.getMessage()); System.exit(ERR_UNKNOWN); } try { clientManager = new TAsyncClientManager(); } catch (Exception e) { System.err.println("Error: " + e.getMessage()); System.exit(ERR_UNKNOWN); } testClient = getClient(); Insanity insane = new Insanity(); long timeMin = 0; long timeMax = 0; long timeTot = 0; for (int test = 0; test < numTests; ++test) { try { long start = System.nanoTime(); /** VOID TEST */ System.out.print("testVoid()"); latch = new CountDownLatch(1); testClient.testVoid( new AsyncMethodCallback() { @Override public void onComplete(Void response) { System.out.print(" = void\n"); latch.countDown(); } @Override public void onError(Exception exception) { exception.printStackTrace(); returnCode |= ERR_BASETYPES; latch.countDown(); } }); latch.await(); /** STRING TEST */ System.out.print("testString(\"Test\")"); latch = new CountDownLatch(1); testClient.testString( "Test", new FailureLessCallback() { @Override public void onComplete(String s) { System.out.print(" = \"" + s + "\"\n"); if (!s.equals("Test")) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** UUID TEST */ System.out.println("testUuid(\"00112233-4455-6677-8899-aabbccddeeff\")"); latch = new CountDownLatch(1); testClient.testUuid( UUID.fromString("00112233-4455-6677-8899-aabbccddeeff"), new FailureLessCallback() { @Override public void onComplete(UUID uuid) { System.out.print(" = \"" + uuid + "\"\n"); if (!uuid.equals(UUID.fromString("00112233-4455-6677-8899-aabbccddeeff"))) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** Multiplexed test */ if (protocol_type.startsWith("multi")) { latch = new CountDownLatch(1); SecondService.AsyncClient secondClient = getSecondServiceClient(); System.out.print("secondtestString(\"Test2\")"); secondClient.secondtestString( "Test2", new FailureLessCallback() { @Override public void onComplete(String s) { System.out.print(" = \"" + s + "\"\n"); if (!s.equals("testString(\"Test2\")")) { returnCode |= ERR_PROTOCOLS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); } /** BYTE TEST */ System.out.print("testByte(1)"); latch = new CountDownLatch(1); testClient.testByte( (byte) 1, new FailureLessCallback() { @Override public void onComplete(Byte i8) { System.out.print(" = " + i8 + "\n"); if (i8 != 1) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** I32 TEST */ System.out.print("testI32(-1)"); latch = new CountDownLatch(1); testClient.testI32( -1, new FailureLessCallback() { @Override public void onComplete(Integer i32) { System.out.print(" = " + i32 + "\n"); if (i32 != -1) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** I64 TEST */ System.out.print("testI64(-34359738368)"); latch = new CountDownLatch(1); testClient.testI64( -34359738368L, new FailureLessCallback() { @Override public void onComplete(Long i64) { System.out.print(" = " + i64 + "\n"); if (i64 != -34359738368L) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** DOUBLE TEST */ System.out.print("testDouble(-5.325098235)"); latch = new CountDownLatch(1); testClient.testDouble( -5.325098235, new FailureLessCallback() { @Override public void onComplete(Double dub) { System.out.print(" = " + dub + "\n"); if (Math.abs(dub - (-5.325098235)) > 0.001) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** BINARY TEST */ System.out.print("testBinary(-128...127) = "); byte[] data = getBytesData(); latch = new CountDownLatch(1); testClient.testBinary( ByteBuffer.wrap(data), new AsyncMethodCallback() { @Override public void onComplete(ByteBuffer bin) { bin.mark(); byte[] bytes = new byte[bin.limit() - bin.position()]; bin.get(bytes); bin.reset(); System.out.print("{"); boolean first = true; for (int i = 0; i < bytes.length; ++i) { if (first) first = false; else System.out.print(", "); System.out.print(bytes[i]); } System.out.println("}"); if (!ByteBuffer.wrap(data).equals(bin)) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } @Override public void onError(Exception ex) { returnCode |= ERR_BASETYPES; System.out.println("\n*** FAILURE ***\n"); ex.printStackTrace(System.out); latch.countDown(); } }); latch.await(); /** STRUCT TEST */ System.out.print("testStruct({\"Zero\", 1, -3, -5})"); Xtruct out = new Xtruct(); out.string_thing = "Zero"; out.byte_thing = (byte) 1; out.i32_thing = -3; out.i64_thing = -5; final Xtruct[] in = {null}; latch = new CountDownLatch(1); testClient.testStruct( out, new FailureLessCallback() { @Override public void onComplete(Xtruct response) { in[0] = response; System.out.print( " = {" + "\"" + in[0].string_thing + "\"," + in[0].byte_thing + ", " + in[0].i32_thing + ", " + in[0].i64_thing + "}\n"); if (!in[0].equals(out)) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** NESTED STRUCT TEST */ System.out.print("testNest({1, {\"Zero\", 1, -3, -5}), 5}"); Xtruct2 out2 = new Xtruct2(); out2.byte_thing = (short) 1; out2.struct_thing = out; out2.i32_thing = 5; latch = new CountDownLatch(1); testClient.testNest( out2, new FailureLessCallback() { @Override public void onComplete(Xtruct2 in2) { in[0] = in2.struct_thing; System.out.print( " = {" + in2.byte_thing + ", {" + "\"" + in[0].string_thing + "\", " + in[0].byte_thing + ", " + in[0].i32_thing + ", " + in[0].i64_thing + "}, " + in2.i32_thing + "}\n"); if (!in2.equals(out2)) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** MAP TEST */ Map mapout = new HashMap(); for (int i = 0; i < 5; ++i) { mapout.put(i, i - 10); } System.out.print("testMap({"); final boolean[] first = {true}; for (int key : mapout.keySet()) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(key + " => " + mapout.get(key)); } System.out.print("})"); latch = new CountDownLatch(1); testClient.testMap( mapout, new FailureLessCallback>() { @Override public void onComplete(Map mapin) { System.out.print(" = {"); first[0] = true; for (int key : mapin.keySet()) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(key + " => " + mapout.get(key)); } System.out.print("}\n"); if (!mapout.equals(mapin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** STRING MAP TEST */ Map smapout = new HashMap(); smapout.put("a", "2"); smapout.put("b", "blah"); smapout.put("some", "thing"); for (String key : smapout.keySet()) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(key + " => " + smapout.get(key)); } System.out.print("})"); latch = new CountDownLatch(1); testClient.testStringMap( smapout, new AsyncMethodCallback>() { @Override public void onComplete(Map smapin) { System.out.print(" = {"); first[0] = true; for (String key : smapin.keySet()) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(key + " => " + smapout.get(key)); } System.out.print("}\n"); if (!smapout.equals(smapin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } @Override public void onError(Exception ex) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); ex.printStackTrace(System.out); latch.countDown(); } }); latch.await(); /** SET TEST */ Set setout = new HashSet(); for (int i = -2; i < 3; ++i) { setout.add(i); } System.out.print("testSet({"); first[0] = true; for (int elem : setout) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})"); latch = new CountDownLatch(1); testClient.testSet( setout, new FailureLessCallback>() { @Override public void onComplete(Set setin) { System.out.print(" = {"); first[0] = true; for (int elem : setin) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("}\n"); if (!setout.equals(setin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** LIST TEST */ List listout = new ArrayList(); for (int i = -2; i < 3; ++i) { listout.add(i); } System.out.print("testList({"); first[0] = true; for (int elem : listout) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})"); latch = new CountDownLatch(1); testClient.testList( listout, new FailureLessCallback>() { @Override public void onComplete(List listin) { System.out.print(" = {"); first[0] = true; for (int elem : listin) { if (first[0]) { first[0] = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("}\n"); if (!listout.equals(listin)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** ENUM TEST */ System.out.print("testEnum(ONE)"); latch = new CountDownLatch(1); testClient.testEnum( Numberz.ONE, new FailureLessCallback() { @Override public void onComplete(Numberz ret) { System.out.print(" = " + ret + "\n"); if (ret != Numberz.ONE) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); System.out.print("testEnum(TWO)"); latch = new CountDownLatch(1); testClient.testEnum( Numberz.TWO, new FailureLessCallback() { @Override public void onComplete(Numberz ret) { System.out.print(" = " + ret + "\n"); if (ret != Numberz.TWO) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); System.out.print("testEnum(THREE)"); latch = new CountDownLatch(1); testClient.testEnum( Numberz.THREE, new FailureLessCallback() { @Override public void onComplete(Numberz ret) { System.out.print(" = " + ret + "\n"); if (ret != Numberz.THREE) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); System.out.print("testEnum(FIVE)"); latch = new CountDownLatch(1); testClient.testEnum( Numberz.FIVE, new FailureLessCallback() { @Override public void onComplete(Numberz ret) { System.out.print(" = " + ret + "\n"); if (ret != Numberz.FIVE) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); System.out.print("testEnum(EIGHT)"); latch = new CountDownLatch(1); testClient.testEnum( Numberz.EIGHT, new FailureLessCallback() { @Override public void onComplete(Numberz ret) { System.out.print(" = " + ret + "\n"); if (ret != Numberz.EIGHT) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** TYPEDEF TEST */ System.out.print("testTypedef(309858235082523)"); latch = new CountDownLatch(1); testClient.testTypedef( 309858235082523L, new FailureLessCallback() { @Override public void onComplete(Long uid) { System.out.print(" = " + uid + "\n"); if (uid != 309858235082523L) { returnCode |= ERR_BASETYPES; System.out.println("*** FAILURE ***\n"); } latch.countDown(); } }); latch.await(); /** NESTED MAP TEST */ System.out.print("testMapMap(1)"); latch = new CountDownLatch(1); testClient.testMapMap( 1, new FailureLessCallback>>() { @Override public void onComplete(Map> mm) { System.out.print(" = {"); for (int key : mm.keySet()) { System.out.print(key + " => {"); Map m2 = mm.get(key); for (int k2 : m2.keySet()) { System.out.print(k2 + " => " + m2.get(k2) + ", "); } System.out.print("}, "); } System.out.print("}\n"); if (mm.size() != 2 || !mm.containsKey(4) || !mm.containsKey(-4)) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } else { Map m1 = mm.get(4); Map m2 = mm.get(-4); if (m1.get(1) != 1 || m1.get(2) != 2 || m1.get(3) != 3 || m1.get(4) != 4 || m2.get(-1) != -1 || m2.get(-2) != -2 || m2.get(-3) != -3 || m2.get(-4) != -4) { returnCode |= ERR_CONTAINERS; System.out.println("*** FAILURE ***\n"); } } latch.countDown(); } }); latch.await(); /** INSANITY TEST */ final boolean[] insanityFailed = {true}; Xtruct hello = new Xtruct(); hello.string_thing = "Hello2"; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = 2; Xtruct goodbye = new Xtruct(); goodbye.string_thing = "Goodbye4"; goodbye.byte_thing = (byte) 4; goodbye.i32_thing = 4; goodbye.i64_thing = (long) 4; insane.userMap = new HashMap(); insane.userMap.put(Numberz.EIGHT, (long) 8); insane.userMap.put(Numberz.FIVE, (long) 5); insane.xtructs = new ArrayList(); insane.xtructs.add(goodbye); insane.xtructs.add(hello); System.out.print("testInsanity()"); latch = new CountDownLatch(1); testClient.testInsanity( insane, new AsyncMethodCallback>>() { @Override public void onComplete(Map> whoa) { System.out.print(" = {"); for (long key : whoa.keySet()) { Map val = whoa.get(key); System.out.print(key + " => {"); for (Numberz k2 : val.keySet()) { Insanity v2 = val.get(k2); System.out.print(k2 + " => {"); Map userMap = v2.userMap; System.out.print("{"); if (userMap != null) { for (Numberz k3 : userMap.keySet()) { System.out.print(k3 + " => " + userMap.get(k3) + ", "); } } System.out.print("}, "); List xtructs = v2.xtructs; System.out.print("{"); if (xtructs != null) { for (Xtruct x : xtructs) { System.out.print( "{" + "\"" + x.string_thing + "\", " + x.byte_thing + ", " + x.i32_thing + ", " + x.i64_thing + "}, "); } } System.out.print("}"); System.out.print("}, "); } System.out.print("}, "); } System.out.print("}\n"); if (whoa.size() == 2 && whoa.containsKey(1L) && whoa.containsKey(2L)) { Map first_map = whoa.get(1L); Map second_map = whoa.get(2L); if (first_map.size() == 2 && first_map.containsKey(Numberz.TWO) && first_map.containsKey(Numberz.THREE) && second_map.size() == 1 && second_map.containsKey(Numberz.SIX) && insane.equals(first_map.get(Numberz.TWO)) && insane.equals(first_map.get(Numberz.THREE))) { Insanity six = second_map.get(Numberz.SIX); // Cannot use "new Insanity().equals(six)" because as of now, struct/container // fields with default requiredness have isset=false for local instances and yet // received empty values from other languages like C++ have isset=true . if (six.getUserMapSize() == 0 && six.getXtructsSize() == 0) { // OK insanityFailed[0] = false; } } } latch.countDown(); } @Override public void onError(Exception ex) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); ex.printStackTrace(System.out); insanityFailed[0] = false; latch.countDown(); } }); latch.await(); if (insanityFailed[0]) { returnCode |= ERR_STRUCTS; System.out.println("*** FAILURE ***\n"); } /** EXECPTION TEST */ System.out.print("testClient.testException(\"Xception\") =>"); latch = new CountDownLatch(1); testClient.testException( "Xception", new AsyncMethodCallback() { @Override public void onComplete(Void response) { System.out.print(" void\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; latch.countDown(); } @Override public void onError(Exception exception) { if (exception instanceof Xception) { Xception e = (Xception) exception; System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message); } testClient = getClient(); latch.countDown(); } }); latch.await(); System.out.print("testClient.testException(\"TException\") =>"); latch = new CountDownLatch(1); testClient.testException( "TException", new AsyncMethodCallback() { @Override public void onComplete(Void response) { System.out.print(" void\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; latch.countDown(); } @Override public void onError(Exception exception) { if (exception instanceof TException) { TException e = (TException) exception; System.out.printf(" {\"%s\"}\n", e.getMessage()); } testClient = getClient(); latch.countDown(); } }); latch.await(); System.out.print("testClient.testException(\"success\") =>"); latch = new CountDownLatch(1); testClient.testException( "success", new AsyncMethodCallback() { @Override public void onComplete(Void response) { System.out.print(" void\n"); latch.countDown(); } @Override public void onError(Exception exception) { System.out.printf(" exception\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; latch.countDown(); } }); latch.await(); /** MULTI EXCEPTION TEST */ System.out.printf("testClient.testMultiException(\"Xception\", \"test 1\") =>"); latch = new CountDownLatch(1); testClient.testMultiException( "Xception", "test 1", new AsyncMethodCallback() { @Override public void onComplete(Xtruct response) { System.out.print(" result\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; latch.countDown(); } @Override public void onError(Exception exception) { if (exception instanceof Xception) { Xception e = (Xception) exception; System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message); } testClient = getClient(); latch.countDown(); } }); latch.await(); System.out.printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>"); latch = new CountDownLatch(1); testClient.testMultiException( "Xception2", "test 2", new AsyncMethodCallback() { @Override public void onComplete(Xtruct response) { System.out.print(" result\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; latch.countDown(); } @Override public void onError(Exception exception) { if (exception instanceof Xception2) { Xception2 e = (Xception2) exception; System.out.printf(" {%d, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing); } testClient = getClient(); latch.countDown(); } }); latch.await(); System.out.print("testClient.testMultiException(\"success\", \"test 3\") =>"); latch = new CountDownLatch(1); testClient.testMultiException( "success", "test 3", new AsyncMethodCallback() { @Override public void onComplete(Xtruct result) { System.out.printf(" {{\"%s\"}}\n", result.string_thing); latch.countDown(); } @Override public void onError(Exception exception) { System.out.printf(" exception\n*** FAILURE ***\n"); returnCode |= ERR_EXCEPTIONS; latch.countDown(); } }); latch.await(); /** ONEWAY TEST */ System.out.print("testOneway(3)..."); long startOneway = System.nanoTime(); latch = new CountDownLatch(1); testClient.testOneway( 3, new FailureLessCallback() { @Override public void onComplete(Void response) { long onewayElapsedMillis = (System.nanoTime() - startOneway) / 1000000; if (onewayElapsedMillis > 200) { System.out.println( "Oneway test took too long to execute failed: took " + onewayElapsedMillis + "ms"); System.out.println( "oneway calls are 'fire and forget' and therefore should not cause blocking."); System.out.println( "Some transports (HTTP) have a required response, and typically this failure"); System.out.println( "means the transport response was delayed until after the execution"); System.out.println( "of the RPC. The server should post the transport response immediately and"); System.out.println("before executing the RPC."); System.out.println("*** FAILURE ***"); returnCode |= ERR_BASETYPES; } else { System.out.println( "Success - fire and forget only took " + onewayElapsedMillis + "ms"); } latch.countDown(); } }); latch.await(); long stop = System.nanoTime(); long tot = stop - start; System.out.println("Total time: " + tot / 1000 + "us"); if (timeMin == 0 || tot < timeMin) { timeMin = tot; } if (tot > timeMax) { timeMax = tot; } timeTot += tot; clientManager.stop(); } catch (Exception x) { System.out.printf("*** FAILURE ***\n"); x.printStackTrace(); returnCode |= ERR_UNKNOWN; } } long timeAvg = timeTot / numTests; System.out.println("Min time: " + timeMin / 1000 + "us"); System.out.println("Max time: " + timeMax / 1000 + "us"); System.out.println("Avg time: " + timeAvg / 1000 + "us"); try { String json = (new TSerializer(new TSimpleJSONProtocol.Factory())).toString(insane); System.out.println("\nSample TSimpleJSONProtocol output:\n" + json); } catch (TException x) { System.out.println("*** FAILURE ***"); x.printStackTrace(); returnCode |= ERR_BASETYPES; } System.exit(returnCode); } private static ThriftTest.AsyncClient getClient() { return new ThriftTest.AsyncClient(getProtocolFactory(), clientManager, getTransport()); } private static SecondService.AsyncClient getSecondServiceClient() { return new SecondService.AsyncClient(getProtocolFactory(), clientManager, getTransport()); } private static TProtocolFactory getProtocolFactory() { TProtocolFactory tProtocolFactory; if (protocol_type.equals("json") || protocol_type.equals("multij")) { tProtocolFactory = new TJSONProtocol.Factory(); } else if (protocol_type.equals("compact") || protocol_type.equals("multic")) { tProtocolFactory = new TCompactProtocol.Factory(); } else { tProtocolFactory = new TBinaryProtocol.Factory(); } return tProtocolFactory; } private static TNonblockingTransport getTransport() { TNonblockingTransport transport = null; try { if (ssl) { transport = TSSLTransportFactory.getNonblockingClientSocket(host, port, socketTimeout); } else { transport = new TNonblockingSocket(host, port, socketTimeout); } } catch (Exception x) { x.printStackTrace(); System.exit(ERR_UNKNOWN); } return transport; } private abstract static class FailureLessCallback implements AsyncMethodCallback { @Override public void onError(Exception exception) { latch.countDown(); } } } thrift-0.23.0/lib/java/src/crossTest/java/org/apache/thrift/test/TestNonblockingServer.java0000664000175000017500000000467415165535636032224 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import org.apache.thrift.server.ServerTestBase.TestHandler; import org.apache.thrift.server.THsHaServer; import org.apache.thrift.server.THsHaServer.Args; import org.apache.thrift.server.TNonblockingServer; import org.apache.thrift.server.TServer; import org.apache.thrift.transport.TNonblockingServerSocket; import thrift.test.ThriftTest; public class TestNonblockingServer extends TestServer { public static void main(String[] args) { try { int port = 9090; boolean hsha = false; for (int i = 0; i < args.length; i++) { if (args[i].equals("-p")) { port = Integer.valueOf(args[i++]); } else if (args[i].equals("-hsha")) { hsha = true; } } // @TODO add other protocol and transport types // Processor TestHandler testHandler = new TestHandler(); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); // Transport TNonblockingServerSocket tServerSocket = new TNonblockingServerSocket( new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs().port(port)); TServer serverEngine; if (hsha) { // HsHa Server serverEngine = new THsHaServer(new Args(tServerSocket).processor(testProcessor)); } else { // Nonblocking Server serverEngine = new TNonblockingServer(new Args(tServerSocket).processor(testProcessor)); } // Run it System.out.println("Starting the server on port " + port + "..."); serverEngine.serve(); } catch (Exception x) { x.printStackTrace(); } System.out.println("done."); } } thrift-0.23.0/lib/java/src/crossTest/java/org/apache/thrift/test/TestTServletServer.java0000664000175000017500000000364615165535636031527 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.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; /** run tomcat for test TServlet */ public class TestTServletServer { static final int port = 9090; public static void main(String[] args) throws Exception { Tomcat tomcat = new Tomcat(); 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"; StandardContext context = new StandardContext(); context.setPath(contextPath); context.addLifecycleListener(new FixContextListener()); tomcat.getHost().addChild(context); tomcat.addServlet(contextPath, "testServlet", new TestServlet()); context.addServletMappingDecoded("/service", "testServlet"); tomcat.start(); tomcat.getServer().await(); } } thrift-0.23.0/lib/java/src/main/0000775000175000017500000000000015165535636016577 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/0000775000175000017500000000000015165535636017520 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/0000775000175000017500000000000015165535636020307 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/0000775000175000017500000000000015165535636021530 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/0000775000175000017500000000000015167543515023025 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TApplicationException.java0000664000175000017500000001053315165535636030143 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TStruct; import org.apache.thrift.protocol.TType; /** Application level exception */ public class TApplicationException extends TException implements TSerializable { private static final TStruct TAPPLICATION_EXCEPTION_STRUCT = new TStruct("TApplicationException"); private static final TField MESSAGE_FIELD = new TField("message", TType.STRING, (short) 1); private static final TField TYPE_FIELD = new TField("type", TType.I32, (short) 2); private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int UNKNOWN_METHOD = 1; public static final int INVALID_MESSAGE_TYPE = 2; public static final int WRONG_METHOD_NAME = 3; public static final int BAD_SEQUENCE_ID = 4; public static final int MISSING_RESULT = 5; public static final int INTERNAL_ERROR = 6; public static final int PROTOCOL_ERROR = 7; public static final int INVALID_TRANSFORM = 8; public static final int INVALID_PROTOCOL = 9; public static final int UNSUPPORTED_CLIENT_TYPE = 10; protected int type_ = UNKNOWN; private String message_ = null; public TApplicationException() { super(); } public TApplicationException(int type) { super(); type_ = type; } public TApplicationException(int type, String message) { super(message); type_ = type; } public TApplicationException(String message) { super(message); } public int getType() { return type_; } @Override public String getMessage() { if (message_ == null) { return super.getMessage(); } else { return message_; } } public void read(TProtocol iprot) throws TException { TField field; iprot.readStructBegin(); String message = null; int type = UNKNOWN; while (true) { field = iprot.readFieldBegin(); if (field.type == TType.STOP) { break; } switch (field.id) { case 1: if (field.type == TType.STRING) { message = iprot.readString(); } else { TProtocolUtil.skip(iprot, field.type); } break; case 2: if (field.type == TType.I32) { type = iprot.readI32(); } else { TProtocolUtil.skip(iprot, field.type); } break; default: TProtocolUtil.skip(iprot, field.type); break; } iprot.readFieldEnd(); } iprot.readStructEnd(); type_ = type; message_ = message; } /** * Convenience factory method for constructing a TApplicationException given a TProtocol input * * @param iprot protocol from which an instance of TApplicationException is read. * @return an instance of TApplicationException read from iprot. * @throws TException if there is an error reading from iprot. */ public static TApplicationException readFrom(TProtocol iprot) throws TException { TApplicationException result = new TApplicationException(); result.read(iprot); return result; } public void write(TProtocol oprot) throws TException { oprot.writeStructBegin(TAPPLICATION_EXCEPTION_STRUCT); if (getMessage() != null) { oprot.writeFieldBegin(MESSAGE_FIELD); oprot.writeString(getMessage()); oprot.writeFieldEnd(); } oprot.writeFieldBegin(TYPE_FIELD); oprot.writeI32(type_); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TEnum.java0000664000175000017500000000155615165535636024732 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; public interface TEnum { int getValue(); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TServiceClientFactory.java0000664000175000017500000000337515165535636030116 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * A TServiceClientFactory provides a general way to get a TServiceClient connected to a remote * TService via a protocol. * * @param the type of TServiceClient to get. */ public interface TServiceClientFactory { /** * Get a brand-new T using prot as both the input and output protocol. * * @param prot The protocol to use for getting T. * @return A brand-new T using prot as both the input and output protocol. */ T getClient(TProtocol prot); /** * Get a brand new T using the specified input and output protocols. The input and output * protocols may be the same instance. * * @param iprot The input protocol to use for getting T. * @param oprot The output protocol to use for getting T. * @return a brand new T using the specified input and output protocols */ T getClient(TProtocol iprot, TProtocol oprot); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/THttpClientResponseHandler.java0000664000175000017500000000471615165535636031122 0ustar00buildbuild00000000000000package org.apache.thrift; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.io.HttpClientResponseHandler; public class THttpClientResponseHandler implements HttpClientResponseHandler { @Override public InputStream handleResponse(ClassicHttpResponse response) throws HttpException, IOException { try (InputStream is = response.getEntity().getContent()) { int responseCode = response.getCode(); if (responseCode != HttpStatus.SC_OK) { throw new IOException("HTTP Response code: " + responseCode); } byte[] readByteArray = readIntoByteArray(is); try { // Indicate we're done with the content. consume(response.getEntity()); } catch (IOException ioe) { // We ignore this exception, it might only mean the server has no // keep-alive capability. } return new ByteArrayInputStream(readByteArray); } catch (IOException ioe) { throw ioe; } } /** * Read the responses into a byte array so we can release the connection early. This implies that * the whole content will have to be read in memory, and that momentarily we might use up twice * the memory (while the thrift struct is being read up the chain). Proceeding differently might * lead to exhaustion of connections and thus to app failure. * * @param is input stream * @return read bytes * @throws IOException when exception during read */ private static byte[] readIntoByteArray(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len; do { len = is.read(buf); if (len > 0) { baos.write(buf, 0, len); } } while (-1 != len); return baos.toByteArray(); } /** * copy from org.apache.http.util.EntityUtils#consume. Android has it's own httpcore that doesn't * have a consume. */ private static void consume(final HttpEntity entity) throws IOException { if (entity == null) { return; } if (entity.isStreaming()) { InputStream instream = entity.getContent(); if (instream != null) { instream.close(); } } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TUnion.java0000664000175000017500000002125215165535636025111 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolException; import org.apache.thrift.protocol.TStruct; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.SchemeFactory; import org.apache.thrift.scheme.StandardScheme; import org.apache.thrift.scheme.TupleScheme; public abstract class TUnion, F extends TFieldIdEnum> implements TBase { protected Object value_; protected F setField_; protected TUnion() { setField_ = null; value_ = null; } private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); static { schemes.put(StandardScheme.class, new TUnionStandardSchemeFactory()); schemes.put(TupleScheme.class, new TUnionTupleSchemeFactory()); } protected TUnion(F setField, Object value) { setFieldValue(setField, value); } protected TUnion(TUnion other) { if (!other.getClass().equals(this.getClass())) { throw new ClassCastException(); } setField_ = other.setField_; value_ = deepCopyObject(other.value_); } private static Object deepCopyObject(Object o) { if (o instanceof TBase) { return ((TBase) o).deepCopy(); } else if (o instanceof ByteBuffer) { return TBaseHelper.copyBinary((ByteBuffer) o); } else if (o instanceof List) { return deepCopyList((List) o); } else if (o instanceof Set) { return deepCopySet((Set) o); } else if (o instanceof Map) { return deepCopyMap((Map) o); } else { return o; } } private static Map deepCopyMap(Map map) { Map copy = new HashMap(map.size()); for (Map.Entry entry : map.entrySet()) { copy.put(deepCopyObject(entry.getKey()), deepCopyObject(entry.getValue())); } return copy; } private static Set deepCopySet(Set set) { Set copy = new HashSet(set.size()); for (Object o : set) { copy.add(deepCopyObject(o)); } return copy; } private static List deepCopyList(List list) { List copy = new ArrayList(list.size()); for (Object o : list) { copy.add(deepCopyObject(o)); } return copy; } public F getSetField() { return setField_; } public Object getFieldValue() { return value_; } public Object getFieldValue(F fieldId) { if (fieldId != setField_) { throw new IllegalArgumentException( "Cannot get the value of field " + fieldId + " because union's set field is " + setField_); } return getFieldValue(); } public Object getFieldValue(int fieldId) { return getFieldValue(enumForId((short) fieldId)); } public boolean isSet() { return setField_ != null; } public boolean isSet(F fieldId) { return setField_ == fieldId; } public boolean isSet(int fieldId) { return isSet(enumForId((short) fieldId)); } public void read(TProtocol iprot) throws TException { schemes.get(iprot.getScheme()).getScheme().read(iprot, this); } public void setFieldValue(F fieldId, Object value) { checkType(fieldId, value); setField_ = fieldId; value_ = value; } public void setFieldValue(int fieldId, Object value) { setFieldValue(enumForId((short) fieldId), value); } public void write(TProtocol oprot) throws TException { schemes.get(oprot.getScheme()).getScheme().write(oprot, this); } /** * Implementation should be generated so that we can efficiently type check various values. * * @param setField the field to assign value to. * @param value the value to be assigned to setField. * @throws ClassCastException if the type of value is incompatible with the type of setField. */ protected abstract void checkType(F setField, Object value) throws ClassCastException; /** * Implementation should be generated to read the right stuff from the wire based on the field * header. * * @param iprot input protocol from which to read a value. * @param field the field whose value is to be read from iprot. * @return read Object based on the field header, as specified by the argument. * @throws TException on error during read. */ protected abstract Object standardSchemeReadValue(TProtocol iprot, TField field) throws TException; protected abstract void standardSchemeWriteValue(TProtocol oprot) throws TException; protected abstract Object tupleSchemeReadValue(TProtocol iprot, short fieldID) throws TException; protected abstract void tupleSchemeWriteValue(TProtocol oprot) throws TException; protected abstract TStruct getStructDesc(); protected abstract TField getFieldDesc(F setField); protected abstract F enumForId(short id); @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("<"); sb.append(this.getClass().getSimpleName()); sb.append(" "); if (getSetField() != null) { Object v = getFieldValue(); sb.append(getFieldDesc(getSetField()).name); sb.append(":"); if (v instanceof ByteBuffer) { TBaseHelper.toString((ByteBuffer) v, sb); } else { sb.append(v.toString()); } } sb.append(">"); return sb.toString(); } public final void clear() { this.setField_ = null; this.value_ = null; } private static class TUnionStandardSchemeFactory implements SchemeFactory { public TUnionStandardScheme getScheme() { return new TUnionStandardScheme(); } } private static class TUnionStandardScheme extends StandardScheme { @Override public void read(TProtocol iprot, TUnion struct) throws TException { struct.setField_ = null; struct.value_ = null; iprot.readStructBegin(); TField field = iprot.readFieldBegin(); struct.value_ = struct.standardSchemeReadValue(iprot, field); if (struct.value_ != null) { struct.setField_ = struct.enumForId(field.id); } iprot.readFieldEnd(); // this is so that we will eat the stop byte. we could put a check here to // make sure that it actually *is* the stop byte, but it's faster to do it // this way. iprot.readFieldBegin(); iprot.readStructEnd(); } @Override public void write(TProtocol oprot, TUnion struct) throws TException { if (struct.getSetField() == null || struct.getFieldValue() == null) { throw new TProtocolException("Cannot write a TUnion with no set value!"); } oprot.writeStructBegin(struct.getStructDesc()); oprot.writeFieldBegin(struct.getFieldDesc(struct.setField_)); struct.standardSchemeWriteValue(oprot); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } } private static class TUnionTupleSchemeFactory implements SchemeFactory { public TUnionTupleScheme getScheme() { return new TUnionTupleScheme(); } } private static class TUnionTupleScheme extends TupleScheme { @Override public void read(TProtocol iprot, TUnion struct) throws TException { struct.setField_ = null; struct.value_ = null; short fieldID = iprot.readI16(); struct.value_ = struct.tupleSchemeReadValue(iprot, fieldID); if (struct.value_ != null) { struct.setField_ = struct.enumForId(fieldID); } } @Override public void write(TProtocol oprot, TUnion struct) throws TException { if (struct.getSetField() == null || struct.getFieldValue() == null) { throw new TProtocolException("Cannot write a TUnion with no set value!"); } oprot.writeI16(struct.setField_.getThriftFieldId()); struct.tupleSchemeWriteValue(oprot); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TAsyncProcessor.java0000664000175000017500000000234515165535636027000 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer; public interface TAsyncProcessor { /** * Process a single frame. * *

Note: Implementations must call fb.responseReady() once processing is complete * * @param fb the frame buffer to process. * @throws TException if the frame cannot be processed */ void process(final AsyncFrameBuffer fb) throws TException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TNonblockingMultiFetchClient.java0000664000175000017500000003211315165535636031406 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class uses a single thread to set up non-blocking sockets to a set of remote servers * (hostname and port pairs), and sends a same request to all these servers. It then fetches * responses from servers. * *

Parameters: int maxRecvBufBytesPerServer - an upper limit for receive buffer size per server * (in byte). If a response from a server exceeds this limit, the client will not allocate memory or * read response data for it. * *

int fetchTimeoutSeconds - time limit for fetching responses from all servers (in second). * After the timeout, the fetch job is stopped and available responses are returned. * *

ByteBuffer requestBuf - request message that is sent to all servers. * *

Output: Responses are stored in an array of ByteBuffers. Index of elements in this array * corresponds to index of servers in the server list. Content in a ByteBuffer may be in one of the * following forms: 1. First 4 bytes form an integer indicating length of following data, then * followed by the data. 2. First 4 bytes form an integer indicating length of following data, then * followed by nothing - this happens when the response data size exceeds maxRecvBufBytesPerServer, * and the client will not read any response data. 3. No data in the ByteBuffer - this happens when * the server does not return any response within fetchTimeoutSeconds. * *

In some special cases (no servers are given, fetchTimeoutSeconds less than or equal to 0, * requestBuf is null), the return is null. * *

Note: It assumes all remote servers are TNonblockingServers and use TFramedTransport. */ public class TNonblockingMultiFetchClient { private static final Logger LOGGER = LoggerFactory.getLogger(TNonblockingMultiFetchClient.class); // if the size of the response msg exceeds this limit (in byte), we will // not read the msg private final int maxRecvBufBytesPerServer; // time limit for fetching data from all servers (in second) private final int fetchTimeoutSeconds; // store request that will be sent to servers private final ByteBuffer requestBuf; private ByteBuffer requestBufDuplication; // a list of remote servers private final List servers; // store fetch results private final TNonblockingMultiFetchStats stats; private ByteBuffer[] recvBuf; public TNonblockingMultiFetchClient( int maxRecvBufBytesPerServer, int fetchTimeoutSeconds, ByteBuffer requestBuf, List servers) { this.maxRecvBufBytesPerServer = maxRecvBufBytesPerServer; this.fetchTimeoutSeconds = fetchTimeoutSeconds; this.requestBuf = requestBuf; this.servers = servers; stats = new TNonblockingMultiFetchStats(); recvBuf = null; } public synchronized int getMaxRecvBufBytesPerServer() { return maxRecvBufBytesPerServer; } public synchronized int getFetchTimeoutSeconds() { return fetchTimeoutSeconds; } /** * Returns a copy of requestBuf, so that requestBuf will not be modified by others. * * @return a copy of requestBuf. */ public synchronized ByteBuffer getRequestBuf() { if (requestBuf == null) { return null; } else { if (requestBufDuplication == null) { requestBufDuplication = requestBuf.duplicate(); } return requestBufDuplication; } } public synchronized List getServerList() { if (servers == null) { return null; } return Collections.unmodifiableList(servers); } public synchronized TNonblockingMultiFetchStats getFetchStats() { return stats; } /** * Main entry function for fetching from servers. * * @return The fetched data. */ public synchronized ByteBuffer[] fetch() { // clear previous results recvBuf = null; stats.clear(); if (servers == null || servers.size() == 0 || requestBuf == null || fetchTimeoutSeconds <= 0) { return recvBuf; } ExecutorService executor = Executors.newSingleThreadExecutor(); MultiFetch multiFetch = new MultiFetch(); FutureTask task = new FutureTask(multiFetch, null); executor.execute(task); try { task.get(fetchTimeoutSeconds, TimeUnit.SECONDS); } catch (InterruptedException ie) { // attempt to cancel execution of the task. task.cancel(true); LOGGER.error("Interrupted during fetch", ie); } catch (ExecutionException ee) { // attempt to cancel execution of the task. task.cancel(true); LOGGER.error("Exception during fetch", ee); } catch (TimeoutException te) { // attempt to cancel execution of the task. task.cancel(true); LOGGER.error("Timeout for fetch", te); } executor.shutdownNow(); multiFetch.close(); return recvBuf; } /** * Private class that does real fetch job. Users are not allowed to directly use this class, as * its run() function may run forever. */ private class MultiFetch implements Runnable { private Selector selector; /** * main entry function for fetching. * *

Server responses are stored in TNonblocingMultiFetchClient.recvBuf, and fetch statistics * is in TNonblockingMultiFetchClient.stats. * *

Sanity check for parameters has been done in TNonblockingMultiFetchClient before calling * this function. */ public void run() { long t1 = System.currentTimeMillis(); int numTotalServers = servers.size(); stats.setNumTotalServers(numTotalServers); // buffer for receiving response from servers recvBuf = new ByteBuffer[numTotalServers]; // buffer for sending request ByteBuffer[] sendBuf = new ByteBuffer[numTotalServers]; long[] numBytesRead = new long[numTotalServers]; int[] frameSize = new int[numTotalServers]; boolean[] hasReadFrameSize = new boolean[numTotalServers]; try { selector = Selector.open(); } catch (IOException ioe) { LOGGER.error("Selector opens error", ioe); return; } for (int i = 0; i < numTotalServers; i++) { // create buffer to send request to server. sendBuf[i] = requestBuf.duplicate(); // create buffer to read response's frame size from server recvBuf[i] = ByteBuffer.allocate(4); stats.incTotalRecvBufBytes(4); InetSocketAddress server = servers.get(i); SocketChannel s = null; SelectionKey key = null; try { s = SocketChannel.open(); s.configureBlocking(false); // now this method is non-blocking s.connect(server); key = s.register(selector, s.validOps()); // attach index of the key key.attach(i); } catch (Exception e) { stats.incNumConnectErrorServers(); LOGGER.error("Set up socket to server {} error", server, e); // free resource if (s != null) { try { s.close(); } catch (Exception ex) { LOGGER.error("failed to free up socket", ex); } } if (key != null) { key.cancel(); } } } // wait for events while (stats.getNumReadCompletedServers() + stats.getNumConnectErrorServers() < stats.getNumTotalServers()) { // if the thread is interrupted (e.g., task is cancelled) if (Thread.currentThread().isInterrupted()) { return; } try { selector.select(); } catch (Exception e) { LOGGER.error("Selector selects error", e); continue; } Iterator it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey selKey = it.next(); it.remove(); // get previously attached index int index = (Integer) selKey.attachment(); if (selKey.isValid() && selKey.isConnectable()) { // if this socket throws an exception (e.g., connection refused), // print error msg and skip it. try { SocketChannel sChannel = (SocketChannel) selKey.channel(); sChannel.finishConnect(); } catch (Exception e) { stats.incNumConnectErrorServers(); LOGGER.error("Socket {} connects to server {} error", index, servers.get(index), e); } } if (selKey.isValid() && selKey.isWritable() && sendBuf[index].hasRemaining()) { // if this socket throws an exception, print error msg and // skip it. try { SocketChannel sChannel = (SocketChannel) selKey.channel(); sChannel.write(sendBuf[index]); } catch (Exception e) { LOGGER.error("Socket {} writes to server {} error", index, servers.get(index), e); } } if (selKey.isValid() && selKey.isReadable()) { // if this socket throws an exception, print error msg and // skip it. try { SocketChannel sChannel = (SocketChannel) selKey.channel(); int bytesRead = sChannel.read(recvBuf[index]); if (bytesRead > 0) { numBytesRead[index] += bytesRead; if (!hasReadFrameSize[index] && recvBuf[index].remaining() == 0) { // if the frame size has been read completely, then prepare // to read the actual frame. frameSize[index] = recvBuf[index].getInt(0); if (frameSize[index] <= 0) { stats.incNumInvalidFrameSize(); LOGGER.error( "Read an invalid frame size {} from {}. Does the server use TFramedTransport?", frameSize[index], servers.get(index)); sChannel.close(); continue; } if (frameSize[index] + 4 > stats.getMaxResponseBytes()) { stats.setMaxResponseBytes(frameSize[index] + 4); } if (frameSize[index] + 4 > maxRecvBufBytesPerServer) { stats.incNumOverflowedRecvBuf(); LOGGER.error( "Read frame size {} from {}, total buffer size would exceed limit {}", frameSize[index], servers.get(index), maxRecvBufBytesPerServer); sChannel.close(); continue; } // reallocate buffer for actual frame data recvBuf[index] = ByteBuffer.allocate(frameSize[index] + 4); recvBuf[index].putInt(frameSize[index]); stats.incTotalRecvBufBytes(frameSize[index]); hasReadFrameSize[index] = true; } if (hasReadFrameSize[index] && numBytesRead[index] >= frameSize[index] + 4) { // has read all data sChannel.close(); stats.incNumReadCompletedServers(); long t2 = System.currentTimeMillis(); stats.setReadTime(t2 - t1); } } } catch (Exception e) { LOGGER.error("Socket {} reads from server {} error", index, servers.get(index), e); } } } } } /** dispose any resource allocated */ public void close() { try { if (selector.isOpen()) { for (SelectionKey selKey : selector.keys()) { SocketChannel sChannel = (SocketChannel) selKey.channel(); sChannel.close(); } selector.close(); } } catch (IOException e) { LOGGER.error("Free resource error", e); } } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TException.java0000664000175000017500000000231415165535636025755 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** Generic exception class for Thrift. */ public class TException extends Exception { private static final long serialVersionUID = 1L; public TException() { super(); } public TException(String message) { super(message); } public TException(Throwable cause) { super(cause); } public TException(String message, Throwable cause) { super(message, cause); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/annotation/0000775000175000017500000000000015165535636025202 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/annotation/Nullable.java0000664000175000017500000000222115165535636027600 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Annotation indicating a field, method return, or method parameter may be {@code null}. We package * our own annotation to avoid a mandatory third-party dependency. */ @Retention(RetentionPolicy.CLASS) public @interface Nullable {} thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TSerializer.java0000664000175000017500000000615515165535636026137 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayOutputStream; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransportException; /** Generic utility for easily serializing objects into a byte array or Java String. */ public class TSerializer { /** This is the byte array that data is actually serialized into */ private final ByteArrayOutputStream baos_ = new ByteArrayOutputStream(); /** Internal protocol used for serializing objects. */ private final TProtocol protocol_; /** * Create a new TSerializer that uses the TBinaryProtocol by default. * * @throws TTransportException if there an error initializing the underlying transport. */ public TSerializer() throws TTransportException { this(new TBinaryProtocol.Factory()); } /** * Create a new TSerializer. It will use the TProtocol specified by the factory that is passed in. * * @param protocolFactory Factory to create a protocol * @throws TTransportException if there is an error initializing the underlying transport. */ public TSerializer(TProtocolFactory protocolFactory) throws TTransportException { /* This transport wraps that byte array */ TIOStreamTransport transport_ = new TIOStreamTransport(new TConfiguration(), baos_); protocol_ = protocolFactory.getProtocol(transport_); } /** * Serialize the Thrift object into a byte array. The process is simple, just clear the byte array * output, write the object into it, and grab the raw bytes. * * @param base The object to serialize * @return Serialized object in byte[] format * @throws TException if an error is encountered during serialization. */ public byte[] serialize(TBase base) throws TException { baos_.reset(); base.write(protocol_); return baos_.toByteArray(); } /** * Serialize the Thrift object into a Java string, using the default JVM charset encoding. * * @param base The object to serialize * @return Serialized object as a String * @throws TException if an error is encountered during serialization. */ public String toString(TBase base) throws TException { return new String(serialize(base)); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TServiceClient.java0000664000175000017500000000571615165535636026567 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TMessageType; import org.apache.thrift.protocol.TProtocol; /** * A TServiceClient is used to communicate with a TService implementation across protocols and * transports. */ public abstract class TServiceClient { public TServiceClient(TProtocol prot) { this(prot, prot); } public TServiceClient(TProtocol iprot, TProtocol oprot) { iprot_ = iprot; oprot_ = oprot; } protected TProtocol iprot_; protected TProtocol oprot_; protected int seqid_; /** * Get the TProtocol being used as the input (read) protocol. * * @return the TProtocol being used as the input (read) protocol. */ public TProtocol getInputProtocol() { return this.iprot_; } /** * Get the TProtocol being used as the output (write) protocol. * * @return the TProtocol being used as the output (write) protocol. */ public TProtocol getOutputProtocol() { return this.oprot_; } protected void sendBase(String methodName, TBase args) throws TException { sendBase(methodName, args, TMessageType.CALL); } protected void sendBaseOneway(String methodName, TBase args) throws TException { sendBase(methodName, args, TMessageType.ONEWAY); } private void sendBase(String methodName, TBase args, byte type) throws TException { oprot_.writeMessageBegin(new TMessage(methodName, type, ++seqid_)); args.write(oprot_); oprot_.writeMessageEnd(); oprot_.getTransport().flush(); } protected void receiveBase(TBase result, String methodName) throws TException { TMessage msg = iprot_.readMessageBegin(); if (msg.type == TMessageType.EXCEPTION) { TApplicationException x = new TApplicationException(); x.read(iprot_); iprot_.readMessageEnd(); throw x; } if (msg.seqid != seqid_) { throw new TApplicationException( TApplicationException.BAD_SEQUENCE_ID, String.format( "%s failed: out of sequence response: expected %d but got %d", methodName, seqid_, msg.seqid)); } result.read(iprot_); iprot_.readMessageEnd(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TByteArrayOutputStream.java0000664000175000017500000000302415165535636030315 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayOutputStream; import java.nio.charset.Charset; /** Class that allows access to the underlying buf without doing deep copies on it. */ public class TByteArrayOutputStream extends ByteArrayOutputStream { private final int initialSize; public TByteArrayOutputStream(int size) { super(size); this.initialSize = size; } public TByteArrayOutputStream() { this(32); } public byte[] get() { return buf; } public void reset() { super.reset(); if (buf.length > initialSize) { buf = new byte[initialSize]; } } public int len() { return count; } public String toString(Charset charset) { return new String(buf, 0, count, charset); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/0000775000175000017500000000000015167543515024333 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TServlet.java0000664000175000017500000000670415165535636026760 0ustar00buildbuild00000000000000package org.apache.thrift.server; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; /** Servlet implementation class ThriftServer */ public class TServlet extends HttpServlet { private final TProcessor processor; private final TProtocolFactory inProtocolFactory; private final TProtocolFactory outProtocolFactory; private final Collection> customHeaders; /** * @see HttpServlet#HttpServlet() */ public TServlet( TProcessor processor, TProtocolFactory inProtocolFactory, TProtocolFactory outProtocolFactory) { super(); this.processor = processor; this.inProtocolFactory = inProtocolFactory; this.outProtocolFactory = outProtocolFactory; this.customHeaders = new ArrayList>(); } /** * @see HttpServlet#HttpServlet() */ public TServlet(TProcessor processor, TProtocolFactory protocolFactory) { this(processor, protocolFactory, protocolFactory); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { TTransport inTransport = null; TTransport outTransport = null; try { response.setContentType("application/x-thrift"); if (null != this.customHeaders) { for (Map.Entry header : this.customHeaders) { response.addHeader(header.getKey(), header.getValue()); } } InputStream in = request.getInputStream(); OutputStream out = response.getOutputStream(); TTransport transport = new TIOStreamTransport(in, out); inTransport = transport; outTransport = transport; TProtocol inProtocol = inProtocolFactory.getProtocol(inTransport); TProtocol outProtocol = outProtocolFactory.getProtocol(outTransport); processor.process(inProtocol, outProtocol); out.flush(); } catch (TException te) { throw new ServletException(te); } } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void addCustomHeader(final String key, final String value) { this.customHeaders.add( new Map.Entry() { @Override public String getKey() { return key; } @Override public String getValue() { return value; } @Override public String setValue(String value) { return null; } }); } public void setCustomHeaders(Collection> headers) { this.customHeaders.clear(); this.customHeaders.addAll(headers); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/AbstractNonblockingServer.java0000664000175000017500000005323615167543515032325 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.io.IOException; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.SelectorProvider; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import org.apache.thrift.TAsyncProcessor; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TException; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.SocketAddressProvider; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.layered.TFramedTransport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Provides common methods and classes used by nonblocking TServer implementations. */ public abstract class AbstractNonblockingServer extends TServer { protected final Logger LOGGER = LoggerFactory.getLogger(getClass().getName()); public abstract static class AbstractNonblockingServerArgs< T extends AbstractNonblockingServerArgs> extends AbstractServerArgs { public long maxReadBufferBytes = 256 * 1024 * 1024; public AbstractNonblockingServerArgs(TNonblockingServerTransport transport) { super(transport); transportFactory(new TFramedTransport.Factory()); } } /** * The maximum amount of memory we will allocate to client IO buffers at a time. Without this * limit, the server will gladly allocate client buffers right into an out of memory exception, * rather than waiting. */ final long MAX_READ_BUFFER_BYTES; /** How many bytes are currently allocated to read buffers. */ final AtomicLong readBufferBytesAllocated = new AtomicLong(0); public AbstractNonblockingServer(AbstractNonblockingServerArgs args) { super(args); MAX_READ_BUFFER_BYTES = args.maxReadBufferBytes; } /** Begin accepting connections and processing invocations. */ public void serve() { // start any IO threads if (!startThreads()) { return; } // start listening, or exit if (!startListening()) { return; } setServing(true); // this will block while we serve waitForShutdown(); setServing(false); // do a little cleanup stopListening(); } /** * Starts any threads required for serving. * * @return true if everything went ok, false if threads could not be started. */ protected abstract boolean startThreads(); /** A method that will block until when threads handling the serving have been shut down. */ protected abstract void waitForShutdown(); /** * Have the server transport start accepting connections. * * @return true if we started listening successfully, false if something went wrong. */ protected boolean startListening() { try { serverTransport_.listen(); return true; } catch (TTransportException ttx) { LOGGER.error("Failed to start listening on server socket!", ttx); return false; } } /** Stop listening for connections. */ protected void stopListening() { serverTransport_.close(); } /** * Perform an invocation. This method could behave several different ways - invoke immediately * inline, queue for separate execution, etc. * * @return true if invocation was successfully requested, which is not a guarantee that invocation * has completed. False if the request failed. */ protected abstract boolean requestInvoke(FrameBuffer frameBuffer); /** * An abstract thread that handles selecting on a set of transports and {@link FrameBuffer * FrameBuffers} associated with selected keys corresponding to requests. */ protected abstract class AbstractSelectThread extends Thread { protected Selector selector; // List of FrameBuffers that want to change their selection interests. protected final Set selectInterestChanges = new HashSet(); public AbstractSelectThread() throws IOException { this.selector = SelectorProvider.provider().openSelector(); } /** If the selector is blocked, wake it up. */ public void wakeupSelector() { selector.wakeup(); } /** * Add FrameBuffer to the list of select interest changes and wake up the selector if it's * blocked. When the select() call exits, it'll give the FrameBuffer a chance to change its * interests. */ public void requestSelectInterestChange(FrameBuffer frameBuffer) { synchronized (selectInterestChanges) { selectInterestChanges.add(frameBuffer); } // wakeup the selector, if it's currently blocked. selector.wakeup(); } /** * Check to see if there are any FrameBuffers that have switched their interest type from read * to write or vice versa. */ protected void processInterestChanges() { synchronized (selectInterestChanges) { for (FrameBuffer fb : selectInterestChanges) { fb.changeSelectInterests(); } selectInterestChanges.clear(); } } /** * Do the work required to read from a readable client. If the frame is fully read, then invoke * the method call. */ protected void handleRead(SelectionKey key) { FrameBuffer buffer = (FrameBuffer) key.attachment(); if (!buffer.read()) { cleanupSelectionKey(key); return; } // if the buffer's frame read is complete, invoke the method. if (buffer.isFrameFullyRead() && !requestInvoke(buffer)) { cleanupSelectionKey(key); } } /** Let a writable client get written, if there's data to be written. */ protected void handleWrite(SelectionKey key) { FrameBuffer buffer = (FrameBuffer) key.attachment(); if (!buffer.write()) { cleanupSelectionKey(key); } } /** Do connection-close cleanup on a given SelectionKey. */ protected void cleanupSelectionKey(SelectionKey key) { // remove the records from the two maps FrameBuffer buffer = (FrameBuffer) key.attachment(); if (buffer != null) { // close the buffer buffer.close(); } // cancel the selection key key.cancel(); } } // SelectThread /** Possible states for the FrameBuffer state machine. */ private enum FrameBufferState { // in the midst of reading the frame size off the wire READING_FRAME_SIZE, // reading the actual frame data now, but not all the way done yet READING_FRAME, // completely read the frame, so an invocation can now happen READ_FRAME_COMPLETE, // waiting to get switched to listening for write events AWAITING_REGISTER_WRITE, // started writing response data, not fully complete yet WRITING, // another thread wants this framebuffer to go back to reading AWAITING_REGISTER_READ, // we want our transport and selection key invalidated in the selector // thread AWAITING_CLOSE } /** * Class that implements a sort of state machine around the interaction with a client and an * invoker. It manages reading the frame size and frame data, getting it handed off as wrapped * transports, and then the writing of response data back to the client. In the process it manages * flipping the read and write bits on the selection key for its client. */ public class FrameBuffer { private final Logger LOGGER = LoggerFactory.getLogger(getClass().getName()); // the actual transport hooked up to the client. protected final TNonblockingTransport trans_; // the SelectionKey that corresponds to our transport protected SelectionKey selectionKey_; // the SelectThread that owns the registration of our transport protected final AbstractSelectThread selectThread_; // where in the process of reading/writing are we? protected FrameBufferState state_ = FrameBufferState.READING_FRAME_SIZE; // the ByteBuffer we'll be using to write and read, depending on the state protected ByteBuffer buffer_; protected final TByteArrayOutputStream response_; // the frame that the TTransport should wrap. protected final TMemoryInputTransport frameTrans_; // the transport that should be used to connect to clients protected final TTransport inTrans_; protected final TTransport outTrans_; // the input protocol to use on frames protected final TProtocol inProt_; // the output protocol to use on frames protected final TProtocol outProt_; // context associated with this connection protected final ServerContext context_; public FrameBuffer( final TNonblockingTransport trans, final SelectionKey selectionKey, final AbstractSelectThread selectThread) throws TTransportException { trans_ = trans; selectionKey_ = selectionKey; selectThread_ = selectThread; buffer_ = ByteBuffer.allocate(4); frameTrans_ = new TMemoryInputTransport(trans_.getConfiguration()); response_ = new TByteArrayOutputStream(); inTrans_ = inputTransportFactory_.getTransport(frameTrans_); outTrans_ = outputTransportFactory_.getTransport( new TIOStreamTransport(trans_.getConfiguration(), response_)); inProt_ = inputProtocolFactory_.getProtocol(inTrans_); outProt_ = outputProtocolFactory_.getProtocol(outTrans_); if (eventHandler_ != null) { context_ = eventHandler_.createContext(inProt_, outProt_); SocketAddress remoteAddress = trans_ instanceof SocketAddressProvider ? ((SocketAddressProvider) trans_).getRemoteSocketAddress() : null; context_.setRemoteAddress(remoteAddress); } else { context_ = null; } } /** * Sets the selection key (this is not thread safe). * * @param selectionKey the new key to set. */ public void setSelectionKey(SelectionKey selectionKey) { selectionKey_ = selectionKey; } /** * @return the amount of memory currently used to read data from clients. This information can * be useful for debugging, metrics, and configuring the maximum memory limit. */ public final long getReadBufferBytesAllocated() { return readBufferBytesAllocated.get(); } /** * Give this FrameBuffer a chance to read. The selector loop should have received a read event * for this FrameBuffer. * * @return true if the connection should live on, false if it should be closed */ public boolean read() { if (state_ == FrameBufferState.READING_FRAME_SIZE) { // try to read the frame size completely if (!internalRead()) { return false; } // if the frame size has been read completely, then prepare to read the // actual frame. if (buffer_.remaining() == 0) { // pull out the frame size as an integer. int frameSize = buffer_.getInt(0); if (frameSize <= 0) { LOGGER.error( "Read an invalid frame size of " + frameSize + ". Are you using TFramedTransport on the client side?"); return false; } // if this frame will always be too large for this server, log the // error and close the connection. if (frameSize > trans_.getMaxFrameSize()) { LOGGER.error( "Read a frame size of " + frameSize + ", which is bigger than the maximum allowable frame size " + trans_.getMaxFrameSize() + " for ALL connections."); return false; } // if this frame will push us over the memory limit, then return. // with luck, more memory will free up the next time around. long currentAllocated = getReadBufferBytesAllocated(); if (currentAllocated + frameSize > MAX_READ_BUFFER_BYTES) { LOGGER.trace( "Deferring reading frame of size {} because {} is already buffered and {} is the limit.", frameSize, currentAllocated, MAX_READ_BUFFER_BYTES); return true; } // increment the amount of memory allocated to read buffers readBufferBytesAllocated.addAndGet(frameSize + 4); // reallocate the readbuffer as a frame-sized buffer buffer_ = ByteBuffer.allocate(frameSize + 4); buffer_.putInt(frameSize); state_ = FrameBufferState.READING_FRAME; } else { // this skips the check of READING_FRAME state below, since we can't // possibly go on to that state if there's data left to be read at // this one. return true; } } // it is possible to fall through from the READING_FRAME_SIZE section // to READING_FRAME if there's already some frame data available once // READING_FRAME_SIZE is complete. if (state_ == FrameBufferState.READING_FRAME) { if (!internalRead()) { return false; } // since we're already in the select loop here for sure, we can just // modify our selection key directly. if (buffer_.remaining() == 0) { // get rid of the read select interests if (selectionKey_.isValid()) { selectionKey_.interestOps(0); } else { LOGGER.warn("SelectionKey was invalidated during read"); } state_ = FrameBufferState.READ_FRAME_COMPLETE; } return true; } // if we fall through to this point, then the state must be invalid. LOGGER.error("Read was called but state is invalid (" + state_ + ")"); return false; } /** Give this FrameBuffer a chance to write its output to the final client. */ public boolean write() { if (state_ == FrameBufferState.WRITING) { try { if (trans_.write(buffer_) < 0) { return false; } } catch (TTransportException e) { LOGGER.warn("Got an Exception during write", e); return false; } // we're done writing. now we need to switch back to reading. if (buffer_.remaining() == 0) { prepareRead(); } return true; } LOGGER.error("Write was called, but state is invalid (" + state_ + ")"); return false; } /** Give this FrameBuffer a chance to set its interest to write, once data has come in. */ public void changeSelectInterests() { switch (state_) { case AWAITING_REGISTER_WRITE: // set the OP_WRITE interest 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(); break; case AWAITING_CLOSE: close(); selectionKey_.cancel(); break; default: LOGGER.error("changeSelectInterest was called, but state is invalid ({})", state_); } } /** Shut the connection down. */ public void close() { // if we're being closed due to an error, we might have allocated a // buffer that we need to subtract for our memory accounting. if (state_ == FrameBufferState.READING_FRAME || state_ == FrameBufferState.READ_FRAME_COMPLETE || state_ == FrameBufferState.AWAITING_CLOSE) { readBufferBytesAllocated.addAndGet(-buffer_.array().length); } try { if (eventHandler_ != null) { eventHandler_.deleteContext(context_, inProt_, outProt_); } } finally { trans_.close(); } } /** Check if this FrameBuffer has a full frame read. */ public boolean isFrameFullyRead() { return state_ == FrameBufferState.READ_FRAME_COMPLETE; } /** * After the processor has processed the invocation, whatever thread is managing invocations * should call this method on this FrameBuffer so we know it's time to start trying to write * again. Also, if it turns out that there actually isn't any data in the response buffer, we'll * skip trying to write and instead go back to reading. */ public void responseReady() { // the read buffer is definitely no longer in use, so we will decrement // our read buffer count. we do this here as well as in close because // we'd like to free this read memory up as quickly as possible for other // clients. readBufferBytesAllocated.addAndGet(-buffer_.array().length); if (response_.len() == 0) { // go straight to reading again. this was probably an oneway method state_ = FrameBufferState.AWAITING_REGISTER_READ; buffer_ = null; } else { buffer_ = ByteBuffer.wrap(response_.get(), 0, response_.len()); // set state that we're waiting to be switched to write. we do this // asynchronously through requestSelectInterestChange() because there is // a possibility that we're not in the main thread, and thus currently // blocked in select(). (this functionality is in place for the sake of // the HsHa server.) state_ = FrameBufferState.AWAITING_REGISTER_WRITE; } requestSelectInterestChange(); } /** Actually invoke the method signified by this FrameBuffer. */ public void invoke() { frameTrans_.reset(buffer_.array()); response_.reset(); try { if (eventHandler_ != null) { eventHandler_.processContext(context_, inTrans_, outTrans_); } processorFactory_.getProcessor(inTrans_).process(inProt_, outProt_); responseReady(); return; } catch (TException te) { LOGGER.warn("Exception while invoking!", te); } catch (Throwable t) { LOGGER.error("Unexpected throwable while invoking!", t); } // This will only be reached when there is a throwable. state_ = FrameBufferState.AWAITING_CLOSE; requestSelectInterestChange(); } /** * Perform a read into buffer. * * @return true if the read succeeded, false if there was an error or the connection closed. */ private boolean internalRead() { try { return trans_.read(buffer_) >= 0; } catch (TTransportException e) { LOGGER.warn("Got an Exception in internalRead", e); return false; } } /** We're done writing, so reset our interest ops and change state accordingly. */ private void prepareRead() { // we can set our interest directly without using the queue because // we're in the select thread. 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; } /** * When this FrameBuffer needs to change its select interests and execution might not be in its * select thread, then this method will make sure the interest change gets done when the select * thread wakes back up. When the current thread is this FrameBuffer's select thread, then it * just does the interest change immediately. */ protected void requestSelectInterestChange() { if (Thread.currentThread() == this.selectThread_) { changeSelectInterests(); } else { this.selectThread_.requestSelectInterestChange(this); } } } // FrameBuffer public class AsyncFrameBuffer extends FrameBuffer { public AsyncFrameBuffer( TNonblockingTransport trans, SelectionKey selectionKey, AbstractSelectThread selectThread) throws TTransportException { super(trans, selectionKey, selectThread); } public TProtocol getInputProtocol() { return inProt_; } public TProtocol getOutputProtocol() { return outProt_; } public void invoke() { frameTrans_.reset(buffer_.array()); response_.reset(); try { if (eventHandler_ != null) { eventHandler_.processContext(context_, inTrans_, outTrans_); } ((TAsyncProcessor) processorFactory_.getProcessor(inTrans_)).process(this); return; } catch (TException te) { LOGGER.warn("Exception while invoking!", te); } catch (Throwable t) { LOGGER.error("Unexpected throwable while invoking!", t); } // This will only be reached when there is a throwable. state_ = FrameBufferState.AWAITING_CLOSE; requestSelectInterestChange(); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TThreadedSelectorServer.java0000664000175000017500000005655615165535636031756 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.io.IOException; import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.SelectorProvider; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Half-Sync/Half-Async server with a separate pool of threads to handle non-blocking I/O. Accepts * are handled on a single thread, and a configurable number of nonblocking selector threads manage * reading and writing of client connections. A synchronous worker thread pool handles processing of * requests. * *

Performs better than TNonblockingServer/THsHaServer in multi-core environments when the * bottleneck is CPU on the single selector thread handling I/O. In addition, because the accept * handling is decoupled from reads/writes and invocation, the server has better ability to handle * back-pressure from new connections (e.g. stop accepting when busy). * *

Like TNonblockingServer, it relies on the use of TFramedTransport. */ public class TThreadedSelectorServer extends AbstractNonblockingServer { private static final Logger LOGGER = LoggerFactory.getLogger(TThreadedSelectorServer.class.getName()); public static class Args extends AbstractNonblockingServerArgs { /** The number of threads for selecting on already-accepted connections */ public int selectorThreads = 2; /** * The size of the executor service (if none is specified) that will handle invocations. This * may be set to 0, in which case invocations will be handled directly on the selector threads * (as is in TNonblockingServer) */ private int workerThreads = 5; /** Time to wait for server to stop gracefully */ private int stopTimeoutVal = 60; private TimeUnit stopTimeoutUnit = TimeUnit.SECONDS; /** The ExecutorService for handling dispatched requests */ private ExecutorService executorService = null; /** * The size of the blocking queue per selector thread for passing accepted connections to the * selector thread */ private int acceptQueueSizePerThread = 4; /** Determines the strategy for handling new accepted connections. */ public static enum AcceptPolicy { /** * Require accepted connection registration to be handled by the executor. If the worker pool * is saturated, further accepts will be closed immediately. Slightly increases latency due to * an extra scheduling. */ FAIR_ACCEPT, /** * Handle the accepts as fast as possible, disregarding the status of the executor service. */ FAST_ACCEPT } private AcceptPolicy acceptPolicy = AcceptPolicy.FAST_ACCEPT; public Args(TNonblockingServerTransport transport) { super(transport); } public Args selectorThreads(int i) { selectorThreads = i; return this; } public int getSelectorThreads() { return selectorThreads; } public Args workerThreads(int i) { workerThreads = i; return this; } public int getWorkerThreads() { return workerThreads; } public int getStopTimeoutVal() { return stopTimeoutVal; } public Args stopTimeoutVal(int stopTimeoutVal) { this.stopTimeoutVal = stopTimeoutVal; return this; } public TimeUnit getStopTimeoutUnit() { return stopTimeoutUnit; } public Args stopTimeoutUnit(TimeUnit stopTimeoutUnit) { this.stopTimeoutUnit = stopTimeoutUnit; return this; } public ExecutorService getExecutorService() { return executorService; } public Args executorService(ExecutorService executorService) { this.executorService = executorService; return this; } public int getAcceptQueueSizePerThread() { return acceptQueueSizePerThread; } public Args acceptQueueSizePerThread(int acceptQueueSizePerThread) { this.acceptQueueSizePerThread = acceptQueueSizePerThread; return this; } public AcceptPolicy getAcceptPolicy() { return acceptPolicy; } public Args acceptPolicy(AcceptPolicy acceptPolicy) { this.acceptPolicy = acceptPolicy; return this; } public void validate() { if (selectorThreads <= 0) { throw new IllegalArgumentException("selectorThreads must be positive."); } if (workerThreads < 0) { throw new IllegalArgumentException("workerThreads must be non-negative."); } if (acceptQueueSizePerThread <= 0) { throw new IllegalArgumentException("acceptQueueSizePerThread must be positive."); } } } // The thread handling all accepts private AcceptThread acceptThread; // Threads handling events on client transports private final Set selectorThreads = new HashSet<>(); // This wraps all the functionality of queueing and thread pool management // for the passing of Invocations from the selector thread(s) to the workers // (if any). private final ExecutorService invoker; private final Args args; /** Create the server with the specified Args configuration */ public TThreadedSelectorServer(Args args) { super(args); args.validate(); invoker = args.executorService == null ? createDefaultExecutor(args) : args.executorService; this.args = args; } /** * Start the accept and selector threads running to deal with clients. * * @return true if everything went ok, false if we couldn't start for some reason. */ @Override protected boolean startThreads() { try { for (int i = 0; i < args.selectorThreads; ++i) { selectorThreads.add(new SelectorThread(args.acceptQueueSizePerThread)); } acceptThread = new AcceptThread( (TNonblockingServerTransport) serverTransport_, createSelectorThreadLoadBalancer(selectorThreads)); for (SelectorThread thread : selectorThreads) { thread.start(); } acceptThread.start(); return true; } catch (IOException e) { LOGGER.error("Failed to start threads!", e); return false; } } /** Joins the accept and selector threads and shuts down the executor service. */ @Override protected void waitForShutdown() { try { joinThreads(); } catch (InterruptedException e) { // Non-graceful shutdown occurred LOGGER.error("Interrupted while joining threads!", e); } gracefullyShutdownInvokerPool(); } protected void joinThreads() throws InterruptedException { // wait until the io threads exit acceptThread.join(); for (SelectorThread thread : selectorThreads) { thread.join(); } } /** Stop serving and shut everything down. */ @Override public void stop() { stopped_ = true; // Stop queuing connect attempts asap stopListening(); if (acceptThread != null) { acceptThread.wakeupSelector(); } for (SelectorThread thread : selectorThreads) { if (thread != null) thread.wakeupSelector(); } } protected void gracefullyShutdownInvokerPool() { // try to gracefully shut down the executor service invoker.shutdown(); // Loop until awaitTermination finally does return without a interrupted // exception. If we don't do this, then we'll shut down prematurely. We want // to let the executorService clear it's task queue, closing client sockets // appropriately. long timeoutMS = args.stopTimeoutUnit.toMillis(args.stopTimeoutVal); long now = System.currentTimeMillis(); while (timeoutMS >= 0) { try { invoker.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS); break; } catch (InterruptedException ix) { long newnow = System.currentTimeMillis(); timeoutMS -= (newnow - now); now = newnow; } } } /** * We override the standard invoke method here to queue the invocation for invoker service instead * of immediately invoking. If there is no thread pool, handle the invocation inline on this * thread */ @Override protected boolean requestInvoke(FrameBuffer frameBuffer) { Runnable invocation = getRunnable(frameBuffer); if (invoker != null) { try { invoker.execute(invocation); return true; } catch (RejectedExecutionException rx) { LOGGER.warn("ExecutorService rejected execution!", rx); return false; } } else { // Invoke on the caller's thread invocation.run(); return true; } } protected Runnable getRunnable(FrameBuffer frameBuffer) { return new Invocation(frameBuffer); } /** Helper to create the invoker if one is not specified */ protected static ExecutorService createDefaultExecutor(Args options) { return (options.workerThreads > 0) ? Executors.newFixedThreadPool(options.workerThreads) : null; } private static BlockingQueue createDefaultAcceptQueue(int queueSize) { if (queueSize == 0) { // Unbounded queue return new LinkedBlockingQueue(); } return new ArrayBlockingQueue(queueSize); } /** * The thread that selects on the server transport (listen socket) and accepts new connections to * hand off to the IO selector threads */ protected class AcceptThread extends Thread { // The listen socket to accept on private final TNonblockingServerTransport serverTransport; private final Selector acceptSelector; private final SelectorThreadLoadBalancer threadChooser; /** * Set up the AcceptThead * * @throws IOException if failed to register selector */ public AcceptThread( TNonblockingServerTransport serverTransport, SelectorThreadLoadBalancer threadChooser) throws IOException { this.serverTransport = serverTransport; this.threadChooser = threadChooser; this.acceptSelector = SelectorProvider.provider().openSelector(); this.serverTransport.registerSelector(acceptSelector); } /** * The work loop. Selects on the server transport and accepts. If there was a server transport * that had blocking accepts, and returned on blocking client transports, that should be used * instead */ public void run() { try { if (eventHandler_ != null) { eventHandler_.preServe(); } while (!stopped_) { select(); } } catch (Throwable t) { LOGGER.error("run() on AcceptThread exiting due to uncaught error", t); } finally { try { acceptSelector.close(); } catch (IOException e) { LOGGER.error("Got an IOException while closing accept selector!", e); } // This will wake up the selector threads TThreadedSelectorServer.this.stop(); } } /** If the selector is blocked, wake it up. */ public void wakeupSelector() { acceptSelector.wakeup(); } /** * Select and process IO events appropriately: If there are connections to be accepted, accept * them. */ private void select() { try { // wait for connect events. acceptSelector.select(); // process the io events we received Iterator selectedKeys = acceptSelector.selectedKeys().iterator(); while (!stopped_ && selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); // skip if not valid if (!key.isValid()) { continue; } if (key.isAcceptable()) { handleAccept(); } else { LOGGER.warn("Unexpected state in select! " + key.interestOps()); } } } catch (IOException e) { LOGGER.warn("Got an IOException while selecting!", e); } } /** Accept a new connection. */ private void handleAccept() { final TNonblockingTransport client = doAccept(); if (client != null) { // Pass this connection to a selector thread final SelectorThread targetThread = threadChooser.nextThread(); if (args.acceptPolicy == Args.AcceptPolicy.FAST_ACCEPT || invoker == null) { doAddAccept(targetThread, client); } else { // FAIR_ACCEPT try { invoker.submit( new Runnable() { public void run() { doAddAccept(targetThread, client); } }); } catch (RejectedExecutionException rx) { LOGGER.warn("ExecutorService rejected accept registration!", rx); // close immediately client.close(); } } } } private TNonblockingTransport doAccept() { try { return serverTransport.accept(); } catch (TTransportException tte) { // something went wrong accepting. LOGGER.warn("Exception trying to accept!", tte); return null; } } private void doAddAccept(SelectorThread thread, TNonblockingTransport client) { if (!thread.addAcceptedConnection(client)) { client.close(); } } } // AcceptThread /** The SelectorThread(s) will be doing all the selecting on accepted active connections. */ protected class SelectorThread extends AbstractSelectThread { // Accepted connections added by the accept thread. private final BlockingQueue acceptedQueue; private static final int SELECTOR_AUTO_REBUILD_THRESHOLD = 512; private static final long MONITOR_PERIOD = 1000L; private int jvmBug = 0; /** * Set up the SelectorThread with an unbounded queue for incoming accepts. * * @throws IOException if a selector cannot be created */ public SelectorThread() throws IOException { this(new LinkedBlockingQueue()); } /** * Set up the SelectorThread with an bounded queue for incoming accepts. * * @throws IOException if a selector cannot be created */ public SelectorThread(int maxPendingAccepts) throws IOException { this(createDefaultAcceptQueue(maxPendingAccepts)); } /** * Set up the SelectorThread with a specified queue for connections. * * @param acceptedQueue The BlockingQueue implementation for holding incoming accepted * connections. * @throws IOException if a selector cannot be created. */ public SelectorThread(BlockingQueue acceptedQueue) throws IOException { this.acceptedQueue = acceptedQueue; } /** * Hands off an accepted connection to be handled by this thread. This method will block if the * queue for new connections is at capacity. * * @param accepted The connection that has been accepted. * @return true if the connection has been successfully added. */ public boolean addAcceptedConnection(TNonblockingTransport accepted) { try { acceptedQueue.put(accepted); } catch (InterruptedException e) { LOGGER.warn("Interrupted while adding accepted connection!", e); return false; } selector.wakeup(); return true; } /** * The work loop. Handles selecting (read/write IO), dispatching, and managing the selection * preferences of all existing connections. */ public void run() { try { while (!stopped_) { select(); processAcceptedConnections(); processInterestChanges(); } for (SelectionKey selectionKey : selector.keys()) { cleanupSelectionKey(selectionKey); } } catch (Throwable t) { LOGGER.error("run() on SelectorThread exiting due to uncaught error", t); } finally { try { selector.close(); } catch (IOException e) { LOGGER.error("Got an IOException while closing selector!", e); } // This will wake up the accept thread and the other selector threads TThreadedSelectorServer.this.stop(); } } /** * Select and process IO events appropriately: If there are existing connections with data * waiting to be read, read it, buffering until a whole frame has been read. If there are any * pending responses, buffer them until their target client is available, and then send the * data. */ private void select() { try { doSelect(); // process the io events we received Iterator selectedKeys = selector.selectedKeys().iterator(); while (!stopped_ && selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); // skip if not valid if (!key.isValid()) { cleanupSelectionKey(key); continue; } if (key.isReadable()) { // deal with reads handleRead(key); } else if (key.isWritable()) { // deal with writes handleWrite(key); } else { LOGGER.warn("Unexpected state in select! " + key.interestOps()); } } } catch (IOException e) { LOGGER.warn("Got an IOException while selecting!", e); } } /** * Do select and judge epoll bug happen. See THRIFT-4251 */ private void doSelect() throws IOException { long beforeSelect = System.currentTimeMillis(); int selectedNums = selector.select(); long afterSelect = System.currentTimeMillis(); if (selectedNums == 0) { jvmBug++; } else { jvmBug = 0; } long selectedTime = afterSelect - beforeSelect; if (selectedTime >= MONITOR_PERIOD) { jvmBug = 0; } else if (jvmBug > SELECTOR_AUTO_REBUILD_THRESHOLD) { LOGGER.warn( "In {} ms happen {} times jvm bug; rebuilding selector.", MONITOR_PERIOD, jvmBug); rebuildSelector(); selector.selectNow(); jvmBug = 0; } } /** * Replaces the current Selector of this SelectorThread with newly created Selector to work * around the infamous epoll 100% CPU bug. */ private synchronized void rebuildSelector() { final Selector oldSelector = selector; if (oldSelector == null) { return; } Selector newSelector = null; try { newSelector = Selector.open(); LOGGER.warn("Created new Selector."); } catch (IOException e) { LOGGER.error("Create new Selector error.", e); } 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) { newKey = channel.register(newSelector, interestOps); } else { 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); } } selector = newSelector; try { oldSelector.close(); } catch (IOException e) { LOGGER.error("Close old selector error.", e); } LOGGER.warn("Replace new selector success."); } private void processAcceptedConnections() { // Register accepted connections while (!stopped_) { TNonblockingTransport accepted = acceptedQueue.poll(); if (accepted == null) { break; } registerAccepted(accepted); } } protected FrameBuffer createFrameBuffer( final TNonblockingTransport trans, final SelectionKey selectionKey, final AbstractSelectThread selectThread) throws TTransportException { return processorFactory_.isAsyncProcessor() ? new AsyncFrameBuffer(trans, selectionKey, selectThread) : new FrameBuffer(trans, selectionKey, selectThread); } private void registerAccepted(TNonblockingTransport accepted) { SelectionKey clientKey = null; try { clientKey = accepted.registerSelector(selector, SelectionKey.OP_READ); FrameBuffer frameBuffer = createFrameBuffer(accepted, clientKey, SelectorThread.this); clientKey.attach(frameBuffer); } catch (IOException | TTransportException e) { LOGGER.warn("Failed to register accepted connection to selector!", e); if (clientKey != null) { cleanupSelectionKey(clientKey); } accepted.close(); } } } // SelectorThread /** * Creates a SelectorThreadLoadBalancer to be used by the accept thread for assigning newly * accepted connections across the threads. */ protected SelectorThreadLoadBalancer createSelectorThreadLoadBalancer( Collection threads) { return new SelectorThreadLoadBalancer(threads); } /** A round robin load balancer for choosing selector threads for new connections. */ protected static class SelectorThreadLoadBalancer { private final Collection threads; private Iterator nextThreadIterator; public SelectorThreadLoadBalancer(Collection threads) { if (threads.isEmpty()) { throw new IllegalArgumentException("At least one selector thread is required"); } this.threads = Collections.unmodifiableList(new ArrayList(threads)); nextThreadIterator = this.threads.iterator(); } public SelectorThread nextThread() { // Choose a selector thread (round robin) if (!nextThreadIterator.hasNext()) { nextThreadIterator = threads.iterator(); } return nextThreadIterator.next(); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/ServerContext.java0000664000175000017500000000410615165535636030015 0ustar00buildbuild00000000000000/* * 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. */ /** Interface for storing server's connection context. */ package org.apache.thrift.server; import java.net.SocketAddress; public interface ServerContext { /** * Returns an object that implements the given interface to allow access to application specific * contexts. * * @param iface A Class defining an interface that the result must implement * @return an object that implements the interface * @throws RuntimeException If the context cannot be unwrapped to the provided class */ T unwrap(Class iface); /** * Returns true if this server context is a wrapper for the provided application specific context * interface argument or returns false otherwise. * * @param iface a Class defining the underlying context * @return true if this implements the interface can be unwrapped to the provided class * @throws RuntimeException if an error occurs while determining whether the provided class can be * unwrapped from this context. */ boolean isWrapperFor(Class iface); /** * Set the remote socket address for this ServerContext. The remoteAddress is null when transport * is not socket based * * @param remoteAddress The remote socket address, may be null. */ default void setRemoteAddress(SocketAddress remoteAddress) {} } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/THsHaServer.java0000664000175000017500000001345315165535636027345 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.thrift.transport.TNonblockingServerTransport; /** * An extension of the TNonblockingServer to a Half-Sync/Half-Async server. Like TNonblockingServer, * it relies on the use of TFramedTransport. */ public class THsHaServer extends TNonblockingServer { public static class Args extends AbstractNonblockingServerArgs { public int minWorkerThreads = 5; public int maxWorkerThreads = Integer.MAX_VALUE; private int stopTimeoutVal = 60; private TimeUnit stopTimeoutUnit = TimeUnit.SECONDS; private ExecutorService executorService = null; public Args(TNonblockingServerTransport transport) { super(transport); } /** * Sets the min and max threads. * * @deprecated use {@link #minWorkerThreads(int)} and {@link #maxWorkerThreads(int)} instead. */ @Deprecated public Args workerThreads(int n) { minWorkerThreads = n; maxWorkerThreads = n; return this; } /** * @return what the min threads was set to. * @deprecated use {@link #getMinWorkerThreads()} and {@link #getMaxWorkerThreads()} instead. */ @Deprecated public int getWorkerThreads() { return minWorkerThreads; } public Args minWorkerThreads(int n) { minWorkerThreads = n; return this; } public Args maxWorkerThreads(int n) { maxWorkerThreads = n; return this; } public int getMinWorkerThreads() { return minWorkerThreads; } public int getMaxWorkerThreads() { return maxWorkerThreads; } public int getStopTimeoutVal() { return stopTimeoutVal; } public Args stopTimeoutVal(int stopTimeoutVal) { this.stopTimeoutVal = stopTimeoutVal; return this; } public TimeUnit getStopTimeoutUnit() { return stopTimeoutUnit; } public Args stopTimeoutUnit(TimeUnit stopTimeoutUnit) { this.stopTimeoutUnit = stopTimeoutUnit; return this; } public ExecutorService getExecutorService() { return executorService; } public Args executorService(ExecutorService executorService) { this.executorService = executorService; return this; } } // This wraps all the functionality of queueing and thread pool management // for the passing of Invocations from the Selector to workers. private final ExecutorService invoker; private final Args args; /** Create the server with the specified Args configuration */ public THsHaServer(Args args) { super(args); invoker = args.executorService == null ? createInvokerPool(args) : args.executorService; this.args = args; } /** {@inheritDoc} */ @Override protected void waitForShutdown() { joinSelector(); gracefullyShutdownInvokerPool(); } /** Helper to create an invoker pool */ protected static ExecutorService createInvokerPool(Args options) { int minWorkerThreads = options.minWorkerThreads; int maxWorkerThreads = options.maxWorkerThreads; int stopTimeoutVal = options.stopTimeoutVal; TimeUnit stopTimeoutUnit = options.stopTimeoutUnit; LinkedBlockingQueue queue = new LinkedBlockingQueue(); ExecutorService invoker = new ThreadPoolExecutor( minWorkerThreads, maxWorkerThreads, stopTimeoutVal, stopTimeoutUnit, queue); return invoker; } protected ExecutorService getInvoker() { return invoker; } protected void gracefullyShutdownInvokerPool() { // try to gracefully shut down the executor service invoker.shutdown(); // Loop until awaitTermination finally does return without a interrupted // exception. If we don't do this, then we'll shut down prematurely. We want // to let the executorService clear it's task queue, closing client sockets // appropriately. long timeoutMS = args.stopTimeoutUnit.toMillis(args.stopTimeoutVal); long now = System.currentTimeMillis(); while (timeoutMS >= 0) { try { invoker.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS); break; } catch (InterruptedException ix) { long newnow = System.currentTimeMillis(); timeoutMS -= (newnow - now); now = newnow; } } } /** * We override the standard invoke method here to queue the invocation for invoker service instead * of immediately invoking. The thread pool takes care of the rest. */ @Override protected boolean requestInvoke(FrameBuffer frameBuffer) { try { Runnable invocation = getRunnable(frameBuffer); invoker.execute(invocation); return true; } catch (RejectedExecutionException rx) { LOGGER.warn("ExecutorService rejected execution!", rx); return false; } } protected Runnable getRunnable(FrameBuffer frameBuffer) { return new Invocation(frameBuffer); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TSimpleServer.java0000664000175000017500000000773415165535636027760 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.net.SocketAddress; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.SocketAddressProvider; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Simple singlethreaded server for testing. */ public class TSimpleServer extends TServer { private static final Logger LOGGER = LoggerFactory.getLogger(TSimpleServer.class.getName()); public TSimpleServer(AbstractServerArgs args) { super(args); } @Override public void serve() { try { serverTransport_.listen(); } catch (TTransportException ttx) { LOGGER.error("Error occurred during listening.", ttx); return; } // Run the preServe event if (eventHandler_ != null) { eventHandler_.preServe(); } setServing(true); while (!stopped_) { TTransport client = null; TProcessor processor = null; TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; ServerContext connectionContext = null; try { client = serverTransport_.accept(); if (client != null) { processor = processorFactory_.getProcessor(client); inputTransport = inputTransportFactory_.getTransport(client); outputTransport = outputTransportFactory_.getTransport(client); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); if (eventHandler_ != null) { connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol); SocketAddress remoteAddress = client instanceof SocketAddressProvider ? ((SocketAddressProvider) client).getRemoteSocketAddress() : null; connectionContext.setRemoteAddress(remoteAddress); } while (true) { if (eventHandler_ != null) { eventHandler_.processContext(connectionContext, inputTransport, outputTransport); } processor.process(inputProtocol, outputProtocol); } } } catch (TTransportException ttx) { // Client died, just move on LOGGER.debug("Client Transportation Exception", ttx); } catch (TException tx) { if (!stopped_) { LOGGER.error("Thrift error occurred during processing of message.", tx); } } catch (Exception x) { if (!stopped_) { LOGGER.error("Error occurred during processing of message.", x); } } if (eventHandler_ != null) { eventHandler_.deleteContext(connectionContext, inputProtocol, outputProtocol); } if (inputTransport != null) { inputTransport.close(); } if (outputTransport != null) { outputTransport.close(); } } setServing(false); } public void stop() { stopped_ = true; serverTransport_.interrupt(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TSaslNonblockingServer.java0000664000175000017500000003712015165535636031605 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.io.IOException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.security.auth.callback.CallbackHandler; import org.apache.thrift.TProcessor; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.sasl.NonblockingSaslHandler; import org.apache.thrift.transport.sasl.NonblockingSaslHandler.Phase; import org.apache.thrift.transport.sasl.TBaseSaslProcessorFactory; import org.apache.thrift.transport.sasl.TSaslProcessorFactory; import org.apache.thrift.transport.sasl.TSaslServerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** TServer with sasl support, using asynchronous execution and nonblocking io. */ public class TSaslNonblockingServer extends TServer { private static final Logger LOGGER = LoggerFactory.getLogger(TSaslNonblockingServer.class); private static final int DEFAULT_NETWORK_THREADS = 1; private static final int DEFAULT_AUTHENTICATION_THREADS = 1; private static final int DEFAULT_PROCESSING_THREADS = Runtime.getRuntime().availableProcessors(); private final AcceptorThread acceptor; private final NetworkThreadPool networkThreadPool; private final ExecutorService authenticationExecutor; private final ExecutorService processingExecutor; private final TSaslServerFactory saslServerFactory; private final TSaslProcessorFactory saslProcessorFactory; public TSaslNonblockingServer(Args args) throws IOException { super(args); acceptor = new AcceptorThread((TNonblockingServerSocket) serverTransport_); networkThreadPool = new NetworkThreadPool(args.networkThreads); authenticationExecutor = Executors.newFixedThreadPool(args.saslThreads); processingExecutor = Executors.newFixedThreadPool(args.processingThreads); saslServerFactory = args.saslServerFactory; saslProcessorFactory = args.saslProcessorFactory; } @Override public void serve() { if (eventHandler_ != null) { eventHandler_.preServe(); } networkThreadPool.start(); acceptor.start(); setServing(true); } /** Trigger a graceful shutdown, but it does not block to wait for the shutdown to finish. */ @Override public void stop() { if (!stopped_) { setServing(false); stopped_ = true; acceptor.wakeup(); networkThreadPool.wakeupAll(); authenticationExecutor.shutdownNow(); processingExecutor.shutdownNow(); } } /** * Gracefully shut down the server and block until all threads are stopped. * * @throws InterruptedException if is interrupted while waiting for shutdown. */ public void shutdown() throws InterruptedException { stop(); acceptor.join(); for (NetworkThread networkThread : networkThreadPool.networkThreads) { networkThread.join(); } while (!authenticationExecutor.isTerminated()) { authenticationExecutor.awaitTermination(10, TimeUnit.SECONDS); } while (!processingExecutor.isTerminated()) { processingExecutor.awaitTermination(10, TimeUnit.SECONDS); } } private class AcceptorThread extends Thread { private final TNonblockingServerTransport serverTransport; private final Selector acceptSelector; private AcceptorThread(TNonblockingServerSocket serverTransport) throws IOException { super("acceptor-thread"); this.serverTransport = serverTransport; acceptSelector = Selector.open(); serverTransport.registerSelector(acceptSelector); } @Override public void run() { try { serverTransport.listen(); while (!stopped_) { select(); acceptNewConnection(); } } catch (TTransportException e) { // Failed to listen. LOGGER.error("Failed to listen on server socket, error " + e.getType(), e); } catch (Throwable e) { // Unexpected errors. LOGGER.error("Unexpected error in acceptor thread.", e); } finally { TSaslNonblockingServer.this.stop(); close(); } } void wakeup() { acceptSelector.wakeup(); } private void acceptNewConnection() { Iterator selectedKeyItr = acceptSelector.selectedKeys().iterator(); while (!stopped_ && selectedKeyItr.hasNext()) { SelectionKey selected = selectedKeyItr.next(); selectedKeyItr.remove(); if (selected.isAcceptable()) { try { while (true) { // Accept all available connections from the backlog. TNonblockingTransport connection = serverTransport.accept(); if (connection == null) { break; } if (!networkThreadPool.acceptNewConnection(connection)) { LOGGER.error("Network thread does not accept: " + connection); connection.close(); } } } catch (TTransportException e) { LOGGER.warn("Failed to accept incoming connection.", e); } } else { LOGGER.error("Not acceptable selection: " + selected.channel()); } } } private void select() { try { acceptSelector.select(); } catch (IOException e) { LOGGER.error("Failed to select on the server socket.", e); } } private void close() { LOGGER.info("Closing acceptor thread."); serverTransport.close(); try { acceptSelector.close(); } catch (IOException e) { LOGGER.error("Failed to close accept selector.", e); } } } private class NetworkThread extends Thread { private final BlockingQueue incomingConnections = new LinkedBlockingQueue<>(); private final BlockingQueue stateTransitions = new LinkedBlockingQueue<>(); private final Selector ioSelector; NetworkThread(String name) throws IOException { super(name); ioSelector = Selector.open(); } @Override public void run() { try { while (!stopped_) { handleIncomingConnections(); handleStateChanges(); select(); handleIO(); } } catch (Throwable e) { LOGGER.error("Unreoverable error in " + getName(), e); } finally { close(); } } private void handleStateChanges() { while (true) { NonblockingSaslHandler statemachine = stateTransitions.poll(); if (statemachine == null) { return; } tryRunNextPhase(statemachine); } } private void select() { try { ioSelector.select(); } catch (IOException e) { LOGGER.error("Failed to select in " + getName(), e); } } private void handleIO() { Iterator selectedKeyItr = ioSelector.selectedKeys().iterator(); while (!stopped_ && selectedKeyItr.hasNext()) { SelectionKey selected = selectedKeyItr.next(); selectedKeyItr.remove(); if (!selected.isValid()) { closeChannel(selected); } NonblockingSaslHandler saslHandler = (NonblockingSaslHandler) selected.attachment(); if (selected.isReadable()) { saslHandler.handleRead(); } else if (selected.isWritable()) { saslHandler.handleWrite(); } else { LOGGER.error("Invalid interest op " + selected.interestOps()); closeChannel(selected); continue; } if (saslHandler.isCurrentPhaseDone()) { tryRunNextPhase(saslHandler); } } } // The following methods are modifying the registered channel set on the selector, which itself // is not thread safe. Thus we need a lock to protect it from race condition. private synchronized void handleIncomingConnections() { while (true) { TNonblockingTransport connection = incomingConnections.poll(); if (connection == null) { return; } if (!connection.isOpen()) { LOGGER.warn("Incoming connection is already closed"); continue; } try { SelectionKey selectionKey = connection.registerSelector(ioSelector, SelectionKey.OP_READ); if (selectionKey.isValid()) { NonblockingSaslHandler saslHandler = new NonblockingSaslHandler( selectionKey, connection, saslServerFactory, saslProcessorFactory, inputProtocolFactory_, outputProtocolFactory_, eventHandler_); selectionKey.attach(saslHandler); } } catch (IOException e) { LOGGER.error("Failed to register connection for the selector, close it.", e); connection.close(); } } } private synchronized void close() { LOGGER.warn("Closing " + getName()); while (true) { TNonblockingTransport incomingConnection = incomingConnections.poll(); if (incomingConnection == null) { break; } incomingConnection.close(); } Set registered = ioSelector.keys(); for (SelectionKey selection : registered) { closeChannel(selection); } try { ioSelector.close(); } catch (IOException e) { LOGGER.error("Failed to close io selector " + getName(), e); } } private synchronized void closeChannel(SelectionKey selectionKey) { if (selectionKey.attachment() == null) { try { selectionKey.channel().close(); } catch (IOException e) { LOGGER.error("Failed to close channel.", e); } finally { selectionKey.cancel(); } } else { NonblockingSaslHandler saslHandler = (NonblockingSaslHandler) selectionKey.attachment(); saslHandler.close(); } } private void tryRunNextPhase(NonblockingSaslHandler saslHandler) { Phase nextPhase = saslHandler.getNextPhase(); saslHandler.stepToNextPhase(); switch (nextPhase) { case EVALUATING_SASL_RESPONSE: authenticationExecutor.submit(new Computation(saslHandler)); break; case PROCESSING: processingExecutor.submit(new Computation(saslHandler)); break; case CLOSING: saslHandler.runCurrentPhase(); break; default: // waiting for next io event for the current state machine } } public boolean accept(TNonblockingTransport connection) { if (stopped_) { return false; } if (incomingConnections.offer(connection)) { wakeup(); return true; } return false; } private void wakeup() { ioSelector.wakeup(); } private class Computation implements Runnable { private final NonblockingSaslHandler statemachine; private Computation(NonblockingSaslHandler statemachine) { this.statemachine = statemachine; } @Override public void run() { try { while (!statemachine.isCurrentPhaseDone()) { statemachine.runCurrentPhase(); } stateTransitions.add(statemachine); wakeup(); } catch (Throwable e) { LOGGER.error("Damn it!", e); } } } } private class NetworkThreadPool { private final List networkThreads; private int accepted = 0; NetworkThreadPool(int size) throws IOException { networkThreads = new ArrayList<>(size); int digits = (int) Math.log10(size) + 1; String threadNamePattern = "network-thread-%0" + digits + "d"; for (int i = 0; i < size; i++) { networkThreads.add(new NetworkThread(String.format(threadNamePattern, i))); } } /** * Round robin new connection among all the network threads. * * @param connection incoming connection. * @return true if the incoming connection is accepted by network thread pool. */ boolean acceptNewConnection(TNonblockingTransport connection) { return networkThreads.get((accepted++) % networkThreads.size()).accept(connection); } public void start() { for (NetworkThread thread : networkThreads) { thread.start(); } } void wakeupAll() { for (NetworkThread networkThread : networkThreads) { networkThread.wakeup(); } } } public static class Args extends AbstractServerArgs { private int networkThreads = DEFAULT_NETWORK_THREADS; private int saslThreads = DEFAULT_AUTHENTICATION_THREADS; private int processingThreads = DEFAULT_PROCESSING_THREADS; private TSaslServerFactory saslServerFactory = new TSaslServerFactory(); private TSaslProcessorFactory saslProcessorFactory; public Args(TNonblockingServerTransport transport) { super(transport); } public Args networkThreads(int networkThreads) { this.networkThreads = networkThreads <= 0 ? DEFAULT_NETWORK_THREADS : networkThreads; return this; } public Args saslThreads(int authenticationThreads) { this.saslThreads = authenticationThreads <= 0 ? DEFAULT_AUTHENTICATION_THREADS : authenticationThreads; return this; } public Args processingThreads(int processingThreads) { this.processingThreads = processingThreads <= 0 ? DEFAULT_PROCESSING_THREADS : processingThreads; return this; } public Args processor(TProcessor processor) { saslProcessorFactory = new TBaseSaslProcessorFactory(processor); return this; } public Args saslProcessorFactory(TSaslProcessorFactory saslProcessorFactory) { if (saslProcessorFactory == null) { throw new NullPointerException("Processor factory cannot be null"); } this.saslProcessorFactory = saslProcessorFactory; return this; } public Args addSaslMechanism( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { saslServerFactory.addSaslMechanism(mechanism, protocol, serverName, props, cbh); return this; } public Args saslServerFactory(TSaslServerFactory saslServerFactory) { if (saslServerFactory == null) { throw new NullPointerException("saslServerFactory cannot be null"); } this.saslServerFactory = saslServerFactory; return this; } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TServer.java0000664000175000017500000001150715165535636026577 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TProcessor; import org.apache.thrift.TProcessorFactory; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TServerTransport; import org.apache.thrift.transport.TTransportFactory; /** Generic interface for a Thrift server. */ public abstract class TServer { public static class Args extends AbstractServerArgs { public Args(TServerTransport transport) { super(transport); } } public abstract static class AbstractServerArgs> { final TServerTransport serverTransport; TProcessorFactory processorFactory; TTransportFactory inputTransportFactory = new TTransportFactory(); TTransportFactory outputTransportFactory = new TTransportFactory(); TProtocolFactory inputProtocolFactory = new TBinaryProtocol.Factory(); TProtocolFactory outputProtocolFactory = new TBinaryProtocol.Factory(); public AbstractServerArgs(TServerTransport transport) { serverTransport = transport; } public T processorFactory(TProcessorFactory factory) { this.processorFactory = factory; return (T) this; } public T processor(TProcessor processor) { this.processorFactory = new TProcessorFactory(processor); return (T) this; } public T transportFactory(TTransportFactory factory) { this.inputTransportFactory = factory; this.outputTransportFactory = factory; return (T) this; } public T inputTransportFactory(TTransportFactory factory) { this.inputTransportFactory = factory; return (T) this; } public T outputTransportFactory(TTransportFactory factory) { this.outputTransportFactory = factory; return (T) this; } public T protocolFactory(TProtocolFactory factory) { this.inputProtocolFactory = factory; this.outputProtocolFactory = factory; return (T) this; } public T inputProtocolFactory(TProtocolFactory factory) { this.inputProtocolFactory = factory; return (T) this; } public T outputProtocolFactory(TProtocolFactory factory) { this.outputProtocolFactory = factory; return (T) this; } } /** Core processor */ protected TProcessorFactory processorFactory_; /** Server transport */ protected TServerTransport serverTransport_; /** Input Transport Factory */ protected TTransportFactory inputTransportFactory_; /** Output Transport Factory */ protected TTransportFactory outputTransportFactory_; /** Input Protocol Factory */ protected TProtocolFactory inputProtocolFactory_; /** Output Protocol Factory */ protected TProtocolFactory outputProtocolFactory_; private volatile boolean isServing; protected TServerEventHandler eventHandler_; // Flag for stopping the server // Please see THRIFT-1795 for the usage of this flag protected volatile boolean stopped_ = false; protected TServer(AbstractServerArgs args) { processorFactory_ = args.processorFactory; serverTransport_ = args.serverTransport; inputTransportFactory_ = args.inputTransportFactory; outputTransportFactory_ = args.outputTransportFactory; inputProtocolFactory_ = args.inputProtocolFactory; outputProtocolFactory_ = args.outputProtocolFactory; } /** The run method fires up the server and gets things going. */ public abstract void serve(); /** * Stop the server. This is optional on a per-implementation basis. Not all servers are required * to be cleanly stoppable. */ public void stop() {} public boolean isServing() { return isServing; } protected void setServing(boolean serving) { isServing = serving; } public void setServerEventHandler(TServerEventHandler eventHandler) { eventHandler_ = eventHandler; } public TServerEventHandler getEventHandler() { return eventHandler_; } public boolean getShouldStop() { return this.stopped_; } public void setShouldStop(boolean shouldStop) { this.stopped_ = shouldStop; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TNonblockingServer.java0000664000175000017500000001700015165535636030755 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.io.IOException; import java.nio.channels.SelectionKey; import java.util.Iterator; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; /** * A nonblocking TServer implementation. This allows for fairness amongst all connected clients in * terms of invocations. * *

This server is inherently single-threaded. If you want a limited thread pool coupled with * invocation-fairness, see THsHaServer. * *

To use this server, you MUST use a TFramedTransport at the outermost transport, otherwise this * server will be unable to determine when a whole method call has been read off the wire. Clients * must also use TFramedTransport. */ public class TNonblockingServer extends AbstractNonblockingServer { public static class Args extends AbstractNonblockingServerArgs { public Args(TNonblockingServerTransport transport) { super(transport); } } private SelectAcceptThread selectAcceptThread_; public TNonblockingServer(AbstractNonblockingServerArgs args) { super(args); } /** * Start the selector thread to deal with accepts and client messages. * * @return true if everything went ok, false if we couldn't start for some reason. */ @Override protected boolean startThreads() { // start the selector try { selectAcceptThread_ = new SelectAcceptThread((TNonblockingServerTransport) serverTransport_); selectAcceptThread_.start(); return true; } catch (IOException e) { LOGGER.error("Failed to start selector thread!", e); return false; } } @Override protected void waitForShutdown() { joinSelector(); } /** Block until the selector thread exits. */ protected void joinSelector() { // wait until the selector thread exits try { selectAcceptThread_.join(); } catch (InterruptedException e) { LOGGER.debug("Interrupted while waiting for accept thread", e); Thread.currentThread().interrupt(); } } /** Stop serving and shut everything down. */ @Override public void stop() { stopped_ = true; if (selectAcceptThread_ != null) { selectAcceptThread_.wakeupSelector(); } } /** * Perform an invocation. This method could behave several different ways - invoke immediately * inline, queue for separate execution, etc. */ @Override protected boolean requestInvoke(FrameBuffer frameBuffer) { frameBuffer.invoke(); return true; } public boolean isStopped() { return selectAcceptThread_.isStopped(); } /** * The thread that will be doing all the selecting, managing new connections and those that still * need to be read. */ protected class SelectAcceptThread extends AbstractSelectThread { // The server transport on which new client transports will be accepted private final TNonblockingServerTransport serverTransport; /** Set up the thread that will handle the non-blocking accepts, reads, and writes. */ public SelectAcceptThread(final TNonblockingServerTransport serverTransport) throws IOException { this.serverTransport = serverTransport; serverTransport.registerSelector(selector); } public boolean isStopped() { return stopped_; } /** * The work loop. Handles both selecting (all IO operations) and managing the selection * preferences of all existing connections. */ @Override public void run() { try { if (eventHandler_ != null) { eventHandler_.preServe(); } while (!stopped_) { select(); processInterestChanges(); } for (SelectionKey selectionKey : selector.keys()) { cleanupSelectionKey(selectionKey); } } catch (Throwable t) { LOGGER.error("run() exiting due to uncaught error", t); } finally { try { selector.close(); } catch (IOException e) { LOGGER.error("Got an IOException while closing selector!", e); } stopped_ = true; } } /** * Select and process IO events appropriately: If there are connections to be accepted, accept * them. If there are existing connections with data waiting to be read, read it, buffering * until a whole frame has been read. If there are any pending responses, buffer them until * their target client is available, and then send the data. */ private void select() { try { // wait for io events. selector.select(); // process the io events we received Iterator selectedKeys = selector.selectedKeys().iterator(); while (!stopped_ && selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); // skip if not valid if (!key.isValid()) { cleanupSelectionKey(key); continue; } // if the key is marked Accept, then it has to be the server // transport. if (key.isAcceptable()) { handleAccept(); } else if (key.isReadable()) { // deal with reads handleRead(key); } else if (key.isWritable()) { // deal with writes handleWrite(key); } else { LOGGER.warn("Unexpected state in select! " + key.interestOps()); } } } catch (IOException e) { LOGGER.warn("Got an IOException while selecting!", e); } } protected FrameBuffer createFrameBuffer( final TNonblockingTransport trans, final SelectionKey selectionKey, final AbstractSelectThread selectThread) throws TTransportException { return processorFactory_.isAsyncProcessor() ? new AsyncFrameBuffer(trans, selectionKey, selectThread) : new FrameBuffer(trans, selectionKey, selectThread); } /** Accept a new connection. */ private void handleAccept() throws IOException { SelectionKey clientKey = null; TNonblockingTransport client = null; try { // accept the connection client = serverTransport.accept(); clientKey = client.registerSelector(selector, SelectionKey.OP_READ); // add this key to the map FrameBuffer frameBuffer = createFrameBuffer(client, clientKey, SelectAcceptThread.this); clientKey.attach(frameBuffer); } catch (TTransportException tte) { // something went wrong accepting. LOGGER.warn("Exception trying to accept!", tte); if (clientKey != null) cleanupSelectionKey(clientKey); if (client != null) client.close(); } } } // SelectAcceptThread } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TExtensibleServlet.java0000664000175000017500000001263515165535636031003 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; /** * Servlet implementation class ThriftServer, that allows {@link TProcessor} and {@link * TProtocolFactory} to be supplied after the {@link #init()} method has finished.
* Subclasses must implement the abstract methods that return the TProcessor and two * TProtocolFactory. Those methods are guaranteed to be called exactly once, and that {@link * ServletContext} is available. */ public abstract class TExtensibleServlet extends HttpServlet { private static final long serialVersionUID = 1L; private TProcessor processor; private TProtocolFactory inFactory; private Collection> customHeaders; /** * Returns the appropriate {@link TProcessor}. This will be called once just after the * {@link #init()} method * * @return the appropriate {@link TProcessor} */ protected abstract TProcessor getProcessor(); /** * Returns the appropriate in {@link TProtocolFactory}. This will be called once just after * the {@link #init()} method * * @return the appropriate in {@link TProtocolFactory} */ protected abstract TProtocolFactory getInProtocolFactory(); /** * Returns the appropriate out {@link TProtocolFactory}. This will be called once just * after the {@link #init()} method * * @return the appropriate out {@link TProtocolFactory} */ protected abstract TProtocolFactory getOutProtocolFactory(); @Override public final void init(ServletConfig config) throws ServletException { super.init(config); // no-args init() happens here this.processor = getProcessor(); this.inFactory = getInProtocolFactory(); TProtocolFactory outFactory = getOutProtocolFactory(); this.customHeaders = new ArrayList>(); if (processor == null) { throw new ServletException("processor must be set"); } if (inFactory == null) { throw new ServletException("inFactory must be set"); } if (outFactory == null) { throw new ServletException("outFactory must be set"); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { TTransport inTransport; TTransport outTransport; try { response.setContentType("application/x-thrift"); if (null != this.customHeaders) { for (Map.Entry header : this.customHeaders) { response.addHeader(header.getKey(), header.getValue()); } } InputStream in = request.getInputStream(); OutputStream out = response.getOutputStream(); TTransport transport = new TIOStreamTransport(in, out); inTransport = transport; outTransport = transport; TProtocol inProtocol = inFactory.getProtocol(inTransport); TProtocol outProtocol = inFactory.getProtocol(outTransport); processor.process(inProtocol, outProtocol); out.flush(); } catch (TException te) { throw new ServletException(te); } } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } public void addCustomHeader(final String key, final String value) { this.customHeaders.add( new Map.Entry() { @Override public String getKey() { return key; } @Override public String getValue() { return value; } @Override public String setValue(String value) { return null; } }); } public void setCustomHeaders(Collection> headers) { this.customHeaders.clear(); this.customHeaders.addAll(headers); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/Invocation.java0000664000175000017500000000110315165535636027305 0ustar00buildbuild00000000000000package org.apache.thrift.server; import org.apache.thrift.server.AbstractNonblockingServer.FrameBuffer; /** * An Invocation represents a method call that is prepared to execute, given an idle worker thread. * It contains the input and output protocols the thread's processor should use to perform the usual * Thrift invocation. */ class Invocation implements Runnable { private final FrameBuffer frameBuffer; public Invocation(final FrameBuffer frameBuffer) { this.frameBuffer = frameBuffer; } @Override public void run() { frameBuffer.invoke(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TThreadPoolServer.java0000664000175000017500000002345715165535636030570 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.net.SocketAddress; import java.net.SocketException; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.SocketAddressProvider; import org.apache.thrift.transport.TServerTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Server which uses Java's built in ThreadPool management to spawn off a worker pool that deals * with client connections in blocking way. */ public class TThreadPoolServer extends TServer { private static final Logger LOGGER = LoggerFactory.getLogger(TThreadPoolServer.class); public static class Args extends AbstractServerArgs { public int minWorkerThreads = 5; public int maxWorkerThreads = Integer.MAX_VALUE; public ExecutorService executorService; public int stopTimeoutVal = 60; public TimeUnit stopTimeoutUnit = TimeUnit.SECONDS; public Args(TServerTransport transport) { super(transport); } public Args minWorkerThreads(int n) { minWorkerThreads = n; return this; } public Args maxWorkerThreads(int n) { maxWorkerThreads = n; return this; } public Args stopTimeoutVal(int n) { stopTimeoutVal = n; return this; } public Args stopTimeoutUnit(TimeUnit tu) { stopTimeoutUnit = tu; return this; } public Args executorService(ExecutorService executorService) { this.executorService = executorService; return this; } } // Executor service for handling client connections private final ExecutorService executorService_; private final TimeUnit stopTimeoutUnit; private final long stopTimeoutVal; public TThreadPoolServer(Args args) { super(args); stopTimeoutUnit = args.stopTimeoutUnit; stopTimeoutVal = args.stopTimeoutVal; executorService_ = args.executorService != null ? args.executorService : createDefaultExecutorService(args); } private static ExecutorService createDefaultExecutorService(Args args) { return new ThreadPoolExecutor( args.minWorkerThreads, args.maxWorkerThreads, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadFactory() { final AtomicLong count = new AtomicLong(); @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(true); thread.setName( String.format("TThreadPoolServer WorkerProcess-%d", count.getAndIncrement())); return thread; } }); } protected ExecutorService getExecutorService() { return executorService_; } protected boolean preServe() { try { serverTransport_.listen(); } catch (TTransportException ttx) { LOGGER.error("Error occurred during listening.", ttx); return false; } // Run the preServe event if (eventHandler_ != null) { eventHandler_.preServe(); } stopped_ = false; setServing(true); return true; } @Override public void serve() { if (!preServe()) { return; } execute(); executorService_.shutdownNow(); if (!waitForShutdown()) { LOGGER.error("Shutdown is not done after " + stopTimeoutVal + stopTimeoutUnit); } setServing(false); } protected void execute() { while (!stopped_) { try { TTransport client = serverTransport_.accept(); try { executorService_.execute(new WorkerProcess(client)); } catch (RejectedExecutionException ree) { if (!stopped_) { LOGGER.warn( "ThreadPool is saturated with incoming requests. Closing latest connection."); } client.close(); } } catch (TTransportException ttx) { if (!stopped_) { LOGGER.warn("Transport error occurred during acceptance of message", ttx); } } } } protected boolean waitForShutdown() { // Loop until awaitTermination finally does return without a interrupted // exception. If we don't do this, then we'll shut down prematurely. We want // to let the executorService clear it's task queue, closing client sockets // appropriately. long timeoutMS = stopTimeoutUnit.toMillis(stopTimeoutVal); long now = System.currentTimeMillis(); while (timeoutMS >= 0) { try { return executorService_.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS); } catch (InterruptedException ix) { long newnow = System.currentTimeMillis(); timeoutMS -= (newnow - now); now = newnow; } } return false; } @Override public void stop() { stopped_ = true; serverTransport_.interrupt(); } private class WorkerProcess implements Runnable { /** Client that this services. */ private final TTransport client_; /** * Default constructor. * * @param client Transport to process */ private WorkerProcess(TTransport client) { client_ = client; } /** Loops on processing a client forever */ @Override public void run() { TProcessor processor = null; TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; Optional eventHandler = Optional.empty(); ServerContext connectionContext = null; try { processor = processorFactory_.getProcessor(client_); inputTransport = inputTransportFactory_.getTransport(client_); outputTransport = outputTransportFactory_.getTransport(client_); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); eventHandler = Optional.ofNullable(getEventHandler()); if (eventHandler.isPresent()) { connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol); SocketAddress remoteAddress = client_ instanceof SocketAddressProvider ? ((SocketAddressProvider) client_).getRemoteSocketAddress() : null; connectionContext.setRemoteAddress(remoteAddress); } while (true) { if (Thread.currentThread().isInterrupted()) { LOGGER.debug("WorkerProcess requested to shutdown"); break; } if (eventHandler.isPresent()) { eventHandler.get().processContext(connectionContext, inputTransport, outputTransport); } // This process cannot be interrupted by Interrupting the Thread. This // will return once a message has been processed or the socket timeout // has elapsed, at which point it will return and check the interrupt // state of the thread. processor.process(inputProtocol, outputProtocol); } } catch (Exception x) { logException(x); } finally { if (eventHandler.isPresent()) { eventHandler.get().deleteContext(connectionContext, inputProtocol, outputProtocol); } if (inputTransport != null) { inputTransport.close(); } if (outputTransport != null) { outputTransport.close(); } if (client_.isOpen()) { client_.close(); } } } 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 LOGGER.debug("Error processing request", x); TTransportException tTransportException = null; if (x instanceof TTransportException) { tTransportException = (TTransportException) x; } else if (x.getCause() instanceof TTransportException) { tTransportException = (TTransportException) x.getCause(); } if (tTransportException != null) { switch (tTransportException.getType()) { case TTransportException.END_OF_FILE: case TTransportException.TIMED_OUT: return; // don't log these } if (tTransportException.getCause() instanceof SocketException) { LOGGER.warn( "SocketException occurred during processing of message.", tTransportException.getCause()); return; } } // Log the exception at error level and continue LOGGER.error( (x instanceof TException ? "Thrift " : "") + "Error occurred during processing of message.", x); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/server/TServerEventHandler.java0000664000175000017500000000412215165535636031072 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TTransport; /** * Interface that can handle events from the server core. To use this you should subclass it and * implement the methods that you care about. Your subclass can also store local data that you may * care about, such as additional "arguments" to these methods (stored in the object instance's * state). * *

TODO: It seems this is a custom code entry point created for some resource management purpose * in hive. But when looking into hive code, we see that the argments of TProtocol and TTransport * are never used. We probably should remove these arguments from all the methods. */ public interface TServerEventHandler { /** Called before the server begins. */ void preServe(); /** Called when a new client has connected and is about to being processing. */ ServerContext createContext(TProtocol input, TProtocol output); /** Called when a client has finished request-handling to delete server context. */ void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output); /** Called when a client is about to call the processor. */ void processContext( ServerContext serverContext, TTransport inputTransport, TTransport outputTransport); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TDeserializer.java0000664000175000017500000006475415165535636026461 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.Collection; import org.apache.thrift.meta_data.EnumMetaData; import org.apache.thrift.meta_data.StructMetaData; import org.apache.thrift.partial.TFieldData; import org.apache.thrift.partial.ThriftFieldValueProcessor; import org.apache.thrift.partial.ThriftMetadata; import org.apache.thrift.partial.ThriftStructProcessor; import org.apache.thrift.partial.Validate; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TList; import org.apache.thrift.protocol.TMap; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TSet; import org.apache.thrift.protocol.TType; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransportException; /** Generic utility for easily deserializing objects from a byte array or Java String. */ public class TDeserializer { private final TProtocol protocol_; private final TMemoryInputTransport trans_; // Metadata that describes fields to deserialize during partial deserialization. private ThriftMetadata.ThriftStruct metadata_ = null; // Processor that handles deserialized field values during partial deserialization. private ThriftFieldValueProcessor processor_ = null; /** * Create a new TDeserializer that uses the TBinaryProtocol by default. * * @throws TTransportException if there an error initializing the underlying transport. */ public TDeserializer() throws TTransportException { this(new TBinaryProtocol.Factory()); } /** * Create a new TDeserializer. It will use the TProtocol specified by the factory that is passed * in. * * @param protocolFactory Factory to create a protocol * @throws TTransportException if there an error initializing the underlying transport. */ public TDeserializer(TProtocolFactory protocolFactory) throws TTransportException { trans_ = new TMemoryInputTransport(new TConfiguration()); protocol_ = protocolFactory.getProtocol(trans_); } /** * Construct a new TDeserializer that supports partial deserialization that outputs instances of * type controlled by the given {@code processor}. * * @param thriftClass a TBase derived class. * @param fieldNames list of fields to deserialize. * @param processor the Processor that handles deserialized field values. * @param protocolFactory the Factory to create a protocol. */ public TDeserializer( Class thriftClass, Collection fieldNames, ThriftFieldValueProcessor processor, TProtocolFactory protocolFactory) throws TTransportException { this(protocolFactory); Validate.checkNotNull(thriftClass, "thriftClass"); Validate.checkNotNull(fieldNames, "fieldNames"); Validate.checkNotNull(processor, "processor"); metadata_ = ThriftMetadata.ThriftStruct.fromFieldNames(thriftClass, fieldNames); processor_ = processor; } /** * Construct a new TDeserializer that supports partial deserialization that outputs {@code TBase} * instances. * * @param thriftClass a TBase derived class. * @param fieldNames list of fields to deserialize. * @param protocolFactory the Factory to create a protocol. */ public TDeserializer( Class thriftClass, Collection fieldNames, TProtocolFactory protocolFactory) throws TTransportException { this(thriftClass, fieldNames, new ThriftStructProcessor(), protocolFactory); } /** * Gets the metadata used for partial deserialization. * * @return the metadata used for partial deserialization. */ public ThriftMetadata.ThriftStruct getMetadata() { return metadata_; } /** * Deserialize the Thrift object from a byte array. * * @param base The object to read into * @param bytes The array to read from * @throws TException if an error is encountered during deserialization. */ public void deserialize(TBase base, byte[] bytes) throws TException { deserialize(base, bytes, 0, bytes.length); } /** * Deserialize the Thrift object from a byte array. * * @param base The object to read into * @param bytes The array to read from * @param offset The offset into {@code bytes} * @param length The length to read from {@code bytes} * @throws TException if an error is encountered during deserialization. */ public void deserialize(TBase base, byte[] bytes, int offset, int length) throws TException { if (this.isPartialDeserializationMode()) { this.partialDeserializeThriftObject(base, bytes, offset, length); } else { try { trans_.reset(bytes, offset, length); base.read(protocol_); } finally { trans_.clear(); protocol_.reset(); } } } /** * Deserialize the Thrift object from a Java string, using a specified character set for decoding. * * @param base The object to read into * @param data The string to read from * @param charset Valid JVM charset * @throws TException if an error is encountered during deserialization. */ public void deserialize(TBase base, String data, String charset) throws TException { try { deserialize(base, data.getBytes(charset)); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); } finally { protocol_.reset(); } } /** * Deserialize only a single Thrift object (addressed by recursively using field id) from a byte * record. * * @param tb The object to read into * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path tb * @param fieldIdPathRest The rest FieldId's that define a path tb * @throws TException if an error is encountered during deserialization. */ public void partialDeserialize( TBase tb, byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { try { if (locateField(bytes, fieldIdPathFirst, fieldIdPathRest) != null) { // if this line is reached, iprot will be positioned at the start of tb. tb.read(protocol_); } } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } /** * Deserialize only a boolean field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a boolean field * @param fieldIdPathRest The rest FieldId's that define a path to a boolean field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public Boolean partialDeserializeBool( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { return (Boolean) partialDeserializeField(TType.BOOL, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a byte field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a byte field * @param fieldIdPathRest The rest FieldId's that define a path to a byte field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public Byte partialDeserializeByte( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { return (Byte) partialDeserializeField(TType.BYTE, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a double field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a double field * @param fieldIdPathRest The rest FieldId's that define a path to a double field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public Double partialDeserializeDouble( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { return (Double) partialDeserializeField(TType.DOUBLE, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i16 field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i16 field * @param fieldIdPathRest The rest FieldId's that define a path to an i16 field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public Short partialDeserializeI16( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { return (Short) partialDeserializeField(TType.I16, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i32 field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i32 field * @param fieldIdPathRest The rest FieldId's that define a path to an i32 field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public Integer partialDeserializeI32( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { return (Integer) partialDeserializeField(TType.I32, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i64 field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i64 field * @param fieldIdPathRest The rest FieldId's that define a path to an i64 field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public Long partialDeserializeI64( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { return (Long) partialDeserializeField(TType.I64, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a string field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a string field * @param fieldIdPathRest The rest FieldId's that define a path to a string field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public String partialDeserializeString( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { return (String) partialDeserializeField(TType.STRING, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a binary field (addressed by recursively using field id) from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a binary field * @param fieldIdPathRest The rest FieldId's that define a path to a binary field * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public ByteBuffer partialDeserializeByteArray( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { // TType does not have binary, so we use the arbitrary num 100 return (ByteBuffer) partialDeserializeField((byte) 100, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only the id of the field set in a TUnion (addressed by recursively using field id) * from a byte record. * * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a TUnion * @param fieldIdPathRest The rest FieldId's that define a path to a TUnion * @return the deserialized value. * @throws TException if an error is encountered during deserialization. */ public Short partialDeserializeSetFieldIdInUnion( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { try { TField field = locateField(bytes, fieldIdPathFirst, fieldIdPathRest); if (field != null) { protocol_.readStructBegin(); // The Union return protocol_.readFieldBegin().id; // The field set in the union } return null; } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } private Object partialDeserializeField( byte ttype, byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { try { TField field = locateField(bytes, fieldIdPathFirst, fieldIdPathRest); if (field != null) { if (ttype == field.type) { // if this point is reached, iprot will be positioned at the start of // the field switch (ttype) { case TType.BOOL: return protocol_.readBool(); case TType.BYTE: return protocol_.readByte(); case TType.DOUBLE: return protocol_.readDouble(); case TType.I16: return protocol_.readI16(); case TType.I32: return protocol_.readI32(); case TType.I64: return protocol_.readI64(); case TType.STRING: return protocol_.readString(); default: return null; } } // hack to differentiate between string and binary if (ttype == 100 && field.type == TType.STRING) { return protocol_.readBinary(); } } return null; } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } private TField locateField( byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { trans_.reset(bytes); TFieldIdEnum[] fieldIdPath = new TFieldIdEnum[fieldIdPathRest.length + 1]; fieldIdPath[0] = fieldIdPathFirst; System.arraycopy(fieldIdPathRest, 0, fieldIdPath, 1, fieldIdPathRest.length); // index into field ID path being currently searched for int curPathIndex = 0; // this will be the located field, or null if it is not located TField field = null; protocol_.readStructBegin(); while (curPathIndex < fieldIdPath.length) { field = protocol_.readFieldBegin(); // we can stop searching if we either see a stop or we go past the field // id we're looking for (since fields should now be serialized in asc // order). if (field.type == TType.STOP || field.id > fieldIdPath[curPathIndex].getThriftFieldId()) { return null; } if (field.id != fieldIdPath[curPathIndex].getThriftFieldId()) { // Not the field we're looking for. Skip field. TProtocolUtil.skip(protocol_, field.type); protocol_.readFieldEnd(); } else { // This field is the next step in the path. Step into field. curPathIndex++; if (curPathIndex < fieldIdPath.length) { protocol_.readStructBegin(); } } } return field; } /** * Deserialize the Thrift object from a Java string, using the default JVM charset encoding. * * @param base The object to read into * @param data The string to read from * @throws TException if an error is encountered during deserialization. */ public void fromString(TBase base, String data) throws TException { deserialize(base, data.getBytes()); } // ---------------------------------------------------------------------- // Methods related to partial deserialization. /** * Partially deserializes the given serialized blob. * * @param bytes the serialized blob. * @return deserialized instance. * @throws TException if an error is encountered during deserialization. */ public Object partialDeserializeObject(byte[] bytes) throws TException { return this.partialDeserializeObject(bytes, 0, bytes.length); } /** * Partially deserializes the given serialized blob into the given {@code TBase} instance. * * @param base the instance into which the given blob is deserialized. * @param bytes the serialized blob. * @param offset the blob is read starting at this offset. * @param length the size of blob read (in number of bytes). * @return deserialized instance. * @throws TException if an error is encountered during deserialization. */ public Object partialDeserializeThriftObject(TBase base, byte[] bytes, int offset, int length) throws TException { ensurePartialThriftDeserializationMode(); return this.partialDeserializeObject(base, bytes, offset, length); } /** * Partially deserializes the given serialized blob. * * @param bytes the serialized blob. * @param offset the blob is read starting at this offset. * @param length the size of blob read (in number of bytes). * @return deserialized instance. * @throws TException if an error is encountered during deserialization. */ public Object partialDeserializeObject(byte[] bytes, int offset, int length) throws TException { ensurePartialDeserializationMode(); return this.partialDeserializeObject(null, bytes, offset, length); } /** * Partially deserializes the given serialized blob. * * @param instance the instance into which the given blob is deserialized. * @param bytes the serialized blob. * @param offset the blob is read starting at this offset. * @param length the size of blob read (in number of bytes). * @return deserialized instance. * @throws TException if an error is encountered during deserialization. */ private Object partialDeserializeObject(Object instance, byte[] bytes, int offset, int length) throws TException { ensurePartialDeserializationMode(); this.trans_.reset(bytes, offset, length); this.protocol_.reset(); return this.deserializeStruct(instance, this.metadata_); } private Object deserialize(ThriftMetadata.ThriftObject data) throws TException { Object value; byte fieldType = data.data.valueMetaData.type; switch (fieldType) { case TType.STRUCT: return this.deserializeStruct(null, (ThriftMetadata.ThriftStruct) data); case TType.LIST: return this.deserializeList((ThriftMetadata.ThriftList) data); case TType.MAP: return this.deserializeMap((ThriftMetadata.ThriftMap) data); case TType.SET: return this.deserializeSet((ThriftMetadata.ThriftSet) data); case TType.ENUM: return this.deserializeEnum((ThriftMetadata.ThriftEnum) data); case TType.BOOL: return this.protocol_.readBool(); case TType.BYTE: return this.protocol_.readByte(); case TType.I16: return this.protocol_.readI16(); case TType.I32: return this.protocol_.readI32(); case TType.I64: return this.protocol_.readI64(); case TType.DOUBLE: return this.protocol_.readDouble(); case TType.STRING: if (((ThriftMetadata.ThriftPrimitive) data).isBinary()) { return this.processor_.prepareBinary(this.protocol_.readBinary()); } else { return this.processor_.prepareString(this.protocol_.readBinary()); } default: throw unsupportedFieldTypeException(fieldType); } } private Object deserializeStruct(Object instance, ThriftMetadata.ThriftStruct data) throws TException { if (instance == null) { instance = this.processor_.createNewStruct(data); } this.protocol_.readStructBegin(); while (true) { int tfieldData = this.protocol_.readFieldBeginData(); byte tfieldType = TFieldData.getType(tfieldData); if (tfieldType == TType.STOP) { break; } Integer id = (int) TFieldData.getId(tfieldData); ThriftMetadata.ThriftObject field = (ThriftMetadata.ThriftObject) data.fields.get(id); if (field != null) { this.deserializeStructField(instance, field.fieldId, field); } else { this.protocol_.skip(tfieldType); } this.protocol_.readFieldEnd(); } this.protocol_.readStructEnd(); return this.processor_.prepareStruct(instance); } private void deserializeStructField( Object instance, TFieldIdEnum fieldId, ThriftMetadata.ThriftObject data) throws TException { byte fieldType = data.data.valueMetaData.type; Object value; switch (fieldType) { case TType.BOOL: this.processor_.setBool(instance, fieldId, this.protocol_.readBool()); break; case TType.BYTE: this.processor_.setByte(instance, fieldId, this.protocol_.readByte()); break; case TType.I16: this.processor_.setInt16(instance, fieldId, this.protocol_.readI16()); break; case TType.I32: this.processor_.setInt32(instance, fieldId, this.protocol_.readI32()); break; case TType.I64: this.processor_.setInt64(instance, fieldId, this.protocol_.readI64()); break; case TType.DOUBLE: this.processor_.setDouble(instance, fieldId, this.protocol_.readDouble()); break; case TType.STRING: if (((ThriftMetadata.ThriftPrimitive) data).isBinary()) { this.processor_.setBinary(instance, fieldId, this.protocol_.readBinary()); } else { this.processor_.setString(instance, fieldId, this.protocol_.readBinary()); } break; case TType.STRUCT: value = this.deserializeStruct(null, (ThriftMetadata.ThriftStruct) data); this.processor_.setStructField(instance, fieldId, value); break; case TType.LIST: value = this.deserializeList((ThriftMetadata.ThriftList) data); this.processor_.setListField(instance, fieldId, value); break; case TType.MAP: value = this.deserializeMap((ThriftMetadata.ThriftMap) data); this.processor_.setMapField(instance, fieldId, value); break; case TType.SET: value = this.deserializeSet((ThriftMetadata.ThriftSet) data); this.processor_.setSetField(instance, fieldId, value); break; case TType.ENUM: value = this.deserializeEnum((ThriftMetadata.ThriftEnum) data); this.processor_.setEnumField(instance, fieldId, value); break; default: throw new RuntimeException("Unsupported field type: " + fieldId.toString()); } } private Object deserializeList(ThriftMetadata.ThriftList data) throws TException { TList tlist = this.protocol_.readListBegin(); Object instance = this.processor_.createNewList(tlist.size); for (int i = 0; i < tlist.size; i++) { Object value = this.deserialize(data.elementData); this.processor_.setListElement(instance, i, value); } this.protocol_.readListEnd(); return this.processor_.prepareList(instance); } private Object deserializeMap(ThriftMetadata.ThriftMap data) throws TException { TMap tmap = this.protocol_.readMapBegin(); Object instance = this.processor_.createNewMap(tmap.size); for (int i = 0; i < tmap.size; i++) { Object key = this.deserialize(data.keyData); Object val = this.deserialize(data.valueData); this.processor_.setMapElement(instance, i, key, val); } this.protocol_.readMapEnd(); return this.processor_.prepareMap(instance); } private Object deserializeSet(ThriftMetadata.ThriftSet data) throws TException { TSet tset = this.protocol_.readSetBegin(); Object instance = this.processor_.createNewSet(tset.size); for (int i = 0; i < tset.size; i++) { Object eltValue = this.deserialize(data.elementData); this.processor_.setSetElement(instance, i, eltValue); } this.protocol_.readSetEnd(); return this.processor_.prepareSet(instance); } private Object deserializeEnum(ThriftMetadata.ThriftEnum data) throws TException { int ordinal = this.protocol_.readI32(); Class enumClass = ((EnumMetaData) data.data.valueMetaData).enumClass; return this.processor_.prepareEnum(enumClass, ordinal); } private Class getStructClass(ThriftMetadata.ThriftStruct data) { return (Class) ((StructMetaData) data.data.valueMetaData).structClass; } private static UnsupportedOperationException unsupportedFieldTypeException(byte fieldType) { return new UnsupportedOperationException("field type not supported: " + fieldType); } private boolean isPartialDeserializationMode() { return (this.metadata_ != null) && (this.processor_ != null); } private void ensurePartialDeserializationMode() throws IllegalStateException { if (!this.isPartialDeserializationMode()) { throw new IllegalStateException( "Members metadata and processor must be correctly initialized in order to use this method"); } } private void ensurePartialThriftDeserializationMode() throws IllegalStateException { this.ensurePartialDeserializationMode(); if (!(this.processor_ instanceof ThriftStructProcessor)) { throw new IllegalStateException( "processor must be an instance of ThriftStructProcessor to use this method"); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/async/0000775000175000017500000000000015165535636024145 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/async/TAsyncClientFactory.java0000664000175000017500000000176715165535636030713 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import org.apache.thrift.transport.TNonblockingTransport; public interface TAsyncClientFactory { T getAsyncClient(TNonblockingTransport transport); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/async/TAsyncClient.java0000664000175000017500000000621215165535636027351 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TNonblockingTransport; public abstract class TAsyncClient { protected final TProtocolFactory ___protocolFactory; protected final TNonblockingTransport ___transport; protected final TAsyncClientManager ___manager; protected TAsyncMethodCall ___currentMethod; private Exception ___error; private long ___timeout; public TAsyncClient( TProtocolFactory protocolFactory, TAsyncClientManager manager, TNonblockingTransport transport) { this(protocolFactory, manager, transport, 0); } public TAsyncClient( TProtocolFactory protocolFactory, TAsyncClientManager manager, TNonblockingTransport transport, long timeout) { this.___protocolFactory = protocolFactory; this.___manager = manager; this.___transport = transport; this.___timeout = timeout; } public TProtocolFactory getProtocolFactory() { return ___protocolFactory; } public long getTimeout() { return ___timeout; } public boolean hasTimeout() { return ___timeout > 0; } public void setTimeout(long timeout) { this.___timeout = timeout; } /** * Is the client in an error state? * * @return If client in an error state? */ public boolean hasError() { return ___error != null; } /** * Get the client's error - returns null if no error * * @return Get the client's error. *

returns null if no error */ public Exception getError() { return ___error; } protected void checkReady() { // Ensure we are not currently executing a method if (___currentMethod != null) { throw new IllegalStateException( "Client is currently executing another method: " + ___currentMethod.getClass().getName()); } // Ensure we're not in an error state if (___error != null) { throw new IllegalStateException("Client has an error!", ___error); } } /** Called by delegate method when finished */ protected void onComplete() { ___currentMethod = null; } /** * Called by delegate method on error. * * @param exception the exception indicating the current error condition. */ protected void onError(Exception exception) { ___transport.close(); ___currentMethod = null; ___error = exception; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/async/TAsyncClientManager.java0000664000175000017500000001625415165535636030653 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import java.io.IOException; import java.io.Serializable; import java.nio.channels.ClosedSelectorException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.SelectorProvider; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeoutException; import org.apache.thrift.TException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Contains selector thread which transitions method call objects */ public class TAsyncClientManager { private static final Logger LOGGER = LoggerFactory.getLogger(TAsyncClientManager.class.getName()); private final SelectThread selectThread; private final ConcurrentLinkedQueue> pendingCalls = new ConcurrentLinkedQueue<>(); public TAsyncClientManager() throws IOException { this.selectThread = new SelectThread(); selectThread.start(); } public void call(TAsyncMethodCall method) throws TException { if (!isRunning()) { throw new TException("SelectThread is not running"); } method.prepareMethodCall(); pendingCalls.add(method); selectThread.getSelector().wakeup(); } public void stop() { selectThread.finish(); } public boolean isRunning() { return selectThread.isAlive(); } private class SelectThread extends Thread { private final Selector selector; private volatile boolean running; private final TreeSet> timeoutWatchSet = new TreeSet<>(new TAsyncMethodCallTimeoutComparator()); public SelectThread() throws IOException { this.selector = SelectorProvider.provider().openSelector(); this.running = true; this.setName("TAsyncClientManager#SelectorThread " + this.getId()); // We don't want to hold up the JVM when shutting down setDaemon(true); } public Selector getSelector() { return selector; } public void finish() { running = false; selector.wakeup(); } public void run() { while (running) { try { try { if (timeoutWatchSet.size() == 0) { // No timeouts, so select indefinitely selector.select(); } else { // We have a timeout pending, so calculate the time until then and select // appropriately long nextTimeout = timeoutWatchSet.first().getTimeoutTimestamp(); long selectTime = nextTimeout - System.currentTimeMillis(); if (selectTime > 0) { // Next timeout is in the future, select and wake up then selector.select(selectTime); } else { // Next timeout is now or in the past, select immediately, so we can time out selector.selectNow(); } } } catch (IOException e) { LOGGER.error("Caught IOException in TAsyncClientManager!", e); } transitionMethods(); timeoutMethods(); startPendingMethods(); } catch (Exception exception) { LOGGER.error("Ignoring uncaught exception in SelectThread", exception); } } try { selector.close(); } catch (IOException ex) { LOGGER.warn("Could not close selector. This may result in leaked resources!", ex); } } // Transition methods for ready keys private void transitionMethods() { try { Iterator keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); keys.remove(); if (!key.isValid()) { // this can happen if the method call experienced an error and the // key was cancelled. can also happen if we time out a method, which // results in a channel close. // just skip continue; } TAsyncMethodCall methodCall = (TAsyncMethodCall) key.attachment(); methodCall.transition(key); // If done or error occurred, remove from timeout watch set if (methodCall.isFinished() || methodCall.getClient().hasError()) { timeoutWatchSet.remove(methodCall); } } } catch (ClosedSelectorException e) { LOGGER.error("Caught ClosedSelectorException in TAsyncClientManager!", e); } } // Timeout any existing method calls private void timeoutMethods() { Iterator> iterator = timeoutWatchSet.iterator(); long currentTime = System.currentTimeMillis(); while (iterator.hasNext()) { TAsyncMethodCall methodCall = iterator.next(); if (currentTime >= methodCall.getTimeoutTimestamp()) { iterator.remove(); methodCall.onError( new TimeoutException( "Operation " + methodCall.getClass() + " timed out after " + (currentTime - methodCall.getStartTime()) + " ms.")); } else { break; } } } // Start any new calls private void startPendingMethods() { TAsyncMethodCall methodCall; while ((methodCall = pendingCalls.poll()) != null) { // Catch registration errors. method will catch transition errors and cleanup. try { methodCall.start(selector); // If timeout specified and first transition went smoothly, add to timeout watch set TAsyncClient client = methodCall.getClient(); if (client.hasTimeout() && !client.hasError()) { timeoutWatchSet.add(methodCall); } } catch (Exception exception) { LOGGER.warn("Caught exception in TAsyncClientManager!", exception); methodCall.onError(exception); } } } } /** Comparator used in TreeSet */ private static class TAsyncMethodCallTimeoutComparator implements Comparator>, Serializable { @Override public int compare(TAsyncMethodCall left, TAsyncMethodCall right) { if (left.getTimeoutTimestamp() == right.getTimeoutTimestamp()) { return (int) (left.getSequenceId() - right.getSequenceId()); } else { return (int) (left.getTimeoutTimestamp() - right.getTimeoutTimestamp()); } } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/async/TAsyncMethodCall.java0000664000175000017500000002124515165535636030152 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.concurrent.atomic.AtomicLong; import org.apache.thrift.TException; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.layered.TFramedTransport; /** * Encapsulates an async method call. * *

Need to generate: * *

    *
  • protected abstract void write_args(TProtocol protocol) *
  • protected abstract T getResult() throws <Exception_1>, <Exception_2>, ... *
* * @param The return type of the encapsulated method call. */ public abstract class TAsyncMethodCall { private static final int INITIAL_MEMORY_BUFFER_SIZE = 128; private static final AtomicLong sequenceIdCounter = new AtomicLong(0); public enum State { CONNECTING, WRITING_REQUEST_SIZE, WRITING_REQUEST_BODY, READING_RESPONSE_SIZE, READING_RESPONSE_BODY, RESPONSE_READ, ERROR; } /** Next step in the call, initialized by start() */ private State state = null; protected final TNonblockingTransport transport; private final TProtocolFactory protocolFactory; protected final TAsyncClient client; private final AsyncMethodCallback callback; private final boolean isOneway; private final long sequenceId; private final long timeout; private ByteBuffer sizeBuffer; private final byte[] sizeBufferArray = new byte[4]; private ByteBuffer frameBuffer; private final long startTime = System.currentTimeMillis(); protected TAsyncMethodCall( TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport, AsyncMethodCallback callback, boolean isOneway) { this.transport = transport; this.callback = callback; this.protocolFactory = protocolFactory; this.client = client; this.isOneway = isOneway; this.sequenceId = TAsyncMethodCall.sequenceIdCounter.getAndIncrement(); this.timeout = client.getTimeout(); } protected State getState() { return state; } protected boolean isFinished() { return state == State.RESPONSE_READ; } protected long getStartTime() { return startTime; } protected long getSequenceId() { return sequenceId; } public TAsyncClient getClient() { return client; } public boolean hasTimeout() { return timeout > 0; } public long getTimeoutTimestamp() { return timeout + startTime; } protected abstract void write_args(TProtocol protocol) throws TException; protected abstract T getResult() throws Exception; /** * Initialize buffers. * * @throws TException if buffer initialization fails */ protected void prepareMethodCall() throws TException { TMemoryBuffer memoryBuffer = new TMemoryBuffer(INITIAL_MEMORY_BUFFER_SIZE); TProtocol protocol = protocolFactory.getProtocol(memoryBuffer); write_args(protocol); int length = memoryBuffer.length(); frameBuffer = ByteBuffer.wrap(memoryBuffer.getArray(), 0, length); TFramedTransport.encodeFrameSize(length, sizeBufferArray); sizeBuffer = ByteBuffer.wrap(sizeBufferArray); } /** * Register with selector and start first state, which could be either connecting or writing. * * @throws IOException if register or starting fails */ void start(Selector sel) throws IOException { SelectionKey key; if (transport.isOpen()) { state = State.WRITING_REQUEST_SIZE; key = transport.registerSelector(sel, SelectionKey.OP_WRITE); } else { state = State.CONNECTING; key = transport.registerSelector(sel, SelectionKey.OP_CONNECT); // non-blocking connect can complete immediately, // in which case we should not expect the OP_CONNECT if (transport.startConnect()) { registerForFirstWrite(key); } } key.attach(this); } void registerForFirstWrite(SelectionKey key) throws IOException { state = State.WRITING_REQUEST_SIZE; key.interestOps(SelectionKey.OP_WRITE); } protected ByteBuffer getFrameBuffer() { return frameBuffer; } /** * Transition to next state, doing whatever work is required. Since this method is only called by * the selector thread, we can make changes to our select interests without worrying about * concurrency. * * @param key selection key */ void transition(SelectionKey key) { // Ensure key is valid if (!key.isValid()) { key.cancel(); Exception e = new TTransportException("Selection key not valid!"); onError(e); return; } // Transition function try { switch (state) { case CONNECTING: doConnecting(key); break; case WRITING_REQUEST_SIZE: doWritingRequestSize(); break; case WRITING_REQUEST_BODY: doWritingRequestBody(key); break; case READING_RESPONSE_SIZE: doReadingResponseSize(); break; case READING_RESPONSE_BODY: doReadingResponseBody(key); break; default: // RESPONSE_READ, ERROR, or bug throw new IllegalStateException( "Method call in state " + state + " but selector called transition method. Seems like a bug..."); } } catch (Exception e) { key.cancel(); key.attach(null); onError(e); } } protected void onError(Exception e) { client.onError(e); callback.onError(e); state = State.ERROR; } private void doReadingResponseBody(SelectionKey key) throws TTransportException { if (transport.read(frameBuffer) < 0) { throw new TTransportException(TTransportException.END_OF_FILE, "Read call frame failed"); } if (frameBuffer.remaining() == 0) { cleanUpAndFireCallback(key); } } private void cleanUpAndFireCallback(SelectionKey key) { state = State.RESPONSE_READ; key.interestOps(0); // this ensures that the TAsyncMethod instance doesn't hang around key.attach(null); try { T result = this.getResult(); client.onComplete(); callback.onComplete(result); } catch (Exception e) { key.cancel(); onError(e); } } private void doReadingResponseSize() throws TTransportException { if (transport.read(sizeBuffer) < 0) { throw new TTransportException(TTransportException.END_OF_FILE, "Read call frame size failed"); } if (sizeBuffer.remaining() == 0) { state = State.READING_RESPONSE_BODY; frameBuffer = ByteBuffer.allocate(TFramedTransport.decodeFrameSize(sizeBufferArray)); } } private void doWritingRequestBody(SelectionKey key) throws TTransportException { if (transport.write(frameBuffer) < 0) { throw new TTransportException(TTransportException.END_OF_FILE, "Write call frame failed"); } if (frameBuffer.remaining() == 0) { if (isOneway) { cleanUpAndFireCallback(key); } else { state = State.READING_RESPONSE_SIZE; sizeBuffer.rewind(); // Prepare to read incoming frame size key.interestOps(SelectionKey.OP_READ); } } } private void doWritingRequestSize() throws TTransportException { if (transport.write(sizeBuffer) < 0) { throw new TTransportException( TTransportException.END_OF_FILE, "Write call frame size failed"); } if (sizeBuffer.remaining() == 0) { state = State.WRITING_REQUEST_BODY; } } private void doConnecting(SelectionKey key) throws IOException { if (!key.isConnectable() || !transport.finishConnect()) { throw new IOException( "not connectable or finishConnect returned false after we got an OP_CONNECT"); } registerForFirstWrite(key); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/async/AsyncMethodCallback.java0000664000175000017500000000372315165535636030650 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; /** * A handler interface asynchronous clients can implement to receive future notice of the results of * an asynchronous method call. * * @param The return type of the asynchronously invoked method. */ public interface AsyncMethodCallback { /** * This method will be called when the remote side has completed invoking your method call and the * result is fully read. For {@code oneway} method calls, this method will be called as soon as we * have completed writing out the request. * * @param response The return value of the asynchronously invoked method; {@code null} for void * methods which includes {@code oneway} methods. */ void onComplete(T response); /** * This method will be called when there is either an unexpected client-side exception like an * IOException or else when the remote method raises an exception, either declared in the IDL or * due to an unexpected server-side error. * * @param exception The exception encountered processing the the asynchronous method call, may be * a local exception or an unmarshalled remote exception. */ void onError(Exception exception); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/async/AsyncMethodFutureAdapter.java0000664000175000017500000000163115165535636031723 0ustar00buildbuild00000000000000package org.apache.thrift.async; import java.util.concurrent.CompletableFuture; /** * A simple adapter that bridges {@link AsyncMethodCallback} with {@link * CompletableFuture}-returning style clients. Compiler generated code will invoke this adapter to * implement {@code FutureClient}s. * * @param return type (can be {@link Void}). */ public final class AsyncMethodFutureAdapter implements AsyncMethodCallback { private AsyncMethodFutureAdapter() {} public static AsyncMethodFutureAdapter create() { return new AsyncMethodFutureAdapter<>(); } private final CompletableFuture future = new CompletableFuture<>(); public CompletableFuture getFuture() { return future; } @Override public void onComplete(T response) { future.complete(response); } @Override public void onError(Exception exception) { future.completeExceptionally(exception); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TNonblockingMultiFetchStats.java0000664000175000017500000000702015165535636031265 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** This class keeps track of statistics for TNonblockinMultiFetchClient. */ public class TNonblockingMultiFetchStats { private int numTotalServers; private int numReadCompletedServers; private int numConnectErrorServers; private int totalRecvBufBytes; private int maxResponseBytes; private int numOverflowedRecvBuf; private int numInvalidFrameSize; // time from the beginning of fetch() function to the reading finish // time of the last socket (in millisecond) private long readTime; public TNonblockingMultiFetchStats() { clear(); } public void clear() { numTotalServers = 0; numReadCompletedServers = 0; numConnectErrorServers = 0; totalRecvBufBytes = 0; maxResponseBytes = 0; numOverflowedRecvBuf = 0; numInvalidFrameSize = 0; readTime = 0; } public String toString() { String stats = String.format( "numTotalServers=%d, " + "numReadCompletedServers=%d, numConnectErrorServers=%d, " + "numUnresponsiveServers=%d, totalRecvBufBytes=%fM, " + "maxResponseBytes=%d, numOverflowedRecvBuf=%d, " + "numInvalidFrameSize=%d, readTime=%dms", numTotalServers, numReadCompletedServers, numConnectErrorServers, (numTotalServers - numReadCompletedServers - numConnectErrorServers), totalRecvBufBytes / 1024.0 / 1024, maxResponseBytes, numOverflowedRecvBuf, numInvalidFrameSize, readTime); return stats; } public void setNumTotalServers(int val) { numTotalServers = val; } public void setMaxResponseBytes(int val) { maxResponseBytes = val; } public void setReadTime(long val) { readTime = val; } public void incNumReadCompletedServers() { numReadCompletedServers++; } public void incNumConnectErrorServers() { numConnectErrorServers++; } public void incNumOverflowedRecvBuf() { numOverflowedRecvBuf++; } public void incTotalRecvBufBytes(int val) { totalRecvBufBytes += val; } public void incNumInvalidFrameSize() { numInvalidFrameSize++; } public int getMaxResponseBytes() { return maxResponseBytes; } public int getNumReadCompletedServers() { return numReadCompletedServers; } public int getNumConnectErrorServers() { return numConnectErrorServers; } public int getNumTotalServers() { return numTotalServers; } public int getNumOverflowedRecvBuf() { return numOverflowedRecvBuf; } public int getTotalRecvBufBytes() { return totalRecvBufBytes; } public int getNumInvalidFrameSize() { return numInvalidFrameSize; } public long getReadTime() { return readTime; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/scheme/0000775000175000017500000000000015165535636024274 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/scheme/IScheme.java0000664000175000017500000000216515165535636026460 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; import org.apache.thrift.TBase; public interface IScheme { void read(org.apache.thrift.protocol.TProtocol iproto, T struct) throws org.apache.thrift.TException; void write(org.apache.thrift.protocol.TProtocol oproto, T struct) throws org.apache.thrift.TException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/scheme/SchemeFactory.java0000664000175000017500000000162015165535636027672 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; public interface SchemeFactory { S getScheme(); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/scheme/StandardScheme.java0000664000175000017500000000166715165535636030036 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; import org.apache.thrift.TBase; public abstract class StandardScheme implements IScheme {} thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/scheme/TupleScheme.java0000664000175000017500000000166415165535636027364 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; import org.apache.thrift.TBase; public abstract class TupleScheme implements IScheme {} thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/ProcessFunction.java0000664000175000017500000000614715167543515027024 0ustar00buildbuild00000000000000package org.apache.thrift; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TMessageType; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolException; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class ProcessFunction { private final String methodName; private static final Logger LOGGER = LoggerFactory.getLogger(ProcessFunction.class.getName()); public ProcessFunction(String methodName) { this.methodName = methodName; } public final void process(int seqid, TProtocol iprot, TProtocol oprot, I iface) throws TException { T args = getEmptyArgsInstance(); try { args.read(iprot); } catch (TProtocolException e) { iprot.readMessageEnd(); TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid)); x.write(oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); return; } iprot.readMessageEnd(); TSerializable result = null; byte msgType = TMessageType.REPLY; try { result = getResult(iface, args); } catch (TTransportException ex) { LOGGER.error("Transport error while processing " + getMethodName(), ex); throw ex; } catch (TApplicationException ex) { LOGGER.error("Internal application error processing " + getMethodName(), ex); result = ex; msgType = TMessageType.EXCEPTION; } catch (Exception ex) { LOGGER.error("Internal error processing " + getMethodName(), ex); if (rethrowUnhandledExceptions()) throw new RuntimeException(ex.getMessage(), ex); if (!isOneway()) { result = new TApplicationException( TApplicationException.INTERNAL_ERROR, "Internal error processing " + getMethodName()); msgType = TMessageType.EXCEPTION; } } if (!isOneway()) { oprot.writeMessageBegin(new TMessage(getMethodName(), msgType, seqid)); result.write(oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); } } private void handleException(int seqid, TProtocol oprot) throws TException { if (!isOneway()) { TApplicationException x = new TApplicationException( TApplicationException.INTERNAL_ERROR, "Internal error processing " + getMethodName()); oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid)); x.write(oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); } } protected boolean rethrowUnhandledExceptions() { return false; } public abstract boolean isOneway(); public abstract A 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; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TProcessor.java0000664000175000017500000000210215165535636025771 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * A processor is a generic object which operates upon an input stream and writes to some output * stream. */ public interface TProcessor { void process(TProtocol in, TProtocol out) throws TException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TFieldRequirementType.java0000664000175000017500000000211315165535636030122 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** Requirement type constants. */ public final class TFieldRequirementType { /* no instantiation */ private TFieldRequirementType() {} public static final byte REQUIRED = 1; public static final byte OPTIONAL = 2; public static final byte DEFAULT = 3; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TBaseAsyncProcessor.java0000664000175000017500000000727115165535636027576 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.util.Collections; import java.util.Map; import org.apache.thrift.async.AsyncMethodCallback; import org.apache.thrift.protocol.*; import org.apache.thrift.server.AbstractNonblockingServer.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TBaseAsyncProcessor implements TAsyncProcessor, TProcessor { protected final Logger LOGGER = LoggerFactory.getLogger(getClass().getName()); final I iface; final Map> processMap; public TBaseAsyncProcessor( I iface, Map> processMap) { this.iface = iface; this.processMap = processMap; } public Map> getProcessMapView() { return Collections.unmodifiableMap(processMap); } public void process(final AsyncFrameBuffer fb) throws TException { final TProtocol in = fb.getInputProtocol(); final TProtocol out = fb.getOutputProtocol(); // Find processing function final TMessage msg = in.readMessageBegin(); AsyncProcessFunction fn = processMap.get(msg.name); if (fn == null) { TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException( TApplicationException.UNKNOWN_METHOD, "Invalid method name: '" + msg.name + "'"); LOGGER.debug("Invalid method name", x); // this means it is a two-way request, so we can send a reply if (msg.type == TMessageType.CALL) { out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); } fb.responseReady(); return; } // Get Args TBase args = fn.getEmptyArgsInstance(); try { args.read(in); } catch (TProtocolException e) { in.readMessageEnd(); TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); LOGGER.debug("Could not retrieve function arguments", x); if (!fn.isOneway()) { out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); } fb.responseReady(); return; } in.readMessageEnd(); if (fn.isOneway()) { fb.responseReady(); } // start off processing function AsyncMethodCallback resultHandler = fn.getResultHandler(fb, msg.seqid); try { fn.start(iface, args, resultHandler); } catch (Exception e) { LOGGER.debug("Exception handling function", e); resultHandler.onError(e); } return; } @Override public void process(TProtocol in, TProtocol out) throws TException {} } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/Option.java0000664000175000017500000000672215165535636025152 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.util.Optional; /** Implementation of the Option type pattern */ public abstract class Option { @SuppressWarnings("rawtypes") private static final Option NONE = new None(); /** * Whether the Option is defined or not * * @return true if the Option is defined (of type Some) false if the Option is not defined (of * type None) */ public abstract boolean isDefined(); /** * Get the value of the Option (if it is defined) * * @return the value * @throws IllegalStateException if called on a None */ public abstract T get(); /** * Get the contained value (if defined) or else return a default value * * @param other what to return if the value is not defined (a None) * @return either the value, or other if the value is not defined */ public T or(T other) { if (isDefined()) { return get(); } else { return other; } } /** * Turn this Option into Java 8 Optional type * * @return Java 8+ Optional Type */ public Optional toOptional() { if (isDefined()) { return Optional.of(get()); } else { return Optional.empty(); } } /** The None type, representing an absent value (instead of "null") */ public static class None extends Option { public boolean isDefined() { return false; } public T get() { throw new IllegalStateException("Cannot call get() on None"); } public String toString() { return "None"; } } /** * The Some type, representing an existence of some value * * @param The type of value */ public static class Some extends Option { private final T value; public Some(T value) { this.value = value; } public boolean isDefined() { return true; } public T get() { return value; } public String toString() { return "Some(" + value + ")"; } } /** * Wraps value in an Option type, depending on whether or not value is null * * @param value the value to wrap in Option * @param the type of value * @return Some(value) if value is not null, None if value is null */ public static Option fromNullable(T value) { if (value != null) { return some(value); } else { return none(); } } /** * Wrap value in a Some type (NB! value must not be null!) * * @param value the value to wrap. * @param the type of value * @return a new Some(value) */ public static Some some(T value) { return new Some(value); } @SuppressWarnings("unchecked") public static None none() { return (None) NONE; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/0000775000175000017500000000000015170007142025042 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TSeekableFile.java0000664000175000017500000000230515165535636030366 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public interface TSeekableFile { public InputStream getInputStream() throws IOException; public OutputStream getOutputStream() throws IOException; public void close() throws IOException; public long length() throws IOException; public void seek(long pos) throws IOException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/SocketAddressProvider.java0000664000175000017500000000204215165535636032176 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.net.SocketAddress; /** Interface that can retrieve the socket address. */ public interface SocketAddressProvider { SocketAddress getRemoteSocketAddress(); SocketAddress getLocalSocketAddress(); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/layered/0000775000175000017500000000000015165535636026511 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/layered/TFastFramedTransport.java0000664000175000017500000001547715165535636033447 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.layered; import java.util.Objects; import org.apache.thrift.TConfiguration; import org.apache.thrift.transport.*; /** * This transport is wire compatible with {@link TFramedTransport}, but makes use of reusable, * expanding read and write buffers in order to avoid allocating new byte[]s all the time. Since the * buffers only expand, you should probably only use this transport if your messages are not too * variably large, unless the persistent memory cost is not an issue. * *

This implementation is NOT threadsafe. */ public class TFastFramedTransport extends TLayeredTransport { public static class Factory extends TTransportFactory { private final int initialCapacity; private final int maxLength; public Factory() { this(DEFAULT_BUF_CAPACITY, TConfiguration.DEFAULT_MAX_FRAME_SIZE); } public Factory(int initialCapacity) { this(initialCapacity, TConfiguration.DEFAULT_MAX_FRAME_SIZE); } public Factory(int initialCapacity, int maxLength) { this.initialCapacity = initialCapacity; this.maxLength = maxLength; } @Override public TTransport getTransport(TTransport trans) throws TTransportException { return new TFastFramedTransport(trans, initialCapacity, maxLength); } } /** How big should the default read and write buffers be? */ public static final int DEFAULT_BUF_CAPACITY = 1024; private final AutoExpandingBufferWriteTransport writeBuffer; private AutoExpandingBufferReadTransport readBuffer; private final int initialBufferCapacity; private final byte[] i32buf = new byte[4]; private final int maxLength; /** * Create a new {@link TFastFramedTransport}. Use the defaults for initial buffer size and max * frame length. * * @param underlying Transport that real reads and writes will go through to. */ public TFastFramedTransport(TTransport underlying) throws TTransportException { this(underlying, DEFAULT_BUF_CAPACITY, TConfiguration.DEFAULT_MAX_FRAME_SIZE); } /** * Create a new {@link TFastFramedTransport}. Use the specified initial buffer capacity and the * default max frame length. * * @param underlying Transport that real reads and writes will go through to. * @param initialBufferCapacity The initial size of the read and write buffers. In practice, it's * not critical to set this unless you know in advance that your messages are going to be very * large. */ public TFastFramedTransport(TTransport underlying, int initialBufferCapacity) throws TTransportException { this(underlying, initialBufferCapacity, TConfiguration.DEFAULT_MAX_FRAME_SIZE); } /** * @param underlying Transport that real reads and writes will go through to. * @param initialBufferCapacity The initial size of the read and write buffers. In practice, it's * not critical to set this unless you know in advance that your messages are going to be very * large. (You can pass TFramedTransportWithReusableBuffer.DEFAULT_BUF_CAPACITY if you're only * using this constructor because you want to set the maxLength.) * @param maxLength The max frame size you are willing to read. You can use this parameter to * limit how much memory can be allocated. */ public TFastFramedTransport(TTransport underlying, int initialBufferCapacity, int maxLength) throws TTransportException { super(underlying); TConfiguration config = Objects.isNull(underlying.getConfiguration()) ? new TConfiguration() : underlying.getConfiguration(); this.maxLength = maxLength; config.setMaxFrameSize(maxLength); this.initialBufferCapacity = initialBufferCapacity; readBuffer = new AutoExpandingBufferReadTransport(config, initialBufferCapacity); writeBuffer = new AutoExpandingBufferWriteTransport(config, initialBufferCapacity, 4); } @Override public void close() { getInnerTransport().close(); } @Override public boolean isOpen() { return getInnerTransport().isOpen(); } @Override public void open() throws TTransportException { getInnerTransport().open(); } @Override public int read(byte[] buf, int off, int len) throws TTransportException { int got = readBuffer.read(buf, off, len); if (got > 0) { return got; } // Read another frame of data readFrame(); return readBuffer.read(buf, off, len); } private void readFrame() throws TTransportException { getInnerTransport().readAll(i32buf, 0, 4); int size = TFramedTransport.decodeFrameSize(i32buf); if (size < 0) { close(); throw new TTransportException( TTransportException.CORRUPTED_DATA, "Read a negative frame size (" + size + ")!"); } if (size > getInnerTransport().getConfiguration().getMaxFrameSize()) { close(); throw new TTransportException( TTransportException.CORRUPTED_DATA, "Frame size (" + size + ") larger than max length (" + maxLength + ")!"); } readBuffer.fill(getInnerTransport(), size); } @Override public void write(byte[] buf, int off, int len) throws TTransportException { writeBuffer.write(buf, off, len); } @Override public void consumeBuffer(int len) { readBuffer.consumeBuffer(len); } /** Only clears the read buffer! */ public void clear() throws TTransportException { readBuffer = new AutoExpandingBufferReadTransport(getConfiguration(), initialBufferCapacity); } @Override public void flush() throws TTransportException { int payloadLength = writeBuffer.getLength() - 4; byte[] data = writeBuffer.getBuf().array(); TFramedTransport.encodeFrameSize(payloadLength, data); getInnerTransport().write(data, 0, payloadLength + 4); writeBuffer.reset(); getInnerTransport().flush(); } @Override public byte[] getBuffer() { return readBuffer.getBuffer(); } @Override public int getBufferPosition() { return readBuffer.getBufferPosition(); } @Override public int getBytesRemainingInBuffer() { return readBuffer.getBytesRemainingInBuffer(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/layered/TFramedTransport.java0000664000175000017500000001320315165535636032612 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.layered; import java.util.Objects; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TConfiguration; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.TTransportFactory; /** * TFramedTransport is a buffered TTransport that ensures a fully read message every time by * preceding messages with a 4-byte frame size. */ public class TFramedTransport extends TLayeredTransport { /** Buffer for output */ private final TByteArrayOutputStream writeBuffer_ = new TByteArrayOutputStream(1024); /** Buffer for input */ private final TMemoryInputTransport readBuffer_; public static class Factory extends TTransportFactory { private final int maxLength_; public Factory() { maxLength_ = TConfiguration.DEFAULT_MAX_FRAME_SIZE; } public Factory(int maxLength) { maxLength_ = maxLength; } @Override public TTransport getTransport(TTransport base) throws TTransportException { return new TFramedTransport(base, maxLength_); } } /** * Something to fill in the first four bytes of the buffer to make room for the frame size. This * allows the implementation to write once instead of twice. */ private static final byte[] sizeFiller_ = new byte[] {0x00, 0x00, 0x00, 0x00}; /** Constructor wraps around another transport */ public TFramedTransport(TTransport transport, int maxLength) throws TTransportException { super(transport); TConfiguration _configuration = Objects.isNull(transport.getConfiguration()) ? new TConfiguration() : transport.getConfiguration(); _configuration.setMaxFrameSize(maxLength); writeBuffer_.write(sizeFiller_, 0, 4); readBuffer_ = new TMemoryInputTransport(_configuration, new byte[0]); } public TFramedTransport(TTransport transport) throws TTransportException { this(transport, TConfiguration.DEFAULT_MAX_FRAME_SIZE); } public void open() throws TTransportException { getInnerTransport().open(); } public boolean isOpen() { return getInnerTransport().isOpen(); } public void close() { getInnerTransport().close(); } public int read(byte[] buf, int off, int len) throws TTransportException { int got = readBuffer_.read(buf, off, len); if (got > 0) { return got; } // Read another frame of data readFrame(); return readBuffer_.read(buf, off, len); } @Override public byte[] getBuffer() { return readBuffer_.getBuffer(); } @Override public int getBufferPosition() { return readBuffer_.getBufferPosition(); } @Override public int getBytesRemainingInBuffer() { return readBuffer_.getBytesRemainingInBuffer(); } @Override public void consumeBuffer(int len) { readBuffer_.consumeBuffer(len); } public void clear() { readBuffer_.clear(); } private final byte[] i32buf = new byte[4]; private void readFrame() throws TTransportException { getInnerTransport().readAll(i32buf, 0, 4); int size = decodeFrameSize(i32buf); if (size < 0) { close(); throw new TTransportException( TTransportException.CORRUPTED_DATA, "Read a negative frame size (" + size + ")!"); } if (size > getInnerTransport().getConfiguration().getMaxFrameSize()) { close(); throw new TTransportException( TTransportException.CORRUPTED_DATA, "Frame size (" + size + ") larger than max length (" + getInnerTransport().getConfiguration().getMaxFrameSize() + ")!"); } byte[] buff = new byte[size]; getInnerTransport().readAll(buff, 0, size); readBuffer_.reset(buff); } public void write(byte[] buf, int off, int len) throws TTransportException { writeBuffer_.write(buf, off, len); } @Override public void flush() throws TTransportException { byte[] buf = writeBuffer_.get(); int len = writeBuffer_.len() - 4; // account for the prepended frame size writeBuffer_.reset(); writeBuffer_.write(sizeFiller_, 0, 4); // make room for the next frame's size data encodeFrameSize(len, buf); // this is the frame length without the filler getInnerTransport().write(buf, 0, len + 4); // we have to write the frame size and frame data getInnerTransport().flush(); } public static void encodeFrameSize(final int frameSize, final byte[] buf) { buf[0] = (byte) (0xff & (frameSize >> 24)); buf[1] = (byte) (0xff & (frameSize >> 16)); buf[2] = (byte) (0xff & (frameSize >> 8)); buf[3] = (byte) (0xff & (frameSize)); } public static int decodeFrameSize(final byte[] buf) { return ((buf[0] & 0xff) << 24) | ((buf[1] & 0xff) << 16) | ((buf[2] & 0xff) << 8) | ((buf[3] & 0xff)); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/layered/TLayeredTransport.java0000664000175000017500000000334315165535636033005 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.layered; import java.util.Objects; import org.apache.thrift.TConfiguration; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; public abstract class TLayeredTransport extends TTransport { private final TTransport innerTransport; @Override public TConfiguration getConfiguration() { return innerTransport.getConfiguration(); } public TLayeredTransport(TTransport transport) { Objects.requireNonNull(transport, "TTransport cannot be null."); innerTransport = transport; } @Override public void updateKnownMessageSize(long size) throws TTransportException { innerTransport.updateKnownMessageSize(size); } @Override public void checkReadBytesAvailable(long numBytes) throws TTransportException { innerTransport.checkReadBytesAvailable(numBytes); } public TTransport getInnerTransport() { return innerTransport; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/AutoExpandingBuffer.java0000664000175000017500000000343415165535636031633 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.util.Arrays; /** * Helper class that wraps a byte[] so that it can expand and be reused. Users should call * resizeIfNecessary to make sure the buffer has suitable capacity, and then use the array as * needed. Note that the internal array will grow at a rate slightly faster than the requested * capacity with the (untested) objective of avoiding expensive buffer allocations and copies. */ public class AutoExpandingBuffer { private byte[] array; public AutoExpandingBuffer(int initialCapacity) { this.array = new byte[initialCapacity]; } public void resizeIfNecessary(int size) { final int currentCapacity = this.array.length; if (currentCapacity < size) { // Increase by a factor of 1.5x int growCapacity = currentCapacity + (currentCapacity >> 1); int newCapacity = Math.max(growCapacity, size); this.array = Arrays.copyOf(array, newCapacity); } } public byte[] array() { return this.array; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TZlibTransport.java0000664000175000017500000001017715165535636030676 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Objects; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import org.apache.thrift.TConfiguration; /** TZlibTransport deflates on write and inflates on read. */ public class TZlibTransport extends TIOStreamTransport { private TTransport transport_ = null; public static class Factory extends TTransportFactory { public Factory() {} @Override public TTransport getTransport(TTransport base) throws TTransportException { return new TZlibTransport(base); } } /** * Constructs a new TZlibTransport instance. * * @param transport the underlying transport to read from and write to */ public TZlibTransport(TTransport transport) throws TTransportException { this(transport, Deflater.BEST_COMPRESSION); } /** * Constructs a new TZlibTransport instance. * * @param transport the underlying transport to read from and write to * @param compressionLevel 0 for no compression, 9 for maximum compression */ public TZlibTransport(TTransport transport, int compressionLevel) throws TTransportException { super( Objects.isNull(transport.getConfiguration()) ? new TConfiguration() : transport.getConfiguration()); transport_ = transport; inputStream_ = new InflaterInputStream(new TTransportInputStream(transport_), new Inflater()); outputStream_ = new DeflaterOutputStream( new TTransportOutputStream(transport_), new Deflater(compressionLevel, false), true); } @Override public boolean isOpen() { return transport_.isOpen(); } @Override public void open() throws TTransportException { transport_.open(); } @Override public void close() { super.close(); if (transport_.isOpen()) { transport_.close(); } } } class TTransportInputStream extends InputStream { private TTransport transport = null; public TTransportInputStream(TTransport transport) { this.transport = transport; } @Override public int read() throws IOException { try { byte[] buf = new byte[1]; transport.read(buf, 0, 1); return buf[0]; } catch (TTransportException e) { throw new IOException(e); } } @Override public int read(byte b[], int off, int len) throws IOException { try { return transport.read(b, off, len); } catch (TTransportException e) { throw new IOException(e); } } } class TTransportOutputStream extends OutputStream { private TTransport transport = null; public TTransportOutputStream(TTransport transport) { this.transport = transport; } @Override public void write(final int b) throws IOException { try { transport.write(new byte[] {(byte) b}); } catch (TTransportException e) { throw new IOException(e); } } @Override public void write(byte b[], int off, int len) throws IOException { try { transport.write(b, off, len); } catch (TTransportException e) { throw new IOException(e); } } @Override public void flush() throws IOException { try { transport.flush(); } catch (TTransportException e) { throw new IOException(e); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TByteBuffer.java0000664000175000017500000000537615165535636030123 0ustar00buildbuild00000000000000package org.apache.thrift.transport; import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import org.apache.thrift.TConfiguration; /** ByteBuffer-backed implementation of TTransport. */ public final class TByteBuffer extends TEndpointTransport { private final ByteBuffer byteBuffer; /** * Creates a new TByteBuffer wrapping a given NIO ByteBuffer and custom TConfiguration. * * @param configuration the custom TConfiguration. * @param byteBuffer the NIO ByteBuffer to wrap. * @throws TTransportException on error. */ public TByteBuffer(TConfiguration configuration, ByteBuffer byteBuffer) throws TTransportException { super(configuration); this.byteBuffer = byteBuffer; updateKnownMessageSize(byteBuffer.capacity()); } /** * Creates a new TByteBuffer wrapping a given NIO ByteBuffer. * * @param byteBuffer the NIO ByteBuffer to wrap. * @throws TTransportException on error. */ public TByteBuffer(ByteBuffer byteBuffer) throws TTransportException { this(new TConfiguration(), byteBuffer); } @Override public boolean isOpen() { return true; } @Override public void open() {} @Override public void close() {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { // checkReadBytesAvailable(len); final int n = Math.min(byteBuffer.remaining(), len); if (n > 0) { try { byteBuffer.get(buf, off, n); } catch (BufferUnderflowException e) { throw new TTransportException("Unexpected end of input buffer", e); } } return n; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { try { byteBuffer.put(buf, off, len); } catch (BufferOverflowException e) { throw new TTransportException("Not enough room in output buffer", e); } } /** * Gets the underlying NIO ByteBuffer. * * @return the underlying NIO ByteBuffer. */ public ByteBuffer getByteBuffer() { return byteBuffer; } /** * Convenience method to call clear() on the underlying NIO ByteBuffer. * * @return this instance. */ public TByteBuffer clear() { byteBuffer.clear(); return this; } /** * Convenience method to call flip() on the underlying NIO ByteBuffer. * * @return this instance. */ public TByteBuffer flip() { byteBuffer.flip(); return this; } /** * Convenience method to convert the underlying NIO ByteBuffer to a plain old byte array. * * @return the byte array backing the underlying NIO ByteBuffer. */ public byte[] toByteArray() { final byte[] data = new byte[byteBuffer.remaining()]; byteBuffer.slice().get(data); return data; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TEOFException.java0000664000175000017500000000205215165535636030342 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** End of file, especially, the underlying socket is closed. */ public class TEOFException extends TTransportException { public TEOFException(String message) { super(TTransportException.END_OF_FILE, message); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TSocket.java0000664000175000017500000001662615165535636027316 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import org.apache.thrift.TConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Socket implementation of the TTransport interface. To be commented soon! */ public class TSocket extends TIOStreamTransport implements SocketAddressProvider { private static final Logger LOGGER = LoggerFactory.getLogger(TSocket.class.getName()); /** Wrapped Socket object */ private Socket socket_; /** Remote host */ private String host_; /** Remote port */ private int port_; /** Socket timeout - read timeout on the socket */ private int socketTimeout_; /** Connection timeout */ private int connectTimeout_; /** * Constructor that takes an already created socket. * * @param socket Already created socket object * @throws TTransportException if there is an error setting up the streams */ public TSocket(Socket socket) throws TTransportException { super(new TConfiguration()); socket_ = socket; try { socket_.setSoLinger(false, 0); socket_.setTcpNoDelay(true); socket_.setKeepAlive(true); } catch (SocketException sx) { LOGGER.warn("Could not configure socket.", sx); } if (isOpen()) { try { inputStream_ = new BufferedInputStream(socket_.getInputStream()); outputStream_ = new BufferedOutputStream(socket_.getOutputStream()); } catch (IOException iox) { close(); throw new TTransportException(TTransportException.NOT_OPEN, iox); } } } /** * Creates a new unconnected socket that will connect to the given host on the given port. * * @param config check config * @param host Remote host * @param port Remote port */ public TSocket(TConfiguration config, String host, int port) throws TTransportException { this(config, host, port, 0); } /** * Creates a new unconnected socket that will connect to the given host on the given port. * * @param host Remote host * @param port Remote port */ public TSocket(String host, int port) throws TTransportException { this(new TConfiguration(), host, port, 0); } /** * Creates a new unconnected socket that will connect to the given host on the given port. * * @param host Remote host * @param port Remote port * @param timeout Socket timeout and connection timeout */ public TSocket(String host, int port, int timeout) throws TTransportException { this(new TConfiguration(), host, port, timeout, timeout); } /** * Creates a new unconnected socket that will connect to the given host on the given port. * * @param config check config * @param host Remote host * @param port Remote port * @param timeout Socket timeout and connection timeout */ public TSocket(TConfiguration config, String host, int port, int timeout) throws TTransportException { this(config, host, port, timeout, timeout); } /** * Creates a new unconnected socket that will connect to the given host on the given port, with a * specific connection timeout and a specific socket timeout. * * @param config check config * @param host Remote host * @param port Remote port * @param socketTimeout Socket timeout * @param connectTimeout Connection timeout */ public TSocket( TConfiguration config, String host, int port, int socketTimeout, int connectTimeout) throws TTransportException { super(config); host_ = host; port_ = port; socketTimeout_ = socketTimeout; connectTimeout_ = connectTimeout; initSocket(); } /** Initializes the socket object */ private void initSocket() { socket_ = new Socket(); try { socket_.setSoLinger(false, 0); socket_.setTcpNoDelay(true); socket_.setKeepAlive(true); socket_.setSoTimeout(socketTimeout_); } catch (SocketException sx) { LOGGER.error("Could not configure socket.", sx); } } /** * Sets the socket timeout and connection timeout. * * @param timeout Milliseconds timeout */ public void setTimeout(int timeout) { this.setConnectTimeout(timeout); this.setSocketTimeout(timeout); } /** * Sets the time after which the connection attempt will time out * * @param timeout Milliseconds timeout */ public void setConnectTimeout(int timeout) { connectTimeout_ = timeout; } /** * Sets the socket timeout * * @param timeout Milliseconds timeout */ public void setSocketTimeout(int timeout) { socketTimeout_ = timeout; try { socket_.setSoTimeout(timeout); } catch (SocketException sx) { LOGGER.warn("Could not set socket timeout.", sx); } } /** Returns a reference to the underlying socket. */ public Socket getSocket() { if (socket_ == null) { initSocket(); } return socket_; } /** Checks whether the socket is connected. */ public boolean isOpen() { if (socket_ == null) { return false; } return socket_.isConnected(); } /** Connects the socket, creating a new socket object if necessary. */ public void open() throws TTransportException { if (isOpen()) { throw new TTransportException(TTransportException.ALREADY_OPEN, "Socket already connected."); } if (host_ == null || host_.length() == 0) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot open null host."); } if (port_ <= 0 || port_ > 65535) { throw new TTransportException(TTransportException.NOT_OPEN, "Invalid port " + port_); } if (socket_ == null) { initSocket(); } try { socket_.connect(new InetSocketAddress(host_, port_), connectTimeout_); inputStream_ = new BufferedInputStream(socket_.getInputStream()); outputStream_ = new BufferedOutputStream(socket_.getOutputStream()); } catch (IOException iox) { close(); throw new TTransportException(TTransportException.NOT_OPEN, iox); } } /** Closes the socket. */ public void close() { // Close the underlying streams super.close(); // Close the socket if (socket_ != null) { try { socket_.close(); } catch (IOException iox) { LOGGER.warn("Could not close socket.", iox); } socket_ = null; } } @Override public SocketAddress getRemoteSocketAddress() { return socket_.getRemoteSocketAddress(); } @Override public SocketAddress getLocalSocketAddress() { return socket_.getLocalSocketAddress(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TNonblockingSSLSocket.java0000664000175000017500000001754415170007142032042 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLException; import javax.net.ssl.SSLParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Transport for use with async ssl client. */ public class TNonblockingSSLSocket extends TNonblockingSocket implements SocketAddressProvider { private static final Logger LOGGER = LoggerFactory.getLogger(TNonblockingSSLSocket.class.getName()); private final SSLEngine sslEngine_; private final ByteBuffer appUnwrap; private final ByteBuffer netUnwrap; private final ByteBuffer netWrap; private boolean isHandshakeCompleted; private SelectionKey selectionKey; private final ExecutorService executorService = Executors.newSingleThreadExecutor(); protected TNonblockingSSLSocket(String host, int port, int timeout, SSLContext sslContext) throws IOException, TTransportException { super(host, port, timeout); sslEngine_ = sslContext.createSSLEngine(host, port); sslEngine_.setUseClientMode(true); SSLParameters sslParams = sslEngine_.getSSLParameters(); sslParams.setEndpointIdentificationAlgorithm("HTTPS"); sslEngine_.setSSLParameters(sslParams); int appBufferSize = sslEngine_.getSession().getApplicationBufferSize(); int netBufferSize = sslEngine_.getSession().getPacketBufferSize(); appUnwrap = ByteBuffer.allocate(appBufferSize); netUnwrap = ByteBuffer.allocate(netBufferSize); netWrap = ByteBuffer.allocate(netBufferSize); isHandshakeCompleted = false; } /** {@inheritDoc} */ @Override public SelectionKey registerSelector(Selector selector, int interests) throws IOException { selectionKey = super.registerSelector(selector, interests); return selectionKey; } /** {@inheritDoc} */ @Override public boolean isOpen() { // isConnected() does not return false after close(), but isOpen() does return super.isOpen() && isHandshakeCompleted; } /** {@inheritDoc} */ @Override public void open() throws TTransportException { throw new RuntimeException("open() is not implemented for TNonblockingSSLSocket"); } /** {@inheritDoc} */ @Override public synchronized int read(ByteBuffer buffer) throws TTransportException { int numBytes = buffer.remaining(); while (appUnwrap.limit() == appUnwrap.capacity() || appUnwrap.remaining() < buffer.remaining()) { if (appUnwrap.limit() < appUnwrap.capacity() && appUnwrap.hasRemaining()) { buffer.put(appUnwrap); } try { if (doUnwrap() == -1) { throw new IOException("Unable to read " + numBytes + " bytes"); } } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } if (buffer.hasRemaining()) { int originLimit = appUnwrap.limit(); appUnwrap.limit(appUnwrap.position() + buffer.remaining()); buffer.put(appUnwrap); appUnwrap.limit(originLimit); } // In SSL mode, the Thrift server may merge the frame size and body into a single TLS package. // Setting OP_WRITE to trigger subsequent read operations in the Thrift async client. selectionKey.interestOps(SelectionKey.OP_WRITE); return numBytes; } /** {@inheritDoc} */ @Override public synchronized int write(ByteBuffer buffer) throws TTransportException { int numBytes = buffer.remaining(); while (buffer.hasRemaining()) { try { if (doWrap(buffer) == -1) { throw new IOException("Unable to write " + numBytes + " bytes"); } } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } return numBytes; } /** {@inheritDoc} */ @Override public void close() { executorService.shutdown(); sslEngine_.closeOutbound(); super.close(); } /** {@inheritDoc} */ @Override public boolean startConnect() throws IOException { if (this.isOpen()) { return true; } sslEngine_.beginHandshake(); return super.startConnect() && doHandShake(); } /** {@inheritDoc} */ @Override public boolean finishConnect() throws IOException { return super.finishConnect() && doHandShake(); } private synchronized boolean doHandShake() throws IOException { while (true) { HandshakeStatus hs = sslEngine_.getHandshakeStatus(); switch (hs) { case NEED_UNWRAP: if (doUnwrap() == -1) { LOGGER.error("Unexpected. Handshake failed abruptly during unwrap"); return false; } break; case NEED_WRAP: if (doWrap(ByteBuffer.wrap(new byte[0])) == -1) { LOGGER.error("Unexpected. Handshake failed abruptly during wrap"); return false; } break; case NEED_TASK: doTask(); break; case FINISHED: case NOT_HANDSHAKING: isHandshakeCompleted = true; return true; default: LOGGER.error("Unknown handshake status. Handshake failed"); return false; } } } private void doTask() { Runnable runnable; while ((runnable = sslEngine_.getDelegatedTask()) != null) { executorService.submit(runnable); } } private int doUnwrap() throws IOException { int num = getSocketChannel().read(netUnwrap); netUnwrap.flip(); if (num < 0) { LOGGER.error("Failed during read operation. Probably server is down"); return -1; } SSLEngineResult unwrapResult; try { appUnwrap.clear(); unwrapResult = sslEngine_.unwrap(netUnwrap, appUnwrap); netUnwrap.compact(); } catch (SSLException ex) { LOGGER.error(ex.getMessage()); throw ex; } switch (unwrapResult.getStatus()) { case OK: if (appUnwrap.position() > 0) { appUnwrap.flip(); } break; case CLOSED: return -1; case BUFFER_OVERFLOW: throw new IllegalStateException("Failed to unwrap"); case BUFFER_UNDERFLOW: break; } return num; } private int doWrap(ByteBuffer appWrap) throws IOException { int num = 0; SSLEngineResult wrapResult; try { wrapResult = sslEngine_.wrap(appWrap, netWrap); } catch (SSLException exc) { LOGGER.error(exc.getMessage()); throw exc; } switch (wrapResult.getStatus()) { case OK: if (netWrap.position() > 0) { netWrap.flip(); num = getSocketChannel().write(netWrap); netWrap.clear(); } break; case BUFFER_UNDERFLOW: // try again later break; case BUFFER_OVERFLOW: throw new IllegalStateException("Failed to wrap"); case CLOSED: LOGGER.error("SSL session is closed"); return -1; } return num; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TSSLTransportFactory.java0000664000175000017500000004270515170007142031747 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyStore; import java.util.Arrays; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Factory for providing and setting up Client and Server SSL wrapped TSocket and TServerSocket */ public class TSSLTransportFactory { private static final Logger LOGGER = LoggerFactory.getLogger(TSSLTransportFactory.class); /** * Get a SSL wrapped TServerSocket bound to the specified port. In this configuration the default * settings are used. Default settings are retrieved from System properties that are set. * *

Example system properties: -Djavax.net.ssl.trustStore=<truststore location> * -Djavax.net.ssl.trustStorePassword=password -Djavax.net.ssl.keyStore=<keystore location> * -Djavax.net.ssl.keyStorePassword=password * * @param port server port * @return A SSL wrapped TServerSocket * @throws TTransportException when failed to create server socket */ public static TServerSocket getServerSocket(int port) throws TTransportException { return getServerSocket(port, 0); } /** * Get a default SSL wrapped TServerSocket bound to the specified port * * @param port * @param clientTimeout * @return A SSL wrapped TServerSocket * @throws TTransportException */ public static TServerSocket getServerSocket(int port, int clientTimeout) throws TTransportException { return getServerSocket(port, clientTimeout, false, null); } /** * Get a default SSL wrapped TServerSocket bound to the specified port and interface * * @param port * @param clientTimeout * @param ifAddress * @return A SSL wrapped TServerSocket * @throws TTransportException */ public static TServerSocket getServerSocket( int port, int clientTimeout, boolean clientAuth, InetAddress ifAddress) throws TTransportException { SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); return createServer(factory, port, clientTimeout, clientAuth, ifAddress, null); } /** * Get a configured SSL wrapped TServerSocket bound to the specified port and interface. Here the * TSSLTransportParameters are used to set the values for the algorithms, keystore, truststore and * other settings * * @param port * @param clientTimeout * @param ifAddress * @param params * @return A SSL wrapped TServerSocket * @throws TTransportException */ public static TServerSocket getServerSocket( int port, int clientTimeout, InetAddress ifAddress, TSSLTransportParameters params) throws TTransportException { if (params == null || !(params.isKeyStoreSet || params.isTrustStoreSet)) { throw new TTransportException( "Either one of the KeyStore or TrustStore must be set for SSLTransportParameters"); } SSLContext ctx = createSSLContext(params); return createServer( ctx.getServerSocketFactory(), port, clientTimeout, params.clientAuth, ifAddress, params); } private static TServerSocket createServer( SSLServerSocketFactory factory, int port, int timeout, boolean clientAuth, InetAddress ifAddress, TSSLTransportParameters params) throws TTransportException { try { SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(port, 100, ifAddress); serverSocket.setSoTimeout(timeout); serverSocket.setNeedClientAuth(clientAuth); if (params != null && params.cipherSuites != null) { serverSocket.setEnabledCipherSuites(params.cipherSuites); } return new TServerSocket( new TServerSocket.ServerSocketTransportArgs() .serverSocket(serverSocket) .clientTimeout(timeout)); } catch (Exception e) { throw new TTransportException("Could not bind to port " + port, e); } } /** * Get a default SSL wrapped TSocket connected to the specified host and port. All the client * methods return a bound connection. So there is no need to call open() on the TTransport. * * @param host * @param port * @param timeout * @return A SSL wrapped TSocket * @throws TTransportException */ public static TSocket getClientSocket(String host, int port, int timeout) throws TTransportException { SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); return createClient(factory, host, port, timeout); } /** * Get a default SSL wrapped TSocket connected to the specified host and port. * * @param host * @param port * @return A SSL wrapped TSocket * @throws TTransportException */ public static TSocket getClientSocket(String host, int port) throws TTransportException { return getClientSocket(host, port, 0); } /** * Get a custom configured SSL wrapped TSocket. The SSL settings are obtained from the passed in * TSSLTransportParameters. * * @param host * @param port * @param timeout * @param params * @return A SSL wrapped TSocket * @throws TTransportException */ public static TSocket getClientSocket( String host, int port, int timeout, TSSLTransportParameters params) throws TTransportException { if (params == null || !(params.isKeyStoreSet || params.isTrustStoreSet)) { throw new TTransportException( TTransportException.NOT_OPEN, "Either one of the KeyStore or TrustStore must be set for SSLTransportParameters"); } SSLContext ctx = createSSLContext(params); return createClient(ctx.getSocketFactory(), host, port, timeout); } /** * Get a default SSL wrapped TNonblockingTransport connected to the specified host and port. * * @param host * @param port * @return A SSL wrapped TNonblockingSocket * @throws TTransportException */ public static TNonblockingSocket getNonblockingClientSocket(String host, int port) throws TTransportException, IOException { return getNonblockingClientSocket(host, port, 0); } /** * Get a default SSL wrapped TNonblockingTransport connected to the specified host and port. * * @param host * @param port * @param timeout * @return A SSL wrapped TNonblockingSocket * @throws TTransportException */ public static TNonblockingSocket getNonblockingClientSocket(String host, int port, int timeout) throws TTransportException, IOException { SSLContext ctx; try { ctx = SSLContext.getDefault(); } catch (Exception e) { throw new TTransportException( TTransportException.NOT_OPEN, "Error creating the transport", e); } return new TNonblockingSSLSocket(host, port, timeout, ctx); } /** * Get a custom configured TNonblockingTransport. The SSL settings are obtained from the passed in * TSSLTransportParameters. * * @param host * @param port * @param timeout * @param params * @return A SSL wrapped TNonblockingSocket * @throws TTransportException */ public static TNonblockingSocket getNonblockingClientSocket( String host, int port, int timeout, TSSLTransportParameters params) throws TTransportException, IOException { if (params == null || !(params.isKeyStoreSet || params.isTrustStoreSet)) { throw new TTransportException( "Either one of the KeyStore or TrustStore must be set for SSLTransportParameters"); } SSLContext ctx = createSSLContext(params); return new TNonblockingSSLSocket(host, port, timeout, ctx); } private static SSLContext createSSLContext(TSSLTransportParameters params) throws TTransportException { SSLContext ctx; InputStream in = null; InputStream is = null; try { ctx = SSLContext.getInstance(params.protocol); TrustManagerFactory tmf = null; KeyManagerFactory kmf = null; if (params.isTrustStoreSet) { tmf = TrustManagerFactory.getInstance(params.trustManagerType); KeyStore ts = KeyStore.getInstance(params.trustStoreType); if (params.trustStoreStream != null) { in = params.trustStoreStream; } else { in = getStoreAsStream(params.trustStore); } ts.load(in, (params.trustPass != null ? params.trustPass.toCharArray() : null)); tmf.init(ts); } if (params.isKeyStoreSet) { kmf = KeyManagerFactory.getInstance(params.keyManagerType); KeyStore ks = KeyStore.getInstance(params.keyStoreType); if (params.keyStoreStream != null) { is = params.keyStoreStream; } else { is = getStoreAsStream(params.keyStore); } ks.load(is, params.keyPass.toCharArray()); kmf.init(ks, params.keyPass.toCharArray()); } if (params.isKeyStoreSet && params.isTrustStoreSet) { ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); } else if (params.isKeyStoreSet) { ctx.init(kmf.getKeyManagers(), null, null); } else { ctx.init(null, tmf.getTrustManagers(), null); } } catch (Exception e) { throw new TTransportException( TTransportException.NOT_OPEN, "Error creating the transport", e); } finally { if (in != null) { try { in.close(); } catch (IOException e) { LOGGER.warn("Unable to close stream", e); } } if (is != null) { try { is.close(); } catch (IOException e) { LOGGER.warn("Unable to close stream", e); } } } return ctx; } private static InputStream getStoreAsStream(String store) throws IOException { try { return new FileInputStream(store); } catch (FileNotFoundException e) { } InputStream storeStream; try { storeStream = new URL(store).openStream(); if (storeStream != null) { return storeStream; } } catch (MalformedURLException e) { } storeStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(store); if (storeStream != null) { return storeStream; } else { throw new IOException("Could not load file: " + store); } } private static TSocket createClient(SSLSocketFactory factory, String host, int port, int timeout) throws TTransportException { try { SSLSocket socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(timeout); SSLParameters sslParams = socket.getSSLParameters(); sslParams.setEndpointIdentificationAlgorithm("HTTPS"); socket.setSSLParameters(sslParams); return new TSocket(socket); } catch (TTransportException tte) { throw tte; } catch (Exception e) { throw new TTransportException( TTransportException.NOT_OPEN, "Could not connect to " + host + " on port " + port, e); } } /** A Class to hold all the SSL parameters */ public static class TSSLTransportParameters { protected String protocol = "TLS"; protected String keyStore; protected InputStream keyStoreStream; protected String keyPass; protected String keyManagerType = KeyManagerFactory.getDefaultAlgorithm(); protected String keyStoreType = "JKS"; protected String trustStore; protected InputStream trustStoreStream; protected String trustPass; protected String trustManagerType = TrustManagerFactory.getDefaultAlgorithm(); protected String trustStoreType = "JKS"; protected String[] cipherSuites; protected boolean clientAuth = false; protected boolean isKeyStoreSet = false; protected boolean isTrustStoreSet = false; public TSSLTransportParameters() {} /** * Create parameters specifying the protocol and cipher suites * * @param protocol The specific protocol (TLS/SSL) can be specified with versions * @param cipherSuites */ public TSSLTransportParameters(String protocol, String[] cipherSuites) { this(protocol, cipherSuites, false); } /** * Create parameters specifying the protocol, cipher suites and if client authentication is * required * * @param protocol The specific protocol (TLS/SSL) can be specified with versions * @param cipherSuites * @param clientAuth */ public TSSLTransportParameters(String protocol, String[] cipherSuites, boolean clientAuth) { if (protocol != null) { this.protocol = protocol; } this.cipherSuites = cipherSuites != null ? Arrays.copyOf(cipherSuites, cipherSuites.length) : null; this.clientAuth = clientAuth; } /** * Set the keystore, password, certificate type and the store type * * @param keyStore Location of the Keystore on disk * @param keyPass Keystore password * @param keyManagerType The default is X509 * @param keyStoreType The default is JKS */ public void setKeyStore( String keyStore, String keyPass, String keyManagerType, String keyStoreType) { this.keyStore = keyStore; this.keyPass = keyPass; if (keyManagerType != null) { this.keyManagerType = keyManagerType; } if (keyStoreType != null) { this.keyStoreType = keyStoreType; } isKeyStoreSet = true; } /** * Set the keystore, password, certificate type and the store type * * @param keyStoreStream Keystore content input stream * @param keyPass Keystore password * @param keyManagerType The default is X509 * @param keyStoreType The default is JKS */ public void setKeyStore( InputStream keyStoreStream, String keyPass, String keyManagerType, String keyStoreType) { this.keyStoreStream = keyStoreStream; setKeyStore("", keyPass, keyManagerType, keyStoreType); } /** * Set the keystore and password * * @param keyStore Location of the Keystore on disk * @param keyPass Keystore password */ public void setKeyStore(String keyStore, String keyPass) { setKeyStore(keyStore, keyPass, null, null); } /** * Set the keystore and password * * @param keyStoreStream Keystore content input stream * @param keyPass Keystore password */ public void setKeyStore(InputStream keyStoreStream, String keyPass) { setKeyStore(keyStoreStream, keyPass, null, null); } /** * Set the truststore, password, certificate type and the store type * * @param trustStore Location of the Truststore on disk * @param trustPass Truststore password * @param trustManagerType The default is X509 * @param trustStoreType The default is JKS */ public void setTrustStore( String trustStore, String trustPass, String trustManagerType, String trustStoreType) { this.trustStore = trustStore; this.trustPass = trustPass; if (trustManagerType != null) { this.trustManagerType = trustManagerType; } if (trustStoreType != null) { this.trustStoreType = trustStoreType; } isTrustStoreSet = true; } /** * Set the truststore, password, certificate type and the store type * * @param trustStoreStream Truststore content input stream * @param trustPass Truststore password * @param trustManagerType The default is X509 * @param trustStoreType The default is JKS */ public void setTrustStore( InputStream trustStoreStream, String trustPass, String trustManagerType, String trustStoreType) { this.trustStoreStream = trustStoreStream; setTrustStore("", trustPass, trustManagerType, trustStoreType); } /** * Set the truststore and password * * @param trustStore Location of the Truststore on disk * @param trustPass Truststore password */ public void setTrustStore(String trustStore, String trustPass) { setTrustStore(trustStore, trustPass, null, null); } /** * Set the truststore and password * * @param trustStoreStream Truststore content input stream * @param trustPass Truststore password */ public void setTrustStore(InputStream trustStoreStream, String trustPass) { setTrustStore(trustStoreStream, trustPass, null, null); } /** * Set if client authentication is required * * @param clientAuth */ public void requireClientAuth(boolean clientAuth) { this.clientAuth = clientAuth; } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TNonblockingSocket.java0000664000175000017500000001563115167543515031472 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import org.apache.thrift.TConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Transport for use with async client. */ public class TNonblockingSocket extends TNonblockingTransport implements SocketAddressProvider { private static final Logger LOGGER = LoggerFactory.getLogger(TNonblockingSocket.class.getName()); /** Host and port if passed in, used for lazy non-blocking connect. */ private final SocketAddress socketAddress_; private final SocketChannel socketChannel_; public TNonblockingSocket(String host, int port) throws IOException, TTransportException { this(host, port, 0); } /** * Create a new nonblocking socket transport that will be connected to host:port. * * @param host * @param port * @throws IOException */ public TNonblockingSocket(String host, int port, int timeout) throws IOException, TTransportException { this(SocketChannel.open(), timeout, new InetSocketAddress(host, port)); } /** * Constructor that takes an already created socket. * * @param socketChannel Already created SocketChannel object * @throws IOException if there is an error setting up the streams */ public TNonblockingSocket(SocketChannel socketChannel) throws IOException, TTransportException { this(socketChannel, 0, null); if (!socketChannel.isConnected()) throw new IOException("Socket must already be connected"); } private TNonblockingSocket(SocketChannel socketChannel, int timeout, SocketAddress socketAddress) throws IOException, TTransportException { this(new TConfiguration(), socketChannel, timeout, socketAddress); } private TNonblockingSocket( TConfiguration config, SocketChannel socketChannel, int timeout, SocketAddress socketAddress) throws IOException, TTransportException { super(config); socketChannel_ = socketChannel; socketAddress_ = socketAddress; // make it a nonblocking channel socketChannel.configureBlocking(false); // set options Socket socket = socketChannel.socket(); socket.setSoLinger(false, 0); socket.setTcpNoDelay(true); socket.setKeepAlive(true); setTimeout(timeout); } /** * Register the new SocketChannel with our Selector, indicating we'd like to be notified when it's * ready for I/O. * * @param selector * @return the selection key for this socket. */ public SelectionKey registerSelector(Selector selector, int interests) throws IOException { return socketChannel_.register(selector, interests); } /** * Sets the socket timeout, although this implementation never uses blocking operations so it is * unused. * * @param timeout Milliseconds timeout */ public void setTimeout(int timeout) { try { socketChannel_.socket().setSoTimeout(timeout); } catch (SocketException sx) { LOGGER.warn("Could not set socket timeout.", sx); } } /** Returns a reference to the underlying SocketChannel. */ public SocketChannel getSocketChannel() { return socketChannel_; } /** Checks whether the socket is connected. */ public boolean isOpen() { // isConnected() does not return false after close(), but isOpen() does return socketChannel_.isOpen() && socketChannel_.isConnected(); } /** Do not call, the implementation provides its own lazy non-blocking connect. */ public void open() throws TTransportException { throw new RuntimeException("open() is not implemented for TNonblockingSocket"); } /** Perform a nonblocking read into buffer. */ public int read(ByteBuffer buffer) throws TTransportException { try { return socketChannel_.read(buffer); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** Reads from the underlying input stream if not null. */ public int read(byte[] buf, int off, int len) throws TTransportException { if ((socketChannel_.validOps() & SelectionKey.OP_READ) != SelectionKey.OP_READ) { throw new TTransportException( TTransportException.NOT_OPEN, "Cannot read from write-only socket channel"); } return read(ByteBuffer.wrap(buf, off, len)); } /** Perform a nonblocking write of the data in buffer; */ public int write(ByteBuffer buffer) throws TTransportException { try { return socketChannel_.write(buffer); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** Writes to the underlying output stream if not null. */ public void write(byte[] buf, int off, int len) throws TTransportException { if ((socketChannel_.validOps() & SelectionKey.OP_WRITE) != SelectionKey.OP_WRITE) { throw new TTransportException( TTransportException.NOT_OPEN, "Cannot write to write-only socket channel"); } write(ByteBuffer.wrap(buf, off, len)); } /** Noop. */ public void flush() throws TTransportException { // Not supported by SocketChannel. } /** Closes the socket. */ public void close() { try { socketChannel_.close(); } catch (IOException iox) { LOGGER.warn("Could not close socket.", iox); } } /** {@inheritDoc} */ public boolean startConnect() throws IOException { return socketChannel_.connect(socketAddress_); } /** {@inheritDoc} */ public boolean finishConnect() throws IOException { return socketChannel_.finishConnect(); } @Override public String toString() { return "[remote: " + socketChannel_.socket().getRemoteSocketAddress() + ", local: " + socketChannel_.socket().getLocalAddress() + "]"; } @Override public SocketAddress getRemoteSocketAddress() { return socketChannel_.socket().getRemoteSocketAddress(); } @Override public SocketAddress getLocalSocketAddress() { return socketChannel_.socket().getLocalSocketAddress(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TNonblockingTransport.java0000664000175000017500000000322415165535636032234 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.net.SocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import org.apache.thrift.TConfiguration; public abstract class TNonblockingTransport extends TEndpointTransport { public TNonblockingTransport(TConfiguration config) throws TTransportException { super(config); } /** * Non-blocking connection initialization. * * @see java.nio.channels.SocketChannel#connect(SocketAddress remote) */ public abstract boolean startConnect() throws IOException; /** * Non-blocking connection completion. * * @see java.nio.channels.SocketChannel#finishConnect() */ public abstract boolean finishConnect() throws IOException; public abstract SelectionKey registerSelector(Selector selector, int interests) throws IOException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TTransportFactory.java0000664000175000017500000000254315165535636031403 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Factory class used to create wrapped instance of Transports. This is used primarily in servers, * which get Transports from a ServerTransport and then may want to mutate them (i.e. create a * BufferedTransport from the underlying base transport) */ public class TTransportFactory { /** * Return a wrapped instance of the base Transport. * * @param trans The base transport * @return Wrapped Transport */ public TTransport getTransport(TTransport trans) throws TTransportException { return trans; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TTransportException.java0000664000175000017500000000405615165535636031733 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TException; /** Transport exceptions. */ public class TTransportException extends TException { private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int NOT_OPEN = 1; public static final int ALREADY_OPEN = 2; 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; public TTransportException() { super(); } public TTransportException(int type) { super(); type_ = type; } public TTransportException(int type, String message) { super(message); type_ = type; } public TTransportException(String message) { super(message); } public TTransportException(int type, Throwable cause) { super(cause); type_ = type; } public TTransportException(Throwable cause) { super(cause); } public TTransportException(String message, Throwable cause) { super(message, cause); } public TTransportException(int type, String message, Throwable cause) { super(message, cause); type_ = type; } public int getType() { return type_; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TServerSocket.java0000664000175000017500000001157615167543515030501 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Wrapper around ServerSocket for Thrift. */ public class TServerSocket extends TServerTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TServerSocket.class.getName()); /** Underlying ServerSocket object */ private ServerSocket serverSocket_ = null; /** Timeout for client sockets from accept */ private int clientTimeout_ = 0; /** Max message size */ private int maxMessageSize_ = 0; public static class ServerSocketTransportArgs extends AbstractServerTransportArgs { ServerSocket serverSocket; public ServerSocketTransportArgs serverSocket(ServerSocket serverSocket) { this.serverSocket = serverSocket; return this; } } /** Creates a server socket from underlying socket object */ public TServerSocket(ServerSocket serverSocket) throws TTransportException { this(serverSocket, 0); } /** Creates a server socket from underlying socket object */ public TServerSocket(ServerSocket serverSocket, int clientTimeout) throws TTransportException { this(new ServerSocketTransportArgs().serverSocket(serverSocket).clientTimeout(clientTimeout)); } /** Creates just a port listening server socket */ public TServerSocket(int port) throws TTransportException { this(port, 0); } /** Creates just a port listening server socket */ public TServerSocket(int port, int clientTimeout) throws TTransportException { this(new InetSocketAddress(port), clientTimeout); } public TServerSocket(InetSocketAddress bindAddr) throws TTransportException { this(bindAddr, 0); } public TServerSocket(InetSocketAddress bindAddr, int clientTimeout) throws TTransportException { this(new ServerSocketTransportArgs().bindAddr(bindAddr).clientTimeout(clientTimeout)); } public TServerSocket(ServerSocketTransportArgs args) throws TTransportException { clientTimeout_ = args.clientTimeout; maxMessageSize_ = args.maxMessageSize; if (args.serverSocket != null) { this.serverSocket_ = args.serverSocket; return; } try { // Make server socket serverSocket_ = new ServerSocket(); // Prevent 2MSL delay problem on server restarts serverSocket_.setReuseAddress(true); // Bind to listening port serverSocket_.bind(args.bindAddr, args.backlog); } catch (IOException ioe) { close(); throw new TTransportException( "Could not create ServerSocket on address " + args.bindAddr.toString() + ".", ioe); } } public void listen() throws TTransportException { // Make sure to block on accept if (serverSocket_ != null) { try { serverSocket_.setSoTimeout(0); } catch (SocketException sx) { LOGGER.error("Could not set socket timeout.", sx); } } } @Override public TSocket accept() throws TTransportException { if (serverSocket_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "No underlying server socket."); } Socket result; try { result = serverSocket_.accept(); } catch (Exception e) { throw new TTransportException(e); } if (result == null) { throw new TTransportException("Blocking server's accept() may not return NULL"); } TSocket socket = new TSocket(result); socket.setTimeout(clientTimeout_); socket.setMaxMessageSize(maxMessageSize_); return socket; } public void close() { if (serverSocket_ != null) { try { serverSocket_.close(); } catch (IOException iox) { LOGGER.warn("Could not close server socket.", iox); } serverSocket_ = null; } } public void interrupt() { // The thread-safeness of this is dubious, but Java documentation suggests // that it is safe to do this from a different thread context close(); } public ServerSocket getServerSocket() { return serverSocket_; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TMemoryInputTransport.java0000664000175000017500000000644115165535636032265 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TConfiguration; public final class TMemoryInputTransport extends TEndpointTransport { private byte[] buf_; private int pos_; private int endPos_; public TMemoryInputTransport() throws TTransportException { this(new TConfiguration()); } public TMemoryInputTransport(TConfiguration _configuration) throws TTransportException { this(_configuration, new byte[0]); } public TMemoryInputTransport(byte[] buf) throws TTransportException { this(new TConfiguration(), buf); } public TMemoryInputTransport(TConfiguration _configuration, byte[] buf) throws TTransportException { this(_configuration, buf, 0, buf.length); } public TMemoryInputTransport(byte[] buf, int offset, int length) throws TTransportException { this(new TConfiguration(), buf, offset, length); } public TMemoryInputTransport(TConfiguration _configuration, byte[] buf, int offset, int length) throws TTransportException { super(_configuration); reset(buf, offset, length); updateKnownMessageSize(length); } public void reset(byte[] buf) { reset(buf, 0, buf.length); } public void reset(byte[] buf, int offset, int length) { buf_ = buf; pos_ = offset; endPos_ = offset + length; try { resetConsumedMessageSize(-1); } catch (TTransportException e) { // ignore } } public void clear() { buf_ = null; try { resetConsumedMessageSize(-1); } catch (TTransportException e) { // ignore } } @Override public void close() {} @Override public boolean isOpen() { return true; } @Override public void open() throws TTransportException {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { int bytesRemaining = getBytesRemainingInBuffer(); int amtToRead = (len > bytesRemaining ? bytesRemaining : len); if (amtToRead > 0) { System.arraycopy(buf_, pos_, buf, off, amtToRead); consumeBuffer(amtToRead); countConsumedMessageBytes(amtToRead); } return amtToRead; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { throw new UnsupportedOperationException("No writing allowed!"); } @Override public byte[] getBuffer() { return buf_; } public int getBufferPosition() { return pos_; } public int getBytesRemainingInBuffer() { return endPos_ - pos_; } public void consumeBuffer(int len) { pos_ += len; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TSaslTransport.java0000664000175000017500000004347315165535636030705 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.charset.StandardCharsets; import java.util.Objects; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.thrift.EncodingUtils; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TConfiguration; import org.apache.thrift.transport.layered.TFramedTransport; import org.apache.thrift.transport.sasl.NegotiationStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A superclass for SASL client/server thrift transports. A subclass need only implement the * open method. */ abstract class TSaslTransport extends TEndpointTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TSaslTransport.class); protected static final int DEFAULT_MAX_LENGTH = 0x7FFFFFFF; protected static final int MECHANISM_NAME_BYTES = 1; protected static final int STATUS_BYTES = 1; protected static final int PAYLOAD_LENGTH_BYTES = 4; protected static enum SaslRole { SERVER, CLIENT; } /** Transport underlying this one. */ protected TTransport underlyingTransport; /** Either a SASL client or a SASL server. */ private SaslParticipant sasl; /** * Whether or not we should wrap/unwrap reads/writes. Determined by whether or not a QOP is * negotiated during the SASL handshake. */ private boolean shouldWrap = false; /** Buffer for input. */ private TMemoryInputTransport readBuffer; /** Buffer for output. */ private final TByteArrayOutputStream writeBuffer = new TByteArrayOutputStream(1024); /** * Create a TSaslTransport. It's assumed that setSaslServer will be called later to initialize the * SASL endpoint underlying this transport. * * @param underlyingTransport The thrift transport which this transport is wrapping. */ protected TSaslTransport(TTransport underlyingTransport) throws TTransportException { super( Objects.isNull(underlyingTransport.getConfiguration()) ? new TConfiguration() : underlyingTransport.getConfiguration()); this.underlyingTransport = underlyingTransport; this.readBuffer = new TMemoryInputTransport(underlyingTransport.getConfiguration()); } /** * Create a TSaslTransport which acts as a client. * * @param saslClient The SaslClient which this transport will use for SASL * negotiation. * @param underlyingTransport The thrift transport which this transport is wrapping. */ protected TSaslTransport(SaslClient saslClient, TTransport underlyingTransport) throws TTransportException { super( Objects.isNull(underlyingTransport.getConfiguration()) ? new TConfiguration() : underlyingTransport.getConfiguration()); sasl = new SaslParticipant(saslClient); this.underlyingTransport = underlyingTransport; this.readBuffer = new TMemoryInputTransport(underlyingTransport.getConfiguration()); } protected void setSaslServer(SaslServer saslServer) { sasl = new SaslParticipant(saslServer); } // Used to read the status byte and payload length. private final byte[] messageHeader = new byte[STATUS_BYTES + PAYLOAD_LENGTH_BYTES]; /** * Send a complete Thrift SASL message. * * @param status The status to send. * @param payload The data to send as the payload of this message. * @throws TTransportException */ protected void sendSaslMessage(NegotiationStatus status, byte[] payload) throws TTransportException { if (payload == null) payload = new byte[0]; messageHeader[0] = status.getValue(); EncodingUtils.encodeBigEndian(payload.length, messageHeader, STATUS_BYTES); LOGGER.debug( "{}: Writing message with status {} and payload length {}", getRole(), status, payload.length); underlyingTransport.write(messageHeader); underlyingTransport.write(payload); underlyingTransport.flush(); } /** * Read a complete Thrift SASL message. * * @return The SASL status and payload from this message. * @throws TTransportException Thrown if there is a failure reading from the underlying transport, * or if a status code of BAD or ERROR is encountered. */ protected SaslResponse receiveSaslMessage() throws TTransportException { underlyingTransport.readAll(messageHeader, 0, messageHeader.length); byte statusByte = messageHeader[0]; NegotiationStatus status = NegotiationStatus.byValue(statusByte); if (status == null) { throw sendAndThrowMessage(NegotiationStatus.ERROR, "Invalid status " + statusByte); } int payloadBytes = EncodingUtils.decodeBigEndian(messageHeader, STATUS_BYTES); if (payloadBytes < 0 || payloadBytes > getConfiguration().getMaxMessageSize() /* 100 MB */) { throw sendAndThrowMessage( NegotiationStatus.ERROR, "Invalid payload header length: " + payloadBytes); } byte[] payload = new byte[payloadBytes]; underlyingTransport.readAll(payload, 0, payload.length); if (status == NegotiationStatus.BAD || status == NegotiationStatus.ERROR) { String remoteMessage = new String(payload, StandardCharsets.UTF_8); throw new TTransportException("Peer indicated failure: " + remoteMessage); } LOGGER.debug( "{}: Received message with status {} and payload length {}", getRole(), status, payload.length); return new SaslResponse(status, payload); } /** * Send a Thrift SASL message with the given status (usually BAD or ERROR) and string message, and * then throw a TTransportException with the given message. * * @param status The Thrift SASL status code to send. Usually BAD or ERROR. * @param message The optional message to send to the other side. * @throws TTransportException Always thrown with the message provided. * @return always throws TTransportException but declares return type to allow throw * sendAndThrowMessage(...) to inform compiler control flow */ protected TTransportException sendAndThrowMessage(NegotiationStatus status, String message) throws TTransportException { try { sendSaslMessage(status, message.getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { LOGGER.warn("Could not send failure response", e); message += "\nAlso, could not send response: " + e.toString(); } throw new TTransportException(message); } /** * Implemented by subclasses to start the Thrift SASL handshake process. When this method * completes, the SaslParticipant in this class is assumed to be initialized. * * @throws TTransportException * @throws SaslException */ protected abstract void handleSaslStartMessage() throws TTransportException, SaslException; protected abstract SaslRole getRole(); /** * Opens the underlying transport if it's not already open and then performs SASL negotiation. If * a QOP is negotiated during this SASL handshake, it used for all communication on this transport * after this call is complete. */ @Override public void open() throws TTransportException { /* * readSaslHeader is used to tag whether the SASL header has been read properly. * If there is a problem in reading the header, there might not be any * data in the stream, possibly a TCP health check from load balancer. */ boolean readSaslHeader = false; LOGGER.debug("opening transport {}", this); if (sasl != null && sasl.isComplete()) throw new TTransportException("SASL transport already open"); if (!underlyingTransport.isOpen()) underlyingTransport.open(); try { // Negotiate a SASL mechanism. The client also sends its // initial response, or an empty one. handleSaslStartMessage(); readSaslHeader = true; LOGGER.debug("{}: Start message handled", getRole()); SaslResponse message = null; while (!sasl.isComplete()) { message = receiveSaslMessage(); if (message.status != NegotiationStatus.COMPLETE && message.status != NegotiationStatus.OK) { throw new TTransportException("Expected COMPLETE or OK, got " + message.status); } byte[] challenge = sasl.evaluateChallengeOrResponse(message.payload); // If we are the client, and the server indicates COMPLETE, we don't need to // send back any further response. if (message.status == NegotiationStatus.COMPLETE && getRole() == SaslRole.CLIENT) { LOGGER.debug("{}: All done!", getRole()); continue; } sendSaslMessage( sasl.isComplete() ? NegotiationStatus.COMPLETE : NegotiationStatus.OK, challenge); } LOGGER.debug("{}: Main negotiation loop complete", getRole()); // If we're the client, and we're complete, but the server isn't // complete yet, we need to wait for its response. This will occur // with ANONYMOUS auth, for example, where we send an initial response // and are immediately complete. if (getRole() == SaslRole.CLIENT && (message == null || message.status == NegotiationStatus.OK)) { LOGGER.debug("{}: SASL Client receiving last message", getRole()); message = receiveSaslMessage(); if (message.status != NegotiationStatus.COMPLETE) { throw new TTransportException("Expected SASL COMPLETE, but got " + message.status); } } } catch (SaslException e) { try { LOGGER.error("SASL negotiation failure", e); throw sendAndThrowMessage(NegotiationStatus.BAD, e.getMessage()); } finally { underlyingTransport.close(); } } catch (TTransportException e) { // If there is no-data or no-sasl header in the stream, // log the failure, and clean up the underlying transport. if (!readSaslHeader && e.getType() == TTransportException.END_OF_FILE) { underlyingTransport.close(); LOGGER.debug("No data or no sasl data in the stream during negotiation"); } throw e; } String qop = (String) sasl.getNegotiatedProperty(Sasl.QOP); if (qop != null && !qop.equalsIgnoreCase("auth")) shouldWrap = true; } /** * Get the underlying SaslClient. * * @return The SaslClient, or null if this transport is backed by a * SaslServer. */ public SaslClient getSaslClient() { return sasl.saslClient; } /** * Get the underlying transport that Sasl is using. * * @return The TTransport transport */ public TTransport getUnderlyingTransport() { return underlyingTransport; } /** * Get the underlying SaslServer. * * @return The SaslServer, or null if this transport is backed by a * SaslClient. */ public SaslServer getSaslServer() { return sasl.saslServer; } /** * Read a 4-byte word from the underlying transport and interpret it as an integer. * * @return The length prefix of the next SASL message to read. * @throws TTransportException Thrown if reading from the underlying transport fails. */ protected int readLength() throws TTransportException { byte[] lenBuf = new byte[4]; underlyingTransport.readAll(lenBuf, 0, lenBuf.length); return EncodingUtils.decodeBigEndian(lenBuf); } /** * Write the given integer as 4 bytes to the underlying transport. * * @param length The length prefix of the next SASL message to write. * @throws TTransportException Thrown if writing to the underlying transport fails. */ protected void writeLength(int length) throws TTransportException { byte[] lenBuf = new byte[4]; TFramedTransport.encodeFrameSize(length, lenBuf); underlyingTransport.write(lenBuf); } // Below is the SASL implementation of the TTransport interface. /** * Closes the underlying transport and disposes of the SASL implementation underlying this * transport. */ @Override public void close() { underlyingTransport.close(); try { sasl.dispose(); } catch (SaslException e) { LOGGER.warn("Failed to dispose sasl participant.", e); } } /** True if the underlying transport is open and the SASL handshake is complete. */ @Override public boolean isOpen() { return underlyingTransport.isOpen() && sasl != null && sasl.isComplete(); } /** * Read from the underlying transport. Unwraps the contents if a QOP was negotiated during the * SASL handshake. */ @Override public int read(byte[] buf, int off, int len) throws TTransportException { if (!isOpen()) throw new TTransportException("SASL authentication not complete"); int got = readBuffer.read(buf, off, len); if (got > 0) { return got; } // Read another frame of data try { readFrame(); } catch (SaslException e) { throw new TTransportException(e); } catch (TTransportException transportException) { // If there is no-data or no-sasl header in the stream, log the failure, and rethrow. if (transportException.getType() == TTransportException.END_OF_FILE) { LOGGER.debug("No data or no sasl data in the stream during negotiation"); } throw transportException; } return readBuffer.read(buf, off, len); } /** * Read a single frame of data from the underlying transport, unwrapping if necessary. * * @throws TTransportException Thrown if there's an error reading from the underlying transport. * @throws SaslException Thrown if there's an error unwrapping the data. */ private void readFrame() throws TTransportException, SaslException { int dataLength = readLength(); if (dataLength < 0) throw new TTransportException("Read a negative frame size (" + dataLength + ")!"); byte[] buff = new byte[dataLength]; LOGGER.debug("{}: reading data length: {}", getRole(), dataLength); underlyingTransport.readAll(buff, 0, dataLength); if (shouldWrap) { buff = sasl.unwrap(buff, 0, buff.length); LOGGER.debug("data length after unwrap: {}", buff.length); } readBuffer.reset(buff); } /** Write to the underlying transport. */ @Override public void write(byte[] buf, int off, int len) throws TTransportException { if (!isOpen()) throw new TTransportException("SASL authentication not complete"); writeBuffer.write(buf, off, len); } /** * Flushes to the underlying transport. Wraps the contents if a QOP was negotiated during the SASL * handshake. */ @Override public void flush() throws TTransportException { byte[] buf = writeBuffer.get(); int dataLength = writeBuffer.len(); writeBuffer.reset(); if (shouldWrap) { LOGGER.debug("data length before wrap: {}", dataLength); try { buf = sasl.wrap(buf, 0, dataLength); } catch (SaslException e) { throw new TTransportException(e); } dataLength = buf.length; } LOGGER.debug("writing data length: {}", dataLength); writeLength(dataLength); underlyingTransport.write(buf, 0, dataLength); underlyingTransport.flush(); } /** Used exclusively by readSaslMessage to return both a status and data. */ protected static class SaslResponse { public NegotiationStatus status; public byte[] payload; public SaslResponse(NegotiationStatus status, byte[] payload) { this.status = status; this.payload = payload; } } /** * Used to abstract over the SaslServer and SaslClient classes, which * share a lot of their interface, but unfortunately don't share a common superclass. */ private static class SaslParticipant { // One of these will always be null. public SaslServer saslServer; public SaslClient saslClient; public SaslParticipant(SaslServer saslServer) { this.saslServer = saslServer; } public SaslParticipant(SaslClient saslClient) { this.saslClient = saslClient; } public byte[] evaluateChallengeOrResponse(byte[] challengeOrResponse) throws SaslException { if (saslClient != null) { return saslClient.evaluateChallenge(challengeOrResponse); } else { return saslServer.evaluateResponse(challengeOrResponse); } } public boolean isComplete() { if (saslClient != null) return saslClient.isComplete(); else return saslServer.isComplete(); } public void dispose() throws SaslException { if (saslClient != null) saslClient.dispose(); else saslServer.dispose(); } public byte[] unwrap(byte[] buf, int off, int len) throws SaslException { if (saslClient != null) return saslClient.unwrap(buf, off, len); else return saslServer.unwrap(buf, off, len); } public byte[] wrap(byte[] buf, int off, int len) throws SaslException { if (saslClient != null) return saslClient.wrap(buf, off, len); else return saslServer.wrap(buf, off, len); } public Object getNegotiatedProperty(String propName) { if (saslClient != null) return saslClient.getNegotiatedProperty(propName); else return saslServer.getNegotiatedProperty(propName); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/THttpClient.java0000664000175000017500000002445515165535636030143 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.io.entity.ByteArrayEntity; import org.apache.hc.core5.util.Timeout; import org.apache.thrift.TConfiguration; import org.apache.thrift.THttpClientResponseHandler; /** * HTTP implementation of the TTransport interface. Used for working with a Thrift web services * implementation (using for example TServlet). * *

This class offers two implementations of the HTTP transport. One uses HttpURLConnection * instances, the other HttpClient from Apache Http Components. The chosen implementation depends on * the constructor used to create the THttpClient instance. Using the THttpClient(String url) * constructor or passing null as the HttpClient to THttpClient(String url, HttpClient client) will * create an instance which will use HttpURLConnection. * *

When using HttpClient, the following configuration leads to 5-15% better performance than the * HttpURLConnection implementation: * *

http.protocol.version=HttpVersion.HTTP_1_1 http.protocol.content-charset=UTF-8 * http.protocol.expect-continue=false http.connection.stalecheck=false * *

Also note that under high load, the HttpURLConnection implementation may exhaust the open file * descriptor limit. * * @see THRIFT-970 */ public class THttpClient extends TEndpointTransport { private final URL url_; private final ByteArrayOutputStream requestBuffer_ = new ByteArrayOutputStream(); private InputStream inputStream_ = null; private int connectTimeout_ = 0; private int readTimeout_ = 0; private Map customHeaders_ = null; private final HttpHost host; private final HttpClient client; private static final Map DEFAULT_HEADERS = Collections.unmodifiableMap(getDefaultHeaders()); public static class Factory extends TTransportFactory { private final String url; private final HttpClient client; public Factory(String url) { this.url = url; this.client = null; } public Factory(String url, HttpClient client) { this.url = url; this.client = client; } @Override public TTransport getTransport(TTransport trans) { try { if (null != client) { return new THttpClient(trans.getConfiguration(), url, client); } else { return new THttpClient(trans.getConfiguration(), url); } } catch (TTransportException tte) { return null; } } } public THttpClient(TConfiguration config, String url) throws TTransportException { super(config); try { url_ = new URL(url); this.client = null; this.host = null; } catch (IOException iox) { throw new TTransportException(iox); } } public THttpClient(String url) throws TTransportException { super(new TConfiguration()); try { url_ = new URL(url); this.client = null; this.host = null; } catch (IOException iox) { throw new TTransportException(iox); } } public THttpClient(TConfiguration config, String url, HttpClient client) throws TTransportException { super(config); try { url_ = new URL(url); this.client = client; this.host = new HttpHost( url_.getProtocol(), url_.getHost(), -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort()); } catch (IOException iox) { throw new TTransportException(iox); } } public THttpClient(String url, HttpClient client) throws TTransportException { super(new TConfiguration()); try { url_ = new URL(url); this.client = client; this.host = new HttpHost( url_.getProtocol(), url_.getHost(), -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort()); } catch (IOException iox) { throw new TTransportException(iox); } } public void setConnectTimeout(int timeout) { connectTimeout_ = timeout; } /** * Use instead {@link * org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager#setConnectionConfig} or * {@link * org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager#setDefaultConnectionConfig} */ @Deprecated public void setReadTimeout(int timeout) { readTimeout_ = timeout; } public void setCustomHeaders(Map headers) { customHeaders_ = new HashMap<>(headers); } public void setCustomHeader(String key, String value) { if (customHeaders_ == null) { customHeaders_ = new HashMap<>(); } customHeaders_.put(key, value); } @Override public void open() {} @Override public void close() { if (null != inputStream_) { try { inputStream_.close(); } catch (IOException ioe) { } inputStream_ = null; } } @Override public boolean isOpen() { return true; } @Override public int read(byte[] buf, int off, int len) throws TTransportException { if (inputStream_ == null) { throw new TTransportException("Response buffer is empty, no request."); } checkReadBytesAvailable(len); try { int ret = inputStream_.read(buf, off, len); if (ret == -1) { throw new TTransportException("No more data available."); } countConsumedMessageBytes(ret); return ret; } catch (IOException iox) { throw new TTransportException(iox); } } @Override public void write(byte[] buf, int off, int len) { requestBuffer_.write(buf, off, len); } private RequestConfig getRequestConfig() { RequestConfig requestConfig = RequestConfig.DEFAULT; if (connectTimeout_ > 0) { requestConfig = RequestConfig.copy(requestConfig) .setConnectionRequestTimeout(Timeout.ofMilliseconds(connectTimeout_)) .build(); } return requestConfig; } private ConnectionConfig getConnectionConfig() { ConnectionConfig connectionConfig = ConnectionConfig.DEFAULT; if (readTimeout_ > 0) { connectionConfig = ConnectionConfig.copy(connectionConfig) .setSocketTimeout(Timeout.ofMilliseconds(readTimeout_)) .build(); } return connectionConfig; } private static Map getDefaultHeaders() { Map headers = new HashMap<>(); headers.put("Content-Type", "application/x-thrift"); headers.put("Accept", "application/x-thrift"); headers.put("User-Agent", "Java/THttpClient/HC"); return headers; } private void flushUsingHttpClient() throws TTransportException { if (null == this.client) { throw new TTransportException("Null HttpClient, aborting."); } // Extract request and reset buffer byte[] data = requestBuffer_.toByteArray(); requestBuffer_.reset(); HttpPost post = new HttpPost(this.url_.getFile()); try { // Set request to path + query string post.setConfig(getRequestConfig()); DEFAULT_HEADERS.forEach(post::addHeader); if (null != customHeaders_) { customHeaders_.forEach(post::addHeader); } post.setEntity(new ByteArrayEntity(data, null)); inputStream_ = client.execute(this.host, post, new THttpClientResponseHandler()); } catch (IOException ioe) { // Abort method so the connection gets released back to the connection manager post.abort(); throw new TTransportException(ioe); } finally { resetConsumedMessageSize(-1); } } public void flush() throws TTransportException { if (null != this.client) { flushUsingHttpClient(); return; } // Extract request and reset buffer byte[] data = requestBuffer_.toByteArray(); requestBuffer_.reset(); try { // Create connection object HttpURLConnection connection = (HttpURLConnection) url_.openConnection(); // Timeouts, only if explicitly set if (connectTimeout_ > 0) { connection.setConnectTimeout(connectTimeout_); } if (readTimeout_ > 0) { connection.setReadTimeout(readTimeout_); } // Make the request connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-thrift"); connection.setRequestProperty("Accept", "application/x-thrift"); connection.setRequestProperty("User-Agent", "Java/THttpClient"); if (customHeaders_ != null) { for (Map.Entry header : customHeaders_.entrySet()) { connection.setRequestProperty(header.getKey(), header.getValue()); } } connection.setDoOutput(true); connection.connect(); connection.getOutputStream().write(data); int responseCode = connection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { throw new TTransportException("HTTP Response code: " + responseCode); } // Read the responses inputStream_ = connection.getInputStream(); } catch (IOException iox) { throw new TTransportException(iox); } finally { resetConsumedMessageSize(-1); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TSaslServerTransport.java0000664000175000017500000002073515165535636032070 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.lang.ref.WeakReference; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.thrift.transport.sasl.NegotiationStatus; import org.apache.thrift.transport.sasl.TSaslServerDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Wraps another Thrift TTransport, but performs SASL server negotiation on the call to * open(). This class will wrap ensuing communication over it, if a SASL QOP is * negotiated with the other party. */ public class TSaslServerTransport extends TSaslTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TSaslServerTransport.class); /** * Mapping from SASL mechanism name -> all the parameters required to instantiate a SASL server. */ private Map serverDefinitionMap = new HashMap(); /** * Uses the given underlying transport. Assumes that addServerDefinition is called later. * * @param transport Transport underlying this one. */ public TSaslServerTransport(TTransport transport) throws TTransportException { super(transport); } /** * Creates a SaslServer using the given SASL-specific parameters. See the Java * documentation for Sasl.createSaslServer for the details of the parameters. * * @param transport The underlying Thrift transport. */ public TSaslServerTransport( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh, TTransport transport) throws TTransportException { super(transport); addServerDefinition(mechanism, protocol, serverName, props, cbh); } private TSaslServerTransport( Map serverDefinitionMap, TTransport transport) throws TTransportException { super(transport); this.serverDefinitionMap.putAll(serverDefinitionMap); } /** * Add a supported server definition to this transport. See the Java documentation for * Sasl.createSaslServer for the details of the parameters. */ public void addServerDefinition( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { serverDefinitionMap.put( mechanism, new TSaslServerDefinition(mechanism, protocol, serverName, props, cbh)); } @Override protected SaslRole getRole() { return SaslRole.SERVER; } /** * Performs the server side of the initial portion of the Thrift SASL protocol. Receives the * initial response from the client, creates a SASL server using the mechanism requested by the * client (if this server supports it), and sends the first challenge back to the client. */ @Override protected void handleSaslStartMessage() throws TTransportException, SaslException { SaslResponse message = receiveSaslMessage(); LOGGER.debug("Received start message with status {}", message.status); if (message.status != NegotiationStatus.START) { throw sendAndThrowMessage( NegotiationStatus.ERROR, "Expecting START status, received " + message.status); } // Get the mechanism name. String mechanismName = new String(message.payload, StandardCharsets.UTF_8); TSaslServerDefinition serverDefinition = serverDefinitionMap.get(mechanismName); LOGGER.debug("Received mechanism name '{}'", mechanismName); if (serverDefinition == null) { throw sendAndThrowMessage( NegotiationStatus.BAD, "Unsupported mechanism type " + mechanismName); } SaslServer saslServer = Sasl.createSaslServer( serverDefinition.mechanism, serverDefinition.protocol, serverDefinition.serverName, serverDefinition.props, serverDefinition.cbh); setSaslServer(saslServer); } /** * TTransportFactory to create TSaslServerTransports. Ensures that a * given underlying TTransport instance receives the same TSaslServerTransport * . This is kind of an awful hack to work around the fact that Thrift is designed assuming * that TTransport instances are stateless, and thus the existing TServers * use different TTransport instances for input and output. */ public static class Factory extends TTransportFactory { /** * This is the implementation of the awful hack described above. WeakHashMap is * used to ensure that we don't leak memory. */ private static Map> transportMap = Collections.synchronizedMap( new WeakHashMap>()); /** * Mapping from SASL mechanism name -> all the parameters required to instantiate a SASL server. */ private Map serverDefinitionMap = new HashMap(); /** Create a new Factory. Assumes that addServerDefinition will be called later. */ public Factory() { super(); } /** * Create a new Factory, initially with the single server definition given. You may * still call addServerDefinition later. See the Java documentation for * Sasl.createSaslServer for the details of the parameters. */ public Factory( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { super(); addServerDefinition(mechanism, protocol, serverName, props, cbh); } /** * Add a supported server definition to the transports created by this factory. See the Java * documentation for Sasl.createSaslServer for the details of the parameters. */ public void addServerDefinition( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { serverDefinitionMap.put( mechanism, new TSaslServerDefinition(mechanism, protocol, serverName, props, cbh)); } /** * Get a new TSaslServerTransport instance, or reuse the existing one if a * TSaslServerTransport has already been created before using the given TTransport * as an underlying transport. This ensures that a given underlying transport instance * receives the same TSaslServerTransport. */ @Override public TTransport getTransport(TTransport base) throws TTransportException { WeakReference ret = transportMap.get(base); if (ret == null || ret.get() == null) { LOGGER.debug("transport map does not contain key", base); ret = new WeakReference( new TSaslServerTransport(serverDefinitionMap, base)); try { ret.get().open(); } catch (TTransportException e) { LOGGER.debug("failed to open server transport", e); throw new RuntimeException(e); } transportMap.put(base, ret); // No need for putIfAbsent(). // Concurrent calls to getTransport() will pass in different TTransports. } else { LOGGER.debug("transport map does contain key {}", base); } return ret.get(); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/0000775000175000017500000000000015167543515026023 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/TSaslServerDefinition.java0000664000175000017500000000277315165535636033130 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import java.util.Map; import javax.security.auth.callback.CallbackHandler; /** Contains all the parameters used to define a SASL server implementation. */ public class TSaslServerDefinition { public final String mechanism; public final String protocol; public final String serverName; public final Map props; public final CallbackHandler cbh; public TSaslServerDefinition( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { this.mechanism = mechanism; this.protocol = protocol; this.serverName = serverName; this.props = props; this.cbh = cbh; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/FrameHeaderReader.java0000664000175000017500000000404515165535636032162 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; /** * Read headers for a frame. For each frame, the header contains payload size and other metadata. */ public interface FrameHeaderReader { /** * As the thrift sasl specification states, all sasl messages (both for negotiatiing and for * sending data) should have a header to indicate the size of the payload. * * @return size of the payload. */ int payloadSize(); /** * @return The received bytes for the header. * @throws IllegalStateException if isComplete returns false. */ byte[] toBytes(); /** * @return true if this header has all its fields set. */ boolean isComplete(); /** Clear the header and make it available to read a new header. */ void clear(); /** * (Nonblocking) Read fields from underlying transport layer. * * @param transport underlying transport. * @return true if header is complete after read. * @throws TSaslNegotiationException if fail to read a valid header of a sasl negotiation message. * @throws TTransportException if io error. */ boolean read(TTransport transport) throws TSaslNegotiationException, TTransportException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/DataFrameWriter.java0000664000175000017500000000465015165535636031717 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.DataFrameHeaderReader.PAYLOAD_LENGTH_BYTES; import java.nio.ByteBuffer; import org.apache.thrift.EncodingUtils; import org.apache.thrift.utils.StringUtils; /** * Write frames of thrift messages. It expects an empty/null header to be provided with a payload to * be written out. Non empty headers are considered as error. */ public class DataFrameWriter extends FrameWriter { @Override public void withOnlyPayload(byte[] payload, int offset, int length) { if (!isComplete()) { throw new IllegalStateException( "Previous write is not yet complete, with " + frameBytes.remaining() + " bytes left."); } frameBytes = buildFrameWithPayload(payload, offset, length); } @Override protected ByteBuffer buildFrame( byte[] header, int headerOffset, int headerLength, byte[] payload, int payloadOffset, int payloadLength) { if (header != null && headerLength > 0) { throw new IllegalArgumentException( "Extra header [" + StringUtils.bytesToHexString(header) + "] offset " + payloadOffset + " length " + payloadLength); } return buildFrameWithPayload(payload, payloadOffset, payloadLength); } private ByteBuffer buildFrameWithPayload(byte[] payload, int offset, int length) { byte[] bytes = new byte[PAYLOAD_LENGTH_BYTES + length]; EncodingUtils.encodeBigEndian(length, bytes, 0); System.arraycopy(payload, offset, bytes, PAYLOAD_LENGTH_BYTES, length); return ByteBuffer.wrap(bytes); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/SaslPeer.java0000664000175000017500000000614615165535636030416 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import org.apache.thrift.transport.TTransportException; /** A peer in a sasl negotiation. */ public interface SaslPeer { /** * Evaluate and validate the negotiation message (response/challenge) received from peer. * * @param negotiationMessage response/challenge received from peer. * @return new response/challenge to send to peer, can be null if authentication becomes success. * @throws TSaslNegotiationException if sasl authentication fails. */ byte[] evaluate(byte[] negotiationMessage) throws TSaslNegotiationException; /** * @return true if authentication is done. */ boolean isAuthenticated(); /** * This method can only be called when the negotiation is complete (isAuthenticated returns true). * Otherwise it will throw IllegalStateExceptiion. * * @return if the qop requires some integrity/confidential protection. * @throws IllegalStateException if negotiation is not yet complete. */ boolean isDataProtected(); /** * Wrap raw bytes to protect it. * * @param data raw bytes. * @param offset the start position of the content to wrap. * @param length the length of the content to wrap. * @return bytes with protection to send to peer. * @throws TTransportException if failure. */ byte[] wrap(byte[] data, int offset, int length) throws TTransportException; /** * Wrap the whole byte array. * * @param data raw bytes. * @return wrapped bytes. * @throws TTransportException if failure. */ default byte[] wrap(byte[] data) throws TTransportException { return wrap(data, 0, data.length); } /** * Unwrap protected data to raw bytes. * * @param data protected data received from peer. * @param offset the start position of the content to unwrap. * @param length the length of the content to unwrap. * @return raw bytes. * @throws TTransportException if failed. */ byte[] unwrap(byte[] data, int offset, int length) throws TTransportException; /** * Unwrap the whole byte array. * * @param data wrapped bytes. * @return raw bytes. * @throws TTransportException if failure. */ default byte[] unwrap(byte[] data) throws TTransportException { return unwrap(data, 0, data.length); } /** Close this peer and release resources. */ void dispose(); } SaslNegotiationFrameReader.java0000664000175000017500000000206315165535636034014 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; /** Read frames for sasl negotiatiions. */ public class SaslNegotiationFrameReader extends FrameReader { public SaslNegotiationFrameReader() { super(new SaslNegotiationHeaderReader()); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/NonblockingSaslHandler.java0000664000175000017500000004364415167543515033265 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.NegotiationStatus.COMPLETE; import static org.apache.thrift.transport.sasl.NegotiationStatus.OK; import java.net.SocketAddress; import java.nio.channels.SelectionKey; import java.nio.charset.StandardCharsets; import javax.security.sasl.SaslServer; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerContext; import org.apache.thrift.server.TServerEventHandler; import org.apache.thrift.transport.SocketAddressProvider; import org.apache.thrift.transport.TMemoryTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.sasl.TSaslNegotiationException.ErrorType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** State machine managing one sasl connection in a nonblocking way. */ public class NonblockingSaslHandler { private static final Logger LOGGER = LoggerFactory.getLogger(NonblockingSaslHandler.class); private static final int INTEREST_NONE = 0; private static final int INTEREST_READ = SelectionKey.OP_READ; private static final int INTEREST_WRITE = SelectionKey.OP_WRITE; // Tracking the current running phase private Phase currentPhase = Phase.INITIIALIIZING; // Tracking the next phase on the next invocation of the state machine. // It should be the same as current phase if current phase is not yet finished. // Otherwise, if it is different from current phase, the statemachine is in a transition state: // current phase is done, and next phase is not yet started. private Phase nextPhase = currentPhase; // Underlying nonblocking transport private SelectionKey selectionKey; private TNonblockingTransport underlyingTransport; // APIs for intercepting event / customizing behaviors: // Factories (decorating the base implementations) & EventHandler (intercepting) private TSaslServerFactory saslServerFactory; private TSaslProcessorFactory processorFactory; private TProtocolFactory inputProtocolFactory; private TProtocolFactory outputProtocolFactory; private TServerEventHandler eventHandler; private ServerContext serverContext; // It turns out the event handler implementation in hive sometimes creates a null ServerContext. // In order to know whether TServerEventHandler#createContext is called we use such a flag. private boolean serverContextCreated = false; // Wrapper around sasl server private ServerSaslPeer saslPeer; // Sasl negotiation io private SaslNegotiationFrameReader saslResponse; private SaslNegotiationFrameWriter saslChallenge; // IO for request from and response to the socket private DataFrameReader requestReader; private DataFrameWriter responseWriter; // If sasl is negotiated for integrity/confidentiality protection private boolean dataProtected; public NonblockingSaslHandler( SelectionKey selectionKey, TNonblockingTransport underlyingTransport, TSaslServerFactory saslServerFactory, TSaslProcessorFactory processorFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TServerEventHandler eventHandler) { this.selectionKey = selectionKey; this.underlyingTransport = underlyingTransport; this.saslServerFactory = saslServerFactory; this.processorFactory = processorFactory; this.inputProtocolFactory = inputProtocolFactory; this.outputProtocolFactory = outputProtocolFactory; this.eventHandler = eventHandler; saslResponse = new SaslNegotiationFrameReader(); saslChallenge = new SaslNegotiationFrameWriter(); requestReader = new DataFrameReader(); responseWriter = new DataFrameWriter(); } /** * Get current phase of the state machine. * * @return current phase. */ public Phase getCurrentPhase() { return currentPhase; } /** * Get next phase of the state machine. It is different from current phase iff current phase is * done (and next phase not yet started). * * @return next phase. */ public Phase getNextPhase() { return nextPhase; } /** * @return underlying nonblocking socket */ public TNonblockingTransport getUnderlyingTransport() { return underlyingTransport; } /** * @return SaslServer instance */ public SaslServer getSaslServer() { return saslPeer.getSaslServer(); } /** * @return true if current phase is done. */ public boolean isCurrentPhaseDone() { return currentPhase != nextPhase; } /** * Run state machine. * * @throws IllegalStateException if current state is already done. */ public void runCurrentPhase() { currentPhase.runStateMachine(this); } /** * When current phase is intrested in read selection, calling this will run the current phase and * its following phases if the following ones are interested to read, until there is nothing * available in the underlying transport. * * @throws IllegalStateException if is called in an irrelevant phase. */ public void handleRead() { handleOps(INTEREST_READ); } /** * Similiar to handleRead. But it is for write ops. * * @throws IllegalStateException if it is called in an irrelevant phase. */ public void handleWrite() { handleOps(INTEREST_WRITE); } private void handleOps(int interestOps) { if (currentPhase.selectionInterest != interestOps) { throw new IllegalStateException( "Current phase " + currentPhase + " but got interest " + interestOps); } runCurrentPhase(); if (isCurrentPhaseDone() && nextPhase.selectionInterest == interestOps) { stepToNextPhase(); handleOps(interestOps); } } /** * When current phase is finished, it's expected to call this method first before running the * state machine again. By calling this, "next phase" is marked as started (and not done), thus is * ready to run. * * @throws IllegalArgumentException if current phase is not yet done. */ public void stepToNextPhase() { if (!isCurrentPhaseDone()) { throw new IllegalArgumentException("Not yet done with current phase: " + currentPhase); } LOGGER.debug("Switch phase {} to {}", currentPhase, nextPhase); switch (nextPhase) { case INITIIALIIZING: throw new IllegalStateException("INITIALIZING cannot be the next phase of " + currentPhase); default: } // If next phase's interest is not the same as current, nor the same as the selection key, // we need to change interest on the selector. if (!(nextPhase.selectionInterest == currentPhase.selectionInterest || nextPhase.selectionInterest == selectionKey.interestOps())) { changeSelectionInterest(nextPhase.selectionInterest); } currentPhase = nextPhase; } private void changeSelectionInterest(int selectionInterest) { selectionKey.interestOps(selectionInterest); } // sasl negotiation failure handling private void failSaslNegotiation(TSaslNegotiationException e) { LOGGER.error("Sasl negotiation failed", e); String errorMsg = e.getDetails(); saslChallenge.withHeaderAndPayload( new byte[] {e.getErrorType().code.getValue()}, errorMsg.getBytes(StandardCharsets.UTF_8)); nextPhase = Phase.WRITING_FAILURE_MESSAGE; } private void fail(Exception e) { LOGGER.error("Failed io in " + currentPhase, e); nextPhase = Phase.CLOSING; } private void failIO(TTransportException e) { StringBuilder errorMsg = new StringBuilder("IO failure ").append(e.getType()).append(" in ").append(currentPhase); if (e.getMessage() != null) { errorMsg.append(": ").append(e.getMessage()); } LOGGER.error(errorMsg.toString(), e); nextPhase = Phase.CLOSING; } // Read handlings private void handleInitializing() { try { saslResponse.read(underlyingTransport); if (saslResponse.isComplete()) { SaslNegotiationHeaderReader startHeader = saslResponse.getHeader(); if (startHeader.getStatus() != NegotiationStatus.START) { throw new TInvalidSaslFrameException( "Expecting START status but got " + startHeader.getStatus()); } String mechanism = new String(saslResponse.getPayload(), StandardCharsets.UTF_8); saslPeer = saslServerFactory.getSaslPeer(mechanism); saslResponse.clear(); nextPhase = Phase.READING_SASL_RESPONSE; } } catch (TSaslNegotiationException e) { failSaslNegotiation(e); } catch (TTransportException e) { failIO(e); } } private void handleReadingSaslResponse() { try { saslResponse.read(underlyingTransport); if (saslResponse.isComplete()) { nextPhase = Phase.EVALUATING_SASL_RESPONSE; } } catch (TSaslNegotiationException e) { failSaslNegotiation(e); } catch (TTransportException e) { failIO(e); } } private void handleReadingRequest() { try { requestReader.read(underlyingTransport); if (requestReader.isComplete()) { nextPhase = Phase.PROCESSING; } } catch (TTransportException e) { failIO(e); } } // Computation executions private void executeEvaluatingSaslResponse() { if (!(saslResponse.getHeader().getStatus() == OK || saslResponse.getHeader().getStatus() == COMPLETE)) { String error = "Expect status OK or COMPLETE, but got " + saslResponse.getHeader().getStatus(); failSaslNegotiation(new TSaslNegotiationException(ErrorType.PROTOCOL_ERROR, error)); return; } try { byte[] response = saslResponse.getPayload(); saslResponse.clear(); byte[] newChallenge = saslPeer.evaluate(response); if (saslPeer.isAuthenticated()) { dataProtected = saslPeer.isDataProtected(); saslChallenge.withHeaderAndPayload(new byte[] {COMPLETE.getValue()}, newChallenge); nextPhase = Phase.WRITING_SUCCESS_MESSAGE; } else { saslChallenge.withHeaderAndPayload(new byte[] {OK.getValue()}, newChallenge); nextPhase = Phase.WRITING_SASL_CHALLENGE; } } catch (TSaslNegotiationException e) { failSaslNegotiation(e); } } private void executeProcessing() { try { byte[] inputPayload = requestReader.getPayload(); requestReader.clear(); byte[] rawInput = dataProtected ? saslPeer.unwrap(inputPayload) : inputPayload; TMemoryTransport memoryTransport = new TMemoryTransport(underlyingTransport.getConfiguration(), rawInput); TProtocol requestProtocol = inputProtocolFactory.getProtocol(memoryTransport); TProtocol responseProtocol = outputProtocolFactory.getProtocol(memoryTransport); if (eventHandler != null) { if (!serverContextCreated) { serverContext = eventHandler.createContext(requestProtocol, responseProtocol); SocketAddress remoteAddress = underlyingTransport instanceof SocketAddressProvider ? ((SocketAddressProvider) underlyingTransport).getRemoteSocketAddress() : null; serverContext.setRemoteAddress(remoteAddress); serverContextCreated = true; } eventHandler.processContext(serverContext, memoryTransport, memoryTransport); } TProcessor processor = processorFactory.getProcessor(this); processor.process(requestProtocol, responseProtocol); TByteArrayOutputStream rawOutput = memoryTransport.getOutput(); if (rawOutput.len() == 0) { // This is a oneway request, no response to send back. Waiting for next incoming request. nextPhase = Phase.READING_REQUEST; return; } if (dataProtected) { byte[] outputPayload = saslPeer.wrap(rawOutput.get(), 0, rawOutput.len()); responseWriter.withOnlyPayload(outputPayload); } else { responseWriter.withOnlyPayload(rawOutput.get(), 0, rawOutput.len()); } nextPhase = Phase.WRITING_RESPONSE; } catch (TTransportException e) { failIO(e); } catch (Exception e) { fail(e); } } // Write handlings private void handleWritingSaslChallenge() { try { saslChallenge.write(underlyingTransport); if (saslChallenge.isComplete()) { saslChallenge.clear(); nextPhase = Phase.READING_SASL_RESPONSE; } } catch (TTransportException e) { fail(e); } } private void handleWritingSuccessMessage() { try { saslChallenge.write(underlyingTransport); if (saslChallenge.isComplete()) { LOGGER.debug("Authentication is done."); saslChallenge = null; saslResponse = null; nextPhase = Phase.READING_REQUEST; } } catch (TTransportException e) { fail(e); } } private void handleWritingFailureMessage() { try { saslChallenge.write(underlyingTransport); if (saslChallenge.isComplete()) { nextPhase = Phase.CLOSING; } } catch (TTransportException e) { fail(e); } } private void handleWritingResponse() { try { responseWriter.write(underlyingTransport); if (responseWriter.isComplete()) { responseWriter.clear(); nextPhase = Phase.READING_REQUEST; } } catch (TTransportException e) { fail(e); } } /** * Release all the resources managed by this state machine (connection, selection and sasl * server). To avoid being blocked, this should be invoked in the network thread that manages the * selector. */ public void close() { try { if (serverContextCreated) { eventHandler.deleteContext( serverContext, inputProtocolFactory.getProtocol(underlyingTransport), outputProtocolFactory.getProtocol(underlyingTransport)); } } finally { selectionKey.cancel(); if (saslPeer != null) { saslPeer.dispose(); } nextPhase = Phase.CLOSED; currentPhase = Phase.CLOSED; underlyingTransport.close(); LOGGER.trace("Connection closed: {}", underlyingTransport); } } public enum Phase { INITIIALIIZING(INTEREST_READ) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.handleInitializing(); } }, READING_SASL_RESPONSE(INTEREST_READ) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.handleReadingSaslResponse(); } }, EVALUATING_SASL_RESPONSE(INTEREST_NONE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.executeEvaluatingSaslResponse(); } }, WRITING_SASL_CHALLENGE(INTEREST_WRITE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.handleWritingSaslChallenge(); } }, WRITING_SUCCESS_MESSAGE(INTEREST_WRITE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.handleWritingSuccessMessage(); } }, WRITING_FAILURE_MESSAGE(INTEREST_WRITE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.handleWritingFailureMessage(); } }, READING_REQUEST(INTEREST_READ) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.handleReadingRequest(); } }, PROCESSING(INTEREST_NONE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.executeProcessing(); } }, WRITING_RESPONSE(INTEREST_WRITE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.handleWritingResponse(); } }, CLOSING(INTEREST_NONE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { statemachine.close(); } }, CLOSED(INTEREST_NONE) { @Override void unsafeRun(NonblockingSaslHandler statemachine) { // Do nothing. } }; // The interest on the selection key during the phase private final int selectionInterest; Phase(int selectionInterest) { this.selectionInterest = selectionInterest; } /** * Provide the execution to run for the state machine in current phase. The execution should * return the next phase after running on the state machine. * * @param statemachine The state machine to run. * @throws IllegalArgumentException if the state machine's current phase is different. * @throws IllegalStateException if the state machine' current phase is already done. */ void runStateMachine(NonblockingSaslHandler statemachine) { if (statemachine.currentPhase != this) { throw new IllegalArgumentException( "State machine is " + statemachine.currentPhase + " but is expected to be " + this); } if (statemachine.isCurrentPhaseDone()) { throw new IllegalStateException("State machine should step into " + statemachine.nextPhase); } unsafeRun(statemachine); } // Run the state machine without checkiing its own phase // It should not be called direcly by users. abstract void unsafeRun(NonblockingSaslHandler statemachine); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/TSaslProcessorFactory.java0000664000175000017500000000225715165535636033155 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; /** * Get processor for a given state machine, so that users can customize the behavior of a TProcessor * by interacting with the state machine. */ public interface TSaslProcessorFactory { TProcessor getProcessor(NonblockingSaslHandler saslHandler) throws TException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/TBaseSaslProcessorFactory.java0000664000175000017500000000226715165535636033751 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import org.apache.thrift.TProcessor; public class TBaseSaslProcessorFactory implements TSaslProcessorFactory { private final TProcessor processor; public TBaseSaslProcessorFactory(TProcessor processor) { this.processor = processor; } @Override public TProcessor getProcessor(NonblockingSaslHandler saslHandler) { return processor; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/FixedSizeHeaderReader.java0000664000175000017500000000417415165535636033025 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import java.nio.ByteBuffer; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.utils.StringUtils; /** Headers' size should be predefined. */ public abstract class FixedSizeHeaderReader implements FrameHeaderReader { protected final ByteBuffer byteBuffer = ByteBuffer.allocate(headerSize()); @Override public boolean isComplete() { return !byteBuffer.hasRemaining(); } @Override public void clear() { byteBuffer.clear(); } @Override public byte[] toBytes() { if (!isComplete()) { throw new IllegalStateException( "Header is not yet complete " + StringUtils.bytesToHexString(byteBuffer.array(), 0, byteBuffer.position())); } return byteBuffer.array(); } @Override public boolean read(TTransport transport) throws TTransportException { FrameReader.readAvailable(transport, byteBuffer); if (byteBuffer.hasRemaining()) { return false; } onComplete(); return true; } /** * @return Size of the header. */ protected abstract int headerSize(); /** * Actions (e.g. validation) to carry out when the header is complete. * * @throws TTransportException */ protected abstract void onComplete() throws TTransportException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/FrameReader.java0000664000175000017500000001130515165535636031046 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import java.nio.ByteBuffer; import org.apache.thrift.transport.TEOFException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; /** * Read frames from a transport. Each frame has a header and a payload. A header will indicate the * size of the payload and other informations about how to decode payload. Implementations should * subclass it by providing a header reader implementation. * * @param Header type. */ public abstract class FrameReader { private final T header; private ByteBuffer payload; protected FrameReader(T header) { this.header = header; } /** * (Nonblocking) Read available bytes out of the transport without blocking to wait for incoming * data. * * @param transport TTransport * @return true if current frame is complete after read. * @throws TSaslNegotiationException if fail to read back a valid sasl negotiation message. * @throws TTransportException if io error. */ public boolean read(TTransport transport) throws TSaslNegotiationException, TTransportException { if (!header.isComplete()) { if (readHeader(transport)) { payload = ByteBuffer.allocate(header.payloadSize()); } else { return false; } } if (header.payloadSize() == 0) { return true; } return readPayload(transport); } /** * (Nonblocking) Try to read available header bytes from transport. * * @return true if header is complete after read. * @throws TSaslNegotiationException if fail to read back a validd sasl negotiation header. * @throws TTransportException if io error. */ private boolean readHeader(TTransport transport) throws TSaslNegotiationException, TTransportException { return header.read(transport); } /** * (Nonblocking) Try to read available * * @param transport underlying transport. * @return true if payload is complete after read. * @throws TTransportException if io error. */ private boolean readPayload(TTransport transport) throws TTransportException { readAvailable(transport, payload); return payload.hasRemaining(); } /** * @return header of the frame */ public T getHeader() { return header; } /** * @return number of bytes of the header */ public int getHeaderSize() { return header.toBytes().length; } /** * @return byte array of the payload */ public byte[] getPayload() { return payload.array(); } /** * @return size of the payload */ public int getPayloadSize() { return header.payloadSize(); } /** * @return true if the reader has fully read a frame */ public boolean isComplete() { return !(payload == null || payload.hasRemaining()); } /** Reset the state of the reader so that it can be reused to read a new frame. */ public void clear() { header.clear(); payload = null; } /** * Read immediately available bytes from the transport into the byte buffer. * * @param transport TTransport * @param recipient ByteBuffer * @return number of bytes read out of the transport * @throws TTransportException if io error */ static int readAvailable(TTransport transport, ByteBuffer recipient) throws TTransportException { if (!recipient.hasRemaining()) { throw new IllegalStateException( "Trying to fill a full recipient with " + recipient.limit() + " bytes"); } int currentPosition = recipient.position(); byte[] bytes = recipient.array(); int offset = recipient.arrayOffset() + currentPosition; int expectedLength = recipient.remaining(); int got = transport.read(bytes, offset, expectedLength); if (got < 0) { throw new TEOFException( "Transport is closed, while trying to read " + expectedLength + " bytes"); } recipient.position(currentPosition + got); return got; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/DataFrameReader.java0000664000175000017500000000202615165535636031640 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; /** Frames for thrift (serialized) messages. */ public class DataFrameReader extends FrameReader { public DataFrameReader() { super(new DataFrameHeaderReader()); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/NegotiationStatus.java0000664000175000017500000000341315165535636032356 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.TSaslNegotiationException.ErrorType.PROTOCOL_ERROR; import java.util.HashMap; import java.util.Map; /** Status bytes used during the initial Thrift SASL handshake. */ public enum NegotiationStatus { START((byte) 0x01), OK((byte) 0x02), BAD((byte) 0x03), ERROR((byte) 0x04), COMPLETE((byte) 0x05); private static final Map reverseMap = new HashMap<>(); static { for (NegotiationStatus s : NegotiationStatus.values()) { reverseMap.put(s.getValue(), s); } } private final byte value; NegotiationStatus(byte val) { this.value = val; } public byte getValue() { return value; } public static NegotiationStatus byValue(byte val) throws TSaslNegotiationException { if (!reverseMap.containsKey(val)) { throw new TSaslNegotiationException(PROTOCOL_ERROR, "Invalid status " + val); } return reverseMap.get(val); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/ServerSaslPeer.java0000664000175000017500000000643115165535636031602 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.TSaslNegotiationException.ErrorType.AUTHENTICATION_FAILURE; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Server side sasl peer, a wrapper around SaslServer to provide some handy methods. */ public class ServerSaslPeer implements SaslPeer { private static final Logger LOGGER = LoggerFactory.getLogger(ServerSaslPeer.class); private static final String QOP_AUTH_INT = "auth-int"; private static final String QOP_AUTH_CONF = "auth-conf"; private final SaslServer saslServer; public ServerSaslPeer(SaslServer saslServer) { this.saslServer = saslServer; } @Override public byte[] evaluate(byte[] negotiationMessage) throws TSaslNegotiationException { try { return saslServer.evaluateResponse(negotiationMessage); } catch (SaslException e) { throw new TSaslNegotiationException( AUTHENTICATION_FAILURE, "Authentication failed with " + saslServer.getMechanismName(), e); } } @Override public boolean isAuthenticated() { return saslServer.isComplete(); } @Override public boolean isDataProtected() { Object qop = saslServer.getNegotiatedProperty(Sasl.QOP); if (qop == null) { return false; } for (String word : qop.toString().split("\\s*,\\s*")) { String lowerCaseWord = word.toLowerCase(); if (QOP_AUTH_INT.equals(lowerCaseWord) || QOP_AUTH_CONF.equals(lowerCaseWord)) { return true; } } return false; } @Override public byte[] wrap(byte[] data, int offset, int length) throws TTransportException { try { return saslServer.wrap(data, offset, length); } catch (SaslException e) { throw new TTransportException("Failed to wrap data", e); } } @Override public byte[] unwrap(byte[] data, int offset, int length) throws TTransportException { try { return saslServer.unwrap(data, offset, length); } catch (SaslException e) { throw new TTransportException(TTransportException.CORRUPTED_DATA, "Failed to unwrap data", e); } } @Override public void dispose() { try { saslServer.dispose(); } catch (Exception e) { LOGGER.warn("Failed to close sasl server " + saslServer.getMechanismName(), e); } } SaslServer getSaslServer() { return saslServer; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/TSaslServerFactory.java0000664000175000017500000000506215165535636032441 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.TSaslNegotiationException.ErrorType.MECHANISME_MISMATCH; import static org.apache.thrift.transport.sasl.TSaslNegotiationException.ErrorType.PROTOCOL_ERROR; import java.util.HashMap; import java.util.Map; import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; /** * Factory to create sasl server. Users can extend this class to customize the SaslServer creation. */ public class TSaslServerFactory { private final Map saslMechanisms; public TSaslServerFactory() { this.saslMechanisms = new HashMap<>(); } public void addSaslMechanism( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { TSaslServerDefinition definition = new TSaslServerDefinition(mechanism, protocol, serverName, props, cbh); saslMechanisms.put(definition.mechanism, definition); } public ServerSaslPeer getSaslPeer(String mechanism) throws TSaslNegotiationException { if (!saslMechanisms.containsKey(mechanism)) { throw new TSaslNegotiationException( MECHANISME_MISMATCH, "Unsupported mechanism " + mechanism); } TSaslServerDefinition saslDef = saslMechanisms.get(mechanism); try { SaslServer saslServer = Sasl.createSaslServer( saslDef.mechanism, saslDef.protocol, saslDef.serverName, saslDef.props, saslDef.cbh); return new ServerSaslPeer(saslServer); } catch (SaslException e) { throw new TSaslNegotiationException( PROTOCOL_ERROR, "Fail to create sasl server " + mechanism, e); } } } SaslNegotiationHeaderReader.java0000664000175000017500000000355515165535636034161 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.TSaslNegotiationException.ErrorType.PROTOCOL_ERROR; /** * Header for sasl negotiation frames. It contains status byte of negotiation and a 4-byte integer * (payload size). */ public class SaslNegotiationHeaderReader extends FixedSizeHeaderReader { public static final int STATUS_BYTES = 1; public static final int PAYLOAD_LENGTH_BYTES = 4; private NegotiationStatus negotiationStatus; private int payloadSize; @Override protected int headerSize() { return STATUS_BYTES + PAYLOAD_LENGTH_BYTES; } @Override protected void onComplete() throws TSaslNegotiationException { negotiationStatus = NegotiationStatus.byValue(byteBuffer.get(0)); payloadSize = byteBuffer.getInt(1); if (payloadSize < 0) { throw new TSaslNegotiationException( PROTOCOL_ERROR, "Payload size is negative: " + payloadSize); } } @Override public int payloadSize() { return payloadSize; } public NegotiationStatus getStatus() { return negotiationStatus; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/DataFrameHeaderReader.java0000664000175000017500000000267215165535636032760 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; /** The header for data frame, it only contains a 4-byte payload size. */ public class DataFrameHeaderReader extends FixedSizeHeaderReader { public static final int PAYLOAD_LENGTH_BYTES = 4; private int payloadSize; @Override protected int headerSize() { return PAYLOAD_LENGTH_BYTES; } @Override protected void onComplete() throws TInvalidSaslFrameException { payloadSize = byteBuffer.getInt(0); if (payloadSize < 0) { throw new TInvalidSaslFrameException("Payload size is negative: " + payloadSize); } } @Override public int payloadSize() { return payloadSize; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/TSaslNegotiationException.java0000664000175000017500000000456215165535636034006 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import org.apache.thrift.transport.TTransportException; /** Exception for sasl negotiation errors. */ public class TSaslNegotiationException extends TTransportException { private final ErrorType error; public TSaslNegotiationException(ErrorType error, String summary) { super(summary); this.error = error; } public TSaslNegotiationException(ErrorType error, String summary, Throwable cause) { super(summary, cause); this.error = error; } public ErrorType getErrorType() { return error; } /** * @return Errory type plus the message. */ public String getSummary() { return error.name() + ": " + getMessage(); } /** * @return Summary and eventually the cause's message. */ public String getDetails() { return getCause() == null ? getSummary() : getSummary() + "\nReason: " + getCause().getMessage(); } public enum ErrorType { // Unexpected system internal error during negotiation (e.g. sasl initialization failure) INTERNAL_ERROR(NegotiationStatus.ERROR), // Cannot read correct sasl frames from the connection => Send "ERROR" status byte to peer PROTOCOL_ERROR(NegotiationStatus.ERROR), // Peer is using unsupported sasl mechanisms => Send "BAD" status byte to peer MECHANISME_MISMATCH(NegotiationStatus.BAD), // Sasl authentication failure => Send "BAD" status byte to peer AUTHENTICATION_FAILURE(NegotiationStatus.BAD), ; public final NegotiationStatus code; ErrorType(NegotiationStatus code) { this.code = code; } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/FrameWriter.java0000664000175000017500000001044515165535636031124 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import java.nio.ByteBuffer; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; /** Write frame (header and payload) to transport in a nonblocking way. */ public abstract class FrameWriter { protected ByteBuffer frameBytes; /** * Provide (maybe empty) header and payload to the frame. This can be called only when isComplete * returns true (last frame has been written out). * * @param header Some extra header bytes (without the 4 bytes for payload length), which will be * the start of the frame. It can be empty, depending on the message format * @param payload Payload as a byte array * @throws IllegalStateException if it is called when isComplete returns false * @throws IllegalArgumentException if header or payload is invalid */ public void withHeaderAndPayload(byte[] header, byte[] payload) { if (payload == null) { payload = new byte[0]; } if (header == null) { withOnlyPayload(payload); } else { withHeaderAndPayload(header, 0, header.length, payload, 0, payload.length); } } /** * Provide extra header and payload to the frame. * * @param header byte array containing the extra header * @param headerOffset starting offset of the header portition * @param headerLength length of the extra header * @param payload byte array containing the payload * @param payloadOffset starting offset of the payload portion * @param payloadLength length of the payload * @throws IllegalStateException if preivous frame is not yet complete (isComplete returns fals) * @throws IllegalArgumentException if header or payload is invalid */ public void withHeaderAndPayload( byte[] header, int headerOffset, int headerLength, byte[] payload, int payloadOffset, int payloadLength) { if (!isComplete()) { throw new IllegalStateException( "Previsous write is not yet complete, with " + frameBytes.remaining() + " bytes left."); } frameBytes = buildFrame(header, headerOffset, headerLength, payload, payloadOffset, payloadLength); } /** * Provide only payload to the frame. Throws UnsupportedOperationException if the frame expects a * header. * * @param payload payload as a byte array */ public void withOnlyPayload(byte[] payload) { withOnlyPayload(payload, 0, payload.length); } /** * Provide only payload to the frame. Throws UnsupportedOperationException if the frame expects a * header. * * @param payload The underlying byte array as a recipient of the payload * @param offset The offset in the byte array starting from where the payload is located * @param length The length of the payload */ public abstract void withOnlyPayload(byte[] payload, int offset, int length); protected abstract ByteBuffer buildFrame( byte[] header, int headerOffset, int headerLength, byte[] payload, int payloadOffset, int payloadLength); /** * Nonblocking write to the underlying transport. * * @throws TTransportException */ public void write(TNonblockingTransport transport) throws TTransportException { transport.write(frameBytes); } /** * @return true when no more data needs to be written out */ public boolean isComplete() { return frameBytes == null || !frameBytes.hasRemaining(); } /** Release the byte buffer. */ public void clear() { frameBytes = null; } } SaslNegotiationFrameWriter.java0000664000175000017500000000460215165535636034067 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.SaslNegotiationHeaderReader.PAYLOAD_LENGTH_BYTES; import static org.apache.thrift.transport.sasl.SaslNegotiationHeaderReader.STATUS_BYTES; import java.nio.ByteBuffer; import org.apache.thrift.EncodingUtils; import org.apache.thrift.utils.StringUtils; /** * Writer for sasl negotiation frames. It expect a status byte as header with a payload to be * written out (any header whose size is not equal to 1 would be considered as error). */ public class SaslNegotiationFrameWriter extends FrameWriter { public static final int HEADER_BYTES = STATUS_BYTES + PAYLOAD_LENGTH_BYTES; @Override public void withOnlyPayload(byte[] payload, int offset, int length) { throw new UnsupportedOperationException("Status byte is expected for sasl frame header."); } @Override protected ByteBuffer buildFrame( byte[] header, int headerOffset, int headerLength, byte[] payload, int payloadOffset, int payloadLength) { if (header == null || headerLength != STATUS_BYTES) { throw new IllegalArgumentException( "Header " + StringUtils.bytesToHexString(header) + " does not have expected length " + STATUS_BYTES); } byte[] bytes = new byte[HEADER_BYTES + payloadLength]; System.arraycopy(header, headerOffset, bytes, 0, STATUS_BYTES); EncodingUtils.encodeBigEndian(payloadLength, bytes, STATUS_BYTES); System.arraycopy(payload, payloadOffset, bytes, HEADER_BYTES, payloadLength); return ByteBuffer.wrap(bytes); } } TInvalidSaslFrameException.java0000664000175000017500000000212315165535636033777 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/sasl/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; /** Got an invalid frame that does not respect the thrift sasl protocol. */ public class TInvalidSaslFrameException extends TSaslNegotiationException { public TInvalidSaslFrameException(String message) { super(ErrorType.PROTOCOL_ERROR, message); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TMemoryBuffer.java0000664000175000017500000000705015165535636030457 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.charset.Charset; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TConfiguration; /** Memory buffer-based implementation of the TTransport interface. */ public class TMemoryBuffer extends TEndpointTransport { /** * Create a TMemoryBuffer with an initial buffer size of size. The internal buffer will * grow as necessary to accommodate the size of the data being written to it. * * @param size the initial size of the buffer * @throws TTransportException on error initializing the underlying transport. */ public TMemoryBuffer(int size) throws TTransportException { super(new TConfiguration()); arr_ = new TByteArrayOutputStream(size); updateKnownMessageSize(size); } /** * Create a TMemoryBuffer with an initial buffer size of size. The internal buffer will * grow as necessary to accommodate the size of the data being written to it. * * @param config the configuration to use. * @param size the initial size of the buffer * @throws TTransportException on error initializing the underlying transport. */ public TMemoryBuffer(TConfiguration config, int size) throws TTransportException { super(config); arr_ = new TByteArrayOutputStream(size); updateKnownMessageSize(size); } @Override public boolean isOpen() { return true; } @Override public void open() { /* Do nothing */ } @Override public void close() { /* Do nothing */ } @Override public int read(byte[] buf, int off, int len) throws TTransportException { checkReadBytesAvailable(len); byte[] src = arr_.get(); int amtToRead = (len > arr_.len() - pos_ ? arr_.len() - pos_ : len); if (amtToRead > 0) { System.arraycopy(src, pos_, buf, off, amtToRead); pos_ += amtToRead; } return amtToRead; } @Override public void write(byte[] buf, int off, int len) { arr_.write(buf, off, len); } /** * Output the contents of the memory buffer as a String, using the supplied encoding * * @param charset the encoding to use * @return the contents of the memory buffer as a String */ public String toString(Charset charset) { return arr_.toString(charset); } public String inspect() { StringBuilder buf = new StringBuilder(); byte[] bytes = arr_.toByteArray(); for (int i = 0; i < bytes.length; i++) { buf.append(pos_ == i ? "==>" : "").append(Integer.toHexString(bytes[i] & 0xff)).append(" "); } return buf.toString(); } // The contents of the buffer private TByteArrayOutputStream arr_; // Position to read next byte from private int pos_; public int length() { return arr_.size(); } public byte[] getArray() { return arr_.get(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TSaslClientTransport.java0000664000175000017500000000745615165535636032045 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.charset.StandardCharsets; import java.util.Map; import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; import org.apache.thrift.transport.sasl.NegotiationStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Wraps another Thrift TTransport, but performs SASL client negotiation on the call to * open(). This class will wrap ensuing communication over it, if a SASL QOP is * negotiated with the other party. */ public class TSaslClientTransport extends TSaslTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TSaslClientTransport.class); /** The name of the mechanism this client supports. */ private final String mechanism; /** * Uses the given SaslClient. * * @param saslClient The SaslClient to use for the subsequent SASL negotiation. * @param transport Transport underlying this one. */ public TSaslClientTransport(SaslClient saslClient, TTransport transport) throws TTransportException { super(saslClient, transport); mechanism = saslClient.getMechanismName(); } /** * Creates a SaslClient using the given SASL-specific parameters. See the Java * documentation for Sasl.createSaslClient for the details of the parameters. * * @param transport The underlying Thrift transport. * @throws SaslException */ public TSaslClientTransport( String mechanism, String authorizationId, String protocol, String serverName, Map props, CallbackHandler cbh, TTransport transport) throws SaslException, TTransportException { super( Sasl.createSaslClient( new String[] {mechanism}, authorizationId, protocol, serverName, props, cbh), transport); this.mechanism = mechanism; } @Override protected SaslRole getRole() { return SaslRole.CLIENT; } /** * Performs the client side of the initial portion of the Thrift SASL protocol. Generates and * sends the initial response to the server, including which mechanism this client wants to use. */ @Override protected void handleSaslStartMessage() throws TTransportException, SaslException { SaslClient saslClient = getSaslClient(); byte[] initialResponse = new byte[0]; if (saslClient.hasInitialResponse()) initialResponse = saslClient.evaluateChallenge(initialResponse); LOGGER.debug( "Sending mechanism name {} and initial response of length {}", mechanism, initialResponse.length); byte[] mechanismBytes = mechanism.getBytes(StandardCharsets.UTF_8); sendSaslMessage(NegotiationStatus.START, mechanismBytes); // Send initial response sendSaslMessage( saslClient.isComplete() ? NegotiationStatus.COMPLETE : NegotiationStatus.OK, initialResponse); underlyingTransport.flush(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TNonblockingServerTransport.java0000664000175000017500000000244715165535636033431 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.channels.Selector; /** Server transport that can be operated in a nonblocking fashion. */ public abstract class TNonblockingServerTransport extends TServerTransport { public abstract void registerSelector(Selector selector); /** * @return an incoming connection or null if there is none. * @throws TTransportException on error during this operation. */ @Override public abstract TNonblockingTransport accept() throws TTransportException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TStandardFile.java0000664000175000017500000000337615165535636030424 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; public class TStandardFile implements TSeekableFile { protected String path_ = null; protected RandomAccessFile inputFile_ = null; public TStandardFile(String path) throws IOException { path_ = path; inputFile_ = new RandomAccessFile(path_, "r"); } public InputStream getInputStream() throws IOException { return new FileInputStream(inputFile_.getFD()); } public OutputStream getOutputStream() throws IOException { return new FileOutputStream(path_); } public void close() throws IOException { if (inputFile_ != null) { inputFile_.close(); } } public long length() throws IOException { return inputFile_.length(); } public void seek(long pos) throws IOException { inputFile_.seek(pos); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TMemoryTransport.java0000664000175000017500000000514115165535636031241 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.ByteBuffer; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TConfiguration; /** In memory transport with separate buffers for input and output. */ public class TMemoryTransport extends TEndpointTransport { private final ByteBuffer inputBuffer; private final TByteArrayOutputStream outputBuffer; public TMemoryTransport(byte[] input) throws TTransportException { super(new TConfiguration()); inputBuffer = ByteBuffer.wrap(input); outputBuffer = new TByteArrayOutputStream(1024); updateKnownMessageSize(input.length); } public TMemoryTransport(TConfiguration config, byte[] input) throws TTransportException { super(config); inputBuffer = ByteBuffer.wrap(input); outputBuffer = new TByteArrayOutputStream(1024); updateKnownMessageSize(input.length); } @Override public boolean isOpen() { return true; } /** Opening on an in memory transport should have no effect. */ @Override public void open() { // Do nothing. } @Override public void close() { // Do nothing. } @Override public int read(byte[] buf, int off, int len) throws TTransportException { checkReadBytesAvailable(len); int remaining = inputBuffer.remaining(); if (remaining < len) { throw new TTransportException( TTransportException.END_OF_FILE, "There's only " + remaining + "bytes, but it asks for " + len); } inputBuffer.get(buf, off, len); return len; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { outputBuffer.write(buf, off, len); } /** * Get all the bytes written by thrift output protocol. * * @return a byte array. */ public TByteArrayOutputStream getOutput() { return outputBuffer; } } AutoExpandingBufferWriteTransport.java0000664000175000017500000000566215165535636034511 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TConfiguration; /** TTransport for writing to an AutoExpandingBuffer. */ public final class AutoExpandingBufferWriteTransport extends TEndpointTransport { private final AutoExpandingBuffer buf; private int pos; private int res; /** * Constructor. * * @param config the configuration to use. Currently used for defining the maximum message size. * @param initialCapacity the initial capacity of the buffer * @param frontReserve space, if any, to reserve at the beginning such that the first write is * after this reserve. This allows framed transport to reserve space for the frame buffer * length. * @throws IllegalArgumentException if initialCapacity is less than one * @throws IllegalArgumentException if frontReserve is less than zero * @throws IllegalArgumentException if frontReserve is greater than initialCapacity */ public AutoExpandingBufferWriteTransport( TConfiguration config, int initialCapacity, int frontReserve) throws TTransportException { super(config); if (initialCapacity < 1) { throw new IllegalArgumentException("initialCapacity"); } if (frontReserve < 0 || initialCapacity < frontReserve) { throw new IllegalArgumentException("frontReserve"); } this.buf = new AutoExpandingBuffer(initialCapacity); this.pos = frontReserve; this.res = frontReserve; } @Override public void close() {} @Override public boolean isOpen() { return true; } @Override public void open() throws TTransportException {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { throw new UnsupportedOperationException(); } @Override public void write(byte[] toWrite, int off, int len) throws TTransportException { buf.resizeIfNecessary(pos + len); System.arraycopy(toWrite, off, buf.array(), pos, len); pos += len; } public AutoExpandingBuffer getBuf() { return buf; } /** * @return length of the buffer, including any front reserve */ public int getLength() { return pos; } public void reset() { pos = res; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TIOStreamTransport.java0000664000175000017500000001431715165535636031461 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.SocketTimeoutException; import org.apache.thrift.TConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This is the most commonly used base transport. It takes an InputStream or an OutputStream or both * and uses it/them to perform transport operations. This allows for compatibility with all the nice * constructs Java already has to provide a variety of types of streams. */ public class TIOStreamTransport extends TEndpointTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TIOStreamTransport.class.getName()); /** Underlying inputStream */ protected InputStream inputStream_ = null; /** Underlying outputStream */ protected OutputStream outputStream_ = null; /** * Subclasses can invoke the default constructor and then assign the input streams in the open * method. */ protected TIOStreamTransport(TConfiguration config) throws TTransportException { super(config); } /** * Subclasses can invoke the default constructor and then assign the input streams in the open * method. */ protected TIOStreamTransport() throws TTransportException { super(new TConfiguration()); } /** * Input stream constructor, constructs an input only transport. * * @param config * @param is Input stream to read from */ public TIOStreamTransport(TConfiguration config, InputStream is) throws TTransportException { super(config); inputStream_ = is; } /** * Input stream constructor, constructs an input only transport. * * @param is Input stream to read from */ public TIOStreamTransport(InputStream is) throws TTransportException { super(new TConfiguration()); inputStream_ = is; } /** * Output stream constructor, constructs an output only transport. * * @param config * @param os Output stream to write to */ public TIOStreamTransport(TConfiguration config, OutputStream os) throws TTransportException { super(config); outputStream_ = os; } /** * Output stream constructor, constructs an output only transport. * * @param os Output stream to write to */ public TIOStreamTransport(OutputStream os) throws TTransportException { super(new TConfiguration()); outputStream_ = os; } /** * Two-way stream constructor. * * @param config * @param is Input stream to read from * @param os Output stream to read from */ public TIOStreamTransport(TConfiguration config, InputStream is, OutputStream os) throws TTransportException { super(config); inputStream_ = is; outputStream_ = os; } /** * Two-way stream constructor. * * @param is Input stream to read from * @param os Output stream to read from */ public TIOStreamTransport(InputStream is, OutputStream os) throws TTransportException { super(new TConfiguration()); inputStream_ = is; outputStream_ = os; } /** * @return false after close is called. */ public boolean isOpen() { return inputStream_ != null || outputStream_ != null; } /** The streams must already be open. This method does nothing. */ public void open() throws TTransportException {} /** Closes both the input and output streams. */ public void close() { try { if (inputStream_ != null) { try { inputStream_.close(); } catch (IOException iox) { LOGGER.warn("Error closing input stream.", iox); } } if (outputStream_ != null) { try { outputStream_.close(); } catch (IOException iox) { LOGGER.warn("Error closing output stream.", iox); } } } finally { inputStream_ = null; outputStream_ = null; } } /** Reads from the underlying input stream if not null. */ public int read(byte[] buf, int off, int len) throws TTransportException { if (inputStream_ == null) { throw new TTransportException( TTransportException.NOT_OPEN, "Cannot read from null inputStream"); } int bytesRead; try { bytesRead = inputStream_.read(buf, off, len); } catch (SocketTimeoutException ste) { throw new TTransportException(TTransportException.TIMED_OUT, ste); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } if (bytesRead < 0) { throw new TTransportException(TTransportException.END_OF_FILE, "Socket is closed by peer."); } return bytesRead; } /** Writes to the underlying output stream if not null. */ public void write(byte[] buf, int off, int len) throws TTransportException { if (outputStream_ == null) { throw new TTransportException( TTransportException.NOT_OPEN, "Cannot write to null outputStream"); } try { outputStream_.write(buf, off, len); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** Flushes the underlying output stream if not null. */ public void flush() throws TTransportException { if (outputStream_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot flush null outputStream"); } try { outputStream_.flush(); resetConsumedMessageSize(-1); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TServerTransport.java0000664000175000017500000000567515167543515031250 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.Closeable; import java.net.InetSocketAddress; import org.apache.thrift.TConfiguration; /** Server transport. Object which provides client transports. */ public abstract class TServerTransport implements Closeable { public abstract static class AbstractServerTransportArgs< T extends AbstractServerTransportArgs> { int backlog = 0; // A value of 0 means the default value will be used (currently set at 50) int clientTimeout = 0; InetSocketAddress bindAddr; int maxFrameSize = TConfiguration.DEFAULT_MAX_FRAME_SIZE; int maxMessageSize = TConfiguration.DEFAULT_MAX_MESSAGE_SIZE; public T backlog(int backlog) { this.backlog = backlog; return (T) this; } public T clientTimeout(int clientTimeout) { this.clientTimeout = clientTimeout; return (T) this; } public T port(int port) { this.bindAddr = new InetSocketAddress(port); return (T) this; } public T bindAddr(InetSocketAddress bindAddr) { this.bindAddr = bindAddr; return (T) this; } public T maxFrameSize(int maxFrameSize) { this.maxFrameSize = maxFrameSize; return (T) this; } public T maxMessageSize(int maxMessageSize) { this.maxMessageSize = maxMessageSize; return (T) this; } } public abstract void listen() throws TTransportException; /** * Accept incoming connection on the server socket. When there is no incoming connection * available: either it should block infinitely in a blocking implementation, either it should * return null in a nonblocking implementation. * * @return new connection * @throws TTransportException if IO error. */ public abstract TTransport accept() throws TTransportException; public abstract void close(); /** * Optional method implementation. This signals to the server transport that it should break out * of any accept() or listen() that it is currently blocked on. This method, if implemented, MUST * be thread safe, as it may be called from a different thread context than the other * TServerTransport methods. */ public void interrupt() {} } AutoExpandingBufferReadTransport.java0000664000175000017500000000462715165535636034272 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TConfiguration; /** TTransport for reading from an AutoExpandingBuffer. */ public class AutoExpandingBufferReadTransport extends TEndpointTransport { private final AutoExpandingBuffer buf; private int pos = 0; private int limit = 0; public AutoExpandingBufferReadTransport(TConfiguration config, int initialCapacity) throws TTransportException { super(config); this.buf = new AutoExpandingBuffer(initialCapacity); } public void fill(TTransport inTrans, int length) throws TTransportException { buf.resizeIfNecessary(length); inTrans.readAll(buf.array(), 0, length); pos = 0; limit = length; } @Override public void close() {} @Override public boolean isOpen() { return true; } @Override public void open() throws TTransportException {} @Override public final int read(byte[] target, int off, int len) throws TTransportException { int amtToRead = Math.min(len, getBytesRemainingInBuffer()); if (amtToRead > 0) { System.arraycopy(buf.array(), pos, target, off, amtToRead); consumeBuffer(amtToRead); } return amtToRead; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { throw new UnsupportedOperationException(); } @Override public final void consumeBuffer(int len) { pos += len; } @Override public final byte[] getBuffer() { return buf.array(); } @Override public final int getBufferPosition() { return pos; } @Override public final int getBytesRemainingInBuffer() { return limit - pos; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TSimpleFileTransport.java0000664000175000017500000001500115165535636032016 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.io.RandomAccessFile; import org.apache.thrift.TConfiguration; /** Basic file support for the TTransport interface */ public final class TSimpleFileTransport extends TEndpointTransport { private RandomAccessFile file = null; private final boolean readable; private final boolean writable; private final String path_; /** * Create a transport backed by a simple file * * @param path the path to the file to open/create * @param read true to support read operations * @param write true to support write operations * @param openFile true to open the file on construction * @throws TTransportException if file open fails */ public TSimpleFileTransport(String path, boolean read, boolean write, boolean openFile) throws TTransportException { this(new TConfiguration(), path, read, write, openFile); } /** * Create a transport backed by a simple file * * @param config * @param path the path to the file to open/create * @param read true to support read operations * @param write true to support write operations * @param openFile true to open the file on construction * @throws TTransportException if file open fails */ public TSimpleFileTransport( TConfiguration config, String path, boolean read, boolean write, boolean openFile) throws TTransportException { super(config); if (path.length() <= 0) { throw new TTransportException("No path specified"); } if (!read && !write) { throw new TTransportException("Neither READ nor WRITE specified"); } readable = read; writable = write; path_ = path; if (openFile) { open(); } } /** * Create a transport backed by a simple file Implicitly opens file to conform to C++ behavior. * * @param path the path to the file to open/create * @param read true to support read operations * @param write true to support write operations * @throws TTransportException if file open fails */ public TSimpleFileTransport(String path, boolean read, boolean write) throws TTransportException { this(path, read, write, true); } /** * Create a transport backed by a simple read only disk file (implicitly opens file) * * @param path the path to the file to open/create * @throws TTransportException if file open fails */ public TSimpleFileTransport(String path) throws TTransportException { this(path, true, false, true); } /** * Test file status * * @return true if open, otherwise false */ @Override public boolean isOpen() { return (file != null); } /** * Open file if not previously opened. * * @throws TTransportException if open fails */ @Override public void open() throws TTransportException { if (file == null) { try { String access = "r"; // RandomAccessFile objects must be readable if (writable) { access += "w"; } file = new RandomAccessFile(path_, access); } catch (IOException ioe) { file = null; throw new TTransportException(ioe.getMessage()); } } } /** Close file, subsequent read/write activity will throw exceptions */ @Override public void close() { if (file != null) { try { file.close(); } catch (Exception e) { // Nothing to do } file = null; } } /** * Read up to len many bytes into buf at offset * * @param buf houses bytes read * @param off offset into buff to begin writing to * @param len maximum number of bytes to read * @return number of bytes actually read * @throws TTransportException on read failure */ @Override public int read(byte[] buf, int off, int len) throws TTransportException { if (!readable) { throw new TTransportException("Read operation on write only file"); } checkReadBytesAvailable(len); int iBytesRead = 0; try { iBytesRead = file.read(buf, off, len); } catch (IOException ioe) { file = null; throw new TTransportException(ioe.getMessage()); } return iBytesRead; } /** * Write len many bytes from buff starting at offset * * @param buf buffer containing bytes to write * @param off offset into buffer to begin writing from * @param len number of bytes to write * @throws TTransportException on write failure */ @Override public void write(byte[] buf, int off, int len) throws TTransportException { try { file.write(buf, off, len); } catch (IOException ioe) { file = null; throw new TTransportException(ioe.getMessage()); } } /** * Move file pointer to specified offset, new read/write calls will act here * * @param offset bytes from beginning of file to move pointer to * @throws TTransportException is seek fails */ public void seek(long offset) throws TTransportException { try { file.seek(offset); } catch (IOException ex) { throw new TTransportException(ex.getMessage()); } } /** * Return the length of the file in bytes * * @return length of the file in bytes * @throws TTransportException if file access fails */ public long length() throws TTransportException { try { return file.length(); } catch (IOException ex) { throw new TTransportException(ex.getMessage()); } } /** * Return current file pointer position in bytes from beginning of file * * @return file pointer position * @throws TTransportException if file access fails */ public long getFilePointer() throws TTransportException { try { return file.getFilePointer(); } catch (IOException ex) { throw new TTransportException(ex.getMessage()); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TEndpointTransport.java0000664000175000017500000000734715167543515031560 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.util.Objects; import org.apache.thrift.TConfiguration; public abstract class TEndpointTransport extends TTransport { protected long getMaxMessageSize() { return getConfiguration().getMaxMessageSize(); } public int getMaxFrameSize() { return getConfiguration().getMaxFrameSize(); } public void setMaxFrameSize(int maxFrameSize) { getConfiguration().setMaxFrameSize(maxFrameSize); } public void setMaxMessageSize(int maxMessageSize) { getConfiguration().setMaxMessageSize(maxMessageSize); } protected long knownMessageSize; protected long remainingMessageSize; private TConfiguration _configuration; public TConfiguration getConfiguration() { return _configuration; } public TEndpointTransport(TConfiguration config) throws TTransportException { _configuration = Objects.isNull(config) ? new TConfiguration() : config; resetConsumedMessageSize(-1); } /** * Resets RemainingMessageSize to the configured maximum * * @param newSize */ protected void resetConsumedMessageSize(long newSize) throws TTransportException { // full reset if (newSize < 0) { knownMessageSize = getMaxMessageSize(); remainingMessageSize = getMaxMessageSize(); return; } // update only: message size can shrink, but not grow if (newSize > knownMessageSize) throw new TTransportException( TTransportException.MESSAGE_SIZE_LIMIT, "Message size exceeds limit: " + getMaxMessageSize()); knownMessageSize = newSize; remainingMessageSize = newSize; } /** * Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport). * Will throw if we already consumed too many bytes or if the new size is larger than allowed. * * @param size */ public void updateKnownMessageSize(long size) throws TTransportException { long consumed = knownMessageSize - remainingMessageSize; resetConsumedMessageSize(size == 0 ? -1 : size); countConsumedMessageBytes(consumed); } /** * Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of * data * * @param numBytes */ public void checkReadBytesAvailable(long numBytes) throws TTransportException { if (remainingMessageSize < numBytes || numBytes < 0) throw new TTransportException( TTransportException.MESSAGE_SIZE_LIMIT, "Message size exceeds limit: " + getMaxMessageSize()); } /** * Consumes numBytes from the RemainingMessageSize. * * @param numBytes */ protected void countConsumedMessageBytes(long numBytes) throws TTransportException { if (remainingMessageSize >= numBytes) { remainingMessageSize -= numBytes; } else { remainingMessageSize = 0; throw new TTransportException( TTransportException.MESSAGE_SIZE_LIMIT, "Message size exceeds limit: " + getMaxMessageSize()); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TTransport.java0000664000175000017500000001513715165535636030056 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.Closeable; import java.nio.ByteBuffer; import org.apache.thrift.TConfiguration; /** * Generic class that encapsulates the I/O layer. This is basically a thin wrapper around the * combined functionality of Java input/output streams. */ public abstract class TTransport implements Closeable { /** * Queries whether the transport is open. * * @return True if the transport is open. */ public abstract boolean isOpen(); /** * Is there more data to be read? * * @return True if the remote side is still alive and feeding us */ public boolean peek() { return isOpen(); } /** * Opens the transport for reading/writing. * * @throws TTransportException if the transport could not be opened */ public abstract void open() throws TTransportException; /** Closes the transport. */ public abstract void close(); /** * Reads a sequence of bytes from this channel into the given buffer. An attempt is made to read * up to the number of bytes remaining in the buffer, that is, dst.remaining(), at the moment this * method is invoked. Upon return the buffer's position will move forward the number of bytes * read; its limit will not have changed. Subclasses are encouraged to provide a more efficient * implementation of this method. * * @param dst The buffer into which bytes are to be transferred * @return The number of bytes read, possibly zero, or -1 if the channel has reached end-of-stream * @throws TTransportException if there was an error reading data */ public int read(ByteBuffer dst) throws TTransportException { byte[] arr = new byte[dst.remaining()]; int n = read(arr, 0, arr.length); dst.put(arr, 0, n); return n; } /** * Reads up to len bytes into buffer buf, starting at offset off. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read * @throws TTransportException if there was an error reading data */ public abstract int read(byte[] buf, int off, int len) throws TTransportException; /** * Guarantees that all of len bytes are actually read off the transport. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read, which must be equal to len * @throws TTransportException if there was an error reading data */ public int readAll(byte[] buf, int off, int len) throws TTransportException { int got = 0; int ret = 0; while (got < len) { ret = read(buf, off + got, len - got); if (ret <= 0) { throw new TTransportException( "Cannot read. Remote side has closed. Tried to read " + len + " bytes, but only got " + got + " bytes. (This is often indicative of an internal error on the server side. Please check your server logs.)"); } got += ret; } return got; } /** * Writes the buffer to the output * * @param buf The output data buffer * @throws TTransportException if an error occurs writing data */ public void write(byte[] buf) throws TTransportException { write(buf, 0, buf.length); } /** * Writes up to len bytes from the buffer. * * @param buf The output data buffer * @param off The offset to start writing from * @param len The number of bytes to write * @throws TTransportException if there was an error writing data */ public abstract void write(byte[] buf, int off, int len) throws TTransportException; /** * Writes a sequence of bytes to the buffer. An attempt is made to write all remaining bytes in * the buffer, that is, src.remaining(), at the moment this method is invoked. Upon return the * buffer's position will updated; its limit will not have changed. Subclasses are encouraged to * provide a more efficient implementation of this method. * * @param src The buffer from which bytes are to be retrieved * @return The number of bytes written, possibly zero * @throws TTransportException if there was an error writing data */ public int write(ByteBuffer src) throws TTransportException { byte[] arr = new byte[src.remaining()]; src.get(arr); write(arr, 0, arr.length); return arr.length; } /** * Flush any pending data out of a transport buffer. * * @throws TTransportException if there was an error writing out data. */ public void flush() throws TTransportException {} /** * Access the protocol's underlying buffer directly. If this is not a buffered transport, return * null. * * @return protocol's Underlying buffer */ public byte[] getBuffer() { return null; } /** * Return the index within the underlying buffer that specifies the next spot that should be read * from. * * @return index within the underlying buffer that specifies the next spot that should be read * from */ public int getBufferPosition() { return 0; } /** * Get the number of bytes remaining in the underlying buffer. Returns -1 if this is a * non-buffered transport. * * @return the number of bytes remaining in the underlying buffer.
* Returns -1 if this is a non-buffered transport. */ public int getBytesRemainingInBuffer() { return -1; } /** * Consume len bytes from the underlying buffer. * * @param len the number of bytes to consume from the underlying buffer. */ public void consumeBuffer(int len) {} public abstract TConfiguration getConfiguration(); public abstract void updateKnownMessageSize(long size) throws TTransportException; public abstract void checkReadBytesAvailable(long numBytes) throws TTransportException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TFileTransport.java0000664000175000017500000004061715165535636030657 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Random; import org.apache.thrift.TConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * FileTransport implementation of the TTransport interface. Currently this is a straightforward * port of the cpp implementation * *

It may make better sense to provide a basic stream access on top of the framed file format The * FileTransport can then be a user of this framed file format with some additional logic for * chunking. */ public class TFileTransport extends TTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TFileTransport.class.getName()); public static class TruncableBufferedInputStream extends BufferedInputStream { public void trunc() { pos = count = 0; } public TruncableBufferedInputStream(InputStream in) { super(in); } public TruncableBufferedInputStream(InputStream in, int size) { super(in, size); } } public static class Event { private byte[] buf_; private int nread_; private int navailable_; /** * Initialize an event. Initially, it has no valid contents * * @param buf byte array buffer to store event */ public Event(byte[] buf) { buf_ = buf; nread_ = navailable_ = 0; } public byte[] getBuf() { return buf_; } public int getSize() { return buf_.length; } public void setAvailable(int sz) { nread_ = 0; navailable_ = sz; } public int getRemaining() { return (navailable_ - nread_); } public int emit(byte[] buf, int offset, int ndesired) { if ((ndesired == 0) || (ndesired > getRemaining())) ndesired = getRemaining(); if (ndesired <= 0) return (ndesired); System.arraycopy(buf_, nread_, buf, offset, ndesired); nread_ += ndesired; return (ndesired); } } public static class ChunkState { /** Chunk Size. Must be same across all implementations */ public static final int DEFAULT_CHUNK_SIZE = 16 * 1024 * 1024; private int chunk_size_ = DEFAULT_CHUNK_SIZE; private long offset_ = 0; public ChunkState() {} public ChunkState(int chunk_size) { chunk_size_ = chunk_size; } public void skip(int size) { offset_ += size; } public void seek(long offset) { offset_ = offset; } public int getChunkSize() { return chunk_size_; } public int getChunkNum() { return ((int) (offset_ / chunk_size_)); } public int getRemaining() { return (chunk_size_ - ((int) (offset_ % chunk_size_))); } public long getOffset() { return (offset_); } } public enum TailPolicy { NOWAIT(0, 0), WAIT_FOREVER(500, -1); /** Time in milliseconds to sleep before next read If 0, no sleep */ public final int timeout_; /** Number of retries before giving up if 0, no retries if -1, retry forever */ public final int retries_; /** * ctor for policy * * @param timeout sleep time for this particular policy * @param retries number of retries */ TailPolicy(int timeout, int retries) { timeout_ = timeout; retries_ = retries; } } /** Current tailing policy */ TailPolicy currentPolicy_ = TailPolicy.NOWAIT; /** Underlying file being read */ protected TSeekableFile inputFile_ = null; /** Underlying outputStream */ protected OutputStream outputStream_ = null; /** Event currently read in */ Event currentEvent_ = null; /** InputStream currently being used for reading */ InputStream inputStream_ = null; /** current Chunk state */ ChunkState cs = null; /** is read only? */ private boolean readOnly_ = false; /** * Get File Tailing Policy * * @return current read policy */ public TailPolicy getTailPolicy() { return (currentPolicy_); } /** * Set file Tailing Policy * * @param policy New policy to set * @return Old policy */ public TailPolicy setTailPolicy(TailPolicy policy) { TailPolicy old = currentPolicy_; currentPolicy_ = policy; return (old); } /** * Initialize read input stream * * @return input stream to read from file */ private InputStream createInputStream() throws TTransportException { InputStream is; try { if (inputStream_ != null) { ((TruncableBufferedInputStream) inputStream_).trunc(); is = inputStream_; } else { is = new TruncableBufferedInputStream(inputFile_.getInputStream()); } } catch (IOException iox) { throw new TTransportException(iox.getMessage(), iox); } return (is); } /** * Read (potentially tailing) an input stream * * @param is InputStream to read from * @param buf Buffer to read into * @param off Offset in buffer to read into * @param len Number of bytes to read * @param tp policy to use if we hit EOF * @return number of bytes read */ private int tailRead(InputStream is, byte[] buf, int off, int len, TailPolicy tp) throws TTransportException { int orig_len = len; try { int retries = 0; while (len > 0) { int cnt = is.read(buf, off, len); if (cnt > 0) { off += cnt; len -= cnt; retries = 0; cs.skip(cnt); // remember that we read so many bytes } else if (cnt == -1) { // EOF retries++; if ((tp.retries_ != -1) && tp.retries_ < retries) return (orig_len - len); if (tp.timeout_ > 0) { try { Thread.sleep(tp.timeout_); } catch (InterruptedException e) { } } } else { // either non-zero or -1 is what the contract says! throw new TTransportException("Unexpected return from InputStream.read = " + cnt); } } } catch (IOException iox) { throw new TTransportException(iox.getMessage(), iox); } return (orig_len - len); } /** * Event is corrupted. Do recovery * * @return true if recovery could be performed and we can read more data false is returned only * when nothing more can be read */ private boolean performRecovery() throws TTransportException { int numChunks = getNumChunks(); int curChunk = cs.getChunkNum(); if (curChunk >= (numChunks - 1)) { return false; } seekToChunk(curChunk + 1); return true; } /** * Read event from underlying file * * @return true if event could be read, false otherwise (on EOF) */ private boolean readEvent() throws TTransportException { byte[] ebytes = new byte[4]; int esize; int nread; int nrequested; retry: do { // corner case. read to end of chunk nrequested = cs.getRemaining(); if (nrequested < 4) { nread = tailRead(inputStream_, ebytes, 0, nrequested, currentPolicy_); if (nread != nrequested) { return (false); } } // assuming serialized on little endian machine nread = tailRead(inputStream_, ebytes, 0, 4, currentPolicy_); if (nread != 4) { return (false); } esize = 0; for (int i = 3; i >= 0; i--) { int val = (0x000000ff & (int) ebytes[i]); esize |= (val << (i * 8)); } // check if event is corrupted and do recovery as required if (esize > cs.getRemaining()) { throw new TTransportException("FileTransport error: bad event size"); /* if(performRecovery()) { esize=0; } else { return false; } */ } } while (esize == 0); // reset existing event or get a larger one if (currentEvent_.getSize() < esize) currentEvent_ = new Event(new byte[esize]); // populate the event byte[] buf = currentEvent_.getBuf(); nread = tailRead(inputStream_, buf, 0, esize, currentPolicy_); if (nread != esize) { return (false); } currentEvent_.setAvailable(esize); return (true); } /** * open if both input/output open unless readonly * * @return true */ public boolean isOpen() { return ((inputStream_ != null) && (readOnly_ || (outputStream_ != null))); } /** * Diverging from the cpp model and sticking to the TSocket model Files are not opened in ctor - * but in explicit open call */ public void open() throws TTransportException { if (isOpen()) throw new TTransportException(TTransportException.ALREADY_OPEN); try { inputStream_ = createInputStream(); cs = new ChunkState(); currentEvent_ = new Event(new byte[256]); if (!readOnly_) outputStream_ = new BufferedOutputStream(inputFile_.getOutputStream()); } catch (IOException iox) { throw new TTransportException(TTransportException.NOT_OPEN, iox); } } /** Closes the transport. */ public void close() { if (inputFile_ != null) { try { inputFile_.close(); } catch (IOException iox) { LOGGER.warn("WARNING: Error closing input file: " + iox.getMessage()); } inputFile_ = null; } if (outputStream_ != null) { try { outputStream_.close(); } catch (IOException iox) { LOGGER.warn("WARNING: Error closing output stream: " + iox.getMessage()); } outputStream_ = null; } } /** * File Transport ctor * * @param path File path to read and write from * @param readOnly Whether this is a read-only transport * @throws IOException if there is an error accessing the file. */ public TFileTransport(final String path, boolean readOnly) throws IOException { inputFile_ = new TStandardFile(path); readOnly_ = readOnly; } /** * File Transport ctor * * @param inputFile open TSeekableFile to read/write from * @param readOnly Whether this is a read-only transport */ public TFileTransport(TSeekableFile inputFile, boolean readOnly) { inputFile_ = inputFile; readOnly_ = readOnly; } /** * Cloned from TTransport.java:readAll(). Only difference is throwing an EOF exception where one * is detected. */ public int readAll(byte[] buf, int off, int len) throws TTransportException { int got = 0; int ret = 0; while (got < len) { ret = read(buf, off + got, len - got); if (ret < 0) { throw new TTransportException("Error in reading from file"); } if (ret == 0) { throw new TTransportException(TTransportException.END_OF_FILE, "End of File reached"); } got += ret; } return got; } /** * Reads up to len bytes into buffer buf, starting at offset off. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read * @throws TTransportException if there was an error reading data */ public int read(byte[] buf, int off, int len) throws TTransportException { if (!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before reading"); if (currentEvent_.getRemaining() == 0 && !readEvent()) { return 0; } return currentEvent_.emit(buf, off, len); } public int getNumChunks() throws TTransportException { if (!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before getNumChunks"); try { long len = inputFile_.length(); if (len == 0) return 0; else return (((int) (len / cs.getChunkSize())) + 1); } catch (IOException iox) { throw new TTransportException(iox.getMessage(), iox); } } public int getCurChunk() throws TTransportException { if (!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before getCurChunk"); return (cs.getChunkNum()); } public void seekToChunk(int chunk) throws TTransportException { if (!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before seeking"); int numChunks = getNumChunks(); // file is empty, seeking to chunk is pointless if (numChunks == 0) { return; } // negative indicates reverse seek (from the end) if (chunk < 0) { chunk += numChunks; } // too large a value for reverse seek, just seek to beginning if (chunk < 0) { chunk = 0; } long eofOffset = 0; boolean seekToEnd = (chunk >= numChunks); if (seekToEnd) { chunk = chunk - 1; try { eofOffset = inputFile_.length(); } catch (IOException iox) { throw new TTransportException(iox.getMessage(), iox); } } if (chunk * cs.getChunkSize() != cs.getOffset()) { try { inputFile_.seek((long) chunk * cs.getChunkSize()); } catch (IOException iox) { throw new TTransportException("Seek to chunk " + chunk + " " + iox.getMessage(), iox); } cs.seek((long) chunk * cs.getChunkSize()); currentEvent_.setAvailable(0); inputStream_ = createInputStream(); } if (seekToEnd) { // waiting forever here - otherwise we can hit EOF and end up // having consumed partial data from the data stream. TailPolicy old = setTailPolicy(TailPolicy.WAIT_FOREVER); while (cs.getOffset() < eofOffset) { readEvent(); } currentEvent_.setAvailable(0); setTailPolicy(old); } } public void seekToEnd() throws TTransportException { if (!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before seeking"); seekToChunk(getNumChunks()); } /** * Writes up to len bytes from the buffer. * * @param buf The output data buffer * @param off The offset to start writing from * @param len The number of bytes to write * @throws TTransportException if there was an error writing data */ public void write(byte[] buf, int off, int len) throws TTransportException { throw new TTransportException("Not Supported"); } /** * Flush any pending data out of a transport buffer. * * @throws TTransportException if there was an error writing out data. */ public void flush() throws TTransportException { throw new TTransportException("Not Supported"); } @Override public TConfiguration getConfiguration() { return null; } @Override public void updateKnownMessageSize(long size) throws TTransportException {} @Override public void checkReadBytesAvailable(long numBytes) throws TTransportException {} /** test program */ public static void main(String[] args) throws Exception { int num_chunks = 10; if ((args.length < 1) || args[0].equals("--help") || args[0].equals("-h") || args[0].equals("-?")) { printUsage(); } if (args.length > 1) { try { num_chunks = Integer.parseInt(args[1]); } catch (Exception e) { LOGGER.error("Cannot parse " + args[1]); printUsage(); } } TFileTransport t = new TFileTransport(args[0], true); t.open(); LOGGER.info("NumChunks=" + t.getNumChunks()); Random r = new Random(); for (int j = 0; j < num_chunks; j++) { byte[] buf = new byte[4096]; int cnum = r.nextInt(t.getNumChunks() - 1); LOGGER.info("Reading chunk " + cnum); t.seekToChunk(cnum); for (int i = 0; i < 4096; i++) { t.read(buf, 0, 4096); } } } private static void printUsage() { LOGGER.error("Usage: TFileTransport [num_chunks]"); LOGGER.error(" (Opens and reads num_chunks chunks from file randomly)"); System.exit(1); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TNonblockingServerSocket.java0000664000175000017500000001414315167543515032656 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.SocketException; import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import org.apache.thrift.TConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Wrapper around ServerSocketChannel */ public class TNonblockingServerSocket extends TNonblockingServerTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TNonblockingServerSocket.class.getName()); /** This channel is where all the nonblocking magic happens. */ private ServerSocketChannel serverSocketChannel = null; /** Underlying ServerSocket object */ private ServerSocket serverSocket_ = null; /** Timeout for client sockets from accept */ private int clientTimeout_ = 0; /** Limit for client sockets request size */ private int maxFrameSize_ = 0; /** Max message size */ private int maxMessageSize_ = 0; public static class NonblockingAbstractServerSocketArgs extends AbstractServerTransportArgs {} /** Creates just a port listening server socket */ public TNonblockingServerSocket(int port) throws TTransportException { this(port, 0); } /** Creates just a port listening server socket */ public TNonblockingServerSocket(int port, int clientTimeout) throws TTransportException { this(port, clientTimeout, TConfiguration.DEFAULT_MAX_FRAME_SIZE); } public TNonblockingServerSocket(int port, int clientTimeout, int maxFrameSize) throws TTransportException { this( new NonblockingAbstractServerSocketArgs() .port(port) .clientTimeout(clientTimeout) .maxFrameSize(maxFrameSize)); } public TNonblockingServerSocket(InetSocketAddress bindAddr) throws TTransportException { this(bindAddr, 0); } public TNonblockingServerSocket(InetSocketAddress bindAddr, int clientTimeout) throws TTransportException { this(bindAddr, clientTimeout, TConfiguration.DEFAULT_MAX_FRAME_SIZE); } public TNonblockingServerSocket(InetSocketAddress bindAddr, int clientTimeout, int maxFrameSize) throws TTransportException { this( new NonblockingAbstractServerSocketArgs() .bindAddr(bindAddr) .clientTimeout(clientTimeout) .maxFrameSize(maxFrameSize)); } public TNonblockingServerSocket(NonblockingAbstractServerSocketArgs args) throws TTransportException { clientTimeout_ = args.clientTimeout; maxFrameSize_ = args.maxFrameSize; maxMessageSize_ = args.maxMessageSize; try { serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); // Make server socket serverSocket_ = serverSocketChannel.socket(); // Prevent 2MSL delay problem on server restarts serverSocket_.setReuseAddress(true); // Bind to listening port serverSocket_.bind(args.bindAddr, args.backlog); } catch (IOException ioe) { serverSocket_ = null; throw new TTransportException( "Could not create ServerSocket on address " + args.bindAddr.toString() + ".", ioe); } } public void listen() throws TTransportException { // Make sure not to block on accept if (serverSocket_ != null) { try { serverSocket_.setSoTimeout(0); } catch (SocketException sx) { LOGGER.error("Socket exception while setting socket timeout", sx); } } } @Override public TNonblockingSocket accept() throws TTransportException { if (serverSocket_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "No underlying server socket."); } try { SocketChannel socketChannel = serverSocketChannel.accept(); if (socketChannel == null) { return null; } TNonblockingSocket tsocket = new TNonblockingSocket(socketChannel); tsocket.setTimeout(clientTimeout_); tsocket.setMaxFrameSize(maxFrameSize_); tsocket.setMaxMessageSize(maxMessageSize_); return tsocket; } catch (IOException iox) { throw new TTransportException(iox); } } public void registerSelector(Selector selector) { try { // Register the server socket channel, indicating an interest in // accepting new connections serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } catch (ClosedChannelException e) { // this shouldn't happen, ideally... // TODO: decide what to do with this. } } public void close() { if (serverSocket_ != null) { try { serverSocket_.close(); } catch (IOException iox) { LOGGER.warn("WARNING: Could not close server socket: " + iox.getMessage()); } serverSocket_ = null; } } public void interrupt() { // The thread-safeness of this is dubious, but Java documentation suggests // that it is safe to do this from a different thread context close(); } public int getPort() { if (serverSocket_ == null) return -1; return serverSocket_.getLocalPort(); } // Expose it for test purpose. ServerSocketChannel getServerSocketChannel() { return serverSocketChannel; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/transport/TFileProcessor.java0000664000175000017500000000775315165535636030646 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; /** * FileProcessor: helps in processing files generated by TFileTransport. Port of original cpp * implementation */ public class TFileProcessor { private TProcessor processor_; private TProtocolFactory inputProtocolFactory_; private TProtocolFactory outputProtocolFactory_; private TFileTransport inputTransport_; private TTransport outputTransport_; public TFileProcessor( TProcessor processor, TProtocolFactory protocolFactory, TFileTransport inputTransport, TTransport outputTransport) { processor_ = processor; inputProtocolFactory_ = outputProtocolFactory_ = protocolFactory; inputTransport_ = inputTransport; outputTransport_ = outputTransport; } public TFileProcessor( TProcessor processor, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TFileTransport inputTransport, TTransport outputTransport) { processor_ = processor; inputProtocolFactory_ = inputProtocolFactory; outputProtocolFactory_ = outputProtocolFactory; inputTransport_ = inputTransport; outputTransport_ = outputTransport; } private void processUntil(int lastChunk) throws TException { TProtocol ip = inputProtocolFactory_.getProtocol(inputTransport_); TProtocol op = outputProtocolFactory_.getProtocol(outputTransport_); int curChunk = inputTransport_.getCurChunk(); try { while (lastChunk >= curChunk) { processor_.process(ip, op); int newChunk = inputTransport_.getCurChunk(); curChunk = newChunk; } } catch (TTransportException e) { // if we are processing the last chunk - we could have just hit EOF // on EOF - trap the error and stop processing. if (e.getType() != TTransportException.END_OF_FILE) throw e; else { return; } } } /** * Process from start to last chunk both inclusive where chunks begin from 0 * * @param startChunkNum first chunk to be processed * @param endChunkNum last chunk to be processed * @throws TException if endChunkNum is less than startChunkNum. */ public void processChunk(int startChunkNum, int endChunkNum) throws TException { int numChunks = inputTransport_.getNumChunks(); if (endChunkNum < 0) endChunkNum += numChunks; if (startChunkNum < 0) startChunkNum += numChunks; if (endChunkNum < startChunkNum) throw new TException("endChunkNum " + endChunkNum + " is less than " + startChunkNum); inputTransport_.seekToChunk(startChunkNum); processUntil(endChunkNum); } /** * Process a single chunk * * @param chunkNum chunk to be processed * @throws TException on error while processing the given chunk. */ public void processChunk(int chunkNum) throws TException { processChunk(chunkNum, chunkNum); } /** * Process a current chunk * * @throws TException on error while processing the given chunk. */ public void processChunk() throws TException { processChunk(inputTransport_.getCurChunk()); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TBaseProcessor.java0000664000175000017500000000277115165535636026600 0ustar00buildbuild00000000000000package org.apache.thrift; import java.util.Collections; import java.util.Map; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TMessageType; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TType; public abstract class TBaseProcessor implements TProcessor { private final I iface; private final Map> processMap; protected TBaseProcessor( I iface, Map> processFunctionMap) { this.iface = iface; this.processMap = processFunctionMap; } public Map> getProcessMapView() { return Collections.unmodifiableMap(processMap); } @Override public void process(TProtocol in, TProtocol out) throws TException { TMessage msg = in.readMessageBegin(); ProcessFunction fn = processMap.get(msg.name); if (fn == null) { TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException( TApplicationException.UNKNOWN_METHOD, "Invalid method name: '" + msg.name + "'"); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); } else { fn.process(msg.seqid, in, out, iface); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/utils/0000775000175000017500000000000015165535636024170 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/utils/StringUtils.java0000664000175000017500000000455015165535636027326 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.utils; public final class StringUtils { private StringUtils() { // Utility class. } private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * Stringify a byte array to the hex representation for each byte. * * @param bytes the byte array to convert to hex string. * @return hex string. */ public static String bytesToHexString(byte[] bytes) { if (bytes == null) { return null; } return bytesToHexString(bytes, 0, bytes.length); } /** * Stringify a portion of the byte array. * * @param bytes byte array. * @param offset portion start. * @param length portion length. * @return hex string. */ public static String bytesToHexString(byte[] bytes, int offset, int length) { if (length < 0) { throw new IllegalArgumentException("Negative length " + length); } if (offset < 0) { throw new IndexOutOfBoundsException("Negative start offset " + offset); } if (length > bytes.length - offset) { throw new IndexOutOfBoundsException( "Invalid range, bytes.length: " + bytes.length + " offset: " + offset + " length: " + length); } char[] chars = new char[length * 2]; for (int i = 0; i < length; i++) { int unsignedInt = bytes[i + offset] & 0xFF; chars[2 * i] = HEX_CHARS[unsignedInt >>> 4]; chars[2 * i + 1] = HEX_CHARS[unsignedInt & 0x0F]; } return new String(chars); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TEnumHelper.java0000664000175000017500000000333615165535636026070 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.lang.reflect.Method; /** Utility class with static methods for interacting with TEnum */ public class TEnumHelper { /* no instantiation */ private TEnumHelper() {} /** * Given a TEnum class and integer value, this method will return the associated constant from the * given TEnum class. This method MUST be modified should the name of the 'findByValue' method * change. * * @param enumClass TEnum from which to return a matching constant. * @param value Value for which to return the constant. * @return The constant in 'enumClass' whose value is 'value' or null if something went wrong. */ public static TEnum getByValue(Class enumClass, int value) { try { Method method = enumClass.getMethod("findByValue", int.class); return (TEnum) method.invoke(null, value); } catch (ReflectiveOperationException nsme) { return null; } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/0000775000175000017500000000000015165535636024464 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/EnumCache.java0000664000175000017500000000547115165535636027166 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.thrift.TEnum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Provides a memoized way to lookup an enum by its value. * *

This class is used internally by {@code TDeserializer}. It is not intended to be used * separately on its own. */ public class EnumCache { private static final Logger LOG = LoggerFactory.getLogger(EnumCache.class); private Map, Map> classMap; public EnumCache() { this.classMap = new HashMap<>(); } /** * Gets an instance of the enum type {@code enumClass} corresponding to the given {@code value}. * * @param enumClass class of the enum to be returned. * @param value value returned by {@code getValue()}. */ public TEnum get(Class enumClass, int value) { Validate.checkNotNull(enumClass, "enumClass"); Map valueMap = classMap.get(enumClass); if (valueMap == null) { valueMap = addClass(enumClass); if (valueMap == null) { return null; } } return valueMap.get(value); } private Map addClass(Class enumClass) { try { Method valuesMethod = enumClass.getMethod("values"); TEnum[] enumValues = (TEnum[]) valuesMethod.invoke(null); Map valueMap = new HashMap<>(); for (TEnum enumValue : enumValues) { valueMap.put(enumValue.getValue(), enumValue); } classMap.put(enumClass, valueMap); return valueMap; } catch (NoSuchMethodException e) { LOG.error("enum class does not have values() method", e); return null; } catch (IllegalAccessException e) { LOG.error("Enum.values() method should be public!", e); return null; } catch (InvocationTargetException e) { LOG.error("Enum.values() threw exception", e); return null; } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/ThriftMetadata.java0000664000175000017500000004261615165535636030241 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.io.Serializable; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.thrift.TBase; import org.apache.thrift.TFieldIdEnum; import org.apache.thrift.TFieldRequirementType; import org.apache.thrift.TUnion; import org.apache.thrift.meta_data.FieldMetaData; import org.apache.thrift.meta_data.ListMetaData; import org.apache.thrift.meta_data.MapMetaData; import org.apache.thrift.meta_data.SetMetaData; import org.apache.thrift.meta_data.StructMetaData; import org.apache.thrift.protocol.TType; /** * Container for Thrift metadata classes such as {@link ThriftPrimitive}, {@link ThriftList}, etc. * *

This class is mainly used by {@code TDeserializer}. */ public class ThriftMetadata { enum FieldTypeEnum implements TFieldIdEnum { ROOT((short) 0, "root"), ENUM((short) 1, "enum"), LIST_ELEMENT((short) 2, "listElement"), MAP_KEY((short) 3, "mapKey"), MAP_VALUE((short) 4, "mapValue"), SET_ELEMENT((short) 5, "setElement"); private final short id; private final String name; FieldTypeEnum(short id, String name) { this.id = id; this.name = name; } @Override public short getThriftFieldId() { return id; } @Override public String getFieldName() { return name; } } private enum ComparisonResult { UNKNOWN, EQUAL, NOT_EQUAL } /** * Base class of field types that can be partially deserialized. * *

Holds metadata necessary for partial deserialization. The metadata is internally computed * and used; therefore it is not visible to the users of {@code TDeserializer}. */ public abstract static class ThriftObject implements Serializable { public final ThriftObject parent; public final TFieldIdEnum fieldId; public final FieldMetaData data; // Placeholder to attach additional data. This class or its descendents // do not try to access or interpret this field. public Object additionalData; ThriftObject(ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data) { this.parent = parent; this.fieldId = fieldId; this.data = data; } /** * Converts this instance to formatted and indented string representation. * * @param sb the {@code StringBuilder} to add formatted strings to. * @param level the current indent level. */ protected abstract void toPrettyString(StringBuilder sb, int level); /** Gets a space string whose length is proportional to the given indent level. */ protected String getIndent(int level) { return StringUtils.repeat(" ", level * 4); } /** Helper method to append a formatted string to the given {@code StringBuilder}. */ protected void append(StringBuilder sb, String format, Object... args) { sb.append(String.format(format, args)); } /** Gets the name of this field. */ protected String getName() { return this.fieldId.getFieldName(); } protected List noFields = Collections.emptyList(); protected String getSubElementName(TFieldIdEnum fieldId) { return getSubElementName(fieldId, "element"); } protected String getSubElementName(TFieldIdEnum fieldId, String suffix) { return String.format("%s_%s", fieldId.getFieldName(), suffix); } private static class Factory { static ThriftObject createNew( ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data, List fields) { byte fieldType = data.valueMetaData.type; switch (fieldType) { case TType.STRUCT: return ThriftStructBase.create(parent, fieldId, data, fields); case TType.LIST: return new ThriftList(parent, fieldId, data, fields); case TType.MAP: return new ThriftMap(parent, fieldId, data, fields); case TType.SET: return new ThriftSet(parent, fieldId, data, fields); case TType.ENUM: return new ThriftEnum(parent, fieldId, data); case TType.BOOL: case TType.BYTE: case TType.I16: case TType.I32: case TType.I64: case TType.DOUBLE: case TType.STRING: return new ThriftPrimitive(parent, fieldId, data); default: throw unsupportedFieldTypeException(fieldType); } } } } /** Metadata about primitive types. */ public static class ThriftPrimitive extends ThriftObject { ThriftPrimitive(ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data) { super(parent, fieldId, data); } public boolean isBinary() { return this.data.valueMetaData.isBinary(); } @Override protected void toPrettyString(StringBuilder sb, int level) { String fieldType = this.getTypeName(); this.append(sb, "%s%s %s;\n", this.getIndent(level), fieldType, this.getName()); } private String getTypeName() { byte fieldType = this.data.valueMetaData.type; switch (fieldType) { case TType.BOOL: return "bool"; case TType.BYTE: return "byte"; case TType.I16: return "i16"; case TType.I32: return "i32"; case TType.I64: return "i64"; case TType.DOUBLE: return "double"; case TType.STRING: if (this.isBinary()) { return "binary"; } else { return "string"; } default: throw unsupportedFieldTypeException(fieldType); } } } public static class ThriftEnum extends ThriftObject { private static EnumCache enums = new EnumCache(); ThriftEnum(ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data) { super(parent, fieldId, data); } @Override protected void toPrettyString(StringBuilder sb, int level) { this.append(sb, "%senum %s;\n", this.getIndent(level), this.getName()); } } /** Metadata of container like objects: list, set, map */ public abstract static class ThriftContainer extends ThriftObject { public ThriftContainer(ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data) { super(parent, fieldId, data); } public abstract boolean hasUnion(); } public static class ThriftList extends ThriftContainer { public final ThriftObject elementData; ThriftList( ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data, List fields) { super(parent, fieldId, data); this.elementData = ThriftObject.Factory.createNew( this, FieldTypeEnum.LIST_ELEMENT, new FieldMetaData( getSubElementName(fieldId), TFieldRequirementType.REQUIRED, ((ListMetaData) data.valueMetaData).elemMetaData), fields); } @Override public boolean hasUnion() { return this.elementData instanceof ThriftUnion; } @Override protected void toPrettyString(StringBuilder sb, int level) { this.append(sb, "%slist<\n", this.getIndent(level)); this.elementData.toPrettyString(sb, level + 1); this.append(sb, "%s> %s;\n", this.getIndent(level), this.getName()); } } public static class ThriftSet extends ThriftContainer { public final ThriftObject elementData; ThriftSet( ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data, List fields) { super(parent, fieldId, data); this.elementData = ThriftObject.Factory.createNew( this, FieldTypeEnum.SET_ELEMENT, new FieldMetaData( getSubElementName(fieldId), TFieldRequirementType.REQUIRED, ((SetMetaData) data.valueMetaData).elemMetaData), fields); } @Override public boolean hasUnion() { return this.elementData instanceof ThriftUnion; } @Override protected void toPrettyString(StringBuilder sb, int level) { this.append(sb, "%sset<\n", this.getIndent(level)); this.elementData.toPrettyString(sb, level + 1); this.append(sb, "%s> %s;\n", this.getIndent(level), this.getName()); } } public static class ThriftMap extends ThriftContainer { public final ThriftObject keyData; public final ThriftObject valueData; ThriftMap( ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data, List fields) { super(parent, fieldId, data); this.keyData = ThriftObject.Factory.createNew( this, FieldTypeEnum.MAP_KEY, new FieldMetaData( getSubElementName(fieldId, "key"), TFieldRequirementType.REQUIRED, ((MapMetaData) data.valueMetaData).keyMetaData), Collections.emptyList()); this.valueData = ThriftObject.Factory.createNew( this, FieldTypeEnum.MAP_VALUE, new FieldMetaData( getSubElementName(fieldId, "value"), TFieldRequirementType.REQUIRED, ((MapMetaData) data.valueMetaData).valueMetaData), fields); } @Override public boolean hasUnion() { return (this.keyData instanceof ThriftUnion) || (this.valueData instanceof ThriftUnion); } @Override protected void toPrettyString(StringBuilder sb, int level) { this.append(sb, "%smap<\n", this.getIndent(level)); this.append(sb, "%skey = {\n", this.getIndent(level + 1)); this.keyData.toPrettyString(sb, level + 2); this.append(sb, "%s},\n", this.getIndent(level + 1)); this.append(sb, "%svalue = {\n", this.getIndent(level + 1)); this.valueData.toPrettyString(sb, level + 2); this.append(sb, "%s}\n", this.getIndent(level + 1)); this.append(sb, "%s> %s;\n", this.getIndent(level), this.getName()); } } /** * Base class for metadata of ThriftStruct and ThriftUnion. Holds functionality that is common to * both. */ public abstract static class ThriftStructBase extends ThriftObject { public ThriftStructBase(ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data) { super(parent, fieldId, data); } public Class getStructClass() { return getStructClass(this.data); } public static Class getStructClass(FieldMetaData data) { return (Class) ((StructMetaData) data.valueMetaData).structClass; } public boolean isUnion() { return isUnion(this.data); } public static boolean isUnion(FieldMetaData data) { return TUnion.class.isAssignableFrom(getStructClass(data)); } public static ThriftStructBase create( ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data, Iterable fieldsData) { if (isUnion(data)) { return new ThriftUnion<>(parent, fieldId, data, fieldsData); } else { return new ThriftStruct<>(parent, fieldId, data, fieldsData); } } } /** Metadata of a Thrift union. Currently not adequately supported. */ public static class ThriftUnion extends ThriftStructBase { public ThriftUnion( ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data, Iterable fieldsData) { super(parent, fieldId, data); } @Override protected void toPrettyString(StringBuilder sb, int level) { String indent = this.getIndent(level); String indent2 = this.getIndent(level + 1); this.append(sb, "%sunion %s {\n", indent, this.getName()); this.append(sb, "%s// unions not adequately supported at present.\n", indent2); this.append(sb, "%s}\n", indent); } } /** Metadata of a Thrift struct. */ public static class ThriftStruct extends ThriftStructBase { public final Map fields; ThriftStruct( ThriftObject parent, TFieldIdEnum fieldId, FieldMetaData data, Iterable fieldsData) { super(parent, fieldId, data); Class clasz = getStructClass(data); this.fields = getFields(this, clasz, fieldsData); } public T createNewStruct() { try { Class structClass = getStructClass(this.data); Constructor declaredConstructor = structClass.getDeclaredConstructor(); return declaredConstructor.newInstance(); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } } public static ThriftStruct of(Class clasz) { return ThriftStruct.fromFields(clasz, Collections.emptyList()); } public static ThriftStruct fromFieldNames( Class clasz, Collection fieldNames) { return fromFields(clasz, ThriftField.fromNames(fieldNames)); } public static ThriftStruct fromFields( Class clasz, Iterable fields) { Validate.checkNotNull(clasz, "clasz"); Validate.checkNotNull(fields, "fields"); return new ThriftStruct<>( null, FieldTypeEnum.ROOT, new FieldMetaData( FieldTypeEnum.ROOT.getFieldName(), TFieldRequirementType.REQUIRED, new StructMetaData(TType.STRUCT, clasz)), fields); } @Override public String toString() { StringBuilder sb = new StringBuilder(); this.toPrettyString(sb, 0); return sb.toString(); } @Override protected void toPrettyString(StringBuilder sb, int level) { String indent = this.getIndent(level); String indent2 = this.getIndent(level + 1); this.append(sb, "%sstruct %s {\n", indent, this.getName()); if (this.fields.size() == 0) { this.append(sb, "%s*;", indent2); } else { List ids = new ArrayList<>(this.fields.keySet()); Collections.sort(ids); for (Integer id : ids) { this.fields.get(id).toPrettyString(sb, level + 1); } } this.append(sb, "%s}\n", indent); } private static Map getFields( ThriftStruct parent, Class clasz, Iterable fieldsData) { Map fieldsMetaData = FieldMetaData.getStructMetaDataMap(clasz); Map fields = new HashMap<>(); boolean getAllFields = !fieldsData.iterator().hasNext(); if (getAllFields) { for (Map.Entry entry : fieldsMetaData.entrySet()) { TFieldIdEnum fieldId = entry.getKey(); FieldMetaData fieldMetaData = entry.getValue(); ThriftObject field = ThriftObject.Factory.createNew( parent, fieldId, fieldMetaData, Collections.emptyList()); fields.put((int) fieldId.getThriftFieldId(), field); } } else { for (ThriftField fieldData : fieldsData) { String fieldName = fieldData.name; FieldMetaData fieldMetaData = findFieldMetaData(fieldsMetaData, fieldName); TFieldIdEnum fieldId = findFieldId(fieldsMetaData, fieldName); ThriftObject field = ThriftObject.Factory.createNew(parent, fieldId, fieldMetaData, fieldData.fields); fields.put((int) fieldId.getThriftFieldId(), field); } } return fields; } private static FieldMetaData findFieldMetaData( Map fieldsMetaData, String fieldName) { for (FieldMetaData fieldData : fieldsMetaData.values()) { if (fieldData.fieldName.equals(fieldName)) { return fieldData; } } throw fieldNotFoundException(fieldName); } private static TFieldIdEnum findFieldId( Map fieldsMetaData, String fieldName) { for (TFieldIdEnum fieldId : fieldsMetaData.keySet()) { if (fieldId.getFieldName().equals(fieldName)) { return fieldId; } } throw fieldNotFoundException(fieldName); } } static IllegalArgumentException fieldNotFoundException(String fieldName) { return new IllegalArgumentException("field not found: '" + fieldName + "'"); } static UnsupportedOperationException unsupportedFieldTypeException(byte fieldType) { return new UnsupportedOperationException("field type not supported: '" + fieldType + "'"); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/ThriftStructProcessor.java0000664000175000017500000001225615165535636031702 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import org.apache.thrift.TBase; import org.apache.thrift.TEnum; import org.apache.thrift.TFieldIdEnum; /** * Provides a way to create and initialize an instance of TBase during partial deserialization. * *

This class is supposed to be used as a helper class for {@code PartialThriftDeserializer}. */ public class ThriftStructProcessor implements ThriftFieldValueProcessor { private static final EnumCache enums = new EnumCache(); @Override public Object createNewStruct(ThriftMetadata.ThriftStruct metadata) { return metadata.createNewStruct(); } @Override public TBase prepareStruct(Object instance) { return (TBase) instance; } @Override public Object createNewList(int expectedSize) { return new Object[expectedSize]; } @Override public void setListElement(Object instance, int index, Object value) { ((Object[]) instance)[index] = value; } @Override public Object prepareList(Object instance) { return Arrays.asList((Object[]) instance); } @Override public Object createNewMap(int expectedSize) { return new HashMap(expectedSize); } @Override public void setMapElement(Object instance, int index, Object key, Object value) { ((HashMap) instance).put(key, value); } @Override public Object prepareMap(Object instance) { return instance; } @Override public Object createNewSet(int expectedSize) { return new HashSet(expectedSize); } @Override public void setSetElement(Object instance, int index, Object value) { ((HashSet) instance).add(value); } @Override public Object prepareSet(Object instance) { return instance; } @Override public Object prepareEnum(Class enumClass, int ordinal) { return enums.get(enumClass, ordinal); } @Override public Object prepareString(ByteBuffer buffer) { return byteBufferToString(buffer); } @Override public Object prepareBinary(ByteBuffer buffer) { return buffer; } @Override public void setBool(TBase valueCollection, TFieldIdEnum fieldId, boolean value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setByte(TBase valueCollection, TFieldIdEnum fieldId, byte value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setInt16(TBase valueCollection, TFieldIdEnum fieldId, short value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setInt32(TBase valueCollection, TFieldIdEnum fieldId, int value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setInt64(TBase valueCollection, TFieldIdEnum fieldId, long value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setDouble(TBase valueCollection, TFieldIdEnum fieldId, double value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setBinary(TBase valueCollection, TFieldIdEnum fieldId, ByteBuffer value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setString(TBase valueCollection, TFieldIdEnum fieldId, ByteBuffer buffer) { String value = byteBufferToString(buffer); valueCollection.setFieldValue(fieldId, value); } @Override public void setEnumField(TBase valueCollection, TFieldIdEnum fieldId, Object value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setListField(TBase valueCollection, TFieldIdEnum fieldId, Object value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setMapField(TBase valueCollection, TFieldIdEnum fieldId, Object value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setSetField(TBase valueCollection, TFieldIdEnum fieldId, Object value) { valueCollection.setFieldValue(fieldId, value); } @Override public void setStructField(TBase valueCollection, TFieldIdEnum fieldId, Object value) { valueCollection.setFieldValue(fieldId, value); } private static String byteBufferToString(ByteBuffer buffer) { byte[] bytes = buffer.array(); int pos = buffer.position(); return new String(bytes, pos, buffer.limit() - pos, StandardCharsets.UTF_8); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/Validate.java0000664000175000017500000002111615165535636027061 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; /** * A superset of Validate class in Apache commons lang3. * *

It provides consistent message strings for frequently encountered checks. That simplifies * callers because they have to supply only the name of the argument that failed a check instead of * having to supply the entire message. */ public final class Validate { private Validate() {} /** Validates that the given reference argument is not null. */ public static void checkNotNull(Object obj, String argName) { checkArgument(obj != null, "'%s' must not be null.", argName); } /** Validates that the given integer argument is not zero or negative. */ public static void checkPositiveInteger(long value, String argName) { checkArgument(value > 0, "'%s' must be a positive integer.", argName); } /** Validates that the given integer argument is not negative. */ public static void checkNotNegative(long value, String argName) { checkArgument(value >= 0, "'%s' must not be negative.", argName); } /* * Validates that the expression (that checks a required field is present) is true. */ public static void checkRequired(boolean isPresent, String argName) { checkArgument(isPresent, "'%s' is required.", argName); } /** Validates that the expression (that checks a field is valid) is true. */ public static void checkValid(boolean isValid, String argName) { checkArgument(isValid, "'%s' is invalid.", argName); } /** Validates that the expression (that checks a field is valid) is true. */ public static void checkValid(boolean isValid, String argName, String validValues) { checkArgument(isValid, "'%s' is invalid. Valid values are: %s.", argName, validValues); } /** Validates that the given string is not null and has non-zero length. */ public static void checkNotNullAndNotEmpty(String arg, String argName) { Validate.checkNotNull(arg, argName); Validate.checkArgument(arg.length() > 0, "'%s' must not be empty.", argName); } /** Validates that the given array is not null and has at least one element. */ public static void checkNotNullAndNotEmpty(T[] array, String argName) { Validate.checkNotNull(array, argName); checkNotEmpty(array.length, argName); } /** Validates that the given array is not null and has at least one element. */ public static void checkNotNullAndNotEmpty(byte[] array, String argName) { Validate.checkNotNull(array, argName); checkNotEmpty(array.length, argName); } /** Validates that the given array is not null and has at least one element. */ public static void checkNotNullAndNotEmpty(short[] array, String argName) { Validate.checkNotNull(array, argName); checkNotEmpty(array.length, argName); } /** Validates that the given array is not null and has at least one element. */ public static void checkNotNullAndNotEmpty(int[] array, String argName) { Validate.checkNotNull(array, argName); checkNotEmpty(array.length, argName); } /** Validates that the given array is not null and has at least one element. */ public static void checkNotNullAndNotEmpty(long[] array, String argName) { Validate.checkNotNull(array, argName); checkNotEmpty(array.length, argName); } /** Validates that the given buffer is not null and has non-zero capacity. */ public static void checkNotNullAndNotEmpty(Iterable iter, String argName) { Validate.checkNotNull(iter, argName); int minNumElements = iter.iterator().hasNext() ? 1 : 0; checkNotEmpty(minNumElements, argName); } /** Validates that the given set is not null and has an exact number of items. */ public static void checkNotNullAndNumberOfElements( Collection collection, int numElements, String argName) { Validate.checkNotNull(collection, argName); checkArgument( collection.size() == numElements, "Number of elements in '%s' must be exactly %s, %s given.", argName, numElements, collection.size()); } /** Validates that the given two values are equal. */ public static void checkValuesEqual( long value1, String value1Name, long value2, String value2Name) { checkArgument( value1 == value2, "'%s' (%s) must equal '%s' (%s).", value1Name, value1, value2Name, value2); } /** Validates that the first value is an integer multiple of the second value. */ public static void checkIntegerMultiple( long value1, String value1Name, long value2, String value2Name) { checkArgument( (value1 % value2) == 0, "'%s' (%s) must be an integer multiple of '%s' (%s).", value1Name, value1, value2Name, value2); } /** Validates that the first value is greater than the second value. */ public static void checkGreater(long value1, String value1Name, long value2, String value2Name) { checkArgument( value1 > value2, "'%s' (%s) must be greater than '%s' (%s).", value1Name, value1, value2Name, value2); } /** Validates that the first value is greater than or equal to the second value. */ public static void checkGreaterOrEqual( long value1, String value1Name, long value2, String value2Name) { checkArgument( value1 >= value2, "'%s' (%s) must be greater than or equal to '%s' (%s).", value1Name, value1, value2Name, value2); } /** Validates that the first value is less than or equal to the second value. */ public static void checkLessOrEqual( long value1, String value1Name, long value2, String value2Name) { checkArgument( value1 <= value2, "'%s' (%s) must be less than or equal to '%s' (%s).", value1Name, value1, value2Name, value2); } /** Validates that the given value is within the given range of values. */ public static void checkWithinRange( long value, String valueName, long minValueInclusive, long maxValueInclusive) { checkArgument( (value >= minValueInclusive) && (value <= maxValueInclusive), "'%s' (%s) must be within the range [%s, %s].", valueName, value, minValueInclusive, maxValueInclusive); } /** Validates that the given value is within the given range of values. */ public static void checkWithinRange( double value, String valueName, double minValueInclusive, double maxValueInclusive) { checkArgument( (value >= minValueInclusive) && (value <= maxValueInclusive), "'%s' (%s) must be within the range [%s, %s].", valueName, value, minValueInclusive, maxValueInclusive); } public static void checkPathExists(Path path, String argName) { checkNotNull(path, argName); checkArgument(Files.exists(path), "Path %s (%s) does not exist.", argName, path); } public static void checkPathExistsAsDir(Path path, String argName) { checkPathExists(path, argName); checkArgument( Files.isDirectory(path), "Path %s (%s) must point to a directory.", argName, path); } public static void checkPathExistsAsFile(Path path, String argName) { checkPathExists(path, argName); checkArgument(Files.isRegularFile(path), "Path %s (%s) must point to a file.", argName, path); } public static void checkArgument(boolean expression, String format, Object... args) { org.apache.commons.lang3.Validate.isTrue(expression, format, args); } public static void checkState(boolean expression, String format, Object... args) { org.apache.commons.lang3.Validate.validState(expression, format, args); } private static void checkNotEmpty(int arraySize, String argName) { Validate.checkArgument(arraySize > 0, "'%s' must have at least one element.", argName); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/PartialThriftComparer.java0000664000175000017500000002314215165535636031577 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.TBase; import org.apache.thrift.protocol.TType; /** * Enables comparison of two TBase instances such that the comparison is limited to the subset of * fields defined by the supplied metadata. * *

This comparer is useful when comparing two instances where: -- one is generated by full * deserialization. -- the other is generated by partial deserialization. * *

The typical use case is to establish correctness of partial deserialization. */ public class PartialThriftComparer { private enum ComparisonResult { UNKNOWN, EQUAL, NOT_EQUAL } // Metadata that defines the scope of comparison. private ThriftMetadata.ThriftStruct metadata; /** * Constructs an instance of {@link PartialThriftComparer}. * * @param metadata defines the scope of comparison. */ public PartialThriftComparer(ThriftMetadata.ThriftStruct metadata) { this.metadata = metadata; } /** * Compares thrift objects {@code t1} and {@code t2} and returns true if they are equal false * otherwise. The comparison is limited to the scope defined by {@code metadata}. * *

If the objects are not equal then it optionally records their differences if {@code sb} is * supplied. * *

* * @param t1 the first object. * @param t2 the second object. * @param sb if non-null, results of the comparison are returned in it. * @return true if objects are equivalent, false otherwise. */ public boolean areEqual(T t1, T t2, StringBuilder sb) { return this.areEqual(this.metadata, t1, t2, sb); } private boolean areEqual( ThriftMetadata.ThriftObject data, Object o1, Object o2, StringBuilder sb) { byte fieldType = data.data.valueMetaData.type; switch (fieldType) { case TType.STRUCT: return this.areEqual((ThriftMetadata.ThriftStruct) data, o1, o2, sb); case TType.LIST: return this.areEqual((ThriftMetadata.ThriftList) data, o1, o2, sb); case TType.MAP: return this.areEqual((ThriftMetadata.ThriftMap) data, o1, o2, sb); case TType.SET: return this.areEqual((ThriftMetadata.ThriftSet) data, o1, o2, sb); case TType.ENUM: return this.areEqual((ThriftMetadata.ThriftEnum) data, o1, o2, sb); case TType.BOOL: case TType.BYTE: case TType.I16: case TType.I32: case TType.I64: case TType.DOUBLE: case TType.STRING: return this.areEqual((ThriftMetadata.ThriftPrimitive) data, o1, o2, sb); default: throw unsupportedFieldTypeException(fieldType); } } private boolean areEqual( ThriftMetadata.ThriftStruct data, Object o1, Object o2, StringBuilder sb) { ComparisonResult result = checkNullEquality(data, o1, o2, sb); if (result != ComparisonResult.UNKNOWN) { return result == ComparisonResult.EQUAL; } TBase t1 = (TBase) o1; TBase t2 = (TBase) o2; if (data.fields.size() == 0) { if (t1.equals(t2)) { return true; } else { appendNotEqual(data, sb, t1, t2, "struct1", "struct2"); return false; } } else { boolean overallResult = true; for (Object o : data.fields.values()) { ThriftMetadata.ThriftObject field = (ThriftMetadata.ThriftObject) o; Object f1 = t1.getFieldValue(field.fieldId); Object f2 = t2.getFieldValue(field.fieldId); overallResult = overallResult && this.areEqual(field, f1, f2, sb); } return overallResult; } } private boolean areEqual( ThriftMetadata.ThriftPrimitive data, Object o1, Object o2, StringBuilder sb) { ComparisonResult result = checkNullEquality(data, o1, o2, sb); if (result != ComparisonResult.UNKNOWN) { return result == ComparisonResult.EQUAL; } if (data.isBinary()) { if (areBinaryFieldsEqual(o1, o2)) { return true; } } else if (o1.equals(o2)) { return true; } appendNotEqual(data, sb, o1, o2, "o1", "o2"); return false; } private boolean areEqual(ThriftMetadata.ThriftEnum data, Object o1, Object o2, StringBuilder sb) { ComparisonResult result = checkNullEquality(data, o1, o2, sb); if (result != ComparisonResult.UNKNOWN) { return result == ComparisonResult.EQUAL; } if (o1.equals(o2)) { return true; } appendNotEqual(data, sb, o1, o2, "o1", "o2"); return false; } private boolean areEqual(ThriftMetadata.ThriftList data, Object o1, Object o2, StringBuilder sb) { List l1 = (List) o1; List l2 = (List) o2; ComparisonResult result = checkNullEquality(data, o1, o2, sb); if (result != ComparisonResult.UNKNOWN) { return result == ComparisonResult.EQUAL; } if (!checkSizeEquality(data, l1, l2, sb, "list")) { return false; } for (int i = 0; i < l1.size(); i++) { Object e1 = l1.get(i); Object e2 = l2.get(i); if (!this.areEqual(data.elementData, e1, e2, sb)) { return false; } } return true; } private boolean areEqual(ThriftMetadata.ThriftSet data, Object o1, Object o2, StringBuilder sb) { Set s1 = (Set) o1; Set s2 = (Set) o2; ComparisonResult result = checkNullEquality(data, o1, o2, sb); if (result != ComparisonResult.UNKNOWN) { return result == ComparisonResult.EQUAL; } if (!checkSizeEquality(data, s1, s2, sb, "set")) { return false; } for (Object e1 : s1) { if (!s2.contains(e1)) { appendResult(data, sb, "Element %s in s1 not found in s2", e1); return false; } } return true; } private boolean areEqual(ThriftMetadata.ThriftMap data, Object o1, Object o2, StringBuilder sb) { Map m1 = (Map) o1; Map m2 = (Map) o2; ComparisonResult result = checkNullEquality(data, o1, o2, sb); if (result != ComparisonResult.UNKNOWN) { return result == ComparisonResult.EQUAL; } if (!checkSizeEquality(data, m1.keySet(), m2.keySet(), sb, "map.keySet")) { return false; } for (Map.Entry e1 : m1.entrySet()) { Object k1 = e1.getKey(); if (!m2.containsKey(k1)) { appendResult(data, sb, "Key %s in m1 not found in m2", k1); return false; } Object v1 = e1.getValue(); Object v2 = m2.get(k1); if (!this.areEqual(data.valueData, v1, v2, sb)) { return false; } } return true; } private boolean areBinaryFieldsEqual(Object o1, Object o2) { if (o1 instanceof byte[]) { if (Arrays.equals((byte[]) o1, (byte[]) o2)) { return true; } } else if (o1 instanceof ByteBuffer) { if (((ByteBuffer) o1).compareTo((ByteBuffer) o2) == 0) { return true; } } else { throw new UnsupportedOperationException( String.format("Unsupported binary field type: %s", o1.getClass().getName())); } return false; } private void appendResult( ThriftMetadata.ThriftObject data, StringBuilder sb, String format, Object... args) { if (sb != null) { String msg = String.format(format, args); sb.append(data.fieldId.getFieldName()); sb.append(" : "); sb.append(msg); } } private void appendNotEqual( ThriftMetadata.ThriftObject data, StringBuilder sb, Object o1, Object o2, String o1name, String o2name) { String o1s = o1.toString(); String o2s = o2.toString(); if ((o1s.length() + o2s.length()) < 100) { appendResult(data, sb, "%s (%s) != %s (%s)", o1name, o1s, o2name, o2s); } else { appendResult( data, sb, "%s != %s\n%s =\n%s\n%s =\n%s\n", o1name, o2name, o1name, o1s, o2name, o2s); } } private ComparisonResult checkNullEquality( ThriftMetadata.ThriftObject data, Object o1, Object o2, StringBuilder sb) { if ((o1 == null) && (o2 == null)) { return ComparisonResult.EQUAL; } if (o1 == null) { appendResult(data, sb, "o1 (null) != o2"); } if (o2 == null) { appendResult(data, sb, "o1 != o2 (null)"); } return ComparisonResult.UNKNOWN; } private boolean checkSizeEquality( ThriftMetadata.ThriftObject data, Collection c1, Collection c2, StringBuilder sb, String typeName) { if (c1.size() != c2.size()) { appendResult( data, sb, "%s1.size(%d) != %s2.size(%d)", typeName, c1.size(), typeName, c2.size()); return false; } return true; } static UnsupportedOperationException unsupportedFieldTypeException(byte fieldType) { return new UnsupportedOperationException("field type not supported: '" + fieldType + "'"); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/ThriftField.java0000664000175000017500000001267415165535636027545 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; /** * Holds name of a thrift field and of its sub-fields recursively. * *

This class is meant to be used in conjunction with {@code TDeserializer}. */ public class ThriftField { /** Name of this field as it appears in a thrift file. Case sensitive. */ public final String name; /** * List of sub-fields of this field. * *

This list should have only those sub-fields that need to be deserialized by the {@code * TDeserializer}. */ public final List fields; /** * Constructs a {@link ThriftField}. * * @param name the name of this field as it appears in a thrift file. Case sensitive. * @param fields List of sub-fields of this field. */ ThriftField(String name, List fields) { Validate.checkNotNullAndNotEmpty(name, "name"); Validate.checkNotNull(fields, "fields"); this.name = name; this.fields = Collections.unmodifiableList(fields); } /** Constructs a {@link ThriftField} that does not have any sub-fields. */ ThriftField(String name) { this(name, Collections.emptyList()); } // Internal-only constructor that does not mark fields as read-only. // That allows fromNames() to construct fields from names. // The actual value of allowFieldAdds is ignored. // It is used only for generating a different function signature. ThriftField(String name, List fields, boolean allowFieldAdds) { Validate.checkNotNullAndNotEmpty(name, "name"); Validate.checkNotNull(fields, "fields"); this.name = name; this.fields = fields; } private int hashcode = 0; @Override public int hashCode() { if (this.hashcode == 0) { int hc = this.name.toLowerCase().hashCode(); for (ThriftField subField : this.fields) { hc ^= subField.hashCode(); } this.hashcode = hc; } return this.hashcode; } @Override public boolean equals(Object o) { if (o == null) { return false; } if (!(o instanceof ThriftField)) { return false; } ThriftField other = (ThriftField) o; if (!this.name.equalsIgnoreCase(other.name)) { return false; } if (this.fields.size() != other.fields.size()) { return false; } for (int i = 0; i < this.fields.size(); i++) { if (!this.fields.get(i).equals(other.fields.get(i))) { return false; } } return true; } @Override public String toString() { return String.join(", ", this.getFieldNames()); } public List getFieldNames() { List fieldsList = new ArrayList<>(); if (this.fields.size() == 0) { fieldsList.add(this.name); } else { for (ThriftField f : this.fields) { for (String subF : f.getFieldNames()) { fieldsList.add(this.name + "." + subF); } } } return fieldsList; } /** * Generates and returns n-ary tree of fields and their sub-fields. * *

* * @param fieldNames collection of fully qualified field names. *

for example, In case of PinJoin thrift struct, the following are valid field names -- * signature -- pins.user.userId -- textSignal.termSignal.termDataMap * @return n-ary tree of fields and their sub-fields. */ public static List fromNames(Collection fieldNames) { Validate.checkNotNullAndNotEmpty(fieldNames, "fieldNames"); List fieldNamesList = new ArrayList<>(fieldNames); Collections.sort(fieldNamesList, String.CASE_INSENSITIVE_ORDER); List fields = new ArrayList<>(); for (String fieldName : fieldNamesList) { List tfields = fields; String[] tokens = fieldName.split("\\."); for (String token : tokens) { ThriftField field = findField(token, tfields); if (field == null) { field = new ThriftField(token, new ArrayList<>(), true); tfields.add(field); } tfields = field.fields; } } return makeReadOnly(fields); } private static ThriftField findField(String name, List fields) { for (ThriftField field : fields) { if (field.name.equalsIgnoreCase(name)) { return field; } } return null; } private static List makeReadOnly(List fields) { List result = new ArrayList<>(fields.size()); for (ThriftField field : fields) { ThriftField copy = new ThriftField(field.name, makeReadOnly(field.fields)); result.add(copy); } return Collections.unmodifiableList(result); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/ThriftFieldValueProcessor.java0000664000175000017500000000612615165535636032435 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.nio.ByteBuffer; import org.apache.thrift.TEnum; import org.apache.thrift.TFieldIdEnum; /** * Provides an abstraction to process deserialized field values and place them into the collection * that holds them. This abstraction allows different types of collections to be output from partial * deserialization. * *

In case of the usual Thrift deserialization, the collection that holds field values is simply * an instance of TBase. */ public interface ThriftFieldValueProcessor { // Struct related methods; Object createNewStruct(ThriftMetadata.ThriftStruct metadata); V prepareStruct(Object instance); void setBool(V valueCollection, TFieldIdEnum fieldId, boolean value); void setByte(V valueCollection, TFieldIdEnum fieldId, byte value); void setInt16(V valueCollection, TFieldIdEnum fieldId, short value); void setInt32(V valueCollection, TFieldIdEnum fieldId, int value); void setInt64(V valueCollection, TFieldIdEnum fieldId, long value); void setDouble(V valueCollection, TFieldIdEnum fieldId, double value); void setBinary(V valueCollection, TFieldIdEnum fieldId, ByteBuffer value); void setString(V valueCollection, TFieldIdEnum fieldId, ByteBuffer buffer); void setEnumField(V valueCollection, TFieldIdEnum fieldId, Object value); void setListField(V valueCollection, TFieldIdEnum fieldId, Object value); void setMapField(V valueCollection, TFieldIdEnum fieldId, Object value); void setSetField(V valueCollection, TFieldIdEnum fieldId, Object value); void setStructField(V valueCollection, TFieldIdEnum fieldId, Object value); Object prepareEnum(Class enumClass, int ordinal); Object prepareString(ByteBuffer buffer); Object prepareBinary(ByteBuffer buffer); // List field related methods. Object createNewList(int expectedSize); void setListElement(Object instance, int index, Object value); Object prepareList(Object instance); // Map field related methods. Object createNewMap(int expectedSize); void setMapElement(Object instance, int index, Object key, Object value); Object prepareMap(Object instance); // Set field related methods. Object createNewSet(int expectedSize); void setSetElement(Object instance, int index, Object value); Object prepareSet(Object instance); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/TFieldData.java0000664000175000017500000000262715165535636027277 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; /** * Holds the type and id members of a {@link org.apache.thrift.protocol.TField} into a single int. * *

This encoding scheme obviates the need to instantiate TField during the partial * deserialization process. */ public class TFieldData { public static int encode(byte type) { return type & 0xff; } public static int encode(byte type, short id) { return (type & 0xff) | (((int) id) << 8); } public static byte getType(int data) { return (byte) (0xff & data); } public static short getId(int data) { return (short) ((0xffff00 & data) >> 8); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/partial/README.md0000664000175000017500000001562715165535636025756 0ustar00buildbuild00000000000000# Partial Thrift Deserialization ## Overview This document describes how partial deserialization of Thrift works. There are two main goals of this documentation: 1. Make it easier to understand the current Java implementation in this folder. 1. Be useful in implementing partial deserialization support in additional languages. This document is divided into two high level areas. The first part explains important concepts relevant to partial deserialization. The second part describes components involved in the Java implementation in this folder. Moreover, this blog provides some performance numbers and addtional information: https://medium.com/pinterest-engineering/improving-data-processing-efficiency-using-partial-deserialization-of-thrift-16bc3a4a38b4 ## Basic Concepts ### Motivation The main motivation behind implementing this feature is to improve performance when we need to access only a subset of fields in any Thrift object. This situation arises often when big data is stored in Thrift encoded format (for example, SequenceFile with serialized Thrift values). Many data processing jobs may access this data. However, not every job needs to access every field of each object. In such cases, if we have prior knowledge of the fields needed for a given job, we can deserialize only that subset of fields and avoid the cost deserializing the rest of the fields. There are two benefits of this approach: we save cpu cycles by not deserializing unnecessary fields and we end up reducing gc pressure. Both of the savings quickly add up when processing billions of instances in a data processing job. ### Partial deserialization Partial deserialization involves deserializing only a subset of the fields of a serialized Thrift object while efficiently skipping over the rest. One very important benefit of partial deserialization is that the output of the deserialization process is not limited to a `TBase` derived object. It can deserialize a serialized blob into any type by using an appropriate `ThriftFieldValueProcessor`. ### Defining the subset of fields to deserialize The subset of fields to deserialize is defined using a list of fully qualified field names. For example, consider the Thrift `struct` definition below: ```Thrift struct SmallStruct { 1: optional string stringValue; 2: optional i16 i16Value; } struct TestStruct { 1: optional i16 i16Field; 2: optional list structList; 3: optional set structSet; 4: optional map structMap; 5: optional SmallStruct structField; } ``` For the Thrift `struct`, each of the following line shows a fully qualified field definition. Partial deserialization uses a non-empty set of such field definitions to identify the subset of fields to deserialize. ``` - i16Field - structList.stringValue - structSet.i16Value - structMap.stringValue - structField.i16Value ``` Note that the syntax of denoting paths involving map fields do not support a way to define sub-fields of the key type. However, that limitation can be addressed in future by amending the syntax in a backword compatible way. For example, the field path `structMap.stringValue` shown above has leaf segment `stringValue` which is a field in map values. ## Components The process of partial deserialization involves the following major components. We have listed names of the Java file(s) implementing each component for easier mapping to the source code. ### Thrift Metadata Source files: - ThriftField.java - ThriftMetadata.java - TDeserializer.java We saw in the previous section how we can identify the subset of fields to deserialize. As the first step, we need to compile the collection of field definitions into an internal efficient data structure that we can traverse at runtime. The compilation takes place internally when one creates an instance of TDeserializer using a constructor that accepts a list of field names. ```Java // First, create a collection of fully qualified field names. List fieldNames = Arrays.asList("i16Field", "structField.i16Value"); // Create an instance of TDeserializer that supports partial deserialization. TDeserializer deserializer = new TDeserializer(TestStruct.class, fieldNames, new TBinaryProtocol.Factory()); ``` At this point, we have an efficient internal representation of the fields that need to get deserialized. ### Partial Thrift Protocol Source files: - TProtocol.java - TBinaryProtocol.java - TCompactProtocol.java This component implements efficient skipping over fields that need not be deserialized. The functionality to skip over fields has been added to the above protocols by addition of `skip*()` methods. The default implementation of each such method simply calls the corresponding `read*()` method in `TProtocol.java`. A derived protocol (for example, `TBinaryProtocol`) provides a more efficient implementation of each `skip*()` method. For example, `TBinaryProtocol` skips a field by incrementing internal offset into the transport buffer. ### Partial Thrift Deserializer Source files: - TDeserializer.java This component, traverses a serialized blob sequentially one field at a time. At the beginning of each field, it consults the informations stored in the compiled `ThriftMetadata` to see if that field needs to be deserialized. If yes, then the field is deserialized into a value as would normally take place during regular deserialization process. If that field is not in the target subset then the deserializer efficiently skips over that field. ### Field Value Processor Source files: - ThriftFieldValueProcessor.java - ThriftStructProcessor.java One very important benefit of partial deserialization is that the output of the deserialization process is not limited to a `TBase` derived object. It can deserialize a serialized blob into any type by using an appropriate `ThriftFieldValueProcessor`. When the partial Thrift deserializer deserializes a field, it passes its value to a `ThriftFieldValueProcessor`. The processor gets to decide whether the value is stored as-is or is stored in some intermediate form. The default implementation of this interface is `ThriftStructProcessor`. This implementation outputs a `TBase` derived object. There are other implementations that exist (not included in this drop at present). For example, one implementation enables deserializing a Thrift blob directly into an `InternalRow` used by `Spark`. That has yielded orders of magnitude performance improvement over a `Spark` engine that consumes `Thrift` data using its default deserializer. ### Miscellanious Helpers Files: - TFieldData.java : Holds the type and id members of a TField into a single int. This encoding scheme obviates the need to instantiate TField during the partial deserialization process. - EnumCache.java : Provides a memoized way to lookup an enum by its value. - PartialThriftComparer.java : Enables comparison of two TBase instances such that the comparison is limited to the subset of fields defined by the supplied metadata. thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/0000775000175000017500000000000015165535636024747 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/FieldMetaData.java0000664000175000017500000001021415165535636030234 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.thrift.TBase; import org.apache.thrift.TFieldIdEnum; /** * This class is used to store meta data about thrift fields. Every field in a a struct should have * a corresponding instance of this class describing it. * *

The meta data is registered by ALL Thrift struct classes via a static {...} initializer block * in the generated Thrift code. * *

Since different threads could be initializing different Thrift classes, calls to the public * static methods of this class could be racy. * *

All methods of this class should be made thread safe. */ public class FieldMetaData implements java.io.Serializable { public final String fieldName; public final byte requirementType; public final FieldValueMetaData valueMetaData; private final Map fieldAnnotations; private static final ConcurrentMap< Class, Map> structMap = new ConcurrentHashMap<>(); public FieldMetaData(String name, byte req, FieldValueMetaData vMetaData) { this(name, req, vMetaData, Collections.emptyMap()); } public FieldMetaData( String fieldName, byte requirementType, FieldValueMetaData valueMetaData, Map fieldAnnotations) { this.fieldName = fieldName; this.requirementType = requirementType; this.valueMetaData = valueMetaData; this.fieldAnnotations = fieldAnnotations; } /** * @return an unmodifiable view of the annotations for this field, empty if no annotations present * or code gen param is not turned on */ public Map getFieldAnnotations() { return Collections.unmodifiableMap(fieldAnnotations); } public static , F extends TFieldIdEnum> void addStructMetaDataMap( Class sClass, Map map) { structMap.put(sClass, map); } /** * Returns a map with metadata (i.e. instances of FieldMetaData) that describe the fields of the * given class. * * @param sClass The TBase class for which the metadata map is requested. It is not guaranteed * that sClass will have been statically initialized before this method is called. A racy call * to {@link FieldMetaData#addStructMetaDataMap(Class, Map)} from a different thread during * static initialization of the Thrift class is possible. */ public static , F extends TFieldIdEnum> Map getStructMetaDataMap(Class sClass) { // Note: Do not use synchronized on this method declaration - it leads to a deadlock. // Similarly, do not trigger sClass.newInstance() while holding a lock on structMap, // it will lead to the same deadlock. // See: https://issues.apache.org/jira/browse/THRIFT-5430 for details. if (!structMap.containsKey(sClass)) { // Load class if it hasn't been loaded try { sClass.getDeclaredConstructor().newInstance(); } catch (ReflectiveOperationException e) { throw new RuntimeException( e.getClass().getSimpleName() + " for TBase class: " + sClass.getName(), e); } } //noinspection unchecked return (Map) structMap.get(sClass); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/EnumMetaData.java0000664000175000017500000000211315165535636030114 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.TEnum; public class EnumMetaData extends FieldValueMetaData { public final Class enumClass; public EnumMetaData(byte type, Class sClass) { super(type); this.enumClass = sClass; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/FieldValueMetaData.java0000664000175000017500000000367515165535636031246 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.protocol.TType; /** * FieldValueMetaData and collection of subclasses to store metadata about the value(s) of a field */ public class FieldValueMetaData implements java.io.Serializable { public final byte type; private final boolean isTypedefType; private final String typedefName; private final boolean isBinary; public FieldValueMetaData(byte type, boolean binary) { this.type = type; this.isTypedefType = false; this.typedefName = null; this.isBinary = binary; } public FieldValueMetaData(byte type) { this(type, false); } public FieldValueMetaData(byte type, String typedefName) { this.type = type; this.isTypedefType = true; this.typedefName = typedefName; this.isBinary = false; } public boolean isTypedef() { return isTypedefType; } public String getTypedefName() { return typedefName; } public boolean isStruct() { return type == TType.STRUCT; } public boolean isContainer() { return type == TType.LIST || type == TType.MAP || type == TType.SET; } public boolean isBinary() { return isBinary; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/MapMetaData.java0000664000175000017500000000223515165535636027732 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; public class MapMetaData extends FieldValueMetaData { public final FieldValueMetaData keyMetaData; public final FieldValueMetaData valueMetaData; public MapMetaData(byte type, FieldValueMetaData kMetaData, FieldValueMetaData vMetaData) { super(type); this.keyMetaData = kMetaData; this.valueMetaData = vMetaData; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/ListMetaData.java0000664000175000017500000000205615165535636030131 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; public class ListMetaData extends FieldValueMetaData { public final FieldValueMetaData elemMetaData; public ListMetaData(byte type, FieldValueMetaData eMetaData) { super(type); this.elemMetaData = eMetaData; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/StructMetaData.java0000664000175000017500000000212315165535636030475 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.TBase; public class StructMetaData extends FieldValueMetaData { public final Class structClass; public StructMetaData(byte type, Class sClass) { super(type); this.structClass = sClass; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/meta_data/SetMetaData.java0000664000175000017500000000205415165535636027747 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; public class SetMetaData extends FieldValueMetaData { public final FieldValueMetaData elemMetaData; public SetMetaData(byte type, FieldValueMetaData eMetaData) { super(type); this.elemMetaData = eMetaData; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/0000775000175000017500000000000015167543515024666 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolUtil.java0000664000175000017500000001556315165535636030331 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; /** Utility class with static methods for interacting with protocol data streams. */ public class TProtocolUtil { // no instantiation private TProtocolUtil() {} /** The maximum recursive depth the skip() function will traverse before throwing a TException. */ private static int maxSkipDepth = Integer.MAX_VALUE; /** * Specifies the maximum recursive depth that the skip function will traverse before throwing a * TException. This is a global setting, so any call to skip in this JVM will enforce this value. * * @param depth the maximum recursive depth. A value of 2 would allow the skip function to skip a * structure or collection with basic children, but it would not permit skipping a struct that * had a field containing a child struct. A value of 1 would only allow skipping of simple * types and empty structs/collections. */ public static void setMaxSkipDepth(int depth) { maxSkipDepth = depth; } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be interpreted as this TType value. */ public static void skip(TProtocol prot, byte type) throws TException { skip(prot, type, maxSkipDepth); } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be interpreted as this TType value. * @param maxDepth this function will only skip complex objects to this recursive depth, to * prevent Java stack overflow. */ public static void skip(TProtocol prot, byte type, int maxDepth) throws TException { if (maxDepth <= 0) { throw new TException("Maximum skip depth exceeded"); } switch (type) { case TType.BOOL: prot.readBool(); break; case TType.BYTE: prot.readByte(); break; case TType.I16: prot.readI16(); break; case TType.I32: prot.readI32(); break; case TType.I64: prot.readI64(); break; case TType.UUID: prot.readUuid(); break; case TType.DOUBLE: prot.readDouble(); break; case TType.STRING: prot.readBinary(); break; case TType.STRUCT: prot.readStructBegin(); while (true) { TField field = prot.readFieldBegin(); if (field.type == TType.STOP) { break; } skip(prot, field.type, maxDepth - 1); prot.readFieldEnd(); } prot.readStructEnd(); break; case TType.MAP: TMap map = prot.readMapBegin(); for (int i = 0; i < map.size; i++) { skip(prot, map.keyType, maxDepth - 1); skip(prot, map.valueType, maxDepth - 1); } prot.readMapEnd(); break; case TType.SET: TSet set = prot.readSetBegin(); for (int i = 0; i < set.size; i++) { skip(prot, set.elemType, maxDepth - 1); } prot.readSetEnd(); break; case TType.LIST: TList list = prot.readListBegin(); for (int i = 0; i < list.size; i++) { skip(prot, list.elemType, maxDepth - 1); } prot.readListEnd(); break; default: throw new TProtocolException(TProtocolException.INVALID_DATA, "Unrecognized type " + type); } } /** * Attempt to determine the protocol used to serialize some data. * *

The guess is based on known specificities of supported protocols. In some cases, no guess * can be done, in that case we return the fallback TProtocolFactory. To be certain to correctly * detect the protocol, the first encoded field should have a field id < 256 * * @param data The serialized data to guess the protocol for. * @param fallback The TProtocol to return if no guess can be made. * @return a Class implementing TProtocolFactory which can be used to create a deserializer. */ public static TProtocolFactory guessProtocolFactory(byte[] data, TProtocolFactory fallback) { // // If the first and last bytes are opening/closing curly braces we guess the protocol as // being TJSONProtocol. // It could not be a TCompactBinary encoding for a field of type 0xb (Map) // with delta id 7 as the last byte for TCompactBinary is always 0. // if ('{' == data[0] && '}' == data[data.length - 1]) { return new TJSONProtocol.Factory(); } // // If the last byte is not 0, then it cannot be TCompactProtocol, it must be // TBinaryProtocol. // if (data[data.length - 1] != 0) { return new TBinaryProtocol.Factory(); } // // A first byte of value > 16 indicates TCompactProtocol was used, and the first byte // encodes a delta field id (id <= 15) and a field type. // if (data[0] > 0x10) { return new TCompactProtocol.Factory(); } // // If the second byte is 0 then it is a field id < 256 encoded by TBinaryProtocol. // It cannot possibly be TCompactProtocol since a value of 0 would imply a field id // of 0 as the zig zag varint encoding would end. // if (data.length > 1 && 0 == data[1]) { return new TBinaryProtocol.Factory(); } // // If bit 7 of the first byte of the field id is set then we have two choices: // 1. A field id > 63 was encoded with TCompactProtocol. // 2. A field id > 0x7fff (32767) was encoded with TBinaryProtocol and the last byte of the // serialized data is 0. // Option 2 is impossible since field ids are short and thus limited to 32767. // if (data.length > 1 && (data[1] & 0x80) != 0) { return new TCompactProtocol.Factory(); } // // The remaining case is either a field id <= 63 encoded as TCompactProtocol, // one >= 256 encoded with TBinaryProtocol with a last byte at 0, or an empty structure. // As we cannot really decide, we return the fallback protocol. // return fallback; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TType.java0000664000175000017500000000305015165535636026577 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** Type constants in the Thrift protocol. */ public final class TType { public static final byte STOP = 0; public static final byte VOID = 1; public static final byte BOOL = 2; public static final byte BYTE = 3; public static final byte DOUBLE = 4; public static final byte I16 = 6; public static final byte I32 = 8; public static final byte I64 = 10; public static final byte STRING = 11; public static final byte STRUCT = 12; public static final byte MAP = 13; public static final byte SET = 14; public static final byte LIST = 15; public static final byte UUID = 16; /** This is not part of the TBinaryProtocol spec but Java specific implementation detail */ public static final byte ENUM = -1; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TStruct.java0000664000175000017500000000210615165535636027143 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** Helper class that encapsulates struct metadata. */ public final class TStruct { public TStruct() { this(""); } public TStruct(String n) { name = n; } public final String name; public String getName() { return name; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TWriteProtocol.java0000664000175000017500000000232215165535636030473 0ustar00buildbuild00000000000000package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.util.UUID; import org.apache.thrift.TException; public interface TWriteProtocol { void writeMessageBegin(TMessage message) throws TException; void writeMessageEnd() throws TException; void writeStructBegin(TStruct struct) throws TException; void writeStructEnd() throws TException; void writeFieldBegin(TField field) throws TException; void writeFieldEnd() throws TException; void writeFieldStop() throws TException; void writeMapBegin(TMap map) throws TException; void writeMapEnd() throws TException; void writeListBegin(TList list) throws TException; void writeListEnd() throws TException; void writeSetBegin(TSet set) throws TException; void writeSetEnd() throws TException; void writeBool(boolean b) throws TException; void writeByte(byte b) throws TException; void writeI16(short i16) throws TException; void writeI32(int i32) throws TException; void writeI64(long i64) throws TException; void writeUuid(UUID uuid) throws TException; void writeDouble(double dub) throws TException; void writeString(String str) throws TException; void writeBinary(ByteBuffer buf) throws TException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TMessage.java0000664000175000017500000000411515165535636027245 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** Helper class that encapsulates struct metadata. */ public final class TMessage { public TMessage() { this("", TType.STOP, 0); } public TMessage(String n, byte t, int s) { name = n; type = t; seqid = s; } public final String name; public final byte type; public final int seqid; public String getName() { return name; } public byte getType() { return type; } public int getSeqid() { return seqid; } @Override public String toString() { return ""; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + seqid; result = prime * result + type; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TMessage other = (TMessage) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (seqid != other.seqid) return false; if (type != other.type) return false; return true; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TCompactProtocol.java0000664000175000017500000007302015167543515030767 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.UUID; import org.apache.thrift.TException; import org.apache.thrift.partial.TFieldData; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; /** * TCompactProtocol2 is the Java implementation of the compact protocol specified in THRIFT-110. The * fundamental approach to reducing the overhead of structures is a) use variable-length integers * all over the place and b) make use of unused bits wherever possible. Your savings will obviously * vary based on the specific makeup of your structs, but in general, the more fields, nested * structures, short strings and collections, and low-value i32 and i64 fields you have, the more * benefit you'll see. */ public class TCompactProtocol extends TProtocol { private static final byte[] EMPTY_BYTES = new byte[0]; private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.wrap(EMPTY_BYTES); private static final long NO_LENGTH_LIMIT = -1; private static final TStruct ANONYMOUS_STRUCT = new TStruct(""); private static final TField TSTOP = new TField("", TType.STOP, (short) 0); private static final byte[] ttypeToCompactType = new byte[18]; static { ttypeToCompactType[TType.STOP] = TType.STOP; ttypeToCompactType[TType.BOOL] = Types.BOOLEAN_TRUE; ttypeToCompactType[TType.BYTE] = Types.BYTE; ttypeToCompactType[TType.I16] = Types.I16; ttypeToCompactType[TType.I32] = Types.I32; ttypeToCompactType[TType.I64] = Types.I64; ttypeToCompactType[TType.DOUBLE] = Types.DOUBLE; ttypeToCompactType[TType.STRING] = Types.BINARY; ttypeToCompactType[TType.LIST] = Types.LIST; ttypeToCompactType[TType.SET] = Types.SET; ttypeToCompactType[TType.MAP] = Types.MAP; ttypeToCompactType[TType.STRUCT] = Types.STRUCT; ttypeToCompactType[TType.UUID] = Types.UUID; } /** TProtocolFactory that produces TCompactProtocols. */ public static class Factory implements TProtocolFactory { private final long stringLengthLimit_; private final long containerLengthLimit_; public Factory() { this(NO_LENGTH_LIMIT, NO_LENGTH_LIMIT); } public Factory(long stringLengthLimit) { this(stringLengthLimit, NO_LENGTH_LIMIT); } public Factory(long stringLengthLimit, long containerLengthLimit) { this.containerLengthLimit_ = containerLengthLimit; this.stringLengthLimit_ = stringLengthLimit; } @Override public TProtocol getProtocol(TTransport trans) { return new TCompactProtocol(trans, stringLengthLimit_, containerLengthLimit_); } } private static final byte PROTOCOL_ID = (byte) 0x82; private static final byte VERSION = 1; private static final byte VERSION_MASK = 0x1f; // 0001 1111 private static final byte TYPE_MASK = (byte) 0xE0; // 1110 0000 private static final byte TYPE_BITS = 0x07; // 0000 0111 private static final int TYPE_SHIFT_AMOUNT = 5; /** All of the on-wire type codes. */ private static class Types { public static final byte BOOLEAN_TRUE = 0x01; public static final byte BOOLEAN_FALSE = 0x02; public static final byte BYTE = 0x03; public static final byte I16 = 0x04; public static final byte I32 = 0x05; public static final byte I64 = 0x06; public static final byte DOUBLE = 0x07; public static final byte BINARY = 0x08; public static final byte LIST = 0x09; public static final byte SET = 0x0A; public static final byte MAP = 0x0B; public static final byte STRUCT = 0x0C; public static final byte UUID = 0x0D; } /** * Used to keep track of the last field for the current and previous structs, so we can do the * delta stuff. */ private final ShortStack lastField_ = new ShortStack(15); private short lastFieldId_ = 0; /** * If we encounter a boolean field begin, save the TField here so it can have the value * incorporated. */ private TField booleanField_ = null; /** * If we read a field header, and it's a boolean field, save the boolean value here so that * readBool can use it. */ private Boolean boolValue_ = null; /** * The maximum number of bytes to read from the transport for variable-length fields (such as * strings or binary) or {@link #NO_LENGTH_LIMIT} for unlimited. */ private final long stringLengthLimit_; /** * The maximum number of elements to read from the network for containers (maps, sets, lists), or * {@link #NO_LENGTH_LIMIT} for unlimited. */ private final long containerLengthLimit_; /** * Temporary buffer used for various operations that would otherwise require a small allocation. */ private final byte[] temp = new byte[16]; /** * Create a TCompactProtocol. * * @param transport the TTransport object to read from or write to. * @param stringLengthLimit the maximum number of bytes to read for variable-length fields. * @param containerLengthLimit the maximum number of elements to read for containers. */ public TCompactProtocol(TTransport transport, long stringLengthLimit, long containerLengthLimit) { super(transport); this.stringLengthLimit_ = stringLengthLimit; this.containerLengthLimit_ = containerLengthLimit; } /** * Create a TCompactProtocol. * * @param transport the TTransport object to read from or write to. * @param stringLengthLimit the maximum number of bytes to read for variable-length fields. * @deprecated Use constructor specifying both string limit and container limit instead */ @Deprecated public TCompactProtocol(TTransport transport, long stringLengthLimit) { this(transport, stringLengthLimit, NO_LENGTH_LIMIT); } /** * Create a TCompactProtocol. * * @param transport the TTransport object to read from or write to. */ public TCompactProtocol(TTransport transport) { this(transport, NO_LENGTH_LIMIT, NO_LENGTH_LIMIT); } @Override public void reset() { lastField_.clear(); lastFieldId_ = 0; } // // Public Writing methods. // /** * Write a message header to the wire. Compact Protocol messages contain the protocol version so * we can migrate forwards in the future if need be. */ @Override public void writeMessageBegin(TMessage message) throws TException { writeByteDirect(PROTOCOL_ID); writeByteDirect((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); writeVarint32(message.seqid); writeString(message.name); } /** * Write a struct begin. This doesn't actually put anything on the wire. We use it as an * opportunity to put special placeholder markers on the field stack so we can get the field id * deltas correct. */ @Override public void writeStructBegin(TStruct struct) throws TException { lastField_.push(lastFieldId_); lastFieldId_ = 0; } /** * Write a struct end. This doesn't actually put anything on the wire. We use this as an * opportunity to pop the last field from the current struct off of the field stack. */ @Override public void writeStructEnd() throws TException { lastFieldId_ = lastField_.pop(); } /** * Write a field header containing the field id and field type. If the difference between the * current field id and the last one is small (< 15), then the field id will be encoded in the * 4 MSB as a delta. Otherwise, the field id will follow the type header as a zigzag varint. */ @Override public void writeFieldBegin(TField field) throws TException { if (field.type == TType.BOOL) { // we want to possibly include the value, so we'll wait. booleanField_ = field; } else { writeFieldBeginInternal(field, (byte) -1); } } /** * The workhorse of writeFieldBegin. It has the option of doing a 'type override' of the type * header. This is used specifically in the boolean field case. */ private void writeFieldBeginInternal(TField field, byte typeOverride) throws TException { // short lastField = lastField_.pop(); // if there's a type override, use that. byte typeToWrite = typeOverride == -1 ? getCompactType(field.type) : typeOverride; // check if we can use delta encoding for the field id if (field.id > lastFieldId_ && field.id - lastFieldId_ <= 15) { // write them together writeByteDirect((field.id - lastFieldId_) << 4 | typeToWrite); } else { // write them separate writeByteDirect(typeToWrite); writeI16(field.id); } lastFieldId_ = field.id; // lastField_.push(field.id); } /** Write the STOP symbol so we know there are no more fields in this struct. */ @Override public void writeFieldStop() throws TException { writeByteDirect(TType.STOP); } /** * Write a map header. If the map is empty, omit the key and value type headers, as we don't need * any additional information to skip it. */ @Override public void writeMapBegin(TMap map) throws TException { if (map.size == 0) { writeByteDirect(0); } else { writeVarint32(map.size); writeByteDirect(getCompactType(map.keyType) << 4 | getCompactType(map.valueType)); } } /** Write a list header. */ @Override public void writeListBegin(TList list) throws TException { writeCollectionBegin(list.elemType, list.size); } /** Write a set header. */ @Override public void writeSetBegin(TSet set) throws TException { writeCollectionBegin(set.elemType, set.size); } /** * Write a boolean value. Potentially, this could be a boolean field, in which case the field * header info isn't written yet. If so, decide what the right type header is for the value and * then write the field header. Otherwise, write a single byte. */ @Override public void writeBool(boolean b) throws TException { if (booleanField_ != null) { // we haven't written the field header yet writeFieldBeginInternal(booleanField_, b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE); booleanField_ = null; } else { // we're not part of a field, so just write the value. writeByteDirect(b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE); } } /** Write a byte. Nothing to see here! */ @Override public void writeByte(byte b) throws TException { writeByteDirect(b); } /** Write an I16 as a zigzag varint. */ @Override public void writeI16(short i16) throws TException { writeVarint32(intToZigZag(i16)); } /** Write an i32 as a zigzag varint. */ @Override public void writeI32(int i32) throws TException { writeVarint32(intToZigZag(i32)); } /** Write an i64 as a zigzag varint. */ @Override public void writeI64(long i64) throws TException { writeVarint64(longToZigzag(i64)); } /** Write a double to the wire as 8 bytes. */ @Override public void writeDouble(double dub) throws TException { fixedLongToBytes(Double.doubleToLongBits(dub), temp, 0); trans_.write(temp, 0, 8); } @Override public void writeUuid(UUID uuid) throws TException { ByteBuffer bb = ByteBuffer.wrap(temp); bb.putLong(uuid.getMostSignificantBits()); bb.putLong(uuid.getLeastSignificantBits()); trans_.write(temp, 0, 16); } /** Write a string to the wire with a varint size preceding. */ @Override public void writeString(String str) throws TException { byte[] bytes = str.getBytes(StandardCharsets.UTF_8); writeVarint32(bytes.length); trans_.write(bytes, 0, bytes.length); } /** Write a byte array, using a varint for the size. */ @Override public void writeBinary(ByteBuffer bin) throws TException { ByteBuffer bb = bin.asReadOnlyBuffer(); writeVarint32(bb.remaining()); trans_.write(bb); } // // These methods are called by structs, but don't actually have any wire // output or purpose. // @Override public void writeMessageEnd() throws TException {} @Override public void writeMapEnd() throws TException {} @Override public void writeListEnd() throws TException {} @Override public void writeSetEnd() throws TException {} @Override public void writeFieldEnd() throws TException {} // // Internal writing methods // /** * Abstract method for writing the start of lists and sets. List and sets on the wire differ only * by the type indicator. */ protected void writeCollectionBegin(byte elemType, int size) throws TException { if (size <= 14) { writeByteDirect(size << 4 | getCompactType(elemType)); } else { writeByteDirect(0xf0 | getCompactType(elemType)); writeVarint32(size); } } /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. TODO: make a permanent buffer like * writeVarint64? */ private void writeVarint32(int n) throws TException { int idx = 0; while (true) { if ((n & ~0x7F) == 0) { temp[idx++] = (byte) n; // writeByteDirect((byte)n); break; // return; } else { temp[idx++] = (byte) ((n & 0x7F) | 0x80); // writeByteDirect((byte)((n & 0x7F) | 0x80)); n >>>= 7; } } trans_.write(temp, 0, idx); } /** Write an i64 as a varint. Results in 1-10 bytes on the wire. */ private void writeVarint64(long n) throws TException { int idx = 0; while (true) { if ((n & ~0x7FL) == 0) { temp[idx++] = (byte) n; break; } else { temp[idx++] = ((byte) ((n & 0x7F) | 0x80)); n >>>= 7; } } trans_.write(temp, 0, idx); } /** * Convert l into a zigzag long. This allows negative numbers to be represented compactly as a * varint. */ private long longToZigzag(long l) { return (l << 1) ^ (l >> 63); } /** * Convert n into a zigzag int. This allows negative numbers to be represented compactly as a * varint. */ private int intToZigZag(int n) { return (n << 1) ^ (n >> 31); } /** Convert a long into little-endian bytes in buf starting at off and going until off+7. */ private void fixedLongToBytes(long n, byte[] buf, int off) { buf[off + 0] = (byte) (n & 0xff); buf[off + 1] = (byte) ((n >> 8) & 0xff); buf[off + 2] = (byte) ((n >> 16) & 0xff); buf[off + 3] = (byte) ((n >> 24) & 0xff); buf[off + 4] = (byte) ((n >> 32) & 0xff); buf[off + 5] = (byte) ((n >> 40) & 0xff); buf[off + 6] = (byte) ((n >> 48) & 0xff); buf[off + 7] = (byte) ((n >> 56) & 0xff); } /** * Writes a byte without any possibility of all that field header nonsense. Used internally by * other writing methods that know they need to write a byte. */ private void writeByteDirect(byte b) throws TException { temp[0] = b; trans_.write(temp, 0, 1); } /** Writes a byte without any possibility of all that field header nonsense. */ private void writeByteDirect(int n) throws TException { writeByteDirect((byte) n); } // // Reading methods. // /** Read a message header. */ @Override public TMessage readMessageBegin() throws TException { byte protocolId = readByte(); if (protocolId != PROTOCOL_ID) { throw new TProtocolException( "Expected protocol id " + Integer.toHexString(PROTOCOL_ID) + " but got " + Integer.toHexString(protocolId)); } byte versionAndType = readByte(); byte version = (byte) (versionAndType & VERSION_MASK); if (version != VERSION) { throw new TProtocolException("Expected version " + VERSION + " but got " + version); } byte type = (byte) ((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); int seqid = readVarint32(); String messageName = readString(); return new TMessage(messageName, type, seqid); } /** * Read a struct begin. There's nothing on the wire for this, but it is our opportunity to push a * new struct begin marker onto the field stack. */ @Override public TStruct readStructBegin() throws TException { lastField_.push(lastFieldId_); lastFieldId_ = 0; return ANONYMOUS_STRUCT; } /** * Doesn't actually consume any wire data, just removes the last field for this struct from the * field stack. */ @Override public void readStructEnd() throws TException { // consume the last field we read off the wire. lastFieldId_ = lastField_.pop(); } /** Read a field header off the wire. */ @Override public TField readFieldBegin() throws TException { byte type = readByte(); // if it's a stop, then we can return immediately, as the struct is over. if (type == TType.STOP) { return TSTOP; } return new TField("", getTType((byte) (type & 0x0f)), readFieldId(type)); } /** * Read a map header off the wire. If the size is zero, skip reading the key and value type. This * means that 0-length maps will yield TMaps without the "correct" types. */ @Override public TMap readMapBegin() throws TException { int size = readVarint32(); checkContainerReadLength(size); byte keyAndValueType = size == 0 ? 0 : readByte(); TMap map = new TMap( getTType((byte) (keyAndValueType >> 4)), getTType((byte) (keyAndValueType & 0xf)), size); checkReadBytesAvailable(map); return map; } /** * Read a list header off the wire. If the list size is 0-14, the size will be packed into the * element type header. If it's a longer list, the 4 MSB of the element type header will be 0xF, * and a varint will follow with the true size. */ @Override public TList readListBegin() throws TException { byte size_and_type = readByte(); int size = (size_and_type >> 4) & 0x0f; if (size == 15) { size = readVarint32(); } checkContainerReadLength(size); TList list = new TList(getTType(size_and_type), size); checkReadBytesAvailable(list); return list; } /** * Read a set header off the wire. If the set size is 0-14, the size will be packed into the * element type header. If it's a longer set, the 4 MSB of the element type header will be 0xF, * and a varint will follow with the true size. */ @Override public TSet readSetBegin() throws TException { return new TSet(readListBegin()); } /** * Read a boolean off the wire. If this is a boolean field, the value should already have been * read during readFieldBegin, so we'll just consume the pre-stored value. Otherwise, read a byte. */ @Override public boolean readBool() throws TException { if (boolValue_ != null) { boolean result = boolValue_; boolValue_ = null; return result; } return readByte() == Types.BOOLEAN_TRUE; } /** Read a single byte off the wire. Nothing interesting here. */ @Override public byte readByte() throws TException { byte b; if (trans_.getBytesRemainingInBuffer() > 0) { b = trans_.getBuffer()[trans_.getBufferPosition()]; trans_.consumeBuffer(1); } else { trans_.readAll(temp, 0, 1); b = temp[0]; } return b; } /** Read an i16 from the wire as a zigzag varint. */ @Override public short readI16() throws TException { return (short) zigzagToInt(readVarint32()); } /** Read an i32 from the wire as a zigzag varint. */ @Override public int readI32() throws TException { return zigzagToInt(readVarint32()); } /** Read an i64 from the wire as a zigzag varint. */ @Override public long readI64() throws TException { return zigzagToLong(readVarint64()); } /** No magic here - just read a double off the wire. */ @Override public double readDouble() throws TException { trans_.readAll(temp, 0, 8); return Double.longBitsToDouble(bytesToLong(temp)); } @Override public UUID readUuid() throws TException { trans_.readAll(temp, 0, 16); ByteBuffer bb = ByteBuffer.wrap(temp, 0, 16); return new UUID(bb.getLong(), bb.getLong()); } /** Reads a byte[] (via readBinary), and then UTF-8 decodes it. */ @Override public String readString() throws TException { int length = readVarint32(); checkStringReadLength(length); if (length == 0) { return ""; } final String str; if (trans_.getBytesRemainingInBuffer() >= length) { str = new String( trans_.getBuffer(), trans_.getBufferPosition(), length, StandardCharsets.UTF_8); trans_.consumeBuffer(length); } else { str = new String(readBinary(length), StandardCharsets.UTF_8); } return str; } /** Read a ByteBuffer from the wire. */ @Override public ByteBuffer readBinary() throws TException { int length = readVarint32(); if (length == 0) { return EMPTY_BUFFER; } getTransport().checkReadBytesAvailable(length); if (trans_.getBytesRemainingInBuffer() >= length) { ByteBuffer bb = ByteBuffer.wrap(trans_.getBuffer(), trans_.getBufferPosition(), length); trans_.consumeBuffer(length); return bb; } byte[] buf = new byte[length]; trans_.readAll(buf, 0, length); return ByteBuffer.wrap(buf); } /** Read a byte[] of a known length from the wire. */ private byte[] readBinary(int length) throws TException { if (length == 0) return EMPTY_BYTES; byte[] buf = new byte[length]; trans_.readAll(buf, 0, length); return buf; } private void checkStringReadLength(int length) throws TException { if (length < 0) { throw new TProtocolException(TProtocolException.NEGATIVE_SIZE, "Negative length: " + length); } getTransport().checkReadBytesAvailable(length); if (stringLengthLimit_ != NO_LENGTH_LIMIT && length > stringLengthLimit_) { throw new TProtocolException( TProtocolException.SIZE_LIMIT, "Length exceeded max allowed: " + length); } } private void checkContainerReadLength(int length) throws TProtocolException { if (length < 0) { throw new TProtocolException(TProtocolException.NEGATIVE_SIZE, "Negative length: " + length); } if (containerLengthLimit_ != NO_LENGTH_LIMIT && length > containerLengthLimit_) { throw new TProtocolException( TProtocolException.SIZE_LIMIT, "Length exceeded max allowed: " + length); } } // // These methods are here for the struct to call, but don't have any wire // encoding. // @Override public void readMessageEnd() throws TException {} @Override public void readFieldEnd() throws TException {} @Override public void readMapEnd() throws TException {} @Override public void readListEnd() throws TException {} @Override public void readSetEnd() throws TException {} // // Internal reading methods // /** * 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. */ private int readVarint32() throws TException { int result = 0; int shift = 0; if (trans_.getBytesRemainingInBuffer() >= 5) { byte[] buf = trans_.getBuffer(); int pos = trans_.getBufferPosition(); int off = 0; while (true) { byte b = buf[pos + off]; result |= (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; off++; } trans_.consumeBuffer(off + 1); } else { while (true) { byte b = readByte(); result |= (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; } } return result; } /** * 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. */ private long readVarint64() throws TException { int shift = 0; long result = 0; if (trans_.getBytesRemainingInBuffer() >= 10) { byte[] buf = trans_.getBuffer(); int pos = trans_.getBufferPosition(); int off = 0; while (true) { byte b = buf[pos + off]; result |= (long) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; off++; } trans_.consumeBuffer(off + 1); } else { while (true) { byte b = readByte(); result |= (long) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; } } return result; } // // encoding helpers // /** Convert from zigzag int to int. */ private int zigzagToInt(int n) { return (n >>> 1) ^ -(n & 1); } /** Convert from zigzag long to long. */ private long zigzagToLong(long n) { return (n >>> 1) ^ -(n & 1); } /** * Note that it's important that the mask bytes are long literals, otherwise they'll default to * ints, and when you shift an int left 56 bits, you just get a messed up int. */ private long bytesToLong(byte[] bytes) { return bytesToLong(bytes, 0); } private long bytesToLong(byte[] bytes, int offset) { return ((bytes[offset + 7] & 0xffL) << 56) | ((bytes[offset + 6] & 0xffL) << 48) | ((bytes[offset + 5] & 0xffL) << 40) | ((bytes[offset + 4] & 0xffL) << 32) | ((bytes[offset + 3] & 0xffL) << 24) | ((bytes[offset + 2] & 0xffL) << 16) | ((bytes[offset + 1] & 0xffL) << 8) | ((bytes[offset + 0] & 0xffL)); } // // type testing and converting // private boolean isBoolType(byte b) { int lowerNibble = b & 0x0f; return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE; } /** Given a TCompactProtocol.Types constant, convert it to its corresponding TType value. */ private byte getTType(byte type) throws TProtocolException { switch ((byte) (type & 0x0f)) { case TType.STOP: return TType.STOP; case Types.BOOLEAN_FALSE: case Types.BOOLEAN_TRUE: return TType.BOOL; case Types.BYTE: return TType.BYTE; case Types.I16: return TType.I16; case Types.I32: return TType.I32; case Types.I64: return TType.I64; case Types.UUID: return TType.UUID; case Types.DOUBLE: return TType.DOUBLE; case Types.BINARY: return TType.STRING; case Types.LIST: return TType.LIST; case Types.SET: return TType.SET; case Types.MAP: return TType.MAP; case Types.STRUCT: return TType.STRUCT; default: throw new TProtocolException("don't know what type: " + (byte) (type & 0x0f)); } } /** Given a TType value, find the appropriate TCompactProtocol.Types constant. */ private byte getCompactType(byte ttype) { return ttypeToCompactType[ttype]; } /** Return the minimum number of bytes a type will consume on the wire */ @Override public int getMinSerializedSize(byte type) throws TTransportException { switch (type) { case 0: return 1; // Stop - T_STOP needs to count itself case 1: return 1; // Void - T_VOID needs to count itself case 2: return 1; // Bool sizeof(byte) case 3: return 1; // Byte sizeof(byte) case 4: return 8; // Double sizeof(double) case 6: return 1; // I16 sizeof(byte) case 8: return 1; // I32 sizeof(byte) case 10: return 1; // I64 sizeof(byte) case 11: return 1; // string length sizeof(byte) case 12: return 1; // empty struct needs at least 1 byte for the T_STOP case 13: return 1; // element count Map sizeof(byte) case 14: return 1; // element count Set sizeof(byte) case 15: return 1; // element count List sizeof(byte) default: throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code"); } } // ----------------------------------------------------------------- // Additional methods to improve performance. @Override public int readFieldBeginData() throws TException { byte type = readByte(); // if it's a stop, then we can return immediately, as the struct is over. if (type == TType.STOP) { return TFieldData.encode(type); } return TFieldData.encode(getTType((byte) (type & 0x0f)), readFieldId(type)); } // Only makes sense to be called by readFieldBegin and readFieldBeginData private short readFieldId(byte type) throws TException { short fieldId; // mask off the 4 MSB of the type header. it could contain a field id delta. short modifier = (short) ((type & 0xf0) >> 4); if (modifier == 0) { // not a delta. look ahead for the zigzag varint field id. fieldId = readI16(); } else { // has a delta. add the delta to the last read field id. fieldId = (short) (lastFieldId_ + modifier); } // if this happens to be a boolean field, the value is encoded in the type if (isBoolType(type)) { // save the boolean value in a special instance variable. boolValue_ = (byte) (type & 0x0f) == Types.BOOLEAN_TRUE ? Boolean.TRUE : Boolean.FALSE; } // push the new field onto the field stack so we can keep the deltas going. lastFieldId_ = fieldId; return fieldId; } @Override protected void skipBinary() throws TException { int size = intToZigZag(readI32()); this.skipBytes(size); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolException.java0000664000175000017500000000404215165535636031340 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; /** Protocol exceptions. */ public class TProtocolException extends TException { private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int INVALID_DATA = 1; public static final int NEGATIVE_SIZE = 2; public static final int SIZE_LIMIT = 3; public static final int BAD_VERSION = 4; public static final int NOT_IMPLEMENTED = 5; public static final int DEPTH_LIMIT = 6; protected int type_ = UNKNOWN; public TProtocolException() { super(); } public TProtocolException(int type) { super(); type_ = type; } public TProtocolException(int type, String message) { super(message); type_ = type; } public TProtocolException(String message) { super(message); } public TProtocolException(int type, Throwable cause) { super(cause); type_ = type; } public TProtocolException(Throwable cause) { super(cause); } public TProtocolException(String message, Throwable cause) { super(message, cause); } public TProtocolException(int type, String message, Throwable cause) { super(message, cause); type_ = type; } public int getType() { return type_; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TLegacyUuidProtocolDecorator.java0000664000175000017500000000670115167543515033301 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.util.UUID; import org.apache.thrift.TException; /** * The TLegacyUuidProtocolDecorator that decorates an existing TProtocol to provide backwards * compatibility with the old UUID format that the Java library used on the wire. * *

The initial UUID implementation in Java was not according to the protocol specification. This * was fixed in THRIFT-5925 and as a result would break backwards compatibility with existing * implementations that depends on that format. * *

This decorator is especially useful where migration is not needed and interop between other * languages, that follows the specification, are not needed. * *

For usage see the TestTLegacyUuidProtocolDecorator tests. */ public class TLegacyUuidProtocolDecorator extends TProtocolDecorator { public TLegacyUuidProtocolDecorator(TProtocol protocol) { super(protocol); } @Override public void writeUuid(UUID uuid) throws TException { byte[] buf = new byte[16]; long lsb = uuid.getLeastSignificantBits(); buf[0] = (byte) (0xff & (lsb >> 56)); buf[1] = (byte) (0xff & (lsb >> 48)); buf[2] = (byte) (0xff & (lsb >> 40)); buf[3] = (byte) (0xff & (lsb >> 32)); buf[4] = (byte) (0xff & (lsb >> 24)); buf[5] = (byte) (0xff & (lsb >> 16)); buf[6] = (byte) (0xff & (lsb >> 8)); buf[7] = (byte) (0xff & (lsb)); long msb = uuid.getMostSignificantBits(); buf[8] = (byte) (0xff & (msb >> 56)); buf[9] = (byte) (0xff & (msb >> 48)); buf[10] = (byte) (0xff & (msb >> 40)); buf[11] = (byte) (0xff & (msb >> 32)); buf[12] = (byte) (0xff & (msb >> 24)); buf[13] = (byte) (0xff & (msb >> 16)); buf[14] = (byte) (0xff & (msb >> 8)); buf[15] = (byte) (0xff & (msb)); getTransport().write(buf, 0, 16); } @Override public UUID readUuid() throws TException { byte[] buf = new byte[16]; getTransport().readAll(buf, 0, 16); long lsb = ((long) (buf[0] & 0xff) << 56) | ((long) (buf[1] & 0xff) << 48) | ((long) (buf[2] & 0xff) << 40) | ((long) (buf[3] & 0xff) << 32) | ((long) (buf[4] & 0xff) << 24) | ((long) (buf[5] & 0xff) << 16) | ((long) (buf[6] & 0xff) << 8) | ((long) (buf[7] & 0xff)); long msb = ((long) (buf[8] & 0xff) << 56) | ((long) (buf[9] & 0xff) << 48) | ((long) (buf[10] & 0xff) << 40) | ((long) (buf[11] & 0xff) << 32) | ((long) (buf[12] & 0xff) << 24) | ((long) (buf[13] & 0xff) << 16) | ((long) (buf[14] & 0xff) << 8) | ((long) (buf[15] & 0xff)); return new UUID(msb, lsb); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TSimpleJSONProtocol.java0000664000175000017500000003166315165535636031336 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Stack; import java.util.UUID; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; /** * JSON protocol implementation for thrift. * *

This protocol is write-only and produces a simple output format suitable for parsing by * scripting languages. It should not be confused with the full-featured TJSONProtocol. */ public class TSimpleJSONProtocol extends TProtocol { /** Factory */ public static class Factory implements TProtocolFactory { @Override public TProtocol getProtocol(TTransport trans) { return new TSimpleJSONProtocol(trans); } } private static final byte[] COMMA = new byte[] {','}; private static final byte[] COLON = new byte[] {':'}; private static final byte[] LBRACE = new byte[] {'{'}; private static final byte[] RBRACE = new byte[] {'}'}; private static final byte[] LBRACKET = new byte[] {'['}; private static final byte[] RBRACKET = new byte[] {']'}; private static final char QUOTE = '"'; private static final String LIST = "list"; private static final String SET = "set"; private static final String MAP = "map"; protected static class Context { protected void write() throws TException {} /** Returns whether the current value is a key in a map */ protected boolean isMapKey() { return false; } } protected class ListContext extends Context { protected boolean first_ = true; protected void write() throws TException { if (first_) { first_ = false; } else { trans_.write(COMMA); } } } protected class StructContext extends Context { protected boolean first_ = true; protected boolean colon_ = true; protected void write() throws TException { if (first_) { first_ = false; colon_ = true; } else { trans_.write(colon_ ? COLON : COMMA); colon_ = !colon_; } } } protected class MapContext extends StructContext { protected boolean isKey = true; @Override protected void write() throws TException { super.write(); isKey = !isKey; } protected boolean isMapKey() { // we want to coerce map keys to json strings regardless // of their type return isKey; } } protected final Context BASE_CONTEXT = new Context(); /** Stack of nested contexts that we may be in. */ protected Stack writeContextStack_ = new Stack(); /** Current context that we are in */ protected Context writeContext_ = BASE_CONTEXT; /** Push a new write context onto the stack. */ protected void pushWriteContext(Context c) { writeContextStack_.push(writeContext_); writeContext_ = c; } /** Pop the last write context off the stack */ protected void popWriteContext() { writeContext_ = writeContextStack_.pop(); } /** Reset the write context stack to its initial state. */ protected void resetWriteContext() { while (!writeContextStack_.isEmpty()) { popWriteContext(); } } /** Used to make sure that we are not encountering a map whose keys are containers */ protected void assertContextIsNotMapKey(String invalidKeyType) throws CollectionMapKeyException { if (writeContext_.isMapKey()) { throw new CollectionMapKeyException( "Cannot serialize a map with keys that are of type " + invalidKeyType); } } /** Constructor */ public TSimpleJSONProtocol(TTransport trans) { super(trans); } @Override public void writeMessageBegin(TMessage message) throws TException { resetWriteContext(); // THRIFT-3743 trans_.write(LBRACKET); pushWriteContext(new ListContext()); writeString(message.name); writeByte(message.type); writeI32(message.seqid); } @Override public void writeMessageEnd() throws TException { popWriteContext(); trans_.write(RBRACKET); } @Override public void writeStructBegin(TStruct struct) throws TException { writeContext_.write(); trans_.write(LBRACE); pushWriteContext(new StructContext()); } @Override public void writeStructEnd() throws TException { popWriteContext(); trans_.write(RBRACE); } @Override public void writeFieldBegin(TField field) throws TException { // Note that extra type information is omitted in JSON! writeString(field.name); } @Override public void writeFieldEnd() throws TException {} @Override public void writeFieldStop() throws TException {} @Override public void writeMapBegin(TMap map) throws TException { assertContextIsNotMapKey(MAP); writeContext_.write(); trans_.write(LBRACE); pushWriteContext(new MapContext()); // No metadata! } @Override public void writeMapEnd() throws TException { popWriteContext(); trans_.write(RBRACE); } @Override public void writeListBegin(TList list) throws TException { assertContextIsNotMapKey(LIST); writeContext_.write(); trans_.write(LBRACKET); pushWriteContext(new ListContext()); // No metadata! } @Override public void writeListEnd() throws TException { popWriteContext(); trans_.write(RBRACKET); } @Override public void writeSetBegin(TSet set) throws TException { assertContextIsNotMapKey(SET); writeContext_.write(); trans_.write(LBRACKET); pushWriteContext(new ListContext()); // No metadata! } @Override public void writeSetEnd() throws TException { popWriteContext(); trans_.write(RBRACKET); } @Override public void writeBool(boolean b) throws TException { writeByte(b ? (byte) 1 : (byte) 0); } @Override public void writeByte(byte b) throws TException { writeI32(b); } @Override public void writeI16(short i16) throws TException { writeI32(i16); } @Override public void writeI32(int i32) throws TException { if (writeContext_.isMapKey()) { writeString(Integer.toString(i32)); } else { writeContext_.write(); _writeStringData(Integer.toString(i32)); } } public void _writeStringData(String s) throws TException { byte[] b = s.getBytes(StandardCharsets.UTF_8); trans_.write(b); } @Override public void writeI64(long i64) throws TException { if (writeContext_.isMapKey()) { writeString(Long.toString(i64)); } else { writeContext_.write(); _writeStringData(Long.toString(i64)); } } @Override public void writeUuid(UUID uuid) throws TException { writeString(uuid.toString()); } @Override public void writeDouble(double dub) throws TException { if (writeContext_.isMapKey()) { writeString(Double.toString(dub)); } else { writeContext_.write(); _writeStringData(Double.toString(dub)); } } @Override public void writeString(String str) throws TException { writeContext_.write(); int length = str.length(); StringBuilder escape = new StringBuilder(length + 16); escape.append(QUOTE); for (int i = 0; i < length; ++i) { char c = str.charAt(i); switch (c) { case '"': case '\\': escape.append('\\'); escape.append(c); break; case '\b': escape.append('\\'); escape.append('b'); break; case '\f': escape.append('\\'); escape.append('f'); break; case '\n': escape.append('\\'); escape.append('n'); break; case '\r': escape.append('\\'); escape.append('r'); break; case '\t': escape.append('\\'); escape.append('t'); break; default: // Control characters! According to JSON RFC u0020 (space) if (c < ' ') { String hex = Integer.toHexString(c); escape.append('\\'); escape.append('u'); for (int j = 4; j > hex.length(); --j) { escape.append('0'); } escape.append(hex); } else { escape.append(c); } break; } } escape.append(QUOTE); _writeStringData(escape.toString()); } @Override public void writeBinary(ByteBuffer bin) throws TException { // TODO(mcslee): Fix this writeString( new String( bin.array(), bin.position() + bin.arrayOffset(), bin.limit() - bin.position() - bin.arrayOffset(), StandardCharsets.UTF_8)); } /** * Reading methods. * *

simplejson is not meant to be read back into thrift - see ThriftUsageJava - use JSON instead */ @Override public TMessage readMessageBegin() throws TException { throw new TException("Not implemented"); } @Override public void readMessageEnd() throws TException { throw new TException("Not implemented"); } @Override public TStruct readStructBegin() throws TException { throw new TException("Not implemented"); } @Override public void readStructEnd() throws TException { throw new TException("Not implemented"); } @Override public TField readFieldBegin() throws TException { throw new TException("Not implemented"); } @Override public void readFieldEnd() throws TException { throw new TException("Not implemented"); } @Override public TMap readMapBegin() throws TException { throw new TException("Not implemented"); } @Override public void readMapEnd() throws TException { throw new TException("Not implemented"); } @Override public TList readListBegin() throws TException { throw new TException("Not implemented"); } @Override public void readListEnd() throws TException { throw new TException("Not implemented"); } @Override public TSet readSetBegin() throws TException { throw new TException("Not implemented"); } @Override public void readSetEnd() throws TException { throw new TException("Not implemented"); } @Override public boolean readBool() throws TException { throw new TException("Not implemented"); } @Override public byte readByte() throws TException { throw new TException("Not implemented"); } @Override public short readI16() throws TException { throw new TException("Not implemented"); } @Override public int readI32() throws TException { throw new TException("Not implemented"); } @Override public long readI64() throws TException { throw new TException("Not implemented"); } @Override public UUID readUuid() throws TException { throw new TException("Not implemented"); } @Override public double readDouble() throws TException { throw new TException("Not implemented"); } @Override public String readString() throws TException { throw new TException("Not implemented"); } public String readStringBody(int size) throws TException { throw new TException("Not implemented"); } @Override public ByteBuffer readBinary() throws TException { throw new TException("Not implemented"); } public static class CollectionMapKeyException extends TException { public CollectionMapKeyException(String message) { super(message); } } /** Return the minimum number of bytes a type will consume on the wire */ @Override public int getMinSerializedSize(byte type) throws TException { switch (type) { case 0: return 1; // Stop - T_STOP needs to count itself case 1: return 1; // Void - T_VOID needs to count itself case 2: return 1; // Bool case 3: return 1; // Byte case 4: return 1; // Double case 6: return 1; // I16 case 8: return 1; // I32 case 10: return 1; // I64 case 11: return 2; // string length case 12: return 2; // empty struct case 13: return 2; // element count Map case 14: return 2; // element count Set case 15: return 2; // element count List default: throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code"); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolDecorator.java0000664000175000017500000001700515167543515031324 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.util.UUID; import org.apache.thrift.TException; /** * TProtocolDecorator forwards all requests to an enclosed TProtocol * instance, providing a way to author concise concrete decorator subclasses. While it has no * abstract methods, it is marked abstract as a reminder that by itself, it does not modify the * behaviour of the enclosed TProtocol. * *

See p.175 of Design Patterns (by Gamma et al.) * * @see org.apache.thrift.protocol.TMultiplexedProtocol */ public abstract class TProtocolDecorator extends TProtocol { private final TProtocol concreteProtocol; /** * Encloses the specified protocol. * * @param protocol All operations will be forward to this protocol. Must be non-null. */ public TProtocolDecorator(TProtocol protocol) { super(protocol.getTransport()); concreteProtocol = protocol; } @Override public void writeMessageBegin(TMessage tMessage) throws TException { concreteProtocol.writeMessageBegin(tMessage); } @Override public void writeMessageEnd() throws TException { concreteProtocol.writeMessageEnd(); } @Override public void writeStructBegin(TStruct tStruct) throws TException { concreteProtocol.writeStructBegin(tStruct); } @Override public UUID readUuid() throws TException { return concreteProtocol.readUuid(); } @Override public void writeUuid(UUID uuid) throws TException { concreteProtocol.writeUuid(uuid); } @Override public void writeStructEnd() throws TException { concreteProtocol.writeStructEnd(); } @Override public void writeFieldBegin(TField tField) throws TException { concreteProtocol.writeFieldBegin(tField); } @Override public void writeFieldEnd() throws TException { concreteProtocol.writeFieldEnd(); } @Override public void writeFieldStop() throws TException { concreteProtocol.writeFieldStop(); } @Override public void writeMapBegin(TMap tMap) throws TException { concreteProtocol.writeMapBegin(tMap); } @Override public void writeMapEnd() throws TException { concreteProtocol.writeMapEnd(); } @Override public void writeListBegin(TList tList) throws TException { concreteProtocol.writeListBegin(tList); } @Override public void writeListEnd() throws TException { concreteProtocol.writeListEnd(); } @Override public void writeSetBegin(TSet tSet) throws TException { concreteProtocol.writeSetBegin(tSet); } @Override public void writeSetEnd() throws TException { concreteProtocol.writeSetEnd(); } @Override public void writeBool(boolean b) throws TException { concreteProtocol.writeBool(b); } @Override public void writeByte(byte b) throws TException { concreteProtocol.writeByte(b); } @Override public void writeI16(short i) throws TException { concreteProtocol.writeI16(i); } @Override public void writeI32(int i) throws TException { concreteProtocol.writeI32(i); } @Override public void writeI64(long l) throws TException { concreteProtocol.writeI64(l); } @Override public void writeDouble(double v) throws TException { concreteProtocol.writeDouble(v); } @Override public void writeString(String s) throws TException { concreteProtocol.writeString(s); } @Override public void writeBinary(ByteBuffer buf) throws TException { concreteProtocol.writeBinary(buf); } @Override public TMessage readMessageBegin() throws TException { return concreteProtocol.readMessageBegin(); } @Override public void readMessageEnd() throws TException { concreteProtocol.readMessageEnd(); } @Override public TStruct readStructBegin() throws TException { return concreteProtocol.readStructBegin(); } @Override public void readStructEnd() throws TException { concreteProtocol.readStructEnd(); } @Override public TField readFieldBegin() throws TException { return concreteProtocol.readFieldBegin(); } @Override public void readFieldEnd() throws TException { concreteProtocol.readFieldEnd(); } @Override public TMap readMapBegin() throws TException { return concreteProtocol.readMapBegin(); } @Override public void readMapEnd() throws TException { concreteProtocol.readMapEnd(); } @Override public TList readListBegin() throws TException { return concreteProtocol.readListBegin(); } @Override public void readListEnd() throws TException { concreteProtocol.readListEnd(); } @Override public TSet readSetBegin() throws TException { return concreteProtocol.readSetBegin(); } @Override public void readSetEnd() throws TException { concreteProtocol.readSetEnd(); } @Override public boolean readBool() throws TException { return concreteProtocol.readBool(); } @Override public byte readByte() throws TException { return concreteProtocol.readByte(); } @Override public short readI16() throws TException { return concreteProtocol.readI16(); } @Override public int readI32() throws TException { return concreteProtocol.readI32(); } @Override public long readI64() throws TException { return concreteProtocol.readI64(); } @Override public double readDouble() throws TException { return concreteProtocol.readDouble(); } @Override public String readString() throws TException { return concreteProtocol.readString(); } @Override public ByteBuffer readBinary() throws TException { return concreteProtocol.readBinary(); } @Override public int readFieldBeginData() throws TException { return concreteProtocol.readFieldBeginData(); } @Override protected void skipBool() throws TException { concreteProtocol.skipBool(); } @Override protected void skipByte() throws TException { concreteProtocol.skipByte(); } @Override protected void skipI16() throws TException { concreteProtocol.skipI16(); } @Override protected void skipI32() throws TException { concreteProtocol.skipI32(); } @Override protected void skipI64() throws TException { concreteProtocol.skipI64(); } @Override protected void skipDouble() throws TException { concreteProtocol.skipDouble(); } @Override protected void skipBinary() throws TException { concreteProtocol.skipBinary(); } /** * @param type Returns the minimum amount of bytes needed to store the smallest possible instance * of TType. * @return size * @throws TException if underlying protocol throws */ @Override public int getMinSerializedSize(byte type) throws TException { return concreteProtocol.getMinSerializedSize(type); } @Override public void reset() { concreteProtocol.reset(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/ShortStack.java0000664000175000017500000000403615165535636027624 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.util.Arrays; /** * ShortStack is a short-specific Stack implementation written for the express purpose of very fast * operations on TCompactProtocol's field id stack. This implementation performs at least 10x faster * than java.util.Stack. */ class ShortStack { private short[] vector; /** Always points to the next location */ private int top = 0; public ShortStack(int initialCapacity) { vector = new short[initialCapacity]; } public short pop() { return vector[--top]; } public void push(short pushed) { if (vector.length == top) { grow(); } vector[top++] = pushed; } private void grow() { vector = Arrays.copyOf(vector, vector.length << 1); } public void clear() { top = 0; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(">").append(value).append("<<"); } else { sb.append(value); } } sb.append("]>"); return sb.toString(); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TField.java0000664000175000017500000000340515165535636026705 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates field metadata. * *

Two fields are considered equal if they have the same type and id. */ public class TField { public TField() { this("", TType.STOP, (short) 0); } public TField(String n, byte t, short i) { name = n; type = t; id = i; } public final String name; public final byte type; public final short id; public String toString() { return ""; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + type; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TField otherField = (TField) obj; return type == otherField.type && id == otherField.id; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TJSONProtocol.java0000664000175000017500000006755615165535636030176 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Stack; import java.util.UUID; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; /** * JSON protocol implementation for thrift. * *

This is a full-featured protocol supporting write and read. * *

Please see the C++ class header for a detailed description of the protocol's wire format. */ public class TJSONProtocol extends TProtocol { /** Factory for JSON protocol objects */ public static class Factory implements TProtocolFactory { protected boolean fieldNamesAsString_ = false; public Factory() {} public Factory(boolean fieldNamesAsString) { fieldNamesAsString_ = fieldNamesAsString; } public TProtocol getProtocol(TTransport trans) { return new TJSONProtocol(trans, fieldNamesAsString_); } } private static final byte[] COMMA = new byte[] {','}; private static final byte[] COLON = new byte[] {':'}; private static final byte[] LBRACE = new byte[] {'{'}; private static final byte[] RBRACE = new byte[] {'}'}; private static final byte[] LBRACKET = new byte[] {'['}; private static final byte[] RBRACKET = new byte[] {']'}; private static final byte[] QUOTE = new byte[] {'"'}; private static final byte[] BACKSLASH = new byte[] {'\\'}; private static final byte[] ESCSEQ = new byte[] {'\\', 'u', '0', '0'}; private static final long VERSION = 1; private static final byte[] JSON_CHAR_TABLE = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 }; private static final String ESCAPE_CHARS = "\"\\/bfnrt"; private static final byte[] ESCAPE_CHAR_VALS = { '"', '\\', '/', '\b', '\f', '\n', '\r', '\t', }; private static final int DEF_STRING_SIZE = 16; private static final byte[] NAME_BOOL = new byte[] {'t', 'f'}; private static final byte[] NAME_BYTE = new byte[] {'i', '8'}; private static final byte[] NAME_I16 = new byte[] {'i', '1', '6'}; private static final byte[] NAME_I32 = new byte[] {'i', '3', '2'}; private static final byte[] NAME_I64 = new byte[] {'i', '6', '4'}; private static final byte[] NAME_UUID = new byte[] {'u', 'i', 'd'}; private static final byte[] NAME_DOUBLE = new byte[] {'d', 'b', 'l'}; private static final byte[] NAME_STRUCT = new byte[] {'r', 'e', 'c'}; private static final byte[] NAME_STRING = new byte[] {'s', 't', 'r'}; private static final byte[] NAME_MAP = new byte[] {'m', 'a', 'p'}; private static final byte[] NAME_LIST = new byte[] {'l', 's', 't'}; private static final byte[] NAME_SET = new byte[] {'s', 'e', 't'}; private static final TStruct ANONYMOUS_STRUCT = new TStruct(); private static byte[] getTypeNameForTypeID(byte typeID) throws TException { switch (typeID) { case TType.BOOL: return NAME_BOOL; case TType.BYTE: return NAME_BYTE; case TType.I16: return NAME_I16; case TType.I32: return NAME_I32; case TType.I64: return NAME_I64; case TType.UUID: return NAME_UUID; case TType.DOUBLE: return NAME_DOUBLE; case TType.STRING: return NAME_STRING; case TType.STRUCT: return NAME_STRUCT; case TType.MAP: return NAME_MAP; case TType.SET: return NAME_SET; case TType.LIST: return NAME_LIST; default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } } private static byte getTypeIDForTypeName(byte[] name) throws TException { byte result = TType.STOP; if (name.length > 1) { switch (name[0]) { case 'd': result = TType.DOUBLE; break; case 'i': switch (name[1]) { case '8': result = TType.BYTE; break; case '1': result = TType.I16; break; case '3': result = TType.I32; break; case '6': result = TType.I64; break; } break; case 'l': result = TType.LIST; break; case 'm': result = TType.MAP; break; case 'r': result = TType.STRUCT; break; case 's': if (name[1] == 't') { result = TType.STRING; } else if (name[1] == 'e') { result = TType.SET; } break; case 'u': result = TType.UUID; break; case 't': result = TType.BOOL; break; } } if (result == TType.STOP) { throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } return result; } // Base class for tracking JSON contexts that may require inserting/reading // additional JSON syntax characters // This base context does nothing. protected static class JSONBaseContext { protected void write() throws TException {} protected void read() throws TException {} protected boolean escapeNum() { return false; } } // Context for JSON lists. Will insert/read commas before each item except // for the first one protected class JSONListContext extends JSONBaseContext { private boolean first_ = true; @Override protected void write() throws TException { if (first_) { first_ = false; } else { trans_.write(COMMA); } } @Override protected void read() throws TException { if (first_) { first_ = false; } else { readJSONSyntaxChar(COMMA); } } } // Context for JSON records. Will insert/read colons before the value portion // of each record pair, and commas before each key except the first. In // addition, will indicate that numbers in the key position need to be // escaped in quotes (since JSON keys must be strings). protected class JSONPairContext extends JSONBaseContext { private boolean first_ = true; private boolean colon_ = true; @Override protected void write() throws TException { if (first_) { first_ = false; colon_ = true; } else { trans_.write(colon_ ? COLON : COMMA); colon_ = !colon_; } } @Override protected void read() throws TException { if (first_) { first_ = false; colon_ = true; } else { readJSONSyntaxChar(colon_ ? COLON : COMMA); colon_ = !colon_; } } @Override protected boolean escapeNum() { return colon_; } } // Holds up to one byte from the transport protected class LookaheadReader { private boolean hasData_; private final byte[] data_ = new byte[1]; // Return and consume the next byte to be read, either taking it from the // data buffer if present or getting it from the transport otherwise. protected byte read() throws TException { if (hasData_) { hasData_ = false; } else { trans_.readAll(data_, 0, 1); } return data_[0]; } // Return the next byte to be read without consuming, filling the data // buffer if it has not been filled already. protected byte peek() throws TException { if (!hasData_) { trans_.readAll(data_, 0, 1); } hasData_ = true; return data_[0]; } } // Stack of nested contexts that we may be in private final Stack contextStack_ = new Stack<>(); // Current context that we are in private JSONBaseContext context_ = new JSONBaseContext(); // Reader that manages a 1-byte buffer private LookaheadReader reader_ = new LookaheadReader(); // Write out the TField names as a string instead of the default integer value private boolean fieldNamesAsString_ = false; // Push a new JSON context onto the stack. private void pushContext(JSONBaseContext c) { contextStack_.push(context_); context_ = c; } // Pop the last JSON context off the stack private void popContext() { context_ = contextStack_.pop(); } // Reset the context stack to its initial state private void resetContext() { while (!contextStack_.isEmpty()) { popContext(); } } /** Constructor */ public TJSONProtocol(TTransport trans) { super(trans); } public TJSONProtocol(TTransport trans, boolean fieldNamesAsString) { super(trans); fieldNamesAsString_ = fieldNamesAsString; } @Override public void reset() { contextStack_.clear(); context_ = new JSONBaseContext(); reader_ = new LookaheadReader(); } // Temporary buffer used by several methods private final byte[] tmpbuf_ = new byte[4]; // Read a byte that must match b[0]; otherwise an exception is thrown. // Marked protected to avoid synthetic accessor in JSONListContext.read // and JSONPairContext.read protected void readJSONSyntaxChar(byte[] b) throws TException { byte ch = reader_.read(); if (ch != b[0]) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Unexpected character:" + (char) ch); } } // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its // corresponding hex value private static byte hexVal(byte ch) throws TException { if ((ch >= '0') && (ch <= '9')) { return (byte) ((char) ch - '0'); } else if ((ch >= 'a') && (ch <= 'f')) { return (byte) ((char) ch - 'a' + 10); } else { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected hex character"); } } // Convert a byte containing a hex value to its corresponding hex character private static byte hexChar(byte val) { val &= 0x0F; if (val < 10) { return (byte) ((char) val + '0'); } else { return (byte) ((char) (val - 10) + 'a'); } } // Write the bytes in array buf as a JSON characters, escaping as needed private void writeJSONString(byte[] b) throws TException { context_.write(); trans_.write(QUOTE); int len = b.length; for (int i = 0; i < len; i++) { if ((b[i] & 0x00FF) >= 0x30) { if (b[i] == BACKSLASH[0]) { trans_.write(BACKSLASH); trans_.write(BACKSLASH); } else { trans_.write(b, i, 1); } } else { tmpbuf_[0] = JSON_CHAR_TABLE[b[i]]; if (tmpbuf_[0] == 1) { trans_.write(b, i, 1); } else if (tmpbuf_[0] > 1) { trans_.write(BACKSLASH); trans_.write(tmpbuf_, 0, 1); } else { trans_.write(ESCSEQ); tmpbuf_[0] = hexChar((byte) (b[i] >> 4)); tmpbuf_[1] = hexChar(b[i]); trans_.write(tmpbuf_, 0, 2); } } } trans_.write(QUOTE); } // Write out number as a JSON value. If the context dictates so, it will be // wrapped in quotes to output as a JSON string. private void writeJSONInteger(long num) throws TException { context_.write(); String str = Long.toString(num); boolean escapeNum = context_.escapeNum(); if (escapeNum) { trans_.write(QUOTE); } byte[] buf = str.getBytes(StandardCharsets.UTF_8); trans_.write(buf); if (escapeNum) { trans_.write(QUOTE); } } // Write out a double as a JSON value. If it is NaN or infinity or if the // context dictates escaping, write out as JSON string. private void writeJSONDouble(double num) throws TException { context_.write(); String str = Double.toString(num); boolean special = false; switch (str.charAt(0)) { case 'N': // NaN case 'I': // Infinity special = true; break; case '-': if (str.charAt(1) == 'I') { // -Infinity special = true; } break; default: break; } boolean escapeNum = special || context_.escapeNum(); if (escapeNum) { trans_.write(QUOTE); } byte[] b = str.getBytes(StandardCharsets.UTF_8); trans_.write(b, 0, b.length); if (escapeNum) { trans_.write(QUOTE); } } // Write out contents of byte array b as a JSON string with base-64 encoded // data private void writeJSONBase64(byte[] b, int offset, int length) throws TException { context_.write(); trans_.write(QUOTE); int len = length; int off = offset; while (len >= 3) { // Encode 3 bytes at a time TBase64Utils.encode(b, off, 3, tmpbuf_, 0); trans_.write(tmpbuf_, 0, 4); off += 3; len -= 3; } if (len > 0) { // Encode remainder TBase64Utils.encode(b, off, len, tmpbuf_, 0); trans_.write(tmpbuf_, 0, len + 1); } trans_.write(QUOTE); } private void writeJSONObjectStart() throws TException { context_.write(); trans_.write(LBRACE); pushContext(new JSONPairContext()); } private void writeJSONObjectEnd() throws TException { popContext(); trans_.write(RBRACE); } private void writeJSONArrayStart() throws TException { context_.write(); trans_.write(LBRACKET); pushContext(new JSONListContext()); } private void writeJSONArrayEnd() throws TException { popContext(); trans_.write(RBRACKET); } @Override public void writeMessageBegin(TMessage message) throws TException { resetContext(); // THRIFT-3743 writeJSONArrayStart(); writeJSONInteger(VERSION); byte[] b = message.name.getBytes(StandardCharsets.UTF_8); writeJSONString(b); writeJSONInteger(message.type); writeJSONInteger(message.seqid); } @Override public void writeMessageEnd() throws TException { writeJSONArrayEnd(); } @Override public void writeStructBegin(TStruct struct) throws TException { writeJSONObjectStart(); } @Override public void writeStructEnd() throws TException { writeJSONObjectEnd(); } @Override public void writeFieldBegin(TField field) throws TException { if (fieldNamesAsString_) { writeString(field.name); } else { writeJSONInteger(field.id); } writeJSONObjectStart(); writeJSONString(getTypeNameForTypeID(field.type)); } @Override public void writeFieldEnd() throws TException { writeJSONObjectEnd(); } @Override public void writeFieldStop() {} @Override public void writeMapBegin(TMap map) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(map.keyType)); writeJSONString(getTypeNameForTypeID(map.valueType)); writeJSONInteger(map.size); writeJSONObjectStart(); } @Override public void writeMapEnd() throws TException { writeJSONObjectEnd(); writeJSONArrayEnd(); } @Override public void writeListBegin(TList list) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(list.elemType)); writeJSONInteger(list.size); } @Override public void writeListEnd() throws TException { writeJSONArrayEnd(); } @Override public void writeSetBegin(TSet set) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(set.elemType)); writeJSONInteger(set.size); } @Override public void writeSetEnd() throws TException { writeJSONArrayEnd(); } @Override public void writeBool(boolean b) throws TException { writeJSONInteger(b ? (long) 1 : (long) 0); } @Override public void writeByte(byte b) throws TException { writeJSONInteger(b); } @Override public void writeI16(short i16) throws TException { writeJSONInteger(i16); } @Override public void writeI32(int i32) throws TException { writeJSONInteger(i32); } @Override public void writeI64(long i64) throws TException { writeJSONInteger(i64); } @Override public void writeUuid(UUID uuid) throws TException { writeJSONString(uuid.toString().getBytes(StandardCharsets.UTF_8)); } @Override public void writeDouble(double dub) throws TException { writeJSONDouble(dub); } @Override public void writeString(String str) throws TException { byte[] b = str.getBytes(StandardCharsets.UTF_8); writeJSONString(b); } @Override public void writeBinary(ByteBuffer bin) throws TException { writeJSONBase64( bin.array(), bin.position() + bin.arrayOffset(), bin.limit() - bin.position() - bin.arrayOffset()); } /** Reading methods. */ // Read in a JSON string, unescaping as appropriate.. Skip reading from the // context if skipContext is true. private TByteArrayOutputStream readJSONString(boolean skipContext) throws TException { TByteArrayOutputStream arr = new TByteArrayOutputStream(DEF_STRING_SIZE); ArrayList codeunits = new ArrayList(); if (!skipContext) { context_.read(); } readJSONSyntaxChar(QUOTE); while (true) { byte ch = reader_.read(); if (ch == QUOTE[0]) { break; } if (ch == ESCSEQ[0]) { ch = reader_.read(); if (ch == ESCSEQ[1]) { trans_.readAll(tmpbuf_, 0, 4); short cu = (short) (((short) hexVal(tmpbuf_[0]) << 12) + ((short) hexVal(tmpbuf_[1]) << 8) + ((short) hexVal(tmpbuf_[2]) << 4) + (short) hexVal(tmpbuf_[3])); try { if (Character.isHighSurrogate((char) cu)) { if (codeunits.size() > 0) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Expected low surrogate char"); } codeunits.add((char) cu); } else if (Character.isLowSurrogate((char) cu)) { if (codeunits.size() == 0) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Expected high surrogate char"); } codeunits.add((char) cu); arr.write( (new String(new int[] {codeunits.get(0), codeunits.get(1)}, 0, 2)) .getBytes(StandardCharsets.UTF_8)); codeunits.clear(); } else { arr.write((new String(new int[] {cu}, 0, 1)).getBytes(StandardCharsets.UTF_8)); } continue; } catch (IOException ex) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Invalid unicode sequence"); } } else { int off = ESCAPE_CHARS.indexOf(ch); if (off == -1) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected control char"); } ch = ESCAPE_CHAR_VALS[off]; } } arr.write(ch); } return arr; } // Return true if the given byte could be a valid part of a JSON number. private boolean isJSONNumeric(byte b) { switch (b) { case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'E': case 'e': return true; } return false; } // Read in a sequence of characters that are all valid in JSON numbers. Does // not do a complete regex check to validate that this is actually a number. private String readJSONNumericChars() throws TException { StringBuilder strbld = new StringBuilder(); while (true) { byte ch = reader_.peek(); if (!isJSONNumeric(ch)) { break; } strbld.append((char) reader_.read()); } return strbld.toString(); } // Read in a JSON number. If the context dictates, read in enclosing quotes. private long readJSONInteger() throws TException { context_.read(); if (context_.escapeNum()) { readJSONSyntaxChar(QUOTE); } String str = readJSONNumericChars(); if (context_.escapeNum()) { readJSONSyntaxChar(QUOTE); } try { return Long.parseLong(str); } catch (NumberFormatException ex) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } // Read in a JSON double value. Throw if the value is not wrapped in quotes // when expected or if wrapped in quotes when not expected. private double readJSONDouble() throws TException { context_.read(); if (reader_.peek() == QUOTE[0]) { TByteArrayOutputStream arr = readJSONString(true); double dub = Double.parseDouble(arr.toString(StandardCharsets.UTF_8)); if (!context_.escapeNum() && !Double.isNaN(dub) && !Double.isInfinite(dub)) { // Throw exception -- we should not be in a string in this case throw new TProtocolException( TProtocolException.INVALID_DATA, "Numeric data unexpectedly quoted"); } return dub; } else { if (context_.escapeNum()) { // This will throw - we should have had a quote if escapeNum == true readJSONSyntaxChar(QUOTE); } try { return Double.parseDouble(readJSONNumericChars()); } catch (NumberFormatException ex) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } } // Read in a JSON string containing base-64 encoded data and decode it. private byte[] readJSONBase64() throws TException { TByteArrayOutputStream arr = readJSONString(false); byte[] b = arr.get(); int len = arr.len(); int off = 0; int size = 0; // Ignore padding int bound = len >= 2 ? len - 2 : 0; for (int i = len - 1; i >= bound && b[i] == '='; --i) { --len; } while (len >= 4) { // Decode 4 bytes at a time TBase64Utils.decode(b, off, 4, b, size); // NB: decoded in place off += 4; len -= 4; size += 3; } // Don't decode if we hit the end or got a single leftover byte (invalid // base64 but legal for skip of regular string type) if (len > 1) { // Decode remainder TBase64Utils.decode(b, off, len, b, size); // NB: decoded in place size += len - 1; } // Sadly we must copy the byte[] (any way around this?) byte[] result = new byte[size]; System.arraycopy(b, 0, result, 0, size); return result; } private void readJSONObjectStart() throws TException { context_.read(); readJSONSyntaxChar(LBRACE); pushContext(new JSONPairContext()); } private void readJSONObjectEnd() throws TException { readJSONSyntaxChar(RBRACE); popContext(); } private void readJSONArrayStart() throws TException { context_.read(); readJSONSyntaxChar(LBRACKET); pushContext(new JSONListContext()); } private void readJSONArrayEnd() throws TException { readJSONSyntaxChar(RBRACKET); popContext(); } @Override public TMessage readMessageBegin() throws TException { resetContext(); // THRIFT-3743 readJSONArrayStart(); if (readJSONInteger() != VERSION) { throw new TProtocolException( TProtocolException.BAD_VERSION, "Message contained bad version."); } String name = readJSONString(false).toString(StandardCharsets.UTF_8); byte type = (byte) readJSONInteger(); int seqid = (int) readJSONInteger(); return new TMessage(name, type, seqid); } @Override public void readMessageEnd() throws TException { readJSONArrayEnd(); } @Override public TStruct readStructBegin() throws TException { readJSONObjectStart(); return ANONYMOUS_STRUCT; } @Override public void readStructEnd() throws TException { readJSONObjectEnd(); } @Override public TField readFieldBegin() throws TException { byte ch = reader_.peek(); byte type; short id = 0; if (ch == RBRACE[0]) { type = TType.STOP; } else { id = (short) readJSONInteger(); readJSONObjectStart(); type = getTypeIDForTypeName(readJSONString(false).get()); } return new TField("", type, id); } @Override public void readFieldEnd() throws TException { readJSONObjectEnd(); } @Override public TMap readMapBegin() throws TException { readJSONArrayStart(); byte keyType = getTypeIDForTypeName(readJSONString(false).get()); byte valueType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int) readJSONInteger(); readJSONObjectStart(); TMap map = new TMap(keyType, valueType, size); checkReadBytesAvailable(map); return map; } @Override public void readMapEnd() throws TException { readJSONObjectEnd(); readJSONArrayEnd(); } @Override public TList readListBegin() throws TException { readJSONArrayStart(); byte elemType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int) readJSONInteger(); TList list = new TList(elemType, size); checkReadBytesAvailable(list); return list; } @Override public void readListEnd() throws TException { readJSONArrayEnd(); } @Override public TSet readSetBegin() throws TException { readJSONArrayStart(); byte elemType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int) readJSONInteger(); TSet set = new TSet(elemType, size); checkReadBytesAvailable(set); return set; } @Override public void readSetEnd() throws TException { readJSONArrayEnd(); } @Override public boolean readBool() throws TException { return (readJSONInteger() != 0); } @Override public byte readByte() throws TException { return (byte) readJSONInteger(); } @Override public short readI16() throws TException { return (short) readJSONInteger(); } @Override public int readI32() throws TException { return (int) readJSONInteger(); } @Override public long readI64() throws TException { return readJSONInteger(); } @Override public UUID readUuid() throws TException { return UUID.fromString(readString()); } @Override public double readDouble() throws TException { return readJSONDouble(); } @Override public String readString() throws TException { return readJSONString(false).toString(StandardCharsets.UTF_8); } @Override public ByteBuffer readBinary() throws TException { return ByteBuffer.wrap(readJSONBase64()); } /** Return the minimum number of bytes a type will consume on the wire */ @Override public int getMinSerializedSize(byte type) throws TTransportException { switch (type) { case 0: return 1; // Stop - T_STOP needs to count itself case 1: return 1; // Void - T_VOID needs to count itself case 2: return 1; // Bool case 3: return 1; // Byte case 4: return 1; // Double case 6: return 1; // I16 case 8: return 1; // I32 case 10: return 1; // I64 case 11: return 2; // string length case 12: return 2; // empty struct case 13: return 2; // element count Map case 14: return 2; // element count Set case 15: return 2; // element count List default: throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code"); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TProtocol.java0000664000175000017500000004453315167543515027467 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.IntFunction; import org.apache.thrift.TException; import org.apache.thrift.partial.TFieldData; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.StandardScheme; import org.apache.thrift.transport.TTransport; /** Protocol interface definition. */ public abstract class TProtocol implements TWriteProtocol, TReadProtocol { /** Prevent direct instantiation */ @SuppressWarnings("unused") private TProtocol() {} /** Transport */ protected TTransport trans_; /** Current recursion depth during deserialization */ private int recursionDepth_ = 0; /** Constructor */ protected TProtocol(TTransport trans) { trans_ = trans; } /** * Increment recursion depth, checking against the configured limit. * * @throws TProtocolException with DEPTH_LIMIT if limit exceeded */ public void incrementRecursionDepth() throws TProtocolException { int limit = trans_.getConfiguration().getRecursionLimit(); if (recursionDepth_ >= limit) { throw new TProtocolException( TProtocolException.DEPTH_LIMIT, "Recursion depth " + (recursionDepth_ + 1) + " exceeds limit " + limit); } ++recursionDepth_; } /** Decrement recursion depth. Call in finally block. */ public void decrementRecursionDepth() { --recursionDepth_; } /** Transport accessor */ public TTransport getTransport() { return trans_; } protected void checkReadBytesAvailable(TMap map) throws TException { long elemSize = getMinSerializedSize(map.keyType) + getMinSerializedSize(map.valueType); trans_.checkReadBytesAvailable(map.size * elemSize); } protected void checkReadBytesAvailable(TList list) throws TException { long size = list.getSize(); trans_.checkReadBytesAvailable(size * getMinSerializedSize(list.elemType)); } protected void checkReadBytesAvailable(TSet set) throws TException { long size = set.getSize(); trans_.checkReadBytesAvailable(size * getMinSerializedSize(set.elemType)); } /** * Return min serialized size in bytes * * @param type Returns the minimum amount of bytes needed to store the smallest possible instance * of TType. * @return min serialized size * @throws TException when error happens */ public abstract int getMinSerializedSize(byte type) throws TException; public interface WriteCallback { void call(T e) throws TException; } public interface ReadCallback { R accept(T t) throws TException; } public interface ReadCollectionCallback { R call() throws TException; } public interface ReadMapEntryCallback { K getKey() throws TException; V getValue() throws TException; } public final void writeSet(byte elementType, Set set, WriteCallback callback) throws TException { writeSetBegin(new TSet(elementType, set.size())); for (T t : set) { callback.call(t); } writeSetEnd(); } public final void writeList(byte elementType, List list, WriteCallback callback) throws TException { writeListBegin(new TList(elementType, list.size())); for (T t : list) { callback.call(t); } writeListEnd(); } public final void writeMap( byte keyType, byte valueType, Map map, WriteCallback> callback) throws TException { writeMapBegin(new TMap(keyType, valueType, map.size())); for (Map.Entry entry : map.entrySet()) { callback.call(entry); } writeMapEnd(); } public final void writeField(TField field, WriteCallback callback) throws TException { writeFieldBegin(field); callback.call(null); writeFieldEnd(); } public final void writeStruct(TStruct struct, WriteCallback callback) throws TException { writeStructBegin(struct); callback.call(null); writeStructEnd(); } public final void writeMessage(TMessage message, WriteCallback callback) throws TException { writeMessageBegin(message); callback.call(null); writeMessageEnd(); } /** * read a message by delegating to a callback, handles {@link #readMessageBegin() begin} and * {@link #readMessageEnd() end} automatically. * * @param callback callback for actual reading * @param result message type * @return the message read * @throws TException when any sub-operation failed */ public final T readMessage(ReadCallback callback) throws TException { TMessage tMessage = readMessageBegin(); T t = callback.accept(tMessage); readMessageEnd(); return t; } /** * read a struct by delegating to a callback, handles {@link #readStructBegin() begin} and {@link * #readStructEnd() end} automatically. * * @param callback callback for actual reading * @param result struct type * @return the struct read * @throws TException when any sub-operation failed */ public final T readStruct(ReadCallback callback) throws TException { TStruct tStruct = readStructBegin(); T t = callback.accept(tStruct); readStructEnd(); return t; } /** * read a field by delegating to a callback, handles {@link #readFieldBegin() begin} and {@link * #readFieldEnd() end} automatically, and returns whether the {@link TType#STOP stop signal} was * encountered. Because the value is not returned, you (the compiler generated code in most cases) * are expected to set the field yourself within the callback. * * @param callback callback for reading a field * @param result field type * @return true if a stop signal was encountered, false otherwise * @throws Exception when any sub-operation failed */ public final boolean readField(ReadCallback callback) throws Exception { TField tField = readFieldBegin(); if (tField.type == org.apache.thrift.protocol.TType.STOP) { return true; } callback.accept(tField); readFieldEnd(); return false; } /** * read a {@link Map} of elements by delegating to the callback, handles {@link #readMapBegin() * begin} and {@link #readMapEnd() end} automatically. * * @param callback callback for reading the map * @param result map type * @return the map read * @throws TException when any sub-operation fails */ public final > T readMap(ReadCallback callback) throws TException { TMap tMap = readMapBegin(); T t = callback.accept(tMap); readMapEnd(); return t; } /** * read a {@link Map} of elements by delegating key and value reading to the callback, handles * {@link #readMapBegin() begin} and {@link #readMapEnd() end} automatically. * * @param callback callback for reading keys and values, calls to {@link * ReadMapEntryCallback#getKey()} and {@link ReadMapEntryCallback#getValue()} will be in * alternating orders, i.e. k1, v1, k2, v2, .., k_n, v_n * @param key type * @param value type * @return the map read * @throws TException when any sub-operation fails */ public final Map readMap(ReadMapEntryCallback callback) throws TException { return readMap(callback::getKey, callback::getValue); } /** * read a {@link Map} of elements by delegating key reading to the callback, handles {@link * #readMapBegin() begin} and {@link #readMapEnd() end} automatically. Calls to keyCallback and * valueCallback will be in alternating orders, i.e. k1, v1, k2, v2, .., k_n, v_n * * @param keyCallback callback for reading keys * @param valueCallback callback for reading values * @param key type * @param value type * @return the map read * @throws TException when any sub-operation fails */ public final Map readMap( ReadCollectionCallback keyCallback, ReadCollectionCallback valueCallback) throws TException { return readMap(keyCallback, valueCallback, size -> new HashMap<>(2 * size)); } /** * read a {@link Map} of elements by delegating key and value reading to the callback, handles * {@link #readMapBegin() begin} and {@link #readMapEnd() end} automatically, with a specialized * map creator given the size hint. * * @param callback callback for reading keys and values, calls to {@link * ReadMapEntryCallback#getKey()} and {@link ReadMapEntryCallback#getValue()} will be in * alternating orders, i.e. k1, v1, k2, v2, .., k_n, v_n * @param mapCreator map creator given the size hint * @param key type * @param value type * @return the map read * @throws TException when any sub-operation fails */ public final Map readMap( ReadMapEntryCallback callback, IntFunction> mapCreator) throws TException { return readMap(callback::getKey, callback::getValue, mapCreator); } /** * read a {@link Map} of elements by delegating key and value reading to the callback, handles * {@link #readMapBegin() begin} and {@link #readMapEnd() end} automatically, with a specialized * map creator given the size hint. Calls to keyCallback and valueCallback will be in alternating * orders, i.e. k1, v1, k2, v2, .., k_n, v_n * * @param keyCallback callback for reading keys * @param valueCallback callback for reading values * @param mapCreator map creator given the size hint * @param key type * @param value type * @return the map read * @throws TException when any sub-operation fails */ public final Map readMap( ReadCollectionCallback keyCallback, ReadCollectionCallback valueCallback, IntFunction> mapCreator) throws TException { return readMap( tMap -> { Map map = mapCreator.apply(tMap.size); for (int i = 0; i < tMap.size; i += 1) { map.put(keyCallback.call(), valueCallback.call()); } return map; }); } /** * read a {@link List} by delegating to the callback, handles {@link #readListBegin() begin} and * {@link #readListEnd() end} automatically. * * @param callback callback for reading the list * @param result list type * @return the list read * @throws TException when any sub-operation fails */ public final > T readList(ReadCallback callback) throws TException { TList tList = readListBegin(); T t = callback.accept(tList); readListEnd(); return t; } /** * read a {@link List} by delegating element reading to the callback, handles {@link * #readListBegin() begin} and {@link #readListEnd() end} automatically. * * @param callback callback for reading one element * @param element type * @return list of elements read * @throws TException when any sub-operation fails */ public final List readList(ReadCollectionCallback callback) throws TException { return readList(callback, ArrayList::new); } /** * read a {@link List} by delegating element reading to the callback, handles {@link * #readListBegin() begin} and {@link #readListEnd() end} automatically, with a specialized list * creator given the size hint. * * @param callback callback for reading one element * @param listCreator list creator given size hint * @param element type * @return list of elements read * @throws TException when any sub-operation fails */ public final List readList( ReadCollectionCallback callback, IntFunction> listCreator) throws TException { return readList( tList -> { List list = listCreator.apply(tList.size); for (int i = 0; i < tList.size; i += 1) { list.add(callback.call()); } return list; }); } /** * read a {@link Set} of elements by delegating to the callback, handles {@link #readSetBegin() * begin} and {@link #readSetEnd() end} automatically * * @param callback callback for reading the set * @param result set type * @return the set read * @throws TException when any sub-operation fails */ public final > T readSet(ReadCallback callback) throws TException { TSet tSet = readSetBegin(); T t = callback.accept(tSet); readSetEnd(); return t; } /** * read a {@link Set} of elements by delegating element reading to the callback, handles {@link * #readSetBegin() begin} and {@link #readSetEnd() end} automatically * * @param callback callback for reading one element * @param element type * @return set of elements read * @throws TException when any sub-operation fails */ public final Set readSet(ReadCollectionCallback callback) throws TException { return readSet(callback, size -> new HashSet<>(2 * size)); } /** * read a {@link Set} of elements by delegating element reading to the callback, handles {@link * #readSetBegin() begin} and {@link #readSetEnd() end} automatically, with a specialized set * creator given the size hint. * * @param callback callback for reading one elment * @param setCreator set creator given size hint * @param element type * @return set of elements read * @throws TException when any sub-operation fails */ public final Set readSet( ReadCollectionCallback callback, IntFunction> setCreator) throws TException { return readSet( tSet -> { Set set = setCreator.apply(tSet.size); for (int i = 0; i < tSet.size; i += 1) { set.add(callback.call()); } return set; }); } /** * Reset any internal state back to a blank slate. This method only needs to be implemented for * stateful protocols. */ public void reset() {} /** Scheme accessor */ public Class getScheme() { return StandardScheme.class; } // ----------------------------------------------------------------- // Additional methods to improve performance. public int readFieldBeginData() throws TException { // Derived classes should provide a more efficient version of this // method if allowed by the encoding used by that protocol. TField tfield = this.readFieldBegin(); return TFieldData.encode(tfield.type, tfield.id); } public void skip(byte fieldType) throws TException { this.skip(fieldType, Integer.MAX_VALUE); } public void skip(byte fieldType, int maxDepth) throws TException { if (maxDepth <= 0) { throw new TException("Maximum skip depth exceeded"); } switch (fieldType) { case TType.BOOL: this.skipBool(); break; case TType.BYTE: this.skipByte(); break; case TType.I16: this.skipI16(); break; case TType.I32: this.skipI32(); break; case TType.I64: this.skipI64(); break; case TType.DOUBLE: this.skipDouble(); break; case TType.STRING: this.skipBinary(); break; case TType.STRUCT: this.readStructBegin(); while (true) { int tfieldData = this.readFieldBeginData(); byte tfieldType = TFieldData.getType(tfieldData); if (tfieldType == TType.STOP) { break; } this.skip(tfieldType, maxDepth - 1); this.readFieldEnd(); } this.readStructEnd(); break; case TType.MAP: TMap map = this.readMapBegin(); for (int i = 0; i < map.size; i++) { this.skip(map.keyType, maxDepth - 1); this.skip(map.valueType, maxDepth - 1); } this.readMapEnd(); break; case TType.SET: TSet set = this.readSetBegin(); for (int i = 0; i < set.size; i++) { this.skip(set.elemType, maxDepth - 1); } this.readSetEnd(); break; case TType.LIST: TList list = this.readListBegin(); for (int i = 0; i < list.size; i++) { this.skip(list.elemType, maxDepth - 1); } this.readListEnd(); break; default: throw new TProtocolException( TProtocolException.INVALID_DATA, "Unrecognized type " + fieldType); } } /** * The default implementation of all skip() methods calls the corresponding read() method. * Protocols that derive from this class are strongly encouraged to provide a more efficient * alternative. */ protected void skipBool() throws TException { this.readBool(); } protected void skipByte() throws TException { this.readByte(); } protected void skipI16() throws TException { this.readI16(); } protected void skipI32() throws TException { this.readI32(); } protected void skipI64() throws TException { this.readI64(); } protected void skipDouble() throws TException { this.readDouble(); } protected void skipBinary() throws TException { this.readBinary(); } static final int MAX_SKIPPED_BYTES = 256; protected byte[] skippedBytes = new byte[MAX_SKIPPED_BYTES]; protected void skipBytes(int numBytes) throws TException { if (numBytes <= MAX_SKIPPED_BYTES) { if (this.getTransport().getBytesRemainingInBuffer() >= numBytes) { this.getTransport().consumeBuffer(numBytes); } else { this.getTransport().readAll(skippedBytes, 0, numBytes); } } else { int remaining = numBytes; while (remaining > 0) { skipBytes(Math.min(remaining, MAX_SKIPPED_BYTES)); remaining -= MAX_SKIPPED_BYTES; } } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TList.java0000664000175000017500000000226015165535636026573 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** Helper class that encapsulates list metadata. */ public final class TList { public TList() { this(TType.STOP, 0); } public TList(byte t, int s) { elemType = t; size = s; } public final byte elemType; public final int size; public byte getElemType() { return elemType; } public int getSize() { return size; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolFactory.java0000664000175000017500000000207315165535636031013 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.Serializable; import org.apache.thrift.transport.TTransport; /** Factory interface for constructing protocol instances. */ public interface TProtocolFactory extends Serializable { TProtocol getProtocol(TTransport trans); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TSet.java0000664000175000017500000000236115165535636026415 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** Helper class that encapsulates set metadata. */ public final class TSet { public TSet() { this(TType.STOP, 0); } public TSet(byte t, int s) { elemType = t; size = s; } public TSet(TList list) { this(list.elemType, list.size); } public final byte elemType; public final int size; public byte getElemType() { return elemType; } public int getSize() { return size; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TReadProtocol.java0000664000175000017500000000202115165535636030250 0ustar00buildbuild00000000000000package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.util.UUID; import org.apache.thrift.TException; public interface TReadProtocol { TMessage readMessageBegin() throws TException; void readMessageEnd() throws TException; TStruct readStructBegin() throws TException; void readStructEnd() throws TException; TField readFieldBegin() throws TException; void readFieldEnd() throws TException; TMap readMapBegin() throws TException; void readMapEnd() throws TException; TList readListBegin() throws TException; void readListEnd() throws TException; TSet readSetBegin() throws TException; void readSetEnd() throws TException; boolean readBool() throws TException; byte readByte() throws TException; short readI16() throws TException; int readI32() throws TException; long readI64() throws TException; UUID readUuid() throws TException; double readDouble() throws TException; String readString() throws TException; ByteBuffer readBinary() throws TException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TBinaryProtocol.java0000664000175000017500000003704215167543515030631 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.UUID; import org.apache.thrift.TException; import org.apache.thrift.partial.TFieldData; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; /** Binary protocol implementation for thrift. */ public class TBinaryProtocol extends TProtocol { private static final TStruct ANONYMOUS_STRUCT = new TStruct(); private static final long NO_LENGTH_LIMIT = -1; protected static final int VERSION_MASK = 0xffff0000; protected static final int VERSION_1 = 0x80010000; /** * The maximum number of bytes to read from the transport for variable-length fields (such as * strings or binary) or {@link #NO_LENGTH_LIMIT} for unlimited. */ private final long stringLengthLimit_; /** * The maximum number of elements to read from the network for containers (maps, sets, lists), or * {@link #NO_LENGTH_LIMIT} for unlimited. */ private final long containerLengthLimit_; protected boolean strictRead_; protected boolean strictWrite_; private final byte[] inoutTemp = new byte[16]; /** Factory */ public static class Factory implements TProtocolFactory { protected long stringLengthLimit_; protected long containerLengthLimit_; protected boolean strictRead_; protected boolean strictWrite_; public Factory() { this(false, true); } public Factory(boolean strictRead, boolean strictWrite) { this(strictRead, strictWrite, NO_LENGTH_LIMIT, NO_LENGTH_LIMIT); } public Factory(long stringLengthLimit, long containerLengthLimit) { this(false, true, stringLengthLimit, containerLengthLimit); } public Factory( boolean strictRead, boolean strictWrite, long stringLengthLimit, long containerLengthLimit) { stringLengthLimit_ = stringLengthLimit; containerLengthLimit_ = containerLengthLimit; strictRead_ = strictRead; strictWrite_ = strictWrite; } public TProtocol getProtocol(TTransport trans) { return new TBinaryProtocol( trans, stringLengthLimit_, containerLengthLimit_, strictRead_, strictWrite_); } } /** Constructor */ public TBinaryProtocol(TTransport trans) { this(trans, false, true); } public TBinaryProtocol(TTransport trans, boolean strictRead, boolean strictWrite) { this(trans, NO_LENGTH_LIMIT, NO_LENGTH_LIMIT, strictRead, strictWrite); } public TBinaryProtocol(TTransport trans, long stringLengthLimit, long containerLengthLimit) { this(trans, stringLengthLimit, containerLengthLimit, false, true); } public TBinaryProtocol( TTransport trans, long stringLengthLimit, long containerLengthLimit, boolean strictRead, boolean strictWrite) { super(trans); stringLengthLimit_ = stringLengthLimit; containerLengthLimit_ = containerLengthLimit; strictRead_ = strictRead; strictWrite_ = strictWrite; } @Override public void writeMessageBegin(TMessage message) throws TException { if (strictWrite_) { int version = VERSION_1 | message.type; writeI32(version); writeString(message.name); writeI32(message.seqid); } else { writeString(message.name); writeByte(message.type); writeI32(message.seqid); } } @Override public void writeMessageEnd() throws TException {} @Override public void writeStructBegin(TStruct struct) throws TException {} @Override public void writeStructEnd() throws TException {} @Override public void writeFieldBegin(TField field) throws TException { writeByte(field.type); writeI16(field.id); } @Override public void writeFieldEnd() throws TException {} @Override public void writeFieldStop() throws TException { writeByte(TType.STOP); } @Override public void writeMapBegin(TMap map) throws TException { writeByte(map.keyType); writeByte(map.valueType); writeI32(map.size); } @Override public void writeMapEnd() throws TException {} @Override public void writeListBegin(TList list) throws TException { writeByte(list.elemType); writeI32(list.size); } @Override public void writeListEnd() throws TException {} @Override public void writeSetBegin(TSet set) throws TException { writeByte(set.elemType); writeI32(set.size); } @Override public void writeSetEnd() throws TException {} @Override public void writeBool(boolean b) throws TException { writeByte(b ? (byte) 1 : (byte) 0); } @Override public void writeByte(byte b) throws TException { inoutTemp[0] = b; trans_.write(inoutTemp, 0, 1); } @Override public void writeI16(short i16) throws TException { inoutTemp[0] = (byte) (0xff & (i16 >> 8)); inoutTemp[1] = (byte) (0xff & (i16)); trans_.write(inoutTemp, 0, 2); } @Override public void writeI32(int i32) throws TException { inoutTemp[0] = (byte) (0xff & (i32 >> 24)); inoutTemp[1] = (byte) (0xff & (i32 >> 16)); inoutTemp[2] = (byte) (0xff & (i32 >> 8)); inoutTemp[3] = (byte) (0xff & (i32)); trans_.write(inoutTemp, 0, 4); } @Override public void writeI64(long i64) throws TException { inoutTemp[0] = (byte) (0xff & (i64 >> 56)); inoutTemp[1] = (byte) (0xff & (i64 >> 48)); inoutTemp[2] = (byte) (0xff & (i64 >> 40)); inoutTemp[3] = (byte) (0xff & (i64 >> 32)); inoutTemp[4] = (byte) (0xff & (i64 >> 24)); inoutTemp[5] = (byte) (0xff & (i64 >> 16)); inoutTemp[6] = (byte) (0xff & (i64 >> 8)); inoutTemp[7] = (byte) (0xff & (i64)); trans_.write(inoutTemp, 0, 8); } @Override public void writeUuid(UUID uuid) throws TException { ByteBuffer bb = ByteBuffer.wrap(inoutTemp); bb.putLong(uuid.getMostSignificantBits()); bb.putLong(uuid.getLeastSignificantBits()); trans_.write(inoutTemp, 0, 16); } @Override public void writeDouble(double dub) throws TException { writeI64(Double.doubleToLongBits(dub)); } @Override public void writeString(String str) throws TException { byte[] dat = str.getBytes(StandardCharsets.UTF_8); writeI32(dat.length); trans_.write(dat, 0, dat.length); } @Override public void writeBinary(ByteBuffer bin) throws TException { int length = bin.limit() - bin.position(); writeI32(length); trans_.write(bin.array(), bin.position() + bin.arrayOffset(), length); } /** Reading methods. */ @Override public TMessage readMessageBegin() throws TException { int size = readI32(); if (size < 0) { int version = size & VERSION_MASK; if (version != VERSION_1) { throw new TProtocolException( TProtocolException.BAD_VERSION, "Bad version in readMessageBegin"); } return new TMessage(readString(), (byte) (size & 0x000000ff), readI32()); } else { if (strictRead_) { throw new TProtocolException( TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?"); } return new TMessage(readStringBody(size), readByte(), readI32()); } } @Override public void readMessageEnd() throws TException {} @Override public TStruct readStructBegin() throws TException { return ANONYMOUS_STRUCT; } @Override public void readStructEnd() throws TException {} @Override public TField readFieldBegin() throws TException { byte type = readByte(); short id = type == TType.STOP ? 0 : readI16(); return new TField("", type, id); } @Override public void readFieldEnd() throws TException {} @Override public TMap readMapBegin() throws TException { TMap map = new TMap(readByte(), readByte(), readI32()); checkReadBytesAvailable(map); checkContainerReadLength(map.size); return map; } @Override public void readMapEnd() throws TException {} @Override public TList readListBegin() throws TException { TList list = new TList(readByte(), readI32()); checkReadBytesAvailable(list); checkContainerReadLength(list.size); return list; } @Override public void readListEnd() throws TException {} @Override public TSet readSetBegin() throws TException { TSet set = new TSet(readByte(), readI32()); checkReadBytesAvailable(set); checkContainerReadLength(set.size); return set; } @Override public void readSetEnd() throws TException {} @Override public boolean readBool() throws TException { return (readByte() == 1); } @Override public byte readByte() throws TException { if (trans_.getBytesRemainingInBuffer() >= 1) { byte b = trans_.getBuffer()[trans_.getBufferPosition()]; trans_.consumeBuffer(1); return b; } readAll(inoutTemp, 0, 1); return inoutTemp[0]; } @Override public short readI16() throws TException { byte[] buf = inoutTemp; int off = 0; if (trans_.getBytesRemainingInBuffer() >= 2) { buf = trans_.getBuffer(); off = trans_.getBufferPosition(); trans_.consumeBuffer(2); } else { readAll(inoutTemp, 0, 2); } return (short) (((buf[off] & 0xff) << 8) | ((buf[off + 1] & 0xff))); } @Override public int readI32() throws TException { byte[] buf = inoutTemp; int off = 0; if (trans_.getBytesRemainingInBuffer() >= 4) { buf = trans_.getBuffer(); off = trans_.getBufferPosition(); trans_.consumeBuffer(4); } else { readAll(inoutTemp, 0, 4); } return ((buf[off] & 0xff) << 24) | ((buf[off + 1] & 0xff) << 16) | ((buf[off + 2] & 0xff) << 8) | ((buf[off + 3] & 0xff)); } @Override public long readI64() throws TException { byte[] buf = inoutTemp; int off = 0; if (trans_.getBytesRemainingInBuffer() >= 8) { buf = trans_.getBuffer(); off = trans_.getBufferPosition(); trans_.consumeBuffer(8); } else { readAll(inoutTemp, 0, 8); } return ((long) (buf[off] & 0xff) << 56) | ((long) (buf[off + 1] & 0xff) << 48) | ((long) (buf[off + 2] & 0xff) << 40) | ((long) (buf[off + 3] & 0xff) << 32) | ((long) (buf[off + 4] & 0xff) << 24) | ((long) (buf[off + 5] & 0xff) << 16) | ((long) (buf[off + 6] & 0xff) << 8) | ((long) (buf[off + 7] & 0xff)); } @Override public UUID readUuid() throws TException { byte[] buf = inoutTemp; int off = 0; if (trans_.getBytesRemainingInBuffer() >= 16) { buf = trans_.getBuffer(); off = trans_.getBufferPosition(); trans_.consumeBuffer(16); } else { readAll(inoutTemp, 0, 16); } ByteBuffer bb = ByteBuffer.wrap(buf, off, 16); long msb = bb.getLong(); long lsb = bb.getLong(); return new UUID(msb, lsb); } @Override public double readDouble() throws TException { return Double.longBitsToDouble(readI64()); } @Override public String readString() throws TException { int size = readI32(); if (trans_.getBytesRemainingInBuffer() >= size) { String s = new String(trans_.getBuffer(), trans_.getBufferPosition(), size, StandardCharsets.UTF_8); trans_.consumeBuffer(size); return s; } return readStringBody(size); } public String readStringBody(int size) throws TException { checkStringReadLength(size); byte[] buf = new byte[size]; trans_.readAll(buf, 0, size); return new String(buf, StandardCharsets.UTF_8); } @Override public ByteBuffer readBinary() throws TException { int size = readI32(); checkStringReadLength(size); if (trans_.getBytesRemainingInBuffer() >= size) { ByteBuffer bb = ByteBuffer.wrap(trans_.getBuffer(), trans_.getBufferPosition(), size); trans_.consumeBuffer(size); return bb; } byte[] buf = new byte[size]; trans_.readAll(buf, 0, size); return ByteBuffer.wrap(buf); } private void checkStringReadLength(int length) throws TException { if (length < 0) { throw new TProtocolException(TProtocolException.NEGATIVE_SIZE, "Negative length: " + length); } getTransport().checkReadBytesAvailable(length); if (stringLengthLimit_ != NO_LENGTH_LIMIT && length > stringLengthLimit_) { throw new TProtocolException( TProtocolException.SIZE_LIMIT, "Length exceeded max allowed: " + length); } } private void checkContainerReadLength(int length) throws TProtocolException { if (length < 0) { throw new TProtocolException(TProtocolException.NEGATIVE_SIZE, "Negative length: " + length); } if (containerLengthLimit_ != NO_LENGTH_LIMIT && length > containerLengthLimit_) { throw new TProtocolException( TProtocolException.SIZE_LIMIT, "Length exceeded max allowed: " + length); } } private int readAll(byte[] buf, int off, int len) throws TException { return trans_.readAll(buf, off, len); } /** Return the minimum number of bytes a type will consume on the wire */ @Override public int getMinSerializedSize(byte type) throws TTransportException { switch (type) { case 0: return 1; // Stop - T_STOP needs to count itself case 1: return 1; // Void - T_VOID needs to count itself case 2: return 1; // Bool sizeof(byte) case 3: return 1; // Byte sizeof(byte) case 4: return 8; // Double sizeof(double) case 6: return 2; // I16 sizeof(short) case 8: return 4; // I32 sizeof(int) case 10: return 8; // I64 sizeof(long) case 11: return 4; // string length sizeof(int) case 12: return 1; // empty struct needs at least 1 byte for the T_STOP case 13: return 4; // element count Map sizeof(int) case 14: return 4; // element count Set sizeof(int) case 15: return 4; // element count List sizeof(int) default: throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code"); } } // ----------------------------------------------------------------- // Additional methods to improve performance. @Override public int readFieldBeginData() throws TException { byte type = this.readByte(); if (type == TType.STOP) { return TFieldData.encode(type); } short id = this.readI16(); return TFieldData.encode(type, id); } @Override protected void skipBool() throws TException { this.skipBytes(1); } @Override protected void skipByte() throws TException { this.skipBytes(1); } @Override protected void skipI16() throws TException { this.skipBytes(2); } @Override protected void skipI32() throws TException { this.skipBytes(4); } @Override protected void skipI64() throws TException { this.skipBytes(8); } @Override protected void skipDouble() throws TException { this.skipBytes(8); } @Override protected void skipBinary() throws TException { int size = readI32(); this.skipBytes(size); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TMessageType.java0000664000175000017500000000210015165535636030077 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** Message type constants in the Thrift protocol. */ public final class TMessageType { public static final byte CALL = 1; public static final byte REPLY = 2; public static final byte EXCEPTION = 3; public static final byte ONEWAY = 4; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TTupleProtocol.java0000664000175000017500000000724715165535636030505 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.util.BitSet; import org.apache.thrift.TException; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.TupleScheme; import org.apache.thrift.transport.TTransport; public final class TTupleProtocol extends TCompactProtocol { public static class Factory implements TProtocolFactory { public Factory() {} @Override public TProtocol getProtocol(TTransport trans) { return new TTupleProtocol(trans); } } public TTupleProtocol(TTransport transport) { super(transport); } @Override public Class getScheme() { return TupleScheme.class; } public void writeBitSet(BitSet bs, int vectorWidth) throws TException { byte[] bytes = toByteArray(bs, vectorWidth); for (byte b : bytes) { writeByte(b); } } public BitSet readBitSet(int i) throws TException { int length = (int) Math.ceil(i / 8.0); byte[] bytes = new byte[length]; for (int j = 0; j < length; j++) { bytes[j] = readByte(); } BitSet bs = fromByteArray(bytes); return bs; } /** Returns a bitset containing the values in bytes. The byte-ordering must be big-endian. */ public static BitSet fromByteArray(byte[] bytes) { BitSet bits = new BitSet(); for (int i = 0; i < bytes.length * 8; i++) { if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0) { bits.set(i); } } return bits; } /** * Returns a byte array of at least length 1. The most significant bit in the result is guaranteed * not to be a 1 (since BitSet does not support sign extension). The byte-ordering of the result * is big-endian which means the most significant bit is in element 0. The bit at index 0 of the * bit set is assumed to be the least significant bit. * * @param bits bit set * @param vectorWidth width of the vector * @return a byte array of at least length 1 */ public static byte[] toByteArray(BitSet bits, int vectorWidth) { byte[] bytes = new byte[(int) Math.ceil(vectorWidth / 8.0)]; for (int i = 0; i < bits.length(); i++) { if (bits.get(i)) { bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8); } } return bytes; } public TMap readMapBegin(byte keyType, byte valTyep) throws TException { int size = super.readI32(); TMap map = new TMap(keyType, valTyep, size); checkReadBytesAvailable(map); return map; } public TList readListBegin(byte type) throws TException { int size = super.readI32(); TList list = new TList(type, size); checkReadBytesAvailable(list); return list; } public TSet readSetBegin(byte type) throws TException { return new TSet(readListBegin(type)); } @Override public void readMapEnd() throws TException {} @Override public void readListEnd() throws TException {} @Override public void readSetEnd() throws TException {} } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TBase64Utils.java0000664000175000017500000001264615165535636027736 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Class for encoding and decoding Base64 data. * *

This class is kept at package level because the interface does no input validation and is * therefore too low-level for generalized reuse. * *

Note also that the encoding does not pad with equal signs , as discussed in section 2.2 of the * RFC (http://www.faqs.org/rfcs/rfc3548.html). Furthermore, bad data encountered when decoding is * neither rejected or ignored but simply results in bad decoded data -- this is not in compliance * with the RFC but is done in the interest of performance. */ class TBase64Utils { private static final String ENCODE_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * Encode len bytes of data in src at offset srcOff, storing the result into dst at offset dstOff. * len must be 1, 2, or 3. dst must have at least len+1 bytes of space at dstOff. src and dst * should not be the same object. This method does no validation of the input values in the * interest of performance. * * @param src the source of bytes to encode * @param srcOff the offset into the source to read the unencoded bytes * @param len the number of bytes to encode (must be 1, 2, or 3). * @param dst the destination for the encoding * @param dstOff the offset into the destination to place the encoded bytes */ static void encode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { dst[dstOff] = (byte) ENCODE_TABLE.charAt((src[srcOff] >> 2) & 0x3F); if (len == 3) { dst[dstOff + 1] = (byte) ENCODE_TABLE.charAt(((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)); dst[dstOff + 2] = (byte) ENCODE_TABLE.charAt( ((src[srcOff + 1] << 2) & 0x3C) | ((src[srcOff + 2] >> 6) & 0x03)); dst[dstOff + 3] = (byte) ENCODE_TABLE.charAt(src[srcOff + 2] & 0x3F); } else if (len == 2) { dst[dstOff + 1] = (byte) ENCODE_TABLE.charAt(((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)); dst[dstOff + 2] = (byte) ENCODE_TABLE.charAt((src[srcOff + 1] << 2) & 0x3C); } else { // len == 1) { dst[dstOff + 1] = (byte) ENCODE_TABLE.charAt((src[srcOff] << 4) & 0x30); } } private static final byte[] DECODE_TABLE = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; /** * Decode len bytes of data in src at offset srcOff, storing the result into dst at offset dstOff. * len must be 2, 3, or 4. dst must have at least len-1 bytes of space at dstOff. src and dst may * be the same object as long as dstoff <= srcOff. This method does no validation of the input * values in the interest of performance. * * @param src the source of bytes to decode * @param srcOff the offset into the source to read the encoded bytes * @param len the number of bytes to decode (must be 2, 3, or 4) * @param dst the destination for the decoding * @param dstOff the offset into the destination to place the decoded bytes */ static void decode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { dst[dstOff] = (byte) ((DECODE_TABLE[src[srcOff] & 0x0FF] << 2) | (DECODE_TABLE[src[srcOff + 1] & 0x0FF] >> 4)); if (len > 2) { dst[dstOff + 1] = (byte) (((DECODE_TABLE[src[srcOff + 1] & 0x0FF] << 4) & 0xF0) | (DECODE_TABLE[src[srcOff + 2] & 0x0FF] >> 2)); if (len > 3) { dst[dstOff + 2] = (byte) (((DECODE_TABLE[src[srcOff + 2] & 0x0FF] << 6) & 0xC0) | DECODE_TABLE[src[srcOff + 3] & 0x0FF]); } } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TMultiplexedProtocol.java0000664000175000017500000000655115165535636031705 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; /** * TMultiplexedProtocol is a protocol-independent concrete decorator that allows a * Thrift client to communicate with a multiplexing Thrift server, by prepending the service name to * the function name during function calls. * *

NOTE: THIS IS NOT USED BY SERVERS. On the server, use {@link * org.apache.thrift.TMultiplexedProcessor TMultiplexedProcessor} to handle requests from a * multiplexing client. * *

This example uses a single socket transport to invoke two services: * *

{@code
 * TSocket transport = new TSocket("localhost", 9090);
 * transport.open();
 *
 * TBinaryProtocol protocol = new TBinaryProtocol(transport);
 *
 * TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
 * Calculator.Client service = new Calculator.Client(mp);
 *
 * TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
 * WeatherReport.Client service2 = new WeatherReport.Client(mp2);
 *
 * System.out.println(service.add(2,2));
 * System.out.println(service2.getTemperature());
 * }
* * @see org.apache.thrift.protocol.TProtocolDecorator */ public class TMultiplexedProtocol extends TProtocolDecorator { /** Used to delimit the service name from the function name */ public static final String SEPARATOR = ":"; private final String SERVICE_NAME; /** * Wrap the specified protocol, allowing it to be used to communicate with a multiplexing server. * The serviceName is required as it is prepended to the message header so that the * multiplexing server can broker the function call to the proper service. * * @param protocol Your communication protocol of choice, e.g. TBinaryProtocol. * @param serviceName The service name of the service communicating via this protocol. */ public TMultiplexedProtocol(TProtocol protocol, String serviceName) { super(protocol); SERVICE_NAME = serviceName; } /** * Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR. * * @param tMessage The original message. * @throws TException Passed through from wrapped TProtocol instance. */ @Override public void writeMessageBegin(TMessage tMessage) throws TException { if (tMessage.type == TMessageType.CALL || tMessage.type == TMessageType.ONEWAY) { super.writeMessageBegin( new TMessage(SERVICE_NAME + SEPARATOR + tMessage.name, tMessage.type, tMessage.seqid)); } else { super.writeMessageBegin(tMessage); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/protocol/TMap.java0000664000175000017500000000245015165535636026376 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** Helper class that encapsulates map metadata. */ public final class TMap { public TMap() { this(TType.STOP, TType.STOP, 0); } public TMap(byte k, byte v, int s) { keyType = k; valueType = v; size = s; } public final byte keyType; public final byte valueType; public final int size; public byte getKeyType() { return keyType; } public byte getValueType() { return valueType; } public int getSize() { return size; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TMultiplexedProcessor.java0000664000175000017500000001412415165535636030215 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.util.HashMap; import java.util.Map; import org.apache.thrift.protocol.*; /** * TMultiplexedProcessor is a TProcessor allowing a single TServer * to provide multiple services. * *

To do so, you instantiate the processor and then register additional processors with it, as * shown in the following example: * *

* * * TMultiplexedProcessor processor = new TMultiplexedProcessor(); * * processor.registerProcessor( * "Calculator", * new Calculator.Processor(new CalculatorHandler())); * * processor.registerProcessor( * "WeatherReport", * new WeatherReport.Processor(new WeatherReportHandler())); * * TServerTransport t = new TServerSocket(9090); * TSimpleServer server = new TSimpleServer(processor, t); * * server.serve(); * * *
*/ public class TMultiplexedProcessor implements TProcessor { private final Map SERVICE_PROCESSOR_MAP = new HashMap(); private TProcessor defaultProcessor; /** * 'Register' a service with this TMultiplexedProcessor. This allows us to broker * requests to individual services by using the service name to select them at request time. * * @param serviceName Name of a service, has to be identical to the name declared in the Thrift * IDL, e.g. "WeatherReport". * @param processor Implementation of a service, usually referred to as "handlers", e.g. * WeatherReportHandler implementing WeatherReport.Iface. */ public void registerProcessor(String serviceName, TProcessor processor) { SERVICE_PROCESSOR_MAP.put(serviceName, processor); } /** * Register a service to be called to process queries without service name * * @param processor the service to be called. */ public void registerDefault(TProcessor processor) { defaultProcessor = processor; } /** * This implementation of process performs the following steps: * *
    *
  1. Read the beginning of the message. *
  2. Extract the service name from the message. *
  3. Using the service name to locate the appropriate processor. *
  4. Dispatch to the processor, with a decorated instance of TProtocol that allows * readMessageBegin() to return the original TMessage. *
* * @throws TProtocolException If the message type is not CALL or ONEWAY, if the service name was * not found in the message, or if the service name was not found in the service map. You * called {@link #registerProcessor(String, TProcessor) registerProcessor} during * initialization, right? :) */ @Override public void process(TProtocol iprot, TProtocol oprot) throws TException { /* Use the actual underlying protocol (e.g. TBinaryProtocol) to read the message header. This pulls the message "off the wire", which we'll deal with at the end of this method. */ TMessage message = iprot.readMessageBegin(); if (message.type != TMessageType.CALL && message.type != TMessageType.ONEWAY) { throw new TProtocolException( TProtocolException.NOT_IMPLEMENTED, "This should not have happened!?"); } // Extract the service name int index = message.name.indexOf(TMultiplexedProtocol.SEPARATOR); if (index < 0) { if (defaultProcessor != null) { // Dispatch processing to the stored processor defaultProcessor.process(new StoredMessageProtocol(iprot, message), oprot); return; } throw new TProtocolException( TProtocolException.NOT_IMPLEMENTED, "Service name not found in message name: " + message.name + ". Did you " + "forget to use a TMultiplexProtocol in your client?"); } // Create a new TMessage, something that can be consumed by any TProtocol String serviceName = message.name.substring(0, index); TProcessor actualProcessor = SERVICE_PROCESSOR_MAP.get(serviceName); if (actualProcessor == null) { throw new TProtocolException( TProtocolException.NOT_IMPLEMENTED, "Service name not found: " + serviceName + ". Did you forget " + "to call registerProcessor()?"); } // Create a new TMessage, removing the service name TMessage standardMessage = new TMessage( message.name.substring(serviceName.length() + TMultiplexedProtocol.SEPARATOR.length()), message.type, message.seqid); // Dispatch processing to the stored processor actualProcessor.process(new StoredMessageProtocol(iprot, standardMessage), oprot); } /** * Our goal was to work with any protocol. In order to do that, we needed to allow them to call * readMessageBegin() and get a TMessage in exactly the standard format, without the service name * prepended to TMessage.name. */ private static class StoredMessageProtocol extends TProtocolDecorator { TMessage messageBegin; public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin) { super(protocol); this.messageBegin = messageBegin; } @Override public TMessage readMessageBegin() throws TException { return messageBegin; } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/EncodingUtils.java0000664000175000017500000001177615165535636026456 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** Utility methods for use when encoding/decoding raw data as byte arrays. */ public class EncodingUtils { /** * Encode integer as a series of 4 bytes into buf starting at position 0 * within that buffer. * * @param integer The integer to encode. * @param buf The buffer to write to. */ public static final void encodeBigEndian(final int integer, final byte[] buf) { encodeBigEndian(integer, buf, 0); } /** * Encode integer as a series of 4 bytes into buf starting at position * offset. * * @param integer The integer to encode. * @param buf The buffer to write to. * @param offset The offset within buf to start the encoding. */ public static final void encodeBigEndian(final int integer, final byte[] buf, int offset) { buf[offset] = (byte) (0xff & (integer >> 24)); buf[offset + 1] = (byte) (0xff & (integer >> 16)); buf[offset + 2] = (byte) (0xff & (integer >> 8)); buf[offset + 3] = (byte) (0xff & (integer)); } /** * Decode a series of 4 bytes from buf, starting at position 0, and interpret them as * an integer. * * @param buf The buffer to read from. * @return An integer, as read from the buffer. */ public static final int decodeBigEndian(final byte[] buf) { return decodeBigEndian(buf, 0); } /** * Decode a series of 4 bytes from buf, start at offset, and interpret * them as an integer. * * @param buf The buffer to read from. * @param offset The offset with buf to start the decoding. * @return An integer, as read from the buffer. */ public static final int decodeBigEndian(final byte[] buf, int offset) { return ((buf[offset] & 0xff) << 24) | ((buf[offset + 1] & 0xff) << 16) | ((buf[offset + 2] & 0xff) << 8) | ((buf[offset + 3] & 0xff)); } /** * Bitfield utilities. Returns true if the bit at position is set in v. * * @param v the value whose bit is to be checked. * @param position the 0 based bit number indicating the bit to check. * @return true if the bit at position is set in v. */ public static final boolean testBit(byte v, int position) { return testBit((int) v, position); } public static final boolean testBit(short v, int position) { return testBit((int) v, position); } public static final boolean testBit(int v, int position) { return (v & (1 << position)) != 0; } public static final boolean testBit(long v, int position) { return (v & (1L << position)) != 0L; } /** * Returns v, with the bit at position set to zero. * * @param v the value whose bit is to be cleared. * @param position the 0 based bit number indicating the bit to clear. * @return v, with the bit at position set to zero. */ public static final byte clearBit(byte v, int position) { return (byte) clearBit((int) v, position); } public static final short clearBit(short v, int position) { return (short) clearBit((int) v, position); } public static final int clearBit(int v, int position) { return v & ~(1 << position); } public static final long clearBit(long v, int position) { return v & ~(1L << position); } /** * Returns v, with the bit at position set to 1 or 0 depending on value. * * @param v the value whose bit is to be set. * @param position the 0 based bit number indicating the bit to set. * @param value if true, the given bit is set to 1; otherwise it is set to 0. * @return v, with the bit at position set to 0 (if value is false) or 1 (if value is true). */ public static final byte setBit(byte v, int position, boolean value) { return (byte) setBit((int) v, position, value); } public static final short setBit(short v, int position, boolean value) { return (short) setBit((int) v, position, value); } public static final int setBit(int v, int position, boolean value) { if (value) return v | (1 << position); else return clearBit(v, position); } public static final long setBit(long v, int position, boolean value) { if (value) return v | (1L << position); else return clearBit(v, position); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TBase.java0000664000175000017500000000436215165535636024676 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.Serializable; /** Generic base interface for generated Thrift objects. */ public interface TBase, F extends TFieldIdEnum> extends Comparable, TSerializable, Serializable { /** * Get the F instance that corresponds to fieldId. * * @param fieldId the ID of the requested field. * @return F instance that corresponds to fieldId. */ F fieldForId(int fieldId); /** * Check if a field is currently set or unset. * * @param field the field to check. * @return true if the field is set, false otherwise. */ boolean isSet(F field); /** * Get a field's value by field variable. Primitive types will be wrapped in the appropriate * "boxed" types. * * @param field the field whose value is requested. * @return the value of the requested field. */ Object getFieldValue(F field); /** * Set a field's value by field variable. Primitive types must be "boxed" in the appropriate * object wrapper type. * * @param field the field whose value is to be set. * @param value the value to be assigned to field. */ void setFieldValue(F field, Object value); /** * Performs a deep copy of this instance and returns the copy. * * @return a deep copy of this instance. */ T deepCopy(); /** * Return to the state of having just been initialized, as though you had just called the default * constructor. */ void clear(); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TConfiguration.java0000664000175000017500000000570315165535636026633 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; public class TConfiguration { public static final int DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024; public static final int DEFAULT_MAX_FRAME_SIZE = 16384000; // this value is used consistently across all Thrift libraries public static final int DEFAULT_RECURSION_DEPTH = 64; private int maxMessageSize; private int maxFrameSize; private int recursionLimit; public TConfiguration() { this(DEFAULT_MAX_MESSAGE_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_RECURSION_DEPTH); } public TConfiguration(int maxMessageSize, int maxFrameSize, int recursionLimit) { this.maxFrameSize = maxFrameSize; this.maxMessageSize = maxMessageSize; this.recursionLimit = recursionLimit; } public int getMaxMessageSize() { return maxMessageSize; } public int getMaxFrameSize() { return maxFrameSize; } public int getRecursionLimit() { return recursionLimit; } public void setMaxMessageSize(int maxMessageSize) { this.maxMessageSize = maxMessageSize; } public void setMaxFrameSize(int maxFrameSize) { this.maxFrameSize = maxFrameSize; } public void setRecursionLimit(int recursionLimit) { this.recursionLimit = recursionLimit; } public static final TConfiguration DEFAULT = new Builder().build(); public static TConfiguration.Builder custom() { return new Builder(); } public static class Builder { private int maxMessageSize; private int maxFrameSize; private int recursionLimit; Builder() { super(); this.maxFrameSize = DEFAULT_MAX_FRAME_SIZE; this.maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE; this.recursionLimit = DEFAULT_RECURSION_DEPTH; } public Builder setMaxMessageSize(int maxMessageSize) { this.maxMessageSize = maxMessageSize; return this; } public Builder setMaxFrameSize(int maxFrameSize) { this.maxFrameSize = maxFrameSize; return this; } public Builder setRecursionLimit(int recursionLimit) { this.recursionLimit = recursionLimit; return this; } public TConfiguration build() { return new TConfiguration(maxMessageSize, maxFrameSize, recursionLimit); } } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TBaseHelper.java0000664000175000017500000002053615165535636026037 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; public final class TBaseHelper { private TBaseHelper() {} private static final Comparator comparator = new NestedStructureComparator(); public static int compareTo(Object o1, Object o2) { if (o1 instanceof Comparable) { return compareTo((Comparable) o1, (Comparable) o2); } else if (o1 instanceof List) { return compareTo((List) o1, (List) o2); } else if (o1 instanceof Set) { return compareTo((Set) o1, (Set) o2); } else if (o1 instanceof Map) { return compareTo((Map) o1, (Map) o2); } else if (o1 instanceof byte[]) { return compareTo((byte[]) o1, (byte[]) o2); } else { throw new IllegalArgumentException("Cannot compare objects of type " + o1.getClass()); } } public static int compareTo(boolean a, boolean b) { return Boolean.compare(a, b); } public static int compareTo(byte a, byte b) { return Byte.compare(a, b); } public static int compareTo(short a, short b) { return Short.compare(a, b); } public static int compareTo(int a, int b) { return Integer.compare(a, b); } public static int compareTo(long a, long b) { return Long.compare(a, b); } public static int compareTo(double a, double b) { return Double.compare(a, b); } public static int compareTo(String a, String b) { return a.compareTo(b); } public static int compareTo(byte[] a, byte[] b) { int compare = compareTo(a.length, b.length); if (compare == 0) { for (int i = 0; i < a.length; i++) { compare = compareTo(a[i], b[i]); if (compare != 0) { break; } } } return compare; } public static int compareTo(Comparable a, Comparable b) { return a.compareTo(b); } public static int compareTo(List a, List b) { int compare = compareTo(a.size(), b.size()); if (compare == 0) { for (int i = 0; i < a.size(); i++) { compare = comparator.compare(a.get(i), b.get(i)); if (compare != 0) { break; } } } return compare; } public static int compareTo(Set a, Set b) { int compare = compareTo(a.size(), b.size()); if (compare == 0) { ArrayList sortedA = new ArrayList(a); ArrayList sortedB = new ArrayList(b); Collections.sort(sortedA, comparator); Collections.sort(sortedB, comparator); Iterator iterA = sortedA.iterator(); Iterator iterB = sortedB.iterator(); // Compare each item. while (iterA.hasNext() && iterB.hasNext()) { compare = comparator.compare(iterA.next(), iterB.next()); if (compare != 0) { break; } } } return compare; } public static int compareTo(Map a, Map b) { int lastComparison = compareTo(a.size(), b.size()); if (lastComparison != 0) { return lastComparison; } // Sort a and b so we can compare them. SortedMap sortedA = new TreeMap(comparator); sortedA.putAll(a); Iterator iterA = sortedA.entrySet().iterator(); SortedMap sortedB = new TreeMap(comparator); sortedB.putAll(b); Iterator iterB = sortedB.entrySet().iterator(); // Compare each item. while (iterA.hasNext() && iterB.hasNext()) { Map.Entry entryA = iterA.next(); Map.Entry entryB = iterB.next(); lastComparison = comparator.compare(entryA.getKey(), entryB.getKey()); if (lastComparison != 0) { return lastComparison; } lastComparison = comparator.compare(entryA.getValue(), entryB.getValue()); if (lastComparison != 0) { return lastComparison; } } return 0; } /** Comparator to compare items inside a structure (e.g. a list, set, or map). */ private static class NestedStructureComparator implements Comparator, Serializable { public int compare(Object oA, Object oB) { if (oA == null && oB == null) { return 0; } else if (oA == null) { return -1; } else if (oB == null) { return 1; } else if (oA instanceof List) { return compareTo((List) oA, (List) oB); } else if (oA instanceof Set) { return compareTo((Set) oA, (Set) oB); } else if (oA instanceof Map) { return compareTo((Map) oA, (Map) oB); } else if (oA instanceof byte[]) { return compareTo((byte[]) oA, (byte[]) oB); } else { return compareTo((Comparable) oA, (Comparable) oB); } } } public static void toString(Collection bbs, StringBuilder sb) { Iterator it = bbs.iterator(); if (!it.hasNext()) { sb.append("[]"); } else { sb.append("["); while (true) { ByteBuffer bb = it.next(); org.apache.thrift.TBaseHelper.toString(bb, sb); if (!it.hasNext()) { sb.append("]"); return; } else { sb.append(", "); } } } } public static void toString(ByteBuffer bb, StringBuilder sb) { byte[] buf = bb.array(); int arrayOffset = bb.arrayOffset(); int offset = arrayOffset + bb.position(); int origLimit = arrayOffset + bb.limit(); int limit = (origLimit - offset > 128) ? offset + 128 : origLimit; for (int i = offset; i < limit; i++) { if (i > offset) { sb.append(" "); } sb.append(paddedByteString(buf[i])); } if (origLimit != limit) { sb.append("..."); } } public static String paddedByteString(byte b) { int extended = (b | 0x100) & 0x1ff; return Integer.toHexString(extended).toUpperCase().substring(1); } public static byte[] byteBufferToByteArray(ByteBuffer byteBuffer) { if (wrapsFullArray(byteBuffer)) { return byteBuffer.array(); } byte[] target = new byte[byteBuffer.remaining()]; byteBufferToByteArray(byteBuffer, target, 0); return target; } public static boolean wrapsFullArray(ByteBuffer byteBuffer) { return byteBuffer.hasArray() && byteBuffer.position() == 0 && byteBuffer.arrayOffset() == 0 && byteBuffer.remaining() == byteBuffer.capacity(); } public static int byteBufferToByteArray(ByteBuffer byteBuffer, byte[] target, int offset) { int remaining = byteBuffer.remaining(); System.arraycopy( byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(), target, offset, remaining); return remaining; } public static ByteBuffer rightSize(ByteBuffer in) { if (in == null) { return null; } if (wrapsFullArray(in)) { return in; } return ByteBuffer.wrap(byteBufferToByteArray(in)); } public static ByteBuffer copyBinary(final ByteBuffer orig) { if (orig == null) { return null; } ByteBuffer copy = ByteBuffer.wrap(new byte[orig.remaining()]); if (orig.hasArray()) { System.arraycopy( orig.array(), orig.arrayOffset() + orig.position(), copy.array(), 0, orig.remaining()); } else { orig.slice().get(copy.array()); } return copy; } public static byte[] copyBinary(final byte[] orig) { return (orig == null) ? null : Arrays.copyOf(orig, orig.length); } public static int hashCode(long value) { return Long.hashCode(value); } public static int hashCode(double value) { return Double.hashCode(value); } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TSerializable.java0000664000175000017500000000256615165535636026436 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** Generic base interface for generated Thrift objects. */ public interface TSerializable { /** * Reads the TObject from the given input protocol. * * @param iprot Input protocol * @throws TException if there is an error reading from iprot */ void read(TProtocol iprot) throws TException; /** * Writes the objects out to the protocol * * @param oprot Output protocol * @throws TException if there is an error writing to oprot */ void write(TProtocol oprot) throws TException; } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TFieldIdEnum.java0000664000175000017500000000230615165535636026145 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** Interface for all generated struct Fields objects. */ public interface TFieldIdEnum { /** * Gets the Thrift field id for the named field. * * @return the Thrift field id for the named field. */ short getThriftFieldId(); /** * Gets the field's name, exactly as in the IDL. * * @return the field's name, exactly as in the IDL. */ String getFieldName(); } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/TProcessorFactory.java0000664000175000017500000000240615165535636027330 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.transport.TTransport; /** The default processor factory just returns a singleton instance. */ public class TProcessorFactory { private final TProcessor processor_; public TProcessorFactory(TProcessor processor) { processor_ = processor; } public TProcessor getProcessor(TTransport trans) { return processor_; } public boolean isAsyncProcessor() { return processor_ instanceof TAsyncProcessor; } } thrift-0.23.0/lib/java/src/main/java/org/apache/thrift/AsyncProcessFunction.java0000664000175000017500000000406615165535636030023 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.async.AsyncMethodCallback; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.server.AbstractNonblockingServer; public abstract class AsyncProcessFunction { final String methodName; public AsyncProcessFunction(String methodName) { this.methodName = methodName; } 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); public String getMethodName() { return methodName; } public void sendResponse( final AbstractNonblockingServer.AsyncFrameBuffer fb, final TSerializable result, final byte type, final int seqid) throws TException { TProtocol oprot = fb.getOutputProtocol(); oprot.writeMessageBegin(new TMessage(getMethodName(), type, seqid)); result.write(oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); fb.responseReady(); } } thrift-0.23.0/lib/java/src/test/0000775000175000017500000000000015165535636016632 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/resources/0000775000175000017500000000000015165535636020644 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/resources/JavaDeepCopyTest.thrift0000664000175000017500000000233615165535636025244 0ustar00buildbuild00000000000000/* * 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 "JavaTypes.thrift" namespace java thrift.test struct DeepCopyFoo { 1: optional list l, 2: optional set s, 3: optional map m, 4: optional list li, 5: optional set si, 6: optional map mi, 7: optional DeepCopyBar bar, } struct DeepCopyBar { 1: optional string a, 2: optional i32 b, 3: optional bool c, } thrift-0.23.0/lib/java/src/test/resources/JavaBeansTest.thrift0000664000175000017500000000221615165535636024561 0ustar00buildbuild00000000000000/* * 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 java thrift.test struct OneOfEachBeans { 1: bool boolean_field, 2: byte a_bite, 3: i16 integer16, 4: i32 integer32, 5: i64 integer64, 6: double double_precision, 7: string some_characters, 8: binary base64, 9: list byte_list, 10: list i16_list, 11: list i64_list } service Service { i64 mymethod(i64 blah); }thrift-0.23.0/lib/java/src/test/resources/log4j.properties0000664000175000017500000000046415165535636024005 0ustar00buildbuild00000000000000# log4j configuration used during build and unit tests log4j.rootLogger=warn,stdout log4j.threshold=ALL log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n thrift-0.23.0/lib/java/src/test/resources/JavaDefinitionOrderB.thrift0000664000175000017500000000314215165535636026056 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // Define Child, then Parent. Parent is a forward declaration and was problematic for our Java compiler before // fixing THRIFT-4086: Java compiler generates different meta data depending on order of structures in file struct Child { 1: required string Name 2: required Age Age 3: required Parent Parent1 4: required MyParent Parent2 5: required Parents GrandParents 6: required MyEnum MyEnum 7: required MyEnumV2 MyEnumV2 8: required MyEnums MyEnums 9: required MyMapping MyMapping 10: required MyBinary MyBinary } typedef i8 Age typedef Parent MyParent typedef list Parents typedef MyEnum MyEnumV2 typedef set MyEnums typedef map MyMapping typedef binary MyBinary struct Parent { 1: required string Name } enum MyEnum { FOO = 1 BAR = 2 } thrift-0.23.0/lib/java/src/test/resources/JavaTypes.thrift0000664000175000017500000000357015165535636024001 0ustar00buildbuild00000000000000/* * 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 java thrift.test struct Integer { 1: i32 val } struct String { 1: string val } struct Binary { 1: binary val } struct Boolean { 1: bool val } struct Double { 1: double val } struct Long { 1: i64 val } struct Byte { 1: byte val } struct Float { 1: double val } struct Uuid { 1: uuid val } struct List { 1: list vals } struct ArrayList { 1: list vals } struct SortedMap { 1: map vals } struct TreeMap { 1: map vals } struct HashMap { 1: map vals } struct Map { 1: map vals } struct Object { 1: Integer integer, 2: String str, 3: Boolean boolean_field, 4: Double dbl, 5: Byte bite, 6: map intmap, 7: Map somemap, } exception Exception { 1: string msg } service AsyncNonblockingService { Object mymethod( 1: Integer integer, 2: String str, 3: Boolean boolean_field, 4: Double dbl, 5: Byte bite, 6: map intmap, 7: Map somemap, ) throws (1:Exception ex); } struct SafeBytes { 1: binary bytes; } thrift-0.23.0/lib/java/src/test/resources/JavaAnnotationTest.thrift0000664000175000017500000000252015165535636025641 0ustar00buildbuild00000000000000/* * 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 java thrift.test.annotations typedef string my_typedef (a = "a", c = "d") struct OneOfEachBeansWithAnnotations { 1: bool boolean_field, 2: byte a_bite (compression = "false"), 3: i16 integer16 (must_be_postive = "true"), 4: i32 integer32, 5: i64 integer64, 6: double double_precision (nan_inf_allowed = "false"), 7: string some_characters, 8: binary base64, 9: list byte_list (non_empty = "true"), 10: list i16_list, 11: list i64_list, // a is overridden to b 12: my_typedef typedef_meta (a = "b"), } thrift-0.23.0/lib/java/src/test/resources/JavaBinaryDefault.thrift0000664000175000017500000000163615165535636025427 0ustar00buildbuild00000000000000/* * 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 java thrift.test struct StringAndBinary { 1: optional string strval = "" 2: optional binary binval = "" } thrift-0.23.0/lib/java/src/test/resources/JavaOptionTypeJdk8Test.thrift0000664000175000017500000000244315165535636026366 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace java thrift.test.optiontypejdk8 struct Person { 1: required i64 id; 2: required string name; 3: optional i64 age; 4: optional string phone; 5: optional list addresses; 6: optional map pets; } enum PetType { Cat = 1 Dog = 2 Bunny = 3 } struct Pet { 1: required string name; 2: optional PetType type; } thrift-0.23.0/lib/java/src/test/resources/JavaDefinitionOrderA.thrift0000664000175000017500000000267715165535636026071 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // Define Parent, then Child. No forward declarations. struct Parent { 1: required string Name } typedef Parent MyParent typedef list Parents enum MyEnum { FOO = 1 BAR = 2 } typedef i8 Age typedef MyEnum MyEnumV2 typedef set MyEnums typedef map MyMapping typedef binary MyBinary struct Child { 1: required string Name 2: required Age Age 3: required Parent Parent1 4: required MyParent Parent2 5: required Parents GrandParents 6: required MyEnum MyEnum 7: required MyEnumV2 MyEnumV2 8: required MyEnums MyEnums 9: required MyMapping MyMapping 10: required MyBinary MyBinary } thrift-0.23.0/lib/java/src/test/java/0000775000175000017500000000000015165535636017553 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/0000775000175000017500000000000015165535636020342 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/0000775000175000017500000000000015165535636021563 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/0000775000175000017500000000000015165535636023063 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestTBaseHelper.java0000664000175000017500000001457415165535636026737 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.jupiter.api.Test; public class TestTBaseHelper { @Test public void testByteArrayComparison() { assertTrue(TBaseHelper.compareTo(new byte[] {'a', 'b'}, new byte[] {'a', 'c'}) < 0); } @Test public void testSets() { Set a = new HashSet<>(); Set b = new HashSet<>(); assertEquals(0, TBaseHelper.compareTo(a, b)); a.add("test"); assertTrue(TBaseHelper.compareTo(a, b) > 0); b.add("test"); assertEquals(0, TBaseHelper.compareTo(a, b)); b.add("aardvark"); assertTrue(TBaseHelper.compareTo(a, b) < 0); a.add("test2"); assertTrue(TBaseHelper.compareTo(a, b) > 0); } @Test public void testNestedStructures() { Set> a = new HashSet<>(); Set> b = new HashSet<>(); a.add(Arrays.asList("a", "b")); b.add(Arrays.asList("a", "b", "c")); a.add(Arrays.asList("a", "b")); b.add(Arrays.asList("a", "b", "c")); assertTrue(TBaseHelper.compareTo(a, b) < 0); } @Test public void testMapsInSets() { Set> a = new HashSet<>(); Set> b = new HashSet<>(); assertEquals(0, TBaseHelper.compareTo(a, b)); Map innerA = new HashMap<>(); Map innerB = new HashMap<>(); a.add(innerA); b.add(innerB); innerA.put("a", 1L); innerB.put("a", 2L); assertTrue(TBaseHelper.compareTo(a, b) < 0); } @Test public void testByteArraysInMaps() { Map a = new HashMap<>(); Map b = new HashMap<>(); assertEquals(0, TBaseHelper.compareTo(a, b)); a.put(new byte[] {'a', 'b'}, 1000L); b.put(new byte[] {'a', 'b'}, 1000L); a.put(new byte[] {'a', 'b', 'd'}, 1000L); b.put(new byte[] {'a', 'b', 'a'}, 1000L); assertTrue(TBaseHelper.compareTo(a, b) > 0); } @Test public void testMapsWithNulls() { Map a = new HashMap<>(); Map b = new HashMap<>(); a.put("a", null); a.put("b", null); b.put("a", null); b.put("b", null); assertEquals(0, TBaseHelper.compareTo(a, b)); } @Test public void testMapKeyComparison() { Map a = new HashMap<>(); Map b = new HashMap<>(); a.put("a", "a"); b.put("b", "a"); assertTrue(TBaseHelper.compareTo(a, b) < 0); } @Test public void testMapValueComparison() { Map a = new HashMap<>(); Map b = new HashMap<>(); a.put("a", "b"); b.put("a", "a"); assertTrue(TBaseHelper.compareTo(a, b) > 0); } @Test public void testByteArraysInSets() { Set a = new HashSet<>(); Set b = new HashSet<>(); if (TBaseHelper.compareTo(a, b) != 0) throw new RuntimeException("Set compare failed:" + a + " vs. " + b); a.add(new byte[] {'a', 'b'}); b.add(new byte[] {'a', 'b'}); a.add(new byte[] {'a', 'b', 'd'}); b.add(new byte[] {'a', 'b', 'a'}); assertTrue(TBaseHelper.compareTo(a, b) > 0); } @Test public void testByteBufferToByteArray() throws Exception { byte[] b1 = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; byte[] b2 = TBaseHelper.byteBufferToByteArray(ByteBuffer.wrap(b1)); assertEquals(b1, b2, "b1 and b2 should be the exact same array (identity) due to fast path"); byte[] b3 = TBaseHelper.byteBufferToByteArray(ByteBuffer.wrap(b1, 1, 3)); assertEquals(3, b3.length); assertEquals(ByteBuffer.wrap(b1, 1, 3), ByteBuffer.wrap(b3)); } @Test public void testRightSize() throws Exception { assertNull(TBaseHelper.rightSize(null)); } @Test public void testByteBufferToString() { byte[] array = new byte[] {1, 2, 3}; ByteBuffer bb = ByteBuffer.wrap(array, 1, 2); StringBuilder sb = new StringBuilder(); TBaseHelper.toString(bb, sb); assertEquals("02 03", sb.toString()); bb = ByteBuffer.wrap(array, 0, array.length); bb.position(1); bb = bb.slice(); assertEquals(1, bb.arrayOffset()); assertEquals(0, bb.position()); assertEquals(2, bb.limit()); sb = new StringBuilder(); TBaseHelper.toString(bb, sb); assertEquals("02 03", sb.toString()); } @Test public void testCopyBinaryWithByteBuffer() throws Exception { byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5}; ByteBuffer b = ByteBuffer.wrap(bytes); ByteBuffer bCopy = TBaseHelper.copyBinary(b); assertEquals(b, bCopy); assertEquals(0, b.position()); b = ByteBuffer.allocateDirect(6); b.put(bytes); b.position(0); bCopy = TBaseHelper.copyBinary(b); assertEquals(6, b.remaining()); assertEquals(0, b.position()); assertEquals(b, bCopy); b.mark(); b.get(); bCopy = TBaseHelper.copyBinary(b); assertEquals(ByteBuffer.wrap(bytes, 1, 5), bCopy); assertEquals(1, b.position()); b.reset(); assertEquals(0, b.position()); assertNull(TBaseHelper.copyBinary((ByteBuffer) null)); } @Test public void testCopyBinaryWithByteArray() throws Exception { byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5}; byte[] copy = TBaseHelper.copyBinary(bytes); assertEquals(ByteBuffer.wrap(bytes), ByteBuffer.wrap(copy)); assertNotSame(bytes, copy); assertNull(TBaseHelper.copyBinary((byte[]) null)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestRenderedDoubleConstants.java0000664000175000017500000002541515165535636031355 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import thrift.test.DoubleConstantsTestConstants; public class TestRenderedDoubleConstants { private static final double EPSILON = 0.0000001; private static final String ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST = "failed to verify a double constant generated by Thrift (expected = %f, got = %f)"; private static final String ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_LIST_TEST = "failed to verify a list item by Thrift (expected = %f, got = %f)"; private static final String ASSERTION_MESSAGE_FOR_TYPE_CHECKS = "the rendered variable with name %s is not of double type"; // to make sure lists containing doubles are generated correctly @Test public void testRenderedDoubleList() throws Exception { final double[] EXPECTED_LIST = { 1d, -100d, 100d, 9223372036854775807d, -9223372036854775807d, 3.14159265359, 1000000.1, -1000000.1, 1.7e+308, -1.7e+308, 9223372036854775816.43, -9223372036854775816.43 }; assertEquals(EXPECTED_LIST.length, DoubleConstantsTestConstants.DOUBLE_LIST_TEST.size()); for (int i = 0; i < EXPECTED_LIST.length; ++i) { assertEquals( EXPECTED_LIST[i], DoubleConstantsTestConstants.DOUBLE_LIST_TEST.get(i), EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_LIST_TEST, EXPECTED_LIST[i], DoubleConstantsTestConstants.DOUBLE_LIST_TEST.get(i))); } } // to make sure the variables inside Thrift files are generated correctly @Test public void testRenderedDoubleConstants() throws Exception { final double EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1.0; final double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100.0; final double EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807.0; final double EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807.0; final double EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359; final double EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1; final double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1; final double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308; final double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43; final double EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308; final double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43; assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST)); assertEquals( EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, EPSILON, String.format( ASSERTION_MESSAGE_FOR_RENDERED_DOUBLE_CONSTANTS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE, DoubleConstantsTestConstants .DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST)); assertTrue( Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST), String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST")); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST")); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST")); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST")); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST")); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST")); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST")); // assertTrue( // String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST"), // // Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST)); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST")); // assertTrue( // String.format(ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST"), // // Double.class.isInstance(DoubleConstantsTestConstants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST)); assertTrue( Double.class.isInstance( DoubleConstantsTestConstants .DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST), String.format( ASSERTION_MESSAGE_FOR_TYPE_CHECKS, "DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST")); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestTEnumHelper.java0000664000175000017500000000272015165535636026757 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; import thrift.test.Numberz; public class TestTEnumHelper { @Test public void testGetByValue_ValidValues() { for (Numberz n : Numberz.values()) { int value = n.getValue(); assertEquals(n, TEnumHelper.getByValue(Numberz.class, value)); } } @Test public void testGetByValue_InvalidValue() { assertNull(TEnumHelper.getByValue(Numberz.class, 0)); } @Test public void testGetByValue_InvalidClass() { assertNull(TEnumHelper.getByValue(TEnum.class, 0)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestTUnion.java0000664000175000017500000002063015165535636026003 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TTupleProtocol; import org.apache.thrift.transport.TMemoryBuffer; import org.junit.jupiter.api.Test; import thrift.test.ComparableUnion; import thrift.test.Empty; import thrift.test.RandomStuff; import thrift.test.SomeEnum; import thrift.test.StructWithAUnion; import thrift.test.TestUnion; import thrift.test.TestUnionMinusStringField; public class TestTUnion { @Test public void testBasic() throws Exception { { TestUnion union = new TestUnion(); assertFalse(union.isSet()); assertFalse(union.isSetI32_field()); assertNull(union.getFieldValue()); } { TestUnion union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); assertEquals(25, union.getFieldValue()); assertEquals(25, union.getFieldValue(TestUnion._Fields.I32_FIELD)); assertTrue(union.isSetI32_field()); assertThrows( IllegalArgumentException.class, () -> union.getFieldValue(TestUnion._Fields.STRING_FIELD)); } { TestUnion union = new TestUnion(); // should not throw an exception here union.hashCode(); union.setI32_field(1); assertEquals(1, union.getI32_field()); union.hashCode(); assertFalse(union.isSetString_field()); assertThrows(Exception.class, union::getString_field); } { TestUnion union = TestUnion.i32_field(1); assertFalse(union.equals(null)); } { TestUnion union = TestUnion.enum_field(SomeEnum.ONE); union.hashCode(); } { TestUnion union = new TestUnion(); // should not throw an exception union.toString(); } } @Test public void testCompareTo() throws Exception { ComparableUnion cu = ComparableUnion.string_field("a"); ComparableUnion cu2 = ComparableUnion.string_field("b"); assertEquals(0, cu.compareTo(cu)); assertEquals(0, cu2.compareTo(cu2)); assertTrue(cu.compareTo(cu2) < 0); assertTrue(cu2.compareTo(cu) > 0); cu2 = ComparableUnion.binary_field(ByteBuffer.wrap(new byte[] {2})); assertTrue(cu.compareTo(cu2) < 0); assertTrue(cu2.compareTo(cu) > 0); cu = ComparableUnion.binary_field(ByteBuffer.wrap(new byte[] {1})); assertTrue(cu.compareTo(cu2) < 0); assertTrue(cu2.compareTo(cu) > 0); TestUnion union1 = new TestUnion(TestUnion._Fields.STRUCT_LIST, new ArrayList()); TestUnion union2 = new TestUnion(TestUnion._Fields.STRUCT_LIST, new ArrayList()); assertEquals(0, union1.compareTo(union2)); TestUnion union3 = new TestUnion(TestUnion._Fields.I32_SET, new HashSet()); Set i32_set = new HashSet(); i32_set.add(1); TestUnion union4 = new TestUnion(TestUnion._Fields.I32_SET, i32_set); assertTrue(union3.compareTo(union4) < 0); Map i32_map = new HashMap(); i32_map.put(1, 1); TestUnion union5 = new TestUnion(TestUnion._Fields.I32_MAP, i32_map); TestUnion union6 = new TestUnion(TestUnion._Fields.I32_MAP, new HashMap()); assertTrue(union5.compareTo(union6) > 0); } @Test public void testEquality() throws Exception { TestUnion union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); TestUnion otherUnion = new TestUnion(TestUnion._Fields.STRING_FIELD, "blah!!!"); assertFalse(union.equals(otherUnion)); otherUnion = new TestUnion(TestUnion._Fields.I32_FIELD, 400); assertFalse(union.equals(otherUnion)); otherUnion = new TestUnion(TestUnion._Fields.OTHER_I32_FIELD, 25); assertFalse(union.equals(otherUnion)); } @Test public void testSerialization() throws Exception { TestUnion union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); union.setI32_set(Collections.singleton(42)); TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = new TBinaryProtocol(buf); union.write(proto); TestUnion u2 = new TestUnion(); u2.read(proto); assertEquals(u2, union); StructWithAUnion swau = new StructWithAUnion(u2); buf = new TMemoryBuffer(0); proto = new TBinaryProtocol(buf); swau.write(proto); StructWithAUnion swau2 = new StructWithAUnion(); assertFalse(swau2.equals(swau)); swau2.read(proto); assertEquals(swau2, swau); // this should NOT throw an exception. buf = new TMemoryBuffer(0); proto = new TBinaryProtocol(buf); swau.write(proto); new Empty().read(proto); } @Test public void testTupleProtocolSerialization() throws Exception { TestUnion union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); union.setI32_set(Collections.singleton(42)); TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = new TTupleProtocol(buf); union.write(proto); TestUnion u2 = new TestUnion(); u2.read(proto); assertEquals(u2, union); StructWithAUnion swau = new StructWithAUnion(u2); buf = new TMemoryBuffer(0); proto = new TBinaryProtocol(buf); swau.write(proto); StructWithAUnion swau2 = new StructWithAUnion(); assertFalse(swau2.equals(swau)); swau2.read(proto); assertEquals(swau2, swau); // this should NOT throw an exception. buf = new TMemoryBuffer(0); proto = new TTupleProtocol(buf); swau.write(proto); new Empty().read(proto); } @Test public void testSkip() throws Exception { TestUnion tu = TestUnion.string_field("string"); byte[] tuSerialized = new TSerializer().serialize(tu); TestUnionMinusStringField tums = new TestUnionMinusStringField(); new TDeserializer().deserialize(tums, tuSerialized); assertNull(tums.getSetField()); assertNull(tums.getFieldValue()); } @Test public void testDeepCopy() throws Exception { byte[] bytes = {1, 2, 3}; ByteBuffer value = ByteBuffer.wrap(bytes); ComparableUnion cu = ComparableUnion.binary_field(value); ComparableUnion copy = cu.deepCopy(); assertEquals(cu, copy); assertNotSame(cu.bufferForBinary_field().array(), copy.bufferForBinary_field().array()); } @Test public void testToString() throws Exception { byte[] bytes = {1, 2, 3}; ByteBuffer value = ByteBuffer.wrap(bytes); ComparableUnion cu = ComparableUnion.binary_field(value); String expectedString = ""; assertEquals(expectedString, cu.toString()); } @Test public void testJavaSerializable() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); TestUnion tu = TestUnion.string_field("string"); // Serialize tu the Java way... oos.writeObject(tu); byte[] serialized = baos.toByteArray(); // Attempt to deserialize it ByteArrayInputStream bais = new ByteArrayInputStream(serialized); ObjectInputStream ois = new ObjectInputStream(bais); TestUnion tu2 = (TestUnion) ois.readObject(); assertEquals(tu, tu2); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestReuse.java0000664000175000017500000000352315165535636025654 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; import java.util.HashSet; import org.apache.thrift.protocol.TBinaryProtocol; import org.junit.jupiter.api.Test; import thrift.test.Reuse; // Tests reusing objects for deserialization. // public class TestReuse extends TestStruct { @Test public void testReuseObject() throws Exception { TSerializer binarySerializer = new TSerializer(new TBinaryProtocol.Factory()); TDeserializer binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory()); Reuse ru1 = new Reuse(); HashSet hs1 = new HashSet<>(); byte[] serBytes; String st1 = "string1"; String st2 = "string2"; ru1.setVal1(11); ru1.setVal2(hs1); ru1.addToVal2(st1); serBytes = binarySerializer.serialize(ru1); // update hash set after serialization hs1.add(st2); binaryDeserializer.deserialize(ru1, serBytes); assertSame(hs1, ru1.getVal2()); assertEquals(2, hs1.size()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/Fixtures.java0000664000175000017500000006461115165535636025547 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import thrift.test.Bonk; import thrift.test.CompactProtoTestStruct; import thrift.test.HolyMoley; import thrift.test.Nesting; import thrift.test.OneOfEach; public class Fixtures { public static OneOfEach getOneOfEach() { return oneOfEach.deepCopy(); } public static Nesting getNesting() { return nesting.deepCopy(); } public static HolyMoley getHolyMoley() { return holyMoley.deepCopy(); } public static CompactProtoTestStruct getCompactProtoTestStruct() { return compactProtoTestStruct.deepCopy(); } public static byte[] getPersistentBytesOneOfEach() { return persistentBytesOneOfEach.clone(); } public static byte[] getPersistentBytesHolyMoley() { return persistentBytesHolyMoley.clone(); } public static byte[] getPersistentBytesNesting() { return persistentBytesNesting.clone(); } private static final OneOfEach oneOfEach; private static final Nesting nesting; private static final HolyMoley holyMoley; private static final CompactProtoTestStruct compactProtoTestStruct; // 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 // test backwards compatibility with respect to the standard scheme. private static final byte[] persistentBytesOneOfEach = new byte[] { (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0xD6, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00 }; private static final byte[] persistentBytesNesting = new byte[] { (byte) 0x0C, (byte) 0x00, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x7A, (byte) 0x69, (byte) 0x0B, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x13, (byte) 0x49, (byte) 0x20, (byte) 0x61, (byte) 0x6D, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x62, (byte) 0x6F, (byte) 0x6E, (byte) 0x6B, (byte) 0x2E, (byte) 0x2E, (byte) 0x2E, (byte) 0x20, (byte) 0x78, (byte) 0x6F, (byte) 0x72, (byte) 0x21, (byte) 0x00, (byte) 0x0C, (byte) 0x00, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0xD6, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00 }; private static final byte[] persistentBytesHolyMoley = new byte[] { (byte) 0x0F, (byte) 0x00, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0x23, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0xD6, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x0E, (byte) 0x00, (byte) 0x02, (byte) 0x0F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x6E, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x2C, (byte) 0x20, (byte) 0x74, (byte) 0x77, (byte) 0x6F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x74, (byte) 0x68, (byte) 0x72, (byte) 0x65, (byte) 0x65, (byte) 0x21, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x46, (byte) 0x4F, (byte) 0x55, (byte) 0x52, (byte) 0x21, (byte) 0x21, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0x61, (byte) 0x6E, (byte) 0x64, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0x61, (byte) 0x6E, (byte) 0x64, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x74, (byte) 0x77, (byte) 0x6F, (byte) 0x0D, (byte) 0x00, (byte) 0x03, (byte) 0x0B, (byte) 0x0F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x74, (byte) 0x77, (byte) 0x6F, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x57, (byte) 0x61, (byte) 0x69, (byte) 0x74, (byte) 0x2E, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x0B, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x57, (byte) 0x68, (byte) 0x61, (byte) 0x74, (byte) 0x3F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x74, (byte) 0x68, (byte) 0x72, (byte) 0x65, (byte) 0x65, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x7A, (byte) 0x65, (byte) 0x72, (byte) 0x6F, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; private static final byte[] kUnicodeBytes = { (byte) 0xd3, (byte) 0x80, (byte) 0xe2, (byte) 0x85, (byte) 0xae, (byte) 0xce, (byte) 0x9d, (byte) 0x20, (byte) 0xd0, (byte) 0x9d, (byte) 0xce, (byte) 0xbf, (byte) 0xe2, (byte) 0x85, (byte) 0xbf, (byte) 0xd0, (byte) 0xbe, (byte) 0xc9, (byte) 0xa1, (byte) 0xd0, (byte) 0xb3, (byte) 0xd0, (byte) 0xb0, (byte) 0xcf, (byte) 0x81, (byte) 0xe2, (byte) 0x84, (byte) 0x8e, (byte) 0x20, (byte) 0xce, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xce, (byte) 0xb1, (byte) 0xe2, (byte) 0x85, (byte) 0xbd, (byte) 0xce, (byte) 0xba, (byte) 0x83, (byte) 0xe2, (byte) 0x80, (byte) 0xbc }; static { try { oneOfEach = new OneOfEach(); oneOfEach.setIm_true(true); oneOfEach.setIm_false(false); oneOfEach.setA_bite((byte) 0xd6); oneOfEach.setInteger16((short) 27000); oneOfEach.setInteger32(1 << 24); oneOfEach.setInteger64((long) 6000 * 1000 * 1000); oneOfEach.setDouble_precision(Math.PI); oneOfEach.setSome_characters("JSON THIS! \"\1"); oneOfEach.setZomg_unicode(new String(kUnicodeBytes, StandardCharsets.UTF_8)); oneOfEach.setBase64(ByteBuffer.wrap("base64".getBytes())); // byte, i16, and i64 lists are populated by default constructor Bonk bonk = new Bonk(); bonk.setType(31337); bonk.setMessage("I am a bonk... xor!"); nesting = new Nesting(bonk, oneOfEach); holyMoley = new HolyMoley(); List big = new ArrayList<>(); big.add(new OneOfEach(oneOfEach)); big.add(nesting.my_ooe); holyMoley.setBig(big); holyMoley.getBig().get(0).setA_bite((byte) 0x22); holyMoley.getBig().get(0).setA_bite((byte) 0x23); holyMoley.setContain(new HashSet<>()); ArrayList stage1 = new ArrayList<>(2); stage1.add("and a one"); stage1.add("and a two"); holyMoley.getContain().add(stage1); stage1 = new ArrayList<>(3); stage1.add("then a one, two"); stage1.add("three!"); stage1.add("FOUR!!"); holyMoley.getContain().add(stage1); stage1 = new ArrayList<>(0); holyMoley.getContain().add(stage1); ArrayList stage2 = new ArrayList<>(); holyMoley.setBonks(new HashMap<>()); // one empty holyMoley.getBonks().put("zero", stage2); // one with two stage2 = new ArrayList<>(); Bonk b = new Bonk(); b.setType(1); b.setMessage("Wait."); stage2.add(b); b = new Bonk(); b.setType(2); b.setMessage("What?"); stage2.add(b); holyMoley.getBonks().put("two", stage2); // one with three stage2 = new ArrayList<>(); b = new Bonk(); b.setType(3); b.setMessage("quoth"); b = new Bonk(); b.setType(4); b.setMessage("the raven"); b = new Bonk(); b.setType(5); b.setMessage("nevermore"); holyMoley.getBonks().put("three", stage2); // superhuge compact proto test struct compactProtoTestStruct = new CompactProtoTestStruct(thrift.test.DebugProtoTestConstants.COMPACT_TEST); compactProtoTestStruct.setA_binary(ByteBuffer.wrap(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8})); } catch (Exception e) { throw new RuntimeException(e); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestOptionType.java0000664000175000017500000000434115165535636026702 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; // Tests and documents behavior for the "Option" type public class TestOptionType { @Test public void testSome() { String name = "Chuck Norris"; Option option = Option.fromNullable(name); assertTrue(option instanceof Option.Some); assertTrue(option.isDefined()); assertEquals("Some(Chuck Norris)", option.toString()); assertEquals(option.or("default value"), "Chuck Norris"); assertEquals(option.get(), "Chuck Norris"); } @Test public void testNone() throws Exception { String name = null; Option option = Option.fromNullable(name); assertTrue(option instanceof Option.None); assertFalse(option.isDefined()); assertEquals("None", option.toString()); assertEquals(option.or("default value"), "default value"); // Expect exception assertThrows(IllegalStateException.class, option::get); } @Test public void testMakeSome() throws Exception { Option some = Option.some("wee"); assertTrue(some.isDefined()); } @Test public void testMakeNone() throws Exception { Option none = Option.none(); assertFalse(none.isDefined()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/0000775000175000017500000000000015165535636024042 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/voidmethexceptions/0000775000175000017500000000000015165535636027763 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/voidmethexceptions/ServiceSyncImp.java0000664000175000017500000000435015165535636033533 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.voidmethexceptions; import org.apache.thrift.TApplicationException; import org.apache.thrift.TException; import thrift.test.voidmethexceptions.TAppService01; import thrift.test.voidmethexceptions.TExampleException; public class ServiceSyncImp extends ServiceBase implements TAppService01.Iface { @Override public String returnString(String msg, boolean throwException) throws TExampleException, TException { if (throwException) { throw new TExampleException(msg); } return msg; } @Override public void returnVoidThrows(String msg, boolean throwException) throws TExampleException, TException { if (throwException) { throw new TExampleException(msg); } } @Override public void returnVoidNoThrowsRuntimeException(String msg, boolean throwException) throws TException { if (throwException) { throw new RuntimeException(msg); } } @Override public void returnVoidNoThrowsTApplicationException(String msg, boolean throwException) throws TException { if (throwException) { throw new TApplicationException(TApplicationException.INTERNAL_ERROR, msg); } } @Override public void onewayVoidNoThrows(String msg, boolean throwException) throws TException { if (throwException) { throw new TApplicationException(TApplicationException.INTERNAL_ERROR, msg); } else { // simulate hang up waitForCancel(); } } } TestVoidMethExceptions.java0000664000175000017500000004640315165535636035177 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/voidmethexceptions/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.voidmethexceptions; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; import org.apache.thrift.TApplicationException; import org.apache.thrift.TConfiguration; import org.apache.thrift.TProcessor; import org.apache.thrift.async.AsyncMethodCallback; import org.apache.thrift.async.TAsyncClientManager; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.server.TNonblockingServer; import org.apache.thrift.server.TServer; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TNonblockingSocket; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.layered.TFramedTransport; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import thrift.test.voidmethexceptions.TAppService01; import thrift.test.voidmethexceptions.TExampleException; public class TestVoidMethExceptions { private static final Logger log = LoggerFactory.getLogger(TestVoidMethExceptions.class); private static Stream provideParameters() throws Exception { return Stream.builder() .add(new TestParameters(ServerImplementationType.SYNC_SERVER)) .add(new TestParameters(ServerImplementationType.ASYNC_SERVER)) .build(); } public static class TestParameters { private static final int TIMEOUT_MILLIS = 5_000; private final TServer server; private final Thread serverThread; private final TNonblockingServerSocket serverTransport; private int serverPort; private final ServerImplementationType serverImplementationType; private final CompletableFuture futureServerStarted = new CompletableFuture<>(); TestParameters(ServerImplementationType serverImplementationType) throws Exception { this.serverImplementationType = serverImplementationType; serverPort = -1; serverImplementationType.service.setCancelled(false); serverTransport = new TNonblockingServerSocket(0); TNonblockingServer.Args args = new TNonblockingServer.Args(serverTransport); args.processor(serverImplementationType.processor); server = new TNonblockingServer(args) { @Override protected void setServing(boolean serving) { super.setServing(serving); if (serving) { serverPort = serverTransport.getPort(); futureServerStarted.complete(null); } } }; serverThread = new Thread(server::serve, "thrift-server"); serverThread.setDaemon(true); } public AutoCloseable start() throws Exception { serverThread.start(); futureServerStarted.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); return () -> { serverImplementationType.service.setCancelled(true); server.stop(); serverThread.join(TIMEOUT_MILLIS); }; } private void checkSyncClient( String desc, String msg, boolean throwException, String expectedResult, Class expectedExceptionClass, String expectedExceptionMsg, SyncCall call) throws Exception { if (log.isInfoEnabled()) { log.info( "start test checkSyncClient::" + desc + ", throwException: " + throwException + ", serverImplementationType: " + serverImplementationType); } assertNotEquals(-1, serverPort); try (TTransport clientTransport = new TFramedTransport( new TSocket(new TConfiguration(), "localhost", serverPort, TIMEOUT_MILLIS))) { clientTransport.open(); TAppService01.Iface client = new TAppService01.Client(new TBinaryProtocol(clientTransport)); if (throwException && expectedExceptionClass != null) { Exception ex = assertThrows( expectedExceptionClass, () -> { call.apply(client, msg, throwException); }); assertEquals(expectedExceptionClass, ex.getClass()); if (expectedExceptionMsg != null) { assertEquals(expectedExceptionMsg, ex.getMessage()); } } else { // expected String result = call.apply(client, msg, throwException); assertEquals(expectedResult, result); } } } private void checkAsyncClient( String desc, String msg, boolean throwException, T expectedResult, Class expectedExceptionClass, String expectedExceptionMsg, AsyncCall> call) throws Throwable { if (log.isInfoEnabled()) { log.info( "start test checkAsyncClient::" + desc + ", throwException: " + throwException + ", serverImplementationType: " + serverImplementationType); } assertNotEquals(serverPort, -1); try (TNonblockingSocket clientTransportAsync = new TNonblockingSocket("localhost", serverPort, TIMEOUT_MILLIS)) { TAsyncClientManager asyncClientManager = new TAsyncClientManager(); try { TAppService01.AsyncClient asyncClient = new TAppService01.AsyncClient( new TBinaryProtocol.Factory(), asyncClientManager, clientTransportAsync); asyncClient.setTimeout(TIMEOUT_MILLIS); CompletableFuture futureResult = new CompletableFuture<>(); call.apply( asyncClient, msg, throwException, new AsyncMethodCallback() { @Override public void onError(Exception exception) { futureResult.completeExceptionally(exception); } @Override public void onComplete(T response) { futureResult.complete(response); } }); if (throwException && expectedExceptionClass != null) { Exception ex = assertThrows( expectedExceptionClass, () -> { try { futureResult.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); } catch (ExecutionException x) { throw x.getCause(); } }); assertEquals(expectedExceptionClass, ex.getClass()); if (expectedExceptionMsg != null) { assertEquals(expectedExceptionMsg, ex.getMessage()); } } else { T result; try { result = futureResult.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); } catch (ExecutionException x) { throw x.getCause(); } assertEquals(expectedResult, result); } } finally { asyncClientManager.stop(); } } } public TServer getServer() { return server; } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustReturnResultReturnString(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnString", "sent msg", false, "sent msg", null, null, TAppService01.Iface::returnString); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustReturnResultReturnVoidThrows(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnVoidThrows", "sent msg", false, null, null, null, (client, msg, throwException) -> { client.returnVoidThrows(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustReturnResultReturnVoidNoThrowsRuntimeException(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnVoidNoThrowsRuntimeException", "sent msg", false, null, null, null, (client, msg, throwException) -> { client.returnVoidNoThrowsRuntimeException(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustReturnResultReturnVoidNoThrowsTApplicationException( TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnVoidNoThrowsTApplicationException", "sent msg", false, null, null, null, (client, msg, throwException) -> { client.returnVoidNoThrowsTApplicationException(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustThrowExceptionReturnString(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnString", "sent msg", true, null, TExampleException.class, "sent msg", TAppService01.Iface::returnString); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustThrowExceptionReturnVoidThrows(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnVoidThrows", "sent msg", true, null, TExampleException.class, "sent msg", (client, msg, throwException) -> { client.returnVoidThrows(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustThrowExceptionReturnVoidNoThrowsRuntimeException(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnVoidNoThrowsRuntimeException", "sent msg", true, null, TApplicationException.class, p.serverImplementationType == ServerImplementationType.ASYNC_SERVER ? "sent msg" : null, // sync server return "Internal error processing // returnVoidNoThrowsRuntimeException" message (client, msg, throwException) -> { client.returnVoidNoThrowsRuntimeException(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientMustThrowExceptionReturnVoidNoThrowsTApplicationException( TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "returnVoidNoThrowsTApplicationException", "sent msg", true, null, TApplicationException.class, "sent msg", (client, msg, throwException) -> { client.returnVoidNoThrowsTApplicationException(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustReturnResultReturnString(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnString", "sent msg", false, "sent msg", null, null, TAppService01.AsyncClient::returnString); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustReturnResultReturnVoidThrows(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnVoidThrows", "sent msg", false, null, null, null, TAppService01.AsyncClient::returnVoidThrows); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustReturnResultReturnVoidNoThrowsRuntimeException(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnVoidNoThrowsRuntimeException", "sent msg", false, null, null, null, TAppService01.AsyncClient::returnVoidNoThrowsRuntimeException); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustReturnResultReturnVoidNoThrowsTApplicationException( TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnVoidNoThrowsTApplicationException", "sent msg", false, null, null, null, TAppService01.AsyncClient::returnVoidNoThrowsTApplicationException); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustThrowExceptionReturnString(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnString", "sent msg", true, null, TExampleException.class, "sent msg", TAppService01.AsyncClient::returnString); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustThrowExceptionReturnVoidThrows(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnVoidThrows", "sent msg", true, null, TExampleException.class, "sent msg", TAppService01.AsyncClient::returnVoidThrows); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustThrowExceptionReturnVoidNoThrowsRuntimeException(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnVoidNoThrowsRuntimeException", "sent msg", true, null, TApplicationException.class, p.serverImplementationType == ServerImplementationType.ASYNC_SERVER ? "sent msg" : null, // sync server return "Internal error processing // returnVoidNoThrowsRuntimeException" message TAppService01.AsyncClient::returnVoidNoThrowsRuntimeException); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientMustThrowExceptionReturnVoidNoThrowsTApplicationException( TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "returnVoidNoThrowsTApplicationException", "sent msg", true, null, TApplicationException.class, "sent msg", TAppService01.AsyncClient::returnVoidNoThrowsTApplicationException); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientNoWaitForResultNoExceptionOnewayVoidNoThrows(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "onewayVoidNoThrows", "sent msg", false, null, null, null, (client, msg, throwException) -> { client.onewayVoidNoThrows(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testSyncClientNoWaitForResultExceptionOnewayVoidNoThrows(TestParameters p) throws Exception { try (AutoCloseable ignored = p.start()) { p.checkSyncClient( "onewayVoidNoThrows", "sent msg", true, null, null, null, (client, msg, throwException) -> { client.onewayVoidNoThrows(msg, throwException); return null; }); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientNoWaitForResultNoExceptionOnewayVoidNoThrows(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "onewayVoidNoThrows", "sent msg", false, null, null, null, TAppService01.AsyncClient::onewayVoidNoThrows); } } @ParameterizedTest @MethodSource("provideParameters") public void testAsyncClientNoWaitForResultExceptionOnewayVoidNoThrows(TestParameters p) throws Throwable { try (AutoCloseable ignored = p.start()) { p.checkAsyncClient( "onewayVoidNoThrows", "sent msg", true, null, null, null, TAppService01.AsyncClient::onewayVoidNoThrows); } } private enum ServerImplementationType { SYNC_SERVER( () -> { ServiceSyncImp service = new ServiceSyncImp(); return Pair.of(new TAppService01.Processor<>(service), service); }), ASYNC_SERVER( () -> { ServiceAsyncImp service = new ServiceAsyncImp(); return Pair.of(new TAppService01.AsyncProcessor<>(service), service); }); final TProcessor processor; final ServiceBase service; ServerImplementationType(Supplier> supplier) { Pair pair = supplier.get(); this.processor = pair.getLeft(); this.service = pair.getRight(); } } @FunctionalInterface private interface SyncCall { R apply(T t, U u, V v) throws Exception; } @FunctionalInterface private interface AsyncCall { void apply(T t, U u, V v, X x) throws Exception; } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/voidmethexceptions/ServiceBase.java0000664000175000017500000000235015165535636033021 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.voidmethexceptions; public class ServiceBase { private volatile boolean cancelled = false; public boolean isCancelled() { return cancelled; } public void setCancelled(boolean cancelled) { this.cancelled = cancelled; } protected void waitForCancel() { while (!isCancelled()) { try { Thread.sleep(10L); } catch (InterruptedException x) { break; } } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/voidmethexceptions/ServiceAsyncImp.java0000664000175000017500000000535315165535636033700 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.voidmethexceptions; import org.apache.thrift.TApplicationException; import org.apache.thrift.TException; import org.apache.thrift.async.AsyncMethodCallback; import thrift.test.voidmethexceptions.TAppService01; import thrift.test.voidmethexceptions.TExampleException; public class ServiceAsyncImp extends ServiceBase implements TAppService01.AsyncIface { @Override public void returnString( String msg, boolean throwException, AsyncMethodCallback resultHandler) throws TException { if (throwException) { resultHandler.onError(new TExampleException(msg)); } else { resultHandler.onComplete(msg); } } @Override public void returnVoidThrows( String msg, boolean throwException, AsyncMethodCallback resultHandler) throws TException { if (throwException) { resultHandler.onError(new TExampleException(msg)); } else { resultHandler.onComplete(null); } } @Override public void returnVoidNoThrowsRuntimeException( String msg, boolean throwException, AsyncMethodCallback resultHandler) throws TException { if (throwException) { resultHandler.onError(new RuntimeException(msg)); } else { resultHandler.onComplete(null); } } @Override public void returnVoidNoThrowsTApplicationException( String msg, boolean throwException, AsyncMethodCallback resultHandler) throws TException { if (throwException) { resultHandler.onError(new TApplicationException(TApplicationException.INTERNAL_ERROR, msg)); } else { resultHandler.onComplete(null); } } @Override public void onewayVoidNoThrows( String msg, boolean throwException, AsyncMethodCallback resultHandler) throws TException { if (throwException) { resultHandler.onError(new TApplicationException(TApplicationException.INTERNAL_ERROR, msg)); } else { // simulate hang up } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/SerializationBenchmark.java0000664000175000017500000000663315165535636031345 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import org.apache.thrift.Fixtures; import org.apache.thrift.TBase; import org.apache.thrift.TConfiguration; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import thrift.test.OneOfEach; public class SerializationBenchmark { private static final int HOW_MANY = 10000000; public static void main(String[] args) throws Exception { TProtocolFactory factory = new TBinaryProtocol.Factory(); testSerialization(factory, Fixtures.getOneOfEach()); testDeserialization(factory, Fixtures.getOneOfEach(), OneOfEach.class); } public static void testSerialization(TProtocolFactory factory, TBase object) throws Exception { TTransport trans = new TTransport() { public void write(byte[] bin, int x, int y) throws TTransportException {} public TConfiguration getConfiguration() { return new TConfiguration(); } public void updateKnownMessageSize(long size) throws TTransportException {} public void checkReadBytesAvailable(long numBytes) throws TTransportException {} public int read(byte[] bin, int x, int y) throws TTransportException { return 0; } public void close() {} public void open() {} public boolean isOpen() { return true; } }; TProtocol proto = factory.getProtocol(trans); long startTime = System.currentTimeMillis(); for (int i = 0; i < HOW_MANY; i++) { object.write(proto); } long endTime = System.currentTimeMillis(); System.out.println("Serialization test time: " + (endTime - startTime) + " ms"); } public static void testDeserialization( TProtocolFactory factory, T object, Class klass) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); object.write(factory.getProtocol(buf)); byte[] serialized = new byte[100 * 1024]; buf.read(serialized, 0, 100 * 1024); long startTime = System.currentTimeMillis(); for (int i = 0; i < HOW_MANY; i++) { T o2 = klass.getConstructor().newInstance(); o2.read(factory.getProtocol(new TMemoryInputTransport(new TConfiguration(), serialized))); } long endTime = System.currentTimeMillis(); System.out.println("Deserialization test time: " + (endTime - startTime) + " ms"); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/JavaBeansTest.java0000664000175000017500000001147515165535636027407 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.nio.ByteBuffer; import java.util.LinkedList; import thrift.test.OneOfEachBeans; public class JavaBeansTest { public static void main(String[] args) throws Exception { // Test isSet methods OneOfEachBeans ooe = new OneOfEachBeans(); // Nothing should be set if (ooe.is_set_a_bite()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_base64()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_byte_list()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_double_precision()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_i16_list()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_i64_list()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_boolean_field()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_integer16()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_integer32()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_integer64()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_some_characters()) throw new RuntimeException("isSet method error: unset field returned as set!"); for (int i = 1; i < 12; i++) { if (ooe.isSet(ooe.fieldForId(i))) throw new RuntimeException("isSet method error: unset field " + i + " returned as set!"); } // Everything is set ooe.set_a_bite((byte) 1); ooe.set_base64(ByteBuffer.wrap("bytes".getBytes())); ooe.set_byte_list(new LinkedList<>()); ooe.set_double_precision(1); ooe.set_i16_list(new LinkedList<>()); ooe.set_i64_list(new LinkedList<>()); ooe.set_boolean_field(true); ooe.set_integer16((short) 1); ooe.set_integer32(1); ooe.set_integer64(1); ooe.set_some_characters("string"); if (!ooe.is_set_a_bite()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_base64()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_byte_list()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_double_precision()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_i16_list()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_i64_list()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_boolean_field()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_integer16()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_integer32()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_integer64()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_some_characters()) throw new RuntimeException("isSet method error: set field returned as unset!"); for (int i = 1; i < 12; i++) { if (!ooe.isSet(ooe.fieldForId(i))) throw new RuntimeException("isSet method error: set field " + i + " returned as unset!"); } // Should throw exception when field doesn't exist boolean exceptionThrown = false; try { ooe.isSet(ooe.fieldForId(100)); } catch (IllegalArgumentException e) { exceptionThrown = true; } if (!exceptionThrown) throw new RuntimeException( "isSet method error: non-existent field provided as agument but no exception thrown!"); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/ReadStruct.java0000664000175000017500000000464015165535636026771 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.io.BufferedInputStream; import java.io.FileInputStream; import org.apache.thrift.Fixtures; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; import thrift.test.CompactProtoTestStruct; public class ReadStruct { public static void main(String[] args) throws Exception { if (args.length != 2) { System.out.println( "usage: java -cp build/classes org.apache.thrift.test.ReadStruct filename proto_factory_class"); System.out.println( "Read in an instance of CompactProtocolTestStruct from 'file', making sure that it is equivalent to Fixtures.compactProtoTestStruct. Use a protocol from 'proto_factory_class'."); } TTransport trans = new TIOStreamTransport(new BufferedInputStream(new FileInputStream(args[0]))); TProtocolFactory factory = (TProtocolFactory) Class.forName(args[1]).getDeclaredConstructor().newInstance(); TProtocol proto = factory.getProtocol(trans); CompactProtoTestStruct cpts = new CompactProtoTestStruct(); for (CompactProtoTestStruct._Fields fid : CompactProtoTestStruct.metaDataMap.keySet()) { cpts.setFieldValue(fid, null); } cpts.read(proto); if (cpts.equals(Fixtures.getCompactProtoTestStruct())) { System.out.println("Object verified successfully!"); } else { System.out.println("Object failed verification!"); System.out.println("Expected: " + Fixtures.getCompactProtoTestStruct() + " but got " + cpts); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/0000775000175000017500000000000015167543515025035 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/ParseBinaryFuzzer.java0000664000175000017500000000206215165535636031330 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import org.apache.thrift.protocol.TBinaryProtocol; public class ParseBinaryFuzzer { public static void fuzzerTestOneInput(byte[] input) throws Exception { FuzzTestUtils.testParse(input, new TBinaryProtocol.Factory()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/RoundtripCompactFuzzer.java0000664000175000017500000000223115165535636032404 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocolFactory; public class RoundtripCompactFuzzer { public static void fuzzerTestOneInput(byte[] input) throws Exception { TProtocolFactory factory = new TCompactProtocol.Factory(); FuzzTestUtils.testRoundtrip(input, factory); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/FuzzTestUtils.java0000664000175000017500000001101515165535636030520 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import org.apache.thrift.TConfiguration; import org.apache.thrift.TException; import org.apache.thrift.fuzz.FuzzTest; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransport; public class FuzzTestUtils { // 10MB message size limit to prevent over-allocation during fuzzing private static final int FUZZ_MAX_MESSAGE_SIZE = 10 * 1024 * 1024; /** * Common fuzzing test implementation that attempts to parse input data using the provided * protocol factory. * * @param input The input bytes to fuzz * @param factory The protocol factory to use for parsing * @throws Exception if an unexpected error occurs */ public static void testParse(byte[] input, TProtocolFactory factory) throws Exception { try { TConfiguration config = new TConfiguration(); config.setMaxMessageSize(FUZZ_MAX_MESSAGE_SIZE); TTransport transport = new TMemoryInputTransport(config, input); TProtocol protocol = factory.getProtocol(transport); // Try to read a FuzzTest object from the input FuzzTest obj = new FuzzTest(); obj.read(protocol); } catch (TException e) { // Ignore Thrift exceptions - they're expected when fuzzing } catch (Exception e) { // TODO: For now we are ignoring unexpected exceptions, but we should fix this // and handle them appropriately. Need to understand the contract to see if it's a // spec violation or not for us to throw non-TException when parsing. } } /** * Common fuzzing test implementation that performs a roundtrip test using the provided protocol * factory. It deserializes the input, serializes it again, and verifies the objects are equal * after a second deserialization. * * @param input The input bytes to fuzz * @param factory The protocol factory to use for serialization/deserialization * @throws Exception if an unexpected error occurs */ public static void testRoundtrip(byte[] input, TProtocolFactory factory) throws Exception { try { TConfiguration config = new TConfiguration(); config.setMaxMessageSize(FUZZ_MAX_MESSAGE_SIZE); // First try to deserialize the raw input bytes TTransport inputTransport = new TMemoryInputTransport(config, input); TProtocol inProtocol = factory.getProtocol(inputTransport); // Try to read a FuzzTest object from the input FuzzTest inputObj = new FuzzTest(); inputObj.read(inProtocol); // Now do the roundtrip test with the successfully deserialized object TMemoryBuffer memoryBuffer = new TMemoryBuffer(config, input.length); TProtocol outProtocol = factory.getProtocol(memoryBuffer); inputObj.write(outProtocol); // Get the serialized bytes byte[] serialized = memoryBuffer.getArray(); // Deserialize again TTransport secondInputTransport = new TMemoryInputTransport(config, serialized); TProtocol secondInProtocol = factory.getProtocol(secondInputTransport); FuzzTest outputObj = new FuzzTest(); outputObj.read(secondInProtocol); // Assert equality if (!inputObj.equals(outputObj)) { throw new AssertionError("Roundtrip objects are not equal"); } } catch (TException e) { // Ignore Thrift exceptions - they're expected when fuzzing } catch (Exception e) { // TODO: For now we are ignoring unexpected exceptions, but we should fix this // and handle them appropriately. Need to understand the contract to see if it's a // spec violation or not for us to throw non-TException when parsing. } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/TestRecursionLimit.java0000664000175000017500000001433715167543515031520 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayOutputStream; import org.apache.thrift.TConfiguration; import org.apache.thrift.fuzz.RecursiveStruct; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolException; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransport; import org.junit.jupiter.api.Test; /** * Tests for TConfiguration.recursionLimit enforcement during deserialization. This brings Java in * line with C++ which already enforces recursion limits. */ public class TestRecursionLimit { private static final int DEFAULT_RECURSION_LIMIT = 64; /** * Creates a nested RecursiveStruct with the specified depth. * * @param depth The depth of nesting * @return A RecursiveStruct with the specified depth */ private RecursiveStruct createNestedStruct(int depth) { RecursiveStruct root = new RecursiveStruct(0); RecursiveStruct current = root; for (int i = 1; i < depth; i++) { RecursiveStruct next = new RecursiveStruct(i); current.setRecurse(next); current = next; } return root; } /** Tests that Binary protocol enforces the recursion limit. */ @Test public void testBinaryProtocolRecursionLimit() throws Exception { RecursiveStruct deepStruct = createNestedStruct(DEFAULT_RECURSION_LIMIT + 10); ByteArrayOutputStream baos = new ByteArrayOutputStream(); TConfiguration config = new TConfiguration(); TTransport transport = new TIOStreamTransport(config, baos); TProtocol protocol = new TBinaryProtocol(transport); deepStruct.write(protocol); byte[] serialized = baos.toByteArray(); TTransport inputTransport = new TMemoryInputTransport(config, serialized); TProtocol inputProtocol = new TBinaryProtocol(inputTransport); RecursiveStruct result = new RecursiveStruct(); TProtocolException exception = assertThrows( TProtocolException.class, () -> { result.read(inputProtocol); }); assertTrue( exception.getType() == TProtocolException.DEPTH_LIMIT, "Expected DEPTH_LIMIT exception type, got: " + exception.getType()); } /** Tests that Compact protocol enforces the recursion limit. */ @Test public void testCompactProtocolRecursionLimit() throws Exception { RecursiveStruct deepStruct = createNestedStruct(DEFAULT_RECURSION_LIMIT + 10); ByteArrayOutputStream baos = new ByteArrayOutputStream(); TConfiguration config = new TConfiguration(); TTransport transport = new TIOStreamTransport(config, baos); TProtocol protocol = new TCompactProtocol(transport); deepStruct.write(protocol); byte[] serialized = baos.toByteArray(); TTransport inputTransport = new TMemoryInputTransport(config, serialized); TProtocol inputProtocol = new TCompactProtocol(inputTransport); RecursiveStruct result = new RecursiveStruct(); TProtocolException exception = assertThrows( TProtocolException.class, () -> { result.read(inputProtocol); }); assertTrue( exception.getType() == TProtocolException.DEPTH_LIMIT, "Expected DEPTH_LIMIT exception type, got: " + exception.getType()); } /** Tests that JSON protocol enforces the recursion limit. */ @Test public void testJSONProtocolRecursionLimit() throws Exception { RecursiveStruct deepStruct = createNestedStruct(DEFAULT_RECURSION_LIMIT + 10); ByteArrayOutputStream baos = new ByteArrayOutputStream(); TConfiguration config = new TConfiguration(); TTransport transport = new TIOStreamTransport(config, baos); TProtocol protocol = new TJSONProtocol(transport); deepStruct.write(protocol); byte[] serialized = baos.toByteArray(); TTransport inputTransport = new TMemoryInputTransport(config, serialized); TProtocol inputProtocol = new TJSONProtocol(inputTransport); RecursiveStruct result = new RecursiveStruct(); TProtocolException exception = assertThrows( TProtocolException.class, () -> { result.read(inputProtocol); }); assertTrue( exception.getType() == TProtocolException.DEPTH_LIMIT, "Expected DEPTH_LIMIT exception type, got: " + exception.getType()); } /** Tests that structures within the recursion limit deserialize successfully. */ @Test public void testWithinRecursionLimit() throws Exception { RecursiveStruct deepStruct = createNestedStruct(DEFAULT_RECURSION_LIMIT); ByteArrayOutputStream baos = new ByteArrayOutputStream(); TConfiguration config = new TConfiguration(); TTransport transport = new TIOStreamTransport(config, baos); TProtocol protocol = new TBinaryProtocol(transport); deepStruct.write(protocol); byte[] serialized = baos.toByteArray(); TTransport inputTransport = new TMemoryInputTransport(config, serialized); TProtocol inputProtocol = new TBinaryProtocol(inputTransport); RecursiveStruct result = new RecursiveStruct(); assertDoesNotThrow(() -> result.read(inputProtocol)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/RoundtripBinaryFuzzer.java0000664000175000017500000000222615165535636032246 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocolFactory; public class RoundtripBinaryFuzzer { public static void fuzzerTestOneInput(byte[] input) throws Exception { TProtocolFactory factory = new TBinaryProtocol.Factory(); FuzzTestUtils.testRoundtrip(input, factory); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/ParseJSONFuzzer.java0000664000175000017500000000205415165535636030656 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import org.apache.thrift.protocol.TJSONProtocol; public class ParseJSONFuzzer { public static void fuzzerTestOneInput(byte[] input) throws Exception { FuzzTestUtils.testParse(input, new TJSONProtocol.Factory()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/ParseCompactFuzzer.java0000664000175000017500000000206515165535636031475 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import org.apache.thrift.protocol.TCompactProtocol; public class ParseCompactFuzzer { public static void fuzzerTestOneInput(byte[] input) throws Exception { FuzzTestUtils.testParse(input, new TCompactProtocol.Factory()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/README.md0000664000175000017500000000263215165535636026322 0ustar00buildbuild00000000000000# Java Fuzzing README The Java Thrift implementation uses Jazzer for fuzzing. Jazzer is a coverage-guided, in-process fuzzer for the JVM. Unlike the C++ implementation, the Java fuzzers are not directly runnable in a local environment. Instead, Jazzer generates Java programs that need to be executed through the appropriate build system. We currently have several fuzz targets that test different aspects of the Thrift implementation: * FuzzParseBinary -- fuzzes the deserialization of the Binary protocol * FuzzParseCompact -- fuzzes the deserialization of the Compact protocol * FuzzParseJson -- fuzzes the deserialization of the JSON protocol * FuzzRoundtripBinary -- fuzzes the roundtrip of the Binary protocol (i.e. serializes then deserializes and compares the result) * FuzzRoundtripCompact -- fuzzes the roundtrip of the Compact protocol * FuzzRoundtripJson -- fuzzes the roundtrip of the JSON protocol The fuzzers use Jazzer's mutation engine to generate test cases. Each fuzzer implements the standard Jazzer interface and uses common testing code from the fuzz test utilities. For more information about Jazzer and its options, see the [Jazzer documentation](https://github.com/CodeIntelligenceTesting/jazzer). You can also use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these Java fuzzers, since the wire formats are identical between implementations. thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/fuzz/RoundtripJSONFuzzer.java0000664000175000017500000000222015165535636031565 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test.fuzz; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocolFactory; public class RoundtripJSONFuzzer { public static void fuzzerTestOneInput(byte[] input) throws Exception { TProtocolFactory factory = new TJSONProtocol.Factory(); FuzzTestUtils.testRoundtrip(input, factory); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/WriteStruct.java0000664000175000017500000000357715165535636027220 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import org.apache.thrift.Fixtures; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; public class WriteStruct { public static void main(String[] args) throws Exception { if (args.length != 2) { System.out.println( "usage: java -cp build/classes org.apache.thrift.test.WriteStruct filename proto_factory_class"); System.out.println( "Write out an instance of Fixtures.compactProtocolTestStruct to 'file'. Use a protocol from 'proto_factory_class'."); } TTransport trans = new TIOStreamTransport(new BufferedOutputStream(new FileOutputStream(args[0]))); TProtocolFactory factory = (TProtocolFactory) Class.forName(args[1]).getDeclaredConstructor().newInstance(); TProtocol proto = factory.getProtocol(trans); Fixtures.getCompactProtoTestStruct().write(proto); trans.flush(); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/EqualityTest.java0000664000175000017500000004727615165535636027362 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* This program was generated by the following Python script: #!/usr/bin/python3 import sys import os.path # Quines the easy way. with open(sys.argv[0], 'r') as handle: source = handle.read() with open(os.path.join(os.path.dirname(sys.argv[0]), 'EqualityTest.java'), 'w') as out: print >> out, ("/""*" r""" * 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. """ "*""/") print >> out print >> out, "/""*" print >> out, "This program was generated by the following Python script:" print >> out out.write(source) print >> out, "*""/" print >> out, r''' package org.apache.thrift.test; // Generated code import thrift.test.*; /'''r'''** *'''r'''/ public class EqualityTest { public static void main(String[] args) throws Exception { JavaTestHelper lhs, rhs; ''' vals = { 'int': ("1", "2"), 'obj': ("\"foo\"", "\"bar\""), 'bin': ("new byte[]{1,2}", "new byte[]{3,4}"), } matrix = ( (False,False), (False,True ), (True ,False), (True ,True ), ) for type in ('int', 'obj', 'bin'): for option in ('req', 'opt'): nulls = matrix[0:1] if type == 'int' else matrix[-1::-1] issets = matrix for is_null in nulls: for is_set in issets: # isset is implied for non-primitives, so only consider the case # where isset and non-null match. if type != 'int' and list(is_set) != [ not null for null in is_null ]: continue for equal in (True, False): print >> out print >> out, " lhs = new JavaTestHelper();" print >> out, " rhs = new JavaTestHelper();" print >> out, " lhs." + option + "_" + type, "=", vals[type][0] + ";" print >> out, " rhs." + option + "_" + type, "=", vals[type][0 if equal else 1] + ";" isset_setter = "set" + option[0].upper() + option[1:] + "_" + type + "IsSet" if (type == 'int' and is_set[0]): print >> out, " lhs." + isset_setter + "(true);" if (type == 'int' and is_set[1]): print >> out, " rhs." + isset_setter + "(true);" if (is_null[0]): print >> out, " lhs." + option + "_" + type, "= null;" if (is_null[1]): print >> out, " rhs." + option + "_" + type, "= null;" this_present = not is_null[0] and (option == 'req' or is_set[0]) that_present = not is_null[1] and (option == 'req' or is_set[1]) print >> out, " // this_present = " + repr(this_present) print >> out, " // that_present = " + repr(that_present) is_equal = \ (not this_present and not that_present) or \ (this_present and that_present and equal) eq_str = 'true' if is_equal else 'false' print >> out, " if (lhs.equals(rhs) != "+eq_str+")" print >> out, " throw new RuntimeException(\"Failure\");" if is_equal: print >> out, " if (lhs.hashCode() != rhs.hashCode())" print >> out, " throw new RuntimeException(\"Failure\");" print >> out, r''' } } ''' */ package org.apache.thrift.test; // Generated code import java.nio.ByteBuffer; import thrift.test.JavaTestHelper; /** */ public class EqualityTest { public static void main(String[] args) throws Exception { JavaTestHelper lhs, rhs; lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; lhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; lhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; lhs.setReq_intIsSet(true); rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; lhs.setReq_intIsSet(true); rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; rhs.setOpt_intIsSet(true); // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; rhs.setOpt_intIsSet(true); // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; lhs.setOpt_intIsSet(true); // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; lhs.setOpt_intIsSet(true); // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; lhs.setOpt_intIsSet(true); rhs.setOpt_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; lhs.setOpt_intIsSet(true); rhs.setOpt_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; lhs.req_obj = null; rhs.req_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; lhs.req_obj = null; rhs.req_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; lhs.req_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; lhs.req_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; rhs.req_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; rhs.req_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; lhs.opt_obj = null; rhs.opt_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; lhs.opt_obj = null; rhs.opt_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; lhs.opt_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; lhs.opt_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; rhs.opt_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; rhs.opt_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); lhs.req_bin = null; rhs.req_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {3, 4}); lhs.req_bin = null; rhs.req_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); lhs.req_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {3, 4}); lhs.req_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {3, 4}); rhs.req_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.req_bin = ByteBuffer.wrap(new byte[] {3, 4}); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); lhs.opt_bin = null; rhs.opt_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {3, 4}); lhs.opt_bin = null; rhs.opt_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); lhs.opt_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {3, 4}); lhs.opt_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {3, 4}); rhs.opt_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[] {1, 2}); rhs.opt_bin = ByteBuffer.wrap(new byte[] {3, 4}); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/test/TestServlet.java0000664000175000017500000000342315165535636027173 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerTestBase.TestHandler; import org.apache.thrift.server.TExtensibleServlet; import thrift.test.ThriftTest; @SuppressWarnings("serial") public class TestServlet extends TExtensibleServlet { @Override protected TProtocolFactory getInProtocolFactory() { TProtocolFactory tProtocolFactory = new TCompactProtocol.Factory(); return tProtocolFactory; } @Override protected TProtocolFactory getOutProtocolFactory() { TProtocolFactory tProtocolFactory = new TCompactProtocol.Factory(); return tProtocolFactory; } @SuppressWarnings({"rawtypes", "unchecked"}) @Override protected TProcessor getProcessor() { TestHandler testHandler = new TestHandler(); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); return testProcessor; } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestMultiplexedProcessor.java0000664000175000017500000000601415165535636030763 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TMessageType; import org.apache.thrift.protocol.TProtocol; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class TestMultiplexedProcessor { private TMultiplexedProcessor mp; private TProtocol iprot; private TProtocol oprot; @BeforeEach public void setUp() throws Exception { mp = new TMultiplexedProcessor(); iprot = mock(TProtocol.class); oprot = mock(TProtocol.class); } @Test public void testWrongMessageType() throws TException { when(iprot.readMessageBegin()).thenReturn(new TMessage("service:func", TMessageType.REPLY, 42)); assertThrows(TException.class, () -> mp.process(iprot, oprot)); } @Test public void testNoSuchService() throws TException { when(iprot.readMessageBegin()).thenReturn(new TMessage("service:func", TMessageType.CALL, 42)); assertThrows(TException.class, () -> mp.process(iprot, oprot)); } static class StubProcessor implements TProcessor { @Override public void process(TProtocol in, TProtocol out) throws TException { TMessage msg = in.readMessageBegin(); if (!"func".equals(msg.name) || msg.type != TMessageType.CALL || msg.seqid != 42) { throw new TException("incorrect parameters"); } out.writeMessageBegin(new TMessage("func", TMessageType.REPLY, 42)); } } @Test public void testExistingService() throws TException { when(iprot.readMessageBegin()).thenReturn(new TMessage("service:func", TMessageType.CALL, 42)); mp.registerProcessor("service", new StubProcessor()); mp.process(iprot, oprot); verify(oprot).writeMessageBegin(any(TMessage.class)); } @Test public void testDefaultService() throws TException { when(iprot.readMessageBegin()).thenReturn(new TMessage("func", TMessageType.CALL, 42)); mp.registerDefault(new StubProcessor()); mp.process(iprot, oprot); verify(oprot).writeMessageBegin(any(TMessage.class)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestDefinitionOrder.java0000664000175000017500000000446615165535636027664 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.*; import java.io.*; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; // Tests that declaring fields in different order (esp. when they reference each other) generates // identical code public class TestDefinitionOrder { @Test public void testDefinitionOrder() throws Exception { List filenames = Arrays.asList("Parent.java", "Child.java", "MyEnum.java"); for (String fn : filenames) { String fnA = "definition-order-test/a/" + fn; String fnB = "definition-order-test/b/" + fn; try (InputStream isA = TestDefinitionOrder.class.getClassLoader().getResourceAsStream(fnA); InputStream isB = TestDefinitionOrder.class.getClassLoader().getResourceAsStream(fnB)) { assertNotNull(isA, "Resource not found: " + fnA); assertNotNull(isB, "Resource not found: " + fnB); int hashA = Arrays.hashCode(readAllBytes(isA)); assertEquals( hashA, Arrays.hashCode(readAllBytes(isB)), String.format("Generated Java files %s and %s differ", fnA, fnB)); } } } // TODO Use InputStream.readAllBytes post-Java8 private byte[] readAllBytes(InputStream is) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); byte[] buff = new byte[1024]; int bytesRead; while ((bytesRead = is.read(buff, 0, buff.length)) != -1) { os.write(buff, 0, bytesRead); } return os.toByteArray(); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestOptionalsWithJdk8.java0000664000175000017500000000507515165535636030122 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import thrift.test.optiontypejdk8.Person; // Tests and documents behavior for the JDK8 "Option" type public class TestOptionalsWithJdk8 { @Test public void testConstruction() { Person person = new Person(1L, "name"); assertFalse(person.getAge().isPresent()); assertFalse(person.isSetAge()); assertFalse(person.getPhone().isPresent()); assertFalse(person.isSetPhone()); assertEquals(1L, person.getId()); assertTrue(person.isSetId()); assertEquals("name", person.getName()); assertTrue(person.isSetName()); assertFalse(person.getAddresses().isPresent()); assertEquals(Integer.valueOf(0), person.getAddressesSize().orElse(0)); assertFalse(person.getPets().isPresent()); assertEquals(Integer.valueOf(0), person.getPetsSize().orElse(0)); } @Test public void testEmpty() { Person person = new Person(); person.setPhone("phone"); assertFalse(person.getAge().isPresent()); assertFalse(person.isSetAge()); assertTrue(person.getPhone().isPresent()); assertEquals("phone", person.getPhone().get()); assertTrue(person.isSetPhone()); assertEquals(0L, person.getId()); assertFalse(person.isSetId()); assertNull(person.getName()); assertFalse(person.isSetName()); assertFalse(person.getAddresses().isPresent()); assertEquals(Integer.valueOf(0), person.getAddressesSize().orElse(0)); assertFalse(person.getPets().isPresent()); assertEquals(Integer.valueOf(0), person.getPetsSize().orElse(0)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/0000775000175000017500000000000015167543515024366 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/TestThreadedSelectorServer.java0000664000175000017500000000253515165535636032511 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.TThreadedSelectorServer.Args; import org.apache.thrift.transport.TNonblockingServerSocket; public class TestThreadedSelectorServer extends TestNonblockingServer { protected TServer getServer( TProcessor processor, TNonblockingServerSocket socket, TProtocolFactory protoFactory) { return new TThreadedSelectorServer( new Args(socket).processor(processor).protocolFactory(protoFactory)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/TestHsHaServer.java0000664000175000017500000000246015165535636030110 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.THsHaServer.Args; import org.apache.thrift.transport.TNonblockingServerSocket; public class TestHsHaServer extends TestNonblockingServer { protected TServer getServer( TProcessor processor, TNonblockingServerSocket socket, TProtocolFactory protoFactory) { return new THsHaServer(new Args(socket).processor(processor).protocolFactory(protoFactory)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/ServerTestBase.java0000664000175000017500000006064515165535636030150 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.async.AsyncMethodCallback; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.TTransportFactory; import org.apache.thrift.transport.layered.TFramedTransport; import org.apache.thrift.transport.layered.TFramedTransport.Factory; import org.junit.jupiter.api.Test; import thrift.test.Insanity; import thrift.test.Numberz; import thrift.test.ThriftTest; import thrift.test.Xception; import thrift.test.Xception2; import thrift.test.Xtruct; import thrift.test.Xtruct2; public abstract class ServerTestBase { public static class TestHandler implements ThriftTest.Iface { public TestHandler() {} @Override public void testVoid() { System.out.print("testVoid()\n"); } @Override public String testString(String thing) { System.out.print("testString(\"" + thing + "\")\n"); return thing; } @Override public boolean testBool(boolean thing) { System.out.print("testBool(" + thing + ")\n"); return thing; } @Override public byte testByte(byte thing) { System.out.print("testByte(" + thing + ")\n"); return thing; } @Override public int testI32(int thing) { System.out.print("testI32(" + thing + ")\n"); return thing; } @Override public long testI64(long thing) { System.out.print("testI64(" + thing + ")\n"); return thing; } @Override public double testDouble(double thing) { System.out.print("testDouble(" + thing + ")\n"); return thing; } @Override public ByteBuffer testBinary(ByteBuffer thing) { StringBuilder sb = new StringBuilder(thing.remaining() * 3); thing.mark(); int limit = 0; // limit output to keep the log size sane while ((thing.remaining() > 0) && (++limit < 1024)) { sb.append(String.format("%02X ", thing.get())); } if (thing.remaining() > 0) { sb.append("..."); // indicate we have more date } System.out.print("testBinary(" + sb + ")\n"); thing.reset(); return thing; } @Override public UUID testUuid(UUID thing) throws TException { System.out.println("testUuid(" + thing + ")"); return thing; } @Override public Xtruct testStruct(Xtruct thing) { System.out.print( "testStruct({" + "\"" + thing.string_thing + "\", " + thing.byte_thing + ", " + thing.i32_thing + ", " + thing.i64_thing + "})\n"); return thing; } @Override public Xtruct2 testNest(Xtruct2 nest) { Xtruct thing = nest.struct_thing; System.out.print( "testNest({" + nest.byte_thing + ", {" + "\"" + thing.string_thing + "\", " + thing.byte_thing + ", " + thing.i32_thing + ", " + thing.i64_thing + "}, " + nest.i32_thing + "})\n"); return nest; } @Override public Map testMap(Map thing) { System.out.print("testMap({"); System.out.print(thing); System.out.print("})\n"); return thing; } @Override public Map testStringMap(Map thing) { System.out.print("testStringMap({"); System.out.print(thing); System.out.print("})\n"); return thing; } @Override public Set testSet(Set thing) { System.out.print("testSet({"); boolean first = true; for (int elem : thing) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})\n"); return thing; } @Override public List testList(List thing) { System.out.print("testList({"); boolean first = true; for (int elem : thing) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})\n"); return thing; } @Override public Numberz testEnum(Numberz thing) { System.out.print("testEnum(" + thing + ")\n"); return thing; } @Override public long testTypedef(long thing) { System.out.print("testTypedef(" + thing + ")\n"); return thing; } @Override public Map> testMapMap(int hello) { System.out.print("testMapMap(" + hello + ")\n"); Map> mapmap = new HashMap<>(); HashMap pos = new HashMap<>(); HashMap neg = new HashMap<>(); for (int i = 1; i < 5; i++) { pos.put(i, i); neg.put(-i, -i); } mapmap.put(4, pos); mapmap.put(-4, neg); return mapmap; } @Override public Map> testInsanity(Insanity argument) { System.out.print("testInsanity()\n"); HashMap first_map = new HashMap<>(); HashMap second_map = new HashMap<>(); first_map.put(Numberz.TWO, argument); first_map.put(Numberz.THREE, argument); Insanity looney = new Insanity(new HashMap<>(), Arrays.asList()); second_map.put(Numberz.SIX, looney); Map> insane = new HashMap<>(); insane.put((long) 1, first_map); insane.put((long) 2, second_map); return insane; } @Override public Xtruct testMulti( byte arg0, int arg1, long arg2, Map arg3, Numberz arg4, long arg5) { System.out.print("testMulti()\n"); Xtruct hello = new Xtruct(); hello.string_thing = "Hello2"; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = arg2; return hello; } @Override public void testException(String arg) throws TException { System.out.print("testException(" + arg + ")\n"); if ("Xception".equals(arg)) { Xception x = new Xception(); x.errorCode = 1001; x.message = arg; throw x; } else if ("TException".equals(arg)) { // Unspecified exception should yield a TApplicationException on client side throw new RuntimeException(arg); } else { Xtruct result = new Xtruct(); result.string_thing = arg; } return; } @Override public Xtruct testMultiException(String arg0, String arg1) throws Xception, Xception2 { System.out.print("testMultiException(" + arg0 + ", " + arg1 + ")\n"); if (arg0.equals("Xception")) { Xception x = new Xception(); x.errorCode = 1001; x.message = "This is an Xception"; throw x; } else if (arg0.equals("Xception2")) { Xception2 x = new Xception2(); x.errorCode = 2002; x.struct_thing = new Xtruct(); x.struct_thing.string_thing = "This is an Xception2"; throw x; } Xtruct result = new Xtruct(); result.string_thing = arg1; return result; } @Override public void testOneway(int sleepFor) { System.out.println("testOneway(" + sleepFor + ") => sleeping..."); try { Thread.sleep(sleepFor * SLEEP_DELAY); System.out.println("Done sleeping!"); } catch (InterruptedException ie) { throw new RuntimeException(ie); } } } // class TestHandler private static final List PROTOCOLS = Arrays.asList(new TBinaryProtocol.Factory(), new TCompactProtocol.Factory()); public static final String HOST = "localhost"; public static final int PORT = Integer.parseInt(System.getProperty("test.port", "9090")); protected static final long SLEEP_DELAY = 1000; protected static final int SOCKET_TIMEOUT = 1500; private static final Xtruct XSTRUCT = new Xtruct("Zero", (byte) 1, -3, -5); private static final Xtruct2 XSTRUCT2 = new Xtruct2((byte) 1, XSTRUCT, 5); public void startServer(TProcessor processor, TProtocolFactory protoFactory) throws Exception { startServer(processor, protoFactory, null); } public abstract void startServer( TProcessor processor, TProtocolFactory protoFactory, TTransportFactory factory) throws Exception; public abstract void stopServer() throws Exception; public abstract TTransport getClientTransport(TTransport underlyingTransport) throws Exception; private void testBool(ThriftTest.Client testClient) throws TException { boolean t = testClient.testBool(true); assertTrue(t); boolean f = testClient.testBool(false); assertFalse(f); } private void testByte(ThriftTest.Client testClient) throws TException { byte i8 = testClient.testByte((byte) 1); assertEquals(1, i8); } private void testUuid(ThriftTest.Client testClient) throws TException { UUID uuid = UUID.fromString("00112233-4455-6677-8899-aabbccddeeff"); UUID got = testClient.testUuid(uuid); assertEquals(uuid, got); } private void testDouble(ThriftTest.Client testClient) throws TException { double dub = testClient.testDouble(5.325098235); assertEquals(5.325098235, dub); } private void testEnum(ThriftTest.Client testClient) throws TException { assertEquals(Numberz.ONE, testClient.testEnum(Numberz.ONE)); assertEquals(Numberz.TWO, testClient.testEnum(Numberz.TWO)); assertEquals(Numberz.THREE, testClient.testEnum(Numberz.THREE)); assertEquals(Numberz.FIVE, testClient.testEnum(Numberz.FIVE)); assertEquals(Numberz.EIGHT, testClient.testEnum(Numberz.EIGHT)); } private void testI32(ThriftTest.Client testClient) throws TException { int i32 = testClient.testI32(-1); assertEquals(i32, -1); } private void testI64(ThriftTest.Client testClient) throws TException { long i64 = testClient.testI64(-34359738368L); assertEquals(i64, -34359738368L); } // todo: add assertions private void testInsanity(ThriftTest.Client testClient) throws TException { Insanity insane; insane = new Insanity(); insane.userMap = new HashMap<>(); insane.userMap.put(Numberz.FIVE, (long) 5000); Xtruct truck = new Xtruct(); truck.string_thing = "Truck"; truck.byte_thing = (byte) 8; truck.i32_thing = 8; truck.i64_thing = 8; insane.xtructs = new ArrayList<>(); insane.xtructs.add(truck); System.out.print("testInsanity()"); Map> whoa = testClient.testInsanity(insane); System.out.print(" = {"); for (long key : whoa.keySet()) { Map val = whoa.get(key); System.out.print(key + " => {"); for (Numberz k2 : val.keySet()) { Insanity v2 = val.get(k2); System.out.print(k2 + " => {"); Map userMap = v2.userMap; System.out.print("{"); if (userMap != null) { for (Numberz k3 : userMap.keySet()) { System.out.print(k3 + " => " + userMap.get(k3) + ", "); } } System.out.print("}, "); List xtructs = v2.xtructs; System.out.print("{"); if (xtructs != null) { for (Xtruct x : xtructs) { System.out.print( "{" + "\"" + x.string_thing + "\", " + x.byte_thing + ", " + x.i32_thing + ", " + x.i64_thing + "}, "); } } System.out.print("}"); System.out.print("}, "); } System.out.print("}, "); } System.out.print("}\n"); } public boolean useAsyncProcessor() { return false; } @Test public void testIt() throws Exception { for (TProtocolFactory protoFactory : getProtocols()) { TProcessor processor = useAsyncProcessor() ? new ThriftTest.AsyncProcessor<>(new AsyncTestHandler()) : new ThriftTest.Processor<>(new TestHandler()); startServer(processor, protoFactory); TSocket socket = new TSocket(HOST, PORT); socket.setTimeout(SOCKET_TIMEOUT); TTransport transport = getClientTransport(socket); TProtocol protocol = protoFactory.getProtocol(transport); ThriftTest.Client testClient = new ThriftTest.Client(protocol); open(transport); testVoid(testClient); testString(testClient); testBool(testClient); testByte(testClient); testI32(testClient); testI64(testClient); testDouble(testClient); testStruct(testClient); testNestedStruct(testClient); testMap(testClient); testUuid(testClient); testStringMap(testClient); testSet(testClient); testList(testClient); testEnum(testClient); testTypedef(testClient); testNestedMap(testClient); testInsanity(testClient); testException(testClient); testOneway(testClient); testI32(testClient); transport.close(); socket.close(); stopServer(); } } public void open(TTransport transport) throws Exception { transport.open(); } public List getProtocols() { return PROTOCOLS; } private void testList(ThriftTest.Client testClient) throws TException { List listout = new ArrayList<>(); for (int i = -2; i < 3; ++i) { listout.add(i); } List listin = testClient.testList(listout); assertEquals(listout, listin); } private void testMap(ThriftTest.Client testClient) throws TException { Map mapout = new HashMap<>(); for (int i = 0; i < 5; ++i) { mapout.put(i, i - 10); } Map mapin = testClient.testMap(mapout); assertEquals(mapout, mapin); } private void testStringMap(ThriftTest.Client testClient) throws TException { Map mapout = new HashMap<>(); mapout.put("a", "123"); mapout.put(" x y ", " with spaces "); mapout.put("same", "same"); mapout.put("0", "numeric key"); Map mapin = testClient.testStringMap(mapout); assertEquals(mapout, mapin); } private void testNestedMap(ThriftTest.Client testClient) throws TException { Map> mm = testClient.testMapMap(1); Map> mapmap = new HashMap<>(); HashMap pos = new HashMap<>(); HashMap neg = new HashMap<>(); for (int i = 1; i < 5; i++) { pos.put(i, i); neg.put(-i, -i); } mapmap.put(4, pos); mapmap.put(-4, neg); assertEquals(mapmap, mm); } private void testNestedStruct(ThriftTest.Client testClient) throws TException { Xtruct2 in2 = testClient.testNest(XSTRUCT2); assertEquals(XSTRUCT2, in2); } private void testOneway(ThriftTest.Client testClient) throws Exception { long begin = System.currentTimeMillis(); testClient.testOneway(1); long elapsed = System.currentTimeMillis() - begin; assertTrue(elapsed < 500); } private void testSet(ThriftTest.Client testClient) throws TException { Set setout = new HashSet<>(); for (int i = -2; i < 3; ++i) { setout.add(i); } Set setin = testClient.testSet(setout); assertEquals(setout, setin); } private void testString(ThriftTest.Client testClient) throws TException { String s = testClient.testString("Test"); assertEquals("Test", s); } private void testStruct(ThriftTest.Client testClient) throws TException { assertEquals(XSTRUCT, testClient.testStruct(XSTRUCT)); } private void testTypedef(ThriftTest.Client testClient) throws TException { assertEquals(309858235082523L, testClient.testTypedef(309858235082523L)); } private void testVoid(ThriftTest.Client testClient) throws TException { testClient.testVoid(); } private static class CallCountingTransportFactory extends TTransportFactory { public int count = 0; private final Factory factory; public CallCountingTransportFactory(Factory factory) { this.factory = factory; } @Override public TTransport getTransport(TTransport trans) throws TTransportException { count++; return factory.getTransport(trans); } } @Test public void testTransportFactory() throws Exception { for (TProtocolFactory protoFactory : getProtocols()) { TestHandler handler = new TestHandler(); ThriftTest.Processor processor = new ThriftTest.Processor<>(handler); final CallCountingTransportFactory factory = new CallCountingTransportFactory(new TFramedTransport.Factory()); startServer(processor, protoFactory, factory); assertEquals(0, factory.count); TSocket socket = new TSocket(HOST, PORT); socket.setTimeout(SOCKET_TIMEOUT); TTransport transport = getClientTransport(socket); open(transport); TProtocol protocol = protoFactory.getProtocol(transport); ThriftTest.Client testClient = new ThriftTest.Client(protocol); assertEquals(0, testClient.testByte((byte) 0)); assertEquals(2, factory.count); socket.close(); stopServer(); } } private void testException(ThriftTest.Client testClient) throws TException { try { testClient.testException("Xception"); assert false; } catch (Xception e) { assertEquals(e.message, "Xception"); assertEquals(e.errorCode, 1001); } try { testClient.testException("TException"); assert false; } catch (TException e) { } testClient.testException("no Exception"); } public static class AsyncTestHandler implements ThriftTest.AsyncIface { TestHandler handler = new TestHandler(); @Override public void testVoid(AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(null); } @Override public void testString(String thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testString(thing)); } @Override public void testBool(boolean thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testBool(thing)); } @Override public void testByte(byte thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testByte(thing)); } @Override public void testI32(int thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testI32(thing)); } @Override public void testI64(long thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testI64(thing)); } @Override public void testDouble(double thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testDouble(thing)); } @Override public void testBinary(ByteBuffer thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testBinary(thing)); } @Override public void testUuid(UUID thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testUuid(thing)); } @Override public void testStruct(Xtruct thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testStruct(thing)); } @Override public void testNest(Xtruct2 thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testNest(thing)); } @Override public void testMap( Map thing, AsyncMethodCallback> resultHandler) throws TException { resultHandler.onComplete(handler.testMap(thing)); } @Override public void testStringMap( Map thing, AsyncMethodCallback> resultHandler) throws TException { resultHandler.onComplete(handler.testStringMap(thing)); } @Override public void testSet(Set thing, AsyncMethodCallback> resultHandler) throws TException { resultHandler.onComplete(handler.testSet(thing)); } @Override public void testList(List thing, AsyncMethodCallback> resultHandler) throws TException { resultHandler.onComplete(handler.testList(thing)); } @Override public void testEnum(Numberz thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testEnum(thing)); } @Override public void testTypedef(long thing, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testTypedef(thing)); } @Override public void testMapMap( int hello, AsyncMethodCallback>> resultHandler) throws TException { resultHandler.onComplete(handler.testMapMap(hello)); } @Override public void testInsanity( Insanity argument, AsyncMethodCallback>> resultHandler) throws TException { resultHandler.onComplete(handler.testInsanity(argument)); } @Override public void testMulti( byte arg0, int arg1, long arg2, Map arg3, Numberz arg4, long arg5, AsyncMethodCallback resultHandler) throws TException { resultHandler.onComplete(handler.testMulti(arg0, arg1, arg2, arg3, arg4, arg5)); } @Override public void testException(String arg, AsyncMethodCallback resultHandler) throws TException { System.out.print("testException(" + arg + ")\n"); if ("Xception".equals(arg)) { Xception x = new Xception(); x.errorCode = 1001; x.message = arg; // throw and onError yield the same result. // throw x; resultHandler.onError(x); return; } else if ("TException".equals(arg)) { // throw and onError yield the same result. // resultHandler.onError(new TException(arg)); // return; // Unspecified exception should yield a TApplicationException on client side throw new RuntimeException(arg); } resultHandler.onComplete(null); } @Override public void testMultiException( String arg0, String arg1, AsyncMethodCallback resultHandler) throws TException { // To change body of implemented methods use File | Settings | File Templates. } @Override public void testOneway(int secondsToSleep, AsyncMethodCallback resultHandler) throws TException { handler.testOneway(secondsToSleep); resultHandler.onComplete(null); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/TestSaslNonblockingServer.java0000664000175000017500000001055015165535636032352 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import static org.apache.thrift.transport.sasl.TSaslNegotiationException.ErrorType.AUTHENTICATION_FAILURE; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TSaslClientTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.TTransportFactory; import org.apache.thrift.transport.TestTSaslTransports; import org.apache.thrift.transport.TestTSaslTransports.TestSaslCallbackHandler; import org.apache.thrift.transport.sasl.TSaslNegotiationException; import org.junit.jupiter.api.Test; import thrift.test.ThriftTest; public class TestSaslNonblockingServer extends TestTSaslTransports.TestTSaslTransportsWithServer { private TSaslNonblockingServer server; @Override public void startServer( TProcessor processor, TProtocolFactory protoFactory, TTransportFactory factory) throws Exception { TNonblockingServerTransport serverSocket = new TNonblockingServerSocket( new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs().port(PORT)); TSaslNonblockingServer.Args args = new TSaslNonblockingServer.Args(serverSocket) .processor(processor) .transportFactory(factory) .protocolFactory(protoFactory) .addSaslMechanism( TestTSaslTransports.WRAPPED_MECHANISM, TestTSaslTransports.SERVICE, TestTSaslTransports.HOST, TestTSaslTransports.WRAPPED_PROPS, new TestSaslCallbackHandler(TestTSaslTransports.PASSWORD)); server = new TSaslNonblockingServer(args); server.serve(); } @Override public void stopServer() throws Exception { server.shutdown(); } @Override @Test public void testIt() throws Exception { super.testIt(); } @Test public void testBadPassword() throws Exception { TProtocolFactory protocolFactory = new TBinaryProtocol.Factory(); TProcessor processor = new ThriftTest.Processor<>(new TestHandler()); startServer(processor, protocolFactory); TSocket socket = new TSocket(HOST, PORT); socket.setTimeout(SOCKET_TIMEOUT); try (TSaslClientTransport client = new TSaslClientTransport( TestTSaslTransports.WRAPPED_MECHANISM, TestTSaslTransports.PRINCIPAL, TestTSaslTransports.SERVICE, TestTSaslTransports.HOST, TestTSaslTransports.WRAPPED_PROPS, new TestSaslCallbackHandler("bad_password"), socket)) { TTransportException error = assertThrows( TTransportException.class, client::open, "Client should fail with sasl negotiation."); TSaslNegotiationException serverSideError = new TSaslNegotiationException( AUTHENTICATION_FAILURE, "Authentication failed with " + TestTSaslTransports.WRAPPED_MECHANISM); assertTrue( error.getMessage().contains(serverSideError.getSummary()), "Server should return error message \"" + serverSideError.getSummary() + "\""); } finally { stopServer(); } } @Test @Override public void testTransportFactory() { // This test is irrelevant here, so skipped. } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/TestThreadPoolServer.java0000664000175000017500000000661715167543515031333 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicReference; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TServerTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransportException; import org.junit.jupiter.api.Test; import thrift.test.ThriftTest; public class TestThreadPoolServer { /** Test server is shut down properly even with some open clients. */ @Test public void testStopServerWithOpenClient() throws Exception { AtomicReference ref = new AtomicReference<>(); TServerSocket serverSocket = new TServerSocket( new TServerSocket.ServerSocketTransportArgs() .port(0) .clientTimeout(3000) .maxMessageSize(51200)) { @Override public TSocket accept() throws TTransportException { TSocket socket = super.accept(); ref.set(socket); return socket; } }; TThreadPoolServer server = buildServer(serverSocket); Thread serverThread = new Thread(server::serve); serverThread.start(); try (TSocket client = new TSocket("localhost", serverSocket.getServerSocket().getLocalPort())) { client.open(); Thread.sleep(1000); // There is a thread listening to the client assertEquals(1, ((ThreadPoolExecutor) server.getExecutorService()).getActiveCount()); assertEquals(51200, ref.get().getConfiguration().getMaxMessageSize()); // Trigger the server to stop, but it does not wait server.stop(); assertTrue(server.waitForShutdown()); // After server is stopped, the executor thread pool should be shut down assertTrue( server.getExecutorService().isTerminated(), "Server thread pool should be terminated"); // TODO: The socket is actually closed (timeout) but the client code // ignores the timeout Exception and maintains the socket open state assertTrue(client.isOpen(), "Client should be closed after server shutdown"); } } private TThreadPoolServer buildServer(TServerTransport serverSocket) { TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverSocket) .protocolFactory(new TBinaryProtocol.Factory()) .processor(new ThriftTest.Processor<>(new ServerTestBase.TestHandler())); return new TThreadPoolServer(args); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/TestAsyncServer.java0000664000175000017500000000171715165535636030346 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; public class TestAsyncServer extends TestNonblockingServer { @Override public boolean useAsyncProcessor() { return true; } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/server/TestNonblockingServer.java0000664000175000017500000001051315165535636031526 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import static org.junit.jupiter.api.Assertions.fail; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.TNonblockingServer.Args; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.TTransportFactory; import org.apache.thrift.transport.layered.TFramedTransport; import org.junit.jupiter.api.Test; import thrift.test.ThriftTest; public class TestNonblockingServer extends ServerTestBase { private Thread serverThread; private TServer server; private static final int NUM_QUERIES = 1000; protected TServer getServer( TProcessor processor, TNonblockingServerSocket socket, TProtocolFactory protoFactory, TTransportFactory factory) { final Args args = new Args(socket).processor(processor).protocolFactory(protoFactory); if (factory != null) { args.transportFactory(factory); } return new TNonblockingServer(args); } @Override public void startServer( final TProcessor processor, final TProtocolFactory protoFactory, final TTransportFactory factory) throws Exception { serverThread = new Thread() { public void run() { try { // Transport TNonblockingServerSocket tServerSocket = new TNonblockingServerSocket( new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs() .port(PORT)); server = getServer(processor, tServerSocket, protoFactory, factory); // Run it System.out.println("Starting the server on port " + PORT + "..."); server.serve(); } catch (Exception e) { e.printStackTrace(); fail(); } } }; serverThread.start(); Thread.sleep(1000); } @Override public void stopServer() throws Exception { server.stop(); try { serverThread.join(); } catch (InterruptedException e) { } } @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { return new TFramedTransport(underlyingTransport); } @Test public void testCleanupAllSelectionKeys() throws Exception { for (TProtocolFactory protoFactory : getProtocols()) { TestHandler handler = new TestHandler(); ThriftTest.Processor processor = new ThriftTest.Processor(handler); startServer(processor, protoFactory); TSocket socket = new TSocket(HOST, PORT); socket.setTimeout(SOCKET_TIMEOUT); TTransport transport = getClientTransport(socket); TProtocol protocol = protoFactory.getProtocol(transport); ThriftTest.Client testClient = new ThriftTest.Client(protocol); open(transport); for (int i = 0; i < NUM_QUERIES; ++i) { testClient.testI32(1); } server.stop(); for (int i = 0; i < NUM_QUERIES; ++i) { try { testClient.testI32(1); } catch (TTransportException e) { System.err.println(e); e.printStackTrace(); if (e.getCause() instanceof java.net.SocketTimeoutException) { fail("timed out when it should have thrown another kind of error!"); } } } transport.close(); stopServer(); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/async/0000775000175000017500000000000015167543515024175 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/async/TestTAsyncClientManager.java0000664000175000017500000003276315167543515031546 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.server.THsHaServer; import org.apache.thrift.server.THsHaServer.Args; import org.apache.thrift.server.TServer; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TNonblockingSocket; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import thrift.test.CompactProtoTestStruct; import thrift.test.ExceptionWithAMap; import thrift.test.Srv; import thrift.test.Srv.Iface; public class TestTAsyncClientManager { protected TServer server_; protected Thread serverThread_; protected TAsyncClientManager clientManager_; @BeforeEach public void setUp() throws Exception { server_ = new THsHaServer( new Args( new TNonblockingServerSocket( new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs() .port(ServerTestBase.PORT))) .processor(new Srv.Processor(new SrvHandler()))); serverThread_ = new Thread( new Runnable() { public void run() { server_.serve(); } }); serverThread_.start(); clientManager_ = new TAsyncClientManager(); Thread.sleep(500); } @AfterEach public void tearDown() throws Exception { server_.stop(); clientManager_.stop(); serverThread_.join(); } @Test public void testBasicCall() throws Exception { Srv.AsyncClient client = getClient(); basicCall(client); } @Test public void testBasicCallWithTimeout() throws Exception { Srv.AsyncClient client = getClient(); client.setTimeout(5000); basicCall(client); } private abstract static class ErrorCallTest { final void runTest() throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicReference error = new AtomicReference(); C client = executeErroringCall( new AsyncMethodCallback() { @Override public void onComplete(R response) { latch.countDown(); } @Override public void onError(Exception exception) { error.set(exception); latch.countDown(); } }); latch.await(2, TimeUnit.SECONDS); assertTrue(client.hasError()); Exception exception = error.get(); assertNotNull(exception); assertSame(exception, client.getError()); validateError(client, exception); } /** * Executes a call that is expected to raise an exception. * * @param callback The testing callback that should be installed. * @return The client the call was made against. * @throws Exception if there was a problem setting up the client or making the call. */ abstract C executeErroringCall(AsyncMethodCallback callback) throws Exception; /** * Further validates the properties of the error raised in the remote call and the state of the * client after that call. * * @param client The client returned from {@link #executeErroringCall(AsyncMethodCallback)}. * @param error The exception raised by the remote call. */ abstract void validateError(C client, Exception error); } @Test public void testUnexpectedRemoteExceptionCall() throws Exception { new ErrorCallTest() { @Override Srv.AsyncClient executeErroringCall(AsyncMethodCallback callback) throws Exception { Srv.AsyncClient client = getClient(); client.declaredExceptionMethod(false, callback); return client; } @Override void validateError(Srv.AsyncClient client, Exception error) { assertFalse(client.hasTimeout()); assertTrue(error instanceof TException); } }.runTest(); } @Test public void testDeclaredRemoteExceptionCall() throws Exception { new ErrorCallTest() { @Override Srv.AsyncClient executeErroringCall(AsyncMethodCallback callback) throws Exception { Srv.AsyncClient client = getClient(); client.declaredExceptionMethod(true, callback); return client; } @Override void validateError(Srv.AsyncClient client, Exception error) { assertFalse(client.hasTimeout()); assertEquals(ExceptionWithAMap.class, error.getClass()); ExceptionWithAMap exceptionWithAMap = (ExceptionWithAMap) error; assertEquals("blah", exceptionWithAMap.getBlah()); assertEquals(new HashMap(), exceptionWithAMap.getMap_field()); } }.runTest(); } @Test public void testTimeoutCall() throws Exception { new ErrorCallTest() { @Override Srv.AsyncClient executeErroringCall(AsyncMethodCallback callback) throws Exception { Srv.AsyncClient client = getClient(); client.setTimeout(100); client.primitiveMethod(callback); return client; } @Override void validateError(Srv.AsyncClient client, Exception error) { assertTrue(client.hasTimeout()); assertTrue(error instanceof TimeoutException); } }.runTest(); } @Test public void testVoidCall() throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); Srv.AsyncClient client = getClient(); client.voidMethod( new FailureLessCallback() { @Override public void onComplete(Void response) { returned.set(true); latch.countDown(); } }); latch.await(1, TimeUnit.SECONDS); assertTrue(returned.get()); } @Test public void testOnewayCall() throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); Srv.AsyncClient client = getClient(); client.onewayMethod( new FailureLessCallback() { @Override public void onComplete(Void response) { returned.set(true); latch.countDown(); } }); latch.await(1, TimeUnit.SECONDS); assertTrue(returned.get()); } @Test public void testParallelCalls() throws Exception { // make multiple calls with deserialization in the selector thread (repro Eric's issue) int numThreads = 50; int numCallsPerThread = 100; List runnables = new ArrayList(); List threads = new ArrayList(); for (int i = 0; i < numThreads; i++) { JankyRunnable runnable = new JankyRunnable(numCallsPerThread); Thread thread = new Thread(runnable); thread.start(); threads.add(thread); runnables.add(runnable); } for (Thread thread : threads) { thread.join(); } int numSuccesses = 0; for (JankyRunnable runnable : runnables) { numSuccesses += runnable.getNumSuccesses(); } assertEquals(numThreads * numCallsPerThread, numSuccesses); } private Srv.AsyncClient getClient() throws IOException, TTransportException { return new Srv.AsyncClient(new TBinaryProtocol.Factory(), clientManager_, getClientTransport()); } protected TNonblockingTransport getClientTransport() throws TTransportException, IOException { return new TNonblockingSocket(ServerTestBase.HOST, ServerTestBase.PORT); } private void basicCall(Srv.AsyncClient client) throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); client.Janky( 1, new FailureLessCallback() { @Override public void onComplete(Integer response) { assertEquals(3, response.intValue()); returned.set(true); latch.countDown(); } @Override public void onError(Exception exception) { try { StringWriter sink = new StringWriter(); exception.printStackTrace(new PrintWriter(sink, true)); Assertions.fail("unexpected onError with exception " + sink.toString()); } finally { latch.countDown(); } } }); latch.await(100, TimeUnit.SECONDS); assertTrue(returned.get()); } public static class SrvHandler implements Iface { // Use this method for a standard call testing @Override public int Janky(int arg) throws TException { assertEquals(1, arg); return 3; } // Using this method for timeout testing - sleeps for 1 second before returning @Override public int primitiveMethod() throws TException { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return 0; } @Override public void methodWithDefaultArgs(int something) throws TException {} @Override public CompactProtoTestStruct structMethod() throws TException { return null; } @Override public void voidMethod() throws TException {} @Override public void onewayMethod() throws TException {} @Override public boolean declaredExceptionMethod(boolean shouldThrowDeclared) throws TException { if (shouldThrowDeclared) { throw new ExceptionWithAMap("blah", new HashMap()); } else { throw new TException("Unexpected!"); } } } private abstract static class FailureLessCallback implements AsyncMethodCallback { @Override public void onError(Exception exception) { fail(exception); } } private static void fail(Exception exception) { StringWriter sink = new StringWriter(); exception.printStackTrace(new PrintWriter(sink, true)); Assertions.fail("unexpected error " + sink); } private class JankyRunnable implements Runnable { private final int numCalls_; private int numSuccesses_ = 0; private final Srv.AsyncClient client_; public JankyRunnable(int numCalls) throws Exception { numCalls_ = numCalls; client_ = getClient(); client_.setTimeout(20000); } public int getNumSuccesses() { return numSuccesses_; } public void run() { for (int i = 0; i < numCalls_ && !client_.hasError(); i++) { final int iteration = i; try { // connect an async client final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); client_.Janky( 1, new AsyncMethodCallback() { @Override public void onComplete(Integer result) { assertEquals(3, result.intValue()); returned.set(true); latch.countDown(); } @Override public void onError(Exception exception) { try { StringWriter sink = new StringWriter(); exception.printStackTrace(new PrintWriter(sink, true)); Assertions.fail( "unexpected onError on iteration " + iteration + ": " + sink.toString()); } finally { latch.countDown(); } } }); boolean calledBack = latch.await(30, TimeUnit.SECONDS); assertTrue(calledBack, "wasn't called back in time on iteration " + iteration); assertTrue(returned.get(), "onComplete not called on iteration " + iteration); this.numSuccesses_++; } catch (Exception e) { fail(e); } } } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/async/TestTAsyncClient.java0000664000175000017500000000131415165535636030242 0ustar00buildbuild00000000000000package org.apache.thrift.async; import static org.junit.jupiter.api.Assertions.assertThrows; import org.apache.thrift.TException; import org.junit.jupiter.api.Test; import thrift.test.Srv; import thrift.test.Srv.AsyncClient; public class TestTAsyncClient { @Test public void testRaisesExceptionWhenUsedConcurrently() throws Exception { TAsyncClientManager mockClientManager = new TAsyncClientManager() { @Override public void call(TAsyncMethodCall method) throws TException { // do nothing } }; Srv.AsyncClient c = new AsyncClient(null, mockClientManager, null); c.Janky(0, null); assertThrows(Exception.class, c::checkReady); } } TestTAsyncSSLClientManagerCustomClient.java0000664000175000017500000000360715167543515034376 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/async/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import java.io.IOException; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TSSLTransportFactory; import org.apache.thrift.transport.TTransportException; public class TestTAsyncSSLClientManagerCustomClient extends TestTAsyncSSLClientManager { private static final String trustStoreLocation = System.getProperty("javax.net.ssl.trustStore"); private static final String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); @Override public TNonblockingTransport getClientTransport() throws TTransportException, IOException { TSSLTransportFactory.TSSLTransportParameters params = new TSSLTransportFactory.TSSLTransportParameters(); params.setTrustStore(trustStoreLocation, trustStorePassword); TNonblockingTransport clientTransport = TSSLTransportFactory.getNonblockingClientSocket( ServerTestBase.HOST, ServerTestBase.PORT, 0, params); clientTransportList.add(clientTransport); return clientTransport; } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/async/TestTAsyncSSLClientManager.java0000664000175000017500000000511215167543515032114 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.server.TThreadPoolServer; import org.apache.thrift.server.TThreadPoolServer.Args; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TSSLTransportFactory; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.layered.TFramedTransport; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import thrift.test.Srv; public class TestTAsyncSSLClientManager extends TestTAsyncClientManager { protected final List clientTransportList = Collections.synchronizedList(new ArrayList<>()); @BeforeEach public void setUp() throws Exception { server_ = new TThreadPoolServer( new Args(TSSLTransportFactory.getServerSocket(ServerTestBase.PORT)) .transportFactory(new TFramedTransport.Factory()) .processor(new Srv.Processor<>(new SrvHandler()))); serverThread_ = new Thread(() -> server_.serve()); serverThread_.start(); clientManager_ = new TAsyncClientManager(); Thread.sleep(500); } @AfterEach public void tearDown() throws Exception { for (TNonblockingTransport clientTransport : clientTransportList) { clientTransport.close(); } super.tearDown(); } @Override public TNonblockingTransport getClientTransport() throws TTransportException, IOException { TNonblockingTransport clientTransport = TSSLTransportFactory.getNonblockingClientSocket(ServerTestBase.HOST, ServerTestBase.PORT); clientTransportList.add(clientTransport); return clientTransport; } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/scheme/0000775000175000017500000000000015165535636024327 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/scheme/TestStandardScheme.java0000664000175000017500000000321115165535636030714 0ustar00buildbuild00000000000000package org.apache.thrift.scheme; import static org.junit.jupiter.api.Assertions.assertEquals; import org.apache.thrift.Fixtures; import org.apache.thrift.TBase; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.junit.jupiter.api.Test; import thrift.test.HolyMoley; import thrift.test.Nesting; import thrift.test.OneOfEach; public class TestStandardScheme { TSerializer serializer = new TSerializer(); TDeserializer deserializer = new TDeserializer(); public TestStandardScheme() throws TTransportException {} /** * This tests whether the Standard Scheme properly reads structs serialized using an older version * of thrift. */ @Test public void testPersistentStructs() throws TException { readAndCompare( new OneOfEach(), Fixtures.getOneOfEach(), Fixtures.getPersistentBytesOneOfEach()); readAndCompare( new HolyMoley(), Fixtures.getHolyMoley(), Fixtures.getPersistentBytesHolyMoley()); readAndCompare(new Nesting(), Fixtures.getNesting(), Fixtures.getPersistentBytesNesting()); } private void readAndCompare(TBase struct, TBase fixture, byte[] inputBytes) throws TException { TTransport trans = new TMemoryBuffer(0); trans.write(inputBytes, 0, inputBytes.length); TProtocol iprot = new TBinaryProtocol(trans); struct.read(iprot); assertEquals(fixture, struct); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestAnnotationMetadata.java0000664000175000017500000000544015165535636030344 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.apache.thrift.meta_data.FieldMetaData; import org.junit.jupiter.api.Test; import thrift.test.OneOfEachBeans; import thrift.test.annotations.OneOfEachBeansWithAnnotations; public class TestAnnotationMetadata { @Test public void testWithoutParamShouldGenerateEmpty() { Map structMetaDataMap = FieldMetaData.getStructMetaDataMap(OneOfEachBeans.class); { Map metadata = structMetaDataMap.get(OneOfEachBeans._Fields.I16_LIST).getFieldAnnotations(); assertEquals(Collections.emptyMap(), metadata); } { Map metadata = structMetaDataMap.get(OneOfEachBeans._Fields.A_BITE).getFieldAnnotations(); assertEquals(Collections.emptyMap(), metadata); } } @Test public void testGeneratedAnnotations() { Map structMetaDataMap = FieldMetaData.getStructMetaDataMap(OneOfEachBeansWithAnnotations.class); { Map metadata = structMetaDataMap .get(OneOfEachBeansWithAnnotations._Fields.I16_LIST) .getFieldAnnotations(); assertEquals(Collections.emptyMap(), metadata); } { Map metadata = structMetaDataMap.get(OneOfEachBeansWithAnnotations._Fields.A_BITE).getFieldAnnotations(); Map expected = new HashMap<>(); expected.put("compression", "false"); assertEquals(expected, metadata); } { Map metadata = structMetaDataMap .get(OneOfEachBeansWithAnnotations._Fields.TYPEDEF_META) .getFieldAnnotations(); Map expected = new HashMap<>(); expected.put("a", "b"); expected.put("c", "d"); assertEquals(expected, metadata); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestStruct.java0000664000175000017500000004210115165535636026050 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import org.apache.thrift.meta_data.FieldMetaData; import org.apache.thrift.meta_data.ListMetaData; import org.apache.thrift.meta_data.MapMetaData; import org.apache.thrift.meta_data.SetMetaData; import org.apache.thrift.meta_data.StructMetaData; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TType; import org.junit.jupiter.api.Test; import thrift.test.Bonk; import thrift.test.CrazyNesting; import thrift.test.HolyMoley; import thrift.test.Insanity; import thrift.test.JavaTestHelper; import thrift.test.Nesting; import thrift.test.Numberz; import thrift.test.OneOfEach; import thrift.test.StructA; import thrift.test.StructB; import thrift.test.Xtruct; public class TestStruct { @Test public void testIdentity() throws Exception { TSerializer binarySerializer = new TSerializer(new TBinaryProtocol.Factory()); TDeserializer binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory()); OneOfEach ooe = Fixtures.getOneOfEach(); Nesting n = new Nesting(); n.my_ooe = ooe; n.my_ooe.integer16 = 16; n.my_ooe.integer32 = 32; n.my_ooe.integer64 = 64; n.my_ooe.double_precision = (Math.sqrt(5) + 1) / 2; n.my_ooe.some_characters = ":R (me going \"rrrr\")"; n.my_ooe.zomg_unicode = "\u04c0\u216e\u039d\u0020\u041d\u03bf\u217f" + "\u043e\u0261\u0433\u0430\u03c1\u210e\u0020" + "\u0391\u0074\u0074\u03b1\u217d\u03ba\u01c3" + "\u203c"; n.my_bonk = Fixtures.getNesting().my_bonk; HolyMoley hm = Fixtures.getHolyMoley(); OneOfEach ooe2 = new OneOfEach(); binaryDeserializer.deserialize(ooe2, binarySerializer.serialize(ooe)); assertEquals(ooe, ooe2); assertEquals(ooe.hashCode(), ooe2.hashCode()); Nesting n2 = new Nesting(); binaryDeserializer.deserialize(n2, binarySerializer.serialize(n)); assertEquals(n, n2); assertEquals(n.hashCode(), n2.hashCode()); HolyMoley hm2 = new HolyMoley(); binaryDeserializer.deserialize(hm2, binarySerializer.serialize(hm)); assertEquals(hm, hm2); assertEquals(hm.hashCode(), hm2.hashCode()); } @Test public void testDeepCopy() throws Exception { TSerializer binarySerializer = new TSerializer(new TBinaryProtocol.Factory()); TDeserializer binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory()); HolyMoley hm = Fixtures.getHolyMoley(); byte[] binaryCopy = binarySerializer.serialize(hm); HolyMoley hmCopy = new HolyMoley(); binaryDeserializer.deserialize(hmCopy, binaryCopy); HolyMoley hmCopy2 = new HolyMoley(hm); assertEquals(hm, hmCopy); assertEquals(hmCopy, hmCopy2); // change binary value in original object hm.big.get(0).base64.array()[0]++; // make sure the change didn't propagate to the copied object assertFalse(hm.equals(hmCopy2)); hm.big.get(0).base64.array()[0]--; // undo change hmCopy2.bonks.get("two").get(1).message = "What else?"; assertFalse(hm.equals(hmCopy2)); } @Test public void testCompareTo() throws Exception { Bonk bonk1 = new Bonk(); Bonk bonk2 = new Bonk(); // Compare empty thrift objects. assertEquals(0, bonk1.compareTo(bonk2)); bonk1.setMessage("m"); // Compare one thrift object with a filled in field and another without it. assertTrue(bonk1.compareTo(bonk2) > 0); assertTrue(bonk2.compareTo(bonk1) < 0); // Compare both have filled-in fields. bonk2.setMessage("z"); assertTrue(bonk1.compareTo(bonk2) < 0); assertTrue(bonk2.compareTo(bonk1) > 0); // Compare bonk1 has a field filled in that bonk2 doesn't. bonk1.setType(123); assertTrue(bonk1.compareTo(bonk2) > 0); assertTrue(bonk2.compareTo(bonk1) < 0); // Compare bonk1 and bonk2 equal. bonk2.setType(123); bonk2.setMessage("m"); assertEquals(0, bonk1.compareTo(bonk2)); } @Test public void testCompareToWithDataStructures() { Insanity insanity1 = new Insanity(); Insanity insanity2 = new Insanity(); // Both empty. expectEquals(insanity1, insanity2); insanity1.setUserMap(new HashMap()); // insanity1.map = {}, insanity2.map = null expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1}, insanity2.map = null insanity1.getUserMap().put(Numberz.TWO, 1L); expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1}, insanity2.map = {} insanity2.setUserMap(new HashMap()); expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1}, insanity2.map = {2:2} insanity2.getUserMap().put(Numberz.TWO, 2L); expectLessThan(insanity1, insanity2); // insanity1.map = {2:1, 3:5}, insanity2.map = {2:2} insanity1.getUserMap().put(Numberz.THREE, 5L); expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1, 3:5}, insanity2.map = {2:1, 4:5} insanity2.getUserMap().put(Numberz.TWO, 1L); insanity2.getUserMap().put(Numberz.FIVE, 5L); expectLessThan(insanity1, insanity2); } private void expectLessThan(Insanity insanity1, Insanity insanity2) { int compareTo = insanity1.compareTo(insanity2); assertTrue( compareTo < 0, insanity1 + " should be less than " + insanity2 + ", but is: " + compareTo); } private void expectGreaterThan(Insanity insanity1, Insanity insanity2) { int compareTo = insanity1.compareTo(insanity2); assertTrue( compareTo > 0, insanity1 + " should be greater than " + insanity2 + ", but is: " + compareTo); } private void expectEquals(Insanity insanity1, Insanity insanity2) { int compareTo = insanity1.compareTo(insanity2); assertEquals( 0, compareTo, insanity1 + " should be equal to " + insanity2 + ", but is: " + compareTo); } @Test public void testMetaData() throws Exception { Map mdMap = CrazyNesting.metaDataMap; // Check for struct fields existence assertEquals(5, mdMap.size()); assertTrue(mdMap.containsKey(CrazyNesting._Fields.SET_FIELD)); assertTrue(mdMap.containsKey(CrazyNesting._Fields.LIST_FIELD)); assertTrue(mdMap.containsKey(CrazyNesting._Fields.STRING_FIELD)); assertTrue(mdMap.containsKey(CrazyNesting._Fields.BINARY_FIELD)); assertTrue(mdMap.containsKey(CrazyNesting._Fields.UUID_FIELD)); // Check for struct fields contents assertEquals("string_field", mdMap.get(CrazyNesting._Fields.STRING_FIELD).fieldName); assertEquals("list_field", mdMap.get(CrazyNesting._Fields.LIST_FIELD).fieldName); assertEquals("set_field", mdMap.get(CrazyNesting._Fields.SET_FIELD).fieldName); assertEquals("binary_field", mdMap.get(CrazyNesting._Fields.BINARY_FIELD).fieldName); assertEquals("uuid_field", mdMap.get(CrazyNesting._Fields.UUID_FIELD).fieldName); assertEquals( TFieldRequirementType.DEFAULT, mdMap.get(CrazyNesting._Fields.STRING_FIELD).requirementType); assertEquals( TFieldRequirementType.REQUIRED, mdMap.get(CrazyNesting._Fields.LIST_FIELD).requirementType); assertEquals( TFieldRequirementType.OPTIONAL, mdMap.get(CrazyNesting._Fields.SET_FIELD).requirementType); assertEquals(TType.STRING, mdMap.get(CrazyNesting._Fields.STRING_FIELD).valueMetaData.type); assertFalse(mdMap.get(CrazyNesting._Fields.STRING_FIELD).valueMetaData.isBinary()); assertEquals(TType.LIST, mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData.type); assertEquals(TType.SET, mdMap.get(CrazyNesting._Fields.SET_FIELD).valueMetaData.type); assertEquals(TType.STRING, mdMap.get(CrazyNesting._Fields.BINARY_FIELD).valueMetaData.type); assertEquals(TType.UUID, mdMap.get(CrazyNesting._Fields.UUID_FIELD).valueMetaData.type); assertTrue(mdMap.get(CrazyNesting._Fields.BINARY_FIELD).valueMetaData.isBinary()); // Check nested structures assertTrue(mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData.isContainer()); assertFalse(mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData.isStruct()); assertEquals( TType.STRUCT, ((MapMetaData) ((ListMetaData) ((SetMetaData) ((MapMetaData) ((MapMetaData) ((ListMetaData) mdMap.get(CrazyNesting._Fields.LIST_FIELD) .valueMetaData) .elemMetaData) .valueMetaData) .valueMetaData) .elemMetaData) .elemMetaData) .keyMetaData .type); assertEquals( Insanity.class, ((StructMetaData) ((MapMetaData) ((ListMetaData) ((SetMetaData) ((MapMetaData) ((MapMetaData) ((ListMetaData) mdMap.get( CrazyNesting._Fields .LIST_FIELD) .valueMetaData) .elemMetaData) .valueMetaData) .valueMetaData) .elemMetaData) .elemMetaData) .keyMetaData) .structClass); // Check that FieldMetaData contains a map with metadata for all generated struct classes assertNotNull(FieldMetaData.getStructMetaDataMap(CrazyNesting.class)); assertNotNull(FieldMetaData.getStructMetaDataMap(Insanity.class)); assertNotNull(FieldMetaData.getStructMetaDataMap(Xtruct.class)); assertEquals(CrazyNesting.metaDataMap, FieldMetaData.getStructMetaDataMap(CrazyNesting.class)); assertEquals(Insanity.metaDataMap, FieldMetaData.getStructMetaDataMap(Insanity.class)); for (Map.Entry mdEntry : mdMap.entrySet()) { assertEquals(mdEntry.getKey(), CrazyNesting._Fields.findByName(mdEntry.getValue().fieldName)); } MapMetaData vmd = (MapMetaData) Insanity.metaDataMap.get(Insanity._Fields.USER_MAP).valueMetaData; assertTrue(vmd.valueMetaData.isTypedef()); assertFalse(vmd.keyMetaData.isTypedef()); } @Test public void testToString() throws Exception { JavaTestHelper object = new JavaTestHelper(); object.req_int = 0; object.req_obj = ""; object.req_bin = ByteBuffer.wrap( new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23, 24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47, 48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71, 72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95, 96, -97, 98, -99, 100, -101, 102, -103, 104, -105, 106, -107, 108, -109, 110, -111, 112, -113, 114, -115, 116, -117, 118, -119, 120, -121, 122, -123, 124, -125, 126, -127, }); assertEquals( "JavaTestHelper(req_int:0, req_obj:, req_bin:" + "00 FF 02 FD 04 FB 06 F9 08 F7 0A F5 0C F3 0E F1 10 EF 12 ED 14 " + "EB 16 E9 18 E7 1A E5 1C E3 1E E1 20 DF 22 DD 24 DB 26 D9 28 D7 " + "2A D5 2C D3 2E D1 30 CF 32 CD 34 CB 36 C9 38 C7 3A C5 3C C3 3E " + "C1 40 BF 42 BD 44 BB 46 B9 48 B7 4A B5 4C B3 4E B1 50 AF 52 AD " + "54 AB 56 A9 58 A7 5A A5 5C A3 5E A1 60 9F 62 9D 64 9B 66 99 68 " + "97 6A 95 6C 93 6E 91 70 8F 72 8D 74 8B 76 89 78 87 7A 85 7C 83 " + "7E 81)", object.toString()); object.req_bin = ByteBuffer.wrap( new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23, 24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47, 48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71, 72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95, 96, -97, 98, -99, 100, -101, 102, -103, 104, -105, 106, -107, 108, -109, 110, -111, 112, -113, 114, -115, 116, -117, 118, -119, 120, -121, 122, -123, 124, -125, 126, -127, 0, }); assertEquals( "JavaTestHelper(req_int:0, req_obj:, req_bin:" + "00 FF 02 FD 04 FB 06 F9 08 F7 0A F5 0C F3 0E F1 10 EF 12 ED 14 " + "EB 16 E9 18 E7 1A E5 1C E3 1E E1 20 DF 22 DD 24 DB 26 D9 28 D7 " + "2A D5 2C D3 2E D1 30 CF 32 CD 34 CB 36 C9 38 C7 3A C5 3C C3 3E " + "C1 40 BF 42 BD 44 BB 46 B9 48 B7 4A B5 4C B3 4E B1 50 AF 52 AD " + "54 AB 56 A9 58 A7 5A A5 5C A3 5E A1 60 9F 62 9D 64 9B 66 99 68 " + "97 6A 95 6C 93 6E 91 70 8F 72 8D 74 8B 76 89 78 87 7A 85 7C 83 " + "7E 81...)", object.toString()); object.req_bin = ByteBuffer.wrap(new byte[] {}); object.setOpt_binIsSet(true); assertEquals("JavaTestHelper(req_int:0, req_obj:, req_bin:)", object.toString()); } @Test public void testBytesBufferFeatures() throws Exception { final String testString = "testBytesBufferFeatures"; final JavaTestHelper o = new JavaTestHelper(); o.setReq_bin((ByteBuffer) null); assertNull(o.getReq_bin()); o.setReq_bin(ByteBuffer.wrap(testString.getBytes())); assertArrayEquals(testString.getBytes(), o.getReq_bin()); o.setReq_bin((byte[]) null); assertNull(o.getReq_bin()); o.setReq_bin(testString.getBytes()); assertArrayEquals(testString.getBytes(), o.getReq_bin()); o.setFieldValue(JavaTestHelper._Fields.REQ_BIN, null); assertNull(o.getReq_bin()); o.setFieldValue(JavaTestHelper._Fields.REQ_BIN, testString.getBytes()); assertArrayEquals(testString.getBytes(), o.getReq_bin()); o.setFieldValue(JavaTestHelper._Fields.REQ_BIN, null); assertNull(o.getReq_bin()); o.setFieldValue(JavaTestHelper._Fields.REQ_BIN, ByteBuffer.wrap(testString.getBytes())); assertArrayEquals(testString.getBytes(), o.getReq_bin()); } @Test public void testJavaSerializable() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); OneOfEach ooe = Fixtures.getOneOfEach(); // Serialize ooe the Java way... oos.writeObject(ooe); byte[] serialized = baos.toByteArray(); // Attempt to deserialize it ByteArrayInputStream bais = new ByteArrayInputStream(serialized); ObjectInputStream ois = new ObjectInputStream(bais); OneOfEach ooe2 = (OneOfEach) ois.readObject(); assertEquals(ooe, ooe2); } @Test public void testSubStructValidation() throws Exception { StructA valid = new StructA("valid"); StructA invalid = new StructA(); StructB b = new StructB(); assertThrows(TException.class, b::validate); b = new StructB().setAb(valid); b.validate(); b = new StructB().setAb(invalid); assertThrows(TException.class, b::validate); b = new StructB().setAb(valid).setAa(invalid); assertThrows(TException.class, b::validate); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestFullCamel.java0000664000175000017500000000400215165535636026426 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.thrift.protocol.TBinaryProtocol; import org.junit.jupiter.api.Test; import thrift.test.fullcamel.OneOfEachZZ; import thrift.test.fullcamel.UnderscoreSrv; // Sanity check for the code generated by 'fullcamel'. // public class TestFullCamel { @Test public void testCamelCaseSyntax() throws Exception { TSerializer binarySerializer = new TSerializer(new TBinaryProtocol.Factory()); TDeserializer binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory()); OneOfEachZZ obj = new OneOfEachZZ(); obj.setABite((byte) 0xae); obj.setImFalse(true); byte[] serBytes = binarySerializer.serialize(obj); binaryDeserializer.deserialize(obj, serBytes); assertEquals((byte) 0xae, obj.getABite()); assertTrue(obj.isImFalse()); } @Test public void testCamelCaseRpcMethods() throws Exception { final UnderscoreSrv.Iface srv = new UnderscoreSrv.Iface() { @Override public long someRpcCall(String message) { return 1l; } }; assertTrue(1l == srv.someRpcCall("test")); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/0000775000175000017500000000000015165535636025117 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTZlibTransport.java0000664000175000017500000001212315165535636031562 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.zip.DataFormatException; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; import org.junit.jupiter.api.Test; public class TestTZlibTransport { protected TTransport getTransport(TTransport underlying) throws TTransportException { return new TZlibTransport(underlying); } public static byte[] byteSequence(int start, int end) { byte[] result = new byte[end - start + 1]; for (int i = 0; i <= (end - start); i++) { result[i] = (byte) (start + i); } return result; } @Test public void testClose() throws TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); WriteCountingTransport countingTrans = new WriteCountingTransport(new TIOStreamTransport(new BufferedOutputStream(baos))); TTransport trans = getTransport(countingTrans); trans.write(byteSequence(0, 245)); countingTrans.close(); trans.close(); } @Test public void testCloseOpen() throws TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); TTransport trans = getTransport(new TIOStreamTransport(baos)); byte[] uncompressed = byteSequence(0, 245); trans.write(uncompressed); trans.close(); final byte[] compressed = baos.toByteArray(); final byte[] buf = new byte[255]; TTransport transRead = getTransport(new TIOStreamTransport(new ByteArrayInputStream(compressed))); int readBytes = transRead.read(buf, 0, buf.length); assertEquals(uncompressed.length, readBytes); transRead.close(); } @Test public void testRead() throws IOException, TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(baos); DataOutputStream dos = new DataOutputStream(deflaterOutputStream); dos.write(byteSequence(0, 49)); dos.write(byteSequence(0, 219)); deflaterOutputStream.finish(); TMemoryBuffer membuf = new TMemoryBuffer(0); membuf.write(baos.toByteArray()); ReadCountingTransport countTrans = new ReadCountingTransport(membuf); TTransport trans = getTransport(countTrans); byte[] readBuf = new byte[10]; trans.read(readBuf, 0, 10); assertArrayEquals(readBuf, byteSequence(0, 9)); assertEquals(1, countTrans.readCount); trans.read(readBuf, 0, 10); assertArrayEquals(readBuf, byteSequence(10, 19)); assertEquals(1, countTrans.readCount); assertEquals(30, trans.read(new byte[30], 0, 30)); assertEquals(1, countTrans.readCount); readBuf = new byte[220]; assertEquals(220, trans.read(readBuf, 0, 220)); assertArrayEquals(readBuf, byteSequence(0, 219)); assertEquals(1, countTrans.readCount); } @Test public void testWrite() throws TTransportException, IOException, DataFormatException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); WriteCountingTransport countingTrans = new WriteCountingTransport(new TIOStreamTransport(new BufferedOutputStream(baos))); TTransport trans = getTransport(countingTrans); trans.write(byteSequence(0, 100)); assertEquals(1, countingTrans.writeCount); trans.write(byteSequence(101, 200)); trans.write(byteSequence(201, 255)); assertEquals(1, countingTrans.writeCount); trans.flush(); assertEquals(2, countingTrans.writeCount); trans.write(byteSequence(0, 245)); trans.flush(); assertEquals(3, countingTrans.writeCount); DataInputStream din = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(baos.toByteArray()))); byte[] buf = new byte[256]; int n = din.read(buf, 0, 256); assertEquals(n, 256); assertArrayEquals(byteSequence(0, 255), buf); buf = new byte[246]; n = din.read(buf, 0, 246); assertEquals(n, 246); for (int i = 0; i < buf.length; i++) { assertEquals(byteSequence(0, 245)[i], buf[i], "for " + i); } assertArrayEquals(byteSequence(0, 245), buf); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTFramedTransport.java0000664000175000017500000001764215165535636032073 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import org.apache.thrift.transport.layered.TFastFramedTransport; import org.apache.thrift.transport.layered.TFramedTransport; import org.junit.jupiter.api.Test; public class TestTFramedTransport { protected TTransport getTransport(TTransport underlying) throws TTransportException { return new TFramedTransport(underlying); } protected TTransport getTransport(TTransport underlying, int maxLength) throws TTransportException { return new TFramedTransport(underlying, maxLength); } public static byte[] byteSequence(int start, int end) { byte[] result = new byte[end - start + 1]; for (int i = 0; i <= (end - start); i++) { result[i] = (byte) (start + i); } return result; } @Test public void testRead() throws IOException, TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeInt(50); dos.write(byteSequence(0, 49)); dos.writeInt(220); dos.write(byteSequence(0, 219)); TMemoryBuffer membuf = new TMemoryBuffer(0); membuf.write(baos.toByteArray()); ReadCountingTransport countTrans = new ReadCountingTransport(membuf); TTransport trans = getTransport(countTrans); byte[] readBuf = new byte[10]; trans.read(readBuf, 0, 10); assertArrayEquals(readBuf, byteSequence(0, 9)); assertEquals(2, countTrans.readCount); trans.read(readBuf, 0, 10); assertArrayEquals(readBuf, byteSequence(10, 19)); assertEquals(2, countTrans.readCount); assertEquals(30, trans.read(new byte[30], 0, 30)); assertEquals(2, countTrans.readCount); // Known message size exceeded readBuf = new byte[220]; assertEquals(220, trans.read(readBuf, 0, 220)); assertArrayEquals(readBuf, byteSequence(0, 219)); assertEquals(4, countTrans.readCount); } @Test public void testInvalidFrameSize() throws IOException, TTransportException { int maxLength = 128; ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeInt(130); dos.write(byteSequence(0, 129)); TMemoryBuffer membuf = new TMemoryBuffer(0); membuf.write(baos.toByteArray()); ReadCountingTransport countTrans = new ReadCountingTransport(membuf); TTransport trans = getTransport(countTrans, maxLength); byte[] readBuf = new byte[10]; TTransportException e = assertThrows(TTransportException.class, () -> trans.read(readBuf, 0, 4)); // We expect this exception because the frame we're trying to read is larger than our max frame // length assertEquals(TTransportException.CORRUPTED_DATA, e.getType()); assertFalse(trans.isOpen()); TTransportException e2 = assertThrows(TTransportException.class, () -> trans.read(readBuf, 0, 4)); // This time we get an exception indicating the connection was closed assertEquals(TTransportException.NOT_OPEN, e2.getType()); } @Test public void testWrite() throws TTransportException, IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); WriteCountingTransport countingTrans = new WriteCountingTransport(new TIOStreamTransport(new BufferedOutputStream(baos))); TTransport trans = getTransport(countingTrans); trans.write(byteSequence(0, 100)); assertEquals(0, countingTrans.writeCount); trans.write(byteSequence(101, 200)); trans.write(byteSequence(201, 255)); assertEquals(0, countingTrans.writeCount); trans.flush(); assertEquals(1, countingTrans.writeCount); trans.write(byteSequence(0, 245)); trans.flush(); assertEquals(2, countingTrans.writeCount); DataInputStream din = new DataInputStream(new ByteArrayInputStream(baos.toByteArray())); assertEquals(256, din.readInt()); byte[] buf = new byte[256]; int readBytes = din.read(buf, 0, 256); assertArrayEquals(byteSequence(0, 255), buf); assertEquals(246, din.readInt()); buf = new byte[246]; int readBytes2 = din.read(buf, 0, 246); assertArrayEquals(byteSequence(0, 245), buf); } @Test public void testDirectRead() throws IOException, TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeInt(50); dos.write(byteSequence(0, 49)); dos.writeInt(50); dos.write(byteSequence(125, 175)); TMemoryBuffer membuf = new TMemoryBuffer(0); membuf.write(baos.toByteArray()); ReadCountingTransport countTrans = new ReadCountingTransport(membuf); TTransport trans = getTransport(countTrans); assertEquals(0, trans.getBytesRemainingInBuffer()); byte[] readBuf = new byte[10]; trans.read(readBuf, 0, 10); assertArrayEquals(readBuf, byteSequence(0, 9)); assertEquals(40, trans.getBytesRemainingInBuffer()); assertEquals(10, trans.getBufferPosition()); trans.consumeBuffer(5); assertEquals(35, trans.getBytesRemainingInBuffer()); assertEquals(15, trans.getBufferPosition()); assertEquals(2, countTrans.readCount); assertEquals(35, trans.read(new byte[35], 0, 35)); assertEquals(0, trans.getBytesRemainingInBuffer()); assertEquals(50, trans.getBufferPosition()); // Known message size exceeded trans.read(readBuf, 0, 10); assertEquals(4, countTrans.readCount); assertArrayEquals(readBuf, byteSequence(125, 134)); assertEquals(40, trans.getBytesRemainingInBuffer()); assertEquals(10, trans.getBufferPosition()); } @Test public void testClear() throws IOException, TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeInt(220); dos.write(byteSequence(0, 219)); TMemoryBuffer membuf = new TMemoryBuffer(0); membuf.write(baos.toByteArray()); ReadCountingTransport countTrans = new ReadCountingTransport(membuf); TTransport trans = getTransport(countTrans); byte[] readBuf = new byte[220]; trans.read(readBuf, 0, 220); assertArrayEquals(readBuf, byteSequence(0, 219)); assertTrue(trans instanceof TFramedTransport || trans instanceof TFastFramedTransport); if (trans instanceof TFramedTransport) { assertTrue(trans.getBuffer() != null && trans.getBuffer().length > 0); ((TFramedTransport) trans).clear(); assertNull(trans.getBuffer()); } else { assertTrue(trans.getBuffer().length > TestTFastFramedTransport.INITIAL_CAPACITY); ((TFastFramedTransport) trans).clear(); assertEquals(TestTFastFramedTransport.INITIAL_CAPACITY, trans.getBuffer().length); } } } TestTSSLTransportFactoryCustomClient1.java0000664000175000017500000000244415165535636035214 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; public class TestTSSLTransportFactoryCustomClient1 extends TestTSSLTransportFactory { @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { TSSLTransportFactory.TSSLTransportParameters params = new TSSLTransportFactory.TSSLTransportParameters(); params.setTrustStore(getTrustStoreLocation(), getTrustStorePassword()); return TSSLTransportFactory.getClientSocket(HOST, PORT, 0 /*timeout*/, params); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTFastFramedTransport.java0000664000175000017500000000262115165535636032700 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.transport.layered.TFastFramedTransport; public class TestTFastFramedTransport extends TestTFramedTransport { protected static final int INITIAL_CAPACITY = 50; @Override protected TTransport getTransport(TTransport underlying) throws TTransportException { return new TFastFramedTransport(underlying, INITIAL_CAPACITY, 10 * 1024 * 1024); } @Override protected TTransport getTransport(TTransport underlying, int maxLength) throws TTransportException { return new TFastFramedTransport(underlying, INITIAL_CAPACITY, maxLength); } } TestTSSLTransportFactoryCustomClient2.java0000664000175000017500000000242115165535636035210 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; public class TestTSSLTransportFactoryCustomClient2 extends TestTSSLTransportFactory { @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { TSSLTransportFactory.TSSLTransportParameters params = new TSSLTransportFactory.TSSLTransportParameters(); params.setTrustStore(getTrustStoreLocation(), null); return TSSLTransportFactory.getClientSocket(HOST, PORT, 0 /*timeout*/, params); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestNonblockingServerSocket.java0000664000175000017500000000255315165535636033432 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertFalse; import java.nio.channels.ServerSocketChannel; import org.junit.jupiter.api.Test; public class TestNonblockingServerSocket { @Test public void testSocketChannelBlockingMode() throws TTransportException { try (TNonblockingServerSocket nonblockingServer = new TNonblockingServerSocket(0)) { ServerSocketChannel socketChannel = nonblockingServer.getServerSocketChannel(); assertFalse(socketChannel.isBlocking(), "Socket channel should be nonblocking"); } } } TestAutoExpandingBufferWriteTransport.java0000664000175000017500000000567215165535636035405 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.ByteBuffer; import org.apache.thrift.TConfiguration; import org.junit.jupiter.api.Test; public class TestAutoExpandingBufferWriteTransport { private final TConfiguration config = new TConfiguration(); @Test public void testIt() throws Exception { AutoExpandingBufferWriteTransport t = new AutoExpandingBufferWriteTransport(config, 1, 0); assertEquals(0, t.getLength()); assertEquals(1, t.getBuf().array().length); byte[] b1 = new byte[] {1, 2, 3}; t.write(b1); assertEquals(3, t.getLength()); assertTrue(t.getBuf().array().length >= 3); assertEquals(ByteBuffer.wrap(b1), ByteBuffer.wrap(t.getBuf().array(), 0, 3)); t.reset(); assertEquals(0, t.getLength()); assertTrue(t.getBuf().array().length >= 3); byte[] b2 = new byte[] {4, 5}; t.write(b2); assertEquals(2, t.getLength()); assertEquals(ByteBuffer.wrap(b2), ByteBuffer.wrap(t.getBuf().array(), 0, 2)); AutoExpandingBufferWriteTransport uut = new AutoExpandingBufferWriteTransport(config, 8, 4); assertEquals(4, uut.getLength()); assertEquals(8, uut.getBuf().array().length); uut.write(b1); assertEquals(7, uut.getLength()); assertEquals(8, uut.getBuf().array().length); assertEquals(ByteBuffer.wrap(b1), ByteBuffer.wrap(uut.getBuf().array(), 4, 3)); } @Test public void testBadInitialSize() throws TTransportException { assertThrows( IllegalArgumentException.class, () -> new AutoExpandingBufferWriteTransport(config, 0, 0)); } @Test public void testBadFrontReserveSize() throws IllegalArgumentException, TTransportException { assertThrows( IllegalArgumentException.class, () -> new AutoExpandingBufferWriteTransport(config, 4, -1)); } @Test public void testTooSmallFrontReserveSize() throws IllegalArgumentException, TTransportException { assertThrows( IllegalArgumentException.class, () -> new AutoExpandingBufferWriteTransport(config, 4, 5)); } } TestAutoExpandingBufferReadTransport.java0000664000175000017500000000351115165535636035154 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertEquals; import java.nio.ByteBuffer; import org.apache.thrift.TConfiguration; import org.junit.jupiter.api.Test; public class TestAutoExpandingBufferReadTransport { private static final byte[] HUNDRED_BYTES = new byte[100]; static { for (byte i = 0; i < 100; i++) { HUNDRED_BYTES[i] = i; } } @Test public void testIt() throws Exception { AutoExpandingBufferReadTransport t = new AutoExpandingBufferReadTransport(new TConfiguration(), 150); TMemoryInputTransport membuf = new TMemoryInputTransport(new TConfiguration(), HUNDRED_BYTES); t.fill(membuf, 100); assertEquals(100, t.getBytesRemainingInBuffer()); assertEquals(0, t.getBufferPosition()); byte[] target = new byte[10]; assertEquals(10, t.read(target, 0, 10)); assertEquals(ByteBuffer.wrap(HUNDRED_BYTES, 0, 10), ByteBuffer.wrap(target)); assertEquals(90, t.getBytesRemainingInBuffer()); assertEquals(10, t.getBufferPosition()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/ReadCountingTransport.java0000664000175000017500000000417715165535636032272 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TConfiguration; public class ReadCountingTransport extends TTransport { public int readCount = 0; private TTransport trans; private boolean open = true; public ReadCountingTransport(TTransport underlying) { trans = underlying; } @Override public void close() { open = false; } @Override public boolean isOpen() { return open; } @Override public void open() throws TTransportException { open = true; } @Override public int read(byte[] buf, int off, int len) throws TTransportException { if (!isOpen()) { throw new TTransportException(TTransportException.NOT_OPEN, "Transport is closed"); } readCount++; return trans.read(buf, off, len); } @Override public void write(byte[] buf, int off, int len) throws TTransportException { if (!isOpen()) { throw new TTransportException(TTransportException.NOT_OPEN, "Transport is closed"); } } @Override public TConfiguration getConfiguration() { return trans.getConfiguration(); } @Override public void updateKnownMessageSize(long size) throws TTransportException { trans.updateKnownMessageSize(size); } @Override public void checkReadBytesAvailable(long numBytes) throws TTransportException { trans.checkReadBytesAvailable(numBytes); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTMemoryTransport.java0000664000175000017500000000551715165535636032143 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.nio.ByteBuffer; import java.util.Random; import org.apache.thrift.TByteArrayOutputStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; public class TestTMemoryTransport { @Test public void testReadBatches() throws TTransportException { byte[] inputBytes = {0x10, 0x7A, (byte) 0xBF, (byte) 0xFE, 0x53, (byte) 0x82, (byte) 0xFF}; TMemoryTransport transport = new TMemoryTransport(inputBytes); byte[] read = new byte[inputBytes.length]; int firstBatch = new Random().nextInt(inputBytes.length); int secondBatch = inputBytes.length - firstBatch; transport.read(read, 0, firstBatch); transport.read(read, firstBatch, secondBatch); boolean equal = true; for (int i = 0; i < inputBytes.length; i++) { equal = equal && inputBytes[i] == read[i]; } assertEquals(ByteBuffer.wrap(inputBytes), ByteBuffer.wrap(read)); } @Test public void testReadMoreThanRemaining() throws TTransportException { TMemoryTransport transport = new TMemoryTransport(new byte[] {0x00, 0x32}); byte[] read = new byte[3]; assertThrows( TTransportException.class, new Executable() { @Override public void execute() throws Throwable { transport.read(read, 0, 3); } }); } @Test public void testWrite() throws TTransportException { TMemoryTransport transport = new TMemoryTransport(new byte[0]); byte[] output1 = {0x72, 0x56, 0x29, (byte) 0xAF, (byte) 0x9B}; transport.write(output1); byte[] output2 = {(byte) 0x83, 0x10, 0x00}; transport.write(output2, 0, 2); byte[] expected = {0x72, 0x56, 0x29, (byte) 0xAF, (byte) 0x9B, (byte) 0x83, 0x10}; TByteArrayOutputStream outputByteArray = transport.getOutput(); assertEquals( ByteBuffer.wrap(expected), ByteBuffer.wrap(outputByteArray.get(), 0, outputByteArray.len())); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTIOStreamTransport.java0000664000175000017500000000437215165535636032354 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import org.junit.jupiter.api.Test; public class TestTIOStreamTransport { // THRIFT-5022 @Test public void testOpenClose_2streams() throws TTransportException { byte[] dummy = {20}; // So the input stream isn't EOF immediately. InputStream input = new ByteArrayInputStream(dummy); OutputStream output = new ByteArrayOutputStream(); TTransport transport = new TIOStreamTransport(input, output); runOpenClose(transport); } // THRIFT-5022 @Test public void testOpenClose_1input() throws TTransportException { byte[] dummy = {20}; InputStream input = new ByteArrayInputStream(dummy); TTransport transport = new TIOStreamTransport(input); runOpenClose(transport); } // THRIFT-5022 @Test public void testIOpenClose_1output() throws TTransportException { OutputStream output = new ByteArrayOutputStream(); TTransport transport = new TIOStreamTransport(output); runOpenClose(transport); } private void runOpenClose(TTransport transport) throws TTransportException { transport.open(); boolean b1 = transport.isOpen(); assertTrue(b1); transport.close(); boolean b2 = transport.isOpen(); assertFalse(b2); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/WriteCountingTransport.java0000664000175000017500000000366615165535636032513 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TConfiguration; public class WriteCountingTransport extends TTransport { public int writeCount = 0; private final TTransport trans; public WriteCountingTransport(TTransport underlying) { trans = underlying; } @Override public void close() {} @Override public boolean isOpen() { return true; } @Override public void open() throws TTransportException {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { return 0; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { writeCount++; trans.write(buf, off, len); } @Override public void flush() throws TTransportException { trans.flush(); } @Override public TConfiguration getConfiguration() { return trans.getConfiguration(); } @Override public void updateKnownMessageSize(long size) throws TTransportException { trans.updateKnownMessageSize(size); } @Override public void checkReadBytesAvailable(long numBytes) throws TTransportException { trans.checkReadBytesAvailable(numBytes); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/sasl/0000775000175000017500000000000015165535636026061 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/sasl/TestDataFrameReader.java0000664000175000017500000000534715165535636032544 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.ByteBuffer; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransportException; import org.junit.jupiter.api.Test; public class TestDataFrameReader { @Test public void testRead() throws TTransportException { // Prepare data int payloadSize = 23; ByteBuffer buffer = ByteBuffer.allocate(DataFrameHeaderReader.PAYLOAD_LENGTH_BYTES + payloadSize); buffer.putInt(payloadSize); for (int i = 0; i < payloadSize; i++) { buffer.put((byte) i); } buffer.rewind(); TMemoryInputTransport transport = new TMemoryInputTransport(); DataFrameReader dataFrameReader = new DataFrameReader(); // No bytes received. dataFrameReader.read(transport); assertFalse(dataFrameReader.isComplete(), "No bytes received"); assertFalse(dataFrameReader.getHeader().isComplete(), "No bytes received"); // Payload size (header) and part of the payload are received. transport.reset(buffer.array(), 0, 6); dataFrameReader.read(transport); assertFalse(dataFrameReader.isComplete(), "Only header is complete"); assertTrue(dataFrameReader.getHeader().isComplete(), "Header should be complete"); assertEquals( payloadSize, dataFrameReader.getHeader().payloadSize(), "Payload size should be " + payloadSize); // Read the rest of payload. transport.reset(buffer.array(), 6, 21); dataFrameReader.read(transport); assertTrue(dataFrameReader.isComplete(), "Reader should be complete"); buffer.position(DataFrameHeaderReader.PAYLOAD_LENGTH_BYTES); assertEquals( buffer, ByteBuffer.wrap(dataFrameReader.getPayload()), "Payload should be the same as from the transport"); } } TestSaslNegotiationFrameReader.java0000664000175000017500000000561315165535636034713 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/sasl/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.ByteBuffer; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransportException; import org.junit.jupiter.api.Test; public class TestSaslNegotiationFrameReader { @Test public void testRead() throws TTransportException { TMemoryInputTransport transport = new TMemoryInputTransport(); SaslNegotiationFrameReader negotiationReader = new SaslNegotiationFrameReader(); // No bytes received negotiationReader.read(transport); assertFalse(negotiationReader.isComplete(), "No bytes received"); assertFalse(negotiationReader.getHeader().isComplete(), "No bytes received"); // Read header ByteBuffer buffer = ByteBuffer.allocate(5); buffer.put(0, NegotiationStatus.OK.getValue()); buffer.putInt(1, 10); transport.reset(buffer.array()); negotiationReader.read(transport); assertFalse(negotiationReader.isComplete(), "Only header is complete"); assertTrue(negotiationReader.getHeader().isComplete(), "Header should be complete"); assertEquals(10, negotiationReader.getHeader().payloadSize(), "Payload size should be 10"); // Read payload transport.reset(new byte[20]); negotiationReader.read(transport); assertTrue(negotiationReader.isComplete(), "Reader should be complete"); assertEquals(10, negotiationReader.getPayload().length, "Payload length should be 10"); } @Test public void testReadInvalidNegotiationStatus() throws TTransportException { byte[] bytes = new byte[5]; // Invalid status byte. bytes[0] = -1; TMemoryInputTransport transport = new TMemoryInputTransport(bytes); SaslNegotiationFrameReader negotiationReader = new SaslNegotiationFrameReader(); assertThrows( TSaslNegotiationException.class, () -> { negotiationReader.read(transport); }); } } TestSaslNegotiationFrameWriter.java0000664000175000017500000000454415165535636034767 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/sasl/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.SaslNegotiationFrameWriter.HEADER_BYTES; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.nio.ByteBuffer; import org.apache.thrift.EncodingUtils; import org.junit.jupiter.api.Test; public class TestSaslNegotiationFrameWriter { private static final byte[] PAYLOAD = {0x11, 0x08, 0x3F, 0x58, 0x73, 0x22, 0x00, (byte) 0xFF}; @Test public void testWithHeaderAndPayload() { SaslNegotiationFrameWriter frameWriter = new SaslNegotiationFrameWriter(); frameWriter.withHeaderAndPayload(new byte[] {NegotiationStatus.OK.getValue()}, PAYLOAD); byte[] expectedBytes = new byte[HEADER_BYTES + PAYLOAD.length]; expectedBytes[0] = NegotiationStatus.OK.getValue(); EncodingUtils.encodeBigEndian(PAYLOAD.length, expectedBytes, 1); System.arraycopy(PAYLOAD, 0, expectedBytes, HEADER_BYTES, PAYLOAD.length); assertEquals(ByteBuffer.wrap(expectedBytes), frameWriter.frameBytes); } @Test public void testWithInvalidHeaderLength() { SaslNegotiationFrameWriter frameWriter = new SaslNegotiationFrameWriter(); assertThrows( IllegalArgumentException.class, () -> frameWriter.withHeaderAndPayload(new byte[5], 0, 2, PAYLOAD, 0, 1)); } @Test public void testWithOnlyPayload() { SaslNegotiationFrameWriter frameWriter = new SaslNegotiationFrameWriter(); assertThrows( UnsupportedOperationException.class, () -> frameWriter.withOnlyPayload(new byte[0])); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/sasl/TestDataFrameWriter.java0000664000175000017500000001014215165535636032603 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport.sasl; import static org.apache.thrift.transport.sasl.DataFrameHeaderReader.PAYLOAD_LENGTH_BYTES; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.ByteBuffer; import org.apache.thrift.EncodingUtils; import org.apache.thrift.transport.TNonblockingTransport; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; public class TestDataFrameWriter { private static final byte[] BYTES = new byte[] {0x32, 0x2A, (byte) 0xE1, 0x18, (byte) 0x90, 0x75}; @Test public void testProvideEntireByteArrayAsPayload() { DataFrameWriter frameWriter = new DataFrameWriter(); frameWriter.withOnlyPayload(BYTES); byte[] expectedBytes = new byte[BYTES.length + PAYLOAD_LENGTH_BYTES]; EncodingUtils.encodeBigEndian(BYTES.length, expectedBytes); System.arraycopy(BYTES, 0, expectedBytes, PAYLOAD_LENGTH_BYTES, BYTES.length); assertEquals(ByteBuffer.wrap(expectedBytes), frameWriter.frameBytes); } @Test public void testProvideByteArrayPortionAsPayload() { DataFrameWriter frameWriter = new DataFrameWriter(); int portionOffset = 2; int portionLength = 3; frameWriter.withOnlyPayload(BYTES, portionOffset, portionLength); byte[] expectedBytes = new byte[portionLength + PAYLOAD_LENGTH_BYTES]; EncodingUtils.encodeBigEndian(portionLength, expectedBytes); System.arraycopy(BYTES, portionOffset, expectedBytes, PAYLOAD_LENGTH_BYTES, portionLength); assertEquals(ByteBuffer.wrap(expectedBytes), frameWriter.frameBytes); } @Test public void testProvideHeaderAndPayload() { DataFrameWriter frameWriter = new DataFrameWriter(); assertThrows( IllegalArgumentException.class, () -> frameWriter.withHeaderAndPayload(new byte[1], new byte[1])); } @Test public void testProvidePayloadToIncompleteFrame() { DataFrameWriter frameWriter = new DataFrameWriter(); assertThrows( IllegalStateException.class, () -> { frameWriter.withOnlyPayload(BYTES); frameWriter.withOnlyPayload(new byte[1]); }); } @Test public void testWrite() throws Exception { DataFrameWriter frameWriter = new DataFrameWriter(); frameWriter.withOnlyPayload(BYTES); // Slow socket which writes one byte per call. TNonblockingTransport transport = Mockito.mock(TNonblockingTransport.class); SlowWriting slowWriting = new SlowWriting(); Mockito.when(transport.write(frameWriter.frameBytes)).thenAnswer(slowWriting); frameWriter.write(transport); while (slowWriting.written < frameWriter.frameBytes.limit()) { assertFalse(frameWriter.isComplete(), "Frame writer should not be complete"); frameWriter.write(transport); } assertTrue(frameWriter.isComplete(), "Frame writer should be complete"); } private static class SlowWriting implements Answer { int written = 0; @Override public Integer answer(InvocationOnMock invocation) throws Throwable { ByteBuffer bytes = (ByteBuffer) invocation.getArguments()[0]; bytes.get(); written++; return 1; } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTSaslTransports.java0000664000175000017500000004355215165535636031761 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.RealmCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslClientFactory; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; import org.apache.thrift.TConfiguration; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TServer.Args; import org.apache.thrift.server.TSimpleServer; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestTSaslTransports { private static final Logger LOGGER = LoggerFactory.getLogger(TestTSaslTransports.class); public static final String HOST = "localhost"; public static final String SERVICE = "thrift-test"; public static final String PRINCIPAL = "thrift-test-principal"; public static final String PASSWORD = "super secret password"; public static final String REALM = "thrift-test-realm"; public static final String UNWRAPPED_MECHANISM = "CRAM-MD5"; public static final Map UNWRAPPED_PROPS = null; public static final String WRAPPED_MECHANISM = "DIGEST-MD5"; public static final Map WRAPPED_PROPS = new HashMap(); static { WRAPPED_PROPS.put(Sasl.QOP, "auth-int"); WRAPPED_PROPS.put("com.sun.security.sasl.digest.realm", REALM); } private static final String testMessage1 = "Hello, world! Also, four " + "score and seven years ago our fathers brought forth on this " + "continent a new nation, conceived in liberty, and dedicated to the " + "proposition that all men are created equal."; private static final String testMessage2 = "I have a dream that one day " + "this nation will rise up and live out the true meaning of its creed: " + "'We hold these truths to be self-evident, that all men are created equal.'"; public static class TestSaslCallbackHandler implements CallbackHandler { private final String password; public TestSaslCallbackHandler(String password) { this.password = password; } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback c : callbacks) { if (c instanceof NameCallback) { ((NameCallback) c).setName(PRINCIPAL); } else if (c instanceof PasswordCallback) { ((PasswordCallback) c).setPassword(password.toCharArray()); } else if (c instanceof AuthorizeCallback) { ((AuthorizeCallback) c).setAuthorized(true); } else if (c instanceof RealmCallback) { ((RealmCallback) c).setText(REALM); } else { throw new UnsupportedCallbackException(c); } } } } private static class ServerThread extends Thread { final String mechanism; final Map props; volatile Throwable thrown; public ServerThread(String mechanism, Map props) { this.mechanism = mechanism; this.props = props; } public void run() { try { internalRun(); } catch (Throwable t) { thrown = t; } } private void internalRun() throws Exception { try (TServerSocket serverSocket = new TServerSocket( new TServerSocket.ServerSocketTransportArgs().port(ServerTestBase.PORT))) { acceptAndWrite(serverSocket); } } private void acceptAndWrite(TServerSocket serverSocket) throws Exception { TTransport serverTransport = serverSocket.accept(); TTransport saslServerTransport = new TSaslServerTransport( mechanism, SERVICE, HOST, props, new TestSaslCallbackHandler(PASSWORD), serverTransport); saslServerTransport.open(); byte[] inBuf = new byte[testMessage1.getBytes().length]; // Deliberately read less than the full buffer to ensure // that TSaslTransport is correctly buffering reads. This // will fail for the WRAPPED test, if it doesn't work. saslServerTransport.readAll(inBuf, 0, 5); saslServerTransport.readAll(inBuf, 5, 10); saslServerTransport.readAll(inBuf, 15, inBuf.length - 15); LOGGER.debug("server got: {}", new String(inBuf)); assertEquals(new String(inBuf), testMessage1); LOGGER.debug("server writing: {}", testMessage2); saslServerTransport.write(testMessage2.getBytes()); saslServerTransport.flush(); saslServerTransport.close(); } } private void testSaslOpen(final String mechanism, final Map props) throws Exception { ServerThread serverThread = new ServerThread(mechanism, props); serverThread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { // Ah well. } try { TSocket clientSocket = new TSocket(HOST, ServerTestBase.PORT); TTransport saslClientTransport = new TSaslClientTransport( mechanism, PRINCIPAL, SERVICE, HOST, props, new TestSaslCallbackHandler(PASSWORD), clientSocket); saslClientTransport.open(); LOGGER.debug("client writing: {}", testMessage1); saslClientTransport.write(testMessage1.getBytes()); saslClientTransport.flush(); byte[] inBuf = new byte[testMessage2.getBytes().length]; saslClientTransport.readAll(inBuf, 0, inBuf.length); LOGGER.debug("client got: {}", new String(inBuf)); assertEquals(new String(inBuf), testMessage2); TTransportException expectedException = null; try { saslClientTransport.open(); } catch (TTransportException e) { expectedException = e; } assertNotNull(expectedException); saslClientTransport.close(); } catch (Exception e) { LOGGER.warn("Exception caught", e); throw e; } finally { serverThread.interrupt(); try { serverThread.join(); } catch (InterruptedException e) { // Ah well. } assertNull(serverThread.thrown); } } @Test public void testUnwrappedOpen() throws Exception { testSaslOpen(UNWRAPPED_MECHANISM, UNWRAPPED_PROPS); } @Test public void testWrappedOpen() throws Exception { testSaslOpen(WRAPPED_MECHANISM, WRAPPED_PROPS); } @Test public void testAnonymousOpen() throws Exception { testSaslOpen("ANONYMOUS", null); } /** * Test that we get the proper exceptions thrown back the server when the client provides invalid * password. */ @Test public void testBadPassword() throws Exception { ServerThread serverThread = new ServerThread(UNWRAPPED_MECHANISM, UNWRAPPED_PROPS); serverThread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { // Ah well. } TTransportException tte = assertThrows( TTransportException.class, () -> { TSocket clientSocket = new TSocket(HOST, ServerTestBase.PORT); TTransport saslClientTransport = new TSaslClientTransport( UNWRAPPED_MECHANISM, PRINCIPAL, SERVICE, HOST, UNWRAPPED_PROPS, new TestSaslCallbackHandler("NOT THE PASSWORD"), clientSocket); saslClientTransport.open(); }, "Was able to open transport with bad password"); LOGGER.error("Exception for bad password", tte); assertNotNull(tte.getMessage()); assertTrue(tte.getMessage().contains("Invalid response")); serverThread.interrupt(); serverThread.join(); assertNotNull(serverThread.thrown); assertTrue(serverThread.thrown.getMessage().contains("Invalid response")); } @Test public void testWithServer() throws Exception { new TestTSaslTransportsWithServer().testIt(); } public static class TestTSaslTransportsWithServer extends ServerTestBase { private Thread serverThread; private TServer server; @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { return new TSaslClientTransport( WRAPPED_MECHANISM, PRINCIPAL, SERVICE, HOST, WRAPPED_PROPS, new TestSaslCallbackHandler(PASSWORD), underlyingTransport); } @Override public void startServer( final TProcessor processor, final TProtocolFactory protoFactory, final TTransportFactory factory) throws Exception { serverThread = new Thread() { public void run() { try { // Transport TServerSocket socket = new TServerSocket(new TServerSocket.ServerSocketTransportArgs().port(PORT)); TTransportFactory factory = new TSaslServerTransport.Factory( WRAPPED_MECHANISM, SERVICE, HOST, WRAPPED_PROPS, new TestSaslCallbackHandler(PASSWORD)); server = new TSimpleServer( new Args(socket) .processor(processor) .transportFactory(factory) .protocolFactory(protoFactory)); // Run it LOGGER.debug("Starting the server on port {}", PORT); server.serve(); } catch (Exception e) { e.printStackTrace(); fail(e); } } }; serverThread.start(); Thread.sleep(1000); } @Override public void stopServer() throws Exception { server.stop(); try { serverThread.join(); } catch (InterruptedException e) { LOGGER.debug("interrupted during sleep", e); } } } /** Implementation of SASL ANONYMOUS, used for testing client-side initial responses. */ private static class AnonymousClient implements SaslClient { private final String username; private boolean hasProvidedInitialResponse; public AnonymousClient(String username) { this.username = username; } @Override public String getMechanismName() { return "ANONYMOUS"; } @Override public boolean hasInitialResponse() { return true; } @Override public byte[] evaluateChallenge(byte[] challenge) throws SaslException { if (hasProvidedInitialResponse) { throw new SaslException("Already complete!"); } hasProvidedInitialResponse = true; return username.getBytes(StandardCharsets.UTF_8); } @Override public boolean isComplete() { return hasProvidedInitialResponse; } @Override public byte[] unwrap(byte[] incoming, int offset, int len) { throw new UnsupportedOperationException(); } @Override public byte[] wrap(byte[] outgoing, int offset, int len) { throw new UnsupportedOperationException(); } @Override public Object getNegotiatedProperty(String propName) { return null; } @Override public void dispose() {} } private static class AnonymousServer implements SaslServer { private String user; @Override public String getMechanismName() { return "ANONYMOUS"; } @Override public byte[] evaluateResponse(byte[] response) throws SaslException { this.user = new String(response, StandardCharsets.UTF_8); return null; } @Override public boolean isComplete() { return user != null; } @Override public String getAuthorizationID() { return user; } @Override public byte[] unwrap(byte[] incoming, int offset, int len) { throw new UnsupportedOperationException(); } @Override public byte[] wrap(byte[] outgoing, int offset, int len) { throw new UnsupportedOperationException(); } @Override public Object getNegotiatedProperty(String propName) { return null; } @Override public void dispose() {} } public static class SaslAnonymousFactory implements SaslClientFactory, SaslServerFactory { @Override public SaslClient createSaslClient( String[] mechanisms, String authorizationId, String protocol, String serverName, Map props, CallbackHandler cbh) { for (String mech : mechanisms) { if ("ANONYMOUS".equals(mech)) { return new AnonymousClient(authorizationId); } } return null; } @Override public SaslServer createSaslServer( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { if ("ANONYMOUS".equals(mechanism)) { return new AnonymousServer(); } return null; } @Override public String[] getMechanismNames(Map props) { return new String[] {"ANONYMOUS"}; } } static { java.security.Security.addProvider(new SaslAnonymousProvider()); } public static class SaslAnonymousProvider extends java.security.Provider { public SaslAnonymousProvider() { super("ThriftSaslAnonymous", 1.0, "Thrift Anonymous SASL provider"); put("SaslClientFactory.ANONYMOUS", SaslAnonymousFactory.class.getName()); put("SaslServerFactory.ANONYMOUS", SaslAnonymousFactory.class.getName()); } } private static class MockTTransport extends TTransport { byte[] badHeader = null; private final TMemoryInputTransport readBuffer; public MockTTransport(int mode) throws TTransportException { readBuffer = new TMemoryInputTransport(); if (mode == 1) { // Invalid status byte badHeader = new byte[] {(byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05}; } else if (mode == 2) { // Valid status byte, negative payload length badHeader = new byte[] {(byte) 0x01, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; } else if (mode == 3) { // Valid status byte, excessively large, bogus payload length badHeader = new byte[] {(byte) 0x01, (byte) 0x64, (byte) 0x00, (byte) 0x00, (byte) 0x00}; } readBuffer.reset(badHeader); } @Override public boolean isOpen() { return true; } @Override public void open() throws TTransportException {} @Override public void close() {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { return readBuffer.read(buf, off, len); } @Override public void write(byte[] buf, int off, int len) throws TTransportException {} @Override public TConfiguration getConfiguration() { return readBuffer.getConfiguration(); } @Override public void updateKnownMessageSize(long size) throws TTransportException { readBuffer.updateKnownMessageSize(size); } @Override public void checkReadBytesAvailable(long numBytes) throws TTransportException { readBuffer.checkReadBytesAvailable(numBytes); } } @Test public void testBadHeader() { TSaslTransport saslTransport; try { saslTransport = new TSaslServerTransport(new MockTTransport(1)); saslTransport.receiveSaslMessage(); fail("Should have gotten an error due to incorrect status byte value."); } catch (TTransportException e) { assertEquals(e.getMessage(), "Invalid status -1"); } try { saslTransport = new TSaslServerTransport(new MockTTransport(2)); saslTransport.receiveSaslMessage(); fail("Should have gotten an error due to negative payload length."); } catch (TTransportException e) { assertEquals(e.getMessage(), "Invalid payload header length: -1"); } try { saslTransport = new TSaslServerTransport(new MockTTransport(3)); saslTransport.receiveSaslMessage(); fail("Should have gotten an error due to bogus (large) payload length."); } catch (TTransportException e) { assertEquals(e.getMessage(), "Invalid payload header length: 1677721600"); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTSimpleFileTransport.java0000664000175000017500000000545415165535636032724 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import java.nio.file.Files; import java.nio.file.Path; import org.junit.jupiter.api.Test; public class TestTSimpleFileTransport { @Test public void testFresh() throws Exception { // Test write side Path tempFilePathName = Files.createTempFile("TSimpleFileTransportTest", null); Files.delete(tempFilePathName); byte[] input_buf = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; TSimpleFileTransport trans_write = new TSimpleFileTransport(tempFilePathName.toString(), false, true, false); assert (!trans_write.isOpen()); trans_write.open(); assert (trans_write.isOpen()); trans_write.write(input_buf); trans_write.write(input_buf, 2, 2); trans_write.flush(); trans_write.close(); // Test read side TSimpleFileTransport trans = new TSimpleFileTransport(tempFilePathName.toString(), true, false); assert (trans.isOpen()); // Simple file trans provides no buffer access assertEquals(0, trans.getBufferPosition()); assertNull(trans.getBuffer()); assertEquals(-1, trans.getBytesRemainingInBuffer()); // Test file pointer operations assertEquals(0, trans.getFilePointer()); assertEquals(12, trans.length()); final int BUFSIZ = 4; byte[] buf1 = new byte[BUFSIZ]; trans.readAll(buf1, 0, BUFSIZ); assertEquals(BUFSIZ, trans.getFilePointer()); assertArrayEquals(new byte[] {1, 2, 3, 4}, buf1); int bytesRead = trans.read(buf1, 0, BUFSIZ); assert (bytesRead > 0); for (int i = 0; i < bytesRead; ++i) { assertEquals(buf1[i], i + 5); } trans.seek(0); assertEquals(0, trans.getFilePointer()); trans.readAll(buf1, 0, BUFSIZ); assertArrayEquals(new byte[] {1, 2, 3, 4}, buf1); assertEquals(BUFSIZ, trans.getFilePointer()); trans.close(); Files.delete(tempFilePathName); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTMemoryInputTransport.java0000664000175000017500000000637715165535636033170 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; public class TestTMemoryInputTransport { @Test public void testFresh() throws Exception { byte[] input_buf = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; TMemoryInputTransport trans = new TMemoryInputTransport(input_buf); assertEquals(0, trans.getBufferPosition()); assertEquals(input_buf, trans.getBuffer()); assertEquals(10, trans.getBytesRemainingInBuffer()); byte[] buf1 = new byte[4]; trans.readAll(buf1, 0, 4); assertArrayEquals(new byte[] {1, 2, 3, 4}, buf1); assertEquals(4, trans.getBufferPosition()); assertEquals(6, trans.getBytesRemainingInBuffer()); trans.consumeBuffer(2); assertEquals(6, trans.getBufferPosition()); assertEquals(4, trans.getBytesRemainingInBuffer()); trans.readAll(buf1, 0, 4); assertArrayEquals(new byte[] {7, 8, 9, 10}, buf1); assertEquals(10, trans.getBufferPosition()); assertEquals(0, trans.getBytesRemainingInBuffer()); } @Test public void testReused() throws Exception { byte[] input_buf = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; TMemoryInputTransport trans = new TMemoryInputTransport(input_buf); assertEquals(0, trans.getBufferPosition()); assertEquals(input_buf, trans.getBuffer()); assertEquals(10, trans.getBytesRemainingInBuffer()); byte[] new_buf = new byte[] {10, 9, 8}; trans.reset(new_buf); assertEquals(0, trans.getBufferPosition()); assertEquals(new_buf, trans.getBuffer()); assertEquals(3, trans.getBytesRemainingInBuffer()); } @Test public void testWithOffsetAndLength() throws TTransportException { byte[] input_buf = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; TMemoryInputTransport trans = new TMemoryInputTransport(input_buf, 1, 3); assertEquals(1, trans.getBufferPosition()); assertEquals(3, trans.getBytesRemainingInBuffer()); { byte[] readBuffer = new byte[3]; trans.readAll(readBuffer, 0, 3); assertArrayEquals(new byte[] {2, 3, 4}, readBuffer); assertThrows(Exception.class, () -> trans.readAll(readBuffer, 0, 3)); } { trans.reset(input_buf, 3, 4); byte[] readBuffer2 = new byte[4]; trans.readAll(readBuffer2, 0, 4); assertArrayEquals(new byte[] {4, 5, 6, 7}, readBuffer2); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTByteBuffer.java0000664000175000017500000000524315165535636031007 0ustar00buildbuild00000000000000package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import org.apache.thrift.TConfiguration; import org.junit.jupiter.api.Test; public class TestTByteBuffer { @Test public void testReadWrite() throws Exception { final TByteBuffer byteBuffer = new TByteBuffer(ByteBuffer.allocate(16)); byteBuffer.write("Hello World".getBytes(StandardCharsets.UTF_8)); assertEquals( "Hello World", new String(byteBuffer.flip().toByteArray(), StandardCharsets.UTF_8)); } @Test public void testReuseReadWrite() throws Exception { final TByteBuffer byteBuffer = new TByteBuffer(ByteBuffer.allocate(16)); byteBuffer.write("Hello World".getBytes(StandardCharsets.UTF_8)); assertEquals( "Hello World", new String(byteBuffer.flip().toByteArray(), StandardCharsets.UTF_8)); byteBuffer.clear(); byteBuffer.write("Goodbye Horses".getBytes(StandardCharsets.UTF_8)); assertEquals( "Goodbye Horses", new String(byteBuffer.flip().toByteArray(), StandardCharsets.UTF_8)); } @Test public void testOverflow() throws Exception { final TByteBuffer byteBuffer = new TByteBuffer(ByteBuffer.allocate(4)); TTransportException e = assertThrows( TTransportException.class, () -> byteBuffer.write("Hello World".getBytes(StandardCharsets.UTF_8))); assertEquals("Not enough room in output buffer", e.getMessage()); } @Test public void testSmallTConfiguration() throws Exception { // Test that TByteBuffer init fail with small max message size. final TConfiguration configSmall = new TConfiguration( 4, TConfiguration.DEFAULT_MAX_FRAME_SIZE, TConfiguration.DEFAULT_RECURSION_DEPTH); TTransportException e = assertThrows( TTransportException.class, () -> new TByteBuffer(configSmall, ByteBuffer.allocate(100))); assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } @Test public void testLargeTConfiguration() throws Exception { // Test that TByteBuffer init pass with large max message size beyond // TConfiguration.DEFAULT_MAX_MESSAGE_SIZE. int maxSize = 101 * 1024 * 1024; int bufferSize = (100 * 1024 + 512) * 1024; final TConfiguration configLarge = new TConfiguration( maxSize, TConfiguration.DEFAULT_MAX_FRAME_SIZE, TConfiguration.DEFAULT_RECURSION_DEPTH); assertDoesNotThrow(() -> new TByteBuffer(configLarge, ByteBuffer.allocate(bufferSize))); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestAutoExpandingBuffer.java0000664000175000017500000000263615165535636032531 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; public class TestAutoExpandingBuffer { @Test public void testExpands() throws Exception { // has expected initial capacity AutoExpandingBuffer b = new AutoExpandingBuffer(10); assertEquals(10, b.array().length); // doesn't shrink b.resizeIfNecessary(8); assertEquals(10, b.array().length); // grows when more capacity is needed b.resizeIfNecessary(100); assertTrue(b.array().length >= 100); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/TestTSSLTransportFactory.java0000664000175000017500000000717015165535636032661 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.util.Collections; import java.util.List; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TServer.Args; import org.apache.thrift.server.TSimpleServer; public class TestTSSLTransportFactory extends ServerTestBase { private Thread serverThread; private TServer server; // TODO: Only supported on TBinaryProtocol. Doesn't work for TCompactProtocol private static final List protocols = Collections.singletonList(new TBinaryProtocol.Factory()); private static final String keyStoreLocation = System.getProperty("javax.net.ssl.keyStore"); private static final String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword"); private static final String trustStoreLocation = System.getProperty("javax.net.ssl.trustStore"); private static final String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); protected final String getKeyStoreLocation() { return keyStoreLocation; } protected final String getKeyStorePassword() { return keyStorePassword; } protected final String getTrustStoreLocation() { return trustStoreLocation; } protected final String getTrustStorePassword() { return trustStorePassword; } @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { return TSSLTransportFactory.getClientSocket(HOST, PORT); } protected TServerSocket getServerTransport() throws Exception { return TSSLTransportFactory.getServerSocket(PORT); } @Override public void startServer( final TProcessor processor, final TProtocolFactory protoFactory, final TTransportFactory factory) throws Exception { serverThread = new Thread( () -> { try { TServerTransport serverTransport = getServerTransport(); final Args args = new Args(serverTransport).processor(processor); server = new TSimpleServer(args); server.serve(); } catch (Exception e) { e.printStackTrace(); assert false; } }); serverThread.start(); Thread.sleep(SLEEP_DELAY); } @Override public void stopServer() throws Exception { server.stop(); serverThread.join(); } @Override public void open(TTransport transport) throws Exception {} @Override public List getProtocols() { return protocols; } @Override public void testTransportFactory() throws Exception { // this test doesn't really apply to this suite, so let's skip it. } } TestTSSLTransportFactoryStreamedStore.java0000664000175000017500000000342315165535636035301 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/transport/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.FileInputStream; import java.net.InetAddress; public class TestTSSLTransportFactoryStreamedStore extends TestTSSLTransportFactory { @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { TSSLTransportFactory.TSSLTransportParameters params = new TSSLTransportFactory.TSSLTransportParameters(); params.setTrustStore(new FileInputStream(getTrustStoreLocation()), getTrustStorePassword()); return TSSLTransportFactory.getClientSocket(HOST, PORT, 0 /*timeout*/, params); } @Override protected TServerSocket getServerTransport() throws Exception { TSSLTransportFactory.TSSLTransportParameters params = new TSSLTransportFactory.TSSLTransportParameters(); params.setKeyStore(new FileInputStream(getKeyStoreLocation()), getKeyStorePassword()); return TSSLTransportFactory.getServerSocket( PORT, 0 /*timeout*/, InetAddress.getByName(HOST), params); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/utils/0000775000175000017500000000000015165535636024223 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/utils/TestStringUtils.java0000664000175000017500000000374515165535636030226 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.utils; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class TestStringUtils { @Test public void testToHexString() { byte[] bytes = {0x00, 0x1A, (byte) 0xEF, (byte) 0xAB, (byte) 0x92}; assertEquals("001AEFAB92", StringUtils.bytesToHexString(bytes)); assertEquals("EFAB92", StringUtils.bytesToHexString(bytes, 2, 3)); assertNull(StringUtils.bytesToHexString(null)); } private byte[] bytes; @BeforeEach public void setUp() throws Exception { bytes = new byte[] {1, 2, 3, 4, 5}; } @Test public void testNegativeLength() { assertThrows(IllegalArgumentException.class, () -> StringUtils.bytesToHexString(bytes, 0, -1)); } @Test public void testNegativeStartOffset() { assertThrows(IndexOutOfBoundsException.class, () -> StringUtils.bytesToHexString(bytes, -1, 1)); } @Test public void testInvalidRange() { assertThrows(IndexOutOfBoundsException.class, () -> StringUtils.bytesToHexString(bytes, 5, 1)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/0000775000175000017500000000000015165535636024517 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/ThriftFieldTest.java0000664000175000017500000001064615165535636030435 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; public class ThriftFieldTest { @Test public void testArgChecks() { ThriftField test; List testFields; // Should not throw. test = new ThriftField("foo"); test = new ThriftField("foo", Collections.singletonList(new ThriftField("bar"))); testFields = ThriftField.fromNames(Collections.singletonList("foo")); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> new ThriftField(null, Collections.emptyList()), "'name' must not be null"); assertThrows( IllegalArgumentException.class, () -> new ThriftField("foo", null), "'fields' must not be null"); assertThrows( IllegalArgumentException.class, () -> ThriftField.fromNames(null), "'fieldNames' must not be null"); assertThrows( IllegalArgumentException.class, () -> ThriftField.fromNames(Collections.emptyList()), "'fieldNames' must have at least one element"); } @Test public void testFromNames() { List fieldNames = Arrays.asList("f1", "f2.f21", "f3.f31.f311", "f3.f32.f321", "f3.f32.f322"); List testFields = ThriftField.fromNames(fieldNames); assertEquals(3, testFields.size()); ThriftField f1 = testFields.get(0); ThriftField f2 = testFields.get(1); ThriftField f3 = testFields.get(2); assertEquals("f1", f1.name); assertEquals("f2", f2.name); assertEquals("f3", f3.name); assertEquals(0, f1.fields.size()); assertEquals(1, f2.fields.size()); assertEquals(2, f3.fields.size()); ThriftField f21 = f2.fields.get(0); ThriftField f31 = f3.fields.get(0); ThriftField f32 = f3.fields.get(1); assertEquals("f21", f21.name); assertEquals("f31", f31.name); assertEquals("f32", f32.name); assertEquals(0, f21.fields.size()); assertEquals(1, f31.fields.size()); assertEquals(2, f32.fields.size()); ThriftField f311 = f31.fields.get(0); ThriftField f321 = f32.fields.get(0); ThriftField f322 = f32.fields.get(1); assertEquals("f311", f311.name); assertEquals("f321", f321.name); assertEquals("f322", f322.name); assertEquals(0, f311.fields.size()); assertEquals(0, f321.fields.size()); assertEquals(0, f322.fields.size()); } @Test public void testEquality() { List fieldNames = Arrays.asList("f1", "f2.f21", "f3.f31.f311", "f3.f32.f321", "f3.f32.f322"); List testFields = ThriftField.fromNames(fieldNames); List testFields2 = testFields; assertSame(testFields, testFields2); assertEquals(testFields, testFields2); List testFields3 = ThriftField.fromNames(fieldNames); assertNotSame(testFields, testFields3); assertEquals(testFields, testFields3); assertEquals(testFields.hashCode(), testFields3.hashCode()); List fieldNamesDiff = Arrays.asList("f1", "f2.f21", "f3.f31.f311", "f3.f32.f323", "f3.f32.f322"); List testFields4 = ThriftField.fromNames(fieldNamesDiff); assertNotSame(testFields, testFields4); assertNotEquals(testFields, testFields4); assertNotEquals(testFields.hashCode(), testFields4.hashCode()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/ThriftStructProcessorTest.java0000664000175000017500000002553715165535636032603 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.TBase; import org.apache.thrift.TException; import org.apache.thrift.TFieldIdEnum; import org.junit.jupiter.api.Test; public class ThriftStructProcessorTest { private PartialThriftTestData testData = new PartialThriftTestData(); @Test public void testStruct() throws TException { List fields = ThriftField.fromNames(Collections.singletonList("i32Field")); ThriftMetadata.ThriftStruct metadata = ThriftMetadata.ThriftStruct.fromFields(TestStruct.class, fields); ThriftStructProcessor processor = new ThriftStructProcessor(); Object instance = processor.createNewStruct(metadata); assertNotNull(instance); assertTrue(instance instanceof TBase); assertTrue(instance instanceof TestStruct); Object instance2 = processor.prepareStruct(instance); assertSame(instance, instance2); } @Test public void testList() throws TException { final int numItems = 10; ThriftStructProcessor processor = new ThriftStructProcessor(); Object instance = processor.createNewList(numItems); assertNotNull(instance); assertTrue(instance instanceof Object[]); Object[] items = (Object[]) instance; for (int i = 0; i < numItems; i++) { assertNull(items[i]); processor.setListElement(instance, i, Integer.valueOf(i)); assertEquals(i, items[i]); } assertTrue(processor.prepareList(instance) instanceof List); } @Test public void testMap() throws TException { final int numItems = 10; ThriftStructProcessor processor = new ThriftStructProcessor(); Object instance = processor.createNewMap(numItems); assertNotNull(instance); assertTrue(instance instanceof Map); Map items = (Map) instance; int ignoredIndex = -1; for (int i = 0; i < numItems; i++) { assertNull(items.get(i)); processor.setMapElement(instance, ignoredIndex, Integer.valueOf(i), Integer.valueOf(i)); assertEquals(i, items.get(i)); } assertTrue(processor.prepareMap(instance) instanceof Map); } @Test public void testSet() throws TException { final int numItems = 10; ThriftStructProcessor processor = new ThriftStructProcessor(); Object instance = processor.createNewSet(numItems); assertNotNull(instance); assertTrue(instance instanceof HashSet); Set items = (HashSet) instance; int ignoredIndex = -1; for (int i = 0; i < numItems; i++) { assertFalse(items.contains(i)); processor.setSetElement(instance, ignoredIndex, Integer.valueOf(i)); assertTrue(items.contains(i)); } assertTrue(processor.prepareSet(instance) instanceof Set); } @Test public void testPrepareEnum() throws TException { ThriftStructProcessor processor = new ThriftStructProcessor(); Object instance = processor.prepareEnum(TstEnum.class, 1); assertNotNull(instance); assertEquals(TstEnum.E_ONE, instance); instance = processor.prepareEnum(TstEnum.class, 2); assertNotNull(instance); assertEquals(TstEnum.E_TWO, instance); } @Test public void testPrepareString() throws TException { ThriftStructProcessor processor = new ThriftStructProcessor(); ByteBuffer emptyBuffer = ByteBuffer.wrap(new byte[0]); Object instance = processor.prepareString(emptyBuffer); assertNotNull(instance); assertTrue(instance instanceof String); assertEquals("", instance); String value = "Hello world!"; ByteBuffer buffer = ByteBuffer.wrap(value.getBytes(StandardCharsets.UTF_8)); instance = processor.prepareString(buffer); assertNotNull(instance); assertTrue(instance instanceof String); assertEquals(value, instance); } @Test public void testPrepareBinary() throws TException { ThriftStructProcessor processor = new ThriftStructProcessor(); ByteBuffer emptyBuffer = ByteBuffer.wrap(new byte[0]); Object instance = processor.prepareBinary(emptyBuffer); assertNotNull(instance); assertTrue(instance instanceof ByteBuffer); assertSame(emptyBuffer, instance); } @Test public void testStructPrimitiveFields() throws TException { List fields = ThriftField.fromNames( Arrays.asList( "byteField", "i16Field", "i32Field", "i64Field", "doubleField", "stringField", "enumField", "binaryField")); ThriftMetadata.ThriftStruct metadata = ThriftMetadata.ThriftStruct.fromFields(TestStruct.class, fields); ThriftStructProcessor processor = new ThriftStructProcessor(); Object instance = processor.createNewStruct(metadata); assertNotNull(instance); assertTrue(instance instanceof TBase); assertTrue(instance instanceof TestStruct); TestStruct struct = (TestStruct) instance; // byte TFieldIdEnum fieldId = findFieldId(metadata, "byteField"); assertNull(getFieldValue(struct, fieldId)); processor.setByte(struct, fieldId, (byte) 42); assertEquals(42, struct.getByteField()); // short fieldId = findFieldId(metadata, "i16Field"); assertNull(getFieldValue(struct, fieldId)); processor.setInt16(struct, fieldId, (short) 42); assertEquals(42, struct.getI16Field()); // int fieldId = findFieldId(metadata, "i32Field"); assertNull(getFieldValue(struct, fieldId)); processor.setInt32(struct, fieldId, 42); assertEquals(42, struct.getI32Field()); // long fieldId = findFieldId(metadata, "i64Field"); assertNull(getFieldValue(struct, fieldId)); processor.setInt64(struct, fieldId, 42L); assertEquals(42, struct.getI64Field()); // binary fieldId = findFieldId(metadata, "binaryField"); assertNull(getFieldValue(struct, fieldId)); byte[] noBytes = new byte[0]; ByteBuffer emptyBuffer = ByteBuffer.wrap(noBytes); processor.setBinary(struct, fieldId, emptyBuffer); assertArrayEquals(noBytes, struct.getBinaryField()); // string fieldId = findFieldId(metadata, "stringField"); assertNull(getFieldValue(struct, fieldId)); String value = "Hello world!"; ByteBuffer buffer = ByteBuffer.wrap(value.getBytes(StandardCharsets.UTF_8)); processor.setString(struct, fieldId, buffer); assertEquals(value, struct.getStringField()); // enum fieldId = findFieldId(metadata, "enumField"); assertNull(getFieldValue(struct, fieldId)); TstEnum e1 = TstEnum.E_ONE; processor.setEnumField(struct, fieldId, e1); assertEquals(TstEnum.E_ONE, struct.getEnumField()); } @Test public void testStructContainerFields() throws TException { List fields = ThriftField.fromNames( Arrays.asList( // List field "i32List", // Set field "stringSet", // Map field "stringMap", // Struct field "structField")); ThriftMetadata.ThriftStruct metadata = ThriftMetadata.ThriftStruct.fromFields(TestStruct.class, fields); ThriftStructProcessor processor = new ThriftStructProcessor(); Object instance = processor.createNewStruct(metadata); assertNotNull(instance); assertTrue(instance instanceof TBase); assertTrue(instance instanceof TestStruct); TestStruct struct = (TestStruct) instance; // list TFieldIdEnum fieldId = findFieldId(metadata, "i32List"); assertNull(getFieldValue(struct, fieldId)); Integer[] ints = new Integer[] {1, 2, 3}; List intList = Arrays.asList(ints); processor.setListField(struct, fieldId, intList); assertArrayEquals(ints, struct.getI32List().toArray()); // set fieldId = findFieldId(metadata, "stringSet"); assertNull(getFieldValue(struct, fieldId)); String[] strings = new String[] {"Hello", "World!"}; Set stringSet = new HashSet<>(Arrays.asList(strings)); processor.setSetField(struct, fieldId, stringSet); assertEquals(stringSet, struct.getStringSet()); // map fieldId = findFieldId(metadata, "stringMap"); assertNull(getFieldValue(struct, fieldId)); Map stringMap = new HashMap<>(); stringMap.put("foo", "bar"); stringMap.put("Hello", "World!"); processor.setMapField(struct, fieldId, stringMap); assertEquals(stringMap, struct.getStringMap()); // struct fieldId = findFieldId(metadata, "structField"); assertNull(getFieldValue(struct, fieldId)); SmallStruct smallStruct = new SmallStruct(); smallStruct.setI32Field(42); SmallStruct smallStruct2 = new SmallStruct(); smallStruct2.setI32Field(42); processor.setStructField(struct, fieldId, smallStruct); assertEquals(smallStruct2, struct.getStructField()); } private TFieldIdEnum findFieldId(ThriftMetadata.ThriftStruct metadata, String fieldName) { Collection fields = metadata.fields.values(); for (ThriftMetadata.ThriftObject field : fields) { if (fieldName.equalsIgnoreCase(field.fieldId.getFieldName())) { return field.fieldId; } } throw new IllegalStateException("Field not found: " + fieldName); } private Object getFieldValue(TBase struct, TFieldIdEnum fieldId) { TFieldIdEnum fieldRef = struct.fieldForId(fieldId.getThriftFieldId()); if (struct.isSet(fieldRef)) { return struct.getFieldValue(fieldRef); } else { return null; } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/EnumCacheTest.java0000664000175000017500000000570015165535636030054 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import org.apache.thrift.TEnum; import org.junit.jupiter.api.Test; /** Test ThriftCodec serializes and deserializes thrift objects correctly. */ public class EnumCacheTest { enum TestEnum implements TEnum { Alice(-1), Bob(0), Charlie(1); private int value; TestEnum(int value) { this.value = value; } @Override public int getValue() { return this.value; } } static class NotEnum implements TEnum { public static final NotEnum Alice = new NotEnum(-11); public static final NotEnum Bob = new NotEnum(10); public static final NotEnum Charlie = new NotEnum(11); private static final NotEnum[] allValues = {Alice, Bob, Charlie}; private int value; private NotEnum(int value) { this.value = value; } public static TEnum[] values() { return NotEnum.allValues; } @Override public int getValue() { return this.value; } @Override public String toString() { return String.format("NotEnum : %d", this.value); } } @Test public void testArgChecks() { EnumCache cache = new EnumCache(); // Should not throw. cache.get(TestEnum.class, 0); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> cache.get(null, 1), "'enumClass' must not be null"); } @Test public void testGet() { EnumCache cache = new EnumCache(); assertEquals(TestEnum.Alice, cache.get(TestEnum.class, -1)); assertEquals(TestEnum.Bob, cache.get(TestEnum.class, 0)); assertEquals(TestEnum.Charlie, cache.get(TestEnum.class, 1)); assertEquals(NotEnum.Alice, cache.get(NotEnum.class, -11)); assertEquals(NotEnum.Bob, cache.get(NotEnum.class, 10)); assertEquals(NotEnum.Charlie, cache.get(NotEnum.class, 11)); } @Test public void testGetInvalid() { EnumCache cache = new EnumCache(); assertNull(cache.get(TestEnum.class, 42)); assertNull(cache.get(NotEnum.class, 42)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/PartialThriftTestData.java0000664000175000017500000002300615165535636031572 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** Helpers for creating test data related to partial deserialization. */ public class PartialThriftTestData { public final byte[] BYTES = new byte[] {1, 2, 3}; public SmallStruct createSmallStruct(int id) { return new SmallStruct() .setByteField((byte) id) .setI16Field((short) id) .setI32Field(id) .setI64Field(id) .setDoubleField(id) .setStringField(Integer.toString(id)) .setEnumField(TstEnum.E_ONE); } public TestStruct createTestStruct(int id, int numItems) { TestStruct ts = new TestStruct() .setByteField((byte) id) .setI16Field((short) id) .setI32Field(id) .setI64Field(id) .setDoubleField(id) .setStringField(Integer.toString(id)) .setEnumField(TstEnum.E_ONE) .setBinaryField(BYTES) .setStructField(createSmallStruct(id)); initListFields(ts, id, numItems); initSetFields(ts, id, numItems); initMapFields(ts, id, numItems); return ts; } public void initListFields(TestStruct ts, int id, int numItems) { List byteList = new ArrayList<>(numItems); List i16List = new ArrayList<>(numItems); List i32List = new ArrayList<>(numItems); List i64List = new ArrayList<>(numItems); List doubleList = new ArrayList<>(numItems); List stringList = new ArrayList<>(numItems); List enumList = new ArrayList<>(numItems); List> listList = new ArrayList<>(numItems); List> setList = new ArrayList<>(numItems); List> mapList = new ArrayList<>(numItems); List structList = new ArrayList<>(numItems); List binaryList = new ArrayList<>(numItems); for (int i = 0; i < numItems; i++) { byteList.add((byte) i); i16List.add((short) i); i32List.add(i); i64List.add((long) i); doubleList.add((double) i); stringList.add(Integer.toString(i)); enumList.add(TstEnum.E_ONE); structList.add(createSmallStruct(i)); binaryList.add(ByteBuffer.wrap(BYTES)); List listItem = new ArrayList<>(numItems); listList.add(listItem); Set setItem = new HashSet<>(); setList.add(setItem); Map mapItem = new HashMap<>(); mapList.add(mapItem); for (int j = 0; j < numItems; j++) { listItem.add(j); setItem.add(j); mapItem.put(Integer.toString(j), j); } } ts.setByteList(byteList) .setI16List(i16List) .setI32List(i32List) .setI64List(i64List) .setDoubleList(doubleList) .setStringList(stringList) .setEnumList(enumList) .setListList(listList) .setSetList(setList) .setMapList(mapList) .setStructList(structList) .setBinaryList(binaryList); } public void initSetFields(TestStruct ts, int id, int numItems) { Set byteSet = new HashSet<>(); Set i16Set = new HashSet<>(); Set i32Set = new HashSet<>(); Set i64Set = new HashSet<>(); Set doubleSet = new HashSet<>(); Set stringSet = new HashSet<>(); Set enumSet = new HashSet<>(); Set> listSet = new HashSet<>(); Set> setSet = new HashSet<>(); Set> mapSet = new HashSet<>(); Set structSet = new HashSet<>(); Set binarySet = new HashSet<>(); for (int i = 0; i < numItems; i++) { byteSet.add((byte) i); i16Set.add((short) i); i32Set.add(i); i64Set.add((long) i); doubleSet.add((double) i); stringSet.add(Integer.toString(i)); enumSet.add(TstEnum.E_ONE); structSet.add(createSmallStruct(i)); binarySet.add(ByteBuffer.wrap(BYTES)); List listItem = new ArrayList<>(numItems); Set setItem = new HashSet<>(); Map mapItem = new HashMap<>(); for (int j = 0; j < numItems; j++) { setItem.add(j); listItem.add(j); mapItem.put(Integer.toString(j), j); } listSet.add(listItem); setSet.add(setItem); mapSet.add(mapItem); } ts.setByteSet(byteSet) .setI16Set(i16Set) .setI32Set(i32Set) .setI64Set(i64Set) .setDoubleSet(doubleSet) .setStringSet(stringSet) .setEnumSet(enumSet) .setListSet(listSet) .setSetSet(setSet) .setMapSet(mapSet) .setStructSet(structSet) .setBinarySet(binarySet); } public void initMapFields(TestStruct ts, int id, int numItems) { Map byteMap = new HashMap<>(); Map i16Map = new HashMap<>(); Map i32Map = new HashMap<>(); Map i64Map = new HashMap<>(); Map doubleMap = new HashMap<>(); Map stringMap = new HashMap<>(); Map enumMap = new HashMap<>(); Map> listMap = new HashMap<>(); Map> setMap = new HashMap<>(); Map> mapMap = new HashMap<>(); Map structMap = new HashMap<>(); Map binaryMap = new HashMap<>(); for (int i = 0; i < numItems; i++) { byteMap.put((byte) i, (byte) i); i16Map.put((short) i, (short) i); i32Map.put(i, i); i64Map.put((long) i, (long) i); doubleMap.put((double) i, (double) i); stringMap.put(Integer.toString(i), Integer.toString(i)); enumMap.put(TstEnum.E_ONE, TstEnum.E_ONE); structMap.put(createSmallStruct(i), createSmallStruct(i)); binaryMap.put(i, ByteBuffer.wrap(BYTES)); List listItem = new ArrayList<>(numItems); listMap.put(i, listItem); Set setItem = new HashSet<>(); setMap.put(i, setItem); Map mapItem = new HashMap<>(); mapMap.put(i, mapItem); for (int j = 0; j < numItems; j++) { listItem.add(j); setItem.add(j); mapItem.put(j, j); } } ts.setByteMap(byteMap) .setI16Map(i16Map) .setI32Map(i32Map) .setI64Map(i64Map) .setDoubleMap(doubleMap) .setStringMap(stringMap) .setEnumMap(enumMap) .setListMap(listMap) .setSetMap(setMap) .setMapMap(mapMap) .setStructMap(structMap) .setBinaryMap(binaryMap); } public List allFieldsOfTestStruct() { return new ArrayList<>( Arrays.asList( "byteField", "i16Field", "i32Field", "i64Field", "doubleField", "stringField", "structField.byteField", "structField.i16Field", "structField.i32Field", "structField.i64Field", "structField.doubleField", "structField.stringField", "structField.enumField", "enumField", "binaryField", "byteList", "i16List", "i32List", "i64List", "doubleList", "stringList", "enumList", "listList", "setList", "mapList", "structList.byteField", "structList.i16Field", "structList.i32Field", "structList.i64Field", "structList.doubleField", "structList.stringField", "structList.enumField", "binaryList", "byteSet", "i16Set", "i32Set", "i64Set", "doubleSet", "stringSet", "enumSet", "listSet", "setSet", "mapSet", "structSet.byteField", "structSet.i16Field", "structSet.i32Field", "structSet.i64Field", "structSet.doubleField", "structSet.stringField", "structSet.enumField", "binarySet", "byteMap", "i16Map", "i32Map", "i64Map", "doubleMap", "stringMap", "enumMap", "listMap", "setMap", "mapMap", "structMap.byteField", "structMap.i16Field", "structMap.i32Field", "structMap.i64Field", "structMap.doubleField", "structMap.stringField", "structMap.enumField", "binaryMap")); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/TestPartialThriftDeserializer.java0000664000175000017500000004511415165535636033347 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.junit.jupiter.api.Test; public class TestPartialThriftDeserializer { private ThriftSerDe serde = new ThriftSerDe(); private TBinaryProtocol.Factory binaryProtocolFactory = new TBinaryProtocol.Factory(); private TCompactProtocol.Factory compactProtocolFactory = new TCompactProtocol.Factory(); private PartialThriftTestData testData = new PartialThriftTestData(); public TestPartialThriftDeserializer() throws TException {} @Test public void testArgChecks() throws TException { // Should not throw. List fieldNames = Collections.singletonList("i32Field"); new TDeserializer(TestStruct.class, fieldNames, binaryProtocolFactory); // Verify it throws correctly. assertThrows( IllegalArgumentException.class, () -> new TDeserializer(null, fieldNames, binaryProtocolFactory), "'thriftClass' must not be null"); assertThrows( IllegalArgumentException.class, () -> new TDeserializer(TestStruct.class, null, binaryProtocolFactory), "'fieldNames' must not be null"); assertThrows( IllegalArgumentException.class, () -> new TDeserializer(TestStruct.class, fieldNames, null, binaryProtocolFactory), "'processor' must not be null"); } /** * This test does not use partial deserialization. It is used to establish correctness of full * serialization used in the other tests. */ @Test public void testRoundTripFull() throws TException { TestStruct ts1 = testData.createTestStruct(1, 2); byte[] bytesBinary = serde.serializeBinary(ts1); byte[] bytesCompact = serde.serializeCompact(ts1); TestStruct ts2 = serde.deserializeBinary(bytesBinary, TestStruct.class); assertEquals(ts1, ts2); ts2 = serde.deserializeCompact(bytesCompact, TestStruct.class); assertEquals(ts1, ts2); } @Test public void testPartialSimpleField() throws TException, IOException { TestStruct ts1 = testData.createTestStruct(1, 1); assertTrue(ts1.isSetI16Field()); assertTrue(ts1.isSetI32Field()); byte[] bytesBinary = serde.serializeBinary(ts1); byte[] bytesCompact = serde.serializeCompact(ts1); List fieldNames = Arrays.asList("i32Field"); TDeserializer partialBinaryDeserializer = new TDeserializer(TestStruct.class, fieldNames, binaryProtocolFactory); TDeserializer partialCompactDeserializer = new TDeserializer(TestStruct.class, fieldNames, compactProtocolFactory); PartialThriftComparer comparer = new PartialThriftComparer(partialBinaryDeserializer.getMetadata()); StringBuilder sb = new StringBuilder(); TestStruct ts2 = (TestStruct) partialBinaryDeserializer.partialDeserializeObject(bytesBinary); validatePartialSimpleField(ts1, ts2); assertTrue(comparer.areEqual(ts1, ts2, sb), sb::toString); ts2 = (TestStruct) partialCompactDeserializer.partialDeserializeObject(bytesCompact); validatePartialSimpleField(ts1, ts2); assertTrue(comparer.areEqual(ts1, ts2, sb), sb::toString); } private void validatePartialSimpleField(TestStruct ts1, TestStruct ts2) { assertTrue(ts2.isSetI32Field(), ts2.toString()); assertEquals(ts1.getI32Field(), ts2.getI32Field()); assertFalse(ts2.isSetI16Field()); } @Test public void testPartialComplex() throws TException { int id = 1; int numItems = 10; TestStruct ts1 = testData.createTestStruct(id, numItems); byte[] bytesBinary = serde.serializeBinary(ts1); byte[] bytesCompact = serde.serializeCompact(ts1); List fieldNames = Arrays.asList( "byteField", "i16Field", "i32Field", "i64Field", "doubleField", "stringField", "enumField", "binaryField", // List fields "byteList", "i16List", "i32List", "i64List", "doubleList", "stringList", "enumList", "listList", "setList", "mapList", "structList", "binaryList", // Set fields "byteSet", "i16Set", "i32Set", "i64Set", "doubleSet", "stringSet", "enumSet", "listSet", "setSet", "mapSet", "structSet", "binarySet", // Map fields "byteMap", "i16Map", "i32Map", "i64Map", "doubleMap", "stringMap", "enumMap", "listMap", "setMap", "mapMap", "structMap", "binaryMap", // Struct field "structField"); StringBuilder sb = new StringBuilder(); TDeserializer partialBinaryDeserializer = new TDeserializer(TestStruct.class, fieldNames, binaryProtocolFactory); TDeserializer partialCompactDeserializer = new TDeserializer(TestStruct.class, fieldNames, compactProtocolFactory); PartialThriftComparer comparer = new PartialThriftComparer(partialBinaryDeserializer.getMetadata()); TestStruct ts2 = (TestStruct) partialBinaryDeserializer.partialDeserializeObject(bytesBinary); validatePartialComplex(ts1, ts2, id, numItems); assertTrue(comparer.areEqual(ts1, ts2, sb), sb::toString); ts2 = (TestStruct) partialCompactDeserializer.partialDeserializeObject(bytesCompact); validatePartialComplex(ts1, ts2, id, numItems); assertTrue(comparer.areEqual(ts1, ts2, sb), sb::toString); } private void validatePartialComplex(TestStruct ts1, TestStruct ts2, int id, int numItems) { // Validate primitive fields. assertTrue(ts2.isSetByteField(), ts2.toString()); assertEquals(ts1.getByteField(), ts2.getByteField()); assertTrue(ts2.isSetI16Field()); assertEquals(ts1.getI16Field(), ts2.getI16Field()); assertTrue(ts2.isSetI32Field()); assertEquals(ts1.getI32Field(), ts2.getI32Field()); assertTrue(ts2.isSetI64Field()); assertEquals(ts1.getI64Field(), ts2.getI64Field()); assertTrue(ts2.isSetDoubleField()); assertEquals(ts1.getDoubleField(), ts2.getDoubleField(), 0.0001); assertTrue(ts2.isSetStringField()); assertEquals(ts1.getStringField(), ts2.getStringField()); assertTrue(ts2.isSetEnumField()); assertEquals(ts1.getEnumField(), ts2.getEnumField()); assertTrue(ts2.isSetBinaryField()); assertArrayEquals(ts1.getBinaryField(), ts2.getBinaryField()); // Validate list fields. validateList(ts2.getByteList(), id, numItems); validateList(ts2.getI16List(), id, numItems); validateList(ts2.getI32List(), id, numItems); validateList(ts2.getI64List(), id, numItems); validateList(ts2.getDoubleList(), id, numItems); validateStringList(ts2.getStringList(), id, numItems); validateEnumList(ts2.getEnumList(), id, numItems); validateListOfList(ts2.getListList(), id, numItems); validateListOfSet(ts2.getSetList(), id, numItems); validateListOfMap(ts2.getMapList(), id, numItems); validateListOfStruct(ts2.getStructList(), id, numItems); validateListOfBinary(ts2.getBinaryList(), id, numItems); // Validate set fields. validateSet(ts2.getByteSet(), Byte.class, numItems); validateSet(ts2.getI16Set(), Short.class, numItems); validateSet(ts2.getI32Set(), Integer.class, numItems); validateSet(ts2.getI64Set(), Long.class, numItems); validateSet(ts2.getDoubleSet(), Double.class, numItems); validateStringSet(ts2.getStringSet(), id, numItems); validateEnumSet(ts2.getEnumSet(), id, numItems); validateSetOfList(ts2.getListSet(), id, numItems); validateSetOfSet(ts2.getSetSet(), id, numItems); validateSetOfMap(ts2.getMapSet(), id, numItems); validateSetOfStruct(ts2.getStructSet(), id, numItems); validateSetOfBinary(ts2.getBinarySet(), id, numItems); // Validate map fields. validateMap(ts2.getByteMap(), Byte.class, numItems); validateMap(ts2.getI16Map(), Short.class, numItems); validateMap(ts2.getI32Map(), Integer.class, numItems); validateMap(ts2.getI64Map(), Long.class, numItems); validateMap(ts2.getDoubleMap(), Double.class, numItems); validateStringMap(ts2.getStringMap(), id, numItems); validateEnumMap(ts2.getEnumMap(), id, numItems); validateMapOfList(ts2.getListMap(), id, numItems); validateMapOfSet(ts2.getSetMap(), id, numItems); validateMapOfMap(ts2.getMapMap(), id, numItems); validateMapOfStruct(ts2.getStructMap(), id, numItems); validateMapOfBinary(ts2.getBinaryMap(), id, numItems); // Validate struct field. assertEquals(testData.createSmallStruct(id), ts2.getStructField()); } private void validateNotNullAndNotEmpty(Collection collection, int numItems) { assertNotNull(collection); assertEquals(numItems, collection.size()); } // ---------------------------------------------------------------------- // List validation helpers. private void validateList(List list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { assertEquals(i, list.get(i).longValue()); } } private void validateStringList(List list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { assertEquals(Integer.valueOf(i), Integer.valueOf(list.get(i))); } } private void validateEnumList(List list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { assertEquals(TstEnum.E_ONE, list.get(i)); } } private void validateListOfList(List> list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { validateList(list.get(i), id, numItems); } } private void validateListOfSet(List> list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { Set set = list.get(i); for (int j = 0; j < numItems; j++) { assertTrue(set.contains(j)); } } } private void validateListOfMap( List> list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { Map map = list.get(i); for (int j = 0; j < numItems; j++) { String key = Integer.toString(j); assertTrue(map.containsKey(key)); assertEquals(j, map.get(key)); } } } private void validateListOfStruct(List list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { SmallStruct ss = testData.createSmallStruct(i); for (int j = 0; j < numItems; j++) { assertEquals(ss, list.get(i)); } } } private void validateListOfBinary(List list, int id, int numItems) { validateNotNullAndNotEmpty(list, numItems); for (int i = 0; i < numItems; i++) { ByteBuffer bb = ByteBuffer.wrap(testData.BYTES); assertEquals(0, bb.compareTo(list.get(i))); } } // ---------------------------------------------------------------------- // Set validation helpers. private void validateSet(Set set, Class clasz, int numItems) { validateNotNullAndNotEmpty(set, numItems); for (int i = 0; i < numItems; i++) { if (clasz == Byte.class) { assertTrue(set.contains((byte) i)); } else if (clasz == Short.class) { assertTrue(set.contains((short) i)); } else if (clasz == Integer.class) { assertTrue(set.contains(i)); } else if (clasz == Long.class) { assertTrue(set.contains((long) i)); } else if (clasz == Double.class) { assertTrue(set.contains((double) i)); } } } private void validateStringSet(Set set, int id, int numItems) { validateNotNullAndNotEmpty(set, numItems); for (int i = 0; i < numItems; i++) { assertTrue(set.contains(Integer.toString(i))); } } private void validateEnumSet(Set set, int id, int numItems) { validateNotNullAndNotEmpty(set, 1); assertTrue(set.contains(TstEnum.E_ONE)); } private void validateSetOfList(Set> set, int id, int numItems) { validateNotNullAndNotEmpty(set, 1); List list = new ArrayList<>(numItems); for (int i = 0; i < numItems; i++) { list.add(i); } assertTrue(set.contains(list)); } private void validateSetOfSet(Set> set, int id, int numItems) { validateNotNullAndNotEmpty(set, 1); Set setElt = new HashSet<>(); for (int i = 0; i < numItems; i++) { setElt.add(i); } assertTrue(set.contains(setElt)); } private void validateSetOfMap(Set> set, int id, int numItems) { validateNotNullAndNotEmpty(set, 1); Map map = new HashMap<>(); for (int i = 0; i < numItems; i++) { map.put(Integer.toString(i), i); } assertTrue(set.contains(map)); } private void validateSetOfStruct(Set set, int id, int numItems) { validateNotNullAndNotEmpty(set, numItems); for (int i = 0; i < numItems; i++) { SmallStruct ss = testData.createSmallStruct(i); assertTrue(set.contains(ss)); } } private void validateSetOfBinary(Set set, int id, int numItems) { validateNotNullAndNotEmpty(set, 1); for (ByteBuffer b : set) { ByteBuffer bb = ByteBuffer.wrap(testData.BYTES); assertEquals(0, bb.compareTo(b)); } } // ---------------------------------------------------------------------- // Map validation helpers. void validateNotNullAndNotEmpty(Map map, int numItems) { assertNotNull(map); assertEquals(numItems, map.size()); } private void validateMap(Map map, Class clasz, int numItems) { validateNotNullAndNotEmpty(map, numItems); for (int i = 0; i < numItems; i++) { if (clasz == Byte.class) { assertTrue(map.containsKey((byte) i)); assertEquals((byte) i, map.get((byte) i)); } else if (clasz == Short.class) { assertTrue(map.containsKey((short) i)); assertEquals((short) i, map.get((short) i)); } else if (clasz == Integer.class) { assertTrue(map.containsKey(i)); assertEquals(i, map.get(i)); } else if (clasz == Long.class) { assertTrue(map.containsKey((long) i)); assertEquals((long) i, map.get((long) i)); } else if (clasz == Double.class) { assertTrue(map.containsKey((double) i)); assertEquals((double) i, map.get((double) i)); } } } private void validateStringMap(Map map, int id, int numItems) { validateNotNullAndNotEmpty(map, numItems); for (int i = 0; i < numItems; i++) { String key = Integer.toString(i); assertTrue(map.containsKey(key)); assertEquals(key, map.get(key)); } } private void validateEnumMap(Map map, int id, int numItems) { validateNotNullAndNotEmpty(map, 1); assertTrue(map.containsKey(TstEnum.E_ONE)); assertEquals(TstEnum.E_ONE, map.get(TstEnum.E_ONE)); } private void validateMapOfList(Map> map, int id, int numItems) { validateNotNullAndNotEmpty(map, numItems); List list = new ArrayList<>(numItems); for (int i = 0; i < numItems; i++) { list.add(i); } for (int i = 0; i < numItems; i++) { assertTrue(map.containsKey(i)); assertEquals(list, map.get(i)); } } private void validateMapOfSet(Map> map, int id, int numItems) { validateNotNullAndNotEmpty(map, numItems); Set setElt = new HashSet<>(); for (int i = 0; i < numItems; i++) { setElt.add(i); } for (int i = 0; i < numItems; i++) { assertTrue(map.containsKey(i)); assertEquals(setElt, map.get(i)); } } private void validateMapOfMap(Map> map, int id, int numItems) { validateNotNullAndNotEmpty(map, numItems); Map mapElt = new HashMap<>(); for (int i = 0; i < numItems; i++) { mapElt.put(i, i); } for (int i = 0; i < numItems; i++) { assertTrue(map.containsKey(i)); assertEquals(mapElt, map.get(i)); } } private void validateMapOfStruct(Map map, int id, int numItems) { validateNotNullAndNotEmpty(map, numItems); for (int i = 0; i < numItems; i++) { SmallStruct ss = testData.createSmallStruct(i); assertTrue(map.containsKey(ss)); assertEquals(ss, map.get(ss)); } } private void validateMapOfBinary(Map map, int id, int numItems) { validateNotNullAndNotEmpty(map, numItems); for (int i = 0; i < numItems; i++) { ByteBuffer bb = ByteBuffer.wrap(testData.BYTES); assertTrue(map.containsKey(i)); assertEquals(0, bb.compareTo(map.get(i))); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/ValidateTest.java0000664000175000017500000002341615165535636027761 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import org.junit.jupiter.api.Test; public class ValidateTest { @Test public void testCheckNotNull() { String nonNullArg = "nonNullArg"; String nullArg = null; // Should not throw. Validate.checkNotNull(nonNullArg, "nonNullArg"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNull(nullArg, "nullArg"), "'nullArg' must not be null"); } @Test public void testCheckPositiveInteger() { int positiveArg = 1; int zero = 0; int negativeArg = -1; // Should not throw. Validate.checkPositiveInteger(positiveArg, "positiveArg"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkPositiveInteger(negativeArg, "negativeArg"), "'negativeArg' must be a positive integer"); assertThrows( IllegalArgumentException.class, () -> Validate.checkPositiveInteger(zero, "zero"), "'zero' must be a positive integer"); } @Test public void testCheckNotNegative() { int positiveArg = 1; int zero = 0; int negativeArg = -1; // Should not throw. Validate.checkNotNegative(zero, "zeroArg"); Validate.checkNotNegative(positiveArg, "positiveArg"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNegative(negativeArg, "negativeArg"), "'negativeArg' must not be negative"); } @Test public void testCheckRequired() { // Should not throw. Validate.checkRequired(true, "arg"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkRequired(false, "arg"), "'arg' is required"); } @Test public void testCheckValid() { // Should not throw. Validate.checkValid(true, "arg"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkValid(false, "arg"), "'arg' is invalid"); } @Test public void testCheckValidWithValues() { String validValues = "foo, bar"; // Should not throw. Validate.checkValid(true, "arg", validValues); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkValid(false, "arg", validValues), "'arg' is invalid. Valid values are: foo, bar"); } @Test public void testCheckNotNullAndNotEmpty() { // Should not throw. Validate.checkNotNullAndNotEmpty(TestData.nonEmptyArray, "array"); Validate.checkNotNullAndNotEmpty(TestData.nonEmptyByteArray, "array"); Validate.checkNotNullAndNotEmpty(TestData.nonEmptyShortArray, "array"); Validate.checkNotNullAndNotEmpty(TestData.nonEmptyIntArray, "array"); Validate.checkNotNullAndNotEmpty(TestData.nonEmptyLongArray, "array"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty("", "string"), "'string' must not be empty"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.nullArray, "array"), "'array' must not be null"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.emptyArray, "array"), "'array' must have at least one element"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.nullByteArray, "array"), "'array' must not be null"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.emptyByteArray, "array"), "'array' must have at least one element"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.nullShortArray, "array"), "'array' must not be null"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.emptyShortArray, "array"), "'array' must have at least one element"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.nullIntArray, "array"), "'array' must not be null"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.emptyIntArray, "array"), "'array' must have at least one element"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.nullLongArray, "array"), "'array' must not be null"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.emptyLongArray, "array"), "'array' must have at least one element"); } @Test public void testCheckListNotNullAndNotEmpty() { // Should not throw. Validate.checkNotNullAndNotEmpty(TestData.validList, "list"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.nullList, "list"), "'list' must not be null"); assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNotEmpty(TestData.emptyList, "list"), "'list' must have at least one element"); } @Test public void testCheckNotNullAndNumberOfElements() { // Should not throw. Validate.checkNotNullAndNumberOfElements(Arrays.asList(1, 2, 3), 3, "arg"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNumberOfElements(null, 3, "arg"), "'arg' must not be null"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkNotNullAndNumberOfElements(Arrays.asList(1, 2), 3, "arg"), "Number of elements in 'arg' must be exactly 3, 2 given."); } @Test public void testCheckValuesEqual() { // Should not throw. Validate.checkValuesEqual(1, "arg1", 1, "arg2"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkValuesEqual(1, "arg1", 2, "arg2"), "'arg1' (1) must equal 'arg2' (2)"); } @Test public void testCheckIntegerMultiple() { // Should not throw. Validate.checkIntegerMultiple(10, "arg1", 5, "arg2"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkIntegerMultiple(10, "arg1", 3, "arg2"), "'arg1' (10) must be an integer multiple of 'arg2' (3)"); } @Test public void testCheckGreater() { // Should not throw. Validate.checkGreater(10, "arg1", 5, "arg2"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkGreater(5, "arg1", 10, "arg2"), "'arg1' (5) must be greater than 'arg2' (10)"); } @Test public void testCheckGreaterOrEqual() { // Should not throw. Validate.checkGreaterOrEqual(10, "arg1", 5, "arg2"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkGreaterOrEqual(5, "arg1", 10, "arg2"), "'arg1' (5) must be greater than or equal to 'arg2' (10)"); } @Test public void testCheckWithinRange() { // Should not throw. Validate.checkWithinRange(10, "arg", 5, 15); Validate.checkWithinRange(10.0, "arg", 5.0, 15.0); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkWithinRange(5, "arg", 10, 20), "'arg' (5) must be within the range [10, 20]"); assertThrows( IllegalArgumentException.class, () -> Validate.checkWithinRange(5.0, "arg", 10.0, 20.0), "'arg' (5.0) must be within the range [10.0, 20.0]"); } @Test public void testCheckPathExists() throws IOException { Path tempFile = Files.createTempFile("foo", "bar"); Path tempDir = tempFile.getParent(); Path notFound = Paths.get(""); // Should not throw. Validate.checkPathExists(tempFile, "tempFile"); Validate.checkPathExists(tempDir, "tempDir"); // Verify it throws. assertThrows( IllegalArgumentException.class, () -> Validate.checkPathExists(null, "nullArg"), "'nullArg' must not be null"); assertThrows( IllegalArgumentException.class, () -> Validate.checkPathExists(notFound, "notFound"), "Path notFound () does not exist"); assertThrows( IllegalArgumentException.class, () -> Validate.checkPathExistsAsDir(tempFile, "tempFile"), "must point to a directory"); assertThrows( IllegalArgumentException.class, () -> Validate.checkPathExistsAsFile(tempDir, "tempDir"), "must point to a file"); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/TFieldDataTest.java0000664000175000017500000000323015165535636030161 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertEquals; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TType; import org.junit.jupiter.api.Test; public class TFieldDataTest { @Test public void testEncodeStop() { TField field = new TField("", TType.STOP, (short) 0); int data = TFieldData.encode(TType.STOP); assertEquals(field.type, TFieldData.getType(data)); assertEquals(field.id, TFieldData.getId(data)); } @Test public void testEncodeRest() { for (byte type = 1; type <= 16; type++) { for (short id = 0; id < Short.MAX_VALUE; id++) { TField field = new TField("", type, id); int data = TFieldData.encode(type, id); assertEquals(field.type, TFieldData.getType(data)); assertEquals(field.id, TFieldData.getId(data)); } } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/ThriftSerDe.java0000664000175000017500000000510315165535636027544 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import org.apache.thrift.TBase; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; public class ThriftSerDe { private TSerializer binarySerializer; private TSerializer compactSerializer; private TDeserializer binaryDeserializer; private TDeserializer compactDeserializer; public ThriftSerDe() throws TException { this.binarySerializer = new TSerializer(new TBinaryProtocol.Factory()); this.compactSerializer = new TSerializer(new TCompactProtocol.Factory()); this.binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory()); this.compactDeserializer = new TDeserializer(new TCompactProtocol.Factory()); } public byte[] serializeBinary(TBase obj) throws TException { return binarySerializer.serialize(obj); } public byte[] serializeCompact(TBase obj) throws TException { return compactSerializer.serialize(obj); } public T deserializeBinary(byte[] bytes, Class clazz) throws TException { T instance = this.newInstance(clazz); binaryDeserializer.deserialize(instance, bytes); return clazz.cast(instance); } public T deserializeCompact(byte[] bytes, Class clazz) throws TException { T instance = this.newInstance(clazz); compactDeserializer.deserialize(instance, bytes); return clazz.cast(instance); } private T newInstance(Class clazz) { T instance = null; try { instance = clazz.getDeclaredConstructor().newInstance(); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } return clazz.cast(instance); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/TestData.java0000664000175000017500000000370415165535636027077 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Frequently used test data items. */ public final class TestData { private TestData() {} // Array data. public static Object[] nullArray = null; public static Object[] emptyArray = new Object[0]; public static Object[] nonEmptyArray = new Object[1]; public static byte[] nullByteArray = null; public static byte[] emptyByteArray = new byte[0]; public static byte[] nonEmptyByteArray = new byte[1]; public static short[] nullShortArray = null; public static short[] emptyShortArray = new short[0]; public static short[] nonEmptyShortArray = new short[1]; public static int[] nullIntArray = null; public static int[] emptyIntArray = new int[0]; public static int[] nonEmptyIntArray = new int[1]; public static long[] nullLongArray = null; public static long[] emptyLongArray = new long[0]; public static long[] nonEmptyLongArray = new long[1]; public static List nullList = null; public static List emptyList = new ArrayList(); public static List validList = Arrays.asList(new Object[1]); } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/PartialThriftComparerTest.java0000664000175000017500000000500615165535636032471 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.util.Arrays; import java.util.List; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.junit.jupiter.api.Test; public class PartialThriftComparerTest { private ThriftSerDe serde; private PartialThriftTestData testData = new PartialThriftTestData(); public PartialThriftComparerTest() throws TException { this.serde = new ThriftSerDe(); } @Test public void testCompareSimple() throws TException, IOException { TestStruct ts1 = testData.createTestStruct(1, 1); assertTrue(ts1.isSetI16Field()); assertTrue(ts1.isSetI32Field()); byte[] bytesBinary = serde.serializeBinary(ts1); byte[] bytesCompact = serde.serializeCompact(ts1); List fieldNames = Arrays.asList("i32Field"); TDeserializer partialBinaryDeser = new TDeserializer(TestStruct.class, fieldNames, new TBinaryProtocol.Factory()); TDeserializer partialCompactDeser = new TDeserializer(TestStruct.class, fieldNames, new TCompactProtocol.Factory()); ThriftMetadata.ThriftStruct metadata = partialBinaryDeser.getMetadata(); PartialThriftComparer comparer = new PartialThriftComparer(metadata); StringBuilder sb = new StringBuilder(); TestStruct ts2 = (TestStruct) partialBinaryDeser.partialDeserializeObject(bytesBinary); assertTrue(comparer.areEqual(ts1, ts2, sb), sb::toString); ts2 = (TestStruct) partialCompactDeser.partialDeserializeObject(bytesCompact); assertTrue(comparer.areEqual(ts1, ts2, sb), sb::toString); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/partial/ThriftMetadataTest.java0000664000175000017500000002531215165535636031126 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.partial; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.List; import org.apache.thrift.TBase; import org.apache.thrift.meta_data.EnumMetaData; import org.apache.thrift.meta_data.FieldValueMetaData; import org.apache.thrift.meta_data.ListMetaData; import org.apache.thrift.meta_data.MapMetaData; import org.apache.thrift.meta_data.SetMetaData; import org.apache.thrift.meta_data.StructMetaData; import org.apache.thrift.protocol.TType; import org.junit.jupiter.api.Test; public class ThriftMetadataTest { private PartialThriftTestData testData = new PartialThriftTestData(); @Test public void testArgChecks() { // Should not throw. List testFields = ThriftField.fromNames(Arrays.asList("byteField")); ThriftMetadata.ThriftStruct.fromFields(TestStruct.class, testFields); // Verify it throws correctly. assertThrows( IllegalArgumentException.class, () -> ThriftMetadata.ThriftStruct.fromFields(null, testFields), "'clasz' must not be null"); assertThrows( IllegalArgumentException.class, () -> ThriftMetadata.ThriftStruct.fromFields(TestStruct.class, null), "'fields' must not be null"); } @Test public void testThriftStructOf() { ThriftMetadata.ThriftStruct testStruct = ThriftMetadata.ThriftStruct.of(TestStruct.class); assertEquals(45, testStruct.fields.keySet().size()); validateFieldMetadata(testStruct, 1, "byteField", TType.BYTE); validateFieldMetadata(testStruct, 2, "i16Field", TType.I16); validateFieldMetadata(testStruct, 3, "i32Field", TType.I32); validateFieldMetadata(testStruct, 4, "i64Field", TType.I64); validateFieldMetadata(testStruct, 5, "doubleField", TType.DOUBLE); validateFieldMetadata(testStruct, 6, "stringField", TType.STRING); validateFieldMetadata(testStruct, 7, "enumField", TType.ENUM); validateFieldMetadata(testStruct, 8, "binaryField", TType.STRING); validateListFieldMetadata(testStruct, 10, "byteList", TType.BYTE); validateSetFieldMetadata(testStruct, 35, "stringSet", TType.STRING); validateMapFieldMetadata(testStruct, 61, "binaryMap", TType.I32, TType.STRING); } @Test public void testUnion() { ThriftMetadata.ThriftStruct structWithUnions = ThriftMetadata.ThriftStruct.of(StructWithUnions.class); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 1, "intValue"); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 2, "smallStruct"); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 3, "simpleUnion"); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 4, "unionList"); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 5, "unionSet"); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 6, "keyUnionMap"); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 7, "valUnionMap"); validateBasicFieldMetadata(structWithUnions, StructWithUnions.class, 8, "unionMap"); ThriftMetadata.ThriftStructBase smallStructMetadata = (ThriftMetadata.ThriftStructBase) structWithUnions.fields.get(2); assertFalse(smallStructMetadata.isUnion()); ThriftMetadata.ThriftStructBase simpleUnionMetadata = (ThriftMetadata.ThriftStructBase) structWithUnions.fields.get(3); assertTrue(simpleUnionMetadata.isUnion()); ThriftMetadata.ThriftList unionListMetadata = (ThriftMetadata.ThriftList) structWithUnions.fields.get(4); assertTrue(unionListMetadata.hasUnion()); ThriftMetadata.ThriftSet unionSetMetadata = (ThriftMetadata.ThriftSet) structWithUnions.fields.get(5); assertTrue(unionSetMetadata.hasUnion()); ThriftMetadata.ThriftMap keyUnionMapMetadata = (ThriftMetadata.ThriftMap) structWithUnions.fields.get(6); assertTrue(keyUnionMapMetadata.hasUnion()); ThriftMetadata.ThriftMap valUnionMapMetadata = (ThriftMetadata.ThriftMap) structWithUnions.fields.get(7); assertTrue(valUnionMapMetadata.hasUnion()); ThriftMetadata.ThriftMap unionMapMetadata = (ThriftMetadata.ThriftMap) structWithUnions.fields.get(8); assertTrue(unionMapMetadata.hasUnion()); } private ThriftMetadata.ThriftObject validateBasicFieldMetadata( ThriftMetadata.ThriftStruct testStruct, int id, String fieldName) { return validateBasicFieldMetadata(testStruct, TestStruct.class, id, fieldName); } private ThriftMetadata.ThriftObject validateBasicFieldMetadata( ThriftMetadata.ThriftStruct testStruct, Class clazz, int id, String fieldName) { assertNotNull(testStruct); assertNull(testStruct.parent); assertEquals(clazz, ((StructMetaData) testStruct.data.valueMetaData).structClass); assertTrue(testStruct.fields.containsKey(id)); ThriftMetadata.ThriftObject fieldMetadata = (ThriftMetadata.ThriftObject) testStruct.fields.get(id); assertEquals(testStruct, fieldMetadata.parent); assertEquals(id, fieldMetadata.fieldId.getThriftFieldId()); assertEquals(fieldName, fieldMetadata.fieldId.getFieldName()); assertEquals(fieldName, fieldMetadata.data.fieldName); assertEquals("root ==> " + fieldName, fieldMetadata.toString()); return fieldMetadata; } private void validateBasicFieldValueMetadata( ThriftMetadata.ThriftObject fieldMetadata, String fieldName, byte ttype) { assertEquals(ttype, fieldMetadata.data.valueMetaData.type); assertEquals(getMetaDataClassForTType(ttype), fieldMetadata.data.valueMetaData.getClass()); Class fieldMetadataClass = getClassForTType(ttype); assertEquals(fieldMetadataClass, fieldMetadata.getClass()); if (fieldMetadataClass == ThriftMetadata.ThriftPrimitive.class) { ThriftMetadata.ThriftPrimitive primitive = (ThriftMetadata.ThriftPrimitive) fieldMetadata; if (fieldName.startsWith("binary") && (ttype == TType.STRING)) { assertTrue(primitive.isBinary()); } else { assertFalse(primitive.isBinary()); } } } private void validateFieldMetadata( ThriftMetadata.ThriftStruct testStruct, int id, String fieldName, byte ttype) { ThriftMetadata.ThriftObject fieldMetadata = validateBasicFieldMetadata(testStruct, id, fieldName); validateBasicFieldValueMetadata(fieldMetadata, fieldName, ttype); } private void validateListFieldMetadata( ThriftMetadata.ThriftStruct testStruct, int id, String fieldName, byte ttype) { ThriftMetadata.ThriftObject fieldMetadata = validateBasicFieldMetadata(testStruct, id, fieldName); validateBasicFieldValueMetadata(fieldMetadata, fieldName, TType.LIST); ThriftMetadata.ThriftList thriftList = (ThriftMetadata.ThriftList) fieldMetadata; ThriftMetadata.ThriftObject elementMetadata = thriftList.elementData; validateBasicFieldValueMetadata(elementMetadata, fieldName + "_element", ttype); } private void validateSetFieldMetadata( ThriftMetadata.ThriftStruct testStruct, int id, String fieldName, byte ttype) { ThriftMetadata.ThriftObject fieldMetadata = validateBasicFieldMetadata(testStruct, id, fieldName); validateBasicFieldValueMetadata(fieldMetadata, fieldName, TType.SET); ThriftMetadata.ThriftSet thriftSet = (ThriftMetadata.ThriftSet) fieldMetadata; ThriftMetadata.ThriftObject elementMetadata = thriftSet.elementData; validateBasicFieldValueMetadata(elementMetadata, fieldName + "_element", ttype); } private void validateMapFieldMetadata( ThriftMetadata.ThriftStruct testStruct, int id, String fieldName, byte keyType, byte valueType) { ThriftMetadata.ThriftObject fieldMetadata = validateBasicFieldMetadata(testStruct, id, fieldName); validateBasicFieldValueMetadata(fieldMetadata, fieldName, TType.MAP); ThriftMetadata.ThriftMap thriftMap = (ThriftMetadata.ThriftMap) fieldMetadata; ThriftMetadata.ThriftObject keyMetadata = thriftMap.keyData; ThriftMetadata.ThriftObject valueMetadata = thriftMap.valueData; validateBasicFieldValueMetadata(keyMetadata, fieldName + "_key", keyType); validateBasicFieldValueMetadata(valueMetadata, fieldName + "_value", valueType); } private Class getMetaDataClassForTType(byte ttype) { switch (ttype) { case TType.STRUCT: return StructMetaData.class; case TType.LIST: return ListMetaData.class; case TType.MAP: return MapMetaData.class; case TType.SET: return SetMetaData.class; case TType.ENUM: return EnumMetaData.class; case TType.BOOL: case TType.BYTE: case TType.I16: case TType.I32: case TType.I64: case TType.DOUBLE: case TType.STRING: return FieldValueMetaData.class; default: throw ThriftMetadata.unsupportedFieldTypeException(ttype); } } private Class getClassForTType(byte ttype) { switch (ttype) { case TType.STRUCT: return ThriftMetadata.ThriftStruct.class; case TType.LIST: return ThriftMetadata.ThriftList.class; case TType.MAP: return ThriftMetadata.ThriftMap.class; case TType.SET: return ThriftMetadata.ThriftSet.class; case TType.ENUM: return ThriftMetadata.ThriftEnum.class; case TType.BOOL: case TType.BYTE: case TType.I16: case TType.I32: case TType.I64: case TType.DOUBLE: case TType.STRING: return ThriftMetadata.ThriftPrimitive.class; default: throw ThriftMetadata.unsupportedFieldTypeException(ttype); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestEnumContainers.java0000664000175000017500000000636015165535636027525 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import org.junit.jupiter.api.Test; import thrift.test.enumcontainers.EnumContainersTestConstants; import thrift.test.enumcontainers.GodBean; import thrift.test.enumcontainers.GreekGodGoddess; public class TestEnumContainers { @Test public void testEnumContainers() throws Exception { final GodBean b1 = new GodBean(); b1.addToGoddess(GreekGodGoddess.HERA); b1.getGoddess().add(GreekGodGoddess.APHRODITE); b1.putToPower(GreekGodGoddess.ZEUS, 1000); b1.getPower().put(GreekGodGoddess.HERA, 333); b1.putToByAlias("Mr. Z", GreekGodGoddess.ZEUS); b1.addToImages("Baths of Aphrodite 01.jpeg"); final GodBean b2 = new GodBean(b1); final GodBean b3 = new GodBean(); { final TSerializer serializer = new TSerializer(); final TDeserializer deserializer = new TDeserializer(); final byte[] bytes = serializer.serialize(b1); deserializer.deserialize(b3, bytes); } assertNotSame(b1.getGoddess(), b2.getGoddess()); assertNotSame(b1.getPower(), b2.getPower()); assertNotSame(b1.getGoddess(), b3.getGoddess()); assertNotSame(b1.getPower(), b3.getPower()); for (GodBean each : new GodBean[] {b1, b2, b3}) { assertTrue(each.getGoddess().contains(GreekGodGoddess.HERA)); assertFalse(each.getGoddess().contains(GreekGodGoddess.POSEIDON)); assertTrue(each.getGoddess() instanceof EnumSet); assertEquals(Integer.valueOf(1000), each.getPower().get(GreekGodGoddess.ZEUS)); assertEquals(Integer.valueOf(333), each.getPower().get(GreekGodGoddess.HERA)); assertTrue(each.getPower() instanceof EnumMap); assertTrue(each.getByAlias() instanceof HashMap); assertTrue(each.getImages() instanceof HashSet); } } @Test public void testEnumConstants() { assertEquals( "lightning bolt", EnumContainersTestConstants.ATTRIBUTES.get(GreekGodGoddess.ZEUS)); assertTrue(EnumContainersTestConstants.ATTRIBUTES instanceof EnumMap); assertTrue(EnumContainersTestConstants.BEAUTY.contains(GreekGodGoddess.APHRODITE)); assertTrue(EnumContainersTestConstants.BEAUTY instanceof EnumSet); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/0000775000175000017500000000000015167543515024721 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java0000664000175000017500000001503115165535636032220 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.nio.charset.StandardCharsets; import org.apache.thrift.Fixtures; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TTransportException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import thrift.test.CompactProtoTestStruct; import thrift.test.HolyMoley; public class TestTSimpleJSONProtocol { private TMemoryBuffer buf; private TSimpleJSONProtocol proto; @BeforeEach public void setUp() throws Exception { buf = new TMemoryBuffer(1000); proto = new TSimpleJSONProtocol(buf); } private String bufToString() { return buf.toString(StandardCharsets.UTF_8); } @Test public void testHolyMoley() throws TException { final HolyMoley holyMoley = Fixtures.getHolyMoley().deepCopy(); // unset sets that produce inconsistent ordering between JDK7/8 holyMoley.unsetBonks(); holyMoley.unsetContain(); holyMoley.write(proto); assertEquals( "{\"big\":[{\"im_true\":1,\"im_false\":0,\"a_bite\":35,\"integer16\":27000,\"integer32\":16777216,\"integer64\":6000000000,\"double_precision\":3.141592653589793,\"some_characters\":\"JSON THIS! \\\"\\u0001\",\"zomg_unicode\":\"ӀⅮΠÐοⅿоɡгаÏℎ Αttαⅽκ�‼\",\"what_who\":0,\"base64\":\"base64\",\"byte_list\":[1,2,3],\"i16_list\":[1,2,3],\"i64_list\":[1,2,3]},{\"im_true\":1,\"im_false\":0,\"a_bite\":-42,\"integer16\":27000,\"integer32\":16777216,\"integer64\":6000000000,\"double_precision\":3.141592653589793,\"some_characters\":\"JSON THIS! \\\"\\u0001\",\"zomg_unicode\":\"ӀⅮΠÐοⅿоɡгаÏℎ Αttαⅽκ�‼\",\"what_who\":0,\"base64\":\"base64\",\"byte_list\":[1,2,3],\"i16_list\":[1,2,3],\"i64_list\":[1,2,3]}]}", bufToString()); } @Test public void testNesting() throws TException { Fixtures.getNesting().write(proto); assertEquals( "{\"my_bonk\":{\"type\":31337,\"message\":\"I am a bonk... xor!\"},\"my_ooe\":{\"im_true\":1,\"im_false\":0,\"a_bite\":-42,\"integer16\":27000,\"integer32\":16777216,\"integer64\":6000000000,\"double_precision\":3.141592653589793,\"some_characters\":\"JSON THIS! \\\"\\u0001\",\"zomg_unicode\":\"ӀⅮΠÐοⅿоɡгаÏℎ Αttαⅽκ�‼\",\"what_who\":0,\"base64\":\"base64\",\"byte_list\":[1,2,3],\"i16_list\":[1,2,3],\"i64_list\":[1,2,3]}}", bufToString()); } @Test public void testOneOfEach() throws TException { Fixtures.getOneOfEach().write(proto); assertEquals( "{\"im_true\":1,\"im_false\":0,\"a_bite\":-42,\"integer16\":27000,\"integer32\":16777216,\"integer64\":6000000000,\"double_precision\":3.141592653589793,\"some_characters\":\"JSON THIS! \\\"\\u0001\",\"zomg_unicode\":\"ӀⅮΠÐοⅿоɡгаÏℎ Αttαⅽκ�‼\",\"what_who\":0,\"base64\":\"base64\",\"byte_list\":[1,2,3],\"i16_list\":[1,2,3],\"i64_list\":[1,2,3]}", bufToString()); } @Test public void testSanePartsOfCompactProtoTestStruct() throws TException { // unset all the maps with container keys CompactProtoTestStruct struct = Fixtures.getCompactProtoTestStruct().deepCopy(); struct.unsetList_byte_map(); struct.unsetSet_byte_map(); struct.unsetMap_byte_map(); // unset sets and maps that produce inconsistent ordering between JDK7/8 struct.unsetByte_set(); struct.unsetI16_set(); struct.unsetI64_set(); struct.unsetDouble_set(); struct.unsetString_set(); struct.unsetI16_byte_map(); struct.unsetI32_byte_map(); struct.unsetI64_byte_map(); struct.unsetDouble_byte_map(); struct.unsetString_byte_map(); struct.write(proto); assertEquals( "{\"a_byte\":127,\"a_i16\":32000,\"a_i32\":1000000000,\"a_i64\":1099511627775,\"a_double\":5.6789,\"a_string\":\"my string\",\"a_binary\":\"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\",\"true_field\":1,\"false_field\":0,\"empty_struct_field\":{},\"byte_list\":[-127,-1,0,1,127],\"i16_list\":[-1,0,1,32767],\"i32_list\":[-1,0,255,65535,16777215,2147483647],\"i64_list\":[-1,0,255,65535,16777215,4294967295,1099511627775,281474976710655,72057594037927935,9223372036854775807],\"double_list\":[0.1,0.2,0.3],\"string_list\":[\"first\",\"second\",\"third\"],\"boolean_list\":[1,1,1,0,0,0],\"struct_list\":[{},{}],\"i32_set\":[1,2,3],\"boolean_set\":[0,1],\"struct_set\":[{}],\"byte_byte_map\":{\"1\":2},\"boolean_byte_map\":{\"0\":0,\"1\":1},\"byte_i16_map\":{\"1\":1,\"2\":-1,\"3\":32767},\"byte_i32_map\":{\"1\":1,\"2\":-1,\"3\":2147483647},\"byte_i64_map\":{\"1\":1,\"2\":-1,\"3\":9223372036854775807},\"byte_double_map\":{\"1\":0.1,\"2\":-0.1,\"3\":1000000.1},\"byte_string_map\":{\"1\":\"\",\"2\":\"blah\",\"3\":\"loooooooooooooong string\"},\"byte_boolean_map\":{\"1\":1,\"2\":0},\"byte_map_map\":{\"0\":{},\"1\":{\"1\":1},\"2\":{\"1\":1,\"2\":2}},\"byte_set_map\":{\"0\":[],\"1\":[1],\"2\":[1,2]},\"byte_list_map\":{\"0\":[],\"1\":[1],\"2\":[1,2]},\"field500\":500,\"field5000\":5000,\"field20000\":20000}", bufToString()); } @Test public void testThrowsOnCollectionKeys() throws TException { assertThrows( TSimpleJSONProtocol.CollectionMapKeyException.class, () -> Fixtures.getCompactProtoTestStruct().write(proto)); } @Test public void testReadingThrows() throws TTransportException { String input = "{\"test\": \"value\"}"; TDeserializer deserializer = new TDeserializer(new TSimpleJSONProtocol.Factory()); TException e = assertThrows( TException.class, () -> { deserializer.fromString(Fixtures.getOneOfEach(), input); }); assertEquals("Not implemented", e.getMessage()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/BenchmarkProtocols.java0000664000175000017500000000544015165535636031371 0ustar00buildbuild00000000000000package org.apache.thrift.protocol; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.Fixtures; import org.apache.thrift.TException; import org.apache.thrift.transport.TMemoryBuffer; public class BenchmarkProtocols { private static final Set FACTORIES = new LinkedHashSet() { { add(new TTupleProtocol.Factory()); add(new TCompactProtocol.Factory()); add(new TBinaryProtocol.Factory()); } }; private static final int NUM_REPS = 100000; private static final int NUM_TRIALS = 10; public static void main(String[] args) throws TException { Map> timesByFactory = new HashMap>(); for (int trial = 0; trial < NUM_TRIALS; trial++) { for (int i = 0; i < 16; i++) { System.gc(); } // TProtocol proto = factory.getProtocol(new TTransport() { // @Override // public void write(byte[] buf, int off, int len) throws TTransportException { // } // // @Override // public int read(byte[] buf, int off, int len) throws TTransportException { // return 0; // } // // @Override // public void open() throws TTransportException { // } // // @Override // public boolean isOpen() { // return true; // } // // @Override // public void close() { // } // }); for (TProtocolFactory factory : FACTORIES) { if (timesByFactory.get(factory) == null) { timesByFactory.put(factory, new ArrayList()); } long start = System.currentTimeMillis(); for (int rep = 0; rep < NUM_REPS; rep++) { TProtocol proto = factory.getProtocol(new TMemoryBuffer(128 * 1024)); Fixtures.getCompactProtoTestStruct().write(proto); Fixtures.getNesting().write(proto); } long end = System.currentTimeMillis(); timesByFactory.get(factory).add(end - start); } } for (TProtocolFactory factory : FACTORIES) { List times = timesByFactory.get(factory); // System.out.println("raw times pre-drop: " + times ); times.remove(Collections.max(times)); long total = 0; for (long t : times) { total += t; } Collections.sort(times); System.out.println( factory.getClass().getName() + " average time: " + (total / times.size()) + "ms"); System.out.println("raw times: " + times); } } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestTTupleProtocol.java0000664000175000017500000000144615165535636031373 0ustar00buildbuild00000000000000package org.apache.thrift.protocol; import org.apache.thrift.TDeserializer; import org.apache.thrift.TSerializer; import org.junit.jupiter.api.Test; import thrift.test.TupleProtocolTestStruct; public class TestTTupleProtocol extends ProtocolTestBase { @Override protected boolean canBeUsedNaked() { return false; } @Override protected TProtocolFactory getFactory() { return new TTupleProtocol.Factory(); } @Test public void testBitsetLengthIssue() throws Exception { final TupleProtocolTestStruct t1 = new TupleProtocolTestStruct(); t1.setField1(0); t1.setField2(12); new TDeserializer(new TTupleProtocol.Factory()) .deserialize( new TupleProtocolTestStruct(), new TSerializer(new TTupleProtocol.Factory()).serialize(t1)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestTBinaryProtocol.java0000664000175000017500000000206715165535636031526 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; public class TestTBinaryProtocol extends ProtocolTestBase { @Override protected TProtocolFactory getFactory() { return new TBinaryProtocol.Factory(); } @Override protected boolean canBeUsedNaked() { return true; } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestTField.java0000664000175000017500000000417015165535636027600 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import org.junit.jupiter.api.Test; public abstract class TestTField { @Test public void testConstructor() { TField uut = new TField(); assertEquals("", uut.name); assertEquals(TType.STOP, uut.type); assertEquals(0, uut.id); uut = new TField("foo", TType.VOID, (short) 42); assertEquals("foo", uut.name); assertEquals(TType.VOID, uut.type); assertEquals(42, uut.id); } @Test public void testEquality() { TField uut1 = new TField(); TField uut2 = new TField(); assertEquals(uut1, uut2); assertEquals(uut1.hashCode(), uut2.hashCode()); uut1 = new TField("foo", TType.I32, (short) 1); uut2 = new TField("foo", TType.I32, (short) 2); assertNotEquals(uut1, uut2); assertNotEquals(uut1.hashCode(), uut2.hashCode()); uut1 = new TField("foo", TType.VOID, (short) 1); uut2 = new TField("foo", TType.I32, (short) 1); assertNotEquals(uut1, uut2); assertNotEquals(uut1.hashCode(), uut2.hashCode()); uut1 = new TField("foo", TType.VOID, (short) 5); uut2 = new TField("bar", TType.I32, (short) 5); assertEquals(uut1, uut2); // name field is ignored assertEquals(uut1.hashCode(), uut2.hashCode()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestTCompactProtocol.java0000664000175000017500000000337715165535636031675 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.junit.jupiter.api.Test; import thrift.test.Bonk; public class TestTCompactProtocol extends ProtocolTestBase { @Override protected TProtocolFactory getFactory() { return new TCompactProtocol.Factory(); } @Override protected boolean canBeUsedNaked() { return true; } @Test public void testOOMDenialOfService() throws Exception { // Struct header, Integer.MAX_VALUE length, and only one real // byte of data byte[] bytes = {24, -1, -1, -1, -17, 49}; TDeserializer deser = new TDeserializer(new TCompactProtocol.Factory(1000)); Bonk bonk = new Bonk(); try { deser.deserialize(bonk, bytes); } catch (TException e) { // Ignore as we are only checking for OOM in the failure case } } public static void main(String args[]) throws Exception { new TestTCompactProtocol().benchmark(); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/ProtocolTestBase.java0000664000175000017500000005011015165535636031020 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.thrift.Fixtures; import org.apache.thrift.TBase; import org.apache.thrift.TConfiguration; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TTransportException; import org.junit.jupiter.api.Test; import thrift.test.CompactProtoTestStruct; import thrift.test.HolyMoley; import thrift.test.Nesting; import thrift.test.OneOfEach; import thrift.test.Srv; import thrift.test.ThriftTest; public abstract class ProtocolTestBase { /** Does it make sense to call methods like writeI32 directly on your protocol? */ protected abstract boolean canBeUsedNaked(); /** The protocol factory for the protocol being tested. */ protected abstract TProtocolFactory getFactory(); @Test public void testDouble() throws Exception { if (canBeUsedNaked()) { TMemoryBuffer buf = new TMemoryBuffer(1000); TProtocol proto = getFactory().getProtocol(buf); proto.writeDouble(123.456); assertEquals(123.456, proto.readDouble()); } internalTestStructField( new StructFieldTestCase(TType.DOUBLE, (short) 15) { @Override public void readMethod(TProtocol proto) throws TException { assertEquals(123.456, proto.readDouble()); } @Override public void writeMethod(TProtocol proto) throws TException { proto.writeDouble(123.456); } }); } @Test public void testSerialization() throws Exception { internalTestSerialization(OneOfEach.class, Fixtures.getOneOfEach()); internalTestSerialization(Nesting.class, Fixtures.getNesting()); internalTestSerialization(HolyMoley.class, Fixtures.getHolyMoley()); internalTestSerialization(CompactProtoTestStruct.class, Fixtures.getCompactProtoTestStruct()); } @Test public void testBinary() throws Exception { for (byte[] b : Arrays.asList( new byte[0], new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, new byte[] {0x5D}, new byte[] {(byte) 0xD5, (byte) 0x5D}, new byte[] {(byte) 0xFF, (byte) 0xD5, (byte) 0x5D}, new byte[128])) { if (canBeUsedNaked()) { internalTestNakedBinary(b); } internalTestBinaryField(b); } if (canBeUsedNaked()) { byte[] data = {1, 2, 3, 4, 5, 6}; TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); ByteBuffer bb = ByteBuffer.wrap(data); bb.get(); proto.writeBinary(bb.slice()); assertEquals(ByteBuffer.wrap(data, 1, 5), proto.readBinary()); } } @Test public void testString() throws Exception { for (String s : Arrays.asList("", "short", "borderlinetiny", "a bit longer than the smallest possible")) { if (canBeUsedNaked()) { internalTestNakedString(s); } internalTestStringField(s); } } @Test public void testUuid() throws Exception { UUID uuid = UUID.fromString("00112233-4455-6677-8899-aabbccddeeff"); if (canBeUsedNaked()) { internalTestNakedUuid(uuid); } internalTestUuidField(uuid); } @Test public void testLong() throws Exception { if (canBeUsedNaked()) { internalTestNakedI64(0); } internalTestI64Field(0); for (int i = 0; i < 62; i++) { if (canBeUsedNaked()) { internalTestNakedI64(1L << i); internalTestNakedI64(-(1L << i)); } internalTestI64Field(1L << i); internalTestI64Field(-(1L << i)); } } @Test public void testInt() throws Exception { for (int i : Arrays.asList( 0, 1, 7, 150, 15000, 31337, 0xffff, 0xffffff, -1, -7, -150, -15000, -0xffff, -0xffffff)) { if (canBeUsedNaked()) { internalTestNakedI32(i); } internalTestI32Field(i); } } @Test public void testShort() throws Exception { for (int s : Arrays.asList(0, 1, 7, 150, 15000, 0x7fff, -1, -7, -150, -15000, -0x7fff)) { if (canBeUsedNaked()) { internalTestNakedI16((short) s); } internalTestI16Field((short) s); } } @Test public void testByte() throws Exception { if (canBeUsedNaked()) { internalTestNakedByte(); } for (int i = 0; i < 128; i++) { internalTestByteField((byte) i); internalTestByteField((byte) -i); } } private void internalTestNakedByte() throws Exception { TMemoryBuffer buf = new TMemoryBuffer(1000); TProtocol proto = getFactory().getProtocol(buf); proto.writeByte((byte) 123); assertEquals((byte) 123, proto.readByte()); } private void internalTestByteField(final byte b) throws Exception { internalTestStructField( new StructFieldTestCase(TType.BYTE, (short) 15) { public void writeMethod(TProtocol proto) throws TException { proto.writeByte(b); } public void readMethod(TProtocol proto) throws TException { assertEquals(b, proto.readByte()); } }); } private void internalTestNakedI16(short n) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeI16(n); assertEquals(n, proto.readI16()); } private void internalTestI16Field(final short n) throws Exception { internalTestStructField( new StructFieldTestCase(TType.I16, (short) 15) { public void writeMethod(TProtocol proto) throws TException { proto.writeI16(n); } public void readMethod(TProtocol proto) throws TException { assertEquals(n, proto.readI16()); } }); } private void internalTestNakedUuid(UUID uuid) throws TException { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol protocol = getFactory().getProtocol(buf); protocol.writeUuid(uuid); assertEquals(uuid, protocol.readUuid()); } private void internalTestUuidField(UUID uuid) throws Exception { internalTestStructField( new StructFieldTestCase(TType.UUID, (short) 17) { @Override public void writeMethod(TProtocol proto) throws TException { proto.writeUuid(uuid); } @Override public void readMethod(TProtocol proto) throws TException { assertEquals(uuid, proto.readUuid()); } }); } private void internalTestNakedI32(int n) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeI32(n); assertEquals(n, proto.readI32()); } private void internalTestI32Field(final int n) throws Exception { internalTestStructField( new StructFieldTestCase(TType.I32, (short) 15) { public void writeMethod(TProtocol proto) throws TException { proto.writeI32(n); } public void readMethod(TProtocol proto) throws TException { assertEquals(n, proto.readI32()); } }); } private void internalTestNakedI64(long n) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeI64(n); assertEquals(n, proto.readI64()); } private void internalTestI64Field(final long n) throws Exception { internalTestStructField( new StructFieldTestCase(TType.I64, (short) 15) { public void writeMethod(TProtocol proto) throws TException { proto.writeI64(n); } public void readMethod(TProtocol proto) throws TException { assertEquals(n, proto.readI64()); } }); } private void internalTestNakedString(String str) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeString(str); assertEquals(str, proto.readString()); } private void internalTestStringField(final String str) throws Exception { internalTestStructField( new StructFieldTestCase(TType.STRING, (short) 15) { public void writeMethod(TProtocol proto) throws TException { proto.writeString(str); } public void readMethod(TProtocol proto) throws TException { assertEquals(str, proto.readString()); } }); } private void internalTestNakedBinary(byte[] data) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeBinary(ByteBuffer.wrap(data)); assertEquals(ByteBuffer.wrap(data), proto.readBinary()); } private void internalTestBinaryField(final byte[] data) throws Exception { internalTestStructField( new StructFieldTestCase(TType.STRING, (short) 15) { public void writeMethod(TProtocol proto) throws TException { proto.writeBinary(ByteBuffer.wrap(data)); } public void readMethod(TProtocol proto) throws TException { assertEquals(ByteBuffer.wrap(data), proto.readBinary()); } }); } private void internalTestSerialization(Class klass, T expected) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TBinaryProtocol binproto = new TBinaryProtocol(buf); expected.write(binproto); buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); expected.write(proto); System.out.println("Size in " + proto.getClass().getSimpleName() + ": " + buf.length()); T actual = klass.getDeclaredConstructor().newInstance(); actual.read(proto); assertEquals(expected, actual); } @Test public void testMessage() throws Exception { List msgs = Arrays.asList( new TMessage[] { new TMessage("short message name", TMessageType.CALL, 0), new TMessage("1", TMessageType.REPLY, 12345), new TMessage( "loooooooooooooooooooooooooooooooooong", TMessageType.EXCEPTION, 1 << 16), new TMessage("Janky", TMessageType.CALL, 0), }); for (TMessage msg : msgs) { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); TMessage output = null; proto.writeMessageBegin(msg); proto.writeMessageEnd(); output = proto.readMessageBegin(); assertEquals(msg, output); } } @Test public void testServerRequest() throws Exception { Srv.Iface handler = new Srv.Iface() { public int Janky(int i32arg) throws TException { return i32arg * 2; } public int primitiveMethod() throws TException { return 0; } public CompactProtoTestStruct structMethod() throws TException { return null; } public void voidMethod() throws TException {} public void methodWithDefaultArgs(int something) throws TException {} @Override public void onewayMethod() throws TException {} @Override public boolean declaredExceptionMethod(boolean shouldThrow) throws TException { return shouldThrow; } }; Srv.Processor testProcessor = new Srv.Processor(handler); TMemoryBuffer clientOutTrans = new TMemoryBuffer(0); TProtocol clientOutProto = getFactory().getProtocol(clientOutTrans); TMemoryBuffer clientInTrans = new TMemoryBuffer(0); TProtocol clientInProto = getFactory().getProtocol(clientInTrans); Srv.Client testClient = new Srv.Client(clientInProto, clientOutProto); testClient.send_Janky(1); // System.out.println(clientOutTrans.inspect()); testProcessor.process(clientOutProto, clientInProto); // System.out.println(clientInTrans.inspect()); assertEquals(2, testClient.recv_Janky()); } @Test public void testTDeserializer() throws TException { TSerializer ser = new TSerializer(getFactory()); byte[] bytes = ser.serialize(Fixtures.getCompactProtoTestStruct()); TDeserializer deser = new TDeserializer(getFactory()); CompactProtoTestStruct cpts = new CompactProtoTestStruct(); deser.deserialize(cpts, bytes); assertEquals(Fixtures.getCompactProtoTestStruct(), cpts); } // // Helper methods // private void internalTestStructField(StructFieldTestCase testCase) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); TField field = new TField("test_field", testCase.type_, testCase.id_); proto.writeStructBegin(new TStruct("test_struct")); proto.writeFieldBegin(field); testCase.writeMethod(proto); proto.writeFieldEnd(); proto.writeStructEnd(); proto.readStructBegin(); TField readField = proto.readFieldBegin(); assertEquals(testCase.id_, readField.id); assertEquals(testCase.type_, readField.type); testCase.readMethod(proto); proto.readStructEnd(); } private abstract static class StructFieldTestCase { byte type_; short id_; public StructFieldTestCase(byte type, short id) { type_ = type; id_ = id; } public abstract void writeMethod(TProtocol proto) throws TException; public abstract void readMethod(TProtocol proto) throws TException; } private static final int NUM_TRIALS = 5; private static final int NUM_REPS = 10000; protected void benchmark() throws Exception { for (int trial = 0; trial < NUM_TRIALS; trial++) { TSerializer ser = new TSerializer(getFactory()); byte[] serialized = null; long serStart = System.currentTimeMillis(); for (int rep = 0; rep < NUM_REPS; rep++) { serialized = ser.serialize(Fixtures.getHolyMoley()); } long serEnd = System.currentTimeMillis(); long serElapsed = serEnd - serStart; System.out.println( "Ser:\t" + serElapsed + "ms\t" + ((double) serElapsed / NUM_REPS) + "ms per serialization"); HolyMoley cpts = new HolyMoley(); TDeserializer deser = new TDeserializer(getFactory()); long deserStart = System.currentTimeMillis(); for (int rep = 0; rep < NUM_REPS; rep++) { deser.deserialize(cpts, serialized); } long deserEnd = System.currentTimeMillis(); long deserElapsed = deserEnd - deserStart; System.out.println( "Des:\t" + deserElapsed + "ms\t" + ((double) deserElapsed / NUM_REPS) + "ms per deserialization"); } } private final ServerTestBase.TestHandler testHandler = new ServerTestBase.TestHandler() { @Override public String testString(String thing) { thing = thing + " Apache Thrift Java " + thing; return thing; } @Override public List testList(List thing) { thing.addAll(thing); thing.addAll(thing); return thing; } @Override public Set testSet(Set thing) { thing.addAll(thing.stream().map(x -> x + 100).collect(Collectors.toSet())); return thing; } @Override public Map testStringMap(Map thing) { thing.put("a", "123"); thing.put(" x y ", " with spaces "); thing.put("same", "same"); thing.put("0", "numeric key"); thing.put("1", ""); thing.put("ok", "2355555"); thing.put("end", "0"); return thing; } }; private TProtocol initConfig(int maxSize) throws TException { TConfiguration config = TConfiguration.custom().setMaxMessageSize(maxSize).build(); TMemoryBuffer bufferTrans = new TMemoryBuffer(config, 0); return getFactory().getProtocol(bufferTrans); } @Test public void testReadCheckMaxMessageRequestForString() throws TException { TProtocol clientOutProto = initConfig(15); TProtocol clientInProto = initConfig(15); ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); try { testClient.send_testString("test"); testProcessor.process(clientOutProto, clientInProto); String result = testClient.recv_testString(); System.out.println("----result: " + result); } catch (TException e) { assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, ((TTransportException) e).getType()); } } @Test public void testReadCheckMaxMessageRequestForList() throws TException { TProtocol clientOutProto = initConfig(15); TProtocol clientInProto = initConfig(15); ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); TTransportException e = assertThrows( TTransportException.class, () -> { testClient.send_testList(Arrays.asList(1, 23242346, 888888, 90)); testProcessor.process(clientOutProto, clientInProto); testClient.recv_testList(); }, "Limitations not achieved as expected"); assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } @Test public void testReadCheckMaxMessageRequestForMap() throws TException { TProtocol clientOutProto = initConfig(13); TProtocol clientInProto = initConfig(13); ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); Map thing = new HashMap<>(); thing.put("key", "Thrift"); TTransportException e = assertThrows( TTransportException.class, () -> { testClient.send_testStringMap(thing); testProcessor.process(clientOutProto, clientInProto); testClient.recv_testStringMap(); }, "Limitations not achieved as expected"); assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } @Test public void testReadCheckMaxMessageRequestForSet() throws TException { TProtocol clientOutProto = initConfig(10); TProtocol clientInProto = initConfig(10); ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); TTransportException e = assertThrows( TTransportException.class, () -> { testClient.send_testSet( Stream.of(234, 0, 987087, 45, 88888888, 9).collect(Collectors.toSet())); testProcessor.process(clientOutProto, clientInProto); testClient.recv_testSet(); }, "Limitations not achieved as expected"); assertEquals(TTransportException.MESSAGE_SIZE_LIMIT, e.getType()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestShortStack.java0000664000175000017500000000261515165535636030520 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; public class TestShortStack { @Test public void testOps() throws Exception { ShortStack s = new ShortStack(1); s.push((short) 10); s.push((short) 11); s.push((short) 12); assertEquals((short) 12, s.pop()); assertEquals((short) 11, s.pop()); s.push((short) 40); assertEquals((short) 40, s.pop()); assertEquals((short) 10, s.pop()); assertThrows(Exception.class, s::pop); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestTProtocolUtil.java0000664000175000017500000000665415165535636031225 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.thrift.TSerializer; import org.junit.jupiter.api.Test; import thrift.test.GuessProtocolStruct; public class TestTProtocolUtil { @Test public void testGuessProtocolFactory_JSON() throws Exception { byte[] data = "{foo}".getBytes(); TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(data, new TCompactProtocol.Factory()); assertTrue(factory instanceof TJSONProtocol.Factory); // Make sure data serialized with TCompact and which starts with '{' // is not mistakenly guessed as serialized with JSON. GuessProtocolStruct s = new GuessProtocolStruct(); s.putToMap_field("}", "}"); byte[] ser = new TSerializer(new TCompactProtocol.Factory()).serialize(s); factory = TProtocolUtil.guessProtocolFactory(ser, new TCompactProtocol.Factory()); assertFalse(factory instanceof TJSONProtocol.Factory); } @Test public void testGuessProtocolFactory_Binary() throws Exception { // Check that a last byte != 0 is correctly reported as Binary byte[] buf = new byte[1]; for (int i = 1; i < 256; i++) { buf[0] = (byte) i; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TCompactProtocol.Factory()); assertTrue(factory instanceof TBinaryProtocol.Factory); } // Check that a second byte set to 0 is reported as Binary buf = new byte[2]; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TCompactProtocol.Factory()); assertTrue(factory instanceof TBinaryProtocol.Factory); } @Test public void testGuessProtocolFactory_Compact() throws Exception { // Check that a first byte > 0x10 is reported as Compact byte[] buf = new byte[3]; buf[0] = 0x11; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TBinaryProtocol.Factory()); assertTrue(factory instanceof TCompactProtocol.Factory); // Check that second byte >= 0x80 is reported as Compact buf[0] = 0; for (int i = 0x80; i < 0x100; i++) { buf[1] = (byte) i; factory = TProtocolUtil.guessProtocolFactory(buf, new TBinaryProtocol.Factory()); assertTrue(factory instanceof TCompactProtocol.Factory); } } @Test public void testGuessProtocolFactory_Undecided() throws Exception { byte[] buf = new byte[3]; buf[1] = 0x7e; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TSimpleJSONProtocol.Factory()); assertTrue(factory instanceof TSimpleJSONProtocol.Factory); } } TestTLegacyUuidProtocolDecorator.java0000664000175000017500000001240715167543515034115 0ustar00buildbuild00000000000000thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import java.util.Arrays; import java.util.UUID; import org.apache.thrift.TException; import org.apache.thrift.transport.TMemoryBuffer; import org.junit.jupiter.api.Test; public class TestTLegacyUuidProtocolDecorator { private static final UUID TEST_UUID = UUID.fromString("00112233-4455-6677-8899-aabbccddeeff"); /** * Check the correct way to wrap a TBinaryProtocol with legacy UUID byte-swapping behaviour for * systems that depend on the original wire format. * *

Use TLegacyUuidProtocolDecorator when: - communicating with a peer that was built against * the old TBinaryProtocol - reading data that was serialized with the old implementation * *

Use TBinaryProtocol directly when: - both peers are on the fixed implementation - starting a * new integration from scratch */ @Test public void checkLegacyUuidRoundTrip() throws TException { TMemoryBuffer transport = new TMemoryBuffer(16); TProtocol protocol = new TLegacyUuidProtocolDecorator(new TBinaryProtocol(transport)); protocol.writeUuid(TEST_UUID); UUID result = protocol.readUuid(); assertEquals(TEST_UUID, result); } /** * Demonstrates that the legacy and fixed protocols produce DIFFERENT bytes on the wire, and are * therefore incompatible with each other. * *

This test exists to make that incompatibility explicit and visible. */ @Test public void checkWireIncompatibility() throws TException { TMemoryBuffer legacyTransport = new TMemoryBuffer(16); TProtocol legacyProtocol = new TLegacyUuidProtocolDecorator(new TBinaryProtocol(legacyTransport)); legacyProtocol.writeUuid(TEST_UUID); TMemoryBuffer fixedTransport = new TMemoryBuffer(16); TProtocol fixedProtocol = new TBinaryProtocol(fixedTransport); fixedProtocol.writeUuid(TEST_UUID); assertNotEquals( Arrays.toString(legacyTransport.getArray()), Arrays.toString(fixedTransport.getArray()), "Legacy and fixed protocols must produce different bytes"); } /** * Check that a UUID written by the legacy protocol CANNOT be correctly read back by the fixed * protocol, and vice versa. */ @Test public void checkCrossProtocolReadFailure() throws TException { TMemoryBuffer transport = new TMemoryBuffer(16); // write with legacy, read with fixed TProtocol legacyWriter = new TLegacyUuidProtocolDecorator(new TBinaryProtocol(transport)); legacyWriter.writeUuid(TEST_UUID); TProtocol fixedReader = new TBinaryProtocol(transport); UUID result = fixedReader.readUuid(); assertNotEquals( TEST_UUID, result, "Reading legacy bytes with the fixed protocol must produce a different UUID"); } /** Check that a UUID written by the legacy protocol is byte swapped as expected. */ @Test public void checkLegacySwapping() throws TException { TMemoryBuffer transport = new TMemoryBuffer(16); // write with legacy, read with fixed TProtocol protocol = new TLegacyUuidProtocolDecorator(new TBinaryProtocol(transport)); protocol.writeUuid(TEST_UUID); // The legacy implementation writes LSB first, then MSB - which is the wrong // order byte[] expected = { (byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb, // LSB high bytes (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, // LSB low bytes (byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33, // MSB high bytes (byte) 0x44, (byte) 0x55, (byte) 0x66, (byte) 0x77, // MSB low bytes }; byte[] actual = transport.getArray(); assertArrayEquals(expected, Arrays.copyOf(actual, 16)); } /** * Check that a UUID written by the correct protocol is as expected * *

This test is probably out of place */ @Test public void checkCorrectSwapping() throws TException { TMemoryBuffer transport = new TMemoryBuffer(16); TProtocol protocol = new TBinaryProtocol(transport); protocol.writeUuid(TEST_UUID); byte[] expected = { (byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, }; byte[] actual = transport.getArray(); assertArrayEquals(expected, Arrays.copyOf(actual, 16)); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/protocol/TestTJSONProtocol.java0000664000175000017500000000440015165535636031044 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import static org.junit.jupiter.api.Assertions.assertEquals; import java.nio.charset.StandardCharsets; import org.apache.thrift.TException; import org.apache.thrift.transport.TMemoryBuffer; import org.junit.jupiter.api.Test; public class TestTJSONProtocol extends ProtocolTestBase { @Override protected TProtocolFactory getFactory() { return new TJSONProtocol.Factory(); } @Override protected boolean canBeUsedNaked() { return false; } @Test public void testEscapedUnicode() throws TException { String jsonString = "\"hello unicode \\u0e01\\ud834\\udd1e world\""; String expectedString = "hello unicode \u0e01\ud834\udd1e world"; TMemoryBuffer buffer = new TMemoryBuffer(1000); TJSONProtocol protocol = new TJSONProtocol(buffer); buffer.write(jsonString.getBytes(StandardCharsets.UTF_8)); assertEquals(expectedString, protocol.readString()); } @Test public void testExactlySizedBuffer() throws TException { // Regression test for https://issues.apache.org/jira/browse/THRIFT-5383. // Ensures that a JSON string can be read after writing to a buffer just // large enough to contain it. String inputString = "abcdefg"; TMemoryBuffer buffer = new TMemoryBuffer(inputString.length() + 2); TJSONProtocol protocol = new TJSONProtocol(buffer); protocol.writeString(inputString); String outputString = protocol.readString(); assertEquals(inputString, outputString); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestOptionals.java0000664000175000017500000000567315165535636026551 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import thrift.test.Opt30; import thrift.test.Opt4; import thrift.test.Opt64; import thrift.test.Opt80; // Exercises the isSet methods using structs from ManyOptionals.thrift public class TestOptionals { @Test public void testEncodingUtils() throws Exception { assertEquals((short) 0x8, EncodingUtils.setBit((short) 0, 3, true)); assertEquals((short) 0, EncodingUtils.setBit((short) 0x8, 3, false)); assertTrue(EncodingUtils.testBit((short) 0x8, 3)); assertFalse(EncodingUtils.testBit((short) 0x8, 4)); assertEquals(Short.MIN_VALUE, EncodingUtils.setBit((short) 0, 15, true)); assertEquals((short) 0, EncodingUtils.setBit(Short.MIN_VALUE, 15, false)); assertTrue(EncodingUtils.testBit(Short.MIN_VALUE, 15)); assertFalse(EncodingUtils.testBit(Short.MIN_VALUE, 14)); } @Test public void testOpt4() throws Exception { Opt4 x = new Opt4(); assertFalse(x.isSetDef1()); x.setDef1(3); assertTrue(x.isSetDef1()); assertFalse(x.isSetDef2()); Opt4 copy = new Opt4(x); assertTrue(copy.isSetDef1()); copy.unsetDef1(); assertFalse(copy.isSetDef1()); assertTrue(x.isSetDef1()); } @Test public void testOpt30() throws Exception { Opt30 x = new Opt30(); assertFalse(x.isSetDef1()); x.setDef1(3); assertTrue(x.isSetDef1()); assertFalse(x.isSetDef2()); } @Test public void testOpt64() throws Exception { Opt64 x = new Opt64(); assertFalse(x.isSetDef1()); x.setDef1(3); assertTrue(x.isSetDef1()); assertFalse(x.isSetDef2()); x.setDef64(22); assertTrue(x.isSetDef64()); assertFalse(x.isSetDef63()); } @Test public void testOpt80() throws Exception { Opt80 x = new Opt80(); assertFalse(x.isSetDef1()); x.setDef1(3); assertTrue(x.isSetDef1()); assertFalse(x.isSetDef2()); Opt80 copy = new Opt80(x); copy.unsetDef1(); assertFalse(copy.isSetDef1()); assertTrue(x.isSetDef1()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestTDeserializer.java0000664000175000017500000001645415165535636027346 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertEquals; import java.nio.ByteBuffer; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.junit.jupiter.api.Test; import thrift.test.Backwards; import thrift.test.OneOfEach; import thrift.test.PrimitiveThenStruct; import thrift.test.StructWithAUnion; import thrift.test.TestUnion; public class TestTDeserializer { private static final TProtocolFactory[] PROTOCOLS = new TProtocolFactory[] { new TBinaryProtocol.Factory(), new TCompactProtocol.Factory(), new TJSONProtocol.Factory() }; @Test public void testPartialDeserialize() throws Exception { // Root:StructWithAUnion // 1:Union // 1.3:OneOfEach OneOfEach level3OneOfEach = Fixtures.getOneOfEach(); TestUnion level2TestUnion = new TestUnion(TestUnion._Fields.STRUCT_FIELD, level3OneOfEach); StructWithAUnion level1SWU = new StructWithAUnion(level2TestUnion); Backwards bw = new Backwards(2, 1); PrimitiveThenStruct pts = new PrimitiveThenStruct(12345, 67890, bw); for (TProtocolFactory factory : PROTOCOLS) { // Level 2 test testPartialDeserialize( factory, level1SWU, new TestUnion(), level2TestUnion, StructWithAUnion._Fields.TEST_UNION); // Level 3 on 3rd field test testPartialDeserialize( factory, level1SWU, new OneOfEach(), level3OneOfEach, StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD); // Test early termination when traversed path Field.id exceeds the one being searched for testPartialDeserialize( factory, level1SWU, new OneOfEach(), new OneOfEach(), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.I32_FIELD); // Test that readStructBegin isn't called on primitive testPartialDeserialize(factory, pts, new Backwards(), bw, PrimitiveThenStruct._Fields.BW); // Test primitive types TDeserializer deserializer = new TDeserializer(factory); Boolean expectedBool = level3OneOfEach.isIm_true(); Boolean resultBool = deserializer.partialDeserializeBool( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.IM_TRUE); assertEquals(expectedBool, resultBool); Byte expectedByte = level3OneOfEach.getA_bite(); Byte resultByte = deserializer.partialDeserializeByte( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.A_BITE); assertEquals(expectedByte, resultByte); Double expectedDouble = level3OneOfEach.getDouble_precision(); Double resultDouble = deserializer.partialDeserializeDouble( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.DOUBLE_PRECISION); assertEquals(expectedDouble, resultDouble); Short expectedI16 = level3OneOfEach.getInteger16(); Short resultI16 = deserializer.partialDeserializeI16( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER16); assertEquals(expectedI16, resultI16); Integer expectedI32 = level3OneOfEach.getInteger32(); Integer resultI32 = deserializer.partialDeserializeI32( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER32); assertEquals(expectedI32, resultI32); Long expectedI64 = level3OneOfEach.getInteger64(); Long resultI64 = deserializer.partialDeserializeI64( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER64); assertEquals(expectedI64, resultI64); String expectedString = level3OneOfEach.getSome_characters(); String resultString = deserializer.partialDeserializeString( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.SOME_CHARACTERS); assertEquals(expectedString, resultString); byte[] expectedBinary = level3OneOfEach.getBase64(); ByteBuffer resultBinary = deserializer.partialDeserializeByteArray( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.BASE64); assertEquals( expectedBinary.length, resultBinary.limit() - resultBinary.position() - resultBinary.arrayOffset()); assertEquals(ByteBuffer.wrap(expectedBinary), resultBinary); // Test field id in Union short id = deserializer.partialDeserializeSetFieldIdInUnion( serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION); assertEquals(level2TestUnion.getSetField().getThriftFieldId(), id); } } private void testPartialDeserialize( TProtocolFactory protocolFactory, TBase input, TBase output, TBase expected, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum... fieldIdPathRest) throws TException { byte[] record = serialize(input, protocolFactory); TDeserializer deserializer = new TDeserializer(protocolFactory); for (int i = 0; i < 2; i++) { TBase outputCopy = output.deepCopy(); deserializer.partialDeserialize(outputCopy, record, fieldIdPathFirst, fieldIdPathRest); assertEquals( expected, outputCopy, "on attempt " + i + ", with " + protocolFactory + ", expected " + expected + " but got " + outputCopy); } } private static byte[] serialize(TBase input, TProtocolFactory protocolFactory) throws TException { return new TSerializer(protocolFactory).serialize(input); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestUnsafeBinaries.java0000664000175000017500000000631615165535636027472 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import java.nio.ByteBuffer; import org.junit.jupiter.api.Test; import thrift.test.SafeBytes; import thrift.test.UnsafeBytes; // test generating types with un-copied byte[]/ByteBuffer input/output // public class TestUnsafeBinaries { private static byte[] input() { return new byte[] {1, 1}; } // // verify that the unsafe_binaries option modifies behavior // // constructor doesn't copy @Test public void testUnsafeConstructor() throws Exception { byte[] input = input(); UnsafeBytes struct = new UnsafeBytes(ByteBuffer.wrap(input)); input[0] = 2; assertArrayEquals(new byte[] {2, 1}, struct.getBytes()); } // getter doesn't copy // note: this behavior is the same with/without the flag, but if this default ever changes, the // current behavior // should be retained when using this flag @Test public void testUnsafeGetter() { UnsafeBytes struct = new UnsafeBytes(ByteBuffer.wrap(input())); byte[] val = struct.getBytes(); val[0] = 2; assertArrayEquals(new byte[] {2, 1}, struct.getBytes()); } // setter doesn't copy @Test public void testUnsafeSetter() { UnsafeBytes struct = new UnsafeBytes(); byte[] val = input(); struct.setBytes(val); val[0] = 2; assertArrayEquals(new byte[] {2, 1}, struct.getBytes()); } // buffer doens't copy @Test public void testUnsafeBufferFor() { UnsafeBytes struct = new UnsafeBytes(ByteBuffer.wrap(input())); ByteBuffer val = struct.bufferForBytes(); val.array()[0] = 2; assertArrayEquals(new byte[] {2, 1}, struct.getBytes()); } // // verify that the default generator does not change behavior // @Test public void testSafeConstructor() { byte[] input = input(); SafeBytes struct = new SafeBytes(ByteBuffer.wrap(input)); input[0] = 2; assertArrayEquals(new byte[] {1, 1}, struct.getBytes()); } @Test public void testSafeSetter() { byte[] input = input(); SafeBytes struct = new SafeBytes(ByteBuffer.wrap(input)); input[0] = 2; assertArrayEquals(new byte[] {1, 1}, struct.getBytes()); } @Test public void testSafeBufferFor() { SafeBytes struct = new SafeBytes(ByteBuffer.wrap(input())); ByteBuffer val = struct.bufferForBytes(); val.array()[0] = 2; assertArrayEquals(new byte[] {1, 1}, struct.getBytes()); } } thrift-0.23.0/lib/java/src/test/java/org/apache/thrift/TestDeepCopy.java0000664000175000017500000000242415165535636026300 0ustar00buildbuild00000000000000package org.apache.thrift; import static org.junit.jupiter.api.Assertions.assertNotSame; import org.junit.jupiter.api.Test; import thrift.test.DeepCopyBar; import thrift.test.DeepCopyFoo; public class TestDeepCopy { @Test public void testDeepCopy() throws Exception { final DeepCopyFoo foo = new DeepCopyFoo(); foo.addToL(new DeepCopyBar()); foo.addToS(new DeepCopyBar()); foo.putToM("test 3", new DeepCopyBar()); foo.addToLi(new thrift.test.Object()); foo.addToSi(new thrift.test.Object()); foo.putToMi("test 3", new thrift.test.Object()); foo.setBar(new DeepCopyBar()); final DeepCopyFoo deepCopyFoo = foo.deepCopy(); assertNotSame(foo.getBar(), deepCopyFoo.getBar()); assertNotSame(foo.getL().get(0), deepCopyFoo.getL().get(0)); assertNotSame( foo.getS().toArray(new DeepCopyBar[0])[0], deepCopyFoo.getS().toArray(new DeepCopyBar[0])[0]); assertNotSame(foo.getM().get("test 3"), deepCopyFoo.getM().get("test 3")); assertNotSame(foo.getLi().get(0), deepCopyFoo.getLi().get(0)); assertNotSame( foo.getSi().toArray(new thrift.test.Object[0])[0], deepCopyFoo.getSi().toArray(new thrift.test.Object[0])[0]); assertNotSame(foo.getMi().get("test 3"), deepCopyFoo.getMi().get("test 3")); } } thrift-0.23.0/lib/java/settings.gradle0000664000175000017500000000150415165535636020104 0ustar00buildbuild00000000000000/* * 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. */ rootProject.name = 'libthrift' thrift-0.23.0/lib/java/code_quality_tools/0000775000175000017500000000000015165535636020766 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/code_quality_tools/findbugs-filter.xml0000664000175000017500000000401715165535636024576 0ustar00buildbuild00000000000000 thrift-0.23.0/lib/java/coding_standards.md0000664000175000017500000000010315165535636020706 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/java/CMakeLists.txt0000664000175000017500000000776315165535636017641 0ustar00buildbuild00000000000000# # 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. # if(ANDROID) set(THRIFT_AAR outputs/aar/thrift-debug.aar outputs/aar/thrift-release.aar) add_custom_command( OUTPUT ${THRIFT_AAR} COMMAND ${GRADLE_EXECUTABLE} -p "${CMAKE_CURRENT_SOURCE_DIR}/android" "-PbuildDir=${CMAKE_CURRENT_BINARY_DIR}/android/build" assemble ) add_custom_target(thrift_aar ALL DEPENDS ${THRIFT_AAR}) else() if(NOT JAVA_INSTALL_DIR) if(IS_ABSOLUTE "${LIB_INSTALL_DIR}") set(JAVA_INSTALL_DIR "${LIB_INSTALL_DIR}/java") else() set(JAVA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/java") endif() endif() if(IS_ABSOLUTE "${DOC_INSTALL_DIR}") set(JAVA_DOC_INSTALL_DIR "${DOC_INSTALL_DIR}/java") else() set(JAVA_DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${DOC_INSTALL_DIR}/java") endif() set(PRELEASE "true") if (CMAKE_BUILD_TYPE MATCHES DEBUG) set(PRELEASE "false") endif () file(GLOB_RECURSE THRIFTJAVA_SOURCES LIST_DIRECTORIES false "${CMAKE_CURRENT_SOURCE_DIR}/src/*") add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/libs/libthrift.jar" COMMENT "Building Java library using Gradle" COMMAND ${GRADLE_EXECUTABLE} ${GRADLE_OPTS} assemble --console=plain --no-daemon -Prelease=${PRELEASE} -Pthrift.version=${thrift_VERSION} "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build" DEPENDS ${THRIFTJAVA_SOURCES} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) add_custom_target(ThriftJava ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/build/libs/libthrift.jar") # Enable publishing from CMake if the publishing information is provided add_custom_target(MavenPublish COMMENT "Publishing Java Library to Apache Maven staging" DEPENDS ThriftJava COMMAND ${GRADLE_EXECUTABLE} ${GRADLE_OPTS} clean uploadArchives --console=plain --no-daemon -Prelease=${PRELEASE} -Pthrift.version=${thrift_VERSION} "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) # Hook the CMake install process to the results from make ALL. # This works best when 'make all && sudo make install/fast' is used. # Using slash to end the source location to avoid copying the directory path. install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build/libs/ DESTINATION ${JAVA_INSTALL_DIR} FILES_MATCHING PATTERN "libthrift-${thrift_VERSION}.jar") install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build/deps/ DESTINATION ${JAVA_INSTALL_DIR} FILES_MATCHING PATTERN "*.jar") install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build/docs/javadoc/ DESTINATION ${JAVA_DOC_INSTALL_DIR}) if(BUILD_TESTING) add_test(NAME JavaTest COMMAND ${GRADLE_EXECUTABLE} ${GRADLE_OPTS} test --console=plain --no-daemon -Prelease=${PRELEASE} -Pthrift.version=${thrift_VERSION} "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build" "-Pthrift.compiler=${THRIFT_COMPILER}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif() endif() thrift-0.23.0/lib/java/build.gradle0000664000175000017500000000442215167543515017342 0ustar00buildbuild00000000000000/* * 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 the legacy plugin classpath for Clover so it can be loaded optionally buildscript { // strictly enforce the minimum version of Java required to build and fail fast if (JavaVersion.current() < JavaVersion.VERSION_1_8) { throw new GradleException("The java version used is ${JavaVersion.current()}, but must be at least ${JavaVersion.VERSION_1_8}") } repositories { mavenCentral() google() gradlePluginPortal() } dependencies { classpath 'com.bmuschko:gradle-clover-plugin:3.0.7' } } plugins { id 'java-library' id 'maven-publish' id 'signing' id 'pmd' id 'com.github.johnrengelman.shadow' version '8.1.1' id "com.github.spotbugs" version "5.2.5" id "com.diffplug.spotless" version "8.4.0" } description = 'Apache Thrift Java Library' defaultTasks 'build' // Version components for this project group = property('thrift.groupid') if (Boolean.parseBoolean(project.release)) { version = property('thrift.version') } else { version = property('thrift.version') + '-SNAPSHOT' } // Keeping the rest of the build logic in functional named scripts for clarity apply from: 'gradle/environment.gradle' apply from: 'gradle/sourceConfiguration.gradle' apply from: 'gradle/generateTestThrift.gradle' apply from: 'gradle/unitTests.gradle' apply from: 'gradle/cloverCoverage.gradle' apply from: 'gradle/functionalTests.gradle' apply from: 'gradle/publishing.gradle' apply from: 'gradle/codeQualityChecks.gradle' thrift-0.23.0/lib/java/gradle.properties0000664000175000017500000000262615170007142020424 0ustar00buildbuild00000000000000# 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.23.0 thrift.groupid=org.apache.thrift release=false # Local Install paths install.path=/usr/local/lib install.javadoc.path=/usr/local/lib # Test execution properties testPort=9090 # Test with Clover Code coverage (disabled by default) cloverEnabled=false # Maven dependency download locations mvn.repo=https://repo1.maven.org/maven2 apache.repo=https://repository.apache.org/content/repositories/releases # Apache Maven publish license=https://www.apache.org/licenses/LICENSE-2.0.txt maven-repository-url=https://repository.apache.org/service/local/staging/deploy/maven2 maven-repository-id=apache.releases.https # Dependency versions httpclient.version=5.2.1 httpcore.version=5.2 slf4j.version=1.7.36 servlet.version=5.0.0 tomcat.embed.version=10.1.4 junit.version=5.9.1 mockito.version=5.3.0 javax.annotation.version=2.1.1 commons-lang3.version=3.18.0 org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED thrift-0.23.0/lib/java/README.md0000664000175000017500000002060215165535636016343 0ustar00buildbuild00000000000000Thrift Java Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Building and installing from source =================================== When using a CMake build from the source distribution on Linux the easiest way to build and install is this simple command line: make all && sudo make install/fast It is important to use the install/fast option to eliminate the automatic rebuild by dependency that causes issues because the build tooling is designed to work with cached files in the user home directory during the build process. Instead this builds the code in the expected local build tree and then uses CMake install code to copy to the target destination. Building Thrift with Gradle without CMake/Autoconf ================================================== 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 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 the [gradle documentation](https://docs.gradle.org/current/userguide/installation.html), or following this step (which is also done in the travis CI docker images): ```bash export GRADLE_VERSION="8.4" # install dependencies apt-get install -y --no-install-recommends openjdk-17-jdk-headless wget unzip # download gradle distribution wget https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip -q -O /tmp/gradle-$GRADLE_VERSION-bin.zip # check binary integrity echo "3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae /tmp/gradle-$GRADLE_VERSION-bin.zip" | sha256sum -c - # unzip and install 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 ``` After the above step, `gradle` binary will be available in `/usr/local/bin/`. You can further choose to locally create the gradle wrapper (even if they are ignored) using: ```bash gradle wrapper --gradle-version $GRADLE_VERSION ``` To compile the Java Thrift libraries, simply do the following: ```bash gradle ``` Yep, that's easy. Look for `libthrift-.jar` in the build/libs directory. The default build will run the unit tests which expect a usable Thrift compiler to exist on the system. You have two choices for that. * Build the Thrift executable from source at the default location in the source tree. The project is configured to look for it there. * Install the published binary distribution to have Thrift executable in a known location and add the path to the ~/.gradle/gradle.properties file using the property name "thrift.compiler". For example this would set the path in a Windows box if Thrift was installed under C:\Thrift thrift.compiler=C:/Thrift/thrift.exe To just build the library without running unit tests you simply do this. ```bash gradle assemble ``` To install the library in the local Maven repository location where other Maven or Gradle builds can reference it simply do this. ```bash gradle publishToMavenLocal ``` The library will be placed in your home directory under .m2/repository To include Thrift in your applications simply add libthrift.jar to your classpath, or install if in your default system classpath of choice. Build Thrift behind a proxy: ```bash gradle -Dhttp.proxyHost=myproxyhost -Dhttp.proxyPort=8080 -Dhttp.proxyUser=thriftuser -Dhttp.proxyPassword=topsecret ``` or via ```bash ./configure --with-java GRADLE_OPTS='-Dhttp.proxyHost=myproxyhost -Dhttp.proxyPort=8080 -Dhttp.proxyUser=thriftuser -Dhttp.proxyPassword=topsecret' ``` Unit Test HTML Reports ====================== The build will automatically generate an HTML Unit Test report. This can be found under build/reports/tests/test/index.html. It can be viewed with a browser directly from that location. Clover Code Coverage for Thrift =============================== The build will optionally generate Clover Code coverage if the Gradle property `cloverEnabled=true` is set in ~/.gradle/gradle.properties or on the command line via `-PcloverEnabled=true`. The generated report can be found under the location build/reports/clover/html/index.html. It can be viewed with a browser directly from that location. Additionally, a PDF report is generated and is found under the location build/reports/clover/clover.pdf. The following command will build, unit test, and generate Clover reports: ```bash gradle -PcloverEnabled=true ``` Publishing Maven Artifacts to Maven Central =========================================== The Automake build generates a Makefile that provides the correct parameters when you run the build provided the configure.ac has been set with the correct version number. The Gradle build will receive the correct value for the build. The same applies to the CMake build, the value from the configure.ac file will be used if you execute these commands: ```bash make maven-publish -- This is for an Automake Linux build make MavenPublish -- This is for a CMake generated build ``` The `publish` task in Gradle is preconfigured with all necessary details to sign and publish the artifacts from the build to the Apache Maven staging repository. The task requires the following externally provided properties to authenticate to the repository and sign the artifacts. The preferred approach is to create or edit the ~/.gradle/gradle.properties file and add the following properties to it. ```properties # Signing key information for artifacts PGP signature (values are examples) signing.keyId=24875D73 signing.password=secret signing.secretKeyRingFile=/Users/me/.gnupg/secring.gpg # Apache Maven staging repository user credentials mavenUser=meMyselfAndI mavenPassword=MySuperAwesomeSecretPassword ``` NOTE: If you do not have a secring.gpg file, see the [gradle signing docs](https://docs.gradle.org/current/userguide/signing_plugin.html) for instructions on how to generate it. It is also possible to manually publish using the Gradle build directly. With the key information and credentials in place the following will generate if needed the build artifacts and proceed to publish the results. ```bash gradle -Prelease=true publish ``` It is also possible to override the target repository for the Maven Publication by using a Gradle property, for example you can publish signed JAR files to your company internal server if you add this to the command line or in the ~/.gradle/gradle.properties file. The URL below assumes a Nexus Repository. ```properties maven-repository-url=https://my.company.com/service/local/staging/deploy/maven2 ``` Or the same on the command line: ```bash gradle -Pmaven-repository-url=https://my.company.com/service/local/staging/deploy/maven2 -Prelease=true -Pthrift.version=0.11.0 publish ``` Dependencies ============ Gradle http://gradle.org/ # Breaking Changes ## 0.13.0 * The signature of the 'process' method in TAsyncProcessor and TProcessor has changed to remove the boolean return type and instead rely on Exceptions. * Per THRIFT-4805, TSaslTransportException has been removed. The same condition is now covered by TTansportException, where `TTransportException.getType() == END_OF_FILE`. ## 0.12.0 The access modifier of the AutoExpandingBuffer class has been changed from public to default (package) and will no longer be accessible by third-party libraries. The access modifier of the ShortStack class has been changed from public to default (package) and will no longer be accessible by third-party libraries. thrift-0.23.0/lib/java/android/0000775000175000017500000000000015165535636016504 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/android/src/0000775000175000017500000000000015165535636017273 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/android/src/main/0000775000175000017500000000000015165535636020217 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/android/src/main/AndroidManifest.xml0000664000175000017500000000015415165535636024010 0ustar00buildbuild00000000000000 thrift-0.23.0/lib/java/android/settings.gradle0000664000175000017500000000003215165535636021517 0ustar00buildbuild00000000000000rootProject.name='thrift' thrift-0.23.0/lib/java/android/build.gradle0000664000175000017500000000302615165535636020764 0ustar00buildbuild00000000000000/* * 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. */ apply plugin: 'com.android.library' android { compileSdkVersion 23 buildToolsVersion "23.0.1" useLibrary 'org.apache.http.legacy' sourceSets.main.java { srcDir '../src' exclude 'org/apache/thrift/transport/TSaslClientTransport.java' exclude 'org/apache/thrift/transport/TSaslServerTransport.java' exclude 'org/apache/thrift/transport/TSaslTransport.java' } } repositories { mavenCentral() } dependencies { compile 'org.slf4j:slf4j-api:1.7.13' compile 'javax.servlet:servlet-api:2.5' compile 'org.apache.httpcomponents:httpcore:4.4.4' } buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' } } thrift-0.23.0/lib/java/gradle/0000775000175000017500000000000015167543515016317 5ustar00buildbuild00000000000000thrift-0.23.0/lib/java/gradle/cloverCoverage.gradle0000664000175000017500000000270515165535636022454 0ustar00buildbuild00000000000000/* * 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. */ // Following Gradle best practices to keep build logic organized // Keep this as an optional feature for now, disabled by default if (Boolean.parseBoolean(project.cloverEnabled)) { apply plugin: 'com.bmuschko.clover' dependencies { clover 'org.openclover:clover:4.2.+' } clover { testIncludes = ['**/Test*.java'] // Exclude the generated test code from code coverage testExcludes = ['thrift/test/Test*.java'] compiler { encoding = 'UTF-8' debug = true } report { html = true pdf = true } } build.dependsOn cloverGenerateReport } thrift-0.23.0/lib/java/gradle/generateTestThrift.gradle0000664000175000017500000001354515165535636023325 0ustar00buildbuild00000000000000/* * 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. */ // Following Gradle best practices to keep build logic organized // Generated code locations for Unit tests ext.genSrc = file("$buildDir/gen-java") ext.genBeanSrc = file("$buildDir/gen-javabean") ext.genReuseSrc = file("$buildDir/gen-javareuse") ext.genFullCamelSrc = file("$buildDir/gen-fullcamel") ext.genOptionTypeJdk8Src = file("$buildDir/gen-option-type-jdk8") ext.genUnsafeSrc = file("$buildDir/gen-unsafe") ext.genDefinitionOrderTestASrc = file("$buildDir/resources/test/definition-order-test/a") ext.genDefinitionOrderTestBSrc = file("$buildDir/resources/test/definition-order-test/b") // Add the generated code directories to the test source set sourceSets { test.java.srcDirs genSrc, genBeanSrc, genReuseSrc, genFullCamelSrc, genUnsafeSrc, genOptionTypeJdk8Src } // ---------------------------------------------------------------------------- // Code generation for Unit Testing // A callable closure to make this easier ext.thriftCompile = { Task task, String thriftFileName, String generator = 'java:jakarta_annotations', File outputDir = genSrc -> def thriftFile = file("$thriftRoot/test/$thriftFileName") if (!thriftFile.exists()) { thriftFile = file("$projectDir/src/test/resources/$thriftFileName") assert thriftFile.exists(), "can't find $thriftFile" } task.inputs.file thriftFile task.outputs.dir outputDir task.doLast { outputDir.mkdirs() def result = exec { executable file(thriftCompiler) args '--gen', generator args '-out', outputDir args thriftFile standardOutput = task.outputBuffer errorOutput = task.outputBuffer ignoreExitValue = true } if (result.exitValue != 0) { // Only show the Thrift compiler output on failures, cuts down on noise! println task.outputBuffer.toString() result.rethrowFailure() } } } task generate(group: 'Build') { description = 'Generate all unit test Thrift sources' compileTestJava.dependsOn it } task generateJava(group: 'Build') { description = 'Generate the thrift gen-java source' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'ThriftTest.thrift') thriftCompile(it, 'JavaTypes.thrift') thriftCompile(it, 'DebugProtoTest.thrift') thriftCompile(it, 'DoubleConstantsTest.thrift') thriftCompile(it, 'OptionalRequiredTest.thrift') thriftCompile(it, 'ManyOptionals.thrift') thriftCompile(it, 'JavaDeepCopyTest.thrift') thriftCompile(it, 'EnumContainersTest.thrift') thriftCompile(it, 'JavaBinaryDefault.thrift') thriftCompile(it, 'VoidMethExceptionsTest.thrift') thriftCompile(it, 'JavaAnnotationTest.thrift') thriftCompile(it, 'partial/thrift_test_schema.thrift') thriftCompile(it, 'FuzzTest.thrift') } task generateOptionalTypeJava(group: 'Build') { description = 'Generate the thrift gen-option-type-jdk8 source' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'JavaOptionTypeJdk8Test.thrift', 'java:option_type=jdk8,jakarta_annotations', genOptionTypeJdk8Src) } task generateBeanJava(group: 'Build') { description = 'Generate the thrift gen-javabean source' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'JavaBeansTest.thrift', 'java:beans,nocamel,future_iface,jakarta_annotations', genBeanSrc) } task generateReuseJava(group: 'Build') { description = 'Generate the thrift gen-javareuse source' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'FullCamelTest.thrift', 'java:fullcamel,future_iface,jakarta_annotations', genFullCamelSrc) } task generateFullCamelJava(group: 'Build') { description = 'Generate the thrift gen-fullcamel source' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'ReuseObjects.thrift', 'java:reuse_objects,jakarta_annotations', genReuseSrc) } task generateUnsafeBinariesJava(group: 'Build') { description = 'Generate the thrift gen-unsafebinaries source' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'UnsafeTypes.thrift', 'java:unsafe_binaries,jakarta_annotations', genUnsafeSrc) } task generateWithAnnotationMetadata(group: 'Build') { description = 'Generate with annotation enabled and add to the default source' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'JavaAnnotationTest.thrift', 'java:annotations_as_metadata,jakarta_annotations', genSrc) } task generateJavaDefinitionOrderTestJava(group: 'Build') { description = 'Generate fields defined in different order and add to build dir so we can compare them' generate.dependsOn it ext.outputBuffer = new ByteArrayOutputStream() thriftCompile(it, 'JavaDefinitionOrderA.thrift', 'java:jakarta_annotations', genDefinitionOrderTestASrc) thriftCompile(it, 'JavaDefinitionOrderB.thrift', 'java:jakarta_annotations', genDefinitionOrderTestBSrc) } thrift-0.23.0/lib/java/gradle/unitTests.gradle0000664000175000017500000000625715167543515021513 0ustar00buildbuild00000000000000/* * 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. */ // Following Gradle best practices to keep build logic organized // Bundle the test classes in a JAR for other Ant based builds task testJar(type: Jar, group: 'Build') { description = 'Assembles a jar archive containing the test classes.' project.test.dependsOn it archiveClassifier = 'test' from sourceSets.test.output } // ---------------------------------------------------------------------------- // Unit test tasks and configurations // Help the up to date algorithm to make these tests done ext.markTaskDone = { task -> def buildFile = file("$buildDir/${task.name}.flag") task.inputs.files task.classpath task.outputs.file buildFile task.doLast { buildFile.text = 'Passed!' } } task deprecatedEqualityTest(type: JavaExec, group: 'Verification') { description = 'Run the non-JUnit test suite ' classpath = sourceSets.test.runtimeClasspath mainClass.set('org.apache.thrift.test.EqualityTest') markTaskDone(it) } task deprecatedJavaBeansTest(type: JavaExec, group: 'Verification') { description = 'Run the non-JUnit test suite ' classpath = sourceSets.test.runtimeClasspath mainClass.set('org.apache.thrift.test.JavaBeansTest') markTaskDone(it) } // Main Unit Test task configuration test { description="Run the full test suite" dependsOn deprecatedEqualityTest, deprecatedJavaBeansTest // Allow repeating tests even after successful execution if (project.hasProperty('rerunTests')) { outputs.upToDateWhen { false } } include '**/Test*.class' exclude '**/Test*\$*.class' // https://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle useJUnitPlatform() { // https://junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution systemProperty("junit.jupiter.execution.parallel.enabled", "true") systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent") systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent") } maxHeapSize = '512m' systemProperties = [ 'test.port': "${testPort}", 'javax.net.ssl.trustStore': "${projectDir}/src/crossTest/resources/.truststore", 'javax.net.ssl.trustStorePassword': 'thrift', 'javax.net.ssl.keyStore': "${projectDir}/src/crossTest/resources/.serverkeystore", 'javax.net.ssl.keyStorePassword': 'thrift' ] } thrift-0.23.0/lib/java/gradle/functionalTests.gradle0000664000175000017500000001724315167543515022673 0ustar00buildbuild00000000000000/* * 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. */ // Following Gradle best practices to keep build logic organized // ---------------------------------------------------------------------------- // Functional testing harness creation. This helps run the cross-check tests. // The Makefile precross target invokes the shadowJar task and the tests.json // code is changed to call runclient or runserver as needed. // ---------------------------------------------------------------------------- // Cross Test sources are separated in their own sourceSet // sourceSets { crossTest { java { } } } // see https://docs.gradle.org/current/userguide/java_library_plugin.html // 1. defines cross test implementation that includes all test implementation, which in turn // contains all implementation dependencies // 2. defines cross test runtime that further includes test runtime only dependencies // 3. the cross test implementation will need to depends on main and test output // 4. shadow jar will package both main and test source set, along with cross test runtime dependencies configurations { crossTestImplementation { description "implementation for cross test" extendsFrom testImplementation } crossTestRuntime { description "runtime dependencies for cross test" extendsFrom crossTestImplementation, testRuntimeOnly } } dependencies { crossTestImplementation "org.apache.tomcat.embed:tomcat-embed-core:${tomcatEmbedVersion}" crossTestImplementation sourceSets.main.output crossTestImplementation sourceSets.test.output } // I am using shadow plugin to make a self contained functional test Uber JAR that // eliminates startup problems with wrapping the cross-check harness in Gradle. // This is used by the runner scripts as the single classpath entry which // allows the process to be as lightweight as it can. shadowJar { description = 'Assemble a test JAR file for cross-check execution' // make sure the runners are created when this runs dependsOn 'generateRunnerScriptForClient', 'generateRunnerScriptForNonblockingClient', 'generateRunnerScriptForServer', 'generateRunnerScriptForNonblockingServer', 'generateRunnerScriptForTServletServer' archiveBaseName.set('functionalTest') destinationDirectory = file("$buildDir/functionalTestJar") // We do not need a version number for this internal jar archiveVersion.set(null) // Bundle the complete set of unit test classes including generated code // and the runtime dependencies in one JAR to expedite execution. // see https://imperceptiblethoughts.com/shadow/custom-tasks/ from sourceSets.test.output from sourceSets.crossTest.output configurations = [project.configurations.crossTestRuntime] } // Common script runner configuration elements def scriptExt = '' def execExt = '' def scriptHead = '#!/bin/bash' def args = '$*' // Although this is marked internal it is an available and stable interface if (org.gradle.internal.os.OperatingSystem.current().windows) { scriptExt = '.bat' execExt = '.exe' scriptHead = '@echo off' args = '%*' } // The Java executable to use with the runner scripts def javaExe = file("${System.getProperty('java.home')}/bin/java${execExt}").canonicalPath // The common Uber jar path def jarPath = shadowJar.archiveFile.get().asFile.canonicalPath def trustStore = file("${projectDir}/src/crossTest/resources/.truststore").canonicalPath def serverKeyStore = file("${projectDir}/src/crossTest/resources/.serverkeystore").canonicalPath def clientKeyStore = file("${projectDir}/src/crossTest/resources/.clientkeystore").canonicalPath task generateRunnerScriptForClient(group: 'Build') { description = 'Generate a runner script for cross-check tests with TestClient' def clientFile = file("$buildDir/runclient${scriptExt}") def runClientText = """\ ${scriptHead} "${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$clientKeyStore" -Djavax.net.ssl.keyStorePassword=thrift "-Djavax.net.ssl.trustStore=$trustStore" -Djavax.net.ssl.trustStorePassword=thrift org.apache.thrift.test.TestClient $args """ inputs.property 'runClientText', runClientText outputs.file clientFile doLast { clientFile.parentFile.mkdirs() clientFile.text = runClientText clientFile.setExecutable(true, false) } } task generateRunnerScriptForNonblockingClient(group: 'Build') { description = 'Generate a runner script for cross-check tests with TestNonblockingClient' def clientFile = file("$buildDir/runnonblockingclient${scriptExt}") def runClientText = """\ ${scriptHead} "${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$clientKeyStore" -Djavax.net.ssl.keyStorePassword=thrift "-Djavax.net.ssl.trustStore=$trustStore" -Djavax.net.ssl.trustStorePassword=thrift org.apache.thrift.test.TestNonblockingClient $args """ inputs.property 'runClientText', runClientText outputs.file clientFile doLast { clientFile.parentFile.mkdirs() clientFile.text = runClientText clientFile.setExecutable(true, false) } } task generateRunnerScriptForServer(group: 'Build') { description = 'Generate a runner script for cross-check tests with TestServer' def serverFile = file("$buildDir/runserver${scriptExt}") def runServerText = """\ ${scriptHead} "${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$serverKeyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestServer $args """ inputs.property 'runServerText', runServerText outputs.file serverFile doLast { serverFile.parentFile.mkdirs() serverFile.text = runServerText serverFile.setExecutable(true, false) } } task generateRunnerScriptForNonblockingServer(group: 'Build') { description = 'Generate a runner script for cross-check tests with TestNonblockingServer' def serverFile = file("$buildDir/runnonblockingserver${scriptExt}") def runServerText = """\ ${scriptHead} "${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$serverKeyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestNonblockingServer $args """ inputs.property 'runServerText', runServerText outputs.file serverFile doLast { serverFile.parentFile.mkdirs() serverFile.text = runServerText serverFile.setExecutable(true, false) } } task generateRunnerScriptForTServletServer(group: 'Build') { description = 'Generate a runner script for cross-check tests with TestTServletServer' def serverFile = file("$buildDir/runservletserver${scriptExt}") def runServerText = """\ ${scriptHead} "${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$serverKeyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestTServletServer $args """ inputs.property 'runServerText', runServerText outputs.file serverFile doLast { serverFile.parentFile.mkdirs() serverFile.text = runServerText serverFile.setExecutable(true, false) } } thrift-0.23.0/lib/java/gradle/publishing.gradle0000664000175000017500000000677215165535636021662 0ustar00buildbuild00000000000000/* * 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. */ // Following Gradle best practices to keep build logic organized // ---------------------------------------------------------------------------- // Installation subtasks, not used currently, we use "make install/fast" task installDist(type: Copy, group: 'Install') { description = "Copy Thrift JAR and dependencies into $installPath location" destinationDir = file(installPath) from jar from configurations.implementation } task installJavadoc(type: Copy, group: 'Install', dependsOn: javadoc) { description = "Install Thrift JavaDoc into $installJavadocPath location" destinationDir = file(installJavadocPath) from javadoc.destinationDir } java { withJavadocJar() withSourcesJar() } // skip shadow jar from publishing. Workaround for https://github.com/johnrengelman/shadow/issues/651 components.java.withVariantsFromConfiguration(configurations.shadowRuntimeElements) { skip() } publishing { publications { mavenJava(MavenPublication) { artifactId = "libthrift" from components.java pom { name = 'Apache Thrift' description = 'Thrift is a software framework for scalable cross-language services development.' url = 'http://thrift.apache.org' licenses { license { name = 'The Apache Software License, Version 2.0' url = "${project.license}" distribution = 'repo' } } developers { developer { id = 'dev' name = 'Apache Thrift Developers' email = 'dev@thrift.apache.org' } } scm { url = 'https://github.com/apache/thrift' connection = 'scm:git:https://github.com/apache/thrift.git' developerConnection = 'scm:git:git@github.com:apache/thrift.git' } } } } repositories { maven { url = mavenRepositoryUrl if (project.hasProperty("mavenUser") && project.hasProperty("mavenPassword")) { credentials { username = mavenUser password = mavenPassword } } } } } // Signing configuration, optional, only when release and publish is activated signing { required { !version.endsWith("SNAPSHOT") && gradle.taskGraph.hasTask("publish") } sign publishing.publications.mavenJava } javadoc { if(JavaVersion.current().isJava9Compatible()) { options.addBooleanOption('html5', true) } } thrift-0.23.0/lib/java/gradle/sourceConfiguration.gradle0000664000175000017500000001133715165535636023537 0ustar00buildbuild00000000000000/* * 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. */ // Following Gradle best practices to keep build logic organized // ---------------------------------------------------------------------------- // Compiler configuration details // We are using Java 17 (latest LTS) toolchain to compile. // This enables decoupling from the Java version that gradle runs, from // the actual JDK version for the project. For more details, see // https://docs.gradle.org/current/userguide/toolchains.html // // The '--release' option added below makes sure that even if we are using // the toolchain version > 11, the final artifact is at version 11. There is // also a runtime CI that's based on Java 11 to ensure that. java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.debug = true options.deprecation = true // the following is to build with Java 8 specifications, even when building with later JDK options.release = 8 options.compilerArgs += [ '-Werror', '-Xlint:deprecation', '-Xlint:cast', '-Xlint:empty', '-Xlint:fallthrough', '-Xlint:finally', '-Xlint:overrides', // we can't enable -Xlint:unchecked just yet ] } tasks.withType(Javadoc) { failOnError false options.addStringOption('Xdoclint:none', '-quiet') options.addStringOption('encoding', 'UTF-8') options.addStringOption('charSet', 'UTF-8') } // ---------------------------------------------------------------------------- // Jar packaging details processResources { into('META-INF') { from "$thriftRoot/LICENSE" from "$thriftRoot/NOTICE" rename('(.+)', '$1.txt') } } jar { project.test.dependsOn it manifest { attributes([ "Implementation-Version": "${project.version}", "Automatic-Module-Name": "${project.group}", "Bundle-ManifestVersion": "2", "Bundle-SymbolicName": "${project.group}", "Bundle-Name": "Apache Thrift", "Bundle-Version": "${project.version}", "Bundle-Description": "Apache Thrift library", "Bundle-License": "${project.license}", "Bundle-ActivationPolicy": "lazy", "Export-Package": "${project.group}.async;uses:=\"${project.group}.protocol,${project.group}.transport,org.slf4j,${project.group}\";version=\"${project.version}\",${project.group}.protocol;uses:=\"${project.group}.transport,${project.group},${project.group}.scheme\";version=\"${project.version}\",${project.group}.server;uses:=\"${project.group}.transport,${project.group}.protocol,${project.group},org.slf4j,javax.servlet,javax.servlet.http\";version=\"${project.version}\",${project.group}.transport;uses:=\"${project.group}.protocol,${project.group},org.apache.http.client,org.apache.http.params,org.apache.http.entity,org.apache.http.client.methods,org.apache.http,org.slf4j,javax.net.ssl,javax.net,javax.security.sasl,javax.security.auth.callback\";version=\"${project.version}\",${project.group};uses:=\"${project.group}.protocol,${project.group}.async,${project.group}.server,${project.group}.transport,org.slf4j,org.apache.log4j,${project.group}.scheme\";version=\"${project.version}\",${project.group}.meta_data;uses:=\"${project.group}\";version=\"${project.version}\",${project.group}.scheme;uses:=\"${project.group}.protocol,${project.group}\";version=\"${project.version}\",${project.group}.annotation;version=\"${project.version}\"", "Import-Package": "javax.net,javax.net.ssl,javax.security.auth.callback,javax.security.sasl,javax.servlet;resolution:=optional,javax.servlet.http;resolution:=optional,org.slf4j;resolution:=optional;version=\"[1.4,2)\",org.apache.http.client;resolution:=optional,org.apache.http.params;resolution:=optional,org.apache.http.entity;resolution:=optional,org.apache.http.client.methods;resolution:=optional,org.apache.http;resolution:=optional" ]) } } thrift-0.23.0/lib/java/gradle/environment.gradle0000664000175000017500000000600015165535636022042 0ustar00buildbuild00000000000000/* * 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. */ // Following Gradle best practices to keep build logic organized // Override the build directory if CMake is used (allows for out-of-tree-builds) if (hasProperty('build.dir')) { buildDir = file(property('build.dir')) } // In order to remain compatible with other Ant based builds in the system // we convert the gradle.properties into DSL friendly camelCased properties ext.installPath = property('install.path') ext.installJavadocPath = property('install.javadoc.path') ext.thriftRoot = rootProject.file('../..') ext.thriftCompiler = findProperty('thrift.compiler') ?: "$thriftRoot/compiler/cpp/thrift" ext.mvnRepo = property('mvn.repo') ext.apacheRepo = property('apache.repo') ext.mavenRepositoryUrl = property('maven-repository-url') // Versions used in this project ext.httpclientVersion = property('httpclient.version') ext.httpcoreVersion = property('httpcore.version') ext.servletVersion = property('servlet.version') ext.tomcatEmbedVersion = property('tomcat.embed.version') ext.slf4jVersion = property('slf4j.version') ext.junitVersion = property('junit.version') ext.mockitoVersion = property('mockito.version') ext.javaxAnnotationVersion = property('javax.annotation.version') ext.commonsLang3Version = property('commons-lang3.version') // In this section you declare where to find the dependencies of your project repositories { maven { name 'Maven Central Repository' url mvnRepo } maven { name 'Apache Maven Repository' url apacheRepo } } dependencies { implementation "org.slf4j:slf4j-api:${slf4jVersion}" implementation "org.apache.httpcomponents.client5:httpclient5:${httpclientVersion}" implementation "org.apache.httpcomponents.core5:httpcore5:${httpcoreVersion}" implementation "jakarta.servlet:jakarta.servlet-api:${servletVersion}" implementation "jakarta.annotation:jakarta.annotation-api:${javaxAnnotationVersion}" implementation "org.apache.commons:commons-lang3:${commonsLang3Version}" 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}" } thrift-0.23.0/lib/java/gradle/codeQualityChecks.gradle0000664000175000017500000000206315165535636023107 0ustar00buildbuild00000000000000 // ================================================================= // Configure the Gradle code quality plugins here. // dependencies { spotbugs configurations.spotbugsPlugins.dependencies spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0' } // see https://spotbugs-gradle-plugin.netlify.app/com/github/spotbugs/snom/spotbugsextension spotbugs { ignoreFailures = true toolVersion = '4.5.3' effort = 'max' reportLevel = 'low' excludeFilter = file('code_quality_tools/findbugs-filter.xml') } // see https://spotbugs-gradle-plugin.netlify.app/com/github/spotbugs/snom/spotbugstask spotbugsMain { reports { text.enabled = false html.enabled = true xml.enabled = false } } pmd { ignoreFailures = true toolVersion = '6.0.0' sourceSets = [ sourceSets.main ] ruleSets = [ 'java-basic' ] } tasks.withType(Pmd) { reports { html.required = true xml.required = false } } spotless { java { target 'src/**/*.java' googleJavaFormat() } } thrift-0.23.0/lib/java/Makefile.in0000644000175000017500000004470715170007167017130 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/java ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ build.gradle \ gradle.properties \ settings.gradle \ gradle \ CMakeLists.txt \ coding_standards.md \ android \ src \ code_quality_tools \ README.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/java/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/java/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-exec-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile export CLASSPATH all-local: $(GRADLE) $(GRADLE_OPTS) assemble \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ --console=plain install-exec-hook: $(GRADLE) $(GRADLE_OPTS) publishToMavenLocal \ -Prelease=true \ -Pinstall.path=$(DESTDIR)$(JAVA_PREFIX) \ -Pinstall.javadoc.path=$(DESTDIR)$(docdir)/java \ -Pthrift.version=$(PACKAGE_VERSION) \ --console=plain clean-local: $(GRADLE) $(GRADLE_OPTS) clean --console=plain precross: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) shadowJar \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain check-local: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) test \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain maven-publish: $(GRADLE) $(GRADLE_OPTS) publish \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ --console=plain distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/java/Makefile.am0000664000175000017500000000357315165535636017130 0ustar00buildbuild00000000000000# # 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. # export CLASSPATH all-local: $(GRADLE) $(GRADLE_OPTS) assemble \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ --console=plain install-exec-hook: $(GRADLE) $(GRADLE_OPTS) publishToMavenLocal \ -Prelease=true \ -Pinstall.path=$(DESTDIR)$(JAVA_PREFIX) \ -Pinstall.javadoc.path=$(DESTDIR)$(docdir)/java \ -Pthrift.version=$(PACKAGE_VERSION) \ --console=plain clean-local: $(GRADLE) $(GRADLE_OPTS) clean --console=plain precross: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) shadowJar \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain check-local: $(THRIFT) $(GRADLE) $(GRADLE_OPTS) test \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ -Pthrift.compiler=$(THRIFT) \ --console=plain maven-publish: $(GRADLE) $(GRADLE_OPTS) publish \ -Prelease=true \ -Pthrift.version=$(PACKAGE_VERSION) \ --console=plain distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ build.gradle \ gradle.properties \ settings.gradle \ gradle \ CMakeLists.txt \ coding_standards.md \ android \ src \ code_quality_tools \ README.md thrift-0.23.0/lib/javame/0000775000175000017500000000000015165535636015406 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/0000775000175000017500000000000015165535636016175 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/org/0000775000175000017500000000000015165535636016764 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/org/apache/0000775000175000017500000000000015165535636020205 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/org/apache/thrift/0000775000175000017500000000000015165535636021505 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/org/apache/thrift/TApplicationException.java0000664000175000017500000000707615165535636026630 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TStruct; import org.apache.thrift.protocol.TType; /** * Application level exception * */ public class TApplicationException extends TException { private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int UNKNOWN_METHOD = 1; public static final int INVALID_MESSAGE_TYPE = 2; public static final int WRONG_METHOD_NAME = 3; public static final int BAD_SEQUENCE_ID = 4; public static final int MISSING_RESULT = 5; public static final int INTERNAL_ERROR = 6; public static final int PROTOCOL_ERROR = 7; public static final int INVALID_TRANSFORM = 8; public static final int INVALID_PROTOCOL = 9; public static final int UNSUPPORTED_CLIENT_TYPE = 10; protected int type_ = UNKNOWN; public TApplicationException() { super(); } public TApplicationException(int type) { super(); type_ = type; } public TApplicationException(int type, String message) { super(message); type_ = type; } public TApplicationException(String message) { super(message); } public int getType() { return type_; } public static TApplicationException read(TProtocol iprot) throws TException { TField field; iprot.readStructBegin(); String message = null; int type = UNKNOWN; while (true) { field = iprot.readFieldBegin(); if (field.type == TType.STOP) { break; } switch (field.id) { case 1: if (field.type == TType.STRING) { message = iprot.readString(); } else { TProtocolUtil.skip(iprot, field.type); } break; case 2: if (field.type == TType.I32) { type = iprot.readI32(); } else { TProtocolUtil.skip(iprot, field.type); } break; default: TProtocolUtil.skip(iprot, field.type); break; } iprot.readFieldEnd(); } iprot.readStructEnd(); return new TApplicationException(type, message); } public void write(TProtocol oprot) throws TException { TStruct struct = new TStruct("TApplicationException"); TField field = new TField(); oprot.writeStructBegin(struct); if (getMessage() != null) { field.name = "message"; field.type = TType.STRING; field.id = 1; oprot.writeFieldBegin(field); oprot.writeString(getMessage()); oprot.writeFieldEnd(); } field.name = "type"; field.type = TType.I32; field.id = 2; oprot.writeFieldBegin(field); oprot.writeI32(type_); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/TEnum.java0000664000175000017500000000156515165535636023407 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; public interface TEnum { public int getValue(); } thrift-0.23.0/lib/javame/src/org/apache/thrift/TException.java0000664000175000017500000000232515165535636024434 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * Generic exception class for Thrift. * */ public class TException extends Exception { private static final long serialVersionUID = 1L; public TException() { super(); } public TException(String message) { super(message); } public TException(Throwable cause) { super(cause.getMessage()); } public TException(String message, Throwable cause) { super(message); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/TSerializer.java0000664000175000017500000000636315165535636024615 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; /** * Generic utility for easily serializing objects into a byte array or Java * String. * */ public class TSerializer { /** * This is the byte array that data is actually serialized into */ private final ByteArrayOutputStream baos_ = new ByteArrayOutputStream(); /** * This transport wraps that byte array */ private final TIOStreamTransport transport_ = new TIOStreamTransport(baos_); /** * Internal protocol used for serializing objects. */ private TProtocol protocol_; /** * Create a new TSerializer that uses the TBinaryProtocol by default. */ public TSerializer() { this(new TBinaryProtocol.Factory()); } /** * Create a new TSerializer. It will use the TProtocol specified by the * factory that is passed in. * * @param protocolFactory Factory to create a protocol */ public TSerializer(TProtocolFactory protocolFactory) { protocol_ = protocolFactory.getProtocol(transport_); } /** * Serialize the Thrift object into a byte array. The process is simple, * just clear the byte array output, write the object into it, and grab the * raw bytes. * * @param base The object to serialize * @return Serialized object in byte[] format */ public byte[] serialize(TBase base) throws TException { baos_.reset(); base.write(protocol_); return baos_.toByteArray(); } /** * Serialize the Thrift object into a Java string, using a specified * character set for encoding. * * @param base The object to serialize * @param charset Valid JVM charset * @return Serialized object as a String */ public String toString(TBase base, String charset) throws TException { try { return new String(serialize(base), charset); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); } } /** * Serialize the Thrift object into a Java string, using the default JVM * charset encoding. * * @param base The object to serialize * @return Serialized object as a String */ public String toString(TBase base) throws TException { return new String(serialize(base)); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/TServiceClient.java0000664000175000017500000000241415165535636025234 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * A TServiceClient is used to communicate with a TService implementation * across protocols and transports. */ public interface TServiceClient { /** * Get the TProtocol being used as the input (read) protocol. * @return */ public TProtocol getInputProtocol(); /** * Get the TProtocol being used as the output (write) protocol. * @return */ public TProtocol getOutputProtocol(); } thrift-0.23.0/lib/javame/src/org/apache/thrift/TByteArrayOutputStream.java0000664000175000017500000000225115165535636026773 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayOutputStream; /** * Class that allows access to the underlying buf without doing deep * copies on it. * */ public class TByteArrayOutputStream extends ByteArrayOutputStream { public TByteArrayOutputStream(int size) { super(size); } public byte[] get() { return buf; } public int len() { return count; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/TDeserializer.java0000664000175000017500000000560015165535636025117 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; /** * Generic utility for easily deserializing objects from a byte array or Java * String. * */ public class TDeserializer { private final TProtocolFactory protocolFactory_; /** * Create a new TDeserializer that uses the TBinaryProtocol by default. */ public TDeserializer() { this(new TBinaryProtocol.Factory()); } /** * Create a new TDeserializer. It will use the TProtocol specified by the * factory that is passed in. * * @param protocolFactory Factory to create a protocol */ public TDeserializer(TProtocolFactory protocolFactory) { protocolFactory_ = protocolFactory; } /** * Deserialize the Thrift object from a byte array. * * @param base The object to read into * @param bytes The array to read from */ public void deserialize(TBase base, byte[] bytes) throws TException { base.read( protocolFactory_.getProtocol( new TIOStreamTransport( new ByteArrayInputStream(bytes)))); } /** * Deserialize the Thrift object from a Java string, using a specified * character set for decoding. * * @param base The object to read into * @param data The string to read from * @param charset Valid JVM charset */ public void deserialize(TBase base, String data, String charset) throws TException { try { deserialize(base, data.getBytes(charset)); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); } } /** * Deerialize the Thrift object from a Java string, using the default JVM * charset encoding. * * @param base The object to read into * @param data The string to read from * @return Serialized object as a String */ public void toString(TBase base, String data) throws TException { deserialize(base, data.getBytes()); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/TProcessor.java0000664000175000017500000000212315165535636024451 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * A processor is a generic object which operates upon an input stream and * writes to some output stream. * */ public interface TProcessor { public boolean process(TProtocol in, TProtocol out) throws TException; } thrift-0.23.0/lib/javame/src/org/apache/thrift/TFieldRequirementType.java0000664000175000017500000000346715165535636026614 0ustar00buildbuild00000000000000/* * 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * Requirement type constants. * */ public final class TFieldRequirementType { public static final byte REQUIRED = 1; public static final byte OPTIONAL = 2; public static final byte DEFAULT = 3; } thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/0000775000175000017500000000000015165535636023541 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/TTransportFactory.java0000664000175000017500000000251515165535636030057 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Factory class used to create wrapped instance of Transports. * This is used primarily in servers, which get Transports from * a ServerTransport and then may want to mutate them (i.e. create * a BufferedTransport from the underlying base transport) * */ public class TTransportFactory { /** * Return a wrapped instance of the base Transport. * * @param in The base transport * @returns Wrapped Transport */ public TTransport getTransport(TTransport trans) { return trans; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/TTransportException.java0000664000175000017500000000372615165535636030413 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TException; /** * Transport exceptions. * */ public class TTransportException extends TException { private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int NOT_OPEN = 1; public static final int ALREADY_OPEN = 2; public static final int TIMED_OUT = 3; public static final int END_OF_FILE = 4; protected int type_ = UNKNOWN; public TTransportException() { super(); } public TTransportException(int type) { super(); type_ = type; } public TTransportException(int type, String message) { super(message); type_ = type; } public TTransportException(String message) { super(message); } public TTransportException(int type, Throwable cause) { super(cause); type_ = type; } public TTransportException(Throwable cause) { super(cause); } public TTransportException(String message, Throwable cause) { super(message, cause); } public TTransportException(int type, String message, Throwable cause) { super(message, cause); type_ = type; } public int getType() { return type_; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/THttpClient.java0000664000175000017500000001110315165535636026602 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Hashtable; import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection; /** * HTTP implementation of the TTransport interface. Used for working with a * Thrift web services implementation. * */ public class THttpClient extends TTransport { private String url_ = null; private final ByteArrayOutputStream requestBuffer_ = new ByteArrayOutputStream(); private InputStream inputStream_ = null; private HttpConnection connection = null; private int connectTimeout_ = 0; private int readTimeout_ = 0; private Hashtable customHeaders_ = null; public THttpClient(String url) throws TTransportException { url_ = url; } public void setConnectTimeout(int timeout) { connectTimeout_ = timeout; } public void setReadTimeout(int timeout) { readTimeout_ = timeout; } public void setCustomHeaders(Hashtable headers) { customHeaders_ = headers; } public void setCustomHeader(String key, String value) { if (customHeaders_ == null) { customHeaders_ = new Hashtable(); } customHeaders_.put(key, value); } public void open() {} public void close() { if (null != inputStream_) { try { inputStream_.close(); } catch (IOException ioe) { } inputStream_ = null; } if (connection != null) { try { connection.close(); } catch (IOException ioe) { } connection = null; } } public boolean isOpen() { return true; } public int read(byte[] buf, int off, int len) throws TTransportException { if (inputStream_ == null) { throw new TTransportException("Response buffer is empty, no request."); } try { int ret = inputStream_.read(buf, off, len); if (ret == -1) { throw new TTransportException("No more data available."); } return ret; } catch (IOException iox) { throw new TTransportException(iox); } } public void write(byte[] buf, int off, int len) { requestBuffer_.write(buf, off, len); } public void flush() throws TTransportException { // Extract request and reset buffer byte[] data = requestBuffer_.toByteArray(); requestBuffer_.reset(); try { // Create connection object connection = (HttpConnection)Connector.open(url_); // Make the request connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-thrift"); connection.setRequestProperty("Accept", "application/x-thrift"); connection.setRequestProperty("User-Agent", "JavaME/THttpClient"); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setRequestProperty("Keep-Alive", "5000"); connection.setRequestProperty("Http-version", "HTTP/1.1"); connection.setRequestProperty("Cache-Control", "no-transform"); if (customHeaders_ != null) { for (Enumeration e = customHeaders_.keys() ; e.hasMoreElements() ;) { String key = (String)e.nextElement(); String value = (String)customHeaders_.get(key); connection.setRequestProperty(key, value); } } OutputStream os = connection.openOutputStream(); os.write(data); os.close(); int responseCode = connection.getResponseCode(); if (responseCode != HttpConnection.HTTP_OK) { throw new TTransportException("HTTP Response code: " + responseCode); } // Read the responses inputStream_ = connection.openInputStream(); } catch (IOException iox) { System.out.println(iox.toString()); throw new TTransportException(iox); } } } thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/TFramedTransport.java0000664000175000017500000000615715165535636027654 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.ByteArrayInputStream; import org.apache.thrift.TByteArrayOutputStream; /** * Socket implementation of the TTransport interface. To be commented soon! * */ public class TFramedTransport extends TTransport { /** * Underlying transport */ private TTransport transport_ = null; /** * Buffer for output */ private final TByteArrayOutputStream writeBuffer_ = new TByteArrayOutputStream(1024); /** * Buffer for input */ private ByteArrayInputStream readBuffer_ = null; public static class Factory extends TTransportFactory { public Factory() { } public TTransport getTransport(TTransport base) { return new TFramedTransport(base); } } /** * Constructor wraps around another tranpsort */ public TFramedTransport(TTransport transport) { transport_ = transport; } public void open() throws TTransportException { transport_.open(); } public boolean isOpen() { return transport_.isOpen(); } public void close() { transport_.close(); } public int read(byte[] buf, int off, int len) throws TTransportException { if (readBuffer_ != null) { int got = readBuffer_.read(buf, off, len); if (got > 0) { return got; } } // Read another frame of data readFrame(); return readBuffer_.read(buf, off, len); } private void readFrame() throws TTransportException { byte[] i32rd = new byte[4]; transport_.readAll(i32rd, 0, 4); int size = ((i32rd[0] & 0xff) << 24) | ((i32rd[1] & 0xff) << 16) | ((i32rd[2] & 0xff) << 8) | ((i32rd[3] & 0xff)); byte[] buff = new byte[size]; transport_.readAll(buff, 0, size); readBuffer_ = new ByteArrayInputStream(buff); } public void write(byte[] buf, int off, int len) throws TTransportException { writeBuffer_.write(buf, off, len); } public void flush() throws TTransportException { byte[] buf = writeBuffer_.get(); int len = writeBuffer_.len(); writeBuffer_.reset(); byte[] i32out = new byte[4]; i32out[0] = (byte)(0xff & (len >> 24)); i32out[1] = (byte)(0xff & (len >> 16)); i32out[2] = (byte)(0xff & (len >> 8)); i32out[3] = (byte)(0xff & (len)); transport_.write(i32out, 0, 4); transport_.write(buf, 0, len); transport_.flush(); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/TMemoryBuffer.java0000664000175000017500000000520015165535636027127 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TByteArrayOutputStream; import java.io.UnsupportedEncodingException; /** * Memory buffer-based implementation of the TTransport interface. */ public class TMemoryBuffer extends TTransport { /** * Create a TMemoryBuffer with an initial buffer size of size. The * internal buffer will grow as necessary to accommodate the size of the data * being written to it. */ public TMemoryBuffer(int size) { arr_ = new TByteArrayOutputStream(size); } public boolean isOpen() { return true; } public void open() { /* Do nothing */ } public void close() { /* Do nothing */ } public int read(byte[] buf, int off, int len) { byte[] src = arr_.get(); int amtToRead = (len > arr_.len() - pos_ ? arr_.len() - pos_ : len); if (amtToRead > 0) { System.arraycopy(src, pos_, buf, off, amtToRead); pos_ += amtToRead; } return amtToRead; } public void write(byte[] buf, int off, int len) { arr_.write(buf, off, len); } /** * Output the contents of the memory buffer as a String, using the supplied * encoding * * @param enc the encoding to use * @return the contents of the memory buffer as a String */ public String toString(String enc) throws UnsupportedEncodingException { return arr_.toString(enc); } public String inspect() { String buf = ""; byte[] bytes = arr_.toByteArray(); for (int i = 0; i < bytes.length; i++) { buf += (pos_ == i ? "==>" : "") + Integer.toHexString(bytes[i] & 0xff) + " "; } return buf; } // The contents of the buffer private TByteArrayOutputStream arr_; // Position to read next byte from private int pos_; public int length() { return arr_.size(); } public byte[] getArray() { return arr_.get(); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/TIOStreamTransport.java0000664000175000017500000001014315165535636030127 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * This is the most commonly used base transport. It takes an InputStream * and an OutputStream and uses those to perform all transport operations. * This allows for compatibility with all the nice constructs Java already * has to provide a variety of types of streams. * */ public class TIOStreamTransport extends TTransport { /** Underlying inputStream */ protected InputStream inputStream_ = null; /** Underlying outputStream */ protected OutputStream outputStream_ = null; /** * Subclasses can invoke the default constructor and then assign the input * streams in the open method. */ protected TIOStreamTransport() {} /** * Input stream constructor. * * @param is Input stream to read from */ public TIOStreamTransport(InputStream is) { inputStream_ = is; } /** * Output stream constructor. * * @param os Output stream to read from */ public TIOStreamTransport(OutputStream os) { outputStream_ = os; } /** * Two-way stream constructor. * * @param is Input stream to read from * @param os Output stream to read from */ public TIOStreamTransport(InputStream is, OutputStream os) { inputStream_ = is; outputStream_ = os; } /** * The streams must already be open at construction time, so this should * always return true. * * @return true */ public boolean isOpen() { return true; } /** * The streams must already be open. This method does nothing. */ public void open() throws TTransportException {} /** * Closes both the input and output streams. */ public void close() { if (inputStream_ != null) { try { inputStream_.close(); } catch (IOException iox) { } inputStream_ = null; } if (outputStream_ != null) { try { outputStream_.close(); } catch (IOException iox) { } outputStream_ = null; } } /** * Reads from the underlying input stream if not null. */ public int read(byte[] buf, int off, int len) throws TTransportException { if (inputStream_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot read from null inputStream"); } try { return inputStream_.read(buf, off, len); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** * Writes to the underlying output stream if not null. */ public void write(byte[] buf, int off, int len) throws TTransportException { if (outputStream_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot write to null outputStream"); } try { outputStream_.write(buf, off, len); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** * Flushes the underlying output stream if not null. */ public void flush() throws TTransportException { if (outputStream_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot flush null outputStream"); } try { outputStream_.flush(); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } } thrift-0.23.0/lib/javame/src/org/apache/thrift/transport/TTransport.java0000664000175000017500000000703515165535636026531 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Generic class that encapsulates the I/O layer. This is basically a thin * wrapper around the combined functionality of Java input/output streams. * */ public abstract class TTransport { /** * Queries whether the transport is open. * * @return True if the transport is open. */ public abstract boolean isOpen(); /** * Is there more data to be read? * * @return True if the remote side is still alive and feeding us */ public boolean peek() { return isOpen(); } /** * Opens the transport for reading/writing. * * @throws TTransportException if the transport could not be opened */ public abstract void open() throws TTransportException; /** * Closes the transport. */ public abstract void close(); /** * Reads up to len bytes into buffer buf, starting att offset off. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read * @throws TTransportException if there was an error reading data */ public abstract int read(byte[] buf, int off, int len) throws TTransportException; /** * Guarantees that all of len bytes are actually read off the transport. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read, which must be equal to len * @throws TTransportException if there was an error reading data */ public int readAll(byte[] buf, int off, int len) throws TTransportException { int got = 0; int ret = 0; while (got < len) { ret = read(buf, off+got, len-got); if (ret <= 0) { throw new TTransportException("Cannot read. Remote side has closed. Tried to read " + len + " bytes, but only got " + got + " bytes."); } got += ret; } return got; } /** * Writes the buffer to the output * * @param buf The output data buffer * @throws TTransportException if an error occurs writing data */ public void write(byte[] buf) throws TTransportException { write(buf, 0, buf.length); } /** * Writes up to len bytes from the buffer. * * @param buf The output data buffer * @param off The offset to start writing from * @param len The number of bytes to write * @throws TTransportException if there was an error writing data */ public abstract void write(byte[] buf, int off, int len) throws TTransportException; /** * Flush any pending data out of a transport buffer. * * @throws TTransportException if there was an error writing out data. */ public void flush() throws TTransportException {} } thrift-0.23.0/lib/javame/src/org/apache/thrift/meta_data/0000775000175000017500000000000015165535636023424 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/org/apache/thrift/meta_data/FieldMetaData.java0000664000175000017500000001053515165535636026717 0ustar00buildbuild00000000000000/* * 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.TBase; import java.util.Hashtable; /** * This class is used to store meta data about thrift fields. Every field in a * a struct should have a corresponding instance of this class describing it. * * The meta data is registered by ALL Thrift struct classes via a static {...} * initializer block in the generated Thrift code. * * Since different threads could be initializing different Thrift classes, calls * to the public static methods of this class could be racy. * * All methods of this class should be made thread safe. */ public class FieldMetaData { public final String fieldName; public final byte requirementType; public final FieldValueMetaData valueMetaData; private static final Hashtable structMap; static { structMap = new Hashtable(); } public FieldMetaData(String name, byte req, FieldValueMetaData vMetaData){ this.fieldName = name; this.requirementType = req; this.valueMetaData = vMetaData; } public static void addStructMetaDataMap(Class sClass, Hashtable map){ synchronized (structMap) { structMap.put(sClass, map); } } /** * Returns a map with metadata (i.e. instances of FieldMetaData) that * describe the fields of the given class. * * @param sClass The TBase class for which the metadata map is requested. It is not * guaranteed that sClass will have been statically initialized before * this method is called. A racy call to * {@link FieldMetaData#addStructMetaDataMap(Class, Hashtable)} from a different * thread during static initialization of the Thrift class is possible. */ public static Hashtable getStructMetaDataMap(Class sClass) { // Note: Do not use synchronized on this method declaration - it leads to a deadlock. // Similarly, do not trigger sClass.newInstance() while holding a lock on structMap, // it will lead to the same deadlock. // See: https://issues.apache.org/jira/browse/THRIFT-5430 for details. boolean isThriftStructStaticallyInitialized = false; synchronized (structMap) { isThriftStructStaticallyInitialized = structMap.containsKey(sClass); } if (!isThriftStructStaticallyInitialized){ // Load class if it hasn't been loaded try{ sClass.newInstance(); } catch (InstantiationException e){ throw new RuntimeException("InstantiationException for TBase class: " + sClass.getName() + ", message: " + e.getMessage()); } catch (IllegalAccessException e){ throw new RuntimeException("IllegalAccessException for TBase class: " + sClass.getName() + ", message: " + e.getMessage()); } } synchronized (structMap) { return (Hashtable) structMap.get(sClass); } } } thrift-0.23.0/lib/javame/src/org/apache/thrift/meta_data/FieldValueMetaData.java0000664000175000017500000000410415165535636027707 0ustar00buildbuild00000000000000/* * 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.protocol.TType; /** * FieldValueMetaData and collection of subclasses to store metadata about * the value(s) of a field */ public class FieldValueMetaData { public final byte type; public FieldValueMetaData(byte type){ this.type = type; } public boolean isStruct() { return type == TType.STRUCT; } public boolean isContainer() { return type == TType.LIST || type == TType.MAP || type == TType.SET; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/meta_data/MapMetaData.java0000664000175000017500000000377615165535636026422 0ustar00buildbuild00000000000000/* * 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.meta_data.FieldValueMetaData; public class MapMetaData extends FieldValueMetaData { public final FieldValueMetaData keyMetaData; public final FieldValueMetaData valueMetaData; public MapMetaData(byte type, FieldValueMetaData kMetaData, FieldValueMetaData vMetaData){ super(type); this.keyMetaData = kMetaData; this.valueMetaData = vMetaData; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/meta_data/ListMetaData.java0000664000175000017500000000361715165535636026612 0ustar00buildbuild00000000000000/* * 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.meta_data.FieldValueMetaData; public class ListMetaData extends FieldValueMetaData { public final FieldValueMetaData elemMetaData; public ListMetaData(byte type, FieldValueMetaData eMetaData){ super(type); this.elemMetaData = eMetaData; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/meta_data/StructMetaData.java0000664000175000017500000000362215165535636027157 0ustar00buildbuild00000000000000/* * 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.TBase; import org.apache.thrift.meta_data.FieldValueMetaData; public class StructMetaData extends FieldValueMetaData { public final Class structClass; public StructMetaData(byte type, Class sClass){ super(type); this.structClass = sClass; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/meta_data/SetMetaData.java0000664000175000017500000000352515165535636026430 0ustar00buildbuild00000000000000/* * 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; public class SetMetaData extends FieldValueMetaData { public final FieldValueMetaData elemMetaData; public SetMetaData(byte type, FieldValueMetaData eMetaData){ super(type); this.elemMetaData = eMetaData; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/0000775000175000017500000000000015165535636023346 5ustar00buildbuild00000000000000thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TProtocolUtil.java0000664000175000017500000001061715165535636027001 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; /** * Utility class with static methods for interacting with protocol data * streams. * */ public class TProtocolUtil { /** * The maximum recursive depth the skip() function will traverse before * throwing a TException. */ private static int maxSkipDepth = Integer.MAX_VALUE; /** * Specifies the maximum recursive depth that the skip function will * traverse before throwing a TException. This is a global setting, so * any call to skip in this JVM will enforce this value. * * @param depth the maximum recursive depth. A value of 2 would allow * the skip function to skip a structure or collection with basic children, * but it would not permit skipping a struct that had a field containing * a child struct. A value of 1 would only allow skipping of simple * types and empty structs/collections. */ public static void setMaxSkipDepth(int depth) { maxSkipDepth = depth; } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be intepreted as this TType value. */ public static void skip(TProtocol prot, byte type) throws TException { skip(prot, type, maxSkipDepth); } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be intepreted as this TType value. * @param maxDepth this function will only skip complex objects to this * recursive depth, to prevent Java stack overflow. */ public static void skip(TProtocol prot, byte type, int maxDepth) throws TException { if (maxDepth <= 0) { throw new TException("Maximum skip depth exceeded"); } switch (type) { case TType.BOOL: { prot.readBool(); break; } case TType.BYTE: { prot.readByte(); break; } case TType.I16: { prot.readI16(); break; } case TType.I32: { prot.readI32(); break; } case TType.I64: { prot.readI64(); break; } case TType.DOUBLE: { prot.readDouble(); break; } case TType.STRING: { prot.readBinary(); break; } case TType.STRUCT: { prot.readStructBegin(); while (true) { TField field = prot.readFieldBegin(); if (field.type == TType.STOP) { break; } skip(prot, field.type, maxDepth - 1); prot.readFieldEnd(); } prot.readStructEnd(); break; } case TType.MAP: { TMap map = prot.readMapBegin(); for (int i = 0; i < map.size; i++) { skip(prot, map.keyType, maxDepth - 1); skip(prot, map.valueType, maxDepth - 1); } prot.readMapEnd(); break; } case TType.SET: { TSet set = prot.readSetBegin(); for (int i = 0; i < set.size; i++) { skip(prot, set.elemType, maxDepth - 1); } prot.readSetEnd(); break; } case TType.LIST: { TList list = prot.readListBegin(); for (int i = 0; i < list.size; i++) { skip(prot, list.elemType, maxDepth - 1); } prot.readListEnd(); break; } default: throw new TProtocolException(TProtocolException.INVALID_DATA, "Unrecognized type " + type); } } } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TType.java0000664000175000017500000000263515165535636025264 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Type constants in the Thrift protocol. * */ public final class TType { public static final byte STOP = 0; public static final byte VOID = 1; public static final byte BOOL = 2; public static final byte BYTE = 3; public static final byte DOUBLE = 4; public static final byte I16 = 6; public static final byte I32 = 8; public static final byte I64 = 10; public static final byte STRING = 11; public static final byte STRUCT = 12; public static final byte MAP = 13; public static final byte SET = 14; public static final byte LIST = 15; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TStruct.java0000664000175000017500000000200315165535636025614 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates struct metadata. * */ public class TStruct { public TStruct() {} public TStruct(String n) { name = n; } public String name = ""; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TMessage.java0000664000175000017500000000213215165535636025717 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates struct metadata. * */ public class TMessage { public TMessage() {} public TMessage(String n, byte t, int s) { name = n; type = t; seqid = s; } public String name = ""; public byte type; public int seqid; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TProtocolException.java0000664000175000017500000000400015165535636030007 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; /** * Protocol exceptions. * */ public class TProtocolException extends TException { private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int INVALID_DATA = 1; public static final int NEGATIVE_SIZE = 2; public static final int SIZE_LIMIT = 3; public static final int BAD_VERSION = 4; public static final int NOT_IMPLEMENTED = 5; protected int type_ = UNKNOWN; public TProtocolException() { super(); } public TProtocolException(int type) { super(); type_ = type; } public TProtocolException(int type, String message) { super(message); type_ = type; } public TProtocolException(String message) { super(message); } public TProtocolException(int type, Throwable cause) { super(cause); type_ = type; } public TProtocolException(Throwable cause) { super(cause); } public TProtocolException(String message, Throwable cause) { super(message, cause); } public TProtocolException(int type, String message, Throwable cause) { super(message, cause); type_ = type; } public int getType() { return type_; } } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TField.java0000664000175000017500000000214715165535636025364 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates field metadata. * */ public class TField { public TField() {} public TField(String n, byte t, short i) { name = n; type = t; id = i; } public String name = ""; public byte type = TType.STOP; public short id = 0; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TJSONProtocol.java0000664000175000017500000006700515165535636026640 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Stack; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; /** * JSON protocol implementation for thrift. * This is a full-featured protocol supporting write and read. * Please see the C++ class header for a detailed description of the * protocol's wire format. */ public class TJSONProtocol extends TProtocol { /** * Factory for JSON protocol objects */ public static class Factory implements TProtocolFactory { public TProtocol getProtocol(TTransport trans) { return new TJSONProtocol(trans); } } private static final byte[] COMMA = new byte[] { ',' }; private static final byte[] COLON = new byte[] { ':' }; private static final byte[] LBRACE = new byte[] { '{' }; private static final byte[] RBRACE = new byte[] { '}' }; private static final byte[] LBRACKET = new byte[] { '[' }; private static final byte[] RBRACKET = new byte[] { ']' }; private static final byte[] QUOTE = new byte[] { '"' }; private static final byte[] BACKSLASH = new byte[] { '\\' }; private static final byte[] ZERO = new byte[] { '0' }; private static final byte[] ESCSEQ = new byte[] { '\\', 'u', '0', '0' }; private static final long VERSION = 1; private static final byte[] JSON_CHAR_TABLE = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 }; private static final String ESCAPE_CHARS = "\"\\/bfnrt"; private static final byte[] ESCAPE_CHAR_VALS = { '"', '\\', '/', '\b', '\f', '\n', '\r', '\t', }; private static final int DEF_STRING_SIZE = 16; private static final byte[] NAME_BOOL = new byte[] { 't', 'f' }; private static final byte[] NAME_BYTE = new byte[] { 'i', '8' }; private static final byte[] NAME_I16 = new byte[] { 'i', '1', '6' }; private static final byte[] NAME_I32 = new byte[] { 'i', '3', '2' }; private static final byte[] NAME_I64 = new byte[] { 'i', '6', '4' }; private static final byte[] NAME_DOUBLE = new byte[] { 'd', 'b', 'l' }; private static final byte[] NAME_STRUCT = new byte[] { 'r', 'e', 'c' }; private static final byte[] NAME_STRING = new byte[] { 's', 't', 'r' }; private static final byte[] NAME_MAP = new byte[] { 'm', 'a', 'p' }; private static final byte[] NAME_LIST = new byte[] { 'l', 's', 't' }; private static final byte[] NAME_SET = new byte[] { 's', 'e', 't' }; private static final TStruct ANONYMOUS_STRUCT = new TStruct(); private static final byte[] getTypeNameForTypeID(byte typeID) throws TException { switch (typeID) { case TType.BOOL: return NAME_BOOL; case TType.BYTE: return NAME_BYTE; case TType.I16: return NAME_I16; case TType.I32: return NAME_I32; case TType.I64: return NAME_I64; case TType.DOUBLE: return NAME_DOUBLE; case TType.STRING: return NAME_STRING; case TType.STRUCT: return NAME_STRUCT; case TType.MAP: return NAME_MAP; case TType.SET: return NAME_SET; case TType.LIST: return NAME_LIST; default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } } private static final byte getTypeIDForTypeName(byte[] name) throws TException { byte result = TType.STOP; if (name.length > 1) { switch (name[0]) { case 'd': result = TType.DOUBLE; break; case 'i': switch (name[1]) { case '8': result = TType.BYTE; break; case '1': result = TType.I16; break; case '3': result = TType.I32; break; case '6': result = TType.I64; break; } break; case 'l': result = TType.LIST; break; case 'm': result = TType.MAP; break; case 'r': result = TType.STRUCT; break; case 's': if (name[1] == 't') { result = TType.STRING; } else if (name[1] == 'e') { result = TType.SET; } break; case 't': result = TType.BOOL; break; } } if (result == TType.STOP) { throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } return result; } // Base class for tracking JSON contexts that may require inserting/reading // additional JSON syntax characters // This base context does nothing. protected class JSONBaseContext { /** * @throws TException */ protected void write() throws TException {} /** * @throws TException */ protected void read() throws TException {} protected boolean escapeNum() { return false; } } // Context for JSON lists. Will insert/read commas before each item except // for the first one protected class JSONListContext extends JSONBaseContext { private boolean first_ = true; protected void write() throws TException { if (first_) { first_ = false; } else { trans_.write(COMMA); } } protected void read() throws TException { if (first_) { first_ = false; } else { readJSONSyntaxChar(COMMA); } } } // Context for JSON records. Will insert/read colons before the value portion // of each record pair, and commas before each key except the first. In // addition, will indicate that numbers in the key position need to be // escaped in quotes (since JSON keys must be strings). protected class JSONPairContext extends JSONBaseContext { private boolean first_ = true; private boolean colon_ = true; protected void write() throws TException { if (first_) { first_ = false; colon_ = true; } else { trans_.write(colon_ ? COLON : COMMA); colon_ = !colon_; } } protected void read() throws TException { if (first_) { first_ = false; colon_ = true; } else { readJSONSyntaxChar(colon_ ? COLON : COMMA); colon_ = !colon_; } } protected boolean escapeNum() { return colon_; } } // Holds up to one byte from the transport protected class LookaheadReader { private boolean hasData_; private byte[] data_ = new byte[1]; // Return and consume the next byte to be read, either taking it from the // data buffer if present or getting it from the transport otherwise. protected byte read() throws TException { if (hasData_) { hasData_ = false; } else { trans_.readAll(data_, 0, 1); } return data_[0]; } // Return the next byte to be read without consuming, filling the data // buffer if it has not been filled already. protected byte peek() throws TException { if (!hasData_) { trans_.readAll(data_, 0, 1); } hasData_ = true; return data_[0]; } } // Stack of nested contexts of type JSONBaseContext that we may be in private Stack contextStack_ = new Stack(); // Current context that we are in private JSONBaseContext context_ = new JSONBaseContext(); // Reader that manages a 1-byte buffer private LookaheadReader reader_ = new LookaheadReader(); // Push a new JSON context onto the stack. private void pushContext(JSONBaseContext c) { contextStack_.push(context_); context_ = c; } // Pop the last JSON context off the stack private void popContext() { context_ = (JSONBaseContext)contextStack_.pop(); } /** * Constructor */ public TJSONProtocol(TTransport trans) { super(trans); } public void reset() { contextStack_.clear(); context_ = new JSONBaseContext(); reader_ = new LookaheadReader(); } // Temporary buffer used by several methods private byte[] tmpbuf_ = new byte[4]; // Read a byte that must match b[0]; otherwise an exception is thrown. // Marked protected to avoid synthetic accessor in JSONListContext.read // and JSONPairContext.read protected void readJSONSyntaxChar(byte[] b) throws TException { byte ch = reader_.read(); if (ch != b[0]) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Unexpected character:" + (char)ch); } } // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its // corresponding hex value private static final byte hexVal(byte ch) throws TException { if ((ch >= '0') && (ch <= '9')) { return (byte)((char)ch - '0'); } else if ((ch >= 'a') && (ch <= 'f')) { return (byte)((char)ch - 'a' + 10); } else { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected hex character"); } } // Convert a byte containing a hex value to its corresponding hex character private static final byte hexChar(byte val) { val &= 0x0F; if (val < 10) { return (byte)((char)val + '0'); } else { return (byte)((char)(val - 10) + 'a'); } } private static boolean isHighSurrogate(char c) { return c >= '\uD800' && c <= '\uDBFF'; } private static boolean isLowSurrogate(char c) { return c >= '\uDC00' && c <= '\uDFFF'; } private static byte[] toUTF8(int codepoint) { final int[] FIRST_BYTE_MASK = { 0, 0xc0, 0xe0, 0xf0 }; int length = 0; if (codepoint <= 0x7f) length = 1; else if (codepoint <= 0x7ff) length = 2; else if (codepoint <= 0xffff) length = 3; else if (codepoint <= 0x1fffff) length = 4; else throw new RuntimeException("Code point over U+1FFFFF is not supported"); byte[] bytes = new byte[length]; switch (length) { case 4: bytes[3] = (byte)((codepoint & 0x3f) | 0x80); codepoint >>= 6; case 3: bytes[2] = (byte)((codepoint & 0x3f) | 0x80); codepoint >>= 6; case 2: bytes[1] = (byte)((codepoint & 0x3f) | 0x80); codepoint >>= 6; case 1: bytes[0] = (byte)(codepoint | FIRST_BYTE_MASK[length - 1]); } return bytes; } private static byte[] toUTF8(int high, int low) { int codepoint = (1 << 16) + ((high & 0x3ff) << 10); codepoint += low & 0x3ff; return toUTF8(codepoint); } // Write the bytes in array buf as a JSON characters, escaping as needed private void writeJSONString(byte[] b) throws TException { context_.write(); trans_.write(QUOTE); int len = b.length; for (int i = 0; i < len; i++) { if ((b[i] & 0x00FF) >= 0x30) { if (b[i] == BACKSLASH[0]) { trans_.write(BACKSLASH); trans_.write(BACKSLASH); } else { trans_.write(b, i, 1); } } else { tmpbuf_[0] = JSON_CHAR_TABLE[b[i]]; if (tmpbuf_[0] == 1) { trans_.write(b, i, 1); } else if (tmpbuf_[0] > 1) { trans_.write(BACKSLASH); trans_.write(tmpbuf_, 0, 1); } else { trans_.write(ESCSEQ); tmpbuf_[0] = hexChar((byte)(b[i] >> 4)); tmpbuf_[1] = hexChar(b[i]); trans_.write(tmpbuf_, 0, 2); } } } trans_.write(QUOTE); } // Write out number as a JSON value. If the context dictates so, it will be // wrapped in quotes to output as a JSON string. private void writeJSONInteger(long num) throws TException { context_.write(); String str = Long.toString(num); boolean escapeNum = context_.escapeNum(); if (escapeNum) { trans_.write(QUOTE); } try { byte[] buf = str.getBytes("UTF-8"); trans_.write(buf); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } if (escapeNum) { trans_.write(QUOTE); } } // Write out a double as a JSON value. If it is NaN or infinity or if the // context dictates escaping, write out as JSON string. private void writeJSONDouble(double num) throws TException { context_.write(); String str = Double.toString(num); boolean special = false; switch (str.charAt(0)) { case 'N': // NaN case 'I': // Infinity special = true; break; case '-': if (str.charAt(1) == 'I') { // -Infinity special = true; } break; } boolean escapeNum = special || context_.escapeNum(); if (escapeNum) { trans_.write(QUOTE); } try { byte[] b = str.getBytes("UTF-8"); trans_.write(b, 0, b.length); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } if (escapeNum) { trans_.write(QUOTE); } } // Write out contents of byte array b as a JSON string with base-64 encoded // data private void writeJSONBase64(byte[] b, int offset, int length) throws TException { context_.write(); trans_.write(QUOTE); int len = length; int off = offset; while (len >= 3) { // Encode 3 bytes at a time TBase64Utils.encode(b, off, 3, tmpbuf_, 0); trans_.write(tmpbuf_, 0, 4); off += 3; len -= 3; } if (len > 0) { // Encode remainder TBase64Utils.encode(b, off, len, tmpbuf_, 0); trans_.write(tmpbuf_, 0, len + 1); } trans_.write(QUOTE); } private void writeJSONObjectStart() throws TException { context_.write(); trans_.write(LBRACE); pushContext(new JSONPairContext()); } private void writeJSONObjectEnd() throws TException { popContext(); trans_.write(RBRACE); } private void writeJSONArrayStart() throws TException { context_.write(); trans_.write(LBRACKET); pushContext(new JSONListContext()); } private void writeJSONArrayEnd() throws TException { popContext(); trans_.write(RBRACKET); } public void writeMessageBegin(TMessage message) throws TException { writeJSONArrayStart(); writeJSONInteger(VERSION); try { byte[] b = message.name.getBytes("UTF-8"); writeJSONString(b); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } writeJSONInteger(message.type); writeJSONInteger(message.seqid); } public void writeMessageEnd() throws TException { writeJSONArrayEnd(); } public void writeStructBegin(TStruct struct) throws TException { writeJSONObjectStart(); } public void writeStructEnd() throws TException { writeJSONObjectEnd(); } public void writeFieldBegin(TField field) throws TException { writeJSONInteger(field.id); writeJSONObjectStart(); writeJSONString(getTypeNameForTypeID(field.type)); } public void writeFieldEnd() throws TException { writeJSONObjectEnd(); } public void writeFieldStop() {} public void writeMapBegin(TMap map) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(map.keyType)); writeJSONString(getTypeNameForTypeID(map.valueType)); writeJSONInteger(map.size); writeJSONObjectStart(); } public void writeMapEnd() throws TException { writeJSONObjectEnd(); writeJSONArrayEnd(); } public void writeListBegin(TList list) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(list.elemType)); writeJSONInteger(list.size); } public void writeListEnd() throws TException { writeJSONArrayEnd(); } public void writeSetBegin(TSet set) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(set.elemType)); writeJSONInteger(set.size); } public void writeSetEnd() throws TException { writeJSONArrayEnd(); } public void writeBool(boolean b) throws TException { writeJSONInteger(b ? (long)1 : (long)0); } public void writeByte(byte b) throws TException { writeJSONInteger(b); } public void writeI16(short i16) throws TException { writeJSONInteger(i16); } public void writeI32(int i32) throws TException { writeJSONInteger(i32); } public void writeI64(long i64) throws TException { writeJSONInteger(i64); } public void writeDouble(double dub) throws TException { writeJSONDouble(dub); } public void writeString(String str) throws TException { try { byte[] b = str.getBytes("UTF-8"); writeJSONString(b); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } public void writeBinary(byte[] bin) throws TException { writeJSONBase64(bin, 0, bin.length); } /** * Reading methods. */ // Read in a JSON string, unescaping as appropriate.. Skip reading from the // context if skipContext is true. private TByteArrayOutputStream readJSONString(boolean skipContext) throws TException { TByteArrayOutputStream arr = new TByteArrayOutputStream(DEF_STRING_SIZE); int highSurrogate = 0; if (!skipContext) { context_.read(); } readJSONSyntaxChar(QUOTE); while (true) { byte ch = reader_.read(); if (ch == QUOTE[0]) { break; } if (ch == ESCSEQ[0]) { ch = reader_.read(); if (ch == ESCSEQ[1]) { trans_.readAll(tmpbuf_, 0, 4); short cu = (short)( ((short)hexVal(tmpbuf_[0]) << 12) + ((short)hexVal(tmpbuf_[1]) << 8) + ((short)hexVal(tmpbuf_[2]) << 4) + (short)hexVal(tmpbuf_[3])); try { if (isHighSurrogate((char)cu)) { if (highSurrogate != 0) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected low surrogate char"); } highSurrogate = cu; } else if (isLowSurrogate((char)cu)) { if (highSurrogate == 0) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected high surrogate char"); } arr.write(toUTF8(highSurrogate, cu)); highSurrogate = 0; } else { arr.write(toUTF8(cu)); } continue; } catch (UnsupportedEncodingException ex) { throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "JVM does not support UTF-8"); } catch (IOException ex) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Invalid unicode sequence"); } } else { int off = ESCAPE_CHARS.indexOf(ch); if (off == -1) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected control char"); } ch = ESCAPE_CHAR_VALS[off]; } } arr.write(ch); } if (highSurrogate != 0) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected low surrogate char"); } return arr; } // Return true if the given byte could be a valid part of a JSON number. private boolean isJSONNumeric(byte b) { switch (b) { case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'E': case 'e': return true; } return false; } // Read in a sequence of characters that are all valid in JSON numbers. Does // not do a complete regex check to validate that this is actually a number. private String readJSONNumericChars() throws TException { StringBuffer strbuf = new StringBuffer(); while (true) { byte ch = reader_.peek(); if (!isJSONNumeric(ch)) { break; } strbuf.append((char)reader_.read()); } return strbuf.toString(); } // Read in a JSON number. If the context dictates, read in enclosing quotes. private long readJSONInteger() throws TException { context_.read(); if (context_.escapeNum()) { readJSONSyntaxChar(QUOTE); } String str = readJSONNumericChars(); if (context_.escapeNum()) { readJSONSyntaxChar(QUOTE); } try { return Long.valueOf(str).longValue(); } catch (NumberFormatException ex) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } // Read in a JSON double value. Throw if the value is not wrapped in quotes // when expected or if wrapped in quotes when not expected. private double readJSONDouble() throws TException { context_.read(); if (reader_.peek() == QUOTE[0]) { TByteArrayOutputStream arr = readJSONString(true); try { double dub = Double.valueOf(arr.toString("UTF-8")).doubleValue(); if (!context_.escapeNum() && !Double.isNaN(dub) && !Double.isInfinite(dub)) { // Throw exception -- we should not be in a string in this case throw new TProtocolException(TProtocolException.INVALID_DATA, "Numeric data unexpectedly quoted"); } return dub; } catch (UnsupportedEncodingException ex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } else { if (context_.escapeNum()) { // This will throw - we should have had a quote if escapeNum == true readJSONSyntaxChar(QUOTE); } try { return Double.valueOf(readJSONNumericChars()).doubleValue(); } catch (NumberFormatException ex) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } } // Read in a JSON string containing base-64 encoded data and decode it. private byte[] readJSONBase64() throws TException { TByteArrayOutputStream arr = readJSONString(false); byte[] b = arr.get(); int len = arr.len(); int off = 0; int size = 0; // Ignore padding int bound = len >= 2 ? len - 2 : 0; for (int i = len - 1; i >= bound && b[i] == '='; --i) { --len; } while (len >= 4) { // Decode 4 bytes at a time TBase64Utils.decode(b, off, 4, b, size); // NB: decoded in place off += 4; len -= 4; size += 3; } // Don't decode if we hit the end or got a single leftover byte (invalid // base64 but legal for skip of regular string type) if (len > 1) { // Decode remainder TBase64Utils.decode(b, off, len, b, size); // NB: decoded in place size += len - 1; } // Sadly we must copy the byte[] (any way around this?) byte[] result = new byte[size]; System.arraycopy(b, 0, result, 0, size); return result; } private void readJSONObjectStart() throws TException { context_.read(); readJSONSyntaxChar(LBRACE); pushContext(new JSONPairContext()); } private void readJSONObjectEnd() throws TException { readJSONSyntaxChar(RBRACE); popContext(); } private void readJSONArrayStart() throws TException { context_.read(); readJSONSyntaxChar(LBRACKET); pushContext(new JSONListContext()); } private void readJSONArrayEnd() throws TException { readJSONSyntaxChar(RBRACKET); popContext(); } public TMessage readMessageBegin() throws TException { readJSONArrayStart(); if (readJSONInteger() != VERSION) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Message contained bad version."); } String name; try { name = readJSONString(false).toString("UTF-8"); } catch (UnsupportedEncodingException ex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } byte type = (byte)readJSONInteger(); int seqid = (int)readJSONInteger(); return new TMessage(name, type, seqid); } public void readMessageEnd() throws TException { readJSONArrayEnd(); } public TStruct readStructBegin() throws TException { readJSONObjectStart(); return ANONYMOUS_STRUCT; } public void readStructEnd() throws TException { readJSONObjectEnd(); } public TField readFieldBegin() throws TException { byte ch = reader_.peek(); byte type; short id = 0; if (ch == RBRACE[0]) { type = TType.STOP; } else { id = (short)readJSONInteger(); readJSONObjectStart(); type = getTypeIDForTypeName(readJSONString(false).get()); } return new TField("", type, id); } public void readFieldEnd() throws TException { readJSONObjectEnd(); } public TMap readMapBegin() throws TException { readJSONArrayStart(); byte keyType = getTypeIDForTypeName(readJSONString(false).get()); byte valueType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int)readJSONInteger(); readJSONObjectStart(); return new TMap(keyType, valueType, size); } public void readMapEnd() throws TException { readJSONObjectEnd(); readJSONArrayEnd(); } public TList readListBegin() throws TException { readJSONArrayStart(); byte elemType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int)readJSONInteger(); return new TList(elemType, size); } public void readListEnd() throws TException { readJSONArrayEnd(); } public TSet readSetBegin() throws TException { readJSONArrayStart(); byte elemType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int)readJSONInteger(); return new TSet(elemType, size); } public void readSetEnd() throws TException { readJSONArrayEnd(); } public boolean readBool() throws TException { return (readJSONInteger() == 0 ? false : true); } public byte readByte() throws TException { return (byte)readJSONInteger(); } public short readI16() throws TException { return (short)readJSONInteger(); } public int readI32() throws TException { return (int)readJSONInteger(); } public long readI64() throws TException { return readJSONInteger(); } public double readDouble() throws TException { return readJSONDouble(); } public String readString() throws TException { try { return readJSONString(false).toString("UTF-8"); } catch (UnsupportedEncodingException ex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } public byte[] readBinary() throws TException { return readJSONBase64(); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TProtocol.java0000664000175000017500000001057315165535636026144 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; /** * Protocol interface definition. * */ public abstract class TProtocol { /** * Prevent direct instantiation */ private TProtocol() {} /** * Transport */ protected TTransport trans_; /** * Constructor */ protected TProtocol(TTransport trans) { trans_ = trans; } /** * Transport accessor */ public TTransport getTransport() { return trans_; } /** * Writing methods. */ public abstract void writeMessageBegin(TMessage message) throws TException; public abstract void writeMessageEnd() throws TException; public abstract void writeStructBegin(TStruct struct) throws TException; public abstract void writeStructEnd() throws TException; public abstract void writeFieldBegin(TField field) throws TException; public abstract void writeFieldEnd() throws TException; public abstract void writeFieldStop() throws TException; public abstract void writeMapBegin(TMap map) throws TException; public abstract void writeMapEnd() throws TException; public abstract void writeListBegin(TList list) throws TException; public abstract void writeListEnd() throws TException; public abstract void writeSetBegin(TSet set) throws TException; public abstract void writeSetEnd() throws TException; public abstract void writeBool(boolean b) throws TException; public void writeBool(Boolean b) throws TException { writeBool(b.booleanValue()); } public abstract void writeByte(byte b) throws TException; public void writeByte(Byte b) throws TException { writeByte(b.byteValue()); } public abstract void writeI16(short i16) throws TException; public void writeI16(Short i16) throws TException { writeI16(i16.shortValue()); } public abstract void writeI32(int i32) throws TException; public void writeI32(Integer i32) throws TException { writeI32(i32.intValue()); } public abstract void writeI64(long i64) throws TException; public void writeI64(Long i64) throws TException { writeI64(i64.longValue()); } public abstract void writeDouble(double dub) throws TException; public void writeDouble(Double d) throws TException { writeDouble(d.doubleValue()); } public abstract void writeString(String str) throws TException; public abstract void writeBinary(byte[] bin) throws TException; /** * Reading methods. */ public abstract TMessage readMessageBegin() throws TException; public abstract void readMessageEnd() throws TException; public abstract TStruct readStructBegin() throws TException; public abstract void readStructEnd() throws TException; public abstract TField readFieldBegin() throws TException; public abstract void readFieldEnd() throws TException; public abstract TMap readMapBegin() throws TException; public abstract void readMapEnd() throws TException; public abstract TList readListBegin() throws TException; public abstract void readListEnd() throws TException; public abstract TSet readSetBegin() throws TException; public abstract void readSetEnd() throws TException; public abstract boolean readBool() throws TException; public abstract byte readByte() throws TException; public abstract short readI16() throws TException; public abstract int readI32() throws TException; public abstract long readI64() throws TException; public abstract double readDouble() throws TException; public abstract String readString() throws TException; public abstract byte[] readBinary() throws TException; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TList.java0000664000175000017500000000207015165535636025247 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates list metadata. * */ public class TList { public TList() {} public TList(byte t, int s) { elemType = t; size = s; } public byte elemType = TType.STOP; public int size = 0; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TProtocolFactory.java0000664000175000017500000000202715165535636027467 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.transport.TTransport; /** * Factory interface for constructing protocol instances. * */ public interface TProtocolFactory { public TProtocol getProtocol(TTransport trans); } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TSet.java0000664000175000017500000000206415165535636025072 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates set metadata. * */ public class TSet { public TSet() {} public TSet(byte t, int s) { elemType = t; size = s; } public byte elemType = TType.STOP; public int size = 0; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TBinaryProtocol.java0000664000175000017500000002071015165535636027303 0ustar00buildbuild00000000000000 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.UnsupportedEncodingException; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; /** * Binary protocol implementation for thrift. * */ public class TBinaryProtocol extends TProtocol { protected static final int VERSION_MASK = 0xffff0000; protected static final int VERSION_1 = 0x80010000; protected boolean strictRead_ = false; protected boolean strictWrite_ = true; /** * Factory */ public static class Factory implements TProtocolFactory { protected boolean strictRead_ = false; protected boolean strictWrite_ = true; public Factory() { this(false, true); } public Factory(boolean strictRead, boolean strictWrite) { strictRead_ = strictRead; strictWrite_ = strictWrite; } public TProtocol getProtocol(TTransport trans) { return new TBinaryProtocol(trans, strictRead_, strictWrite_); } } /** * Constructor */ public TBinaryProtocol(TTransport trans) { this(trans, false, true); } public TBinaryProtocol(TTransport trans, boolean strictRead, boolean strictWrite) { super(trans); strictRead_ = strictRead; strictWrite_ = strictWrite; } public void writeMessageBegin(TMessage message) throws TException { if (strictWrite_) { int version = VERSION_1 | message.type; writeI32(version); writeString(message.name); writeI32(message.seqid); } else { writeString(message.name); writeByte(message.type); writeI32(message.seqid); } } public void writeMessageEnd() {} public void writeStructBegin(TStruct struct) {} public void writeStructEnd() {} public void writeFieldBegin(TField field) throws TException { writeByte(field.type); writeI16(field.id); } public void writeFieldEnd() {} public void writeFieldStop() throws TException { writeByte(TType.STOP); } public void writeMapBegin(TMap map) throws TException { writeByte(map.keyType); writeByte(map.valueType); writeI32(map.size); } public void writeMapEnd() {} public void writeListBegin(TList list) throws TException { writeByte(list.elemType); writeI32(list.size); } public void writeListEnd() {} public void writeSetBegin(TSet set) throws TException { writeByte(set.elemType); writeI32(set.size); } public void writeSetEnd() {} public void writeBool(boolean b) throws TException { writeByte(b ? (byte)1 : (byte)0); } private byte [] bout = new byte[1]; public void writeByte(byte b) throws TException { bout[0] = b; trans_.write(bout, 0, 1); } private byte[] i16out = new byte[2]; public void writeI16(short i16) throws TException { i16out[0] = (byte)(0xff & (i16 >> 8)); i16out[1] = (byte)(0xff & (i16)); trans_.write(i16out, 0, 2); } private byte[] i32out = new byte[4]; public void writeI32(int i32) throws TException { i32out[0] = (byte)(0xff & (i32 >> 24)); i32out[1] = (byte)(0xff & (i32 >> 16)); i32out[2] = (byte)(0xff & (i32 >> 8)); i32out[3] = (byte)(0xff & (i32)); trans_.write(i32out, 0, 4); } private byte[] i64out = new byte[8]; public void writeI64(long i64) throws TException { i64out[0] = (byte)(0xff & (i64 >> 56)); i64out[1] = (byte)(0xff & (i64 >> 48)); i64out[2] = (byte)(0xff & (i64 >> 40)); i64out[3] = (byte)(0xff & (i64 >> 32)); i64out[4] = (byte)(0xff & (i64 >> 24)); i64out[5] = (byte)(0xff & (i64 >> 16)); i64out[6] = (byte)(0xff & (i64 >> 8)); i64out[7] = (byte)(0xff & (i64)); trans_.write(i64out, 0, 8); } public void writeDouble(double dub) throws TException { writeI64(Double.doubleToLongBits(dub)); } public void writeString(String str) throws TException { try { byte[] dat = str.getBytes("UTF-8"); writeI32(dat.length); trans_.write(dat, 0, dat.length); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } public void writeBinary(byte[] bin) throws TException { writeI32(bin.length); trans_.write(bin, 0, bin.length); } /** * Reading methods. */ public TMessage readMessageBegin() throws TException { TMessage message = new TMessage(); int size = readI32(); if (size < 0) { int version = size & VERSION_MASK; if (version != VERSION_1) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Bad version in readMessageBegin"); } message.type = (byte)(size & 0x000000ff); message.name = readString(); message.seqid = readI32(); } else { if (strictRead_) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?"); } message.name = readStringBody(size); message.type = readByte(); message.seqid = readI32(); } return message; } public void readMessageEnd() {} public TStruct readStructBegin() { return new TStruct(); } public void readStructEnd() {} public TField readFieldBegin() throws TException { TField field = new TField(); field.type = readByte(); if (field.type != TType.STOP) { field.id = readI16(); } return field; } public void readFieldEnd() {} public TMap readMapBegin() throws TException { TMap map = new TMap(); map.keyType = readByte(); map.valueType = readByte(); map.size = readI32(); return map; } public void readMapEnd() {} public TList readListBegin() throws TException { TList list = new TList(); list.elemType = readByte(); list.size = readI32(); return list; } public void readListEnd() {} public TSet readSetBegin() throws TException { TSet set = new TSet(); set.elemType = readByte(); set.size = readI32(); return set; } public void readSetEnd() {} public boolean readBool() throws TException { return (readByte() == 1); } private byte[] bin = new byte[1]; public byte readByte() throws TException { readAll(bin, 0, 1); return bin[0]; } private byte[] i16rd = new byte[2]; public short readI16() throws TException { readAll(i16rd, 0, 2); return (short) (((i16rd[0] & 0xff) << 8) | ((i16rd[1] & 0xff))); } private byte[] i32rd = new byte[4]; public int readI32() throws TException { readAll(i32rd, 0, 4); return ((i32rd[0] & 0xff) << 24) | ((i32rd[1] & 0xff) << 16) | ((i32rd[2] & 0xff) << 8) | ((i32rd[3] & 0xff)); } private byte[] i64rd = new byte[8]; public long readI64() throws TException { readAll(i64rd, 0, 8); return ((long)(i64rd[0] & 0xff) << 56) | ((long)(i64rd[1] & 0xff) << 48) | ((long)(i64rd[2] & 0xff) << 40) | ((long)(i64rd[3] & 0xff) << 32) | ((long)(i64rd[4] & 0xff) << 24) | ((long)(i64rd[5] & 0xff) << 16) | ((long)(i64rd[6] & 0xff) << 8) | ((long)(i64rd[7] & 0xff)); } public double readDouble() throws TException { return Double.longBitsToDouble(readI64()); } public String readString() throws TException { int size = readI32(); return readStringBody(size); } public String readStringBody(int size) throws TException { try { byte[] buf = new byte[size]; trans_.readAll(buf, 0, size); return new String(buf, "UTF-8"); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } public byte[] readBinary() throws TException { int size = readI32(); byte[] buf = new byte[size]; trans_.readAll(buf, 0, size); return buf; } private int readAll(byte[] buf, int off, int len) throws TException { return trans_.readAll(buf, off, len); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TMessageType.java0000664000175000017500000000204115165535636026560 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Message type constants in the Thrift protocol. * */ public final class TMessageType { public static final byte CALL = 1; public static final byte REPLY = 2; public static final byte EXCEPTION = 3; } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TBase64Utils.java0000664000175000017500000001236015165535636026404 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Class for encoding and decoding Base64 data. * * This class is kept at package level because the interface does no input * validation and is therefore too low-level for generalized reuse. * * Note also that the encoding does not pad with equal signs , as discussed in * section 2.2 of the RFC (http://www.faqs.org/rfcs/rfc3548.html). Furthermore, * bad data encountered when decoding is neither rejected or ignored but simply * results in bad decoded data -- this is not in compliance with the RFC but is * done in the interest of performance. * */ class TBase64Utils { private static final String ENCODE_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * Encode len bytes of data in src at offset srcOff, storing the result into * dst at offset dstOff. len must be 1, 2, or 3. dst must have at least len+1 * bytes of space at dstOff. src and dst should not be the same object. This * method does no validation of the input values in the interest of * performance. * * @param src the source of bytes to encode * @param srcOff the offset into the source to read the unencoded bytes * @param len the number of bytes to encode (must be 1, 2, or 3). * @param dst the destination for the encoding * @param dstOff the offset into the destination to place the encoded bytes */ static final void encode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { dst[dstOff] = (byte)ENCODE_TABLE.charAt((src[srcOff] >> 2) & 0x3F); if (len == 3) { dst[dstOff + 1] = (byte)ENCODE_TABLE.charAt( ((src[srcOff] << 4) & 0x30) | ((src[srcOff+1] >> 4) & 0x0F)); dst[dstOff + 2] = (byte)ENCODE_TABLE.charAt( ((src[srcOff+1] << 2) & 0x3C) | ((src[srcOff+2] >> 6) & 0x03)); dst[dstOff + 3] = (byte)ENCODE_TABLE.charAt(src[srcOff+2] & 0x3F); } else if (len == 2) { dst[dstOff+1] = (byte)ENCODE_TABLE.charAt( ((src[srcOff] << 4) & 0x30) | ((src[srcOff+1] >> 4) & 0x0F)); dst[dstOff + 2] = (byte)ENCODE_TABLE.charAt((src[srcOff+1] << 2) & 0x3C); } else { // len == 1) { dst[dstOff + 1] = (byte)ENCODE_TABLE.charAt((src[srcOff] << 4) & 0x30); } } private static final byte[] DECODE_TABLE = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; /** * Decode len bytes of data in src at offset srcOff, storing the result into * dst at offset dstOff. len must be 2, 3, or 4. dst must have at least len-1 * bytes of space at dstOff. src and dst may be the same object as long as * dstoff <= srcOff. This method does no validation of the input values in * the interest of performance. * * @param src the source of bytes to decode * @param srcOff the offset into the source to read the encoded bytes * @param len the number of bytes to decode (must be 2, 3, or 4) * @param dst the destination for the decoding * @param dstOff the offset into the destination to place the decoded bytes */ static final void decode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { dst[dstOff] = (byte) ((DECODE_TABLE[src[srcOff] & 0x0FF] << 2) | (DECODE_TABLE[src[srcOff+1] & 0x0FF] >> 4)); if (len > 2) { dst[dstOff+1] = (byte) (((DECODE_TABLE[src[srcOff+1] & 0x0FF] << 4) & 0xF0) | (DECODE_TABLE[src[srcOff+2] & 0x0FF] >> 2)); if (len > 3) { dst[dstOff+2] = (byte) (((DECODE_TABLE[src[srcOff+2] & 0x0FF] << 6) & 0xC0) | DECODE_TABLE[src[srcOff+3] & 0x0FF]); } } } } thrift-0.23.0/lib/javame/src/org/apache/thrift/protocol/TMap.java0000664000175000017500000000217115165535636025053 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates map metadata. * */ public class TMap { public TMap() {} public TMap(byte k, byte v, int s) { keyType = k; valueType = v; size = s; } public byte keyType = TType.STOP; public byte valueType = TType.STOP; public int size = 0; } thrift-0.23.0/lib/javame/src/org/apache/thrift/TBase.java0000664000175000017500000000245615165535636023355 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * Generic base interface for generated Thrift objects. * */ public interface TBase { /** * Reads the TObject from the given input protocol. * * @param iprot Input protocol */ public void read(TProtocol iprot) throws TException; /** * Writes the objects out to the protocol * * @param oprot Output protocol */ public void write(TProtocol oprot) throws TException; public int compareTo(Object other); } thrift-0.23.0/lib/javame/src/org/apache/thrift/TBaseHelper.java0000664000175000017500000001336615165535636024517 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.util.Vector; import java.util.Hashtable; import java.util.Enumeration; public class TBaseHelper { public static int compareTo(boolean a, boolean b) { return (a == b) ? 0 : (a ? 1 : -1); } public static int compareTo(Boolean a, Boolean b) { return (a.booleanValue() == b.booleanValue()) ? 0 : (a.booleanValue() ? 1 : -1); } public static int compareTo(Boolean a, boolean b) { return (a.booleanValue() == b) ? 0 : (a.booleanValue() ? 1 : -1); } public static Boolean booleanValueOf(boolean b) { return (b ? Boolean.TRUE : Boolean.FALSE); } public static int compareTo(byte a, byte b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(short a, short b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(int a, int b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(long a, long b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(double a, double b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(String a, String b) { return a.compareTo(b); } public static int compareTo(byte[] a, byte[] b) { int sizeCompare = compareTo(a.length, b.length); if (sizeCompare != 0) { return sizeCompare; } for (int i = 0; i < a.length; i++) { int byteCompare = compareTo(a, b); if (byteCompare != 0) { return byteCompare; } } return 0; } public static int compareTo(Object a, Object b) { if (a instanceof Vector) { return compareTo((Vector)a, (Vector)b); } if (a instanceof Hashtable) { return compareTo((Hashtable)a, (Hashtable)b); } else { return ((TBase)a).compareTo(b); } } public static int compareTo(Vector a, Vector b) { int lastComparison = compareTo(a.size(), b.size()); if (lastComparison != 0) { return lastComparison; } for (int i = 0; i < a.size(); i++) { Object oA = a.elementAt(i); Object oB = b.elementAt(i); lastComparison = compareTo(oA, oB); if (lastComparison != 0) { return lastComparison; } } return 0; } public static int compareTo(Hashtable a, Hashtable b) { int lastComparison = compareTo(a.size(), b.size()); if (lastComparison != 0) { return lastComparison; } Enumeration enumA = a.keys(); Enumeration enumB = b.keys(); while (lastComparison == 0 && enumA.hasMoreElements()) { Object keyA = enumA.nextElement(); Object keyB = enumB.nextElement(); lastComparison = compareTo(keyA, keyB); if (lastComparison == 0) { lastComparison = compareTo(a.get(keyA), b.get(keyB)); } } return lastComparison; } public static int compareTo(TEnum a, TEnum b) { return compareTo(a.getValue(), b.getValue()); } /* public static int compareTo(List a, List b) { int lastComparison = compareTo(a.size(), b.size()); if (lastComparison != 0) { return lastComparison; } for (int i = 0; i < a.size(); i++) { Object oA = a.get(i); Object oB = b.get(i); if (oA instanceof List) { lastComparison = compareTo((List) oA, (List) oB); } else { lastComparison = compareTo((Comparable) oA, (Comparable) oB); } if (lastComparison != 0) { return lastComparison; } } return 0; } */ public static void toString(byte[] bytes, StringBuffer sb) { toString(bytes, 0, bytes.length, sb); } public static void toString(byte[] buf, int arrayOffset, int origLimit, StringBuffer sb) { int limit = (origLimit - arrayOffset > 128) ? arrayOffset + 128 : origLimit; for (int i = arrayOffset; i < limit; i++) { if (i > arrayOffset) { sb.append(" "); } sb.append(paddedByteString(buf[i])); } if (origLimit != limit) { sb.append("..."); } } public static String paddedByteString(byte b) { int extended = (b | 0x100) & 0x1ff; return Integer.toHexString(extended).toUpperCase().substring(1); } } thrift-0.23.0/lib/javame/src/org/apache/thrift/TProcessorFactory.java0000664000175000017500000000226015165535636026003 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.transport.TTransport; /** * The default processor factory just returns a singleton * instance. */ public class TProcessorFactory { private final TProcessor processor_; public TProcessorFactory(TProcessor processor) { processor_ = processor; } public TProcessor getProcessor(TTransport trans) { return processor_; } } thrift-0.23.0/lib/javame/coding_standards.md0000664000175000017500000000010315165535636021230 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/py/0000755000175000017500000000000015170007200014542 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/setup.cfg0000664000175000017500000000013615165535636016414 0ustar00buildbuild00000000000000[install] optimize = 1 [metadata] description_file = README.md [flake8] max-line-length = 100 thrift-0.23.0/lib/py/src/0000775000175000017500000000000015167543515015357 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/src/TTornado.py0000664000175000017500000001540015167543515017463 0ustar00buildbuild00000000000000# # 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 logging import socket import struct import warnings from .transport.TTransport import TTransportException, TTransportBase, TMemoryBuffer from io import BytesIO from collections import deque from contextlib import contextmanager from tornado import gen, iostream, ioloop, tcpserver, concurrent __all__ = ['TTornadoServer', 'TTornadoStreamTransport'] logger = logging.getLogger(__name__) class _Lock: def __init__(self): self._waiters = deque() def acquired(self): return len(self._waiters) > 0 @gen.coroutine def acquire(self): blocker = self._waiters[-1] if self.acquired() else None future = concurrent.Future() self._waiters.append(future) if blocker: yield blocker raise gen.Return(self._lock_context()) def release(self): assert self.acquired(), 'Lock not aquired' future = self._waiters.popleft() future.set_result(None) @contextmanager def _lock_context(self): try: yield finally: self.release() 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 = ioloop.IOLoop.current() self.__wbuf = BytesIO() self._read_lock = _Lock() # servers provide a ready-to-go stream self.stream = stream def with_timeout(self, timeout, future): 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): logger.debug('socket connecting') sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) self.stream = iostream.IOStream(sock) try: connect = self.stream.connect((self.host, self.port)) if timeout is not None: yield self.with_timeout(timeout, connect) else: yield connect except (socket.error, IOError, ioloop.TimeoutError) as e: message = 'could not connect to {}:{} ({})'.format(self.host, self.port, e) raise TTransportException( type=TTransportException.NOT_OPEN, message=message) raise gen.Return(self) def set_close_callback(self, callback): """ Should be called only after open() returns """ self.stream.set_close_callback(callback) def close(self): # don't raise if we intend to close self.stream.set_close_callback(None) self.stream.close() def read(self, _): # The generated code for Tornado shouldn't do individual reads -- only # frames at a time assert False, "you're doing it wrong" @contextmanager def io_exception_context(self): try: yield except (socket.error, IOError) as e: raise TTransportException( type=TTransportException.END_OF_FILE, message=str(e)) except iostream.StreamBufferFullError as e: raise TTransportException( type=TTransportException.UNKNOWN, message=str(e)) @gen.coroutine def readFrame(self): # IOStream processes reads one at a time with (yield self._read_lock.acquire()): with self.io_exception_context(): frame_header = yield self.stream.read_bytes(4) if len(frame_header) == 0: raise iostream.StreamClosedError('Read zero bytes from stream') frame_length, = struct.unpack('!i', frame_header) frame = yield self.stream.read_bytes(frame_length) raise gen.Return(frame) def write(self, buf): self.__wbuf.write(buf) def flush(self): frame = self.__wbuf.getvalue() # reset wbuf before write/flush to preserve state on underlying failure frame_length = struct.pack('!i', len(frame)) self.__wbuf = BytesIO() with self.io_exception_context(): return self.stream.write(frame_length + frame) class TTornadoServer(tcpserver.TCPServer): def __init__(self, processor, iprot_factory, oprot_factory=None, *args, **kwargs): super(TTornadoServer, self).__init__(*args, **kwargs) self._processor = processor self._iprot_factory = iprot_factory self._oprot_factory = (oprot_factory if oprot_factory is not None else iprot_factory) @gen.coroutine def handle_stream(self, stream, address): host, port = address[:2] trans = TTornadoStreamTransport(host=host, port=port, stream=stream) oprot = self._oprot_factory.getProtocol(trans) try: while not trans.stream.closed(): try: frame = yield trans.readFrame() except TTransportException as e: if e.type == TTransportException.END_OF_FILE: break else: raise tr = TMemoryBuffer(frame) iprot = self._iprot_factory.getProtocol(tr) yield self._processor.process(iprot, oprot) except Exception: logger.exception('thrift exception in handle_stream') trans.close() logger.info('client disconnected %s:%d', host, port) thrift-0.23.0/lib/py/src/ext/0000775000175000017500000000000015170007142016140 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/src/ext/protocol.tcc0000664000175000017500000006010515170007142020476 0ustar00buildbuild00000000000000/* * 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_PY_PROTOCOL_TCC #define THRIFT_PY_PROTOCOL_TCC #include #define CHECK_RANGE(v, min, max) (((v) <= (max)) && ((v) >= (min))) #define INIT_OUTBUF_SIZE 128 #if PY_MAJOR_VERSION < 3 #include #else #include #endif namespace apache { namespace thrift { namespace py { #if PY_MAJOR_VERSION < 3 namespace detail { inline bool input_check(PyObject* input) { return PycStringIO_InputCheck(input); } inline EncodeBuffer* new_encode_buffer(size_t size) { if (!PycStringIO) { PycString_IMPORT; } if (!PycStringIO) { return nullptr; } return PycStringIO->NewOutput(size); } inline int read_buffer(PyObject* buf, char** output, int len) { if (!PycStringIO) { PycString_IMPORT; } if (!PycStringIO) { PyErr_SetString(PyExc_ImportError, "failed to import native cStringIO"); return -1; } return PycStringIO->cread(buf, output, len); } } template inline ProtocolBase::~ProtocolBase() { if (output_) { Py_CLEAR(output_); } } template inline bool ProtocolBase::isUtf8(PyObject* typeargs) { return PyString_Check(typeargs) && !strncmp(PyString_AS_STRING(typeargs), "UTF8", 4); } template PyObject* ProtocolBase::getEncodedValue() { if (!PycStringIO) { PycString_IMPORT; } if (!PycStringIO) { return nullptr; } return PycStringIO->cgetvalue(output_); } template inline bool ProtocolBase::writeBuffer(char* data, size_t size) { if (!PycStringIO) { PycString_IMPORT; } if (!PycStringIO) { PyErr_SetString(PyExc_ImportError, "failed to import native cStringIO"); return false; } int len = PycStringIO->cwrite(output_, data, size); if (len < 0) { PyErr_SetString(PyExc_IOError, "failed to write to cStringIO object"); return false; } if (static_cast(len) != size) { PyErr_Format(PyExc_EOFError, "write length mismatch: expected %lu got %d", size, len); return false; } return true; } #else namespace detail { inline bool input_check(PyObject* input) { // TODO: Check for BytesIO type return true; } inline EncodeBuffer* new_encode_buffer(size_t size) { EncodeBuffer* buffer = new EncodeBuffer; buffer->buf.reserve(size); buffer->pos = 0; return buffer; } struct bytesio { PyObject_HEAD #if PY_MINOR_VERSION < 5 char* buf; #else PyObject* buf; #endif Py_ssize_t pos; Py_ssize_t string_size; }; inline int read_buffer(PyObject* buf, char** output, int len) { bytesio* buf2 = reinterpret_cast(buf); #if PY_MINOR_VERSION < 5 *output = buf2->buf + buf2->pos; #else *output = PyBytes_AS_STRING(buf2->buf) + buf2->pos; #endif Py_ssize_t pos0 = buf2->pos; buf2->pos = (std::min)(buf2->pos + static_cast(len), buf2->string_size); return static_cast(buf2->pos - pos0); } } template inline ProtocolBase::~ProtocolBase() { if (output_) { delete output_; } } template inline bool ProtocolBase::isUtf8(PyObject* typeargs) { // while condition for py2 is "arg == 'UTF8'", it should be "arg != 'BINARY'" for py3. // HACK: check the length and don't bother reading the value return !PyUnicode_Check(typeargs) || PyUnicode_GET_LENGTH(typeargs) != 6; } template PyObject* ProtocolBase::getEncodedValue() { return PyBytes_FromStringAndSize(output_->buf.data(), output_->buf.size()); } template inline bool ProtocolBase::writeBuffer(char* data, size_t size) { size_t need = size + output_->pos; if (output_->buf.capacity() < need) { try { output_->buf.reserve(need); } catch (std::bad_alloc&) { PyErr_SetString(PyExc_MemoryError, "Failed to allocate write buffer"); return false; } } std::copy(data, data + size, std::back_inserter(output_->buf)); return true; } #endif namespace detail { #define DECLARE_OP_SCOPE(name, op) \ template \ struct name##Scope { \ Impl* impl; \ bool valid; \ name##Scope(Impl* thiz) : impl(thiz), valid(impl->op##Begin()) {} \ ~name##Scope() { \ if (valid) \ impl->op##End(); \ } \ operator bool() { return valid; } \ }; \ template class T> \ name##Scope op##Scope(T* thiz) { \ return name##Scope(static_cast(thiz)); \ } DECLARE_OP_SCOPE(WriteStruct, writeStruct) DECLARE_OP_SCOPE(ReadStruct, readStruct) #undef DECLARE_OP_SCOPE inline bool check_ssize_t_32(Py_ssize_t len) { // error from getting the int if (INT_CONV_ERROR_OCCURRED(len)) { return false; } if (!CHECK_RANGE(len, 0, (std::numeric_limits::max)())) { PyErr_SetString(PyExc_OverflowError, "size out of range: exceeded INT32_MAX"); return false; } return true; } } template bool parse_pyint(PyObject* o, T* ret, int32_t min, int32_t max) { long val = PyInt_AsLong(o); if (INT_CONV_ERROR_OCCURRED(val)) { return false; } if (!CHECK_RANGE(val, min, max)) { PyErr_SetString(PyExc_OverflowError, "int out of range"); return false; } *ret = static_cast(val); return true; } template inline bool ProtocolBase::checkType(TType got, TType expected) { if (expected != got) { PyErr_SetString(PyExc_TypeError, "got wrong ttype while reading field"); return false; } return true; } template bool ProtocolBase::checkLengthLimit(int32_t len, long limit) { if (len < 0) { PyErr_Format(PyExc_OverflowError, "negative length: %ld", limit); return false; } if (len > limit) { PyErr_Format(PyExc_OverflowError, "size exceeded specified limit: %ld", limit); return false; } return true; } template bool ProtocolBase::readBytes(char** output, int len) { if (len < 0) { PyErr_Format(PyExc_ValueError, "attempted to read negative length: %d", len); return false; } // TODO(dreiss): Don't fear the malloc. Think about taking a copy of // the partial read instead of forcing the transport // to prepend it to its buffer. int rlen = detail::read_buffer(input_.stringiobuf.get(), output, len); if (rlen == len) { return true; } else if (rlen == -1) { return false; } else { // using building functions as this is a rare codepath ScopedPyObject newiobuf(PyObject_CallFunction(input_.refill_callable.get(), refill_signature, *output, rlen, len, nullptr)); if (!newiobuf) { return false; } // must do this *AFTER* the call so that we don't deref the io buffer input_.stringiobuf.reset(newiobuf.release()); rlen = detail::read_buffer(input_.stringiobuf.get(), output, len); if (rlen == len) { return true; } else if (rlen == -1) { return false; } else { // TODO(dreiss): This could be a valid code path for big binary blobs. PyErr_SetString(PyExc_TypeError, "refill claimed to have refilled the buffer, but didn't!!"); return false; } } } template bool ProtocolBase::prepareDecodeBufferFromTransport(PyObject* trans) { if (input_.stringiobuf) { PyErr_SetString(PyExc_ValueError, "decode buffer is already initialized"); return false; } ScopedPyObject stringiobuf(PyObject_GetAttr(trans, INTERN_STRING(cstringio_buf))); if (!stringiobuf) { return false; } if (!detail::input_check(stringiobuf.get())) { PyErr_SetString(PyExc_TypeError, "expecting stringio input_"); return false; } ScopedPyObject refill_callable(PyObject_GetAttr(trans, INTERN_STRING(cstringio_refill))); if (!refill_callable) { return false; } if (!PyCallable_Check(refill_callable.get())) { PyErr_SetString(PyExc_TypeError, "expecting callable"); return false; } input_.stringiobuf.swap(stringiobuf); input_.refill_callable.swap(refill_callable); return true; } template bool ProtocolBase::prepareEncodeBuffer() { output_ = detail::new_encode_buffer(INIT_OUTBUF_SIZE); return output_ != nullptr; } template bool ProtocolBase::encodeValue(PyObject* value, TType type, PyObject* typeargs) { /* * Refcounting Strategy: * * We assume that elements of the thrift_spec tuple are not going to be * mutated, so we don't ref count those at all. Other than that, we try to * keep a reference to all the user-created objects while we work with them. * encodeValue assumes that a reference is already held. The *caller* is * responsible for handling references */ switch (type) { case T_BOOL: { int v = PyObject_IsTrue(value); if (v == -1) { return false; } impl()->writeBool(v); return true; } case T_I08: { int8_t val; if (!parse_pyint(value, &val, (std::numeric_limits::min)(), (std::numeric_limits::max)())) { return false; } impl()->writeI8(val); return true; } case T_I16: { int16_t val; if (!parse_pyint(value, &val, (std::numeric_limits::min)(), (std::numeric_limits::max)())) { return false; } impl()->writeI16(val); return true; } case T_I32: { int32_t val; if (!parse_pyint(value, &val, (std::numeric_limits::min)(), (std::numeric_limits::max)())) { return false; } impl()->writeI32(val); return true; } case T_I64: { int64_t nval = PyLong_AsLongLong(value); if (INT_CONV_ERROR_OCCURRED(nval)) { return false; } if (!CHECK_RANGE(nval, (std::numeric_limits::min)(), (std::numeric_limits::max)())) { PyErr_SetString(PyExc_OverflowError, "int out of range"); return false; } impl()->writeI64(nval); return true; } case T_DOUBLE: { double nval = PyFloat_AsDouble(value); if (nval == -1.0 && PyErr_Occurred()) { return false; } impl()->writeDouble(nval); return true; } case T_STRING: { ScopedPyObject nval; if (PyUnicode_Check(value)) { nval.reset(PyUnicode_AsUTF8String(value)); if (!nval) { return false; } } else { Py_INCREF(value); nval.reset(value); } Py_ssize_t len = PyBytes_Size(nval.get()); if (!detail::check_ssize_t_32(len)) { return false; } impl()->writeString(nval.get(), static_cast(len)); return true; } case T_LIST: case T_SET: { SetListTypeArgs parsedargs; if (!parse_set_list_args(&parsedargs, typeargs)) { return false; } Py_ssize_t len = PyObject_Length(value); if (!detail::check_ssize_t_32(len)) { return false; } if (!impl()->writeListBegin(value, parsedargs, static_cast(len)) || PyErr_Occurred()) { return false; } ScopedPyObject iterator(PyObject_GetIter(value)); if (!iterator) { return false; } while (PyObject* rawItem = PyIter_Next(iterator.get())) { ScopedPyObject item(rawItem); if (!encodeValue(item.get(), parsedargs.element_type, parsedargs.typeargs)) { return false; } } return true; } case T_MAP: { Py_ssize_t len = PyDict_Size(value); if (!detail::check_ssize_t_32(len)) { return false; } MapTypeArgs parsedargs; if (!parse_map_args(&parsedargs, typeargs)) { return false; } if (!impl()->writeMapBegin(value, parsedargs, static_cast(len)) || PyErr_Occurred()) { return false; } Py_ssize_t pos = 0; PyObject* k = nullptr; PyObject* v = nullptr; // TODO(bmaurer): should support any mapping, not just dicts while (PyDict_Next(value, &pos, &k, &v)) { if (!encodeValue(k, parsedargs.ktag, parsedargs.ktypeargs) || !encodeValue(v, parsedargs.vtag, parsedargs.vtypeargs)) { return false; } } return true; } case T_STRUCT: { StructTypeArgs parsedargs; if (!parse_struct_args(&parsedargs, typeargs)) { return false; } Py_ssize_t nspec = PyTuple_Size(parsedargs.spec); if (nspec == -1) { PyErr_SetString(PyExc_TypeError, "spec is not a tuple"); return false; } detail::WriteStructScope scope = detail::writeStructScope(this); if (!scope) { return false; } for (Py_ssize_t i = 0; i < nspec; i++) { PyObject* spec_tuple = PyTuple_GET_ITEM(parsedargs.spec, i); if (spec_tuple == Py_None) { continue; } StructItemSpec parsedspec; if (!parse_struct_item_spec(&parsedspec, spec_tuple)) { return false; } ScopedPyObject instval(PyObject_GetAttr(value, parsedspec.attrname)); if (!instval) { return false; } if (instval.get() == Py_None) { continue; } bool res = impl()->writeField(instval.get(), parsedspec); if (!res) { return false; } } impl()->writeFieldStop(); return true; } case T_UUID: { ScopedPyObject instval(PyObject_GetAttr(value, INTERN_STRING(bytes))); if (!instval) { return false; } Py_ssize_t size; char* buffer; if (PyBytes_AsStringAndSize(instval.get(), &buffer, &size) < 0) { return false; } if (size != 16) { PyErr_SetString(PyExc_TypeError, "uuid.bytes must be exactly 16 bytes long"); return false; } impl()->writeUuid(buffer); return true; } case T_STOP: case T_VOID: case T_U64: default: PyErr_Format(PyExc_TypeError, "Unexpected TType for encodeValue: %d", type); return false; } return true; } template bool ProtocolBase::skip(TType type) { switch (type) { case T_BOOL: return impl()->skipBool(); case T_I08: return impl()->skipByte(); case T_I16: return impl()->skipI16(); case T_I32: return impl()->skipI32(); case T_I64: return impl()->skipI64(); case T_DOUBLE: return impl()->skipDouble(); case T_STRING: { return impl()->skipString(); } case T_LIST: case T_SET: { TType etype = T_STOP; int32_t len = impl()->readListBegin(etype); if (len < 0) { return false; } for (int32_t i = 0; i < len; i++) { if (!skip(etype)) { return false; } } return true; } case T_MAP: { TType ktype = T_STOP; TType vtype = T_STOP; int32_t len = impl()->readMapBegin(ktype, vtype); if (len < 0) { return false; } for (int32_t i = 0; i < len; i++) { if (!skip(ktype) || !skip(vtype)) { return false; } } return true; } case T_STRUCT: { detail::ReadStructScope scope = detail::readStructScope(this); if (!scope) { return false; } while (true) { TType type = T_STOP; int16_t tag; if (!impl()->readFieldBegin(type, tag)) { return false; } if (type == T_STOP) { return true; } if (!skip(type)) { return false; } } return true; } case T_UUID: { return impl()->skipUuid(); } case T_STOP: case T_VOID: case T_U64: default: PyErr_Format(PyExc_TypeError, "Unexpected TType for skip: %d", type); return false; } return true; } // Returns a new reference. template PyObject* ProtocolBase::decodeValue(TType type, PyObject* typeargs) { switch (type) { case T_BOOL: { bool v = 0; if (!impl()->readBool(v)) { return nullptr; } if (v) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } case T_I08: { int8_t v = 0; if (!impl()->readI8(v)) { return nullptr; } return PyInt_FromLong(v); } case T_I16: { int16_t v = 0; if (!impl()->readI16(v)) { return nullptr; } return PyInt_FromLong(v); } case T_I32: { int32_t v = 0; if (!impl()->readI32(v)) { return nullptr; } return PyInt_FromLong(v); } case T_I64: { int64_t v = 0; if (!impl()->readI64(v)) { return nullptr; } // TODO(dreiss): Find out if we can take this fastpath always when // sizeof(long) == sizeof(long long). if (CHECK_RANGE(v, LONG_MIN, LONG_MAX)) { return PyInt_FromLong((long)v); } return PyLong_FromLongLong(v); } case T_DOUBLE: { double v = 0.0; if (!impl()->readDouble(v)) { return nullptr; } return PyFloat_FromDouble(v); } case T_STRING: { char* buf = nullptr; int len = impl()->readString(&buf); if (len < 0) { return nullptr; } if (isUtf8(typeargs)) { return PyUnicode_DecodeUTF8(buf, len, "replace"); } else { return PyBytes_FromStringAndSize(buf, len); } } case T_LIST: case T_SET: { SetListTypeArgs parsedargs; if (!parse_set_list_args(&parsedargs, typeargs)) { return nullptr; } TType etype = T_STOP; int32_t len = impl()->readListBegin(etype); if (len < 0) { return nullptr; } if (len > 0 && !checkType(etype, parsedargs.element_type)) { return nullptr; } bool use_tuple = type == T_LIST && parsedargs.immutable; ScopedPyObject ret(use_tuple ? PyTuple_New(len) : PyList_New(len)); if (!ret) { return nullptr; } for (int i = 0; i < len; i++) { PyObject* item = decodeValue(etype, parsedargs.typeargs); if (!item) { return nullptr; } if (use_tuple) { PyTuple_SET_ITEM(ret.get(), i, item); } else { PyList_SET_ITEM(ret.get(), i, item); } } // TODO(dreiss): Consider biting the bullet and making two separate cases // for list and set, avoiding this post facto conversion. if (type == T_SET) { PyObject* setret; setret = parsedargs.immutable ? PyFrozenSet_New(ret.get()) : PySet_New(ret.get()); return setret; } return ret.release(); } case T_MAP: { MapTypeArgs parsedargs; if (!parse_map_args(&parsedargs, typeargs)) { return nullptr; } TType ktype = T_STOP; TType vtype = T_STOP; uint32_t len = impl()->readMapBegin(ktype, vtype); if (len > 0 && (!checkType(ktype, parsedargs.ktag) || !checkType(vtype, parsedargs.vtag))) { return nullptr; } ScopedPyObject ret(PyDict_New()); if (!ret) { return nullptr; } for (uint32_t i = 0; i < len; i++) { ScopedPyObject k(decodeValue(ktype, parsedargs.ktypeargs)); if (!k) { return nullptr; } ScopedPyObject v(decodeValue(vtype, parsedargs.vtypeargs)); if (!v) { return nullptr; } if (PyDict_SetItem(ret.get(), k.get(), v.get()) == -1) { return nullptr; } } if (parsedargs.immutable) { if (!ThriftModule) { ThriftModule = PyImport_ImportModule("thrift.Thrift"); } if (!ThriftModule) { return nullptr; } ScopedPyObject cls(PyObject_GetAttr(ThriftModule, INTERN_STRING(TFrozenDict))); if (!cls) { return nullptr; } ScopedPyObject arg(PyTuple_New(1)); PyTuple_SET_ITEM(arg.get(), 0, ret.release()); ret.reset(PyObject_CallObject(cls.get(), arg.get())); } return ret.release(); } case T_STRUCT: { StructTypeArgs parsedargs; if (!parse_struct_args(&parsedargs, typeargs)) { return nullptr; } return readStruct(Py_None, parsedargs.klass, parsedargs.spec); } case T_UUID: { char* buf = nullptr; if(!impl()->readUuid(&buf)) { return nullptr; } if(!UuidModule) { UuidModule = PyImport_ImportModule("uuid"); if (!UuidModule) return nullptr; } ScopedPyObject cls(PyObject_GetAttr(UuidModule, INTERN_STRING(UUID))); if (!cls) { return nullptr; } ScopedPyObject pyBytes(PyBytes_FromStringAndSize(buf, 16)); if (!pyBytes) { return nullptr; } ScopedPyObject args(PyTuple_New(0)); ScopedPyObject kwargs(Py_BuildValue("{O:O}", INTERN_STRING(bytes), pyBytes.get())); ScopedPyObject ret(PyObject_Call(cls.get(), args.get(), kwargs.get())); return ret.release(); } case T_STOP: case T_VOID: case T_U64: default: PyErr_Format(PyExc_TypeError, "Unexpected TType for decodeValue: %d", type); return nullptr; } } template PyObject* ProtocolBase::readStruct(PyObject* output, PyObject* klass, PyObject* spec_seq) { int spec_seq_len = PyTuple_Size(spec_seq); bool immutable = output == Py_None; ScopedPyObject kwargs; if (spec_seq_len == -1) { return nullptr; } if (immutable) { kwargs.reset(PyDict_New()); if (!kwargs) { PyErr_SetString(PyExc_TypeError, "failed to prepare kwargument storage"); return nullptr; } } detail::ReadStructScope scope = detail::readStructScope(this); if (!scope) { return nullptr; } while (true) { TType type = T_STOP; int16_t tag; if (!impl()->readFieldBegin(type, tag)) { return nullptr; } if (type == T_STOP) { break; } if (tag < 0 || tag >= spec_seq_len) { if (!skip(type)) { PyErr_SetString(PyExc_TypeError, "Error while skipping unknown field"); return nullptr; } continue; } PyObject* item_spec = PyTuple_GET_ITEM(spec_seq, tag); if (item_spec == Py_None) { if (!skip(type)) { PyErr_SetString(PyExc_TypeError, "Error while skipping unknown field"); return nullptr; } continue; } StructItemSpec parsedspec; if (!parse_struct_item_spec(&parsedspec, item_spec)) { return nullptr; } if (parsedspec.type != type) { if (!skip(type)) { PyErr_Format(PyExc_TypeError, "struct field had wrong type: expected %d but got %d", parsedspec.type, type); return nullptr; } continue; } ScopedPyObject fieldval(decodeValue(parsedspec.type, parsedspec.typeargs)); if (!fieldval) { return nullptr; } if ((immutable && PyDict_SetItem(kwargs.get(), parsedspec.attrname, fieldval.get()) == -1) || (!immutable && PyObject_SetAttr(output, parsedspec.attrname, fieldval.get()) == -1)) { return nullptr; } } if (immutable) { ScopedPyObject args(PyTuple_New(0)); if (!args) { PyErr_SetString(PyExc_TypeError, "failed to prepare argument storage"); return nullptr; } return PyObject_Call(klass, args.get(), kwargs.get()); } Py_INCREF(output); return output; } } } } #endif // THRIFT_PY_PROTOCOL_H thrift-0.23.0/lib/py/src/ext/module.cpp0000664000175000017500000001461615167543515020160 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define PY_SSIZE_T_CLEAN #include #include "types.h" #include "binary.h" #include "compact.h" #include #include // TODO(dreiss): defval appears to be unused. Look into removing it. // TODO(dreiss): Make parse_spec_args recursive, and cache the output // permanently in the object. (Malloc and orphan.) // TODO(dreiss): Why do we need cStringIO for reading, why not just char*? // Can cStringIO let us work with a BufferedTransport? // TODO(dreiss): Don't ignore the rv from cwrite (maybe). // Doing a benchmark shows that interning actually makes a difference, amazingly. /** Pointer to interned string to speed up attribute lookup. */ PyObject* INTERN_STRING(TFrozenDict); PyObject* INTERN_STRING(cstringio_buf); PyObject* INTERN_STRING(cstringio_refill); PyObject* INTERN_STRING(UUID); PyObject* INTERN_STRING(bytes); static PyObject* INTERN_STRING(string_length_limit); static PyObject* INTERN_STRING(container_length_limit); static PyObject* INTERN_STRING(trans); namespace apache { namespace thrift { namespace py { template static PyObject* encode_impl(PyObject* args) { if (!args) return nullptr; PyObject* enc_obj = nullptr; PyObject* type_args = nullptr; if (!PyArg_ParseTuple(args, "OO", &enc_obj, &type_args)) { return nullptr; } if (!enc_obj || !type_args) { return nullptr; } T protocol; if (!protocol.prepareEncodeBuffer() || !protocol.encodeValue(enc_obj, T_STRUCT, type_args)) { return nullptr; } return protocol.getEncodedValue(); } static inline long as_long_then_delete(PyObject* value, long default_value) { ScopedPyObject scope(value); long v = PyInt_AsLong(value); if (INT_CONV_ERROR_OCCURRED(v)) { PyErr_Clear(); return default_value; } return v; } template static PyObject* decode_impl(PyObject* args) { PyObject* output_obj = nullptr; PyObject* oprot = nullptr; PyObject* typeargs = nullptr; if (!PyArg_ParseTuple(args, "OOO", &output_obj, &oprot, &typeargs)) { return nullptr; } T protocol; int32_t default_limit = (std::numeric_limits::max)(); protocol.setStringLengthLimit( as_long_then_delete(PyObject_GetAttr(oprot, INTERN_STRING(string_length_limit)), default_limit)); protocol.setContainerLengthLimit( as_long_then_delete(PyObject_GetAttr(oprot, INTERN_STRING(container_length_limit)), default_limit)); ScopedPyObject transport(PyObject_GetAttr(oprot, INTERN_STRING(trans))); if (!transport) { return nullptr; } StructTypeArgs parsedargs; if (!parse_struct_args(&parsedargs, typeargs)) { return nullptr; } if (!protocol.prepareDecodeBufferFromTransport(transport.get())) { return nullptr; } return protocol.readStruct(output_obj, parsedargs.klass, parsedargs.spec); } } } } using namespace apache::thrift::py; /* -- PYTHON MODULE SETUP STUFF --- */ extern "C" { static PyObject* encode_binary(PyObject*, PyObject* args) { return encode_impl(args); } static PyObject* decode_binary(PyObject*, PyObject* args) { return decode_impl(args); } static PyObject* encode_compact(PyObject*, PyObject* args) { return encode_impl(args); } static PyObject* decode_compact(PyObject*, PyObject* args) { return decode_impl(args); } static PyMethodDef ThriftFastBinaryMethods[] = { {"encode_binary", encode_binary, METH_VARARGS, ""}, {"decode_binary", decode_binary, METH_VARARGS, ""}, {"encode_compact", encode_compact, METH_VARARGS, ""}, {"decode_compact", decode_compact, METH_VARARGS, ""}, {nullptr, nullptr, 0, nullptr} /* Sentinel */ }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef ThriftFastBinaryDef = {PyModuleDef_HEAD_INIT, "thrift.protocol.fastbinary", nullptr, 0, ThriftFastBinaryMethods, nullptr, nullptr, nullptr, nullptr}; #define INITERROR return nullptr; PyObject* PyInit_fastbinary() { #else #define INITERROR return; void initfastbinary() { PycString_IMPORT; if (PycStringIO == nullptr) INITERROR #endif #define INIT_INTERN_STRING(value) \ do { \ INTERN_STRING(value) = PyString_InternFromString(#value); \ if (!INTERN_STRING(value)) \ INITERROR \ } while (0) INIT_INTERN_STRING(TFrozenDict); INIT_INTERN_STRING(cstringio_buf); INIT_INTERN_STRING(cstringio_refill); INIT_INTERN_STRING(string_length_limit); INIT_INTERN_STRING(container_length_limit); INIT_INTERN_STRING(trans); INIT_INTERN_STRING(UUID); INIT_INTERN_STRING(bytes); #undef INIT_INTERN_STRING PyObject* module = #if PY_MAJOR_VERSION >= 3 PyModule_Create(&ThriftFastBinaryDef); #else Py_InitModule("thrift.protocol.fastbinary", ThriftFastBinaryMethods); #endif if (module == nullptr) INITERROR; #ifdef Py_GIL_DISABLED PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED); #endif #if PY_MAJOR_VERSION >= 3 return module; #endif } } thrift-0.23.0/lib/py/src/ext/compact.h0000664000175000017500000002177315167543515017770 0ustar00buildbuild00000000000000/* * 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_PY_COMPACT_H #define THRIFT_PY_COMPACT_H #include #include "ext/protocol.h" #include "ext/endian.h" #include #include namespace apache { namespace thrift { namespace py { class CompactProtocol : public ProtocolBase { public: CompactProtocol() { readBool_.exists = false; } virtual ~CompactProtocol() {} void writeI8(int8_t val) { writeBuffer(reinterpret_cast(&val), 1); } void writeI16(int16_t val) { writeVarint(toZigZag(val)); } int writeI32(int32_t val) { return writeVarint(toZigZag(val)); } void writeI64(int64_t val) { writeVarint64(toZigZag64(val)); } void writeDouble(double dub) { union { double f; int64_t t; } transfer; transfer.f = dub; transfer.t = htolell(transfer.t); writeBuffer(reinterpret_cast(&transfer.t), sizeof(int64_t)); } void writeBool(int v) { writeByte(static_cast(v ? CT_BOOLEAN_TRUE : CT_BOOLEAN_FALSE)); } void writeString(PyObject* value, int32_t len) { writeVarint(len); writeBuffer(PyBytes_AS_STRING(value), len); } bool writeListBegin(PyObject* value, const SetListTypeArgs& args, int32_t len) { int ctype = toCompactType(args.element_type); if (len <= 14) { writeByte(static_cast(len << 4 | ctype)); } else { writeByte(0xf0 | ctype); writeVarint(len); } return true; } bool writeMapBegin(PyObject* value, const MapTypeArgs& args, int32_t len) { if (len == 0) { writeByte(0); return true; } int ctype = toCompactType(args.ktag) << 4 | toCompactType(args.vtag); writeVarint(len); writeByte(ctype); return true; } bool writeStructBegin() { writeTags_.push(0); return true; } bool writeStructEnd() { writeTags_.pop(); return true; } bool writeField(PyObject* value, const StructItemSpec& spec) { if (spec.type == T_BOOL) { doWriteFieldBegin(spec, PyObject_IsTrue(value) ? CT_BOOLEAN_TRUE : CT_BOOLEAN_FALSE); return true; } else { doWriteFieldBegin(spec, toCompactType(spec.type)); return encodeValue(value, spec.type, spec.typeargs); } } void writeFieldStop() { writeByte(0); } void writeUuid(char* value) { writeBuffer(value, 16); } bool readBool(bool& val) { if (readBool_.exists) { readBool_.exists = false; val = readBool_.value; return true; } char* buf; if (!readBytes(&buf, 1)) { return false; } val = buf[0] == CT_BOOLEAN_TRUE; return true; } bool readI8(int8_t& val) { char* buf; if (!readBytes(&buf, 1)) { return false; } val = buf[0]; return true; } bool readI16(int16_t& val) { uint16_t uval; if (readVarint(uval)) { val = fromZigZag(uval); return true; } return false; } bool readI32(int32_t& val) { uint32_t uval; if (readVarint(uval)) { val = fromZigZag(uval); return true; } return false; } bool readI64(int64_t& val) { uint64_t uval; if (readVarint(uval)) { val = fromZigZag(uval); return true; } return false; } bool readDouble(double& val) { union { int64_t f; double t; } transfer; char* buf; if (!readBytes(&buf, 8)) { return false; } memcpy(&transfer.f, buf, sizeof(int64_t)); transfer.f = letohll(transfer.f); val = transfer.t; return true; } int32_t readString(char** buf) { uint32_t len; if (!readVarint(len) || !checkLengthLimit(len, stringLimit())) { return -1; } if (len == 0) { return 0; } if (!readBytes(buf, len)) { return -1; } return len; } int32_t readListBegin(TType& etype) { uint8_t b; if (!readByte(b)) { return -1; } etype = getTType(b & 0xf); if (etype == -1) { return -1; } uint32_t len = (b >> 4) & 0xf; if (len == 15 && !readVarint(len)) { return -1; } if (!checkLengthLimit(len, containerLimit())) { return -1; } return len; } int32_t readMapBegin(TType& ktype, TType& vtype) { uint32_t len; if (!readVarint(len) || !checkLengthLimit(len, containerLimit())) { return -1; } if (len != 0) { uint8_t kvType; if (!readByte(kvType)) { return -1; } ktype = getTType(kvType >> 4); vtype = getTType(kvType & 0xf); if (ktype == -1 || vtype == -1) { return -1; } } return len; } bool readStructBegin() { readTags_.push(0); return true; } bool readStructEnd() { readTags_.pop(); return true; } bool readFieldBegin(TType& type, int16_t& tag); bool readUuid(char** buf) { if (!readBytes(buf, 16)) { return false; } return true; } bool skipBool() { bool val; return readBool(val); } #define SKIPBYTES(n) \ do { \ if (!readBytes(&dummy_buf_, (n))) { \ return false; \ } \ return true; \ } while (0) bool skipByte() { SKIPBYTES(1); } bool skipDouble() { SKIPBYTES(8); } bool skipI16() { int16_t val; return readI16(val); } bool skipI32() { int32_t val; return readI32(val); } bool skipI64() { int64_t val; return readI64(val); } bool skipString() { uint32_t len; if (!readVarint(len)) { return false; } SKIPBYTES(len); } bool skipUuid() { SKIPBYTES(16); } #undef SKIPBYTES private: enum 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_UUID = 0x0D, }; static const uint8_t TTypeToCType[]; TType getTType(uint8_t type); int toCompactType(TType type) { int i = static_cast(type); return i <= 16 ? TTypeToCType[i] : -1; } uint32_t toZigZag(int32_t val) { return (val >> 31) ^ (val << 1); } uint64_t toZigZag64(int64_t val) { return (val >> 63) ^ (val << 1); } int writeVarint(uint32_t val) { int cnt = 1; while (val & ~0x7fU) { writeByte(static_cast((val & 0x7fU) | 0x80U)); val >>= 7; ++cnt; } writeByte(static_cast(val)); return cnt; } int writeVarint64(uint64_t val) { int cnt = 1; while (val & ~0x7fULL) { writeByte(static_cast((val & 0x7fULL) | 0x80ULL)); val >>= 7; ++cnt; } writeByte(static_cast(val)); return cnt; } template bool readVarint(T& result) { uint8_t b; T val = 0; int shift = 0; for (int i = 0; i < Max; ++i) { if (!readByte(b)) { return false; } if (b & 0x80) { val |= static_cast(b & 0x7f) << shift; } else { val |= static_cast(b) << shift; result = val; return true; } shift += 7; } PyErr_Format(PyExc_OverflowError, "varint exceeded %d bytes", Max); return false; } template S fromZigZag(U val) { return (val >> 1) ^ static_cast(-static_cast(val & 1)); } void doWriteFieldBegin(const StructItemSpec& spec, int ctype) { int diff = spec.tag - writeTags_.top(); if (diff > 0 && diff <= 15) { writeByte(static_cast(diff << 4 | ctype)); } else { writeByte(static_cast(ctype)); writeI16(spec.tag); } writeTags_.top() = spec.tag; } std::stack writeTags_; std::stack readTags_; struct { bool exists; bool value; } readBool_; char* dummy_buf_; }; } } } #endif // THRIFT_PY_COMPACT_H thrift-0.23.0/lib/py/src/ext/endian.h0000664000175000017500000000443015167543515017567 0ustar00buildbuild00000000000000/* * 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_PY_ENDIAN_H #define THRIFT_PY_ENDIAN_H #include #ifdef _WIN32 #include #pragma comment(lib, "ws2_32.lib") #define inline __inline #else #include #ifndef ntohll static inline unsigned long long ntohll(unsigned long long n) { union { unsigned long long f; unsigned char t[8]; } u; u.f = n; return static_cast(u.t[0]) << 56 | static_cast(u.t[1]) << 48 | static_cast(u.t[2]) << 40 | static_cast(u.t[3]) << 32 | static_cast(u.t[4]) << 24 | static_cast(u.t[5]) << 16 | static_cast(u.t[6]) << 8 | static_cast(u.t[7]); } #endif #ifndef htonll #define htonll(n) ntohll(n) #endif #endif // !_WIN32 static inline unsigned long long letohll(unsigned long long n) { union { unsigned long long f; unsigned char t[8]; } u; u.f = n; return static_cast(u.t[0]) | static_cast(u.t[1]) << 8 | static_cast(u.t[2]) << 16 | static_cast(u.t[3]) << 24 | static_cast(u.t[4]) << 32 | static_cast(u.t[5]) << 40 | static_cast(u.t[6]) << 48 | static_cast(u.t[7]) << 56; } #define htolell(n) letohll(n) #endif // THRIFT_PY_ENDIAN_H thrift-0.23.0/lib/py/src/ext/types.cpp0000664000175000017500000000661215167543515020034 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define PY_SSIZE_T_CLEAN #include "ext/types.h" #include "ext/protocol.h" namespace apache { namespace thrift { namespace py { PyObject* ThriftModule = nullptr; PyObject* UuidModule = nullptr; #if PY_MAJOR_VERSION < 3 char refill_signature[] = {'s', '#', 'i'}; #else const char* refill_signature = "y#i"; #endif bool parse_struct_item_spec(StructItemSpec* dest, PyObject* spec_tuple) { // i'd like to use ParseArgs here, but it seems to be a bottleneck. if (PyTuple_Size(spec_tuple) != 5) { PyErr_Format(PyExc_TypeError, "expecting 5 arguments for spec tuple but got %d", static_cast(PyTuple_Size(spec_tuple))); return false; } dest->tag = static_cast(PyInt_AsLong(PyTuple_GET_ITEM(spec_tuple, 0))); if (INT_CONV_ERROR_OCCURRED(dest->tag)) { return false; } dest->type = static_cast(PyInt_AsLong(PyTuple_GET_ITEM(spec_tuple, 1))); if (INT_CONV_ERROR_OCCURRED(dest->type)) { return false; } dest->attrname = PyTuple_GET_ITEM(spec_tuple, 2); dest->typeargs = PyTuple_GET_ITEM(spec_tuple, 3); dest->defval = PyTuple_GET_ITEM(spec_tuple, 4); return true; } bool parse_set_list_args(SetListTypeArgs* dest, PyObject* typeargs) { if (PyTuple_Size(typeargs) != 3) { PyErr_SetString(PyExc_TypeError, "expecting tuple of size 3 for list/set type args"); return false; } dest->element_type = static_cast(PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 0))); if (INT_CONV_ERROR_OCCURRED(dest->element_type)) { return false; } dest->typeargs = PyTuple_GET_ITEM(typeargs, 1); dest->immutable = Py_True == PyTuple_GET_ITEM(typeargs, 2); return true; } bool parse_map_args(MapTypeArgs* dest, PyObject* typeargs) { if (PyTuple_Size(typeargs) != 5) { PyErr_SetString(PyExc_TypeError, "expecting 5 arguments for typeargs to map"); return false; } dest->ktag = static_cast(PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 0))); if (INT_CONV_ERROR_OCCURRED(dest->ktag)) { return false; } dest->vtag = static_cast(PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 2))); if (INT_CONV_ERROR_OCCURRED(dest->vtag)) { return false; } dest->ktypeargs = PyTuple_GET_ITEM(typeargs, 1); dest->vtypeargs = PyTuple_GET_ITEM(typeargs, 3); dest->immutable = Py_True == PyTuple_GET_ITEM(typeargs, 4); return true; } bool parse_struct_args(StructTypeArgs* dest, PyObject* typeargs) { if (PyList_Size(typeargs) != 2) { PyErr_SetString(PyExc_TypeError, "expecting list of size 2 for struct args"); return false; } dest->klass = PyList_GET_ITEM(typeargs, 0); dest->spec = PyList_GET_ITEM(typeargs, 1); return true; } } } } thrift-0.23.0/lib/py/src/ext/compact.cpp0000664000175000017500000000574315167543515020322 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define PY_SSIZE_T_CLEAN #include "ext/compact.h" namespace apache { namespace thrift { namespace py { /** Mapping of Compact type to Thrift Type according. * This list must match the TType enum in TEnum.h */ const uint8_t CompactProtocol::TTypeToCType[] = { /* 0 */ CT_STOP, // T_STOP /* 1 */ 0, // unused /* 2 */ CT_BOOLEAN_TRUE, // T_BOOL /* 3 */ CT_BYTE, // T_BYTE /* 4 */ CT_DOUBLE, // T_DOUBLE /* 5 */ 0, // unused /* 6 */ CT_I16, // T_I16 /* 7 */ 0, // unused /* 8 */ CT_I32, // T_I32 /* 9 */ 0, // unused /* 10 */ CT_I64, // T_I64 /* 11 */ CT_BINARY, // T_STRING /* 12 */ CT_STRUCT, // T_STRUCT /* 13 */ CT_MAP, // T_MAP /* 14 */ CT_SET, // T_SET /* 15 */ CT_LIST, // T_LIST /* 16 */ CT_UUID, // T_UUID }; bool CompactProtocol::readFieldBegin(TType& type, int16_t& tag) { uint8_t b; if (!readByte(b)) { return false; } uint8_t ctype = b & 0xf; type = getTType(ctype); if (type == -1) { return false; } else if (type == T_STOP) { tag = 0; return true; } uint8_t diff = (b & 0xf0) >> 4; if (diff) { tag = readTags_.top() + diff; } else if (!readI16(tag)) { readTags_.top() = -1; return false; } if (ctype == CT_BOOLEAN_FALSE || ctype == CT_BOOLEAN_TRUE) { readBool_.exists = true; readBool_.value = ctype == CT_BOOLEAN_TRUE; } readTags_.top() = tag; return true; } TType CompactProtocol::getTType(uint8_t type) { switch (type) { case T_STOP: return T_STOP; case CT_BOOLEAN_FALSE: case CT_BOOLEAN_TRUE: return T_BOOL; case CT_BYTE: return T_BYTE; case CT_I16: return T_I16; case CT_I32: return T_I32; case CT_I64: return T_I64; case CT_DOUBLE: return T_DOUBLE; case CT_BINARY: return T_STRING; case CT_LIST: return T_LIST; case CT_SET: return T_SET; case CT_MAP: return T_MAP; case CT_STRUCT: return T_STRUCT; case CT_UUID: return T_UUID; default: PyErr_Format(PyExc_TypeError, "don't know what type: %d", type); return static_cast(-1); } } } } } thrift-0.23.0/lib/py/src/ext/protocol.h0000664000175000017500000000500515165535636020174 0ustar00buildbuild00000000000000/* * 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_PY_PROTOCOL_H #define THRIFT_PY_PROTOCOL_H #include "ext/types.h" #include #include namespace apache { namespace thrift { namespace py { template class ProtocolBase { public: ProtocolBase() : stringLimit_((std::numeric_limits::max)()), containerLimit_((std::numeric_limits::max)()), output_(nullptr) {} inline virtual ~ProtocolBase(); bool prepareDecodeBufferFromTransport(PyObject* trans); PyObject* readStruct(PyObject* output, PyObject* klass, PyObject* spec_seq); bool prepareEncodeBuffer(); bool encodeValue(PyObject* value, TType type, PyObject* typeargs); PyObject* getEncodedValue(); long stringLimit() const { return stringLimit_; } void setStringLengthLimit(long limit) { stringLimit_ = limit; } long containerLimit() const { return containerLimit_; } void setContainerLengthLimit(long limit) { containerLimit_ = limit; } protected: bool readBytes(char** output, int len); bool readByte(uint8_t& val) { char* buf; if (!readBytes(&buf, 1)) { return false; } val = static_cast(buf[0]); return true; } bool writeBuffer(char* data, size_t len); void writeByte(uint8_t val) { writeBuffer(reinterpret_cast(&val), 1); } PyObject* decodeValue(TType type, PyObject* typeargs); bool skip(TType type); inline bool checkType(TType got, TType expected); inline bool checkLengthLimit(int32_t len, long limit); inline bool isUtf8(PyObject* typeargs); private: Impl* impl() { return static_cast(this); } long stringLimit_; long containerLimit_; EncodeBuffer* output_; DecodeBuffer input_; }; } } } #include "ext/protocol.tcc" #endif // THRIFT_PY_PROTOCOL_H thrift-0.23.0/lib/py/src/ext/binary.cpp0000664000175000017500000000216615165535636020157 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define PY_SSIZE_T_CLEAN #include "ext/binary.h" namespace apache { namespace thrift { namespace py { bool BinaryProtocol::readFieldBegin(TType& type, int16_t& tag) { uint8_t b = 0; if (!readByte(b)) { return false; } type = static_cast(b); if (type == T_STOP) { return true; } return readI16(tag); } } } } thrift-0.23.0/lib/py/src/ext/binary.h0000664000175000017500000001355415167543515017624 0ustar00buildbuild00000000000000/* * 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_PY_BINARY_H #define THRIFT_PY_BINARY_H #include #include "ext/protocol.h" #include "ext/endian.h" #include namespace apache { namespace thrift { namespace py { class BinaryProtocol : public ProtocolBase { public: virtual ~BinaryProtocol() {} void writeI8(int8_t val) { writeBuffer(reinterpret_cast(&val), sizeof(int8_t)); } void writeI16(int16_t val) { int16_t net = static_cast(htons(val)); writeBuffer(reinterpret_cast(&net), sizeof(int16_t)); } void writeI32(int32_t val) { int32_t net = static_cast(htonl(val)); writeBuffer(reinterpret_cast(&net), sizeof(int32_t)); } void writeI64(int64_t val) { int64_t net = static_cast(htonll(val)); writeBuffer(reinterpret_cast(&net), sizeof(int64_t)); } void writeDouble(double dub) { // Unfortunately, bitwise_cast doesn't work in C. Bad C! union { double f; int64_t t; } transfer; transfer.f = dub; writeI64(transfer.t); } void writeBool(int v) { writeByte(static_cast(v)); } void writeString(PyObject* value, int32_t len) { writeI32(len); writeBuffer(PyBytes_AS_STRING(value), len); } bool writeListBegin(PyObject* value, const SetListTypeArgs& parsedargs, int32_t len) { writeByte(parsedargs.element_type); writeI32(len); return true; } bool writeMapBegin(PyObject* value, const MapTypeArgs& parsedargs, int32_t len) { writeByte(parsedargs.ktag); writeByte(parsedargs.vtag); writeI32(len); return true; } bool writeStructBegin() { return true; } bool writeStructEnd() { return true; } bool writeField(PyObject* value, const StructItemSpec& parsedspec) { writeByte(static_cast(parsedspec.type)); writeI16(parsedspec.tag); return encodeValue(value, parsedspec.type, parsedspec.typeargs); } void writeUuid(char* value) { writeBuffer(value, 16); } void writeFieldStop() { writeByte(static_cast(T_STOP)); } bool readBool(bool& val) { char* buf; if (!readBytes(&buf, 1)) { return false; } val = buf[0] == 1; return true; } bool readI8(int8_t& val) { char* buf; if (!readBytes(&buf, 1)) { return false; } val = buf[0]; return true; } bool readI16(int16_t& val) { char* buf; if (!readBytes(&buf, sizeof(int16_t))) { return false; } memcpy(&val, buf, sizeof(int16_t)); val = ntohs(val); return true; } bool readI32(int32_t& val) { char* buf; if (!readBytes(&buf, sizeof(int32_t))) { return false; } memcpy(&val, buf, sizeof(int32_t)); val = ntohl(val); return true; } bool readI64(int64_t& val) { char* buf; if (!readBytes(&buf, sizeof(int64_t))) { return false; } memcpy(&val, buf, sizeof(int64_t)); val = ntohll(val); return true; } bool readDouble(double& val) { union { int64_t f; double t; } transfer; if (!readI64(transfer.f)) { return false; } val = transfer.t; return true; } int32_t readString(char** buf) { int32_t len = 0; if (!readI32(len) || !checkLengthLimit(len, stringLimit()) || !readBytes(buf, len)) { return -1; } return len; } int32_t readUuid(char** buf) { if (!readBytes(buf, 16)) { return -1; } return 16; } int32_t readListBegin(TType& etype) { int32_t len; uint8_t b = 0; if (!readByte(b) || !readI32(len) || !checkLengthLimit(len, containerLimit())) { return -1; } etype = static_cast(b); return len; } int32_t readMapBegin(TType& ktype, TType& vtype) { int32_t len; uint8_t k, v; if (!readByte(k) || !readByte(v) || !readI32(len) || !checkLengthLimit(len, containerLimit())) { return -1; } ktype = static_cast(k); vtype = static_cast(v); return len; } bool readStructBegin() { return true; } bool readStructEnd() { return true; } bool readFieldBegin(TType& type, int16_t& tag); #define SKIPBYTES(n) \ do { \ if (!readBytes(&dummy_buf_, (n))) { \ return false; \ } \ return true; \ } while (0) bool skipBool() { SKIPBYTES(1); } bool skipByte() { SKIPBYTES(1); } bool skipI16() { SKIPBYTES(2); } bool skipI32() { SKIPBYTES(4); } bool skipI64() { SKIPBYTES(8); } bool skipDouble() { SKIPBYTES(8); } bool skipString() { int32_t len; if (!readI32(len)) { return false; } SKIPBYTES(len); } bool skipUuid() { SKIPBYTES(16); } #undef SKIPBYTES private: char* dummy_buf_; }; } } } #endif // THRIFT_PY_BINARY_H thrift-0.23.0/lib/py/src/ext/types.h0000664000175000017500000001053215167543515017475 0ustar00buildbuild00000000000000/* * 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_PY_TYPES_H #define THRIFT_PY_TYPES_H #include #ifdef _MSC_VER #define __STDC_FORMAT_MACROS #define __STDC_LIMIT_MACROS #endif #include #if PY_MAJOR_VERSION >= 3 #include // TODO: better macros #define PyInt_AsLong(v) PyLong_AsLong(v) #define PyInt_FromLong(v) PyLong_FromLong(v) #define PyString_InternFromString(v) PyUnicode_InternFromString(v) #endif #define INTERN_STRING(value) _intern_##value #define INT_CONV_ERROR_OCCURRED(v) (((v) == -1) && PyErr_Occurred()) extern "C" { extern PyObject* INTERN_STRING(TFrozenDict); extern PyObject* INTERN_STRING(cstringio_buf); extern PyObject* INTERN_STRING(cstringio_refill); extern PyObject* INTERN_STRING(UUID); extern PyObject* INTERN_STRING(bytes); } namespace apache { namespace thrift { namespace py { extern PyObject* ThriftModule; extern PyObject* UuidModule; // Stolen out of TProtocol.h. // It would be a huge pain to have both get this from one place. enum TType { T_INVALID = -1, T_STOP = 0, T_VOID = 1, T_BOOL = 2, T_BYTE = 3, T_I08 = 3, T_I16 = 6, T_I32 = 8, T_U64 = 9, T_I64 = 10, T_DOUBLE = 4, T_STRING = 11, T_UTF7 = 11, T_STRUCT = 12, T_MAP = 13, T_SET = 14, T_LIST = 15, T_UUID = 16, }; // replace with unique_ptr when we're OK with C++11 class ScopedPyObject { public: ScopedPyObject() : obj_(nullptr) {} explicit ScopedPyObject(PyObject* py_object) : obj_(py_object) {} ~ScopedPyObject() { if (obj_) Py_DECREF(obj_); } PyObject* get() throw() { return obj_; } operator bool() { return obj_; } void reset(PyObject* py_object) throw() { if (obj_) Py_DECREF(obj_); obj_ = py_object; } PyObject* release() throw() { PyObject* tmp = obj_; obj_ = nullptr; return tmp; } void swap(ScopedPyObject& other) throw() { ScopedPyObject tmp(other.release()); other.reset(release()); reset(tmp.release()); } private: ScopedPyObject(const ScopedPyObject&) {} ScopedPyObject& operator=(const ScopedPyObject&) { return *this; } PyObject* obj_; }; /** * A cache of the two key attributes of a CReadableTransport, * so we don't have to keep calling PyObject_GetAttr. */ struct DecodeBuffer { ScopedPyObject stringiobuf; ScopedPyObject refill_callable; }; #if PY_MAJOR_VERSION < 3 extern char refill_signature[3]; typedef PyObject EncodeBuffer; #else extern const char* refill_signature; struct EncodeBuffer { std::vector buf; size_t pos; }; #endif /** * A cache of the spec_args for a set or list, * so we don't have to keep calling PyTuple_GET_ITEM. */ struct SetListTypeArgs { TType element_type; PyObject* typeargs; bool immutable; }; /** * A cache of the spec_args for a map, * so we don't have to keep calling PyTuple_GET_ITEM. */ struct MapTypeArgs { TType ktag; TType vtag; PyObject* ktypeargs; PyObject* vtypeargs; bool immutable; }; /** * A cache of the spec_args for a struct, * so we don't have to keep calling PyTuple_GET_ITEM. */ struct StructTypeArgs { PyObject* klass; PyObject* spec; bool immutable; }; /** * A cache of the item spec from a struct specification, * so we don't have to keep calling PyTuple_GET_ITEM. */ struct StructItemSpec { int tag; TType type; PyObject* attrname; PyObject* typeargs; PyObject* defval; }; bool parse_set_list_args(SetListTypeArgs* dest, PyObject* typeargs); bool parse_map_args(MapTypeArgs* dest, PyObject* typeargs); bool parse_struct_args(StructTypeArgs* dest, PyObject* typeargs); bool parse_struct_item_spec(StructItemSpec* dest, PyObject* spec_tuple); } } } #endif // THRIFT_PY_TYPES_H thrift-0.23.0/lib/py/src/TRecursive.py0000664000175000017500000000654215167543515020033 0ustar00buildbuild00000000000000# # 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 thrift.Thrift import TType TYPE_IDX = 1 SPEC_ARGS_IDX = 3 SPEC_ARGS_CLASS_REF_IDX = 0 SPEC_ARGS_THRIFT_SPEC_IDX = 1 def fix_spec(all_structs): """Wire up recursive references for all TStruct definitions inside of each thrift_spec.""" for struc in all_structs: spec = struc.thrift_spec for thrift_spec in spec: if thrift_spec is None: continue elif thrift_spec[TYPE_IDX] == TType.STRUCT: other = thrift_spec[SPEC_ARGS_IDX][SPEC_ARGS_CLASS_REF_IDX].thrift_spec thrift_spec[SPEC_ARGS_IDX][SPEC_ARGS_THRIFT_SPEC_IDX] = other elif thrift_spec[TYPE_IDX] in (TType.LIST, TType.SET): _fix_list_or_set(thrift_spec[SPEC_ARGS_IDX]) elif thrift_spec[TYPE_IDX] == TType.MAP: _fix_map(thrift_spec[SPEC_ARGS_IDX]) def _fix_list_or_set(element_type): # For a list or set, the thrift_spec entry looks like, # (1, TType.LIST, 'lister', (TType.STRUCT, [RecList, None], False), None, ), # 1 # so ``element_type`` will be, # (TType.STRUCT, [RecList, None], False) if element_type[0] == TType.STRUCT: element_type[1][1] = element_type[1][0].thrift_spec elif element_type[0] in (TType.LIST, TType.SET): _fix_list_or_set(element_type[1]) elif element_type[0] == TType.MAP: _fix_map(element_type[1]) def _fix_map(element_type): # For a map of key -> value type, ``element_type`` will be, # (TType.I16, None, TType.STRUCT, [RecMapBasic, None], False), None, ) # which is just a normal struct definition. # # For a map of key -> list / set, ``element_type`` will be, # (TType.I16, None, TType.LIST, (TType.STRUCT, [RecMapList, None], False), False) # and we need to process the 3rd element as a list. # # For a map of key -> map, ``element_type`` will be, # (TType.I16, None, TType.MAP, (TType.I16, None, TType.STRUCT, # [RecMapMap, None], False), False) # and need to process 3rd element as a map. # Is the map key a struct? if element_type[0] == TType.STRUCT: element_type[1][1] = element_type[1][0].thrift_spec elif element_type[0] in (TType.LIST, TType.SET): _fix_list_or_set(element_type[1]) elif element_type[0] == TType.MAP: _fix_map(element_type[1]) # Is the map value a struct? if element_type[2] == TType.STRUCT: element_type[3][1] = element_type[3][0].thrift_spec elif element_type[2] in (TType.LIST, TType.SET): _fix_list_or_set(element_type[3]) elif element_type[2] == TType.MAP: _fix_map(element_type[3]) thrift-0.23.0/lib/py/src/server/0000775000175000017500000000000015167543515016665 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/src/server/TNonblockingServer.py0000664000175000017500000003432715165535636023031 0ustar00buildbuild00000000000000# # 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. # """Implementation of non-blocking server. The main idea of the server is to receive and send requests only from the main thread. The thread pool should be sized for concurrent tasks, not maximum connections """ import logging import select import socket import struct import threading from collections import deque import queue from thrift.transport import TTransport from thrift.protocol.TBinaryProtocol import TBinaryProtocolFactory __all__ = ['TNonblockingServer'] logger = logging.getLogger(__name__) class Worker(threading.Thread): """Worker is a small helper to process incoming connection.""" def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue def run(self): """Process queries from task queue, stop if processor is None.""" while True: try: processor, iprot, oprot, otrans, callback = self.queue.get() if processor is None: break processor.process(iprot, oprot) callback(True, otrans.getvalue()) except Exception: logger.exception("Exception while processing request", exc_info=True) callback(False, b'') WAIT_LEN = 0 WAIT_MESSAGE = 1 WAIT_PROCESS = 2 SEND_ANSWER = 3 CLOSED = 4 def locked(func): """Decorator which locks self.lock.""" def nested(self, *args, **kwargs): self.lock.acquire() try: return func(self, *args, **kwargs) finally: self.lock.release() return nested def socket_exception(func): """Decorator close object on socket.error.""" def read(self, *args, **kwargs): try: return func(self, *args, **kwargs) except socket.error: logger.debug('ignoring socket exception', exc_info=True) self.close() return read class Message(object): def __init__(self, offset, len_, header): self.offset = offset self.len = len_ self.buffer = None self.is_header = header @property def end(self): return self.offset + self.len class Connection(object): """Basic class is represented connection. It can be in state: WAIT_LEN --- connection is reading request len. WAIT_MESSAGE --- connection is reading request. WAIT_PROCESS --- connection has just read whole request and waits for call ready routine. SEND_ANSWER --- connection is sending answer string (including length of answer). CLOSED --- socket was closed and connection should be deleted. """ def __init__(self, new_socket, wake_up): self.socket = new_socket self.socket.setblocking(False) self.status = WAIT_LEN self.len = 0 self.received = deque() self._reading = Message(0, 4, True) self._rbuf = b'' self._wbuf = b'' self.lock = threading.Lock() self.wake_up = wake_up self.remaining = False @socket_exception def read(self): """Reads data from stream and switch state.""" assert self.status in (WAIT_LEN, WAIT_MESSAGE) assert not self.received buf_size = 8192 first = True done = False while not done: read = self.socket.recv(buf_size) rlen = len(read) done = rlen < buf_size self._rbuf += read if first and rlen == 0: if self.status != WAIT_LEN or self._rbuf: logger.error('could not read frame from socket') else: logger.debug('read zero length. client might have disconnected') self.close() while len(self._rbuf) >= self._reading.end: if self._reading.is_header: mlen, = struct.unpack('!i', self._rbuf[:4]) if mlen < 0: logger.error('could not read the head from frame') self.close() break self._reading = Message(self._reading.end, mlen, False) self.status = WAIT_MESSAGE else: self._reading.buffer = self._rbuf self.received.append(self._reading) self._rbuf = self._rbuf[self._reading.end:] self._reading = Message(0, 4, True) first = False if self.received: self.status = WAIT_PROCESS break self.remaining = not done @socket_exception def write(self): """Writes data from socket and switch state.""" assert self.status == SEND_ANSWER sent = self.socket.send(self._wbuf) if sent == len(self._wbuf): self.status = WAIT_LEN self._wbuf = b'' self.len = 0 else: self._wbuf = self._wbuf[sent:] @locked def ready(self, all_ok, message): """Callback function for switching state and waking up main thread. This function is the only function witch can be called asynchronous. The ready can switch Connection to three states: WAIT_LEN if request was oneway. SEND_ANSWER if request was processed in normal way. CLOSED if request throws unexpected exception. The one wakes up main thread. """ assert self.status == WAIT_PROCESS if not all_ok: self.close() self.wake_up() return self.len = 0 if len(message) == 0: # it was a oneway request, do not write answer self._wbuf = b'' self.status = WAIT_LEN else: self._wbuf = struct.pack('!i', len(message)) + message self.status = SEND_ANSWER self.wake_up() @locked def is_writeable(self): """Return True if connection should be added to write list of select""" return self.status == SEND_ANSWER # it's not necessary, but... @locked def is_readable(self): """Return True if connection should be added to read list of select""" return self.status in (WAIT_LEN, WAIT_MESSAGE) @locked def is_closed(self): """Returns True if connection is closed.""" return self.status == CLOSED def fileno(self): """Returns the file descriptor of the associated socket.""" return self.socket.fileno() def close(self): """Closes connection""" self.status = CLOSED self.socket.close() class TNonblockingServer(object): """Non-blocking server.""" def __init__(self, processor, lsocket, inputProtocolFactory=None, outputProtocolFactory=None, threads=10): self.processor = processor self.socket = lsocket self.in_protocol = inputProtocolFactory or TBinaryProtocolFactory() self.out_protocol = outputProtocolFactory or self.in_protocol self.threads = int(threads) self.clients = {} self.tasks = queue.Queue() self._read, self._write = socket.socketpair() self.prepared = False self._stop = False self.poll = select.poll() if hasattr(select, 'poll') else None def setNumThreads(self, num): """Set the number of worker threads that should be created.""" # implement ThreadPool interface assert not self.prepared, "Can't change number of threads after start" self.threads = num def prepare(self): """Prepares server for serve requests.""" if self.prepared: return self.socket.listen() for _ in range(self.threads): thread = Worker(self.tasks) thread.daemon = True thread.start() self.prepared = True def wake_up(self): """Wake up main thread. The server usually waits in select call in we should terminate one. The simplest way is using socketpair. Select always wait to read from the first socket of socketpair. In this case, we can just write anything to the second socket from socketpair. """ self._write.send(b'1') def stop(self): """Stop the server. This method causes the serve() method to return. stop() may be invoked from within your handler, or from another thread. After stop() is called, serve() will return but the server will still be listening on the socket. serve() may then be called again to resume processing requests. Alternatively, close() may be called after serve() returns to close the server socket and shutdown all worker threads. """ self._stop = True self.wake_up() def _select(self): """Does select on open connections.""" readable = [self.socket.handle.fileno(), self._read.fileno()] writable = [] remaining = [] for i, connection in list(self.clients.items()): if connection.is_readable(): readable.append(connection.fileno()) if connection.remaining or connection.received: remaining.append(connection.fileno()) if connection.is_writeable(): writable.append(connection.fileno()) if connection.is_closed(): del self.clients[i] if remaining: return remaining, [], [], False else: return select.select(readable, writable, readable) + (True,) def _poll_select(self): """Does poll on open connections, if available.""" remaining = [] self.poll.register(self.socket.handle.fileno(), select.POLLIN | select.POLLRDNORM) self.poll.register(self._read.fileno(), select.POLLIN | select.POLLRDNORM) for i, connection in list(self.clients.items()): if connection.is_readable(): self.poll.register(connection.fileno(), select.POLLIN | select.POLLRDNORM | select.POLLERR | select.POLLHUP | select.POLLNVAL) if connection.remaining or connection.received: remaining.append(connection.fileno()) if connection.is_writeable(): self.poll.register(connection.fileno(), select.POLLOUT | select.POLLWRNORM) if connection.is_closed(): try: self.poll.unregister(i) except KeyError: logger.debug("KeyError in unregistering connections...") del self.clients[i] if remaining: return remaining, [], [], False rlist = [] wlist = [] xlist = [] pollres = self.poll.poll() for fd, event in pollres: if event & (select.POLLERR | select.POLLHUP | select.POLLNVAL): xlist.append(fd) elif event & (select.POLLOUT | select.POLLWRNORM): wlist.append(fd) elif event & (select.POLLIN | select.POLLRDNORM): rlist.append(fd) else: # should be impossible logger.debug("reached an impossible state in _poll_select") xlist.append(fd) return rlist, wlist, xlist, True def handle(self): """Handle requests. WARNING! You must call prepare() BEFORE calling handle() """ assert self.prepared, "You have to call prepare before handle" rset, wset, xset, selected = self._select() if not self.poll else self._poll_select() for readable in rset: if readable == self._read.fileno(): # don't care i just need to clean readable flag self._read.recv(1024) elif readable == self.socket.handle.fileno(): try: client = self.socket.accept() if client: self.clients[client.handle.fileno()] = Connection(client.handle, self.wake_up) except socket.error: logger.debug('error while accepting', exc_info=True) else: connection = self.clients[readable] if selected: connection.read() if connection.received: connection.status = WAIT_PROCESS if self.poll: self.poll.unregister(connection.fileno()) msg = connection.received.popleft() itransport = TTransport.TMemoryBuffer(msg.buffer, msg.offset) otransport = TTransport.TMemoryBuffer() iprot = self.in_protocol.getProtocol(itransport) oprot = self.out_protocol.getProtocol(otransport) self.tasks.put([self.processor, iprot, oprot, otransport, connection.ready]) for writeable in wset: self.clients[writeable].write() for oob in xset: self.clients[oob].close() def close(self): """Closes the server.""" for _ in range(self.threads): self.tasks.put([None, None, None, None, None]) self.socket.close() self.prepared = False def serve(self): """Serve requests. Serve requests forever, or until stop() is called. """ self._stop = False self.prepare() while not self._stop: self.handle() thrift-0.23.0/lib/py/src/server/THttpServer.py0000664000175000017500000001330315167543515021471 0ustar00buildbuild00000000000000# # 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 ssl import http.server as BaseHTTPServer from thrift.Thrift import TMessageType from thrift.server import TServer from thrift.transport import TTransport class ResponseException(Exception): """Allows handlers to override the HTTP response Normally, THttpServer always sends a 200 response. If a handler wants to override this behavior (e.g., to simulate a misconfigured or overloaded web server during testing), it can raise a ResponseException. The function passed to the constructor will be called with the RequestHandler as its only argument. Note that this is irrelevant for ONEWAY requests, as the HTTP response must be sent before the RPC is processed. """ def __init__(self, handler): self.handler = handler class THttpServer(TServer.TServer): """A simple HTTP-based Thrift server This class is not very performant, but it is useful (for example) for acting as a mock version of an Apache-based PHP Thrift endpoint. Also important to note the HTTP implementation pretty much violates the transport/protocol/processor/server layering, by performing the transport functions here. This means things like oneway handling are oddly exposed. """ def __init__(self, processor, server_address, inputProtocolFactory, outputProtocolFactory=None, server_class=BaseHTTPServer.HTTPServer, **kwargs): """Set up protocol factories and HTTP (or HTTPS) server. See BaseHTTPServer for server_address. See TServer for protocol factories. To make a secure server, provide the named arguments: * cafile - to validate clients [optional] * cert_file - the server cert * key_file - the server's key """ if outputProtocolFactory is None: outputProtocolFactory = inputProtocolFactory TServer.TServer.__init__(self, processor, None, None, None, inputProtocolFactory, outputProtocolFactory) thttpserver = self self._replied = None class RequestHander(BaseHTTPServer.BaseHTTPRequestHandler): def do_POST(self): # Don't care about the request path. thttpserver._replied = False iftrans = TTransport.TFileObjectTransport(self.rfile) itrans = TTransport.TBufferedTransport( iftrans, int(self.headers['Content-Length'])) otrans = TTransport.TMemoryBuffer() iprot = thttpserver.inputProtocolFactory.getProtocol(itrans) oprot = thttpserver.outputProtocolFactory.getProtocol(otrans) try: thttpserver.processor.on_message_begin(self.on_begin) thttpserver.processor.process(iprot, oprot) except ResponseException as exn: exn.handler(self) else: if not thttpserver._replied: # If the request was ONEWAY we would have replied already data = otrans.getvalue() self.send_response(200) self.send_header("Content-Length", len(data)) self.send_header("Content-Type", "application/x-thrift") self.end_headers() self.wfile.write(data) def on_begin(self, name, type, seqid): """ Inspect the message header. This allows us to post an immediate transport response if the request is a ONEWAY message type. """ if type == TMessageType.ONEWAY: self.send_response(200) self.send_header("Content-Type", "application/x-thrift") self.end_headers() thttpserver._replied = True self.httpd = server_class(server_address, RequestHander) if (kwargs.get('cafile') or kwargs.get('cert_file') or kwargs.get('key_file')): if hasattr(ssl, 'PROTOCOL_TLS_SERVER'): context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) else: context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) cafile = kwargs.get('cafile') if cafile: context.load_verify_locations(cafile=cafile) context.verify_mode = ssl.CERT_REQUIRED else: context.verify_mode = ssl.CERT_NONE context.load_cert_chain(kwargs.get('cert_file'), kwargs.get('key_file')) context.check_hostname = False self.httpd.socket = context.wrap_socket(self.httpd.socket, server_side=True) def serve(self): self.httpd.serve_forever() def shutdown(self): self.httpd.socket.close() # self.httpd.shutdown() # hangs forever, python doesn't handle POLLNVAL properly! thrift-0.23.0/lib/py/src/server/TServer.py0000664000175000017500000002676515165535636020654 0ustar00buildbuild00000000000000# # 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 queue import logging import os import threading from thrift.protocol import TBinaryProtocol from thrift.protocol.THeaderProtocol import THeaderProtocolFactory from thrift.transport import TTransport logger = logging.getLogger(__name__) class TServer(object): """Base interface for a server, which must have a serve() method. Three constructors for all servers: 1) (processor, serverTransport) 2) (processor, serverTransport, transportFactory, protocolFactory) 3) (processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory) """ def __init__(self, *args): if (len(args) == 2): self.__initArgs__(args[0], args[1], TTransport.TTransportFactoryBase(), TTransport.TTransportFactoryBase(), TBinaryProtocol.TBinaryProtocolFactory(), TBinaryProtocol.TBinaryProtocolFactory()) elif (len(args) == 4): self.__initArgs__(args[0], args[1], args[2], args[2], args[3], args[3]) elif (len(args) == 6): self.__initArgs__(args[0], args[1], args[2], args[3], args[4], args[5]) def __initArgs__(self, processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory): self.processor = processor self.serverTransport = serverTransport self.inputTransportFactory = inputTransportFactory self.outputTransportFactory = outputTransportFactory self.inputProtocolFactory = inputProtocolFactory self.outputProtocolFactory = outputProtocolFactory input_is_header = isinstance(self.inputProtocolFactory, THeaderProtocolFactory) output_is_header = isinstance(self.outputProtocolFactory, THeaderProtocolFactory) if any((input_is_header, output_is_header)) and input_is_header != output_is_header: raise ValueError("THeaderProtocol servers require that both the input and " "output protocols are THeaderProtocol.") def serve(self): pass class TSimpleServer(TServer): """Simple single-threaded server that just pumps around one transport.""" def __init__(self, *args): TServer.__init__(self, *args) def serve(self): self.serverTransport.listen() while True: client = self.serverTransport.accept() if not client: continue itrans = self.inputTransportFactory.getTransport(client) iprot = self.inputProtocolFactory.getProtocol(itrans) # for THeaderProtocol, we must use the same protocol instance for # input and output so that the response is in the same dialect that # the server detected the request was in. if isinstance(self.inputProtocolFactory, THeaderProtocolFactory): otrans = None oprot = iprot else: otrans = self.outputTransportFactory.getTransport(client) oprot = self.outputProtocolFactory.getProtocol(otrans) try: while True: self.processor.process(iprot, oprot) except TTransport.TTransportException: pass except Exception as x: logger.exception(x) itrans.close() if otrans: otrans.close() class TThreadedServer(TServer): """Threaded server that spawns a new thread per each connection.""" def __init__(self, *args, **kwargs): TServer.__init__(self, *args) self.daemon = kwargs.get("daemon", False) def serve(self): self.serverTransport.listen() while True: try: client = self.serverTransport.accept() if not client: continue t = threading.Thread(target=self.handle, args=(client,)) t.daemon = self.daemon t.start() except KeyboardInterrupt: raise except Exception as x: logger.exception(x) def handle(self, client): itrans = self.inputTransportFactory.getTransport(client) iprot = self.inputProtocolFactory.getProtocol(itrans) # for THeaderProtocol, we must use the same protocol instance for input # and output so that the response is in the same dialect that the # server detected the request was in. if isinstance(self.inputProtocolFactory, THeaderProtocolFactory): otrans = None oprot = iprot else: otrans = self.outputTransportFactory.getTransport(client) oprot = self.outputProtocolFactory.getProtocol(otrans) try: while True: self.processor.process(iprot, oprot) except TTransport.TTransportException: pass except Exception as x: logger.exception(x) itrans.close() if otrans: otrans.close() class TThreadPoolServer(TServer): """Server with a fixed size pool of threads which service requests.""" def __init__(self, *args, **kwargs): TServer.__init__(self, *args) self.clients = queue.Queue() self.threads = 10 self.daemon = kwargs.get("daemon", False) def setNumThreads(self, num): """Set the number of worker threads that should be created""" self.threads = num def serveThread(self): """Loop around getting clients from the shared queue and process them.""" while True: try: client = self.clients.get() self.serveClient(client) except Exception as x: logger.exception(x) def serveClient(self, client): """Process input/output from a client for as long as possible""" itrans = self.inputTransportFactory.getTransport(client) iprot = self.inputProtocolFactory.getProtocol(itrans) # for THeaderProtocol, we must use the same protocol instance for input # and output so that the response is in the same dialect that the # server detected the request was in. if isinstance(self.inputProtocolFactory, THeaderProtocolFactory): otrans = None oprot = iprot else: otrans = self.outputTransportFactory.getTransport(client) oprot = self.outputProtocolFactory.getProtocol(otrans) try: while True: self.processor.process(iprot, oprot) except TTransport.TTransportException: pass except Exception as x: logger.exception(x) itrans.close() if otrans: otrans.close() def serve(self): """Start a fixed number of worker threads and put client into a queue""" for i in range(self.threads): try: t = threading.Thread(target=self.serveThread) t.daemon = self.daemon t.start() except Exception as x: logger.exception(x) # Pump the socket for clients self.serverTransport.listen() while True: try: client = self.serverTransport.accept() if not client: continue self.clients.put(client) except Exception as x: logger.exception(x) class TForkingServer(TServer): """A Thrift server that forks a new process for each request This is more scalable than the threaded server as it does not cause GIL contention. Note that this has different semantics from the threading server. Specifically, updates to shared variables will no longer be shared. It will also not work on windows. This code is heavily inspired by SocketServer.ForkingMixIn in the Python stdlib. """ def __init__(self, *args): TServer.__init__(self, *args) self.children = [] def serve(self): def try_close(file): try: file.close() except IOError as e: logger.warning(e, exc_info=True) self.serverTransport.listen() while True: client = self.serverTransport.accept() if not client: continue try: pid = os.fork() if pid: # parent # add before collect, otherwise you race w/ waitpid self.children.append(pid) self.collect_children() # Parent must close socket or the connection may not get # closed promptly itrans = self.inputTransportFactory.getTransport(client) otrans = self.outputTransportFactory.getTransport(client) try_close(itrans) try_close(otrans) else: itrans = self.inputTransportFactory.getTransport(client) iprot = self.inputProtocolFactory.getProtocol(itrans) # for THeaderProtocol, we must use the same protocol # instance for input and output so that the response is in # the same dialect that the server detected the request was # in. if isinstance(self.inputProtocolFactory, THeaderProtocolFactory): otrans = None oprot = iprot else: otrans = self.outputTransportFactory.getTransport(client) oprot = self.outputProtocolFactory.getProtocol(otrans) ecode = 0 try: try: while True: self.processor.process(iprot, oprot) except TTransport.TTransportException: pass except Exception as e: logger.exception(e) ecode = 1 finally: try_close(itrans) if otrans: try_close(otrans) os._exit(ecode) except TTransport.TTransportException: pass except Exception as x: logger.exception(x) def collect_children(self): while self.children: try: pid, status = os.waitpid(0, os.WNOHANG) except os.error: pid = None if pid: self.children.remove(pid) else: break thrift-0.23.0/lib/py/src/server/TProcessPoolServer.py0000664000175000017500000001011515165535636023023 0ustar00buildbuild00000000000000# # 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 logging from multiprocessing import Process, Value, Condition from .TServer import TServer from thrift.transport.TTransport import TTransportException logger = logging.getLogger(__name__) class TProcessPoolServer(TServer): """Server with a fixed size pool of worker subprocesses to service requests Note that if you need shared state between the handlers - it's up to you! Written by Dvir Volk, doat.com """ def __init__(self, *args): TServer.__init__(self, *args) self.numWorkers = 10 self.workers = [] self.isRunning = Value('b', False) self.stopCondition = Condition() self.postForkCallback = None def __getstate__(self): state = self.__dict__.copy() state['workers'] = None return state def setPostForkCallback(self, callback): if not callable(callback): raise TypeError("This is not a callback!") self.postForkCallback = callback def setNumWorkers(self, num): """Set the number of worker threads that should be created""" self.numWorkers = num def workerProcess(self): """Loop getting clients from the shared queue and process them""" if self.postForkCallback: self.postForkCallback() while self.isRunning.value: try: client = self.serverTransport.accept() if not client: continue self.serveClient(client) except (KeyboardInterrupt, SystemExit): return 0 except Exception as x: logger.exception(x) def serveClient(self, client): """Process input/output from a client for as long as possible""" itrans = self.inputTransportFactory.getTransport(client) otrans = self.outputTransportFactory.getTransport(client) iprot = self.inputProtocolFactory.getProtocol(itrans) oprot = self.outputProtocolFactory.getProtocol(otrans) try: while True: self.processor.process(iprot, oprot) except TTransportException: pass except Exception as x: logger.exception(x) itrans.close() otrans.close() def serve(self): """Start workers and put into queue""" # this is a shared state that can tell the workers to exit when False self.isRunning.value = True # first bind and listen to the port self.serverTransport.listen() # fork the children for i in range(self.numWorkers): try: w = Process(target=self.workerProcess) w.daemon = True w.start() self.workers.append(w) except Exception as x: logger.exception(x) # wait until the condition is set by stop() while True: self.stopCondition.acquire() try: self.stopCondition.wait() break except (SystemExit, KeyboardInterrupt): break except Exception as x: logger.exception(x) self.isRunning.value = False def stop(self): self.isRunning.value = False self.stopCondition.acquire() self.stopCondition.notify() self.stopCondition.release() thrift-0.23.0/lib/py/src/server/__init__.py0000664000175000017500000000147615165535636021011 0ustar00buildbuild00000000000000# # 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. # __all__ = ['TServer', 'TNonblockingServer'] thrift-0.23.0/lib/py/src/TSCons.py0000664000175000017500000000240315165535636017104 0ustar00buildbuild00000000000000# # 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 os import path from SCons.Builder import Builder def scons_env(env, add=''): opath = path.dirname(path.abspath('$TARGET')) lstr = 'thrift --gen cpp -o ' + opath + ' ' + add + ' $SOURCE' cppbuild = Builder(action=lstr) env.Append(BUILDERS={'ThriftCpp': cppbuild}) def gen_cpp(env, dir, file): scons_env(env) suffixes = ['_types.h', '_types.cpp'] targets = map(lambda s: 'gen-cpp/' + file + s, suffixes) return env.ThriftCpp(targets, dir + file + '.thrift') thrift-0.23.0/lib/py/src/transport/0000775000175000017500000000000015167543515017413 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/src/transport/THttpClient.py0000664000175000017500000001641215167543515022173 0ustar00buildbuild00000000000000# # 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 io import BytesIO import os import ssl import sys import warnings import base64 import urllib.parse import urllib.request import http.client from .TTransport import TTransportBase class THttpClient(TTransportBase): """Http implementation of TTransport base.""" def __init__(self, uri_or_host, port=None, path=None, cafile=None, cert_file=None, key_file=None, ssl_context=None): """THttpClient supports two different types of construction: THttpClient(host, port, path) - deprecated THttpClient(uri, [port=, path=, cafile=, cert_file=, key_file=, ssl_context=]) Only the second supports https. To properly authenticate against the server, provide the client's identity by specifying cert_file and key_file. To properly authenticate the server, specify either cafile or ssl_context with a CA defined. NOTE: if ssl_context is defined, it will override any provided cert_file, key_file, and cafile. """ if port is not None: warnings.warn( "Please use the THttpClient('http{s}://host:port/path') constructor", DeprecationWarning, stacklevel=2) self.host = uri_or_host self.port = port assert path self.path = path self.scheme = 'http' else: parsed = urllib.parse.urlparse(uri_or_host) self.scheme = parsed.scheme assert self.scheme in ('http', 'https') if self.scheme == 'http': self.port = parsed.port or http.client.HTTP_PORT elif self.scheme == 'https': self.port = parsed.port or http.client.HTTPS_PORT if (cafile or cert_file or key_file) and not ssl_context: self.context = ssl.create_default_context(cafile=cafile) self.context.load_cert_chain(certfile=cert_file, keyfile=key_file) else: self.context = ssl_context self.host = parsed.hostname self.path = parsed.path if parsed.query: self.path += '?%s' % parsed.query try: proxy = urllib.request.getproxies()[self.scheme] except KeyError: proxy = None else: if urllib.request.proxy_bypass(self.host): proxy = None if proxy: parsed = urllib.parse.urlparse(proxy) self.realhost = self.host self.realport = self.port self.host = parsed.hostname self.port = parsed.port self.proxy_auth = self.basic_proxy_auth_header(parsed) else: self.realhost = self.realport = self.proxy_auth = None self.__wbuf = BytesIO() self.__http = None self.__http_response = None self.__timeout = None self.__custom_headers = None self.headers = None @staticmethod def basic_proxy_auth_header(proxy): if proxy is None or not proxy.username: return None ap = "%s:%s" % (urllib.parse.unquote(proxy.username), urllib.parse.unquote(proxy.password)) cr = base64.b64encode(ap.encode()).strip() return "Basic " + cr.decode("ascii") def using_proxy(self): return self.realhost is not None def open(self): if self.scheme == 'http': 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, timeout=self.__timeout, context=self.context) if self.using_proxy(): self.__http.set_tunnel(self.realhost, self.realport, {"Proxy-Authorization": self.proxy_auth}) def close(self): self.__http.close() self.__http = None self.__http_response = None def isOpen(self): return self.__http is not None def setTimeout(self, ms): if ms is None: self.__timeout = None else: self.__timeout = ms / 1000.0 def setCustomHeaders(self, headers): self.__custom_headers = headers def read(self, sz): return self.__http_response.read(sz) def write(self, buf): self.__wbuf.write(buf) def flush(self): if self.isOpen(): self.close() self.open() # Pull data out of buffer data = self.__wbuf.getvalue() self.__wbuf = BytesIO() # HTTP request if self.using_proxy() and self.scheme == "http": # need full URL of real host for HTTP proxy here (HTTPS uses CONNECT tunnel) self.__http.putrequest('POST', "http://%s:%s%s" % (self.realhost, self.realport, self.path)) else: self.__http.putrequest('POST', self.path) # Write headers self.__http.putheader('Content-Type', 'application/x-thrift') self.__http.putheader('Content-Length', str(len(data))) if self.using_proxy() and self.scheme == "http" and self.proxy_auth is not None: self.__http.putheader("Proxy-Authorization", self.proxy_auth) if not self.__custom_headers or 'User-Agent' not in self.__custom_headers: user_agent = 'Python/THttpClient' script = os.path.basename(sys.argv[0]) if script: user_agent = '%s (%s)' % (user_agent, urllib.parse.quote(script)) self.__http.putheader('User-Agent', user_agent) if 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. # HTTPConnection.putheader can only be called after a request has been # started, and before it's been sent. if self.headers and 'Set-Cookie' in self.headers: self.__http.putheader('Cookie', self.headers['Set-Cookie']) self.__http.endheaders() # Write payload self.__http.send(data) # Get reply to flush the request self.__http_response = self.__http.getresponse() self.code = self.__http_response.status self.message = self.__http_response.reason self.headers = self.__http_response.msg thrift-0.23.0/lib/py/src/transport/THeaderTransport.py0000664000175000017500000003120315165535636023220 0ustar00buildbuild00000000000000# # 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 struct import zlib from io import BytesIO from thrift.protocol.TBinaryProtocol import TBinaryProtocol from thrift.protocol.TCompactProtocol import TCompactProtocol, readVarint, writeVarint from thrift.Thrift import TApplicationException from thrift.transport.TTransport import ( CReadableTransport, TMemoryBuffer, TTransportBase, TTransportException, ) U16 = struct.Struct("!H") I32 = struct.Struct("!i") HEADER_MAGIC = 0x0FFF HARD_MAX_FRAME_SIZE = 0x3FFFFFFF class THeaderClientType(object): HEADERS = 0x00 FRAMED_BINARY = 0x01 UNFRAMED_BINARY = 0x02 FRAMED_COMPACT = 0x03 UNFRAMED_COMPACT = 0x04 class THeaderSubprotocolID(object): BINARY = 0x00 COMPACT = 0x02 class TInfoHeaderType(object): KEY_VALUE = 0x01 class THeaderTransformID(object): ZLIB = 0x01 READ_TRANSFORMS_BY_ID = { THeaderTransformID.ZLIB: zlib.decompress, } WRITE_TRANSFORMS_BY_ID = { THeaderTransformID.ZLIB: zlib.compress, } def _readString(trans): size = readVarint(trans) if size < 0: raise TTransportException( TTransportException.NEGATIVE_SIZE, "Negative length" ) return trans.read(size) def _writeString(trans, value): writeVarint(trans, len(value)) trans.write(value) class THeaderTransport(TTransportBase, CReadableTransport): def __init__(self, transport, allowed_client_types, default_protocol=THeaderSubprotocolID.BINARY): self._transport = transport self._client_type = THeaderClientType.HEADERS self._allowed_client_types = allowed_client_types self._read_buffer = BytesIO(b"") self._read_headers = {} self._write_buffer = BytesIO() self._write_headers = {} self._write_transforms = [] self.flags = 0 self.sequence_id = 0 self._protocol_id = default_protocol self._max_frame_size = HARD_MAX_FRAME_SIZE def isOpen(self): return self._transport.isOpen() def open(self): return self._transport.open() def close(self): return self._transport.close() def get_headers(self): return self._read_headers def set_header(self, key, value): if not isinstance(key, bytes): raise ValueError("header names must be bytes") if not isinstance(value, bytes): raise ValueError("header values must be bytes") self._write_headers[key] = value def clear_headers(self): self._write_headers.clear() def add_transform(self, transform_id): if transform_id not in WRITE_TRANSFORMS_BY_ID: raise ValueError("unknown transform") self._write_transforms.append(transform_id) def set_max_frame_size(self, size): if not 0 < size < HARD_MAX_FRAME_SIZE: raise ValueError("maximum frame size should be < %d and > 0" % HARD_MAX_FRAME_SIZE) self._max_frame_size = size @property def protocol_id(self): if self._client_type == THeaderClientType.HEADERS: return self._protocol_id elif self._client_type in (THeaderClientType.FRAMED_BINARY, THeaderClientType.UNFRAMED_BINARY): return THeaderSubprotocolID.BINARY elif self._client_type in (THeaderClientType.FRAMED_COMPACT, THeaderClientType.UNFRAMED_COMPACT): return THeaderSubprotocolID.COMPACT else: raise TTransportException( TTransportException.INVALID_CLIENT_TYPE, "Protocol ID not know for client type %d" % self._client_type, ) def read(self, sz): # if there are bytes left in the buffer, produce those first. bytes_read = self._read_buffer.read(sz) bytes_left_to_read = sz - len(bytes_read) if bytes_left_to_read == 0: return bytes_read # if we've determined this is an unframed client, just pass the read # through to the underlying transport until we're reset again at the # beginning of the next message. if self._client_type in (THeaderClientType.UNFRAMED_BINARY, THeaderClientType.UNFRAMED_COMPACT): return bytes_read + self._transport.read(bytes_left_to_read) # we're empty and (maybe) framed. fill the buffers with the next frame. self.readFrame(bytes_left_to_read) return bytes_read + self._read_buffer.read(bytes_left_to_read) def _set_client_type(self, client_type): if client_type not in self._allowed_client_types: raise TTransportException( TTransportException.INVALID_CLIENT_TYPE, "Client type %d not allowed by server." % client_type, ) self._client_type = client_type def readFrame(self, req_sz): # the first word could either be the length field of a framed message # or the first bytes of an unframed message. first_word = self._transport.readAll(I32.size) frame_size, = I32.unpack(first_word) is_unframed = False if frame_size & TBinaryProtocol.VERSION_MASK == TBinaryProtocol.VERSION_1: self._set_client_type(THeaderClientType.UNFRAMED_BINARY) is_unframed = True 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 if is_unframed: bytes_left_to_read = req_sz - I32.size if bytes_left_to_read > 0: rest = self._transport.read(bytes_left_to_read) else: rest = b"" self._read_buffer = BytesIO(first_word + rest) return # ok, we're still here so we're framed. if frame_size > self._max_frame_size: raise TTransportException( TTransportException.SIZE_LIMIT, "Frame was too large.", ) 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 # header protocol message. second_word = read_buffer.read(I32.size) version, = I32.unpack(second_word) read_buffer.seek(0) if version >> 16 == HEADER_MAGIC: self._set_client_type(THeaderClientType.HEADERS) self._read_buffer = self._parse_header_format(read_buffer) elif version & TBinaryProtocol.VERSION_MASK == TBinaryProtocol.VERSION_1: self._set_client_type(THeaderClientType.FRAMED_BINARY) self._read_buffer = read_buffer 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: raise TTransportException( TTransportException.INVALID_CLIENT_TYPE, "Could not detect client transport type.", ) def _parse_header_format(self, buffer): # make BytesIO look like TTransport for varint helpers buffer_transport = TMemoryBuffer() buffer_transport._buffer = buffer buffer.read(2) # discard the magic bytes self.flags, = U16.unpack(buffer.read(U16.size)) self.sequence_id, = I32.unpack(buffer.read(I32.size)) header_length = U16.unpack(buffer.read(U16.size))[0] * 4 end_of_headers = buffer.tell() + header_length if end_of_headers > len(buffer.getvalue()): raise TTransportException( TTransportException.SIZE_LIMIT, "Header size is larger than whole frame.", ) self._protocol_id = readVarint(buffer_transport) transforms = [] transform_count = readVarint(buffer_transport) for _ in range(transform_count): transform_id = readVarint(buffer_transport) if transform_id not in READ_TRANSFORMS_BY_ID: raise TApplicationException( TApplicationException.INVALID_TRANSFORM, "Unknown transform: %d" % transform_id, ) transforms.append(transform_id) transforms.reverse() headers = {} while buffer.tell() < end_of_headers: header_type = readVarint(buffer_transport) if header_type == TInfoHeaderType.KEY_VALUE: count = readVarint(buffer_transport) for _ in range(count): key = _readString(buffer_transport) value = _readString(buffer_transport) headers[key] = value else: break # ignore unknown headers self._read_headers = headers # skip padding / anything we didn't understand buffer.seek(end_of_headers) payload = buffer.read() for transform_id in transforms: transform_fn = READ_TRANSFORMS_BY_ID[transform_id] payload = transform_fn(payload) return BytesIO(payload) def write(self, buf): self._write_buffer.write(buf) def flush(self): payload = self._write_buffer.getvalue() self._write_buffer = BytesIO() 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 = BytesIO() writeVarint(headers, self._protocol_id) writeVarint(headers, len(self._write_transforms)) for transform_id in self._write_transforms: writeVarint(headers, transform_id) if self._write_headers: writeVarint(headers, TInfoHeaderType.KEY_VALUE) writeVarint(headers, len(self._write_headers)) for key, value in self._write_headers.items(): _writeString(headers, key) _writeString(headers, value) self._write_headers = {} padding_needed = (4 - (len(headers.getvalue()) % 4)) % 4 headers.write(b"\x00" * padding_needed) header_bytes = headers.getvalue() buffer.write(I32.pack(10 + len(header_bytes) + len(payload))) buffer.write(U16.pack(HEADER_MAGIC)) buffer.write(U16.pack(self.flags)) buffer.write(I32.pack(self.sequence_id)) buffer.write(U16.pack(len(header_bytes) // 4)) buffer.write(header_bytes) buffer.write(payload) elif self._client_type in (THeaderClientType.FRAMED_BINARY, THeaderClientType.FRAMED_COMPACT): buffer.write(I32.pack(len(payload))) buffer.write(payload) elif self._client_type in (THeaderClientType.UNFRAMED_BINARY, THeaderClientType.UNFRAMED_COMPACT): buffer.write(payload) else: raise TTransportException( TTransportException.INVALID_CLIENT_TYPE, "Unknown client type.", ) # the frame length field doesn't count towards the frame payload size frame_bytes = buffer.getvalue() frame_payload_size = len(frame_bytes) - 4 if frame_payload_size > self._max_frame_size: raise TTransportException( TTransportException.SIZE_LIMIT, "Attempting to send frame that is too large.", ) self._transport.write(frame_bytes) self._transport.flush() @property def cstringio_buf(self): return self._read_buffer def cstringio_refill(self, partialread, reqlen): result = bytearray(partialread) while len(result) < reqlen: result += self.read(reqlen - len(result)) self._read_buffer = BytesIO(result) return self._read_buffer thrift-0.23.0/lib/py/src/transport/TTransport.py0000664000175000017500000003254715167543515022120 0ustar00buildbuild00000000000000# # 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 io import BytesIO from struct import pack, unpack from thrift.Thrift import TException class TTransportException(TException): """Custom Transport Exception class""" UNKNOWN = 0 NOT_OPEN = 1 ALREADY_OPEN = 2 TIMED_OUT = 3 END_OF_FILE = 4 NEGATIVE_SIZE = 5 SIZE_LIMIT = 6 INVALID_CLIENT_TYPE = 7 def __init__(self, type=UNKNOWN, message=None, inner=None): TException.__init__(self, message) self.type = type self.inner = inner class TTransportBase(object): """Base class for Thrift transport layer.""" def isOpen(self): pass def open(self): pass def close(self): pass def read(self, sz): pass def readAll(self, sz): buff = b'' have = 0 while (have < sz): chunk = self.read(sz - have) chunkLen = len(chunk) have += chunkLen buff += chunk if chunkLen == 0: raise EOFError() return buff def write(self, buf): pass def flush(self): pass # This class should be thought of as an interface. class CReadableTransport(object): """base class for transports that are readable from C""" # TODO(dreiss): Think about changing this interface to allow us to use # a (Python, not c) StringIO instead, because it allows # you to write after reading. # NOTE: This is a classic class, so properties will NOT work # correctly for setting. @property def cstringio_buf(self): """A cStringIO buffer that contains the current chunk we are reading.""" pass def cstringio_refill(self, partialread, reqlen): """Refills cstringio_buf. Returns the currently used buffer (which can but need not be the same as the old cstringio_buf). partialread is what the C code has read from the buffer, and should be inserted into the buffer before any more reads. The return value must be a new, not borrowed reference. Something along the lines of self._buf should be fine. If reqlen bytes can't be read, throw EOFError. """ pass class TServerTransportBase(object): """Base class for Thrift server transports.""" def listen(self): pass def accept(self): pass def close(self): pass class TTransportFactoryBase(object): """Base class for a Transport Factory""" def getTransport(self, trans): return trans class TBufferedTransportFactory(object): """Factory transport that builds buffered transports""" def getTransport(self, trans): buffered = TBufferedTransport(trans) return buffered class TBufferedTransport(TTransportBase, CReadableTransport): """Class that wraps another transport and buffers its I/O. The implementation uses a (configurable) fixed-size read buffer but buffers all writes until a flush is performed. """ DEFAULT_BUFFER = 4096 def __init__(self, trans, rbuf_size=DEFAULT_BUFFER): self.__trans = trans self.__wbuf = BytesIO() # Pass string argument to initialize read buffer as cStringIO.InputType self.__rbuf = BytesIO(b'') self.__rbuf_size = rbuf_size def isOpen(self): return self.__trans.isOpen() def open(self): return self.__trans.open() def close(self): return self.__trans.close() def read(self, sz): ret = self.__rbuf.read(sz) if len(ret) != 0: return ret self.__rbuf = BytesIO(self.__trans.read(max(sz, self.__rbuf_size))) return self.__rbuf.read(sz) def write(self, buf): try: self.__wbuf.write(buf) except Exception as e: # on exception reset wbuf so it doesn't contain a partial function call 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 = BytesIO() self.__trans.write(out) self.__trans.flush() # Implement the CReadableTransport interface. @property def cstringio_buf(self): return self.__rbuf def cstringio_refill(self, partialread, reqlen): retstring = partialread if reqlen < self.__rbuf_size: # try to make a read of as much as we can. retstring += self.__trans.read(self.__rbuf_size) # but make sure we do read reqlen bytes. if len(retstring) < reqlen: retstring += self.__trans.readAll(reqlen - len(retstring)) self.__rbuf = BytesIO(retstring) return self.__rbuf class TMemoryBuffer(TTransportBase, CReadableTransport): """Wraps a cBytesIO object as a TTransport. NOTE: Unlike the C++ version of this class, you cannot write to it then immediately read from it. If you want to read from a TMemoryBuffer, you must either pass a string to the constructor. TODO(dreiss): Make this work like the C++ version. """ def __init__(self, value=None, offset=0): """value -- a value to read from for stringio If value is set, this will be a transport for reading, otherwise, it is for writing""" if value is not None: self._buffer = BytesIO(value) else: self._buffer = BytesIO() if offset: self._buffer.seek(offset) def isOpen(self): return not self._buffer.closed def open(self): pass def close(self): self._buffer.close() def read(self, sz): return self._buffer.read(sz) def write(self, buf): self._buffer.write(buf) def flush(self): pass def getvalue(self): return self._buffer.getvalue() # Implement the CReadableTransport interface. @property def cstringio_buf(self): return self._buffer def cstringio_refill(self, partialread, reqlen): # only one shot at reading... raise EOFError() class TFramedTransportFactory(object): """Factory transport that builds framed transports""" def getTransport(self, trans): framed = TFramedTransport(trans) return framed class TFramedTransport(TTransportBase, CReadableTransport): """Class that wraps another transport and frames its I/O when writing.""" def __init__(self, trans,): self.__trans = trans self.__rbuf = BytesIO(b'') self.__wbuf = BytesIO() def isOpen(self): return self.__trans.isOpen() def open(self): return self.__trans.open() def close(self): return self.__trans.close() def read(self, sz): ret = self.__rbuf.read(sz) if len(ret) != 0: return ret self.readFrame() return self.__rbuf.read(sz) def readFrame(self): buff = self.__trans.readAll(4) sz, = unpack('!i', buff) self.__rbuf = BytesIO(self.__trans.readAll(sz)) def write(self, buf): self.__wbuf.write(buf) def flush(self): wout = self.__wbuf.getvalue() wsz = len(wout) # reset wbuf before write/flush to preserve state on underlying failure 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 # good job of managing string buffer operations without excessive copies buf = pack("!i", wsz) + wout self.__trans.write(buf) self.__trans.flush() # Implement the CReadableTransport interface. @property def cstringio_buf(self): return self.__rbuf def cstringio_refill(self, prefix, reqlen): # self.__rbuf will already be empty here because fastbinary doesn't # ask for a refill until the previous buffer is empty. Therefore, # we can start reading new frames immediately. while len(prefix) < reqlen: self.readFrame() prefix += self.__rbuf.getvalue() self.__rbuf = BytesIO(prefix) return self.__rbuf class TFileObjectTransport(TTransportBase): """Wraps a file-like object to make it work as a Thrift transport.""" def __init__(self, fileobj): self.fileobj = fileobj def isOpen(self): return True def close(self): self.fileobj.close() def read(self, sz): return self.fileobj.read(sz) def write(self, buf): self.fileobj.write(buf) def flush(self): self.fileobj.flush() class TSaslClientTransport(TTransportBase, CReadableTransport): """ SASL transport """ START = 1 OK = 2 BAD = 3 ERROR = 4 COMPLETE = 5 def __init__(self, transport, host, service, mechanism='GSSAPI', **sasl_kwargs): """ transport: an underlying transport to use, typically just a TSocket host: the name of the server, from a SASL perspective service: the name of the server's service, from a SASL perspective mechanism: the name of the preferred mechanism to use All other kwargs will be passed to the puresasl.client.SASLClient constructor. """ from puresasl.client import SASLClient self.transport = transport self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs) self.__wbuf = BytesIO() self.__rbuf = BytesIO(b'') def open(self): if not self.transport.isOpen(): self.transport.open() self.send_sasl_msg(self.START, bytes(self.sasl.mechanism, 'ascii')) initial_response = self.sasl.process() self.send_sasl_msg(self.OK, initial_response if initial_response is not None else b'') while True: status, challenge = self.recv_sasl_msg() if status == self.OK: self.send_sasl_msg(self.OK, self.sasl.process(challenge)) elif status == self.COMPLETE: if challenge: # Process server's final challenge (e.g. DIGEST-MD5 rspauth # verification). Return value intentionally unused; puresasl # raises on verification failure. self.sasl.process(challenge) if not self.sasl.complete: raise TTransportException( TTransportException.NOT_OPEN, "The server erroneously indicated " "that SASL negotiation was complete") else: break else: raise TTransportException( TTransportException.NOT_OPEN, "Bad SASL negotiation status: %d (%s)" % (status, challenge)) def isOpen(self): return self.transport.isOpen() def send_sasl_msg(self, status, body): if body is None: body = b'' header = pack(">BI", status, len(body)) self.transport.write(header + body) self.transport.flush() def recv_sasl_msg(self): header = self.transport.readAll(5) status, length = unpack(">BI", header) if length > 0: payload = self.transport.readAll(length) else: payload = b"" return status, payload def write(self, data): self.__wbuf.write(data) def flush(self): data = self.__wbuf.getvalue() encoded = self.sasl.wrap(data) self.transport.write(pack("!i", len(encoded)) + encoded) self.transport.flush() self.__wbuf = BytesIO() def read(self, sz): ret = self.__rbuf.read(sz) if len(ret) != 0: return ret self._read_frame() return self.__rbuf.read(sz) def _read_frame(self): header = self.transport.readAll(4) length, = unpack('!i', header) encoded = self.transport.readAll(length) self.__rbuf = BytesIO(self.sasl.unwrap(encoded)) def close(self): self.sasl.dispose() self.transport.close() # based on TFramedTransport @property def cstringio_buf(self): return self.__rbuf def cstringio_refill(self, prefix, reqlen): # self.__rbuf will already be empty here because fastbinary doesn't # ask for a refill until the previous buffer is empty. Therefore, # we can start reading new frames immediately. while len(prefix) < reqlen: self._read_frame() prefix += self.__rbuf.getvalue() self.__rbuf = BytesIO(prefix) return self.__rbuf thrift-0.23.0/lib/py/src/transport/TTwisted.py0000664000175000017500000002523015165535636021541 0ustar00buildbuild00000000000000# # 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 io import BytesIO import struct from zope.interface import implementer, Interface, Attribute from twisted.internet.protocol import ServerFactory, ClientFactory, \ connectionDone from twisted.internet import defer from twisted.internet.threads import deferToThread from twisted.protocols import basic from twisted.web import server, resource, http from thrift.transport import TTransport class TMessageSenderTransport(TTransport.TTransportBase): def __init__(self): self.__wbuf = BytesIO() def write(self, buf): self.__wbuf.write(buf) def flush(self): msg = self.__wbuf.getvalue() self.__wbuf = BytesIO() return self.sendMessage(msg) def sendMessage(self, message): raise NotImplementedError class TCallbackTransport(TMessageSenderTransport): def __init__(self, func): TMessageSenderTransport.__init__(self) self.func = func def sendMessage(self, message): return self.func(message) class ThriftClientProtocol(basic.Int32StringReceiver): MAX_LENGTH = 2 ** 31 - 1 def __init__(self, client_class, iprot_factory, oprot_factory=None): self._client_class = client_class self._iprot_factory = iprot_factory if oprot_factory is None: self._oprot_factory = iprot_factory else: self._oprot_factory = oprot_factory self.recv_map = {} self.started = defer.Deferred() def dispatch(self, msg): self.sendString(msg) def connectionMade(self): tmo = TCallbackTransport(self.dispatch) self.client = self._client_class(tmo, self._oprot_factory) self.started.callback(self.client) def connectionLost(self, reason=connectionDone): # the called errbacks can add items to our client's _reqs, # so we need to use a tmp, and iterate until no more requests # are added during errbacks if self.client: tex = TTransport.TTransportException( type=TTransport.TTransportException.END_OF_FILE, message='Connection closed (%s)' % reason) while self.client._reqs: _, v = self.client._reqs.popitem() v.errback(tex) del self.client._reqs self.client = None def stringReceived(self, frame): tr = TTransport.TMemoryBuffer(frame) iprot = self._iprot_factory.getProtocol(tr) (fname, mtype, rseqid) = iprot.readMessageBegin() try: method = self.recv_map[fname] except KeyError: method = getattr(self.client, 'recv_' + fname) self.recv_map[fname] = method method(iprot, mtype, rseqid) class ThriftSASLClientProtocol(ThriftClientProtocol): START = 1 OK = 2 BAD = 3 ERROR = 4 COMPLETE = 5 MAX_LENGTH = 2 ** 31 - 1 def __init__(self, client_class, iprot_factory, oprot_factory=None, host=None, service=None, mechanism='GSSAPI', **sasl_kwargs): """ host: the name of the server, from a SASL perspective service: the name of the server's service, from a SASL perspective mechanism: the name of the preferred mechanism to use All other kwargs will be passed to the puresasl.client.SASLClient constructor. """ from puresasl.client import SASLClient self.SASLCLient = SASLClient ThriftClientProtocol.__init__(self, client_class, iprot_factory, oprot_factory) self._sasl_negotiation_deferred = None self._sasl_negotiation_status = None self.client = None if host is not None: self.createSASLClient(host, service, mechanism, **sasl_kwargs) def createSASLClient(self, host, service, mechanism, **kwargs): self.sasl = self.SASLClient(host, service, mechanism, **kwargs) def dispatch(self, msg): encoded = self.sasl.wrap(msg) len_and_encoded = ''.join((struct.pack('!i', len(encoded)), encoded)) ThriftClientProtocol.dispatch(self, len_and_encoded) @defer.inlineCallbacks def connectionMade(self): self._sendSASLMessage(self.START, self.sasl.mechanism) initial_message = yield deferToThread(self.sasl.process) self._sendSASLMessage(self.OK, initial_message) while True: status, challenge = yield self._receiveSASLMessage() if status == self.OK: response = yield deferToThread(self.sasl.process, challenge) self._sendSASLMessage(self.OK, response) elif status == self.COMPLETE: if not self.sasl.complete: msg = "The server erroneously indicated that SASL " \ "negotiation was complete" raise TTransport.TTransportException(msg, message=msg) else: break else: msg = "Bad SASL negotiation status: %d (%s)" % (status, challenge) raise TTransport.TTransportException(msg, message=msg) self._sasl_negotiation_deferred = None ThriftClientProtocol.connectionMade(self) def _sendSASLMessage(self, status, body): if body is None: body = "" header = struct.pack(">BI", status, len(body)) self.transport.write(header + body) def _receiveSASLMessage(self): self._sasl_negotiation_deferred = defer.Deferred() self._sasl_negotiation_status = None return self._sasl_negotiation_deferred def connectionLost(self, reason=connectionDone): if self.client: ThriftClientProtocol.connectionLost(self, reason) def dataReceived(self, data): if self._sasl_negotiation_deferred: # we got a sasl challenge in the format (status, length, challenge) # save the status, let IntNStringReceiver piece the challenge data together self._sasl_negotiation_status, = struct.unpack("B", data[0]) ThriftClientProtocol.dataReceived(self, data[1:]) else: # normal frame, let IntNStringReceiver piece it together ThriftClientProtocol.dataReceived(self, data) def stringReceived(self, frame): if self._sasl_negotiation_deferred: # the frame is just a SASL challenge response = (self._sasl_negotiation_status, frame) self._sasl_negotiation_deferred.callback(response) else: # there's a second 4 byte length prefix inside the frame decoded_frame = self.sasl.unwrap(frame[4:]) ThriftClientProtocol.stringReceived(self, decoded_frame) class ThriftServerProtocol(basic.Int32StringReceiver): MAX_LENGTH = 2 ** 31 - 1 def dispatch(self, msg): self.sendString(msg) def processError(self, error): self.transport.loseConnection() def processOk(self, _, tmo): msg = tmo.getvalue() if len(msg) > 0: self.dispatch(msg) def stringReceived(self, frame): tmi = TTransport.TMemoryBuffer(frame) tmo = TTransport.TMemoryBuffer() iprot = self.factory.iprot_factory.getProtocol(tmi) oprot = self.factory.oprot_factory.getProtocol(tmo) d = self.factory.processor.process(iprot, oprot) d.addCallbacks(self.processOk, self.processError, callbackArgs=(tmo,)) class IThriftServerFactory(Interface): processor = Attribute("Thrift processor") iprot_factory = Attribute("Input protocol factory") oprot_factory = Attribute("Output protocol factory") class IThriftClientFactory(Interface): client_class = Attribute("Thrift client class") iprot_factory = Attribute("Input protocol factory") oprot_factory = Attribute("Output protocol factory") @implementer(IThriftServerFactory) class ThriftServerFactory(ServerFactory): protocol = ThriftServerProtocol def __init__(self, processor, iprot_factory, oprot_factory=None): self.processor = processor self.iprot_factory = iprot_factory if oprot_factory is None: self.oprot_factory = iprot_factory else: self.oprot_factory = oprot_factory @implementer(IThriftClientFactory) class ThriftClientFactory(ClientFactory): protocol = ThriftClientProtocol def __init__(self, client_class, iprot_factory, oprot_factory=None): self.client_class = client_class self.iprot_factory = iprot_factory if oprot_factory is None: self.oprot_factory = iprot_factory else: self.oprot_factory = oprot_factory def buildProtocol(self, addr): p = self.protocol(self.client_class, self.iprot_factory, self.oprot_factory) p.factory = self return p class ThriftResource(resource.Resource): allowedMethods = ('POST',) def __init__(self, processor, inputProtocolFactory, outputProtocolFactory=None): resource.Resource.__init__(self) self.inputProtocolFactory = inputProtocolFactory if outputProtocolFactory is None: self.outputProtocolFactory = inputProtocolFactory else: self.outputProtocolFactory = outputProtocolFactory self.processor = processor def getChild(self, path, request): return self def _cbProcess(self, _, request, tmo): msg = tmo.getvalue() request.setResponseCode(http.OK) request.setHeader("content-type", "application/x-thrift") request.write(msg) request.finish() def render_POST(self, request): request.content.seek(0, 0) data = request.content.read() tmi = TTransport.TMemoryBuffer(data) tmo = TTransport.TMemoryBuffer() iprot = self.inputProtocolFactory.getProtocol(tmi) oprot = self.outputProtocolFactory.getProtocol(tmo) d = self.processor.process(iprot, oprot) d.addCallback(self._cbProcess, request, tmo) return server.NOT_DONE_YET thrift-0.23.0/lib/py/src/transport/TSSLSocket.py0000664000175000017500000004042315167543515021726 0ustar00buildbuild00000000000000# # 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 logging import os import socket import ssl import sys import warnings from .sslcompat import _match_has_ipaddress from thrift.transport import TSocket from thrift.transport.TTransport import TTransportException def _match_hostname(cert, hostname): return True logger = logging.getLogger(__name__) warnings.filterwarnings( 'default', category=DeprecationWarning, module=__name__) class TSSLBase(object): # SSLContext is not available for Python < 2.7.9 _has_ssl_context = sys.hexversion >= 0x020709F0 # ciphers argument is not available for Python < 2.7.0 _has_ciphers = sys.hexversion >= 0x020700F0 # For python >= 2.7.9, use latest TLS that both client and server # supports. # 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. # For python < 3.6, use SSLv23 since TLS is not available if sys.version_info < (3, 6): _default_protocol = ssl.PROTOCOL_SSLv23 if _has_ssl_context else \ ssl.PROTOCOL_TLSv1 else: _default_protocol = ssl.PROTOCOL_TLS_CLIENT if _has_ssl_context else \ ssl.PROTOCOL_TLSv1 def _init_context(self, ssl_version): if self._has_ssl_context: self._context = ssl.SSLContext(ssl_version) if self._context.protocol == ssl.PROTOCOL_SSLv23: self._context.options |= ssl.OP_NO_SSLv2 self._context.options |= ssl.OP_NO_SSLv3 else: self._context = None self._ssl_version = ssl_version @property def _should_verify(self): if self._has_ssl_context: return self._context.verify_mode != ssl.CERT_NONE else: return self.cert_reqs != ssl.CERT_NONE @property def ssl_version(self): if self._has_ssl_context: return self.ssl_context.protocol else: return self._ssl_version @property def ssl_context(self): return self._context SSL_VERSION = _default_protocol """ Default SSL version. For backwards compatibility, it can be modified. Use __init__ keyword argument "ssl_version" instead. """ def _deprecated_arg(self, args, kwargs, pos, key): if len(args) <= pos: return real_pos = pos + 3 warnings.warn( '%dth positional argument is deprecated.' 'please use keyword argument instead.' % real_pos, DeprecationWarning, stacklevel=3) if key in kwargs: raise TypeError( 'Duplicate argument: %dth argument and %s keyword argument.' % (real_pos, key)) kwargs[key] = args[pos] def _unix_socket_arg(self, host, port, args, kwargs): key = 'unix_socket' if host is None and port is None and len(args) == 1 and key not in kwargs: kwargs[key] = args[0] return True return False def __getattr__(self, key): if key == 'SSL_VERSION': warnings.warn( 'SSL_VERSION is deprecated.' 'please use ssl_version attribute instead.', DeprecationWarning, stacklevel=2) return self.ssl_version def __init__(self, server_side, host, ssl_opts): self._server_side = server_side if TSSLBase.SSL_VERSION != self._default_protocol: warnings.warn( 'SSL_VERSION is deprecated.' 'please use ssl_version keyword argument instead.', DeprecationWarning, stacklevel=2) self._context = ssl_opts.pop('ssl_context', None) self._server_hostname = None if not self._server_side: self._server_hostname = ssl_opts.pop('server_hostname', host) if self._context: self._custom_context = True if ssl_opts: raise ValueError( 'Incompatible arguments: ssl_context and %s' % ' '.join(ssl_opts.keys())) if not self._has_ssl_context: raise ValueError( 'ssl_context is not available for this version of Python') else: self._custom_context = False ssl_version = ssl_opts.pop('ssl_version', TSSLBase.SSL_VERSION) self._init_context(ssl_version) self.cert_reqs = ssl_opts.pop('cert_reqs', ssl.CERT_REQUIRED) self.ca_certs = ssl_opts.pop('ca_certs', None) self.keyfile = ssl_opts.pop('keyfile', None) self.certfile = ssl_opts.pop('certfile', None) self.ciphers = ssl_opts.pop('ciphers', None) if ssl_opts: raise ValueError( 'Unknown keyword arguments: ', ' '.join(ssl_opts.keys())) if self._should_verify: if not self.ca_certs: raise ValueError( 'ca_certs is needed when cert_reqs is not ssl.CERT_NONE') if not os.access(self.ca_certs, os.R_OK): raise IOError('Certificate Authority ca_certs file "%s" ' 'is not readable, cannot validate SSL ' 'certificates.' % (self.ca_certs)) @property def certfile(self): return self._certfile @certfile.setter def certfile(self, certfile): if self._server_side and not certfile: raise ValueError('certfile is needed for server-side') if certfile and not os.access(certfile, os.R_OK): raise IOError('No such certfile found: %s' % (certfile)) self._certfile = certfile def _wrap_socket(self, sock): if self._has_ssl_context: if not self._custom_context: self.ssl_context.verify_mode = self.cert_reqs if self.certfile: self.ssl_context.load_cert_chain(self.certfile, self.keyfile) if self.ciphers: self.ssl_context.set_ciphers(self.ciphers) if self.ca_certs: self.ssl_context.load_verify_locations(self.ca_certs) return self.ssl_context.wrap_socket( sock, server_side=self._server_side, server_hostname=self._server_hostname) else: ssl_opts = { 'ssl_version': self._ssl_version, 'server_side': self._server_side, 'ca_certs': self.ca_certs, 'keyfile': self.keyfile, 'certfile': self.certfile, 'cert_reqs': self.cert_reqs, } if self.ciphers: if self._has_ciphers: ssl_opts['ciphers'] = self.ciphers else: logger.warning( 'ciphers is specified but ignored due to old Python version') return ssl.wrap_socket(sock, **ssl_opts) class TSSLSocket(TSocket.TSocket, TSSLBase): """ SSL implementation of TSocket This class creates outbound sockets wrapped using the python standard ssl module for encrypted connections. """ # New signature # def __init__(self, host='localhost', port=9090, unix_socket=None, # **ssl_args): # Deprecated signature # def __init__(self, host='localhost', port=9090, validate=True, # ca_certs=None, keyfile=None, certfile=None, # unix_socket=None, ciphers=None): def __init__(self, host='localhost', port=9090, *args, **kwargs): """Positional arguments: ``host``, ``port``, ``unix_socket`` Keyword arguments: ``keyfile``, ``certfile``, ``cert_reqs``, ``ssl_version``, ``ca_certs``, ``ciphers`` (Python 2.7.0 or later), ``server_hostname`` (Python 2.7.9 or later) Passed to ssl.wrap_socket. See ssl.wrap_socket documentation. Alternative keyword arguments: (Python 2.7.9 or later) ``ssl_context``: ssl.SSLContext to be used for SSLContext.wrap_socket ``server_hostname``: Passed to SSLContext.wrap_socket Common keyword argument: ``validate_callback`` (cert, hostname) -> None: Called after SSL handshake. Can raise when hostname does not match the cert. ``socket_keepalive`` enable TCP keepalive, default off. """ self.is_valid = False self.peercert = None if args: if len(args) > 6: raise TypeError('Too many positional argument') if not self._unix_socket_arg(host, port, args, kwargs): self._deprecated_arg(args, kwargs, 0, 'validate') self._deprecated_arg(args, kwargs, 1, 'ca_certs') self._deprecated_arg(args, kwargs, 2, 'keyfile') self._deprecated_arg(args, kwargs, 3, 'certfile') self._deprecated_arg(args, kwargs, 4, 'unix_socket') self._deprecated_arg(args, kwargs, 5, 'ciphers') validate = kwargs.pop('validate', None) if validate is not None: cert_reqs_name = 'CERT_REQUIRED' if validate else 'CERT_NONE' warnings.warn( 'validate is deprecated. please use cert_reqs=ssl.%s instead' % cert_reqs_name, DeprecationWarning, stacklevel=2) if 'cert_reqs' in kwargs: raise TypeError('Cannot specify both validate and cert_reqs') kwargs['cert_reqs'] = ssl.CERT_REQUIRED if validate else ssl.CERT_NONE unix_socket = kwargs.pop('unix_socket', None) socket_keepalive = kwargs.pop('socket_keepalive', False) self._validate_callback = kwargs.pop('validate_callback', _match_hostname) TSSLBase.__init__(self, False, host, kwargs) TSocket.TSocket.__init__(self, host, port, unix_socket, socket_keepalive=socket_keepalive) def close(self): try: self.handle.settimeout(0.001) self.handle = self.handle.unwrap() except (ssl.SSLError, socket.error, OSError): # could not complete shutdown in a reasonable amount of time. bail. pass TSocket.TSocket.close(self) @property def validate(self): warnings.warn('validate is deprecated. please use cert_reqs instead', DeprecationWarning, stacklevel=2) return self.cert_reqs != ssl.CERT_NONE @validate.setter def validate(self, value): warnings.warn('validate is deprecated. please use cert_reqs instead', DeprecationWarning, stacklevel=2) self.cert_reqs = ssl.CERT_REQUIRED if value else ssl.CERT_NONE def _do_open(self, family, socktype): plain_sock = socket.socket(family, socktype) try: return self._wrap_socket(plain_sock) except Exception as ex: plain_sock.close() msg = 'failed to initialize SSL' logger.exception(msg) raise TTransportException(type=TTransportException.NOT_OPEN, message=msg, inner=ex) def open(self): super(TSSLSocket, self).open() if self._should_verify: self.peercert = self.handle.getpeercert() try: self._validate_callback(self.peercert, self._server_hostname) self.is_valid = True except TTransportException: raise except Exception as ex: raise TTransportException(message=str(ex), inner=ex) class TSSLServerSocket(TSocket.TServerSocket, TSSLBase): """SSL implementation of TServerSocket This uses the ssl module's wrap_socket() method to provide SSL negotiated encryption. """ # New signature # def __init__(self, host='localhost', port=9090, unix_socket=None, **ssl_args): # Deprecated signature # def __init__(self, host=None, port=9090, certfile='cert.pem', unix_socket=None, ciphers=None): def __init__(self, host=None, port=9090, *args, **kwargs): """Positional arguments: ``host``, ``port``, ``unix_socket`` Keyword arguments: ``keyfile``, ``certfile``, ``cert_reqs``, ``ssl_version``, ``ca_certs``, ``ciphers`` (Python 2.7.0 or later) See ssl.wrap_socket documentation. Alternative keyword arguments: (Python 2.7.9 or later) ``ssl_context``: ssl.SSLContext to be used for SSLContext.wrap_socket ``server_hostname``: Passed to SSLContext.wrap_socket Common keyword argument: ``validate_callback`` (cert, hostname) -> None: Called after SSL handshake. Can raise when hostname does not match the cert. """ if args: if len(args) > 3: raise TypeError('Too many positional argument') if not self._unix_socket_arg(host, port, args, kwargs): self._deprecated_arg(args, kwargs, 0, 'certfile') self._deprecated_arg(args, kwargs, 1, 'unix_socket') self._deprecated_arg(args, kwargs, 2, 'ciphers') if 'ssl_context' not in kwargs: # Preserve existing behaviors for default values if 'cert_reqs' not in kwargs: kwargs['cert_reqs'] = ssl.CERT_NONE if 'certfile' not in kwargs: kwargs['certfile'] = 'cert.pem' unix_socket = kwargs.pop('unix_socket', None) self._validate_callback = \ kwargs.pop('validate_callback', _match_hostname) TSSLBase.__init__(self, True, None, kwargs) TSocket.TServerSocket.__init__(self, host, port, unix_socket) if self._should_verify and not _match_has_ipaddress: raise ValueError('Need ipaddress and backports.ssl_match_hostname ' 'module to verify client certificate') def setCertfile(self, certfile): """Set or change the server certificate file used to wrap new connections. @param certfile: The filename of the server certificate, i.e. '/etc/certs/server.pem' @type certfile: str Raises an IOError exception if the certfile is not present or unreadable. """ warnings.warn( 'setCertfile is deprecated. please use certfile property instead.', DeprecationWarning, stacklevel=2) self.certfile = certfile def accept(self): plain_client, addr = self.handle.accept() try: client = self._wrap_socket(plain_client) except (ssl.SSLError, socket.error, OSError): logger.exception('Error while accepting from %s', addr) # failed handshake/ssl wrap, close socket to client plain_client.close() # raise # We can't raise the exception, because it kills most TServer derived # serve() methods. # Instead, return None, and let the TServer instance deal with it in # other exception handling. (but TSimpleServer dies anyway) return None if self._should_verify: client.peercert = client.getpeercert() try: self._validate_callback(client.peercert, addr[0]) client.is_valid = True except Exception: logger.warning('Failed to validate client certificate address: %s', addr[0], exc_info=True) client.close() plain_client.close() return None result = TSocket.TSocket() result.handle = client return result thrift-0.23.0/lib/py/src/transport/TZlibTransport.py0000664000175000017500000002102515165535636022731 0ustar00buildbuild00000000000000# # 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. # """TZlibTransport provides a compressed transport and transport factory class, using the python standard library zlib module to implement data compression. """ import zlib from io import BytesIO from .TTransport import TTransportBase, CReadableTransport class TZlibTransportFactory: """Factory transport that builds zlib compressed transports. This factory caches the last single client/transport that it was passed and returns the same TZlibTransport object that was created. This caching means the TServer class will get the _same_ transport object for both input and output transports from this factory. (For non-threaded scenarios only, since the cache only holds one object) The purpose of this caching is to allocate only one TZlibTransport where only one is really needed (since it must have separate read/write buffers), and makes the statistics from getCompSavings() and getCompRatio() easier to understand. """ # class scoped cache of last transport given and zlibtransport returned _last_trans = None _last_z = None def getTransport(self, trans, compresslevel=9): """Wrap a transport, trans, with the TZlibTransport compressed transport class, returning a new transport to the caller. @param compresslevel: The zlib compression level, ranging from 0 (no compression) to 9 (best compression). Defaults to 9. @type compresslevel: int This method returns a TZlibTransport which wraps the passed C{trans} TTransport derived instance. """ if trans == self._last_trans: return self._last_z ztrans = TZlibTransport(trans, compresslevel) self._last_trans = trans self._last_z = ztrans return ztrans class TZlibTransport(TTransportBase, CReadableTransport): """Class that wraps a transport with zlib, compressing writes and decompresses reads, using the python standard library zlib module. """ # Read buffer size for the python fastbinary C extension, # the TBinaryProtocolAccelerated class. DEFAULT_BUFFSIZE = 4096 def __init__(self, trans, compresslevel=9): """Create a new TZlibTransport, wrapping C{trans}, another TTransport derived object. @param trans: A thrift transport object, i.e. a TSocket() object. @type trans: TTransport @param compresslevel: The zlib compression level, ranging from 0 (no compression) to 9 (best compression). Default is 9. @type compresslevel: int """ self.__trans = trans self.compresslevel = compresslevel self.__rbuf = BytesIO() self.__wbuf = BytesIO() self._init_zlib() self._init_stats() def _reinit_buffers(self): """Internal method to initialize/reset the internal StringIO objects for read and write buffers. """ self.__rbuf = BytesIO() self.__wbuf = BytesIO() def _init_stats(self): """Internal method to reset the internal statistics counters for compression ratios and bandwidth savings. """ self.bytes_in = 0 self.bytes_out = 0 self.bytes_in_comp = 0 self.bytes_out_comp = 0 def _init_zlib(self): """Internal method for setting up the zlib compression and decompression objects. """ self._zcomp_read = zlib.decompressobj() self._zcomp_write = zlib.compressobj(self.compresslevel) def getCompRatio(self): """Get the current measured compression ratios (in,out) from this transport. Returns a tuple of: (inbound_compression_ratio, outbound_compression_ratio) The compression ratios are computed as: compressed / uncompressed E.g., data that compresses by 10x will have a ratio of: 0.10 and data that compresses to half of ts original size will have a ratio of 0.5 None is returned if no bytes have yet been processed in a particular direction. """ r_percent, w_percent = (None, None) if self.bytes_in > 0: r_percent = self.bytes_in_comp / self.bytes_in if self.bytes_out > 0: w_percent = self.bytes_out_comp / self.bytes_out return (r_percent, w_percent) def getCompSavings(self): """Get the current count of saved bytes due to data compression. Returns a tuple of: (inbound_saved_bytes, outbound_saved_bytes) Note: if compression is actually expanding your data (only likely with very tiny thrift objects), then the values returned will be negative. """ r_saved = self.bytes_in - self.bytes_in_comp w_saved = self.bytes_out - self.bytes_out_comp return (r_saved, w_saved) def isOpen(self): """Return the underlying transport's open status""" return self.__trans.isOpen() def open(self): """Open the underlying transport""" self._init_stats() return self.__trans.open() def listen(self): """Invoke the underlying transport's listen() method""" self.__trans.listen() def accept(self): """Accept connections on the underlying transport""" return self.__trans.accept() def close(self): """Close the underlying transport,""" self._reinit_buffers() self._init_zlib() return self.__trans.close() def read(self, sz): """Read up to sz bytes from the decompressed bytes buffer, and read from the underlying transport if the decompression buffer is empty. """ ret = self.__rbuf.read(sz) if len(ret) > 0: return ret # keep reading from transport until something comes back while True: if self.readComp(sz): break ret = self.__rbuf.read(sz) return ret def readComp(self, sz): """Read compressed data from the underlying transport, then decompress it and append it to the internal StringIO read buffer """ zbuf = self.__trans.read(sz) zbuf = self._zcomp_read.unconsumed_tail + zbuf buf = self._zcomp_read.decompress(zbuf) self.bytes_in += len(zbuf) self.bytes_in_comp += len(buf) old = self.__rbuf.read() self.__rbuf = BytesIO(old + buf) if len(old) + len(buf) == 0: return False return True def write(self, buf): """Write some bytes, putting them into the internal write buffer for eventual compression. """ self.__wbuf.write(buf) def flush(self): """Flush any queued up data in the write buffer and ensure the compression buffer is flushed out to the underlying transport """ wout = self.__wbuf.getvalue() if len(wout) > 0: zbuf = self._zcomp_write.compress(wout) self.bytes_out += len(wout) self.bytes_out_comp += len(zbuf) else: zbuf = '' ztail = self._zcomp_write.flush(zlib.Z_SYNC_FLUSH) self.bytes_out_comp += len(ztail) if (len(zbuf) + len(ztail)) > 0: self.__wbuf = BytesIO() self.__trans.write(zbuf + ztail) self.__trans.flush() @property def cstringio_buf(self): """Implement the CReadableTransport interface""" return self.__rbuf def cstringio_refill(self, partialread, reqlen): """Implement the CReadableTransport interface for refill""" retstring = partialread if reqlen < self.DEFAULT_BUFFSIZE: retstring += self.read(self.DEFAULT_BUFFSIZE) while len(retstring) < reqlen: retstring += self.read(reqlen - len(retstring)) self.__rbuf = BytesIO(retstring) return self.__rbuf thrift-0.23.0/lib/py/src/transport/TSocket.py0000664000175000017500000002347315167543515021352 0ustar00buildbuild00000000000000# # 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 errno import logging import os import socket import sys import platform from .TTransport import TTransportBase, TTransportException, TServerTransportBase logger = logging.getLogger(__name__) class TSocketBase(TTransportBase): def _resolveAddr(self): if self._unix_socket is not None: return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None, self._unix_socket)] else: return socket.getaddrinfo(self.host, self.port, self._socket_family, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) def close(self): if self.handle: self.handle.close() self.handle = None class TSocket(TSocketBase): """Socket implementation of TTransport base.""" def __init__(self, host='localhost', port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC, socket_keepalive=False): """Initialize a TSocket @param host(str) The host to connect to. @param port(int) The (TCP) port to connect to. @param unix_socket(str) The filename of a unix socket to connect to. (host and port will be ignored.) @param socket_family(int) The socket family to use with this socket. @param socket_keepalive(bool) enable TCP keepalive, default off. """ self.host = host self.port = port self.handle = None self._unix_socket = unix_socket self._timeout = None self._socket_family = socket_family self._socket_keepalive = socket_keepalive def setHandle(self, h): self.handle = h def isOpen(self): if self.handle is None: return False # this lets us cheaply see if the other end of the socket is still # connected. if disconnected, we'll get EOF back (expressed as zero # bytes of data) otherwise we'll get one byte or an error indicating # we'd have to block for data. # # note that we're not doing this with socket.MSG_DONTWAIT because 1) # it's linux-specific and 2) gevent-patched sockets hide EAGAIN from us # when timeout is non-zero. original_timeout = self.handle.gettimeout() try: 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 except ValueError: # SSLSocket fails on recv with non-zero flags; fallback to the old behavior return True finally: self.handle.settimeout(original_timeout) # 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: self._timeout = None else: self._timeout = ms / 1000.0 if self.handle is not None: self.handle.settimeout(self._timeout) def _do_open(self, family, socktype): return socket.socket(family, socktype) @property def _address(self): return self._unix_socket if self._unix_socket else '%s:%d' % (self.host, self.port) def open(self): if self.handle: raise TTransportException(type=TTransportException.ALREADY_OPEN, message="already open") try: addrs = self._resolveAddr() except socket.gaierror as gai: msg = 'failed to resolve sockaddr for ' + str(self._address) logger.exception(msg) raise TTransportException(type=TTransportException.NOT_OPEN, message=msg, inner=gai) # Preserve the last exception to report if all addresses fail. last_exc = None for family, socktype, _, _, sockaddr in addrs: handle = self._do_open(family, socktype) # TCP keep-alive if self._socket_keepalive: handle.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) handle.settimeout(self._timeout) try: handle.connect(sockaddr) self.handle = handle return except socket.error as e: handle.close() logger.info('Could not connect to %s', sockaddr, exc_info=True) last_exc = e msg = 'Could not connect to any of %s' % list(map(lambda a: a[4], addrs)) logger.error(msg) raise TTransportException(type=TTransportException.NOT_OPEN, message=msg, inner=last_exc) def read(self, sz): try: buff = self.handle.recv(sz) # TODO: remove socket.timeout when 3.10 becomes the earliest version of python supported. except (socket.timeout, TimeoutError) 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'))): # freebsd and Mach don't follow POSIX semantic of recv # and fail with ECONNRESET if peer performed shutdown. # See corresponding comment and code in TSocket::read() # in lib/cpp/src/transport/TSocket.cpp. self.close() # Trigger the check to raise the END_OF_FILE exception below. buff = '' else: raise TTransportException(message="unexpected exception", inner=e) if len(buff) == 0: raise TTransportException(type=TTransportException.END_OF_FILE, message='TSocket read 0 bytes') return buff def write(self, buff): if not self.handle: raise TTransportException(type=TTransportException.NOT_OPEN, message='Transport not open') sent = 0 have = len(buff) while sent < have: try: plus = self.handle.send(buff) if plus == 0: raise TTransportException(type=TTransportException.END_OF_FILE, message='TSocket sent 0 bytes') sent += plus buff = buff[plus:] except socket.error as e: raise TTransportException(message="unexpected exception", inner=e) def flush(self): pass class TServerSocket(TSocketBase, TServerTransportBase): """Socket implementation of TServerTransport base.""" def __init__(self, host=None, port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC): self.host = host self.port = port self._unix_socket = unix_socket self._socket_family = socket_family self.handle = None self._backlog = 128 def setBacklog(self, backlog=None): if not self.handle: self._backlog = backlog else: # We cann't update backlog when it is already listening, since the # handle has been created. logger.warning('You have to set backlog before listen.') def listen(self): res0 = self._resolveAddr() socket_family = self._socket_family == socket.AF_UNSPEC and socket.AF_INET6 or self._socket_family for res in res0: if res[0] is socket_family or res is res0[-1]: break # We need remove the old unix socket if the file exists and # nobody is listening on it. if self._unix_socket: tmp = socket.socket(res[0], res[1]) try: tmp.connect(res[4]) except socket.error as err: eno, message = err.args if eno == errno.ECONNREFUSED: os.unlink(res[4]) self.handle = s = socket.socket(res[0], res[1]) if s.family is socket.AF_INET6: if platform.system() == 'Windows' and sys.version_info < (3, 8): logger.warning('Windows socket defaulting to IPv4 for Python < 3.8: See https://github.com/python/cpython/issues/73701') else: s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if hasattr(s, 'settimeout'): s.settimeout(None) s.bind(res[4]) s.listen(self._backlog) def accept(self): client, addr = self.handle.accept() result = TSocket() result.setHandle(client) return result thrift-0.23.0/lib/py/src/transport/sslcompat.py0000664000175000017500000001004515167543515021772 0ustar00buildbuild00000000000000# # 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 logging import sys from thrift.transport.TTransport import TTransportException logger = logging.getLogger(__name__) def legacy_validate_callback(cert, hostname): """legacy method to validate the peer's SSL certificate, and to check the commonName of the certificate to ensure it matches the hostname we used to make this connection. Does not support subjectAltName records in certificates. raises TTransportException if the certificate fails validation. """ if 'subject' not in cert: raise TTransportException( TTransportException.NOT_OPEN, 'No SSL certificate found from %s' % hostname) fields = cert['subject'] for field in fields: # ensure structure we get back is what we expect if not isinstance(field, tuple): continue cert_pair = field[0] if len(cert_pair) < 2: continue cert_key, cert_value = cert_pair[0:2] if cert_key != 'commonName': continue certhost = cert_value # this check should be performed by some sort of Access Manager if certhost == hostname: # success, cert commonName matches desired hostname return else: raise TTransportException( TTransportException.UNKNOWN, 'Hostname we connected to "%s" doesn\'t match certificate ' 'provided commonName "%s"' % (hostname, certhost)) raise TTransportException( TTransportException.UNKNOWN, 'Could not validate SSL certificate from host "%s". Cert=%s' % (hostname, cert)) def _optional_dependencies(): try: import ipaddress # noqa logger.debug('ipaddress module is available') ipaddr = True except ImportError: logger.warning('ipaddress module is unavailable') ipaddr = False if sys.hexversion < 0x030500F0: try: from backports.ssl_match_hostname import match_hostname, __version__ as ver ver = list(map(int, ver.split('.'))) logger.debug('backports.ssl_match_hostname module is available') match = match_hostname if ver[0] * 10 + ver[1] >= 35: return ipaddr, match else: logger.warning('backports.ssl_match_hostname module is too old') ipaddr = False except ImportError: 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: # 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): def match(cert, hostname): return True else: logger.warning('using legacy validation callback') match = legacy_validate_callback return ipaddr, match _match_has_ipaddress, _match_hostname = _optional_dependencies() thrift-0.23.0/lib/py/src/transport/__init__.py0000664000175000017500000000152715165535636021534 0ustar00buildbuild00000000000000# # 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. # __all__ = ['TTransport', 'TSocket', 'THttpClient', 'TZlibTransport'] thrift-0.23.0/lib/py/src/TSerialization.py0000664000175000017500000000255515165535636020704 0ustar00buildbuild00000000000000# # 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 .protocol import TBinaryProtocol from .transport import TTransport def serialize(thrift_object, protocol_factory=TBinaryProtocol.TBinaryProtocolFactory()): transport = TTransport.TMemoryBuffer() protocol = protocol_factory.getProtocol(transport) thrift_object.write(protocol) return transport.getvalue() def deserialize(base, buf, protocol_factory=TBinaryProtocol.TBinaryProtocolFactory()): transport = TTransport.TMemoryBuffer(buf) protocol = protocol_factory.getProtocol(transport) base.read(protocol) return base thrift-0.23.0/lib/py/src/protocol/0000775000175000017500000000000015167543515017220 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/src/protocol/TCompactProtocol.py0000664000175000017500000003654715167543515023045 0ustar00buildbuild00000000000000# # 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 .TProtocol import TType, TProtocolBase, TProtocolException, TProtocolFactory, checkIntegerLimits from struct import pack, unpack import uuid __all__ = ['TCompactProtocol', 'TCompactProtocolFactory'] CLEAR = 0 FIELD_WRITE = 1 VALUE_WRITE = 2 CONTAINER_WRITE = 3 BOOL_WRITE = 4 FIELD_READ = 5 CONTAINER_READ = 6 VALUE_READ = 7 BOOL_READ = 8 def make_helper(v_from, container): def helper(func): def nested(self, *args, **kwargs): assert self.state in (v_from, container), (self.state, v_from, container) return func(self, *args, **kwargs) return nested return helper writer = make_helper(VALUE_WRITE, CONTAINER_WRITE) reader = make_helper(VALUE_READ, CONTAINER_READ) def makeZigZag(n, bits): checkIntegerLimits(n, bits) return (n << 1) ^ (n >> (bits - 1)) def fromZigZag(n): return (n >> 1) ^ -(n & 1) def writeVarint(trans, n): assert n >= 0, "Input to TCompactProtocol writeVarint cannot be negative!" out = bytearray() while True: if n & ~0x7f == 0: out.append(n) break else: out.append((n & 0xff) | 0x80) n = n >> 7 trans.write(bytes(out)) def readVarint(trans): result = 0 shift = 0 while True: x = trans.readAll(1) byte = ord(x) result |= (byte & 0x7f) << shift if byte >> 7 == 0: return result shift += 7 # As per TCompactProtocol.tcc class CompactType(object): STOP = 0x00 TRUE = 0x01 FALSE = 0x02 BYTE = 0x03 I16 = 0x04 I32 = 0x05 I64 = 0x06 DOUBLE = 0x07 BINARY = 0x08 LIST = 0x09 SET = 0x0A MAP = 0x0B STRUCT = 0x0C UUID = 0x0D CTYPES = { TType.STOP: CompactType.STOP, TType.BOOL: CompactType.TRUE, # used for collection TType.BYTE: CompactType.BYTE, TType.I16: CompactType.I16, TType.I32: CompactType.I32, TType.I64: CompactType.I64, TType.DOUBLE: CompactType.DOUBLE, TType.STRING: CompactType.BINARY, TType.STRUCT: CompactType.STRUCT, TType.LIST: CompactType.LIST, TType.SET: CompactType.SET, TType.MAP: CompactType.MAP, TType.UUID: CompactType.UUID, } TTYPES = {} for k, v in CTYPES.items(): TTYPES[v] = k TTYPES[CompactType.FALSE] = TType.BOOL del k del v class TCompactProtocol(TProtocolBase): """Compact implementation of the Thrift protocol driver.""" PROTOCOL_ID = 0x82 VERSION = 1 VERSION_MASK = 0x1f TYPE_MASK = 0xe0 TYPE_BITS = 0x07 TYPE_SHIFT_AMOUNT = 5 def __init__(self, trans, string_length_limit=None, container_length_limit=None): TProtocolBase.__init__(self, trans) self.state = CLEAR self.__last_fid = 0 self.__bool_fid = None self.__bool_value = None self.__structs = [] self.__containers = [] self.string_length_limit = string_length_limit self.container_length_limit = container_length_limit def _check_string_length(self, length): self._check_length(self.string_length_limit, length) def _check_container_length(self, length): self._check_length(self.container_length_limit, length) def __writeVarint(self, n): writeVarint(self.trans, n) def writeMessageBegin(self, name, type, seqid): assert self.state == CLEAR self.__writeUByte(self.PROTOCOL_ID) self.__writeUByte(self.VERSION | (type << self.TYPE_SHIFT_AMOUNT)) # The sequence id is a signed 32-bit integer but the compact protocol # writes this out as a "var int" which is always positive, and attempting # to write a negative number results in an infinite loop, so we may # need to do some conversion here... tseqid = seqid if tseqid < 0: tseqid = 2147483648 + (2147483648 + tseqid) self.__writeVarint(tseqid) self.__writeBinary(bytes(name, 'utf-8')) self.state = VALUE_WRITE def writeMessageEnd(self): assert self.state == VALUE_WRITE self.state = CLEAR def writeStructBegin(self, name): assert self.state in (CLEAR, CONTAINER_WRITE, VALUE_WRITE), self.state self.__structs.append((self.state, self.__last_fid)) self.state = FIELD_WRITE self.__last_fid = 0 def writeStructEnd(self): assert self.state == FIELD_WRITE self.state, self.__last_fid = self.__structs.pop() def writeFieldStop(self): self.__writeByte(0) def __writeFieldHeader(self, type, fid): delta = fid - self.__last_fid if 0 < delta <= 15: self.__writeUByte(delta << 4 | type) else: self.__writeByte(type) self.__writeI16(fid) self.__last_fid = fid def writeFieldBegin(self, name, type, fid): assert self.state == FIELD_WRITE, self.state if type == TType.BOOL: self.state = BOOL_WRITE self.__bool_fid = fid else: self.state = VALUE_WRITE self.__writeFieldHeader(CTYPES[type], fid) def writeFieldEnd(self): assert self.state in (VALUE_WRITE, BOOL_WRITE), self.state self.state = FIELD_WRITE def __writeUByte(self, byte): self.trans.write(pack('!B', byte)) def __writeByte(self, byte): self.trans.write(pack('!b', byte)) def __writeI16(self, i16): self.__writeVarint(makeZigZag(i16, 16)) def __writeSize(self, i32): self.__writeVarint(i32) def writeCollectionBegin(self, etype, size): assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state if size <= 14: self.__writeUByte(size << 4 | CTYPES[etype]) else: self.__writeUByte(0xf0 | CTYPES[etype]) self.__writeSize(size) self.__containers.append(self.state) self.state = CONTAINER_WRITE writeSetBegin = writeCollectionBegin writeListBegin = writeCollectionBegin def writeMapBegin(self, ktype, vtype, size): assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state if size == 0: self.__writeByte(0) else: self.__writeSize(size) self.__writeUByte(CTYPES[ktype] << 4 | CTYPES[vtype]) self.__containers.append(self.state) self.state = CONTAINER_WRITE def writeCollectionEnd(self): assert self.state == CONTAINER_WRITE, self.state self.state = self.__containers.pop() writeMapEnd = writeCollectionEnd writeSetEnd = writeCollectionEnd writeListEnd = writeCollectionEnd def writeBool(self, bool): if self.state == BOOL_WRITE: if bool: ctype = CompactType.TRUE else: ctype = CompactType.FALSE self.__writeFieldHeader(ctype, self.__bool_fid) elif self.state == CONTAINER_WRITE: if bool: self.__writeByte(CompactType.TRUE) else: self.__writeByte(CompactType.FALSE) else: raise AssertionError("Invalid state in compact protocol") writeByte = writer(__writeByte) writeI16 = writer(__writeI16) @writer def writeI32(self, i32): self.__writeVarint(makeZigZag(i32, 32)) @writer def writeI64(self, i64): self.__writeVarint(makeZigZag(i64, 64)) @writer def writeDouble(self, dub): self.trans.write(pack('> 4 if delta == 0: fid = self.__readI16() else: fid = self.__last_fid + delta self.__last_fid = fid type = type & 0x0f if type == CompactType.TRUE: self.state = BOOL_READ self.__bool_value = True elif type == CompactType.FALSE: self.state = BOOL_READ self.__bool_value = False else: self.state = VALUE_READ return (None, self.__getTType(type), fid) def readFieldEnd(self): assert self.state in (VALUE_READ, BOOL_READ), self.state self.state = FIELD_READ def __readUByte(self): result, = unpack('!B', self.trans.readAll(1)) return result def __readByte(self): result, = unpack('!b', self.trans.readAll(1)) return result def __readVarint(self): return readVarint(self.trans) def __readZigZag(self): return fromZigZag(self.__readVarint()) def __readSize(self): result = self.__readVarint() if result < 0: raise TProtocolException("Length < 0") return result def readMessageBegin(self): assert self.state == CLEAR proto_id = self.__readUByte() if proto_id != self.PROTOCOL_ID: raise TProtocolException(TProtocolException.BAD_VERSION, 'Bad protocol id in the message: %d' % proto_id) ver_type = self.__readUByte() type = (ver_type >> self.TYPE_SHIFT_AMOUNT) & self.TYPE_BITS version = ver_type & self.VERSION_MASK if version != self.VERSION: raise TProtocolException(TProtocolException.BAD_VERSION, 'Bad version: %d (expect %d)' % (version, self.VERSION)) seqid = self.__readVarint() # the sequence is a compact "var int" which is treaded as unsigned, # however the sequence is actually signed... if seqid > 2147483647: seqid = -2147483648 - (2147483648 - seqid) name = self.__readBinary().decode('utf-8') return (name, type, seqid) def readMessageEnd(self): assert self.state == CLEAR assert len(self.__structs) == 0 def readStructBegin(self): assert self.state in (CLEAR, CONTAINER_READ, VALUE_READ), self.state self.__structs.append((self.state, self.__last_fid)) self.state = FIELD_READ self.__last_fid = 0 def readStructEnd(self): assert self.state == FIELD_READ self.state, self.__last_fid = self.__structs.pop() def readCollectionBegin(self): assert self.state in (VALUE_READ, CONTAINER_READ), self.state size_type = self.__readUByte() size = size_type >> 4 type = self.__getTType(size_type) if size == 15: size = self.__readSize() self._check_container_length(size) self.__containers.append(self.state) self.state = CONTAINER_READ return type, size readSetBegin = readCollectionBegin readListBegin = readCollectionBegin def readMapBegin(self): assert self.state in (VALUE_READ, CONTAINER_READ), self.state size = self.__readSize() self._check_container_length(size) types = 0 if size > 0: types = self.__readUByte() vtype = self.__getTType(types) ktype = self.__getTType(types >> 4) self.__containers.append(self.state) self.state = CONTAINER_READ return (ktype, vtype, size) def readCollectionEnd(self): assert self.state == CONTAINER_READ, self.state self.state = self.__containers.pop() readSetEnd = readCollectionEnd readListEnd = readCollectionEnd readMapEnd = readCollectionEnd def readBool(self): if self.state == BOOL_READ: return self.__bool_value == CompactType.TRUE elif self.state == CONTAINER_READ: return self.__readByte() == CompactType.TRUE else: raise AssertionError("Invalid state in compact protocol: %d" % self.state) readByte = reader(__readByte) __readI16 = __readZigZag readI16 = reader(__readZigZag) readI32 = reader(__readZigZag) readI64 = reader(__readZigZag) @reader def readDouble(self): buff = self.trans.readAll(8) val, = unpack('= 0xd800 and codeunit <= 0xdbff def _isLowSurrogate(self, codeunit): return codeunit >= 0xdc00 and codeunit <= 0xdfff def _toChar(self, high, low=None): if not low: return chr(high) else: codepoint = (1 << 16) + ((high & 0x3ff) << 10) codepoint += low & 0x3ff return chr(codepoint) def readJSONString(self, skipContext): highSurrogate = None string = [] if skipContext is False: self.context.read() self.readJSONSyntaxChar(QUOTE) while True: character = self.reader.read() if character == QUOTE: break if ord(character) == ESCSEQ0: character = self.reader.read() if ord(character) == ESCSEQ1: character = self.trans.read(4).decode('ascii') codeunit = int(character, 16) if self._isHighSurrogate(codeunit): if highSurrogate: raise TProtocolException( TProtocolException.INVALID_DATA, "Expected low surrogate char") highSurrogate = codeunit continue elif self._isLowSurrogate(codeunit): if not highSurrogate: raise TProtocolException( TProtocolException.INVALID_DATA, "Expected high surrogate char") character = self._toChar(highSurrogate, codeunit) highSurrogate = None else: character = self._toChar(codeunit) else: if character not in ESCAPE_CHARS: raise TProtocolException( TProtocolException.INVALID_DATA, "Expected control char") character = ESCAPE_CHARS[character] elif character in ESCAPE_CHAR_VALS: raise TProtocolException(TProtocolException.INVALID_DATA, "Unescaped control char") else: utf8_bytes = bytearray([ord(character)]) while ord(self.reader.peek()) >= 0x80: utf8_bytes.append(ord(self.reader.read())) character = utf8_bytes.decode('utf-8') string.append(character) if highSurrogate: raise TProtocolException(TProtocolException.INVALID_DATA, "Expected low surrogate char") return ''.join(string) def isJSONNumeric(self, character): return (True if NUMERIC_CHAR.find(character) != - 1 else False) def readJSONQuotes(self): if (self.context.escapeNum()): self.readJSONSyntaxChar(QUOTE) def readJSONNumericChars(self): numeric = [] while True: character = self.reader.peek() if self.isJSONNumeric(character) is False: break numeric.append(self.reader.read()) return b''.join(numeric).decode('ascii') def readJSONInteger(self): self.context.read() self.readJSONQuotes() numeric = self.readJSONNumericChars() self.readJSONQuotes() try: return int(numeric) except ValueError: raise TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data") def readJSONDouble(self): self.context.read() if self.reader.peek() == QUOTE: string = self.readJSONString(True) try: double = float(string) if (self.context.escapeNum is False and not math.isinf(double) and not math.isnan(double)): raise TProtocolException( TProtocolException.INVALID_DATA, "Numeric data unexpectedly quoted") return double except ValueError: raise TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data") else: if self.context.escapeNum() is True: self.readJSONSyntaxChar(QUOTE) try: return float(self.readJSONNumericChars()) except ValueError: raise TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data") def readJSONBase64(self): string = self.readJSONString(False) size = len(string) m = size % 4 # Force padding since b64encode method does not allow it if m != 0: for i in range(4 - m): string += '=' return base64.b64decode(string) def readJSONObjectStart(self): self.context.read() self.readJSONSyntaxChar(LBRACE) self.pushContext(JSONPairContext(self)) def readJSONObjectEnd(self): self.readJSONSyntaxChar(RBRACE) self.popContext() def readJSONArrayStart(self): self.context.read() self.readJSONSyntaxChar(LBRACKET) self.pushContext(JSONListContext(self)) def readJSONArrayEnd(self): self.readJSONSyntaxChar(RBRACKET) self.popContext() class TJSONProtocol(TJSONProtocolBase): def readMessageBegin(self): self.resetReadContext() self.readJSONArrayStart() if self.readJSONInteger() != VERSION: raise TProtocolException(TProtocolException.BAD_VERSION, "Message contained bad version.") name = self.readJSONString(False) typen = self.readJSONInteger() seqid = self.readJSONInteger() return (name, typen, seqid) def readMessageEnd(self): self.readJSONArrayEnd() def readStructBegin(self): self.readJSONObjectStart() def readStructEnd(self): self.readJSONObjectEnd() def readFieldBegin(self): character = self.reader.peek() ttype = 0 id = 0 if character == RBRACE: ttype = TType.STOP else: id = self.readJSONInteger() self.readJSONObjectStart() ttype = JTYPES[self.readJSONString(False)] return (None, ttype, id) def readFieldEnd(self): self.readJSONObjectEnd() def readMapBegin(self): self.readJSONArrayStart() keyType = JTYPES[self.readJSONString(False)] valueType = JTYPES[self.readJSONString(False)] size = self.readJSONInteger() self.readJSONObjectStart() return (keyType, valueType, size) def readMapEnd(self): self.readJSONObjectEnd() self.readJSONArrayEnd() def readCollectionBegin(self): self.readJSONArrayStart() elemType = JTYPES[self.readJSONString(False)] size = self.readJSONInteger() return (elemType, size) readListBegin = readCollectionBegin readSetBegin = readCollectionBegin def readCollectionEnd(self): self.readJSONArrayEnd() readSetEnd = readCollectionEnd readListEnd = readCollectionEnd def readBool(self): return (False if self.readJSONInteger() == 0 else True) def readNumber(self): return self.readJSONInteger() readByte = readNumber readI16 = readNumber readI32 = readNumber readI64 = readNumber def readDouble(self): return self.readJSONDouble() def readString(self): return self.readJSONString(False) def readBinary(self): return self.readJSONBase64() def readUuid(self): buff = self.readJSONString(False) val = uuid.UUID(buff) return val def writeMessageBegin(self, name, request_type, seqid): self.resetWriteContext() self.writeJSONArrayStart() self.writeJSONNumber(VERSION) self.writeJSONString(name) self.writeJSONNumber(request_type) self.writeJSONNumber(seqid) def writeMessageEnd(self): self.writeJSONArrayEnd() def writeStructBegin(self, name): self.writeJSONObjectStart() def writeStructEnd(self): self.writeJSONObjectEnd() def writeFieldBegin(self, name, ttype, id): self.writeJSONNumber(id) self.writeJSONObjectStart() self.writeJSONString(CTYPES[ttype]) def writeFieldEnd(self): self.writeJSONObjectEnd() def writeFieldStop(self): pass def writeMapBegin(self, ktype, vtype, size): self.writeJSONArrayStart() self.writeJSONString(CTYPES[ktype]) self.writeJSONString(CTYPES[vtype]) self.writeJSONNumber(size) self.writeJSONObjectStart() def writeMapEnd(self): self.writeJSONObjectEnd() self.writeJSONArrayEnd() def writeListBegin(self, etype, size): self.writeJSONArrayStart() self.writeJSONString(CTYPES[etype]) self.writeJSONNumber(size) def writeListEnd(self): self.writeJSONArrayEnd() def writeSetBegin(self, etype, size): self.writeJSONArrayStart() self.writeJSONString(CTYPES[etype]) self.writeJSONNumber(size) def writeSetEnd(self): self.writeJSONArrayEnd() def writeBool(self, boolean): self.writeJSONNumber(1 if boolean is True else 0) def writeByte(self, byte): checkIntegerLimits(byte, 8) self.writeJSONNumber(byte) def writeI16(self, i16): checkIntegerLimits(i16, 16) self.writeJSONNumber(i16) def writeI32(self, i32): checkIntegerLimits(i32, 32) self.writeJSONNumber(i32) def writeI64(self, i64): checkIntegerLimits(i64, 64) self.writeJSONNumber(i64) def writeDouble(self, dbl): # 17 significant digits should be just enough for any double precision # value. self.writeJSONNumber(dbl, '{0:.17g}') def writeString(self, string): self.writeJSONString(string) def writeBinary(self, binary): self.writeJSONBase64(binary) def writeUuid(self, uuid): self.writeJSONString(str(uuid)) class TJSONProtocolFactory(TProtocolFactory): def getProtocol(self, trans): return TJSONProtocol(trans) @property def string_length_limit(senf): return None @property def container_length_limit(senf): return None class TSimpleJSONProtocol(TJSONProtocolBase): """Simple, readable, write-only JSON protocol. Useful for interacting with scripting languages. """ def readMessageBegin(self): raise NotImplementedError() def readMessageEnd(self): raise NotImplementedError() def readStructBegin(self): raise NotImplementedError() def readStructEnd(self): raise NotImplementedError() def writeMessageBegin(self, name, request_type, seqid): self.resetWriteContext() def writeMessageEnd(self): pass def writeStructBegin(self, name): self.writeJSONObjectStart() def writeStructEnd(self): self.writeJSONObjectEnd() def writeFieldBegin(self, name, ttype, fid): self.writeJSONString(name) def writeFieldEnd(self): pass def writeMapBegin(self, ktype, vtype, size): self.writeJSONObjectStart() def writeMapEnd(self): self.writeJSONObjectEnd() def _writeCollectionBegin(self, etype, size): self.writeJSONArrayStart() def _writeCollectionEnd(self): self.writeJSONArrayEnd() writeListBegin = _writeCollectionBegin writeListEnd = _writeCollectionEnd writeSetBegin = _writeCollectionBegin writeSetEnd = _writeCollectionEnd def writeByte(self, byte): checkIntegerLimits(byte, 8) self.writeJSONNumber(byte) def writeI16(self, i16): checkIntegerLimits(i16, 16) self.writeJSONNumber(i16) def writeI32(self, i32): checkIntegerLimits(i32, 32) self.writeJSONNumber(i32) def writeI64(self, i64): checkIntegerLimits(i64, 64) self.writeJSONNumber(i64) def writeBool(self, boolean): self.writeJSONNumber(1 if boolean is True else 0) def writeDouble(self, dbl): self.writeJSONNumber(dbl) def writeString(self, string): self.writeJSONString(string) def writeBinary(self, binary): self.writeJSONBase64(binary) def writeUuid(self, uuid): self.writeJSONString(str(uuid)) class TSimpleJSONProtocolFactory(TProtocolFactory): def getProtocol(self, trans): return TSimpleJSONProtocol(trans) thrift-0.23.0/lib/py/src/protocol/THeaderProtocol.py0000664000175000017500000001707615165535636022646 0ustar00buildbuild00000000000000# # 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 thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated from thrift.protocol.TCompactProtocol import TCompactProtocolAccelerated from thrift.protocol.TProtocol import TProtocolBase, TProtocolException, TProtocolFactory from thrift.Thrift import TApplicationException, TMessageType from thrift.transport.THeaderTransport import THeaderTransport, THeaderSubprotocolID, THeaderClientType PROTOCOLS_BY_ID = { THeaderSubprotocolID.BINARY: TBinaryProtocolAccelerated, THeaderSubprotocolID.COMPACT: TCompactProtocolAccelerated, } class THeaderProtocol(TProtocolBase): """A framed protocol with headers and payload transforms. THeaderProtocol frames other Thrift protocols and adds support for optional out-of-band headers. The currently supported subprotocols are TBinaryProtocol and TCompactProtocol. When used as a client, the subprotocol to frame can be chosen with the `default_protocol` parameter to the constructor. It's also possible to apply transforms to the encoded message payload. The only transform currently supported is to gzip. When used in a server, THeaderProtocol can accept messages from non-THeaderProtocol clients if allowed (see `allowed_client_types`). This includes framed and unframed transports and both TBinaryProtocol and TCompactProtocol. The server will respond in the appropriate dialect for the connected client. HTTP clients are not currently supported. THeaderProtocol does not currently support THTTPServer, TNonblockingServer, or TProcessPoolServer. See doc/specs/HeaderFormat.md for details of the wire format. """ def __init__(self, transport, allowed_client_types, default_protocol=THeaderSubprotocolID.BINARY): # much of the actual work for THeaderProtocol happens down in # THeaderTransport since we need to do low-level shenanigans to detect # if the client is sending us headers or one of the headerless formats # we support. this wraps the real transport with the one that does all # the magic. if not isinstance(transport, THeaderTransport): transport = THeaderTransport(transport, allowed_client_types, default_protocol) super(THeaderProtocol, self).__init__(transport) self._set_protocol() def get_headers(self): return self.trans.get_headers() def set_header(self, key, value): self.trans.set_header(key, value) def clear_headers(self): self.trans.clear_headers() def add_transform(self, transform_id): self.trans.add_transform(transform_id) def writeMessageBegin(self, name, ttype, seqid): self.trans.sequence_id = seqid return self._protocol.writeMessageBegin(name, ttype, seqid) def writeMessageEnd(self): return self._protocol.writeMessageEnd() def writeStructBegin(self, name): return self._protocol.writeStructBegin(name) def writeStructEnd(self): return self._protocol.writeStructEnd() def writeFieldBegin(self, name, ttype, fid): return self._protocol.writeFieldBegin(name, ttype, fid) def writeFieldEnd(self): return self._protocol.writeFieldEnd() def writeFieldStop(self): return self._protocol.writeFieldStop() def writeMapBegin(self, ktype, vtype, size): return self._protocol.writeMapBegin(ktype, vtype, size) def writeMapEnd(self): return self._protocol.writeMapEnd() def writeListBegin(self, etype, size): return self._protocol.writeListBegin(etype, size) def writeListEnd(self): return self._protocol.writeListEnd() def writeSetBegin(self, etype, size): return self._protocol.writeSetBegin(etype, size) def writeSetEnd(self): return self._protocol.writeSetEnd() def writeBool(self, bool_val): return self._protocol.writeBool(bool_val) def writeByte(self, byte): return self._protocol.writeByte(byte) def writeI16(self, i16): return self._protocol.writeI16(i16) def writeI32(self, i32): return self._protocol.writeI32(i32) def writeI64(self, i64): return self._protocol.writeI64(i64) def writeDouble(self, dub): return self._protocol.writeDouble(dub) def writeBinary(self, str_val): return self._protocol.writeBinary(str_val) def _set_protocol(self): try: protocol_cls = PROTOCOLS_BY_ID[self.trans.protocol_id] except KeyError: raise TApplicationException( TProtocolException.INVALID_PROTOCOL, "Unknown protocol requested.", ) self._protocol = protocol_cls(self.trans) self._fast_encode = self._protocol._fast_encode self._fast_decode = self._protocol._fast_decode def readMessageBegin(self): try: self.trans.readFrame(0) self._set_protocol() except TApplicationException as exc: self._protocol.writeMessageBegin(b"", TMessageType.EXCEPTION, 0) exc.write(self._protocol) self._protocol.writeMessageEnd() self.trans.flush() return self._protocol.readMessageBegin() def readMessageEnd(self): return self._protocol.readMessageEnd() def readStructBegin(self): return self._protocol.readStructBegin() def readStructEnd(self): return self._protocol.readStructEnd() def readFieldBegin(self): return self._protocol.readFieldBegin() def readFieldEnd(self): return self._protocol.readFieldEnd() def readMapBegin(self): return self._protocol.readMapBegin() def readMapEnd(self): return self._protocol.readMapEnd() def readListBegin(self): return self._protocol.readListBegin() def readListEnd(self): return self._protocol.readListEnd() def readSetBegin(self): return self._protocol.readSetBegin() def readSetEnd(self): return self._protocol.readSetEnd() def readBool(self): return self._protocol.readBool() def readByte(self): return self._protocol.readByte() def readI16(self): return self._protocol.readI16() def readI32(self): return self._protocol.readI32() def readI64(self): return self._protocol.readI64() def readDouble(self): return self._protocol.readDouble() def readBinary(self): return self._protocol.readBinary() class THeaderProtocolFactory(TProtocolFactory): def __init__( self, allowed_client_types=(THeaderClientType.HEADERS,), default_protocol=THeaderSubprotocolID.BINARY, ): self.allowed_client_types = allowed_client_types self.default_protocol = default_protocol def getProtocol(self, trans): return THeaderProtocol(trans, self.allowed_client_types, self.default_protocol) thrift-0.23.0/lib/py/src/protocol/TProtocolDecorator.py0000664000175000017500000000211515165535636023364 0ustar00buildbuild00000000000000# # 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. # class TProtocolDecorator(object): def __new__(cls, protocol, *args, **kwargs): decorated_cls = type(''.join(['Decorated', protocol.__class__.__name__]), (cls, protocol.__class__), protocol.__dict__) return object.__new__(decorated_cls) thrift-0.23.0/lib/py/src/protocol/TProtocol.py0000664000175000017500000003156315167543515021527 0ustar00buildbuild00000000000000# # 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 thrift.Thrift import TException, TType, TFrozenDict from thrift.transport.TTransport import TTransportException from itertools import islice class TProtocolException(TException): """Custom Protocol Exception class""" UNKNOWN = 0 INVALID_DATA = 1 NEGATIVE_SIZE = 2 SIZE_LIMIT = 3 BAD_VERSION = 4 NOT_IMPLEMENTED = 5 DEPTH_LIMIT = 6 INVALID_PROTOCOL = 7 def __init__(self, type=UNKNOWN, message=None): TException.__init__(self, message) self.type = type class TProtocolBase(object): """Base class for Thrift protocol driver.""" def __init__(self, trans): self.trans = trans self._fast_decode = None self._fast_encode = None @staticmethod def _check_length(limit, length): if length < 0: raise TTransportException(TTransportException.NEGATIVE_SIZE, 'Negative length: %d' % length) if limit is not None and length > limit: raise TTransportException(TTransportException.SIZE_LIMIT, 'Length exceeded max allowed: %d' % limit) def writeMessageBegin(self, name, ttype, seqid): pass def writeMessageEnd(self): pass def writeStructBegin(self, name): pass def writeStructEnd(self): pass def writeFieldBegin(self, name, ttype, fid): pass def writeFieldEnd(self): pass def writeFieldStop(self): pass def writeMapBegin(self, ktype, vtype, size): pass def writeMapEnd(self): pass def writeListBegin(self, etype, size): pass def writeListEnd(self): pass def writeSetBegin(self, etype, size): pass def writeSetEnd(self): pass def writeBool(self, bool_val): pass def writeByte(self, byte): pass def writeI16(self, i16): pass def writeI32(self, i32): pass def writeI64(self, i64): pass def writeDouble(self, dub): pass def writeString(self, str_val): self.writeBinary(bytes(str_val, 'utf-8')) def writeBinary(self, uuid): pass def writeUuid(self, str_val): pass def readMessageBegin(self): pass def readMessageEnd(self): pass def readStructBegin(self): pass def readStructEnd(self): pass def readFieldBegin(self): pass def readFieldEnd(self): pass def readMapBegin(self): pass def readMapEnd(self): pass def readListBegin(self): pass def readListEnd(self): pass def readSetBegin(self): pass def readSetEnd(self): pass def readBool(self): pass def readByte(self): pass def readI16(self): pass def readI32(self): pass def readI64(self): pass def readDouble(self): pass def readString(self): return self.readBinary().decode('utf-8') def readBinary(self): pass def readUuid(self): pass def skip(self, ttype): if ttype == TType.BOOL: self.readBool() elif ttype == TType.BYTE: self.readByte() elif ttype == TType.I16: self.readI16() elif ttype == TType.I32: self.readI32() elif ttype == TType.I64: self.readI64() elif ttype == TType.DOUBLE: self.readDouble() elif ttype == TType.STRING: self.readString() elif ttype == TType.STRUCT: name = self.readStructBegin() while True: (name, ttype, id) = self.readFieldBegin() if ttype == TType.STOP: break self.skip(ttype) self.readFieldEnd() self.readStructEnd() elif ttype == TType.MAP: (ktype, vtype, size) = self.readMapBegin() for i in range(size): self.skip(ktype) self.skip(vtype) self.readMapEnd() elif ttype == TType.SET: (etype, size) = self.readSetBegin() for i in range(size): self.skip(etype) self.readSetEnd() elif ttype == TType.LIST: (etype, size) = self.readListBegin() for i in range(size): self.skip(etype) self.readListEnd() elif ttype == TType.UUID: self.readUuid() else: raise TProtocolException( TProtocolException.INVALID_DATA, "invalid TType") # tuple of: ( 'reader method' name, is_container bool, 'writer_method' name ) _TTYPE_HANDLERS = ( (None, None, False), # 0 TType.STOP (None, None, False), # 1 TType.VOID # TODO: handle void? ('readBool', 'writeBool', False), # 2 TType.BOOL ('readByte', 'writeByte', False), # 3 TType.BYTE and I08 ('readDouble', 'writeDouble', False), # 4 TType.DOUBLE (None, None, False), # 5 undefined ('readI16', 'writeI16', False), # 6 TType.I16 (None, None, False), # 7 undefined ('readI32', 'writeI32', False), # 8 TType.I32 (None, None, False), # 9 undefined ('readI64', 'writeI64', False), # 10 TType.I64 ('readString', 'writeString', False), # 11 TType.STRING and UTF7 ('readContainerStruct', 'writeContainerStruct', True), # 12 *.STRUCT ('readContainerMap', 'writeContainerMap', True), # 13 TType.MAP ('readContainerSet', 'writeContainerSet', True), # 14 TType.SET ('readContainerList', 'writeContainerList', True), # 15 TType.LIST ('readUuid', 'writeUuid', False), # 16 TType.UUID ) def _ttype_handlers(self, ttype, spec): if spec == 'BINARY': if ttype != TType.STRING: raise TProtocolException(type=TProtocolException.INVALID_DATA, message='Invalid binary field type %d' % ttype) return ('readBinary', 'writeBinary', False) return self._TTYPE_HANDLERS[ttype] if ttype < len(self._TTYPE_HANDLERS) else (None, None, False) def _read_by_ttype(self, ttype, spec, espec): reader_name, _, is_container = self._ttype_handlers(ttype, espec) if reader_name is None: raise TProtocolException(type=TProtocolException.INVALID_DATA, message='Invalid type %d' % (ttype)) reader_func = getattr(self, reader_name) read = (lambda: reader_func(espec)) if is_container else reader_func while True: yield read() def readFieldByTType(self, ttype, spec): return next(self._read_by_ttype(ttype, spec, spec)) def readContainerList(self, spec): ttype, tspec, is_immutable = spec (list_type, list_len) = self.readListBegin() # TODO: compare types we just decoded with thrift_spec elems = islice(self._read_by_ttype(ttype, spec, tspec), list_len) results = (tuple if is_immutable else list)(elems) self.readListEnd() return results def readContainerSet(self, spec): ttype, tspec, is_immutable = spec (set_type, set_len) = self.readSetBegin() # TODO: compare types we just decoded with thrift_spec elems = islice(self._read_by_ttype(ttype, spec, tspec), set_len) results = (frozenset if is_immutable else set)(elems) self.readSetEnd() return results def readContainerStruct(self, spec): (obj_class, obj_spec) = spec # If obj_class.read is a classmethod (e.g. in frozen structs), # call it as such. if getattr(obj_class.read, '__self__', None) is obj_class: obj = obj_class.read(self) else: obj = obj_class() obj.read(self) return obj def readContainerMap(self, spec): ktype, kspec, vtype, vspec, is_immutable = spec (map_ktype, map_vtype, map_len) = self.readMapBegin() # TODO: compare types we just decoded with thrift_spec and # abort/skip if types disagree keys = self._read_by_ttype(ktype, spec, kspec) vals = self._read_by_ttype(vtype, spec, vspec) keyvals = islice(zip(keys, vals), map_len) results = (TFrozenDict if is_immutable else dict)(keyvals) self.readMapEnd() return results def readStruct(self, obj, thrift_spec, is_immutable=False): if is_immutable: fields = {} self.readStructBegin() while True: (fname, ftype, fid) = self.readFieldBegin() if ftype == TType.STOP: break try: field = thrift_spec[fid] except IndexError: self.skip(ftype) else: if field is not None and ftype == field[1]: fname = field[2] fspec = field[3] val = self.readFieldByTType(ftype, fspec) if is_immutable: fields[fname] = val else: setattr(obj, fname, val) else: self.skip(ftype) self.readFieldEnd() self.readStructEnd() if is_immutable: return obj(**fields) def writeContainerStruct(self, val, spec): val.write(self) def writeContainerList(self, val, spec): ttype, tspec, _ = spec self.writeListBegin(ttype, len(val)) for _ in self._write_by_ttype(ttype, val, spec, tspec): pass self.writeListEnd() def writeContainerSet(self, val, spec): ttype, tspec, _ = spec self.writeSetBegin(ttype, len(val)) for _ in self._write_by_ttype(ttype, val, spec, tspec): pass self.writeSetEnd() def writeContainerMap(self, val, spec): ktype, kspec, vtype, vspec, _ = spec self.writeMapBegin(ktype, vtype, len(val)) for _ in zip(self._write_by_ttype(ktype, val.keys(), spec, kspec), self._write_by_ttype(vtype, val.values(), spec, vspec)): pass self.writeMapEnd() def writeStruct(self, obj, thrift_spec): self.writeStructBegin(obj.__class__.__name__) for field in thrift_spec: if field is None: continue fname = field[2] val = getattr(obj, fname) if val is None: # skip writing out unset fields continue fid = field[0] ftype = field[1] fspec = field[3] self.writeFieldBegin(fname, ftype, fid) self.writeFieldByTType(ftype, val, fspec) self.writeFieldEnd() self.writeFieldStop() self.writeStructEnd() def _write_by_ttype(self, ttype, vals, spec, espec): _, writer_name, is_container = self._ttype_handlers(ttype, espec) writer_func = getattr(self, writer_name) write = (lambda v: writer_func(v, espec)) if is_container else writer_func for v in vals: yield write(v) def writeFieldByTType(self, ttype, val, spec): next(self._write_by_ttype(ttype, [val], spec, spec)) def checkIntegerLimits(i, bits): if bits == 8 and (i < -128 or i > 127): raise TProtocolException(TProtocolException.INVALID_DATA, "i8 requires -128 <= number <= 127") elif bits == 16 and (i < -32768 or i > 32767): raise TProtocolException(TProtocolException.INVALID_DATA, "i16 requires -32768 <= number <= 32767") elif bits == 32 and (i < -2147483648 or i > 2147483647): raise TProtocolException(TProtocolException.INVALID_DATA, "i32 requires -2147483648 <= number <= 2147483647") elif bits == 64 and (i < -9223372036854775808 or i > 9223372036854775807): raise TProtocolException(TProtocolException.INVALID_DATA, "i64 requires -9223372036854775808 <= number <= 9223372036854775807") class TProtocolFactory(object): def getProtocol(self, trans): pass thrift-0.23.0/lib/py/src/protocol/__init__.py0000664000175000017500000000163215165535636021336 0ustar00buildbuild00000000000000# # 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. # __all__ = ['fastbinary', 'TBase', 'TBinaryProtocol', 'TCompactProtocol', 'TJSONProtocol', 'TProtocol', 'TProtocolDecorator'] thrift-0.23.0/lib/py/src/Thrift.py0000664000175000017500000001262315167543515017175 0ustar00buildbuild00000000000000# # 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. # class TType(object): STOP = 0 VOID = 1 BOOL = 2 BYTE = 3 I08 = 3 DOUBLE = 4 I16 = 6 I32 = 8 I64 = 10 STRING = 11 UTF7 = 11 STRUCT = 12 MAP = 13 SET = 14 LIST = 15 UUID = 16 _VALUES_TO_NAMES = ( 'STOP', 'VOID', 'BOOL', 'BYTE', 'DOUBLE', None, 'I16', None, 'I32', None, 'I64', 'STRING', 'STRUCT', 'MAP', 'SET', 'LIST', 'UUID', ) class TMessageType(object): CALL = 1 REPLY = 2 EXCEPTION = 3 ONEWAY = 4 class TProcessor(object): """Base class for processor, which works on two streams.""" def process(self, iprot, oprot): """ Process a request. The normal behvaior is to have the processor invoke the correct handler and then it is the server's responsibility to write the response to oprot. """ pass def on_message_begin(self, func): """ Install a callback that receives (name, type, seqid) after the message header is read. """ pass class TException(Exception): """Base class for all thrift exceptions.""" def __init__(self, message=None): Exception.__init__(self, message) super(TException, self).__setattr__("message", message) class TApplicationException(TException): """Application level thrift exceptions.""" UNKNOWN = 0 UNKNOWN_METHOD = 1 INVALID_MESSAGE_TYPE = 2 WRONG_METHOD_NAME = 3 BAD_SEQUENCE_ID = 4 MISSING_RESULT = 5 INTERNAL_ERROR = 6 PROTOCOL_ERROR = 7 INVALID_TRANSFORM = 8 INVALID_PROTOCOL = 9 UNSUPPORTED_CLIENT_TYPE = 10 def __init__(self, type=UNKNOWN, message=None): TException.__init__(self, message) self.type = type def __str__(self): if self.message: return self.message elif self.type == self.UNKNOWN_METHOD: return 'Unknown method' elif self.type == self.INVALID_MESSAGE_TYPE: return 'Invalid message type' elif self.type == self.WRONG_METHOD_NAME: return 'Wrong method name' elif self.type == self.BAD_SEQUENCE_ID: return 'Bad sequence ID' elif self.type == self.MISSING_RESULT: return 'Missing result' elif self.type == self.INTERNAL_ERROR: return 'Internal error' elif self.type == self.PROTOCOL_ERROR: return 'Protocol error' elif self.type == self.INVALID_TRANSFORM: return 'Invalid transform' elif self.type == self.INVALID_PROTOCOL: return 'Invalid protocol' elif self.type == self.UNSUPPORTED_CLIENT_TYPE: return 'Unsupported client type' else: return 'Default (unknown) TApplicationException' def read(self, iprot): iprot.readStructBegin() while True: (fname, ftype, fid) = iprot.readFieldBegin() if ftype == TType.STOP: break if fid == 1: if ftype == TType.STRING: self.message = iprot.readString() else: iprot.skip(ftype) elif fid == 2: if ftype == TType.I32: self.type = iprot.readI32() else: iprot.skip(ftype) else: iprot.skip(ftype) iprot.readFieldEnd() iprot.readStructEnd() def write(self, oprot): oprot.writeStructBegin('TApplicationException') if self.message is not None: oprot.writeFieldBegin('message', TType.STRING, 1) oprot.writeString(self.message) oprot.writeFieldEnd() if self.type is not None: oprot.writeFieldBegin('type', TType.I32, 2) oprot.writeI32(self.type) oprot.writeFieldEnd() oprot.writeFieldStop() oprot.writeStructEnd() class TFrozenDict(dict): """A dictionary that is "frozen" like a frozenset""" def __init__(self, *args, **kwargs): super(TFrozenDict, self).__init__(*args, **kwargs) # Sort the items so they will be in a consistent order. # XOR in the hash of the class so we don't collide with # the hash of a list of tuples. self.__hashval = hash(TFrozenDict) ^ hash(tuple(sorted(self.items()))) def __setitem__(self, *args): raise TypeError("Can't modify frozen TFreezableDict") def __delitem__(self, *args): raise TypeError("Can't modify frozen TFreezableDict") def __hash__(self): return self.__hashval thrift-0.23.0/lib/py/src/TMultiplexedProcessor.py0000664000175000017500000000641115165535636022256 0ustar00buildbuild00000000000000# # 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 thrift.Thrift import TProcessor, TMessageType from thrift.protocol import TProtocolDecorator, TMultiplexedProtocol from thrift.protocol.TProtocol import TProtocolException class TMultiplexedProcessor(TProcessor): def __init__(self): self.defaultProcessor = None self.services = {} def registerDefault(self, processor): """ If a non-multiplexed processor connects to the server and wants to communicate, use the given processor to handle it. This mechanism allows servers to upgrade from non-multiplexed to multiplexed in a backwards-compatible way and still handle old clients. """ self.defaultProcessor = processor def registerProcessor(self, serviceName, processor): self.services[serviceName] = processor def on_message_begin(self, func): for key in self.services.keys(): self.services[key].on_message_begin(func) def process(self, iprot, oprot): (name, type, seqid) = iprot.readMessageBegin() if type != TMessageType.CALL and type != TMessageType.ONEWAY: raise TProtocolException( TProtocolException.NOT_IMPLEMENTED, "TMultiplexedProtocol only supports CALL & ONEWAY") index = name.find(TMultiplexedProtocol.SEPARATOR) if index < 0: if self.defaultProcessor: return self.defaultProcessor.process( StoredMessageProtocol(iprot, (name, type, seqid)), oprot) else: raise TProtocolException( TProtocolException.NOT_IMPLEMENTED, "Service name not found in message name: " + name + ". " + "Did you forget to use TMultiplexedProtocol in your client?") serviceName = name[0:index] call = name[index + len(TMultiplexedProtocol.SEPARATOR):] if serviceName not in self.services: raise TProtocolException( TProtocolException.NOT_IMPLEMENTED, "Service name not found: " + serviceName + ". " + "Did you forget to call registerProcessor()?") standardMessage = (call, type, seqid) return self.services[serviceName].process( StoredMessageProtocol(iprot, standardMessage), oprot) class StoredMessageProtocol(TProtocolDecorator.TProtocolDecorator): def __init__(self, protocol, messageBegin): self.messageBegin = messageBegin def readMessageBegin(self): return self.messageBegin thrift-0.23.0/lib/py/src/__init__.py0000664000175000017500000000146115165535636017475 0ustar00buildbuild00000000000000# # 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. # __all__ = ['Thrift', 'TSCons'] thrift-0.23.0/lib/py/MANIFEST.in0000664000175000017500000000002215165535636016323 0ustar00buildbuild00000000000000include src/ext/* thrift-0.23.0/lib/py/test/0000775000175000017500000000000015167543515015547 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/test/test_sslsocket.py0000664000175000017500000003614015165535636021201 0ustar00buildbuild00000000000000# # 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 inspect import logging import time import os import platform import ssl import sys import tempfile import threading import unittest import warnings from contextlib import contextmanager import _import_local_thrift # noqa SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__)) ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR))) SERVER_PEM = os.path.join(ROOT_DIR, 'test', 'keys', 'server.pem') SERVER_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'server.crt') SERVER_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'server.key') CLIENT_CERT_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.crt') CLIENT_KEY_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.key') CLIENT_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.crt') CLIENT_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.key') CLIENT_CA = os.path.join(ROOT_DIR, 'test', 'keys', 'CA.pem') TEST_CIPHERS = 'DES-CBC3-SHA:ECDHE-RSA-AES128-GCM-SHA256' class ServerAcceptor(threading.Thread): def __init__(self, server, expect_failure=False): super(ServerAcceptor, self).__init__() self.daemon = True self._server = server self._listening = threading.Event() self._port = None self._port_bound = threading.Event() self._client = None self._client_accepted = threading.Event() self._expect_failure = expect_failure frame = inspect.stack(3)[2] self.name = frame[3] del frame def run(self): self._server.listen() self._listening.set() try: address = self._server.handle.getsockname() if len(address) > 1: # AF_INET addresses are 2-tuples (host, port) and AF_INET6 are # 4-tuples (host, port, ...), but in each case port is in the second slot. self._port = address[1] finally: self._port_bound.set() try: self._client = self._server.accept() if self._client: 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) if not self._expect_failure: raise finally: self._client_accepted.set() def await_listening(self): self._listening.wait() @property def port(self): self._port_bound.wait() return self._port @property def client(self): self._client_accepted.wait() return self._client def close(self): if self._client: self._client.close() self._server.close() # Python 2.6 compat class AssertRaises(object): def __init__(self, expected): self._expected = expected def __enter__(self): pass def __exit__(self, exc_type, exc_value, traceback): if not exc_type or not issubclass(exc_type, self._expected): raise Exception('fail') return True @unittest.skip("failing SSL test to be fixed in subsequent pull request") class TSSLSocketTest(unittest.TestCase): def _server_socket(self, **kwargs): return TSSLServerSocket(port=0, **kwargs) @contextmanager def _connectable_client(self, server, expect_failure=False, path=None, **client_kwargs): acc = ServerAcceptor(server, expect_failure) try: acc.start() acc.await_listening() host, port = ('localhost', acc.port) if path is None else (None, None) client = TSSLSocket(host, port, unix_socket=path, **client_kwargs) yield acc, client finally: acc.close() def _assert_connection_failure(self, server, path=None, **client_args): logging.disable(logging.CRITICAL) try: with self._connectable_client(server, True, path=path, **client_args) as (acc, client): # We need to wait for a connection failure, but not too long. 20ms is a tunable # compromise between test speed and stability client.setTimeout(20) with self._assert_raises(TTransportException): client.open() client.write(b"hello") client.read(5) # b"there" finally: logging.disable(logging.NOTSET) def _assert_raises(self, exc): if sys.hexversion >= 0x020700F0: return self.assertRaises(exc) else: return AssertRaises(exc) def _assert_connection_success(self, server, path=None, **client_args): with self._connectable_client(server, path=path, **client_args) as (acc, client): try: self.assertFalse(client.isOpen()) client.open() self.assertTrue(client.isOpen()) client.write(b"hello") self.assertEqual(client.read(5), b"there") self.assertTrue(acc.client is not None) finally: client.close() # deprecated feature def test_deprecation(self): with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT) self.assertEqual(len(w), 1) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) # Deprecated signature # def __init__(self, host='localhost', port=9090, validate=True, ca_certs=None, keyfile=None, certfile=None, unix_socket=None, ciphers=None): TSSLSocket('localhost', 0, True, SERVER_CERT, CLIENT_KEY, CLIENT_CERT, None, TEST_CIPHERS) self.assertEqual(len(w), 7) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) # Deprecated signature # def __init__(self, host=None, port=9090, certfile='cert.pem', unix_socket=None, ciphers=None): TSSLServerSocket(None, 0, SERVER_PEM, None, TEST_CIPHERS) self.assertEqual(len(w), 3) # deprecated feature def test_set_cert_reqs_by_validate(self): with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) c1 = TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT) self.assertEqual(c1.cert_reqs, ssl.CERT_REQUIRED) c1 = TSSLSocket('localhost', 0, validate=False) self.assertEqual(c1.cert_reqs, ssl.CERT_NONE) self.assertEqual(len(w), 2) # deprecated feature def test_set_validate_by_cert_reqs(self): with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__) c1 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_NONE) self.assertFalse(c1.validate) c2 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT) self.assertTrue(c2.validate) c3 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_OPTIONAL, ca_certs=SERVER_CERT) self.assertTrue(c3.validate) self.assertEqual(len(w), 3) def test_unix_domain_socket(self): if platform.system() == 'Windows': print('skipping test_unix_domain_socket') return fd, path = tempfile.mkstemp() os.close(fd) os.unlink(path) try: server = self._server_socket(unix_socket=path, keyfile=SERVER_KEY, certfile=SERVER_CERT) self._assert_connection_success(server, path=path, cert_reqs=ssl.CERT_NONE) finally: os.unlink(path) def test_server_cert(self): server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT) server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) # server cert not in ca_certs self._assert_connection_failure(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=CLIENT_CERT) server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE) def test_set_server_cert(self): server = self._server_socket(keyfile=SERVER_KEY, certfile=CLIENT_CERT) with self._assert_raises(Exception): server.certfile = 'foo' with self._assert_raises(Exception): server.certfile = None server.certfile = SERVER_CERT self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT) def test_client_cert(self): if not _match_has_ipaddress: print('skipping test_client_cert') return server = self._server_socket( cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY, certfile=SERVER_CERT, ca_certs=CLIENT_CERT) self._assert_connection_failure(server, cert_reqs=ssl.CERT_NONE, certfile=SERVER_CERT, keyfile=SERVER_KEY) server = self._server_socket( cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY, certfile=SERVER_CERT, ca_certs=CLIENT_CA) self._assert_connection_failure(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT_NO_IP, keyfile=CLIENT_KEY_NO_IP) server = self._server_socket( cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY, certfile=SERVER_CERT, ca_certs=CLIENT_CA) self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY) server = self._server_socket( cert_reqs=ssl.CERT_OPTIONAL, keyfile=SERVER_KEY, certfile=SERVER_CERT, ca_certs=CLIENT_CA) self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY) def test_ciphers(self): server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS) self._assert_connection_success(server, ca_certs=SERVER_CERT, ciphers=TEST_CIPHERS) if not TSSLSocket._has_ciphers: # unittest.skip is not available for Python 2.6 print('skipping test_ciphers') return server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL') server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS) self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL') def test_ssl2_and_ssl3_disabled(self): if not hasattr(ssl, 'PROTOCOL_SSLv3'): print('PROTOCOL_SSLv3 is not available') else: server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3) server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3) self._assert_connection_failure(server, ca_certs=SERVER_CERT) if not hasattr(ssl, 'PROTOCOL_SSLv2'): print('PROTOCOL_SSLv2 is not available') else: server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT) self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv2) server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv2) self._assert_connection_failure(server, ca_certs=SERVER_CERT) def test_newer_tls(self): if not TSSLSocket._has_ssl_context: # unittest.skip is not available for Python 2.6 print('skipping test_newer_tls') return if not hasattr(ssl, 'PROTOCOL_TLSv1_2'): print('PROTOCOL_TLSv1_2 is not available') else: server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2) self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2) if not hasattr(ssl, 'PROTOCOL_TLSv1_1'): print('PROTOCOL_TLSv1_1 is not available') else: server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1) self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1) if not hasattr(ssl, 'PROTOCOL_TLSv1_1') or not hasattr(ssl, 'PROTOCOL_TLSv1_2'): print('PROTOCOL_TLSv1_1 and/or PROTOCOL_TLSv1_2 is not available') else: server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2) self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1) def test_ssl_context(self): if not TSSLSocket._has_ssl_context: # unittest.skip is not available for Python 2.6 print('skipping test_ssl_context') return server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) server_context.load_cert_chain(SERVER_CERT, SERVER_KEY) server_context.load_verify_locations(CLIENT_CA) server_context.verify_mode = ssl.CERT_REQUIRED server = self._server_socket(ssl_context=server_context) client_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) client_context.load_cert_chain(CLIENT_CERT, CLIENT_KEY) client_context.load_verify_locations(SERVER_CERT) client_context.verify_mode = ssl.CERT_REQUIRED self._assert_connection_success(server, ssl_context=client_context) # Add a dummy test because starting from python 3.12, if all tests in a test # file are skipped that's considered an error. class DummyTest(unittest.TestCase): def test_dummy(self): self.assertEqual(0, 0) if __name__ == '__main__': logging.basicConfig(level=logging.WARN) from thrift.transport.TSSLSocket import TSSLSocket, TSSLServerSocket, _match_has_ipaddress from thrift.transport.TTransport import TTransportException unittest.main() thrift-0.23.0/lib/py/test/test_thrift_file/0000775000175000017500000000000015165535636021110 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/test/test_thrift_file/TestServer.thrift0000664000175000017500000000162615165535636024445 0ustar00buildbuild00000000000000# # 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 Message { 1: optional string body, 2: optional i64 num, } service TestServer{ string add_and_get_msg(1:string msg) } thrift-0.23.0/lib/py/test/test_sasl_transport.py0000664000175000017500000001301415167543515022235 0ustar00buildbuild00000000000000# # 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 os import sys import types import unittest from unittest.mock import MagicMock, PropertyMock, call # Register 'thrift' as a package alias for the src directory so that # tests can run without a build step. This mirrors setup.py's # package_dir={'thrift': 'src'} configuration. _src_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'src')) if 'thrift' not in sys.modules: _thrift_pkg = types.ModuleType('thrift') _thrift_pkg.__path__ = [_src_dir] _thrift_pkg.__package__ = 'thrift' sys.modules['thrift'] = _thrift_pkg # Stub puresasl so TSaslClientTransport can be imported without it installed. sys.modules.setdefault('puresasl', types.ModuleType('puresasl')) sys.modules.setdefault('puresasl.client', types.ModuleType('puresasl.client')) from thrift.transport.TTransport import TSaslClientTransport from thrift.transport.TTransport import TTransportException class TSaslClientTransportTest(unittest.TestCase): def _make_transport(self, process_side_effect, recv_messages, complete_value=True): transport = object.__new__(TSaslClientTransport) mock_inner = MagicMock() mock_inner.isOpen.return_value = True transport.transport = mock_inner mock_sasl = MagicMock() mock_sasl.mechanism = 'DIGEST-MD5' mock_sasl.process.side_effect = process_side_effect type(mock_sasl).complete = PropertyMock(return_value=complete_value) transport.sasl = mock_sasl transport.send_sasl_msg = MagicMock() transport.recv_sasl_msg = MagicMock(side_effect=recv_messages) return transport, mock_sasl def test_open_with_none_initial_response(self): transport, mock_sasl = self._make_transport( process_side_effect=[None, b'response'], recv_messages=[ (TSaslClientTransport.OK, b'server-challenge'), (TSaslClientTransport.COMPLETE, b''), ], ) transport.open() transport.send_sasl_msg.assert_any_call( TSaslClientTransport.START, b'DIGEST-MD5' ) transport.send_sasl_msg.assert_any_call(TSaslClientTransport.OK, b'') mock_sasl.process.assert_any_call(b'server-challenge') def test_open_with_bytes_initial_response(self): transport, mock_sasl = self._make_transport( process_side_effect=[b'initial-token'], recv_messages=[ (TSaslClientTransport.COMPLETE, b''), ], ) transport.open() transport.send_sasl_msg.assert_any_call( TSaslClientTransport.OK, b'initial-token' ) def test_open_complete_with_challenge(self): transport, mock_sasl = self._make_transport( process_side_effect=[b'initial', b'response', None], recv_messages=[ (TSaslClientTransport.OK, b'challenge1'), (TSaslClientTransport.COMPLETE, b'rspauth=abc123'), ], ) transport.open() mock_sasl.process.assert_any_call(b'rspauth=abc123') def test_open_complete_without_challenge(self): transport, mock_sasl = self._make_transport( process_side_effect=[b'initial'], recv_messages=[ (TSaslClientTransport.COMPLETE, b''), ], ) transport.open() process_calls = mock_sasl.process.call_args_list self.assertNotIn(call(b''), process_calls) def test_open_bad_status_raises(self): transport, mock_sasl = self._make_transport( process_side_effect=[b'initial'], recv_messages=[ (0xFF, b'error message'), ], ) with self.assertRaises(TTransportException) as ctx: transport.open() self.assertIn('Bad SASL negotiation status', str(ctx.exception)) def test_open_incomplete_after_complete_status_raises(self): transport, mock_sasl = self._make_transport( process_side_effect=[b'initial'], recv_messages=[ (TSaslClientTransport.COMPLETE, b''), ], complete_value=False, ) with self.assertRaises(TTransportException) as ctx: transport.open() self.assertIn('erroneously indicated', str(ctx.exception)) def test_open_process_raises_during_complete(self): transport, mock_sasl = self._make_transport( process_side_effect=[b'initial', Exception('rspauth verification failed')], recv_messages=[ (TSaslClientTransport.COMPLETE, b'rspauth=bad'), ], ) with self.assertRaises(Exception) as ctx: transport.open() self.assertIn('rspauth verification failed', str(ctx.exception)) if __name__ == '__main__': unittest.main() thrift-0.23.0/lib/py/test/_import_local_thrift.py0000664000175000017500000000232715165535636022333 0ustar00buildbuild00000000000000# # 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 glob import os import sys SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__)) ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR))) for libpath in glob.glob(os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib.*')): for pattern in ('-%d.%d', '-%d%d'): postfix = pattern % (sys.version_info[0], sys.version_info[1]) if libpath.endswith(postfix): sys.path.insert(0, libpath) break thrift-0.23.0/lib/py/test/thrift_TSerializer.py0000664000175000017500000000524715167543515021746 0ustar00buildbuild00000000000000# # 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 unittest import os import sys gen_path = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "gen-py" ) sys.path.append(gen_path) import _import_local_thrift # noqa from thrift.protocol.TBinaryProtocol import TBinaryProtocolFactory from thrift.protocol.TBinaryProtocol import TBinaryProtocolAcceleratedFactory from thrift.protocol.TCompactProtocol import TCompactProtocolFactory from thrift.protocol.TCompactProtocol import TCompactProtocolAcceleratedFactory from thrift.TSerialization import serialize, deserialize from TestServer.ttypes import Message class TestSerializer(unittest.TestCase): def setUp(self): self.message = Message("hello thrift", 42) self.binary_serialized = b"\x0b\x00\x01\x00\x00\x00\x0chello thrift\n\x00\x02\x00\x00\x00\x00\x00\x00\x00*\x00" self.compact_serialized = b'\x18\x0chello thrift\x16T\x00' def verify(self, serialized, factory): self.assertEqual(serialized, serialize(self.message, factory)) self.assertEqual( "hello thrift", deserialize(Message(), serialized, factory).body, ) self.assertEqual( 42, deserialize(Message(), serialized, factory).num ) self.assertRaises(EOFError, deserialize, Message(), b'', factory) def test_TBinaryProtocol(self): factory = TBinaryProtocolFactory() self.verify(self.binary_serialized, factory) def test_TBinaryProtocolAccelerated(self): factory = TBinaryProtocolAcceleratedFactory() self.verify(self.binary_serialized, factory) def test_TCompactProtocol(self): factory = TCompactProtocolFactory() self.verify(self.compact_serialized, factory) def test_TCompactProtocolAccelerated(self): factory = TCompactProtocolAcceleratedFactory() self.verify(self.compact_serialized, factory) if __name__ == "__main__": unittest.main() thrift-0.23.0/lib/py/test/thrift_TZlibTransport.py0000664000175000017500000000637515165535636022460 0ustar00buildbuild00000000000000# # 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 unittest import random import string import _import_local_thrift # noqa from thrift.transport import TTransport from thrift.transport import TZlibTransport def generate_random_buff(): data = [] buf_len = 1024 * 32 index = 0 while index < buf_len: run_len = random.randint(1, 64) if index + run_len > buf_len: run_len = buf_len - index for i in range(run_len): data.extend(random.sample(string.printable, 1)) index += 1 new_data = ''.join(data) return new_data class TestTZlibTransport(unittest.TestCase): def test_write_then_read(self): buff = TTransport.TMemoryBuffer() trans = TTransport.TBufferedTransportFactory().getTransport(buff) zlib_trans = TZlibTransport.TZlibTransport(trans) data_w = generate_random_buff() zlib_trans.write(data_w.encode('utf-8')) zlib_trans.flush() value = buff.getvalue() zlib_trans.close() buff = TTransport.TMemoryBuffer(value) trans = TTransport.TBufferedTransportFactory().getTransport(buff) zlib_trans = TZlibTransport.TZlibTransport(trans) data_r = zlib_trans.read(len(data_w)) zlib_trans.close() try: self.assertEqual(data_w, data_r.decode('utf-8')) self.assertEqual(len(data_w), len(data_r.decode('utf-8'))) except AssertionError: raise def test_after_flushd_write_then_read(self): buff = TTransport.TMemoryBuffer() trans = TTransport.TBufferedTransportFactory().getTransport(buff) zlib_trans = TZlibTransport.TZlibTransport(trans) data_w_1 = "hello thrift !@#" * 50 zlib_trans.write(data_w_1.encode('utf-8')) zlib_trans.flush() data_w_2 = "{'name': 'thrift', 1: ['abcd' , 233, ('a','c')]}" * 20 zlib_trans.write(data_w_2.encode('utf-8')) zlib_trans.flush() value = buff.getvalue() zlib_trans.close() buff = TTransport.TMemoryBuffer(value) trans = TTransport.TBufferedTransportFactory().getTransport(buff) zlib_trans = TZlibTransport.TZlibTransport(trans) data_r = zlib_trans.read(len(data_w_1) + len(data_w_2)) zlib_trans.close() try: self.assertEqual(data_w_1 + data_w_2, data_r.decode('utf-8')) self.assertEqual(len(data_w_1) + len(data_w_2), len(data_r.decode('utf-8'))) except AssertionError: raise if __name__ == '__main__': unittest.main() thrift-0.23.0/lib/py/test/thrift_TNonblockingServer.py0000664000175000017500000000561515165535636023271 0ustar00buildbuild00000000000000# # 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 os import sys import threading import unittest import time gen_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "gen-py") sys.path.append(gen_path) import _import_local_thrift # noqa from TestServer import TestServer from thrift.transport import TSocket, TTransport from thrift.protocol import TBinaryProtocol from thrift.server import TNonblockingServer class Handler: def add_and_get_msg(self, msg): return msg class Server: def __init__(self): handler = Handler() processor = TestServer.Processor(handler) transport = TSocket.TServerSocket("127.0.0.1", 30030) self.server = TNonblockingServer.TNonblockingServer(processor, transport) def start_server(self): print("-------start server ------\n") self.server.serve() print("------stop server -----\n") def close_server(self): self.server.stop() self.server.close() class Client: def start_client(self): transport = TSocket.TSocket("127.0.0.1", 30030) trans = TTransport.TFramedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(trans) client = TestServer.Client(protocol) trans.open() self.msg = client.add_and_get_msg("hello thrift") def get_message(self): try: msg = self.msg return msg except AttributeError as e: raise e print("self.msg not exit\n") class TestNonblockingServer(unittest.TestCase): def test_normalconnection(self): serve = Server() client = Client() serve_thread = threading.Thread(target=serve.start_server) client_thread = threading.Thread(target=client.start_client) serve_thread.start() time.sleep(10) client_thread.start() client_thread.join(0.5) try: msg = client.get_message() self.assertEqual("hello thrift", msg) except AssertionError as e: raise e print("assert failure") finally: serve.close_server() if __name__ == '__main__': unittest.main() thrift-0.23.0/lib/py/test/thrift_TCompactProtocol.py0000664000175000017500000002550315167543515022742 0ustar00buildbuild00000000000000# # 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 _import_local_thrift # noqa from thrift.protocol import TCompactProtocol from thrift.transport import TTransport import unittest import uuid CLEAR = 0 FIELD_WRITE = 1 VALUE_WRITE = 2 CONTAINER_WRITE = 3 BOOL_WRITE = 4 FIELD_READ = 5 CONTAINER_READ = 6 VALUE_READ = 7 BOOL_READ = 8 def testNaked(type, data): buf = TTransport.TMemoryBuffer() transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TCompactProtocol.TCompactProtocol(transport) if type.capitalize() == 'Byte': protocol.state = VALUE_WRITE protocol.writeByte(data) elif type.capitalize() == 'I16': protocol.state = CONTAINER_WRITE protocol.writeI16(data) elif type.capitalize() == 'I32': protocol.state = CONTAINER_WRITE protocol.writeI32(data) elif type.capitalize() == 'I64': protocol.state = CONTAINER_WRITE protocol.writeI64(data) elif type.capitalize() == 'String': protocol.state = CONTAINER_WRITE protocol.writeString(data) elif type.capitalize() == 'Double': protocol.state = VALUE_WRITE protocol.writeDouble(data) elif type.capitalize() == 'Binary': protocol.state = FIELD_WRITE protocol.writeBinary(data) elif type.capitalize() == 'Bool': protocol.state = CONTAINER_WRITE protocol.writeBool(True) if type.capitalize() == 'Uuid': protocol.state = CONTAINER_WRITE protocol.writeUuid(data) transport.flush() data_r = buf.getvalue() buf = TTransport.TMemoryBuffer(data_r) transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TCompactProtocol.TCompactProtocol(transport) if type.capitalize() == 'Byte': protocol.state = VALUE_READ return protocol.readByte() elif type.capitalize() == 'I16': protocol.state = CONTAINER_READ return protocol.readI16() elif type.capitalize() == 'I32': protocol.state = CONTAINER_READ return protocol.readI32() elif type.capitalize() == 'I64': protocol.state = CONTAINER_READ return protocol.readI64() elif type.capitalize() == 'String': protocol.state = VALUE_READ return protocol.readString() elif type.capitalize() == 'Double': protocol.state = VALUE_READ return protocol.readDouble() elif type.capitalize() == 'Binary': protocol.state = FIELD_READ return protocol.readBinary() elif type.capitalize() == 'Bool': protocol.state = CONTAINER_READ return protocol.readBool() if type.capitalize() == 'Uuid': protocol.state = CONTAINER_READ return protocol.readUuid() def testField(type, data): TType = {"Bool": 2, "Byte": 3, "Binary": 5, "I16": 6, "I32": 8, "I64": 10, "Double": 11, "String": 12, "Uuid": 13} buf = TTransport.TMemoryBuffer() transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TCompactProtocol.TCompactProtocol(transport) protocol.writeStructBegin('struct') protocol.writeFieldBegin("field", TType[type.capitalize()], 10) if type.capitalize() == 'Byte': protocol.writeByte(data) elif type.capitalize() == 'I16': protocol.writeI16(data) elif type.capitalize() == 'I32': protocol.writeI32(data) elif type.capitalize() == 'I64': protocol.writeI64(data) elif type.capitalize() == 'String': protocol.writeString(data) elif type.capitalize() == 'Double': protocol.writeDouble(data) elif type.capitalize() == 'Binary': protocol.writeBinary(data) elif type.capitalize() == 'Bool': protocol.writeBool(data) if type.capitalize() == 'Uuid': protocol.writeUuid(data) protocol.writeFieldEnd() protocol.writeStructEnd() transport.flush() data_r = buf.getvalue() buf = TTransport.TMemoryBuffer(data_r) transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TCompactProtocol.TCompactProtocol(transport) protocol.readStructBegin() protocol.readFieldBegin() if type.capitalize() == 'Byte': return protocol.readByte() elif type.capitalize() == 'I16': return protocol.readI16() elif type.capitalize() == 'I32': return protocol.readI32() elif type.capitalize() == 'I64': return protocol.readI32() elif type.capitalize() == 'String': return protocol.readString() elif type.capitalize() == 'Double': return protocol.readDouble() elif type.capitalize() == 'Binary': return protocol.readBinary() elif type.capitalize() == 'Bool': return protocol.readBool() if type.capitalize() == 'Uuid': return protocol.readUuid() protocol.readFieldEnd() protocol.readStructEnd() def testMessage(data): message = {} message['name'] = data[0] message['type'] = data[1] message['seqid'] = data[2] buf = TTransport.TMemoryBuffer() transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TCompactProtocol.TCompactProtocol(transport) protocol.writeMessageBegin(message['name'], message['type'], message['seqid']) protocol.writeMessageEnd() transport.flush() data_r = buf.getvalue() buf = TTransport.TMemoryBuffer(data_r) transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TCompactProtocol.TCompactProtocol(transport) result = protocol.readMessageBegin() protocol.readMessageEnd() return result class TestTCompactProtocol(unittest.TestCase): def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) def test_TCompactProtocol_write_read(self): try: testNaked('Byte', 123) for i in range(0, 128): self.assertEqual(i, testField('Byte', i)) self.assertEqual(-i, testField('Byte', -i)) self.assertEqual(0, testNaked("I16", 0)) self.assertEqual(1, testNaked("I16", 1)) self.assertEqual(15000, testNaked("I16", 15000)) self.assertEqual(0x7fff, testNaked('I16', 0x7fff)) self.assertEqual(-1, testNaked('I16', -1)) self.assertEqual(-15000, testNaked('I16', -15000)) self.assertEqual(-0x7fff, testNaked('I16', -0x7fff)) self.assertEqual(32767, testNaked('I16', 32767)) self.assertEqual(0, testField('I16', 0)) self.assertEqual(1, testField('I16', 1)) self.assertEqual(7, testField('I16', 7)) self.assertEqual(150, testField('I16', 150)) self.assertEqual(15000, testField('I16', 15000)) self.assertEqual(0x7fff, testField('I16', 0x7fff)) self.assertEqual(-1, testField('I16', -1)) self.assertEqual(-7, testField('I16', -7)) self.assertEqual(-150, testField('I16', -150)) self.assertEqual(-15000, testField('I16', -15000)) self.assertEqual(-0xfff, testField('I16', -0xfff)) self.assertEqual(0, testNaked('I32', 0)) self.assertEqual(1, testNaked('I32', 1)) self.assertEqual(15000, testNaked('I32', 15000)) self.assertEqual(0xfff, testNaked('I32', 0xfff)) self.assertEqual(-1, testNaked('I32', -1)) self.assertEqual(-15000, testNaked('I32', -15000)) self.assertEqual(-0xfff, testNaked('I32', -0xfff)) self.assertEqual(2147483647, testNaked('I32', 2147483647)) self.assertEqual(-2147483647, testNaked('I32', -2147483647)) self.assertEqual(0, testField('I32', 0)) self.assertEqual(1, testField('I32', 1)) self.assertEqual(7, testField('I32', 7)) self.assertEqual(150, testField('I32', 150)) self.assertEqual(15000, testField('I32', 15000)) self.assertEqual(31337, testField('I32', 31337)) self.assertEqual(0xffff, testField('I32', 0xffff)) self.assertEqual(0xffffff, testField('I32', 0xffffff)) self.assertEqual(-1, testField('I32', -1)) self.assertEqual(-7, testField('I32', -7)) self.assertEqual(-150, testField('I32', -150)) self.assertEqual(-15000, testField('I32', -15000)) self.assertEqual(-0xffff, testField('I32', -0xffff)) self.assertEqual(-0xffffff, testField('I32', -0xffffff)) self.assertEqual(9223372036854775807, testNaked("I64", 9223372036854775807)) self.assertEqual(-9223372036854775807, testNaked('I64', -9223372036854775807)) self.assertEqual(-0, testNaked('I64', 0)) self.assertEqual(True, testNaked('Bool', True)) self.assertEqual(3.14159261, testNaked('Double', 3.14159261)) self.assertEqual("hello thrift", testNaked('String', "hello thrift")) self.assertEqual(True, testField('Bool', True)) self.assertEqual(3.14159261, testField('Double', 3.14159261)) self.assertEqual("hello thrift", testField('String', "hello thrift")) self.assertEqual(uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'), testNaked("Uuid", uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'))) self.assertEqual(uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'), testField("Uuid", uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'))) TMessage = {"T_CALL": 1, "T_REPLY": 2, "T_EXCEPTION": 3, "T_ONEWAY": 4} test_data = [("short message name", TMessage["T_CALL"], 0), ("1", TMessage["T_REPLY"], 12345), ("loooooooooooooooooooong", TMessage["T_EXCEPTION"], 1 << 16), ("one way push", TMessage["T_ONEWAY"], 12), ("JANKY", TMessage["T_CALL"], 0)] for dt in test_data: result = testMessage(dt) 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() thrift-0.23.0/lib/py/test/fuzz/0000775000175000017500000000000015167543515016545 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/test/fuzz/fuzz_roundtrip_TBinaryProtocolAccelerated.py0000664000175000017500000000177715167543515027526 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_roundtrip_fuzzer from thrift.protocol.TBinaryProtocol import TBinaryProtocolAcceleratedFactory def main(): run_roundtrip_fuzzer(TBinaryProtocolAcceleratedFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/fuzz/fuzz_roundtrip_TCompactProtocol.py0000664000175000017500000000175415167543515025546 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_roundtrip_fuzzer from thrift.protocol.TCompactProtocol import TCompactProtocolFactory def main(): run_roundtrip_fuzzer(TCompactProtocolFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/fuzz/fuzz_common.py0000664000175000017500000001212215167543515021463 0ustar00buildbuild00000000000000# # 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 glob import sys import os import atheris def setup_thrift_imports(): """Set up the Python path to include Thrift libraries and generated code.""" # For oss-fuzz, we need to package it using pyinstaller and set up paths properly if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): print('running in a PyInstaller bundle') sys.path.insert(0, "thrift_lib") sys.path.insert(0, "gen-py") else: print('running in a normal Python process') SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__)) ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR)))) for libpath in glob.glob(os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib.*')): for pattern in ('-%d.%d', '-%d%d'): postfix = pattern % (sys.version_info[0], sys.version_info[1]) if libpath.endswith(postfix): sys.path.insert(0, libpath) break gen_path = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "..", "gen-py" ) sys.path.append(gen_path) print(sys.path) setup_thrift_imports() from thrift.transport import TTransport from thrift.TSerialization import serialize, deserialize from fuzz.ttypes import FuzzTest def create_parser_fuzzer(protocol_factory_class): """ Create a parser fuzzer function for a specific protocol. Args: protocol_factory_class: The Thrift protocol factory class to use Returns: A function that can be used with atheris.Setup() """ def TestOneInput(data): if len(data) < 2: return try: # Create a memory buffer with the fuzzed data buf = TTransport.TMemoryBuffer(data) TTransport.TBufferedTransportFactory().getTransport(buf) factory = protocol_factory_class(string_length_limit=1000, container_length_limit=1000) # Try to deserialize the fuzzed data into the test class deserialize(FuzzTest(), data, factory) except Exception: # We expect various exceptions during fuzzing pass return TestOneInput def create_roundtrip_fuzzer(protocol_factory_class): """ Create a roundtrip fuzzer function for a specific protocol. Args: protocol_factory_class: The Thrift protocol factory class to use Returns: A function that can be used with atheris.Setup() """ def TestOneInput(data): if len(data) < 2: return try: # Create a memory buffer with the fuzzed data buf = TTransport.TMemoryBuffer(data) TTransport.TBufferedTransportFactory().getTransport(buf) factory = protocol_factory_class(string_length_limit=1000, container_length_limit=1000) # Try to deserialize the fuzzed data into the test class test_instance = deserialize(FuzzTest(), data, factory) # If deserialization succeeds, try to serialize it back serialized = serialize(test_instance, factory) # Deserialize again deserialized = deserialize(FuzzTest(), serialized, factory) # Verify the objects are equal after a second deserialization assert test_instance == deserialized except AssertionError: raise except Exception: # We expect various exceptions during fuzzing pass return TestOneInput def _run_fuzzer(fuzzer_function): """ Set up and run the fuzzer for a specific protocol. Args: fuzzer_function: The fuzzer function to use """ setup_thrift_imports() atheris.instrument_all() atheris.Setup(sys.argv, fuzzer_function, enable_python_coverage=True) atheris.Fuzz() def run_roundtrip_fuzzer(protocol_factory_class): """ Set up and run the fuzzer for a specific protocol. Args: protocol_factory_class: The Thrift protocol factory class to use """ _run_fuzzer(create_roundtrip_fuzzer(protocol_factory_class)) def run_parser_fuzzer(protocol_factory_class): """ Set up and run the fuzzer for a specific protocol. Args: protocol_factory_class: The Thrift protocol factory class to use """ _run_fuzzer(create_parser_fuzzer(protocol_factory_class)) thrift-0.23.0/lib/py/test/fuzz/fuzz_parse_TCompactProtocolAccelerated.py0000664000175000017500000000177415167543515026751 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_parser_fuzzer from thrift.protocol.TCompactProtocol import TCompactProtocolAcceleratedFactory def main(): run_parser_fuzzer(TCompactProtocolAcceleratedFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/fuzz/fuzz_parse_TCompactProtocol.py0000664000175000017500000000174615167543515024633 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_parser_fuzzer from thrift.protocol.TCompactProtocol import TCompactProtocolFactory def main(): run_parser_fuzzer(TCompactProtocolFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/fuzz/README.md0000664000175000017500000000330115165535636020024 0ustar00buildbuild00000000000000# Python Fuzzing README The Python Thrift implementation uses Atheris for fuzzing. Atheris is a coverage-guided, in-process fuzzer for Python that integrates with libFuzzer. Unlike the C++ implementation, the Python fuzzers are not directly runnable in a local environment. Instead, Atheris generates Python programs that need to be executed through the appropriate build system. We currently have several fuzz targets that test different aspects of the Thrift implementation: * FuzzParseBinary -- fuzzes the deserialization of the Binary protocol * FuzzParseBinaryAccelerated -- fuzzes the deserialization of the accelerated Binary protocol * FuzzParseCompact -- fuzzes the deserialization of the Compact protocol * FuzzParseCompactAccelerated -- fuzzes the deserialization of the accelerated Compact protocol * FuzzRoundtripBinary -- fuzzes the roundtrip of the Binary protocol (i.e. serializes then deserializes and compares the result) * FuzzRoundtripBinaryAccelerated -- fuzzes the roundtrip of the accelerated Binary protocol * FuzzRoundtripCompact -- fuzzes the roundtrip of the Compact protocol * FuzzRoundtripCompactAccelerated -- fuzzes the roundtrip of the accelerated Compact protocol The fuzzers use Atheris's mutation engine to generate test cases. Each fuzzer implements the standard Atheris interface and uses common testing code from the fuzz test utilities in `fuzz_common.py`. For more information about Atheris and its options, see the [Atheris documentation](https://github.com/google/atheris). You can also use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these Python fuzzers, since the wire formats are identical between implementations. thrift-0.23.0/lib/py/test/fuzz/fuzz_parse_TBinaryProtocolAccelerated.py0000664000175000017500000000177115167543515026604 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_parser_fuzzer from thrift.protocol.TBinaryProtocol import TBinaryProtocolAcceleratedFactory def main(): run_parser_fuzzer(TBinaryProtocolAcceleratedFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/fuzz/fuzz_parse_TBinaryProtocol.py0000664000175000017500000000174315167543515024466 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_parser_fuzzer from thrift.protocol.TBinaryProtocol import TBinaryProtocolFactory def main(): run_parser_fuzzer(TBinaryProtocolFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/fuzz/fuzz_roundtrip_TBinaryProtocol.py0000664000175000017500000000175115167543515025401 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_roundtrip_fuzzer from thrift.protocol.TBinaryProtocol import TBinaryProtocolFactory def main(): run_roundtrip_fuzzer(TBinaryProtocolFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/fuzz/fuzz_roundtrip_TCompactProtocolAccelerated.py0000664000175000017500000000200215167543515027646 0ustar00buildbuild00000000000000# # 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 fuzz_common import run_roundtrip_fuzzer from thrift.protocol.TCompactProtocol import TCompactProtocolAcceleratedFactory def main(): run_roundtrip_fuzzer(TCompactProtocolAcceleratedFactory) if __name__ == "__main__": main() thrift-0.23.0/lib/py/test/thrift_transport.py0000664000175000017500000000455015165535636021544 0ustar00buildbuild00000000000000# # 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 unittest import os import _import_local_thrift # noqa from thrift.transport import TTransport class TestTFileObjectTransport(unittest.TestCase): def test_TFileObjectTransport(self): test_dir = os.path.dirname(os.path.abspath(__file__)) datatxt_path = os.path.join(test_dir, 'data.txt') buffer = '{"soft":"thrift","version":0.13,"1":true}' with open(datatxt_path, "w+") as f: buf = TTransport.TFileObjectTransport(f) buf.write(buffer) buf.flush() buf.close() with open(datatxt_path, "rb") as f: buf = TTransport.TFileObjectTransport(f) value = buf.read(len(buffer)).decode('utf-8') self.assertEqual(buffer, value) buf.close() os.remove(datatxt_path) class TestMemoryBuffer(unittest.TestCase): def test_memorybuffer_write(self): data = '{"1":[1,"hello"],"a":{"A":"abc"},"bool":true,"num":12345}' buffer_w = TTransport.TMemoryBuffer() buffer_w.write(data.encode('utf-8')) value = buffer_w.getvalue() self.assertEqual(value.decode('utf-8'), data) buffer_w.close() def test_memorybuffer_read(self): data = '{"1":[1, "hello"],"a":{"A":"abc"},"bool":true,"num":12345}' buffer_r = TTransport.TMemoryBuffer(data.encode('utf-8')) value_r = buffer_r.read(len(data)) value = buffer_r.getvalue() self.assertEqual(value.decode('utf-8'), data) self.assertEqual(value_r.decode('utf-8'), data) buffer_r.close() if __name__ == '__main__': unittest.main() thrift-0.23.0/lib/py/test/thrift_TBinaryProtocol.py0000664000175000017500000002561715167543515022606 0ustar00buildbuild00000000000000# # 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 unittest import uuid import _import_local_thrift # noqa from thrift.protocol.TBinaryProtocol import TBinaryProtocol from thrift.transport import TTransport def testNaked(type, data): buf = TTransport.TMemoryBuffer() transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TBinaryProtocol(transport) if type.capitalize() == 'Byte': protocol.writeByte(data) if type.capitalize() == 'I16': protocol.writeI16(data) if type.capitalize() == 'I32': protocol.writeI32(data) if type.capitalize() == 'I64': protocol.writeI64(data) if type.capitalize() == 'String': protocol.writeString(data) if type.capitalize() == 'Double': protocol.writeDouble(data) if type.capitalize() == 'Binary': protocol.writeBinary(data) if type.capitalize() == 'Bool': protocol.writeBool(data) if type.capitalize() == 'Uuid': protocol.writeUuid(data) transport.flush() data_r = buf.getvalue() buf = TTransport.TMemoryBuffer(data_r) transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TBinaryProtocol(transport) if type.capitalize() == 'Byte': return protocol.readByte() if type.capitalize() == 'I16': return protocol.readI16() if type.capitalize() == 'I32': return protocol.readI32() if type.capitalize() == 'I64': return protocol.readI64() if type.capitalize() == 'String': return protocol.readString() if type.capitalize() == 'Double': return protocol.readDouble() if type.capitalize() == 'Binary': return protocol.readBinary() if type.capitalize() == 'Bool': return protocol.readBool() if type.capitalize() == 'Uuid': return protocol.readUuid() def testField(type, data): TType = {"Bool": 2, "Byte": 3, "Binary": 5, "I16": 6, "I32": 8, "I64": 10, "Double": 11, "String": 12, "Uuid": 13} buf = TTransport.TMemoryBuffer() transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TBinaryProtocol(transport) protocol.writeStructBegin('struct') protocol.writeFieldBegin("field", TType[type.capitalize()], 10) if type.capitalize() == 'Byte': protocol.writeByte(data) if type.capitalize() == 'I16': protocol.writeI16(data) if type.capitalize() == 'I32': protocol.writeI32(data) if type.capitalize() == 'I64': protocol.writeI64(data) if type.capitalize() == 'String': protocol.writeString(data) if type.capitalize() == 'Double': protocol.writeDouble(data) if type.capitalize() == 'Binary': protocol.writeBinary(data) if type.capitalize() == 'Bool': protocol.writeBool(data) if type.capitalize() == 'Uuid': protocol.writeUuid(data) protocol.writeFieldEnd() protocol.writeStructEnd() transport.flush() data_r = buf.getvalue() buf = TTransport.TMemoryBuffer(data_r) transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TBinaryProtocol(transport) protocol.readStructBegin() protocol.readFieldBegin() if type.capitalize() == 'Byte': return protocol.readByte() if type.capitalize() == 'I16': return protocol.readI16() if type.capitalize() == 'I32': return protocol.readI32() if type.capitalize() == 'I64': return protocol.readI64() if type.capitalize() == 'String': return protocol.readString() if type.capitalize() == 'Double': return protocol.readDouble() if type.capitalize() == 'Binary': return protocol.readBinary() if type.capitalize() == 'Bool': return protocol.readBool() if type.capitalize() == 'Uuid': return protocol.readUuid() protocol.readFieldEnd() protocol.readStructEnd() 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, strictRead=strictRead, strictWrite=strictWrite) protocol.writeMessageBegin(message['name'], message['type'], message['seqid']) protocol.writeMessageEnd() transport.flush() data_r = buf.getvalue() buf = TTransport.TMemoryBuffer(data_r) transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TBinaryProtocol(transport, strictRead=strictRead, strictWrite=strictWrite) result = protocol.readMessageBegin() protocol.readMessageEnd() return result class TestTBinaryProtocol(unittest.TestCase): def test_TBinaryProtocol_write_read(self): try: testNaked('Byte', 123) for i in range(0, 128): self.assertEqual(i, testField('Byte', i)) self.assertEqual(-i, testField('Byte', -i)) self.assertEqual(0, testNaked("I16", 0)) self.assertEqual(1, testNaked("I16", 1)) self.assertEqual(15000, testNaked("I16", 15000)) self.assertEqual(0x7fff, testNaked("I16", 0x7fff)) self.assertEqual(-1, testNaked("I16", -1)) self.assertEqual(-15000, testNaked("I16", -15000)) self.assertEqual(-0x7fff, testNaked("I16", -0x7fff)) self.assertEqual(32767, testNaked("I16", 32767)) self.assertEqual(-32768, testNaked("I16", -32768)) self.assertEqual(0, testField("I16", 0)) self.assertEqual(1, testField("I16", 1)) self.assertEqual(7, testField("I16", 7)) self.assertEqual(150, testField("I16", 150)) self.assertEqual(15000, testField("I16", 15000)) self.assertEqual(0x7fff, testField("I16", 0x7fff)) self.assertEqual(-1, testField("I16", -1)) self.assertEqual(-7, testField("I16", -7)) self.assertEqual(-150, testField("I16", -150)) self.assertEqual(-15000, testField("I16", -15000)) self.assertEqual(-0xfff, testField("I16", -0xfff)) self.assertEqual(0, testNaked("I32", 0)) self.assertEqual(1, testNaked("I32", 1)) self.assertEqual(15000, testNaked("I32", 15000)) self.assertEqual(0xffff, testNaked("I32", 0xffff)) self.assertEqual(-1, testNaked("I32", -1)) self.assertEqual(-15000, testNaked("I32", -15000)) self.assertEqual(-0xffff, testNaked("I32", -0xffff)) self.assertEqual(2147483647, testNaked("I32", 2147483647)) self.assertEqual(-2147483647, testNaked("I32", -2147483647)) self.assertEqual(0, testField("I32", 0)) self.assertEqual(1, testField("I32", 1)) self.assertEqual(7, testField("I32", 7)) self.assertEqual(150, testField("I32", 150)) self.assertEqual(15000, testField("I32", 15000)) self.assertEqual(31337, testField("I32", 31337)) self.assertEqual(0xffff, testField("I32", 0xffff)) self.assertEqual(0xffffff, testField("I32", 0xffffff)) self.assertEqual(-1, testField("I32", -1)) self.assertEqual(-7, testField("I32", -7)) self.assertEqual(-150, testField("I32", -150)) self.assertEqual(-15000, testField("I32", -15000)) self.assertEqual(-0xffff, testField("I32", -0xffff)) self.assertEqual(-0xffffff, testField("I32", -0xffffff)) self.assertEqual(9223372036854775807, testNaked("I64", 9223372036854775807)) self.assertEqual(-9223372036854775807, testNaked("I64", -9223372036854775807)) self.assertEqual(-0, testNaked("I64", 0)) self.assertEqual(True, testNaked("Bool", True)) self.assertEqual(3.14159261, testNaked("Double", 3.14159261)) self.assertEqual("hello thrift", testNaked("String", "hello thrift")) self.assertEqual(True, testField('Bool', True)) self.assertEqual(3.1415926, testNaked("Double", 3.1415926)) self.assertEqual("hello thrift", testNaked("String", "hello thrift")) self.assertEqual(uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'), testNaked("Uuid", uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'))) self.assertEqual(uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'), testField("Uuid", uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}'))) 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)] for dt in test_data: result = testMessage(dt) 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 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() thrift-0.23.0/lib/py/test/test_socket.py0000664000175000017500000000771415167543515020461 0ustar00buildbuild00000000000000# # 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 errno import time import unittest from test_sslsocket import ServerAcceptor import _import_local_thrift # noqa from thrift.transport.TSocket import TServerSocket from thrift.transport.TSocket import TSocket from thrift.transport.TTransport import TTransportException class TSocketTest(unittest.TestCase): def test_failed_connection_raises_exception(self): sock = TSocket(host="localhost", port=60606) # unused port with self.assertRaises(TTransportException) as ctx: sock.open() exc = ctx.exception self.assertEqual(exc.type, TTransportException.NOT_OPEN) self.assertIn("Could not connect to any of", exc.message) self.assertIsNotNone(exc.inner) self.assertIn("Connection refused", str(exc.inner)) 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 timeouts = [ None, # blocking mode 0, # non-blocking mode 1.0, # timeout mode ] for timeout in timeouts: acc = ServerAcceptor(TServerSocket(port=0)) acc.start() sock = TSocket(host="localhost", port=acc.port) self.assertFalse(sock.isOpen()) sock.open() sock.setTimeout(timeout) # the socket shows as open immediately after connecting self.assertTrue(sock.isOpen()) # and remains open during usage sock.write(b"hello") self.assertTrue(sock.isOpen()) while True: try: sock.read(5) except TTransportException as exc: if exc.inner.errno == errno.EAGAIN: # try again when we're in non-blocking mode continue raise break self.assertTrue(sock.isOpen()) # 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.assertIsNotNone(sock.handle) # Give the kernel a moment to propagate FIN before asserting. deadline = time.monotonic() + 0.5 while sock.isOpen() and time.monotonic() < deadline: time.sleep(0.01) self.assertFalse(sock.isOpen(), "socket still open after 0.5s") # after isOpen() returned False the socket should be closed (THRIFT-5813) self.assertIsNone(sock.handle) if __name__ == "__main__": unittest.main() thrift-0.23.0/lib/py/test/test_compiler/0000775000175000017500000000000015167543515020420 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/test/test_compiler/test_keyword_escape.py0000775000175000017500000000751015167543515025043 0ustar00buildbuild00000000000000#!/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. import os import sys import subprocess import tempfile import py_compile import glob import shutil def find_thrift(): """Find the thrift compiler.""" # Check THRIFT environment variable (set by build system) if 'THRIFT' in os.environ: thrift_path = os.environ['THRIFT'] if os.path.exists(thrift_path): return thrift_path # Check common locations in PATH paths = [ 'thrift', '/usr/local/bin/thrift', '/usr/bin/thrift', ] for path in paths: if shutil.which(path): return path # Check if we're in the source tree with built compiler possible_build_thrift = os.path.join( os.path.dirname(__file__), '..', '..', '..', 'build', 'compiler', 'cpp', 'bin', 'thrift') if os.path.exists(possible_build_thrift): return possible_build_thrift # Check for cpp compiler location possible_cpp_thrift = os.path.join( os.path.dirname(__file__), '..', '..', '..', 'compiler', 'cpp', 'thrift') if os.path.exists(possible_cpp_thrift): return possible_cpp_thrift return None def test_keyword_escape_compilation(): """ Test that the Python generator produces valid Python code when the Thrift schema contains Python keywords. This verifies THRIFT-5927: Python code generator should escape identifiers that are Python reserved keywords. """ thrift_file = os.path.join(os.path.dirname(__file__), 'Thrift5927.thrift') if not os.path.exists(thrift_file): print("ERROR: Test file not found: " + thrift_file) return 1 thrift_bin = find_thrift() if not thrift_bin: print("WARNING: thrift compiler not found, skipping test") print("(In CI, thrift should be available via THRIFT env var)") return 0 # Skip gracefully rather than fail with tempfile.TemporaryDirectory() as tmpdir: result = subprocess.run( [thrift_bin, '-r', '-gen', 'py', '-out', tmpdir, thrift_file], capture_output=True, text=True ) if result.returncode != 0: print("ERROR: thrift compiler failed") print("stdout: " + result.stdout) print("stderr: " + result.stderr) return 1 py_files = glob.glob(os.path.join(tmpdir, '**', '*.py'), recursive=True) if not py_files: print("ERROR: No Python files generated") return 1 failed = [] for py_file in py_files: try: py_compile.compile(py_file, doraise=True) except py_compile.PyCompileError as e: failed.append((py_file, str(e))) if failed: print("ERROR: Generated Python files have syntax errors:") for file_path, error in failed: print(" " + file_path + ": " + error) return 1 print("OK: All " + str(len(py_files)) + " generated Python files compile successfully") return 0 if __name__ == '__main__': sys.exit(test_keyword_escape_compilation()) thrift-0.23.0/lib/py/test/test_compiler/Thrift5927.thrift0000664000175000017500000000204215167543515023427 0ustar00buildbuild00000000000000# 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 py thrift5927 enum Lambda { None = 0, FluxCapacitor = 1 } struct False { 1: Lambda finally } union import { 1: import print 2: False while } exception True { 1: import print } service continue { import return(1: False while) throws (1: True yield) } thrift-0.23.0/lib/py/test/test_immutable_exception.py0000664000175000017500000002277315167543515023230 0ustar00buildbuild00000000000000#!/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. # """ Test cases for THRIFT-4002: Immutable exception deserialization. This test verifies that immutable structs (including exceptions, which are immutable by default since Thrift 0.14.0) can be properly deserialized without triggering the __setattr__ TypeError. The bug manifests when: 1. A struct class is marked immutable (has __setattr__ that raises TypeError) 2. Thrift's deserialization tries to set attributes via setattr instead of using the kwargs constructor This test ensures that all deserialization paths (C extension, pure Python, all protocols) correctly handle immutable structs. """ import unittest from collections.abc import Hashable import glob import os import sys SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__)) ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR))) for libpath in glob.glob(os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib.*')): for pattern in ('-%d.%d', '-%d%d'): postfix = pattern % (sys.version_info[0], sys.version_info[1]) if libpath.endswith(postfix): sys.path.insert(0, libpath) break else: src_path = os.path.join(ROOT_DIR, 'lib', 'py', 'src') if os.path.exists(src_path): sys.path.insert(0, src_path) from thrift.Thrift import TException from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol, TCompactProtocol class ImmutableException(TException): """Test exception that mimics generated immutable exception behavior.""" thrift_spec = ( None, # 0 (1, 11, 'message', 'UTF8', None, ), # 1: string ) def __init__(self, message=None): super(ImmutableException, self).__init__(message) def __setattr__(self, *args): raise TypeError("can't modify immutable instance") def __delattr__(self, *args): raise TypeError("can't modify immutable instance") def __hash__(self): return hash(self.__class__) ^ hash((self.message,)) def __eq__(self, other): return isinstance(other, self.__class__) and self.message == other.message def write(self, oprot): if oprot._fast_encode is not None and self.thrift_spec is not None: oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) return oprot.writeStructBegin('ImmutableException') if self.message is not None: oprot.writeFieldBegin('message', 11, 1) oprot.writeString(self.message) oprot.writeFieldEnd() oprot.writeFieldStop() oprot.writeStructEnd() @classmethod def read(cls, iprot): if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and cls.thrift_spec is not None: return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec]) return iprot.readStruct(cls, cls.thrift_spec, True) class MutableException(TException): """Test exception that mimics generated mutable exception behavior.""" thrift_spec = ( None, # 0 (1, 11, 'message', 'UTF8', None, ), # 1: string ) def __init__(self, message=None): super(MutableException, self).__init__(message) def write(self, oprot): if oprot._fast_encode is not None and self.thrift_spec is not None: oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec])) return oprot.writeStructBegin('MutableException') if self.message is not None: oprot.writeFieldBegin('message', 11, 1) oprot.writeString(self.message) oprot.writeFieldEnd() oprot.writeFieldStop() oprot.writeStructEnd() @classmethod def read(cls, iprot): if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and cls.thrift_spec is not None: return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec]) return iprot.readStruct(cls, cls.thrift_spec, False) class TestImmutableExceptionDeserialization(unittest.TestCase): """Test that immutable exceptions can be properly deserialized.""" def _roundtrip(self, exc, protocol_class): """Serialize and deserialize an exception.""" otrans = TTransport.TMemoryBuffer() oproto = protocol_class.getProtocol(otrans) exc.write(oproto) itrans = TTransport.TMemoryBuffer(otrans.getvalue()) iproto = protocol_class.getProtocol(itrans) return exc.__class__.read(iproto) def test_immutable_exception_is_hashable(self): """Verify that immutable exceptions are hashable (required for caching/logging).""" exc = ImmutableException(message="test") self.assertTrue(isinstance(exc, Hashable)) self.assertEqual(hash(exc), hash(ImmutableException(message="test"))) def test_immutable_exception_blocks_modification(self): """Verify that immutable exceptions raise TypeError on attribute modification.""" exc = ImmutableException(message="test") with self.assertRaises(TypeError) as cm: exc.message = "modified" self.assertIn("immutable", str(cm.exception)) def test_immutable_exception_blocks_deletion(self): """Verify that immutable exceptions raise TypeError on attribute deletion.""" exc = ImmutableException(message="test") with self.assertRaises(TypeError) as cm: del exc.message self.assertIn("immutable", str(cm.exception)) def test_immutable_exception_binary_protocol(self): """Test immutable exception deserialization with TBinaryProtocol.""" exc = ImmutableException(message="test error") deserialized = self._roundtrip(exc, TBinaryProtocol.TBinaryProtocolFactory()) self.assertEqual(exc.message, deserialized.message) self.assertEqual(exc, deserialized) def test_immutable_exception_compact_protocol(self): """Test immutable exception deserialization with TCompactProtocol.""" exc = ImmutableException(message="test error") deserialized = self._roundtrip(exc, TCompactProtocol.TCompactProtocolFactory()) self.assertEqual(exc.message, deserialized.message) self.assertEqual(exc, deserialized) def test_mutable_exception_can_be_modified(self): """Verify that mutable exceptions can be modified (control test).""" exc = MutableException(message="original") exc.message = "modified" self.assertEqual(exc.message, "modified") class TestImmutableExceptionAccelerated(unittest.TestCase): """Test immutable exception deserialization with accelerated protocols (C extension).""" def setUp(self): try: # The import is intentionally unused - it only checks if the C extension # is available by catching ImportError. The noqa comment documents this. from thrift.protocol import fastbinary # noqa: F401 self._has_c_extension = True except ImportError: self._has_c_extension = False def _roundtrip(self, exc, protocol_class): """Serialize and deserialize an exception.""" otrans = TTransport.TMemoryBuffer() oproto = protocol_class.getProtocol(otrans) exc.write(oproto) itrans = TTransport.TMemoryBuffer(otrans.getvalue()) iproto = protocol_class.getProtocol(itrans) return exc.__class__.read(iproto) def test_immutable_exception_binary_accelerated(self): """Test immutable exception with TBinaryProtocolAccelerated.""" if not self._has_c_extension: self.skipTest("C extension not available") exc = ImmutableException(message="test error") deserialized = self._roundtrip( exc, TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False) ) self.assertEqual(exc.message, deserialized.message) self.assertEqual(exc, deserialized) def test_immutable_exception_compact_accelerated(self): """Test immutable exception with TCompactProtocolAccelerated.""" if not self._has_c_extension: self.skipTest("C extension not available") exc = ImmutableException(message="test error") deserialized = self._roundtrip( exc, TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False) ) self.assertEqual(exc.message, deserialized.message) self.assertEqual(exc, deserialized) def suite(): suite = unittest.TestSuite() loader = unittest.TestLoader() suite.addTest(loader.loadTestsFromTestCase(TestImmutableExceptionDeserialization)) suite.addTest(loader.loadTestsFromTestCase(TestImmutableExceptionAccelerated)) return suite if __name__ == "__main__": unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2)) thrift-0.23.0/lib/py/test/thrift_json.py0000664000175000017500000001024515165535636020457 0ustar00buildbuild00000000000000# # 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 unittest import _import_local_thrift # noqa from thrift.protocol.TJSONProtocol import TJSONProtocol from thrift.transport import TTransport # # In order to run the test under Windows. We need to create symbolic link # name 'thrift' to '../src' folder by using: # # mklink /D thrift ..\src # class TestJSONString(unittest.TestCase): def test_escaped_unicode_string(self): unicode_json = b'"hello \\u0e01\\u0e02\\u0e03\\ud835\\udcab\\udb40\\udc70 unicode"' unicode_text = u'hello \u0e01\u0e02\u0e03\U0001D4AB\U000E0070 unicode' buf = TTransport.TMemoryBuffer(unicode_json) transport = TTransport.TBufferedTransportFactory().getTransport(buf) protocol = TJSONProtocol(transport) self.assertEqual(protocol.readString(), unicode_text) def test_TJSONProtocol_write(self): write_data = '{"software":"thrift","1":[23,1.2010000000000001,32767,2147483647,9223372036854775807],"base64":"aGVsbG8gdGhyaWZ0","bool":0}' buff = TTransport.TMemoryBuffer() transport = TTransport.TBufferedTransportFactory().getTransport(buff) protocol = TJSONProtocol(transport) protocol.writeJSONObjectStart() protocol.writeJSONString("software") protocol.writeJSONString("thrift") protocol.writeJSONString("1") protocol.writeJSONArrayStart() protocol.writeJSONNumber(23) protocol.writeDouble(1.201) protocol.writeI16(32767) protocol.writeI32(2147483647) protocol.writeI64(9223372036854775807) protocol.writeJSONArrayEnd() protocol.writeJSONString("base64") protocol.writeJSONBase64("hello thrift".encode('utf-8')) protocol.writeJSONString("bool") protocol.writeBool(0) protocol.writeJSONObjectEnd() transport.flush() value = buff.getvalue() self.assertEqual(write_data, value.decode('utf-8')) def test_TJSONProtol_read(self): expected = "{'software':'thrift','1':[23,1.2010000000000001,32767,2147483647,9223372036854775807],'base64':'hello thrift','bool':False}" read_data = '{"software":"thrift","1":[23,1.2010000000000001,32767,2147483647,9223372036854775807],"base64":"aGVsbG8gdGhyaWZ0","bool":0}' buff = TTransport.TMemoryBuffer(read_data.encode('utf-8')) transport = TTransport.TBufferedTransportFactory().getTransport(buff) protocol = TJSONProtocol(transport) protocol.readJSONObjectStart() u_1 = protocol.readString() u_2 = protocol.readString() u_3 = protocol.readString() protocol.readJSONArrayStart() u_4 = protocol.readNumber() u_5 = protocol.readDouble() u_6 = protocol.readI16() u_7 = protocol.readI32() u_8 = protocol.readI64() protocol.readJSONArrayEnd() u_9 = protocol.readString() u_10 = protocol.readJSONBase64() u_11 = protocol.readString() u_12 = protocol.readBool() protocol.writeJSONObjectEnd() result_read = {} result_read[u_1] = u_2 result_read[u_3] = [] result_read[u_3].append(u_4) result_read[u_3].append(u_5) result_read[u_3].append(u_6) result_read[u_3].append(u_7) result_read[u_3].append(u_8) result_read[u_9] = u_10.decode('utf-8') result_read[u_11] = u_12 self.assertEqual(eval(expected), result_read) if __name__ == '__main__': unittest.main() thrift-0.23.0/lib/py/coding_standards.md0000664000175000017500000000043115165535636020421 0ustar00buildbuild00000000000000## Python Coding Standards Please follow: * [Thrift General Coding Standards](/doc/coding_standards.md) * Code Style for Python Code [PEP8](http://legacy.python.org/dev/peps/pep-0008/) When in doubt - check with or online with . thrift-0.23.0/lib/py/compat/0000775000175000017500000000000015165535636016056 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/compat/win32/0000775000175000017500000000000015165535636017020 5ustar00buildbuild00000000000000thrift-0.23.0/lib/py/compat/win32/stdint.h0000664000175000017500000001706015165535636020502 0ustar00buildbuild00000000000000// ISO C9x compliant stdint.h for Microsoft Visual Studio // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 // // Copyright (c) 2006-2008 Alexander Chemeris // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The name of the author may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// #ifndef _MSC_VER // [ #error "Use this header only with Microsoft Visual C++ compilers!" #endif // _MSC_VER ] #ifndef _MSC_STDINT_H_ // [ #define _MSC_STDINT_H_ #if _MSC_VER > 1000 #pragma once #endif #include // For Visual Studio 6 in C++ mode and for many Visual Studio versions when // compiling for ARM we should wrap include with 'extern "C++" {}' // or compiler give many errors like this: // error C2733: second C linkage of overloaded function 'wmemchr' not allowed #ifdef __cplusplus extern "C" { #endif # include #ifdef __cplusplus } #endif // Define _W64 macros to mark types changing their size, like intptr_t. #ifndef _W64 # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 # define _W64 __w64 # else # define _W64 # endif #endif // 7.18.1 Integer types // 7.18.1.1 Exact-width integer types // Visual Studio 6 and Embedded Visual C++ 4 doesn't // realize that, e.g. char has the same size as __int8 // so we give up on __intX for them. #if (_MSC_VER < 1300) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #else typedef signed __int8 int8_t; typedef signed __int16 int16_t; typedef signed __int32 int32_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; #endif typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; // 7.18.1.2 Minimum-width integer types typedef int8_t int_least8_t; typedef int16_t int_least16_t; typedef int32_t int_least32_t; typedef int64_t int_least64_t; typedef uint8_t uint_least8_t; typedef uint16_t uint_least16_t; typedef uint32_t uint_least32_t; typedef uint64_t uint_least64_t; // 7.18.1.3 Fastest minimum-width integer types typedef int8_t int_fast8_t; typedef int16_t int_fast16_t; typedef int32_t int_fast32_t; typedef int64_t int_fast64_t; typedef uint8_t uint_fast8_t; typedef uint16_t uint_fast16_t; typedef uint32_t uint_fast32_t; typedef uint64_t uint_fast64_t; // 7.18.1.4 Integer types capable of holding object pointers #ifdef _WIN64 // [ typedef signed __int64 intptr_t; typedef unsigned __int64 uintptr_t; #else // _WIN64 ][ typedef _W64 signed int intptr_t; typedef _W64 unsigned int uintptr_t; #endif // _WIN64 ] // 7.18.1.5 Greatest-width integer types typedef int64_t intmax_t; typedef uint64_t uintmax_t; // 7.18.2 Limits of specified-width integer types #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 // 7.18.2.1 Limits of exact-width integer types #define INT8_MIN ((int8_t)_I8_MIN) #define INT8_MAX _I8_MAX #define INT16_MIN ((int16_t)_I16_MIN) #define INT16_MAX _I16_MAX #define INT32_MIN ((int32_t)_I32_MIN) #define INT32_MAX _I32_MAX #define INT64_MIN ((int64_t)_I64_MIN) #define INT64_MAX _I64_MAX #define UINT8_MAX _UI8_MAX #define UINT16_MAX _UI16_MAX #define UINT32_MAX _UI32_MAX #define UINT64_MAX _UI64_MAX // 7.18.2.2 Limits of minimum-width integer types #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST8_MAX INT8_MAX #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST16_MAX INT16_MAX #define INT_LEAST32_MIN INT32_MIN #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST64_MIN INT64_MIN #define INT_LEAST64_MAX INT64_MAX #define UINT_LEAST8_MAX UINT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define UINT_LEAST64_MAX UINT64_MAX // 7.18.2.3 Limits of fastest minimum-width integer types #define INT_FAST8_MIN INT8_MIN #define INT_FAST8_MAX INT8_MAX #define INT_FAST16_MIN INT16_MIN #define INT_FAST16_MAX INT16_MAX #define INT_FAST32_MIN INT32_MIN #define INT_FAST32_MAX INT32_MAX #define INT_FAST64_MIN INT64_MIN #define INT_FAST64_MAX INT64_MAX #define UINT_FAST8_MAX UINT8_MAX #define UINT_FAST16_MAX UINT16_MAX #define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST64_MAX UINT64_MAX // 7.18.2.4 Limits of integer types capable of holding object pointers #ifdef _WIN64 // [ # define INTPTR_MIN INT64_MIN # define INTPTR_MAX INT64_MAX # define UINTPTR_MAX UINT64_MAX #else // _WIN64 ][ # define INTPTR_MIN INT32_MIN # define INTPTR_MAX INT32_MAX # define UINTPTR_MAX UINT32_MAX #endif // _WIN64 ] // 7.18.2.5 Limits of greatest-width integer types #define INTMAX_MIN INT64_MIN #define INTMAX_MAX INT64_MAX #define UINTMAX_MAX UINT64_MAX // 7.18.3 Limits of other integer types #ifdef _WIN64 // [ # define PTRDIFF_MIN _I64_MIN # define PTRDIFF_MAX _I64_MAX #else // _WIN64 ][ # define PTRDIFF_MIN _I32_MIN # define PTRDIFF_MAX _I32_MAX #endif // _WIN64 ] #define SIG_ATOMIC_MIN INT_MIN #define SIG_ATOMIC_MAX INT_MAX #ifndef SIZE_MAX // [ # ifdef _WIN64 // [ # define SIZE_MAX _UI64_MAX # else // _WIN64 ][ # define SIZE_MAX _UI32_MAX # endif // _WIN64 ] #endif // SIZE_MAX ] // WCHAR_MIN and WCHAR_MAX are also defined in #ifndef WCHAR_MIN // [ # define WCHAR_MIN 0 #endif // WCHAR_MIN ] #ifndef WCHAR_MAX // [ # define WCHAR_MAX _UI16_MAX #endif // WCHAR_MAX ] #define WINT_MIN 0 #define WINT_MAX _UI16_MAX #endif // __STDC_LIMIT_MACROS ] // 7.18.4 Limits of other integer types #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 // 7.18.4.1 Macros for minimum-width integer constants #define INT8_C(val) val##i8 #define INT16_C(val) val##i16 #define INT32_C(val) val##i32 #define INT64_C(val) val##i64 #define UINT8_C(val) val##ui8 #define UINT16_C(val) val##ui16 #define UINT32_C(val) val##ui32 #define UINT64_C(val) val##ui64 // 7.18.4.2 Macros for greatest-width integer constants #define INTMAX_C INT64_C #define UINTMAX_C UINT64_C #endif // __STDC_CONSTANT_MACROS ] #endif // _MSC_STDINT_H_ ] thrift-0.23.0/lib/py/CMakeLists.txt0000664000175000017500000000413315167543515017331 0ustar00buildbuild00000000000000# # 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_directories(${Python3_INCLUDE_DIRS}) add_custom_target(python_build ALL COMMAND ${THRIFT_COMPILER} --gen py test/test_thrift_file/TestServer.thrift COMMAND Python3::Interpreter setup.py build WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Building Python library" ) if(BUILD_TESTING) add_test(NAME PythonTestSSLSocket COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/test_sslsocket.py) add_test(NAME PythonThriftJson COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/thrift_json.py) add_test(NAME PythonThriftTransport COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/thrift_transport.py) add_test(NAME PythonThriftTBinaryProtocol COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/thrift_TBinaryProtocol.py) add_test(NAME PythonThriftTZlibTransport COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/thrift_TZlibTransport.py) add_test(NAME PythonThriftProtocol COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/thrift_TCompactProtocol.py) add_test(NAME PythonThriftTNonblockingServer COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/thrift_TNonblockingServer.py) add_test(NAME PythonImmutableException COMMAND Python3::Interpreter ${CMAKE_CURRENT_SOURCE_DIR}/test/test_immutable_exception.py) endif() thrift-0.23.0/lib/py/README.md0000664000175000017500000000271215165535636016054 0ustar00buildbuild00000000000000Thrift Python Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Thrift with Python ======================== Thrift is provided as a set of Python packages. The top level package is thrift, and there are subpackages for the protocol, transport, and server code. Each package contains modules using standard Thrift naming conventions (i.e. TProtocol, TTransport) and implementations in corresponding modules (i.e. TSocket). There is also a subpackage reflection, which contains the generated code for the reflection structures. The Python libraries can be installed manually using the provided setup.py file, or automatically using the install hook provided via autoconf/automake. To use the latter, become superuser and do make install. thrift-0.23.0/lib/py/Makefile.in0000644000175000017500000004704315170007167016633 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/py ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # 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. # AUTOMAKE_OPTIONS = serial-tests EXTRA_DIST = \ CMakeLists.txt \ MANIFEST.in \ coding_standards.md \ compat \ setup.py \ setup.cfg \ pyproject.toml \ src \ test \ README.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/py/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/py/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-exec-am install-strip .PHONY: all all-am all-local check check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ dist-hook distclean distclean-generic distclean-libtool \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-exec-hook \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile DESTDIR ?= / @WITH_PY3_TRUE@py3-build: @WITH_PY3_TRUE@ $(PYTHON3) setup.py build @WITH_PY3_TRUE@py3-test: py3-build @WITH_PY3_TRUE@ $(PYTHON3) test/thrift_json.py @WITH_PY3_TRUE@ $(PYTHON3) test/thrift_transport.py @WITH_PY3_TRUE@ $(PYTHON3) test/test_sslsocket.py @WITH_PY3_TRUE@ $(PYTHON3) test/thrift_TBinaryProtocol.py @WITH_PY3_TRUE@ $(PYTHON3) test/thrift_TZlibTransport.py @WITH_PY3_TRUE@ $(PYTHON3) test/thrift_TCompactProtocol.py @WITH_PY3_TRUE@ $(PYTHON3) test/thrift_TNonblockingServer.py @WITH_PY3_TRUE@ $(PYTHON3) test/thrift_TSerializer.py @WITH_PY3_FALSE@py3-build: @WITH_PY3_FALSE@py3-test: all-local: py3-build $(PYTHON) setup.py build ${THRIFT} --gen py test/test_thrift_file/TestServer.thrift ${THRIFT} --gen py ../../test/v0.16/FuzzTestNoUuid.thrift # We're ignoring prefix here because site-packages seems to be # the equivalent of /usr/local/lib in Python land. # 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) -m pip install . --root=$(DESTDIR) --prefix=$(PY_PREFIX) $(PYTHON_SETUPUTIL_ARGS) check-local: all py3-test $(PYTHON) test/thrift_json.py $(PYTHON) test/thrift_transport.py $(PYTHON) test/test_sslsocket.py $(PYTHON) test/test_socket.py $(PYTHON) test/thrift_TBinaryProtocol.py $(PYTHON) test/thrift_TZlibTransport.py $(PYTHON) test/thrift_TCompactProtocol.py $(PYTHON) test/thrift_TNonblockingServer.py $(PYTHON) test/thrift_TSerializer.py $(PYTHON) test/test_compiler/test_keyword_escape.py clean-local: $(RM) -r build $(RM) -r gen-py find . -type f \( -iname "*.pyc" \) | xargs rm -f find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf dist-hook: find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/py/pyproject.toml0000664000175000017500000000014015167543515017477 0ustar00buildbuild00000000000000[build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta" thrift-0.23.0/lib/py/setup.py0000664000175000017500000001174115170007142016267 0ustar00buildbuild00000000000000#!/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. # import sys from setuptools import Extension, setup from setuptools.command.build_ext import build_ext from setuptools.errors import CompileError, ExecError, PlatformError # Fix to build sdist under vagrant import os if 'vagrant' in str(os.environ): try: del os.link except AttributeError: pass include_dirs = ['src'] if sys.platform == 'win32': include_dirs.append('compat/win32') ext_errors = (CompileError, ExecError, PlatformError, IOError) else: ext_errors = (CompileError, ExecError, PlatformError) class BuildFailed(Exception): pass class ve_build_ext(build_ext): def run(self): try: build_ext.run(self) except PlatformError: raise BuildFailed() def build_extension(self, ext): try: build_ext.build_extension(self, ext) except ext_errors: raise BuildFailed() def read_file(path): """ Return the contents of a file Arguments: - path: path to the file Returns: - contents of the file """ with open(path, "r") as desc_file: return desc_file.read().rstrip() def run_setup(with_binary): if with_binary: extensions = dict( ext_modules=[ Extension('thrift.protocol.fastbinary', extra_compile_args=['-std=c++11'], sources=[ 'src/ext/module.cpp', 'src/ext/types.cpp', 'src/ext/binary.cpp', 'src/ext/compact.cpp', ], depends=[ 'src/ext/binary.h', 'src/ext/compact.h', 'src/ext/endian.h', 'src/ext/protocol.h', 'src/ext/protocol.tcc', 'src/ext/types.h', ], include_dirs=include_dirs, ) ], cmdclass=dict(build_ext=ve_build_ext) ) else: extensions = dict() ssl_deps = [] if sys.hexversion < 0x03050000: ssl_deps.append('backports.ssl_match_hostname>=3.5') tornado_deps = ['tornado>=6.3.0'] twisted_deps = ['twisted>=24.3.0', 'zope.interface>=6.1'] setup(name='thrift', version='0.23.0', description='Python bindings for the Apache Thrift RPC system', long_description=read_file("README.md"), long_description_content_type="text/markdown", author='Apache Thrift Developers', author_email='dev@thrift.apache.org', url='http://thrift.apache.org', license='Apache License 2.0', extras_require={ 'ssl': ssl_deps, 'tornado': tornado_deps, 'twisted': twisted_deps, 'all': ssl_deps + tornado_deps + twisted_deps, }, packages=[ 'thrift', 'thrift.protocol', 'thrift.transport', 'thrift.server', ], package_dir={'thrift': 'src'}, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Topic :: Software Development :: Libraries', 'Topic :: System :: Networking' ], zip_safe=False, **extensions ) try: with_binary = True run_setup(with_binary) sys.exit(0) except BuildFailed: print() print('*' * 80) print("An error occurred while trying to compile with the C extension enabled") print("Attempting to build without the extension now") print('*' * 80) print() # Retry but without the binary try: run_setup(False) sys.exit(0) except BuildFailed: print() print('*' * 80) print("An error occurred while trying to compile without the C extension enabled") print("Build failed") print('*' * 80) print() sys.exit(1) thrift-0.23.0/lib/py/Makefile.am0000664000175000017500000000531015170007142016604 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = serial-tests DESTDIR ?= / if WITH_PY3 py3-build: $(PYTHON3) setup.py build py3-test: py3-build $(PYTHON3) test/thrift_json.py $(PYTHON3) test/thrift_transport.py $(PYTHON3) test/test_sslsocket.py $(PYTHON3) test/thrift_TBinaryProtocol.py $(PYTHON3) test/thrift_TZlibTransport.py $(PYTHON3) test/thrift_TCompactProtocol.py $(PYTHON3) test/thrift_TNonblockingServer.py $(PYTHON3) test/thrift_TSerializer.py else py3-build: py3-test: endif all-local: py3-build $(PYTHON) setup.py build ${THRIFT} --gen py test/test_thrift_file/TestServer.thrift ${THRIFT} --gen py ../../test/v0.16/FuzzTestNoUuid.thrift # We're ignoring prefix here because site-packages seems to be # the equivalent of /usr/local/lib in Python land. # 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) -m pip install . --root=$(DESTDIR) --prefix=$(PY_PREFIX) $(PYTHON_SETUPUTIL_ARGS) check-local: all py3-test $(PYTHON) test/thrift_json.py $(PYTHON) test/thrift_transport.py $(PYTHON) test/test_sslsocket.py $(PYTHON) test/test_socket.py $(PYTHON) test/thrift_TBinaryProtocol.py $(PYTHON) test/thrift_TZlibTransport.py $(PYTHON) test/thrift_TCompactProtocol.py $(PYTHON) test/thrift_TNonblockingServer.py $(PYTHON) test/thrift_TSerializer.py $(PYTHON) test/test_compiler/test_keyword_escape.py clean-local: $(RM) -r build $(RM) -r gen-py find . -type f \( -iname "*.pyc" \) | xargs rm -f find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf dist-hook: find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ CMakeLists.txt \ MANIFEST.in \ coding_standards.md \ compat \ setup.py \ setup.cfg \ pyproject.toml \ src \ test \ README.md thrift-0.23.0/lib/delphi/0000775000175000017500000000000015165535636015410 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/src/0000775000175000017500000000000015170007142016155 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/src/Thrift.WinHTTP.pas0000664000175000017500000016572615165535636021421 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.WinHTTP; {$I Thrift.Defines.inc} {$SCOPEDENUMS ON} // packing according to winhttp.h {$IFDEF Win64} {$ALIGN 8} {$ELSE} {$ALIGN 4} {$ENDIF} interface uses Windows, Classes, SysUtils, Math, Generics.Collections; type HINTERNET = type Pointer; INTERNET_PORT = type WORD; INTERNET_SCHEME = type Integer; LPLPCWSTR = ^LPCWSTR; LPURL_COMPONENTS = ^URL_COMPONENTS; URL_COMPONENTS = record dwStructSize : DWORD; // set to SizeOf(URL_COMPONENTS) lpszScheme : LPWSTR; // scheme name dwSchemeLength : DWORD; nScheme : INTERNET_SCHEME; // enumerated scheme type lpszHostName : LPWSTR; // host name dwHostNameLength : DWORD; nPort : INTERNET_PORT; // port number lpszUserName : LPWSTR; // user name dwUserNameLength : DWORD; lpszPassword : LPWSTR; // password dwPasswordLength : DWORD; lpszUrlPath : LPWSTR; // URL-path dwUrlPathLength : DWORD; lpszExtraInfo : LPWSTR; // extra information dwExtraInfoLength : DWORD; end; URL_COMPONENTSW = URL_COMPONENTS; LPURL_COMPONENTSW = LPURL_COMPONENTS; // When retrieving proxy data, an application must free the lpszProxy and // lpszProxyBypass strings contained in this structure (if they are non-NULL) // using the GlobalFree function. LPWINHTTP_PROXY_INFO = ^WINHTTP_PROXY_INFO; WINHTTP_PROXY_INFO = record dwAccessType : DWORD; // see WINHTTP_ACCESS_* types below lpszProxy : LPWSTR; // proxy server list lpszProxyBypass : LPWSTR; // proxy bypass list end; LPWINHTTP_PROXY_INFOW = ^WINHTTP_PROXY_INFOW; WINHTTP_PROXY_INFOW = WINHTTP_PROXY_INFO; WINHTTP_AUTOPROXY_OPTIONS = record dwFlags : DWORD; dwAutoDetectFlags : DWORD; lpszAutoConfigUrl : LPCWSTR; lpvReserved : LPVOID; dwReserved : DWORD; fAutoLogonIfChallenged : BOOL; end; WINHTTP_CURRENT_USER_IE_PROXY_CONFIG = record fAutoDetect : BOOL; lpszAutoConfigUrl : LPWSTR; lpszProxy : LPWSTR; lpszProxyBypass : LPWSTR; end; function WinHttpCloseHandle( aHandle : HINTERNET) : BOOL; stdcall; function WinHttpOpen( const pszAgentW : LPCWSTR; const dwAccessType : DWORD; const pszProxyW : LPCWSTR; const pszProxyBypassW : LPCWSTR; const dwFlags : DWORD ) : HINTERNET; stdcall; function WinHttpConnect( const hSession : HINTERNET; const pswzServerName : LPCWSTR; const nServerPort : INTERNET_PORT; const dwReserved : DWORD ) : HINTERNET; stdcall; function WinHttpOpenRequest( const hConnect : HINTERNET; const pwszVerb, pwszObjectName, pwszVersion, pwszReferrer : LPCWSTR; const ppwszAcceptTypes : LPLPCWSTR; const dwFlags : DWORD ) : HINTERNET; stdcall; function WinHttpQueryOption( const hInternet : HINTERNET; const dwOption : DWORD; const pBuffer : Pointer; var dwBufferLength : DWORD) : BOOL; stdcall; function WinHttpSetOption( const hInternet : HINTERNET; const dwOption : DWORD; const pBuffer : Pointer; const dwBufferLength : DWORD) : BOOL; stdcall; function WinHttpSetTimeouts( const hRequestOrSession : HINTERNET; const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32 ) : BOOL; stdcall; function WinHttpAddRequestHeaders( const hRequest : HINTERNET; const pwszHeaders : LPCWSTR; const dwHeadersLengthInChars : DWORD; const dwModifiers : DWORD ) : BOOL; stdcall; function WinHttpGetProxyForUrl( const hSession : HINTERNET; const lpcwszUrl : LPCWSTR; const options : WINHTTP_AUTOPROXY_OPTIONS; const info : WINHTTP_PROXY_INFO ) : BOOL; stdcall; function WinHttpGetIEProxyConfigForCurrentUser( var config : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ) : BOOL; stdcall; function WinHttpSendRequest( const hRequest : HINTERNET; const lpszHeaders : LPCWSTR; const dwHeadersLength : DWORD; const lpOptional : Pointer; const dwOptionalLength : DWORD; const dwTotalLength : DWORD; const pContext : Pointer ) : BOOL; stdcall; function WinHttpWriteData( const hRequest : HINTERNET; const pBuf : Pointer; const dwBytesToWrite : DWORD; out dwBytesWritten : DWORD ) : BOOL; stdcall; function WinHttpReceiveResponse( const hRequest : HINTERNET; const lpReserved : Pointer) : BOOL; stdcall; function WinHttpQueryHeaders( const hRequest : HINTERNET; const dwInfoLevel : DWORD; const pwszName : LPCWSTR; const lpBuffer : Pointer; var dwBufferLength : DWORD; var dwIndex : DWORD ) : BOOL; stdcall; function WinHttpQueryDataAvailable( const hRequest : HINTERNET; var dwNumberOfBytesAvailable : DWORD ) : BOOL; stdcall; function WinHttpReadData( const hRequest : HINTERNET; const lpBuffer : Pointer; const dwBytesToRead : DWORD; out dwBytesRead : DWORD ) : BOOL; stdcall; function WinHttpCrackUrl( const pwszUrl : LPCWSTR; const dwUrlLength : DWORD; const dwFlags : DWORD; var urlComponents : URL_COMPONENTS ) : BOOL; stdcall; function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; const dwFlags : DWORD; const pwszUrl : LPCWSTR; var pdwUrlLength : DWORD ) : BOOL; stdcall; const // ports INTERNET_DEFAULT_PORT = 0; // use the protocol-specific default (80 or 443) INTERNET_DEFAULT_HTTP_PORT = 80; INTERNET_DEFAULT_HTTPS_PORT = 443; // flags for WinHttpOpenRequest(): WINHTTP_FLAG_SECURE = $00800000; // use SSL if applicable (HTTPS) WINHTTP_FLAG_ESCAPE_PERCENT = $00000004; // if escaping enabled, escape percent as well WINHTTP_FLAG_NULL_CODEPAGE = $00000008; // assume all symbols are ASCII, use fast convertion WINHTTP_FLAG_ESCAPE_DISABLE = $00000040; // disable escaping WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = $00000080; // if escaping enabled escape path part, but do not escape query WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add "pragma: no-cache" request header WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE; // flags for WinHttpOpen(): WINHTTP_FLAG_ASYNC = $10000000; // want async session, requires WinHttpSetStatusCallback() usage // flags for WinHttpSendRequest(): WINHTTP_NO_PROXY_NAME = nil; WINHTTP_NO_PROXY_BYPASS = nil; WINHTTP_NO_CLIENT_CERT_CONTEXT = nil; WINHTTP_NO_REFERER = nil; WINHTTP_DEFAULT_ACCEPT_TYPES = nil; WINHTTP_NO_ADDITIONAL_HEADERS = nil; WINHTTP_NO_REQUEST_DATA = nil; WINHTTP_HEADER_NAME_BY_INDEX = nil; WINHTTP_NO_OUTPUT_BUFFER = nil; WINHTTP_NO_HEADER_INDEX = nil; // WinHttpAddRequestHeaders() dwModifiers WINHTTP_ADDREQ_INDEX_MASK = $0000FFFF; WINHTTP_ADDREQ_FLAGS_MASK = $FFFF0000; WINHTTP_ADDREQ_FLAG_ADD_IF_NEW = $10000000; WINHTTP_ADDREQ_FLAG_ADD = $20000000; WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = $40000000; WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = $01000000; WINHTTP_ADDREQ_FLAG_COALESCE = WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA; WINHTTP_ADDREQ_FLAG_REPLACE = $80000000; // URL functions ICU_NO_ENCODE = $20000000; // Don't convert unsafe characters to escape sequence ICU_DECODE = $10000000; // Convert %XX escape sequences to characters ICU_NO_META = $08000000; // Don't convert .. etc. meta path sequences ICU_ENCODE_SPACES_ONLY = $04000000; // Encode spaces only ICU_BROWSER_MODE = $02000000; // Special encode/decode rules for browser ICU_ENCODE_PERCENT = $00001000; // Encode any percent (ASCII25) ICU_ESCAPE = $80000000; // (un)escape URL characters ICU_ESCAPE_AUTHORITY = $00002000; // causes InternetCreateUrlA to escape chars in authority components (user, pwd, host) ICU_REJECT_USERPWD = $00004000; // rejects urls with username/pwd sections INTERNET_SCHEME_HTTP = INTERNET_SCHEME(1); INTERNET_SCHEME_HTTPS = INTERNET_SCHEME(2); INTERNET_SCHEME_FTP = INTERNET_SCHEME(3); INTERNET_SCHEME_SOCKS = INTERNET_SCHEME(4); // options manifests for WinHttp{Query|Set}Option WINHTTP_OPTION_CALLBACK = 1; WINHTTP_OPTION_RESOLVE_TIMEOUT = 2; WINHTTP_OPTION_CONNECT_TIMEOUT = 3; WINHTTP_OPTION_CONNECT_RETRIES = 4; WINHTTP_OPTION_SEND_TIMEOUT = 5; WINHTTP_OPTION_RECEIVE_TIMEOUT = 6; WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT = 7; WINHTTP_OPTION_HANDLE_TYPE = 9; WINHTTP_OPTION_READ_BUFFER_SIZE = 12; WINHTTP_OPTION_WRITE_BUFFER_SIZE = 13; WINHTTP_OPTION_PARENT_HANDLE = 21; WINHTTP_OPTION_EXTENDED_ERROR = 24; WINHTTP_OPTION_SECURITY_FLAGS = 31; WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT = 32; WINHTTP_OPTION_URL = 34; WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36; WINHTTP_OPTION_PROXY = 38; WINHTTP_OPTION_PROXY_RESULT_ENTRY = 39; WINHTTP_OPTION_USER_AGENT = 41; WINHTTP_OPTION_CONTEXT_VALUE = 45; WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47; WINHTTP_OPTION_REQUEST_PRIORITY = 58; WINHTTP_OPTION_HTTP_VERSION = 59; WINHTTP_OPTION_DISABLE_FEATURE = 63; WINHTTP_OPTION_CODEPAGE = 68; WINHTTP_OPTION_MAX_CONNS_PER_SERVER = 73; WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER = 74; WINHTTP_OPTION_AUTOLOGON_POLICY = 77; WINHTTP_OPTION_SERVER_CERT_CONTEXT = 78; WINHTTP_OPTION_ENABLE_FEATURE = 79; WINHTTP_OPTION_WORKER_THREAD_COUNT = 80; WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT = 81; WINHTTP_OPTION_PASSPORT_COBRANDING_URL = 82; WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH = 83; WINHTTP_OPTION_SECURE_PROTOCOLS = 84; WINHTTP_OPTION_ENABLETRACING = 85; WINHTTP_OPTION_PASSPORT_SIGN_OUT = 86; WINHTTP_OPTION_PASSPORT_RETURN_URL = 87; WINHTTP_OPTION_REDIRECT_POLICY = 88; WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS = 89; WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE = 90; WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE = 91; WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE = 92; WINHTTP_OPTION_CONNECTION_INFO = 93; WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST = 94; WINHTTP_OPTION_SPN = 96; WINHTTP_OPTION_GLOBAL_PROXY_CREDS = 97; WINHTTP_OPTION_GLOBAL_SERVER_CREDS = 98; WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT = 99; WINHTTP_OPTION_REJECT_USERPWD_IN_URL = 100; WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS = 101; WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE = 103; WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE = 104; WINHTTP_OPTION_SERVER_SPN_USED = 106; WINHTTP_OPTION_PROXY_SPN_USED = 107; WINHTTP_OPTION_SERVER_CBT = 108; WINHTTP_OPTION_UNSAFE_HEADER_PARSING = 110; WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS = 111; WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114; WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT = 115; WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL = 116; WINHTTP_OPTION_DECOMPRESSION = 118; WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE = 122; WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE = 123; WINHTTP_OPTION_TCP_PRIORITY_HINT = 128; WINHTTP_OPTION_CONNECTION_FILTER = 131; WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL = 133; WINHTTP_OPTION_HTTP_PROTOCOL_USED = 134; WINHTTP_OPTION_KDC_PROXY_SETTINGS = 136; WINHTTP_OPTION_ENCODE_EXTRA = 138; WINHTTP_OPTION_DISABLE_STREAM_QUEUE = 139; WINHTTP_OPTION_IPV6_FAST_FALLBACK = 140; WINHTTP_OPTION_CONNECTION_STATS_V0 = 141; WINHTTP_OPTION_REQUEST_TIMES = 142; WINHTTP_OPTION_EXPIRE_CONNECTION = 143; WINHTTP_OPTION_DISABLE_SECURE_PROTOCOL_FALLBACK = 144; WINHTTP_OPTION_HTTP_PROTOCOL_REQUIRED = 145; WINHTTP_OPTION_REQUEST_STATS = 146; WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT = 147; WINHTTP_OPTION_CONNECTION_STATS_V1 = 150; WINHTTP_OPTION_SECURITY_INFO = 151; WINHTTP_OPTION_TCP_KEEPALIVE = 152; WINHTTP_OPTION_TCP_FAST_OPEN = 153; WINHTTP_OPTION_TCP_FALSE_START = 154; WINHTTP_OPTION_IGNORE_CERT_REVOCATION_OFFLINE = 155; WINHTTP_OPTION_TLS_PROTOCOL_INSECURE_FALLBACK = 158; WINHTTP_OPTION_STREAM_ERROR_CODE = 159; WINHTTP_OPTION_REQUIRE_STREAM_END = 160; WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT = 161; WINHTTP_OPTION_FAILED_CONNECTION_RETRIES = 162; WINHTTP_OPTION_HTTP2_KEEPALIVE = 164; WINHTTP_OPTION_RESOLUTION_HOSTNAME = 165; WINHTTP_OPTION_SET_TOKEN_BINDING = 166; WINHTTP_OPTION_TOKEN_BINDING_PUBLIC_KEY = 167; WINHTTP_OPTION_REFERER_TOKEN_BINDING_HOSTNAME = 168; WINHTTP_OPTION_HTTP2_PLUS_TRANSFER_ENCODING = 169; WINHTTP_OPTION_RESOLVER_CACHE_CONFIG = 170; WINHTTP_OPTION_DISABLE_CERT_CHAIN_BUILDING = 171; WINHTTP_OPTION_BACKGROUND_CONNECTIONS = 172; WINHTTP_OPTION_FIRST_AVAILABLE_CONNECTION = 173; WINHTTP_OPTION_TCP_PRIORITY_STATUS = 177; WINHTTP_OPTION_CONNECTION_GUID = 178; WINHTTP_OPTION_MATCH_CONNECTION_GUID = 179; WINHTTP_OPTION_HTTP2_RECEIVE_WINDOW = 183; WINHTTP_OPTION_FEATURE_SUPPORTED = 184; WINHTTP_OPTION_QUIC_STATS = 185; WINHTTP_OPTION_HTTP3_KEEPALIVE = 188; WINHTTP_OPTION_HTTP3_HANDSHAKE_TIMEOUT = 189; WINHTTP_OPTION_HTTP3_INITIAL_RTT = 190; WINHTTP_OPTION_HTTP3_STREAM_ERROR_CODE = 191; WINHTTP_OPTION_REQUEST_ANNOTATION = 192; WINHTTP_OPTION_DISABLE_PROXY_AUTH_SCHEMES = 193; WINHTTP_OPTION_REVERT_IMPERSONATION_SERVER_CERT = 194; WINHTTP_OPTION_DISABLE_GLOBAL_POOLING = 195; WINHTTP_OPTION_USE_SESSION_SCH_CRED = 196; WINHTTP_OPTION_QUIC_STATS_V2 = 200; WINHTTP_OPTION_QUIC_STREAM_STATS = 202; WINHTTP_OPTION_USE_LOOKASIDE = 203; WINHTTP_OPTION_ERROR_LOG_GUID = 204; WINHTTP_OPTION_ENABLE_FAST_FORWARDING = 205; WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_DATA = 206; WINHTTP_OPTION_UPGRADE_TO_PROTOCOL = 207; WINHTTP_OPTION_CONNECTION_STATS_V2 = 208; WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS = 209; WINHTTP_FIRST_OPTION = WINHTTP_OPTION_CALLBACK; //WINHTTP_LAST_OPTION = WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS; WINHTTP_OPTION_USERNAME = $1000; WINHTTP_OPTION_PASSWORD = $1001; WINHTTP_OPTION_PROXY_USERNAME = $1002; WINHTTP_OPTION_PROXY_PASSWORD = $1003; // manifest value for WINHTTP_OPTION_MAX_CONNS_PER_SERVER and WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER WINHTTP_CONNS_PER_SERVER_UNLIMITED = $FFFFFFFF; // values for WINHTTP_OPTION_AUTOLOGON_POLICY WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM = 0; WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW = 1; WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH = 2; WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM; // values for WINHTTP_OPTION_REDIRECT_POLICY WINHTTP_OPTION_REDIRECT_POLICY_NEVER = 0; WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP = 1; WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS = 2; WINHTTP_OPTION_REDIRECT_POLICY_LAST = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP; WINHTTP_DISABLE_PASSPORT_AUTH = $00000000; WINHTTP_ENABLE_PASSPORT_AUTH = $10000000; WINHTTP_DISABLE_PASSPORT_KEYRING = $20000000; WINHTTP_ENABLE_PASSPORT_KEYRING = $40000000; // values for WINHTTP_OPTION_DISABLE_FEATURE WINHTTP_DISABLE_COOKIES = $00000001; WINHTTP_DISABLE_REDIRECTS = $00000002; WINHTTP_DISABLE_AUTHENTICATION = $00000004; WINHTTP_DISABLE_KEEP_ALIVE = $00000008; // values for WINHTTP_OPTION_ENABLE_FEATURE WINHTTP_ENABLE_SSL_REVOCATION = $00000001; WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION = $00000002; // values for WINHTTP_OPTION_SPN WINHTTP_DISABLE_SPN_SERVER_PORT = $00000000; WINHTTP_ENABLE_SPN_SERVER_PORT = $00000001; WINHTTP_OPTION_SPN_MASK = WINHTTP_ENABLE_SPN_SERVER_PORT; // winhttp handle types WINHTTP_HANDLE_TYPE_SESSION = 1; WINHTTP_HANDLE_TYPE_CONNECT = 2; WINHTTP_HANDLE_TYPE_REQUEST = 3; // values for auth schemes WINHTTP_AUTH_SCHEME_BASIC = $00000001; WINHTTP_AUTH_SCHEME_NTLM = $00000002; WINHTTP_AUTH_SCHEME_PASSPORT = $00000004; WINHTTP_AUTH_SCHEME_DIGEST = $00000008; WINHTTP_AUTH_SCHEME_NEGOTIATE = $00000010; // WinHttp supported Authentication Targets WINHTTP_AUTH_TARGET_SERVER = $00000000; WINHTTP_AUTH_TARGET_PROXY = $00000001; // options for WINHTTP_OPTION_DECOMPRESSION WINHTTP_DECOMPRESSION_FLAG_GZIP = $00000001; WINHTTP_DECOMPRESSION_FLAG_DEFLATE = $00000002; WINHTTP_DECOMPRESSION_FLAG_ALL = WINHTTP_DECOMPRESSION_FLAG_GZIP or WINHTTP_DECOMPRESSION_FLAG_DEFLATE; // WinHttpOpen dwAccessType values WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0; WINHTTP_ACCESS_TYPE_NO_PROXY = 1; WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3; WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4; WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH = 0; // values for WINHTTP_OPTION_SECURITY_FLAGS // query only SECURITY_FLAG_SECURE = $00000001; // can query only SECURITY_FLAG_STRENGTH_WEAK = $10000000; SECURITY_FLAG_STRENGTH_MEDIUM = $40000000; SECURITY_FLAG_STRENGTH_STRONG = $20000000; // query flags WINHTTP_QUERY_MIME_VERSION = 0; WINHTTP_QUERY_CONTENT_TYPE = 1; WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING = 2; WINHTTP_QUERY_CONTENT_ID = 3; WINHTTP_QUERY_CONTENT_DESCRIPTION = 4; WINHTTP_QUERY_CONTENT_LENGTH = 5; WINHTTP_QUERY_CONTENT_LANGUAGE = 6; WINHTTP_QUERY_ALLOW = 7; WINHTTP_QUERY_PUBLIC = 8; WINHTTP_QUERY_DATE = 9; WINHTTP_QUERY_EXPIRES = 10; WINHTTP_QUERY_LAST_MODIFIED = 11; WINHTTP_QUERY_MESSAGE_ID = 12; WINHTTP_QUERY_URI = 13; WINHTTP_QUERY_DERIVED_FROM = 14; WINHTTP_QUERY_COST = 15; WINHTTP_QUERY_LINK = 16; WINHTTP_QUERY_PRAGMA = 17; WINHTTP_QUERY_VERSION = 18; WINHTTP_QUERY_STATUS_CODE = 19; WINHTTP_QUERY_STATUS_TEXT = 20; WINHTTP_QUERY_RAW_HEADERS = 21; WINHTTP_QUERY_RAW_HEADERS_CRLF = 22; WINHTTP_QUERY_CONNECTION = 23; WINHTTP_QUERY_ACCEPT = 24; WINHTTP_QUERY_ACCEPT_CHARSET = 25; WINHTTP_QUERY_ACCEPT_ENCODING = 26; WINHTTP_QUERY_ACCEPT_LANGUAGE = 27; WINHTTP_QUERY_AUTHORIZATION = 28; WINHTTP_QUERY_CONTENT_ENCODING = 29; WINHTTP_QUERY_FORWARDED = 30; WINHTTP_QUERY_FROM = 31; WINHTTP_QUERY_IF_MODIFIED_SINCE = 32; WINHTTP_QUERY_LOCATION = 33; WINHTTP_QUERY_ORIG_URI = 34; WINHTTP_QUERY_REFERER = 35; WINHTTP_QUERY_RETRY_AFTER = 36; WINHTTP_QUERY_SERVER = 37; WINHTTP_QUERY_TITLE = 38; WINHTTP_QUERY_USER_AGENT = 39; WINHTTP_QUERY_WWW_AUTHENTICATE = 40; WINHTTP_QUERY_PROXY_AUTHENTICATE = 41; WINHTTP_QUERY_ACCEPT_RANGES = 42; WINHTTP_QUERY_SET_COOKIE = 43; WINHTTP_QUERY_COOKIE = 44; WINHTTP_QUERY_REQUEST_METHOD = 45; WINHTTP_QUERY_REFRESH = 46; WINHTTP_QUERY_CONTENT_DISPOSITION = 47; WINHTTP_QUERY_AGE = 48; WINHTTP_QUERY_CACHE_CONTROL = 49; WINHTTP_QUERY_CONTENT_BASE = 50; WINHTTP_QUERY_CONTENT_LOCATION = 51; WINHTTP_QUERY_CONTENT_MD5 = 52; WINHTTP_QUERY_CONTENT_RANGE = 53; WINHTTP_QUERY_ETAG = 54; WINHTTP_QUERY_HOST = 55; WINHTTP_QUERY_IF_MATCH = 56; WINHTTP_QUERY_IF_NONE_MATCH = 57; WINHTTP_QUERY_IF_RANGE = 58; WINHTTP_QUERY_IF_UNMODIFIED_SINCE = 59; WINHTTP_QUERY_MAX_FORWARDS = 60; WINHTTP_QUERY_PROXY_AUTHORIZATION = 61; WINHTTP_QUERY_RANGE = 62; WINHTTP_QUERY_TRANSFER_ENCODING = 63; WINHTTP_QUERY_UPGRADE = 64; WINHTTP_QUERY_VARY = 65; WINHTTP_QUERY_VIA = 66; WINHTTP_QUERY_WARNING = 67; WINHTTP_QUERY_EXPECT = 68; WINHTTP_QUERY_PROXY_CONNECTION = 69; WINHTTP_QUERY_UNLESS_MODIFIED_SINCE = 70; WINHTTP_QUERY_PROXY_SUPPORT = 75; WINHTTP_QUERY_AUTHENTICATION_INFO = 76; WINHTTP_QUERY_PASSPORT_URLS = 77; WINHTTP_QUERY_PASSPORT_CONFIG = 78; WINHTTP_QUERY_MAX = 78; WINHTTP_QUERY_CUSTOM = 65535; WINHTTP_QUERY_FLAG_REQUEST_HEADERS = $80000000; WINHTTP_QUERY_FLAG_SYSTEMTIME = $40000000; WINHTTP_QUERY_FLAG_NUMBER = $20000000; WINHTTP_QUERY_FLAG_NUMBER64 = $08000000; // Secure connection error status flags WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED = $00000001; WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT = $00000002; WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED = $00000004; WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA = $00000008; WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID = $00000010; WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID = $00000020; WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE = $00000040; WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR = $80000000; WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 = $00000008; WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 = $00000020; WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 = $00000080; WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = $00000200; WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = $00000800; WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 = $00002000; // Note: SECURE_PROTOCOL_ALL does NOT include TLS1.1 and higher! WINHTTP_FLAG_SECURE_PROTOCOL_ALL = WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 or WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1; // AutoProxy WINHTTP_AUTOPROXY_AUTO_DETECT = $00000001; WINHTTP_AUTOPROXY_CONFIG_URL = $00000002; WINHTTP_AUTOPROXY_HOST_KEEPCASE = $00000004; WINHTTP_AUTOPROXY_HOST_LOWERCASE = $00000008; WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG = $00000100; WINHTTP_AUTOPROXY_ALLOW_STATIC = $00000200; WINHTTP_AUTOPROXY_ALLOW_CM = $00000400; WINHTTP_AUTOPROXY_RUN_INPROCESS = $00010000; WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = $00020000; WINHTTP_AUTOPROXY_NO_DIRECTACCESS = $00040000; WINHTTP_AUTOPROXY_NO_CACHE_CLIENT = $00080000; WINHTTP_AUTOPROXY_NO_CACHE_SVC = $00100000; WINHTTP_AUTOPROXY_SORT_RESULTS = $00400000; // Flags for dwAutoDetectFlags WINHTTP_AUTO_DETECT_TYPE_DHCP = $00000001; WINHTTP_AUTO_DETECT_TYPE_DNS_A = $00000002; const WINHTTP_ERROR_BASE = 12000; ERROR_WINHTTP_OUT_OF_HANDLES = WINHTTP_ERROR_BASE + 1; ERROR_WINHTTP_TIMEOUT = WINHTTP_ERROR_BASE + 2; ERROR_WINHTTP_INTERNAL_ERROR = WINHTTP_ERROR_BASE + 4; ERROR_WINHTTP_INVALID_URL = WINHTTP_ERROR_BASE + 5; ERROR_WINHTTP_UNRECOGNIZED_SCHEME = WINHTTP_ERROR_BASE + 6; ERROR_WINHTTP_NAME_NOT_RESOLVED = WINHTTP_ERROR_BASE + 7; ERROR_WINHTTP_INVALID_OPTION = WINHTTP_ERROR_BASE + 9; ERROR_WINHTTP_OPTION_NOT_SETTABLE = WINHTTP_ERROR_BASE + 11; ERROR_WINHTTP_SHUTDOWN = WINHTTP_ERROR_BASE + 12; ERROR_WINHTTP_LOGIN_FAILURE = WINHTTP_ERROR_BASE + 15; ERROR_WINHTTP_OPERATION_CANCELLED = WINHTTP_ERROR_BASE + 17; ERROR_WINHTTP_INCORRECT_HANDLE_TYPE = WINHTTP_ERROR_BASE + 18; ERROR_WINHTTP_INCORRECT_HANDLE_STATE = WINHTTP_ERROR_BASE + 19; ERROR_WINHTTP_CANNOT_CONNECT = WINHTTP_ERROR_BASE + 29; ERROR_WINHTTP_CONNECTION_ERROR = WINHTTP_ERROR_BASE + 30; ERROR_WINHTTP_RESEND_REQUEST = WINHTTP_ERROR_BASE + 32; //ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37; - see below //ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38; - see below ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = WINHTTP_ERROR_BASE + 44; //ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45; - see below //ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57; - see below ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = WINHTTP_ERROR_BASE + 100; ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = WINHTTP_ERROR_BASE + 101; ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = WINHTTP_ERROR_BASE + 102; ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = WINHTTP_ERROR_BASE + 103; ERROR_WINHTTP_HEADER_NOT_FOUND = WINHTTP_ERROR_BASE + 150; ERROR_WINHTTP_INVALID_SERVER_RESPONSE = WINHTTP_ERROR_BASE + 152; ERROR_WINHTTP_INVALID_HEADER = WINHTTP_ERROR_BASE + 153; ERROR_WINHTTP_INVALID_QUERY_REQUEST = WINHTTP_ERROR_BASE + 154; ERROR_WINHTTP_HEADER_ALREADY_EXISTS = WINHTTP_ERROR_BASE + 155; ERROR_WINHTTP_REDIRECT_FAILED = WINHTTP_ERROR_BASE + 156; //ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157; - see below ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT = WINHTTP_ERROR_BASE + 166; ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = WINHTTP_ERROR_BASE + 167; //ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169; - see below ERROR_WINHTTP_NOT_INITIALIZED = WINHTTP_ERROR_BASE + 172; ERROR_WINHTTP_SECURE_FAILURE = WINHTTP_ERROR_BASE + 175; ERROR_WINHTTP_UNHANDLED_SCRIPT_TYPE = WINHTTP_ERROR_BASE + 176; ERROR_WINHTTP_SCRIPT_EXECUTION_ERROR = WINHTTP_ERROR_BASE + 177; ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = WINHTTP_ERROR_BASE + 178; // Certificate security errors. Additional information is provided // via the WINHTTP_CALLBACK_STATUS_SECURE_FAILURE callback notification. ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37; ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38; ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45; ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57; ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157; ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169; ERROR_WINHTTP_SECURE_CERT_REVOKED = WINHTTP_ERROR_BASE + 170; ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = WINHTTP_ERROR_BASE + 179; ERROR_WINHTTP_AUTODETECTION_FAILED = WINHTTP_ERROR_BASE + 180; ERROR_WINHTTP_HEADER_COUNT_EXCEEDED = WINHTTP_ERROR_BASE + 181; ERROR_WINHTTP_HEADER_SIZE_OVERFLOW = WINHTTP_ERROR_BASE + 182; ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW = WINHTTP_ERROR_BASE + 183; ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW = WINHTTP_ERROR_BASE + 184; ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY = WINHTTP_ERROR_BASE + 185; ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY = WINHTTP_ERROR_BASE + 186; ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED_PROXY = WINHTTP_ERROR_BASE + 187; ERROR_WINHTTP_SECURE_FAILURE_PROXY = WINHTTP_ERROR_BASE + 188; ERROR_WINHTTP_RESERVED_189 = WINHTTP_ERROR_BASE + 189; ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH = WINHTTP_ERROR_BASE + 190; WINHTTP_ERROR_LAST = ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH; const WINHTTP_THRIFT_DEFAULTS = WINHTTP_FLAG_NULL_CODEPAGE or WINHTTP_FLAG_BYPASS_PROXY_CACHE or WINHTTP_FLAG_ESCAPE_DISABLE; type IWinHTTPSession = interface; IWinHTTPConnection = interface; IWinHTTPRequest = interface ['{FADA4B45-D447-4F07-8361-1AD6656E5E8C}'] function Handle : HINTERNET; function Connection : IWinHTTPConnection; function AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean; function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; procedure TryAutoProxy( const aUrl : string); procedure EnableAutomaticContentDecompression( const aEnable : Boolean); function SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean; function WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD; function FlushAndReceiveResponse : Boolean; function ReadData( const dwRead : DWORD) : TBytes; overload; function ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; overload; function QueryDataAvailable : DWORD; function QueryTotalResponseSize( out dwSize : DWORD) : Boolean; function QueryHttpStatus( out dwStatusCode : DWORD; out sStatusText : string) : Boolean; end; IWinHTTPConnection = interface ['{ED5BCA49-84D6-4CFE-BF18-3238B1FF2AFB}'] function Handle : HINTERNET; function Session : IWinHTTPSession; function OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest; end; IWinHTTPSession = interface ['{261ADCB7-5465-4407-8840-468C17F009F0}'] function Handle : HINTERNET; function Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection; function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; function EnableSecureProtocols( const aFlagSet : DWORD) : Boolean; end; IWinHTTPUrl = interface ['{78BE977C-4171-4AF5-A250-FD2890205E63}'] // url parts getter function GetScheme : UnicodeString; function GetNumScheme : INTERNET_SCHEME; function GetHostName : UnicodeString; function GetPort : INTERNET_PORT; function GetUserName : UnicodeString; function GetPassword : UnicodeString; function GetUrlPath : UnicodeString; function GetExtraInfo : UnicodeString; // url parts setter procedure SetScheme( const value : UnicodeString); procedure SetHostName ( const value : UnicodeString); procedure SetPort( const value : INTERNET_PORT); procedure SetUserName( const value : UnicodeString); procedure SetPassword( const value : UnicodeString); procedure SetUrlPath( const value : UnicodeString); procedure SetExtraInfo( const value : UnicodeString); // url as a whole function BuildUrl : UnicodeString; procedure CrackUrl( const value : UnicodeString); // url parts property Scheme : UnicodeString read GetScheme write SetScheme; property NumScheme : INTERNET_SCHEME read GetNumScheme; // readonly property HostName : UnicodeString read GetHostName write SetHostName; property Port : INTERNET_PORT read GetPort write SetPort; property UserName : UnicodeString read GetUserName write SetUserName; property Password : UnicodeString read GetPassword write SetPassword; property UrlPath : UnicodeString read GetUrlPath write SetUrlPath; property ExtraInfo : UnicodeString read GetExtraInfo write SetExtraInfo; // url as a whole property CompleteURL : UnicodeString read BuildUrl write CrackUrl; end; type TWinHTTPHandleObjectImpl = class( TInterfacedObject) strict protected FHandle : HINTERNET; function Handle : HINTERNET; public constructor Create( const aHandle : HINTERNET); destructor Destroy; override; end; TWinHTTPSessionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPSession) strict protected // IWinHTTPSession function Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection; function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; function EnableSecureProtocols( const aFlagSet : DWORD) : Boolean; public constructor Create( const aAgent : UnicodeString; const aAccessType : DWORD = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY; const aProxy : UnicodeString = ''; const aProxyBypass : UnicodeString = ''; const aFlags : DWORD = 0); destructor Destroy; override; end; TWinHTTPConnectionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPConnection) strict protected FSession : IWinHTTPSession; // IWinHTTPConnection function OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest; function Session : IWinHTTPSession; public constructor Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT); destructor Destroy; override; end; TAcceptTypesArray = array of string; TWinHTTPRequestImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPRequest) strict protected FConnection : IWinHTTPConnection; // IWinHTTPRequest function Connection : IWinHTTPConnection; function AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean; function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; procedure TryAutoProxy( const aUrl : string); procedure EnableAutomaticContentDecompression( const aEnable : Boolean); function SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean; function WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD; function FlushAndReceiveResponse : Boolean; function ReadData( const dwRead : DWORD) : TBytes; overload; function ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; overload; function QueryDataAvailable : DWORD; function QueryTotalResponseSize( out dwSize : DWORD) : Boolean; function QueryHttpStatus( out dwStatusCode : DWORD; out sStatusText : string) : Boolean; public constructor Create( const aConnection : IWinHTTPConnection; const aVerb, aObjName : UnicodeString; const aVersion : UnicodeString = ''; const aReferrer : UnicodeString = ''; const aAcceptTypes : UnicodeString = '*/*'; const aFlags : DWORD = WINHTTP_THRIFT_DEFAULTS ); destructor Destroy; override; end; TWinHTTPUrlImpl = class( TInterfacedObject, IWinHTTPUrl) strict private FScheme : UnicodeString; FNumScheme : INTERNET_SCHEME; FHostName : UnicodeString; FPort : INTERNET_PORT; FUserName : UnicodeString; FPassword : UnicodeString; FUrlPath : UnicodeString; FExtraInfo : UnicodeString; strict protected // url parts getter function GetScheme : UnicodeString; function GetNumScheme : INTERNET_SCHEME; function GetHostName : UnicodeString; function GetPort : INTERNET_PORT; function GetUserName : UnicodeString; function GetPassword : UnicodeString; function GetUrlPath : UnicodeString; function GetExtraInfo : UnicodeString; // url parts setter procedure SetScheme( const value : UnicodeString); procedure SetHostName ( const value : UnicodeString); procedure SetPort( const value : INTERNET_PORT); procedure SetUserName( const value : UnicodeString); procedure SetPassword( const value : UnicodeString); procedure SetUrlPath( const value : UnicodeString); procedure SetExtraInfo( const value : UnicodeString); // url as a whole function BuildUrl : UnicodeString; procedure CrackUrl( const value : UnicodeString); public constructor Create( const aUri : UnicodeString); destructor Destroy; override; end; WINHTTP_PROXY_INFO_Helper = record helper for WINHTTP_PROXY_INFO procedure Initialize; procedure FreeAllocatedResources; end; WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper = record helper for WINHTTP_CURRENT_USER_IE_PROXY_CONFIG procedure Initialize; procedure FreeAllocatedResources; end; EWinHTTPException = class(Exception); { helper functions } function WinHttpSysErrorMessage( const error : Cardinal): string; procedure RaiseLastWinHttpError; implementation const WINHTTP_DLL = 'WinHTTP.dll'; function WinHttpCloseHandle; stdcall; external WINHTTP_DLL; function WinHttpOpen; stdcall; external WINHTTP_DLL; function WinHttpConnect; stdcall; external WINHTTP_DLL; function WinHttpOpenRequest; stdcall; external WINHTTP_DLL; function WinHttpSendRequest; stdcall; external WINHTTP_DLL; function WinHttpSetTimeouts; stdcall; external WINHTTP_DLL; function WinHttpQueryOption; stdcall; external WINHTTP_DLL; function WinHttpSetOption; stdcall; external WINHTTP_DLL; function WinHttpAddRequestHeaders; stdcall; external WINHTTP_DLL; function WinHttpGetProxyForUrl; stdcall; external WINHTTP_DLL; function WinHttpGetIEProxyConfigForCurrentUser; stdcall; external WINHTTP_DLL; function WinHttpWriteData; stdcall; external WINHTTP_DLL; function WinHttpReceiveResponse; stdcall; external WINHTTP_DLL; function WinHttpQueryHeaders; stdcall; external WINHTTP_DLL; function WinHttpQueryDataAvailable; stdcall; external WINHTTP_DLL; function WinHttpReadData; stdcall; external WINHTTP_DLL; function WinHttpCrackUrl; stdcall; external WINHTTP_DLL; function WinHttpCreateUrl; stdcall; external WINHTTP_DLL; { helper functions } function WinHttpSysErrorMessage( const error : Cardinal): string; const FLAGS = FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_FROM_HMODULE; var pBuffer : PChar; nChars : Cardinal; begin if (error < WINHTTP_ERROR_BASE) or (error > WINHTTP_ERROR_LAST) then Exit( SysUtils.SysErrorMessage( error)); pBuffer := nil; try nChars := FormatMessage( FLAGS, Pointer( GetModuleHandle( WINHTTP_DLL)), error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language @pBuffer, 0, nil); SetString( result, pBuffer, nChars); finally LocalFree( NativeUInt( pBuffer)); end; end; procedure RaiseLastWinHttpError; var error : Cardinal; sMsg : string; begin error := Cardinal( GetLastError); if error <> NOERROR then begin sMSg := IntToStr(Integer(error))+' '+WinHttpSysErrorMessage(error); raise EWinHTTPException.Create( sMsg); end; end; { misc. record helper } procedure GlobalFreeAndNil( var p : LPWSTR); begin if p <> nil then begin GlobalFree( HGLOBAL( p)); p := nil; end; end; procedure WINHTTP_PROXY_INFO_Helper.Initialize; begin FillChar( Self, SizeOf(Self), 0); end; procedure WINHTTP_PROXY_INFO_Helper.FreeAllocatedResources; // The caller must free the lpszProxy and lpszProxyBypass strings // if they are non-NULL. Use GlobalFree to free the strings. begin GlobalFreeAndNil( lpszProxy); GlobalFreeAndNil( lpszProxyBypass); Initialize; end; procedure WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper.Initialize; begin FillChar( Self, SizeOf(Self), 0); end; procedure WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper.FreeAllocatedResources; // The caller must free the lpszProxy, lpszProxyBypass and lpszAutoConfigUrl strings // if they are non-NULL. Use GlobalFree to free the strings. begin GlobalFreeAndNil( lpszProxy); GlobalFreeAndNil( lpszProxyBypass); GlobalFreeAndNil( lpszAutoConfigUrl); Initialize; end; { TWinHTTPHandleObjectImpl } constructor TWinHTTPHandleObjectImpl.Create( const aHandle : HINTERNET); begin inherited Create; FHandle := aHandle; if FHandle = nil then raise EWinHTTPException.Create('Invalid handle'); end; destructor TWinHTTPHandleObjectImpl.Destroy; begin try if Assigned(FHandle) then begin WinHttpCloseHandle(FHandle); FHandle := nil; end; finally inherited Destroy; end; end; function TWinHTTPHandleObjectImpl.Handle : HINTERNET; begin result := FHandle; end; { TWinHTTPSessionImpl } constructor TWinHTTPSessionImpl.Create( const aAgent : UnicodeString; const aAccessType : DWORD; const aProxy, aProxyBypass : UnicodeString; const aFlags : DWORD); var handle : HINTERNET; begin handle := WinHttpOpen( PWideChar(aAgent), aAccessType, PWideChar(Pointer(aProxy)), // may be nil PWideChar(Pointer(aProxyBypass)), // may be nil aFlags); if handle = nil then RaiseLastWinHttpError; inherited Create( handle); end; destructor TWinHTTPSessionImpl.Destroy; begin inherited Destroy; // add code here end; function TWinHTTPSessionImpl.Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT) : IWinHTTPConnection; begin result := TWinHTTPConnectionImpl.Create( Self, aHostName, aPort); end; function TWinHTTPSessionImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; begin result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout); end; function TWinHTTPSessionImpl.EnableSecureProtocols( const aFlagSet : DWORD) : Boolean; var dwSize : DWORD; begin dwSize := SizeOf(aFlagSet); result := WinHttpSetOption( Handle, WINHTTP_OPTION_SECURE_PROTOCOLS, @aFlagset, dwSize); end; { TWinHTTPConnectionImpl } constructor TWinHTTPConnectionImpl.Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT); var handle : HINTERNET; begin FSession := aSession; handle := WinHttpConnect( FSession.Handle, PWideChar(aHostName), aPort, 0); if handle = nil then RaiseLastWinHttpError; inherited Create( handle); end; destructor TWinHTTPConnectionImpl.Destroy; begin inherited Destroy; FSession := nil; end; function TWinHTTPConnectionImpl.Session : IWinHTTPSession; begin result := FSession; end; function TWinHTTPConnectionImpl.OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest; var dwFlags : DWORD; begin dwFlags := WINHTTP_THRIFT_DEFAULTS; if secure then dwFlags := dwFlags or WINHTTP_FLAG_SECURE else dwFlags := dwFlags and not WINHTTP_FLAG_SECURE; result := TWinHTTPRequestImpl.Create( Self, aVerb, aObjName, '', '', aAcceptTypes, dwFlags); end; { TWinHTTPRequestImpl } constructor TWinHTTPRequestImpl.Create( const aConnection : IWinHTTPConnection; const aVerb, aObjName, aVersion, aReferrer : UnicodeString; const aAcceptTypes : UnicodeString; const aFlags : DWORD ); var handle : HINTERNET; accept : array[0..1] of PWideChar; begin FConnection := aConnection; accept[0] := PWideChar(aAcceptTypes); accept[1] := nil; handle := WinHttpOpenRequest( FConnection.Handle, PWideChar(UpperCase(aVerb)), PWideChar(aObjName), PWideChar(aVersion), PWideChar(aReferrer), @accept, aFlags); if handle = nil then RaiseLastWinHttpError; inherited Create( handle); end; destructor TWinHTTPRequestImpl.Destroy; begin inherited Destroy; FConnection := nil; end; function TWinHTTPRequestImpl.Connection : IWinHTTPConnection; begin result := FConnection; end; function TWinHTTPRequestImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; begin result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout); end; function TWinHTTPRequestImpl.AddRequestHeader( const aHeader : string; const addflag : DWORD) : Boolean; begin result := WinHttpAddRequestHeaders( FHandle, PWideChar(aHeader), DWORD(-1), addflag); end; procedure TWinHTTPRequestImpl.TryAutoProxy( const aUrl : string); // From MSDN: // AutoProxy support is not fully integrated into the HTTP stack in WinHTTP. // Before sending a request, the application must call WinHttpGetProxyForUrl // to obtain the name of a proxy server and then call WinHttpSetOption using // WINHTTP_OPTION_PROXY to set the proxy configuration on the WinHTTP request // handle created by WinHttpOpenRequest. // See https://docs.microsoft.com/en-us/windows/desktop/winhttp/winhttp-autoproxy-api var options : WINHTTP_AUTOPROXY_OPTIONS; proxy : WINHTTP_PROXY_INFO; ieProxy : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; dwSize : DWORD; begin // try AutoProxy via PAC first proxy.Initialize; try FillChar( options, SizeOf(options), 0); options.dwFlags := WINHTTP_AUTOPROXY_AUTO_DETECT; options.dwAutoDetectFlags := WINHTTP_AUTO_DETECT_TYPE_DHCP or WINHTTP_AUTO_DETECT_TYPE_DNS_A; options.fAutoLogonIfChallenged := TRUE; if WinHttpGetProxyForUrl( FConnection.Session.Handle, PChar(aUrl), options, proxy) then begin dwSize := SizeOf(proxy); WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize); Exit; end; finally proxy.FreeAllocatedResources; end; // Use IE settings as a fallback, useful in client (i.e. non-server) environments ieProxy.Initialize; try if WinHttpGetIEProxyConfigForCurrentUser( ieProxy) then begin // lpszAutoConfigUrl = "Use automatic proxy configuration" if ieProxy.lpszAutoConfigUrl <> nil then begin options.lpszAutoConfigUrl := ieProxy.lpszAutoConfigUrl; options.dwFlags := options.dwFlags or WINHTTP_AUTOPROXY_CONFIG_URL; proxy.Initialize; try if WinHttpGetProxyForUrl( FConnection.Session.Handle, PChar(aUrl), options, proxy) then begin dwSize := SizeOf(proxy); WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize); Exit; end; finally proxy.FreeAllocatedResources; end; end; // lpszProxy = "use a proxy server" if ieProxy.lpszProxy <> nil then begin proxy.Initialize; try proxy.dwAccessType := WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy.lpszProxy := ieProxy.lpszProxy; proxy.lpszProxyBypass := ieProxy.lpszProxyBypass; dwSize := SizeOf(proxy); WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize); Exit; finally proxy.Initialize; // not FreeAllocatedResources, we only hold pointer copies! end; end; end; finally ieProxy.FreeAllocatedResources; end; end; procedure TWinHTTPRequestImpl.EnableAutomaticContentDecompression( const aEnable : Boolean); // Enable automatic gzip,deflate decompression on systems that support this option // From the docs: WinHTTP will automatically set an appropriate Accept-Encoding header, // overriding any value supplied by the caller -> we don't have to do this // Available on Win 8.1 or higher var value : DWORD; begin if aEnable then value := WINHTTP_DECOMPRESSION_FLAG_ALL else value := 0; // ignore returned value, the option is not supported with older WinHTTP versions WinHttpSetOption( Handle, WINHTTP_OPTION_DECOMPRESSION, @value, SizeOf(DWORD)); end; function TWinHTTPRequestImpl.SendRequest( const pBuf : Pointer; const dwBytes, dwExtra : DWORD) : Boolean; begin result := WinHttpSendRequest( FHandle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, pBuf, dwBytes, // number of bytes in pBuf dwBytes + dwExtra, // becomes the Content-Length nil); // context for async operations end; function TWinHTTPRequestImpl.WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD; begin if not WinHttpWriteData( FHandle, pBuf, dwBytes, result) then result := 0; end; function TWinHTTPRequestImpl.FlushAndReceiveResponse : Boolean; begin result := WinHttpReceiveResponse( FHandle, nil); end; function TWinHTTPRequestImpl.ReadData( const dwRead : DWORD) : TBytes; var dwAvailable, dwReceived : DWORD; begin if WinHttpQueryDataAvailable( FHandle, dwAvailable) then dwAvailable := Min( dwRead, dwAvailable) else dwAvailable := 0; SetLength( result, dwAvailable); if dwAvailable = 0 then Exit; if WinHttpReadData( FHandle, @result[0], Length(result), dwReceived) then SetLength( result, dwReceived) else SetLength( result, 0); end; function TWinHTTPRequestImpl.ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; var dwAvailable : DWORD; begin if WinHttpQueryDataAvailable( FHandle, dwAvailable) then dwAvailable := Min( dwRead, dwAvailable) else dwAvailable := 0; if (dwAvailable = 0) or not WinHttpReadData( FHandle, pBuf, dwAvailable, result) then result := 0; end; function TWinHTTPRequestImpl.QueryDataAvailable : DWORD; begin if not WinHttpQueryDataAvailable( FHandle, result) then result := 0; end; function TWinHTTPRequestImpl.QueryTotalResponseSize( out dwSize : DWORD) : Boolean; var dwBytes, dwError, dwIndex : DWORD; bytes : array[0..32-1] of Byte; begin dwBytes := SizeOf( result); dwIndex := DWORD( WINHTTP_NO_HEADER_INDEX); result := WinHttpQueryHeaders( FHandle, WINHTTP_QUERY_CONTENT_LENGTH or WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, @dwSize, dwBytes, dwIndex); if result then Exit; dwError := GetLastError; // Hack: WinHttpQueryHeaders() sometimes returns error 122 even if the buffer is large enough // According to the docs, WINHTTP_QUERY_FLAG_NUMBER always returns a 32 bit number (which it does!) // but for some strange reason since win 10 build 18636.815 passing a 4 bytes buffer is not enough anymore if dwError = ERROR_INSUFFICIENT_BUFFER then begin dwBytes := sizeof(bytes); FillChar( bytes[0], dwBytes, 0); result := WinHttpQueryHeaders( FHandle, WINHTTP_QUERY_CONTENT_LENGTH or WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, @bytes[0], dwBytes, dwIndex); if result then begin ASSERT( dwBytes = SizeOf(dwSize)); // result is still a DWORD Move( bytes[0], dwSize, SizeOf(dwSize)); // copy over result data Exit; end; end; // header may just not be there dwSize := MAXINT; // we don't know, just return something useful ASSERT( dwError = ERROR_WINHTTP_HEADER_NOT_FOUND); // anything else would be an real error end; function TWinHTTPRequestImpl.QueryHttpStatus( out dwStatusCode : DWORD; out sStatusText : string) : Boolean; var dwBytes, dwError, dwIndex : DWORD; begin // HTTP status code dwIndex := DWORD( WINHTTP_NO_HEADER_INDEX); dwBytes := SizeOf(dwStatusCode); result := WinHttpQueryHeaders( FHandle, WINHTTP_QUERY_STATUS_CODE or WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, @dwStatusCode, dwBytes, dwIndex); if not result then begin dwStatusCode := 0; // no data dwError := GetLastError; if dwError <> ERROR_WINHTTP_HEADER_NOT_FOUND then ASSERT(FALSE); // anything else would be an real error end; // HTTP status text dwIndex := DWORD( WINHTTP_NO_HEADER_INDEX); dwBytes := 0; result := WinHttpQueryHeaders( FHandle, WINHTTP_QUERY_STATUS_TEXT, WINHTTP_HEADER_NAME_BY_INDEX, WINHTTP_NO_OUTPUT_BUFFER, // we need to determine the size first dwBytes, // will receive the required buffer size dwIndex); if dwBytes > 0 then begin // allocate buffer and call again to get the value SetLength( sStatusText, dwBytes div SizeOf(Char)); dwBytes := Length(sStatusText) * SizeOf(Char); result := WinHttpQueryHeaders( FHandle, WINHTTP_QUERY_STATUS_TEXT, WINHTTP_HEADER_NAME_BY_INDEX, @sStatusText[1], dwBytes, dwIndex); end; if result then SetLength( sStatusText, StrLen(PChar(sStatusText))) // get rid of any terminating #0 chars else begin sStatusText := ''; // no data dwError := GetLastError; if dwError <> ERROR_WINHTTP_HEADER_NOT_FOUND then ASSERT(FALSE); // anything else would be an real error end; // do we have at least something? result := (dwStatusCode <> 0) or (sStatusText <> ''); end; { TWinHTTPUrlImpl } constructor TWinHTTPUrlImpl.Create(const aUri: UnicodeString); begin inherited Create; CrackUrl( aUri) end; destructor TWinHTTPUrlImpl.Destroy; begin inherited Destroy; end; procedure TWinHTTPUrlImpl.CrackURL( const value : UnicodeString); const FLAGS = 0; // no special operations, leave components as-is var components : URL_COMPONENTS; begin FillChar(components, SizeOf(components), 0); components.dwStructSize := SizeOf(components); if value <> '' then begin { For the WinHttpCrackUrl function, [...] if the pointer member is NULL but the length member is not zero, both the pointer and length members are returned. } components.dwSchemeLength := DWORD(-1); components.dwHostNameLength := DWORD(-1); components.dwUserNameLength := DWORD(-1); components.dwPasswordLength := DWORD(-1); components.dwUrlPathLength := DWORD(-1); components.dwExtraInfoLength := DWORD(-1); WinHttpCrackUrl( PWideChar(value), Length(value), FLAGS, components); end; FNumScheme := components.nScheme; FPort := components.nPort; SetString( FScheme, components.lpszScheme, components.dwSchemeLength); SetString( FHostName, components.lpszHostName, components.dwHostNameLength); SetString( FUserName, components.lpszUserName, components.dwUserNameLength); SetString( FPassword, components.lpszPassword, components.dwPasswordLength); SetString( FUrlPath, components.lpszUrlPath, components.dwUrlPathLength); SetString( FExtraInfo, components.lpszExtraInfo, components.dwExtraInfoLength); end; function TWinHTTPUrlImpl.BuildUrl : UnicodeString; const FLAGS = 0; // no special operations, leave components as-is var components : URL_COMPONENTS; dwChars : DWORD; begin FillChar(components, SizeOf(components), 0); components.dwStructSize := SizeOf(components); components.lpszScheme := PWideChar(FScheme); components.dwSchemeLength := Length(FScheme); components.lpszHostName := PWideChar(FHostName); components.dwHostNameLength := Length(FHostName); components.nPort := FPort; components.lpszUserName := PWideChar(FUserName); components.dwUserNameLength := Length(FUserName); components.lpszPassword := PWideChar(FPassword); components.dwPasswordLength := Length(FPassword); components.lpszUrlPath := PWideChar(FUrlPath); components.dwUrlPathLength := Length(FUrlPath); components.lpszExtraInfo := PWideChar(FExtraInfo); components.dwExtraInfoLength := Length(FExtraInfo); WinHttpCreateUrl( components, FLAGS, nil, dwChars); if dwChars = 0 then result := '' else begin SetLength( result, dwChars + 1); WinHttpCreateUrl( components, FLAGS, @result[1], dwChars); SetLength( result, dwChars); // cut off terminating #0 end; end; function TWinHTTPUrlImpl.GetExtraInfo: UnicodeString; begin result := FExtraInfo; end; function TWinHTTPUrlImpl.GetHostName: UnicodeString; begin result := FHostName; end; function TWinHTTPUrlImpl.GetNumScheme: INTERNET_SCHEME; begin result := FNumScheme; end; function TWinHTTPUrlImpl.GetPassword: UnicodeString; begin result := FPassword; end; function TWinHTTPUrlImpl.GetPort: INTERNET_PORT; begin result := FPort; end; function TWinHTTPUrlImpl.GetScheme: UnicodeString; begin result := FScheme; end; function TWinHTTPUrlImpl.GetUrlPath: UnicodeString; begin result := FUrlPath; end; function TWinHTTPUrlImpl.GetUserName: UnicodeString; begin result := FUserName; end; procedure TWinHTTPUrlImpl.SetExtraInfo(const value: UnicodeString); begin FExtraInfo := value; end; procedure TWinHTTPUrlImpl.SetHostName(const value: UnicodeString); begin FHostName := value; end; procedure TWinHTTPUrlImpl.SetPassword(const value: UnicodeString); begin FPassword := value; end; procedure TWinHTTPUrlImpl.SetPort(const value: INTERNET_PORT); begin FPort := value; end; procedure TWinHTTPUrlImpl.SetScheme(const value: UnicodeString); begin FScheme := value; end; procedure TWinHTTPUrlImpl.SetUrlPath(const value: UnicodeString); begin FUrlPath := value; end; procedure TWinHTTPUrlImpl.SetUserName(const value: UnicodeString); begin FUserName := value; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Configuration.pas0000664000175000017500000000751015165535636022755 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Configuration; interface uses SysUtils, Generics.Collections, Generics.Defaults; const DEFAULT_RECURSION_LIMIT = 64; DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024; // 100 MB DEFAULT_MAX_FRAME_SIZE = 16384000; // this value is used consistently across all Thrift libraries DEFAULT_THRIFT_TIMEOUT = 5 * 1000; // ms type IThriftConfiguration = interface ['{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 : 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; end; implementation { TThriftConfigurationImpl } constructor TThriftConfigurationImpl.Create; begin inherited Create; FRecursionLimit := DEFAULT_RECURSION_LIMIT; FMaxFrameSize := DEFAULT_MAX_FRAME_SIZE; FMaxMessageSize := DEFAULT_MAX_MESSAGE_SIZE; end; 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 and MAXINT; ASSERT( result > 0); end; procedure TThriftConfigurationImpl.SetRecursionLimit(const value: Integer); begin ValidateLimitArgument( value); ASSERT( value > 0); FRecursionLimit := value and MAXINT; end; function TThriftConfigurationImpl.GetMaxFrameSize: Integer; begin result := FMaxFrameSize and MAXINT; ASSERT( result > 0); end; procedure TThriftConfigurationImpl.SetMaxFrameSize(const value: Integer); begin ValidateLimitArgument( value); ASSERT( value > 0); FMaxFrameSize := value and MAXINT; end; function TThriftConfigurationImpl.GetMaxMessageSize: Integer; begin result := FMaxMessageSize and MAXINT; ASSERT( result > 0); end; procedure TThriftConfigurationImpl.SetMaxMessageSize(const value: Integer); begin ValidateLimitArgument( value); ASSERT( value > 0); FMaxMessageSize := value and MAXINT; end; end. thrift-0.23.0/lib/delphi/src/Thrift.TypeRegistry.pas0000664000175000017500000000473315165535636022624 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.TypeRegistry; interface uses Generics.Collections, TypInfo, Thrift.Protocol; type TFactoryMethod = function:T; TypeRegistry = class strict private class var FTypeInfoToFactoryLookup : TDictionary; public class constructor Create; class destructor Destroy; class procedure RegisterTypeFactory(const aFactoryMethod: TFactoryMethod); class function Construct: F; class function ConstructFromTypeInfo(const aTypeInfo: PTypeInfo): IBase; end; implementation { TypeRegistration } class constructor TypeRegistry.Create; begin FTypeInfoToFactoryLookup := TDictionary.Create; end; class destructor TypeRegistry.Destroy; begin FTypeInfoToFactoryLookup.Free; end; class procedure TypeRegistry.RegisterTypeFactory(const aFactoryMethod: TFactoryMethod); var TypeInfo : Pointer; begin TypeInfo := System.TypeInfo(F); if (TypeInfo <> nil) and (PTypeInfo(TypeInfo).Kind = tkInterface) then FTypeInfoToFactoryLookup.AddOrSetValue(TypeInfo, @aFactoryMethod); end; class function TypeRegistry.Construct: F; var TypeInfo : PTypeInfo; Factory : Pointer; begin Result := default(F); TypeInfo := System.TypeInfo(F); if Assigned(TypeInfo) and (TypeInfo.Kind = tkInterface) then begin if FTypeInfoToFactoryLookup.TryGetValue(TypeInfo, Factory) then Result := TFactoryMethod(Factory)(); end; end; class function TypeRegistry.ConstructFromTypeInfo(const aTypeInfo: PTypeInfo): IBase; var Factory : Pointer; begin Result := nil; if FTypeInfoToFactoryLookup.TryGetValue(aTypeInfo, Factory) then Result := IBase(TFactoryMethod(Factory)()); end; end. thrift-0.23.0/lib/delphi/src/Thrift.Stream.pas0000664000175000017500000002571015165535636021403 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Stream; {$I Thrift.Defines.inc} interface uses Classes, SysUtils, SysConst, RTLConsts, {$IFDEF OLD_UNIT_NAMES} ActiveX, {$ELSE} Winapi.ActiveX, {$ENDIF} Thrift.Utils; type IThriftStream = interface ['{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; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; overload; procedure Open; procedure Close; procedure Flush; function IsOpen: Boolean; function ToArray: TBytes; function CanSeek : Boolean; function Size : Int64; function Position : Int64; end; TThriftStreamImpl = class abstract( TInterfacedObject, IThriftStream) strict private procedure CheckSizeAndOffset( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer); overload; strict protected // IThriftStream procedure Write( const buffer: TBytes; offset: Integer; count: Integer); overload; inline; procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); overload; virtual; function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; overload; inline; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; overload; virtual; procedure Open; virtual; abstract; procedure Close; virtual; abstract; 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; TThriftStreamAdapterDelphi = class( TThriftStreamImpl) strict private FStream : TStream; FOwnsStream : Boolean; strict protected // IThriftStream procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); override; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override; procedure Open; override; procedure Close; override; procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public constructor Create( const aStream: TStream; aOwnsStream : Boolean); destructor Destroy; override; end; TThriftStreamAdapterCOM = class( TThriftStreamImpl) strict private FStream : IStream; strict protected // IThriftStream procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); override; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override; procedure Open; override; procedure Close; override; procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public constructor Create( const aStream: IStream); end; TThriftMemoryStream = class(TMemoryStream) strict protected FInitialCapacity : NativeInt; public constructor Create( const aInitialCapacity : NativeInt = 4096); // reimplemented procedure Clear; // make it publicly visible property Capacity; end; implementation uses Thrift.Transport; { TThriftMemoryStream } constructor TThriftMemoryStream.Create( const aInitialCapacity : NativeInt); begin inherited Create; FInitialCapacity := aInitialCapacity; Clear; end; procedure TThriftMemoryStream.Clear; // reimplemented to keep initial capacity begin Position := 0; Size := 0; // primary goal: minimize costly reallocations (performance!) // secondary goal: prevent costly ressource over-allocations if (FInitialCapacity >= 1024*1024) // if we are talking about MB or ((Capacity div 2) > FInitialCapacity) // or the allocated buffer is really large or (Capacity < FInitialCapacity) // or we are actually below the limit then Capacity := FInitialCapacity; end; { TThriftStreamAdapterCOM } procedure TThriftStreamAdapterCOM.Close; begin FStream := nil; end; constructor TThriftStreamAdapterCOM.Create( const aStream: IStream); begin inherited Create; FStream := aStream; end; procedure TThriftStreamAdapterCOM.Flush; begin if IsOpen then begin if FStream <> nil then begin FStream.Commit( STGC_DEFAULT ); end; 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 FillChar( statstg, SizeOf( statstg), 0); if IsOpen and Succeeded( FStream.Stat( statstg, STATFLAG_NONAME )) then result := statstg.cbSize else result := 0; end; function TThriftStreamAdapterCOM.Position : Int64; var newpos : {$IF CompilerVersion >= 29.0} UInt64 {$ELSE} Int64 {$IFEND}; begin if SUCCEEDED( FStream.Seek( 0, STREAM_SEEK_CUR, newpos)) then result := Int64(newpos) else raise TTransportExceptionEndOfFile.Create('Seek() error'); end; function TThriftStreamAdapterCOM.IsOpen: Boolean; begin Result := FStream <> nil; end; procedure TThriftStreamAdapterCOM.Open; begin // nothing to do end; function TThriftStreamAdapterCOM.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; var pTmp : PByte; begin inherited; if count >= buflen-offset then count := buflen-offset; Result := 0; if FStream <> nil then begin if count > 0 then begin pTmp := pBuf; Inc( pTmp, offset); FStream.Read( pTmp, count, @Result); end; end; end; function TThriftStreamAdapterCOM.ToArray: TBytes; var len : Int64; NewPos : {$IF CompilerVersion >= 29.0} UInt64 {$ELSE} Int64 {$IFEND}; cbRead : Integer; begin len := Self.Size; SetLength( Result, len ); if len > 0 then begin if Succeeded( FStream.Seek( 0, STREAM_SEEK_SET, NewPos) ) then begin FStream.Read( @Result[0], len, @cbRead); end; end; end; procedure TThriftStreamAdapterCOM.Write( const pBuf: Pointer; offset: Integer; count: Integer); var nWritten : Integer; pTmp : PByte; begin inherited; if IsOpen then begin if count > 0 then begin pTmp := pBuf; Inc( pTmp, offset); FStream.Write( pTmp, count, @nWritten); end; end; end; { TThriftStreamImpl } procedure TThriftStreamImpl.CheckSizeAndOffset( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer); begin if count > 0 then begin if (offset < 0) or ( offset >= buflen) then begin raise ERangeError.Create( SBitsIndexError ); end; if count > buflen then begin raise ERangeError.Create( SBitsIndexError ); end; end; end; function TThriftStreamImpl.Read(var buffer: TBytes; offset, count: Integer): Integer; begin if Length(buffer) > 0 then Result := Read( @buffer[0], Length(buffer), offset, count) else Result := 0; end; function TThriftStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; begin Result := 0; CheckSizeAndOffset( pBuf, buflen, offset, count ); end; procedure TThriftStreamImpl.Write(const buffer: TBytes; offset, count: Integer); begin if Length(buffer) > 0 then Write( @buffer[0], offset, count); end; procedure TThriftStreamImpl.Write( const pBuf : Pointer; offset: Integer; count: Integer); begin 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); raise ENotImplemented.Create(ClassName+'.Size'); end; function TThriftStreamImpl.Position : Int64; begin ASSERT(FALSE); raise ENotImplemented.Create(ClassName+'.Position'); end; { TThriftStreamAdapterDelphi } constructor TThriftStreamAdapterDelphi.Create( const aStream: TStream; aOwnsStream: Boolean); begin inherited Create; FStream := aStream; FOwnsStream := aOwnsStream; end; destructor TThriftStreamAdapterDelphi.Destroy; begin if FOwnsStream then Close; inherited; end; procedure TThriftStreamAdapterDelphi.Close; begin FStream.Free; FStream := nil; FOwnsStream := False; end; procedure TThriftStreamAdapterDelphi.Flush; begin // 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; end; function TThriftStreamAdapterDelphi.Position : Int64; begin result := FStream.Position; end; function TThriftStreamAdapterDelphi.IsOpen: Boolean; begin Result := FStream <> nil; end; procedure TThriftStreamAdapterDelphi.Open; begin // nothing to do end; function TThriftStreamAdapterDelphi.Read(const pBuf : Pointer; const buflen : Integer; offset, count: Integer): Integer; var pTmp : PByte; begin inherited; if count >= buflen-offset then count := buflen-offset; if count > 0 then begin pTmp := pBuf; Inc( pTmp, offset); Result := FStream.Read( pTmp^, count) end else Result := 0; end; function TThriftStreamAdapterDelphi.ToArray: TBytes; var OrgPos : Integer; len : Integer; begin if FStream <> nil then len := FStream.Size else len := 0; SetLength( Result, len ); if len > 0 then begin OrgPos := FStream.Position; try FStream.Position := 0; FStream.ReadBuffer( Pointer(@Result[0])^, len ); finally FStream.Position := OrgPos; end; end end; procedure TThriftStreamAdapterDelphi.Write(const pBuf : Pointer; offset, count: Integer); var pTmp : PByte; begin inherited; if count > 0 then begin pTmp := pBuf; Inc( pTmp, offset); FStream.Write( pTmp^, count) end; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Defines.inc0000664000175000017500000000267115165535636021514 0ustar00buildbuild00000000000000(* * 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. *) // Good lists of Delphi version numbers // https://github.com/project-jedi/jedi/blob/master/jedi.inc // http://docwiki.embarcadero.com/RADStudio/Seattle/en/Compiler_Versions // start with most backwards compatible defaults {$DEFINE OLD_UNIT_NAMES} {$DEFINE OLD_SOCKETS} // TODO: add socket support for CompilerVersion >= 28.0 {$UNDEF HAVE_CLASS_CTOR} // enable features as they are available {$IF CompilerVersion >= 21.0} // Delphi 2010 {$DEFINE HAVE_CLASS_CTOR} {$IFEND} {$IF CompilerVersion >= 23.0} // Delphi XE2 {$UNDEF OLD_UNIT_NAMES} {$IFEND} {$IF CompilerVersion >= 28.0} // Delphi XE7 {$UNDEF OLD_SOCKETS} {$IFEND} // EOF thrift-0.23.0/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas0000664000175000017500000002033215165535636023736 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Transport.MsxmlHTTP; {$I Thrift.Defines.inc} {$SCOPEDENUMS ON} interface uses Classes, SysUtils, Math, Generics.Collections, {$IFDEF OLD_UNIT_NAMES} ActiveX, msxml, {$ELSE} Winapi.ActiveX, Winapi.msxml, {$ENDIF} Thrift.Collections, Thrift.Configuration, Thrift.Transport, Thrift.Exception, Thrift.Utils, Thrift.Stream; type TMsxmlHTTPClientImpl = class( TEndpointTransportBase, IHTTPClient) strict private FUri : string; FInputStream : IThriftStream; FOutputStream : IThriftStream; FDnsResolveTimeout : Integer; FConnectionTimeout : Integer; FSendTimeout : Integer; FReadTimeout : Integer; FCustomHeaders : IThriftDictionary; function CreateRequest: IXMLHTTPRequest; class procedure EnsureSuccessHttpStatus( const aRequest : IXMLHTTPRequest); strict protected function GetIsOpen: Boolean; override; procedure Open(); override; procedure Close(); override; function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override; procedure Write( const pBuf : Pointer; off, len : Integer); override; procedure Flush; override; procedure SetDnsResolveTimeout(const Value: Integer); function GetDnsResolveTimeout: Integer; procedure SetConnectionTimeout(const Value: Integer); function GetConnectionTimeout: Integer; procedure SetSendTimeout(const Value: Integer); function GetSendTimeout: Integer; procedure SetReadTimeout(const Value: Integer); function GetReadTimeout: Integer; function GetSecureProtocols : TSecureProtocols; procedure SetSecureProtocols( const value : TSecureProtocols); function GetCustomHeaders: IThriftDictionary; procedure SendRequest; property DnsResolveTimeout: Integer read GetDnsResolveTimeout write SetDnsResolveTimeout; property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout; property SendTimeout: Integer read GetSendTimeout write SetSendTimeout; property ReadTimeout: Integer read GetReadTimeout write SetReadTimeout; property CustomHeaders: IThriftDictionary read GetCustomHeaders; public constructor Create( const aUri: string; const aConfig : IThriftConfiguration); reintroduce; destructor Destroy; override; end; implementation const XMLHTTP_CONNECTION_TIMEOUT = 60 * 1000; XMLHTTP_SENDRECV_TIMEOUT = 30 * 1000; { TMsxmlHTTPClientImpl } constructor TMsxmlHTTPClientImpl.Create( const aUri: string; const aConfig : IThriftConfiguration); begin inherited Create( aConfig); FUri := aUri; // defaults according to MSDN FDnsResolveTimeout := 0; // no timeout FConnectionTimeout := XMLHTTP_CONNECTION_TIMEOUT; FSendTimeout := XMLHTTP_SENDRECV_TIMEOUT; FReadTimeout := XMLHTTP_SENDRECV_TIMEOUT; FCustomHeaders := TThriftDictionaryImpl.Create; FOutputStream := TThriftStreamAdapterDelphi.Create( TThriftMemoryStream.Create, True); end; function TMsxmlHTTPClientImpl.CreateRequest: IXMLHTTPRequest; var pair : TPair; srvHttp : IServerXMLHTTPRequest; begin {$IF CompilerVersion >= 21.0} Result := CoServerXMLHTTP.Create; {$ELSE} Result := CoXMLHTTPRequest.Create; {$IFEND} // setting a timeout value to 0 (zero) means "no timeout" for that setting if Supports( result, IServerXMLHTTPRequest, srvHttp) then srvHttp.setTimeouts( DnsResolveTimeout, ConnectionTimeout, SendTimeout, ReadTimeout); Result.open('POST', FUri, False, '', ''); Result.setRequestHeader( 'Content-Type', THRIFT_MIMETYPE); Result.setRequestHeader( 'Accept', THRIFT_MIMETYPE); Result.setRequestHeader( 'User-Agent', 'ApacheThriftDelphi/msxml'); for pair in FCustomHeaders do begin Result.setRequestHeader( pair.Key, pair.Value ); end; end; destructor TMsxmlHTTPClientImpl.Destroy; begin Close; inherited; end; function TMsxmlHTTPClientImpl.GetDnsResolveTimeout: Integer; begin Result := FDnsResolveTimeout; end; procedure TMsxmlHTTPClientImpl.SetDnsResolveTimeout(const Value: Integer); begin FDnsResolveTimeout := Value; end; function TMsxmlHTTPClientImpl.GetConnectionTimeout: Integer; begin Result := FConnectionTimeout; end; procedure TMsxmlHTTPClientImpl.SetConnectionTimeout(const Value: Integer); begin FConnectionTimeout := Value; end; function TMsxmlHTTPClientImpl.GetSendTimeout: Integer; begin Result := FSendTimeout; end; procedure TMsxmlHTTPClientImpl.SetSendTimeout(const Value: Integer); begin FSendTimeout := Value; end; function TMsxmlHTTPClientImpl.GetReadTimeout: Integer; begin Result := FReadTimeout; end; procedure TMsxmlHTTPClientImpl.SetReadTimeout(const Value: Integer); begin FReadTimeout := Value; end; function TMsxmlHTTPClientImpl.GetSecureProtocols : TSecureProtocols; begin Result := []; end; procedure TMsxmlHTTPClientImpl.SetSecureProtocols( const value : TSecureProtocols); begin raise TTransportExceptionBadArgs.Create('SetSecureProtocols: Not supported with '+ClassName); end; function TMsxmlHTTPClientImpl.GetCustomHeaders: IThriftDictionary; begin Result := FCustomHeaders; end; function TMsxmlHTTPClientImpl.GetIsOpen: Boolean; begin Result := Assigned(FOutputStream); end; procedure TMsxmlHTTPClientImpl.Open; begin FOutputStream := TThriftStreamAdapterDelphi.Create( TThriftMemoryStream.Create, True); end; procedure TMsxmlHTTPClientImpl.Close; begin FInputStream := nil; FOutputStream := nil; end; procedure TMsxmlHTTPClientImpl.Flush; begin try SendRequest; finally FOutputStream := nil; FOutputStream := TThriftStreamAdapterDelphi.Create( TThriftMemoryStream.Create, True); ASSERT( FOutputStream <> nil); end; end; function TMsxmlHTTPClientImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; begin if FInputStream = nil then begin raise TTransportExceptionNotOpen.Create('No request has been sent'); end; try Result := FInputStream.Read( pBuf, buflen, off, len); except on E: Exception do raise TTransportExceptionUnknown.Create(E.Message); end; end; procedure TMsxmlHTTPClientImpl.SendRequest; var xmlhttp : IXMLHTTPRequest; ms : TThriftMemoryStream; a : TBytes; len : Integer; begin xmlhttp := CreateRequest; ms := TThriftMemoryStream.Create; try a := FOutputStream.ToArray; len := Length(a); if len > 0 then begin ms.WriteBuffer( Pointer(@a[0])^, len); end; ms.Position := 0; xmlhttp.send( IUnknown( TStreamAdapter.Create( ms, soReference ))); FInputStream := nil; EnsureSuccessHttpStatus(xmlhttp); // throws if not FInputStream := TThriftStreamAdapterCOM.Create( IUnknown( xmlhttp.responseStream) as IStream); ResetMessageSizeAndConsumedBytes; UpdateKnownMessageSize( FInputStream.Size); finally ms.Free; end; end; procedure TMsxmlHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer); begin if FOutputStream <> nil then FOutputStream.Write( pBuf, off, len) else raise TTransportExceptionNotOpen.Create('Transport closed'); 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. thrift-0.23.0/lib/delphi/src/Thrift.Protocol.Multiplex.pas0000664000175000017500000000666515165535636023743 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Protocol.Multiplex; interface uses Thrift.Protocol; { TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift client to communicate with a multiplexing Thrift server, by prepending the service name to the function name during function calls. NOTE: THIS IS NOT USED BY SERVERS. On the server, use TMultiplexedProcessor to handle requests from a multiplexing client. This example uses a single socket transport to invoke two services: TSocket transport = new TSocket("localhost", 9090); transport.open(); TBinaryProtocol protocol = new TBinaryProtocol(transport); TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator"); Calculator.Client service = new Calculator.Client(mp); TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport"); WeatherReport.Client service2 = new WeatherReport.Client(mp2); System.out.println(service.add(2,2)); System.out.println(service2.getTemperature()); } type TMultiplexedProtocol = class( TProtocolDecorator) public const { Used to delimit the service name from the function name } SEPARATOR = ':'; strict private FServiceName : String; public { Wrap the specified protocol, allowing it to be used to communicate with a multiplexing server. The serviceName is required as it is prepended to the message header so that the multiplexing server can broker the function call to the proper service. Args: protocol ....... Your communication protocol of choice, e.g. TBinaryProtocol. serviceName .... The service name of the service communicating via this protocol. } constructor Create( const aProtocol : IProtocol; const aServiceName : string); { Prepends the service name to the function name, separated by SEPARATOR. Args: The original message. } procedure WriteMessageBegin( const msg: TThriftMessage); override; end; implementation constructor TMultiplexedProtocol.Create(const aProtocol: IProtocol; const aServiceName: string); begin ASSERT( aServiceName <> ''); inherited Create(aProtocol); FServiceName := aServiceName; end; procedure TMultiplexedProtocol.WriteMessageBegin( const msg: TThriftMessage); // Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR. var newMsg : TThriftMessage; begin case msg.Type_ of TMessageType.Call, TMessageType.Oneway : begin Init( newMsg, FServiceName + SEPARATOR + msg.Name, msg.Type_, msg.SeqID); inherited WriteMessageBegin( newMsg); end; else inherited WriteMessageBegin( msg); end; end; end. thrift-0.23.0/lib/delphi/src/Thrift.pas0000664000175000017500000002703515170007142020131 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift; interface uses SysUtils, Thrift.Utils, Thrift.Exception, Thrift.Protocol; const Version = '0.23.0'; type TException = Thrift.Exception.TException; // compatibility alias TApplicationExceptionSpecializedClass = class of TApplicationExceptionSpecialized; TApplicationException = class( TException, IBase, ISupportsToString) public type {$SCOPEDENUMS ON} TExceptionType = ( Unknown, UnknownMethod, InvalidMessageType, WrongMethodName, BadSequenceID, MissingResult, InternalError, ProtocolError, InvalidTransform, InvalidProtocol, UnsupportedClientType ); {$SCOPEDENUMS OFF} strict private FExceptionType : TExceptionType; strict protected function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; strict protected constructor HiddenCreate(const Msg: string); class function GetSpecializedExceptionType(AType: TExceptionType): TApplicationExceptionSpecializedClass; public // purposefully hide inherited constructor class function Create(const Msg: string): TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)'; class function Create: TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)'; class function Create( AType: TExceptionType): TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)'; class function Create( AType: TExceptionType; const msg: string): TApplicationException; overload; deprecated 'Use specialized TApplicationException types (or regenerate from IDL)'; function Type_: TExceptionType; virtual; procedure IBase_Read( const iprot: IProtocol); procedure IBase.Read = IBase_Read; class function Read( const iprot: IProtocol): TApplicationException; procedure Write( const oprot: IProtocol ); end; // Needed to remove deprecation warning TApplicationExceptionSpecialized = class abstract (TApplicationException) strict protected class function GetType: TApplicationException.TExceptionType; virtual; abstract; public constructor Create(const Msg: string); function Type_: TApplicationException.TExceptionType; override; end; TApplicationExceptionUnknown = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionUnknownMethod = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionInvalidMessageType = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionWrongMethodName = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionBadSequenceID = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionMissingResult = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionInternalError = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionProtocolError = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionInvalidTransform = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionInvalidProtocol = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; TApplicationExceptionUnsupportedClientType = class (TApplicationExceptionSpecialized) strict protected class function GetType: TApplicationException.TExceptionType; override; end; implementation { TApplicationException } constructor TApplicationException.HiddenCreate(const Msg: string); begin inherited Create(Msg); end; class function TApplicationException.Create(const Msg: string): TApplicationException; begin Result := TApplicationExceptionUnknown.Create(Msg); end; class function TApplicationException.Create: TApplicationException; begin Result := TApplicationExceptionUnknown.Create(''); end; class function TApplicationException.Create( AType: TExceptionType): TApplicationException; begin {$WARN SYMBOL_DEPRECATED OFF} Result := Create(AType, ''); {$WARN SYMBOL_DEPRECATED DEFAULT} end; class function TApplicationException.Create( AType: TExceptionType; const msg: string): TApplicationException; begin Result := GetSpecializedExceptionType(AType).Create(msg); end; function TApplicationException.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID, Obj) then result := S_OK else result := E_NOINTERFACE; end; function TApplicationException._AddRef: Integer; begin result := -1; // not refcounted end; function TApplicationException._Release: Integer; begin result := -1; // not refcounted end; function TApplicationException.Type_: TExceptionType; begin result := FExceptionType; end; class function TApplicationException.GetSpecializedExceptionType(AType: TExceptionType): TApplicationExceptionSpecializedClass; begin case AType of TExceptionType.UnknownMethod: Result := TApplicationExceptionUnknownMethod; TExceptionType.InvalidMessageType: Result := TApplicationExceptionInvalidMessageType; TExceptionType.WrongMethodName: Result := TApplicationExceptionWrongMethodName; TExceptionType.BadSequenceID: Result := TApplicationExceptionBadSequenceID; TExceptionType.MissingResult: Result := TApplicationExceptionMissingResult; TExceptionType.InternalError: Result := TApplicationExceptionInternalError; TExceptionType.ProtocolError: Result := TApplicationExceptionProtocolError; TExceptionType.InvalidTransform: Result := TApplicationExceptionInvalidTransform; TExceptionType.InvalidProtocol: Result := TApplicationExceptionInvalidProtocol; TExceptionType.UnsupportedClientType: Result := TApplicationExceptionUnsupportedClientType; else ASSERT( TExceptionType.Unknown = aType); Result := TApplicationExceptionUnknown; end; end; procedure TApplicationException.IBase_Read( const iprot: IProtocol); var field : TThriftField; struc : TThriftStruct; begin struc := iprot.ReadStructBegin; while ( True ) do begin field := iprot.ReadFieldBegin; if ( field.Type_ = TType.Stop) then begin Break; end; case field.Id of 1 : begin if ( field.Type_ = TType.String_) then begin Exception(Self).Message := iprot.ReadString; end else begin TProtocolUtil.Skip( iprot, field.Type_ ); end; end; 2 : begin if ( field.Type_ = TType.I32) then begin FExceptionType := TExceptionType( iprot.ReadI32 ); end else begin TProtocolUtil.Skip( iprot, field.Type_ ); end; end else begin TProtocolUtil.Skip( iprot, field.Type_); end; end; iprot.ReadFieldEnd; end; iprot.ReadStructEnd; end; class function TApplicationException.Read( const iprot: IProtocol): TApplicationException; var instance : TApplicationException; base : IBase; begin instance := TApplicationException.CreateFmt('',[]); try if Supports( instance, IBase, base) then try base.Read(iprot); finally base := nil; // clear ref before free end; result := GetSpecializedExceptionType(instance.Type_).Create( Exception(instance).Message); finally instance.Free; end; end; procedure TApplicationException.Write( const oprot: IProtocol); var struc : TThriftStruct; field : TThriftField; begin Init(struc, 'TApplicationException'); Init(field); oprot.WriteStructBegin( struc ); if Message <> '' then begin field.Name := 'message'; field.Type_ := TType.String_; field.Id := 1; oprot.WriteFieldBegin( field ); oprot.WriteString( Message ); oprot.WriteFieldEnd; end; field.Name := 'type'; field.Type_ := TType.I32; field.Id := 2; oprot.WriteFieldBegin(field); oprot.WriteI32(Integer(Type_)); oprot.WriteFieldEnd(); oprot.WriteFieldStop(); oprot.WriteStructEnd(); end; { TApplicationExceptionSpecialized } constructor TApplicationExceptionSpecialized.Create(const Msg: string); begin inherited HiddenCreate(Msg); end; function TApplicationExceptionSpecialized.Type_: TApplicationException.TExceptionType; begin result := GetType; end; { specialized TApplicationExceptions } class function TApplicationExceptionUnknownMethod.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.UnknownMethod; end; class function TApplicationExceptionInvalidMessageType.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.InvalidMessageType; end; class function TApplicationExceptionWrongMethodName.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.WrongMethodName; end; class function TApplicationExceptionBadSequenceID.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.BadSequenceID; end; class function TApplicationExceptionMissingResult.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.MissingResult; end; class function TApplicationExceptionInternalError.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.InternalError; end; class function TApplicationExceptionProtocolError.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.ProtocolError; end; class function TApplicationExceptionInvalidTransform.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.InvalidTransform; end; class function TApplicationExceptionInvalidProtocol.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.InvalidProtocol; end; class function TApplicationExceptionUnsupportedClientType.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.UnsupportedClientType; end; class function TApplicationExceptionUnknown.GetType : TApplicationException.TExceptionType; begin result := TExceptionType.Unknown; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Protocol.Compact.pas0000664000175000017500000010544215165535636023337 0ustar00buildbuild00000000000000(* * 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. *) {$SCOPEDENUMS ON} unit Thrift.Protocol.Compact; interface uses Classes, SysUtils, Math, Generics.Collections, Thrift.Configuration, Thrift.Transport, Thrift.Protocol, Thrift.Utils; type ICompactProtocol = interface( IProtocol) ['{C01927EC-021A-45F7-93B1-23D6A5420EDD}'] end; // Compact protocol implementation for thrift. // Adapted from the C# version. TCompactProtocolImpl = class( TProtocolImpl, ICompactProtocol) public type TFactory = class( TInterfacedObject, IProtocolFactory) public function GetProtocol( const trans: ITransport): IProtocol; end; strict private const { TODO static TStruct ANONYMOUS_STRUCT = new TStruct(""); static TField TSTOP = new TField("", TType.Stop, (short)0); } PROTOCOL_ID = Byte( $82); VERSION = Byte( 1); VERSION_MASK = Byte( $1F); // 0001 1111 TYPE_MASK = Byte( $E0); // 1110 0000 TYPE_BITS = Byte( $07); // 0000 0111 TYPE_SHIFT_AMOUNT = Byte( 5); strict private type // All of the on-wire type codes. Types = ( STOP = $00, BOOLEAN_TRUE = $01, BOOLEAN_FALSE = $02, BYTE_ = $03, I16 = $04, I32 = $05, I64 = $06, DOUBLE_ = $07, BINARY = $08, LIST = $09, SET_ = $0A, MAP = $0B, STRUCT = $0C, UUID = $0D ); private type TEightBytesArray = packed array[0..7] of Byte; strict private const ttypeToCompactType : array[TType] of Types = ( Types.STOP, // Stop = 0, Types(-1), // Void = 1, Types.BOOLEAN_TRUE, // Bool_ = 2, Types.BYTE_, // Byte_ = 3, Types.DOUBLE_, // Double_ = 4, Types(-5), // unused Types.I16, // I16 = 6, Types(-7), // unused Types.I32, // I32 = 8, Types(-9), // unused Types.I64, // I64 = 10, Types.BINARY, // String_ = 11, Types.STRUCT, // Struct = 12, Types.MAP, // Map = 13, Types.SET_, // Set_ = 14, Types.LIST, // List = 15, Types.UUID // Uuid = 16 ); tcompactTypeToType : array[Types] of TType = ( TType.Stop, // STOP TType.Bool_, // BOOLEAN_TRUE TType.Bool_, // BOOLEAN_FALSE TType.Byte_, // BYTE_ TType.I16, // I16 TType.I32, // I32 TType.I64, // I64 TType.Double_, // DOUBLE_ TType.String_, // BINARY TType.List, // LIST TType.Set_, // SET_ TType.Map, // MAP TType.Struct, // STRUCT TType.Uuid // UUID ); strict private // Used to keep track of the last field for the current and previous structs, // so we can do the delta stuff. lastField_ : TStack; lastFieldId_ : Integer; // If we encounter a boolean field begin, save the TField here so it can // have the value incorporated. strict private booleanField_ : TThriftField; // If we Read a field header, and it's a boolean field, save the boolean // value here so that ReadBool can use it. strict private boolValue_ : ( unused, bool_true, bool_false); public constructor Create(const trans : ITransport); override; destructor Destroy; override; strict private procedure WriteByteDirect( const b : Byte); overload; // Writes a byte without any possibility of all that field header nonsense. procedure WriteByteDirect( const n : Integer); overload; // Write an i32 as a varint. Results in 1-5 bytes on the wire. // TODO: make a permanent buffer like WriteVarint64? procedure WriteVarint32( n : Cardinal); strict private // The workhorse of WriteFieldBegin. It has the option of doing a 'type override' // of the type header. This is used specifically in the boolean field case. procedure WriteFieldBeginInternal( const field : TThriftField; typeOverride : Byte); public procedure WriteMessageBegin( const msg: TThriftMessage); override; procedure WriteMessageEnd; override; procedure WriteStructBegin( const struc: TThriftStruct); override; procedure WriteStructEnd; override; procedure WriteFieldBegin( const field: TThriftField); override; procedure WriteFieldEnd; override; procedure WriteFieldStop; override; procedure WriteMapBegin( const map: TThriftMap); override; procedure WriteMapEnd; override; procedure WriteListBegin( const list: TThriftList); override; procedure WriteListEnd(); override; procedure WriteSetBegin( const set_: TThriftSet ); override; procedure WriteSetEnd(); override; procedure WriteBool( b: Boolean); override; procedure WriteByte( b: ShortInt); override; procedure WriteI16( i16: SmallInt); override; procedure WriteI32( i32: Integer); override; 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 class function DoubleToInt64Bits( const db : Double) : Int64; class function Int64BitsToDouble( const i64 : Int64) : Double; // Abstract method for writing the start of lists and sets. List and sets on // the wire differ only by the type indicator. procedure WriteCollectionBegin( const elemType : TType; size : Integer); procedure WriteVarint64( n : UInt64); // Convert l into a zigzag long. This allows negative numbers to be // represented compactly as a varint. class function longToZigzag( const n : Int64) : UInt64; // Convert n into a zigzag int. This allows negative numbers to be // represented compactly as a varint. class function intToZigZag( const n : Integer) : Cardinal; //Convert a Int64 into little-endian bytes in buf starting at off and going until off+7. class procedure fixedLongToBytes( const n : Int64; var buf : TEightBytesArray); inline; strict protected function GetMinSerializedSize( const aType : TType) : Integer; override; procedure Reset; override; public function ReadMessageBegin: TThriftMessage; override; procedure ReadMessageEnd(); override; function ReadStructBegin: TThriftStruct; override; procedure ReadStructEnd; override; function ReadFieldBegin: TThriftField; override; procedure ReadFieldEnd(); override; function ReadMapBegin: TThriftMap; override; procedure ReadMapEnd(); override; function ReadListBegin: TThriftList; override; procedure ReadListEnd(); override; function ReadSetBegin: TThriftSet; override; procedure ReadSetEnd(); override; function ReadBool: Boolean; override; function ReadByte: ShortInt; override; function ReadI16: SmallInt; override; function ReadI32: Integer; override; function ReadI64: Int64; override; function ReadDouble:Double; override; function ReadBinary: TBytes; overload; override; function ReadUuid: TGuid; override; private // Internal Reading methods // 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. function ReadVarint32 : Cardinal; // 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. function ReadVarint64 : UInt64; // encoding helpers // Convert from zigzag Integer to Integer. class function zigzagToInt( const n : Cardinal ) : Integer; // Convert from zigzag Int64 to Int64. class function zigzagToLong( const n : UInt64) : Int64; // Note that it's important that the mask bytes are Int64 literals, // otherwise they'll default to ints, and when you shift an Integer left 56 bits, // you just get a messed up Integer. class function bytesToLong( const bytes : TEightBytesArray) : Int64; inline; // type testing and converting class function isBoolType( const b : byte) : Boolean; // Given a TCompactProtocol.Types constant, convert it to its corresponding TType value. class function getTType( const type_ : byte) : TType; // Given a TType value, find the appropriate TCompactProtocol.Types constant. class function getCompactType( const ttype : TType) : Byte; end; implementation //--- TCompactProtocolImpl.TFactory ---------------------------------------- function TCompactProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol; begin result := TCompactProtocolImpl.Create( trans); end; //--- TCompactProtocolImpl ------------------------------------------------- constructor TCompactProtocolImpl.Create( const trans : ITransport); begin inherited Create( trans); lastFieldId_ := 0; lastField_ := TStack.Create; Init( booleanField_, '', TType.Stop, 0); boolValue_ := unused; end; destructor TCompactProtocolImpl.Destroy; begin try FreeAndNil( lastField_); finally inherited Destroy; end; end; procedure TCompactProtocolImpl.Reset; begin inherited Reset; lastField_.Clear(); lastFieldId_ := 0; Init( booleanField_, '', TType.Stop, 0); boolValue_ := unused; end; // Writes a byte without any possibility of all that field header nonsense. // Used internally by other writing methods that know they need to Write a byte. procedure TCompactProtocolImpl.WriteByteDirect( const b : Byte); begin Transport.Write( @b, SizeOf(b)); end; // Writes a byte without any possibility of all that field header nonsense. procedure TCompactProtocolImpl.WriteByteDirect( const n : Integer); begin WriteByteDirect( Byte(n)); end; // Write an i32 as a varint. Results in 1-5 bytes on the wire. procedure TCompactProtocolImpl.WriteVarint32( n : Cardinal); var idx : Integer; i32buf : packed array[0..4] of Byte; begin idx := 0; while TRUE do begin ASSERT( idx < Length(i32buf)); // last part? if ((n and not $7F) = 0) then begin i32buf[idx] := Byte(n); Inc(idx); Break; end; i32buf[idx] := Byte((n and $7F) or $80); Inc(idx); n := n shr 7; end; Transport.Write( @i32buf[0], 0, idx); end; // Write a message header to the wire. Compact Protocol messages contain the // protocol version so we can migrate forwards in the future if need be. procedure TCompactProtocolImpl.WriteMessageBegin( const msg: TThriftMessage); var versionAndType : Byte; begin Reset; versionAndType := Byte( VERSION and VERSION_MASK) or Byte( (Cardinal(msg.Type_) shl TYPE_SHIFT_AMOUNT) and TYPE_MASK); WriteByteDirect( PROTOCOL_ID); WriteByteDirect( versionAndType); WriteVarint32( Cardinal(msg.SeqID)); WriteString( msg.Name); end; // Write a struct begin. This doesn't actually put anything on the wire. We use it as an // opportunity to put special placeholder markers on the field stack so we can get the // field id deltas correct. procedure TCompactProtocolImpl.WriteStructBegin( const struc: TThriftStruct); begin lastField_.Push(lastFieldId_); lastFieldId_ := 0; end; // Write a struct end. This doesn't actually put anything on the wire. We use this as an // opportunity to pop the last field from the current struct off of the field stack. procedure TCompactProtocolImpl.WriteStructEnd; begin lastFieldId_ := lastField_.Pop(); end; // Write a field header containing the field id and field type. If the difference between the // current field id and the last one is small (< 15), then the field id will be encoded in // the 4 MSB as a delta. Otherwise, the field id will follow the type header as a zigzag varint. procedure TCompactProtocolImpl.WriteFieldBegin( const field: TThriftField); begin case field.Type_ of TType.Bool_ : booleanField_ := field; // we want to possibly include the value, so we'll wait. else WriteFieldBeginInternal(field, $FF); end; end; // The workhorse of WriteFieldBegin. It has the option of doing a 'type override' // of the type header. This is used specifically in the boolean field case. procedure TCompactProtocolImpl.WriteFieldBeginInternal( const field : TThriftField; typeOverride : Byte); var typeToWrite : Byte; begin // if there's a type override, use that. if typeOverride = $FF then typeToWrite := getCompactType( field.Type_) else typeToWrite := typeOverride; // check if we can use delta encoding for the field id if (field.ID > lastFieldId_) and ((field.ID - lastFieldId_) <= 15) then begin // Write them together WriteByteDirect( ((field.ID - lastFieldId_) shl 4) or typeToWrite); end else begin // Write them separate WriteByteDirect( typeToWrite); WriteI16( field.ID); end; lastFieldId_ := field.ID; end; // Write the STOP symbol so we know there are no more fields in this struct. procedure TCompactProtocolImpl.WriteFieldStop; begin WriteByteDirect( Byte( Types.STOP)); end; // Write a map header. If the map is empty, omit the key and value type // headers, as we don't need any additional information to skip it. procedure TCompactProtocolImpl.WriteMapBegin( const map: TThriftMap); var key, val : Byte; begin if (map.Count = 0) then WriteByteDirect( 0) else begin WriteVarint32( Cardinal( map.Count)); key := getCompactType(map.KeyType); val := getCompactType(map.ValueType); WriteByteDirect( (key shl 4) or val); end; end; // Write a list header. procedure TCompactProtocolImpl.WriteListBegin( const list: TThriftList); begin WriteCollectionBegin( list.ElementType, list.Count); end; // Write a set header. procedure TCompactProtocolImpl.WriteSetBegin( const set_: TThriftSet ); begin WriteCollectionBegin( set_.ElementType, set_.Count); end; // Write a boolean value. Potentially, this could be a boolean field, in // which case the field header info isn't written yet. If so, decide what the // right type header is for the value and then Write the field header. // Otherwise, Write a single byte. procedure TCompactProtocolImpl.WriteBool( b: Boolean); var bt : Types; begin if b then bt := Types.BOOLEAN_TRUE else bt := Types.BOOLEAN_FALSE; if booleanField_.Type_ = TType.Bool_ then begin // we haven't written the field header yet WriteFieldBeginInternal( booleanField_, Byte(bt)); booleanField_.Type_ := TType.Stop; end else begin // we're not part of a field, so just Write the value. WriteByteDirect( Byte(bt)); end; end; // Write a byte. Nothing to see here! procedure TCompactProtocolImpl.WriteByte( b: ShortInt); begin WriteByteDirect( Byte(b)); end; // Write an I16 as a zigzag varint. procedure TCompactProtocolImpl.WriteI16( i16: SmallInt); begin WriteVarint32( intToZigZag( i16)); end; // Write an i32 as a zigzag varint. procedure TCompactProtocolImpl.WriteI32( i32: Integer); begin WriteVarint32( intToZigZag( i32)); end; // Write an i64 as a zigzag varint. procedure TCompactProtocolImpl.WriteI64( const i64: Int64); begin WriteVarint64( longToZigzag( i64)); end; class function TCompactProtocolImpl.DoubleToInt64Bits( const db : Double) : Int64; begin ASSERT( SizeOf(db) = SizeOf(result)); Move( db, result, SizeOf(result)); end; class function TCompactProtocolImpl.Int64BitsToDouble( const i64 : Int64) : Double; begin ASSERT( SizeOf(i64) = SizeOf(result)); Move( i64, result, SizeOf(result)); end; // Write a double to the wire as 8 bytes. procedure TCompactProtocolImpl.WriteDouble( const dub: Double); var data : TEightBytesArray; begin fixedLongToBytes( DoubleToInt64Bits(dub), data); Transport.Write( @data[0], 0, SizeOf(data)); end; // Write a byte array, using a varint for the size. procedure TCompactProtocolImpl.WriteBinary( const b: TBytes); begin WriteVarint32( Cardinal(Length(b))); 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 ASSERT( SizeOf(uuid) = 16); network := GuidUtils.SwapByteOrder(uuid); Transport.Write( @network, 0, SizeOf(network)); end; procedure TCompactProtocolImpl.WriteMessageEnd; begin // nothing to do end; procedure TCompactProtocolImpl.WriteMapEnd; begin // nothing to do end; procedure TCompactProtocolImpl.WriteListEnd; begin // nothing to do end; procedure TCompactProtocolImpl.WriteSetEnd; begin // nothing to do end; procedure TCompactProtocolImpl.WriteFieldEnd; begin // nothing to do end; // Abstract method for writing the start of lists and sets. List and sets on // the wire differ only by the type indicator. procedure TCompactProtocolImpl.WriteCollectionBegin( const elemType : TType; size : Integer); begin if size <= 14 then WriteByteDirect( (size shl 4) or getCompactType(elemType)) else begin WriteByteDirect( $F0 or getCompactType(elemType)); WriteVarint32( Cardinal(size)); end; end; // Write an i64 as a varint. Results in 1-10 bytes on the wire. procedure TCompactProtocolImpl.WriteVarint64( n : UInt64); var idx : Integer; varint64out : packed array[0..9] of Byte; begin idx := 0; while TRUE do begin ASSERT( idx < Length(varint64out)); // last one? if (n and not UInt64($7F)) = 0 then begin varint64out[idx] := Byte(n); Inc(idx); Break; end; varint64out[idx] := Byte((n and $7F) or $80); Inc(idx); n := n shr 7; end; Transport.Write( @varint64out[0], 0, idx); end; // Convert l into a zigzag Int64. This allows negative numbers to be // represented compactly as a varint. class function TCompactProtocolImpl.longToZigzag( const n : Int64) : UInt64; begin // there is no arithmetic right shift in Delphi if n >= 0 then result := UInt64(n shl 1) else result := UInt64(n shl 1) xor $FFFFFFFFFFFFFFFF; end; // Convert n into a zigzag Integer. This allows negative numbers to be // represented compactly as a varint. class function TCompactProtocolImpl.intToZigZag( const n : Integer) : Cardinal; begin // there is no arithmetic right shift in Delphi if n >= 0 then result := Cardinal(n shl 1) else result := Cardinal(n shl 1) xor $FFFFFFFF; end; // Convert a Int64 into 8 little-endian bytes in buf class procedure TCompactProtocolImpl.fixedLongToBytes( const n : Int64; var buf : TEightBytesArray); begin ASSERT( Length(buf) >= 8); buf[0] := Byte( n and $FF); buf[1] := Byte((n shr 8) and $FF); buf[2] := Byte((n shr 16) and $FF); buf[3] := Byte((n shr 24) and $FF); buf[4] := Byte((n shr 32) and $FF); buf[5] := Byte((n shr 40) and $FF); buf[6] := Byte((n shr 48) and $FF); buf[7] := Byte((n shr 56) and $FF); end; // Read a message header. function TCompactProtocolImpl.ReadMessageBegin : TThriftMessage; var protocolId, versionAndType, version, type_ : Byte; seqid : Integer; msgNm : String; begin Reset; protocolId := Byte( ReadByte); if (protocolId <> PROTOCOL_ID) then raise TProtocolExceptionBadVersion.Create( 'Expected protocol id ' + IntToHex(PROTOCOL_ID,2) + ' but got ' + IntToHex(protocolId,2)); versionAndType := Byte( ReadByte); version := Byte( versionAndType and VERSION_MASK); if (version <> VERSION) then raise TProtocolExceptionBadVersion.Create( 'Expected version ' +IntToStr(VERSION) + ' but got ' + IntToStr(version)); type_ := Byte( (versionAndType shr TYPE_SHIFT_AMOUNT) and TYPE_BITS); seqid := Integer( ReadVarint32); msgNm := ReadString; Init( result, msgNm, TMessageType(type_), seqid); end; // Read a struct begin. There's nothing on the wire for this, but it is our // opportunity to push a new struct begin marker onto the field stack. function TCompactProtocolImpl.ReadStructBegin: TThriftStruct; begin lastField_.Push( lastFieldId_); lastFieldId_ := 0; Init( result); end; // Doesn't actually consume any wire data, just removes the last field for // this struct from the field stack. procedure TCompactProtocolImpl.ReadStructEnd; begin // consume the last field we Read off the wire. lastFieldId_ := lastField_.Pop(); end; // Read a field header off the wire. function TCompactProtocolImpl.ReadFieldBegin: TThriftField; var type_ : Byte; modifier : ShortInt; fieldId : SmallInt; begin type_ := Byte( ReadByte); // if it's a stop, then we can return immediately, as the struct is over. if type_ = Byte(Types.STOP) then begin Init( result, '', TType.Stop, 0); Exit; end; // mask off the 4 MSB of the type header. it could contain a field id delta. modifier := ShortInt( (type_ and $F0) shr 4); if (modifier = 0) then fieldId := ReadI16 // not a delta. look ahead for the zigzag varint field id. else fieldId := SmallInt( lastFieldId_ + modifier); // add the delta to the last Read field id. Init( result, '', getTType(Byte(type_ and $0F)), fieldId); // if this happens to be a boolean field, the value is encoded in the type // save the boolean value in a special instance variable. if isBoolType(type_) then begin if Byte(type_ and $0F) = Byte(Types.BOOLEAN_TRUE) then boolValue_ := bool_true else boolValue_ := bool_false; end; // push the new field onto the field stack so we can keep the deltas going. lastFieldId_ := result.ID; end; // Read a map header off the wire. If the size is zero, skip Reading the key // and value type. This means that 0-length maps will yield TMaps without the // "correct" types. function TCompactProtocolImpl.ReadMapBegin: TThriftMap; var size : Integer; keyAndValueType : Byte; key, val : TType; begin size := Integer( ReadVarint32); if size = 0 then keyAndValueType := 0 else keyAndValueType := Byte( ReadByte); key := getTType( Byte( keyAndValueType shr 4)); val := getTType( Byte( keyAndValueType and $F)); Init( result, key, val, size); ASSERT( (result.KeyType = key) and (result.ValueType = val)); CheckReadBytesAvailable(result); end; // Read a list header off the wire. If the list size is 0-14, the size will // be packed into the element type header. If it's a longer list, the 4 MSB // of the element type header will be $F, and a varint will follow with the // true size. function TCompactProtocolImpl.ReadListBegin: TThriftList; var size_and_type : Byte; size : Integer; type_ : TType; begin size_and_type := Byte( ReadByte); size := (size_and_type shr 4) and $0F; if (size = 15) then size := Integer( ReadVarint32); type_ := getTType( size_and_type); Init( result, type_, size); CheckReadBytesAvailable(result); end; // Read a set header off the wire. If the set size is 0-14, the size will // be packed into the element type header. If it's a longer set, the 4 MSB // of the element type header will be $F, and a varint will follow with the // true size. function TCompactProtocolImpl.ReadSetBegin: TThriftSet; var size_and_type : Byte; size : Integer; type_ : TType; begin size_and_type := Byte( ReadByte); size := (size_and_type shr 4) and $0F; if (size = 15) then size := Integer( ReadVarint32); type_ := getTType( size_and_type); Init( result, type_, size); CheckReadBytesAvailable(result); end; // Read a boolean off the wire. If this is a boolean field, the value should // already have been Read during ReadFieldBegin, so we'll just consume the // pre-stored value. Otherwise, Read a byte. function TCompactProtocolImpl.ReadBool: Boolean; begin if boolValue_ <> unused then begin result := (boolValue_ = bool_true); boolValue_ := unused; Exit; end; result := (Byte(ReadByte) = Byte(Types.BOOLEAN_TRUE)); end; // Read a single byte off the wire. Nothing interesting here. function TCompactProtocolImpl.ReadByte: ShortInt; begin Transport.ReadAll( @result, SizeOf(result), 0, 1); end; // Read an i16 from the wire as a zigzag varint. function TCompactProtocolImpl.ReadI16: SmallInt; begin result := SmallInt( zigzagToInt( ReadVarint32)); end; // Read an i32 from the wire as a zigzag varint. function TCompactProtocolImpl.ReadI32: Integer; begin result := zigzagToInt( ReadVarint32); end; // Read an i64 from the wire as a zigzag varint. function TCompactProtocolImpl.ReadI64: Int64; begin result := zigzagToLong( ReadVarint64); end; // No magic here - just Read a double off the wire. function TCompactProtocolImpl.ReadDouble : Double; var longBits : TEightBytesArray; begin ASSERT( SizeOf(longBits) = SizeOf(result)); Transport.ReadAll( @longBits[0], SizeOf(longBits), 0, SizeOf(longBits)); result := Int64BitsToDouble( bytesToLong( longBits)); end; // Read a byte[] from the wire. function TCompactProtocolImpl.ReadBinary: TBytes; var length : Integer; begin length := Integer( ReadVarint32); FTrans.CheckReadBytesAvailable(length); SetLength( result, length); if (length > 0) then Transport.ReadAll( result, 0, length); end; function TCompactProtocolImpl.ReadUuid: TGuid; var network : TGuid; // in network order (Big Endian) begin ASSERT( SizeOf(result) = 16); FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network)); result := GuidUtils.SwapByteOrder(network); end; procedure TCompactProtocolImpl.ReadMessageEnd; begin // nothing to do end; procedure TCompactProtocolImpl.ReadFieldEnd; begin // nothing to do end; procedure TCompactProtocolImpl.ReadMapEnd; begin // nothing to do end; procedure TCompactProtocolImpl.ReadListEnd; begin // nothing to do end; procedure TCompactProtocolImpl.ReadSetEnd; begin // nothing to do end; // 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. function TCompactProtocolImpl.ReadVarint32 : Cardinal; var shift : Integer; b : Byte; begin result := 0; shift := 0; while TRUE do begin b := Byte( ReadByte); result := result or (Cardinal(b and $7F) shl shift); if ((b and $80) <> $80) then Break; Inc( shift, 7); end; end; // 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. function TCompactProtocolImpl.ReadVarint64 : UInt64; var shift : Integer; b : Byte; begin result := 0; shift := 0; while TRUE do begin b := Byte( ReadByte); result := result or (UInt64(b and $7F) shl shift); if ((b and $80) <> $80) then Break; Inc( shift, 7); end; end; // Convert from zigzag Integer to Integer. class function TCompactProtocolImpl.zigzagToInt( const n : Cardinal ) : Integer; begin result := Integer(n shr 1) xor (-Integer(n and 1)); end; // Convert from zigzag Int64 to Int64. class function TCompactProtocolImpl.zigzagToLong( const n : UInt64) : Int64; begin result := Int64(n shr 1) xor (-Int64(n and 1)); end; // Note that it's important that the mask bytes are Int64 literals, // otherwise they'll default to ints, and when you shift an Integer left 56 bits, // you just get a messed up Integer. class function TCompactProtocolImpl.bytesToLong( const bytes : TEightBytesArray) : Int64; begin ASSERT( Length(bytes) >= 8); result := (Int64(bytes[7] and $FF) shl 56) or (Int64(bytes[6] and $FF) shl 48) or (Int64(bytes[5] and $FF) shl 40) or (Int64(bytes[4] and $FF) shl 32) or (Int64(bytes[3] and $FF) shl 24) or (Int64(bytes[2] and $FF) shl 16) or (Int64(bytes[1] and $FF) shl 8) or (Int64(bytes[0] and $FF)); end; class function TCompactProtocolImpl.isBoolType( const b : byte) : Boolean; var lowerNibble : Byte; begin lowerNibble := b and $0f; result := (Types(lowerNibble) in [Types.BOOLEAN_TRUE, Types.BOOLEAN_FALSE]); end; // Given a TCompactProtocol.Types constant, convert it to its corresponding TType value. class function TCompactProtocolImpl.getTType( const type_ : byte) : TType; var tct : Types; begin tct := Types( type_ and $0F); if tct in [Low(Types)..High(Types)] then result := tcompactTypeToType[tct] else raise TProtocolExceptionInvalidData.Create('don''t know what type: '+IntToStr(Ord(tct))); end; // Given a TType value, find the appropriate TCompactProtocol.Types constant. class function TCompactProtocolImpl.getCompactType( const ttype : TType) : Byte; begin if ttype in VALID_TTYPES then result := Byte( ttypeToCompactType[ttype]) else raise TProtocolExceptionInvalidData.Create('don''t know what type: '+IntToStr(Ord(ttype))); end; function TCompactProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer; // Return the minimum number of bytes a type will consume on the wire begin case aType of TType.Stop: result := 1; // T_STOP needs to count itself TType.Void: result := 1; // T_VOID needs to count itself TType.Bool_: result := SizeOf(Byte); TType.Byte_: result := SizeOf(Byte); TType.Double_: result := 8; // uses fixedLongToBytes() which always writes 8 bytes TType.I16: result := SizeOf(Byte); TType.I32: result := SizeOf(Byte); TType.I64: result := SizeOf(Byte); TType.String_: result := SizeOf(Byte); // string length TType.Struct: result := 1; // empty struct needs at least 1 byte for the T_STOP TType.Map: result := SizeOf(Byte); // element count TType.Set_: result := SizeOf(Byte); // element count TType.List: result := SizeOf(Byte); // element count TType.Uuid: result := SizeOf(TGuid); else raise TTransportExceptionBadArgs.Create('Unhandled type code'); end; end; //--- unit tests ------------------------------------------- {$IFDEF Debug} procedure TestDoubleToInt64Bits; procedure TestPair( const a : Double; const b : Int64); begin ASSERT( TCompactProtocolImpl.DoubleToInt64Bits(a) = b); ASSERT( TCompactProtocolImpl.Int64BitsToDouble(b) = a); end; begin TestPair( 1.0000000000000000E+000, Int64($3FF0000000000000)); TestPair( 1.5000000000000000E+001, Int64($402E000000000000)); TestPair( 2.5500000000000000E+002, Int64($406FE00000000000)); TestPair( 4.2949672950000000E+009, Int64($41EFFFFFFFE00000)); TestPair( 3.9062500000000000E-003, Int64($3F70000000000000)); TestPair( 2.3283064365386963E-010, Int64($3DF0000000000000)); TestPair( 1.2345678901230000E-300, Int64($01AA74FE1C1E7E45)); TestPair( 1.2345678901234500E-150, Int64($20D02A36586DB4BB)); TestPair( 1.2345678901234565E+000, Int64($3FF3C0CA428C59FA)); TestPair( 1.2345678901234567E+000, Int64($3FF3C0CA428C59FB)); TestPair( 1.2345678901234569E+000, Int64($3FF3C0CA428C59FC)); TestPair( 1.2345678901234569E+150, Int64($5F182344CD3CDF9F)); TestPair( 1.2345678901234569E+300, Int64($7E3D7EE8BCBBD352)); TestPair( -1.7976931348623157E+308, Int64($FFEFFFFFFFFFFFFF)); TestPair( 1.7976931348623157E+308, Int64($7FEFFFFFFFFFFFFF)); TestPair( 4.9406564584124654E-324, Int64($0000000000000001)); TestPair( 0.0000000000000000E+000, Int64($0000000000000000)); TestPair( 4.94065645841247E-324, Int64($0000000000000001)); TestPair( 3.2378592100206092E-319, Int64($000000000000FFFF)); TestPair( 1.3906711615669959E-309, Int64($0000FFFFFFFFFFFF)); TestPair( NegInfinity, Int64($FFF0000000000000)); TestPair( Infinity, Int64($7FF0000000000000)); // NaN is special ASSERT( TCompactProtocolImpl.DoubleToInt64Bits( NaN) = Int64($FFF8000000000000)); ASSERT( IsNan( TCompactProtocolImpl.Int64BitsToDouble( Int64($FFF8000000000000)))); end; {$ENDIF} {$IFDEF Debug} procedure TestZigZag; procedure Test32( const test : Integer); var zz : Cardinal; begin zz := TCompactProtocolImpl.intToZigZag(test); ASSERT( TCompactProtocolImpl.zigzagToInt(zz) = test, IntToStr(test)); end; procedure Test64( const test : Int64); var zz : UInt64; begin zz := TCompactProtocolImpl.longToZigzag(test); ASSERT( TCompactProtocolImpl.zigzagToLong(zz) = test, IntToStr(test)); end; var i : Integer; begin // protobuf testcases ASSERT( TCompactProtocolImpl.intToZigZag(0) = 0, 'pb #1 to ZigZag'); ASSERT( TCompactProtocolImpl.intToZigZag(-1) = 1, 'pb #2 to ZigZag'); ASSERT( TCompactProtocolImpl.intToZigZag(1) = 2, 'pb #3 to ZigZag'); ASSERT( TCompactProtocolImpl.intToZigZag(-2) = 3, 'pb #4 to ZigZag'); ASSERT( TCompactProtocolImpl.intToZigZag(+2147483647) = 4294967294, 'pb #5 to ZigZag'); ASSERT( TCompactProtocolImpl.intToZigZag(-2147483648) = 4294967295, 'pb #6 to ZigZag'); // protobuf testcases ASSERT( TCompactProtocolImpl.zigzagToInt(0) = 0, 'pb #1 from ZigZag'); ASSERT( TCompactProtocolImpl.zigzagToInt(1) = -1, 'pb #2 from ZigZag'); ASSERT( TCompactProtocolImpl.zigzagToInt(2) = 1, 'pb #3 from ZigZag'); ASSERT( TCompactProtocolImpl.zigzagToInt(3) = -2, 'pb #4 from ZigZag'); ASSERT( TCompactProtocolImpl.zigzagToInt(4294967294) = +2147483647, 'pb #5 from ZigZag'); ASSERT( TCompactProtocolImpl.zigzagToInt(4294967295) = -2147483648, 'pb #6 from ZigZag'); // back and forth 32 Test32( 0); for i := 0 to 30 do begin Test32( +(Integer(1) shl i)); Test32( -(Integer(1) shl i)); end; Test32( Integer($7FFFFFFF)); Test32( Integer($80000000)); // back and forth 64 Test64( 0); for i := 0 to 62 do begin Test64( +(Int64(1) shl i)); Test64( -(Int64(1) shl i)); end; Test64( Int64($7FFFFFFFFFFFFFFF)); Test64( Int64($8000000000000000)); end; {$ENDIF} {$IFDEF Debug} procedure TestLongBytes; procedure Test( const test : Int64); var buf : TCompactProtocolImpl.TEightBytesArray; begin TCompactProtocolImpl.fixedLongToBytes( test, buf); ASSERT( TCompactProtocolImpl.bytesToLong( buf) = test, IntToStr(test)); end; var i : Integer; begin Test( 0); for i := 0 to 62 do begin Test( +(Int64(1) shl i)); Test( -(Int64(1) shl i)); end; Test( Int64($7FFFFFFFFFFFFFFF)); Test( Int64($8000000000000000)); end; {$ENDIF} {$IFDEF Debug} procedure UnitTest; var w : WORD; const FPU_CW_DENORMALIZED = $0002; begin w := Get8087CW; try Set8087CW( w or FPU_CW_DENORMALIZED); TestDoubleToInt64Bits; TestZigZag; TestLongBytes; finally Set8087CW( w); end; end; {$ENDIF} initialization {$IFDEF Debug} UnitTest; {$ENDIF} end. thrift-0.23.0/lib/delphi/src/Thrift.Processor.Multiplex.pas0000664000175000017500000001720715165535636024113 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Processor.Multiplex; interface uses SysUtils, Generics.Collections, Thrift, Thrift.Protocol, Thrift.Protocol.Multiplex; { TMultiplexedProcessor is a TProcessor allowing a single TServer to provide multiple services. To do so, you instantiate the processor and then register additional processors with it, as shown in the following example: TMultiplexedProcessor processor = new TMultiplexedProcessor(); processor.registerProcessor( "Calculator", new Calculator.Processor(new CalculatorHandler())); processor.registerProcessor( "WeatherReport", new WeatherReport.Processor(new WeatherReportHandler())); TServerTransport t = new TServerSocket(9090); TSimpleServer server = new TSimpleServer(processor, t); server.serve(); } type IMultiplexedProcessor = interface( IProcessor) ['{807F9D19-6CF4-4789-840E-93E87A12EB63}'] // Register a service with this TMultiplexedProcessor. This allows us // to broker requests to individual services by using the service name // to select them at request time. procedure RegisterProcessor( const serviceName : String; const processor : IProcessor; const asDefault : Boolean = FALSE); end; TMultiplexedProcessorImpl = class( TInterfacedObject, IMultiplexedProcessor, IProcessor) strict private type // Our goal was to work with any protocol. In order to do that, we needed // to allow them to call readMessageBegin() and get a TMessage in exactly // the standard format, without the service name prepended to TMessage.name. TStoredMessageProtocol = class( TProtocolDecorator) strict private FMessageBegin : TThriftMessage; public constructor Create( const protocol : IProtocol; const aMsgBegin : TThriftMessage); function ReadMessageBegin: TThriftMessage; override; end; strict private FServiceProcessorMap : TDictionary; FDefaultProcessor : IProcessor; procedure Error( const oprot : IProtocol; const msg : TThriftMessage; extype : TApplicationExceptionSpecializedClass; const etxt : string); public constructor Create; destructor Destroy; override; // Register a service with this TMultiplexedProcessorImpl. This allows us // to broker requests to individual services by using the service name // to select them at request time. procedure RegisterProcessor( const serviceName : String; const processor : IProcessor; const asDefault : Boolean = FALSE); { This implementation of process performs the following steps: - Read the beginning of the message. - Extract the service name from the message. - Using the service name to locate the appropriate processor. - Dispatch to the processor, with a decorated instance of TProtocol that allows readMessageBegin() to return the original TMessage. An exception is thrown if the message type is not CALL or ONEWAY or if the service is unknown (or not properly registered). } function Process( const iprot, oprot: IProtocol; const events : IProcessorEvents = nil): Boolean; end; implementation constructor TMultiplexedProcessorImpl.TStoredMessageProtocol.Create( const protocol : IProtocol; const aMsgBegin : TThriftMessage); begin inherited Create( protocol); FMessageBegin := aMsgBegin; end; constructor TMultiplexedProcessorImpl.Create; begin inherited Create; FServiceProcessorMap := TDictionary.Create; end; destructor TMultiplexedProcessorImpl.Destroy; begin try FreeAndNil( FServiceProcessorMap); finally inherited Destroy; end; end; function TMultiplexedProcessorImpl.TStoredMessageProtocol.ReadMessageBegin: TThriftMessage; begin Reset; result := FMessageBegin; end; procedure TMultiplexedProcessorImpl.RegisterProcessor( const serviceName : String; const processor : IProcessor; const asDefault : Boolean); begin FServiceProcessorMap.Add( serviceName, processor); if asDefault then begin if FDefaultProcessor = nil then FDefaultProcessor := processor else raise TApplicationExceptionInternalError.Create('Only one default service allowed'); end; end; procedure TMultiplexedProcessorImpl.Error( const oprot : IProtocol; const msg : TThriftMessage; extype : TApplicationExceptionSpecializedClass; const etxt : string); var appex : TApplicationException; newMsg : TThriftMessage; begin appex := extype.Create(etxt); try Init( newMsg, msg.Name, TMessageType.Exception, msg.SeqID); oprot.WriteMessageBegin(newMsg); appex.Write(oprot); oprot.WriteMessageEnd(); oprot.Transport.Flush(); finally appex.Free; end; end; function TMultiplexedProcessorImpl.Process(const iprot, oprot : IProtocol; const events : IProcessorEvents = nil): Boolean; var msg, newMsg : TThriftMessage; idx : Integer; sService : string; processor : IProcessor; protocol : IProtocol; const ERROR_INVALID_MSGTYPE = 'Message must be "call" or "oneway"'; ERROR_INCOMPATIBLE_PROT = 'No service name found in "%s". Client is expected to use TMultiplexProtocol.'; ERROR_UNKNOWN_SERVICE = 'Service "%s" is not registered with MultiplexedProcessor'; begin // Use the actual underlying protocol (e.g. TBinaryProtocol) to read the message header. // This pulls the message "off the wire", which we'll deal with at the end of this method. msg := iprot.readMessageBegin(); if not (msg.Type_ in [TMessageType.Call, TMessageType.Oneway]) then begin Error( oprot, msg, TApplicationExceptionInvalidMessageType, ERROR_INVALID_MSGTYPE); Exit( FALSE); end; // Extract the service name // use FDefaultProcessor as fallback if there is no separator idx := Pos( TMultiplexedProtocol.SEPARATOR, msg.Name); if idx > 0 then begin // Create a new TMessage, something that can be consumed by any TProtocol sService := Copy( msg.Name, 1, idx-1); if not FServiceProcessorMap.TryGetValue( sService, processor) then begin Error( oprot, msg, TApplicationExceptionInternalError, Format(ERROR_UNKNOWN_SERVICE,[sService])); Exit( FALSE); end; // Create a new TMessage, removing the service name Inc( idx, Length(TMultiplexedProtocol.SEPARATOR)); Init( newMsg, Copy( msg.Name, idx, MAXINT), msg.Type_, msg.SeqID); end else if FDefaultProcessor <> nil then begin processor := FDefaultProcessor; newMsg := msg; // no need to change end else begin Error( oprot, msg, TApplicationExceptionInvalidProtocol, Format(ERROR_INCOMPATIBLE_PROT,[msg.Name])); Exit( FALSE); end; // Dispatch processing to the stored processor protocol := TStoredMessageProtocol.Create( iprot, newMsg); result := processor.process( protocol, oprot, events); end; end. thrift-0.23.0/lib/delphi/src/Thrift.Transport.WinHTTP.pas0000664000175000017500000003044715165535636023403 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Transport.WinHTTP; {$I Thrift.Defines.inc} {$SCOPEDENUMS ON} interface uses Classes, SysUtils, Math, Generics.Collections, Thrift.Collections, Thrift.Configuration, Thrift.Transport, Thrift.Exception, Thrift.Utils, Thrift.WinHTTP, Thrift.Stream; type TWinHTTPClientImpl = class( TEndpointTransportBase, IHTTPClient) strict private FUri : string; FInputStream : IThriftStream; FOutputMemoryStream : TThriftMemoryStream; FDnsResolveTimeout : Integer; FConnectionTimeout : Integer; FSendTimeout : Integer; FReadTimeout : Integer; FCustomHeaders : IThriftDictionary; FSecureProtocols : TSecureProtocols; function CreateRequest: IWinHTTPRequest; function SecureProtocolsAsWinHTTPFlags : Cardinal; class procedure EnsureSuccessHttpStatus( const aRequest : IWinHTTPRequest); strict private type TErrorInfo = ( SplitUrl, WinHTTPSession, WinHTTPConnection, WinHTTPRequest, RequestSetup, AutoProxy ); THTTPResponseStream = class( TThriftStreamImpl) strict private FRequest : IWinHTTPRequest; strict protected procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); override; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override; procedure Open; override; procedure Close; override; procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; public constructor Create( const aRequest : IWinHTTPRequest); destructor Destroy; override; end; strict protected function GetIsOpen: Boolean; override; procedure Open(); override; procedure Close(); override; function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override; procedure Write( const pBuf : Pointer; off, len : Integer); override; procedure Flush; override; procedure SetDnsResolveTimeout(const Value: Integer); function GetDnsResolveTimeout: Integer; procedure SetConnectionTimeout(const Value: Integer); function GetConnectionTimeout: Integer; procedure SetSendTimeout(const Value: Integer); function GetSendTimeout: Integer; procedure SetReadTimeout(const Value: Integer); function GetReadTimeout: Integer; function GetSecureProtocols : TSecureProtocols; procedure SetSecureProtocols( const value : TSecureProtocols); function GetCustomHeaders: IThriftDictionary; procedure SendRequest; property DnsResolveTimeout: Integer read GetDnsResolveTimeout write SetDnsResolveTimeout; property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout; property SendTimeout: Integer read GetSendTimeout write SetSendTimeout; property ReadTimeout: Integer read GetReadTimeout write SetReadTimeout; property CustomHeaders: IThriftDictionary read GetCustomHeaders; public constructor Create( const aUri: string; const aConfig : IThriftConfiguration = nil); destructor Destroy; override; end; implementation const WINHTTP_CONNECTION_TIMEOUT = 60 * 1000; WINHTTP_SENDRECV_TIMEOUT = 30 * 1000; { TWinHTTPClientImpl } constructor TWinHTTPClientImpl.Create( const aUri: string; const aConfig : IThriftConfiguration); begin inherited Create( aConfig); FUri := AUri; // defaults according to MSDN FDnsResolveTimeout := 0; // no timeout FConnectionTimeout := WINHTTP_CONNECTION_TIMEOUT; FSendTimeout := WINHTTP_SENDRECV_TIMEOUT; FReadTimeout := WINHTTP_SENDRECV_TIMEOUT; FSecureProtocols := DEFAULT_THRIFT_SECUREPROTOCOLS; FCustomHeaders := TThriftDictionaryImpl.Create; FOutputMemoryStream := TThriftMemoryStream.Create; end; destructor TWinHTTPClientImpl.Destroy; begin Close; FreeAndNil( FOutputMemoryStream); inherited; end; function TWinHTTPClientImpl.CreateRequest: IWinHTTPRequest; var pair : TPair; session : IWinHTTPSession; connect : IWinHTTPConnection; url : IWinHTTPUrl; sPath : string; info : TErrorInfo; begin info := TErrorInfo.SplitUrl; try url := TWinHTTPUrlImpl.Create( FUri); info := TErrorInfo.WinHTTPSession; session := TWinHTTPSessionImpl.Create('ApacheThriftDelphi/WinHTTP'); session.EnableSecureProtocols( SecureProtocolsAsWinHTTPFlags); info := TErrorInfo.WinHTTPConnection; connect := session.Connect( url.HostName, url.Port); info := TErrorInfo.WinHTTPRequest; sPath := url.UrlPath + url.ExtraInfo; result := connect.OpenRequest( (url.Scheme = 'https'), 'POST', sPath, THRIFT_MIMETYPE); // setting a timeout value to 0 (zero) means "no timeout" for that setting info := TErrorInfo.RequestSetup; result.SetTimeouts( DnsResolveTimeout, ConnectionTimeout, SendTimeout, ReadTimeout); // headers result.AddRequestHeader( 'Content-Type: '+THRIFT_MIMETYPE, WINHTTP_ADDREQ_FLAG_ADD); for pair in FCustomHeaders do begin Result.AddRequestHeader( pair.Key +': '+ pair.Value, WINHTTP_ADDREQ_FLAG_ADD); end; // enable automatic gzip,deflate decompression result.EnableAutomaticContentDecompression(TRUE); // AutoProxy support info := TErrorInfo.AutoProxy; result.TryAutoProxy( FUri); except on e:TException do raise; on e:Exception do raise TTransportExceptionUnknown.Create( e.Message+' (at '+EnumUtils.ToString(Ord(info))+')'); end; end; function TWinHTTPClientImpl.SecureProtocolsAsWinHTTPFlags : Cardinal; const PROTOCOL_MAPPING : array[TSecureProtocol] of Cardinal = ( WINHTTP_FLAG_SECURE_PROTOCOL_SSL2, WINHTTP_FLAG_SECURE_PROTOCOL_SSL3, WINHTTP_FLAG_SECURE_PROTOCOL_TLS1, WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1, WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2, WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 ); var prot : TSecureProtocol; protos : TSecureProtocols; begin result := 0; protos := GetSecureProtocols; for prot := Low(TSecureProtocol) to High(TSecureProtocol) do begin if prot in protos then result := result or PROTOCOL_MAPPING[prot]; end; end; function TWinHTTPClientImpl.GetDnsResolveTimeout: Integer; begin Result := FDnsResolveTimeout; end; procedure TWinHTTPClientImpl.SetDnsResolveTimeout(const Value: Integer); begin FDnsResolveTimeout := Value; end; function TWinHTTPClientImpl.GetConnectionTimeout: Integer; begin Result := FConnectionTimeout; end; procedure TWinHTTPClientImpl.SetConnectionTimeout(const Value: Integer); begin FConnectionTimeout := Value; end; function TWinHTTPClientImpl.GetSendTimeout: Integer; begin Result := FSendTimeout; end; procedure TWinHTTPClientImpl.SetSendTimeout(const Value: Integer); begin FSendTimeout := Value; end; function TWinHTTPClientImpl.GetReadTimeout: Integer; begin Result := FReadTimeout; end; procedure TWinHTTPClientImpl.SetReadTimeout(const Value: Integer); begin FReadTimeout := Value; end; function TWinHTTPClientImpl.GetSecureProtocols : TSecureProtocols; begin Result := FSecureProtocols; end; procedure TWinHTTPClientImpl.SetSecureProtocols( const value : TSecureProtocols); begin FSecureProtocols := Value; end; function TWinHTTPClientImpl.GetCustomHeaders: IThriftDictionary; begin Result := FCustomHeaders; end; function TWinHTTPClientImpl.GetIsOpen: Boolean; begin Result := Assigned( FOutputMemoryStream); end; procedure TWinHTTPClientImpl.Open; begin FreeAndNil( FOutputMemoryStream); FOutputMemoryStream := TThriftMemoryStream.Create; end; procedure TWinHTTPClientImpl.Close; begin FInputStream := nil; FreeAndNil( FOutputMemoryStream); end; procedure TWinHTTPClientImpl.Flush; begin try SendRequest; finally FreeAndNil( FOutputMemoryStream); FOutputMemoryStream := TThriftMemoryStream.Create; ASSERT( FOutputMemoryStream <> nil); end; end; function TWinHTTPClientImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; begin if FInputStream = nil then begin raise TTransportExceptionNotOpen.Create('No request has been sent'); end; try Result := FInputStream.Read( pBuf, buflen, off, len); CountConsumedMessageBytes( result); except on E: Exception do raise TTransportExceptionUnknown.Create(E.Message); end; end; procedure TWinHTTPClientImpl.SendRequest; var http : IWinHTTPRequest; pData : PByte; len : Integer; error, dwSize : Cardinal; sMsg : string; begin http := CreateRequest; pData := FOutputMemoryStream.Memory; len := FOutputMemoryStream.Size; // send all data immediately, since we have it in memory if not http.SendRequest( pData, len, 0) then begin error := Cardinal( GetLastError); sMsg := 'WinHTTP send error '+IntToStr(Int64(error))+' '+WinHttpSysErrorMessage(error); raise TTransportExceptionUnknown.Create(sMsg); end; // end request and start receiving if not http.FlushAndReceiveResponse then begin error := Cardinal( GetLastError); sMsg := 'WinHTTP recv error '+IntToStr(Int64(error))+' '+WinHttpSysErrorMessage(error); if error = ERROR_WINHTTP_TIMEOUT then raise TTransportExceptionTimedOut.Create( sMsg) else raise TTransportExceptionInterrupted.Create( sMsg); end; // we're about to receive a new message, so reset everyting ResetMessageSizeAndConsumedBytes(-1); EnsureSuccessHttpStatus(http); // throws if not FInputStream := THTTPResponseStream.Create( http); if http.QueryTotalResponseSize( dwSize) // FALSE indicates "no info available" then UpdateKnownMessageSize( dwSize); end; procedure TWinHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer); var pTmp : PByte; begin pTmp := pBuf; Inc(pTmp,off); FOutputMemoryStream.Write( pTmp^, len); 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); begin inherited Create; FRequest := aRequest; end; destructor TWinHTTPClientImpl.THTTPResponseStream.Destroy; begin try Close; finally inherited Destroy; end; end; procedure TWinHTTPClientImpl.THTTPResponseStream.Close; begin FRequest := nil; end; procedure TWinHTTPClientImpl.THTTPResponseStream.Flush; begin raise ENotImplemented(ClassName+'.Flush'); end; function TWinHTTPClientImpl.THTTPResponseStream.IsOpen: Boolean; begin Result := FRequest <> nil; end; procedure TWinHTTPClientImpl.THTTPResponseStream.Open; begin // nothing to do end; procedure TWinHTTPClientImpl.THTTPResponseStream.Write(const pBuf : Pointer; offset, count: Integer); begin inherited; // check pointers raise ENotImplemented(ClassName+'.Write'); end; function TWinHTTPClientImpl.THTTPResponseStream.Read(const pBuf : Pointer; const buflen : Integer; offset, count: Integer): Integer; var pTmp : PByte; begin inherited; // check pointers if count >= buflen-offset then count := buflen-offset; if count > 0 then begin pTmp := pBuf; Inc( pTmp, offset); Result := FRequest.ReadData( pTmp, count); ASSERT( Result >= 0); end else Result := 0; end; function TWinHTTPClientImpl.THTTPResponseStream.ToArray: TBytes; begin raise ENotImplemented(ClassName+'.ToArray'); end; end. thrift-0.23.0/lib/delphi/src/Thrift.Transport.Pipes.pas0000664000175000017500000010526115165535636023223 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Transport.Pipes; {$WARN SYMBOL_PLATFORM OFF} {$I Thrift.Defines.inc} interface uses {$IFDEF OLD_UNIT_NAMES} Windows, SysUtils, Math, AccCtrl, AclAPI, SyncObjs, {$ELSE} Winapi.Windows, System.SysUtils, System.Math, Winapi.AccCtrl, Winapi.AclAPI, System.SyncObjs, {$ENDIF} Thrift.Configuration, Thrift.Transport, Thrift.Utils, Thrift.Stream; const DEFAULT_THRIFT_PIPE_OPEN_TIMEOUT = 10; // default: fail fast on open type //--- Pipe Streams --- TPipeStreamBase = class( TThriftStreamImpl) strict protected FPipe : THandle; FTimeout : DWORD; FOpenTimeOut : DWORD; // separate value to allow for fail-fast-on-open scenarios FOverlapped : Boolean; procedure Write( const pBuf : Pointer; offset, count : Integer); override; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override; //procedure Open; override; - see derived classes procedure Close; override; procedure Flush; override; function ReadDirect( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; overload; function ReadOverlapped( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; overload; procedure WriteDirect( const pBuf : Pointer; offset: Integer; count: Integer); overload; procedure WriteOverlapped( const pBuf : Pointer; offset: Integer; count: Integer); overload; function IsOpen: Boolean; override; function ToArray: TBytes; override; public constructor Create( aEnableOverlapped : Boolean; const aTimeOut : DWORD = DEFAULT_THRIFT_TIMEOUT; const aOpenTimeOut : DWORD = DEFAULT_THRIFT_PIPE_OPEN_TIMEOUT ); reintroduce; overload; destructor Destroy; override; end; TNamedPipeStreamImpl = class sealed( TPipeStreamBase) strict private FPipeName : string; FShareMode : DWORD; FSecurityAttribs : PSecurityAttributes; strict protected procedure Open; override; public constructor Create( const aPipeName : string; const aEnableOverlapped : Boolean; const aShareMode: DWORD = 0; const aSecurityAttributes: PSecurityAttributes = nil; const aTimeOut : DWORD = DEFAULT_THRIFT_TIMEOUT; const aOpenTimeOut : DWORD = DEFAULT_THRIFT_PIPE_OPEN_TIMEOUT ); reintroduce; overload; end; THandlePipeStreamImpl = class sealed( TPipeStreamBase) strict private FSrcHandle : THandle; strict protected procedure Open; override; public constructor Create( const aPipeHandle : THandle; const aOwnsHandle, aEnableOverlapped : Boolean; const aTimeOut : DWORD = DEFAULT_THRIFT_TIMEOUT ); reintroduce; overload; destructor Destroy; override; end; //--- Pipe Transports --- IPipeTransport = interface( IStreamTransport) ['{5E05CC85-434F-428F-BFB2-856A168B5558}'] end; TPipeTransportBase = class( TStreamTransportImpl, IPipeTransport) strict protected // ITransport function GetIsOpen: Boolean; override; procedure Open; override; procedure Close; override; end; TNamedPipeTransportClientEndImpl = class( TPipeTransportBase) public // Named pipe constructors constructor Create( const aPipe : THandle; const aOwnsHandle : Boolean; const aTimeOut : DWORD; const aConfig : IThriftConfiguration = nil ); reintroduce; overload; constructor Create( const aPipeName : string; const aShareMode: DWORD = 0; const aSecurityAttributes: PSecurityAttributes = nil; const aTimeOut : DWORD = DEFAULT_THRIFT_TIMEOUT; const aOpenTimeOut : DWORD = DEFAULT_THRIFT_PIPE_OPEN_TIMEOUT; const aConfig : IThriftConfiguration = nil ); reintroduce; overload; end; TNamedPipeTransportServerEndImpl = class( TNamedPipeTransportClientEndImpl) strict private FHandle : THandle; strict protected // ITransport procedure Close; override; public constructor Create( const aPipe : THandle; const aOwnsHandle : Boolean; const aTimeOut : DWORD = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil ); reintroduce; overload; end; TAnonymousPipeTransportImpl = class( TPipeTransportBase) public // Anonymous pipe constructor constructor Create( const aPipeRead, aPipeWrite : THandle; const aOwnsHandles : Boolean; const aTimeOut : DWORD = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil ); reintroduce; overload; end; //--- Server Transports --- IAnonymousPipeServerTransport = interface( IServerTransport) ['{7AEE6793-47B9-4E49-981A-C39E9108E9AD}'] // Server side anonymous pipe ends function ReadHandle : THandle; function WriteHandle : THandle; // Client side anonymous pipe ends function ClientAnonRead : THandle; function ClientAnonWrite : THandle; end; INamedPipeServerTransport = interface( IServerTransport) ['{9DF9EE48-D065-40AF-8F67-D33037D3D960}'] function Handle : THandle; end; TPipeServerTransportBase = class( TServerTransportImpl) strict protected FStopServer : TEvent; procedure InternalClose; virtual; abstract; function QueryStopServer : Boolean; public constructor Create( const aConfig : IThriftConfiguration); destructor Destroy; override; procedure Listen; override; procedure Close; override; end; TAnonymousPipeServerTransportImpl = class( TPipeServerTransportBase, IAnonymousPipeServerTransport) strict private FBufSize : DWORD; // Server side anonymous pipe handles FReadHandle, FWriteHandle : THandle; //Client side anonymous pipe handles FClientAnonRead, FClientAnonWrite : THandle; FTimeOut: DWORD; strict protected function Accept(const fnAccepting: TProc): ITransport; override; function CreateAnonPipe : Boolean; // IAnonymousPipeServerTransport function ReadHandle : THandle; function WriteHandle : THandle; function ClientAnonRead : THandle; function ClientAnonWrite : THandle; procedure InternalClose; override; public constructor Create( const aBufsize : Cardinal = 4096; const aTimeOut : DWORD = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil ); reintroduce; overload; end; TNamedPipeFlag = ( OnlyLocalClients // sets PIPE_REJECT_REMOTE_CLIENTS ); TNamedPipeFlags = set of TNamedPipeFlag; TNamedPipeServerTransportImpl = class( TPipeServerTransportBase, INamedPipeServerTransport) strict private FPipeName : string; FMaxConns : DWORD; FBufSize : DWORD; FTimeout : DWORD; FHandle : THandle; FConnected : Boolean; FOnlyLocalClients : Boolean; strict protected function Accept(const fnAccepting: TProc): ITransport; override; function CreateNamedPipe : THandle; function CreateTransportInstance : ITransport; // INamedPipeServerTransport function Handle : THandle; procedure InternalClose; override; public constructor Create( const aPipename : string; const aBufsize : Cardinal = 4096; const aMaxConns : Cardinal = PIPE_UNLIMITED_INSTANCES; const aTimeOut : Cardinal = INFINITE; const aConfig : IThriftConfiguration = nil ); reintroduce; overload; deprecated 'use the other CTOR instead'; constructor Create( const aPipename : string; const aFlags : TNamedPipeFlags; const aConfig : IThriftConfiguration = nil; const aBufsize : Cardinal = 4096; const aMaxConns : Cardinal = PIPE_UNLIMITED_INSTANCES; const aTimeOut : Cardinal = INFINITE ); reintroduce; overload; end; implementation const // flags used but not declared in all Delphi versions, see MSDN PIPE_ACCEPT_REMOTE_CLIENTS = 0; // CreateNamedPipe() -> dwPipeMode = default PIPE_REJECT_REMOTE_CLIENTS = $00000008; // CreateNamedPipe() -> dwPipeMode // Windows platfoms only // https://github.com/dotnet/coreclr/pull/379/files // https://referencesource.microsoft.com/#System.Runtime.Remoting/channels/ipc/win32namedpipes.cs,46b96e3f3828f497,references // Citation from the first source: // > For mitigating local elevation of privilege attack through named pipes // > make sure we always call CreateFile with SECURITY_ANONYMOUS so that the // > named pipe server can't impersonate a high privileged client security context {$IFDEF MSWINDOWS} PREVENT_PIPE_IMPERSONATION = SECURITY_SQOS_PRESENT or SECURITY_ANONYMOUS; {$ELSE} PREVENT_PIPE_IMPERSONATION = 0; // not available on Linux etc {$ENDIF} procedure ClosePipeHandle( var hPipe : THandle); begin if hPipe <> INVALID_HANDLE_VALUE then try CloseHandle( hPipe); finally hPipe := INVALID_HANDLE_VALUE; end; end; function DuplicatePipeHandle( const hSource : THandle) : THandle; begin if not DuplicateHandle( GetCurrentProcess, hSource, GetCurrentProcess, @result, 0, FALSE, DUPLICATE_SAME_ACCESS) then raise TTransportExceptionNotOpen.Create('DuplicateHandle: '+SysErrorMessage(GetLastError)); end; { TPipeStreamBase } constructor TPipeStreamBase.Create( aEnableOverlapped : Boolean; const aTimeOut, aOpenTimeOut : DWORD); begin inherited Create; FPipe := INVALID_HANDLE_VALUE; FTimeout := aTimeOut; FOpenTimeOut := aOpenTimeOut; FOverlapped := aEnableOverlapped; ASSERT( FTimeout > 0); // FOpenTimeout may be 0 end; destructor TPipeStreamBase.Destroy; begin try Close; finally inherited Destroy; end; end; procedure TPipeStreamBase.Close; begin ClosePipeHandle( FPipe); end; procedure TPipeStreamBase.Flush; begin FlushFileBuffers( FPipe); end; function TPipeStreamBase.IsOpen: Boolean; begin result := (FPipe <> INVALID_HANDLE_VALUE); end; procedure TPipeStreamBase.Write( const pBuf : Pointer; offset, count : Integer); begin if FOverlapped then WriteOverlapped( pBuf, offset, count) else WriteDirect( pBuf, offset, count); end; function TPipeStreamBase.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; begin if FOverlapped then result := ReadOverlapped( pBuf, buflen, offset, count) else result := ReadDirect( pBuf, buflen, offset, count); end; procedure TPipeStreamBase.WriteDirect( const pBuf : Pointer; offset: Integer; count: Integer); var cbWritten, nBytes : DWORD; pData : PByte; begin if not IsOpen then raise TTransportExceptionNotOpen.Create('Called write on non-open pipe'); // if necessary, send the data in chunks // there's a system limit around 0x10000 bytes that we hit otherwise // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section." nBytes := Min( 15*4096, count); // 16 would exceed the limit pData := pBuf; Inc( pData, offset); while nBytes > 0 do begin if not WriteFile( FPipe, pData^, nBytes, cbWritten, nil) then raise TTransportExceptionNotOpen.Create('Write to pipe failed'); Inc( pData, cbWritten); Dec( count, cbWritten); nBytes := Min( nBytes, count); end; end; procedure TPipeStreamBase.WriteOverlapped( const pBuf : Pointer; offset: Integer; count: Integer); var cbWritten, dwWait, dwError, nBytes : DWORD; overlapped : IOverlappedHelper; pData : PByte; begin if not IsOpen then raise TTransportExceptionNotOpen.Create('Called write on non-open pipe'); // if necessary, send the data in chunks // there's a system limit around 0x10000 bytes that we hit otherwise // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section." nBytes := Min( 15*4096, count); // 16 would exceed the limit pData := pBuf; Inc( pData, offset); while nBytes > 0 do begin overlapped := TOverlappedHelperImpl.Create; if not WriteFile( FPipe, pData^, nBytes, cbWritten, overlapped.OverlappedPtr) then begin dwError := GetLastError; case dwError of ERROR_IO_PENDING : begin dwWait := overlapped.WaitFor(FTimeout); if (dwWait = WAIT_TIMEOUT) then begin CancelIo( FPipe); // prevents possible AV on invalid overlapped ptr raise TTransportExceptionTimedOut.Create('Pipe write timed out'); end; if (dwWait <> WAIT_OBJECT_0) or not GetOverlappedResult( FPipe, overlapped.Overlapped, cbWritten, TRUE) then raise TTransportExceptionUnknown.Create('Pipe write error'); end; else raise TTransportExceptionUnknown.Create(SysErrorMessage(dwError)); end; end; ASSERT( DWORD(nBytes) = cbWritten); Inc( pData, cbWritten); Dec( count, cbWritten); nBytes := Min( nBytes, count); end; end; function TPipeStreamBase.ReadDirect( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; var cbRead, dwErr, nRemaining : DWORD; bytes, retries : LongInt; bOk : Boolean; pData : PByte; const INTERVAL = 10; // ms begin if not IsOpen then raise TTransportExceptionNotOpen.Create('Called read on non-open pipe'); // MSDN: Handle can be a handle to a named pipe instance, // or it can be a handle to the read end of an anonymous pipe, // The handle must have GENERIC_READ access to the pipe. if FTimeOut <> INFINITE then begin retries := Max( 1, Round( 1.0 * FTimeOut / INTERVAL)); while TRUE do begin if not PeekNamedPipe( FPipe, nil, 0, nil, @bytes, nil) then begin dwErr := GetLastError; if (dwErr = ERROR_INVALID_HANDLE) or (dwErr = ERROR_BROKEN_PIPE) or (dwErr = ERROR_PIPE_NOT_CONNECTED) then begin result := 0; // other side closed the pipe Exit; end; end else if bytes > 0 then begin Break; // there are data end; Dec( retries); if retries > 0 then Sleep( INTERVAL) else raise TTransportExceptionTimedOut.Create('Pipe read timed out'); end; end; result := 0; nRemaining := count; pData := pBuf; Inc( pData, offset); while nRemaining > 0 do begin // read the data (or block INFINITE-ly) bOk := ReadFile( FPipe, pData^, nRemaining, cbRead, nil); if (not bOk) and (GetLastError() <> ERROR_MORE_DATA) then Break; // No more data, possibly because client disconnected. Dec( nRemaining, cbRead); Inc( pData, cbRead); Inc( result, cbRead); end; end; function TPipeStreamBase.ReadOverlapped( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; var cbRead, dwWait, dwError, nRemaining : DWORD; bOk : Boolean; overlapped : IOverlappedHelper; pData : PByte; begin if not IsOpen then raise TTransportExceptionNotOpen.Create('Called read on non-open pipe'); result := 0; nRemaining := count; pData := pBuf; Inc( pData, offset); while nRemaining > 0 do begin overlapped := TOverlappedHelperImpl.Create; // read the data bOk := ReadFile( FPipe, pData^, nRemaining, cbRead, overlapped.OverlappedPtr); if not bOk then begin dwError := GetLastError; case dwError of ERROR_IO_PENDING : begin dwWait := overlapped.WaitFor(FTimeout); if (dwWait = WAIT_TIMEOUT) then begin CancelIo( FPipe); // prevents possible AV on invalid overlapped ptr raise TTransportExceptionTimedOut.Create('Pipe read timed out'); end; if (dwWait <> WAIT_OBJECT_0) or not GetOverlappedResult( FPipe, overlapped.Overlapped, cbRead, TRUE) then raise TTransportExceptionUnknown.Create('Pipe read error'); end; else raise TTransportExceptionUnknown.Create(SysErrorMessage(dwError)); end; end; ASSERT( cbRead > 0); // see TTransportImpl.ReadAll() ASSERT( cbRead <= DWORD(nRemaining)); Dec( nRemaining, cbRead); Inc( pData, cbRead); Inc( result, cbRead); end; end; function TPipeStreamBase.ToArray: TBytes; var bytes : LongInt; begin SetLength( result, 0); bytes := 0; if IsOpen and PeekNamedPipe( FPipe, nil, 0, nil, @bytes, nil) and (bytes > 0) then begin SetLength( result, bytes); Read( result, 0, bytes); end; end; { TNamedPipeStreamImpl } constructor TNamedPipeStreamImpl.Create( const aPipeName : string; const aEnableOverlapped : Boolean; const aShareMode: DWORD; const aSecurityAttributes: PSecurityAttributes; const aTimeOut, aOpenTimeOut : DWORD); begin inherited Create( aEnableOverlapped, aTimeOut, aOpenTimeOut); FPipeName := aPipeName; FShareMode := aShareMode; FSecurityAttribs := aSecurityAttributes; if Copy(FPipeName,1,2) <> '\\' then FPipeName := '\\.\pipe\' + FPipeName; // assume localhost end; procedure TNamedPipeStreamImpl.Open; var hPipe : THandle; retries, timeout, dwErr, dwFlagsAndAttributes : DWORD; const INTERVAL = 10; // ms begin if IsOpen then Exit; retries := Max( 1, Round( 1.0 * FOpenTimeOut / INTERVAL)); timeout := FOpenTimeOut; // if the server hasn't gotten to the point where the pipe has been created, at least wait the timeout // According to MSDN, if no instances of the specified named pipe exist, the WaitNamedPipe function // returns IMMEDIATELY, regardless of the time-out value. // Always use INTERVAL, since WaitNamedPipe(0) defaults to some other value while not WaitNamedPipe( PChar(FPipeName), INTERVAL) do begin dwErr := GetLastError; if dwErr <> ERROR_FILE_NOT_FOUND then raise TTransportExceptionNotOpen.Create('Unable to open pipe, '+SysErrorMessage(dwErr)); if timeout <> INFINITE then begin if (retries > 0) then Dec(retries) else raise TTransportExceptionNotOpen.Create('Unable to open pipe, timed out'); end; Sleep(INTERVAL) end; dwFlagsAndAttributes := FILE_FLAG_OVERLAPPED or FILE_FLAG_WRITE_THROUGH // async+fast, please or PREVENT_PIPE_IMPERSONATION; // open that thingy hPipe := CreateFile( PChar( FPipeName), GENERIC_READ or GENERIC_WRITE, FShareMode, // sharing FSecurityAttribs, // security attributes OPEN_EXISTING, // opens existing pipe dwFlagsAndAttributes, // flags + attribs 0); // no template file if hPipe = INVALID_HANDLE_VALUE then raise TTransportExceptionNotOpen.Create('Unable to open pipe, '+SysErrorMessage(GetLastError)); // everything fine FPipe := hPipe; end; { THandlePipeStreamImpl } constructor THandlePipeStreamImpl.Create( const aPipeHandle : THandle; const aOwnsHandle, aEnableOverlapped : Boolean; const aTimeOut : DWORD); begin inherited Create( aEnableOverlapped, aTimeout, aTimeout); if aOwnsHandle then FSrcHandle := aPipeHandle else FSrcHandle := DuplicatePipeHandle( aPipeHandle); Open; end; destructor THandlePipeStreamImpl.Destroy; begin try ClosePipeHandle( FSrcHandle); finally inherited Destroy; end; end; procedure THandlePipeStreamImpl.Open; begin if not IsOpen then FPipe := DuplicatePipeHandle( FSrcHandle); end; { TPipeTransportBase } function TPipeTransportBase.GetIsOpen: Boolean; begin result := (InputStream <> nil) and (InputStream.IsOpen) and (OutputStream <> nil) and (OutputStream.IsOpen); end; procedure TPipeTransportBase.Open; begin InputStream.Open; OutputStream.Open; end; procedure TPipeTransportBase.Close; begin InputStream.Close; OutputStream.Close; end; { TNamedPipeTransportClientEndImpl } constructor TNamedPipeTransportClientEndImpl.Create( const aPipeName : string; const aShareMode: DWORD; const aSecurityAttributes: PSecurityAttributes; const aTimeOut, aOpenTimeOut : DWORD; const aConfig : IThriftConfiguration); // Named pipe constructor begin inherited Create( nil, nil, aConfig); SetInputStream( TNamedPipeStreamImpl.Create( aPipeName, TRUE, aShareMode, aSecurityAttributes, aTimeOut, aOpenTimeOut)); SetOutputStream( InputStream); // true for named pipes end; constructor TNamedPipeTransportClientEndImpl.Create( const aPipe : THandle; const aOwnsHandle : Boolean; const aTimeOut : DWORD; const aConfig : IThriftConfiguration); // Named pipe constructor begin inherited Create( nil, nil, aConfig); SetInputStream( THandlePipeStreamImpl.Create( aPipe, aOwnsHandle, TRUE, aTimeOut)); SetOutputStream( InputStream); // true for named pipes end; { TNamedPipeTransportServerEndImpl } constructor TNamedPipeTransportServerEndImpl.Create( const aPipe : THandle; const aOwnsHandle : Boolean; const aTimeOut : DWORD; const aConfig : IThriftConfiguration); // Named pipe constructor begin FHandle := DuplicatePipeHandle( aPipe); inherited Create( aPipe, aOwnsHandle, aTimeout, aConfig); end; procedure TNamedPipeTransportServerEndImpl.Close; begin FlushFileBuffers( FHandle); DisconnectNamedPipe( FHandle); // force client off the pipe ClosePipeHandle( FHandle); inherited Close; end; { TAnonymousPipeTransportImpl } constructor TAnonymousPipeTransportImpl.Create( const aPipeRead, aPipeWrite : THandle; const aOwnsHandles : Boolean; const aTimeOut : DWORD; const aConfig : IThriftConfiguration); // Anonymous pipe constructor begin inherited Create( nil, nil, aConfig); // overlapped is not supported with AnonPipes, see MSDN SetInputStream( THandlePipeStreamImpl.Create( aPipeRead, aOwnsHandles, FALSE, aTimeout)); SetOutputStream( THandlePipeStreamImpl.Create( aPipeWrite, aOwnsHandles, FALSE, aTimeout)); end; { TPipeServerTransportBase } constructor TPipeServerTransportBase.Create( const aConfig : IThriftConfiguration); begin inherited Create( aConfig); FStopServer := TEvent.Create(nil,TRUE,FALSE,''); // manual reset end; destructor TPipeServerTransportBase.Destroy; begin try FreeAndNil( FStopServer); finally inherited Destroy; end; end; function TPipeServerTransportBase.QueryStopServer : Boolean; begin result := (FStopServer = nil) or (FStopServer.WaitFor(0) <> wrTimeout); end; procedure TPipeServerTransportBase.Listen; begin FStopServer.ResetEvent; end; procedure TPipeServerTransportBase.Close; begin FStopServer.SetEvent; InternalClose; end; { TAnonymousPipeServerTransportImpl } constructor TAnonymousPipeServerTransportImpl.Create( const aBufsize : Cardinal; const aTimeOut : DWORD; const aConfig : IThriftConfiguration); // Anonymous pipe CTOR begin inherited Create(aConfig); FBufsize := aBufSize; FReadHandle := INVALID_HANDLE_VALUE; FWriteHandle := INVALID_HANDLE_VALUE; FClientAnonRead := INVALID_HANDLE_VALUE; FClientAnonWrite := INVALID_HANDLE_VALUE; FTimeOut := aTimeOut; // The anonymous pipe needs to be created first so that the server can // pass the handles on to the client before the serve (acceptImpl) // blocking call. if not CreateAnonPipe then raise TTransportExceptionNotOpen.Create(ClassName+'.Create() failed'); end; function TAnonymousPipeServerTransportImpl.Accept(const fnAccepting: TProc): ITransport; var buf : Byte; br : DWORD; begin if Assigned(fnAccepting) then fnAccepting(); // This 0-byte read serves merely as a blocking call. if not ReadFile( FReadHandle, buf, 0, br, nil) and (GetLastError() <> ERROR_MORE_DATA) then raise TTransportExceptionNotOpen.Create('TServerPipe unable to initiate pipe communication'); // create the transport impl result := TAnonymousPipeTransportImpl.Create( FReadHandle, FWriteHandle, FALSE, FTimeOut, Configuration); end; procedure TAnonymousPipeServerTransportImpl.InternalClose; begin ClosePipeHandle( FReadHandle); ClosePipeHandle( FWriteHandle); ClosePipeHandle( FClientAnonRead); ClosePipeHandle( FClientAnonWrite); end; function TAnonymousPipeServerTransportImpl.ReadHandle : THandle; begin result := FReadHandle; end; function TAnonymousPipeServerTransportImpl.WriteHandle : THandle; begin result := FWriteHandle; end; function TAnonymousPipeServerTransportImpl.ClientAnonRead : THandle; begin result := FClientAnonRead; end; function TAnonymousPipeServerTransportImpl.ClientAnonWrite : THandle; begin result := FClientAnonWrite; end; function TAnonymousPipeServerTransportImpl.CreateAnonPipe : Boolean; var sd : PSECURITY_DESCRIPTOR; sa : SECURITY_ATTRIBUTES; //TSecurityAttributes; hCAR, hPipeW, hCAW, hPipe : THandle; begin sd := PSECURITY_DESCRIPTOR( LocalAlloc( LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH)); try Win32Check( InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION)); Win32Check( SetSecurityDescriptorDacl( sd, TRUE, nil, FALSE)); sa.nLength := sizeof( sa); sa.lpSecurityDescriptor := sd; sa.bInheritHandle := TRUE; //allow passing handle to child Result := CreatePipe( hCAR, hPipeW, @sa, FBufSize); //create stdin pipe if not Result then begin //create stdin pipe raise TTransportExceptionNotOpen.Create('TServerPipe CreatePipe (anon) failed, '+SysErrorMessage(GetLastError)); Exit; end; Result := CreatePipe( hPipe, hCAW, @sa, FBufSize); //create stdout pipe if not Result then begin //create stdout pipe CloseHandle( hCAR); CloseHandle( hPipeW); raise TTransportExceptionNotOpen.Create('TServerPipe CreatePipe (anon) failed, '+SysErrorMessage(GetLastError)); Exit; end; FClientAnonRead := hCAR; FClientAnonWrite := hCAW; FReadHandle := hPipe; FWriteHandle := hPipeW; finally if sd <> nil then LocalFree( NativeUInt(sd)); end; end; { TNamedPipeServerTransportImpl } constructor TNamedPipeServerTransportImpl.Create( const aPipename : string; const aFlags : TNamedPipeFlags; const aConfig : IThriftConfiguration; const aBufsize, aMaxConns, aTimeOut : Cardinal); // Named Pipe CTOR begin inherited Create( aConfig); FPipeName := aPipename; FBufsize := aBufSize; FMaxConns := Max( 1, Min( PIPE_UNLIMITED_INSTANCES, aMaxConns)); FHandle := INVALID_HANDLE_VALUE; FTimeout := aTimeOut; FConnected := FALSE; ASSERT( FTimeout > 0); FOnlyLocalClients := (TNamedPipeFlag.OnlyLocalClients in aFlags); if Copy(FPipeName,1,2) <> '\\' then FPipeName := '\\.\pipe\' + FPipeName; // assume localhost end; constructor TNamedPipeServerTransportImpl.Create( const aPipename : string; const aBufsize, aMaxConns, aTimeOut : Cardinal; const aConfig : IThriftConfiguration); // Named Pipe CTOR (deprecated) begin {$WARN SYMBOL_DEPRECATED OFF} // Delphi XE emits a false warning here Create( aPipeName, [], aConfig, aBufsize, aMaxConns, aTimeOut); {$WARN SYMBOL_DEPRECATED ON} end; function TNamedPipeServerTransportImpl.Accept(const fnAccepting: TProc): ITransport; var dwError, dwWait, dwDummy : DWORD; overlapped : IOverlappedHelper; handles : array[0..1] of THandle; begin overlapped := TOverlappedHelperImpl.Create; ASSERT( not FConnected); CreateNamedPipe; while not FConnected do begin if QueryStopServer then begin InternalClose; Abort; end; if Assigned(fnAccepting) then fnAccepting(); // Wait for the client to connect; if it succeeds, the // function returns a nonzero value. If the function returns // zero, GetLastError should return ERROR_PIPE_CONNECTED. if ConnectNamedPipe( Handle, overlapped.OverlappedPtr) then begin FConnected := TRUE; Break; end; // ConnectNamedPipe() returns FALSE for OverlappedIO, even if connected. // We have to check GetLastError() explicitly to find out dwError := GetLastError; case dwError of ERROR_PIPE_CONNECTED : begin FConnected := not QueryStopServer; // special case: pipe immediately connected end; ERROR_IO_PENDING : begin handles[0] := overlapped.WaitHandle; handles[1] := FStopServer.Handle; dwWait := WaitForMultipleObjects( 2, @handles, FALSE, FTimeout); FConnected := (dwWait = WAIT_OBJECT_0) and GetOverlappedResult( Handle, overlapped.Overlapped, dwDummy, TRUE) and not QueryStopServer; end; else InternalClose; raise TTransportExceptionNotOpen.Create('Client connection failed'); end; end; // create the transport impl result := CreateTransportInstance; end; function TNamedPipeServerTransportImpl.CreateTransportInstance : ITransport; // create the transport impl var hPipe : THandle; begin hPipe := THandle( InterlockedExchangePointer( Pointer(FHandle), Pointer(INVALID_HANDLE_VALUE))); try FConnected := FALSE; result := TNamedPipeTransportServerEndImpl.Create( hPipe, TRUE, FTimeout, Configuration); except ClosePipeHandle(hPipe); raise; end; end; procedure TNamedPipeServerTransportImpl.InternalClose; var hPipe : THandle; begin hPipe := THandle( InterlockedExchangePointer( Pointer(FHandle), Pointer(INVALID_HANDLE_VALUE))); if hPipe = INVALID_HANDLE_VALUE then Exit; try if FConnected then FlushFileBuffers( hPipe) else CancelIo( hPipe); DisconnectNamedPipe( hPipe); finally ClosePipeHandle( hPipe); FConnected := FALSE; end; end; function TNamedPipeServerTransportImpl.Handle : THandle; begin {$IFDEF WIN64} result := THandle( InterlockedExchangeAdd64( Int64(FHandle), 0)); {$ELSE} result := THandle( InterlockedExchangeAdd( Integer(FHandle), 0)); {$ENDIF} end; function TNamedPipeServerTransportImpl.CreateNamedPipe : THandle; var SIDAuthWorld : SID_IDENTIFIER_AUTHORITY ; everyone_sid : PSID; ea : EXPLICIT_ACCESS; acl : PACL; sd : PSECURITY_DESCRIPTOR; sa : SECURITY_ATTRIBUTES; dwPipeModeXtra : DWORD; const SECURITY_WORLD_SID_AUTHORITY : TSIDIdentifierAuthority = (Value : (0,0,0,0,0,1)); SECURITY_WORLD_RID = $00000000; begin sd := nil; everyone_sid := nil; try ASSERT( (FHandle = INVALID_HANDLE_VALUE) and not FConnected); // Windows - set security to allow non-elevated apps // to access pipes created by elevated apps. SIDAuthWorld := SECURITY_WORLD_SID_AUTHORITY; AllocateAndInitializeSid( SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, everyone_sid); ZeroMemory( @ea, SizeOf(ea)); ea.grfAccessPermissions := GENERIC_ALL; //SPECIFIC_RIGHTS_ALL or STANDARD_RIGHTS_ALL; ea.grfAccessMode := SET_ACCESS; ea.grfInheritance := NO_INHERITANCE; ea.Trustee.TrusteeForm := TRUSTEE_IS_SID; ea.Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName := PChar(everyone_sid); acl := nil; SetEntriesInAcl( 1, @ea, nil, acl); sd := PSECURITY_DESCRIPTOR( LocalAlloc( LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH)); Win32Check( InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION)); Win32Check( SetSecurityDescriptorDacl( sd, TRUE, acl, FALSE)); sa.nLength := SizeOf(sa); sa.lpSecurityDescriptor := sd; sa.bInheritHandle := FALSE; // any extra flags we want to add to dwPipeMode dwPipeModeXtra := 0; if FOnlyLocalClients then dwPipeModeXtra := dwPipeModeXtra or PIPE_REJECT_REMOTE_CLIENTS; // Create an instance of the named pipe {$IFDEF OLD_UNIT_NAMES} result := Windows.CreateNamedPipe( {$ELSE} result := Winapi.Windows.CreateNamedPipe( {$ENDIF} PChar( FPipeName), // pipe name PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED, // read/write access + async mode PIPE_TYPE_BYTE or PIPE_READMODE_BYTE or dwPipeModeXtra, // byte type pipe + byte read mode + extras FMaxConns, // max. instances FBufSize, // output buffer size FBufSize, // input buffer size FTimeout, // time-out, see MSDN @sa // default security attribute ); if( result <> INVALID_HANDLE_VALUE) then InterlockedExchangePointer( Pointer(FHandle), Pointer(result)) else raise TTransportExceptionNotOpen.Create('CreateNamedPipe() failed ' + IntToStr(GetLastError)); finally if sd <> nil then LocalFree( NativeUInt(sd)); if acl <> nil then LocalFree( NativeUInt(acl)); if everyone_sid <> nil then FreeSid(everyone_sid); end; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Socket.pas0000664000175000017500000014566615165535636021415 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Socket; {$I Thrift.Defines.inc} {$I-} // prevent annoying errors with default log delegate and no console interface {$IFNDEF OLD_SOCKETS} // not for OLD_SOCKETS uses Winapi.Windows, Winapi.Winsock2; const AI_PASSIVE = $00000001; // Socket address will be used in bind() call AI_CANONNAME = $00000002; // Return canonical name in first ai_canonname AI_NUMERICHOST = $00000004; // Nodename must be a numeric address string AI_NUMERICSERV = $00000008; // Servicename must be a numeric port number AI_ALL = $00000100; // Query both IP6 and IP4 with AI_V4MAPPED AI_ADDRCONFIG = $00000400; // Resolution only if global address configured AI_V4MAPPED = $00000800; // On v6 failure, query v4 and convert to V4MAPPED format AI_NON_AUTHORITATIVE = $00004000; // LUP_NON_AUTHORITATIVE AI_SECURE = $00008000; // LUP_SECURE AI_RETURN_PREFERRED_NAMES = $00010000; // LUP_RETURN_PREFERRED_NAMES AI_FQDN = $00020000; // Return the FQDN in ai_canonname AI_FILESERVER = $00040000; // Resolving fileserver name resolution type PAddrInfoA = ^TAddrInfoA; TAddrInfoA = record ai_flags: Integer; ai_family: Integer; ai_socktype: Integer; ai_protocol: Integer; ai_addrlen: NativeUInt; ai_canonname: PAnsiChar; ai_addr: PSockAddr; ai_next: PAddrInfoA; end; PAddrInfoW = ^TAddrInfoW; TAddrInfoW = record ai_flags: Integer; ai_family: Integer; ai_socktype: Integer; ai_protocol: Integer; ai_addrlen: NativeUInt; ai_canonname: PChar; ai_addr: PSockAddr; ai_next: PAddrInfoW; end; TAddressFamily = USHORT; TIn6Addr = record case Integer of 0: (_Byte: array[0..15] of UCHAR); 1: (_Word: array[0..7] of USHORT); end; TScopeId = record public Value: ULONG; strict private function GetBitField(Loc: Integer): Integer; inline; procedure SetBitField(Loc: Integer; const aValue: Integer); inline; public property Zone: Integer index $0028 read GetBitField write SetBitField; property Level: Integer index $2804 read GetBitField write SetBitField; end; TSockAddrIn6 = record sin6_family: TAddressFamily; sin6_port: USHORT; sin6_flowinfo: ULONG; sin6_addr: TIn6Addr; case Integer of 0: (sin6_scope_id: ULONG); 1: (sin6_scope_struct: TScopeId); end; PSockAddrIn6 = ^TSockAddrIn6; const NI_NOFQDN = $01; // Only return nodename portion for local hosts NI_NUMERICHOST = $02; // Return numeric form of the host's address NI_NAMEREQD = $04; // Error if the host's name not in DNS NI_NUMERICSERV = $08; // Return numeric form of the service (port #) NI_DGRAM = $10; // Service is a datagram service NI_MAXHOST = 1025; // Max size of a fully-qualified domain name NI_MAXSERV = 32; // Max size of a service name function getaddrinfo(pNodeName, pServiceName: PAnsiChar; const pHints: TAddrInfoA; var ppResult: PAddrInfoA): Integer; stdcall; function GetAddrInfoW(pNodeName, pServiceName: PWideChar; const pHints: TAddrInfoW; var ppResult: PAddrInfoW): Integer; stdcall; procedure freeaddrinfo(pAddrInfo: PAddrInfoA); stdcall; procedure FreeAddrInfoW(pAddrInfo: PAddrInfoW); stdcall; function getnameinfo(const pSockaddr: TSockAddr; SockaddrLength: Integer; pNodeBuffer: PAnsiChar; NodeBufferSize: DWORD; pServiceBuffer: PAnsiChar; ServiceBufferSize: DWORD; Flags: Integer): Integer; stdcall; function GetNameInfoW(const pSockaddr: TSockAddr; SockaddrLength: Integer; pNodeBuffer: PWideChar; NodeBufferSize: DWORD; pServiceBuffer: PWideChar; ServiceBufferSize: DWORD; Flags: Integer): Integer; stdcall; type TSmartPointerDestroyer = reference to procedure(Value: T); ISmartPointer = reference to function: T; TSmartPointer = class(TInterfacedObject, ISmartPointer) strict private FValue: T; FDestroyer: TSmartPointerDestroyer; public constructor Create(AValue: T; ADestroyer: TSmartPointerDestroyer); destructor Destroy; override; function Invoke: T; end; TBaseSocket = class abstract public type TLogDelegate = reference to procedure( const str: string); strict private FPort: Integer; FSocket: Winapi.Winsock2.TSocket; FSendTimeout, FRecvTimeout: Longword; FKeepAlive: Boolean; FLogDelegate: TLogDelegate; class constructor Create; class destructor Destroy; class procedure DefaultLogDelegate(const Str: string); strict protected type IGetAddrInfoWrapper = interface function Init: Integer; function GetRes: PAddrInfoW; property Res: PAddrInfoW read GetRes; end; TGetAddrInfoWrapper = class(TInterfacedObject, IGetAddrInfoWrapper) strict private FNode: string; FService: string; FHints, FRes: PAddrInfoW; public constructor Create(ANode, AService: string; AHints: PAddrInfoW); destructor Destroy; override; function Init: Integer; function GetRes: PAddrInfoW; property Res: PAddrInfoW read GetRes; end; strict protected procedure CommonInit; virtual; function CreateSocket(AAddress: string; APort: Integer): IGetAddrInfoWrapper; procedure SetRecvTimeout(ARecvTimeout: Longword); virtual; procedure SetSendTimeout(ASendTimeout: Longword); virtual; procedure SetKeepAlive(AKeepAlive: Boolean); virtual; procedure SetSocket(ASocket: Winapi.Winsock2.TSocket); property LogDelegate: TLogDelegate read FLogDelegate; public // // Constructs a new socket. Note that this does NOT actually connect the // socket. // constructor Create(ALogDelegate: TLogDelegate = nil); overload; constructor Create(APort: Integer; ALogDelegate: TLogDelegate = nil); overload; // // Destroys the socket object, closing it if necessary. // destructor Destroy; override; // // Shuts down communications on the socket // procedure Close; virtual; // The port that the socket is connected to property Port: Integer read FPort write FPort; // The receive timeout property RecvTimeout: Longword read FRecvTimeout write SetRecvTimeout; // The send timeout property SendTimeout: Longword read FSendTimeout write SetSendTimeout; // Set SO_KEEPALIVE property KeepAlive: Boolean read FKeepAlive write SetKeepAlive; // The underlying socket descriptor property Socket: Winapi.Winsock2.TSocket read FSocket write SetSocket; end; TSocket = class(TBaseSocket) strict private type TCachedPeerAddr = record case Integer of 0: (ipv4: TSockAddrIn); 1: (ipv6: TSockAddrIn6); end; strict private FHost: string; FPeerHost: string; FPeerAddress: string; FPeerPort: Integer; FInterruptListener: ISmartPointer; FConnTimeout: Longword; FLingerOn: Boolean; FLingerVal: Integer; FNoDelay: Boolean; FMaxRecvRetries: Longword; FCachedPeerAddr: TCachedPeerAddr; procedure InitPeerInfo; procedure OpenConnection(Res: TBaseSocket.IGetAddrInfoWrapper); procedure LocalOpen; procedure SetGenericTimeout(S: Winapi.Winsock2.TSocket; Timeout: Longword; OptName: Integer); function GetIsOpen: Boolean; procedure SetNoDelay(ANoDelay: Boolean); function GetSocketInfo: string; function GetPeerHost: string; function GetPeerAddress: string; function GetPeerPort: Integer; function GetOrigin: string; strict protected procedure CommonInit; override; procedure SetRecvTimeout(ARecvTimeout: Longword); override; procedure SetSendTimeout(ASendTimeout: Longword); override; procedure SetKeepAlive(AKeepAlive: Boolean); override; public // // Constructs a new socket. Note that this does NOT actually connect the // socket. // constructor Create(ALogDelegate: TBaseSocket.TLogDelegate = nil); overload; // // Constructs a new socket. Note that this does NOT actually connect the // socket. // // @param host An IP address or hostname to connect to // @param port The port to connect on // constructor Create(AHost: string; APort: Integer; ALogDelegate: TBaseSocket.TLogDelegate = nil); overload; // // Constructor to create socket from socket descriptor. // constructor Create(ASocket: Winapi.Winsock2.TSocket; ALogDelegate: TBaseSocket.TLogDelegate = nil); overload; // // Constructor to create socket from socket descriptor that // can be interrupted safely. // constructor Create(ASocket: Winapi.Winsock2.TSocket; AInterruptListener: ISmartPointer; ALogDelegate: TBaseSocket.TLogDelegate = nil); overload; // // Creates and opens the socket // // @throws ETransportationException If the socket could not connect // procedure Open; // // Shuts down communications on the socket // procedure Close; override; // // Reads from the underlying socket. // \returns the number of bytes read or 0 indicates EOF // \throws TTransportException of types: // Interrupted means the socket was interrupted // out of a blocking call // NotOpen means the socket has been closed // TimedOut means the receive timeout expired // Unknown means something unexpected happened // function Read(var Buf; Len: Integer): Integer; // // Writes to the underlying socket. Loops until done or fail. // procedure Write(const Buf; Len: Integer); // // Writes to the underlying socket. Does single send() and returns result. // function WritePartial(const Buf; Len: Integer): Integer; // // Returns a cached copy of the peer address. // function GetCachedAddress(out Len: Integer): PSockAddr; // // Set a cache of the peer address (used when trivially available: e.g. // accept() or connect()). Only caches IPV4 and IPV6; unset for others. // procedure SetCachedAddress(const Addr: TSockAddr; Len: Integer); // // Controls whether the linger option is set on the socket. // // @param on Whether SO_LINGER is on // @param linger If linger is active, the number of seconds to linger for // procedure SetLinger(LingerOn: Boolean; LingerVal: Integer); // // Calls select() on the socket to see if there is more data available. // function Peek: Boolean; // Whether the socket is alive property IsOpen: Boolean read GetIsOpen; // The host that the socket is connected to property Host: string read FHost write FHost; // Whether to enable or disable Nagle's algorithm property NoDelay: Boolean read FNoDelay write SetNoDelay; // Connect timeout property ConnTimeout: Longword read FConnTimeout write FConnTimeout; // The max number of recv retries in the case of a WSAEWOULDBLOCK property MaxRecvRetries: Longword read FMaxRecvRetries write FMaxRecvRetries; // Socket information formatted as a string property SocketInfo: string read GetSocketInfo; // The DNS name of the host to which the socket is connected property PeerHost: string read GetPeerHost; // The address of the host to which the socket is connected property PeerAddress: string read GetPeerAddress; // The port of the host to which the socket is connected property PeerPort: Integer read GetPeerPort; // The origin the socket is connected to property Origin: string read GetOrigin; end; TServerSocketFunc = reference to procedure(sock: Winapi.Winsock2.TSocket); TServerSocket = class(TBaseSocket) strict private FAddress: string; FAcceptBacklog, FRetryLimit, FRetryDelay, FTcpSendBuffer, FTcpRecvBuffer: Integer; FAcceptTimeout: Longword; FListening, FInterruptableChildren: Boolean; FInterruptSockWriter, // is notified on Interrupt() FInterruptSockReader, // is used in select with FSocket for interruptability FChildInterruptSockWriter: Winapi.Winsock2.TSocket; // is notified on InterruptChildren() FChildInterruptSockReader: ISmartPointer; // if FnterruptableChildren this is shared with child TSockets FListenCallback, FAcceptCallback: TServerSocketFunc; function CreateSocketObj(Client: Winapi.Winsock2.TSocket): TSocket; procedure Notify(NotifySocket: Winapi.Winsock2.TSocket); procedure SetInterruptableChildren(AValue: Boolean); strict protected procedure CommonInit; override; public const DEFAULT_BACKLOG = 1024; public // // Constructor. // // @param port Port number to bind to // constructor Create(APort: Integer; ALogDelegate: TBaseSocket.TLogDelegate = nil); overload; // // Constructor. // // @param port Port number to bind to // @param sendTimeout Socket send timeout // @param recvTimeout Socket receive timeout // constructor Create(APort: Integer; ASendTimeout, ARecvTimeout: Longword; ALogDelegate: TBaseSocket.TLogDelegate = nil); overload; // // Constructor. // // @param address Address to bind to // @param port Port number to bind to // constructor Create(AAddress: string; APort: Integer; ALogDelegate: TBaseSocket.TLogDelegate = nil); overload; procedure Listen; function Accept: TSocket; procedure Interrupt; procedure InterruptChildren; procedure Close; override; property AcceptBacklog: Integer read FAcceptBacklog write FAcceptBacklog; property AcceptTimeout: Longword read FAcceptTimeout write FAcceptTimeout; property RetryLimit: Integer read FRetryLimit write FRetryLimit; property RetryDelay: Integer read FRetryDelay write FRetryDelay; property TcpSendBuffer: Integer read FTcpSendBuffer write FTcpSendBuffer; property TcpRecvBuffer: Integer read FTcpRecvBuffer write FTcpRecvBuffer; // When enabled (the default), new children TSockets will be constructed so // they can be interrupted by TServerTransport.InterruptChildren(). // This is more expensive in terms of system calls (poll + recv) however // ensures a connected client cannot interfere with TServer.Stop(). // // When disabled, TSocket children do not incur an additional poll() call. // Server-side reads are more efficient, however a client can interfere with // the server's ability to shutdown properly by staying connected. // // Must be called before listen(); mode cannot be switched after that. // \throws EPropertyError if listen() has been called property InterruptableChildren: Boolean read FInterruptableChildren write SetInterruptableChildren; // listenCallback gets called just before listen, and after all Thrift // setsockopt calls have been made. If you have custom setsockopt // things that need to happen on the listening socket, this is the place to do it. property ListenCallback: TServerSocketFunc read FListenCallback write FListenCallback; // acceptCallback gets called after each accept call, on the newly created socket. // It is called after all Thrift setsockopt calls have been made. If you have // custom setsockopt things that need to happen on the accepted // socket, this is the place to do it. property AcceptCallback: TServerSocketFunc read FAcceptCallback write FAcceptCallback; end; {$ENDIF} // not for OLD_SOCKETS implementation {$IFNDEF OLD_SOCKETS} // not for OLD_SOCKETS uses System.SysUtils, System.Math, System.DateUtils, Thrift.Transport; constructor TBaseSocket.TGetAddrInfoWrapper.Create(ANode, AService: string; AHints: PAddrInfoW); begin inherited Create; FNode := ANode; FService := AService; FHints := AHints; FRes := nil; end; destructor TBaseSocket.TGetAddrInfoWrapper.Destroy; begin if Assigned(FRes) then FreeAddrInfoW(FRes); inherited Destroy; end; function TBaseSocket.TGetAddrInfoWrapper.Init: Integer; begin if FRes = nil then Exit(GetAddrInfoW(@FNode[1], @FService[1], FHints^, FRes)); Result := 0; end; function TBaseSocket.TGetAddrInfoWrapper.GetRes: PAddrInfoW; begin Result := FRes; end; procedure DestroyerOfFineSockets(ssock: Winapi.Winsock2.TSocket); begin closesocket(ssock); end; function TScopeId.GetBitField(Loc: Integer): Integer; begin Result := (Value shr (Loc shr 8)) and ((1 shl (Loc and $FF)) - 1); end; procedure TScopeId.SetBitField(Loc: Integer; const aValue: Integer); begin Value := (Value and ULONG((not ((1 shl (Loc and $FF)) - 1)))) or ULONG(aValue shl (Loc shr 8)); end; function getaddrinfo; external 'ws2_32.dll' name 'getaddrinfo'; function GetAddrInfoW; external 'ws2_32.dll' name 'GetAddrInfoW'; procedure freeaddrinfo; external 'ws2_32.dll' name 'freeaddrinfo'; procedure FreeAddrInfoW; external 'ws2_32.dll' name 'FreeAddrInfoW'; function getnameinfo; external 'ws2_32.dll' name 'getnameinfo'; function GetNameInfoW; external 'ws2_32.dll' name 'GetNameInfoW'; constructor TSmartPointer.Create(AValue: T; ADestroyer: TSmartPointerDestroyer); begin inherited Create; FValue := AValue; FDestroyer := ADestroyer; end; destructor TSmartPointer.Destroy; begin if Assigned(FDestroyer) then FDestroyer(FValue); inherited Destroy; end; function TSmartPointer.Invoke: T; begin Result := FValue; end; class constructor TBaseSocket.Create; var Version: WORD; Data: WSAData; Error: Integer; begin Version := $0202; FillChar(Data, SizeOf(Data), 0); Error := WSAStartup(Version, Data); if Error <> 0 then raise Exception.Create('Failed to initialize Winsock.'); end; class destructor TBaseSocket.Destroy; begin WSACleanup; end; class procedure TBaseSocket.DefaultLogDelegate(const Str: string); var OutStr: string; begin OutStr := Format('Thrift: %s %s', [DateTimeToStr(Now, TFormatSettings.Create), Str]); try Writeln(OutStr); if IoResult <> 0 then OutputDebugString(PChar(OutStr)); except OutputDebugString(PChar(OutStr)); end; end; procedure TBaseSocket.CommonInit; begin FSocket := INVALID_SOCKET; FPort := 0; FSendTimeout := 0; FRecvTimeout := 0; FKeepAlive := False; FLogDelegate := DefaultLogDelegate; end; function TBaseSocket.CreateSocket(AAddress: string; APort: Integer): IGetAddrInfoWrapper; var Hints: TAddrInfoW; Res: PAddrInfoW; ThePort: array[0..5] of Char; Error: Integer; begin FillChar(Hints, SizeOf(Hints), 0); Hints.ai_family := PF_UNSPEC; Hints.ai_socktype := SOCK_STREAM; Hints.ai_flags := AI_PASSIVE; StrFmt(ThePort, '%d', [FPort]); Result := TGetAddrInfoWrapper.Create(AAddress, ThePort, @Hints); Error := Result.Init; if Error <> 0 then begin LogDelegate(Format('GetAddrInfoW %d: %s', [Error, SysErrorMessage(Error)])); Close; raise TTransportExceptionNotOpen.Create('Could not resolve host for server socket.'); end; // Pick the ipv6 address first since ipv4 addresses can be mapped // into ipv6 space. Res := Result.Res; while Assigned(Res) do begin if (Res^.ai_family = AF_INET6) or (not Assigned(Res^.ai_next)) then Break; Res := Res^.ai_next; end; FSocket := Winapi.Winsock2.socket(Res^.ai_family, Res^.ai_socktype, Res^.ai_protocol); if FSocket = INVALID_SOCKET then begin Error := WSAGetLastError; LogDelegate(Format('TBaseSocket.CreateSocket() socket() %s', [SysErrorMessage(Error)])); Close; raise TTransportExceptionNotOpen.Create(Format('socket(): %s', [SysErrorMessage(Error)])); end; end; procedure TBaseSocket.SetRecvTimeout(ARecvTimeout: Longword); begin FRecvTimeout := ARecvTimeout; end; procedure TBaseSocket.SetSendTimeout(ASendTimeout: Longword); begin FSendTimeout := ASendTimeout; end; procedure TBaseSocket.SetKeepAlive(AKeepAlive: Boolean); begin FKeepAlive := AKeepAlive; end; procedure TBaseSocket.SetSocket(ASocket: Winapi.Winsock2.TSocket); begin if FSocket <> INVALID_SOCKET then Close; FSocket := ASocket; end; constructor TBaseSocket.Create(ALogDelegate: TLogDelegate); begin inherited Create; CommonInit; if Assigned(ALogDelegate) then FLogDelegate := ALogDelegate; end; constructor TBaseSocket.Create(APort: Integer; ALogDelegate: TLogDelegate); begin inherited Create; CommonInit; FPort := APort; if Assigned(ALogDelegate) then FLogDelegate := ALogDelegate; end; destructor TBaseSocket.Destroy; begin Close; inherited Destroy; end; procedure TBaseSocket.Close; begin if FSocket <> INVALID_SOCKET then begin shutdown(FSocket, SD_BOTH); closesocket(FSocket); end; FSocket := INVALID_SOCKET; end; procedure TSocket.InitPeerInfo; begin FCachedPeerAddr.ipv4.sin_family := AF_UNSPEC; FPeerHost := ''; FPeerAddress := ''; FPeerPort := 0; end; procedure TSocket.CommonInit; begin inherited CommonInit; FHost := ''; FInterruptListener := nil; FConnTimeout := 0; FLingerOn := True; FLingerVal := 0; FNoDelay := True; FMaxRecvRetries := 5; InitPeerInfo; end; procedure TSocket.OpenConnection(Res: TBaseSocket.IGetAddrInfoWrapper); label Done; var ErrnoCopy: Integer; Ret, Ret2: Integer; Fds: TFdSet; TVal: TTimeVal; PTVal: PTimeVal; Val, Lon: Integer; One, Zero: Cardinal; begin if SendTimeout > 0 then SetSendTimeout(SendTimeout); if RecvTimeout > 0 then SetRecvTimeout(RecvTimeout); if KeepAlive then SetKeepAlive(KeepAlive); SetLinger(FLingerOn, FLingerVal); SetNoDelay(FNoDelay); // Set the socket to be non blocking for connect if a timeout exists Zero := 0; if FConnTimeout > 0 then begin One := 1; if ioctlsocket(Socket, Integer(FIONBIO), One) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TSocket.OpenConnection() ioctlsocket() %s %s', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('ioctlsocket() failed: %s', [SysErrorMessage(ErrnoCopy)])); end; end else begin if ioctlsocket(Socket, Integer(FIONBIO), Zero) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TSocket.OpenConnection() ioctlsocket() %s %s', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('ioctlsocket() failed: %s', [SysErrorMessage(ErrnoCopy)])); end; end; Ret := connect(Socket, Res.Res^.ai_addr^, Res.Res^.ai_addrlen); if Ret = 0 then goto Done; ErrnoCopy := WSAGetLastError; if (ErrnoCopy <> WSAEINPROGRESS) and (ErrnoCopy <> WSAEWOULDBLOCK) then begin LogDelegate(Format('TSocket.OpenConnection() connect() ', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('connect() failed: %s', [SysErrorMessage(ErrnoCopy)])); end; FD_ZERO(Fds); _FD_SET(Socket, Fds); if FConnTimeout > 0 then begin TVal.tv_sec := FConnTimeout div 1000; TVal.tv_usec := (FConnTimeout mod 1000) * 1000; PTVal := @TVal; end else PTVal := nil; Ret := select(1, nil, @Fds, nil, PTVal); if Ret > 0 then begin // Ensure the socket is connected and that there are no errors set Lon := SizeOf(Val); Ret2 := getsockopt(Socket, SOL_SOCKET, SO_ERROR, @Val, Lon); if Ret2 = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TSocket.OpenConnection() getsockopt() ', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('getsockopt(): %s', [SysErrorMessage(ErrnoCopy)])); end; // no errors on socket, go to town if Val = 0 then goto Done; LogDelegate(Format('TSocket.OpenConnection() error on socket (after select()) ', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('socket OpenConnection() error: %s', [SysErrorMessage(Val)])); end else if Ret = 0 then begin // socket timed out LogDelegate(Format('TSocket.OpenConnection() timed out ', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create('OpenConnection() timed out'); end else begin // error on select() ErrnoCopy := WSAGetLastError; LogDelegate(Format('TSocket.OpenConnection() select() ', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('select() failed: %s', [SysErrorMessage(ErrnoCopy)])); end; Done: // Set socket back to normal mode (blocking) ioctlsocket(Socket, Integer(FIONBIO), Zero); SetCachedAddress(Res.Res^.ai_addr^, Res.Res^.ai_addrlen); end; procedure TSocket.LocalOpen; var Res: TBaseSocket.IGetAddrInfoWrapper; begin if IsOpen then Exit; // Validate port number if (Port < 0) or (Port > $FFFF) then raise TTransportExceptionBadArgs.Create('Specified port is invalid'); Res := CreateSocket(Host, Port); OpenConnection(Res); end; procedure TSocket.SetGenericTimeout(S: Winapi.Winsock2.TSocket; Timeout: Longword; OptName: Integer); var Time: DWORD; begin if S = INVALID_SOCKET then Exit; Time := Timeout; if setsockopt(S, SOL_SOCKET, OptName, @Time, SizeOf(Time)) = SOCKET_ERROR then LogDelegate(Format('SetGenericTimeout() setsockopt() %s', [SysErrorMessage(WSAGetLastError)])); end; function TSocket.GetIsOpen: Boolean; begin Result := Socket <> INVALID_SOCKET; end; procedure TSocket.SetNoDelay(ANoDelay: Boolean); var V: Integer; begin FNoDelay := ANoDelay; if Socket = INVALID_SOCKET then Exit; V := IfThen(FNoDelay, 1, 0); if setsockopt(Socket, IPPROTO_TCP, TCP_NODELAY, @V, SizeOf(V)) = SOCKET_ERROR then LogDelegate(Format('TSocket.SetNoDelay() setsockopt() %s %s', [SocketInfo, SysErrorMessage(WSAGetLastError)])); end; function TSocket.GetSocketInfo: string; begin if (FHost = '') or (Port = 0) then Result := '' else Result := ''; end; function TSocket.GetPeerHost: string; var Addr: TSockAddrStorage; AddrPtr: PSockAddr; AddrLen: Integer; ClientHost: array[0..NI_MAXHOST-1] of Char; ClientService: array[0..NI_MAXSERV-1] of Char; begin if FPeerHost = '' then begin if Socket = INVALID_SOCKET then Exit(FPeerHost); AddrPtr := GetCachedAddress(AddrLen); if AddrPtr = nil then begin AddrLen := SizeOf(Addr); if getpeername(Socket, PSockAddr(@Addr)^, AddrLen) <> 0 then Exit(FPeerHost); AddrPtr := PSockAddr(@Addr); SetCachedAddress(AddrPtr^, AddrLen); end; GetNameInfoW(AddrPtr^, AddrLen, ClientHost, NI_MAXHOST, ClientService, NI_MAXSERV, 0); FPeerHost := ClientHost; end; Result := FPeerHost; end; function TSocket.GetPeerAddress: string; var Addr: TSockAddrStorage; AddrPtr: PSockAddr; AddrLen: Integer; ClientHost: array[0..NI_MAXHOST-1] of Char; ClientService: array[0..NI_MAXSERV-1] of Char; begin if FPeerAddress = '' then begin if Socket = INVALID_SOCKET then Exit(FPeerAddress); AddrPtr := GetCachedAddress(AddrLen); if AddrPtr = nil then begin AddrLen := SizeOf(Addr); if getpeername(Socket, PSockAddr(@Addr)^, AddrLen) <> 0 then Exit(FPeerHost); AddrPtr := PSockAddr(@Addr); SetCachedAddress(AddrPtr^, AddrLen); end; GetNameInfoW(AddrPtr^, AddrLen, ClientHost, NI_MAXHOST, ClientService, NI_MAXSERV, NI_NUMERICHOST or NI_NUMERICSERV); FPeerAddress := ClientHost; TryStrToInt(ClientService, FPeerPort); end; Result := FPeerAddress end; function TSocket.GetPeerPort: Integer; begin GetPeerAddress; Result := FPeerPort; end; function TSocket.GetOrigin: string; begin Result := GetPeerHost + ':' + GetPeerPort.ToString; end; procedure TSocket.SetRecvTimeout(ARecvTimeout: Longword); begin inherited SetRecvTimeout(ARecvTimeout); SetGenericTimeout(Socket, ARecvTimeout, SO_RCVTIMEO); end; procedure TSocket.SetSendTimeout(ASendTimeout: Longword); begin inherited SetSendTimeout(ASendTimeout); SetGenericTimeout(Socket, ASendTimeout, SO_SNDTIMEO); end; procedure TSocket.SetKeepAlive(AKeepAlive: Boolean); var Value: Integer; begin inherited SetKeepAlive(AKeepAlive); Value := IfThen(KeepAlive, 1, 0); if setsockopt(Socket, SOL_SOCKET, SO_KEEPALIVE, @Value, SizeOf(Value)) = SOCKET_ERROR then LogDelegate(Format('TSocket.SetKeepAlive() setsockopt() %s %s', [SocketInfo, SysErrorMessage(WSAGetLastError)])); end; constructor TSocket.Create(ALogDelegate: TBaseSocket.TLogDelegate = nil); begin // Not needed, but just a placeholder inherited Create(ALogDelegate); end; constructor TSocket.Create(AHost: string; APort: Integer; ALogDelegate: TBaseSocket.TLogDelegate); begin inherited Create(APort, ALogDelegate); FHost := AHost; end; constructor TSocket.Create(ASocket: Winapi.Winsock2.TSocket; ALogDelegate: TBaseSocket.TLogDelegate); begin inherited Create(ALogDelegate); Socket := ASocket; end; constructor TSocket.Create(ASocket: Winapi.Winsock2.TSocket; AInterruptListener: ISmartPointer; ALogDelegate: TBaseSocket.TLogDelegate); begin inherited Create(ALogDelegate); Socket := ASocket; FInterruptListener := AInterruptListener; end; procedure TSocket.Open; begin if IsOpen then Exit; LocalOpen; end; procedure TSocket.Close; begin inherited Close; InitPeerInfo; end; function TSocket.Read(var Buf; Len: Integer): Integer; label TryAgain; var Retries: Longword; EAgainThreshold, ReadElapsed: UInt64; Start: TDateTime; Got: Integer; Fds: TFdSet; ErrnoCopy: Integer; TVal: TTimeVal; PTVal: PTimeVal; Ret: Integer; begin if Socket = INVALID_SOCKET then raise TTransportExceptionNotOpen.Create('Called read on non-open socket'); Retries := 0; // THRIFT_EAGAIN can be signalled both when a timeout has occurred and when // the system is out of resources (an awesome undocumented feature). // The following is an approximation of the time interval under which // THRIFT_EAGAIN is taken to indicate an out of resources error. EAgainThreshold := 0; if RecvTimeout <> 0 then // if a readTimeout is specified along with a max number of recv retries, then // the threshold will ensure that the read timeout is not exceeded even in the // case of resource errors EAgainThreshold := RecvTimeout div IfThen(FMaxRecvRetries > 0, FMaxRecvRetries, 2); TryAgain: // Read from the socket if RecvTimeout > 0 then Start := Now else // if there is no read timeout we don't need the TOD to determine whether // an THRIFT_EAGAIN is due to a timeout or an out-of-resource condition. Start := 0; if Assigned(FInterruptListener) then begin FD_ZERO(Fds); _FD_SET(Socket, Fds); _FD_SET(FInterruptListener, Fds); if RecvTimeout > 0 then begin TVal.tv_sec := RecvTimeout div 1000; TVal.tv_usec := (RecvTimeout mod 1000) * 1000; PTVal := @TVal; end else PTVal := nil; Ret := select(2, @Fds, nil, nil, PTVal); ErrnoCopy := WSAGetLastError; if Ret < 0 then begin // error cases if (ErrnoCopy = WSAEINTR) and (Retries < FMaxRecvRetries) then begin Inc(Retries); goto TryAgain; end; LogDelegate(Format('TSocket.Read() select() %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionUnknown.Create(Format('Unknown: %s', [SysErrorMessage(ErrnoCopy)])); end else if Ret > 0 then begin // Check the interruptListener if FD_ISSET(FInterruptListener, Fds) then raise TTransportExceptionInterrupted.Create('Interrupted'); end else // Ret = 0 raise TTransportExceptionTimedOut.Create('WSAEWOULDBLOCK (timed out)'); // falling through means there is something to recv and it cannot block end; Got := recv(Socket, Buf, Len, 0); ErrnoCopy := WSAGetLastError; // Check for error on read if Got < 0 then begin if ErrnoCopy = WSAEWOULDBLOCK then begin // if no timeout we can assume that resource exhaustion has occurred. if RecvTimeout = 0 then raise TTransportExceptionTimedOut.Create('WSAEWOULDBLOCK (unavailable resources)'); // check if this is the lack of resources or timeout case ReadElapsed := MilliSecondsBetween(Now, Start); if (EAgainThreshold = 0) or (ReadElapsed < EAgainThreshold) then begin if Retries < FMaxRecvRetries then begin Inc(Retries); Sleep(1); goto TryAgain; end else raise TTransportExceptionTimedOut.Create('WSAEWOULDBLOCK (unavailable resources)'); end else // infer that timeout has been hit raise TTransportExceptionTimedOut.Create('WSAEWOULDBLOCK (timed out)'); end; // If interrupted, try again if (ErrnoCopy = WSAEINTR) and (Retries < FMaxRecvRetries) then begin Inc(Retries); goto TryAgain; end; if ErrnoCopy = WSAECONNRESET then Exit(0); // This ish isn't open if ErrnoCopy = WSAENOTCONN then raise TTransportExceptionNotOpen.Create('WSAENOTCONN'); // Timed out! if ErrnoCopy = WSAETIMEDOUT then raise TTransportExceptionNotOpen.Create('WSAETIMEDOUT'); // Now it's not a try again case, but a real probblez LogDelegate(Format('TSocket.Read() recv() %s %s', [SocketInfo, SysErrorMessage(ErrnoCopy)])); // Some other error, whatevz raise TTransportExceptionUnknown.Create(Format('Unknown: %s', [SysErrorMessage(ErrnoCopy)])); end; Result := Got; end; procedure TSocket.Write(const Buf; Len: Integer); var Sent, B: Integer; begin Sent := 0; while Sent < Len do begin B := WritePartial((PByte(@Buf) + Sent)^, Len - Sent); if B = 0 then // This should only happen if the timeout set with SO_SNDTIMEO expired. // Raise an exception. raise TTransportExceptionTimedOut.Create('send timeout expired'); Inc(Sent, B); end; end; function TSocket.WritePartial(const Buf; Len: Integer): Integer; var B: Integer; ErrnoCopy: Integer; begin if Socket = INVALID_SOCKET then raise TTransportExceptionNotOpen.Create('Called write on non-open socket'); B := send(Socket, Buf, Len, 0); if B < 0 then begin // Fail on a send error ErrnoCopy := WSAGetLastError; if ErrnoCopy = WSAEWOULDBLOCK then Exit(0); LogDelegate(Format('TSocket.WritePartial() send() %s %s', [SocketInfo, SysErrorMessage(ErrnoCopy)])); if (ErrnoCopy = WSAECONNRESET) or (ErrnoCopy = WSAENOTCONN) then begin Close; raise TTransportExceptionNotOpen.Create(Format('write() send(): %s', [SysErrorMessage(ErrnoCopy)])); end; raise TTransportExceptionUnknown.Create(Format('write() send(): %s', [SysErrorMessage(ErrnoCopy)])); end; // Fail on blocked send if B = 0 then raise TTransportExceptionNotOpen.Create('Socket send returned 0.'); Result := B; end; function TSocket.GetCachedAddress(out Len: Integer): PSockAddr; begin case FCachedPeerAddr.ipv4.sin_family of AF_INET: begin Len := SizeOf(TSockAddrIn); Result := PSockAddr(@FCachedPeerAddr.ipv4); end; AF_INET6: begin Len := SizeOf(TSockAddrIn6); Result := PSockAddr(@FCachedPeerAddr.ipv6); end; else Len := 0; Result := nil; end; end; procedure TSocket.SetCachedAddress(const Addr: TSockAddr; Len: Integer); begin case Addr.sa_family of AF_INET: if Len = SizeOf(TSockAddrIn) then FCachedPeerAddr.ipv4 := PSockAddrIn(@Addr)^; AF_INET6: if Len = SizeOf(TSockAddrIn6) then FCachedPeerAddr.ipv6 := PSockAddrIn6(@Addr)^; end; FPeerAddress := ''; FPeerHost := ''; FPeerPort := 0; end; procedure TSocket.SetLinger(LingerOn: Boolean; LingerVal: Integer); var L: TLinger; begin FLingerOn := LingerOn; FLingerVal := LingerVal; if Socket = INVALID_SOCKET then Exit; L.l_onoff := IfThen(FLingerOn, 1, 0); L.l_linger := LingerVal; if setsockopt(Socket, SOL_SOCKET, SO_LINGER, @L, SizeOf(L)) = SOCKET_ERROR then LogDelegate(Format('TSocket.SetLinger() setsockopt() %s %s', [SocketInfo, SysErrorMessage(WSAGetLastError)])); end; function TSocket.Peek: Boolean; var Retries: Longword; Fds: TFdSet; TVal: TTimeVal; PTVal: PTimeVal; Ret: Integer; ErrnoCopy: Integer; Buf: Byte; begin if not IsOpen then Exit(False); if Assigned(FInterruptListener) then begin Retries := 0; while true do begin FD_ZERO(Fds); _FD_SET(Socket, Fds); _FD_SET(FInterruptListener, Fds); if RecvTimeout > 0 then begin TVal.tv_sec := RecvTimeout div 1000; TVal.tv_usec := (RecvTimeout mod 1000) * 1000; PTVal := @TVal; end else PTVal := nil; Ret := select(2, @Fds, nil, nil, PTVal); ErrnoCopy := WSAGetLastError; if Ret < 0 then begin // error cases if (ErrnoCopy = WSAEINTR) and (Retries < FMaxRecvRetries) then begin Inc(Retries); Continue; end; LogDelegate(Format('TSocket.Peek() select() %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionUnknown.Create(Format('Unknown: %s', [SysErrorMessage(ErrnoCopy)])); end else if Ret > 0 then begin // Check the interruptListener if FD_ISSET(FInterruptListener, Fds) then Exit(False); // There must be data or a disconnection, fall through to the PEEK Break; end else // timeout Exit(False); end; end; // Check to see if data is available or if the remote side closed Ret := recv(Socket, Buf, 1, MSG_PEEK); if Ret = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; if ErrnoCopy = WSAECONNRESET then begin Close; Exit(False); end; LogDelegate(Format('TSocket.Peek() recv() %s %s', [SocketInfo, SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionUnknown.Create(Format('recv(): %s', [SysErrorMessage(ErrnoCopy)])); end; Result := Ret > 0; end; function TServerSocket.CreateSocketObj(Client: Winapi.Winsock2.TSocket): TSocket; begin if FInterruptableChildren then Result := TSocket.Create(Client, FChildInterruptSockReader) else Result := TSocket.Create(Client); end; procedure TServerSocket.Notify(NotifySocket: Winapi.Winsock2.TSocket); var Byt: Byte; begin if NotifySocket <> INVALID_SOCKET then begin Byt := 0; if send(NotifySocket, Byt, SizeOf(Byt), 0) = SOCKET_ERROR then LogDelegate(Format('TServerSocket.Notify() send() %s', [SysErrorMessage(WSAGetLastError)])); end; end; procedure TServerSocket.SetInterruptableChildren(AValue: Boolean); begin if FListening then raise Exception.Create('InterruptableChildren cannot be set after listen()'); FInterruptableChildren := AValue; end; procedure TServerSocket.CommonInit; begin inherited CommonInit; FInterruptableChildren := True; FAcceptBacklog := DEFAULT_BACKLOG; FAcceptTimeout := 0; FRetryLimit := 0; FRetryDelay := 0; FTcpSendBuffer := 0; FTcpRecvBuffer := 0; FListening := False; FInterruptSockWriter := INVALID_SOCKET; FInterruptSockReader := INVALID_SOCKET; FChildInterruptSockWriter := INVALID_SOCKET; end; constructor TServerSocket.Create(APort: Integer; ALogDelegate: TBaseSocket.TLogDelegate = nil); begin // Unnecessary, but here for documentation purposes inherited Create(APort, ALogDelegate); end; constructor TServerSocket.Create(APort: Integer; ASendTimeout, ARecvTimeout: Longword; ALogDelegate: TBaseSocket.TLogDelegate); begin inherited Create(APort, ALogDelegate); SendTimeout := ASendTimeout; RecvTimeout := ARecvTimeout; end; constructor TServerSocket.Create(AAddress: string; APort: Integer; ALogDelegate: TBaseSocket.TLogDelegate); begin inherited Create(APort, ALogDelegate); FAddress := AAddress; end; procedure TServerSocket.Listen; function CreateSocketPair(var Reader, Writer: Winapi.Winsock2.TSocket): Integer; label Error; type TSAUnion = record case Integer of 0: (inaddr: TSockAddrIn); 1: (addr: TSockAddr); end; var a: TSAUnion; listener: Winapi.Winsock2.TSocket; e: Integer; addrlen: Integer; flags: DWORD; reuse: Integer; begin addrlen := SizeOf(a.inaddr); flags := 0; reuse := 1; listener := Winapi.Winsock2.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if listener = INVALID_SOCKET then Exit(SOCKET_ERROR); FillChar(a, SizeOf(a), 0); a.inaddr.sin_family := AF_INET; a.inaddr.sin_addr.s_addr := htonl(INADDR_LOOPBACK); a.inaddr.sin_port := 0; Reader := INVALID_SOCKET; Writer := INVALID_SOCKET; // ignore errors coming out of this setsockopt. This is because // SO_EXCLUSIVEADDRUSE requires admin privileges on WinXP, but we don't // want to force socket pairs to be an admin. setsockopt(listener, SOL_SOCKET, Integer(SO_EXCLUSIVEADDRUSE), @reuse, SizeOf(reuse)); if bind(listener, a.addr, SizeOf(a.inaddr)) = SOCKET_ERROR then goto Error; if getsockname(listener, a.addr, addrlen) = SOCKET_ERROR then goto Error; if Winapi.Winsock2.listen(listener, 1) = SOCKET_ERROR then goto Error; Reader := WSASocket(AF_INET, SOCK_STREAM, 0, nil, 0, flags); if Reader = INVALID_SOCKET then goto Error; if connect(Reader, a.addr, SizeOf(a.inaddr)) = SOCKET_ERROR then goto Error; Writer := Winapi.Winsock2.accept(listener, nil, nil); if Writer = INVALID_SOCKET then goto Error; closesocket(listener); Exit(0); Error: e := WSAGetLastError; closesocket(listener); closesocket(Reader); closesocket(Writer); WSASetLastError(e); Result := SOCKET_ERROR; end; var TempIntReader, TempIntWriter: Winapi.Winsock2.TSocket; One: Cardinal; ErrnoCopy: Integer; Ling: TLinger; Retries: Integer; AddrInfo: IGetAddrInfoWrapper; SA: TSockAddrStorage; Len: Integer; begin // Create the socket pair used to interrupt if CreateSocketPair(TempIntReader, TempIntWriter) = SOCKET_ERROR then begin LogDelegate(Format('TServerSocket.Listen() CreateSocketPair() Interrupt %s', [SysErrorMessage(WSAGetLastError)])); FInterruptSockReader := INVALID_SOCKET; FInterruptSockWriter := INVALID_SOCKET; end else begin FInterruptSockReader := TempIntReader; FInterruptSockWriter := TempIntWriter; end; // Create the socket pair used to interrupt all clients if CreateSocketPair(TempIntReader, TempIntWriter) = SOCKET_ERROR then begin LogDelegate(Format('TServerSocket.Listen() CreateSocketPair() ChildInterrupt %s', [SysErrorMessage(WSAGetLastError)])); FChildInterruptSockReader := TSmartPointer.Create(INVALID_SOCKET, nil); FChildInterruptSockWriter := INVALID_SOCKET; end else begin FChildInterruptSockReader := TSmartPointer.Create(TempIntReader, DestroyerOfFineSockets); FChildInterruptSockWriter := TempIntWriter; end; if (Port < 0) or (Port > $FFFF) then raise TTransportExceptionBadArgs.Create('Specified port is invalid'); AddrInfo := CreateSocket(FAddress, Port); // Set SO_EXCLUSIVEADDRUSE to prevent 2MSL delay on accept One := 1; setsockopt(Socket, SOL_SOCKET, Integer(SO_EXCLUSIVEADDRUSE), @one, SizeOf(One)); // ignore errors coming out of this setsockopt on Windows. This is because // SO_EXCLUSIVEADDRUSE requires admin privileges on WinXP, but we don't // want to force servers to be an admin. // Set TCP buffer sizes if FTcpSendBuffer > 0 then begin if setsockopt(Socket, SOL_SOCKET, SO_SNDBUF, @FTcpSendBuffer, SizeOf(FTcpSendBuffer)) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Listen() setsockopt() SO_SNDBUF %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('Could not set SO_SNDBUF: %s', [SysErrorMessage(ErrnoCopy)])); end; end; if FTcpRecvBuffer > 0 then begin if setsockopt(Socket, SOL_SOCKET, SO_RCVBUF, @FTcpRecvBuffer, SizeOf(FTcpRecvBuffer)) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Listen() setsockopt() SO_RCVBUF %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('Could not set SO_RCVBUF: %s', [SysErrorMessage(ErrnoCopy)])); end; end; // Turn linger off, don't want to block on calls to close Ling.l_onoff := 0; Ling.l_linger := 0; if setsockopt(Socket, SOL_SOCKET, SO_LINGER, @Ling, SizeOf(Ling)) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Listen() setsockopt() SO_LINGER %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('Could not set SO_LINGER: %s', [SysErrorMessage(ErrnoCopy)])); end; // TCP Nodelay, speed over bandwidth if setsockopt(Socket, IPPROTO_TCP, TCP_NODELAY, @One, SizeOf(One)) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Listen() setsockopt() TCP_NODELAY %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('Could not set TCP_NODELAY: %s', [SysErrorMessage(ErrnoCopy)])); end; // Set NONBLOCK on the accept socket if ioctlsocket(Socket, Integer(FIONBIO), One) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Listen() ioctlsocket() FIONBIO %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('ioctlsocket() FIONBIO: %s', [SysErrorMessage(ErrnoCopy)])); end; // prepare the port information // we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't // always seem to work. The client can configure the retry variables. Retries := 0; while True do begin if bind(Socket, AddrInfo.Res^.ai_addr^, AddrInfo.Res^.ai_addrlen) = 0 then Break; Inc(Retries); if Retries > FRetryLimit then Break; Sleep(FRetryDelay * 1000); end; // retrieve bind info if (Port = 0) and (Retries < FRetryLimit) then begin Len := SizeOf(SA); FillChar(SA, Len, 0); if getsockname(Socket, PSockAddr(@SA)^, Len) = SOCKET_ERROR then LogDelegate(Format('TServerSocket.Listen() getsockname() %s', [SysErrorMessage(WSAGetLastError)])) else begin if SA.ss_family = AF_INET6 then Port := ntohs(PSockAddrIn6(@SA)^.sin6_port) else Port := ntohs(PSockAddrIn(@SA)^.sin_port); end; end; // throw an error if we failed to bind properly if (Retries > FRetryLimit) then begin LogDelegate(Format('TServerSocket.Listen() BIND %d', [Port])); Close; raise TTransportExceptionNotOpen.Create(Format('Could not bind: %s', [SysErrorMessage(WSAGetLastError)])); end; if Assigned(FListenCallback) then FListenCallback(Socket); // Call listen if Winapi.Winsock2.listen(Socket, FAcceptBacklog) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Listen() listen() %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionNotOpen.Create(Format('Could not listen: %s', [SysErrorMessage(ErrnoCopy)])); end; // The socket is now listening! end; function TServerSocket.Accept: TSocket; var Fds: TFdSet; MaxEInters, NumEInters: Integer; TVal: TTimeVal; PTVal: PTimeVal; ErrnoCopy: Integer; Buf: Byte; ClientAddress: TSockAddrStorage; Size: Integer; ClientSocket: Winapi.Winsock2.TSocket; Zero: Cardinal; Client: TSocket; Ret: Integer; begin MaxEInters := 5; NumEInters := 0; while True do begin FD_ZERO(Fds); _FD_SET(Socket, Fds); _FD_SET(FInterruptSockReader, Fds); if FAcceptTimeout > 0 then begin TVal.tv_sec := FAcceptTimeout div 1000; TVal.tv_usec := (FAcceptTimeout mod 1000) * 1000; PTVal := @TVal; end else PTVal := nil; // TODO: if WSAEINTR is received, we'll restart the timeout. // To be accurate, we need to fix this in the future. Ret := select(2, @Fds, nil, nil, PTVal); if Ret < 0 then begin // error cases if (WSAGetLastError = WSAEINTR) and (NumEInters < MaxEInters) then begin // THRIFT_EINTR needs to be handled manually and we can tolerate // a certain number Inc(NumEInters); Continue; end; ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Accept() select() %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionUnknown.Create(Format('Unknown: %s', [SysErrorMessage(ErrnoCopy)])); end else if Ret > 0 then begin // Check for an interrupt signal if (FInterruptSockReader <> INVALID_SOCKET) and FD_ISSET(FInterruptSockReader, Fds) then begin if recv(FInterruptSockReader, Buf, SizeOf(Buf), 0) = SOCKET_ERROR then LogDelegate(Format('TServerSocket.Accept() recv() interrupt %s', [SysErrorMessage(WSAGetLastError)])); raise TTransportExceptionInterrupted.Create('interrupted'); end; // Check for the actual server socket being ready if FD_ISSET(Socket, Fds) then Break; end else begin LogDelegate('TServerSocket.Accept() select() 0'); raise TTransportExceptionUnknown.Create('unknown error'); end; end; Size := SizeOf(ClientAddress); ClientSocket := Winapi.Winsock2.accept(Socket, @ClientAddress, @Size); if ClientSocket = INVALID_SOCKET then begin ErrnoCopy := WSAGetLastError; LogDelegate(Format('TServerSocket.Accept() accept() %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionUnknown.Create(Format('accept(): %s', [SysErrorMessage(ErrnoCopy)])); end; // Make sure client socket is blocking Zero := 0; if ioctlsocket(ClientSocket, Integer(FIONBIO), Zero) = SOCKET_ERROR then begin ErrnoCopy := WSAGetLastError; closesocket(ClientSocket); LogDelegate(Format('TServerSocket.Accept() ioctlsocket() FIONBIO %s', [SysErrorMessage(ErrnoCopy)])); raise TTransportExceptionUnknown.Create(Format('ioctlsocket(): %s', [SysErrorMessage(ErrnoCopy)])); end; Client := CreateSocketObj(ClientSocket); if SendTimeout > 0 then Client.SendTimeout := SendTimeout; if RecvTimeout > 0 then Client.RecvTimeout := RecvTimeout; if KeepAlive then Client.KeepAlive := KeepAlive; Client.SetCachedAddress(PSockAddr(@ClientAddress)^, Size); if Assigned(FAcceptCallback) then FAcceptCallback(ClientSocket); Result := Client; end; procedure TServerSocket.Interrupt; begin Notify(FInterruptSockWriter); end; procedure TServerSocket.InterruptChildren; begin Notify(FChildInterruptSockWriter); end; procedure TServerSocket.Close; begin inherited Close; if FInterruptSockWriter <> INVALID_SOCKET then closesocket(FInterruptSockWriter); if FInterruptSockReader <> INVALID_SOCKET then closesocket(FInterruptSockReader); if FChildInterruptSockWriter <> INVALID_SOCKET then closesocket(FChildInterruptSockWriter); FChildInterruptSockReader := TSmartPointer.Create(INVALID_SOCKET, nil); FListening := False; end; {$ENDIF} // not for OLD_SOCKETS end. thrift-0.23.0/lib/delphi/src/Thrift.Collections.pas0000664000175000017500000004632115165535636022427 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Collections; interface uses SysUtils, Generics.Collections, Generics.Defaults, Thrift.Utils; type {$IF CompilerVersion < 21.0} TArray = array of T; {$IFEND} IThriftContainer = interface( ISupportsToString) ['{E05C0F9D-A4F5-491D-AADA-C926B4BDB6E4}'] end; IThriftDictionary = interface(IThriftContainer) ['{25EDD506-F9D1-4008-A40F-5940364B7E46}'] function GetEnumerator: TEnumerator>; function GetKeys: TDictionary.TKeyCollection; function GetValues: TDictionary.TValueCollection; function GetItem(const Key: TKey): TValue; procedure SetItem(const Key: TKey; const Value: TValue); function GetCount: Integer; procedure Add(const Key: TKey; const Value: TValue); procedure Remove(const Key: TKey); {$IF CompilerVersion >= 21.0} function ExtractPair(const Key: TKey): TPair; {$IFEND} procedure Clear; procedure TrimExcess; function TryGetValue(const Key: TKey; out Value: TValue): Boolean; procedure AddOrSetValue(const Key: TKey; const Value: TValue); function ContainsKey(const Key: TKey): Boolean; function ContainsValue(const Value: TValue): Boolean; function ToArray: TArray>; property Items[const Key: TKey]: TValue read GetItem write SetItem; default; property Count: Integer read GetCount; property Keys: TDictionary.TKeyCollection read GetKeys; property Values: TDictionary.TValueCollection read GetValues; end; TThriftDictionaryImpl = class( TInterfacedObject, IThriftDictionary, IThriftContainer, ISupportsToString) strict private FDictionary : TDictionary; strict protected function GetEnumerator: TEnumerator>; function GetKeys: TDictionary.TKeyCollection; function GetValues: TDictionary.TValueCollection; function GetItem(const Key: TKey): TValue; procedure SetItem(const Key: TKey; const Value: TValue); function GetCount: Integer; procedure Add(const Key: TKey; const Value: TValue); procedure Remove(const Key: TKey); {$IF CompilerVersion >= 21.0} function ExtractPair(const Key: TKey): TPair; {$IFEND} procedure Clear; procedure TrimExcess; function TryGetValue(const Key: TKey; out Value: TValue): Boolean; procedure AddOrSetValue(const Key: TKey; const Value: TValue); function ContainsKey(const Key: TKey): Boolean; function ContainsValue(const Value: TValue): Boolean; function ToArray: TArray>; property Items[const Key: TKey]: TValue read GetItem write SetItem; default; property Count: Integer read GetCount; property Keys: TDictionary.TKeyCollection read GetKeys; property Values: TDictionary.TValueCollection read GetValues; public constructor Create( const aCapacity: Integer = 0); overload; constructor Create( const aCapacity: Integer; const aComparer : IEqualityComparer); overload; destructor Destroy; override; function ToString : string; override; end; IThriftList = interface(IThriftContainer) ['{29BEEE31-9CB4-401B-AA04-5148A75F473B}'] function GetEnumerator: TEnumerator; function GetCapacity: Integer; procedure SetCapacity(Value: Integer); function GetCount: Integer; procedure SetCount(Value: Integer); function GetItem(Index: Integer): T; procedure SetItem(Index: Integer; const Value: T); function Add(const Value: T): Integer; procedure AddRange(const Values: array of T); overload; procedure AddRange(const Collection: IEnumerable); overload; procedure AddRange(Collection: TEnumerable); overload; procedure Insert(Index: Integer; const Value: T); procedure InsertRange(Index: Integer; const Values: array of T); overload; procedure InsertRange(Index: Integer; const Collection: IEnumerable); overload; procedure InsertRange(Index: Integer; const Collection: TEnumerable); overload; function Remove(const Value: T): Integer; procedure Delete(Index: Integer); procedure DeleteRange(AIndex, ACount: Integer); function Extract(const Value: T): T; {$IF CompilerVersion >= 21.0} procedure Exchange(Index1, Index2: Integer); procedure Move(CurIndex, NewIndex: Integer); function First: T; function Last: T; {$IFEND} procedure Clear; function Contains(const Value: T): Boolean; function IndexOf(const Value: T): Integer; function LastIndexOf(const Value: T): Integer; procedure Reverse; procedure Sort; overload; procedure Sort(const AComparer: IComparer); overload; function BinarySearch(const Item: T; out Index: Integer): Boolean; overload; function BinarySearch(const Item: T; out Index: Integer; const AComparer: IComparer): Boolean; overload; procedure TrimExcess; function ToArray: TArray; property Capacity: Integer read GetCapacity write SetCapacity; property Count: Integer read GetCount write SetCount; property Items[Index: Integer]: T read GetItem write SetItem; default; end; TThriftListImpl = class( TInterfacedObject, IThriftList, IThriftContainer, ISupportsToString) strict private FList : TList; strict protected function GetEnumerator: TEnumerator; function GetCapacity: Integer; procedure SetCapacity(Value: Integer); function GetCount: Integer; procedure SetCount(Value: Integer); function GetItem(Index: Integer): T; procedure SetItem(Index: Integer; const Value: T); function Add(const Value: T): Integer; procedure AddRange(const Values: array of T); overload; procedure AddRange(const Collection: IEnumerable); overload; procedure AddRange(Collection: TEnumerable); overload; procedure Insert(Index: Integer; const Value: T); procedure InsertRange(Index: Integer; const Values: array of T); overload; procedure InsertRange(Index: Integer; const Collection: IEnumerable); overload; procedure InsertRange(Index: Integer; const Collection: TEnumerable); overload; function Remove(const Value: T): Integer; procedure Delete(Index: Integer); procedure DeleteRange(AIndex, ACount: Integer); function Extract(const Value: T): T; {$IF CompilerVersion >= 21.0} procedure Exchange(Index1, Index2: Integer); procedure Move(CurIndex, NewIndex: Integer); function First: T; function Last: T; {$IFEND} procedure Clear; function Contains(const Value: T): Boolean; function IndexOf(const Value: T): Integer; function LastIndexOf(const Value: T): Integer; procedure Reverse; procedure Sort; overload; procedure Sort(const AComparer: IComparer); overload; function BinarySearch(const Item: T; out Index: Integer): Boolean; overload; function BinarySearch(const Item: T; out Index: Integer; const AComparer: IComparer): Boolean; overload; procedure TrimExcess; function ToArray: TArray; property Capacity: Integer read GetCapacity write SetCapacity; property Count: Integer read GetCount write SetCount; property Items[Index: Integer]: T read GetItem write SetItem; default; public constructor Create( const aCapacity: Integer = 0); destructor Destroy; override; function ToString : string; override; end; IThriftHashSet = interface(IThriftContainer) ['{733E2B57-C374-4359-BBD5-2B9CD8DF737C}'] function GetEnumerator: TEnumerator; function GetCount: Integer; property Count: Integer read GetCount; function Add( const item: T) : Boolean; procedure Clear; function Contains( const item: T): Boolean; function Remove( const item: T): Boolean; end; // compatibility IHashSet = interface( IThriftHashSet) ['{C3CF557F-21D9-4524-B899-D3145B0389BB}'] end deprecated 'use IThriftHashSet'; {$WARN SYMBOL_DEPRECATED OFF} TThriftHashSetImpl = class( TInterfacedObject, IHashSet, IThriftHashSet, IThriftContainer, ISupportsToString) {$WARN SYMBOL_DEPRECATED DEFAULT} strict private FDictionary : TDictionary; // there is no THashSet in older Delphi versions strict protected function GetEnumerator: TEnumerator; function GetCount: Integer; property Count: Integer read GetCount; function Add( const item: T) : Boolean; procedure Clear; 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; destructor Destroy; override; function ToString : string; override; end; // compatibility THashSetImpl = class( TThriftHashSetImpl) end deprecated 'use TThriftHashSetImpl'; implementation { TThriftHashSetImpl. } function TThriftHashSetImpl.Add( const item: T) : Boolean; begin result := not FDictionary.ContainsKey(item); if result then FDictionary.Add( item, 0); end; procedure TThriftHashSetImpl.Clear; begin FDictionary.Clear; end; function TThriftHashSetImpl.Contains( const item: T): Boolean; begin Result := FDictionary.ContainsKey(item); end; constructor TThriftHashSetImpl.Create( const aCapacity: Integer); begin inherited Create; FDictionary := TDictionary.Create( aCapacity); end; constructor TThriftHashSetImpl.Create( const aCapacity: Integer; const aComparer : IEqualityComparer); begin inherited Create; FDictionary := TDictionary.Create( aCapacity, aComparer); end; destructor TThriftHashSetImpl.Destroy; begin FDictionary.Free; inherited Destroy; end; function TThriftHashSetImpl.GetCount: Integer; begin Result := FDictionary.Count; end; function TThriftHashSetImpl.GetEnumerator: TEnumerator; begin Result := FDictionary.Keys.GetEnumerator; end; function TThriftHashSetImpl.Remove( const item: T): Boolean; begin Result := FDictionary.ContainsKey( item); if Result then FDictionary.Remove( item ); end; function TThriftHashSetImpl.ToString : string; var elm : T; sb : TThriftStringBuilder; first : Boolean; begin sb := TThriftStringBuilder.Create('{'); try first := TRUE; for elm in FDictionary.Keys do begin if first then first := FALSE else sb.Append(', '); sb.Append( StringUtils.ToString(elm)); end; sb.Append('}'); Result := sb.ToString; finally sb.Free; end; end; { TThriftDictionaryImpl } procedure TThriftDictionaryImpl.Add(const Key: TKey; const Value: TValue); begin FDictionary.Add( Key, Value); end; procedure TThriftDictionaryImpl.AddOrSetValue(const Key: TKey; const Value: TValue); begin FDictionary.AddOrSetValue( Key, Value); end; procedure TThriftDictionaryImpl.Clear; begin FDictionary.Clear; end; function TThriftDictionaryImpl.ContainsKey( const Key: TKey): Boolean; begin Result := FDictionary.ContainsKey( Key ); end; function TThriftDictionaryImpl.ContainsValue( const Value: TValue): Boolean; begin Result := FDictionary.ContainsValue( Value ); end; constructor TThriftDictionaryImpl.Create(const aCapacity: Integer); begin inherited Create; FDictionary := TDictionary.Create( aCapacity); end; constructor TThriftDictionaryImpl.Create(const aCapacity: Integer; const aComparer : IEqualityComparer); begin inherited Create; FDictionary := TDictionary.Create( aCapacity, aComparer); end; destructor TThriftDictionaryImpl.Destroy; begin FDictionary.Free; inherited; end; {$IF CompilerVersion >= 21.0} function TThriftDictionaryImpl.ExtractPair( const Key: TKey): TPair; begin Result := FDictionary.ExtractPair( Key); end; {$IFEND} function TThriftDictionaryImpl.GetCount: Integer; begin Result := FDictionary.Count; end; function TThriftDictionaryImpl.GetEnumerator: TEnumerator>; begin Result := FDictionary.GetEnumerator; end; function TThriftDictionaryImpl.GetItem(const Key: TKey): TValue; begin Result := FDictionary.Items[Key]; end; function TThriftDictionaryImpl.GetKeys: TDictionary.TKeyCollection; begin Result := FDictionary.Keys; end; function TThriftDictionaryImpl.GetValues: TDictionary.TValueCollection; begin Result := FDictionary.Values; end; procedure TThriftDictionaryImpl.Remove(const Key: TKey); begin FDictionary.Remove( Key ); end; procedure TThriftDictionaryImpl.SetItem(const Key: TKey; const Value: TValue); begin FDictionary.AddOrSetValue( Key, Value); end; function TThriftDictionaryImpl.ToArray: TArray>; {$IF CompilerVersion < 22.0} var x : TPair; i : Integer; {$IFEND} begin {$IF CompilerVersion < 22.0} SetLength(Result, Count); i := 0; for x in FDictionaly do begin Result[i] := x; Inc( i ); end; {$ELSE} Result := FDictionary.ToArray; {$IFEND} end; function TThriftDictionaryImpl.ToString : string; var pair : TPair; sb : TThriftStringBuilder; first : Boolean; begin sb := TThriftStringBuilder.Create('{'); try first := TRUE; for pair in FDictionary do begin if first then first := FALSE else sb.Append(', '); sb.Append( '('); sb.Append( StringUtils.ToString(pair.Key)); sb.Append(' => '); sb.Append( StringUtils.ToString(pair.Value)); sb.Append(')'); end; sb.Append('}'); Result := sb.ToString; finally sb.Free; end; end; procedure TThriftDictionaryImpl.TrimExcess; begin FDictionary.TrimExcess; end; function TThriftDictionaryImpl.TryGetValue(const Key: TKey; out Value: TValue): Boolean; begin Result := FDictionary.TryGetValue( Key, Value); end; { TThriftListImpl } function TThriftListImpl.Add(const Value: T): Integer; begin Result := FList.Add( Value ); end; procedure TThriftListImpl.AddRange(Collection: TEnumerable); begin FList.AddRange( Collection ); end; procedure TThriftListImpl.AddRange(const Collection: IEnumerable); begin FList.AddRange( Collection ); end; procedure TThriftListImpl.AddRange(const Values: array of T); begin FList.AddRange( Values ); end; function TThriftListImpl.BinarySearch(const Item: T; out Index: Integer): Boolean; begin Result := FList.BinarySearch( Item, Index); end; function TThriftListImpl.BinarySearch(const Item: T; out Index: Integer; const AComparer: IComparer): Boolean; begin Result := FList.BinarySearch( Item, Index, AComparer); end; procedure TThriftListImpl.Clear; begin FList.Clear; end; function TThriftListImpl.Contains(const Value: T): Boolean; begin Result := FList.Contains( Value ); end; constructor TThriftListImpl.Create( const aCapacity: Integer); begin inherited Create; FList := TList.Create; if aCapacity > 0 then FList.Capacity := aCapacity; end; procedure TThriftListImpl.Delete(Index: Integer); begin FList.Delete( Index ) end; procedure TThriftListImpl.DeleteRange(AIndex, ACount: Integer); begin FList.DeleteRange( AIndex, ACount) end; destructor TThriftListImpl.Destroy; begin FList.Free; inherited; end; {$IF CompilerVersion >= 21.0} procedure TThriftListImpl.Exchange(Index1, Index2: Integer); begin FList.Exchange( Index1, Index2 ) end; {$IFEND} function TThriftListImpl.Extract(const Value: T): T; begin Result := FList.Extract( Value ) end; {$IF CompilerVersion >= 21.0} function TThriftListImpl.First: T; begin Result := FList.First; end; {$IFEND} function TThriftListImpl.GetCapacity: Integer; begin Result := FList.Capacity; end; function TThriftListImpl.GetCount: Integer; begin Result := FList.Count; end; function TThriftListImpl.GetEnumerator: TEnumerator; begin Result := FList.GetEnumerator; end; function TThriftListImpl.GetItem(Index: Integer): T; begin Result := FList[Index]; end; function TThriftListImpl.IndexOf(const Value: T): Integer; begin Result := FList.IndexOf( Value ); end; procedure TThriftListImpl.Insert(Index: Integer; const Value: T); begin FList.Insert( Index, Value); end; procedure TThriftListImpl.InsertRange(Index: Integer; const Collection: TEnumerable); begin FList.InsertRange( Index, Collection ); end; procedure TThriftListImpl.InsertRange(Index: Integer; const Values: array of T); begin FList.InsertRange( Index, Values); end; procedure TThriftListImpl.InsertRange(Index: Integer; const Collection: IEnumerable); begin FList.InsertRange( Index, Collection ); end; {$IF CompilerVersion >= 21.0} function TThriftListImpl.Last: T; begin Result := FList.Last; end; {$IFEND} function TThriftListImpl.LastIndexOf(const Value: T): Integer; begin Result := FList.LastIndexOf( Value ); end; {$IF CompilerVersion >= 21.0} procedure TThriftListImpl.Move(CurIndex, NewIndex: Integer); begin FList.Move( CurIndex, NewIndex); end; {$IFEND} function TThriftListImpl.Remove(const Value: T): Integer; begin Result := FList.Remove( Value ); end; procedure TThriftListImpl.Reverse; begin FList.Reverse; end; procedure TThriftListImpl.SetCapacity(Value: Integer); begin FList.Capacity := Value; end; procedure TThriftListImpl.SetCount(Value: Integer); begin FList.Count := Value; end; procedure TThriftListImpl.SetItem(Index: Integer; const Value: T); begin FList[Index] := Value; end; procedure TThriftListImpl.Sort; begin FList.Sort; end; procedure TThriftListImpl.Sort(const AComparer: IComparer); begin FList.Sort(AComparer); end; function TThriftListImpl.ToArray: TArray; {$IF CompilerVersion < 22.0} var x : T; i : Integer; {$IFEND} begin {$IF CompilerVersion < 22.0} SetLength(Result, Count); i := 0; for x in FList do begin Result[i] := x; Inc( i ); end; {$ELSE} Result := FList.ToArray; {$IFEND} end; function TThriftListImpl.ToString : string; var elm : T; sb : TThriftStringBuilder; first : Boolean; begin sb := TThriftStringBuilder.Create('{'); try first := TRUE; for elm in FList do begin if first then first := FALSE else sb.Append(', '); sb.Append( StringUtils.ToString(elm)); end; sb.Append('}'); Result := sb.ToString; finally sb.Free; end; end; procedure TThriftListImpl.TrimExcess; begin FList.TrimExcess; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Serializer.pas0000664000175000017500000001531615165535636022262 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Serializer; {$I Thrift.Defines.inc} interface uses {$IFDEF OLD_UNIT_NAMES} Classes, Windows, SysUtils, {$ELSE} System.Classes, Winapi.Windows, System.SysUtils, {$ENDIF} Thrift.Configuration, Thrift.Protocol, Thrift.Transport, Thrift.Stream; type // Generic utility for easily serializing objects into a byte array or Stream. TSerializer = class strict private FStream : TThriftMemoryStream; FTransport : ITransport; FProtocol : IProtocol; public constructor Create( const aProtFact : IProtocolFactory = nil; // defaults to TBinaryProtocol const aTransFact : ITransportFactory = nil; const aConfig : IThriftConfiguration = nil); // DTOR destructor Destroy; override; // Serialize the Thrift object. function Serialize( const input : IBase) : TBytes; overload; procedure Serialize( const input : IBase; const aStm : TStream); overload; end; // Generic utility for easily deserializing objects from byte array or Stream. TDeserializer = class strict private FStream : TThriftMemoryStream; FTransport : ITransport; FProtocol : IProtocol; public constructor Create( const aProtFact : IProtocolFactory = nil; // defaults to TBinaryProtocol const aTransFact : ITransportFactory = nil; const aConfig : IThriftConfiguration = nil); // DTOR destructor Destroy; override; // Deserialize the Thrift object data. procedure Deserialize( const input : TBytes; const target : IBase); overload; procedure Deserialize( const input : TStream; const target : IBase); overload; // helper property Protocol : IProtocol read FProtocol; property Transport : ITransport read FTransport; property Stream : TThriftMemoryStream read FStream; end; implementation { TSerializer } constructor TSerializer.Create( const aProtFact : IProtocolFactory; const aTransFact : ITransportFactory; const aConfig : IThriftConfiguration); var adapter : IThriftStream; protfact : IProtocolFactory; begin inherited Create; FStream := TThriftMemoryStream.Create; adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE); FTransport := TStreamTransportImpl.Create( nil, adapter, aConfig); if aTransfact <> nil then FTransport := aTransfact.GetTransport( FTransport); if aProtFact <> nil then protfact := aProtFact else protfact := TBinaryProtocolImpl.TFactory.Create; FProtocol := protfact.GetProtocol( FTransport); if not FTransport.IsOpen then FTransport.Open; end; destructor TSerializer.Destroy; begin try FProtocol := nil; FTransport := nil; FreeAndNil( FStream); finally inherited Destroy; end; end; function TSerializer.Serialize( const input : IBase) : TBytes; // Serialize the Thrift object into a byte array. The process is simple, // just clear the byte array output, write the object into it, and grab the // raw bytes. var iBytes : Int64; begin try FStream.Size := 0; input.Write( FProtocol); FTransport.Flush; SetLength( result, FStream.Size); iBytes := Length(result); if iBytes > 0 then Move( FStream.Memory^, result[0], iBytes); finally FStream.Size := 0; // free any allocated memory end; end; procedure TSerializer.Serialize( const input : IBase; const aStm : TStream); // Serialize the Thrift object into a byte array. The process is simple, // just clear the byte array output, write the object into it, and grab the // raw bytes. const COPY_ENTIRE_STREAM = 0; begin try FStream.Size := 0; input.Write( FProtocol); FTransport.Flush; aStm.CopyFrom( FStream, COPY_ENTIRE_STREAM); finally FStream.Size := 0; // free any allocated memory end; end; { TDeserializer } constructor TDeserializer.Create( const aProtFact : IProtocolFactory; const aTransFact : ITransportFactory; const aConfig : IThriftConfiguration); var adapter : IThriftStream; protfact : IProtocolFactory; begin inherited Create; FStream := TThriftMemoryStream.Create; adapter := TThriftStreamAdapterDelphi.Create( FStream, FALSE); FTransport := TStreamTransportImpl.Create( adapter, nil, aConfig); if aTransfact <> nil then FTransport := aTransfact.GetTransport( FTransport); if aProtFact <> nil then protfact := aProtFact else protfact := TBinaryProtocolImpl.TFactory.Create; FProtocol := protfact.GetProtocol( FTransport); if not FTransport.IsOpen then FTransport.Open; end; destructor TDeserializer.Destroy; begin try FProtocol := nil; FTransport := nil; FreeAndNil( FStream); finally inherited Destroy; end; end; procedure TDeserializer.Deserialize( const input : TBytes; const target : IBase); // Deserialize the Thrift object data from the byte array. var iBytes : Int64; begin try iBytes := Length(input); FStream.Size := iBytes; if iBytes > 0 then begin Move( input[0], FStream.Memory^, iBytes); Transport.ResetMessageSizeAndConsumedBytes(); // size has changed Transport.UpdateKnownMessageSize(iBytes); end; target.Read( FProtocol); finally FStream.Size := 0; // free any allocated memory end; end; procedure TDeserializer.Deserialize( const input : TStream; const target : IBase); // Deserialize the Thrift object data from the byte array. const COPY_ENTIRE_STREAM = 0; var before : Int64; begin try if Assigned(input) then begin before := FStream.Position; ASSERT( before = 0); FStream.CopyFrom( input, COPY_ENTIRE_STREAM); FStream.Position := before; Transport.ResetMessageSizeAndConsumedBytes(); // size has changed Transport.UpdateKnownMessageSize(FStream.Size); end; target.Read( FProtocol); finally FStream.Size := 0; // free any allocated memory end; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Protocol.pas0000664000175000017500000013276015165535636021755 0ustar00buildbuild00000000000000(* * 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. *) {$SCOPEDENUMS ON} {$IFOPT M+} {$DEFINE TYPEINFO_WAS_ON} {$ELSE} {$UNDEF TYPEINFO_WAS_ON} {$ENDIF} unit Thrift.Protocol; interface uses Classes, SysUtils, Contnrs, Math, Thrift.Exception, Thrift.Stream, Thrift.Utils, Thrift.Collections, Thrift.Configuration, Thrift.Transport; type TType = ( Stop = 0, Void = 1, Bool_ = 2, Byte_ = 3, Double_ = 4, I16 = 6, I32 = 8, I64 = 10, String_ = 11, Struct = 12, Map = 13, Set_ = 14, List = 15, Uuid = 16 ); TMessageType = ( Call = 1, Reply = 2, Exception = 3, Oneway = 4 ); const VALID_TTYPES = [ TType.Stop, TType.Void, TType.Bool_, TType.Byte_, TType.Double_, TType.I16, TType.I32, TType.I64, TType.String_, TType.Uuid, TType.Struct, TType.Map, TType.Set_, TType.List ]; VALID_MESSAGETYPES = [Low(TMessageType)..High(TMessageType)]; type IProtocol = interface; TThriftMessage = record Name: string; Type_: TMessageType; SeqID: Integer; end; TThriftStruct = record Name: string; end; TThriftField = record Name: string; Type_: TType; Id: SmallInt; end; TThriftList = record ElementType: TType; Count: Integer; end; TThriftMap = record KeyType: TType; ValueType: TType; Count: Integer; end; TThriftSet = record ElementType: TType; Count: Integer; end; IProtocolFactory = interface ['{7CD64A10-4E9F-4E99-93BF-708A31F4A67B}'] function GetProtocol( const trans: ITransport): IProtocol; end; TProtocolException = class abstract( TException) public type TExceptionType = ( UNKNOWN = 0, INVALID_DATA = 1, NEGATIVE_SIZE = 2, SIZE_LIMIT = 3, BAD_VERSION = 4, NOT_IMPLEMENTED = 5, DEPTH_LIMIT = 6 ); strict protected constructor HiddenCreate(const Msg: string); class function GetType: TExceptionType; virtual; abstract; public // purposefully hide inherited constructor class function Create(const Msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)'; class function Create: TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)'; class function Create( aType: TExceptionType): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)'; class function Create( aType: TExceptionType; const msg: string): TProtocolException; overload; deprecated 'Use specialized TProtocolException types (or regenerate from IDL)'; property Type_: TExceptionType read GetType; end; // Needed to remove deprecation warning TProtocolExceptionSpecialized = class abstract (TProtocolException) public constructor Create(const Msg: string); end; TProtocolExceptionUnknown = class (TProtocolExceptionSpecialized) strict protected class function GetType: TProtocolException.TExceptionType; override; end; TProtocolExceptionInvalidData = class (TProtocolExceptionSpecialized) strict protected class function GetType: TProtocolException.TExceptionType; override; end; TProtocolExceptionNegativeSize = class (TProtocolExceptionSpecialized) strict protected class function GetType: TProtocolException.TExceptionType; override; end; TProtocolExceptionSizeLimit = class (TProtocolExceptionSpecialized) strict protected class function GetType: TProtocolException.TExceptionType; override; end; TProtocolExceptionBadVersion = class (TProtocolExceptionSpecialized) strict protected class function GetType: TProtocolException.TExceptionType; override; end; TProtocolExceptionNotImplemented = class (TProtocolExceptionSpecialized) strict protected class function GetType: TProtocolException.TExceptionType; override; end; TProtocolExceptionDepthLimit = class (TProtocolExceptionSpecialized) strict protected class function GetType: TProtocolException.TExceptionType; override; end; TProtocolUtil = class public class procedure Skip( prot: IProtocol; type_: TType); end; IProtocolRecursionTracker = interface ['{29CA033F-BB56-49B1-9EE3-31B1E82FC7A5}'] // no members yet end; TProtocolRecursionTrackerImpl = class abstract( TInterfacedObject, IProtocolRecursionTracker) strict protected FProtocol : IProtocol; public constructor Create( prot : IProtocol); destructor Destroy; override; end; IThriftBytes = interface; // forward {$TYPEINFO ON} TThriftBytes = packed record // can't use SysUtils.TBytes because it has no typinfo -> E2134 data : System.TArray; class operator Implicit(aRec : SysUtils.TBytes) : TThriftBytes; class operator Implicit(aRec : TThriftBytes) : SysUtils.TBytes; function Length : Integer; end; {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF} IProtocol = interface ['{6067A28E-15BF-4C9D-9A6F-D991BB3DCB85}'] function GetTransport: ITransport; procedure WriteMessageBegin( const msg: TThriftMessage); procedure WriteMessageEnd; procedure WriteStructBegin( const struc: TThriftStruct); procedure WriteStructEnd; procedure WriteFieldBegin( const field: TThriftField); procedure WriteFieldEnd; procedure WriteFieldStop; procedure WriteMapBegin( const map: TThriftMap); procedure WriteMapEnd; procedure WriteListBegin( const list: TThriftList); procedure WriteListEnd(); procedure WriteSetBegin( const set_: TThriftSet ); procedure WriteSetEnd(); procedure WriteBool( b: Boolean); procedure WriteByte( b: ShortInt); procedure WriteI16( i16: SmallInt); procedure WriteI32( i32: Integer); procedure WriteI64( const i64: Int64); procedure WriteDouble( const d: Double); procedure WriteString( const s: string ); procedure WriteBinary( const b: TBytes); overload; procedure WriteBinary( const b: IThriftBytes); overload; procedure WriteUuid( const uuid: TGuid); function ReadMessageBegin: TThriftMessage; procedure ReadMessageEnd(); function ReadStructBegin: TThriftStruct; procedure ReadStructEnd; function ReadFieldBegin: TThriftField; procedure ReadFieldEnd(); function ReadMapBegin: TThriftMap; procedure ReadMapEnd(); function ReadListBegin: TThriftList; procedure ReadListEnd(); function ReadSetBegin: TThriftSet; procedure ReadSetEnd(); function ReadBool: Boolean; function ReadByte: ShortInt; function ReadI16: SmallInt; function ReadI32: Integer; function ReadI64: Int64; function ReadDouble:Double; function ReadBinary: TBytes; // IMPORTANT: this is NOT safe across module boundaries function ReadBinaryCOM : IThriftBytes; function ReadUuid: TGuid; function ReadString: string; function NextRecursionLevel : IProtocolRecursionTracker; procedure IncrementRecursionDepth; procedure DecrementRecursionDepth; function GetMinSerializedSize( const aType : TType) : Integer; property Transport: ITransport read GetTransport; function Configuration : IThriftConfiguration; end; TProtocolImplClass = class of TProtocolImpl; TProtocolImpl = class abstract( TInterfacedObject, IProtocol) strict protected FTrans : ITransport; FRecursionLimit : Integer; FRecursionDepth : Integer; function NextRecursionLevel : IProtocolRecursionTracker; procedure IncrementRecursionDepth; procedure DecrementRecursionDepth; function GetMinSerializedSize( const aType : TType) : Integer; virtual; abstract; procedure CheckReadBytesAvailable( const value : TThriftList); overload; inline; procedure CheckReadBytesAvailable( const value : TThriftSet); overload; inline; procedure CheckReadBytesAvailable( const value : TThriftMap); overload; inline; procedure Reset; virtual; function GetTransport: ITransport; function Configuration : IThriftConfiguration; procedure WriteMessageBegin( const msg: TThriftMessage); virtual; abstract; procedure WriteMessageEnd; virtual; abstract; procedure WriteStructBegin( const struc: TThriftStruct); virtual; abstract; procedure WriteStructEnd; virtual; abstract; procedure WriteFieldBegin( const field: TThriftField); virtual; abstract; procedure WriteFieldEnd; virtual; abstract; procedure WriteFieldStop; virtual; abstract; procedure WriteMapBegin( const map: TThriftMap); virtual; abstract; procedure WriteMapEnd; virtual; abstract; procedure WriteListBegin( const list: TThriftList); virtual; abstract; procedure WriteListEnd(); virtual; abstract; procedure WriteSetBegin( const set_: TThriftSet ); virtual; abstract; procedure WriteSetEnd(); virtual; abstract; procedure WriteBool( b: Boolean); virtual; abstract; procedure WriteByte( b: ShortInt); virtual; abstract; procedure WriteI16( i16: SmallInt); virtual; abstract; procedure WriteI32( i32: Integer); virtual; abstract; procedure WriteI64( const i64: Int64); virtual; abstract; procedure WriteDouble( const d: Double); virtual; abstract; procedure WriteString( const s: string ); virtual; procedure WriteBinary( const b: TBytes); overload; virtual; abstract; procedure WriteUuid( const b: TGuid); virtual; abstract; function ReadMessageBegin: TThriftMessage; virtual; abstract; procedure ReadMessageEnd(); virtual; abstract; function ReadStructBegin: TThriftStruct; virtual; abstract; procedure ReadStructEnd; virtual; abstract; function ReadFieldBegin: TThriftField; virtual; abstract; procedure ReadFieldEnd(); virtual; abstract; function ReadMapBegin: TThriftMap; virtual; abstract; procedure ReadMapEnd(); virtual; abstract; function ReadListBegin: TThriftList; virtual; abstract; procedure ReadListEnd(); virtual; abstract; function ReadSetBegin: TThriftSet; virtual; abstract; procedure ReadSetEnd(); virtual; abstract; function ReadBool: Boolean; virtual; abstract; function ReadByte: ShortInt; virtual; abstract; function ReadI16: SmallInt; virtual; abstract; function ReadI32: Integer; virtual; abstract; function ReadI64: Int64; virtual; abstract; function ReadDouble:Double; virtual; abstract; function ReadBinary: TBytes; virtual; abstract; function ReadUuid: TGuid; virtual; abstract; function ReadString: string; virtual; // provide generic implementation for all derived classes procedure WriteBinary( const bytes : IThriftBytes); overload; virtual; function ReadBinaryCOM : IThriftBytes; virtual; property Transport: ITransport read GetTransport; public constructor Create( const aTransport : ITransport); virtual; end; {.$TYPEINFO ON} // big NO -> may cause E2134 due to Delphis stupidity on enums vs TypeInfo {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])} IBase = interface( ISupportsToString) ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}'] procedure Read( const prot: IProtocol); procedure Write( const prot: IProtocol); end; {$TYPEINFO ON} {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])} IBaseWithTypeInfo = interface( IBase) end; {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} {$IFNDEF TYPEINFO_WAS_ON} {$TYPEINFO OFF} {$ENDIF} IThriftBytes = interface( ISupportsToString) ['{CDBEF7E8-BEF2-4A0A-983A-F334E3FF0016}'] function GetCount : Integer; procedure SetCount(const value : Integer); // WARNING: This returns a direct pointer to the underlying data structure function QueryRawDataPtr : Pointer; property Count : Integer read GetCount write SetCount; end; TThriftBytesImpl = class( TInterfacedObject, IThriftBytes, ISupportsToString) strict private FData : TBytes; strict protected function GetCount : Integer; procedure SetCount(const value : Integer); function QueryRawDataPtr : Pointer; public 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; TBinaryProtocolImpl = class( TProtocolImpl ) strict protected const VERSION_MASK : Cardinal = $ffff0000; VERSION_1 : Cardinal = $80010000; strict protected FStrictRead : Boolean; FStrictWrite : Boolean; function GetMinSerializedSize( const aType : TType) : Integer; override; strict private function ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; inline; function ReadStringBody( size: Integer): string; public type TFactory = class( TInterfacedObject, IProtocolFactory) strict protected FStrictRead : Boolean; FStrictWrite : Boolean; function GetProtocol( const trans: ITransport): IProtocol; public constructor Create( const aStrictRead : Boolean = FALSE; const aStrictWrite: Boolean = TRUE); reintroduce; end; constructor Create( const trans: ITransport); overload; override; constructor Create( const trans: ITransport; strictRead, strictWrite: Boolean); reintroduce; overload; procedure WriteMessageBegin( const msg: TThriftMessage); override; procedure WriteMessageEnd; override; procedure WriteStructBegin( const struc: TThriftStruct); override; procedure WriteStructEnd; override; procedure WriteFieldBegin( const field: TThriftField); override; procedure WriteFieldEnd; override; procedure WriteFieldStop; override; procedure WriteMapBegin( const map: TThriftMap); override; procedure WriteMapEnd; override; procedure WriteListBegin( const list: TThriftList); override; procedure WriteListEnd(); override; procedure WriteSetBegin( const set_: TThriftSet ); override; procedure WriteSetEnd(); override; procedure WriteBool( b: Boolean); override; procedure WriteByte( b: ShortInt); override; procedure WriteI16( i16: SmallInt); override; procedure WriteI32( i32: Integer); override; 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; procedure ReadMessageEnd(); override; function ReadStructBegin: TThriftStruct; override; procedure ReadStructEnd; override; function ReadFieldBegin: TThriftField; override; procedure ReadFieldEnd(); override; function ReadMapBegin: TThriftMap; override; procedure ReadMapEnd(); override; function ReadListBegin: TThriftList; override; procedure ReadListEnd(); override; function ReadSetBegin: TThriftSet; override; procedure ReadSetEnd(); override; function ReadBool: Boolean; override; function ReadByte: ShortInt; override; function ReadI16: SmallInt; override; function ReadI32: Integer; override; function ReadI64: Int64; override; function ReadDouble:Double; override; function ReadBinary: TBytes; override; function ReadUuid: TGuid; override; end; { TProtocolDecorator forwards all requests to an enclosed TProtocol instance, providing a way to author concise concrete decorator subclasses. The decorator does not (and should not) modify the behaviour of the enclosed TProtocol See p.175 of Design Patterns (by Gamma et al.) } TProtocolDecorator = class( TProtocolImpl) strict private FWrappedProtocol : IProtocol; strict protected function GetMinSerializedSize( const aType : TType) : Integer; override; public // Encloses the specified protocol. // All operations will be forward to the given protocol. Must be non-null. constructor Create( const aProtocol : IProtocol); reintroduce; procedure WriteMessageBegin( const msg: TThriftMessage); override; procedure WriteMessageEnd; override; procedure WriteStructBegin( const struc: TThriftStruct); override; procedure WriteStructEnd; override; procedure WriteFieldBegin( const field: TThriftField); override; procedure WriteFieldEnd; override; procedure WriteFieldStop; override; procedure WriteMapBegin( const map: TThriftMap); override; procedure WriteMapEnd; override; procedure WriteListBegin( const list: TThriftList); override; procedure WriteListEnd(); override; procedure WriteSetBegin( const set_: TThriftSet ); override; procedure WriteSetEnd(); override; procedure WriteBool( b: Boolean); override; procedure WriteByte( b: ShortInt); override; procedure WriteI16( i16: SmallInt); override; procedure WriteI32( i32: Integer); override; procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const d: Double); override; procedure WriteString( const s: string ); override; procedure WriteBinary( const b: TBytes); override; procedure WriteBinary( const bytes : IThriftBytes); overload; override; procedure WriteUuid( const uuid: TGuid); override; function ReadMessageBegin: TThriftMessage; override; procedure ReadMessageEnd(); override; function ReadStructBegin: TThriftStruct; override; procedure ReadStructEnd; override; function ReadFieldBegin: TThriftField; override; procedure ReadFieldEnd(); override; function ReadMapBegin: TThriftMap; override; procedure ReadMapEnd(); override; function ReadListBegin: TThriftList; override; procedure ReadListEnd(); override; function ReadSetBegin: TThriftSet; override; procedure ReadSetEnd(); override; function ReadBool: Boolean; override; function ReadByte: ShortInt; override; function ReadI16: SmallInt; override; function ReadI32: Integer; override; function ReadI64: Int64; override; function ReadDouble:Double; override; function ReadBinary: TBytes; override; function ReadUuid: TGuid; override; function ReadString: string; override; end; type IRequestEvents = interface ['{F926A26A-5B00-4560-86FA-2CAE3BA73DAF}'] // Called before reading arguments. procedure PreRead; // Called between reading arguments and calling the handler. procedure PostRead; // Called between calling the handler and writing the response. procedure PreWrite; // Called after writing the response. procedure PostWrite; // Called when an oneway (async) function call completes successfully. procedure OnewayComplete; // Called if the handler throws an undeclared exception. procedure UnhandledError( const e : Exception); // Called when a client has finished request-handling to clean up procedure CleanupContext; end; IProcessorEvents = interface ['{A8661119-657C-447D-93C5-512E36162A45}'] // Called when a client is about to call the processor. procedure Processing( const transport : ITransport); // Called on any service function invocation function CreateRequestContext( const aFunctionName : string) : IRequestEvents; // Called when a client has finished request-handling to clean up procedure CleanupContext; end; IProcessor = interface ['{7BAE92A5-46DA-4F13-B6EA-0EABE233EE5F}'] function Process( const iprot :IProtocol; const oprot: IProtocol; const events : IProcessorEvents = nil): Boolean; end; procedure Init( var rec : TThriftMessage; const AName: string = ''; const AMessageType: TMessageType = Low(TMessageType); const ASeqID: Integer = 0); overload; inline; procedure Init( var rec : TThriftStruct; const AName: string = ''); overload; inline; procedure Init( var rec : TThriftField; const AName: string = ''; const AType: TType = Low(TType); const AID: SmallInt = 0); overload; inline; procedure Init( var rec : TThriftMap; const AKeyType: TType = Low(TType); const AValueType: TType = Low(TType); const ACount: Integer = 0); overload; inline; procedure Init( var rec : TThriftSet; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline; procedure Init( var rec : TThriftList; const AElementType: TType = Low(TType); const ACount: Integer = 0); overload; inline; implementation function ConvertInt64ToDouble( const n: Int64): Double; inline; begin ASSERT( SizeOf(n) = SizeOf(Result)); System.Move( n, Result, SizeOf(Result)); end; function ConvertDoubleToInt64( const d: Double): Int64; inline; begin ASSERT( SizeOf(d) = SizeOf(Result)); System.Move( d, Result, SizeOf(Result)); end; //--- TThriftBytes ---------------------------------------------------------------------- class operator TThriftBytes.Implicit(aRec : SysUtils.TBytes) : TThriftBytes; begin ASSERT( @result.data = @result); // must be first field ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field result := TThriftBytes(aRec); end; class operator TThriftBytes.Implicit(aRec : TThriftBytes) : SysUtils.TBytes; begin ASSERT( @aRec.data = @aRec); // must be first field ASSERT( SizeOf(aRec) = SizeOf(result)); // must be the only field result := SysUtils.TBytes(aRec.data); end; function TThriftBytes.Length : Integer; begin result := System.Length(data); end; { TProtocolRecursionTrackerImpl } constructor TProtocolRecursionTrackerImpl.Create( prot : IProtocol); begin inherited Create; // storing the pointer *after* the (successful) increment is important here prot.IncrementRecursionDepth; FProtocol := prot; end; destructor TProtocolRecursionTrackerImpl.Destroy; begin try // we have to release the reference iff the pointer has been stored if FProtocol <> nil then begin FProtocol.DecrementRecursionDepth; FProtocol := nil; end; finally inherited Destroy; end; end; { TProtocolImpl } constructor TProtocolImpl.Create( const aTransport : ITransport); begin inherited Create; FTrans := aTransport; FRecursionLimit := aTransport.Configuration.RecursionLimit; FRecursionDepth := 0; end; function TProtocolImpl.NextRecursionLevel : IProtocolRecursionTracker; begin result := TProtocolRecursionTrackerImpl.Create(Self); end; procedure TProtocolImpl.IncrementRecursionDepth; begin if FRecursionDepth < FRecursionLimit then Inc(FRecursionDepth) else raise TProtocolExceptionDepthLimit.Create('Depth limit exceeded'); end; procedure TProtocolImpl.DecrementRecursionDepth; begin Dec(FRecursionDepth) end; function TProtocolImpl.GetTransport: ITransport; begin Result := FTrans; end; function TProtocolImpl.Configuration : IThriftConfiguration; begin Result := FTrans.Configuration; end; procedure TProtocolImpl.Reset; begin FTrans.ResetMessageSizeAndConsumedBytes; end; function TProtocolImpl.ReadString: string; begin Result := TEncoding.UTF8.GetString( ReadBinary ); end; procedure TProtocolImpl.WriteString(const s: string); var b : TBytes; begin b := TEncoding.UTF8.GetBytes(s); WriteBinary( b ); end; procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftList); begin FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType)); end; procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftSet); begin FTrans.CheckReadBytesAvailable( value.Count * GetMinSerializedSize(value.ElementType)); end; procedure TProtocolImpl.CheckReadBytesAvailable( const value : TThriftMap); var nPairSize : Integer; begin nPairSize := GetMinSerializedSize(value.KeyType) + GetMinSerializedSize(value.ValueType); FTrans.CheckReadBytesAvailable( value.Count * nPairSize); end; 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); if Length(tmp) > 0 then Move( bytes.QueryRawDataPtr^, tmp[0], Length(tmp)); WriteBinary( tmp); end; function TProtocolImpl.ReadBinaryCOM : IThriftBytes; var bytes : TBytes; begin bytes := ReadBinary; result := TThriftBytesImpl.Create(bytes,TRUE); end; { TThriftBytesImpl } constructor TThriftBytesImpl.Create; begin inherited Create; ASSERT( Length(FData) = 0); end; constructor TThriftBytesImpl.Create( const bytes : TBytes); begin FData := bytes; // copies the data end; constructor TThriftBytesImpl.Create( var bytes : TBytes; const aTakeOwnership : Boolean); procedure SwapPointer( var one, two); var pOne : Pointer absolute one; pTwo : Pointer absolute two; pTmp : Pointer; begin pTmp := pOne; pOne := pTwo; pTwo := pTmp; end; begin inherited Create; ASSERT( Length(FData) = 0); if aTakeOwnership then SwapPointer( FData, bytes) else FData := bytes; // copies the data 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 sb := TThriftStringBuilder.Create(); try sb.Append('Bin: '); sb.Append( FData); result := sb.ToString; finally sb.Free; end; end; function TThriftBytesImpl.GetCount : Integer; begin result := Length(FData); end; procedure TThriftBytesImpl.SetCount(const value : Integer); begin SetLength( FData, value); end; function TThriftBytesImpl.QueryRawDataPtr : Pointer; begin result := FData; end; { TProtocolUtil } class procedure TProtocolUtil.Skip( prot: IProtocol; type_: TType); var field : TThriftField; map : TThriftMap; set_ : TThriftSet; list : TThriftList; i : Integer; tracker : IProtocolRecursionTracker; begin tracker := prot.NextRecursionLevel; case type_ of // simple types TType.Bool_ : prot.ReadBool(); TType.Byte_ : prot.ReadByte(); TType.I16 : prot.ReadI16(); TType.I32 : prot.ReadI32(); TType.I64 : prot.ReadI64(); TType.Double_ : prot.ReadDouble(); TType.String_ : prot.ReadBinary();// Don't try to decode the string, just skip it. TType.Uuid : prot.ReadUuid(); // structured types TType.Struct : begin prot.ReadStructBegin(); while TRUE do begin field := prot.ReadFieldBegin(); if (field.Type_ = TType.Stop) then Break; Skip(prot, field.Type_); prot.ReadFieldEnd(); end; prot.ReadStructEnd(); end; TType.Map : begin map := prot.ReadMapBegin(); for i := 0 to map.Count-1 do begin Skip(prot, map.KeyType); Skip(prot, map.ValueType); end; prot.ReadMapEnd(); end; TType.Set_ : begin set_ := prot.ReadSetBegin(); for i := 0 to set_.Count-1 do Skip( prot, set_.ElementType); prot.ReadSetEnd(); end; TType.List : begin list := prot.ReadListBegin(); for i := 0 to list.Count-1 do Skip( prot, list.ElementType); prot.ReadListEnd(); end; else raise TProtocolExceptionInvalidData.Create('Unexpected type '+IntToStr(Ord(type_))); end; end; { TBinaryProtocolImpl } constructor TBinaryProtocolImpl.Create( const trans: ITransport); begin // call the real CTOR Self.Create( trans, FALSE, TRUE); end; constructor TBinaryProtocolImpl.Create( const trans: ITransport; strictRead, strictWrite: Boolean); begin inherited Create( trans); FStrictRead := strictRead; FStrictWrite := strictWrite; end; function TBinaryProtocolImpl.ReadAll( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer ): Integer; begin Result := FTrans.ReadAll( pBuf, buflen, off, len ); end; function TBinaryProtocolImpl.ReadBinary: TBytes; var size : Integer; buf : TBytes; begin size := ReadI32; FTrans.CheckReadBytesAvailable( size); SetLength( buf, size); FTrans.ReadAll( buf, 0, size); Result := buf; end; function TBinaryProtocolImpl.ReadUuid : TGuid; var network : TGuid; // in network order (Big Endian) begin ASSERT( SizeOf(result) = 16); FTrans.ReadAll( @network, SizeOf(network), 0, SizeOf(network)); result := GuidUtils.SwapByteOrder(network); end; function TBinaryProtocolImpl.ReadBool: Boolean; begin Result := (ReadByte = 1); end; function TBinaryProtocolImpl.ReadByte: ShortInt; begin ReadAll( @result, SizeOf(result), 0, 1); end; function TBinaryProtocolImpl.ReadDouble: Double; begin Result := ConvertInt64ToDouble( ReadI64 ) end; function TBinaryProtocolImpl.ReadFieldBegin: TThriftField; begin Init( result, '', TType( ReadByte), 0); if ( result.Type_ <> TType.Stop ) then begin result.Id := ReadI16; end; end; procedure TBinaryProtocolImpl.ReadFieldEnd; begin end; function TBinaryProtocolImpl.ReadI16: SmallInt; var i16in : packed array[0..1] of Byte; begin ReadAll( @i16in, Sizeof(i16in), 0, 2); Result := SmallInt(((i16in[0] and $FF) shl 8) or (i16in[1] and $FF)); end; function TBinaryProtocolImpl.ReadI32: Integer; var i32in : packed array[0..3] of Byte; begin ReadAll( @i32in, SizeOf(i32in), 0, 4); Result := Integer( ((i32in[0] and $FF) shl 24) or ((i32in[1] and $FF) shl 16) or ((i32in[2] and $FF) shl 8) or (i32in[3] and $FF)); end; function TBinaryProtocolImpl.ReadI64: Int64; var i64in : packed array[0..7] of Byte; begin ReadAll( @i64in, SizeOf(i64in), 0, 8); Result := (Int64( i64in[0] and $FF) shl 56) or (Int64( i64in[1] and $FF) shl 48) or (Int64( i64in[2] and $FF) shl 40) or (Int64( i64in[3] and $FF) shl 32) or (Int64( i64in[4] and $FF) shl 24) or (Int64( i64in[5] and $FF) shl 16) or (Int64( i64in[6] and $FF) shl 8) or (Int64( i64in[7] and $FF)); end; function TBinaryProtocolImpl.ReadListBegin: TThriftList; begin result.ElementType := TType(ReadByte); result.Count := ReadI32; CheckReadBytesAvailable(result); end; procedure TBinaryProtocolImpl.ReadListEnd; begin end; function TBinaryProtocolImpl.ReadMapBegin: TThriftMap; begin result.KeyType := TType(ReadByte); result.ValueType := TType(ReadByte); result.Count := ReadI32; CheckReadBytesAvailable(result); end; procedure TBinaryProtocolImpl.ReadMapEnd; begin end; function TBinaryProtocolImpl.ReadMessageBegin: TThriftMessage; var size : Integer; version : Integer; begin Reset; Init( result); size := ReadI32; if (size < 0) then begin version := size and Integer( VERSION_MASK); if ( version <> Integer( VERSION_1)) then begin raise TProtocolExceptionBadVersion.Create('Bad version in ReadMessageBegin: ' + IntToStr(version) ); end; result.Type_ := TMessageType( size and $000000ff); result.Name := ReadString; result.SeqID := ReadI32; Exit; end; try if FStrictRead then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' ); result.Name := ReadStringBody( size ); result.Type_ := TMessageType( ReadByte ); result.SeqID := ReadI32; except if CharUtils.IsHtmlDoctype(size) then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data') else raise; // something else end; end; procedure TBinaryProtocolImpl.ReadMessageEnd; begin inherited; end; function TBinaryProtocolImpl.ReadSetBegin: TThriftSet; begin result.ElementType := TType(ReadByte); result.Count := ReadI32; CheckReadBytesAvailable(result); end; procedure TBinaryProtocolImpl.ReadSetEnd; begin end; function TBinaryProtocolImpl.ReadStringBody( size: Integer): string; var buf : TBytes; begin FTrans.CheckReadBytesAvailable( size); SetLength( buf, size); FTrans.ReadAll( buf, 0, size ); Result := TEncoding.UTF8.GetString( buf); end; function TBinaryProtocolImpl.ReadStructBegin: TThriftStruct; begin Init( Result); end; procedure TBinaryProtocolImpl.ReadStructEnd; begin inherited; end; procedure TBinaryProtocolImpl.WriteBinary( const b: TBytes); var iLen : Integer; begin iLen := Length(b); WriteI32( iLen); 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 ASSERT( SizeOf(uuid) = 16); network := GuidUtils.SwapByteOrder(uuid); Transport.Write( @network, 0, SizeOf(network)); end; procedure TBinaryProtocolImpl.WriteBool(b: Boolean); begin if b then begin WriteByte( 1 ); end else begin WriteByte( 0 ); end; end; procedure TBinaryProtocolImpl.WriteByte(b: ShortInt); begin FTrans.Write( @b, 0, 1); end; procedure TBinaryProtocolImpl.WriteDouble( const d: Double); begin WriteI64(ConvertDoubleToInt64(d)); end; procedure TBinaryProtocolImpl.WriteFieldBegin( const field: TThriftField); begin WriteByte(ShortInt(field.Type_)); WriteI16(field.ID); end; procedure TBinaryProtocolImpl.WriteFieldEnd; begin end; procedure TBinaryProtocolImpl.WriteFieldStop; begin WriteByte(ShortInt(TType.Stop)); end; procedure TBinaryProtocolImpl.WriteI16(i16: SmallInt); var i16out : packed array[0..1] of Byte; begin i16out[0] := Byte($FF and (i16 shr 8)); i16out[1] := Byte($FF and i16); FTrans.Write( @i16out, 0, 2); end; procedure TBinaryProtocolImpl.WriteI32(i32: Integer); var i32out : packed array[0..3] of Byte; begin i32out[0] := Byte($FF and (i32 shr 24)); i32out[1] := Byte($FF and (i32 shr 16)); i32out[2] := Byte($FF and (i32 shr 8)); i32out[3] := Byte($FF and i32); FTrans.Write( @i32out, 0, 4); end; procedure TBinaryProtocolImpl.WriteI64( const i64: Int64); var i64out : packed array[0..7] of Byte; begin i64out[0] := Byte($FF and (i64 shr 56)); i64out[1] := Byte($FF and (i64 shr 48)); i64out[2] := Byte($FF and (i64 shr 40)); i64out[3] := Byte($FF and (i64 shr 32)); i64out[4] := Byte($FF and (i64 shr 24)); i64out[5] := Byte($FF and (i64 shr 16)); i64out[6] := Byte($FF and (i64 shr 8)); i64out[7] := Byte($FF and i64); FTrans.Write( @i64out, 0, 8); end; procedure TBinaryProtocolImpl.WriteListBegin( const list: TThriftList); begin WriteByte(ShortInt(list.ElementType)); WriteI32(list.Count); end; procedure TBinaryProtocolImpl.WriteListEnd; begin end; procedure TBinaryProtocolImpl.WriteMapBegin( const map: TThriftMap); begin WriteByte(ShortInt(map.KeyType)); WriteByte(ShortInt(map.ValueType)); WriteI32(map.Count); end; procedure TBinaryProtocolImpl.WriteMapEnd; begin end; procedure TBinaryProtocolImpl.WriteMessageBegin( const msg: TThriftMessage); var version : Cardinal; begin Reset; if FStrictWrite then begin version := VERSION_1 or Cardinal( msg.Type_); WriteI32( Integer( version) ); WriteString( msg.Name); WriteI32( msg.SeqID); end else begin WriteString( msg.Name); WriteByte(ShortInt( msg.Type_)); WriteI32( msg.SeqID); end; end; procedure TBinaryProtocolImpl.WriteMessageEnd; begin end; procedure TBinaryProtocolImpl.WriteSetBegin( const set_: TThriftSet); begin WriteByte(ShortInt(set_.ElementType)); WriteI32(set_.Count); end; procedure TBinaryProtocolImpl.WriteSetEnd; begin end; procedure TBinaryProtocolImpl.WriteStructBegin( const struc: TThriftStruct); begin end; procedure TBinaryProtocolImpl.WriteStructEnd; begin end; function TBinaryProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer; // Return the minimum number of bytes a type will consume on the wire begin case aType of TType.Stop: result := 1; // T_STOP needs to count itself TType.Void: result := 1; // T_VOID needs to count itself TType.Bool_: result := SizeOf(Byte); TType.Byte_: result := SizeOf(Byte); TType.Double_: result := SizeOf(Double); TType.I16: result := SizeOf(Int16); TType.I32: result := SizeOf(Int32); TType.I64: result := SizeOf(Int64); TType.String_: result := SizeOf(Int32); // string length TType.Struct: result := 1; // empty struct needs at least 1 byte for the T_STOP TType.Map: result := SizeOf(Int32); // element count TType.Set_: result := SizeOf(Int32); // element count TType.List: result := SizeOf(Int32); // element count TType.Uuid: result := SizeOf(TGuid); else raise TTransportExceptionBadArgs.Create('Unhandled type code'); end; end; { TProtocolException } constructor TProtocolException.HiddenCreate(const Msg: string); begin inherited Create(Msg); end; class function TProtocolException.Create(const Msg: string): TProtocolException; begin Result := TProtocolExceptionUnknown.Create(Msg); end; class function TProtocolException.Create: TProtocolException; begin Result := TProtocolExceptionUnknown.Create(''); end; class function TProtocolException.Create(aType: TExceptionType): TProtocolException; begin {$WARN SYMBOL_DEPRECATED OFF} Result := Create(aType, ''); {$WARN SYMBOL_DEPRECATED DEFAULT} end; class function TProtocolException.Create(aType: TExceptionType; const msg: string): TProtocolException; begin case aType of TExceptionType.INVALID_DATA: Result := TProtocolExceptionInvalidData.Create(msg); TExceptionType.NEGATIVE_SIZE: Result := TProtocolExceptionNegativeSize.Create(msg); TExceptionType.SIZE_LIMIT: Result := TProtocolExceptionSizeLimit.Create(msg); TExceptionType.BAD_VERSION: Result := TProtocolExceptionBadVersion.Create(msg); TExceptionType.NOT_IMPLEMENTED: Result := TProtocolExceptionNotImplemented.Create(msg); TExceptionType.DEPTH_LIMIT: Result := TProtocolExceptionDepthLimit.Create(msg); else ASSERT( TExceptionType.UNKNOWN = aType); Result := TProtocolExceptionUnknown.Create(msg); end; end; { TProtocolExceptionSpecialized } constructor TProtocolExceptionSpecialized.Create(const Msg: string); begin inherited HiddenCreate(Msg); end; { specialized TProtocolExceptions } class function TProtocolExceptionUnknown.GetType: TProtocolException.TExceptionType; begin result := TExceptionType.UNKNOWN; end; class function TProtocolExceptionInvalidData.GetType: TProtocolException.TExceptionType; begin result := TExceptionType.INVALID_DATA; end; class function TProtocolExceptionNegativeSize.GetType: TProtocolException.TExceptionType; begin result := TExceptionType.NEGATIVE_SIZE; end; class function TProtocolExceptionSizeLimit.GetType: TProtocolException.TExceptionType; begin result := TExceptionType.SIZE_LIMIT; end; class function TProtocolExceptionBadVersion.GetType: TProtocolException.TExceptionType; begin result := TExceptionType.BAD_VERSION; end; class function TProtocolExceptionNotImplemented.GetType: TProtocolException.TExceptionType; begin result := TExceptionType.NOT_IMPLEMENTED; end; class function TProtocolExceptionDepthLimit.GetType: TProtocolException.TExceptionType; begin result := TExceptionType.DEPTH_LIMIT; end; { TBinaryProtocolImpl.TFactory } constructor TBinaryProtocolImpl.TFactory.Create( const aStrictRead, aStrictWrite: Boolean); begin inherited Create; FStrictRead := AStrictRead; FStrictWrite := AStrictWrite; end; function TBinaryProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol; begin Result := TBinaryProtocolImpl.Create( trans, FStrictRead, FStrictWrite); end; { TProtocolDecorator } constructor TProtocolDecorator.Create( const aProtocol : IProtocol); begin ASSERT( aProtocol <> nil); inherited Create( aProtocol.Transport); FWrappedProtocol := aProtocol; end; procedure TProtocolDecorator.WriteMessageBegin( const msg: TThriftMessage); begin FWrappedProtocol.WriteMessageBegin( msg); end; procedure TProtocolDecorator.WriteMessageEnd; begin FWrappedProtocol.WriteMessageEnd; end; procedure TProtocolDecorator.WriteStructBegin( const struc: TThriftStruct); begin FWrappedProtocol.WriteStructBegin( struc); end; procedure TProtocolDecorator.WriteStructEnd; begin FWrappedProtocol.WriteStructEnd; end; procedure TProtocolDecorator.WriteFieldBegin( const field: TThriftField); begin FWrappedProtocol.WriteFieldBegin( field); end; procedure TProtocolDecorator.WriteFieldEnd; begin FWrappedProtocol.WriteFieldEnd; end; procedure TProtocolDecorator.WriteFieldStop; begin FWrappedProtocol.WriteFieldStop; end; procedure TProtocolDecorator.WriteMapBegin( const map: TThriftMap); begin FWrappedProtocol.WriteMapBegin( map); end; procedure TProtocolDecorator.WriteMapEnd; begin FWrappedProtocol.WriteMapEnd; end; procedure TProtocolDecorator.WriteListBegin( const list: TThriftList); begin FWrappedProtocol.WriteListBegin( list); end; procedure TProtocolDecorator.WriteListEnd(); begin FWrappedProtocol.WriteListEnd(); end; procedure TProtocolDecorator.WriteSetBegin( const set_: TThriftSet ); begin FWrappedProtocol.WriteSetBegin( set_); end; procedure TProtocolDecorator.WriteSetEnd(); begin FWrappedProtocol.WriteSetEnd(); end; procedure TProtocolDecorator.WriteBool( b: Boolean); begin FWrappedProtocol.WriteBool( b); end; procedure TProtocolDecorator.WriteByte( b: ShortInt); begin FWrappedProtocol.WriteByte( b); end; procedure TProtocolDecorator.WriteI16( i16: SmallInt); begin FWrappedProtocol.WriteI16( i16); end; procedure TProtocolDecorator.WriteI32( i32: Integer); begin FWrappedProtocol.WriteI32( i32); end; procedure TProtocolDecorator.WriteI64( const i64: Int64); begin FWrappedProtocol.WriteI64( i64); end; procedure TProtocolDecorator.WriteDouble( const d: Double); begin FWrappedProtocol.WriteDouble( d); end; procedure TProtocolDecorator.WriteString( const s: string ); begin FWrappedProtocol.WriteString( s); end; procedure TProtocolDecorator.WriteBinary( const b: TBytes); begin FWrappedProtocol.WriteBinary( b); end; procedure TProtocolDecorator.WriteBinary( const bytes : IThriftBytes); begin FWrappedProtocol.WriteBinary( bytes); end; procedure TProtocolDecorator.WriteUuid( const uuid: TGuid); begin FWrappedProtocol.WriteUuid( uuid); end; function TProtocolDecorator.ReadMessageBegin: TThriftMessage; begin result := FWrappedProtocol.ReadMessageBegin; end; procedure TProtocolDecorator.ReadMessageEnd(); begin FWrappedProtocol.ReadMessageEnd(); end; function TProtocolDecorator.ReadStructBegin: TThriftStruct; begin result := FWrappedProtocol.ReadStructBegin; end; procedure TProtocolDecorator.ReadStructEnd; begin FWrappedProtocol.ReadStructEnd; end; function TProtocolDecorator.ReadFieldBegin: TThriftField; begin result := FWrappedProtocol.ReadFieldBegin; end; procedure TProtocolDecorator.ReadFieldEnd(); begin FWrappedProtocol.ReadFieldEnd(); end; function TProtocolDecorator.ReadMapBegin: TThriftMap; begin result := FWrappedProtocol.ReadMapBegin; end; procedure TProtocolDecorator.ReadMapEnd(); begin FWrappedProtocol.ReadMapEnd(); end; function TProtocolDecorator.ReadListBegin: TThriftList; begin result := FWrappedProtocol.ReadListBegin; end; procedure TProtocolDecorator.ReadListEnd(); begin FWrappedProtocol.ReadListEnd(); end; function TProtocolDecorator.ReadSetBegin: TThriftSet; begin result := FWrappedProtocol.ReadSetBegin; end; procedure TProtocolDecorator.ReadSetEnd(); begin FWrappedProtocol.ReadSetEnd(); end; function TProtocolDecorator.ReadBool: Boolean; begin result := FWrappedProtocol.ReadBool; end; function TProtocolDecorator.ReadByte: ShortInt; begin result := FWrappedProtocol.ReadByte; end; function TProtocolDecorator.ReadI16: SmallInt; begin result := FWrappedProtocol.ReadI16; end; function TProtocolDecorator.ReadI32: Integer; begin result := FWrappedProtocol.ReadI32; end; function TProtocolDecorator.ReadI64: Int64; begin result := FWrappedProtocol.ReadI64; end; function TProtocolDecorator.ReadDouble:Double; begin result := FWrappedProtocol.ReadDouble; end; function TProtocolDecorator.ReadBinary: TBytes; begin result := FWrappedProtocol.ReadBinary; end; function TProtocolDecorator.ReadUuid: TGuid; begin result := FWrappedProtocol.ReadUuid; end; function TProtocolDecorator.ReadString: string; begin result := FWrappedProtocol.ReadString; end; function TProtocolDecorator.GetMinSerializedSize( const aType : TType) : Integer; begin result := FWrappedProtocol.GetMinSerializedSize(aType); end; { Init helper functions } procedure Init( var rec : TThriftMessage; const AName: string; const AMessageType: TMessageType; const ASeqID: Integer); begin rec.Name := AName; rec.Type_ := AMessageType; rec.SeqID := ASeqID; end; procedure Init( var rec : TThriftStruct; const AName: string = ''); begin rec.Name := AName; end; procedure Init( var rec : TThriftField; const AName: string; const AType: TType; const AID: SmallInt); begin rec.Name := AName; rec.Type_ := AType; rec.Id := AId; end; procedure Init( var rec : TThriftMap; const AKeyType, AValueType: TType; const ACount: Integer); begin rec.ValueType := AValueType; rec.KeyType := AKeyType; rec.Count := ACount; end; procedure Init( var rec : TThriftSet; const AElementType: TType; const ACount: Integer); begin rec.Count := ACount; rec.ElementType := AElementType; end; procedure Init( var rec : TThriftList; const AElementType: TType; const ACount: Integer); begin rec.Count := ACount; rec.ElementType := AElementType; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Exception.pas0000664000175000017500000000361215165535636022103 0ustar00buildbuild00000000000000(* * 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. *) {$SCOPEDENUMS ON} unit Thrift.Exception; interface uses Classes, SysUtils; type // base class for all Thrift exceptions TException = class( SysUtils.Exception) strict private function GetMessageText : string; public function Message : string; // hide inherited property: allow read, but prevent accidental writes procedure UpdateMessageProperty; // update inherited message property with toString() end; implementation { TException } function TException.Message; // allow read (exception summary), but prevent accidental writes // read will return the exception summary begin result := Self.GetMessageText; end; procedure TException.UpdateMessageProperty; // Update the inherited Message property to better conform to standard behaviour. // Nice benefit: The IDE is now able to show the exception message again. begin inherited Message := Self.GetMessageText; end; function TException.GetMessageText : string; // produces a summary text begin result := Self.ToString; if (result <> '') and (result[1] = '(') then result := Copy(result,2,Length(result)-2); end; end. thrift-0.23.0/lib/delphi/src/Thrift.Server.pas0000664000175000017500000002173315165535636021417 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Server; {$I Thrift.Defines.inc} {$I-} // prevent annoying errors with default log delegate and no console interface uses {$IFDEF OLD_UNIT_NAMES} Windows, SysUtils, {$ELSE} Winapi.Windows, System.SysUtils, {$ENDIF} Thrift, Thrift.Protocol, Thrift.Transport, Thrift.Configuration; type IServerEvents = interface ['{9E2A99C5-EE85-40B2-9A52-2D1722B18176}'] // Called before the server begins. procedure PreServe; // Called when the server transport is ready to accept requests procedure PreAccept; // Called when a new client has connected and the server is about to being processing. function CreateProcessingContext( const input, output : IProtocol) : IProcessorEvents; end; IServer = interface ['{ADC46F2D-8199-4D1C-96D2-87FD54351723}'] procedure Serve; procedure Stop; function GetServerEvents : IServerEvents; procedure SetServerEvents( const value : IServerEvents); property ServerEvents : IServerEvents read GetServerEvents write SetServerEvents; end; TServerImpl = class abstract( TInterfacedObject, IServer ) public type TLogDelegate = reference to procedure( const str: string); strict protected FProcessor : IProcessor; FServerTransport : IServerTransport; FInputTransportFactory : ITransportFactory; FOutputTransportFactory : ITransportFactory; FInputProtocolFactory : IProtocolFactory; FOutputProtocolFactory : IProtocolFactory; FLogDelegate : TLogDelegate; FServerEvents : IServerEvents; FConfiguration : IThriftConfiguration; class procedure DefaultLogDelegate( const str: string); function GetServerEvents : IServerEvents; procedure SetServerEvents( const value : IServerEvents); procedure Serve; virtual; abstract; procedure Stop; virtual; abstract; public constructor Create( const aProcessor :IProcessor; const aServerTransport: IServerTransport; const aInputTransportFactory : ITransportFactory; const aOutputTransportFactory : ITransportFactory; const aInputProtocolFactory : IProtocolFactory; const aOutputProtocolFactory : IProtocolFactory; const aConfig : IThriftConfiguration; const aLogDelegate : TLogDelegate ); overload; constructor Create( const aProcessor: IProcessor; const aServerTransport: IServerTransport; const aTransportFactory: ITransportFactory = nil; const aProtocolFactory: IProtocolFactory = nil; const aConfig : IThriftConfiguration = nil; const aLogDel: TServerImpl.TLogDelegate = nil ); overload; end; TSimpleServer = class( TServerImpl) private FStop : Boolean; public procedure Serve; override; procedure Stop; override; end; implementation { TServerImpl } constructor TServerImpl.Create( const aProcessor: IProcessor; const aServerTransport: IServerTransport; const aInputTransportFactory, aOutputTransportFactory: ITransportFactory; const aInputProtocolFactory, aOutputProtocolFactory: IProtocolFactory; const aConfig : IThriftConfiguration; const aLogDelegate : TLogDelegate); begin inherited Create; FProcessor := aProcessor; FServerTransport := aServerTransport; if aConfig <> nil then FConfiguration := aConfig else FConfiguration := TThriftConfigurationImpl.Create; if aInputTransportFactory <> nil then FInputTransportFactory := aInputTransportFactory else FInputTransportFactory := TTransportFactoryImpl.Create; if aOutputTransportFactory <> nil then FOutputTransportFactory := aOutputTransportFactory else FOutputTransportFactory := TTransportFactoryImpl.Create; if aInputProtocolFactory <> nil then FInputProtocolFactory := aInputProtocolFactory else FInputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; if aOutputProtocolFactory <> nil then FOutputProtocolFactory := aOutputProtocolFactory else FOutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; if Assigned(aLogDelegate) then FLogDelegate := aLogDelegate else FLogDelegate := DefaultLogDelegate; end; constructor TServerImpl.Create( const aProcessor: IProcessor; const aServerTransport: IServerTransport; const aTransportFactory: ITransportFactory; const aProtocolFactory: IProtocolFactory; const aConfig : IThriftConfiguration; const aLogDel: TServerImpl.TLogDelegate); begin Create( aProcessor, aServerTransport, aTransportFactory, aTransportFactory, aProtocolFactory, aProtocolFactory, aConfig, aLogDel); end; class procedure TServerImpl.DefaultLogDelegate( const str: string); begin try Writeln( str); if IoResult <> 0 then OutputDebugString(PChar(str)); except OutputDebugString(PChar(str)); end; end; function TServerImpl.GetServerEvents : IServerEvents; begin result := FServerEvents; end; procedure TServerImpl.SetServerEvents( const value : IServerEvents); begin // if you need more than one, provide a specialized IServerEvents implementation FServerEvents := value; end; { TSimpleServer } procedure TSimpleServer.Serve; var client : ITransport; InputTransport : ITransport; OutputTransport : ITransport; InputProtocol : IProtocol; OutputProtocol : IProtocol; context : IProcessorEvents; begin try FServerTransport.Listen; except on E: Exception do begin FLogDelegate( E.ToString); end; end; if FServerEvents <> nil then FServerEvents.PreServe; client := nil; while (not FStop) do begin try // clean up any old instances before waiting for clients InputTransport := nil; OutputTransport := nil; InputProtocol := nil; OutputProtocol := nil; // close any old connections before before waiting for new clients if client <> nil then try try client.Close; finally client := nil; end; except // catch all, we can't do much about it at this point end; client := FServerTransport.Accept( procedure begin if FServerEvents <> nil then FServerEvents.PreAccept; end); if client = nil then begin if FStop then Abort // silent exception else raise TTransportExceptionUnknown.Create('ServerTransport.Accept() may not return NULL'); end; FLogDelegate( 'Client Connected!'); InputTransport := FInputTransportFactory.GetTransport( client ); OutputTransport := FOutputTransportFactory.GetTransport( client ); InputProtocol := FInputProtocolFactory.GetProtocol( InputTransport ); OutputProtocol := FOutputProtocolFactory.GetProtocol( OutputTransport ); if FServerEvents <> nil then context := FServerEvents.CreateProcessingContext( InputProtocol, OutputProtocol) else context := nil; while not FStop do begin if context <> nil then context.Processing( client); if not FProcessor.Process( InputProtocol, OutputProtocol, context) then Break; end; except on E: TTransportException do begin if FStop then FLogDelegate('TSimpleServer was shutting down, caught ' + E.ToString) else FLogDelegate( E.ToString); end; on E: Exception do begin FLogDelegate( E.ToString); end; end; if context <> nil then begin context.CleanupContext; context := nil; end; if InputTransport <> nil then begin InputTransport.Close; end; if OutputTransport <> nil then begin OutputTransport.Close; end; end; if FStop then begin try FServerTransport.Close; except on E: TTransportException do begin FLogDelegate('TServerTranport failed on close: ' + E.Message); end; end; FStop := False; end; end; procedure TSimpleServer.Stop; begin FStop := True; FServerTransport.Close; end; end. thrift-0.23.0/lib/delphi/src/Thrift.Protocol.JSON.pas0000664000175000017500000007762215165535636022532 0ustar00buildbuild00000000000000(* * 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. *) {$SCOPEDENUMS ON} unit Thrift.Protocol.JSON; interface uses Character, Classes, SysUtils, Math, Generics.Collections, Thrift.Configuration, Thrift.Transport, Thrift.Protocol, Thrift.Stream, Thrift.Utils; type IJSONProtocol = interface( IProtocol) ['{F0DAFDBD-692A-4B71-9736-F5D485A2178F}'] // Read a byte that must match b; otherwise an exception is thrown. procedure ReadJSONSyntaxChar( b : Byte); end; // JSON protocol implementation for thrift. // This is a full-featured protocol supporting Write and Read. // Please see the C++ class header for a detailed description of the protocol's wire format. // Adapted from the C# version. TJSONProtocolImpl = class( TProtocolImpl, IJSONProtocol) public type TFactory = class( TInterfacedObject, IProtocolFactory) public function GetProtocol( const trans: ITransport): IProtocol; end; strict private class function GetTypeNameForTypeID(typeID : TType) : string; class function GetTypeIDForTypeName( const name : string) : TType; strict protected type // Base class for tracking JSON contexts that may require // inserting/Reading additional JSON syntax characters. // This base context does nothing. TJSONBaseContext = class strict protected FProto : Pointer; // weak IJSONProtocol; public constructor Create( const aProto : IJSONProtocol); procedure Write; virtual; procedure Read; virtual; function EscapeNumbers : Boolean; virtual; end; // Context for JSON lists. // Will insert/Read commas before each item except for the first one. TJSONListContext = class( TJSONBaseContext) strict private FFirst : Boolean; public constructor Create( const aProto : IJSONProtocol); procedure Write; override; procedure Read; override; end; // Context for JSON records. Will insert/Read colons before the value portion of each record // pair, and commas before each key except the first. In addition, will indicate that numbers // in the key position need to be escaped in quotes (since JSON keys must be strings). TJSONPairContext = class( TJSONBaseContext) strict private FFirst, FColon : Boolean; public constructor Create( const aProto : IJSONProtocol); procedure Write; override; procedure Read; override; function EscapeNumbers : Boolean; override; end; // Holds up to one byte from the transport TLookaheadReader = class strict protected FProto : Pointer; // weak IJSONProtocol; protected constructor Create( const aProto : IJSONProtocol); strict private FHasData : Boolean; FData : Byte; public // Return and consume the next byte to be Read, either taking it from the // data buffer if present or getting it from the transport otherwise. function Read : Byte; // Return the next byte to be Read without consuming, filling the data // buffer if it has not been filled alReady. function Peek : Byte; end; strict protected // Stack of nested contexts that we may be in FContextStack : TStack; // Current context that we are in FContext : TJSONBaseContext; // Reader that manages a 1-byte buffer FReader : TLookaheadReader; // Push/pop a new JSON context onto/from the stack. procedure ResetContextStack; procedure PushContext( const aCtx : TJSONBaseContext); procedure PopContext; strict protected function GetMinSerializedSize( const aType : TType) : Integer; override; procedure Reset; override; public // TJSONProtocolImpl Constructor constructor Create( const aTrans : ITransport); override; destructor Destroy; override; strict protected // IJSONProtocol // Read a byte that must match b; otherwise an exception is thrown. procedure ReadJSONSyntaxChar( b : Byte); strict private // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its corresponding hex value class function HexVal( ch : Byte) : Byte; // Convert a byte containing a hex value to its corresponding hex character class function HexChar( val : Byte) : Byte; // Write the bytes in array buf as a JSON characters, escaping as needed procedure WriteJSONString( const b : TBytes); overload; procedure WriteJSONString( const str : string); overload; // Write out number as a JSON value. If the context dictates so, it will be // wrapped in quotes to output as a JSON string. procedure WriteJSONInteger( const num : Int64); // Write out a double as a JSON value. If it is NaN or infinity or if the // context dictates escaping, Write out as JSON string. procedure WriteJSONDouble( const num : Double); // Write out contents of byte array b as a JSON string with base-64 encoded data procedure WriteJSONBase64( const b : TBytes); procedure WriteJSONObjectStart; procedure WriteJSONObjectEnd; procedure WriteJSONArrayStart; procedure WriteJSONArrayEnd; public // IProtocol procedure WriteMessageBegin( const aMsg : TThriftMessage); override; procedure WriteMessageEnd; override; procedure WriteStructBegin( const struc: TThriftStruct); override; procedure WriteStructEnd; override; procedure WriteFieldBegin( const field: TThriftField); override; procedure WriteFieldEnd; override; procedure WriteFieldStop; override; procedure WriteMapBegin( const map: TThriftMap); override; procedure WriteMapEnd; override; procedure WriteListBegin( const list: TThriftList); override; procedure WriteListEnd(); override; procedure WriteSetBegin( const set_: TThriftSet ); override; procedure WriteSetEnd(); override; procedure WriteBool( b: Boolean); override; procedure WriteByte( b: ShortInt); override; procedure WriteI16( i16: SmallInt); override; procedure WriteI32( i32: Integer); override; procedure WriteI64( const i64: Int64); override; procedure WriteDouble( const d: Double); override; procedure WriteString( const s: string ); override; procedure WriteBinary( const b: TBytes); override; procedure WriteUuid( const uuid: TGuid); override; // function ReadMessageBegin: TThriftMessage; override; procedure ReadMessageEnd(); override; function ReadStructBegin: TThriftStruct; override; procedure ReadStructEnd; override; function ReadFieldBegin: TThriftField; override; procedure ReadFieldEnd(); override; function ReadMapBegin: TThriftMap; override; procedure ReadMapEnd(); override; function ReadListBegin: TThriftList; override; procedure ReadListEnd(); override; function ReadSetBegin: TThriftSet; override; procedure ReadSetEnd(); override; function ReadBool: Boolean; override; function ReadByte: ShortInt; override; function ReadI16: SmallInt; override; function ReadI32: Integer; override; function ReadI64: Int64; override; function ReadDouble:Double; override; function ReadString : string; override; function ReadBinary: TBytes; override; function ReadUuid: TGuid; override; strict private // Reading methods. // Read in a JSON string, unescaping as appropriate. // Skip Reading from the context if skipContext is true. function ReadJSONString( skipContext : Boolean) : TBytes; // Return true if the given byte could be a valid part of a JSON number. function IsJSONNumeric( b : Byte) : Boolean; // Read in a sequence of characters that are all valid in JSON numbers. Does // not do a complete regex check to validate that this is actually a number. function ReadJSONNumericChars : String; // Read in a JSON number. If the context dictates, Read in enclosing quotes. function ReadJSONInteger : Int64; // Read in a JSON double value. Throw if the value is not wrapped in quotes // when expected or if wrapped in quotes when not expected. function ReadJSONDouble : Double; // Read in a JSON string containing base-64 encoded data and decode it. function ReadJSONBase64 : TBytes; procedure ReadJSONObjectStart; procedure ReadJSONObjectEnd; procedure ReadJSONArrayStart; procedure ReadJSONArrayEnd; end; implementation var COMMA : TBytes; COLON : TBytes; LBRACE : TBytes; RBRACE : TBytes; LBRACKET : TBytes; RBRACKET : TBytes; QUOTE : TBytes; BACKSLASH : TBytes; ESCSEQ : TBytes; const VERSION = 1; JSON_CHAR_TABLE : array[0..$2F] of Byte = (0,0,0,0, 0,0,0,0, Byte('b'),Byte('t'),Byte('n'),0, Byte('f'),Byte('r'),0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,Byte('"'),1, 1,1,1,1, 1,1,1,1, 1,1,1,1); ESCAPE_CHARS = '"\/btnfr'; ESCAPE_CHAR_VALS = '"\/'#8#9#10#12#13; DEF_STRING_SIZE = 16; NAME_BOOL = 'tf'; NAME_BYTE = 'i8'; NAME_I16 = 'i16'; NAME_I32 = 'i32'; NAME_I64 = 'i64'; NAME_DOUBLE = 'dbl'; NAME_STRUCT = 'rec'; NAME_STRING = 'str'; NAME_MAP = 'map'; NAME_LIST = 'lst'; NAME_SET = 'set'; NAME_UUID = 'uid'; INVARIANT_CULTURE : TFormatSettings = ( ThousandSeparator: ','; DecimalSeparator: '.'); //--- TJSONProtocolImpl ---------------------- function TJSONProtocolImpl.TFactory.GetProtocol( const trans: ITransport): IProtocol; begin result := TJSONProtocolImpl.Create( trans); end; class function TJSONProtocolImpl.GetTypeNameForTypeID(typeID : TType) : string; begin case typeID of TType.Bool_: result := NAME_BOOL; TType.Byte_: result := NAME_BYTE; TType.I16: result := NAME_I16; TType.I32: result := NAME_I32; TType.I64: result := NAME_I64; TType.Double_: result := NAME_DOUBLE; TType.String_: result := NAME_STRING; TType.Struct: result := NAME_STRUCT; TType.Map: result := NAME_MAP; TType.Set_: result := NAME_SET; TType.List: result := NAME_LIST; TType.Uuid: result := NAME_UUID; else raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+IntToStr(Ord(typeID))+')'); end; end; class function TJSONProtocolImpl.GetTypeIDForTypeName( const name : string) : TType; begin if name = NAME_BOOL then result := TType.Bool_ else if name = NAME_BYTE then result := TType.Byte_ else if name = NAME_I16 then result := TType.I16 else if name = NAME_I32 then result := TType.I32 else if name = NAME_I64 then result := TType.I64 else if name = NAME_DOUBLE then result := TType.Double_ else if name = NAME_STRUCT then result := TType.Struct else if name = NAME_STRING then result := TType.String_ else if name = NAME_MAP then result := TType.Map else if name = NAME_LIST then result := TType.List else if name = NAME_SET then result := TType.Set_ else if name = NAME_UUID then result := TType.Uuid else raise TProtocolExceptionNotImplemented.Create('Unrecognized type ('+name+')'); end; constructor TJSONProtocolImpl.TJSONBaseContext.Create( const aProto : IJSONProtocol); begin inherited Create; FProto := Pointer(aProto); end; procedure TJSONProtocolImpl.TJSONBaseContext.Write; begin // nothing end; procedure TJSONProtocolImpl.TJSONBaseContext.Read; begin // nothing end; function TJSONProtocolImpl.TJSONBaseContext.EscapeNumbers : Boolean; begin result := FALSE; end; constructor TJSONProtocolImpl.TJSONListContext.Create( const aProto : IJSONProtocol); begin inherited Create( aProto); FFirst := TRUE; end; procedure TJSONProtocolImpl.TJSONListContext.Write; begin if FFirst then FFirst := FALSE else IJSONProtocol(FProto).Transport.Write( COMMA); end; procedure TJSONProtocolImpl.TJSONListContext.Read; begin if FFirst then FFirst := FALSE else IJSONProtocol(FProto).ReadJSONSyntaxChar( COMMA[0]); end; constructor TJSONProtocolImpl.TJSONPairContext.Create( const aProto : IJSONProtocol); begin inherited Create( aProto); FFirst := TRUE; FColon := TRUE; end; procedure TJSONProtocolImpl.TJSONPairContext.Write; begin if FFirst then begin FFirst := FALSE; FColon := TRUE; end else begin if FColon then IJSONProtocol(FProto).Transport.Write( COLON) else IJSONProtocol(FProto).Transport.Write( COMMA); FColon := not FColon; end; end; procedure TJSONProtocolImpl.TJSONPairContext.Read; begin if FFirst then begin FFirst := FALSE; FColon := TRUE; end else begin if FColon then IJSONProtocol(FProto).ReadJSONSyntaxChar( COLON[0]) else IJSONProtocol(FProto).ReadJSONSyntaxChar( COMMA[0]); FColon := not FColon; end; end; function TJSONProtocolImpl.TJSONPairContext.EscapeNumbers : Boolean; begin result := FColon; end; constructor TJSONProtocolImpl.TLookaheadReader.Create( const aProto : IJSONProtocol); begin inherited Create; FProto := Pointer(aProto); FHasData := FALSE; end; function TJSONProtocolImpl.TLookaheadReader.Read : Byte; begin if FHasData then FHasData := FALSE else begin IJSONProtocol(FProto).Transport.ReadAll( @FData, SizeOf(FData), 0, 1); end; result := FData; end; function TJSONProtocolImpl.TLookaheadReader.Peek : Byte; begin if not FHasData then begin IJSONProtocol(FProto).Transport.ReadAll( @FData, SizeOf(FData), 0, 1); FHasData := TRUE; end; result := FData; end; constructor TJSONProtocolImpl.Create( const aTrans : ITransport); begin inherited Create( aTrans); // Stack of nested contexts that we may be in FContextStack := TStack.Create; FContext := TJSONBaseContext.Create( Self); FReader := TLookaheadReader.Create( Self); end; destructor TJSONProtocolImpl.Destroy; begin try ResetContextStack; // free any contents FreeAndNil( FReader); FreeAndNil( FContext); FreeAndNil( FContextStack); finally inherited Destroy; end; end; procedure TJSONProtocolImpl.Reset; begin inherited Reset; ResetContextStack; end; procedure TJSONProtocolImpl.ResetContextStack; begin while FContextStack.Count > 0 do PopContext; end; procedure TJSONProtocolImpl.PushContext( const aCtx : TJSONBaseContext); begin FContextStack.Push( FContext); FContext := aCtx; end; procedure TJSONProtocolImpl.PopContext; begin FreeAndNil(FContext); FContext := FContextStack.Pop; end; procedure TJSONProtocolImpl.ReadJSONSyntaxChar( b : Byte); var ch : Byte; begin ch := FReader.Read; if (ch <> b) then raise TProtocolExceptionInvalidData.Create('Unexpected character ('+Char(ch)+')'); end; class function TJSONProtocolImpl.HexVal( ch : Byte) : Byte; var i : Integer; begin i := StrToIntDef( '$0'+Char(ch), -1); if (0 <= i) and (i < $10) then result := i else raise TProtocolExceptionInvalidData.Create('Expected hex character ('+Char(ch)+')'); end; class function TJSONProtocolImpl.HexChar( val : Byte) : Byte; const HEXCHARS = '0123456789ABCDEF'; begin result := Byte( PChar(HEXCHARS)[val and $0F]); ASSERT( Pos( Char(result), HEXCHARS) > 0); end; procedure TJSONProtocolImpl.WriteJSONString( const str : string); begin WriteJSONString( SysUtils.TEncoding.UTF8.GetBytes( str)); end; procedure TJSONProtocolImpl.WriteJSONString( const b : TBytes); var i : Integer; tmp : TBytes; begin FContext.Write; Transport.Write( QUOTE); for i := 0 to Length(b)-1 do begin if (b[i] and $00FF) >= $30 then begin if (b[i] = BACKSLASH[0]) then begin Transport.Write( BACKSLASH); Transport.Write( BACKSLASH); end else begin Transport.Write( b, i, 1); end; end else begin SetLength( tmp, 2); tmp[0] := JSON_CHAR_TABLE[b[i]]; if (tmp[0] = 1) then begin Transport.Write( b, i, 1) end else if (tmp[0] > 1) then begin Transport.Write( BACKSLASH); Transport.Write( tmp, 0, 1); end else begin Transport.Write( ESCSEQ); tmp[0] := HexChar( b[i] div $10); tmp[1] := HexChar( b[i]); Transport.Write( tmp, 0, 2); end; end; end; Transport.Write( QUOTE); end; procedure TJSONProtocolImpl.WriteJSONInteger( const num : Int64); var str : String; escapeNum : Boolean; begin FContext.Write; str := IntToStr(num); escapeNum := FContext.EscapeNumbers; if escapeNum then Transport.Write( QUOTE); Transport.Write( SysUtils.TEncoding.UTF8.GetBytes( str)); if escapeNum then Transport.Write( QUOTE); end; procedure TJSONProtocolImpl.WriteJSONDouble( const num : Double); var str : string; special : Boolean; escapeNum : Boolean; begin FContext.Write; str := FloatToStr( num, INVARIANT_CULTURE); special := FALSE; case UpCase(str[1]) of 'N' : special := TRUE; // NaN 'I' : special := TRUE; // Infinity '-' : special := (UpCase(str[2]) = 'I'); // -Infinity end; escapeNum := special or FContext.EscapeNumbers; if escapeNum then Transport.Write( QUOTE); Transport.Write( SysUtils.TEncoding.UTF8.GetBytes( str)); if escapeNum then Transport.Write( QUOTE); end; procedure TJSONProtocolImpl.WriteJSONBase64( const b : TBytes); var len, off, cnt : Integer; tmpBuf : TBytes; begin FContext.Write; Transport.Write( QUOTE); len := Length(b); off := 0; SetLength( tmpBuf, 4); while len >= 3 do begin // Encode 3 bytes at a time Base64Utils.Encode( b, off, 3, tmpBuf, 0); Transport.Write( tmpBuf, 0, 4); Inc( off, 3); Dec( len, 3); end; // Encode remainder, if any if len > 0 then begin cnt := Base64Utils.Encode( b, off, len, tmpBuf, 0); Transport.Write( tmpBuf, 0, cnt); end; Transport.Write( QUOTE); end; procedure TJSONProtocolImpl.WriteJSONObjectStart; begin FContext.Write; Transport.Write( LBRACE); PushContext( TJSONPairContext.Create( Self)); end; procedure TJSONProtocolImpl.WriteJSONObjectEnd; begin PopContext; Transport.Write( RBRACE); end; procedure TJSONProtocolImpl.WriteJSONArrayStart; begin FContext.Write; Transport.Write( LBRACKET); PushContext( TJSONListContext.Create( Self)); end; procedure TJSONProtocolImpl.WriteJSONArrayEnd; begin PopContext; Transport.Write( RBRACKET); end; procedure TJSONProtocolImpl.WriteMessageBegin( const aMsg : TThriftMessage); begin Reset; ResetContextStack; // THRIFT-1473 WriteJSONArrayStart; WriteJSONInteger(VERSION); WriteJSONString( SysUtils.TEncoding.UTF8.GetBytes( aMsg.Name)); WriteJSONInteger( LongInt( aMsg.Type_)); WriteJSONInteger( aMsg.SeqID); end; procedure TJSONProtocolImpl.WriteMessageEnd; begin WriteJSONArrayEnd; end; procedure TJSONProtocolImpl.WriteStructBegin( const struc: TThriftStruct); begin WriteJSONObjectStart; end; procedure TJSONProtocolImpl.WriteStructEnd; begin WriteJSONObjectEnd; end; procedure TJSONProtocolImpl.WriteFieldBegin( const field : TThriftField); begin WriteJSONInteger(field.ID); WriteJSONObjectStart; WriteJSONString( GetTypeNameForTypeID(field.Type_)); end; procedure TJSONProtocolImpl.WriteFieldEnd; begin WriteJSONObjectEnd; end; procedure TJSONProtocolImpl.WriteFieldStop; begin // nothing to do end; procedure TJSONProtocolImpl.WriteMapBegin( const map: TThriftMap); begin WriteJSONArrayStart; WriteJSONString( GetTypeNameForTypeID( map.KeyType)); WriteJSONString( GetTypeNameForTypeID( map.ValueType)); WriteJSONInteger( map.Count); WriteJSONObjectStart; end; procedure TJSONProtocolImpl.WriteMapEnd; begin WriteJSONObjectEnd; WriteJSONArrayEnd; end; procedure TJSONProtocolImpl.WriteListBegin( const list: TThriftList); begin WriteJSONArrayStart; WriteJSONString( GetTypeNameForTypeID( list.ElementType)); WriteJSONInteger(list.Count); end; procedure TJSONProtocolImpl.WriteListEnd; begin WriteJSONArrayEnd; end; procedure TJSONProtocolImpl.WriteSetBegin( const set_: TThriftSet); begin WriteJSONArrayStart; WriteJSONString( GetTypeNameForTypeID( set_.ElementType)); WriteJSONInteger( set_.Count); end; procedure TJSONProtocolImpl.WriteSetEnd; begin WriteJSONArrayEnd; end; procedure TJSONProtocolImpl.WriteBool( b: Boolean); begin if b then WriteJSONInteger( 1) else WriteJSONInteger( 0); end; procedure TJSONProtocolImpl.WriteByte( b: ShortInt); begin WriteJSONInteger( b); end; procedure TJSONProtocolImpl.WriteI16( i16: SmallInt); begin WriteJSONInteger( i16); end; procedure TJSONProtocolImpl.WriteI32( i32: Integer); begin WriteJSONInteger( i32); end; procedure TJSONProtocolImpl.WriteI64( const i64: Int64); begin WriteJSONInteger(i64); end; procedure TJSONProtocolImpl.WriteDouble( const d: Double); begin WriteJSONDouble( d); end; procedure TJSONProtocolImpl.WriteString( const s: string ); begin WriteJSONString( SysUtils.TEncoding.UTF8.GetBytes( s)); end; procedure TJSONProtocolImpl.WriteBinary( const b: TBytes); begin WriteJSONBase64( b); end; procedure TJSONProtocolImpl.WriteUuid( const uuid: TGuid); begin WriteString( Copy( GuidToString(uuid), 2, 36)); // strip off the { braces } end; function TJSONProtocolImpl.ReadJSONString( skipContext : Boolean) : TBytes; var buffer : TThriftMemoryStream; ch : Byte; wch : Word; highSurogate: Char; surrogatePairs: Array[0..1] of Char; off : Integer; tmp : TBytes; begin highSurogate := #0; buffer := TThriftMemoryStream.Create; try if not skipContext then FContext.Read; ReadJSONSyntaxChar( QUOTE[0]); while TRUE do begin ch := FReader.Read; if (ch = QUOTE[0]) then Break; // check for escapes if (ch <> ESCSEQ[0]) then begin buffer.Write( ch, 1); Continue; end; // distuinguish between \uNNNN and \? ch := FReader.Read; if (ch <> ESCSEQ[1]) then begin off := Pos( Char(ch), ESCAPE_CHARS); if off < 1 then raise TProtocolExceptionInvalidData.Create('Expected control char'); ch := Byte( ESCAPE_CHAR_VALS[off]); buffer.Write( ch, 1); Continue; end; // it is \uXXXX SetLength( tmp, 4); Transport.ReadAll( tmp, 0, 4); wch := (HexVal(tmp[0]) shl 12) + (HexVal(tmp[1]) shl 8) + (HexVal(tmp[2]) shl 4) + HexVal(tmp[3]); // we need to make UTF8 bytes from it, to be decoded later if CharUtils.IsHighSurrogate(char(wch)) then begin if highSurogate <> #0 then raise TProtocolExceptionInvalidData.Create('Expected low surrogate char'); highSurogate := char(wch); end else if CharUtils.IsLowSurrogate(char(wch)) then begin if highSurogate = #0 then TProtocolExceptionInvalidData.Create('Expected high surrogate char'); surrogatePairs[0] := highSurogate; surrogatePairs[1] := char(wch); tmp := TEncoding.UTF8.GetBytes(surrogatePairs); buffer.Write( tmp[0], Length(tmp)); highSurogate := #0; end else begin tmp := SysUtils.TEncoding.UTF8.GetBytes(Char(wch)); buffer.Write( tmp[0], Length(tmp)); end; end; if highSurogate <> #0 then raise TProtocolExceptionInvalidData.Create('Expected low surrogate char'); SetLength( result, buffer.Size); if buffer.Size > 0 then Move( buffer.Memory^, result[0], Length(result)); finally buffer.Free; end; end; function TJSONProtocolImpl.IsJSONNumeric( b : Byte) : Boolean; const NUMCHARS = ['+','-','.','0','1','2','3','4','5','6','7','8','9','E','e']; begin result := CharInSet( Char(b), NUMCHARS); end; function TJSONProtocolImpl.ReadJSONNumericChars : string; var strbld : TThriftStringBuilder; ch : Byte; begin strbld := TThriftStringBuilder.Create; try while TRUE do begin ch := FReader.Peek; if IsJSONNumeric(ch) then strbld.Append( Char(FReader.Read)) else Break; end; result := strbld.ToString; finally strbld.Free; end; end; function TJSONProtocolImpl.ReadJSONInteger : Int64; var str : string; begin FContext.Read; if FContext.EscapeNumbers then ReadJSONSyntaxChar( QUOTE[0]); str := ReadJSONNumericChars; if FContext.EscapeNumbers then ReadJSONSyntaxChar( QUOTE[0]); try result := StrToInt64(str); except on e:Exception do begin raise TProtocolExceptionInvalidData.Create('Bad data encounted in numeric data ('+str+') ('+e.Message+')'); end; end; end; function TJSONProtocolImpl.ReadJSONDouble : Double; var dub : Double; str : string; begin FContext.Read; if FReader.Peek = QUOTE[0] then begin str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( TRUE)); dub := StrToFloat( str, INVARIANT_CULTURE); if not FContext.EscapeNumbers() and not Math.IsNaN(dub) and not Math.IsInfinite(dub) then begin // Throw exception -- we should not be in a string in Self case raise TProtocolExceptionInvalidData.Create('Numeric data unexpectedly quoted'); end; result := dub; Exit; end; // will throw - we should have had a quote if escapeNum == true if FContext.EscapeNumbers then ReadJSONSyntaxChar( QUOTE[0]); try str := ReadJSONNumericChars; result := StrToFloat( str, INVARIANT_CULTURE); except on e:Exception do raise TProtocolExceptionInvalidData.Create('Bad data encounted in numeric data ('+str+') ('+e.Message+')'); end; end; function TJSONProtocolImpl.ReadJSONBase64 : TBytes; var b : TBytes; len, off, size : Integer; begin b := ReadJSONString(false); len := Length(b); off := 0; size := 0; // reduce len to ignore fill bytes Dec(len); while (len >= 0) and (b[len] = Byte('=')) do Dec(len); Inc(len); // read & decode full byte triplets = 4 source bytes while (len >= 4) do begin // Decode 4 bytes at a time Inc( size, Base64Utils.Decode( b, off, 4, b, size)); // decoded in place Inc( off, 4); Dec( len, 4); end; // Don't decode if we hit the end or got a single leftover byte (invalid // base64 but legal for skip of regular string type) if len > 1 then begin // Decode remainder Inc( size, Base64Utils.Decode( b, off, len, b, size)); // decoded in place end; // resize to final size and return the data SetLength( b, size); result := b; end; procedure TJSONProtocolImpl.ReadJSONObjectStart; begin FContext.Read; ReadJSONSyntaxChar( LBRACE[0]); PushContext( TJSONPairContext.Create( Self)); end; procedure TJSONProtocolImpl.ReadJSONObjectEnd; begin ReadJSONSyntaxChar( RBRACE[0]); PopContext; end; procedure TJSONProtocolImpl.ReadJSONArrayStart; begin FContext.Read; ReadJSONSyntaxChar( LBRACKET[0]); PushContext( TJSONListContext.Create( Self)); end; procedure TJSONProtocolImpl.ReadJSONArrayEnd; begin ReadJSONSyntaxChar( RBRACKET[0]); PopContext; end; function TJSONProtocolImpl.ReadMessageBegin: TThriftMessage; begin Reset; ResetContextStack; // THRIFT-1473 Init( result); ReadJSONArrayStart; if ReadJSONInteger <> VERSION then raise TProtocolExceptionBadVersion.Create('Message contained bad version.'); result.Name := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( FALSE)); result.Type_ := TMessageType( ReadJSONInteger); result.SeqID := ReadJSONInteger; end; procedure TJSONProtocolImpl.ReadMessageEnd; begin ReadJSONArrayEnd; end; function TJSONProtocolImpl.ReadStructBegin : TThriftStruct ; begin ReadJSONObjectStart; Init( result); end; procedure TJSONProtocolImpl.ReadStructEnd; begin ReadJSONObjectEnd; end; function TJSONProtocolImpl.ReadFieldBegin : TThriftField; var ch : Byte; str : string; begin Init( result); ch := FReader.Peek; if ch = RBRACE[0] then result.Type_ := TType.Stop else begin result.ID := ReadJSONInteger; ReadJSONObjectStart; str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( FALSE)); result.Type_ := GetTypeIDForTypeName( str); end; end; procedure TJSONProtocolImpl.ReadFieldEnd; begin ReadJSONObjectEnd; end; function TJSONProtocolImpl.ReadMapBegin : TThriftMap; var str : string; begin Init( result); ReadJSONArrayStart; str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE)); result.KeyType := GetTypeIDForTypeName( str); str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE)); result.ValueType := GetTypeIDForTypeName( str); result.Count := ReadJSONInteger; CheckReadBytesAvailable(result); ReadJSONObjectStart; end; procedure TJSONProtocolImpl.ReadMapEnd; begin ReadJSONObjectEnd; ReadJSONArrayEnd; end; function TJSONProtocolImpl.ReadListBegin : TThriftList; var str : string; begin Init( result); ReadJSONArrayStart; str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE)); result.ElementType := GetTypeIDForTypeName( str); result.Count := ReadJSONInteger; CheckReadBytesAvailable(result); end; procedure TJSONProtocolImpl.ReadListEnd; begin ReadJSONArrayEnd; end; function TJSONProtocolImpl.ReadSetBegin : TThriftSet; var str : string; begin Init( result); ReadJSONArrayStart; str := SysUtils.TEncoding.UTF8.GetString( ReadJSONString(FALSE)); result.ElementType := GetTypeIDForTypeName( str); result.Count := ReadJSONInteger; CheckReadBytesAvailable(result); end; procedure TJSONProtocolImpl.ReadSetEnd; begin ReadJSONArrayEnd; end; function TJSONProtocolImpl.ReadBool : Boolean; begin result := (ReadJSONInteger <> 0); end; function TJSONProtocolImpl.ReadByte : ShortInt; begin result := ReadJSONInteger; end; function TJSONProtocolImpl.ReadI16 : SmallInt; begin result := ReadJSONInteger; end; function TJSONProtocolImpl.ReadI32 : LongInt; begin result := ReadJSONInteger; end; function TJSONProtocolImpl.ReadI64 : Int64; begin result := ReadJSONInteger; end; function TJSONProtocolImpl.ReadDouble : Double; begin result := ReadJSONDouble; end; function TJSONProtocolImpl.ReadString : string; begin result := SysUtils.TEncoding.UTF8.GetString( ReadJSONString( FALSE)); end; function TJSONProtocolImpl.ReadBinary : TBytes; begin result := ReadJSONBase64; end; function TJSONProtocolImpl.ReadUuid: TGuid; begin result := StringToGUID( '{' + ReadString + '}'); end; function TJSONProtocolImpl.GetMinSerializedSize( const aType : TType) : Integer; // Return the minimum number of bytes a type will consume on the wire begin case aType of TType.Stop: result := 1; // T_STOP needs to count itself TType.Void: result := 1; // T_VOID needs to count itself TType.Bool_: result := 1; TType.Byte_: result := 1; TType.Double_: result := 1; TType.I16: result := 1; TType.I32: result := 1; TType.I64: result := 1; TType.String_: result := 2; // empty string TType.Struct: result := 2; // empty struct TType.Map: result := 2; // empty map TType.Set_: result := 2; // empty set TType.List: result := 2; // empty list TType.Uuid: result := 36; // "E236974D-F0B0-4E05-8F29-0B455D41B1A1" else raise TTransportExceptionBadArgs.Create('Unhandled type code'); end; end; //--- init code --- procedure InitBytes( var b : TBytes; aData : array of Byte); begin SetLength( b, Length(aData)); Move( aData, b[0], Length(b)); end; initialization InitBytes( COMMA, [Byte(',')]); InitBytes( COLON, [Byte(':')]); InitBytes( LBRACE, [Byte('{')]); InitBytes( RBRACE, [Byte('}')]); InitBytes( LBRACKET, [Byte('[')]); InitBytes( RBRACKET, [Byte(']')]); InitBytes( QUOTE, [Byte('"')]); InitBytes( BACKSLASH, [Byte('\')]); InitBytes( ESCSEQ, [Byte('\'),Byte('u'),Byte('0'),Byte('0')]); end. thrift-0.23.0/lib/delphi/src/Thrift.Utils.pas0000664000175000017500000003317015165535636021247 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Utils; interface {$I Thrift.Defines.inc} uses {$IFDEF OLD_UNIT_NAMES} Classes, Windows, SysUtils, Character, SyncObjs, TypInfo, Rtti; {$ELSE} System.Classes, Winapi.Windows, System.SysUtils, System.Character, System.SyncObjs, System.TypInfo, System.Rtti; {$ENDIF} type ISupportsToString = interface ['{AF71C350-E0CD-4E94-B77C-0310DC8227FF}'] function ToString : string; end; IOverlappedHelper = interface ['{A1832EFA-2E02-4884-8F09-F0A0277157FA}'] function Overlapped : TOverlapped; function OverlappedPtr : POverlapped; function WaitHandle : THandle; function WaitFor(dwTimeout: DWORD) : DWORD; end; TOverlappedHelperImpl = class( TInterfacedObject, IOverlappedHelper) strict protected FOverlapped : TOverlapped; FEvent : TEvent; // IOverlappedHelper function Overlapped : TOverlapped; function OverlappedPtr : POverlapped; function WaitHandle : THandle; function WaitFor(dwTimeout: DWORD) : DWORD; public constructor Create; destructor Destroy; override; end; TThriftStringBuilder = class( TStringBuilder) public function Append(const Value: TBytes): TStringBuilder; overload; function Append(const Value: ISupportsToString): TStringBuilder; overload; end; Base64Utils = class sealed public class function Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static; class function Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static; end; CharUtils = class sealed public class function IsHighSurrogate( const c : Char) : Boolean; static; inline; class function IsLowSurrogate( const c : Char) : Boolean; static; inline; class function IsHtmlDoctype( const fourBytes : Integer) : Boolean; static; end; IntegerUtils = class sealed strict private class procedure SwapBytes( var one, two : Byte); static; inline; class procedure Swap2( const pValue : Pointer); static; class procedure Swap4( const pValue : Pointer); static; class procedure Swap8( const pValue : Pointer); static; public class procedure SwapByteOrder( const pValue : Pointer; const size : Integer); overload; static; end; // problem: inheritance possible for class helpers ONLY but not with record helpers // workaround: use static class method instead of record helper :-( GuidUtils = class sealed public // new stuff class function SwapByteOrder( const aGuid : TGuid) : TGuid; static; {$IFDEF Debug} class procedure SelfTest; static; {$ENDIF} end; EnumUtils = class sealed public class function ToString(const value : Integer) : string; reintroduce; static; inline; end; StringUtils = class sealed public class function ToString(const value : T) : string; reintroduce; static; inline; end; const THRIFT_MIMETYPE = 'application/x-thrift'; {$IFDEF Win64} function InterlockedExchangeAdd64( var Addend : Int64; Value : Int64) : Int64; {$ENDIF} implementation { TOverlappedHelperImpl } constructor TOverlappedHelperImpl.Create; begin inherited Create; FillChar( FOverlapped, SizeOf(FOverlapped), 0); FEvent := TEvent.Create( nil, TRUE, FALSE, ''); // always ManualReset, see MSDN FOverlapped.hEvent := FEvent.Handle; end; destructor TOverlappedHelperImpl.Destroy; begin try FOverlapped.hEvent := 0; FreeAndNil( FEvent); finally inherited Destroy; end; end; function TOverlappedHelperImpl.Overlapped : TOverlapped; begin result := FOverlapped; end; function TOverlappedHelperImpl.OverlappedPtr : POverlapped; begin result := @FOverlapped; end; function TOverlappedHelperImpl.WaitHandle : THandle; begin result := FOverlapped.hEvent; end; function TOverlappedHelperImpl.WaitFor( dwTimeout : DWORD) : DWORD; begin result := WaitForSingleObject( FOverlapped.hEvent, dwTimeout); end; { Base64Utils } class function Base64Utils.Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; const ENCODE_TABLE : PAnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; begin ASSERT( len in [1..3]); dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shr 2) and $3F]); case len of 3 : begin Inc(dstOff); dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]); Inc(dstOff); dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff + 1] shl 2) and $3C) or ((src[srcOff + 2] shr 6) and $03)]); Inc(dstOff); dst[dstOff] := Byte( ENCODE_TABLE[ src[srcOff + 2] and $3F]); result := 4; end; 2 : begin Inc(dstOff); dst[dstOff] := Byte( ENCODE_TABLE[ ((src[srcOff] shl 4) and $30) or ((src[srcOff + 1] shr 4) and $0F)]); Inc(dstOff); dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff + 1] shl 2) and $3C]); result := 3; end; 1 : begin Inc(dstOff); dst[dstOff] := Byte( ENCODE_TABLE[ (src[srcOff] shl 4) and $30]); result := 2; end; else ASSERT( FALSE); result := 0; // because invalid call end; end; class function Base64Utils.Decode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; const DECODE_TABLE : array[0..$FF] of Integer = ( -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ); begin ASSERT( len in [1..4]); result := 1; dst[dstOff] := ((DECODE_TABLE[src[srcOff] and $0FF] shl 2) or (DECODE_TABLE[src[srcOff + 1] and $0FF] shr 4)); if (len > 2) then begin Inc( result); Inc( dstOff); dst[dstOff] := (((DECODE_TABLE[src[srcOff + 1] and $0FF] shl 4) and $F0) or (DECODE_TABLE[src[srcOff + 2] and $0FF] shr 2)); if (len > 3) then begin Inc( result); Inc( dstOff); dst[dstOff] := (((DECODE_TABLE[src[srcOff + 2] and $0FF] shl 6) and $C0) or DECODE_TABLE[src[srcOff + 3] and $0FF]); end; end; end; class function CharUtils.IsHighSurrogate( const c : Char) : Boolean; begin {$IF CompilerVersion < 25.0} {$IFDEF OLD_UNIT_NAMES} result := Character.IsHighSurrogate(c); {$ELSE} result := System.Character.IsHighSurrogate(c); {$ENDIF} {$ELSE} result := c.IsHighSurrogate(); {$IFEND} end; class function CharUtils.IsLowSurrogate( const c : Char) : Boolean; begin {$IF CompilerVersion < 25.0} {$IFDEF OLD_UNIT_NAMES} result := Character.IsLowSurrogate(c); {$ELSE} result := System.Character.IsLowSurrogate(c); {$ENDIF} {$ELSE} result := c.IsLowSurrogate(); {$IFEND} end; class function CharUtils.IsHtmlDoctype( const fourBytes : Integer) : Boolean; var pc : PAnsiChar; const HTML_BEGIN : PAnsiChar = 'OD!<'; // first 4 bytes of ' HTML_BEGIN[0] then Exit(FALSE); Inc( pc); if UpCase(pc^) <> HTML_BEGIN[1] then Exit(FALSE); Inc( pc); if UpCase(pc^) <> HTML_BEGIN[2] then Exit(FALSE); Inc( pc); result := (UpCase(pc^) = HTML_BEGIN[3]); end; { IntegerUtils } class procedure IntegerUtils.SwapBytes( var one, two : Byte); var tmp : Byte; begin tmp := one; one := two; two := tmp; end; class procedure IntegerUtils.Swap2( const pValue : Pointer); var pData : PByteArray absolute pValue; begin SwapBytes( pData^[0], pData^[1]); end; class procedure IntegerUtils.Swap4( const pValue : Pointer); var pData : PByteArray absolute pValue; begin SwapBytes( pData^[0], pData^[3]); SwapBytes( pData^[1], pData^[2]); end; class procedure IntegerUtils.Swap8( const pValue : Pointer); var pData : PByteArray absolute pValue; begin SwapBytes( pData^[0], pData^[7]); SwapBytes( pData^[1], pData^[6]); SwapBytes( pData^[2], pData^[5]); SwapBytes( pData^[3], pData^[4]); end; class procedure IntegerUtils.SwapByteOrder( const pValue : Pointer; const size : Integer); begin case size of 2 : Swap2( pValue); 4 : Swap4( pValue); 8 : Swap8( pValue); else raise EArgumentException.Create('Unexpected size'); end; end; { GuidUtils } class function GuidUtils.SwapByteOrder( const aGuid : TGuid) : TGuid; // convert to/from network byte order // - https://www.ietf.org/rfc/rfc4122.txt // - https://stackoverflow.com/questions/10850075/guid-uuid-compatibility-issue-between-net-and-linux // - https://lists.gnu.org/archive/html/bug-parted/2002-01/msg00099.html begin result := aGuid; IntegerUtils.SwapByteOrder( @result.D1, SizeOf(result.D1)); IntegerUtils.SwapByteOrder( @result.D2, SizeOf(result.D2)); IntegerUtils.SwapByteOrder( @result.D3, SizeOf(result.D3)); //result.D4 = array of byte -> implicitly correct end; {$IFDEF Debug} class procedure GuidUtils.SelfTest; var guid : TGuid; pBytes : PByteArray; i, expected : Integer; const TEST_GUID : TGuid = '{00112233-4455-6677-8899-aabbccddeeff}'; begin // host to network guid := TEST_GUID; guid := GuidUtils.SwapByteOrder(guid); // validate network order pBytes := @guid; for i := 0 to $F do begin expected := i * $11; ASSERT( pBytes^[i] = expected); end; // network to host and final validation guid := GuidUtils.SwapByteOrder(guid); ASSERT( IsEqualGuid( guid, TEST_GUID)); // prevent collisions with SysUtils.TGuidHelper guid := TGuid.NewGuid; end; {$ENDIF} {$IFDEF Win64} function InterlockedCompareExchange64( var Target : Int64; Exchange, Comparand : Int64) : Int64; inline; begin {$IFDEF OLD_UNIT_NAMES} result := Windows.InterlockedCompareExchange64( Target, Exchange, Comparand); {$ELSE} result := WinApi.Windows.InterlockedCompareExchange64( Target, Exchange, Comparand); {$ENDIF} end; function InterlockedExchangeAdd64( var Addend : Int64; Value : Int64) : Int64; var old : Int64; begin repeat Old := Addend; until (InterlockedCompareExchange64( Addend, Old + Value, Old) = Old); result := Old; end; {$ENDIF} { EnumUtils } class function EnumUtils.ToString(const value : Integer) : string; var pType : PTypeInfo; begin pType := PTypeInfo(TypeInfo(T)); if Assigned(pType) and (pType^.Kind = tkEnumeration) {$IF CompilerVersion >= 23.0} // TODO: Range correct? What we know is that XE does not offer it, but Rio has it and (pType^.TypeData^.MaxValue >= value) and (pType^.TypeData^.MinValue <= value) {$ELSE} and FALSE // THRIFT-5048: pType^.TypeData^ member not supported -> prevent GetEnumName() from reading outside the legal range {$IFEND} then result := GetEnumName( PTypeInfo(pType), value) else result := IntToStr(Ord(value)); end; { StringUtils } class function StringUtils.ToString(const value : T) : string; type PInterface = ^IInterface; var pType : PTypeInfo; stos : ISupportsToString; pIntf : PInterface; // Workaround: Rio does not allow the direct typecast begin pType := PTypeInfo(TypeInfo(T)); if Assigned(pType) then begin case pType^.Kind of tkInterface : begin pIntf := PInterface(@value); if Supports( pIntf^, ISupportsToString, stos) then begin result := stos.toString; Exit; end; end; tkEnumeration : begin case SizeOf(value) of 1 : begin result := EnumUtils.ToString( PShortInt(@value)^); Exit; end; 2 : begin result := EnumUtils.ToString( PSmallInt(@value)^); Exit; end; 4 : begin result := EnumUtils.ToString( PLongInt(@value)^); Exit; end; else ASSERT(FALSE); // in theory, this should not happen end; end; end; end; result := TValue.From(value).ToString; end; { TThriftStringBuilder } function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder; begin Result := Append( string( RawByteString(Value)) ); end; function TThriftStringBuilder.Append( const Value: ISupportsToString): TStringBuilder; begin Result := Append( Value.ToString ); end; begin {$IFDEF Debug} GuidUtils.SelfTest; {$ENDIF} end. thrift-0.23.0/lib/delphi/src/Thrift.Transport.pas0000664000175000017500000014644715165535636022157 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit Thrift.Transport; {$I Thrift.Defines.inc} {$SCOPEDENUMS ON} interface uses Classes, SysUtils, Math, Generics.Collections, {$IFDEF OLD_UNIT_NAMES} WinSock, Sockets, {$ELSE} Winapi.WinSock, {$IFDEF OLD_SOCKETS} Web.Win.Sockets, {$ELSE} Thrift.Socket, {$ENDIF} {$ENDIF} Thrift.Configuration, Thrift.Collections, Thrift.Exception, Thrift.Utils, Thrift.WinHTTP, Thrift.Stream; type IStreamTransport = interface; ITransport = interface ['{52F81383-F880-492F-8AA7-A66B85B93D6B}'] function GetIsOpen: Boolean; property IsOpen: Boolean read GetIsOpen; function Peek: Boolean; procedure Open; procedure Close; function Read(var buf: TBytes; off: Integer; len: Integer): Integer; overload; function Read(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload; function ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer; overload; function ReadAll(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload; procedure Write( const buf: TBytes); overload; procedure Write( const buf: TBytes; off: Integer; len: Integer); overload; procedure Write( const pBuf : Pointer; off, len : Integer); overload; procedure Write( const pBuf : Pointer; len : Integer); overload; procedure Flush; function Configuration : IThriftConfiguration; function MaxMessageSize : Integer; procedure ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); procedure CheckReadBytesAvailable( const numBytes : Int64); procedure UpdateKnownMessageSize( const size : Int64); end; TTransportBase = class abstract( TInterfacedObject) strict protected function GetIsOpen: Boolean; virtual; abstract; property IsOpen: Boolean read GetIsOpen; function Peek: Boolean; virtual; procedure Open(); virtual; abstract; procedure Close(); virtual; abstract; function Read(var buf: TBytes; off: Integer; len: Integer): Integer; overload; inline; function Read(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload; virtual; abstract; function ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer; overload; inline; function ReadAll(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; overload; virtual; procedure Write( const buf: TBytes); overload; inline; procedure Write( const buf: TBytes; off: Integer; len: Integer); overload; inline; procedure Write( const pBuf : Pointer; len : Integer); overload; inline; procedure Write( const pBuf : Pointer; off, len : Integer); overload; virtual; abstract; procedure Flush; virtual; function Configuration : IThriftConfiguration; virtual; abstract; procedure UpdateKnownMessageSize( const size : Int64); virtual; abstract; end; // base class for all endpoint transports, e.g. sockets, pipes or HTTP TEndpointTransportBase = class abstract( TTransportBase, ITransport) strict private FRemainingMessageSize : Int64; FKnownMessageSize : Int64; FConfiguration : IThriftConfiguration; strict protected function Configuration : IThriftConfiguration; override; function MaxMessageSize : Integer; property RemainingMessageSize : Int64 read FRemainingMessageSize; property KnownMessageSize : Int64 read FKnownMessageSize; procedure ResetMessageSizeAndConsumedBytes( const newSize : Int64 = -1); procedure UpdateKnownMessageSize(const size : Int64); override; 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; // base class for all layered transports, e.g. framed TLayeredTransportBase = class abstract( TTransportBase, ITransport) strict private FTransport : T; strict protected property InnerTransport : T read FTransport; function GetUnderlyingTransport: ITransport; function Configuration : IThriftConfiguration; override; procedure UpdateKnownMessageSize( const size : Int64); override; function MaxMessageSize : Integer; inline; procedure ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); inline; procedure CheckReadBytesAvailable( const numBytes : Int64); virtual; public constructor Create( const aTransport: T); reintroduce; property UnderlyingTransport: ITransport read GetUnderlyingTransport; end; TTransportException = class abstract( TException) public type TExceptionType = ( Unknown, NotOpen, AlreadyOpen, TimedOut, EndOfFile, BadArgs, Interrupted, CorruptedData ); strict protected constructor HiddenCreate(const Msg: string); class function GetType: TExceptionType; virtual; abstract; public class function Create( aType: TExceptionType): TTransportException; overload; deprecated 'Use specialized TTransportException types (or regenerate from IDL)'; class function Create( const msg: string): TTransportException; reintroduce; overload; deprecated 'Use specialized TTransportException types (or regenerate from IDL)'; class function Create( aType: TExceptionType; const msg: string): TTransportException; overload; deprecated 'Use specialized TTransportException types (or regenerate from IDL)'; property Type_: TExceptionType read GetType; end; // Needed to remove deprecation warning TTransportExceptionSpecialized = class abstract (TTransportException) public constructor Create(const Msg: string); end; TTransportExceptionUnknown = class (TTransportExceptionSpecialized) strict protected class function GetType: TTransportException.TExceptionType; override; end; TTransportExceptionNotOpen = class (TTransportExceptionSpecialized) strict protected class function GetType: TTransportException.TExceptionType; override; end; TTransportExceptionAlreadyOpen = class (TTransportExceptionSpecialized) strict protected class function GetType: TTransportException.TExceptionType; override; end; TTransportExceptionTimedOut = class (TTransportExceptionSpecialized) strict protected class function GetType: TTransportException.TExceptionType; override; end; TTransportExceptionEndOfFile = class (TTransportExceptionSpecialized) strict protected class function GetType: TTransportException.TExceptionType; override; end; TTransportExceptionBadArgs = class (TTransportExceptionSpecialized) strict protected class function GetType: TTransportException.TExceptionType; override; end; TTransportExceptionInterrupted = class (TTransportExceptionSpecialized) strict protected class function GetType: TTransportException.TExceptionType; override; end; TTransportExceptionCorruptedData = class (TTransportExceptionSpecialized) protected class function GetType: TTransportException.TExceptionType; override; end; TSecureProtocol = ( // outdated, for compatibility only SSL_2, SSL_3, TLS_1, TLS_1_1, // secure (as of today) TLS_1_2, TLS_1_3 ); TSecureProtocols = set of TSecureProtocol; IHTTPClient = interface( ITransport ) ['{7BF615DD-8680-4004-A5B2-88947BA3BA3D}'] procedure SetDnsResolveTimeout(const Value: Integer); function GetDnsResolveTimeout: Integer; procedure SetConnectionTimeout(const Value: Integer); function GetConnectionTimeout: Integer; procedure SetSendTimeout(const Value: Integer); function GetSendTimeout: Integer; procedure SetReadTimeout(const Value: Integer); function GetReadTimeout: Integer; function GetCustomHeaders: IThriftDictionary; procedure SendRequest; function GetSecureProtocols : TSecureProtocols; procedure SetSecureProtocols( const value : TSecureProtocols); property DnsResolveTimeout: Integer read GetDnsResolveTimeout write SetDnsResolveTimeout; property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout; property SendTimeout: Integer read GetSendTimeout write SetSendTimeout; property ReadTimeout: Integer read GetReadTimeout write SetReadTimeout; property CustomHeaders: IThriftDictionary read GetCustomHeaders; property SecureProtocols : TSecureProtocols read GetSecureProtocols write SetSecureProtocols; end; IServerTransport = interface ['{FA01363F-6B40-482F-971E-4A085535EFC8}'] procedure Listen; procedure Close; function Accept( const fnAccepting: TProc): ITransport; function Configuration : IThriftConfiguration; end; TServerTransportImpl = class( TInterfacedObject, IServerTransport) strict private FConfig : IThriftConfiguration; strict protected function Configuration : IThriftConfiguration; procedure Listen; virtual; abstract; procedure Close; virtual; abstract; function Accept( const fnAccepting: TProc): ITransport; virtual; abstract; public constructor Create( const aConfig : IThriftConfiguration); end; ITransportFactory = interface ['{DD809446-000F-49E1-9BFF-E0D0DC76A9D7}'] function GetTransport( const aTransport: ITransport): ITransport; end; TTransportFactoryImpl = class ( TInterfacedObject, ITransportFactory) strict protected function GetTransport( const aTransport: ITransport): ITransport; virtual; end; TTcpSocketStreamImpl = class( TThriftStreamImpl) {$IFDEF OLD_SOCKETS} strict private type TWaitForData = ( wfd_HaveData, wfd_Timeout, wfd_Error); strict private FTcpClient : TCustomIpClient; FTimeout : Integer; function Select( ReadReady, WriteReady, ExceptFlag: PBoolean; TimeOut: Integer; var wsaError : Integer): Integer; function WaitForData( TimeOut : Integer; pBuf : Pointer; DesiredBytes: Integer; var wsaError, bytesReady : Integer): TWaitForData; {$ELSE} FTcpClient: TSocket; strict protected const SLEEP_TIME = 200; {$ENDIF} strict protected procedure Write( const pBuf : Pointer; offset, count: Integer); override; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override; procedure Open; override; procedure Close; override; procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; public {$IFDEF OLD_SOCKETS} constructor Create( const aTcpClient: TCustomIpClient; const aTimeout : Integer = DEFAULT_THRIFT_TIMEOUT); {$ELSE} constructor Create( const aTcpClient: TSocket; const aTimeout : Longword = DEFAULT_THRIFT_TIMEOUT); {$ENDIF} end; IStreamTransport = interface( ITransport ) ['{A8479B47-2A3E-4421-A9A0-D5A9EDCC634A}'] function GetInputStream: IThriftStream; function GetOutputStream: IThriftStream; property InputStream : IThriftStream read GetInputStream; property OutputStream : IThriftStream read GetOutputStream; end; TStreamTransportImpl = class( TEndpointTransportBase, IStreamTransport) strict private FInternalInputStream : IThriftStream; FInternalOutputStream : IThriftStream; strict protected function GetIsOpen: Boolean; override; function GetInputStream: IThriftStream; inline; procedure SetInputStream( const stream : IThriftStream); function GetOutputStream: IThriftStream; inline; procedure SetOutputStream( const stream : IThriftStream); strict protected procedure Open; override; procedure Close; override; 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; property InputStream : IThriftStream read GetInputStream; property OutputStream : IThriftStream read GetOutputStream; end; TBufferedStreamImpl = class( TThriftStreamImpl) strict private FStream : IThriftStream; FBufSize : Integer; FReadBuffer : TThriftMemoryStream; FWriteBuffer : TThriftMemoryStream; strict protected procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); override; function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override; procedure Open; override; procedure Close; override; procedure Flush; override; function IsOpen: Boolean; override; function ToArray: TBytes; override; function CanSeek : Boolean; override; function Size : Int64; override; function Position : Int64; override; public constructor Create( const aStream: IThriftStream; const aBufSize : Integer); destructor Destroy; override; end; TServerSocketImpl = class( TServerTransportImpl) strict private {$IFDEF OLD_SOCKETS} FServer : TTcpServer; FPort : Integer; FClientTimeout : Integer; {$ELSE} FServer: TServerSocket; {$ENDIF} FUseBufferedSocket : Boolean; FOwnsServer : Boolean; strict protected function Accept( const fnAccepting: TProc) : ITransport; override; public {$IFDEF OLD_SOCKETS} constructor Create( const aServer: TTcpServer; const aClientTimeout : Integer = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil); overload; constructor Create( const aPort: Integer; const aClientTimeout: Integer = DEFAULT_THRIFT_TIMEOUT; aUseBufferedSockets: Boolean = FALSE; const aConfig : IThriftConfiguration = nil); overload; {$ELSE} constructor Create( const aServer: TServerSocket; const aClientTimeout: Longword = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil); overload; constructor Create( const aPort: Integer; const aClientTimeout: Longword = DEFAULT_THRIFT_TIMEOUT; aUseBufferedSockets: Boolean = FALSE; const aConfig : IThriftConfiguration = nil); overload; {$ENDIF} destructor Destroy; override; procedure Listen; override; procedure Close; override; end; TBufferedTransportImpl = class( TLayeredTransportBase) strict private FInputBuffer : IThriftStream; FOutputBuffer : IThriftStream; FBufSize : Integer; procedure InitBuffers; strict protected function GetIsOpen: Boolean; override; procedure Flush; override; public type TFactory = class( TTransportFactoryImpl ) public function GetTransport( const aTransport: ITransport): ITransport; override; end; constructor Create( const aTransport : IStreamTransport; const aBufSize: Integer = 1024); procedure Open(); override; procedure Close(); override; function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override; procedure Write( const pBuf : Pointer; off, len : Integer); override; procedure CheckReadBytesAvailable( const value : Int64); override; property IsOpen: Boolean read GetIsOpen; end; TSocketImpl = class(TStreamTransportImpl) strict private {$IFDEF OLD_SOCKETS} FClient : TCustomIpClient; {$ELSE} FClient: TSocket; {$ENDIF} FOwnsClient : Boolean; FHost : string; FPort : Integer; {$IFDEF OLD_SOCKETS} FTimeout : Integer; {$ELSE} FTimeout : Longword; {$ENDIF} procedure InitSocket; strict protected function GetIsOpen: Boolean; override; public {$IFDEF OLD_SOCKETS} constructor Create( const aClient : TCustomIpClient; const aOwnsClient : Boolean; const aTimeout: Integer = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil); overload; constructor Create( const aHost: string; const aPort: Integer; const aTimeout: Integer = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil); overload; {$ELSE} constructor Create(const aClient: TSocket; const aOwnsClient: Boolean; const aConfig : IThriftConfiguration = nil); overload; constructor Create( const aHost: string; const aPort: Integer; const aTimeout: Longword = DEFAULT_THRIFT_TIMEOUT; const aConfig : IThriftConfiguration = nil); overload; {$ENDIF} destructor Destroy; override; procedure Open; override; procedure Close; override; {$IFDEF OLD_SOCKETS} property TcpClient: TCustomIpClient read FClient; {$ELSE} property TcpClient: TSocket read FClient; {$ENDIF} property Host : string read FHost; property Port: Integer read FPort; end; TFramedTransportImpl = class( TLayeredTransportBase) strict protected type TFramedHeader = Int32; strict protected FWriteBuffer : TThriftMemoryStream; FReadBuffer : TThriftMemoryStream; procedure InitWriteBuffer; procedure ReadFrame; procedure Open(); override; function GetIsOpen: Boolean; override; procedure Close(); override; function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override; procedure Write( const pBuf : Pointer; off, len : Integer); override; procedure CheckReadBytesAvailable( const value : Int64); override; procedure Flush; override; public type TFactory = class( TTransportFactoryImpl ) public function GetTransport( const aTransport: ITransport): ITransport; override; end; constructor Create( const aTransport: ITransport); overload; destructor Destroy; override; end; const // From https://learn.microsoft.com/en-us/windows/win32/secauthn/protocols-in-tls-ssl--schannel-ssp- // > TLS 1.3 is supported starting in Windows 11 and Windows Server 2022. // > Enabling TLS 1.3 on earlier versions of Windows is not a safe system configuration. DEFAULT_THRIFT_SECUREPROTOCOLS = [ TSecureProtocol.TLS_1_2 //TSecureProtocol.TLS_1_3 -- not supported on Win10 (see comment) ]; implementation { TTransportBase } procedure TTransportBase.Flush; begin // nothing to do end; function TTransportBase.Peek: Boolean; begin Result := IsOpen; end; function TTransportBase.Read(var buf: TBytes; off: Integer; len: Integer): Integer; begin if Length(buf) > 0 then result := Read( @buf[0], Length(buf), off, len) else result := 0; end; function TTransportBase.ReadAll(var buf: TBytes; off: Integer; len: Integer): Integer; begin if Length(buf) > 0 then result := ReadAll( @buf[0], Length(buf), off, len) else result := 0; end; function TTransportBase.ReadAll(const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; var ret : Integer; begin result := 0; while result < len do begin ret := Read( pBuf, buflen, off + result, len - result); if ret > 0 then Inc( result, ret) else raise TTransportExceptionNotOpen.Create( 'Cannot read, Remote side has closed' ); end; end; procedure TTransportBase.Write( const buf: TBytes); begin if Length(buf) > 0 then Write( @buf[0], 0, Length(buf)); end; procedure TTransportBase.Write( const buf: TBytes; off: Integer; len: Integer); begin if Length(buf) > 0 then Write( @buf[0], off, len); end; procedure TTransportBase.Write( const pBuf : Pointer; len : Integer); begin Self.Write( pBuf, 0, len); end; { TEndpointTransportBase } constructor TEndpointTransportBase.Create( const aConfig : IThriftConfiguration); begin inherited Create; if aConfig <> nil then FConfiguration := aConfig else FConfiguration := TThriftConfigurationImpl.Create; ResetMessageSizeAndConsumedBytes; end; function TEndpointTransportBase.Configuration : IThriftConfiguration; begin result := FConfiguration; end; function TEndpointTransportBase.MaxMessageSize : Integer; begin ASSERT( Configuration <> nil); result := Configuration.MaxMessageSize; end; procedure TEndpointTransportBase.ResetMessageSizeAndConsumedBytes( const newSize : Int64); // Resets RemainingMessageSize to the configured maximum begin // full reset if newSize < 0 then begin FKnownMessageSize := MaxMessageSize; FRemainingMessageSize := MaxMessageSize; Exit; end; // update only: message size can shrink, but not grow ASSERT( KnownMessageSize <= MaxMessageSize); if newSize > KnownMessageSize then raise TTransportExceptionEndOfFile.Create('MaxMessageSize reached'); FKnownMessageSize := newSize; FRemainingMessageSize := newSize; end; procedure TEndpointTransportBase.UpdateKnownMessageSize( const size : Int64); // 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; ResetMessageSizeAndConsumedBytes(size); CountConsumedMessageBytes(consumed); end; procedure TEndpointTransportBase.CheckReadBytesAvailable( const numBytes : Int64); // Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data begin if (RemainingMessageSize < numBytes) or (numBytes < 0) then raise TTransportExceptionEndOfFile.Create('MaxMessageSize reached'); end; procedure TEndpointTransportBase.CountConsumedMessageBytes( const numBytes : Int64); // Consumes numBytes from the RemainingMessageSize. begin if (RemainingMessageSize >= numBytes) and (numBytes >= 0) then Dec( FRemainingMessageSize, numBytes) else begin FRemainingMessageSize := 0; raise TTransportExceptionEndOfFile.Create('MaxMessageSize reached'); end; end; { TLayeredTransportBase } constructor TLayeredTransportBase.Create( const aTransport: T); begin inherited Create; FTransport := aTransport; end; function TLayeredTransportBase.GetUnderlyingTransport: ITransport; begin result := InnerTransport; end; function TLayeredTransportBase.Configuration : IThriftConfiguration; begin result := InnerTransport.Configuration; end; procedure TLayeredTransportBase.UpdateKnownMessageSize( const size : Int64); begin InnerTransport.UpdateKnownMessageSize( size); end; function TLayeredTransportBase.MaxMessageSize : Integer; begin result := InnerTransport.MaxMessageSize; end; procedure TLayeredTransportBase.ResetMessageSizeAndConsumedBytes( const knownSize : Int64 = -1); begin InnerTransport.ResetMessageSizeAndConsumedBytes( knownSize); end; procedure TLayeredTransportBase.CheckReadBytesAvailable( const numBytes : Int64); begin InnerTransport.CheckReadBytesAvailable( numBytes); end; { TTransportException } constructor TTransportException.HiddenCreate(const Msg: string); begin inherited Create(Msg); end; class function TTransportException.Create(aType: TExceptionType): TTransportException; begin //no inherited; {$WARN SYMBOL_DEPRECATED OFF} Result := Create(aType, '') {$WARN SYMBOL_DEPRECATED DEFAULT} end; class function TTransportException.Create(aType: TExceptionType; const msg: string): TTransportException; begin case aType of TExceptionType.NotOpen: Result := TTransportExceptionNotOpen.Create(msg); TExceptionType.AlreadyOpen: Result := TTransportExceptionAlreadyOpen.Create(msg); TExceptionType.TimedOut: Result := TTransportExceptionTimedOut.Create(msg); TExceptionType.EndOfFile: Result := TTransportExceptionEndOfFile.Create(msg); TExceptionType.BadArgs: Result := TTransportExceptionBadArgs.Create(msg); TExceptionType.Interrupted: Result := TTransportExceptionInterrupted.Create(msg); else ASSERT( TExceptionType.Unknown = aType); Result := TTransportExceptionUnknown.Create(msg); end; end; class function TTransportException.Create(const msg: string): TTransportException; begin Result := TTransportExceptionUnknown.Create(Msg); end; { TTransportExceptionSpecialized } constructor TTransportExceptionSpecialized.Create(const Msg: string); begin inherited HiddenCreate(Msg); end; { specialized TTransportExceptions } class function TTransportExceptionUnknown.GetType: TTransportException.TExceptionType; begin result := TExceptionType.Unknown; end; class function TTransportExceptionNotOpen.GetType: TTransportException.TExceptionType; begin result := TExceptionType.NotOpen; end; class function TTransportExceptionAlreadyOpen.GetType: TTransportException.TExceptionType; begin result := TExceptionType.AlreadyOpen; end; class function TTransportExceptionTimedOut.GetType: TTransportException.TExceptionType; begin result := TExceptionType.TimedOut; end; class function TTransportExceptionEndOfFile.GetType: TTransportException.TExceptionType; begin result := TExceptionType.EndOfFile; end; class function TTransportExceptionBadArgs.GetType: TTransportException.TExceptionType; begin result := TExceptionType.BadArgs; end; class function TTransportExceptionInterrupted.GetType: TTransportException.TExceptionType; begin result := TExceptionType.Interrupted; end; class function TTransportExceptionCorruptedData.GetType: TTransportException.TExceptionType; begin result := TExceptionType.CorruptedData; end; { TTransportFactoryImpl } function TTransportFactoryImpl.GetTransport( const aTransport: ITransport): ITransport; begin Result := aTransport; end; { TServerTransportImpl } constructor TServerTransportImpl.Create( const aConfig : IThriftConfiguration); begin inherited Create; if aConfig <> nil then FConfig := aConfig else FConfig := TThriftConfigurationImpl.Create; end; function TServerTransportImpl.Configuration : IThriftConfiguration; begin result := FConfig; end; { TServerSocket } {$IFDEF OLD_SOCKETS} constructor TServerSocketImpl.Create( const aServer: TTcpServer; const aClientTimeout : Integer; const aConfig : IThriftConfiguration); {$ELSE} constructor TServerSocketImpl.Create( const aServer: TServerSocket; const aClientTimeout: Longword; const aConfig : IThriftConfiguration); {$ENDIF} begin inherited Create( aConfig); FServer := aServer; {$IFDEF OLD_SOCKETS} FClientTimeout := aClientTimeout; {$ELSE} FServer.RecvTimeout := aClientTimeout; FServer.SendTimeout := aClientTimeout; {$ENDIF} end; {$IFDEF OLD_SOCKETS} constructor TServerSocketImpl.Create( const aPort: Integer; const aClientTimeout: Integer; aUseBufferedSockets: Boolean; const aConfig : IThriftConfiguration); {$ELSE} constructor TServerSocketImpl.Create( const aPort: Integer; const aClientTimeout: Longword; aUseBufferedSockets: Boolean; const aConfig : IThriftConfiguration); {$ENDIF} begin inherited Create( aConfig); {$IFDEF OLD_SOCKETS} FPort := aPort; FClientTimeout := aClientTimeout; FOwnsServer := True; FServer := TTcpServer.Create( nil ); FServer.BlockMode := bmBlocking; {$IF CompilerVersion >= 21.0} FServer.LocalPort := AnsiString( IntToStr( FPort)); {$ELSE} FServer.LocalPort := IntToStr( FPort); {$IFEND} {$ELSE} FOwnsServer := True; FServer := TServerSocket.Create(aPort, aClientTimeout, aClientTimeout); {$ENDIF} FUseBufferedSocket := aUseBufferedSockets; end; destructor TServerSocketImpl.Destroy; begin if FOwnsServer then begin FServer.Free; FServer := nil; end; inherited; end; function TServerSocketImpl.Accept( const fnAccepting: TProc): ITransport; var {$IFDEF OLD_SOCKETS} client : TCustomIpClient; {$ELSE} client: TSocket; {$ENDIF} trans : IStreamTransport; begin if FServer = nil then begin raise TTransportExceptionNotOpen.Create('No underlying server socket.'); end; {$IFDEF OLD_SOCKETS} client := nil; try client := TCustomIpClient.Create(nil); if Assigned(fnAccepting) then fnAccepting(); if not FServer.Accept( client) then begin client.Free; Result := nil; Exit; end; if client = nil then begin Result := nil; Exit; end; trans := TSocketImpl.Create( client, TRUE, FClientTimeout, Configuration); client := nil; // trans owns it now if FUseBufferedSocket then result := TBufferedTransportImpl.Create( trans) else result := trans; except on E: Exception do begin client.Free; raise TTransportExceptionUnknown.Create(E.ToString); end; end; {$ELSE} if Assigned(fnAccepting) then fnAccepting(); client := FServer.Accept; try trans := TSocketImpl.Create(client, TRUE, Configuration); client := nil; if FUseBufferedSocket then Result := TBufferedTransportImpl.Create(trans) else Result := trans; except client.Free; raise; end; {$ENDIF} end; procedure TServerSocketImpl.Listen; begin if FServer <> nil then begin {$IFDEF OLD_SOCKETS} try FServer.Active := True; except on E: Exception do raise TTransportExceptionUnknown.Create('Could not accept on listening socket: ' + E.Message); end; {$ELSE} FServer.Listen; {$ENDIF} end; end; procedure TServerSocketImpl.Close; begin if FServer <> nil then {$IFDEF OLD_SOCKETS} try FServer.Active := False; except on E: Exception do raise TTransportExceptionUnknown.Create('Error on closing socket : ' + E.Message); end; {$ELSE} FServer.Close; {$ENDIF} end; { TSocket } {$IFDEF OLD_SOCKETS} constructor TSocketImpl.Create( const aClient : TCustomIpClient; const aOwnsClient : Boolean; const aTimeout: Integer; const aConfig : IThriftConfiguration); {$ELSE} constructor TSocketImpl.Create(const aClient: TSocket; const aOwnsClient: Boolean; const aConfig : IThriftConfiguration); {$ENDIF} var stream : IThriftStream; begin FClient := aClient; FOwnsClient := aOwnsClient; {$IFDEF OLD_SOCKETS} FTimeout := aTimeout; {$ELSE} FTimeout := aClient.RecvTimeout; {$ENDIF} stream := TTcpSocketStreamImpl.Create( FClient, FTimeout); inherited Create( stream, stream, aConfig); end; {$IFDEF OLD_SOCKETS} constructor TSocketImpl.Create(const aHost: string; const aPort, aTimeout: Integer; const aConfig : IThriftConfiguration); {$ELSE} constructor TSocketImpl.Create(const aHost: string; const aPort : Integer; const aTimeout: Longword; const aConfig : IThriftConfiguration); {$ENDIF} begin inherited Create(nil,nil, aConfig); FHost := aHost; FPort := aPort; FTimeout := aTimeout; InitSocket; end; destructor TSocketImpl.Destroy; begin if FOwnsClient then FreeAndNil( FClient); inherited; end; procedure TSocketImpl.Close; begin inherited Close; SetInputStream( nil); SetOutputStream( nil); if FOwnsClient then FreeAndNil( FClient) else FClient := nil; end; function TSocketImpl.GetIsOpen: Boolean; begin {$IFDEF OLD_SOCKETS} Result := (FClient <> nil) and FClient.Connected; {$ELSE} Result := (FClient <> nil) and FClient.IsOpen {$ENDIF} end; procedure TSocketImpl.InitSocket; var stream : IThriftStream; begin if FOwnsClient then FreeAndNil( FClient) else FClient := nil; {$IFDEF OLD_SOCKETS} FClient := TTcpClient.Create( nil); {$ELSE} FClient := TSocket.Create(FHost, FPort); {$ENDIF} FOwnsClient := True; stream := TTcpSocketStreamImpl.Create( FClient, FTimeout); SetInputStream( stream); SetOutputStream( stream); end; procedure TSocketImpl.Open; begin if IsOpen then begin raise TTransportExceptionAlreadyOpen.Create('Socket already connected'); end; if FHost = '' then begin raise TTransportExceptionNotOpen.Create('Cannot open null host'); end; if Port <= 0 then begin raise TTransportExceptionNotOpen.Create('Cannot open without port'); end; if FClient = nil then InitSocket; {$IFDEF OLD_SOCKETS} FClient.RemoteHost := TSocketHost( Host); FClient.RemotePort := TSocketPort( IntToStr( Port)); FClient.Connect; {$ELSE} FClient.Open; {$ENDIF} SetInputStream( TTcpSocketStreamImpl.Create( FClient, FTimeout)); SetOutputStream( InputStream); // same end; { TBufferedStream } procedure TBufferedStreamImpl.Close; begin Flush; FStream := nil; FReadBuffer.Free; FReadBuffer := nil; FWriteBuffer.Free; FWriteBuffer := nil; end; constructor TBufferedStreamImpl.Create( const aStream: IThriftStream; const aBufSize : Integer); begin inherited Create; FStream := aStream; FBufSize := aBufSize; FReadBuffer := TThriftMemoryStream.Create(FBufSize); FWriteBuffer := TThriftMemoryStream.Create(FBufSize); end; destructor TBufferedStreamImpl.Destroy; begin Close; inherited; end; procedure TBufferedStreamImpl.Flush; var buf : TBytes; len : Integer; begin if IsOpen then begin len := FWriteBuffer.Size; if len > 0 then begin SetLength( buf, len ); FWriteBuffer.Position := 0; FWriteBuffer.Read( Pointer(@buf[0])^, len ); FStream.Write( buf, 0, len ); end; FWriteBuffer.Clear; end; end; function TBufferedStreamImpl.IsOpen: Boolean; begin Result := (FWriteBuffer <> nil) and (FReadBuffer <> nil) and (FStream <> nil) and FStream.IsOpen; end; procedure TBufferedStreamImpl.Open; begin FStream.Open; end; function TBufferedStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; var nRead : Integer; tempbuf : TBytes; pTmp : PByte; begin inherited; Result := 0; if IsOpen then begin while count > 0 do begin if FReadBuffer.Position >= FReadBuffer.Size then begin FReadBuffer.Clear; SetLength( tempbuf, FBufSize); nRead := FStream.Read( tempbuf, 0, FBufSize ); if nRead = 0 then Break; // avoid infinite loop FReadBuffer.WriteBuffer( Pointer(@tempbuf[0])^, nRead ); FReadBuffer.Position := 0; end; if FReadBuffer.Position < FReadBuffer.Size then begin nRead := Min( FReadBuffer.Size - FReadBuffer.Position, count); pTmp := pBuf; Inc( pTmp, offset); Inc( Result, FReadBuffer.Read( pTmp^, nRead)); Dec( count, nRead); Inc( offset, nRead); end; end; end; end; function TBufferedStreamImpl.ToArray: TBytes; var len : Integer; begin if IsOpen then len := FReadBuffer.Size else len := 0; SetLength( Result, len); if len > 0 then begin FReadBuffer.Position := 0; FReadBuffer.Read( Pointer(@Result[0])^, len ); end; end; procedure TBufferedStreamImpl.Write( const pBuf : Pointer; offset: Integer; count: Integer); var pTmp : PByte; begin inherited; if count > 0 then begin if IsOpen then begin pTmp := pBuf; Inc( pTmp, offset); FWriteBuffer.Write( pTmp^, count ); if FWriteBuffer.Size > FBufSize then begin Flush; end; end; end; end; function TBufferedStreamImpl.CanSeek : Boolean; begin result := TRUE; end; function TBufferedStreamImpl.Size : Int64; begin result := FReadBuffer.Size; end; function TBufferedStreamImpl.Position : Int64; begin result := FReadBuffer.Position; end; { TStreamTransportImpl } constructor TStreamTransportImpl.Create( const aInputStream, aOutputStream : IThriftStream; const aConfig : IThriftConfiguration); begin inherited Create( aConfig); SetInputStream( aInputStream); SetOutputStream( aOutputStream); end; destructor TStreamTransportImpl.Destroy; begin SetInputStream( nil); SetInputStream( nil); inherited; end; procedure TStreamTransportImpl.Close; begin SetInputStream( nil); SetInputStream( nil); end; procedure TStreamTransportImpl.Flush; begin if OutputStream = nil then begin raise TTransportExceptionNotOpen.Create('Cannot flush null outputstream' ); end; OutputStream.Flush; end; function TStreamTransportImpl.GetInputStream: IThriftStream; begin Result := FInternalInputStream; end; procedure TStreamTransportImpl.SetInputStream( const stream : IThriftStream); begin FInternalInputStream := stream; ResetMessageSizeAndConsumedBytes(-1); // full reset to configured maximum UpdateKnownMessageSize( -1); // adjust to real stream size end; function TStreamTransportImpl.GetOutputStream: IThriftStream; begin Result := FInternalOutputStream; end; procedure TStreamTransportImpl.SetOutputStream( const stream : IThriftStream); begin FInternalOutputStream := stream; end; function TStreamTransportImpl.GetIsOpen: Boolean; begin Result := True; end; procedure TStreamTransportImpl.Open; begin // nothing to do end; function TStreamTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; begin if InputStream = nil then raise TTransportExceptionNotOpen.Create('Cannot read from null inputstream' ); Result := InputStream.Read( pBuf,buflen, off, len ); CountConsumedMessageBytes( result); end; procedure TStreamTransportImpl.Write( const pBuf : Pointer; off, len : Integer); begin if OutputStream = nil then raise TTransportExceptionNotOpen.Create('Cannot write to null outputstream' ); 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 } constructor TBufferedTransportImpl.Create( const aTransport : IStreamTransport; const aBufSize: Integer); begin ASSERT( aTransport <> nil); inherited Create( aTransport); FBufSize := aBufSize; InitBuffers; end; procedure TBufferedTransportImpl.Close; begin InnerTransport.Close; FInputBuffer := nil; FOutputBuffer := nil; end; procedure TBufferedTransportImpl.Flush; begin if FOutputBuffer <> nil then begin FOutputBuffer.Flush; end; end; function TBufferedTransportImpl.GetIsOpen: Boolean; begin Result := InnerTransport.IsOpen; end; procedure TBufferedTransportImpl.InitBuffers; begin if InnerTransport.InputStream <> nil then begin FInputBuffer := TBufferedStreamImpl.Create( InnerTransport.InputStream, FBufSize ); end; if InnerTransport.OutputStream <> nil then begin FOutputBuffer := TBufferedStreamImpl.Create( InnerTransport.OutputStream, FBufSize ); end; end; procedure TBufferedTransportImpl.Open; begin InnerTransport.Open; InitBuffers; // we need to get the buffers to match FTransport substreams again end; function TBufferedTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; begin if FInputBuffer <> nil then Result := FInputBuffer.Read( pBuf,buflen, off, len ) else Result := 0; end; procedure TBufferedTransportImpl.Write( const pBuf : Pointer; off, len : Integer); begin if FOutputBuffer <> nil then begin FOutputBuffer.Write( pBuf, off, len ); end; end; procedure TBufferedTransportImpl.CheckReadBytesAvailable( const value : Int64); var buffered, need : Int64; begin need := value; // buffered bytes buffered := FInputBuffer.Size - FInputBuffer.Position; if buffered < need then InnerTransport.CheckReadBytesAvailable( need - buffered); end; { TBufferedTransportImpl.TFactory } function TBufferedTransportImpl.TFactory.GetTransport( const aTransport: ITransport): ITransport; begin Result := TFramedTransportImpl.Create( aTransport); end; { TFramedTransportImpl } constructor TFramedTransportImpl.Create( const aTransport: ITransport); begin ASSERT( aTransport <> nil); inherited Create( aTransport); InitWriteBuffer; end; destructor TFramedTransportImpl.Destroy; begin FWriteBuffer.Free; FWriteBuffer := nil; FReadBuffer.Free; FReadBuffer := nil; inherited; end; procedure TFramedTransportImpl.Close; begin InnerTransport.Close; end; procedure TFramedTransportImpl.Flush; var buf : TBytes; len : Integer; data_len : Int64; begin if not IsOpen then raise TTransportExceptionNotOpen.Create('not open'); len := FWriteBuffer.Size; SetLength( buf, len); if len > 0 then begin System.Move( FWriteBuffer.Memory^, buf[0], len ); end; data_len := len - SizeOf(TFramedHeader); if (0 > data_len) or (data_len > Configuration.MaxFrameSize) then raise TTransportExceptionUnknown.Create('TFramedTransport.Flush: invalid frame size ('+IntToStr(data_len)+')') else UpdateKnownMessageSize( len); InitWriteBuffer; buf[0] := Byte($FF and (data_len shr 24)); buf[1] := Byte($FF and (data_len shr 16)); buf[2] := Byte($FF and (data_len shr 8)); buf[3] := Byte($FF and data_len); InnerTransport.Write( buf, 0, len ); InnerTransport.Flush; end; function TFramedTransportImpl.GetIsOpen: Boolean; begin Result := InnerTransport.IsOpen; end; procedure TFramedTransportImpl.InitWriteBuffer; const DUMMY_HEADER : TFramedHeader = 0; begin FreeAndNil( FWriteBuffer); FWriteBuffer := TThriftMemoryStream.Create(1024); FWriteBuffer.Write( DUMMY_HEADER, SizeOf(DUMMY_HEADER)); end; procedure TFramedTransportImpl.Open; begin InnerTransport.Open; end; function TFramedTransportImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; var pTmp : PByte; begin if len > (buflen-off) then len := buflen-off; pTmp := pBuf; Inc( pTmp, off); if (FReadBuffer <> nil) and (len > 0) then begin result := FReadBuffer.Read( pTmp^, len); if result > 0 then Exit; end; ReadFrame; if len > 0 then Result := FReadBuffer.Read( pTmp^, len) else Result := 0; end; procedure TFramedTransportImpl.ReadFrame; var i32rd : packed array[0..SizeOf(TFramedHeader)-1] of Byte; size : Integer; buff : TBytes; begin InnerTransport.ReadAll( @i32rd[0], SizeOf(i32rd), 0, SizeOf(i32rd)); size := ((i32rd[0] and $FF) shl 24) or ((i32rd[1] and $FF) shl 16) or ((i32rd[2] and $FF) shl 8) or (i32rd[3] and $FF); if size < 0 then begin Close(); raise TTransportExceptionCorruptedData.Create('Read a negative frame size ('+IntToStr(size)+')'); end; if Int64(size) > Int64(Configuration.MaxFrameSize) then begin Close(); if CharUtils.IsHtmlDoctype(size) then raise TTransportExceptionCorruptedData.Create('Remote end sends HTML instead of data') else raise TTransportExceptionCorruptedData.Create('Frame size ('+IntToStr(size)+') larger than allowed maximum ('+IntToStr(Configuration.MaxFrameSize)+')'); end; UpdateKnownMessageSize(size + SizeOf(size)); SetLength( buff, size ); InnerTransport.ReadAll( buff, 0, size ); FreeAndNil( FReadBuffer); FReadBuffer := TThriftMemoryStream.Create(1024); if Length(buff) > 0 then FReadBuffer.Write( Pointer(@buff[0])^, size ); FReadBuffer.Position := 0; end; procedure TFramedTransportImpl.Write( const pBuf : Pointer; off, len : Integer); var pTmp : PByte; begin if len > 0 then begin pTmp := pBuf; Inc( pTmp, off); FWriteBuffer.Write( pTmp^, len ); end; end; procedure TFramedTransportImpl.CheckReadBytesAvailable( const value : Int64); var buffered, need : Int64; begin need := value; // buffered bytes buffered := FReadBuffer.Size - FReadBuffer.Position; if buffered < need then InnerTransport.CheckReadBytesAvailable( need - buffered); end; { TFramedTransport.TFactory } function TFramedTransportImpl.TFactory.GetTransport( const aTransport: ITransport): ITransport; begin Result := TFramedTransportImpl.Create( aTransport); end; { TTcpSocketStreamImpl } procedure TTcpSocketStreamImpl.Close; begin FTcpClient.Close; end; {$IFDEF OLD_SOCKETS} constructor TTcpSocketStreamImpl.Create( const aTcpClient: TCustomIpClient; const aTimeout : Integer); begin inherited Create; FTcpClient := aTcpClient; FTimeout := aTimeout; end; {$ELSE} constructor TTcpSocketStreamImpl.Create( const aTcpClient: TSocket; const aTimeout : Longword); begin inherited Create; FTcpClient := aTcpClient; if aTimeout = 0 then FTcpClient.RecvTimeout := SLEEP_TIME else FTcpClient.RecvTimeout := aTimeout; FTcpClient.SendTimeout := aTimeout; end; {$ENDIF} procedure TTcpSocketStreamImpl.Flush; begin // nothing to do end; function TTcpSocketStreamImpl.IsOpen: Boolean; begin {$IFDEF OLD_SOCKETS} Result := FTcpClient.Active; {$ELSE} Result := FTcpClient.IsOpen; {$ENDIF} end; procedure TTcpSocketStreamImpl.Open; begin FTcpClient.Open; end; {$IFDEF OLD_SOCKETS} function TTcpSocketStreamImpl.Select( ReadReady, WriteReady, ExceptFlag: PBoolean; TimeOut: Integer; var wsaError : Integer): Integer; var ReadFds: TFDset; ReadFdsptr: PFDset; WriteFds: TFDset; WriteFdsptr: PFDset; ExceptFds: TFDset; ExceptFdsptr: PFDset; tv: timeval; Timeptr: PTimeval; socket : TSocket; begin if not FTcpClient.Active then begin wsaError := WSAEINVAL; Exit( SOCKET_ERROR); end; socket := FTcpClient.Handle; if Assigned(ReadReady) then begin ReadFdsptr := @ReadFds; FD_ZERO(ReadFds); FD_SET(socket, ReadFds); end else begin ReadFdsptr := nil; end; if Assigned(WriteReady) then begin WriteFdsptr := @WriteFds; FD_ZERO(WriteFds); FD_SET(socket, WriteFds); end else begin WriteFdsptr := nil; end; if Assigned(ExceptFlag) then begin ExceptFdsptr := @ExceptFds; FD_ZERO(ExceptFds); FD_SET(socket, ExceptFds); end else begin ExceptFdsptr := nil; end; if TimeOut >= 0 then begin tv.tv_sec := TimeOut div 1000; tv.tv_usec := 1000 * (TimeOut mod 1000); Timeptr := @tv; end else begin Timeptr := nil; // wait forever end; wsaError := 0; try {$IFDEF MSWINDOWS} {$IFDEF OLD_UNIT_NAMES} result := WinSock.select( socket + 1, ReadFdsptr, WriteFdsptr, ExceptFdsptr, Timeptr); {$ELSE} result := Winapi.WinSock.select( socket + 1, ReadFdsptr, WriteFdsptr, ExceptFdsptr, Timeptr); {$ENDIF} {$ENDIF} {$IFDEF LINUX} result := Libc.select( socket + 1, ReadFdsptr, WriteFdsptr, ExceptFdsptr, Timeptr); {$ENDIF} if result = SOCKET_ERROR then wsaError := WSAGetLastError; except result := SOCKET_ERROR; end; if Assigned(ReadReady) then ReadReady^ := FD_ISSET(socket, ReadFds); if Assigned(WriteReady) then WriteReady^ := FD_ISSET(socket, WriteFds); if Assigned(ExceptFlag) then ExceptFlag^ := FD_ISSET(socket, ExceptFds); end; {$ENDIF} {$IFDEF OLD_SOCKETS} function TTcpSocketStreamImpl.WaitForData( TimeOut : Integer; pBuf : Pointer; DesiredBytes : Integer; var wsaError, bytesReady : Integer): TWaitForData; var bCanRead, bError : Boolean; retval : Integer; const MSG_PEEK = {$IFDEF OLD_UNIT_NAMES} WinSock.MSG_PEEK {$ELSE} Winapi.WinSock.MSG_PEEK {$ENDIF}; begin bytesReady := 0; // The select function returns the total number of socket handles that are ready // and contained in the fd_set structures, zero if the time limit expired, // or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, // WSAGetLastError can be used to retrieve a specific error code. retval := Self.Select( @bCanRead, nil, @bError, TimeOut, wsaError); if retval = SOCKET_ERROR then Exit( TWaitForData.wfd_Error); if (retval = 0) or not bCanRead then Exit( TWaitForData.wfd_Timeout); // recv() returns the number of bytes received, or -1 if an error occurred. // The return value will be 0 when the peer has performed an orderly shutdown. retval := recv( FTcpClient.Handle, pBuf^, DesiredBytes, MSG_PEEK); if retval <= 0 then Exit( TWaitForData.wfd_Error); // at least we have some data bytesReady := Min( retval, DesiredBytes); result := TWaitForData.wfd_HaveData; end; {$ENDIF} {$IFDEF OLD_SOCKETS} function TTcpSocketStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; // old sockets version var wfd : TWaitForData; wsaError, msecs : Integer; nBytes : Integer; pTmp : PByte; begin inherited; if FTimeout > 0 then msecs := FTimeout else msecs := DEFAULT_THRIFT_TIMEOUT; result := 0; pTmp := pBuf; Inc( pTmp, offset); while (count > 0) and (result = 0) do begin while TRUE do begin wfd := WaitForData( msecs, pTmp, count, wsaError, nBytes); case wfd of TWaitForData.wfd_Error : Exit; TWaitForData.wfd_HaveData : Break; TWaitForData.wfd_Timeout : begin if (FTimeout = 0) then Exit else raise TTransportExceptionTimedOut.Create(SysErrorMessage(Cardinal(wsaError))); end; else ASSERT( FALSE); end; end; // reduce the timeout once we got data if FTimeout > 0 then msecs := FTimeout div 10 else msecs := DEFAULT_THRIFT_TIMEOUT div 10; msecs := Max( msecs, 200); ASSERT( nBytes <= count); nBytes := FTcpClient.ReceiveBuf( pTmp^, nBytes); Inc( pTmp, nBytes); Dec( count, nBytes); Inc( result, nBytes); end; end; function TTcpSocketStreamImpl.ToArray: TBytes; // old sockets version var len : Integer; begin len := 0; if IsOpen then begin len := FTcpClient.BytesReceived; end; SetLength( Result, len ); if len > 0 then begin FTcpClient.ReceiveBuf( Pointer(@Result[0])^, len); end; end; procedure TTcpSocketStreamImpl.Write( const pBuf : Pointer; offset, count: Integer); // old sockets version var bCanWrite, bError : Boolean; retval, wsaError : Integer; pTmp : PByte; begin inherited; if not FTcpClient.Active then raise TTransportExceptionNotOpen.Create('not open'); // The select function returns the total number of socket handles that are ready // and contained in the fd_set structures, zero if the time limit expired, // or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, // WSAGetLastError can be used to retrieve a specific error code. retval := Self.Select( nil, @bCanWrite, @bError, FTimeOut, wsaError); if retval = SOCKET_ERROR then raise TTransportExceptionUnknown.Create(SysErrorMessage(Cardinal(wsaError))); if (retval = 0) then raise TTransportExceptionTimedOut.Create('timed out'); if bError or not bCanWrite then raise TTransportExceptionUnknown.Create('unknown error'); pTmp := pBuf; Inc( pTmp, offset); FTcpClient.SendBuf( pTmp^, count); end; {$ELSE} function TTcpSocketStreamImpl.Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; // new sockets version var nBytes : Integer; pTmp : PByte; begin inherited; result := 0; pTmp := pBuf; Inc( pTmp, offset); while count > 0 do begin nBytes := FTcpClient.Read( pTmp^, count); if nBytes = 0 then Exit; Inc( pTmp, nBytes); Dec( count, nBytes); Inc( result, nBytes); end; end; function TTcpSocketStreamImpl.ToArray: TBytes; // new sockets version var len : Integer; begin len := 0; try if FTcpClient.Peek then repeat SetLength(Result, Length(Result) + 1024); len := FTcpClient.Read(Result[Length(Result) - 1024], 1024); until len < 1024; except on TTransportException do begin { don't allow default exceptions } end; else raise; end; if len > 0 then SetLength(Result, Length(Result) - 1024 + len); end; procedure TTcpSocketStreamImpl.Write( const pBuf : Pointer; offset, count: Integer); // new sockets version var pTmp : PByte; begin inherited; if not FTcpClient.IsOpen then raise TTransportExceptionNotOpen.Create('not open'); pTmp := pBuf; Inc( pTmp, offset); FTcpClient.Write( pTmp^, count); end; {$ENDIF} end. thrift-0.23.0/lib/delphi/test/0000775000175000017500000000000015165535636016367 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/serializer/0000775000175000017500000000000015165535636020540 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/serializer/TestSerializer.dpr0000664000175000017500000000422315165535636024221 0ustar00buildbuild00000000000000(* * 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. *) program TestSerializer; {$APPTYPE CONSOLE} uses Classes, Windows, SysUtils, Generics.Collections, Thrift in '..\..\src\Thrift.pas', Thrift.Exception in '..\..\src\Thrift.Exception.pas', Thrift.Socket in '..\..\src\Thrift.Socket.pas', Thrift.Transport in '..\..\src\Thrift.Transport.pas', Thrift.Protocol in '..\..\src\Thrift.Protocol.pas', Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas', Thrift.Protocol.Compact in '..\..\src\Thrift.Protocol.Compact.pas', Thrift.Collections in '..\..\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\src\Thrift.Configuration.pas', Thrift.Server in '..\..\src\Thrift.Server.pas', Thrift.Utils in '..\..\src\Thrift.Utils.pas', Thrift.Serializer in '..\..\src\Thrift.Serializer.pas', Thrift.Stream in '..\..\src\Thrift.Stream.pas', Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas', Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', System_ 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'; var test : TTestSerializer; begin test := TTestSerializer.Create; try test.RunTests; finally test.Free; end; end. thrift-0.23.0/lib/delphi/test/serializer/SerializerData.dproj0000664000175000017500000001535315165535636024512 0ustar00buildbuild00000000000000 {B523D1D7-2C9A-4B39-A6CF-69EF536D5079} SerializerData.dpr 12.3 True Debug Win32 Library None DCC32 true true Base true true Base true .\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias) bin\$(Config)\$(Platform) false true false false false DEBUG;$(DCC_Define) false true false RELEASE;$(DCC_Define) 0 false MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 SerializerData.dpr bin\Debug\Win32\TestSerializer.exe True 12 thrift-0.23.0/lib/delphi/test/serializer/TestSerializer.Data.pas0000664000175000017500000004045415165535636025075 0ustar00buildbuild00000000000000(* * 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 TestSerializer.Data; interface uses SysUtils, ActiveX, ComObj, Thrift.Protocol, Thrift.Collections, test.ExceptionStruct, test.SimpleException, DebugProtoTest; type Fixtures = class public class function CreateOneOfEach : IOneOfEach; 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 // test backwards compatibility with respect to the standard scheme. (* all data copied from JAVA version, to be used later public static final byte[] persistentBytesOneOfEach = new byte[] { $02, $00, $01, $01, $02, $00, $02, $00, $03, $00, $03, $D6, $06, $00, $04, $69, $78, $08, $00, $05, $01, $00, $00, $00, $0A, $00, $06, $00, $00, $00, $01, $65, $A0, $BC, $00, $04, $00, $07, $40, $09, $21, $FB, $54, $44, $2D, $18, $0B, $00, $08, $00, $00, $00, $0D, $4A, $53, $4F, $4E, $20, $54, $48, $49, $53, $21, $20, $22, $01, $0B, $00, $09, $00, $00, $00, $2E, $D3, $80, $E2, $85, $AE, $CE, $9D, $20, $D0, $9D, $CE, $BF, $E2, $85, $BF, $D0, $BE, $C9, $A1, $D0, $B3, $D0, $B0, $CF, $81, $E2, $84, $8E, $20, $CE, $91, $74, $74, $CE, $B1, $E2, $85, $BD, $CE, $BA, $EF, $BF, $BD, $E2, $80, $BC, $02, $00, $0A, $00, $0B, $00, $0B, $00, $00, $00, $06, $62, $61, $73, $65, $36, $34, $0F, $00, $0C, $03, $00, $00, $00, $03, $01, $02, $03, $0F, $00, $0D, $06, $00, $00, $00, $03, $00, $01, $00, $02, $00, $03, $0F, $00, $0E, $0A, $00, $00, $00, $03, $00, $00, $00, $00, $00, $00, $00, $01, $00, $00, $00, $00, $00, $00, $00, $02, $00, $00, $00, $00, $00, $00, $00, $03, $00 }; public static final byte[] persistentBytesNesting = new byte[] { $0C, $00, $01, $08, $00, $01, $00, $00, $7A, $69, $0B, $00, $02, $00, $00, $00, $13, $49, $20, $61, $6D, $20, $61, $20, $62, $6F, $6E, $6B, $2E, $2E, $2E, $20, $78, $6F, $72, $21, $00, $0C, $00, $02, $02, $00, $01, $01, $02, $00, $02, $00, $03, $00, $03, $D6, $06, $00, $04, $69, $78, $08, $00, $05, $01, $00, $00, $00, $0A, $00, $06, $00, $00, $00, $01, $65, $A0, $BC, $00, $04, $00, $07, $40, $09, $21, $FB, $54, $44, $2D, $18, $0B, $00, $08, $00, $00, $00, $0D, $4A, $53, $4F, $4E, $20, $54, $48, $49, $53, $21, $20, $22, $01, $0B, $00, $09, $00, $00, $00, $2E, $D3, $80, $E2, $85, $AE, $CE, $9D, $20, $D0, $9D, $CE, $BF, $E2, $85, $BF, $D0, $BE, $C9, $A1, $D0, $B3, $D0, $B0, $CF, $81, $E2, $84, $8E, $20, $CE, $91, $74, $74, $CE, $B1, $E2, $85, $BD, $CE, $BA, $EF, $BF, $BD, $E2, $80, $BC, $02, $00, $0A, $00, $0B, $00, $0B, $00, $00, $00, $06, $62, $61, $73, $65, $36, $34, $0F, $00, $0C, $03, $00, $00, $00, $03, $01, $02, $03, $0F, $00, $0D, $06, $00, $00, $00, $03, $00, $01, $00, $02, $00, $03, $0F, $00, $0E, $0A, $00, $00, $00, $03, $00, $00, $00, $00, $00, $00, $00, $01, $00, $00, $00, $00, $00, $00, $00, $02, $00, $00, $00, $00, $00, $00, $00, $03, $00, $00 }; public static final byte[] persistentBytesHolyMoley = new byte[] { $0F, $00, $01, $0C, $00, $00, $00, $02, $02, $00, $01, $01, $02, $00, $02, $00, $03, $00, $03, $23, $06, $00, $04, $69, $78, $08, $00, $05, $01, $00, $00, $00, $0A, $00, $06, $00, $00, $00, $01, $65, $A0, $BC, $00, $04, $00, $07, $40, $09, $21, $FB, $54, $44, $2D, $18, $0B, $00, $08, $00, $00, $00, $0D, $4A, $53, $4F, $4E, $20, $54, $48, $49, $53, $21, $20, $22, $01, $0B, $00, $09, $00, $00, $00, $2E, $D3, $80, $E2, $85, $AE, $CE, $9D, $20, $D0, $9D, $CE, $BF, $E2, $85, $BF, $D0, $BE, $C9, $A1, $D0, $B3, $D0, $B0, $CF, $81, $E2, $84, $8E, $20, $CE, $91, $74, $74, $CE, $B1, $E2, $85, $BD, $CE, $BA, $EF, $BF, $BD, $E2, $80, $BC, $02, $00, $0A, $00, $0B, $00, $0B, $00, $00, $00, $06, $62, $61, $73, $65, $36, $34, $0F, $00, $0C, $03, $00, $00, $00, $03, $01, $02, $03, $0F, $00, $0D, $06, $00, $00, $00, $03, $00, $01, $00, $02, $00, $03, $0F, $00, $0E, $0A, $00, $00, $00, $03, $00, $00, $00, $00, $00, $00, $00, $01, $00, $00, $00, $00, $00, $00, $00, $02, $00, $00, $00, $00, $00, $00, $00, $03, $00, $02, $00, $01, $01, $02, $00, $02, $00, $03, $00, $03, $D6, $06, $00, $04, $69, $78, $08, $00, $05, $01, $00, $00, $00, $0A, $00, $06, $00, $00, $00, $01, $65, $A0, $BC, $00, $04, $00, $07, $40, $09, $21, $FB, $54, $44, $2D, $18, $0B, $00, $08, $00, $00, $00, $0D, $4A, $53, $4F, $4E, $20, $54, $48, $49, $53, $21, $20, $22, $01, $0B, $00, $09, $00, $00, $00, $2E, $D3, $80, $E2, $85, $AE, $CE, $9D, $20, $D0, $9D, $CE, $BF, $E2, $85, $BF, $D0, $BE, $C9, $A1, $D0, $B3, $D0, $B0, $CF, $81, $E2, $84, $8E, $20, $CE, $91, $74, $74, $CE, $B1, $E2, $85, $BD, $CE, $BA, $EF, $BF, $BD, $E2, $80, $BC, $02, $00, $0A, $00, $0B, $00, $0B, $00, $00, $00, $06, $62, $61, $73, $65, $36, $34, $0F, $00, $0C, $03, $00, $00, $00, $03, $01, $02, $03, $0F, $00, $0D, $06, $00, $00, $00, $03, $00, $01, $00, $02, $00, $03, $0F, $00, $0E, $0A, $00, $00, $00, $03, $00, $00, $00, $00, $00, $00, $00, $01, $00, $00, $00, $00, $00, $00, $00, $02, $00, $00, $00, $00, $00, $00, $00, $03, $00, $0E, $00, $02, $0F, $00, $00, $00, $03, $0B, $00, $00, $00, $00, $0B, $00, $00, $00, $03, $00, $00, $00, $0F, $74, $68, $65, $6E, $20, $61, $20, $6F, $6E, $65, $2C, $20, $74, $77, $6F, $00, $00, $00, $06, $74, $68, $72, $65, $65, $21, $00, $00, $00, $06, $46, $4F, $55, $52, $21, $21, $0B, $00, $00, $00, $02, $00, $00, $00, $09, $61, $6E, $64, $20, $61, $20, $6F, $6E, $65, $00, $00, $00, $09, $61, $6E, $64, $20, $61, $20, $74, $77, $6F, $0D, $00, $03, $0B, $0F, $00, $00, $00, $03, $00, $00, $00, $03, $74, $77, $6F, $0C, $00, $00, $00, $02, $08, $00, $01, $00, $00, $00, $01, $0B, $00, $02, $00, $00, $00, $05, $57, $61, $69, $74, $2E, $00, $08, $00, $01, $00, $00, $00, $02, $0B, $00, $02, $00, $00, $00, $05, $57, $68, $61, $74, $3F, $00, $00, $00, $00, $05, $74, $68, $72, $65, $65, $0C, $00, $00, $00, $00, $00, $00, $00, $04, $7A, $65, $72, $6F, $0C, $00, $00, $00, $00, $00 }; *) private const kUnicodeBytes : packed array[0..43] of Byte = ( $d3, $80, $e2, $85, $ae, $ce, $9d, $20, $d0, $9d, $ce, $bf, $e2, $85, $bf, $d0, $be, $c9, $a1, $d0, $b3, $d0, $b0, $cf, $81, $e2, $84, $8e, $20, $ce, $91, $74, $74, $ce, $b1, $e2, $85, $bd, $ce, $ba, $83, $e2, $80, $bc); end; implementation class function Fixtures.CreateOneOfEach : IOneOfEach; var db : Double; us : Utf8String; begin result := TOneOfEachImpl.Create; result.setIm_true( TRUE); result.setIm_false( FALSE); result.setA_bite( ShortInt($D6)); result.setInteger16( 27000); result.setInteger32( 1 shl 24); result.setInteger64( Int64(6000) * Int64(1000) * Int64(1000)); db := Pi; result.setDouble_precision( db); result.setSome_characters( 'JSON THIS! \"\1'); // ?? SetLength( us, Length(kUnicodeBytes)); Move( kUnicodeBytes[0], us[1], Length(kUnicodeBytes)); // ?? SetString( us, PChar(@kUnicodeBytes[0]), Length(kUnicodeBytes)); // !! result.setZomg_unicode( UnicodeString( us)); result.Rfc4122_uuid := TGuid.Create('{00112233-4455-6677-8899-aabbccddeeff}'); {$IF cDebugProtoTest_Option_AnsiStr_Binary} result.SetBase64('base64'); {$ELSEIF cDebugProtoTest_Option_COM_Types} result.SetBase64( TThriftBytesImpl.Create( TEncoding.UTF8.GetBytes('base64'))); {$ELSE} result.SetBase64( TEncoding.UTF8.GetBytes('base64')); {$IFEND} // byte, i16, and i64 lists are populated by default constructor end; class function Fixtures.CreateNesting : INesting; var bonk : IBonk; begin bonk := TBonkImpl.Create; bonk.&Type := 31337; bonk.Message := 'I am a bonk... xor!'; result := TNestingImpl.Create; result.My_bonk := bonk; result.My_ooe := CreateOneOfEach; end; class function Fixtures.CreateHolyMoley : IHolyMoley; type TStringType = {$IF cDebugProtoTest_Option_COM_Types} WideString {$ELSE} String {$IFEND}; var big : IThriftList; stage1 : IThriftList; stage2 : IThriftList; b : IBonk; begin result := THolyMoleyImpl.Create; big := TThriftListImpl.Create; big.add( CreateOneOfEach); big.add( CreateNesting.my_ooe); result.Big := big; result.Big[0].setA_bite( $22); result.Big[0].setA_bite( $23); result.Contain := TThriftHashSetImpl< IThriftList>.Create; stage1 := TThriftListImpl.Create; stage1.add( 'and a one'); stage1.add( 'and a two'); result.Contain.add( stage1); stage1 := TThriftListImpl.Create; stage1.add( 'then a one, two'); stage1.add( 'three!'); stage1.add( 'FOUR!!'); result.Contain.add( stage1); stage1 := TThriftListImpl.Create; result.Contain.add( stage1); stage2 := TThriftListImpl.Create; result.Bonks := TThriftDictionaryImpl< TStringType, IThriftList< IBonk>>.Create; // one empty result.Bonks.Add( 'zero', stage2); // one with two stage2 := TThriftListImpl.Create; b := TBonkImpl.Create; b.&type := 1; b.message := 'Wait.'; stage2.Add( b); b := TBonkImpl.Create; b.&type := 2; b.message := 'What?'; stage2.Add( b); result.Bonks.Add( 'two', stage2); // one with three stage2 := TThriftListImpl.Create; b := TBonkImpl.Create; b.&type := 3; b.message := 'quoth'; stage2.Add( b); b := TBonkImpl.Create; b.&type := 4; b.message := 'the raven'; stage2.Add( b); b := TBonkImpl.Create; b.&type := 5; b.message := 'nevermore'; stage2.Add( b); result.bonks.Add( 'three', stage2); end; class function Fixtures.CreateCompactProtoTestStruct : ICompactProtoTestStruct; // superhuge compact proto test struct begin result := TCompactProtoTestStructImpl.Create; result.A_byte := DebugProtoTest.TConstants.COMPACT_TEST.A_byte; result.A_i16 := DebugProtoTest.TConstants.COMPACT_TEST.A_i16; result.A_i32 := DebugProtoTest.TConstants.COMPACT_TEST.A_i32; result.A_i64 := DebugProtoTest.TConstants.COMPACT_TEST.A_i64; result.A_double := DebugProtoTest.TConstants.COMPACT_TEST.A_double; result.A_string := DebugProtoTest.TConstants.COMPACT_TEST.A_string; result.A_binary := DebugProtoTest.TConstants.COMPACT_TEST.A_binary; result.True_field := DebugProtoTest.TConstants.COMPACT_TEST.True_field; result.False_field := DebugProtoTest.TConstants.COMPACT_TEST.False_field; result.Empty_struct_field := DebugProtoTest.TConstants.COMPACT_TEST.Empty_struct_field; result.Byte_list := DebugProtoTest.TConstants.COMPACT_TEST.Byte_list; result.I16_list := DebugProtoTest.TConstants.COMPACT_TEST.I16_list; result.I32_list := DebugProtoTest.TConstants.COMPACT_TEST.I32_list; result.I64_list := DebugProtoTest.TConstants.COMPACT_TEST.I64_list; result.Double_list := DebugProtoTest.TConstants.COMPACT_TEST.Double_list; result.String_list := DebugProtoTest.TConstants.COMPACT_TEST.String_list; result.Binary_list := DebugProtoTest.TConstants.COMPACT_TEST.Binary_list; result.Boolean_list := DebugProtoTest.TConstants.COMPACT_TEST.Boolean_list; result.Struct_list := DebugProtoTest.TConstants.COMPACT_TEST.Struct_list; result.Byte_set := DebugProtoTest.TConstants.COMPACT_TEST.Byte_set; result.I16_set := DebugProtoTest.TConstants.COMPACT_TEST.I16_set; result.I32_set := DebugProtoTest.TConstants.COMPACT_TEST.I32_set; result.I64_set := DebugProtoTest.TConstants.COMPACT_TEST.I64_set; result.Double_set := DebugProtoTest.TConstants.COMPACT_TEST.Double_set; result.String_set := DebugProtoTest.TConstants.COMPACT_TEST.String_set; result.String_set := DebugProtoTest.TConstants.COMPACT_TEST.String_set; result.String_set := DebugProtoTest.TConstants.COMPACT_TEST.String_set; result.Binary_set := DebugProtoTest.TConstants.COMPACT_TEST.Binary_set; result.Boolean_set := DebugProtoTest.TConstants.COMPACT_TEST.Boolean_set; result.Struct_set := DebugProtoTest.TConstants.COMPACT_TEST.Struct_set; result.Byte_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_byte_map; result.I16_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.I16_byte_map; result.I32_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.I32_byte_map; result.I64_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.I64_byte_map; result.Double_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Double_byte_map; result.String_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.String_byte_map; result.Binary_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Binary_byte_map; result.Boolean_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Boolean_byte_map; result.Byte_i16_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_i16_map; result.Byte_i32_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_i32_map; result.Byte_i64_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_i64_map; result.Byte_double_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_double_map; result.Byte_string_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_string_map; result.Byte_binary_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_binary_map; result.Byte_boolean_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_boolean_map; result.List_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.List_byte_map; result.Set_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Set_byte_map; result.Map_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Map_byte_map; result.Byte_map_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_map_map; result.Byte_set_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_set_map; result.Byte_list_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_list_map; result.Field500 := 500; result.Field5000 := 5000; result.Field20000 := 20000; {$IF cDebugProtoTest_Option_AnsiStr_Binary} result.A_binary := AnsiString( #0#1#2#3#4#5#6#7#8); {$ELSEIF cDebugProtoTest_Option_COM_Types} result.A_binary := TThriftBytesImpl.Create( TEncoding.UTF8.GetBytes( #0#1#2#3#4#5#6#7#8)); {$ELSE} result.A_binary := TEncoding.UTF8.GetBytes( #0#1#2#3#4#5#6#7#8); {$IFEND} 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. thrift-0.23.0/lib/delphi/test/serializer/SerializerData.res0000664000175000017500000026231015165535636024162 0ustar00buildbuild00000000000000 ÿÿÿÿL ÿÿÿÿ‰PNG  IHDR\r¨fÿÿIDATxÚ콜eWq'\7¼;çîé鞥QJH€%Ç58`ƒ×ì·`/Æ?{ƒðÚüc/ø³ùð:/¶/6&JBÅ43šœSOçðúåxïùªêœsßëIÝ#FšOÝóú…N¥ý«Ê€«ëŠ\ùå>ôÓo¿þ ³™2LNMA¾T0l˜MÍÃøô Ø–\a€eûalbfç2ø» Âtùý†kžó™®áà Õ*´4%¡»³œZ™þ®SƒîŽ6hN&Àuk‰¡»¥šã!øú#Û>ü_é¾?¿Ü×äêzù˸ÜpuN¦>ÓÝžÜràØhöÈé1˜Ïäa>]Äçg`z6ç4%#k{:ZÖU ¥ L¢ìšP®T _.á' €  Ó†R© ¥JU='ðÿ¨P9Ý~¹>o(€*?„ð!Àá÷ C@8€ Ÿs˜¶É÷ÛŒLÍ웘™ÛßZ+—AS"­ÑlY¿²uÏÑÑzÛ­kÿúr_Ï«ëüëªx¬ï=ñÂ[ׯê¿}ÇþS™#GÇad|ʽñšU¿E:¦ææa6“"ZøB¾ ™\ Å TkT]—…ÙdY'Á6Ø‚[> ÕÆ']0H°ñ9òØð[zB}³áý—ž2L´þp¤U) Âjµ5|üNÒôyþnâçùða¡‚ú}ÐÒÜ„ŠÂ‘ º:Z`b6³kÇÞcßšŒÚ]mM°z¨®_»,¾ûÐé'ï½ëºÇ.÷µ³¯« à5\ŽžYµry÷Šm;…Cg¦atbÚ¹}˪ô´ßwldª86ž‚ÙtÚ-–+Ç!ç¤Fyô¡ÐhM“¬7ð_LFBÛ”] 6ø|Ba$KŽ’Ì7ÙB…`ãó´Üìæ³àWðåO`A/WpúfäËȳ¨B)|aÍqù3R@ôNõ;)!ú ö.èiTA¶eæ"¿Ý”ŒBog ÷v„NNï/ø“î6k°·V´Â­×­í>:zdÓÊÞC—û^½YÖUð*®Ïþï¯ûßuß½{žt^ÚʽûÖõÿ½¿»õ§v85üÌ$œœ˜ƒ¹ùLÅïó Ù¶© €ÕPêQÄ T® UGÁ&ËMVÝ‹GÑ‚£€ûÑ’û-f­nÅ7ò³å'q7ñõ&[~eéIŠMzÞæ²À+Ï@xÊ€<Ò8$ä(·ü~Á^„Å^ýNc¾PdåSÀ£VP®Õ P&ÏD@®gÅA¯Ä4-ðáqÑ[¨œLÛÀ°Á‡JÂÍW«ÕcmÍ1og v%aóºåÉ£#“ÿñÀÛÿø–ë×™›Vt[_ýö3g~ÿ7ßU¹Ü÷òº®*€K¼¶í9æ/jæÃOﱈ½é§ÞqëýûŸÎ91^Ä?¿­wO¦P‚\±ÅB*hm å „6ZçHÈAŒ­ÃÂÁ0þôC…ÞF!ò+«Ž•­¾‰å³lŽÉý¨H~[w`W]*iÙ0Ôï®CâR=¸j 7MïyÂHDÄaŒâ{Û´~(´a¨+úõïmýd¡T}é­·n$uäÞsÓ†«Ê஫ à¯öx*€ÞGŸÛ5[*®Y½bà×&g2-=ŒO¦|ùRÙ4P€Éª3¨†ßîyÀGÖÜ´î>²î(á ÇÕ>²ÞhíAÇæ,ÇRØH@]ê1¾O¿Ó/ôWxÎ=[zRø¼¿ÇÄc`0œtÃäÏ)—*üSxØ€z/aÒÑ—@¡Éê‚õ ý$EDËTaˆK> )|”«UÆ/Ê(øô H Qy”Q9’ ¯¡X,±‡Aï l·³­©ÚÞÚ- cßÁ“„vÞ~Óú<²3o½aÝ—/÷=~#­« à‡\÷õG»oÚ²êšÇŸ=”;x쌸ýÆÕŸ+WjûŸ®ŒOÍDªŽh"13MŠ×-vƒ}(Ì$üápbaZz?DÑ †P0 ~­Ér,@ÿcaÇÿ{Îa ÊeIÁ¤Ï¦÷™ „… ÄdáU†Ÿ–Ð{R<‘{‚L7Èì‹Ö»/J¥Áƒ`‘¾„À>ú^!5 ¿ÆUŠÇE€Ž„< rùt4 ¥$+ ö,”B"EeS,•!—/C¿·ˆÊ”}½š¼ 1ðôR½íÍù5Ã}~üÎSmÛ÷;[Ö÷ܼ6ºuÇ¡¿ú®»Ç.÷¸’×Uð ÖT*׳çÈióG_LöµþÊÆuƒ¿úü®“åã§Çq³»7:ŽcTªª¸Ñ«û|& y2x$„ÂŽ‚OBˆ‚a“ ÀšÜs ÍWwEÆßRÐy—¼L¿ù1$ÀÏ ‚ضÍàaô9>?y~/µÇnkT ¨@LC¨Ø¤Õ&av¥’0ÊÔ€Áa ¹ò‚€?WžÅü5|¥1žÇ×Tñ5e‚%ù½.‡R‘È4ƒ!ÁHtÓC‹…˜oOÛÒUDŽÄ âÆ›LÚá¾O2á|¶Å¨<‘}@§Õ€ñ>r7ï2ú6 ý‡+|)gr¶A=A@ B8‘I©•Ž$ЩIA &–ÑÊ~ààûlSfN˜ñ„Ta>_€yô 2ù*±óÙ< £Àd#ªAX9ÐE¯ÛÚÓ‘|bÓª‘îŽ/^îËòzXo€ÝõÊ×ÃϾ”¸}Ëú·ÿÛ÷·•ú{[þáÌèló³;ÂÈÔ,„0çc¿-™€Îæ8n(‹‹cØÊÓ¤T (£¼< y@‡¾€Á!_Èg¸ç–M¾ñəϮ_9øÜªå}™ŽÖØéWo—^Þõ†Uÿ÷»Ï„oظâ¿8yfíS/ì_V*9×̤‰RZ†hÈ‚þÎèíh…D8Ñ`lŸŒÓkйWCÁ':*Ř.×¹›º¤N}CãW„-„ž•ÇÏT™6^Ü—ªÆ<¿Am^WÝ™:ëOaìšÆ¹·L†Jå < é‘ÇašŠˆ#ÄËÊ)xü?Å`tb/qá ¯°yœ sŠFî‚‚ø åÙˆ†c6$ \hP®wž Ô€RРp¼‹æQ˜µ²•©BâgøœµTµ¤¥J–ñÂäÍxlfNOÎBºPbêv+zƒ!¿±óöë7œ\Þ×µÿévÿñ{ßuOárìãW{½¡ÀS/2â¡ÿŸ¿ó”qÃúåïÆÝúGGÏLv:6³©$›¢Ð‰|t·7CZw ‘Nå~V*.в‰fÍ­q>ÚÛsK4ž\«h»BJ¸ÄÔ%740¦ÿ%„—¤®<ºÎ¼†f½;Ï€‡j‹É A,/ãÀ¯uL~‘3h8aC65¤ÐsÒò‚/ÍuKlèXßðªé=’%©ÏÏð²%²Q'HÐW°tÖk¨#§e} XÐå ð€¸5<ŽÙtƧç`b.‹Ê ó´%ðj¨ú:[Ç«•âÇöûÊÏÞw›ÈK•;¯[}%£² ÖMtEƒ¡Íÿò§`å@Ç—·8Úrf"-ñ$0ÎoJ„`¸» :Û9]Ç%®†¬’«bH´Ô|NòÔéwªm7 ·ÀÚ,²¼]€çxÉ>ÕÇP¹C¹¥RP$8hzýú¤@h'؃Ĵ­;ü¨_à PÍ;5W?¶%° Eƒ0”ObœG$]©°4“Ñ;mð+£l‚ôv(¬¢k*Swbáguá÷Ü~±PïšÆu°ÒˆÂÐQ‚¬PURí•R»‚y…à Ø¬èÇ&fáÈÈÌ¡'Foqv> ímQ¸fõÀìÈØì{~ö¾Û!W*íB0~©öìå^o(ðضýï ØöŸþû÷·¢VÏ5UǠد…å@;¬èbbÜÓ2>¦tR¥ZÆ8°©T–›Rxˆ½ªr“À’ÚàÆâ—L›ÖÐ$x× ÀŸÚ²/L‘Jx‚¥­¿rà…ª ¯w=«o¨Š<$MT(»Rîn9Ë®[·ðôÞšPaá#®ü)‹}‚ ¯· ¨t§ú,…軪'ô”§cªÂ¡²g‰¸¾&gÿ~ÑãW½]<ʸ à ü|*ÒjN&¹7õO V¡`ÅKÇVðυ£gfàà‰ jΊJË¡ ¢-MýäÝ7AÙ©}äž›ÖýÃk²¡_ƒõ†QŸÿòƒ¿‹þp×þ“ËŠ¥"Æwe¼¹>¦€®_ÑÅz~NëÙKG¿Zq`|&csóP*¢»OÝmˆ“®\Ù:òÜOæ¦߀ÂUî°©Ù~:%(­©RaØÊÎ×›o:efhËZ·ÆW«PÅuR;&Ô[Ü]êDØuÆØª§€Å|†‹£tˆ7ø¨ Wä¨s¶!W(0>RSžQt…—âY¹§I=–;4ŽçêÖaÜÈ‘úP+8’šBåÿz¨¤ÿ»0s°ÖèI@r­<Ÿ-Û¯u´D¡§#‰ŠÀ§†—Æ`¥†žá †ûOÁáÓ“P,׸J3ÁƵý' ùÂ'>üË÷ýÓeÜî—l]ñ Ë}ò?Û?plì¾b¡´úôè$ºtôv¶Àʾ^îm‡Ö¦¬1ÇM||¢”N§ÒèòÍÃÆÙbEZMÕÊzáåÑ(µrÙ—€¢ eú´u7¼”ÀœUí ί²¨w–z¸uþ†¹ 5 ¡x–:QÊ2€.-;qÃPêäóÉïw…×1Èhô§/°¸@• ¿ëzœDjØAõwñ©©ÜzÿV¢j¾bY6­T\*]J˜!;‘sÐõöh<üOm?S(д«âÑ ZüN¸iÓ´Æ"2%¥8çgó%Øl c¼)(—ªà7•€˜Š ã%ëµeªÇžRˆEÂwáåŬÐb°N¶Þ¦ñ|.W¶©É>†xrÕ©§Y¦–D §6ãyPb]P—]rCN¡èÅ*,pMOSi¥c¸ yuy"’¿°È2¡.|ÚÍw=}r¦Ršì%ðßMv¡Éæ’àä²YV¸S„¯¤sœ‚­82ÍêÔª<…ˆÂ šiH<~ …‘Ô¹° î7–€Á¨»P?гï‹ÊÒpˆ„žU ’‚èn†Í«—Aœèߨx]ÚB2 Sù,<·ë=5 /‰6ÞŒ ù·m¦^?µõÅÝßÿ‹û?X|Dà’­+Jä‹Uß“Ûv›/¾tôí‰Dì_ž:,*èrV¡³= 7l†C½Ùâ“&'Ð/›/Âî#gPøGñµîcg*ð‹kë ’”òÒU@÷ò—«…D5÷0\Ù\³$d›îÎÖ§%;Ð % Äé*²¸ÔД=õ7îô=ÕH¤a¿7º»÷t+磻1„ y4å¶!篿ßÐ)ªí·U´â˜2Dqk¤ E˜ž!Jn–)¹S³)ŒµÓÜЃróÜ‚ÍMUkõ¬l!ŒºÀבc×âQ…faÒ5¨ÏE åº’¸E3ÂA…¿C‚A4,]Д qXC›¦Œ×ùøØ4{{Ÿ‚b…&‘7'žÄ³¼ÿ?÷[WÌÐÓ+B<òìKï@kð™­;_³ÿØn=Ý‹ÂÚ=pËuë ¿#Î1œaËÑÕsÓ)8tb ¶¢å?51Ã7”À2î½w¾Xç<ïÅZè…Ü(¼q„ІëæI±ÙÎ0P ú>RDq´öTeØÓÖË{Û¡»£ ‘ ¿×‡Ç£m´P©=‡CKë6T×]ü+*nê~©-0;ŽËm±HÞª4XƒXŒâ×$§A+!øÔ…—º×ÀY@§!¯UAJ‚DÐ)…hØò9ºV>Ê:Ðë‚!°lSÞX²«/….¶%±®‘på¼*yeŽºN¶ä Øì¹rÊbìÌ䙄 T33óÃF©Qæ!Ä XmUu Ji‰z&¡¿uÚ”w´ÐʺãÑ÷œ”,]#ºÆ„ÉPhvýšAذz•wL4ѵÄŸJÃ3/ì…]‡N3ÆáÃðÙö÷ÀöýÁ?|æ7¯ˆ®Ä¯kð§û-«§³å6t[?‹Vÿú#ÇÇe*éÆÍ«`Ëæa®$ ‰Üç4¨b|z¶m߇OŒÃÔ\–Šòÿºíõ)½VDèJ@ðRF¦G*1¼|¼¶ü26… aŽš@Ï`VÍQŠÑÔᎇV‚Ç<ÔŠùœ^Š*Õ(<üG§vÕŸ…¨7tÅyot=ÛÑS[³|n¼v%´·'fa³!˜šKÁó»à /‰©¹iŽßïû~Âï÷`ˆçTÝ‘ÿùÑ_._nYºÐzÝ*€O~ákf"¾> òÔè̽‡Ñò“…ZÖ 7]³ ®Ý°Ú[cP(9j¢­ §F'áùá ¾6‹.d( p¸K`¿†«ö‘šƒ§€«i°Šù&L.ð‘a‚Œu! QLÛZ›¡§³º»Z¡³½…+“Q?”Éu¬ÐÄÜš,È~ûÔ-˜Çt‘P;‘€'ÝúJj4y§@}õ‹`’õ®–ð'Æ£”ß'¥!¼><É£ bVZ*áN:’-(Ó›z@ˆú¯rÙ%ÃO0q¨‚çXòÜ©rßRÁŸe| _Ià%uÍ(Ññ“g@ˆ|~n‡fäï~Tž}ˆJ!à´¥ìªdÊK¨>¿¤xÔˆqJJÒ’Åàg:WÞÇiôèNNÁI¼¿Ó3tÅ‹ û † FC@£q‡…}4¹@óµcg-ø³ÇÂT‹ð9.½ŠÊ;+‡ºáÚÍCh€z0 ày W¶ar& ;w†­;±cá 0,ëï:Ûⶨ‰,—ªO~áÞ÷ºììúºTÿ³¯>Ÿ=ì³ÍO˵_ýòÞN¸ç¶-°z¸—ãÍ5îÄ#/£ÕÜwðì9xfÐM¤i£›É°™®D¥ål4 †j⡌ eš›c0ˆÉà`7´¶Å™ÈC,=å¸s-uÒezÔ \çÔ0~wr¨¥çÁ-YøC¸±}‚bù ·´ÕËTV—Kx´P@¤Ý\-üüg… €v€)´2S'á1ì$ßX²Ùê;žK]w£ñï๠ç™7÷¸þJé°WäÊ<%T„E|eQø ã AÊ€åf-!†œùâ¿£Ô‚-¦dB1MYÆìJtŸºÿq 2÷\4e GMÎ!L¥ópüÄ>zæÓYž I[Ús«ß{WÕ(>}‡åHQð’Àz.ƒÎ™¦›RH@ŸÕÔ…U+—Áµ×p¨ÉÓŸ-:6Á˜ÅwzF'瀎}óA¿õå/|â}ºÜ2vözÝ(€ñ©ÙV¼ÜŸûê·Ÿ*ž›ûÅùl1V«Ua¨¿î}ëͰj¸ÑåZ­ÂH5‘{vî:ÇŽŸá\2å¼} $‰¸×ŠbÑåµé††#ê‚ S]ÄÎ[½bººš9¥—@WŸ<”b©Êyn#dnÙÀs0I° 00¦·ð߀VÞ!„7“I±¼I|} ºJ¸å´^+“Pº*–÷RmO·îy8Žª´$0=ö 04ÀGÉ–àa½³y+…@¬pìuT°—׌×4‹blfZ´t$^"';<úœ:ûRfƒúüMOÏÃèØ =1ŠŠ  •´iœåÎ×)Ù® ÷4§£žð©·*WoQÏËð›Áš¤d¡exV/_›6 C,ágÝKçA¸÷Ð)xô©p•} *œm_øËO½ÿã—[Ö×ëBŒÍÌwÔÊ¥lßsâ£/¢ uj|–ÓL«Ñº¾cþk7­ä¯äSþy>•ýx÷ì?‰7£ÄÂ4}^:ÏU®] ¾”Ó¬f× ÅÜ38}VãÍF¡­ cüžX94±h@æÛ+UpÅ(É.c¡£Ï Š¹BÜl  …>@s/5Kv™g/àý§&'OObx0“³CÁ$Cy†ö^t¥{4èc]²0I¤X ’wa¸õªÃ`(\½jÖ®„V‘Z¸Õ˜Ü”5§¤´É%˪UøóXÀéy~Ñÿ¦PA 'að{ª¼-~>J ×óϽó3¼–ZšµGJN2<«gÊ>”Mq¹-ËwY1X  äk,•Ñ„?ÅþãÜ>ôxÇRãg‰~cA…1*;—m?ýQ˜÷…¡@±>MSJ¶$ ½½âM1ð?Ÿ“i* Ïh`»ßT<•šÍÀ¡#§àôé n^.£ò1l…©{¬Â¸³'$Ëû¿°ç€nÊbòyÖ8E _!åRf n^¿ 6®ä‰Q”—!¯* À᡼‡OœaEñóž}7~î·¿xÿ.;&pYÀl*gÛÿ§·î:òûÿú§Õœ¸*ôww½wm¨U‰TCSr)O<;—aåôÈ8ȹºéeÝyba~8×±?Ïjüœ:}„q]=]°rxcþ~®Ë…õÙ}*t …,>YïZ& "›[T™9Çx †RV»¦v"÷ 'A À$& Z–J‚½R•áBÕaŒÁ©•åóU©x6™ËP5[M–Þr}US“Æ^{ï@{>Šm( 9‘—ÀV&QÁ—ðY¿súÒ$/=/ÛRœzÃKÉé<»õ®>.!ý®$ÁJAò($(Ù>Hc80Fåê ¢ù JÜôè³â‰twu@GGz2uWg3È8Fg;˜2mù`÷ÊÁƒG`l|ZfbÀTÔf™½Yzh¨`Òwª"Š~h…¢ñ&Ò ½ '0Œ©àµ'æ$õ؃ÆêÇ·ÃI Sˆ“BÕ–!~I¸ÆW¿ø‡¸¬µ—U8®øô“Ïø­o>þ|loMmmIøÑ»o€«™eÆH9º÷ù\öï=Ê.1eñˆuŽ\{)vM iÐìšn[ÿ·¶„W§íÊìEtt´Âðò>H¢+ ‡»’n®é±U*k¢›™ XÅ"ŠF•óõ¤{ h<ÍujLÜG¥ßȪãw8(Èê+áwUJp£Tfá?•§QÙ¸¬p¤»-ÝÉ%½+ñ€†Ë#`áõðž7êE<ÜJ›(Ó¦݈Íc0@a«ßñ'õ °‹¼öˆ©_‹Â+|–×Hß:ÝÊ3ÊŠù A¿»àA:ÔÙPæÂ1T>N}&„ƒ!hNÄ¡£«‰³t£I¸A’\ÉlF›¯q&—…Ô|N=“S)ÞKܦazKcí,ô 4­x!YT3‘õ5䆭¸úº;`ÃÆ‰†ñI`°¢²=ü,ŒÍfÁ° ä·fMaþÖ?ýËÚXä²(€JµŒÞœñ¡m;Oþ·ï?½³ûà©Qv)©¨âžÛ¯ƒk× C((™aß§Ñí?zä$Œœgz+³íøÈ/ÍÑÃ7¤Å«£:‚®,Åh4E&‹@oZ›Î&hmjf€^ç¨÷i›i’ðQLŽÂYËeÀA%à'OT¥¡2®J§qM=¹ü$¸«,üÄêÄò+X`‹2þ$@éB|ðkªRPX@Š’KƒkŠTä*! cT}ñMÅþ“‡ÝÀûó6qÃnöäÁðB ¶˜¶¡BKÚ:rûQMºþä`ñ…ž½›‚á÷I´ŸÂ6R ô~CxíȤ!–XÞŽ9I)TQç!ÈùÃèÄ ŒB ¯š~p,?7?iŠ¡%Ö–fâL4Ô ‚  TÝ£f VðºÍͦa|rÆÇ¦™ F ²MDÕ ‘†ŠOy4&°T‰ËES”ìén‡Áe½Ð‚!ŒPÔî<î“Ý»Â÷ŸÚÅd&â@„¾}º~úÿûÃ÷ÿëåCXÚ™½:kçþSûxbך]óæ#Îõ·®ƒ7¯ã)=®”(½366…nÿÊGÅ+ˆ9/÷|'("\mõÄy²˜†zÃEbQèE7®µx(BÀy-ÇË¥3}ÝY7—CÁÅÍDÂJ¨>*Ÿ)Qq®,döˆËÜ|ᨸœ(¼TP‚Â-ÐÊ u œ|‘?‹¬½¨HA8(÷žiÆlõk°©|èü½¦ëü½tMÕ5hìt¤î³Ê݆—Ôù3†Êƒ*j­hC=Ï@¦%_z>T>öøAŠ‚~VìY€äÛ/P ºÔ$¢S‘+vRáz (ðŠÀ‘c¹RSkzŒÍH — ±‚wh²0ã7–‚+䵡‘ãè‚Ó#“Ér*‘ÀCyIŒÆù¬õ¨J—´Ïd¹7‘š¨¢««–uASSBzªxlTôÛw†'ŸÝ³sè˜Týù<ª«}ñÓ¿þÈåÃË¢>tÿ?\ßÙÖüð±ÑñµäêëlƒÛ®_ ·ßº‚÷1‘7H:•†'F`58•ÓšŠ.—€Eò‡8¬ÐúK¬ Û;2N*¥(ÜzKOWwÈÑy=oêæ¹Å(.¨Ašp®8ßÎÐÍÌd6P¨ Rx]~rGh©˜iJ²Ëô`*ð[~¿¢ ûX€M¥z؈T´¬pI"7ƒá…Å` 2á8þA=ò<ðûxrsszPiÓpô€›|(<Ä"èÂÇçC¬½y 5ÇÆ&`f6#«%AMvn¸&uþ§ëQÃ$CÃøé–VTPƒËú˜ød(ED’žzv<µ}/LÎÑjêú|6ôèOÿû¯¼øZËâkª¾ô/Zó¹ÜºùTù³SsÙ;óÕb ‰Úû¶ëÖÁ[oY‡î\Œé½tc³ÙœA—jj† ¬­ÉC–È Ùg±T¯«ë„[§öE.egg'4a¬ßÔg÷°ÆCúñŽžøƒëfÒW’e&ª®©œZ®2äʼ»æ.£ó5éÂç `ë¸ùà‰@åá’µ§çÉåGÅ@ô_Ð1¼+ë ÍÎU¤¢ÛçA]÷éɸ €N±°¥™^Eç4iÀRßé*¶ ¡òèšC@ ÀTVO7Q•Q^(K„äp}€?ˆÞ†u„øè‚ûØkà+hØR‘Ð9ó5ÀР&ÁU*k¦ã©âçd0HE[!h‚|0e:O¼V$D‰d’Bö´wpÑ¡ ^_UÛaãw»ìUæ¸Òpbb½Ê²º–êи°RR·RYtŸ™šJ Üé˜ÊXx^m­Ð¿¬bZÈM}2Ò>öÜKðôóû`>“ãTg,|ÿü»~Ÿ¹ïs¿÷˯0øš)€o<´Í˜œ›_9—É|lb*ÿžºaÈܼe-Üó–Mx¡ËUø+Ê0::Ó“)Õ1FUàÁBÄ)€¡rÚíS¹bã…oE²½½oŒÜŽ+ê…3”zse.Ÿ„Õ7ºï0ñN é3iG .án­Ê 8¹úF=…B‹x\úü71É'¼¨:нçz®§.MÊ›j†­ó¶È2tykƒ¸Èõ¹hg  à*l¡FÔ+#Lݳ ‘8Ã/¶TH"½á3™×¯±RV ÀX­ÂËK§’r·\9èÓ¨Èô'G_“÷E ŠB6Ö¹HB¨’†Š4 Bks3tu4Css‚…˜{ÂUê‰+å¡Rˆ¹é4Æã3G¯ŒÒ¾¬È¡Q Ô b‹o4:Ê•H·µ7AoO7wªâ~ŠF09‚GŸÚÏí8eÜ‘P<•/‡üöÙ¶qø3¿óK¯IÝÀk¦¾õðóm§'gÿäøôoLNeƒݲe5Ü{ǵÐ×Ó…’"‘ æžŸf2G•êê)¾ÕÌRHb‡.ÐXÊØlÝ#^Ãð<¨J$FáoA7­Y‘?Y‹Ïq¿`Ÿ™{(ð"3ÇBÍóå 9ïO2óÞx#÷díóŒØsxPʳàSvÀEŸ‘}Bô‹eÆX°MÖÝÞÃkn¡Ósõd×¹·ªÇXx-´"0/z].ôy M}êìá³^¯Ëçy¿|—«zýsÙ­!3-($Åéã°‚‰ð(\ðÉlƒ)óôL¿q@µkwP)HTB R‰vôÚ ‰AÍò£ò6Éîs³•þÞNhiOB(äçÞˆ2ä“•ᵂ´1HÁÌÔƒƒ¤ƒ ôu…8+K´C£B/݃˜÷‰©"µµ½:»Zñte8A¯èôØ<øƒ°m×Þ[Á€¿„þ*à³?ûGù…‰K'}9î×âK¶¾tÈ›˜ÿƒÝ‡Nÿæ‘‘‰VºžÝmMðÖ ÷ au9ƧÙŸKÁÔô ”PP,N+Rƒ›ªw›Fÿ½RºEV£5S£»cj´µ¶âÏ·ÒbÊ©S ²ô(ÄV¹H]6dšŽ€Bîm-m§¬À:NÑ•P¨QQ¤Ó` ° TN…ô9-¾d¢‹[•±.ïG,¸õë†NU5×ó‘WtåÎÙ·uïèÜMÝ8d¡bzXᢟ#šRIêa©^ÇoÛô˜ˆ„p¶€Yœ¨HW@¸):WKò \Ux$‰PU¾eü¬²„B ™D Ì5w@)‡ªú>J¶u4A_[WB Uë`ÊöhôÑY ˦§g!‹î¸æœU¸ørMð*Fn L×c RJKkÚ;¤Á!\‚2‡ŽÂ¿ïi8yf†•xs<:ƒ?þðóÿÕ?_Šlý°ë5QÏí:ô»Ïï>ñÛ/î9ÞI%•½Ý­pß][`óº!¼3ëèâ•ÑõŸŸ•õÞ¦pÁ×Öü:eÕ4Ì%Þ• ·’jöãQH65A4f¥BÄ#–ÇâøÓr*l¹Ýt­yNöÚ#W–òýª= >ÅîD9åð Nzÿq>Yüb‰>tmìÓU{¦:]šËŒ:Ý_¯Ñm÷âu€y^ÀŠQQ—/z[ ‰øg+£Þ'@wØQ0£Bë¦ÃÎ.¶ÑP„PcÄø5š†­[ àêû¡8<ŒÃ’=u¢žˆ”5 ·Þ§zÒµv ²2¸J™*ÑEsž‹5Ád[cíPÆð H8¾Ž ÇššâÐB×ÑÑ‚Þ@@–6kàTÀt~ÔÚ<ÎB&5/÷[£Ïe.¾Ñ˜ÂÍ@ ßé^X^(Àµ$x@ÔI©³»Rˆ½»@Ðf|kÏÁð퇟‡q4|„àù›¿ýÌo¾ÿUÈ‹ï”K»öyߎÝÇ?÷ô‹‡““3ó0ˆàntûo¿i-ßÔ §¶TèÌe €¥ûê·Ñë]^;u-œQþ?RŒùã‰ß®^#k SRxƒ,j#ŸáXSr£Szu»Ê½Èq>ÅóyŠé³Ô®½†ÔH õ¨ÀÈÍw* ôX@BM ®OÏ5 ëD¾Ço`1xµæ SW‹ÜJíL¸S:ŽÕo J« RŒ§Å]øñò¸'X*3³áµ ¿ÑÝY˜a(ËwéÞPÏ@Ó/€°U 2ôL¿csz!ÄÆs3©)Ð ¾6ŠA¶© 2ÉüÙ€ù$xTmØÙÙÂùy*4rUÿFíÁ†j$šãù¼7¨· „>ˆ¢Q¿w²ã¨ HÉ8× Ðó~ÕWñÙ‡áÁG·ÂÄlšØ£[Q}Üÿ÷Ÿý¯^\l[¼:ëÌd*ˆqÛ]GG&¾÷õ¶ÁèÄ tµ%áú«à]?~«ªx“±†7*;Ÿc¶ŸåÓE<Š–+Ô¬x¡àÎËrãiÙÎ[7<{Õàr‚"…ñÂGÐå§Í.¿Bðù]¤„¨c/ºêlùñw3^-Åů1ª[%Ę0RŠîëbŒOŸêû)ö‡B™sü¼É\YÌãªE#¹D4XYÝ' ¶Iêl…öp¥,Ìóˆû…Òzž· €qPOƒiœ¥¡­¸®®k Ñ: Üz£áû\C yíÕ½ñˆ’ð zJ÷ž¬¼cº²Í–í‡ú ú$§À†™lÄ% –º&ŽŠåÉšS(F Sð r‰(¤ãmjí…\S+T}²¥ÿÈÓìÇp``Y7ã>KÚjMÓfÄE…ôJäÅ9²SôùHäg ÁùþnÔ6 ½7ƒÇÎK%C¥DåÆŸçOCH¾ö'aÛ®ƒ4g€0–Ïþ±¿ùÿyÿ«%£:öK²NMo)•«/üõWIº‰Bsãæð ?u'†z!æ´Ë~—.³yŒÃrrrìYêB‹!3bŸ:2žvÙMWÌpÕKZ[B”f‰Ç¹‘#-Sh6¨+-}¿;7/uH¨òÞd­ÊߣB xÞÅã¹,ø»˜GW1›½·Tfâa†«Ów¯æm{ã-OAhò‘iI|€ ¾ˆnì“Y°í:°ë*òPMÎuä*HšFäÁLç2˜ì†R$Áµ ÜÐ_ß܇•+˜IÈÍW•2Ö 5š Ÿ¼¯%4HÌ%P ÔT%UZz—.a\d}‘¢uLÇÂŒù< ‡š¿ºP@ñßx¶í8Äá¯å³¦[›ãkMÓ˜ýãßz÷«²£^5ðåÿxrù|:lÏ‘“0“.pïþûîº6¬d–¡&ÅVQxJÅ¢JÃo©Åî£ÍAT¶›&—Ÿ[<[à ¹Y¥×¾[iy*Ü1©ÏpèF—ò ÒÉ|»`.9Yr¦áy­»ƒÖÞA—ߤã%t¿˜Sî¾dûQx`‚{N¼|u-¾ôÐ¡Š’˜\DJ€¬$Õ0yHyš j2߯  ¦*úBC‚ÖnÈ&Û!ÛÜå`ˆ'ýPøC ÜßÓ ýCílùÉC ïJ6^‘ä&R Ô¢­BYGMy6uë4¯®°á¿K8GPõ$5SžZÄv ˆï§p  žëÞC#ð½G·ÃÁ#§ ™AG[˱¦Xä-}ß¿*YWe—>úÌžUNŒ}iïá“wæKví~ôî-p÷­›Y³Q—Rô#“p\É{XÊгÞUø”tZU*FÒ¶‚A°0Öb^¸£ÊnA¦ïlîÌ<ÆíiÙ\“™†òs ±g¾h _ç¦ñõy‰ê»y)üÌÕç&Òc0ë™óWãÒ¾a×9!Œ©ê,É`+L¤"Â4”Õˆ¼—ïÏ  ”!Q³ñ.”ÂIHuôÃ|[?šš¡ê§"!‰¡Dbèîj†¡þ^†PªJö¦))O¼gh_RcVQ¬ªpõ|Öɨ󇗰Ç ÂpòÑSµ1ı¯U®i¨¡5{jÛ^xð‰m¢ñ–©Z¯Èh4èý:tX:uäêjXçB‰LdÊ2[`Qã}°XøÙ+pM™ò4x¾€ì©@YJR† kR(SËWCº½‹½®5Ú~è낾þNEƒ²J“9 Àý&Y¶©<÷lÍ‘¥Øç(ȼԙ…œkõòh¬`€S’ôWêq13—GžÚßr'ø6ô´·0ø3ŸþðÏ|ýR_÷KºSñ&Ÿ<3ý±ï<þÂ{ŸÚy€ÎþÎ6xÏO݃P,U¼U.u4H/¯äÐÖ³¾Q‘Tt??—Ë/)f4¹$ÕâvRš»Æ%›Dè¡Ü<¡÷Ôb$`Å=u©„Ðüý=Ï´]ªí'á§ØßÅçe™®£€'u šüq5îÅ낵 zOh†òL… B`–¡¤x² .“–=¸ ï×tßJ˜A%PÀp B±*³ §¯{;&B!6(5C6=5•'Ç_˜ì%G¦Ÿï¸—<´T žÕ¬TNOÛÄ ðËÄn¢†+GONÂW¾ñœ˜˜Æc êObQÿç¾ðñ_›º”×ý’*€b©ü¿zzï¿ýèv¡T€d2?ûŽàÚ5Cèæ˜<;ž’]+*|i¼hçƒZ=xW±Ý”[®l*iûeá«ZÙ¡¤šx³ÍB ~Bù…#•‘%¤Õw1LâI3çŸ@>@Ë_ËäÐíÏpáÁi=Eäqn"¯ÒPgÓ¯ú/o¯OCýߊ­ŠžÈ+`ú0a4k€pºßšêÍÍVj4Ë…\g ÒL ­…ùÎ^¨†âÜoóó>úzÚaå²^îDäšBµRSUªÍ5páZ×=çX—¬)”@“³}éí€h[F¥µçÀ1ø×ž‡ùl>;Óœ ÿQ,øÒ§>øó™KuÝ/Ù>ýæ#Ï‘Pøñgw»ãŽǠ£)7m^ o¿yDÃ~n¢( ÎÅ?û¯â›F¤0›–|*Ú`‚—EL!·Ýz3—ç¦ÅŠºxŽÆtSY.ÕäŸEáÇXß™O ÐãjèÉxØÂ€Ú )³2 tU•ÜùuW×ËYg+•Õ ’C@-ËdƒÛkP"o¬Åüª¿ +D>ó¡â¯„03°fzú¡o…j¬‰= *È |ÐÕN\Vˆ… ±¤:aHóæB™Ùxœ‹Ÿ˜Rg^ŸÕ©‰ÇÖÉŠÞ×¶% Cyv?<½ë0” eho‰ŸŒ'ÃÿóSü¹/]ªë|IvéwÛêËßîC£vøÔørÁ=Ôßïþ‘ µ)*cëšlËl(—NêZO=«Ûb‹É#ô?Wv•ᜲ79ו–…ÝFK`aÌn–iªNÕë‚GÚÜá’]ŒéÉÊ£«dý)Ö§ŸT$B…=”ÿweƒMݳÞT7SßUÉÕ“eÌW}€~-èÑ'ŸP< i‘½þ„¨„ª'àqBÄ%Pc»¨þ ¨DêÁûH¥ÈùDÌ·`8o†ÔÐz¨‚\ÜUã¢3::’°¬£"á 1¥ÆvLÓ#H)Gà<{xÑóòj…öH#ËUy0²-£€™T¾úÐ6812±HÐõû­ïþùÇß÷—ê:_’]ú…zÀjއžzaïñkόϺ[[à-[ÖÀ× aVc¶S^¨¼my´Qç à¹oêRœÝ¿âüS)—H:¢¦zñØgrI¦U+ƒÝ?_©*=!K€©ð“nlÊqQ1¸Ù þZ}rý)˜—…<\ à0}T ˆsHßCÏZ\þW².¦øÏ¶®:ä‚Î7‰!j±å“09äPOI2 ÜV PEå@ `5‚ñu7@¶£•@Hve¦0?«·­º;“ ùe³%å¦{ŒKj;fIö ³:Ý—a´ Ù†µNlk`qRñã5Ußá³}ðÌ®#ðø Qd!d[ûÐyç?~îC‡.Åu¿$;õãùõáB¾´gf.$ äúõCð¶[6@8([mß™@jᬫ¼ÔÐ[Tcec8 mu6–TÂõrM¿¯Äã±k’ÍåšàXr2mµ~…ØBТ;i¨¾t¤$ˆª[È2è ËóR°ðHX©*º©*C–/\µzºß¼Cæ±MÑp¬/ç.¼‰ADMörë¡¡|Âû«ãµrÍÕ•= ©Ú2 Jê4“¹F#@¥ÜÜ«·áMšé_ Ó+6B•€ë·Ù[$.X UgsO‚ßc¼!"2ÏCôd¿jInh–§7>¾q¿jö§.•2ÕÄ&=¤ÔðŠ¦¸ZÕ ªó2TÈkÅã·}&7Æ}𙽰}ï :ŸtÀo=ÐÑÑüûüÛï>ùÃ^÷Z|ûñú_8pê÷o­R ­ZÖ w^¿Vtò¼4Cñðèq™ú(ÔxJ£ñ¢5.e!l‹Z=ãzn“¡ª¬ªe‡IDEn¯Í‘Ÿg„}¨x’DéÅ8àzB{Õ[Ÿè£”Ï'& Ð“ j/„ô­—Ûp¹²g?o±†Ê¼WO¡žûE©+5lÓ5¼‘êB7"ÈuÖƒW…(êµöÆ‚môÆ_³r ï9ÃóÖcÉ€¬&ÿnûT3Sž³ F-jEVÒÃAa/…¢0³l5Ì®|k+*Ø®Å54“°£5 -É·©W%‘ª·„ü~ê+ ¹cµœ6¼ðœ Õb¤Þ\D3u‹:íý×-…ÈeüþB¾L“…Ù“MF‚pøä<¾ý ¡!#ÐÚ’üÒuë>ó®¹åôsݨÝõض½­™láÿyî¥ÃŸœIåQ «p×ká†õƒÜˆÁ2§Æ4Röhk´åç/IeN–h@Ô3Ë›Kãµñó³êû^‚š¡zÀñ ¹øQcGQkFݾ´¦>Çd·ŠÓxÛsœ?î| Ütމ=@é?"q;.É[wýSN^¢{¯ÆZ ¼vã¬TX–Í›ž[éšjú°ªztø²PŸèóæPKYçëåÏKõ*ä&°–¬)  [xË m)¥"3Ž#«:‹Ñ&Hõ­€Tÿ0›[Áð‡Yèhž@ V[s b±0˜^ñi½F…þ  '`Ê>–u·L¯jB(¡ê@Àû>‹v…â`üo(f—¢öR'ß*y2Y0åÇG8ýÜ߯Èi#ðzñÉcq½M&”Æ^œ¯è(7Ñ”E¼°b„dËÒQY4&ÏÓPM<&7©& † oêø a]HÈIKÒ¤ ÕÉØP^3 U‡'âð<GæTPQä›: ßÖ …ö.H÷,GO@zt\SתÖd”[ÃË¢B6Å+ÅC ÆŸ4ùØ^P¾^¢û6öH¸Ø"EVÂ0 •JC¹è27ÀÀÄL^Øwžžäqswݼž¸6¿þ‹?yÇß¾ÒëùC)€/þóƒïÙwdäÿäòvËÉú¯ìë’ qy\5@G{3#ª–âà/åj 5]@~Ÿ¼îªtÔ@á/ÂäZp£î&Ыø1£q´ôAQ›;tÚ2Ç_)r‹®*•û¢Ð©ÿ¬RÚçöQ?`:)U ꌄ¥©ž|µ–˜žÔu í0ÏÙ°òã,ÕªÌë Êfç­¥²4¥ófY‹…jR™TTdÉæÜš? B£Ê8–øT5†r4™¶.˜Ø| 8~?ÇßT`Fû0ˆŠ„æCÐä!M+£Ït„ì}@·¸ƒZ”ÇBr,šn„²`Þ¬àÞB,~/%ÅÝe*ðäDŠS˶j™vøô<²}/ï‰XÈ]­¿üÑüô—_éõ|Š็ÞùìŽCŸØºëئh$ ý]I¸~í4ÅÃP¢ÚztÃbÔ¡£‰Ý¾ ¨ÿ¢7™ÀCxC8¼£®*él¦¦f¡HEÔ®·fò…¢µ£ÅŒ£ÐÇÈ›rœ5ð"Æa‘?Êñg¡ÊÂ?Çÿ¦j>ÙÀÓá×»†£ÆZ™Ò 7$9ãåå{,“d–«òßzé²~VÍþÉ$T³ï„.ˆ1‚DW×¢D§ ¹´×PœS²©#‘P”È ¨:²Ð‡Òƒ(©±ÈõwC®¥\âÐg8ʸàŽÆ#¸—ë \äJ‹ x¨M÷&C=½Hã9œ_ʽT}jø9““s-”Ø{¡‰shü¶ï? 'ÇÑ;¨”`Ýòî—®Y=ð‡?v÷ÿöJ®ç+ÚYÂuþÓcÛößÿÍG_Ø0›ÊAÀM›‡¡‹rþ–à)¹Á@úºZ Æwt³¤kz±Ïuß@ZxÃòPƒñ‰9˜Me@6—A¥àúYh›¬*´dùñfÑ="b…#{ñ jÁ£ ý¬Í]››‘t`GZkÙ¬£±'Ÿö m½²¿–¾aÁC€‹„² jkÈϲÏg)(•`*Ôãª÷ï­‹õ=ÐᲿr$»!«ûˆ.LCMT§&íÛ¥>‚ô\µ 5šC0´Rk1$hG%BåkÉ©Çh‚wSbS×xƒdåþ R㮎Vw5÷Q¿ÎëÚ¾”“T¯§ï$Cwjt CØ®þšš‡§wƒl© I”¯·Þ´zÏM×~²§­ë/÷z¾"061ýÄ×ÚvÇž?ÀñQ/ZùkV-ãyïUꤋ›·%‡þ¾€dã=Ço)_`Ê«¥‹&øv⟘æQÐ5#€âf?ÆÇ~ôÝ;ì*´šÂ“8îXË=û <™—Ü}©¨¢/ ÎÜ*…"¨Àîu´½¬â›rO 4*f£¡šÔ:Ù}˜<€†qá’õ® iÅé]Å`RËÖ@¦*-àbxÀpŸÂh<ÛÏÆÐÐÒóIÕ1QóOÚ™CÐ"[ÀAC¡ ![Ò/e›Õ1Éw¢¡83ÿS­¿£†!Ì‹GNÃ) æ3E¸qã2¸÷ö ?ظjøÎ—{-_Ö®?:2eøm»õÙû¿ûÌ΃×OLg ýÚµ}ЋpÙo¹êB"‚eýíFê©=(r)  šÁgêî9xåˆ=‚"›Ë«¦‘’öI®»Ï….ô‘75 5týLª„öÓÄ^B…_7‚u½œuq,ÀëøÂYS( YV½¦€¦)×d9:w¨p½×\[äû‡!ß; ¥¦žs ƒyÚ¿4ðÕfLA™tÕªŽjJ ŽÄÑxHMVttY ÞÀwXl)Ï÷t)_‚㧦`.•† ßb/ …{{û¾S05ŸfÚý­›Wm¿óæõ?Z­:3ýÝ­/›‚²¤uld*ðû¾ôßxâûŸ Ó¯žöfذ¼[ZdCöX# 8´¼“G4éê‡zƒË%•7ù‚'lÁÔx4ÐAá€Ç¢ŠZ5BŸ¿ÅÒ\)æ§ûUã} b=Ðâ—H`ÌO-ȨÇ?ñį*€+w-P ã¿Õ ¬ó0„©˜š²)ãU9›A¶tàq"Pñ Û=©Õ› ØÕ+Û¶5d­åR Íj!ÉD5)+…ÁÁ~Ø?ò†¯@SÖ™·¯Ù«šœèÒ\?¬_7ÌY1y‹: {öÌ£ÎQ'¡„ÁâVdäq8pä gØ,E4;rjNŽÍñþïíL~ü®ëÞoÛö·¯_?”]Êõ\²ì:4²|ljö›ß|xÛšl®d%ãèæt7CwKLöÀ‹Ö‚ÖíªBˆË,  ¨ºb ¯½µëEð%4@ó¦ÚÆû8rì œT C%7é06 É6 YõŽUN|ÜbŒ¹48ãcà¤SàPÁºþT Hy_îñ¯6ÅÕue­‹–‹7à{ßT)S÷m­ ¦¨K,ôÄÀ#“8,ô b°bs'Lm~ ”zû Žs¡wF²÷dEí)] ÊÑ>» ôõvÁð`7Ä¢t:]5¾tA‹:TQ ßkÐ8™ßPY"ÔMÍeàÀáÓ03“Ûoñ¬Ã™Ù*€Y˜œOC$äw~æGn>МŒþäW_Êõ\’œ™L³©Ì;úÁÎö8ƒa“ Ë{Z¡·#ÁEdí]·›7¬B·§ƒu®®â 1*(t­¶«A’ü¹ž %ó·ªí4c.œD÷f÷þcLÇ5TÇ*¾¾'d¦¸É“zB¶œðB¹]¹UÌ«˜Ÿ<âû—ª<ˆ“ÛD¹Š”ñ&áØ¿Ù×þ†ŽÕ/WŽŒãÔnÜVrY͆l÷¤7\ Õd8Á€4Ϊïd _S¬H>.2ÀÁ k‡`²aä‹Ðà­HZ¸ËšCxu%Œ^Ê¡(¤`¨—&~ÊÈÈìÚ}€û Y‰X±g¦æàÄè †6¬^Ö[6 Ý‹„ºaãð¢ñÆÒÀÄÜÀ±‘‰þÍWþ/†ß„ /ƒIhID X“M8’1\Ý&hiŠB¹TT%0R!<·©±8¢±tV(‡Bê‘>9•†={OÂØø4øC>TPsg˰`yÄ›“˜¡~ïìiPÊ'õdÁMÏÊtßôWöQM¸ °ÇuTç1•¿J°yïóÒ°uÀ0 ‘VÌ)A4$Ò,Ü„:•mZ¿Ê­PijæP€Àr‡…j ¥ZCoP‰úçÑíëê„Më–£WƒjU{¼ ^¨¸%ByĦòX²er$žLlRõá\* Ïï8éL‘ÝšAfæs02–‚™Õ*¼ëÞ›ÿr »ýO®Y;xj±ë³$ 8r|ì×÷ý«¯}÷9ÓöÐÕœ„6Œmè‚РFc’MkúapY76ËdÊ£©ç¥—054 Æ”©>¡Š{T©„œCšyçžã°oß N-R˜V3ª@-؆®Ïš˜ Cø¨ªÁüÔ΋À>Ö1? "EdŸYžzا7‹ïªà¿YÖy')ƒ®À¬×¨ËÞ”ÄßËD5£›Ž®„b{äVC-Ù*«J s¢ *ŽT.fkZªcË ¢ríê~Ø´a9w®-È4̪r°N|MÓ 42v4Õ˜R‚{öŸâú*)¢›ÏóüZ­ ÷Þv­»qÍ²ßØ´jào»>K’„ÇŸÛûáG·íþüé1*:²`YW$Â9Ç3ÃÛo¿b± W6É9XåòŸ³1ÅÖÕ=t@æWMŽw,ËщìØ{Æ&fÑÛ°9}ƒjB¤h’>X™Po = Æ¬.17îÌ,¸ÔÓ=šðCS{hp„¬- Ö ¼-Bñë«À~-F’ME´?2€ûš†ÈÐ|nŠûÄÁ}XJ$ ½ñv( ¬dlŽKQ¨ô…7S,pù»SÓcìe;)…®¶8l^¿z»¡R«¨¿›êk5-Ílè(„^¼‡£É}›Êá±'w Í+H³‰†‘èÂD BWºÛÛáî›×ÿÖ=·løÂb×gQ ›ýµç÷ýÈWxzm8b&RWKBþTLì-Wð0Æšã4”ðžU½¥ÄÝ”%6 Uÿêõhêm¿?xv:6Ù¥¢ ú´£õ_‘ðCGØ„² qÑ8NÌ2ºÿ3ÓàLNs=-ƒ [`¦—¡¹õú„]‰AK;ý«ë _‹¦zµÐ{‚«1@*ê UÃø?׿2뮇JW7˜<Àࡳô=D‹ŸÏ乿¿¡&X× Ê`÷Ê^xËM@Såàýw5_A4Ài$ W9&W*Uxq÷!8~bJ•2§‹¨h¦R®ÂÍ¡<üìܸÿ–kVýiw[óß]ìô•€GÇþêÑ­»?ðض}†1îA,`לRs-ɼýŽk 9åT…WìãåE¨†äD™j^šj¥â) Ò¶“Ó)xrë^˜ž™çFT†¼œø}Nøh÷ç3E"˜\;7^9> $Öΰ®-¡‹óèü¶pƒâF{ȳè!—}í;{Qwì”d^™¡ TâÓq[u^!' N¡o"F*F®gÐ|SMgDÏ_ç‘ÑɨÅC0­ø_µ×r,¦¥i1ÆËm¶Ïõ@Ë<Ï»i”v§¨•ã)Ð ŸÉ)³œ¿ñü|8’jƒá˜gœ¦0àÀáÓâu:t•çb/ÀåtcÒ¨r,]:Sæ :–f SÉsÝR—¶Y±FZRN5¿«G‡j3B(ÁËonÃ~z­@ŽO Š&’ˆÐãݽL›0"±d΄¯Z0íÏÏw .¿}nÝ›ïî>|e Ëû<ð¬=V±¡ÈˆP gLÂMWÏU^­ÿnš¥’Š>I@C”{…º Õ)Åj'§Ï´ãé7 Wâ§”¸9\6­èøôè< ?Èd߇‡‹FC¢ãgðÐÎöV$[Éýçɽ¬ê“Š«×Ìhê)!RCÕ\òæ/¯ý:·gª@qWLiŠÒF5ªm˜+N<nôDÄV|Fa.¯2Z(7½‡ 7ÍÞX,½ª€¨ ÝuÃrTUˆœ½ÃP”Òµd]Hk¨Œi~|:…nñiè[7…Æ«)dÞ²ã€êyÐզƯ!O8/7€Ù“G½þ'w]½â|×àœ6°ïØ)·Ûí¼õñ6~Ðe4k ;™sÏ#˜8ïF®wqQ.®X4ó§C˜eÀ΀CÈ8ŒiLnèìcóöýذuŸLƒexcÒÏab|Љ[Fæ)uáS;¥ƒKïé@’9þ¬é×Ö‚$‹{êñ{÷·“‹—×åu®u>PÒl…æ³ ¬#˜"Û¨…äÒ« •–@/.REo×…Œsðt ö9)ÃpyçWù±ý½†es'aÁœ (滓×I鬚•RCIÓܘ /?Éö}ÇÈsރƦv8ÈCç0"KJ[s<žÀ„1•õŸ»uùÿˆÅ“ÏÑ÷ñþÇ8§u¬ß¾/7Çïyí‰Ug;ÕêÌae‡šiÎûg˜â ~×,™ŽÂ`@.ÎuälàÌe§ñœ¦RÜåAˆ{Õãù×6¡£;*¥¦ó.n Š?†Ä‰ãHÒÏ úþã¶Î—/J®%åÆ <ºMpœM;k’Y®…epTÕ ç¦Û‘**¢'£°:øA3Þ­;Žì$SQ‡)$è¡ÐফçãŠùSEEˆ)êr_ËÆo‡!·)&α&ÇZ²ŸgV¿£šâH7±§Îåù¹Sdžó‚þò[¯™wV‡àYÖ±cßQ-K”½¶~÷žgÚŠÙú>볆:\hÅöîA”¾"[·|,á¼ Ã,`joÔ€b¹g;0´1VTÀÿ‰Ûଫº ¹©ˆ702ÄÎp¯¬ß‰ƒtûäÞæ§„¨3uì\·|6Æ©¦0J»ª‡¬—À-Ë Â¼v<ŽçÖlÆé3pH®Ì®z©ß+) ¶ÝrÍÜ©>«iîÔq}嬗Ù^w$ŽÄïüýªM?êê NS µàd¡£ßÒyÓpå©29…E:lô‹Ÿ±ºâIçû¿î]xeíiœàÙœt™ã¨/¦û1©Ð-_Î…¢ùH67Q,Æ}þ<Ð#,³àaéºVbU@Ãf$ ¡5œ {±§À€zqÕ°ƒ …öó’àvs¦“áó$*þWæÂ9k‚‹¯„§´D’JæÞ䄟«7nÇæÝ‡Äí²yÜ.7®¿r.V,%Š>2û‚u5`3d°èp¬VÜJ›à: ÞÚ°›Ž«48ÕXs§P‘}>Gèþ[–5Çç~jÞ´ñ=ýÑw½±eϬT*µêÉ—¶”÷ÆâºËÁÙ©t÷\œÞàgîº3¦ÔJ²Íxƒµ´ð‡) )#©áÙ—×ãí-;‘ðK™%Lvn¡3 s0"׋"¿.È+ÈÀMF̦/ÑÒ“E»{e”—–ʈ Ö4ÍÐ.À%Z ½o½ñQŸÊµÎé Xä6® p—í9¹ÆMª² ü>è••(¼ëÓÈ™4Y˜·Ú‚9i^wô4ÞÚ²ÇO7Iˆ«^Ë@¨7Œå fâ¶–ÂÉ oÖ #í¿øâ†:É/Ðùîª;ˆGžX·ÛmqpØvJÒÑïw·¯˜ÛèÔµ›V,™¹£Ï1ú”â‰E{žÙ¸}ÏÄ“„T‚L ¹Ó /ägïþÆŒ¬&äRdÝ¢ñ^ô„­/¶g·GÇÞ}'ðÚº­8~²9>¯¤í¢däW–û±¤ª…Ò{ ×U3Ü9Æç)>FSŒV€8ýVóÞ²§ÄÈ@ K€ÄÔ†Z Ë7|óæ#çÊ«?êSÔÅ^A÷; ¸w@øš!”`Öêç4ÆEØ`y"1ýzÕŸÁ%KDr^f=(ErÞ³ðúÛÛñææø•<‡p$‚QUXqÅ\L›8Z”®M[M$[óBË4ƒwŽ?ß<þ 9Èq¥HÀôbn¡3] :fL‰‰c*¯X4ý>‡è̵ß›ùøêÍ;"̲#Ôs U7%V9ë8~B5V^±e%EÒšÈK×6ðÖL`t€NúÉçßÀ»;ê”P‚RAЀÌ.͇ßE.L*7¡O2–,+õJ654+Žý©l‘I¨h–v»9àìÄG³œ%¥Èÿü>N‹ ýÇ?’a8¬ó&-EkÞíùg“UGE7€ÍÙXw*¿ðe^·R:ót‡[¼\n$Êóù±e{V½þÂÑ„jð‘–á“ÿ0{ÆDÜqóÕ⪫ ‹70 NUÅ=ðz]hmiÅ«omÂþ'(NÉtä”LÊtÉïù=NÜvÝÂY+ÏØÙ÷YëÈÑÓÕGN6}þ—O¿ùîüÓ ãœfJJkÌsf—æ×/ä £á§øå“TS¯Þg¾Àe¶tØ4îùèã/bÿácðù½Vû#0µÐƒù%ÔÈ,6¥'à M†»”ÚOW7RÍH´µ©Œ©5ËÏ´z Ôhn…²}Qah¯Á Øð8ƒÏ™üþËk½Î¥(G†^|ÝxüœçñQ¯óM{ê3sjЫf8…­§ï{é~‹$’êþ7ˆä_½ÅŸ¸9cFÃéÍÁÞÐý7NžnÆëëßÅŽ½¤›Ö´ZÑ#´©­{ïü„hê·ÛYÀ‹Ÿ¿­¢¥“±Çh#Üà(ž_½1žŠ-š†:’<›@€ÙŸ¹ãÊ¿SSþëɵէÒÇÈ>஺£_«ohûÁã«7ÁAp›Qè†â„*99|á3w¡¬¬Ð’ú7Óþ®rÇ ¹òûöÇëo¾ƒB.—×)]’>2ø«*9Ès{ÓýÒäo!î–<Ð3ÕÜŠTG—jŒ¶À¤¢i2Ø´ú ¿Ïq^íbO â'?´ãüäíú=Ïä)â…ðy öbo õûßr‰Â€"’rfß!,ÀT(Àä öX”&ÁS;…7Ü€‚… áÕh9޼șž»iÛ{xî¥7D0G·Ct3ËÉ–®ºr!¦Œ'cÈÍ÷‘S“så;_W½‡MmøÕcÏ Ü‚Kw‹¬^’¥Ä4·äÈïºnOëúúÜ)µ?Ìz{™õèªÍÖÞÝý³­;÷Ëo"B—2㨨*Å=w߆ü\ŸRCÍÒóØÉZ3ÏâÞ\»»ÞÛîPr™Àÿ1ùAiVB iîÑB!iÄHu¶Á Ð0yªiXJîø.«ü_ÿ]våÁX€þ‹A xãMƒž¤d ó׻܀½T5À”D`ŒGvÑ&Ƥ TŠã ¤Èè ¯½¥+o„»¸H­JíÊâ{öÀ¯}Ú3¯L'Ež‹éL2 7\w\.%I>P¯5»—+h<-û±ÇŸFCC+GÇ 0u'z 9L'ÊËùóûn^’Þiú¼ÒëïÔÝ·jí¶G;:»ägw2 'S é=>/&NªÅׯ@Žß-Ý€™÷E-Öú'TJ˜xà¡Çp¦¡AQž™øKW%Ï|a\ÊÉÓHYã3¥’ )&þ´´·Ã GÓaÇÇ ÿò«ƒ–ücÀ^ yŸ¼gЀóà Ì´$—a%ç¸;0L!q\ÆÎ[ƒt?T|ê^¸KJÈ =)ȱÎ3§ñÒêµfŸÕ!ŽÑ•¡ŠŠ |îþ»ÈñªÉÒæû±)eĺÓ)¤¼×^{uû ·'ª€€(¡ù‘"C+ËÏǵ‹§~zåòY¿Ëþ[õ6Msùº­ûþþç¯^Á’Ü:½‹€5dìôÇË–/ÄìYSD¢˜ß„-hnZ¸Ø‰ŠûŸÂé†f<úØÓuwÃÅí”L r^w®"÷ß!®ÇD2à“i¾ÜôÓB‚}Ð÷z(Ø+ø‰›%I9˜kx€ê_‘ÙÖ­§]šó1¥ÔÛÙ¼‹QvÇpÕTÃWRž¶‡ËAny;wîÃó/¼¬Èðܬq+Ü`î½ûÔÔ”Ãét*MÁØ––!<‰“د­Y‹––¸Ün‚’Òý*@ž÷çn[ºæªE“¿ãtz×e‚Kzß}mÃ{ÿó7Ͼ…`Ðg* G""õh4*ç÷~ê“(,Ê•žd[¶HÈÀÜžnʳý¶nÞ† ë·Òköʼ6‚”x˜\äÃrrŸ¼.]2¨rD–]"ƒ7ÛÈð ¸Ì @=ËUº g¯Á^–p’r0†Ãú7±Á[¥@æÜKH@÷µgôX,Y(š3Œ2¥ô/Yƒ‚þöÔ©F<ôÐ#´SÇÒ‚¤ì]óÄáE‹çañbÖÕÌ•â}M¡·[ˆé_n«ø7¢þd|>¿ê1púrxÑŠãÞàÊ¿WZTô-þÓôËì=TÿÀ–]‡¿ôÒº÷“ã‚3νõ1IJ$ãqL ÷ÿK_þ"¹þqë5íø_%"XnÍ-mXõôó8q¢±DT’wB¯1A®¨.ÀO„RVù…ùÕÌ÷Oµ¶ pË/ba‹Viî¾ ý×`¯ÁÎ 4ÿãß¹ÄàÙ+v(ÀÞiÔ°¸dÌ ˆr9º ¾q‘7}6Êo¹Eh¹fR)ÿ¸È èêáÉ'ŸÃÑÃÇ‘ˆ%ÄEçûœ«]¥¥…¸çÞ;PQY‰(OÁ‚qÑ3Ë$Þ2qK¾ÓåÂ/~þ8,lCæpÃðä#Iáš1sRÍ/Íœüeû/e=óêæŸ®oþÊŽ}Ç…8àìm’ »L|`Îþì¹ÓñÉOÞ‰X4j{Æý7¤çùâíÀ GǯxÅ|„°ÃÀK'9µ 7.G@S5C˜¬ãÏl?Úý“m­B⩾f"j‰üd^ó¢ê¯Ã` eà5Ø ÀÕ¦o~cH–3ËV¶²¼^æÐcQkçOÐýK¦$£Ÿôxବ@áìù¨¸ï>¸|^ž8*û‡‘HïnÝ·ÞX‡. œR´š×ÈÓþÒ—?qãÇI~m@9³/Ë…íÆíòàO>ƒíÛvŠ2Óɤ$'’þR åuL®-GMEÁO?{ÛÕ!cÿñ¿=´ê'íí¡¯œllƒCOÂÑӨ꞉Š‹ ±tÙB\qåRkšŽì>E“¸0°¦@‚Àd×®ÝxôáßÂíô(QzÎO'9³0€[GV©Hx 5´‘©¿´û'XûŸµþÌ„ÿ÷éݸ ÙëÃ^\%(þæ·íxÌàêÀP^}¤íLᙊñGiƒJº°W£ %êÈÏCþœù¨ú“/ÀÈW°‘¤I47µ’‹þ[46*j°ðKP¨{ï}÷`ƬéBçU9¶‹Wß>7Ñ7¥zÃÛ±nÝ´ÐkyÜJV?å/',r¢¢$yy¾Ÿþï?»«/üìñÕ?zgÇ‘¿bƒ– C“Á‘ÀŒÀQ#GáÚ•×`ÚŒÉfºãÎæL=u»]himÇÛk×cÝ›kÅýᤠǩ£ˆÐqZn+«Ka¸ÒÏ/Œ§©¿‰®€(4v81¨k–Âïùk¸—àÃYœääà`-†2c04K]*FƯŒ^“îÀ0S„yD˜×#!@Íg¦ºïE ÆšzÅÇøÏÿø!Ž;!ZìÇ)åE/_¾K¯X†’’R„‹ž—=k+­ÀmJrñð¡ÃxùåÕ8|ð|nâL §ú~Þ”1ÿõW÷ßøU>†XH<Özöí߬^¿ç3y>¹ÝmТÝ2¬›fΜ;î¼…E…i­ÿ´Ü—|oÍA¿Àòù}8rè(^\õ"Ž>ª\)ÝD …£}~Œæ`AY.Å+kz˜çev…llÁQN$Õ´UËpÞõa‡eÿúïƒFbãgª+ª2%Ú{ q5BŒ=Þ„!›¥An}`ìx”Þx#Š.‡; ,¡ZæiÓr;]xðW¿Á®»Ø’¸çר©©Â-·ÝЉ“&³¹øyÙÓ´,92Èx1 ½½üáñ?`ë–­È¥ÏJÂy#¾„(,¸zî¤Gî¾~áçJŠ U&¯µ½ý/{qã×ÞØzp|¾—\†Ðñ¨'.®¼â Üÿ™ûÈûŽ¥³iÛ ЭJÀùW ƒÛwâÉÇŸ@o$,ôb[AnÐô¢Œ-ÌÃX¿#­­Æñ¿Æ­•Lý=Ó(ðë“»Å} ̧ÖsÌ}» ²>Là5Ø¡ÀP÷xñÆ#}/&b C’€qºW{’ ´19ðÕT#Ñ"TÞt¼Å0x7×ÕØ/f¾ñúÛxë·ÐÒÒ$³/$ä5ÕÜŒOß?,\€îP¶vGVÅ­Ï ÛGy€%³äøsð…Ùo½ñ&òƒ¹Ògcº¼Ðr+Ð1°tæØƒ·­˜ûÃÑ#*,Gݵïè¾W7¼7qK]=üÚaÛŽ ÷ŸŠUE®]qî¹÷“hïì´2¢Y'¥Y³þú51jYðEó¡oz{=žüýïáô{á0™J Œ ø°¸¦JK›Šª1Î"ü“” º:‘d‡¡qƒ»ÿÂÏÎÐ/ÀÙëÃ^ƒÙ¿0Ô½^’ë²AïskpŒ§ˆ' *$ົ»¬éS0ò¾/À[VA›iB5ùÈdlGŸÀ³O=ƒƒûö{nÄNÈ™s÷}ŸÂrÚp™ÛŸi ÎEF/@ƒЭ„ ªÇåàé?<…7^{ n‡“íDŠ< GÑ(:W'fM¨ÁU‹¦î_0cü$9âS¯nÙ°³îÄâ#§šà4zÉå>(YxNør‚¸âš¸zÅ5ÓέÔv³.ŠMèÇÊžÀä’u¯¿Õ«VÁOn‰.M&¦pCíHŒ+-E²·NKÉ„Ý&-Ò“@'Á@ñ• däxÊPC†›_l 7l/ ñ›ß’eÁ>=–F¿Œ c/€6I.öDU‡ Ì¬ øáª©Ä”¯ÿ¼£ª‘ŠÆ•}ˆ¤“‚zñð/ÂÖw¶ Ttvò¢¡®\¹W\}µxÌR ÈbÚŠäΑð¶ÇšJÅÈO!õ;ë߯Ú5¯£³­&‘ß쮘Œ„Ç1•E˜1iÔÆO^¿h‰üÝÏÿðê†#Ç›Ÿiꄞ¡÷d”˜¥TZ^«¯]‰ù‹ˆÈ`ÿAÙÉ‘s©«ðcÌ,lnlÆ[kÖ`ËÆðù”†y˜Ž¿¤¬·NƒšÂ|D­ãKé„ùÑ^òF:$À?ó OÃÒûÓÍËp¡u)€70 V.€‰ALj«/(™Dÿ‰ðä T ½äþ‡É`a/Íí†`οüü´¹%z£"«' ?²ÐÜ7~øï?Å«¯¬F~~¾ÚP)vç2áÌY³q@õ¨ˆ‹¬øù«[Ùv—Ýà%o{÷®xcõÔ?Na†GBjõTh¾\çûQUš¿ñ¿ÿÉí ¾÷Ëç6œiéZÜÖÖ#Ô‚žS%ËEQ;q"®¹ö:Lš2‘˜=”öH{®§–NA¦Go›VíT~—§úz}8xà ^_½êö •8)õO+jÊpóØ($ÔÜpŠýSj¸y)æxˆà§5IÈ4¬AI—à¼ëRÀ`R…™púó÷_’ó~?ë\D ™Ha,ݲÚ©Ãq®˜ÒÀêAIÚég~ÿûÈ›JF—0…ÜK #7àÁÃþ/<÷‚4ÿ8xÖ…I F×Öâêë®Ç”Ó„{Öp]Ë®äg +”-@É’{¼²³:¼ñÊ«dw¤Ç›jnÍD8ò)Ôúôy6þßÿþùí6$ mqo¨‘–“èi8*ùÅH4‚y âZ:¡òÊré @öÅ0TâÂFF³¨¢õ/mÕ~ÛÞÝŠ5/¿‚Ó§N )‚3Ÿ~BÊOŒ.Çõ£Êôº—™'<ù‡b&fþ10ÙÒn)þZ‚I¦þ±3~^û¹õ_¿‹È–Í—äܺú¡E¾) ž¡p•Ú„ÉÐE=8ÑÐ)ÿômΘ ‡Û#_0cÖOÀê×à©'žÂÉúSð¸ÜÆ'É#.,*ÆÊnÀ’åËD2ÜLWÚÐ'ÛŸaÿÙ`¤Cö¸Ï­!cëæÍðÒæÊ³`ùäTTCsyPSšÿÖ?ÿ·û®RðO¬í'–sÒ­ãô!tŸ9&3ô“_ÿ‰å„8‰gˆðF+*+íׇ” )–ž45'Ás_Yõ"^|þ$bIHÓ¾¡£Œb¥OÔVથÈõ{'ÃfÙ1¬òCèÇê?­Vï?b4 KSèãçþóŽÀk0Û˜‡"1èB° ‡A €Ïé›üo¢`ú,8óóà äŠp ß¼Ÿ ;·ïÆï~”Bâ-ðûs”æ@JIƒßtë­¸åöÛÐ%]¹¦ý¥t dƒé©AZzcæ4 ç xvÁ«/¿Œ—Èîr‚A‰YòJk?¢ ‡“G•þú}+¾©uu†'þÇ#/ý~߱ƎDšîAgóièB¸÷þOã†[n °RÿU/h@:Êök/Piÿ™RûÌÏÍÅoó0žöyú>)fú¤tL,*À㪰°¦”\/=® ˆw“ãŸP7@›jF2­÷\€‹­K ƒ0=¸á/þì’û@Vv ?0Õ?JÆ"ï¸'nZS„âRªÿù/!úlø*+á),!6Dž†uòäi<ô‹ñⳫK¤ìàtìNºçÙøïÿÜg….,6¦ÛŠ[fzØhöyȹI¯‚iUT"ð¥^À£?‚Ü‚ùóÜ¢2”ÔN¼ù˜P]‚/ßµ¼Y;^ßòÆCϬ]xèT³/ÖÙˆSû¶£7ÔÝp¢»£ŸÿÓ/á&A£Nô­Gö­MfÒ™¤„¸$2êÇÀc<‚5¯¾†ü‚<™”LX:¢·M‹éÅÂ4ä±' E»»¤Àìee"£O¡ñ2\x]JàÝŸ½€ÁZœ:ýV1.«Äe»âi ÃîN$) 0ÔH.3)-Â5·Ü†¢Ùs‘W;ÞÒ ©lñâ€Î®.üâG?Ç#¿þ- Ón}gW'®Yy-î#àÄ¡aX’död¬~ ?[BÌ(bZ6X—KîsøÕ/~B€yíÞœ j¦Î†¿ £ËŠðé[CÛ²ë`â™×¶9Nµuk½Mõ8¶}zzºDn˜kîŸûÒ±â†ë-ÈrõÓT3"¦ªïIÑ‚%[OÆÏÊ>Ü*ùøo‡µo¼‰ÜÜ€5o-…OÐîß¼˜T^J¡ADØ}’X ã×"Q€NÄÛÛ¡…c’LÔúi|Ü@`¸¯*º‘«Ihh‘‚Ô®j™^û¾ã9lÒ rÝ;)ò’ÒÞŽ@ eW_â9sQ0e|U5JÙš †ìÂçsâßÿ1¾÷ÏßC9Ç媎‡P(„ÅË–   °@Â[‡À¡YC„Ó'’ ÂíÒ¼aå ‚¹xýµ5øÍC¿†É¹;·Ï‡Ú¹‹‘_> ey9¸áŠiÐ^^·Ã|}Ó´†¢h;¼{×½N.LLê•~ŠËïÿÒpåŠkâžü챺6¶+’IHhÖ€þæ&Ÿª?…'÷8¶lÚLñˆŸvsM2§÷ϨÅç—ÍØÒ"b÷1ÞF"@$,ôßd;y#‘Ô„våêôÿ >.k8À`’‚ºžø½‰eZ$—³5&Õ¤ eì´û3$h÷çÄ sŠçÏ'˜ƒ¢9 9Š¼Þ˜h²/[”ãÆÏ~þ[ü¯ÿñ¿ æ+µ`æÆç3kÎlÜyïݨ; öt‹TgØfgÝ÷º½év÷¼òtä‚X¿vy¿AWG§kìNYv-Êj§ (àÆÒ¹ã =½æ]sý¶:tG’8¶m ÞYý4<LrÑË*Ëqÿ—¿€%W,COw(3ñY@VFRÁ˜™UÔd&Ú»›¶âé'žÄ¾º:øü~8 MCãsÅ\|~ù\”dï½0N8Ø{ ÝáNj1jnªúïùf»ç5œ`0Ï«\ 2+‹å–¡Ák Låöw“½p% j$eŠP‚~§`Ây(¥=8¦ òlUi(ò»ð뇟Äßþõ·‰$Dd‡Ù€¬ŸdéçÌ›ko¼5£GIðBK¤Ã5•ÄËÎ ¯×‡'{›Ö¯GŒb{]Ä) 7öÀ×উ#ŽÇd¤²t-qf•€p˜Â£+D9•ž›Þÿù8­á œäDà`­¡çVçQ¹žÌ@'y©]´‰rïWÐ¥»½ä,ƨ»îFþôÉHE’*¡HÇ ø<ØûÞü쇿ÀÓO>/ô]QÈ¢c±TøâeKp@49€³ÊávYV‰Ðï!8~«_~;ÞÝ&¹¸$y£gÍèYsQ\X€ªÂk–_sjFÔ+»àEÊ@F!æ7¶ê™ç°õMäE„%1,øÕÍËqý˜ BθtQ©ÖFº ÿ§Xú«»G}Ym˜Šo ÉPDf\\†l8­á ¼jþðÌ k(5{€ˆ²÷> BMÍ,_¸c>u fM'ˆ§—ã÷à½uøùO~‰WV½Jž²GÂnÀc1On fBP$KS€Ó!0â,{°„ÐÀìÂæ†F¬[»›7m‚D,Šê©³P3uŠ QSZLð«UæÉ†´¶¶áÌ=hØÿœ„¬HÂåˆ9óçI{a"‘¸è…Ò³&ñªÄ©—Ë…Ÿ{»vl"„ƒ'¡ÒóôƸf®U†nfHñl@»¡1–:0Ï4zÈ0“}ÝšÖrο> øø–Ïd{]‰$º)ˆ¤R’H0×%GÙ¢%{ÿgP4k&ýµÿ’ŒÜ‹#‡âá‡~‹'{~_Žº÷9¤ˆqþm2>õÙÏ J¯f%ö ÕOdMËè{>ª)XýoÆlwÚD·¿û.Þ\óœ.…ÖQÔLžŽªIS‘ÈEQ0ÚßþÛïÌöPz{zÐx¨ ëàt»%)·üê«0eú4á§ Q&å?:)%Þ¤“$ææÉ§phÿa@Ùd†.”Ÿ,™‚kF” Kz€”ˆz{``Ðy@Ü&GVà£.>—*?Nk¸À`–‡¨xè7þ®ÄÉH¤I$tòJ,ÂØOßâ³ÉËæÇŽ„‹ì‚z>õ‡çðóŸ=N ]äï¥p¼vÂ8Ü{ÿýˆÓF™€ƒŒ¡§ú“â¬6}CWß³ËÏÝ„uïíÁ[¯¯!p˳ò±“Q1a*<fx؆þìï~j&ùMÐÉ5Ùæã‡DZ˜w|öÆOš(ÝEÝ®TˆF "%p+â³ÇŽ¥q_ÈÈy×ÿÏùcqeU: \|‡LKáö£·[¡0]^µÑgÕa/ÀÅ×e¼eZ-ÀúE “¼€hÊPÀ ÂhÅ `ô=ŸFñtöÂêO5¥‘ÑêÅ /¼‚ŸüøŠû°³ú‘H£ÇÁ­wÞ.I@»öoåýÓ¶e×åmH#„lºäíí;€wÖ¯—ÉALʯ‰ÒÚÉðsÉ#Cûüßþ—éÐ݈„ºÐzâ º›NÃÉèA¿÷­›¬éì@ûÉ£ˆv´XÞILŸ9 £jG“»b+ºÀ’„„¦˜Ó/‹þÆéq‘ ò¦´'²7 . .×L¿3¥‹KsÑc8±Ô›Ò)Cdø}@‘‹l b†õqZ— ³†ØÀysôI©±àI3©`î\Tßqr§N§-bm\yôÐý½fÍ[øí#OÀKÞ±iªFî䫨©¦üJ ÅuËÀe×OYªÜšÚp ˜iª°f±p8ÙΆŽ9Š÷vý¬Q˜_=ú7™J°ðSSXBíè:s±î68uvÄ”©ÓP5¢z@í¦pòO—˜Ä„‹âþoo@cC£R&1•ëÎ"Šÿ41‹ üèI¦q3ÈH²Û±â®èv¢CO¿ÒY¢èƒu2k¨{ ºcäðÌ@ÉõkDP0{*o¿ Á)Ó„â®AÉŠ»z{"xóÍxüñgÈSöZd7ž†—@YE,Y$T`‡Å¬M[ WÊL é©”•'°àdýIìÛ['!·Ôûr [9žÜ"r&R 8öŽww¢·ñ4b¡8ȉÆM/“K9£x1Hw)[´EÍ"í0òlß¶ ÍMÍ’ø°uÕÂt¢7&€ùù„ÈèÙE±}6zIFzéߨ¥+d7õ—Í.Ϙ}žÓ¡¥C£þk(r.@fõ«V8óò³iÿçÿUW_V2Ͳ53?ól¿”D¢––fMñå’vœbþÎ(}YU€¸ˆš²ãçÍš‹Ò[îD€¯‹(üÈ Ë80€õë·à™gž‡‡gX¯$£/(,ÂÔéÓ$TvÕsÃݵvû½Ý„—MÌÊe/¾©á <,,[&ÙyƒyÈ)­;X@à•Ì@²§±–Äz: ‰» ¡fd5JKKɈݪ_ù‚ËÒ§wšöz‡ûêö¢­µ]< MÄ SíÆœ !¡F'çpføÍ¼ëSäþ€ˆ’!345XA: ­B·î„s€jBZ@ä\þP[— ³Î» vû©™u÷÷gÅdRe¦u=ë>š5û‚oβó9¨öt]4,â´³¶‹”‰A" ÆJ˜9…7Ýœ‰SaR<¯Æèi’g‹Ðó›7mË/¾"„9[Ù'I ’K†:jÌ(éë—hÚš ##b¿SÛèMdlÿahmnÁÉãÇÉ‹fª±wNÞ¢r¸¹ê\l0z{èhB2Ò­jò´———"¿°ðÀ±#GDÝÄávÊs‡ µºº n ›ÏuŸjòæõMèõííh>ÓÓéP99_.Šÿ5®:ðûøã$w;Eñ¿ «öÔ¢âsƒRS4Œ _RfëivIBæúñ£º„œ S<¯¹–¢¯A ákÁ$fð 8T?XžhD­ …†®‹8BÒÝBnÝ´K¤ý&d$ aoç½€Ôêל1° ç¢+—Œ?ïžA€;oœ“z«ôÛÿ¦_¹EW²èòíÀªCINVÓ}Ç 3{ÀMºËÎþ\Ɉ´ž°ÈÒŒœ¿ àT³)ↀÎXJª¬”b/€ ƒ{Òt䬸 î±¥­Ý~®´±°ßlÙô.\äeÛ®+Ͼàœ@aaá9U°²UÎMSÎ\Ÿ0m¦¡î*3ÉΓääÑ¿~±qí ßú©¼-ƒ#‚#•x›/:—&™týlÍÿ³×¹B]þ¶§»GˆE™“$£§ ð§zÓq„9þgÿŸPQhŽ˜<ã&V²Ox7`Tôº3Ì [¢([§”Çé€6È~>8²—Úë%DõÓ÷5°DËŒhb$Õ­ÐÅN7Ù!Jÿů¸¹W]?(çÙðÝoef8ò&ª0rr hùz÷qV½êf`4Ïq³o<3‘”¾þÒ/þÜ£ÆÊù7þçÿ!/0’>7EŒ6=™ i‡?ûüújV^xñ´ö:è–»Ÿ¶Pàa4ì‰v…•2U[²C…LçnÖîHÅÅ+0U=ž‰Óá½ê8ÇNŸí–Nav"ÇáCG°}Û ” ßGlw@@µlÞ¿qìÿñ@ž°ÌÛPy‹”Û¤ŸÀá±C€+¥q# w¢.MnÝé÷ÿYêBª“ãX„ÝÍ>1zƒa͉?1Û0E‹8$K™¢pk›I;°<3ø “+¨çä¢èVyÐÌꓤÕÉzè¶Öà]ÊoƒévÃ&7&Ÿ *£QÐçcÈ>ÀE_"¸ð*]ýÁϕ֙ü#Ò.­š>™Q=oþ£_ì¼+ë÷ ;9ÝýExªGøÌþOŸŸíR—‰ì›_U…²÷ûì]òâoðɒۖÝY ü|rÿɸµžR'[e`­ªHë¢þÛB¹ÿ세x¼¡1€¹'΀çÊë¡ S ãp¥íØ±ãØ»k7ÝB.±áÑÈ­æ”êÛ] 2aˆHƒ=múÚ7þåA³»7!C r †L/á:'»|’†a(Ì= }5,NÀMAiÆ/JwgçqLˆw!Áî'šÚe#q˜±ˆ€«ãIüB®kA.Å‚E0ss q £Ÿð1mirݪ V¬ßïfìÅÆÏ^À`¬>p‰Våû§A9NìÔq´=ùÐyží÷Yj™P ûÙg.Îþýþ9#;åËS~S'š µtʽÇ÷%ù2¸îÓ®˜ //ˆÜ¼…âzZcZ†Ìë¬)/`I°'ÌúÆ.ô†“(8PଦS.@wwÚÛ: ¢éZéùK’Û´CÙ'§£¬´yùA)¹V 5Fß/Œ”ºÜLD!€VQ$]Oƒ–Ý"k8@áÍŸ‚·vâ>N¢¥-þô’žû@—Ak9´’ÀM@t¿óP÷Ä•,xRî}CB†hy5RÕc‘5 É¢F©&pA\ª fF%6×,¾óX¤©©ÍÍÍç ìÕgV`ÏØî’ÒÌ—Ë!€ÏåÀÆ޶v£´0ˆ)£k =»æ]óííûqât+Æ–çcêˆB$’JÒƒ'NÔ£ÕjäQ/˜=’X¥Þ2îˆÝ®›ÊŠQ4䣪ºBÆ‚±è¡ðúéÕœ8€Ê“G‘ÓÓ _8·S%>8a·1ÊÛ"ÐkJ`V Ê wˆ¬á e_ük8ró?ðqzw¼ƒ®µ¯\ÒsÈâZ?sùS‡O³.Éê3@ÝÓm½œ»’ÝZ‰ØFÉøãUc¨dA‘5áÚ”€‚ÿË÷¼Ç*k¦-ˆ‰s¡œ>݈¶¶6EÙÐÎÙžf±9<áŽÂââŒ9BðL(r;tì=Õà ¨*+À¼©c ½²v‡ùúæ=8vº µôà”Q…p9±…“ÌTjhh„ÛíîóBfZ!»AW%+`¥Vè|=jŠÉqQ®ÍÓS¥' ôè>ä¶7S|bWà‘DŸ°øøBÅ`t¤sàøgÕã?k¸>À`¬öCôÈþýœßOÀ‹‡ÓHyúèh!¤Èƒ²¡‘GˆßBáj8©šñ™8Ä1~oítÄ+G"^R‰d _BÕ*ï”~\Ÿ†\¯ )öH+>wÎ;v¡P÷YU€³ÞGv>ÎfššØYyy1jÇÕŠâ°$Äé5wŸhÅ‘†.Œ Í~Éì±Ð¶ì<˜xêµÍŽÃ'[´±•%˜:ªŸEK¤c×ÕíGý‰SðxÜÖ\CGZ¦Ø:…ô¿i°š2LKʇ½‡ñãÇ¢º¦B¸&ƒ.·ù4JöíBÞ™cp³×àpÂðz¥$(Á»H‘˜”\„ôãqB/¥ÝŸÞ˜é÷Ÿàã´†+ fðR÷û)Ò}¦{÷xÐÕƒ$…·qòZx€¦bqö|»¦,@¬¼‰Ü"$ý¹ÂÈäÒ nªdxQÐ…â\/…ªêÆÉ—Û!»ÿ¡CG/*ÅÍ&j[ŒFX¸¦855•˜õú½‡OùÆW—aúØ ¼3°‚Ï®]{pøàŠß½ª¶ XÜvXhg×ÿS–H AÚ ~ÊÔI3fât¡8ÕÁ.”‡\ÿÂ=ï¢ààn8)bî¾áóKch§ÑÅ5ɵÒèK8øtqÅ„¤E0‚9p¤.ÀùÖ¥6~ºxçgàR¬K‰ˆK­¤ê¹§Za„z‘ Ç# ON •6©˜ÌÆà?Rý ­³®B¸´)º§S¿ÚÄ,ú²ƒ¼Üò?Jós¤w@ä¾éqσ£Çê±{÷~I†C»@g#7øØB³KÞÜþ‰`ÜØ1˜1kº5^Ì@yÓ;5à0½‡Ic*qÿM‹È›é OüÁ#/ü~Ǿ3FV”`&ÀÈÒá3³vùŽ{°ÿÀ!á%k}ZŸïùd ‹?ÝSÆÉX4"'2eòx:±¨dP ºB¤ü›¿k31¦Ç+mÃ,Ê”aƒùÓ ì>ÑóŽ¼ @a€Q„#9<Ê{]ØÄD º˜üÃ$ K±ìÌþÅ–ô ‘³ÛÞ̦v¤zˆӭǕèXJÕÿÛé^Nª×J‰è83ÿ„‹*$±m8݃OmŠ>¯#Jó r$Ä¥¿b‚ÎÞý‡±cû{äº+‚œœÇyH?v_ŠMb^5N¾'ã˜8qfΘ.öÇ'vª¥ ï>ƒcgÚ0el%¾tDzf± ¯ûµí=ËKŠò0kl¦Œª”ØÆE.÷Þºƒò•J%¬É?ý/›•P­ȪI¨“äl(Àd2þ©S'K~AÉ,«7³m#‚[Þ†“Ë!Í6ô¦é‹;´ú€hø}ŠPI¡ÀÅg• «5`°@çäÿˆKeÏ/îAšºòD™þkö’!µv!EaiŒþ–§qÐK ”Š‹B°–'Ž-ºáÂrÕQ åmÅóO•–äú1®º%ÉTR6O‡å@ïÚsï½·~Ÿ'›ÿ›uVýKÙm°º5DÇäIhÓ€…:…×u'šðÞ¡S¨olÃŒ U‡¿vß5ß”#|õÛ¿ÚŽ%»f¯Æ‚ÉãD•ÄIpøÈ rGö¡‹ÙJVr°/Xi§<7ðˆãÑ£ª1uÚdæÉ•Á!.7Ü[×óá 8»BðÒ1 f+¸=ªÉ‡/·Gcb°×`r% ²®‘å2Âüã´†# –û©Øöz_ÀLئ6W§uôX%ÁõˆhšÒ Øk&Ò}Ц¸æn\| z Ë ³ú.´´àP4™ÄتRL¦67è“’ïÿÜX¢×ØIÆðàQòÀ=™&¥,cÏ&ÙÙÙÀÕ1®äç1uÊ$ÔÖŽD*’MuDZë`=ºè5FW—¼õÿý·O]%Gýîƒ/l8}¦}1 L_‰—ÌVàvãÔ©ìܵ§OŸËéR/Ô§g7gg²þé%úœ‘Œ¡¢² 3fNCUu9’.~Üó]˜o½†TC# 8ÇíMO b°pØÀ*¬ôÚN U\ä©ÉúGrŽí†ànÀnéÿzPÜÿ¦ÿ©îÎýœíuö ó½IMU£N5Áà‰Õ=ÂÒÆÃmÀ=tsæŸÅ@"ФXxÌxuùqpÞõèÉ-„žŒ«¹©üä0Ê‚ic1­¶ZimªaÅI\#…vŸ¨?E!€;}çnsΨ¥{€˜ DPUEö6c ª«*¢óävã—6¼‡ÝGN A(/ØøÝoÜ»DŽð³Ç_ÛpäDÓâã§Ú0™ ë³7/B"¥tþ;Ú;°sÇ^8pnKÓOjðÂÃ'£dÑ Ñ<{rT¬?Î\€Y3g[2Ýæö>ˆî·ßFÏ¡ý¨‰¶ƒ_ÁÀ¥Ê…\5塊¦†d&ÊŠà˜2‚✤¸6F:©>XÇ0u † Öù^ŠæŸ³—bÞÙÍbro¥|b ^‹$¥þ¯ó¬J2ø87ÑÆ"C‹ßßÁ•­”*ñº IO.º Q?~¢9¹ä$å~·Ž^òn^>ÓÆÕžÄ¬™~Ü.ò¸ÉEß¹cš›[ÒÜ›ó/«ëÐ>W‹wÃì˜Ñ#0sö4”–•H>Àãðâ×/®Cݱ“¨,.@UIáÆ¿ùò­ žzuˆûŽ-Þ{ð$&Ž!¸u©(»Y·,Åöm»±mÛ{ä’¸Õ‹òœ>æ3qížLÖh`]µ¬ ¨ª,‘ä$C5k:-Co:JFªzëgêѶqÚvlǘÎ&¸t5#@úøy’0}9â)f6Ðñè{­(Ž Õ"]¦9ÜJ©Õú ÏêòºÜ ø¡¬ÁÚý9öo¦Ýÿæþžóµ5œlÏÀ´dÃ9ö76@ …$/£»7¡˜1 B–°qOÕò壽¨'k¦"é н®6GÓ*[»Éý~ÙLLª­B8šTÀ 'áõx°íÝ=ر}·(3'à¢+=LÜÓÈÎ"‘0¦M›„9sf  Ààò$ÙÕ¯ž^ƒ½‡ObJm ¦Ž¹ñS7-V°sÿ‰}¯®ß1qý¶ո禅(,("p’ÛïĦÍÛðÚê7Ùm@ÆÍÏ"ûhH÷9g2a‚!ôÆé³§bå W#F¶Î G¬ØÓÜ€®mÛнm ÊìWªU,YÅ\ujÐãFØýÒ ráSIÏ@x=R`æ tpõ—Fº Cú\/uìo/[;FÃÙša¦‰5bX]÷×7ˆ,3긧¯'ž’/žØŠKx*‚et߆…h¨¨ESñ$ÉØÖ½©dâLTWãÚE31ª¦ QÞÐäÕy,xŽØÙöí»àáp{7®ÊeXãFHÒIxõ5W`þ¢Ù䘧D²,ÔÛ‹ß>ó:êŸÂ‚ã°|Þ¤ýKçLž$/ÑÒúËÇV½ýµÕoï?aL n^1ãFWÃE€ßç•Ýÿ¥—^…ÛéVî¿Uw̦0ž‹[rtê_%N8žÜÿko¸ >‘Õ¢SfïìBüð!D·m‚{íëj:îöH%‘4Å Ô,oB' rV—Àôº‘ ú¥oá2ô]&0ó¯äÓ_ùÀ»ÿGÉûÙ;;lÌ~‘؜ï=ºï´¶.$Ï´JüϽþQú QÜâiÀIÙH 08,4'ÚrKqlätJ‘KÕ¶n·«“ñaÉìÉ´Éæ!žHYó9‡àÄ+/½†=»÷"à¿ø˜u¥¬g¾7ù. ãÆ›¯ÃìyÓî S`àÈÉF¼ðê&ì?zWÌ›xðæ«gÿp˜?Ûˆ%“Úožzó7/¼¹í3#«Ë°lÞd,™5N’nú™ôÖ[ÐÕVóÿ,¡ÂóëßÙMCzºIÉܰhé|ÔT—‹»Â‚F®”ÙÞ‚ø»ï üøïÅÿr’ûÏ“S¤3¥’tÕÄ*¦LPÒ½.h, –GîMaPå Ò|ʾĉË0ø‹ßURþÃÆÏ ðQ,žè£›ÆY`köÉæÅU/Nüi†ÑÞ#º€<øSÒý§È?JD1üS’6çWàà¨éˆ¸ÂzU*9†è¸î³·_iF‹îïÐÊ7ÐÔÜ… ëÞÁ‰ãõ™9XZz6Ó¬x“âb¯××.§ wœ„‰xwÆú-u8y¦W/šôÈ×Îû\UEYÆoÿùãk~´~Û¾¿bÎÿ¤±5¸ëšYð{U2®±©Yò'Ž7¨jß9ˆ@ýW¶`R’f iS'`Úô gÙTCH±¢ÛßEËÃߌÁëP“N%sÊzºjâø+-n™ãƒ^V³,Wy ©¬àDË$\†‹ñówÅõÈ™µè‡~¸ñç£Z6sE¹æÊêu‹X›Î#1/¥£©ÃõÐȈX¨†õ29‰×F!­Ýþk˜*Æçø?êõ£9¯j¦ÑÏ\5³Ü`ë5XõîÏﻣ*Ëã·õR|ïÞs{w@Wg·èY^lÙcòÌ4%X©fWV–`Þ¼¨ª*—f¥p4Šg^ߎ}‡N δQÿõõÏÞôU Ë>þÿ_½ø“ÖÎί'W§¼¸z×ry,¸ÉÔç^™b&'°âÈšJ,]:Oæ’)ú™y*H]Ÿ~ ¥-ðX˜Ì=ÓB⤠ÕF,ñ™=(¢¢Zy…®L gö—‰>k¨À`qþ?š¬ß•QθϺmDÖ®*d´–.$ö—ŸEäÃàò_­ä t3˜*~go"îö“Û_€¶¼+§rS6OŸžwн^RT€O^·%…¹dŒ‰ô¼Aöb×­ß‚úúåå꿃5[!ÝÊÚJ@ãÇ×bÒÄÑÈ'™í0‰âÁ§Ö¡¡µ •ÅyÈÏõýôÿÅ'ÿBŽaì™5›r¸¾é+[vB~NŸ¿}ŠórXÔ‹N4‰S'È Ø«”vµ¾õÈ €iñdV]¸¢Â<,_6_æ—ëê%ΊÕ×£mÝ[(=R'}\䱈.Ö ´ß : ê/àó()€£4fÐ ƒµ õ¼#k2Ìp‚¡ ƒeüü¼tK•ÎújFÙî¿z"¡à@½Lãeš-7¦w‘ñwpû/RJœKÕF!_Zh÷ïÊÍGcao_J—«>·“'ÖbÁ´1È øÅ+ñ±ëÖnDK[çÀåÀ­ÍvµÂTS…fÍš†‘#Êávq¾N§·Ð…Gž{ÎL[å?ýÜ]+úÀžÃ'ØúÞ‘/=ÿú6æqÝâ©QU ·SábKk¶nÝ#±¹êvR|çþÞÿù@r'§N‡‚Â|ñä·9~ïìBôPòÞXGo* ;JQ$9$HÙC+éxfA~:˃¤¢`ÏPà2NZørà-Nôå’Û?l?Ž÷Ùø?Š’_ÿewf—ÿìÙ¢ÿÇî9ËÒÑ®™\¨ öí?†˜Œ8¶IøJè⪥*là7ÌãŽËK P3¢ZÆ…sV_¼&Kt¶"ðèpvu@ã‰Dà˜‰€@ÀÉ2Gš•7`çÁ9^˜ñ’2Óàp€ÁRÕá5À<ÿü•·ŠÐ»ýÝ÷ãç%š€)•éï_Á樔ÇÒ¡̶.í"ãÅ®y˜Œª• ‹BõÌXw*ަ¢j¯œ€°Ï'8`U§R—ÑQšŸk—Í‚‡‡íÂJ>ò1ÈHOŸi™ÆV$¹D®k€6°»ÖžÛ¡Y6Æ65yÊxäýrün.ýí>~]aÜsÝ,›=þ{U•¥ßRg-2Âåk·îûûŸ=öê ¿ß¢@ gÔ¢0/(n747µ¡µ½]5GhöËÚYÓ‹cRn—Åì£Ç&…ví¤•ˆá;äúû{Þæ3pijçgãws iVÿ³5‰‰Hì*åŒ,ƒÎÒÇÜN'˜W€ÊÊ2²1·ä0Z»zðîÞchêì¦Í;‰ûo^ºæÊ¹“¾ãøÖý6Ç77í½ï…·¶>ÚÚ¢ØÛ‰+fM@Yqâɤ(¢ô’ ÑÜÚJïמʪ eÍ<ˆt¸iÍö«5^S1i%èÓÐüt£x@ †[vBW™àjZ¹‡å¾¥ä{ÍO{d¹„LŠ0¬¹Žadø¼SV›×û.é¹J*à®IȤAáöóâݾóÕg.‰ÂÏ»l‚Žfõä«¡²ô}{8Õ†ÙB\&þj"þ&W¾-C/}ï€rÕäwåàTÉ(´”!áôÈ|H¾C9ÈM&’ÈËÍ%zŠŠòÔœC‹ÆË·k,žÀ™úÓ²ÑêšaÿÀlÉVë–; × KJ‘K!<“鸜ÞL¶a÷aÄc ò|¸fÑ”OßtÕ¼ßÙÇèó*¿_µéÏÚºC?{ggˆ,˜Z‹Šâ|…VœåŒ&dˆ·/ª¡8oÖÿüg­æ¦óóà#/Ãåp*ÅcïÁ»g;‚mð1ÀXcýP’Éü JËÔBW zE ´2 ÜnåreË” ƒ€ Ž0jëöˆ¬¶“¼Áò8Îõúlü—²Áçý¬>3¬°Ò´&I™,ÿE±?Èõ§M/J7QŒ6=ýŠkÂü‹q±Þ–\äœÉ¯Â©²‘è æ!©«¹{Ì ` à©[¥ÅŘ9}ªè\VÂ\òZäQ°2pW{—5+»µ÷«O9žéöä—ÀÃå{«õ°‘B˜Í»ÈìÍ9ÓjŸëýóÏÞzíÏÓï=û€;ëN|­¾¡í¿²‘v^c«JPSVÛ)'Ç1|OG§484ÅC”{_»­â+{¸˜@w¸Tû$£nÜD°±ùû6"xæ\Lüar<2͌ƥ˜\Fd<à¢Å…0+ `äøàL*pH6Yih›?ïü¹WÜ0¨ÆÿQ.6ø®µ/é]Ÿ—mr²ñó¿zúÍïø<”äady!rÉͯŸ‡!ŠŽyDéšê"h¬Ps@ÓXMað²ÚXl/OG7sêL;Œ&úê Ë€ÞýC)ÑTRÔ˜ÿÏCe^Ý‹.z¼nôtœ*®¦û:%’áÊ0 Ù4ýþª«*QRV,“„4ÑÕ´F²”X¤W fO›ÐÀîZ¶—Ê£i.Ú}>ù™«gÝ‘N4t …˜X,‰Oß´àïGWÿzÚÄq§ÎûJ¯oÜ3ó‰W7ïˆs›"¹Þ£*ŠP’áBÛFBÜo~£¦=‡ï}€ôra•<žS®²©¬¤êD’Ü˜Šƒ»<²þÎVä*¿À]‚2 ª2 zéL¯äïäþŒ$U&³Ú˜ Å€Ýý‹á³«©Û9| ßZ†f3Gm¢Ž‚NÚ%Ž7!ÕÒ =—û)Dß•àÆŸz)òñ“äwœ†çÔ6œ@uo·d35ÚñšS4ל¬©®éé®NÙQ’O@1 /…~_†Ó}}q=?LF=²oÈÆø[IN*›}¸z0xšoW‰Óm0º{Á» t¦R¢ú“ çyúoÒö,éÞg—¿5Pˆú¢jôÐîË­¿V¶Jy¨t·–VÔ ¸¬œ 1‘.Q3‹iÁ'…°ªZºêI³”.²4Íò]¬{OŠAEWãÌéX-! :áu»1c|&Œ)[¼rÙÜ>üë³^å­Í»g%Sƪ?¼¼¥¼;ÖKò(¦/“ QGžÏ ¿S•å2;ÿ@pªË­Y3Ð;y>]hÎôsØÃñ“'ÑowÊë`ô™CÐ9«ÊoJ'äriWÙ¥]&ë¦èEù@AFAœRjš Aà Øàã§ŽÉn§¯¡RËÿ K’ΊZ÷ÓÍy"µ~¼©Ž$ÃQÉ#Eé&j#ÃíŽ&$ù²©ýì³Òßôzsp‚Œ¿-X€{©6AŽ_ƒ~ß,D^i%|þ —ËÄÐÕ“´+»œ"Áﴨ¦%‡Ïv6°=ÕPy0zѸA¶¾ ·&3ë¶­;Bî/‡ðÆ+g6(Ü´béœ>®ÚY¶±³îH 7¿ów«Öý¨³' ªüøÝjâ!\®×- XÂ(“¬bY®×E¹®|w$F'ž7Ë£àÿ¹âaT׿‡qwKïM3°—AÀípˆÇÀɧåjq| rD0Ô( ª.Â!ª 4Ô€wñ¤µ“'[ÄÀÙèùñª[ïý.Éúè»OSñµ*ë©j?®[É7Ó¢çÂ*K 3^Ùè÷Ö‹ègŠ H’<õ'§ !mfõÀ'n„’Ĺö”(ƶ57“= æÓèê[‰xº]ñXÈñæ2`‘p@yÒ![Qê3Ò•3ùš7Лõ§;þxùåÊpm0P®HÖªX•Xß²TÕa<[Àd6'IÍζÔäï»es,ݶeýœãY³ýýçö·ÌJ#Ͼt2><žEw[½í-Û($)…x-ñmVC4«|9l€;_¸ªæÉ7'[¢k¶ 5TŠü ¦Ñqñ$6ŸÝ/\kœ;a2QQ–BªÒ £þå~€t læ pÀaCG1µ¸——üñhŸô%Ýh­ðÖzm‹nà+‹éÜ”¿Vî˜ÖY¸†PqÛ2óÏ™ÍÃ"׿:4Ž*ÏÅ$ÃÄÈ¿œV,†5æàü s.ÅÙÖÂId£qÔUŸ¼.ï‘5§¿íìZ„Ö®ÅFââ=()áP·ŠT"†)€! Ñ<‚b… ¯¡Iw.•+ó7äWPxRÅd¡"Õ2Ö1žI0™ÅØt]ßzÓòb:ëùлdÛ.·—;÷K%c‘Gÿþ;»¶é võïhK"Ác»\Õ»ÓBÖ¿5”rƒ‹…+WØVl@÷P‹»RU  Þp½Á"ŒôãššÁæ‹kЮSX¼‡ ì€+1O€[-ÂɰAR)rÇ–vÃ'Ô gx¥«ruÍìjêv«ÙEüʰ o­7âræ)sWw­àWæ\ê)=ü;r•±)ŠýgQ+–¤âÅ®?Í6È6ª"hácãb"J®G ¡„¼¯k²Î’‘'Ï4ÅÒOµ)%D„£×aº’V:£qžƒé4.qÙ÷pX£§ÿÀºDpèâÔ]dIø³¤¤„EKÚ+ûç0Iñÿª¾öúǼeo¾Xy×ýwÝ–›¿g—UgÎõ‡#¡àÿþ»»þøÈ©ÁŒÖkM'°¸#-¬\¹/`îï\Å"¬³µüayAžn@‡08¶íÇŒª‘\=‡v"6Þ(il!W‚ÏtߎÎ|é× ÒßOdp„¾øÔ4$hWºQWÃtº—,ÇŠµ›Ùêê‘àâÈÓ›ÇC!iÕ ]M§¯òjb ç$¦,¹>õlͺ­óf*Ζ­q ‹$3!mP¹pq<‡iòf¶¬_\»ëÖ5_ºÿö›?órûvÅs_.ןü»o>uß÷žÙC TKK»ZdBU†ærN$šYKý²WôìhÖU«™¤cŽõ‰lAÃ%… T6ë#©£/Â:}í…Úƒ4x^€vû#ôÜ( |æõ¸6B¾Äòº2B†pXÜ>ÛÌQ×Z³®uËd_ßZoÔå¾üÇÊmfüçξ€z.*Y‰ýéÓ…*Š$q5‰§]oî^…þÍ‘ Bç¬0jP%Aå¬Û¾æ±bÍl¿ãn´d:D!˜Jç›ßÆÖ?¢€¿Z–%4à+ X%æ|6õd/9HÃóƳyò\³õŸ pàü0Åÿôï;6bãš¾¯Ü¿cË'¯¼¯WYƒCSÿÓ®C§ýkß{~#+ŽGXE®uK,F1+Š  ß»!Žsu~S œC,j`ôw“tS Å dJˆÄöu™AlÐmØûÒ‡÷`Qˆç©…EééÎGèõ"œ°U 8hb&òVlòlîhKÒ÷Y{V±Ø[À{)ËcéŒK¹J@˜}u=ÝñjÚ»¶•gíò€™|È•Q¦«2 O•. ÝWQoòR2rÄPŒ5,Œ»!tƒ¥ hzzF¦2»/÷àßz×½¸yÛíd•+ê4sKºTº,áÂd÷ŽìúAˆk>˜CÕ5—L´rä)ç+U8uG85òÕ*Î^ÁL‰Œ'y1?þÐíGïܶêÏzºº¾t¥]]Щâ…CŸ}|çÁ?¿02%eŒõ«¡;ÓB{£zì +€ƒp0¨¡—W§k"³šŽ«â÷R½*1L¹ÔЃHªëžVº8€ÄþX>t’bû„„FpÀá{a¨R"»÷6)«=‹—Ã|ëúµŒåoXoyoø¥c}Gw‡¾ÜPO{^h`2ÿL;•Eut Eç+Ït\5Îøsé•A]sO*0{‘ãæ>OÂŒ¼…™º%!ˆØé@Cú` dy?ðááö»îB<™”Ü•«[ÖYcd[“ Äb!¨ˆ`®ZáxÞïMeM}nËcùáYG’s,ÀÈÄ,Ž÷’'R¥°¼Ž½cÛÿµ¬¯ý?ݾucÿÕötA  xÒšÎæzz÷áïí;råz ëI¬îë’Ò[]$§!“H’ñˆ¶ê®Ö¢&º_8Ó©jÔ¢›R %-‰‚ YUQN0‚`1 œ:†â¾=HŒ •\,8ÊÙU&1 Ø %à›)ÀxÁNw¥nnI’·…Ó¸Ìe™‡m<І·4À YM¯’š›±i²újR K'ý4ï>+äKÂòScÀO™bôF,¿‹\¥&%¿ “whN>Kñóˆp²PÅ·&Š‚ (;ÜaªP…åZI ݺ ›ñÑ}‹¡QS³=åÖÑ–J¡%SPa¨k_ا5ÏÕ=‚–ð’Knl‚¼cIuÚJ¶Î]Ã±ó£¤ "X³¬ÛÖ-{O2ýþÝ·ßtÕÓº`¿÷ØÙá•cS3ßúÇo=½!›/Ú3i¬]Ú…%$L•ZC4-Ç:mé…Aa8U]Xzjæ-_H§³¥ý¯*Åe³¹2²Å"YpGx«&)äÐ8~ #O>†%õ"Úh“ÙÕ”û!¯AzlÕ2l[Ê ð`Qò\ìŽ6Xɸî§öššW>Ês£¥ýMDo­ë»”e×÷Æé•óeù<5G+™' „cš¯I8ÃS¨—*^§_–Î× YR.ù™{ÏOѹ™&Å0IÞçž™"ÍѲ–Ÿ;ý˜&¿^AO_>ùsŸÆšÍ7I"ΑöÆÓu‘ˆ…ÑJ†& JsP³#vŸVW4 bë_âyœ+WäeøuG§s8=0 nÚ‹Å£?p˱֖øï½}ËÙ…ìë‚À‘³Ã-$ÔïÿÞÓ/ýדg†ã욯&p˚ŊÕŠ•„K™dŠãÄnR.k° Rí”êûZ¹Ž±™Ad (# &»ZÙ)œ{ìqtœ=Œn·†P$* A¶øìD­ „qÉ ÞŠ@*!UñѬ:ëËk+ãCb¾¥nÜò€@Pe5ÁoÀÀfU"×S¶‚š[Œã!Wä±ÖÏ >‘“ò^Y¬=DÈgIøëš;ÀÒ#ïùNÌ”±o2ƒÓEœÍ—hæhž œŽTüÀ{ñáŸø˜Âª04ÖœoWƒ~Òi)û™±]¼ÂQkXi©B!2Ôx:_¤°¸„ K_GÎ ãÌà¸ÈL_Wºøî{núù`È~øîm7Í^ý^!YΡÓíəܹo?¶gɹQkIO6¯]ŒnŠ©9¾©2"ÅÙm-qD)ö©¹:Ï/ZL¿á‚v@?×V“O"<ÃSZ…„²/8…U. ÿä£h:‹Î“……‰Q‚Ì[ ªêW_eä8ÅmAéLÀ"%`u¦UU@ó:&7kjÍ&ðÔFç­TáY†%‹CÊš™CfõÆösK-¬bMâ}ù’û_¥8žÁ<®ù“gÍÿªIÃ9J°¥#KûÒT»& ÈUtjÄ[yzýwÜ…O}ææ¹z݃ïr2‘èI’FȪ¼Q“/cÁ$Õºz!¬ÃôGårYŠóà s§ÇÆfrd˜/ââø wwà¾[× t¶·¬¸{ûæSá¼¢óLš&Nnþ_~ùO~ôðñx‚„|qonY½H ‰JæµUmMµ(ÔNš<ÀB€tAÂÒ¢¬˜šžE‰n#¯lù}uú}¼áâìó;Ü÷úòt§"û“ Äñ:#ÿÛÍiCòÜýÀ;0“›£µg¯$JafkkZ®Ñ+ã馽 `”™ž\Ä*„›{ò ߇=áý'Σxeº¦›Ö-+|ü½w£R­}fÍÊEÅ…îé+R§Ç­p0رsïÑïü`ï‰Û†ÇrèÌ´àÖKÑ‘Ž“æ QläÒò…›€L“¼q¯þ–M¾s. Z‚7¨V˜âˆ”ÝXYFäIÚ1ûƒ'PÚù )]œˆä‘bŒ  wZˆùÃþžB†@:!^€ÃPá`Hu)ú„ÝKüùKo­²äD0ÔC7‘*¤^³ÓÏÕêi‘À°Ë_'+é–j2ÒK¾jçï6$a'q½Å™%R ÜIWtp0_Å@¥iŠØÛ0Íb\âËd2øàG?‚w¼ëATjU‰í=L? 8WÁx2O,¾ôÚMkòÕ>§vïmWy'Œ+àd8Çþâ²·=S¨bçá3æF½[V~ó¾Û6ýBµVŸ °àCúª<ÚÁቧ¾þÈη?¹û(ÚS),íåÌãbDBA¡AæOÄÐFZÐV…E…ì.¬ t㮎©„AXU\gfóÈç+Òˆ¤ò<–‚Zô^¥c‡1þè÷Pí?‡Étu›0$eëå¤d2r,$Œ°äJ’íëB­=I߇­²¥Ú œ2gá´§o­×o܆(jèô—$Ê™jšâþ‰4F§Q'ãÀç¥àpÆŸ;üj(ñ™4Ciõï Ý ßÏå-'…1QcN[eÚ¹á§An8 ü»Þûn¼û=ïEG[EžbÐÉcGqýI&lijè¦6ãcA…dWc¤Ž®afzù2{¿L…G¡/ý§pvd%z¼;“xøÎ­ëþÝO¾ïîc¯t?_•pkî‡éÐç¿ùÄ‹7MMN&pÇM«Ñ•‰ Y'3û(Înoå¾ç všïêW¥ÀÆØ æš3¹¬ùfФÊ*d;ª“Šß£\Báø ÌìzîÙcè¦÷çP€o OJájo™„5PH~Í¿‹ñ”áìLBõD"ª7ÁÑ®”66„“o­»V“UÚözj\EÉ]¨ÀáŸÉiT(æ¯»Ž”©³×ËPí%ä÷T™›’þ«Øx¤h 8—mWÍ×k¸5IFßqÏ]xà½aÑ¢>ñ:-M8béN½xœ„?’°S•$]’´õàSSºòRJ‰3<”·Ž©©,jN•^&,A“S3øÁ¡SÒô“N†ÑÖýÏ_øµOýò«ÙËW}œ°ïÄG°ïøïî>pææT,†Å=íØº~Ú’Q5L”6N‚­)©· SÊ?ü\¼³JÀ)º$Õàá’KRl§YÚjE÷FT•„–ã¾üÁ8ÿÄ#HOŒ"CRÌsØe˜Çÿ¤btsÂ\&”aP´¶]ãé­ä3´ªp™”(–ÿ€ëƒešé‘o­²¼ý÷(½ ,,Wœè< P†3‡C–¿:[@‘䈃aføa å>»ï3wãþÇék¨nc°¾ª¥:ó,R­©¶Ý¾¾^|âg>‰EËÓùV|Ã;È‚!—¿5–©¼ a†F!*ØrS\½cÖòøj˜ÉÍ¢X®«†¸`@’á{Oôc€1 tÞ—u§´µD¾ø¹óñ/¿š=}M§ùÿø‡ýégÿ®È Ú„{·mÄÊE"1uG1°vˆ&’Úè,è ÝÖ+9yWÍ_c<7`0}s¡TÄÔÌ´À9Ah„£¯rYLž8Š‘§ž@×Ô$Ò5NˆAv@…azHÐÕ%€ô,B E×Ú‘‚EÊÀ ‡äzd¤¦’¶f 0ÿv¾µ^¿Õ¤òV¨Ï&}1gÿLVøü\bIðòœð˹\³wPvŒG©Š½Ðy¦,Ýÿ³ ÎÕ§W.hzz)ù5iGgOÞûž‡°~Ã:iù­K§Ÿß’^«-ÓŠ$~ØD[¶&íä÷Spôæ ?ù4¸âÉáÏDï]bÐOvZ’~!!Àupfp í9AïD Û¶Xð“ðëŸüÊ«Ý××t~~ò¥OÓEþõ7ß+˜äÅ]lݸ ‹;ÛÈuiÈF‡9hO S ï›)ÛÌïPqùÁûÆ]À²þg.ŽŠ,½ëÎ<«óç~ñøo¯v¿_Ó½{aɩÜg¾ûÌKP¬Ar;nYƒ[Ö-ƒS« š5U†P[ÂÚ«¨Ó\x£9€u½]—/=Äæ&úéžø7Uzý,»G…¢‚oÚj °¶ÒµT+% þóW1»÷h ‰&%£Ë BÎ8°1Ð CVó ƒyÁî ,ž4Ä}Î ÅÏ«néNCfeuuS嘹Ç? ÀjÈ(ªk©ü|_ßo?Å›”¼#e¾Úð+¡^iÈø-îî+PXǧJtW¸FæX 25 ¼AR nGÙ@E+¨ƒ¶*禳èèìĽï¸ÛoÛŽh$Úóè­!ÞA2™¤_PX~üŠa~ÝØ÷³þ€ê<«j†ÁÈò9âDælq3Ù¼PÙñÜ®ƒ§†°óàiÞDɰ޽mõ煉ѿ|ßwN¼Úý~Íwî©Þ;‘Í?ýÇö€Š®^Þ‡7­ÂÊÞ ò¤ù‡‚aÒ’)Ä“1i„¥µeâƒÛös¢ù¯Òò’-ðm7F²Q2‚~¤ÖJ79ÁÌáýÝù ŠÇŽ!F!3xr ,ÂYWØ€ˆI þ€»#ÄÌ´ˆ€.ëx½æ W;wÍ*!´Õ2œóoö¥úá®=£bS ¸Ô×›öÊ ›e¨Lñ~–Üý‰T™Õ—Lb¥Ú@™é¼\ﯢ⨠)´õ­Šø[8Jã¼£0€ ÃÊÅæ¹zù\²êo»ómØqÇmtvÓ¨Õj:‘mé쾋X,Ž2lQÎ?Ù Kð©<`¦ÁD>šk–0X-H繄Ééia)âð“„Ï Nâ…ƒgq~hL\ÿ{oÛŒTÔzû‡ºû™×²×¯ùΜXf_ùë¯=rÏ™aéßß²z î¾e%"ÑÅ_U)Ã$qG„#A™’âèöGsÇmß•Ìo!6‰¸M¦£êÿqR[$m³£<"ŠG†Ó3ýgqá™gÛÿR…œÌc Ùa‰©‚Â%Àù>…äù‡ü¸x ’ ã1;R°[“„5Ÿ€+e!¯'’-Ÿhž{÷f]¯G`–c2ì† Cãúå?ÆÂ“Ð×Çs¨‘°r/J…3ù÷“(6ªòá\—Ñ,4;R‹¤í§ìòn"­(U»š­Á@ b¾ýÎ[qÇ;ÐÑÑ!É6;M·ž«“~ŠûÃÚB#²TõBŠ„sØŠx±÷Y£ð%;•Å,…5<þŠ SB™g÷ÄSDvzÚÓøøGxÖmÔ~ú¶+¯ÚñwÅëy­7ªTu"ÕjímϾtèO¿ÿܾÍC£ÙHO{Û7,ÁÖ +¤ÃŠ­>ƒqRé´¶¥5€£¹¡÷ܬÎw¡š®¿ë6-K{ÉÝÏ’ËVáé(U×å£& Ý 4uæ4.îÚ…Ñ—v£½\@ŠÝ}ŒànFž5 X’!'¡¨žxÔx0V”bôeµÄ„v\U´°un á¢y?ßü À±^k¸c_ þ6±ù´òHXx^_¾ˆjv–@µ|IÚoKLÊÁ½ú$˜òª ò‘Ra iYù9déGÂq …˜µâÆDx¹œ+õs\Fp˶͸íÎíè¡øßa0 e³5×%¡ %Õ"I?U®«kÖÞ«ï ¹«Ç—Ê1[ødäà ã}>~'¼¹”½ÿļxä,&HÙ%¢gyoç¾~àÞÏÅbÑVt¦*¯å^³Súü“xv÷á/ž<3²²X­cQOîØ(X¿Ä‘l•z©šÎê»×’æ]–aNòýh¾“< !GGšÓ×< ˜‰xs%~o`êÜŽ?ýÜSG‘šF˜Gšq)ÐÕ½Ü=P]„ª“ÒSÀΡ8ˆñ(¬¶$B餌o'c…º£“Rvýìå¿Yוúò¯¾,Ý{Ñç[Òv½°¥æeêÎ:ò5H8ù2¬éÊ3yú¾(¼x\¿/‘K^ªª~~G3K9:”s¬šä)ø½¦‚ \ˆf0K (³&õ,Az‹ ÓÍ“5¿é¦ xÛÛnCgO»!S}KV^ç˜p†Ë}-©$ÌIt< ûÕ—LfššïF{P,HäÄ ñÌ@ƽ̖ñýb`x ¡p¨Ñ YÚÛñ»¿ñóüöµ¸‡×ì¨>õÒQ«^­=¹sßé·ï=Út&-+áîm+Ädª0Ÿ–H$жö6BøS›è‘=Àt{ÏMž4Ût}ïªt"—÷êŒÈæQ(½^GæÅ©R»“g0B^Àìþ½RHÔ,IÊŠ‰E™`$"ˆA&dáæa#œ á·9æëNÁMFTw¢nA 4®Õnþp,K—G_å_+ŒM±u£i©›šžÓá¶‚AaÇûµ™YX³dõé^VÊUÁój‚o•?uEDÓ û•§ÉXþÉhC±6LDÓ˜% ^×<,…URñd7­ÁÖ­[Èò÷Ê 48ï«V1ÙLB'ýB¡ª÷»Í¾ü…ì„äº4®Eí¡zœùC§&'Q*)>AxS-ÕñÂá³Øò<òÅ b±Øùd<úÇ‹:Òõï~ñCד~MmU©\ùâ÷Ÿ=øKß~â¥p‘nP&•Àƒw¬Çúå}Ò†1c [ÝDKR¼•Ew¼ymåñè¡ê88ðûêól€­ÜCÚÔ*Å¥|,CUO|ÕÊ…­Š’ljöÂN?ñ8fîClvz3 s¤´â D„OÀ–Ð@‹˜dÄRù9”ü»Å°Z)$ Å`™¨$¨¬ÉH@-3SéUžE©íó} jò¨æpM0-wƒüƒ"xàS›)ÈØn±øŽr÷Yøy˜‡cȘi•ìÔè¾Ô­ÒmŽgP 19G@;ùDq?Çó›·lÀ=÷ÜABN,¾7¬C±X‡"!¤$ã’kSÆJÁ}¯ô*ÖVªaôZŒóÏçót= )3šöäÙüëîÃôx©dŒ™²¾T¯;¿òWŸÿô‚Z}t ®åq M[}fpì·¿óäÞŸÙ¹ç$BQ=m)¼ïí[±¤·“>dM™Áá÷îë‰BÐ,.º[ÊÄGóÏ•fš…&„I¤¸úÆ1VšCÛ­ëÄÿ> V>pSƒC8³s&^Ú…øø0"n™¾‚ÐÈp}eÀ­ÄÑã\ñ¸B J9IH7Én‰Kn€çpO‡ CXyÍz†Æ5 N×õæ—7Y©©X)[i.¡@óumBLÈ5ÿõÍ@5uéU|* â‘ ±ð;¨’*ô0W«hůŽÍÈÈ.ŒJ݈.sùé¬ðØ®ŒÑ0Ÿž;ÉÂ>AB?™Ì`*Ù‚*w|ºª»”ß·A¯£ÐnÓ¦uؾm º::PmTÄ“°u€k)‚›•>y~.÷iŒçö² Sƒ†4×Ö]~fpC¹ý\Zä.Ö()¤þ± |穽¸8‘—ϳnE7:2Éßû¥ŸzÏ®ÕÉòßãk¶F§³÷>ûûÏî<öãã“‚ÖÛ±e%î¹e-z2iéÆr\ÇCP™N=‚AlJãeÜ©&gš¹éjÄXÀŠÚ*®—J#&êé+f”’4}DToêâ .ìÞé=/¢12ˆD½,u~K·"5§³ E4¤{ Â6„&Psàæ!ž‘ÀÃQX¤RV è Ôk_®×I©>¹Oà|y‘yÒlþtþ+鿱tÙµI¦éqÀ§h}/繪ú ãU*;VjŽÆSHÖF`·dõ¹—¼G&í¬ó¸nfð%ÃQ#/¬…ÙçÙûæm¨ŸÎð¥YÞ„õ:ü¨šænPâQd€Â&'0°ï†_xõá3ˆ–ŠM¾wÝ(ÂïÌì¨ÐÙ âŒ2W ¸—€CAFõ¸§ƒÆÞ€xª„yé1Ð÷ÍN6O0®pcü xûcÜ]{A¯áh@57Ánòí©¶æ_ËäZšVÎn6]îW¾\«5³£&”mäê:<ì¢@Öbáz¥ŽJ©,£â*L à öðxt¼ñàj’W†ÉÖÈÊW"$üdõg’m¨Æ“¨ÛŒæä0#(ÌRy™ V¯[í[o’Œ~žî½éç7 Q§aו²tG'üÌç¶š'ÓÖ>©è¿14fš\ÒQm¬2e›óK\7{Îý*œ+ÛuèžÞ}ùZ ;wµ?ÕÕ™úÌg~⡯b«¯¸^·põïþåé•ÓÙÙ3‡Ï !K7uåòn<°c3nZÑ'ÐLèyR³•²dymÝ›íšô¯«ÜsýÍ 7?;—@Š-w<»mñh-¡ÜªF@ý]PO F„µ@gŸÛ‹/îBµÿXΰg@ÿ(<` 37NŠžà&#&јÕÊ`Í0ÀTÛuÓ„/ù6g‚ÑœyåîÏæËϾxÞßãp¹¾&Ûoá½ÐÅd -!È1¾[%§ûYŸÍ E·EB^¯ÖÅê×*5I²I9¯a)‹/#·4ôÕš²žc)+j7øõƒ¨'’¨¶“à·w£J®?ÿl…#¢xª ¥Pâá(º»Iø—õ‘X„YܚƇ¨¤œjWgcr¶ Üú£ôU%£óK&ä\ i%ÀŸÎŽžöã@]Ýûµ«z!CÀ[ÍlYÌ-pàd?¾ûÔ!\“<Àº‹G6­[úŽc럼޲y}Àž3ÁÁñ‰ääùsz`¬ƒaÀ}ø©»W.–Ö^®ÛóžÆ©aòJ2lÁ°‰¥d;iƒÐ/L°<’ïÃù=¨,.¯^r¯V.éDG{J•eêJ±ðûY(í…%EL]ÆÀþý˜Ø¿Õ‹°(LUÔT…Z®î$s!#Œ`Å@‘­B@‡\†¤›ÎIB“w`GC‚0“°É2Ÿ[¼JKcQüŽmõ×[6¯[.é[ìî¼86ñ[ýC“¿8<šs¬u×ö5xïÛ·ai_'Š%eõ¹@pôt?ÎŒ L‚³î¶žùn鸩g»ÍÿQ|©eð`ÊEãÊ—>m©V,í–÷æÎ?×U‡QþŽ~Ï Ál½J¹I Ÿ@ÿž½ÈÜðøPÈÒá¬jáPc›øï¶ò‚š‚œkœàÞþ!K+ òl¦%çÏÅåĸ†Ó¿n”„?ÅàHhb{VÐr}Ñ5ÀsÞ^®ØØ\Æ‹0Óu_n¹Í3 “Á6–ÍÆL±úRg—š3ùdÙ].ße Þá™Û àa_c«ßpå«ì6„ž«ê¨°ŽUzÃwß,ã‚8ŠJ’}LÖšjA½w9êÝ=@k'Å\) §B’°µê–PÆóêì"«¿bz»;J'DY;ìÒK§úD’C´1pqgûG0I×\§0%,ÝÍù½ëj‚äAÚ-Ï+R1]¦/_Ö…Õ«– A¦a)o€dÿúÌ~ìÚ‚>Ÿ›mIÄ­¥=_êîhý£ŸýÈÛǯ‡\^7ðÝeMO¯Ê~{t|ö§'²9`Þ½}#2FwW+ò…B$|Y²þÇOœÇ™þ‹Bç …½²¡8ô*e«;°^î†@ßxy‰å\KáH¸Ø[±´Ë—öQL¥¸ÐÇVÝ]2f<ÄdŒž9‡Ñ‘=u³ÃMOÂÎeɤ”´‹h©Cª0dʕ׭Å!Á‘Ø¢ÂF1X ~,teL`J €CèžN ëPP\±¬ Šlê`¾Ðç² »yÛã%½.§,_RÏjF¿²}z µ„Xœx£{––­¥ÍÞ :)kÒÒ¬ä áu„Yב¾|Ûš Ãɽó `’¥²ç†Ÿï¿)C·%¤Û`µuÁéêA½£SFÃsvŸïiaÃô©Ö4ÚÈ»ë[ÔMJ ±X˜”OE0 F™Ù¡€”‡ó’\šÀ™sØÎ*d­$¡‡š4^ŠèªË+ioнZn1_¹l6¬[†4ÅÿŒ2LÐýåpã±À {N T-çí€ûÅŽ¶L §-óõöÖ–ŸþØ}× Kz¥u]«Iÿ忘ɗ6å²Å?ž˜¾¯T©G˜:üÞqÿ[JQŒVª“ÀÄ;tô4Î’‹ÄS\"Šã.SX¸¥¹ŽÜä Fû01t…ÃÇQ=w Î̬FU:m¶‚–á‹ÓCI¥']qÇqhÀÃ0ŒRPžŠ8?Áµay[4†ÛÜ‘à`‘;ÁD)@ˆJ!09F[nytf.繚êe÷Mç \×P¸ëQi,ìuW d……½*Õá$[¹ ”«‚©ç¤µ°Å¯9Ò™)ã¬YØ]W%õ\““1Øy38Ö$lm …ØûïêºÁêZ «£‹â¡ÁÔ\,¨ u½Ú—––8Ú»;ѽ¨Gµé*î6Q@®«8õ‚´w¬xÆ'fpñÂNŸÄ,ÏÔ“¡ ' ½ŒP½û/‡ó»‰©“Ï\A°I£®Z¾7m\® 7ë<¾.,óýþ žÛuÙl!Šÿ™®ôß“¨‘˜ýÍŸ{ízÉäõ.'ËúìþÛm}­ž¼0šž"k±´·wݶ ÷ßµ &Ü„kfhtœÄ…‘IT*ŽÄÒV`^ñ•>œ«çè±O‚ÖÒÃyq²‡on$EG[ŠnÔ ,_Ô)Äüì}é…¥˜Z}V­–Q*0rð(&OGþB?j£ÀÌìQ xØ3ÏZ:Ž÷„R%º§@ ¶:˜ai6²…hKÁU<Ü´blAˆ, ý· ÛÊ ü<{!M»n‹vñ*(°_68ÒÎ…*»®Â¤K⪮by¶ò,äØZÇ÷$øbé™ù™㮼:'ú¸Î.VÞՉޫècô"Á¨wêšék¶XÜÊÊ¥=“ĆÕK±~í2¤˜ÔRXjñÜs`“{R]šÅÔøÆOžÅÌñ£¨ œFíÄ 8å"阚G_æè¦9õ¾4‘ Káªj,¡ O1‹%„:è¶NZY&Ä`—6ÃŽºŒå þ  š¬t¹Ðlýp^˧èÒȭ˵ïºró¹tç”ê’ß–[î΃RŠì¢3ÇbU3غ+´žþ†°ñ8Vsân³¬é4ÁMŽjúwÌXnVrÉVz#¸|BKVÂM·JÍ^)9“bg-YýÖ´µ·¢5B,©8û8ìàÏ[5tÙ{?=[ w§N]$ ' ÷…PÉÕÕ$Ûš{­j­=ÆæžéJ”‡Bu•Ÿ Š‡Ù‚‚XM–ËÆ•èënS÷†þ+•ëxþ¥ãxúùýÌ3 Ï.ðÿ~ééÇo”Þ@›Æ„;¿¼óÀÉ_ûî“ûûNœ¦î ·½ï¼o+nݲñXXn4×hǧòؽï(Žœ8b¹ŒH0¬â­,ל -\~é¸ü-ó-¡‡]±,)Ó0· =ß°v9–/ïÆ¢Þ6ÉS¨Ä´9ˆ®$v¸^Ë!;@Êiðr'O 86JÁÜ™i8<œ«VÀ I üIA€ e9×l¯ÂÇ¡‡ ÌX,Tèp¼pB¾³îHY2Žˆ»,³(ØC *bS±HzzNÓìº:<±ô앦`%'EêH‡š#V^2ù,Ü®J ²ð7´PUÙF:ªÆÍÊ,<†ÓÌ€Û*––©½Zõ9¦¤¦á²<ÏÁfFÝL'‚==P|Hµ#ØÑ-^€Å¡Ÿx JqÙ.JÏO¦hmM!Ñ’P4ôÝùi††êýfWüÂÐÎŒàÄé 2dƒ‰?x^„º— Ä%¶ÞxRëw¼ÀÒãÂÅC¢Ç¹ÄÅĈlÙ´‚ÎO‡âÀ¤gç+5ì9t>u€Îó·öò5¡?þß¾ôG¿ô÷7BÍç½a‹¬ïžÞuôW~bOË(m [ãnRïð6…à&)ÍY˜™ÉáÉÝqâÔ ¹œŒQõš.<jêåƒÖÐ b!­²’^¤×aB¶ºËxôùMkÐKžI†¼.ßA'¦ê\Æ©UÉ.¢BGÒK˜žšÄ +ƒS§P9wÕá ¨OŽ©7©‰WÉ}®6“†PÓ_çXb¯Í”=‚ šŠd5¤±‰=…XS׬†Zš¡X\=ÌDF©[9!¿Ð”VŽŽk­f3‘ciŤKŽ ±`ë.¸u­\ÅÂK -Ѐ¡Ú0l¶ŠÒ]p U q”YÃcùÐKïŽÊÔªCÃ( _„“›F}l É)RerÛ¡,²Ót#=oE*PšôIJ›1³¾eþÞwRÅN¡¸Ò%&Òñr®J€ZÚ3Poäz0^úq4V–ðEO§53ÚLÏÒÈERLÍa¯šáŽºvüa«ý´#1úÐÖØòhY¼N„”+¹ùhv4&xÅ!W!¯ЇlM"™L =¶(k×ò&çÚf‡Ìnp¤3L‚¶ûÅc8vz•z>ÿP¯—‹éç/µË¶ ýj<?Ρ]êf&Ãݱ =}¨–k¢ 8Øwô<¾ûØ.\S9&Æ †?aÿô¥?üÅÊ#uC¯¡±ÉvÒÌŸ=|ââï~å[/U­RìÄú½xÏ;nÃÖµK0]® y'ãñ§¦³xjç<¹ëцº&ñ%µ¬…¡·üKd=âGK: l#7sÓºe¸uëZôu¤P¬8"ìjJ­ÊX« :[:•»`AªÌÌ`òÌiÌœ9‡ú…CC¨Ž“(æEÙ‰µdL½&D¬Š®(‹¬” ,5ÕØ9¹ÍpD…@z~¡Ioš^¯œo?ßÁ÷ǺþfÓµ¨ždù"ûºÚÏõ½ŽÕ|A#ûB¹ÆŒIa™ÄÌø†÷Ftv#¶z’+Ö¤ìDDÁ¦5=ZõLYˆ‘Bˆ&#Q8ÈIX¥8Tl4T UJ0¹ÿ"Fxd,‹œÄ‘S2V«\Õ AhrK™ C YJùª0G9kÞnègÔ1[*‘Õߊ{nß,pó€Vžiºn&ôüÞS{pòìE IU?E/úð—ÿì³…ë+m—ÿ|7| OvWk_?xìâoì>pçÇ$Ž]Oõ®Û7á¶[V£VqÔ¦ƒ1>9‰öÃÓ»‰›Èr[fw¨6cNÖÁG_ÈF8&ìcwcw•_’nZ&IJÅXµ¬·nZC.^L\Of9ªËÓ%¤‚°ä°:•J¹*ù,JÙ¬Y–É ˜={¥‹ý¨æfàLN 4:JžCIðRv¤ë0Ý4ã øƒYölàºþì½±lše¦ Ò1ŒhfzAs†½÷™ý­¼ÀÊÇ ëÙëÜ9JC¼&ŠÍÁ¹®0¯Oá¡- ÜÂ$ªÄ/CrÃØç³2æ“}‰”|F;àJhÁ€¬`ÈÊ-ö¾xT› H¨Ú Ì|ƒg€ÔúYฑìØÉó"^ÄÙ £àê’Tí †ã:Ⱪ¢¥° ÐFÔÝ|j&7ŠË"±qûÖõ¸ûÖ›ÈKÌ¢P 'N÷r?Yþ'wÆ‘ÓçÅ«ÉÄ“˜Éý*½Ôÿùå/þêëŽò[й¿Ñ`ÖðøTG$þÓ¯|ã©Ò™ £Ÿš-µp|·fy/~ì·cÃêeR®á,+wôMggðÈ3pää€ÄU,ta®‘Kƒ¡7¶iÝ\šØÓS39¸ts5¼í­)Ü~Ó:¬\Öƒ^ºáë1IH‰1îœ}f[Kµ IÉÎVcÇ8ëÌns5?‹â…‹(^¼ˆÊlÕiR"T(dp¸'‚cZú·–#…Q))tÀ[¡¸òlÕmI>@áµ'òd`»Ži¡v/qxç…†›Q¾Ü&ý•tP6”ð5T@†£ðÜò‘˜Xù[ù– BíþpŠbüžÄV­D…ž[¼¦†ú{ÉÑØ ñîXðC<Êç3¡ 瀌rv\åÙ…™‹qôôèäÌ,. NHÉácg(æÏJù1ÀhK•jÕêÏñĪ[ÏòÐ{W^æ9¥@,Š̹½®¶46“gxÿÛnBg&- 0ˆ—uôX?Ïý8~nXðí­‰|È þÅŸüÖOÿΖµ9çþF_€Må¢]m©ò¿ÿ‹¯ýy¶XþÔØät+—Ö/êÆƒo߆kú‰FPo°›XGq¶Š]û“Ëwš¼ˆ¹Ý&èd-põØ®…¥{Ýfl&r³ª"8ªÅS—y,Gqtµ·Òõ,ÁM¢ôv¤e £¾XQ0ÜUEêä(Z¶îøsD˜œŠÎª“PU 3( £4Bž)žm˜ë?‡Ê)ò ÜbÑJƒÌ:G)7E/­,°2âºüè—£÷2?û½SacÅâèAÀ uß…%Ü[F©©Ì‘î.D÷"ÒÖ‰Hª ¡¶v´¬X`¦ – õl•+°t÷†@² /žrõí¢`ÙAÄs¥¢`뤥€ª„œU•M«ÌX©`2›ÇáS°ïàLÈt åÙÛz¬‘o[¾qs L «}2ÍeŠÅš'ñ~÷v·aÇ–5¸mË:¤!õ9èú¸,zúÜE|û±Ý8qL’¡=í­3©dü+¿÷Ë{U#¼_Ïõ†RfýΟ- Ù:“Íjt"c‹ÐF.÷‡¼·l\% ‡\->.…j‡O à™Ž¡Ÿ6<ãò£°BÍ›·ÐpM—IÕðáeÔðQÎæKüÏ“†#¤[¸§ [7­ÄŠEíJ€tß_c3Ú¶=¨‚m¼GÎZ3°¦šÏ“"( Á 3LƒE@½\$o€¹ñf(„˜B=_b<„ )ŠFaV¥¢ˆ%)„¨Ñïœ`ò}ó]3R7ø;ƒŽD³¿‚+zo[tqÁ#dÕ‚B %x`*}%ÉëI¶PìÞ‚ýLµˆågö#ÎîG2­°ÃQC¹:—ÁaÓÒm+"|QÒb¥Y¸,G“µX2rÌ! ¨ÎH[Õõ–r½DZÿðœ»8"¤%Þ/GÏ€¨éÁÞ NîðrDjTÞDˆã®*Š$UU¯Râ‘Ü ¾}Çf²þËÅÕwuâ‘QŸÃ·݉ñé¬à#:Û’¥ŽtË—)|ùÜïöc7<æŸ¿Þ à·¿øÏV$XÚ¿—/Õ?~ôܹÙ!,ï뼴ñ·oe­F±T~ö|¡ ðÒ¾“2@&è¹€—®ùÖ—'¾_*…`{3áàFÔÂG¿L&cXÔÓ!1àâžv¬XÒ‡t**¯Y'áVã¤u6_¿“cRSˆ$²¥` nKà @Cu×¹µ*ÊÓ“(£–%o€”B­G…gÇÑè÷u>ä¥ÊSÓ¨khë¥üÚ&aòX|ôG’Ä›dÒÉ Ç¢dÉS§'¤ú™……?L.}„;ÀÃ]ÚÉÚ·¦éCrø}IùYú $üQÿªZž®Ñ£©yDÑ:lõëêqWuèÙÅ«â LÐq¢CC“›Àðð$rÜpÄm׺M[³=h³¿Ž¶Þs•_³Ûáòá?#üzŒ"d~õk—bÇÖµX½¤‰DLJ¤sÅ ö5«@MzT—i÷W%,ó†~ ËÃûGÎ[5¨<<Ó)hæQ˜|cPxµeZ°ré"l½izºÒ’²uKñÈTÏï=]{ŽSH2&IÀµË{qóú•/6œÚo?û¹Oø ;3ê ­ÌzìùQLÿŸ?pbë±ÓÈë­ ¡â¦µËðö;¶¦íP¬¼AåæNNÍ ÿâ8;+ /N]¤ J\™Ú¶Î-Cu¤ë&^“ŠÉÌ«ûý8Ë·‹lɸ´Ìà%:œ rŸ9<Ȥ’hooÁºÎ®Ž )ÅQot,¬Óш9^¶FáÓôÄ ¯”“îQâJG •$ëUWž4ò ‰Äc"­Ð>ŒNƒ¨-ª«bm?ÛrP$¿Sm£Lƒîœ|†Q–Ÿ°)|¥“§Íý’ìtT‹18Š©bœ¬=fÆ'g1=3‹"¹ÖÌÁî7+O¡b·›7ižÏ¦¿™_®4–ÿQ*³ïSÐ;YAñ\ ºà®ŽVlX³kVô¢=“bgGHE8ü'åôôÎCØ{ø¬$!b¼ŽžwÛ–eûBÁÈo½óm›¿£eçjë‡Bð:waú›šüN¬>pbÙìl(Lñÿ-W ¿àÚÕ‹¥€z”´p¡\E?…ÇN]”2O^‘Z·I5æšú¸> s7Ƈ!ðZ=凫n©¥Ë\B„!]i6ZZbr€ÚÉšdÒ-hK§ÐÖ– kŽŠbjN=v=‹d•·~o·[ª ÑkÛek¯Fa± Èú(`{óU•€ˆ| 7í XšûÚ|N[c,òù z޾òÜ™œÉ’0Í 7[¥ÈÞA”+(ÉULJD¸úºòd5_Aø»3ÌÃü>\f\BÜúUK±´·î_•ªzf¹QÅ©óCx~÷1>vŽÂÍ*bÑHmëÆåxÛ-kN§["ÿaãêeÿxEäU­À«V­î™—ŽÝóg´×ëõ»&è°”ÈBl^·wïØ€«ûJÄ%`¡b¨ CS8rê\óCŠÆÊâ3žµˆÎLW:†Rº }Oâ¤J¥öžèÇ¡ãýèÄØLNʺ[×­ÀÖMËa‡ÂŸ¸ïÖuÿpíO÷õY?Ô €W¶\ø½o~ÿ¥Ô‰Sƒï-Vªë™Þ™;ÃV-iÇ–UK°ž<‚ÎŽ´¤øÆÉ]e|8ÀD#¹|ùrY“SB»ý–g5ýÖo~àe—«¶ â½ÿ›Wð[XóÚz®œ­¨´Øcptv_ò¡ç<>NRñ÷R;+ˆ¬¢4W+åhš1#p®_Ú/umT @Õ¾ŸÖR}÷êZ¸šÀ{ȃ<øgž­Ç^¤A†bå“#x`>`šy £…Œ¥‡ùÖõ©Ex{d*š€QžW^sS~ºÄ ¾˜é¾ÌÜC.|<Žî¶:ZãB¿È8&¡åüé û‰sÃØâ"Î]B•>ï²%]h‰Eo\¹è»|p[®%žüüu?ô×pýÐ+³þâo¿ó‰d2öûŽ_.îg©B‡ÞÁæ5Kpë¦UèiOË䞆ÎòrÙ™'MÍ”H«çU‰¬QW5u¯J`Ü÷&h! À둟£üùhýýÚó‘‰þ§–Ï_p<:*ãe4Ka>DÂ! ®<ì@ÊüY34ßè²RVlpRK•èt_A…YJTÝX¯7±Ä^k5_˴ͪ_kÃФ)œ¸ÉGúæå%L¢SâwÛòyTºQéjûï-“ÜÔ(AÏ„²¼¨ÖTími„C¡/ £þȳžÌaïñ³8|ú¢(ºx<ˆ8)ŒmV/*¿û?ê¡Jäq­Ö›FðzrçáŸ!«øgÿòýÏV25§*ý+äâm\»[Ö-G,h{ÜöŽfærY–ÜÖB±"n«jäi–Õ¡s}!ÂeѾç»M¾B§ií=8ŒN*Z²ëWþW4αkù,£îÐkN¡QŠÉòJ”º\g²zZàTíÞÇm7ÿ²ÝæµûsfðŠ£IR †BýÏ™óù=Eæ#BU7ÕŸÁšß6¡¹ðï©—;™ó/çƒ]Σ™û|Wç‚8|⪠SwE‚®„PþéÓ¥ªƒãg/à¹ý#³b0"AÛʹƧ?ôÕù×ïß±þo_¿S|}×›J<ûÒ±Þd,vË?=ü V.ïýʾ£gÛyÒP&Ó‚t:ŽŽLk—õÒWô›³§ÀK¦Ë6¶ŸçÔ•ÙÂ9u¯Œ¤ŒŽ¢Ž6ˆ:9œ¶IÄùž«¬½;ïLšªƒÂÓ¸qæ#º„ïøºFaèÇ}wÉr›°¿»¬„²üúáKsÄbN¼9 Ð|xÎëk´¢ù…_ä/W›÷× æûN _n°F9ZÆkÐtÇ®‡éÖ•WÌl>u ŠÒeè ¢0Jò&jð‹­ùc‘ˆÜ÷“ýÃ8¡‡„p¥bjª ‰ÁmëOžÿéŸøà}(ªûïÙ¾føõ:Ã×{½Ù€•ŠÇÂ_}økë–U?EèÏ Œö?7$‰?Æå÷vµbqg+V.ê¾?Ž¡«ÕŠ –€Ž¿¹‡ËW qT©€PÜf-\§¬Õ®V@×Þ]Uh0æ"×L ýŠVí•X»K—{…WYÈš¿²k™[0|yÉ}™×3jÃòÂC« )öœÇ]C€ÈËV‡š}|ߢš0U¸$WCr¯G§²878þ‘)²ú3˜¤°“Œç–÷u תµß>xjà«?ù·»…BµJ àÕnén½©€}õ;ÏÅwܼö=ynp#)†å¥JmëäT^r)2+wbÅ’šŒ…J̽ùu§iA\=ñb1lI×øªaÚqç8¯9¥Íœ›×k€æïà¾i·ÿ•¯9(K“Tß»šÆ]yQf·mzwéðÊVcÚ¸gÀÕèËTD\5˜…=õr¥¦sôâÌÅ1dg+D‹öÝ{ÛÆó«–ô}þ¥ãôÉÞ_¼Ñ[ôºmû›uMdóKŸèO95ð¶¾î¶ß|ôÙƒ¤Ì 3ùY9]m­XԙƢî´§ctÓC’­æU×së ÀTUÜ' Š…· Ö]3å˜a“¨šŸó÷7y/güM½ý¯lÍW– µ,OÐų²›%Zpé’¤£IOe²0‡p•šª•l ¤†wp¹•“zSäŒÏ`hl ã“Ó¢nZ“IDBÖ±wÝsKhptâO6¯]ú†•Ks]íé½=¯ë¶¿Ù×ß|ãñΫ–¾ÿï¿õTyݪ%¿svptýÀдŮ!»…mmŒÄKaIwÚ“q) 6LS‰&Ý%@q#³¼FcQ¡€6‰=e“€ÅKV鿟ï ÏA¾iÉk°|I/dš“ÄS¿µl_vÁU!ï;÷]p)²,x„† ¡«ÐÍCŒ³ÈÊË’à“«ŸE©R•Ç—.îtW,î=~ê̹ÿð‰Ý=rzàáŸýÈ»®Ë€Î¹~$€}ëÉÝŸ%×þ×Î]ï;waÔ’–° uogÝœ0l‰"‘ˆHíÜÖ.½ŒÍ"‹&/iɘ_> ÓWT:Ôx™Yuî¼Øøré¸Ë¡ë~¤×eøþÉ;&‰¢¸ù ¶”"Ë¥²Â!”k$Ìe8rõ O]á²f®PÁ´€Àò¥8?[( ×BwW¦±ri»biÏ©Œÿý#÷oÿ‹½×sýÈ)€¯~÷¹ðCwoûÃÁ¡Éw>öü(… ëó³LÌ„Å%I‚ßÝ‘pHk"Ž(#î‚j@‡Ìºa#‘LH3O<f¢0'™tK²@} “¯~Ú¬g»XX_ÁÆr½ ©FP*)ö¼0uKlƳHÉÊ;ÜRF6›C¡PD­ÚP)UöÔlµ¿F&Òs’sn(=04vïÆµËþë£/È9ٟηÃ@cäî·§¢ :Z“ˆØÊ›Ì´²¡™®Â‘Z[[dTUŠBˆ@H“U0µc¦ËûºÏŒõÿ‘ÜýË/Sæ3 Üi(ÉW ŠR|uH€''§xª®€“TžOý­mºéOyB1ó 0 ‡Á^ î±ôd%†Y/_Ü™ýèƒ;ÒÇÏŽüüÒ¾ögV.ïͶDC£7z®û¾ßè ¸‘ëñç¦ï¾}ãƒ_dWyù¢Î¿o{~ïI ŽN‘å*>¹û‰Hm©:3IÁ‡›ðTqŒOg.O𥠋 Ù³VdH!pÞ@¥Óh¶`n»ñ[«Ù2¬†‡:j4:©N¶ì3Ù¼¼äóyrõ+BZÓ³™7Pž«ùËå2FgrϤrV* áôë!e¾}Ór õZ§NõýÌ/üÄ;£Ïï=õÈwnÌÞèÏ#÷ý­¶î/í>prÉ©sÃ÷‘5ºãøùAœ»0&Þwè¥ZÈeä=žOÇJB…®”©¹ª|ÈÐY5Ñ&*¡A:ÝBÏ‹J[iŒgا’‚ѯë®n“mÂUßÜk> ɲš` ¶Ì<€ûîgó³ÒÂÏQ¤¯,Åî³$Ð¥²" aÀS¯4¿É7¸-À„¶ ⢠¾”/øÄØ>Àb|@ DŒÄ!jŒ•²®Œ’Ò¤m²æÚ%MÒ¤ub;¾¾¶ß÷å<Ï9ǯ³¥PF‹êGr'ΛÆöyÎyn¿ÿ‡kô¹3ñÇíÿnëÿ/Ú–YDÂä* Þ€œÐÔXLC!Ø]ðáPwtøÔd3Ú|<ŸMÂΧÆCô– ×pÐçƨU»C¯ÇþÒÓÙ`ü#öå`ø{Ý»ïäûe»[ÑÜÂ^<8v¤ç•™EéôùcîzÐ-ɪÓäønHZAó8*~…OÀÉb±æ;PM7«Sà"5Õ>ú3¥Ô!¸ðT€£±B”›YT¦†Ã'q‡3LÃØ°ê6s –å÷êóD¤dÜ2¹ùµ6›¿å#ÂbVàýß•6>VÎ»Ž˜Äƒad°‘H”„דdåÆ*½ŸÄªŠh·fD!™±úx}…M"fpœ;DwzHÞB_…Öé—lmª‹7ꦟúèƒý…~/me+:€[Ø‹ƒo:Ž ôv\™^’~ÿæÐRu¹ç¹†úÚ§Ï O‘…¥ .Z!±Ãx.=öÛé} þºœ6œÄƒSAnj轌þÉÔ{iÌj³ÙQRLµÑð‚:²R¨(¸HEEñ€Ð4Âèá0 ž ûÀðQÞ¯µ_dÈØ¸ÐsðÞ~+Y-¶›™É'ê îÖMžÈàe7ÑÅhêÚ ãRØ`U¸á=Îñ>NÖé & 30^ ù”,£ƒA"ÐàýVpílÆ$ ÿ§4¬ÇÓx¼‡Ó$÷hD'º r¨· /DÚ·:îo(§àÝB¿—¶²ÀmÚuª§9P×óöèLÝþöÆç®-¯bކ0T°ŽR·°øaÄÔIãO‡jÃxUVTT©,0ÂY}‚”`€zõpf@£,hB¯×í!®RÖ äq;1cyÓdUƒ/X†£ÃÄ 'ò˜†Ä„ArºYb¸Hb‹Õ¶ +F*‰… NGÁ¶Ztl2£ !„.ê(ÝÉã±8rô~ŠÆç°kkôHÍ:ýX0Nê\ –]BO%ÔÉ€ *€\ÔI›ÞD]…`ñ[‹ZfüÁ|ÑPÞ¶ Ý·K°´¦a·•qQj.l C]œCJÓIœ.Tä(òp%çàøG†€“Ë·,ûÁuÁyhEA ­Ú{vŸ3(§Â•3š6´»½…Üs¿cx|æäÕ…àÏyÀÛÝ0ª+<‹…~ol7+:€ÿÒNþöOþhÛfh<66yÍèÛýÝtÆhŸ˜O¯WÝiìd!6ŠÊf€VìàÕEa0PMfsð¼iˆ÷ ™‡W F°ˆ™¸ë>Çe.â¡È2çî®GD‚€xÂίÒS S¡|7†+*=}¨ø·(’¤ÛTyÂﯓšêË¥} åÓó+¿{íϾ}¨·CÞ×ѨüæÔ¹…¯?ý‰â¢¿KVtÿcûÑËØq¸¯ýÀù‹3‰‰«AóñÃÝÏ;íjçÂJ(¹Œ ^A06RÝ͆‡KÊaÅ$é4¸Ð§”£ÞŠjžÄËr,— sD– ° ˜_üù¢ „´Z”‰`pì†tð~|…AT9 Õ€ž}¤ =æ´+*¨ìúk}ôh_Nêk|NMKýñ­ÑMÍ©½¹šô÷ìr^ž¼6µ·­i¢Ð¯Ó½bEP`»^?^îvµŒÏ,&¡¯`êê™[Z1ú{;¾áq;ko¬†h˜À,;ðöC4t€ÙwHž¸LfzC|‚–'Þr„ƒkìÉÖÉà„¢|æ®pŽ?‹Ðkgƒp¹1P=’tüº‚ÉL¨¼¥. Ý‚5>rc-:ò±Ù“Õ^—Z_ç#­Í~ıµßWïŒF“³•Þ_ú5¸—­è¶¨-®¬}Ç_SÑ;>³™[&áxg߯.­‘àjT÷•»w×ï¨è„œ–ˆiwö4u -A†µŸÀ2žÎU‘ÿ½£°;d¤åbc‘ÄJ{Î&HŽ„™z‘,.¯­®¯Wù@«ÿ?A®ÿ?A¯ÿ?A¯ÿ>A®ÿ>A«ÿ=?©ÿIK¬ÿjj·ÿ¤ ÇÿÙÑÕÿëåàÿ÷óíÿÞÔÉÿïêæÿïêæÿïêæÿïêæÿïêæÿÒŸÿÐÁ´ý—zen¶¢“mʹªÿÛÐÆÿïêæÿïêæÿõðìÿÿüøÿæ×ËÿÿÿÿÿÞÚèÿtt¼ÿAD«ÿAC³ÿHKÃÿSZÐÿ_iÙÿhtÞÿlzàÿl{àÿjyÞÿcnÛÿYaÒÿLPÅÿBDµÿ?A«ÿMN«ÿˆƒ±ÿ¿´·ÿâÛÖÿõðéÿ̽±ÿïêæÿïêæÿïêæÿïêæÿÛÏÅÿȸ©û›j>ij§E¹§™õåÞÛÿïêæÿïêæÿòíéÿÔżÿõìèÿþûÿÿ™—ÏÿKL´ÿGI¿ÿQVÑÿfrÞÿw‡ãÿ~äÿ~äÿ}ãÿ}ãÿ}ãÿ}ãÿ}äÿ~ãÿ{äÿp~àÿZcÔÿFI¾ÿ>A¬ÿQP¥ÿŒ€™ÿ÷µÿöñðÿæÞÙÿïêæÿïêæÿïêæÿïêæÿåÞÚÿ¹§˜õ½©˜EØÎÄ®˜‡ßâÛØÿäÝ×ÿãÛÔÿãÛÔÿæÝ×ÿìäáÿáÛäÿnm¼ÿHJ¼ÿKOÎÿfrßÿz‹äÿ}äÿ}Žäÿ}äÿ}ãÿ}ãÿ}ãÿ}äÿ}ãÿ}äÿ~äÿ~äÿ}Žäÿ}äÿráÿU\ÒÿBDµÿEFªÿ„{¤ÿ¸¨¦ÿúóñÿìåáÿâÛÔÿãÛÕÿãÛÕÿäÜÖÿáÛ×ÿ«•‚ß­˜…º§—œÉ»³ÿíçáÿòíæÿòíæÿòíæÿåÝØÿÇ¿ÉÿYW¯ÿHJÃÿTZÙÿsƒâÿ}ãÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}Žäÿ}Žäÿ~äÿ}äÿ|ŽãÿdoÝÿIKÂÿ_bÊÿ—¿ÿ½¬ªÿõëçÿîæáÿòíæÿñíæÿòíçÿíçáÿʼ´ÿ¬•‚•Æ·ª-¸¢’úßÔÏÿîæáÿëâÞÿéàÛÿÜÑÌÿ¿´¸ÿTQ­ÿGIÆÿW^Ýÿx‰ãÿ}äÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}äÿ}ãÿjvàÿ\`Ùÿz|åÿ¤šÃÿ±  ÿíàÜÿäÚÕÿéàÛÿîåáÿñéäÿâ×Òÿ²œŒú§“ƒ&æÝÕ·£’²È·®ÿæÛ×ÿîäßÿèÞÚÿÜÐËÿĵ¯ÿd^«ÿHJÉÿU[ÝÿyŠãÿ}ãÿ~äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}ãÿ}ãÿo|æÿgjãÿ‚„èÿ€œÿ¦“”ÿìÝÕÿèÜ×ÿëáÜÿñçãÿêßÛÿÇ·®ÿ±Œ«ÒÌÃÓǽ+´‹úÙÊÄÿóèãÿöêæÿåÙÔÿŵ¬ÿ‡}¥ÿGJÆÿPUÜÿs‚ãÿ}äÿ}äÿ}åÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}äÿ}ãÿ}ãÿfoãÿdfÙÿ€€Öÿ’„ŒÿË»µÿãÒÊÿíáÝÿúîéÿóèãÿÖÇÀÿ¨úÇ»±+´Ÿ“¶ “ÿçØÔÿýïìÿ÷éåÿÕÅ¿ÿ«˜šÿOP¾ÿMQÙÿgtâÿ}ãÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}ãÿ}ãÿzŒäÿZ`ßÿacÏÿ‡ƒ¶ÿªžÿåÐÅÿç×ÑÿöéåÿôæãÿãÕÑÿ´žÿª”‚…×ÏÇ­–„ÞÁ« ÿðáÞÿÿðíÿñáÞÿÀ«žÿzp¥ÿKOÓÿU[àÿ{Œäÿ}äÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ•£éÿ¬·îÿ¬·îÿ¬·îÿ¬·îÿ¬·îÿ¨³íÿ ­ëÿŸèÿåÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}ãÿ}ãÿn{äÿPRÍÿZ\¹ÿš“ÿǶ«ÿäÎÂÿúëçÿÿðíÿñáÞÿƱ¦ÿ­–…ÞÕÏÉñ£3´Œÿ̺´ÿïÞÚÿòáÞÿÜÌÈÿ»©¥ÿUVÈÿNRÞÿiuâÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ ­ëÿñòüÿþþþÿþþþÿþþþÿùúýÿùúýÿþþþÿþþþÿðòüÿÀÈòÿ…•æÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}äÿ{ŒäÿSXÙÿCE³ÿyq˜ÿ¬›ÿáÎÃÿíÞÛÿÿðíÿöçäÿÔüÿµÿǸ«3´ {˼³ÿØÉÆÿöçäÿóäáÿÙÌÈÿ­¦ÈÿMQÚÿQWáÿx‰ãÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ°ºïÿþþþÿþþþÿþþþÿŽœèÿ}Žäÿ‰™çÿ¿Çòÿüüþÿþþþÿíðûÿ’ éÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}ãÿdoáÿEHÁÿVSŸÿ™„vÿÚÌÅÿàÒÏÿöçäÿíÞÛÿáÒÏÿ×È¿ÿ¬œ{±›‰¤à×ÒÿÛÌÉÿðáÞÿêÛØÿîåàÿŽÚÿQVàÿZbâÿ}ãÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}ŽäÿªµíÿþþþÿþþþÿþþþÿŽœèÿ}Žäÿ}Žäÿ}Žäÿ»Äñÿþþþÿþþþÿìîûÿƒ“æÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ~äÿ}ãÿs‚ãÿKNÑÿAC¨ÿ‹tmÿñ£ÿéßÛÿáÒÏÿÞÏÌÿÛÌÉÿéàÚÿ½§•¤¯˜‡ÆÆ¹·ÿÕÆÃÿäÕÒÿáÒÏÿäÙ×ÿjkÜÿV[áÿeqâÿ~äÿ}äÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}ŽäÿªµíÿþþþÿþþþÿþþþÿŽœèÿ}Žäÿ}Žäÿ}Žäÿ‚’åÿôöüÿþþþÿþþþÿ¸Áðÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ~äÿ}äÿz‹äÿQWÛÿ@B°ÿ‚sˆÿ³žÿÞÔÒÿÛÌÉÿØÉÆÿØÉÆÿË¿½ÿ¹£’Ò»¥–ü° žÿÏÀ½ÿáÒÏÿáÒÏÿʽÂÿgkçÿW\áÿn{ãÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}Žäÿ}ŽäÿªµíÿþþþÿþþþÿþþþÿŽœèÿ}Žäÿ}Žäÿ}Žäÿ}ŽäÿÐ×õÿþþþÿþþþÿæéúÿ~åÿ}Žäÿ}Žäÿ}Žäÿ}äÿ}Žäÿ}ŽäÿYaßÿCE¸ÿulœÿ¾©ÿ;¼ÿçØÕÿÞÏÌÿÞÏÌÿ¶¥¤ÿµ ‘ÿ®—ˆÿ½¨›ÿÒÃÀÿáÒÏÿáÒÏÿ¿¬¢ÿqwðÿV[áÿlzãÿ|äÿ|Žäÿ|Žäÿ|Žäÿ|Žäÿ~äÿ~äÿ~äÿ~äÿªµíÿþþþÿþþþÿþþþÿŽèÿ~äÿ}Žäÿ}Žäÿ}Žäÿ»Äñÿþþþÿþþþÿûûþÿ†–æÿ}äÿ~äÿ~äÿ~äÿ}äÿ}äÿ]eáÿEHÀÿlh¨ÿÖżÿŰ£ÿðáÞÿáÒÏÿêÛØÿ·¤£ÿ°™Šÿº¤“ÿŰ£ÿÞÏÌÿçØÕÿêÛØÿÁ¬¤ÿ~„öÿW[âÿRXáÿV^âÿYaâÿZbãÿZbãÿZbãÿ\câÿ`jãÿajãÿajâÿ—ìÿþþþÿþþþÿþþþÿv~æÿakãÿblãÿblãÿclãÿŸ¤íÿþþþÿþþþÿþþþÿ{ƒçÿiuãÿiuãÿiuãÿiuãÿlyãÿjwãÿRYáÿGIÄÿlj°ÿëßÚÿï¡ÿùêçÿçØÕÿùêçÿÁ®«ÿíœÿ̶¤ÿѼ¯ÿóäáÿêÛØÿðáÞÿ¼§Ÿÿ‚‡õÿW]âÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿŒŽëÿþþþÿþþþÿþþþÿeiåÿOSáÿOSáÿOSáÿOSáÿ”–íÿþþþÿþþþÿþþþÿnqæÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿNSáÿGIÆÿrs¹ÿÿûúÿ»§šÿÿðíÿêÛØÿÿöóÿ¾­ªÿůžÿй©ÿÝɼÿÿöóÿíÞÛÿöçäÿ¶¢™ÿ‡Œôÿ[`ãÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿŒŽëÿÿÿÿÿÿÿÿÿÿÿÿÿeiåÿOSáÿOSáÿOSáÿOSáÿ›îÿþþþÿþþþÿþþþÿknæÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿNSáÿGIÆÿ{|Àÿÿÿÿÿ±œÿÿöóÿíÞÛÿÿÿüÿµ¤¢ÿíœÿ¶Ÿ’üØÄ·ÿÿÿüÿòäÝÿíÞÙÿ²ž•ÿ–šôÿbgãÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿŒŽëÿÿÿÿÿÿÿÿÿÿÿÿÿeiåÿOSáÿOSáÿOSáÿOSáÿ´µòÿþþþÿþþþÿùùþÿZ^ãÿOSáÿOSáÿOSáÿOSáÿOSáÿOTáÿOSàÿGHÅÿ””Ëÿÿÿÿÿ°›ÿüíêÿáÒÏÿÿóðÿ¨˜—ÿÁ«šÿ½¦•ÆÓÀ³ÿÿÿþÿôêâÿÿþ÷ÿ¿¬ ÿžŸëÿotåÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿŒŽëÿÿÿÿÿÿÿÿÿÿÿÿÿeiåÿOSáÿOSáÿOSáÿPTâÿäåúÿþþþÿþþþÿÙÚøÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSàÿEHÁÿ·µÙÿöðêÿ¸¥™ÿÿþ÷ÿõêâÿÿÿÿÿ®£ ÿįò¿­žÿÿÿõÿõíäÿÿÿÿÿȶ§ÿ¦¤Øÿ…èÿQUáÿOSáÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿŒŽëÿÿÿÿÿÿÿÿÿÿÿÿÿeiåÿOSáÿOSáÿOSáÿ‡Šëÿþþþÿþþþÿþþþÿ“ìÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿMRÝÿHH½ÿßÛèÿÙÑÊÿÁ¯¡ÿÿÿúÿ÷ðçÿÿÿÿÿ­¢›ÿÁ«™¤Ì¸§{·¢‘ÿ÷ñçÿõðæÿÿÿÿÿá×Íÿ¦´ÿ–™ëÿZ_âÿOSáÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿŒìÿÿÿÿÿÿÿÿÿÿÿÿÿeiåÿOSáÿOSáÿy|èÿññüÿþþþÿþþþÿÈÉõÿQUâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿLP×ÿdcÅÿÿûöÿÁ³ªÿÜÒÈÿÿüòÿõðæÿÿÿÿÿ°ž‘ÿκ©{ØÇ¹3º£‘ÿÜÑÇÿóíæÿÿÿûÿÿüôÿ¸¥žÿ¨¨çÿsxåÿOTáÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿ[_ãÿÄÅõÿÿÿÿÿÿÿÿÿÿÿÿÿ¹ºóÿ²´òÿÔÕ÷ÿýýþÿþþþÿøøýÿ®¯ñÿTXâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿJNÐÿ™—Õÿøñëÿ´Ÿÿÿùðÿüöïÿöðéÿôéßÿ²™†ÿÜ˽3óêàÄ«˜Þɵ¤ÿôðéÿÿÿ÷ÿÿÿÿÿϹ¦ÿ±¨Äÿ—šêÿX\âÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿ’”ìÿÐÑ÷ÿÐÑ÷ÿÐÑ÷ÿÐÑ÷ÿÐÑ÷ÿÐÑ÷ÿËÍöÿ¹»óÿ—™íÿbeäÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿNRÞÿNPÈÿÏÈÚÿØÅ¸ÿÔ¾¬ÿÿÿÿÿ÷óëÿúöïÿÖ°ÿÅ­™ÞíãÚÕÀ°“À¦”ÿóíçÿü÷òÿÿÿÿÿöìãÿ¸¤¡ÿ±±èÿx|æÿPUáÿOTáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOTáÿLQØÿvr¿ÿØÈÁÿëšÿùïåÿÿúôÿóïéÿöðêÿ»¡ÿ똅ä×Í+¿¦”úÞÒÊÿøóïÿÿüøÿÿüøÿϽ´ÿ·¯Åÿ¨©ëÿbgãÿOTáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOTáÿOSáÿPTáÿPUàÿSUÍÿ¬Ÿ¬ÿÇ´©ÿÔøÿÿÿúÿõðìÿïêæÿßÒÊÿ³š‡úØÊ½+éÞÓűŸ²É¸¯ÿïéåÿ÷òïÿ÷òïÿïèãÿô°ÿÀ¾ãÿ™œêÿZ_âÿOSâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿNSáÿOTáÿTXáÿOSÛÿ‡¸ÿÁ±©ÿɹ±ÿìåàÿôïìÿîéæÿïéæÿ̼³ÿÁ¬œ²åÜÓÅ·ª-¼§—ûáÙÖÿñìêÿñìêÿñíêÿáÙÕÿÑÈÎÿÃÃíÿ’•éÿY^âÿOTáÿOSáÿOSáÿOSáÿNSáÿOSáÿOSáÿPTâÿPTâÿPTâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOTáÿVZáÿTYàÿvrÆÿ²¬ÿÒÆÁÿàÙÕÿîéçÿîéçÿîéçÿæßÛÿ¼§˜ûȸ«-­—„ŽÔÉÃÿìèæÿìèæÿìèçÿìèçÿèâáÿßÜèÿÇÈðÿ—šéÿ]câÿOTáÿOSáÿOSáÿOTâÿOTáÿOTáÿPTâÿPTâÿPTâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿPTáÿZ_âÿ^câÿomÏÿÁ²¯ÿâÜÚÿçâáÿìèçÿìèçÿìèæÿðìêÿàÖÐÿ­“~xÙÎŲœ‹ßòíæÿëæåÿêååÿêååÿêåäÿóîéÿìéïÿËÌðÿ¦¨ëÿmqäÿRWáÿOTáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿTXáÿchãÿhmäÿzxÎÿõ´ÿñëäÿóîêÿêæåÿêåäÿíèèÿñìëÿþùòÿ»¤Ò¯—‚ Ä´¦E¾«šõïéãÿïêæÿïêæÿïêæÿïêæÿêãÜÿòîíÿÔÓïÿ½¾îÿ’éÿbgãÿQVáÿNSàÿNSáÿOSáÿNSáÿOSáÿOSáÿOTáÿNTáÿOSáÿOSáÿOTáÿSWáÿbgãÿtyçÿuzäÿ”ŽÄÿÐþÿõïèÿêãÜÿïêæÿïêæÿòíéÿáÖÓÿûõïÿ˸§ô¤ˆr%¶¡’mɸ¨ÿãØÐÿïêæÿïêæÿïêæÿïêæÿÕÉÀÿôîçÿäáìÿÎÎïÿº»ïÿ—šêÿtxåÿ^câÿTYáÿPUáÿOSáÿOSáÿOSáÿQUàÿV[âÿ_dãÿptåÿ€…çÿ„‰èÿŽÖÿ¸¬»ÿåÜÒÿõðçÿÖÊÁÿïêæÿïêæÿïêæÿõðìÿîäÛÿׯ·û§‹uZøõô¿­ž™Ï¿°ýÚÎÄÿïêæÿïêæÿïêæÿïêæÿÝÈ»ÿâØÍÿóïêÿàÞëÿÍÍîÿÀÀïÿ±³ìÿ¡£êÿ’•éÿ‰èÿ‡‹èÿˆ‹éÿéÿ’•êÿ–™ìÿ–˜æÿœ™Ôÿ¸°ÄÿßÖÎÿöñçÿâØÍÿïêæÿïêæÿïêæÿïêæÿòíéÿã×ÌÿÛ̽ý£‡qn¸¥–ª’€‚ͼ¬þÝÒÆÿòíéÿïêæÿïêæÿïêæÿïêæÿïêæÿÜÑÃÿóîçÿêåèÿÛ×åÿËÉãÿÁ¿åÿ¹¸äÿµ³àÿ²°ßÿ±®Ûÿµ°ÔÿüÎÿÖÎÏÿìäÜÿôïæÿÝÒÄÿïêæÿïêæÿïêæÿïêæÿòíéÿõðìÿã×ÌÿÑÁ±ù¡‡qoŸ„pëáß¿«sÀ­žüàÖÏÿÓ½¬ÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿ̼²ÿÓÈÂÿß×ÔÿãÜÙÿâÛØÿâÛÖÿâÛ×ÿâÜØÿãÝÚÿߨÕÿÓÈÃÿÁ°¦ÿïêæÿïêæÿïêæÿïêæÿòíéÿõðìÿûöòÿàÖÏÿð¢ü£‹xdÇ´¤C¹¢Þξµÿ˺°ÿι¬ÿÙöÿòíéÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿòíéÿõðìÿ¿ªÿ˹°ÿѸÿ¶ŸÞƳ£CÒŹ¼¨—œÃ«šþǵ«ÿÓºÿÑÁ¹ÿõðìÿòíéÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿïêæÿòíéÿøóïÿͼ´ÿʸ­ÿ¶ŸŽþÀ«šœÎÀµÖËÀØÊ¿;±˜ƒ¥À¨—úƲ¦ÿÒûÿÜÏÊÿãØÔÿèßÜÿèàÝÿèßÜÿçßÜÿçßÜÿçßÜÿèßÜÿèßÜÿèàÝÿèßÜÿãØÕÿÙÌÇÿÒûÿƲ§ÿ· Žú±˜ƒ¥ÎÀ³;ÔÇ¿»©›ų¤+»¤’еœŠÝ¶ŸŽý¾©œÿ˺²ÿÖÉÂÿÞÒÍÿâØÓÿäÚÖÿäÚÖÿâ×ÓÿÞÒÍÿÖÈÃÿË»²ÿ¾ªÿ³œŒý´œ‰Ý¹¢ŠËº¬+»ª˜È·ª ǵ¦?²›‡t¶ Ž¶®•‚Ѹ¡ÿ¼¤’ÿº¡Žÿº¡Žÿ¼¤‘ÿÁª˜ÿ³š†Ñ°—ƒ©²›‡tʸª?ȸª ÿÿÿÿtQÿøÿtQÿàÿtQÿÀÿtQÿ€ÿtQþtQü?tQø?tQøtQðtQàtQàtQÀtQ€tQ€tQ€tQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQ€tQ€tQ€tQÀtQàtQàtQðtQøtQø?tQü?tQþÿtQÿ€ÿtQÿÀÿtQÿàÿtQÿøÿtQÿÿÿÿtQ¨ ÿÿÿÿ( @ Í»­½¦“k¼¥“µ³š†Ü´š†ÿ¯”ÿ¯”ÿ´š†ÿ´š†Ý¹ ¯Ã­›q˸©Í»­=¼¥”¯À©™úÙÈ»ÿðã×ÿÿ÷ìÿÿÿ÷ÿÿÿúÿÿÿúÿÿþóÿýôéÿìàÔÿÚÈ»ÿ¬œú¿¨–®Æ²¢7Ⱥ®³Ÿ¢¾¬ ÿÑúÿêàÖÿùïåÿùïåÿðæÜÿçÝÓÿêàÖÿðæÜÿóéßÿüòèÿÿûñÿÿþôÿýòèÿãÖÌÿÌ»¯ÿ½¨˜¢Ê»®¾ª›4Å´¥áÍÀ¸ÿ¼©œÿòíéÿþùõÿÙǹÿíàÕÿñèáÿíæáÿðéåÿóìèÿñéäÿôêãÿóæÛÿëÙËÿÿÿÿÿÿÿÿÿλ®ÿÙÌÃÿÈ·©á¸¥–4½¨—<ÔÆ·òÁ­œÿïêæÿïêæÿòíéÿåØÍÿÿüüÿÕÒìÿžžÑÿyz½ÿttºÿ{{¾ÿ˜—ËÿÌÊäÿÿÿÿÿÿÿÿÿÿúîÿÿÿÿÿÿÿÿÿÿÿþÿʶ¦ÿÏÀ²ò¡‡s4Á¯ 2Ú˾÷ʸªÿõðìÿïêæÿƵ§ÿàÛÝÿ‹ŠÁÿJL±ÿFJ¼ÿRYÉÿ\eÐÿ^hÒÿ[eÏÿRYÇÿEI¸ÿLN±ÿŒÆÿåÝãÿÿÿÿÿóâÕÿÿÿÿÿÿÿÿÿ̺­ÿͽ®ëŸ…nÙÌÂ̺®ÞèÞØÿõðìÿòíéÿÛÒÎÿ«¨ÌÿKL²ÿOTËÿjwÞÿz‹ãÿ~ãÿ}ãÿ}ãÿ}ãÿ~ãÿzŒãÿjvÜÿPUÇÿYZ¼ÿ¦œ¿ÿÿ÷öÿÿÿÿÿÿÿÿÿÿüøÿèÞØÿų¥ÞÅ´¤ÓÀ±¤úòìÿÿùóÿöðêÿâÚÕÿŒˆ¸ÿFH¾ÿakÜÿ{äÿ~åÿ~åÿ}äÿ}äÿ}äÿ}äÿ~äÿ~äÿ~äÿ{ãÿfpÝÿ]_Íÿ…µÿÜÏÍÿÿÿÿÿÿÿÿÿÿÿùÿîæáÿµŸžäÓÅ5âÐÅýÿüøÿ÷îêÿãØÒÿކ²ÿGJÆÿhtàÿ}äÿ~äÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ}äÿ}äÿ~åÿ}äÿ€’çÿz†ïÿfiÚÿŠ€ªÿȹ·ÿÿõðÿÿÿþÿðçãÿʹ®ý´¢“/ÛÆ¶°ïáÛÿ÷ëçÿã×Òÿ°¢°ÿJLÅÿclàÿ}äÿ}äÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ}äÿƒ•éÿtíÿln×ÿ—‰žÿÜÌÄÿõèäÿëßÛÿÚÌÆÿ¸¤”°éÞÕÚ³üêÜØÿäÖÓÿŲ©ÿda¼ÿU[Ýÿ|ãÿ}äÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ~åÿ}äÿ}ãÿ‘æÿfkåÿpo»ÿ£–‘ÿæÓÊÿêÝÙÿÞÐÌÿÁªšúÐÆ¼É´£iÞÊÁÿÞÏÌÿÕÆÃÿ£”¦ÿLP×ÿlyâÿ~äÿ~åÿ~åÿ~åÿ˜¥êÿìïûÿòôüÿñóüÿíïûÿèëúÿÐÖõÿŸ«ëÿ~åÿ~åÿ~åÿ}äÿ}äÿs€çÿ[]Ïÿ‚’ÿÙŹÿíÞÛÿçØÕÿÒ¿µÿÉ´¤iÖĵ«ãÕÑÿäÕÒÿÕÈÄÿŽÙÿRWàÿ{Œãÿ~äÿ~åÿ~åÿ~åÿ~åÿÉÐôÿÿÿÿÿÞãøÿ~åÿœèÿÜà÷ÿþþþÿ¿Çòÿ~åÿ~åÿ~åÿ}äÿ{ãÿRWÔÿog›ÿÒÁ´ÿèÚ×ÿíÞÛÿÝÎËÿ×ĵ«áÐÃ×íÞÛÿäÕÒÿÜÏÌÿqsåÿ]fâÿ}äÿ~äÿ~åÿ~åÿ~åÿ~åÿÆÎóÿÿÿÿÿÞãøÿ~åÿ~åÿˆ—çÿúûþÿþþþÿš§êÿ~åÿ~åÿ~äÿ~äÿ_gßÿZX°ÿɲ¢ÿëßÜÿíÞÛÿçØÕÿÛʾÜÔ½¬ÿÿöóÿðáÞÿȲ¥ÿhméÿdoâÿ}äÿ}äÿ~äÿ~äÿ~åÿ~åÿÆÎóÿÿÿÿÿÞãøÿ~åÿ~åÿ~åÿÜàøÿÿÿÿÿÈÐôÿ~åÿ~åÿ}äÿ~äÿfqáÿHJ¶ÿ¼ª¦ÿÕ¿°ÿöçäÿùêçÿÁª™ÿÖ¾­ÿÿÿÿÿÿðíÿй®ÿtyñÿV]áÿcnâÿeqãÿfqãÿgrãÿjvãÿjvãÿ¾ÃóÿÿÿÿÿÚÝøÿkwãÿkxãÿlxãÿÄÉôÿÿÿÿÿÚÞøÿn|ãÿsäÿp~ãÿrãÿ^gâÿBEºÿźÀÿÒ»­ÿüíêÿÿùöÿ¾¦•ÿÕ½¬ÿÿÿÿÿÿöóÿ̶«ÿ…öÿNSáÿOSáÿOSáÿPTâÿPTâÿPTâÿPTâÿ²´òÿÿÿÿÿÓÔ÷ÿPTâÿPTâÿPTâÿ¸ºóÿÿÿÿÿØÙøÿOSáÿVZâÿOSáÿOSáÿNSáÿCE¼ÿáÝæÿη©ÿÿðíÿÿùöÿ´›‹ÿȰ ÿÿÿÿÿÿÿüÿȲ§ÿ“—ûÿPTáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿ²´òÿÿÿÿÿÓÔ÷ÿPTâÿPTâÿPTâÿÈÉõÿÿÿÿÿÌÍöÿPTâÿPTâÿPTâÿPTâÿOSáÿHJ¾ÿóðòÿÁ«ÿÿöðÿÿöðÿ­•„ÿìšòÿÿÿÿÿÿÿÿÒ¾¯ÿž îÿTYâÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿ²´òÿÿÿÿÿÓÔ÷ÿPTâÿPTâÿVZãÿóóýÿÿÿÿÿ ¢ïÿPTâÿPTâÿPTâÿPTâÿOSàÿ\]ÄÿôïèÿÌ·¨ÿÿÿÿÿÿ÷ðÿ´‹ô»§—«ÿ÷íÿÿÿÿÿïçÝÿ£ŸÌÿgkäÿOSáÿPTâÿPTâÿPTâÿPTâÿPTâÿ²´òÿÿÿÿÿÓÔ÷ÿPTâÿRVâÿ¹»óÿÿÿÿÿæçúÿY]ãÿPTâÿPTâÿPTâÿPTâÿMRÜÿŽŒÔÿá×ÎÿñéàÿÿÿÿÿèßÖÿ­™‰«Í¸§iâÒÃÿÿÿÿÿÿÿùÿ¥•œÿŠŽèÿPUáÿOSáÿPTâÿPTâÿPTâÿilæÿååúÿÿÿÿÿòòüÿÊÌöÿëëûÿ÷÷ýÿ¾¿ôÿ`däÿPTâÿPTâÿPTâÿOSáÿOSáÿKOÔÿÇÃäÿÁ®žÿÿÿÿÿÿÿÿÿÄ´¦ÿ·¢iëàÕŬ˜üÿÿýÿÿûõÿǶ¨ÿ¬©ÙÿeiãÿOSáÿPTâÿPTâÿPTâÿY]ãÿknæÿknæÿknæÿknæÿeiåÿRVâÿPTâÿPTâÿPTâÿPTâÿOSáÿOSáÿOSàÿ``ÇÿÌ»µÿо°ÿÿÿÿÿÿûôÿ¯–‚ú˼°̶¦°îãÜÿûöòÿðêåÿ½°¶ÿŸ¡éÿUZâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿOSáÿOTáÿPTáÿOSÛÿ’±ÿÀ®¤ÿíæáÿûöòÿßÔÎÿµŸŽ°Ôõ5ͽ²ýöñïÿúõóÿèàÜÿÌÇÞÿ’•êÿTXáÿOSáÿOSáÿOSáÿOSáÿOTáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿOSáÿPTáÿUYáÿzÂÿʼ¶ÿß×ÓÿîéçÿðëèÿÅ´ªýÀ¯¡5òíêÿøôóÿû÷öÿóîíÿÙÙòÿ˜›êÿY]âÿOTáÿOTáÿOTáÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿPTâÿOSáÿSWáÿ_dâÿyvÌÿÖÌÈÿêåäÿìèçÿìèçÿêåáÿ©’€‹ÞÐÆϾ®Þñêæÿþùõÿþùõÿöïéÿçäôÿ´¶ðÿswåÿRWáÿOSáÿOSáÿOSáÿOSáÿOTáÿOSáÿOSáÿQUáÿ_dãÿquäÿ’ŒÉÿàÖÑÿëäÝÿìèçÿìèçÿìèçÿÀ®Ò¬• ı¢2ÕÅ·÷ÙËÂÿþùõÿøôóÿòîíÿîééÿÓÒîÿ®¯íÿ…ˆçÿjnäÿ\aãÿY]âÿ[_ãÿdhãÿswåÿƒ‡çÿ‘‘ÙÿÁ¸ÈÿìäÛÿÔÆ¼ÿòîíÿòîíÿйÿɸ©ë›i(¹¤“<ØÈ¹òѾ°ÿþùõÿõñðÿïëêÿìèçÿèãäÿÛØêÿÈÆæÿ¸·çÿ¯¯åÿ¬«ãÿ­«Ýÿ¸´ØÿÐÉÔÿìäÛÿ×ɺÿûöòÿÿüøÿÿÿûÿ˸ªÿÌ»«ç›€j4İ¢4˺¬áɸ­ÿøóïÿòíéÿïêæÿïêæÿìèçÿÍÀ¹ÿÔÉÃÿ×ÍÇÿ×ÍÇÿÔÊÄÿÍÀ¹ÿïëêÿøóïÿþùõÿÿÿûÿÿÿþÿÒÁ¶ÿÈ·©á ˆu,ÖÆ»Á¬›¢Å±¤ÿÉ·®ÿøóïÿøóïÿøóïÿøóïÿøóïÿøóïÿøóïÿøóïÿøóïÿûöòÿÿüøÿÿÿþÿØÆ½ÿκ­ÿÁ¬œ¢Í½°Ê·¨7º£‘®»¦˜úο¶ÿÝÑÌÿæÝÙÿëäâÿíçåÿíæåÿëäâÿæÝÙÿàÔÏÿÔŽÿį¡ú¼¦•®Â°Ÿ7Ų£º¥“q¶ŸŽ¯¸¢’Ü»¦˜ÿ¹£”ÿ¹£”ÿ»¦˜ÿ¸¢’ݲ›‰©º¤’q®ŸÿÀÿÿÿü?øðàÀÀ€€€€ÀÀàðøü?ÿÿÿÀÿˆ ÿÿÿÿ(0 µ -«“€…µžŒÎ»¥“ó½§•ÿº¤’ÿµŸŽó­–„Ê«“‰´ŸŽ-¹¥–-»§š»Í¼°þéÞÓÿþ÷íÿþöíÿÿùïÿÿùïÿÿùïÿøðæÿàÕÊÿÁ°¤þµ¡“·¸¥•-ïãß¼©šm̽²÷Ó¶ÿÿÿÿÿÿÿÿÿ÷ëáÿùðèÿÿ÷ñÿÿ÷ñÿÿõîÿòåÛÿÿüøÿõðìÿij§ÿ̽²÷¯ mäßÙøøõñ¡†Î½®ÿÿÿûÿÿÿÿÿúêÞÿðëùÿµ´åÿƒƒÌÿzzËÿ‚‚Ïÿ§§ßÿàÝöÿÿÿúÿåÖÉÿÿüøÿÿüøÿÒÀ²ÿ»§•{¿­ŸjàÔÊÿÿÿþÿÿÿÿÿñêõÿ““àÿflÛÿs~åÿzˆèÿ~Žëÿ{Šéÿt€ãÿhoÚÿqrÌÿƾÙÿÿÿúÿÿÿÿÿÿÿÿÿàÓÊþ´Ÿ^±¢-ÛÏÆ÷ÿùóÿÿÿúÿÕÏéÿjlÚÿtéÿ€‘çÿ}äÿ}äÿ}äÿ}äÿ}äÿƒ•êÿíÿlqßÿŸ˜Çÿÿÿÿÿÿÿÿÿÿÿÿÿ×ËÂ÷¬–‚*À­Ÿ¶èÝÙÿôêåÿɾÐÿceÛÿ~Œîÿ€’çÿ~äÿ~åÿ}Žåÿ~åÿ~åÿ}äÿ~åÿ€’çÿ‡˜ñÿzñÿ‘‡±ÿüîêÿÿÿÿÿñçâÿ¾«³Ç´¦/Ô·þîáÝÿÔÄÀÿdcÉÿp|çÿ€’çÿ}åÿ~åÿ~åÿ}äÿ~åÿ~åÿ~åÿ~åÿ}äÿ}äÿ„”ñÿtvãÿœ‘ÿýìåÿñäàÿÑ¿´þ¿­,Àªš…ßÍÇÿìÜØÿ¤˜½ÿU\Ýÿ}Žäÿ~äÿ~ŽåÿŒ›çÿÒØöÿÕÛöÿÑ×õÿËÒôÿ«¶îÿåÿ~åÿ}äÿ}äÿoxçÿmi§ÿͺ¯ÿãÓÏÿØÇÁÿßÏÄÇíÞÛÿæØÔÿ‚‚âÿhtâÿ~äÿ~åÿ}Žåÿ~åÿÖÛöÿþþþÿ†–æÿ‘ŸèÿíïûÿÚß÷ÿåÿ~åÿ}äÿ}ëÿTUÁÿı¦ÿáÒÏÿɸµÿàÐÅÇ̺²ðíÞÛÿØÉÆÿ\`Þÿt‚äÿ~äÿ~åÿ}äÿ~åÿÔÚöÿþþþÿ†–æÿ~åÿ±»ïÿÿÿÿÿ¦²íÿ~åÿ~äÿ…–íÿW\Õÿ¨˜¢ÿäÕÒÿêÛØÿÒÀ¸ôÁ¬£ÿÿóðÿØÉÆÿ`eäÿdoâÿkxãÿkxãÿn{ãÿo|äÿÏÔöÿÿÿÿÿy…åÿp}äÿŽ™éÿÿÿÿÿ¾Åòÿs‚äÿs‚äÿz‰éÿ[`Þÿ”²ÿçØÕÿðáÞÿ¸£šÿµ ˜ÿòâÜÿ̽ºÿjoæÿOSáÿOSáÿOSáÿOSáÿOSáÿÅÆõÿþþþÿZ^ãÿPTâÿswçÿþþþÿµ·òÿOSáÿOSáÿRVäÿTWÜÿ±¯ÏÿêÛØÿóäáÿ¥ˆÿ¬™’ðÿóìÿÀ±®ÿx|áÿOSáÿOSáÿOSáÿOSáÿOSáÿÅÆõÿþþþÿZ^ãÿOSâÿŽìÿþþþÿŸ¡ïÿPTáÿOSâÿOSáÿMPÔÿ¹¶ÉÿÛÌÉÿáÒÏÿ‹ƒô«šÇÿÿöÿÛÓËÿ‘ÐÿX]çÿOSáÿOSáÿOSáÿOSáÿÅÇõÿþþþÿZ^ãÿZ^ãÿÝÞùÿññüÿ`däÿPTâÿPTâÿOSáÿQSÍÿÍÅÃÿÝÖÍÿÿÿöÿ¡ƒÇ±›‰…æÜÑÿÿûóÿª®ÿuzíÿOSáÿOSáÿOSáÿcfåÿÙÚøÿçèûÿÃÄõÿÕÖøÿ¼½óÿhlæÿPTâÿPTâÿOSáÿOSàÿ{zÍÿº©œÿúõíÿãÙÎÿ§‘…ñ£/ǵ©þþúõÿ×ÊÄÿ®­ìÿW\äÿOSáÿOSáÿOSáÿOSáÿOSáÿOSáÿOSâÿPTáÿOSâÿOSâÿOSáÿOSáÿPTÙÿ¨›­ÿÑøÿøôïÿij¦þ¶¢‘,¼ªœ¶ðêçÿòíêÿÓËÔÿ•˜ìÿRVáÿOSáÿOSáÿOSáÿOSáÿOSáÿPTâÿPTâÿPTâÿPTâÿOSáÿSXáÿ…ÁÿÔÇÁÿõðíÿíçäÿ¸¦˜¶¶£’*ÙÏÇ÷úöõÿü÷öÿçåòÿ™œêÿW\âÿOSáÿOTáÿOSáÿOSáÿPTâÿPTâÿPTâÿPTáÿ]bâÿ…‚Ðÿ÷ïëÿÿÿÿÿûöõÿØÎÅôŸ…q ¾¬œjûðçÿÿûôÿÿýöÿÿùüÿ¿Àìÿ„çÿ\`âÿPUáÿOSáÿOTáÿUYâÿeiäÿz}âÿª¤Íÿðçßÿûîçÿ÷éâÿåÚÒþ­–ƒ]øõôÑ¿¯†ûëßÿÿÿÿÿÿÿÿÿÛ̾ÿâÝäÿÍÌêÿ°°çÿ ¡åÿžžãÿ¨§Þÿ½¹ÙÿàØÕÿÖÆ·ÿÿÿþÿÿÿÿÿÜÍÀý±›ˆwëáß½ª›mÜʾ÷ÿÿÿÿÿÿÿÿøóïÿòíéÿïêæÿïêæÿïêæÿïêæÿïêæÿøóïÿþùõÿÁª›ÿǵ¨÷¸¤”i¾«›-¼§˜·Å²§þÒüÿÚÎÉÿøóïÿøóïÿøóïÿõðìÿÕÈÃÿÒýÿȵªþį ·Á®Ÿ-¿ª™-¹£“‰¿«ÊÆ´¨óɸ¬ÿɸ¬ÿñ¥ó·¢”dzŒ‰·¢‘-þAøAàAÀAÀA€A€AAAAAAAAAAA€A€AÀAÀAàAøAþAh ÿÿÿÿ(  ¹¤”;¿«›ŸÐ¿°äÓ³ÿÓóÿͼ¬â½©š¡³Œ9İ¡ ÔÄ·¥Ð¾²ÿþùõÿþùõÿûöòÿþùõÿÿüøÿèÙÍÿâÐÄÿ×Ǻ¥Á®Ÿ ¾¬ ØÈºÉƯÿþùõÿ«§Ëÿ~€ÌÿjoÆÿquÉÿ™™ÔÿâÛæÿÿÿÿÿÒ»©ÿÒÀ±Ä¥‹tÔÆ»¥ôìåÿÕÌÔÿmpÌÿmzÜÿ}Žäÿ}äÿ}äÿ{‹åÿksÙÿ¦ŸÏÿÿÿÿÿôìåÿÐÀµ£¾«›9ÝÐÉþØÌÌÿabÇÿxˆãÿ~äÿ~åÿ~åÿ}äÿ}äÿ}äÿ†‘øÿ‡~§ÿôçâÿãÖÏþ¹¥•8­ ¡ÐÁ½ÿކÁÿn|âÿ}äÿ„”æÿÿÿÿÿÿÿÿÿÿÿÿÿ†–æÿ}äÿ‰›ðÿ„ëÿÚÊÈÿèÙÕÿÐÀ¸à;»ÿwzêÿ}Žäÿ~åÿ~åÿÿÿÿÿ®¹îÿ›¨ëÿÿÿÿÿ…•æÿ~äÿ€Œôÿ°¤¿ÿðáÞÿÖŽáݪÿØÉÆÿfmèÿqãÿr€äÿt‚äÿÿÿÿÿ¨±îÿtƒäÿÿÿÿÿ¤®íÿx‡äÿs€éÿˆ‚»ÿíÞÛÿÀ¬¦ÿǵ®ÿÒÃÀÿchäÿOSáÿPTâÿPTâÿÿÿÿÿ‘”ìÿPTâÿÿÿÿÿ‘“ìÿQUâÿRVäÿ–•ÓÿäÕÒÿ»¨¡ÿáÓÉàÏÀ½ÿuwÖÿOSáÿPTâÿPTâÿÿÿÿÿ‘”ìÿlpæÿÿÿÿÿfjåÿPTâÿOSàÿ¡ÄÿéàÙÿ̾´áË·¦¡ÿÿøÿ£›¼ÿUYâÿPTâÿX\ãÿÿÿÿÿÿÿÿÿÿÿÿÿorçÿPTâÿOSáÿRU×ÿ¼®­ÿþùòÿ¸£’ŸË·§9ùïéÿâÙØÿ”•äÿPUáÿOSáÿOSáÿPTâÿPTâÿPTâÿOSáÿQUáÿ“ÇÿèÞÙÿäÚÔÿ³ŸŽ9ðâ×£ÿù÷ÿëæéÿ ¢êÿY]âÿOSáÿOSáÿOSáÿPTáÿ\aâÿ›˜Ûÿôìéÿóíëÿ̽±šÐ½® èØËÉ×µÿÿÿþÿ×Óåÿ¤¥çÿ‡‰äÿ†‡áÿ£¢áÿÒÊÚÿÿÿÿÿι¬ÿν¯Á¡…o dz¥ ÖĶ¥Ó½¯ÿÿÿþÿøóïÿõðìÿõðìÿþùõÿÿÿÿÿÓ½¯ÿÊ·ª¥£‹x ¾¨—9ɵ©¡Î¾´âйÿйÿÐÀ¶áλ®¡¿ª™9ð¬AÀ¬A€¬A€¬A¬A¬A¬A¬A¬A¬A¬A¬A€¬A€¬AÀ¬Að¬AL0ÿÿMAINICON L00 ¨%  ¨ ˆ  hthrift-0.23.0/lib/delphi/test/serializer/SimpleException.thrift0000664000175000017500000000215615165535636025076 0ustar00buildbuild00000000000000/* * 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 thrift-0.23.0/lib/delphi/test/serializer/SerializerData.dpr0000664000175000017500000000563715165535636024165 0ustar00buildbuild00000000000000library SerializerData; (* * 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. *) uses Classes, Windows, SysUtils, Generics.Collections, Thrift in '..\..\src\Thrift.pas', Thrift.Exception in '..\..\src\Thrift.Exception.pas', Thrift.Socket in '..\..\src\Thrift.Socket.pas', Thrift.Transport in '..\..\src\Thrift.Transport.pas', Thrift.Protocol in '..\..\src\Thrift.Protocol.pas', Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas', Thrift.Protocol.Compact in '..\..\src\Thrift.Protocol.Compact.pas', Thrift.Collections in '..\..\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\src\Thrift.Configuration.pas', Thrift.Server in '..\..\src\Thrift.Server.pas', Thrift.Utils in '..\..\src\Thrift.Utils.pas', Thrift.Serializer in '..\..\src\Thrift.Serializer.pas', Thrift.Stream in '..\..\src\Thrift.Stream.pas', Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas', Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', System_ 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'; {$R *.res} function CreateOneOfEach : IOneOfEach; stdcall; begin result := Fixtures.CreateOneOfEach; end; function CreateNesting : INesting; stdcall; begin result := Fixtures.CreateNesting; end; function CreateHolyMoley : IHolyMoley; stdcall; begin result := Fixtures.CreateHolyMoley; end; function CreateCompactProtoTestStruct : ICompactProtoTestStruct; stdcall; begin result := Fixtures.CreateCompactProtoTestStruct; end; function CreateBatchGetResponse : IBatchGetResponse; stdcall; begin result := Fixtures.CreateBatchGetResponse; end; function CreateSimpleException : IError; stdcall; begin result := Fixtures.CreateSimpleException; end; exports CreateOneOfEach, CreateNesting, CreateHolyMoley, CreateCompactProtoTestStruct, CreateBatchGetResponse, CreateSimpleException; begin IsMultiThread := TRUE; ASSERT( cDebugProtoTest_Option_COM_types); ASSERT( cSystem__Option_COM_types); end. thrift-0.23.0/lib/delphi/test/serializer/TestSerializer.dproj0000664000175000017500000001526315165535636024560 0ustar00buildbuild00000000000000 {9282EDD8-7C12-41B0-8172-61C6BFA6E238} TestSerializer.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication TestSerializer.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 True 12 thrift-0.23.0/lib/delphi/test/serializer/TestSerializer.Tests.pas0000664000175000017500000004375615165535636025336 0ustar00buildbuild00000000000000unit TestSerializer.Tests; (* * 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. *) interface uses Classes, Windows, SysUtils, Generics.Collections, Thrift, Thrift.Exception, Thrift.Socket, Thrift.Transport, Thrift.Protocol, Thrift.Protocol.JSON, Thrift.Protocol.Compact, Thrift.Collections, Thrift.Configuration, Thrift.Server, Thrift.Utils, Thrift.Serializer, Thrift.Stream, Thrift.WinHTTP, Thrift.TypeRegistry, System_, test.ExceptionStruct, test.SimpleException, DebugProtoTest; {$TYPEINFO ON} type TFactoryPair = record proto : IProtocolFactory; trans : ITransportFactory; end; TTestSerializer = class //extends TestCase { private type TMethod = ( mt_Bytes, mt_Stream ); strict private FProtocols : TList< TFactoryPair>; procedure AddFactoryCombination( const aProto : IProtocolFactory; const aTrans : ITransportFactory); class function UserFriendlyName( const factory : TFactoryPair) : string; overload; class function UserFriendlyName( const method : TMethod) : string; overload; class function Serialize(const input : IBase; const factory : TFactoryPair) : TBytes; overload; class procedure Serialize(const input : IBase; const factory : TFactoryPair; const aStream : TStream); overload; class procedure Deserialize( const input : TBytes; const target : IBase; const factory : TFactoryPair); overload; class procedure Deserialize( const input : TStream; const target : IBase; const factory : TFactoryPair); overload; class procedure Deserialize( const input : TBytes; out target : TGuid; const factory : TFactoryPair); overload; class procedure ValidateReadToEnd( const serial : TDeserializer); overload; class function LengthOf( const bytes : TBytes) : Integer; overload; inline; class function LengthOf( const bytes : IThriftBytes) : Integer; overload; inline; class function DataPtrOf( const bytes : TBytes) : Pointer; overload; inline; class function DataPtrOf( const bytes : IThriftBytes) : Pointer; overload; inline; procedure Test_Serializer_Deserializer; procedure Test_COM_Types; 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); procedure Test_ProtocolConformity( const factory : TFactoryPair; const stream : TFileStream); procedure Test_UuidDeserialization( const factory : TFactoryPair; const stream : TFileStream); public constructor Create; destructor Destroy; override; procedure RunTests; end; implementation const SERIALIZERDATA_DLL = 'SerializerData.dll'; 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 } constructor TTestSerializer.Create; begin inherited Create; FProtocols := TList< TFactoryPair>.Create; AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, nil); AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, nil); AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, nil); AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create); AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create); AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create); AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create); AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create); AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create); end; destructor TTestSerializer.Destroy; begin try FreeAndNil( FProtocols); finally inherited Destroy; end; end; procedure TTestSerializer.AddFactoryCombination( const aProto : IProtocolFactory; const aTrans : ITransportFactory); var rec : TFactoryPair; begin rec.proto := aProto; rec.trans := aTrans; FProtocols.Add( rec); end; class function TTestSerializer.LengthOf( const bytes : TBytes) : Integer; begin result := Length(bytes); end; class function TTestSerializer.LengthOf( const bytes : IThriftBytes) : Integer; begin if bytes <> nil then result := bytes.Count else result := 0; end; class function TTestSerializer.DataPtrOf( const bytes : TBytes) : Pointer; begin result := bytes; end; class function TTestSerializer.DataPtrOf( const bytes : IThriftBytes) : Pointer; begin if bytes <> nil then result := bytes.QueryRawDataPtr else result := nil; end; procedure TTestSerializer.Test_ProtocolConformity( const factory : TFactoryPair; const stream : TFileStream); begin Test_UuidDeserialization( factory, stream); // add more tests here end; procedure TTestSerializer.Test_UuidDeserialization( const factory : TFactoryPair; const stream : TFileStream); function CreateGuidBytes : TBytes; var obj : TObject; i : Integer; begin obj := factory.proto as TObject; if obj is TJSONProtocolImpl.TFactory then begin result := TEncoding.UTF8.GetBytes('"00112233-4455-6677-8899-aabbccddeeff"'); Exit; end; if (obj is TBinaryProtocolImpl.TFactory) or (obj is TCompactProtocolImpl.TFactory) then begin SetLength(result,16); for i := 0 to Length(result)-1 do result[i] := (i * $10) + i; Exit; end; raise Exception.Create('Unhandled case'); end; var tested, correct : TGuid; bytes : TBytes; begin // write bytes := CreateGuidBytes(); // init + read Deserialize( bytes, tested, factory); // check correct := TGuid.Create('{00112233-4455-6677-8899-aabbccddeeff}'); ASSERT( tested = correct); end; procedure TTestSerializer.Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); var tested, correct : IOneOfEach; bytes : TBytes; i : Integer; begin // write tested := CreateOneOfEach; 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 tested := TOneOfEachImpl.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 := CreateOneOfEach; ASSERT( tested.Im_true = correct.Im_true); ASSERT( tested.Im_false = correct.Im_false); ASSERT( tested.A_bite = correct.A_bite); ASSERT( tested.Integer16 = correct.Integer16); ASSERT( tested.Integer32 = correct.Integer32); ASSERT( tested.Integer64 = correct.Integer64); ASSERT( Abs( tested.Double_precision - correct.Double_precision) < 1E-12); ASSERT( tested.Some_characters = correct.Some_characters); ASSERT( tested.Zomg_unicode = correct.Zomg_unicode); ASSERT( tested.Rfc4122_uuid = correct.Rfc4122_uuid); ASSERT( tested.What_who = correct.What_who); ASSERT( LengthOf(tested.Base64) = LengthOf(correct.Base64)); ASSERT( CompareMem( DataPtrOf(tested.Base64), DataPtrOf(correct.Base64), LengthOf(correct.Base64))); ASSERT( tested.Byte_list.Count = correct.Byte_list.Count); for i := 0 to tested.Byte_list.Count-1 do ASSERT( tested.Byte_list[i] = correct.Byte_list[i]); ASSERT( tested.I16_list.Count = correct.I16_list.Count); for i := 0 to tested.I16_list.Count-1 do ASSERT( tested.I16_list[i] = correct.I16_list[i]); ASSERT( tested.I64_list.Count = correct.I64_list.Count); for i := 0 to tested.I64_list.Count-1 do ASSERT( tested.I64_list[i] = correct.I64_list[i]); end; procedure TTestSerializer.Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream); var tested, correct : ICompactProtoTestStruct; bytes : TBytes; begin // write tested := CreateCompactProtoTestStruct; 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 := TCompactProtoTestStructImpl.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 := CreateCompactProtoTestStruct; ASSERT( correct.Field500 = tested.Field500); ASSERT( correct.Field5000 = tested.Field5000); ASSERT( correct.Field20000 = tested.Field20000); 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; method : TMethod; begin stream := TFileStream.Create( 'TestSerializer.dat', fmCreate); try for method in [Low(TMethod)..High(TMethod)] do begin Writeln( UserFriendlyName(method)); for factory in FProtocols do begin Writeln('- '+UserFriendlyName(factory)); // protocol conformity tests if (method = TMethod.mt_Bytes) and (factory.trans = nil) then Test_ProtocolConformity( factory, stream); // normal objects Test_OneOfEach( method, factory, stream); Test_CompactStruct( method, factory, stream); Test_ExceptionStruct( method, factory, stream); Test_SimpleException( method, factory, stream); end; Writeln; end; finally stream.Free; end; end; class function TTestSerializer.UserFriendlyName( const factory : TFactoryPair) : string; begin result := Copy( (factory.proto as TObject).ClassName, 2, MAXINT); if factory.trans <> nil then result := Copy( (factory.trans as TObject).ClassName, 2, MAXINT) +' '+ result; result := StringReplace( result, 'Impl', '', [rfReplaceAll]); result := StringReplace( result, 'Transport.TFactory', '', [rfReplaceAll]); result := StringReplace( result, 'Protocol.TFactory', '', [rfReplaceAll]); end; class function TTestSerializer.UserFriendlyName( const method : TMethod) : string; const NAMES : array[TMethod] of string = ('TBytes','Stream'); begin result := NAMES[method]; end; procedure TTestSerializer.Test_COM_Types; var tested : IOneOfEach; begin {$IF cDebugProtoTest_Option_COM_types} ASSERT( SizeOf(TSomeEnum) = SizeOf(Int32)); // -> MINENUMSIZE 4 // try to set values that allocate memory tested := CreateOneOfEach; tested.Zomg_unicode := 'This is a test'; tested.Base64 := TThriftBytesImpl.Create( TEncoding.UTF8.GetBytes('abc')); {$IFEND} 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); Write('Hit ENTER to close ... '); Readln; end; end; end; class function TTestSerializer.Serialize(const input : IBase; const factory : TFactoryPair) : TBytes; var serial : TSerializer; config : IThriftConfiguration; begin config := TThriftConfigurationImpl.Create; //config.MaxMessageSize := 0; // we don't read anything here serial := TSerializer.Create( factory.proto, factory.trans, config); try result := serial.Serialize( input); finally serial.Free; end; end; class procedure TTestSerializer.Serialize(const input : IBase; const factory : TFactoryPair; const aStream : TStream); var serial : TSerializer; config : IThriftConfiguration; begin config := TThriftConfigurationImpl.Create; //config.MaxMessageSize := 0; // we don't read anything here serial := TSerializer.Create( factory.proto, factory.trans, config); try serial.Serialize( input, aStream); finally serial.Free; end; end; class procedure TTestSerializer.Deserialize( const input : TBytes; const target : IBase; const factory : TFactoryPair); var serial : TDeserializer; config : IThriftConfiguration; begin config := TThriftConfigurationImpl.Create; config.MaxMessageSize := Length(input); serial := TDeserializer.Create( factory.proto, factory.trans, config); try serial.Deserialize( input, target); ValidateReadToEnd( serial); finally serial.Free; end; end; class procedure TTestSerializer.Deserialize( const input : TStream; const target : IBase; const factory : TFactoryPair); var serial : TDeserializer; config : IThriftConfiguration; begin config := TThriftConfigurationImpl.Create; config.MaxMessageSize := input.Size; serial := TDeserializer.Create( factory.proto, factory.trans, config); try serial.Deserialize( input, target); ValidateReadToEnd( serial); finally serial.Free; end; end; class procedure TTestSerializer.Deserialize( const input : TBytes; out target : TGuid; const factory : TFactoryPair); var serial : TDeserializer; config : IThriftConfiguration; begin config := TThriftConfigurationImpl.Create; config.MaxMessageSize := Length(input); serial := TDeserializer.Create( factory.proto, factory.trans, config); try serial.Stream.Write(input[0], Length(input)); serial.Stream.Position := 0; serial.Transport.ResetMessageSizeAndConsumedBytes(); // size has changed target := serial.Protocol.ReadUuid; finally serial.Free; end; end; class procedure TTestSerializer.ValidateReadToEnd( const serial : TDeserializer); // we should not have any more byte to read var dummy : IBase; begin try dummy := TOneOfEachImpl.Create; serial.Deserialize( nil, dummy); raise EInOutError.Create('Expected exception not thrown?'); except on e:TTransportException do {expected}; on e:Exception do raise; // unexpected end; end; end. thrift-0.23.0/lib/delphi/test/server.dpr0000664000175000017500000000476315165535636020416 0ustar00buildbuild00000000000000(* * 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. *) program server; {$APPTYPE CONSOLE} uses SysUtils, 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', Thrift.Transport in '..\src\Thrift.Transport.pas', Thrift.Socket in '..\src\Thrift.Socket.pas', Thrift.Transport.Pipes in '..\src\Thrift.Transport.Pipes.pas', Thrift.Protocol in '..\src\Thrift.Protocol.pas', Thrift.Protocol.JSON in '..\src\Thrift.Protocol.JSON.pas', Thrift.Protocol.Compact in '..\src\Thrift.Protocol.Compact.pas', Thrift.Protocol.Multiplex in '..\src\Thrift.Protocol.Multiplex.pas', Thrift.Processor.Multiplex in '..\src\Thrift.Processor.Multiplex.pas', Thrift.Collections in '..\src\Thrift.Collections.pas', Thrift.Configuration in '..\src\Thrift.Configuration.pas', Thrift.Server in '..\src\Thrift.Server.pas', Thrift.TypeRegistry in '..\src\Thrift.TypeRegistry.pas', Thrift.Utils in '..\src\Thrift.Utils.pas', Thrift.WinHTTP in '..\src\Thrift.WinHTTP.pas', Thrift.Stream in '..\src\Thrift.Stream.pas'; var nParamCount : Integer; args : array of string; i : Integer; arg : string; begin try Writeln( 'Delphi TestServer '+Thrift.Version); nParamCount := ParamCount; SetLength( args, nParamCount); for i := 1 to nParamCount do begin arg := ParamStr( i ); args[i-1] := arg; end; TTestServer.Execute( args ); except on E: EAbort do begin ExitCode := $FF; end; on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := $FF; end; end; end. thrift-0.23.0/lib/delphi/test/typeregistry/0000775000175000017500000000000015165535636021141 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/typeregistry/TestTypeRegistry.dproj0000664000175000017500000001444515165535636025523 0ustar00buildbuild00000000000000 {D6B3910D-CD64-449F-B7A6-404D5DF1DAC5} TestTypeRegistry.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication TestTypeRegistry.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 True 12 thrift-0.23.0/lib/delphi/test/typeregistry/TestTypeRegistry.dpr0000664000175000017500000000372515165535636025171 0ustar00buildbuild00000000000000(* * 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. *) program TestTypeRegistry; {$APPTYPE CONSOLE} uses Classes, Windows, SysUtils, Generics.Collections, TypInfo, Thrift in '..\..\src\Thrift.pas', Thrift.Transport in '..\..\src\Thrift.Transport.pas', Thrift.Exception in '..\..\src\Thrift.Exception.pas', Thrift.Socket in '..\..\src\Thrift.Socket.pas', Thrift.Protocol in '..\..\src\Thrift.Protocol.pas', Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas', Thrift.Collections in '..\..\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\src\Thrift.Configuration.pas', Thrift.Server in '..\..\src\Thrift.Server.pas', Thrift.Utils in '..\..\src\Thrift.Utils.pas', Thrift.Serializer in '..\..\src\Thrift.Serializer.pas', Thrift.Stream in '..\..\src\Thrift.Stream.pas', Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas', Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', Thrift.Test in 'gen-delphi\Thrift.Test.pas', DebugProtoTest in 'gen-delphi\DebugProtoTest.pas', Test.TypeRegistry, Test.EnumToString; begin try Test.TypeRegistry.RunTest; Test.EnumToString.RunTest; Writeln('Completed.'); except on e:Exception do Writeln(e.ClassName,': ',e.Message); end; end. thrift-0.23.0/lib/delphi/test/typeregistry/Test.EnumToString.pas0000664000175000017500000000506015165535636025163 0ustar00buildbuild00000000000000(* * 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 Test.EnumToString; interface uses Classes, SysUtils, Thrift.Utils, DebugProtoTest; procedure RunTest; implementation {$SCOPEDENUMS ON} type TIrregularEnum = ( // has gaps and/or does not start at zero FiveHundretOne = 501, FiveHundretTwo = 502, FiveHundretFive = 505 ); TRegularEnum = ( // starts at zero, no gaps, no duplicates One, Two, Three ); procedure IrregularEnumToString; // TIrregularEnum does not run from 0 to N, so we don't have RTTI for it // Search for "E2134: Type has no typeinfo" message to get the details // Unfortunately, this also means that StringUtils.ToString() does not work for enums w/o RTTI var value : Integer; sA,sB : string; begin for value := Pred(Ord(Low(TIrregularEnum))) to Succ(Ord(High(TIrregularEnum))) do begin sA := EnumUtils.ToString(Ord(value)); // much more reliable sB := StringUtils.ToString(TIrregularEnum(value)); // does not really work WriteLn( '- TIrregularEnum('+IntToStr(value)+'): EnumUtils => ',sA,', StringUtils => ', sB); end; end; procedure RegularEnumToString; // Regular enums have RTTI and work like a charm var value : Integer; sA,sB : string; begin for value := Pred(Ord(Low(TRegularEnum))) to Succ(Ord(High(TRegularEnum))) do begin sA := EnumUtils.ToString(Ord(value)); sB := StringUtils.ToString(TRegularEnum(value)); if sA = sB // both are expected to work with regular enums then WriteLn( '- TRegularEnum('+IntToStr(value)+'): ',sA,' = ', sB) else raise Exception.Create( 'Test failed: '+sA+' <> '+sB); end; end; procedure RunTest; begin Writeln('Testing enum utils ...'); RegularEnumToString; IrregularEnumToString; Writeln; end; end. thrift-0.23.0/lib/delphi/test/typeregistry/Test.TypeRegistry.pas0000664000175000017500000000425315165535636025242 0ustar00buildbuild00000000000000(* * 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 Test.TypeRegistry; interface uses Classes, SysUtils, TypInfo, Thrift, Thrift.TypeRegistry, DebugProtoTest; procedure RunTest; implementation type Tester = class public class procedure Test; end; class procedure Tester.Test; var instance : T; name : string; begin instance := TypeRegistry.Construct; name := GetTypeName(TypeInfo(T)); if instance <> nil then Writeln( name, ' = ok') else begin Writeln( name, ' = failed'); raise Exception.Create( 'Test with '+name+' failed!'); end; end; procedure RunTest; begin Writeln('Testing type registry ...'); Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Tester.Test; Writeln; end; end. thrift-0.23.0/lib/delphi/test/client.dpr0000664000175000017500000000541715165535636020363 0ustar00buildbuild00000000000000(* * 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. *) program client; {$APPTYPE CONSOLE} uses SysUtils, 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', Thrift.Socket in '..\src\Thrift.Socket.pas', Thrift.Configuration in '..\src\Thrift.Configuration.pas', Thrift.Exception in '..\src\Thrift.Exception.pas', Thrift.Transport.Pipes in '..\src\Thrift.Transport.Pipes.pas', Thrift.Transport.WinHTTP in '..\src\Thrift.Transport.WinHTTP.pas', Thrift.Transport.MsxmlHTTP in '..\src\Thrift.Transport.MsxmlHTTP.pas', Thrift.Protocol in '..\src\Thrift.Protocol.pas', Thrift.Protocol.JSON in '..\src\Thrift.Protocol.JSON.pas', Thrift.Protocol.Compact in '..\src\Thrift.Protocol.Compact.pas', Thrift.Protocol.Multiplex in '..\src\Thrift.Protocol.Multiplex.pas', Thrift.Collections in '..\src\Thrift.Collections.pas', Thrift.Server in '..\src\Thrift.Server.pas', Thrift.Stream in '..\src\Thrift.Stream.pas', Thrift.TypeRegistry in '..\src\Thrift.TypeRegistry.pas', Thrift.WinHTTP in '..\src\Thrift.WinHTTP.pas', Thrift.Utils in '..\src\Thrift.Utils.pas'; var nParamCount : Integer; args : array of string; i : Integer; arg : string; begin try Writeln( 'Delphi TestClient '+Thrift.Version); nParamCount := ParamCount; SetLength( args, nParamCount); for i := 1 to nParamCount do begin arg := ParamStr( i ); args[i-1] := arg; end; ExitCode := TTestClient.Execute( args); except on E: EAbort do begin ExitCode := $FF; end; on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := $FF; end; end; end. thrift-0.23.0/lib/delphi/test/testsuite/0000775000175000017500000000000015165535636020420 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/testsuite/TestConstants.pas0000664000175000017500000002536415165535636023753 0ustar00buildbuild00000000000000(* * 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 TestConstants; interface uses SysUtils, Thrift.Protocol, Thrift.Protocol.Compact, Thrift.Protocol.JSON; type TKnownProtocol = ( prot_Binary, // default binary protocol prot_JSON, // JSON protocol prot_Compact ); TServerType = ( srv_Simple, srv_Nonblocking, srv_Threadpool, srv_Threaded ); TEndpointTransport = ( trns_Sockets, trns_MsxmlHttp, trns_WinHttp, trns_NamedPipes, trns_AnonPipes, trns_EvHttp // as listed on http://thrift.apache.org/test ); TLayeredTransport = ( trns_None, trns_Buffered, trns_Framed ); 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, TJSONProtocolImpl, TCompactProtocolImpl ); const SERVER_TYPES : array[TServerType] of string = ('Simple', 'Nonblocking', 'Threadpool', 'Threaded'); THRIFT_PROTOCOLS : array[TKnownProtocol] of string = ('Binary', 'JSON', 'Compact'); LAYERED_TRANSPORTS : array[TLayeredTransport] of string = ('None', 'Buffered', 'Framed'); ENDPOINT_TRANSPORTS : array[TEndpointTransport] of string = ('Sockets', 'Http', 'WinHttp', 'Named Pipes','Anon Pipes', 'EvHttp'); HUGE_TEST_STRING = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ' + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ' + 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam ' + 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit ' + 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam ' + 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed ' + 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet ' + 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '; function BytesToHex( const bytes : TBytes) : string; function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes; implementation function BytesToHex( const bytes : TBytes) : string; var i : Integer; begin result := ''; for i := Low(bytes) to High(bytes) do begin result := result + IntToHex(bytes[i],2); end; 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. thrift-0.23.0/lib/delphi/test/testsuite/client/0000775000175000017500000000000015165535636021676 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/testsuite/client/TestClient.pas0000664000175000017500000012525115165535636024467 0ustar00buildbuild00000000000000(* * 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 TestClient; {$I ../src/Thrift.Defines.inc} {.$DEFINE StressTest} // activate to stress-test the server with frequent connects/disconnects {.$DEFINE PerfTest} // activate the performance test {$DEFINE Exceptions} // activate the exceptions test (or disable while debugging) {$if CompilerVersion >= 28} {$DEFINE SupportsAsync} {$ifend} {$WARN SYMBOL_PLATFORM OFF} // Win32Check interface uses Classes, Windows, SysUtils, Math, ActiveX, ComObj, {$IFDEF SupportsAsync} System.Threading, {$ENDIF} DateUtils, Generics.Collections, TestConstants, TestLogger, ConsoleHelper, PerfTests, UnitTests, 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 TClientThread = class; TThreadConsole = class(TThriftConsole) strict private FThread : TClientThread; FLogThreadID : Boolean; public constructor Create( const aThread: TClientThread; const aLogThreadID : Boolean); procedure Write( const S: string); override; procedure WriteLine( const S: string); override; end; TTestSetup = record protType : TKnownProtocol; endpoint : TEndpointTransport; layered : TLayeredTransports; useSSL : Boolean; // include where appropriate (TLayeredTransport?) host : string; port : Integer; sPipeName : string; hAnonRead, hAnonWrite : THandle; end; TClientThread = class( TThread ) strict private FSetup : TTestSetup; FTransport : ITransport; FProtocol : IProtocol; FNumIterations : Integer; FThreadNo : Integer; FConsole : TThreadConsole; FLogger : ITestLogger; procedure ClientTest; {$IFDEF SupportsAsync} procedure ClientAsyncTest; {$ENDIF} procedure InitializeProtocolTransportStack; procedure ShutdownProtocolTransportStack; function InitializeHttpTransport( const aTimeoutSetting : Integer; const aConfig : IThriftConfiguration = nil) : IHTTPClient; {$IFDEF StressTest} procedure StressTest(const client : TThriftTest.Iface); {$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; property Console : TThreadConsole read FConsole; public constructor Create( const aSetup : TTestSetup; const aNumIteration, aThreadNo: Integer; const aLogThreadID : Boolean); destructor Destroy; override; property ThreadNo : Integer read FThreadNo; end; TTestClient = class private class var FNumIterations : Integer; FNumThreads : Integer; class procedure PrintCmdLineHelp; class procedure InvalidArgs; public class function Execute( const arguments: array of string) : Byte; end; implementation const EXITCODE_SUCCESS = $00; // no errors bits set // EXITCODE_FAILBIT_BASETYPES = $01; EXITCODE_FAILBIT_STRUCTS = $02; EXITCODE_FAILBIT_CONTAINERS = $04; EXITCODE_FAILBIT_EXCEPTIONS = $08; MAP_FAILURES_TO_EXITCODE_BITS : array[TClientTestGroup] of Byte = ( EXITCODE_SUCCESS, // no bits here EXITCODE_FAILBIT_BASETYPES, EXITCODE_FAILBIT_STRUCTS, EXITCODE_FAILBIT_CONTAINERS, EXITCODE_FAILBIT_EXCEPTIONS ); function BoolToString( b : Boolean) : string; // overrides global BoolToString() begin if b then result := 'true' else result := 'false'; end; // not available in all versions, so make sure we have this one imported function IsDebuggerPresent: BOOL; stdcall; external KERNEL32 name 'IsDebuggerPresent'; { TTestClient } class procedure TTestClient.PrintCmdLineHelp; const HELPTEXT = ' [options]'#10 + #10 + 'Allowed options:'#10 + ' -h | --help Produces this help message'#10 + ' --host=arg (localhost) Host to connect'#10 + ' --port=arg (9090) Port number to connect'#10 + ' --pipe=arg Windows Named Pipe (e.g. MyThriftPipe)'#10 + ' --anon-pipes hRead hWrite Windows Anonymous Pipes pair (handles)'#10 + ' --transport=arg (sockets) Transport: buffered, framed, http, winhttp'#10 + ' --protocol=arg (binary) Protocol: binary, compact, json'#10 + ' --ssl Encrypted Transport using SSL'#10 + ' -n=num | --testloops=num (1) Number of Tests'#10 + ' -t=num | --threads=num (1) Number of Test threads'#10 + ' --performance Run the built-in performance test (no other arguments)'#10 ; begin Writeln( ChangeFileExt(ExtractFileName(ParamStr(0)),'') + HELPTEXT); end; class procedure TTestClient.InvalidArgs; begin Console.WriteLine( 'Invalid args.'); Console.WriteLine( ChangeFileExt(ExtractFileName(ParamStr(0)),'') + ' -h for more information'); Abort; end; class function TTestClient.Execute(const arguments: array of string) : Byte; function IsSwitch( const aArgument, aSwitch : string; out sValue : string) : Boolean; begin sValue := ''; result := (Copy( aArgument, 1, Length(aSwitch)) = aSwitch); if result then begin if (Copy( aArgument, 1, Length(aSwitch)+1) = (aSwitch+'=')) then sValue := Copy( aArgument, Length(aSwitch)+2, MAXINT); end; end; var iArg : Integer; threadExitCode : Byte; sArg, sValue : string; threads : array of TThread; dtStart : TDateTime; test : Integer; thread : TThread; setup : TTestSetup; begin // init record with setup do begin protType := prot_Binary; endpoint := trns_Sockets; layered := []; useSSL := FALSE; host := 'localhost'; port := 9090; sPipeName := ''; hAnonRead := INVALID_HANDLE_VALUE; hAnonWrite := INVALID_HANDLE_VALUE; end; try iArg := 0; while iArg < Length(arguments) do begin sArg := arguments[iArg]; Inc(iArg); if IsSwitch( sArg, '-h', sValue) or IsSwitch( sArg, '--help', sValue) then begin // -h [ --help ] produce help message PrintCmdLineHelp; result := $FF; // all tests failed Exit; end else if IsSwitch( sArg, '--host', sValue) then begin // --host arg (=localhost) Host to connect setup.host := sValue; end else if IsSwitch( sArg, '--port', sValue) then begin // --port arg (=9090) Port number to connect setup.port := StrToIntDef(sValue,0); if setup.port <= 0 then InvalidArgs; end else if IsSwitch( sArg, '--domain-socket', sValue) then begin // --domain-socket arg Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port raise Exception.Create('domain-socket not supported'); end // --pipe arg Windows Named Pipe (e.g. MyThriftPipe) else if IsSwitch( sArg, '--pipe', sValue) then begin // --pipe arg Windows Named Pipe (e.g. MyThriftPipe) setup.endpoint := trns_NamedPipes; setup.sPipeName := sValue; Console.WriteLine('Using named pipe ('+setup.sPipeName+')'); end else if IsSwitch( sArg, '--anon-pipes', sValue) then begin // --anon-pipes hRead hWrite Windows Anonymous Pipes pair (handles) setup.endpoint := trns_AnonPipes; setup.hAnonRead := THandle( StrToIntDef( arguments[iArg], Integer(INVALID_HANDLE_VALUE))); Inc(iArg); setup.hAnonWrite := THandle( StrToIntDef( arguments[iArg], Integer(INVALID_HANDLE_VALUE))); Inc(iArg); Console.WriteLine('Using anonymous pipes ('+IntToStr(Integer(setup.hAnonRead))+' and '+IntToStr(Integer(setup.hAnonWrite))+')'); end else if IsSwitch( sArg, '--transport', sValue) then begin // --transport arg (=sockets) Transport: buffered, framed, http, winhttp, evhttp if sValue = 'buffered' then Include( setup.layered, trns_Buffered) else if sValue = 'framed' then Include( setup.layered, trns_Framed) else if sValue = 'http' then setup.endpoint := trns_MsXmlHttp else if sValue = 'winhttp' then setup.endpoint := trns_WinHttp else if sValue = 'evhttp' then setup.endpoint := trns_EvHttp // recognized, but not supported else InvalidArgs; end else if IsSwitch( sArg, '--protocol', sValue) then begin // --protocol arg (=binary) Protocol: binary, compact, json if sValue = 'binary' then setup.protType := prot_Binary else if sValue = 'compact' then setup.protType := prot_Compact else if sValue = 'json' then setup.protType := prot_JSON else InvalidArgs; end else if IsSwitch( sArg, '--ssl', sValue) then begin // --ssl Encrypted Transport using SSL setup.useSSL := TRUE; end else if IsSwitch( sArg, '-n', sValue) or IsSwitch( sArg, '--testloops', sValue) then begin // -n [ --testloops ] arg (=1) Number of Tests FNumIterations := StrToIntDef( sValue, 0); if FNumIterations <= 0 then InvalidArgs; end else if IsSwitch( sArg, '-t', sValue) or IsSwitch( sArg, '--threads', sValue) then begin // -t [ --threads ] arg (=1) Number of Test threads FNumThreads := StrToIntDef( sValue, 0); if FNumThreads <= 0 then InvalidArgs; end else if IsSwitch( sArg, '--performance', sValue) then begin result := TPerformanceTests.Execute; Exit; end else begin InvalidArgs; end; end; // In the anonymous pipes mode the client is launched by the test server // -> behave nicely and allow for attaching a debugger to this process if (setup.endpoint = trns_AnonPipes) and not IsDebuggerPresent then MessageBox( 0, 'Attach Debugger and/or click OK to continue.', 'Thrift TestClient (Delphi)', MB_OK or MB_ICONEXCLAMATION); SetLength( threads, FNumThreads); dtStart := Now; // layered transports are not really meant to be stacked upon each other if (trns_Framed in setup.layered) then begin Console.WriteLine('Using framed transport'); end else if (trns_Buffered in setup.layered) then begin Console.WriteLine('Using buffered transport'); end; Console.WriteLine(THRIFT_PROTOCOLS[setup.protType]+' protocol'); if FNumThreads <> 1 then Console.WriteLine(IntToStr(FNumThreads)+' client threads'); if FNumIterations <> 1 then Console.WriteLine(IntToStr(FNumIterations)+' iterations'); for test := 0 to FNumThreads - 1 do begin thread := TClientThread.Create( setup, FNumIterations, test, FNumThreads<>1); threads[test] := thread; thread.Start; end; result := 0; for test := 0 to FNumThreads - 1 do begin threadExitCode := threads[test].WaitFor; result := result or threadExitCode; threads[test].Free; threads[test] := nil; end; Console.Write('Total time: ' + IntToStr( MilliSecondsBetween(Now, dtStart))); except on E: EAbort do raise; on E: Exception do begin Console.WriteLine( E.Message + #10 + E.StackTrace); raise; end; end; Console.WriteLine(''); Console.WriteLine('done!'); end; { TClientThread } procedure TClientThread.ClientTest; var client : TThriftTest.Iface; s : string; i8 : ShortInt; i32 : Integer; i64 : Int64; binOut,binIn : TBytes; guidIn, guidOut : TGuid; dub : Double; o : IXtruct; o2 : IXtruct2; i : IXtruct; i2 : IXtruct2; mapout : IThriftDictionary; mapin : IThriftDictionary; strmapout : IThriftDictionary; strmapin : IThriftDictionary; j : Integer; first : Boolean; key : Integer; strkey : string; listout : IThriftList; listin : IThriftList; setout : IThriftHashSet; setin : IThriftHashSet; ret : TNumberz; uid : Int64; mm : IThriftDictionary>; pos : IThriftDictionary; neg : IThriftDictionary; m2 : IThriftDictionary; k2 : Integer; insane : IInsanity; truck : IXtruct; whoa : IThriftDictionary>; key64 : Int64; val : IThriftDictionary; k2_2 : TNumberz; k3 : TNumberz; v2 : IInsanity; userMap : IThriftDictionary; xtructs : IThriftList; x : IXtruct; arg0 : ShortInt; arg1 : Integer; arg2 : Int64; arg3 : IThriftDictionary; arg4 : TNumberz; arg5 : Int64; {$IFDEF PerfTest} StartTick : Cardinal; k : Integer; {$ENDIF} hello, goodbye : IXtruct; crazy : IInsanity; looney : IInsanity; first_map : IThriftDictionary; second_map : IThriftDictionary; pair : TPair; testsize : TTestSize; begin client := TThriftTest.TClient.Create( FProtocol); FTransport.Open; {$IFDEF StressTest} StressTest( client); {$ENDIF StressTest} {$IFDEF Exceptions} // in-depth exception test // (1) do we get an exception at all? // (2) do we get the right exception? // (3) does the exception contain the expected data? StartTestGroup( 'testException', test_Exceptions); // case 1: exception type declared in IDL at the function call try client.testException('Xception'); Expect( FALSE, 'testException(''Xception''): must trow an exception'); except on e:TXception do begin Expect( e.ErrorCode = 1001, 'error code'); Expect( e.Message_ = 'Xception', 'error message'); Console.WriteLine( ' = ' + IntToStr(e.ErrorCode) + ', ' + e.Message_ ); end; on e:TTransportException do Expect( FALSE, 'Unexpected : "'+e.ToString+'"'); on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message); end; // re-open connection if needed if not FTransport.IsOpen then FTransport.Open; // case 2: exception type NOT declared in IDL at the function call // this will close the connection try client.testException('TException'); Expect( FALSE, 'testException(''TException''): must trow an exception'); except on e:TTransportException do begin Console.WriteLine( e.ClassName+' = '+e.Message); // this is what we get end; on e:TApplicationException do begin Console.WriteLine( e.ClassName+' = '+e.Message); // this is what we get end; on e:TException do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message); on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message); end; if FTransport.IsOpen then FTransport.Close; FTransport.Open; // re-open connection, server has already closed // case 3: no exception try client.testException('something'); Expect( TRUE, 'testException(''something''): must not trow an exception'); except on e:TTransportException do Expect( FALSE, 'Unexpected : "'+e.ToString+'"'); on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message); end; {$ENDIF Exceptions} // re-open connection if needed if not FTransport.IsOpen then FTransport.Open; // simple things StartTestGroup( 'simple Thrift calls', test_BaseTypes); client.testVoid(); Expect( TRUE, 'testVoid()'); // success := no exception s := BoolToString( client.testBool(TRUE)); Expect( s = BoolToString(TRUE), 'testBool(TRUE) = '+s); s := BoolToString( client.testBool(FALSE)); Expect( s = BoolToString(FALSE), 'testBool(FALSE) = '+s); s := client.testString('Test'); Expect( s = 'Test', 'testString(''Test'') = "'+s+'"'); s := client.testString(''); // empty string Expect( s = '', 'testString('''') = "'+s+'"'); s := client.testString(HUGE_TEST_STRING); Expect( length(s) = length(HUGE_TEST_STRING), 'testString( length(HUGE_TEST_STRING) = '+IntToStr(Length(HUGE_TEST_STRING))+') ' +'=> length(result) = '+IntToStr(Length(s))); i8 := client.testByte(1); Expect( i8 = 1, 'testByte(1) = ' + IntToStr( i8 )); i32 := client.testI32(-1); Expect( i32 = -1, 'testI32(-1) = ' + IntToStr(i32)); Console.WriteLine('testI64(-34359738368)'); i64 := client.testI64(-34359738368); Expect( i64 = -34359738368, 'testI64(-34359738368) = ' + IntToStr( i64)); guidOut := StringToGUID('{00112233-4455-6677-8899-AABBCCDDEEFF}'); Console.WriteLine('testUuid('+GUIDToString(guidOut)+')'); try guidIn := client.testUuid(guidOut); Expect( IsEqualGUID(guidIn, guidOut), 'testUuid('+GUIDToString(guidOut)+') = '+GUIDToString(guidIn)); except on e:TApplicationException do Console.WriteLine('testUuid(): '+e.Message); on e:Exception do Expect( FALSE, 'testUuid(): Unexpected exception "'+e.ClassName+'": '+e.Message); end; // random binary small for testsize := Low(TTestSize) to High(TTestSize) do begin binOut := PrepareBinaryData( TRUE, testsize); Console.WriteLine('testBinary('+IntToStr(Length(binOut))+' bytes)'); try binIn := client.testBinary(binOut); Expect( Length(binOut) = Length(binIn), 'testBinary('+IntToStr(Length(binOut))+' bytes): '+IntToStr(Length(binIn))+' bytes received'); i32 := Min( Length(binOut), Length(binIn)); Expect( CompareMem( binOut, binIn, i32), 'testBinary('+IntToStr(Length(binOut))+' bytes): validating received data'); except on e:TApplicationException do Console.WriteLine('testBinary(): '+e.Message); on e:Exception do Expect( FALSE, 'testBinary(): Unexpected exception "'+e.ClassName+'": '+e.Message); end; end; Console.WriteLine('testDouble(5.325098235)'); dub := client.testDouble(5.325098235); Expect( abs(dub-5.325098235) < 1e-14, 'testDouble(5.325098235) = ' + FloatToStr( dub)); // structs StartTestGroup( 'testStruct', test_Structs); Console.WriteLine('testStruct({''Zero'', 1, -3, -5})'); o := TXtructImpl.Create; o.String_thing := 'Zero'; o.Byte_thing := 1; o.I32_thing := -3; o.I64_thing := -5; i := client.testStruct(o); Expect( i.String_thing = 'Zero', 'i.String_thing = "'+i.String_thing+'"'); Expect( i.Byte_thing = 1, 'i.Byte_thing = '+IntToStr(i.Byte_thing)); Expect( i.I32_thing = -3, 'i.I32_thing = '+IntToStr(i.I32_thing)); Expect( i.I64_thing = -5, 'i.I64_thing = '+IntToStr(i.I64_thing)); Expect( i.__isset_String_thing, 'i.__isset_String_thing = '+BoolToString(i.__isset_String_thing)); Expect( i.__isset_Byte_thing, 'i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing)); Expect( i.__isset_I32_thing, 'i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing)); Expect( i.__isset_I64_thing, 'i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing)); // nested structs StartTestGroup( 'testNest', test_Structs); Console.WriteLine('testNest({1, {''Zero'', 1, -3, -5}, 5})'); o2 := TXtruct2Impl.Create; o2.Byte_thing := 1; o2.Struct_thing := o; o2.I32_thing := 5; i2 := client.testNest(o2); i := i2.Struct_thing; Expect( i.String_thing = 'Zero', 'i.String_thing = "'+i.String_thing+'"'); Expect( i.Byte_thing = 1, 'i.Byte_thing = '+IntToStr(i.Byte_thing)); Expect( i.I32_thing = -3, 'i.I32_thing = '+IntToStr(i.I32_thing)); Expect( i.I64_thing = -5, 'i.I64_thing = '+IntToStr(i.I64_thing)); Expect( i2.Byte_thing = 1, 'i2.Byte_thing = '+IntToStr(i2.Byte_thing)); Expect( i2.I32_thing = 5, 'i2.I32_thing = '+IntToStr(i2.I32_thing)); Expect( i.__isset_String_thing, 'i.__isset_String_thing = '+BoolToString(i.__isset_String_thing)); Expect( i.__isset_Byte_thing, 'i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing)); Expect( i.__isset_I32_thing, 'i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing)); Expect( i.__isset_I64_thing, 'i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing)); Expect( i2.__isset_Byte_thing, 'i2.__isset_Byte_thing'); Expect( i2.__isset_I32_thing, 'i2.__isset_I32_thing'); // map: A map of strictly unique keys to values. // Translates to an STL map, Java HashMap, PHP associative array, Python/Ruby dictionary, etc. StartTestGroup( 'testMap', test_Containers); mapout := TThriftDictionaryImpl.Create; for j := 0 to 4 do begin mapout.AddOrSetValue( j, j - 10); end; Console.Write('testMap({'); first := True; for key in mapout.Keys do begin if first then first := False else Console.Write( ', ' ); Console.Write( IntToStr( key) + ' => ' + IntToStr( mapout[key])); end; Console.WriteLine('})'); mapin := client.testMap( mapout ); Expect( mapin.Count = mapout.Count, 'testMap: mapin.Count = mapout.Count'); for j := 0 to 4 do begin Expect( mapout.ContainsKey(j), 'testMap: mapout.ContainsKey('+IntToStr(j)+') = '+BoolToString(mapout.ContainsKey(j))); end; for key in mapin.Keys do begin Expect( mapin[key] = mapout[key], 'testMap: '+IntToStr(key) + ' => ' + IntToStr( mapin[key])); Expect( mapin[key] = key - 10, 'testMap: mapin['+IntToStr(key)+'] = '+IntToStr( mapin[key])); end; // map: A map of strictly unique keys to values. // Translates to an STL map, Java HashMap, PHP associative array, Python/Ruby dictionary, etc. StartTestGroup( 'testStringMap', test_Containers); strmapout := TThriftDictionaryImpl.Create; for j := 0 to 4 do begin strmapout.AddOrSetValue( IntToStr(j), IntToStr(j - 10)); end; Console.Write('testStringMap({'); first := True; for strkey in strmapout.Keys do begin if first then first := False else Console.Write( ', ' ); Console.Write( strkey + ' => ' + strmapout[strkey]); end; Console.WriteLine('})'); strmapin := client.testStringMap( strmapout ); Expect( strmapin.Count = strmapout.Count, 'testStringMap: strmapin.Count = strmapout.Count'); for j := 0 to 4 do begin Expect( strmapout.ContainsKey(IntToStr(j)), 'testStringMap: strmapout.ContainsKey('+IntToStr(j)+') = ' + BoolToString(strmapout.ContainsKey(IntToStr(j)))); end; for strkey in strmapin.Keys do begin Expect( strmapin[strkey] = strmapout[strkey], 'testStringMap: '+strkey + ' => ' + strmapin[strkey]); Expect( strmapin[strkey] = IntToStr( StrToInt(strkey) - 10), 'testStringMap: strmapin['+strkey+'] = '+strmapin[strkey]); end; // set: An unordered set of unique elements. // Translates to an STL set, Java HashSet, set in Python, etc. // Note: PHP does not support sets, so it is treated similar to a List StartTestGroup( 'testSet', test_Containers); setout := TThriftHashSetImpl.Create; for j := -2 to 2 do begin setout.Add( j ); end; Console.Write('testSet({'); first := True; for j in setout do begin if first then first := False else Console.Write(', '); Console.Write(IntToStr( j)); end; Console.WriteLine('})'); setin := client.testSet(setout); Expect( setin.Count = setout.Count, 'testSet: setin.Count = setout.Count'); Expect( setin.Count = 5, 'testSet: setin.Count = '+IntToStr(setin.Count)); for j := -2 to 2 do // unordered, we can't rely on the order => test for known elements only begin Expect( setin.Contains(j), 'testSet: setin.Contains('+IntToStr(j)+') => '+BoolToString(setin.Contains(j))); end; // list: An ordered list of elements. // Translates to an STL vector, Java ArrayList, native arrays in scripting languages, etc. StartTestGroup( 'testList', test_Containers); listout := TThriftListImpl.Create; listout.Add( +1); listout.Add( -2); listout.Add( +3); listout.Add( -4); listout.Add( 0); Console.Write('testList({'); first := True; for j in listout do begin if first then first := False else Console.Write(', '); Console.Write(IntToStr( j)); end; Console.WriteLine('})'); listin := client.testList(listout); Expect( listin.Count = listout.Count, 'testList: listin.Count = listout.Count'); Expect( listin.Count = 5, 'testList: listin.Count = '+IntToStr(listin.Count)); Expect( listin[0] = +1, 'listin[0] = '+IntToStr( listin[0])); Expect( listin[1] = -2, 'listin[1] = '+IntToStr( listin[1])); Expect( listin[2] = +3, 'listin[2] = '+IntToStr( listin[2])); Expect( listin[3] = -4, 'listin[3] = '+IntToStr( listin[3])); Expect( listin[4] = 0, 'listin[4] = '+IntToStr( listin[4])); // enums ret := client.testEnum(TNumberz.ONE); Expect( ret = TNumberz.ONE, 'testEnum(ONE) = '+IntToStr(Ord(ret))); ret := client.testEnum(TNumberz.TWO); Expect( ret = TNumberz.TWO, 'testEnum(TWO) = '+IntToStr(Ord(ret))); ret := client.testEnum(TNumberz.THREE); Expect( ret = TNumberz.THREE, 'testEnum(THREE) = '+IntToStr(Ord(ret))); ret := client.testEnum(TNumberz.FIVE); Expect( ret = TNumberz.FIVE, 'testEnum(FIVE) = '+IntToStr(Ord(ret))); ret := client.testEnum(TNumberz.EIGHT); Expect( ret = TNumberz.EIGHT, 'testEnum(EIGHT) = '+IntToStr(Ord(ret))); // typedef uid := client.testTypedef(309858235082523); Expect( uid = 309858235082523, 'testTypedef(309858235082523) = '+IntToStr(uid)); // maps of maps StartTestGroup( 'testMapMap(1)', test_Containers); mm := client.testMapMap(1); Console.Write(' = {'); for key in mm.Keys do begin Console.Write( IntToStr( key) + ' => {'); m2 := mm[key]; for k2 in m2.Keys do begin Console.Write( IntToStr( k2) + ' => ' + IntToStr( m2[k2]) + ', '); end; Console.Write('}, '); end; Console.WriteLine('}'); // verify result data Expect( mm.Count = 2, 'mm.Count = '+IntToStr(mm.Count)); pos := mm[4]; neg := mm[-4]; for j := 1 to 4 do begin Expect( pos[j] = j, 'pos[j] = '+IntToStr(pos[j])); Expect( neg[-j] = -j, 'neg[-j] = '+IntToStr(neg[-j])); end; // insanity StartTestGroup( 'testInsanity', test_Structs); insane := TInsanityImpl.Create; insane.UserMap := TThriftDictionaryImpl.Create; insane.UserMap.AddOrSetValue( TNumberz.FIVE, 5000); truck := TXtructImpl.Create; truck.String_thing := 'Truck'; truck.Byte_thing := -8; // byte is signed truck.I32_thing := 32; truck.I64_thing := 64; insane.Xtructs := TThriftListImpl.Create; insane.Xtructs.Add( truck ); whoa := client.testInsanity( insane ); Console.Write(' = {'); for key64 in whoa.Keys do begin val := whoa[key64]; Console.Write( IntToStr( key64) + ' => {'); for k2_2 in val.Keys do begin v2 := val[k2_2]; Console.Write( IntToStr( Integer( k2_2)) + ' => {'); userMap := v2.UserMap; Console.Write('{'); if userMap <> nil then begin for k3 in userMap.Keys do begin Console.Write( IntToStr( Integer( k3)) + ' => ' + IntToStr( userMap[k3]) + ', '); end; end else begin Console.Write('null'); end; Console.Write('}, '); xtructs := v2.Xtructs; Console.Write('{'); if xtructs <> nil then begin for x in xtructs do begin Console.Write('{"' + x.String_thing + '", ' + IntToStr( x.Byte_thing) + ', ' + IntToStr( x.I32_thing) + ', ' + IntToStr( x.I32_thing) + '}, '); end; end else begin Console.Write('null'); end; Console.Write('}'); Console.Write('}, '); end; Console.Write('}, '); end; Console.WriteLine('}'); (** * So you think you've got this all worked, out eh? * * Creates a the returned map with these values and prints it out: * { 1 => { 2 => argument, * 3 => argument, * }, * 2 => { 6 => , }, * } * @return map> - a map with the above values *) // verify result data Expect( whoa.Count = 2, 'whoa.Count = '+IntToStr(whoa.Count)); // first_map := whoa[1]; second_map := whoa[2]; Expect( first_map.Count = 2, 'first_map.Count = '+IntToStr(first_map.Count)); Expect( second_map.Count = 1, 'second_map.Count = '+IntToStr(second_map.Count)); // looney := second_map[TNumberz.SIX]; Expect( Assigned(looney), 'Assigned(looney) = '+BoolToString(Assigned(looney))); Expect( not looney.__isset_UserMap, 'looney.__isset_UserMap = '+BoolToString(looney.__isset_UserMap)); Expect( not looney.__isset_Xtructs, 'looney.__isset_Xtructs = '+BoolToString(looney.__isset_Xtructs)); // for ret in [TNumberz.TWO, TNumberz.THREE] do begin crazy := first_map[ret]; Console.WriteLine('first_map['+intToStr(Ord(ret))+']'); Expect( crazy.__isset_UserMap, 'crazy.__isset_UserMap = '+BoolToString(crazy.__isset_UserMap)); Expect( crazy.__isset_Xtructs, 'crazy.__isset_Xtructs = '+BoolToString(crazy.__isset_Xtructs)); Expect( crazy.UserMap.Count = insane.UserMap.Count, 'crazy.UserMap.Count = '+IntToStr(crazy.UserMap.Count)); for pair in insane.UserMap do begin Expect( crazy.UserMap[pair.Key] = pair.Value, 'crazy.UserMap['+IntToStr(Ord(pair.key))+'] = '+IntToStr(crazy.UserMap[pair.Key])); end; Expect( crazy.Xtructs.Count = insane.Xtructs.Count, 'crazy.Xtructs.Count = '+IntToStr(crazy.Xtructs.Count)); for arg0 := 0 to insane.Xtructs.Count-1 do begin hello := insane.Xtructs[arg0]; goodbye := crazy.Xtructs[arg0]; Expect( goodbye.String_thing = hello.String_thing, 'goodbye.String_thing = '+goodbye.String_thing); Expect( goodbye.Byte_thing = hello.Byte_thing, 'goodbye.Byte_thing = '+IntToStr(goodbye.Byte_thing)); Expect( goodbye.I32_thing = hello.I32_thing, 'goodbye.I32_thing = '+IntToStr(goodbye.I32_thing)); Expect( goodbye.I64_thing = hello.I64_thing, 'goodbye.I64_thing = '+IntToStr(goodbye.I64_thing)); end; end; // multi args StartTestGroup( 'testMulti', test_BaseTypes); arg0 := 1; arg1 := 2; arg2 := High(Int64); arg3 := TThriftDictionaryImpl.Create; arg3.AddOrSetValue( 1, 'one'); arg4 := TNumberz.FIVE; arg5 := 5000000; Console.WriteLine('Test Multi(' + IntToStr( arg0) + ',' + IntToStr( arg1) + ',' + IntToStr( arg2) + ',' + arg3.ToString + ',' + IntToStr( Integer( arg4)) + ',' + IntToStr( arg5) + ')'); i := client.testMulti( arg0, arg1, arg2, arg3, arg4, arg5); Expect( i.String_thing = 'Hello2', 'testMulti: i.String_thing = "'+i.String_thing+'"'); Expect( i.Byte_thing = arg0, 'testMulti: i.Byte_thing = '+IntToStr(i.Byte_thing)); Expect( i.I32_thing = arg1, 'testMulti: i.I32_thing = '+IntToStr(i.I32_thing)); Expect( i.I64_thing = arg2, 'testMulti: i.I64_thing = '+IntToStr(i.I64_thing)); Expect( i.__isset_String_thing, 'testMulti: i.__isset_String_thing = '+BoolToString(i.__isset_String_thing)); Expect( i.__isset_Byte_thing, 'testMulti: i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing)); Expect( i.__isset_I32_thing, 'testMulti: i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing)); Expect( i.__isset_I64_thing, 'testMulti: i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing)); // multi exception StartTestGroup( 'testMultiException(1)', test_Exceptions); try i := client.testMultiException( 'need more pizza', 'run out of beer'); Expect( i.String_thing = 'run out of beer', 'i.String_thing = "' +i.String_thing+ '"'); Expect( i.__isset_String_thing, 'i.__isset_String_thing = '+BoolToString(i.__isset_String_thing)); { this is not necessarily true, these fields are default-serialized Expect( not i.__isset_Byte_thing, 'i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing)); Expect( not i.__isset_I32_thing, 'i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing)); Expect( not i.__isset_I64_thing, 'i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing)); } except on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message); end; StartTestGroup( 'testMultiException(Xception)', test_Exceptions); try i := client.testMultiException( 'Xception', 'second test'); Expect( FALSE, 'testMultiException(''Xception''): must trow an exception'); except on x:TXception do begin Expect( x.__isset_ErrorCode, 'x.__isset_ErrorCode = '+BoolToString(x.__isset_ErrorCode)); Expect( x.__isset_Message, 'x.__isset_Message = '+BoolToString(x.__isset_Message)); Expect( x.ErrorCode = 1001, 'x.ErrorCode = '+IntToStr(x.ErrorCode)); Expect( x.Message_ = 'This is an Xception', 'x.Message = "'+x.Message_+'"'); end; on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message); end; StartTestGroup( 'testMultiException(Xception2)', test_Exceptions); try i := client.testMultiException( 'Xception2', 'third test'); Expect( FALSE, 'testMultiException(''Xception2''): must trow an exception'); except on x:TXception2 do begin Expect( x.__isset_ErrorCode, 'x.__isset_ErrorCode = '+BoolToString(x.__isset_ErrorCode)); Expect( x.__isset_Struct_thing, 'x.__isset_Struct_thing = '+BoolToString(x.__isset_Struct_thing)); Expect( x.ErrorCode = 2002, 'x.ErrorCode = '+IntToStr(x.ErrorCode)); Expect( x.Struct_thing.String_thing = 'This is an Xception2', 'x.Struct_thing.String_thing = "'+x.Struct_thing.String_thing+'"'); Expect( x.Struct_thing.__isset_String_thing, 'x.Struct_thing.__isset_String_thing = '+BoolToString(x.Struct_thing.__isset_String_thing)); { this is not necessarily true, these fields are default-serialized Expect( not x.Struct_thing.__isset_Byte_thing, 'x.Struct_thing.__isset_Byte_thing = '+BoolToString(x.Struct_thing.__isset_Byte_thing)); Expect( not x.Struct_thing.__isset_I32_thing, 'x.Struct_thing.__isset_I32_thing = '+BoolToString(x.Struct_thing.__isset_I32_thing)); Expect( not x.Struct_thing.__isset_I64_thing, 'x.Struct_thing.__isset_I64_thing = '+BoolToString(x.Struct_thing.__isset_I64_thing)); } end; on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message); end; // oneway functions StartTestGroup( 'Test Oneway(1)', test_Unknown); client.testOneway(1); Expect( TRUE, 'Test Oneway(1)'); // success := no exception // call time {$IFDEF PerfTest} StartTestGroup( 'Test Calltime()'); StartTick := GetTickCount; for k := 0 to 1000 - 1 do begin client.testVoid(); end; Console.WriteLine(' = ' + FloatToStr( (GetTickCount - StartTick) / 1000 ) + ' ms a testVoid() call' ); {$ENDIF PerfTest} // no more tests here StartTestGroup( '', test_Unknown); end; {$IFDEF SupportsAsync} procedure TClientThread.ClientAsyncTest; var client : TThriftTest.IAsync; s : string; i8 : ShortInt; begin StartTestGroup( 'Async Tests', test_Unknown); client := TThriftTest.TClient.Create( FProtocol); FTransport.Open; // oneway void functions client.testOnewayAsync(1).Wait; Expect( TRUE, 'Test Oneway(1)'); // success := no exception // normal functions s := client.testStringAsync(HUGE_TEST_STRING).Value; Expect( length(s) = length(HUGE_TEST_STRING), 'testString( length(HUGE_TEST_STRING) = '+IntToStr(Length(HUGE_TEST_STRING))+') ' +'=> length(result) = '+IntToStr(Length(s))); i8 := client.testByte(1).Value; Expect( i8 = 1, 'testByte(1) = ' + IntToStr( i8 )); end; {$ENDIF} {$IFDEF StressTest} procedure TClientThread.StressTest(const client : TThriftTest.Iface); begin while TRUE do begin try if not FTransport.IsOpen then FTransport.Open; // re-open connection, server has already closed try client.testString('Test'); Write('.'); finally if FTransport.IsOpen then FTransport.Close; end; except on e:Exception do Writeln(#10+e.message); end; end; end; {$ENDIF} procedure TClientThread.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup); begin FLogger.StartTestGroup( aGroup, aTest); end; procedure TClientThread.Expect( aTestResult : Boolean; const aTestInfo : string); begin FLogger.Expect( aTestResult, aTestInfo); end; function TClientThread.CalculateExitCode : Byte; var test : TClientTestGroup; failed, executed : TClientTestGroups; begin result := EXITCODE_SUCCESS; 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; constructor TClientThread.Create( const aSetup : TTestSetup; const aNumIteration, aThreadNo: Integer; const aLogThreadID : Boolean); begin FSetup := aSetup; FThreadNo := aThreadNo; FNumIterations := aNumIteration; FConsole := TThreadConsole.Create( Self, aLogThreadID); FLogger := TTestLoggerImpl.Create; inherited Create( TRUE); end; destructor TClientThread.Destroy; begin FreeAndNil( FConsole); FLogger := nil; //-> Release inherited; end; procedure TClientThread.Execute; var i : Integer; begin // perform all tests try // 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; try for i := 0 to FNumIterations - 1 do begin ClientTest; {$IFDEF SupportsAsync} ClientAsyncTest; {$ENDIF} end; // report the outcome FLogger.ReportResults; SetReturnValue( CalculateExitCode); finally ShutdownProtocolTransportStack; end; except on e:Exception do Expect( FALSE, 'unexpected exception: "'+e.message+'"'); end; end; function TClientThread.InitializeHttpTransport( const aTimeoutSetting : Integer; const aConfig : IThriftConfiguration) : IHTTPClient; var sUrl : string; comps : URL_COMPONENTS; dwChars : DWORD; begin ASSERT( FSetup.endpoint in [trns_MsxmlHttp, trns_WinHttp]); if FSetup.useSSL then sUrl := 'https://' else sUrl := 'http://'; sUrl := sUrl + FSetup.host; // add the port number if necessary and at the right place FillChar( comps, SizeOf(comps), 0); comps.dwStructSize := SizeOf(comps); comps.dwSchemeLength := MAXINT; comps.dwHostNameLength := MAXINT; comps.dwUserNameLength := MAXINT; comps.dwPasswordLength := MAXINT; comps.dwUrlPathLength := MAXINT; comps.dwExtraInfoLength := MAXINT; Win32Check( WinHttpCrackUrl( PChar(sUrl), Length(sUrl), 0, comps)); case FSetup.port of 80 : if FSetup.useSSL then comps.nPort := FSetup.port; 443 : if not FSetup.useSSL then comps.nPort := FSetup.port; else if FSetup.port > 0 then comps.nPort := FSetup.port; end; dwChars := Length(sUrl) + 64; SetLength( sUrl, dwChars); Win32Check( WinHttpCreateUrl( comps, 0, @sUrl[1], dwChars)); SetLength( sUrl, dwChars); Console.WriteLine('Target URL: '+sUrl); case FSetup.endpoint of trns_MsxmlHttp : result := TMsxmlHTTPClientImpl.Create( sUrl, aConfig); trns_WinHttp : result := TWinHTTPClientImpl.Create( sUrl, aConfig); else raise Exception.Create(ENDPOINT_TRANSPORTS[FSetup.endpoint]+' unhandled case'); end; result.DnsResolveTimeout := aTimeoutSetting; result.ConnectionTimeout := aTimeoutSetting; result.SendTimeout := aTimeoutSetting; result.ReadTimeout := aTimeoutSetting; end; procedure TClientThread.InitializeProtocolTransportStack; var streamtrans : IStreamTransport; canSSL : Boolean; const DEBUG_TIMEOUT = 30 * 1000; RELEASE_TIMEOUT = DEFAULT_THRIFT_TIMEOUT; PIPE_TIMEOUT = RELEASE_TIMEOUT; HTTP_TIMEOUTS = 10 * 1000; begin // needed for HTTP clients as they utilize the MSXML COM components OleCheck( CoInitialize( nil)); canSSL := FALSE; case FSetup.endpoint of trns_Sockets: begin Console.WriteLine('Using sockets ('+FSetup.host+' port '+IntToStr(FSetup.port)+')'); streamtrans := TSocketImpl.Create( FSetup.host, FSetup.port); FTransport := streamtrans; end; trns_MsxmlHttp, trns_WinHttp: begin Console.WriteLine('Using HTTPClient'); FTransport := InitializeHttpTransport( HTTP_TIMEOUTS); canSSL := TRUE; end; trns_EvHttp: begin raise Exception.Create(ENDPOINT_TRANSPORTS[FSetup.endpoint]+' transport not implemented'); end; trns_NamedPipes: begin streamtrans := TNamedPipeTransportClientEndImpl.Create( FSetup.sPipeName, 0, nil, PIPE_TIMEOUT, PIPE_TIMEOUT); FTransport := streamtrans; end; trns_AnonPipes: begin streamtrans := TAnonymousPipeTransportImpl.Create( FSetup.hAnonRead, FSetup.hAnonWrite, FALSE, PIPE_TIMEOUT); FTransport := streamtrans; end; else raise Exception.Create('Unhandled endpoint transport'); end; ASSERT( FTransport <> nil); // layered transports are not really meant to be stacked upon each other if (trns_Framed in FSetup.layered) then begin FTransport := TFramedTransportImpl.Create( FTransport); end else if (trns_Buffered in FSetup.layered) and (streamtrans <> nil) then begin FTransport := TBufferedTransportImpl.Create( streamtrans, 32); // small buffer to test read() end; if FSetup.useSSL and not canSSL then begin raise Exception.Create('SSL/TLS not implemented'); end; // create protocol instance, default to BinaryProtocol FProtocol := PROTOCOL_CLASSES[FSetup.protType].Create(FTransport); ASSERT( (FTransport <> nil) and (FProtocol <> nil)); end; procedure TClientThread.ShutdownProtocolTransportStack; begin try FProtocol := nil; if FTransport <> nil then begin FTransport.Close; FTransport := nil; end; finally CoUninitialize; end; end; { TThreadConsole } constructor TThreadConsole.Create( const aThread: TClientThread; const aLogThreadID : Boolean); begin inherited Create; FThread := AThread; FLogThreadID := aLogThreadID; end; procedure TThreadConsole.Write(const S: string); begin if FLogThreadID then ConsoleHelper.Console.Write( IntToStr(FThread.ThreadNo)+'> '+S) else ConsoleHelper.Console.Write( S); end; procedure TThreadConsole.WriteLine(const S: string); begin if FLogThreadID then ConsoleHelper.Console.WriteLine( IntToStr(FThread.ThreadNo)+'> '+S) else ConsoleHelper.Console.WriteLine( S); end; initialization TTestClient.FNumIterations := 1; TTestClient.FNumThreads := 1; end. thrift-0.23.0/lib/delphi/test/testsuite/client/Performance/0000775000175000017500000000000015165535636024137 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/testsuite/client/Performance/DataFactory.pas0000664000175000017500000001637215165535636027056 0ustar00buildbuild00000000000000// 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 DataFactory; interface uses SysUtils, Thrift.Collections, Thrift.Test; type TestDataFactory = class strict protected class function CreateSetField(const count : Integer) : IThriftHashSet< IInsanity>; static; class function CreateInsanity(const count : Integer) : IInsanity; static; class function CreateBytesArray(const count : Integer) : TBytes; static; class function CreateXtructs(const count : Integer) : IThriftList< IXtruct>; static; class function CreateXtruct(const count : Integer) : IXtruct; static; class function CreateListField(const count : Integer) : IThriftList< IThriftDictionary< IThriftHashSet< Integer>, IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>>>; static; class function CreateUserMap(const count : Integer) : IThriftDictionary< TNumberz, Int64>; static; class function CreateListFieldData(const count : Integer) : IThriftDictionary< IThriftHashSet< Integer>, IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>>; static; class function CreateIntHashSet(const count : Integer) : IThriftHashSet< Integer>; static; class function CreateListFieldDataDict(const count : Integer) : IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>; static; class function CreateListFieldDataDictValue(const count : Integer) : IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>; static; class function CreateListFieldDataDictValueList(const count : Integer) : IThriftList< IThriftDictionary< IInsanity, string>>; static; class function CreateListFieldDataDictValueListDict(const count : Integer) : IThriftDictionary< IInsanity, string>; static; public class function CreateCrazyNesting(const count : Integer = 10) : ICrazyNesting; static; end; implementation class function TestDataFactory.CreateCrazyNesting(const count : Integer = 10) : ICrazyNesting; begin if (count <= 0) then Exit(nil); result := TCrazyNestingImpl.Create; result.Binary_field := CreateBytesArray(count); result.List_field := CreateListField(count); result.Set_field := CreateSetField(count); result.String_field := Format('data level %d', [count]); end; class function TestDataFactory.CreateSetField(const count : Integer) : IThriftHashSet< IInsanity>; var i : Integer; begin result := TThriftHashSetImpl< IInsanity>.Create; for i := 0 to count-1 do begin result.Add(CreateInsanity(count)); end; end; class function TestDataFactory.CreateInsanity(const count : Integer) : IInsanity; begin result := TInsanityImpl.Create; result.UserMap := CreateUserMap(count); result.Xtructs := CreateXtructs(count); end; class function TestDataFactory.CreateXtructs(const count : Integer) : IThriftList< IXtruct>; var i : Integer; begin result := TThriftListImpl< IXtruct>.Create; for i := 0 to count-1 do begin result.Add(CreateXtruct(count)); end; end; class function TestDataFactory.CreateXtruct(const count : Integer) : IXtruct; begin result := TXtructImpl.Create; result.Byte_thing := SmallInt(count mod 128); result.I32_thing := count; result.I64_thing := count; result.String_thing := Format('data level %d', [count]); end; class function TestDataFactory.CreateUserMap(const count : Integer) : IThriftDictionary< TNumberz, Int64>; begin result := TThriftDictionaryImpl< TNumberz, Int64>.Create; result.Add(TNumberz.ONE, count); result.Add(TNumberz.TWO, count); result.Add(TNumberz.THREE, count); result.Add(TNumberz.FIVE, count); result.Add(TNumberz.SIX, count); result.Add(TNumberz.EIGHT, count); end; class function TestDataFactory.CreateListField(const count : Integer) : IThriftList< IThriftDictionary< IThriftHashSet< Integer>, IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>>>; var i : Integer; begin result := TThriftListImpl< IThriftDictionary< IThriftHashSet< Integer>, IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>>>.Create; for i := 0 to count-1 do begin result.Add(CreateListFieldData(count)); end; end; class function TestDataFactory.CreateListFieldData(const count : Integer) : IThriftDictionary< IThriftHashSet< Integer>, IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>>; var i : Integer; begin result := TThriftDictionaryImpl< IThriftHashSet< Integer>, IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>>.Create; for i := 0 to count-1 do begin result.Add( CreateIntHashSet(count), CreateListFieldDataDict(count)); end; end; class function TestDataFactory.CreateIntHashSet(const count : Integer) : IThriftHashSet< Integer>; var i : Integer; begin result := TThriftHashSetImpl< Integer>.Create; for i := 0 to count-1 do begin result.Add(i); end; end; class function TestDataFactory.CreateListFieldDataDict(const count : Integer) : IThriftDictionary< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>; var i : Integer; begin result := TThriftDictionaryImpl< Integer, IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>>.Create; for i := 0 to count-1 do begin result.Add(i, CreateListFieldDataDictValue(count)); end; end; class function TestDataFactory.CreateListFieldDataDictValue(const count : Integer) : IThriftHashSet< IThriftList< IThriftDictionary< IInsanity, string>>>; var i : Integer; begin result := TThriftHashSetImpl< IThriftList< IThriftDictionary< IInsanity, string>>>.Create; for i := 0 to count-1 do begin result.Add( CreateListFieldDataDictValueList(count)); end; end; class function TestDataFactory.CreateListFieldDataDictValueList(const count : Integer) : IThriftList< IThriftDictionary< IInsanity, string>>; var i : Integer; begin result := TThriftListImpl< IThriftDictionary< IInsanity, string>>.Create; for i := 0 to count-1 do begin result.Add(CreateListFieldDataDictValueListDict(count)); end; end; class function TestDataFactory.CreateListFieldDataDictValueListDict(const count : Integer) : IThriftDictionary< IInsanity, string>; begin result := TThriftDictionaryImpl< IInsanity, string>.Create; result.Add(CreateInsanity(count), Format('data level %d', [count])); end; class function TestDataFactory.CreateBytesArray(const count : Integer) : TBytes; var i : Integer; begin SetLength( result, count); for i := 0 to count-1 do begin result[i] := i mod $FF; end; end; end. thrift-0.23.0/lib/delphi/test/testsuite/client/Performance/PerfTests.pas0000664000175000017500000001245215165535636026567 0ustar00buildbuild00000000000000// 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 PerfTests; interface uses Windows, Classes, SysUtils, Thrift.Collections, Thrift.Configuration, Thrift.Test, Thrift.Protocol, Thrift.Protocol.JSON, Thrift.Protocol.Compact, Thrift.Transport, Thrift.Stream, ConsoleHelper, TestConstants, DataFactory; type TPerformanceTests = class strict private FTestdata : ICrazyNesting; FMemBuffer : TMemoryStream; FTransport : ITransport; FConfig : IThriftConfiguration; procedure ProtocolPeformanceTest; procedure RunTest( const ptyp : TKnownProtocol; const layered : TLayeredTransport); function GenericProtocolFactory(const ptyp : TKnownProtocol; const layered : TLayeredTransport; const forWrite : Boolean) : IProtocol; function GetProtocolTransportName(const ptyp : TKnownProtocol; const layered : TLayeredTransport) : string; public class function Execute : Integer; end; implementation // not available in all versions, so make sure we have this one imported function IsDebuggerPresent: BOOL; stdcall; external KERNEL32 name 'IsDebuggerPresent'; class function TPerformanceTests.Execute : Integer; var instance : TPerformanceTests; begin instance := TPerformanceTests.Create; instance.ProtocolPeformanceTest; // debug only if IsDebuggerPresent then begin Console.Write('Hit ENTER ...'); ReadLn; end; result := 0; end; procedure TPerformanceTests.ProtocolPeformanceTest; var layered : TLayeredTransport; begin Console.WriteLine('Setting up for ProtocolPeformanceTest ...'); FTestdata := TestDataFactory.CreateCrazyNesting(); for layered := Low(TLayeredTransport) to High(TLayeredTransport) do begin RunTest( TKnownProtocol.prot_Binary, layered); RunTest( TKnownProtocol.prot_Compact, layered); RunTest( TKnownProtocol.prot_JSON, layered); end; end; procedure TPerformanceTests.RunTest( const ptyp : TKnownProtocol; const layered : TLayeredTransport); var freq, start, stop : Int64; proto : IProtocol; restored : ICrazyNesting; begin QueryPerformanceFrequency( freq); FConfig := TThriftConfigurationImpl.Create; proto := GenericProtocolFactory( ptyp, layered, TRUE); QueryPerformanceCounter( start); FTestdata.Write(proto); FTransport.Flush; QueryPerformanceCounter( stop); Console.WriteLine( Format('RunTest(%s): write = %d msec', [ GetProtocolTransportName(ptyp,layered), Round(1000.0*(stop-start)/freq) ])); restored := TCrazyNestingImpl.Create; proto := GenericProtocolFactory( ptyp, layered, FALSE); QueryPerformanceCounter( start); restored.Read(proto); QueryPerformanceCounter( stop); Console.WriteLine( Format('RunTest(%s): read = %d msec', [ GetProtocolTransportName(ptyp,layered), Round(1000.0*(stop-start)/freq) ])); end; function TPerformanceTests.GenericProtocolFactory(const ptyp : TKnownProtocol; const layered : TLayeredTransport; const forWrite : Boolean) : IProtocol; var newBuf : TMemoryStream; stream : IThriftStream; trans : IStreamTransport; const COPY_ENTIRE_STREAM = 0; begin // read happens after write here, so let's take over the written bytes newBuf := TMemoryStream.Create; if not forWrite then newBuf.CopyFrom( FMemBuffer, COPY_ENTIRE_STREAM); FMemBuffer := newBuf; FMemBuffer.Position := 0; // layered transports anyone? stream := TThriftStreamAdapterDelphi.Create( newBuf, TRUE); if forWrite then trans := TStreamTransportImpl.Create( nil, stream, FConfig) else trans := TStreamTransportImpl.Create( stream, nil, FConfig); case layered of trns_Framed : FTransport := TFramedTransportImpl.Create( trans); trns_Buffered : FTransport := TBufferedTransportImpl.Create( trans); else FTransport := trans; end; if not FTransport.IsOpen then FTransport.Open; case ptyp of prot_Binary : result := TBinaryProtocolImpl.Create(trans); prot_Compact : result := TCompactProtocolImpl.Create(trans); prot_JSON : result := TJSONProtocolImpl.Create(trans); else ASSERT(FALSE); end; end; function TPerformanceTests.GetProtocolTransportName(const ptyp : TKnownProtocol; const layered : TLayeredTransport) : string; begin case layered of trns_Framed : result := ' + framed'; trns_Buffered : result := ' + buffered'; else result := ''; end; case ptyp of prot_Binary : result := 'binary' + result; prot_Compact : result := 'compact' + result; prot_JSON : result := 'JSON' + result; else ASSERT(FALSE); end; end; end. thrift-0.23.0/lib/delphi/test/testsuite/client/UnitTests.pas0000664000175000017500000002511615165535636024352 0ustar00buildbuild00000000000000(* * 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. thrift-0.23.0/lib/delphi/test/testsuite/client/TestLogger.pas0000664000175000017500000001162715165535636024471 0ustar00buildbuild00000000000000(* * 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. thrift-0.23.0/lib/delphi/test/testsuite/server/0000775000175000017500000000000015165535636021726 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/testsuite/server/TestServerEvents.pas0000664000175000017500000001015115165535636025724 0ustar00buildbuild00000000000000(* * 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 TestServerEvents; interface uses SysUtils, Thrift, Thrift.Protocol, Thrift.Transport, Thrift.Server, ConsoleHelper; type TRequestEventsImpl = class( TInterfacedObject, IRequestEvents) protected FStart : TDateTime; // IRequestProcessingEvents procedure PreRead; procedure PostRead; procedure PreWrite; procedure PostWrite; procedure OnewayComplete; procedure UnhandledError( const e : Exception); procedure CleanupContext; public constructor Create; end; TProcessorEventsImpl = class( TInterfacedObject, IProcessorEvents) protected FReqs : Integer; // IProcessorEvents procedure Processing( const transport : ITransport); function CreateRequestContext( const aFunctionName : string) : IRequestEvents; procedure CleanupContext; public constructor Create; end; TServerEventsImpl = class( TInterfacedObject, IServerEvents) protected // IServerEvents procedure PreServe; procedure PreAccept; function CreateProcessingContext( const input, output : IProtocol) : IProcessorEvents; end; implementation { TServerEventsImpl } procedure TServerEventsImpl.PreServe; begin Console.WriteLine('ServerEvents: Server starting to serve requests'); end; procedure TServerEventsImpl.PreAccept; begin Console.WriteLine('ServerEvents: Server transport is ready to accept incoming calls'); end; function TServerEventsImpl.CreateProcessingContext(const input, output: IProtocol): IProcessorEvents; begin result := TProcessorEventsImpl.Create; end; { TProcessorEventsImpl } constructor TProcessorEventsImpl.Create; begin inherited Create; FReqs := 0; Console.WriteLine('ProcessorEvents: Client connected, processing begins'); end; procedure TProcessorEventsImpl.Processing(const transport: ITransport); begin Console.WriteLine('ProcessorEvents: Processing of incoming request begins'); end; function TProcessorEventsImpl.CreateRequestContext( const aFunctionName: string): IRequestEvents; begin result := TRequestEventsImpl.Create; Inc( FReqs); end; procedure TProcessorEventsImpl.CleanupContext; begin Console.WriteLine( 'ProcessorEvents: completed after handling '+IntToStr(FReqs)+' requests.'); end; { TRequestEventsImpl } constructor TRequestEventsImpl.Create; begin inherited Create; FStart := Now; Console.WriteLine('RequestEvents: New request'); end; procedure TRequestEventsImpl.PreRead; begin Console.WriteLine('RequestEvents: Reading request message ...'); end; procedure TRequestEventsImpl.PostRead; begin Console.WriteLine('RequestEvents: Reading request message completed'); end; procedure TRequestEventsImpl.PreWrite; begin Console.WriteLine('RequestEvents: Writing response message ...'); end; procedure TRequestEventsImpl.PostWrite; begin Console.WriteLine('RequestEvents: Writing response message completed'); end; procedure TRequestEventsImpl.OnewayComplete; begin Console.WriteLine('RequestEvents: Oneway message processed'); end; procedure TRequestEventsImpl.UnhandledError(const e: Exception); begin Console.WriteLine('RequestEvents: Unhandled exception of type '+e.classname); end; procedure TRequestEventsImpl.CleanupContext; var millis : Double; begin millis := (Now - FStart) * (24*60*60*1000); Console.WriteLine( 'Request processing completed in '+IntToStr(Round(millis))+' ms'); end; end. thrift-0.23.0/lib/delphi/test/testsuite/server/TestServer.pas0000664000175000017500000005417615165535636024556 0ustar00buildbuild00000000000000(* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *) unit TestServer; {$I ../src/Thrift.Defines.inc} {$WARN SYMBOL_PLATFORM OFF} {.$DEFINE RunEndless} // activate to interactively stress-test the server stop routines via Ctrl+C interface uses Windows, SysUtils, Generics.Collections, Thrift.Server, Thrift.Transport, Thrift.Transport.Pipes, Thrift.Protocol, Thrift.Protocol.JSON, Thrift.Protocol.Compact, Thrift.Collections, Thrift.Configuration, Thrift.Utils, Thrift.Test, Thrift, TestConstants, TestServerEvents, ConsoleHelper, Contnrs; type TTestServer = class public type ITestHandler = interface( TThriftTest.Iface ) procedure SetServer( const AServer : IServer ); procedure TestStop; end; TTestHandlerImpl = class( TInterfacedObject, ITestHandler, TThriftTest.Iface) strict private FServer : IServer; strict protected procedure testVoid(); function testBool(thing: Boolean): Boolean; function testString(const thing: string): string; function testByte(thing: ShortInt): ShortInt; function testI32(thing: Integer): Integer; function testI64(const thing: Int64): Int64; function testDouble(const thing: Double): Double; function testBinary(const thing: TBytes): TBytes; function testUuid(const thing: System.TGuid): System.TGuid; function testStruct(const thing: IXtruct): IXtruct; function testNest(const thing: IXtruct2): IXtruct2; function testMap(const thing: IThriftDictionary): IThriftDictionary; function testStringMap(const thing: IThriftDictionary): IThriftDictionary; function testSet(const thing: IThriftHashSet): IThriftHashSet; function testList(const thing: IThriftList): IThriftList; function testEnum(thing: TNumberz): TNumberz; function testTypedef(const thing: Int64): Int64; function testMapMap(hello: Integer): IThriftDictionary>; function testInsanity(const argument: IInsanity): IThriftDictionary>; function testMulti(arg0: ShortInt; arg1: Integer; const arg2: Int64; const arg3: IThriftDictionary; arg4: TNumberz; const arg5: Int64): IXtruct; procedure testException(const arg: string); function testMultiException(const arg0: string; const arg1: string): IXtruct; procedure testOneway(secondsToSleep: Integer); procedure TestStop; procedure SetServer( const AServer : IServer ); end; class procedure PrintCmdLineHelp; class procedure InvalidArgs; class function IsSwitch( const aArgument, aSwitch : string; out sValue : string) : Boolean; class procedure LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport); class procedure Execute( const arguments : array of string); end; implementation var g_Handler : TTestServer.ITestHandler = nil; function MyConsoleEventHandler( dwCtrlType : DWORD) : BOOL; stdcall; // Note that this Handler procedure is called from another thread var handler : TTestServer.ITestHandler; begin result := TRUE; try case dwCtrlType of CTRL_C_EVENT : Console.WriteLine( 'Ctrl+C pressed'); CTRL_BREAK_EVENT : Console.WriteLine( 'Ctrl+Break pressed'); CTRL_CLOSE_EVENT : Console.WriteLine( 'Received CloseTask signal'); CTRL_LOGOFF_EVENT : Console.WriteLine( 'Received LogOff signal'); CTRL_SHUTDOWN_EVENT : Console.WriteLine( 'Received Shutdown signal'); else Console.WriteLine( 'Received console event #'+IntToStr(Integer(dwCtrlType))); end; handler := g_Handler; if handler <> nil then handler.TestStop; except // catch all end; end; { TTestServer.TTestHandlerImpl } procedure TTestServer.TTestHandlerImpl.SetServer( const AServer: IServer); begin FServer := AServer; end; function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt; begin Console.WriteLine('testByte("' + IntToStr( thing) + '")'); Result := thing; end; function TTestServer.TTestHandlerImpl.testDouble( const thing: Double): Double; begin Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")'); Result := thing; end; function TTestServer.TTestHandlerImpl.testBinary(const thing: TBytes): TBytes; begin Console.WriteLine('testBinary('+IntToStr(Length(thing)) + ' bytes)'); Result := thing; end; function TTestServer.TTestHandlerImpl.testUuid(const thing: System.TGuid): System.TGuid; begin Console.WriteLine('testUuid('+GUIDToString(thing)+')'); Result := thing; end; function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz; begin Console.WriteLine('testEnum(' + EnumUtils.ToString(Ord(thing)) + ')'); Result := thing; end; procedure TTestServer.TTestHandlerImpl.testException(const arg: string); begin Console.WriteLine('testException(' + arg + ')'); if ( arg = 'Xception') then begin raise TXception.Create( 1001, arg); end; if (arg = 'TException') then begin raise TException.Create('TException'); end; // else do not throw anything end; function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer; begin Console.WriteLine('testI32("' + IntToStr( thing) + '")'); Result := thing; end; function TTestServer.TTestHandlerImpl.testI64( const thing: Int64): Int64; begin Console.WriteLine('testI64("' + IntToStr( thing) + '")'); Result := thing; end; function TTestServer.TTestHandlerImpl.testInsanity( const argument: IInsanity): IThriftDictionary>; var looney : IInsanity; first_map : IThriftDictionary; second_map : IThriftDictionary; insane : IThriftDictionary>; begin Console.Write('testInsanity('); if argument <> nil then Console.Write(argument.ToString); Console.WriteLine(')'); (** * So you think you've got this all worked, out eh? * * Creates a the returned map with these values and prints it out: * { 1 => { 2 => argument, * 3 => argument, * }, * 2 => { 6 => , }, * } * @return map> - a map with the above values *) first_map := TThriftDictionaryImpl.Create; second_map := TThriftDictionaryImpl.Create; first_map.AddOrSetValue( TNumberz.TWO, argument); first_map.AddOrSetValue( TNumberz.THREE, argument); looney := TInsanityImpl.Create; second_map.AddOrSetValue( TNumberz.SIX, looney); insane := TThriftDictionaryImpl>.Create; insane.AddOrSetValue( 1, first_map); insane.AddOrSetValue( 2, second_map); Result := insane; end; function TTestServer.TTestHandlerImpl.testList( const thing: IThriftList): IThriftList; begin Console.Write('testList('); if thing <> nil then Console.Write(thing.ToString); Console.WriteLine(')'); Result := thing; end; function TTestServer.TTestHandlerImpl.testMap( const thing: IThriftDictionary): IThriftDictionary; begin Console.Write('testMap('); if thing <> nil then Console.Write(thing.ToString); Console.WriteLine(')'); Result := thing; end; function TTestServer.TTestHandlerImpl.TestMapMap( hello: Integer): IThriftDictionary>; var mapmap : IThriftDictionary>; pos : IThriftDictionary; neg : IThriftDictionary; i : Integer; begin Console.WriteLine('testMapMap(' + IntToStr( hello) + ')'); mapmap := TThriftDictionaryImpl>.Create; pos := TThriftDictionaryImpl.Create; neg := TThriftDictionaryImpl.Create; for i := 1 to 4 do begin pos.AddOrSetValue( i, i); neg.AddOrSetValue( -i, -i); end; mapmap.AddOrSetValue(4, pos); mapmap.AddOrSetValue( -4, neg); Result := mapmap; end; function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer; const arg2: Int64; const arg3: IThriftDictionary; arg4: TNumberz; const arg5: Int64): IXtruct; var hello : IXtruct; begin Console.WriteLine('testMulti()'); hello := TXtructImpl.Create; hello.String_thing := 'Hello2'; hello.Byte_thing := arg0; hello.I32_thing := arg1; hello.I64_thing := arg2; Result := hello; end; function TTestServer.TTestHandlerImpl.testMultiException( const arg0, arg1: string): IXtruct; var x2 : TXception2; begin Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')'); if ( arg0 = 'Xception') then begin raise TXception.Create( 1001, 'This is an Xception'); // test the new rich CTOR end; if ( arg0 = 'Xception2') then begin x2 := TXception2.Create; // the old way still works too? x2.ErrorCode := 2002; x2.Struct_thing := TXtructImpl.Create; x2.Struct_thing.String_thing := 'This is an Xception2'; x2.UpdateMessageProperty; raise x2; end; Result := TXtructImpl.Create; Result.String_thing := arg1; end; function TTestServer.TTestHandlerImpl.testNest( const thing: IXtruct2): IXtruct2; begin Console.Write('testNest('); if thing <> nil then Console.Write(thing.ToString); Console.WriteLine(')'); Result := thing; end; procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer); begin Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...'); Sleep(secondsToSleep * 1000); Console.WriteLine('testOneway finished'); end; function TTestServer.TTestHandlerImpl.testSet( const thing: IThriftHashSet):IThriftHashSet; begin Console.Write('testSet('); if thing <> nil then Console.Write(thing.ToString); Console.WriteLine(')');; Result := thing; end; procedure TTestServer.TTestHandlerImpl.testStop; begin if FServer <> nil then begin FServer.Stop; end; end; function TTestServer.TTestHandlerImpl.testBool(thing: Boolean): Boolean; begin Console.WriteLine('testBool(' + BoolToStr(thing,true) + ')'); Result := thing; end; function TTestServer.TTestHandlerImpl.testString( const thing: string): string; begin Console.WriteLine('teststring("' + thing + '")'); Result := thing; end; function TTestServer.TTestHandlerImpl.testStringMap( const thing: IThriftDictionary): IThriftDictionary; begin Console.Write('testStringMap('); if thing <> nil then Console.Write(thing.ToString); Console.WriteLine(')'); Result := thing; end; function TTestServer.TTestHandlerImpl.testTypedef( const thing: Int64): Int64; begin Console.WriteLine('testTypedef(' + IntToStr( thing) + ')'); Result := thing; end; procedure TTestServer.TTestHandlerImpl.TestVoid; begin Console.WriteLine('testVoid()'); end; function TTestServer.TTestHandlerImpl.testStruct( const thing: IXtruct): IXtruct; begin Console.Write('testStruct('); if thing <> nil then Console.Write(thing.ToString); Console.WriteLine(')'); Result := thing; end; { TTestServer } class procedure TTestServer.PrintCmdLineHelp; const HELPTEXT = ' [options]'#10 + #10 + 'Allowed options:'#10 + ' -h | --help Produces this help message'#10 + ' --port=arg (9090) Port number to connect'#10 + ' --pipe=arg Windows Named Pipe (e.g. MyThriftPipe)'#10 + ' --anon-pipes Windows Anonymous Pipes server, auto-starts client.exe'#10 + ' --server-type=arg (simple) Type of server (simple, thread-pool, threaded, nonblocking)'#10 + ' --transport=arg (sockets) Transport: buffered, framed, anonpipe'#10 + ' --protocol=arg (binary) Protocol: binary, compact, json'#10 + ' --ssl Encrypted Transport using SSL'#10 + ' --processor-events Enable processor-events'#10 + ' -n=num | --workers=num (4) Number of thread-pool server workers'#10 ; begin Console.WriteLine( ChangeFileExt(ExtractFileName(ParamStr(0)),'') + HELPTEXT); end; class procedure TTestServer.InvalidArgs; begin Console.WriteLine( 'Invalid args.'); Console.WriteLine( ChangeFileExt(ExtractFileName(ParamStr(0)),'') + ' -h for more information'); Abort; end; class function TTestServer.IsSwitch( const aArgument, aSwitch : string; out sValue : string) : Boolean; begin sValue := ''; result := (Copy( aArgument, 1, Length(aSwitch)) = aSwitch); if result then begin if (Copy( aArgument, 1, Length(aSwitch)+1) = (aSwitch+'=')) then sValue := Copy( aArgument, Length(aSwitch)+2, MAXINT); end; end; class procedure TTestServer.LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport); //Launch child process and pass R/W anonymous pipe handles on cmd line. //This is a simple example and does not include elevation or other //advanced features. var pi : PROCESS_INFORMATION; si : STARTUPINFO; sArg, sHandles, sCmdLine : string; i : Integer; begin GetStartupInfo( si); //set startupinfo for the spawned process // preformat handles args sHandles := Format( '%d %d', [ Integer(transport.ClientAnonRead), Integer(transport.ClientAnonWrite)]); // pass all settings to client sCmdLine := app; for i := 1 to ParamCount do begin sArg := ParamStr(i); // add anonymous handles and quote strings where appropriate if sArg = '--anon-pipes' then sArg := sArg +' '+ sHandles else begin if Pos(' ',sArg) > 0 then sArg := '"'+sArg+'"'; end;; sCmdLine := sCmdLine +' '+ sArg; end; // spawn the child process Console.WriteLine('Starting client '+sCmdLine); Win32Check( CreateProcess( nil, PChar(sCmdLine), nil,nil,TRUE,0,nil,nil,si,pi)); CloseHandle( pi.hThread); CloseHandle( pi.hProcess); end; class procedure TTestServer.Execute( const arguments : array of string); var Port : Integer; ServerEvents : Boolean; sPipeName : string; testHandler : ITestHandler; testProcessor : IProcessor; ServerTrans : IServerTransport; ServerEngine : IServer; anonymouspipe : IAnonymousPipeServerTransport; namedpipe : INamedPipeServerTransport; TransportFactory : ITransportFactory; ProtocolFactory : IProtocolFactory; iArg, numWorker : Integer; sArg, sValue : string; protType : TKnownProtocol; servertype : TServerType; endpoint : TEndpointTransport; layered : TLayeredTransports; UseSSL : Boolean; // include where appropriate (TLayeredTransport?) config : IThriftConfiguration; const PIPEFLAGS = [ TNamedPipeFlag.OnlyLocalClients]; begin try ServerEvents := FALSE; protType := prot_Binary; servertype := srv_Simple; endpoint := trns_Sockets; layered := []; UseSSL := FALSE; Port := 9090; sPipeName := ''; numWorker := 4; iArg := 0; while iArg < Length(arguments) do begin sArg := arguments[iArg]; Inc(iArg); // Allowed options: if IsSwitch( sArg, '-h', sValue) or IsSwitch( sArg, '--help', sValue) then begin // -h | --help produce help message PrintCmdLineHelp; Exit; end else if IsSwitch( sArg, '--port', sValue) then begin // --port arg (=9090) Port number to listen Port := StrToIntDef( sValue, Port); end else if IsSwitch( sArg, '--anon-pipes', sValue) then begin endpoint := trns_AnonPipes; end else if IsSwitch( sArg, '--pipe', sValue) then begin // --pipe arg Windows Named Pipe (e.g. MyThriftPipe) endpoint := trns_NamedPipes; sPipeName := sValue; // --pipe end else if IsSwitch( sArg, '--server-type', sValue) then begin // --server-type arg (=simple) type of server, // arg = "simple", "thread-pool", "threaded", or "nonblocking" if sValue = 'simple' then servertype := srv_Simple else if sValue = 'thread-pool' then servertype := srv_Threadpool else if sValue = 'threaded' then servertype := srv_Threaded else if sValue = 'nonblocking' then servertype := srv_Nonblocking else InvalidArgs; end else if IsSwitch( sArg, '--transport', sValue) then begin // --transport arg (=buffered) transport: buffered, framed, http if sValue = 'buffered' then Include( layered, trns_Buffered) else if sValue = 'framed' then Include( layered, trns_Framed) else if sValue = 'http' then endpoint := trns_MsxmlHttp else if sValue = 'winhttp' then endpoint := trns_WinHttp else if sValue = 'anonpipe' then endpoint := trns_AnonPipes else InvalidArgs; end else if IsSwitch( sArg, '--protocol', sValue) then begin // --protocol arg (=binary) protocol: binary, compact, json if sValue = 'binary' then protType := prot_Binary else if sValue = 'compact' then protType := prot_Compact else if sValue = 'json' then protType := prot_JSON else InvalidArgs; end else if IsSwitch( sArg, '--ssl', sValue) then begin // --ssl Encrypted Transport using SSL UseSSL := TRUE; end else if IsSwitch( sArg, '--processor-events', sValue) then begin // --processor-events processor-events ServerEvents := TRUE; end else if IsSwitch( sArg, '-n', sValue) or IsSwitch( sArg, '--workers', sValue) then begin // -n [ --workers ] arg (=4) Number of thread pools workers. // Only valid for thread-pool server type numWorker := StrToIntDef(sValue,4); end else begin InvalidArgs; end; end; Console.WriteLine('Server configuration: '); // create protocol factory, default to BinaryProtocol case protType of prot_Binary : ProtocolFactory := TBinaryProtocolImpl.TFactory.Create; prot_JSON : ProtocolFactory := TJSONProtocolImpl.TFactory.Create; prot_Compact : ProtocolFactory := TCompactProtocolImpl.TFactory.Create; else raise Exception.Create('Unhandled protocol'); end; ASSERT( ProtocolFactory <> nil); Console.WriteLine('- '+THRIFT_PROTOCOLS[protType]+' protocol'); config := nil; // TODO case endpoint of trns_Sockets : begin Console.WriteLine('- sockets (port '+IntToStr(port)+')'); if (trns_Buffered in layered) then Console.WriteLine('- buffered'); servertrans := TServerSocketImpl.Create( Port, DEFAULT_THRIFT_TIMEOUT, (trns_Buffered in layered)); end; trns_MsxmlHttp, trns_WinHttp : begin raise Exception.Create('HTTP server transport not implemented'); end; trns_NamedPipes : begin Console.WriteLine('- named pipe ('+sPipeName+')'); namedpipe := TNamedPipeServerTransportImpl.Create( sPipeName, PIPEFLAGS, config); servertrans := namedpipe; end; trns_AnonPipes : begin Console.WriteLine('- anonymous pipes'); anonymouspipe := TAnonymousPipeServerTransportImpl.Create; servertrans := anonymouspipe; end else raise Exception.Create('Unhandled endpoint transport'); end; ASSERT( servertrans <> nil); if UseSSL then begin raise Exception.Create('SSL not implemented'); end; if (trns_Framed in layered) then begin Console.WriteLine('- framed transport'); TransportFactory := TFramedTransportImpl.TFactory.Create; end else begin TransportFactory := TTransportFactoryImpl.Create; end; ASSERT( TransportFactory <> nil); testHandler := TTestHandlerImpl.Create; testProcessor := TThriftTest.TProcessorImpl.Create( testHandler ); case servertype of srv_Simple : begin ServerEngine := TSimpleServer.Create( testProcessor, ServerTrans, TransportFactory, ProtocolFactory); end; srv_Nonblocking : begin raise Exception.Create(SERVER_TYPES[servertype]+' server not implemented'); end; srv_Threadpool, srv_Threaded: begin if numWorker > 1 then {use here}; raise Exception.Create(SERVER_TYPES[servertype]+' server not implemented'); end; else raise Exception.Create('Unhandled server type'); end; ASSERT( ServerEngine <> nil); testHandler.SetServer( ServerEngine); // test events? if ServerEvents then begin Console.WriteLine('- server events test enabled'); ServerEngine.ServerEvents := TServerEventsImpl.Create; end; // start the client now when we have the anon handles, but before the server starts if endpoint = trns_AnonPipes then LaunchAnonPipeChild( ExtractFilePath(ParamStr(0))+'client.exe', anonymouspipe); // install Ctrl+C handler before the server starts g_Handler := testHandler; SetConsoleCtrlHandler( @MyConsoleEventHandler, TRUE); Console.WriteLine(''); repeat Console.WriteLine('Starting the server ...'); serverEngine.Serve; until {$IFDEF RunEndless} FALSE {$ELSE} TRUE {$ENDIF}; testHandler.SetServer( nil); g_Handler := nil; except on E: EAbort do raise; on E: Exception do begin Console.WriteLine( E.Message + #10 + E.StackTrace ); end; end; Console.WriteLine( 'done.'); end; end. thrift-0.23.0/lib/delphi/test/ConsoleHelper.pas0000664000175000017500000000652515165535636021646 0ustar00buildbuild00000000000000(* * 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 ConsoleHelper; interface uses Classes, SysUtils, SyncObjs; type TThriftConsole = class strict private FLock : TCriticalSection; strict protected procedure Lock; procedure UnLock; public constructor Create; destructor Destroy; override; procedure Write( const S: string); virtual; procedure WriteLine( const S: string); virtual; end; TGUIConsole = class( TThriftConsole ) strict private FLineBreak : Boolean; FMemo : TStrings; procedure InternalWrite( const S: string; bWriteLine: Boolean); public constructor Create( AMemo: TStrings); procedure Write( const S: string); override; procedure WriteLine( const S: string); override; end; function Console: TThriftConsole; procedure ChangeConsole( AConsole: TThriftConsole ); procedure RestoreConsoleToDefault; implementation var FDefaultConsole : TThriftConsole; FConsole : TThriftConsole; function Console: TThriftConsole; begin Result := FConsole; end; { TThriftConsole } constructor TThriftConsole.Create; begin inherited Create; FLock := TCriticalSection.Create; end; destructor TThriftConsole.Destroy; begin FreeAndNil( FLock); inherited Destroy; end; procedure TThriftConsole.Lock; begin FLock.Enter; end; procedure TThriftConsole.UnLock; begin FLock.Leave; end; procedure TThriftConsole.Write(const S: string); begin Lock; try System.Write( S ); finally Unlock; end; end; procedure TThriftConsole.WriteLine(const S: string); begin Lock; try System.Writeln( S ); finally Unlock; end; end; procedure ChangeConsole( AConsole: TThriftConsole ); begin FConsole := AConsole; end; procedure RestoreConsoleToDefault; begin FConsole := FDefaultConsole; end; { TGUIConsole } constructor TGUIConsole.Create( AMemo: TStrings); begin inherited Create; FMemo := AMemo; FLineBreak := True; end; procedure TGUIConsole.InternalWrite(const S: string; bWriteLine: Boolean); var idx : Integer; begin Lock; try if FLineBreak then begin FMemo.Add( S ) end else begin idx := FMemo.Count - 1; if idx < 0 then FMemo.Add( S ) else FMemo[idx] := FMemo[idx] + S; end; FLineBreak := bWriteLine; finally Unlock; end; end; procedure TGUIConsole.Write(const S: string); begin InternalWrite( S, False); end; procedure TGUIConsole.WriteLine(const S: string); begin InternalWrite( S, True); end; initialization FDefaultConsole := TThriftConsole.Create; FConsole := FDefaultConsole; finalization FDefaultConsole.Free; FDefaultConsole := nil; end. thrift-0.23.0/lib/delphi/test/maketest.sh0000775000175000017500000000155515165535636020551 0ustar00buildbuild00000000000000#!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ../../../compiler/cpp/thrift --gen delphi -o . ../../../test/ThriftTest.thrift thrift-0.23.0/lib/delphi/test/codegen/0000775000175000017500000000000015165535636017773 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/codegen/README.md0000664000175000017500000000100315165535636021244 0ustar00buildbuild00000000000000Prerequisites ---------------------------------------------- - 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 How to use the test case: ---------------------------------------------- - 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 *EOF* thrift-0.23.0/lib/delphi/test/codegen/run-Pascal-Codegen-Tests.ps10000664000175000017500000001566015165535636025077 0ustar00buildbuild00000000000000# # 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 thrift-0.23.0/lib/delphi/test/skip/0000775000175000017500000000000015165535636017335 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/skip/skiptest_version2.dproj0000664000175000017500000001422515165535636024076 0ustar00buildbuild00000000000000 {DBB2D6D8-0FC6-4329-8408-28B1452B33AD} skiptest_version2.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication skiptest_version2.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 True 12 thrift-0.23.0/lib/delphi/test/skip/skiptest_version2.dpr0000664000175000017500000001631615165535636023550 0ustar00buildbuild00000000000000(* * 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. *) program skiptest_version2; {$APPTYPE CONSOLE} uses Classes, Windows, SysUtils, Skiptest.Two in 'gen-delphi\Skiptest.Two.pas', Thrift in '..\..\src\Thrift.pas', Thrift.Exception in '..\..\src\Thrift.Exception.pas', Thrift.Socket in '..\..\src\Thrift.Socket.pas', Thrift.Transport in '..\..\src\Thrift.Transport.pas', Thrift.Protocol in '..\..\src\Thrift.Protocol.pas', Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas', Thrift.Protocol.Compact in '..\..\src\Thrift.Protocol.Compact.pas', Thrift.Collections in '..\..\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\src\Thrift.Configuration.pas', Thrift.Server in '..\..\src\Thrift.Server.pas', Thrift.Utils in '..\..\src\Thrift.Utils.pas', Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas', Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', Thrift.Stream in '..\..\src\Thrift.Stream.pas'; const REQUEST_EXT = '.request'; RESPONSE_EXT = '.response'; function CreatePing : IPing; var list : IThriftList; set_ : IThriftHashSet; begin result := TPingImpl.Create; result.Version1 := TConstants.SKIPTESTSERVICE_VERSION; result.EnumTest := TPingPongEnum.PingTwo; result.BoolVal := TRUE; result.ByteVal := 2; result.DbVal := 3; result.I16Val := 4; result.I32Val := 5; result.I64Val := 6; result.StrVal := 'seven'; result.StructVal := TPongImpl.Create; result.StructVal.Version1 := -1; result.StructVal.Version2 := -2; result.StructVal.EnumTest := TPingPongEnum.PongTwo; list := TThriftListImpl.Create; list.Add( result.StructVal); list.Add( result.StructVal); set_ := TThriftHashSetImpl.Create; set_.Add( 'one'); set_.Add( 'uno'); set_.Add( 'eins'); set_.Add( 'een'); result.MapVal := TThriftDictionaryImpl< IThriftList, IThriftHashSet>.Create; result.MapVal.Add( list, set_); end; type TDummyServer = class( TInterfacedObject, TSkipTestService.Iface) protected // TSkipTestService.Iface function PingPong(const ping: IPing; const pong: IPong): IPing; end; function TDummyServer.PingPong(const ping: IPing; const pong: IPong): IPing; // TSkipTestService.Iface begin Writeln('- performing request from version '+IntToStr(ping.Version1)+' client'); Writeln( ping.ToString); result := CreatePing; end; function CreateProtocol( protfact : IProtocolFactory; stm : TStream; aForInput : Boolean) : IProtocol; var adapt : IThriftStream; trans : ITransport; begin adapt := TThriftStreamAdapterDelphi.Create( stm, FALSE); if aForInput then trans := TStreamTransportImpl.Create( adapt, nil, TThriftConfigurationImpl.Create) else trans := TStreamTransportImpl.Create( nil, adapt, TThriftConfigurationImpl.Create); result := protfact.GetProtocol( trans); end; procedure CreateRequest( protfact : IProtocolFactory; fname : string); var stm : TFileStream; ping : IPing; proto : IProtocol; client : TSkipTestService.TClient; // we need access to send/recv_pingpong() cliRef : IUnknown; // holds the refcount begin Writeln('- creating new request'); stm := TFileStream.Create( fname+REQUEST_EXT+'.tmp', fmCreate); try ping := CreatePing; // save request data proto := CreateProtocol( protfact, stm, FALSE); client := TSkipTestService.TClient.Create( nil, proto); cliRef := client as IUnknown; client.send_PingPong( ping, ping.StructVal); finally client := nil; // not Free! cliRef := nil; stm.Free; if client = nil then {warning suppressed}; end; DeleteFile( fname+REQUEST_EXT); RenameFile( fname+REQUEST_EXT+'.tmp', fname+REQUEST_EXT); end; procedure ReadResponse( protfact : IProtocolFactory; fname : string); var stm : TFileStream; ping : IPing; proto : IProtocol; client : TSkipTestService.TClient; // we need access to send/recv_pingpong() cliRef : IUnknown; // holds the refcount begin Writeln('- reading response'); stm := TFileStream.Create( fname+RESPONSE_EXT, fmOpenRead); try // load request data proto := CreateProtocol( protfact, stm, TRUE); client := TSkipTestService.TClient.Create( proto, nil); cliRef := client as IUnknown; ping := client.recv_PingPong; finally client := nil; // not Free! cliRef := nil; stm.Free; if client = nil then {warning suppressed}; end; end; procedure ProcessFile( protfact : IProtocolFactory; fname : string); var stmIn, stmOut : TFileStream; protIn, protOut : IProtocol; server : IProcessor; begin Writeln('- processing request'); stmOut := nil; stmIn := TFileStream.Create( fname+REQUEST_EXT, fmOpenRead); try stmOut := TFileStream.Create( fname+RESPONSE_EXT+'.tmp', fmCreate); // process request and write response data protIn := CreateProtocol( protfact, stmIn, TRUE); protOut := CreateProtocol( protfact, stmOut, FALSE); server := TSkipTestService.TProcessorImpl.Create( TDummyServer.Create); server.Process( protIn, protOut); finally server := nil; // not Free! stmIn.Free; stmOut.Free; if server = nil then {warning suppressed}; end; DeleteFile( fname+RESPONSE_EXT); RenameFile( fname+RESPONSE_EXT+'.tmp', fname+RESPONSE_EXT); end; procedure Test( protfact : IProtocolFactory; fname : string); begin // try to read an existing request Writeln; Writeln('Reading data file '+fname); if FileExists( fname + REQUEST_EXT) then begin ProcessFile( protfact, fname); ReadResponse( protfact, fname); end; // create a new request and try to process Writeln; Writeln('Writing data file '+fname); CreateRequest( protfact, fname); ProcessFile( protfact, fname); ReadResponse( protfact, fname); end; const FILE_BINARY = 'pingpong.bin'; FILE_JSON = 'pingpong.json'; FILE_COMPACT = 'pingpong.compact'; begin try Writeln( 'Delphi SkipTest '+IntToStr(TConstants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version); Writeln; Writeln('Binary protocol'); Test( TBinaryProtocolImpl.TFactory.Create, FILE_BINARY); Writeln; Writeln('JSON protocol'); Test( TJSONProtocolImpl.TFactory.Create, FILE_JSON); Writeln; Writeln('Compact protocol'); Test( TCompactProtocolImpl.TFactory.Create, FILE_COMPACT); Writeln; Writeln('Test completed without errors.'); Writeln; Write('Press ENTER to close ...'); Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. thrift-0.23.0/lib/delphi/test/skip/skiptest_version1.dproj0000664000175000017500000001422015165535636024070 0ustar00buildbuild00000000000000 {894CD87B-337B-49F7-BC7D-2D9F65CE8FE0} skiptest_version1.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication skiptest_version1.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 True 12 thrift-0.23.0/lib/delphi/test/skip/idl/0000775000175000017500000000000015165535636020105 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/skip/idl/skiptest_version_1.thrift0000664000175000017500000000224315165535636025163 0ustar00buildbuild00000000000000/* * 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. */ // version 1 of the interface namespace * Skiptest.One const i32 SKIPTESTSERVICE_VERSION = 1 enum PingPongEnum { PingOne = 0, PongOne = 1, } struct Ping { 1 : optional i32 version1 100 : PingPongEnum EnumTest } exception PongFailed { 222 : optional i32 pongErrorCode } service SkipTestService { Ping PingPong( 1: Ping ping) throws (444: PongFailed pof); } // EOFthrift-0.23.0/lib/delphi/test/skip/idl/skiptest_version_2.thrift0000664000175000017500000000367415165535636025175 0ustar00buildbuild00000000000000/* * 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. */ // version 2 of the interface namespace * Skiptest.Two const i32 SKIPTESTSERVICE_VERSION = 2 enum PingPongEnum { PingOne = 0, PongOne = 1, PingTwo = 2, PongTwo = 3, } struct Pong { 1 : optional i32 version1 2 : optional i16 version2 100 : PingPongEnum EnumTest } struct Ping { 1 : optional i32 version1 10 : optional bool boolVal 11 : optional byte byteVal 12 : optional double dbVal 13 : optional i16 i16Val 14 : optional i32 i32Val 15 : optional i64 i64Val 16 : optional string strVal 17 : optional Pong structVal 18 : optional map< list< Pong>, set< string>> mapVal 100 : PingPongEnum EnumTest } exception PingFailed { 1 : optional i32 pingErrorCode } exception PongFailed { 222 : optional i32 pongErrorCode 10 : optional bool boolVal 11 : optional byte byteVal 12 : optional double dbVal 13 : optional i16 i16Val 14 : optional i32 i32Val 15 : optional i64 i64Val 16 : optional string strVal 17 : optional Pong structVal 18 : optional map< list< Pong>, set< string>> mapVal } service SkipTestService { Ping PingPong( 1: Ping ping, 3: Pong pong) throws (1: PingFailed pif, 444: PongFailed pof); } // EOF thrift-0.23.0/lib/delphi/test/skip/README.md0000664000175000017500000000054515165535636020620 0ustar00buildbuild00000000000000These two projects belong together. Both programs simulate server and client for different versions of the same protocol. The intention of this test is to ensure fully working compatibility features of the Delphi Thrift implementation. The expected test result is, that no errors occur with both programs, regardless in which order they might be started. thrift-0.23.0/lib/delphi/test/skip/skiptest_version1.dpr0000664000175000017500000001457215165535636023551 0ustar00buildbuild00000000000000(* * 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. *) program skiptest_version1; {$APPTYPE CONSOLE} uses Classes, Windows, SysUtils, Skiptest.One in 'gen-delphi\Skiptest.One.pas', Thrift in '..\..\src\Thrift.pas', Thrift.Exception in '..\..\src\Thrift.Exception.pas', Thrift.Socket in '..\..\src\Thrift.Socket.pas', Thrift.Transport in '..\..\src\Thrift.Transport.pas', Thrift.Protocol in '..\..\src\Thrift.Protocol.pas', Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas', Thrift.Protocol.Compact in '..\..\src\Thrift.Protocol.Compact.pas', Thrift.Collections in '..\..\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\src\Thrift.Configuration.pas', Thrift.Server in '..\..\src\Thrift.Server.pas', Thrift.Utils in '..\..\src\Thrift.Utils.pas', Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas', Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', Thrift.Stream in '..\..\src\Thrift.Stream.pas'; const REQUEST_EXT = '.request'; RESPONSE_EXT = '.response'; function CreatePing : IPing; begin result := TPingImpl.Create; result.Version1 := TConstants.SKIPTESTSERVICE_VERSION; result.EnumTest := TPingPongEnum.PingOne; end; type TDummyServer = class( TInterfacedObject, TSkipTestService.Iface) protected // TSkipTestService.Iface function PingPong(const ping: IPing): IPing; end; function TDummyServer.PingPong(const ping: IPing): IPing; // TSkipTestService.Iface begin Writeln('- performing request from version '+IntToStr(ping.Version1)+' client'); Writeln( ping.ToString); result := CreatePing; end; function CreateProtocol( protfact : IProtocolFactory; stm : TStream; aForInput : Boolean) : IProtocol; var adapt : IThriftStream; trans : ITransport; begin adapt := TThriftStreamAdapterDelphi.Create( stm, FALSE); if aForInput then trans := TStreamTransportImpl.Create( adapt, nil, TThriftConfigurationImpl.Create) else trans := TStreamTransportImpl.Create( nil, adapt, TThriftConfigurationImpl.Create); result := protfact.GetProtocol( trans); end; procedure CreateRequest( protfact : IProtocolFactory; fname : string); var stm : TFileStream; ping : IPing; proto : IProtocol; client : TSkipTestService.TClient; // we need access to send/recv_pingpong() cliRef : IUnknown; // holds the refcount begin Writeln('- creating new request'); stm := TFileStream.Create( fname+REQUEST_EXT+'.tmp', fmCreate); try ping := CreatePing; // save request data proto := CreateProtocol( protfact, stm, FALSE); client := TSkipTestService.TClient.Create( nil, proto); cliRef := client as IUnknown; client.send_PingPong( ping); finally client := nil; // not Free! cliRef := nil; stm.Free; if client = nil then {warning suppressed}; end; DeleteFile( fname+REQUEST_EXT); RenameFile( fname+REQUEST_EXT+'.tmp', fname+REQUEST_EXT); end; procedure ReadResponse( protfact : IProtocolFactory; fname : string); var stm : TFileStream; ping : IPing; proto : IProtocol; client : TSkipTestService.TClient; // we need access to send/recv_pingpong() cliRef : IUnknown; // holds the refcount begin Writeln('- reading response'); stm := TFileStream.Create( fname+RESPONSE_EXT, fmOpenRead); try // load request data proto := CreateProtocol( protfact, stm, TRUE); client := TSkipTestService.TClient.Create( proto, nil); cliRef := client as IUnknown; ping := client.recv_PingPong; finally client := nil; // not Free! cliRef := nil; stm.Free; if client = nil then {warning suppressed}; end; end; procedure ProcessFile( protfact : IProtocolFactory; fname : string); var stmIn, stmOut : TFileStream; protIn, protOut : IProtocol; server : IProcessor; begin Writeln('- processing request'); stmOut := nil; stmIn := TFileStream.Create( fname+REQUEST_EXT, fmOpenRead); try stmOut := TFileStream.Create( fname+RESPONSE_EXT+'.tmp', fmCreate); // process request and write response data protIn := CreateProtocol( protfact, stmIn, TRUE); protOut := CreateProtocol( protfact, stmOut, FALSE); server := TSkipTestService.TProcessorImpl.Create( TDummyServer.Create); server.Process( protIn, protOut); finally server := nil; // not Free! stmIn.Free; stmOut.Free; if server = nil then {warning suppressed}; end; DeleteFile( fname+RESPONSE_EXT); RenameFile( fname+RESPONSE_EXT+'.tmp', fname+RESPONSE_EXT); end; procedure Test( protfact : IProtocolFactory; fname : string); begin // try to read an existing request Writeln('Reading data file '+fname); if FileExists( fname + REQUEST_EXT) then begin ProcessFile( protfact, fname); ReadResponse( protfact, fname); end; // create a new request and try to process Writeln('Writing data file '+fname); CreateRequest( protfact, fname); ProcessFile( protfact, fname); ReadResponse( protfact, fname); end; const FILE_BINARY = 'pingpong.bin'; FILE_JSON = 'pingpong.json'; FILE_COMPACT = 'pingpong.compact'; begin try Writeln( 'Delphi SkipTest '+IntToStr(TConstants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version); Writeln; Writeln('Binary protocol'); Test( TBinaryProtocolImpl.TFactory.Create, FILE_BINARY); Writeln; Writeln('JSON protocol'); Test( TJSONProtocolImpl.TFactory.Create, FILE_JSON); Writeln; Writeln('Compact protocol'); Test( TCompactProtocolImpl.TFactory.Create, FILE_COMPACT); Writeln; Writeln('Test completed without errors.'); Writeln; Write('Press ENTER to close ...'); Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. thrift-0.23.0/lib/delphi/test/keywords/0000775000175000017500000000000015165535636020236 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/keywords/ReservedKeywords.dproj0000664000175000017500000001257015165535636024612 0ustar00buildbuild00000000000000 {F2E9B6FC-A931-4271-8E30-5A4E402481B4} ReservedKeywords.dpr 12.3 True Debug Win32 Console None DCC32 true true Base true true Base true bin\$(Config)\$(Platform) dcu\$(Project)\$(Config)\$(Platform) 00400000 gen-delphi;..\..\src;$(DCC_UnitSearchPath) WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias) false false false false false DEBUG;$(DCC_Define) false true false RELEASE;$(DCC_Define) 0 false MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 ReservedKeywords.dpr True 12 thrift-0.23.0/lib/delphi/test/keywords/ReservedKeywords.thrift0000664000175000017500000000570015165535636024771 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // make sure generated code does not produce name collisions with predefined keywords namespace delphi System include "ReservedIncluded.thrift" typedef i32 Cardinal typedef string message typedef list< map< Cardinal, message>> program struct unit { 1: Cardinal downto; 2: program procedure; } typedef set< unit> units exception exception1 { 1: program message; 2: unit array; } service constructor { unit Create(1: Cardinal asm; 2: message inherited) throws (1: exception1 label); units Destroy(); } const Cardinal downto = +1 const Cardinal published = -1 enum keywords { record = 1, repeat = 2, deprecated = 3 } struct Struct_lists { 1: list init; 2: list struc; 3: list field; 4: list field_; 5: list tracker; 6: list Self; } struct Struct_structs { 1: Struct_simple init; 2: Struct_simple struc; 3: Struct_simple field; 4: Struct_simple field_; 5: Struct_simple tracker; 6: Struct_simple Self; } struct Struct_simple { 1: bool init; 2: bool struc; 3: bool field; 4: bool field_; 5: bool tracker; 6: bool Self; } struct Struct_strings { 1: string init; 2: string struc; 3: string field; 4: string field_; 5: string tracker; 6: string Self; } struct Struct_binary { 1: binary init; 2: binary struc; 3: binary field; 4: binary field_; 5: binary tracker; 6: binary Self; } typedef i32 IProtocol typedef i32 ITransport typedef i32 IFace typedef i32 IAsync typedef i32 System typedef i32 SysUtils typedef i32 Generics typedef i32 Thrift struct Struct_Thrift_Names { 1: IProtocol IProtocol 2: ITransport ITransport 3: IFace IFace 4: IAsync IAsync 5: System System 6: SysUtils SysUtils 7: Generics Generics 8: Thrift Thrift } enum Thrift4554_Enum { Foo = 0, Bar = 1, Baz = 2, } struct Thrift4554_Struct { 1 : optional double MinValue 2 : optional double MaxValue 3 : optional bool Integer // causes issue 4 : optional Thrift4554_Enum Foo } service deprecate_included_outer extends ReservedIncluded.deprecate_included_inner { void FooBarBaz() } // EOF thrift-0.23.0/lib/delphi/test/keywords/ReservedKeywords.dpr0000664000175000017500000000036715165535636024262 0ustar00buildbuild00000000000000program ReservedKeywords; {$APPTYPE CONSOLE} uses SysUtils, System_, AnnotationTest; begin try { TODO -oUser -cConsole Main : Code hier einfügen } except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. thrift-0.23.0/lib/delphi/test/keywords/ReservedIncluded.thrift0000664000175000017500000000237515165535636024716 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // make sure generated code does not produce name collisions with predefined keywords namespace delphi SysUtils const i32 integer = 42 service deprecate_included_inner { void Foo( ) ( deprecated = "This method has neither 'x' nor \"y\"" ) void Bar( ) ( deprecated = "Fails to deliver 中文 колбаÑа" ) void Baz( ) ( deprecated = "Need this to work with tabs (\t) or Umlauts (äöüÄÖÜß) too" ) void Deprecated() ( deprecated ) // no comment } // EOF thrift-0.23.0/lib/delphi/test/server.dproj0000664000175000017500000001354115165535636020741 0ustar00buildbuild00000000000000 {07CEDA3D-0963-40FE-B3C2-0ED4E24DE067} server.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false bin\$(Config)\$(Platform) DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication server.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 --protocol=compact True 12 thrift-0.23.0/lib/delphi/test/client.dproj0000664000175000017500000001423115165535636020706 0ustar00buildbuild00000000000000 {F262F488-F81C-4B6E-8694-518C54CBB8F3} client.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false bin\$(Config)\$(Platform) DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication client.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 --protocol=compact True 12 thrift-0.23.0/lib/delphi/test/multiplexed/0000775000175000017500000000000015165535636020723 5ustar00buildbuild00000000000000thrift-0.23.0/lib/delphi/test/multiplexed/Multiplex.Test.Server.dproj0000664000175000017500000001472215165535636026137 0ustar00buildbuild00000000000000 {42C6ED3D-36E2-47C5-99B2-02BDA574B9E5} Multiplex.Test.Server.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication Multiplex.Test.Server.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 True 12 thrift-0.23.0/lib/delphi/test/multiplexed/Multiplex.Client.Main.pas0000664000175000017500000000625015165535636025516 0ustar00buildbuild00000000000000(* * 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 Multiplex.Client.Main; {.$DEFINE StressTest} // activate to stress-test the server with frequent connects/disconnects {.$DEFINE PerfTest} // activate to activate the performance test interface uses Windows, SysUtils, Classes, DateUtils, Generics.Collections, Thrift, Thrift.Protocol, Thrift.Protocol.Multiplex, Thrift.Transport.Pipes, Thrift.Transport, Thrift.Stream, Thrift.Collections, Thrift.Configuration, Benchmark, Aggr, Multiplex.Test.Common; type TTestClient = class protected FProtocol : IProtocol; procedure ParseArgs( const args: array of string); procedure Setup; procedure Run; public constructor Create( const args: array of string); class procedure Execute( const args: array of string); end; implementation type IServiceClient = interface ['{7745C1C2-AB20-43BA-B6F0-08BF92DE0BAC}'] procedure Test; end; //--- TTestClient ------------------------------------- class procedure TTestClient.Execute( const args: array of string); var client : TTestClient; begin client := TTestClient.Create(args); try client.Run; finally client.Free; end; end; constructor TTestClient.Create( const args: array of string); begin inherited Create; ParseArgs(args); Setup; end; procedure TTestClient.ParseArgs( const args: array of string); begin if Length(args) <> 0 then raise Exception.Create('No args accepted so far'); end; procedure TTestClient.Setup; var trans : ITransport; config : IThriftConfiguration; begin config := TThriftConfigurationImpl.Create; trans := TSocketImpl.Create( 'localhost', 9090, DEFAULT_THRIFT_TIMEOUT, config); trans := TFramedTransportImpl.Create( trans); trans.Open; FProtocol := TBinaryProtocolImpl.Create( trans, TRUE, TRUE); end; procedure TTestClient.Run; var bench : TBenchmarkService.Iface; aggr : TAggr.Iface; multiplex : IProtocol; i : Integer; begin try multiplex := TMultiplexedProtocol.Create( FProtocol, NAME_BENCHMARKSERVICE); bench := TBenchmarkService.TClient.Create( multiplex); multiplex := TMultiplexedProtocol.Create( FProtocol, NAME_AGGR); aggr := TAggr.TClient.Create( multiplex); for i := 1 to 10 do aggr.addValue( bench.fibonacci(i)); for i in aggr.getValues do Write(IntToStr(i)+' '); WriteLn; except on e:Exception do Writeln(#10+e.Message); end; end; end. thrift-0.23.0/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr0000664000175000017500000000456215165535636025607 0ustar00buildbuild00000000000000(* * 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. *) program Multiplex.Test.Server; {$APPTYPE CONSOLE} uses SysUtils, Multiplex.Server.Main in 'Multiplex.Server.Main.pas', Benchmark in 'gen-delphi\Benchmark.pas', Aggr in 'gen-delphi\Aggr.pas', ConsoleHelper in '..\ConsoleHelper.pas', Thrift in '..\..\src\Thrift.pas', Thrift.Exception in '..\..\src\Thrift.Exception.pas', Thrift.Socket in '..\..\src\Thrift.Socket.pas', Thrift.Transport in '..\..\src\Thrift.Transport.pas', Thrift.Transport.Pipes in '..\..\src\Thrift.Transport.Pipes.pas', Thrift.Protocol in '..\..\src\Thrift.Protocol.pas', Thrift.Protocol.Multiplex in '..\..\src\Thrift.Protocol.Multiplex.pas', Thrift.Processor.Multiplex in '..\..\src\Thrift.Processor.Multiplex.pas', Thrift.Configuration in '..\..\src\Thrift.Configuration.pas', Thrift.Collections in '..\..\src\Thrift.Collections.pas', Thrift.Server in '..\..\src\Thrift.Server.pas', Thrift.Utils in '..\..\src\Thrift.Utils.pas', Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas', Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', Thrift.Stream in '..\..\src\Thrift.Stream.pas'; var nParamCount : Integer; args : array of string; i : Integer; arg : string; s : string; begin try Writeln( 'Multiplex TestServer '+Thrift.Version); nParamCount := ParamCount; SetLength( args, nParamCount); for i := 1 to nParamCount do begin arg := ParamStr( i ); args[i-1] := arg; end; TTestServer.Execute( args ); Writeln('Press ENTER to close ... '); Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. thrift-0.23.0/lib/delphi/test/multiplexed/Multiplex.Test.Client.dproj0000664000175000017500000001453215165535636026106 0ustar00buildbuild00000000000000 {59132A87-6294-4E25-AE9C-7CD17CD4400D} Multiplex.Test.Client.dpr True Debug Win32 Console None DCC32 12.3 true true Base true true Base true dcu\$(Project)\$(Config)\$(Platform) bin\$(Config)\$(Platform) false 00400000 WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) false false false false false RELEASE;$(DCC_Define) 0 false DEBUG;$(DCC_Define) false true MainSource Cfg_2 Base Base Cfg_1 Base Delphi.Personality.12 VCLApplication Multiplex.Test.Client.dpr False False 1 0 0 0 False False False False False 1031 1252 1.0.0.0 1.0.0.0 True 12 thrift-0.23.0/lib/delphi/test/multiplexed/Multiplex.Server.Main.pas0000664000175000017500000001216615165535636025551 0ustar00buildbuild00000000000000(* * 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 Multiplex.Server.Main; {$WARN SYMBOL_PLATFORM OFF} {.$DEFINE RunEndless} // activate to interactively stress-test the server stop routines via Ctrl+C interface uses Windows, SysUtils, Generics.Collections, Thrift.Server, Thrift.Transport, Thrift.Transport.Pipes, Thrift.Protocol, Thrift.Protocol.Multiplex, Thrift.Processor.Multiplex, Thrift.Collections, Thrift.Configuration, Thrift.Utils, Thrift, Benchmark, // in gen-delphi folder Aggr, // in gen-delphi folder Multiplex.Test.Common, ConsoleHelper, Contnrs; type TTestServer = class public type ITestHandler = interface ['{CAE09AAB-80FB-48E9-B3A8-7F9B96F5419A}'] procedure SetServer( const AServer : IServer ); end; protected type TTestHandlerImpl = class( TInterfacedObject, ITestHandler) private FServer : IServer; protected // ITestHandler procedure SetServer( const AServer : IServer ); property Server : IServer read FServer write SetServer; end; TBenchmarkServiceImpl = class( TTestHandlerImpl, TBenchmarkService.Iface) protected // TBenchmarkService.Iface function fibonacci(n: ShortInt): Integer; end; TAggrImpl = class( TTestHandlerImpl, TAggr.Iface) protected FList : IThriftList; // TAggr.Iface procedure addValue(value: Integer); function getValues(): IThriftList; public constructor Create; destructor Destroy; override; end; public class procedure Execute( const args: array of string); end; implementation { TTestServer.TTestHandlerImpl } procedure TTestServer.TTestHandlerImpl.SetServer( const AServer: IServer); begin FServer := AServer; end; { TTestServer.TBenchmarkServiceImpl } function TTestServer.TBenchmarkServiceImpl.fibonacci(n: ShortInt): Integer; var prev, next : Integer; begin prev := 0; result := 1; while n > 0 do begin next := result + prev; prev := result; result := next; Dec(n); end; end; { TTestServer.TAggrImpl } constructor TTestServer.TAggrImpl.Create; begin inherited Create; FList := TThriftListImpl.Create; end; destructor TTestServer.TAggrImpl.Destroy; begin try FreeAndNil( FList); finally inherited Destroy; end; end; procedure TTestServer.TAggrImpl.addValue(value: Integer); begin FList.Add( value); end; function TTestServer.TAggrImpl.getValues(): IThriftList; begin result := FList; end; { TTestServer } class procedure TTestServer.Execute( const args: array of string); var TransportFactory : ITransportFactory; ProtocolFactory : IProtocolFactory; ServerTrans : IServerTransport; benchHandler : TBenchmarkService.Iface; aggrHandler : TAggr.Iface; benchProcessor : IProcessor; aggrProcessor : IProcessor; multiplex : IMultiplexedProcessor; ServerEngine : IServer; config : IThriftConfiguration; begin try config := TThriftConfigurationImpl.Create; // create protocol factory, default to BinaryProtocol ProtocolFactory := TBinaryProtocolImpl.TFactory.Create( TRUE, TRUE); servertrans := TServerSocketImpl.Create( 9090, DEFAULT_THRIFT_TIMEOUT, FALSE, config); TransportFactory := TFramedTransportImpl.TFactory.Create; benchHandler := TBenchmarkServiceImpl.Create; benchProcessor := TBenchmarkService.TProcessorImpl.Create( benchHandler); aggrHandler := TAggrImpl.Create; aggrProcessor := TAggr.TProcessorImpl.Create( aggrHandler); multiplex := TMultiplexedProcessorImpl.Create; multiplex.RegisterProcessor( NAME_BENCHMARKSERVICE, benchProcessor); multiplex.RegisterProcessor( NAME_AGGR, aggrProcessor); ServerEngine := TSimpleServer.Create( multiplex, ServerTrans, TransportFactory, ProtocolFactory); (benchHandler as ITestHandler).SetServer( ServerEngine); (aggrHandler as ITestHandler).SetServer( ServerEngine); Console.WriteLine('Starting the server ...'); ServerEngine.serve(); (benchHandler as ITestHandler).SetServer( nil); (aggrHandler as ITestHandler).SetServer( nil); except on E: Exception do begin Console.Write( E.Message); end; end; Console.WriteLine( 'done.'); end; end. thrift-0.23.0/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr0000664000175000017500000000437415165535636025560 0ustar00buildbuild00000000000000(* * 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. *) program Multiplex.Test.Client; {$APPTYPE CONSOLE} uses SysUtils, Multiplex.Client.Main in 'Multiplex.Client.Main.pas', Benchmark in 'gen-delphi\Benchmark.pas', Aggr in 'gen-delphi\Aggr.pas', Thrift in '..\..\src\Thrift.pas', Thrift.Socket in '..\..\src\Thrift.Socket.pas', Thrift.Exception in '..\..\src\Thrift.Exception.pas', Thrift.Transport in '..\..\src\Thrift.Transport.pas', Thrift.Transport.Pipes in '..\..\src\Thrift.Transport.Pipes.pas', Thrift.Protocol in '..\..\src\Thrift.Protocol.pas', Thrift.Protocol.Multiplex in '..\..\src\Thrift.Protocol.Multiplex.pas', Thrift.Collections in '..\..\src\Thrift.Collections.pas', Thrift.Configuration in '..\..\src\Thrift.Configuration.pas', Thrift.Server in '..\..\src\Thrift.Server.pas', Thrift.Stream in '..\..\src\Thrift.Stream.pas', Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas', Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas', Thrift.Utils in '..\..\src\Thrift.Utils.pas'; var nParamCount : Integer; args : array of string; i : Integer; arg : string; s : string; begin try Writeln( 'Multiplex TestClient '+Thrift.Version); nParamCount := ParamCount; SetLength( args, nParamCount); for i := 1 to nParamCount do begin arg := ParamStr( i ); args[i-1] := arg; end; TTestClient.Execute( args ); Readln; except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := $FFFF; end; end; end. thrift-0.23.0/lib/delphi/test/multiplexed/Multiplex.Test.Common.pas0000664000175000017500000000170415165535636025562 0ustar00buildbuild00000000000000(* * 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 Multiplex.Test.Common; interface const NAME_BENCHMARKSERVICE = 'BenchmarkService'; NAME_AGGR = 'Aggr'; implementation // nix end. thrift-0.23.0/lib/delphi/coding_standards.md0000664000175000017500000000010315165535636021232 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/delphi/DelphiThrift.groupproj0000664000175000017500000001710315165535636021751 0ustar00buildbuild00000000000000 {6BD327A5-7688-4263-B6A8-B15207CF4EC5} Default.Personality.12 thrift-0.23.0/lib/delphi/README.md0000664000175000017500000000177615165535636016702 0ustar00buildbuild00000000000000Thrift Delphi Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Thrift with Delphi ==================== The Thrift Delphi Library requires at least Delphi 2010. Because the Library heavily relies on generics, using it with earlier versions (such as Delphi 7) will *not* work. thrift-0.23.0/lib/xml/0000755000175000017500000000000015170007200014712 5ustar00buildbuild00000000000000thrift-0.23.0/lib/xml/test/0000775000175000017500000000000015170007175015706 5ustar00buildbuild00000000000000thrift-0.23.0/lib/xml/test/build.xml0000664000175000017500000001007215165535636017543 0ustar00buildbuild00000000000000 XML Schema Validation Test Thrift compiler is missing ! thrift-0.23.0/lib/xml/test/Makefile0000644000175000017500000004371215170007175017353 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/xml/test/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/xml/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/xml/test abs_srcdir = /thrift/src/lib/xml/test abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/xml/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/xml/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile 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 ; \ $$ANT $(ANT_FLAGS) clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/xml/test/Makefile.in0000644000175000017500000004262515170007167017763 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/xml/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/xml/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/xml/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile 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 ; \ $$ANT $(ANT_FLAGS) clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/xml/test/Makefile.am0000664000175000017500000000177015165535636017763 0ustar00buildbuild00000000000000# # 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. # 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 ; \ $$ANT $(ANT_FLAGS) clean thrift-0.23.0/lib/xml/thrift-idl.xsd0000664000175000017500000002305415165535636017535 0ustar00buildbuild00000000000000 thrift-0.23.0/lib/xml/Makefile.in0000644000175000017500000005704715170007167017010 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ # Schema validation test depends on java @WITH_JAVA_TRUE@am__append_1 = test subdir = lib/xml ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = test am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = $(am__append_1) EXTRA_DIST = \ thrift-idl.xsd \ test all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/xml/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/xml/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/xml/Makefile.am0000664000175000017500000000170115165535636016776 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = if WITH_JAVA # Schema validation test depends on java SUBDIRS += test endif distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ thrift-idl.xsd \ test thrift-0.23.0/lib/php/0000755000175000017500000000000015170007201014702 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/thrift_protocol.ini0000664000175000017500000000003515165535636020652 0ustar00buildbuild00000000000000extension=thrift_protocol.so thrift-0.23.0/lib/php/src/0000755000175000017500000000000015170007201015471 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/src/ext/0000755000175000017500000000000015170007201016271 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/src/ext/thrift_protocol/0000755000175000017500000000000015170007201021512 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h0000664000175000017500000000543715165535636026014 0ustar00buildbuild00000000000000/* * 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. */ #pragma once /* backward compat macros */ #if PHP_VERSION_ID >= 80000 # define Z4_OBJ_P(zval) (Z_OBJ_P(zval)) #else # define Z4_OBJ_P(zval) (zval) #endif #ifndef IS_MIXED # define IS_MIXED 0 #endif #ifndef ZEND_PARSE_PARAMETERS_NONE #define ZEND_PARSE_PARAMETERS_NONE() \ ZEND_PARSE_PARAMETERS_START(0, 0) \ ZEND_PARSE_PARAMETERS_END() #endif #ifndef ZEND_ARG_INFO_WITH_DEFAULT_VALUE #define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \ ZEND_ARG_INFO(pass_by_ref, name) #endif #if PHP_VERSION_ID < 70200 #undef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX #define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \ static const zend_internal_arg_info name[] = { \ { (const char*)(zend_uintptr_t)(required_num_args), ( #class_name ), 0, return_reference, allow_null, 0 }, #endif #ifndef ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX # define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) #endif #ifndef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX # define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, num_args, type) \ ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, num_args) #endif #ifndef ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX # define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \ ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, required_num_args) #endif #ifndef ZEND_ARG_TYPE_MASK # define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask, default_value) \ ZEND_ARG_TYPE_INFO(pass_by_ref, name, 0, 0) #endif #ifndef ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE # define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \ ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) #endif #include "php_thrift_protocol_arginfo.h" thrift-0.23.0/lib/php/src/ext/thrift_protocol/config.w320000664000175000017500000000041015165535636023337 0ustar00buildbuild00000000000000// $Id: config.w32 250404 2008-01-11 13:37:24Z rrichards $ // vim:ft=javascript ARG_WITH("thrift_protocol", "whether to enable the thrift_protocol extension", "yes"); if (PHP_THRIFT_PROTOCOL == "yes"){ EXTENSION("thrift_protocol", "php_thrift_protocol.cpp") } thrift-0.23.0/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp0000664000175000017500000010455515170007142026326 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "zend_interfaces.h" #include "zend_exceptions.h" #include "php_thrift_protocol.h" #if PHP_VERSION_ID >= 70000 #include #include #include #include #include #ifndef bswap_64 #define bswap_64(x) (((uint64_t)(x) << 56) | \ (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \ (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \ (((uint64_t)(x) << 8) & 0xff00000000ULL) | \ (((uint64_t)(x) >> 8) & 0xff000000ULL) | \ (((uint64_t)(x) >> 24) & 0xff0000ULL) | \ (((uint64_t)(x) >> 40) & 0xff00ULL) | \ ((uint64_t)(x) >> 56)) #endif #if __BYTE_ORDER == __LITTLE_ENDIAN #define htonll(x) bswap_64(x) #define ntohll(x) bswap_64(x) #elif __BYTE_ORDER == __BIG_ENDIAN #define htonll(x) x #define ntohll(x) x #else #error Unknown __BYTE_ORDER #endif enum TType { T_STOP = 0, T_VOID = 1, T_BOOL = 2, T_BYTE = 3, T_I08 = 3, T_I16 = 6, T_I32 = 8, T_U64 = 9, T_I64 = 10, T_DOUBLE = 4, T_STRING = 11, T_UTF7 = 11, T_STRUCT = 12, T_MAP = 13, T_SET = 14, T_LIST = 15, T_UTF8 = 16, T_UTF16 = 17 }; const int32_t VERSION_MASK = 0xffff0000; const int32_t VERSION_1 = 0x80010000; const int8_t T_CALL = 1; const int8_t T_REPLY = 2; const int8_t T_EXCEPTION = 3; // tprotocolexception const int INVALID_DATA = 1; const int BAD_VERSION = 4; zend_module_entry thrift_protocol_module_entry = { STANDARD_MODULE_HEADER, "thrift_protocol", ext_functions, nullptr, nullptr, nullptr, nullptr, nullptr, "1.0", STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_THRIFT_PROTOCOL ZEND_GET_MODULE(thrift_protocol) #endif class PHPExceptionWrapper : public std::exception { public: PHPExceptionWrapper(zval* _ex) throw() { ZVAL_COPY(&ex, _ex); snprintf(_what, 40, "PHP exception zval=%p", _ex); } PHPExceptionWrapper(zend_object* _exobj) throw() { ZVAL_OBJ(&ex, _exobj); snprintf(_what, 40, "PHP exception zval=%p", _exobj); } ~PHPExceptionWrapper() throw() { zval_dtor(&ex); } const char* what() const throw() { return _what; } operator zval*() const throw() { return const_cast(&ex); } // Zend API doesn't do 'const'... protected: zval ex; char _what[40]; } ; class PHPTransport { protected: PHPTransport(zval* _p, size_t _buffer_size) { assert(Z_TYPE_P(_p) == IS_OBJECT); ZVAL_UNDEF(&t); buffer = reinterpret_cast(emalloc(_buffer_size)); buffer_ptr = buffer; buffer_used = 0; buffer_size = _buffer_size; // Get the transport for the passed protocol zval gettransport; ZVAL_STRING(&gettransport, "getTransport"); call_user_function(nullptr, _p, &gettransport, &t, 0, nullptr); zval_dtor(&gettransport); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } assert(Z_TYPE(t) == IS_OBJECT); } ~PHPTransport() { efree(buffer); zval_dtor(&t); } char* buffer; char* buffer_ptr; size_t buffer_used; size_t buffer_size; zval t; }; class PHPOutputTransport : public PHPTransport { public: PHPOutputTransport(zval* _p, size_t _buffer_size = 8192) : PHPTransport(_p, _buffer_size) { } ~PHPOutputTransport() { } void write(const char* data, size_t len) { if ((len + buffer_used) > buffer_size) { internalFlush(); } if (len > buffer_size) { directWrite(data, len); } else { memcpy(buffer_ptr, data, len); buffer_used += len; buffer_ptr += len; } } void writeI64(int64_t i) { i = htonll(i); write((const char*)&i, 8); } void writeU32(uint32_t i) { i = htonl(i); write((const char*)&i, 4); } void writeI32(int32_t i) { i = htonl(i); write((const char*)&i, 4); } void writeI16(int16_t i) { i = htons(i); write((const char*)&i, 2); } void writeI8(int8_t i) { write((const char*)&i, 1); } void writeString(const char* str, size_t len) { writeU32(len); write(str, len); } void flush() { internalFlush(); directFlush(); } protected: void internalFlush() { if (buffer_used) { directWrite(buffer, buffer_used); buffer_ptr = buffer; buffer_used = 0; } } void directFlush() { zval ret, flushfn; ZVAL_NULL(&ret); ZVAL_STRING(&flushfn, "flush"); call_user_function(EG(function_table), &(this->t), &flushfn, &ret, 0, nullptr); zval_dtor(&flushfn); zval_dtor(&ret); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } } void directWrite(const char* data, size_t len) { zval args[1], ret, writefn; ZVAL_STRING(&writefn, "write"); ZVAL_STRINGL(&args[0], data, len); ZVAL_NULL(&ret); call_user_function(EG(function_table), &(this->t), &writefn, &ret, 1, args); zval_dtor(&writefn); zval_dtor(&ret); zval_dtor(&args[0]); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } } }; class PHPInputTransport : public PHPTransport { public: PHPInputTransport(zval* _p, size_t _buffer_size = 8192) : PHPTransport(_p, _buffer_size) { } ~PHPInputTransport() { put_back(); } void put_back() { if (buffer_used) { zval args[1], ret, putbackfn; ZVAL_STRINGL(&args[0], buffer_ptr, buffer_used); ZVAL_STRING(&putbackfn, "putBack"); ZVAL_NULL(&ret); call_user_function(EG(function_table), &(this->t), &putbackfn, &ret, 1, args); zval_dtor(&putbackfn); zval_dtor(&ret); zval_dtor(&args[0]); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } } buffer_used = 0; buffer_ptr = buffer; } void skip(size_t len) { while (len) { size_t chunk_size = (std::min)(len, buffer_used); if (chunk_size) { buffer_ptr = reinterpret_cast(buffer_ptr) + chunk_size; buffer_used -= chunk_size; len -= chunk_size; } if (! len) break; refill(); } } void readBytes(void* buf, size_t len) { while (len) { size_t chunk_size = (std::min)(len, buffer_used); if (chunk_size) { memcpy(buf, buffer_ptr, chunk_size); buffer_ptr = reinterpret_cast(buffer_ptr) + chunk_size; buffer_used -= chunk_size; buf = reinterpret_cast(buf) + chunk_size; len -= chunk_size; } if (! len) break; refill(); } } int8_t readI8() { int8_t c; readBytes(&c, 1); return c; } int16_t readI16() { int16_t c; readBytes(&c, 2); return (int16_t)ntohs(c); } uint32_t readU32() { uint32_t c; readBytes(&c, 4); return (uint32_t)ntohl(c); } int32_t readI32() { int32_t c; readBytes(&c, 4); return (int32_t)ntohl(c); } protected: void refill() { assert(buffer_used == 0); zval retval; zval args[1]; zval funcname; ZVAL_NULL(&retval); ZVAL_LONG(&args[0], buffer_size); ZVAL_STRING(&funcname, "read"); call_user_function(EG(function_table), &(this->t), &funcname, &retval, 1, args); zval_dtor(&args[0]); zval_dtor(&funcname); if (EG(exception)) { zval_dtor(&retval); zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } buffer_used = Z_STRLEN(retval); memcpy(buffer, Z_STRVAL(retval), buffer_used); zval_dtor(&retval); buffer_ptr = buffer; } }; static void binary_deserialize_spec(zval* zthis, PHPInputTransport& transport, HashTable* spec); static void binary_serialize_spec(zval* zthis, PHPOutputTransport& transport, HashTable* spec); static void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval* value, HashTable* fieldspec); static inline bool ttype_is_scalar(int8_t t); // Create a PHP object given a typename and call the ctor, optionally passing up to 2 arguments static void createObject(const char* obj_typename, zval* return_value, int nargs = 0, zval* arg1 = nullptr, zval* arg2 = nullptr) { /* is there a better way to do that on the stack ? */ zend_string *obj_name = zend_string_init(obj_typename, strlen(obj_typename), 0); zend_class_entry* ce = zend_fetch_class(obj_name, ZEND_FETCH_CLASS_DEFAULT); zend_string_release(obj_name); if (! ce) { php_error_docref(nullptr, E_ERROR, "Class %s does not exist", obj_typename); RETURN_NULL(); } object_and_properties_init(return_value, ce, nullptr); zend_function* constructor = zend_std_get_constructor(Z_OBJ_P(return_value)); zval ctor_rv; zend_call_method(Z4_OBJ_P(return_value), ce, &constructor, nullptr, 0, &ctor_rv, nargs, arg1, arg2); zval_dtor(&ctor_rv); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } } static void throw_tprotocolexception(const char* what, long errorcode) { zval zwhat, zerrorcode; ZVAL_STRING(&zwhat, what); ZVAL_LONG(&zerrorcode, errorcode); zval ex; createObject("\\Thrift\\Exception\\TProtocolException", &ex, 2, &zwhat, &zerrorcode); zval_dtor(&zwhat); zval_dtor(&zerrorcode); throw PHPExceptionWrapper(&ex); } // Sets EG(exception), call this and then RETURN_NULL(); static void throw_zend_exception_from_std_exception(const std::exception& ex) { zend_throw_exception(zend_ce_exception, const_cast(ex.what()), 0); } static void skip_element(long thrift_typeID, PHPInputTransport& transport) { switch (thrift_typeID) { case T_STOP: case T_VOID: return; case T_STRUCT: while (true) { int8_t ttype = transport.readI8(); // get field type if (ttype == T_STOP) break; transport.skip(2); // skip field number, I16 skip_element(ttype, transport); // skip field payload } return; case T_BOOL: case T_BYTE: transport.skip(1); return; case T_I16: transport.skip(2); return; case T_I32: transport.skip(4); return; case T_U64: case T_I64: case T_DOUBLE: transport.skip(8); return; //case T_UTF7: // aliases T_STRING case T_UTF8: case T_UTF16: case T_STRING: { uint32_t len = transport.readU32(); transport.skip(len); } return; case T_MAP: { int8_t keytype = transport.readI8(); int8_t valtype = transport.readI8(); uint32_t size = transport.readU32(); for (uint32_t i = 0; i < size; ++i) { skip_element(keytype, transport); skip_element(valtype, transport); } } return; case T_LIST: case T_SET: { int8_t valtype = transport.readI8(); uint32_t size = transport.readU32(); for (uint32_t i = 0; i < size; ++i) { skip_element(valtype, transport); } } return; }; char errbuf[128]; sprintf(errbuf, "Unknown thrift typeID %ld", thrift_typeID); throw_tprotocolexception(errbuf, INVALID_DATA); } static inline bool zval_is_bool(zval* v) { return Z_TYPE_P(v) == IS_TRUE || Z_TYPE_P(v) == IS_FALSE; } static void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval* return_value, HashTable* fieldspec) { ZVAL_NULL(return_value); switch (thrift_typeID) { case T_STOP: case T_VOID: RETURN_NULL(); return; case T_STRUCT: { zval* val_ptr = zend_hash_str_find(fieldspec, "class", sizeof("class")-1); if (val_ptr == nullptr) { throw_tprotocolexception("no class type in spec", INVALID_DATA); skip_element(T_STRUCT, transport); RETURN_NULL(); } char* structType = Z_STRVAL_P(val_ptr); // Create an object in PHP userland based on our spec createObject(structType, return_value); if (Z_TYPE_P(return_value) == IS_NULL) { // unable to create class entry skip_element(T_STRUCT, transport); RETURN_NULL(); } zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false); ZVAL_DEREF(spec); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } if (Z_TYPE_P(spec) != IS_ARRAY) { char errbuf[128]; snprintf(errbuf, 128, "spec for %s is wrong type: %d\n", structType, Z_TYPE_P(spec)); throw_tprotocolexception(errbuf, INVALID_DATA); RETURN_NULL(); } binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); return; } break; case T_BOOL: { uint8_t c; transport.readBytes(&c, 1); RETURN_BOOL(c != 0); } //case T_I08: // same numeric value as T_BYTE case T_BYTE: { uint8_t c; transport.readBytes(&c, 1); RETURN_LONG((int8_t)c); } case T_I16: { uint16_t c; transport.readBytes(&c, 2); RETURN_LONG((int16_t)ntohs(c)); } case T_I32: { uint32_t c; transport.readBytes(&c, 4); RETURN_LONG((int32_t)ntohl(c)); } case T_U64: case T_I64: { uint64_t c; transport.readBytes(&c, 8); RETURN_LONG((int64_t)ntohll(c)); } case T_DOUBLE: { union { uint64_t c; double d; } a; transport.readBytes(&(a.c), 8); a.c = ntohll(a.c); RETURN_DOUBLE(a.d); } //case T_UTF7: // aliases T_STRING case T_UTF8: case T_UTF16: case T_STRING: { uint32_t size = transport.readU32(); if (size) { char strbuf[size+1]; transport.readBytes(strbuf, size); strbuf[size] = '\0'; ZVAL_STRINGL(return_value, strbuf, size); } else { ZVAL_EMPTY_STRING(return_value); } return; } case T_MAP: { // array of key -> value uint8_t types[2]; transport.readBytes(types, 2); uint32_t size = transport.readU32(); array_init(return_value); zval *val_ptr; val_ptr = zend_hash_str_find(fieldspec, "key", sizeof("key")-1); HashTable* keyspec = Z_ARRVAL_P(val_ptr); val_ptr = zend_hash_str_find(fieldspec, "val", sizeof("val")-1); HashTable* valspec = Z_ARRVAL_P(val_ptr); for (uint32_t s = 0; s < size; ++s) { zval key, value; binary_deserialize(types[0], transport, &key, keyspec); binary_deserialize(types[1], transport, &value, valspec); if (Z_TYPE(key) == IS_LONG) { zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value); } else { if (Z_TYPE(key) != IS_STRING) convert_to_string(&key); zend_symtable_update(Z_ARR_P(return_value), Z_STR(key), &value); } zval_dtor(&key); } return; // return_value already populated } case T_LIST: { // array with autogenerated numeric keys int8_t type = transport.readI8(); uint32_t size = transport.readU32(); zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1); HashTable* elemspec = Z_ARRVAL_P(val_ptr); array_init(return_value); for (uint32_t s = 0; s < size; ++s) { zval value; binary_deserialize(type, transport, &value, elemspec); zend_hash_next_index_insert(Z_ARR_P(return_value), &value); } return; } case T_SET: { // array of key -> TRUE uint8_t type; uint32_t size; transport.readBytes(&type, 1); transport.readBytes(&size, 4); size = ntohl(size); zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1); HashTable* elemspec = Z_ARRVAL_P(val_ptr); array_init(return_value); for (uint32_t s = 0; s < size; ++s) { zval key, value; ZVAL_TRUE(&value); binary_deserialize(type, transport, &key, elemspec); if (Z_TYPE(key) == IS_LONG) { zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value); } else { if (Z_TYPE(key) != IS_STRING) convert_to_string(&key); zend_symtable_update(Z_ARR_P(return_value), Z_STR(key), &value); } zval_dtor(&key); } return; } }; char errbuf[128]; sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID); throw_tprotocolexception(errbuf, INVALID_DATA); } static void binary_serialize_hashtable_key(int8_t keytype, PHPOutputTransport& transport, HashTable* ht, HashPosition& ht_pos, HashTable* spec) { bool keytype_is_numeric = (!((keytype == T_STRING) || (keytype == T_UTF8) || (keytype == T_UTF16))); zend_string* key; uint key_len; long index = 0; zval z; int res = zend_hash_get_current_key_ex(ht, &key, (zend_ulong*)&index, &ht_pos); if (res == HASH_KEY_IS_STRING) { ZVAL_STR_COPY(&z, key); } else { ZVAL_LONG(&z, index); } binary_serialize(keytype, transport, &z, spec); zval_dtor(&z); } static void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval* value, HashTable* fieldspec) { if (value) { ZVAL_DEREF(value); } // At this point the typeID (and field num, if applicable) should've already been written to the output so all we need to do is write the payload. switch (thrift_typeID) { case T_STOP: case T_VOID: return; case T_STRUCT: { if (Z_TYPE_P(value) != IS_OBJECT) { throw_tprotocolexception("Attempt to send non-object type as a T_STRUCT", INVALID_DATA); } zval* spec = zend_read_static_property(Z_OBJCE_P(value), "_TSPEC", sizeof("_TSPEC")-1, true); if (spec && Z_TYPE_P(spec) == IS_REFERENCE) { ZVAL_DEREF(spec); } if (!spec || Z_TYPE_P(spec) != IS_ARRAY) { throw_tprotocolexception("Attempt to send non-Thrift object as a T_STRUCT", INVALID_DATA); } binary_serialize_spec(value, transport, Z_ARRVAL_P(spec)); } return; case T_BOOL: if (!zval_is_bool(value)) convert_to_boolean(value); transport.writeI8(Z_TYPE_INFO_P(value) == IS_TRUE ? 1 : 0); return; case T_BYTE: if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value); transport.writeI8(Z_LVAL_P(value)); return; case T_I16: if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value); transport.writeI16(Z_LVAL_P(value)); return; case T_I32: if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value); transport.writeI32(Z_LVAL_P(value)); return; case T_I64: case T_U64: { int64_t l_data; #if defined(_LP64) || defined(_WIN64) if (Z_TYPE_P(value) != IS_LONG) convert_to_long(value); l_data = Z_LVAL_P(value); #else if (Z_TYPE_P(value) != IS_DOUBLE) convert_to_double(value); l_data = (int64_t)Z_DVAL_P(value); #endif transport.writeI64(l_data); } return; case T_DOUBLE: { union { int64_t c; double d; } a; if (Z_TYPE_P(value) != IS_DOUBLE) convert_to_double(value); a.d = Z_DVAL_P(value); transport.writeI64(a.c); } return; case T_UTF8: case T_UTF16: case T_STRING: if (Z_TYPE_P(value) != IS_STRING) convert_to_string(value); transport.writeString(Z_STRVAL_P(value), Z_STRLEN_P(value)); return; case T_MAP: { if (Z_TYPE_P(value) != IS_ARRAY) convert_to_array(value); if (Z_TYPE_P(value) != IS_ARRAY) { throw_tprotocolexception("Attempt to send an incompatible type as an array (T_MAP)", INVALID_DATA); } HashTable* ht = Z_ARRVAL_P(value); zval* val_ptr; val_ptr = zend_hash_str_find(fieldspec, "ktype", sizeof("ktype")-1); if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr); uint8_t keytype = Z_LVAL_P(val_ptr); transport.writeI8(keytype); val_ptr = zend_hash_str_find(fieldspec, "vtype", sizeof("vtype")-1); if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr); uint8_t valtype = Z_LVAL_P(val_ptr); transport.writeI8(valtype); val_ptr = zend_hash_str_find(fieldspec, "val", sizeof("val")-1); HashTable* valspec = Z_ARRVAL_P(val_ptr); HashTable* keyspec = Z_ARRVAL_P(zend_hash_str_find(fieldspec, "key", sizeof("key")-1)); transport.writeI32(zend_hash_num_elements(ht)); HashPosition key_ptr; for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); (val_ptr = zend_hash_get_current_data_ex(ht, &key_ptr)) != nullptr; zend_hash_move_forward_ex(ht, &key_ptr)) { binary_serialize_hashtable_key(keytype, transport, ht, key_ptr, keyspec); binary_serialize(valtype, transport, val_ptr, valspec); } } return; case T_LIST: { if (Z_TYPE_P(value) != IS_ARRAY) convert_to_array(value); if (Z_TYPE_P(value) != IS_ARRAY) { throw_tprotocolexception("Attempt to send an incompatible type as an array (T_LIST)", INVALID_DATA); } HashTable* ht = Z_ARRVAL_P(value); zval* val_ptr; val_ptr = zend_hash_str_find(fieldspec, "etype", sizeof("etype")-1); if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr); uint8_t valtype = Z_LVAL_P(val_ptr); transport.writeI8(valtype); val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1); HashTable* valspec = Z_ARRVAL_P(val_ptr); transport.writeI32(zend_hash_num_elements(ht)); HashPosition key_ptr; for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); (val_ptr = zend_hash_get_current_data_ex(ht, &key_ptr)) != nullptr; zend_hash_move_forward_ex(ht, &key_ptr)) { binary_serialize(valtype, transport, val_ptr, valspec); } } return; case T_SET: { if (Z_TYPE_P(value) != IS_ARRAY) convert_to_array(value); if (Z_TYPE_P(value) != IS_ARRAY) { throw_tprotocolexception("Attempt to send an incompatible type as an array (T_SET)", INVALID_DATA); } HashTable* ht = Z_ARRVAL_P(value); zval* val_ptr; val_ptr = zend_hash_str_find(fieldspec, "etype", sizeof("etype")-1); HashTable* spec = Z_ARRVAL_P(zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1)); if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr); uint8_t keytype = Z_LVAL_P(val_ptr); transport.writeI8(keytype); transport.writeI32(zend_hash_num_elements(ht)); HashPosition key_ptr; if(ttype_is_scalar(keytype)){ for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); (val_ptr = zend_hash_get_current_data_ex(ht, &key_ptr)) != nullptr; zend_hash_move_forward_ex(ht, &key_ptr)) { binary_serialize_hashtable_key(keytype, transport, ht, key_ptr, spec); } } else { for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); (val_ptr = zend_hash_get_current_data_ex(ht, &key_ptr)) != nullptr; zend_hash_move_forward_ex(ht, &key_ptr)) { binary_serialize(keytype, transport, val_ptr, spec); } } } return; }; char errbuf[128]; snprintf(errbuf, 128, "Unknown thrift typeID %d", thrift_typeID); throw_tprotocolexception(errbuf, INVALID_DATA); } static void protocol_writeMessageBegin(zval* transport, zend_string* method_name, int32_t msgtype, int32_t seqID) { zval args[3]; zval ret; zval writeMessagefn; ZVAL_STR_COPY(&args[0], method_name); ZVAL_LONG(&args[1], msgtype); ZVAL_LONG(&args[2], seqID); ZVAL_NULL(&ret); ZVAL_STRING(&writeMessagefn, "writeMessageBegin"); call_user_function(EG(function_table), transport, &writeMessagefn, &ret, 3, args); zval_dtor(&writeMessagefn); zval_dtor(&args[2]); zval_dtor(&args[1]); zval_dtor(&args[0]); zval_dtor(&ret); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } } static inline bool ttype_is_int(int8_t t) { return ((t == T_BYTE) || ((t >= T_I16) && (t <= T_I64))); } static inline bool ttype_is_scalar(int8_t t) { return !((t == T_STRUCT) || ( t== T_MAP) || (t == T_SET) || (t == T_LIST)); } static inline bool ttypes_are_compatible(int8_t t1, int8_t t2) { // Integer types of different widths are considered compatible; // otherwise the typeID must match. return ((t1 == t2) || (ttype_is_int(t1) && ttype_is_int(t2))); } //is used to validate objects before serialization and after deserialization. For now, only required fields are validated. static void validate_thrift_object(zval* object) { zend_class_entry* object_class_entry = Z_OBJCE_P(object); zval* is_validate = zend_read_static_property(object_class_entry, "isValidate", sizeof("isValidate")-1, true); if (is_validate) { ZVAL_DEREF(is_validate); } zval* spec = zend_read_static_property(object_class_entry, "_TSPEC", sizeof("_TSPEC")-1, true); if (spec) { ZVAL_DEREF(spec); } HashPosition key_ptr; zval* val_ptr; if (is_validate && Z_TYPE_INFO_P(is_validate) == IS_TRUE) { for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(spec), &key_ptr); (val_ptr = zend_hash_get_current_data_ex(Z_ARRVAL_P(spec), &key_ptr)) != nullptr; zend_hash_move_forward_ex(Z_ARRVAL_P(spec), &key_ptr)) { zend_ulong fieldno; if (zend_hash_get_current_key_ex(Z_ARRVAL_P(spec), nullptr, &fieldno, &key_ptr) != HASH_KEY_IS_LONG) { throw_tprotocolexception("Bad keytype in TSPEC (expected 'long')", INVALID_DATA); return; } HashTable* fieldspec = Z_ARRVAL_P(val_ptr); // field name zval* zvarname = zend_hash_str_find(fieldspec, "var", sizeof("var")-1); char* varname = Z_STRVAL_P(zvarname); zval* is_required = zend_hash_str_find(fieldspec, "isRequired", sizeof("isRequired")-1); zval rv; zval* prop = zend_read_property(object_class_entry, Z4_OBJ_P(object), varname, strlen(varname), false, &rv); if (Z_TYPE_INFO_P(is_required) == IS_TRUE && Z_TYPE_P(prop) == IS_NULL) { char errbuf[128]; snprintf(errbuf, 128, "Required field %s.%s is unset!", ZSTR_VAL(object_class_entry->name), varname); throw_tprotocolexception(errbuf, INVALID_DATA); } } } } static void binary_deserialize_spec(zval* zthis, PHPInputTransport& transport, HashTable* spec) { // SET and LIST have 'elem' => array('type', [optional] 'class') // MAP has 'val' => array('type', [optiona] 'class') zend_class_entry* ce = Z_OBJCE_P(zthis); while (true) { int8_t ttype = transport.readI8(); if (ttype == T_STOP) { validate_thrift_object(zthis); return; } int16_t fieldno = transport.readI16(); zval* val_ptr = zend_hash_index_find(spec, fieldno); if (val_ptr != nullptr) { HashTable* fieldspec = Z_ARRVAL_P(val_ptr); // pull the field name val_ptr = zend_hash_str_find(fieldspec, "var", sizeof("var")-1); char* varname = Z_STRVAL_P(val_ptr); // and the type val_ptr = zend_hash_str_find(fieldspec, "type", sizeof("type")-1); if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr); int8_t expected_ttype = Z_LVAL_P(val_ptr); if (ttypes_are_compatible(ttype, expected_ttype)) { zval rv; ZVAL_UNDEF(&rv); binary_deserialize(ttype, transport, &rv, fieldspec); zend_update_property(ce, Z4_OBJ_P(zthis), varname, strlen(varname), &rv); zval_ptr_dtor(&rv); } else { skip_element(ttype, transport); } } else { skip_element(ttype, transport); } } } static void binary_serialize_spec(zval* zthis, PHPOutputTransport& transport, HashTable* spec) { validate_thrift_object(zthis); HashPosition key_ptr; zval* val_ptr; for (zend_hash_internal_pointer_reset_ex(spec, &key_ptr); (val_ptr = zend_hash_get_current_data_ex(spec, &key_ptr)) != nullptr; zend_hash_move_forward_ex(spec, &key_ptr)) { zend_ulong fieldno; if (zend_hash_get_current_key_ex(spec, nullptr, &fieldno, &key_ptr) != HASH_KEY_IS_LONG) { throw_tprotocolexception("Bad keytype in TSPEC (expected 'long')", INVALID_DATA); return; } HashTable* fieldspec = Z_ARRVAL_P(val_ptr); // field name val_ptr = zend_hash_str_find(fieldspec, "var", sizeof("var")-1); char* varname = Z_STRVAL_P(val_ptr); // thrift type val_ptr = zend_hash_str_find(fieldspec, "type", sizeof("type")-1); if (Z_TYPE_P(val_ptr) != IS_LONG) convert_to_long(val_ptr); int8_t ttype = Z_LVAL_P(val_ptr); zval rv; zval* prop = zend_read_property(Z_OBJCE_P(zthis), Z4_OBJ_P(zthis), varname, strlen(varname), false, &rv); if (Z_TYPE_P(prop) == IS_REFERENCE){ ZVAL_DEREF(prop); } if (Z_TYPE_P(prop) != IS_NULL) { transport.writeI8(ttype); transport.writeI16(fieldno); binary_serialize(ttype, transport, prop, fieldspec); } } transport.writeI8(T_STOP); // struct end } // 6 params: $transport $method_name $ttype $request_struct $seqID $strict_write PHP_FUNCTION(thrift_protocol_write_binary) { zval *protocol; zval *request_struct; zend_string *method_name; long msgtype, seqID; zend_bool strict_write; if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "oSlolb", &protocol, &method_name, &msgtype, &request_struct, &seqID, &strict_write) == FAILURE) { return; } try { zval* spec = zend_read_static_property(Z_OBJCE_P(request_struct), "_TSPEC", sizeof("_TSPEC")-1, true); if (spec) { ZVAL_DEREF(spec); } if (!spec || Z_TYPE_P(spec) != IS_ARRAY) { throw_tprotocolexception("Attempt serialize from non-Thrift object", INVALID_DATA); } PHPOutputTransport transport(protocol); protocol_writeMessageBegin(protocol, method_name, (int32_t) msgtype, (int32_t) seqID); binary_serialize_spec(request_struct, transport, Z_ARRVAL_P(spec)); transport.flush(); } catch (const PHPExceptionWrapper& ex) { // ex will be destructed, so copy to a zval that zend_throw_exception_object can take ownership of zval myex; ZVAL_COPY(&myex, ex); zend_throw_exception_object(&myex); RETURN_NULL(); } catch (const std::exception& ex) { throw_zend_exception_from_std_exception(ex); RETURN_NULL(); } } // 4 params: $transport $response_Typename $strict_read $buffer_size PHP_FUNCTION(thrift_protocol_read_binary) { zval *protocol; zend_string *obj_typename; zend_bool strict_read; size_t buffer_size = 8192; if (zend_parse_parameters(ZEND_NUM_ARGS(), "oSb|l", &protocol, &obj_typename, &strict_read, &buffer_size) == FAILURE) { return; } try { PHPInputTransport transport(protocol, buffer_size); int8_t messageType = 0; int32_t sz = transport.readI32(); if (sz < 0) { // Check for correct version number int32_t version = sz & VERSION_MASK; if (version != VERSION_1) { throw_tprotocolexception("Bad version identifier", BAD_VERSION); } messageType = (sz & 0x000000ff); int32_t namelen = transport.readI32(); // skip the name string and the sequence ID, we don't care about those transport.skip(namelen + 4); } else { if (strict_read) { throw_tprotocolexception("No version identifier... old protocol client in strict mode?", BAD_VERSION); } else { // Handle pre-versioned input transport.skip(sz); // skip string body messageType = transport.readI8(); transport.skip(4); // skip sequence number } } if (messageType == T_EXCEPTION) { zval ex; createObject("\\Thrift\\Exception\\TApplicationException", &ex); zval* spec = zend_read_static_property(Z_OBJCE(ex), "_TSPEC", sizeof("_TPSEC")-1, false); ZVAL_DEREF(spec); if (EG(exception)) { zend_object *ex = EG(exception); EG(exception) = nullptr; throw PHPExceptionWrapper(ex); } binary_deserialize_spec(&ex, transport, Z_ARRVAL_P(spec)); throw PHPExceptionWrapper(&ex); } createObject(ZSTR_VAL(obj_typename), return_value); zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, true); if (spec) { ZVAL_DEREF(spec); } if (!spec || Z_TYPE_P(spec) != IS_ARRAY) { throw_tprotocolexception("Attempt deserialize to non-Thrift object", INVALID_DATA); } binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); } catch (const PHPExceptionWrapper& ex) { // ex will be destructed, so copy to a zval that zend_throw_exception_object can ownership of zval myex; ZVAL_COPY(&myex, ex); zval_dtor(return_value); zend_throw_exception_object(&myex); RETURN_NULL(); } catch (const std::exception& ex) { throw_zend_exception_from_std_exception(ex); RETURN_NULL(); } } // 4 params: $transport $response_Typename $strict_read $buffer_size PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin) { zval *protocol; zend_string *obj_typename; zend_bool strict_read; size_t buffer_size = 8192; if (zend_parse_parameters(ZEND_NUM_ARGS(), "oSb|l", &protocol, &obj_typename, &strict_read, &buffer_size) == FAILURE) { return; } try { PHPInputTransport transport(protocol, buffer_size); createObject(ZSTR_VAL(obj_typename), return_value); zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false); ZVAL_DEREF(spec); binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); } catch (const PHPExceptionWrapper& ex) { // ex will be destructed, so copy to a zval that zend_throw_exception_object can take ownership of zval myex; ZVAL_COPY(&myex, ex); zend_throw_exception_object(&myex); RETURN_NULL(); } catch (const std::exception& ex) { throw_zend_exception_from_std_exception(ex); RETURN_NULL(); } } #endif /* PHP_VERSION_ID >= 70000 */ thrift-0.23.0/lib/php/src/ext/thrift_protocol/config.m40000664000175000017500000000270515165535636023255 0ustar00buildbuild00000000000000dnl Copyright (C) 2009 Facebook dnl Copying and distribution of this file, with or without modification, dnl are permitted in any medium without royalty provided the copyright dnl notice and this notice are preserved. dnl dnl Licensed to the Apache Software Foundation (ASF) under one dnl or more contributor license agreements. See the NOTICE file dnl distributed with this work for additional information dnl regarding copyright ownership. The ASF licenses this file dnl to you under the Apache License, Version 2.0 (the dnl "License"); you may not use this file except in compliance dnl with the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, dnl software distributed under the License is distributed on an dnl "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY dnl KIND, either express or implied. See the License for the dnl specific language governing permissions and limitations dnl under the License. PHP_ARG_ENABLE(thrift_protocol, whether to enable the thrift_protocol extension, [ --enable-thrift_protocol Enable the thrift_protocol extension]) if test "$PHP_THRIFT_PROTOCOL" != "no"; then PHP_REQUIRE_CXX() PHP_ADD_LIBRARY_WITH_PATH(stdc++, "", THRIFT_PROTOCOL_SHARED_LIBADD) PHP_SUBST(THRIFT_PROTOCOL_SHARED_LIBADD) CXXFLAGS="$CXXFLAGS -std=c++11" PHP_NEW_EXTENSION(thrift_protocol, php_thrift_protocol.cpp, $ext_shared) fi thrift-0.23.0/lib/php/src/ext/thrift_protocol/php_thrift_protocol_arginfo.h0000664000175000017500000000266115165535636027515 0ustar00buildbuild00000000000000/* This is a generated file, edit the .stub.php file instead. * Stub hash: 3bd6e0bc99143d614ddb80ee0aec192e385c8927 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_thrift_protocol_write_binary, 0, 6, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, protocol, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, method_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, msgtype, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, request_struct, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, seqID, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, strict_write, _IS_BOOL, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_thrift_protocol_read_binary, 0, 3, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, protocol, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, obj_typename, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, strict_read, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, buffer_size, IS_LONG, 0, "8192") ZEND_END_ARG_INFO() #define arginfo_thrift_protocol_read_binary_after_message_begin arginfo_thrift_protocol_read_binary ZEND_FUNCTION(thrift_protocol_write_binary); ZEND_FUNCTION(thrift_protocol_read_binary); ZEND_FUNCTION(thrift_protocol_read_binary_after_message_begin); static const zend_function_entry ext_functions[] = { ZEND_FE(thrift_protocol_write_binary, arginfo_thrift_protocol_write_binary) ZEND_FE(thrift_protocol_read_binary, arginfo_thrift_protocol_read_binary) ZEND_FE(thrift_protocol_read_binary_after_message_begin, arginfo_thrift_protocol_read_binary_after_message_begin) ZEND_FE_END }; thrift-0.23.0/lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php0000664000175000017500000000111015165535636027310 0ustar00buildbuild00000000000000strlen($str) - $start; } return mb_substr((string) $str, $start, $length, '8bit'); } public function strlen($str) { return mb_strlen((string) $str, '8bit'); } } class TStringFuncFactory { private static $_instance; /** * Get the Singleton instance of TStringFunc implementation that is * compatible with the current system's mbstring.func_overload settings. * * @return TStringFunc */ public static function create() { if (!self::$_instance) { self::_setInstance(); } return self::$_instance; } private static function _setInstance() { /** * Cannot use str* functions for byte counting because multibyte * characters will be read a single bytes. * * See: http://us.php.net/manual/en/mbstring.overload.php */ if (ini_get('mbstring.func_overload') & 2) { self::$_instance = new TStringFunc_Mbstring(); } /** * mbstring is not installed or does not have function overloading * of the str* functions enabled so use PHP core str* functions for * byte counting. */ else { self::$_instance = new TStringFunc_Core(); } } } thrift-0.23.0/lib/php/src/autoload.php0000664000175000017500000000357215165535636020051 0ustar00buildbuild00000000000000 $fspec) { $var = $fspec['var']; if (isset($vals[$var])) { $this->$var = $vals[$var]; } } } else { parent::__construct((string)$p1, $p2); } } static $tmethod = array(TType::BOOL => 'Bool', TType::BYTE => 'Byte', TType::I16 => 'I16', TType::I32 => 'I32', TType::I64 => 'I64', TType::DOUBLE => 'Double', TType::STRING => 'String'); private function _readMap(&$var, $spec, $input) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kread = $vread = null; if (isset(TBase::$tmethod[$ktype])) { $kread = 'read'.TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vread = 'read'.TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $var = array(); $_ktype = $_vtype = $size = 0; $xfer += $input->readMapBegin($_ktype, $_vtype, $size); for ($i = 0; $i < $size; ++$i) { $key = $val = null; if ($kread !== null) { $xfer += $input->$kread($key); } else { switch ($ktype) { case TType::STRUCT: $class = $kspec['class']; $key = new $class(); $xfer += $key->read($input); break; case TType::MAP: $xfer += $this->_readMap($key, $kspec, $input); break; case TType::LST: $xfer += $this->_readList($key, $kspec, $input, false); break; case TType::SET: $xfer += $this->_readList($key, $kspec, $input, true); break; } } if ($vread !== null) { $xfer += $input->$vread($val); } else { switch ($vtype) { case TType::STRUCT: $class = $vspec['class']; $val = new $class(); $xfer += $val->read($input); break; case TType::MAP: $xfer += $this->_readMap($val, $vspec, $input); break; case TType::LST: $xfer += $this->_readList($val, $vspec, $input, false); break; case TType::SET: $xfer += $this->_readList($val, $vspec, $input, true); break; } } $var[$key] = $val; } $xfer += $input->readMapEnd(); return $xfer; } private function _readList(&$var, $spec, $input, $set=false) { $xfer = 0; $etype = $spec['etype']; $eread = $vread = null; if (isset(TBase::$tmethod[$etype])) { $eread = 'read'.TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } $var = array(); $_etype = $size = 0; if ($set) { $xfer += $input->readSetBegin($_etype, $size); } else { $xfer += $input->readListBegin($_etype, $size); } for ($i = 0; $i < $size; ++$i) { $elem = null; if ($eread !== null) { $xfer += $input->$eread($elem); } else { $espec = $spec['elem']; switch ($etype) { case TType::STRUCT: $class = $espec['class']; $elem = new $class(); $xfer += $elem->read($input); break; case TType::MAP: $xfer += $this->_readMap($elem, $espec, $input); break; case TType::LST: $xfer += $this->_readList($elem, $espec, $input, false); break; case TType::SET: $xfer += $this->_readList($elem, $espec, $input, true); break; } } if ($set) { $var[$elem] = true; } else { $var []= $elem; } } if ($set) { $xfer += $input->readSetEnd(); } else { $xfer += $input->readListEnd(); } return $xfer; } protected function _read($class, $spec, $input) { $xfer = 0; $fname = null; $ftype = 0; $fid = 0; $xfer += $input->readStructBegin($fname); while (true) { $xfer += $input->readFieldBegin($fname, $ftype, $fid); if ($ftype == TType::STOP) { break; } if (isset($spec[$fid])) { $fspec = $spec[$fid]; $var = $fspec['var']; if ($ftype == $fspec['type']) { $xfer = 0; if (isset(TBase::$tmethod[$ftype])) { $func = 'read'.TBase::$tmethod[$ftype]; $xfer += $input->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $class = $fspec['class']; $this->$var = new $class(); $xfer += $this->$var->read($input); break; case TType::MAP: $xfer += $this->_readMap($this->$var, $fspec, $input); break; case TType::LST: $xfer += $this->_readList($this->$var, $fspec, $input, false); break; case TType::SET: $xfer += $this->_readList($this->$var, $fspec, $input, true); break; } } } else { $xfer += $input->skip($ftype); } } else { $xfer += $input->skip($ftype); } $xfer += $input->readFieldEnd(); } $xfer += $input->readStructEnd(); return $xfer; } private function _writeMap($var, $spec, $output) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kwrite = $vwrite = null; if (isset(TBase::$tmethod[$ktype])) { $kwrite = 'write'.TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vwrite = 'write'.TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $xfer += $output->writeMapBegin($ktype, $vtype, count($var)); foreach ($var as $key => $val) { if (isset($kwrite)) { $xfer += $output->$kwrite($key); } else { switch ($ktype) { case TType::STRUCT: $xfer += $key->write($output); break; case TType::MAP: $xfer += $this->_writeMap($key, $kspec, $output); break; case TType::LST: $xfer += $this->_writeList($key, $kspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($key, $kspec, $output, true); break; } } if (isset($vwrite)) { $xfer += $output->$vwrite($val); } else { switch ($vtype) { case TType::STRUCT: $xfer += $val->write($output); break; case TType::MAP: $xfer += $this->_writeMap($val, $vspec, $output); break; case TType::LST: $xfer += $this->_writeList($val, $vspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($val, $vspec, $output, true); break; } } } $xfer += $output->writeMapEnd(); return $xfer; } private function _writeList($var, $spec, $output, $set=false) { $xfer = 0; $etype = $spec['etype']; $ewrite = null; if (isset(TBase::$tmethod[$etype])) { $ewrite = 'write'.TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } if ($set) { $xfer += $output->writeSetBegin($etype, count($var)); } else { $xfer += $output->writeListBegin($etype, count($var)); } foreach ($var as $key => $val) { $elem = $set ? $key : $val; if (isset($ewrite)) { $xfer += $output->$ewrite($elem); } else { switch ($etype) { case TType::STRUCT: $xfer += $elem->write($output); break; case TType::MAP: $xfer += $this->_writeMap($elem, $espec, $output); break; case TType::LST: $xfer += $this->_writeList($elem, $espec, $output, false); break; case TType::SET: $xfer += $this->_writeList($elem, $espec, $output, true); break; } } } if ($set) { $xfer += $output->writeSetEnd(); } else { $xfer += $output->writeListEnd(); } return $xfer; } protected function _write($class, $spec, $output) { $xfer = 0; $xfer += $output->writeStructBegin($class); foreach ($spec as $fid => $fspec) { $var = $fspec['var']; if ($this->$var !== null) { $ftype = $fspec['type']; $xfer += $output->writeFieldBegin($var, $ftype, $fid); if (isset(TBase::$tmethod[$ftype])) { $func = 'write'.TBase::$tmethod[$ftype]; $xfer += $output->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $xfer += $this->$var->write($output); break; case TType::MAP: $xfer += $this->_writeMap($this->$var, $fspec, $output); break; case TType::LST: $xfer += $this->_writeList($this->$var, $fspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($this->$var, $fspec, $output, true); break; } } $xfer += $output->writeFieldEnd(); } } $xfer += $output->writeFieldStop(); $xfer += $output->writeStructEnd(); return $xfer; } } /** * Base class from which other Thrift structs extend. This is so that we can * cut back on the size of the generated code which is turning out to have a * nontrivial cost just to load thanks to the wondrously abysmal implementation * 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', TType::BYTE => 'Byte', TType::I16 => 'I16', TType::I32 => 'I32', TType::I64 => 'I64', TType::DOUBLE => 'Double', TType::STRING => 'String'); abstract public function read($input); abstract public function write($output); public function __construct($spec=null, $vals=null) { if (is_array($spec) && is_array($vals)) { foreach ($spec as $fid => $fspec) { $var = $fspec['var']; if (isset($vals[$var])) { $this->$var = $vals[$var]; } } } } private function _readMap(&$var, $spec, $input) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kread = $vread = null; if (isset(TBase::$tmethod[$ktype])) { $kread = 'read'.TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vread = 'read'.TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $var = array(); $_ktype = $_vtype = $size = 0; $xfer += $input->readMapBegin($_ktype, $_vtype, $size); for ($i = 0; $i < $size; ++$i) { $key = $val = null; if ($kread !== null) { $xfer += $input->$kread($key); } else { switch ($ktype) { case TType::STRUCT: $class = $kspec['class']; $key = new $class(); $xfer += $key->read($input); break; case TType::MAP: $xfer += $this->_readMap($key, $kspec, $input); break; case TType::LST: $xfer += $this->_readList($key, $kspec, $input, false); break; case TType::SET: $xfer += $this->_readList($key, $kspec, $input, true); break; } } if ($vread !== null) { $xfer += $input->$vread($val); } else { switch ($vtype) { case TType::STRUCT: $class = $vspec['class']; $val = new $class(); $xfer += $val->read($input); break; case TType::MAP: $xfer += $this->_readMap($val, $vspec, $input); break; case TType::LST: $xfer += $this->_readList($val, $vspec, $input, false); break; case TType::SET: $xfer += $this->_readList($val, $vspec, $input, true); break; } } $var[$key] = $val; } $xfer += $input->readMapEnd(); return $xfer; } private function _readList(&$var, $spec, $input, $set=false) { $xfer = 0; $etype = $spec['etype']; $eread = $vread = null; if (isset(TBase::$tmethod[$etype])) { $eread = 'read'.TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } $var = array(); $_etype = $size = 0; if ($set) { $xfer += $input->readSetBegin($_etype, $size); } else { $xfer += $input->readListBegin($_etype, $size); } for ($i = 0; $i < $size; ++$i) { $elem = null; if ($eread !== null) { $xfer += $input->$eread($elem); } else { $espec = $spec['elem']; switch ($etype) { case TType::STRUCT: $class = $espec['class']; $elem = new $class(); $xfer += $elem->read($input); break; case TType::MAP: $xfer += $this->_readMap($elem, $espec, $input); break; case TType::LST: $xfer += $this->_readList($elem, $espec, $input, false); break; case TType::SET: $xfer += $this->_readList($elem, $espec, $input, true); break; } } if ($set) { $var[$elem] = true; } else { $var []= $elem; } } if ($set) { $xfer += $input->readSetEnd(); } else { $xfer += $input->readListEnd(); } return $xfer; } protected function _read($class, $spec, $input) { $xfer = 0; $fname = null; $ftype = 0; $fid = 0; $xfer += $input->readStructBegin($fname); while (true) { $xfer += $input->readFieldBegin($fname, $ftype, $fid); if ($ftype == TType::STOP) { break; } if (isset($spec[$fid])) { $fspec = $spec[$fid]; $var = $fspec['var']; if ($ftype == $fspec['type']) { $xfer = 0; if (isset(TBase::$tmethod[$ftype])) { $func = 'read'.TBase::$tmethod[$ftype]; $xfer += $input->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $class = $fspec['class']; $this->$var = new $class(); $xfer += $this->$var->read($input); break; case TType::MAP: $xfer += $this->_readMap($this->$var, $fspec, $input); break; case TType::LST: $xfer += $this->_readList($this->$var, $fspec, $input, false); break; case TType::SET: $xfer += $this->_readList($this->$var, $fspec, $input, true); break; } } } else { $xfer += $input->skip($ftype); } } else { $xfer += $input->skip($ftype); } $xfer += $input->readFieldEnd(); } $xfer += $input->readStructEnd(); return $xfer; } private function _writeMap($var, $spec, $output) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kwrite = $vwrite = null; if (isset(TBase::$tmethod[$ktype])) { $kwrite = 'write'.TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vwrite = 'write'.TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $xfer += $output->writeMapBegin($ktype, $vtype, count($var)); foreach ($var as $key => $val) { if (isset($kwrite)) { $xfer += $output->$kwrite($key); } else { switch ($ktype) { case TType::STRUCT: $xfer += $key->write($output); break; case TType::MAP: $xfer += $this->_writeMap($key, $kspec, $output); break; case TType::LST: $xfer += $this->_writeList($key, $kspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($key, $kspec, $output, true); break; } } if (isset($vwrite)) { $xfer += $output->$vwrite($val); } else { switch ($vtype) { case TType::STRUCT: $xfer += $val->write($output); break; case TType::MAP: $xfer += $this->_writeMap($val, $vspec, $output); break; case TType::LST: $xfer += $this->_writeList($val, $vspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($val, $vspec, $output, true); break; } } } $xfer += $output->writeMapEnd(); return $xfer; } private function _writeList($var, $spec, $output, $set=false) { $xfer = 0; $etype = $spec['etype']; $ewrite = null; if (isset(TBase::$tmethod[$etype])) { $ewrite = 'write'.TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } if ($set) { $xfer += $output->writeSetBegin($etype, count($var)); } else { $xfer += $output->writeListBegin($etype, count($var)); } foreach ($var as $key => $val) { $elem = $set ? $key : $val; if (isset($ewrite)) { $xfer += $output->$ewrite($elem); } else { switch ($etype) { case TType::STRUCT: $xfer += $elem->write($output); break; case TType::MAP: $xfer += $this->_writeMap($elem, $espec, $output); break; case TType::LST: $xfer += $this->_writeList($elem, $espec, $output, false); break; case TType::SET: $xfer += $this->_writeList($elem, $espec, $output, true); break; } } } if ($set) { $xfer += $output->writeSetEnd(); } else { $xfer += $output->writeListEnd(); } return $xfer; } protected function _write($class, $spec, $output) { $xfer = 0; $xfer += $output->writeStructBegin($class); foreach ($spec as $fid => $fspec) { $var = $fspec['var']; if ($this->$var !== null) { $ftype = $fspec['type']; $xfer += $output->writeFieldBegin($var, $ftype, $fid); if (isset(TBase::$tmethod[$ftype])) { $func = 'write'.TBase::$tmethod[$ftype]; $xfer += $output->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $xfer += $this->$var->write($output); break; case TType::MAP: $xfer += $this->_writeMap($this->$var, $fspec, $output); break; case TType::LST: $xfer += $this->_writeList($this->$var, $fspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($this->$var, $fspec, $output, true); break; } } $xfer += $output->writeFieldEnd(); } } $xfer += $output->writeFieldStop(); $xfer += $output->writeStructEnd(); return $xfer; } } class TApplicationException extends TException { static $_TSPEC = array(1 => array('var' => 'message', 'type' => TType::STRING), 2 => array('var' => 'code', 'type' => TType::I32)); const UNKNOWN = 0; const UNKNOWN_METHOD = 1; const INVALID_MESSAGE_TYPE = 2; const WRONG_METHOD_NAME = 3; const BAD_SEQUENCE_ID = 4; const MISSING_RESULT = 5; const INTERNAL_ERROR = 6; const PROTOCOL_ERROR = 7; public function __construct($message=null, $code=0) { parent::__construct($message, $code); } public function read($output) { return $this->_read('TApplicationException', self::$_TSPEC, $output); } public function write($output) { $xfer = 0; $xfer += $output->writeStructBegin('TApplicationException'); if ($message = $this->getMessage()) { $xfer += $output->writeFieldBegin('message', TType::STRING, 1); $xfer += $output->writeString($message); $xfer += $output->writeFieldEnd(); } if ($code = $this->getCode()) { $xfer += $output->writeFieldBegin('type', TType::I32, 2); $xfer += $output->writeI32($code); $xfer += $output->writeFieldEnd(); } $xfer += $output->writeFieldStop(); $xfer += $output->writeStructEnd(); return $xfer; } } /** * Set global THRIFT ROOT automatically via inclusion here */ if (!isset($GLOBALS['THRIFT_ROOT'])) { $GLOBALS['THRIFT_ROOT'] = dirname(__FILE__); } include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TProtocol.php'; include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php'; include_once $GLOBALS['THRIFT_ROOT'].'/TStringUtils.php'; thrift-0.23.0/lib/php/test/0000775000175000017500000000000015170007175015675 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/0000775000175000017500000000000015165535636016630 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/0000775000175000017500000000000015167543515017333 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Exception/0000775000175000017500000000000015165535636021274 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Exception/TExceptionTest.php0000664000175000017500000000351415165535636024732 0ustar00buildbuild00000000000000assertInstanceOf(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); } } thrift-0.23.0/lib/php/test/Unit/Lib/Factory/0000775000175000017500000000000015167543515020742 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Factory/TBinaryProtocolFactoryTest.php0000664000175000017500000000454615167543515026746 0ustar00buildbuild00000000000000createMock(TTransport::class); $factory = new TBinaryProtocolFactory($strictRead, $strictWrite); $protocol = $factory->getProtocol($transport); $this->assertInstanceOf(TBinaryProtocol::class, $protocol); $this->assertEquals($strictRead, $this->getPropertyValue($protocol, 'strictRead_')); $this->assertEquals($strictWrite, $this->getPropertyValue($protocol, 'strictWrite_')); $this->assertSame($transport, $this->getPropertyValue($protocol, 'trans_')); } 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, ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Factory/TJSONProtocolFactoryTest.php0000664000175000017500000000275515167543515026273 0ustar00buildbuild00000000000000createMock(TTransport::class); $factory = new TJSONProtocolFactory(); $protocol = $factory->getProtocol($transport); $this->assertInstanceOf(TJSONProtocol::class, $protocol); $this->assertSame($transport, $this->getPropertyValue($protocol, 'trans_')); } } thrift-0.23.0/lib/php/test/Unit/Lib/Factory/TStringFuncFactoryTest.php0000664000175000017500000000433315167543515026054 0ustar00buildbuild00000000000000getFunctionMock('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 */ $this->setPropertyValue($factory, '_instance', 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 ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Factory/TCompactProtocolFactoryTest.php0000664000175000017500000000277415167543515027111 0ustar00buildbuild00000000000000createMock(TTransport::class); $factory = new TCompactProtocolFactory(); $protocol = $factory->getProtocol($transport); $this->assertInstanceOf(TCompactProtocol::class, $protocol); $this->assertSame($transport, $this->getPropertyValue($protocol, 'trans_')); } } thrift-0.23.0/lib/php/test/Unit/Lib/Factory/TTransportFactoryTest.php0000664000175000017500000000242315165535636025767 0ustar00buildbuild00000000000000createMock(TTransport::class); $factory = new TTransportFactory(); $result = $factory->getTransport($transport); $this->assertSame($transport, $result); } } thrift-0.23.0/lib/php/test/Unit/Lib/Factory/TFramedTransportFactoryTest.php0000664000175000017500000000326715167543515027112 0ustar00buildbuild00000000000000createMock(TTransport::class); $factory = new TFramedTransportFactory(); $framedTransport = $factory->getTransport($transport); $this->assertInstanceOf(TFramedTransport::class, $framedTransport); $this->assertTrue($this->getPropertyValue($framedTransport, 'read_')); $this->assertTrue($this->getPropertyValue($framedTransport, 'write_')); $this->assertSame($transport, $this->getPropertyValue($framedTransport, 'transport_')); } } thrift-0.23.0/lib/php/test/Unit/Lib/StringFunc/0000775000175000017500000000000015165535636021420 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/StringFunc/MbStringTest.php0000664000175000017500000001373115165535636024523 0ustar00buildbuild00000000000000assertEquals($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' => '粵語', ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/StringFunc/CoreTest.php0000664000175000017500000001371115165535636023664 0ustar00buildbuild00000000000000assertEquals($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' => '粵語', ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/ClassLoader/0000775000175000017500000000000015165535636021532 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/ClassLoader/Fixtures/0000775000175000017500000000000015165535636023343 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/ClassLoader/Fixtures/E/0000775000175000017500000000000015165535636023527 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/ClassLoader/Fixtures/E/TestClass.php0000664000175000017500000000162315165535636026147 0ustar00buildbuild00000000000000getFunctionMock('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', ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/0000775000175000017500000000000015167543515021327 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Transport/THttpClientTest.php0000664000175000017500000002502715167543515025110 0ustar00buildbuild00000000000000setTimeoutSecs(1000); $this->assertEquals(1000, $this->getPropertyValue($transport, 'timeout_')); } 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); $this->setPropertyValue($transport, 'handle_', $handle); $this->assertNull($transport->close()); $this->assertNull($this->getPropertyValue($transport, 'handle_')); } /** * @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); $this->setPropertyValue($transport, 'handle_', $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); $transport->write('1234567890'); $this->assertEquals('1234567890', $this->getPropertyValue($transport, 'buf_')); } /** * @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); $this->setPropertyValue($transport, 'headers_', ['test' => '1234567890']); $transport->addHeaders(['test2' => '12345']); $this->assertEquals(['test' => '1234567890', 'test2' => '12345'], $this->getPropertyValue($transport, 'headers_')); } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TSocketPoolTest.php0000664000175000017500000004345315167543515025117 0ustar00buildbuild00000000000000assertEquals($expectedServers, $this->getPropertyValue($socketPool, 'servers_')); } 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); $this->assertEquals([['host' => 'localhost', 'port' => 9090]], $this->getPropertyValue($socketPool, 'servers_')); } public function testSetNumRetries(): void { $socketPool = new TSocketPool([], []); $socketPool->setNumRetries(5); $this->assertEquals(5, $this->getPropertyValue($socketPool, 'numRetries_')); } public function testrSetRetryInterval(): void { $socketPool = new TSocketPool([], []); $socketPool->setRetryInterval(5); $this->assertEquals(5, $this->getPropertyValue($socketPool, 'retryInterval_')); } public function testrSetMaxConsecutiveFailures(): void { $socketPool = new TSocketPool([], []); $socketPool->setMaxConsecutiveFailures(5); $this->assertEquals(5, $this->getPropertyValue($socketPool, 'maxConsecutiveFailures_')); } public function testrSetRandomize(): void { $socketPool = new TSocketPool([], []); $socketPool->setRandomize(false); $this->assertEquals(false, $this->getPropertyValue($socketPool, 'randomize_')); } public function testrSetAlwaysTryLast(): void { $socketPool = new TSocketPool([], []); $socketPool->setAlwaysTryLast(false); $this->assertEquals(false, $this->getPropertyValue($socketPool, 'alwaysTryLast_')); } /** * @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, ], ] ); } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TPhpStreamTest.php0000664000175000017500000002403715165535636024740 0ustar00buildbuild00000000000000 $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(); } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TNullTransportTest.php0000664000175000017500000000347315165535636025665 0ustar00buildbuild00000000000000assertTrue($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')); } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TMemoryBufferTest.php0000664000175000017500000001042415165535636025432 0ustar00buildbuild00000000000000assertTrue($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()); } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TBufferedTransportTest.php0000664000175000017500000002052415167543515026466 0ustar00buildbuild00000000000000createMock(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'); $this->assertEquals('test', $this->getPropertyValue($bufferedTransport, 'rBuf_')); $bufferedTransport->putBack('abcde'); $this->assertEquals('abcdetest', $this->getPropertyValue($bufferedTransport, 'rBuf_')); } /** * @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)); $this->assertEquals($expectedBufferValue, $this->getPropertyValue($bufferedTransport, 'rBuf_')); } 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)); $this->assertEquals($expectedBufferValue, $this->getPropertyValue($bufferedTransport, 'rBuf_')); } 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)); $this->assertEquals($expectedWriteBufferValue, $this->getPropertyValue($bufferedTransport, 'wBuf_')); } 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); $this->setPropertyValue($bufferedTransport, 'wBuf_', $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('', $this->getPropertyValue($bufferedTransport, 'wBuf_')); } public function flushDataProvider() { yield 'empty buffer' => [ 'writeBuffer' => '', ]; yield 'not empty buffer' => [ 'writeBuffer' => '12345', ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TFramedTransportTest.php0000664000175000017500000001643515167543515026150 0ustar00buildbuild00000000000000createMock(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'); $this->assertEquals('test', $this->getPropertyValue($framedTransport, 'rBuf_')); $framedTransport->putBack('abcde'); $this->assertEquals('abcdetest', $this->getPropertyValue($framedTransport, 'rBuf_')); } /** * @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); $this->assertEquals($expectedWriteBufferValue, $this->getPropertyValue($framedTransport, 'wBuf_')); } 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); $this->setPropertyValue($framedTransport, 'wBuf_', $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', ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TCurlClientTest.php0000664000175000017500000003431515167543515025076 0ustar00buildbuild00000000000000setTimeoutSecs(1000); $this->assertEquals(1000, $this->getPropertyValue($transport, 'timeout_')); } public function testSetConnectionTimeoutSecs() { $host = 'localhost'; $transport = new TCurlClient($host); $transport->setConnectionTimeoutSecs(1000); $this->assertEquals(1000, $this->getPropertyValue($transport, 'connectionTimeout_')); } 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); $this->setPropertyValue($transport, 'request_', 'testRequest'); $this->setPropertyValue($transport, 'response_', 'testResponse'); $this->assertNull($transport->close()); $this->assertEmpty($this->getPropertyValue($transport, 'request_')); $this->assertEmpty($this->getPropertyValue($transport, 'response_')); } public function testRead() { $host = 'localhost'; $transport = new TCurlClient($host); $this->setPropertyValue($transport, 'response_', '1234567890'); $response = $transport->read(5); $this->assertEquals('12345', $response); $this->assertEquals('67890', $this->getPropertyValue($transport, 'response_')); $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', $this->getPropertyValue($transport, 'response_')); } public function testReadAll() { $host = 'localhost'; $transport = new TCurlClient($host); $this->setPropertyValue($transport, 'response_', '1234567890'); $response = $transport->readAll(5); $this->assertEquals('12345', $response); $this->assertEquals('67890', $this->getPropertyValue($transport, 'response_')); } public function testReadAllThrift4656() { $host = 'localhost'; $transport = new TCurlClient($host); $this->setPropertyValue($transport, 'response_', ''); $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); $this->setPropertyValue($transport, 'request_', '1234567890'); $transport->write('12345'); $this->assertEquals('123456789012345', $this->getPropertyValue($transport, 'request_')); } public function testAddHeaders() { $host = 'localhost'; $transport = new TCurlClient($host); $this->setPropertyValue($transport, 'headers_', ['test' => '1234567890']); $transport->addHeaders(['test2' => '12345']); $this->assertEquals(['test' => '1234567890', 'test2' => '12345'], $this->getPropertyValue($transport, 'headers_')); } /** * @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'); $this->setPropertyValue($transport, 'curlHandle', 'testHandle'); $transport::closeCurlHandle(); } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TSSLSocketTest.php0000664000175000017500000001734215167543515024645 0ustar00buildbuild00000000000000expectException($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']; } } thrift-0.23.0/lib/php/test/Unit/Lib/Transport/TSocketTest.php0000664000175000017500000005153515167543515024265 0ustar00buildbuild00000000000000expectException($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 openThrift5132DataProvider */ public function testOpenThrift5132( $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 openThrift5132DataProvider() { 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); $this->assertEquals(9.0, $this->getPropertyValue($transport, 'sendTimeoutSec_')); $this->assertEquals(999000, $this->getPropertyValue($transport, 'sendTimeoutUsec_')); } public function testSetRecvTimeout() { $host = 'localhost'; $port = 9090; $persist = false; $debugHandler = null; $transport = new TSocket( $host, $port, $persist, $debugHandler ); $transport->setRecvTimeout(9999); $this->assertEquals(9.0, $this->getPropertyValue($transport, 'recvTimeoutSec_')); $this->assertEquals(999000, $this->getPropertyValue($transport, 'recvTimeoutUsec_')); } /** * @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+')); $this->assertNotNull($this->getPropertyValue($transport, 'handle_')); $transport->close(); $this->assertNull($this->getPropertyValue($transport, 'handle_')); } /** * @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()); } } thrift-0.23.0/lib/php/test/Unit/Lib/Server/0000775000175000017500000000000015167543515020601 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Server/TSSLServerSocketTest.php0000664000175000017500000001171415167543515025303 0ustar00buildbuild00000000000000assertEquals('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(); $this->assertIsResource($this->getPropertyValue($socket, 'listener_')); $this->getFunctionMock('Thrift\Server', 'fclose') ->expects($this->once()) ->with($this->equalTo($listener)) ->willReturn(true); $socket->close(); $this->assertNull($this->getPropertyValue($socket, 'listener_')); } 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); $this->assertEquals($transportHandle, $this->getPropertyValue($result, 'handle_')); } 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(); } } thrift-0.23.0/lib/php/test/Unit/Lib/Server/TServerSocketTest.php0000664000175000017500000000724415167543515024724 0ustar00buildbuild00000000000000setAcceptTimeout(1000); $this->assertEquals(1000, $this->getPropertyValue($socket, 'acceptTimeout_')); } 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(); $this->assertIsResource($this->getPropertyValue($socket, 'listener_')); $this->getFunctionMock('Thrift\Server', 'fclose') ->expects($this->once()) ->with($this->equalTo($listener)) ->willReturn(true); $socket->close(); $this->assertNull($this->getPropertyValue($socket, 'listener_')); } 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); $this->assertEquals($transportHandle, $this->getPropertyValue($result, 'handle_')); } 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(); } } thrift-0.23.0/lib/php/test/Unit/Lib/Server/TForkingServerTest.php0000664000175000017500000000211115165535636025062 0ustar00buildbuild00000000000000markTestSkipped('Unit test could not be written for class which use pcntl_fork and exit functions'); } } thrift-0.23.0/lib/php/test/Unit/Lib/Server/Fixture/0000775000175000017500000000000015165535636022232 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Server/Fixture/TestProcessor.php0000664000175000017500000000170215165535636025562 0ustar00buildbuild00000000000000processor = $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, ] ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/ReflectionHelper.php0000664000175000017500000000427615167543515023307 0ustar00buildbuild00000000000000getProperty($propertyName); // Only call setAccessible for PHP < 8.1.0 if (PHP_VERSION_ID < 80100) { $property->setAccessible(true); } return $property; } /** * Get the value of a private/protected property * * @param object $object * @param string $propertyName * @return mixed */ protected function getPropertyValue($object, string $propertyName) { $property = $this->getAccessibleProperty($object, $propertyName); return $property->getValue($object); } /** * Set the value of a private/protected property * * @param object $object * @param string $propertyName * @param mixed $value * @return void */ protected function setPropertyValue($object, string $propertyName, $value): void { $property = $this->getAccessibleProperty($object, $propertyName); $property->setValue($object, $value); } } thrift-0.23.0/lib/php/test/Unit/Lib/Protocol/0000775000175000017500000000000015167543515021134 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php0000664000175000017500000006436315167543515025755 0ustar00buildbuild00000000000000createMock(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); $this->assertSame(self::STATE_VALUE_WRITE, $this->getPropertyValue($protocol, 'state')); } public function testWriteMessageEnd() { $transport = $this->createMock(TTransport::class); $protocol = new TCompactProtocol($transport); $this->assertSame(0, $protocol->writeMessageEnd()); $this->assertSame(self::STATE_CLEAR, $this->getPropertyValue($protocol, 'state')); } public function testWriteStruct() { $name = 'testName'; $transport = $this->createMock(TTransport::class); $protocol = new TCompactProtocol($transport); $this->assertSame(0, $protocol->writeStructBegin($name)); $this->assertSame([[self::STATE_CLEAR, 0]], $this->getPropertyValue($protocol, 'structs')); $this->assertSame(self::STATE_FIELD_WRITE, $this->getPropertyValue($protocol, 'state')); $this->assertSame(0, $this->getPropertyValue($protocol, 'lastFid')); $this->assertSame(0, $protocol->writeStructBegin($name)); $this->assertSame(self::STATE_FIELD_WRITE, $this->getPropertyValue($protocol, 'state')); $this->assertSame(0, $this->getPropertyValue($protocol, 'lastFid')); $this->assertSame([[self::STATE_CLEAR, 0], [self::STATE_FIELD_WRITE, 0]], $this->getPropertyValue($protocol, 'structs')); $this->assertSame(0, $protocol->writeStructEnd()); $this->assertSame(self::STATE_FIELD_WRITE, $this->getPropertyValue($protocol, 'state')); $this->assertSame(0, $this->getPropertyValue($protocol, 'lastFid')); $this->assertSame([[self::STATE_CLEAR, 0]], $this->getPropertyValue($protocol, 'structs')); $this->assertSame(0, $protocol->writeStructEnd()); $this->assertSame(self::STATE_CLEAR, $this->getPropertyValue($protocol, 'state')); $this->assertSame(0, $this->getPropertyValue($protocol, 'lastFid')); $this->assertSame([], $this->getPropertyValue($protocol, 'structs')); } 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)); $this->assertSame($expectedState, $this->getPropertyValue($protocol, 'state')); $this->assertSame($expectedBoolFid, $this->getPropertyValue($protocol, 'boolFid')); $this->assertSame($expectedLastFid, $this->getPropertyValue($protocol, 'lastFid')); } 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()); $this->assertSame(self::STATE_FIELD_WRITE, $this->getPropertyValue($protocol, 'state')); } /** * @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)); $this->assertSame($expectedState, $this->getPropertyValue($protocol, 'state')); $this->assertSame($expectedContainers, $this->getPropertyValue($protocol, 'containers')); $this->assertSame(0, $protocol->writeCollectionEnd()); $this->assertSame(TCompactProtocol::STATE_CLEAR, $this->getPropertyValue($protocol, 'state')); } 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)); $this->assertSame($expectedContainers, $this->getPropertyValue($protocol, 'containers')); $this->assertSame(TCompactProtocol::STATE_CLEAR, $this->getPropertyValue($protocol, 'state')); $this->assertSame(0, $protocol->writeMapEnd()); $this->assertSame(TCompactProtocol::STATE_CLEAR, $this->getPropertyValue($protocol, 'state')); $this->assertSame([], $this->getPropertyValue($protocol, 'containers')); } 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)) { $this->setPropertyValue($protocol, 'state', $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')); } public function testWriteUuid() { $uuid = '01234567-89ab-cdef-0123-456789abcdef'; $transport = $this->createMock(TTransport::class); $protocol = new TCompactProtocol($transport); $transport ->expects($this->once()) ->method('write') ->with(hex2bin('0123456789abcdef0123456789abcdef'), 16) ->willReturn(16); $this->assertSame(16, $protocol->writeUuid($uuid)); } public function testReadUuid() { $transport = $this->createMock(TTransport::class); $protocol = new TCompactProtocol($transport); $transport ->expects($this->once()) ->method('readAll') ->with(16) ->willReturn(hex2bin('0123456789abcdef0123456789abcdef')); $this->assertSame(16, $protocol->readUuid($value)); $this->assertSame('01234567-89ab-cdef-0123-456789abcdef', $value); } /** * @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, ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Protocol/TSimpleJSONProtocolTest.php0000664000175000017500000001017615165535636026306 0ustar00buildbuild00000000000000expectException(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'], ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php0000664000175000017500000007516115167543515025611 0ustar00buildbuild00000000000000createMock(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)); } public function testWriteUuid() { $uuid = '01234567-89ab-cdef-0123-456789abcdef'; $transport = $this->createMock(TTransport::class); $protocol = new TBinaryProtocol($transport, false, false); $transport ->expects($this->once()) ->method('write') ->with(hex2bin('0123456789abcdef0123456789abcdef'), 16) ->willReturn(16); $this->assertEquals(16, $protocol->writeUuid($uuid)); } public function testReadUuid() { $transport = $this->createMock(TTransport::class); $protocol = new TBinaryProtocol($transport, false, false); $transport ->expects($this->once()) ->method('readAll') ->with(16) ->willReturn(hex2bin('0123456789abcdef0123456789abcdef')); $this->assertEquals(16, $protocol->readUuid($value)); $this->assertEquals('01234567-89ab-cdef-0123-456789abcdef', $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', ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Protocol/TMultiplexedProtocolTest.php0000664000175000017500000000513315167543515026651 0ustar00buildbuild00000000000000createMock(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' ]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolAcceleratedTest.php0000664000175000017500000000463715165535636027731 0ustar00buildbuild00000000000000assertInstanceOf($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]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Protocol/TProtocolDecoratorTest.php0000664000175000017500000001005415165535636026300 0ustar00buildbuild00000000000000createMock(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']]; } } thrift-0.23.0/lib/php/test/Unit/Lib/Serializer/0000775000175000017500000000000015165535636021447 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Unit/Lib/Serializer/TBinarySerializerTest.php0000664000175000017500000000235215165535636026424 0ustar00buildbuild00000000000000markTestIncomplete('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'); } } thrift-0.23.0/lib/php/test/bootstrap.php0000664000175000017500000000116015165535636020435 0ustar00buildbuild00000000000000registerNamespace('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(); thrift-0.23.0/lib/php/test/Integration/0000775000175000017500000000000015165535636020174 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Integration/Lib/0000775000175000017500000000000015165535636020702 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Integration/Lib/ClassLoader/0000775000175000017500000000000015165535636023076 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Integration/Lib/ClassLoader/ThriftClassLoaderTest.php0000664000175000017500000001222215165535636030023 0ustar00buildbuild00000000000000getFunctionMock('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', ]; } } thrift-0.23.0/lib/php/test/Integration/Lib/Protocol/0000775000175000017500000000000015170007142022461 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Integration/Lib/Protocol/TSimpleJSONProtocolTest.php0000664000175000017500000007077115170007142027637 0ustar00buildbuild00000000000000transport = 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}', ]; } } thrift-0.23.0/lib/php/test/Integration/Lib/Protocol/TJSONProtocolTest.php0000664000175000017500000015054715170007142026465 0ustar00buildbuild00000000000000transport = 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, ]; } } thrift-0.23.0/lib/php/test/Integration/Lib/Serializer/0000775000175000017500000000000015165535636023013 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Integration/Lib/Serializer/JsonSerializeTest.php0000664000175000017500000001004015165535636027140 0ustar00buildbuild00000000000000 'bar')); $this->assertEquals(new stdClass(), json_decode(json_encode($empty))); } public function testStringsAndInts() { $input = array( 'string_thing' => 'foo', 'i64_thing' => 1234567890, ); $xtruct = new \Json\ThriftTest\Xtruct($input); // Xtruct's 'i32_thing' and 'byte_thing' fields should not be present here! $expected = new stdClass(); $expected->string_thing = $input['string_thing']; $expected->i64_thing = $input['i64_thing']; $this->assertEquals($expected, json_decode(json_encode($xtruct))); } public function testNestedStructs() { $xtruct2 = new \Json\ThriftTest\Xtruct2(array( 'byte_thing' => 42, 'struct_thing' => new \Json\ThriftTest\Xtruct(array( 'i32_thing' => 123456, )), )); $expected = new stdClass(); $expected->byte_thing = $xtruct2->byte_thing; $expected->struct_thing = new stdClass(); $expected->struct_thing->i32_thing = $xtruct2->struct_thing->i32_thing; $this->assertEquals($expected, json_decode(json_encode($xtruct2))); } public function testInsanity() { $xinput = array('string_thing' => 'foo'); $xtruct = new \Json\ThriftTest\Xtruct($xinput); $insanity = new \Json\ThriftTest\Insanity(array( 'xtructs' => array($xtruct, $xtruct, $xtruct) )); $expected = new stdClass(); $expected->xtructs = array((object)$xinput, (object)$xinput, (object)$xinput); $this->assertEquals($expected, json_decode(json_encode($insanity))); } public function testNestedLists() { $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))); } public function testMaps() { $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 \Json\ThriftTest\Bools(['im_true' => '1', 'im_false' => '0']); $this->assertEquals('{"im_true":true,"im_false":false}', json_encode($b)); $s = new \Json\ThriftTest\StructA(['s' => 42]); $this->assertEquals('{"s":"42"}', json_encode($s)); } } thrift-0.23.0/lib/php/test/Integration/Lib/Serializer/BinarySerializerTest.php0000664000175000017500000000332515165535636027645 0ustar00buildbuild00000000000000 'abc')); $serialized = TBinarySerializer::serialize($struct, '\\Basic\\ThriftTest\\Xtruct'); $deserialized = TBinarySerializer::deserialize($serialized, '\\Basic\\ThriftTest\\Xtruct'); $this->assertEquals($struct, $deserialized); } } thrift-0.23.0/lib/php/test/Integration/BaseValidatorTest.php0000664000175000017500000001334215165535636024270 0ustar00buildbuild00000000000000assertNoReadValidator($this->getNsGlobal() . '\ThriftTest\EmptyStruct'); $this->assertNoWriteValidator($this->getNsGlobal() . '\ThriftTest\EmptyStruct'); } public function testBonkValidator() { $this->assertNoReadValidator($this->getNsGlobal() . '\ThriftTest\Bonk'); $this->assertHasWriteValidator($this->getNsGlobal() . '\ThriftTest\Bonk'); } public function testStructAValidator() { $this->assertHasReadValidator($this->getNsGlobal() . '\ThriftTest\StructA'); $this->assertHasWriteValidator($this->getNsGlobal() . '\ThriftTest\StructA'); } public function testUnionOfStringsValidator() { $this->assertNoWriteValidator($this->getNsGlobal() . '\TestValidators\UnionOfStrings'); } public function testServiceResultValidator() { $this->assertNoReadValidator($this->getNsGlobal() . '\TestValidators\TestService_test_result'); $this->assertNoWriteValidator($this->getNsGlobal() . '\TestValidators\TestService_test_result'); } public function testReadEmpty() { $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() { $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 $className = $this->getNsGlobal() . '\ThriftTest\StructA'; $structa = new $className(); $transport = new TMemoryBuffer(); $protocol = new TBinaryProtocol($transport); try { $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; } } public function testReadStructA() { $transport = new TMemoryBuffer(base64_decode('CwABAAAAA2FiYwA=')); $protocol = new TBinaryProtocol($transport); $className = $this->getNsGlobal() . '\ThriftTest\StructA'; $structa = new $className(); $structa->read($protocol); $this->assertEquals("abc", $structa->s); } public function testWriteStructA() { $transport = new TMemoryBuffer(); $protocol = new TBinaryProtocol($transport); $className = $this->getNsGlobal() . '\ThriftTest\StructA'; $structa = new $className(); $structa->s = "abc"; $structa->write($protocol); $writeResult = base64_encode($transport->getBuffer()); $this->assertEquals('CwABAAAAA2FiYwA=', $writeResult); } protected static function assertHasReadValidator($class) { if (!static::hasReadValidator($class)) { static::fail($class . ' class should have a read validator'); } else { static::assertTrue(true); } } protected static function assertNoReadValidator($class) { if (static::hasReadValidator($class)) { static::fail($class . ' class should not have a write validator'); } else { static::assertTrue(true); } } protected static function assertHasWriteValidator($class) { if (!static::hasWriteValidator($class)) { static::fail($class . ' class should have a write validator'); } else { static::assertTrue(true); } } protected static function assertNoWriteValidator($class) { if (static::hasWriteValidator($class)) { static::fail($class . ' class should not have a write validator'); } else { static::assertTrue(true); } } private static function hasReadValidator($class) { $rc = new \ReflectionClass($class); return $rc->hasMethod('_validateForRead'); } private static function hasWriteValidator($class) { $rc = new \ReflectionClass($class); return $rc->hasMethod('_validateForWrite'); } } thrift-0.23.0/lib/php/test/Integration/ValidatorTest.php0000664000175000017500000000231615165535636023474 0ustar00buildbuild00000000000000&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/php/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/php/test abs_srcdir = /thrift/src/lib/php/test abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. PHPUNIT = php $(top_srcdir)/vendor/bin/phpunit all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/php/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/php/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile 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: deps stubs $(PHPUNIT) --log-junit=test-log-junit.xml -c phpunit.xml / distclean-local: distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am clean-local: $(RM) -r ./Resources/packages $(RM) test-log-junit.xml # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/php/test/Resources/0000775000175000017500000000000015167543515017660 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/test/Resources/ThriftTest.thrift0000664000175000017500000000177415167543515023213 0ustar00buildbuild00000000000000/* * 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 php TestValidators include "../../../../test/ThriftTest.thrift" union UnionOfStrings { 1: string aa; 2: string bb; } service TestService { void test() throws(1: ThriftTest.Xception xception); } thrift-0.23.0/lib/php/test/Makefile.in0000644000175000017500000004453415170007167017753 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/php/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ PHPUNIT = php $(top_srcdir)/vendor/bin/phpunit all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/php/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/php/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distclean-local distdir \ dvi dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile 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: deps stubs $(PHPUNIT) --log-junit=test-log-junit.xml -c phpunit.xml / distclean-local: distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am clean-local: $(RM) -r ./Resources/packages $(RM) test-log-junit.xml # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/php/test/Makefile.am0000664000175000017500000000360715165535636017753 0ustar00buildbuild00000000000000# # 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. # PHPUNIT=php $(top_srcdir)/vendor/bin/phpunit 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: deps stubs $(PHPUNIT) --log-junit=test-log-junit.xml -c phpunit.xml / distclean-local: distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am clean-local: $(RM) -r ./Resources/packages $(RM) test-log-junit.xml thrift-0.23.0/lib/php/coding_standards.md0000664000175000017500000000022515165535636020561 0ustar00buildbuild00000000000000## PHP Coding Standards Please follow: * [Thrift General Coding Standards](/doc/coding_standards.md) * [PSR-2](http://www.php-fig.org/psr/psr-2/) thrift-0.23.0/lib/php/phpunit.xml0000664000175000017500000000331515165535636017145 0ustar00buildbuild00000000000000 ./lib ./test/Unit ./test/Integration thrift-0.23.0/lib/php/README.apache.md0000664000175000017500000000406315165535636017434 0ustar00buildbuild00000000000000Thrift PHP/Apache Integration License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Building PHP Thrift Services with Apache ======================================== Thrift can be embedded in the Apache webserver with PHP installed. Sample code is provided below. Note that to make requests to this type of server you must use a THttpClient transport. Sample Code =========== ```php registerNamespace('Thrift', $THRIFT_ROOT); $loader->registerDefinition('Thrift', $THRIFT_ROOT . '/packages'); $loader->register(); use Thrift\Transport\TPhpStream; use Thrift\Protocol\TBinaryProtocol; /** * Example of how to build a Thrift server in Apache/PHP */ class ServiceHandler implements ServiceIf { // Implement your interface and methods here } header('Content-Type: application/x-thrift'); $handler = new ServiceHandler(); $processor = new ServiceProcessor($handler); // Use the TPhpStream transport to read/write directly from HTTP $transport = new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W); $protocol = new TBinaryProtocol($transport); $transport->open(); $processor->process($protocol, $protocol); $transport->close(); ``` thrift-0.23.0/lib/php/README.md0000664000175000017500000000406315165535636016214 0ustar00buildbuild00000000000000Thrift PHP Software Library # License Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. # Using Thrift with 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. To use Thrift in your PHP codebase, take the following steps: 1. Copy all of thrift/lib/php/lib into your PHP codebase 2. Configure Symfony Autoloader (or whatever you usually use) After that, you have to manually include the Thrift package created by the compiler: ``` require_once 'packages/Service/Service.php'; require_once 'packages/Service/Types.php'; ``` # Dependencies PHP_INT_SIZE This built-in signals whether your architecture is 32 or 64 bit and is used by the TBinaryProtocol to properly use pack() and unpack() to serialize data. apcu_fetch(), apcu_store() APCu cache is used by the TSocketPool class. If you do not have APCu installed, Thrift will fill in null stub function definitions. # Breaking Changes ## 0.12.0 1. [PSR-4](https://www.php-fig.org/psr/psr-4/) loader is now the default. If you want to use class maps instead, use `-gen php:classmap`. 2. If using PSR-4, use `$thriftClassLoader->registerNamespace('namespace', '')` instead of `$thriftClassLoader->registerDefinition('namespace', '')`. thrift-0.23.0/lib/php/lib/0000775000175000017500000000000015165535636015500 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/TMultiplexedProcessor.php0000664000175000017500000001073215165535636022534 0ustar00buildbuild00000000000000TMultiplexedProcessor is a Processor allowing * a single TServer to provide multiple services. * *

To do so, you instantiate the processor and then register additional * processors with it, as shown in the following example:

* *
* $processor = new TMultiplexedProcessor(); * * processor->registerProcessor( * "Calculator", * new \tutorial\CalculatorProcessor(new CalculatorHandler())); * * processor->registerProcessor( * "WeatherReport", * new \tutorial\WeatherReportProcessor(new WeatherReportHandler())); * * $processor->process($protocol, $protocol); *
*/ class TMultiplexedProcessor { private $serviceProcessorMap_; /** * 'Register' a service with this TMultiplexedProcessor. This * allows us to broker requests to individual services by using the service * name to select them at request time. * * @param serviceName Name of a service, has to be identical to the name * declared in the Thrift IDL, e.g. "WeatherReport". * @param processor Implementation of a service, usually referred to * as "handlers", e.g. WeatherReportHandler implementing WeatherReport.Iface. */ public function registerProcessor($serviceName, $processor) { $this->serviceProcessorMap_[$serviceName] = $processor; } /** * This implementation of process performs the following steps: * *
    *
  1. Read the beginning of the message.
  2. *
  3. Extract the service name from the message.
  4. *
  5. Using the service name to locate the appropriate processor.
  6. *
  7. Dispatch to the processor, with a decorated instance of TProtocol * that allows readMessageBegin() to return the original Message.
  8. *
* * @throws TException If the message type is not CALL or ONEWAY, if * the service name was not found in the message, or if the service * name was not found in the service map. */ public function process(TProtocol $input, TProtocol $output) { /* Use the actual underlying protocol (e.g. TBinaryProtocol) to read the message header. This pulls the message "off the wire", which we'll deal with at the end of this method. */ $input->readMessageBegin($fname, $mtype, $rseqid); if ($mtype !== TMessageType::CALL && $mtype != TMessageType::ONEWAY) { throw new TException("This should not have happened!?"); } // Extract the service name and the new Message name. if (strpos((string) $fname, TMultiplexedProtocol::SEPARATOR) === false) { throw new TException("Service name not found in message name: {$fname}. Did you " . "forget to use a TMultiplexProtocol in your client?"); } list($serviceName, $messageName) = explode(':', $fname, 2); if (!array_key_exists($serviceName, $this->serviceProcessorMap_)) { throw new TException("Service name not found: {$serviceName}. Did you forget " . "to call registerProcessor()?"); } // Dispatch processing to the stored processor $processor = $this->serviceProcessorMap_[$serviceName]; return $processor->process( new StoredMessageProtocol($input, $messageName, $mtype, $rseqid), $output ); } } thrift-0.23.0/lib/php/lib/Exception/0000775000175000017500000000000015165535636017436 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Exception/TTransportException.php0000664000175000017500000000225715165535636024154 0ustar00buildbuild00000000000000 array('var' => 'message', 'type' => TType::STRING), 2 => array('var' => 'code', 'type' => TType::I32)); const UNKNOWN = 0; const UNKNOWN_METHOD = 1; const INVALID_MESSAGE_TYPE = 2; const WRONG_METHOD_NAME = 3; const BAD_SEQUENCE_ID = 4; const MISSING_RESULT = 5; const INTERNAL_ERROR = 6; const PROTOCOL_ERROR = 7; const INVALID_TRANSFORM = 8; const INVALID_PROTOCOL = 9; const UNSUPPORTED_CLIENT_TYPE = 10; public function __construct($message = null, $code = 0) { parent::__construct($message, $code); } public function read($output) { return $this->_read('TApplicationException', self::$_TSPEC, $output); } public function write($output) { $xfer = 0; $xfer += $output->writeStructBegin('TApplicationException'); if ($message = $this->getMessage()) { $xfer += $output->writeFieldBegin('message', TType::STRING, 1); $xfer += $output->writeString($message); $xfer += $output->writeFieldEnd(); } if ($code = $this->getCode()) { $xfer += $output->writeFieldBegin('type', TType::I32, 2); $xfer += $output->writeI32($code); $xfer += $output->writeFieldEnd(); } $xfer += $output->writeFieldStop(); $xfer += $output->writeStructEnd(); return $xfer; } } thrift-0.23.0/lib/php/lib/Exception/TProtocolException.php0000664000175000017500000000265715165535636023765 0ustar00buildbuild00000000000000 $fspec) { $var = $fspec['var']; if (isset($vals[$var])) { $this->$var = $vals[$var]; } } } else { parent::__construct((string)$p1, $p2); } } public static $tmethod = array( TType::BOOL => 'Bool', TType::BYTE => 'Byte', TType::I16 => 'I16', TType::I32 => 'I32', TType::I64 => 'I64', TType::DOUBLE => 'Double', TType::STRING => 'String' ); private function _readMap(&$var, $spec, $input) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kread = $vread = null; if (isset(TBase::$tmethod[$ktype])) { $kread = 'read' . TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vread = 'read' . TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $var = array(); $_ktype = $_vtype = $size = 0; $xfer += $input->readMapBegin($_ktype, $_vtype, $size); for ($i = 0; $i < $size; ++$i) { $key = $val = null; if ($kread !== null) { $xfer += $input->$kread($key); } else { switch ($ktype) { case TType::STRUCT: $class = $kspec['class']; $key = new $class(); $xfer += $key->read($input); break; case TType::MAP: $xfer += $this->_readMap($key, $kspec, $input); break; case TType::LST: $xfer += $this->_readList($key, $kspec, $input, false); break; case TType::SET: $xfer += $this->_readList($key, $kspec, $input, true); break; } } if ($vread !== null) { $xfer += $input->$vread($val); } else { switch ($vtype) { case TType::STRUCT: $class = $vspec['class']; $val = new $class(); $xfer += $val->read($input); break; case TType::MAP: $xfer += $this->_readMap($val, $vspec, $input); break; case TType::LST: $xfer += $this->_readList($val, $vspec, $input, false); break; case TType::SET: $xfer += $this->_readList($val, $vspec, $input, true); break; } } $var[$key] = $val; } $xfer += $input->readMapEnd(); return $xfer; } private function _readList(&$var, $spec, $input, $set = false) { $xfer = 0; $etype = $spec['etype']; $eread = $vread = null; if (isset(TBase::$tmethod[$etype])) { $eread = 'read' . TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } $var = array(); $_etype = $size = 0; if ($set) { $xfer += $input->readSetBegin($_etype, $size); } else { $xfer += $input->readListBegin($_etype, $size); } for ($i = 0; $i < $size; ++$i) { $elem = null; if ($eread !== null) { $xfer += $input->$eread($elem); } else { $espec = $spec['elem']; switch ($etype) { case TType::STRUCT: $class = $espec['class']; $elem = new $class(); $xfer += $elem->read($input); break; case TType::MAP: $xfer += $this->_readMap($elem, $espec, $input); break; case TType::LST: $xfer += $this->_readList($elem, $espec, $input, false); break; case TType::SET: $xfer += $this->_readList($elem, $espec, $input, true); break; } } if ($set) { $var[$elem] = true; } else { $var [] = $elem; } } if ($set) { $xfer += $input->readSetEnd(); } else { $xfer += $input->readListEnd(); } return $xfer; } protected function _read($class, $spec, $input) { $xfer = 0; $fname = null; $ftype = 0; $fid = 0; $xfer += $input->readStructBegin($fname); while (true) { $xfer += $input->readFieldBegin($fname, $ftype, $fid); if ($ftype == TType::STOP) { break; } if (isset($spec[$fid])) { $fspec = $spec[$fid]; $var = $fspec['var']; if ($ftype == $fspec['type']) { $xfer = 0; if (isset(TBase::$tmethod[$ftype])) { $func = 'read' . TBase::$tmethod[$ftype]; $xfer += $input->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $class = $fspec['class']; $this->$var = new $class(); $xfer += $this->$var->read($input); break; case TType::MAP: $xfer += $this->_readMap($this->$var, $fspec, $input); break; case TType::LST: $xfer += $this->_readList($this->$var, $fspec, $input, false); break; case TType::SET: $xfer += $this->_readList($this->$var, $fspec, $input, true); break; } } } else { $xfer += $input->skip($ftype); } } else { $xfer += $input->skip($ftype); } $xfer += $input->readFieldEnd(); } $xfer += $input->readStructEnd(); return $xfer; } private function _writeMap($var, $spec, $output) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kwrite = $vwrite = null; if (isset(TBase::$tmethod[$ktype])) { $kwrite = 'write' . TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vwrite = 'write' . TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $xfer += $output->writeMapBegin($ktype, $vtype, count($var)); foreach ($var as $key => $val) { if (isset($kwrite)) { $xfer += $output->$kwrite($key); } else { switch ($ktype) { case TType::STRUCT: $xfer += $key->write($output); break; case TType::MAP: $xfer += $this->_writeMap($key, $kspec, $output); break; case TType::LST: $xfer += $this->_writeList($key, $kspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($key, $kspec, $output, true); break; } } if (isset($vwrite)) { $xfer += $output->$vwrite($val); } else { switch ($vtype) { case TType::STRUCT: $xfer += $val->write($output); break; case TType::MAP: $xfer += $this->_writeMap($val, $vspec, $output); break; case TType::LST: $xfer += $this->_writeList($val, $vspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($val, $vspec, $output, true); break; } } } $xfer += $output->writeMapEnd(); return $xfer; } private function _writeList($var, $spec, $output, $set = false) { $xfer = 0; $etype = $spec['etype']; $ewrite = null; if (isset(TBase::$tmethod[$etype])) { $ewrite = 'write' . TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } if ($set) { $xfer += $output->writeSetBegin($etype, count($var)); } else { $xfer += $output->writeListBegin($etype, count($var)); } foreach ($var as $key => $val) { $elem = $set ? $key : $val; if (isset($ewrite)) { $xfer += $output->$ewrite($elem); } else { switch ($etype) { case TType::STRUCT: $xfer += $elem->write($output); break; case TType::MAP: $xfer += $this->_writeMap($elem, $espec, $output); break; case TType::LST: $xfer += $this->_writeList($elem, $espec, $output, false); break; case TType::SET: $xfer += $this->_writeList($elem, $espec, $output, true); break; } } } if ($set) { $xfer += $output->writeSetEnd(); } else { $xfer += $output->writeListEnd(); } return $xfer; } protected function _write($class, $spec, $output) { $xfer = 0; $xfer += $output->writeStructBegin($class); foreach ($spec as $fid => $fspec) { $var = $fspec['var']; if ($this->$var !== null) { $ftype = $fspec['type']; $xfer += $output->writeFieldBegin($var, $ftype, $fid); if (isset(TBase::$tmethod[$ftype])) { $func = 'write' . TBase::$tmethod[$ftype]; $xfer += $output->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $xfer += $this->$var->write($output); break; case TType::MAP: $xfer += $this->_writeMap($this->$var, $fspec, $output); break; case TType::LST: $xfer += $this->_writeList($this->$var, $fspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($this->$var, $fspec, $output, true); break; } } $xfer += $output->writeFieldEnd(); } } $xfer += $output->writeFieldStop(); $xfer += $output->writeStructEnd(); return $xfer; } } thrift-0.23.0/lib/php/lib/Type/0000775000175000017500000000000015167543515016416 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Type/TConstant.php0000664000175000017500000000257215165535636021055 0ustar00buildbuild00000000000000strictRead_ = $strictRead; $this->strictWrite_ = $strictWrite; } /** * @param TTransport $trans * @return TBinaryProtocol */ public function getProtocol($trans) { return new TBinaryProtocol($trans, $this->strictRead_, $this->strictWrite_); } } thrift-0.23.0/lib/php/lib/Factory/TFramedTransportFactory.php0000664000175000017500000000211515165535636024406 0ustar00buildbuild00000000000000strlen($str) - $start; } return mb_substr((string) $str, $start, $length, '8bit'); } /** * @param string $str * @return int */ public function strlen($str) { return mb_strlen((string) $str, '8bit'); } } thrift-0.23.0/lib/php/lib/StringFunc/TStringFunc.php0000664000175000017500000000217715165535636022510 0ustar00buildbuild00000000000000apcu = $apc; $this->apcu_prefix = $apcu_prefix; } /** * Registers a namespace. * * @param string $namespace The namespace * @param array|string $paths The location(s) of the namespace */ public function registerNamespace($namespace, $paths) { $this->namespaces[$namespace] = (array)$paths; } /** * Registers a Thrift definition namespace. * * @param string $namespace The definition namespace * @param array|string $paths The location(s) of the definition namespace */ public function registerDefinition($namespace, $paths) { $this->definitions[$namespace] = (array)$paths; } /** * Registers this instance as an autoloader. * * @param Boolean $prepend Whether to prepend the autoloader or not */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } /** * Loads the given class, definition or interface. * * @param string $class The name of the class */ public function loadClass($class) { if ((true === $this->apcu && ($file = $this->findFileInApcu($class))) || ($file = $this->findFile($class))) { require_once $file; } } /** * Loads the given class or interface in APCu. * @param string $class The name of the class * @return string */ protected function findFileInApcu($class) { if (false === $file = apcu_fetch($this->apcu_prefix . $class)) { apcu_store($this->apcu_prefix . $class, $file = $this->findFile($class)); } return $file; } /** * Find class in namespaces or definitions directories * @param string $class * @return string */ public function findFile($class) { // Remove first backslash if ('\\' == $class[0]) { $class = substr($class, 1); } if (false !== $pos = strrpos($class, '\\')) { // Namespaced class name $namespace = substr($class, 0, $pos); // Iterate in normal namespaces foreach ($this->namespaces as $ns => $dirs) { //Don't interfere with other autoloaders if (0 !== strpos($namespace, $ns)) { continue; } foreach ($dirs as $dir) { $className = substr($class, $pos + 1); $file = $dir . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR . $className . '.php'; if (file_exists($file)) { return $file; } } } // Iterate in Thrift namespaces // Remove first part of namespace $m = explode('\\', $class); // Ignore wrong call if (count($m) <= 1) { #HOW TO TEST THIS? HOW TEST CASE SHOULD LOOK LIKE? return; } $class = array_pop($m); $namespace = implode('\\', $m); foreach ($this->definitions as $ns => $dirs) { //Don't interfere with other autoloaders if (0 !== strpos($namespace, $ns)) { continue; } foreach ($dirs as $dir) { /** * Available in service: Interface, Client, Processor, Rest * And every service methods (_.+) */ 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 { $className = $n[1]; } $file = $dir . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR . $className . '.php'; if (file_exists($file)) { return $file; } } } } } } thrift-0.23.0/lib/php/lib/Transport/0000775000175000017500000000000015167543515017471 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Transport/TNullTransport.php0000664000175000017500000000262415165535636023164 0ustar00buildbuild00000000000000host_ = $host; $this->port_ = $port; $this->persist_ = $persist; $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log'; } /** * @param resource $handle * @return void */ public function setHandle($handle) { $this->handle_ = $handle; stream_set_blocking($this->handle_, false); } /** * Sets the send timeout. * * @param int $timeout Timeout in milliseconds. */ public function setSendTimeout($timeout) { $this->sendTimeoutSec_ = floor($timeout / 1000); $this->sendTimeoutUsec_ = ($timeout - ($this->sendTimeoutSec_ * 1000)) * 1000; } /** * Sets the receive timeout. * * @param int $timeout Timeout in milliseconds. */ public function setRecvTimeout($timeout) { $this->recvTimeoutSec_ = floor($timeout / 1000); $this->recvTimeoutUsec_ = ($timeout - ($this->recvTimeoutSec_ * 1000)) * 1000; } /** * Sets debugging output on or off * * @param bool $debug */ public function setDebug($debug) { $this->debug_ = $debug; } /** * Get the host that this socket is connected to * * @return string host */ public function getHost() { return $this->host_; } /** * Get the remote port that this socket is connected to * * @return int port */ public function getPort() { return $this->port_; } /** * Tests whether this is open * * @return bool true if the socket is open */ public function isOpen() { return is_resource($this->handle_); } /** * Connects the socket. */ public function open() { if ($this->isOpen()) { throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN); } if (empty($this->host_)) { throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN); } if ($this->port_ <= 0 && strpos($this->host_, 'unix://') !== 0) { throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN); } if ($this->persist_) { $this->handle_ = @pfsockopen( $this->host_, $this->port_, $errno, $errstr, $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000) ); } else { $this->handle_ = @fsockopen( $this->host_, $this->port_, $errno, $errstr, $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000) ); } // Connect failed? if ($this->handle_ === false) { $error = 'TSocket: Could not connect to ' . $this->host_ . ':' . $this->port_ . ' (' . $errstr . ' [' . $errno . '])'; if ($this->debug_) { call_user_func($this->debugHandler_, $error); } throw new TException($error); } 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_); if ($socket !== false) { @socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1); } } } /** * Closes the socket. */ public function close() { @fclose($this->handle_); $this->handle_ = null; } /** * Read from the socket at most $len bytes. * * This method will not wait for all the requested data, it will return as * soon as any data is received. * * @param int $len Maximum number of bytes to read. * @return string Binary data */ public function read($len) { $null = null; $read = array($this->handle_); $readable = @stream_select( $read, $null, $null, $this->recvTimeoutSec_, $this->recvTimeoutUsec_ ); if ($readable > 0) { $data = fread($this->handle_, $len); if ($data === false) { throw new TTransportException('TSocket: Could not read ' . $len . ' bytes from ' . $this->host_ . ':' . $this->port_); } elseif ($data == '' && feof($this->handle_)) { throw new TTransportException('TSocket read 0 bytes'); } return $data; } elseif ($readable === 0) { throw new TTransportException('TSocket: timed out reading ' . $len . ' bytes from ' . $this->host_ . ':' . $this->port_); } else { throw new TTransportException('TSocket: Could not read ' . $len . ' bytes from ' . $this->host_ . ':' . $this->port_); } } /** * Write to the socket. * * @param string $buf The data to write */ public function write($buf) { $null = null; $write = array($this->handle_); // keep writing until all the data has been written while (TStringFuncFactory::create()->strlen($buf) > 0) { // wait for stream to become available for writing $writable = @stream_select( $null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_ ); if ($writable > 0) { // write buffer to stream $written = fwrite($this->handle_, $buf); $closed_socket = $written === 0 && feof($this->handle_); if ($written === -1 || $written === false || $closed_socket) { throw new TTransportException( 'TSocket: Could not write ' . TStringFuncFactory::create()->strlen($buf) . ' bytes ' . $this->host_ . ':' . $this->port_ ); } // determine how much of the buffer is left to write $buf = TStringFuncFactory::create()->substr($buf, $written); } elseif ($writable === 0) { throw new TTransportException( 'TSocket: timed out writing ' . TStringFuncFactory::create()->strlen($buf) . ' bytes from ' . $this->host_ . ':' . $this->port_ ); } else { throw new TTransportException( 'TSocket: Could not write ' . TStringFuncFactory::create()->strlen($buf) . ' bytes ' . $this->host_ . ':' . $this->port_ ); } } } /** * Flush output to the socket. * * Since read(), readAll() and write() operate on the sockets directly, * this is a no-op * * If you wish to have flushable buffering behaviour, wrap this TSocket * in a TBufferedTransport. */ public function flush() { // no-op } } thrift-0.23.0/lib/php/lib/Transport/TSocketPool.php0000664000175000017500000002301215165535636022411 0ustar00buildbuild00000000000000 $val) { $ports[$key] = $port; } } foreach ($hosts as $key => $host) { $this->servers_ [] = array( 'host' => $host, 'port' => $ports[$key] ); } $this->useApcuCache = function_exists('apcu_fetch'); } /** * Add a server to the pool * * This function does not prevent you from adding a duplicate server entry. * * @param string $host hostname or IP * @param int $port port */ public function addServer($host, $port) { $this->servers_[] = array('host' => $host, 'port' => $port); } /** * Sets how many time to keep retrying a host in the connect function. * * @param int $numRetries */ public function setNumRetries($numRetries) { $this->numRetries_ = $numRetries; } /** * Sets how long to wait until retrying a host if it was marked down * * @param int $numRetries */ public function setRetryInterval($retryInterval) { $this->retryInterval_ = $retryInterval; } /** * Sets how many time to keep retrying a host before marking it as down. * * @param int $numRetries */ public function setMaxConsecutiveFailures($maxConsecutiveFailures) { $this->maxConsecutiveFailures_ = $maxConsecutiveFailures; } /** * Turns randomization in connect order on or off. * * @param bool $randomize */ public function setRandomize($randomize) { $this->randomize_ = $randomize; } /** * Whether to always try the last server. * * @param bool $alwaysTryLast */ public function setAlwaysTryLast($alwaysTryLast) { $this->alwaysTryLast_ = $alwaysTryLast; } /** * Connects the socket by iterating through all the servers in the pool * and trying to find one that works. */ public function open() { // Check if we want order randomization if ($this->randomize_) { shuffle($this->servers_); } // Count servers to identify the "last" one $numServers = count($this->servers_); for ($i = 0; $i < $numServers; ++$i) { // This extracts the $host and $port variables extract($this->servers_[$i]); // Check APCu cache for a record of this server being down $failtimeKey = 'thrift_failtime:' . $host . ':' . $port . '~'; // Cache miss? Assume it's OK $lastFailtime = $this->apcuFetch($failtimeKey); if ($lastFailtime === false) { $lastFailtime = 0; } $retryIntervalPassed = false; // Cache hit...make sure enough the retry interval has elapsed if ($lastFailtime > 0) { $elapsed = time() - $lastFailtime; if ($elapsed > $this->retryInterval_) { $retryIntervalPassed = true; if ($this->debug_) { call_user_func( $this->debugHandler_, 'TSocketPool: retryInterval ' . '(' . $this->retryInterval_ . ') ' . 'has passed for host ' . $host . ':' . $port ); } } } // Only connect if not in the middle of a fail interval, OR if this // is the LAST server we are trying, just hammer away on it $isLastServer = false; if ($this->alwaysTryLast_) { $isLastServer = ($i == ($numServers - 1)); } if (($lastFailtime === 0) || ($isLastServer) || ($lastFailtime > 0 && $retryIntervalPassed)) { // Set underlying TSocket params to this one $this->host_ = $host; $this->port_ = $port; // Try up to numRetries_ connections per server for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) { try { // Use the underlying TSocket open function parent::open(); // Only clear the failure counts if required to do so if ($lastFailtime > 0) { $this->apcuStore($failtimeKey, 0); } // Successful connection, return now return; } catch (TException $tx) { // Connection failed } } // Mark failure of this host in the cache $consecfailsKey = 'thrift_consecfails:' . $host . ':' . $port . '~'; // Ignore cache misses $consecfails = $this->apcuFetch($consecfailsKey); if ($consecfails === false) { $consecfails = 0; } // Increment by one $consecfails++; // Log and cache this failure if ($consecfails >= $this->maxConsecutiveFailures_) { if ($this->debug_) { call_user_func( $this->debugHandler_, 'TSocketPool: marking ' . $host . ':' . $port . ' as down for ' . $this->retryInterval_ . ' secs ' . 'after ' . $consecfails . ' failed attempts.' ); } // Store the failure time $this->apcuStore($failtimeKey, time()); // Clear the count of consecutive failures $this->apcuStore($consecfailsKey, 0); } else { $this->apcuStore($consecfailsKey, $consecfails); } } } // Oh no; we failed them all. The system is totally ill! $error = 'TSocketPool: All hosts in pool are down. '; $hosts = array(); foreach ($this->servers_ as $server) { $hosts [] = $server['host'] . ':' . $server['port']; } $hostlist = implode(',', $hosts); $error .= '(' . $hostlist . ')'; if ($this->debug_) { call_user_func($this->debugHandler_, $error); } 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; } } thrift-0.23.0/lib/php/lib/Transport/TBufferedTransport.php0000664000175000017500000001273115165535636023774 0ustar00buildbuild00000000000000transport_ = $transport; $this->rBufSize_ = $rBufSize; $this->wBufSize_ = $wBufSize; } public function isOpen() { return $this->transport_->isOpen(); } /** * @inheritdoc * * @throws TTransportException */ public function open() { $this->transport_->open(); } public function close() { $this->transport_->close(); } public function putBack($data) { if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { $this->rBuf_ = $data; } else { $this->rBuf_ = ($data . $this->rBuf_); } } /** * The reason that we customize readAll here is that the majority of PHP * streams are already internally buffered by PHP. The socket stream, for * example, buffers internally and blocks if you call read with $len greater * than the amount of data available, unlike recv() in C. * * Therefore, use the readAll method of the wrapped transport inside * the buffered readAll. * * @throws TTransportException */ public function readAll($len) { $have = TStringFuncFactory::create()->strlen($this->rBuf_); if ($have == 0) { $data = $this->transport_->readAll($len); } elseif ($have < $len) { $data = $this->rBuf_; $this->rBuf_ = ''; $data .= $this->transport_->readAll($len - $have); } elseif ($have == $len) { $data = $this->rBuf_; $this->rBuf_ = ''; } elseif ($have > $len) { $data = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len); $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len); } return $data; } /** * @inheritdoc * * @param int $len * @return string * @throws TTransportException */ public function read($len) { if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { $this->rBuf_ = $this->transport_->read($this->rBufSize_); } if (TStringFuncFactory::create()->strlen($this->rBuf_) <= $len) { $ret = $this->rBuf_; $this->rBuf_ = ''; return $ret; } $ret = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len); $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len); return $ret; } /** * @inheritdoc * * @param string $buf * @throws TTransportException */ public function write($buf) { $this->wBuf_ .= $buf; if (TStringFuncFactory::create()->strlen($this->wBuf_) >= $this->wBufSize_) { $out = $this->wBuf_; // Note that we clear the internal wBuf_ prior to the underlying write // to ensure we're in a sane state (i.e. internal buffer cleaned) // if the underlying write throws up an exception $this->wBuf_ = ''; $this->transport_->write($out); } } /** * @inheritdoc * * @throws TTransportException */ public function flush() { if (TStringFuncFactory::create()->strlen($this->wBuf_) > 0) { $out = $this->wBuf_; // Note that we clear the internal wBuf_ prior to the underlying write // to ensure we're in a sane state (i.e. internal buffer cleaned) // if the underlying write throws up an exception $this->wBuf_ = ''; $this->transport_->write($out); } $this->transport_->flush(); } } thrift-0.23.0/lib/php/lib/Transport/TSSLSocket.php0000664000175000017500000000723115165535636022146 0ustar00buildbuild00000000000000host_ = $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'; } /** * Creates a host name with SSL transport protocol * if no transport protocol already specified in * the host name. * * @param string $host Host to listen on * @return string $host Host name with transport protocol */ private function getSSLHost($host) { $transport_protocol_loc = strpos($host, "://"); if ($transport_protocol_loc === false) { $host = 'ssl://' . $host; } return $host; } /** * Connects the socket. */ public function open() { if ($this->isOpen()) { throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN); } $host = parse_url($this->host_, PHP_URL_HOST); if (empty($host)) { throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN); } if ($this->port_ <= 0) { throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN); } $this->handle_ = @stream_socket_client( $this->host_ . ':' . $this->port_, $errno, $errstr, $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), STREAM_CLIENT_CONNECT, $this->context_ ); // Connect failed? if ($this->handle_ === false) { $error = 'TSocket: Could not connect to ' . $this->host_ . ':' . $this->port_ . ' (' . $errstr . ' [' . $errno . '])'; if ($this->debug_) { call_user_func($this->debugHandler_, $error); } throw new TException($error); } } } thrift-0.23.0/lib/php/lib/Transport/TPhpStream.php0000664000175000017500000000651015165535636022236 0ustar00buildbuild00000000000000read_ = $mode & self::MODE_R; $this->write_ = $mode & self::MODE_W; } public function open() { if ($this->read_) { $this->inStream_ = @fopen($this->inStreamName(), 'r'); if (!is_resource($this->inStream_)) { throw new TException('TPhpStream: Could not open php://input'); } } if ($this->write_) { $this->outStream_ = @fopen('php://output', 'w'); if (!is_resource($this->outStream_)) { throw new TException('TPhpStream: Could not open php://output'); } } } public function close() { if ($this->read_) { @fclose($this->inStream_); $this->inStream_ = null; } if ($this->write_) { @fclose($this->outStream_); $this->outStream_ = null; } } public function isOpen() { return (!$this->read_ || is_resource($this->inStream_)) && (!$this->write_ || is_resource($this->outStream_)); } public function read($len) { $data = @fread($this->inStream_, $len); if ($data === false || $data === '') { throw new TException('TPhpStream: Could not read ' . $len . ' bytes'); } return $data; } public function write($buf) { while (TStringFuncFactory::create()->strlen($buf) > 0) { $got = @fwrite($this->outStream_, $buf); if ($got === 0 || $got === false) { throw new TException( 'TPhpStream: Could not write ' . TStringFuncFactory::create()->strlen($buf) . ' bytes' ); } $buf = TStringFuncFactory::create()->substr($buf, $got); } } public function flush() { @fflush($this->outStream_); } private function inStreamName() { if (php_sapi_name() == 'cli') { return 'php://stdin'; } return 'php://input'; } } thrift-0.23.0/lib/php/lib/Transport/TMemoryBuffer.php0000664000175000017500000000511715165535636022737 0ustar00buildbuild00000000000000buf_ = $buf; } public function isOpen() { return true; } public function open() { } public function close() { } public function write($buf) { $this->buf_ .= $buf; } public function read($len) { $bufLength = TStringFuncFactory::create()->strlen($this->buf_); if ($bufLength === 0) { throw new TTransportException( 'TMemoryBuffer: Could not read ' . $len . ' bytes from buffer.', TTransportException::UNKNOWN ); } if ($bufLength <= $len) { $ret = $this->buf_; $this->buf_ = ''; return $ret; } $ret = TStringFuncFactory::create()->substr($this->buf_, 0, $len); $this->buf_ = TStringFuncFactory::create()->substr($this->buf_, $len); return $ret; } public function getBuffer() { return $this->buf_; } public function available() { return TStringFuncFactory::create()->strlen($this->buf_); } public function putBack($data) { $this->buf_ = $data . $this->buf_; } } thrift-0.23.0/lib/php/lib/Transport/THttpClient.php0000664000175000017500000001463115165535636022414 0ustar00buildbuild00000000000000strlen($uri) > 0) && ($uri[0] != '/')) { $uri = '/' . $uri; } $this->scheme_ = $scheme; $this->host_ = $host; $this->port_ = $port; $this->uri_ = $uri; $this->buf_ = ''; $this->handle_ = null; $this->timeout_ = null; $this->headers_ = array(); $this->context_ = $context; } /** * Set read timeout * * @param float $timeout */ public function setTimeoutSecs($timeout) { $this->timeout_ = $timeout; } /** * Whether this transport is open. * * @return boolean true if open */ public function isOpen() { return true; } /** * Open the transport for reading/writing * * @throws TTransportException if cannot open */ public function open() { } /** * Close the transport. */ public function close() { if ($this->handle_) { @fclose($this->handle_); $this->handle_ = null; } } /** * Read some data into the array. * * @param int $len How much to read * @return string The data that has been read * @throws TTransportException if cannot read any more data */ public function read($len) { $data = @fread($this->handle_, $len); if ($data === false || $data === '') { $md = stream_get_meta_data($this->handle_); if ($md['timed_out']) { throw new TTransportException( 'THttpClient: timed out reading ' . $len . ' bytes from ' . $this->host_ . ':' . $this->port_ . $this->uri_, TTransportException::TIMED_OUT ); } else { throw new TTransportException( 'THttpClient: Could not read ' . $len . ' bytes from ' . $this->host_ . ':' . $this->port_ . $this->uri_, TTransportException::UNKNOWN ); } } return $data; } /** * Writes some data into the pending buffer * * @param string $buf The data to write * @throws TTransportException if writing fails */ public function write($buf) { $this->buf_ .= $buf; } /** * Opens and sends the actual request over the HTTP connection * * @throws TTransportException if a writing error occurs */ public function flush() { // God, PHP really has some esoteric ways of doing simple things. $host = $this->host_ . ($this->port_ != 80 ? ':' . $this->port_ : ''); $headers = array(); $defaultHeaders = array( 'Host' => $host, 'Accept' => 'application/x-thrift', 'User-Agent' => 'PHP/THttpClient', 'Content-Type' => 'application/x-thrift', 'Content-Length' => TStringFuncFactory::create()->strlen($this->buf_) ); foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) { $headers[] = "$key: $value"; } $options = $this->context_; $baseHttpOptions = isset($options["http"]) ? $options["http"] : array(); $httpOptions = $baseHttpOptions + array( 'method' => 'POST', 'header' => implode("\r\n", $headers), 'max_redirects' => 1, 'content' => $this->buf_ ); if ($this->timeout_ > 0) { $httpOptions['timeout'] = $this->timeout_; } $this->buf_ = ''; $options["http"] = $httpOptions; $contextid = stream_context_create($options); $this->handle_ = @fopen( $this->scheme_ . '://' . $host . $this->uri_, 'r', false, $contextid ); // Connect failed? if ($this->handle_ === false) { $this->handle_ = null; $error = 'THttpClient: Could not connect to ' . $host . $this->uri_; throw new TTransportException($error, TTransportException::NOT_OPEN); } } public function addHeaders($headers) { $this->headers_ = array_merge($this->headers_, $headers); } } thrift-0.23.0/lib/php/lib/Transport/TCurlClient.php0000664000175000017500000002101415167543515022370 0ustar00buildbuild00000000000000strlen($uri) > 0) && ($uri[0] != '/')) { $uri = '/' . $uri; } $this->scheme_ = $scheme; $this->host_ = $host; $this->port_ = $port; $this->uri_ = $uri; $this->request_ = ''; $this->response_ = null; $this->timeout_ = null; $this->connectionTimeout_ = null; $this->headers_ = array(); } /** * Set read timeout * * @param float $timeout */ public function setTimeoutSecs($timeout) { $this->timeout_ = $timeout; } /** * Set connection timeout * * @param float $connectionTimeout */ public function setConnectionTimeoutSecs($connectionTimeout) { $this->connectionTimeout_ = $connectionTimeout; } /** * Whether this transport is open. * * @return boolean true if open */ public function isOpen() { return true; } /** * Open the transport for reading/writing * * @throws TTransportException if cannot open */ public function open() { } /** * Close the transport. */ public function close() { $this->request_ = ''; $this->response_ = null; } /** * Read some data into the array. * * @param int $len How much to read * @return string The data that has been read * @throws TTransportException if cannot read any more data */ public function read($len) { if ($len >= strlen($this->response_)) { return $this->response_; } else { $ret = substr($this->response_, 0, $len); $this->response_ = substr($this->response_, $len); return $ret; } } /** * Guarantees that the full amount of data is read. Since TCurlClient gets entire payload at * once, parent readAll cannot be used. * * @return string The data, of exact length * @throws TTransportException if cannot read data */ public function readAll($len) { $data = $this->read($len); if (TStringFuncFactory::create()->strlen($data) !== $len) { throw new TTransportException('TCurlClient could not read '.$len.' bytes'); } return $data; } /** * Writes some data into the pending buffer * * @param string $buf The data to write * @throws TTransportException if writing fails */ public function write($buf) { $this->request_ .= $buf; } /** * Opens and sends the actual request over the HTTP connection * * @throws TTransportException if a writing error occurs */ public function flush() { if (!self::$curlHandle) { register_shutdown_function(array('Thrift\\Transport\\TCurlClient', 'closeCurlHandle')); self::$curlHandle = curl_init(); curl_setopt(self::$curlHandle, CURLOPT_RETURNTRANSFER, true); curl_setopt(self::$curlHandle, CURLOPT_USERAGENT, 'PHP/TCurlClient'); curl_setopt(self::$curlHandle, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt(self::$curlHandle, CURLOPT_FOLLOWLOCATION, true); curl_setopt(self::$curlHandle, CURLOPT_MAXREDIRS, 1); } // God, PHP really has some esoteric ways of doing simple things. $host = $this->host_ . ($this->port_ != 80 ? ':' . $this->port_ : ''); $fullUrl = $this->scheme_ . "://" . $host . $this->uri_; $headers = array(); $defaultHeaders = array( 'Accept' => 'application/x-thrift', 'Content-Type' => 'application/x-thrift', 'Content-Length' => TStringFuncFactory::create()->strlen($this->request_) ); foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) { $headers[] = "$key: $value"; } curl_setopt(self::$curlHandle, CURLOPT_HTTPHEADER, $headers); if ($this->timeout_ > 0) { if ($this->timeout_ < 1.0) { // Timestamps smaller than 1 second are ignored when CURLOPT_TIMEOUT is used curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT_MS, 1000 * $this->timeout_); } else { curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_); } } if ($this->connectionTimeout_ > 0) { if ($this->connectionTimeout_ < 1.0) { // Timestamps smaller than 1 second are ignored when CURLOPT_CONNECTTIMEOUT is used curl_setopt(self::$curlHandle, CURLOPT_CONNECTTIMEOUT_MS, 1000 * $this->connectionTimeout_); } else { curl_setopt(self::$curlHandle, CURLOPT_CONNECTTIMEOUT, $this->connectionTimeout_); } } curl_setopt(self::$curlHandle, CURLOPT_POSTFIELDS, $this->request_); $this->request_ = ''; curl_setopt(self::$curlHandle, CURLOPT_URL, $fullUrl); $this->response_ = curl_exec(self::$curlHandle); $responseError = curl_error(self::$curlHandle); $code = curl_getinfo(self::$curlHandle, CURLINFO_HTTP_CODE); // Handle non 200 status code / connect failure if ($this->response_ === false || $code !== 200) { curl_close(self::$curlHandle); self::$curlHandle = null; $this->response_ = null; $error = 'TCurlClient: Could not connect to ' . $fullUrl; if ($responseError) { $error .= ', ' . $responseError; } if ($code) { $error .= ', HTTP status code: ' . $code; } throw new TTransportException($error, TTransportException::UNKNOWN); } } public static function closeCurlHandle() { try { if (self::$curlHandle) { // This function has no effect. Prior to PHP 8.0.0, // this function was used to close the resource. curl_close(self::$curlHandle); 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()); } } public function addHeaders($headers) { $this->headers_ = array_merge($this->headers_, $headers); } } thrift-0.23.0/lib/php/lib/Transport/TFramedTransport.php0000664000175000017500000001140615165535636023446 0ustar00buildbuild00000000000000transport_ = $transport; $this->read_ = $read; $this->write_ = $write; } public function isOpen() { return $this->transport_->isOpen(); } public function open() { $this->transport_->open(); } public function close() { $this->transport_->close(); } /** * Reads from the buffer. When more data is required reads another entire * chunk and serves future reads out of that. * * @param int $len How much data */ public function read($len) { if (!$this->read_) { return $this->transport_->read($len); } if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { $this->readFrame(); } // Just return full buff if ($len >= TStringFuncFactory::create()->strlen($this->rBuf_)) { $out = $this->rBuf_; $this->rBuf_ = null; return $out; } // Return TStringFuncFactory::create()->substr $out = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len); $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len); return $out; } /** * Put previously read data back into the buffer * * @param string $data data to return */ public function putBack($data) { if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { $this->rBuf_ = $data; } else { $this->rBuf_ = ($data . $this->rBuf_); } } /** * Reads a chunk of data into the internal read buffer. */ private function readFrame() { $buf = $this->transport_->readAll(4); $val = unpack('N', $buf); $sz = $val[1]; $this->rBuf_ = $this->transport_->readAll($sz); } /** * Writes some data to the pending output buffer. * * @param string $buf The data * @param int $len Limit of bytes to write */ public function write($buf, $len = null) { if (!$this->write_) { return $this->transport_->write($buf, $len); } if ($len !== null && $len < TStringFuncFactory::create()->strlen($buf)) { $buf = TStringFuncFactory::create()->substr($buf, 0, $len); } $this->wBuf_ .= $buf; } /** * Writes the output buffer to the stream in the format of a 4-byte length * followed by the actual data. */ public function flush() { if (!$this->write_ || TStringFuncFactory::create()->strlen($this->wBuf_) == 0) { return $this->transport_->flush(); } $out = pack('N', TStringFuncFactory::create()->strlen($this->wBuf_)); $out .= $this->wBuf_; // Note that we clear the internal wBuf_ prior to the underlying write // to ensure we're in a sane state (i.e. internal buffer cleaned) // if the underlying write throws up an exception $this->wBuf_ = ''; $this->transport_->write($out); $this->transport_->flush(); } } thrift-0.23.0/lib/php/lib/Transport/TTransport.php0000664000175000017500000000474315165535636022335 0ustar00buildbuild00000000000000read($len); $data = ''; $got = 0; while (($got = TStringFuncFactory::create()->strlen($data)) < $len) { $data .= $this->read($len - $got); } return $data; } /** * Writes the given data out. * * @param string $buf The data to write * @throws TTransportException if writing fails */ abstract public function write($buf); /** * Flushes any pending data out of a buffer * * @throws TTransportException if a writing error occurs */ public function flush() { } } thrift-0.23.0/lib/php/lib/StoredMessageProtocol.php0000664000175000017500000000324415165535636022503 0ustar00buildbuild00000000000000fname_ = $fname; $this->mtype_ = $mtype; $this->rseqid_ = $rseqid; } public function readMessageBegin(&$name, &$type, &$seqid) { $name = $this->fname_; $type = $this->mtype_; $seqid = $this->rseqid_; } } thrift-0.23.0/lib/php/lib/Server/0000775000175000017500000000000015165535636016746 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Server/TServerSocket.php0000664000175000017500000000537515165535636022234 0ustar00buildbuild00000000000000host_ = $host; $this->port_ = $port; } /** * Sets the accept timeout * * @param int $acceptTimeout * @return void */ public function setAcceptTimeout($acceptTimeout) { $this->acceptTimeout_ = $acceptTimeout; } /** * Opens a new socket server handle * * @return void */ public function listen() { $this->listener_ = stream_socket_server('tcp://' . $this->host_ . ':' . $this->port_); } /** * Closes the socket server handle * * @return void */ public function close() { @fclose($this->listener_); $this->listener_ = null; } /** * Implementation of accept. If not client is accepted in the given time * * @return TSocket */ protected function acceptImpl() { $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0); if (!$handle) { return null; } $socket = new TSocket(); $socket->setHandle($handle); return $socket; } } thrift-0.23.0/lib/php/lib/Server/TForkingServer.php0000664000175000017500000000571015165535636022374 0ustar00buildbuild00000000000000transport_->listen(); while (!$this->stop_) { try { $transport = $this->transport_->accept(); if ($transport != null) { $pid = pcntl_fork(); if ($pid > 0) { $this->handleParent($transport, $pid); } elseif ($pid === 0) { $this->handleChild($transport); } else { throw new TException('Failed to fork'); } } } catch (TTransportException $e) { } $this->collectChildren(); } } /** * Code run by the parent * * @param TTransport $transport * @param int $pid * @return void */ private function handleParent(TTransport $transport, $pid) { $this->children_[$pid] = $transport; } /** * Code run by the child. * * @param TTransport $transport * @return void */ private function handleChild(TTransport $transport) { try { $inputTransport = $this->inputTransportFactory_->getTransport($transport); $outputTransport = $this->outputTransportFactory_->getTransport($transport); $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport); $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport); while ($this->processor_->process($inputProtocol, $outputProtocol)) { } @$transport->close(); } catch (TTransportException $e) { } exit(0); } /** * Collects any children we may have * * @return void */ private function collectChildren() { foreach ($this->children_ as $pid => $transport) { if (pcntl_waitpid($pid, $status, WNOHANG) > 0) { unset($this->children_[$pid]); if ($transport) { @$transport->close(); } } } } /** * Stops the server running. Kills the transport * and then stops the main serving loop * * @return void */ public function stop() { $this->transport_->close(); $this->stop_ = true; } } thrift-0.23.0/lib/php/lib/Server/TSSLServerSocket.php0000664000175000017500000000517715165535636022616 0ustar00buildbuild00000000000000getSSLHost($host); parent::__construct($ssl_host, $port); // Initialize a stream context if not provided if ($context === null) { $context = stream_context_create(); } $this->context_ = $context; } public function getSSLHost($host) { $transport_protocol_loc = strpos($host, "://"); if ($transport_protocol_loc === false) { $host = 'ssl://' . $host; } return $host; } /** * Opens a new socket server handle * * @return void */ public function listen() { $this->listener_ = @stream_socket_server( $this->host_ . ':' . $this->port_, $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $this->context_ ); } /** * Implementation of accept. If not client is accepted in the given time * * @return TSocket */ protected function acceptImpl() { $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0); if (!$handle) { return null; } $socket = new TSSLSocket(); $socket->setHandle($handle); return $socket; } } thrift-0.23.0/lib/php/lib/Server/TServer.php0000664000175000017500000000456315165535636021061 0ustar00buildbuild00000000000000processor_ = $processor; $this->transport_ = $transport; $this->inputTransportFactory_ = $inputTransportFactory; $this->outputTransportFactory_ = $outputTransportFactory; $this->inputProtocolFactory_ = $inputProtocolFactory; $this->outputProtocolFactory_ = $outputProtocolFactory; } /** * Serves the server. This should never return * unless a problem permits it to do so or it * is interrupted intentionally * * @abstract * @return void */ abstract public function serve(); /** * Stops the server serving * * @abstract * @return void */ abstract public function stop(); } thrift-0.23.0/lib/php/lib/Server/TServerTransport.php0000664000175000017500000000203215165535636022763 0ustar00buildbuild00000000000000acceptImpl(); if ($transport == null) { throw new TTransportException("accept() may not return NULL"); } return $transport; } } thrift-0.23.0/lib/php/lib/Server/TSimpleServer.php0000664000175000017500000000301515165535636022222 0ustar00buildbuild00000000000000transport_->listen(); while (!$this->stop_) { try { $transport = $this->transport_->accept(); if ($transport != null) { $inputTransport = $this->inputTransportFactory_->getTransport($transport); $outputTransport = $this->outputTransportFactory_->getTransport($transport); $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport); $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport); while ($this->processor_->process($inputProtocol, $outputProtocol)) { } } } catch (TTransportException $e) { } } } /** * Stops the server running. Kills the transport * and then stops the main serving loop * * @return void */ public function stop() { $this->transport_->close(); $this->stop_ = true; } } thrift-0.23.0/lib/php/lib/Protocol/0000775000175000017500000000000015170007142017257 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Protocol/TCompactProtocol.php0000664000175000017500000005030315167543515023244 0ustar00buildbuild00000000000000 TCompactProtocol::COMPACT_STOP, TType::BOOL => TCompactProtocol::COMPACT_TRUE, // used for collection TType::BYTE => TCompactProtocol::COMPACT_BYTE, TType::I16 => TCompactProtocol::COMPACT_I16, TType::I32 => TCompactProtocol::COMPACT_I32, TType::I64 => TCompactProtocol::COMPACT_I64, TType::DOUBLE => TCompactProtocol::COMPACT_DOUBLE, TType::STRING => TCompactProtocol::COMPACT_BINARY, TType::STRUCT => TCompactProtocol::COMPACT_STRUCT, TType::LST => TCompactProtocol::COMPACT_LIST, TType::SET => TCompactProtocol::COMPACT_SET, TType::MAP => TCompactProtocol::COMPACT_MAP, TType::UUID => TCompactProtocol::COMPACT_UUID, ); protected static $ttypes = array( TCompactProtocol::COMPACT_STOP => TType::STOP, TCompactProtocol::COMPACT_TRUE => TType::BOOL, // used for collection TCompactProtocol::COMPACT_FALSE => TType::BOOL, TCompactProtocol::COMPACT_BYTE => TType::BYTE, TCompactProtocol::COMPACT_I16 => TType::I16, TCompactProtocol::COMPACT_I32 => TType::I32, TCompactProtocol::COMPACT_I64 => TType::I64, TCompactProtocol::COMPACT_DOUBLE => TType::DOUBLE, TCompactProtocol::COMPACT_BINARY => TType::STRING, TCompactProtocol::COMPACT_STRUCT => TType::STRUCT, TCompactProtocol::COMPACT_LIST => TType::LST, TCompactProtocol::COMPACT_SET => TType::SET, TCompactProtocol::COMPACT_MAP => TType::MAP, TCompactProtocol::COMPACT_UUID => TType::UUID, ); protected $state = TCompactProtocol::STATE_CLEAR; protected $lastFid = 0; protected $boolFid = null; protected $boolValue = null; protected $structs = array(); protected $containers = array(); // Some varint / zigzag helper methods public function toZigZag($n, $bits) { return ($n << 1) ^ ($n >> ($bits - 1)); } public function fromZigZag($n) { return ($n >> 1) ^ -($n & 1); } public function getVarint($data) { $out = ""; while (true) { if (($data & ~0x7f) === 0) { $out .= chr($data); break; } else { $out .= chr(($data & 0xff) | 0x80); $data = $data >> 7; } } return $out; } public function writeVarint($data) { $out = $this->getVarint($data); $result = TStringFuncFactory::create()->strlen($out); $this->trans_->write($out, $result); return $result; } public function readVarint(&$result) { $idx = 0; $shift = 0; $result = 0; while (true) { $x = $this->trans_->readAll(1); $arr = unpack('C', $x); $byte = $arr[1]; $idx += 1; $result |= ($byte & 0x7f) << $shift; if (($byte >> 7) === 0) { return $idx; } $shift += 7; } #unreachable statement return $idx; } public function __construct($trans) { parent::__construct($trans); } public function writeMessageBegin($name, $type, $seqid) { $written = $this->writeUByte(TCompactProtocol::PROTOCOL_ID) + $this->writeUByte(TCompactProtocol::VERSION | ($type << TCompactProtocol::TYPE_SHIFT_AMOUNT)) + $this->writeVarint($seqid) + $this->writeString($name); $this->state = TCompactProtocol::STATE_VALUE_WRITE; return $written; } public function writeMessageEnd() { $this->state = TCompactProtocol::STATE_CLEAR; return 0; } public function writeStructBegin($name) { $this->structs[] = array($this->state, $this->lastFid); $this->state = TCompactProtocol::STATE_FIELD_WRITE; $this->lastFid = 0; return 0; } public function writeStructEnd() { $old_values = array_pop($this->structs); $this->state = $old_values[0]; $this->lastFid = $old_values[1]; return 0; } public function writeFieldStop() { return $this->writeByte(0); } public function writeFieldHeader($type, $fid) { $written = 0; $delta = $fid - $this->lastFid; if (0 < $delta && $delta <= 15) { $written = $this->writeUByte(($delta << 4) | $type); } else { $written = $this->writeByte($type) + $this->writeI16($fid); } $this->lastFid = $fid; return $written; } public function writeFieldBegin($field_name, $field_type, $field_id) { if ($field_type == TTYPE::BOOL) { $this->state = TCompactProtocol::STATE_BOOL_WRITE; $this->boolFid = $field_id; return 0; } else { $this->state = TCompactProtocol::STATE_VALUE_WRITE; return $this->writeFieldHeader(self::$ctypes[$field_type], $field_id); } } public function writeFieldEnd() { $this->state = TCompactProtocol::STATE_FIELD_WRITE; return 0; } public function writeCollectionBegin($etype, $size) { $written = 0; if ($size <= 14) { $written = $this->writeUByte($size << 4 | self::$ctypes[$etype]); } else { $written = $this->writeUByte(0xf0 | self::$ctypes[$etype]) + $this->writeVarint($size); } $this->containers[] = $this->state; $this->state = TCompactProtocol::STATE_CONTAINER_WRITE; return $written; } public function writeMapBegin($key_type, $val_type, $size) { $written = 0; if ($size == 0) { $written = $this->writeByte(0); } else { $written = $this->writeVarint($size) + $this->writeUByte(self::$ctypes[$key_type] << 4 | self::$ctypes[$val_type]); } $this->containers[] = $this->state; return $written; } public function writeCollectionEnd() { $this->state = array_pop($this->containers); return 0; } public function writeMapEnd() { return $this->writeCollectionEnd(); } public function writeListBegin($elem_type, $size) { return $this->writeCollectionBegin($elem_type, $size); } public function writeListEnd() { return $this->writeCollectionEnd(); } public function writeSetBegin($elem_type, $size) { return $this->writeCollectionBegin($elem_type, $size); } public function writeSetEnd() { return $this->writeCollectionEnd(); } public function writeBool($value) { if ($this->state == TCompactProtocol::STATE_BOOL_WRITE) { $ctype = TCompactProtocol::COMPACT_FALSE; if ($value) { $ctype = TCompactProtocol::COMPACT_TRUE; } return $this->writeFieldHeader($ctype, $this->boolFid); } elseif ($this->state == TCompactProtocol::STATE_CONTAINER_WRITE) { return $this->writeByte($value ? 1 : 0); } else { throw new TProtocolException('Invalid state in compact protocol'); } } public function writeByte($value) { $data = pack('c', $value); $this->trans_->write($data, 1); return 1; } public function writeUByte($byte) { $this->trans_->write(pack('C', $byte), 1); return 1; } public function writeI16($value) { $thing = $this->toZigZag($value, 16); return $this->writeVarint($thing); } public function writeI32($value) { $thing = $this->toZigZag($value, 32); return $this->writeVarint($thing); } public function writeDouble($value) { $data = pack('d', $value); $this->trans_->write($data, 8); return 8; } public function writeString($value) { $len = TStringFuncFactory::create()->strlen($value); $result = $this->writeVarint($len); if ($len) { $this->trans_->write($value, $len); } return $result + $len; } public function writeUuid($uuid) { $data = hex2bin(str_replace('-', '', $uuid)); $this->trans_->write($data, 16); return 16; } public function readFieldBegin(&$name, &$field_type, &$field_id) { $result = $this->readUByte($compact_type_and_delta); $compact_type = $compact_type_and_delta & 0x0f; if ($compact_type == TType::STOP) { $field_type = $compact_type; $field_id = 0; return $result; } $delta = $compact_type_and_delta >> 4; if ($delta == 0) { $result += $this->readI16($field_id); } else { $field_id = $this->lastFid + $delta; } $this->lastFid = $field_id; $field_type = $this->getTType($compact_type); if ($compact_type == TCompactProtocol::COMPACT_TRUE) { $this->state = TCompactProtocol::STATE_BOOL_READ; $this->boolValue = true; } elseif ($compact_type == TCompactProtocol::COMPACT_FALSE) { $this->state = TCompactProtocol::STATE_BOOL_READ; $this->boolValue = false; } else { $this->state = TCompactProtocol::STATE_VALUE_READ; } return $result; } public function readFieldEnd() { $this->state = TCompactProtocol::STATE_FIELD_READ; return 0; } public function readUByte(&$value) { $data = $this->trans_->readAll(1); $arr = unpack('C', $data); $value = $arr[1]; return 1; } public function readByte(&$value) { $data = $this->trans_->readAll(1); $arr = unpack('c', $data); $value = $arr[1]; return 1; } public function readZigZag(&$value) { $result = $this->readVarint($value); $value = $this->fromZigZag($value); return $result; } public function readMessageBegin(&$name, &$type, &$seqid) { $protoId = 0; $result = $this->readUByte($protoId); if ($protoId != TCompactProtocol::PROTOCOL_ID) { throw new TProtocolException('Bad protocol id in TCompact message'); } $verType = 0; $result += $this->readUByte($verType); $type = ($verType >> TCompactProtocol::TYPE_SHIFT_AMOUNT) & TCompactProtocol::TYPE_BITS; $version = $verType & TCompactProtocol::VERSION_MASK; if ($version != TCompactProtocol::VERSION) { throw new TProtocolException('Bad version in TCompact message'); } $result += $this->readVarint($seqid); $result += $this->readString($name); return $result; } public function readMessageEnd() { return 0; } public function readStructBegin(&$name) { $name = ''; // unused $this->structs[] = array($this->state, $this->lastFid); $this->state = TCompactProtocol::STATE_FIELD_READ; $this->lastFid = 0; return 0; } public function readStructEnd() { $last = array_pop($this->structs); $this->state = $last[0]; $this->lastFid = $last[1]; return 0; } public function readCollectionBegin(&$type, &$size) { $sizeType = 0; $result = $this->readUByte($sizeType); $size = $sizeType >> 4; $type = $this->getTType($sizeType); if ($size == 15) { $result += $this->readVarint($size); } $this->containers[] = $this->state; $this->state = TCompactProtocol::STATE_CONTAINER_READ; return $result; } public function readMapBegin(&$key_type, &$val_type, &$size) { $result = $this->readVarint($size); $types = 0; if ($size > 0) { $result += $this->readUByte($types); } $val_type = $this->getTType($types); $key_type = $this->getTType($types >> 4); $this->containers[] = $this->state; $this->state = TCompactProtocol::STATE_CONTAINER_READ; return $result; } public function readCollectionEnd() { $this->state = array_pop($this->containers); return 0; } public function readMapEnd() { return $this->readCollectionEnd(); } public function readListBegin(&$elem_type, &$size) { return $this->readCollectionBegin($elem_type, $size); } public function readListEnd() { return $this->readCollectionEnd(); } public function readSetBegin(&$elem_type, &$size) { return $this->readCollectionBegin($elem_type, $size); } public function readSetEnd() { return $this->readCollectionEnd(); } public function readBool(&$value) { if ($this->state == TCompactProtocol::STATE_BOOL_READ) { $value = $this->boolValue; return 0; } elseif ($this->state == TCompactProtocol::STATE_CONTAINER_READ) { return $this->readByte($value); } else { throw new TProtocolException('Invalid state in compact protocol'); } } public function readI16(&$value) { return $this->readZigZag($value); } public function readI32(&$value) { return $this->readZigZag($value); } public function readDouble(&$value) { $data = $this->trans_->readAll(8); $arr = unpack('d', $data); $value = $arr[1]; return 8; } public function readString(&$value) { $result = $this->readVarint($len); if ($len) { $value = $this->trans_->readAll($len); } else { $value = ''; } return $result + $len; } public function readUuid(&$value) { $data = $this->trans_->readAll(16); $hex = bin2hex($data); $value = substr($hex, 0, 8) . '-' . substr($hex, 8, 4) . '-' . substr($hex, 12, 4) . '-' . substr($hex, 16, 4) . '-' . substr($hex, 20, 12); return 16; } public function getTType($byte) { return self::$ttypes[$byte & 0x0f]; } // If we are on a 32bit architecture we have to explicitly deal with // 64-bit twos-complement arithmetic since PHP wants to treat all ints // as signed and any int over 2^31 - 1 as a float // Read and write I64 as two 32 bit numbers $hi and $lo public function readI64(&$value) { // Read varint from wire $hi = 0; $lo = 0; $idx = 0; $shift = 0; while (true) { $x = $this->trans_->readAll(1); $arr = unpack('C', $x); $byte = $arr[1]; $idx += 1; // Shift hi and lo together. if ($shift < 28) { $lo |= (($byte & 0x7f) << $shift); } elseif ($shift == 28) { $lo |= (($byte & 0x0f) << 28); $hi |= (($byte & 0x70) >> 4); } else { $hi |= (($byte & 0x7f) << ($shift - 32)); } if (($byte >> 7) === 0) { break; } $shift += 7; } // Now, unzig it. $xorer = 0; if ($lo & 1) { $xorer = 0xffffffff; } $lo = ($lo >> 1) & 0x7fffffff; $lo = $lo | (($hi & 1) << 31); $hi = ($hi >> 1) ^ $xorer; $lo = $lo ^ $xorer; // Now put $hi and $lo back together $isNeg = $hi < 0 || $hi & 0x80000000; // Check for a negative if ($isNeg) { $hi = ~$hi & (int)0xffffffff; $lo = ~$lo & (int)0xffffffff; if ($lo == (int)0xffffffff) { $hi++; $lo = 0; } else { $lo++; } } // Force 32bit words in excess of 2G to be positive - we deal with sign // explicitly below if ($hi & (int)0x80000000) { $hi &= (int)0x7fffffff; $hi += 0x80000000; } if ($lo & (int)0x80000000) { $lo &= (int)0x7fffffff; $lo += 0x80000000; } // Create as negative value first, since we can store -2^63 but not 2^63 $value = -$hi * 4294967296 - $lo; if (!$isNeg) { $value = -$value; } return $idx; } public function writeI64($value) { // If we are in an I32 range, use the easy method below. if (($value > 4294967296) || ($value < -4294967296)) { // Convert $value to $hi and $lo $neg = $value < 0; if ($neg) { $value *= -1; } $hi = (int)$value >> 32; $lo = (int)$value & 0xffffffff; if ($neg) { $hi = ~$hi; $lo = ~$lo; if (($lo & (int)0xffffffff) == (int)0xffffffff) { $lo = 0; $hi++; } else { $lo++; } } // Now do the zigging and zagging. $xorer = 0; if ($neg) { $xorer = 0xffffffff; } $lowbit = ($lo >> 31) & 1; $hi = ($hi << 1) | $lowbit; $lo = ($lo << 1); $lo = ($lo ^ $xorer) & 0xffffffff; $hi = ($hi ^ $xorer) & 0xffffffff; // now write out the varint, ensuring we shift both hi and lo $out = ""; while (true) { if (($lo & ~0x7f) === 0 && $hi === 0) { $out .= chr($lo); break; } else { $out .= chr(($lo & 0xff) | 0x80); $lo = $lo >> 7; $lo = $lo | ($hi << 25); $hi = $hi >> 7; // Right shift carries sign, but we don't want it to. $hi = $hi & (127 << 25); } } $ret = TStringFuncFactory::create()->strlen($out); $this->trans_->write($out, $ret); return $ret; } else { return $this->writeVarint($this->toZigZag($value, 64)); } } } thrift-0.23.0/lib/php/lib/Protocol/TBinaryProtocol.php0000664000175000017500000002607015167543515023106 0ustar00buildbuild00000000000000strictRead_ = $strictRead; $this->strictWrite_ = $strictWrite; } public function writeMessageBegin($name, $type, $seqid) { if ($this->strictWrite_) { $version = self::VERSION_1 | $type; return $this->writeI32($version) + $this->writeString($name) + $this->writeI32($seqid); } else { return $this->writeString($name) + $this->writeByte($type) + $this->writeI32($seqid); } } public function writeMessageEnd() { return 0; } public function writeStructBegin($name) { return 0; } public function writeStructEnd() { return 0; } public function writeFieldBegin($fieldName, $fieldType, $fieldId) { return $this->writeByte($fieldType) + $this->writeI16($fieldId); } public function writeFieldEnd() { return 0; } public function writeFieldStop() { return $this->writeByte(TType::STOP); } public function writeMapBegin($keyType, $valType, $size) { return $this->writeByte($keyType) + $this->writeByte($valType) + $this->writeI32($size); } public function writeMapEnd() { return 0; } public function writeListBegin($elemType, $size) { return $this->writeByte($elemType) + $this->writeI32($size); } public function writeListEnd() { return 0; } public function writeSetBegin($elemType, $size) { return $this->writeByte($elemType) + $this->writeI32($size); } public function writeSetEnd() { return 0; } public function writeBool($value) { $data = pack('c', $value ? 1 : 0); $this->trans_->write($data, 1); return 1; } public function writeByte($value) { $data = pack('c', $value); $this->trans_->write($data, 1); return 1; } public function writeI16($value) { $data = pack('n', $value); $this->trans_->write($data, 2); return 2; } public function writeI32($value) { $data = pack('N', $value); $this->trans_->write($data, 4); return 4; } public function writeI64($value) { // If we are on a 32bit architecture we have to explicitly deal with // 64-bit twos-complement arithmetic since PHP wants to treat all ints // as signed and any int over 2^31 - 1 as a float if (PHP_INT_SIZE == 4) { $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++; } } $data = pack('N2', $hi, $lo); } else { $hi = $value >> 32; $lo = $value & 0xFFFFFFFF; $data = pack('N2', $hi, $lo); } $this->trans_->write($data, 8); return 8; } public function writeDouble($value) { $data = pack('d', $value); $this->trans_->write(strrev($data), 8); return 8; } public function writeString($value) { $len = TStringFuncFactory::create()->strlen($value); $result = $this->writeI32($len); if ($len) { $this->trans_->write($value, $len); } return $result + $len; } public function writeUuid($uuid) { $data = hex2bin(str_replace('-', '', $uuid)); $this->trans_->write($data, 16); return 16; } public function readMessageBegin(&$name, &$type, &$seqid) { $result = $this->readI32($sz); if ($sz < 0) { $version = (int)($sz & self::VERSION_MASK); if ($version != (int)self::VERSION_1) { throw new TProtocolException('Bad version identifier: ' . $sz, TProtocolException::BAD_VERSION); } $type = $sz & 0x000000ff; $result += $this->readString($name) + $this->readI32($seqid); } else { if ($this->strictRead_) { throw new TProtocolException( 'No version identifier, old protocol client?', TProtocolException::BAD_VERSION ); } else { // Handle pre-versioned input $name = $this->trans_->readAll($sz); $result += $sz + $this->readByte($type) + $this->readI32($seqid); } } return $result; } public function readMessageEnd() { return 0; } public function readStructBegin(&$name) { $name = ''; return 0; } public function readStructEnd() { return 0; } public function readFieldBegin(&$name, &$fieldType, &$fieldId) { $result = $this->readByte($fieldType); if ($fieldType == TType::STOP) { $fieldId = 0; return $result; } $result += $this->readI16($fieldId); return $result; } public function readFieldEnd() { return 0; } public function readMapBegin(&$keyType, &$valType, &$size) { return $this->readByte($keyType) + $this->readByte($valType) + $this->readI32($size); } public function readMapEnd() { return 0; } public function readListBegin(&$elemType, &$size) { return $this->readByte($elemType) + $this->readI32($size); } public function readListEnd() { return 0; } public function readSetBegin(&$elemType, &$size) { return $this->readByte($elemType) + $this->readI32($size); } public function readSetEnd() { return 0; } public function readBool(&$value) { $data = $this->trans_->readAll(1); $arr = unpack('c', $data); $value = $arr[1] == 1; return 1; } public function readByte(&$value) { $data = $this->trans_->readAll(1); $arr = unpack('c', $data); $value = $arr[1]; return 1; } public function readI16(&$value) { $data = $this->trans_->readAll(2); $arr = unpack('n', $data); $value = $arr[1]; if ($value > 0x7fff) { $value = 0 - (($value - 1) ^ 0xffff); } return 2; } public function readI32(&$value) { $data = $this->trans_->readAll(4); $arr = unpack('N', $data); $value = $arr[1]; if ($value > 0x7fffffff) { $value = 0 - (($value - 1) ^ 0xffffffff); } return 4; } public function readI64(&$value) { $data = $this->trans_->readAll(8); $arr = unpack('N2', $data); // If we are on a 32bit architecture we have to explicitly deal with // 64-bit twos-complement arithmetic since PHP wants to treat all ints // as signed and any int over 2^31 - 1 as a float if (PHP_INT_SIZE == 4) { $hi = $arr[1]; $lo = $arr[2]; $isNeg = $hi < 0; // Check for a negative if ($isNeg) { $hi = ~$hi & (int)0xffffffff; $lo = ~$lo & (int)0xffffffff; if ($lo == (int)0xffffffff) { $hi++; $lo = 0; } else { $lo++; } } // Force 32bit words in excess of 2G to pe positive - we deal wigh sign // explicitly below if ($hi & (int)0x80000000) { $hi &= (int)0x7fffffff; $hi += 0x80000000; } if ($lo & (int)0x80000000) { $lo &= (int)0x7fffffff; $lo += 0x80000000; } $value = $hi * 4294967296 + $lo; if ($isNeg) { $value = 0 - $value; } } else { // Upcast negatives in LSB bit if ($arr[2] & 0x80000000) { $arr[2] = $arr[2] & 0xffffffff; } // Check for a negative if ($arr[1] & 0x80000000) { $arr[1] = $arr[1] & 0xffffffff; $arr[1] = $arr[1] ^ 0xffffffff; $arr[2] = $arr[2] ^ 0xffffffff; $value = 0 - $arr[1] * 4294967296 - $arr[2] - 1; } else { $value = $arr[1] * 4294967296 + $arr[2]; } } return 8; } public function readDouble(&$value) { $data = strrev($this->trans_->readAll(8)); $arr = unpack('d', $data); $value = $arr[1]; return 8; } public function readString(&$value) { $result = $this->readI32($len); if ($len) { $value = $this->trans_->readAll($len); } else { $value = ''; } return $result + $len; } public function readUuid(&$value) { $data = $this->trans_->readAll(16); $hex = bin2hex($data); $value = substr($hex, 0, 8) . '-' . substr($hex, 8, 4) . '-' . substr($hex, 12, 4) . '-' . substr($hex, 16, 4) . '-' . substr($hex, 20, 12); return 16; } } thrift-0.23.0/lib/php/lib/Protocol/SimpleJSON/0000775000175000017500000000000015165535636021224 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Protocol/SimpleJSON/CollectionMapKeyException.php0000664000175000017500000000204715165535636027021 0ustar00buildbuild00000000000000p_ = $p; } public function write() { if ($this->first_) { $this->first_ = false; } else { $this->p_->getTransport()->write(TSimpleJSONProtocol::COMMA); } } } thrift-0.23.0/lib/php/lib/Protocol/SimpleJSON/StructContext.php0000664000175000017500000000275015165535636024572 0ustar00buildbuild00000000000000p_ = $p; } public function write() { if ($this->first_) { $this->first_ = false; $this->colon_ = true; } else { $this->p_->getTransport()->write( $this->colon_ ? TSimpleJSONProtocol::COLON : TSimpleJSONProtocol::COMMA ); $this->colon_ = !$this->colon_; } } } thrift-0.23.0/lib/php/lib/Protocol/SimpleJSON/Context.php0000664000175000017500000000175515165535636023371 0ustar00buildbuild00000000000000isKey = !$this->isKey; } public function isMapKey() { // we want to coerce map keys to json strings regardless // of their type return $this->isKey; } } thrift-0.23.0/lib/php/lib/Protocol/TSimpleJSONProtocol.php0000664000175000017500000002172015170007142023563 0ustar00buildbuild00000000000000writeContextStack_[] = $this->writeContext_; $this->writeContext_ = $c; } /** * Pop the last write context off the stack */ protected function popWriteContext() { $this->writeContext_ = array_pop($this->writeContextStack_); } /** * Used to make sure that we are not encountering a map whose keys are containers */ protected function assertContextIsNotMapKey($invalidKeyType) { if ($this->writeContext_->isMapKey()) { throw new CollectionMapKeyException( "Cannot serialize a map with keys that are of type " . $invalidKeyType ); } } private function writeJSONString($b) { $this->writeContext_->write(); $this->trans_->write(json_encode((string)$b)); } private function writeJSONInteger($num) { $isMapKey = $this->writeContext_->isMapKey(); $this->writeContext_->write(); if ($isMapKey) { $this->trans_->write(self::QUOTE); } $this->trans_->write((int)$num); if ($isMapKey) { $this->trans_->write(self::QUOTE); } } private function writeJSONDouble($num) { $isMapKey = $this->writeContext_->isMapKey(); $this->writeContext_->write(); if ($isMapKey) { $this->trans_->write(self::QUOTE); } #TODO add compatibility with NAN and INF $this->trans_->write(json_encode((float)$num)); if ($isMapKey) { $this->trans_->write(self::QUOTE); } } /** * Constructor */ public function __construct($trans) { parent::__construct($trans); $this->writeContext_ = new Context(); } /** * Writes the message header * * @param string $name Function name * @param int $type message type TMessageType::CALL or TMessageType::REPLY * @param int $seqid The sequence id of this message */ public function writeMessageBegin($name, $type, $seqid) { $this->trans_->write(self::LBRACKET); $this->pushWriteContext(new ListContext($this)); $this->writeJSONString($name); $this->writeJSONInteger($type); $this->writeJSONInteger($seqid); } /** * Close the message */ public function writeMessageEnd() { $this->popWriteContext(); $this->trans_->write(self::RBRACKET); } /** * Writes a struct header. * * @param string $name Struct name */ public function writeStructBegin($name) { $this->writeContext_->write(); $this->trans_->write(self::LBRACE); $this->pushWriteContext(new StructContext($this)); } /** * Close a struct. */ public function writeStructEnd() { $this->popWriteContext(); $this->trans_->write(self::RBRACE); } public function writeFieldBegin($fieldName, $fieldType, $fieldId) { $this->writeJSONString($fieldName); } public function writeFieldEnd() { } public function writeFieldStop() { } public function writeMapBegin($keyType, $valType, $size) { $this->assertContextIsNotMapKey(self::NAME_MAP); $this->writeContext_->write(); $this->trans_->write(self::LBRACE); $this->pushWriteContext(new MapContext($this)); } public function writeMapEnd() { $this->popWriteContext(); $this->trans_->write(self::RBRACE); } public function writeListBegin($elemType, $size) { $this->assertContextIsNotMapKey(self::NAME_LIST); $this->writeContext_->write(); $this->trans_->write(self::LBRACKET); $this->pushWriteContext(new ListContext($this)); // No metadata! } public function writeListEnd() { $this->popWriteContext(); $this->trans_->write(self::RBRACKET); } public function writeSetBegin($elemType, $size) { $this->assertContextIsNotMapKey(self::NAME_SET); $this->writeContext_->write(); $this->trans_->write(self::LBRACKET); $this->pushWriteContext(new ListContext($this)); // No metadata! } public function writeSetEnd() { $this->popWriteContext(); $this->trans_->write(self::RBRACKET); } public function writeBool($bool) { $this->writeJSONInteger($bool ? 1 : 0); } public function writeByte($byte) { $this->writeJSONInteger($byte); } public function writeI16($i16) { $this->writeJSONInteger($i16); } public function writeI32($i32) { $this->writeJSONInteger($i32); } public function writeI64($i64) { $this->writeJSONInteger($i64); } public function writeDouble($dub) { $this->writeJSONDouble($dub); } public function writeString($str) { $this->writeJSONString($str); } public function writeUuid($uuid) { $this->writeJSONString($uuid); } /** * Reading methods. * * simplejson is not meant to be read back into thrift * - see http://wiki.apache.org/thrift/ThriftUsageJava * - use JSON instead */ public function readMessageBegin(&$name, &$type, &$seqid) { throw new TException("Not implemented"); } public function readMessageEnd() { throw new TException("Not implemented"); } public function readStructBegin(&$name) { throw new TException("Not implemented"); } public function readStructEnd() { throw new TException("Not implemented"); } public function readFieldBegin(&$name, &$fieldType, &$fieldId) { throw new TException("Not implemented"); } public function readFieldEnd() { throw new TException("Not implemented"); } public function readMapBegin(&$keyType, &$valType, &$size) { throw new TException("Not implemented"); } public function readMapEnd() { throw new TException("Not implemented"); } public function readListBegin(&$elemType, &$size) { throw new TException("Not implemented"); } public function readListEnd() { throw new TException("Not implemented"); } public function readSetBegin(&$elemType, &$size) { throw new TException("Not implemented"); } public function readSetEnd() { throw new TException("Not implemented"); } public function readBool(&$bool) { throw new TException("Not implemented"); } public function readByte(&$byte) { throw new TException("Not implemented"); } public function readI16(&$i16) { throw new TException("Not implemented"); } public function readI32(&$i32) { throw new TException("Not implemented"); } public function readI64(&$i64) { throw new TException("Not implemented"); } public function readDouble(&$dub) { throw new TException("Not implemented"); } public function readString(&$str) { throw new TException("Not implemented"); } public function readUuid(&$uuid) { throw new TException("Not implemented"); } } thrift-0.23.0/lib/php/lib/Protocol/TProtocol.php0000664000175000017500000002463515167543515021746 0ustar00buildbuild00000000000000trans_ = $trans; } /** * Accessor for transport * * @return TTransport */ public function getTransport() { return $this->trans_; } /** * Writes the message header * * @param string $name Function name * @param int $type message type TMessageType::CALL or TMessageType::REPLY * @param int $seqid The sequence id of this message */ abstract public function writeMessageBegin($name, $type, $seqid); /** * Close the message */ abstract public function writeMessageEnd(); /** * Writes a struct header. * * @param string $name Struct name * @throws TException on write error * @return int How many bytes written */ abstract public function writeStructBegin($name); /** * Close a struct. * * @throws TException on write error * @return int How many bytes written */ abstract public function writeStructEnd(); /* * Starts a field. * * @param string $name Field name * @param int $type Field type * @param int $fid Field id * @throws TException on write error * @return int How many bytes written */ abstract public function writeFieldBegin($fieldName, $fieldType, $fieldId); abstract public function writeFieldEnd(); abstract public function writeFieldStop(); abstract public function writeMapBegin($keyType, $valType, $size); abstract public function writeMapEnd(); abstract public function writeListBegin($elemType, $size); abstract public function writeListEnd(); abstract public function writeSetBegin($elemType, $size); abstract public function writeSetEnd(); abstract public function writeBool($bool); abstract public function writeByte($byte); abstract public function writeI16($i16); abstract public function writeI32($i32); abstract public function writeI64($i64); abstract public function writeDouble($dub); abstract public function writeString($str); abstract public function writeUuid($uuid); /** * Reads the message header * * @param string $name Function name * @param int $type message type TMessageType::CALL or TMessageType::REPLY * @parem int $seqid The sequence id of this message */ abstract public function readMessageBegin(&$name, &$type, &$seqid); /** * Read the close of message */ abstract public function readMessageEnd(); abstract public function readStructBegin(&$name); abstract public function readStructEnd(); abstract public function readFieldBegin(&$name, &$fieldType, &$fieldId); abstract public function readFieldEnd(); abstract public function readMapBegin(&$keyType, &$valType, &$size); abstract public function readMapEnd(); abstract public function readListBegin(&$elemType, &$size); abstract public function readListEnd(); abstract public function readSetBegin(&$elemType, &$size); abstract public function readSetEnd(); abstract public function readBool(&$bool); abstract public function readByte(&$byte); abstract public function readI16(&$i16); abstract public function readI32(&$i32); abstract public function readI64(&$i64); abstract public function readDouble(&$dub); abstract public function readString(&$str); abstract public function readUuid(&$uuid); /** * The skip function is a utility to parse over unrecognized date without * causing corruption. * * @param int $type What type is it (defined in TType::class) */ public function skip($type) { switch ($type) { case TType::BOOL: return $this->readBool($bool); case TType::BYTE: return $this->readByte($byte); case TType::I16: return $this->readI16($i16); case TType::I32: return $this->readI32($i32); case TType::I64: return $this->readI64($i64); case TType::DOUBLE: return $this->readDouble($dub); case TType::STRING: return $this->readString($str); case TType::UUID: return $this->readUuid($uuid); case TType::STRUCT: $result = $this->readStructBegin($name); while (true) { $result += $this->readFieldBegin($name, $ftype, $fid); if ($ftype == TType::STOP) { break; } $result += $this->skip($ftype); $result += $this->readFieldEnd(); } $result += $this->readStructEnd(); return $result; case TType::MAP: $result = $this->readMapBegin($keyType, $valType, $size); for ($i = 0; $i < $size; $i++) { $result += $this->skip($keyType); $result += $this->skip($valType); } $result += $this->readMapEnd(); return $result; case TType::SET: $result = $this->readSetBegin($elemType, $size); for ($i = 0; $i < $size; $i++) { $result += $this->skip($elemType); } $result += $this->readSetEnd(); return $result; case TType::LST: $result = $this->readListBegin($elemType, $size); for ($i = 0; $i < $size; $i++) { $result += $this->skip($elemType); } $result += $this->readListEnd(); return $result; default: throw new TProtocolException( 'Unknown field type: ' . $type, TProtocolException::INVALID_DATA ); } } /** * Utility for skipping binary data * * @param TTransport $itrans TTransport object * @param int $type Field type */ public static function skipBinary($itrans, $type) { switch ($type) { case TType::BOOL: return $itrans->readAll(1); case TType::BYTE: return $itrans->readAll(1); case TType::I16: return $itrans->readAll(2); case TType::I32: return $itrans->readAll(4); case TType::I64: return $itrans->readAll(8); case TType::DOUBLE: return $itrans->readAll(8); case TType::UUID: return $itrans->readAll(16); case TType::STRING: $len = unpack('N', $itrans->readAll(4)); $len = $len[1]; if ($len > 0x7fffffff) { $len = 0 - (($len - 1) ^ 0xffffffff); } return 4 + $itrans->readAll($len); case TType::STRUCT: $result = 0; while (true) { $ftype = 0; $fid = 0; $data = $itrans->readAll(1); $arr = unpack('c', $data); $ftype = $arr[1]; if ($ftype == TType::STOP) { break; } // I16 field id $result += $itrans->readAll(2); $result += self::skipBinary($itrans, $ftype); } return $result; case TType::MAP: // Ktype $data = $itrans->readAll(1); $arr = unpack('c', $data); $ktype = $arr[1]; // Vtype $data = $itrans->readAll(1); $arr = unpack('c', $data); $vtype = $arr[1]; // Size $data = $itrans->readAll(4); $arr = unpack('N', $data); $size = $arr[1]; if ($size > 0x7fffffff) { $size = 0 - (($size - 1) ^ 0xffffffff); } $result = 6; for ($i = 0; $i < $size; $i++) { $result += self::skipBinary($itrans, $ktype); $result += self::skipBinary($itrans, $vtype); } return $result; case TType::SET: case TType::LST: // Vtype $data = $itrans->readAll(1); $arr = unpack('c', $data); $vtype = $arr[1]; // Size $data = $itrans->readAll(4); $arr = unpack('N', $data); $size = $arr[1]; if ($size > 0x7fffffff) { $size = 0 - (($size - 1) ^ 0xffffffff); } $result = 5; for ($i = 0; $i < $size; $i++) { $result += self::skipBinary($itrans, $vtype); } return $result; default: throw new TProtocolException( 'Unknown field type: ' . $type, TProtocolException::INVALID_DATA ); } } } thrift-0.23.0/lib/php/lib/Protocol/JSON/0000775000175000017500000000000015165535636020052 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Protocol/JSON/PairContext.php0000664000175000017500000000342315165535636023025 0ustar00buildbuild00000000000000p_ = $p; } public function write() { if ($this->first_) { $this->first_ = false; $this->colon_ = true; } else { $this->p_->getTransport()->write($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA); $this->colon_ = !$this->colon_; } } public function read() { if ($this->first_) { $this->first_ = false; $this->colon_ = true; } else { $this->p_->readJSONSyntaxChar($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA); $this->colon_ = !$this->colon_; } } public function escapeNum() { return $this->colon_; } } thrift-0.23.0/lib/php/lib/Protocol/JSON/ListContext.php0000664000175000017500000000267315165535636023053 0ustar00buildbuild00000000000000p_ = $p; } public function write() { if ($this->first_) { $this->first_ = false; } else { $this->p_->getTransport()->write(TJSONProtocol::COMMA); } } public function read() { if ($this->first_) { $this->first_ = false; } else { $this->p_->readJSONSyntaxChar(TJSONProtocol::COMMA); } } } thrift-0.23.0/lib/php/lib/Protocol/JSON/LookaheadReader.php0000664000175000017500000000276215165535636023604 0ustar00buildbuild00000000000000p_ = $p; } public function read() { if ($this->hasData_) { $this->hasData_ = false; } else { $this->data_ = $this->p_->getTransport()->readAll(1); } return substr($this->data_, 0, 1); } public function peek() { if (!$this->hasData_) { $this->data_ = $this->p_->getTransport()->readAll(1); } $this->hasData_ = true; return substr($this->data_, 0, 1); } } thrift-0.23.0/lib/php/lib/Protocol/JSON/BaseContext.php0000664000175000017500000000202415165535636023000 0ustar00buildbuild00000000000000TMultiplexedProtocol is a protocol-independent concrete decorator * that allows a Thrift client to communicate with a multiplexing Thrift server, * by prepending the service name to the function name during function calls. * * @package Thrift\Protocol */ class TMultiplexedProtocol extends TProtocolDecorator { /** * Separator between service name and function name. * Should be the same as used at multiplexed Thrift server. * * @var string */ const SEPARATOR = ":"; /** * The name of service. * * @var string */ private $serviceName_; /** * Constructor of TMultiplexedProtocol class. * * Wrap the specified protocol, allowing it to be used to communicate with a * multiplexing server. The $serviceName is required as it is * prepended to the message header so that the multiplexing server can broker * the function call to the proper service. * * @param TProtocol $protocol * @param string $serviceName The name of service. */ public function __construct(TProtocol $protocol, $serviceName) { parent::__construct($protocol); $this->serviceName_ = $serviceName; } /** * Writes the message header. * Prepends the service name to the function name, separated by TMultiplexedProtocol::SEPARATOR. * * @param string $name Function name. * @param int $type Message type. * @param int $seqid The sequence id of this message. */ public function writeMessageBegin($name, $type, $seqid) { if ($type == TMessageType::CALL || $type == TMessageType::ONEWAY) { $nameWithService = $this->serviceName_ . self::SEPARATOR . $name; parent::writeMessageBegin($nameWithService, $type, $seqid); } else { parent::writeMessageBegin($name, $type, $seqid); } } } thrift-0.23.0/lib/php/lib/Protocol/TJSONProtocol.php0000664000175000017500000004551015170007142022414 0ustar00buildbuild00000000000000 1) { switch (substr($name, 0, 1)) { case 'd': $result = TType::DOUBLE; break; case 'i': switch (substr($name, 1, 1)) { case '8': $result = TType::BYTE; break; case '1': $result = TType::I16; break; case '3': $result = TType::I32; break; case '6': $result = TType::I64; break; } break; case 'l': $result = TType::LST; break; case 'm': $result = TType::MAP; break; case 'r': $result = TType::STRUCT; break; case 's': if (substr($name, 1, 1) == 't') { $result = TType::STRING; } elseif (substr($name, 1, 1) == 'e') { $result = TType::SET; } break; case 't': $result = TType::BOOL; break; case 'u': $result = TType::UUID; break; } } if ($result == TType::STOP) { throw new TProtocolException("Unrecognized type", TProtocolException::INVALID_DATA); } return $result; } public $contextStack_ = array(); public $context_; public $reader_; private function pushContext($c) { array_push($this->contextStack_, $this->context_); $this->context_ = $c; } private function popContext() { $this->context_ = array_pop($this->contextStack_); } public function __construct($trans) { parent::__construct($trans); $this->context_ = new BaseContext(); $this->reader_ = new LookaheadReader($this); } public function reset() { $this->contextStack_ = array(); $this->context_ = new BaseContext(); $this->reader_ = new LookaheadReader($this); } public function readJSONSyntaxChar($b) { $ch = $this->reader_->read(); if (substr($ch, 0, 1) != $b) { throw new TProtocolException("Unexpected character: " . $ch, TProtocolException::INVALID_DATA); } } private function writeJSONString($b) { $this->context_->write(); if (is_numeric($b) && $this->context_->escapeNum()) { $this->trans_->write(self::QUOTE); } $this->trans_->write(json_encode($b, JSON_UNESCAPED_UNICODE)); if (is_numeric($b) && $this->context_->escapeNum()) { $this->trans_->write(self::QUOTE); } } private function writeJSONInteger($num) { $this->context_->write(); if ($this->context_->escapeNum()) { $this->trans_->write(self::QUOTE); } $this->trans_->write($num); if ($this->context_->escapeNum()) { $this->trans_->write(self::QUOTE); } } private function writeJSONDouble($num) { $this->context_->write(); if ($this->context_->escapeNum()) { $this->trans_->write(self::QUOTE); } #TODO add compatibility with NAN and INF $this->trans_->write(json_encode($num)); if ($this->context_->escapeNum()) { $this->trans_->write(self::QUOTE); } } private function writeJSONObjectStart() { $this->context_->write(); $this->trans_->write(self::LBRACE); $this->pushContext(new PairContext($this)); } private function writeJSONObjectEnd() { $this->popContext(); $this->trans_->write(self::RBRACE); } private function writeJSONArrayStart() { $this->context_->write(); $this->trans_->write(self::LBRACKET); $this->pushContext(new ListContext($this)); } private function writeJSONArrayEnd() { $this->popContext(); $this->trans_->write(self::RBRACKET); } private function readJSONString($skipContext) { if (!$skipContext) { $this->context_->read(); } $jsonString = ''; $lastChar = null; while (true) { $ch = $this->reader_->read(); $jsonString .= $ch; if ($ch == self::QUOTE && $lastChar !== null && $lastChar !== self::ESCSEQ) { break; } if ($ch == self::ESCSEQ && $lastChar == self::ESCSEQ) { $lastChar = self::DOUBLEESC; } else { $lastChar = $ch; } } return json_decode($jsonString); } private function isJSONNumeric($b) { switch ($b) { case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'E': case 'e': return true; } return false; } private function readJSONNumericChars() { $strbld = array(); while (true) { $ch = $this->reader_->peek(); if (!$this->isJSONNumeric($ch)) { break; } $strbld[] = $this->reader_->read(); } return implode("", $strbld); } private function readJSONInteger() { $this->context_->read(); if ($this->context_->escapeNum()) { $this->readJSONSyntaxChar(self::QUOTE); } $str = $this->readJSONNumericChars(); if ($this->context_->escapeNum()) { $this->readJSONSyntaxChar(self::QUOTE); } if (!is_numeric($str)) { throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA); } return intval($str); } /** * Identical to readJSONInteger but without the final cast. * Needed for proper handling of i64 on 32 bit machines. Why a * separate function? So we don't have to force the rest of the * use cases through the extra conditional. */ private function readJSONIntegerAsString() { $this->context_->read(); if ($this->context_->escapeNum()) { $this->readJSONSyntaxChar(self::QUOTE); } $str = $this->readJSONNumericChars(); if ($this->context_->escapeNum()) { $this->readJSONSyntaxChar(self::QUOTE); } if (!is_numeric($str)) { throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA); } return $str; } private function readJSONDouble() { $this->context_->read(); if (substr($this->reader_->peek(), 0, 1) == self::QUOTE) { $arr = $this->readJSONString(true); if ($arr == "NaN") { return NAN; } elseif ($arr == "Infinity") { return INF; } elseif (!$this->context_->escapeNum()) { throw new TProtocolException( "Numeric data unexpectedly quoted " . $arr, TProtocolException::INVALID_DATA ); } return floatval($arr); } else { if ($this->context_->escapeNum()) { $this->readJSONSyntaxChar(self::QUOTE); } return floatval($this->readJSONNumericChars()); } } private function readJSONObjectStart() { $this->context_->read(); $this->readJSONSyntaxChar(self::LBRACE); $this->pushContext(new PairContext($this)); } private function readJSONObjectEnd() { $this->readJSONSyntaxChar(self::RBRACE); $this->popContext(); } private function readJSONArrayStart() { $this->context_->read(); $this->readJSONSyntaxChar(self::LBRACKET); $this->pushContext(new ListContext($this)); } private function readJSONArrayEnd() { $this->readJSONSyntaxChar(self::RBRACKET); $this->popContext(); } /** * Writes the message header * * @param string $name Function name * @param int $type message type TMessageType::CALL or TMessageType::REPLY * @param int $seqid The sequence id of this message */ public function writeMessageBegin($name, $type, $seqid) { $this->writeJSONArrayStart(); $this->writeJSONInteger(self::VERSION); $this->writeJSONString($name); $this->writeJSONInteger($type); $this->writeJSONInteger($seqid); } /** * Close the message */ public function writeMessageEnd() { $this->writeJSONArrayEnd(); } /** * Writes a struct header. * * @param string $name Struct name * @throws TException on write error * @return int How many bytes written */ public function writeStructBegin($name) { $this->writeJSONObjectStart(); } /** * Close a struct. * * @throws TException on write error * @return int How many bytes written */ public function writeStructEnd() { $this->writeJSONObjectEnd(); } public function writeFieldBegin($fieldName, $fieldType, $fieldId) { $this->writeJSONInteger($fieldId); $this->writeJSONObjectStart(); $this->writeJSONString($this->getTypeNameForTypeID($fieldType)); } public function writeFieldEnd() { $this->writeJsonObjectEnd(); } public function writeFieldStop() { } public function writeMapBegin($keyType, $valType, $size) { $this->writeJSONArrayStart(); $this->writeJSONString($this->getTypeNameForTypeID($keyType)); $this->writeJSONString($this->getTypeNameForTypeID($valType)); $this->writeJSONInteger($size); $this->writeJSONObjectStart(); } public function writeMapEnd() { $this->writeJSONObjectEnd(); $this->writeJSONArrayEnd(); } public function writeListBegin($elemType, $size) { $this->writeJSONArrayStart(); $this->writeJSONString($this->getTypeNameForTypeID($elemType)); $this->writeJSONInteger($size); } public function writeListEnd() { $this->writeJSONArrayEnd(); } public function writeSetBegin($elemType, $size) { $this->writeJSONArrayStart(); $this->writeJSONString($this->getTypeNameForTypeID($elemType)); $this->writeJSONInteger($size); } public function writeSetEnd() { $this->writeJSONArrayEnd(); } public function writeBool($bool) { $this->writeJSONInteger($bool ? 1 : 0); } public function writeByte($byte) { $this->writeJSONInteger($byte); } public function writeI16($i16) { $this->writeJSONInteger($i16); } public function writeI32($i32) { $this->writeJSONInteger($i32); } public function writeI64($i64) { $this->writeJSONInteger($i64); } public function writeDouble($dub) { $this->writeJSONDouble($dub); } public function writeString($str) { $this->writeJSONString($str); } public function writeUuid($uuid) { $this->writeJSONString($uuid); } /** * Reads the message header * * @param string $name Function name * @param int $type message type TMessageType::CALL or TMessageType::REPLY * @parem int $seqid The sequence id of this message */ public function readMessageBegin(&$name, &$type, &$seqid) { $this->readJSONArrayStart(); if ($this->readJSONInteger() != self::VERSION) { throw new TProtocolException("Message contained bad version", TProtocolException::BAD_VERSION); } $name = $this->readJSONString(false); $type = $this->readJSONInteger(); $seqid = $this->readJSONInteger(); return true; } /** * Read the close of message */ public function readMessageEnd() { $this->readJSONArrayEnd(); } public function readStructBegin(&$name) { $this->readJSONObjectStart(); return 0; } public function readStructEnd() { $this->readJSONObjectEnd(); } public function readFieldBegin(&$name, &$fieldType, &$fieldId) { $ch = $this->reader_->peek(); $name = ""; if (substr($ch, 0, 1) == self::RBRACE) { $fieldType = TType::STOP; } else { $fieldId = $this->readJSONInteger(); $this->readJSONObjectStart(); $fieldType = $this->getTypeIDForTypeName($this->readJSONString(false)); } } public function readFieldEnd() { $this->readJSONObjectEnd(); } public function readMapBegin(&$keyType, &$valType, &$size) { $this->readJSONArrayStart(); $keyType = $this->getTypeIDForTypeName($this->readJSONString(false)); $valType = $this->getTypeIDForTypeName($this->readJSONString(false)); $size = $this->readJSONInteger(); $this->readJSONObjectStart(); } public function readMapEnd() { $this->readJSONObjectEnd(); $this->readJSONArrayEnd(); } public function readListBegin(&$elemType, &$size) { $this->readJSONArrayStart(); $elemType = $this->getTypeIDForTypeName($this->readJSONString(false)); $size = $this->readJSONInteger(); return true; } public function readListEnd() { $this->readJSONArrayEnd(); } public function readSetBegin(&$elemType, &$size) { $this->readJSONArrayStart(); $elemType = $this->getTypeIDForTypeName($this->readJSONString(false)); $size = $this->readJSONInteger(); return true; } public function readSetEnd() { $this->readJSONArrayEnd(); } public function readBool(&$bool) { $bool = $this->readJSONInteger() == 0 ? false : true; return true; } public function readByte(&$byte) { $byte = $this->readJSONInteger(); return true; } public function readI16(&$i16) { $i16 = $this->readJSONInteger(); return true; } public function readI32(&$i32) { $i32 = $this->readJSONInteger(); return true; } public function readI64(&$i64) { if (PHP_INT_SIZE === 4) { $i64 = $this->readJSONIntegerAsString(); } else { $i64 = $this->readJSONInteger(); } return true; } public function readDouble(&$dub) { $dub = $this->readJSONDouble(); return true; } public function readString(&$str) { $str = $this->readJSONString(false); return true; } public function readUuid(&$uuid) { $uuid = $this->readJSONString(false); return true; } } thrift-0.23.0/lib/php/lib/Protocol/TBinaryProtocolAccelerated.php0000664000175000017500000000513215165535636025222 0ustar00buildbuild00000000000000strictRead_; } public function isStrictWrite() { return $this->strictWrite_; } } thrift-0.23.0/lib/php/lib/Protocol/TProtocolDecorator.php0000664000175000017500000001672415167543515023611 0ustar00buildbuild00000000000000TProtocolDecorator forwards all requests to an enclosed * TProtocol instance, providing a way to author concise * concrete decorator subclasses. While it has no abstract methods, it * is marked abstract as a reminder that by itself, it does not modify * the behaviour of the enclosed TProtocol. * * @package Thrift\Protocol */ abstract class TProtocolDecorator extends TProtocol { /** * Instance of protocol, to which all operations will be forwarded. * * @var TProtocol */ private $concreteProtocol_; /** * Constructor of TProtocolDecorator class. * Encloses the specified protocol. * * @param TProtocol $protocol All operations will be forward to this instance. Must be non-null. */ protected function __construct(TProtocol $protocol) { parent::__construct($protocol->getTransport()); $this->concreteProtocol_ = $protocol; } /** * Writes the message header. * * @param string $name Function name * @param int $type message type TMessageType::CALL or TMessageType::REPLY * @param int $seqid The sequence id of this message */ public function writeMessageBegin($name, $type, $seqid) { return $this->concreteProtocol_->writeMessageBegin($name, $type, $seqid); } /** * Closes the message. */ public function writeMessageEnd() { return $this->concreteProtocol_->writeMessageEnd(); } /** * Writes a struct header. * * @param string $name Struct name * * @throws TException on write error * @return int How many bytes written */ public function writeStructBegin($name) { return $this->concreteProtocol_->writeStructBegin($name); } /** * Close a struct. * * @throws TException on write error * @return int How many bytes written */ public function writeStructEnd() { return $this->concreteProtocol_->writeStructEnd(); } public function writeFieldBegin($fieldName, $fieldType, $fieldId) { return $this->concreteProtocol_->writeFieldBegin($fieldName, $fieldType, $fieldId); } public function writeFieldEnd() { return $this->concreteProtocol_->writeFieldEnd(); } public function writeFieldStop() { return $this->concreteProtocol_->writeFieldStop(); } public function writeMapBegin($keyType, $valType, $size) { return $this->concreteProtocol_->writeMapBegin($keyType, $valType, $size); } public function writeMapEnd() { return $this->concreteProtocol_->writeMapEnd(); } public function writeListBegin($elemType, $size) { return $this->concreteProtocol_->writeListBegin($elemType, $size); } public function writeListEnd() { return $this->concreteProtocol_->writeListEnd(); } public function writeSetBegin($elemType, $size) { return $this->concreteProtocol_->writeSetBegin($elemType, $size); } public function writeSetEnd() { return $this->concreteProtocol_->writeSetEnd(); } public function writeBool($bool) { return $this->concreteProtocol_->writeBool($bool); } public function writeByte($byte) { return $this->concreteProtocol_->writeByte($byte); } public function writeI16($i16) { return $this->concreteProtocol_->writeI16($i16); } public function writeI32($i32) { return $this->concreteProtocol_->writeI32($i32); } public function writeI64($i64) { return $this->concreteProtocol_->writeI64($i64); } public function writeDouble($dub) { return $this->concreteProtocol_->writeDouble($dub); } public function writeString($str) { return $this->concreteProtocol_->writeString($str); } public function writeUuid($uuid) { return $this->concreteProtocol_->writeUuid($uuid); } /** * Reads the message header * * @param string $name Function name * @param int $type message type TMessageType::CALL or TMessageType::REPLY * @param int $seqid The sequence id of this message */ public function readMessageBegin(&$name, &$type, &$seqid) { return $this->concreteProtocol_->readMessageBegin($name, $type, $seqid); } /** * Read the close of message */ public function readMessageEnd() { return $this->concreteProtocol_->readMessageEnd(); } public function readStructBegin(&$name) { return $this->concreteProtocol_->readStructBegin($name); } public function readStructEnd() { return $this->concreteProtocol_->readStructEnd(); } public function readFieldBegin(&$name, &$fieldType, &$fieldId) { return $this->concreteProtocol_->readFieldBegin($name, $fieldType, $fieldId); } public function readFieldEnd() { return $this->concreteProtocol_->readFieldEnd(); } public function readMapBegin(&$keyType, &$valType, &$size) { $this->concreteProtocol_->readMapBegin($keyType, $valType, $size); } public function readMapEnd() { return $this->concreteProtocol_->readMapEnd(); } public function readListBegin(&$elemType, &$size) { $this->concreteProtocol_->readListBegin($elemType, $size); } public function readListEnd() { return $this->concreteProtocol_->readListEnd(); } public function readSetBegin(&$elemType, &$size) { return $this->concreteProtocol_->readSetBegin($elemType, $size); } public function readSetEnd() { return $this->concreteProtocol_->readSetEnd(); } public function readBool(&$bool) { return $this->concreteProtocol_->readBool($bool); } public function readByte(&$byte) { return $this->concreteProtocol_->readByte($byte); } public function readI16(&$i16) { return $this->concreteProtocol_->readI16($i16); } public function readI32(&$i32) { return $this->concreteProtocol_->readI32($i32); } public function readI64(&$i64) { return $this->concreteProtocol_->readI64($i64); } public function readDouble(&$dub) { return $this->concreteProtocol_->readDouble($dub); } public function readString(&$str) { return $this->concreteProtocol_->readString($str); } public function readUuid(&$uuid) { return $this->concreteProtocol_->readUuid($uuid); } } thrift-0.23.0/lib/php/lib/Serializer/0000775000175000017500000000000015165535636017611 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Serializer/TBinarySerializer.php0000664000175000017500000000627315165535636023734 0ustar00buildbuild00000000000000getName(), TMessageType::REPLY, $object, 0, $protocol->isStrictWrite() ); $protocol->readMessageBegin($unused_name, $unused_type, $unused_seqid); } else { $object->write($protocol); } $protocol->getTransport()->flush(); return $transport->getBuffer(); } public static function deserialize($string_object, $class_name, $buffer_size = 8192) { $transport = new TMemoryBuffer(); $protocol = new TBinaryProtocolAccelerated($transport); if (function_exists('thrift_protocol_read_binary')) { // NOTE (t.heintz) TBinaryProtocolAccelerated internally wraps our TMemoryBuffer in a // TBufferedTransport, so we have to retrieve it again or risk losing data when writing // less than 512 bytes to the transport (see the comment there as well). // @see THRIFT-1579 $protocol->writeMessageBegin('', TMessageType::REPLY, 0); $protocolTransport = $protocol->getTransport(); $protocolTransport->write($string_object); $protocolTransport->flush(); return thrift_protocol_read_binary($protocol, $class_name, $protocol->isStrictRead(), $buffer_size); } else { $transport->write($string_object); $object = new $class_name(); $object->read($protocol); return $object; } } } thrift-0.23.0/lib/php/lib/Base/0000775000175000017500000000000015167543515016347 5ustar00buildbuild00000000000000thrift-0.23.0/lib/php/lib/Base/TBase.php0000664000175000017500000003223615167543515020064 0ustar00buildbuild00000000000000 'Bool', TType::BYTE => 'Byte', TType::I16 => 'I16', TType::I32 => 'I32', TType::I64 => 'I64', TType::DOUBLE => 'Double', TType::STRING => 'String', TType::UUID => 'Uuid' ); abstract public function read($input); abstract public function write($output); public function __construct($spec = null, $vals = null) { if (is_array($spec) && is_array($vals)) { foreach ($spec as $fid => $fspec) { $var = $fspec['var']; if (isset($vals[$var])) { $this->$var = $vals[$var]; } } } } public function __wakeup() { $this->__construct(get_object_vars($this)); } private function _readMap(&$var, $spec, $input) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kread = $vread = null; if (isset(TBase::$tmethod[$ktype])) { $kread = 'read' . TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vread = 'read' . TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $var = array(); $_ktype = $_vtype = $size = 0; $xfer += $input->readMapBegin($_ktype, $_vtype, $size); for ($i = 0; $i < $size; ++$i) { $key = $val = null; if ($kread !== null) { $xfer += $input->$kread($key); } else { switch ($ktype) { case TType::STRUCT: $class = $kspec['class']; $key = new $class(); $xfer += $key->read($input); break; case TType::MAP: $xfer += $this->_readMap($key, $kspec, $input); break; case TType::LST: $xfer += $this->_readList($key, $kspec, $input, false); break; case TType::SET: $xfer += $this->_readList($key, $kspec, $input, true); break; } } if ($vread !== null) { $xfer += $input->$vread($val); } else { switch ($vtype) { case TType::STRUCT: $class = $vspec['class']; $val = new $class(); $xfer += $val->read($input); break; case TType::MAP: $xfer += $this->_readMap($val, $vspec, $input); break; case TType::LST: $xfer += $this->_readList($val, $vspec, $input, false); break; case TType::SET: $xfer += $this->_readList($val, $vspec, $input, true); break; } } $var[$key] = $val; } $xfer += $input->readMapEnd(); return $xfer; } private function _readList(&$var, $spec, $input, $set = false) { $xfer = 0; $etype = $spec['etype']; $eread = $vread = null; if (isset(TBase::$tmethod[$etype])) { $eread = 'read' . TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } $var = array(); $_etype = $size = 0; if ($set) { $xfer += $input->readSetBegin($_etype, $size); } else { $xfer += $input->readListBegin($_etype, $size); } for ($i = 0; $i < $size; ++$i) { $elem = null; if ($eread !== null) { $xfer += $input->$eread($elem); } else { $espec = $spec['elem']; switch ($etype) { case TType::STRUCT: $class = $espec['class']; $elem = new $class(); $xfer += $elem->read($input); break; case TType::MAP: $xfer += $this->_readMap($elem, $espec, $input); break; case TType::LST: $xfer += $this->_readList($elem, $espec, $input, false); break; case TType::SET: $xfer += $this->_readList($elem, $espec, $input, true); break; } } if ($set) { $var[$elem] = true; } else { $var [] = $elem; } } if ($set) { $xfer += $input->readSetEnd(); } else { $xfer += $input->readListEnd(); } return $xfer; } protected function _read($class, $spec, $input) { $xfer = 0; $fname = null; $ftype = 0; $fid = 0; $xfer += $input->readStructBegin($fname); while (true) { $xfer += $input->readFieldBegin($fname, $ftype, $fid); if ($ftype == TType::STOP) { break; } if (isset($spec[$fid])) { $fspec = $spec[$fid]; $var = $fspec['var']; if ($ftype == $fspec['type']) { $xfer = 0; if (isset(TBase::$tmethod[$ftype])) { $func = 'read' . TBase::$tmethod[$ftype]; $xfer += $input->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $class = $fspec['class']; $this->$var = new $class(); $xfer += $this->$var->read($input); break; case TType::MAP: $xfer += $this->_readMap($this->$var, $fspec, $input); break; case TType::LST: $xfer += $this->_readList($this->$var, $fspec, $input, false); break; case TType::SET: $xfer += $this->_readList($this->$var, $fspec, $input, true); break; } } } else { $xfer += $input->skip($ftype); } } else { $xfer += $input->skip($ftype); } $xfer += $input->readFieldEnd(); } $xfer += $input->readStructEnd(); return $xfer; } private function _writeMap($var, $spec, $output) { $xfer = 0; $ktype = $spec['ktype']; $vtype = $spec['vtype']; $kwrite = $vwrite = null; if (isset(TBase::$tmethod[$ktype])) { $kwrite = 'write' . TBase::$tmethod[$ktype]; } else { $kspec = $spec['key']; } if (isset(TBase::$tmethod[$vtype])) { $vwrite = 'write' . TBase::$tmethod[$vtype]; } else { $vspec = $spec['val']; } $xfer += $output->writeMapBegin($ktype, $vtype, count($var)); foreach ($var as $key => $val) { if (isset($kwrite)) { $xfer += $output->$kwrite($key); } else { switch ($ktype) { case TType::STRUCT: $xfer += $key->write($output); break; case TType::MAP: $xfer += $this->_writeMap($key, $kspec, $output); break; case TType::LST: $xfer += $this->_writeList($key, $kspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($key, $kspec, $output, true); break; } } if (isset($vwrite)) { $xfer += $output->$vwrite($val); } else { switch ($vtype) { case TType::STRUCT: $xfer += $val->write($output); break; case TType::MAP: $xfer += $this->_writeMap($val, $vspec, $output); break; case TType::LST: $xfer += $this->_writeList($val, $vspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($val, $vspec, $output, true); break; } } } $xfer += $output->writeMapEnd(); return $xfer; } private function _writeList($var, $spec, $output, $set = false) { $xfer = 0; $etype = $spec['etype']; $ewrite = null; if (isset(TBase::$tmethod[$etype])) { $ewrite = 'write' . TBase::$tmethod[$etype]; } else { $espec = $spec['elem']; } if ($set) { $xfer += $output->writeSetBegin($etype, count($var)); } else { $xfer += $output->writeListBegin($etype, count($var)); } foreach ($var as $key => $val) { $elem = $set ? $key : $val; if (isset($ewrite)) { $xfer += $output->$ewrite($elem); } else { switch ($etype) { case TType::STRUCT: $xfer += $elem->write($output); break; case TType::MAP: $xfer += $this->_writeMap($elem, $espec, $output); break; case TType::LST: $xfer += $this->_writeList($elem, $espec, $output, false); break; case TType::SET: $xfer += $this->_writeList($elem, $espec, $output, true); break; } } } if ($set) { $xfer += $output->writeSetEnd(); } else { $xfer += $output->writeListEnd(); } return $xfer; } protected function _write($class, $spec, $output) { $xfer = 0; $xfer += $output->writeStructBegin($class); foreach ($spec as $fid => $fspec) { $var = $fspec['var']; if ($this->$var !== null) { $ftype = $fspec['type']; $xfer += $output->writeFieldBegin($var, $ftype, $fid); if (isset(TBase::$tmethod[$ftype])) { $func = 'write' . TBase::$tmethod[$ftype]; $xfer += $output->$func($this->$var); } else { switch ($ftype) { case TType::STRUCT: $xfer += $this->$var->write($output); break; case TType::MAP: $xfer += $this->_writeMap($this->$var, $fspec, $output); break; case TType::LST: $xfer += $this->_writeList($this->$var, $fspec, $output, false); break; case TType::SET: $xfer += $this->_writeList($this->$var, $fspec, $output, true); break; } } $xfer += $output->writeFieldEnd(); } } $xfer += $output->writeFieldStop(); $xfer += $output->writeStructEnd(); return $xfer; } } thrift-0.23.0/lib/php/Makefile.in0000644000175000017500000013066715170007167016777 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/php ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(phpmoduledir)" "$(DESTDIR)$(phpdir)" \ "$(DESTDIR)$(phpbasedir)" "$(DESTDIR)$(phpclassloaderdir)" \ "$(DESTDIR)$(phpconfdir)" "$(DESTDIR)$(phpexceptiondir)" \ "$(DESTDIR)$(phpfactorydir)" "$(DESTDIR)$(phpprotocoldir)" \ "$(DESTDIR)$(phpprotocoljsondir)" \ "$(DESTDIR)$(phpprotocolsimplejsondir)" \ "$(DESTDIR)$(phpserializerdir)" "$(DESTDIR)$(phpserverdir)" \ "$(DESTDIR)$(phpstringfuncdir)" "$(DESTDIR)$(phptransportdir)" \ "$(DESTDIR)$(phptypedir)" SCRIPTS = $(phpmodule_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(php_DATA) $(phpbase_DATA) $(phpclassloader_DATA) \ $(phpconf_DATA) $(phpexception_DATA) $(phpfactory_DATA) \ $(phpprotocol_DATA) $(phpprotocoljson_DATA) \ $(phpprotocolsimplejson_DATA) $(phpserializer_DATA) \ $(phpserver_DATA) $(phpstringfunc_DATA) $(phptransport_DATA) \ $(phptype_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = test am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_TESTS_TRUE@SUBDIRS = test @WITH_PHP_EXTENSION_TRUE@phpconfdir = $(PHP_CONFIG_PREFIX) @WITH_PHP_EXTENSION_TRUE@phpconf_DATA = thrift_protocol.ini @WITH_PHP_EXTENSION_TRUE@phpmoduledir = `php-config --extension-dir` @WITH_PHP_EXTENSION_TRUE@phpmodule_SCRIPTS = src/ext/thrift_protocol/modules/thrift_protocol.so phpdir = $(PHP_PREFIX)/ php_DATA = \ lib/TMultiplexedProcessor.php phpbasedir = $(phpdir)/Base phpbase_DATA = \ lib/Base/TBase.php phpclassloaderdir = $(phpdir)/ClassLoader phpclassloader_DATA = \ lib/ClassLoader/ThriftClassLoader.php phpexceptiondir = $(phpdir)/Exception phpexception_DATA = \ lib/Exception/TApplicationException.php \ lib/Exception/TException.php \ lib/Exception/TProtocolException.php \ lib/Exception/TTransportException.php phpfactorydir = $(phpdir)/Factory phpfactory_DATA = \ lib/Factory/TBinaryProtocolFactory.php \ lib/Factory/TCompactProtocolFactory.php \ lib/Factory/TJSONProtocolFactory.php \ lib/Factory/TProtocolFactory.php \ lib/Factory/TStringFuncFactory.php \ lib/Factory/TTransportFactoryInterface.php phpprotocoldir = $(phpdir)/Protocol phpprotocol_DATA = \ lib/Protocol/TBinaryProtocolAccelerated.php \ lib/Protocol/TBinaryProtocol.php \ lib/Protocol/TCompactProtocol.php \ lib/Protocol/TJSONProtocol.php \ lib/Protocol/TMultiplexedProtocol.php \ lib/Protocol/TProtocol.php \ lib/Protocol/TProtocolDecorator.php \ lib/Protocol/TSimpleJSONProtocol.php phpprotocoljsondir = $(phpprotocoldir)/JSON phpprotocoljson_DATA = \ lib/Protocol/JSON/BaseContext.php \ lib/Protocol/JSON/ListContext.php \ lib/Protocol/JSON/LookaheadReader.php \ lib/Protocol/JSON/PairContext.php phpprotocolsimplejsondir = $(phpprotocoldir)/SimpleJSON phpprotocolsimplejson_DATA = \ lib/Protocol/SimpleJSON/CollectionMapKeyException.php \ lib/Protocol/SimpleJSON/Context.php \ lib/Protocol/SimpleJSON/ListContext.php \ lib/Protocol/SimpleJSON/MapContext.php \ lib/Protocol/SimpleJSON/StructContext.php phpserializerdir = $(phpdir)/Serializer phpserializer_DATA = \ lib/Serializer/TBinarySerializer.php phpserverdir = $(phpdir)/Server phpserver_DATA = \ lib/Server/TServerSocket.php \ lib/Server/TForkingServer.php \ lib/Server/TServer.php \ lib/Server/TServerTransport.php \ lib/Server/TSimpleServer.php phpstringfuncdir = $(phpdir)/StringFunc phpstringfunc_DATA = \ lib/StringFunc/Mbstring.php \ lib/StringFunc/Core.php \ lib/StringFunc/TStringFunc.php phptransportdir = $(phpdir)/Transport phptransport_DATA = \ lib/Transport/TBufferedTransport.php \ lib/Transport/TCurlClient.php \ lib/Transport/TFramedTransport.php \ lib/Transport/THttpClient.php \ lib/Transport/TMemoryBuffer.php \ lib/Transport/TNullTransport.php \ lib/Transport/TPhpStream.php \ lib/Transport/TSocket.php \ lib/Transport/TSocketPool.php \ lib/Transport/TTransport.php phptypedir = $(phpdir)/Type phptype_DATA = \ lib/Type/TMessageType.php \ lib/Type/TType.php \ lib/Type/TConstant.php EXTRA_DIST = \ lib \ src/autoload.php \ src/ext/thrift_protocol/config.m4 \ src/ext/thrift_protocol/config.w32 \ src/ext/thrift_protocol/php_thrift_protocol.cpp \ src/ext/thrift_protocol/php_thrift_protocol.h \ src/ext/thrift_protocol/php_thrift_protocol.stub.php \ src/ext/thrift_protocol/php_thrift_protocol_arginfo.h \ src/Thrift.php \ src/TStringUtils.php \ coding_standards.md \ thrift_protocol.ini \ phpunit.xml \ README.apache.md \ README.md \ test MAINTAINERCLEANFILES = \ Makefile.in all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/php/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/php/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-phpmoduleSCRIPTS: $(phpmodule_SCRIPTS) @$(NORMAL_INSTALL) @list='$(phpmodule_SCRIPTS)'; test -n "$(phpmoduledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpmoduledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpmoduledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(phpmoduledir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(phpmoduledir)$$dir" || exit $$?; \ } \ ; done uninstall-phpmoduleSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(phpmodule_SCRIPTS)'; test -n "$(phpmoduledir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(phpmoduledir)'; $(am__uninstall_files_from_dir) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-phpDATA: $(php_DATA) @$(NORMAL_INSTALL) @list='$(php_DATA)'; test -n "$(phpdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpdir)" || exit $$?; \ done uninstall-phpDATA: @$(NORMAL_UNINSTALL) @list='$(php_DATA)'; test -n "$(phpdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpdir)'; $(am__uninstall_files_from_dir) install-phpbaseDATA: $(phpbase_DATA) @$(NORMAL_INSTALL) @list='$(phpbase_DATA)'; test -n "$(phpbasedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpbasedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpbasedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpbasedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpbasedir)" || exit $$?; \ done uninstall-phpbaseDATA: @$(NORMAL_UNINSTALL) @list='$(phpbase_DATA)'; test -n "$(phpbasedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpbasedir)'; $(am__uninstall_files_from_dir) install-phpclassloaderDATA: $(phpclassloader_DATA) @$(NORMAL_INSTALL) @list='$(phpclassloader_DATA)'; test -n "$(phpclassloaderdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpclassloaderdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpclassloaderdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpclassloaderdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpclassloaderdir)" || exit $$?; \ done uninstall-phpclassloaderDATA: @$(NORMAL_UNINSTALL) @list='$(phpclassloader_DATA)'; test -n "$(phpclassloaderdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpclassloaderdir)'; $(am__uninstall_files_from_dir) install-phpconfDATA: $(phpconf_DATA) @$(NORMAL_INSTALL) @list='$(phpconf_DATA)'; test -n "$(phpconfdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpconfdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpconfdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpconfdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpconfdir)" || exit $$?; \ done uninstall-phpconfDATA: @$(NORMAL_UNINSTALL) @list='$(phpconf_DATA)'; test -n "$(phpconfdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpconfdir)'; $(am__uninstall_files_from_dir) install-phpexceptionDATA: $(phpexception_DATA) @$(NORMAL_INSTALL) @list='$(phpexception_DATA)'; test -n "$(phpexceptiondir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpexceptiondir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpexceptiondir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpexceptiondir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpexceptiondir)" || exit $$?; \ done uninstall-phpexceptionDATA: @$(NORMAL_UNINSTALL) @list='$(phpexception_DATA)'; test -n "$(phpexceptiondir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpexceptiondir)'; $(am__uninstall_files_from_dir) install-phpfactoryDATA: $(phpfactory_DATA) @$(NORMAL_INSTALL) @list='$(phpfactory_DATA)'; test -n "$(phpfactorydir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpfactorydir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpfactorydir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpfactorydir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpfactorydir)" || exit $$?; \ done uninstall-phpfactoryDATA: @$(NORMAL_UNINSTALL) @list='$(phpfactory_DATA)'; test -n "$(phpfactorydir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpfactorydir)'; $(am__uninstall_files_from_dir) install-phpprotocolDATA: $(phpprotocol_DATA) @$(NORMAL_INSTALL) @list='$(phpprotocol_DATA)'; test -n "$(phpprotocoldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpprotocoldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpprotocoldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpprotocoldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpprotocoldir)" || exit $$?; \ done uninstall-phpprotocolDATA: @$(NORMAL_UNINSTALL) @list='$(phpprotocol_DATA)'; test -n "$(phpprotocoldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpprotocoldir)'; $(am__uninstall_files_from_dir) install-phpprotocoljsonDATA: $(phpprotocoljson_DATA) @$(NORMAL_INSTALL) @list='$(phpprotocoljson_DATA)'; test -n "$(phpprotocoljsondir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpprotocoljsondir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpprotocoljsondir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpprotocoljsondir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpprotocoljsondir)" || exit $$?; \ done uninstall-phpprotocoljsonDATA: @$(NORMAL_UNINSTALL) @list='$(phpprotocoljson_DATA)'; test -n "$(phpprotocoljsondir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpprotocoljsondir)'; $(am__uninstall_files_from_dir) install-phpprotocolsimplejsonDATA: $(phpprotocolsimplejson_DATA) @$(NORMAL_INSTALL) @list='$(phpprotocolsimplejson_DATA)'; test -n "$(phpprotocolsimplejsondir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpprotocolsimplejsondir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpprotocolsimplejsondir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpprotocolsimplejsondir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpprotocolsimplejsondir)" || exit $$?; \ done uninstall-phpprotocolsimplejsonDATA: @$(NORMAL_UNINSTALL) @list='$(phpprotocolsimplejson_DATA)'; test -n "$(phpprotocolsimplejsondir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpprotocolsimplejsondir)'; $(am__uninstall_files_from_dir) install-phpserializerDATA: $(phpserializer_DATA) @$(NORMAL_INSTALL) @list='$(phpserializer_DATA)'; test -n "$(phpserializerdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpserializerdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpserializerdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpserializerdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpserializerdir)" || exit $$?; \ done uninstall-phpserializerDATA: @$(NORMAL_UNINSTALL) @list='$(phpserializer_DATA)'; test -n "$(phpserializerdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpserializerdir)'; $(am__uninstall_files_from_dir) install-phpserverDATA: $(phpserver_DATA) @$(NORMAL_INSTALL) @list='$(phpserver_DATA)'; test -n "$(phpserverdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpserverdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpserverdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpserverdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpserverdir)" || exit $$?; \ done uninstall-phpserverDATA: @$(NORMAL_UNINSTALL) @list='$(phpserver_DATA)'; test -n "$(phpserverdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpserverdir)'; $(am__uninstall_files_from_dir) install-phpstringfuncDATA: $(phpstringfunc_DATA) @$(NORMAL_INSTALL) @list='$(phpstringfunc_DATA)'; test -n "$(phpstringfuncdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phpstringfuncdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phpstringfuncdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phpstringfuncdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phpstringfuncdir)" || exit $$?; \ done uninstall-phpstringfuncDATA: @$(NORMAL_UNINSTALL) @list='$(phpstringfunc_DATA)'; test -n "$(phpstringfuncdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phpstringfuncdir)'; $(am__uninstall_files_from_dir) install-phptransportDATA: $(phptransport_DATA) @$(NORMAL_INSTALL) @list='$(phptransport_DATA)'; test -n "$(phptransportdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phptransportdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phptransportdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phptransportdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phptransportdir)" || exit $$?; \ done uninstall-phptransportDATA: @$(NORMAL_UNINSTALL) @list='$(phptransport_DATA)'; test -n "$(phptransportdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phptransportdir)'; $(am__uninstall_files_from_dir) install-phptypeDATA: $(phptype_DATA) @$(NORMAL_INSTALL) @list='$(phptype_DATA)'; test -n "$(phptypedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(phptypedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(phptypedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(phptypedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(phptypedir)" || exit $$?; \ done uninstall-phptypeDATA: @$(NORMAL_UNINSTALL) @list='$(phptype_DATA)'; test -n "$(phptypedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(phptypedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(SCRIPTS) $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(phpmoduledir)" "$(DESTDIR)$(phpdir)" "$(DESTDIR)$(phpbasedir)" "$(DESTDIR)$(phpclassloaderdir)" "$(DESTDIR)$(phpconfdir)" "$(DESTDIR)$(phpexceptiondir)" "$(DESTDIR)$(phpfactorydir)" "$(DESTDIR)$(phpprotocoldir)" "$(DESTDIR)$(phpprotocoljsondir)" "$(DESTDIR)$(phpprotocolsimplejsondir)" "$(DESTDIR)$(phpserializerdir)" "$(DESTDIR)$(phpserverdir)" "$(DESTDIR)$(phpstringfuncdir)" "$(DESTDIR)$(phptransportdir)" "$(DESTDIR)$(phptypedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) @WITH_PHP_EXTENSION_FALSE@distclean-local: clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-phpDATA install-phpbaseDATA \ install-phpclassloaderDATA install-phpconfDATA \ install-phpexceptionDATA install-phpfactoryDATA \ install-phpmoduleSCRIPTS install-phpprotocolDATA \ install-phpprotocoljsonDATA install-phpprotocolsimplejsonDATA \ install-phpserializerDATA install-phpserverDATA \ install-phpstringfuncDATA install-phptransportDATA \ install-phptypeDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: uninstall-phpDATA uninstall-phpbaseDATA \ uninstall-phpclassloaderDATA uninstall-phpconfDATA \ uninstall-phpexceptionDATA uninstall-phpfactoryDATA \ uninstall-phpmoduleSCRIPTS uninstall-phpprotocolDATA \ uninstall-phpprotocoljsonDATA \ uninstall-phpprotocolsimplejsonDATA \ uninstall-phpserializerDATA uninstall-phpserverDATA \ uninstall-phpstringfuncDATA uninstall-phptransportDATA \ uninstall-phptypeDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-local distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-phpDATA install-phpbaseDATA \ install-phpclassloaderDATA install-phpconfDATA \ install-phpexceptionDATA install-phpfactoryDATA \ install-phpmoduleSCRIPTS install-phpprotocolDATA \ install-phpprotocoljsonDATA install-phpprotocolsimplejsonDATA \ install-phpserializerDATA install-phpserverDATA \ install-phpstringfuncDATA install-phptransportDATA \ install-phptypeDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am \ uninstall-phpDATA uninstall-phpbaseDATA \ uninstall-phpclassloaderDATA uninstall-phpconfDATA \ uninstall-phpexceptionDATA uninstall-phpfactoryDATA \ uninstall-phpmoduleSCRIPTS uninstall-phpprotocolDATA \ uninstall-phpprotocoljsonDATA \ uninstall-phpprotocolsimplejsonDATA \ uninstall-phpserializerDATA uninstall-phpserverDATA \ uninstall-phpstringfuncDATA uninstall-phptransportDATA \ uninstall-phptypeDATA .PRECIOUS: Makefile @WITH_PHP_EXTENSION_TRUE@%.so: @WITH_PHP_EXTENSION_TRUE@ cd src/ext/thrift_protocol/ && $(MAKE) @WITH_PHP_EXTENSION_TRUE@distclean-local: @WITH_PHP_EXTENSION_TRUE@ if [ -f src/ext/thrift_protocol/Makefile ]; then cd src/ext/thrift_protocol/ && $(MAKE) distclean; fi @WITH_PHP_EXTENSION_TRUE@ cd $(phpmodule_SCRIPTS) && $(PHPIZE) --clean lib/Factory/TTransportFactory.php lib/Factory/TFramedTransportFactory.php clean-local: if [ -f src/ext/thrift_protocol/Makefile ]; then cd src/ext/thrift_protocol/ && $(MAKE) clean; fi distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/php/Makefile.am0000664000175000017500000001102315170007142016741 0ustar00buildbuild00000000000000# # 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. # if WITH_TESTS SUBDIRS = test endif if WITH_PHP_EXTENSION %.so: cd src/ext/thrift_protocol/ && $(MAKE) phpconfdir=$(PHP_CONFIG_PREFIX) phpconf_DATA=thrift_protocol.ini phpmoduledir = `php-config --extension-dir` phpmodule_SCRIPTS = src/ext/thrift_protocol/modules/thrift_protocol.so distclean-local: if [ -f src/ext/thrift_protocol/Makefile ]; then cd src/ext/thrift_protocol/ && $(MAKE) distclean; fi cd $(phpmodule_SCRIPTS) && $(PHPIZE) --clean endif phpdir = $(PHP_PREFIX)/ php_DATA = \ lib/TMultiplexedProcessor.php phpbasedir = $(phpdir)/Base phpbase_DATA = \ lib/Base/TBase.php phpclassloaderdir = $(phpdir)/ClassLoader phpclassloader_DATA = \ lib/ClassLoader/ThriftClassLoader.php phpexceptiondir = $(phpdir)/Exception phpexception_DATA = \ lib/Exception/TApplicationException.php \ lib/Exception/TException.php \ lib/Exception/TProtocolException.php \ lib/Exception/TTransportException.php phpfactorydir = $(phpdir)/Factory phpfactory_DATA = \ lib/Factory/TBinaryProtocolFactory.php \ lib/Factory/TCompactProtocolFactory.php \ lib/Factory/TJSONProtocolFactory.php \ lib/Factory/TProtocolFactory.php \ lib/Factory/TStringFuncFactory.php \ lib/Factory/TTransportFactoryInterface.php lib/Factory/TTransportFactory.php lib/Factory/TFramedTransportFactory.php phpprotocoldir = $(phpdir)/Protocol phpprotocol_DATA = \ lib/Protocol/TBinaryProtocolAccelerated.php \ lib/Protocol/TBinaryProtocol.php \ lib/Protocol/TCompactProtocol.php \ lib/Protocol/TJSONProtocol.php \ lib/Protocol/TMultiplexedProtocol.php \ lib/Protocol/TProtocol.php \ lib/Protocol/TProtocolDecorator.php \ lib/Protocol/TSimpleJSONProtocol.php phpprotocoljsondir = $(phpprotocoldir)/JSON phpprotocoljson_DATA = \ lib/Protocol/JSON/BaseContext.php \ lib/Protocol/JSON/ListContext.php \ lib/Protocol/JSON/LookaheadReader.php \ lib/Protocol/JSON/PairContext.php phpprotocolsimplejsondir = $(phpprotocoldir)/SimpleJSON phpprotocolsimplejson_DATA = \ lib/Protocol/SimpleJSON/CollectionMapKeyException.php \ lib/Protocol/SimpleJSON/Context.php \ lib/Protocol/SimpleJSON/ListContext.php \ lib/Protocol/SimpleJSON/MapContext.php \ lib/Protocol/SimpleJSON/StructContext.php phpserializerdir = $(phpdir)/Serializer phpserializer_DATA = \ lib/Serializer/TBinarySerializer.php phpserverdir = $(phpdir)/Server phpserver_DATA = \ lib/Server/TServerSocket.php \ lib/Server/TForkingServer.php \ lib/Server/TServer.php \ lib/Server/TServerTransport.php \ lib/Server/TSimpleServer.php phpstringfuncdir = $(phpdir)/StringFunc phpstringfunc_DATA = \ lib/StringFunc/Mbstring.php \ lib/StringFunc/Core.php \ lib/StringFunc/TStringFunc.php phptransportdir = $(phpdir)/Transport phptransport_DATA = \ lib/Transport/TBufferedTransport.php \ lib/Transport/TCurlClient.php \ lib/Transport/TFramedTransport.php \ lib/Transport/THttpClient.php \ lib/Transport/TMemoryBuffer.php \ lib/Transport/TNullTransport.php \ lib/Transport/TPhpStream.php \ lib/Transport/TSocket.php \ lib/Transport/TSocketPool.php \ lib/Transport/TTransport.php phptypedir = $(phpdir)/Type phptype_DATA = \ lib/Type/TMessageType.php \ lib/Type/TType.php \ lib/Type/TConstant.php clean-local: if [ -f src/ext/thrift_protocol/Makefile ]; then cd src/ext/thrift_protocol/ && $(MAKE) clean; fi distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ lib \ src/autoload.php \ src/ext/thrift_protocol/config.m4 \ src/ext/thrift_protocol/config.w32 \ src/ext/thrift_protocol/php_thrift_protocol.cpp \ src/ext/thrift_protocol/php_thrift_protocol.h \ src/ext/thrift_protocol/php_thrift_protocol.stub.php \ src/ext/thrift_protocol/php_thrift_protocol_arginfo.h \ src/Thrift.php \ src/TStringUtils.php \ coding_standards.md \ thrift_protocol.ini \ phpunit.xml \ README.apache.md \ README.md \ test MAINTAINERCLEANFILES = \ Makefile.in thrift-0.23.0/lib/netstd/0000755000175000017500000000000015170007201015414 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Benchmarks/0000755000175000017500000000000015170007201017471 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Benchmarks/Thrift.Benchmarks/0000775000175000017500000000000015170007142023013 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj0000664000175000017500000000277215170007142027561 0ustar00buildbuild00000000000000 Exe net10.0 0.23.0 latestMajor false true enable thrift-0.23.0/lib/netstd/Benchmarks/Thrift.Benchmarks/Program.cs0000664000175000017500000000177415165535636025004 0ustar00buildbuild00000000000000// 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 BenchmarkDotNet.Running; namespace Thrift.Benchmarks { internal static class Program { public static void Main(string[] args) { BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); } } } thrift-0.23.0/lib/netstd/Benchmarks/Thrift.Benchmarks/CompactProtocolBenchmarks.cs0000664000175000017500000000470415165535636030477 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.IO; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Thrift.Protocol; using Thrift.Transport.Client; namespace Thrift.Benchmarks { [MemoryDiagnoser] public class CompactProtocolBenchmarks { private MemoryStream? _Stream; private TProtocol? _Protocol; [Params(10000)] public int NumberOfOperationsPerIteration { get; set; } [GlobalSetup] public void GlobalSetup() { _Stream = new MemoryStream(); var transport = new TStreamTransport(_Stream, _Stream, null); _Protocol = new TCompactProtocol(transport); } [GlobalCleanup] public void GlobalCleanup() { _Protocol?.Dispose(); } [Benchmark] public async Task WriteString() { if ((_Protocol is null) || (_Stream is null)) throw new System.Exception("unexpected internal state"); for (int i = 0; i < NumberOfOperationsPerIteration; i++) { await _Protocol.WriteStringAsync("Thrift String Benchmark"); _Stream.Seek(0, SeekOrigin.Begin); } } [Benchmark] public async Task ReadString() { if ((_Protocol is null) || (_Stream is null)) throw new System.Exception("unexpected internal state"); await _Protocol.WriteStringAsync("Thrift String Benchmark"); for (int i = 0; i < NumberOfOperationsPerIteration; i++) { _Stream.Seek(0, SeekOrigin.Begin); await _Protocol.ReadStringAsync(); } } } } thrift-0.23.0/lib/netstd/build.cmd0000664000175000017500000000166315165535636017236 0ustar00buildbuild00000000000000@echo off rem /* rem * Licensed to the Apache Software Foundation (ASF) under one rem * or more contributor license agreements. See the NOTICE file rem * distributed with this work for additional information rem * regarding copyright ownership. The ASF licenses this file rem * to you under the Apache License, Version 2.0 (the rem * "License"); you may not use this file except in compliance rem * with the License. You may obtain a copy of the License at rem * rem * http://www.apache.org/licenses/LICENSE-2.0 rem * rem * Unless required by applicable law or agreed to in writing, rem * software distributed under the License is distributed on an rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY rem * KIND, either express or implied. See the License for the rem * specific language governing permissions and limitations rem * under the License. rem */ setlocal thrift -version dotnet --info dotnet build :eof thrift-0.23.0/lib/netstd/Tests/0000755000175000017500000000000015170007201016516 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/0000755000175000017500000000000015170007201021057 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj0000664000175000017500000000350215170007142024650 0ustar00buildbuild00000000000000 net10.0 latestMajor 0.23.0.0 enable thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Collections/0000775000175000017500000000000015165535636023365 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Collections/THashSetTests.cs0000664000175000017500000000414315165535636026424 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Collections; #pragma warning disable IDE0063 // simplify using namespace Thrift.Tests.Collections { // ReSharper disable once InconsistentNaming [TestClass] public class THashSetTests { [TestMethod] public void THashSet_Equals_Primitive_Test() { const int value = 1; var hashSet = new HashSet {value}; Assert.IsTrue(hashSet.Contains(value)); hashSet.Remove(value); Assert.IsTrue(hashSet.Count == 0); hashSet.Add(value); Assert.IsTrue(hashSet.Contains(value)); hashSet.Clear(); Assert.IsTrue(hashSet.Count == 0); var newArr = new int[1]; hashSet.Add(value); hashSet.CopyTo(newArr, 0); Assert.IsTrue(newArr.Contains(value)); var en = hashSet.GetEnumerator(); en.MoveNext(); Assert.IsTrue((int)en.Current == value); using (var ien = ((IEnumerable)hashSet).GetEnumerator()) { ien.MoveNext(); Assert.IsTrue(ien.Current == value); } } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs0000664000175000017500000002266615165535636027355 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.Xml; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Collections; namespace Thrift.Tests.Collections { // ReSharper disable once InconsistentNaming [TestClass] public class TCollectionsTests { //TODO: Add tests for IEnumerable with objects and primitive values inside [TestMethod] public void TCollection_List_Equals_Primitive_Test() { var collection1 = new List {1,2,3}; var collection2 = new List {1,2,3}; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_List_Equals_Primitive_Different_Test() { var collection1 = new List { 1, 2, 3 }; var collection2 = new List { 1, 2 }; Assert.IsFalse(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); collection2.Add(4); Assert.IsFalse(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_List_Equals_Objects_Test() { var collection1 = new List { new() { X = 1 }, new() { X = 2 } }; var collection2 = new List { new() { X = 1 }, new() { X = 2 } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_List_List_Equals_Objects_Test() { var collection1 = new List> { new() { new() { X = 1 }, new() { X = 2 } } }; var collection2 = new List> { new() { new() { X = 1 }, new() { X = 2 } } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); // SequenceEqual() calls Equals() of the inner list instead of SequenceEqual() } [TestMethod] public void TCollection_List_Equals_OneAndTheSameObject_Test() { var collection1 = new List { new() { X = 1 }, new() { X = 2 } }; var collection2 = collection1; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_Set_Equals_Primitive_Test() { var collection1 = new HashSet {1,2,3}; var collection2 = new HashSet {1,2,3}; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_Set_Equals_Primitive_Different_Test() { var collection1 = new HashSet { 1, 2, 3 }; var collection2 = new HashSet { 1, 2 }; Assert.IsFalse(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); collection2.Add(4); Assert.IsFalse(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_Set_Equals_Objects_Test() { var collection1 = new HashSet { new() { X = 1 }, new() { X = 2 } }; var collection2 = new HashSet { new() { X = 1 }, new() { X = 2 } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_Set_Set_Equals_Objects_Test() { var collection1 = new HashSet> { new() { new() { X = 1 }, new() { X = 2 } } }; var collection2 = new HashSet> { new() { new() { X = 1 }, new() { X = 2 } } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); // SequenceEqual() calls Equals() of the inner list instead of SequenceEqual() } [TestMethod] public void TCollection_Set_Equals_OneAndTheSameObject_Test() { var collection1 = new HashSet { new() { X = 1 }, new() { X = 2 } }; var collection2 = collection1; // references to one and the same collection Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_Map_Equals_Primitive_Test() { var collection1 = new Dictionary { [1] = 1, [2] = 2, [3] = 3 }; var collection2 = new Dictionary { [1] = 1, [2] = 2, [3] = 3 }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_Map_Equals_Primitive_Different_Test() { var collection1 = new Dictionary { [1] = 1, [2] = 2, [3] = 3 }; var collection2 = new Dictionary { [1] = 1, [2] = 2 }; Assert.IsFalse(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); collection2[3] = 3; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); collection2[3] = 4; Assert.IsFalse(TCollections.Equals(collection1, collection2)); } [TestMethod] public void TCollection_Map_Equals_Objects_Test() { var collection1 = new Dictionary { [1] = new() { X = 1 }, [-1] = new() { X = 2 } }; var collection2 = new Dictionary { [1] = new() { X = 1 }, [-1] = new() { X = 2 } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } [TestMethod] public void TCollection_Map_Map_Equals_Objects_Test() { var collection1 = new Dictionary> { [0] = new Dictionary { [1] = new() { X = 1 }, [-1] = new() { X = 2 } } }; var collection2 = new Dictionary> { [0] = new Dictionary { [1] = new() { X = 1 }, [-1] = new() { X = 2 } } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); // SequenceEqual() calls Equals() of the inner list instead of SequenceEqual() } [TestMethod] public void TCollection_Map_Equals_OneAndTheSameObject_Test() { var collection1 = new Dictionary { [1] = new() { X = 1 }, [-1] = new() { X = 2 } }; var collection2 = collection1; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } private class ExampleClass { public int X { get; set; } // all Thrift-generated classes override Equals(), we do just the same public override bool Equals(object? that) { if (that is not ExampleClass other) return false; if (ReferenceEquals(this, other)) return true; return this.X == other.X; } // overriding Equals() requires GetHashCode() as well public override int GetHashCode() { int hashcode = 157; unchecked { hashcode = (hashcode * 397) + X.GetHashCode(); } return hashcode; } } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Protocols/0000775000175000017500000000000015167543515023070 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs0000664000175000017500000000474315165535636027234 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Protocol; using Thrift.Protocol.Entities; using Thrift.Transport; using Thrift.Transport.Client; namespace Thrift.Tests.Protocols { // ReSharper disable once InconsistentNaming [TestClass] public class TJSONProtocolTests { [TestMethod] public void TJSONProtocol_Can_Create_Instance_Test() { var httpClientTransport = new THttpTransport( new Uri("http://localhost"), null, null, null); var result = new TJSONProtocolWrapper(httpClientTransport); Assert.IsNotNull(result); Assert.IsNotNull(result.WrappedContext); Assert.IsNotNull(result.WrappedReader); Assert.IsNotNull(result.Transport); Assert.IsTrue(result.WrappedRecursionDepth == 0); Assert.IsTrue(result.WrappedRecursionLimit == TConfiguration.DEFAULT_RECURSION_DEPTH); Assert.IsTrue(result.Transport.Equals(httpClientTransport)); Assert.IsTrue(result.WrappedContext.GetType().Name.Equals("JSONBaseContext", StringComparison.OrdinalIgnoreCase)); Assert.IsTrue(result.WrappedReader.GetType().Name.Equals("LookaheadReader", StringComparison.OrdinalIgnoreCase)); } private class TJSONProtocolWrapper(TTransport trans) : TJsonProtocol(trans) { public object WrappedContext => Context; public object WrappedReader => Reader; public int WrappedRecursionDepth => RecursionDepth; public int WrappedRecursionLimit => RecursionLimit; } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs0000664000175000017500000001540015167543515030361 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Protocol; using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; namespace Thrift.Tests.Protocols { [TestClass] public class TJSONProtocolHelperTests { [TestMethod] public void GetTypeNameForTypeId_Test() { // input/output var sets = new List> { new(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool), new(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte), new(TType.I16, TJSONProtocolConstants.TypeNames.NameI16), new(TType.I32, TJSONProtocolConstants.TypeNames.NameI32), new(TType.I64, TJSONProtocolConstants.TypeNames.NameI64), new(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble), new(TType.String, TJSONProtocolConstants.TypeNames.NameString), new(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct), new(TType.Map, TJSONProtocolConstants.TypeNames.NameMap), new(TType.Set, TJSONProtocolConstants.TypeNames.NameSet), new(TType.List, TJSONProtocolConstants.TypeNames.NameList), }; foreach (var t in sets) { Assert.AreEqual(t.Item2, TJSONProtocolHelper.GetTypeNameForTypeId(t.Item1), $"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}"); } } [TestMethod] public void GetTypeNameForTypeId_TStop_Test() { Assert.ThrowsExactly(() => TJSONProtocolHelper.GetTypeNameForTypeId(TType.Stop)); } [TestMethod] public void GetTypeNameForTypeId_NonExistingTType_Test() { Assert.ThrowsExactly(() => TJSONProtocolHelper.GetTypeNameForTypeId((TType)100)); } [TestMethod] public void GetTypeIdForTypeName_Test() { // input/output var sets = new List> { new(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool), new(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte), new(TType.I16, TJSONProtocolConstants.TypeNames.NameI16), new(TType.I32, TJSONProtocolConstants.TypeNames.NameI32), new(TType.I64, TJSONProtocolConstants.TypeNames.NameI64), new(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble), new(TType.String, TJSONProtocolConstants.TypeNames.NameString), new(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct), new(TType.Map, TJSONProtocolConstants.TypeNames.NameMap), new(TType.Set, TJSONProtocolConstants.TypeNames.NameSet), new(TType.List, TJSONProtocolConstants.TypeNames.NameList), }; foreach (var t in sets) { Assert.AreEqual(t.Item1, TJSONProtocolHelper.GetTypeIdForTypeName(t.Item2), $"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}"); } } [TestMethod] public void GetTypeIdForTypeName_TStopTypeName_Test() { Assert.ThrowsExactly(() => TJSONProtocolHelper.GetTypeIdForTypeName([(byte)TType.Stop, (byte)TType.Stop])); } [TestMethod] public void GetTypeIdForTypeName_NonExistingTypeName_Test() { Assert.ThrowsExactly(() => TJSONProtocolHelper.GetTypeIdForTypeName([100])); } [TestMethod] public void GetTypeIdForTypeName_EmptyName_Test() { Assert.ThrowsExactly(() => TJSONProtocolHelper.GetTypeIdForTypeName([])); } [TestMethod] public void IsJsonNumeric_Test() { // input/output var correctJsonNumeric = "+-.0123456789Ee"; var incorrectJsonNumeric = "AaBcDd/*\\"; var sets = correctJsonNumeric.Select(ch => new Tuple((byte) ch, true)).ToList(); sets.AddRange(incorrectJsonNumeric.Select(ch => new Tuple((byte) ch, false))); foreach (var t in sets) { Assert.AreEqual(t.Item2, TJSONProtocolHelper.IsJsonNumeric(t.Item1), $"Wrong mapping of Char {t.Item1} to bool: {t.Item2}"); } } [TestMethod] public void ToHexVal_Test() { // input/output var chars = "0123456789abcdef"; var expectedHexValues = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; var sets = chars.Select((ch, i) => new Tuple(ch, expectedHexValues[i])).ToList(); foreach (var t in sets) { var actualResult = TJSONProtocolHelper.ToHexVal((byte)t.Item1); Assert.AreEqual(t.Item2, actualResult, $"Wrong mapping of char byte {t.Item1} to it expected hex value: {t.Item2}. Actual hex value: {actualResult}"); } } [TestMethod] public void ToHexVal_WrongInputChar_Test() { Assert.ThrowsExactly(() => TJSONProtocolHelper.ToHexVal((byte)'s')); } [TestMethod] public void ToHexChar_Test() { // input/output var hexValues = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; var expectedChars = "0123456789abcdef"; var sets = hexValues.Select((hv, i) => new Tuple(hv, expectedChars[i])).ToList(); foreach (var t in sets) { var actualResult = (char)TJSONProtocolHelper.ToHexChar(t.Item1); Assert.AreEqual(t.Item2, actualResult, $"Wrong mapping of hex value {t.Item1} to it expected char: {t.Item2}. Actual hex value: {actualResult}"); } } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Transports/0000775000175000017500000000000015165535636023266 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/Transports/THttpTransportTests.cs0000664000175000017500000000265015165535636027623 0ustar00buildbuild00000000000000// 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.Net.Http; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Transport.Client; namespace Thrift.Tests.Transports { [TestClass] public class THttpTransportTests { [TestMethod] public void THttpTransport_Uses_Configured_ConnectionTimeout_Test() { var client = new HttpClient(); var httpClientTransport = new THttpTransport(client, null) { ConnectTimeout = 5000 }; Assert.IsTrue(client.Timeout.TotalMilliseconds == 5000); Assert.IsTrue(httpClientTransport.ConnectTimeout == 5000); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/DataModel/0000775000175000017500000000000015165535636022741 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs0000664000175000017500000000727115165535636026045 0ustar00buildbuild00000000000000// 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.Linq; using System.Text; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; using OptReqDefTest; using Thrift.Collections; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0017 // init can be simplified - we don't want that here namespace Thrift.Tests.DataModel { // ReSharper disable once InconsistentNaming [TestClass] public class Thrift_5238 { private static void CheckInstance(RaceDetails instance) { // object Assert.IsTrue(instance.__isset.def_nested); Assert.IsTrue(instance.__isset.opt_nested); Assert.IsNull(instance.Def_nested); Assert.IsNull(instance.Opt_nested); // string Assert.IsTrue(instance.__isset.def_four); Assert.IsTrue(instance.__isset.opt_four); Assert.IsTrue(string.IsNullOrEmpty(instance.Req_four)); Assert.IsNull(instance.Def_four); Assert.IsNull(instance.Opt_four); // list<> Assert.IsTrue(instance.__isset.def_six); Assert.IsTrue(instance.__isset.opt_six); Assert.IsNull(instance.Req_six); Assert.IsNull(instance.Opt_six); Assert.IsNull(instance.Def_six); // byte[] Assert.IsTrue(instance.__isset.def_nine); Assert.IsTrue(instance.__isset.opt_nine); Assert.IsTrue((instance.Req_nine == null) || (instance.Req_nine.Length == 0)); Assert.IsNull(instance.Def_nine); Assert.IsNull(instance.Opt_nine); } [TestMethod] public void Thrift_5238_ProperNullChecks() { var instance = new OptReqDefTest.RaceDetails(); // the following code INTENTIONALLY assigns null to non.nullable reftypes #pragma warning disable CS8625 // object instance.Def_nested = null; instance.Opt_nested = null; // string instance.Req_four = null; instance.Def_four = null; instance.Opt_four = null; // list<> instance.Req_six = null; instance.Opt_six = null; instance.Def_six = null; // byte[] instance.Req_nine = null; instance.Def_nine = null; instance.Opt_nine = null; // back to normal #pragma warning restore CS8625 // test the setup CheckInstance(instance); // validate proper null checks, any of these throws if not instance.ToString(); instance.GetHashCode(); // validate proper null checks, any of these throws if not var copy = instance.DeepCopy(); CheckInstance(copy); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs0000664000175000017500000007220615165535636025007 0ustar00buildbuild00000000000000// 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.Linq; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using OptReqDefTest; using Thrift.Collections; namespace Thrift.Tests.DataModel { // ReSharper disable once InconsistentNaming [TestClass] public class DeepCopyTests { [TestMethod] public void Test_Complex_DeepCopy() { var first = InitializeInstance(new RaceDetails()); VerifyIdenticalContent(first, InitializeInstance(new RaceDetails())); var second = first.DeepCopy(); VerifyIdenticalContent(first, second); ModifyInstance(second,0); VerifyDifferentContent(first, second); VerifyIdenticalContent(first, InitializeInstance(new RaceDetails())); var third = second.DeepCopy(); VerifyIdenticalContent(second, third); ModifyInstance(third,0); VerifyDifferentContent(second, third); VerifyIdenticalContent(first, InitializeInstance(new RaceDetails())); } private RaceDetails? MakeNestedRaceDetails(int nesting) { if (++nesting > 1) return null; var instance = new RaceDetails(); InitializeInstance(instance,nesting); return instance; } private jack.nested_struct? MakeNestedUnion(int nesting) { if (++nesting > 1) return null; var details = new RaceDetails(); InitializeInstance(details,nesting); return new jack.nested_struct(details); } private RaceDetails InitializeInstance(RaceDetails instance, int nesting = 0) { // at init, we intentionally leave all non-required fields unset Assert.IsFalse(instance.__isset.opt_one); Assert.IsFalse(instance.__isset.opt_two); Assert.IsFalse(instance.__isset.opt_three); Assert.IsFalse(instance.__isset.opt_four); Assert.IsFalse(instance.__isset.opt_five); Assert.IsFalse(instance.__isset.opt_six); Assert.IsFalse(instance.__isset.opt_seven); Assert.IsFalse(instance.__isset.opt_eight); Assert.IsFalse(instance.__isset.opt_nine); // set all required to null/default instance.Req_one = default; instance.Req_two = default; instance.Req_three = default; Assert.IsNotNull(instance.Req_four); instance.Req_five = default; instance.Req_six = default; instance.Req_seven = default; instance.Req_eight = default; Assert.IsNotNull(instance.Req_nine); // leave non-required fields unset again Assert.IsFalse(instance.__isset.def_one); Assert.IsFalse(instance.__isset.def_two); Assert.IsFalse(instance.__isset.def_three); Assert.IsFalse(instance.__isset.def_four); Assert.IsFalse(instance.__isset.def_five); Assert.IsFalse(instance.__isset.def_six); Assert.IsFalse(instance.__isset.def_seven); Assert.IsFalse(instance.__isset.def_eight); Assert.IsFalse(instance.__isset.def_nine); // these should have IDL defaults set Assert.IsTrue(instance.__isset.opt_one_with_value); Assert.IsTrue(instance.__isset.opt_two_with_value); Assert.IsTrue(instance.__isset.opt_three_with_value); Assert.IsTrue(instance.__isset.opt_four_with_value); Assert.IsTrue(instance.__isset.opt_five_with_value); Assert.IsTrue(instance.__isset.opt_six_with_value); Assert.IsTrue(instance.__isset.opt_seven_with_value); Assert.IsTrue(instance.__isset.opt_eight_with_value); Assert.IsTrue(instance.__isset.opt_nine_with_value); Assert.AreEqual(instance.Req_one_with_value, (Distance)1); Assert.AreEqual(instance.Req_two_with_value, 2.22); Assert.AreEqual(instance.Req_three_with_value, 3); Assert.AreEqual(instance.Req_four_with_value, "four"); Assert.AreEqual(new Guid("55555555-5555-5555-5555-000000000000"), instance.Req_five_with_value); Assert.IsTrue(instance.Req_six_with_value!.Count == 1); Assert.AreEqual(instance.Req_six_with_value[0], 6 ); Assert.IsTrue(instance.Req_seven_with_value!.Count == 1); Assert.IsTrue(instance.Req_seven_with_value.Contains(7)); Assert.IsTrue(instance.Req_eight_with_value!.Count == 1); Assert.IsTrue(instance.Req_eight_with_value[8] == 8); Assert.AreEqual("nine", Encoding.UTF8.GetString(instance.Req_nine_with_value!)); Assert.IsTrue(instance.__isset.def_one_with_value); Assert.IsTrue(instance.__isset.def_two_with_value); Assert.IsTrue(instance.__isset.def_three_with_value); Assert.IsTrue(instance.__isset.def_four_with_value); Assert.IsTrue(instance.__isset.def_five_with_value); Assert.IsTrue(instance.__isset.def_six_with_value); Assert.IsTrue(instance.__isset.def_seven_with_value); Assert.IsTrue(instance.__isset.def_eight_with_value); Assert.IsTrue(instance.__isset.def_nine_with_value); instance.Last_of_the_mohicans = true; if (nesting < 2) { instance.Far_list = [Distance.foo, Distance.bar, Distance.baz]; instance.Far_set = [Distance.foo, Distance.bar, Distance.baz]; instance.Far_map = new() { [Distance.foo] = Distance.foo, [Distance.bar] = Distance.bar, [Distance.baz] = Distance.baz }; instance.Far_set_list = [[Distance.foo]]; instance.Far_list_map_set = [new Dictionary>() { [1] = [Distance.baz] }]; instance.Far_map_dist_to_rds = new() { [Distance.bar] = [] }; var details = MakeNestedRaceDetails(nesting); if (details != null) instance.Far_map_dist_to_rds[Distance.bar].Add(details); instance.Req_nested = MakeNestedRaceDetails(nesting); Assert.IsFalse(instance.__isset.opt_nested); Assert.IsFalse(instance.__isset.def_nested); instance.Req_union = MakeNestedUnion(nesting); Assert.IsFalse(instance.__isset.opt_union); Assert.IsFalse(instance.__isset.def_union); } instance.Triplesix = (Distance)666; return instance; } private void ModifyInstance(RaceDetails instance, int level) { if ((instance == null) || (++level > 4)) return; instance.Opt_one = ModifyValue(instance.Opt_one); instance.Opt_two = ModifyValue(instance.Opt_two); instance.Opt_three = ModifyValue(instance.Opt_three); instance.Opt_four = ModifyValue(instance.Opt_four); instance.Opt_five = ModifyValue(instance.Opt_five); instance.Opt_six = ModifyValue(instance.Opt_six); instance.Opt_seven = ModifyValue(instance.Opt_seven); instance.Opt_eight = ModifyValue(instance.Opt_eight); instance.Opt_nine = ModifyValue(instance.Opt_nine); instance.Req_one = ModifyValue(instance.Req_one); instance.Req_two = ModifyValue(instance.Req_two); instance.Req_three = ModifyValue(instance.Req_three); instance.Req_four = ModifyValue(instance.Req_four); instance.Req_five = ModifyValue(instance.Req_five); instance.Req_six = ModifyValue(instance.Req_six); instance.Req_seven = ModifyValue(instance.Req_seven); instance.Req_eight = ModifyValue(instance.Req_eight); instance.Req_nine = ModifyValue(instance.Req_nine); instance.Def_one = ModifyValue(instance.Def_one); instance.Def_two = ModifyValue(instance.Def_two); instance.Def_three = ModifyValue(instance.Def_three); instance.Def_four = ModifyValue(instance.Def_four); instance.Def_five = ModifyValue(instance.Def_five); instance.Def_six = ModifyValue(instance.Def_six); instance.Def_seven = ModifyValue(instance.Def_seven); instance.Def_eight = ModifyValue(instance.Def_eight); instance.Def_nine = ModifyValue(instance.Def_nine); instance.Opt_one_with_value = ModifyValue(instance.Opt_one_with_value); instance.Opt_two_with_value = ModifyValue(instance.Opt_two_with_value); instance.Opt_three_with_value = ModifyValue(instance.Opt_three_with_value); instance.Opt_four_with_value = ModifyValue(instance.Opt_four_with_value); instance.Opt_five_with_value = ModifyValue(instance.Opt_five_with_value); instance.Opt_six_with_value = ModifyValue(instance.Opt_six_with_value); instance.Opt_seven_with_value = ModifyValue(instance.Opt_seven_with_value); instance.Opt_eight_with_value = ModifyValue(instance.Opt_eight_with_value); instance.Opt_nine_with_value = ModifyValue(instance.Opt_nine_with_value); instance.Req_one_with_value = ModifyValue(instance.Req_one_with_value); instance.Req_two_with_value = ModifyValue(instance.Req_two_with_value); instance.Req_three_with_value = ModifyValue(instance.Req_three_with_value); instance.Req_four_with_value = ModifyValue(instance.Req_four_with_value); instance.Req_five_with_value = ModifyValue(instance.Req_five_with_value); instance.Req_six_with_value = ModifyValue(instance.Req_six_with_value); instance.Req_seven_with_value = ModifyValue(instance.Req_seven_with_value); instance.Req_eight_with_value = ModifyValue(instance.Req_eight_with_value); instance.Req_nine_with_value = ModifyValue(instance.Req_nine_with_value); instance.Def_one_with_value = ModifyValue(instance.Def_one_with_value); instance.Def_two_with_value = ModifyValue(instance.Def_two_with_value); instance.Def_three_with_value = ModifyValue(instance.Def_three_with_value); instance.Def_four_with_value = ModifyValue(instance.Def_four_with_value); instance.Def_five_with_value = ModifyValue(instance.Def_five_with_value); instance.Def_six_with_value = ModifyValue(instance.Def_six_with_value); instance.Def_seven_with_value = ModifyValue(instance.Def_seven_with_value); instance.Def_eight_with_value = ModifyValue(instance.Def_eight_with_value); instance.Def_nine_with_value = ModifyValue(instance.Def_nine_with_value); instance.Last_of_the_mohicans = ModifyValue(instance.Last_of_the_mohicans); instance.Far_list = ModifyValue(instance.Far_list); instance.Far_set = ModifyValue(instance.Far_set); instance.Far_map = ModifyValue(instance.Far_map); instance.Far_set_list = ModifyValue(instance.Far_set_list); instance.Far_list_map_set = ModifyValue(instance.Far_list_map_set); instance.Far_map_dist_to_rds = ModifyValue(instance.Far_map_dist_to_rds, level); instance.Req_nested = ModifyValue(instance.Req_nested, level); instance.Opt_nested = ModifyValue(instance.Opt_nested, level); instance.Def_nested = ModifyValue(instance.Def_nested, level); instance.Req_union = ModifyValue(instance.Req_union, level); instance.Opt_union = ModifyValue(instance.Opt_union, level); instance.Def_union = ModifyValue(instance.Def_union, level); instance.Triplesix = ModifyValue(instance.Triplesix); } private jack? ModifyValue(jack? value, int level) { if (++level > 4) return value; value ??= MakeNestedUnion(0); Debug.Assert(value?.As_nested_struct != null); ModifyInstance(value.As_nested_struct, level); return value; } private RaceDetails? ModifyValue(RaceDetails? value, int level) { if (++level > 4) return value; value ??= new RaceDetails(); ModifyInstance(value,level); return value; } private Dictionary> ModifyValue(Dictionary>? value, int level) { value ??= []; if (++level > 4) return value; var details = new RaceDetails(); InitializeInstance(details); value[Distance.foo] = [details]; if (value.TryGetValue(Distance.bar, out var list) && (list.Count > 0)) { ModifyInstance(list[0], level); //list.Add(null); -- Thrift does not allow null values in containers } // Thrift does not allow null values in containers //value[Distance.baz] = null; return value; } private static List>> ModifyValue(List>>? value) { value ??= []; if (value.Count == 0) value.Add([]); //else //value.Add(null); --Thrift does not allow null values in containers sbyte key = (sbyte)(value[0].Count + 10); if (value[0].Count == 0) value[0].Add(key, []); //else //value[0].Add(key, null); --Thrift does not allow null values in containers foreach (var entry in value) { if (entry != null) { foreach (var pair in entry) { if (pair.Value != null) { if (!pair.Value.Remove(Distance.baz)) pair.Value.Add(Distance.baz); } } } } return value; } private static HashSet> ModifyValue(HashSet>? value) { value ??= []; if (value.Count == 0) value.Add([]); //else //value.Add(null); -- Thrift does not allow null values in containers foreach (var entry in value) entry?.Add(Distance.baz); return value; } private static Dictionary ModifyValue(Dictionary? value) { value ??= []; value[Distance.foo] = value.ContainsKey(Distance.foo) ? ++value[Distance.foo] : Distance.foo; value[Distance.bar] = value.ContainsKey(Distance.bar) ? ++value[Distance.bar] : Distance.bar; value[Distance.baz] = value.ContainsKey(Distance.baz) ? ++value[Distance.baz] : Distance.baz; return value; } private static HashSet ModifyValue(HashSet? value) { value ??= []; if (!value.Remove(Distance.foo)) value.Add(Distance.foo); if (!value.Remove(Distance.bar)) value.Add(Distance.bar); if (!value.Remove(Distance.baz)) value.Add(Distance.baz); return value; } private static List ModifyValue(List? value) { value ??= []; value.Add(Distance.foo); value.Add(Distance.bar); value.Add(Distance.baz); return value; } private static bool ModifyValue(bool value) { return !value; } private static Dictionary ModifyValue(Dictionary? value) { value ??= []; value.Add((sbyte)(value.Count + 10), (short)value.Count); return value; } private static HashSet ModifyValue(HashSet? value) { value ??= []; value.Add(value.Count+100); return value; } private static List ModifyValue(List? value) { value ??= []; value.Add(value.Count); return value; } private static byte[] ModifyValue(byte[]? value) { value ??= [0]; if (value.Length > 0) value[0] = (value[0] < 0xFF) ? ++value[0] : (byte)0; else value = [0]; return value; } private static string ModifyValue(string? value) { return value + "1"; } private static Guid ModifyValue(Guid value) { return new Guid( ModifyValue(value.ToByteArray())); } private static double ModifyValue(double value) { return value + 1.1; } private static short ModifyValue(short value) { return ++value; } private static Distance ModifyValue(Distance value) { return ++value; } private static void VerifyDifferentContent(RaceDetails first, RaceDetails second) { Assert.AreNotEqual(first, second); Assert.AreNotEqual(first.Opt_two, second.Opt_two); Assert.AreNotEqual(first.Opt_three, second.Opt_three); Assert.AreNotEqual(first.Opt_four, second.Opt_four); Assert.IsFalse(TCollections.Equals(first.Opt_five, second.Opt_five)); Assert.IsFalse(TCollections.Equals(first.Opt_six, second.Opt_six)); Assert.IsFalse(TCollections.Equals(first.Opt_seven, second.Opt_seven)); Assert.IsFalse(TCollections.Equals(first.Opt_eight, second.Opt_eight)); Assert.IsFalse(TCollections.Equals(first.Opt_nine, second.Opt_nine)); Assert.AreNotEqual(first.Req_one, second.Req_one); Assert.AreNotEqual(first.Req_two, second.Req_two); Assert.AreNotEqual(first.Req_three, second.Req_three); Assert.AreNotEqual(first.Req_four, second.Req_four); Assert.IsFalse(TCollections.Equals(first.Req_five, second.Req_five)); Assert.IsFalse(TCollections.Equals(first.Req_six, second.Req_six)); Assert.IsFalse(TCollections.Equals(first.Req_seven, second.Req_seven)); Assert.IsFalse(TCollections.Equals(first.Req_eight, second.Req_eight)); Assert.IsFalse(TCollections.Equals(first.Req_nine, second.Req_nine)); Assert.AreNotEqual(first.Def_one, second.Def_one); Assert.AreNotEqual(first.Def_two, second.Def_two); Assert.AreNotEqual(first.Def_three, second.Def_three); Assert.AreNotEqual(first.Def_four, second.Def_four); Assert.IsFalse(TCollections.Equals(first.Def_five, second.Def_five)); Assert.IsFalse(TCollections.Equals(first.Def_six, second.Def_six)); Assert.IsFalse(TCollections.Equals(first.Def_seven, second.Def_seven)); Assert.IsFalse(TCollections.Equals(first.Def_eight, second.Def_eight)); Assert.IsFalse(TCollections.Equals(first.Def_nine, second.Def_nine)); Assert.AreNotEqual(first.Opt_one_with_value, second.Opt_one_with_value); Assert.AreNotEqual(first.Opt_two_with_value, second.Opt_two_with_value); Assert.AreNotEqual(first.Opt_three_with_value, second.Opt_three_with_value); Assert.AreNotEqual(first.Opt_four_with_value, second.Opt_four_with_value); Assert.IsFalse(TCollections.Equals(first.Opt_five_with_value, second.Opt_five_with_value)); Assert.IsFalse(TCollections.Equals(first.Opt_six_with_value, second.Opt_six_with_value)); Assert.IsFalse(TCollections.Equals(first.Opt_seven_with_value, second.Opt_seven_with_value)); Assert.IsFalse(TCollections.Equals(first.Opt_eight_with_value, second.Opt_eight_with_value)); Assert.IsFalse(TCollections.Equals(first.Opt_nine_with_value, second.Opt_nine_with_value)); Assert.AreNotEqual(first.Req_one_with_value, second.Req_one_with_value); Assert.AreNotEqual(first.Req_two_with_value, second.Req_two_with_value); Assert.AreNotEqual(first.Req_three_with_value, second.Req_three_with_value); Assert.AreNotEqual(first.Req_four_with_value, second.Req_four_with_value); Assert.IsFalse(TCollections.Equals(first.Req_five_with_value, second.Req_five_with_value)); Assert.IsFalse(TCollections.Equals(first.Req_six_with_value, second.Req_six_with_value)); Assert.IsFalse(TCollections.Equals(first.Req_seven_with_value, second.Req_seven_with_value)); Assert.IsFalse(TCollections.Equals(first.Req_eight_with_value, second.Req_eight_with_value)); Assert.IsFalse(TCollections.Equals(first.Req_nine_with_value, second.Req_nine_with_value)); Assert.AreNotEqual(first.Def_one_with_value, second.Def_one_with_value); Assert.AreNotEqual(first.Def_two_with_value, second.Def_two_with_value); Assert.AreNotEqual(first.Def_three_with_value, second.Def_three_with_value); Assert.AreNotEqual(first.Def_four_with_value, second.Def_four_with_value); Assert.IsFalse(TCollections.Equals(first.Def_five_with_value, second.Def_five_with_value)); Assert.IsFalse(TCollections.Equals(first.Def_six_with_value, second.Def_six_with_value)); Assert.IsFalse(TCollections.Equals(first.Def_seven_with_value, second.Def_seven_with_value)); Assert.IsFalse(TCollections.Equals(first.Def_eight_with_value, second.Def_eight_with_value)); Assert.IsFalse(TCollections.Equals(first.Def_nine_with_value, second.Def_nine_with_value)); Assert.AreNotEqual(first.Last_of_the_mohicans, second.Last_of_the_mohicans); Assert.IsFalse(TCollections.Equals(first.Far_list, second.Far_list)); Assert.IsFalse(TCollections.Equals(first.Far_set, second.Far_set)); Assert.IsFalse(TCollections.Equals(first.Far_map, second.Far_map)); Assert.IsFalse(TCollections.Equals(first.Far_set_list, second.Far_set_list)); Assert.IsFalse(TCollections.Equals(first.Far_list_map_set, second.Far_list_map_set)); Assert.IsFalse(TCollections.Equals(first.Far_map_dist_to_rds, second.Far_map_dist_to_rds)); Assert.AreNotEqual(first.Req_nested, second.Req_nested); Assert.AreNotEqual(first.Opt_nested, second.Opt_nested); Assert.AreNotEqual(first.Def_nested, second.Def_nested); Assert.AreNotEqual(first.Req_union, second.Req_union); Assert.AreNotEqual(first.Opt_union, second.Opt_union); Assert.AreNotEqual(first.Def_union, second.Def_union); Assert.AreNotEqual(first.Triplesix, second.Triplesix); } private static void VerifyIdenticalContent(RaceDetails first, RaceDetails second) { Assert.AreEqual(first, second); Assert.AreEqual(first.Opt_two, second.Opt_two); Assert.AreEqual(first.Opt_three, second.Opt_three); Assert.AreEqual(first.Opt_four, second.Opt_four); Assert.IsTrue(TCollections.Equals(first.Opt_five, second.Opt_five)); Assert.IsTrue(TCollections.Equals(first.Opt_six, second.Opt_six)); Assert.IsTrue(TCollections.Equals(first.Opt_seven, second.Opt_seven)); Assert.IsTrue(TCollections.Equals(first.Opt_eight, second.Opt_eight)); Assert.IsTrue(TCollections.Equals(first.Opt_nine, second.Opt_nine)); Assert.AreEqual(first.Req_one, second.Req_one); Assert.AreEqual(first.Req_two, second.Req_two); Assert.AreEqual(first.Req_three, second.Req_three); Assert.AreEqual(first.Req_four, second.Req_four); Assert.IsTrue(TCollections.Equals(first.Req_five, second.Req_five)); Assert.IsTrue(TCollections.Equals(first.Req_six, second.Req_six)); Assert.IsTrue(TCollections.Equals(first.Req_seven, second.Req_seven)); Assert.IsTrue(TCollections.Equals(first.Req_eight, second.Req_eight)); Assert.IsTrue(TCollections.Equals(first.Req_nine, second.Req_nine)); Assert.AreEqual(first.Def_one, second.Def_one); Assert.AreEqual(first.Def_two, second.Def_two); Assert.AreEqual(first.Def_three, second.Def_three); Assert.AreEqual(first.Def_four, second.Def_four); Assert.IsTrue(TCollections.Equals(first.Def_five, second.Def_five)); Assert.IsTrue(TCollections.Equals(first.Def_six, second.Def_six)); Assert.IsTrue(TCollections.Equals(first.Def_seven, second.Def_seven)); Assert.IsTrue(TCollections.Equals(first.Def_eight, second.Def_eight)); Assert.IsTrue(TCollections.Equals(first.Def_nine, second.Def_nine)); Assert.AreEqual(first.Opt_one_with_value, second.Opt_one_with_value); Assert.AreEqual(first.Opt_two_with_value, second.Opt_two_with_value); Assert.AreEqual(first.Opt_three_with_value, second.Opt_three_with_value); Assert.AreEqual(first.Opt_four_with_value, second.Opt_four_with_value); Assert.IsTrue(TCollections.Equals(first.Opt_five_with_value, second.Opt_five_with_value)); Assert.IsTrue(TCollections.Equals(first.Opt_six_with_value, second.Opt_six_with_value)); Assert.IsTrue(TCollections.Equals(first.Opt_seven_with_value, second.Opt_seven_with_value)); Assert.IsTrue(TCollections.Equals(first.Opt_eight_with_value, second.Opt_eight_with_value)); Assert.IsTrue(TCollections.Equals(first.Opt_nine_with_value, second.Opt_nine_with_value)); Assert.AreEqual(first.Req_one_with_value, second.Req_one_with_value); Assert.AreEqual(first.Req_two_with_value, second.Req_two_with_value); Assert.AreEqual(first.Req_three_with_value, second.Req_three_with_value); Assert.AreEqual(first.Req_four_with_value, second.Req_four_with_value); Assert.IsTrue(TCollections.Equals(first.Req_five_with_value, second.Req_five_with_value)); Assert.IsTrue(TCollections.Equals(first.Req_six_with_value, second.Req_six_with_value)); Assert.IsTrue(TCollections.Equals(first.Req_seven_with_value, second.Req_seven_with_value)); Assert.IsTrue(TCollections.Equals(first.Req_eight_with_value, second.Req_eight_with_value)); Assert.IsTrue(TCollections.Equals(first.Req_nine_with_value, second.Req_nine_with_value)); Assert.AreEqual(first.Def_one_with_value, second.Def_one_with_value); Assert.AreEqual(first.Def_two_with_value, second.Def_two_with_value); Assert.AreEqual(first.Def_three_with_value, second.Def_three_with_value); Assert.AreEqual(first.Def_four_with_value, second.Def_four_with_value); Assert.IsTrue(TCollections.Equals(first.Def_five_with_value, second.Def_five_with_value)); Assert.IsTrue(TCollections.Equals(first.Def_six_with_value, second.Def_six_with_value)); Assert.IsTrue(TCollections.Equals(first.Def_seven_with_value, second.Def_seven_with_value)); Assert.IsTrue(TCollections.Equals(first.Def_eight_with_value, second.Def_eight_with_value)); Assert.IsTrue(TCollections.Equals(first.Def_nine_with_value, second.Def_nine_with_value)); Assert.AreEqual(first.Last_of_the_mohicans, second.Last_of_the_mohicans); Assert.IsTrue(TCollections.Equals(first.Far_list, second.Far_list)); Assert.IsTrue(TCollections.Equals(first.Far_set, second.Far_set)); Assert.IsTrue(TCollections.Equals(first.Far_map, second.Far_map)); Assert.IsTrue(TCollections.Equals(first.Far_set_list, second.Far_set_list)); Assert.IsTrue(TCollections.Equals(first.Far_list_map_set, second.Far_list_map_set)); Assert.IsTrue(TCollections.Equals(first.Far_map_dist_to_rds, second.Far_map_dist_to_rds)); Assert.AreEqual(first.Req_nested, second.Req_nested); Assert.AreEqual(first.Opt_nested, second.Opt_nested); Assert.AreEqual(first.Def_nested, second.Def_nested); Assert.AreEqual(first.Req_union, second.Req_union); Assert.AreEqual(first.Opt_union, second.Opt_union); Assert.AreEqual(first.Def_union, second.Def_union); Assert.AreEqual(first.Triplesix, second.Triplesix); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Tests/DataModel/ExceptionAsStruct.cs0000664000175000017500000001042715165535636026723 0ustar00buildbuild00000000000000// 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]); } } } } thrift-0.23.0/lib/netstd/Tests/Thrift.IntegrationTests/0000755000175000017500000000000015170007201023263 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/0000775000175000017500000000000015167543515025274 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolConformityTests.cs0000664000175000017500000000652415165535636032533 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; using KellermanSoftware.CompareNetObjects; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Protocol; using Thrift.Protocol.Entities; using Thrift.Transport; using Thrift.Transport.Client; namespace Thrift.IntegrationTests.Protocols { [TestClass] public class ProtocolConformityTests : TestBase { [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task ReadUuidFromStream(Type protocolType) { var expected = new Guid("{00112233-4455-6677-8899-aabbccddeeff}"); try { var tuple = GetProtocolInstance(protocolType); using var stream = tuple.Stream; await GenerateGuidTestData(stream, protocolType, default); stream.Seek(0, SeekOrigin.Begin); tuple.Transport.ResetMessageSizeAndConsumedBytes(); // length has changed var actual = await tuple.Protocol.ReadUuidAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } private static async Task GenerateGuidTestData(Stream stream, Type protocolType, CancellationToken cancel) { stream.Seek(0, SeekOrigin.Begin); if(protocolType == typeof(TJsonProtocol)) { await stream.WriteAsync(Encoding.UTF8.GetBytes("\"00112233-4455-6677-8899-aabbccddeeff\""), cancel); return; } if (protocolType == typeof(TBinaryProtocol)) { var data = new byte[16] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; await stream.WriteAsync(data, cancel); return; } if (protocolType == typeof(TCompactProtocol)) { var data = new byte[16] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; await stream.WriteAsync(data, cancel); return; } throw new Exception($"Unhandled protocol: {protocolType.FullName}"); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/TestBase.cs0000664000175000017500000000355415165535636027347 0ustar00buildbuild00000000000000// 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 KellermanSoftware.CompareNetObjects; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Thrift.Protocol; using Thrift.Transport; using Thrift.Transport.Client; namespace Thrift.IntegrationTests.Protocols { public class TestBase { protected readonly CompareLogic _compareLogic = new(); protected static readonly TConfiguration Configuration = new(); protected record struct ProtocolTransportStack(Stream Stream, TTransport Transport, TProtocol Protocol); protected 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 ProtocolTransportStack(memoryStream, streamClientTransport, protocol); throw new Exception("Unexpected"); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs0000664000175000017500000004656415167543515032715 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.IO; using System.Text; using System.Threading.Tasks; using KellermanSoftware.CompareNetObjects; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Protocol; using Thrift.Protocol.Entities; using Thrift.Transport; using Thrift.Transport.Client; #pragma warning disable IDE0063 // using namespace Thrift.IntegrationTests.Protocols { [TestClass] public class ProtocolsOperationsTests : TestBase { [TestMethod] [DataRow(typeof(TBinaryProtocol), TMessageType.Call)] [DataRow(typeof(TBinaryProtocol), TMessageType.Exception)] [DataRow(typeof(TBinaryProtocol), TMessageType.Oneway)] [DataRow(typeof(TBinaryProtocol), TMessageType.Reply)] [DataRow(typeof(TCompactProtocol), TMessageType.Call)] [DataRow(typeof(TCompactProtocol), TMessageType.Exception)] [DataRow(typeof(TCompactProtocol), TMessageType.Oneway)] [DataRow(typeof(TCompactProtocol), TMessageType.Reply)] [DataRow(typeof(TJsonProtocol), TMessageType.Call)] [DataRow(typeof(TJsonProtocol), TMessageType.Exception)] [DataRow(typeof(TJsonProtocol), TMessageType.Oneway)] [DataRow(typeof(TJsonProtocol), TMessageType.Reply)] public async Task WriteReadMessage_Test(Type protocolType, TMessageType messageType) { var expected = new TMessage(nameof(TMessage), messageType, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteMessageBeginAsync(expected, default); await protocol.WriteMessageEndAsync(default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actualMessage = await protocol.ReadMessageBeginAsync(default); await protocol.ReadMessageEndAsync(default); var result = _compareLogic.Compare(expected, actualMessage); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadStruct_Test(Type protocolType) { var expected = new TStruct(nameof(TStruct)); await Assert.ThrowsAsync(async () => { try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteStructBeginAsync(expected, default); await protocol.WriteStructEndAsync(default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadStructBeginAsync(default); await protocol.ReadStructEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } }); } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadField_Test(Type protocolType) { var expected = new TField(nameof(TField), TType.String, 1); await Assert.ThrowsAsync(async() => { try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteFieldBeginAsync(expected, default); await protocol.WriteFieldEndAsync(default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadFieldBeginAsync(default); await protocol.ReadFieldEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } }); } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadMap_Test(Type protocolType) { var expected = new TMap(TType.String, TType.String, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteMapBeginAsync(expected, default); await protocol.WriteMapEndAsync(default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadMapBeginAsync(default); await protocol.ReadMapEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadList_Test(Type protocolType) { var expected = new TList(TType.String, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteListBeginAsync(expected, default); await protocol.WriteListEndAsync(default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadListBeginAsync(default); await protocol.ReadListEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadSet_Test(Type protocolType) { var expected = new TSet(TType.String, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteSetBeginAsync(expected, default); await protocol.WriteSetEndAsync(default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadSetBeginAsync(default); await protocol.ReadSetEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadBool_Test(Type protocolType) { var expected = true; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteBoolAsync(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadBoolAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadByte_Test(Type protocolType) { var expected = sbyte.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteByteAsync(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadByteAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadI16_Test(Type protocolType) { var expected = short.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteI16Async(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadI16Async(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadI32_Test(Type protocolType) { var expected = int.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteI32Async(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadI32Async(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadI64_Test(Type protocolType) { var expected = long.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteI64Async(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadI64Async(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadDouble_Test(Type protocolType) { var expected = double.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteDoubleAsync(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadDoubleAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadUuid_Test(Type protocolType) { var expected = new Guid("{00112233-4455-6677-8899-aabbccddeeff}"); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteUuidAsync(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadUuidAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadString_Test(Type protocolType) { var expected = nameof(String); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteStringAsync(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadStringAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [TestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadBinary_Test(Type protocolType) { var expected = Encoding.UTF8.GetBytes(nameof(String)); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteBinaryAsync(expected, default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadBinaryAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } } } thrift-0.23.0/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj0000664000175000017500000000455315170007142031267 0ustar00buildbuild00000000000000 net10.0 latestMajor Thrift.IntegrationTests Thrift.IntegrationTests 0.23.0.0 Exe false false false false false false enable thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/0000775000175000017500000000000015167543515022473 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/GlobalSuppressions.cs0000664000175000017500000000240715165535636026666 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // This file is used by Code Analysis to maintain SuppressMessage // attributes that are applied to this project. // Project-level suppressions either have no target or are given // a specific target and scoped to a namespace, type, member, etc. using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("Performance", "CA1822", Justification = "", Scope = "module")] [assembly: SuppressMessage("Style", "IDE0090", Justification = "", Scope = "module")] thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.struct.thrift0000664000175000017500000000172315165535636027020 0ustar00buildbuild00000000000000/* * 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-5320 Usage of "Task" as IDL identifier generates uncompileable code namespace * Thrift5320.structs struct Task { 1: Task left 2: Task right } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.exception.thrift0000664000175000017500000000206115165535636027466 0ustar00buildbuild00000000000000/* * 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-5320 Usage of "Task" as IDL identifier generates uncompileable code namespace * Thrift5320.exceptions exception Task { 1: ErrorData data // it would be illegal to use exception as struct type } struct ErrorData { 1: string messitsch } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/optional_required_default.thrift0000664000175000017500000001432515165535636031156 0ustar00buildbuild00000000000000/* * 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-5216 generate DeepCopy methods namespace netstd OptReqDefTest enum Distance { foo = 0, bar = 1, baz = 2 } struct RaceDetails { // this is really the max field index used here, intentionally placed at the beginning 666: required Distance triplesix // without default values 1: optional Distance opt_one 2: optional double opt_two 3: optional i16 opt_three 4: optional string opt_four 5: optional uuid opt_five 6: optional list opt_six 7: optional set opt_seven 8: optional map opt_eight 9: optional binary opt_nine 11: required Distance req_one 12: required double req_two 13: required i16 req_three 14: required string req_four 15: required uuid req_five 16: required list req_six 17: required set req_seven 18: required map req_eight 19: required binary req_nine 21: Distance def_one 22: double def_two 23: i16 def_three 24: string def_four 25: uuid def_five 26: list def_six 27: set def_seven 28: map def_eight 29: binary def_nine // having default values 31: optional Distance opt_one_with_value = Distance.bar 32: optional double opt_two_with_value = 2.22 33: optional i16 opt_three_with_value = 3 34: optional string opt_four_with_value = "four" 35: optional uuid opt_five_with_value = "55555555-5555-5555-5555-000000000000" 36: optional list opt_six_with_value = [6] 37: optional set opt_seven_with_value = [7] 38: optional map opt_eight_with_value = { 8 : 8 } 39: optional binary opt_nine_with_value = "nine\t" 41: required Distance req_one_with_value = Distance.bar 42: required double req_two_with_value = 2.22 43: required i16 req_three_with_value = 3 44: required string req_four_with_value = "four" 45: required uuid req_five_with_value = "55555555-5555-5555-5555-000000000000" 46: required list req_six_with_value = [6] 47: required set req_seven_with_value = [7] 48: required map req_eight_with_value = { 8 : 8 } 49: required binary req_nine_with_value = "nine" 51: Distance def_one_with_value = Distance.bar 52: double def_two_with_value = 2.22 53: i16 def_three_with_value = 3 54: string def_four_with_value = "four" 55: uuid def_five_with_value = "55555555-5555-5555-5555-000000000000" 56: list def_six_with_value = [6] 57: set def_seven_with_value = [7] 58: map def_eight_with_value = { 8 : 8 } 59: binary def_nine_with_value = "nine" 90: optional bool last_of_the_mohicans // some more complicated ones, including recursion 300: required list far_list 301: optional set far_set 302: map far_map 310: required set> far_set_list 311: optional list>> far_list_map_set 312: map far_map_dist_to_rds 320: required RaceDetails req_nested 321: optional RaceDetails opt_nested 322: RaceDetails def_nested 330: required jack req_union 331: optional jack opt_union 332: jack def_union } union jack { 1: list stars 2: list stripes 310: set> far_set_list 311: list>> far_list_map_set 312: map far_map_dist_to_rds 320: jack nested_union 321: RaceDetails nested_struct 401: optional Distance opt_one 402: optional double opt_two 403: optional i16 opt_three 404: optional string opt_four 405: optional uuid opt_five 406: optional list opt_six 407: optional set opt_seven 408: optional map opt_eight 409: optional binary opt_nine } typedef RaceDetails RaceDetails2 typedef list RDs exception CrashBoomBang { 1 : i32 MyErrorCode } service foobar { set>> DoItNow( 1 : list>> rd, 2: i32 mitDefault = 42) throws (1: CrashBoomBang cbb) } service deprecate_everything { void Foo( ) ( deprecated = "This method has neither 'x' nor \"y\"" ) void Bar( ) ( deprecated = "Fails to deliver 中文 колбаÑа" ) void Baz( ) ( deprecated = "Need this to work with tabs (\t) or Umlauts (äöüÄÖÜß) too" ) void Deprecated() ( deprecated ) // no comment } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/0000775000175000017500000000000015170007142026665 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Properties/0000775000175000017500000000000015165535636031043 5ustar00buildbuild00000000000000AssemblyInfo.cs0000664000175000017500000000326115165535636033710 0ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Properties// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("Thrift")] [assembly: AssemblyCopyright("The Apache Software Foundation")] [assembly: AssemblyTrademark("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("d0d3706b-fed5-4cf5-b984-04f448de9d7b")]Thrift.Compile.netstd2.csproj0000664000175000017500000001125415170007142034244 0ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2 0.23.0 Thrift version $(ThriftVersion) netstandard2.0 latestMajor $(ThriftVersion).0 Thrift.Compile.netstd2 Thrift.Compile.netstd2 false false false false thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Impl/0000775000175000017500000000000015165535636027610 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Impl/Thrift5253/0000775000175000017500000000000015165535636031367 5ustar00buildbuild00000000000000MyService.cs0000664000175000017500000000506315165535636033551 0ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.netstd2/Impl/Thrift5253// 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 }); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5253.thrift0000664000175000017500000000336015165535636025501 0ustar00buildbuild00000000000000/* * 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-5253 using Result in result name generates wrong IAsync interface namespace * Thrift5253 // this works struct WorksArrrgs { 1: i32 foo } struct WorksRslt { 1: i32 foo } // this does not struct BrokenResult{ 1: i32 foo } struct BrokenArgs { 1: i32 foo } struct InternalStructs { 1: optional i32 foo } struct AsyncProcessor { 1: optional i32 foo } struct Client { 1: optional i32 foo } struct IAsync { 1: optional i32 foo } struct ReservedMemberName { 1: optional i32 Isset } service MyService{ BrokenResult Broken( 1 : BrokenArgs foo) WorksRslt Works( 1 : WorksArrrgs foo) InternalStructs InternalStructs( 1: InternalStructs foo) AsyncProcessor AsyncProcessor ( 1: AsyncProcessor foo) Client Client ( 1: Client foo) IAsync IAsync ( 1: IAsync foo) // inconsistent treatment of methods ending in "Async" void TestXsync() void TestAsync() } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.thrift0000664000175000017500000000230115165535636025466 0ustar00buildbuild00000000000000/* * 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-5320 Usage of "Task" as IDL identifier generates uncompileable code namespace * Thrift5320.Task include "Thrift5320.enum.thrift" include "Thrift5320.exception.thrift" include "Thrift5320.struct.thrift" enum Foobar { Task = 0 } service Task { Thrift5320.enum.Task Task( 1 : Thrift5320.struct.Task foo, 2: Foobar bar ) throws ( 1: Thrift5320.exception.Task error ) } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/name_conflicts.enum.thrift0000664000175000017500000000220615165535636027647 0ustar00buildbuild00000000000000/* * 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. */ // Testcases for // - THRIFT-5091 Netstd generator produces uncompileable code for struct names ending with "_result" or "_args" // - THRIFT-5444 netstd generator produces uncompileable code for enums ending with "_result" or "_args" namespace * name_conflicts_enum enum some_result { foo, bar, baz } enum some_args { foo, bar, baz } // EOF thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/0000775000175000017500000000000015170007142026160 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Properties/0000775000175000017500000000000015165535636030336 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Properties/AssemblyInfo.cs0000664000175000017500000000326115165535636033262 0ustar00buildbuild00000000000000// 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")]thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Impl/0000775000175000017500000000000015165535636027103 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Impl/Thrift5253/0000775000175000017500000000000015165535636030662 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Impl/Thrift5253/MyService.cs0000664000175000017500000000506615165535636033126 0ustar00buildbuild00000000000000// 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.net8.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 }); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net8/Thrift.Compile.net8.csproj0000664000175000017500000001176715170007142033122 0ustar00buildbuild00000000000000 0.23.0 Thrift version $(ThriftVersion) net8.0 latestMajor $(ThriftVersion).0 Thrift.Compile.net8 Thrift.Compile.net8 false false false false enable thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5794.thrift0000664000175000017500000000202215165535636025505 0ustar00buildbuild00000000000000/* * 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; } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5795.thrift0000664000175000017500000000164315165535636025516 0ustar00buildbuild00000000000000/* * 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; } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5320.enum.thrift0000664000175000017500000000167315165535636026444 0ustar00buildbuild00000000000000/* * 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-5320 Usage of "Task" as IDL identifier generates uncompileable code namespace * Thrift5320.enums enum Task { Zero, More } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/name_conflicts.thrift0000664000175000017500000000332015165535636026702 0ustar00buildbuild00000000000000/* * 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. */ // Testcases for // - THRIFT-5091 Netstd generator produces uncompileable code for struct names ending with "_result" or "_args" // - THRIFT-5444 netstd generator produces uncompileable code for enums ending with "_result" or "_args" // - THRIFT-5445 "cancellationToken" cannot be used as argument name namespace * name_conflicts include "name_conflicts.enum.thrift" struct some_struct_args { 1: name_conflicts.enum.some_args some_args 2: name_conflicts.enum.some_result some_result 3: required i32 cancellationToken } exception some_error_result { 1: name_conflicts.enum.some_args some_args 2: name_conflicts.enum.some_result some_result 3: optional i32 cancellationToken } service some_service { name_conflicts.enum.some_result some_method( 1: name_conflicts.enum.some_args some_args 2: some_struct_args more_args 3: i32 cancellationToken ) throws ( 1: some_error_result cancellationToken ) } // EOF thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5382.objs.thrift0000664000175000017500000000171115165535636026436 0ustar00buildbuild00000000000000/* * 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-5382 Netstd default list/set enums values are generated incorrectly namespace * Thrift5382.objs enum FoobarEnum { Val_1 = 0, Val_2 = 1 } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/0000775000175000017500000000000015170007142026231 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/Properties/0000775000175000017500000000000015167543515030404 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/Properties/AssemblyInfo.cs0000664000175000017500000000326115167543515033330 0ustar00buildbuild00000000000000// 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")]thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/Thrift.Compile.net10.csproj0000664000175000017500000001201315170007142033225 0ustar00buildbuild00000000000000 0.23.0 Thrift version $(ThriftVersion) net10.0 latestMajor $(ThriftVersion).0 Thrift.Compile.net10 Thrift.Compile.net10 false false false false enable thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/Impl/0000775000175000017500000000000015167543515027151 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/Impl/Thrift5253/0000775000175000017500000000000015167543515030730 5ustar00buildbuild00000000000000MyService.cs0000664000175000017500000000506715167543515033116 0ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net10/Impl/Thrift5253// 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.net10.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 }); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift5382.thrift0000664000175000017500000000246115165535636025505 0ustar00buildbuild00000000000000/* * 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-5382 Netstd default list/set enums values are generated incorrectly namespace * Thrift5382 include "Thrift5382.objs.thrift" struct RequestModel { // Breaks 1: optional set data_1 = [ FoobarEnum.Val_1, FoobarEnum.Val_2 ], // Breaks 2: optional list data_2 = [ FoobarEnum.Val_1, FoobarEnum.Val_2 ], // Works 3: optional Thrift5382.objs.FoobarEnum data_3 = FoobarEnum.Val_1 } service Test { void CallMe( 1 : RequestModel foo, ) } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/CassandraTest.thrift0000664000175000017500000007212615165535636026467 0ustar00buildbuild00000000000000#!/usr/local/bin/thrift --java --php --py # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # *** PLEASE REMEMBER TO EDIT THE VERSION CONSTANT WHEN MAKING CHANGES *** # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Interface definition for Cassandra Service # namespace netstd Apache.Cassandra.Test # Thrift.rb has a bug where top-level modules that include modules # with the same name are not properly referenced, so we can't do # Cassandra::Cassandra::Client. namespace rb CassandraThrift # The API version (NOT the product version), composed as a dot delimited # string with major, minor, and patch level components. # # - Major: Incremented for backward incompatible changes. An example would # be changes to the number or disposition of method arguments. # - Minor: Incremented for backward compatible changes. An example would # be the addition of a new (optional) method. # - Patch: Incremented for bug fixes. The patch level should be increased # for every edit that doesn't result in a change to major/minor. # # See the Semantic Versioning Specification (SemVer) http://semver.org. const string VERSION = "19.24.0" # # data structures # /** Basic unit of data within a ColumnFamily. * @param name, the name by which this column is set and retrieved. Maximum 64KB long. * @param value. The data associated with the name. Maximum 2GB long, but in practice you should limit it to small numbers of MB (since Thrift must read the full value into memory to operate on it). * @param timestamp. The timestamp is used for conflict detection/resolution when two columns with same name need to be compared. * @param ttl. An optional, positive delay (in seconds) after which the column will be automatically deleted. */ struct Column { 1: required binary name, 2: optional binary value, 3: optional i64 timestamp, 4: optional i32 ttl, } /** A named list of columns. * @param name. see Column.name. * @param columns. A collection of standard Columns. The columns within a super column are defined in an adhoc manner. * Columns within a super column do not have to have matching structures (similarly named child columns). */ struct SuperColumn { 1: required binary name, 2: required list columns, } struct CounterColumn { 1: required binary name, 2: required i64 value } struct CounterSuperColumn { 1: required binary name, 2: required list columns } /** Methods for fetching rows/records from Cassandra will return either a single instance of ColumnOrSuperColumn or a list of ColumnOrSuperColumns (get_slice()). If you're looking up a SuperColumn (or list of SuperColumns) then the resulting instances of ColumnOrSuperColumn will have the requested SuperColumn in the attribute super_column. For queries resulting in Columns, those values will be in the attribute column. This change was made between 0.3 and 0.4 to standardize on single query methods that may return either a SuperColumn or Column. If the query was on a counter column family, you will either get a counter_column (instead of a column) or a counter_super_column (instead of a super_column) @param column. The Column returned by get() or get_slice(). @param super_column. The SuperColumn returned by get() or get_slice(). @param counter_column. The Counterolumn returned by get() or get_slice(). @param counter_super_column. The CounterSuperColumn returned by get() or get_slice(). */ struct ColumnOrSuperColumn { 1: optional Column column, 2: optional SuperColumn super_column, 3: optional CounterColumn counter_column, 4: optional CounterSuperColumn counter_super_column } # # Exceptions # (note that internal server errors will raise a TApplicationException, courtesy of Thrift) # /** A specific column was requested that does not exist. */ exception NotFoundException { } /** Invalid request could mean keyspace or column family does not exist, required parameters are missing, or a parameter is malformed. why contains an associated error message. */ exception InvalidRequestException { 1: required string why } /** Not all the replicas required could be created and/or read. */ exception UnavailableException { } /** RPC timeout was exceeded. either a node failed mid-operation, or load was too high, or the requested op was too large. */ exception TimedOutException { } /** invalid authentication request (invalid keyspace, user does not exist, or credentials invalid) */ exception AuthenticationException { 1: required string why } /** invalid authorization request (user does not have access to keyspace) */ exception AuthorizationException { 1: required string why } /** schemas are not in agreement across all nodes */ exception SchemaDisagreementException { } # # service api # /** * The ConsistencyLevel is an enum that controls both read and write * behavior based on the ReplicationFactor of the keyspace. The * different consistency levels have different meanings, depending on * if you're doing a write or read operation. * * If W + R > ReplicationFactor, where W is the number of nodes to * block for on write, and R the number to block for on reads, you * will have strongly consistent behavior; that is, readers will * always see the most recent write. Of these, the most interesting is * to do QUORUM reads and writes, which gives you consistency while * still allowing availability in the face of node failures up to half * of . Of course if latency is more important than * consistency then you can use lower values for either or both. * * Some ConsistencyLevels (ONE, TWO, THREE) refer to a specific number * of replicas rather than a logical concept that adjusts * automatically with the replication factor. Of these, only ONE is * commonly used; TWO and (even more rarely) THREE are only useful * when you care more about guaranteeing a certain level of * durability, than consistency. * * Write consistency levels make the following guarantees before reporting success to the client: * ANY Ensure that the write has been written once somewhere, including possibly being hinted in a non-target node. * ONE Ensure that the write has been written to at least 1 node's commit log and memory table * TWO Ensure that the write has been written to at least 2 node's commit log and memory table * THREE Ensure that the write has been written to at least 3 node's commit log and memory table * QUORUM Ensure that the write has been written to / 2 + 1 nodes * LOCAL_QUORUM Ensure that the write has been written to / 2 + 1 nodes, within the local datacenter (requires NetworkTopologyStrategy) * EACH_QUORUM Ensure that the write has been written to / 2 + 1 nodes in each datacenter (requires NetworkTopologyStrategy) * ALL Ensure that the write is written to <ReplicationFactor> nodes before responding to the client. * * Read consistency levels make the following guarantees before returning successful results to the client: * ANY Not supported. You probably want ONE instead. * ONE Returns the record obtained from a single replica. * TWO Returns the record with the most recent timestamp once two replicas have replied. * THREE Returns the record with the most recent timestamp once three replicas have replied. * QUORUM Returns the record with the most recent timestamp once a majority of replicas have replied. * LOCAL_QUORUM Returns the record with the most recent timestamp once a majority of replicas within the local datacenter have replied. * EACH_QUORUM Returns the record with the most recent timestamp once a majority of replicas within each datacenter have replied. * ALL Returns the record with the most recent timestamp once all replicas have replied (implies no replica may be down).. */ enum ConsistencyLevel { ONE = 1, QUORUM = 2, LOCAL_QUORUM = 3, EACH_QUORUM = 4, ALL = 5, ANY = 6, TWO = 7, THREE = 8, } /** ColumnParent is used when selecting groups of columns from the same ColumnFamily. In directory structure terms, imagine ColumnParent as ColumnPath + '/../'. See also ColumnPath */ struct ColumnParent { 3: required string column_family, 4: optional binary super_column, } /** The ColumnPath is the path to a single column in Cassandra. It might make sense to think of ColumnPath and * ColumnParent in terms of a directory structure. * * ColumnPath is used to looking up a single column. * * @param column_family. The name of the CF of the column being looked up. * @param super_column. The super column name. * @param column. The column name. */ struct ColumnPath { 3: required string column_family, 4: optional binary super_column, 5: optional binary column, } /** A slice range is a structure that stores basic range, ordering and limit information for a query that will return multiple columns. It could be thought of as Cassandra's version of LIMIT and ORDER BY @param start. The column name to start the slice with. This attribute is not required, though there is no default value, and can be safely set to '', i.e., an empty byte array, to start with the first column name. Otherwise, it must a valid value under the rules of the Comparator defined for the given ColumnFamily. @param finish. The column name to stop the slice at. This attribute is not required, though there is no default value, and can be safely set to an empty byte array to not stop until 'count' results are seen. Otherwise, it must also be a valid value to the ColumnFamily Comparator. @param reversed. Whether the results should be ordered in reversed order. Similar to ORDER BY blah DESC in SQL. @param count. How many columns to return. Similar to LIMIT in SQL. May be arbitrarily large, but Thrift will materialize the whole result into memory before returning it to the client, so be aware that you may be better served by iterating through slices by passing the last value of one call in as the 'start' of the next instead of increasing 'count' arbitrarily large. */ struct SliceRange { 1: required binary start, 2: required binary finish, 3: required bool reversed=0, 4: required i32 count=100, } /** A SlicePredicate is similar to a mathematic predicate (see http://en.wikipedia.org/wiki/Predicate_(mathematical_logic)), which is described as "a property that the elements of a set have in common." SlicePredicate's in Cassandra are described with either a list of column_names or a SliceRange. If column_names is specified, slice_range is ignored. @param column_name. A list of column names to retrieve. This can be used similar to Memcached's "multi-get" feature to fetch N known column names. For instance, if you know you wish to fetch columns 'Joe', 'Jack', and 'Jim' you can pass those column names as a list to fetch all three at once. @param slice_range. A SliceRange describing how to range, order, and/or limit the slice. */ struct SlicePredicate { 1: optional list column_names, 2: optional SliceRange slice_range, } enum IndexOperator { EQ, GTE, GT, LTE, LT } struct IndexExpression { 1: required binary column_name, 2: required IndexOperator op, 3: required binary value, } struct IndexClause { 1: required list expressions 2: required binary start_key, 3: required i32 count=100, } /** The semantics of start keys and tokens are slightly different. Keys are start-inclusive; tokens are start-exclusive. Token ranges may also wrap -- that is, the end token may be less than the start one. Thus, a range from keyX to keyX is a one-element range, but a range from tokenY to tokenY is the full ring. */ struct KeyRange { 1: optional binary start_key, 2: optional binary end_key, 3: optional string start_token, 4: optional string end_token, 5: required i32 count=100 } /** A KeySlice is key followed by the data it maps to. A collection of KeySlice is returned by the get_range_slice operation. @param key. a row key @param columns. List of data represented by the key. Typically, the list is pared down to only the columns specified by a SlicePredicate. */ struct KeySlice { 1: required binary key, 2: required list columns, } struct KeyCount { 1: required binary key, 2: required i32 count } /** * Note that the timestamp is only optional in case of counter deletion. */ struct Deletion { 1: optional i64 timestamp, 2: optional binary super_column, 3: optional SlicePredicate predicate, } /** A Mutation is either an insert (represented by filling column_or_supercolumn) or a deletion (represented by filling the deletion attribute). @param column_or_supercolumn. An insert to a column or supercolumn (possibly counter column or supercolumn) @param deletion. A deletion of a column or supercolumn */ struct Mutation { 1: optional ColumnOrSuperColumn column_or_supercolumn, 2: optional Deletion deletion, } struct EndpointDetails { 1: string host, 2: string datacenter, 3: optional string rack } /** A TokenRange describes part of the Cassandra ring, it is a mapping from a range to endpoints responsible for that range. @param start_token The first token in the range @param end_token The last token in the range @param endpoints The endpoints responsible for the range (listed by their configured listen_address) @param rpc_endpoints The endpoints responsible for the range (listed by their configured rpc_address) */ struct TokenRange { 1: required string start_token, 2: required string end_token, 3: required list endpoints, 4: optional list rpc_endpoints 5: optional list endpoint_details, } /** Authentication requests can contain any data, dependent on the IAuthenticator used */ struct AuthenticationRequest { 1: required map credentials } enum IndexType { KEYS, CUSTOM } /* describes a column in a column family. */ struct ColumnDef { 1: required binary name, 2: required string validation_class, 3: optional IndexType index_type, 4: optional string index_name, 5: optional map index_options } /* describes a column family. */ struct CfDef { 1: required string keyspace, 2: required string name, 3: optional string column_type="Standard", 5: optional string comparator_type="BytesType", 6: optional string subcomparator_type, 8: optional string comment, 12: optional double read_repair_chance=1.0, 13: optional list column_metadata, 14: optional i32 gc_grace_seconds, 15: optional string default_validation_class, 16: optional i32 id, 17: optional i32 min_compaction_threshold, 18: optional i32 max_compaction_threshold, 24: optional bool replicate_on_write, 25: optional double merge_shards_chance, 26: optional string key_validation_class, 28: optional binary key_alias, 29: optional string compaction_strategy, 30: optional map compaction_strategy_options, 32: optional map compression_options, 33: optional double bloom_filter_fp_chance, } /* describes a keyspace. */ struct KsDef { 1: required string name, 2: required string strategy_class, 3: optional map strategy_options, /** @deprecated */ 4: optional i32 replication_factor, 5: required list cf_defs, 6: optional bool durable_writes=1, } /** CQL query compression */ enum Compression { GZIP = 1, NONE = 2 } enum CqlResultType { ROWS = 1, VOID = 2, INT = 3 } /** Row returned from a CQL query */ struct CqlRow { 1: required binary key, 2: required list columns } struct CqlMetadata { 1: required map name_types, 2: required map value_types, 3: required string default_name_type, 4: required string default_value_type } struct CqlResult { 1: required CqlResultType type, 2: optional list rows, 3: optional i32 num, 4: optional CqlMetadata schema } struct CqlPreparedResult { 1: required i32 itemId, 2: required i32 count } service Cassandra { # auth methods void login(1: required AuthenticationRequest auth_request) throws (1:AuthenticationException authnx, 2:AuthorizationException authzx), # set keyspace void set_keyspace(1: required string keyspace) throws (1:InvalidRequestException ire), # retrieval methods /** Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is the only method that can throw an exception under non-failure conditions.) */ ColumnOrSuperColumn get(1:required binary key, 2:required ColumnPath column_path, 3:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:NotFoundException nfe, 3:UnavailableException ue, 4:TimedOutException te), /** Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name pair) specified by the given SlicePredicate. If no matching values are found, an empty list is returned. */ list get_slice(1:required binary key, 2:required ColumnParent column_parent, 3:required SlicePredicate predicate, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** returns the number of columns matching predicate for a particular key, ColumnFamily and optionally SuperColumn. */ i32 get_count(1:required binary key, 2:required ColumnParent column_parent, 3:required SlicePredicate predicate, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** Performs a get_slice for column_parent and predicate for the given keys in parallel. */ map> multiget_slice(1:required list keys, 2:required ColumnParent column_parent, 3:required SlicePredicate predicate, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** Perform a get_count in parallel on the given list keys. The return value maps keys to the count found. */ map multiget_count(1:required list keys, 2:required ColumnParent column_parent, 3:required SlicePredicate predicate, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** returns a subset of columns for a contiguous range of keys. */ list get_range_slices(1:required ColumnParent column_parent, 2:required SlicePredicate predicate, 3:required KeyRange range, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** Returns the subset of columns specified in SlicePredicate for the rows matching the IndexClause */ list get_indexed_slices(1:required ColumnParent column_parent, 2:required IndexClause index_clause, 3:required SlicePredicate column_predicate, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), # modification methods /** * Insert a Column at the given column_parent.column_family and optional column_parent.super_column. */ void insert(1:required binary key, 2:required ColumnParent column_parent, 3:required Column column, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** * Increment or decrement a counter. */ void add(1:required binary key, 2:required ColumnParent column_parent, 3:required CounterColumn column, 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too. */ void remove(1:required binary key, 2:required ColumnPath column_path, 3:required i64 timestamp, 4:ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** * Remove a counter at the specified location. * Note that counters have limited support for deletes: if you remove a counter, you must wait to issue any following update * until the delete has reached all the nodes and all of them have been fully compacted. */ void remove_counter(1:required binary key, 2:required ColumnPath path, 3:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** Mutate many columns or super columns for many row keys. See also: Mutation. mutation_map maps key to column family to a list of Mutation objects to take place at that scope. **/ void batch_mutate(1:required map>> mutation_map, 2:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), /** Truncate will mark and entire column family as deleted. From the user's perspective a successful call to truncate will result complete data deletion from cfname. Internally, however, disk space will not be immediatily released, as with all deletes in cassandra, this one only marks the data as deleted. The operation succeeds only if all hosts in the cluster at available and will throw an UnavailableException if some hosts are down. */ void truncate(1:required string cfname) throws (1: InvalidRequestException ire, 2: UnavailableException ue, 3: TimedOutException te), // Meta-APIs -- APIs to get information about the node or cluster, // rather than user data. The nodeprobe program provides usage examples. /** * for each schema version present in the cluster, returns a list of nodes at that version. * hosts that do not respond will be under the key DatabaseDescriptor.INITIAL_VERSION. * the cluster is all on the same version if the size of the map is 1. */ map> describe_schema_versions() throws (1: InvalidRequestException ire), /** list the defined keyspaces in this cluster */ list describe_keyspaces() throws (1:InvalidRequestException ire), /** get the cluster name */ string describe_cluster_name(), /** get the thrift api version */ string describe_version(), /** get the token ring: a map of ranges to host addresses, represented as a set of TokenRange instead of a map from range to list of endpoints, because you can't use Thrift structs as map keys: https://issues.apache.org/jira/browse/THRIFT-162 for the same reason, we can't return a set here, even though order is neither important nor predictable. */ list describe_ring(1:required string keyspace) throws (1:InvalidRequestException ire), /** returns the partitioner used by this cluster */ string describe_partitioner(), /** returns the snitch used by this cluster */ string describe_snitch(), /** describe specified keyspace */ KsDef describe_keyspace(1:required string keyspace) throws (1:NotFoundException nfe, 2:InvalidRequestException ire), /** experimental API for hadoop/parallel query support. may change violently and without warning. returns list of token strings such that first subrange is (list[0], list[1]], next is (list[1], list[2]], etc. */ list describe_splits(1:required string cfName, 2:required string start_token, 3:required string end_token, 4:required i32 keys_per_split) throws (1:InvalidRequestException ire), /** adds a column family. returns the new schema id. */ string system_add_column_family(1:required CfDef cf_def) throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde), /** drops a column family. returns the new schema id. */ string system_drop_column_family(1:required string column_family) throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde), /** adds a keyspace and any column families that are part of it. returns the new schema id. */ string system_add_keyspace(1:required KsDef ks_def) throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde), /** drops a keyspace and any column families that are part of it. returns the new schema id. */ string system_drop_keyspace(1:required string keyspace) throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde), /** updates properties of a keyspace. returns the new schema id. */ string system_update_keyspace(1:required KsDef ks_def) throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde), /** updates properties of a column family. returns the new schema id. */ string system_update_column_family(1:required CfDef cf_def) throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde), /** * Executes a CQL (Cassandra Query Language) statement and returns a * CqlResult containing the results. */ CqlResult execute_cql_query(1:required binary query, 2:required Compression compression) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te, 4:SchemaDisagreementException sde) /** * Prepare a CQL (Cassandra Query Language) statement by compiling and returning * - the type of CQL statement * - an id token of the compiled CQL stored on the server side. * - a count of the discovered bound markers in the statement */ CqlPreparedResult prepare_cql_query(1:required binary query, 2:required Compression compression) throws (1:InvalidRequestException ire) /** * Executes a prepared CQL (Cassandra Query Language) statement by passing an id token and a list of variables * to bind and returns a CqlResult containing the results. */ CqlResult execute_prepared_cql_query(1:required i32 itemId, 2:required list values) throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te, 4:SchemaDisagreementException sde) } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/0000775000175000017500000000000015170007142026161 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Properties/0000775000175000017500000000000015165535636030337 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Properties/AssemblyInfo.cs0000664000175000017500000000326115165535636033263 0ustar00buildbuild00000000000000// 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")]thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Impl/0000775000175000017500000000000015165535636027104 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Impl/Thrift5253/0000775000175000017500000000000015165535636030663 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Impl/Thrift5253/MyService.cs0000664000175000017500000000506615165535636033127 0ustar00buildbuild00000000000000// 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 }); } } } thrift-0.23.0/lib/netstd/Tests/Thrift.Compile.Tests/Thrift.Compile.net9/Thrift.Compile.net9.csproj0000664000175000017500000001176715170007142033124 0ustar00buildbuild00000000000000 0.23.0 Thrift version $(ThriftVersion) net9.0 latestMajor $(ThriftVersion).0 Thrift.Compile.net9 Thrift.Compile.net9 false false false false enable thrift-0.23.0/lib/netstd/Thrift.sln0000664000175000017500000002477715167543515017440 0ustar00buildbuild00000000000000Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 VisualStudioVersion = 18.0.11205.157 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{ED5A45B0-07D1-4507-96B7-83FBD3D031CA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "Thrift\Thrift.csproj", "{5B501D21-D428-408D-AB5C-32D6F5355294}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.IntegrationTests", "Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj", "{837F4084-AAD7-45F5-BC96-10E05A669DB4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Tests", "Tests\Thrift.Tests\Thrift.Tests.csproj", "{0790D388-1A3C-4423-8CF2-C97074A8B68B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{BF7B896B-8BB6-447C-84F8-26871882A14A}" EndProject 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 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift.Compile.net10", "Tests\Thrift.Compile.Tests\Thrift.Compile.net10\Thrift.Compile.net10.csproj", "{7899EDD8-1CA5-F033-B68D-D596B20A1941}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|Any CPU.Build.0 = Debug|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x64.ActiveCfg = Debug|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x64.Build.0 = Debug|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x86.ActiveCfg = Debug|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x86.Build.0 = Debug|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|Any CPU.ActiveCfg = Release|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|Any CPU.Build.0 = Release|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x64.ActiveCfg = Release|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x64.Build.0 = Release|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x86.ActiveCfg = Release|Any CPU {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x86.Build.0 = Release|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|Any CPU.Build.0 = Debug|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x64.ActiveCfg = Debug|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x64.Build.0 = Debug|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x86.ActiveCfg = Debug|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x86.Build.0 = Debug|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|Any CPU.ActiveCfg = Release|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|Any CPU.Build.0 = Release|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x64.ActiveCfg = Release|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x64.Build.0 = Release|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x86.ActiveCfg = Release|Any CPU {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x86.Build.0 = Release|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|Any CPU.Build.0 = Debug|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x64.ActiveCfg = Debug|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x64.Build.0 = Debug|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x86.ActiveCfg = Debug|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x86.Build.0 = Debug|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|Any CPU.ActiveCfg = Release|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|Any CPU.Build.0 = Release|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x64.ActiveCfg = Release|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x64.Build.0 = Release|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x86.ActiveCfg = Release|Any CPU {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x86.Build.0 = Release|Any CPU {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 {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Debug|x64.Build.0 = Debug|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Debug|x86.ActiveCfg = Debug|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Debug|x86.Build.0 = Debug|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Release|Any CPU.ActiveCfg = Release|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Release|Any CPU.Build.0 = Release|Any CPU {D0559DFF-6632-446C-9EFC-C750DA20B1D9}.Release|x64.ActiveCfg = Release|Any CPU {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 {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Debug|Any CPU.Build.0 = Debug|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Debug|x64.ActiveCfg = Debug|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Debug|x64.Build.0 = Debug|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Debug|x86.ActiveCfg = Debug|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Debug|x86.Build.0 = Debug|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Release|Any CPU.ActiveCfg = Release|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Release|Any CPU.Build.0 = Release|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Release|x64.ActiveCfg = Release|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Release|x64.Build.0 = Release|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Release|x86.ActiveCfg = Release|Any CPU {7899EDD8-1CA5-F033-B68D-D596B20A1941}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {837F4084-AAD7-45F5-BC96-10E05A669DB4} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA} {0790D388-1A3C-4423-8CF2-C97074A8B68B} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA} {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} {7899EDD8-1CA5-F033-B68D-D596B20A1941} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FD20BC4A-0109-41D8-8C0C-893E784D7EF9} EndGlobalSection EndGlobal thrift-0.23.0/lib/netstd/build.sh0000664000175000017500000000202715165535636017100 0ustar00buildbuild00000000000000#!/usr/bin/env bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #exit if any command fails #set -e thrift --version dotnet --info dotnet build #revision=${TRAVIS_JOB_ID:=1} #revision=$(printf "%04d" $revision) #dotnet pack ./src/PROJECT_NAME -c Release -o ./artifacts --version-suffix=$revision thrift-0.23.0/lib/netstd/runtests.sh0000664000175000017500000000170115165535636017666 0ustar00buildbuild00000000000000#!/usr/bin/env bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # thrift -version dotnet --info dotnet test Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj dotnet test Tests\Thrift.Tests\Thrift.Tests.csprojthrift-0.23.0/lib/netstd/Directory.Build.props0000664000175000017500000000024615165535636021535 0ustar00buildbuild00000000000000 thrift-0.23.0/lib/netstd/runtests.cmd0000664000175000017500000000204115165535636020015 0ustar00buildbuild00000000000000@echo off rem /* rem * Licensed to the Apache Software Foundation (ASF) under one rem * or more contributor license agreements. See the NOTICE file rem * distributed with this work for additional information rem * regarding copyright ownership. The ASF licenses this file rem * to you under the Apache License, Version 2.0 (the rem * "License"); you may not use this file except in compliance rem * with the License. You may obtain a copy of the License at rem * rem * http://www.apache.org/licenses/LICENSE-2.0 rem * rem * Unless required by applicable law or agreed to in writing, rem * software distributed under the License is distributed on an rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY rem * KIND, either express or implied. See the License for the rem * specific language governing permissions and limitations rem * under the License. rem */ setlocal thrift -version dotnet --info dotnet test Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj dotnet test Tests\Thrift.Tests\Thrift.Tests.csproj :eof thrift-0.23.0/lib/netstd/README.md0000664000175000017500000000672415170003262016711 0ustar00buildbuild00000000000000# Apache Thrift netstd Thrift client library for Microsoft .NET Standard # Build the library ## How to build on Windows - Get Thrift IDL compiler executable, add to some folder and add path to this folder into PATH variable. - 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 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 - In trace logging mode you can see some not important internal exceptions # Migration to netstd ## ... from netcore If you are migrating your code from netcore library, you will have to: - Switch to `thrift -gen netstd` - the following compiler flags are no longer needed or supported: `hashcode` is now standard, while `nullable` is no longer supported. - the `Thrift.Transport` and `Thrift.Protocol` namespaces now use the singular form - add `using Thrift.Processor;` in the server code where appropriate - rename all `T*ClientTransport` to `T*Transport` - rename all `TBaseServer` occurrences in your code to `TServer` - the `SingletonTProcessorFactory` is now called `TSingletonProcessorFactory` - and the `AsyncBaseServer` is now the `TSimpleAsyncServer` You may wonder why we changed so many names. The naming scheme has been revised for two reasons: First, we want to get back the established, well-known naming consistency across the Thrift libraries which the netcore library did not fully respect. Second, by achieving that first objective, we get the additional benefit of making migration at least a bit easier for C# projects. ## ... from csharp Because of the different environment requirements, migration from C# takes slightly more efforts. While the code changes related to Thrift itself are moderate, you may need to upgrade certain dependencies, components or even modules to more recent versions. 1. Client and server applications must use at least framework 4.6.1, any version below will not work. 1. Switch to `thrift -gen netstd`. The following compiler flags are no longer needed or supported: `hashcode` and `async` are now standard, while `nullable` is no longer supported. 1. [Familiarize yourself with the `async/await` model](https://msdn.microsoft.com/en-us/magazine/jj991977.aspx), if you have not already done so. As netstd does not support `ISync` anymore, async is mandatory. The synchronous model is simply no longer available (that's also the reason why we don't need the `async` flag anymore). 1. Consider proper use of `cancellationToken` parameters. They are optional but may be quite helpful. 1. As you probably already guessed, there are a few names that have been changed: - add `using Thrift.Processor;` in the server code where appropriate - the `TServerSocket` is now called `TServerSocketTransport` - change `IProtocolFactory` into `ITProtocolFactory` - if you are looking for `TSimpleServer`, try `TSimpleAsyncServer` instead - similarly, the `TThreadPoolServer` is now a `TThreadPoolAsyncServer` - the server's `Serve()` method does now `ServeAsync()` - In case you are using Thrift server event handlers: the `SetEventHandler` method now starts with an uppercase letter - and you will also have to revise the method names of all `TServerEventHandler` descendants you have in your code thrift-0.23.0/lib/netstd/Thrift/0000755000175000017500000000000015170007201016654 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/GlobalSuppressions.cs0000664000175000017500000000354215165535636023075 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // This file is used by Code Analysis to maintain SuppressMessage // attributes that are applied to this project. // Project-level suppressions either have no target or are given // a specific target and scoped to a namespace, type, member, etc. using System.Diagnostics.CodeAnalysis; // suppress certain messages for compatibility reasons with older C# versions we want to support [assembly: SuppressMessage("Style", "IDE0057", Justification = "compatibility", Scope = "module")] [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")] thrift-0.23.0/lib/netstd/Thrift/Collections/0000775000175000017500000000000015165535636021162 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Collections/THashSet.cs0000664000175000017500000000271715165535636023203 0ustar00buildbuild00000000000000// 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; using System.Collections.Generic; namespace Thrift.Collections { // ReSharper disable once InconsistentNaming [Obsolete("deprecated, use HashSet instead")] public class THashSet : System.Collections.Generic.HashSet { public THashSet() : base() { } public THashSet(int capacity) #if NET5_0_OR_GREATER : base(capacity) #elif NETFRAMEWORK || NETSTANDARD : base(/*capacity not supported*/) #else #error Unknown platform #endif { } public THashSet(IEnumerable collection) : base(collection) { } } } thrift-0.23.0/lib/netstd/Thrift/Collections/TCollections.cs0000664000175000017500000000717615165535636024126 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Collections; using System.Collections.Generic; namespace Thrift.Collections { // ReSharper disable once InconsistentNaming public static class TCollections { /// /// This will return true if the two collections are value-wise the same. /// If the collection contains a collection, the collections will be compared using this method. /// public static bool Equals(IEnumerable first, IEnumerable second) { if (first == null && second == null) { return true; } if (first == null || second == null) { return false; } // for dictionaries, we need to compare keys and values separately // because KeyValuePair.Equals() will not do what we want var fdict = first as IDictionary; var sdict = second as IDictionary; if ((fdict != null) || (sdict != null)) { if ((fdict == null) || (sdict == null)) return false; return TCollections.Equals(fdict.Keys, sdict.Keys) && TCollections.Equals(fdict.Values, sdict.Values); } var fiter = first.GetEnumerator(); var siter = second.GetEnumerator(); var fnext = fiter.MoveNext(); var snext = siter.MoveNext(); while (fnext && snext) { var fenum = fiter.Current as IEnumerable; var senum = siter.Current as IEnumerable; if (fenum != null && senum != null) { if (!Equals(fenum, senum)) { return false; } } else if (fenum == null ^ senum == null) { return false; } else if (!Equals(fiter.Current, siter.Current)) { return false; } fnext = fiter.MoveNext(); snext = siter.MoveNext(); } return fnext == snext; } /// /// This returns a hashcode based on the value of the enumerable. /// public static int GetHashCode(IEnumerable enumerable) { if (enumerable == null) { return 0; } var hashcode = 0; foreach (var obj in enumerable) { var objHash = (obj is IEnumerable enum2) ? GetHashCode(enum2) : obj.GetHashCode(); unchecked { hashcode = (hashcode * 397) ^ (objHash); } } return hashcode; } } } thrift-0.23.0/lib/netstd/Thrift/Properties/0000775000175000017500000000000015170007142021016 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Properties/AssemblyInfo.cs0000664000175000017500000000431315170007142023741 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Thrift")] [assembly: AssemblyDescription("C# .NET Core bindings for the Apache Thrift RPC system")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("Thrift")] [assembly: AssemblyCopyright("The Apache Software Foundation")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] //@TODO where to put License information? // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a exType in this assembly from // COM, set the ComVisible attribute to true on that exType. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("df3f8ef0-e0a3-4c86-a65b-8ec84e016b1d")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("0.23.0.0")] [assembly: AssemblyFileVersion("0.23.0.0")] thrift-0.23.0/lib/netstd/Thrift/Transport/0000775000175000017500000000000015165535636020700 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Transport/TEndpointTransport.cs0000664000175000017500000000763415165535636025062 0ustar00buildbuild00000000000000// 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.Text; namespace Thrift.Transport { abstract public class TEndpointTransport : TTransport { protected long MaxMessageSize { get => Configuration.MaxMessageSize; } protected long KnownMessageSize { get; private set; } protected long RemainingMessageSize { get; private set; } private readonly TConfiguration _configuration; public override TConfiguration Configuration { get => _configuration; } public TEndpointTransport( TConfiguration config) { _configuration = config ?? new TConfiguration(); Debug.Assert(Configuration != null); ResetMessageSizeAndConsumedBytes(); } /// /// Resets RemainingMessageSize to the configured maximum /// public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { // full reset if (newSize < 0) { KnownMessageSize = MaxMessageSize; RemainingMessageSize = MaxMessageSize; return; } // update only: message size can shrink, but not grow Debug.Assert(KnownMessageSize <= MaxMessageSize); if (newSize > KnownMessageSize) throw new TTransportException(TTransportException.ExceptionType.MessageSizeLimit, "MaxMessageSize reached"); KnownMessageSize = newSize; RemainingMessageSize = newSize; } /// /// Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport). /// Will throw if we already consumed too many bytes or if the new size is larger than allowed. /// /// public override void UpdateKnownMessageSize(long size) { var consumed = KnownMessageSize - RemainingMessageSize; ResetMessageSizeAndConsumedBytes(size); CountConsumedMessageBytes(consumed); } /// /// Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data /// /// public override void CheckReadBytesAvailable(long numBytes) { if ((RemainingMessageSize < numBytes) || (numBytes < 0)) throw new TTransportException(TTransportException.ExceptionType.MessageSizeLimit, "MaxMessageSize reached"); } /// /// Consumes numBytes from the RemainingMessageSize. /// /// protected void CountConsumedMessageBytes(long numBytes) { if (RemainingMessageSize >= numBytes) { RemainingMessageSize -= numBytes; } else { RemainingMessageSize = 0; throw new TTransportException(TTransportException.ExceptionType.MessageSizeLimit, "MaxMessageSize reached"); } } } } thrift-0.23.0/lib/netstd/Thrift/Transport/TTransport.cs0000664000175000017500000001341415165535636023352 0ustar00buildbuild00000000000000// 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.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable CA1510 // net8 - use ThrowIfNull #pragma warning disable CA1513 // net8 - use ThrowIfNull namespace Thrift.Transport { //TODO: think about client info // ReSharper disable once InconsistentNaming public abstract class TTransport : IDisposable { //TODO: think how to avoid peek byte private readonly byte[] _peekBuffer = new byte[1]; private bool _hasPeekByte; public abstract bool IsOpen { get; } public abstract TConfiguration Configuration { get; } public abstract void UpdateKnownMessageSize(long size); public abstract void CheckReadBytesAvailable(long numBytes); public abstract void ResetMessageSizeAndConsumedBytes(long newSize = -1); public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public async ValueTask PeekAsync(CancellationToken cancellationToken) { //If we already have a byte read but not consumed, do nothing. if (_hasPeekByte) { return true; } //If transport closed we can't peek. if (!IsOpen) { return false; } //Try to read one byte. If succeeds we will need to store it for the next read. try { var bytes = await ReadAsync(_peekBuffer, 0, 1, cancellationToken); if (bytes == 0) { return false; } } catch (IOException) { return false; } _hasPeekByte = true; return true; } public abstract Task OpenAsync(CancellationToken cancellationToken = default); public abstract void Close(); protected static void ValidateBufferArgs(byte[] buffer, int offset, int length) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } #if DEBUG // let it fail with OutOfRange in RELEASE mode if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset), "Buffer offset must be >= 0"); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "Buffer length must be >= 0"); } if (offset + length > buffer.Length) { throw new ArgumentOutOfRangeException(nameof(buffer), "Not enough data"); } #endif } public abstract ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken); public virtual async ValueTask ReadAllAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); ValidateBufferArgs(buffer, offset, length); if (length <= 0) return 0; // If we previously peeked a byte, we need to use that first. var totalBytes = 0; if (_hasPeekByte) { buffer[offset++] = _peekBuffer[0]; _hasPeekByte = false; if (1 == length) { return 1; // we're done } ++totalBytes; } var remaining = length - totalBytes; Debug.Assert(remaining > 0); // any other possible cases should have been handled already while (true) { var numBytes = await ReadAsync(buffer, offset, remaining, cancellationToken); totalBytes += numBytes; if (totalBytes >= length) { return totalBytes; // we're done } if (numBytes <= 0) { throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "Cannot read, Remote side has closed"); } remaining -= numBytes; offset += numBytes; } } public virtual async Task WriteAsync(byte[] buffer, CancellationToken cancellationToken) { await WriteAsync(buffer, 0, buffer.Length, CancellationToken.None); } public virtual async Task WriteAsync(byte[] buffer, int offset, int length) { await WriteAsync(buffer, offset, length, CancellationToken.None); } public abstract Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken); public abstract Task FlushAsync(CancellationToken cancellationToken); protected abstract void Dispose(bool disposing); } } thrift-0.23.0/lib/netstd/Thrift/Transport/Client/0000775000175000017500000000000015165535636022116 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs0000664000175000017500000001270715165535636027117 0ustar00buildbuild00000000000000// 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.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; namespace Thrift.Transport.Client { // ReSharper disable once InconsistentNaming public class TMemoryBufferTransport : TEndpointTransport { private bool IsDisposed; private byte[] Bytes; private int _bytesUsed; public TMemoryBufferTransport(TConfiguration config, int initialCapacity = 2048) : base(config) { Bytes = new byte[initialCapacity]; } public TMemoryBufferTransport(byte[] buf, TConfiguration config) :base(config) { Bytes = (byte[])buf.Clone(); _bytesUsed = Bytes.Length; UpdateKnownMessageSize(_bytesUsed); } public int Position { get; set; } public int Capacity { get { Debug.Assert(_bytesUsed <= Bytes.Length); return Bytes.Length; } set { Array.Resize(ref Bytes, value); _bytesUsed = value; } } public int Length { get { Debug.Assert(_bytesUsed <= Bytes.Length); return _bytesUsed; } set { if ((Bytes.Length < value) || (Bytes.Length > (10 * value))) Array.Resize(ref Bytes, Math.Max(2048, (int)(value * 1.25))); _bytesUsed = value; } } public void SetLength(int value) { Length = value; Position = Math.Min(Position, value); } public override bool IsOpen => true; public override Task OpenAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override void Close() { /* do nothing */ } public void Seek(int delta, SeekOrigin origin) { int newPos; switch (origin) { case SeekOrigin.Begin: newPos = delta; break; case SeekOrigin.Current: newPos = Position + delta; break; case SeekOrigin.End: newPos = _bytesUsed + delta; break; default: throw new ArgumentException("Unrecognized value",nameof(origin)); } if ((0 > newPos) || (newPos > _bytesUsed)) throw new ArgumentException("Cannot seek outside of the valid range",nameof(origin)); Position = newPos; ResetMessageSizeAndConsumedBytes(); CountConsumedMessageBytes(Position); } public override ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { var count = Math.Min(Length - Position, length); Buffer.BlockCopy(Bytes, Position, buffer, offset, count); Position += count; CountConsumedMessageBytes(count); return new ValueTask(count); } public override Task WriteAsync(byte[] buffer, CancellationToken cancellationToken) { return WriteAsync(buffer, 0, buffer.Length, cancellationToken); } public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { var free = Length - Position; Length = Length + count - free; Buffer.BlockCopy(buffer, offset, Bytes, Position, count); Position += count; return Task.CompletedTask; } public override Task FlushAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); ResetMessageSizeAndConsumedBytes(); return Task.CompletedTask; } public byte[] GetBuffer() { var retval = new byte[Length]; Buffer.BlockCopy(Bytes, 0, retval, 0, Length); return retval; } internal bool TryGetBuffer(out ArraySegment bufSegment) { bufSegment = new ArraySegment(Bytes, 0, _bytesUsed); return true; } // IDisposable protected override void Dispose(bool disposing) { if (!IsDisposed) { if (disposing) { // nothing to do } } IsDisposed = true; } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Client/TSocketTransport.cs0000664000175000017500000002014515165535636025740 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; namespace Thrift.Transport.Client { // ReSharper disable once InconsistentNaming public class TSocketTransport : TStreamTransport { private bool _isDisposed; public TSocketTransport(TcpClient client, TConfiguration config) : base(config) { TcpClient = client ?? throw new ArgumentNullException(nameof(client)); SetInputOutputStream(); } /// /// The constructor for a TSocketTransport which takes an IPAddress object. /// /// The IP address. /// The TcpClient port number. /// The . /// The TcpClient send timeout. /// /// The TcpClient is not connected automatically. You are required to use . /// public TSocketTransport(IPAddress host, int port, TConfiguration config, int timeout = 0) : base(config) { Host = host; Port = port; TcpClient = new TcpClient(); TcpClient.ReceiveTimeout = TcpClient.SendTimeout = timeout; TcpClient.Client.NoDelay = true; SetInputOutputStream(); } /// /// The constructor for a TSocketTransport which takes either a host name, e.g. 'host.example.com' and port number. /// If host is not found using Dns.GetHostEntry(host) an exception will be thrown. /// /// The host name. /// The TcpClient port number. /// The . /// The TcpClient send timeout. /// /// /// The TcpClient is connected automatically. /// public TSocketTransport(string host, int port, TConfiguration config, int timeout = 0) : base(config) { try { var entry = Dns.GetHostEntry(host); if (entry.AddressList.Length == 0) throw new TTransportException(TTransportException.ExceptionType.Unknown, "unable to resolve host name"); Host = entry.AddressList[0]; Port = port; TcpClient = new TcpClient(host, port); TcpClient.ReceiveTimeout = TcpClient.SendTimeout = timeout; TcpClient.Client.NoDelay = true; SetInputOutputStream(); } catch (SocketException e) { throw new TTransportException(TTransportException.ExceptionType.Unknown, e.Message, e); } } /// /// The constructor for a TSocketTransport which takes either a host name, e.g. 'host.example.com' or and IP address string, e.g '123.456.789' and port number. /// If hostNameOrIpAddress represents a valid IP address this will be used directly. /// If hostNameOrIpAddress does not represent a valid IP address an IP address will be retrieved using Dns.GetHostEntry(hostNameOrIpAddress). /// If that fails an exception will be thrown. /// /// The host name or IP address. /// The TcpClient port number. /// If true attempt to connect the TcpClient. /// The . /// The TcpClient send timeout. /// /// /// The TcpClient is connected dependent on the value of ./>. /// public TSocketTransport(string hostNameOrIpAddress, int port, bool connectClient, TConfiguration config, int timeout = 0) : base(config) { try { if (!IPAddress.TryParse(hostNameOrIpAddress, out var address)) { var entry = Dns.GetHostEntry(hostNameOrIpAddress); if (entry.AddressList.Length == 0) throw new TTransportException(TTransportException.ExceptionType.Unknown, "unable to resolve host name"); address = entry.AddressList[0]; } Host = address; Port = port; TcpClient = new TcpClient(); TcpClient.ReceiveTimeout = TcpClient.SendTimeout = timeout; TcpClient.Client.NoDelay = true; if (connectClient) { TcpClient.Connect(Host, Port); } SetInputOutputStream(); } catch (SocketException e) { throw new TTransportException(TTransportException.ExceptionType.Unknown, e.Message, e); } } private void SetInputOutputStream() { if (IsOpen) { InputStream = TcpClient.GetStream(); OutputStream = TcpClient.GetStream(); } } public TcpClient TcpClient { get; private set; } public IPAddress Host { get; } public int Port { get; } public int Timeout { set { if (TcpClient != null) { TcpClient.ReceiveTimeout = TcpClient.SendTimeout = value; } } } public override bool IsOpen { get { return (TcpClient != null) && TcpClient.Connected; } } public override async Task OpenAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (IsOpen) { throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected"); } if (Port <= 0) { throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port"); } if (TcpClient == null) { throw new InvalidOperationException("Invalid or not initialized tcp client"); } await TcpClient.ConnectAsync(Host, Port); SetInputOutputStream(); } public override void Close() { base.Close(); if (TcpClient != null) { TcpClient.Dispose(); TcpClient = null; } } // IDisposable protected override void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { TcpClient?.Dispose(); base.Dispose(disposing); } } _isDisposed = true; } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs0000664000175000017500000001165415165535636026357 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.IO.Pipes; using System.Security.Principal; using System.Threading; using System.Threading.Tasks; namespace Thrift.Transport.Client { // ReSharper disable once InconsistentNaming public class TNamedPipeTransport : TEndpointTransport { private NamedPipeClientStream PipeStream; private readonly int ConnectTimeout; private const int DEFAULT_CONNECT_TIMEOUT = 60 * 1000; // Timeout.Infinite is not a good default public TNamedPipeTransport(string pipe, TConfiguration config, int timeout = DEFAULT_CONNECT_TIMEOUT) : this(".", pipe, config, timeout) { } public TNamedPipeTransport(string server, string pipe, TConfiguration config, int timeout = DEFAULT_CONNECT_TIMEOUT) : base(config) { var serverName = string.IsNullOrWhiteSpace(server) ? server : "."; ConnectTimeout = (timeout > 0) ? timeout : DEFAULT_CONNECT_TIMEOUT; PipeStream = new NamedPipeClientStream(serverName, pipe, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Anonymous); } public override bool IsOpen => PipeStream != null && PipeStream.IsConnected; public override async Task OpenAsync(CancellationToken cancellationToken) { if (IsOpen) { throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen); } await PipeStream.ConnectAsync( ConnectTimeout, cancellationToken); ResetMessageSizeAndConsumedBytes(); } public override void Close() { if (PipeStream != null) { if (PipeStream.IsConnected) PipeStream.Close(); PipeStream.Dispose(); PipeStream = null; } } public override async ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { if (PipeStream == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } CheckReadBytesAvailable(length); #if NET5_0_OR_GREATER var numRead = await PipeStream.ReadAsync(new Memory(buffer, offset, length), cancellationToken); #else var numRead = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken); #endif CountConsumedMessageBytes(numRead); return numRead; } public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { if (PipeStream == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // if necessary, send the data in chunks // there's a system limit around 0x10000 bytes that we hit otherwise // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section." var nBytes = Math.Min(15 * 4096, length); // 16 would exceed the limit while (nBytes > 0) { #if NET5_0_OR_GREATER await PipeStream.WriteAsync(buffer.AsMemory(offset, nBytes), cancellationToken); #else await PipeStream.WriteAsync(buffer, offset, nBytes, cancellationToken); #endif offset += nBytes; length -= nBytes; nBytes = Math.Min(nBytes, length); } } public override async Task FlushAsync(CancellationToken cancellationToken) { await PipeStream.FlushAsync(cancellationToken); ResetMessageSizeAndConsumedBytes(); } protected override void Dispose(bool disposing) { if (disposing) { if (PipeStream != null) { if (PipeStream.IsConnected) PipeStream.Close(); PipeStream.Dispose(); PipeStream = null; } } } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Client/THttpTransport.cs0000664000175000017500000002715015165535636025432 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; #pragma warning disable IDE0079 // unneeded suppression -> all except net8 #pragma warning disable IDE0301 // simplify collection init -> net8 only #pragma warning disable IDE0305 // simplify collection init -> net8 only namespace Thrift.Transport.Client { // ReSharper disable once InconsistentNaming public class THttpTransport : TEndpointTransport { private readonly X509Certificate[] _certificates; private readonly Uri _uri; private int _connectTimeout = 30000; // Timeouts in milliseconds private HttpClient _httpClient; private Stream _inputStream; private MemoryStream _outputStream = new MemoryStream(); private bool _isDisposed; public THttpTransport(Uri uri, TConfiguration config, IDictionary customRequestHeaders = null, string userAgent = null) : this(uri, config, Enumerable.Empty(), customRequestHeaders, userAgent) { } public THttpTransport(Uri uri, TConfiguration config, IEnumerable certificates, IDictionary customRequestHeaders, string userAgent = null) : base(config) { _uri = uri; _certificates = (certificates ?? Enumerable.Empty()).ToArray(); if (!string.IsNullOrEmpty(userAgent)) UserAgent = userAgent; // due to current bug with performance of Dispose in netcore https://github.com/dotnet/corefx/issues/8809 // this can be switched to default way (create client->use->dispose per flush) later _httpClient = CreateClient(customRequestHeaders); ConfigureClient(_httpClient); } /// /// Constructor that takes a HttpClient instance to support using IHttpClientFactory. /// /// As the HttpMessageHandler of the client must be configured at the time of creation, it /// is assumed that the consumer has already added any certificates and configured decompression methods. The /// consumer can use the CreateHttpClientHandler method to get a handler with these set. /// Client configured with the desired message handler, user agent, and URI if not /// specified in the uri parameter. A default user agent will be used if not set. /// Thrift configuration object /// Optional URI to use for requests, if not specified the base address of httpClient /// is used. public THttpTransport(HttpClient httpClient, TConfiguration config, Uri uri = null) : base(config) { _httpClient = httpClient; _uri = uri ?? httpClient.BaseAddress; httpClient.BaseAddress = _uri; var userAgent = _httpClient.DefaultRequestHeaders.UserAgent.ToString(); if (!string.IsNullOrEmpty(userAgent)) UserAgent = userAgent; ConfigureClient(_httpClient); } // According to RFC 2616 section 3.8, the "User-Agent" header may not carry a version number public readonly string UserAgent = "Thrift netstd THttpClient"; public int ConnectTimeout { set { _connectTimeout = value; if(_httpClient != null) _httpClient.Timeout = TimeSpan.FromMilliseconds(_connectTimeout); } get { if (_httpClient == null) return _connectTimeout; return (int)_httpClient.Timeout.TotalMilliseconds; } } public override bool IsOpen => true; public HttpRequestHeaders RequestHeaders => _httpClient.DefaultRequestHeaders; public MediaTypeHeaderValue ContentType { get; set; } public override Task OpenAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override void Close() { if (_inputStream != null) { _inputStream.Dispose(); _inputStream = null; } if (_outputStream != null) { _outputStream.Dispose(); _outputStream = null; } if (_httpClient != null) { _httpClient.Dispose(); _httpClient = null; } } public override async ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (_inputStream == null) throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No request has been sent"); CheckReadBytesAvailable(length); try { #if NET5_0_OR_GREATER var ret = await _inputStream.ReadAsync(new Memory(buffer, offset, length), cancellationToken); #else var ret = await _inputStream.ReadAsync(buffer, offset, length, cancellationToken); #endif if (ret == -1) { throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "No more data available"); } CountConsumedMessageBytes(ret); return ret; } catch (IOException iox) { throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox); } } public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); #if NET5_0_OR_GREATER await _outputStream.WriteAsync(buffer.AsMemory(offset, length), cancellationToken); #else await _outputStream.WriteAsync(buffer, offset, length, cancellationToken); #endif } /// /// Get a client handler configured with recommended properties to use with the HttpClient constructor /// and an IHttpClientFactory. /// /// An optional array of client certificates to associate with the handler. /// /// A client handler with deflate and gZip compression-decompression algorithms and any client /// certificates passed in via certificates. /// public virtual HttpClientHandler CreateHttpClientHandler(X509Certificate[] certificates = null) { var handler = new HttpClientHandler(); if (certificates != null) handler.ClientCertificates.AddRange(certificates); handler.AutomaticDecompression = System.Net.DecompressionMethods.Deflate | System.Net.DecompressionMethods.GZip; return handler; } private HttpClient CreateClient(IDictionary customRequestHeaders) { var handler = CreateHttpClientHandler(_certificates); var httpClient = new HttpClient(handler); if (customRequestHeaders != null) { foreach (var item in customRequestHeaders) { httpClient.DefaultRequestHeaders.Add(item.Key, item.Value); } } return httpClient; } private void ConfigureClient(HttpClient httpClient) { if (_connectTimeout > 0) { httpClient.Timeout = TimeSpan.FromMilliseconds(_connectTimeout); } httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-thrift")); // Clear any user agent values to avoid drift with the field value httpClient.DefaultRequestHeaders.UserAgent.Clear(); httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(UserAgent); httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); } public override async Task FlushAsync(CancellationToken cancellationToken) { try { _outputStream.Seek(0, SeekOrigin.Begin); using (var contentStream = new StreamContent(_outputStream)) { contentStream.Headers.ContentType = ContentType ?? new MediaTypeHeaderValue(@"application/x-thrift"); var response = (await _httpClient.PostAsync(_uri, contentStream, cancellationToken)).EnsureSuccessStatusCode(); _inputStream?.Dispose(); #if NET5_0_OR_GREATER _inputStream = await response.Content.ReadAsStreamAsync(cancellationToken); #else _inputStream = await response.Content.ReadAsStreamAsync(); #endif if (_inputStream.CanSeek) { _inputStream.Seek(0, SeekOrigin.Begin); } } } catch (IOException iox) { throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox); } catch (HttpRequestException wx) { throw new TTransportException(TTransportException.ExceptionType.Unknown, "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, ex); } finally { _outputStream = new MemoryStream(); ResetMessageSizeAndConsumedBytes(); } } // IDisposable protected override void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { _inputStream?.Dispose(); _outputStream?.Dispose(); _httpClient?.Dispose(); } } _isDisposed = true; } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs0000664000175000017500000002402215165535636026421 0ustar00buildbuild00000000000000// 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.Diagnostics; using System.Net; using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0028 // net8 - simplified collection init namespace Thrift.Transport.Client { //TODO: check for correct work // ReSharper disable once InconsistentNaming public class TTlsSocketTransport : TStreamTransport { private readonly X509Certificate2 _certificate; private readonly RemoteCertificateValidationCallback _certValidator; private readonly IPAddress _host; private readonly bool _isServer; private readonly LocalCertificateSelectionCallback _localCertificateSelectionCallback; private readonly int _port; private readonly SslProtocols _sslProtocols; private readonly string _targetHost; private TcpClient _client; private SslStream _secureStream; private int _timeout; #if NET7_0_OR_GREATER public const SslProtocols DefaultSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13; #else public const SslProtocols DefaultSslProtocols = SslProtocols.Tls12; #endif public TTlsSocketTransport(TcpClient client, TConfiguration config, X509Certificate2 certificate, bool isServer = false, RemoteCertificateValidationCallback certValidator = null, LocalCertificateSelectionCallback localCertificateSelectionCallback = null, SslProtocols sslProtocols = DefaultSslProtocols) : base(config) { _client = client; _certificate = certificate; _certValidator = certValidator; _localCertificateSelectionCallback = localCertificateSelectionCallback; _sslProtocols = sslProtocols; _isServer = isServer; if (isServer && certificate == null) { throw new ArgumentException("TTlsSocketTransport needs certificate to be used for server", nameof(certificate)); } if (IsOpen) { InputStream = client.GetStream(); OutputStream = client.GetStream(); } } #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, LocalCertificateSelectionCallback localCertificateSelectionCallback = null, SslProtocols sslProtocols = DefaultSslProtocols) : this(host, port, config, 0, new X509Certificate2(certificatePath), certValidator, localCertificateSelectionCallback, sslProtocols) { } #pragma warning restore SYSLIB0057 public TTlsSocketTransport(IPAddress host, int port, TConfiguration config, X509Certificate2 certificate = null, RemoteCertificateValidationCallback certValidator = null, LocalCertificateSelectionCallback localCertificateSelectionCallback = null, SslProtocols sslProtocols = DefaultSslProtocols) : this(host, port, config, 0, certificate, certValidator, localCertificateSelectionCallback, sslProtocols) { } public TTlsSocketTransport(IPAddress host, int port, TConfiguration config, int timeout, X509Certificate2 certificate, RemoteCertificateValidationCallback certValidator = null, LocalCertificateSelectionCallback localCertificateSelectionCallback = null, SslProtocols sslProtocols = DefaultSslProtocols) : base(config) { _host = host; _port = port; _timeout = timeout; _certificate = certificate; _certValidator = certValidator; _localCertificateSelectionCallback = localCertificateSelectionCallback; _sslProtocols = sslProtocols; InitSocket(); } public TTlsSocketTransport(string host, int port, TConfiguration config, int timeout, X509Certificate2 certificate, RemoteCertificateValidationCallback certValidator = null, LocalCertificateSelectionCallback localCertificateSelectionCallback = null, SslProtocols sslProtocols = DefaultSslProtocols) : base(config) { try { _targetHost = host; var entry = Dns.GetHostEntry(host); if (entry.AddressList.Length == 0) throw new TTransportException(TTransportException.ExceptionType.Unknown, "unable to resolve host name"); _host = entry.AddressList[0]; _port = port; _timeout = timeout; _certificate = certificate; _certValidator = certValidator; _localCertificateSelectionCallback = localCertificateSelectionCallback; _sslProtocols = sslProtocols; InitSocket(); } catch (SocketException e) { throw new TTransportException(TTransportException.ExceptionType.Unknown, e.Message, e); } } public int Timeout { set { _client.ReceiveTimeout = _client.SendTimeout = _timeout = value; } } public TcpClient TcpClient => _client; public IPAddress Host => _host; public int Port => _port; public override bool IsOpen { get { if (_client == null) { return false; } return _client.Connected; } } private void InitSocket() { _client = new TcpClient(); _client.ReceiveTimeout = _client.SendTimeout = _timeout; _client.Client.NoDelay = true; } private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslValidationErrors) { return sslValidationErrors == SslPolicyErrors.None; } public override async Task OpenAsync(CancellationToken cancellationToken) { if (IsOpen) { throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected"); } if (_host == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host"); } if (_port <= 0) { throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port"); } if (_client == null) { InitSocket(); } if (_client != null) { await _client.ConnectAsync(_host, _port); await SetupTlsAsync(); } } public async Task SetupTlsAsync() { var validator = _certValidator ?? DefaultCertificateValidator; if (_localCertificateSelectionCallback != null) { _secureStream = new SslStream(_client.GetStream(), false, validator, _localCertificateSelectionCallback); } else { _secureStream = new SslStream(_client.GetStream(), false, validator); } try { if (_isServer) { // Server authentication await _secureStream.AuthenticateAsServerAsync(_certificate, _certValidator != null, _sslProtocols, true); } else { // Client authentication var certs = _certificate != null ? new X509CertificateCollection { _certificate } : new X509CertificateCollection(); var targetHost = _targetHost ?? _host.ToString(); await _secureStream.AuthenticateAsClientAsync(targetHost, certs, _sslProtocols, true); } } catch (Exception) { Close(); throw; } InputStream = _secureStream; OutputStream = _secureStream; } public override void Close() { base.Close(); if (_client != null) { _client.Dispose(); _client = null; } if (_secureStream != null) { _secureStream.Dispose(); _secureStream = null; } } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs0000664000175000017500000001104615165535636025743 0ustar00buildbuild00000000000000// 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.Drawing; using System.IO; using System.Threading; using System.Threading.Tasks; namespace Thrift.Transport.Client { // ReSharper disable once InconsistentNaming public class TStreamTransport : TEndpointTransport { private bool _isDisposed; protected TStreamTransport(TConfiguration config) :base(config) { } public TStreamTransport(Stream inputStream, Stream outputStream, TConfiguration config) : base(config) { InputStream = inputStream; OutputStream = outputStream; } protected Stream OutputStream { get; set; } private Stream _InputStream = null; protected Stream InputStream { get => _InputStream; set { _InputStream = value; 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) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override void Close() { if (InputStream != null) { InputStream.Dispose(); InputStream = null; } if (OutputStream != null) { OutputStream.Dispose(); OutputStream = null; } } public override async ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { if (InputStream == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot read from null inputstream"); } #if NET5_0_OR_GREATER return await InputStream.ReadAsync(new Memory(buffer, offset, length), cancellationToken); #else return await InputStream.ReadAsync(buffer, offset, length, cancellationToken); #endif } public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { if (OutputStream == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot write to null outputstream"); } #if NET5_0_OR_GREATER await OutputStream.WriteAsync(buffer.AsMemory(offset, length), cancellationToken); #else await OutputStream.WriteAsync(buffer, offset, length, cancellationToken); #endif } public override async Task FlushAsync(CancellationToken cancellationToken) { await OutputStream.FlushAsync(cancellationToken); ResetMessageSizeAndConsumedBytes(); } // IDisposable protected override void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { InputStream?.Dispose(); OutputStream?.Dispose(); } } _isDisposed = true; } } } thrift-0.23.0/lib/netstd/Thrift/Transport/TTransportException.cs0000664000175000017500000000343715165535636025235 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; namespace Thrift.Transport { // ReSharper disable once InconsistentNaming public class TTransportException : TException { public enum ExceptionType { Unknown, NotOpen, AlreadyOpen, TimedOut, EndOfFile, Interrupted, MessageSizeLimit } public ExceptionType ExType { get; private set; } public TTransportException() { } public TTransportException(ExceptionType exType, Exception inner = null) : base(string.Empty, inner) { ExType = exType; } public TTransportException(ExceptionType exType, string message, Exception inner = null) : base(message, inner) { ExType = exType; } public TTransportException(string message, Exception inner = null) : base(message, inner) { } public ExceptionType Type => ExType; } } thrift-0.23.0/lib/netstd/Thrift/Transport/Server/0000775000175000017500000000000015165535636022146 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs0000664000175000017500000001273415165535636026653 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Thrift.Processor; using Thrift.Protocol; using Thrift.Transport.Client; namespace Thrift.Transport.Server { // ReSharper disable once InconsistentNaming public class THttpServerTransport { protected const string ContentType = "application/x-thrift"; /* never used private readonly ILogger _logger; private readonly RequestDelegate _next; */ protected Encoding Encoding = Encoding.UTF8; protected TProtocolFactory InputProtocolFactory; protected TProtocolFactory OutputProtocolFactory; protected TTransportFactory InputTransportFactory; protected TTransportFactory OutputTransportFactory; protected ITAsyncProcessor Processor; protected TConfiguration Configuration; public THttpServerTransport( ITAsyncProcessor processor, TConfiguration config, RequestDelegate next = null, ILoggerFactory loggerFactory = null) : this(processor, config, new TBinaryProtocol.Factory(), null, next, loggerFactory) { } public THttpServerTransport( ITAsyncProcessor processor, TConfiguration config, TProtocolFactory protocolFactory, TTransportFactory transFactory = null, RequestDelegate next = null, ILoggerFactory loggerFactory = null) : this(processor, config, protocolFactory, protocolFactory, transFactory, transFactory, next, loggerFactory) { } public THttpServerTransport( ITAsyncProcessor processor, TConfiguration config, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TTransportFactory inputTransFactory = null, TTransportFactory outputTransFactory = null, RequestDelegate next = null, ILoggerFactory loggerFactory = null) { // loggerFactory == null is not illegal anymore Processor = processor ?? throw new ArgumentNullException(nameof(processor)); Configuration = config; // may be null InputProtocolFactory = inputProtocolFactory ?? throw new ArgumentNullException(nameof(inputProtocolFactory)); OutputProtocolFactory = outputProtocolFactory ?? throw new ArgumentNullException(nameof(outputProtocolFactory)); InputTransportFactory = inputTransFactory; OutputTransportFactory = outputTransFactory; // never used _ = next; _ = loggerFactory; /* never used _next = next; _logger = (loggerFactory != null) ? loggerFactory.CreateLogger() : new NullLogger(); */ } public async Task Invoke(HttpContext context) { await ProcessRequestAsync(context, context.RequestAborted); //TODO: check for correct logic } public async Task ProcessRequestAsync(HttpContext context, CancellationToken cancellationToken) { var transport = new TStreamTransport(context.Request.Body, context.Response.Body, Configuration); try { var intrans = (InputTransportFactory != null) ? InputTransportFactory.GetTransport(transport) : transport; var outtrans = (OutputTransportFactory != null) ? OutputTransportFactory.GetTransport(transport) : transport; var input = InputProtocolFactory.GetProtocol(intrans); var output = OutputProtocolFactory.GetProtocol(outtrans); context.Response.ContentType = ContentType; while (await Processor.ProcessAsync(input, output, cancellationToken)) { if (!context.Response.HasStarted) // oneway method called await context.Response.Body.FlushAsync(cancellationToken); } } catch (TTransportException) { if (!context.Response.HasStarted) // if something goes bust, let the client know context.Response.StatusCode = 500; // internal server error } catch (TProtocolException) { if (!context.Response.HasStarted) // if something goes bust, let the client know context.Response.StatusCode = 400; // bad request, e.g. required field missing } finally { transport.Close(); } } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Server/NullLogger.cs0000664000175000017500000000321515165535636024550 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Microsoft.Extensions.Logging; using System; namespace Thrift.Transport.Server { // sometimes we just don't want to log anything internal class NullLogger : IDisposable, ILogger, ILogger { internal class NullScope : IDisposable { public void Dispose() { // nothing to do } } public IDisposable BeginScope(TState state) { return new NullScope(); } public void Dispose() { // nothing to do } public bool IsEnabled(LogLevel logLevel) { return false; // no } public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { // do nothing } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs0000664000175000017500000001447715165535636027655 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Net; using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; using Thrift.Transport.Client; namespace Thrift.Transport.Server { // ReSharper disable once InconsistentNaming public class TTlsServerSocketTransport : TServerTransport { private readonly RemoteCertificateValidationCallback _clientCertValidator; private readonly int _clientTimeout = 0; private readonly LocalCertificateSelectionCallback _localCertificateSelectionCallback; private readonly X509Certificate2 _serverCertificate; private readonly SslProtocols _sslProtocols; private TcpListener _server; public TTlsServerSocketTransport( TcpListener listener, TConfiguration config, X509Certificate2 certificate, RemoteCertificateValidationCallback clientCertValidator = null, LocalCertificateSelectionCallback localCertificateSelectionCallback = null, SslProtocols sslProtocols = TTlsSocketTransport.DefaultSslProtocols) : base(config) { if (!certificate.HasPrivateKey) { throw new TTransportException(TTransportException.ExceptionType.Unknown, "Your server-certificate needs to have a private key"); } _serverCertificate = certificate; _clientCertValidator = clientCertValidator; _localCertificateSelectionCallback = localCertificateSelectionCallback; _sslProtocols = sslProtocols; _server = listener; } public TTlsServerSocketTransport( int port, TConfiguration config, X509Certificate2 certificate, RemoteCertificateValidationCallback clientCertValidator = null, LocalCertificateSelectionCallback localCertificateSelectionCallback = null, SslProtocols sslProtocols = TTlsSocketTransport.DefaultSslProtocols) : this(null, config, certificate, clientCertValidator, localCertificateSelectionCallback, sslProtocols) { try { // Create server socket _server = new TcpListener(IPAddress.Any, port); _server.Server.NoDelay = true; } catch (Exception ex) { _server = null; throw new TTransportException($"Could not create ServerSocket on port {port}.", ex); } } public override bool IsOpen() { return (_server != null) && (_server.Server != null) && _server.Server.IsBound; } public int GetPort() { if ((_server != null) && (_server.Server != null) && (_server.Server.LocalEndPoint != null)) { if (_server.Server.LocalEndPoint is IPEndPoint server) { return server.Port; } else { throw new TTransportException("ServerSocket is not a network socket"); } } else { throw new TTransportException("ServerSocket is not open"); } } public override void Listen() { // Make sure accept is not blocking if (_server != null) { try { _server.Start(); } catch (SocketException sx) { throw new TTransportException($"Could not accept on listening socket: {sx.Message}", sx); } } } public override bool IsClientPending() { return _server.Pending(); } protected override async ValueTask AcceptImplementationAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (_server == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket."); } try { #if NET6_0_OR_GREATER var client = await _server.AcceptTcpClientAsync(cancellationToken); #else var client = await _server.AcceptTcpClientAsync(); #endif client.SendTimeout = client.ReceiveTimeout = _clientTimeout; //wrap the client in an SSL Socket passing in the SSL cert var tTlsSocket = new TTlsSocketTransport( client, Configuration, _serverCertificate, true, _clientCertValidator, _localCertificateSelectionCallback, _sslProtocols); await tTlsSocket.SetupTlsAsync(); return tTlsSocket; } catch (Exception ex) { throw new TTransportException(ex.ToString(), ex); } } public override void Close() { if (_server != null) { try { _server.Stop(); } catch (Exception ex) { throw new TTransportException($"WARNING: Could not close server socket: {ex}", ex); } _server = null; } } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs0000664000175000017500000001252415165535636027161 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Thrift.Transport.Client; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Transport.Server { // ReSharper disable once InconsistentNaming public class TServerSocketTransport : TServerTransport { private readonly int _clientTimeout; private TcpListener _server; public TServerSocketTransport(TcpListener listener, TConfiguration config, int clientTimeout = 0) : base(config) { _server = listener; _clientTimeout = clientTimeout; } public TServerSocketTransport(int port, TConfiguration config, int clientTimeout = 0) : this(null, config, clientTimeout) { try { // Make server socket _server = new TcpListener(IPAddress.IPv6Any, port); _server.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); _server.Server.NoDelay = true; } catch (Exception ex) { _server = null; throw new TTransportException("Could not create ServerSocket on port " + port + ".", ex); } } public override bool IsOpen() { return (_server != null) && (_server.Server != null) && _server.Server.IsBound; } public int GetPort() { if ((_server != null) && (_server.Server != null) && (_server.Server.LocalEndPoint != null)) { if (_server.Server.LocalEndPoint is IPEndPoint server) { return server.Port; } else { throw new TTransportException("ServerSocket is not a network socket"); } } else { throw new TTransportException("ServerSocket is not open"); } } public override void Listen() { // Make sure not to block on accept if (_server != null) { try { _server.Start(); } catch (SocketException sx) { throw new TTransportException("Could not accept on listening socket: " + sx.Message, sx); } } } public override bool IsClientPending() { return _server.Pending(); } protected override async ValueTask AcceptImplementationAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (_server == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket."); } try { TTransport tSocketTransport = null; #if NET6_0_OR_GREATER var tcpClient = await _server.AcceptTcpClientAsync(cancellationToken); #else var tcpClient = await _server.AcceptTcpClientAsync(); #endif try { tSocketTransport = new TSocketTransport(tcpClient, Configuration) { Timeout = _clientTimeout }; return tSocketTransport; } catch (Exception) { if (tSocketTransport != null) { tSocketTransport.Dispose(); } else // Otherwise, clean it up ourselves. { ((IDisposable)tcpClient).Dispose(); } throw; } } catch (Exception ex) { throw new TTransportException(ex.ToString(), ex); } } public override void Close() { if (_server != null) { try { _server.Stop(); } catch (Exception ex) { throw new TTransportException("WARNING: Could not close server socket: " + ex, ex); } _server = null; } } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs0000664000175000017500000004213215165535636027571 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Microsoft.Win32.SafeHandles; using System; using System.IO.Pipes; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.ComponentModel; using System.Security.AccessControl; using System.Security.Principal; using System.Collections.Generic; using System.IO; using System.Diagnostics; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0028 // net8 - simplified collection init #pragma warning disable IDE0300 // net8 - simplified collection init #pragma warning disable IDE0290 // net8 - primary CTOR #pragma warning disable SYSLIB1054 // net8 - use LibraryImport attribute #pragma warning disable CS1998 // async no await namespace Thrift.Transport.Server { [Flags] public enum NamedPipeServerFlags { None = 0x00, OnlyLocalClients = 0x01, }; // ReSharper disable once InconsistentNaming public class TNamedPipeServerTransport : TServerTransport { // to manage incoming connections, we set up a task for each stream to listen on private struct TaskStreamPair { public readonly NamedPipeServerStream Stream; public Task Task; public TaskStreamPair(NamedPipeServerStream stream, Task task) { Stream = stream; Task = task; } } /// /// This is the address of the Pipe on the localhost. /// private readonly string _pipeAddress; private bool _asyncMode = true; private volatile bool _isPending = true; private readonly List _streams = new List(); private readonly bool _onlyLocalClients = false; // compatibility default private readonly byte _numListenPipes = 1; // compatibility default public TNamedPipeServerTransport(string pipeAddress, TConfiguration config, NamedPipeServerFlags flags, int numListenPipes) : base(config) { if ((numListenPipes < 1) || (numListenPipes > 254)) throw new ArgumentOutOfRangeException(nameof(numListenPipes), "Value must be in the range of [1..254]"); _pipeAddress = pipeAddress; _onlyLocalClients = flags.HasFlag(NamedPipeServerFlags.OnlyLocalClients); _numListenPipes = (byte)numListenPipes; } public override bool IsOpen() { return true; } public override void Listen() { // nothing to do here } private static void Close(NamedPipeServerStream pipe) { if (pipe != null) { try { if (pipe.IsConnected) pipe.Disconnect(); } finally { pipe.Dispose(); } } } public override void Close() { try { if (_streams != null) { while(_streams.Count > 0) { Close(_streams[0].Stream); _streams.RemoveAt(0); } } } finally { _streams.Clear(); _isPending = false; } } public override bool IsClientPending() { return _isPending; } private void EnsurePipeInstances() { // set up a pool for accepting multiple calls when in multithread mode // once connected, we hand that stream over to the processor and create a fresh one try { while (_streams.Count < _numListenPipes) _streams.Add(CreatePipeInstance()); } catch { // we might not be able to create all requested instances, e.g. due to some existing instances already processing calls // if we have at least one pipe to listen on -> Good Enough(tm) if (_streams.Count < 1) throw; // no pipes is really bad } } private TaskStreamPair CreatePipeInstance() { const PipeDirection direction = PipeDirection.InOut; const int maxconn = NamedPipeServerStream.MaxAllowedServerInstances; const PipeTransmissionMode mode = PipeTransmissionMode.Byte; const int inbuf = 4096; const int outbuf = 4096; var options = _asyncMode ? PipeOptions.Asynchronous : PipeOptions.None; // TODO: "CreatePipeNative" ist only a workaround, and there are have basically two possible outcomes: // - once NamedPipeServerStream() gets a CTOR that supports pipesec, remove CreatePipeNative() // - if 31190 gets resolved before, use _stream.SetAccessControl(pipesec) instead of CreatePipeNative() // EITHER WAY, // - if CreatePipeNative() finally gets removed, also remove "allow unsafe code" from the project settings NamedPipeServerStream instance; try { var handle = CreatePipeNative(_pipeAddress, inbuf, outbuf, _onlyLocalClients); if ((handle != null) && (!handle.IsInvalid)) { instance = new NamedPipeServerStream(PipeDirection.InOut, _asyncMode, false, handle); handle = null; // we don't own it any longer } else { handle?.Dispose(); instance = new NamedPipeServerStream(_pipeAddress, direction, maxconn, mode, options, inbuf, outbuf/*, pipesec*/); } } catch (NotImplementedException) // Mono still does not support async, fallback to sync { if (_asyncMode) { options &= (~PipeOptions.Asynchronous); instance = new NamedPipeServerStream(_pipeAddress, direction, maxconn, mode, options, inbuf, outbuf); _asyncMode = false; } else { throw; } } // the task gets added later return new TaskStreamPair( instance, null); } #region CreatePipeNative workaround [StructLayout(LayoutKind.Sequential)] internal class SECURITY_ATTRIBUTES { internal int nLength = 0; internal IntPtr lpSecurityDescriptor = IntPtr.Zero; internal int bInheritHandle = 0; } private const string Kernel32 = "kernel32.dll"; [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern IntPtr CreateNamedPipe( string lpName, uint dwOpenMode, uint dwPipeMode, uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut, SECURITY_ATTRIBUTES pipeSecurityDescriptor ); // Workaround: create the pipe via API call // we have to do it this way, since NamedPipeServerStream() for netstd still lacks a few CTORs and/or arguments // and _stream.SetAccessControl(pipesec); only keeps throwing ACCESS_DENIED errors at us // References: // - https://github.com/dotnet/corefx/issues/30170 (closed, continued in 31190) // - https://github.com/dotnet/corefx/issues/31190 System.IO.Pipes.AccessControl package does not work // - https://github.com/dotnet/corefx/issues/24040 NamedPipeServerStream: Provide support for WRITE_DAC // - https://github.com/dotnet/corefx/issues/34400 Have a mechanism for lower privileged user to connect to a privileged user's pipe private static SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf, bool OnlyLocalClients) { if (! RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return null; // Windows only var pinningHandle = new GCHandle(); try { // owner gets full access, everyone else read/write var pipesec = new PipeSecurity(); using (var currentIdentity = WindowsIdentity.GetCurrent()) { var sidOwner = currentIdentity.Owner; var sidWorld = new SecurityIdentifier(WellKnownSidType.WorldSid, null); pipesec.SetOwner(sidOwner); pipesec.AddAccessRule(new PipeAccessRule(sidOwner, PipeAccessRights.FullControl, AccessControlType.Allow)); pipesec.AddAccessRule(new PipeAccessRule(sidWorld, PipeAccessRights.ReadWrite, AccessControlType.Allow)); } // create a security descriptor and assign it to the security attribs var secAttrs = new SECURITY_ATTRIBUTES(); byte[] sdBytes = pipesec.GetSecurityDescriptorBinaryForm(); pinningHandle = GCHandle.Alloc(sdBytes, GCHandleType.Pinned); unsafe { fixed (byte* pSD = sdBytes) { secAttrs.lpSecurityDescriptor = (IntPtr)pSD; } } // a bunch of constants we will need shortly const uint PIPE_ACCESS_DUPLEX = 0x00000003; const uint FILE_FLAG_OVERLAPPED = 0x40000000; const uint WRITE_DAC = 0x00040000; const uint PIPE_TYPE_BYTE = 0x00000000; const uint PIPE_READMODE_BYTE = 0x00000000; const uint PIPE_UNLIMITED_INSTANCES = 255; const uint PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000; // Connections from remote clients can be accepted and checked against the security descriptor for the pipe. const uint PIPE_REJECT_REMOTE_CLIENTS = 0x00000008; // Connections from remote clients are automatically rejected. // any extra flags we want to add uint dwPipeModeXtra = (OnlyLocalClients ? PIPE_REJECT_REMOTE_CLIENTS : PIPE_ACCEPT_REMOTE_CLIENTS) ; // create the pipe via API call var rawHandle = CreateNamedPipe( @"\\.\pipe\" + name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | dwPipeModeXtra, PIPE_UNLIMITED_INSTANCES, (uint)inbuf, (uint)outbuf, 5 * 1000, secAttrs ); // make a SafePipeHandle() from it var handle = new SafePipeHandle(rawHandle, true); if (handle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); // return it (to be packaged) return handle; } finally { if (pinningHandle.IsAllocated) pinningHandle.Free(); } } #endregion protected override async ValueTask AcceptImplementationAsync(CancellationToken cancellationToken) { try { EnsurePipeInstances(); // fill the list and wait for any task to be completed var tasks = new List(); for (var i = 0; i < _streams.Count; ++i) { if (_streams[i].Task == null) { var pair = _streams[i]; pair.Task = Task.Run(async () => await pair.Stream.WaitForConnectionAsync(cancellationToken), cancellationToken); _streams[i] = pair; } tasks.Add(_streams[i].Task); } // there must be an exact mapping between task index and stream index Debug.Assert(_streams.Count == tasks.Count); #pragma warning disable IDE0305 // see https://github.com/dotnet/roslyn/issues/70656 - yet unsolved var index = Task.WaitAny(tasks.ToArray(), cancellationToken); #pragma warning restore IDE0305 var trans = new ServerTransport(_streams[index].Stream, Configuration); _streams.RemoveAt(index); // pass stream ownership to ServerTransport return trans; } catch (TTransportException) { Close(); throw; } catch (TaskCanceledException) { Close(); throw; // let it bubble up } catch (Exception e) { Close(); throw new TTransportException(TTransportException.ExceptionType.NotOpen, e.Message, e); } } private class ServerTransport : TEndpointTransport { private NamedPipeServerStream PipeStream; public ServerTransport(NamedPipeServerStream stream, TConfiguration config) : base(config) { PipeStream = stream; } public override bool IsOpen => PipeStream != null && PipeStream.IsConnected; public override Task OpenAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override void Close() { if (PipeStream != null) { if (PipeStream.IsConnected) PipeStream.Disconnect(); PipeStream.Dispose(); PipeStream = null; } } public override async ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { if (PipeStream == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } CheckReadBytesAvailable(length); #if NET5_0_OR_GREATER var numBytes = await PipeStream.ReadAsync(buffer.AsMemory(offset, length), cancellationToken); #else var numBytes = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken); #endif CountConsumedMessageBytes(numBytes); return numBytes; } public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { if (PipeStream == null) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // if necessary, send the data in chunks // there's a system limit around 0x10000 bytes that we hit otherwise // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section." var nBytes = Math.Min(15 * 4096, length); // 16 would exceed the limit while (nBytes > 0) { #if NET5_0_OR_GREATER await PipeStream.WriteAsync(buffer.AsMemory(offset, nBytes), cancellationToken); #else await PipeStream.WriteAsync(buffer, offset, nBytes, cancellationToken); #endif offset += nBytes; length -= nBytes; nBytes = Math.Min(nBytes, length); } } public override async Task FlushAsync(CancellationToken cancellationToken) { await PipeStream.FlushAsync(cancellationToken); ResetMessageSizeAndConsumedBytes(); } protected override void Dispose(bool disposing) { if (disposing) { if (PipeStream != null) { if (PipeStream.IsConnected) PipeStream.Disconnect(); PipeStream.Dispose(); PipeStream = null; } } } } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Server/TServerTransport.cs0000664000175000017500000000354515165535636026013 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Threading; using System.Threading.Tasks; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Transport { // ReSharper disable once InconsistentNaming public abstract class TServerTransport { public readonly TConfiguration Configuration; public TServerTransport(TConfiguration config) { Configuration = config ?? new TConfiguration(); } public abstract bool IsOpen(); public abstract void Listen(); public abstract void Close(); public abstract bool IsClientPending(); protected abstract ValueTask AcceptImplementationAsync(CancellationToken cancellationToken = default); public async ValueTask AcceptAsync(CancellationToken cancellationToken = default) { return await AcceptImplementationAsync(cancellationToken) ?? throw new TTransportException($"{nameof(AcceptImplementationAsync)} should not return null"); } } } thrift-0.23.0/lib/netstd/Thrift/Transport/TTransportFactory.cs0000664000175000017500000000262115165535636024700 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. namespace Thrift.Transport { /// /// From Mark Slee & Aditya Agarwal of Facebook: /// Factory class used to create wrapped instance of Transports. /// This is used primarily in servers, which get Transports from /// a ServerTransport and then may want to mutate them (i.e. create /// a BufferedTransport from the underlying base transport) /// // ReSharper disable once InconsistentNaming public class TTransportFactory { public virtual TTransport GetTransport(TTransport trans) { return trans; } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Layered/0000775000175000017500000000000015165535636022265 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs0000664000175000017500000000342615165535636026247 0ustar00buildbuild00000000000000// 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; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Transport { public abstract class TLayeredTransport : TTransport { public readonly TTransport InnerTransport; public override TConfiguration Configuration { get => InnerTransport.Configuration; } public TLayeredTransport(TTransport transport) { InnerTransport = transport ?? throw new ArgumentNullException(nameof(transport)); } public override void UpdateKnownMessageSize(long size) { InnerTransport.UpdateKnownMessageSize(size); } public override void CheckReadBytesAvailable(long numBytes) { InnerTransport.CheckReadBytesAvailable(numBytes); } public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { InnerTransport.ResetMessageSizeAndConsumedBytes(newSize); } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Layered/TBufferedTransport.cs0000664000175000017500000001611615165535636026404 0ustar00buildbuild00000000000000// 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.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; namespace Thrift.Transport { // ReSharper disable once InconsistentNaming public class TBufferedTransport : TLayeredTransport { private readonly int DesiredBufferSize; private readonly Client.TMemoryBufferTransport ReadBuffer; private readonly Client.TMemoryBufferTransport WriteBuffer; private bool IsDisposed; public class Factory : TTransportFactory { public override TTransport GetTransport(TTransport trans) { return new TBufferedTransport(trans); } } //TODO: should support only specified input transport? public TBufferedTransport(TTransport transport, int bufSize = 1024) : base(transport) { if (bufSize <= 0) { throw new ArgumentOutOfRangeException(nameof(bufSize), "Buffer size must be a positive number."); } DesiredBufferSize = bufSize; WriteBuffer = new Client.TMemoryBufferTransport(InnerTransport.Configuration, bufSize); ReadBuffer = new Client.TMemoryBufferTransport(InnerTransport.Configuration, bufSize); Debug.Assert(DesiredBufferSize == ReadBuffer.Capacity); Debug.Assert(DesiredBufferSize == WriteBuffer.Capacity); } public TTransport UnderlyingTransport { get { CheckNotDisposed(); return InnerTransport; } } public override bool IsOpen => !IsDisposed && InnerTransport.IsOpen; public override async Task OpenAsync(CancellationToken cancellationToken) { CheckNotDisposed(); await InnerTransport.OpenAsync(cancellationToken); } public override void Close() { CheckNotDisposed(); InnerTransport.Close(); } public override async ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { CheckNotDisposed(); ValidateBufferArgs(buffer, offset, length); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // do we have something buffered? var count = ReadBuffer.Length - ReadBuffer.Position; if (count > 0) { return await ReadBuffer.ReadAsync(buffer, offset, length, cancellationToken); } // does the request even fit into the buffer? // Note we test for >= instead of > to avoid nonsense buffering if (length >= ReadBuffer.Capacity) { return await InnerTransport.ReadAsync(buffer, offset, length, cancellationToken); } // buffer a new chunk of bytes from the underlying transport ReadBuffer.Length = ReadBuffer.Capacity; ReadBuffer.TryGetBuffer(out ArraySegment bufSegment); ReadBuffer.Length = await InnerTransport.ReadAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken); ReadBuffer.Position = 0; // deliver the bytes return await ReadBuffer.ReadAsync(buffer, offset, length, cancellationToken); } public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { CheckNotDisposed(); ValidateBufferArgs(buffer, offset, length); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // enough space left in buffer? var free = WriteBuffer.Capacity - WriteBuffer.Length; if (length > free) { WriteBuffer.TryGetBuffer(out ArraySegment bufSegment); await InnerTransport.WriteAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken); WriteBuffer.SetLength(0); } // do the data even fit into the buffer? // Note we test for < instead of <= to avoid nonsense buffering if (length < WriteBuffer.Capacity) { await WriteBuffer.WriteAsync(buffer, offset, length, cancellationToken); return; } // write thru await InnerTransport.WriteAsync(buffer, offset, length, cancellationToken); } public override async Task FlushAsync(CancellationToken cancellationToken) { CheckNotDisposed(); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } if (WriteBuffer.Length > 0) { WriteBuffer.TryGetBuffer(out ArraySegment bufSegment); await InnerTransport.WriteAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken); WriteBuffer.SetLength(0); } await InnerTransport.FlushAsync(cancellationToken); } public override void CheckReadBytesAvailable(long numBytes) { var buffered = ReadBuffer.Length - ReadBuffer.Position; if (buffered < numBytes) { numBytes -= buffered; InnerTransport.CheckReadBytesAvailable(numBytes); } } public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { base.ResetMessageSizeAndConsumedBytes(newSize); ReadBuffer.ResetMessageSizeAndConsumedBytes(newSize); } private void CheckNotDisposed() { if (IsDisposed) { throw new ObjectDisposedException(nameof(InnerTransport)); } } // IDisposable protected override void Dispose(bool disposing) { if (!IsDisposed) { if (disposing) { ReadBuffer?.Dispose(); WriteBuffer?.Dispose(); InnerTransport?.Dispose(); } } IsDisposed = true; } } } thrift-0.23.0/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs0000664000175000017500000001537215165535636026063 0ustar00buildbuild00000000000000// 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.Buffers.Binary; using System.IO; using System.Threading; using System.Threading.Tasks; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable CA1510 // net8 - use ThrowIfNull #pragma warning disable CA1513 // net8 - use ThrowIfNull namespace Thrift.Transport { // ReSharper disable once InconsistentNaming public class TFramedTransport : TLayeredTransport { private const int HeaderSize = 4; private readonly byte[] HeaderBuf = new byte[HeaderSize]; private readonly Client.TMemoryBufferTransport ReadBuffer; private readonly Client.TMemoryBufferTransport WriteBuffer; private bool IsDisposed; public class Factory : TTransportFactory { public override TTransport GetTransport(TTransport trans) { return new TFramedTransport(trans); } } public TFramedTransport(TTransport transport) : base(transport) { ReadBuffer = new Client.TMemoryBufferTransport(Configuration); WriteBuffer = new Client.TMemoryBufferTransport(Configuration); InitWriteBuffer(); } public override bool IsOpen => !IsDisposed && InnerTransport.IsOpen; public override async Task OpenAsync(CancellationToken cancellationToken) { CheckNotDisposed(); await InnerTransport.OpenAsync(cancellationToken); } public override void Close() { CheckNotDisposed(); InnerTransport.Close(); } public override async ValueTask ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { CheckNotDisposed(); ValidateBufferArgs(buffer, offset, length); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // Read another frame of data if we run out of bytes if (ReadBuffer.Position >= ReadBuffer.Length) { await ReadFrameAsync(cancellationToken); } return await ReadBuffer.ReadAsync(buffer, offset, length, cancellationToken); } private async ValueTask ReadFrameAsync(CancellationToken cancellationToken) { UpdateKnownMessageSize(-1); await InnerTransport.ReadAllAsync(HeaderBuf, 0, HeaderSize, cancellationToken); int size = BinaryPrimitives.ReadInt32BigEndian(HeaderBuf); if ((0 > size) || (size > Configuration.MaxFrameSize)) // size must be in the range 0 to allowed max throw new TTransportException(TTransportException.ExceptionType.Unknown, $"Maximum frame size exceeded ({size} bytes)"); UpdateKnownMessageSize(size + HeaderSize); ReadBuffer.SetLength(size); ReadBuffer.Seek(0, SeekOrigin.Begin); ReadBuffer.TryGetBuffer(out ArraySegment bufSegment); await InnerTransport.ReadAllAsync(bufSegment.Array, 0, size, cancellationToken); } public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { CheckNotDisposed(); ValidateBufferArgs(buffer, offset, length); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } if (WriteBuffer.Length > (int.MaxValue - length)) { await FlushAsync(cancellationToken); } await WriteBuffer.WriteAsync(buffer, offset, length, cancellationToken); } public override async Task FlushAsync(CancellationToken cancellationToken) { CheckNotDisposed(); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } WriteBuffer.TryGetBuffer(out ArraySegment bufSegment); int dataLen = bufSegment.Count - HeaderSize; if (dataLen < 0) { throw new InvalidOperationException(); // logic error actually } // Inject message header into the reserved buffer space BinaryPrimitives.WriteInt32BigEndian(bufSegment.Array, dataLen); // Send the entire message at once await InnerTransport.WriteAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken); InitWriteBuffer(); await InnerTransport.FlushAsync(cancellationToken); } private void InitWriteBuffer() { // Reserve space for message header to be put right before sending it out WriteBuffer.SetLength(HeaderSize); WriteBuffer.Seek(0, SeekOrigin.End); } public override void CheckReadBytesAvailable(long numBytes) { var buffered = ReadBuffer.Length - ReadBuffer.Position; if (buffered < numBytes) { numBytes -= buffered; InnerTransport.CheckReadBytesAvailable(numBytes); } } private void CheckNotDisposed() { if (IsDisposed) { throw new ObjectDisposedException(this.GetType().Name); } } // IDisposable protected override void Dispose(bool disposing) { if (!IsDisposed) { if (disposing) { ReadBuffer?.Dispose(); WriteBuffer?.Dispose(); InnerTransport?.Dispose(); } } IsDisposed = true; } public override void ResetMessageSizeAndConsumedBytes(long newSize = -1) { base.ResetMessageSizeAndConsumedBytes(newSize); ReadBuffer.ResetMessageSizeAndConsumedBytes(newSize); } } } thrift-0.23.0/lib/netstd/Thrift/Server/0000775000175000017500000000000015165535636020152 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Server/TServerEventHandler.cs0000664000175000017500000000456715165535636024407 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Threading; using System.Threading.Tasks; using Thrift.Protocol; using Thrift.Transport; namespace Thrift.Server { //TODO: replacement by event? /// /// Interface implemented by server users to handle events from the server /// /// Replaced by ITServerEventHandler // ReSharper disable once InconsistentNaming #pragma warning disable IDE1006 public interface TServerEventHandler : ITServerEventHandler { } #pragma warning restore IDE1006 /// /// Interface implemented by server users to handle events from the server /// public interface ITServerEventHandler { /// /// Called before the server begins */ /// Task PreServeAsync(CancellationToken cancellationToken); /// /// Called when a new client has connected and is about to being processing */ /// Task CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken); /// /// Called when a client has finished request-handling to delete server context */ /// Task DeleteContextAsync(object serverContext, TProtocol input, TProtocol output, CancellationToken cancellationToken); /// /// Called when a client is about to call the processor */ /// Task ProcessContextAsync(object serverContext, TTransport transport, CancellationToken cancellationToken); } } thrift-0.23.0/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs0000664000175000017500000002133315165535636024245 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Threading; using Thrift.Protocol; using Thrift.Transport; using Thrift.Processor; using System.Threading.Tasks; using Microsoft.Extensions.Logging; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Server { // ReSharper disable once InconsistentNaming public class TSimpleAsyncServer : TServer { private volatile bool stop = false; private CancellationToken ServerCancellationToken; public TSimpleAsyncServer(ITProcessorFactory itProcessorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, ILogger logger) : base(itProcessorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, logger) { } public TSimpleAsyncServer(ITProcessorFactory itProcessorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, ILoggerFactory loggerFactory) : this(itProcessorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, loggerFactory.CreateLogger()) { } public TSimpleAsyncServer(ITAsyncProcessor processor, TServerTransport serverTransport, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, ILoggerFactory loggerFactory) : this(new TSingletonProcessorFactory(processor), serverTransport, null, // defaults to TTransportFactory() null, // defaults to TTransportFactory() inputProtocolFactory, outputProtocolFactory, loggerFactory.CreateLogger(nameof(TSimpleAsyncServer))) { } public override async Task ServeAsync(CancellationToken cancellationToken) { ServerCancellationToken = cancellationToken; try { try { ServerTransport.Listen(); } catch (TTransportException ttx) { LogError("Error, could not listen on ServerTransport: " + ttx); return; } //Fire the preServe server event when server is up but before any client connections if (ServerEventHandler != null) await ServerEventHandler.PreServeAsync(cancellationToken); while (!(stop || ServerCancellationToken.IsCancellationRequested)) { try { using (TTransport client = await ServerTransport.AcceptAsync(cancellationToken)) { await ExecuteAsync(client); } } catch (TaskCanceledException) { stop = true; } catch (TTransportException ttx) { if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted) { LogError(ttx.ToString()); } } } if (stop) { try { ServerTransport.Close(); } catch (TTransportException ttx) { LogError("TServerTransport failed on close: " + ttx.Message); } stop = false; } } finally { ServerCancellationToken = default; } } /// /// Loops on processing a client forever /// client will be a TTransport instance /// /// private async Task ExecuteAsync(TTransport client) { var cancellationToken = ServerCancellationToken; var processor = ProcessorFactory.GetAsyncProcessor(client, this); TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; object connectionContext = null; try { try { inputTransport = InputTransportFactory.GetTransport(client); outputTransport = OutputTransportFactory.GetTransport(client); inputProtocol = InputProtocolFactory.GetProtocol(inputTransport); outputProtocol = OutputProtocolFactory.GetProtocol(outputTransport); //Recover event handler (if any) and fire createContext server event when a client connects if (ServerEventHandler != null) connectionContext = await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken); //Process client requests until client disconnects while (!(stop || cancellationToken.IsCancellationRequested)) { if (!await inputTransport.PeekAsync(cancellationToken)) break; //Fire processContext server event //N.B. This is the pattern implemented in C++ and the event fires provisionally. //That is to say it may be many minutes between the event firing and the client request //actually arriving or the client may hang up without ever makeing a request. if (ServerEventHandler != null) await ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken); //Process client request (blocks until transport is readable) if (!await processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken)) break; } } catch (TTransportException) { //Usually a client disconnect, expected } catch (Exception x) { //Unexpected LogError("Error: " + x); } //Fire deleteContext server event after client disconnects if (ServerEventHandler != null) await ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken); } finally { //Close transports inputTransport?.Close(); outputTransport?.Close(); // disposable stuff should be disposed inputProtocol?.Dispose(); outputProtocol?.Dispose(); inputTransport?.Dispose(); outputTransport?.Dispose(); } } public override void Stop() { stop = true; ServerTransport?.Close(); } } } thrift-0.23.0/lib/netstd/Thrift/Server/TServer.cs0000664000175000017500000000633115165535636022076 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Thrift.Protocol; using Thrift.Transport; using Thrift.Processor; namespace Thrift.Server { // ReSharper disable once InconsistentNaming public abstract class TServer { protected readonly ILogger Logger; protected TProtocolFactory InputProtocolFactory; protected TTransportFactory InputTransportFactory; protected ITProcessorFactory ProcessorFactory; protected TProtocolFactory OutputProtocolFactory; protected TTransportFactory OutputTransportFactory; protected ITServerEventHandler ServerEventHandler; protected TServerTransport ServerTransport; protected TServer(ITProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, ILogger logger = null) { ProcessorFactory = processorFactory ?? throw new ArgumentNullException(nameof(processorFactory)); ServerTransport = serverTransport; InputTransportFactory = inputTransportFactory ?? new TTransportFactory(); OutputTransportFactory = outputTransportFactory ?? new TTransportFactory(); InputProtocolFactory = inputProtocolFactory ?? throw new ArgumentNullException(nameof(inputProtocolFactory)); OutputProtocolFactory = outputProtocolFactory ?? throw new ArgumentNullException(nameof(outputProtocolFactory)); Logger = logger; // null is absolutely legal } public void SetEventHandler(ITServerEventHandler seh) { ServerEventHandler = seh; } public ITServerEventHandler GetEventHandler() { return ServerEventHandler; } // Log delegation? deprecated, use ILogger protected void LogError( string msg) { Logger?.LogError("{Msg}",msg); // NOTE: Log message template, not string interpolation! } public abstract void Stop(); public virtual void Start() { // do nothing } public virtual Task ServeAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } } } thrift-0.23.0/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs0000664000175000017500000003011715165535636025055 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ using System; using System.Threading; using Thrift.Protocol; using Thrift.Transport; using Thrift.Processor; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace Thrift.Server { /// /// Server that uses C# built-in ThreadPool to spawn threads when handling requests. /// public class TThreadPoolAsyncServer : TServer { private const int DEFAULT_MIN_THREADS = -1; // use .NET ThreadPool defaults private const int DEFAULT_MAX_THREADS = -1; // use .NET ThreadPool defaults private volatile bool stop = false; private CancellationToken ServerCancellationToken; public struct Configuration { public int MinWorkerThreads; public int MaxWorkerThreads; public int MinIOThreads; public int MaxIOThreads; public Configuration(int min = DEFAULT_MIN_THREADS, int max = DEFAULT_MAX_THREADS) { MinWorkerThreads = min; MaxWorkerThreads = max; MinIOThreads = min; MaxIOThreads = max; } public Configuration(int minWork, int maxWork, int minIO, int maxIO) { MinWorkerThreads = minWork; MaxWorkerThreads = maxWork; MinIOThreads = minIO; MaxIOThreads = maxIO; } } public TThreadPoolAsyncServer(ITAsyncProcessor processor, TServerTransport serverTransport, ILogger logger = null) : this(new TSingletonProcessorFactory(processor), serverTransport, null, null, // defaults to TTransportFactory() new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), new Configuration(), logger) { } public TThreadPoolAsyncServer(ITAsyncProcessor processor, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory) : this(new TSingletonProcessorFactory(processor), serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, new Configuration()) { } public TThreadPoolAsyncServer(ITProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory) : this(processorFactory, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, new Configuration()) { } public TThreadPoolAsyncServer(ITProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, int minThreadPoolThreads, int maxThreadPoolThreads, ILogger logger = null) : this(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, new Configuration(minThreadPoolThreads, maxThreadPoolThreads), logger) { } public TThreadPoolAsyncServer(ITProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, Configuration threadConfig, ILogger logger = null) : base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, logger) { lock (typeof(TThreadPoolAsyncServer)) { if ((threadConfig.MaxWorkerThreads > 0) || (threadConfig.MaxIOThreads > 0)) { ThreadPool.GetMaxThreads(out int work, out int comm); if (threadConfig.MaxWorkerThreads > 0) work = threadConfig.MaxWorkerThreads; if (threadConfig.MaxIOThreads > 0) comm = threadConfig.MaxIOThreads; if (!ThreadPool.SetMaxThreads(work, comm)) throw new Exception("Error: could not SetMaxThreads in ThreadPool"); } if ((threadConfig.MinWorkerThreads > 0) || (threadConfig.MinIOThreads > 0)) { ThreadPool.GetMinThreads(out int work, out int comm); if (threadConfig.MinWorkerThreads > 0) work = threadConfig.MinWorkerThreads; if (threadConfig.MinIOThreads > 0) comm = threadConfig.MinIOThreads; if (!ThreadPool.SetMinThreads(work, comm)) throw new Exception("Error: could not SetMinThreads in ThreadPool"); } } } /// /// Use new ThreadPool thread for each new client connection. /// public override async Task ServeAsync(CancellationToken cancellationToken) { ServerCancellationToken = cancellationToken; try { try { ServerTransport.Listen(); } catch (TTransportException ttx) { LogError("Error, could not listen on ServerTransport: " + ttx); return; } //Fire the preServe server event when server is up but before any client connections if (ServerEventHandler != null) await ServerEventHandler.PreServeAsync(cancellationToken); while (!(stop || ServerCancellationToken.IsCancellationRequested)) { try { TTransport client = await ServerTransport.AcceptAsync(cancellationToken); _ = Task.Run(async () => await ExecuteAsync(client), cancellationToken); // intentionally ignoring retval } catch (TaskCanceledException) { stop = true; } catch (TTransportException ttx) { if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted) { LogError(ttx.ToString()); } } } if (stop) { try { ServerTransport.Close(); } catch (TTransportException ttx) { LogError("TServerTransport failed on close: " + ttx.Message); } stop = false; } } finally { ServerCancellationToken = default; } } /// /// Loops on processing a client forever /// client will be a TTransport instance /// /// private async Task ExecuteAsync(TTransport client) { var cancellationToken = ServerCancellationToken; using (client) { ITAsyncProcessor processor = ProcessorFactory.GetAsyncProcessor(client, this); TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; object connectionContext = null; try { try { inputTransport = InputTransportFactory.GetTransport(client); outputTransport = OutputTransportFactory.GetTransport(client); inputProtocol = InputProtocolFactory.GetProtocol(inputTransport); outputProtocol = OutputProtocolFactory.GetProtocol(outputTransport); //Recover event handler (if any) and fire createContext server event when a client connects if (ServerEventHandler != null) connectionContext = await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken); //Process client requests until client disconnects while (!(stop || cancellationToken.IsCancellationRequested)) { if (!await inputTransport.PeekAsync(cancellationToken)) break; //Fire processContext server event //N.B. This is the pattern implemented in C++ and the event fires provisionally. //That is to say it may be many minutes between the event firing and the client request //actually arriving or the client may hang up without ever makeing a request. if (ServerEventHandler != null) await ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken); //Process client request (blocks until transport is readable) if (!await processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken)) break; } } catch (TTransportException) { //Usually a client disconnect, expected } catch (Exception x) { //Unexpected LogError("Error: " + x); } //Fire deleteContext server event after client disconnects if (ServerEventHandler != null) await ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken); } finally { //Close transports inputTransport?.Close(); outputTransport?.Close(); // disposable stuff should be disposed inputProtocol?.Dispose(); outputProtocol?.Dispose(); inputTransport?.Dispose(); outputTransport?.Dispose(); } } } public override void Stop() { stop = true; ServerTransport?.Close(); } } } thrift-0.23.0/lib/netstd/Thrift/Processor/0000775000175000017500000000000015165535636020663 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs0000664000175000017500000001333715165535636025541 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using Thrift.Protocol; using Thrift.Protocol.Entities; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0028 // net8 - simplified collection init #pragma warning disable IDE0300 // net8 - simplified collection init #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Processor { // ReSharper disable once InconsistentNaming public class TMultiplexedProcessor : ITAsyncProcessor { //TODO: Localization private readonly Dictionary _serviceProcessorMap = new Dictionary(); public async Task ProcessAsync(TProtocol iprot, TProtocol oprot) { return await ProcessAsync(iprot, oprot, CancellationToken.None); } public async Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); try { var message = await iprot.ReadMessageBeginAsync(cancellationToken); if ((message.Type != TMessageType.Call) && (message.Type != TMessageType.Oneway)) { await FailAsync(oprot, message, TApplicationException.ExceptionType.InvalidMessageType, "Message exType CALL or ONEWAY expected", cancellationToken); return false; } // Extract the service name var index = message.Name.IndexOf(TMultiplexedProtocol.Separator, StringComparison.Ordinal); if (index < 0) { await FailAsync(oprot, message, TApplicationException.ExceptionType.InvalidProtocol, $"Service name not found in message name: {message.Name}. Did you forget to use a TMultiplexProtocol in your client?", cancellationToken); return false; } // Create a new TMessage, something that can be consumed by any TProtocol var serviceName = message.Name.Substring(0, index); if (!_serviceProcessorMap.TryGetValue(serviceName, out ITAsyncProcessor actualProcessor)) { await FailAsync(oprot, message, TApplicationException.ExceptionType.InternalError, $"Service name not found: {serviceName}. Did you forget to call RegisterProcessor()?", cancellationToken); return false; } // Create a new TMessage, removing the service name var newMessage = new TMessage( message.Name.Substring(serviceName.Length + TMultiplexedProtocol.Separator.Length), message.Type, message.SeqID); // Dispatch processing to the stored processor return await actualProcessor.ProcessAsync(new StoredMessageProtocol(iprot, newMessage), oprot, cancellationToken); } catch (IOException) { return false; // similar to all other processors } } public void RegisterProcessor(string serviceName, ITAsyncProcessor processor) { if (_serviceProcessorMap.ContainsKey(serviceName)) { throw new InvalidOperationException( $"Processor map already contains processor with name: '{serviceName}'"); } _serviceProcessorMap.Add(serviceName, processor); } private static async Task FailAsync(TProtocol oprot, TMessage message, TApplicationException.ExceptionType extype, string etxt, CancellationToken cancellationToken) { var appex = new TApplicationException(extype, etxt); var newMessage = new TMessage(message.Name, TMessageType.Exception, message.SeqID); await oprot.WriteMessageBeginAsync(newMessage, cancellationToken); await appex.WriteAsync(oprot, cancellationToken); await oprot.WriteMessageEndAsync(cancellationToken); await oprot.Transport.FlushAsync(cancellationToken); } private class StoredMessageProtocol : TProtocolDecorator { readonly TMessage _msgBegin; public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin) : base(protocol) { _msgBegin = messageBegin; } public override ValueTask ReadMessageBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return new ValueTask(_msgBegin); } } } } thrift-0.23.0/lib/netstd/Thrift/Processor/ITAsyncProcessor.cs0000664000175000017500000000206015165535636024422 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Threading; using System.Threading.Tasks; using Thrift.Protocol; namespace Thrift.Processor { public interface ITAsyncProcessor { Task ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken = default); } } thrift-0.23.0/lib/netstd/Thrift/Processor/ITProcessorFactory.cs0000664000175000017500000000205415165535636024757 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Thrift.Server; using Thrift.Transport; namespace Thrift.Processor { // ReSharper disable once InconsistentNaming public interface ITProcessorFactory { ITAsyncProcessor GetAsyncProcessor(TTransport trans, TServer baseServer = null); } }thrift-0.23.0/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs0000664000175000017500000000270315165535636026532 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Thrift.Server; using Thrift.Transport; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Processor { // ReSharper disable once InconsistentNaming public class TSingletonProcessorFactory : ITProcessorFactory { private readonly ITAsyncProcessor _asyncProcessor; public TSingletonProcessorFactory(ITAsyncProcessor asyncProcessor) { _asyncProcessor = asyncProcessor; } public ITAsyncProcessor GetAsyncProcessor(TTransport trans, TServer baseServer = null) { return _asyncProcessor; } } } thrift-0.23.0/lib/netstd/Thrift/Thrift.csproj0000664000175000017500000001213315170007142021344 0ustar00buildbuild00000000000000 netstandard2.1;netstandard2.0;net8.0;net9.0;net10.0 Thrift ApacheThrift true true false false false false false false false false true true true thrift.snk false Apache Thrift 0.23.0 0.23.0.0 false http://thrift.apache.org/ Apache Thrift Developers false Apache-2.0 C# .NET Core bindings for the Apache Thrift RPC system Apache Thrift RPC https://github.com/apache/thrift/blob/0.23.0/CHANGES.md https://thrift.apache.org/ https://github.com/apache/thrift git README.md Copyright 2025 The Apache Software Foundation $(IntermediateOutputPath)$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension) thrift-0.23.0/lib/netstd/Thrift/Protocol/0000775000175000017500000000000015165535636020505 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Protocol/TJSONProtocol.cs0000664000175000017500000012010515165535636023452 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; using Thrift.Transport; #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 { /// /// JSON protocol implementation for thrift. /// This is a full-featured protocol supporting Write and Read. /// Please see the C++ class header for a detailed description of the /// protocol's wire format. /// Adapted from the Java version. /// // ReSharper disable once InconsistentNaming public class TJsonProtocol : TProtocol { private const long Version = 1; // Temporary buffer used by several methods private readonly byte[] _tempBuffer = new byte[4]; // Current context that we are in protected JSONBaseContext Context; // Stack of nested contexts that we may be in protected Stack ContextStack = new Stack(); // Reader that manages a 1-byte buffer protected LookaheadReader Reader; // Default encoding protected Encoding Utf8Encoding = Encoding.UTF8; /// /// TJsonProtocol Constructor /// public TJsonProtocol(TTransport trans) : base(trans) { Context = new JSONBaseContext(this); Reader = new LookaheadReader(this); } /// /// Push a new JSON context onto the stack. /// protected void PushContext(JSONBaseContext c) { ContextStack.Push(Context); Context = c; } /// /// Pop the last JSON context off the stack /// protected void PopContext() { Context = ContextStack.Pop(); } /// /// Resets the context stack to pristine state. Allows for reusal of the protocol /// even in cases where the protocol instance was in an undefined state due to /// dangling/stale/obsolete contexts /// private void ResetContext() { ContextStack.Clear(); Context = new JSONBaseContext(this); } /// /// Read a byte that must match b[0]; otherwise an exception is thrown. /// Marked protected to avoid synthetic accessor in JSONListContext.Read /// and JSONPairContext.Read /// protected async Task ReadJsonSyntaxCharAsync(byte[] bytes, CancellationToken cancellationToken) { var ch = await Reader.ReadAsync(cancellationToken); if (ch != bytes[0]) { throw new TProtocolException(TProtocolException.INVALID_DATA, $"Unexpected character: {(char) ch}"); } } /// /// Write the bytes in array buf as a JSON characters, escaping as needed /// private async Task WriteJsonStringAsync(byte[] bytes, CancellationToken cancellationToken) { await Context.WriteConditionalDelimiterAsync(cancellationToken); await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); var len = bytes.Length; for (var i = 0; i < len; i++) { if ((bytes[i] & 0x00FF) >= 0x30) { if (bytes[i] == TJSONProtocolConstants.Backslash[0]) { await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken); await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken); } else { await Trans.WriteAsync(bytes, i, 1, cancellationToken); } } else { _tempBuffer[0] = TJSONProtocolConstants.JsonCharTable[bytes[i]]; if (_tempBuffer[0] == 1) { await Trans.WriteAsync(bytes, i, 1, cancellationToken); } else if (_tempBuffer[0] > 1) { await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken); await Trans.WriteAsync(_tempBuffer, 0, 1, cancellationToken); } else { await Trans.WriteAsync(TJSONProtocolConstants.EscSequences, cancellationToken); _tempBuffer[0] = TJSONProtocolHelper.ToHexChar((byte) (bytes[i] >> 4)); _tempBuffer[1] = TJSONProtocolHelper.ToHexChar(bytes[i]); await Trans.WriteAsync(_tempBuffer, 0, 2, cancellationToken); } } } await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); } /// /// Write out number as a JSON value. If the context dictates so, it will be /// wrapped in quotes to output as a JSON string. /// private async Task WriteJsonIntegerAsync(long num, CancellationToken cancellationToken) { await Context.WriteConditionalDelimiterAsync(cancellationToken); var str = num.ToString(); var escapeNum = Context.EscapeNumbers(); if (escapeNum) { await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); } var bytes = Utf8Encoding.GetBytes(str); await Trans.WriteAsync(bytes, cancellationToken); if (escapeNum) { await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); } } /// /// Write out a double as a JSON value. If it is NaN or infinity or if the /// context dictates escaping, Write out as JSON string. /// private async Task WriteJsonDoubleAsync(double num, CancellationToken cancellationToken) { await Context.WriteConditionalDelimiterAsync(cancellationToken); var str = num.ToString("G17", CultureInfo.InvariantCulture); var special = false; switch (str[0]) { case 'N': // NaN case 'I': // Infinity special = true; break; case '-': if (str[1] == 'I') { // -Infinity special = true; } break; } var escapeNum = special || Context.EscapeNumbers(); if (escapeNum) { await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); } await Trans.WriteAsync(Utf8Encoding.GetBytes(str), cancellationToken); if (escapeNum) { await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); } } /// /// Write out contents of byte array b as a JSON string with base-64 encoded /// data /// private async Task WriteJsonBase64Async(byte[] bytes, CancellationToken cancellationToken) { await Context.WriteConditionalDelimiterAsync(cancellationToken); await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); var len = bytes.Length; var off = 0; while (len >= 3) { // Encode 3 bytes at a time TBase64Utils.Encode(bytes, off, 3, _tempBuffer, 0); await Trans.WriteAsync(_tempBuffer, 0, 4, cancellationToken); off += 3; len -= 3; } if (len > 0) { // Encode remainder TBase64Utils.Encode(bytes, off, len, _tempBuffer, 0); await Trans.WriteAsync(_tempBuffer, 0, len + 1, cancellationToken); } await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken); } private async Task WriteJsonObjectStartAsync(CancellationToken cancellationToken) { await Context.WriteConditionalDelimiterAsync(cancellationToken); await Trans.WriteAsync(TJSONProtocolConstants.LeftBrace, cancellationToken); PushContext(new JSONPairContext(this)); } private async Task WriteJsonObjectEndAsync(CancellationToken cancellationToken) { PopContext(); await Trans.WriteAsync(TJSONProtocolConstants.RightBrace, cancellationToken); } private async Task WriteJsonArrayStartAsync(CancellationToken cancellationToken) { await Context.WriteConditionalDelimiterAsync(cancellationToken); await Trans.WriteAsync(TJSONProtocolConstants.LeftBracket, cancellationToken); PushContext(new JSONListContext(this)); } private async Task WriteJsonArrayEndAsync(CancellationToken cancellationToken) { PopContext(); await Trans.WriteAsync(TJSONProtocolConstants.RightBracket, cancellationToken); } public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken) { ResetContext(); await WriteJsonArrayStartAsync(cancellationToken); await WriteJsonIntegerAsync(Version, cancellationToken); var b = Utf8Encoding.GetBytes(message.Name); await WriteJsonStringAsync(b, cancellationToken); await WriteJsonIntegerAsync((long) message.Type, cancellationToken); await WriteJsonIntegerAsync(message.SeqID, cancellationToken); } public override async Task WriteMessageEndAsync(CancellationToken cancellationToken) { await WriteJsonArrayEndAsync(cancellationToken); } public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken) { await WriteJsonObjectStartAsync(cancellationToken); } public override async Task WriteStructEndAsync(CancellationToken cancellationToken) { await WriteJsonObjectEndAsync(cancellationToken); } public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken) { await WriteJsonIntegerAsync(field.ID, cancellationToken); await WriteJsonObjectStartAsync(cancellationToken); await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(field.Type), cancellationToken); } public override async Task WriteFieldEndAsync(CancellationToken cancellationToken) { await WriteJsonObjectEndAsync(cancellationToken); } public override Task WriteFieldStopAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken) { await WriteJsonArrayStartAsync(cancellationToken); await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(map.KeyType), cancellationToken); await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(map.ValueType), cancellationToken); await WriteJsonIntegerAsync(map.Count, cancellationToken); await WriteJsonObjectStartAsync(cancellationToken); } public override async Task WriteMapEndAsync(CancellationToken cancellationToken) { await WriteJsonObjectEndAsync(cancellationToken); await WriteJsonArrayEndAsync(cancellationToken); } public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken) { await WriteJsonArrayStartAsync(cancellationToken); await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(list.ElementType), cancellationToken); await WriteJsonIntegerAsync(list.Count, cancellationToken); } public override async Task WriteListEndAsync(CancellationToken cancellationToken) { await WriteJsonArrayEndAsync(cancellationToken); } public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken) { await WriteJsonArrayStartAsync(cancellationToken); await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(set.ElementType), cancellationToken); await WriteJsonIntegerAsync(set.Count, cancellationToken); } public override async Task WriteSetEndAsync(CancellationToken cancellationToken) { await WriteJsonArrayEndAsync(cancellationToken); } public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken) { await WriteJsonIntegerAsync(b ? 1 : 0, cancellationToken); } public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken) { await WriteJsonIntegerAsync(b, cancellationToken); } public override async Task WriteI16Async(short i16, CancellationToken cancellationToken) { await WriteJsonIntegerAsync(i16, cancellationToken); } public override async Task WriteI32Async(int i32, CancellationToken cancellationToken) { await WriteJsonIntegerAsync(i32, cancellationToken); } public override async Task WriteI64Async(long i64, CancellationToken cancellationToken) { await WriteJsonIntegerAsync(i64, cancellationToken); } public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken) { await WriteJsonDoubleAsync(d, cancellationToken); } public override async Task WriteStringAsync(string s, CancellationToken cancellationToken) { var b = Utf8Encoding.GetBytes(s); await WriteJsonStringAsync(b, cancellationToken); } public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken) { await WriteJsonBase64Async(bytes, cancellationToken); } public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken = default) { await WriteStringAsync(uuid.ToString("D"), cancellationToken); // no curly braces } /// /// Read in a JSON string, unescaping as appropriate.. Skip Reading from the /// context if skipContext is true. /// private async ValueTask ReadJsonStringAsync(bool skipContext, CancellationToken cancellationToken) { using (var buffer = new MemoryStream()) { var codeunits = new List(); if (!skipContext) { await Context.ReadConditionalDelimiterAsync(cancellationToken); } await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken); while (true) { var ch = await Reader.ReadAsync(cancellationToken); if (ch == TJSONProtocolConstants.Quote[0]) { break; } // escaped? if (ch != TJSONProtocolConstants.EscSequences[0]) { #if NET5_0_OR_GREATER var wbuf = new[] { ch }; await buffer.WriteAsync(wbuf.AsMemory(0, 1), cancellationToken); #else await buffer.WriteAsync(new[] { ch }, 0, 1, cancellationToken); #endif continue; } // distinguish between \uXXXX and \? ch = await Reader.ReadAsync(cancellationToken); if (ch != TJSONProtocolConstants.EscSequences[1]) // control chars like \n { var off = Array.IndexOf(TJSONProtocolConstants.EscapeChars, (char) ch); if (off == -1) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected control char"); } ch = TJSONProtocolConstants.EscapeCharValues[off]; #if NET5_0_OR_GREATER var wbuf = new[] { ch }; await buffer.WriteAsync( wbuf.AsMemory(0, 1), cancellationToken); #else await buffer.WriteAsync(new[] { ch }, 0, 1, cancellationToken); #endif continue; } // it's \uXXXX Trans.CheckReadBytesAvailable(4); await Trans.ReadAllAsync(_tempBuffer, 0, 4, cancellationToken); var wch = (short) ((TJSONProtocolHelper.ToHexVal(_tempBuffer[0]) << 12) + (TJSONProtocolHelper.ToHexVal(_tempBuffer[1]) << 8) + (TJSONProtocolHelper.ToHexVal(_tempBuffer[2]) << 4) + TJSONProtocolHelper.ToHexVal(_tempBuffer[3])); if (char.IsHighSurrogate((char) wch)) { if (codeunits.Count > 0) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected low surrogate char"); } codeunits.Add((char) wch); } else if (char.IsLowSurrogate((char) wch)) { if (codeunits.Count == 0) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected high surrogate char"); } codeunits.Add((char) wch); var tmp = Utf8Encoding.GetBytes(codeunits.ToArray()); #if NET5_0_OR_GREATER await buffer.WriteAsync(tmp.AsMemory(0, tmp.Length), cancellationToken); #else await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken); #endif codeunits.Clear(); } else { var tmp = Utf8Encoding.GetBytes(new[] { (char)wch }); #if NET5_0_OR_GREATER await buffer.WriteAsync(tmp.AsMemory( 0, tmp.Length), cancellationToken); #else await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken); #endif } } if (codeunits.Count > 0) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected low surrogate char"); } return buffer.ToArray(); } } /// /// Read in a sequence of characters that are all valid in JSON numbers. Does /// not do a complete regex check to validate that this is actually a number. /// private async ValueTask ReadJsonNumericCharsAsync(CancellationToken cancellationToken) { var strbld = new StringBuilder(); while (true) { //TODO: workaround for primitive types with TJsonProtocol, think - how to rewrite into more easy form without exceptions try { var ch = await Reader.PeekAsync(cancellationToken); if (!TJSONProtocolHelper.IsJsonNumeric(ch)) { break; } var c = (char)await Reader.ReadAsync(cancellationToken); strbld.Append(c); } catch (TTransportException) { break; } } return strbld.ToString(); } /// /// Read in a JSON number. If the context dictates, Read in enclosing quotes. /// private async ValueTask ReadJsonIntegerAsync(CancellationToken cancellationToken) { await Context.ReadConditionalDelimiterAsync(cancellationToken); if (Context.EscapeNumbers()) { await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken); } var str = await ReadJsonNumericCharsAsync(cancellationToken); if (Context.EscapeNumbers()) { await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken); } try { return long.Parse(str); } catch (FormatException) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } /// /// Read in a JSON double value. Throw if the value is not wrapped in quotes /// when expected or if wrapped in quotes when not expected. /// private async ValueTask ReadJsonDoubleAsync(CancellationToken cancellationToken) { await Context.ReadConditionalDelimiterAsync(cancellationToken); if (await Reader.PeekAsync(cancellationToken) == TJSONProtocolConstants.Quote[0]) { var arr = await ReadJsonStringAsync(true, cancellationToken); var dub = double.Parse(Utf8Encoding.GetString(arr, 0, arr.Length), CultureInfo.InvariantCulture); if (!Context.EscapeNumbers() && !double.IsNaN(dub) && !double.IsInfinity(dub)) { // Throw exception -- we should not be in a string in this case throw new TProtocolException(TProtocolException.INVALID_DATA, "Numeric data unexpectedly quoted"); } return dub; } if (Context.EscapeNumbers()) { // This will throw - we should have had a quote if escapeNum == true await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken); } try { return double.Parse(await ReadJsonNumericCharsAsync(cancellationToken), CultureInfo.InvariantCulture); } catch (FormatException) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } /// /// Read in a JSON string containing base-64 encoded data and decode it. /// private async ValueTask ReadJsonBase64Async(CancellationToken cancellationToken) { var b = await ReadJsonStringAsync(false, cancellationToken); var len = b.Length; var off = 0; var size = 0; // reduce len to ignore fill bytes while ((len > 0) && (b[len - 1] == '=')) { --len; } // read & decode full byte triplets = 4 source bytes while (len > 4) { // Decode 4 bytes at a time TBase64Utils.Decode(b, off, 4, b, size); // NB: decoded in place off += 4; len -= 4; size += 3; } // Don't decode if we hit the end or got a single leftover byte (invalid // base64 but legal for skip of regular string exType) if (len > 1) { // Decode remainder TBase64Utils.Decode(b, off, len, b, size); // NB: decoded in place size += len - 1; } // Sadly we must copy the byte[] (any way around this?) var result = new byte[size]; Array.Copy(b, 0, result, 0, size); return result; } private async Task ReadJsonObjectStartAsync(CancellationToken cancellationToken) { await Context.ReadConditionalDelimiterAsync(cancellationToken); await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.LeftBrace, cancellationToken); PushContext(new JSONPairContext(this)); } private async Task ReadJsonObjectEndAsync(CancellationToken cancellationToken) { await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.RightBrace, cancellationToken); PopContext(); } private async Task ReadJsonArrayStartAsync(CancellationToken cancellationToken) { await Context.ReadConditionalDelimiterAsync(cancellationToken); await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.LeftBracket, cancellationToken); PushContext(new JSONListContext(this)); } private async Task ReadJsonArrayEndAsync(CancellationToken cancellationToken) { await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.RightBracket, cancellationToken); PopContext(); } public override async ValueTask ReadMessageBeginAsync(CancellationToken cancellationToken) { var message = new TMessage(); ResetContext(); await ReadJsonArrayStartAsync(cancellationToken); if (await ReadJsonIntegerAsync(cancellationToken) != Version) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Message contained bad version."); } var buf = await ReadJsonStringAsync(false, cancellationToken); message.Name = Utf8Encoding.GetString(buf, 0, buf.Length); message.Type = (TMessageType) await ReadJsonIntegerAsync(cancellationToken); message.SeqID = (int) await ReadJsonIntegerAsync(cancellationToken); return message; } public override async Task ReadMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await ReadJsonArrayEndAsync(cancellationToken); Transport.ResetMessageSizeAndConsumedBytes(); } public override async ValueTask ReadStructBeginAsync(CancellationToken cancellationToken) { await ReadJsonObjectStartAsync(cancellationToken); return AnonymousStruct; } public override async Task ReadStructEndAsync(CancellationToken cancellationToken) { await ReadJsonObjectEndAsync(cancellationToken); } public override async ValueTask ReadFieldBeginAsync(CancellationToken cancellationToken) { var ch = await Reader.PeekAsync(cancellationToken); if (ch == TJSONProtocolConstants.RightBrace[0]) { return StopField; } var field = new TField() { ID = (short)await ReadJsonIntegerAsync(cancellationToken) }; await ReadJsonObjectStartAsync(cancellationToken); field.Type = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken)); return field; } public override async Task ReadFieldEndAsync(CancellationToken cancellationToken) { await ReadJsonObjectEndAsync(cancellationToken); } public override async ValueTask ReadMapBeginAsync(CancellationToken cancellationToken) { var map = new TMap(); await ReadJsonArrayStartAsync(cancellationToken); map.KeyType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken)); map.ValueType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken)); map.Count = (int) await ReadJsonIntegerAsync(cancellationToken); CheckReadBytesAvailable(map); await ReadJsonObjectStartAsync(cancellationToken); return map; } public override async Task ReadMapEndAsync(CancellationToken cancellationToken) { await ReadJsonObjectEndAsync(cancellationToken); await ReadJsonArrayEndAsync(cancellationToken); } public override async ValueTask ReadListBeginAsync(CancellationToken cancellationToken) { var list = new TList(); await ReadJsonArrayStartAsync(cancellationToken); list.ElementType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken)); list.Count = (int) await ReadJsonIntegerAsync(cancellationToken); CheckReadBytesAvailable(list); return list; } public override async Task ReadListEndAsync(CancellationToken cancellationToken) { await ReadJsonArrayEndAsync(cancellationToken); } public override async ValueTask ReadSetBeginAsync(CancellationToken cancellationToken) { var set = new TSet(); await ReadJsonArrayStartAsync(cancellationToken); set.ElementType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken)); set.Count = (int) await ReadJsonIntegerAsync(cancellationToken); CheckReadBytesAvailable(set); return set; } public override async Task ReadSetEndAsync(CancellationToken cancellationToken) { await ReadJsonArrayEndAsync(cancellationToken); } public override async ValueTask ReadBoolAsync(CancellationToken cancellationToken) { return await ReadJsonIntegerAsync(cancellationToken) != 0; } public override async ValueTask ReadByteAsync(CancellationToken cancellationToken) { return (sbyte) await ReadJsonIntegerAsync(cancellationToken); } public override async ValueTask ReadI16Async(CancellationToken cancellationToken) { return (short) await ReadJsonIntegerAsync(cancellationToken); } public override async ValueTask ReadI32Async(CancellationToken cancellationToken) { return (int) await ReadJsonIntegerAsync(cancellationToken); } public override async ValueTask ReadI64Async(CancellationToken cancellationToken) { return await ReadJsonIntegerAsync(cancellationToken); } public override async ValueTask ReadDoubleAsync(CancellationToken cancellationToken) { return await ReadJsonDoubleAsync(cancellationToken); } public override async ValueTask ReadStringAsync(CancellationToken cancellationToken) { var buf = await ReadJsonStringAsync(false, cancellationToken); return Utf8Encoding.GetString(buf, 0, buf.Length); } public override async ValueTask ReadBinaryAsync(CancellationToken cancellationToken) { return await ReadJsonBase64Async(cancellationToken); } public override async ValueTask ReadUuidAsync(CancellationToken cancellationToken = default) { return new Guid( await ReadStringAsync(cancellationToken)); } // Return the minimum number of bytes a type will consume on the wire public override int GetMinSerializedSize(TType type) { switch (type) { case TType.Stop: return 1; // T_STOP needs to count itself case TType.Void: return 1; // T_VOID needs to count itself case TType.Bool: return 1; // written as int case TType.Byte: return 1; case TType.Double: return 1; case TType.I16: return 1; case TType.I32: return 1; case TType.I64: return 1; case TType.String: return 2; // empty string case TType.Struct: return 2; // empty struct case TType.Map: return 2; // empty map case TType.Set: return 2; // empty set case TType.List: return 2; // empty list case TType.Uuid: return 36; // "E236974D-F0B0-4E05-8F29-0B455D41B1A1" default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code"); } } /// /// Factory for JSON protocol objects /// public class Factory : TProtocolFactory { public override TProtocol GetProtocol(TTransport trans) { return new TJsonProtocol(trans); } } /// /// Base class for tracking JSON contexts that may require /// inserting/Reading additional JSON syntax characters /// This base context does nothing. /// protected class JSONBaseContext { protected TJsonProtocol Proto; public JSONBaseContext(TJsonProtocol proto) { Proto = proto; } public virtual Task WriteConditionalDelimiterAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public virtual Task ReadConditionalDelimiterAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public virtual bool EscapeNumbers() { return false; } } /// /// Context for JSON lists. Will insert/Read commas before each item except /// for the first one /// protected class JSONListContext : JSONBaseContext { private bool _first = true; public JSONListContext(TJsonProtocol protocol) : base(protocol) { } public override async Task WriteConditionalDelimiterAsync(CancellationToken cancellationToken) { if (_first) { _first = false; } else { await Proto.Trans.WriteAsync(TJSONProtocolConstants.Comma, cancellationToken); } } public override async Task ReadConditionalDelimiterAsync(CancellationToken cancellationToken) { if (_first) { _first = false; } else { await Proto.ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Comma, cancellationToken); } } } /// /// Context for JSON records. Will insert/Read colons before the value portion /// of each record pair, and commas before each key except the first. In /// addition, will indicate that numbers in the key position need to be /// escaped in quotes (since JSON keys must be strings). /// // ReSharper disable once InconsistentNaming protected class JSONPairContext : JSONBaseContext { private bool _colon = true; private bool _first = true; public JSONPairContext(TJsonProtocol proto) : base(proto) { } public override async Task WriteConditionalDelimiterAsync(CancellationToken cancellationToken) { if (_first) { _first = false; _colon = true; } else { await Proto.Trans.WriteAsync(_colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma, cancellationToken); _colon = !_colon; } } public override async Task ReadConditionalDelimiterAsync(CancellationToken cancellationToken) { if (_first) { _first = false; _colon = true; } else { await Proto.ReadJsonSyntaxCharAsync(_colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma, cancellationToken); _colon = !_colon; } } public override bool EscapeNumbers() { return _colon; } } /// /// Holds up to one byte from the transport /// protected class LookaheadReader { private readonly byte[] _data = new byte[1]; private bool _hasData; protected TJsonProtocol Proto; public LookaheadReader(TJsonProtocol proto) { Proto = proto; } /// /// Return and consume the next byte to be Read, either taking it from the /// data buffer if present or getting it from the transport otherwise. /// public async ValueTask ReadAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (_hasData) { _hasData = false; } else { // find more easy way to avoid exception on reading primitive types Proto.Trans.CheckReadBytesAvailable(1); await Proto.Trans.ReadAllAsync(_data, 0, 1, cancellationToken); } return _data[0]; } /// /// Return the next byte to be Read without consuming, filling the data /// buffer if it has not been filled alReady. /// public async ValueTask PeekAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (!_hasData) { // find more easy way to avoid exception on reading primitive types Proto.Trans.CheckReadBytesAvailable(1); await Proto.Trans.ReadAllAsync(_data, 0, 1, cancellationToken); _hasData = true; } return _data[0]; } } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/0000775000175000017500000000000015165535636022271 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TSet.cs0000664000175000017500000000253015165535636023477 0ustar00buildbuild00000000000000// 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. #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public struct TSet { public TSet(TType elementType, int count) { ElementType = elementType; Count = count; } public TSet(TList list) : this(list.ElementType, list.Count) { } public TType ElementType { get; set; } public int Count { get; set; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TList.cs0000664000175000017500000000236415165535636023664 0ustar00buildbuild00000000000000// 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. #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public struct TList { public TList(TType elementType, int count) { ElementType = elementType; Count = count; } public TType ElementType { get; set; } public int Count { get; set; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TMessageType.cs0000664000175000017500000000175615165535636025203 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public enum TMessageType { Call = 1, Reply = 2, Exception = 3, Oneway = 4 } }thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TField.cs0000664000175000017500000000260115165535636023766 0ustar00buildbuild00000000000000// 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. #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public struct TField { public TField(string name, TType type, short id) { Name = name; Type = type; ID = id; } public string Name { get; set; } public TType Type { get; set; } // ReSharper disable once InconsistentNaming - do not rename - it used for generation public short ID { get; set; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TStruct.cs0000664000175000017500000000222515165535636024231 0ustar00buildbuild00000000000000// 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. #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public readonly struct TStruct { public TStruct(string name) { Name = name; } public string Name { get; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TType.cs0000664000175000017500000000224315165535636023666 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public enum TType : byte { Stop = 0, Void = 1, Bool = 2, Byte = 3, Double = 4, I16 = 6, I32 = 8, I64 = 10, String = 11, Struct = 12, Map = 13, Set = 14, List = 15, Uuid = 16 } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TMessage.cs0000664000175000017500000000263315165535636024334 0ustar00buildbuild00000000000000// 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. #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public struct TMessage { public TMessage(string name, TMessageType type, int seqid) { Name = name; Type = type; SeqID = seqid; } public string Name { get; set; } public TMessageType Type { get; set; } // ReSharper disable once InconsistentNaming - do not rename - it used for generation public int SeqID { get; set; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Entities/TMap.cs0000664000175000017500000000250415165535636023462 0ustar00buildbuild00000000000000// 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. #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming public struct TMap { public TMap(TType keyType, TType valueType, int count) { KeyType = keyType; ValueType = valueType; Count = count; } public TType KeyType { get; set; } public TType ValueType { get; set; } public int Count { get; set; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs0000664000175000017500000002432615165535636024633 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; namespace Thrift.Protocol { // ReSharper disable once InconsistentNaming /// /// TProtocolDecorator forwards all requests to an enclosed TProtocol instance, /// providing a way to author concise concrete decorator subclasses.While it has /// no abstract methods, it is marked abstract as a reminder that by itself, /// it does not modify the behaviour of the enclosed TProtocol. /// public abstract class TProtocolDecorator : TProtocol { private readonly TProtocol _wrappedProtocol; protected TProtocolDecorator(TProtocol protocol) : base(protocol.Transport) { _wrappedProtocol = protocol ?? throw new ArgumentNullException(nameof(protocol)); } public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken) { await _wrappedProtocol.WriteMessageBeginAsync(message, cancellationToken); } public override async Task WriteMessageEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.WriteMessageEndAsync(cancellationToken); } public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken) { await _wrappedProtocol.WriteStructBeginAsync(@struct, cancellationToken); } public override async Task WriteStructEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.WriteStructEndAsync(cancellationToken); } public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken) { await _wrappedProtocol.WriteFieldBeginAsync(field, cancellationToken); } public override async Task WriteFieldEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.WriteFieldEndAsync(cancellationToken); } public override async Task WriteFieldStopAsync(CancellationToken cancellationToken) { await _wrappedProtocol.WriteFieldStopAsync(cancellationToken); } public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken) { await _wrappedProtocol.WriteMapBeginAsync(map, cancellationToken); } public override async Task WriteMapEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.WriteMapEndAsync(cancellationToken); } public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken) { await _wrappedProtocol.WriteListBeginAsync(list, cancellationToken); } public override async Task WriteListEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.WriteListEndAsync(cancellationToken); } public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken) { await _wrappedProtocol.WriteSetBeginAsync(set, cancellationToken); } public override async Task WriteSetEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.WriteSetEndAsync(cancellationToken); } public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken) { await _wrappedProtocol.WriteBoolAsync(b, cancellationToken); } public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken) { await _wrappedProtocol.WriteByteAsync(b, cancellationToken); } public override async Task WriteI16Async(short i16, CancellationToken cancellationToken) { await _wrappedProtocol.WriteI16Async(i16, cancellationToken); } public override async Task WriteI32Async(int i32, CancellationToken cancellationToken) { await _wrappedProtocol.WriteI32Async(i32, cancellationToken); } public override async Task WriteI64Async(long i64, CancellationToken cancellationToken) { await _wrappedProtocol.WriteI64Async(i64, cancellationToken); } public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken) { await _wrappedProtocol.WriteDoubleAsync(d, cancellationToken); } public override async Task WriteStringAsync(string s, CancellationToken cancellationToken) { await _wrappedProtocol.WriteStringAsync(s, cancellationToken); } public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken) { await _wrappedProtocol.WriteBinaryAsync(bytes, cancellationToken); } public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken) { await _wrappedProtocol.WriteUuidAsync(uuid, cancellationToken); } public override async ValueTask ReadMessageBeginAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadMessageBeginAsync(cancellationToken); } public override async Task ReadMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await _wrappedProtocol.ReadMessageEndAsync(cancellationToken); Transport.ResetMessageSizeAndConsumedBytes(); } public override async ValueTask ReadStructBeginAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadStructBeginAsync(cancellationToken); } public override async Task ReadStructEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.ReadStructEndAsync(cancellationToken); } public override async ValueTask ReadFieldBeginAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadFieldBeginAsync(cancellationToken); } public override async Task ReadFieldEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.ReadFieldEndAsync(cancellationToken); } public override async ValueTask ReadMapBeginAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadMapBeginAsync(cancellationToken); } public override async Task ReadMapEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.ReadMapEndAsync(cancellationToken); } public override async ValueTask ReadListBeginAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadListBeginAsync(cancellationToken); } public override async Task ReadListEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.ReadListEndAsync(cancellationToken); } public override async ValueTask ReadSetBeginAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadSetBeginAsync(cancellationToken); } public override async Task ReadSetEndAsync(CancellationToken cancellationToken) { await _wrappedProtocol.ReadSetEndAsync(cancellationToken); } public override async ValueTask ReadBoolAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadBoolAsync(cancellationToken); } public override async ValueTask ReadByteAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadByteAsync(cancellationToken); } public override async ValueTask ReadI16Async(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadI16Async(cancellationToken); } public override async ValueTask ReadI32Async(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadI32Async(cancellationToken); } public override async ValueTask ReadI64Async(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadI64Async(cancellationToken); } public override async ValueTask ReadDoubleAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadDoubleAsync(cancellationToken); } public override async ValueTask ReadStringAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadStringAsync(cancellationToken); } public override async ValueTask ReadBinaryAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadBinaryAsync(cancellationToken); } public override async ValueTask ReadUuidAsync(CancellationToken cancellationToken) { return await _wrappedProtocol.ReadUuidAsync(cancellationToken); } // Returns the minimum amount of bytes needed to store the smallest possible instance of TType. public override int GetMinSerializedSize(TType type) { return _wrappedProtocol.GetMinSerializedSize(type); } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/TBase.cs0000664000175000017500000000243515165535636022036 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Threading; using System.Threading.Tasks; #pragma warning disable IDE1006 // some interfaces here are intentionally not I-prefixed namespace Thrift.Protocol { public interface TUnionBase { Task WriteAsync(TProtocol tProtocol, CancellationToken cancellationToken = default); } // ReSharper disable once InconsistentNaming public interface TBase : TUnionBase { Task ReadAsync(TProtocol tProtocol, CancellationToken cancellationToken = default); } } thrift-0.23.0/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs0000664000175000017500000004512715165535636024137 0ustar00buildbuild00000000000000// 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.Buffers.Binary; using System.Text; using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; using Thrift.Transport; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol { // ReSharper disable once InconsistentNaming public class TBinaryProtocol : TProtocol { protected const uint VersionMask = 0xffff0000; protected const uint Version1 = 0x80010000; protected readonly bool StrictRead; protected readonly bool StrictWrite; // minimize memory allocations by means of an preallocated bytes buffer // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long) private readonly byte[] PreAllocatedBuffer = new byte[128]; public TBinaryProtocol(TTransport trans) : this(trans, false, true) { } public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite) : base(trans) { StrictRead = strictRead; StrictWrite = strictWrite; } public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (StrictWrite) { var version = Version1 | (uint) message.Type; await WriteI32Async((int) version, cancellationToken); await WriteStringAsync(message.Name, cancellationToken); await WriteI32Async(message.SeqID, cancellationToken); } else { await WriteStringAsync(message.Name, cancellationToken); await WriteByteAsync((sbyte) message.Type, cancellationToken); await WriteI32Async(message.SeqID, cancellationToken); } } public override Task WriteMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override Task WriteStructEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteByteAsync((sbyte) field.Type, cancellationToken); await WriteI16Async(field.ID, cancellationToken); } public override Task WriteFieldEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteFieldStopAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteByteAsync((sbyte) TType.Stop, cancellationToken); } public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); PreAllocatedBuffer[0] = (byte)map.KeyType; PreAllocatedBuffer[1] = (byte)map.ValueType; await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken); await WriteI32Async(map.Count, cancellationToken); } public override Task WriteMapEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteByteAsync((sbyte) list.ElementType, cancellationToken); await WriteI32Async(list.Count, cancellationToken); } public override Task WriteListEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteByteAsync((sbyte) set.ElementType, cancellationToken); await WriteI32Async(set.Count, cancellationToken); } public override Task WriteSetEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteByteAsync(b ? (sbyte) 1 : (sbyte) 0, cancellationToken); } public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); PreAllocatedBuffer[0] = (byte)b; await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); } public override async Task WriteI16Async(short i16, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); BinaryPrimitives.WriteInt16BigEndian(PreAllocatedBuffer, i16); await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken); } public override async Task WriteI32Async(int i32, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); BinaryPrimitives.WriteInt32BigEndian(PreAllocatedBuffer, i32); await Trans.WriteAsync(PreAllocatedBuffer, 0, 4, cancellationToken); } public override async Task WriteI64Async(long i64, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); BinaryPrimitives.WriteInt64BigEndian(PreAllocatedBuffer, i64); await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken); } public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken); } public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteI32Async(bytes.Length, cancellationToken); await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken); } public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var bytes = uuid.SwapByteOrder().ToByteArray(); await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken); } public override async ValueTask ReadMessageBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var message = new TMessage(); var size = await ReadI32Async(cancellationToken); if (size < 0) { var version = (uint) size & VersionMask; if (version != Version1) { throw new TProtocolException(TProtocolException.BAD_VERSION, $"Bad version in ReadMessageBegin: {version}"); } message.Type = (TMessageType) (size & 0x000000ff); message.Name = await ReadStringAsync(cancellationToken); message.SeqID = await ReadI32Async(cancellationToken); } else { if (StrictRead) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Missing version in ReadMessageBegin, old client?"); } message.Name = (size > 0) ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty; message.Type = (TMessageType) await ReadByteAsync(cancellationToken); message.SeqID = await ReadI32Async(cancellationToken); } return message; } public override Task ReadMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Transport.ResetMessageSizeAndConsumedBytes(); return Task.CompletedTask; } public override ValueTask ReadStructBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return new ValueTask(AnonymousStruct); } public override Task ReadStructEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadFieldBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var type = (TType)await ReadByteAsync(cancellationToken); if (type == TType.Stop) { return StopField; } return new TField { Type = type, ID = await ReadI16Async(cancellationToken) }; } public override Task ReadFieldEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadMapBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var map = new TMap { KeyType = (TType) await ReadByteAsync(cancellationToken), ValueType = (TType) await ReadByteAsync(cancellationToken), Count = await ReadI32Async(cancellationToken) }; CheckReadBytesAvailable(map); return map; } public override Task ReadMapEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadListBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var list = new TList { ElementType = (TType) await ReadByteAsync(cancellationToken), Count = await ReadI32Async(cancellationToken) }; CheckReadBytesAvailable(list); return list; } public override Task ReadListEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadSetBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var set = new TSet { ElementType = (TType) await ReadByteAsync(cancellationToken), Count = await ReadI32Async(cancellationToken) }; CheckReadBytesAvailable(set); return set; } public override Task ReadSetEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadBoolAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return await ReadByteAsync(cancellationToken) == 1; } public override async ValueTask ReadByteAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 1, cancellationToken); return (sbyte)PreAllocatedBuffer[0]; } public override async ValueTask ReadI16Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 2, cancellationToken); var result = BinaryPrimitives.ReadInt16BigEndian(PreAllocatedBuffer); return result; } public override async ValueTask ReadI32Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 4, cancellationToken); var result = BinaryPrimitives.ReadInt32BigEndian(PreAllocatedBuffer); return result; } public override async ValueTask ReadI64Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken); return BinaryPrimitives.ReadInt64BigEndian(PreAllocatedBuffer); } public override async ValueTask ReadDoubleAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var d = await ReadI64Async(cancellationToken); return BitConverter.Int64BitsToDouble(d); } public override async ValueTask ReadBinaryAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var size = await ReadI32Async(cancellationToken); Transport.CheckReadBytesAvailable(size); var buf = new byte[size]; await Trans.ReadAllAsync(buf, 0, size, cancellationToken); return buf; } public override async ValueTask ReadUuidAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Transport.CheckReadBytesAvailable(16); // = sizeof(uuid) var buf = new byte[16]; await Trans.ReadAllAsync(buf, 0, 16, cancellationToken); return new Guid(buf).SwapByteOrder(); } public override async ValueTask ReadStringAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var size = await ReadI32Async(cancellationToken); return size > 0 ? await ReadStringBodyAsync(size, cancellationToken) : string.Empty; } private async ValueTask ReadStringBodyAsync(int size, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (size <= PreAllocatedBuffer.Length) { await Trans.ReadAllAsync(PreAllocatedBuffer, 0, size, cancellationToken); return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, size); } Transport.CheckReadBytesAvailable(size); var buf = new byte[size]; await Trans.ReadAllAsync(buf, 0, size, cancellationToken); return Encoding.UTF8.GetString(buf, 0, buf.Length); } // Return the minimum number of bytes a type will consume on the wire public override int GetMinSerializedSize(TType type) { switch (type) { case TType.Stop: return 1; // T_STOP needs to count itself case TType.Void: return 1; // T_VOID needs to count itself case TType.Bool: return sizeof(byte); case TType.Byte: return sizeof(byte); case TType.Double: return sizeof(double); case TType.I16: return sizeof(short); case TType.I32: return sizeof(int); case TType.I64: return sizeof(long); case TType.String: return sizeof(int); // string length case TType.Struct: return 1; // empty struct needs at least 1 byte for the T_STOP case TType.Map: return sizeof(int); // element count case TType.Set: return sizeof(int); // element count case TType.List: return sizeof(int); // element count case TType.Uuid: return 16; // uuid bytes default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code"); } } public class Factory : TProtocolFactory { protected readonly bool StrictRead; protected readonly bool StrictWrite; // emtpy default CTOR required public Factory() : this(false, true) { } public Factory(bool strictRead, bool strictWrite) { StrictRead = strictRead; StrictWrite = strictWrite; } public override TProtocol GetProtocol(TTransport trans) { return new TBinaryProtocol(trans, StrictRead, StrictWrite); } } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/TProtocol.cs0000664000175000017500000001754215165535636022772 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Text; using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; using Thrift.Transport; namespace Thrift.Protocol { // ReSharper disable once InconsistentNaming public abstract class TProtocol : IDisposable { private bool _isDisposed; protected int RecursionDepth; protected TTransport Trans; protected static readonly TStruct AnonymousStruct = new TStruct(string.Empty); protected static readonly TField StopField = new TField() { Type = TType.Stop }; protected TProtocol(TTransport trans) { Trans = trans; RecursionLimit = trans.Configuration.RecursionLimit; RecursionDepth = 0; } public TTransport Transport => Trans; protected int RecursionLimit { get; set; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public void IncrementRecursionDepth() { if (RecursionDepth < RecursionLimit) { ++RecursionDepth; } else { throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded"); } } public void DecrementRecursionDepth() { --RecursionDepth; } protected virtual void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { (Trans as IDisposable)?.Dispose(); } } _isDisposed = true; } protected void CheckReadBytesAvailable(TSet set) { Transport.CheckReadBytesAvailable(set.Count * GetMinSerializedSize(set.ElementType)); } protected void CheckReadBytesAvailable(TList list) { Transport.CheckReadBytesAvailable(list.Count * GetMinSerializedSize(list.ElementType)); } protected void CheckReadBytesAvailable(TMap map) { var elmSize = GetMinSerializedSize(map.KeyType) + GetMinSerializedSize(map.ValueType); Transport.CheckReadBytesAvailable(map.Count * elmSize); } // Returns the minimum amount of bytes needed to store the smallest possible instance of TType. public abstract int GetMinSerializedSize(TType type); public abstract Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken = default); public abstract Task WriteMessageEndAsync(CancellationToken cancellationToken = default); public abstract Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken = default); public abstract Task WriteStructEndAsync(CancellationToken cancellationToken = default); public abstract Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken = default); public abstract Task WriteFieldEndAsync(CancellationToken cancellationToken = default); public abstract Task WriteFieldStopAsync(CancellationToken cancellationToken = default); public abstract Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken = default); public abstract Task WriteMapEndAsync(CancellationToken cancellationToken = default); public abstract Task WriteListBeginAsync(TList list, CancellationToken cancellationToken = default); public abstract Task WriteListEndAsync(CancellationToken cancellationToken = default); public abstract Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken = default); public abstract Task WriteSetEndAsync(CancellationToken cancellationToken = default); public abstract Task WriteBoolAsync(bool b, CancellationToken cancellationToken = default); public abstract Task WriteByteAsync(sbyte b, CancellationToken cancellationToken = default); public abstract Task WriteI16Async(short i16, CancellationToken cancellationToken = default); public abstract Task WriteI32Async(int i32, CancellationToken cancellationToken = default); public abstract Task WriteI64Async(long i64, CancellationToken cancellationToken = default); public abstract Task WriteDoubleAsync(double d, CancellationToken cancellationToken = default); public virtual async Task WriteStringAsync(string s, CancellationToken cancellationToken = default) { var bytes = Encoding.UTF8.GetBytes(s); await WriteBinaryAsync(bytes, cancellationToken); } public abstract Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken = default); public abstract Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken = default); public abstract ValueTask ReadMessageBeginAsync(CancellationToken cancellationToken = default); public abstract Task ReadMessageEndAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadStructBeginAsync(CancellationToken cancellationToken = default); public abstract Task ReadStructEndAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadFieldBeginAsync(CancellationToken cancellationToken = default); public abstract Task ReadFieldEndAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadMapBeginAsync(CancellationToken cancellationToken = default); public abstract Task ReadMapEndAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadListBeginAsync(CancellationToken cancellationToken = default); public abstract Task ReadListEndAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadSetBeginAsync(CancellationToken cancellationToken = default); public abstract Task ReadSetEndAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadBoolAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadByteAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadI16Async(CancellationToken cancellationToken = default); public abstract ValueTask ReadI32Async(CancellationToken cancellationToken = default); public abstract ValueTask ReadI64Async(CancellationToken cancellationToken = default); public abstract ValueTask ReadDoubleAsync(CancellationToken cancellationToken = default); public virtual async ValueTask ReadStringAsync(CancellationToken cancellationToken = default) { var buf = await ReadBinaryAsync(cancellationToken); return Encoding.UTF8.GetString(buf, 0, buf.Length); } public abstract ValueTask ReadBinaryAsync(CancellationToken cancellationToken = default); public abstract ValueTask ReadUuidAsync(CancellationToken cancellationToken = default); } } thrift-0.23.0/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs0000664000175000017500000000730315165535636025201 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol { /** * TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift * client to communicate with a multiplexing Thrift server, by prepending the service name * to the function name during function calls. * * NOTE: THIS IS NOT TO BE USED BY SERVERS. * On the server, use TMultiplexedProcessor to handle requests from a multiplexing client. * * This example uses a single socket transport to invoke two services: * * TSocketTransport transport = new TSocketTransport("localhost", 9090); * transport.open(); * * TBinaryProtocol protocol = new TBinaryProtocol(transport); * * TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator"); * Calculator.Client service = new Calculator.Client(mp); * * TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport"); * WeatherReport.Client service2 = new WeatherReport.Client(mp2); * * System.out.println(service.add(2,2)); * System.out.println(service2.getTemperature()); * */ //TODO: implementation of TProtocol // ReSharper disable once InconsistentNaming public class TMultiplexedProtocol : TProtocolDecorator { /** Used to delimit the service name from the function name */ public const string Separator = ":"; private readonly string _serviceName; /** * Wrap the specified protocol, allowing it to be used to communicate with a * multiplexing server. The serviceName is required as it is * prepended to the message header so that the multiplexing server can broker * the function call to the proper service. * * Args: * protocol Your communication protocol of choice, e.g. TBinaryProtocol * serviceName The service name of the service communicating via this protocol. */ public TMultiplexedProtocol(TProtocol protocol, string serviceName) : base(protocol) { _serviceName = serviceName; } public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken) { switch (message.Type) { case TMessageType.Call: case TMessageType.Oneway: await base.WriteMessageBeginAsync(new TMessage($"{_serviceName}{Separator}{message.Name}", message.Type, message.SeqID), cancellationToken); break; default: await base.WriteMessageBeginAsync(message, cancellationToken); break; } } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/TProtocolException.cs0000664000175000017500000000363115165535636024643 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // ReSharper disable InconsistentNaming using System; namespace Thrift.Protocol { public class TProtocolException : TException { // do not rename public constants - they used in generated files public const int UNKNOWN = 0; public const int INVALID_DATA = 1; public const int NEGATIVE_SIZE = 2; public const int SIZE_LIMIT = 3; public const int BAD_VERSION = 4; public const int NOT_IMPLEMENTED = 5; public const int DEPTH_LIMIT = 6; protected int Type = UNKNOWN; public TProtocolException() { } public TProtocolException(int type, Exception inner = null) : base(string.Empty, inner) { Type = type; } public TProtocolException(int type, string message, Exception inner = null) : base(message, inner) { Type = type; } public TProtocolException(string message, Exception inner = null) : base(message, inner) { } public int GetExceptionType() { return Type; } } }thrift-0.23.0/lib/netstd/Thrift/Protocol/TCompactProtocol.cs0000664000175000017500000010042415165535636024271 0ustar00buildbuild00000000000000// 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.Buffers; using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; using Thrift.Transport; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0301 // net8 - simplified collection init namespace Thrift.Protocol { // ReSharper disable once InconsistentNaming public class TCompactProtocol : TProtocol { private const byte ProtocolId = 0x82; private const byte Version = 1; private const byte VersionMask = 0x1f; // 0001 1111 private const byte TypeMask = 0xE0; // 1110 0000 private const byte TypeBits = 0x07; // 0000 0111 private const int TypeShiftAmount = 5; private const byte NoTypeOverride = 0xFF; // ReSharper disable once InconsistentNaming private static readonly byte[] TTypeToCompactType = new byte[17]; private static readonly TType[] CompactTypeToTType = new TType[14]; /// /// Used to keep track of the last field for the current and previous structs, so we can do the delta stuff. /// private readonly Stack _lastField = new Stack(15); /// /// If we encounter a boolean field begin, save the TField here so it can have the value incorporated. /// private TField? _booleanField; /// /// If we Read a field header, and it's a boolean field, save the boolean value here so that ReadBool can use it. /// private bool? _boolValue; private short _lastFieldId; // minimize memory allocations by means of an preallocated bytes buffer // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long) private readonly byte[] PreAllocatedBuffer = new byte[128]; private struct VarInt { public byte[] bytes; public int count; } // minimize memory allocations by means of an preallocated VarInt buffer private VarInt PreAllocatedVarInt = new VarInt() { bytes = new byte[10], // see Int64ToVarInt() count = 0 }; public TCompactProtocol(TTransport trans) : base(trans) { TTypeToCompactType[(int)TType.Stop] = Types.Stop; TTypeToCompactType[(int)TType.Bool] = Types.BooleanTrue; TTypeToCompactType[(int)TType.Byte] = Types.Byte; TTypeToCompactType[(int)TType.I16] = Types.I16; TTypeToCompactType[(int)TType.I32] = Types.I32; TTypeToCompactType[(int)TType.I64] = Types.I64; TTypeToCompactType[(int)TType.Double] = Types.Double; TTypeToCompactType[(int)TType.String] = Types.Binary; TTypeToCompactType[(int)TType.List] = Types.List; TTypeToCompactType[(int)TType.Set] = Types.Set; TTypeToCompactType[(int)TType.Map] = Types.Map; TTypeToCompactType[(int)TType.Struct] = Types.Struct; TTypeToCompactType[(int)TType.Uuid] = Types.Uuid; CompactTypeToTType[Types.Stop] = TType.Stop; CompactTypeToTType[Types.BooleanTrue] = TType.Bool; CompactTypeToTType[Types.BooleanFalse] = TType.Bool; CompactTypeToTType[Types.Byte] = TType.Byte; CompactTypeToTType[Types.I16] = TType.I16; CompactTypeToTType[Types.I32] = TType.I32; CompactTypeToTType[Types.I64] = TType.I64; CompactTypeToTType[Types.Double] = TType.Double; CompactTypeToTType[Types.Binary] = TType.String; CompactTypeToTType[Types.List] = TType.List; CompactTypeToTType[Types.Set] = TType.Set; CompactTypeToTType[Types.Map] = TType.Map; CompactTypeToTType[Types.Struct] = TType.Struct; CompactTypeToTType[Types.Uuid] = TType.Uuid; } public void Reset() { _lastField.Clear(); _lastFieldId = 0; } public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken) { PreAllocatedBuffer[0] = ProtocolId; PreAllocatedBuffer[1] = (byte)((Version & VersionMask) | (((uint)message.Type << TypeShiftAmount) & TypeMask)); await Trans.WriteAsync(PreAllocatedBuffer, 0, 2, cancellationToken); Int32ToVarInt((uint) message.SeqID, ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); await WriteStringAsync(message.Name, cancellationToken); } public override Task WriteMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } /// /// Write a struct begin. This doesn't actually put anything on the wire. We /// use it as an opportunity to put special placeholder markers on the field /// stack so we can get the field id deltas correct. /// public override Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); _lastField.Push(_lastFieldId); _lastFieldId = 0; return Task.CompletedTask; } public override Task WriteStructEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); _lastFieldId = _lastField.Pop(); return Task.CompletedTask; } private async Task WriteFieldBeginInternalAsync(TField field, byte fieldType, CancellationToken cancellationToken) { // if there's a exType override passed in, use that. Otherwise ask GetCompactType(). if (fieldType == NoTypeOverride) fieldType = GetCompactType(field.Type); // check if we can use delta encoding for the field id if (field.ID > _lastFieldId) { var delta = field.ID - _lastFieldId; if (delta <= 15) { // Write them together PreAllocatedBuffer[0] = (byte)((delta << 4) | fieldType); await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); _lastFieldId = field.ID; return; } } // Write them separate PreAllocatedBuffer[0] = fieldType; await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); await WriteI16Async(field.ID, cancellationToken); _lastFieldId = field.ID; } public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken) { if (field.Type == TType.Bool) { _booleanField = field; } else { await WriteFieldBeginInternalAsync(field, NoTypeOverride, cancellationToken); } } public override Task WriteFieldEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteFieldStopAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); PreAllocatedBuffer[0] = Types.Stop; await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); } protected async Task WriteCollectionBeginAsync(TType elemType, int size, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* Abstract method for writing the start of lists and sets. List and sets on the wire differ only by the exType indicator. */ if (size <= 14) { PreAllocatedBuffer[0] = (byte)((size << 4) | GetCompactType(elemType)); await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); } else { PreAllocatedBuffer[0] = (byte)(0xf0 | GetCompactType(elemType)); await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); Int32ToVarInt((uint) size, ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); } } public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken) { await WriteCollectionBeginAsync(list.ElementType, list.Count, cancellationToken); } public override Task WriteListEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await WriteCollectionBeginAsync(set.ElementType, set.Count, cancellationToken); } public override Task WriteSetEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* Write a boolean value. Potentially, this could be a boolean field, in which case the field header info isn't written yet. If so, decide what the right exType header is for the value and then Write the field header. Otherwise, Write a single byte. */ if (_booleanField != null) { // we haven't written the field header yet var type = b ? Types.BooleanTrue : Types.BooleanFalse; await WriteFieldBeginInternalAsync(_booleanField.Value, type, cancellationToken); _booleanField = null; } else { // we're not part of a field, so just write the value. PreAllocatedBuffer[0] = b ? Types.BooleanTrue : Types.BooleanFalse; await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); } } public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); PreAllocatedBuffer[0] = (byte)b; await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); } public override async Task WriteI16Async(short i16, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Int32ToVarInt(IntToZigzag(i16), ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); } private static void Int32ToVarInt(uint n, ref VarInt varint) { // Write an i32 as a varint. Results in 1 - 5 bytes on the wire. varint.count = 0; Debug.Assert(varint.bytes.Length >= 5); while (true) { if ((n & ~0x7F) == 0) { varint.bytes[varint.count++] = (byte)n; break; } varint.bytes[varint.count++] = (byte)((n & 0x7F) | 0x80); n >>= 7; } } public override async Task WriteI32Async(int i32, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Int32ToVarInt(IntToZigzag(i32), ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); } static private void Int64ToVarInt(ulong n, ref VarInt varint) { // Write an i64 as a varint. Results in 1-10 bytes on the wire. varint.count = 0; Debug.Assert(varint.bytes.Length >= 10); while (true) { if ((n & ~(ulong)0x7FL) == 0) { varint.bytes[varint.count++] = (byte)n; break; } varint.bytes[varint.count++] = (byte)((n & 0x7F) | 0x80); n >>= 7; } } public override async Task WriteI64Async(long i64, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Int64ToVarInt(LongToZigzag(i64), ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); } public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); BinaryPrimitives.WriteInt64LittleEndian(PreAllocatedBuffer, BitConverter.DoubleToInt64Bits(d)); await Trans.WriteAsync(PreAllocatedBuffer, 0, 8, cancellationToken); } public override async Task WriteStringAsync(string str, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var buf = ArrayPool.Shared.Rent(Encoding.UTF8.GetByteCount(str)); try { var numberOfBytes = Encoding.UTF8.GetBytes(str, 0, str.Length, buf, 0); Int32ToVarInt((uint)numberOfBytes, ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); await Trans.WriteAsync(buf, 0, numberOfBytes, cancellationToken); } finally { ArrayPool.Shared.Return(buf); } } public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Int32ToVarInt((uint) bytes.Length, ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken); } public override async Task WriteUuidAsync(Guid uuid, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var bytes = uuid.SwapByteOrder().ToByteArray(); await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken); } public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (map.Count == 0) { PreAllocatedBuffer[0] = 0; await Trans.WriteAsync( PreAllocatedBuffer, 0, 1, cancellationToken); } else { Int32ToVarInt((uint) map.Count, ref PreAllocatedVarInt); await Trans.WriteAsync(PreAllocatedVarInt.bytes, 0, PreAllocatedVarInt.count, cancellationToken); PreAllocatedBuffer[0] = (byte)((GetCompactType(map.KeyType) << 4) | GetCompactType(map.ValueType)); await Trans.WriteAsync(PreAllocatedBuffer, 0, 1, cancellationToken); } } public override Task WriteMapEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadMessageBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var protocolId = (byte) await ReadByteAsync(cancellationToken); if (protocolId != ProtocolId) { throw new TProtocolException($"Expected protocol id {ProtocolId:X} but got {protocolId:X}"); } var versionAndType = (byte) await ReadByteAsync(cancellationToken); var version = (byte) (versionAndType & VersionMask); if (version != Version) { throw new TProtocolException($"Expected version {Version} but got {version}"); } var type = (byte) ((versionAndType >> TypeShiftAmount) & TypeBits); var seqid = (int) await ReadVarInt32Async(cancellationToken); var messageName = await ReadStringAsync(cancellationToken); return new TMessage(messageName, (TMessageType) type, seqid); } public override Task ReadMessageEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Transport.ResetMessageSizeAndConsumedBytes(); return Task.CompletedTask; } public override ValueTask ReadStructBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); _lastField.Push(_lastFieldId); _lastFieldId = 0; return new ValueTask(AnonymousStruct); } public override Task ReadStructEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* Doesn't actually consume any wire data, just removes the last field for this struct from the field stack. */ // consume the last field we Read off the wire. _lastFieldId = _lastField.Pop(); return Task.CompletedTask; } public override async ValueTask ReadFieldBeginAsync(CancellationToken cancellationToken) { // Read a field header off the wire. var type = (byte) await ReadByteAsync(cancellationToken); // if it's a stop, then we can return immediately, as the struct is over. if (type == Types.Stop) { return StopField; } // mask off the 4 MSB of the exType header. it could contain a field id delta. var modifier = (short) ((type & 0xf0) >> 4); var compactType = (byte)(type & 0x0f); short fieldId; if (modifier == 0) { fieldId = await ReadI16Async(cancellationToken); } else { fieldId = (short) (_lastFieldId + modifier); } var ttype = GetTType(compactType); var field = new TField(string.Empty, ttype, fieldId); // if this happens to be a boolean field, the value is encoded in the exType if( ttype == TType.Bool) { _boolValue = (compactType == Types.BooleanTrue); } // push the new field onto the field stack so we can keep the deltas going. _lastFieldId = field.ID; return field; } public override Task ReadFieldEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadMapBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* Read a map header off the wire. If the size is zero, skip Reading the key and value exType. This means that 0-length maps will yield TMaps without the "correct" types. */ var size = (int) await ReadVarInt32Async(cancellationToken); var keyAndValueType = size == 0 ? (byte) 0 : (byte) await ReadByteAsync(cancellationToken); var map = new TMap(GetTType((byte) (keyAndValueType >> 4)), GetTType((byte) (keyAndValueType & 0xf)), size); CheckReadBytesAvailable(map); return map; } public override Task ReadMapEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override async ValueTask ReadSetBeginAsync(CancellationToken cancellationToken) { /* Read a set header off the wire. If the set size is 0-14, the size will be packed into the element exType header. If it's a longer set, the 4 MSB of the element exType header will be 0xF, and a varint will follow with the true size. */ return new TSet(await ReadListBeginAsync(cancellationToken)); } public override ValueTask ReadBoolAsync(CancellationToken cancellationToken) { /* Read a boolean off the wire. If this is a boolean field, the value should already have been Read during ReadFieldBegin, so we'll just consume the pre-stored value. Otherwise, Read a byte. */ if (_boolValue != null) { var result = _boolValue.Value; _boolValue = null; return new ValueTask(result); } return InternalCall(); async ValueTask InternalCall() { var data = await ReadByteAsync(cancellationToken); return (data == Types.BooleanTrue); } } public override async ValueTask ReadByteAsync(CancellationToken cancellationToken) { // Read a single byte off the wire. Nothing interesting here. await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 1, cancellationToken); return (sbyte)PreAllocatedBuffer[0]; } public override async ValueTask ReadI16Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return (short) ZigzagToInt(await ReadVarInt32Async(cancellationToken)); } public override async ValueTask ReadI32Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return ZigzagToInt(await ReadVarInt32Async(cancellationToken)); } public override async ValueTask ReadI64Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return ZigzagToLong(await ReadVarInt64Async(cancellationToken)); } public override async ValueTask ReadDoubleAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await Trans.ReadAllAsync(PreAllocatedBuffer, 0, 8, cancellationToken); return BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(PreAllocatedBuffer)); } public override async ValueTask ReadStringAsync(CancellationToken cancellationToken) { // read length var length = (int) await ReadVarInt32Async(cancellationToken); if (length == 0) { return string.Empty; } // read and decode data if (length < PreAllocatedBuffer.Length) { await Trans.ReadAllAsync(PreAllocatedBuffer, 0, length, cancellationToken); return Encoding.UTF8.GetString(PreAllocatedBuffer, 0, length); } Transport.CheckReadBytesAvailable(length); var buf = ArrayPool.Shared.Rent(length); try { await Trans.ReadAllAsync(buf, 0, length, cancellationToken); return Encoding.UTF8.GetString(buf, 0, length); } finally { ArrayPool.Shared.Return(buf); } } public override async ValueTask ReadBinaryAsync(CancellationToken cancellationToken) { // read length var length = (int) await ReadVarInt32Async(cancellationToken); if (length == 0) { return Array.Empty(); } // read data Transport.CheckReadBytesAvailable(length); var buf = new byte[length]; await Trans.ReadAllAsync(buf, 0, length, cancellationToken); return buf; } public override async ValueTask ReadUuidAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Transport.CheckReadBytesAvailable(16); // = sizeof(uuid) var buf = new byte[16]; await Trans.ReadAllAsync(buf, 0, 16, cancellationToken); return new Guid(buf).SwapByteOrder(); } public override async ValueTask ReadListBeginAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* Read a list header off the wire. If the list size is 0-14, the size will be packed into the element exType header. If it's a longer list, the 4 MSB of the element exType header will be 0xF, and a varint will follow with the true size. */ var sizeAndType = (byte) await ReadByteAsync(cancellationToken); var size = (sizeAndType >> 4) & 0x0f; if (size == 15) { size = (int) await ReadVarInt32Async(cancellationToken); } var type = GetTType(sizeAndType); var list = new TList(type, size); CheckReadBytesAvailable(list); return list; } public override Task ReadListEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } public override Task ReadSetEndAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } private static byte GetCompactType(TType ttype) { // Given a TType value, find the appropriate TCompactProtocol.Types constant. return TTypeToCompactType[(int) ttype]; } private async ValueTask ReadVarInt32Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* Read an i32 from the wire as a varint. The MSB of each byte is set if there is another byte to follow. This can Read up to 5 bytes. */ uint result = 0; var shift = 0; while (true) { var b = (byte) await ReadByteAsync(cancellationToken); result |= (uint) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) { break; } shift += 7; } return result; } private async ValueTask ReadVarInt64Async(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* Read an i64 from the wire as a proper varint. The MSB of each byte is set if there is another byte to follow. This can Read up to 10 bytes. */ var shift = 0; ulong result = 0; while (true) { var b = (byte) await ReadByteAsync(cancellationToken); result |= (ulong) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) { break; } shift += 7; } return result; } private static int ZigzagToInt(uint n) { return (int) (n >> 1) ^ -(int) (n & 1); } private static long ZigzagToLong(ulong n) { return (long) (n >> 1) ^ -(long) (n & 1); } private static TType GetTType(byte type) { // Given a TCompactProtocol.Types constant, convert it to its corresponding TType value. return CompactTypeToTType[type & 0x0f]; } private static ulong LongToZigzag(long n) { // Convert l into a zigzag long. This allows negative numbers to be represented compactly as a varint return (ulong) (n << 1) ^ (ulong) (n >> 63); } private static uint IntToZigzag(int n) { // Convert n into a zigzag int. This allows negative numbers to be represented compactly as a varint return (uint) (n << 1) ^ (uint) (n >> 31); } // Return the minimum number of bytes a type will consume on the wire public override int GetMinSerializedSize(TType type) { switch (type) { case TType.Stop: return 1; // T_STOP needs to count itself case TType.Void: return 1; // T_VOID needs to count itself case TType.Bool: return sizeof(byte); case TType.Double: return 8; // uses fixedLongToBytes() which always writes 8 bytes case TType.Byte: return sizeof(byte); case TType.I16: return sizeof(byte); // zigzag case TType.I32: return sizeof(byte); // zigzag case TType.I64: return sizeof(byte); // zigzag case TType.String: return sizeof(byte); // string length case TType.Struct: return 1; // empty struct needs at least 1 byte for the T_STOP case TType.Map: return sizeof(byte); // element count case TType.Set: return sizeof(byte); // element count case TType.List: return sizeof(byte); // element count case TType.Uuid: return 16; // uuid bytes default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code"); } } public class Factory : TProtocolFactory { public override TProtocol GetProtocol(TTransport trans) { return new TCompactProtocol(trans); } } /// /// All of the on-wire exType codes. /// private static class Types { public const byte Stop = 0x00; public const byte BooleanTrue = 0x01; public const byte BooleanFalse = 0x02; public const byte Byte = 0x03; public const byte I16 = 0x04; public const byte I32 = 0x05; public const byte I64 = 0x06; public const byte Double = 0x07; public const byte Binary = 0x08; public const byte List = 0x09; public const byte Set = 0x0A; public const byte Map = 0x0B; public const byte Struct = 0x0C; public const byte Uuid = 0x0D; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/TProtocolFactory.cs0000664000175000017500000000177715165535636024325 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Thrift.Transport; namespace Thrift.Protocol { // ReSharper disable once InconsistentNaming public abstract class TProtocolFactory { public abstract TProtocol GetProtocol(TTransport trans); } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Utilities/0000775000175000017500000000000015165535636022460 5ustar00buildbuild00000000000000thrift-0.23.0/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs0000664000175000017500000001154315165535636025576 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; namespace Thrift.Protocol.Utilities { // ReSharper disable once InconsistentNaming public static class TProtocolUtil { public static async Task SkipAsync(TProtocol protocol, TType type, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); protocol.IncrementRecursionDepth(); try { switch (type) { case TType.Bool: await protocol.ReadBoolAsync(cancellationToken); break; case TType.Byte: await protocol.ReadByteAsync(cancellationToken); break; case TType.I16: await protocol.ReadI16Async(cancellationToken); break; case TType.I32: await protocol.ReadI32Async(cancellationToken); break; case TType.I64: await protocol.ReadI64Async(cancellationToken); break; case TType.Double: await protocol.ReadDoubleAsync(cancellationToken); break; case TType.String: // Don't try to decode the string, just skip it. await protocol.ReadBinaryAsync(cancellationToken); break; case TType.Uuid: await protocol.ReadUuidAsync(cancellationToken); break; case TType.Struct: await protocol.ReadStructBeginAsync(cancellationToken); while (true) { var field = await protocol.ReadFieldBeginAsync(cancellationToken); if (field.Type == TType.Stop) { break; } await SkipAsync(protocol, field.Type, cancellationToken); await protocol.ReadFieldEndAsync(cancellationToken); } await protocol.ReadStructEndAsync(cancellationToken); break; case TType.Map: var map = await protocol.ReadMapBeginAsync(cancellationToken); for (var i = 0; i < map.Count; i++) { await SkipAsync(protocol, map.KeyType, cancellationToken); await SkipAsync(protocol, map.ValueType, cancellationToken); } await protocol.ReadMapEndAsync(cancellationToken); break; case TType.Set: var set = await protocol.ReadSetBeginAsync(cancellationToken); for (var i = 0; i < set.Count; i++) { await SkipAsync(protocol, set.ElementType, cancellationToken); } await protocol.ReadSetEndAsync(cancellationToken); break; case TType.List: var list = await protocol.ReadListBeginAsync(cancellationToken); for (var i = 0; i < list.Count; i++) { await SkipAsync(protocol, list.ElementType, cancellationToken); } await protocol.ReadListEndAsync(cancellationToken); break; default: throw new TProtocolException(TProtocolException.INVALID_DATA, "Unknown data type " + type.ToString("d")); } } finally { protocol.DecrementRecursionDepth(); } } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs0000664000175000017500000000456315165535636026113 0ustar00buildbuild00000000000000// 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.Text; namespace Thrift.Protocol.Utilities { public static class TGuidExtensions { public static Guid SwapByteOrder(this Guid self) { var bytes = self.ToByteArray(); // already network order on BigEndian machines if (BitConverter.IsLittleEndian) { SwapBytes(ref bytes[0], ref bytes[3]); SwapBytes(ref bytes[1], ref bytes[2]); SwapBytes(ref bytes[4], ref bytes[5]); SwapBytes(ref bytes[6], ref bytes[7]); } return new Guid(bytes); } private static void SwapBytes(ref byte one, ref byte two) { (two, one) = (one, two); } #region SelfTest #if DEBUG static private readonly Guid TEST_GUID = new Guid("{00112233-4455-6677-8899-aabbccddeeff}"); static TGuidExtensions() { SelfTest(); } private static void SelfTest() { // host to network var guid = TEST_GUID; guid = guid.SwapByteOrder(); // validate network order var bytes = guid.ToByteArray(); for (var i = 0; i < 10; ++i) { var expected = i * 0x11; Debug.Assert( bytes[i] == expected); } // network to host and final validation guid = guid.SwapByteOrder(); Debug.Assert(guid.Equals(TEST_GUID)); } #endif #endregion } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs0000664000175000017500000001112015165535636025173 0ustar00buildbuild00000000000000// 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; #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0300 // net8 - simplified collection init #pragma warning disable IDE0028 // net8 - simplified collection init #pragma warning disable CA1510 // net8 - use ThrowIfNull #pragma warning disable CA1513 // net8 - use ThrowIfNull namespace Thrift.Protocol.Utilities { // ReSharper disable once InconsistentNaming internal static class TBase64Utils { //TODO: Constants //TODO: Check for args //TODO: Unitests internal const string EncodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; private static readonly int[] DecodeTable = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; internal static void Encode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { if (src == null) { throw new ArgumentNullException(nameof(src)); } dst[dstOff] = (byte) EncodeTable[(src[srcOff] >> 2) & 0x3F]; if (len == 3) { dst[dstOff + 1] = (byte) EncodeTable[((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)]; dst[dstOff + 2] = (byte) EncodeTable[((src[srcOff + 1] << 2) & 0x3C) | ((src[srcOff + 2] >> 6) & 0x03)]; dst[dstOff + 3] = (byte) EncodeTable[src[srcOff + 2] & 0x3F]; } else if (len == 2) { dst[dstOff + 1] = (byte) EncodeTable[((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)]; dst[dstOff + 2] = (byte) EncodeTable[(src[srcOff + 1] << 2) & 0x3C]; } else { // len == 1 dst[dstOff + 1] = (byte) EncodeTable[(src[srcOff] << 4) & 0x30]; } } internal static void Decode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { if (src == null) { throw new ArgumentNullException(nameof(src)); } dst[dstOff] = (byte) ((DecodeTable[src[srcOff] & 0x0FF] << 2) | (DecodeTable[src[srcOff + 1] & 0x0FF] >> 4)); if (len > 2) { dst[dstOff + 1] = (byte) (((DecodeTable[src[srcOff + 1] & 0x0FF] << 4) & 0xF0) | (DecodeTable[src[srcOff + 2] & 0x0FF] >> 2)); if (len > 3) { dst[dstOff + 2] = (byte) (((DecodeTable[src[srcOff + 2] & 0x0FF] << 6) & 0xC0) | DecodeTable[src[srcOff + 3] & 0x0FF]); } } } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs0000664000175000017500000000704215165535636027466 0ustar00buildbuild00000000000000// 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. #pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0300 // net8 - simplified collection init namespace Thrift.Protocol.Utilities { // ReSharper disable once InconsistentNaming public static class TJSONProtocolConstants { //TODO Check for performance for reusing ImmutableArray from System.Collections.Immutable (https://blogs.msdn.microsoft.com/dotnet/2013/06/24/please-welcome-immutablearrayt/) // can be possible to get better performance and also better GC public static readonly byte[] Comma = {(byte) ','}; public static readonly byte[] Colon = {(byte) ':'}; public static readonly byte[] LeftBrace = {(byte) '{'}; public static readonly byte[] RightBrace = {(byte) '}'}; public static readonly byte[] LeftBracket = {(byte) '['}; public static readonly byte[] RightBracket = {(byte) ']'}; public static readonly byte[] Quote = {(byte) '"'}; public static readonly byte[] Backslash = {(byte) '\\'}; public static readonly byte[] JsonCharTable = { 0, 0, 0, 0, 0, 0, 0, 0, (byte) 'b', (byte) 't', (byte) 'n', 0, (byte) 'f', (byte) 'r', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, (byte) '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; public static readonly char[] EscapeChars = "\"\\/bfnrt".ToCharArray(); public static readonly byte[] EscapeCharValues = {(byte) '"', (byte) '\\', (byte) '/', (byte) '\b', (byte) '\f', (byte) '\n', (byte) '\r', (byte) '\t'}; public static readonly byte[] EscSequences = {(byte) '\\', (byte) 'u', (byte) '0', (byte) '0'}; public static class TypeNames { public static readonly byte[] NameBool = { (byte)'t', (byte)'f' }; public static readonly byte[] NameByte = { (byte)'i', (byte)'8' }; public static readonly byte[] NameI16 = { (byte)'i', (byte)'1', (byte)'6' }; public static readonly byte[] NameI32 = { (byte)'i', (byte)'3', (byte)'2' }; public static readonly byte[] NameI64 = { (byte)'i', (byte)'6', (byte)'4' }; public static readonly byte[] NameDouble = { (byte)'d', (byte)'b', (byte)'l' }; public static readonly byte[] NameStruct = { (byte)'r', (byte)'e', (byte)'c' }; public static readonly byte[] NameString = { (byte)'s', (byte)'t', (byte)'r' }; public static readonly byte[] NameMap = { (byte)'m', (byte)'a', (byte)'p' }; public static readonly byte[] NameList = { (byte)'l', (byte)'s', (byte)'t' }; public static readonly byte[] NameSet = { (byte)'s', (byte)'e', (byte)'t' }; public static readonly byte[] NameUuid = { (byte)'u', (byte)'i', (byte)'d' }; } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs0000664000175000017500000001456215165535636026736 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using Thrift.Protocol.Entities; namespace Thrift.Protocol.Utilities { // ReSharper disable once InconsistentNaming public static class TJSONProtocolHelper { public static byte[] GetTypeNameForTypeId(TType typeId) { switch (typeId) { case TType.Bool: return TJSONProtocolConstants.TypeNames.NameBool; case TType.Byte: return TJSONProtocolConstants.TypeNames.NameByte; case TType.I16: return TJSONProtocolConstants.TypeNames.NameI16; case TType.I32: return TJSONProtocolConstants.TypeNames.NameI32; case TType.I64: return TJSONProtocolConstants.TypeNames.NameI64; case TType.Double: return TJSONProtocolConstants.TypeNames.NameDouble; case TType.String: return TJSONProtocolConstants.TypeNames.NameString; case TType.Struct: return TJSONProtocolConstants.TypeNames.NameStruct; case TType.Map: return TJSONProtocolConstants.TypeNames.NameMap; case TType.Set: return TJSONProtocolConstants.TypeNames.NameSet; case TType.List: return TJSONProtocolConstants.TypeNames.NameList; case TType.Uuid: return TJSONProtocolConstants.TypeNames.NameUuid; default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType"); } } public static TType GetTypeIdForTypeName(byte[] name) { var result = TType.Stop; if (name.Length > 1) { switch (name[0]) { case (byte) 'd': result = TType.Double; break; case (byte) 'i': switch (name[1]) { case (byte) '8': result = TType.Byte; break; case (byte) '1': result = TType.I16; break; case (byte) '3': result = TType.I32; break; case (byte) '6': result = TType.I64; break; } break; case (byte) 'l': result = TType.List; break; case (byte) 'm': result = TType.Map; break; case (byte) 'r': result = TType.Struct; break; case (byte) 's': if (name[1] == (byte) 't') { result = TType.String; } else if (name[1] == (byte) 'e') { result = TType.Set; } break; case (byte) 't': result = TType.Bool; break; case (byte)'u': result = TType.Uuid; break; } } if (result == TType.Stop) { throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType"); } return result; } /// /// Return true if the given byte could be a valid part of a JSON number. /// public static bool IsJsonNumeric(byte b) { switch (b) { case (byte)'+': case (byte)'-': case (byte)'.': case (byte)'0': case (byte)'1': case (byte)'2': case (byte)'3': case (byte)'4': case (byte)'5': case (byte)'6': case (byte)'7': case (byte)'8': case (byte)'9': case (byte)'E': case (byte)'e': return true; default: return false; } } /// /// Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its /// corresponding hex value /// public static byte ToHexVal(byte ch) { if (ch >= '0' && ch <= '9') { return (byte)((char)ch - '0'); } if (ch >= 'a' && ch <= 'f') { ch += 10; return (byte)((char)ch - 'a'); } throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected hex character"); } /// /// Convert a byte containing a hex value to its corresponding hex character /// public static byte ToHexChar(byte val) { val &= 0x0F; if (val < 10) { return (byte)((char)val + '0'); } val -= 10; return (byte)((char)val + 'a'); } } } thrift-0.23.0/lib/netstd/Thrift/Protocol/ToString.cs0000664000175000017500000000521115165535636022604 0ustar00buildbuild00000000000000// 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; using System.Collections.Generic; using System.Globalization; using System.Text; using Thrift.Protocol; namespace Thrift.Protocol { public static class ToStringExtensions { public static void ToString(this object self, StringBuilder sb, bool first = true) { if (!first) sb.Append(", "); bool first_child = true; if (self is string str) // string is IEnumerable { sb.Append('"'); sb.Append(str); sb.Append('"'); } else if (self is IDictionary dict) { sb.Append("{ "); foreach (DictionaryEntry pair in dict) { if (first_child) first_child = false; else sb.Append(','); sb.Append("{ "); pair.Key.ToString(sb); sb.Append(", "); pair.Value.ToString(sb); sb.Append('}'); } sb.Append('}'); } else if (self is IEnumerable enumerable) { sb.Append("{ "); foreach (var elm in enumerable) { elm.ToString(sb, first_child); first_child = false; } sb.Append('}'); } else if (self is TBase tbase) { sb.Append(tbase.ToString()); } else if (self is double dbVal) { sb.Append(dbVal.ToString(CultureInfo.InvariantCulture)); } else { sb.Append(self != null ? self.ToString() : ""); } } } } thrift-0.23.0/lib/netstd/Thrift/TConfiguration.cs0000664000175000017500000000267315165535636022176 0ustar00buildbuild00000000000000// 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; namespace Thrift { public class TConfiguration { public const int DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024; public const int DEFAULT_MAX_FRAME_SIZE = 16384000; // this value is used consistently across all Thrift libraries public const int DEFAULT_RECURSION_DEPTH = 64; public int MaxMessageSize { get; set; } = DEFAULT_MAX_MESSAGE_SIZE; public int MaxFrameSize { get; set; } = DEFAULT_MAX_FRAME_SIZE; public int RecursionLimit { get; set; } = DEFAULT_RECURSION_DEPTH; // TODO(JensG): add connection and i/o timeouts } } thrift-0.23.0/lib/netstd/Thrift/TBaseClient.cs0000664000175000017500000000553315165535636021376 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; using System.Threading; using System.Threading.Tasks; using Thrift.Protocol; namespace Thrift { // ReSharper disable once InconsistentNaming /// /// TBaseClient. /// Base client for generated clients. /// Do not change this class without checking generated code (namings, etc.) /// public abstract class TBaseClient { private readonly TProtocol _inputProtocol; private readonly TProtocol _outputProtocol; private bool _isDisposed; private int _seqId; public readonly Guid ClientId = Guid.NewGuid(); protected TBaseClient(TProtocol inputProtocol, TProtocol outputProtocol) { _inputProtocol = inputProtocol ?? throw new ArgumentNullException(nameof(inputProtocol)); _outputProtocol = outputProtocol ?? throw new ArgumentNullException(nameof(outputProtocol)); } public TProtocol InputProtocol => _inputProtocol; public TProtocol OutputProtocol => _outputProtocol; public int SeqId { get { return ++_seqId; } } public virtual async Task OpenTransportAsync() { await OpenTransportAsync(CancellationToken.None); } public virtual async Task OpenTransportAsync(CancellationToken cancellationToken) { if (!_inputProtocol.Transport.IsOpen) { await _inputProtocol.Transport.OpenAsync(cancellationToken); } if (!_outputProtocol.Transport.IsOpen) { await _outputProtocol.Transport.OpenAsync(cancellationToken); } } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (!_isDisposed) { if (disposing) { _inputProtocol?.Dispose(); _outputProtocol?.Dispose(); } } _isDisposed = true; } } } thrift-0.23.0/lib/netstd/Thrift/TApplicationException.cs0000664000175000017500000001250715165535636023506 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System.Threading; using System.Threading.Tasks; using Thrift.Protocol; using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; namespace Thrift { // ReSharper disable once InconsistentNaming public class TApplicationException : TException { public enum ExceptionType { Unknown, UnknownMethod, InvalidMessageType, WrongMethodName, BadSequenceId, MissingResult, InternalError, ProtocolError, InvalidTransform, InvalidProtocol, UnsupportedClientType } private const int MessageTypeFieldId = 1; private const int ExTypeFieldId = 2; public ExceptionType Type { get; private set; } public TApplicationException() { } public TApplicationException(ExceptionType type) { Type = type; } public TApplicationException(ExceptionType type, string message) : base(message, null) // TApplicationException is serializable, but we never serialize InnerException { Type = type; } public static async ValueTask ReadAsync(TProtocol inputProtocol, CancellationToken cancellationToken) { string message = null; var type = ExceptionType.Unknown; await inputProtocol.ReadStructBeginAsync(cancellationToken); while (true) { var field = await inputProtocol.ReadFieldBeginAsync(cancellationToken); if (field.Type == TType.Stop) { break; } switch (field.ID) { case MessageTypeFieldId: if (field.Type == TType.String) { message = await inputProtocol.ReadStringAsync(cancellationToken); } else { await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken); } break; case ExTypeFieldId: if (field.Type == TType.I32) { type = (ExceptionType) await inputProtocol.ReadI32Async(cancellationToken); } else { await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken); } break; default: await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken); break; } await inputProtocol.ReadFieldEndAsync(cancellationToken); } await inputProtocol.ReadStructEndAsync(cancellationToken); return new TApplicationException(type, message); } public async Task WriteAsync(TProtocol outputProtocol, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); const string messageTypeFieldName = "message"; const string exTypeFieldName = "exType"; const string structApplicationExceptionName = "TApplicationException"; var struc = new TStruct(structApplicationExceptionName); var field = new TField(); await outputProtocol.WriteStructBeginAsync(struc, cancellationToken); if (!string.IsNullOrEmpty(Message)) { field.Name = messageTypeFieldName; field.Type = TType.String; field.ID = MessageTypeFieldId; await outputProtocol.WriteFieldBeginAsync(field, cancellationToken); await outputProtocol.WriteStringAsync(Message, cancellationToken); await outputProtocol.WriteFieldEndAsync(cancellationToken); } field.Name = exTypeFieldName; field.Type = TType.I32; field.ID = ExTypeFieldId; await outputProtocol.WriteFieldBeginAsync(field, cancellationToken); await outputProtocol.WriteI32Async((int) Type, cancellationToken); await outputProtocol.WriteFieldEndAsync(cancellationToken); await outputProtocol.WriteFieldStopAsync(cancellationToken); await outputProtocol.WriteStructEndAsync(cancellationToken); } } } thrift-0.23.0/lib/netstd/Thrift/TException.cs0000664000175000017500000000211215165535636021311 0ustar00buildbuild00000000000000// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using System; namespace Thrift { // ReSharper disable once InconsistentNaming public class TException : Exception { public TException() { } public TException(string message, Exception inner) : base(message, inner) { } } }thrift-0.23.0/lib/netstd/Thrift/thrift.snk0000664000175000017500000000112415165535636020717 0ustar00buildbuild00000000000000$RSA2ÑhŸ‚A¬nÀ,Ïó.ÓÚ RÕ}…¥aÒ¼bÜ ö®|ceØã5ÿÎ+ª9ÝÉàì\åòØòê_zY¹5€T$€±äö'°¬f{ÁGÞëF­ißä­ìPÎfÈ×_¦ue0JÑ,ÔˆW¹‰D¸.9Ââ°“ÌWÁQ¥à¬Ã8†œ€\Wªãj eb"ê2¦Ü¢8M`8¥eçÞM [oJ8ô¨ÆˆQC¯ÛGDK¢Ë&À Çkbƒ€©è|³-ß)£¾Gßßbÿ>¦Ùh0â®ÃPl>É€ÐD‚MqS‰YÅU8„ÒFÍ­#ûÿžÄHÝ@j(¤à7ɨîÿS©ö†`8XýÏ{´Fk3àlÇsÂíÛJM¾ö™ ×Ú÷ÌpÌ~pã5KØK®',Ÿ©K+îB%C6Šëˆ‚Ë+_)>5>ˆqfsGò@æZ_±"Èòk1Á8#žw Z#¹í!îµÑðìNü@³;`³öW}Ùy·iC‚Ç“;W‡Á“³D$;Þäˆ(š8Ëô~ÅcžÕÊB×Ó¥Å=@çhR°н¸*¯Qnñ73øB¶=¢W%˜5Œ_åÏ˜Ű·Á ßP¤ ­[‚Èê¡Xæ·ü×Ì-Q¿¨k$oð0Îw_ŸVlÇ$2Œ^mCqU›äxà\ËL»é¥|› ´/ì+ãó¬T)ªÙÚƒàGŽ—I˲íßµ‡Ã’×#»"dthrift-0.23.0/lib/netstd/Thrift/.editorconfig0000664000175000017500000000044115165535636021360 0ustar00buildbuild00000000000000[*.cs] # CS1591: missing XML comment for public element 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 thrift-0.23.0/lib/netstd/Makefile.in0000644000175000017500000006343015170007167017502 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/netstd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . EXTRA_DIST = \ README.md \ Directory.Build.props \ Benchmarks/Thrift.Benchmarks \ Tests/Thrift.IntegrationTests/Protocols \ Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.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 \ Tests/Thrift.Tests/Transports \ Tests/Thrift.Tests/Thrift.Tests.csproj \ Thrift/.editorconfig \ Thrift/Collections \ Thrift/Processor \ Thrift/Properties \ Thrift/Protocol \ Thrift/Server \ Thrift/GlobalSuppressions.cs \ Thrift/TApplicationException.cs \ Thrift/TBaseClient.cs \ Thrift/TConfiguration.cs \ Thrift/TException.cs \ Thrift/Thrift.csproj \ Thrift/Transport \ Thrift/*.snk \ Thrift.sln \ build.cmd \ build.sh \ runtests.cmd \ runtests.sh all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/netstd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/netstd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile all-local: $(DOTNETCORE) build -c Release check-local: $(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 clean-local: $(RM) -r Thrift/bin $(RM) -r Thrift/obj $(RM) -r Benchmarks/Thrift.Benchmarks/bin $(RM) -r Benchmarks/Thrift.Benchmarks/obj $(RM) -r Tests/Thrift.Tests/bin $(RM) -r Tests/Thrift.Tests/obj $(RM) -r Tests/Thrift.IntegrationTests/bin $(RM) -r Tests/Thrift.IntegrationTests/obj $(RM) -r Tests/Thrift.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 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/netstd/Makefile.am0000664000175000017500000000610415170003262017456 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . all-local: $(DOTNETCORE) build -c Release check-local: $(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 clean-local: $(RM) -r Thrift/bin $(RM) -r Thrift/obj $(RM) -r Benchmarks/Thrift.Benchmarks/bin $(RM) -r Benchmarks/Thrift.Benchmarks/obj $(RM) -r Tests/Thrift.Tests/bin $(RM) -r Tests/Thrift.Tests/obj $(RM) -r Tests/Thrift.IntegrationTests/bin $(RM) -r Tests/Thrift.IntegrationTests/obj $(RM) -r Tests/Thrift.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 \ Directory.Build.props \ Benchmarks/Thrift.Benchmarks \ Tests/Thrift.IntegrationTests/Protocols \ Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.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 \ Tests/Thrift.Tests/Transports \ Tests/Thrift.Tests/Thrift.Tests.csproj \ Thrift/.editorconfig \ Thrift/Collections \ Thrift/Processor \ Thrift/Properties \ Thrift/Protocol \ Thrift/Server \ Thrift/GlobalSuppressions.cs \ Thrift/TApplicationException.cs \ Thrift/TBaseClient.cs \ Thrift/TConfiguration.cs \ Thrift/TException.cs \ Thrift/Thrift.csproj \ Thrift/Transport \ Thrift/*.snk \ Thrift.sln \ build.cmd \ build.sh \ runtests.cmd \ runtests.sh thrift-0.23.0/lib/nodejs/0000755000175000017500000000000015170007201015375 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodejs/test/0000775000175000017500000000000015170007142016362 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodejs/test/testAll.sh0000775000175000017500000001467015170007142020341 0ustar00buildbuild00000000000000#! /bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. if [ -n "${1}" ]; then COVER=${1}; fi DIR="$( cd "$( dirname "$0" )" && pwd )" EPISODIC_DIR=${DIR}/episodic-code-generation-test THRIFT_FILES_DIR=${DIR}/../../../test THRIFT_COMPILER=${DIR}/../../../compiler/cpp/thrift ISTANBUL="$DIR/../../../node_modules/istanbul/lib/cli.js" REPORT_PREFIX="${DIR}/../coverage/report" COUNT=0 testServer() { echo " [Variant: $1] Testing $2 Client/Server with protocol $3 and transport $4 $5"; RET=0 if [ -n "${COVER}" ]; then ${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.mjs --${1} --type $2 -p $3 -t $4 $5 & fi SERVERPID=$! sleep 0.1 if [ -n "${COVER}" ]; then ${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.mjs --${1} --type $2 -p $3 -t $4 $5 || RET=1 fi kill -2 $SERVERPID || RET=1 wait $SERVERPID return $RET } testEpisodicCompilation() { local _server=$1 local _client=$2 echo " [Episodic Variant: ${_server}:${_client}] Testing Client(${_client})/Server(${_server})"; RET=0 if [ -n "${COVER}" ]; then ${ISTANBUL} cover ${EPISODIC_DIR}/server.js --dir ${REPORT_PREFIX}${COUNT} --handle-sigint -- --base "${_server}" & COUNT=$((COUNT+1)) else node ${EPISODIC_DIR}/server.js --base "${_server}" & fi SERVERPID=$! sleep 0.1 if [ -n "${COVER}" ]; then ${ISTANBUL} cover ${EPISODIC_DIR}/client.js --dir ${REPORT_PREFIX}${COUNT} -- --base "${_client}" || RET=1 COUNT=$((COUNT+1)) else node ${EPISODIC_DIR}/client.js --base "${_client}" || RET=1 fi kill -2 $SERVERPID || RET=1 wait $SERVERPID return $RET } TESTOK=0 # generating Thrift code ${THRIFT_COMPILER} -o ${DIR} --gen js:node ${THRIFT_FILES_DIR}/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}/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}/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 # generate the first episode mkdir --parents ${EPISODIC_DIR}/gen-1/first-episode ${THRIFT_COMPILER} -o ${EPISODIC_DIR}/gen-1/first-episode --gen js:node,ts,thrift_package_output_directory=first-episode ${THRIFT_FILES_DIR}/Types.thrift # create a "package" from the first episode and "install" it, the episode file must be at the module root mkdir --parents ${TYPES_PACKAGE}/first-episode cp --force ${EPISODIC_DIR}/episodic_compilation.package.json ${TYPES_PACKAGE}/package.json cp --force ${EPISODIC_DIR}/gen-1/first-episode/gen-nodejs/Types_types.js ${TYPES_PACKAGE}/first-episode/ cp --force ${EPISODIC_DIR}/gen-1/first-episode/gen-nodejs/Types_types.d.ts ${TYPES_PACKAGE}/first-episode/ cp --force ${EPISODIC_DIR}/gen-1/first-episode/gen-nodejs/BaseService.js ${TYPES_PACKAGE}/first-episode/ cp --force ${EPISODIC_DIR}/gen-1/first-episode/gen-nodejs/BaseService.d.ts ${TYPES_PACKAGE}/first-episode/ cp --force ${EPISODIC_DIR}/gen-1/first-episode/gen-nodejs/thrift.js.episode ${TYPES_PACKAGE} rm --force --recursive ${EPISODIC_DIR}/gen-1 # generate the second episode mkdir --parents ${EPISODIC_DIR}/gen-2/second-episode ${THRIFT_COMPILER} -o ${EPISODIC_DIR}/gen-2/second-episode --gen js:node,ts,imports=${TYPES_PACKAGE} ${THRIFT_FILES_DIR}/Service.thrift if [ -f ${EPISODIC_DIR}/gen-2/second-episode/Types_types.js ]; then TESTOK=1 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 node ${DIR}/thrift_4987_xhr_protocol.test.mjs || TESTOK=1 # integration tests for type in tcp multiplex websocket http do for protocol in compact binary json do for transport in buffered framed do for gen_variant in es5 es6 esm do 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 done # episodic compilation test echo "Testing Episode Compilation" testEpisodicCompilation 'pure' 'pure' || TESTOK=1 testEpisodicCompilation 'base' 'base' || TESTOK=1 testEpisodicCompilation 'extend' 'extend' || TESTOK=1 testEpisodicCompilation 'extend' 'base' || TESTOK=1 testEpisodicCompilation 'base' 'pure' || TESTOK=1 if [ -n "${COVER}" ]; then ${ISTANBUL} report --dir "${DIR}/../coverage" --include "${DIR}/../coverage/report*/coverage.json" lcov cobertura html rm -r ${DIR}/../coverage/report*/* rmdir ${DIR}/../coverage/report* fi exit $TESTOK thrift-0.23.0/lib/nodejs/test/test_driver.mjs0000664000175000017500000002667615165535636021472 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * 'License'); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // This is the 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 from "tape"; import helpers from "./helpers.js"; import thrift from "thrift"; import Int64 from "node-int64"; import * as testCases from "./test-cases.mjs"; 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) { const checkRecursively = makeRecursiveCheck(assert); function makeAsserter(assertionFn) { return function (c) { const fnName = c[0]; const expected = c[1]; client[fnName](expected, function (err, actual) { assert.error(err, fnName + ": no callback error"); assertionFn(actual, expected, fnName); }); }; } testCases.simple.forEach( 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)), ); const arr = []; for (let i = 0; i < 256; ++i) { arr[i] = 255 - i; } let buf = new Buffer(arr); 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) { 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) { const expected = { 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) { assert.error(err, "testStruct: no callback error"); checkRecursively(testCases.out, response, "testStruct"); }); 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) { assert.error(err, "testInsanity: no callback error"); checkRecursively(testCases.insanity, response, "testInsanity"); }); 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) { assert.ok( err instanceof TException, "testException: correct error type", ); assert.ok(!response, "testException: no response"); }); client.testException("Xception", function (err, response) { assert.ok( err instanceof ttypes.Xception, "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", ); }); 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) { assert.error(err, "testOneway: no callback error"); assert.strictEqual(response, undefined, "testOneway: void 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); } }; export const ThriftTestDriverPromise = function (client, callback) { test("Promise Client Tests", function (assert) { const checkRecursively = makeRecursiveCheck(assert); function makeAsserter(assertionFn) { return function (c) { const fnName = c[0]; const expected = c[1]; client[fnName](expected) .then(function (actual) { assertionFn(actual, expected, fnName); }) .catch(() => assert.fail("fnName")); }; } testCases.simple.forEach( 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)), ); client .testStruct(testCases.out) .then(function (response) { checkRecursively(testCases.out, response, "testStruct"); }) .catch(() => assert.fail("testStruct")); client .testNest(testCases.out2) .then(function (response) { checkRecursively(testCases.out2, response, "testNest"); }) .catch(() => assert.fail("testNest")); client .testInsanity(testCases.crazy) .then(function (response) { checkRecursively(testCases.insanity, response, "testInsanity"); }) .catch(() => assert.fail("testInsanity")); client .testInsanity(testCases.crazy2) .then(function (response) { checkRecursively(testCases.insanity, response, "testInsanity2"); }) .catch(() => assert.fail("testInsanity2")); client .testException("TException") .then(function () { assert.fail("testException: TException"); }) .catch(function (err) { assert.ok(err instanceof TException); }); client .testException("Xception") .then(function () { assert.fail("testException: Xception"); }) .catch(function (err) { assert.ok(err instanceof ttypes.Xception); assert.equal(err.errorCode, 1001); assert.equal("Xception", err.message); }); client .testException("no Exception") .then(function (response) { assert.equal(undefined, response); //void }) .catch(() => assert.fail("testException")); client .testOneway(0) .then(function (response) { assert.strictEqual(response, undefined, "testOneway: void response"); }) .catch(() => assert.fail("testOneway: should not reject")); checkOffByOne(function (done) { client .testI32(-1) .then(function (response) { assert.equal(-1, response); assert.end(); done(); }) .catch(() => assert.fail("checkOffByOne")); }, callback); }); }; // Helper Functions // ========================================================= function makeRecursiveCheck(assert) { return function (map1, map2, msg) { const equal = checkRecursively(map1, map2); assert.ok(equal, msg); // deepEqual doesn't work with fields using node-int64 function checkRecursively(map1, map2) { if (typeof map1 !== "function" && typeof map2 !== "function") { 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 ) { const n = new Int64(map2.buffer); return map1 === n.toNumber(); } else { return map1 == map2; } } else { return Object.keys(map1).every(function (key) { return checkRecursively(map1[key], map2[key]); }); } } } }; } function checkOffByOne(done, callback) { const retry_limit = 30; const retry_interval = 100; let test_complete = false; let retrys = 0; /** * redo a simple test after the oneway to make sure we aren't "off by one" -- * if the server treated oneway void like normal void, this next test will * fail since it will get the void confirmation rather than the correct * result. In this circumstance, the client will throw the exception: * * 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 () { test_complete = true; }); //We wait up to retry_limit * retry_interval for the test suite to complete function TestForCompletion() { 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", ); } } } setTimeout(TestForCompletion, retry_interval); } function makeUnorderedDeepEqual(assert) { return function (actual, expected, name) { assert.equal(actual.length, expected.length, name); for (const k in actual) { let found = false; for (const k2 in expected) { if (actual[k] === expected[k2]) { found = true; } } if (!found) { assert.fail("Unexpected value " + actual[k] + " with key " + k); } } }; } thrift-0.23.0/lib/nodejs/test/exceptions.js0000664000175000017500000001154415165535636021130 0ustar00buildbuild00000000000000/* * 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. */ "use strict"; const test = require("tape"); const thrift = require("../lib/thrift/thrift.js"); 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", ); 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", ); assert.ok( e.stack.indexOf("test/exceptions.js:7:11") !== -1, "stack trace starts on correct line and column", ); assert.equal( e.name, "TApplicationException", "has function name TApplicationException", ); assert.equal(e.message, "foo", 'has error message "foo"'); assert.equal(e.type, 1, "has type 1"); assert.end(); }); test("unexpected TApplicationException ", function t(assert) { const e = new thrift.TApplicationException(1, 100); assert.ok( e instanceof thrift.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", ); assert.ok( e.stack.indexOf("test/exceptions.js:7:11") !== -1, "stack trace starts on correct line and column", ); assert.equal( e.name, "TApplicationException", "has function name TApplicationException", ); assert.equal(e.message, 100, "has error message 100"); assert.equal(e.type, 1, "has type 1"); assert.end(); }); test("TException", function t(assert) { const e = new thrift.TException("foo"); 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( /^TException: foo/.test(e.stack), "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", ); assert.equal(e.name, "TException", "has function name TException"); assert.equal(e.message, "foo", 'has error message "foo"'); assert.end(); }); test("TProtocolException", function t(assert) { const e = new thrift.TProtocolException(1, "foo"); assert.ok( e instanceof thrift.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", ); assert.ok( e.stack.indexOf("test/exceptions.js:33:11") !== -1, "stack trace starts on correct line and column", ); assert.equal( e.name, "TProtocolException", "has function name TProtocolException", ); assert.equal(e.message, "foo", 'has error message "foo"'); assert.equal(e.type, 1, "has type 1"); assert.end(); }); test("InputBufferUnderrunError", function t(assert) { const e = new InputBufferUnderrunError("foo"); assert.ok( e 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", ); assert.ok( e.stack.indexOf("test/exceptions.js:46:11") !== -1, "stack trace starts on correct line and column", ); assert.equal( e.name, "InputBufferUnderrunError", "has function name InputBufferUnderrunError", ); assert.equal(e.message, "foo", 'has error message "foo"'); assert.end(); }); thrift-0.23.0/lib/nodejs/test/client.mjs0000664000175000017500000001240615167543515020375 0ustar00buildbuild00000000000000#!/usr/bin/env node /* * 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 fs from "fs"; import path from "path"; import assert from "assert"; import thrift from "thrift"; import helpers from "./helpers.js"; 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}` ); import { program } from "commander"; program .option( "-p, --protocol ", "Set thrift protocol (binary|compact|json) [protocol]", ) .option( "-t, --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", ) .option("--ssl", "use SSL transport") .option("--callback", "test with callback style functions") .option( "--type ", "Select server type (http|multiplex|tcp|websocket)", "tcp", ) .option("--es6", "Use es6 code") .option("--es5", "Use es5 code") .option("--esm", "Use es modules") .parse(process.argv); 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 (opts.transport === "http") { opts.transport = "buffered"; type = "http"; } if (opts.transport === "websocket") { opts.transport = "buffered"; type = "websocket"; } const options = { transport: helpers.transports[opts.transport], protocol: helpers.protocols[opts.protocol], }; if (type === "http" || type === "websocket") { options.path = "/test"; } if (type === "http") { options.headers = { Connection: "close" }; } if (ssl) { if (type === "tcp" || type === "multiplex") { options.secureProtocol = "TLS_method"; options.secureOptions = 0; options.rejectUnauthorized = false; options.cert = fs.readFileSync( path.resolve(import.meta.dirname, "../../../test/keys/client.crt"), ); options.key = fs.readFileSync( path.resolve(import.meta.dirname, "../../../test/keys/client.key"), ); } else if (type === "http") { options.nodeOptions = { rejectUnauthorized: false }; options.https = true; } else if (type === "websocket") { options.wsOptions = { rejectUnauthorized: false }; options.secure = true; } } let connection; let client; const testDriver = opts.callback ? ThriftTestDriver : ThriftTestDriverPromise; if (helpers.ecmaMode === "es6" && opts.callback) { console.log("ES6 does not support callback style"); process.exit(0); } if (type === "tcp" || type === "multiplex") { if (domainSocket) { connection = thrift.createUDSConnection(domainSocket, options); } else { connection = ssl ? thrift.createSSLConnection(host, port, options) : thrift.createConnection(host, port, options); } } else if (type === "http") { if (domainSocket) { connection = thrift.createHttpUDSConnection(domainSocket, options); } else { connection = thrift.createHttpConnection(host, port, options); } } else if (type === "websocket") { connection = thrift.createWSConnection(host, port, options); connection.open(); } connection.on("error", function (err) { assert(false, err); }); if (type === "tcp") { client = thrift.createClient(ThriftTest, connection); runTests(); } else if (type === "multiplex") { const mp = new thrift.Multiplexer(); client = mp.createClient("ThriftTest", ThriftTest, connection); const secondclient = mp.createClient( "SecondService", SecondService, connection, ); connection.on("connect", function () { secondclient.secondtestString("Test", function (err, response) { assert(!err); assert.equal('testString("Test")', response); }); runTests(); }); } else if (type === "http") { client = thrift.createHttpClient(ThriftTest, connection); runTests(); } else if (type === "websocket") { client = thrift.createWSClient(ThriftTest, connection); runTests(); } function runTests() { testDriver(client, function (status) { console.log(status); if (type !== "http" && type !== "websocket") { connection.end(); } if (type !== "multiplex") { process.exit(0); } }); } export const expressoTest = function () {}; thrift-0.23.0/lib/nodejs/test/package.json0000664000175000017500000000007515165535636020674 0ustar00buildbuild00000000000000{ "devDependencies": { "thrift": "file:../../.." } } thrift-0.23.0/lib/nodejs/test/server.mjs0000664000175000017500000000756615167543515020440 0ustar00buildbuild00000000000000#!/usr/bin/env node /* * 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 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", ) .option( "-t, --transport ", "Set thrift transport (buffered|framed|http)", "buffered", ) .option("--ssl", "use ssl transport") .option("--port ", "Set thrift server port", 9090) .option("--domain-socket ", "Set thift server unix domain socket") .option( "--type ", "Select server type (http|multiplex|tcp|websocket)", "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 = 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 (opts.transport === "websocket") { opts.transport = "buffered"; type = "websocket"; } let options = { transport: helpers.transports[opts.transport], protocol: helpers.protocols[opts.protocol], }; if (type === "http" || type === "websocket") { options.handler = ThriftTestHandler; options.processor = ThriftTest; options = { services: { "/test": options }, cors: { "*": true, }, }; } let processor; if (type === "multiplex") { const SecondServiceHandler = { secondtestString: function (thing, result) { console.log('testString("' + thing + '")'); result(null, 'testString("' + thing + '")'); }, }; processor = new thrift.MultiplexedProcessor(); processor.registerProcessor( "ThriftTest", new ThriftTest.Processor(ThriftTestHandler), ); processor.registerProcessor( "SecondService", new SecondService.Processor(SecondServiceHandler), ); } if (ssl) { if ( type === "tcp" || type === "multiplex" || type === "http" || type === "websocket" ) { options.tls = { key: fs.readFileSync( path.resolve(import.meta.dirname, "../../../test/keys/server.key"), ), cert: fs.readFileSync( path.resolve(import.meta.dirname, "../../../test/keys/server.crt"), ), }; } } let server; if (type === "tcp") { server = thrift.createServer(ThriftTest, ThriftTestHandler, options); } else if (type === "multiplex") { server = thrift.createMultiplexServer(processor, options); } else if (type === "http" || type === "websocket") { server = thrift.createWebServer(options); } if (domainSocket) { server.listen(domainSocket); } else if ( type === "tcp" || type === "multiplex" || type === "http" || type === "websocket" ) { server.listen(port); } thrift-0.23.0/lib/nodejs/test/deep-constructor.test.js0000664000175000017500000002507115165535636023225 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const ttypes = require("./gen-nodejs/JsDeepConstructorTest_types"); const thrift = require("thrift"); const test = require("tape"); const bufferEquals = require("buffer-equals"); function serializeBinary(data) { let buff; const transport = new thrift.TBufferedTransport(null, function (msg) { buff = msg; }); const prot = new thrift.TBinaryProtocol(transport); data[Symbol.for("write")](prot); prot.flush(); return buff; } function deserializeBinary(serialized, type) { const t = new thrift.TFramedTransport(serialized); const p = new thrift.TBinaryProtocol(t); const data = new type(); data[Symbol.for("read")](p); return data; } function serializeJSON(data) { let buff; const transport = new thrift.TBufferedTransport(null, function (msg) { buff = msg; }); const protocol = new thrift.TJSONProtocol(transport); protocol.writeMessageBegin("", 0, 0); data[Symbol.for("write")](protocol); protocol.writeMessageEnd(); protocol.flush(); return buff; } function deserializeJSON(serialized, type) { const transport = new thrift.TFramedTransport(serialized); const protocol = new thrift.TJSONProtocol(transport); protocol.readMessageBegin(); const data = new type(); data[Symbol.for("read")](protocol); protocol.readMessageEnd(); return data; } function createThriftObj() { return new ttypes.Complex({ struct_field: new ttypes.Simple({ value: "a" }), struct_list_field: [ new ttypes.Simple({ value: "b" }), new ttypes.Simple({ value: "c" }), ], struct_set_field: [ new ttypes.Simple({ value: "d" }), new ttypes.Simple({ value: "e" }), ], struct_map_field: { A: new ttypes.Simple({ value: "f" }), B: new ttypes.Simple({ value: "g" }), }, struct_nested_containers_field: [ [ { C: [ new ttypes.Simple({ value: "h" }), new ttypes.Simple({ value: "i" }), ], }, ], ], struct_nested_containers_field2: { D: [ { DA: new ttypes.Simple({ value: "j" }), }, { DB: new ttypes.Simple({ value: "k" }), }, ], }, list_of_list_field: [ ["l00", "l01", "l02"], ["l10", "l11", "l12"], ["l20", "l21", "l22"], ], list_of_list_of_list_field: [ [ ["m000", "m001", "m002"], ["m010", "m011", "m012"], ["m020", "m021", "m022"], ], [ ["m100", "m101", "m102"], ["m110", "m111", "m112"], ["m120", "m121", "m122"], ], [ ["m200", "m201", "m202"], ["m210", "m211", "m212"], ["m220", "m221", "m222"], ], ], }); } function createJsObj() { return { struct_field: { value: "a" }, struct_list_field: [{ value: "b" }, { value: "c" }], struct_set_field: [{ value: "d" }, { value: "e" }], struct_map_field: { A: { value: "f" }, B: { value: "g" }, }, struct_nested_containers_field: [ [ { C: [{ value: "h" }, { value: "i" }], }, ], ], struct_nested_containers_field2: { D: [ { DA: { value: "j" }, }, { DB: { value: "k" }, }, ], }, list_of_list_field: [ ["l00", "l01", "l02"], ["l10", "l11", "l12"], ["l20", "l21", "l22"], ], list_of_list_of_list_field: [ [ ["m000", "m001", "m002"], ["m010", "m011", "m012"], ["m020", "m021", "m022"], ], [ ["m100", "m101", "m102"], ["m110", "m111", "m112"], ["m120", "m121", "m122"], ], [ ["m200", "m201", "m202"], ["m210", "m211", "m212"], ["m220", "m221", "m222"], ], ], }; } function assertValues(obj, assert) { assert.equals(obj.struct_field.value, "a"); assert.equals(obj.struct_list_field[0].value, "b"); assert.equals(obj.struct_list_field[1].value, "c"); assert.equals(obj.struct_set_field[0].value, "d"); assert.equals(obj.struct_set_field[1].value, "e"); assert.equals(obj.struct_map_field.A.value, "f"); assert.equals(obj.struct_map_field.B.value, "g"); assert.equals(obj.struct_nested_containers_field[0][0].C[0].value, "h"); assert.equals(obj.struct_nested_containers_field[0][0].C[1].value, "i"); assert.equals(obj.struct_nested_containers_field2.D[0].DA.value, "j"); assert.equals(obj.struct_nested_containers_field2.D[1].DB.value, "k"); assert.equals(obj.list_of_list_field[0][0], "l00"); assert.equals(obj.list_of_list_field[0][1], "l01"); assert.equals(obj.list_of_list_field[0][2], "l02"); assert.equals(obj.list_of_list_field[1][0], "l10"); assert.equals(obj.list_of_list_field[1][1], "l11"); assert.equals(obj.list_of_list_field[1][2], "l12"); assert.equals(obj.list_of_list_field[2][0], "l20"); assert.equals(obj.list_of_list_field[2][1], "l21"); assert.equals(obj.list_of_list_field[2][2], "l22"); assert.equals(obj.list_of_list_of_list_field[0][0][0], "m000"); assert.equals(obj.list_of_list_of_list_field[0][0][1], "m001"); assert.equals(obj.list_of_list_of_list_field[0][0][2], "m002"); assert.equals(obj.list_of_list_of_list_field[0][1][0], "m010"); assert.equals(obj.list_of_list_of_list_field[0][1][1], "m011"); assert.equals(obj.list_of_list_of_list_field[0][1][2], "m012"); assert.equals(obj.list_of_list_of_list_field[0][2][0], "m020"); assert.equals(obj.list_of_list_of_list_field[0][2][1], "m021"); assert.equals(obj.list_of_list_of_list_field[0][2][2], "m022"); assert.equals(obj.list_of_list_of_list_field[1][0][0], "m100"); assert.equals(obj.list_of_list_of_list_field[1][0][1], "m101"); assert.equals(obj.list_of_list_of_list_field[1][0][2], "m102"); assert.equals(obj.list_of_list_of_list_field[1][1][0], "m110"); assert.equals(obj.list_of_list_of_list_field[1][1][1], "m111"); assert.equals(obj.list_of_list_of_list_field[1][1][2], "m112"); assert.equals(obj.list_of_list_of_list_field[1][2][0], "m120"); assert.equals(obj.list_of_list_of_list_field[1][2][1], "m121"); assert.equals(obj.list_of_list_of_list_field[1][2][2], "m122"); assert.equals(obj.list_of_list_of_list_field[2][0][0], "m200"); assert.equals(obj.list_of_list_of_list_field[2][0][1], "m201"); assert.equals(obj.list_of_list_of_list_field[2][0][2], "m202"); assert.equals(obj.list_of_list_of_list_field[2][1][0], "m210"); assert.equals(obj.list_of_list_of_list_field[2][1][1], "m211"); assert.equals(obj.list_of_list_of_list_field[2][1][2], "m212"); assert.equals(obj.list_of_list_of_list_field[2][2][0], "m220"); assert.equals(obj.list_of_list_of_list_field[2][2][1], "m221"); assert.equals(obj.list_of_list_of_list_field[2][2][2], "m222"); } function createTestCases(serialize, deserialize) { const cases = { "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"); assert.deepEqual(tObj, received); 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) { 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, }); const received = deserialize(serialize(tObj), ttypes.Complex); assert.strictEqual(tObj.struct_field, null); assert.ok(tObj !== received); assert.deepEqual(tObj, received); assert.end(); }, "Can make list with objects": function (assert) { const tObj = new ttypes.ComplexList({ struct_list_field: [new ttypes.Complex({})], }); const innerObj = tObj.struct_list_field[0]; assert.ok(innerObj instanceof ttypes.Complex); assert.strictEqual(innerObj.struct_field, null); assert.strictEqual(innerObj.struct_list_field, null); assert.strictEqual(innerObj.struct_set_field, null); assert.strictEqual(innerObj.struct_map_field, null); 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) { test(name + ": " + caseName, cases[caseName]); }); } run("binary", createTestCases(serializeBinary, deserializeBinary)); run("json", createTestCases(serializeJSON, deserializeJSON)); thrift-0.23.0/lib/nodejs/test/include.test.mjs0000664000175000017500000000125615165535636021524 0ustar00buildbuild00000000000000import 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)); thrift-0.23.0/lib/nodejs/test/fuzz/0000775000175000017500000000000015167543515017377 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodejs/test/fuzz/fuzz_common.js0000664000175000017500000001042215167543515022302 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const FuzzTest = require("./gen-nodejs/FuzzTestNoUuid_types"); // const { FuzzedDataProvider } = require("@jazzer.js/core"); /** * Creates a parser fuzzer function for a specific protocol * @param {Function} protocolFactory - The Thrift protocol factory function * @param {boolean} [readMessageBegin=false] - Whether to call readMessageBegin before reading the test instance * This is needed for protocols that do not support parsing just a struct, such as TJSONProtocol. * @returns {Function} A fuzzer function that can be used with Jazzer.js */ function createParserFuzzer(protocolFactory, readMessageBegin = false) { return function fuzz(data) { if (data.length < 2) { return; } try { // Set up transport with input data const transport = new thrift.TFramedTransport(data); const protocol = protocolFactory(transport); const testInstance = new FuzzTest.FuzzTest(); if (readMessageBegin) { protocol.readMessageBegin(); } testInstance[Symbol.for("read")](protocol); } catch (e) { if ( !( e.name === "InputBufferUnderrunError" || e.name === "TProtocolException" ) ) { // TODO: Are other exceptions expected? // console.log(e); } } }; } /** * Creates a roundtrip fuzzer function for a specific protocol * @param {Function} protocolFactory - The Thrift protocol factory function * @param {boolean} [readMessageBegin=false] - Whether to call readMessageBegin before reading the test instance * This is needed for protocols that do not support parsing just a struct, such as TJSONProtocol. * @returns {Function} A fuzzer function that can be used with Jazzer.js */ function createRoundtripFuzzer(protocolFactory, readMessageBegin = false) { return function fuzz(data) { if (data.length < 2) { return; } try { // First deserialize using framed transport for input const transport1 = new thrift.TFramedTransport(data); const protocol1 = protocolFactory(transport1); const testInstance = new FuzzTest.FuzzTest(); if (readMessageBegin) { protocol1.readMessageBegin(); } testInstance[Symbol.for("read")](protocol1); // Then serialize using buffered transport with callback let serializedData; const transport2 = new thrift.TBufferedTransport(null, function (buf) { serializedData = buf; }); const protocol2 = protocolFactory(transport2); testInstance[Symbol.for("write")](protocol2); protocol2.flush(); if (!serializedData) { throw new Error("Serialization failed - no data produced"); } // Finally deserialize again and compare using framed transport const transport3 = new thrift.TFramedTransport(serializedData); const protocol3 = protocolFactory(transport3); const deserialized = new FuzzTest.FuzzTest(); if (readMessageBegin) { protocol3.readMessageBegin(); } deserialized[Symbol.for("read")](protocol3); // Compare the objects if (!testInstance.equals(deserialized)) { throw new Error("Roundtrip comparison failed"); } } catch (e) { if ( !( e.name === "InputBufferUnderrunError" || e.name === "TProtocolException" ) ) { // TODO: Are other exceptions expected? // console.log(e); } } }; } module.exports = { createParserFuzzer, createRoundtripFuzzer, }; thrift-0.23.0/lib/nodejs/test/fuzz/fuzz_parse_TJSONProtocol.js0000664000175000017500000000177515167543515024636 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const { createParserFuzzer } = require("./fuzz_common"); module.exports.fuzz = createParserFuzzer((transport) => { return new thrift.TJSONProtocol(transport); }, true); thrift-0.23.0/lib/nodejs/test/fuzz/fuzz_parse_TCompactProtocol.js0000664000175000017500000000177215167543515025450 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const { createParserFuzzer } = require("./fuzz_common"); module.exports.fuzz = createParserFuzzer((transport) => { return new thrift.TCompactProtocol(transport); }); thrift-0.23.0/lib/nodejs/test/fuzz/fuzz_roundtrip_TBinaryProtocol.js0000664000175000017500000000177715167543515026227 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const { createRoundtripFuzzer } = require("./fuzz_common"); module.exports.fuzz = createRoundtripFuzzer((transport) => { return new thrift.TBinaryProtocol(transport); }); thrift-0.23.0/lib/nodejs/test/fuzz/fuzz_parse_TBinaryProtocol.js0000664000175000017500000000177115167543515025305 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const { createParserFuzzer } = require("./fuzz_common"); module.exports.fuzz = createParserFuzzer((transport) => { return new thrift.TBinaryProtocol(transport); }); thrift-0.23.0/lib/nodejs/test/fuzz/fuzz_roundtrip_TJSONProtocol.js0000664000175000017500000000200315167543515025533 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const { createRoundtripFuzzer } = require("./fuzz_common"); module.exports.fuzz = createRoundtripFuzzer((transport) => { return new thrift.TJSONProtocol(transport); }, true); thrift-0.23.0/lib/nodejs/test/fuzz/README.md0000664000175000017500000000373615165535636020672 0ustar00buildbuild00000000000000# Node.js Fuzzing README The Node.js Thrift implementation uses Jazzer.js for fuzzing. Jazzer.js is a coverage-guided, in-process fuzzer for JavaScript that integrates with libFuzzer. ## Setup 1. Install Jazzer.js: ```bash npm install --save-dev @jazzer.js/core ``` ## Available Fuzzers The Node.js Thrift implementation currently supports the following fuzz targets: * `fuzz_parse_TJSONProtocol.js` - fuzzes the deserialization of the JSON protocol * `fuzz_roundtrip_TJSONProtocol.js` - fuzzes the roundtrip of the JSON protocol (serialize -> deserialize -> compare) * `fuzz_parse_TBinaryProtocol.js` - fuzzes the deserialization of the Binary protocol * `fuzz_roundtrip_TBinaryProtocol.js` - fuzzes the roundtrip of the Binary protocol * `fuzz_parse_TCompactProtocol.js` - fuzzes the deserialization of the Compact protocol * `fuzz_roundtrip_TCompactProtocol.js` - fuzzes the roundtrip of the Compact protocol ## Running Fuzzers To run a fuzzer, use the Jazzer.js CLI: ```bash npx jazzer ./fuzz_parse_TJSONProtocol.js --corpus=./corpus ``` Where: - `--corpus` points to a directory containing seed inputs (optional) ## Corpus Generation You can use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these Node.js fuzzers. For JSON protocol fuzzers, ensure the corpus contains valid JSON data. ## Adding New Fuzzers To add a new fuzzer: 1. Create a new file in the `fuzz` directory 2. Import the appropriate helper functions from `fuzz_common.js` 3. Export a `fuzz` function that takes a Buffer parameter 4. Use either `createParserFuzzer` or `createRoundtripFuzzer` with the appropriate protocol factory Example: ```javascript const { createParserFuzzer } = require('./fuzz_common'); module.exports.fuzz = createParserFuzzer((transport) => { return new thrift.TJSONProtocol(transport); }); ``` For more information about Jazzer.js and its options, see the [Jazzer.js documentation](https://github.com/CodeIntelligenceTesting/jazzer.js). thrift-0.23.0/lib/nodejs/test/fuzz/fuzz_roundtrip_TCompactProtocol.js0000664000175000017500000000200015167543515026345 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const { createRoundtripFuzzer } = require("./fuzz_common"); module.exports.fuzz = createRoundtripFuzzer((transport) => { return new thrift.TCompactProtocol(transport); }); thrift-0.23.0/lib/nodejs/test/test_handler.mjs0000664000175000017500000001251515167543515021574 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * 'License'); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ //This is the server side Node test handler for the standard // Apache Thrift test service. 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 thing; }; } const syncHandlers = { testVoid: testVoid, testMapMap: testMapMap, testInsanity: testInsanity, testMulti: testMulti, testException: testException, testMultiException: testMultiException, testOneway: testOneway, }; function makeAsyncHandler(label) { return function (thing, result) { thing = syncHandlers[label](thing); result(null, thing); }; } const asyncHandlers = { testVoid: testVoidAsync, testMulti: testMultiAsync, testException: testExceptionAsync, testMultiException: testMultiExceptionAsync, testOneway: testOnewayAsync, }; const identityHandlers = [ "testString", "testBool", "testByte", "testI32", "testI64", "testDouble", "testBinary", "testUuid", "testStruct", "testNest", "testMap", "testStringMap", "testSet", "testList", "testEnum", "testTypedef", ]; function testVoid() { //console.log('testVoid()'); } function testVoidAsync(result) { result(testVoid()); } function testMapMap() { const mapmap = []; const pos = []; const neg = []; for (let i = 1; i < 5; i++) { pos[i] = i; neg[-i] = -i; } mapmap[4] = pos; mapmap[-4] = neg; return mapmap; } function testInsanity(argument) { //console.log('testInsanity('); //console.log(argument); //console.log(')'); const first_map = []; const second_map = []; 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 = []; insane[1] = first_map; insane[2] = second_map; //console.log('insane result:'); //console.log(insane); return insane; } function testMulti(arg0, arg1, arg2) { //console.log('testMulti()'); const hello = new ttypes.Xtruct(); hello.string_thing = "Hello2"; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = arg2; return hello; } function testMultiAsync(arg0, arg1, arg2, arg3, arg4, arg5, result) { const hello = testMulti(arg0, arg1, arg2, arg3, arg4, arg5); result(null, hello); } function testException(arg) { //console.log('testException('+arg+')'); if (arg === "Xception") { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; throw x; } else if (arg === "TException") { throw new TException(arg); } else { return; } } function testExceptionAsync(arg, result) { //console.log('testException('+arg+')'); if (arg === "Xception") { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; result(x); } else if (arg === "TException") { result(new TException(arg)); } else { result(null); } } function testMultiException(arg0, arg1) { //console.log('testMultiException(' + arg0 + ', ' + arg1 + ')'); if (arg0 === "Xception") { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = "This is an Xception"; throw x; } else if (arg0 === "Xception2") { const x2 = new ttypes.Xception2(); x2.errorCode = 2002; x2.struct_thing = new ttypes.Xtruct(); x2.struct_thing.string_thing = "This is an Xception2"; throw x2; } const res = new ttypes.Xtruct(); res.string_thing = arg1; return res; } function testMultiExceptionAsync(arg0, arg1, result) { //console.log('testMultiException(' + arg0 + ', ' + arg1 + ')'); if (arg0 === "Xception") { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = "This is an Xception"; result(x); } else if (arg0 === "Xception2") { const x2 = new ttypes.Xception2(); x2.errorCode = 2002; x2.struct_thing = new ttypes.Xtruct(); x2.struct_thing.string_thing = "This is an Xception2"; result(x2); } else { const res = new ttypes.Xtruct(); res.string_thing = arg1; result(null, res); } } //console.log('testOneway(' + sleepFor + ') => JavaScript (like Rust) never sleeps!'); function testOneway() {} function testOnewayAsync(sleepFor) { testOneway(sleepFor); } identityHandlers.forEach(function (label) { syncHandlers[label] = makeSyncHandler(label); asyncHandlers[label] = makeAsyncHandler(label); }); ["testMapMap", "testInsanity"].forEach(function (label) { asyncHandlers[label] = makeAsyncHandler(label); }); export { asyncHandlers as ThriftTestHandler }; thrift-0.23.0/lib/nodejs/test/package-lock.json0000664000175000017500000000244315167543515021620 0ustar00buildbuild00000000000000{ "name": "test", "lockfileVersion": 3, "requires": true, "packages": { "": { "devDependencies": { "thrift": "file:../../.." } }, "../../..": { "name": "thrift", "version": "0.23.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", "uuid": "^13.0.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 } } } thrift-0.23.0/lib/nodejs/test/int64.test.js0000664000175000017500000000654515165535636020676 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const Int64 = require("node-int64"); const JSONInt64 = require("json-int64"); const i64types = require("./gen-nodejs-es6/Int64Test_types.js"); const test = require("tape"); const cases = { "should correctly generate Int64 constants": function (assert) { const EXPECTED_SMALL_INT64_AS_NUMBER = 42; const EXPECTED_SMALL_INT64 = new Int64(42); const EXPECTED_MAX_JS_SAFE_INT64 = new Int64(Number.MAX_SAFE_INTEGER); const EXPECTED_MIN_JS_SAFE_INT64 = new Int64(Number.MIN_SAFE_INTEGER); const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64 = new Int64("0020000000000000"); // hex-encoded const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64 = new Int64("ffe0000000000000"); // hex-encoded 2's complement const EXPECTED_MAX_SIGNED_INT64 = new Int64("7fffffffffffffff"); // hex-encoded const EXPECTED_MIN_SIGNED_INT64 = new Int64("8000000000000000"); // hex-encoded 2's complement const EXPECTED_INT64_LIST = [ EXPECTED_SMALL_INT64, EXPECTED_MAX_JS_SAFE_INT64, EXPECTED_MIN_JS_SAFE_INT64, EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64, EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64, EXPECTED_MAX_SIGNED_INT64, EXPECTED_MIN_SIGNED_INT64, ]; assert.ok(EXPECTED_SMALL_INT64.equals(i64types.SMALL_INT64)); assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(i64types.MAX_JS_SAFE_INT64)); assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(i64types.MIN_JS_SAFE_INT64)); assert.ok( EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals( i64types.MAX_JS_SAFE_PLUS_ONE_INT64, ), ); assert.ok( EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals( i64types.MIN_JS_SAFE_MINUS_ONE_INT64, ), ); assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(i64types.MAX_SIGNED_INT64)); assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(i64types.MIN_SIGNED_INT64)); assert.equal( EXPECTED_SMALL_INT64_AS_NUMBER, i64types.SMALL_INT64.toNumber(), ); assert.equal( Number.MAX_SAFE_INTEGER, i64types.MAX_JS_SAFE_INT64.toNumber(), ); assert.equal( Number.MIN_SAFE_INTEGER, i64types.MIN_JS_SAFE_INT64.toNumber(), ); for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { assert.ok(EXPECTED_INT64_LIST[i].equals(i64types.INT64_LIST[i])); } for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { const int64Object = EXPECTED_INT64_LIST[i]; assert.ok( i64types.INT64_2_INT64_MAP[ JSONInt64.toDecimalString(int64Object) ].equals(int64Object), ); } assert.end(); }, }; Object.keys(cases).forEach(function (caseName) { test(caseName, cases[caseName]); }); thrift-0.23.0/lib/nodejs/test/thrift_4987_xhr_protocol.test.mjs0000664000175000017500000006607615167543515024706 0ustar00buildbuild00000000000000#!/usr/bin/env node /** * 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. */ /** * Regression test for THRIFT-4987: * "TProtocolException: Bad version in readMessageBegin when using XHR * client with binary protocol against a C++ server" * * Disclaimer: This file, except for this disclaimer, was written entirely by * Claude. Claude needed a lot of guidance on getting to this solution to test * the actual code in question which lead to finding an issue in the previous * proposed solution and it was subsequently fixed. The Claude output was fixed * using eslint. * * ───────────────────────────────────────────────────────────────────────── * BUG ANATOMY * ───────────────────────────────────────────────────────────────────────── * File: lib/nodejs/lib/thrift/xhr_connection.js * * XHRConnection.flush() (line 103–121) builds an XMLHttpRequest and fires * it. The onreadystatechange handler reads the server reply as: * * self.setRecvBuffer(this.responseText); // line 117 — THE BUG * * setRecvBuffer() (line 134) then does: * * if ([object ArrayBuffer]) { data = new Uint8Array(buf); } // line 140 * var thing = new Buffer(data || buf); // line 143 * * When `buf` is a string (which it always is from line 117), the ArrayBuffer * guard on line 140 is never reached — it is dead code. `new Buffer(string)` * encodes the string as UTF-8: any character with code point 0x80–0xFF * becomes a 2-byte UTF-8 sequence, inflating the buffer and shifting all * subsequent byte positions. * * TBinaryProtocol and TCompactProtocol both start their REPLY messages with * a byte >= 0x80 (the protocol identifier / version word), so after the * corruption the first readI32/readByte reads a garbage value and throws * TProtocolException. * * TJSONProtocol is NOT affected because its wire format is pure 7-bit ASCII * — the Latin-1→UTF-8 round-trip is a no-op for bytes <= 0x7F. This is * why xhr_connection.js defaulting to TJSONProtocol masked the bug for years. * * THE FIX (two lines in XHRConnection.flush()): * xreq.responseType = 'arraybuffer'; // BEFORE xreq.open() — line ~105 * self.setRecvBuffer(this.response); // not this.responseText — line 117 * * With responseType='arraybuffer', this.response is an ArrayBuffer, the * guard on line 140 fires, and new Buffer(Uint8Array) copies bytes verbatim. * * ───────────────────────────────────────────────────────────────────────── * TEST APPROACH * ───────────────────────────────────────────────────────────────────────── * We exercise XHRConnection.flush() and XHRConnection.setRecvBuffer() * directly by replacing getXmlHttpRequestObject() with a MockXHR. * * MockXHR: * - holds both responseText (Latin-1 string of the raw bytes) and * response (actual ArrayBuffer of the raw bytes) pre-loaded from * the raw wire-level REPLY buffer produced by the server protocol * - its send() method fires onreadystatechange immediately, using * whichever property flush() selected (responseType decides this): * responseType === 'arraybuffer' → delivers this.response (ArrayBuffer) * responseType === '' → delivers this.responseText (string) * * We also supply a minimal stub Thrift client attached to the connection * (connection.client) so that __decodeCallback can look up recv_testI32. * That stub captures the decoded result or error so the test can assert on it. * * Three scenarios per protocol: * A reproduceIssue=true — _brokenFlush() active: * verbatim copy of the unpatched XHRConnection.flush(), which uses * responseText with no responseType set → new Buffer(string) → UTF-8 * inflation → TProtocolException thrown from __decodeCallback * * B reproduceIssue=false — real XHRConnection.prototype.flush() called: * no flush() override on the instance; the library's own flush() runs. * Once the fix (responseType='arraybuffer' + this.response) is applied * to the library, this path produces a clean decode. If the library is * still unpatched, this path fails too — making the regression visible. * * ───────────────────────────────────────────────────────────────────────── * RUNNING (standalone, no server needed) * ───────────────────────────────────────────────────────────────────────── * cd /test/nodejs * npm install thrift * node thrift_4987_xhr_protocol.test.mjs * * ───────────────────────────────────────────────────────────────────────── * WIRING INTO THE CROSS-LANGUAGE MAKE TARGET * ───────────────────────────────────────────────────────────────────────── * In test/nodejs/Makefile.am, add alongside the existing client.mjs target: * * check-THRIFT-4987: * $(NODE) thrift_4987_xhr_protocol.test.mjs && echo "THRIFT-4987 PASS" * * No server is required; the test is entirely self-contained. */ import { createRequire } from "module"; const require = createRequire(import.meta.url); const thrift = require("thrift"); const XHRConnection = require("thrift/lib/nodejs/lib/thrift/xhr_connection").XHRConnection; const TBufferedTransport = require("thrift/lib/nodejs/lib/thrift/buffered_transport"); const TBinaryProtocol = require("thrift/lib/nodejs/lib/thrift/binary_protocol"); const TCompactProtocol = require("thrift/lib/nodejs/lib/thrift/compact_protocol"); const TJSONProtocol = require("thrift/lib/nodejs/lib/thrift/json_protocol"); const { Thrift } = thrift; const GREEN = (s) => `\x1b[32m${s}\x1b[0m`; const RED = (s) => `\x1b[31m${s}\x1b[0m`; const BOLD = (s) => `\x1b[1m${s}\x1b[0m`; const DIM = (s) => `\x1b[2m${s}\x1b[0m`; // ───────────────────────────────────────────────────────────────────────────── // Encode a server-side TBinaryProtocol / TCompactProtocol / TJSONProtocol // REPLY for testI32(42). This is the raw buffer the server would send over // HTTP; what arrives at the browser depends on how XHR decodes the body. // ───────────────────────────────────────────────────────────────────────────── function encodeServerReply(ProtoClass, methodName, seqId, i32Value) { let encoded = null; const t = new TBufferedTransport(null, (buf) => { encoded = buf; }); const p = new ProtoClass(t); p.writeMessageBegin(methodName, Thrift.MessageType.REPLY, seqId); p.writeStructBegin("testI32_result"); p.writeFieldBegin("success", Thrift.Type.I32, 0); p.writeI32(i32Value); p.writeFieldEnd(); p.writeFieldStop(); p.writeStructEnd(); p.writeMessageEnd(); t.flush(); if (!encoded) throw new Error("TBufferedTransport did not flush"); return encoded; } // ───────────────────────────────────────────────────────────────────────────── // MockXHR — drop-in replacement for the browser XMLHttpRequest object. // // Holds two representations of the raw server reply: // responseText — Latin-1 string (charCode === byte value), as a browser // delivers when Content-Type has no charset or charset=latin-1 // response — actual ArrayBuffer of the raw bytes, as a browser delivers // when xreq.responseType = 'arraybuffer' // // send() fires onreadystatechange synchronously (simulating a completed XHR). // It inspects this.responseType (set by flush() before open() in the fix) to // decide which property to hand back, exactly mirroring browser behaviour. // ───────────────────────────────────────────────────────────────────────────── class MockXHR { constructor(rawBuf) { this.readyState = 0; this.status = 0; this.responseType = ""; // flush() writes this; send() reads it back // responseText: browser Latin-1 decoding of the raw HTTP body bytes. // Each byte value maps 1:1 to a character code point. let latin1 = ""; for (let i = 0; i < rawBuf.length; i++) latin1 += String.fromCharCode(rawBuf[i]); this.responseText = latin1; // response: ArrayBuffer view of the same raw bytes (responseType='arraybuffer'). const ab = new ArrayBuffer(rawBuf.length); new Uint8Array(ab).set(rawBuf); this.response = ab; } overrideMimeType() {} open() { this.readyState = 1; } setRequestHeader() {} send() { this.readyState = 4; this.status = 200; // Mirror browser: deliver response vs responseText based on responseType. // This is the decision point under test: // - responseType === '' → this.responseText is a string → bug path // - responseType === 'arraybuffer' → this.response is an ArrayBuffer → fix path if (this.responseType === "arraybuffer") { // Temporarily shadow responseText so setRecvBuffer can only get the ArrayBuffer const savedText = this.responseText; this.responseText = null; this.onreadystatechange(); this.responseText = savedText; } else { // Temporarily shadow response so setRecvBuffer can only get the string const savedResponse = this.response; this.response = null; this.onreadystatechange(); this.response = savedResponse; } } } // ───────────────────────────────────────────────────────────────────────────── // TestableXHRConnection — subclass of XHRConnection that injects MockXHR. // // getXmlHttpRequestObject() is always overridden so the real network is never // touched; MockXHR pre-loads the raw server reply and fires onreadystatechange // synchronously when send() is called. // // reproduceIssue (boolean): // true — also overrides flush() with the original broken implementation // (responseText, no responseType) to confirm the bug is present in // the unpatched code path. _brokenFlush() is a verbatim copy of // the buggy XHRConnection.flush() so the test documents exactly // what is wrong. // // false — does NOT override flush(); the real XHRConnection.flush() from // the library is called as-is. Once the fix is applied to the // library, this path must produce a clean decode. If flush() is // still broken in the library, this path will also fail — which // is precisely the point of the regression test. // ───────────────────────────────────────────────────────────────────────────── class TestableXHRConnection extends XHRConnection { constructor(rawReplyBuf, options, reproduceIssue) { // XHRConnection constructor accesses window.location when host/port are // omitted; supply dummy values to prevent that reference error in Node.js. super("localhost", 9090, options); this._rawReplyBuf = rawReplyBuf; this._reproduceIssue = reproduceIssue; // Bind the broken flush onto this instance only when reproducing the bug. // This leaves the prototype chain untouched so the fixed path genuinely // calls XHRConnection.prototype.flush with no override in the way. if (reproduceIssue) { this.flush = this._brokenFlush.bind(this); } // When reproduceIssue is false, flush is not set here, so this.flush // resolves to XHRConnection.prototype.flush — the real library code. } getXmlHttpRequestObject() { return new MockXHR(this._rawReplyBuf); } // Verbatim copy of the buggy XHRConnection.flush() (xhr_connection.js // lines 103-127) before the fix was applied. // Used only when reproduceIssue=true. // The two lines that constitute the fix are deliberately absent: // MISSING: xreq.responseType = 'arraybuffer'; // MISSING: self.setRecvBuffer(this.response); (uses responseText instead) /* eslint-disable */ _brokenFlush() { var self = this; if (this.url === undefined || this.url === "") { return this.send_buf; } var xreq = this.getXmlHttpRequestObject(); if (xreq.overrideMimeType) { xreq.overrideMimeType("application/json"); } xreq.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { self.setRecvBuffer(this.responseText); } }; xreq.open("POST", this.url, true); Object.keys(this.headers).forEach(function (headerKey) { xreq.setRequestHeader(headerKey, self.headers[headerKey]); }); xreq.send(this.send_buf); } /* eslint-enable */ } // ───────────────────────────────────────────────────────────────────────────── // Minimal stub Thrift client. // // XHRConnection.__decodeCallback() calls: // client._reqs[dummy_seqid] = function(err, success) { ... } // client['recv_' + header.fname](proto, header.mtype, dummy_seqid) // // The real generated client's recv_testI32 reads the i32 from the protocol // and invokes the callback stored in _reqs[seqid]. We supply a lightweight // version that captures the result so the test can assert on it. // ───────────────────────────────────────────────────────────────────────────── function makeStubClient(ProtoClass, seqId, onResult) { return { _reqs: { // The real seqid callback — called by our recv_ after it reads the value [seqId]: (err, val) => onResult(err, val), }, recv_testI32(proto) { // Mirrors what the generated client recv_ method does: // read the success field from the REPLY struct, then invoke callback let result = null; proto.readStructBegin(); while (true) { const field = proto.readFieldBegin(); if (field.ftype === Thrift.Type.STOP) break; if (field.fid === 0 && field.ftype === Thrift.Type.I32) { result = proto.readI32(); } else { proto.skip(field.ftype); } proto.readFieldEnd(); } proto.readStructEnd(); proto.readMessageEnd(); // Invoke the callback registered by __decodeCallback under dummy_seqid const dummy_seqid = seqId * -1; const cb = this._reqs[dummy_seqid]; if (cb) cb(null, result); }, }; } // ───────────────────────────────────────────────────────────────────────────── // Run one scenario against a real XHRConnection.flush() call. // // Flow: // 1. Build raw server REPLY buffer (what the server would write on the wire) // 2. Create a TestableXHRConnection with a MockXHR pre-loaded with that buffer // 3. Attach a stub client with a recv_testI32 and a seqid callback // 4. Write the encoded client REQUEST into the connection's send buffer, // then call flush() — this is either _brokenFlush() (reproduceIssue=true) // or the real XHRConnection.prototype.flush() (reproduceIssue=false) // 5. MockXHR.send() fires onreadystatechange synchronously; depending on // whether responseType='arraybuffer' was set by flush(), it delivers // either this.response (ArrayBuffer) or this.responseText (string) // 6. setRecvBuffer() → transport.receiver() → __decodeCallback() // → proto.readMessageBegin() → recv_testI32 (success) or throw (bug) // ───────────────────────────────────────────────────────────────────────────── async function runScenario(ProtoClass, reproduceIssue) { const METHOD = "testI32", SEQ_ID = 1, VALUE = 42; // The raw buffer the server sends on the wire const rawReplyBuf = encodeServerReply(ProtoClass, METHOD, SEQ_ID, VALUE); return new Promise((resolve) => { let settled = false; const done = (err, val) => { if (!settled) { settled = true; resolve({ err, val }); } }; const conn = new TestableXHRConnection( rawReplyBuf, { transport: TBufferedTransport, protocol: ProtoClass }, reproduceIssue, ); // Listen for errors emitted by the connection on non-protocol failures. // NOTE: __decodeCallback in xhr_connection.js throws TProtocolException // directly (it does not call self.emit('error')), so protocol errors are // caught via the try/catch around conn.flush() below, not here. conn.on("error", (e) => done(e, null)); // Attach the stub client conn.client = makeStubClient(ProtoClass, SEQ_ID, done); // Encode a minimal client-side REQUEST (just enough to have a send_buf // so flush() proceeds past the early-return guard). // We write directly to the underlying transport the same way createClient does. const writeCb = (buf) => { conn.send_buf = buf; }; const sendTransport = new TBufferedTransport(undefined, writeCb); sendTransport.setCurrSeqId(SEQ_ID); const sendProto = new ProtoClass(sendTransport); sendProto.writeMessageBegin(METHOD, Thrift.MessageType.CALL, SEQ_ID); sendProto.writeStructBegin("testI32_args"); sendProto.writeFieldBegin("thing", Thrift.Type.I32, 1); sendProto.writeI32(VALUE); sendProto.writeFieldEnd(); sendProto.writeFieldStop(); sendProto.writeStructEnd(); sendProto.writeMessageEnd(); sendTransport.flush(); // populates conn.send_buf via writeCb // Now fire the actual XHRConnection.flush(). // NOTE: XHRConnection.__decodeCallback() re-throws TProtocolException // directly (line 199 of xhr_connection.js) rather than emitting 'error' // as http_connection.js does. The throw propagates synchronously back // through setRecvBuffer → MockXHR.send() → flush() so we catch it here. try { conn.flush(); } catch (e) { done(e, null); } // Guard: if neither the error event nor the recv_ callback fired // synchronously (nor a thrown exception), the mock wiring is broken. if (!settled) done( new Error("Neither result nor error received — check MockXHR wiring"), null, ); }); } // ───────────────────────────────────────────────────────────────────────────── // Protocol table // ───────────────────────────────────────────────────────────────────────────── const PROTOCOLS = [ { name: "TBinaryProtocol", Class: TBinaryProtocol, affected: true, // Version word first byte: 0x80 → inflates to 0xC2 0x80 via UTF-8 symptom: "Bad version in readMessageBegin", }, { name: "TCompactProtocol", Class: TCompactProtocol, affected: true, // PROTOCOL_ID first byte: 0x82 → inflates to 0xC2 0x82 via UTF-8 symptom: "Bad protocol identifier", }, { name: "TJSONProtocol", Class: TJSONProtocol, affected: false, // Wire format is pure 7-bit ASCII — no bytes >= 0x80, no inflation symptom: null, }, ]; // ───────────────────────────────────────────────────────────────────────────── // Main // ───────────────────────────────────────────────────────────────────────────── async function main() { console.log( BOLD( "\nTHRIFT-4987 — XHRConnection.flush() + setRecvBuffer() regression test", ), ); console.log( DIM("Exercises real XHRConnection code paths via MockXHR injection\n"), ); let totalPass = 0, totalFail = 0; const summary = []; for (const proto of PROTOCOLS) { console.log(BOLD(`${"─".repeat(68)}`)); console.log( BOLD( ` ${proto.name} ${proto.affected ? RED("(AFFECTED)") : GREEN("(NOT AFFECTED)")}`, ), ); console.log(BOLD(`${"─".repeat(68)}`)); console.log( ` ${DIM( proto.affected ? `First wire byte >= 0x80 → inflates under UTF-8 → corrupt → "${proto.symptom}"` : "Wire format is 7-bit ASCII → Latin-1→UTF-8 round-trip is a no-op", )}\n`, ); let scenPass = 0, scenFail = 0; // ── Scenario A: BUG path — _brokenFlush() active (reproduceIssue=true) ── { const { err, val } = await runScenario(proto.Class, true); process.stdout.write( ` Scenario A ${DIM("reproduceIssue=true — _brokenFlush() (responseText, no responseType)")}:\n`, ); if (proto.affected) { // Expect an error containing the known symptom string if (err && err.message && err.message.includes(proto.symptom)) { console.log( GREEN( ` ✓ PASS — XHRConnection emitted error: ${err.constructor.name}: ${err.message}`, ), ); scenPass++; } else if (err) { console.log( RED( ` ✗ FAIL — got error but wrong message: ${err.constructor.name}: ${err.message}`, ), ); scenFail++; } else { console.log( RED( ` ✗ FAIL — expected error "${proto.symptom}" but got val=${val}`, ), ); scenFail++; } } else { // JSON: not affected, should decode cleanly on bug path too if (!err && val === 42) { console.log( GREEN( ` ✓ PASS — decoded correctly (JSON is immune): val=${val}`, ), ); scenPass++; } else if (err) { console.log( RED( ` ✗ FAIL — unexpected error: ${err.constructor.name}: ${err.message}`, ), ); scenFail++; } else { console.log(RED(` ✗ FAIL — unexpected val=${val}`)); scenFail++; } } } // ── Scenario B: FIX path — real XHRConnection.flush() (reproduceIssue=false) ── { const { err, val } = await runScenario(proto.Class, false); process.stdout.write( ` Scenario B ${DIM("reproduceIssue=false — real XHRConnection.prototype.flush() from library")}:\n`, ); if (!err && val === 42) { console.log(GREEN(` ✓ PASS — decoded correctly: val=${val}`)); scenPass++; } else if (err) { console.log( RED( ` ✗ FAIL — unexpected error on fix path: ${err.constructor.name}: ${err.message}`, ), ); scenFail++; } else { console.log(RED(` ✗ FAIL — wrong value: val=${val}`)); scenFail++; } } totalPass += scenPass; totalFail += scenFail; const status = scenFail === 0 ? GREEN("PASS") : RED("FAIL"); summary.push({ name: proto.name, affected: proto.affected, scenPass, scenFail, status, }); console.log(); } // ── Summary ──────────────────────────────────────────────────────────────── console.log(BOLD(`${"â•".repeat(68)}`)); console.log(BOLD(" SUMMARY")); console.log(BOLD(`${"â•".repeat(68)}`)); console.log( ` ${"Protocol".padEnd(22)} ${"Affected".padEnd(14)} ${"Scenarios".padEnd(14)} Result`, ); console.log(` ${"─".repeat(64)}`); for (const r of summary) { const aff = r.affected ? RED("YES") : GREEN("NO"); const sc = `${r.scenPass}/${r.scenPass + r.scenFail} passed`; console.log( ` ${r.name.padEnd(22)} ${aff.padEnd(22)} ${sc.padEnd(14)} ${r.status}`, ); } console.log(BOLD(`${"â•".repeat(68)}`)); console.log(`\n Total: ${totalPass} passed, ${totalFail} failed\n`); if (totalFail > 0) { console.log( RED(" REGRESSION: unexpected scenario result(s) — see above.\n"), ); process.exit(1); } else { console.log(GREEN(" All scenarios passed.")); console.log( " TBinaryProtocol and TCompactProtocol fail on the bug path (scenario A)", ); console.log( " and pass on the fix path (scenario B, real XHRConnection.prototype.flush).", ); console.log( " TJSONProtocol passes on both paths (immune due to 7-bit ASCII wire format).\n", ); } } main().catch((e) => { console.error(e); process.exit(1); }); thrift-0.23.0/lib/nodejs/test/binary.test.js0000664000175000017500000001452215165535636021210 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const test = require("tape"); const binary = require("thrift/lib/nodejs/lib/thrift/binary"); const cases = { "Should read signed byte": function (assert) { assert.equal(1, binary.readByte(0x01)); assert.equal(-1, binary.readByte(0xff)); assert.equal(127, binary.readByte(0x7f)); assert.equal(-128, binary.readByte(0x80)); assert.end(); }, "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) { assert.equal(0, binary.readI16([0x00, 0x00])); assert.equal(1, binary.readI16([0x00, 0x01])); assert.equal(-1, binary.readI16([0xff, 0xff])); // Min I16 assert.equal(-32768, binary.readI16([0x80, 0x00])); // Max I16 assert.equal(32767, binary.readI16([0x7f, 0xff])); assert.end(); }, "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)); // Min I16 assert.deepEqual([0x80, 0x00], binary.writeI16([], -32768)); // Max I16 assert.deepEqual([0x7f, 0xff], binary.writeI16([], 32767)); assert.end(); }, "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])); // Min I32 assert.equal(-2147483648, binary.readI32([0x80, 0x00, 0x00, 0x00])); // Max I32 assert.equal(2147483647, binary.readI32([0x7f, 0xff, 0xff, 0xff])); assert.end(); }, "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)); // Min I32 assert.deepEqual( [0x80, 0x00, 0x00, 0x00], binary.writeI32([], -2147483648), ); // Max I32 assert.deepEqual([0x7f, 0xff, 0xff, 0xff], binary.writeI32([], 2147483647)); assert.end(); }, "Should read doubles": function (assert) { assert.equal( 0, binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( 0, binary.readDouble([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( 1, binary.readDouble([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( 2, binary.readDouble([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( -2, binary.readDouble([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( Math.PI, binary.readDouble([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18]), ); assert.equal( Infinity, binary.readDouble([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.equal( -Infinity, binary.readDouble([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), ); assert.ok( 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]), ); // Min subnormal positive double assert.equal( 4.9406564584124654e-324, 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]), ); // Max positive double assert.equal( 1.7976931348623157e308, binary.readDouble([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), ); assert.end(); }, "Should write doubles": function (assert) { assert.deepEqual( [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 0), ); assert.deepEqual( [0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 1), ); assert.deepEqual( [0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2), ); assert.deepEqual( [0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -2), ); assert.deepEqual( [0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18], binary.writeDouble([], Math.PI), ); assert.deepEqual( [0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], Infinity), ); assert.deepEqual( [0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -Infinity), ); assert.deepEqual( [0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], NaN), ); assert.deepEqual( [0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55], binary.writeDouble([], 1 / 3), ); // Min subnormal positive double assert.deepEqual( [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01], binary.writeDouble([], 4.9406564584124654e-324), ); // Min normal positive double assert.deepEqual( [0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2.2250738585072014e-308), ); // Max positive double assert.deepEqual( [0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], binary.writeDouble([], 1.7976931348623157e308), ); assert.end(); }, }; Object.keys(cases).forEach(function (caseName) { test(caseName, cases[caseName]); }); thrift-0.23.0/lib/nodejs/test/test_header_payload0000664000175000017500000000011415165535636022323 0ustar00buildbuild00000000000000HÿParentshoobarTraceabcde€addthrift-0.23.0/lib/nodejs/test/helpers.js0000664000175000017500000000366615165535636020417 0ustar00buildbuild00000000000000/* * 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. */ "use strict"; const thrift = require("thrift"); module.exports.transports = { buffered: thrift.TBufferedTransport, framed: thrift.TFramedTransport, }; module.exports.protocols = { json: thrift.TJSONProtocol, binary: thrift.TBinaryProtocol, compact: thrift.TCompactProtocol, header: thrift.THeaderProtocol, }; 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; } }; thrift-0.23.0/lib/nodejs/test/episodic-code-generation-test/0000775000175000017500000000000015167543515024216 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodejs/test/episodic-code-generation-test/server.js0000664000175000017500000000454115167543515026066 0ustar00buildbuild00000000000000#!/usr/bin/env node /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * 'License'); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const thrift = require("../../lib/thrift"); const { program } = require("commander"); program .option("--port ", "Set the thrift server port", 9090) .option("--base ", "Set the base: 'pure', 'base' or 'extend'", "pure") .parse(process.argv); const ServiceBase = require("types-package/first-episode/BaseService"); const ServicePure = require("./gen-2/second-episode/gen-nodejs/Service"); const ServiceExtended = require("./gen-2/second-episode/gen-nodejs/ExtendedService"); const Types = require("types-package/first-episode/Types_types"); const opts = program.opts(); const port = opts.port; let Service; if (opts.base === "pure") { Service = ServicePure; } else if (opts.base === "base") { Service = ServiceBase; } else if (opts.base === "extend") { Service = ServiceExtended; } const options = { transport: thrift.TBufferedTransport, protocol: thrift.TJSONProtocol, }; const ServiceHandler = { testEpisode: function (receivedType1Object) { const type1Object = new Types.Type1(); type1Object.number = receivedType1Object.number + 1; type1Object.message = receivedType1Object.message + " [Hello from the server]"; return type1Object; }, testEpisodeExtend: function (receivedType1Object) { const type1Object = new Types.Type1(); type1Object.number = receivedType1Object.number + 1; type1Object.message = receivedType1Object.message + " [Hello from the extended server]"; return type1Object; }, }; const server = thrift.createServer(Service, ServiceHandler, options); server.listen(port); thrift-0.23.0/lib/nodejs/test/episodic-code-generation-test/client.js0000664000175000017500000000706015167543515026035 0ustar00buildbuild00000000000000#!/usr/bin/env node /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const assert = require("assert"); const test = require("tape"); const thrift = require("thrift"); const { program } = require("commander"); const tape = require("tape"); program .option("--host ", "Set the thrift server host to connect", "localhost") .option("--port ", "Set the thrift server port number to connect", 9090) .option("--base ", "Set the base: 'pure', 'base' or 'extend'", "pure") .parse(process.argv); const ServiceBase = require("types-package/first-episode/BaseService"); const ServicePure = require("./gen-2/second-episode/gen-nodejs/Service"); const ServiceExtended = require("./gen-2/second-episode/gen-nodejs/ExtendedService"); const Types = require("types-package/first-episode/Types_types"); const opts = program.opts(); const host = opts.host; const port = opts.port; let Service; if (opts.base === "pure") { Service = ServicePure; } else if (opts.base === "base") { Service = ServiceBase; } else if (opts.base === "extend") { Service = ServiceExtended; } const options = { transport: thrift.TBufferedTransport, 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 type1Object = new Types.Type1(); type1Object.number = 42; type1Object.message = "The answer"; 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]", ); assert.end(); callback("Server successfully tested"); }); }); if (opts.base === "extend") { test("NodeJS episodic compilation client-server extended test", function (assert) { const type1Object = new Types.Type1(); type1Object.number = 42; type1Object.message = "The answer"; client.testEpisodeExtend(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 extended server]", ); assert.end(); callback("Extended Server successfully tested"); }); }); } }; connection.on("error", function (err) { assert(false, err); }); const client = thrift.createClient(Service, connection); runTests(); function runTests() { testDriver(client, function (status) { console.log(status); }); tape.onFinish(function () { console.log("Tests finished"); connection.destroy(); }); } exports.expressoTest = function () {}; thrift-0.23.0/lib/nodejs/test/episodic-code-generation-test/episodic_compilation.package.json0000664000175000017500000000004015165535636032675 0ustar00buildbuild00000000000000{ "name": "types-package" } thrift-0.23.0/lib/nodejs/test/header.test.js0000664000175000017500000001105315165535636021150 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const TFramedTransport = require("../lib/thrift/framed_transport"); const THeaderTransport = require("../lib/thrift/header_transport"); const THeaderProtocol = require("../lib/thrift/header_protocol"); const thrift = require("../lib/thrift"); const fs = require("fs"); const test = require("tape"); const path = require("path"); const headerPayload = fs.readFileSync( path.join(__dirname, "test_header_payload"), ); const cases = { "Should read headers from payload": function (assert) { const transport = new TFramedTransport(); transport.inBuf = Buffer.from(headerPayload); const headers = transport.readHeaders(); assert.equals(headers.Parent, "shoobar"); assert.equals(headers.Trace, "abcde"); assert.end(); }, "Should read different headers from different payload": function (assert) { const transport = new TFramedTransport(); const buf = Buffer.from(headerPayload); buf[24] = 115; // Change Parent to Parens buf[32] = 122; // Change shoobar to shoobaz transport.inBuf = buf; const headers = transport.readHeaders(); assert.equals(headers.Parent, undefined); assert.equals(headers.Parens, "shoobaz"); assert.equals(headers.Trace, "abcde"); assert.end(); }, "Should read headers when reading message begin": function (assert) { const transport = new TFramedTransport(); transport.inBuf = Buffer.from(headerPayload); const protocol = new THeaderProtocol(transport); const result = protocol.readMessageBegin(); const headers = transport.getReadHeaders(); assert.equals(headers.Parent, "shoobar"); assert.equals(headers.Trace, "abcde"); assert.equals(result.fname, "add"); assert.equals(result.mtype, thrift.Thrift.MessageType.CALL); assert.end(); }, "Should be able to write headers": function (assert) { const writeTransport = new TFramedTransport(); writeTransport.setProtocolId(THeaderTransport.SubprotocolId.BINARY); writeTransport.setWriteHeader("Hihihihi", "hohohoho"); writeTransport.setWriteHeader("boobooboo", "fooshoopoo"); writeTransport.setWriteHeader("a", "z"); writeTransport.writeHeaders(); const writeBuffer = writeTransport.outBuffers[0]; const readTransport = new TFramedTransport(); readTransport.inBuf = writeBuffer; readTransport.readHeaders(); const headers = readTransport.getReadHeaders(); assert.equals(headers.Hihihihi, "hohohoho"); assert.equals(headers.boobooboo, "fooshoopoo"); assert.equals(headers.a, "z"); assert.end(); }, "Separate transports should have separate headers": function (assert) { const writeTransport = new TFramedTransport(); writeTransport.setProtocolId(THeaderTransport.SubprotocolId.BINARY); writeTransport.setWriteHeader("foo", "bar"); const headers = writeTransport.getWriteHeaders(); const otherWriteTransport = new TFramedTransport(); otherWriteTransport.setProtocolId(THeaderTransport.SubprotocolId.BINARY); otherWriteTransport.setWriteHeader("otherfoo", "baz"); const otherHeaders = otherWriteTransport.getWriteHeaders(); assert.equals(headers.foo, "bar"); assert.equals(headers.otherfoo, undefined); 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) { test(caseName, cases[caseName]); }); thrift-0.23.0/lib/nodejs/test/test-cases.mjs0000664000175000017500000001334115167543515021171 0ustar00buildbuild00000000000000/* * 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. */ "use strict"; import helpers from "./helpers.js"; import Int64 from "node-int64"; import { v4 as uuidv4, v7 as uuidv7 } from "uuid"; const ttypes = await helpers.importTypes(`ThriftTest_types`); //all Languages in UTF-8 /*jshint -W100 */ export const 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 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: ]] "]] \\" }}}{ [[[ '; export const mapTestInput = { a: "123", "a b": "with spaces ", same: "same", 0: "numeric key", longValue: stringTest, stringTest: "long key", }; export const simple = [ ["testVoid", undefined], ["testString", "Test"], ["testString", ""], ["testString", stringTest], ["testString", specialCharacters], ["testBool", true], ["testBool", false], ["testByte", 1], ["testByte", 0], ["testByte", -1], ["testByte", -127], ["testI32", -1], ["testDouble", -5.2098523], ["testDouble", 7.012052175215044], ["testEnum", ttypes.Numberz.ONE], ["testI64", 5], ["testI64", -5], ["testI64", 734359738368], ["testI64", -734359738368], ["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])), ], // -2^53-1 ["testTypedef", 69], ["testUuid", "00112233-4455-6677-8899-aabbccddeeff"], ["testUuid", uuidv4()], ["testUuid", uuidv7()], ]; const mapout = {}; for (let i = 0; i < 5; ++i) { mapout[i] = i - 10; } export const deep = [ [ "testList", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], ], ]; export const deepUnordered = [ ["testMap", mapout], ["testSet", [1, 2, 3]], ["testStringMap", mapTestInput], ]; export const out = new ttypes.Xtruct({ string_thing: "Zero", byte_thing: 1, i32_thing: -3, i64_thing: 1000000, }); export const out2 = new ttypes.Xtruct2(); out2.byte_thing = 1; out2.struct_thing = out; out2.i32_thing = 5; 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, }), new ttypes.Xtruct({ string_thing: "Hello2", byte_thing: 2, i32_thing: 2, i64_thing: 2, }), ], }); export const crazy2 = new ttypes.Insanity({ userMap: { 5: 5, 8: 8 }, xtructs: [ { string_thing: "Goodbye4", byte_thing: 4, i32_thing: 4, i64_thing: 4, }, { string_thing: "Hello2", byte_thing: 2, i32_thing: 2, i64_thing: 2, }, ], }); export const insanity = { 1: { 2: crazy, 3: crazy }, 2: { 6: { userMap: {}, xtructs: [] } }, }; thrift-0.23.0/lib/nodejs/coding_standards.md0000664000175000017500000000010315165535636021247 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/nodejs/CMakeLists.txt0000664000175000017500000000313415165535636020166 0ustar00buildbuild00000000000000# # 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. # if(NOT NODEJS_INSTALL_DIR) if(IS_ABSOLUTE "${LIB_INSTALL_DIR}") set(NODEJS_INSTALL_DIR "${LIB_INSTALL_DIR}/nodejs") else() set(NODEJS_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/nodejs") endif() endif() # Currently no doc #if(IS_ABSOLUTE "${DOC_INSTALL_DIR}") # set(NODEJS_DOC_INSTALL_DIR "${DOC_INSTALL_DIR}/nodejs") #else() # set(NODEJS_DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${DOC_INSTALL_DIR}/nodejs") #endif() add_custom_target(ThriftNodeJS ALL COMMENT "Installing NodeJS dependencies with npm" COMMAND npm install WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../" ) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib/" DESTINATION "${NODEJS_INSTALL_DIR}") #install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/doc/" # DESTINATION "${NODEJS_DOC_INSTALL_DIR}") thrift-0.23.0/lib/nodejs/examples/0000775000175000017500000000000015167543515017240 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodejs/examples/httpClient.js0000664000175000017500000000252015167543515021713 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var 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, }; var connection = thrift.createHttpConnection("localhost", 9090, options); var client = thrift.createHttpClient(helloSvc, connection); connection.on("error", function (err) { console.log("Error: " + err); }); client.hello_func(function (error, result) { console.log("Msg from server: " + result); }); thrift-0.23.0/lib/nodejs/examples/server_http.js0000664000175000017500000000325315165535636022151 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var connect = require("connect"); var thrift = require("thrift"); var UserStorage = require("./gen-nodejs/UserStorage"), ttypes = require("./gen-nodejs/user_types"); var users = {}; var store = function (user, result) { console.log("stored:", user.uid); users[user.uid] = user; result(null); }; var retrieve = function (uid, result) { console.log("retrieved:", uid); result(null, users[uid]); }; var server_http = thrift.createHttpServer(UserStorage, { store: store, retrieve: retrieve, }); server_http.listen(9090); 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 }, ), ); server_connect_json.listen(9092); thrift-0.23.0/lib/nodejs/examples/client_multitransport.js0000664000175000017500000000444615165535636024256 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var thrift = require("thrift"), ttransport = require("thrift/transport"); 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.", }); f_conn.on("error", function (err) { console.error("framed:", err); }); 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; } console.log("retrieved:", responseUser.uid, " as ", responseUser.name); }); }); 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; } console.log("retrieved:", responseUser.uid, " as ", responseUser.name); }); }); thrift-0.23.0/lib/nodejs/examples/server.js0000664000175000017500000000240115165535636021104 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var thrift = require("thrift"); var UserStorage = require("./gen-nodejs/UserStorage.js"), ttypes = require("./gen-nodejs/user_types"); var users = {}; var server = thrift.createServer(UserStorage, { store: function (user, result) { console.log("server stored:", user.uid); users[user.uid] = user; result(null); }, retrieve: function (uid, result) { console.log("server retrieved:", uid); result(null, users[uid]); }, }); server.listen(9090); thrift-0.23.0/lib/nodejs/examples/client.js0000664000175000017500000000312015165535636021053 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var thrift = require("thrift"); 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 user = new ttypes.UserProfile({ uid: 1, name: "Mark Slee", blurb: "I'll find something to put here.", }); connection.on("error", function (err) { console.error(err); }); 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) { if (err) { console.error(err); } else { console.log("client retrieved:", responseUser.uid); connection.end(); } }); } }); thrift-0.23.0/lib/nodejs/examples/server_multitransport.js0000664000175000017500000000300515165535636024274 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var thrift = require("thrift"), ttransport = require("thrift/transport"); var UserStorage = require("./gen-nodejs/UserStorage"), ttypes = require("./gen-nodejs/user_types"); var users = {}; var store = function (user, result) { console.log("stored:", user.uid); users[user.uid] = user; result(null); }; var retrieve = function (uid, result) { console.log("retrieved:", uid); result(null, users[uid]); }; var server_framed = thrift.createServer(UserStorage, { store: store, retrieve: retrieve, }); server_framed.listen(9090); var server_buffered = thrift.createServer( UserStorage, { store: store, retrieve: retrieve, }, { transport: ttransport.TBufferedTransport }, ); server_buffered.listen(9091); thrift-0.23.0/lib/nodejs/examples/hello.js0000664000175000017500000000353015165535636020705 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var 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); }, }; var timesTwoHandler = { 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, }; var dblService = { transport: thrift.TBufferedTransport, protocol: thrift.TJSONProtocol, processor: TimesTwoSvc, handler: timesTwoHandler, }; var ServerOptions = { files: ".", services: { "/hello": helloService, "/dbl": dblService, }, }; var server = thrift.createWebServer(ServerOptions); var port = 8585; server.listen(port); console.log("Http/Thrift Server running on port: " + port); thrift-0.23.0/lib/nodejs/examples/user.thrift0000664000175000017500000000166615165535636021454 0ustar00buildbuild00000000000000# 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 UserProfile { 1: i32 uid, 2: string name, 3: string blurb } service UserStorage { void store(1: UserProfile user), UserProfile retrieve(1: i32 uid) } thrift-0.23.0/lib/nodejs/examples/httpServer.js0000664000175000017500000000300215167543515021737 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var thrift = require("thrift"); var helloSvc = require("./gen-nodejs/HelloSvc"); //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, }; //ServerOptions: Define server features var serverOpt = { services: { "/hello": helloSvcOpt, }, }; //Create and start the web server var port = 9090; thrift.createWebServer(serverOpt).listen(port); console.log("Http/Thrift Server running on port: " + port); thrift-0.23.0/lib/nodejs/examples/README.md0000664000175000017500000000262015165535636020522 0ustar00buildbuild00000000000000# Thrift Node.js Examples ## License Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ## Running the user example Generate the bindings: ../../../compiler/cpp/thrift --gen js:node user.thrift ../../../compiler/cpp/thrift --gen js:node --gen py hello.thrift To run the user example, first start up the server in one terminal: NODE_PATH=../lib:../lib/thrift node server.js Now run the client: NODE_PATH=../lib:../lib/thrift node client.js For an example using JavaScript in the browser to connect to a node.js server look at hello.html, hello.js and hello.thrift HTTP examples are provided also: httpClient.js and httpServer.js You can test HTTP cross platform with the httpServer.py Python server thrift-0.23.0/lib/nodejs/examples/Makefile0000664000175000017500000000173715165535636020713 0ustar00buildbuild00000000000000# 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. all: ../../../compiler/cpp/thrift --gen js:node user.thrift server: all NODE_PATH=../lib:../lib/thrift:$(NODE_PATH) node server.js client: all NODE_PATH=../lib:../lib/thrift:$(NODE_PATH) node client.js thrift-0.23.0/lib/nodejs/examples/httpServer.py0000664000175000017500000000243515167543515021764 0ustar00buildbuild00000000000000# # 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 sys sys.path.append('gen-py') from hello import HelloSvc from thrift.protocol import TJSONProtocol from thrift.server import THttpServer class HelloSvcHandler: def hello_func(self): print("Hello Called") return "hello from Python" processor = HelloSvc.Processor(HelloSvcHandler()) protoFactory = TJSONProtocol.TJSONProtocolFactory() port = 9090 server = THttpServer.THttpServer(processor, ("localhost", port), protoFactory) print("Python server running on port " + str(port)) server.serve() thrift-0.23.0/lib/nodejs/examples/parse.js0000664000175000017500000000343115165535636020714 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** This is a standalone deserialize/parse example if you just want to deserialize thrift decoupled from cassandra server 1. acquire thrift template specification files from who ever built it (eg: EXAMPLE.thrift) 2. Install thrift on local machine 3. generate thrift clients for nodejs using template specification files (#1) thrift --gen js:node schema/EXAMPLE.thrift This creates creates gen-node.js directory containing a new file, GENERATED.js 4. Inside GENERATED.js is a class you will want to instanciate. Find this class name and plug it into the example code below (ie, "YOUR_CLASS_NAME") */ function parseThrift(thriftEncodedData, callback) { var thrift = require("thrift"); var transport = new thrift.TFramedTransport(thriftEncodedData); var protocol = new thrift.TBinaryProtocol(transport); var clientClass = require("../gen-nodejs/GENERATED").YOUR_CLASS_NAME; var client = new clientClass(); client.read(protocol); callback(null, client); } thrift-0.23.0/lib/nodejs/examples/hello.thrift0000664000175000017500000000160315165535636021570 0ustar00buildbuild00000000000000/* * 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. */ service HelloSvc { string hello_func(), } service TimesTwo { i64 dbl(1: i64 val), } thrift-0.23.0/lib/nodejs/examples/hello.html0000664000175000017500000000761415165535636021244 0ustar00buildbuild00000000000000 Apache Thrift JavaScript Browser Client Demo

Apache Thrift JavaScript Browser Client Demo

This html file demonstrates Apache Thrift JavaScrpt RPC between a browser client to a node.js server. Clicking the buttons below will call the RPC functions hosted by the Apache Thrift server at localhost:8585. The file hello.js contains the JavaScript node.js server required. Here are the steps to get the example running:

  1. Install Node.js
    nodejs.org
  2. Install Apache Thrift for node (note that the node package manager will create the node_modules folder in the current directory so make sure to run npm from the same directory as hello.js so that the server can find the Thrift libraries. This example requires Apache Thrift 0.9.2+)
    $ npm install thrift
  3. Compile the hello.idl for JavaScript and Node.js (you'll need to have the Apache Thrift compiler installed for this step. This also needs to be executed in the same directory as hello.js because hello.js and hello.html look for the gen-nodejs and gen-js directories here.)
    $ thrift -gen js -gen js:node hello.thrift
  4. Run the node server in the directory with the hello.html file
    $ node hello.js
  5. Copy the Apache Thrift JavaScript library, thrift.js, into the directory with this html file.
    $ cp ...../thrift.js . (you should be able to use Bower to install the browser based Apache Thrift library in the near future.)
  6. Reload this page in a browser through the node server using using the URL:
    http://localhost:8585/hello.html
    then click a button below to make an RPC call

Server Response:

Server Dbl:

thrift-0.23.0/lib/nodejs/README.md0000664000175000017500000000756615165535636016722 0ustar00buildbuild00000000000000Thrift Node.js Library ========================= License ------- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ## Compatibility node version 6 or later is required ## Install npm install thrift ## Thrift Compiler You can compile IDL sources for Node.js with the following command: thrift --gen js:node thrift_file ## Cassandra Client Example: Here is a Cassandra example: ```js var thrift = require('thrift'), Cassandra = require('./gen-nodejs/Cassandra') ttypes = require('./gen-nodejs/cassandra_types'); var connection = thrift.createConnection("localhost", 9160), client = thrift.createClient(Cassandra, connection); connection.on('error', function(err) { console.error(err); }); client.get_slice("Keyspace", "key", new ttypes.ColumnParent({column_family: "ExampleCF"}), new ttypes.SlicePredicate({slice_range: new ttypes.SliceRange({start: '', finish: ''})}), ttypes.ConsistencyLevel.ONE, function(err, data) { if (err) { // handle err } else { // data == [ttypes.ColumnOrSuperColumn, ...] } connection.end(); }); ``` ## Int64 Since JavaScript represents all numbers as doubles, int64 values cannot be accurately represented naturally. To solve this, int64 values in responses will be wrapped with Thrift.Int64 objects. The Int64 implementation used is [broofa/node-int64](https://github.com/broofa/node-int64). ## Client and server examples Several example clients and servers are included in the thrift/lib/nodejs/examples folder and the cross language tutorial thrift/tutorial/nodejs folder. ## Use on browsers You can use code generated with js:node on browsers with Webpack. Here is an example. thrift --gen js:node,ts,es6,with_ns ```javascript import * as thrift from 'thrift'; import { MyServiceClient } from '../gen-nodejs/MyService'; let host = window.location.hostname; let port = 443; let opts = { transport: thrift.TBufferedTransport, protocol: thrift.TJSONProtocol, headers: { 'Content-Type': 'application/vnd.apache.thrift.json', }, https: true, path: '/url/path', useCORS: true, }; let connection = thrift.createXHRConnection(host, port, opts); let thriftClient = thrift.createXHRClient(MyServiceClient, connection); connection.on('error', (err) => { console.error(err); }); thriftClient.myService(param) .then((result) => { console.log(result); }) .catch((err) => { .... }); ``` Bundlers, like webpack, will use thrift/browser.js by default because of the `"browser": "./lib/nodejs/lib/thrift/browser.js"` field in package.json. ### Browser example with WebSocket, BufferedTransport and BinaryProtocol ```javascript import thrift from 'thrift'; import { MyServiceClient } from '../gen-nodejs/MyService'; const host = window.location.hostname; const port = 9090; const opts = { transport: thrift.TBufferedTransport, protocol: thrift.TBinaryProtocol } const connection = thrift.createWSConnection(host, port, opts); connection.open(); const thriftClient = thrift.createWSClient(MyServiceClient, connection); connection.on('error', (err) => { console.error(err); }); thriftClient.myService(param) .then((result) => { console.log(result); }) .catch((err) => { .... }); ``` thrift-0.23.0/lib/nodejs/lib/0000775000175000017500000000000015165535636016173 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodejs/lib/thrift/0000775000175000017500000000000015170007142017451 5ustar00buildbuild00000000000000thrift-0.23.0/lib/nodejs/lib/thrift/framed_transport.js0000664000175000017500000001212615165535636023405 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var binary = require("./binary"); var InputBufferUnderrunError = require("./input_buffer_underrun_error"); var THeaderTransport = require("./header_transport"); module.exports = TFramedTransport; function TFramedTransport(buffer, callback) { THeaderTransport.call(this); this.inBuf = buffer || new Buffer(0); this.outBuffers = []; this.outCount = 0; this.readPos = 0; this.onFlush = callback; } Object.setPrototypeOf(TFramedTransport.prototype, THeaderTransport.prototype); TFramedTransport.receiver = function (callback, seqid) { var residual = new Buffer(0); 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 size var frameSize = binary.readI32(residual, 0); // Not enough bytes to continue, save and resume on next packet if (residual.length < 4 + frameSize) { return; } // 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 () {}), // TODO: Implement open/close support (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) { this._seqid = seqid; }; 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. this.ensureAvailable(len); var end = this.readPos + len; if (this.inBuf.length < end) { throw new Error("read(" + len + ") failed - not enough data"); } var buf = this.inBuf.slice(this.readPos, end); this.readPos = end; return buf; }; TFramedTransport.prototype.readByte = function () { this.ensureAvailable(1); return binary.readByte(this.inBuf[this.readPos++]); }; TFramedTransport.prototype.readI16 = function () { this.ensureAvailable(2); var i16 = binary.readI16(this.inBuf, this.readPos); this.readPos += 2; return i16; }; TFramedTransport.prototype.readI32 = function () { this.ensureAvailable(4); var i32 = binary.readI32(this.inBuf, this.readPos); this.readPos += 4; return i32; }; 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) { this.ensureAvailable(len); var str = this.inBuf.toString("utf8", this.readPos, this.readPos + len); this.readPos += len; return str; }; TFramedTransport.prototype.borrow = function () { return { buf: this.inBuf, readIndex: this.readPos, writeIndex: this.inBuf.length, }; }; TFramedTransport.prototype.consume = function (bytesConsumed) { this.readPos += bytesConsumed; }; 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 () { // 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) { buf.copy(out, pos, 0); pos += buf.length; }); if (this.onFlush) { // TODO: optimize this better, allocate one buffer instead of both: var msg = new Buffer(out.length + 4); binary.writeI32(msg, out.length); out.copy(msg, 4, 0, out.length); if (this.onFlush) { // Passing seqid through this call to get it to the connection this.onFlush(msg, seqid); } } this.outBuffers = []; this.outCount = 0; }; thrift-0.23.0/lib/nodejs/lib/thrift/input_buffer_underrun_error.js0000664000175000017500000000221015165535636025647 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); module.exports = InputBufferUnderrunError; function InputBufferUnderrunError(message) { Error.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.message = message; } util.inherits(InputBufferUnderrunError, Error); thrift-0.23.0/lib/nodejs/lib/thrift/ws_transport.js0000664000175000017500000001342415165535636022602 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var log = require("./log"); module.exports = TWebSocketTransport; /** * Constructor Function for the WebSocket transport. * @constructor * @param {string} [url] - The URL to connect to. * @classdesc 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. * (see: node.js example server_http.js). * @example * 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 }; /** * 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 {object} callback - The client completion callback. * @returns {undefined|string} Nothing (undefined) */ 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(); }; })(), ); } else { //Queue the send to go out __onOpen this.send_pending.push({ buf: this.send_buf, 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.__onClose = function (evt) { this.__reset(this.url); }; TWebSocketTransport.prototype.__onMessage = function (evt) { if (this.callbacks.length) { this.callbacks.shift()(evt.data); } }; TWebSocketTransport.prototype.__onError = function (evt) { log.error("websocket: " + evt.toString()); this.socket.close(); }; /** * Sets the buffer to use when receiving server responses. * @param {string} buf - The buffer to receive server responses. */ TWebSocketTransport.prototype.setRecvBuffer = function (buf) { this.recv_buf = buf; this.recv_buf_sz = this.recv_buf.length; this.wpos = this.recv_buf.length; this.rpos = 0; }; /** * Returns true if the transport is open * @readonly * @returns {boolean} */ TWebSocketTransport.prototype.isOpen = function () { return this.socket && this.socket.readyState == this.socket.OPEN; }; /** * Opens the transport connection */ TWebSocketTransport.prototype.open = function () { //If OPEN/CONNECTING/CLOSING ignore additional opens if (this.socket && this.socket.readyState != this.socket.CLOSED) { return; } //If there is no socket or the socket is closed: this.socket = new WebSocket(this.url); this.socket.onopen = this.__onOpen.bind(this); this.socket.onmessage = this.__onMessage.bind(this); this.socket.onerror = this.__onError.bind(this); this.socket.onclose = this.__onClose.bind(this); }; /** * Closes the transport connection */ TWebSocketTransport.prototype.close = function () { this.socket.close(); }; /** * Returns the specified number of characters from the response * buffer. * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ TWebSocketTransport.prototype.read = function (len) { var avail = this.wpos - this.rpos; if (avail === 0) { return ""; } var give = len; if (avail < len) { give = avail; } var ret = this.read_buf.substr(this.rpos, give); this.rpos += give; //clear buf when complete? return ret; }; /** * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ TWebSocketTransport.prototype.readAll = function () { return this.recv_buf; }; /** * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ TWebSocketTransport.prototype.write = function (buf) { this.send_buf = buf; }; /** * Returns the send buffer. * @readonly * @returns {string} The send buffer. */ TWebSocketTransport.prototype.getSendBuffer = function () { return this.send_buf; }; thrift-0.23.0/lib/nodejs/lib/thrift/multiplexed_protocol.js0000664000175000017500000000462515165535636024315 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var 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) { if (type == Thrift.MessageType.CALL || type == Thrift.MessageType.ONEWAY) { connection.seqId2Service[seqid] = serviceName; MultiplexProtocol.super_.prototype.writeMessageBegin.call( this, serviceName + ":" + name, type, seqid, ); } else { MultiplexProtocol.super_.prototype.writeMessageBegin.call( this, name, type, seqid, ); } }; return MultiplexProtocol; } function Multiplexer() { this.seqid = 0; } Multiplexer.prototype.createClient = function ( serviceName, ServiceClient, connection, ) { if (ServiceClient.Client) { ServiceClient = ServiceClient.Client; } 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 client = new ServiceClient(transport, protocolWrapper); var self = this; client.new_seqid = function () { self.seqid += 1; return self.seqid; }; if (typeof connection.client !== "object") { connection.client = {}; } connection.client[serviceName] = client; return client; }; thrift-0.23.0/lib/nodejs/lib/thrift/buffered_transport.js0000664000175000017500000001236415165535636023735 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var binary = require("./binary"); var InputBufferUnderrunError = require("./input_buffer_underrun_error"); var THeaderTransport = require("./header_transport"); module.exports = TBufferedTransport; function TBufferedTransport(buffer, callback) { THeaderTransport.call(this); this.defaultReadBufferSize = 1024; this.writeBufferSize = 512; // Soft Limit this.inBuf = new Buffer(this.defaultReadBufferSize); this.readCursor = 0; this.writeCursor = 0; // for input buffer this.outBuffers = []; this.outCount = 0; this.onFlush = callback; } Object.setPrototypeOf(TBufferedTransport.prototype, THeaderTransport.prototype); 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) { var reader = new TBufferedTransport(); 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); reader.inBuf = buf; } data.copy(reader.inBuf, reader.writeCursor, 0); reader.writeCursor += data.length; callback(reader, seqid); }; }; TBufferedTransport.prototype.commitPosition = function () { var unreadSize = this.writeCursor - this.readCursor; 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); } this.readCursor = 0; this.writeCursor = unreadSize; this.inBuf = buf; }; TBufferedTransport.prototype.rollbackPosition = function () { this.readCursor = 0; }; // TODO: Implement open/close support TBufferedTransport.prototype.isOpen = function () { return true; }; TBufferedTransport.prototype.open = 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) { this._seqid = seqid; }; TBufferedTransport.prototype.ensureAvailable = function (len) { if (this.readCursor + len > this.writeCursor) { throw new InputBufferUnderrunError(); } }; TBufferedTransport.prototype.read = function (len) { this.ensureAvailable(len); var buf = new Buffer(len); this.inBuf.copy(buf, 0, this.readCursor, this.readCursor + len); this.readCursor += len; return buf; }; TBufferedTransport.prototype.readByte = function () { this.ensureAvailable(1); return binary.readByte(this.inBuf[this.readCursor++]); }; TBufferedTransport.prototype.readI16 = function () { this.ensureAvailable(2); var i16 = binary.readI16(this.inBuf, this.readCursor); this.readCursor += 2; return i16; }; TBufferedTransport.prototype.readI32 = function () { this.ensureAvailable(4); var i32 = binary.readI32(this.inBuf, this.readCursor); this.readCursor += 4; return i32; }; 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) { this.ensureAvailable(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, }; return obj; }; TBufferedTransport.prototype.consume = function (bytesConsumed) { this.readCursor += bytesConsumed; }; 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 () { // 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; if (this.outCount < 1) { return; } var msg = new Buffer(this.outCount), pos = 0; this.outBuffers.forEach(function (buf) { buf.copy(msg, pos, 0); pos += buf.length; }); if (this.onFlush) { // Passing seqid through this call to get it to the connection this.onFlush(msg, seqid); } this.outBuffers = []; this.outCount = 0; }; thrift-0.23.0/lib/nodejs/lib/thrift/browser.js0000664000175000017500000000440315165535636021515 0ustar00buildbuild00000000000000/* * 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. */ exports.Thrift = require("./thrift"); var wsConnection = require("./ws_connection"); exports.WSConnection = wsConnection.WSConnection; exports.createWSConnection = wsConnection.createWSConnection; exports.createWSClient = wsConnection.createWSClient; var xhrConnection = require("./xhr_connection"); exports.XHRConnection = xhrConnection.XHRConnection; exports.createXHRConnection = xhrConnection.createXHRConnection; exports.createXHRClient = xhrConnection.createXHRClient; var ohosConnection = require("./ohos_connection"); exports.OhosConnection = ohosConnection.OhosConnection; exports.createOhosConnection = ohosConnection.createOhosConnection; exports.createOhosClient = ohosConnection.createOhosClient; exports.createClient = require("./create_client"); 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.InputBufferUnderrunError = require("./input_buffer_underrun_error"); thrift-0.23.0/lib/nodejs/lib/thrift/http_connection.js0000664000175000017500000002362415165535636023236 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var 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 createClient = require("./create_client"); /** * @class * @name ConnectOptions * @property {string} transport - The Thrift layered transport to use (TBufferedTransport, etc). * @property {string} protocol - The Thrift serialization protocol to use (TBinaryProtocol, etc.). * @property {string} path - The URL path to POST to (e.g. "/", "/mySvc", "/thrift/quoteSvc", etc.). * @property {object} headers - A standard Node.js header hash, an object hash containing key/value * pairs where the key is the header name string and the value is the header value string. * @property {boolean} https - True causes the connection to use https, otherwise http is used. * @property {object} nodeOptions - Options passed on to node. * @example * //Use a connection that requires ssl/tls, closes the connection after each request, * // uses the buffered transport layer, uses the JSON protocol and directs RPC traffic * // to https://thrift.example.com:9090/hello * var thrift = require('thrift'); * var options = { * transport: thrift.TBufferedTransport, * protocol: thrift.TJSONProtocol, * path: "/hello", * headers: {"Connection": "close"}, * https: true * }; * var con = thrift.createHttpConnection("thrift.example.com", 9090, options); * var client = thrift.createHttpClient(myService, connection); * client.myServiceFunction(); */ /** * Initializes a Thrift HttpConnection instance (use createHttpConnection() rather than * instantiating directly). * @constructor * @param {ConnectOptions} options - The configuration options to use. * @throws {error} Exceptions other than InputBufferUnderrunError are rethrown * @event {error} The "error" event is fired when a Node.js error event occurs during * request or response processing, in which case the node error is passed on. An "error" * event may also be fired when the connection can not map a response back to the * appropriate client (an internal error), generating a TApplicationException. * @classdesc HttpConnection objects provide Thrift end point transport * semantics implemented over the Node.js http.request() method. * @see {@link createHttpConnection} */ var HttpConnection = (exports.HttpConnection = function (options) { //Initialize the emitter base object EventEmitter.call(this); //Set configuration var self = this; this.options = options || {}; this.host = this.options.host; this.port = this.options.port; this.socketPath = this.options.socketPath; this.https = this.options.https || false; this.transport = this.options.transport || TBufferedTransport; this.protocol = this.options.protocol || TBinaryProtocol; //Prepare Node.js options this.nodeOptions = { host: this.host, port: this.port, socketPath: this.socketPath, path: this.options.path || "/", method: "POST", headers: this.options.headers || {}, 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"; } /*jshint +W069 */ //The sequence map is used to map seqIDs back to the // calling client in multiplexed scenarios this.seqId2Service = {}; function decodeCallback(transport_with_data) { var proto = new self.protocol(transport_with_data); try { while (true) { var header = proto.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 client var 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]; delete self.seqId2Service[header.rseqid]; } /*jshint -W083 */ 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 () { clientCallback(err, success); }); } }; /*jshint +W083 */ 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", ), ); } } } catch (e) { if (e instanceof InputBufferUnderrunError) { transport_with_data.rollbackPosition(); } else { self.emit("error", e); } } } //Response handler ////////////////////////////////////////////////// this.responseCallback = function (response) { var data = []; var dataLen = 0; if (response.statusCode !== 200) { this.emit("error", new THTTPException(response)); } 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]" ) { // Wrap ArrayBuffer/string in a Buffer so data[i].copy will work data.push(new Buffer(chunk)); } else { data.push(chunk); } dataLen += chunk.length; }); response.on("end", function () { var buf = new Buffer(dataLen); for (var i = 0, len = data.length, pos = 0; i < len; i++) { data[i].copy(buf, pos); pos += data[i].length; } //Get the receiver function for the transport and // call it with the buffer self.transport.receiver(decodeCallback)(buf); }); }; }); util.inherits(HttpConnection, EventEmitter); /** * Writes Thrift message data to the connection * @param {Buffer} data - A Node.js Buffer containing the data to write * @returns {void} No return value. * @event {error} the "error" event is raised upon request failure passing the * Node.js error object to the listener. */ HttpConnection.prototype.write = function (data) { var self = this; var opts = self.nodeOptions; opts.headers["Content-length"] = data.length; if (!opts.headers["Content-Type"]) opts.headers["Content-Type"] = "application/x-thrift"; var req = self.https ? https.request(opts, self.responseCallback) : http.request(opts, self.responseCallback); req.on("error", function (err) { self.emit("error", err); }); req.write(data); req.end(); }; /** * Creates a new HttpConnection object, used by Thrift clients to connect * to Thrift HTTP based servers. * @param {string} host - The host name or IP to connect to. * @param {number} port - The TCP port to connect to. * @param {ConnectOptions} options - The configuration options to use. * @returns {HttpConnection} The connection object. * @see {@link ConnectOptions} */ exports.createHttpConnection = function (host, port, options) { options.host = host; options.port = port || 80; return new HttpConnection(options); }; exports.createHttpUDSConnection = function (path, options) { options.socketPath = path; return new HttpConnection(options); }; exports.createHttpClient = createClient; function THTTPException(response) { thrift.TApplicationException.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.statusCode = response.statusCode; this.response = response; this.type = thrift.TApplicationExceptionType.PROTOCOL_ERROR; this.message = "Received a response with a bad HTTP status code: " + response.statusCode; } util.inherits(THTTPException, thrift.TApplicationException); thrift-0.23.0/lib/nodejs/lib/thrift/json_protocol.js0000664000175000017500000005321315170007142022705 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var 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 InputBufferUnderrunError = require("./input_buffer_underrun_error"); module.exports = TJSONProtocol; /** * Initializes a Thrift JSON protocol instance. * @constructor * @param {Thrift.Transport} trans - The transport to serialize to/from. * @classdesc Apache Thrift Protocols perform serialization which enables cross * language RPC. The Protocol type is the JavaScript browser implementation * of the Apache Thrift TJSONProtocol. * @example * var protocol = new Thrift.Protocol(transport); */ function TJSONProtocol(trans) { this.tstack = []; this.tpos = []; this.trans = trans; } /** * Thrift IDL type Id to string mapping. * @readonly * @see {@link Thrift.Type} */ TJSONProtocol.Type = {}; TJSONProtocol.Type[Type.BOOL] = '"tf"'; TJSONProtocol.Type[Type.BYTE] = '"i8"'; TJSONProtocol.Type[Type.I16] = '"i16"'; TJSONProtocol.Type[Type.I32] = '"i32"'; TJSONProtocol.Type[Type.I64] = '"i64"'; TJSONProtocol.Type[Type.DOUBLE] = '"dbl"'; TJSONProtocol.Type[Type.STRUCT] = '"rec"'; TJSONProtocol.Type[Type.STRING] = '"str"'; TJSONProtocol.Type[Type.MAP] = '"map"'; TJSONProtocol.Type[Type.LIST] = '"lst"'; TJSONProtocol.Type[Type.SET] = '"set"'; TJSONProtocol.Type[Type.UUID] = '"uid"'; /** * Thrift IDL type string to Id mapping. * @readonly * @see {@link Thrift.Type} */ TJSONProtocol.RType = {}; TJSONProtocol.RType.tf = Type.BOOL; TJSONProtocol.RType.i8 = Type.BYTE; TJSONProtocol.RType.i16 = Type.I16; TJSONProtocol.RType.i32 = Type.I32; TJSONProtocol.RType.i64 = Type.I64; TJSONProtocol.RType.dbl = Type.DOUBLE; TJSONProtocol.RType.rec = Type.STRUCT; TJSONProtocol.RType.str = Type.STRING; TJSONProtocol.RType.map = Type.MAP; TJSONProtocol.RType.lst = Type.LIST; TJSONProtocol.RType.set = Type.SET; TJSONProtocol.RType.uid = Type.UUID; /** * The TJSONProtocol version number. * @readonly * @const {number} Version * @memberof Thrift.Protocol */ TJSONProtocol.Version = 1; TJSONProtocol.prototype.flush = function () { this.writeToTransportIfStackIsFlushable(); return this.trans.flush(); }; TJSONProtocol.prototype.writeToTransportIfStackIsFlushable = function () { if (this.tstack.length === 1) { this.trans.write(this.tstack.pop()); } }; /** * Serializes the beginning of a Thrift RPC message. * @param {string} name - The service method to call. * @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, ]); }; /** * Serializes the end of a Thrift RPC message. */ TJSONProtocol.prototype.writeMessageEnd = function () { var obj = this.tstack.pop(); this.wobj = this.tstack.pop(); this.wobj.push(obj); this.wbuf = "[" + this.wobj.join(",") + "]"; // we assume there is nothing more to come so we write this.trans.write(this.wbuf); }; /** * Serializes the beginning of a struct. * @param {string} name - The name of the struct. */ TJSONProtocol.prototype.writeStructBegin = function (name) { this.tpos.push(this.tstack.length); this.tstack.push({}); }; /** * Serializes the end of a struct. */ TJSONProtocol.prototype.writeStructEnd = function () { var p = this.tpos.pop(); var struct = this.tstack[p]; var str = "{"; var first = true; for (var key in struct) { if (first) { first = false; } else { str += ","; } str += key + ":" + struct[key]; } str += "}"; this.tstack[p] = str; this.writeToTransportIfStackIsFlushable(); }; /** * Serializes the beginning of a struct field. * @param {string} name - The name of the field. * @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) { this.tpos.push(this.tstack.length); this.tstack.push({ fieldId: '"' + fieldId + '"', fieldType: TJSONProtocol.Type[fieldType], }); }; /** * Serializes the end of a field. */ 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) + "}"; } else { this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = "{" + fieldInfo.fieldType + ":" + value + "}"; } this.tpos.pop(); this.writeToTransportIfStackIsFlushable(); }; /** * Serializes the end of the set of fields for a struct. */ TJSONProtocol.prototype.writeFieldStop = function () {}; /** * Serializes the beginning of a map collection. * @param {Thrift.Type} keyType - The data type of the key. * @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) { //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, ]); }; /** * Serializes the end of a map. */ TJSONProtocol.prototype.writeMapEnd = function () { var p = this.tpos.pop(); if (p == this.tstack.length) { return; } if ((this.tstack.length - p - 1) % 2 !== 0) { this.tstack.push(""); } var size = (this.tstack.length - p - 1) / 2; this.tstack[p][this.tstack[p].length - 1] = size; var map = "}"; var first = true; while (this.tstack.length > p + 1) { var v = this.tstack.pop(); var k = this.tstack.pop(); if (first) { first = false; } else { map = "," + map; } if (!isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings map = k + ":" + v + map; } map = "{" + map; this.tstack[p].push(map); this.tstack[p] = "[" + this.tstack[p].join(",") + "]"; this.writeToTransportIfStackIsFlushable(); }; /** * Serializes the beginning of a list collection. * @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) { this.tpos.push(this.tstack.length); this.tstack.push([TJSONProtocol.Type[elemType], size]); }; /** * Serializes the end of a list. */ TJSONProtocol.prototype.writeListEnd = function () { var p = this.tpos.pop(); while (this.tstack.length > p + 1) { var tmpVal = this.tstack[p + 1]; this.tstack.splice(p + 1, 1); this.tstack[p].push(tmpVal); } this.tstack[p] = "[" + this.tstack[p].join(",") + "]"; this.writeToTransportIfStackIsFlushable(); }; /** * Serializes the beginning of a set collection. * @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]); }; /** * Serializes the end of a set. */ TJSONProtocol.prototype.writeSetEnd = function () { var p = this.tpos.pop(); while (this.tstack.length > p + 1) { var tmpVal = this.tstack[p + 1]; this.tstack.splice(p + 1, 1); this.tstack[p].push(tmpVal); } this.tstack[p] = "[" + this.tstack[p].join(",") + "]"; this.writeToTransportIfStackIsFlushable(); }; /** Serializes a boolean */ TJSONProtocol.prototype.writeBool = function (bool) { this.tstack.push(bool ? 1 : 0); }; /** Serializes a number */ TJSONProtocol.prototype.writeByte = function (byte) { this.tstack.push(byte); }; /** Serializes a number */ TJSONProtocol.prototype.writeI16 = function (i16) { this.tstack.push(i16); }; /** Serializes a number */ TJSONProtocol.prototype.writeI32 = function (i32) { this.tstack.push(i32); }; /** Serializes a number */ TJSONProtocol.prototype.writeI64 = function (i64) { if (i64 instanceof Int64) { this.tstack.push(Int64Util.toDecimalString(i64)); } else { this.tstack.push(i64); } }; /** Serializes a number */ TJSONProtocol.prototype.writeDouble = function (dub) { this.tstack.push(dub); }; /** Serializes a string */ TJSONProtocol.prototype.writeString = function (arg) { // We do not encode uri components for wire transfer: if (arg === 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, ); } // 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 + '"'); } }; /** 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]" ) { var buf = arg; } else { throw new Error( "writeBinary called without a string/Buffer argument: " + arg, ); } this.tstack.push('"' + buf.toString("base64") + '"'); }; /** Serializes a UUID */ TJSONProtocol.prototype.writeUuid = function (arg) { this.tstack.push('"' + arg + '"'); }; /** * @class * @name AnonReadMessageBeginReturn * @property {string} fname - The name of the service method. * @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. * @returns {AnonReadMessageBeginReturn} */ TJSONProtocol.prototype.readMessageBegin = function () { this.rstack = []; this.rpos = []; //Borrow the inbound transport buffer and ensure data is present/consistent var transBuf = this.trans.borrow(); if (transBuf.readIndex >= transBuf.writeIndex) { throw new InputBufferUnderrunError(); } var cursor = transBuf.readIndex; if (transBuf.buf[cursor] !== 0x5b) { //[ throw new Error("Malformed JSON input, no opening bracket"); } //Parse a single message (there may be several in the buffer) // TODO: Handle characters using multiple code units cursor++; var openBracketCount = 1; var inString = false; for (; cursor < transBuf.writeIndex; cursor++) { 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) { //" inString = false; } else if (chr === 0x5c) { //\ //escaped character, skip cursor += 1; } } else { if (chr === 0x5b) { //[ openBracketCount += 1; } else if (chr === 0x5d) { //] openBracketCount -= 1; if (openBracketCount === 0) { //end of json message detected break; } } else if (chr === 0x22) { //" inString = true; } } } if (openBracketCount !== 0) { // Missing closing bracket. Can be buffer underrun. throw new InputBufferUnderrunError(); } //Reconstitute the JSON object and conume the necessary bytes 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); } //Objectify the thrift message {name/type/sequence-number} for return // and then save the JSON object in rstack var r = {}; r.fname = this.robj.shift(); r.mtype = this.robj.shift(); r.rseqid = this.robj.shift(); this.rstack.push(this.robj.shift()); return r; }; /** Deserializes the end of a message. */ 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 () { var r = {}; r.fname = ""; //incase this is an array of structs if (this.rstack[this.rstack.length - 1] instanceof Array) { this.rstack.push(this.rstack[this.rstack.length - 1].shift()); } return r; }; /** Deserializes the end of a struct. */ TJSONProtocol.prototype.readStructEnd = function () { this.rstack.pop(); }; /** * @class * @name AnonReadFieldBeginReturn * @property {string} fname - The name of the field (always ''). * @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. * @returns {AnonReadFieldBeginReturn} */ 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]) { if (f === null) { continue; } fid = parseInt(f, 10); this.rpos.push(this.rstack.length); var field = this.rstack[this.rstack.length - 1][fid]; //remove so we don't see it again delete this.rstack[this.rstack.length - 1][fid]; this.rstack.push(field); break; } 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]) { if (TJSONProtocol.RType[i] === null) { continue; } ftype = TJSONProtocol.RType[i]; this.rstack[this.rstack.length - 1] = this.rstack[this.rstack.length - 1][i]; } } r.fname = ""; r.ftype = ftype; r.fid = fid; return r; }; /** Deserializes the end of a field. */ TJSONProtocol.prototype.readFieldEnd = function () { var pos = this.rpos.pop(); //get back to the right place in the stack while (this.rstack.length > pos) { this.rstack.pop(); } }; /** * @class * @name AnonReadMapBeginReturn * @property {Thrift.Type} ktype - The data type of the key. * @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. * @returns {AnonReadMapBeginReturn} */ TJSONProtocol.prototype.readMapBegin = function () { var map = this.rstack.pop(); var first = map.shift(); if (first instanceof Array) { this.rstack.push(map); map = first; first = map.shift(); } var r = {}; r.ktype = TJSONProtocol.RType[first]; r.vtype = TJSONProtocol.RType[map.shift()]; r.size = map.shift(); this.rpos.push(this.rstack.length); this.rstack.push(map.shift()); return r; }; /** Deserializes the end of a map. */ TJSONProtocol.prototype.readMapEnd = function () { this.readFieldEnd(); }; /** * @class * @name AnonReadColBeginReturn * @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. * @returns {AnonReadColBeginReturn} */ TJSONProtocol.prototype.readListBegin = function () { var list = this.rstack[this.rstack.length - 1]; var r = {}; r.etype = TJSONProtocol.RType[list.shift()]; r.size = list.shift(); this.rpos.push(this.rstack.length); this.rstack.push(list.shift()); return r; }; /** Deserializes the end of a list. */ TJSONProtocol.prototype.readListEnd = function () { var pos = this.rpos.pop() - 2; var st = this.rstack; st.pop(); if (st instanceof Array && st.length > pos && st[pos].length > 0) { st.push(st[pos].shift()); } }; /** * Deserializes the beginning of a set. * @returns {AnonReadColBeginReturn} */ TJSONProtocol.prototype.readSetBegin = function () { return this.readListBegin(); }; /** Deserializes the end of a set. */ TJSONProtocol.prototype.readSetEnd = function () { return this.readListEnd(); }; TJSONProtocol.prototype.readBool = function () { return this.readValue() == "1"; }; TJSONProtocol.prototype.readByte = function () { return this.readI32(); }; TJSONProtocol.prototype.readI16 = function () { return this.readI32(); }; TJSONProtocol.prototype.readI32 = function (f) { return +this.readValue(); }; /** Returns the next value found in the protocol buffer */ TJSONProtocol.prototype.readValue = function (f) { if (f === undefined) { f = this.rstack[this.rstack.length - 1]; } var r = {}; if (f instanceof Array) { if (f.length === 0) { r.value = undefined; } else { r.value = f.shift(); } } else if (!(f instanceof Int64) && f instanceof Object) { for (var i in f) { if (i === null) { continue; } this.rstack.push(f[i]); delete f[i]; r.value = i; break; } } else { r.value = f; this.rstack.pop(); } return r.value; }; 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 { return new Int64(n); } }; TJSONProtocol.prototype.readDouble = function () { return this.readI32(); }; TJSONProtocol.prototype.readBinary = function () { return new Buffer(this.readValue(), "base64"); }; TJSONProtocol.prototype.readString = function () { return this.readValue(); }; TJSONProtocol.prototype.readUuid = function() { return this.readValue(); }; /** * Returns the underlying transport. * @readonly * @returns {Thrift.Transport} The underlying transport. */ TJSONProtocol.prototype.getTransport = function () { return this.trans; }; /** * Method to arbitrarily skip over data */ TJSONProtocol.prototype.skip = function (type, depth) { depth = (depth || 0) + 1; if (depth > 64) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.DEPTH_LIMIT, "Maximum skip depth exceeded" ); } switch (type) { case Type.BOOL: this.readBool(); break; case Type.BYTE: this.readByte(); break; case Type.I16: this.readI16(); break; case Type.I32: this.readI32(); break; case Type.I64: this.readI64(); break; case Type.DOUBLE: this.readDouble(); break; case Type.STRING: this.readString(); break; case Type.UUID: this.readUuid(); break; case Type.STRUCT: this.readStructBegin(); while (true) { var r = this.readFieldBegin(); if (r.ftype === Type.STOP) { break; } this.skip(r.ftype, depth); this.readFieldEnd(); } this.readStructEnd(); break; case Type.MAP: var mapBegin = this.readMapBegin(); for (var i = 0; i < mapBegin.size; ++i) { this.skip(mapBegin.ktype, depth); this.skip(mapBegin.vtype, depth); } this.readMapEnd(); break; case Type.SET: var setBegin = this.readSetBegin(); for (var i2 = 0; i2 < setBegin.size; ++i2) { this.skip(setBegin.etype, depth); } this.readSetEnd(); break; case Type.LIST: var listBegin = this.readListBegin(); for (var i3 = 0; i3 < listBegin.size; ++i3) { this.skip(listBegin.etype, depth); } this.readListEnd(); break; default: throw new Error("Invalid type: " + type); } }; thrift-0.23.0/lib/nodejs/lib/thrift/multiplexed_processor.js0000664000175000017500000000365315165535636024473 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var Thrift = require("./thrift"); exports.MultiplexedProcessor = MultiplexedProcessor; function MultiplexedProcessor(stream, options) { this.services = {}; } MultiplexedProcessor.prototype.registerProcessor = function (name, handler) { this.services[name] = handler; }; 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", ); } 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, ); } //construct a proxy object which stubs the readMessageBegin //for the service var inpProxy = {}; for (var attr in inp) { inpProxy[attr] = inp[attr]; } inpProxy.readMessageBegin = function () { return { fname: fname, mtype: begin.mtype, rseqid: begin.rseqid, }; }; this.services[sname].process(inpProxy, out); }; thrift-0.23.0/lib/nodejs/lib/thrift/log.js0000664000175000017500000000432215165535636020613 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var disabled = function () {}; var logFunc = console.log; 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)); return logFunc(util.format.apply(null, args)); }; } var trace = disabled; var debug = disabled; var error = disabled; var warning = disabled; var info = disabled; exports.setLogFunc = function (func) { logFunc = func; }; 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"); } }); // set default setLogLevel(logLevel); exports.getLogLevel = function () { return logLevel; }; exports.trace = function () { return trace.apply(null, arguments); }; exports.debug = function () { return debug.apply(null, arguments); }; exports.error = function () { return error.apply(null, arguments); }; exports.warning = function () { return warning.apply(null, arguments); }; exports.info = function () { return info.apply(null, arguments); }; thrift-0.23.0/lib/nodejs/lib/thrift/server.js0000664000175000017500000001134215165535636021340 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var 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"); /** * Create a Thrift server which can serve one or multiple services. * @param {object} processor - A normal or multiplexedProcessor (must * be preconstructed with the desired handler). * @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; function serverImpl(stream) { var self = this; 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.write(buf); } catch (err) { self.emit("error", err); stream.end(); } }; var output = new protocol(new transport(undefined, outputCb)); // Read and write need to be performed on the same transport // for THeaderProtocol because we should only respond with // headers if the request contains headers if (protocol === THeaderProtocol) { output = input; output.trans.onFlush = outputCb; } try { do { 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.end(); }); } if (options && 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; } return tls.createServer(options.tls, serverImpl); } else { return net.createServer(serverImpl); } }; /** * Create a single service Apache Thrift server. * @param {object} processor - A service class or processor function. * @param {ServerOptions} options - Optional additional server configuration. * @returns {object} - The Apache Thrift Multiplex Server. */ exports.createServer = function (processor, handler, options) { if (processor.Processor) { processor = processor.Processor; } return exports.createMultiplexServer(new processor(handler), options); }; thrift-0.23.0/lib/nodejs/lib/thrift/json_parse.js0000664000175000017500000001423515165535636022201 0ustar00buildbuild00000000000000/* * Imported from Douglas Crockford's reference implementation with minimum modification * to handle Int64. * * https://github.com/douglascrockford/JSON-js/blob/c98948ae1944a28e2e8ebc3717894e580aeaaa05/json_parse.js * * Original license header: * * json_parse.js * 2015-05-02 * Public Domain. * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. */ /*jslint for */ /*property at, b, call, charAt, f, fromCharCode, hasOwnProperty, message, n, name, 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(); } } 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; } uffff = uffff * 16 + hex; } string += String.fromCharCode(uffff); } else if (typeof escapee[ch] === "string") { string += escapee[ch]; } else { break; } } 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(); 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. 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; }; })()); thrift-0.23.0/lib/nodejs/lib/thrift/xhr_connection.js0000664000175000017500000002176215167543515023056 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var EventEmitter = require("events").EventEmitter; var thrift = require("./thrift"); var TBufferedTransport = require("./buffered_transport"); var TJSONProtocol = require("./json_protocol"); var InputBufferUnderrunError = require("./input_buffer_underrun_error"); var createClient = require("./create_client"); exports.XHRConnection = XHRConnection; /** * Constructor Function for the XHR Connection. * If you do not specify a host and port then XHRConnection will default to the * host and port of the page from which this javascript is served. * @constructor * @param {string} [url] - The URL to connect to. * @classdesc TXHRConnection objects provide Thrift end point transport * semantics implemented using XHR. * @example * var transport = new Thrift.TXHRConnection('localhost', 9099, {}); */ 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.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 || "/"; if (port === "") { port = undefined; } if (!port || port === 80 || port === "80") { this.url = prefix + host + path; } else { 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) {} throw "Your browser doesn't support XHR."; }; /** * Sends the current XRH request if the transport was created with a URL * and the async parameter is false. If the transport was not created with * a URL, or the async parameter is True and no callback is provided, 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 {object} callback - Optional async completion callback * @returns {undefined|string} Nothing or the current send buffer. * @throws {string} If XHR fails. */ XHRConnection.prototype.flush = function () { var self = this; if (this.url === undefined || this.url === "") { return this.send_buf; } var xreq = this.getXmlHttpRequestObject(); if (this.protocol == TJSONProtocol) { xreq.overrideMimeType('application/json'); } else { xreq.responseType = 'arraybuffer'; xreq.overrideMimeType('application/octet-stream'); } xreq.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { if(self.protocol == TJSONProtocol) { self.setRecvBuffer(this.responseText); } else { self.setRecvBuffer(this.response); } } }; xreq.ontimeout = function(error) { self.emit("error", error); }; xreq.onerror = function(error) { self.emit("error", error); }; xreq.open("POST", this.url, true); if (this.options.timeout) xreq.timeout = this.options.timeout; Object.keys(this.headers).forEach(function (headerKey) { xreq.setRequestHeader(headerKey, self.headers[headerKey]); }); xreq.send(this.send_buf); }; /** * Sets the buffer to provide the protocol when deserializing. * @param {string} buf - The buffer to supply the protocol. */ XHRConnection.prototype.setRecvBuffer = function (buf) { this.recv_buf = buf; this.recv_buf_sz = this.recv_buf.length; this.wpos = this.recv_buf.length; this.rpos = 0; if (Object.prototype.toString.call(buf) == "[object ArrayBuffer]") { var data = new Uint8Array(buf); } var thing = new Buffer(data || buf); this.transport.receiver(this.__decodeCallback.bind(this))(thing); }; XHRConnection.prototype.__decodeCallback = function (transport_with_data) { var proto = new this.protocol(transport_with_data); try { while (true) { var header = proto.readMessageBegin(); var dummy_seqid = header.rseqid * -1; var client = this.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 client var 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 = this.seqId2Service[header.rseqid]; if (service_name) { client = this.client[service_name]; delete this.seqId2Service[header.rseqid]; } /*jshint -W083 */ client._reqs[dummy_seqid] = function (err, success) { transport_with_data.commitPosition(); var clientCallback = client._reqs[header.rseqid]; delete client._reqs[header.rseqid]; if (clientCallback) { clientCallback(err, success); } }; /*jshint +W083 */ if (client["recv_" + header.fname]) { client["recv_" + header.fname](proto, header.mtype, dummy_seqid); } else { delete client._reqs[dummy_seqid]; this.emit( "error", new thrift.TApplicationException( thrift.TApplicationExceptionType.WRONG_METHOD_NAME, "Received a response to an unknown RPC function", ), ); } } } catch (e) { if (e instanceof InputBufferUnderrunError) { transport_with_data.rollbackPosition(); } else { throw e; } } }; /** * Returns true if the transport is open, XHR always returns true. * @readonly * @returns {boolean} Always True. */ XHRConnection.prototype.isOpen = function () { return true; }; /** * Opens the transport connection, with XHR this is a nop. */ XHRConnection.prototype.open = function () {}; /** * Closes the transport connection, with XHR this is a nop. */ XHRConnection.prototype.close = function () {}; /** * Returns the specified number of characters from the response * buffer. * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ XHRConnection.prototype.read = function (len) { var avail = this.wpos - this.rpos; if (avail === 0) { return ""; } var give = len; if (avail < len) { give = avail; } var ret = this.read_buf.substr(this.rpos, give); this.rpos += give; //clear buf when complete? return ret; }; /** * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ XHRConnection.prototype.readAll = function () { return this.recv_buf; }; /** * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ XHRConnection.prototype.write = function (buf) { this.send_buf = buf; this.flush(); }; /** * Returns the send buffer. * @readonly * @returns {string} The send buffer. */ XHRConnection.prototype.getSendBuffer = function () { return this.send_buf; }; /** * Creates a new TXHRTransport object, used by Thrift clients to connect * to Thrift HTTP based servers. * @param {string} host - The host name or IP to connect to. * @param {number} port - The TCP port to connect to. * @param {XHRConnectOptions} options - The configuration options to use. * @returns {XHRConnection} The connection object. * @see {@link XHRConnectOptions} */ exports.createXHRConnection = function (host, port, options) { return new XHRConnection(host, port, options); }; exports.createXHRClient = createClient; thrift-0.23.0/lib/nodejs/lib/thrift/web_server.js0000664000175000017500000005112215170007142022153 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var 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 MultiplexedProcessor = require("./multiplexed_processor").MultiplexedProcessor; function sanitizeHeader(value) { return (value || "").replace(/[\r\n]/g, ""); } var TBufferedTransport = require("./buffered_transport"); var TBinaryProtocol = require("./binary_protocol"); var InputBufferUnderrunError = require("./input_buffer_underrun_error"); // WSFrame constructor and prototype ///////////////////////////////////////////////////////////////////// /** Apache Thrift RPC Web Socket Transport * Frame layout conforming to RFC 6455 circa 12/2011 * * Theoretical frame size limit is 4GB*4GB, however the Node Buffer * limit is 1GB as of v0.10. The frame length encoding is also * configured for a max of 4GB presently and needs to be adjusted * if Node/Browsers become capabile of > 4GB frames. * * - FIN is 1 if the message is complete * - RSV1/2/3 are always 0 * - Opcode is 1(TEXT) for TJSONProtocol and 2(BIN) for TBinaryProtocol * - Mask Present bit is 1 sending to-server and 0 sending to-client * - Payload Len: * + If < 126: then represented directly * + If >=126: but within range of an unsigned 16 bit integer * then Payload Len is 126 and the two following bytes store * the length * + Else: Payload Len is 127 and the following 8 bytes store the * length as an unsigned 64 bit integer * - Masking key is a 32 bit key only present when sending to the server * - Payload follows the masking key or length * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-------+-+-------------+-------------------------------+ * |F|R|R|R| opcode|M| Payload len | Extended payload length | * |I|S|S|S| (4) |A| (7) | (16/64) | * |N|V|V|V| |S| | (if payload len==126/127) | * | |1|2|3| |K| | | * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + * | Extended payload length continued, if payload len == 127 | * + - - - - - - - - - - - - - - - +-------------------------------+ * | |Masking-key, if MASK set to 1 | * +-------------------------------+-------------------------------+ * | Masking-key (continued) | Payload Data | * +-------------------------------- - - - - - - - - - - - - - - - + * : Payload Data continued ... : * + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * | Payload Data continued ... | * +---------------------------------------------------------------+ */ var wsFrame = { /** Encodes a WebSocket frame * * @param {Buffer} data - The raw data to encode * @param {Buffer} mask - The mask to apply when sending to server, null for no mask * @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 = Buffer.alloc(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; }, /** * @class * @name WSDecodeResult * @property {Buffer} data - The decoded data for the first ATRPC message * @property {Buffer} mask - The frame mask * @property {Boolean} binEncoding - True if binary (TBinaryProtocol), * False if text (TJSONProtocol) * @property {Buffer} nextFrame - Multiple ATRPC messages may be sent in a * single WebSocket frame, this Buffer contains * any bytes remaining to be decoded * @property {Boolean} FIN - True is the message is complete */ /** 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. * @returns {WSDecodeResult} - The decoded payload * * @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 = Buffer.alloc(4); frame.copy(result.mask, 0, dataOffset, dataOffset + 4); dataOffset += 4; } //Payload result.data = Buffer.alloc(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 = Buffer.alloc(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; }, /** Masks/Unmasks data * * @param {Buffer} data - data to mask/unmask in place * @param {Buffer} mask - the 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]; } }, /** Computes frame size on the wire from data to be sent * * @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) { var headerSize = 10; if (data.length < 0x7e) { headerSize = 2; } else if (data.length < 0xffff) { headerSize = 4; } return headerSize + data.length + (mask ? 4 : 0); }, frameOpCodes: { CONT: 0x00, TEXT: 0x01, BIN: 0x02, CTRL: 0x80, }, mask: { TO_SERVER: 0x80, TO_CLIENT: 0x00, }, fin: { CONT: 0x00, FIN: 0x80, }, }; // createWebServer constructor and options ///////////////////////////////////////////////////////////////////// /** * @class * @name ServerOptions * @property {array} cors - Array of CORS origin strings to permit requests from. * @property {string} files - Path to serve static files from, if absent or "" * static file service is disabled. * @property {object} headers - An object hash mapping header strings to header value * strings, these headers are transmitted in response to * static file GET operations. * @property {object} services - An object hash mapping service URI strings * to ServiceOptions objects * @property {object} tls - Node.js TLS options (see: nodejs.org/api/tls.html), * if not present or null regular http is used, * at least a key and a cert must be defined to use SSL/TLS * @see {@link ServiceOptions} */ /** * @class * @name ServiceOptions * @property {object} transport - The layered transport to use (defaults * to TBufferedTransport). * @property {object} protocol - The serialization Protocol to use (defaults to * TBinaryProtocol). * @property {object} processor - The Thrift Service class/processor generated * by the IDL Compiler for the service (the "cls" * key can also be used for this attribute). * @property {object} handler - The handler methods for the Thrift Service. */ /** * Create a Thrift server which can serve static files and/or one or * more Thrift Services. * @param {ServerOptions} options - The server configuration. * @returns {object} - The Apache Thrift Web Server. */ 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", }; //Setup all of the services var services = options.services; for (var uri in services) { var svcObj = services[uri]; //Setup the processor if (svcObj.processor instanceof MultiplexedProcessor) { //Multiplex processors have pre embedded processor/handler pairs, save as is svcObj.processor = svcObj.processor; } else { //For historical reasons Node.js supports processors passed in directly or via the // 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; //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 if (svcObj.handler) { svcObj.processor = new processor(svcObj.handler); } else { svcObj.processor = processor; } } svcObj.transport = svcObj.transport ? svcObj.transport : TBufferedTransport; svcObj.protocol = svcObj.protocol ? svcObj.protocol : TBinaryProtocol; } //Verify CORS requirements function VerifyCORSAndSetHeaders(request, response) { 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-max-age", "60"); return true; } else { //Disallow, origin denied return false; } } //Allow, CORS is not in use return true; } //Handle OPTIONS method (CORS) /////////////////////////////////////////////////// function processOptions(request, response) { if (VerifyCORSAndSetHeaders(request, response)) { response.writeHead("204", "No Content", { "content-length": 0 }); } else { response.writeHead( "403", "Origin " + request.headers.origin + " not allowed", {}, ); } response.end(); } //Handle POST methods (TXHRTransport) /////////////////////////////////////////////////// function processPost(request, response) { //Lookup service var uri = url.parse(request.url).pathname; var svc = services[uri]; if (!svc) { response.writeHead("403", "No Apache Thrift Service at " + uri, {}); response.end(); return; } //Verify CORS requirements if (!VerifyCORSAndSetHeaders(request, response)) { 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) { try { response.writeHead(200); response.end(buf); } 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(); } } }), ); } //Handle GET methods (Static Page Server) /////////////////////////////////////////////////// function processGet(request, response) { //Undefined or empty base directory means do not serve static files if (!baseDir || "" === baseDir) { response.writeHead(404); response.end(); return; } //Verify CORS requirements if (!VerifyCORSAndSetHeaders(request, response)) { response.writeHead( "403", "Origin " + request.headers.origin + " not allowed", {}, ); response.end(); return; } //Locate the file requested and send it var uri = url.parse(request.url).pathname; var filename = path.resolve(path.join(baseDir, uri)); //Ensure the basedir path is not able to be escaped var normalizedBase = baseDir.endsWith(path.sep) ? baseDir : baseDir + path.sep; if (filename !== baseDir && filename.indexOf(normalizedBase) !== 0) { response.writeHead(400, "Invalid request path", {}); response.end(); return; } fs.exists(filename, function (exists) { if (!exists) { response.writeHead(404); response.end(); return; } if (fs.statSync(filename).isDirectory()) { filename += "/index.html"; } fs.readFile(filename, "binary", function (err, file) { if (err) { response.writeHead(500); response.end(err + "\n"); return; } var headers = {}; var contentType = contentTypesByExtension[path.extname(filename)]; if (contentType) { headers["Content-Type"] = contentType; } for (var k in options.headers) { headers[k] = options.headers[k]; } response.writeHead(200, headers); response.write(file, "binary"); response.end(); }); }); } //Handle WebSocket calls (TWebSocketTransport) /////////////////////////////////////////////////// function processWS(data, socket, svc, binEncoding) { 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 } }), ); try { svc.processor.process(input, output); transportWithData.commitPosition(); } catch (err) { if (err instanceof InputBufferUnderrunError) { transportWithData.rollbackPosition(); } else { //TODO: Add better error processing } } })(data); } //Create the server (HTTP or HTTPS) var server = null; if (options.tls) { server = https.createServer(options.tls); } else { server = http.createServer(); } //Wire up listeners for upgrade(to WebSocket) & request methods for: // - 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) { //Verify CORS origin for WebSocket upgrades if (request.headers.origin && options.cors) { if (!options.cors["*"] && !options.cors[request.headers.origin]) { socket.write("HTTP/1.1 403 Origin not allowed\r\n\r\n"); socket.destroy(); return; } } //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", ); var origin = sanitizeHeader(request.headers.origin); var host = sanitizeHeader(request.headers.host); var reqUrl = sanitizeHeader(request.url); 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: " + origin + "\r\n" + "Sec-WebSocket-Location: ws://" + host + reqUrl + "\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 = Buffer.alloc(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 { data = result.data; } //Prepare next frame for decoding (if any) frame = result.nextFrame; } } catch (e) { log.error("TWebSocketTransport Exception: " + e); socket.destroy(); } }); }); //Return the server return server; }; thrift-0.23.0/lib/nodejs/lib/thrift/thrift.js0000664000175000017500000001256315167543515021335 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var Type = (exports.Type = { STOP: 0, VOID: 1, BOOL: 2, BYTE: 3, I08: 3, DOUBLE: 4, I16: 6, I32: 8, I64: 10, STRING: 11, UTF7: 11, STRUCT: 12, MAP: 13, SET: 14, LIST: 15, UUID: 16, }); exports.MessageType = { CALL: 1, REPLY: 2, EXCEPTION: 3, ONEWAY: 4, }; exports.TException = TException; function TException(message) { Error.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.message = message; } util.inherits(TException, Error); var TApplicationExceptionType = (exports.TApplicationExceptionType = { UNKNOWN: 0, UNKNOWN_METHOD: 1, INVALID_MESSAGE_TYPE: 2, WRONG_METHOD_NAME: 3, BAD_SEQUENCE_ID: 4, MISSING_RESULT: 5, INTERNAL_ERROR: 6, PROTOCOL_ERROR: 7, INVALID_TRANSFORM: 8, INVALID_PROTOCOL: 9, UNSUPPORTED_CLIENT_TYPE: 10, }); exports.TApplicationException = TApplicationException; function TApplicationException(type, message) { TException.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.type = type || TApplicationExceptionType.UNKNOWN; this.name = this.constructor.name; this.message = message; } util.inherits(TApplicationException, TException); TApplicationException.prototype[Symbol.for("read")] = TApplicationException.prototype.read = function (input) { var ftype; var ret = input.readStructBegin("TApplicationException"); while (1) { ret = input.readFieldBegin(); 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; } input.readFieldEnd(); } input.readStructEnd(); }; TApplicationException.prototype[Symbol.for("write")] = TApplicationException.prototype.write = function (output) { output.writeStructBegin("TApplicationException"); if (this.message) { output.writeFieldBegin("message", Type.STRING, 1); output.writeString(this.message); output.writeFieldEnd(); } if (this.code) { output.writeFieldBegin("type", Type.I32, 2); output.writeI32(this.code); output.writeFieldEnd(); } output.writeFieldStop(); output.writeStructEnd(); }; var TProtocolExceptionType = (exports.TProtocolExceptionType = { UNKNOWN: 0, INVALID_DATA: 1, NEGATIVE_SIZE: 2, SIZE_LIMIT: 3, BAD_VERSION: 4, NOT_IMPLEMENTED: 5, DEPTH_LIMIT: 6, }); exports.TProtocolException = TProtocolException; function TProtocolException(type, message) { Error.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.type = type; this.message = message; } util.inherits(TProtocolException, Error); exports.objectLength = function (obj) { return Object.keys(obj).length; }; exports.inherits = function (constructor, superConstructor) { util.inherits(constructor, superConstructor); }; var copyList, copyMap; copyList = function (lst, types) { if (!lst) { return lst; } var type; if (types.shift === undefined) { type = types; } else { type = types[0]; } var Type = type; 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) { result.push(type(val, types.slice(1))); } else { result.push(new Type(val)); } } return result; }; copyMap = function (obj, types) { if (!obj) { return obj; } var type; if (types.shift === undefined) { type = types; } else { type = types[0]; } var Type = type; 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) { result[prop] = type(val, types.slice(1)); } else { result[prop] = new Type(val); } } } return result; }; module.exports.copyMap = copyMap; module.exports.copyList = copyList; thrift-0.23.0/lib/nodejs/lib/thrift/header_transport.js0000664000175000017500000002415015165535636023377 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var TCompactProtocol = require("./compact_protocol"); var TBinaryProtocol = require("./binary_protocol"); var InputBufferUnderrunError = require("./input_buffer_underrun_error"); function THeaderTransportError(message) { Error.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.message = message; } util.inherits(THeaderTransportError, Error); module.exports = THeaderTransport; // from HeaderFormat.md var COMPACT_PROTOCOL_OFFSET = 0; var COMPACT_PROTOCOL_VERSION_OFFSET = 1; var FRAME_SIZE_OFFSET = 0; var HEADER_MAGIC_OFFSET = 32 / 8; var FLAGS_OFFSET = 48 / 8; var SEQID_OFFSET = 64 / 8; var HEADER_SIZE_OFFSET = 96 / 8; var HEADER_START_OFFSET = 112 / 8; var HEADER_MAGIC = 0x0fff; var TINFO_HEADER_KEY_VALUE_TYPE = 0x01; var MAX_FRAME_SIZE = 0x3fffffff; // A helper class for reading/writing varints. Uses // TCompactProtocol under the hood function VarintHelper(readBuffer) { var TBufferedTransport = require("./buffered_transport"); this.outputBuffer = null; var _this = this; this.transport = new TBufferedTransport(null, function (output) { _this.outputBuffer = output; }); this.transport.inBuf = readBuffer || Buffer.alloc(0); this.transport.writeCursor = this.transport.inBuf.length; this.protocol = new TCompactProtocol(this.transport); } VarintHelper.prototype.readVarint32 = function () { return this.protocol.readVarint32(); }; VarintHelper.prototype.writeVarint32 = function (i) { this.protocol.writeVarint32(i); }; VarintHelper.prototype.readString = function () { return this.protocol.readString(); }; VarintHelper.prototype.writeString = function (str) { this.protocol.writeString(str); }; VarintHelper.prototype.getOutCount = function () { return this.transport.outCount; }; VarintHelper.prototype.write = function (str) { this.transport.write(str); }; VarintHelper.prototype.toBuffer = function () { this.transport.flush(); return this.outputBuffer; }; // from lib/cpp/src/thrift/protocol/TProtocolTypes.h THeaderTransport.SubprotocolId = { BINARY: 0, JSON: 1, COMPACT: 2, }; /** An abstract transport used as a prototype for other transports to enable reading/writing theaders. This should NOT be used as a standalone transport The methods in this transport are called by THeaderProtocol, which will call readHeaders/writeHeaders in the read/writeMessageBegin methods and parse/write headers to/from a request prior to reading/writing. The reason this is not a standalone transport type is because different transport types have their own individual static receiver methods that are called prior to instantiation. There doesn't seem to be a way for THeaderTransport to know which receiver method to use without reworking the server API. For reading headers from a request, the parsed headers can be retrieved via getReadHeader. Similarly, you can set headers to be written on the client via setWriteHeader. */ function THeaderTransport() { this.maxFrameSize = MAX_FRAME_SIZE; this.protocolId = THeaderTransport.SubprotocolId.BINARY; this.rheaders = {}; this.wheaders = {}; this.inBuf = Buffer.alloc(0); this.outCount = 0; this.flags = null; this.seqid = 0; this.shouldWriteHeaders = true; } var validateHeaders = function (key, value) { if (typeof key !== "string" || typeof value !== "string") { throw new THeaderTransportError("Header key and values must be strings"); } }; var validateProtocolId = function (protocolId) { var protocols = Object.keys(THeaderTransport.SubprotocolId); for (var i = 0; i < protocols.length; i++) { if (protocolId === THeaderTransport.SubprotocolId[protocols[i]]) return true; } throw new Error(protocolId + " is not a valid protocol id"); }; THeaderTransport.prototype.setSeqId = function (seqid) { this.seqid = seqid; }; THeaderTransport.prototype.getSeqId = function (seqid) { return this.seqid; }; THeaderTransport.prototype.setFlags = function (flags) { this.flags = flags; }; THeaderTransport.prototype.getReadHeaders = function () { return this.rheaders; }; THeaderTransport.prototype.setReadHeader = function (key, value) { validateHeaders(key, value); this.rheaders[key] = value; }; THeaderTransport.prototype.clearReadHeaders = function () { this.rheaders = {}; }; THeaderTransport.prototype.getWriteHeaders = function () { return this.wheaders; }; THeaderTransport.prototype.setWriteHeader = function (key, value) { validateHeaders(key, value); this.wheaders[key] = value; }; THeaderTransport.prototype.clearWriteHeaders = function () { this.wheaders = {}; }; THeaderTransport.prototype.setMaxFrameSize = function (frameSize) { this.maxFrameSize = frameSize; }; THeaderTransport.prototype.setProtocolId = function (protocolId) { validateProtocolId(protocolId); this.protocolId = protocolId; }; THeaderTransport.prototype.getProtocolId = function () { return this.protocolId; }; var isUnframedBinary = function (readBuffer) { var version = readBuffer.readInt32BE(); return (version & TBinaryProtocol.VERSION_MASK) === TBinaryProtocol.VERSION_1; }; var isUnframedCompact = function (readBuffer) { var protocolId = readBuffer.readInt8(COMPACT_PROTOCOL_OFFSET); var version = readBuffer.readInt8(COMPACT_PROTOCOL_VERSION_OFFSET); return ( protocolId === TCompactProtocol.PROTOCOL_ID && (version & TCompactProtocol.VERSION_MASK) === TCompactProtocol.VERSION_N ); }; THeaderTransport.prototype.readHeaders = function () { var readBuffer = this.inBuf; var isUnframed = false; if (isUnframedBinary(readBuffer)) { this.setProtocolId(THeaderTransport.SubprotocolId.BINARY); isUnframed = true; } if (isUnframedCompact(readBuffer)) { this.setProtocolId(THeaderTransport.SubprotocolId.COMPACT); isUnframed = true; } if (isUnframed) { this.shouldWriteHeaders = false; return; } var frameSize = readBuffer.readInt32BE(FRAME_SIZE_OFFSET); if (frameSize > this.maxFrameSize) { throw new THeaderTransportError("Frame exceeds maximum frame size"); } var headerMagic = readBuffer.readInt16BE(HEADER_MAGIC_OFFSET); this.shouldWriteHeaders = headerMagic === HEADER_MAGIC; if (!this.shouldWriteHeaders) { return; } this.setFlags(readBuffer.readInt16BE(FLAGS_OFFSET)); this.setSeqId(readBuffer.readInt32BE(SEQID_OFFSET)); var headerSize = readBuffer.readInt16BE(HEADER_SIZE_OFFSET) * 4; var endOfHeaders = HEADER_START_OFFSET + headerSize; if (endOfHeaders > readBuffer.length) { throw new THeaderTransportError("Header size is greater than frame size"); } var headerBuffer = Buffer.alloc(headerSize); readBuffer.copy(headerBuffer, 0, HEADER_START_OFFSET, endOfHeaders); var varintHelper = new VarintHelper(headerBuffer); this.setProtocolId(varintHelper.readVarint32()); var transformCount = varintHelper.readVarint32(); if (transformCount > 0) { throw new THeaderTransportError("Transforms are not yet supported"); } while (true) { try { var headerType = varintHelper.readVarint32(); if (headerType !== TINFO_HEADER_KEY_VALUE_TYPE) { break; } var numberOfHeaders = varintHelper.readVarint32(); for (var i = 0; i < numberOfHeaders; i++) { var key = varintHelper.readString(); var value = varintHelper.readString(); this.setReadHeader(key, value); } } catch (e) { if (e instanceof InputBufferUnderrunError) { break; } throw e; } } // moves the read cursor past the headers this.read(endOfHeaders); return this.getReadHeaders(); }; THeaderTransport.prototype.writeHeaders = function () { // only write headers on the server if the client contained headers if (!this.shouldWriteHeaders) { return; } var headers = this.getWriteHeaders(); var varintWriter = new VarintHelper(); varintWriter.writeVarint32(this.protocolId); varintWriter.writeVarint32(0); // transforms not supported // writing info header key values var headerKeys = Object.keys(headers); if (headerKeys.length > 0) { varintWriter.writeVarint32(TINFO_HEADER_KEY_VALUE_TYPE); varintWriter.writeVarint32(headerKeys.length); for (var i = 0; i < headerKeys.length; i++) { var key = headerKeys[i]; var value = headers[key]; varintWriter.writeString(key); varintWriter.writeString(value); } } var headerSizeWithoutPadding = varintWriter.getOutCount(); var paddingNeeded = (4 - (headerSizeWithoutPadding % 4)) % 4; var headerSize = Buffer.alloc(2); headerSize.writeInt16BE( Math.floor((headerSizeWithoutPadding + paddingNeeded) / 4), ); var paddingBuffer = Buffer.alloc(paddingNeeded); paddingBuffer.fill(0x00); varintWriter.write(paddingBuffer); var headerContentBuffer = varintWriter.toBuffer(); var frameSize = Buffer.alloc(4); frameSize.writeInt32BE(10 + this.outCount + headerContentBuffer.length); var headerMagic = Buffer.alloc(2); headerMagic.writeInt16BE(HEADER_MAGIC); // flags are not yet supported, so write a zero var flags = Buffer.alloc(2); flags.writeInt16BE(0); var seqid = Buffer.alloc(4); seqid.writeInt32BE(this.getSeqId()); var headerBuffer = Buffer.concat([ frameSize, headerMagic, flags, seqid, headerSize, headerContentBuffer, ]); this.outBuffers.unshift(headerBuffer); this.outCount += headerBuffer.length; }; thrift-0.23.0/lib/nodejs/lib/thrift/protocol.js0000664000175000017500000000174015165535636021674 0ustar00buildbuild00000000000000/* * 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. */ module.exports.TBinaryProtocol = require("./binary_protocol"); module.exports.TCompactProtocol = require("./compact_protocol"); module.exports.TJSONProtocol = require("./json_protocol"); thrift-0.23.0/lib/nodejs/lib/thrift/transport.js0000664000175000017500000000177715165535636022101 0ustar00buildbuild00000000000000/* * 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. */ module.exports.TBufferedTransport = require("./buffered_transport"); module.exports.TFramedTransport = require("./framed_transport"); module.exports.InputBufferUnderrunError = require("./input_buffer_underrun_error"); thrift-0.23.0/lib/nodejs/lib/thrift/index.js0000664000175000017500000000622715165535636021147 0ustar00buildbuild00000000000000/* * 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. */ exports.Thrift = require("./thrift"); var log = require("./log"); exports.setLogFunc = log.setLogFunc; exports.setLogLevel = log.setLogLevel; exports.getLogLevel = log.getLogLevel; var connection = require("./connection"); exports.Connection = connection.Connection; exports.createClient = connection.createClient; exports.createConnection = connection.createConnection; exports.createUDSConnection = connection.createUDSConnection; exports.createSSLConnection = connection.createSSLConnection; exports.createStdIOClient = connection.createStdIOClient; exports.createStdIOConnection = connection.createStdIOConnection; var httpConnection = require("./http_connection"); exports.HttpConnection = httpConnection.HttpConnection; exports.createHttpConnection = httpConnection.createHttpConnection; exports.createHttpUDSConnection = httpConnection.createHttpUDSConnection; exports.createHttpClient = httpConnection.createHttpClient; var wsConnection = require("./ws_connection"); exports.WSConnection = wsConnection.WSConnection; exports.createWSConnection = wsConnection.createWSConnection; exports.createWSClient = wsConnection.createWSClient; var xhrConnection = require("./xhr_connection"); exports.XHRConnection = xhrConnection.XHRConnection; exports.createXHRConnection = xhrConnection.createXHRConnection; exports.createXHRClient = xhrConnection.createXHRClient; var server = require("./server"); exports.createServer = server.createServer; exports.createMultiplexServer = server.createMultiplexServer; var web_server = require("./web_server"); exports.createWebServer = web_server.createWebServer; exports.Int64 = require("node-int64"); exports.Q = require("q"); var mpxProcessor = require("./multiplexed_processor"); var mpxProtocol = require("./multiplexed_protocol"); exports.MultiplexedProcessor = mpxProcessor.MultiplexedProcessor; 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.TJSONProtocol = require("./json_protocol"); exports.TBinaryProtocol = require("./binary_protocol"); exports.TCompactProtocol = require("./compact_protocol"); exports.THeaderProtocol = require("./header_protocol"); exports.InputBufferUnderrunError = require("./input_buffer_underrun_error"); thrift-0.23.0/lib/nodejs/lib/thrift/int64_util.js0000664000175000017500000000634515165535636022042 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var Int64 = require("node-int64"); var Int64Util = (module.exports = {}); var POW2_24 = Math.pow(2, 24); var POW2_31 = Math.pow(2, 31); var POW2_32 = Math.pow(2, 32); var POW10_11 = Math.pow(10, 11); Int64Util.toDecimalString = function (i64) { var b = i64.buffer; var o = i64.offset; if ((!b[o] && !(b[o + 1] & 0xe0)) || (!~b[o] && !~(b[o + 1] & 0xe0))) { // The magnitude is small enough. return i64.toString(); } else { var negative = b[o] & 0x80; if (negative) { // 2's complement var incremented = false; var buffer = new Buffer(8); for (var i = 7; i >= 0; --i) { buffer[i] = (~b[o + i] + (incremented ? 0 : 1)) & 0xff; incremented |= b[o + i]; } b = buffer; } var high2 = b[o + 1] + (b[o] << 8); // Lesser 11 digits with exceeding values but is under 53 bits capacity. var low = b[o + 7] + (b[o + 6] << 8) + (b[o + 5] << 16) + b[o + 4] * POW2_24 + // Bit shift renders 32th bit as sign, so use multiplication (b[o + 3] + (b[o + 2] << 8)) * POW2_32 + high2 * 74976710656; // The literal is 2^48 % 10^11 // 12th digit and greater. var high = Math.floor(low / POW10_11) + high2 * 2814; // The literal is 2^48 / 10^11 // Make it exactly 11 with leading zeros. low = ("00000000000" + String(low % POW10_11)).slice(-11); return (negative ? "-" : "") + String(high) + low; } }; Int64Util.fromDecimalString = function (text) { var negative = text.charAt(0) === "-"; if (text.length < (negative ? 17 : 16)) { // The magnitude is smaller than 2^53. return new Int64(+text); } else if (text.length > (negative ? 20 : 19)) { 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 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 (negative) { // 2's complement high = ~high; if (low === 0) { high = (high + 1) & 0xffffffff; } else { low = ~low + 1; } high = 0x80000000 | high; } return new Int64(high, low); } }; thrift-0.23.0/lib/nodejs/lib/thrift/create_client.js0000664000175000017500000000361315165535636022635 0ustar00buildbuild00000000000000/* * 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. */ module.exports = createClient; /** * Creates a new client object for the specified Thrift service. * @param {object} ServiceClient - The module containing the generated service client * @param {Connection} Connection - The connection to use. * @returns {object} The client object. */ function createClient(ServiceClient, connection) { // TODO validate required options and throw otherwise if (ServiceClient.Client) { ServiceClient = ServiceClient.Client; } // TODO detangle these initialization calls // creating "client" requires // - new service client instance // // New service client instance requires // - new transport instance // - protocol class reference // // New transport instance requires // - Buffer to use (or none) // - Callback to call on flush // Wrap the write method var writeCb = function (buf, seqid) { connection.write(buf, seqid); }; var transport = new connection.transport(undefined, writeCb); var client = new ServiceClient(transport, connection.protocol); transport.client = client; connection.client = client; return client; } thrift-0.23.0/lib/nodejs/lib/thrift/binary_protocol.js0000664000175000017500000002427015170007142023221 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var log = require("./log"); var binary = require("./binary"); var Int64 = require("node-int64"); var Thrift = require("./thrift"); var Type = Thrift.Type; const { parse: uuidParse, stringify: uuidStringify } = require("uuid"); module.exports = TBinaryProtocol; // JavaScript supports only numeric doubles, therefore even hex values are always signed. // 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; TBinaryProtocol.VERSION_MASK = VERSION_MASK; TBinaryProtocol.VERSION_1 = VERSION_1; TBinaryProtocol.TYPE_MASK = TYPE_MASK; function TBinaryProtocol(trans, strictRead, strictWrite) { this.trans = trans; this.strictRead = strictRead !== undefined ? strictRead : false; this.strictWrite = strictWrite !== undefined ? strictWrite : true; this._seqid = null; } 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.writeMessageEnd = function () { if (this._seqid !== null) { this._seqid = null; } else { log.warning("No seqid to unset"); } }; TBinaryProtocol.prototype.writeStructBegin = function (name) {}; TBinaryProtocol.prototype.writeStructEnd = function () {}; TBinaryProtocol.prototype.writeFieldBegin = function (name, type, id) { this.writeByte(type); this.writeI16(id); }; TBinaryProtocol.prototype.writeFieldEnd = function () {}; TBinaryProtocol.prototype.writeFieldStop = function () { this.writeByte(Type.STOP); }; TBinaryProtocol.prototype.writeMapBegin = function (ktype, vtype, size) { this.writeByte(ktype); this.writeByte(vtype); this.writeI32(size); }; TBinaryProtocol.prototype.writeMapEnd = function () {}; TBinaryProtocol.prototype.writeListBegin = function (etype, size) { this.writeByte(etype); this.writeI32(size); }; TBinaryProtocol.prototype.writeListEnd = function () {}; TBinaryProtocol.prototype.writeSetBegin = function (etype, size) { this.writeByte(etype); this.writeI32(size); }; TBinaryProtocol.prototype.writeSetEnd = function () {}; TBinaryProtocol.prototype.writeBool = function (bool) { if (bool) { this.writeByte(1); } else { this.writeByte(0); } }; TBinaryProtocol.prototype.writeByte = function (b) { this.trans.write(new Buffer([b])); }; TBinaryProtocol.prototype.writeI16 = function (i16) { this.trans.write(binary.writeI16(new Buffer(2), i16)); }; TBinaryProtocol.prototype.writeI32 = function (i32) { this.trans.write(binary.writeI32(new Buffer(4), i32)); }; TBinaryProtocol.prototype.writeI64 = function (i64) { if (i64.buffer) { this.trans.write(i64.buffer); } else { this.trans.write(new Int64(i64).buffer); } }; 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") { 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]" ) { // 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); } }; TBinaryProtocol.prototype.writeString = function (arg) { this.writeStringOrBinary("writeString", "utf8", arg); }; TBinaryProtocol.prototype.writeBinary = function (arg) { this.writeStringOrBinary("writeBinary", "binary", arg); }; TBinaryProtocol.prototype.writeUuid = function (arg) { this.trans.write(Buffer.from(uuidParse(arg))); }; 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, ); } 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", ); } name = this.trans.read(sz); type = this.readByte(); seqid = this.readI32(); } return { fname: name, mtype: type, rseqid: seqid }; }; TBinaryProtocol.prototype.readMessageEnd = function () {}; TBinaryProtocol.prototype.readStructBegin = function () { return { fname: "" }; }; TBinaryProtocol.prototype.readStructEnd = function () {}; TBinaryProtocol.prototype.readFieldBegin = function () { var type = this.readByte(); if (type == Type.STOP) { return { fname: null, ftype: type, fid: 0 }; } var id = this.readI16(); return { fname: null, ftype: type, fid: id }; }; TBinaryProtocol.prototype.readFieldEnd = function () {}; TBinaryProtocol.prototype.readMapBegin = function () { var ktype = this.readByte(); var vtype = this.readByte(); var size = this.readI32(); return { ktype: ktype, vtype: vtype, size: size }; }; TBinaryProtocol.prototype.readMapEnd = function () {}; TBinaryProtocol.prototype.readListBegin = function () { var etype = this.readByte(); var size = this.readI32(); return { etype: etype, size: size }; }; TBinaryProtocol.prototype.readListEnd = function () {}; TBinaryProtocol.prototype.readSetBegin = function () { var etype = this.readByte(); var size = this.readI32(); return { etype: etype, size: size }; }; TBinaryProtocol.prototype.readSetEnd = function () {}; TBinaryProtocol.prototype.readBool = function () { var b = this.readByte(); if (b === 0) { return false; } return true; }; TBinaryProtocol.prototype.readByte = function () { return this.trans.readByte(); }; TBinaryProtocol.prototype.readI16 = function () { return this.trans.readI16(); }; TBinaryProtocol.prototype.readI32 = function () { return this.trans.readI32(); }; TBinaryProtocol.prototype.readI64 = function () { var buff = this.trans.read(8); return new Int64(buff); }; TBinaryProtocol.prototype.readDouble = function () { return this.trans.readDouble(); }; 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", ); } return this.trans.read(len); }; 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", ); } return this.trans.readString(len); }; TBinaryProtocol.prototype.readUuid = function () { const buf = this.trans.read(16); return uuidStringify(new Uint8Array(buf)); }; TBinaryProtocol.prototype.getTransport = function () { return this.trans; }; TBinaryProtocol.prototype.skip = function (type, depth) { depth = (depth || 0) + 1; if (depth > 64) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.DEPTH_LIMIT, "Maximum skip depth exceeded" ); } switch (type) { case Type.BOOL: this.readBool(); break; case Type.BYTE: this.readByte(); break; case Type.I16: this.readI16(); break; case Type.I32: this.readI32(); break; case Type.I64: this.readI64(); break; case Type.DOUBLE: this.readDouble(); break; case Type.STRING: this.readString(); break; case Type.UUID: this.readUuid(); break; case Type.STRUCT: this.readStructBegin(); while (true) { var r = this.readFieldBegin(); if (r.ftype === Type.STOP) { break; } this.skip(r.ftype, depth); this.readFieldEnd(); } this.readStructEnd(); break; case Type.MAP: var mapBegin = this.readMapBegin(); for (var i = 0; i < mapBegin.size; ++i) { this.skip(mapBegin.ktype, depth); this.skip(mapBegin.vtype, depth); } this.readMapEnd(); break; case Type.SET: var setBegin = this.readSetBegin(); for (var i2 = 0; i2 < setBegin.size; ++i2) { this.skip(setBegin.etype, depth); } this.readSetEnd(); break; case Type.LIST: var listBegin = this.readListBegin(); for (var i3 = 0; i3 < listBegin.size; ++i3) { this.skip(listBegin.etype, depth); } this.readListEnd(); break; default: throw new Error("Invalid type: " + type); } }; thrift-0.23.0/lib/nodejs/lib/thrift/ws_connection.js0000664000175000017500000002356515165535636022714 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var WebSocket = require("isomorphic-ws"); var EventEmitter = require("events").EventEmitter; var thrift = require("./thrift"); 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"); exports.WSConnection = WSConnection; /** * @class * @name WSConnectOptions * @property {string} transport - The Thrift layered transport to use (TBufferedTransport, etc). * @property {string} protocol - The Thrift serialization protocol to use (TJSONProtocol, etc.). * @property {string} path - The URL path to connect to (e.g. "/", "/mySvc", "/thrift/quoteSvc", etc.). * @property {object} headers - A standard Node.js header hash, an object hash containing key/value * pairs where the key is the header name string and the value is the header value string. * @property {boolean} secure - True causes the connection to use wss, otherwise ws is used. * @property {object} wsOptions - Options passed on to WebSocket. * @example * //Use a secured websocket connection * // uses the buffered transport layer, uses the JSON protocol and directs RPC traffic * // to wss://thrift.example.com:9090/hello * var thrift = require('thrift'); * var options = { * transport: thrift.TBufferedTransport, * protocol: thrift.TJSONProtocol, * path: "/hello", * secure: true * }; * var con = thrift.createWSConnection("thrift.example.com", 9090, options); * con.open() * var client = thrift.createWSClient(myService, connection); * client.myServiceFunction(); * con.close() */ /** * Initializes a Thrift WSConnection instance (use createWSConnection() rather than * instantiating directly). * @constructor * @param {string} host - The host name or IP to connect to. * @param {number} port - The TCP port to connect to. * @param {WSConnectOptions} options - The configuration options to use. * @throws {error} Exceptions other than ttransport.InputBufferUnderrunError are rethrown * @event {error} The "error" event is fired when a Node.js error event occurs during * request or response processing, in which case the node error is passed on. An "error" * event may also be fired when the connection can not map a response back to the * appropriate client (an internal error), generating a TApplicationException. * @classdesc WSConnection objects provide Thrift end point transport * semantics implemented using Websockets. * @see {@link createWSConnection} */ function WSConnection(host, port, options) { //Initialize the emitter base object EventEmitter.call(this); //Set configuration this.options = options || {}; this.host = host; this.port = port; this.secure = this.options.secure || false; this.transport = this.options.transport || TBufferedTransport; this.protocol = this.options.protocol || TJSONProtocol; this.path = this.options.path; this.send_pending = []; //The sequence map is used to map seqIDs back to the // calling client in multiplexed scenarios this.seqId2Service = {}; //Prepare WebSocket options this.wsOptions = { host: this.host, port: this.port || 80, 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 () { this.socket = null; //The web socket this.send_pending = []; //Buffers/Callback pairs waiting to be sent }; 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.socket.send(data); }, this); this.send_pending = []; } }; WSConnection.prototype.__onClose = function (evt) { this.emit("close"); this.__reset(); }; WSConnection.prototype.__decodeCallback = function (transport_with_data) { var proto = new this.protocol(transport_with_data); try { while (true) { var header = proto.readMessageBegin(); var dummy_seqid = header.rseqid * -1; var client = this.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 client var 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 = this.seqId2Service[header.rseqid]; if (service_name) { client = this.client[service_name]; delete this.seqId2Service[header.rseqid]; } /*jshint -W083 */ client._reqs[dummy_seqid] = function (err, success) { transport_with_data.commitPosition(); var clientCallback = client._reqs[header.rseqid]; delete client._reqs[header.rseqid]; if (clientCallback) { clientCallback(err, success); } }; /*jshint +W083 */ if (client["recv_" + header.fname]) { client["recv_" + header.fname](proto, header.mtype, dummy_seqid); } else { delete client._reqs[dummy_seqid]; this.emit( "error", new thrift.TApplicationException( thrift.TApplicationExceptionType.WRONG_METHOD_NAME, "Received a response to an unknown RPC function", ), ); } } } catch (e) { if (e instanceof InputBufferUnderrunError) { transport_with_data.rollbackPosition(); } else { throw e; } } }; 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) { this.__onData(evt.data); }; WSConnection.prototype.__onError = function (evt) { this.emit("error", evt); this.socket.close(); }; /** * Returns true if the transport is open * @readonly * @returns {boolean} */ WSConnection.prototype.isOpen = function () { return this.socket && this.socket.readyState === this.socket.OPEN; }; /** * Opens the transport connection */ WSConnection.prototype.open = function () { //If OPEN/CONNECTING/CLOSING ignore additional opens if (this.socket && this.socket.readyState !== this.socket.CLOSED) { return; } //If there is no socket or the socket is closed: if (jsEnv.isBrowser) { this.socket = new WebSocket(this.uri()); } else { this.socket = new WebSocket(this.uri(), "", this.wsOptions); } 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); this.socket.onclose = this.__onClose.bind(this); }; /** * Closes the transport connection */ WSConnection.prototype.close = function () { this.socket.close(); }; /** * Return URI for the connection * @returns {string} URI */ 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; } return schema + "://" + host + port + path; }; /** * Writes Thrift message data to the connection * @param {Buffer} data - A Node.js Buffer containing the data to write * @returns {void} No return value. * @event {error} the "error" event is raised upon request failure passing the * Node.js error object to the listener. */ WSConnection.prototype.write = function (data) { if (this.isOpen()) { //Send data and register a callback to invoke the client callback this.socket.send(data); } else { //Queue the send to go out __onOpen this.send_pending.push(data); } }; /** * Creates a new WSConnection object, used by Thrift clients to connect * to Thrift HTTP based servers. * @param {string} host - The host name or IP to connect to. * @param {number} port - The TCP port to connect to. * @param {WSConnectOptions} options - The configuration options to use. * @returns {WSConnection} The connection object. * @see {@link WSConnectOptions} */ exports.createWSConnection = function (host, port, options) { return new WSConnection(host, port, options); }; exports.createWSClient = createClient; thrift-0.23.0/lib/nodejs/lib/thrift/connection.js0000664000175000017500000003020615165535636022171 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var 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 createClient = require("./create_client"); var binary = require("./binary"); var Connection = (exports.Connection = function (stream, options) { var self = this; EventEmitter.call(this); this.seqId2Service = {}; this.connection = stream; this.ssl = stream.encrypted; this.options = options || {}; this.transport = this.options.transport || TBufferedTransport; this.protocol = this.options.protocol || TBinaryProtocol; this.offline_queue = []; this.connected = false; this.forceClose = false; 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; } 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; } 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; } 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(); self.emit("connect"); }, ); 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 ) { self.emit("error", err); } }); // Add a close listener this.connection.addListener("close", function () { self.connection_gone(); // handle close event. try to reconnect }); 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]; 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", ), ); } } } catch (e) { if (e instanceof InputBufferUnderrunError) { transport_with_data.rollbackPosition(); } else { self.emit("error", e); } } }), ); }); util.inherits(Connection, EventEmitter); Connection.prototype.end = function () { this.forceClose = true; this.connection.end(); }; Connection.prototype.destroy = function () { this.connection.destroy(); }; Connection.prototype.initialize_retry_vars = function () { this.retry_timer = null; this.retry_totaltime = 0; this.retry_delay = 150; this.retry_backoff = 1.7; this.attempts = 0; }; Connection.prototype.flush_offline_queue = function () { var self = this; var offline_queue = this.offline_queue; // Reset offline queue this.offline_queue = []; // Attempt to write queued items offline_queue.forEach(function (data) { self.write(data); }); }; Connection.prototype.write = function (data) { if (!this.connected) { this.offline_queue.push(data); return; } this.connection.write(data); }; Connection.prototype.connection_gone = function () { var self = this; this.connected = false; // If closed by manual, emit close event and cancel reconnect process if (this.forceClose) { if (this.retry_timer) { clearTimeout(this.retry_timer); this.retry_timer = null; } self.emit("close"); return; } // If a retry is already in progress, just let that happen if (this.retry_timer) { return; } // We cannot reconnect a secure socket. if (!this.max_attempts || this.ssl) { self.emit("close"); return; } 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); } log.debug("Retry connection in " + this.retry_delay + " ms"); 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.", ); self.emit("close"); return; } this.attempts += 1; this.emit("reconnecting", { delay: self.retry_delay, attempt: self.attempts, }); this.retry_timer = setTimeout(function () { log.debug("Retrying connection..."); 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; } if (self.path !== undefined) { self.connection.connect(self.path); } else { self.connection.connect(self.port, self.host); } self.retry_timer = null; }, this.retry_delay); }; exports.createConnection = function (host, port, options) { var stream = net.createConnection({ port: port, host: host, timeout: options.connect_timeout || options.timeout || 0, }); var connection = new Connection(stream, options); connection.host = host; connection.port = port; return connection; }; exports.createUDSConnection = function (path, options) { var stream = net.createConnection(path); var connection = new Connection(stream, options); connection.path = path; return connection; }; 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; } var stream = tls.connect(port, host, options); var connection = new Connection(stream, options); connection.host = host; connection.port = port; return connection; }; exports.createClient = createClient; 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 self = this; EventEmitter.call(this); this.connection = child.stdin; this.options = options || {}; this.transport = this.options.transport || TBufferedTransport; 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"); }); this.child.on("exit", function (code, signal) { log.debug(code + ":" + signal, "CHILD EXITED"); }); } this.frameLeft = 0; this.framePos = 0; this.frame = null; this.connected = true; self.flush_offline_queue(); this.connection.addListener("error", function (err) { self.emit("error", err); }); // Add a close listener 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); } }; 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 () { this.connection.end(); }; StdIOConnection.prototype.flush_offline_queue = function () { var self = this; var offline_queue = this.offline_queue; // Reset offline queue this.offline_queue = []; // Attempt to write queued items offline_queue.forEach(function (data) { self.write(data); }); }; StdIOConnection.prototype.write = function (data) { if (!this.connected) { this.offline_queue.push(data); return; } this.connection.write(data); }; exports.createStdIOConnection = function (command, options) { return new StdIOConnection(command, options); }; exports.createStdIOClient = createClient; thrift-0.23.0/lib/nodejs/lib/thrift/header_protocol.js0000664000175000017500000001657715167543515023217 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var TBinaryProtocol = require("./binary_protocol"); var TCompactProtocol = require("./compact_protocol"); var THeaderTransport = require("./header_transport"); var ProtocolMap = {}; ProtocolMap[THeaderTransport.SubprotocolId.BINARY] = TBinaryProtocol; ProtocolMap[THeaderTransport.SubprotocolId.COMPACT] = TCompactProtocol; module.exports = THeaderProtocol; function THeaderProtocolError(message) { Error.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.message = message; } util.inherits(THeaderProtocolError, Error); /** * A framed protocol with headers. * * THeaderProtocol frames other Thrift protocols and adds support for * optional out-of-band headers. The currently supported subprotocols are * TBinaryProtocol and TCompactProtocol. It can currently only be used with * transports that inherit THeaderTransport. * * THeaderProtocol does not currently support THTTPServer, TNonblockingServer, * or TProcessPoolServer. * * See doc/specs/HeaderFormat.md for details of the wire format. */ function THeaderProtocol(trans) { if (!(trans instanceof THeaderTransport)) { throw new THeaderProtocolError( "Only transports that inherit THeaderTransport can be" + " used with THeaderProtocol", ); } this.trans = trans; this.setProtocol(); } THeaderProtocol.prototype.flush = function () { // Headers must be written prior to flushing because because // you need to calculate the length of the payload for the length // field of the header this.trans.writeHeaders(); return this.trans.flush(); }; THeaderProtocol.prototype.writeMessageBegin = function (name, type, seqid) { return this.protocol.writeMessageBegin(name, type, seqid); }; THeaderProtocol.prototype.writeMessageEnd = function () { return this.protocol.writeMessageEnd(); }; THeaderProtocol.prototype.writeStructBegin = function (name) { return this.protocol.writeStructBegin(name); }; THeaderProtocol.prototype.writeStructEnd = function () { return this.protocol.writeStructEnd(); }; THeaderProtocol.prototype.writeFieldBegin = function (name, type, id) { return this.protocol.writeFieldBegin(name, type, id); }; THeaderProtocol.prototype.writeFieldEnd = function () { return this.protocol.writeFieldEnd(); }; THeaderProtocol.prototype.writeFieldStop = function () { return this.protocol.writeFieldStop(); }; THeaderProtocol.prototype.writeMapBegin = function (ktype, vtype, size) { return this.protocol.writeMapBegin(ktype, vtype, size); }; THeaderProtocol.prototype.writeMapEnd = function () { return this.protocol.writeMapEnd(); }; THeaderProtocol.prototype.writeListBegin = function (etype, size) { return this.protocol.writeListBegin(etype, size); }; THeaderProtocol.prototype.writeListEnd = function () { return this.protocol.writeListEnd(); }; THeaderProtocol.prototype.writeSetBegin = function (etype, size) { return this.protocol.writeSetBegin(etype, size); }; THeaderProtocol.prototype.writeSetEnd = function () { return this.protocol.writeSetEnd(); }; THeaderProtocol.prototype.writeBool = function (b) { return this.protocol.writeBool(b); }; THeaderProtocol.prototype.writeByte = function (b) { return this.protocol.writeByte(b); }; THeaderProtocol.prototype.writeI16 = function (i16) { return this.protocol.writeI16(i16); }; THeaderProtocol.prototype.writeI32 = function (i32) { return this.protocol.writeI32(i32); }; THeaderProtocol.prototype.writeI64 = function (i64) { return this.protocol.writeI64(i64); }; THeaderProtocol.prototype.writeDouble = function (dub) { return this.protocol.writeDouble(dub); }; THeaderProtocol.prototype.writeStringOrBinary = function (name, encoding, arg) { return this.protocol.writeStringOrBinary(name, encoding, arg); }; THeaderProtocol.prototype.writeString = function (arg) { return this.protocol.writeString(arg); }; THeaderProtocol.prototype.writeBinary = function (arg) { return this.protocol.writeBinary(arg); }; THeaderProtocol.prototype.writeUuid = function (arg) { return this.protocol.writeUuid(arg); }; THeaderProtocol.prototype.readMessageBegin = function () { this.trans.readHeaders(); this.setProtocol(); return this.protocol.readMessageBegin(); }; THeaderProtocol.prototype.readMessageEnd = function () { return this.protocol.readMessageEnd(); }; THeaderProtocol.prototype.readStructBegin = function () { return this.protocol.readStructBegin(); }; THeaderProtocol.prototype.readStructEnd = function () { return this.protocol.readStructEnd(); }; THeaderProtocol.prototype.readFieldBegin = function () { return this.protocol.readFieldBegin(); }; THeaderProtocol.prototype.readFieldEnd = function () { return this.protocol.readFieldEnd(); }; THeaderProtocol.prototype.readMapBegin = function () { return this.protocol.readMapBegin(); }; THeaderProtocol.prototype.readMapEnd = function () { return this.protocol.readMapEnd(); }; THeaderProtocol.prototype.readListBegin = function () { return this.protocol.readListBegin(); }; THeaderProtocol.prototype.readListEnd = function () { return this.protocol.readListEnd(); }; THeaderProtocol.prototype.readSetBegin = function () { return this.protocol.readSetBegin(); }; THeaderProtocol.prototype.readSetEnd = function () { return this.protocol.readSetEnd(); }; THeaderProtocol.prototype.readBool = function () { return this.protocol.readBool(); }; THeaderProtocol.prototype.readByte = function () { return this.protocol.readByte(); }; THeaderProtocol.prototype.readI16 = function () { return this.protocol.readI16(); }; THeaderProtocol.prototype.readI32 = function () { return this.protocol.readI32(); }; THeaderProtocol.prototype.readI64 = function () { return this.protocol.readI64(); }; THeaderProtocol.prototype.readDouble = function () { return this.protocol.readDouble(); }; THeaderProtocol.prototype.readBinary = function () { return this.protocol.readBinary(); }; THeaderProtocol.prototype.readUuid = function () { return this.protocol.readUuid(); }; THeaderProtocol.prototype.readString = function () { return this.protocol.readString(); }; THeaderProtocol.prototype.getTransport = function () { return this.trans; }; THeaderProtocol.prototype.skip = function (type) { return this.protocol.skip(type); }; THeaderProtocol.prototype.setProtocol = function (subProtocolId) { var subProtocolId = this.trans.getProtocolId(); if (!ProtocolMap[subProtocolId]) { throw new THeaderProtocolError( "Headers not supported for protocol " + subProtocolId, ); } this.protocol = new ProtocolMap[subProtocolId](this.trans); }; thrift-0.23.0/lib/nodejs/lib/thrift/binary.js0000664000175000017500000000712215165535636021317 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var POW_8 = Math.pow(2, 8); var POW_16 = Math.pow(2, 16); var POW_24 = Math.pow(2, 24); var POW_32 = Math.pow(2, 32); var POW_40 = Math.pow(2, 40); 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.readI16 = function (buff, off) { off = off || 0; var v = buff[off + 1]; v += buff[off] << 8; if (buff[off] & 128) { v -= POW_16; } return v; }; exports.readI32 = function (buff, off) { off = off || 0; var v = buff[off + 3]; v += buff[off + 2] << 8; v += buff[off + 1] << 16; v += buff[off] * POW_24; if (buff[off] & 0x80) { v -= POW_32; } return v; }; exports.writeI16 = function (buff, v) { buff[1] = v & 0xff; v >>= 8; buff[0] = v & 0xff; return buff; }; exports.writeI32 = function (buff, v) { buff[3] = v & 0xff; v >>= 8; buff[2] = v & 0xff; v >>= 8; buff[1] = v & 0xff; v >>= 8; buff[0] = v & 0xff; return buff; }; 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 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; default: m += POW_52; e -= 1023; } if (signed) { m *= -1; } return m * Math.pow(2, e - 52); }; /* * Based on code from the jspack module: * http://code.google.com/p/jspack/ */ exports.writeDouble = function (buff, v) { var m, e, c; buff[0] = v < 0 ? 0x80 : 0x00; v = Math.abs(v); if (v !== v) { // NaN, use QNaN IEEE format m = 2251799813685248; e = 2047; } else if (v === Infinity) { m = 0; e = 2047; } else { e = Math.floor(Math.log(v) / Math.LN2); c = Math.pow(2, -e); if (v * c < 1) { e--; c *= 2; } if (e + 1023 >= 2047) { // Overflow m = 0; e = 2047; } 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; e += 1023; } else { // Denormalized - also catches the '0' case, somewhat by chance m = v * POW_1022 * POW_52; e = 0; } } buff[1] = (e << 4) & 0xf0; buff[0] |= (e >> 4) & 0x7f; buff[7] = m & 0xff; m = Math.floor(m / POW_8); buff[6] = m & 0xff; m = Math.floor(m / POW_8); buff[5] = m & 0xff; m = Math.floor(m / POW_8); buff[4] = m & 0xff; m >>= 8; buff[3] = m & 0xff; m >>= 8; buff[2] = m & 0xff; m >>= 8; buff[1] |= m & 0x0f; return buff; }; thrift-0.23.0/lib/nodejs/lib/thrift/compact_protocol.js0000664000175000017500000006341015170007142023362 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var log = require("./log"); var Int64 = require("node-int64"); var Thrift = require("./thrift"); var Type = Thrift.Type; const { parse: uuidParse, stringify: uuidStringify } = require("uuid"); module.exports = TCompactProtocol; var POW_8 = Math.pow(2, 8); var POW_24 = Math.pow(2, 24); var POW_32 = Math.pow(2, 32); var POW_40 = Math.pow(2, 40); var POW_48 = Math.pow(2, 48); var POW_52 = Math.pow(2, 52); var POW_1022 = Math.pow(2, 1022); /** * Constructor Function for the Compact Protocol. * @constructor * @param {object} [trans] - The underlying transport to read/write. * @classdesc The Apache Thrift Protocol layer performs serialization * of base types, the compact protocol serializes data in binary * form with minimal space used for scalar values. */ function TCompactProtocol(trans) { this.trans = trans; this.lastField_ = []; this.lastFieldId_ = 0; this.string_limit_ = 0; this.string_buf_ = null; this.string_buf_size_ = 0; this.container_limit_ = 0; this.booleanField_ = { name: null, hasBoolValue: false, }; this.boolValue_ = { hasBoolValue: false, boolValue: false, }; } // // Compact Protocol Constants // /** * Compact Protocol ID number. * @readonly * @const {number} PROTOCOL_ID */ TCompactProtocol.PROTOCOL_ID = -126; //1000 0010 /** * 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 */ 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 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 */ TCompactProtocol.TYPE_SHIFT_AMOUNT = 5; /** * Compact Protocol type IDs used to keep type data within one nibble. * @readonly * @property {number} CT_STOP - End of a set of fields. * @property {number} CT_BOOLEAN_TRUE - Flag for Boolean field with true value (packed field and value). * @property {number} CT_BOOLEAN_FALSE - Flag for Boolean field with false value (packed field and value). * @property {number} CT_BYTE - Signed 8 bit integer. * @property {number} CT_I16 - Signed 16 bit integer. * @property {number} CT_I32 - Signed 32 bit integer. * @property {number} CT_I64 - Signed 64 bit integer (2^53 max in JavaScript). * @property {number} CT_DOUBLE - 64 bit IEEE 854 floating point. * @property {number} CT_BINARY - Array of bytes (used for strings also). * @property {number} CT_LIST - A collection type (unordered). * @property {number} CT_SET - A collection type (unordered and without repeated values). * @property {number} CT_MAP - A collection type (map/associative-array/dictionary). * @property {number} CT_STRUCT - A multifield type. * @property {number} CT_UUID - A UUID 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_UUID: 0x0d, }; /** * Array mapping Compact type IDs to standard Thrift type IDs. * @readonly */ TCompactProtocol.TTypeToCType = [ 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_UUID, // T_UUID ]; // // Compact Protocol Utilities // /** * Returns the underlying transport layer. * @return {object} The underlying transport layer. */ TCompactProtocol.prototype.getTransport = function () { return this.trans; }; /** * Lookup a Compact Protocol Type value for a given Thrift Type value. * N.B. Used only internally. * @param {number} ttype - Thrift type value * @returns {number} Compact protocol type value */ TCompactProtocol.prototype.getCompactType = function (ttype) { return TCompactProtocol.TTypeToCType[ttype]; }; /** * Lookup a Thrift Type value for a given Compact Protocol Type value. * N.B. Used only internally. * @param {number} type - Compact Protocol type value * @returns {number} Thrift Type value */ TCompactProtocol.prototype.getTType = function (type) { switch (type) { case Type.STOP: return Type.STOP; case TCompactProtocol.Types.CT_BOOLEAN_FALSE: case TCompactProtocol.Types.CT_BOOLEAN_TRUE: return Type.BOOL; case TCompactProtocol.Types.CT_BYTE: return Type.BYTE; case TCompactProtocol.Types.CT_I16: return Type.I16; case TCompactProtocol.Types.CT_I32: return Type.I32; case TCompactProtocol.Types.CT_I64: return Type.I64; case TCompactProtocol.Types.CT_DOUBLE: return Type.DOUBLE; case TCompactProtocol.Types.CT_BINARY: return Type.STRING; case TCompactProtocol.Types.CT_LIST: return Type.LIST; case TCompactProtocol.Types.CT_SET: return Type.SET; case TCompactProtocol.Types.CT_MAP: return Type.MAP; case TCompactProtocol.Types.CT_STRUCT: return Type.STRUCT; case TCompactProtocol.Types.CT_UUID: return Type.UUID; default: throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.INVALID_DATA, "Unknown type: " + type, ); } return Type.STOP; }; // // Compact Protocol write operations // /** * Send any buffered bytes to the end point. */ TCompactProtocol.prototype.flush = function () { return this.trans.flush(); }; /** * Writes an RPC message header * @param {string} name - The method name for the message. * @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) { this.writeByte(TCompactProtocol.PROTOCOL_ID); 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 }); } else { this._seqid = seqid; this.trans.setCurrSeqId(seqid); } }; TCompactProtocol.prototype.writeMessageEnd = function () {}; TCompactProtocol.prototype.writeStructBegin = function (name) { this.lastField_.push(this.lastFieldId_); this.lastFieldId_ = 0; }; TCompactProtocol.prototype.writeStructEnd = function () { this.lastFieldId_ = this.lastField_.pop(); }; /** * Writes a struct field header * @param {string} name - The field name (not written with the compact protocol). * @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) { if (type != Type.BOOL) { return this.writeFieldBeginInternal(name, type, id, -1); } this.booleanField_.name = name; this.booleanField_.fieldType = type; this.booleanField_.fieldId = id; }; TCompactProtocol.prototype.writeFieldEnd = function () {}; TCompactProtocol.prototype.writeFieldStop = function () { this.writeByte(TCompactProtocol.Types.CT_STOP); }; /** * Writes a map collection header * @param {number} keyType - The Thrift type of the map keys. * @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) { if (size === 0) { this.writeByte(0); } else { this.writeVarint32(size); this.writeByte( (this.getCompactType(keyType) << 4) | this.getCompactType(valType), ); } }; 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) { this.writeCollectionBegin(elemType, size); }; 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) { this.writeCollectionBegin(elemType, size); }; TCompactProtocol.prototype.writeSetEnd = function () {}; 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.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, ); } }; TCompactProtocol.prototype.writeByte = function (b) { this.trans.write(new Buffer([b])); }; TCompactProtocol.prototype.writeI16 = function (i16) { this.writeVarint32(this.i32ToZigzag(i16)); }; TCompactProtocol.prototype.writeI32 = function (i32) { this.writeVarint32(this.i32ToZigzag(i32)); }; TCompactProtocol.prototype.writeI64 = function (i64) { this.writeVarint64(this.i64ToZigzag(i64)); }; // Little-endian, unlike TBinaryProtocol TCompactProtocol.prototype.writeDouble = function (v) { var buff = new Buffer(8); var m, e, c; buff[7] = v < 0 ? 0x80 : 0x00; v = Math.abs(v); if (v !== v) { // NaN, use QNaN IEEE format m = 2251799813685248; e = 2047; } else if (v === Infinity) { m = 0; e = 2047; } else { e = Math.floor(Math.log(v) / Math.LN2); c = Math.pow(2, -e); if (v * c < 1) { e--; c *= 2; } if (e + 1023 >= 2047) { // Overflow m = 0; e = 2047; } 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; e += 1023; } else { // Denormalized - also catches the '0' case, somewhat by chance m = v * POW_1022 * POW_52; e = 0; } } buff[6] = (e << 4) & 0xf0; buff[7] |= (e >> 4) & 0x7f; buff[0] = m & 0xff; m = Math.floor(m / POW_8); buff[1] = m & 0xff; m = Math.floor(m / POW_8); buff[2] = m & 0xff; m = Math.floor(m / POW_8); buff[3] = m & 0xff; m >>= 8; buff[4] = m & 0xff; m >>= 8; buff[5] = m & 0xff; m >>= 8; buff[6] |= m & 0x0f; this.trans.write(buff); }; 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]" ) { // 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); } }; TCompactProtocol.prototype.writeString = function (arg) { this.writeStringOrBinary("writeString", "utf8", arg); }; TCompactProtocol.prototype.writeBinary = function (arg) { this.writeStringOrBinary("writeBinary", "binary", arg); }; TCompactProtocol.prototype.writeUuid = function (arg) { this.trans.write(Buffer.from(uuidParse(arg))); }; // // Compact Protocol internal write methods // TCompactProtocol.prototype.writeFieldBeginInternal = function ( name, fieldType, fieldId, typeOverride, ) { //If there's a type override, use that. 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); } else { //Write separate type and ID values this.writeByte(typeToWrite); this.writeI16(fieldId); } this.lastFieldId_ = fieldId; }; 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)); } else { this.writeByte(0xf0 | this.getCompactType(elemType)); this.writeVarint32(size); } }; /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. */ TCompactProtocol.prototype.writeVarint32 = function (n) { var buf = new Buffer(5); var wsize = 0; while (true) { if ((n & ~0x7f) === 0) { buf[wsize++] = n; break; } else { buf[wsize++] = (n & 0x7f) | 0x80; n = n >>> 7; } } var wbuf = new Buffer(wsize); buf.copy(wbuf, 0, 0, wsize); this.trans.write(wbuf); }; /** * 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") { n = new Int64(n); } if (!(n instanceof Int64)) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.INVALID_DATA, "Expected Int64 or Number, found: " + n, ); } var buf = new Buffer(10); var wsize = 0; var hi = n.buffer.readUInt32BE(0, true); var lo = n.buffer.readUInt32BE(4, true); var mask = 0; while (true) { if ((lo & ~0x7f) === 0 && hi === 0) { buf[wsize++] = lo; break; } else { buf[wsize++] = (lo & 0x7f) | 0x80; mask = hi << 25; lo = lo >>> 7; hi = hi >>> 7; lo = lo | mask; } } var wbuf = new Buffer(wsize); buf.copy(wbuf, 0, 0, wsize); this.trans.write(wbuf); }; /** * 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") { l = new Int64(parseInt(l, 10)); } 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, ); } 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); return new Int64(hi, lo); }; /** * 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); }; // // Compact Protocol read operations // 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, ); } //Read Version and Type var versionAndType = this.trans.readByte(); var version = versionAndType & TCompactProtocol.VERSION_MASK; if (version != TCompactProtocol.VERSION_N) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.BAD_VERSION, "Bad protocol version " + version, ); } var type = (versionAndType >> TCompactProtocol.TYPE_SHIFT_AMOUNT) & TCompactProtocol.TYPE_BITS; //Read SeqId var seqid = this.readVarint32(); //Read name var name = this.readString(); return { fname: name, mtype: type, rseqid: seqid }; }; TCompactProtocol.prototype.readMessageEnd = function () {}; TCompactProtocol.prototype.readStructBegin = function () { this.lastField_.push(this.lastFieldId_); this.lastFieldId_ = 0; return { fname: "" }; }; TCompactProtocol.prototype.readStructEnd = function () { this.lastFieldId_ = this.lastField_.pop(); }; TCompactProtocol.prototype.readFieldBegin = function () { var fieldId = 0; var b = this.trans.readByte(b); var type = b & 0x0f; if (type == TCompactProtocol.Types.CT_STOP) { 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; 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; } var fieldType = this.getTType(type); //Boolean are encoded with the type 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; } //Save the new field for the next delta computation. this.lastFieldId_ = fieldId; return { fname: null, ftype: fieldType, fid: fieldId }; }; TCompactProtocol.prototype.readFieldEnd = function () {}; TCompactProtocol.prototype.readMapBegin = function () { var msize = this.readVarint32(); if (msize < 0) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative map size", ); } var kvType = 0; if (msize !== 0) { kvType = this.trans.readByte(); } var keyType = this.getTType((kvType & 0xf0) >>> 4); var valType = this.getTType(kvType & 0xf); return { ktype: keyType, vtype: valType, size: msize }; }; TCompactProtocol.prototype.readMapEnd = function () {}; TCompactProtocol.prototype.readListBegin = function () { var size_and_type = this.trans.readByte(); var lsize = (size_and_type >>> 4) & 0x0000000f; if (lsize == 15) { lsize = this.readVarint32(); } if (lsize < 0) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative list size", ); } var elemType = this.getTType(size_and_type & 0x0000000f); return { etype: elemType, size: lsize }; }; TCompactProtocol.prototype.readListEnd = function () {}; TCompactProtocol.prototype.readSetBegin = function () { return this.readListBegin(); }; TCompactProtocol.prototype.readSetEnd = function () {}; TCompactProtocol.prototype.readBool = function () { var value = false; var rsize = 0; if (this.boolValue_.hasBoolValue === true) { value = this.boolValue_.boolValue; this.boolValue_.hasBoolValue = false; } else { var res = this.trans.readByte(); rsize = res.rsize; value = res.value == TCompactProtocol.Types.CT_BOOLEAN_TRUE; } return value; }; TCompactProtocol.prototype.readByte = function () { return this.trans.readByte(); }; TCompactProtocol.prototype.readUuid = function () { const buf = this.trans.read(16); return uuidStringify(new Uint8Array(buf)); }; TCompactProtocol.prototype.readI16 = function () { return this.readI32(); }; TCompactProtocol.prototype.readI32 = function () { return this.zigzagToI32(this.readVarint32()); }; TCompactProtocol.prototype.readI64 = function () { return this.zigzagToI64(this.readVarint64()); }; // Little-endian, unlike TBinaryProtocol 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 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; switch (e) { case 0: e = -1022; break; case 2047: return m ? NaN : signed ? -Infinity : Infinity; default: m += POW_52; e -= 1023; } if (signed) { m *= -1; } return m * Math.pow(2, e - 52); }; 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", ); } return this.trans.read(size); }; TCompactProtocol.prototype.readString = function () { var size = this.readVarint32(); // Catch empty string case if (size === 0) { return ""; } // Catch error cases if (size < 0) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative string size", ); } return this.trans.readString(size); }; // // Compact Protocol internal read operations // /** * 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 () { return this.readVarint64().toNumber(); }; /** * 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 () { var rsize = 0; var lo = 0; var hi = 0; var shift = 0; while (true) { var b = this.trans.readByte(); 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)); } else { 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.", ); } } return new Int64(hi, lo); }; /** * Convert from zigzag int to int. */ TCompactProtocol.prototype.zigzagToI32 = function (n) { return (n >>> 1) ^ (-1 * (n & 1)); }; /** * Convert from zigzag long to long. */ TCompactProtocol.prototype.zigzagToI64 = function (n) { var hi = n.buffer.readUInt32BE(0, true); var lo = n.buffer.readUInt32BE(4, true); var neg = new Int64(hi & 0, lo & 1); neg._2scomp(); 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; return new Int64(hi, lo); }; TCompactProtocol.prototype.skip = function (type, depth) { depth = (depth || 0) + 1; if (depth > 64) { throw new Thrift.TProtocolException( Thrift.TProtocolExceptionType.DEPTH_LIMIT, "Maximum skip depth exceeded" ); } switch (type) { case Type.BOOL: this.readBool(); break; case Type.BYTE: this.readByte(); break; case Type.I16: this.readI16(); break; case Type.I32: this.readI32(); break; case Type.I64: this.readI64(); break; case Type.DOUBLE: this.readDouble(); break; case Type.STRING: this.readString(); break; case Type.UUID: this.readUuid(); break; case Type.STRUCT: this.readStructBegin(); while (true) { var r = this.readFieldBegin(); if (r.ftype === Type.STOP) { break; } this.skip(r.ftype, depth); this.readFieldEnd(); } this.readStructEnd(); break; case Type.MAP: var mapBegin = this.readMapBegin(); for (var i = 0; i < mapBegin.size; ++i) { this.skip(mapBegin.ktype, depth); this.skip(mapBegin.vtype, depth); } this.readMapEnd(); break; case Type.SET: var setBegin = this.readSetBegin(); for (var i2 = 0; i2 < setBegin.size; ++i2) { this.skip(setBegin.etype, depth); } this.readSetEnd(); break; case Type.LIST: var listBegin = this.readListBegin(); for (var i3 = 0; i3 < listBegin.size; ++i3) { this.skip(listBegin.etype, depth); } this.readListEnd(); break; default: throw new Error("Invalid type: " + type); } }; thrift-0.23.0/lib/nodejs/lib/thrift/ohos_connection.js0000664000175000017500000002500615165535636023223 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var util = require("util"); var 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 createClient = require("./create_client"); /** * @class * @name ConnectOptions * @property {string} transport - The Thrift layered transport to use (TBufferedTransport, etc). * @property {string} protocol - The Thrift serialization protocol to use (TBinaryProtocol, etc.). * @property {string} path - The URL path to POST to (e.g. "/", "/mySvc", "/thrift/quoteSvc", etc.). * @property {object} header - A standard Node.js header hash, an object hash containing key/value * pairs where the key is the header name string and the value is the header value string. * @property {object} requestOptions - Options passed on to http request. Details: * https://developer.harmonyos.com/en/docs/documentation/doc-references/js-apis-net-http-0000001168304341#section12262183471518 * @example * //Use a connection that requires ssl/tls, closes the connection after each request, * // uses the buffered transport layer, uses the JSON protocol and directs RPC traffic * // to https://thrift.example.com:9090/hello * import http from '@ohos.net.http' // HTTP module of OpenHarmonyOS * var thrift = require('thrift'); * var options = { * transport: thrift.TBufferedTransport, * protocol: thrift.TJSONProtocol, * path: "/hello", * headers: {"Connection": "close"} * }; * // With OpenHarmonyOS HTTP module, HTTPS is supported by default. To support HTTP, See: * // https://developer.harmonyos.com/en/docs/documentation/doc-references/js-apis-net-http-0000001168304341#EN-US_TOPIC_0000001171944450__s56d19203690d4782bfc74069abb6bd71 * var con = thrift.createOhosConnection(http.createHttp, "thrift.example.com", 9090, options); * var client = thrift.createOhosClient(myService, connection); * client.myServiceFunction(); */ /** * Initializes a Thrift HttpConnection instance (use createHttpConnection() rather than * instantiating directly). * @constructor * @param {ConnectOptions} options - The configuration options to use. * @throws {error} Exceptions other than InputBufferUnderrunError are rethrown * @event {error} The "error" event is fired when a Node.js error event occurs during * request or response processing, in which case the node error is passed on. An "error" * event may also be fired when the connection can not map a response back to the * appropriate client (an internal error), generating a TApplicationException. * @classdesc OhosConnection objects provide Thrift end point transport * semantics implemented over the OpenHarmonyOS http.request() method. * @see {@link createOhosConnection} */ var OhosConnection = (exports.OhosConnection = function (options) { //Initialize the emitter base object EventEmitter.call(this); //Set configuration var self = this; this.options = options || {}; this.host = this.options.host; this.port = this.options.port; 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.transport = this.options.transport || TBufferedTransport; this.protocol = this.options.protocol || TBinaryProtocol; //Inherit method from OpenHarmonyOS HTTP module this.createHttp = this.options.createHttp; //Prepare HTTP request options this.requestOptions = { method: "POST", header: this.options.header || {}, readTimeout: this.options.readTimeout || 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"; } /*jshint +W069 */ //The sequence map is used to map seqIDs back to the // calling client in multiplexed scenarios this.seqId2Service = {}; function decodeCallback(transport_with_data) { var proto = new self.protocol(transport_with_data); try { while (true) { var header = proto.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 client var 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]; delete self.seqId2Service[header.rseqid]; } /*jshint -W083 */ 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 () { clientCallback(err, success); }); } }; /*jshint +W083 */ 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", ), ); } } } catch (e) { if (e instanceof InputBufferUnderrunError) { transport_with_data.rollbackPosition(); } else { self.emit("error", e); } } } //Response handler ////////////////////////////////////////////////// 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); return; } if (!response || response.responseCode !== 200) { 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]" ) { // Wrap ArrayBuffer/string in a Buffer so data[i].copy will work data.push(Buffer.from(response.result)); } dataLen += response.result.length; var buf = Buffer.alloc(dataLen); for (var i = 0, len = data.length, pos = 0; i < len; i++) { data[i].copy(buf, pos); pos += data[i].length; } //Get the receiver function for the transport and // call it with the buffer self.transport.receiver(decodeCallback)(buf); }; /** * Writes Thrift message data to the connection * @param {Buffer} data - A Node.js Buffer containing the data to write * @returns {void} No return value. * @event {error} the "error" event is raised upon request failure passing the * Node.js error object to the listener. */ this.write = function (data) { //To initiate multiple HTTP requests, we must create an HttpRequest object // for each HTTP request var http = self.createHttp(); var opts = self.requestOptions; opts.header["Content-length"] = data.length; if (!opts.header["Content-Type"]) opts.header["Content-Type"] = "application/x-thrift"; // extraData not support array data currently opts.extraData = data.toString(); http.request(self.url, opts, self.responseCallback); }; }); util.inherits(OhosConnection, EventEmitter); /** * Creates a new OhosConnection object, used by Thrift clients to connect * to Thrift HTTP based servers. * @param {Function} createHttp - OpenHarmonyOS method to initiate or destroy an HTTP request. * @param {string} host - The host name or IP to connect to. * @param {number} port - The TCP port to connect to. * @param {ConnectOptions} options - The configuration options to use. * @returns {OhosConnection} The connection object. * @see {@link ConnectOptions} */ exports.createOhosConnection = function (createHttp, host, port, options) { options.createHttp = createHttp; options.host = host; options.port = port || 80; return new OhosConnection(options); }; exports.createOhosClient = createClient; function THTTPException(response) { thrift.TApplicationException.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.responseCode = response.responseCode; this.response = response; this.type = thrift.TApplicationExceptionType.PROTOCOL_ERROR; this.message = "Received a response with a bad HTTP status code: " + response.responseCode; } util.inherits(THTTPException, thrift.TApplicationException); thrift-0.23.0/lib/nodejs/Makefile.in0000644000175000017500000004412415170007167017462 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # 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. # We call npm twice to work around npm issues VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/nodejs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ examples \ lib \ test \ coding_standards.md \ CMakeLists.txt \ README.md all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/nodejs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/nodejs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT) --gen js:node -o test/ $(top_srcdir)/test/ThriftTest.thrift 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 # TODO: Lint nodejs lib and gen-code as part of build check: deps cd $(top_srcdir) && $(NPM) test && $(NPM) run lint-tests && cd lib/nodejs clean-local: $(RM) -r test/gen-* $(RM) -r test/fuzz/gen-* $(RM) -r $(top_srcdir)/node_modules $(RM) -r test/episodic-code-generation-test/gen* $(RM) -r test/episodic-code-generation-test/node_modules distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/nodejs/Makefile.am0000664000175000017500000000323415167543515017460 0ustar00buildbuild00000000000000# 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. # We call npm twice to work around npm issues stubs: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT) --gen js:node -o test/ $(top_srcdir)/test/ThriftTest.thrift 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 # TODO: Lint nodejs lib and gen-code as part of build check: deps cd $(top_srcdir) && $(NPM) test && $(NPM) run lint-tests && cd lib/nodejs clean-local: $(RM) -r test/gen-* $(RM) -r test/fuzz/gen-* $(RM) -r $(top_srcdir)/node_modules $(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 \ test \ coding_standards.md \ CMakeLists.txt \ README.md thrift-0.23.0/lib/json/0000755000175000017500000000000015170007200015063 5ustar00buildbuild00000000000000thrift-0.23.0/lib/json/test/0000775000175000017500000000000015170007175016057 5ustar00buildbuild00000000000000thrift-0.23.0/lib/json/test/build.properties0000664000175000017500000000050715165535636021312 0ustar00buildbuild00000000000000# Jar versions mvn.ant.task.version=2.1.3 # Dependency versions json-schema-validator.version=2.2.6 # Maven dependency download locations mvn.repo=https://repo1.maven.org/maven2 mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version} mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar thrift-0.23.0/lib/json/test/build.xml0000664000175000017500000001207215165535636017716 0ustar00buildbuild00000000000000 JSON Schema Validation Test Thrift compiler is missing ! thrift-0.23.0/lib/json/test/Makefile0000644000175000017500000004372015170007175017523 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/json/test/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/json/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/json/test abs_srcdir = /thrift/src/lib/json/test abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/json/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/json/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile 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 ; \ $$ANT $(ANT_FLAGS) clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/json/test/Makefile.in0000644000175000017500000004263015170007167020130 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/json/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/json/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/json/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile 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 ; \ $$ANT $(ANT_FLAGS) clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/json/test/Makefile.am0000664000175000017500000000177015165535636020134 0ustar00buildbuild00000000000000# # 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. # 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 ; \ $$ANT $(ANT_FLAGS) clean thrift-0.23.0/lib/json/schema.json0000664000175000017500000002064315165535636017254 0ustar00buildbuild00000000000000{ "$schema": "http://json-schema.org/draft-04/schema#", "id": "http://thrift.apache.org/schema.json#", "description": "Schema for Apache Thrift protocol descriptors", "definitions": { "type-id": { "title": "Any type id (name)", "enum": [ "void", "string", "bool", "byte", "i8", "i16", "i32", "i64", "double", "list", "set", "map", "union", "struct", "binary", "uuid", "enum" ] }, "base-type": { "title": "Base type schema", "type": "object", "properties": { "typeId": { "enum": ["void", "string", "bool", "byte", "i8", "i16", "i32", "i64", "double", "binary", "uuid" ] } }, "required": [ "typeId" ] }, "list-type": { "title": "List and set schema", "type": "object", "properties": { "typeId": { "enum": [ "list", "set" ] }, "elemTypeId": { "$ref": "#/definitions/type-id" }, "elemType": { "$ref": "#/definitions/type-desc" } }, "required": [ "typeId", "elemTypeId" ] }, "map-type": { "title": "Map schema", "type": "object", "properties": { "typeId": { "enum": [ "map" ] }, "keyTypeId": { "$ref": "#/definitions/type-id" }, "keyType": { "$ref": "#/definitions/type-desc" }, "valueTypeId": { "$ref": "#/definitions/type-id" }, "valueType": { "$ref": "#/definitions/type-desc" } }, "required": [ "typeId", "keyTypeId", "valueTypeId" ] }, "struct-type": { "title": "Struct, union, enum and exception schema", "type": "object", "properties": { "typeId": { "enum": [ "union", "struct", "exception", "enum" ] } }, "required": [ "typeId", "class" ] }, "type-desc": { "title": "Type descriptor schema", "allOf": [ { "type": "object", "properties": { "typeId": { "type": "string" }, "class": { "type": "string" } } }, { "oneOf": [ { "$ref": "#/definitions/base-type" }, { "$ref": "#/definitions/list-type" }, { "$ref": "#/definitions/map-type" }, { "$ref": "#/definitions/struct-type" } ] } ] }, "name-and-doc": { "title": "Name and documentation sub-schema", "type": "object", "properties": { "name": { "type": "string" }, "doc": { "type": "string" } }, "required": [ "name" ] }, "enum": { "title": "Thrift 'enum' definition schema", "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, { "required": [ "members" ], "properties": { "members": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "value": { "type": "integer" } }, "required": [ "name", "value" ] } } } } ] }, "typedef": { "title": "Thrift typedef definition schema", "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, { "properties": { "typeId": { "$ref": "#/definitions/type-id" }, "type": { "$ref": "#/definitions/type-desc" } }, "required": [ "typeId" ] } ] }, "constant": { "title": "Thrift constant definition schema", "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, { "properties": { "type": { "$ref": "#/definitions/type-desc" }, "value": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "array" }, { "type": "object" } ] } }, "required": [ "value" ] } ] }, "field": { "title": "Thrift struct field definition schema", "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, { "properties": { "key": { "type": "integer", "minimum": 1, "maximum": 65535 }, "required": { "enum": [ "required", "optional", "req_out" ] }, "typeId": { "$ref": "#/definitions/type-id" }, "type": { "$ref": "#/definitions/type-desc" }, "default": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "array" }, { "type": "object" } ] } }, "required": [ "key", "required" ] } ] }, "struct": { "title": "Thrift struct definition schema", "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, { "properties": { "isException": { "type": "boolean" }, "isUnion": { "type": "boolean" }, "fields": { "type": "array", "items": { "$ref": "#/definitions/field" } } }, "required": [ "isException", "isUnion", "fields" ] } ] }, "union": { "title": "Thrift union definition schema", "$ref": "#/definitions/struct" }, "exception": { "title": "Thrift exception definition schema", "type": "object", "properties": { "key": { "type": "integer", "minimum": 1, "maximum": 65535 }, "name": { "type": "string" }, "typeId": { "enum": [ "exception" ] }, "type": { "$ref": "#/definitions/struct-type" } }, "required": [ "key", "name", "typeId" ] }, "function": { "title": "Thrift service function definition schema", "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, { "properties": { "oneway": { "type": "boolean" }, "returnType": { "$ref": "#/definitions/type-desc" }, "arguments": { "type": "array", "items": { "$ref": "#/definitions/field" } }, "exceptions": { "type": "array", "items": { "$ref": "#/definitions/exception" } } }, "required": [ "oneway", "arguments", "exceptions" ] } ] }, "service": { "title": "Thrift service definition schema", "type": "object", "allOf": [ { "$ref": "#/definitions/name-and-doc" }, { "properties": { "functions": { "type": "array", "items": { "$ref": "#/definitions/function" } } }, "required": [ "functions" ] } ] }, "annotations": { "title": "Map of annotation names to values", "type": "object", "additionalProperties": { "type": "string" } } }, "type": "object", "required": [ "name", "enums", "typedefs", "structs", "constants", "services" ], "properties": { "name": { "type": "string" }, "includes": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "namespaces": { "type": "object", "additionalProperties": { "type": "string" } }, "enums": { "type": "array", "items": { "$ref": "#/definitions/enum" } }, "typedefs": { "type": "array", "items": { "$ref": "#/definitions/typedef" } }, "structs": { "type": "array", "items": { "$ref": "#/definitions/struct" } }, "constants": { "type": "array", "items": { "$ref": "#/definitions/constant" } }, "services": { "type": "array", "items": { "$ref": "#/definitions/service" } } }, "additionalProperties": false } thrift-0.23.0/lib/json/Makefile.in0000644000175000017500000005733615170007167017162 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/json ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = test am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # Schema validation test depends on java @WITH_JAVA_TRUE@SUBDIRS = test EXTRA_DIST = \ schema.json \ test all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/json/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/json/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am dist-hook distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile clean-local: $(RM) -r test/build/ dist-hook: $(RM) -r $(distdir)/test/build/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/json/Makefile.am0000664000175000017500000000200715165535636017147 0ustar00buildbuild00000000000000# # 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. # if WITH_JAVA # Schema validation test depends on java SUBDIRS = test endif clean-local: $(RM) -r test/build/ dist-hook: $(RM) -r $(distdir)/test/build/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ schema.json \ test thrift-0.23.0/lib/Makefile.in0000644000175000017500000006206315170007166016201 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_CPP_TRUE@am__append_1 = cpp @WITH_C_GLIB_TRUE@am__append_2 = c_glib # JavaScript unit test depends on java # so test only if java, ant & co is available @WITH_JAVA_TRUE@am__append_3 = java js @WITH_JAVA_TRUE@am__append_4 = precross-java @WITH_KOTLIN_TRUE@am__append_5 = kotlin @WITH_KOTLIN_TRUE@am__append_6 = precross-kotlin @WITH_PYTHON_TRUE@am__append_7 = py @WITH_ERLANG_TRUE@am__append_8 = erl @WITH_RUBY_TRUE@am__append_9 = rb @WITH_PERL_TRUE@am__append_10 = perl @WITH_PHP_TRUE@am__append_11 = php @WITH_DART_TRUE@am__append_12 = dart @WITH_DOTNET_TRUE@am__append_13 = netstd @WITH_GO_TRUE@am__append_14 = go @WITH_D_TRUE@am__append_15 = d @WITH_D_TRUE@am__append_16 = precross-d @WITH_NODEJS_TRUE@am__append_17 = nodejs nodets @WITH_NODEJS_TRUE@am__append_18 = precross-nodejs @WITH_LUA_TRUE@am__append_19 = lua @WITH_RS_TRUE@am__append_20 = rs @WITH_CL_TRUE@am__append_21 = cl @WITH_SWIFT_TRUE@am__append_22 = swift subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = json xml cpp c_glib java js kotlin py erl rb perl php \ dart netstd go d nodejs nodets lua rs cl swift am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = json xml $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_5) $(am__append_7) $(am__append_8) \ $(am__append_9) $(am__append_10) $(am__append_11) \ $(am__append_12) $(am__append_13) $(am__append_14) \ $(am__append_15) $(am__append_17) $(am__append_19) \ $(am__append_20) $(am__append_21) $(am__append_22) PRECROSS_TARGET = $(am__append_4) $(am__append_6) $(am__append_16) \ $(am__append_18) EXTRA_DIST = \ d \ dart \ delphi \ haxe \ javame \ js \ ocaml \ st \ ts all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile # 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 precross-%: $(MAKE) -C $* precross precross: $(PRECROSS_TARGET) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/haxe/0000775000175000017500000000000015170007142015046 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/0000775000175000017500000000000015165535636015657 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/0000775000175000017500000000000015165535636016446 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/apache/0000775000175000017500000000000015165535636017667 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/apache/thrift/0000775000175000017500000000000015165535636021167 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/apache/thrift/TApplicationException.hx0000664000175000017500000000723115165535636026001 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TStruct; import org.apache.thrift.protocol.TType; /** * Application level exception */ class TApplicationException extends TException { private static var TAPPLICATION_EXCEPTION_STRUCT = { new TStruct("TApplicationException"); }; private static var MESSAGE_FIELD = { new TField("message", TType.STRING, 1); }; private static var TYPE_FIELD = { new TField("type", TType.I32, 2); }; // WARNING: These are subject to be extended in the future, so we can't use enums // with Haxe 3.1.3 because of https://github.com/HaxeFoundation/haxe/issues/3649 public static inline var UNKNOWN : Int = 0; public static inline var UNKNOWN_METHOD : Int = 1; public static inline var INVALID_MESSAGE_TYPE : Int = 2; public static inline var WRONG_METHOD_NAME : Int = 3; public static inline var BAD_SEQUENCE_ID : Int = 4; public static inline var MISSING_RESULT : Int = 5; public static inline var INTERNAL_ERROR : Int = 6; public static inline var PROTOCOL_ERROR : Int = 7; public static inline var INVALID_TRANSFORM : Int = 8; public static inline var INVALID_PROTOCOL : Int = 9; public static inline var UNSUPPORTED_CLIENT_TYPE : Int = 10; public function new(type : Int = UNKNOWN, message : String = "") { super(message, type); } public static function read(iprot:TProtocol) : TApplicationException { var field:TField; iprot.readStructBegin(); var message : String = null; var type : Int = UNKNOWN; while (true) { field = iprot.readFieldBegin(); if (field.type == TType.STOP) { break; } switch (field.id) { case 1: if (field.type == TType.STRING) { message = iprot.readString(); } else { TProtocolUtil.skip(iprot, field.type); } case 2: if (field.type == TType.I32) { type = iprot.readI32(); } else { TProtocolUtil.skip(iprot, field.type); } default: TProtocolUtil.skip(iprot, field.type); } iprot.readFieldEnd(); } iprot.readStructEnd(); return new TApplicationException(type, message); } public function write(oprot:TProtocol) : Void { oprot.writeStructBegin(TAPPLICATION_EXCEPTION_STRUCT); if (errorMsg != null) { oprot.writeFieldBegin(MESSAGE_FIELD); oprot.writeString(errorMsg); oprot.writeFieldEnd(); } oprot.writeFieldBegin(TYPE_FIELD); oprot.writeI32(errorID); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/TConfiguration.hx0000664000175000017500000000263415165535636024470 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; class TConfiguration { public static inline var DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024; public static inline var DEFAULT_MAX_FRAME_SIZE = 16384000; // this value is used consistently across all Thrift libraries public static inline var DEFAULT_RECURSION_DEPTH = 64; public var MaxMessageSize(default,default) : Int = DEFAULT_MAX_MESSAGE_SIZE; public var MaxFrameSize(default,default) : Int = DEFAULT_MAX_FRAME_SIZE; public var RecursionLimit(default,default) : Int = DEFAULT_RECURSION_DEPTH; // TODO(JensG): add connection and i/o timeouts public function new() { // CTOR } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/TBase.hx0000664000175000017500000000425315165535636022532 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; // Make sure we use at least 3.1.3 // Some Linux platforms have waaaay too old packages in their repos // Pro Tip: Look at http://openfl.com for a good Linux install script #if( haxe_ver < 3.103) #error Haxe 3.1.3 or newer required, sorry! #end import org.apache.thrift.protocol.TProtocol; /** * Generic base interface for generated Thrift objects. * */ interface TBase { /** * Reads the TObject from the given input protocol. * * @param iprot Input protocol */ function read(iprot:TProtocol) : Void; /** * Writes the objects out to the protocol * * @param oprot Output protocol */ function write(oprot:TProtocol) : Void; /** * Check if a field is currently set or unset. * * @param fieldId The field's id tag as found in the IDL. */ function isSet(fieldId : Int) : Bool; /** * Get a field's value by id. Primitive types will be wrapped in the * appropriate "boxed" types. * * @param fieldId The field's id tag as found in the IDL. */ function getFieldValue(fieldId : Int) : Dynamic; /** * Set a field's value by id. Primitive types must be "boxed" in the * appropriate object wrapper type. * * @param fieldId The field's id tag as found in the IDL. */ function setFieldValue(fieldId : Int, value : Dynamic) : Void; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/TFieldRequirementType.hx0000664000175000017500000000207215165535636025763 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * Requirement type constants. * */ enum abstract TFieldRequirementType(Int) from Int to Int { public static inline var REQUIRED : Int = 1; public static inline var OPTIONAL : Int = 2; public static inline var DEFAULT : Int = 3; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/TException.hx0000664000175000017500000000233115165535636023611 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; class TException { @:isVar public var errorID(default,null) : Int; @:isVar public var errorMsg(default,null) : String; public function new(msg : String = "", id : Int = 0) { errorID = id; errorMsg = msg; } public function toString() : String { var clsname = Type.getClassName( Type.getClass(this)); return '${clsname}: ${errorMsg} (code ${errorID})'; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/Limits.hx0000664000175000017500000000274615165535636023002 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; class Limits { // Haxe limits are not fixed values, they depend on the target platform // For example, neko limits an int to 31 bits instead of 32. So we detect // the values once during initialization in order to // (a) get the right values for the current platform, and // (b) prevent us from dependencies to a bunch of defines public static var I32_MAX = { var last : Int = 0; var next : Int = 0; for(bit in 0 ... 32) { last = next; next = last | (1 << bit); if(next < 0) { break; } } last; // final value } // add whatever you need }thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/0000775000175000017500000000000015165535636022446 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/UuidHelper.hx0000664000175000017500000000251315165535636025056 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.helper; import haxe.io.Bytes; import uuid.Uuid; class UuidHelper { public static function CanonicalUuid( uuid : String) : String { uuid = StringTools.replace( uuid, "{", ""); uuid = StringTools.replace( uuid, "}", ""); uuid = Uuid.stringify( Uuid.parse( uuid)); return uuid; } #if debug public static function UnitTest() : Void { var guid : String = CanonicalUuid("{00112233-4455-6677-8899-AABBCCDDEEFF}"); if ( guid.length != 36) throw 'UuidHelper Test: CanonicalUuid() failed'; } #end } thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/ZigZag.hx0000664000175000017500000001104515165535636024203 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.helper; import haxe.Int64; import haxe.Int32; class ZigZag { /** * Convert n into a zigzag int. This allows negative numbers to be * represented compactly as a varint. */ public static function FromInt( n : Int) : UInt { #if php return cast(cast(cast(n,Int32) << 1,Int32) ^ cast(cast(n,Int32) >> 31,Int32),UInt); #else return cast(n << 1,UInt) ^ cast(n >> 31,UInt); #end } /** * Convert from zigzag int to int. */ public static function ToInt( n : UInt) : Int { #if php var a = (0x7FFFFFFF & cast(n >> 1,Int)); var b = (cast(n & 1,Int)); b = -b; // workaround for https://github.com/HaxeFoundation/haxe/issues/5288 return a ^ b; #else return (0x7FFFFFFF & cast(n >> 1,Int)) ^ (-cast(n & 1,Int)); #end } /** * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ public static function FromLong( n : Int64) : Int64 { return Int64.xor( Int64.shl(n, 1), Int64.shr(n, 63)); } /** * Convert from zigzag long to long. */ public static function ToLong( n : Int64) : Int64 { return Int64.xor( Int64.and( Int64.shr(n, 1), Int64.make(0x7FFFFFFF, 0xFFFFFFFF)), Int64.sub( Int64.make(0, 0), Int64.and(n, Int64.make(0,1)))); } #if debug private static function Test32( test : Int) : Void { var a : UInt = ZigZag.FromInt( test); var b : Int = ZigZag.ToInt(a); #if php test = test & 0xFFFFFFFF; // workaround for https://github.com/HaxeFoundation/haxe/issues/5289 #end if( test != b) throw 'ZigZag.Test32($test) failed: a = $a, b = $b'; } #end #if debug private static function Test64( test : haxe.Int64) : Void { var a : Int64 = ZigZag.FromLong( test); var b : Int64 = ZigZag.ToLong(a); if( Int64.compare( test, b) != 0) throw 'ZigZag.Test64($test) failed: a = $a, b = $b'; } #end #if debug public static function UnitTest() : Void { var u1 : UInt = 0xFFFFFFFE; var u2 : UInt = 0xFFFFFFFF; var i1 : Int = 2147483647; var i2 : Int = -2147483648; #if php i2 = i2 & 0xFFFFFFFF; // workaround for https://github.com/HaxeFoundation/haxe/issues/5289 #end // protobuf testcases if( FromInt(0) != 0) throw 'pb #1 to ZigZag'; if( FromInt(-1) != 1) throw 'pb #2 to ZigZag'; if( FromInt(1) != 2) throw 'pb #3 to ZigZag'; if( FromInt(-2) != 3) throw 'pb #4 to ZigZag'; if( FromInt(i1) != u1) throw 'pb #5 to ZigZag'; if( FromInt(i2) != u2) throw 'pb #6 to ZigZag'; // protobuf testcases if( ToInt(0) != 0) throw 'pb #1 from ZigZag'; if( ToInt(1) != -1) throw 'pb #2 from ZigZag'; if( ToInt(2) != 1) throw 'pb #3 from ZigZag'; if( ToInt(3) != -2) throw 'pb #4 from ZigZag'; if( ToInt(u1) != i1) throw 'pb #5 from ZigZag, got ${ToInt(u1)} expected $i1'; if( ToInt(u2) != i2) throw 'pb #6 from ZigZag, got ${ToInt(u2)} expected $i2'; // back and forth 32 Test32( 0); for( i in 0 ... 30) { Test32( 1 << i); Test32( -(1 << i)); } Test32( 0x7FFFFFFF); Test32( cast(0x80000000,Int)); // back and forth 64 Test64( Int64.make(0,0)); for( i in 0 ... 62) { Test64( Int64.shl( Int64.make(0,1), i)); Test64( Int64.sub( Int64.make(0,0), Int64.shl( Int64.make(0,1), i))); } Test64( Int64.make(0x7FFFFFFF,0xFFFFFFFF)); Test64( Int64.make(cast(0x80000000,Int),0x00000000)); } #end } thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx0000664000175000017500000002220115165535636024346 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.helper; import Map; import haxe.Int64; import haxe.ds.IntMap; // Int64Map allows mapping of Int64 keys to arbitrary values. // ObjectMap<> cannot be used, since we want to compare by value, not address class Int64Map implements haxe.Constraints.IMap< Int64, T> { private var SubMaps : IntMap< IntMap< T>>; // Hi -> Lo -> Value public function new() : Void { SubMaps = new IntMap< IntMap< T>>(); }; private function GetSubMap( hi : haxe.Int32, canCreate : Bool) : IntMap< T> { if( SubMaps.exists(hi)) { return SubMaps.get(hi); } if( ! canCreate) { return null; } var lomap = new IntMap< T>(); SubMaps.set( hi, lomap); return lomap; } private function GetLowMap( key : haxe.Int64, canCreate : Bool) : IntMap< T> { #if( haxe_ver < 3.2) return GetSubMap( Int64.getHigh(key), canCreate); #else return GetSubMap( key.high, canCreate); #end } private function GetLowIndex( key : haxe.Int64) : haxe.Int32 { #if( haxe_ver < 3.2) return Int64.getLow(key); #else return key.low; #end } private function NullCheck( key : haxe.Int64) : Bool { #if( haxe_ver < 3.2) return (key != null); #else return true; // Int64 is not nullable anymore (it never really was) #end }; /** Maps `key` to `value`. If `key` already has a mapping, the previous value disappears. If `key` is null, the result is unspecified. **/ public function set( key : Int64, value : T ) : Void { if( ! NullCheck(key)) { return; } var lomap = GetLowMap( key, true); lomap.set( GetLowIndex(key), value); } /** Returns the current mapping of `key`. If no such mapping exists, null is returned. If `key` is null, the result is unspecified. Note that a check like `map.get(key) == null` can hold for two reasons: 1. the map has no mapping for `key` 2. the map has a mapping with a value of `null` If it is important to distinguish these cases, `exists()` should be used. **/ public function get( key : Int64) : Null { if( ! NullCheck(key)) { return null; } var lomap = GetLowMap( key, true); if( lomap == null) { return null; } return lomap.get( GetLowIndex(key)); } /** Returns true if `key` has a mapping, false otherwise. If `key` is null, the result is unspecified. **/ public function exists( key : Int64) : Bool { if( ! NullCheck(key)) { return false; } var lomap = GetLowMap( key, true); if( lomap == null) { return false; } return lomap.exists( GetLowIndex(key)); } public function clear() : Void { SubMaps.clear(); } public function copy() : haxe.Constraints.IMap< Int64, T> { var retval = new Int64Map(); for( key in this.keys()) retval.set( key, this.get(key)); return retval; } /** Removes the mapping of `key` and returns true if such a mapping existed, false otherwise. If `key` is null, the result is unspecified. **/ public function remove( key : Int64) : Bool { if( ! NullCheck(key)) { return false; } var lomap = GetLowMap( key, true); if( lomap == null) { return false; } return lomap.remove( GetLowIndex(key)); } /** Returns an Iterator over the keys of `this` Map. The order of keys is undefined. **/ public function keys() : Iterator { return new Int64KeyIterator(SubMaps); } /** Returns an Iterator over the values of `this` Map. The order of values is undefined. **/ public function iterator() : Iterator { return new Int64ValueIterator(SubMaps); } /** Returns an Iterator over the values of `this` Map. The order of values is undefined. **/ public function keyValueIterator() : KeyValueIterator { return new Int64KeyValueIterator(SubMaps); } /** Returns a String representation of `this` Map. The exact representation depends on the platform and key-type. **/ public function toString() : String { var result : String = "{"; var first = true; for( key in this.keys()) { if( first) { first = false; } else { result += ","; } result += " "; var value = this.get(key); result += Int64.toStr(key) + ' => $value'; } return result + "}"; } } // internal helper class for Int64Map // all class with matching methods can be used as iterator (duck typing) private class Int64MapIteratorBase { private var SubMaps : IntMap< IntMap< T>>; // Hi -> Lo -> Value private var HiIterator : Iterator< Int> = null; private var LoIterator : Iterator< Int> = null; private var CurrentHi : Int = 0; public function new( data : IntMap< IntMap< T>>) : Void { SubMaps = data; HiIterator = SubMaps.keys(); LoIterator = null; CurrentHi = 0; }; /** Returns false if the iteration is complete, true otherwise. Usually iteration is considered to be complete if all elements of the underlying data structure were handled through calls to next(). However, in custom iterators any logic may be used to determine the completion state. **/ public function hasNext() : Bool { if( (LoIterator != null) && LoIterator.hasNext()) { return true; } while( (HiIterator != null) && HiIterator.hasNext()) { CurrentHi = HiIterator.next(); LoIterator = SubMaps.get(CurrentHi).keys(); if( (LoIterator != null) && LoIterator.hasNext()) { return true; } } HiIterator = null; LoIterator = null; return false; } } // internal helper class for Int64Map // all class with matching methods can be used as iterator (duck typing) private class Int64KeyIterator extends Int64MapIteratorBase { public function new( data : IntMap< IntMap< T>>) : Void { super(data); }; /** Returns the current item of the Iterator and advances to the next one. This method is not required to check hasNext() first. A call to this method while hasNext() is false yields unspecified behavior. **/ public function next() : Int64 { if( hasNext()) { return Int64.make( CurrentHi, LoIterator.next()); } else { throw "no more elements"; } } } // internal helper class for Int64Map // all class with matching methods can be used as iterator (duck typing) private class Int64KeyValueIterator extends Int64MapIteratorBase { public function new( data : IntMap< IntMap< T>>) : Void { super(data); }; /** Returns the current key/item pair and advances to the next one. This method is not required to check hasNext() first. A call to this method while hasNext() is false yields unspecified behavior. **/ public function next() : {value:T,key:Int64} { if( ! hasNext()) throw "no more elements"; return { key: Int64.make( CurrentHi, LoIterator.next()), value: SubMaps.get(CurrentHi).get(LoIterator.next()) }; } } // internal helper class for Int64Map // all class with matching methods can be used as iterator (duck typing) private class Int64ValueIterator extends Int64MapIteratorBase { public function new( data : IntMap< IntMap< T>>) : Void { super(data); }; /** Returns the current item of the Iterator and advances to the next one. This method is not required to check hasNext() first. A call to this method while hasNext() is false yields unspecified behavior. **/ public function next() : T { if( hasNext()) { return SubMaps.get(CurrentHi).get(LoIterator.next()); } else { throw "no more elements"; } } } // EOF thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/IntSet.hx0000664000175000017500000000501115165535636024212 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.helper; class IntSet { private var _elements = new haxe.ds.IntMap(); private var _size : Int = 0; public var size(get,never) : Int; public function new( values : Array = null) { if ( values != null) { addRange(values.iterator()); } } public function iterator():Iterator { return _elements.keys(); } public function traceAll() : Void { trace('$_size entries'); for(entry in this) { var yes = contains(entry); trace('- $entry, contains() = $yes'); } } public function add(o : Int) : Bool { if( _elements.exists(o)) { return false; } _size++; _elements.set(o,_size); return true; } public function addRange( values : Iterator) { if ( values != null) { for ( value in values) { add(value); } } } public function clear() : Void { while( _size > 0) { remove( _elements.keys().next()); } } public function contains(o : Int) : Bool { return _elements.exists(o); } public function isEmpty() : Bool { return _size == 0; } public function remove(o : Int) : Bool { if (contains(o)) { _elements.remove(o); _size--; return true; } else { return false; } } public function toArray() : Array { var ret : Array = new Array(); for (key in _elements.keys()) { ret.push(key); } return ret; } public function get_size() : Int { return _size; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/BitConverter.hx0000664000175000017500000002021015165535636025410 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.helper; import haxe.Int64; import haxe.io.Bytes; import haxe.io.BytesBuffer; class BitConverter { public static function DoubleToInt64Bits( db : Float) : Int64 { var buf = new BytesBuffer(); buf.addDouble( db); return bytesToLong( buf.getBytes()); } public static function Int64BitsToDouble( i64 : Int64) : Float { var buf = new BytesBuffer(); buf.add( fixedLongToBytes( i64)); return buf.getBytes().getDouble(0); } /** * Convert a long into little-endian bytes in buf starting at off and going * until off+7. */ public static function fixedLongToBytes( n : Int64) : Bytes { var buf = Bytes.alloc(8); #if( haxe_ver < 3.2) buf.set( 0, Int64.getLow( Int64.and( n, Int64.make(0, 0xff)))); buf.set( 1, Int64.getLow( Int64.and( Int64.shr( n, 8), Int64.make(0, 0xff)))); buf.set( 2, Int64.getLow( Int64.and( Int64.shr( n, 16), Int64.make(0, 0xff)))); buf.set( 3, Int64.getLow( Int64.and( Int64.shr( n, 24), Int64.make(0, 0xff)))); buf.set( 4, Int64.getLow( Int64.and( Int64.shr( n, 32), Int64.make(0, 0xff)))); buf.set( 5, Int64.getLow( Int64.and( Int64.shr( n, 40), Int64.make(0, 0xff)))); buf.set( 6, Int64.getLow( Int64.and( Int64.shr( n, 48), Int64.make(0, 0xff)))); buf.set( 7, Int64.getLow( Int64.and( Int64.shr( n, 56), Int64.make(0, 0xff)))); #else buf.set( 0, Int64.and( n, Int64.make(0, 0xff)).low); buf.set( 1, Int64.and( Int64.shr( n, 8), Int64.make(0, 0xff)).low); buf.set( 2, Int64.and( Int64.shr( n, 16), Int64.make(0, 0xff)).low); buf.set( 3, Int64.and( Int64.shr( n, 24), Int64.make(0, 0xff)).low); buf.set( 4, Int64.and( Int64.shr( n, 32), Int64.make(0, 0xff)).low); buf.set( 5, Int64.and( Int64.shr( n, 40), Int64.make(0, 0xff)).low); buf.set( 6, Int64.and( Int64.shr( n, 48), Int64.make(0, 0xff)).low); buf.set( 7, Int64.and( Int64.shr( n, 56), Int64.make(0, 0xff)).low); #end return buf; } /** * Note that it's important that the mask bytes are long literals, * otherwise they'll default to ints, and when you shift an int left 56 bits, * you just get a messed up int. */ public static function bytesToLong( bytes : Bytes) : Int64 { var result : Int64 = Int64.make(0, 0); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(7))); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(6))); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(5))); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(4))); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(3))); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(2))); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(1))); result = Int64.or( Int64.shl( result, 8), Int64.make( 0, bytes.get(0))); return result; } #if debug private static function TestBTL( test : Int64) : Void { var buf : Bytes = fixedLongToBytes( test); var erg = bytesToLong(buf); if ( Int64.compare( erg, test) != 0) throw 'BitConverter.bytesToLongTest($test) failed: $erg'; } #end #if debug private static function TestPair( a : Float, b : Int64) : Void { var bx = DoubleToInt64Bits(a); if ( Int64.compare( bx, b) != 0) throw 'BitConverter.TestPair: DoubleToInt64Bits($a): expected $b, got $bx'; var ax = Int64BitsToDouble(b); if( ax != a) throw 'BitConverter.TestPair: Int64BitsToDouble($b: expected $a, got $ax'; } #end #if debug public static function UnitTest() : Void { // bytesToLong() var i : Int; TestBTL( Int64.make(0,0)); for ( i in 0 ... 62) { TestBTL( Int64.shl( Int64.make(0,1), i)); TestBTL( Int64.sub( Int64.make(0,0), Int64.shl( Int64.make(0,1), i))); } TestBTL( Int64.make(0x7FFFFFFF,0xFFFFFFFF)); TestBTL( Int64.make(cast(0x80000000,Int),0x00000000)); // DoubleToInt64Bits; TestPair( 1.0000000000000000E+000, Int64.make(cast(0x3FF00000,Int),cast(0x00000000,Int))); TestPair( 1.5000000000000000E+001, Int64.make(cast(0x402E0000,Int),cast(0x00000000,Int))); TestPair( 2.5500000000000000E+002, Int64.make(cast(0x406FE000,Int),cast(0x00000000,Int))); TestPair( 4.2949672950000000E+009, Int64.make(cast(0x41EFFFFF,Int),cast(0xFFE00000,Int))); TestPair( 3.9062500000000000E-003, Int64.make(cast(0x3F700000,Int),cast(0x00000000,Int))); TestPair( 2.3283064365386963E-010, Int64.make(cast(0x3DF00000,Int),cast(0x00000000,Int))); TestPair( 1.2345678901230000E-300, Int64.make(cast(0x01AA74FE,Int),cast(0x1C1E7E45,Int))); TestPair( 1.2345678901234500E-150, Int64.make(cast(0x20D02A36,Int),cast(0x586DB4BB,Int))); TestPair( 1.2345678901234565E+000, Int64.make(cast(0x3FF3C0CA,Int),cast(0x428C59FA,Int))); TestPair( 1.2345678901234567E+000, Int64.make(cast(0x3FF3C0CA,Int),cast(0x428C59FB,Int))); TestPair( 1.2345678901234569E+000, Int64.make(cast(0x3FF3C0CA,Int),cast(0x428C59FC,Int))); TestPair( 1.2345678901234569E+150, Int64.make(cast(0x5F182344,Int),cast(0xCD3CDF9F,Int))); TestPair( 1.2345678901234569E+300, Int64.make(cast(0x7E3D7EE8,Int),cast(0xBCBBD352,Int))); TestPair( -1.7976931348623157E+308, Int64.make(cast(0xFFEFFFFF,Int),cast(0xFFFFFFFF,Int))); TestPair( 1.7976931348623157E+308, Int64.make(cast(0x7FEFFFFF,Int),cast(0xFFFFFFFF,Int))); TestPair( 4.9406564584124654E-324, Int64.make(cast(0x00000000,Int),cast(0x00000001,Int))); TestPair( 0.0000000000000000E+000, Int64.make(cast(0x00000000,Int),cast(0x00000000,Int))); TestPair( 4.94065645841247E-324, Int64.make(cast(0x00000000,Int),cast(0x00000001,Int))); TestPair( 3.2378592100206092E-319, Int64.make(cast(0x00000000,Int),cast(0x0000FFFF,Int))); TestPair( 1.3906711615669959E-309, Int64.make(cast(0x0000FFFF,Int),cast(0xFFFFFFFF,Int))); TestPair( Math.NEGATIVE_INFINITY, Int64.make(cast(0xFFF00000,Int),cast(0x00000000,Int))); TestPair( Math.POSITIVE_INFINITY, Int64.make(cast(0x7FF00000,Int),cast(0x00000000,Int))); // NaN is special var i64nan = DoubleToInt64Bits( Math.NaN); var i64cmp = Int64.make(cast(0xFFF80000, Int), cast(0x00000000, Int)); if ( ! Math.isNaN( Int64BitsToDouble( i64cmp))) throw 'BitConverter NaN-Test #1: expected NaN'; // For doubles, a quiet NaN is a bit pattern // between 7FF8000000000000 and 7FFFFFFFFFFFFFFF // or FFF8000000000000 and FFFFFFFFFFFFFFFF var min1 = Int64.make( cast(0x7FF80000, Int), cast(0x00000000, Int)); var max1 = Int64.make( cast(0x7FFFFFFF, Int), cast(0xFFFFFFFF, Int)); var min2 = Int64.make( cast(0xFFF80000, Int), cast(0x00000000, Int)); var max2 = Int64.make( cast(0xFFFFFFFF, Int), cast(0xFFFFFFFF, Int)); var ok1 = (Int64.compare( min1, i64nan) <= 0) && (Int64.compare( i64nan, max1) <= 0); var ok2 = (Int64.compare( min2, i64nan) <= 0) && (Int64.compare( i64nan, max2) <= 0); if( ! (ok1 || ok2)) throw 'BitConverter NaN-Test #2: failed'; } #end } thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/StringSet.hx0000664000175000017500000000505215165535636024733 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.helper; class StringSet { private var _elements = new haxe.ds.StringMap(); private var _size : Int = 0; public var size(get,never) : Int; public function new( values : Array = null) { if ( values != null) { addRange(values.iterator()); } } public function iterator():Iterator { return _elements.keys(); } public function traceAll() : Void { trace('$_size entries'); for(entry in this) { var yes = contains(entry); trace('- $entry, contains() = $yes'); } } public function add(o : String) : Bool { if( _elements.exists(o)) { return false; } _size++; _elements.set(o,_size); return true; } public function addRange( values : Iterator) { if ( values != null) { for ( value in values) { add(value); } } } public function clear() : Void { while( _size > 0) { remove( _elements.keys().next()); } } public function contains(o : String) : Bool { return _elements.exists(o); } public function isEmpty() : Bool { return _size == 0; } public function remove(o : String) : Bool { if (contains(o)) { _elements.remove(o); _size--; return true; } else { return false; } } public function toArray() : Array { var ret : Array = new Array(); for (key in _elements.keys()) { ret.push(key); } return ret; } public function get_size() : Int { return _size; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/helper/ObjectSet.hx0000664000175000017500000000502315165535636024671 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.helper; import Map; class ObjectSet { private var _elements = new haxe.ds.ObjectMap(); private var _size : Int = 0; public var size(get,never) : Int; public function new( values : Array = null) { if ( values != null) { addRange(values.iterator()); } } public function iterator():Iterator { return _elements.keys(); } public function traceAll() : Void { trace('$_size entries'); for(entry in this) { var yes = contains(entry); trace('- $entry, contains() = $yes'); } } public function add(o : K) : Bool { if( _elements.exists(o)) { return false; } _size++; _elements.set(o,_size); return true; } public function addRange( values : Iterator) { if ( values != null) { for ( value in values) { add(value); } } } public function clear() : Void { while( _size > 0) { remove( _elements.keys().next()); } } public function contains(o : K) : Bool { return _elements.exists(o); } public function isEmpty() : Bool { return _size == 0; } public function remove(o : K) : Bool { if (contains(o)) { _elements.remove(o); _size--; return true; } else { return false; } } public function toArray() : Array { var ret : Array = new Array(); for (key in _elements.keys()) { ret.push(key); } return ret; } public function get_size() : Int { return _size; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/server/0000775000175000017500000000000015165535636022475 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/apache/thrift/server/TServerEventHandler.hx0000664000175000017500000000311515165535636026730 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.*; import org.apache.thrift.transport.*; import org.apache.thrift.protocol.*; // Interface implemented by server users to handle events from the server interface TServerEventHandler { // Called before the server begins function preServe() : Void; // Called when a new client has connected and is about to being processing function createContext( input : TProtocol, output : TProtocol) : Dynamic; // Called when a client has finished request-handling to delete server context function deleteContext( serverContext : Dynamic, input : TProtocol, output : TProtocol) : Void; // Called when a client is about to call the processor function processContext( serverContext : Dynamic, transport : TTransport) : Void; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/server/TSimpleServer.hx0000664000175000017500000001233615165535636025607 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.meta_data.*; // Simple single-threaded server for testing class TSimpleServer extends TServer { private var stop : Bool = false; //stops just after input transport returns EOF //useful for limited scenarios, like embeding into php server public var runOnce : Bool = false; public function new( processor : TProcessor, serverTransport : TServerTransport, transportFactory : TTransportFactory = null, protocolFactory : TProtocolFactory = null, logger : Dynamic->Void = null) { super( processor, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, logger); } public override function Serve() : Void { try { serverTransport.Listen(); } catch (ttx : TTransportException) { logDelegate(ttx); return; } // Fire the preServe server event when server is up, // but before any client connections if (serverEventHandler != null) { serverEventHandler.preServe(); } while( ! stop) { var client : TTransport = null; var inputTransport : TTransport = null; var outputTransport : TTransport = null; var inputProtocol : TProtocol = null; var outputProtocol : TProtocol = null; var connectionContext : Dynamic = null; try { client = serverTransport.Accept(); if (client != null) { inputTransport = inputTransportFactory.getTransport( client); outputTransport = outputTransportFactory.getTransport( client); inputProtocol = inputProtocolFactory.getProtocol( inputTransport); outputProtocol = outputProtocolFactory.getProtocol( outputTransport); // Recover event handler (if any) and fire createContext // server event when a client connects if (serverEventHandler != null) { connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol); } // Process client requests until client disconnects while( true) { // Fire processContext server event // N.B. This is the pattern implemented in C++ and the event fires provisionally. // That is to say it may be many minutes between the event firing and the client request // actually arriving or the client may hang up without ever makeing a request. if (serverEventHandler != null) { serverEventHandler.processContext(connectionContext, inputTransport); } //Process client request (blocks until transport is readable) if( ! processor.process( inputProtocol, outputProtocol)) { break; } } } } catch( ttx : TTransportException) { // Usually a client disconnect, expected if(runOnce && ttx.errorID == TTransportException.END_OF_FILE) { //input returns eof, exit //follows lib/cpp/src/thrift/server/TServerFramework.cpp Stop(); } } catch( pex : TProtocolException) { logDelegate('$pex ${pex.errorID} ${pex.errorMsg}'); // Unexpected } catch( e : Dynamic) { logDelegate(e); // Unexpected } if(client != null && !runOnce) { client.close(); } // Fire deleteContext server event after client disconnects if (serverEventHandler != null) { serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol); } } } public override function Stop() : Void { stop = true; serverTransport.Close(); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/server/TServer.hx0000664000175000017500000000737315165535636024442 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.meta_data.*; class TServer { private var processor : TProcessor = null; private var serverTransport : TServerTransport = null; private var inputTransportFactory : TTransportFactory = null; private var outputTransportFactory : TTransportFactory = null; private var inputProtocolFactory : TProtocolFactory = null; private var outputProtocolFactory : TProtocolFactory = null; // server events public var serverEventHandler : TServerEventHandler = null; // Log delegation private var _logDelegate : Dynamic->Void = null; public var logDelegate(get,set) : Dynamic->Void; public function new( processor : TProcessor, serverTransport : TServerTransport, inputTransportFactory : TTransportFactory = null, outputTransportFactory : TTransportFactory = null, inputProtocolFactory : TProtocolFactory = null, outputProtocolFactory : TProtocolFactory = null, logDelegate : Dynamic->Void = null) { this.processor = processor; this.serverTransport = serverTransport; this.inputTransportFactory = inputTransportFactory; this.outputTransportFactory = outputTransportFactory; this.inputProtocolFactory = inputProtocolFactory; this.outputProtocolFactory = outputProtocolFactory; this.logDelegate = logDelegate; ApplyMissingDefaults(); } private function ApplyMissingDefaults() { if( processor == null) throw "Invalid server configuration: processor missing"; if( serverTransport == null) throw "Invalid server configuration: serverTransport missing"; if( inputTransportFactory == null) inputTransportFactory = new TTransportFactory(); if( outputTransportFactory == null) outputTransportFactory = new TTransportFactory(); if( inputProtocolFactory == null) inputProtocolFactory = new TBinaryProtocolFactory(); if( outputProtocolFactory == null) outputProtocolFactory= new TBinaryProtocolFactory(); if( logDelegate == null) logDelegate = DefaultLogDelegate; } private function set_logDelegate(value : Dynamic->Void) : Dynamic->Void { if(value != null) { _logDelegate = value; } else { _logDelegate = DefaultLogDelegate; } return _logDelegate; } private function get_logDelegate() : Dynamic->Void { return _logDelegate; } private function DefaultLogDelegate(value : Dynamic) : Void { trace( value); } public function Serve() : Void { throw new AbstractMethodError(); } public function Stop() : Void { throw new AbstractMethodError(); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/0000775000175000017500000000000015165535636023223 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx0000664000175000017500000000220415165535636030351 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TConfiguration; import org.apache.thrift.transport.*; class TFramedTransportFactory extends TTransportFactory { public function new() { super(); } public override function getTransport(base : TTransport) : TTransport { return new TFramedTransport(base); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx0000664000175000017500000000321715165535636027076 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; class TServerTransport { private var Configuration(default,null) : TConfiguration; // private CTOR to prevent direct instantiation // in other words, this class MUST be extended private function new( config : TConfiguration) { Configuration = (config != null) ? config : new TConfiguration(); } public function Accept() : TTransport { var transport = AcceptImpl(); if (transport == null) { throw new TTransportException( TTransportException.UNKNOWN, "accept() may not return NULL"); } return transport; } public function Listen() : Void { throw new AbstractMethodError(); } public function Close() : Void { throw new AbstractMethodError(); } private function AcceptImpl() : TTransport { throw new AbstractMethodError(); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx0000664000175000017500000000233215165535636030677 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.transport.*; class TBufferedTransportFactory extends TTransportFactory { private var bufSize : Int; public function new(bufSize : Int = TBufferedTransport.DEFAULT_BUFSIZE) { super(); this.bufSize = bufSize; } public override function getTransport(base : TTransport) : TTransport { return new TBufferedTransport(base, bufSize); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx0000664000175000017500000000625215165535636025773 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import haxe.Timer; import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.BytesOutput; import haxe.io.BytesInput; import haxe.Http; #if js import js.lib.Promise; #end /** * HTTP implementation of the TTransport interface. Used for working with a * Thrift web services implementation. */ class THttpClient extends TEndpointTransport { private var requestBuffer_ : BytesOutput = new BytesOutput(); private var responseBuffer_ : BytesInput = null; private var request_ : Http = null; public function new( requestUrl : String, config : TConfiguration = null) : Void { super(config); request_ = new Http(requestUrl); request_.addHeader( "Content-Type", "application/x-thrift"); } public override function open() : Void { ResetConsumedMessageSize(); } public override function close() : Void { } public override function isOpen() : Bool { return true; } public override function read(buf:BytesBuffer, off : Int, len : Int) : Int { if (responseBuffer_ == null) { throw new TTransportException(TTransportException.UNKNOWN, "Response buffer is empty, no request."); } var data =Bytes.alloc(len); len = responseBuffer_.readBytes(data, off, len); buf.addBytes(data,0,len); CountConsumedMessageBytes(len); return len; } public override function write(buf:Bytes, off : Int, len : Int) : Void { requestBuffer_.writeBytes(buf, off, len); } public override function flush(callback:Dynamic->Void = null) : Void { var buffer = requestBuffer_; requestBuffer_ = new BytesOutput(); responseBuffer_ = null; ResetConsumedMessageSize(); /* request_.onData = function(data : String) { var tmp = new BytesBuffer(); tmp.addString(data); responseBuffer_ = new BytesInput(tmp.getBytes()); if( callback != null) { callback(null); }; */ request_.onBytes = function(data : Bytes) { responseBuffer_ = new BytesInput(data); if( callback != null) { callback(null); } }; request_.onError = function(msg : String) { if( callback != null) { callback(new TTransportException(TTransportException.UNKNOWN, "IOError: " + msg)); } }; // the request request_.setPostBytes(buffer.getBytes()); request_.request(true/*POST*/); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TTransport.hx0000664000175000017500000001110515165535636025702 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import haxe.Int64; import haxe.io.Eof; import haxe.io.Bytes; import haxe.io.BytesBuffer; import org.apache.thrift.AbstractMethodError; class TTransport { public var Configuration(get, never) : TConfiguration; public function get_Configuration() : TConfiguration throw "abstract method called"; public function UpdateKnownMessageSize(size : Int64) : Void throw "abstract method called"; public function CheckReadBytesAvailable(numBytes : Int64) : Void throw "abstract method called"; /** * Queries whether the transport is open. * * @return True if the transport is open. */ public function isOpen() : Bool { throw new AbstractMethodError(); } /** * Is there more data to be read? * * @return True if the remote side is still alive and feeding us */ public function peek() : Bool { return isOpen(); } /** * Opens the transport for reading/writing. * * @throws TTransportException if the transport could not be opened */ public function open() : Void { throw new AbstractMethodError(); } /** * Closes the transport. */ public function close() : Void { throw new AbstractMethodError(); }; /** * Reads up to len bytes into buffer buf, starting att offset off. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The bytes count actually read * @throws TTransportException if there was an error reading data */ public function read( buf : BytesBuffer, off : Int, len : Int) : Int { throw new AbstractMethodError(); } /** * Guarantees that all of len bytes are actually read off the transport. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read, which must be equal to len * @throws TTransportException if there was an error reading data */ public function readAll(buf : BytesBuffer, off : Int, len : Int) : Int { var got : Int = 0; var ret : Int = 0; while (got < len) { try { ret = read(buf, off+got, len-got); if (ret <= 0) { throw new TTransportException(TTransportException.UNKNOWN, "Cannot read. Remote side has closed. Tried to read " + len + " bytes, but only got " + got + " bytes."); } } catch (eof : Eof) { throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $len bytes!'); } got += ret; } return got; } /** * Writes the buffer to the output * * @param buf The output data buffer * @throws TTransportException if an error occurs writing data */ public function writeAll(buf:Bytes) : Void { write(buf, 0, buf.length); } /** * Writes up to len bytes from the buffer. * * @param buf The output data buffer * @param off The offset to start writing from * @param len The number of bytes to write * @throws TTransportException if there was an error writing data */ public function write(buf:Bytes, off : Int, len : Int) : Void { throw new AbstractMethodError(); } /** * Flush any pending data out of a transport buffer. * * @throws TTransportException if there was an error writing out data. */ public function flush(callback:Dynamic->Void =null) : Void { if(callback != null) callback(new AbstractMethodError()); else throw new AbstractMethodError(); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx0000664000175000017500000000611015165535636027056 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TConfiguration; import org.apache.thrift.transport.*; import org.apache.thrift.helper.*; import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.BytesOutput; import haxe.io.BytesInput; class TStreamTransport extends TEndpointTransport { public var InputStream(default,null) : TStream; public var OutputStream(default,null) : TStream; public function new( input : TStream, output : TStream, config : TConfiguration) { super(config); this.InputStream = input; this.OutputStream = output; } public override function isOpen() : Bool { return true; } public override function peek() : Bool { return (InputStream != null); } public override function open() : Void { } public override function close() : Void { if (InputStream != null) { InputStream.Close(); InputStream = null; } if (OutputStream != null) { OutputStream.Close(); OutputStream = null; } } public override function read( buf : BytesBuffer, off : Int, len : Int) : Int { if (InputStream == null) { throw new TTransportException( TTransportException.NOT_OPEN, "Cannot read from null InputStream"); } var data : Bytes = Bytes.alloc(len); var size = InputStream.Read( data, off, len); buf.addBytes( data, 0, size); return size; } public override function write(buf:Bytes, off : Int, len : Int) : Void { if (OutputStream == null) { throw new TTransportException( TTransportException.NOT_OPEN, "Cannot write to null OutputStream"); } OutputStream.Write(buf, off, len); } public override function flush(callback:Dynamic->Void =null) : Void { if (OutputStream == null) { var err = new TTransportException( TTransportException.NOT_OPEN, "Cannot flush null OutputStream"); if(callback != null) callback(err); else throw err; } OutputStream.Flush(); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TMemoryStream.hx0000664000175000017500000000417315165535636026341 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.Output; class TMemoryStream implements TStream { private var Data : Bytes; public var Position(default,default) : Int; public function new( data : Bytes = null) { var target = new BytesBuffer(); if ( data != null) { for ( i in 0...data.length) { target.addByte( data.get(i)); ++Position; } } Data = target.getBytes(); } private function IsEof() : Bool { return (0 > Position) || (Position >= Data.length); } public function Close() : Void { var target = new BytesBuffer(); Data = target.getBytes(); Position = 0; } public function Peek() : Bool { return (! IsEof()); } // read count bytes into buf starting at offset public function Read( buf : Bytes, offset : Int, count : Int) : Int { var numRead = 0; for ( i in 0...count) { if ( IsEof()) break; buf.set( offset + i, Data.get( Position++)); ++numRead; } return numRead; } // write count bytes from buf starting at offset public function Write( buf : Bytes, offset : Int, count : Int) : Void { var numBytes = buf.length - offset; if ( numBytes > count) { numBytes = count; } for ( i in 0...numBytes) { Data.set( Position + i, buf.get( offset + i)); } } public function Flush() : Void { // nothing to do } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx0000664000175000017500000000321015165535636027206 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import haxe.Int64; import org.apache.thrift.TConfiguration; class TLayeredTransport extends TTransport { private var InnerTransport : TTransport; public override function get_Configuration() : TConfiguration { return InnerTransport.Configuration; } // private CTOR to prevent direct instantiation // in other words, this class MUST be extended private function new(transport : TTransport) { if( transport != null) InnerTransport = transport; else throw new TTransportException( TTransportException.UNKNOWN, "Inner transport must not be null"); } public override function UpdateKnownMessageSize(size : Int64) : Void { InnerTransport.UpdateKnownMessageSize(size); } public override function CheckReadBytesAvailable(numBytes : Int64) : Void { InnerTransport.CheckReadBytesAvailable(numBytes); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TSocket.hx0000664000175000017500000002052015165535636025137 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; #if (cs || neko || cpp || java || macro || lua || php || python || hl) import sys.net.Socket; #elseif flash import flash.net.Socket; #elseif js import js.html.WebSocket; #end import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.BytesInput; import haxe.io.BytesOutput; import haxe.io.Input; import haxe.io.Output; import haxe.io.Eof; import org.apache.thrift.TConfiguration; #if ! (flash || js) import sys.net.Host; #end /** * Socket implementation of the TTransport interface. Used for working with a * Thrift Socket Server based implementations. */ class TSocket extends TEndpointTransport { #if (flash || js) private var host : String; #else private var host : Host; #end private var port : Int; #if js private var socket : WebSocket = null; #else private var socket : Socket = null; #end #if js private var input : Dynamic = null; private var output : WebSocket = null; #elseif flash private var input : Socket = null; private var output : Socket = null; #else private var input : Input = null; private var output : Output = null; #end private var timeout : Float = 30; private var obuffer : BytesOutput = new BytesOutput(); private var ioCallback : TException->Void = null; private var readCount : Int = 0; public function new(host : String, port : Int, config : TConfiguration = null) : Void { super(config); #if (flash || js) this.host = host; #else this.host = new Host(host); #end this.port = port; } #if ! (flash || js) // used by TSocketServer public static function fromSocket( socket : Socket) : TSocket { var socketHost = socket.host(); var result = new TSocket(socketHost.host.toString(), socketHost.port); result.assignSocket(socket); return result; } #end public override function close() : Void { input = null; output = null; socket.close(); } public override function peek() : Bool { if( (input == null) || (socket == null)) { return false; } else { #if flash return (input.bytesAvailable > 0); #elseif js return true; #else var ready = Socket.select( [socket], null, null, 0); return (ready.read.length > 0); #end } } // Reads up to len bytes into buffer buf, starting att offset off. // May return less bytes than len required public override function read( buf : BytesBuffer, off : Int, len : Int) : Int { try { #if flash var remaining = len; while( remaining > 0) { buf.addByte( input.readByte()); --remaining; } CountConsumedMessageBytes(len); return len; #elseif js if( input == null) { throw new TTransportException(TTransportException.UNKNOWN, "Still no data "); // don't block } var nr = len; while( nr < len) { buf.addByte( input.get(off+nr)); ++nr; } CountConsumedMessageBytes(len); return len; #else //socket.waitForRead(); - no, this ignores timeout and blocks infinitely if(readCount < off) { input.read(off-readCount); readCount = off; } var data = Bytes.alloc(len); var got = input.readBytes(data, 0, len); buf.addBytes( data, 0, got); readCount += got; CountConsumedMessageBytes(got); return got; #end } catch (e : Eof) { trace('Eof $e'); throw new TTransportException(TTransportException.END_OF_FILE, "No more data available."); } catch (e : TException) { trace('TException $e'); throw e; } catch (e : Dynamic) { trace('Error $e'); throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error : $e'); } } public override function write(buf : Bytes, off : Int, len : Int) : Void { obuffer.writeBytes(buf, off, len); } public override function flush(callback : Dynamic->Void = null) : Void { if( ! isOpen()) { throw new TTransportException(TTransportException.NOT_OPEN, "Transport not open"); } #if flash var bytes = new flash.utils.ByteArray(); var data = obuffer.getBytes(); var len = 0; while( len < data.length) { bytes.writeByte(data.get(len)); ++len; } #elseif js var data = obuffer.getBytes(); var outbuf = new js.lib.Int8Array(data.length); var len = 0; while( len < data.length) { outbuf.set( [data.get(len)], len); ++len; } var bytes = outbuf.buffer; #else var bytes = obuffer.getBytes(); var len = bytes.length; #end obuffer = new BytesOutput(); ResetConsumedMessageSize(); ioCallback = callback; try { readCount = 0; #if js output.send( bytes); #else output.writeBytes( bytes, 0, bytes.length); #end if(ioCallback != null) { ioCallback(null); // success call } } catch (e : TException) { trace('TException $e, message : ${e.errorMsg}'); if(ioCallback != null) { ioCallback(e); } } catch (e : Dynamic) { trace(e); if(ioCallback != null) { ioCallback(new TTransportException(TTransportException.UNKNOWN, 'Bad IO error : $e')); } } } public override function isOpen() : Bool { return (socket != null); } public override function open() : Void { #if js var socket = new WebSocket(host); socket.onmessage = function( event : js.html.MessageEvent) { this.input = event.data; } #elseif flash var socket = new Socket(); socket.connect(host, port); #elseif php var socket = new Socket(); socket.connect(host, port); socket.setBlocking(true); socket.setTimeout(timeout); #else var socket = new Socket(); socket.setBlocking(true); socket.setFastSend(true); socket.setTimeout(timeout); socket.connect(host, port); #end assignSocket( socket); ResetConsumedMessageSize(); } #if js private function assignSocket( socket : WebSocket) : Void #else private function assignSocket( socket : Socket) : Void #end { this.socket = socket; #if (flash || js) output = socket; input = socket; #else output = socket.output; input = socket.input; #end } #if (flash) public function setTimeout( timeout : UInt) : Void { if(isOpen()) { socket.timeout = timeout; } this.timeout = timeout; } #else public function setTimeout( timeout : Float ) : Void { if(isOpen()) { #if ! (js) socket.setTimeout(timeout); #end } this.timeout = timeout; } #end } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx0000664000175000017500000001153315165535636027026 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.transport.*; import haxe.Int64; import haxe.io.Eof; import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.BytesOutput; import haxe.io.BytesInput; /** * TFramedTransport is a buffered TTransport that ensures a fully read message * every time by preceding messages with a 4-byte frame size. */ class TFramedTransport extends TLayeredTransport { private static inline var HEADER_SIZE = 4; /** * Buffer for output */ var writeBuffer_ : BytesOutput = new BytesOutput(); /** * Buffer for input */ var readBuffer_ : BytesInput = null; /** * Constructor wraps around another transport */ public function new( transport : TTransport) { super(transport); } public override function open() : Void { InnerTransport.open(); } public override function isOpen() : Bool { return InnerTransport.isOpen(); } public override function close() : Void { InnerTransport.close(); } public override function read(buf : BytesBuffer, off : Int, len : Int) : Int { try { var data = Bytes.alloc(len); if ((readBuffer_ != null) && (readBuffer_.position < readBuffer_.length)) { var got : Int = readBuffer_.readBytes(data, off, len); if (got > 0) { buf.addBytes(data,0,got); return got; }; }; // Read another frame of data readFrame(); var got = readBuffer_.readBytes(data, off, len); buf.addBytes(data,0,got); return got; } catch (eof : Eof) { throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $len bytes!'); } } function readFrameSize() : Int { try { var buffer = new BytesBuffer(); var len = InnerTransport.readAll( buffer, 0, HEADER_SIZE); var inp = new BytesInput( buffer.getBytes(), 0, HEADER_SIZE); inp.bigEndian = true; return inp.readInt32(); } catch(eof : Eof) { throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read ${HEADER_SIZE} bytes!'); } } function readFrame() : Void { var size : Int = readFrameSize(); if (size < 0) { throw new TTransportException(TTransportException.UNKNOWN, 'Read a negative frame size ($size)!'); }; if (size > Configuration.MaxFrameSize) { throw new TTransportException(TTransportException.UNKNOWN, 'Frame size ($size) larger than max length ($Configuration.MaxFrameSize)!'); }; UpdateKnownMessageSize(size + HEADER_SIZE); try { var buffer = new BytesBuffer(); size = InnerTransport.readAll( buffer, 0, size); readBuffer_ = new BytesInput( buffer.getBytes(), 0, size); readBuffer_.bigEndian = true; } catch(eof : Eof) { throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $size bytes!'); } } public override function write(buf : Bytes, off : Int, len : Int) : Void { writeBuffer_.writeBytes(buf, off, len); } function writeFrameSize(len : Int) : Void { var out = new BytesOutput(); out.bigEndian = true; out.writeInt32(len); InnerTransport.write(out.getBytes(), 0, HEADER_SIZE); } public override function flush( callback : Dynamic->Void =null) : Void { var buf : Bytes = writeBuffer_.getBytes(); var len : Int = buf.length; writeBuffer_ = new BytesOutput(); readBuffer_ = null; writeFrameSize(len); InnerTransport.write(buf, 0, len); InnerTransport.flush(callback); } public override function CheckReadBytesAvailable(numBytes : Int64) : Void { var buffered = readBuffer_.length - readBuffer_.position; if (buffered < numBytes) { numBytes -= buffered; InnerTransport.CheckReadBytesAvailable(numBytes); } } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TTransportException.hx0000664000175000017500000000267215165535636027572 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TException; class TTransportException extends TException { // WARNING: These are subject to be extended in the future, so we can't use enums // with Haxe 3.1.3 because of https://github.com/HaxeFoundation/haxe/issues/3649 public static inline var UNKNOWN : Int = 0; public static inline var NOT_OPEN : Int = 1; public static inline var ALREADY_OPEN : Int = 2; public static inline var TIMED_OUT : Int = 3; public static inline var END_OF_FILE : Int = 4; public function new(error : Int = UNKNOWN, message : String = "") { super(message, error); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx0000664000175000017500000000243115165535636030603 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /* wraps real transport, provided by constructor */ class TWrappingServerTransport extends TServerTransport { private var transport(default,null) : TTransport; public function new(transport : TTransport) { super(transport.Configuration); this.transport = transport; } public override function Listen() : Void { } private override function AcceptImpl() : TTransport { return transport; } public override function Close() : Void { } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TTransportFactory.hx0000664000175000017500000000261015165535636027233 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Factory class used to create wrapped instance of Transports. * This is used primarily in servers, which get Transports from * a ServerTransport and then may want to mutate them (i.e. create * a BufferedTransport from the underlying base transport) * */ class TTransportFactory { public function new() { } /** * Return a wrapped instance of the base Transport. * * @param trans The base transport * @return Wrapped Transport */ public function getTransport( trans : TTransport) : TTransport { return trans; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx0000664000175000017500000000741515165535636026336 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; #if (cs || neko || cpp || java || macro || lua || php || python || hl) import sys.net.Socket; #end import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.BytesInput; import haxe.io.BytesOutput; import haxe.io.Input; import haxe.io.Output; import haxe.io.Eof; import org.apache.thrift.TConfiguration; #if ! (flash || html5 || js) import sys.net.Host; class TServerSocket extends TServerTransport { // Underlying server with socket private var _socket : Socket= null; // Timeout for client sockets from accept private var _clientTimeout : Float = 5; // Whether or not to wrap new TSocket connections in buffers private var _useBufferedSockets : Bool = false; public function new(?address : String = 'localhost', port : Int, clientTimeout : Float = 5, useBufferedSockets : Bool = false, config : TConfiguration = null) { super(config); _clientTimeout = clientTimeout; _useBufferedSockets = useBufferedSockets; try { _socket = new Socket(); _socket.bind( new Host(address), port); } catch (e : Dynamic) { _socket = null; throw new TTransportException( TTransportException.UNKNOWN, 'Could not create ServerSocket on port $port: $e'); } } public override function Listen() : Void { // Make sure not to block on accept if (_socket != null) { try { #if !php _socket.listen(1); #end } catch (e : Dynamic) { trace('Error $e'); throw new TTransportException( TTransportException.UNKNOWN, 'Could not accept on listening socket: $e'); } } } private override function AcceptImpl() : TTransport { if (_socket == null) { throw new TTransportException( TTransportException.NOT_OPEN, "No underlying server socket."); } try { var accepted = _socket.accept(); var result = TSocket.fromSocket(accepted); result.setTimeout( _clientTimeout); if( _useBufferedSockets) { throw "buffered transport not yet supported"; // TODO //result = new TBufferedTransport(result); } return result; } catch (e : Dynamic) { trace('Error $e'); throw new TTransportException( TTransportException.UNKNOWN, '$e'); } } public override function Close() : Void { if (_socket != null) { try { _socket.close(); } catch (e : Dynamic) { trace('Error $e'); throw new TTransportException( TTransportException.UNKNOWN, 'WARNING: Could not close server socket: $e'); } _socket = null; } } } #end thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TFileStream.hx0000664000175000017500000000542615165535636025752 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; #if sys import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.Input; import haxe.io.Output; enum TFileMode { CreateNew; Append; Read; } class TFileStream implements TStream { public var FileName(default,null) : String; private var Input : sys.io.FileInput; private var Output : sys.io.FileOutput; public function new( fname : String, mode : TFileMode) { FileName = fname; switch ( mode) { case TFileMode.CreateNew: Output = sys.io.File.write( fname, true); case TFileMode.Append: Output = sys.io.File.append( fname, true); case TFileMode.Read: Input = sys.io.File.read( fname, true); default: throw new TTransportException( TTransportException.UNKNOWN, "Unsupported mode"); } } public function Close() : Void { if( Input != null) { Input.close(); Input = null; } if( Output != null) { Output.close(); Output = null; } } public function Peek() : Bool { if( Input == null) throw new TTransportException( TTransportException.NOT_OPEN, "File not open for input"); return (! Input.eof()); } public function Read( buf : Bytes, offset : Int, count : Int) : Int { if( Input == null) throw new TTransportException( TTransportException.NOT_OPEN, "File not open for input"); return Input.readBytes( buf, offset, count); } public function Write( buf : Bytes, offset : Int, count : Int) : Void { if( Output == null) throw new TTransportException( TTransportException.NOT_OPEN, "File not open for output"); Output.writeBytes( buf, offset, count); } public function Flush() : Void { if( Output != null) Output.flush(); } } #end thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx0000664000175000017500000000646315165535636027416 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import haxe.Int64; import org.apache.thrift.TConfiguration; class TEndpointTransport extends TTransport { private var MaxMessageSize(get, never) : Int64; private var KnownMessageSize(default, null) : Int64 ; private var RemainingMessageSize(default, null) : Int64 ; private var _configuration(default,null) : TConfiguration; public override function get_Configuration() : TConfiguration { return _configuration; } private function get_MaxMessageSize() : Int64 { return Configuration.MaxMessageSize; } // private CTOR to prevent direct instantiation // in other words, this class MUST be extended private function new( config : TConfiguration) { _configuration = (config != null) ? config : new TConfiguration(); ResetConsumedMessageSize(); } // Resets RemainingMessageSize to the configured maximum private function ResetConsumedMessageSize(?newSize : Int64) : Void { // full reset if (newSize == null) { KnownMessageSize = MaxMessageSize; RemainingMessageSize = MaxMessageSize; return; } // update only: message size can shrink, but not grow if (newSize > KnownMessageSize) throw new TTransportException(TTransportException.END_OF_FILE, "ResetConsumedMessageSize: MaxMessageSize reached"); KnownMessageSize = newSize; RemainingMessageSize = newSize; } // Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport). // Will throw if we already consumed too many bytes or if the new size is larger than allowed. public override function UpdateKnownMessageSize(size : Int64) : Void { var consumed = KnownMessageSize - RemainingMessageSize; ResetConsumedMessageSize(size); CountConsumedMessageBytes(consumed); } // Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data public override function CheckReadBytesAvailable(numBytes : Int64) : Void { if (RemainingMessageSize < numBytes || numBytes < 0) throw new TTransportException(TTransportException.END_OF_FILE, 'CheckReadBytesAvailable(${numBytes}): MaxMessageSize reached, only ${RemainingMessageSize} bytes available'); } // Consumes numBytes from the RemainingMessageSize. private function CountConsumedMessageBytes(numBytes : Int64) : Void { if (RemainingMessageSize >= numBytes) { RemainingMessageSize -= numBytes; } else { RemainingMessageSize = 0; throw new TTransportException(TTransportException.END_OF_FILE, 'CountConsumedMessageBytes(${numBytes}): MaxMessageSize reached'); } } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TStream.hx0000664000175000017500000000216115165535636025143 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import haxe.io.Bytes; import haxe.io.BytesBuffer; interface TStream { function Close() : Void; function Peek() : Bool; function Read( buf : Bytes, offset : Int, count : Int) : Int; function Write( buf : Bytes, offset : Int, count : Int) : Void; function Flush() : Void; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx0000664000175000017500000001531015165535636027773 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; #if swf import flash.errors.EOFError; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.utils.IDataInput; import flash.utils.IDataOutput; import haxe.io.Bytes; import flash.net.Socket; import flash.events.EventDispatcher; /** * HTTP implementation of the TTransport interface. Used for working with a * Thrift web services implementation. * Unlike Http Client, it uses a single POST, and chunk-encoding to transfer all messages. */ class TFullDuplexHttpClient extends TEndpointTransport { private var socket : Socket = null; private var host : String; private var port : Int; private var resource : String; private var stripped : Bool = false; private var obuffer : Bytes = new Bytes(); private var input : IDataInput; private var output : IDataOutput; private var bytesInChunk : Int = 0; private var CRLF : Bytes = new Bytes(); private var ioCallback : TException->Void = null; private var eventDispatcher : EventDispatcher = new EventDispatcher(); public function new(host : String, port : Int, resource : String, config : TConfiguration = null) : Void { super(config); CRLF.writeByte(13); CRLF.writeByte(10); this.host = host; this.port = port; this.resource = resource; } public override function close() : Void { this.input = null; this.output = null; this.stripped = false; socket.close(); ResetConsumedMessageSize(); } public override function peek() : Bool { if(socket.connected) { trace("Bytes remaining:" + socket.bytesAvailable); return socket.bytesAvailable>0; } return false; } public override function read(buf : Bytes, off : Int, len : Int) : Int { var n1 : Int = 0, n2 : Int = 0, n3 : Int = 0, n4 : Int = 0, cidx : Int = 2; var chunkSize : Bytes = new Bytes(); try { while (!stripped) { n1 = n2; n2 = n3; n3 = n4; n4 = input.readByte(); if ((n1 == 13) && (n2 == 10) && (n3 == 13) && (n4 == 10)) { stripped = true; } } // read chunk size if (bytesInChunk == 0) { n1 = input.readByte(); n2 = input.readByte(); chunkSize.writeByte(n1); chunkSize.writeByte(n2); while (!((n1 == 13) && (n2 == 10))) { n1 = n2; n2 = input.readByte(); chunkSize.writeByte(n2); } bytesInChunk = parseInt(chunkSize.toString(), 16); } input.readBytes(buf, off, len); debugBuffer(buf); bytesInChunk -= len; if (bytesInChunk == 0) { // advance the : "\r\n" input.readUTFBytes(2); } CountConsumedMessageBytes(len); return len; } catch (e : EOFError) { trace(e); throw new TTransportException(TTransportException.UNKNOWN, "No more data available."); } catch (e : TException) { trace('TException $e'); throw e; } catch (e : Error) { trace(e); throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e'); } catch (e : Dynamic) { trace(e); throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e'); } return 0; } public function debugBuffer(buf : Bytes) : Void { var debug : String = "BUFFER >>"; var i : Int; for (i in 0 ... buf.length) { debug += buf.get(i); debug += " "; } trace(debug + "<<"); } public override function write(buf : Bytes, off : Int, len : Int) : Void { obuffer.writeBytes(buf, off, len); } public function addEventListener(type : String, listener : Function, useCapture : Bool = false, priority : Int = 0, useWeakReference : Bool = false) : Void { this.eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference); } public override function open() : Void { this.socket = new Socket(); this.socket.addEventListener(Event.CONNECT, socketConnected); this.socket.addEventListener(IOErrorEvent.IO_ERROR, socketError); this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketSecurityError); this.socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler); this.socket.connect(host, port); ResetConsumedMessageSize(); } public function socketConnected(event : Event) : Void { this.output = this.socket; this.input = this.socket; this.output.writeUTF( "CONNECT " + resource + " HTTP/1.1\n" + "Host : " + host + ":" + port + "\r\n" + "User-Agent : Thrift/Haxe\r\n" + "Transfer-Encoding : chunked\r\n" + "Content-Type : application/x-thrift\r\n" + "Accept : */*\r\n" + "\r\n"); this.eventDispatcher.dispatchEvent(event); } public function socketError(event : IOErrorEvent) : Void { trace("Error Connecting:" + event); this.close(); if (ioCallback == null) { return; } ioCallback(new TTransportException(TTransportException.UNKNOWN, "IOError : " + event.text)); this.eventDispatcher.dispatchEvent(event); } public function socketSecurityError(event : SecurityErrorEvent) : Void { trace("Security Error Connecting:" + event); this.close(); this.eventDispatcher.dispatchEvent(event); } public function socketDataHandler(event : ProgressEvent) : Void { trace("Got Data call:" +ioCallback); if (ioCallback != null) { ioCallback(null); }; this.eventDispatcher.dispatchEvent(event); } public override function flush(callback : Error->Void = null) : Void { trace("set callback:" + callback); this.ioCallback = callback; this.output.writeUTF(this.obuffer.length.toString(16)); this.output.writeBytes(CRLF); this.output.writeBytes(this.obuffer); this.output.writeBytes(CRLF); this.socket.flush(); this.obuffer = new Bytes(); ResetConsumedMessageSize(); } public override function isOpen() : Bool { return (this.socket != null) && this.socket.connected; } } #end thrift-0.23.0/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx0000664000175000017500000001276715165535636027364 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.transport.*; import haxe.Int64; import haxe.io.Eof; import haxe.io.Bytes; import haxe.io.BytesBuffer; import haxe.io.BytesOutput; import haxe.io.BytesInput; class TBufferedTransport extends TLayeredTransport { // constants public static inline var DEFAULT_BUFSIZE : Int = 0x1000; // 4096 Bytes public static inline var MIN_BUFSIZE : Int = 0x100; // 256 Bytes public static inline var MAX_BUFSIZE : Int = 0x100000; // 1 MB // Buffer for input/output private var readBuffer_ : BytesInput = null; private var writeBuffer_ : BytesOutput = null; private var bufSize : Int; // Constructor wraps around another transport public function new( transport : TTransport, bufSize : Int = DEFAULT_BUFSIZE) { super(transport); // ensure buffer size is in the range if ( bufSize < MIN_BUFSIZE) bufSize = MIN_BUFSIZE; else if( bufSize > MAX_BUFSIZE) bufSize = MAX_BUFSIZE; this.bufSize = bufSize; this.writeBuffer_ = new BytesOutput(); this.writeBuffer_.bigEndian = true; } public override function open() : Void { InnerTransport.open(); } public override function isOpen() : Bool { return InnerTransport.isOpen(); } public override function close() : Void { InnerTransport.close(); } public override function read(buf : BytesBuffer, off : Int, len : Int) : Int { try { var data = Bytes.alloc(len); while( true) { if ((readBuffer_ != null) && (readBuffer_.position < readBuffer_.length)) { var got = readBuffer_.readBytes(data, 0, len); if (got > 0) { buf.addBytes(data, 0, got); return got; } } // there is no point in buffering whenever the // remaining length exceeds the buffer size if ( len >= bufSize) { var got = InnerTransport.read( buf, off, len); if (got > 0) { buf.addBytes(data, 0, got); return got; } } // fill the buffer if ( readChunk() <= 0) break; } throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $len bytes!'); } catch (eof : Eof) { throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $len bytes!'); } } function readChunk() : Int { var size = bufSize; try { var buffer = new BytesBuffer(); size = InnerTransport.read( buffer, 0, size); readBuffer_ = new BytesInput( buffer.getBytes(), 0, size); readBuffer_.bigEndian = true; return size; } catch(eof : Eof) { throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $size bytes!'); } } private function writeChunk(forceWrite : Bool) : Void { if( writeBuffer_.length > 0) { if ( forceWrite || (writeBuffer_.length >= bufSize)) { var buf = writeBuffer_.getBytes(); writeBuffer_ = new BytesOutput(); writeBuffer_.bigEndian = true; InnerTransport.write(buf, 0, buf.length); } } } public override function write(buf : Bytes, off : Int, len : Int) : Void { var halfSize : Int = Std.int(bufSize / 2); // No point in buffering if len exceeds the buffer size. // However, if the buffer is less than half full we should still consider // squashing all into one write, except when the actual write len is very large. var huge_write : Bool = (len >= (2 * bufSize)); var exceeds_buf : Bool = huge_write || (len >= bufSize); var write_thru : Bool = exceeds_buf && (writeBuffer_.length >= halfSize); if ( write_thru) { writeChunk(true); // force send whatever we have in there InnerTransport.write(buf, off, len); // write thru } else { writeBuffer_.writeBytes(buf, off, len); writeChunk(false); } } public override function flush( callback : Dynamic->Void =null) : Void { writeChunk(true); InnerTransport.flush(callback); } public override function CheckReadBytesAvailable(numBytes : Int64) : Void { var buffered = readBuffer_.length - readBuffer_.position; if (buffered < numBytes) { numBytes -= buffered; InnerTransport.CheckReadBytesAvailable(numBytes); } } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/TProcessor.hx0000664000175000017500000000207415165535636023636 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * A processor is a generic object which operates upon an input stream and * writes to some output stream. */ interface TProcessor { function process(input:TProtocol, output:TProtocol) : Bool; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/0000775000175000017500000000000015165535636023030 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProcessor.hx0000664000175000017500000001541715165535636027721 0ustar00buildbuild00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import haxe.ds.StringMap; import org.apache.thrift.TApplicationException; import org.apache.thrift.TProcessor; import org.apache.thrift.transport.TTransport; /** * TMultiplexedProcessor is a TProcessor allowing a single TServer to provide multiple services. * To do so, you instantiate the processor and then register additional processors with it, * as shown in the following example: * * TMultiplexedProcessor processor = new TMultiplexedProcessor(); * * processor.registerProcessor( * "Calculator", * new Calculator.Processor(new CalculatorHandler())); * * processor.registerProcessor( * "WeatherReport", * new WeatherReport.Processor(new WeatherReportHandler())); * * TServerTransport t = new TServerSocket(9090); * TSimpleServer server = new TSimpleServer(processor, t); * * server.serve(); */ class TMultiplexedProcessor implements TProcessor { private var serviceProcessorMap : StringMap = new StringMap(); private var defaultProcessor : TProcessor = null; public function new() { } /** * 'Register' a service with this TMultiplexedProcessor. This allows us to broker * requests to individual services by using the service name to select them at request time. * * Args: * - serviceName Name of a service, has to be identical to the name * declared in the Thrift IDL, e.g. "WeatherReport". * - processor Implementation of a service, usually referred to as "handlers", * e.g. WeatherReportHandler implementing WeatherReport.Iface. */ public function RegisterProcessor(serviceName : String, processor : TProcessor, asDefault : Bool = false) : Void { serviceProcessorMap.set(serviceName, processor); if ( asDefault) { if( defaultProcessor != null) { throw new TApplicationException( TApplicationException.UNKNOWN, "Can't have multiple default processors"); } else { defaultProcessor = processor; } } } private function Fail( oprot : TProtocol, message : TMessage, extype : Int, etxt : String) : Void { var appex = new TApplicationException( extype, etxt); var newMessage = new TMessage(message.name, TMessageType.EXCEPTION, message.seqid); oprot.writeMessageBegin(newMessage); appex.write( oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); } /** * This implementation of process performs the following steps: * * - Read the beginning of the message. * - Extract the service name from the message. * - Using the service name to locate the appropriate processor. * - Dispatch to the processor, with a decorated instance of TProtocol * that allows readMessageBegin() to return the original TMessage. * * Throws an exception if * - the message type is not CALL or ONEWAY, * - the service name was not found in the message, or * - the service name has not been RegisterProcessor()ed. */ public function process( iprot : TProtocol, oprot : TProtocol) : Bool { /* Use the actual underlying protocol (e.g. TBinaryProtocol) to read the message header. This pulls the message "off the wire", which we'll deal with at the end of this method. */ var message : TMessage = iprot.readMessageBegin(); var methodName : String = ""; if ((message.type != TMessageType.CALL) && (message.type != TMessageType.ONEWAY)) { Fail(oprot, message, TApplicationException.INVALID_MESSAGE_TYPE, "Message type CALL or ONEWAY expected"); return false; } // Extract the service name var actualProcessor : TProcessor = null; var index = message.name.indexOf(TMultiplexedProtocol.SEPARATOR); if (index < 0) { // fallback to default processor methodName = message.name; actualProcessor = defaultProcessor; if( actualProcessor == null) { Fail(oprot, message, TApplicationException.INVALID_PROTOCOL, "Service name not found in message name: " + message.name + " and no default processor defined. " + "Did you forget to use a TMultiplexProtocol in your client?"); return false; } } else { // service name given var serviceName = message.name.substring(0, index); methodName = message.name.substring( serviceName.length + TMultiplexedProtocol.SEPARATOR.length); actualProcessor = serviceProcessorMap.get( serviceName); if( actualProcessor == null) { Fail(oprot, message, TApplicationException.INTERNAL_ERROR, "Service name not found: " + serviceName + ". " + "Did you forget to call RegisterProcessor()?"); return false; } } // Create a new TMessage, removing the service name // Dispatch processing to the stored processor var newMessage = new TMessage( methodName, message.type, message.seqid); var storedMsg = new StoredMessageProtocol( iprot, newMessage); return actualProcessor.process( storedMsg, oprot); } } /** * Our goal was to work with any protocol. In order to do that, we needed * to allow them to call readMessageBegin() and get a TMessage in exactly * the standard format, without the service name prepended to TMessage.name. */ class StoredMessageProtocol extends TProtocolDecorator { private var messageBegin : TMessage; public function new( protocol : TProtocol, messageBegin : TMessage) { super( protocol); this.messageBegin = messageBegin; } public override function readMessageBegin() : TMessage { return messageBegin; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx0000664000175000017500000001402115165535636027157 0ustar00buildbuild00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import haxe.io.Bytes; import haxe.Int64; import org.apache.thrift.transport.TTransport; /** * TProtocolDecorator forwards all requests to an enclosed TProtocol instance, * providing a way to author concise concrete decorator subclasses. While it has * no abstract methods, it is marked abstract as a reminder that by itself, * it does not modify the behaviour of the enclosed TProtocol. * * See p.175 of Design Patterns (by Gamma et al.) * See TMultiplexedProtocol */ class TProtocolDecorator implements TProtocol { private var wrapped : TProtocol; /** * Encloses the specified protocol. * @param protocol All operations will be forward to this protocol. Must be non-null. */ private function new( protocol : TProtocol) // not to be instantiated, must derive a class { wrapped = protocol; } public function getTransport() : TTransport { return wrapped.getTransport(); } public function writeMessageBegin( value : TMessage) : Void { wrapped.writeMessageBegin( value); } public function writeMessageEnd() : Void { wrapped.writeMessageEnd(); } public function writeStructBegin(value : TStruct) : Void { wrapped.writeStructBegin( value); } public function writeStructEnd() : Void { wrapped.writeStructEnd(); } public function writeFieldBegin(value : TField) : Void { wrapped.writeFieldBegin( value); } public function writeFieldEnd() : Void { wrapped.writeFieldEnd(); } public function writeFieldStop() : Void { wrapped.writeFieldStop(); } public function writeMapBegin( value : TMap) : Void { wrapped.writeMapBegin( value); } public function writeMapEnd() : Void { wrapped.writeMapEnd(); } public function writeListBegin( value : TList) : Void { wrapped.writeListBegin( value); } public function writeListEnd() : Void { wrapped.writeListEnd(); } public function writeSetBegin( value : TSet) : Void { wrapped.writeSetBegin( value); } public function writeSetEnd() : Void { wrapped.writeSetEnd(); } public function writeBool(value : Bool) : Void { wrapped.writeBool( value); } public function writeByte(value : Int) : Void { wrapped.writeByte( value); } public function writeI16(value : Int) : Void { wrapped.writeI16( value); } public function writeI32(value : Int) : Void { wrapped.writeI32( value); } public function writeI64(value : haxe.Int64) : Void { wrapped.writeI64( value); } public function writeDouble(value : Float) : Void { wrapped.writeDouble( value); } public function writeString(value : String) : Void { wrapped.writeString( value); } public function writeBinary(value : Bytes ) : Void { wrapped.writeBinary( value); } public function writeUuid(value : String ) : Void { wrapped.writeUuid( value); } public function readMessageBegin() : TMessage { return wrapped.readMessageBegin(); } public function readMessageEnd() : Void { wrapped.readMessageEnd(); } public function readStructBegin() : TStruct { return wrapped.readStructBegin(); } public function readStructEnd() : Void { wrapped.readStructEnd(); } public function readFieldBegin() : TField { return wrapped.readFieldBegin(); } public function readFieldEnd() : Void { wrapped.readFieldEnd(); } public function readMapBegin() : TMap { return wrapped.readMapBegin(); } public function readMapEnd() : Void { wrapped.readMapEnd(); } public function readListBegin() : TList { return wrapped.readListBegin(); } public function readListEnd() : Void { wrapped.readListEnd(); } public function readSetBegin() : TSet { return wrapped.readSetBegin(); } public function readSetEnd() : Void { wrapped.readSetEnd(); } public function readBool() : Bool { return wrapped.readBool(); } public function readByte() : Int { return wrapped.readByte(); } public function readI16() : Int { return wrapped.readI16(); } public function readI32() : Int { return wrapped.readI32(); } public function readI64() : haxe.Int64 { return wrapped.readI64(); } public function readDouble() : Float { return wrapped.readDouble(); } public function readString() : String { return wrapped.readString(); } public function readBinary() : Bytes { return wrapped.readBinary(); } public function readUuid() : String { return wrapped.readUuid(); } public function IncrementRecursionDepth() : Void { return wrapped.IncrementRecursionDepth(); } public function DecrementRecursionDepth() : Void { return wrapped.DecrementRecursionDepth(); } // Returns the minimum amount of bytes needed to store the smallest possible instance of TType. public function GetMinSerializedSize(type : TType) : Int { return wrapped.GetMinSerializedSize(type); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocolFactory.hx0000664000175000017500000000216415165535636027343 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.transport.TTransport; /** * JSON Protocol Factory */ class TJSONProtocolFactory implements TProtocolFactory { public function new() { } public function getProtocol( trans : TTransport) : TProtocol { return new TJSONProtocol( trans); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TMessage.hx0000664000175000017500000000250115165535636025077 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; class TMessage { public var name : String; public var type : Int; public var seqid : Int; public function new(n : String = "", t : Int = 0, s : Int = 0) { name = n; type = t; seqid = s; } public function toString() : String { return ""; } public function equals(other:TMessage) : Bool { return name == other.name && type == other.type && seqid == other.seqid; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx0000664000175000017500000000504015165535636026732 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.*; import org.apache.thrift.transport.TTransport; class TProtocolImplBase { private var Configuration : TConfiguration; public var Transport(default,null) : TTransport; public function new( transport : TTransport) { Transport = transport; Configuration = (transport.Configuration != null) ? transport.Configuration : new TConfiguration(); } public function getTransport() : TTransport { return Transport; } // limit and actual value public var recursionLimit(get,never) : Int; private var recursionDepth : Int = 0; public function get_recursionLimit() : Int { return Configuration.RecursionLimit; } public function IncrementRecursionDepth() : Void { if (recursionDepth < recursionLimit) ++recursionDepth; else throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded"); } public function DecrementRecursionDepth() : Void { --recursionDepth; } private function CheckReadBytesAvailableSet(set : TSet) : Void { Transport.CheckReadBytesAvailable(set.size * GetMinSerializedSize(set.elemType)); } private function CheckReadBytesAvailableList(list : TList) : Void { Transport.CheckReadBytesAvailable(list.size * GetMinSerializedSize(list.elemType)); } private function CheckReadBytesAvailableMap (map : TMap) : Void { var elmSize = GetMinSerializedSize(map.keyType) + GetMinSerializedSize(map.valueType); Transport.CheckReadBytesAvailable(map.size * elmSize); } // Returns the minimum amount of bytes needed to store the smallest possible instance of TType. public function GetMinSerializedSize(type : TType) : Int throw "abstract method called"; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TStruct.hx0000664000175000017500000000167715165535636025014 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; class TStruct { public var name : String; public function new(n : String = "") { name = n; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TField.hx0000664000175000017500000000245015165535636024541 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; class TField { public var name : String; public var type : Int; public var id : Int; public function new(n : String = "", t : Int = 0, i : Int = 0) { name = n; type = t; id = i; } public function toString() : String { return ''; } public function equals( otherField : TField) : Bool { return (type == otherField.type) && (id == otherField.id); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx0000664000175000017500000010016415165535636026012 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import haxe.io.Bytes; import haxe.io.BytesInput; import haxe.io.BytesOutput; import haxe.io.BytesBuffer; import haxe.io.Encoding; import haxe.ds.GenericStack; import haxe.crypto.Base64; import haxe.Int64; import uuid.Uuid; import org.apache.thrift.TException; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TMap; import org.apache.thrift.protocol.TSet; import org.apache.thrift.protocol.TList; import org.apache.thrift.transport.TTransport; import org.apache.thrift.helper.UuidHelper; /* JSON protocol implementation for thrift. * This is a full-featured protocol supporting Write and Read. * * Please see the C++ class header for a detailed description of the wire format. * * Adapted from the Java version. */ class TJSONProtocol extends TProtocolImplBase implements TProtocol { // Stack of nested contexts that we may be in private var contextStack : GenericStack = new GenericStack(); // Current context that we are in private var context : JSONBaseContext; // Reader that manages a 1-byte buffer private var reader : LookaheadReader; // TJSONProtocol Constructor public function new( transport : TTransport) { super(transport); this.context = new JSONBaseContext(this); this.reader = new LookaheadReader(this); } public function writeMessageBegin(message:TMessage) : Void { WriteJSONArrayStart(); WriteJSONInteger( JSONConstants.VERSION); WriteJSONString( BytesFromString(message.name)); WriteJSONInteger( message.type); WriteJSONInteger( message.seqid); } public function writeMessageEnd() : Void { WriteJSONArrayEnd(); } public function writeStructBegin(struct:TStruct) : Void { WriteJSONObjectStart(); } public function writeStructEnd() : Void { WriteJSONObjectEnd(); } public function writeFieldBegin(field:TField) : Void { WriteJSONInteger( field.id ); WriteJSONObjectStart(); WriteJSONString( BytesFromString( JSONConstants.GetTypeNameForTypeID( field.type))); } public function writeFieldEnd() : Void { WriteJSONObjectEnd(); } public function writeFieldStop() : Void { } public function writeMapBegin(map:TMap) : Void { WriteJSONArrayStart(); WriteJSONString( BytesFromString( JSONConstants.GetTypeNameForTypeID( map.keyType))); WriteJSONString( BytesFromString( JSONConstants.GetTypeNameForTypeID( map.valueType))); WriteJSONInteger( map.size); WriteJSONObjectStart(); } public function writeMapEnd() : Void { WriteJSONObjectEnd(); WriteJSONArrayEnd(); } public function writeListBegin(list:TList) : Void { WriteJSONArrayStart(); WriteJSONString( BytesFromString( JSONConstants.GetTypeNameForTypeID( list.elemType ))); WriteJSONInteger( list.size); } public function writeListEnd() : Void { WriteJSONArrayEnd(); } public function writeSetBegin(set:TSet) : Void { WriteJSONArrayStart(); WriteJSONString( BytesFromString( JSONConstants.GetTypeNameForTypeID( set.elemType))); WriteJSONInteger( set.size); } public function writeSetEnd() : Void { WriteJSONArrayEnd(); } public function writeBool(b : Bool) : Void { if( b) WriteJSONInteger( 1); else WriteJSONInteger( 0); } public function writeByte(b : Int) : Void { WriteJSONInteger( b); } public function writeI16(i16 : Int) : Void { WriteJSONInteger( i16); } public function writeI32(i32 : Int) : Void { WriteJSONInteger( i32); } public function writeI64(i64 : haxe.Int64) : Void { WriteJSONInt64( i64); } public function writeDouble(dub:Float) : Void { WriteJSONDouble(dub); } public function writeString(str : String) : Void { WriteJSONString( BytesFromString(str)); } public function writeBinary(bin:Bytes) : Void { WriteJSONBase64(bin); } public function writeUuid(uuid : String) : Void { writeString( UuidHelper.CanonicalUuid(uuid)); } public function readMessageBegin():TMessage { var message : TMessage = new TMessage(); ReadJSONArrayStart(); if (ReadJSONInteger() != JSONConstants.VERSION) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Message contained bad version."); } message.name = ReadJSONString(false); message.type = ReadJSONInteger(); message.seqid = ReadJSONInteger(); return message; } public function readMessageEnd() : Void { ReadJSONArrayEnd(); } public function readStructBegin():TStruct { ReadJSONObjectStart(); return new TStruct(); } public function readStructEnd() : Void { ReadJSONObjectEnd(); } public function readFieldBegin() : TField { var field : TField = new TField(); var ch = reader.Peek(); if (StringFromBytes(ch) == JSONConstants.RBRACE) { field.type = TType.STOP; } else { field.id = ReadJSONInteger(); ReadJSONObjectStart(); field.type = JSONConstants.GetTypeIDForTypeName( ReadJSONString(false)); } return field; } public function readFieldEnd() : Void { ReadJSONObjectEnd(); } public function readMapBegin() : TMap { ReadJSONArrayStart(); var KeyType = JSONConstants.GetTypeIDForTypeName( ReadJSONString(false)); var ValueType = JSONConstants.GetTypeIDForTypeName( ReadJSONString(false)); var Count : Int = ReadJSONInteger(); ReadJSONObjectStart(); var map = new TMap( KeyType, ValueType, Count); CheckReadBytesAvailableMap(map); return map; } public function readMapEnd() : Void { ReadJSONObjectEnd(); ReadJSONArrayEnd(); } public function readListBegin():TList { ReadJSONArrayStart(); var ElementType = JSONConstants.GetTypeIDForTypeName( ReadJSONString(false)); var Count : Int = ReadJSONInteger(); var list = new TList( ElementType, Count); CheckReadBytesAvailableList(list); return list; } public function readListEnd() : Void { ReadJSONArrayEnd(); } public function readSetBegin() : TSet { ReadJSONArrayStart(); var ElementType = JSONConstants.GetTypeIDForTypeName( ReadJSONString(false)); var Count : Int = ReadJSONInteger(); var set = new TSet( ElementType, Count); CheckReadBytesAvailableSet(set); return set; } public function readSetEnd() : Void { ReadJSONArrayEnd(); } public function readBool() : Bool { return (ReadJSONInteger() != 0); } public function readByte() : Int { return ReadJSONInteger(); } public function readI16() : Int { return ReadJSONInteger(); } public function readI32() : Int { return ReadJSONInteger(); } public function readI64() : haxe.Int64 { return ReadJSONInt64(); } public function readDouble():Float { return ReadJSONDouble(); } public function readString() : String { return ReadJSONString(false); } public function readBinary() : Bytes { return ReadJSONBase64(); } public function readUuid() : String { return UuidHelper.CanonicalUuid( readString()); } // Push a new JSON context onto the stack. private function PushContext(c : JSONBaseContext) : Void { contextStack.add(context); context = c; } // Pop the last JSON context off the stack private function PopContext() : Void { context = contextStack.pop(); } // Write the bytes in array buf as a JSON characters, escaping as needed private function WriteJSONString( b : Bytes) : Void { context.Write(); var tmp = BytesFromString( JSONConstants.QUOTE); Transport.write( tmp, 0, tmp.length); for (i in 0 ... b.length) { var value = b.get(i); if ((value & 0x00FF) >= 0x30) { if (String.fromCharCode(value) == JSONConstants.BACKSLASH.charAt(0)) { tmp = BytesFromString( JSONConstants.BACKSLASH + JSONConstants.BACKSLASH); Transport.write( tmp, 0, tmp.length); } else { Transport.write( b, i, 1); } } else { var num = JSONConstants.JSON_CHAR_TABLE[value]; if (num == 1) { Transport.write( b, i, 1); } else if (num > 1) { var buf = new BytesBuffer(); buf.addString( JSONConstants.BACKSLASH); buf.addByte( num); tmp = buf.getBytes(); Transport.write( tmp, 0, tmp.length); } else { var buf = new BytesBuffer(); buf.addString( JSONConstants.ESCSEQ); buf.addString( HexChar( (value & 0xFF000000) >> 12)); buf.addString( HexChar( (value & 0x00FF0000) >> 8)); buf.addString( HexChar( (value & 0x0000FF00) >> 4)); buf.addString( HexChar( value & 0x000000FF)); tmp = buf.getBytes(); Transport.write( tmp, 0, tmp.length); } } } tmp = BytesFromString( JSONConstants.QUOTE); Transport.write( tmp, 0, tmp.length); } // Write out number as a JSON value. If the context dictates so, // it will be wrapped in quotes to output as a JSON string. private function WriteJSONInteger( num : Int) : Void { context.Write(); var str : String = ""; var escapeNum : Bool = context.EscapeNumbers(); if (escapeNum) { str += JSONConstants.QUOTE; } str += Std.string(num); if (escapeNum) { str += JSONConstants.QUOTE; } var tmp = BytesFromString( str); Transport.write( tmp, 0, tmp.length); } // Write out number as a JSON value. If the context dictates so, // it will be wrapped in quotes to output as a JSON string. private function WriteJSONInt64( num : Int64) : Void { context.Write(); var str : String = ""; var escapeNum : Bool = context.EscapeNumbers(); if (escapeNum) { str += JSONConstants.QUOTE; } str += Std.string(num); if (escapeNum) { str += JSONConstants.QUOTE; } var tmp = BytesFromString( str); Transport.write( tmp, 0, tmp.length); } // Write out a double as a JSON value. If it is NaN or infinity or if the // context dictates escaping, Write out as JSON string. private function WriteJSONDouble(num : Float) : Void { context.Write(); var special : Bool = false; var rendered : String = ""; if( Math.isNaN(num)) { special = true; rendered = JSONConstants.FLOAT_IS_NAN; } else if (! Math.isFinite(num)) { special = true; if( num > 0) { rendered = JSONConstants.FLOAT_IS_POS_INF; } else { rendered = JSONConstants.FLOAT_IS_NEG_INF; } } else { rendered = Std.string(num); // plain and simple float number } // compose output var escapeNum : Bool = special || context.EscapeNumbers(); var str : String = ""; if (escapeNum) { str += JSONConstants.QUOTE; } str += rendered; if (escapeNum) { str += JSONConstants.QUOTE; } var tmp = BytesFromString( str); Transport.write( tmp, 0, tmp.length); } // Write out contents of byte array b as a JSON string with base-64 encoded data private function WriteJSONBase64( b : Bytes) : Void { context.Write(); var buf = new BytesBuffer(); buf.addString( JSONConstants.QUOTE); buf.addString( Base64.encode(b)); buf.addString( JSONConstants.QUOTE); var tmp = buf.getBytes(); Transport.write( tmp, 0, tmp.length); } private function WriteJSONObjectStart() : Void { context.Write(); var tmp = BytesFromString( JSONConstants.LBRACE); Transport.write( tmp, 0, tmp.length); PushContext( new JSONPairContext(this)); } private function WriteJSONObjectEnd() : Void { PopContext(); var tmp = BytesFromString( JSONConstants.RBRACE); Transport.write( tmp, 0, tmp.length); } private function WriteJSONArrayStart() : Void { context.Write(); var tmp = BytesFromString( JSONConstants.LBRACKET); Transport.write( tmp, 0, tmp.length); PushContext( new JSONListContext(this)); } private function WriteJSONArrayEnd() : Void { PopContext(); var tmp = BytesFromString( JSONConstants.RBRACKET); Transport.write( tmp, 0, tmp.length); } /** * Reading methods. */ // Read a byte that must match char, otherwise an exception is thrown. public function ReadJSONSyntaxChar( char : String) : Void { var b = BytesFromString( char); var ch = reader.Read(); if (ch.get(0) != b.get(0)) { throw new TProtocolException(TProtocolException.INVALID_DATA, 'Unexpected character: $ch'); } } // Read in a JSON string, unescaping as appropriate. // Skip Reading from the context if skipContext is true. private function ReadJSONString(skipContext : Bool) : String { if (!skipContext) { context.Read(); } var buffer : BytesBuffer = new BytesBuffer(); ReadJSONSyntaxChar( JSONConstants.QUOTE); while (true) { var ch = reader.Read(); // end of string? if (StringFromBytes(ch) == JSONConstants.QUOTE) { break; } // escaped? if (StringFromBytes(ch) != JSONConstants.ESCSEQ.charAt(0)) { buffer.addByte( ch.get(0)); continue; } // distinguish between \uXXXX (hex unicode) and \X (control chars) ch = reader.Read(); if (StringFromBytes(ch) != JSONConstants.ESCSEQ.charAt(1)) { var value = JSONConstants.ESCAPE_CHARS_TO_VALUES[ch.get(0)]; if( value == null) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Expected control char"); } buffer.addByte( value); continue; } // it's \uXXXX var hexbuf = new BytesBuffer(); var hexlen = Transport.readAll( hexbuf, 0, 4); if( hexlen != 4) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Not enough data for \\uNNNN sequence"); } var hexdigits = hexbuf.getBytes(); var charcode = 0; charcode = (charcode << 4) + HexVal( String.fromCharCode(hexdigits.get(0))); charcode = (charcode << 4) + HexVal( String.fromCharCode(hexdigits.get(1))); charcode = (charcode << 4) + HexVal( String.fromCharCode(hexdigits.get(2))); charcode = (charcode << 4) + HexVal( String.fromCharCode(hexdigits.get(3))); buffer.addString( String.fromCharCode(charcode)); } return StringFromBytes( buffer.getBytes()); } // Return true if the given byte could be a valid part of a JSON number. private function IsJSONNumeric(b : Int) : Bool { switch (b) { case "+".code: return true; case "-".code: return true; case ".".code: return true; case "0".code: return true; case "1".code: return true; case "2".code: return true; case "3".code: return true; case "4".code: return true; case "5".code: return true; case "6".code: return true; case "7".code: return true; case "8".code: return true; case "9".code: return true; case "E".code: return true; case "e".code: return true; } return false; } // Read in a sequence of characters that are all valid in JSON numbers. Does // not do a complete regex check to validate that this is actually a number. private function ReadJSONNumericChars() : String { var buffer : BytesBuffer = new BytesBuffer(); while (true) { var ch = reader.Peek(); if( ! IsJSONNumeric( ch.get(0))) { break; } buffer.addByte( reader.Read().get(0)); } return StringFromBytes( buffer.getBytes()); } // Read in a JSON number. If the context dictates, Read in enclosing quotes. private function ReadJSONInteger() : Int { context.Read(); if (context.EscapeNumbers()) { ReadJSONSyntaxChar( JSONConstants.QUOTE); } var str : String = ReadJSONNumericChars(); if (context.EscapeNumbers()) { ReadJSONSyntaxChar( JSONConstants.QUOTE); } var value = Std.parseInt(str); if( value == null) { throw new TProtocolException(TProtocolException.INVALID_DATA, 'Bad numeric data: $str'); } return value; } // Read in a JSON number. If the context dictates, Read in enclosing quotes. private function ReadJSONInt64() : haxe.Int64 { context.Read(); if (context.EscapeNumbers()) { ReadJSONSyntaxChar( JSONConstants.QUOTE); } var str : String = ReadJSONNumericChars(); if( str.length == 0) { throw new TProtocolException(TProtocolException.INVALID_DATA, 'Bad numeric data: $str'); } if (context.EscapeNumbers()) { ReadJSONSyntaxChar( JSONConstants.QUOTE); } // process sign var bMinus = false; var startAt = 0; if( (str.charAt(0) == "+") || (str.charAt(0) == "-")) { bMinus = (str.charAt(0) == "-"); startAt++; } // process digits var value : Int64 = Int64.make(0,0); var bGotDigits = false; for( i in startAt ... str.length) { var ch = str.charAt(i); var digit = JSONConstants.DECIMAL_DIGITS[ch]; if( digit == null) { throw new TProtocolException(TProtocolException.INVALID_DATA, 'Bad numeric data: $str'); } bGotDigits = true; // these are decimal digits value = Int64.mul( value, Int64.make(0,10)); value = Int64.add( value, Int64.make(0,digit)); } // process pending minus sign, if applicable // this should also handle the edge case MIN_INT64 correctly if( bMinus && (Int64.compare(value,Int64.make(0,0)) > 0)) { value = Int64.neg( value); bMinus = false; } if( ! bGotDigits) { throw new TProtocolException(TProtocolException.INVALID_DATA, 'Bad numeric data: $str'); } return value; } // Read in a JSON double value. Throw if the value is not wrapped in quotes // when expected or if wrapped in quotes when not expected. private function ReadJSONDouble() : Float { context.Read(); var str : String = ""; if (StringFromBytes(reader.Peek()) == JSONConstants.QUOTE) { str = ReadJSONString(true); // special cases if( str == JSONConstants.FLOAT_IS_NAN) { return Math.NaN; } if( str == JSONConstants.FLOAT_IS_POS_INF) { return Math.POSITIVE_INFINITY; } if( str == JSONConstants.FLOAT_IS_NEG_INF) { return Math.NEGATIVE_INFINITY; } if( ! context.EscapeNumbers()) { // throw - we should not be in a string in this case throw new TProtocolException(TProtocolException.INVALID_DATA, "Numeric data unexpectedly quoted"); } } else { if( context.EscapeNumbers()) { // This will throw - we should have had a quote if EscapeNumbers() == true ReadJSONSyntaxChar( JSONConstants.QUOTE); } str = ReadJSONNumericChars(); } // parse and check - we should have at least one valid digit var dub = Std.parseFloat( str); if( (str.length == 0) || Math.isNaN(dub)) { throw new TProtocolException(TProtocolException.INVALID_DATA, 'Bad numeric data: $str'); } return dub; } // Read in a JSON string containing base-64 encoded data and decode it. private function ReadJSONBase64() : Bytes { var str = ReadJSONString(false); return Base64.decode( str); } private function ReadJSONObjectStart() : Void { context.Read(); ReadJSONSyntaxChar( JSONConstants.LBRACE); PushContext(new JSONPairContext(this)); } private function ReadJSONObjectEnd() : Void { ReadJSONSyntaxChar( JSONConstants.RBRACE); PopContext(); } private function ReadJSONArrayStart() : Void { context.Read(); ReadJSONSyntaxChar( JSONConstants.LBRACKET); PushContext(new JSONListContext(this)); } private function ReadJSONArrayEnd() : Void { ReadJSONSyntaxChar( JSONConstants.RBRACKET); PopContext(); } public static function BytesFromString( str : String) : Bytes { var buf = new BytesBuffer(); buf.addString( str, Encoding.UTF8); return buf.getBytes(); } public static function StringFromBytes( buf : Bytes) : String { var inp = new BytesInput( buf); if( buf.length == 0) return ""; // readString() would return null in that case, which is wrong return inp.readString( buf.length, Encoding.UTF8); } // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its corresponding hex value private static function HexVal(char : String) : Int { var value = JSONConstants.HEX_DIGITS[char]; if( value == null) { throw new TProtocolException(TProtocolException.INVALID_DATA, 'Expected hex character: $char'); } return value; } // Convert a byte containing a hex nibble to its corresponding hex character private static function HexChar(nibble : Int) : String { return "0123456789abcdef".charAt(nibble & 0x0F); } // Return the minimum number of bytes a type will consume on the wire public override function GetMinSerializedSize(type : TType) : Int { switch (type) { case TType.STOP: return 1; // T_STOP needs to count itself case TType.VOID_: return 1; // T_VOID needs to count itself case TType.BOOL: return 1; // written as int case TType.BYTE: return 1; case TType.DOUBLE: return 1; case TType.I16: return 1; case TType.I32: return 1; case TType.I64: return 1; case TType.STRING: return 2; // empty string case TType.STRUCT: return 2; // empty struct case TType.MAP: return 2; // empty map case TType.SET: return 2; // empty set case TType.LIST: return 2; // empty list case TType.UUID: return 36; // "E236974D-F0B0-4E05-8F29-0B455D41B1A1" default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code"); } } } @:allow(TJSONProtocol) class JSONConstants { public static var COMMA = ","; public static var COLON = ":"; public static var LBRACE = "{"; public static var RBRACE = "}"; public static var LBRACKET = "["; public static var RBRACKET = "]"; public static var QUOTE = "\""; public static var BACKSLASH = "\\"; public static var ESCSEQ = "\\u"; public static var FLOAT_IS_NAN = "NaN"; public static var FLOAT_IS_POS_INF = "Infinity"; public static var FLOAT_IS_NEG_INF = "-Infinity"; public static var VERSION = 1; public static var JSON_CHAR_TABLE = [ 0, 0, 0, 0, 0, 0, 0, 0, "b".code, "t".code, "n".code, 0, "f".code, "r".code, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, "\"".code, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ]; public static var ESCAPE_CHARS = ['"','\\','/','b','f','n','r','t']; public static var ESCAPE_CHARS_TO_VALUES = [ "\"".code => 0x22, "\\".code => 0x5C, "/".code => 0x2F, "b".code => 0x08, "f".code => 0x0C, "n".code => 0x0A, "r".code => 0x0D, "t".code => 0x09 ]; public static var DECIMAL_DIGITS = [ "0" => 0, "1" => 1, "2" => 2, "3" => 3, "4" => 4, "5" => 5, "6" => 6, "7" => 7, "8" => 8, "9" => 9 ]; public static var HEX_DIGITS = [ "0" => 0, "1" => 1, "2" => 2, "3" => 3, "4" => 4, "5" => 5, "6" => 6, "7" => 7, "8" => 8, "9" => 9, "A" => 10, "a" => 10, "B" => 11, "b" => 11, "C" => 12, "c" => 12, "D" => 13, "d" => 13, "E" => 14, "e" => 14, "F" => 15, "f" => 15 ]; public static var DEF_STRING_SIZE = 16; public static var NAME_BOOL = 'tf'; public static var NAME_BYTE = 'i8'; public static var NAME_I16 = 'i16'; public static var NAME_I32 = 'i32'; public static var NAME_I64 = 'i64'; public static var NAME_DOUBLE = 'dbl'; public static var NAME_STRUCT = 'rec'; public static var NAME_STRING = 'str'; public static var NAME_MAP = 'map'; public static var NAME_LIST = 'lst'; public static var NAME_SET = 'set'; public static var NAME_UUID = 'uid'; public static function GetTypeNameForTypeID(typeID : Int) : String { switch (typeID) { case TType.BOOL: return NAME_BOOL; case TType.BYTE: return NAME_BYTE; case TType.I16: return NAME_I16; case TType.I32: return NAME_I32; case TType.I64: return NAME_I64; case TType.DOUBLE: return NAME_DOUBLE; case TType.STRING: return NAME_STRING; case TType.STRUCT: return NAME_STRUCT; case TType.MAP: return NAME_MAP; case TType.SET: return NAME_SET; case TType.LIST: return NAME_LIST; case TType.UUID: return NAME_UUID; } throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } private static var NAMES_TO_TYPES = [ NAME_BOOL => TType.BOOL, NAME_BYTE => TType.BYTE, NAME_I16 => TType.I16, NAME_I32 => TType.I32, NAME_I64 => TType.I64, NAME_DOUBLE => TType.DOUBLE, NAME_STRING => TType.STRING, NAME_STRUCT => TType.STRUCT, NAME_MAP => TType.MAP, NAME_SET => TType.SET, NAME_LIST => TType.LIST, NAME_UUID => TType.UUID ]; public static function GetTypeIDForTypeName(name : String) : Int { var type = NAMES_TO_TYPES[name]; if( null != type) { return type; } throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } } // Base class for tracking JSON contexts that may require inserting/Reading // additional JSON syntax characters. This base context does nothing. @:allow(TJSONProtocol) class JSONBaseContext { private var proto : TJSONProtocol; public function new(proto : TJSONProtocol ) { this.proto = proto; } public function Write() : Void { } public function Read() : Void { } public function EscapeNumbers() : Bool { return false; } } // Context for JSON lists. // Will insert/Read commas before each item except for the first one @:allow(TJSONProtocol) class JSONListContext extends JSONBaseContext { public function new( proto : TJSONProtocol) { super(proto); } private var first : Bool = true; public override function Write() : Void { if (first) { first = false; } else { var buf = new BytesBuffer(); buf.addString( JSONConstants.COMMA); var tmp = buf.getBytes(); proto.Transport.write( tmp, 0, tmp.length); } } public override function Read() : Void { if (first) { first = false; } else { proto.ReadJSONSyntaxChar( JSONConstants.COMMA); } } } // Context for JSON records. // Will insert/Read colons before the value portion of each record // pair, and commas before each key except the first. In addition, // will indicate that numbers in the key position need to be escaped // in quotes (since JSON keys must be strings). @:allow(TJSONProtocol) class JSONPairContext extends JSONBaseContext { public function new( proto : TJSONProtocol ) { super( proto); } private var first : Bool = true; private var colon : Bool = true; public override function Write() : Void { if (first) { first = false; colon = true; } else { var buf = new BytesBuffer(); buf.addString( colon ? JSONConstants.COLON : JSONConstants.COMMA); var tmp = buf.getBytes(); proto.Transport.write( tmp, 0, tmp.length); colon = !colon; } } public override function Read() : Void { if (first) { first = false; colon = true; } else { proto.ReadJSONSyntaxChar( colon ? JSONConstants.COLON : JSONConstants.COMMA); colon = !colon; } } public override function EscapeNumbers() : Bool { return colon; } } // Holds up to one byte from the transport @:allow(TJSONProtocol) class LookaheadReader { private var proto : TJSONProtocol; private var data : Bytes; public function new( proto : TJSONProtocol ) { this.proto = proto; data = null; } // Return and consume the next byte to be Read, either taking it from the // data buffer if present or getting it from the transport otherwise. public function Read() : Bytes { var retval = Peek(); data = null; return retval; } // Return the next byte to be Read without consuming, filling the data // buffer if it has not been filled alReady. public function Peek() : Bytes { if (data == null) { var buf = new BytesBuffer(); proto.Transport.readAll(buf, 0, 1); data = buf.getBytes(); } return data; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TList.hx0000664000175000017500000000177415165535636024441 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; class TList { public var elemType : Int; public var size : Int; public function new(t : Int = 0, s : Int = 0) { elemType = t; size = s; } }thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TProtocolException.hx0000664000175000017500000000305015165535636027173 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; class TProtocolException extends TException { // WARNING: These are subject to be extended in the future, so we can't use enums // with Haxe 3.1.3 because of https://github.com/HaxeFoundation/haxe/issues/3649 public static inline var UNKNOWN : Int = 0; public static inline var INVALID_DATA : Int = 1; public static inline var NEGATIVE_SIZE : Int = 2; public static inline var SIZE_LIMIT : Int = 3; public static inline var BAD_VERSION : Int = 4; public static inline var NOT_IMPLEMENTED : Int = 5; public static inline var DEPTH_LIMIT : Int = 6; public function new(error : Int = UNKNOWN, message : String = "") { super(message, error); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TCompactTypes.hx0000664000175000017500000000316715165535636026137 0ustar00buildbuild00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * All of the on-wire type codes. */ enum abstract TCompactTypes(Int) from Int to Int { public static inline var STOP = 0x00; public static inline var BOOLEAN_TRUE = 0x01; public static inline var BOOLEAN_FALSE = 0x02; public static inline var BYTE = 0x03; public static inline var I16 = 0x04; public static inline var I32 = 0x05; public static inline var I64 = 0x06; public static inline var DOUBLE = 0x07; public static inline var BINARY = 0x08; public static inline var LIST = 0x09; public static inline var SET = 0x0A; public static inline var MAP = 0x0B; public static inline var STRUCT = 0x0C; public static inline var UUID = 0x0D; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx0000664000175000017500000000564215165535636025325 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import haxe.io.Bytes; import org.apache.thrift.transport.TTransport; /** * Protocol interface definition */ interface TProtocol { function getTransport() : TTransport; /** * Writing methods. */ function writeMessageBegin(message:TMessage) : Void; function writeMessageEnd() : Void; function writeStructBegin(struct:TStruct) : Void; function writeStructEnd() : Void; function writeFieldBegin(field:TField) : Void; function writeFieldEnd() : Void; function writeFieldStop() : Void; function writeMapBegin(map:TMap) : Void; function writeMapEnd() : Void; function writeListBegin(list:TList) : Void; function writeListEnd() : Void; function writeSetBegin(set:TSet) : Void; function writeSetEnd() : Void; function writeBool(b : Bool) : Void; function writeByte(b : Int) : Void; function writeI16(i16 : Int) : Void; function writeI32(i32 : Int) : Void; function writeI64(i64 : haxe.Int64) : Void; function writeDouble(dub : Float) : Void; function writeString(str : String) : Void; function writeBinary(bin : Bytes) : Void; function writeUuid(uuid : String) : Void; /** * Reading methods. */ function readMessageBegin():TMessage; function readMessageEnd() : Void; function readStructBegin():TStruct; function readStructEnd() : Void; function readFieldBegin():TField; function readFieldEnd() : Void; function readMapBegin():TMap; function readMapEnd() : Void; function readListBegin():TList; function readListEnd() : Void; function readSetBegin():TSet; function readSetEnd() : Void; function readBool() : Bool; function readByte() : Int; function readI16() : Int; function readI32() : Int; function readI64() : haxe.Int64; function readDouble() : Float; function readString() : String; function readBinary() : Bytes; function readUuid() : String; // recursion tracking function IncrementRecursionDepth() : Void; function DecrementRecursionDepth() : Void; // message size function GetMinSerializedSize(type : TType) : Int; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx0000664000175000017500000005673215165535636026642 0ustar00buildbuild00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import haxe.io.Bytes; import haxe.io.BytesInput; import haxe.io.BytesOutput; import haxe.io.BytesBuffer; import haxe.io.Encoding; import haxe.ds.GenericStack; import haxe.Int32; import haxe.Int64; import uuid.Uuid; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.helper.ZigZag; import org.apache.thrift.helper.BitConverter; import org.apache.thrift.helper.UuidHelper; /** * Compact protocol implementation for thrift. */ class TCompactProtocol extends TProtocolImplBase implements TProtocol { private static var ANONYMOUS_STRUCT : TStruct = new TStruct(""); private static var TSTOP : TField = new TField("", TType.STOP, 0); private static inline var PROTOCOL_ID : Int = 0x82; private static inline var VERSION : Int = 1; private static inline var VERSION_MASK : Int = 0x1f; // 0001 1111 private static inline var TYPE_MASK : Int = 0xE0; // 1110 0000 private static inline var TYPE_BITS : Int = 0x07; // 0000 0111 private static inline var TYPE_SHIFT_AMOUNT : Int = 5; private static var ttypeToCompactType = [ TType.STOP => TCompactTypes.STOP, TType.BOOL => TCompactTypes.BOOLEAN_TRUE, TType.BYTE => TCompactTypes.BYTE, TType.DOUBLE => TCompactTypes.DOUBLE, TType.I16 => TCompactTypes.I16, TType.I32 => TCompactTypes.I32, TType.I64 => TCompactTypes.I64, TType.STRING => TCompactTypes.BINARY, TType.STRUCT => TCompactTypes.STRUCT, TType.MAP => TCompactTypes.MAP, TType.SET => TCompactTypes.SET, TType.LIST => TCompactTypes.LIST, TType.UUID => TCompactTypes.UUID ]; private static var tcompactTypeToType = [ TCompactTypes.STOP => TType.STOP, TCompactTypes.BOOLEAN_TRUE => TType.BOOL, TCompactTypes.BOOLEAN_FALSE => TType.BOOL, TCompactTypes.BYTE => TType.BYTE, TCompactTypes.I16 => TType.I16, TCompactTypes.I32 => TType.I32, TCompactTypes.I64 => TType.I64, TCompactTypes.DOUBLE => TType.DOUBLE, TCompactTypes.BINARY => TType.STRING, TCompactTypes.LIST => TType.LIST, TCompactTypes.SET => TType.SET, TCompactTypes.MAP => TType.MAP, TCompactTypes.STRUCT => TType.STRUCT, TCompactTypes.UUID => TType.UUID ]; /** * Used to keep track of the last field for the current and previous structs, * so we can do the delta stuff. */ private var lastField_ : GenericStack = new GenericStack(); private var lastFieldId_ : Int = 0; /** * If we encounter a boolean field begin, save the TField here so it can * have the value incorporated. */ private var booleanField_ : Null; /** * If we Read a field header, and it's a boolean field, save the boolean * value here so that ReadBool can use it. */ private var boolValue_ : Null; // TCompactProtocol Constructor public function new( transport : TTransport) { super(transport); } public function Reset() : Void{ while ( ! lastField_.isEmpty()) { lastField_.pop(); } lastFieldId_ = 0; } /** * Writes a byte without any possibility of all that field header nonsense. * Used internally by other writing methods that know they need to Write a byte. */ private function WriteByteDirect( b : Int) : Void { var buf = Bytes.alloc(1); buf.set( 0, b); Transport.write( buf, 0, 1); } /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. */ private function WriteVarint32( n : UInt) : Void { var i32buf = new BytesBuffer(); while (true) { if ((n & ~0x7F) == 0) { i32buf.addByte( n & 0xFF); break; } else { i32buf.addByte( (n & 0x7F) | 0x80); n >>= 7; } } var tmp = i32buf.getBytes(); Transport.write( tmp, 0, tmp.length); } /** * Write a message header to the wire. Compact Protocol messages contain the * protocol version so we can migrate forwards in the future if need be. */ public function writeMessageBegin( message : TMessage) : Void { Reset(); var versionAndType : Int = (VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK); WriteByteDirect( PROTOCOL_ID); WriteByteDirect( versionAndType); WriteVarint32( cast( message.seqid, UInt)); writeString( message.name); } /** * Write a struct begin. This doesn't actually put anything on the wire. We * use it as an opportunity to put special placeholder markers on the field * stack so we can get the field id deltas correct. */ public function writeStructBegin(struct:TStruct) : Void { lastField_.add( lastFieldId_); lastFieldId_ = 0; } /** * Write a struct end. This doesn't actually put anything on the wire. We use * this as an opportunity to pop the last field from the current struct off * of the field stack. */ public function writeStructEnd() : Void { lastFieldId_ = lastField_.pop(); } /** * Write a field header containing the field id and field type. If the * difference between the current field id and the last one is small (< 15), * then the field id will be encoded in the 4 MSB as a delta. Otherwise, the * field id will follow the type header as a zigzag varint. */ public function writeFieldBegin(field:TField) : Void { if (field.type == TType.BOOL) booleanField_ = field; // we want to possibly include the value, so we'll wait. else WriteFieldBeginInternal(field, 0xFF); } /** * The workhorse of WriteFieldBegin. It has the option of doing a * 'type override' of the type header. This is used specifically in the * boolean field case. */ private function WriteFieldBeginInternal( field : TField, typeOverride : Int) : Void { // if there's a type override, use that. var typeToWrite : Int; if ( typeOverride == 0xFF) typeToWrite = getCompactType( field.type); else typeToWrite = typeOverride; // check if we can use delta encoding for the field id if (field.id > lastFieldId_ && field.id - lastFieldId_ <= 15) { // Write them together WriteByteDirect((field.id - lastFieldId_) << 4 | typeToWrite); } else { // Write them separate WriteByteDirect(typeToWrite); writeI16(field.id); } lastFieldId_ = field.id; } /** * Write the STOP symbol so we know there are no more fields in this struct. */ public function writeFieldStop() : Void { WriteByteDirect( cast(TCompactTypes.STOP, Int)); } /** * Write a map header. If the map is empty, omit the key and value type * headers, as we don't need any additional information to skip it. */ public function writeMapBegin(map:TMap) : Void { if (map.size == 0) { WriteByteDirect(0); } else { var kvtype = (getCompactType(map.keyType) << 4) | getCompactType(map.valueType); WriteVarint32( cast( map.size, UInt)); WriteByteDirect( kvtype); } } /** * Write a list header. */ public function writeListBegin( list : TList) : Void { WriteCollectionBegin( list.elemType, list.size); } /** * Write a set header. */ public function writeSetBegin( set : TSet) : Void { WriteCollectionBegin( set.elemType, set.size); } /** * Write a boolean value. Potentially, this could be a boolean field, in * which case the field header info isn't written yet. If so, decide what the * right type header is for the value and then Write the field header. * Otherwise, Write a single byte. */ public function writeBool(b : Bool) : Void { var bct : Int = b ? TCompactTypes.BOOLEAN_TRUE : TCompactTypes.BOOLEAN_FALSE; if (booleanField_ != null) { // we haven't written the field header yet WriteFieldBeginInternal( booleanField_, bct); booleanField_ = null; } else { // we're not part of a field, so just Write the value. WriteByteDirect( bct); } } /** * Write a byte. Nothing to see here! */ public function writeByte( b : Int) : Void { WriteByteDirect( b); } /** * Write an I16 as a zigzag varint. */ public function writeI16( i16 : Int) : Void { WriteVarint32( ZigZag.FromInt( i16)); } /** * Write an i32 as a zigzag varint. */ public function writeI32( i32 : Int) : Void { WriteVarint32( ZigZag.FromInt( i32)); } /** * Write an i64 as a zigzag varint. */ public function writeI64( i64 : haxe.Int64) : Void { WriteVarint64( ZigZag.FromLong( i64)); } /** * Write a double to the wire as 8 bytes. */ public function writeDouble( dub : Float) : Void { var data = BitConverter.fixedLongToBytes( BitConverter.DoubleToInt64Bits(dub)); Transport.write( data, 0, data.length); } /** * Write a string to the wire with a varint size preceding. */ public function writeString(str : String) : Void { var buf = new BytesBuffer(); buf.addString( str, Encoding.UTF8); var tmp = buf.getBytes(); writeBinary( tmp); } /** * Write a byte array, using a varint for the size. */ public function writeBinary( bin : Bytes) : Void { WriteVarint32( cast(bin.length,UInt)); Transport.write( bin, 0, bin.length); } public function writeUuid(uuid : String) : Void { var bytes : Bytes = Uuid.parse(UuidHelper.CanonicalUuid(uuid)); Transport.write(bytes, 0, bytes.length); } // These methods are called by structs, but don't actually have any wire // output or purpose. public function writeMessageEnd() : Void { } public function writeMapEnd() : Void { } public function writeListEnd() : Void { } public function writeSetEnd() : Void { } public function writeFieldEnd() : Void { } // // Internal writing methods // /** * Abstract method for writing the start of lists and sets. List and sets on * the wire differ only by the type indicator. */ private function WriteCollectionBegin( elemType : Int, size : Int) : Void { if (size <= 14) { WriteByteDirect( size << 4 | getCompactType(elemType)); } else { WriteByteDirect( 0xf0 | getCompactType(elemType)); WriteVarint32( cast(size, UInt)); } } /** * Write an i64 as a varint. Results in 1-10 bytes on the wire. */ private function WriteVarint64(n : haxe.Int64) : Void { var varint64out = new BytesBuffer(); while (true) { if( Int64.isZero( Int64.and( n, Int64.neg(Int64.make(0,0x7F))))) { #if( haxe_ver < 3.2) varint64out.addByte( Int64.getLow(n)); #else varint64out.addByte( n.low); #end break; } else { #if ( haxe_ver < 3.2) varint64out.addByte( (Int64.getLow(n) & 0x7F) | 0x80); #else varint64out.addByte( (n.low & 0x7F) | 0x80); #end n = Int64.shr( n, 7); n = Int64.and( n, Int64.make(0x01FFFFFF,0xFFFFFFFF)); // clean out the shifted 7 bits } } var tmp = varint64out.getBytes(); Transport.write( tmp, 0, tmp.length); } /** * Read a message header. */ public function readMessageBegin():TMessage { Reset(); var protocolId : Int = readByte(); if (protocolId != PROTOCOL_ID) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Expected protocol id " + StringTools.hex(PROTOCOL_ID,2) + " but got " + StringTools.hex(protocolId)); } var versionAndType : Int = readByte(); var version : Int = (versionAndType & VERSION_MASK); if (version != VERSION) { throw new TProtocolException( TProtocolException.INVALID_DATA, "Expected version " + VERSION + " but got " + version); } var type : Int = ((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); var seqid : Int = cast( ReadVarint32(), Int); var msgNm : String = readString(); return new TMessage( msgNm, type, seqid); } /** * Read a struct begin. There's nothing on the wire for this, but it is our * opportunity to push a new struct begin marker onto the field stack. */ public function readStructBegin():TStruct { lastField_.add(lastFieldId_); lastFieldId_ = 0; return ANONYMOUS_STRUCT; } /** * Doesn't actually consume any wire data, just removes the last field for * this struct from the field stack. */ public function readStructEnd() : Void { // consume the last field we Read off the wire. lastFieldId_ = lastField_.pop(); } /** * Read a field header off the wire. */ public function readFieldBegin() : TField { var type : Int = readByte(); // if it's a stop, then we can return immediately, as the struct is over. if (type == cast(TCompactTypes.STOP,Int)) { return TSTOP; } var fieldId : Int; // mask off the 4 MSB of the type header. it could contain a field id delta. var modifier : Int = ((type & 0xf0) >> 4); if (modifier == 0) fieldId = readI16(); // not a delta. look ahead for the zigzag varint field id. else fieldId = lastFieldId_ + modifier; // add the delta to the last Read field id. var field : TField = new TField( "", cast(getTType(type & 0x0f),Int), fieldId); // if this happens to be a boolean field, the value is encoded in the type if (isBoolType(type)) { // save the boolean value in a special instance variable. boolValue_ = ((type & 0x0f) == cast(TCompactTypes.BOOLEAN_TRUE,Int)); } // push the new field onto the field stack so we can keep the deltas going. lastFieldId_ = field.id; return field; } /** * Read a map header off the wire. If the size is zero, skip Reading the key * and value type. This means that 0-length maps will yield TMaps without the * "correct" types. */ public function readMapBegin() : TMap { var size : Int = cast( ReadVarint32(), Int); var keyAndValueType : Int = ((size == 0) ? 0 : readByte()); var key : Int = cast( getTType( (keyAndValueType & 0xF0) >> 4), Int); var val : Int = cast( getTType( keyAndValueType & 0x0F), Int); var map = new TMap( key, val, size); CheckReadBytesAvailableMap(map); return map; } /** * Read a list header off the wire. If the list size is 0-14, the size will * be packed into the element type header. If it's a longer list, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ public function readListBegin():TList { var size_and_type : Int = readByte(); var size : Int = ((size_and_type & 0xF0) >> 4) & 0x0F; if (size == 15) { size = cast( ReadVarint32(), Int); } var type = getTType(size_and_type); var list = new TList( type, size); CheckReadBytesAvailableList(list); return list; } /** * Read a set header off the wire. If the set size is 0-14, the size will * be packed into the element type header. If it's a longer set, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ public function readSetBegin() : TSet { var size_and_type : Int = readByte(); var size : Int = ((size_and_type & 0xF0) >> 4) & 0x0F; if (size == 15) { size = cast( ReadVarint32(), Int); } var type = getTType(size_and_type); var set = new TSet( type, size); CheckReadBytesAvailableSet(set); return set; } /** * Read a boolean off the wire. If this is a boolean field, the value should * already have been Read during ReadFieldBegin, so we'll just consume the * pre-stored value. Otherwise, Read a byte. */ public function readBool() : Bool { if (boolValue_ != null) { var result : Bool = boolValue_; boolValue_ = null; return result; } return (readByte() == cast(TCompactTypes.BOOLEAN_TRUE,Int)); } /** * Read a single byte off the wire. Nothing interesting here. */ public function readByte() : Int { var byteRawBuf = new BytesBuffer(); Transport.readAll( byteRawBuf, 0, 1); return byteRawBuf.getBytes().get(0); } /** * Read an i16 from the wire as a zigzag varint. */ public function readI16() : Int { return ZigZag.ToInt( ReadVarint32()); } /** * Read an i32 from the wire as a zigzag varint. */ public function readI32() : Int { return ZigZag.ToInt( ReadVarint32()); } /** * Read an i64 from the wire as a zigzag varint. */ public function readI64() : haxe.Int64 { return ZigZag.ToLong( ReadVarint64()); } /** * No magic here - just Read a double off the wire. */ public function readDouble():Float { var longBits = new BytesBuffer(); Transport.readAll( longBits, 0, 8); return BitConverter.Int64BitsToDouble( BitConverter.bytesToLong( longBits.getBytes())); } /** * Reads a byte[] (via ReadBinary), and then UTF-8 decodes it. */ public function readString() : String { var length : Int = cast( ReadVarint32(), Int); Transport.CheckReadBytesAvailable(length); if (length == 0) { return ""; } var buf = new BytesBuffer(); Transport.readAll( buf, 0, length); length = buf.length; var inp = new BytesInput( buf.getBytes()); var str = inp.readString( length, Encoding.UTF8); return str; } /** * Read a byte[] from the wire. */ public function readBinary() : Bytes { var length : Int = cast( ReadVarint32(), Int); Transport.CheckReadBytesAvailable(length); if (length == 0) { return Bytes.alloc(0); } var buf = new BytesBuffer(); Transport.readAll( buf, 0, length); return buf.getBytes(); } public function readUuid() : String { var buffer = new BytesBuffer(); Transport.readAll( buffer, 0, 16); var bytes : Bytes = buffer.getBytes(); return Uuid.stringify( bytes); } // These methods are here for the struct to call, but don't have any wire // encoding. public function readMessageEnd() : Void { } public function readFieldEnd() : Void { } public function readMapEnd() : Void { } public function readListEnd() : Void { } public function readSetEnd() : Void { } // // Internal Reading methods // /** * 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. */ private function ReadVarint32() : UInt { var result : UInt = 0; var shift : Int = 0; while (true) { var b : Int = readByte(); result |= cast((b & 0x7f) << shift, UInt); if ((b & 0x80) != 0x80) { break; } shift += 7; } return result; } /** * 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. */ private function ReadVarint64() : Int64 { var shift : Int = 0; var result : Int64 = Int64.make(0,0); while (true) { var b : Int = readByte(); result = Int64.or( result, Int64.shl( Int64.make(0,b & 0x7f), shift)); if ((b & 0x80) != 0x80) { break; } shift += 7; } return result; } // // type testing and converting // private function isBoolType( b : Int) : Bool { var lowerNibble : Int = b & 0x0f; switch(lowerNibble) { case TCompactTypes.BOOLEAN_TRUE: return true; case TCompactTypes.BOOLEAN_FALSE: return true; default: return false; } } /** * Given a TCompactProtocol.TCompactTypes constant, convert it to its corresponding * TType value. */ private function getTType( type : Int) : Int { try { return tcompactTypeToType[type]; } catch ( e : Dynamic) { var tt : Int = (type & 0x0f); throw new TProtocolException( TProtocolException.UNKNOWN, 'don\'t know what type: $tt ($e)'); } } /** * Given a TType value, find the appropriate TCompactProtocol.TCompactTypes constant. */ private function getCompactType( ttype : Int) : Int { return cast( ttypeToCompactType[ttype], Int); } // Return the minimum number of bytes a type will consume on the wire public override function GetMinSerializedSize(type : TType) : Int { switch (type) { case TType.STOP: return 1; // T_STOP needs to count itself case TType.VOID_: return 1; // T_VOID needs to count itself case TType.BOOL: return 1; case TType.DOUBLE: return 8; // uses fixedLongToBytes() which always writes 8 bytes case TType.BYTE: return 1; case TType.I16: return 1; // zigzag case TType.I32: return 1; // zigzag case TType.I64: return 1; // zigzag case TType.STRING: return 1; // string length case TType.STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP case TType.MAP: return 1; // element count case TType.SET: return 1; // element count case TType.LIST: return 1; // element count case TType.UUID: return 16; // uuid bytes default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code"); } } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TProtocolUtil.hx0000664000175000017500000000657215165535636026166 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.*; /** * Utility class with static methods for interacting with protocol data * streams. * */ class TProtocolUtil { /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be intepreted as this TType value. */ public static function skip(prot:TProtocol, type : Int) : Void { prot.IncrementRecursionDepth(); try { switch (type) { case TType.BOOL: prot.readBool(); case TType.BYTE: prot.readByte(); case TType.I16: prot.readI16(); case TType.I32: prot.readI32(); case TType.I64: prot.readI64(); case TType.DOUBLE: prot.readDouble(); case TType.STRING: prot.readBinary(); case TType.STRUCT: prot.readStructBegin(); while (true) { var field:TField = prot.readFieldBegin(); if (field.type == TType.STOP) { break; } skip(prot, field.type); prot.readFieldEnd(); } prot.readStructEnd(); case TType.MAP: var map:TMap = prot.readMapBegin(); for (i in 0 ... map.size) { skip(prot, map.keyType); skip(prot, map.valueType); } prot.readMapEnd(); case TType.SET: var set:TSet = prot.readSetBegin(); for (j in 0 ... set.size) { skip(prot, set.elemType); } prot.readSetEnd(); case TType.LIST: var list:TList = prot.readListBegin(); for (k in 0 ... list.size) { skip(prot, list.elemType); } prot.readListEnd(); default: throw new TProtocolException(TProtocolException.UNKNOWN, "Unknown field type ${type}"); } prot.DecrementRecursionDepth(); } catch(e:Dynamic) { prot.DecrementRecursionDepth(); throw e; } } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TMultiplexedProtocol.hx0000664000175000017500000000677315165535636027550 0ustar00buildbuild00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.transport.TTransport; /** * TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift * client to communicate with a multiplexing Thrift server, by prepending the service name * to the function name during function calls. * * NOTE: THIS IS NOT TO BE USED BY SERVERS. * On the server, use TMultiplexedProcessor to handle requests from a multiplexing client. * * This example uses a single socket transport to invoke two services: * * TSocket transport = new TSocket("localhost", 9090); * transport.open(); * * TBinaryProtocol protocol = new TBinaryProtocol(transport); * * TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator"); * Calculator.Client service = new Calculator.Client(mp); * * TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport"); * WeatherReport.Client service2 = new WeatherReport.Client(mp2); * * System.out.println(service.add(2,2)); * System.out.println(service2.getTemperature()); * */ class TMultiplexedProtocol extends TProtocolDecorator { /** Used to delimit the service name from the function name */ public static inline var SEPARATOR : String = ":"; private var service : String; /** * Wrap the specified protocol, allowing it to be used to communicate with a * multiplexing server. The serviceName is required as it is * prepended to the message header so that the multiplexing server can broker * the function call to the proper service. * * Args: * protocol Your communication protocol of choice, e.g. TBinaryProtocol * serviceName The service name of the service communicating via this protocol. */ public function new( protocol : TProtocol, serviceName : String) { super( protocol); service = serviceName; } /** * Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR. * Args: * tMessage The original message. */ public override function writeMessageBegin( message : TMessage) : Void { switch( message.type) { case TMessageType.CALL: super.writeMessageBegin(new TMessage( service + SEPARATOR + message.name, message.type, message.seqid)); case TMessageType.ONEWAY: super.writeMessageBegin(new TMessage( service + SEPARATOR + message.name, message.type, message.seqid)); default: super.writeMessageBegin(message); } } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TProtocolFactory.hx0000664000175000017500000000171715165535636026654 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.transport.TTransport; interface TProtocolFactory { function getProtocol(trans:TTransport):TProtocol; }thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TSet.hx0000664000175000017500000000177715165535636024264 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; class TSet { public var elemType : Int; public var size : Int; public function new(t : Int = 0, s : Int = 0) { elemType = t; size = s; } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TMessageType.hx0000664000175000017500000000211015165535636025735 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; enum abstract TMessageType(Int) from Int to Int { public static inline var CALL : Int = 1; public static inline var REPLY : Int = 2; public static inline var EXCEPTION : Int = 3; public static inline var ONEWAY : Int = 4; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocolFactory.hx0000664000175000017500000000255215165535636030017 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.transport.TTransport; /** * Binary Protocol Factory */ class TBinaryProtocolFactory implements TProtocolFactory { private var strictRead_ : Bool = false; private var strictWrite_ : Bool = true; public function new( strictRead : Bool = false, strictWrite : Bool = true) { strictRead_ = strictRead; strictWrite_ = strictWrite; } public function getProtocol( trans : TTransport) : TProtocol { return new TBinaryProtocol( trans, strictRead_, strictWrite_); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TMap.hx0000664000175000017500000000206315165535636024233 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; class TMap { public var keyType : Int; public var valueType : Int; public var size : Int; public function new(k : Int = 0, v : Int = 0, s : Int = 0) { keyType = k; valueType = v; size = s; } }thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TType.hx0000664000175000017500000000311315165535636024434 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; enum abstract TType(Int) from Int to Int { public static inline var STOP : Int = 0; public static inline var VOID_ : Int = 1; // VOID produces collisions with cpp targets in some cases public static inline var BOOL : Int = 2; public static inline var BYTE : Int = 3; public static inline var DOUBLE : Int = 4; public static inline var I16 : Int = 6; public static inline var I32 : Int = 8; public static inline var I64 : Int = 10; public static inline var STRING : Int = 11; public static inline var STRUCT : Int = 12; public static inline var MAP : Int = 13; public static inline var SET : Int = 14; public static inline var LIST : Int = 15; public static inline var UUID : Int = 16; } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocolFactory.hx0000664000175000017500000000217515165535636030162 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.transport.TTransport; /** * Compact Protocol Factory */ class TCompactProtocolFactory implements TProtocolFactory { public function new() { } public function getProtocol( trans : TTransport) : TProtocol { return new TCompactProtocol( trans); } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx0000664000175000017500000002362015165535636026466 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import haxe.io.Bytes; import haxe.io.BytesInput; import haxe.io.BytesOutput; import haxe.io.BytesBuffer; import haxe.Int64; import uuid.Uuid; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.helper.UuidHelper; /** * Binary protocol implementation for thrift. */ class TBinaryProtocol extends TProtocolImplBase implements TProtocol { private static var ANONYMOUS_STRUCT:TStruct = new TStruct(); private static inline var VERSION_MASK : haxe.Int32 = 0xffff0000; private static inline var VERSION_1 : haxe.Int32 = 0x80010000; private var strictRead_ : Bool = false; private var strictWrite_ : Bool = true; /** * Constructor */ public function new(transport:TTransport, strictRead : Bool = false, strictWrite : Bool = true) { super(transport); strictRead_ = strictRead; strictWrite_ = strictWrite; } public function writeMessageBegin(message:TMessage) : Void { if (strictWrite_) { var version : Int = VERSION_1 | message.type; writeI32(version); writeString(message.name); writeI32(message.seqid); } else { writeString(message.name); writeByte(message.type); writeI32(message.seqid); } } public function writeMessageEnd() : Void {} public function writeStructBegin(struct:TStruct) : Void {} public function writeStructEnd() : Void {} public function writeFieldBegin(field:TField) : Void { writeByte(field.type); writeI16(field.id); } public function writeFieldEnd() : Void {} public function writeFieldStop() : Void { writeByte(TType.STOP); } public function writeMapBegin(map:TMap) : Void { writeByte(map.keyType); writeByte(map.valueType); writeI32(map.size); } public function writeMapEnd() : Void {} public function writeListBegin(list:TList) : Void { writeByte(list.elemType); writeI32(list.size); } public function writeListEnd() : Void {} public function writeSetBegin(set:TSet) : Void { writeByte(set.elemType); writeI32(set.size); } public function writeSetEnd() : Void {} public function writeBool(b : Bool) : Void { writeByte(b ? 1 : 0); } public function writeByte(b : Int) : Void { var out = new BytesOutput(); out.bigEndian = true; out.writeByte(b); Transport.write(out.getBytes(), 0, 1); } public function writeI16(i16 : Int) : Void { var out = new BytesOutput(); out.bigEndian = true; out.writeInt16(i16); Transport.write(out.getBytes(), 0, 2); } public function writeI32(i32 : Int) : Void { var out = new BytesOutput(); out.bigEndian = true; out.writeInt32(i32); Transport.write(out.getBytes(), 0, 4); } public function writeI64(i64 : haxe.Int64) : Void { var out = new BytesOutput(); out.bigEndian = true; #if( haxe_ver < 3.2) var hi = Int64.getHigh(i64); var lo = Int64.getLow(i64); out.writeInt32(hi); out.writeInt32(lo); #else out.writeInt32(i64.high); out.writeInt32(i64.low); #end Transport.write(out.getBytes(), 0, 8); } public function writeDouble(dub:Float) : Void { var out = new BytesOutput(); out.bigEndian = true; out.writeDouble(dub); Transport.write(out.getBytes(), 0, 8); } public function writeString(str : String) : Void { var out = new BytesOutput(); out.bigEndian = true; out.writeString(str); var bytes = out.getBytes(); writeI32( bytes.length); Transport.write( bytes, 0, bytes.length); } public function writeBinary(bin:Bytes) : Void { writeI32(bin.length); Transport.write(bin, 0, bin.length); } public function writeUuid(uuid : String) : Void { var bytes : Bytes = Uuid.parse(UuidHelper.CanonicalUuid(uuid)); Transport.write(bytes, 0, bytes.length); } /** * Reading methods. */ public function readMessageBegin():TMessage { var size : Int = readI32(); if (size < 0) { var version : Int = size & VERSION_MASK; if (version != VERSION_1) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Bad version in readMessageBegin"); } return new TMessage(readString(), size & 0x000000ff, readI32()); } else { if (strictRead_) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?"); } return new TMessage(readStringBody(size), readByte(), readI32()); } } public function readMessageEnd() : Void {} public function readStructBegin():TStruct { return ANONYMOUS_STRUCT; } public function readStructEnd() : Void {} public function readFieldBegin() : TField { var type : Int = readByte(); var id : Int = 0; if (type != TType.STOP) { id = readI16(); } return new TField("", type, id); } public function readFieldEnd() : Void {} public function readMapBegin() : TMap { var map = new TMap(readByte(), readByte(), readI32()); CheckReadBytesAvailableMap(map); return map; } public function readMapEnd() : Void {} public function readListBegin():TList { var list = new TList(readByte(), readI32()); CheckReadBytesAvailableList(list); return list; } public function readListEnd() : Void {} public function readSetBegin() : TSet { var set = new TSet(readByte(), readI32()); CheckReadBytesAvailableSet(set); return set; } public function readSetEnd() : Void {} public function readBool() : Bool { return (readByte() == 1); } public function readByte() : Int { var buffer = new BytesBuffer(); var len = Transport.readAll( buffer, 0, 1); var inp = new BytesInput( buffer.getBytes(), 0, 1); inp.bigEndian = true; return inp.readByte(); } public function readI16() : Int { var buffer = new BytesBuffer(); var len = Transport.readAll( buffer, 0, 2); var inp = new BytesInput( buffer.getBytes(), 0, 2); inp.bigEndian = true; return inp.readInt16(); } public function readI32() : Int { var buffer = new BytesBuffer(); var len = Transport.readAll( buffer, 0, 4); var inp = new BytesInput( buffer.getBytes(), 0, 4); inp.bigEndian = true; return inp.readInt32(); } public function readI64() : haxe.Int64 { var buffer = new BytesBuffer(); var len = Transport.readAll( buffer, 0, 8); var inp = new BytesInput( buffer.getBytes(), 0, 8); inp.bigEndian = true; var hi = inp.readInt32(); var lo = inp.readInt32(); return Int64.make(hi,lo); } public function readDouble():Float { var buffer = new BytesBuffer(); var len = Transport.readAll( buffer, 0, 8); var inp = new BytesInput( buffer.getBytes(), 0, 8); inp.bigEndian = true; return inp.readDouble(); } public function readString() : String { return readStringBody( readI32()); } public function readStringBody(len : Int) : String { Transport.CheckReadBytesAvailable(len); if( len > 0) { var buffer = new BytesBuffer(); Transport.readAll( buffer, 0, len); var inp = new BytesInput( buffer.getBytes(), 0, len); inp.bigEndian = true; return inp.readString(len); } else { return ""; } } public function readBinary() : Bytes { var len : Int = readI32(); Transport.CheckReadBytesAvailable(len); var buffer = new BytesBuffer(); Transport.readAll( buffer, 0, len); return buffer.getBytes(); } public function readUuid() : String { var buffer = new BytesBuffer(); Transport.readAll( buffer, 0, 16); var bytes : Bytes = buffer.getBytes(); return Uuid.stringify( bytes); } // Return the minimum number of bytes a type will consume on the wire public override function GetMinSerializedSize(type : TType) : Int { switch (type) { case TType.STOP: return 1; // T_STOP needs to count itself case TType.VOID_: return 1; // T_VOID needs to count itself case TType.BOOL: return 1; case TType.BYTE: return 1; case TType.DOUBLE: return 8; case TType.I16: return 2; case TType.I32: return 4; case TType.I64: return 8; case TType.STRING: return 4; // string length case TType.STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP case TType.MAP: return 4; // element count case TType.SET: return 4; // element count case TType.LIST: return 4; // element count case TType.UUID: return 16; // uuid bytes default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code"); } } } thrift-0.23.0/lib/haxe/src/org/apache/thrift/ArgumentError.hx0000664000175000017500000000174115165535636024327 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; #if ! flash // predefined for flash only class ArgumentError extends TException { public function new(msg : String = "") { super(msg); } } #end thrift-0.23.0/lib/haxe/src/org/apache/thrift/AbstractMethodError.hx0000664000175000017500000000217115165535636025447 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; #if flash import flash.errors.IllegalOperationError; #else import org.apache.thrift.TException; #end class AbstractMethodError #if flash extends IllegalOperationError #else extends TException #end { public function new(message : String="") { super("Attempt to call an abstract method"); } } thrift-0.23.0/lib/haxe/test/0000775000175000017500000000000015170007175016033 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/test/HaxeTests.hxproj0000664000175000017500000000446415165535636021223 0ustar00buildbuild00000000000000 thrift -r -gen haxe ../../../test/ThriftTest.thrift thrift -r -gen haxe ../../../test/ConstantsDemo.thrift thrift -r -gen haxe ../../../contrib/async-test/aggr.thrift thrift -r -gen haxe ../../../lib/rb/benchmark/Benchmark.thrift thrift-0.23.0/lib/haxe/test/make_all.sh0000664000175000017500000000243315165535636020152 0ustar00buildbuild00000000000000#!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # invoke Thrift comnpiler thrift -r -gen haxe ../../../test/ThriftTest.thrift thrift -r -gen haxe ../../../contrib/async-test/aggr.thrift thrift -r -gen haxe ../../../lib/rb/benchmark/Benchmark.thrift # output folder if [ ! -d bin ]; then mkdir bin fi # invoke Haxe compiler for target in *.hxml; do echo -------------------------- echo Building ${target} ... echo -------------------------- if [ ! -d bin/${target} ]; then mkdir bin/${target} fi haxe --cwd . ${target} done #eof thrift-0.23.0/lib/haxe/test/cpp.hxml0000664000175000017500000000241115165535636017521 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #CPP target -cpp bin #To produce 64 bit binaries the file should define the HXCPP_M64 compile variable: #-D HXCPP_M64 # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/lib/haxe/test/src/0000775000175000017500000000000015165535636016636 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/test/src/Main.hx0000664000175000017500000000474615165535636020076 0ustar00buildbuild00000000000000/* * 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; import org.apache.thrift.*; import org.apache.thrift.meta_data.*; import org.apache.thrift.protocol.*; import org.apache.thrift.server.*; import org.apache.thrift.transport.*; import tests.ConstantsTest; import tests.MultiplexTest; import tests.StreamTest; import thrift.test.*; enum WhatTests { Normal; Multiplex; Constants; } class Main { static private var what : WhatTests = Normal; static private var server : Bool = false; static private inline var CMDLINEHELP : String = "\nHaxeTests [client|server] [multiplex]\n" + " client|server ... determines run mode for some tests, default is client\n" + " multiplex ........ run multiplex test server or client\n" + " constants ........ run constants and conformity tests\n" ; static private function ParseArgs() { #if sys var args = Sys.args(); if ( args != null) { for ( arg in args) { switch (arg.toLowerCase()) { case "client": server = false; case "server" : server = true; case "multiplex" : what = Multiplex; case "constants" : what = Constants; default: throw 'Invalid argument "$arg"\n'+CMDLINEHELP; } } } #end } static public function main() { try { ParseArgs(); switch ( what) { case Normal: #if sys tests.StreamTest.Run(server); #end case Multiplex: #if ! (flash || html5 || js) tests.MultiplexTest.Run(server); #end case Constants: tests.ConstantsTest.Run(server); default: throw 'Unhandled test mode $what'; } trace("All tests completed."); } catch ( e: Dynamic) { trace('$e'); #if sys Sys.exit(1); // indicate error #end } } }thrift-0.23.0/lib/haxe/test/src/tests/0000775000175000017500000000000015165535636020000 5ustar00buildbuild00000000000000thrift-0.23.0/lib/haxe/test/src/tests/ConstantsTest.hx0000664000175000017500000001372415165535636023164 0ustar00buildbuild00000000000000/* * 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 haxe.Int64; import haxe.io.BytesBuffer; import tests.TestBase; import org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.server.*; import org.apache.thrift.meta_data.*; import constantsDemo.*; // generated code class ConstantsTest extends tests.TestBase { public static function Run(server : Bool) : Void { TestConstants(); TestProtocolConformity(); } private static function TestConstants() : Void { tests.TestBase.Expect( ConstantsDemoConstants.myInt == 3, "myInt = 3"); tests.TestBase.Expect( ConstantsDemoConstants.hex_const == 0x0001F, "hex_const = 31"); tests.TestBase.Expect( ConstantsDemoConstants.negative_hex_constant == -0x0001F, "negative_hex_constant = -31"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_ME == -3523553, "GEN_ME = -3523553"); tests.TestBase.Expect( ConstantsDemoConstants.GEn_DUB == 325.532, "GEn_DUB = 325.532"); tests.TestBase.Expect( ConstantsDemoConstants.GEn_DU == 85.2355, "GEn_DU = 85.2355"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_STRING == "asldkjasfd", "GEN_STRING = \"asldkjasfd\""); tests.TestBase.Expect( ConstantsDemoConstants.e10 == 1e+10, "e10 = 1e+10"); tests.TestBase.Expect( ConstantsDemoConstants.e11 == -1e+10, "e11 = -1e+10"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_UUID == "00000000-4444-CCCC-ffff-0123456789ab", "GEN_UUID = \"00000000-4444-CCCC-ffff-0123456789ab\""); tests.TestBase.Expect( ConstantsDemoConstants.GEN_MAP.get(35532) == 233, "GEN_MAP.get(35532) == 233"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_MAP.get(43523) == 853, "GEN_MAP.get(43523) == 853"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_LIST.length == 3, "GEN_LIST.size() == 3"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_LIST.join("/") == "235235/23598352/3253523", "GEN_LIST elements"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_MAPMAP.get(235).get(532) == 53255, "GEN_MAPMAP.get(235).get(532) == 53255"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_MAPMAP.get(235).get(235) == 235, "GEN_MAPMAP.get(235).get(235) == 235"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_MAP2.get("hello") == 233, "GEN_MAP2.get(\"hello\") == 233"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_MAP2.get("lkj98d") == 853, "GEN_MAP2.get(\"lkj98d\") == 853"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_MAP2.get('lkjsdf') == 98325, "GEN_MAP2.get('lkjsdf') == 98325"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_THING.hello == 325, "GEN_THING.hello == 325"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_THING.goodbye == 325352, "GEN_THING.goodbye == 325352"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_WHAT.get(35).hello == 325, "GEN_WHAT.get(35).hello == 325"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_WHAT.get(35).goodbye == 325352, "GEN_WHAT.get(35).goodbye == 325352"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_SET.size == 2, "GEN_SET.size() == 2"); tests.TestBase.Expect( ConstantsDemoConstants.GEN_SET.contains(235), "GEN_SET.contains(235)"); // added twice, but this is a set tests.TestBase.Expect( ConstantsDemoConstants.GEN_SET.contains(53235), "GEN_SET.contains(53235)"); } private static function TestProtocolConformity() : Void { for( factory in [new TBinaryProtocolFactory(), new TCompactProtocolFactory(), new TJSONProtocolFactory()]) { DeserializeGuidData(factory); } } private static function DeserializeGuidData(factory : TProtocolFactory) : Void { var data = new BytesBuffer(); var sCase = Type.getClassName(Type.getClass(factory)).split('.').pop(); switch(sCase) { case "TJSONProtocolFactory": data.addString('"00112233-4455-6677-8899-aabbccddeeff"'); case "TCompactProtocolFactory": data.addByte(0x00); data.addByte(0x11); data.addByte(0x22); data.addByte(0x33); data.addByte(0x44); data.addByte(0x55); data.addByte(0x66); data.addByte(0x77); data.addByte(0x88); data.addByte(0x99); data.addByte(0xaa); data.addByte(0xbb); data.addByte(0xcc); data.addByte(0xdd); data.addByte(0xee); data.addByte(0xff); case "TBinaryProtocolFactory": data.addByte(0x00); data.addByte(0x11); data.addByte(0x22); data.addByte(0x33); data.addByte(0x44); data.addByte(0x55); data.addByte(0x66); data.addByte(0x77); data.addByte(0x88); data.addByte(0x99); data.addByte(0xaa); data.addByte(0xbb); data.addByte(0xcc); data.addByte(0xdd); data.addByte(0xee); data.addByte(0xff); default: tests.TestBase.Expect( false, 'Unhandled ${sCase}'); } var stream = new TMemoryStream(data.getBytes()); stream.Position = 0; var config = new TConfiguration(); var transport = new TStreamTransport(stream, stream, config); var protocol = factory.getProtocol(transport); var sUuid = protocol.readUuid(); tests.TestBase.Expect( sUuid == "00112233-4455-6677-8899-aabbccddeeff", 'DeserializeGuidData(${sCase}): ${sUuid}'); } } thrift-0.23.0/lib/haxe/test/src/tests/MultiplexTest.hx0000664000175000017500000001473715165535636023200 0ustar00buildbuild00000000000000/* * 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 tests.TestBase; #if ! (flash || html5 || js) import haxe.Int64; import haxe.Int32; import org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.server.*; import org.apache.thrift.meta_data.*; // debug only import org.apache.thrift.protocol.TProtocolDecorator; import org.apache.thrift.protocol.TMultiplexedProtocol; import org.apache.thrift.protocol.TMultiplexedProcessor; // generated code imports import Aggr; import AggrImpl; import AggrProcessor; import BenchmarkService; import BenchmarkServiceImpl; import BenchmarkServiceProcessor; import Error; class BenchmarkServiceHandler implements BenchmarkService_service { public function new() { } public function fibonacci(n : haxe.Int32) : haxe.Int32 { trace('Benchmark.fibonacci($n)'); var next : Int; var prev = 0; var result = 1; while( n > 0) { next = result + prev; prev = result; result = next; --n; } return result; } } class AggrServiceHandler implements Aggr_service { private var values : List = new List(); public function new() { } public function addValue(value : haxe.Int32) : Void { trace('Aggr.addValue($value)'); values.add( value); } public function getValues() : List< haxe.Int32> { trace('Aggr.getValues()'); return values; } } class MultiplexTest extends tests.TestBase { private inline static var NAME_BENCHMARKSERVICE : String = "BenchmarkService"; private inline static var NAME_AGGR : String = "Aggr"; public static function Run(server : Bool) : Void { if ( server) { RunMultiplexServer(); } else { RunMultiplexClient(); RunDefaultClient(); } } // run the multiplex server public static function RunMultiplexServer() : Void { try { var benchHandler : BenchmarkService_service = new BenchmarkServiceHandler(); var benchProcessor : TProcessor = new BenchmarkServiceProcessor( benchHandler); var aggrHandler : Aggr_service = new AggrServiceHandler(); var aggrProcessor : TProcessor = new AggrProcessor( aggrHandler); var multiplex : TMultiplexedProcessor = new TMultiplexedProcessor(); multiplex.RegisterProcessor( NAME_BENCHMARKSERVICE, benchProcessor, true); // default multiplex.RegisterProcessor( NAME_AGGR, aggrProcessor); // protocol+transport stack var protfact : TProtocolFactory = new TBinaryProtocolFactory(true,true); var servertrans : TServerTransport = new TServerSocket( 9090, 5, false); var transfact : TTransportFactory = new TFramedTransportFactory(); var server : TServer = new TSimpleServer( multiplex, servertrans, transfact, protfact); trace("Starting the server ..."); server.Serve(); } catch( e : TApplicationException) { tests.TestBase.Expect(false,'${e.errorID} ${e.errorMsg}'); } catch( e : TException) { tests.TestBase.Expect(false,'$e'); } } // run multiplex client against multiplex server public static function RunMultiplexClient() : Void { try { var trans : TTransport; trans = new TSocket("localhost", 9090); trans = new TFramedTransport(trans); trans.open(); var protocol : TProtocol = new TBinaryProtocol(trans,true,true); var multiplex : TMultiplexedProtocol; multiplex = new TMultiplexedProtocol( protocol, NAME_BENCHMARKSERVICE); var bench = new BenchmarkServiceImpl( multiplex); multiplex = new TMultiplexedProtocol( protocol, NAME_AGGR); var aggr = new AggrImpl( multiplex); trace('calling aggr.add( bench.fibo())...'); for( i in 1 ... 10) { trace('$i'); aggr.addValue( bench.fibonacci(i)); } trace('calling aggr ...'); var i = 1; var values = aggr.getValues(); tests.TestBase.Expect(values != null,'aggr.getValues() == null'); for( k in values) { trace('fib($i) = $k'); ++i; } trans.close(); trace('done.'); } catch( e : TApplicationException) { tests.TestBase.Expect(false,'${e.errorID} ${e.errorMsg}'); } catch( e : TException) { tests.TestBase.Expect(false,'$e'); } } // run non-multiplex client against multiplex server to test default fallback public static function RunDefaultClient() : Void { try { var trans : TTransport; trans = new TSocket("localhost", 9090); trans = new TFramedTransport(trans); trans.open(); var protocol : TProtocol = new TBinaryProtocol(trans,true,true); var bench = new BenchmarkServiceImpl( protocol); trace('calling bench (via default) ...'); for( i in 1 ... 10) { var k = bench.fibonacci(i); trace('fib($i) = $k'); } trans.close(); trace('done.'); } catch( e : TApplicationException) { tests.TestBase.Expect(false,'${e.errorID} ${e.errorMsg}'); } catch( e : TException) { tests.TestBase.Expect(false,'$e'); } } } #end thrift-0.23.0/lib/haxe/test/src/tests/StreamTest.hx0000664000175000017500000000573515165535636022446 0ustar00buildbuild00000000000000/* * 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 tests.TestBase; #if sys import haxe.Int64; import sys.FileSystem; import org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.server.*; import org.apache.thrift.meta_data.*; import thrift.test.*; // generated code class StreamTest extends tests.TestBase { private inline static var tmpfile : String = "data.tmp"; private static function MakeTestData() : Xtruct { var data : Xtruct = new Xtruct(); data.string_thing = "Streamtest"; data.byte_thing = -128; data.i32_thing = 4711; data.i64_thing = Int64.make(0x12345678,0x9ABCDEF0); return data; } public static function WriteData() : Xtruct { var config : TConfiguration = new TConfiguration(); var stream : TStream = new TFileStream( tmpfile, CreateNew); var trans : TTransport = new TStreamTransport( null, stream, config); var prot = new TJSONProtocol( trans); var data = MakeTestData(); data.write(prot); trans.close(); return data; } public static function ReadData() : Xtruct { var config : TConfiguration = new TConfiguration(); var stream : TStream = new TFileStream( tmpfile, Read); var trans : TTransport = new TStreamTransport( stream, null, config); var prot = new TJSONProtocol( trans); var data : Xtruct = new Xtruct(); data.read(prot); trans.close(); return data; } public static function Run(server : Bool) : Void { try { var written = WriteData(); var read = ReadData(); FileSystem.deleteFile(tmpfile); tests.TestBase.Expect( read.string_thing == written.string_thing, "string data"); tests.TestBase.Expect( read.byte_thing == written.byte_thing, "byte data"); tests.TestBase.Expect( read.i32_thing == written.i32_thing, "i32 data"); tests.TestBase.Expect( Int64.compare( read.i64_thing, written.i64_thing) == 0, "i64 data"); } catch(e:Dynamic) { FileSystem.deleteFile(tmpfile); throw e; } } } #end thrift-0.23.0/lib/haxe/test/src/tests/TestBase.hx0000664000175000017500000000267115165535636022061 0ustar00buildbuild00000000000000/* * 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 org.apache.thrift.*; import org.apache.thrift.protocol.*; import org.apache.thrift.transport.*; import org.apache.thrift.server.*; import org.apache.thrift.meta_data.*; class TestBase { private function new() { // override, if necessary } public static function Run(server : Bool) : Void { throw new AbstractMethodError(); } public static function Expect( expr : Bool, info : String, ?pos : haxe.PosInfos) : Void { if( ! expr) { throw ('Test "$info" failed at '+pos.methodName+' in '+pos.fileName+':'+pos.lineNumber); } trace('Test "$info" - OK'); } } thrift-0.23.0/lib/haxe/test/flash.hxml0000664000175000017500000000226215165535636020040 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #Flash target -swf bin/Test.swf # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/lib/haxe/test/javascript.hxml0000664000175000017500000000273115165535636021112 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #JavaScript target -js bin/Test.js #You can use -D source-map-content (requires Haxe 3.1+) to have the .hx #files directly embedded into the map file, this way you only have to #upload it, and it will be always in sync with the compiled .js even if #you modify your .hx files. -D source-map-content # libs -lib uuid #Generate source map and add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/lib/haxe/test/python.hxml0000664000175000017500000000226515165535636020267 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #Python target -python bin/Test.py # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/lib/haxe/test/project.hide0000664000175000017500000000303315165535636020347 0ustar00buildbuild00000000000000{ "type" : 0 ,"target" : 4 ,"name" : "Test" ,"main" : null ,"projectPackage" : "" ,"company" : "" ,"license" : "" ,"url" : "" ,"targetData" : [ { "pathToHxml" : "flash.hxml" ,"runActionType" : 1 ,"runActionText" : "bin/Test.swf" } ,{ "pathToHxml" : "javascript.hxml" ,"runActionType" : 1 ,"runActionText" : "bin\\index.html" } ,{ "pathToHxml" : "neko.hxml" ,"runActionType" : 2 ,"runActionText" : "neko bin/Test.n" } ,{ "pathToHxml" : "php.hxml" } ,{ "pathToHxml" : "cpp.hxml" ,"runActionType" : 2 ,"runActionText" : "bin/Main-debug.exe" } ,{ "pathToHxml" : "java.hxml" } ,{ "pathToHxml" : "csharp.hxml" } ,{ "pathToHxml" : "python.hxml" ,"runActionType" : 2 ,"runActionText" : "python bin/Test.py" } ] ,"files" : [ { "path" : "src\\Main.hx" ,"useTabs" : true ,"indentSize" : 4 ,"foldedRegions" : [ ] ,"activeLine" : 13 } ] ,"activeFile" : "src\\Main.hx" ,"openFLTarget" : null ,"openFLBuildMode" : "Debug" ,"runActionType" : null ,"runActionText" : null ,"buildActionCommand" : null ,"hiddenItems" : [ ] ,"showHiddenItems" : false }thrift-0.23.0/lib/haxe/test/make_all.bat0000664000175000017500000000400615165535636020304 0ustar00buildbuild00000000000000@echo off rem /* rem * Licensed to the Apache Software Foundation (ASF) under one rem * or more contributor license agreements. See the NOTICE file rem * distributed with this work for additional information rem * regarding copyright ownership. The ASF licenses this file rem * to you under the Apache License, Version 2.0 (the rem * "License"); you may not use this file except in compliance rem * with the License. You may obtain a copy of the License at rem * rem * http://www.apache.org/licenses/LICENSE-2.0 rem * rem * Unless required by applicable law or agreed to in writing, rem * software distributed under the License is distributed on an rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY rem * KIND, either express or implied. See the License for the rem * specific language governing permissions and limitations rem * under the License. rem */ setlocal if "%HOMEDRIVE%"=="" goto MISSINGVARS if "%HOMEPATH%"=="" goto MISSINGVARS if "%HAXEPATH%"=="" goto NOTINSTALLED set path=%HAXEPATH%;%HAXEPATH%\..\neko;%path% rem # invoke Thrift comnpiler thrift -r -gen haxe ..\..\..\test\ThriftTest.thrift thrift -r -gen haxe ..\..\..\test\ConstantsDemo.thrift thrift -r -gen haxe ..\..\..\contrib\async-test\aggr.thrift thrift -r -gen haxe ..\..\..\lib\rb\benchmark\Benchmark.thrift if errorlevel 1 goto STOP rem # invoke Haxe compiler for all targets for %%a in (*.hxml) do ( rem * filter Python, as it is not supported by Haxe 3.1.3 (but will be in 3.1.4) if not "%%a"=="python.hxml" ( echo -------------------------- echo Building %%a ... echo -------------------------- haxe --cwd . %%a ) ) echo. echo done. pause goto eof :NOTINSTALLED echo FATAL: Either Haxe is not installed, or the HAXEPATH variable is not set. pause goto eof :MISSINGVARS echo FATAL: Unable to locate home folder. echo. echo Both HOMEDRIVE and HOMEPATH need to be set to point to your Home folder. echo The current values are: echo HOMEDRIVE=%HOMEDRIVE% echo HOMEPATH=%HOMEPATH% pause goto eof :STOP pause goto eof :eof thrift-0.23.0/lib/haxe/test/Makefile0000644000175000017500000004656615170007175017512 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/haxe/test/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/haxe/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/haxe/test abs_srcdir = /thrift/src/lib/haxe/test abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. THRIFTCMD = $(THRIFT) --gen haxe -r THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift AGGR = $(top_srcdir)/contrib/async-test/aggr.thrift BENCHMARK = $(top_srcdir)/lib/rb/benchmark/Benchmark.thrift BIN_CPP = bin/Main-debug BIN_PHP = bin/php/Main-debug.php EXTRA_DIST = \ src \ cpp.hxml \ csharp.hxml \ flash.hxml \ java.hxml \ javascript.hxml \ neko.hxml \ php.hxml \ python.hxml \ project.hide \ HaxeTests.hxproj \ make_all.bat \ make_all.sh all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/haxe/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/haxe/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-haxe/thrift/test/ThriftTest.hx: $(THRIFTTEST) $(THRIFTCMD) $(THRIFTTEST) gen-haxe/thrift/test/Aggr.hx: $(AGGR) $(THRIFTCMD) $(AGGR) gen-haxe/thrift/test/BenchmarkService.hx: $(BENCHMARK) $(THRIFTCMD) $(BENCHMARK) all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_CPP): \ src/*.hx \ ../src/org/apache/thrift/**/*.hx \ gen-haxe/thrift/test/ThriftTest.hx \ gen-haxe/thrift/test/Aggr.hx \ gen-haxe/thrift/test/BenchmarkService.hx $(HAXE) --cwd . cpp.hxml $(BIN_PHP): \ src/*.hx \ ../src/org/apache/thrift/**/*.hx \ gen-haxe/thrift/test/ThriftTest.hx \ gen-haxe/thrift/test/Aggr.hx \ gen-haxe/thrift/test/BenchmarkService.hx $(HAXE) --cwd . php.hxml #TODO: other haxe targets # $(HAXE) --cwd . csharp # $(HAXE) --cwd . flash # $(HAXE) --cwd . java # $(HAXE) --cwd . javascript # $(HAXE) --cwd . neko # $(HAXE) --cwd . python # needs Haxe 3.2.0 clean-local: $(RM) -r gen-haxe bin check: $(BIN_CPP) $(BIN_PHP) $(BIN_CPP) php -f $(BIN_PHP) distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/haxe/test/csharp.hxml0000664000175000017500000000226215165535636020223 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #CSHARP target -cs bin/Test.exe # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/lib/haxe/test/neko.hxml0000664000175000017500000000226015165535636017675 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #neko target -neko bin/Test.n # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/lib/haxe/test/java.hxml0000664000175000017500000000226215165535636017664 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #Java target -java bin/Test.jar # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce fullthrift-0.23.0/lib/haxe/test/Makefile.in0000644000175000017500000004547615170007167020117 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/haxe/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ THRIFTCMD = $(THRIFT) --gen haxe -r THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift AGGR = $(top_srcdir)/contrib/async-test/aggr.thrift BENCHMARK = $(top_srcdir)/lib/rb/benchmark/Benchmark.thrift BIN_CPP = bin/Main-debug BIN_PHP = bin/php/Main-debug.php EXTRA_DIST = \ src \ cpp.hxml \ csharp.hxml \ flash.hxml \ java.hxml \ javascript.hxml \ neko.hxml \ php.hxml \ python.hxml \ project.hide \ HaxeTests.hxproj \ make_all.bat \ make_all.sh all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/haxe/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/haxe/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gen-haxe/thrift/test/ThriftTest.hx: $(THRIFTTEST) $(THRIFTCMD) $(THRIFTTEST) gen-haxe/thrift/test/Aggr.hx: $(AGGR) $(THRIFTCMD) $(AGGR) gen-haxe/thrift/test/BenchmarkService.hx: $(BENCHMARK) $(THRIFTCMD) $(BENCHMARK) all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_CPP): \ src/*.hx \ ../src/org/apache/thrift/**/*.hx \ gen-haxe/thrift/test/ThriftTest.hx \ gen-haxe/thrift/test/Aggr.hx \ gen-haxe/thrift/test/BenchmarkService.hx $(HAXE) --cwd . cpp.hxml $(BIN_PHP): \ src/*.hx \ ../src/org/apache/thrift/**/*.hx \ gen-haxe/thrift/test/ThriftTest.hx \ gen-haxe/thrift/test/Aggr.hx \ gen-haxe/thrift/test/BenchmarkService.hx $(HAXE) --cwd . php.hxml #TODO: other haxe targets # $(HAXE) --cwd . csharp # $(HAXE) --cwd . flash # $(HAXE) --cwd . java # $(HAXE) --cwd . javascript # $(HAXE) --cwd . neko # $(HAXE) --cwd . python # needs Haxe 3.2.0 clean-local: $(RM) -r gen-haxe bin check: $(BIN_CPP) $(BIN_PHP) $(BIN_CPP) php -f $(BIN_PHP) distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/haxe/test/php.hxml0000664000175000017500000000231115165535636017525 0ustar00buildbuild00000000000000# # 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. # #integrate files to classpath -cp src -cp ../src -cp gen-haxe #this class wil be used as entry point for your app. -main Main # forced compile of all source files --macro include('org.apache.thrift', true) --macro include('thrift', true) --macro include('constantsDemo', true) #PHP target -php bin/php/ #--php-front Main-debug.php # libs -lib uuid #Add debug information -debug #dead code elimination : remove unused code -dce full thrift-0.23.0/lib/haxe/test/Makefile.am0000664000175000017500000000461315165535636020107 0ustar00buildbuild00000000000000# # 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. # THRIFTCMD = $(THRIFT) --gen haxe -r THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift AGGR = $(top_srcdir)/contrib/async-test/aggr.thrift BENCHMARK = $(top_srcdir)/lib/rb/benchmark/Benchmark.thrift BIN_CPP = bin/Main-debug BIN_PHP = bin/php/Main-debug.php gen-haxe/thrift/test/ThriftTest.hx: $(THRIFTTEST) $(THRIFTCMD) $(THRIFTTEST) gen-haxe/thrift/test/Aggr.hx: $(AGGR) $(THRIFTCMD) $(AGGR) gen-haxe/thrift/test/BenchmarkService.hx: $(BENCHMARK) $(THRIFTCMD) $(BENCHMARK) all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_CPP): \ src/*.hx \ ../src/org/apache/thrift/**/*.hx \ gen-haxe/thrift/test/ThriftTest.hx \ gen-haxe/thrift/test/Aggr.hx \ gen-haxe/thrift/test/BenchmarkService.hx $(HAXE) --cwd . cpp.hxml $(BIN_PHP): \ src/*.hx \ ../src/org/apache/thrift/**/*.hx \ gen-haxe/thrift/test/ThriftTest.hx \ gen-haxe/thrift/test/Aggr.hx \ gen-haxe/thrift/test/BenchmarkService.hx $(HAXE) --cwd . php.hxml #TODO: other haxe targets # $(HAXE) --cwd . csharp # $(HAXE) --cwd . flash # $(HAXE) --cwd . java # $(HAXE) --cwd . javascript # $(HAXE) --cwd . neko # $(HAXE) --cwd . python # needs Haxe 3.2.0 clean-local: $(RM) -r gen-haxe bin check: $(BIN_CPP) $(BIN_PHP) $(BIN_CPP) php -f $(BIN_PHP) distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ src \ cpp.hxml \ csharp.hxml \ flash.hxml \ java.hxml \ javascript.hxml \ neko.hxml \ php.hxml \ python.hxml \ project.hide \ HaxeTests.hxproj \ make_all.bat \ make_all.sh thrift-0.23.0/lib/haxe/coding_standards.md0000664000175000017500000000010315165535636020712 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/haxe/README.md0000664000175000017500000001165315165535636016355 0ustar00buildbuild00000000000000Thrift Haxe Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Thrift with Haxe ======================== Haxe setup --------------- Thrift requires Haxe 4.2.1. Installers for Windows and OSX platforms are available at `http://haxe.org/download`. Depending on the desired targets, you may have to install the appropriate HaxeLibs after installing Haxe itself. For example, if you plan to target C++, enter the following command after installing Haxe: haxelib install hxcpp For other targets, please consult the Haxe documentation whether or not any additional target libraries need to be installed and how to achieve this. Haxe on Linux --------------- For Linux platforms it is recommended to use the distro-specific package manager, where possible. More detailed information can be found at the Haxe Linux download section: http://haxe.org/download/linux If you run into the error message Uncaught exception - load.c(237) : Failed to load library : /usr/lib/neko/regexp.ndll (libpcre.so.3: cannot open shared object file: No such file or directory) this can be solved depending on your OSes bitness by either sudo ln -sf /usr/lib/libpcre.so.1 /usr/lib/libpcre.so.3 sudo ldconfig or sudo ln -sf /usr/lib64/libpcre.so.1 /usr/lib64/libpcre.so.3 sudo ldconfig Thrift Haxe bindings ------------------- Thrift Haxe bindings can be set up via the `haxelib` tool as usual. Alternatively, the "github" method can be used. - To set up any **stable version**, choose the appropriate branch (e.g. `0.14.1`): - `haxelib git thrift https://github.com/apache/thrift.git 0.14.1 lib/haxe` - To set up the current **development version**, use the `master` branch: - `haxelib git thrift https://github.com/apache/thrift.git master lib/haxe` As usual, the installed library can be updated using `haxelib upgrade` or `haxelib update thrift`. In order to work with Thrift, you will need to install the Thrift compiler or build from source, depending on your operating system. Appropriate downloads and more information can be found at http://thrift.apache.org To get started, visit the /tutorial/haxe and /test/haxe dirs for examples. If you are using the HaxeDevelop IDE, you'll find appropriate project files in these folders. Breaking changes ======================== This version requires Haxe 4 and cannot be used with earlier versions. It is recommended to clear out all gen-haxe contents once before switching to the new version. Otherwise you may run into troubles with leftovers from previous versions. The compiler option ```callbacks``` is now obsolete. The compiler will always generate a dual interface (i.e. with optional callback style) for use on the client side, plus a new ```_service``` interface to be used for server implementations. Consequentially, your client and server implementations will need some manual intervention. PHP HTTP Server notes ======================== - you have to import PHP files generated by haxe into PHP ```php require_once dirname(__FILE__) . '/bin/php-web-server/Main-debug.php'; ``` - trace() by default outputs into stdout (http response), so you have to redirect it to stderr or you own logs, something like ```haxe //remap trace to error log haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) { //simulate normal trace https://github.com/HaxeFoundation/haxe/blob/development/std/haxe/Log.hx var newValue : Dynamic; if (infos != null && infos.customParams!=null) { var extra:String = ""; for( v in infos.customParams ) extra += "," + v; newValue = v + extra; } else { newValue = v; } var msg = infos != null ? infos.fileName + ':' + infos.lineNumber + ': ' : ''; Sys.stderr().writeString('${msg}${newValue}\n'); } ``` - to allow thrift server to read/write HTTP request/response, it should be pointed out to php streams ```haxe transport = new TWrappingServerTransport( new TStreamTransport( new TFileStream("php://input", Read), new TFileStream("php://output", Append) ) ); ``` - TSimpleServer doesn't stop after first call, so processor.process() should be called instead, or use runOnce property ```haxe var server = new TSimpleServer( processor, transport, transfactory, protfactory); server.runOnce = true; ``` thrift-0.23.0/lib/haxe/haxelib.json0000664000175000017500000000077315170007142017364 0ustar00buildbuild00000000000000{ "name": "thrift", "url" : "http://thrift.apache.org", "license": "Apache", "tags": [ "thrift", "rpc", "serialization", "cross", "framework" ], "description": "Haxe bindings for the Apache Thrift RPC and serialization framework", "version": "0.23.0", "releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.", "contributors": ["ApacheThrift"], "dependencies": { "crypto": "", "uuid": "" }, "classPath": "src" } thrift-0.23.0/lib/cpp/0000755000175000017500000000000015170007200014674 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/libthriftnb.vcxproj.filters0000664000175000017500000000502415165535636022321 0ustar00buildbuild00000000000000 {bf449d92-4be8-4f6f-a010-c536f57c6f13} {0294d0a6-ce46-4be8-a659-826d6e98ae41} {60fc9e5e-0866-4aba-8662-439bb4a461d3} {23fe2fde-a7c9-43ec-a409-7f53df5eee64} server async async async transport transport server async async async windows windows windows transport transport transport thrift-0.23.0/lib/cpp/libthrift.vcxproj.filters0000664000175000017500000002237615165535636022012 0ustar00buildbuild00000000000000 transport transport windows concurrency concurrency protocol protocol protocol protocol transport transport transport transport transport server server server async async processor transport transport windows windows windows transport transport transport transport protocol concurrency transport transport transport windows transport windows protocol protocol server server server server async async processor processor transport transport transport transport protocol protocol protocol transport windows windows windows windows transport transport {07ced19b-b72a-4105-9ffb-6d2bcf64497e} {e9f61404-1148-4103-bd6f-e5869d37fa79} {2814002a-3c68-427e-b0eb-33acd2f406ae} {addd4707-dbaa-4d0c-bef6-fff8be7b495a} {f55a8e9b-6959-487f-a396-c31b4d6c61d6} {d526885b-1b3e-4ee3-8027-e694fe98ad63} {8f428da8-5a83-44fb-9578-de935fb415e1} {eea10406-3380-4f2d-9365-c26fa2875dae} protocol thrift-0.23.0/lib/cpp/src/0000755000175000017500000000000015170007200015463 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/0000755000175000017500000000000015170007200016763 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/thrift-config.h0000664000175000017500000000157015165535636021733 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifdef _WIN32 #include #endif #include thrift-0.23.0/lib/cpp/src/thrift/TOutput.h0000664000175000017500000000355515167543515020616 0ustar00buildbuild00000000000000/* * 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_OUTPUT_H_ #define _THRIFT_OUTPUT_H_ 1 namespace apache { namespace thrift { class TOutput { public: TOutput(); inline void setOutputFunction(void (*function)(const char*)) { f_ = function; } inline void operator()(const char* message) { f_(message); } // It is important to have a const char* overload here instead of // just the string version, otherwise errno could be corrupted // if there is some problem allocating memory when constructing // the string. void perror(const char* message, int errno_copy); inline void perror(const std::string& message, int errno_copy) { perror(message.c_str(), errno_copy); } void printf(const char* message, ...); static void errorTimeWrapper(const char* msg); /** Just like strerror_r but returns a C++ string object. */ static std::string strerror_s(int errno_copy); /** Get a singleton instance of the global TOutput object used by * the library internally. */ static TOutput& instance(); private: void (*f_)(const char*); }; } } // namespace apache::thrift #endif //_THRIFT_OUTPUT_H_ thrift-0.23.0/lib/cpp/src/thrift/concurrency/0000755000175000017500000000000015170007200021315 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/concurrency/ThreadManager.h0000664000175000017500000001536715165535636024235 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_ #define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1 #include #include #include namespace apache { namespace thrift { namespace concurrency { /** * Thread Pool Manager and related classes * * @version $Id:$ */ class ThreadManager; /** * ThreadManager class * * This class manages a pool of threads. It uses a ThreadFactory to create * threads. It never actually creates or destroys worker threads, rather * it maintains statistics on number of idle threads, number of active threads, * task backlog, and average wait and service times and informs the PoolPolicy * object bound to instances of this manager of interesting transitions. It is * then up the PoolPolicy object to decide if the thread pool size needs to be * adjusted and call this object addWorker and removeWorker methods to make * changes. * * This design allows different policy implementations to use this code to * handle basic worker thread management and worker task execution and focus on * policy issues. The simplest policy, StaticPolicy, does nothing other than * create a fixed number of threads. */ class ThreadManager { protected: ThreadManager() = default; public: typedef std::function)> ExpireCallback; virtual ~ThreadManager() = default; /** * Starts the thread manager. Verifies all attributes have been properly * initialized, then allocates necessary resources to begin operation */ virtual void start() = 0; /** * Stops the thread manager. Aborts all remaining unprocessed task, shuts * down all created worker threads, and releases all allocated resources. * This method blocks for all worker threads to complete, thus it can * potentially block forever if a worker thread is running a task that * won't terminate. * * Worker threads will be joined depending on the threadFactory's detached * disposition. */ virtual void stop() = 0; enum STATE { UNINITIALIZED, STARTING, STARTED, JOINING, STOPPING, STOPPED }; virtual STATE state() const = 0; /** * \returns the current thread factory */ virtual std::shared_ptr threadFactory() const = 0; /** * Set the thread factory. * \throws InvalidArgumentException if the new thread factory has a different * detached disposition than the one replacing it */ virtual void threadFactory(std::shared_ptr value) = 0; /** * Adds worker thread(s). */ virtual void addWorker(size_t value = 1) = 0; /** * Removes worker thread(s). * Threads are joined if the thread factory detached disposition allows it. * Blocks until the number of worker threads reaches the new limit. * \param[in] value the number to remove * \throws InvalidArgumentException if the value is greater than the number * of workers */ virtual void removeWorker(size_t value = 1) = 0; /** * Gets the current number of idle worker threads */ virtual size_t idleWorkerCount() const = 0; /** * Gets the current number of total worker threads */ virtual size_t workerCount() const = 0; /** * Gets the current number of pending tasks */ virtual size_t pendingTaskCount() const = 0; /** * Gets the current number of pending and executing tasks */ virtual size_t totalTaskCount() const = 0; /** * Gets the maximum pending task count. 0 indicates no maximum */ virtual size_t pendingTaskCountMax() const = 0; /** * Gets the number of tasks which have been expired without being run * since start() was called. */ virtual size_t expiredTaskCount() const = 0; /** * Adds a task to be executed at some time in the future by a worker thread. * * This method will block if pendingTaskCountMax() in not zero and pendingTaskCount() * is greater than or equalt to pendingTaskCountMax(). If this method is called in the * context of a ThreadManager worker thread it will throw a * TooManyPendingTasksException * * @param task The task to queue for execution * * @param timeout Time to wait in milliseconds to add a task when a pending-task-count * is specified. Specific cases: * timeout = 0 : Wait forever to queue task. * timeout = -1 : Return immediately if pending task count exceeds specified max * @param expiration when nonzero, the number of milliseconds the task is valid * to be run; if exceeded, the task will be dropped off the queue and not run. * * @throws TooManyPendingTasksException Pending task count exceeds max pending task count */ virtual void add(std::shared_ptr task, int64_t timeout = 0LL, int64_t expiration = 0LL) = 0; /** * Removes a pending task */ virtual void remove(std::shared_ptr task) = 0; /** * Remove the next pending task which would be run. * * @return the task removed. */ virtual std::shared_ptr removeNextPending() = 0; /** * Remove tasks from front of task queue that have expired. */ virtual void removeExpiredTasks() = 0; /** * Set a callback to be called when a task is expired and not run. * * @param expireCallback a function called with the shared_ptr for * the expired task. */ virtual void setExpireCallback(ExpireCallback expireCallback) = 0; static std::shared_ptr newThreadManager(); /** * Creates a simple thread manager the uses count number of worker threads and has * a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit * on pending tasks */ static std::shared_ptr newSimpleThreadManager(size_t count = 4, size_t pendingTaskCountMax = 0); class Task; class Worker; class Impl; }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_ thrift-0.23.0/lib/cpp/src/thrift/concurrency/Mutex.cpp0000664000175000017500000000301215165535636023150 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace concurrency { /** * Implementation of Mutex class using C++11 std::timed_mutex * * Methods throw std::system_error on error. * * @version $Id:$ */ class Mutex::impl : public std::timed_mutex {}; Mutex::Mutex() : impl_(new Mutex::impl()) { } void* Mutex::getUnderlyingImpl() const { return impl_.get(); } void Mutex::lock() const { impl_->lock(); } bool Mutex::trylock() const { return impl_->try_lock(); } bool Mutex::timedlock(int64_t ms) const { return impl_->try_lock_for(std::chrono::milliseconds(ms)); } void Mutex::unlock() const { impl_->unlock(); } } } } // apache::thrift::concurrency thrift-0.23.0/lib/cpp/src/thrift/concurrency/Mutex.h0000664000175000017500000000412615165535636022624 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_MUTEX_H_ #define _THRIFT_CONCURRENCY_MUTEX_H_ 1 #include #include #include namespace apache { namespace thrift { namespace concurrency { /** * NOTE: All mutex implementations throw an exception on failure. See each * specific implementation to understand the exception type(s) used. */ /** * A simple mutex class * * @version $Id:$ */ class Mutex { public: Mutex(); virtual ~Mutex() = default; virtual void lock() const; virtual bool trylock() const; virtual bool timedlock(int64_t milliseconds) const; virtual void unlock() const; void* getUnderlyingImpl() const; private: class impl; std::shared_ptr impl_; }; class Guard : apache::thrift::TNonCopyable { public: Guard(const Mutex& value, int64_t timeout = 0) : mutex_(&value) { if (timeout == 0) { value.lock(); } else if (timeout < 0) { if (!value.trylock()) { mutex_ = nullptr; } } else { if (!value.timedlock(timeout)) { mutex_ = nullptr; } } } ~Guard() { if (mutex_) { mutex_->unlock(); } } operator bool() const { return (mutex_ != nullptr); } private: const Mutex* mutex_; }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_MUTEX_H_ thrift-0.23.0/lib/cpp/src/thrift/concurrency/Monitor.h0000664000175000017500000001013215165535636023143 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_MONITOR_H_ #define _THRIFT_CONCURRENCY_MONITOR_H_ 1 #include #include #include #include namespace apache { namespace thrift { namespace concurrency { /** * A monitor is a combination mutex and condition-event. Waiting and * notifying condition events requires that the caller own the mutex. Mutex * lock and unlock operations can be performed independently of condition * events. This is more or less analogous to java.lang.Object multi-thread * operations. * * Note the Monitor can create a new, internal mutex; alternatively, a * separate Mutex can be passed in and the Monitor will re-use it without * taking ownership. It's the user's responsibility to make sure that the * Mutex is not deallocated before the Monitor. * * Note that all methods are const. Monitors implement logical constness, not * bit constness. This allows const methods to call monitor methods without * needing to cast away constness or change to non-const signatures. * * @version $Id:$ */ class Monitor : apache::thrift::TNonCopyable { public: /** Creates a new mutex, and takes ownership of it. */ Monitor(); /** Uses the provided mutex without taking ownership. */ explicit Monitor(Mutex* mutex); /** Uses the mutex inside the provided Monitor without taking ownership. */ explicit Monitor(Monitor* monitor); /** Deallocates the mutex only if we own it. */ virtual ~Monitor(); Mutex& mutex() const; virtual void lock() const; virtual void unlock() const; /** * Waits a maximum of the specified timeout in milliseconds for the condition * to occur, or waits forever if timeout is zero. * * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code. */ int waitForTimeRelative(const std::chrono::milliseconds &timeout) const; int waitForTimeRelative(uint64_t timeout_ms) const { return waitForTimeRelative(std::chrono::milliseconds(timeout_ms)); } /** * Waits until the absolute time specified by abstime. * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code. */ int waitForTime(const std::chrono::time_point& abstime) const; /** * Waits forever until the condition occurs. * Returns 0 if condition occurs, or an error code otherwise. */ int waitForever() const; /** * Exception-throwing version of waitForTimeRelative(), called simply * wait(std::chrono::milliseconds) for historical reasons. Timeout is in milliseconds. * * If the condition occurs, this function returns cleanly; on timeout or * error an exception is thrown. */ void wait(const std::chrono::milliseconds &timeout) const; void wait(uint64_t timeout_ms = 0ULL) const { this->wait(std::chrono::milliseconds(timeout_ms)); } /** Wakes up one thread waiting on this monitor. */ virtual void notify() const; /** Wakes up all waiting threads on this monitor. */ virtual void notifyAll() const; private: class Impl; Impl* impl_; }; class Synchronized { public: Synchronized(const Monitor* monitor) : g(monitor->mutex()) {} Synchronized(const Monitor& monitor) : g(monitor.mutex()) {} private: Guard g; }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_MONITOR_H_ thrift-0.23.0/lib/cpp/src/thrift/concurrency/ThreadManager.cpp0000664000175000017500000004006115167543515024552 0ustar00buildbuild00000000000000/* * 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 #include #include #include namespace apache { namespace thrift { namespace concurrency { using std::shared_ptr; using std::unique_ptr; using std::dynamic_pointer_cast; /** * ThreadManager class * * This class manages a pool of threads. It uses a ThreadFactory to create * threads. It never actually creates or destroys worker threads, rather * it maintains statistics on number of idle threads, number of active threads, * task backlog, and average wait and service times. * * There are three different monitors used for signaling different conditions * however they all share the same mutex_. * * @version $Id:$ */ class ThreadManager::Impl : public ThreadManager { public: Impl() : workerCount_(0), workerMaxCount_(0), idleCount_(0), pendingTaskCountMax_(0), expiredCount_(0), state_(ThreadManager::UNINITIALIZED), monitor_(&mutex_), maxMonitor_(&mutex_), workerMonitor_(&mutex_) {} ~Impl() override { stop(); } void start() override; void stop() override; ThreadManager::STATE state() const override { return state_; } shared_ptr threadFactory() const override { Guard g(mutex_); return threadFactory_; } void threadFactory(shared_ptr value) override { Guard g(mutex_); if (threadFactory_ && threadFactory_->isDetached() != value->isDetached()) { throw InvalidArgumentException(); } threadFactory_ = value; } void addWorker(size_t value) override; void removeWorker(size_t value) override; size_t idleWorkerCount() const override { return idleCount_; } size_t workerCount() const override { Guard g(mutex_); return workerCount_; } size_t pendingTaskCount() const override { Guard g(mutex_); return tasks_.size(); } size_t totalTaskCount() const override { Guard g(mutex_); return tasks_.size() + workerCount_ - idleCount_; } size_t pendingTaskCountMax() const override { Guard g(mutex_); return pendingTaskCountMax_; } size_t expiredTaskCount() const override { Guard g(mutex_); return expiredCount_; } void pendingTaskCountMax(const size_t value) { Guard g(mutex_); pendingTaskCountMax_ = value; } void add(shared_ptr value, int64_t timeout, int64_t expiration) override; void remove(shared_ptr task) override; shared_ptr removeNextPending() override; void removeExpiredTasks() override { removeExpired(false); } void setExpireCallback(ExpireCallback expireCallback) override; private: /** * Remove one or more expired tasks. * \param[in] justOne if true, try to remove just one task and return */ void removeExpired(bool justOne); /** * \returns whether it is acceptable to block, depending on the current thread id */ bool canSleep() const; /** * Lowers the maximum worker count and blocks until enough worker threads complete * to get to the new maximum worker limit. The caller is responsible for acquiring * a lock on the class mutex_. */ void removeWorkersUnderLock(size_t value); size_t workerCount_; size_t workerMaxCount_; size_t idleCount_; size_t pendingTaskCountMax_; size_t expiredCount_; ExpireCallback expireCallback_; ThreadManager::STATE state_; shared_ptr threadFactory_; friend class ThreadManager::Task; typedef std::deque > TaskQueue; TaskQueue tasks_; Mutex mutex_; Monitor monitor_; Monitor maxMonitor_; Monitor workerMonitor_; // used to synchronize changes in worker count friend class ThreadManager::Worker; std::set > workers_; std::set > deadWorkers_; std::map > idMap_; }; class ThreadManager::Task : public Runnable { public: enum STATE { WAITING, EXECUTING, TIMEDOUT, COMPLETE }; Task(shared_ptr runnable, uint64_t expiration = 0ULL) : runnable_(runnable), state_(WAITING) { if (expiration != 0ULL) { expireTime_.reset(new std::chrono::steady_clock::time_point(std::chrono::steady_clock::now() + std::chrono::milliseconds(expiration))); } } ~Task() override = default; void run() override { if (state_ == EXECUTING) { runnable_->run(); state_ = COMPLETE; } } shared_ptr getRunnable() { return runnable_; } const unique_ptr & getExpireTime() const { return expireTime_; } private: shared_ptr runnable_; friend class ThreadManager::Worker; STATE state_; unique_ptr expireTime_; }; class ThreadManager::Worker : public Runnable { enum STATE { UNINITIALIZED, STARTING, STARTED, STOPPING, STOPPED }; public: Worker(ThreadManager::Impl* manager) : manager_(manager), state_(UNINITIALIZED) {} ~Worker() override = default; private: bool isActive() const { return (manager_->workerCount_ <= manager_->workerMaxCount_) || (manager_->state_ == JOINING && !manager_->tasks_.empty()); } public: /** * Worker entry point * * As long as worker thread is running, pull tasks off the task queue and * execute. */ void run() override { Guard g(manager_->mutex_); /** * This method has three parts; one is to check for and account for * admitting a task which happens under a lock. Then the lock is released * and the task itself is executed. Finally we do some accounting * under lock again when the task completes. */ /** * Admitting */ /** * Increment worker semaphore and notify manager if worker count reached * desired max */ bool active = manager_->workerCount_ < manager_->workerMaxCount_; if (active) { if (++manager_->workerCount_ == manager_->workerMaxCount_) { manager_->workerMonitor_.notify(); } } while (active) { /** * While holding manager monitor block for non-empty task queue (Also * check that the thread hasn't been requested to stop). Once the queue * is non-empty, dequeue a task, release monitor, and execute. If the * worker max count has been decremented such that we exceed it, mark * ourself inactive, decrement the worker count and notify the manager * (technically we're notifying the next blocked thread but eventually * the manager will see it. */ active = isActive(); while (active && manager_->tasks_.empty()) { manager_->idleCount_++; manager_->monitor_.wait(); active = isActive(); manager_->idleCount_--; } shared_ptr task; if (active) { if (!manager_->tasks_.empty()) { task = manager_->tasks_.front(); manager_->tasks_.pop_front(); if (task->state_ == ThreadManager::Task::WAITING) { // If the state is changed to anything other than EXECUTING or TIMEDOUT here // then the execution loop needs to be changed below. task->state_ = (task->getExpireTime() && *(task->getExpireTime()) < std::chrono::steady_clock::now()) ? ThreadManager::Task::TIMEDOUT : ThreadManager::Task::EXECUTING; } } /* If we have a pending task max and we just dropped below it, wakeup any thread that might be blocked on add. */ if (manager_->pendingTaskCountMax_ != 0 && manager_->tasks_.size() <= manager_->pendingTaskCountMax_ - 1) { manager_->maxMonitor_.notify(); } } /** * Execution - not holding a lock */ if (task) { if (task->state_ == ThreadManager::Task::EXECUTING) { // Release the lock so we can run the task without blocking the thread manager manager_->mutex_.unlock(); try { task->run(); } catch (const std::exception& e) { TOutput::instance().printf("[ERROR] task->run() raised an exception: %s", e.what()); } catch (...) { TOutput::instance().printf("[ERROR] task->run() raised an unknown exception"); } // Re-acquire the lock to proceed in the thread manager manager_->mutex_.lock(); } else if (manager_->expireCallback_) { // The only other state the task could have been in is TIMEDOUT (see above) manager_->mutex_.unlock(); manager_->expireCallback_(task->getRunnable()); manager_->mutex_.lock(); manager_->expiredCount_++; } } } /** * Final accounting for the worker thread that is done working */ manager_->deadWorkers_.insert(this->thread()); if (--manager_->workerCount_ == manager_->workerMaxCount_) { manager_->workerMonitor_.notify(); } } private: ThreadManager::Impl* manager_; friend class ThreadManager::Impl; STATE state_; }; void ThreadManager::Impl::addWorker(size_t value) { std::set > newThreads; for (size_t ix = 0; ix < value; ix++) { shared_ptr worker = std::make_shared(this); newThreads.insert(threadFactory_->newThread(worker)); } Guard g(mutex_); workerMaxCount_ += value; workers_.insert(newThreads.begin(), newThreads.end()); for (const auto & newThread : newThreads) { shared_ptr worker = dynamic_pointer_cast(newThread->runnable()); worker->state_ = ThreadManager::Worker::STARTING; newThread->start(); idMap_.insert(std::pair >(newThread->getId(), newThread)); } while (workerCount_ != workerMaxCount_) { workerMonitor_.wait(); } } void ThreadManager::Impl::start() { Guard g(mutex_); if (state_ == ThreadManager::STOPPED) { return; } if (state_ == ThreadManager::UNINITIALIZED) { if (!threadFactory_) { throw InvalidArgumentException(); } state_ = ThreadManager::STARTED; monitor_.notifyAll(); } while (state_ == STARTING) { monitor_.wait(); } } void ThreadManager::Impl::stop() { Guard g(mutex_); bool doStop = false; if (state_ != ThreadManager::STOPPING && state_ != ThreadManager::JOINING && state_ != ThreadManager::STOPPED) { doStop = true; state_ = ThreadManager::JOINING; } if (doStop) { removeWorkersUnderLock(workerCount_); } state_ = ThreadManager::STOPPED; } void ThreadManager::Impl::removeWorker(size_t value) { Guard g(mutex_); removeWorkersUnderLock(value); } void ThreadManager::Impl::removeWorkersUnderLock(size_t value) { if (value > workerMaxCount_) { throw InvalidArgumentException(); } workerMaxCount_ -= value; if (idleCount_ > value) { // There are more idle workers than we need to remove, // so notify enough of them so they can terminate. for (size_t ix = 0; ix < value; ix++) { monitor_.notify(); } } else { // There are as many or less idle workers than we need to remove, // so just notify them all so they can terminate. monitor_.notifyAll(); } while (workerCount_ != workerMaxCount_) { workerMonitor_.wait(); } for (const auto & deadWorker : deadWorkers_) { // when used with a joinable thread factory, we join the threads as we remove them if (!threadFactory_->isDetached()) { deadWorker->join(); } idMap_.erase(deadWorker->getId()); workers_.erase(deadWorker); } deadWorkers_.clear(); } bool ThreadManager::Impl::canSleep() const { const Thread::id_t id = threadFactory_->getCurrentThreadId(); return idMap_.find(id) == idMap_.end(); } void ThreadManager::Impl::add(shared_ptr value, int64_t timeout, int64_t expiration) { Guard g(mutex_, timeout); if (!g) { throw TimedOutException(); } if (state_ != ThreadManager::STARTED) { throw IllegalStateException( "ThreadManager::Impl::add ThreadManager " "not started"); } // if we're at a limit, remove an expired task to see if the limit clears if (pendingTaskCountMax_ > 0 && (tasks_.size() >= pendingTaskCountMax_)) { removeExpired(true); } if (pendingTaskCountMax_ > 0 && (tasks_.size() >= pendingTaskCountMax_)) { if (canSleep() && timeout >= 0) { while (pendingTaskCountMax_ > 0 && tasks_.size() >= pendingTaskCountMax_) { // This is thread safe because the mutex is shared between monitors. maxMonitor_.wait(timeout); } } else { throw TooManyPendingTasksException(); } } tasks_.push_back(std::make_shared(value, expiration)); // If idle thread is available notify it, otherwise all worker threads are // running and will get around to this task in time. if (idleCount_ > 0) { monitor_.notify(); } } void ThreadManager::Impl::remove(shared_ptr task) { Guard g(mutex_); if (state_ != ThreadManager::STARTED) { throw IllegalStateException( "ThreadManager::Impl::remove ThreadManager not " "started"); } for (auto it = tasks_.begin(); it != tasks_.end(); ++it) { if ((*it)->getRunnable() == task) { tasks_.erase(it); return; } } } std::shared_ptr ThreadManager::Impl::removeNextPending() { Guard g(mutex_); if (state_ != ThreadManager::STARTED) { throw IllegalStateException( "ThreadManager::Impl::removeNextPending " "ThreadManager not started"); } if (tasks_.empty()) { return std::shared_ptr(); } shared_ptr task = tasks_.front(); tasks_.pop_front(); return task->getRunnable(); } void ThreadManager::Impl::removeExpired(bool justOne) { // this is always called under a lock if (tasks_.empty()) { return; } auto now = std::chrono::steady_clock::now(); for (auto it = tasks_.begin(); it != tasks_.end(); ) { if ((*it)->getExpireTime() && *((*it)->getExpireTime()) < now) { if (expireCallback_) { expireCallback_((*it)->getRunnable()); } it = tasks_.erase(it); ++expiredCount_; if (justOne) { return; } } else { ++it; } } } void ThreadManager::Impl::setExpireCallback(ExpireCallback expireCallback) { Guard g(mutex_); expireCallback_ = expireCallback; } class SimpleThreadManager : public ThreadManager::Impl { public: SimpleThreadManager(size_t workerCount = 4, size_t pendingTaskCountMax = 0) : workerCount_(workerCount), pendingTaskCountMax_(pendingTaskCountMax) {} void start() override { ThreadManager::Impl::pendingTaskCountMax(pendingTaskCountMax_); ThreadManager::Impl::start(); addWorker(workerCount_); } private: const size_t workerCount_; const size_t pendingTaskCountMax_; }; shared_ptr ThreadManager::newThreadManager() { return shared_ptr(new ThreadManager::Impl()); } shared_ptr ThreadManager::newSimpleThreadManager(size_t count, size_t pendingTaskCountMax) { return shared_ptr(new SimpleThreadManager(count, pendingTaskCountMax)); } } } } // apache::thrift::concurrency thrift-0.23.0/lib/cpp/src/thrift/concurrency/TimerManager.h0000664000175000017500000001053715165535636024100 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_TIMERMANAGER_H_ #define _THRIFT_CONCURRENCY_TIMERMANAGER_H_ 1 #include #include #include #include namespace apache { namespace thrift { namespace concurrency { /** * Timer Manager * * This class dispatches timer tasks when they fall due. * * @version $Id:$ */ class TimerManager { public: class Task; typedef std::weak_ptr Timer; TimerManager(); virtual ~TimerManager(); virtual std::shared_ptr threadFactory() const; virtual void threadFactory(std::shared_ptr value); /** * Starts the timer manager service * * @throws IllegalArgumentException Missing thread factory attribute */ virtual void start(); /** * Stops the timer manager service */ virtual void stop(); virtual size_t taskCount() const; /** * Adds a task to be executed at some time in the future by a worker thread. * * @param task The task to execute * @param timeout Time in milliseconds to delay before executing task * @return Handle of the timer, which can be used to remove the timer. */ virtual Timer add(std::shared_ptr task, const std::chrono::milliseconds &timeout); Timer add(std::shared_ptr task, uint64_t timeout) { return add(task,std::chrono::milliseconds(timeout)); } /** * Adds a task to be executed at some time in the future by a worker thread. * * @param task The task to execute * @param abstime Absolute time in the future to execute task. * @return Handle of the timer, which can be used to remove the timer. */ virtual Timer add(std::shared_ptr task, const std::chrono::time_point& abstime); /** * Removes a pending task * * @param task The task to remove. All timers which execute this task will * be removed. * @throws NoSuchTaskException Specified task doesn't exist. It was either * processed already or this call was made for a * task that was never added to this timer * * @throws UncancellableTaskException Specified task is already being * executed or has completed execution. */ virtual void remove(std::shared_ptr task); /** * Removes a single pending task * * @param timer The timer to remove. The timer is returned when calling the * add() method. * @throws NoSuchTaskException Specified task doesn't exist. It was either * processed already or this call was made for a * task that was never added to this timer * * @throws UncancellableTaskException Specified task is already being * executed or has completed execution. */ virtual void remove(Timer timer); enum STATE { UNINITIALIZED, STARTING, STARTED, STOPPING, STOPPED }; virtual STATE state() const; private: std::shared_ptr threadFactory_; friend class Task; std::multimap, std::shared_ptr > taskMap_; size_t taskCount_; Monitor monitor_; STATE state_; class Dispatcher; friend class Dispatcher; std::shared_ptr dispatcher_; std::shared_ptr dispatcherThread_; using task_iterator = decltype(taskMap_)::iterator; typedef std::pair task_range; }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_TIMERMANAGER_H_ thrift-0.23.0/lib/cpp/src/thrift/concurrency/Exception.h0000664000175000017500000000414615165535636023462 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_EXCEPTION_H_ #define _THRIFT_CONCURRENCY_EXCEPTION_H_ 1 #include #include namespace apache { namespace thrift { namespace concurrency { class NoSuchTaskException : public apache::thrift::TException {}; class UncancellableTaskException : public apache::thrift::TException {}; class InvalidArgumentException : public apache::thrift::TException {}; class IllegalStateException : public apache::thrift::TException { public: IllegalStateException() = default; IllegalStateException(const std::string& message) : TException(message) {} }; class TimedOutException : public apache::thrift::TException { public: TimedOutException() : TException("TimedOutException"){}; TimedOutException(const std::string& message) : TException(message) {} }; class TooManyPendingTasksException : public apache::thrift::TException { public: TooManyPendingTasksException() : TException("TooManyPendingTasksException"){}; TooManyPendingTasksException(const std::string& message) : TException(message) {} }; class SystemResourceException : public apache::thrift::TException { public: SystemResourceException() = default; SystemResourceException(const std::string& message) : TException(message) {} }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_EXCEPTION_H_ thrift-0.23.0/lib/cpp/src/thrift/concurrency/ThreadFactory.cpp0000664000175000017500000000245715165535636024621 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace concurrency { std::shared_ptr ThreadFactory::newThread(std::shared_ptr runnable) const { std::shared_ptr result = std::make_shared(isDetached(), runnable); runnable->thread(result); return result; } Thread::id_t ThreadFactory::getCurrentThreadId() const { return std::this_thread::get_id(); } } } } // apache::thrift::concurrency thrift-0.23.0/lib/cpp/src/thrift/concurrency/Thread.cpp0000664000175000017500000000222615165535636023263 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace concurrency { void Thread::threadMain(std::shared_ptr thread) { thread->setState(started); thread->runnable()->run(); if (thread->getState() != stopping && thread->getState() != stopped) { thread->setState(stopping); } } } } } // apache::thrift::concurrency thrift-0.23.0/lib/cpp/src/thrift/concurrency/TimerManager.cpp0000664000175000017500000002040015165535636024421 0ustar00buildbuild00000000000000/* * 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 #include namespace apache { namespace thrift { namespace concurrency { using std::shared_ptr; using std::weak_ptr; /** * TimerManager class * * @version $Id:$ */ class TimerManager::Task : public Runnable { public: enum STATE { WAITING, EXECUTING, CANCELLED, COMPLETE }; Task(shared_ptr runnable) : runnable_(runnable), state_(WAITING) {} ~Task() override = default; void run() override { if (state_ == EXECUTING) { runnable_->run(); state_ = COMPLETE; } } bool operator==(const shared_ptr & runnable) const { return runnable_ == runnable; } task_iterator it_; private: shared_ptr runnable_; friend class TimerManager::Dispatcher; STATE state_; }; class TimerManager::Dispatcher : public Runnable { public: Dispatcher(TimerManager* manager) : manager_(manager) {} ~Dispatcher() override = default; /** * Dispatcher entry point * * As long as dispatcher thread is running, pull tasks off the task taskMap_ * and execute. */ void run() override { { Synchronized s(manager_->monitor_); if (manager_->state_ == TimerManager::STARTING) { manager_->state_ = TimerManager::STARTED; manager_->monitor_.notifyAll(); } } do { std::set > expiredTasks; { Synchronized s(manager_->monitor_); task_iterator expiredTaskEnd; auto now = std::chrono::steady_clock::now(); while (manager_->state_ == TimerManager::STARTED && (expiredTaskEnd = manager_->taskMap_.upper_bound(now)) == manager_->taskMap_.begin()) { std::chrono::milliseconds timeout(0); if (!manager_->taskMap_.empty()) { timeout = std::chrono::duration_cast(manager_->taskMap_.begin()->first - now); //because the unit of steady_clock is smaller than millisecond,timeout may be 0. if (timeout.count() == 0) { timeout = std::chrono::milliseconds(1); } manager_->monitor_.waitForTimeRelative(timeout); } else { manager_->monitor_.waitForTimeRelative(0); } now = std::chrono::steady_clock::now(); } if (manager_->state_ == TimerManager::STARTED) { for (auto ix = manager_->taskMap_.begin(); ix != expiredTaskEnd; ix++) { shared_ptr task = ix->second; expiredTasks.insert(task); task->it_ = manager_->taskMap_.end(); if (task->state_ == TimerManager::Task::WAITING) { task->state_ = TimerManager::Task::EXECUTING; } manager_->taskCount_--; } manager_->taskMap_.erase(manager_->taskMap_.begin(), expiredTaskEnd); } } for (const auto & expiredTask : expiredTasks) { expiredTask->run(); } } while (manager_->state_ == TimerManager::STARTED); { Synchronized s(manager_->monitor_); if (manager_->state_ == TimerManager::STOPPING) { manager_->state_ = TimerManager::STOPPED; manager_->monitor_.notifyAll(); } } return; } private: TimerManager* manager_; friend class TimerManager; }; #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4355) // 'this' used in base member initializer list #endif TimerManager::TimerManager() : taskCount_(0), state_(TimerManager::UNINITIALIZED), dispatcher_(std::make_shared(this)) { } #if defined(_MSC_VER) #pragma warning(pop) #endif TimerManager::~TimerManager() { // If we haven't been explicitly stopped, do so now. We don't need to grab // the monitor here, since stop already takes care of reentrancy. if (state_ != STOPPED) { try { stop(); } catch (...) { // We're really hosed. } } } void TimerManager::start() { bool doStart = false; { Synchronized s(monitor_); if (!threadFactory_) { throw InvalidArgumentException(); } if (state_ == TimerManager::UNINITIALIZED) { state_ = TimerManager::STARTING; doStart = true; } } if (doStart) { dispatcherThread_ = threadFactory_->newThread(dispatcher_); dispatcherThread_->start(); } { Synchronized s(monitor_); while (state_ == TimerManager::STARTING) { monitor_.wait(); } assert(state_ != TimerManager::STARTING); } } void TimerManager::stop() { bool doStop = false; { Synchronized s(monitor_); if (state_ == TimerManager::UNINITIALIZED) { state_ = TimerManager::STOPPED; } else if (state_ != STOPPING && state_ != STOPPED) { doStop = true; state_ = STOPPING; monitor_.notifyAll(); } while (state_ != STOPPED) { monitor_.wait(); } } if (doStop) { // Clean up any outstanding tasks taskMap_.clear(); // Remove dispatcher's reference to us. dispatcher_->manager_ = nullptr; } } shared_ptr TimerManager::threadFactory() const { Synchronized s(monitor_); return threadFactory_; } void TimerManager::threadFactory(shared_ptr value) { Synchronized s(monitor_); threadFactory_ = value; } size_t TimerManager::taskCount() const { return taskCount_; } TimerManager::Timer TimerManager::add(shared_ptr task, const std::chrono::milliseconds &timeout) { return add(task, std::chrono::steady_clock::now() + timeout); } TimerManager::Timer TimerManager::add(shared_ptr task, const std::chrono::time_point& abstime) { auto now = std::chrono::steady_clock::now(); if (abstime < now) { throw InvalidArgumentException(); } Synchronized s(monitor_); if (state_ != TimerManager::STARTED) { throw IllegalStateException(); } // If the task map is empty, we will kick the dispatcher for sure. Otherwise, we kick him // if the expiration time is shorter than the current value. Need to test before we insert, // because the new task might insert at the front. bool notifyRequired = (taskCount_ == 0) ? true : abstime < taskMap_.begin()->first; shared_ptr timer(new Task(task)); taskCount_++; timer->it_ = taskMap_.emplace(abstime, timer); // If the task map was empty, or if we have an expiration that is earlier // than any previously seen, kick the dispatcher so it can update its // timeout if (notifyRequired) { monitor_.notify(); } return timer; } void TimerManager::remove(shared_ptr task) { Synchronized s(monitor_); if (state_ != TimerManager::STARTED) { throw IllegalStateException(); } bool found = false; for (auto ix = taskMap_.begin(); ix != taskMap_.end();) { if (*ix->second == task) { found = true; taskCount_--; taskMap_.erase(ix++); } else { ++ix; } } if (!found) { throw NoSuchTaskException(); } } void TimerManager::remove(Timer handle) { Synchronized s(monitor_); if (state_ != TimerManager::STARTED) { throw IllegalStateException(); } shared_ptr task = handle.lock(); if (!task) { throw NoSuchTaskException(); } if (task->it_ == taskMap_.end()) { // Task is being executed throw UncancellableTaskException(); } taskMap_.erase(task->it_); taskCount_--; } TimerManager::STATE TimerManager::state() const { return state_; } } } } // apache::thrift::concurrency thrift-0.23.0/lib/cpp/src/thrift/concurrency/FunctionRunner.h0000664000175000017500000000733215165535636024503 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H #define _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H 1 #include #include #include namespace apache { namespace thrift { namespace concurrency { /** * Convenient implementation of Runnable that will execute arbitrary callbacks. * Interfaces are provided to accept both a generic 'void(void)' callback, and * a 'void* (void*)' pthread_create-style callback. * * Example use: * void* my_thread_main(void* arg); * shared_ptr factory = ...; * // To create a thread that executes my_thread_main once: * shared_ptr thread = factory->newThread( * FunctionRunner::create(my_thread_main, some_argument)); * thread->start(); * * bool A::foo(); * A* a = new A(); * // To create a thread that executes a.foo() every 100 milliseconds: * factory->newThread(FunctionRunner::create( * std::bind(&A::foo, a), 100))->start(); * */ class FunctionRunner : public Runnable { public: // This is the type of callback 'pthread_create()' expects. typedef void* (*PthreadFuncPtr)(void* arg); // This a fully-generic void(void) callback for custom bindings. typedef std::function VoidFunc; typedef std::function BoolFunc; /** * Syntactic sugar to make it easier to create new FunctionRunner * objects wrapped in shared_ptr. */ static std::shared_ptr create(const VoidFunc& cob) { return std::shared_ptr(new FunctionRunner(cob)); } static std::shared_ptr create(PthreadFuncPtr func, void* arg) { return std::shared_ptr(new FunctionRunner(func, arg)); } private: static void pthread_func_wrapper(PthreadFuncPtr func, void* arg) { // discard return value func(arg); } public: /** * Given a 'pthread_create' style callback, this FunctionRunner will * execute the given callback. Note that the 'void*' return value is ignored. */ FunctionRunner(PthreadFuncPtr func, void* arg) : func_(std::bind(pthread_func_wrapper, func, arg)), intervalMs_(-1) {} /** * Given a generic callback, this FunctionRunner will execute it. */ FunctionRunner(const VoidFunc& cob) : func_(cob), intervalMs_(-1) {} /** * Given a bool foo(...) type callback, FunctionRunner will execute * the callback repeatedly with 'intervalMs' milliseconds between the calls, * until it returns false. Note that the actual interval between calls will * be intervalMs plus execution time of the callback. */ FunctionRunner(const BoolFunc& cob, int intervalMs) : repFunc_(cob), intervalMs_(intervalMs) {} void run() override { if (repFunc_) { while (repFunc_()) { THRIFT_SLEEP_USEC(intervalMs_ * 1000); } } else { func_(); } } private: VoidFunc func_; BoolFunc repFunc_; int intervalMs_; }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H thrift-0.23.0/lib/cpp/src/thrift/concurrency/Monitor.cpp0000664000175000017500000001262715165535636023511 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include namespace apache { namespace thrift { namespace concurrency { /** * Monitor implementation using the std thread library * * @version $Id:$ */ class Monitor::Impl { public: Impl() : ownedMutex_(new Mutex()), conditionVariable_(), mutex_(nullptr) { init(ownedMutex_.get()); } Impl(Mutex* mutex) : ownedMutex_(), conditionVariable_(), mutex_(nullptr) { init(mutex); } Impl(Monitor* monitor) : ownedMutex_(), conditionVariable_(), mutex_(nullptr) { init(&(monitor->mutex())); } Mutex& mutex() { return *mutex_; } void lock() { mutex_->lock(); } void unlock() { mutex_->unlock(); } /** * Exception-throwing version of waitForTimeRelative(), called simply * wait(int64) for historical reasons. Timeout is in milliseconds. * * If the condition occurs, this function returns cleanly; on timeout or * error an exception is thrown. */ void wait(const std::chrono::milliseconds &timeout) { int result = waitForTimeRelative(timeout); if (result == THRIFT_ETIMEDOUT) { throw TimedOutException(); } else if (result != 0) { throw TException("Monitor::wait() failed"); } } /** * Waits until the specified timeout in milliseconds for the condition to * occur, or waits forever if timeout is zero. * * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code. */ int waitForTimeRelative(const std::chrono::milliseconds &timeout) { if (timeout.count() == 0) { return waitForever(); } assert(mutex_); auto* mutexImpl = static_cast(mutex_->getUnderlyingImpl()); assert(mutexImpl); std::unique_lock lock(*mutexImpl, std::adopt_lock); bool timedout = (conditionVariable_.wait_for(lock, timeout) == std::cv_status::timeout); lock.release(); return (timedout ? THRIFT_ETIMEDOUT : 0); } /** * Waits until the absolute time specified by abstime. * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code. */ int waitForTime(const std::chrono::time_point& abstime) { assert(mutex_); auto* mutexImpl = static_cast(mutex_->getUnderlyingImpl()); assert(mutexImpl); std::unique_lock lock(*mutexImpl, std::adopt_lock); bool timedout = (conditionVariable_.wait_until(lock, abstime) == std::cv_status::timeout); lock.release(); return (timedout ? THRIFT_ETIMEDOUT : 0); } /** * Waits forever until the condition occurs. * Returns 0 if condition occurs, or an error code otherwise. */ int waitForever() { assert(mutex_); auto* mutexImpl = static_cast(mutex_->getUnderlyingImpl()); assert(mutexImpl); std::unique_lock lock(*mutexImpl, std::adopt_lock); conditionVariable_.wait(lock); lock.release(); return 0; } void notify() { conditionVariable_.notify_one(); } void notifyAll() { conditionVariable_.notify_all(); } private: void init(Mutex* mutex) { mutex_ = mutex; } const std::unique_ptr ownedMutex_; std::condition_variable_any conditionVariable_; Mutex* mutex_; }; Monitor::Monitor() : impl_(new Monitor::Impl()) { } Monitor::Monitor(Mutex* mutex) : impl_(new Monitor::Impl(mutex)) { } Monitor::Monitor(Monitor* monitor) : impl_(new Monitor::Impl(monitor)) { } Monitor::~Monitor() { delete impl_; } Mutex& Monitor::mutex() const { return const_cast(impl_)->mutex(); } void Monitor::lock() const { const_cast(impl_)->lock(); } void Monitor::unlock() const { const_cast(impl_)->unlock(); } void Monitor::wait(const std::chrono::milliseconds &timeout) const { const_cast(impl_)->wait(timeout); } int Monitor::waitForTime(const std::chrono::time_point& abstime) const { return const_cast(impl_)->waitForTime(abstime); } int Monitor::waitForTimeRelative(const std::chrono::milliseconds &timeout) const { return const_cast(impl_)->waitForTimeRelative(timeout); } int Monitor::waitForever() const { return const_cast(impl_)->waitForever(); } void Monitor::notify() const { const_cast(impl_)->notify(); } void Monitor::notifyAll() const { const_cast(impl_)->notifyAll(); } } } } // apache::thrift::concurrency thrift-0.23.0/lib/cpp/src/thrift/concurrency/ThreadFactory.h0000664000175000017500000000420615165535636024260 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_THREADFACTORY_H_ #define _THRIFT_CONCURRENCY_THREADFACTORY_H_ 1 #include #include namespace apache { namespace thrift { namespace concurrency { /** * Factory to create thread object and bind them to Runnable * object for execution */ class ThreadFactory { public: /** * All threads created by a factory are reference-counted * via std::shared_ptr. The factory guarantees that threads and the Runnable tasks * they host will be properly cleaned up once the last strong reference * to both is given up. * * By default threads are not joinable. */ ThreadFactory(bool detached = true) : detached_(detached) { } virtual ~ThreadFactory() = default; /** * Gets current detached mode */ bool isDetached() const { return detached_; } /** * Sets the detached disposition of newly created threads. */ void setDetached(bool detached) { detached_ = detached; } /** * Create a new thread. */ virtual std::shared_ptr newThread(std::shared_ptr runnable) const; /** * Gets the current thread id or unknown_thread_id if the current thread is not a thrift thread */ Thread::id_t getCurrentThreadId() const; private: bool detached_; }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_THREADFACTORY_H_ thrift-0.23.0/lib/cpp/src/thrift/concurrency/Thread.h0000664000175000017500000001153215165535636022730 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_THREAD_H_ #define _THRIFT_CONCURRENCY_THREAD_H_ 1 #include #include #include namespace apache { namespace thrift { namespace concurrency { class Thread; /** * Minimal runnable class. More or less analogous to java.lang.Runnable. * * @version $Id:$ */ class Runnable { public: virtual ~Runnable() = default; virtual void run() = 0; /** * Gets the thread object that is hosting this runnable object - can return * an empty boost::shared pointer if no references remain on that thread object */ virtual std::shared_ptr thread() { return thread_.lock(); } /** * Sets the thread that is executing this object. This is only meant for * use by concrete implementations of Thread. */ virtual void thread(std::shared_ptr value) { thread_ = value; } private: std::weak_ptr thread_; }; /** * Minimal thread class. Returned by thread factory bound to a Runnable object * and ready to start execution. More or less analogous to java.lang.Thread * (minus all the thread group, priority, mode and other baggage, since that * is difficult to abstract across platforms and is left for platform-specific * ThreadFactory implementations to deal with * * @see apache::thrift::concurrency::ThreadFactory) */ class Thread : public std::enable_shared_from_this { public: typedef std::thread::id id_t; typedef void (*thread_funct_t)(std::shared_ptr ); enum STATE { uninitialized, starting, started, stopping, stopped }; static void threadMain(std::shared_ptr thread); static inline bool is_current(id_t t) { return t == std::this_thread::get_id(); } static inline id_t get_current() { return std::this_thread::get_id(); } Thread(bool detached, std::shared_ptr runnable) : state_(uninitialized), detached_(detached) { this->_runnable = runnable; } virtual ~Thread() { if (!detached_ && thread_->joinable()) { try { join(); } catch (...) { // We're really hosed. } } } STATE getState() const { Synchronized sync(monitor_); return state_; } void setState(STATE newState) { Synchronized sync(monitor_); state_ = newState; // unblock start() with the knowledge that the thread has actually // started running, which avoids a race in detached threads. if (newState == started) { monitor_.notify(); } } /** * Starts the thread. Does platform specific thread creation and * configuration then invokes the run method of the Runnable object bound * to this thread. */ virtual void start() { if (getState() != uninitialized) { return; } std::shared_ptr selfRef = shared_from_this(); setState(starting); Synchronized sync(monitor_); thread_ = std::unique_ptr(new std::thread(getThreadFunc(), selfRef)); if (detached_) thread_->detach(); // Wait for the thread to start and get far enough to grab everything // that it needs from the calling context, thus absolving the caller // from being required to hold on to runnable indefinitely. monitor_.wait(); } /** * Join this thread. If this thread is joinable, the calling thread blocks * until this thread completes. If the target thread is not joinable, then * nothing happens. */ virtual void join() { if (!detached_ && state_ != uninitialized) { thread_->join(); } } /** * Gets the thread's platform-specific ID */ Thread::id_t getId() const { return thread_.get() ? thread_->get_id() : std::thread::id(); } /** * Gets the runnable object this thread is hosting */ std::shared_ptr runnable() const { return _runnable; } protected: virtual thread_funct_t getThreadFunc() const { return threadMain; } private: std::shared_ptr _runnable; std::unique_ptr thread_; Monitor monitor_; STATE state_; bool detached_; }; } } } // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_THREAD_H_ thrift-0.23.0/lib/cpp/src/thrift/windows/0000775000175000017500000000000015167543515020503 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/windows/SocketPair.cpp0000664000175000017500000000615515165535636023265 0ustar00buildbuild00000000000000/* socketpair.c * Copyright 2007 by Nathan C. Myers ; some rights reserved. * This code is Free Software. It may be copied freely, in original or * modified form, subject only to the restrictions that (1) the author is * relieved from all responsibilities for any use for any purpose, and (2) * this copyright notice must be retained, unchanged, in its entirety. If * for any reason the author might be held responsible for any consequences * of copying or use, license is withheld. */ /* * 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 // stl #include // Win32 #include int thrift_socketpair(int d, int type, int protocol, THRIFT_SOCKET sv[2]) { THRIFT_UNUSED_VARIABLE(protocol); THRIFT_UNUSED_VARIABLE(type); THRIFT_UNUSED_VARIABLE(d); union { struct sockaddr_in inaddr; struct sockaddr addr; } a; THRIFT_SOCKET listener; int e; socklen_t addrlen = sizeof(a.inaddr); DWORD flags = 0; int reuse = 1; if (sv == 0) { WSASetLastError(WSAEINVAL); return SOCKET_ERROR; } listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listener == INVALID_SOCKET) return SOCKET_ERROR; memset(&a, 0, sizeof(a)); a.inaddr.sin_family = AF_INET; a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); a.inaddr.sin_port = 0; sv[0] = sv[1] = INVALID_SOCKET; do { // ignore errors coming out of this setsockopt. This is because // SO_EXCLUSIVEADDRUSE requires admin privileges on WinXP, but we don't // want to force socket pairs to be an admin. setsockopt(listener, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&reuse, (socklen_t)sizeof(reuse)); if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) break; if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR) break; if (listen(listener, 1) == SOCKET_ERROR) break; sv[0] = WSASocket(AF_INET, SOCK_STREAM, 0, nullptr, 0, flags); if (sv[0] == INVALID_SOCKET) break; if (connect(sv[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) break; sv[1] = accept(listener, nullptr, nullptr); if (sv[1] == INVALID_SOCKET) break; closesocket(listener); return 0; } while (0); e = WSAGetLastError(); closesocket(listener); closesocket(sv[0]); closesocket(sv[1]); WSASetLastError(e); return SOCKET_ERROR; } thrift-0.23.0/lib/cpp/src/thrift/windows/WinFcntl.cpp0000664000175000017500000000263215165535636022741 0ustar00buildbuild00000000000000/* * 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 int thrift_fcntl(THRIFT_SOCKET fd, int cmd, int flags) { if (cmd != THRIFT_F_GETFL && cmd != THRIFT_F_SETFL) { return -1; } if (flags != THRIFT_O_NONBLOCK && flags != 0) { return -1; } if (cmd == THRIFT_F_GETFL) { return 0; } int res; if (flags) { res = ioctlsocket(fd, FIONBIO, reinterpret_cast(&(flags = 1))); } else { res = ioctlsocket(fd, FIONBIO, reinterpret_cast(&(flags = 0))); } return res; } #ifdef _WIN32_WCE std::string thrift_wstr2str(std::wstring ws) { std::string s(ws.begin(), ws.end()); return s; } #endif thrift-0.23.0/lib/cpp/src/thrift/windows/config.h0000664000175000017500000000501015167543515022115 0ustar00buildbuild00000000000000/* * 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_WINDOWS_CONFIG_H_ #define _THRIFT_WINDOWS_CONFIG_H_ 1 #if defined(_MSC_VER) && (_MSC_VER > 1200) #pragma once #endif // _MSC_VER #ifndef _WIN32 #error "This is a Windows header only" #endif // Something that defines PRId64 is required to build #define HAVE_INTTYPES_H 1 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0601 #endif #if defined(_M_IX86) || defined(_M_X64) #define ARITHMETIC_RIGHT_SHIFT 1 #define SIGNED_RIGHT_SHIFT_IS 1 #endif #ifndef __MINGW32__ #pragma warning(disable : 4996) // Deprecated posix name. #endif #define HAVE_GETTIMEOFDAY 1 #define HAVE_SYS_STAT_H 1 #include #include #include #include #include #include // windows #include #include #ifndef __MINGW32__ #ifdef _WIN32_WCE #pragma comment(lib, "Ws2.lib") #else #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "gdi32.lib") // For static OpenSSL #pragma comment(lib, "crypt32.lib") // For static OpenSSL #pragma comment(lib, "user32.lib") // For static OpenSSL #pragma comment(lib, "advapi32.lib") // For security APIs in TPipeServer #pragma comment(lib, "Shlwapi.lib") // For StrStrIA in TPipeServer #endif #endif // __MINGW32__ // Replicate the logic of afunix.h on Windows (the header is only present on // newer Windows SDKs) #ifdef HAVE_AF_UNIX_H #include #else #ifndef UNIX_PATH_MAX #define UNIX_PATH_MAX 108 #endif typedef struct sockaddr_un { ADDRESS_FAMILY sun_family; // AF_UNIX char sun_path[UNIX_PATH_MAX]; // pathname } SOCKADDR_UN, *PSOCKADDR_UN; #endif // HAVE_AF_UNIX_H #endif // _THRIFT_WINDOWS_CONFIG_H_ thrift-0.23.0/lib/cpp/src/thrift/windows/Sync.h0000664000175000017500000000671015167543515021574 0ustar00buildbuild00000000000000/* * 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_WINDOWS_Sync_H_ #define _THRIFT_WINDOWS_Sync_H_ 1 #ifndef _WIN32 #error "windows/Sync.h is only usable on Windows" #endif #include #include // Including Windows.h can conflict with Winsock2 usage, and also // adds problematic macros like min() and max(). Try to work around: #ifndef NOMINMAX #define NOMINMAX #define _THRIFT_UNDEF_NOMINMAX #endif #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #define _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #endif #include #ifdef _THRIFT_UNDEF_NOMINMAX #undef NOMINMAX #undef _THRIFT_UNDEF_NOMINMAX #endif #ifdef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN #undef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #endif /* Lightweight synchronization objects that only make sense on Windows. For cross-platform code, use the classes found in the concurrency namespace */ namespace apache { namespace thrift { struct TCriticalSection : apache::thrift::TNonCopyable { CRITICAL_SECTION cs; TCriticalSection() { InitializeCriticalSection(&cs); } virtual ~TCriticalSection() { DeleteCriticalSection(&cs); } }; class TAutoCrit : apache::thrift::TNonCopyable { private: CRITICAL_SECTION* cs_; public: explicit TAutoCrit(TCriticalSection& cs) : cs_(&cs.cs) { EnterCriticalSection(cs_); } virtual ~TAutoCrit() { LeaveCriticalSection(cs_); } }; struct TAutoResetEvent : apache::thrift::TNonCopyable { HANDLE h; TAutoResetEvent() { h = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (h == nullptr) { TOutput::instance().perror("TAutoResetEvent unable to create event, GLE=", GetLastError()); throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed"); } } virtual ~TAutoResetEvent() { CloseHandle(h); } }; struct TManualResetEvent : apache::thrift::TNonCopyable { HANDLE h; TManualResetEvent() { h = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (h == nullptr) { TOutput::instance().perror("TManualResetEvent unable to create event, GLE=", GetLastError()); throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed"); } } virtual ~TManualResetEvent() { CloseHandle(h); } }; struct TAutoHandle : apache::thrift::TNonCopyable { HANDLE h; explicit TAutoHandle(HANDLE h_ = INVALID_HANDLE_VALUE) : h(h_) {} ~TAutoHandle() { if (h != INVALID_HANDLE_VALUE) CloseHandle(h); } HANDLE release() { HANDLE retval = h; h = INVALID_HANDLE_VALUE; return retval; } void reset(HANDLE h_ = INVALID_HANDLE_VALUE) { if (h_ == h) return; if (h != INVALID_HANDLE_VALUE) CloseHandle(h); h = h_; } }; } } // apache::thrift #endif thrift-0.23.0/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp0000664000175000017500000001101315167543515026510 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace transport { TOverlappedWorkItem::TOverlappedWorkItem() : SLIST_ENTRY(), action(UNKNOWN), h(INVALID_HANDLE_VALUE), buffer(NULL), buffer_len(0), overlap(), last_error(0), success(TRUE) { } void TOverlappedWorkItem::reset(uint8_t* buf, uint32_t len, HANDLE event) { memset(&overlap, 0, sizeof(overlap)); overlap.hEvent = event; buffer = buf; buffer_len = len; last_error = 0; success = FALSE; } uint32_t TOverlappedWorkItem::overlappedResults(bool signal_failure) { DWORD bytes = 0; BOOL result = ::GetOverlappedResult(h, &overlap, &bytes, TRUE); if (signal_failure && !result) // get overlapped error case { TOutput::instance().perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: GetOverlappedResult failed"); } return bytes; } bool TOverlappedWorkItem::process() { BOOST_SCOPE_EXIT((&doneSubmittingEvent)) { SetEvent(doneSubmittingEvent.h); } BOOST_SCOPE_EXIT_END switch (action) { case (CONNECT): success = ::ConnectNamedPipe(h, &overlap); if (success == FALSE) last_error = ::GetLastError(); return true; case (READ): success = ::ReadFile(h, buffer, buffer_len, NULL, &overlap); if (success == FALSE) last_error = ::GetLastError(); return true; case (CANCELIO): success = ::CancelIo(h); if (success == FALSE) last_error = ::GetLastError(); return true; case (STOP): default: return false; } } void TOverlappedSubmissionThread::addWorkItem(TOverlappedWorkItem* item) { InterlockedPushEntrySList(&workList_, item); SetEvent(workAvailableEvent_.h); WaitForSingleObject(item->doneSubmittingEvent.h, INFINITE); } TOverlappedSubmissionThread* TOverlappedSubmissionThread::acquire_instance() { TAutoCrit lock(instanceGuard_); if (instance_ == NULL) { assert(instanceRefCount_ == 0); instance_ = new TOverlappedSubmissionThread; } ++instanceRefCount_; return instance_; } void TOverlappedSubmissionThread::release_instance() { TAutoCrit lock(instanceGuard_); if (--instanceRefCount_ == 0) { delete instance_; instance_ = NULL; } } TOverlappedSubmissionThread::TOverlappedSubmissionThread() { stopItem_.action = TOverlappedWorkItem::STOP; InitializeSListHead(&workList_); thread_ = (HANDLE)_beginthreadex(NULL, 0, thread_proc, this, 0, NULL); if (thread_ == 0) { TOutput::instance().perror("TOverlappedSubmissionThread unable to create thread, errno=", errno); throw TTransportException(TTransportException::NOT_OPEN, " TOverlappedSubmissionThread unable to create thread"); } } TOverlappedSubmissionThread::~TOverlappedSubmissionThread() { addWorkItem(&stopItem_); ::WaitForSingleObject(thread_, INFINITE); CloseHandle(thread_); } void TOverlappedSubmissionThread::run() { for (;;) { WaitForSingleObject(workAvailableEvent_.h, INFINITE); // todo check result SLIST_ENTRY* entry = NULL; while ((entry = InterlockedPopEntrySList(&workList_)) != NULL) { TOverlappedWorkItem& item = *static_cast(entry); if (!item.process()) return; } } } unsigned __stdcall TOverlappedSubmissionThread::thread_proc(void* addr) { static_cast(addr)->run(); return 0; } TCriticalSection TOverlappedSubmissionThread::instanceGuard_; TOverlappedSubmissionThread* TOverlappedSubmissionThread::instance_; uint32_t TOverlappedSubmissionThread::instanceRefCount_ = 0; } } } // apach::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/windows/SocketPair.h0000664000175000017500000000226015165535636022723 0ustar00buildbuild00000000000000/* * 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_WINDOWS_SOCKETPAIR_H_ #define _THRIFT_WINDOWS_SOCKETPAIR_H_ 1 #if defined(_MSC_VER) && (_MSC_VER > 1200) #pragma once #endif // _MSC_VER #ifndef _WIN32 #error This is a MSVC header only. #endif // Win32 #include #include int thrift_socketpair(int d, int type, int protocol, THRIFT_SOCKET sv[2]); #endif // _THRIFT_WINDOWS_SOCKETPAIR_H_ thrift-0.23.0/lib/cpp/src/thrift/windows/GetTimeOfDay.h0000664000175000017500000000255715165535636023151 0ustar00buildbuild00000000000000/* * 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_WINDOWS_GETTIMEOFDAY_H_ #define _THRIFT_WINDOWS_GETTIMEOFDAY_H_ #if defined(_MSC_VER) && (_MSC_VER > 1200) #pragma once #endif // _MSC_VER #ifndef _WIN32 #error This is a MSVC header only. #endif #include #include struct thrift_timespec { int64_t tv_sec; int64_t tv_nsec; }; int thrift_gettimeofday(struct timeval* tv, struct timezone* tz); int thrift_sleep(unsigned int seconds); int thrift_usleep(unsigned int micro_seconds); char* thrift_ctime_r(const time_t* _clock, char* _buf); #endif // _THRIFT_WINDOWS_GETTIMEOFDAY_H_ thrift-0.23.0/lib/cpp/src/thrift/windows/Operators.h0000664000175000017500000000206715165535636022642 0ustar00buildbuild00000000000000/* * 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_WINDOWS_OPERATORS_H_ #define _THRIFT_WINDOWS_OPERATORS_H_ #if defined(_MSC_VER) && (_MSC_VER > 1200) #pragma once #endif // _MSC_VER namespace apache { namespace thrift { class TEnumIterator; } } // apache::thrift #endif // _THRIFT_WINDOWS_OPERATORS_H_ thrift-0.23.0/lib/cpp/src/thrift/windows/TWinsockSingleton.cpp0000664000175000017500000000352415165535636024642 0ustar00buildbuild00000000000000/* * 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 #include namespace apache { namespace thrift { namespace transport { TWinsockSingleton::instance_ptr TWinsockSingleton::instance_ptr_(nullptr); std::once_flag TWinsockSingleton::flags_; //------------------------------------------------------------------------------ TWinsockSingleton::TWinsockSingleton(void) { WORD version(MAKEWORD(2, 2)); WSAData data = {0}; int error(WSAStartup(version, &data)); if (error != 0) { throw std::runtime_error("Failed to initialise Winsock."); } } //------------------------------------------------------------------------------ TWinsockSingleton::~TWinsockSingleton(void) { WSACleanup(); } //------------------------------------------------------------------------------ void TWinsockSingleton::create(void) { std::call_once(flags_, init); } //------------------------------------------------------------------------------ void TWinsockSingleton::init(void) { instance_ptr_.reset(new TWinsockSingleton); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/windows/WinFcntl.h0000664000175000017500000000243415165535636022406 0ustar00buildbuild00000000000000/* * 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_WINDOWS_FCNTL_H_ #define _THRIFT_WINDOWS_FCNTL_H_ 1 #if defined(_MSC_VER) && (_MSC_VER > 1200) #pragma once #endif // _MSC_VER #ifndef _WIN32 #error This is a MSVC header only. #endif #ifdef _WIN32_WCE #include #endif // Win32 #include #include extern "C" { int thrift_fcntl(THRIFT_SOCKET fd, int cmd, int flags); } #ifdef _WIN32_WCE std::string thrift_wstr2str(std::wstring ws); #endif #endif // _THRIFT_WINDOWS_FCNTL_H_ thrift-0.23.0/lib/cpp/src/thrift/windows/GetTimeOfDay.cpp0000664000175000017500000000615215165535636023477 0ustar00buildbuild00000000000000/* * 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 // win32 #if defined(__MINGW32__) #include #endif #if !defined(__MINGW32__) struct timezone { int tz_minuteswest; /* minutes W of Greenwich */ int tz_dsttime; /* type of dst correction */ }; #endif #if defined(__MINGW32__) int thrift_gettimeofday(struct timeval* tv, struct timezone* tz) { return gettimeofday(tv,tz); } #else #define WIN32_LEAN_AND_MEAN #include #include #include #include // This code started from a "FREE implementation" posted to Stack Overflow at: // https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows // added: assert // added: error handling // added: C++ style casts int thrift_gettimeofday(struct timeval * tp, struct timezone * tzp) { // We don't fill it in so prove nobody is looking for the data assert(tzp == nullptr); // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC) // until 00:00:00 January 1, 1970 static const uint64_t EPOCH = static_cast(116444736000000000ULL); SYSTEMTIME system_time; FILETIME file_time; uint64_t time; GetSystemTime( &system_time ); if (!SystemTimeToFileTime( &system_time, &file_time )) { DWORD lastError = GetLastError(); std::stringstream ss; ss << "SystemTimeToFileTime failed: 0x" << std::hex << lastError; using apache::thrift::transport::TTransportException; throw TTransportException(TTransportException::INTERNAL_ERROR, ss.str()); } time = static_cast(file_time.dwLowDateTime ) ; time += static_cast(file_time.dwHighDateTime) << 32; tp->tv_sec = static_cast((time - EPOCH) / 10000000L); tp->tv_usec = static_cast(system_time.wMilliseconds * 1000); return 0; } #endif int thrift_sleep(unsigned int seconds) { ::Sleep(seconds * 1000); return 0; } int thrift_usleep(unsigned int microseconds) { unsigned int milliseconds = (microseconds + 999) / 1000; ::Sleep(milliseconds); return 0; } char* thrift_ctime_r(const time_t* _clock, char* _buf) { strcpy(_buf, ctime(_clock)); return _buf; } thrift-0.23.0/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h0000664000175000017500000001121315165535636026162 0ustar00buildbuild00000000000000/* * 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_WINDOWS_OverlappedSubmissionThread_H_ #define _THRIFT_WINDOWS_OverlappedSubmissionThread_H_ 1 #ifndef _WIN32 #error "OverlappedSubmissionThread.h is only usable on Windows" #endif #include #include /* *** Why does this class exist? In short, because we want to enable something similar to a "select" loop, on Windows, with named pipes. The core of the "select" loop is a call to WaitForMultipleObjects. So that means we need a signalable object that indicates when data is available. A pipe handle doesn't do that. A pipe handle is signaled when a read or write completes, and if no one has called read or write, then the pipe handle is useless in WaitForMultipleObjects. So instead, we use overlapped I/O. With overlapped I/O, you call read, and associate an event with the read. When the read finishes, the event is signaled. This means that when you create a pipe, you start a read. When the customer calls read on your transport object, you wait for the last read to finish, and then kick off another. There is one big caveat to this though. The thread that initiated the read must stay alive. If the thread that initiated the read exits, then the read completes in an error state. To ensure that the initiating thread stays alive, we create a singleton thread whose sole responsibility is to manage this overlapped I/O requests. This introduces some overhead, but it is overhead that is necessary for correct behavior. This thread currently supports connect, read, and cancel io. So far, I haven't needed to put any writes on this thread, but if needed, it could be done. The client write buffer would need to be copied to ensure that it doesn't get invalidated. *** How does one use this class? Create a TOverlappedWorkItem, and fill in the action and "h", then call reset(). Your work item is now ready to be submitted to the overlapped submission thread. Create a TAutoOverlapThread, and call thread->addWorkItem with your work item. After addWorkItem completes, you may inspect last_error and success. At some point in the future, call workItem.overlappedResults to wait until the operation has completed. */ namespace apache { namespace thrift { namespace transport { struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) TOverlappedWorkItem : public SLIST_ENTRY { TOverlappedWorkItem(); enum action_t { UNKNOWN = 3000, CONNECT, READ, CANCELIO, STOP, }; TAutoResetEvent doneSubmittingEvent; action_t action; HANDLE h; uint8_t* buffer; uint32_t buffer_len; OVERLAPPED overlap; DWORD last_error; BOOL success; void reset(uint8_t* buf, uint32_t len, HANDLE event); uint32_t overlappedResults(bool signal_failure = true); bool process(); }; class TOverlappedSubmissionThread : apache::thrift::TNonCopyable { public: void addWorkItem(TOverlappedWorkItem* item); // singleton stuff public: static TOverlappedSubmissionThread* acquire_instance(); static void release_instance(); private: static TCriticalSection instanceGuard_; static TOverlappedSubmissionThread* instance_; static uint32_t instanceRefCount_; // thread details private: TOverlappedSubmissionThread(); virtual ~TOverlappedSubmissionThread(); void run(); static unsigned __stdcall thread_proc(void* addr); private: DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) SLIST_HEADER workList_; TOverlappedWorkItem stopItem_; TAutoResetEvent workAvailableEvent_; HANDLE thread_; }; class TAutoOverlapThread : apache::thrift::TNonCopyable { private: TOverlappedSubmissionThread* p; public: TAutoOverlapThread() : p(TOverlappedSubmissionThread::acquire_instance()) {} virtual ~TAutoOverlapThread() { TOverlappedSubmissionThread::release_instance(); } TOverlappedSubmissionThread* operator->() { return p; } }; } } } // apache::thrift::transport #endif thrift-0.23.0/lib/cpp/src/thrift/windows/TWinsockSingleton.h0000664000175000017500000000346015165535636024306 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_WINDOWS_TWINSOCKSINGLETON_H_ #define _THRIFT_TRANSPORT_WINDOWS_TWINSOCKSINGLETON_H_ 1 #if defined(_MSC_VER) && (_MSC_VER > 1200) #pragma once #endif // _MSC_VER #ifndef _WIN32 #error This is a MSVC header only. #endif #include // boost #include #include #include namespace apache { namespace thrift { namespace transport { /** * Winsock2 must be intialised once only in order to create sockets. This class * performs a one time initialisation when create is called. */ class TWinsockSingleton : private apache::thrift::TNonCopyable { public: typedef std::shared_ptr instance_ptr; private: TWinsockSingleton(void); public: virtual ~TWinsockSingleton(void); public: static void create(void); private: static void init(void); private: static instance_ptr instance_ptr_; static std::once_flag flags_; }; } } } // apache::thrift::transport #endif // _THRIFT_TRANSPORT_WINDOWS_TWINSOCKSINGLETON_H_ thrift-0.23.0/lib/cpp/src/thrift/TApplicationException.h0000664000175000017500000000673115165535636023442 0ustar00buildbuild00000000000000/* * 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_TAPPLICATIONEXCEPTION_H_ #define _THRIFT_TAPPLICATIONEXCEPTION_H_ 1 #include namespace apache { namespace thrift { namespace protocol { class TProtocol; } class TApplicationException : public TException { public: /** * Error codes for the various types of exceptions. */ enum TApplicationExceptionType { UNKNOWN = 0, UNKNOWN_METHOD = 1, INVALID_MESSAGE_TYPE = 2, WRONG_METHOD_NAME = 3, BAD_SEQUENCE_ID = 4, MISSING_RESULT = 5, INTERNAL_ERROR = 6, PROTOCOL_ERROR = 7, INVALID_TRANSFORM = 8, INVALID_PROTOCOL = 9, UNSUPPORTED_CLIENT_TYPE = 10 }; TApplicationException() : TException(), type_(UNKNOWN) {} TApplicationException(TApplicationExceptionType type) : TException(), type_(type) {} TApplicationException(const std::string& message) : TException(message), type_(UNKNOWN) {} TApplicationException(TApplicationExceptionType type, const std::string& message) : TException(message), type_(type) {} ~TApplicationException() noexcept override = default; /** * Returns an error code that provides information about the type of error * that has occurred. * * @return Error code */ TApplicationExceptionType getType() const { return type_; } const char* what() const noexcept override { if (message_.empty()) { switch (type_) { case UNKNOWN: return "TApplicationException: Unknown application exception"; case UNKNOWN_METHOD: return "TApplicationException: Unknown method"; case INVALID_MESSAGE_TYPE: return "TApplicationException: Invalid message type"; case WRONG_METHOD_NAME: return "TApplicationException: Wrong method name"; case BAD_SEQUENCE_ID: return "TApplicationException: Bad sequence identifier"; case MISSING_RESULT: return "TApplicationException: Missing result"; case INTERNAL_ERROR: return "TApplicationException: Internal error"; case PROTOCOL_ERROR: return "TApplicationException: Protocol error"; case INVALID_TRANSFORM: return "TApplicationException: Invalid transform"; case INVALID_PROTOCOL: return "TApplicationException: Invalid protocol"; case UNSUPPORTED_CLIENT_TYPE: return "TApplicationException: Unsupported client type"; default: return "TApplicationException: (Invalid exception type)"; }; } else { return message_.c_str(); } } uint32_t read(protocol::TProtocol* iprot); uint32_t write(protocol::TProtocol* oprot) const; protected: /** * Error code */ TApplicationExceptionType type_; }; } } // apache::thrift #endif // #ifndef _THRIFT_TAPPLICATIONEXCEPTION_H_ thrift-0.23.0/lib/cpp/src/thrift/TOutput.cpp0000664000175000017500000001023315167543515021140 0ustar00buildbuild00000000000000/* * 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 #include #ifdef _WIN32 #include #endif namespace apache { namespace thrift { TOutput::TOutput() : f_(&errorTimeWrapper) {} void TOutput::printf(const char* message, ...) { #ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT // Try to reduce heap usage, even if printf is called rarely. static const int STACK_BUF_SIZE = 256; char stack_buf[STACK_BUF_SIZE]; va_list ap; #ifdef _MSC_VER va_start(ap, message); int need = _vscprintf(message, ap); va_end(ap); if (need < STACK_BUF_SIZE) { va_start(ap, message); vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap); va_end(ap); f_(stack_buf); return; } #else va_start(ap, message); int need = vsnprintf(stack_buf, STACK_BUF_SIZE, message, ap); va_end(ap); if (need < STACK_BUF_SIZE) { f_(stack_buf); return; } #endif char* heap_buf = (char*)malloc((need + 1) * sizeof(char)); if (heap_buf == nullptr) { #ifdef _MSC_VER va_start(ap, message); vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap); va_end(ap); #endif // Malloc failed. We might as well print the stack buffer. f_(stack_buf); return; } va_start(ap, message); int rval = vsnprintf(heap_buf, need + 1, message, ap); va_end(ap); // TODO(shigin): inform user if (rval != -1) { f_(heap_buf); } free(heap_buf); #else THRIFT_UNUSED_VARIABLE(message); #endif } void TOutput::errorTimeWrapper(const char* msg) { #ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT time_t now; char dbgtime[26]; time(&now); THRIFT_CTIME_R(&now, dbgtime); dbgtime[24] = 0; fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg); #else THRIFT_UNUSED_VARIABLE(msg); #endif } void TOutput::perror(const char* message, int errno_copy) { std::string out = message + std::string(": ") + strerror_s(errno_copy); f_(out.c_str()); } std::string TOutput::strerror_s(int errno_copy) { #ifdef __ZEPHYR__ return std::string(strerror(errno_copy)); #else char b_errbuf[1024] = {'\0'}; #ifdef HAVE_STRERROR_R #ifdef STRERROR_R_CHAR_P char* b_error = ::strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf)); #else // STRERROR_R_CHAR_P char* b_error = b_errbuf; int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf)); if (rv == -1) { // strerror_r failed. omgwtfbbq. return "XSI-compliant strerror_r() failed with errno = " + to_string(errno_copy); } #endif // STRERROR_R_CHAR_P #else // HAVE_STRERROR_R #ifdef _WIN32 const size_t size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errno_copy, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), b_errbuf, sizeof(b_errbuf), nullptr); if (size > 2 && b_errbuf[size-2] == '\r' && b_errbuf[size-1] == '\n') { b_errbuf[size-2] = '\0'; b_errbuf[size-1] = '\0'; } #else // _WIN32 ::strerror_s(b_errbuf, sizeof(b_errbuf), errno_copy); #endif // _WIN32 char* b_error = b_errbuf; #endif // HAVE_STRERROR_R // Can anyone prove that explicit cast is probably not necessary // to ensure that the string object is constructed before // b_error becomes invalid? return std::string(b_error); #endif // __ZEPHYR__ } TOutput& TOutput::instance() { static TOutput instance; return instance; } } } // apache::thrift thrift-0.23.0/lib/cpp/src/thrift/processor/0000755000175000017500000000000015170007200021002 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/processor/StatsProcessor.h0000664000175000017500000001411415165535636024203 0ustar00buildbuild00000000000000/* * 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 STATSPROCESSOR_H #define STATSPROCESSOR_H #include #include #include #include namespace apache { namespace thrift { namespace processor { /* * Class for keeping track of function call statistics and printing them if desired * */ class StatsProcessor : public apache::thrift::TProcessor { public: StatsProcessor(bool print, bool frequency) : print_(print), frequency_(frequency) {} virtual ~StatsProcessor(){}; virtual bool process(std::shared_ptr piprot, std::shared_ptr poprot, void* serverContext) { piprot_ = piprot; std::string fname; apache::thrift::protocol::TMessageType mtype; int32_t seqid; piprot_->readMessageBegin(fname, mtype, seqid); if (mtype != apache::thrift::protocol::T_CALL && mtype != apache::thrift::protocol::T_ONEWAY) { if (print_) { printf("Unknown message type\n"); } throw apache::thrift::TException("Unexpected message type"); } if (print_) { printf("%s (", fname.c_str()); } if (frequency_) { if (frequency_map_.find(fname) != frequency_map_.end()) { frequency_map_[fname]++; } else { frequency_map_[fname] = 1; } } apache::thrift::protocol::TType ftype; int16_t fid; while (true) { piprot_->readFieldBegin(fname, ftype, fid); if (ftype == apache::thrift::protocol::T_STOP) { break; } printAndPassToBuffer(ftype); if (print_) { printf(", "); } } if (print_) { printf("\b\b)\n"); } return true; } const std::map& get_frequency_map() { return frequency_map_; } protected: void printAndPassToBuffer(apache::thrift::protocol::TType ftype) { switch (ftype) { case apache::thrift::protocol::T_BOOL: { bool boolv; piprot_->readBool(boolv); if (print_) { printf("%d", boolv); } } break; case apache::thrift::protocol::T_BYTE: { int8_t bytev; piprot_->readByte(bytev); if (print_) { printf("%d", bytev); } } break; case apache::thrift::protocol::T_I16: { int16_t i16; piprot_->readI16(i16); if (print_) { printf("%d", i16); } } break; case apache::thrift::protocol::T_I32: { int32_t i32; piprot_->readI32(i32); if (print_) { printf("%d", i32); } } break; case apache::thrift::protocol::T_I64: { int64_t i64; piprot_->readI64(i64); if (print_) { printf("%ld", i64); } } break; case apache::thrift::protocol::T_DOUBLE: { double dub; piprot_->readDouble(dub); if (print_) { printf("%f", dub); } } break; case apache::thrift::protocol::T_STRING: { std::string str; piprot_->readString(str); if (print_) { printf("%s", str.c_str()); } } break; case apache::thrift::protocol::T_STRUCT: { std::string name; int16_t fid; apache::thrift::protocol::TType ftype; piprot_->readStructBegin(name); if (print_) { printf("<"); } while (true) { piprot_->readFieldBegin(name, ftype, fid); if (ftype == apache::thrift::protocol::T_STOP) { break; } printAndPassToBuffer(ftype); if (print_) { printf(","); } piprot_->readFieldEnd(); } piprot_->readStructEnd(); if (print_) { printf("\b>"); } } break; case apache::thrift::protocol::T_MAP: { apache::thrift::protocol::TType keyType; apache::thrift::protocol::TType valType; uint32_t i, size; piprot_->readMapBegin(keyType, valType, size); if (print_) { printf("{"); } for (i = 0; i < size; i++) { printAndPassToBuffer(keyType); if (print_) { printf("=>"); } printAndPassToBuffer(valType); if (print_) { printf(","); } } piprot_->readMapEnd(); if (print_) { printf("\b}"); } } break; case apache::thrift::protocol::T_SET: { apache::thrift::protocol::TType elemType; uint32_t i, size; piprot_->readSetBegin(elemType, size); if (print_) { printf("{"); } for (i = 0; i < size; i++) { printAndPassToBuffer(elemType); if (print_) { printf(","); } } piprot_->readSetEnd(); if (print_) { printf("\b}"); } } break; case apache::thrift::protocol::T_LIST: { apache::thrift::protocol::TType elemType; uint32_t i, size; piprot_->readListBegin(elemType, size); if (print_) { printf("["); } for (i = 0; i < size; i++) { printAndPassToBuffer(elemType); if (print_) { printf(","); } } piprot_->readListEnd(); if (print_) { printf("\b]"); } } break; default: break; } } std::shared_ptr piprot_; std::map frequency_map_; bool print_; bool frequency_; }; } } } // apache::thrift::processor #endif thrift-0.23.0/lib/cpp/src/thrift/processor/PeekProcessor.h0000664000175000017500000000631615165535636023776 0ustar00buildbuild00000000000000/* * 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 PEEKPROCESSOR_H #define PEEKPROCESSOR_H #include #include #include #include #include #include namespace apache { namespace thrift { namespace processor { /* * Class for peeking at the raw data that is being processed by another processor * and gives the derived class a chance to change behavior accordingly * */ class PeekProcessor : public apache::thrift::TProcessor { public: PeekProcessor(); ~PeekProcessor() override; // Input here: actualProcessor - the underlying processor // protocolFactory - the protocol factory used to wrap the memory buffer // transportFactory - this TPipedTransportFactory is used to wrap the source transport // via a call to getPipedTransport void initialize( std::shared_ptr actualProcessor, std::shared_ptr protocolFactory, std::shared_ptr transportFactory); std::shared_ptr getPipedTransport( std::shared_ptr in); void setTargetTransport(std::shared_ptr targetTransport); bool process(std::shared_ptr in, std::shared_ptr out, void* connectionContext) override; // The following three functions can be overloaded by child classes to // achieve desired peeking behavior virtual void peekName(const std::string& fname); virtual void peekBuffer(uint8_t* buffer, uint32_t size); virtual void peek(std::shared_ptr in, apache::thrift::protocol::TType ftype, int16_t fid); virtual void peekEnd(); private: std::shared_ptr actualProcessor_; std::shared_ptr pipedProtocol_; std::shared_ptr transportFactory_; std::shared_ptr memoryBuffer_; std::shared_ptr targetTransport_; }; } } } // apache::thrift::processor #endif thrift-0.23.0/lib/cpp/src/thrift/processor/TMultiplexedProcessor.h0000664000175000017500000002042715165535636025531 0ustar00buildbuild00000000000000/* * 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_TMULTIPLEXEDPROCESSOR_H_ #define THRIFT_TMULTIPLEXEDPROCESSOR_H_ 1 #include #include #include #include namespace apache { namespace thrift { namespace protocol { /** * To be able to work with any protocol, we needed * to allow them to call readMessageBegin() and get a TMessage in exactly * the standard format, without the service name prepended to TMessage.name. */ class StoredMessageProtocol : public TProtocolDecorator { public: StoredMessageProtocol(std::shared_ptr _protocol, const std::string& _name, const TMessageType _type, const int32_t _seqid) : TProtocolDecorator(_protocol), name(_name), type(_type), seqid(_seqid) {} uint32_t readMessageBegin_virt(std::string& _name, TMessageType& _type, int32_t& _seqid) override { _name = name; _type = type; _seqid = seqid; return 0; // (Normal TProtocol read functions return number of bytes read) } std::string name; TMessageType type; int32_t seqid; }; } // namespace protocol /** * TMultiplexedProcessor is a TProcessor allowing * a single TServer to provide multiple services. * *

To do so, you instantiate the processor and then register additional * processors with it, as shown in the following example:

* *
* std::shared_ptr processor(new TMultiplexedProcessor()); * * processor->registerProcessor( * "Calculator", * std::shared_ptr( new CalculatorProcessor( * std::shared_ptr( new CalculatorHandler())))); * * processor->registerProcessor( * "WeatherReport", * std::shared_ptr( new WeatherReportProcessor( * std::shared_ptr( new WeatherReportHandler())))); * * std::shared_ptr transport(new TServerSocket(9090)); * TSimpleServer server(processor, transport); * * server.serve(); *
*/ class TMultiplexedProcessor : public TProcessor { public: typedef std::map > services_t; /** * 'Register' a service with this TMultiplexedProcessor. This * allows us to broker requests to individual services by using the service * name to select them at request time. * * \param [in] serviceName Name of a service, has to be identical to the name * declared in the Thrift IDL, e.g. "WeatherReport". * \param [in] processor Implementation of a service, usually referred to * as "handlers", e.g. WeatherReportHandler, * implementing WeatherReportIf interface. */ void registerProcessor(const std::string& serviceName, std::shared_ptr processor) { services[serviceName] = processor; } /** * Register a service to be called to process queries without service name * \param [in] processor Implementation of a service. */ void registerDefault(const std::shared_ptr& processor) { defaultProcessor = processor; } /** * Chew up invalid input and return an exception to throw. */ TException protocol_error(std::shared_ptr in, std::shared_ptr out, const std::string& name, int32_t seqid, const std::string& msg) const { in->skip(::apache::thrift::protocol::T_STRUCT); in->readMessageEnd(); in->getTransport()->readEnd(); ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::PROTOCOL_ERROR, "TMultiplexedProcessor: " + msg); out->writeMessageBegin(name, ::apache::thrift::protocol::T_EXCEPTION, seqid); x.write(out.get()); out->writeMessageEnd(); out->getTransport()->writeEnd(); out->getTransport()->flush(); return TException(msg); } /** * This implementation of process performs the following steps: * *
    *
  1. Read the beginning of the message.
  2. *
  3. Extract the service name from the message.
  4. *
  5. Using the service name to locate the appropriate processor.
  6. *
  7. Dispatch to the processor, with a decorated instance of TProtocol * that allows readMessageBegin() to return the original TMessage.
  8. *
* * \throws TException If the message type is not T_CALL or T_ONEWAY, if * the service name was not found in the message, or if the service * name was not found in the service map. */ bool process(std::shared_ptr in, std::shared_ptr out, void* connectionContext) override { std::string name; protocol::TMessageType type; int32_t seqid; // Use the actual underlying protocol (e.g. TBinaryProtocol) to read the // message header. This pulls the message "off the wire", which we'll // deal with at the end of this method. in->readMessageBegin(name, type, seqid); if (type != protocol::T_CALL && type != protocol::T_ONEWAY) { // Unexpected message type. throw protocol_error(in, out, name, seqid, "Unexpected message type"); } // Extract the service name boost::tokenizer > tok(name, boost::char_separator(":")); std::vector tokens; std::copy(tok.begin(), tok.end(), std::back_inserter(tokens)); // A valid message should consist of two tokens: the service // name and the name of the method to call. if (tokens.size() == 2) { // Search for a processor associated with this service name. auto it = services.find(tokens[0]); if (it != services.end()) { std::shared_ptr processor = it->second; // Let the processor registered for this service name // process the message. return processor ->process(std::shared_ptr( new protocol::StoredMessageProtocol(in, tokens[1], type, seqid)), out, connectionContext); } else { // Unknown service. throw protocol_error(in, out, name, seqid, "Unknown service: " + tokens[0] + ". Did you forget to call registerProcessor()?"); } } else if (tokens.size() == 1) { if (defaultProcessor) { // non-multiplexed client forwards to default processor return defaultProcessor ->process(std::shared_ptr( new protocol::StoredMessageProtocol(in, tokens[0], type, seqid)), out, connectionContext); } else { throw protocol_error(in, out, name, seqid, "Non-multiplexed client request dropped. " "Did you forget to call defaultProcessor()?"); } } else { throw protocol_error(in, out, name, seqid, "Wrong number of tokens."); } } private: /** Map of service processor objects, indexed by service names. */ services_t services; //! If a non-multi client requests something, it goes to the //! default processor (if one is defined) for backwards compatibility. std::shared_ptr defaultProcessor; }; } } #endif // THRIFT_TMULTIPLEXEDPROCESSOR_H_ thrift-0.23.0/lib/cpp/src/thrift/processor/PeekProcessor.cpp0000664000175000017500000000747315165535636024336 0ustar00buildbuild00000000000000/* * 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 using namespace apache::thrift::transport; using namespace apache::thrift::protocol; using namespace apache::thrift; namespace apache { namespace thrift { namespace processor { PeekProcessor::PeekProcessor() { memoryBuffer_.reset(new TMemoryBuffer()); targetTransport_ = memoryBuffer_; } PeekProcessor::~PeekProcessor() = default; void PeekProcessor::initialize(std::shared_ptr actualProcessor, std::shared_ptr protocolFactory, std::shared_ptr transportFactory) { actualProcessor_ = actualProcessor; pipedProtocol_ = protocolFactory->getProtocol(targetTransport_); transportFactory_ = transportFactory; transportFactory_->initializeTargetTransport(targetTransport_); } std::shared_ptr PeekProcessor::getPipedTransport(std::shared_ptr in) { return transportFactory_->getTransport(in); } void PeekProcessor::setTargetTransport(std::shared_ptr targetTransport) { targetTransport_ = targetTransport; if (std::dynamic_pointer_cast(targetTransport_)) { memoryBuffer_ = std::dynamic_pointer_cast(targetTransport); } else if (std::dynamic_pointer_cast(targetTransport_)) { memoryBuffer_ = std::dynamic_pointer_cast( std::dynamic_pointer_cast(targetTransport_)->getTargetTransport()); } if (!memoryBuffer_) { throw TException( "Target transport must be a TMemoryBuffer or a TPipedTransport with TMemoryBuffer"); } } bool PeekProcessor::process(std::shared_ptr in, std::shared_ptr out, void* connectionContext) { std::string fname; TMessageType mtype; int32_t seqid; in->readMessageBegin(fname, mtype, seqid); if (mtype != T_CALL && mtype != T_ONEWAY) { throw TException("Unexpected message type"); } // Peek at the name peekName(fname); TType ftype; int16_t fid; while (true) { in->readFieldBegin(fname, ftype, fid); if (ftype == T_STOP) { break; } // Peek at the variable peek(in, ftype, fid); in->readFieldEnd(); } in->readMessageEnd(); in->getTransport()->readEnd(); // // All the data is now in memoryBuffer_ and ready to be processed // // Let's first take a peek at the full data in memory uint8_t* buffer; uint32_t size; memoryBuffer_->getBuffer(&buffer, &size); peekBuffer(buffer, size); // Done peeking at variables peekEnd(); bool ret = actualProcessor_->process(pipedProtocol_, out, connectionContext); memoryBuffer_->resetBuffer(); return ret; } void PeekProcessor::peekName(const std::string& fname) { (void)fname; } void PeekProcessor::peekBuffer(uint8_t* buffer, uint32_t size) { (void)buffer; (void)size; } void PeekProcessor::peek(std::shared_ptr in, TType ftype, int16_t fid) { (void)fid; in->skip(ftype); } void PeekProcessor::peekEnd() { } } } } thrift-0.23.0/lib/cpp/src/thrift/qt/0000755000175000017500000000000015170007200017407 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/qt/TQIODeviceTransport.cpp0000664000175000017500000001105615165535636023760 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { using std::shared_ptr; namespace transport { TQIODeviceTransport::TQIODeviceTransport(shared_ptr dev) : dev_(dev) { } TQIODeviceTransport::~TQIODeviceTransport() { dev_->close(); } void TQIODeviceTransport::open() { if (!isOpen()) { throw TTransportException(TTransportException::NOT_OPEN, "open(): underlying QIODevice isn't open"); } } bool TQIODeviceTransport::isOpen() const { return dev_->isOpen(); } bool TQIODeviceTransport::peek() { return dev_->bytesAvailable() > 0; } void TQIODeviceTransport::close() { dev_->close(); } uint32_t TQIODeviceTransport::readAll(uint8_t* buf, uint32_t len) { uint32_t requestLen = len; while (len) { uint32_t readSize; try { readSize = read(buf, len); } catch (...) { if (len != requestLen) { // something read already return requestLen - len; } // error but nothing read yet throw; } if (readSize == 0) { dev_->waitForReadyRead(50); } else { buf += readSize; len -= readSize; } } return requestLen; } uint32_t TQIODeviceTransport::read(uint8_t* buf, uint32_t len) { uint32_t actualSize; qint64 readSize; if (!dev_->isOpen()) { throw TTransportException(TTransportException::NOT_OPEN, "read(): underlying QIODevice is not open"); } actualSize = (uint32_t)(std::min)((qint64)len, dev_->bytesAvailable()); readSize = dev_->read(reinterpret_cast(buf), actualSize); if (readSize < 0) { QAbstractSocket* socket; if ((socket = qobject_cast(dev_.get()))) { throw TTransportException(TTransportException::UNKNOWN, "Failed to read() from QAbstractSocket", socket->error()); } throw TTransportException(TTransportException::UNKNOWN, "Failed to read from from QIODevice"); } return (uint32_t)readSize; } void TQIODeviceTransport::write(const uint8_t* buf, uint32_t len) { while (len) { uint32_t written = write_partial(buf, len); len -= written; dev_->waitForBytesWritten(50); } } uint32_t TQIODeviceTransport::write_partial(const uint8_t* buf, uint32_t len) { qint64 written; if (!dev_->isOpen()) { throw TTransportException(TTransportException::NOT_OPEN, "write_partial(): underlying QIODevice is not open"); } written = dev_->write(reinterpret_cast(buf), len); if (written < 0) { QAbstractSocket* socket; if ((socket = qobject_cast(dev_.get()))) { throw TTransportException(TTransportException::UNKNOWN, "write_partial(): failed to write to QAbstractSocket", socket->error()); } throw TTransportException(TTransportException::UNKNOWN, "write_partial(): failed to write to underlying QIODevice"); } return (uint32_t)written; } void TQIODeviceTransport::flush() { if (!dev_->isOpen()) { throw TTransportException(TTransportException::NOT_OPEN, "flush(): underlying QIODevice is not open"); } QAbstractSocket* socket; if ((socket = qobject_cast(dev_.get()))) { socket->flush(); } else { dev_->waitForBytesWritten(1); } } uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len) { (void)buf; (void)len; return nullptr; } void TQIODeviceTransport::consume(uint32_t len) { (void)len; throw TTransportException(TTransportException::UNKNOWN); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/qt/TQIODeviceTransport.h0000664000175000017500000000372115165535636023425 0ustar00buildbuild00000000000000/* * 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_ASYNC_TQIODEVICE_TRANSPORT_H_ #define _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ 1 #include #include class QIODevice; namespace apache { namespace thrift { namespace transport { /** * Transport that operates on a QIODevice (socket, file, etc). */ class TQIODeviceTransport : public apache::thrift::transport::TVirtualTransport { public: explicit TQIODeviceTransport(std::shared_ptr dev); ~TQIODeviceTransport() override; void open() override; bool isOpen() const override; bool peek() override; void close() override; uint32_t readAll(uint8_t* buf, uint32_t len); uint32_t read(uint8_t* buf, uint32_t len); void write(const uint8_t* buf, uint32_t len); uint32_t write_partial(const uint8_t* buf, uint32_t len); void flush() override; uint8_t* borrow(uint8_t* buf, uint32_t* len); void consume(uint32_t len); private: TQIODeviceTransport(const TQIODeviceTransport&); TQIODeviceTransport& operator=(const TQIODeviceTransport&); std::shared_ptr dev_; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/qt/CMakeLists.txt0000664000175000017500000000211315165535636022175 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # set( thriftcppqt5_SOURCES TQIODeviceTransport.cpp TQTcpServer.cpp ) set(CMAKE_AUTOMOC ON) find_package(Qt5 REQUIRED COMPONENTS Core Network) ADD_LIBRARY_THRIFT(thriftqt5 ${thriftcppqt5_SOURCES}) target_link_libraries(thriftqt5 PUBLIC thrift) target_link_libraries(thriftqt5 PUBLIC Qt5::Core Qt5::Network) thrift-0.23.0/lib/cpp/src/thrift/qt/TQTcpServer.cpp0000664000175000017500000001203715165535636022331 0ustar00buildbuild00000000000000/* * 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 #include #include #include using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TQIODeviceTransport; using std::bind; using std::function; using std::placeholders::_1; using std::shared_ptr; QT_USE_NAMESPACE namespace apache { namespace thrift { namespace async { struct TQTcpServer::ConnectionContext { shared_ptr connection_; shared_ptr transport_; shared_ptr iprot_; shared_ptr oprot_; explicit ConnectionContext(shared_ptr connection, shared_ptr transport, shared_ptr iprot, shared_ptr oprot) : connection_(connection), transport_(transport), iprot_(iprot), oprot_(oprot) {} }; TQTcpServer::TQTcpServer(shared_ptr server, shared_ptr processor, shared_ptr pfact, QObject* parent) : QObject(parent), server_(server), processor_(processor), pfact_(pfact) { qRegisterMetaType("QTcpSocket*"); connect(server.get(), SIGNAL(newConnection()), SLOT(processIncoming())); } TQTcpServer::~TQTcpServer() = default; void TQTcpServer::processIncoming() { while (server_->hasPendingConnections()) { // take ownership of the QTcpSocket; technically it could be deleted // when the QTcpServer is destroyed, but any real app should delete this // class before deleting the QTcpServer that we are using shared_ptr connection(server_->nextPendingConnection()); shared_ptr transport; shared_ptr iprot; shared_ptr oprot; try { transport = shared_ptr(new TQIODeviceTransport(connection)); iprot = shared_ptr(pfact_->getProtocol(transport)); oprot = shared_ptr(pfact_->getProtocol(transport)); } catch (...) { qWarning("[TQTcpServer] Failed to initialize transports/protocols"); continue; } ctxMap_[connection.get()] = std::make_shared(connection, transport, iprot, oprot); connect(connection.get(), SIGNAL(readyRead()), SLOT(beginDecode())); connect(connection.get(), SIGNAL(disconnected()), SLOT(socketClosed())); } } void TQTcpServer::beginDecode() { auto* connection(qobject_cast(sender())); Q_ASSERT(connection); if (ctxMap_.find(connection) == ctxMap_.end()) { qWarning("[TQTcpServer] Got data on an unknown QTcpSocket"); return; } shared_ptr ctx = ctxMap_[connection]; try { processor_ ->process(bind(&TQTcpServer::finish, this, ctx, _1), ctx->iprot_, ctx->oprot_); } catch (const TTransportException& ex) { qWarning("[TQTcpServer] TTransportException during processing: '%s'", ex.what()); scheduleDeleteConnectionContext(connection); } catch (...) { qWarning("[TQTcpServer] Unknown processor exception"); scheduleDeleteConnectionContext(connection); } } void TQTcpServer::socketClosed() { auto* connection(qobject_cast(sender())); Q_ASSERT(connection); scheduleDeleteConnectionContext(connection); } void TQTcpServer::deleteConnectionContext(QTcpSocket* connection) { const ConnectionContextMap::size_type deleted = ctxMap_.erase(connection); if (0 == deleted) { qWarning("[TQTcpServer] Unknown QTcpSocket"); } } void TQTcpServer::scheduleDeleteConnectionContext(QTcpSocket* connection) { QMetaObject::invokeMethod(this, "deleteConnectionContext", Qt::QueuedConnection, Q_ARG(QTcpSocket*, connection)); } void TQTcpServer::finish(shared_ptr ctx, bool healthy) { if (!healthy) { qWarning("[TQTcpServer] Processor failed to process data successfully"); deleteConnectionContext(ctx->connection_.get()); } } } } } // apache::thrift::async thrift-0.23.0/lib/cpp/src/thrift/qt/TQTcpServer.h0000664000175000017500000000451215165535636021775 0ustar00buildbuild00000000000000/* * 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_TASYNC_QTCP_SERVER_H_ #define _THRIFT_TASYNC_QTCP_SERVER_H_ #include #include #include namespace apache { namespace thrift { namespace protocol { class TProtocolFactory; } } } // apache::thrift::protocol namespace apache { namespace thrift { namespace async { class TAsyncProcessor; /** * Server that uses Qt to listen for connections. * Simply give it a QTcpServer that is listening, along with an async * processor and a protocol factory, and then run the Qt event loop. */ class TQTcpServer : public QObject { Q_OBJECT public: TQTcpServer(std::shared_ptr server, std::shared_ptr processor, std::shared_ptr protocolFactory, QObject* parent = nullptr); ~TQTcpServer() override; private Q_SLOTS: void processIncoming(); void beginDecode(); void socketClosed(); void deleteConnectionContext(QTcpSocket* connection); private: Q_DISABLE_COPY(TQTcpServer) struct ConnectionContext; void scheduleDeleteConnectionContext(QTcpSocket* connection); void finish(std::shared_ptr ctx, bool healthy); std::shared_ptr server_; std::shared_ptr processor_; std::shared_ptr pfact_; typedef std::map > ConnectionContextMap; ConnectionContextMap ctxMap_; }; } } } // apache::thrift::async #endif // #ifndef _THRIFT_TASYNC_QTCP_SERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/server/0000755000175000017500000000000015170007200020271 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/server/TThreadPoolServer.cpp0000664000175000017500000001231715165535636024406 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace server { using apache::thrift::concurrency::ThreadManager; using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TTransportFactory; using std::shared_ptr; using std::string; TThreadPoolServer::TThreadPoolServer(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory, const shared_ptr& threadManager) : TServerFramework(processorFactory, serverTransport, transportFactory, protocolFactory), threadManager_(threadManager), timeout_(0), taskExpiration_(0) { } TThreadPoolServer::TThreadPoolServer(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory, const shared_ptr& threadManager) : TServerFramework(processor, serverTransport, transportFactory, protocolFactory), threadManager_(threadManager), timeout_(0), taskExpiration_(0) { } TThreadPoolServer::TThreadPoolServer(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory, const shared_ptr& threadManager) : TServerFramework(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory), threadManager_(threadManager), timeout_(0), taskExpiration_(0) { } TThreadPoolServer::TThreadPoolServer(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory, const shared_ptr& threadManager) : TServerFramework(processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory), threadManager_(threadManager), timeout_(0), taskExpiration_(0) { } TThreadPoolServer::~TThreadPoolServer() = default; void TThreadPoolServer::serve() { TServerFramework::serve(); threadManager_->stop(); } int64_t TThreadPoolServer::getTimeout() const { return timeout_; } void TThreadPoolServer::setTimeout(int64_t value) { timeout_ = value; } int64_t TThreadPoolServer::getTaskExpiration() const { return taskExpiration_; } void TThreadPoolServer::setTaskExpiration(int64_t value) { taskExpiration_ = value; } std::shared_ptr TThreadPoolServer::getThreadManager() const { return threadManager_; } void TThreadPoolServer::onClientConnected(const shared_ptr& pClient) { threadManager_->add(pClient, getTimeout(), getTaskExpiration()); } void TThreadPoolServer::onClientDisconnected(TConnectedClient*) { } } } } // apache::thrift::server thrift-0.23.0/lib/cpp/src/thrift/server/TServer.h0000664000175000017500000002512015165535636022065 0ustar00buildbuild00000000000000/* * 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_SERVER_TSERVER_H_ #define _THRIFT_SERVER_TSERVER_H_ 1 #include #include #include #include #include namespace apache { namespace thrift { namespace server { using apache::thrift::TProcessor; using apache::thrift::protocol::TBinaryProtocolFactory; using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportFactory; /** * Virtual interface class that can handle events from the server core. To * use this you should subclass it and implement the methods that you care * about. Your subclass can also store local data that you may care about, * such as additional "arguments" to these methods (stored in the object * instance's state). */ class TServerEventHandler { public: virtual ~TServerEventHandler() = default; /** * Called before the server begins. */ virtual void preServe() {} /** * Called when a new client has connected and is about to being processing. */ virtual void* createContext(std::shared_ptr input, std::shared_ptr output) { (void)input; (void)output; return nullptr; } /** * Called when a client has finished request-handling to delete server * context. */ virtual void deleteContext(void* serverContext, std::shared_ptr input, std::shared_ptr output) { (void)serverContext; (void)input; (void)output; } /** * Called when a client is about to call the processor. */ virtual void processContext(void* serverContext, std::shared_ptr transport) { (void)serverContext; (void)transport; } protected: /** * Prevent direct instantiation. */ TServerEventHandler() = default; }; /** * Thrift server. * */ class TServer : public concurrency::Runnable { public: ~TServer() override = default; virtual void serve() = 0; virtual void stop() {} // Allows running the server as a Runnable thread void run() override { serve(); } std::shared_ptr getProcessorFactory() { return processorFactory_; } std::shared_ptr getServerTransport() { return serverTransport_; } std::shared_ptr getInputTransportFactory() { return inputTransportFactory_; } std::shared_ptr getOutputTransportFactory() { return outputTransportFactory_; } std::shared_ptr getInputProtocolFactory() { return inputProtocolFactory_; } std::shared_ptr getOutputProtocolFactory() { return outputProtocolFactory_; } std::shared_ptr getEventHandler() { return eventHandler_; } protected: TServer(const std::shared_ptr& processorFactory) : processorFactory_(processorFactory) { setInputTransportFactory(std::shared_ptr(new TTransportFactory())); setOutputTransportFactory(std::shared_ptr(new TTransportFactory())); setInputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); } TServer(const std::shared_ptr& processor) : processorFactory_(new TSingletonProcessorFactory(processor)) { setInputTransportFactory(std::shared_ptr(new TTransportFactory())); setOutputTransportFactory(std::shared_ptr(new TTransportFactory())); setInputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); } TServer(const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport) : processorFactory_(processorFactory), serverTransport_(serverTransport) { setInputTransportFactory(std::shared_ptr(new TTransportFactory())); setOutputTransportFactory(std::shared_ptr(new TTransportFactory())); setInputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); } TServer(const std::shared_ptr& processor, const std::shared_ptr& serverTransport) : processorFactory_(new TSingletonProcessorFactory(processor)), serverTransport_(serverTransport) { setInputTransportFactory(std::shared_ptr(new TTransportFactory())); setOutputTransportFactory(std::shared_ptr(new TTransportFactory())); setInputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(std::shared_ptr(new TBinaryProtocolFactory())); } TServer(const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory) : processorFactory_(processorFactory), serverTransport_(serverTransport), inputTransportFactory_(transportFactory), outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory), outputProtocolFactory_(protocolFactory) {} TServer(const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory) : processorFactory_(new TSingletonProcessorFactory(processor)), serverTransport_(serverTransport), inputTransportFactory_(transportFactory), outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory), outputProtocolFactory_(protocolFactory) {} TServer(const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory) : processorFactory_(processorFactory), serverTransport_(serverTransport), inputTransportFactory_(inputTransportFactory), outputTransportFactory_(outputTransportFactory), inputProtocolFactory_(inputProtocolFactory), outputProtocolFactory_(outputProtocolFactory) {} TServer(const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory) : processorFactory_(new TSingletonProcessorFactory(processor)), serverTransport_(serverTransport), inputTransportFactory_(inputTransportFactory), outputTransportFactory_(outputTransportFactory), inputProtocolFactory_(inputProtocolFactory), outputProtocolFactory_(outputProtocolFactory) {} /** * Get a TProcessor to handle calls on a particular connection. * * This method should only be called once per connection (never once per * call). This allows the TProcessorFactory to return a different processor * for each connection if it desires. */ std::shared_ptr getProcessor(std::shared_ptr inputProtocol, std::shared_ptr outputProtocol, std::shared_ptr transport) { TConnectionInfo connInfo; connInfo.input = inputProtocol; connInfo.output = outputProtocol; connInfo.transport = transport; return processorFactory_->getProcessor(connInfo); } // Class variables std::shared_ptr processorFactory_; std::shared_ptr serverTransport_; std::shared_ptr inputTransportFactory_; std::shared_ptr outputTransportFactory_; std::shared_ptr inputProtocolFactory_; std::shared_ptr outputProtocolFactory_; std::shared_ptr eventHandler_; public: void setInputTransportFactory(std::shared_ptr inputTransportFactory) { inputTransportFactory_ = inputTransportFactory; } void setOutputTransportFactory(std::shared_ptr outputTransportFactory) { outputTransportFactory_ = outputTransportFactory; } void setInputProtocolFactory(std::shared_ptr inputProtocolFactory) { inputProtocolFactory_ = inputProtocolFactory; } void setOutputProtocolFactory(std::shared_ptr outputProtocolFactory) { outputProtocolFactory_ = outputProtocolFactory; } void setServerEventHandler(std::shared_ptr eventHandler) { eventHandler_ = eventHandler; } }; /** * Helper function to increase the max file descriptors limit * for the current process and all of its children. * By default, tries to increase it to as much as 2^24. */ #ifdef HAVE_SYS_RESOURCE_H int increase_max_fds(int max_fds = (1 << 24)); #endif } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TSERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/server/TThreadedServer.cpp0000664000175000017500000001415515165535636024067 0ustar00buildbuild00000000000000/* * 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 server { using apache::thrift::concurrency::Runnable; using apache::thrift::concurrency::Synchronized; using apache::thrift::concurrency::Thread; using apache::thrift::concurrency::ThreadFactory; using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using std::make_shared; using std::shared_ptr; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TTransportFactory; TThreadedServer::TThreadedServer(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory, const shared_ptr& threadFactory) : TServerFramework(processorFactory, serverTransport, transportFactory, protocolFactory), threadFactory_(threadFactory) { } TThreadedServer::TThreadedServer(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory, const shared_ptr& threadFactory) : TServerFramework(processor, serverTransport, transportFactory, protocolFactory), threadFactory_(threadFactory) { } TThreadedServer::TThreadedServer(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory, const shared_ptr& threadFactory) : TServerFramework(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory), threadFactory_(threadFactory) { } TThreadedServer::TThreadedServer(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory, const shared_ptr& threadFactory) : TServerFramework(processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory), threadFactory_(threadFactory) { } TThreadedServer::~TThreadedServer() = default; void TThreadedServer::serve() { TServerFramework::serve(); // Ensure post-condition of no active clients Synchronized s(clientMonitor_); while (!activeClientMap_.empty()) { clientMonitor_.wait(); } drainDeadClients(); } void TThreadedServer::drainDeadClients() { // we're in a monitor here while (!deadClientMap_.empty()) { auto it = deadClientMap_.begin(); it->second->join(); deadClientMap_.erase(it); } } void TThreadedServer::onClientConnected(const shared_ptr& pClient) { Synchronized sync(clientMonitor_); shared_ptr pRunnable = make_shared(pClient); shared_ptr pThread = threadFactory_->newThread(pRunnable); pRunnable->thread(pThread); activeClientMap_.insert(ClientMap::value_type(pClient.get(), pThread)); pThread->start(); } void TThreadedServer::onClientDisconnected(TConnectedClient* pClient) { Synchronized sync(clientMonitor_); drainDeadClients(); // use the outgoing thread to do some maintenance on our dead client backlog auto it = activeClientMap_.find(pClient); if (it != activeClientMap_.end()) { auto end = it; deadClientMap_.insert(it, ++end); activeClientMap_.erase(it); } if (activeClientMap_.empty()) { clientMonitor_.notify(); } } TThreadedServer::TConnectedClientRunner::TConnectedClientRunner(const shared_ptr& pClient) : pClient_(pClient) { } TThreadedServer::TConnectedClientRunner::~TConnectedClientRunner() = default; void TThreadedServer::TConnectedClientRunner::run() /* override */ { pClient_->run(); // Run the client pClient_.reset(); // The client is done - release it here rather than in the destructor for safety } } } } // apache::thrift::server thrift-0.23.0/lib/cpp/src/thrift/server/TConnectedClient.h0000664000175000017500000000744215165535636023667 0ustar00buildbuild00000000000000/* * 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_SERVER_TCONNECTEDCLIENT_H_ #define _THRIFT_SERVER_TCONNECTEDCLIENT_H_ 1 #include #include #include #include #include namespace apache { namespace thrift { namespace server { /** * This represents a client connected to a TServer. The * processing loop for a client must provide some required * functionality common to all implementations so it is * encapsulated here. */ class TConnectedClient : public apache::thrift::concurrency::Runnable { public: /** * Constructor. * * @param[in] processor the TProcessor * @param[in] inputProtocol the input TProtocol * @param[in] outputProtocol the output TProtocol * @param[in] eventHandler the server event handler * @param[in] client the TTransport representing the client */ TConnectedClient( const std::shared_ptr& processor, const std::shared_ptr& inputProtocol, const std::shared_ptr& outputProtocol, const std::shared_ptr& eventHandler, const std::shared_ptr& client); /** * Destructor. */ ~TConnectedClient() override; /** * Drive the client until it is done. * The client processing loop is: * * [optional] call eventHandler->createContext once * [optional] call eventHandler->processContext per request * call processor->process per request * handle expected transport exceptions: * END_OF_FILE means the client is gone * INTERRUPTED means the client was interrupted * by TServerTransport::interruptChildren() * handle unexpected transport exceptions by logging * handle standard exceptions by logging * handle unexpected exceptions by logging * cleanup() */ void run() override /* override */; protected: /** * Cleanup after a client. This happens if the client disconnects, * or if the server is stopped, or if an exception occurs. * * The cleanup processing is: * [optional] call eventHandler->deleteContext once * close the inputProtocol's TTransport * close the outputProtocol's TTransport * close the client */ virtual void cleanup(); private: std::shared_ptr processor_; std::shared_ptr inputProtocol_; std::shared_ptr outputProtocol_; std::shared_ptr eventHandler_; std::shared_ptr client_; /** * Context acquired from the eventHandler_ if one exists. */ void* opaqueContext_; }; } } } #endif // #ifndef _THRIFT_SERVER_TCONNECTEDCLIENT_H_ thrift-0.23.0/lib/cpp/src/thrift/server/TSimpleServer.cpp0000664000175000017500000001066715165535636023604 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace server { using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TTransportFactory; using std::shared_ptr; using std::string; TSimpleServer::TSimpleServer(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory) : TServerFramework(processorFactory, serverTransport, transportFactory, protocolFactory) { TServerFramework::setConcurrentClientLimit(1); } TSimpleServer::TSimpleServer(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory) : TServerFramework(processor, serverTransport, transportFactory, protocolFactory) { TServerFramework::setConcurrentClientLimit(1); } TSimpleServer::TSimpleServer(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory) : TServerFramework(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory) { TServerFramework::setConcurrentClientLimit(1); } TSimpleServer::TSimpleServer(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory) : TServerFramework(processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory) { TServerFramework::setConcurrentClientLimit(1); } TSimpleServer::~TSimpleServer() = default; /** * The main body of customized implementation for TSimpleServer is quite simple: * When a client connects, use the serve() thread to drive it to completion thus * blocking new connections. */ void TSimpleServer::onClientConnected(const shared_ptr& pClient) { pClient->run(); } /** * TSimpleServer does not track clients so there is nothing to do here. */ void TSimpleServer::onClientDisconnected(TConnectedClient*) { } /** * This makes little sense to the simple server because it is not capable * of having more than one client at a time, so we hide it. */ void TSimpleServer::setConcurrentClientLimit(int64_t) { } } } } // apache::thrift::server thrift-0.23.0/lib/cpp/src/thrift/server/TSimpleServer.h0000664000175000017500000000671015165535636023243 0ustar00buildbuild00000000000000/* * 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_SERVER_TSIMPLESERVER_H_ #define _THRIFT_SERVER_TSIMPLESERVER_H_ 1 #include namespace apache { namespace thrift { namespace server { /** * This is the most basic simple server. It is single-threaded and runs a * continuous loop of accepting a single connection, processing requests on * that connection until it closes, and then repeating. */ class TSimpleServer : public TServerFramework { public: TSimpleServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory); TSimpleServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory); TSimpleServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory); TSimpleServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory); ~TSimpleServer() override; protected: void onClientConnected(const std::shared_ptr& pClient) override /* override */; void onClientDisconnected(TConnectedClient* pClient) override /* override */; private: void setConcurrentClientLimit(int64_t newLimit) override; // hide }; } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TSIMPLESERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/server/TThreadPoolServer.h0000664000175000017500000001076015165535636024053 0ustar00buildbuild00000000000000/* * 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_SERVER_TTHREADPOOLSERVER_H_ #define _THRIFT_SERVER_TTHREADPOOLSERVER_H_ 1 #include #include #include namespace apache { namespace thrift { namespace server { /** * Manage clients using a thread pool. */ class TThreadPoolServer : public TServerFramework { public: TThreadPoolServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory, const std::shared_ptr& threadManager = apache::thrift::concurrency::ThreadManager::newSimpleThreadManager()); TThreadPoolServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory, const std::shared_ptr& threadManager = apache::thrift::concurrency::ThreadManager::newSimpleThreadManager()); TThreadPoolServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& threadManager = apache::thrift::concurrency::ThreadManager::newSimpleThreadManager()); TThreadPoolServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& threadManager = apache::thrift::concurrency::ThreadManager::newSimpleThreadManager()); ~TThreadPoolServer() override; /** * Post-conditions (return guarantees): * There will be no clients connected. */ void serve() override; virtual int64_t getTimeout() const; virtual void setTimeout(int64_t value); virtual int64_t getTaskExpiration() const; virtual void setTaskExpiration(int64_t value); virtual std::shared_ptr getThreadManager() const; protected: void onClientConnected(const std::shared_ptr& pClient) override /* override */; void onClientDisconnected(TConnectedClient* pClient) override /* override */; std::shared_ptr threadManager_; std::atomic timeout_; std::atomic taskExpiration_; }; } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TTHREADPOOLSERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/server/TNonblockingServer.h0000664000175000017500000007275515165535636024271 0ustar00buildbuild00000000000000/* * 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_SERVER_TNONBLOCKINGSERVER_H_ #define _THRIFT_SERVER_TNONBLOCKINGSERVER_H_ 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include namespace apache { namespace thrift { namespace server { using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TSocket; using apache::thrift::transport::TNonblockingServerTransport; using apache::thrift::protocol::TProtocol; using apache::thrift::concurrency::Runnable; using apache::thrift::concurrency::ThreadManager; using apache::thrift::concurrency::ThreadFactory; using apache::thrift::concurrency::Thread; using apache::thrift::concurrency::Mutex; using apache::thrift::concurrency::Guard; #ifdef LIBEVENT_VERSION_NUMBER #define LIBEVENT_VERSION_MAJOR (LIBEVENT_VERSION_NUMBER >> 24) #define LIBEVENT_VERSION_MINOR ((LIBEVENT_VERSION_NUMBER >> 16) & 0xFF) #define LIBEVENT_VERSION_REL ((LIBEVENT_VERSION_NUMBER >> 8) & 0xFF) #else // assume latest version 1 series #define LIBEVENT_VERSION_MAJOR 1 #define LIBEVENT_VERSION_MINOR 14 #define LIBEVENT_VERSION_REL 13 #define LIBEVENT_VERSION_NUMBER \ ((LIBEVENT_VERSION_MAJOR << 24) | (LIBEVENT_VERSION_MINOR << 16) | (LIBEVENT_VERSION_REL << 8)) #endif #if LIBEVENT_VERSION_NUMBER < 0x02000000 typedef THRIFT_SOCKET evutil_socket_t; #endif #ifndef SOCKOPT_CAST_T #ifndef _WIN32 #define SOCKOPT_CAST_T void #else #define SOCKOPT_CAST_T char #endif // _WIN32 #endif template inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v) { return reinterpret_cast(v); } template inline SOCKOPT_CAST_T* cast_sockopt(T* v) { return reinterpret_cast(v); } /** * This is a non-blocking server in C++ for high performance that * operates a set of IO threads (by default only one). It assumes that * all incoming requests are framed with a 4 byte length indicator and * writes out responses using the same framing. */ /// Overload condition actions. enum TOverloadAction { T_OVERLOAD_NO_ACTION, ///< Don't handle overload */ T_OVERLOAD_CLOSE_ON_ACCEPT, ///< Drop new connections immediately */ T_OVERLOAD_DRAIN_TASK_QUEUE ///< Drop some tasks from head of task queue */ }; class TNonblockingIOThread; class TNonblockingServer : public TServer { private: class TConnection; friend class TNonblockingIOThread; private: /// Listen backlog static const int LISTEN_BACKLOG = 1024; /// Default limit on size of idle connection pool static const size_t CONNECTION_STACK_LIMIT = 1024; /// Default limit on frame size static const int MAX_FRAME_SIZE = 256 * 1024 * 1024; /// Default limit on total number of connected sockets static const int MAX_CONNECTIONS = INT_MAX; /// Default limit on connections in handler/task processing static const int MAX_ACTIVE_PROCESSORS = INT_MAX; /// Default size of write buffer static const int WRITE_BUFFER_DEFAULT_SIZE = 1024; /// Maximum size of read buffer allocated to idle connection (0 = unlimited) static const int IDLE_READ_BUFFER_LIMIT = 1024; /// Maximum size of write buffer allocated to idle connection (0 = unlimited) static const int IDLE_WRITE_BUFFER_LIMIT = 1024; /// # of calls before resizing oversized buffers (0 = check only on close) static const int RESIZE_BUFFER_EVERY_N = 512; /// # of IO threads to use by default static const int DEFAULT_IO_THREADS = 1; /// # of IO threads this server will use size_t numIOThreads_; /// Whether to set high scheduling priority for IO threads bool useHighPriorityIOThreads_; /// Server socket file descriptor THRIFT_SOCKET serverSocket_; /// The optional user-provided event-base (for single-thread servers) event_base* userEventBase_; /// For processing via thread pool, may be nullptr std::shared_ptr threadManager_; /// Is thread pool processing? bool threadPoolProcessing_; // Factory to create the IO threads std::shared_ptr ioThreadFactory_; // Vector of IOThread objects that will handle our IO std::vector > ioThreads_; // Index of next IO Thread to be used (for round-robin) uint32_t nextIOThread_; // Synchronizes access to connection stack and similar data Mutex connMutex_; /// Number of TConnection object we've created size_t numTConnections_; /// Number of Connections processing or waiting to process size_t numActiveProcessors_; /// Limit for how many TConnection objects to cache size_t connectionStackLimit_; /// Limit for number of connections processing or waiting to process size_t maxActiveProcessors_; /// Limit for number of open connections size_t maxConnections_; /// Limit for frame size size_t maxFrameSize_; /// Time in milliseconds before an unperformed task expires (0 == infinite). int64_t taskExpireTime_; /** * Hysteresis for overload state. This is the fraction of the overload * value that needs to be reached before the overload state is cleared; * must be <= 1.0. */ double overloadHysteresis_; /// Action to take when we're overloaded. TOverloadAction overloadAction_; /** * The write buffer is initialized (and when idleWriteBufferLimit_ is checked * and found to be exceeded, reinitialized) to this size. */ size_t writeBufferDefaultSize_; /** * Max read buffer size for an idle TConnection. When we place an idle * TConnection into connectionStack_ or on every resizeBufferEveryN_ calls, * we will free the buffer (such that it will be reinitialized by the next * received frame) if it has exceeded this limit. 0 disables this check. */ size_t idleReadBufferLimit_; /** * Max write buffer size for an idle connection. When we place an idle * TConnection into connectionStack_ or on every resizeBufferEveryN_ calls, * we insure that its write buffer is <= to this size; otherwise we * replace it with a new one of writeBufferDefaultSize_ bytes to insure that * idle connections don't hog memory. 0 disables this check. */ size_t idleWriteBufferLimit_; /** * Every N calls we check the buffer size limits on a connected TConnection. * 0 disables (i.e. the checks are only done when a connection closes). */ int32_t resizeBufferEveryN_; /// Set if we are currently in an overloaded state. bool overloaded_; /// Count of connections dropped since overload started uint32_t nConnectionsDropped_; /// Count of connections dropped on overload since server started uint64_t nTotalConnectionsDropped_; /** * This is a stack of all the objects that have been created but that * are NOT currently in use. When we close a connection, we place it on this * stack so that the object can be reused later, rather than freeing the * memory and reallocating a new object later. */ std::stack connectionStack_; /** * This container holds pointers to all active connections. This container * allows the server to clean up unlcosed connection objects at destruction, * which in turn allows their transports, protocols, processors and handlers * to deallocate and clean up correctly. */ std::unordered_set activeConnections_; /* */ std::shared_ptr serverTransport_; /** * Called when server socket had something happen. We accept all waiting * client connections on listen socket fd and assign TConnection objects * to handle those requests. * * @param which the event flag that triggered the handler. */ void handleEvent(THRIFT_SOCKET fd, short which); void init() { serverSocket_ = THRIFT_INVALID_SOCKET; numIOThreads_ = DEFAULT_IO_THREADS; nextIOThread_ = 0; useHighPriorityIOThreads_ = false; userEventBase_ = nullptr; threadPoolProcessing_ = false; numTConnections_ = 0; numActiveProcessors_ = 0; connectionStackLimit_ = CONNECTION_STACK_LIMIT; maxActiveProcessors_ = MAX_ACTIVE_PROCESSORS; maxConnections_ = MAX_CONNECTIONS; maxFrameSize_ = MAX_FRAME_SIZE; taskExpireTime_ = 0; overloadHysteresis_ = 0.8; overloadAction_ = T_OVERLOAD_NO_ACTION; writeBufferDefaultSize_ = WRITE_BUFFER_DEFAULT_SIZE; idleReadBufferLimit_ = IDLE_READ_BUFFER_LIMIT; idleWriteBufferLimit_ = IDLE_WRITE_BUFFER_LIMIT; resizeBufferEveryN_ = RESIZE_BUFFER_EVERY_N; overloaded_ = false; nConnectionsDropped_ = 0; nTotalConnectionsDropped_ = 0; } public: TNonblockingServer(const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport) : TServer(processorFactory), serverTransport_(serverTransport) { init(); } TNonblockingServer(const std::shared_ptr& processor, const std::shared_ptr& serverTransport) : TServer(processor), serverTransport_(serverTransport) { init(); } TNonblockingServer(const std::shared_ptr& processorFactory, const std::shared_ptr& protocolFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& threadManager = std::shared_ptr()) : TServer(processorFactory), serverTransport_(serverTransport) { init(); setInputProtocolFactory(protocolFactory); setOutputProtocolFactory(protocolFactory); setThreadManager(threadManager); } TNonblockingServer(const std::shared_ptr& processor, const std::shared_ptr& protocolFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& threadManager = std::shared_ptr()) : TServer(processor), serverTransport_(serverTransport) { init(); setInputProtocolFactory(protocolFactory); setOutputProtocolFactory(protocolFactory); setThreadManager(threadManager); } TNonblockingServer(const std::shared_ptr& processorFactory, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& threadManager = std::shared_ptr()) : TServer(processorFactory), serverTransport_(serverTransport) { init(); setInputTransportFactory(inputTransportFactory); setOutputTransportFactory(outputTransportFactory); setInputProtocolFactory(inputProtocolFactory); setOutputProtocolFactory(outputProtocolFactory); setThreadManager(threadManager); } TNonblockingServer(const std::shared_ptr& processor, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& threadManager = std::shared_ptr()) : TServer(processor), serverTransport_(serverTransport) { init(); setInputTransportFactory(inputTransportFactory); setOutputTransportFactory(outputTransportFactory); setInputProtocolFactory(inputProtocolFactory); setOutputProtocolFactory(outputProtocolFactory); setThreadManager(threadManager); } ~TNonblockingServer() override; void setThreadManager(std::shared_ptr threadManager); int getListenPort() { return serverTransport_->getListenPort(); } std::shared_ptr getThreadManager() { return threadManager_; } /** * Sets the number of IO threads used by this server. Can only be used before * the call to serve() and has no effect afterwards. */ void setNumIOThreads(size_t numThreads) { numIOThreads_ = numThreads; // User-provided event-base doesn't works for multi-threaded servers assert(numIOThreads_ <= 1 || !userEventBase_); } /** Return whether the IO threads will get high scheduling priority */ bool useHighPriorityIOThreads() const { return useHighPriorityIOThreads_; } /** Set whether the IO threads will get high scheduling priority. */ void setUseHighPriorityIOThreads(bool val) { useHighPriorityIOThreads_ = val; } /** Return the number of IO threads used by this server. */ size_t getNumIOThreads() const { return numIOThreads_; } /** * Get the maximum number of unused TConnection we will hold in reserve. * * @return the current limit on TConnection pool size. */ size_t getConnectionStackLimit() const { return connectionStackLimit_; } /** * Set the maximum number of unused TConnection we will hold in reserve. * * @param sz the new limit for TConnection pool size. */ void setConnectionStackLimit(size_t sz) { connectionStackLimit_ = sz; } bool isThreadPoolProcessing() const { return threadPoolProcessing_; } void addTask(std::shared_ptr task) { threadManager_->add(task, 0LL, taskExpireTime_); } /** * Return the count of sockets currently connected to. * * @return count of connected sockets. */ size_t getNumConnections() const { return numTConnections_; } /** * Return the count of sockets currently connected to. * * @return count of connected sockets. */ size_t getNumActiveConnections() const { return getNumConnections() - getNumIdleConnections(); } /** * Return the count of connection objects allocated but not in use. * * @return count of idle connection objects. */ size_t getNumIdleConnections() const { return connectionStack_.size(); } /** * Return count of number of connections which are currently processing. * This is defined as a connection where all data has been received and * either assigned a task (when threading) or passed to a handler (when * not threading), and where the handler has not yet returned. * * @return # of connections currently processing. */ size_t getNumActiveProcessors() const { return numActiveProcessors_; } /// Increment the count of connections currently processing. void incrementActiveProcessors() { Guard g(connMutex_); ++numActiveProcessors_; } /// Decrement the count of connections currently processing. void decrementActiveProcessors() { Guard g(connMutex_); if (numActiveProcessors_ > 0) { --numActiveProcessors_; } } /** * Get the maximum # of connections allowed before overload. * * @return current setting. */ size_t getMaxConnections() const { return maxConnections_; } /** * Set the maximum # of connections allowed before overload. * * @param maxConnections new setting for maximum # of connections. */ void setMaxConnections(size_t maxConnections) { maxConnections_ = maxConnections; } /** * Get the maximum # of connections waiting in handler/task before overload. * * @return current setting. */ size_t getMaxActiveProcessors() const { return maxActiveProcessors_; } /** * Set the maximum # of connections waiting in handler/task before overload. * * @param maxActiveProcessors new setting for maximum # of active processes. */ void setMaxActiveProcessors(size_t maxActiveProcessors) { maxActiveProcessors_ = maxActiveProcessors; } /** * Get the maximum allowed frame size. * * If a client tries to send a message larger than this limit, * its connection will be closed. * * @return Maxium frame size, in bytes. */ size_t getMaxFrameSize() const { return maxFrameSize_; } /** * Set the maximum allowed frame size. * * @param maxFrameSize The new maximum frame size. */ void setMaxFrameSize(size_t maxFrameSize) { maxFrameSize_ = maxFrameSize; } /** * Get fraction of maximum limits before an overload condition is cleared. * * @return hysteresis fraction */ double getOverloadHysteresis() const { return overloadHysteresis_; } /** * Set fraction of maximum limits before an overload condition is cleared. * A good value would probably be between 0.5 and 0.9. * * @param hysteresisFraction fraction <= 1.0. */ void setOverloadHysteresis(double hysteresisFraction) { if (hysteresisFraction <= 1.0 && hysteresisFraction > 0.0) { overloadHysteresis_ = hysteresisFraction; } } /** * Get the action the server will take on overload. * * @return a TOverloadAction enum value for the currently set action. */ TOverloadAction getOverloadAction() const { return overloadAction_; } /** * Set the action the server is to take on overload. * * @param overloadAction a TOverloadAction enum value for the action. */ void setOverloadAction(TOverloadAction overloadAction) { overloadAction_ = overloadAction; } /** * Get the time in milliseconds after which a task expires (0 == infinite). * * @return a 64-bit time in milliseconds. */ int64_t getTaskExpireTime() const { return taskExpireTime_; } /** * Set the time in milliseconds after which a task expires (0 == infinite). * * @param taskExpireTime a 64-bit time in milliseconds. */ void setTaskExpireTime(int64_t taskExpireTime) { taskExpireTime_ = taskExpireTime; } /** * Determine if the server is currently overloaded. * This function checks the maximums for open connections and connections * currently in processing, and sets an overload condition if they are * exceeded. The overload will persist until both values are below the * current hysteresis fraction of their maximums. * * @return true if an overload condition exists, false if not. */ bool serverOverloaded(); /** Pop and discard next task on threadpool wait queue. * * @return true if a task was discarded, false if the wait queue was empty. */ bool drainPendingTask(); /** * Get the starting size of a TConnection object's write buffer. * * @return # bytes we initialize a TConnection object's write buffer to. */ size_t getWriteBufferDefaultSize() const { return writeBufferDefaultSize_; } /** * Set the starting size of a TConnection object's write buffer. * * @param size # bytes we initialize a TConnection object's write buffer to. */ void setWriteBufferDefaultSize(size_t size) { writeBufferDefaultSize_ = size; } /** * Get the maximum size of read buffer allocated to idle TConnection objects. * * @return # bytes beyond which we will dealloc idle buffer. */ size_t getIdleReadBufferLimit() const { return idleReadBufferLimit_; } /** * [NOTE: This is for backwards compatibility, use getIdleReadBufferLimit().] * Get the maximum size of read buffer allocated to idle TConnection objects. * * @return # bytes beyond which we will dealloc idle buffer. */ size_t getIdleBufferMemLimit() const { return idleReadBufferLimit_; } /** * Set the maximum size read buffer allocated to idle TConnection objects. * If a TConnection object is found (either on connection close or between * calls when resizeBufferEveryN_ is set) with more than this much memory * allocated to its read buffer, we free it and allow it to be reinitialized * on the next received frame. * * @param limit of bytes beyond which we will shrink buffers when checked. */ void setIdleReadBufferLimit(size_t limit) { idleReadBufferLimit_ = limit; } /** * [NOTE: This is for backwards compatibility, use setIdleReadBufferLimit().] * Set the maximum size read buffer allocated to idle TConnection objects. * If a TConnection object is found (either on connection close or between * calls when resizeBufferEveryN_ is set) with more than this much memory * allocated to its read buffer, we free it and allow it to be reinitialized * on the next received frame. * * @param limit of bytes beyond which we will shrink buffers when checked. */ void setIdleBufferMemLimit(size_t limit) { idleReadBufferLimit_ = limit; } /** * Get the maximum size of write buffer allocated to idle TConnection objects. * * @return # bytes beyond which we will reallocate buffers when checked. */ size_t getIdleWriteBufferLimit() const { return idleWriteBufferLimit_; } /** * Set the maximum size write buffer allocated to idle TConnection objects. * If a TConnection object is found (either on connection close or between * calls when resizeBufferEveryN_ is set) with more than this much memory * allocated to its write buffer, we destroy and construct that buffer with * writeBufferDefaultSize_ bytes. * * @param limit of bytes beyond which we will shrink buffers when idle. */ void setIdleWriteBufferLimit(size_t limit) { idleWriteBufferLimit_ = limit; } /** * Get # of calls made between buffer size checks. 0 means disabled. * * @return # of calls between buffer size checks. */ int32_t getResizeBufferEveryN() const { return resizeBufferEveryN_; } /** * Check buffer sizes every "count" calls. This allows buffer limits * to be enforced for persistent connections with a controllable degree * of overhead. 0 disables checks except at connection close. * * @param count the number of calls between checks, or 0 to disable */ void setResizeBufferEveryN(int32_t count) { resizeBufferEveryN_ = count; } /** * Main workhorse function, starts up the server listening on a port and * loops over the libevent handler. */ void serve() override; /** * Causes the server to terminate gracefully (can be called from any thread). */ void stop() override; /// Creates a socket to listen on and binds it to the local port. void createAndListenOnSocket(); /** * Register the optional user-provided event-base (for single-thread servers) * * This method should be used when the server is running in a single-thread * mode, and the event base is provided by the user (i.e., the caller). * * @param user_event_base the user-provided event-base. The user is * responsible for freeing the event base memory. */ void registerEvents(event_base* user_event_base); /** * Returns the optional user-provided event-base (for single-thread servers). */ event_base* getUserEventBase() const { return userEventBase_; } /** Some transports, like THeaderTransport, require passing through * the framing size instead of stripping it. */ bool getHeaderTransport(); private: /** * Callback function that the threadmanager calls when a task reaches * its expiration time. It is needed to clean up the expired connection. * * @param task the runnable associated with the expired task. */ void expireClose(std::shared_ptr task); /** * Return an initialized connection object. Creates or recovers from * pool a TConnection and initializes it with the provided socket FD * and flags. * * @param socket FD of socket associated with this connection. * @param addr the sockaddr of the client * @param addrLen the length of addr * @return pointer to initialized TConnection object. */ TConnection* createConnection(std::shared_ptr socket); /** * Returns a connection to pool or deletion. If the connection pool * (a stack) isn't full, place the connection object on it, otherwise * just delete it. * * @param connection the TConection being returned. */ void returnConnection(TConnection* connection); }; class TNonblockingIOThread : public Runnable { public: // Creates an IO thread and sets up the event base. The listenSocket should // be a valid FD on which listen() has already been called. If the // listenSocket is < 0, accepting will not be done. TNonblockingIOThread(TNonblockingServer* server, int number, THRIFT_SOCKET listenSocket, bool useHighPriority); ~TNonblockingIOThread() override; // Returns the event-base for this thread. event_base* getEventBase() const { return eventBase_; } // Returns the server for this thread. TNonblockingServer* getServer() const { return server_; } // Returns the number of this IO thread. int getThreadNumber() const { return number_; } // Returns the thread id associated with this object. This should // only be called after the thread has been started. Thread::id_t getThreadId() const { return threadId_; } // Returns the send-fd for task complete notifications. evutil_socket_t getNotificationSendFD() const { return notificationPipeFDs_[1]; } // Returns the read-fd for task complete notifications. evutil_socket_t getNotificationRecvFD() const { return notificationPipeFDs_[0]; } // Returns the actual thread object associated with this IO thread. std::shared_ptr getThread() const { return thread_; } // Sets the actual thread object associated with this IO thread. void setThread(const std::shared_ptr& t) { thread_ = t; } // Used by TConnection objects to indicate processing has finished. bool notify(TNonblockingServer::TConnection* conn); // Enters the event loop and does not return until a call to stop(). void run() override; // Exits the event loop as soon as possible. void stop(); // Ensures that the event-loop thread is fully finished and shut down. void join(); /// Registers the events for the notification & listen sockets void registerEvents(); private: /** * C-callable event handler for signaling task completion. Provides a * callback that libevent can understand that will read a connection * object's address from a pipe and call connection->transition() for * that object. * * @param fd the descriptor the event occurred on. */ static void notifyHandler(evutil_socket_t fd, short which, void* v); /** * C-callable event handler for listener events. Provides a callback * that libevent can understand which invokes server->handleEvent(). * * @param fd the descriptor the event occurred on. * @param which the flags associated with the event. * @param v void* callback arg where we placed TNonblockingServer's "this". */ static void listenHandler(evutil_socket_t fd, short which, void* v) { ((TNonblockingServer*)v)->handleEvent(fd, which); } /// Exits the loop ASAP in case of shutdown or error. void breakLoop(bool error); /// Create the pipe used to notify I/O process of task completion. void createNotificationPipe(); /// Unregisters our events for notification and listen sockets. void cleanupEvents(); /// Sets (or clears) high priority scheduling status for the current thread. void setCurrentThreadHighPriority(bool value); private: /// associated server TNonblockingServer* server_; /// thread number (for debugging). const int number_; /// The actual physical thread id. Thread::id_t threadId_; /// If listenSocket_ >= 0, adds an event on the event_base to accept conns THRIFT_SOCKET listenSocket_; /// Sets a high scheduling priority when running bool useHighPriority_; /// pointer to eventbase to be used for looping event_base* eventBase_; /// Set to true if this class is responsible for freeing the event base /// memory. bool ownEventBase_; /// Used with eventBase_ for connection events (only in listener thread) struct event serverEvent_; /// Used with eventBase_ for task completion notification struct event notificationEvent_; /// File descriptors for pipe used for task completion notification. evutil_socket_t notificationPipeFDs_[2]; /// Actual IO Thread std::shared_ptr thread_; }; } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TNONBLOCKINGSERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/server/TServerFramework.cpp0000664000175000017500000002075715167543515024306 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace server { using apache::thrift::concurrency::Synchronized; using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using std::bind; using std::shared_ptr; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TTransportFactory; using std::string; TServerFramework::TServerFramework(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory) : TServer(processorFactory, serverTransport, transportFactory, protocolFactory), clients_(0), hwm_(0), limit_(INT64_MAX) { } TServerFramework::TServerFramework(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& transportFactory, const shared_ptr& protocolFactory) : TServer(processor, serverTransport, transportFactory, protocolFactory), clients_(0), hwm_(0), limit_(INT64_MAX) { } TServerFramework::TServerFramework(const shared_ptr& processorFactory, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory) : TServer(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory), clients_(0), hwm_(0), limit_(INT64_MAX) { } TServerFramework::TServerFramework(const shared_ptr& processor, const shared_ptr& serverTransport, const shared_ptr& inputTransportFactory, const shared_ptr& outputTransportFactory, const shared_ptr& inputProtocolFactory, const shared_ptr& outputProtocolFactory) : TServer(processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory), clients_(0), hwm_(0), limit_(INT64_MAX) { } TServerFramework::~TServerFramework() = default; template static void releaseOneDescriptor(const string& name, T& pTransport) { if (pTransport) { try { pTransport->close(); } catch (const TTransportException& ttx) { string errStr = string("TServerFramework " + name + " close failed: ") + ttx.what(); TOutput::instance()(errStr.c_str()); } } } void TServerFramework::serve() { shared_ptr client; shared_ptr inputTransport; shared_ptr outputTransport; shared_ptr inputProtocol; shared_ptr outputProtocol; // Start the server listening serverTransport_->listen(); // Run the preServe event to indicate server is now listening // and that it is safe to connect. if (eventHandler_) { eventHandler_->preServe(); } // Fetch client from server for (;;) { try { // Dereference any resources from any previous client creation // such that a blocking accept does not hold them indefinitely. outputProtocol.reset(); inputProtocol.reset(); outputTransport.reset(); inputTransport.reset(); client.reset(); // If we have reached the limit on the number of concurrent // clients allowed, wait for one or more clients to drain before // accepting another. { Synchronized sync(mon_); while (clients_ >= limit_) { mon_.wait(); } } client = serverTransport_->accept(); inputTransport = inputTransportFactory_->getTransport(client); outputTransport = outputTransportFactory_->getTransport(client); if (!outputProtocolFactory_) { inputProtocol = inputProtocolFactory_->getProtocol(inputTransport, outputTransport); outputProtocol = inputProtocol; } else { inputProtocol = inputProtocolFactory_->getProtocol(inputTransport); outputProtocol = outputProtocolFactory_->getProtocol(outputTransport); } newlyConnectedClient(shared_ptr( new TConnectedClient(getProcessor(inputProtocol, outputProtocol, client), inputProtocol, outputProtocol, eventHandler_, client), bind(&TServerFramework::disposeConnectedClient, this, std::placeholders::_1))); } catch (TTransportException& ttx) { releaseOneDescriptor("inputTransport", inputTransport); releaseOneDescriptor("outputTransport", outputTransport); releaseOneDescriptor("client", client); if (ttx.getType() == TTransportException::TIMED_OUT || ttx.getType() == TTransportException::CLIENT_DISCONNECT) { // Accept timeout and client disconnect - continue processing. continue; } else if (ttx.getType() == TTransportException::END_OF_FILE || ttx.getType() == TTransportException::INTERRUPTED) { // Server was interrupted. This only happens when stopping. break; } else { // All other transport exceptions are logged. // State of connection is unknown. Done. string errStr = string("TServerTransport died: ") + ttx.what(); TOutput::instance()(errStr.c_str()); break; } } } releaseOneDescriptor("serverTransport", serverTransport_); } int64_t TServerFramework::getConcurrentClientLimit() const { Synchronized sync(mon_); return limit_; } int64_t TServerFramework::getConcurrentClientCount() const { Synchronized sync(mon_); return clients_; } int64_t TServerFramework::getConcurrentClientCountHWM() const { Synchronized sync(mon_); return hwm_; } void TServerFramework::setConcurrentClientLimit(int64_t newLimit) { if (newLimit < 1) { throw std::invalid_argument("newLimit must be greater than zero"); } Synchronized sync(mon_); limit_ = newLimit; if (limit_ - clients_ > 0) { mon_.notify(); } } void TServerFramework::stop() { // Order is important because serve() releases serverTransport_ when it is // interrupted, which closes the socket that interruptChildren uses. serverTransport_->interruptChildren(); serverTransport_->interrupt(); } void TServerFramework::newlyConnectedClient(const shared_ptr& pClient) { { Synchronized sync(mon_); ++clients_; hwm_ = (std::max)(hwm_, clients_); } onClientConnected(pClient); } void TServerFramework::disposeConnectedClient(TConnectedClient* pClient) { onClientDisconnected(pClient); delete pClient; Synchronized sync(mon_); if (limit_ - --clients_ > 0) { mon_.notify(); } } } } } // apache::thrift::server thrift-0.23.0/lib/cpp/src/thrift/server/TServerFramework.h0000664000175000017500000001542615165535636023753 0ustar00buildbuild00000000000000/* * 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_SERVER_TSERVERFRAMEWORK_H_ #define _THRIFT_SERVER_TSERVERFRAMEWORK_H_ 1 #include #include #include #include #include #include #include #include namespace apache { namespace thrift { namespace server { /** * TServerFramework provides a single consolidated processing loop for * servers. By having a single processing loop, behavior between servers * is more predictable and maintenance cost is lowered. Implementations * of TServerFramework must provide a method to deal with a client that * connects and one that disconnects. * * While this functionality could be rolled directly into TServer, and * probably should be, it would break the TServer interface contract so * to maintain backwards compatibility for third party servers, no TServers * were harmed in the making of this class. */ class TServerFramework : public TServer { public: TServerFramework( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory); TServerFramework( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory); TServerFramework( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory); TServerFramework( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory); ~TServerFramework() override; /** * Accept clients from the TServerTransport and add them for processing. * Call stop() on another thread to interrupt processing * and return control to the caller. * Post-conditions (return guarantees): * The serverTransport will be closed. */ void serve() override; /** * Interrupt serve() so that it meets post-conditions and returns. */ void stop() override; /** * Get the concurrent client limit. * \returns the concurrent client limit */ virtual int64_t getConcurrentClientLimit() const; /** * Get the number of currently connected clients. * \returns the number of currently connected clients */ virtual int64_t getConcurrentClientCount() const; /** * Get the highest number of concurrent clients. * \returns the highest number of concurrent clients */ virtual int64_t getConcurrentClientCountHWM() const; /** * Set the concurrent client limit. This can be changed while * the server is serving however it will not necessarily be * enforced until the next client is accepted and added. If the * limit is lowered below the number of connected clients, no * action is taken to disconnect the clients. * The default value used if this is not called is INT64_MAX. * \param[in] newLimit the new limit of concurrent clients * \throws std::invalid_argument if newLimit is less than 1 */ virtual void setConcurrentClientLimit(int64_t newLimit); protected: /** * A client has connected. The implementation is responsible for managing the * lifetime of the client object. This is called during the serve() thread, * therefore a failure to return quickly will result in new client connection * delays. * * \param[in] pClient the newly connected client */ virtual void onClientConnected(const std::shared_ptr& pClient) = 0; /** * A client has disconnected. * When called: * The server no longer tracks the client. * The client TTransport has already been closed. * The implementation must not delete the pointer. * * \param[in] pClient the disconnected client */ virtual void onClientDisconnected(TConnectedClient* pClient) = 0; private: /** * Common handling for new connected clients. Implements concurrent * client rate limiting after onClientConnected returns by blocking the * serve() thread if the limit has been reached. */ void newlyConnectedClient(const std::shared_ptr& pClient); /** * Smart pointer client deletion. * Calls onClientDisconnected and then deletes pClient. */ void disposeConnectedClient(TConnectedClient* pClient); /** * Monitor for limiting the number of concurrent clients. */ apache::thrift::concurrency::Monitor mon_; /** * The number of concurrent clients. */ int64_t clients_; /** * The high water mark of concurrent clients. */ int64_t hwm_; /** * The limit on the number of concurrent clients. */ int64_t limit_; }; } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TSERVERFRAMEWORK_H_ thrift-0.23.0/lib/cpp/src/thrift/server/TNonblockingServer.cpp0000664000175000017500000013443215167543515024610 0ustar00buildbuild00000000000000/* * 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 #include #include #include #ifdef HAVE_POLL_H #include #elif HAVE_SYS_POLL_H #include #elif HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #include #ifdef HAVE_SCHED_H #include #endif #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif #ifdef HAVE_INTTYPES_H #include #endif #ifdef HAVE_STDINT_H #include #endif namespace apache { namespace thrift { namespace server { using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace apache::thrift::concurrency; using apache::thrift::transport::TSocket; using apache::thrift::transport::TTransportException; using std::shared_ptr; /// Three states for sockets: recv frame size, recv data, and send mode enum TSocketState { SOCKET_RECV_FRAMING, SOCKET_RECV, SOCKET_SEND }; /** * Five states for the nonblocking server: * 1) initialize * 2) read 4 byte frame size * 3) read frame of data * 4) send back data (if any) * 5) force immediate connection close */ enum TAppState { APP_INIT, APP_READ_FRAME_SIZE, APP_READ_REQUEST, APP_WAIT_TASK, APP_SEND_RESULT, APP_CLOSE_CONNECTION }; /** * Represents a connection that is handled via libevent. This connection * essentially encapsulates a socket that has some associated libevent state. */ class TNonblockingServer::TConnection { private: /// Server IO Thread handling this connection TNonblockingIOThread* ioThread_; /// Server handle TNonblockingServer* server_; /// TProcessor std::shared_ptr processor_; /// Object wrapping network socket std::shared_ptr tSocket_; /// Libevent object struct event event_; /// Libevent flags short eventFlags_; /// Socket mode TSocketState socketState_; /// Application state TAppState appState_; /// How much data needed to read uint32_t readWant_; /// Where in the read buffer are we uint32_t readBufferPos_; /// Read buffer uint8_t* readBuffer_; /// Read buffer size uint32_t readBufferSize_; /// Write buffer uint8_t* writeBuffer_; /// Write buffer size uint32_t writeBufferSize_; /// How far through writing are we? uint32_t writeBufferPos_; /// Largest size of write buffer seen since buffer was constructed size_t largestWriteBufferSize_; /// Count of the number of calls for use with getResizeBufferEveryN(). int32_t callsForResize_; /// Transport to read from std::shared_ptr inputTransport_; /// Transport that processor writes to std::shared_ptr outputTransport_; /// extra transport generated by transport factory (e.g. BufferedRouterTransport) std::shared_ptr factoryInputTransport_; std::shared_ptr factoryOutputTransport_; /// Protocol decoder std::shared_ptr inputProtocol_; /// Protocol encoder std::shared_ptr outputProtocol_; /// Server event handler, if any std::shared_ptr serverEventHandler_; /// Thrift call context, if any void* connectionContext_; /// Go into read mode void setRead() { setFlags(EV_READ | EV_PERSIST); } /// Go into write mode void setWrite() { setFlags(EV_WRITE | EV_PERSIST); } /// Set socket idle void setIdle() { setFlags(0); } /** * Set event flags for this connection. * * @param eventFlags flags we pass to libevent for the connection. */ void setFlags(short eventFlags); /** * Libevent handler called (via our static wrapper) when the connection * socket had something happen. Rather than use the flags libevent passed, * we use the connection state to determine whether we need to read or * write the socket. */ void workSocket(); public: class Task; /// Constructor TConnection(std::shared_ptr socket, TNonblockingIOThread* ioThread) { readBuffer_ = nullptr; readBufferSize_ = 0; ioThread_ = ioThread; server_ = ioThread->getServer(); // Allocate input and output transports these only need to be allocated // once per TConnection (they don't need to be reallocated on init() call) inputTransport_.reset(new TMemoryBuffer(readBuffer_, readBufferSize_)); outputTransport_.reset( new TMemoryBuffer(static_cast(server_->getWriteBufferDefaultSize()))); tSocket_ = socket; init(ioThread); } ~TConnection() { std::free(readBuffer_); } /// Close this connection and free or reset its resources. void close(); /** * Check buffers against any size limits and shrink it if exceeded. * * @param readLimit we reduce read buffer size to this (if nonzero). * @param writeLimit if nonzero and write buffer is larger, replace it. */ void checkIdleBufferMemLimit(size_t readLimit, size_t writeLimit); /// Initialize void init(TNonblockingIOThread* ioThread); /// set socket for connection void setSocket(std::shared_ptr socket); /** * This is called when the application transitions from one state into * another. This means that it has finished writing the data that it needed * to, or finished receiving the data that it needed to. */ void transition(); /** * C-callable event handler for connection events. Provides a callback * that libevent can understand which invokes connection_->workSocket(). * * @param fd the descriptor the event occurred on. * @param which the flags associated with the event. * @param v void* callback arg where we placed TConnection's "this". */ static void eventHandler(evutil_socket_t fd, short /* which */, void* v) { assert(fd == static_cast(((TConnection*)v)->getTSocket()->getSocketFD())); ((TConnection*)v)->workSocket(); } /** * Notification to server that processing has ended on this request. * Can be called either when processing is completed or when a waiting * task has been preemptively terminated (on overload). * * Don't call this from the IO thread itself. * * @return true if successful, false if unable to notify (check THRIFT_GET_SOCKET_ERROR). */ bool notifyIOThread() { return ioThread_->notify(this); } /* * Returns the number of this connection's currently assigned IO * thread. */ int getIOThreadNumber() const { return ioThread_->getThreadNumber(); } /// Force connection shutdown for this connection. void forceClose() { appState_ = APP_CLOSE_CONNECTION; if (!notifyIOThread()) { server_->decrementActiveProcessors(); close(); throw TException("TConnection::forceClose: failed write on notify pipe"); } } /// return the server this connection was initialized for. TNonblockingServer* getServer() const { return server_; } /// get state of connection. TAppState getState() const { return appState_; } /// return the TSocket transport wrapping this network connection std::shared_ptr getTSocket() const { return tSocket_; } /// return the server event handler if any std::shared_ptr getServerEventHandler() { return serverEventHandler_; } /// return the Thrift connection context if any void* getConnectionContext() { return connectionContext_; } }; class TNonblockingServer::TConnection::Task : public Runnable { public: Task(std::shared_ptr processor, std::shared_ptr input, std::shared_ptr output, TConnection* connection) : processor_(processor), input_(input), output_(output), connection_(connection), serverEventHandler_(connection_->getServerEventHandler()), connectionContext_(connection_->getConnectionContext()) {} void run() override { try { for (;;) { if (serverEventHandler_) { serverEventHandler_->processContext(connectionContext_, connection_->getTSocket()); } if (!processor_->process(input_, output_, connectionContext_) || !input_->getTransport()->peek()) { break; } } } catch (const TTransportException& ttx) { TOutput::instance().printf("TNonblockingServer: client died: %s", ttx.what()); } catch (const std::bad_alloc&) { TOutput::instance()("TNonblockingServer: caught bad_alloc exception."); exit(1); } catch (const std::exception& x) { TOutput::instance().printf("TNonblockingServer: process() exception: %s: %s", typeid(x).name(), x.what()); } catch (...) { TOutput::instance().printf("TNonblockingServer: unknown exception while processing."); } // Signal completion back to the libevent thread via a pipe if (!connection_->notifyIOThread()) { TOutput::instance().printf("TNonblockingServer: failed to notifyIOThread, closing."); connection_->server_->decrementActiveProcessors(); connection_->close(); throw TException("TNonblockingServer::Task::run: failed write on notify pipe"); } } TConnection* getTConnection() { return connection_; } private: std::shared_ptr processor_; std::shared_ptr input_; std::shared_ptr output_; TConnection* connection_; std::shared_ptr serverEventHandler_; void* connectionContext_; }; void TNonblockingServer::TConnection::init(TNonblockingIOThread* ioThread) { ioThread_ = ioThread; server_ = ioThread->getServer(); appState_ = APP_INIT; eventFlags_ = 0; readBufferPos_ = 0; readWant_ = 0; writeBuffer_ = nullptr; writeBufferSize_ = 0; writeBufferPos_ = 0; largestWriteBufferSize_ = 0; socketState_ = SOCKET_RECV_FRAMING; callsForResize_ = 0; // get input/transports factoryInputTransport_ = server_->getInputTransportFactory()->getTransport(inputTransport_); factoryOutputTransport_ = server_->getOutputTransportFactory()->getTransport(outputTransport_); // Create protocol if (server_->getHeaderTransport()) { inputProtocol_ = server_->getInputProtocolFactory()->getProtocol(factoryInputTransport_, factoryOutputTransport_); outputProtocol_ = inputProtocol_; } else { inputProtocol_ = server_->getInputProtocolFactory()->getProtocol(factoryInputTransport_); outputProtocol_ = server_->getOutputProtocolFactory()->getProtocol(factoryOutputTransport_); } // Set up for any server event handler serverEventHandler_ = server_->getEventHandler(); if (serverEventHandler_) { connectionContext_ = serverEventHandler_->createContext(inputProtocol_, outputProtocol_); } else { connectionContext_ = nullptr; } // Get the processor processor_ = server_->getProcessor(inputProtocol_, outputProtocol_, tSocket_); } void TNonblockingServer::TConnection::setSocket(std::shared_ptr socket) { tSocket_ = socket; } void TNonblockingServer::TConnection::workSocket() { while (true) { int got = 0, left = 0, sent = 0; uint32_t fetch = 0; switch (socketState_) { case SOCKET_RECV_FRAMING: union { uint8_t buf[sizeof(uint32_t)]; uint32_t size; } framing; // if we've already received some bytes we kept them here framing.size = readWant_; // determine size of this frame try { // Read from the socket fetch = tSocket_->read(&framing.buf[readBufferPos_], uint32_t(sizeof(framing.size) - readBufferPos_)); if (fetch == 0) { // Whenever we get here it means a remote disconnect close(); return; } readBufferPos_ += fetch; } catch (TTransportException& te) { //In Nonblocking SSLSocket some operations need to be retried again. //Current approach is parsing exception message, but a better solution needs to be investigated. if(!strstr(te.what(), "retry")) { TOutput::instance().printf("TConnection::workSocket(): %s", te.what()); close(); return; } } if (readBufferPos_ < sizeof(framing.size)) { // more needed before frame size is known -- save what we have so far readWant_ = framing.size; return; } readWant_ = ntohl(framing.size); if (readWant_ > server_->getMaxFrameSize()) { // Don't allow giant frame sizes. This prevents bad clients from // causing us to try and allocate a giant buffer. TOutput::instance().printf( "TNonblockingServer: frame size too large " "(%" PRIu32 " > %" PRIu64 ") from client %s. " "Remote side not using TFramedTransport?", readWant_, (uint64_t)server_->getMaxFrameSize(), tSocket_->getSocketInfo().c_str()); close(); return; } // size known; now get the rest of the frame transition(); // If the socket has more data than the frame header, continue to work on it. This is not strictly necessary for // regular sockets, because if there is more data, libevent will fire the event handler registered for read // readiness, which will in turn call workSocket(). However, some socket types (such as TSSLSocket) may have the // data sitting in their internal buffers and from libevent's perspective, there is no further data available. In // that case, not trying another processing cycle here would result in a hang as we will never get to work the socket, // despite having more data. if (tSocket_->hasPendingDataToRead()) { continue; } return; case SOCKET_RECV: // It is an error to be in this state if we already have all the data if (!(readBufferPos_ < readWant_)) { TOutput::instance().printf("TNonblockingServer: frame size too short"); close(); return; } try { // Read from the socket fetch = readWant_ - readBufferPos_; got = tSocket_->read(readBuffer_ + readBufferPos_, fetch); } catch (TTransportException& te) { //In Nonblocking SSLSocket some operations need to be retried again. //Current approach is parsing exception message, but a better solution needs to be investigated. if(!strstr(te.what(), "retry")) { TOutput::instance().printf("TConnection::workSocket(): %s", te.what()); close(); } return; } if (got > 0) { // Move along in the buffer readBufferPos_ += got; // Check that we did not overdo it assert(readBufferPos_ <= readWant_); // We are done reading, move onto the next state if (readBufferPos_ == readWant_) { transition(); if (socketState_ == SOCKET_RECV_FRAMING && tSocket_->hasPendingDataToRead()) { continue; } } return; } // Whenever we get down here it means a remote disconnect close(); return; case SOCKET_SEND: // Should never have position past size assert(writeBufferPos_ <= writeBufferSize_); // If there is no data to send, then let us move on if (writeBufferPos_ == writeBufferSize_) { TOutput::instance()("WARNING: Send state with no data to send"); transition(); return; } try { left = writeBufferSize_ - writeBufferPos_; sent = tSocket_->write_partial(writeBuffer_ + writeBufferPos_, left); } catch (TTransportException& te) { TOutput::instance().printf("TConnection::workSocket(): %s ", te.what()); close(); return; } writeBufferPos_ += sent; // Did we overdo it? assert(writeBufferPos_ <= writeBufferSize_); // We are done! if (writeBufferPos_ == writeBufferSize_) { transition(); } return; default: TOutput::instance().printf("Unexpected Socket State %d", socketState_); assert(0); return; } } } bool TNonblockingServer::getHeaderTransport() { // Currently if there is no output protocol factory, // we assume header transport (without having to create // a new transport and check) return getOutputProtocolFactory() == nullptr; } /** * This is called when the application transitions from one state into * another. This means that it has finished writing the data that it needed * to, or finished receiving the data that it needed to. */ void TNonblockingServer::TConnection::transition() { // ensure this connection is active right now assert(ioThread_); assert(server_); // Switch upon the state that we are currently in and move to a new state switch (appState_) { case APP_READ_REQUEST: // We are done reading the request, package the read buffer into transport // and get back some data from the dispatch function if (server_->getHeaderTransport()) { inputTransport_->resetBuffer(readBuffer_, readBufferPos_); outputTransport_->resetBuffer(); } else { // We saved room for the framing size in case header transport needed it, // but just skip it for the non-header case inputTransport_->resetBuffer(readBuffer_ + 4, readBufferPos_ - 4); outputTransport_->resetBuffer(); // Prepend four bytes of blank space to the buffer so we can // write the frame size there later. outputTransport_->getWritePtr(4); outputTransport_->wroteBytes(4); } server_->incrementActiveProcessors(); if (server_->isThreadPoolProcessing()) { // We are setting up a Task to do this work and we will wait on it // Create task and dispatch to the thread manager std::shared_ptr task = std::shared_ptr( new Task(processor_, inputProtocol_, outputProtocol_, this)); // The application is now waiting on the task to finish appState_ = APP_WAIT_TASK; // Set this connection idle so that libevent doesn't process more // data on it while we're still waiting for the threadmanager to // finish this task setIdle(); try { server_->addTask(task); } catch (IllegalStateException& ise) { // The ThreadManager is not ready to handle any more tasks (it's probably shutting down). TOutput::instance().printf("IllegalStateException: Server::process() %s", ise.what()); server_->decrementActiveProcessors(); close(); } catch (TimedOutException& to) { TOutput::instance().printf("[ERROR] TimedOutException: Server::process() %s", to.what()); server_->decrementActiveProcessors(); close(); } return; } else { try { if (serverEventHandler_) { serverEventHandler_->processContext(connectionContext_, getTSocket()); } // Invoke the processor processor_->process(inputProtocol_, outputProtocol_, connectionContext_); } catch (const TTransportException& ttx) { TOutput::instance().printf( "TNonblockingServer transport error in " "process(): %s", ttx.what()); server_->decrementActiveProcessors(); close(); return; } catch (const std::exception& x) { TOutput::instance().printf("Server::process() uncaught exception: %s: %s", typeid(x).name(), x.what()); server_->decrementActiveProcessors(); close(); return; } catch (...) { TOutput::instance().printf("Server::process() unknown exception"); server_->decrementActiveProcessors(); close(); return; } } // fallthrough // Intentionally fall through here, the call to process has written into // the writeBuffer_ case APP_WAIT_TASK: // We have now finished processing a task and the result has been written // into the outputTransport_, so we grab its contents and place them into // the writeBuffer_ for actual writing by the libevent thread server_->decrementActiveProcessors(); // Get the result of the operation outputTransport_->getBuffer(&writeBuffer_, &writeBufferSize_); // If the function call generated return data, then move into the send // state and get going // 4 bytes were reserved for frame size if (writeBufferSize_ > 4) { // Move into write state writeBufferPos_ = 0; socketState_ = SOCKET_SEND; // Put the frame size into the write buffer auto frameSize = (int32_t)htonl(writeBufferSize_ - 4); memcpy(writeBuffer_, &frameSize, 4); // Socket into write mode appState_ = APP_SEND_RESULT; setWrite(); return; } // In this case, the request was oneway and we should fall through // right back into the read frame header state goto LABEL_APP_INIT; case APP_SEND_RESULT: // it's now safe to perform buffer size housekeeping. if (writeBufferSize_ > largestWriteBufferSize_) { largestWriteBufferSize_ = writeBufferSize_; } if (server_->getResizeBufferEveryN() > 0 && ++callsForResize_ >= server_->getResizeBufferEveryN()) { checkIdleBufferMemLimit(server_->getIdleReadBufferLimit(), server_->getIdleWriteBufferLimit()); callsForResize_ = 0; } // fallthrough // N.B.: We also intentionally fall through here into the INIT state! LABEL_APP_INIT: case APP_INIT: // Clear write buffer variables writeBuffer_ = nullptr; writeBufferPos_ = 0; writeBufferSize_ = 0; // Into read4 state we go socketState_ = SOCKET_RECV_FRAMING; appState_ = APP_READ_FRAME_SIZE; readBufferPos_ = 0; // Register read event setRead(); return; case APP_READ_FRAME_SIZE: readWant_ += 4; // We just read the request length // Double the buffer size until it is big enough if (readWant_ > readBufferSize_) { if (readBufferSize_ == 0) { readBufferSize_ = 1; } uint32_t newSize = readBufferSize_; while (readWant_ > newSize) { newSize *= 2; } auto* newBuffer = (uint8_t*)std::realloc(readBuffer_, newSize); if (newBuffer == nullptr) { // nothing else to be done... throw std::bad_alloc(); } readBuffer_ = newBuffer; readBufferSize_ = newSize; } readBufferPos_ = 4; *((uint32_t*)readBuffer_) = htonl(readWant_ - 4); // Move into read request state socketState_ = SOCKET_RECV; appState_ = APP_READ_REQUEST; return; case APP_CLOSE_CONNECTION: server_->decrementActiveProcessors(); close(); return; default: TOutput::instance().printf("Unexpected Application State %d", appState_); assert(0); } } void TNonblockingServer::TConnection::setFlags(short eventFlags) { // Catch the do nothing case if (eventFlags_ == eventFlags) { return; } // Delete a previously existing event if (eventFlags_ && event_del(&event_) == -1) { TOutput::instance().perror("TConnection::setFlags() event_del", THRIFT_GET_SOCKET_ERROR); return; } // Update in memory structure eventFlags_ = eventFlags; // Do not call event_set if there are no flags if (!eventFlags_) { return; } /* * event_set: * * Prepares the event structure &event to be used in future calls to * event_add() and event_del(). The event will be prepared to call the * eventHandler using the 'sock' file descriptor to monitor events. * * The events can be either EV_READ, EV_WRITE, or both, indicating * that an application can read or write from the file respectively without * blocking. * * The eventHandler will be called with the file descriptor that triggered * the event and the type of event which will be one of: EV_TIMEOUT, * EV_SIGNAL, EV_READ, EV_WRITE. * * The additional flag EV_PERSIST makes an event_add() persistent until * event_del() has been called. * * Once initialized, the &event struct can be used repeatedly with * event_add() and event_del() and does not need to be reinitialized unless * the eventHandler and/or the argument to it are to be changed. However, * when an ev structure has been added to libevent using event_add() the * structure must persist until the event occurs (assuming EV_PERSIST * is not set) or is removed using event_del(). You may not reuse the same * ev structure for multiple monitored descriptors; each descriptor needs * its own ev. */ event_set(&event_, tSocket_->getSocketFD(), eventFlags_, TConnection::eventHandler, this); event_base_set(ioThread_->getEventBase(), &event_); // Add the event if (event_add(&event_, nullptr) == -1) { TOutput::instance().perror("TConnection::setFlags(): could not event_add", THRIFT_GET_SOCKET_ERROR); } } /** * Closes a connection */ void TNonblockingServer::TConnection::close() { setIdle(); if (serverEventHandler_) { serverEventHandler_->deleteContext(connectionContext_, inputProtocol_, outputProtocol_); } ioThread_ = nullptr; // Close the socket tSocket_->close(); // close any factory produced transports factoryInputTransport_->close(); factoryOutputTransport_->close(); // release processor and handler processor_.reset(); // Give this object back to the server that owns it server_->returnConnection(this); } void TNonblockingServer::TConnection::checkIdleBufferMemLimit(size_t readLimit, size_t writeLimit) { if (readLimit > 0 && readBufferSize_ > readLimit) { free(readBuffer_); readBuffer_ = nullptr; readBufferSize_ = 0; } if (writeLimit > 0 && largestWriteBufferSize_ > writeLimit) { // just start over outputTransport_->resetBuffer(static_cast(server_->getWriteBufferDefaultSize())); largestWriteBufferSize_ = 0; } } TNonblockingServer::~TNonblockingServer() { // Close any active connections (moves them to the idle connection stack) while (!activeConnections_.empty()) { (*activeConnections_.begin())->close(); } // Clean up unused TConnection objects in connectionStack_ while (!connectionStack_.empty()) { TConnection* connection = connectionStack_.top(); connectionStack_.pop(); delete connection; } // The TNonblockingIOThread objects have shared_ptrs to the Thread // objects and the Thread objects have shared_ptrs to the TNonblockingIOThread // objects (as runnable) so these objects will never deallocate without help. while (!ioThreads_.empty()) { std::shared_ptr iot = ioThreads_.back(); ioThreads_.pop_back(); iot->setThread(std::shared_ptr()); } } /** * Creates a new connection either by reusing an object off the stack or * by allocating a new one entirely */ TNonblockingServer::TConnection* TNonblockingServer::createConnection(std::shared_ptr socket) { // Check the stack Guard g(connMutex_); // pick an IO thread to handle this connection -- currently round robin assert(nextIOThread_ < ioThreads_.size()); int selectedThreadIdx = nextIOThread_; nextIOThread_ = static_cast((nextIOThread_ + 1) % ioThreads_.size()); TNonblockingIOThread* ioThread = ioThreads_[selectedThreadIdx].get(); // Check the connection stack to see if we can re-use TConnection* result = nullptr; if (connectionStack_.empty()) { result = new TConnection(socket, ioThread); ++numTConnections_; } else { result = connectionStack_.top(); connectionStack_.pop(); result->setSocket(socket); result->init(ioThread); } activeConnections_.insert(result); return result; } /** * Returns a connection to the stack */ void TNonblockingServer::returnConnection(TConnection* connection) { Guard g(connMutex_); activeConnections_.erase(connection); if (connectionStackLimit_ && (connectionStack_.size() >= connectionStackLimit_)) { delete connection; --numTConnections_; } else { connection->checkIdleBufferMemLimit(idleReadBufferLimit_, idleWriteBufferLimit_); connectionStack_.push(connection); } } /** * Server socket had something happen. We accept all waiting client * connections on fd and assign TConnection objects to handle those requests. */ void TNonblockingServer::handleEvent(THRIFT_SOCKET fd, short which) { (void)which; // Make sure that libevent didn't mess up the socket handles assert(fd == serverSocket_); // Going to accept a new client socket std::shared_ptr clientSocket; clientSocket = serverTransport_->accept(); if (clientSocket) { // If we're overloaded, take action here if (overloadAction_ != T_OVERLOAD_NO_ACTION && serverOverloaded()) { Guard g(connMutex_); nConnectionsDropped_++; nTotalConnectionsDropped_++; if (overloadAction_ == T_OVERLOAD_CLOSE_ON_ACCEPT) { clientSocket->close(); return; } else if (overloadAction_ == T_OVERLOAD_DRAIN_TASK_QUEUE) { if (!drainPendingTask()) { // Nothing left to discard, so we drop connection instead. clientSocket->close(); return; } } } // Create a new TConnection for this client socket. TConnection* clientConnection = createConnection(clientSocket); // Fail fast if we could not create a TConnection object if (clientConnection == nullptr) { TOutput::instance().printf("thriftServerEventHandler: failed TConnection factory"); clientSocket->close(); return; } /* * Either notify the ioThread that is assigned this connection to * start processing, or if it is us, we'll just ask this * connection to do its initial state change here. * * (We need to avoid writing to our own notification pipe, to * avoid possible deadlocks if the pipe is full.) * * The IO thread #0 is the only one that handles these listen * events, so unless the connection has been assigned to thread #0 * we know it's not on our thread. */ if (clientConnection->getIOThreadNumber() == 0) { clientConnection->transition(); } else { if (!clientConnection->notifyIOThread()) { TOutput::instance().perror("[ERROR] notifyIOThread failed on fresh connection, closing", errno); clientConnection->close(); } } } } /** * Creates a socket to listen on and binds it to the local port. */ void TNonblockingServer::createAndListenOnSocket() { serverTransport_->listen(); serverSocket_ = serverTransport_->getSocketFD(); } void TNonblockingServer::setThreadManager(std::shared_ptr threadManager) { threadManager_ = threadManager; if (threadManager) { threadManager->setExpireCallback( std::bind(&TNonblockingServer::expireClose, this, std::placeholders::_1)); threadPoolProcessing_ = true; } else { threadPoolProcessing_ = false; } } bool TNonblockingServer::serverOverloaded() { size_t activeConnections = numTConnections_ - connectionStack_.size(); if (numActiveProcessors_ > maxActiveProcessors_ || activeConnections > maxConnections_) { if (!overloaded_) { TOutput::instance().printf("TNonblockingServer: overload condition begun."); overloaded_ = true; } } else { if (overloaded_ && (numActiveProcessors_ <= overloadHysteresis_ * maxActiveProcessors_) && (activeConnections <= overloadHysteresis_ * maxConnections_)) { TOutput::instance().printf( "TNonblockingServer: overload ended; " "%u dropped (%llu total)", nConnectionsDropped_, nTotalConnectionsDropped_); nConnectionsDropped_ = 0; overloaded_ = false; } } return overloaded_; } bool TNonblockingServer::drainPendingTask() { if (threadManager_) { std::shared_ptr task = threadManager_->removeNextPending(); if (task) { TConnection* connection = static_cast(task.get())->getTConnection(); assert(connection && connection->getServer() && connection->getState() == APP_WAIT_TASK); connection->forceClose(); return true; } } return false; } void TNonblockingServer::expireClose(std::shared_ptr task) { TConnection* connection = static_cast(task.get())->getTConnection(); assert(connection && connection->getServer() && connection->getState() == APP_WAIT_TASK); connection->forceClose(); } void TNonblockingServer::stop() { // Breaks the event loop in all threads so that they end ASAP. for (auto & ioThread : ioThreads_) { ioThread->stop(); } } void TNonblockingServer::registerEvents(event_base* user_event_base) { userEventBase_ = user_event_base; // init listen socket if (serverSocket_ == THRIFT_INVALID_SOCKET) createAndListenOnSocket(); // set up the IO threads assert(ioThreads_.empty()); if (!numIOThreads_) { numIOThreads_ = DEFAULT_IO_THREADS; } // User-provided event-base doesn't works for multi-threaded servers assert(numIOThreads_ == 1 || !userEventBase_); for (uint32_t id = 0; id < numIOThreads_; ++id) { // the first IO thread also does the listening on server socket THRIFT_SOCKET listenFd = (id == 0 ? serverSocket_ : THRIFT_INVALID_SOCKET); shared_ptr thread( new TNonblockingIOThread(this, id, listenFd, useHighPriorityIOThreads_)); ioThreads_.push_back(thread); } // Notify handler of the preServe event if (eventHandler_) { eventHandler_->preServe(); } // Start all of our helper IO threads. Note that the threads run forever, // only terminating if stop() is called. assert(ioThreads_.size() == numIOThreads_); assert(ioThreads_.size() > 0); TOutput::instance().printf("TNonblockingServer: Serving with %d io threads.", ioThreads_.size()); // Launch all the secondary IO threads in separate threads if (ioThreads_.size() > 1) { ioThreadFactory_.reset(new ThreadFactory( false // detached )); assert(ioThreadFactory_.get()); // intentionally starting at thread 1, not 0 for (uint32_t i = 1; i < ioThreads_.size(); ++i) { shared_ptr thread = ioThreadFactory_->newThread(ioThreads_[i]); ioThreads_[i]->setThread(thread); thread->start(); } } // Register the events for the primary (listener) IO thread ioThreads_[0]->registerEvents(); } /** * Main workhorse function, starts up the server listening on a port and * loops over the libevent handler. */ void TNonblockingServer::serve() { if (ioThreads_.empty()) registerEvents(nullptr); // Run the primary (listener) IO thread loop in our main thread; this will // only return when the server is shutting down. ioThreads_[0]->run(); // Ensure all threads are finished before exiting serve() for (uint32_t i = 0; i < ioThreads_.size(); ++i) { ioThreads_[i]->join(); TOutput::instance().printf("TNonblocking: join done for IO thread #%d", i); } } TNonblockingIOThread::TNonblockingIOThread(TNonblockingServer* server, int number, THRIFT_SOCKET listenSocket, bool useHighPriority) : server_(server), number_(number), threadId_{}, listenSocket_(listenSocket), useHighPriority_(useHighPriority), eventBase_(nullptr), ownEventBase_(false), serverEvent_{}, notificationEvent_{} { notificationPipeFDs_[0] = -1; notificationPipeFDs_[1] = -1; } TNonblockingIOThread::~TNonblockingIOThread() { // make sure our associated thread is fully finished join(); if (eventBase_ && ownEventBase_) { event_base_free(eventBase_); ownEventBase_ = false; } if (listenSocket_ != THRIFT_INVALID_SOCKET) { if (0 != ::THRIFT_CLOSESOCKET(listenSocket_)) { TOutput::instance().perror("TNonblockingIOThread listenSocket_ close(): ", THRIFT_GET_SOCKET_ERROR); } listenSocket_ = THRIFT_INVALID_SOCKET; } for (auto notificationPipeFD : notificationPipeFDs_) { if (notificationPipeFD >= 0) { if (0 != ::THRIFT_CLOSESOCKET(notificationPipeFD)) { TOutput::instance().perror("TNonblockingIOThread notificationPipe close(): ", THRIFT_GET_SOCKET_ERROR); } notificationPipeFD = THRIFT_INVALID_SOCKET; } } } void TNonblockingIOThread::createNotificationPipe() { if (evutil_socketpair(AF_LOCAL, SOCK_STREAM, 0, notificationPipeFDs_) == -1) { TOutput::instance().perror("TNonblockingServer::createNotificationPipe ", EVUTIL_SOCKET_ERROR()); throw TException("can't create notification pipe"); } if (evutil_make_socket_nonblocking(notificationPipeFDs_[0]) < 0 || evutil_make_socket_nonblocking(notificationPipeFDs_[1]) < 0) { ::THRIFT_CLOSESOCKET(notificationPipeFDs_[0]); ::THRIFT_CLOSESOCKET(notificationPipeFDs_[1]); throw TException("TNonblockingServer::createNotificationPipe() THRIFT_O_NONBLOCK"); } for (auto notificationPipeFD : notificationPipeFDs_) { #if LIBEVENT_VERSION_NUMBER < 0x02000000 int flags; if ((flags = THRIFT_FCNTL(notificationPipeFD, F_GETFD, 0)) < 0 || THRIFT_FCNTL(notificationPipeFD, F_SETFD, flags | FD_CLOEXEC) < 0) { #else if (evutil_make_socket_closeonexec(notificationPipeFD) < 0) { #endif ::THRIFT_CLOSESOCKET(notificationPipeFDs_[0]); ::THRIFT_CLOSESOCKET(notificationPipeFDs_[1]); throw TException( "TNonblockingServer::createNotificationPipe() " "FD_CLOEXEC"); } } } /** * Register the core libevent events onto the proper base. */ void TNonblockingIOThread::registerEvents() { threadId_ = Thread::get_current(); assert(eventBase_ == nullptr); eventBase_ = getServer()->getUserEventBase(); if (eventBase_ == nullptr) { eventBase_ = event_base_new(); ownEventBase_ = true; } // Print some libevent stats if (number_ == 0) { TOutput::instance().printf("TNonblockingServer: using libevent %s method %s", event_get_version(), event_base_get_method(eventBase_)); } if (listenSocket_ != THRIFT_INVALID_SOCKET) { // Register the server event event_set(&serverEvent_, listenSocket_, EV_READ | EV_PERSIST, TNonblockingIOThread::listenHandler, server_); event_base_set(eventBase_, &serverEvent_); // Add the event and start up the server if (-1 == event_add(&serverEvent_, nullptr)) { throw TException( "TNonblockingServer::serve(): " "event_add() failed on server listen event"); } TOutput::instance().printf("TNonblocking: IO thread #%d registered for listen.", number_); } createNotificationPipe(); // Create an event to be notified when a task finishes event_set(¬ificationEvent_, getNotificationRecvFD(), EV_READ | EV_PERSIST, TNonblockingIOThread::notifyHandler, this); // Attach to the base event_base_set(eventBase_, ¬ificationEvent_); // Add the event and start up the server if (-1 == event_add(¬ificationEvent_, nullptr)) { throw TException( "TNonblockingServer::serve(): " "event_add() failed on task-done notification event"); } TOutput::instance().printf("TNonblocking: IO thread #%d registered for notify.", number_); } bool TNonblockingIOThread::notify(TNonblockingServer::TConnection* conn) { auto fd = getNotificationSendFD(); if (fd < 0) { return false; } int ret = -1; long kSize = sizeof(conn); const char * pos = (const char *)const_cast_sockopt(&conn); #if defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H) struct pollfd pfd = {fd, POLLOUT, 0}; while (kSize > 0) { pfd.revents = 0; ret = poll(&pfd, 1, -1); if (ret < 0) { return false; } else if (ret == 0) { continue; } if (pfd.revents & POLLHUP || pfd.revents & POLLERR) { ::THRIFT_CLOSESOCKET(fd); return false; } if (pfd.revents & POLLOUT) { ret = send(fd, pos, kSize, 0); if (ret < 0) { if (errno == EAGAIN) { continue; } ::THRIFT_CLOSESOCKET(fd); return false; } kSize -= ret; pos += ret; } } #else fd_set wfds, efds; while (kSize > 0) { FD_ZERO(&wfds); FD_ZERO(&efds); FD_SET(fd, &wfds); FD_SET(fd, &efds); ret = select(static_cast(fd + 1), nullptr, &wfds, &efds, nullptr); if (ret < 0) { return false; } else if (ret == 0) { continue; } if (FD_ISSET(fd, &efds)) { ::THRIFT_CLOSESOCKET(fd); return false; } if (FD_ISSET(fd, &wfds)) { ret = send(fd, pos, kSize, 0); if (ret < 0) { if (errno == EAGAIN) { continue; } ::THRIFT_CLOSESOCKET(fd); return false; } kSize -= ret; pos += ret; } } #endif return true; } /* static */ void TNonblockingIOThread::notifyHandler(evutil_socket_t fd, short which, void* v) { auto* ioThread = (TNonblockingIOThread*)v; assert(ioThread); (void)which; while (true) { TNonblockingServer::TConnection* connection = nullptr; const int kSize = sizeof(connection); long nBytes = recv(fd, cast_sockopt(&connection), kSize, 0); if (nBytes == kSize) { if (connection == nullptr) { // this is the command to stop our thread, exit the handler! ioThread->breakLoop(false); return; } connection->transition(); } else if (nBytes > 0) { // throw away these bytes and hope that next time we get a solid read TOutput::instance().printf("notifyHandler: Bad read of %d bytes, wanted %d", nBytes, kSize); ioThread->breakLoop(true); return; } else if (nBytes == 0) { TOutput::instance().printf("notifyHandler: Notify socket closed!"); ioThread->breakLoop(false); // exit the loop break; } else { // nBytes < 0 if (THRIFT_GET_SOCKET_ERROR != THRIFT_EWOULDBLOCK && THRIFT_GET_SOCKET_ERROR != THRIFT_EAGAIN) { TOutput::instance().perror("TNonblocking: notifyHandler read() failed: ", THRIFT_GET_SOCKET_ERROR); ioThread->breakLoop(true); return; } // exit the loop break; } } } void TNonblockingIOThread::breakLoop(bool error) { if (error) { TOutput::instance().printf("TNonblockingServer: IO thread #%d exiting with error.", number_); // TODO: figure out something better to do here, but for now kill the // whole process. TOutput::instance().printf("TNonblockingServer: aborting process."); ::abort(); } // If we're running in the same thread, we can't use the notify(0) // mechanism to stop the thread, but happily if we're running in the // same thread, this means the thread can't be blocking in the event // loop either. if (!Thread::is_current(threadId_)) { notify(nullptr); } else { // cause the loop to stop ASAP - even if it has things to do in it event_base_loopbreak(eventBase_); } } void TNonblockingIOThread::setCurrentThreadHighPriority(bool value) { #ifdef HAVE_SCHED_H // Start out with a standard, low-priority setup for the sched params. struct sched_param sp; memset(static_cast(&sp), 0, sizeof(sp)); int policy = SCHED_OTHER; // If desired, set up high-priority sched params structure. if (value) { // FIFO scheduler, ranked above default SCHED_OTHER queue policy = SCHED_FIFO; // The priority only compares us to other SCHED_FIFO threads, so we // just pick a random priority halfway between min & max. const int priority = (sched_get_priority_max(policy) + sched_get_priority_min(policy)) / 2; sp.sched_priority = priority; } // Actually set the sched params for the current thread. if (0 == pthread_setschedparam(pthread_self(), policy, &sp)) { TOutput::instance().printf("TNonblocking: IO Thread #%d using high-priority scheduler!", number_); } else { TOutput::instance().perror("TNonblocking: pthread_setschedparam(): ", THRIFT_GET_SOCKET_ERROR); } #else THRIFT_UNUSED_VARIABLE(value); #endif } void TNonblockingIOThread::run() { if (eventBase_ == nullptr) { registerEvents(); } if (useHighPriority_) { setCurrentThreadHighPriority(true); } if (eventBase_ != nullptr) { TOutput::instance().printf("TNonblockingServer: IO thread #%d entering loop...", number_); // Run libevent engine, never returns, invokes calls to eventHandler event_base_loop(eventBase_, 0); if (useHighPriority_) { setCurrentThreadHighPriority(false); } // cleans up our registered events cleanupEvents(); } TOutput::instance().printf("TNonblockingServer: IO thread #%d run() done!", number_); } void TNonblockingIOThread::cleanupEvents() { // stop the listen socket, if any if (listenSocket_ != THRIFT_INVALID_SOCKET) { if (event_del(&serverEvent_) == -1) { TOutput::instance().perror("TNonblockingIOThread::stop() event_del: ", THRIFT_GET_SOCKET_ERROR); } } event_del(¬ificationEvent_); } void TNonblockingIOThread::stop() { // This should cause the thread to fall out of its event loop ASAP. breakLoop(false); } void TNonblockingIOThread::join() { // If this was a thread created by a factory (not the thread that called // serve()), we join() it to make sure we shut down fully. if (thread_) { try { // Note that it is safe to both join() ourselves twice, as well as join // the current thread as the pthread implementation checks for deadlock. thread_->join(); } catch (...) { // swallow everything } } } } } } // apache::thrift::server thrift-0.23.0/lib/cpp/src/thrift/server/TConnectedClient.cpp0000664000175000017500000000767315167543515024225 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace server { using apache::thrift::TProcessor; using apache::thrift::protocol::TProtocol; using apache::thrift::server::TServerEventHandler; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using std::shared_ptr; using std::string; TConnectedClient::TConnectedClient(const shared_ptr& processor, const shared_ptr& inputProtocol, const shared_ptr& outputProtocol, const shared_ptr& eventHandler, const shared_ptr& client) : processor_(processor), inputProtocol_(inputProtocol), outputProtocol_(outputProtocol), eventHandler_(eventHandler), client_(client), opaqueContext_(nullptr) { } TConnectedClient::~TConnectedClient() = default; void TConnectedClient::run() { if (eventHandler_) { opaqueContext_ = eventHandler_->createContext(inputProtocol_, outputProtocol_); } for (bool done = false; !done;) { if (eventHandler_) { eventHandler_->processContext(opaqueContext_, client_); } try { if (!processor_->process(inputProtocol_, outputProtocol_, opaqueContext_)) { break; } } catch (const TTransportException& ttx) { switch (ttx.getType()) { case TTransportException::END_OF_FILE: case TTransportException::INTERRUPTED: case TTransportException::TIMED_OUT: // Client disconnected or was interrupted or did not respond within the receive timeout. // No logging needed. Done. done = true; break; default: { // All other transport exceptions are logged. // State of connection is unknown. Done. string errStr = string("TConnectedClient died: ") + ttx.what(); TOutput::instance()(errStr.c_str()); done = true; break; } } } catch (const TException& tex) { string errStr = string("TConnectedClient processing exception: ") + tex.what(); TOutput::instance()(errStr.c_str()); // Disconnect from client, because we could not process the message. done = true; } } cleanup(); } void TConnectedClient::cleanup() { if (eventHandler_) { eventHandler_->deleteContext(opaqueContext_, inputProtocol_, outputProtocol_); } try { inputProtocol_->getTransport()->close(); } catch (const TTransportException& ttx) { string errStr = string("TConnectedClient input close failed: ") + ttx.what(); TOutput::instance()(errStr.c_str()); } try { outputProtocol_->getTransport()->close(); } catch (const TTransportException& ttx) { string errStr = string("TConnectedClient output close failed: ") + ttx.what(); TOutput::instance()(errStr.c_str()); } try { client_->close(); } catch (const TTransportException& ttx) { string errStr = string("TConnectedClient client close failed: ") + ttx.what(); TOutput::instance()(errStr.c_str()); } } } } } // apache::thrift::server thrift-0.23.0/lib/cpp/src/thrift/server/TServer.cpp0000664000175000017500000000266215165535636022426 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_RESOURCE_H #include #endif #ifdef HAVE_UNISTD_H #include #endif namespace apache { namespace thrift { namespace server { #ifdef HAVE_SYS_RESOURCE_H int increase_max_fds(int max_fds = (1 << 24)) { struct rlimit fdmaxrl; for (fdmaxrl.rlim_cur = max_fds, fdmaxrl.rlim_max = max_fds; max_fds && (setrlimit(RLIMIT_NOFILE, &fdmaxrl) < 0); fdmaxrl.rlim_cur = max_fds, fdmaxrl.rlim_max = max_fds) { max_fds /= 2; } return static_cast(fdmaxrl.rlim_cur); } #endif } } } // apache::thrift::server thrift-0.23.0/lib/cpp/src/thrift/server/TThreadedServer.h0000664000175000017500000001376615165535636023543 0ustar00buildbuild00000000000000/* * 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_SERVER_TTHREADEDSERVER_H_ #define _THRIFT_SERVER_TTHREADEDSERVER_H_ 1 #include #include #include #include #include namespace apache { namespace thrift { namespace server { /** * Manage clients using threads - threads are created one for each client and are * released when the client disconnects. This server is used to make a dynamically * scalable server up to the concurrent connection limit. */ class TThreadedServer : public TServerFramework { public: TThreadedServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); TThreadedServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); TThreadedServer( const std::shared_ptr& processorFactory, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); TThreadedServer( const std::shared_ptr& processor, const std::shared_ptr& serverTransport, const std::shared_ptr& inputTransportFactory, const std::shared_ptr& outputTransportFactory, const std::shared_ptr& inputProtocolFactory, const std::shared_ptr& outputProtocolFactory, const std::shared_ptr& threadFactory = std::shared_ptr( new apache::thrift::concurrency::ThreadFactory(false))); ~TThreadedServer() override; /** * Post-conditions (return guarantees): * There will be no clients connected. */ void serve() override; protected: /** * Drain recently connected clients by joining their threads - this is done lazily because * we cannot do it inside the thread context that is disconnecting. */ virtual void drainDeadClients(); /** * Implementation of TServerFramework::onClientConnected */ void onClientConnected(const std::shared_ptr& pClient) override /* override */; /** * Implementation of TServerFramework::onClientDisconnected */ void onClientDisconnected(TConnectedClient *pClient) override /* override */; std::shared_ptr threadFactory_; /** * A helper wrapper used to wrap the client in something we can use to maintain * the lifetime of the connected client within a detached thread. We cannot simply * track the threads because a shared_ptr hangs on to the Runnable it is * passed, and TServerFramework requires the runnable (TConnectedClient) to be * destroyed in order to work properly. */ class TConnectedClientRunner : public apache::thrift::concurrency::Runnable { public: TConnectedClientRunner(const std::shared_ptr& pClient); ~TConnectedClientRunner() override; void run() override /* override */; private: std::shared_ptr pClient_; }; apache::thrift::concurrency::Monitor clientMonitor_; typedef std::map > ClientMap; /** * A map of active clients */ ClientMap activeClientMap_; /** * A map of clients that have disconnected but their threads have not been joined */ ClientMap deadClientMap_; }; } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TTHREADEDSERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/TUuid.cpp0000664000175000017500000000331515165535636020554 0ustar00buildbuild00000000000000/* * 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::thriftthrift-0.23.0/lib/cpp/src/thrift/TNonCopyable.h0000664000175000017500000000237015165535636021524 0ustar00buildbuild00000000000000/* * 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 TNONCOPYABLE_H #define TNONCOPYABLE_H /** * @brief A simple non-copyable base class pattern. Derive from TNonCopyable to * make a class non-copyable and prohibit assignment and copy-construction. */ namespace apache { namespace thrift { class TNonCopyable { protected: TNonCopyable() = default; virtual ~TNonCopyable() = default; TNonCopyable(const TNonCopyable&) = delete; TNonCopyable& operator=(const TNonCopyable&) = delete; }; } } #endif thrift-0.23.0/lib/cpp/src/thrift/async/0000755000175000017500000000000015170007200020100 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/async/TAsyncBufferProcessor.h0000664000175000017500000000321715165535636024540 0ustar00buildbuild00000000000000/* * 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_TASYNC_BUFFER_PROCESSOR_H_ #define _THRIFT_TASYNC_BUFFER_PROCESSOR_H_ 1 #include #include #include namespace apache { namespace thrift { namespace async { class TAsyncBufferProcessor { public: // Process data in "in", putting the result in "out". // Call _return(true) when done, or _return(false) to // forcefully close the connection (if applicable). // "in" and "out" should be TMemoryBuffer or similar, // not a wrapper around a socket. virtual void process(std::function _return, std::shared_ptr ibuf, std::shared_ptr obuf) = 0; virtual ~TAsyncBufferProcessor() = default; }; } } } // apache::thrift::async #endif // #ifndef _THRIFT_TASYNC_BUFFER_PROCESSOR_H_ thrift-0.23.0/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h0000664000175000017500000000743715165535636025373 0ustar00buildbuild00000000000000/* * 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_TCONCURRENTCLIENTSYNCINFO_H_ #define _THRIFT_TCONCURRENTCLIENTSYNCINFO_H_ 1 #include #include #include #include #include #include #include namespace apache { namespace thrift { namespace async { class TConcurrentClientSyncInfo; class TConcurrentSendSentry { public: explicit TConcurrentSendSentry(TConcurrentClientSyncInfo* sync); virtual ~TConcurrentSendSentry(); void commit(); private: TConcurrentClientSyncInfo& sync_; bool committed_; }; class TConcurrentRecvSentry { public: TConcurrentRecvSentry(TConcurrentClientSyncInfo* sync, int32_t seqid); virtual ~TConcurrentRecvSentry(); void commit(); private: TConcurrentClientSyncInfo& sync_; int32_t seqid_; bool committed_; }; class TConcurrentClientSyncInfo { private: // typedefs typedef std::shared_ptr< ::apache::thrift::concurrency::Monitor> MonitorPtr; typedef std::map MonitorMap; public: TConcurrentClientSyncInfo(); int32_t generateSeqId(); bool getPending(std::string& fname, ::apache::thrift::protocol::TMessageType& mtype, int32_t& rseqid); /* requires readMutex_ */ void updatePending(const std::string& fname, ::apache::thrift::protocol::TMessageType mtype, int32_t rseqid); /* requires readMutex_ */ void waitForWork(int32_t seqid); /* requires readMutex_ */ ::apache::thrift::concurrency::Mutex& getReadMutex() { return readMutex_; } ::apache::thrift::concurrency::Mutex& getWriteMutex() { return writeMutex_; } private: // constants enum { MONITOR_CACHE_SIZE = 10 }; private: // functions MonitorPtr newMonitor_( const ::apache::thrift::concurrency::Guard& seqidGuard); /* requires seqidMutex_ */ void deleteMonitor_(const ::apache::thrift::concurrency::Guard& seqidGuard, MonitorPtr& m); /*noexcept*/ /* requires seqidMutex_ */ void wakeupAnyone_( const ::apache::thrift::concurrency::Guard& seqidGuard); /* requires seqidMutex_ */ void markBad_(const ::apache::thrift::concurrency::Guard& seqidGuard); /* requires seqidMutex_ */ void throwBadSeqId_(); void throwDeadConnection_(); private: // data members volatile bool stop_; ::apache::thrift::concurrency::Mutex seqidMutex_; // begin seqidMutex_ protected members int32_t nextseqid_; MonitorMap seqidToMonitorMap_; std::vector freeMonitors_; // end seqidMutex_ protected members ::apache::thrift::concurrency::Mutex writeMutex_; ::apache::thrift::concurrency::Mutex readMutex_; // begin readMutex_ protected members bool recvPending_; bool wakeupSomeone_; int32_t seqidPending_; std::string fnamePending_; ::apache::thrift::protocol::TMessageType mtypePending_; // end readMutex_ protected members friend class TConcurrentSendSentry; friend class TConcurrentRecvSentry; }; } } } // apache::thrift::async #endif // _THRIFT_TCONCURRENTCLIENTSYNCINFO_H_ thrift-0.23.0/lib/cpp/src/thrift/async/TEvhttpClientChannel.h0000664000175000017500000000531215165535636024331 0ustar00buildbuild00000000000000/* * 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_TEVHTTP_CLIENT_CHANNEL_H_ #define _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_ 1 #include #include #include #include #include struct event_base; struct evdns_base; struct evhttp_connection; struct evhttp_request; namespace apache { namespace thrift { namespace transport { class TMemoryBuffer; } } } namespace apache { namespace thrift { namespace async { class TEvhttpClientChannel : public TAsyncChannel { public: using TAsyncChannel::VoidCallback; TEvhttpClientChannel(const std::string& host, const std::string& path, const char* address, int port, struct event_base* eb, struct evdns_base *dnsbase = nullptr); ~TEvhttpClientChannel() override; void sendAndRecvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* sendBuf, apache::thrift::transport::TMemoryBuffer* recvBuf) override; void sendMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) override; void recvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) override; void finish(struct evhttp_request* req); // XXX bool good() const override { return true; } bool error() const override { return false; } bool timedOut() const override { return false; } private: static void response(struct evhttp_request* req, void* arg); std::string host_; std::string path_; typedef std::pair Completion; typedef std::queue CompletionQueue; CompletionQueue completionQueue_; struct evhttp_connection* conn_; }; } } } // apache::thrift::async #endif // #ifndef _THRIFT_TEVHTTP_CLIENT_CHANNEL_H_ thrift-0.23.0/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.h0000664000175000017500000000372615165535636025135 0ustar00buildbuild00000000000000/* * 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_TNAME_ME_H_ #define _THRIFT_TNAME_ME_H_ 1 #include #include #include namespace apache { namespace thrift { namespace async { class TAsyncProtocolProcessor : public TAsyncBufferProcessor { public: TAsyncProtocolProcessor(std::shared_ptr underlying, std::shared_ptr pfact) : underlying_(underlying), pfact_(pfact) {} void process(std::function _return, std::shared_ptr ibuf, std::shared_ptr obuf) override; ~TAsyncProtocolProcessor() override = default; private: static void finish(std::function _return, std::shared_ptr oprot, bool healthy); std::shared_ptr underlying_; std::shared_ptr pfact_; }; } } } // apache::thrift::async #endif // #ifndef _THRIFT_TNAME_ME_H_ thrift-0.23.0/lib/cpp/src/thrift/async/TAsyncChannel.cpp0000664000175000017500000000236215165535636023332 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace async { void TAsyncChannel::sendAndRecvMessage(const VoidCallback& cob, TMemoryBuffer* sendBuf, TMemoryBuffer* recvBuf) { std::function send_done = std::bind(&TAsyncChannel::recvMessage, this, cob, recvBuf); sendMessage(send_done, sendBuf); } } } } // apache::thrift::async thrift-0.23.0/lib/cpp/src/thrift/async/TAsyncChannel.h0000664000175000017500000000416715165535636023004 0ustar00buildbuild00000000000000/* * 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_ASYNC_TASYNCCHANNEL_H_ #define _THRIFT_ASYNC_TASYNCCHANNEL_H_ 1 #include #include #include namespace apache { namespace thrift { namespace transport { class TMemoryBuffer; } } } namespace apache { namespace thrift { namespace async { using apache::thrift::transport::TMemoryBuffer; class TAsyncChannel { public: typedef std::function VoidCallback; virtual ~TAsyncChannel() = default; // is the channel in a good state? virtual bool good() const = 0; virtual bool error() const = 0; virtual bool timedOut() const = 0; /** * Send a message over the channel. */ virtual void sendMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) = 0; /** * Receive a message from the channel. */ virtual void recvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) = 0; /** * Send a message over the channel and receive a response. */ virtual void sendAndRecvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* sendBuf, apache::thrift::transport::TMemoryBuffer* recvBuf); }; } } } // apache::thrift::async #endif // #ifndef _THRIFT_ASYNC_TASYNCCHANNEL_H_ thrift-0.23.0/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h0000664000175000017500000001310515167543515025060 0ustar00buildbuild00000000000000/* * 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_ASYNC_TASYNCDISPATCHPROCESSOR_H_ #define _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_ 1 #include namespace apache { namespace thrift { namespace async { /** * TAsyncDispatchProcessor is a helper class to parse the message header then * call another function to dispatch based on the function name. * * Subclasses must implement dispatchCall() to dispatch on the function name. */ template class TAsyncDispatchProcessorT : public TAsyncProcessor { public: void process(std::function _return, std::shared_ptr in, std::shared_ptr out) override { protocol::TProtocol* inRaw = in.get(); protocol::TProtocol* outRaw = out.get(); // Try to dynamic cast to the template protocol type auto* specificIn = dynamic_cast(inRaw); auto* specificOut = dynamic_cast(outRaw); if (specificIn && specificOut) { return processFast(_return, specificIn, specificOut); } // Log the fact that we have to use the slow path T_GENERIC_PROTOCOL(this, inRaw, specificIn); T_GENERIC_PROTOCOL(this, outRaw, specificOut); std::string fname; protocol::TMessageType mtype; int32_t seqid; inRaw->readMessageBegin(fname, mtype, seqid); // If this doesn't look like a valid call, log an error and return false so // that the server will close the connection. // // (The old generated processor code used to try to skip a T_STRUCT and // continue. However, that seems unsafe.) if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { TOutput::instance().printf("received invalid message type %d from client", mtype); _return(false); return; } return this->dispatchCall(_return, inRaw, outRaw, fname, seqid); } void processFast(std::function _return, Protocol_* in, Protocol_* out) { std::string fname; protocol::TMessageType mtype; int32_t seqid; in->readMessageBegin(fname, mtype, seqid); if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { TOutput::instance().printf("received invalid message type %d from client", mtype); _return(false); return; } return this->dispatchCallTemplated(_return, in, out, fname, seqid); } virtual void dispatchCall(std::function _return, apache::thrift::protocol::TProtocol* in, apache::thrift::protocol::TProtocol* out, const std::string& fname, int32_t seqid) = 0; virtual void dispatchCallTemplated(std::function _return, Protocol_* in, Protocol_* out, const std::string& fname, int32_t seqid) = 0; }; /** * Non-templatized version of TAsyncDispatchProcessor, * that doesn't bother trying to perform a dynamic_cast. */ class TAsyncDispatchProcessor : public TAsyncProcessor { public: void process(std::function _return, std::shared_ptr in, std::shared_ptr out) override { protocol::TProtocol* inRaw = in.get(); protocol::TProtocol* outRaw = out.get(); std::string fname; protocol::TMessageType mtype; int32_t seqid; inRaw->readMessageBegin(fname, mtype, seqid); // If this doesn't look like a valid call, log an error and return false so // that the server will close the connection. // // (The old generated processor code used to try to skip a T_STRUCT and // continue. However, that seems unsafe.) if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { TOutput::instance().printf("received invalid message type %d from client", mtype); _return(false); return; } return dispatchCall(_return, inRaw, outRaw, fname, seqid); } virtual void dispatchCall(std::function _return, apache::thrift::protocol::TProtocol* in, apache::thrift::protocol::TProtocol* out, const std::string& fname, int32_t seqid) = 0; }; // Specialize TAsyncDispatchProcessorT for TProtocol and TDummyProtocol just to // use the generic TDispatchProcessor. template <> class TAsyncDispatchProcessorT : public TAsyncDispatchProcessor {}; template <> class TAsyncDispatchProcessorT : public TAsyncDispatchProcessor {}; } } } // apache::thrift::async #endif // _THRIFT_ASYNC_TASYNCDISPATCHPROCESSOR_H_ thrift-0.23.0/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp0000664000175000017500000001523115165535636025715 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace async { using namespace ::apache::thrift::concurrency; TConcurrentClientSyncInfo::TConcurrentClientSyncInfo() : stop_(false), seqidMutex_(), // test rollover all the time nextseqid_((std::numeric_limits::max)()-10), seqidToMonitorMap_(), freeMonitors_(), writeMutex_(), readMutex_(), recvPending_(false), wakeupSomeone_(false), seqidPending_(0), fnamePending_(), mtypePending_(::apache::thrift::protocol::T_CALL) { freeMonitors_.reserve(MONITOR_CACHE_SIZE); } bool TConcurrentClientSyncInfo::getPending( std::string &fname, ::apache::thrift::protocol::TMessageType &mtype, int32_t &rseqid) { if(stop_) throwDeadConnection_(); wakeupSomeone_ = false; if(recvPending_) { recvPending_ = false; rseqid = seqidPending_; fname = fnamePending_; mtype = mtypePending_; return true; } return false; } void TConcurrentClientSyncInfo::updatePending( const std::string &fname, ::apache::thrift::protocol::TMessageType mtype, int32_t rseqid) { recvPending_ = true; seqidPending_ = rseqid; fnamePending_ = fname; mtypePending_ = mtype; MonitorPtr monitor; { Guard seqidGuard(seqidMutex_); auto i = seqidToMonitorMap_.find(rseqid); if(i == seqidToMonitorMap_.end()) throwBadSeqId_(); monitor = i->second; } monitor->notify(); } void TConcurrentClientSyncInfo::waitForWork(int32_t seqid) { MonitorPtr m; { Guard seqidGuard(seqidMutex_); m = seqidToMonitorMap_[seqid]; } while(true) { // be very careful about setting state in this loop that affects waking up. You may exit // this function, attempt to grab some work, and someone else could have beaten you (or not // left) the read mutex, and that will put you right back in this loop, with the mangled // state you left behind. if(stop_) throwDeadConnection_(); if(wakeupSomeone_) return; if(recvPending_ && seqidPending_ == seqid) return; m->waitForever(); } } void TConcurrentClientSyncInfo::throwBadSeqId_() { throw apache::thrift::TApplicationException( TApplicationException::BAD_SEQUENCE_ID, "server sent a bad seqid"); } void TConcurrentClientSyncInfo::throwDeadConnection_() { throw apache::thrift::transport::TTransportException( apache::thrift::transport::TTransportException::NOT_OPEN, "this client died on another thread, and is now in an unusable state"); } void TConcurrentClientSyncInfo::wakeupAnyone_(const Guard &) { wakeupSomeone_ = true; if(!seqidToMonitorMap_.empty()) { // The monitor map maps integers to monitors. Larger integers are more recent // messages. Since this is ordered, it means that the last element is the most recent. // We are trying to guess which thread will have its message complete next, so we are picking // the most recent. The oldest message is likely to be some polling, long lived message. // If we guess right, the thread we wake up will handle the message that comes in. // If we guess wrong, the thread we wake up will hand off the work to the correct thread, // costing us an extra context switch. seqidToMonitorMap_.rbegin()->second->notify(); } } void TConcurrentClientSyncInfo::markBad_(const Guard &) { wakeupSomeone_ = true; stop_ = true; for(auto & i : seqidToMonitorMap_) i.second->notify(); } TConcurrentClientSyncInfo::MonitorPtr TConcurrentClientSyncInfo::newMonitor_(const Guard &) { if(freeMonitors_.empty()) return std::make_shared(&readMutex_); MonitorPtr retval; //swapping to avoid an atomic operation retval.swap(freeMonitors_.back()); freeMonitors_.pop_back(); return retval; } void TConcurrentClientSyncInfo::deleteMonitor_( const Guard &, TConcurrentClientSyncInfo::MonitorPtr &m) /*noexcept*/ { if(freeMonitors_.size() > MONITOR_CACHE_SIZE) { m.reset(); return; } //freeMonitors_ was reserved up to MONITOR_CACHE_SIZE in the ctor, //so this shouldn't throw freeMonitors_.push_back(TConcurrentClientSyncInfo::MonitorPtr()); //swapping to avoid an atomic operation m.swap(freeMonitors_.back()); } int32_t TConcurrentClientSyncInfo::generateSeqId() { Guard seqidGuard(seqidMutex_); if(stop_) throwDeadConnection_(); if(!seqidToMonitorMap_.empty()) if(nextseqid_ == seqidToMonitorMap_.begin()->first) throw apache::thrift::TApplicationException( TApplicationException::BAD_SEQUENCE_ID, "about to repeat a seqid"); int32_t newSeqId = nextseqid_; if (nextseqid_ == (std::numeric_limits::max)()) nextseqid_ = (std::numeric_limits::min)(); else ++nextseqid_; seqidToMonitorMap_[newSeqId] = newMonitor_(seqidGuard); return newSeqId; } TConcurrentRecvSentry::TConcurrentRecvSentry(TConcurrentClientSyncInfo *sync, int32_t seqid) : sync_(*sync), seqid_(seqid), committed_(false) { sync_.getReadMutex().lock(); } TConcurrentRecvSentry::~TConcurrentRecvSentry() { { Guard seqidGuard(sync_.seqidMutex_); sync_.deleteMonitor_(seqidGuard, sync_.seqidToMonitorMap_[seqid_]); sync_.seqidToMonitorMap_.erase(seqid_); if(committed_) sync_.wakeupAnyone_(seqidGuard); else sync_.markBad_(seqidGuard); } sync_.getReadMutex().unlock(); } void TConcurrentRecvSentry::commit() { committed_ = true; } TConcurrentSendSentry::TConcurrentSendSentry(TConcurrentClientSyncInfo *sync) : sync_(*sync), committed_(false) { sync_.getWriteMutex().lock(); } TConcurrentSendSentry::~TConcurrentSendSentry() { if(!committed_) { Guard seqidGuard(sync_.seqidMutex_); sync_.markBad_(seqidGuard); } sync_.getWriteMutex().unlock(); } void TConcurrentSendSentry::commit() { committed_ = true; } }}} // apache::thrift::async thrift-0.23.0/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.cpp0000664000175000017500000000364215165535636025465 0ustar00buildbuild00000000000000/* * 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 using apache::thrift::transport::TBufferBase; using apache::thrift::protocol::TProtocol; namespace apache { namespace thrift { namespace async { void TAsyncProtocolProcessor::process(std::function _return, std::shared_ptr ibuf, std::shared_ptr obuf) { std::shared_ptr iprot(pfact_->getProtocol(ibuf)); std::shared_ptr oprot(pfact_->getProtocol(obuf)); return underlying_ ->process(std::bind(&TAsyncProtocolProcessor::finish, _return, oprot, std::placeholders::_1), iprot, oprot); } /* static */ void TAsyncProtocolProcessor::finish( std::function _return, std::shared_ptr oprot, bool healthy) { (void)oprot; // This is a stub function to hold a reference to oprot. return _return(healthy); } } } } // apache::thrift::async thrift-0.23.0/lib/cpp/src/thrift/async/TEvhttpServer.cpp0000664000175000017500000001135015165535636023422 0ustar00buildbuild00000000000000/* * 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 #include #include #include #ifndef HTTP_INTERNAL // libevent < 2 #define HTTP_INTERNAL 500 #endif using apache::thrift::transport::TMemoryBuffer; using std::shared_ptr; namespace apache { namespace thrift { namespace async { struct TEvhttpServer::RequestContext { struct evhttp_request* req; std::shared_ptr ibuf; std::shared_ptr obuf; RequestContext(struct evhttp_request* req); }; TEvhttpServer::TEvhttpServer(std::shared_ptr processor) : processor_(processor), eb_(nullptr), eh_(nullptr) { } TEvhttpServer::TEvhttpServer(std::shared_ptr processor, int port) : processor_(processor), eb_(nullptr), eh_(nullptr) { // Create event_base and evhttp. eb_ = event_base_new(); if (eb_ == nullptr) { throw TException("event_base_new failed"); } eh_ = evhttp_new(eb_); if (eh_ == nullptr) { event_base_free(eb_); throw TException("evhttp_new failed"); } // Bind to port. int ret = evhttp_bind_socket(eh_, nullptr, port); if (ret < 0) { evhttp_free(eh_); event_base_free(eb_); throw TException("evhttp_bind_socket failed"); } // Register a handler. If you use the other constructor, // you will want to do this yourself. // Don't forget to unregister before destorying this TEvhttpServer. evhttp_set_cb(eh_, "/", request, (void*)this); } TEvhttpServer::~TEvhttpServer() { if (eh_ != nullptr) { evhttp_free(eh_); } if (eb_ != nullptr) { event_base_free(eb_); } } int TEvhttpServer::serve() { if (eb_ == nullptr) { throw TException("Unexpected call to TEvhttpServer::serve"); } return event_base_dispatch(eb_); } TEvhttpServer::RequestContext::RequestContext(struct evhttp_request* req) : req(req), ibuf(new TMemoryBuffer(EVBUFFER_DATA(req->input_buffer), static_cast(EVBUFFER_LENGTH(req->input_buffer)))), obuf(new TMemoryBuffer()) { } void TEvhttpServer::request(struct evhttp_request* req, void* self) { try { static_cast(self)->process(req); } catch (std::exception& e) { evhttp_send_reply(req, HTTP_INTERNAL, e.what(), nullptr); } } void TEvhttpServer::process(struct evhttp_request* req) { auto* ctx = new RequestContext(req); return processor_->process(std::bind(&TEvhttpServer::complete, this, ctx, std::placeholders::_1), ctx->ibuf, ctx->obuf); } void TEvhttpServer::complete(RequestContext* ctx, bool success) { (void)success; std::unique_ptr ptr(ctx); int code = success ? 200 : 400; const char* reason = success ? "OK" : "Bad Request"; 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__ << '\n'; } struct evbuffer* buf = evbuffer_new(); if (buf == nullptr) { // TODO: Log an error. std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << '\n'; } else { uint8_t* obuf; uint32_t sz; ctx->obuf->getBuffer(&obuf, &sz); int ret = evbuffer_add(buf, obuf, sz); if (ret != 0) { // TODO: Log an error. std::cerr << "evhttp_add failed with " << ret << " " << __FILE__ << ":" << __LINE__ << '\n'; } } evhttp_send_reply(ctx->req, code, reason, buf); if (buf != nullptr) { evbuffer_free(buf); } } struct event_base* TEvhttpServer::getEventBase() { return eb_; } } } } // apache::thrift::async thrift-0.23.0/lib/cpp/src/thrift/async/TAsyncProcessor.h0000664000175000017500000000507015165535636023405 0ustar00buildbuild00000000000000/* * 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_TASYNCPROCESSOR_H_ #define _THRIFT_TASYNCPROCESSOR_H_ 1 #include #include #include #include namespace apache { namespace thrift { namespace async { /** * Async version of a TProcessor. It is not expected to complete by the time * the call to process returns. Instead, it calls a cob to signal completion. */ class TAsyncProcessor { public: virtual ~TAsyncProcessor() = default; virtual void process(std::function _return, std::shared_ptr in, std::shared_ptr out) = 0; void process(std::function _return, std::shared_ptr io) { return process(_return, io, io); } std::shared_ptr getEventHandler() const { return eventHandler_; } void setEventHandler(std::shared_ptr eventHandler) { eventHandler_ = eventHandler; } protected: TAsyncProcessor() = default; std::shared_ptr eventHandler_; }; class TAsyncProcessorFactory { public: virtual ~TAsyncProcessorFactory() = default; /** * Get the TAsyncProcessor to use for a particular connection. * * This method is always invoked in the same thread that the connection was * accepted on. This generally means that this call does not need to be * thread safe, as it will always be invoked from a single thread. */ virtual std::shared_ptr getProcessor(const TConnectionInfo& connInfo) = 0; }; } } } // apache::thrift::async namespace apache { namespace thrift { using apache::thrift::async::TAsyncProcessor; } } #endif // #ifndef _THRIFT_TASYNCPROCESSOR_H_ thrift-0.23.0/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp0000664000175000017500000001205515165535636024666 0ustar00buildbuild00000000000000/* * 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 #include #include #include using namespace apache::thrift::protocol; using apache::thrift::transport::TTransportException; namespace apache { namespace thrift { namespace async { TEvhttpClientChannel::TEvhttpClientChannel(const std::string& host, const std::string& path, const char* address, int port, struct event_base* eb, struct evdns_base* dnsbase) : host_(host), path_(path), conn_(nullptr) { conn_ = evhttp_connection_base_new(eb, dnsbase, address, port); if (conn_ == nullptr) { throw TException("evhttp_connection_new failed"); } } TEvhttpClientChannel::~TEvhttpClientChannel() { if (conn_ != nullptr) { evhttp_connection_free(conn_); } } void TEvhttpClientChannel::sendAndRecvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* sendBuf, apache::thrift::transport::TMemoryBuffer* recvBuf) { struct evhttp_request* req = evhttp_request_new(response, this); if (req == nullptr) { throw TException("evhttp_request_new failed"); } int rv; rv = evhttp_add_header(req->output_headers, "Host", host_.c_str()); if (rv != 0) { throw TException("evhttp_add_header failed"); } rv = evhttp_add_header(req->output_headers, "Content-Type", "application/x-thrift"); if (rv != 0) { throw TException("evhttp_add_header failed"); } uint8_t* obuf; uint32_t sz; sendBuf->getBuffer(&obuf, &sz); rv = evbuffer_add(req->output_buffer, obuf, sz); if (rv != 0) { throw TException("evbuffer_add failed"); } rv = evhttp_make_request(conn_, req, EVHTTP_REQ_POST, path_.c_str()); if (rv != 0) { throw TException("evhttp_make_request failed"); } completionQueue_.push(Completion(cob, recvBuf)); } void TEvhttpClientChannel::sendMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) { (void)cob; (void)message; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "Unexpected call to TEvhttpClientChannel::sendMessage"); } void TEvhttpClientChannel::recvMessage(const VoidCallback& cob, apache::thrift::transport::TMemoryBuffer* message) { (void)cob; (void)message; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "Unexpected call to TEvhttpClientChannel::recvMessage"); } void TEvhttpClientChannel::finish(struct evhttp_request* req) { assert(!completionQueue_.empty()); Completion completion = completionQueue_.front(); completionQueue_.pop(); if (req == nullptr) { try { completion.first(); } catch (const TTransportException& e) { if (e.getType() == TTransportException::END_OF_FILE) throw TException("connect failed"); else throw; } return; } else if (req->response_code != 200) { try { completion.first(); } catch (const TTransportException& e) { std::stringstream ss; ss << "server returned code " << req->response_code; if (req->response_code_line) ss << ": " << req->response_code_line; if (e.getType() == TTransportException::END_OF_FILE) throw TException(ss.str()); else throw; } return; } completion.second->resetBuffer(EVBUFFER_DATA(req->input_buffer), static_cast(EVBUFFER_LENGTH(req->input_buffer))); completion.first(); return; } /* static */ void TEvhttpClientChannel::response(struct evhttp_request* req, void* arg) { auto* self = (TEvhttpClientChannel*)arg; try { 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() << '\n'; } } } } } // apache::thrift::async thrift-0.23.0/lib/cpp/src/thrift/async/TEvhttpServer.h0000664000175000017500000000413615165535636023073 0ustar00buildbuild00000000000000/* * 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_TEVHTTP_SERVER_H_ #define _THRIFT_TEVHTTP_SERVER_H_ 1 #include struct event_base; struct evhttp; struct evhttp_request; namespace apache { namespace thrift { namespace async { class TAsyncBufferProcessor; class TEvhttpServer { public: /** * Create a TEvhttpServer for use with an external evhttp instance. * Must be manually installed with evhttp_set_cb, using * TEvhttpServer::request as the callback and the * address of the server as the extra arg. * Do not call "serve" on this server. */ TEvhttpServer(std::shared_ptr processor); /** * Create a TEvhttpServer with an embedded event_base and evhttp, * listening on port and responding on the endpoint "/". * Call "serve" on this server to serve forever. */ TEvhttpServer(std::shared_ptr processor, int port); virtual ~TEvhttpServer(); static void request(struct evhttp_request* req, void* self); int serve(); struct event_base* getEventBase(); private: struct RequestContext; void process(struct evhttp_request* req); void complete(RequestContext* ctx, bool success); std::shared_ptr processor_; struct event_base* eb_; struct evhttp* eh_; }; } } } // apache::thrift::async #endif // #ifndef _THRIFT_TEVHTTP_SERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/TApplicationException.cpp0000664000175000017500000000466715165535636024003 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { uint32_t TApplicationException::read(apache::thrift::protocol::TProtocol* iprot) { uint32_t xfer = 0; std::string fname; apache::thrift::protocol::TType ftype; int16_t fid; xfer += iprot->readStructBegin(fname); while (true) { xfer += iprot->readFieldBegin(fname, ftype, fid); if (ftype == apache::thrift::protocol::T_STOP) { break; } switch (fid) { case 1: if (ftype == apache::thrift::protocol::T_STRING) { xfer += iprot->readString(message_); } else { xfer += iprot->skip(ftype); } break; case 2: if (ftype == apache::thrift::protocol::T_I32) { int32_t type; xfer += iprot->readI32(type); type_ = (TApplicationExceptionType)type; } else { xfer += iprot->skip(ftype); } break; default: xfer += iprot->skip(ftype); break; } xfer += iprot->readFieldEnd(); } xfer += iprot->readStructEnd(); return xfer; } uint32_t TApplicationException::write(apache::thrift::protocol::TProtocol* oprot) const { uint32_t xfer = 0; xfer += oprot->writeStructBegin("TApplicationException"); xfer += oprot->writeFieldBegin("message", apache::thrift::protocol::T_STRING, 1); xfer += oprot->writeString(message_); xfer += oprot->writeFieldEnd(); xfer += oprot->writeFieldBegin("type", apache::thrift::protocol::T_I32, 2); xfer += oprot->writeI32(type_); xfer += oprot->writeFieldEnd(); xfer += oprot->writeFieldStop(); xfer += oprot->writeStructEnd(); return xfer; } } } // apache::thrift thrift-0.23.0/lib/cpp/src/thrift/transport/0000755000175000017500000000000015170007200021017 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp0000664000175000017500000005113715167543515026507 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_UN_H #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_SYS_POLL_H #include #endif #ifdef HAVE_NETINET_IN_H #include #include #endif #ifdef HAVE_NETDB_H #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #include #include #include #include #include #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif #ifndef SOCKOPT_CAST_T #ifndef _WIN32 #define SOCKOPT_CAST_T void #else #define SOCKOPT_CAST_T char #endif // _WIN32 #endif #if _WIN32 #include #endif template inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v) { return reinterpret_cast(v); } template inline SOCKOPT_CAST_T* cast_sockopt(T* v) { return reinterpret_cast(v); } using std::shared_ptr; using std::string; namespace apache { namespace thrift { namespace transport { TNonblockingServerSocket::TNonblockingServerSocket(int port) : port_(port), listenPort_(port), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(0), recvTimeout_(0), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false) { } TNonblockingServerSocket::TNonblockingServerSocket(int port, int sendTimeout, int recvTimeout) : port_(port), listenPort_(port), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(sendTimeout), recvTimeout_(recvTimeout), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false) { } TNonblockingServerSocket::TNonblockingServerSocket(const string& address, int port) : port_(port), listenPort_(port), address_(address), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(0), recvTimeout_(0), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false) { } TNonblockingServerSocket::TNonblockingServerSocket(const string& path) : port_(0), listenPort_(0), path_(path), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(0), recvTimeout_(0), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false) { } TNonblockingServerSocket::~TNonblockingServerSocket() { close(); } bool TNonblockingServerSocket::isOpen() const { if (serverSocket_ == THRIFT_INVALID_SOCKET) return false; if (!listening_) return false; if (isUnixDomainSocket() && (path_[0] != '\0')) { // On some platforms the domain socket file may not be instantly // available yet, i.e. the Windows file system can be slow. Therefore // we should check that the domain socket file actually exists. #ifdef _MSC_VER // Currently there is a bug in ClangCl on Windows so the stat() call // does not work. Workaround is a Windows-specific call if file exists: DWORD const f_attrib = GetFileAttributesA(path_.c_str()); if (f_attrib == INVALID_FILE_ATTRIBUTES) { #else struct THRIFT_STAT path_info; if (::THRIFT_STAT(path_.c_str(), &path_info) < 0) { #endif const std::string vError = "TNonblockingServerSocket::isOpen(): The domain socket path '" + path_ + "' does not exist (yet)."; TOutput::instance().perror(vError.c_str(), THRIFT_GET_SOCKET_ERROR); return false; } } return true; } void TNonblockingServerSocket::setSendTimeout(int sendTimeout) { sendTimeout_ = sendTimeout; } void TNonblockingServerSocket::setRecvTimeout(int recvTimeout) { recvTimeout_ = recvTimeout; } void TNonblockingServerSocket::setAcceptBacklog(int accBacklog) { acceptBacklog_ = accBacklog; } void TNonblockingServerSocket::setRetryLimit(int retryLimit) { retryLimit_ = retryLimit; } void TNonblockingServerSocket::setRetryDelay(int retryDelay) { retryDelay_ = retryDelay; } void TNonblockingServerSocket::setTcpSendBuffer(int tcpSendBuffer) { tcpSendBuffer_ = tcpSendBuffer; } void TNonblockingServerSocket::setTcpRecvBuffer(int tcpRecvBuffer) { tcpRecvBuffer_ = tcpRecvBuffer; } void TNonblockingServerSocket::_setup_sockopts() { int one = 1; if (!isUnixDomainSocket()) { // Set THRIFT_NO_SOCKET_CACHING to prevent 2MSL delay on accept. // This does not work with Domain sockets on most platforms. And // on Windows it completely breaks the socket. Therefore do not // use this on Domain sockets. if (-1 == setsockopt(serverSocket_, SOL_SOCKET, THRIFT_NO_SOCKET_CACHING, cast_sockopt(&one), sizeof(one))) { // NOTE: SO_EXCLUSIVEADDRUSE socket option can only be used by members // of the Administrators security group on Windows XP and earlier. But // we do not target WinXP anymore so no special checks required. int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set THRIFT_NO_SOCKET_CACHING", errno_copy); } } // Set TCP buffer sizes if (tcpSendBuffer_ > 0) { if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_SNDBUF, cast_sockopt(&tcpSendBuffer_), sizeof(tcpSendBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", errno_copy); } } if (tcpRecvBuffer_ > 0) { if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_RCVBUF, cast_sockopt(&tcpRecvBuffer_), sizeof(tcpRecvBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", errno_copy); } } // Turn linger off, don't want to block on calls to close struct linger ling = {0, 0}; if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER, cast_sockopt(&ling), sizeof(ling))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_LINGER ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy); } // Keepalive to ensure full result flushing if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_KEEPALIVE, const_cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_KEEPALIVE ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy); } #ifdef SO_NOSIGPIPE if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() SO_NOSIGPIPE", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_NOSIGPIPE", errno_copy); } #endif // Set NONBLOCK on the accept socket int flags = THRIFT_FCNTL(serverSocket_, THRIFT_F_GETFL, 0); if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_GETFL failed", errno_copy); } if (-1 == THRIFT_FCNTL(serverSocket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_SETFL THRIFT_O_NONBLOCK failed", errno_copy); } } void TNonblockingServerSocket::_setup_unixdomain_sockopts() { } void TNonblockingServerSocket::_setup_tcp_sockopts() { int one = 1; // Set TCP nodelay if available, MAC OS X Hack // See http://lists.danga.com/pipermail/memcached/2005-March/001240.html #ifndef TCP_NOPUSH // TCP Nodelay, speed over bandwidth if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY, cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy); } #endif #ifdef TCP_LOW_MIN_RTO if (TSocket::getUseLowMinRto()) { if (-1 == setsockopt(s, IPPROTO_TCP, TCP_LOW_MIN_RTO, const_cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() setsockopt() TCP_LOW_MIN_RTO ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy); } } #endif } // _setup_tcp_sockopts() void TNonblockingServerSocket::listen() { #ifdef _WIN32 TWinsockSingleton::create(); #endif // _WIN32 // Validate port number if (port_ < 0 || port_ > 0xFFFF) { throw TTransportException(TTransportException::BAD_ARGS, "Specified port is invalid"); } // Resolve host:port strings into an iterable of struct addrinfo* AddressResolutionHelper resolved_addresses; if (!isUnixDomainSocket()) { try { resolved_addresses.resolve(address_, std::to_string(port_), SOCK_STREAM, #ifdef ANDROID AI_PASSIVE | AI_ADDRCONFIG); #else AI_PASSIVE | AI_V4MAPPED); #endif } catch (const std::system_error& e) { TOutput::instance().printf("getaddrinfo() -> %d; %s", e.code().value(), e.what()); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for server socket."); } } // we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't // always seem to work. The client can configure the retry variables. int retries = 0; int errno_copy = 0; if (isUnixDomainSocket()) { // -- Unix Domain Socket -- // serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP); if (serverSocket_ == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy); } _setup_sockopts(); _setup_unixdomain_sockopts(); // Windows supports Unix domain sockets since it ships the header // HAVE_AF_UNIX_H (see https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/) #if (!defined(_WIN32) || defined(HAVE_AF_UNIX_H)) struct sockaddr_un address; socklen_t structlen = fillUnixSocketAddr(address, path_); do { if (0 == ::bind(serverSocket_, (struct sockaddr*)&address, structlen)) { break; } errno_copy = THRIFT_GET_SOCKET_ERROR; // use short circuit evaluation here to only sleep if we need to } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); #else TOutput::instance().perror("TNonblockingServerSocket::open() Unix Domain socket path not supported on this version of Windows", -99); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported"); #endif } else { // -- TCP socket -- // auto addr_iter = AddressResolutionHelper::Iter{}; // Via DNS or somehow else, single hostname can resolve into many addresses. // Results may contain perhaps a mix of IPv4 and IPv6. Here, we iterate // over what system gave us, picking the first address that works. do { if (!addr_iter) { // init + recycle over many retries addr_iter = resolved_addresses.iterate(); } auto trybind = *addr_iter++; serverSocket_ = socket(trybind->ai_family, trybind->ai_socktype, trybind->ai_protocol); if (serverSocket_ == -1) { errno_copy = THRIFT_GET_SOCKET_ERROR; continue; } _setup_sockopts(); _setup_tcp_sockopts(); #ifdef IPV6_V6ONLY if (trybind->ai_family == AF_INET6) { int zero = 0; if (-1 == setsockopt(serverSocket_, IPPROTO_IPV6, IPV6_V6ONLY, cast_sockopt(&zero), sizeof(zero))) { TOutput::instance().perror("TNonblockingServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR); } } #endif // #ifdef IPV6_V6ONLY if (0 == ::bind(serverSocket_, trybind->ai_addr, static_cast(trybind->ai_addrlen))) { break; } errno_copy = THRIFT_GET_SOCKET_ERROR; // use short circuit evaluation here to only sleep if we need to } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); // retrieve bind info if (port_ == 0 && retries <= retryLimit_) { struct sockaddr_storage sa; socklen_t len = sizeof(sa); std::memset(&sa, 0, len); if (::getsockname(serverSocket_, reinterpret_cast(&sa), &len) < 0) { errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::getPort() getsockname() ", errno_copy); } else { if (sa.ss_family == AF_INET6) { const auto* sin = reinterpret_cast(&sa); listenPort_ = ntohs(sin->sin6_port); } else { const auto* sin = reinterpret_cast(&sa); listenPort_ = ntohs(sin->sin_port); } } } } // TCP socket // // throw error if socket still wasn't created successfully if (serverSocket_ == THRIFT_INVALID_SOCKET) { TOutput::instance().perror("TNonblockingServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy); } // throw an error if we failed to bind properly if (retries > retryLimit_) { char errbuf[1024]; if (isUnixDomainSocket()) { #ifdef _WIN32 THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TNonblockingServerSocket::listen() Could not bind to domain socket path %s, error %d", path_.c_str(), WSAGetLastError()); #else // Fixme: This does not currently handle abstract domain sockets: THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TNonblockingServerSocket::listen() Could not bind to domain socket path %s", path_.c_str()); #endif } else { THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TNonblockingServerSocket::listen() Could not bind to port %d", port_); } TOutput::instance()(errbuf); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not bind", errno_copy); } if (listenCallback_) listenCallback_(serverSocket_); // Call listen if (-1 == ::listen(serverSocket_, acceptBacklog_)) { errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::listen() listen() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy); } // The socket is now listening! listening_ = true; } int TNonblockingServerSocket::getPort() { return port_; } int TNonblockingServerSocket::getListenPort() { return listenPort_; } std::string TNonblockingServerSocket::getPath() const { return path_; } bool TNonblockingServerSocket::isUnixDomainSocket() const { return !path_.empty(); } shared_ptr TNonblockingServerSocket::acceptImpl() { if (serverSocket_ == THRIFT_INVALID_SOCKET) { throw TTransportException(TTransportException::NOT_OPEN, "TNonblockingServerSocket not listening"); } struct sockaddr_storage clientAddress; int size = sizeof(clientAddress); THRIFT_SOCKET clientSocket = ::accept(serverSocket_, (struct sockaddr*)&clientAddress, (socklen_t*)&size); if (clientSocket == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TNonblockingServerSocket::acceptImpl() ::accept() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy); } // Explicitly set this socket to NONBLOCK mode int flags = THRIFT_FCNTL(clientSocket, THRIFT_F_GETFL, 0); if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); TOutput::instance().perror("TNonblockingServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_GETFL)", errno_copy); } if (-1 == THRIFT_FCNTL(clientSocket, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); TOutput::instance() .perror("TNonblockingServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_SETFL ~THRIFT_O_NONBLOCK ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_SETFL)", errno_copy); } shared_ptr client = createSocket(clientSocket); client->setPath(path_); if (sendTimeout_ > 0) { client->setSendTimeout(sendTimeout_); } if (recvTimeout_ > 0) { client->setRecvTimeout(recvTimeout_); } if (keepAlive_) { client->setKeepAlive(keepAlive_); } client->setCachedAddress((sockaddr*)&clientAddress, size); if (acceptCallback_) acceptCallback_(clientSocket); return client; } shared_ptr TNonblockingServerSocket::createSocket(THRIFT_SOCKET clientSocket) { return std::make_shared(clientSocket); } void TNonblockingServerSocket::close() { if (serverSocket_ != THRIFT_INVALID_SOCKET) { shutdown(serverSocket_, THRIFT_SHUT_RDWR); ::THRIFT_CLOSESOCKET(serverSocket_); } serverSocket_ = THRIFT_INVALID_SOCKET; listening_ = false; } } // namespace transport } // namespace thrift } // namespace apache thrift-0.23.0/lib/cpp/src/thrift/transport/TWebSocketServer.cpp0000664000175000017500000000317715165535636024765 0ustar00buildbuild00000000000000/* * 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 #include using std::string; namespace apache { namespace thrift { namespace transport { std::string base64Encode(unsigned char* data, int length) { std::unique_ptr> base64(BIO_new(BIO_f_base64()), [](BIO* b) { BIO_free_all(b); }); BIO_set_flags(base64.get(), BIO_FLAGS_BASE64_NO_NL); BIO* dest = BIO_new(BIO_s_mem()); BIO_push(base64.get(), dest); BIO_write(base64.get(), data, length); int ret = BIO_flush(base64.get()); THRIFT_UNUSED_VARIABLE(ret); char* encoded; length = BIO_get_mem_data(dest, &encoded); return std::string(encoded, length); } } // namespace transport } // namespace thrift } // namespace apache thrift-0.23.0/lib/cpp/src/thrift/transport/TTransportUtils.cpp0000664000175000017500000001123615165535636024720 0ustar00buildbuild00000000000000/* * 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 using std::string; namespace apache { namespace thrift { namespace transport { uint32_t TPipedTransport::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); uint32_t need = len; // We don't have enough data yet if (rLen_ - rPos_ < need) { // Copy out whatever we have if (rLen_ - rPos_ > 0) { memcpy(buf, rBuf_ + rPos_, rLen_ - rPos_); need -= rLen_ - rPos_; buf += rLen_ - rPos_; rPos_ = rLen_; } // Double the size of the underlying buffer if it is full if (rLen_ == rBufSize_) { rBufSize_ *= 2; auto *tmpBuf = (uint8_t*)std::realloc(rBuf_, sizeof(uint8_t) * rBufSize_); if (tmpBuf == nullptr) { throw std::bad_alloc(); } rBuf_ = tmpBuf; } // try to fill up the buffer rLen_ += srcTrans_->read(rBuf_ + rPos_, rBufSize_ - rPos_); } // Hand over whatever we have uint32_t give = need; if (rLen_ - rPos_ < give) { give = rLen_ - rPos_; } if (give > 0) { memcpy(buf, rBuf_ + rPos_, give); rPos_ += give; need -= give; } return (len - need); } void TPipedTransport::write(const uint8_t* buf, uint32_t len) { if (len == 0) { return; } // Make the buffer as big as it needs to be if ((len + wLen_) >= wBufSize_) { uint32_t newBufSize = wBufSize_ * 2; while ((len + wLen_) >= newBufSize) { newBufSize *= 2; } auto *tmpBuf= (uint8_t*)std::realloc(wBuf_, sizeof(uint8_t) * newBufSize); if (tmpBuf == nullptr) { throw std::bad_alloc(); } wBuf_ = tmpBuf; wBufSize_ = newBufSize; } // Copy into the buffer memcpy(wBuf_ + wLen_, buf, len); wLen_ += len; } void TPipedTransport::flush() { // Write out any data waiting in the write buffer if (wLen_ > 0) { srcTrans_->write(wBuf_, wLen_); wLen_ = 0; } // Flush the underlying transport srcTrans_->flush(); } TPipedFileReaderTransport::TPipedFileReaderTransport( std::shared_ptr srcTrans, std::shared_ptr dstTrans, std::shared_ptr config) : TPipedTransport(srcTrans, dstTrans, config), srcTrans_(srcTrans) { } TPipedFileReaderTransport::~TPipedFileReaderTransport() = default; bool TPipedFileReaderTransport::isOpen() const { return TPipedTransport::isOpen(); } bool TPipedFileReaderTransport::peek() { return TPipedTransport::peek(); } void TPipedFileReaderTransport::open() { TPipedTransport::open(); } void TPipedFileReaderTransport::close() { TPipedTransport::close(); } uint32_t TPipedFileReaderTransport::read(uint8_t* buf, uint32_t len) { return TPipedTransport::read(buf, len); } uint32_t TPipedFileReaderTransport::readAll(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); uint32_t have = 0; uint32_t get = 0; while (have < len) { get = read(buf + have, len - have); if (get <= 0) { throw TEOFException(); } have += get; } return have; } uint32_t TPipedFileReaderTransport::readEnd() { return TPipedTransport::readEnd(); } void TPipedFileReaderTransport::write(const uint8_t* buf, uint32_t len) { TPipedTransport::write(buf, len); } uint32_t TPipedFileReaderTransport::writeEnd() { return TPipedTransport::writeEnd(); } void TPipedFileReaderTransport::flush() { TPipedTransport::flush(); } int32_t TPipedFileReaderTransport::getReadTimeout() { return srcTrans_->getReadTimeout(); } void TPipedFileReaderTransport::setReadTimeout(int32_t readTimeout) { srcTrans_->setReadTimeout(readTimeout); } uint32_t TPipedFileReaderTransport::getNumChunks() { return srcTrans_->getNumChunks(); } uint32_t TPipedFileReaderTransport::getCurChunk() { return srcTrans_->getCurChunk(); } void TPipedFileReaderTransport::seekToChunk(int32_t chunk) { srcTrans_->seekToChunk(chunk); } void TPipedFileReaderTransport::seekToEnd() { srcTrans_->seekToEnd(); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/THttpServer.cpp0000664000175000017500000001256615165535636024020 0ustar00buildbuild00000000000000/* * 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 #include #if defined(_MSC_VER) || defined(__MINGW32__) #include #endif using std::string; namespace apache { namespace thrift { namespace transport { THttpServer::THttpServer(std::shared_ptr transport, std::shared_ptr config) : THttpTransport(transport, config) { } THttpServer::~THttpServer() = default; #if defined(_MSC_VER) || defined(__MINGW32__) #define THRIFT_GMTIME(TM, TIME) gmtime_s(&TM, &TIME) #define THRIFT_strncasecmp(str1, str2, len) _strnicmp(str1, str2, len) #define THRIFT_strcasestr(haystack, needle) StrStrIA(haystack, needle) #else #define THRIFT_GMTIME(TM, TIME) gmtime_r(&TIME, &TM) #define THRIFT_strncasecmp(str1, str2, len) strncasecmp(str1, str2, len) #define THRIFT_strcasestr(haystack, needle) strcasestr(haystack, needle) #endif void THttpServer::parseHeader(char* header) { char* colon = strchr(header, ':'); if (colon == nullptr) { return; } size_t sz = colon - header; char* value = colon + 1; if (THRIFT_strncasecmp(header, "Transfer-Encoding", sz) == 0) { if (THRIFT_strcasestr(value, "chunked") != nullptr) { chunked_ = true; } } else if (THRIFT_strncasecmp(header, "Content-length", sz) == 0) { chunked_ = false; contentLength_ = atoi(value); } else if (strncmp(header, "X-Forwarded-For", sz) == 0) { origin_ = value; } } bool THttpServer::parseStatusLine(char* status) { char* method = status; char* path = strchr(method, ' '); if (path == nullptr) { throw TTransportException(string("Bad Status: ") + status); } *path = '\0'; while (*(++path) == ' ') { }; char* http = strchr(path, ' '); if (http == nullptr) { throw TTransportException(string("Bad Status: ") + status); } *http = '\0'; if (strcmp(method, "POST") == 0) { // POST method ok, looking for content. return true; } else if (strcmp(method, "OPTIONS") == 0) { // preflight OPTIONS method, we don't need further content. // how to graciously close connection? uint8_t* buf; uint32_t len; writeBuffer_.getBuffer(&buf, &len); // Construct the HTTP header std::ostringstream h; h << "HTTP/1.1 200 OK" << CRLF << "Date: " << getTimeRFC1123() << CRLF << "Access-Control-Allow-Origin: *" << CRLF << "Access-Control-Allow-Methods: POST, OPTIONS" << CRLF << "Access-Control-Allow-Headers: Content-Type" << CRLF << CRLF; string header = h.str(); // Write the header, then the data, then flush transport_->write((const uint8_t*)header.c_str(), static_cast(header.size())); transport_->write(buf, len); transport_->flush(); // Reset the buffer and header variables writeBuffer_.resetBuffer(); readHeaders_ = true; return true; } throw TTransportException(string("Bad Status (unsupported method): ") + status); } void THttpServer::flush() { resetConsumedMessageSize(); // Fetch the contents of the write buffer uint8_t* buf; uint32_t len; writeBuffer_.getBuffer(&buf, &len); // Construct the HTTP header string header = getHeader(len); // Write the header, then the data, then flush // cast should be fine, because none of "header" is under attacker control transport_->write((const uint8_t*)header.c_str(), static_cast(header.size())); transport_->write(buf, len); transport_->flush(); // Reset the buffer and header variables writeBuffer_.resetBuffer(); readHeaders_ = true; } std::string THttpServer::getHeader(uint32_t len) { std::ostringstream h; h << "HTTP/1.1 200 OK" << CRLF << "Date: " << getTimeRFC1123() << CRLF << "Server: Thrift/" << PACKAGE_VERSION << CRLF << "Access-Control-Allow-Origin: *" << CRLF << "Content-Type: application/x-thrift" << CRLF << "Content-Length: " << len << CRLF << "Connection: Keep-Alive" << CRLF << CRLF; return h.str(); } std::string THttpServer::getTimeRFC1123() { static const char* Days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; static const char* Months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; char buff[128]; time_t t = time(nullptr); struct tm tmb; THRIFT_GMTIME(tmb, t); sprintf(buff, "%s, %d %s %d %d:%d:%d GMT", Days[tmb.tm_wday], tmb.tm_mday, Months[tmb.tm_mon], tmb.tm_year + 1900, tmb.tm_hour, tmb.tm_min, tmb.tm_sec); return std::string(buff); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TServerSocket.h0000664000175000017500000001347315167543515023771 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSERVERSOCKET_H_ #define _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 1 #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETDB_H #include #endif namespace apache { namespace thrift { namespace transport { class TSocket; enum class SocketType { NONE, INET, INET6, UNIX }; /** * Server socket implementation of TServerTransport. Wrapper around a unix * socket listen and accept calls. * */ class TServerSocket : public TServerTransport { public: typedef std::function socket_func_t; const static int DEFAULT_BACKLOG = 1024; /** * Constructor. * * @param port Port number to bind to */ TServerSocket(int port); /** * Constructor. * * @param port Port number to bind to * @param sendTimeout Socket send timeout * @param recvTimeout Socket receive timeout */ TServerSocket(int port, int sendTimeout, int recvTimeout); /** * Constructor. * * @param address Address to bind to * @param port Port number to bind to */ TServerSocket(const std::string& address, int port); /** * Constructor used for unix sockets. * * @param path Pathname for unix socket. */ TServerSocket(const std::string& path); /** * Constructor used for to initialize from an already bound unix socket. * Useful for socket activation on systemd. * * @param fd */ TServerSocket(THRIFT_SOCKET sock,SocketType socketType); ~TServerSocket() override; bool isOpen() const override; void setSendTimeout(int sendTimeout); void setRecvTimeout(int recvTimeout); void setAcceptTimeout(int accTimeout); void setAcceptBacklog(int accBacklog); void setRetryLimit(int retryLimit); void setRetryDelay(int retryDelay); void setKeepAlive(bool keepAlive) { keepAlive_ = keepAlive; } void setTcpSendBuffer(int tcpSendBuffer); void setTcpRecvBuffer(int tcpRecvBuffer); // listenCallback gets called just before listen, and after all Thrift // setsockopt calls have been made. If you have custom setsockopt // things that need to happen on the listening socket, this is the place to do it. void setListenCallback(const socket_func_t& listenCallback) { listenCallback_ = listenCallback; } // acceptCallback gets called after each accept call, on the newly created socket. // It is called after all Thrift setsockopt calls have been made. If you have // custom setsockopt things that need to happen on the accepted // socket, this is the place to do it. void setAcceptCallback(const socket_func_t& acceptCallback) { acceptCallback_ = acceptCallback; } // When enabled (the default), new children TSockets will be constructed so // they can be interrupted by TServerTransport::interruptChildren(). // This is more expensive in terms of system calls (poll + recv) however // ensures a connected client cannot interfere with TServer::stop(). // // When disabled, TSocket children do not incur an additional poll() call. // Server-side reads are more efficient, however a client can interfere with // the server's ability to shutdown properly by staying connected. // // Must be called before listen(); mode cannot be switched after that. // \throws std::logic_error if listen() has been called void setInterruptableChildren(bool enable); THRIFT_SOCKET getSocketFD() override { return serverSocket_; } int getPort() const; std::string getPath() const; bool isUnixDomainSocket() const; void listen() override; void interrupt() override; void interruptChildren() override; void close() override; protected: std::shared_ptr acceptImpl() override; virtual std::shared_ptr createSocket(THRIFT_SOCKET client); bool interruptableChildren_; std::shared_ptr pChildInterruptSockReader_; // if interruptableChildren_ this is shared with child TSockets private: void notify(THRIFT_SOCKET notifySock); void _setup_sockopts(); void _setup_unixdomain_sockopts(); void _setup_tcp_sockopts(); int port_; std::string address_; std::string path_; THRIFT_SOCKET serverSocket_; int acceptBacklog_; int sendTimeout_; int recvTimeout_; int accTimeout_; int retryLimit_; int retryDelay_; int tcpSendBuffer_; int tcpRecvBuffer_; bool keepAlive_; bool listening_; concurrency::Mutex rwMutex_; // thread-safe interrupt THRIFT_SOCKET interruptSockWriter_; // is notified on interrupt() THRIFT_SOCKET interruptSockReader_; // is used in select/poll with serverSocket_ for interruptability THRIFT_SOCKET childInterruptSockWriter_; // is notified on interruptChildren() socket_func_t listenCallback_; socket_func_t acceptCallback_; SocketType boundSocketType_; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TSERVERSOCKET_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TPipe.cpp0000664000175000017500000003253015167543515022575 0ustar00buildbuild00000000000000/* * 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 #ifdef _WIN32 #include #include #endif namespace apache { namespace thrift { namespace transport { /** * TPipe implementation. */ #ifdef _WIN32 uint32_t pipe_read(HANDLE pipe, uint8_t* buf, uint32_t len); void pipe_write(HANDLE pipe, const uint8_t* buf, uint32_t len); uint32_t pseudo_sync_read(HANDLE pipe, HANDLE event, uint8_t* buf, uint32_t len); void pseudo_sync_write(HANDLE pipe, HANDLE event, const uint8_t* buf, uint32_t len); class TPipeImpl : apache::thrift::TNonCopyable { public: TPipeImpl() {} virtual ~TPipeImpl() {} virtual uint32_t read(uint8_t* buf, uint32_t len) = 0; virtual void write(const uint8_t* buf, uint32_t len) = 0; virtual HANDLE getPipeHandle() = 0; // doubles as the read handle for anon pipe virtual void setPipeHandle(HANDLE pipehandle) = 0; virtual HANDLE getWrtPipeHandle() { return INVALID_HANDLE_VALUE; } virtual void setWrtPipeHandle(HANDLE) {} virtual bool isBufferedDataAvailable() { return false; } virtual HANDLE getNativeWaitHandle() { return INVALID_HANDLE_VALUE; } }; class TNamedPipeImpl : public TPipeImpl { public: explicit TNamedPipeImpl(TAutoHandle &pipehandle) : Pipe_(pipehandle.release()) {} virtual ~TNamedPipeImpl() {} virtual uint32_t read(uint8_t* buf, uint32_t len) { return pseudo_sync_read(Pipe_.h, read_event_.h, buf, len); } virtual void write(const uint8_t* buf, uint32_t len) { pseudo_sync_write(Pipe_.h, write_event_.h, buf, len); } virtual HANDLE getPipeHandle() { return Pipe_.h; } virtual void setPipeHandle(HANDLE pipehandle) { Pipe_.reset(pipehandle); } private: TManualResetEvent read_event_; TManualResetEvent write_event_; TAutoHandle Pipe_; }; class TAnonPipeImpl : public TPipeImpl { public: TAnonPipeImpl(HANDLE PipeRd, HANDLE PipeWrt) : PipeRd_(PipeRd), PipeWrt_(PipeWrt) {} virtual ~TAnonPipeImpl() {} virtual uint32_t read(uint8_t* buf, uint32_t len) { return pipe_read(PipeRd_.h, buf, len); } virtual void write(const uint8_t* buf, uint32_t len) { pipe_write(PipeWrt_.h, buf, len); } virtual HANDLE getPipeHandle() { return PipeRd_.h; } virtual void setPipeHandle(HANDLE PipeRd) { PipeRd_.reset(PipeRd); } virtual HANDLE getWrtPipeHandle() { return PipeWrt_.h; } virtual void setWrtPipeHandle(HANDLE PipeWrt) { PipeWrt_.reset(PipeWrt); } private: TAutoHandle PipeRd_; TAutoHandle PipeWrt_; }; // If you want a select-like loop to work, use this subclass. Be warned... // the read implementation has several context switches, so this is slower // than using the regular named pipe implementation class TWaitableNamedPipeImpl : public TPipeImpl { public: explicit TWaitableNamedPipeImpl(TAutoHandle &pipehandle) : begin_unread_idx_(0), end_unread_idx_(0) { readOverlap_.action = TOverlappedWorkItem::READ; readOverlap_.h = pipehandle.h; cancelOverlap_.action = TOverlappedWorkItem::CANCELIO; cancelOverlap_.h = pipehandle.h; buffer_.resize(1024 /*arbitrary buffer size*/, '\0'); beginAsyncRead(&buffer_[0], static_cast(buffer_.size())); Pipe_.reset(pipehandle.release()); } virtual ~TWaitableNamedPipeImpl() { // see if there is an outstanding read request if (begin_unread_idx_ == end_unread_idx_) { // if so, cancel it, and wait for the dead completion thread_->addWorkItem(&cancelOverlap_); readOverlap_.overlappedResults(false /*ignore errors*/); } } virtual uint32_t read(uint8_t* buf, uint32_t len); virtual void write(const uint8_t* buf, uint32_t len) { pseudo_sync_write(Pipe_.h, write_event_.h, buf, len); } virtual HANDLE getPipeHandle() { return Pipe_.h; } virtual void setPipeHandle(HANDLE pipehandle) { Pipe_.reset(pipehandle); } virtual bool isBufferedDataAvailable() { return begin_unread_idx_ < end_unread_idx_; } virtual HANDLE getNativeWaitHandle() { return ready_event_.h; } private: void beginAsyncRead(uint8_t* buf, uint32_t len); uint32_t endAsyncRead(); TAutoOverlapThread thread_; TAutoHandle Pipe_; TOverlappedWorkItem readOverlap_; TOverlappedWorkItem cancelOverlap_; TManualResetEvent ready_event_; TManualResetEvent write_event_; std::vector buffer_; uint32_t begin_unread_idx_; uint32_t end_unread_idx_; }; void TWaitableNamedPipeImpl::beginAsyncRead(uint8_t* buf, uint32_t len) { begin_unread_idx_ = end_unread_idx_ = 0; readOverlap_.reset(buf, len, ready_event_.h); thread_->addWorkItem(&readOverlap_); if (readOverlap_.success == FALSE && readOverlap_.last_error != ERROR_IO_PENDING) { TOutput::instance().perror("TPipe ::ReadFile errored GLE=", readOverlap_.last_error); throw TTransportException(TTransportException::UNKNOWN, "TPipe: ReadFile failed"); } } uint32_t TWaitableNamedPipeImpl::endAsyncRead() { return readOverlap_.overlappedResults(); } uint32_t TWaitableNamedPipeImpl::read(uint8_t* buf, uint32_t len) { if (begin_unread_idx_ == end_unread_idx_) { end_unread_idx_ = endAsyncRead(); } uint32_t __idxsize = end_unread_idx_ - begin_unread_idx_; uint32_t bytes_to_copy = (len < __idxsize) ? len : __idxsize; memcpy(buf, &buffer_[begin_unread_idx_], bytes_to_copy); begin_unread_idx_ += bytes_to_copy; if (begin_unread_idx_ != end_unread_idx_) { assert(len == bytes_to_copy); // we were able to fulfill the read with just the bytes in our // buffer, and we still have buffer left return bytes_to_copy; } uint32_t bytes_copied = bytes_to_copy; // all of the requested data has been read. Kick off an async read for the next round. beginAsyncRead(&buffer_[0], static_cast(buffer_.size())); return bytes_copied; } void pseudo_sync_write(HANDLE pipe, HANDLE event, const uint8_t* buf, uint32_t len) { OVERLAPPED tempOverlap; memset(&tempOverlap, 0, sizeof(tempOverlap)); tempOverlap.hEvent = event; uint32_t written = 0; while (written < len) { BOOL result = ::WriteFile(pipe, buf + written, len - written, nullptr, &tempOverlap); if (result == FALSE && ::GetLastError() != ERROR_IO_PENDING) { TOutput::instance().perror("TPipe ::WriteFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: write failed"); } DWORD bytes = 0; result = ::GetOverlappedResult(pipe, &tempOverlap, &bytes, TRUE); if (!result) { TOutput::instance().perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: GetOverlappedResult failed"); } written += bytes; } } uint32_t pseudo_sync_read(HANDLE pipe, HANDLE event, uint8_t* buf, uint32_t len) { OVERLAPPED tempOverlap; memset(&tempOverlap, 0, sizeof(tempOverlap)); tempOverlap.hEvent = event; BOOL result = ::ReadFile(pipe, buf, len, nullptr, &tempOverlap); if (result == FALSE && ::GetLastError() != ERROR_IO_PENDING) { TOutput::instance().perror("TPipe ::ReadFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: read failed"); } DWORD bytes = 0; result = ::GetOverlappedResult(pipe, &tempOverlap, &bytes, TRUE); if (!result) { TOutput::instance().perror("TPipe ::GetOverlappedResult errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::UNKNOWN, "TPipe: GetOverlappedResult failed"); } return bytes; } //---- Constructors ---- TPipe::TPipe(TAutoHandle &Pipe, std::shared_ptr config) : impl_(new TWaitableNamedPipeImpl(Pipe)), TimeoutSeconds_(3), isAnonymous_(false), TVirtualTransport(config) { } TPipe::TPipe(HANDLE Pipe, std::shared_ptr config) : TimeoutSeconds_(3), isAnonymous_(false), TVirtualTransport(config) { TAutoHandle pipeHandle(Pipe); impl_.reset(new TWaitableNamedPipeImpl(pipeHandle)); } TPipe::TPipe(const char* pipename, std::shared_ptr config) : TimeoutSeconds_(3), isAnonymous_(false), TVirtualTransport(config) { setPipename(pipename); } TPipe::TPipe(const std::string& pipename, std::shared_ptr config) : TimeoutSeconds_(3), isAnonymous_(false), TVirtualTransport(config) { setPipename(pipename); } TPipe::TPipe(HANDLE PipeRd, HANDLE PipeWrt, std::shared_ptr config) : impl_(new TAnonPipeImpl(PipeRd, PipeWrt)), TimeoutSeconds_(3), isAnonymous_(true), TVirtualTransport(config) { } TPipe::TPipe(std::shared_ptr config) : TimeoutSeconds_(3), isAnonymous_(false), TVirtualTransport(config) { } TPipe::~TPipe() { } //--------------------------------------------------------- // Transport callbacks //--------------------------------------------------------- bool TPipe::isOpen() const { return impl_.get() != nullptr; } bool TPipe::peek() { return isOpen(); } void TPipe::open() { if (isOpen()) return; TAutoHandle hPipe; do { DWORD flags = FILE_FLAG_OVERLAPPED; // async mode, so we can do reads at the same time as writes hPipe.reset(CreateFileA(pipename_.c_str(), GENERIC_READ | GENERIC_WRITE, 0, // no sharing nullptr, // default security attributes OPEN_EXISTING, // opens existing pipe flags, nullptr)); // no template file if (hPipe.h != INVALID_HANDLE_VALUE) break; // success! if (::GetLastError() != ERROR_PIPE_BUSY) { TOutput::instance().perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, "Unable to open pipe"); } } while (::WaitNamedPipeA(pipename_.c_str(), TimeoutSeconds_ * 1000)); if (hPipe.h == INVALID_HANDLE_VALUE) { TOutput::instance().perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, "Unable to open pipe"); } impl_.reset(new TNamedPipeImpl(hPipe)); } void TPipe::close() { impl_.reset(); } uint32_t TPipe::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); if (!isOpen()) throw TTransportException(TTransportException::NOT_OPEN, "Called read on non-open pipe"); return impl_->read(buf, len); } uint32_t pipe_read(HANDLE pipe, uint8_t* buf, uint32_t len) { DWORD cbRead; int fSuccess = ReadFile(pipe, // pipe handle buf, // buffer to receive reply len, // size of buffer &cbRead, // number of bytes read nullptr); // not overlapped if (!fSuccess && GetLastError() != ERROR_MORE_DATA) return 0; // No more data, possibly because client disconnected. return cbRead; } void TPipe::write(const uint8_t* buf, uint32_t len) { if (!isOpen()) throw TTransportException(TTransportException::NOT_OPEN, "Called write on non-open pipe"); impl_->write(buf, len); } void pipe_write(HANDLE pipe, const uint8_t* buf, uint32_t len) { DWORD cbWritten; int fSuccess = WriteFile(pipe, // pipe handle buf, // message len, // message length &cbWritten, // bytes written nullptr); // not overlapped if (!fSuccess) throw TTransportException(TTransportException::NOT_OPEN, "Write to pipe failed"); } //--------------------------------------------------------- // Accessors //--------------------------------------------------------- std::string TPipe::getPipename() { return pipename_; } void TPipe::setPipename(const std::string& pipename) { if (pipename.find("\\\\") == std::string::npos) pipename_ = "\\\\.\\pipe\\" + pipename; else pipename_ = pipename; } HANDLE TPipe::getPipeHandle() { if (impl_) return impl_->getPipeHandle(); return INVALID_HANDLE_VALUE; } void TPipe::setPipeHandle(HANDLE pipehandle) { if (isAnonymous_) impl_->setPipeHandle(pipehandle); else { TAutoHandle pipe(pipehandle); impl_.reset(new TNamedPipeImpl(pipe)); } } HANDLE TPipe::getWrtPipeHandle() { if (impl_) return impl_->getWrtPipeHandle(); return INVALID_HANDLE_VALUE; } void TPipe::setWrtPipeHandle(HANDLE pipehandle) { if (impl_) impl_->setWrtPipeHandle(pipehandle); } HANDLE TPipe::getNativeWaitHandle() { if (impl_) return impl_->getNativeWaitHandle(); return INVALID_HANDLE_VALUE; } long TPipe::getConnTimeout() { return TimeoutSeconds_; } void TPipe::setConnTimeout(long seconds) { TimeoutSeconds_ = seconds; } #endif //_WIN32 } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TTransport.h0000664000175000017500000002710115165535636023342 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TTRANSPORT_H_ #define _THRIFT_TRANSPORT_TTRANSPORT_H_ 1 #include #include #include #include #include namespace apache { namespace thrift { namespace transport { /** * Helper template to hoist readAll implementation out of TTransport */ template uint32_t readAll(Transport_& trans, uint8_t* buf, uint32_t len) { uint32_t have = 0; uint32_t get = 0; while (have < len) { get = trans.read(buf + have, len - have); if (get <= 0) { throw TTransportException(TTransportException::END_OF_FILE, "No more data to read."); } have += get; } return have; } /** * Generic interface for a method of transporting data. A TTransport may be * capable of either reading or writing, but not necessarily both. * */ class TTransport { public: TTransport(std::shared_ptr config = nullptr) { if(config == nullptr) { configuration_ = std::shared_ptr (new TConfiguration()); } else { configuration_ = config; } resetConsumedMessageSize(); } /** * Virtual deconstructor. */ virtual ~TTransport() = default; /** * Whether this transport is open. */ virtual bool isOpen() const { return false; } /** * Tests whether there is more data to read or if the remote side is * still open. By default this is true whenever the transport is open, * but implementations should add logic to test for this condition where * possible (i.e. on a socket). * This is used by a server to check if it should listen for another * request. */ virtual bool peek() { return isOpen(); } /** * Opens the transport for communications. * * @return bool Whether the transport was successfully opened * @throws TTransportException if opening failed */ virtual void open() { throw TTransportException(TTransportException::NOT_OPEN, "Cannot open base TTransport."); } /** * Closes the transport. */ virtual void close() { throw TTransportException(TTransportException::NOT_OPEN, "Cannot close base TTransport."); } /** * Attempt to read up to the specified number of bytes into the string. * * @param buf Reference to the location to write the data * @param len How many bytes to read * @return How many bytes were actually read * @throws TTransportException If an error occurs */ uint32_t read(uint8_t* buf, uint32_t len) { T_VIRTUAL_CALL(); return read_virt(buf, len); } virtual uint32_t read_virt(uint8_t* /* buf */, uint32_t /* len */) { throw TTransportException(TTransportException::NOT_OPEN, "Base TTransport cannot read."); } /** * Reads the given amount of data in its entirety no matter what. * * @param s Reference to location for read data * @param len How many bytes to read * @return How many bytes read, which must be equal to size * @throws TTransportException If insufficient data was read */ uint32_t readAll(uint8_t* buf, uint32_t len) { T_VIRTUAL_CALL(); return readAll_virt(buf, len); } virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len) { return apache::thrift::transport::readAll(*this, buf, len); } /** * Called when read is completed. * This can be over-ridden to perform a transport-specific action * e.g. logging the request to a file * * @return number of bytes read if available, 0 otherwise. */ virtual uint32_t readEnd() { // default behaviour is to do nothing return 0; } /** * Writes the string in its entirety to the buffer. * * Note: You must call flush() to ensure the data is actually written, * and available to be read back in the future. Destroying a TTransport * object does not automatically flush pending data--if you destroy a * TTransport object with written but unflushed data, that data may be * discarded. * * @param buf The data to write out * @throws TTransportException if an error occurs */ void write(const uint8_t* buf, uint32_t len) { T_VIRTUAL_CALL(); write_virt(buf, len); } virtual void write_virt(const uint8_t* /* buf */, uint32_t /* len */) { throw TTransportException(TTransportException::NOT_OPEN, "Base TTransport cannot write."); } /** * Called when write is completed. * This can be over-ridden to perform a transport-specific action * at the end of a request. * * @return number of bytes written if available, 0 otherwise */ virtual uint32_t writeEnd() { // default behaviour is to do nothing return 0; } /** * Flushes any pending data to be written. Typically used with buffered * transport mechanisms. * * @throws TTransportException if an error occurs */ virtual void flush() { // default behaviour is to do nothing } /** * Attempts to return a pointer to \c len bytes, possibly copied into \c buf. * Does not consume the bytes read (i.e.: a later read will return the same * data). This method is meant to support protocols that need to read * variable-length fields. They can attempt to borrow the maximum amount of * data that they will need, then consume (see next method) what they * actually use. Some transports will not support this method and others * will fail occasionally, so protocols must be prepared to use read if * borrow fails. * * @oaram buf A buffer where the data can be stored if needed. * If borrow doesn't return buf, then the contents of * buf after the call are undefined. This parameter may be * nullptr to indicate that the caller is not supplying storage, * but would like a pointer into an internal buffer, if * available. * @param len *len should initially contain the number of bytes to borrow. * If borrow succeeds, *len will contain the number of bytes * available in the returned pointer. This will be at least * what was requested, but may be more if borrow returns * a pointer to an internal buffer, rather than buf. * If borrow fails, the contents of *len are undefined. * @return If the borrow succeeds, return a pointer to the borrowed data. * This might be equal to \c buf, or it might be a pointer into * the transport's internal buffers. * @throws TTransportException if an error occurs */ const uint8_t* borrow(uint8_t* buf, uint32_t* len) { T_VIRTUAL_CALL(); return borrow_virt(buf, len); } virtual const uint8_t* borrow_virt(uint8_t* /* buf */, uint32_t* /* len */) { return nullptr; } /** * Remove len bytes from the transport. This should always follow a borrow * of at least len bytes, and should always succeed. * TODO(dreiss): Is there any transport that could borrow but fail to * consume, or that would require a buffer to dump the consumed data? * * @param len How many bytes to consume * @throws TTransportException If an error occurs */ void consume(uint32_t len) { T_VIRTUAL_CALL(); consume_virt(len); } virtual void consume_virt(uint32_t /* len */) { throw TTransportException(TTransportException::NOT_OPEN, "Base TTransport cannot consume."); } /** * Returns the origin of the transports call. The value depends on the * transport used. An IP based transport for example will return the * IP address of the client making the request. * If the transport doesn't know the origin Unknown is returned. * * The returned value can be used in a log message for example */ virtual const std::string getOrigin() const { return "Unknown"; } std::shared_ptr getConfiguration() { return configuration_; } void setConfiguration(std::shared_ptr config) { if (config != nullptr) configuration_ = config; } /** * Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport). * Will throw if we already consumed too many bytes or if the new size is larger than allowed. * * @param size real message size */ void updateKnownMessageSize(long int size) { long int consumed = knownMessageSize_ - remainingMessageSize_; resetConsumedMessageSize(size); countConsumedMessageBytes(consumed); } /** * Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data * * @param numBytes numBytes bytes of data */ void checkReadBytesAvailable(long int numBytes) { if (remainingMessageSize_ < numBytes || numBytes < 0) throw TTransportException(TTransportException::END_OF_FILE, "MaxMessageSize reached"); } protected: std::shared_ptr configuration_; long int remainingMessageSize_; long int knownMessageSize_; inline long int getRemainingMessageSize() { return remainingMessageSize_; } inline void setRemainingMessageSize(long int remainingMessageSize) { remainingMessageSize_ = remainingMessageSize; } inline int getMaxMessageSize() { return configuration_->getMaxMessageSize(); } inline long int getKnownMessageSize() { return knownMessageSize_; } void setKnownMessageSize(long int knownMessageSize) { knownMessageSize_ = knownMessageSize; } /** * Resets RemainingMessageSize to the configured maximum * * @param newSize configured size */ void resetConsumedMessageSize(long newSize = -1) { // full reset if (newSize < 0) { knownMessageSize_ = getMaxMessageSize(); remainingMessageSize_ = getMaxMessageSize(); return; } // update only: message size can shrink, but not grow if (newSize > knownMessageSize_) throw TTransportException(TTransportException::END_OF_FILE, "MaxMessageSize reached"); knownMessageSize_ = newSize; remainingMessageSize_ = newSize; } /** * Consumes numBytes from the RemainingMessageSize. * * @param numBytes Consumes numBytes */ void countConsumedMessageBytes(long int numBytes) { if (remainingMessageSize_ >= numBytes) { remainingMessageSize_ -= numBytes; } else { remainingMessageSize_ = 0; throw TTransportException(TTransportException::END_OF_FILE, "MaxMessageSize reached"); } } }; /** * Generic factory class to make an input and output transport out of a * source transport. Commonly used inside servers to make input and output * streams out of raw clients. * */ class TTransportFactory { public: TTransportFactory() = default; virtual ~TTransportFactory() = default; /** * Default implementation does nothing, just returns the transport given. */ virtual std::shared_ptr getTransport(std::shared_ptr trans) { return trans; } }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/THeaderTransport.cpp0000664000175000017500000004716215165535636025017 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include using std::map; using std::string; using std::vector; namespace apache { namespace thrift { using std::shared_ptr; namespace transport { using namespace apache::thrift::protocol; using apache::thrift::protocol::TBinaryProtocol; uint32_t THeaderTransport::readSlow(uint8_t* buf, uint32_t len) { if (clientType == THRIFT_UNFRAMED_BINARY || clientType == THRIFT_UNFRAMED_COMPACT) { return transport_->read(buf, len); } return TFramedTransport::readSlow(buf, len); } uint16_t THeaderTransport::getProtocolId() const { if (clientType == THRIFT_HEADER_CLIENT_TYPE) { return protoId; } else if (clientType == THRIFT_UNFRAMED_COMPACT || clientType == THRIFT_FRAMED_COMPACT) { return T_COMPACT_PROTOCOL; } else { return T_BINARY_PROTOCOL; // Assume other transports use TBinary } } void THeaderTransport::ensureReadBuffer(uint32_t sz) { if (sz > rBufSize_) { rBuf_.reset(new uint8_t[sz]); rBufSize_ = sz; } } bool THeaderTransport::readFrame() { // szN is network byte order of sz uint32_t szN; uint32_t sz; // Read the size of the next frame. // We can't use readAll(&sz, sizeof(sz)), since that always throws an // exception on EOF. We want to throw an exception only if EOF occurs after // partial size data. uint32_t sizeBytesRead = 0; while (sizeBytesRead < sizeof(szN)) { uint8_t* szp = reinterpret_cast(&szN) + sizeBytesRead; uint32_t bytesRead = transport_->read(szp, sizeof(szN) - sizeBytesRead); if (bytesRead == 0) { if (sizeBytesRead == 0) { // EOF before any data was read. return false; } else { // EOF after a partial frame header. Raise an exception. throw TTransportException(TTransportException::END_OF_FILE, "No more data to read after " "partial frame header."); } } sizeBytesRead += bytesRead; } sz = ntohl(szN); ensureReadBuffer(4); if ((sz & TBinaryProtocol::VERSION_MASK) == (uint32_t)TBinaryProtocol::VERSION_1) { // unframed clientType = THRIFT_UNFRAMED_BINARY; memcpy(rBuf_.get(), &szN, sizeof(szN)); setReadBuffer(rBuf_.get(), 4); } else if (static_cast(sz >> 24) == TCompactProtocol::PROTOCOL_ID && (static_cast(sz >> 16) & TCompactProtocol::VERSION_MASK) == TCompactProtocol::VERSION_N) { clientType = THRIFT_UNFRAMED_COMPACT; memcpy(rBuf_.get(), &szN, sizeof(szN)); setReadBuffer(rBuf_.get(), 4); } else { // Could be header format or framed. Check next uint32 uint32_t magic_n; uint32_t magic; if (sz > MAX_FRAME_SIZE) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Header transport frame is too large"); } ensureReadBuffer(sz); // We can use readAll here, because it would be an invalid frame otherwise transport_->readAll(reinterpret_cast(&magic_n), sizeof(magic_n)); memcpy(rBuf_.get(), &magic_n, sizeof(magic_n)); magic = ntohl(magic_n); if ((magic & TBinaryProtocol::VERSION_MASK) == (uint32_t)TBinaryProtocol::VERSION_1) { // framed clientType = THRIFT_FRAMED_BINARY; transport_->readAll(rBuf_.get() + 4, sz - 4); setReadBuffer(rBuf_.get(), sz); } else if (static_cast(magic >> 24) == TCompactProtocol::PROTOCOL_ID && (static_cast(magic >> 16) & TCompactProtocol::VERSION_MASK) == TCompactProtocol::VERSION_N) { clientType = THRIFT_FRAMED_COMPACT; transport_->readAll(rBuf_.get() + 4, sz - 4); setReadBuffer(rBuf_.get(), sz); } else if (HEADER_MAGIC == (magic & HEADER_MASK)) { if (sz < 10) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Header transport frame is too small"); } transport_->readAll(rBuf_.get() + 4, sz - 4); // header format clientType = THRIFT_HEADER_CLIENT_TYPE; // flags flags = magic & FLAGS_MASK; // seqId uint32_t seqId_n; memcpy(&seqId_n, rBuf_.get() + 4, sizeof(seqId_n)); seqId = ntohl(seqId_n); // header size uint16_t headerSize_n; memcpy(&headerSize_n, rBuf_.get() + 8, sizeof(headerSize_n)); uint16_t headerSize = ntohs(headerSize_n); setReadBuffer(rBuf_.get(), sz); readHeaderFormat(headerSize, sz); } else { clientType = THRIFT_UNKNOWN_CLIENT_TYPE; throw TTransportException(TTransportException::BAD_ARGS, "Could not detect client transport type"); } } return true; } /** * Reads a string from ptr, taking care not to reach headerBoundary * Advances ptr on success * * @param str output string * @throws CORRUPTED_DATA if size of string exceeds boundary */ void THeaderTransport::readString(uint8_t*& ptr, /* out */ string& str, uint8_t const* headerBoundary) { int32_t strLen; uint32_t bytes = readVarint32(ptr, &strLen, headerBoundary); if (strLen > headerBoundary - ptr) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Info header length exceeds header size"); } ptr += bytes; str.assign(reinterpret_cast(ptr), strLen); ptr += strLen; } void THeaderTransport::readHeaderFormat(uint16_t headerSize, uint32_t sz) { readTrans_.clear(); // Clear out any previous transforms. readHeaders_.clear(); // Clear out any previous headers. // skip over already processed magic(4), seqId(4), headerSize(2) auto* ptr = reinterpret_cast(rBuf_.get() + 10); // Catch integer overflow, check for reasonable header size if (headerSize >= 16384) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Header size is unreasonable"); } headerSize *= 4; const uint8_t* const headerBoundary = ptr + headerSize; if (headerSize > sz) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Header size is larger than frame"); } uint8_t* data = ptr + headerSize; ptr += readVarint16(ptr, &protoId, headerBoundary); int16_t numTransforms; ptr += readVarint16(ptr, &numTransforms, headerBoundary); // For now all transforms consist of only the ID, not data. for (int i = 0; i < numTransforms; i++) { int32_t transId; ptr += readVarint32(ptr, &transId, headerBoundary); readTrans_.push_back(transId); } // Info headers while (ptr < headerBoundary) { int32_t infoId; ptr += readVarint32(ptr, &infoId, headerBoundary); if (infoId == 0) { // header padding break; } if (infoId >= infoIdType::END) { // cannot handle infoId break; } switch (infoId) { case infoIdType::KEYVALUE: // Process key-value headers uint32_t numKVHeaders; ptr += readVarint32(ptr, (int32_t*)&numKVHeaders, headerBoundary); // continue until we reach (padded) end of packet while (numKVHeaders-- && ptr < headerBoundary) { // format: key; value // both: length (varint32); value (string) string key, value; readString(ptr, key, headerBoundary); // value readString(ptr, value, headerBoundary); // save to headers readHeaders_[key] = value; } break; } } // Untransform the data section. rBuf will contain result. untransform(data, safe_numeric_cast(static_cast(sz) - (data - rBuf_.get()))); } void THeaderTransport::untransform(uint8_t* ptr, uint32_t sz) { // Update the transform buffer size if needed resizeTransformBuffer(); for (vector::const_iterator it = readTrans_.begin(); it != readTrans_.end(); ++it) { const uint16_t transId = *it; if (transId == ZLIB_TRANSFORM) { z_stream stream; int err; stream.next_in = ptr; stream.avail_in = sz; // Setting these to 0 means use the default free/alloc functions stream.zalloc = (alloc_func)nullptr; stream.zfree = (free_func)nullptr; stream.opaque = (voidpf)nullptr; err = inflateInit(&stream); if (err != Z_OK) { throw TApplicationException(TApplicationException::MISSING_RESULT, "Error while zlib deflateInit"); } stream.next_out = tBuf_.get(); stream.avail_out = tBufSize_; err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END || stream.avail_out == 0) { throw TApplicationException(TApplicationException::MISSING_RESULT, "Error while zlib deflate"); } sz = stream.total_out; err = inflateEnd(&stream); if (err != Z_OK) { throw TApplicationException(TApplicationException::MISSING_RESULT, "Error while zlib deflateEnd"); } memcpy(ptr, tBuf_.get(), sz); } else { throw TApplicationException(TApplicationException::MISSING_RESULT, "Unknown transform"); } } setReadBuffer(ptr, sz); } /** * We may have updated the wBuf size, update the tBuf size to match. * Should be called in transform. * * The buffer should be slightly larger than write buffer size due to * compression transforms (that may slightly grow on small frame sizes) */ void THeaderTransport::resizeTransformBuffer(uint32_t additionalSize) { if (tBufSize_ < wBufSize_ + DEFAULT_BUFFER_SIZE) { uint32_t new_size = wBufSize_ + DEFAULT_BUFFER_SIZE + additionalSize; auto* new_buf = new uint8_t[new_size]; tBuf_.reset(new_buf); tBufSize_ = new_size; } } void THeaderTransport::transform(uint8_t* ptr, uint32_t sz) { // Update the transform buffer size if needed resizeTransformBuffer(); for (vector::const_iterator it = writeTrans_.begin(); it != writeTrans_.end(); ++it) { const uint16_t transId = *it; if (transId == ZLIB_TRANSFORM) { z_stream stream; int err; stream.next_in = ptr; stream.avail_in = sz; stream.zalloc = (alloc_func)nullptr; stream.zfree = (free_func)nullptr; stream.opaque = (voidpf)nullptr; err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); if (err != Z_OK) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Error while zlib deflateInit"); } uint32_t tbuf_size = 0; while (err == Z_OK) { resizeTransformBuffer(tbuf_size); stream.next_out = tBuf_.get(); stream.avail_out = tBufSize_; err = deflate(&stream, Z_FINISH); tbuf_size += DEFAULT_BUFFER_SIZE; } sz = stream.total_out; err = deflateEnd(&stream); if (err != Z_OK) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Error while zlib deflateEnd"); } memcpy(ptr, tBuf_.get(), sz); } else { throw TTransportException(TTransportException::CORRUPTED_DATA, "Unknown transform"); } } wBase_ = wBuf_.get() + sz; } void THeaderTransport::resetProtocol() { // Set to anything except HTTP type so we don't flush again clientType = THRIFT_HEADER_CLIENT_TYPE; // Read the header and decide which protocol to go with readFrame(); } uint32_t THeaderTransport::getWriteBytes() { return safe_numeric_cast(wBase_ - wBuf_.get()); } /** * Writes a string to a byte buffer, as size (varint32) + string (non-null * terminated) * Automatically advances ptr to after the written portion */ void THeaderTransport::writeString(uint8_t*& ptr, const string& str) { auto strLen = safe_numeric_cast(str.length()); ptr += writeVarint32(strLen, ptr); memcpy(ptr, str.c_str(), strLen); // no need to write \0 ptr += strLen; } void THeaderTransport::setHeader(const string& key, const string& value) { writeHeaders_[key] = value; } uint32_t THeaderTransport::getMaxWriteHeadersSize() const { size_t maxWriteHeadersSize = 0; THeaderTransport::StringToStringMap::const_iterator it; for (it = writeHeaders_.begin(); it != writeHeaders_.end(); ++it) { // add sizes of key and value to maxWriteHeadersSize // 2 varints32 + the strings themselves maxWriteHeadersSize += 5 + 5 + (it->first).length() + (it->second).length(); } return safe_numeric_cast(maxWriteHeadersSize); } void THeaderTransport::clearHeaders() { writeHeaders_.clear(); } void THeaderTransport::flush() { resetConsumedMessageSize(); // Write out any data waiting in the write buffer. uint32_t haveBytes = getWriteBytes(); if (clientType == THRIFT_HEADER_CLIENT_TYPE) { transform(wBuf_.get(), haveBytes); haveBytes = getWriteBytes(); // transform may have changed the size } // Note that we reset wBase_ prior to the underlying write // to ensure we're in a sane state (i.e. internal buffer cleaned) // if the underlying write throws up an exception wBase_ = wBuf_.get(); if (haveBytes > MAX_FRAME_SIZE) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Attempting to send frame that is too large"); } if (clientType == THRIFT_HEADER_CLIENT_TYPE) { // header size will need to be updated at the end because of varints. // Make it big enough here for max varint size, plus 4 for padding. uint32_t headerSize = (2 + getNumTransforms()) * THRIFT_MAX_VARINT32_BYTES + 4; // add approximate size of info headers headerSize += getMaxWriteHeadersSize(); // Pkt size uint32_t maxSzHbo = headerSize + haveBytes // thrift header + payload + 10; // common header section uint8_t* pkt = tBuf_.get(); uint8_t* headerStart; uint8_t* headerSizePtr; uint8_t* pktStart = pkt; if (maxSzHbo > tBufSize_) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Attempting to header frame that is too large"); } uint32_t szHbo; uint32_t szNbo; uint16_t headerSizeN; // Fixup szHbo later pkt += sizeof(szNbo); uint16_t headerN = htons(HEADER_MAGIC >> 16); memcpy(pkt, &headerN, sizeof(headerN)); pkt += sizeof(headerN); uint16_t flagsN = htons(flags); memcpy(pkt, &flagsN, sizeof(flagsN)); pkt += sizeof(flagsN); uint32_t seqIdN = htonl(seqId); memcpy(pkt, &seqIdN, sizeof(seqIdN)); pkt += sizeof(seqIdN); headerSizePtr = pkt; // Fixup headerSizeN later pkt += sizeof(headerSizeN); headerStart = pkt; pkt += writeVarint32(protoId, pkt); pkt += writeVarint32(getNumTransforms(), pkt); // For now, each transform is only the ID, no following data. for (vector::const_iterator it = writeTrans_.begin(); it != writeTrans_.end(); ++it) { pkt += writeVarint32(*it, pkt); } // write info headers // for now only write kv-headers auto headerCount = safe_numeric_cast(writeHeaders_.size()); if (headerCount > 0) { pkt += writeVarint32(infoIdType::KEYVALUE, pkt); // Write key-value headers count pkt += writeVarint32(static_cast(headerCount), pkt); // Write info headers map::const_iterator it; for (it = writeHeaders_.begin(); it != writeHeaders_.end(); ++it) { writeString(pkt, it->first); // key writeString(pkt, it->second); // value } writeHeaders_.clear(); } // Fixups after varint size calculations headerSize = safe_numeric_cast(pkt - headerStart); uint8_t padding = 4 - (headerSize % 4); headerSize += padding; // Pad out pkt with 0x00 for (int i = 0; i < padding; i++) { *(pkt++) = 0x00; } // Pkt size ptrdiff_t szHbp = (headerStart - pktStart - 4); if (static_cast(szHbp) > static_cast((std::numeric_limits().max)()) - (headerSize + haveBytes)) { throw TTransportException(TTransportException::CORRUPTED_DATA, "Header section size is unreasonable"); } szHbo = headerSize + haveBytes // thrift header + payload + static_cast(szHbp); // common header section headerSizeN = htons(headerSize / 4); memcpy(headerSizePtr, &headerSizeN, sizeof(headerSizeN)); // Set framing size. szNbo = htonl(szHbo); memcpy(pktStart, &szNbo, sizeof(szNbo)); outTransport_->write(pktStart, szHbo - haveBytes + 4); outTransport_->write(wBuf_.get(), haveBytes); } else if (clientType == THRIFT_FRAMED_BINARY || clientType == THRIFT_FRAMED_COMPACT) { auto szHbo = (uint32_t)haveBytes; uint32_t szNbo = htonl(szHbo); outTransport_->write(reinterpret_cast(&szNbo), 4); outTransport_->write(wBuf_.get(), haveBytes); } else if (clientType == THRIFT_UNFRAMED_BINARY || clientType == THRIFT_UNFRAMED_COMPACT) { outTransport_->write(wBuf_.get(), haveBytes); } else { throw TTransportException(TTransportException::BAD_ARGS, "Unknown client type"); } // Flush the underlying transport. outTransport_->flush(); } /** * Read an i16 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 3 bytes. */ uint32_t THeaderTransport::readVarint16(uint8_t const* ptr, int16_t* i16, uint8_t const* boundary) { int32_t val; uint32_t rsize = readVarint32(ptr, &val, boundary); *i16 = (int16_t)val; return rsize; } /** * 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. */ uint32_t THeaderTransport::readVarint32(uint8_t const* ptr, int32_t* i32, uint8_t const* boundary) { uint32_t rsize = 0; uint32_t val = 0; int shift = 0; while (true) { if (ptr == boundary) { throw TApplicationException(TApplicationException::INVALID_MESSAGE_TYPE, "Trying to read past header boundary"); } uint8_t byte = *(ptr++); rsize++; val |= (uint64_t)(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { *i32 = val; return rsize; } } } /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. */ uint32_t THeaderTransport::writeVarint32(int32_t n, uint8_t* pkt) { uint8_t buf[5]; uint32_t wsize = 0; while (true) { if ((n & ~0x7F) == 0) { buf[wsize++] = (int8_t)n; break; } else { buf[wsize++] = (int8_t)((n & 0x7F) | 0x80); n >>= 7; } } // Caller will advance pkt. for (uint32_t i = 0; i < wsize; i++) { pkt[i] = buf[i]; } return wsize; } uint32_t THeaderTransport::writeVarint16(int16_t n, uint8_t* pkt) { return writeVarint32(n, pkt); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TSocketPool.h0000664000175000017500000001074615165535636023437 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSOCKETPOOL_H_ #define _THRIFT_TRANSPORT_TSOCKETPOOL_H_ 1 #include #include namespace apache { namespace thrift { namespace transport { /** * Class to hold server information for TSocketPool * */ class TSocketPoolServer { public: /** * Default constructor for server info */ TSocketPoolServer(); /** * Constructor for TSocketPool server */ TSocketPoolServer(const std::string& host, int port); // Host name std::string host_; // Port to connect on int port_; // Socket for the server THRIFT_SOCKET socket_; // Last time connecting to this server failed time_t lastFailTime_; // Number of consecutive times connecting to this server failed int consecutiveFailures_; }; /** * TCP Socket implementation of the TTransport interface. * */ class TSocketPool : public TSocket { public: /** * Socket pool constructor */ TSocketPool(); /** * Socket pool constructor * * @param hosts list of host names * @param ports list of port names */ TSocketPool(const std::vector& hosts, const std::vector& ports); /** * Socket pool constructor * * @param servers list of pairs of host name and port */ TSocketPool(const std::vector >& servers); /** * Socket pool constructor * * @param servers list of TSocketPoolServers */ TSocketPool(const std::vector >& servers); /** * Socket pool constructor * * @param host single host * @param port single port */ TSocketPool(const std::string& host, int port); /** * Destroyes the socket object, closing it if necessary. */ ~TSocketPool() override; /** * Add a server to the pool */ void addServer(const std::string& host, int port); /** * Add a server to the pool */ void addServer(std::shared_ptr& server); /** * Set list of servers in this pool */ void setServers(const std::vector >& servers); /** * Get list of servers in this pool */ void getServers(std::vector >& servers); /** * Sets how many times to keep retrying a host in the connect function. */ void setNumRetries(int numRetries); /** * Sets how long to wait until retrying a host if it was marked down */ void setRetryInterval(int retryInterval); /** * Sets how many times to keep retrying a host before marking it as down. */ void setMaxConsecutiveFailures(int maxConsecutiveFailures); /** * Turns randomization in connect order on or off. */ void setRandomize(bool randomize); /** * Whether to always try the last server. */ void setAlwaysTryLast(bool alwaysTryLast); /** * Creates and opens the UNIX socket. */ void open() override; /* * Closes the UNIX socket */ void close() override; protected: void setCurrentServer(const std::shared_ptr& server); /** List of servers to connect to */ std::vector > servers_; /** Current server */ std::shared_ptr currentServer_; /** How many times to retry each host in connect */ int numRetries_; /** Retry interval in seconds, how long to not try a host if it has been * marked as down. */ time_t retryInterval_; /** Max consecutive failures before marking a host down. */ int maxConsecutiveFailures_; /** Try hosts in order? or Randomized? */ bool randomize_; /** Always try last host, even if marked down? */ bool alwaysTryLast_; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TSOCKETPOOL_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/SocketCommon.cpp0000664000175000017500000000454515167543515024162 0ustar00buildbuild00000000000000/* * 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. * * @author: David Suárez */ #include #include #include #include #include namespace apache { namespace thrift { namespace transport { socklen_t fillUnixSocketAddr(struct sockaddr_un& address, std::string& path) { // abstract namespace socket ? bool isAbstractNamespace = path[0] == 0; #ifndef __linux__ if (isAbstractNamespace) { TOutput::instance().perror("TSocket::open() Abstract Namespace Domain sockets only supported on linux: ", -99); throw TTransportException(TTransportException::NOT_OPEN, " Abstract Namespace Domain socket path not supported"); } #endif /* * For abstract namespace sockets, the path string is not null-terminated (as opposite to path based), so we * rely in pass the string size, to the bind() call. */ size_t addr_len = isAbstractNamespace ? path.size() : path.size() + 1; if (addr_len > sizeof(((sockaddr_un*)nullptr)->sun_path)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() Unix Domain socket path too long", errno_copy); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path too long"); } address.sun_family = AF_UNIX; memcpy(address.sun_path, path.c_str(), addr_len); return static_cast(sizeof((sockaddr_un*)nullptr)->sun_family + addr_len); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.h0000664000175000017500000000447715165535636026546 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TNONBLOCKINGSSLSERVERSOCKET_H_ #define _THRIFT_TRANSPORT_TNONBLOCKINGSSLSERVERSOCKET_H_ 1 #include namespace apache { namespace thrift { namespace transport { class TSSLSocketFactory; /** * Nonblocking Server socket that accepts SSL connections. */ class TNonblockingSSLServerSocket : public TNonblockingServerSocket { public: /** * Constructor. Binds to all interfaces. * * @param port Listening port * @param factory SSL socket factory implementation */ TNonblockingSSLServerSocket(int port, std::shared_ptr factory); /** * Constructor. Binds to the specified address. * * @param address Address to bind to * @param port Listening port * @param factory SSL socket factory implementation */ TNonblockingSSLServerSocket(const std::string& address, int port, std::shared_ptr factory); /** * Constructor. Binds to all interfaces. * * @param port Listening port * @param sendTimeout Socket send timeout * @param recvTimeout Socket receive timeout * @param factory SSL socket factory implementation */ TNonblockingSSLServerSocket(int port, int sendTimeout, int recvTimeout, std::shared_ptr factory); protected: std::shared_ptr createSocket(THRIFT_SOCKET socket) override; std::shared_ptr factory_; }; } } } #endif thrift-0.23.0/lib/cpp/src/thrift/transport/TSocket.cpp0000664000175000017500000006663115167543515023141 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_SYS_IOCTL_H #include #ifdef __sun #include #endif // __sun #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_UN_H #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_SYS_POLL_H #include #endif #include #ifdef HAVE_NETINET_IN_H #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #ifndef SOCKOPT_CAST_T #ifndef _WIN32 #define SOCKOPT_CAST_T void #else #define SOCKOPT_CAST_T char #endif // _WIN32 #endif #if _WIN32 #include #endif template inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v) { return reinterpret_cast(v); } template inline SOCKOPT_CAST_T* cast_sockopt(T* v) { return reinterpret_cast(v); } using std::string; namespace apache { namespace thrift { namespace transport { /** * TSocket implementation. * */ TSocket::TSocket(const string& host, int port, std::shared_ptr config) : TVirtualTransport(config), host_(host), port_(port), socket_(THRIFT_INVALID_SOCKET), peerPort_(0), connTimeout_(0), sendTimeout_(0), recvTimeout_(0), keepAlive_(false), lingerOn_(1), lingerVal_(0), noDelay_(1), maxRecvRetries_(5) { } TSocket::TSocket(const string& path, std::shared_ptr config) : TVirtualTransport(config), port_(0), path_(path), socket_(THRIFT_INVALID_SOCKET), peerPort_(0), connTimeout_(0), sendTimeout_(0), recvTimeout_(0), keepAlive_(false), lingerOn_(1), lingerVal_(0), noDelay_(1), maxRecvRetries_(5) { cachedPeerAddr_.ipv4.sin_family = AF_UNSPEC; } TSocket::TSocket(std::shared_ptr config) : TVirtualTransport(config), port_(0), socket_(THRIFT_INVALID_SOCKET), peerPort_(0), connTimeout_(0), sendTimeout_(0), recvTimeout_(0), keepAlive_(false), lingerOn_(1), lingerVal_(0), noDelay_(1), maxRecvRetries_(5) { cachedPeerAddr_.ipv4.sin_family = AF_UNSPEC; } TSocket::TSocket(THRIFT_SOCKET socket, std::shared_ptr config) : TVirtualTransport(config), port_(0), socket_(socket), peerPort_(0), connTimeout_(0), sendTimeout_(0), recvTimeout_(0), keepAlive_(false), lingerOn_(1), lingerVal_(0), noDelay_(1), maxRecvRetries_(5) { cachedPeerAddr_.ipv4.sin_family = AF_UNSPEC; #ifdef SO_NOSIGPIPE { int one = 1; setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one)); } #endif } TSocket::TSocket(THRIFT_SOCKET socket, std::shared_ptr interruptListener, std::shared_ptr config) : TVirtualTransport(config), port_(0), socket_(socket), peerPort_(0), interruptListener_(interruptListener), connTimeout_(0), sendTimeout_(0), recvTimeout_(0), keepAlive_(false), lingerOn_(1), lingerVal_(0), noDelay_(1), maxRecvRetries_(5) { cachedPeerAddr_.ipv4.sin_family = AF_UNSPEC; #ifdef SO_NOSIGPIPE { int one = 1; setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one)); } #endif } TSocket::~TSocket() { close(); } bool TSocket::hasPendingDataToRead() { if (!isOpen()) { return false; } int32_t retries = 0; THRIFT_IOCTL_SOCKET_NUM_BYTES_TYPE numBytesAvailable; try_again: int r = THRIFT_IOCTL_SOCKET(socket_, FIONREAD, &numBytesAvailable); if (r == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; if (errno_copy == THRIFT_EINTR && (retries++ < maxRecvRetries_)) { goto try_again; } TOutput::instance().perror("TSocket::hasPendingDataToRead() THRIFT_IOCTL_SOCKET() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } return numBytesAvailable > 0; } bool TSocket::isOpen() const { return (socket_ != THRIFT_INVALID_SOCKET); } bool TSocket::peek() { if (!isOpen()) { return false; } if (interruptListener_) { for (int retries = 0;;) { struct THRIFT_POLLFD fds[2]; std::memset(fds, 0, sizeof(fds)); fds[0].fd = socket_; fds[0].events = THRIFT_POLLIN; fds[1].fd = *(interruptListener_.get()); fds[1].events = THRIFT_POLLIN; int ret = THRIFT_POLL(fds, 2, (recvTimeout_ == 0) ? -1 : recvTimeout_); int errno_copy = THRIFT_GET_SOCKET_ERROR; if (ret < 0) { // error cases if (errno_copy == THRIFT_EINTR && (retries++ < maxRecvRetries_)) { continue; } TOutput::instance().perror("TSocket::peek() THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0) { // Check the interruptListener if (fds[1].revents & THRIFT_POLLIN) { return false; } // There must be data or a disconnection, fall through to the PEEK break; } else { // timeout return false; } } } // Check to see if data is available or if the remote side closed uint8_t buf; int r = static_cast(recv(socket_, cast_sockopt(&buf), 1, MSG_PEEK)); if (r == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; #if defined __FreeBSD__ || defined __MACH__ /* shigin: * freebsd returns -1 and THRIFT_ECONNRESET if socket was closed by * the other side */ if (errno_copy == THRIFT_ECONNRESET) { return false; } #endif TOutput::instance().perror("TSocket::peek() recv() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::UNKNOWN, "recv()", errno_copy); } return (r > 0); } void TSocket::openConnection(struct addrinfo* res) { if (isOpen()) { return; } if (isUnixDomainSocket()) { socket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP); } else { socket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol); } if (socket_ == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() socket() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "socket()", errno_copy); } // Send timeout if (sendTimeout_ > 0) { setSendTimeout(sendTimeout_); } // Recv timeout if (recvTimeout_ > 0) { setRecvTimeout(recvTimeout_); } if (keepAlive_) { setKeepAlive(keepAlive_); } // Linger setLinger(lingerOn_, lingerVal_); // No delay setNoDelay(noDelay_); #ifdef SO_NOSIGPIPE { int one = 1; setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one)); } #endif // Uses a low min RTO if asked to. #ifdef TCP_LOW_MIN_RTO if (getUseLowMinRto()) { int one = 1; setsockopt(socket_, IPPROTO_TCP, TCP_LOW_MIN_RTO, &one, sizeof(one)); } #endif // Set the socket to be non blocking for connect if a timeout exists int flags = THRIFT_FCNTL(socket_, THRIFT_F_GETFL, 0); if (connTimeout_ > 0) { if (-1 == THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() THRIFT_FCNTL() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy); } } else { if (-1 == THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags & ~THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() THRIFT_FCNTL " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy); } } // Connect the socket int ret; if (isUnixDomainSocket()) { // Windows supports Unix domain sockets since it ships the header // HAVE_AF_UNIX_H (see https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/) #if (!defined(_WIN32) || defined(HAVE_AF_UNIX_H)) struct sockaddr_un address; socklen_t structlen = fillUnixSocketAddr(address, path_); ret = connect(socket_, (struct sockaddr*)&address, structlen); #else TOutput::instance().perror("TSocket::open() Unix Domain socket path not supported on this version of Windows", -99); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported"); #endif } else { ret = connect(socket_, res->ai_addr, static_cast(res->ai_addrlen)); } // success case if (ret == 0) { goto done; } if ((THRIFT_GET_SOCKET_ERROR != THRIFT_EINPROGRESS) && (THRIFT_GET_SOCKET_ERROR != THRIFT_EWOULDBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() connect() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "connect() failed", errno_copy); } struct THRIFT_POLLFD fds[1]; std::memset(fds, 0, sizeof(fds)); fds[0].fd = socket_; fds[0].events = THRIFT_POLLOUT; ret = THRIFT_POLL(fds, 1, connTimeout_); if (ret > 0) { // Ensure the socket is connected and that there are no errors set int val; socklen_t lon; lon = sizeof(int); int ret2 = getsockopt(socket_, SOL_SOCKET, SO_ERROR, cast_sockopt(&val), &lon); if (ret2 == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() getsockopt() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "getsockopt()", errno_copy); } // no errors on socket, go to town if (val == 0) { goto done; } TOutput::instance().perror("TSocket::open() error on socket (after THRIFT_POLL) " + getSocketInfo(), val); throw TTransportException(TTransportException::NOT_OPEN, "socket open() error", val); } else if (ret == 0) { // socket timed out string errStr = "TSocket::open() timed out " + getSocketInfo(); TOutput::instance()(errStr.c_str()); throw TTransportException(TTransportException::NOT_OPEN, "open() timed out"); } else { // error on THRIFT_POLL() int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() THRIFT_POLL() " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_POLL() failed", errno_copy); } done: // Set socket back to normal mode (blocking) if (-1 == THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::open() THRIFT_FCNTL " + getSocketInfo(), errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() failed", errno_copy); } if (!isUnixDomainSocket()) { setCachedAddress(res->ai_addr, static_cast(res->ai_addrlen)); } } void TSocket::open() { if (isOpen()) { return; } if (isUnixDomainSocket()) { unix_open(); } else { local_open(); } } void TSocket::unix_open() { if (isUnixDomainSocket()) { // Unix Domain Socket does not need addrinfo struct, so we pass NULL openConnection(nullptr); } } void TSocket::local_open() { #ifdef _WIN32 TWinsockSingleton::create(); #endif // _WIN32 if (isOpen()) { return; } // Validate port number if (port_ < 0 || port_ > 0xFFFF) { throw TTransportException(TTransportException::BAD_ARGS, "Specified port is invalid"); } struct addrinfo hints, *res, *res0; res = nullptr; res0 = nullptr; int error; char port[sizeof("65535")]; std::memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; sprintf(port, "%d", port_); error = getaddrinfo(host_.c_str(), port, &hints, &res0); if ( #ifdef _WIN32 error == WSANO_DATA #else // to support systems with no ipv4 addresses but using "127.0.0.1" as a hostname // getaddrinfo() fails when AI_ADDRCONFIG is present in this situation... error == EAI_NODATA || error == EAI_ADDRFAMILY #endif ) { hints.ai_flags &= ~AI_ADDRCONFIG; error = getaddrinfo(host_.c_str(), port, &hints, &res0); } if (error) { string errStr = "TSocket::open() getaddrinfo() " + getSocketInfo() + string(THRIFT_GAI_STRERROR(error)); TOutput::instance()(errStr.c_str()); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for client socket."); } // Cycle through all the returned addresses until one // connects or push the exception up. for (res = res0; res; res = res->ai_next) { try { openConnection(res); break; } catch (TTransportException&) { if (res->ai_next) { close(); } else { close(); freeaddrinfo(res0); // cleanup on failure throw; } } } // Free address structure memory freeaddrinfo(res0); } void TSocket::close() { if (socket_ != THRIFT_INVALID_SOCKET) { shutdown(socket_, THRIFT_SHUT_RDWR); ::THRIFT_CLOSESOCKET(socket_); } socket_ = THRIFT_INVALID_SOCKET; } void TSocket::setSocketFD(THRIFT_SOCKET socket) { if (socket_ != THRIFT_INVALID_SOCKET) { close(); } socket_ = socket; } uint32_t TSocket::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); if (socket_ == THRIFT_INVALID_SOCKET) { throw TTransportException(TTransportException::NOT_OPEN, "Called read on non-open socket"); } int32_t retries = 0; // THRIFT_EAGAIN can be signalled both when a timeout has occurred and when // the system is out of resources (an awesome undocumented feature). // The following is an approximation of the time interval under which // THRIFT_EAGAIN is taken to indicate an out of resources error. uint32_t eagainThresholdMicros = 0; if (recvTimeout_) { // if a readTimeout is specified along with a max number of recv retries, then // the threshold will ensure that the read timeout is not exceeded even in the // case of resource errors eagainThresholdMicros = (recvTimeout_ * 1000) / ((maxRecvRetries_ > 0) ? maxRecvRetries_ : 2); } try_again: // Read from the socket struct timeval begin; if (recvTimeout_ > 0) { THRIFT_GETTIMEOFDAY(&begin, nullptr); } else { // if there is no read timeout we don't need the TOD to determine whether // an THRIFT_EAGAIN is due to a timeout or an out-of-resource condition. begin.tv_sec = begin.tv_usec = 0; } int got = 0; if (interruptListener_) { struct THRIFT_POLLFD fds[2]; std::memset(fds, 0, sizeof(fds)); fds[0].fd = socket_; fds[0].events = THRIFT_POLLIN; fds[1].fd = *(interruptListener_.get()); fds[1].events = THRIFT_POLLIN; int ret = THRIFT_POLL(fds, 2, (recvTimeout_ == 0) ? -1 : recvTimeout_); int errno_copy = THRIFT_GET_SOCKET_ERROR; if (ret < 0) { // error cases if (errno_copy == THRIFT_EINTR && (retries++ < maxRecvRetries_)) { goto try_again; } TOutput::instance().perror("TSocket::read() THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0) { // Check the interruptListener if (fds[1].revents & THRIFT_POLLIN) { throw TTransportException(TTransportException::INTERRUPTED, "Interrupted"); } } else /* ret == 0 */ { TOutput::instance().printf("TSocket::read() THRIFT_EAGAIN (timed out) after %d ms", recvTimeout_); throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_EAGAIN (timed out)"); } // falling through means there is something to recv and it cannot block } got = static_cast(recv(socket_, cast_sockopt(buf), len, 0)); // THRIFT_GETTIMEOFDAY can change THRIFT_GET_SOCKET_ERROR int errno_copy = THRIFT_GET_SOCKET_ERROR; // Check for error on read if (got < 0) { if (errno_copy == THRIFT_EAGAIN) { // if no timeout we can assume that resource exhaustion has occurred. if (recvTimeout_ == 0) { throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_EAGAIN (unavailable resources)"); } // check if this is the lack of resources or timeout case struct timeval end; THRIFT_GETTIMEOFDAY(&end, nullptr); auto readElapsedMicros = static_cast(((end.tv_sec - begin.tv_sec) * 1000 * 1000) + (end.tv_usec - begin.tv_usec)); if (!eagainThresholdMicros || (readElapsedMicros < eagainThresholdMicros)) { if (retries++ < maxRecvRetries_) { THRIFT_SLEEP_USEC(50); goto try_again; } else { throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_EAGAIN (unavailable resources)"); } } else { // infer that timeout has been hit throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_EAGAIN (timed out)"); } } // If interrupted, try again if (errno_copy == THRIFT_EINTR && retries++ < maxRecvRetries_) { goto try_again; } if (errno_copy == THRIFT_ECONNRESET) { return 0; } // This ish isn't open if (errno_copy == THRIFT_ENOTCONN) { throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_ENOTCONN"); } // Timed out! if (errno_copy == THRIFT_ETIMEDOUT) { throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_ETIMEDOUT"); } // Now it's not a try again case, but a real probblez TOutput::instance().perror("TSocket::read() recv() " + getSocketInfo(), errno_copy); // Some other error, whatevz throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } return got; } void TSocket::write(const uint8_t* buf, uint32_t len) { uint32_t sent = 0; while (sent < len) { uint32_t b = write_partial(buf + sent, len - sent); if (b == 0) { // This should only happen if the timeout set with SO_SNDTIMEO expired. // Raise an exception. throw TTransportException(TTransportException::TIMED_OUT, "send timeout expired"); } sent += b; } } uint32_t TSocket::write_partial(const uint8_t* buf, uint32_t len) { if (socket_ == THRIFT_INVALID_SOCKET) { throw TTransportException(TTransportException::NOT_OPEN, "Called write on non-open socket"); } uint32_t sent = 0; int flags = 0; #ifdef MSG_NOSIGNAL // Note the use of MSG_NOSIGNAL to suppress SIGPIPE errors, instead we // check for the THRIFT_EPIPE return condition and close the socket in that case flags |= MSG_NOSIGNAL; #endif // ifdef MSG_NOSIGNAL int b = static_cast(send(socket_, const_cast_sockopt(buf + sent), len - sent, flags)); if (b < 0) { if (THRIFT_GET_SOCKET_ERROR == THRIFT_EWOULDBLOCK || THRIFT_GET_SOCKET_ERROR == THRIFT_EAGAIN) { return 0; } // Fail on a send error int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSocket::write_partial() send() " + getSocketInfo(), errno_copy); if (errno_copy == THRIFT_EPIPE || errno_copy == THRIFT_ECONNRESET || errno_copy == THRIFT_ENOTCONN) { throw TTransportException(TTransportException::NOT_OPEN, "write() send()", errno_copy); } throw TTransportException(TTransportException::UNKNOWN, "write() send()", errno_copy); } // Fail on blocked send if (b == 0) { throw TTransportException(TTransportException::NOT_OPEN, "Socket send returned 0."); } return b; } std::string TSocket::getHost() const { return host_; } int TSocket::getPort() const { return port_; } std::string TSocket::getPath() const { return path_; } bool TSocket::isUnixDomainSocket() const { return !path_.empty(); } void TSocket::setHost(string host) { host_ = host; } void TSocket::setPort(int port) { port_ = port; } void TSocket::setPath(std::string path) { path_ = path; } void TSocket::setLinger(bool on, int linger) { lingerOn_ = on; lingerVal_ = linger; if (socket_ == THRIFT_INVALID_SOCKET) { return; } #ifndef _WIN32 struct linger l = {(lingerOn_ ? 1 : 0), lingerVal_}; #else struct linger l = {static_cast(lingerOn_ ? 1 : 0), static_cast(lingerVal_)}; #endif int ret = setsockopt(socket_, SOL_SOCKET, SO_LINGER, cast_sockopt(&l), sizeof(l)); if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. TOutput::instance().perror("TSocket::setLinger() setsockopt() " + getSocketInfo(), errno_copy); } } void TSocket::setNoDelay(bool noDelay) { noDelay_ = noDelay; if (socket_ == THRIFT_INVALID_SOCKET || isUnixDomainSocket()) { return; } // Set socket to NODELAY int v = noDelay_ ? 1 : 0; int ret = setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, cast_sockopt(&v), sizeof(v)); if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. TOutput::instance().perror("TSocket::setNoDelay() setsockopt() " + getSocketInfo(), errno_copy); } } void TSocket::setConnTimeout(int ms) { connTimeout_ = ms; } void setGenericTimeout(THRIFT_SOCKET s, int timeout_ms, int optname) { if (timeout_ms < 0) { char errBuf[512]; sprintf(errBuf, "TSocket::setGenericTimeout with negative input: %d\n", timeout_ms); TOutput::instance()(errBuf); return; } if (s == THRIFT_INVALID_SOCKET) { return; } #ifdef _WIN32 DWORD platform_time = static_cast(timeout_ms); #else struct timeval platform_time = {(int)(timeout_ms / 1000), (int)((timeout_ms % 1000) * 1000)}; #endif int ret = setsockopt(s, SOL_SOCKET, optname, cast_sockopt(&platform_time), sizeof(platform_time)); if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. TOutput::instance().perror("TSocket::setGenericTimeout() setsockopt() ", errno_copy); } } void TSocket::setRecvTimeout(int ms) { setGenericTimeout(socket_, ms, SO_RCVTIMEO); recvTimeout_ = ms; } void TSocket::setSendTimeout(int ms) { setGenericTimeout(socket_, ms, SO_SNDTIMEO); sendTimeout_ = ms; } void TSocket::setKeepAlive(bool keepAlive) { keepAlive_ = keepAlive; if (socket_ == THRIFT_INVALID_SOCKET) { return; } #ifdef _WIN32 if (isUnixDomainSocket()) { // Windows Domain sockets do not support SO_KEEPALIVE. return; } #endif int value = keepAlive_; int ret = setsockopt(socket_, SOL_SOCKET, SO_KEEPALIVE, const_cast_sockopt(&value), sizeof(value)); if (ret == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; // Copy THRIFT_GET_SOCKET_ERROR because we're allocating memory. TOutput::instance().perror("TSocket::setKeepAlive() setsockopt() " + getSocketInfo(), errno_copy); } } void TSocket::setMaxRecvRetries(int maxRecvRetries) { maxRecvRetries_ = maxRecvRetries; } string TSocket::getSocketInfo() const { std::ostringstream oss; if (!isUnixDomainSocket()) { if (host_.empty() || port_ == 0) { oss << ""; } else { oss << ""; } } else { std::string fmt_path_ = path_; // Handle printing abstract sockets (first character is a '\0' char): if (!fmt_path_.empty() && fmt_path_[0] == '\0') fmt_path_[0] = '@'; oss << ""; } return oss.str(); } std::string TSocket::getPeerHost() const { if (peerHost_.empty() && !isUnixDomainSocket()) { struct sockaddr_storage addr; struct sockaddr* addrPtr; socklen_t addrLen; if (socket_ == THRIFT_INVALID_SOCKET) { return host_; } addrPtr = getCachedAddress(&addrLen); if (addrPtr == nullptr) { addrLen = sizeof(addr); if (getpeername(socket_, (sockaddr*)&addr, &addrLen) != 0) { return peerHost_; } addrPtr = (sockaddr*)&addr; const_cast(*this).setCachedAddress(addrPtr, addrLen); } char clienthost[NI_MAXHOST]; char clientservice[NI_MAXSERV]; getnameinfo((sockaddr*)addrPtr, addrLen, clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), 0); peerHost_ = clienthost; } return peerHost_; } std::string TSocket::getPeerAddress() const { if (peerAddress_.empty() && !isUnixDomainSocket()) { struct sockaddr_storage addr; struct sockaddr* addrPtr; socklen_t addrLen; if (socket_ == THRIFT_INVALID_SOCKET) { return peerAddress_; } addrPtr = getCachedAddress(&addrLen); if (addrPtr == nullptr) { addrLen = sizeof(addr); if (getpeername(socket_, (sockaddr*)&addr, &addrLen) != 0) { return peerAddress_; } addrPtr = (sockaddr*)&addr; const_cast(*this).setCachedAddress(addrPtr, addrLen); } char clienthost[NI_MAXHOST]; char clientservice[NI_MAXSERV]; getnameinfo(addrPtr, addrLen, clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), NI_NUMERICHOST | NI_NUMERICSERV); peerAddress_ = clienthost; peerPort_ = std::atoi(clientservice); } return peerAddress_; } int TSocket::getPeerPort() const { getPeerAddress(); return peerPort_; } void TSocket::setCachedAddress(const sockaddr* addr, socklen_t len) { if (isUnixDomainSocket()) { return; } switch (addr->sa_family) { case AF_INET: if (len == sizeof(sockaddr_in)) { memcpy((void*)&cachedPeerAddr_.ipv4, (void*)addr, len); } break; case AF_INET6: if (len == sizeof(sockaddr_in6)) { memcpy((void*)&cachedPeerAddr_.ipv6, (void*)addr, len); } break; } peerAddress_.clear(); peerHost_.clear(); } sockaddr* TSocket::getCachedAddress(socklen_t* len) const { switch (cachedPeerAddr_.ipv4.sin_family) { case AF_INET: *len = sizeof(sockaddr_in); return (sockaddr*)&cachedPeerAddr_.ipv4; case AF_INET6: *len = sizeof(sockaddr_in6); return (sockaddr*)&cachedPeerAddr_.ipv6; default: return nullptr; } } bool TSocket::useLowMinRto_ = false; void TSocket::setUseLowMinRto(bool useLowMinRto) { useLowMinRto_ = useLowMinRto; } bool TSocket::getUseLowMinRto() { return useLowMinRto_; } const std::string TSocket::getOrigin() const { std::ostringstream oss; oss << getPeerHost() << ":" << getPeerPort(); return oss.str(); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TPipeServer.h0000664000175000017500000000657015165535636023441 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSERVERWINPIPES_H_ #define _THRIFT_TRANSPORT_TSERVERWINPIPES_H_ 1 #include #include #ifndef _WIN32 #include #endif #define TPIPE_SERVER_MAX_CONNS_DEFAULT PIPE_UNLIMITED_INSTANCES // Windows - set security to allow non-elevated apps // to access pipes created by elevated apps. // Full access to everyone const std::string DEFAULT_PIPE_SECURITY{"D:(A;;FA;;;WD)"}; namespace apache { namespace thrift { namespace transport { /** * Windows Pipes implementation of TServerTransport. * Don't destroy a TPipeServer at global scope, as that will cause a thread join * during DLLMain. That also means that TServer's using TPipeServer shouldn't be at global * scope. */ #ifdef _WIN32 class TPipeServerImpl; class TPipe; class TPipeServer : public TServerTransport { public: // Constructors // Named Pipe - TPipeServer(const std::string& pipename, uint32_t bufsize); TPipeServer(const std::string& pipename, uint32_t bufsize, uint32_t maxconnections); TPipeServer(const std::string& pipename, uint32_t bufsize, uint32_t maxconnections, const std::string& securityDescriptor); TPipeServer(const std::string& pipename); // Anonymous pipe - TPipeServer(int bufsize); TPipeServer(); // Destructor virtual ~TPipeServer(); bool isOpen() const override; // Standard transport callbacks void interrupt() override; void close() override; void listen() override; // Accessors std::string getPipename(); void setPipename(const std::string& pipename); int getBufferSize(); void setBufferSize(int bufsize); HANDLE getPipeHandle(); // Named Pipe R/W -or- Anonymous pipe Read handle HANDLE getWrtPipeHandle(); HANDLE getClientRdPipeHandle(); HANDLE getClientWrtPipeHandle(); bool getAnonymous(); void setAnonymous(bool anon); void setMaxConnections(uint32_t maxconnections); void setSecurityDescriptor(const std::string& securityDescriptor); // this function is intended to be used in generic / template situations, // so its name needs to be the same as TPipe's HANDLE getNativeWaitHandle(); protected: virtual std::shared_ptr acceptImpl(); private: std::shared_ptr impl_; std::string pipename_; std::string securityDescriptor_; uint32_t bufsize_; uint32_t maxconns_; bool isAnonymous_; }; #else //_WIN32 //*NIX named pipe implementation uses domain socket typedef TServerSocket TPipeServer; #endif } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TSERVERWINPIPES_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TFileTransport.h0000664000175000017500000003116415167543515024143 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TFILETRANSPORT_H_ #define _THRIFT_TRANSPORT_TFILETRANSPORT_H_ 1 #include #include #include #include #include #include #include #include #include #include namespace apache { namespace thrift { namespace transport { using apache::thrift::TProcessor; using apache::thrift::protocol::TProtocolFactory; using apache::thrift::concurrency::Mutex; using apache::thrift::concurrency::Monitor; // Data pertaining to a single event typedef struct eventInfo { uint8_t* eventBuff_; uint32_t eventSize_; uint32_t eventBuffPos_; eventInfo() : eventBuff_(nullptr), eventSize_(0), eventBuffPos_(0){}; ~eventInfo() { if (eventBuff_) { delete[] eventBuff_; } } } eventInfo; // information about current read state typedef struct readState { eventInfo* event_; // keep track of event size uint8_t eventSizeBuff_[4]; uint8_t eventSizeBuffPos_; bool readingSize_; // read buffer variables int32_t bufferPtr_; int32_t bufferLen_; // last successful dispatch point int32_t lastDispatchPtr_; void resetState(uint32_t lastDispatchPtr) { readingSize_ = true; eventSizeBuffPos_ = 0; lastDispatchPtr_ = lastDispatchPtr; } void resetAllValues() { resetState(0); bufferPtr_ = 0; bufferLen_ = 0; if (event_) { delete (event_); } event_ = nullptr; } inline uint32_t getEventSize() { const void* buffer = reinterpret_cast(eventSizeBuff_); return *reinterpret_cast(buffer); } readState() { event_ = nullptr; resetAllValues(); } ~readState() { if (event_) { delete (event_); } } } readState; /** * TFileTransportBuffer - buffer class used by TFileTransport for queueing up events * to be written to disk. Should be used in the following way: * 1) Buffer created * 2) Buffer written to (addEvent) * 3) Buffer read from (getNext) * 4) Buffer reset (reset) * 5) Go back to 2, or destroy buffer * * The buffer should never be written to after it is read from, unless it is reset first. * Note: The above rules are enforced mainly for debugging its sole client TFileTransport * which uses the buffer in this way. * */ class TFileTransportBuffer { public: TFileTransportBuffer(uint32_t size); virtual ~TFileTransportBuffer(); bool addEvent(eventInfo* event); eventInfo* getNext(); void reset(); bool isFull(); bool isEmpty(); private: TFileTransportBuffer(); // should not be used enum mode { WRITE, READ }; mode bufferMode_; uint32_t writePoint_; uint32_t readPoint_; uint32_t size_; eventInfo** buffer_; }; /** * Abstract interface for transports used to read files */ class TFileReaderTransport : virtual public TTransport { public: virtual int32_t getReadTimeout() = 0; virtual void setReadTimeout(int32_t readTimeout) = 0; virtual uint32_t getNumChunks() = 0; virtual uint32_t getCurChunk() = 0; virtual void seekToChunk(int32_t chunk) = 0; virtual void seekToEnd() = 0; }; /** * Abstract interface for transports used to write files */ class TFileWriterTransport : virtual public TTransport { public: virtual uint32_t getChunkSize() = 0; virtual void setChunkSize(uint32_t chunkSize) = 0; }; /** * File implementation of a transport. Reads and writes are done to a * file on disk. * */ class TFileTransport : public TFileReaderTransport, public TFileWriterTransport { public: TFileTransport(std::string path, bool readOnly = false, std::shared_ptr config = nullptr); ~TFileTransport() override; // TODO: what is the correct behaviour for this? // the log file is generally always open bool isOpen() const override { return true; } void write(const uint8_t* buf, uint32_t len); void flush() override; uint32_t readAll(uint8_t* buf, uint32_t len); uint32_t read(uint8_t* buf, uint32_t len); bool peek() override; // log-file specific functions void seekToChunk(int32_t chunk) override; void seekToEnd() override; uint32_t getNumChunks() override; uint32_t getCurChunk() override; // for changing the output file void resetOutputFile(int fd, std::string filename, off_t offset); // Setter/Getter functions for user-controllable options void setReadBuffSize(uint32_t readBuffSize) { if (readBuffSize) { readBuffSize_ = readBuffSize; } } uint32_t getReadBuffSize() { return readBuffSize_; } static const int32_t TAIL_READ_TIMEOUT = -1; static const int32_t NO_TAIL_READ_TIMEOUT = 0; void setReadTimeout(int32_t readTimeout) override { readTimeout_ = readTimeout; } int32_t getReadTimeout() override { return readTimeout_; } void setChunkSize(uint32_t chunkSize) override { if (chunkSize) { chunkSize_ = chunkSize; } } uint32_t getChunkSize() override { return chunkSize_; } void setEventBufferSize(uint32_t bufferSize) { if (bufferAndThreadInitialized_) { TOutput::instance()("Cannot change the buffer size after writer thread started"); return; } eventBufferSize_ = bufferSize; } uint32_t getEventBufferSize() { return eventBufferSize_; } void setFlushMaxUs(uint32_t flushMaxUs) { if (flushMaxUs) { flushMaxUs_ = flushMaxUs; } } uint32_t getFlushMaxUs() { return flushMaxUs_; } void setFlushMaxBytes(uint32_t flushMaxBytes) { if (flushMaxBytes) { flushMaxBytes_ = flushMaxBytes; } } uint32_t getFlushMaxBytes() { return flushMaxBytes_; } void setMaxEventSize(uint32_t maxEventSize) { maxEventSize_ = maxEventSize; } uint32_t getMaxEventSize() { return maxEventSize_; } void setMaxCorruptedEvents(uint32_t maxCorruptedEvents) { maxCorruptedEvents_ = maxCorruptedEvents; } uint32_t getMaxCorruptedEvents() { return maxCorruptedEvents_; } void setEofSleepTimeUs(uint32_t eofSleepTime) { if (eofSleepTime) { eofSleepTime_ = eofSleepTime; } } uint32_t getEofSleepTimeUs() { return eofSleepTime_; } /* * Override TTransport *_virt() functions to invoke our implementations. * We cannot use TVirtualTransport to provide these, since we need to inherit * virtually from TTransport. */ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return this->read(buf, len); } uint32_t readAll_virt(uint8_t* buf, uint32_t len) override { return this->readAll(buf, len); } void write_virt(const uint8_t* buf, uint32_t len) override { this->write(buf, len); } private: // helper functions for writing to a file void enqueueEvent(const uint8_t* buf, uint32_t eventLen); bool swapEventBuffers(const std::chrono::time_point *deadline); bool initBufferAndWriteThread(); // control for writer thread static void* startWriterThread(void* ptr) { static_cast(ptr)->writerThread(); return nullptr; } void writerThread(); // helper functions for reading from a file eventInfo* readEvent(); // event corruption-related functions bool isEventCorrupted(); void performRecovery(); // Utility functions void openLogFile(); std::chrono::time_point getNextFlushTime(); // Class variables readState readState_; uint8_t* readBuff_; eventInfo* currentEvent_; uint32_t readBuffSize_; static const uint32_t DEFAULT_READ_BUFF_SIZE = 1 * 1024 * 1024; int32_t readTimeout_; static const int32_t DEFAULT_READ_TIMEOUT_MS = 200; // size of chunks that file will be split up into uint32_t chunkSize_; static const uint32_t DEFAULT_CHUNK_SIZE = 16 * 1024 * 1024; // size of event buffers uint32_t eventBufferSize_; static const uint32_t DEFAULT_EVENT_BUFFER_SIZE = 10000; // max number of microseconds that can pass without flushing uint32_t flushMaxUs_; static const uint32_t DEFAULT_FLUSH_MAX_US = 3000000; // max number of bytes that can be written without flushing uint32_t flushMaxBytes_; static const uint32_t DEFAULT_FLUSH_MAX_BYTES = 1000 * 1024; // max event size uint32_t maxEventSize_; static const uint32_t DEFAULT_MAX_EVENT_SIZE = 0; // max number of corrupted events per chunk uint32_t maxCorruptedEvents_; static const uint32_t DEFAULT_MAX_CORRUPTED_EVENTS = 0; // sleep duration when EOF is hit uint32_t eofSleepTime_; static const uint32_t DEFAULT_EOF_SLEEP_TIME_US = 500 * 1000; // sleep duration when a corrupted event is encountered uint32_t corruptedEventSleepTime_; static const uint32_t DEFAULT_CORRUPTED_SLEEP_TIME_US = 1 * 1000 * 1000; // sleep duration in seconds when an IO error is encountered in the writer thread uint32_t writerThreadIOErrorSleepTime_; static const uint32_t DEFAULT_WRITER_THREAD_SLEEP_TIME_US = 60 * 1000 * 1000; // writer thread apache::thrift::concurrency::ThreadFactory threadFactory_; std::shared_ptr writerThread_; // buffers to hold data before it is flushed. Each element of the buffer stores a msg that // needs to be written to the file. The buffers are swapped by the writer thread. TFileTransportBuffer* dequeueBuffer_; TFileTransportBuffer* enqueueBuffer_; // conditions used to block when the buffer is full or empty Monitor notFull_, notEmpty_; std::atomic closing_; // To keep track of whether the buffer has been flushed Monitor flushed_; std::atomic forceFlush_; // Mutex that is grabbed when enqueueing and swapping the read/write buffers Mutex mutex_; // File information std::string filename_; int fd_; // Whether the writer thread and buffers have been initialized bool bufferAndThreadInitialized_; // Offset within the file off_t offset_; // event corruption information uint32_t lastBadChunk_; uint32_t numCorruptedEventsInChunk_; bool readOnly_; }; // Exception thrown when EOF is hit class TEOFException : public TTransportException { public: TEOFException() : TTransportException(TTransportException::END_OF_FILE){}; }; // wrapper class to process events from a file containing thrift events class TFileProcessor { public: /** * Constructor that defaults output transport to null transport * * @param processor processes log-file events * @param protocolFactory protocol factory * @param inputTransport file transport */ TFileProcessor(std::shared_ptr processor, std::shared_ptr protocolFactory, std::shared_ptr inputTransport); TFileProcessor(std::shared_ptr processor, std::shared_ptr inputProtocolFactory, std::shared_ptr outputProtocolFactory, std::shared_ptr inputTransport); /** * Constructor * * @param processor processes log-file events * @param protocolFactory protocol factory * @param inputTransport input file transport * @param output output transport */ TFileProcessor(std::shared_ptr processor, std::shared_ptr protocolFactory, std::shared_ptr inputTransport, std::shared_ptr outputTransport); /** * processes events from the file * * @param numEvents number of events to process (0 for unlimited) * @param tail tails the file if true */ void process(uint32_t numEvents, bool tail); /** * process events until the end of the chunk * */ void processChunk(); private: std::shared_ptr processor_; std::shared_ptr inputProtocolFactory_; std::shared_ptr outputProtocolFactory_; std::shared_ptr inputTransport_; std::shared_ptr outputTransport_; }; } } } // apache::thrift::transport #endif // _THRIFT_TRANSPORT_TFILETRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TFDTransport.cpp0000664000175000017500000000570615165535636024116 0ustar00buildbuild00000000000000/* * 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 #ifdef _WIN32 #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #include #include using std::string; namespace apache { namespace thrift { namespace transport { void TFDTransport::close() { if (!isOpen()) { return; } int rv = ::THRIFT_CLOSE(fd_); int errno_copy = THRIFT_ERRNO; fd_ = -1; // Have to check uncaught_exception because this is called in the destructor. #ifdef __cpp_lib_uncaught_exceptions if (rv < 0 && !std::uncaught_exceptions()) { #else if (rv < 0 && !std::uncaught_exception()) { #endif throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::close()", errno_copy); } } uint32_t TFDTransport::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); unsigned int maxRetries = 5; // same as the TSocket default unsigned int retries = 0; while (true) { THRIFT_SSIZET rv = ::THRIFT_READ(fd_, buf, len); if (rv < 0) { if (THRIFT_ERRNO == THRIFT_EINTR && retries < maxRetries) { // If interrupted, try again ++retries; continue; } int errno_copy = THRIFT_ERRNO; throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::read()", errno_copy); } // this should be fine, since we already checked for negative values, // and ::read should only return a 32-bit value since len is 32-bit. return static_cast(rv); } } void TFDTransport::write(const uint8_t* buf, uint32_t len) { while (len > 0) { THRIFT_SSIZET rv = ::THRIFT_WRITE(fd_, buf, len); if (rv < 0) { int errno_copy = THRIFT_ERRNO; throw TTransportException(TTransportException::UNKNOWN, "TFDTransport::write()", errno_copy); } else if (rv == 0) { throw TTransportException(TTransportException::END_OF_FILE, "TFDTransport::write()"); } buf += rv; // this should be fine, as we've already checked for negative values, and //::write shouldn't return more than a uint32_t since len is a uint32_t len -= static_cast(rv); } } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TServerSocket.cpp0000664000175000017500000006401715167543515024324 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_UN_H #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_SYS_POLL_H #include #endif #ifdef HAVE_NETINET_IN_H #include #include #endif #ifdef HAVE_NETDB_H #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #include #include #include #include #include #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif #ifndef SOCKOPT_CAST_T #ifndef _WIN32 #define SOCKOPT_CAST_T void #else #define SOCKOPT_CAST_T char #endif // _WIN32 #endif #ifdef _WIN32 // Including Windows.h can conflict with Winsock2 usage, and also // adds problematic macros like min() and max(). Try to work around: #define NOMINMAX #define WIN32_LEAN_AND_MEAN #include #undef NOMINMAX #undef WIN32_LEAN_AND_MEAN #include #endif template inline const SOCKOPT_CAST_T* const_cast_sockopt(const T* v) { return reinterpret_cast(v); } template inline SOCKOPT_CAST_T* cast_sockopt(T* v) { return reinterpret_cast(v); } void destroyer_of_fine_sockets(THRIFT_SOCKET* ssock) { ::THRIFT_CLOSESOCKET(*ssock); delete ssock; } using std::shared_ptr; using std::string; namespace apache { namespace thrift { namespace transport { TServerSocket::TServerSocket(int port) : interruptableChildren_(true), port_(port), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(0), recvTimeout_(0), accTimeout_(-1), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), childInterruptSockWriter_(THRIFT_INVALID_SOCKET), boundSocketType_(SocketType::NONE) { } TServerSocket::TServerSocket(int port, int sendTimeout, int recvTimeout) : interruptableChildren_(true), port_(port), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(sendTimeout), recvTimeout_(recvTimeout), accTimeout_(-1), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), childInterruptSockWriter_(THRIFT_INVALID_SOCKET), boundSocketType_(SocketType::NONE) { } TServerSocket::TServerSocket(const string& address, int port) : interruptableChildren_(true), port_(port), address_(address), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(0), recvTimeout_(0), accTimeout_(-1), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), childInterruptSockWriter_(THRIFT_INVALID_SOCKET), boundSocketType_(SocketType::NONE) { } TServerSocket::TServerSocket(const string& path) : interruptableChildren_(true), port_(0), path_(path), serverSocket_(THRIFT_INVALID_SOCKET), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(0), recvTimeout_(0), accTimeout_(-1), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), childInterruptSockWriter_(THRIFT_INVALID_SOCKET), boundSocketType_(SocketType::NONE) { } TServerSocket::TServerSocket(THRIFT_SOCKET sock,SocketType socketType) : interruptableChildren_(true), port_(0), path_(), serverSocket_(sock), acceptBacklog_(DEFAULT_BACKLOG), sendTimeout_(0), recvTimeout_(0), accTimeout_(-1), retryLimit_(0), retryDelay_(0), tcpSendBuffer_(0), tcpRecvBuffer_(0), keepAlive_(false), listening_(false), interruptSockWriter_(THRIFT_INVALID_SOCKET), interruptSockReader_(THRIFT_INVALID_SOCKET), childInterruptSockWriter_(THRIFT_INVALID_SOCKET), boundSocketType_(socketType) { } TServerSocket::~TServerSocket() { close(); } bool TServerSocket::isOpen() const { if (serverSocket_ == THRIFT_INVALID_SOCKET) return false; if (!listening_) return false; if (isUnixDomainSocket() && (path_[0] != '\0')) { // On some platforms the domain socket file may not be instantly // available yet, i.e. the Windows file system can be slow. Therefore // we should check that the domain socket file actually exists. #ifdef _MSC_VER // Currently there is a bug in ClangCl on Windows so the stat() call // does not work. Workaround is a Windows-specific call if file exists: DWORD const f_attrib = GetFileAttributesA(path_.c_str()); if (f_attrib == INVALID_FILE_ATTRIBUTES) { #else struct THRIFT_STAT path_info; if (::THRIFT_STAT(path_.c_str(), &path_info) < 0) { #endif const std::string vError = "TServerSocket::isOpen(): The domain socket path '" + path_ + "' does not exist (yet)."; TOutput::instance().perror(vError.c_str(), THRIFT_GET_SOCKET_ERROR); return false; } } return true; } void TServerSocket::setSendTimeout(int sendTimeout) { sendTimeout_ = sendTimeout; } void TServerSocket::setRecvTimeout(int recvTimeout) { recvTimeout_ = recvTimeout; } void TServerSocket::setAcceptTimeout(int accTimeout) { accTimeout_ = accTimeout; } void TServerSocket::setAcceptBacklog(int accBacklog) { acceptBacklog_ = accBacklog; } void TServerSocket::setRetryLimit(int retryLimit) { retryLimit_ = retryLimit; } void TServerSocket::setRetryDelay(int retryDelay) { retryDelay_ = retryDelay; } void TServerSocket::setTcpSendBuffer(int tcpSendBuffer) { tcpSendBuffer_ = tcpSendBuffer; } void TServerSocket::setTcpRecvBuffer(int tcpRecvBuffer) { tcpRecvBuffer_ = tcpRecvBuffer; } void TServerSocket::setInterruptableChildren(bool enable) { if (listening_) { throw std::logic_error("setInterruptableChildren cannot be called after listen()"); } interruptableChildren_ = enable; } void TServerSocket::_setup_sockopts() { int one = 1; if (!isUnixDomainSocket()) { // Set THRIFT_NO_SOCKET_CACHING to prevent 2MSL delay on accept. // This does not work with Domain sockets on most platforms. And // on Windows it completely breaks the socket. Therefore do not // use this on Domain sockets. if (-1 == setsockopt(serverSocket_, SOL_SOCKET, THRIFT_NO_SOCKET_CACHING, cast_sockopt(&one), sizeof(one))) { // NOTE: SO_EXCLUSIVEADDRUSE socket option can only be used by members // of the Administrators security group on Windows XP and earlier. But // we do not target WinXP anymore so no special checks required. int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() setsockopt() THRIFT_NO_SOCKET_CACHING ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set THRIFT_NO_SOCKET_CACHING", errno_copy); } } // Set TCP buffer sizes if (tcpSendBuffer_ > 0) { if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_SNDBUF, cast_sockopt(&tcpSendBuffer_), sizeof(tcpSendBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_SNDBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", errno_copy); } } if (tcpRecvBuffer_ > 0) { if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_RCVBUF, cast_sockopt(&tcpRecvBuffer_), sizeof(tcpRecvBuffer_))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_RCVBUF ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", errno_copy); } } // Turn linger off, don't want to block on calls to close struct linger ling = {0, 0}; if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER, cast_sockopt(&ling), sizeof(ling))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_LINGER ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy); } #ifdef SO_NOSIGPIPE if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() setsockopt() SO_NOSIGPIPE", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_NOSIGPIPE", errno_copy); } #endif // Set NONBLOCK on the accept socket int flags = THRIFT_FCNTL(serverSocket_, THRIFT_F_GETFL, 0); if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_GETFL failed", errno_copy); } if (-1 == THRIFT_FCNTL(serverSocket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() THRIFT_FCNTL() THRIFT_O_NONBLOCK ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "THRIFT_FCNTL() THRIFT_F_SETFL THRIFT_O_NONBLOCK failed", errno_copy); } } void TServerSocket::_setup_unixdomain_sockopts() { } void TServerSocket::_setup_tcp_sockopts() { int one = 1; // Defer accept #ifdef TCP_DEFER_ACCEPT if (!isUnixDomainSocket()) { if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_DEFER_ACCEPT, &one, sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() setsockopt() TCP_DEFER_ACCEPT ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_DEFER_ACCEPT", errno_copy); } } #endif // #ifdef TCP_DEFER_ACCEPT // TCP Nodelay, speed over bandwidth if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY, cast_sockopt(&one), sizeof(one))) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() setsockopt() TCP_NODELAY ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy); } } void TServerSocket::listen() { #ifdef _WIN32 TWinsockSingleton::create(); #endif // _WIN32 THRIFT_SOCKET sv[2]; // Create the socket pair used to interrupt if (-1 == THRIFT_SOCKETPAIR(AF_LOCAL, SOCK_STREAM, 0, sv)) { TOutput::instance().perror("TServerSocket::listen() socketpair() interrupt", THRIFT_GET_SOCKET_ERROR); interruptSockWriter_ = THRIFT_INVALID_SOCKET; interruptSockReader_ = THRIFT_INVALID_SOCKET; } else { interruptSockWriter_ = sv[1]; interruptSockReader_ = sv[0]; } // Create the socket pair used to interrupt all clients if (-1 == THRIFT_SOCKETPAIR(AF_LOCAL, SOCK_STREAM, 0, sv)) { TOutput::instance().perror("TServerSocket::listen() socketpair() childInterrupt", THRIFT_GET_SOCKET_ERROR); childInterruptSockWriter_ = THRIFT_INVALID_SOCKET; pChildInterruptSockReader_.reset(); } else { childInterruptSockWriter_ = sv[1]; pChildInterruptSockReader_ = std::shared_ptr(new THRIFT_SOCKET(sv[0]), destroyer_of_fine_sockets); } // Validate port number if (port_ < 0 || port_ > 0xFFFF) { throw TTransportException(TTransportException::BAD_ARGS, "Specified port is invalid"); } // Resolve host:port strings into an iterable of struct addrinfo* AddressResolutionHelper resolved_addresses; if (!isUnixDomainSocket()) { try { resolved_addresses.resolve(address_, std::to_string(port_), SOCK_STREAM, #ifdef ANDROID AI_PASSIVE | AI_ADDRCONFIG); #else AI_PASSIVE | AI_V4MAPPED); #endif } catch (const std::system_error& e) { TOutput::instance().printf("getaddrinfo() -> %d; %s", e.code().value(), e.what()); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for server socket."); } } // we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't // always seem to work. The client can configure the retry variables. int retries = 0; int errno_copy = 0; if (isUnixDomainSocket()) { // -- Unix Domain Socket -- // if (serverSocket_ == THRIFT_INVALID_SOCKET) serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP); if (serverSocket_ == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy); } _setup_sockopts(); _setup_unixdomain_sockopts(); // Windows supports Unix domain sockets since it ships the header // HAVE_AF_UNIX_H (see https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/) #if (!defined(_WIN32) || defined(HAVE_AF_UNIX_H)) struct sockaddr_un address; socklen_t structlen = fillUnixSocketAddr(address, path_); do { if (0 == ::bind(serverSocket_, (struct sockaddr*)&address, structlen)) { break; } errno_copy = THRIFT_GET_SOCKET_ERROR; // use short circuit evaluation here to only sleep if we need to } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); #else TOutput::instance().perror("TServerSocket::open() Unix Domain socket path not supported on this version of Windows", -99); throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path not supported"); #endif } else if( boundSocketType_ != SocketType::NONE){ // -- Socket is already bound } else { // -- TCP socket -- // auto addr_iter = AddressResolutionHelper::Iter{}; // Via DNS or somehow else, single hostname can resolve into many addresses. // Results may contain perhaps a mix of IPv4 and IPv6. Here, we iterate // over what system gave us, picking the first address that works. do { if (!addr_iter) { // init + recycle over many retries addr_iter = resolved_addresses.iterate(); } auto trybind = *addr_iter++; serverSocket_ = socket(trybind->ai_family, trybind->ai_socktype, trybind->ai_protocol); if (serverSocket_ == -1) { errno_copy = THRIFT_GET_SOCKET_ERROR; continue; } _setup_sockopts(); _setup_tcp_sockopts(); #ifdef IPV6_V6ONLY if (trybind->ai_family == AF_INET6) { int zero = 0; if (-1 == setsockopt(serverSocket_, IPPROTO_IPV6, IPV6_V6ONLY, cast_sockopt(&zero), sizeof(zero))) { TOutput::instance().perror("TServerSocket::listen() IPV6_V6ONLY ", THRIFT_GET_SOCKET_ERROR); } } #endif // #ifdef IPV6_V6ONLY if (0 == ::bind(serverSocket_, trybind->ai_addr, static_cast(trybind->ai_addrlen))) { break; } errno_copy = THRIFT_GET_SOCKET_ERROR; // use short circuit evaluation here to only sleep if we need to } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); } // TCP socket // // retrieve bind info if ((port_ == 0 || path_.empty() ) && retries <= retryLimit_) { struct sockaddr_storage sa; socklen_t len = sizeof(sa); std::memset(&sa, 0, len); if (::getsockname(serverSocket_, reinterpret_cast(&sa), &len) < 0) { errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::getPort() getsockname() ", errno_copy); } else { if (sa.ss_family == AF_INET6) { const auto* sin = reinterpret_cast(&sa); port_ = ntohs(sin->sin6_port); } else if (sa.ss_family == AF_INET) { const auto* sin = reinterpret_cast(&sa); port_ = ntohs(sin->sin_port); } else if (sa.ss_family == AF_UNIX) { const auto* sin = reinterpret_cast(&sa); path_ = sin->sun_path; } else { TOutput::instance().perror("TServerSocket::getPort() getsockname() unhandled socket type",EINVAL); } } } // throw error if socket still wasn't created successfully if (serverSocket_ == THRIFT_INVALID_SOCKET) { TOutput::instance().perror("TServerSocket::listen() socket() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy); } // throw an error if we failed to bind properly if (retries > retryLimit_) { char errbuf[1024]; if (isUnixDomainSocket()) { #ifdef _WIN32 THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TServerSocket::listen() Could not bind to domain socket path %s, error %d", path_.c_str(), WSAGetLastError()); #else // Fixme: This does not currently handle abstract domain sockets: THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TServerSocket::listen() Could not bind to domain socket path %s", path_.c_str()); #endif } else { THRIFT_SNPRINTF(errbuf, sizeof(errbuf), "TServerSocket::listen() Could not bind to port %d", port_); } TOutput::instance()(errbuf); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not bind", errno_copy); } if (listenCallback_) listenCallback_(serverSocket_); // Call listen if (boundSocketType_ == SocketType::NONE && -1 == ::listen(serverSocket_, acceptBacklog_)) { errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::listen() listen() ", errno_copy); close(); throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy); } // The socket is now listening! listening_ = true; } int TServerSocket::getPort() const { return port_; } std::string TServerSocket::getPath() const { return path_; } bool TServerSocket::isUnixDomainSocket() const { return !path_.empty(); } shared_ptr TServerSocket::acceptImpl() { if (serverSocket_ == THRIFT_INVALID_SOCKET) { throw TTransportException(TTransportException::NOT_OPEN, "TServerSocket not listening"); } struct THRIFT_POLLFD fds[2]; int maxEintrs = 5; int numEintrs = 0; while (true) { std::memset(fds, 0, sizeof(fds)); fds[0].fd = serverSocket_; fds[0].events = THRIFT_POLLIN; if (interruptSockReader_ != THRIFT_INVALID_SOCKET) { fds[1].fd = interruptSockReader_; fds[1].events = THRIFT_POLLIN; } /* TODO: if THRIFT_EINTR is received, we'll restart the timeout. To be accurate, we need to fix this in the future. */ int ret = THRIFT_POLL(fds, 2, accTimeout_); if (ret < 0) { // error cases if (THRIFT_GET_SOCKET_ERROR == THRIFT_EINTR && (numEintrs++ < maxEintrs)) { // THRIFT_EINTR needs to be handled manually and we can tolerate // a certain number continue; } int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::acceptImpl() THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0) { // Check for an interrupt signal if (interruptSockReader_ != THRIFT_INVALID_SOCKET && (fds[1].revents & THRIFT_POLLIN)) { int8_t buf; if (-1 == recv(interruptSockReader_, cast_sockopt(&buf), sizeof(int8_t), 0)) { TOutput::instance().perror("TServerSocket::acceptImpl() recv() interrupt ", THRIFT_GET_SOCKET_ERROR); } throw TTransportException(TTransportException::INTERRUPTED); } // Check for the actual server socket being ready if (fds[0].revents & THRIFT_POLLIN) { break; } } else { TOutput::instance()("TServerSocket::acceptImpl() THRIFT_POLL 0"); throw TTransportException(TTransportException::UNKNOWN); } } struct sockaddr_storage clientAddress; int size = sizeof(clientAddress); THRIFT_SOCKET clientSocket = ::accept(serverSocket_, (struct sockaddr*)&clientAddress, (socklen_t*)&size); if (clientSocket == THRIFT_INVALID_SOCKET) { int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TServerSocket::acceptImpl() ::accept() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy); } // Make sure client socket is blocking int flags = THRIFT_FCNTL(clientSocket, THRIFT_F_GETFL, 0); if (flags == -1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); TOutput::instance().perror("TServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_GETFL ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_GETFL)", errno_copy); } if (-1 == THRIFT_FCNTL(clientSocket, THRIFT_F_SETFL, flags & ~THRIFT_O_NONBLOCK)) { int errno_copy = THRIFT_GET_SOCKET_ERROR; ::THRIFT_CLOSESOCKET(clientSocket); TOutput::instance() .perror("TServerSocket::acceptImpl() THRIFT_FCNTL() THRIFT_F_SETFL ~THRIFT_O_NONBLOCK ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "THRIFT_FCNTL(THRIFT_F_SETFL)", errno_copy); } shared_ptr client = createSocket(clientSocket); client->setPath(path_); if (sendTimeout_ > 0) { client->setSendTimeout(sendTimeout_); } if (recvTimeout_ > 0) { client->setRecvTimeout(recvTimeout_); } if (keepAlive_) { client->setKeepAlive(keepAlive_); } client->setCachedAddress((sockaddr*)&clientAddress, size); if (acceptCallback_) acceptCallback_(clientSocket); return client; } shared_ptr TServerSocket::createSocket(THRIFT_SOCKET clientSocket) { if (interruptableChildren_) { return std::make_shared(clientSocket, pChildInterruptSockReader_); } else { return std::make_shared(clientSocket); } } void TServerSocket::notify(THRIFT_SOCKET notifySocket) { if (notifySocket != THRIFT_INVALID_SOCKET) { int8_t byte = 0; if (-1 == send(notifySocket, cast_sockopt(&byte), sizeof(int8_t), 0)) { TOutput::instance().perror("TServerSocket::notify() send() ", THRIFT_GET_SOCKET_ERROR); } } } void TServerSocket::interrupt() { concurrency::Guard g(rwMutex_); if (interruptSockWriter_ != THRIFT_INVALID_SOCKET) { notify(interruptSockWriter_); } } void TServerSocket::interruptChildren() { concurrency::Guard g(rwMutex_); if (childInterruptSockWriter_ != THRIFT_INVALID_SOCKET) { notify(childInterruptSockWriter_); } } void TServerSocket::close() { concurrency::Guard g(rwMutex_); if (serverSocket_ != THRIFT_INVALID_SOCKET) { if( boundSocketType_ == SocketType::NONE) //Do not close the server socket if it owned by systemd { shutdown(serverSocket_, THRIFT_SHUT_RDWR); ::THRIFT_CLOSESOCKET(serverSocket_); } } if (interruptSockWriter_ != THRIFT_INVALID_SOCKET) { ::THRIFT_CLOSESOCKET(interruptSockWriter_); } if (interruptSockReader_ != THRIFT_INVALID_SOCKET) { ::THRIFT_CLOSESOCKET(interruptSockReader_); } if (childInterruptSockWriter_ != THRIFT_INVALID_SOCKET) { ::THRIFT_CLOSESOCKET(childInterruptSockWriter_); } serverSocket_ = THRIFT_INVALID_SOCKET; interruptSockWriter_ = THRIFT_INVALID_SOCKET; interruptSockReader_ = THRIFT_INVALID_SOCKET; childInterruptSockWriter_ = THRIFT_INVALID_SOCKET; pChildInterruptSockReader_.reset(); listening_ = false; } } // namespace transport } // namespace thrift } // namespace apache thrift-0.23.0/lib/cpp/src/thrift/transport/TBufferTransports.h0000664000175000017500000005563215165535636024671 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TBUFFERTRANSPORTS_H_ #define _THRIFT_TRANSPORT_TBUFFERTRANSPORTS_H_ 1 #include #include #include #include #include #ifdef __GNUC__ #define TDB_LIKELY(val) (__builtin_expect((val), 1)) #define TDB_UNLIKELY(val) (__builtin_expect((val), 0)) #else #define TDB_LIKELY(val) (val) #define TDB_UNLIKELY(val) (val) #endif namespace apache { namespace thrift { namespace transport { /** * Base class for all transports that use read/write buffers for performance. * * TBufferBase is designed to implement the fast-path "memcpy" style * operations that work in the common case. It does so with small and * (eventually) nonvirtual, inlinable methods. TBufferBase is an abstract * class. Subclasses are expected to define the "slow path" operations * that have to be done when the buffers are full or empty. * */ class TBufferBase : public TVirtualTransport { public: /** * Fast-path read. * * When we have enough data buffered to fulfill the read, we can satisfy it * with a single memcpy, then adjust our internal pointers. If the buffer * is empty, we call out to our slow path, implemented by a subclass. * This method is meant to eventually be nonvirtual and inlinable. */ uint32_t read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); uint8_t* new_rBase = rBase_ + len; if (TDB_LIKELY(new_rBase <= rBound_)) { std::memcpy(buf, rBase_, len); rBase_ = new_rBase; return len; } return readSlow(buf, len); } /** * Shortcutted version of readAll. */ uint32_t readAll(uint8_t* buf, uint32_t len) { uint8_t* new_rBase = rBase_ + len; if (TDB_LIKELY(new_rBase <= rBound_)) { std::memcpy(buf, rBase_, len); rBase_ = new_rBase; return len; } return apache::thrift::transport::readAll(*this, buf, len); } /** * Fast-path write. * * When we have enough empty space in our buffer to accommodate the write, we * can satisfy it with a single memcpy, then adjust our internal pointers. * If the buffer is full, we call out to our slow path, implemented by a * subclass. This method is meant to eventually be nonvirtual and * inlinable. */ void write(const uint8_t* buf, uint32_t len) { uint8_t* new_wBase = wBase_ + len; if (TDB_LIKELY(new_wBase <= wBound_)) { std::memcpy(wBase_, buf, len); wBase_ = new_wBase; return; } writeSlow(buf, len); } /** * Fast-path borrow. A lot like the fast-path read. */ const uint8_t* borrow(uint8_t* buf, uint32_t* len) { if (TDB_LIKELY(static_cast(*len) <= rBound_ - rBase_)) { // With strict aliasing, writing to len shouldn't force us to // refetch rBase_ from memory. TODO(dreiss): Verify this. *len = static_cast(rBound_ - rBase_); return rBase_; } return borrowSlow(buf, len); } /** * Consume doesn't require a slow path. */ void consume(uint32_t len) { countConsumedMessageBytes(len); if (TDB_LIKELY(static_cast(len) <= rBound_ - rBase_)) { rBase_ += len; } else { throw TTransportException(TTransportException::BAD_ARGS, "consume did not follow a borrow."); } } protected: /// Slow path read. virtual uint32_t readSlow(uint8_t* buf, uint32_t len) = 0; /// Slow path write. virtual void writeSlow(const uint8_t* buf, uint32_t len) = 0; /** * Slow path borrow. * * POSTCONDITION: return == nullptr || rBound_ - rBase_ >= *len */ virtual const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) = 0; /** * Trivial constructor. * * Initialize pointers safely. Constructing is not a very * performance-sensitive operation, so it is okay to just leave it to * the concrete class to set up pointers correctly. */ TBufferBase(std::shared_ptr config = nullptr) : TVirtualTransport(config), rBase_(nullptr), rBound_(nullptr), wBase_(nullptr), wBound_(nullptr) {} /// Convenience mutator for setting the read buffer. void setReadBuffer(uint8_t* buf, uint32_t len) { rBase_ = buf; rBound_ = buf + len; } /// Convenience mutator for setting the write buffer. void setWriteBuffer(uint8_t* buf, uint32_t len) { wBase_ = buf; wBound_ = buf + len; } ~TBufferBase() override = default; /// Reads begin here. uint8_t* rBase_; /// Reads may extend to just before here. uint8_t* rBound_; /// Writes begin here. uint8_t* wBase_; /// Writes may extend to just before here. uint8_t* wBound_; }; /** * Buffered transport. For reads it will read more data than is requested * and will serve future data out of a local buffer. For writes, data is * stored to an in memory buffer before being written out. * */ class TBufferedTransport : public TVirtualTransport { public: static const int DEFAULT_BUFFER_SIZE = 512; /// Use default buffer sizes. TBufferedTransport(std::shared_ptr transport, std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(transport), rBufSize_(DEFAULT_BUFFER_SIZE), wBufSize_(DEFAULT_BUFFER_SIZE), rBuf_(new uint8_t[rBufSize_]), wBuf_(new uint8_t[wBufSize_]) { initPointers(); } /// Use specified buffer sizes. TBufferedTransport(std::shared_ptr transport, uint32_t sz, std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(transport), rBufSize_(sz), wBufSize_(sz), rBuf_(new uint8_t[rBufSize_]), wBuf_(new uint8_t[wBufSize_]) { initPointers(); } /// Use specified read and write buffer sizes. TBufferedTransport(std::shared_ptr transport, uint32_t rsz, uint32_t wsz, std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(transport), rBufSize_(rsz), wBufSize_(wsz), rBuf_(new uint8_t[rBufSize_]), wBuf_(new uint8_t[wBufSize_]) { initPointers(); } void open() override { transport_->open(); } bool isOpen() const override { return transport_->isOpen(); } bool peek() override { if (rBase_ == rBound_) { setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_)); } return (rBound_ > rBase_); } void close() override { flush(); transport_->close(); } uint32_t readSlow(uint8_t* buf, uint32_t len) override; void writeSlow(const uint8_t* buf, uint32_t len) override; void flush() override; /** * Returns the origin of the underlying transport */ const std::string getOrigin() const override { return transport_->getOrigin(); } /** * The following behavior is currently implemented by TBufferedTransport, * but that may change in a future version: * 1/ If len is at most rBufSize_, borrow will never return nullptr. * Depending on the underlying transport, it could throw an exception * or hang forever. * 2/ Some borrow requests may copy bytes internally. However, * if len is at most rBufSize_/2, none of the copied bytes * will ever have to be copied again. For optimial performance, * stay under this limit. */ const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) override; std::shared_ptr getUnderlyingTransport() { return transport_; } /* * TVirtualTransport provides a default implementation of readAll(). * We want to use the TBufferBase version instead. */ uint32_t readAll(uint8_t* buf, uint32_t len) { return TBufferBase::readAll(buf, len); } uint32_t readEnd() override { resetConsumedMessageSize(); return 0; } protected: void initPointers() { setReadBuffer(rBuf_.get(), 0); setWriteBuffer(wBuf_.get(), wBufSize_); // Write size never changes. } std::shared_ptr transport_; uint32_t rBufSize_; uint32_t wBufSize_; std::unique_ptr rBuf_; std::unique_ptr wBuf_; }; /** * Wraps a transport into a buffered one. * */ class TBufferedTransportFactory : public TTransportFactory { public: TBufferedTransportFactory() = default; ~TBufferedTransportFactory() override = default; /** * Wraps the transport into a buffered one. */ std::shared_ptr getTransport(std::shared_ptr trans) override { return std::shared_ptr(new TBufferedTransport(trans)); } }; /** * Framed transport. All writes go into an in-memory buffer until flush is * called, at which point the transport writes the length of the entire * binary chunk followed by the data payload. This allows the receiver on the * other end to always do fixed-length reads. * */ class TFramedTransport : public TVirtualTransport { public: static const int DEFAULT_BUFFER_SIZE = 512; static const int DEFAULT_MAX_FRAME_SIZE = 256 * 1024 * 1024; /// Use default buffer sizes. TFramedTransport(std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(), rBufSize_(0), wBufSize_(DEFAULT_BUFFER_SIZE), rBuf_(), wBuf_(new uint8_t[wBufSize_]), bufReclaimThresh_((std::numeric_limits::max)()) { initPointers(); } TFramedTransport(std::shared_ptr transport, std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(transport), rBufSize_(0), wBufSize_(DEFAULT_BUFFER_SIZE), rBuf_(), wBuf_(new uint8_t[wBufSize_]), bufReclaimThresh_((std::numeric_limits::max)()), maxFrameSize_(configuration_->getMaxFrameSize()) { initPointers(); } TFramedTransport(std::shared_ptr transport, uint32_t sz, uint32_t bufReclaimThresh = (std::numeric_limits::max)(), std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(transport), rBufSize_(0), wBufSize_(sz), rBuf_(), wBuf_(new uint8_t[wBufSize_]), bufReclaimThresh_(bufReclaimThresh), maxFrameSize_(configuration_->getMaxFrameSize()) { initPointers(); } void open() override { transport_->open(); } bool isOpen() const override { return transport_->isOpen(); } bool peek() override { return (rBase_ < rBound_) || transport_->peek(); } void close() override { flush(); transport_->close(); } uint32_t readSlow(uint8_t* buf, uint32_t len) override; void writeSlow(const uint8_t* buf, uint32_t len) override; void flush() override; uint32_t readEnd() override; uint32_t writeEnd() override; const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) override; std::shared_ptr getUnderlyingTransport() { return transport_; } /* * TVirtualTransport provides a default implementation of readAll(). * We want to use the TBufferBase version instead. */ using TBufferBase::readAll; /** * Returns the origin of the underlying transport */ const std::string getOrigin() const override { return transport_->getOrigin(); } /** * Set the maximum size of the frame at read */ void setMaxFrameSize(uint32_t maxFrameSize) { maxFrameSize_ = maxFrameSize; } /** * Get the maximum size of the frame at read */ uint32_t getMaxFrameSize() { return maxFrameSize_; } protected: /** * Reads a frame of input from the underlying stream. * * Returns true if a frame was read successfully, or false on EOF. * (Raises a TTransportException if EOF occurs after a partial frame.) */ virtual bool readFrame(); void initPointers() { setReadBuffer(nullptr, 0); setWriteBuffer(wBuf_.get(), wBufSize_); // Pad the buffer so we can insert the size later. int32_t pad = 0; this->write(reinterpret_cast(&pad), sizeof(pad)); } std::shared_ptr transport_; uint32_t rBufSize_; uint32_t wBufSize_; std::unique_ptr rBuf_; std::unique_ptr wBuf_; uint32_t bufReclaimThresh_; uint32_t maxFrameSize_; }; /** * Wraps a transport into a framed one. * */ class TFramedTransportFactory : public TTransportFactory { public: TFramedTransportFactory() = default; ~TFramedTransportFactory() override = default; /** * Wraps the transport into a framed one. */ std::shared_ptr getTransport(std::shared_ptr trans) override { return std::shared_ptr(new TFramedTransport(trans)); } }; /** * A memory buffer is a tranpsort that simply reads from and writes to an * in memory buffer. Anytime you call write on it, the data is simply placed * into a buffer, and anytime you call read, data is read from that buffer. * * The buffers are allocated using C constructs malloc,realloc, and the size * doubles as necessary. We've considered using scoped * */ class TMemoryBuffer : public TVirtualTransport { private: // Common initialization done by all constructors. void initCommon(uint8_t* buf, uint32_t size, bool owner, uint32_t wPos) { maxBufferSize_ = (std::numeric_limits::max)(); if (buf == nullptr && size != 0) { assert(owner); buf = static_cast(std::malloc(size)); if (buf == nullptr) { throw std::bad_alloc(); } } buffer_ = buf; bufferSize_ = size; rBase_ = buffer_; rBound_ = buffer_ + wPos; // TODO(dreiss): Investigate NULL-ing this if !owner. wBase_ = buffer_ + wPos; wBound_ = buffer_ + bufferSize_; owner_ = owner; // rBound_ is really an artifact. In principle, it should always be // equal to wBase_. We update it in a few places (computeRead, etc.). } public: static const uint32_t defaultSize = 1024; /** * This enum specifies how a TMemoryBuffer should treat * memory passed to it via constructors or resetBuffer. * * OBSERVE: * TMemoryBuffer will simply store a pointer to the memory. * It is the callers responsibility to ensure that the pointer * remains valid for the lifetime of the TMemoryBuffer, * and that it is properly cleaned up. * Note that no data can be written to observed buffers. * * COPY: * TMemoryBuffer will make an internal copy of the buffer. * The caller has no responsibilities. * * TAKE_OWNERSHIP: * TMemoryBuffer will become the "owner" of the buffer, * and will be responsible for freeing it. * The memory must have been allocated with malloc. */ enum MemoryPolicy { OBSERVE = 1, COPY = 2, TAKE_OWNERSHIP = 3 }; /** * Construct a TMemoryBuffer with a default-sized buffer, * owned by the TMemoryBuffer object. */ TMemoryBuffer(std::shared_ptr config = nullptr) : TVirtualTransport(config) { initCommon(nullptr, defaultSize, true, 0); } /** * Construct a TMemoryBuffer with a buffer of a specified size, * owned by the TMemoryBuffer object. * * @param sz The initial size of the buffer. */ TMemoryBuffer(uint32_t sz, std::shared_ptr config = nullptr) : TVirtualTransport(config) { initCommon(nullptr, sz, true, 0); } /** * Construct a TMemoryBuffer with buf as its initial contents. * * @param buf The initial contents of the buffer. * Note that, while buf is a non-const pointer, * TMemoryBuffer will not write to it if policy == OBSERVE, * so it is safe to const_cast(whatever). * @param sz The size of @c buf. * @param policy See @link MemoryPolicy @endlink . */ TMemoryBuffer(uint8_t* buf, uint32_t sz, MemoryPolicy policy = OBSERVE, std::shared_ptr config = nullptr) : TVirtualTransport(config) { if (buf == nullptr && sz != 0) { throw TTransportException(TTransportException::BAD_ARGS, "TMemoryBuffer given null buffer with non-zero size."); } switch (policy) { case OBSERVE: case TAKE_OWNERSHIP: initCommon(buf, sz, policy == TAKE_OWNERSHIP, sz); break; case COPY: initCommon(nullptr, sz, true, 0); this->write(buf, sz); break; default: throw TTransportException(TTransportException::BAD_ARGS, "Invalid MemoryPolicy for TMemoryBuffer"); } } ~TMemoryBuffer() override { if (owner_) { std::free(buffer_); } } bool isOpen() const override { return true; } bool peek() override { return (rBase_ < wBase_); } void open() override {} void close() override {} // TODO(dreiss): Make bufPtr const. void getBuffer(uint8_t** bufPtr, uint32_t* sz) { *bufPtr = rBase_; *sz = static_cast(wBase_ - rBase_); } std::string getBufferAsString() { if (buffer_ == nullptr) { return ""; } uint8_t* buf; uint32_t sz; getBuffer(&buf, &sz); return {reinterpret_cast(buf), static_cast(sz)}; } void appendBufferToString(std::string& str) { if (buffer_ == nullptr) { return; } uint8_t* buf; uint32_t sz; getBuffer(&buf, &sz); str.append(reinterpret_cast(buf), sz); } void resetBuffer() { rBase_ = buffer_; rBound_ = buffer_; wBase_ = buffer_; // It isn't safe to write into a buffer we don't own. if (!owner_) { wBound_ = wBase_; bufferSize_ = 0; } } /// See constructor documentation. void resetBuffer(uint8_t* buf, uint32_t sz, MemoryPolicy policy = OBSERVE) { // Use a variant of the copy-and-swap trick for assignment operators. // This is sub-optimal in terms of performance for two reasons: // 1/ The constructing and swapping of the (small) values // in the temporary object takes some time, and is not necessary. // 2/ If policy == COPY, we allocate the new buffer before // freeing the old one, precluding the possibility of // reusing that memory. // I doubt that either of these problems could be optimized away, // but the second is probably no a common case, and the first is minor. // I don't expect resetBuffer to be a common operation, so I'm willing to // bite the performance bullet to make the method this simple. // Construct the new buffer. TMemoryBuffer new_buffer(buf, sz, policy); // Move it into ourself. this->swap(new_buffer); // Our old self gets destroyed. } /// See constructor documentation. void resetBuffer(uint32_t sz) { // Construct the new buffer. TMemoryBuffer new_buffer(sz); // Move it into ourself. this->swap(new_buffer); // Our old self gets destroyed. } std::string readAsString(uint32_t len) { std::string str; (void)readAppendToString(str, len); return str; } uint32_t readAppendToString(std::string& str, uint32_t len); // return number of bytes read uint32_t readEnd() override { // This cast should be safe, because buffer_'s size is a uint32_t auto bytes = static_cast(rBase_ - buffer_); if (rBase_ == wBase_) { resetBuffer(); } resetConsumedMessageSize(); return bytes; } // Return number of bytes written uint32_t writeEnd() override { // This cast should be safe, because buffer_'s size is a uint32_t return static_cast(wBase_ - buffer_); } uint32_t available_read() const { // Remember, wBase_ is the real rBound_. return static_cast(wBase_ - rBase_); } uint32_t available_write() const { return static_cast(wBound_ - wBase_); } // Returns a pointer to where the client can write data to append to // the TMemoryBuffer, and ensures the buffer is big enough to accommodate a // write of the provided length. The returned pointer is very convenient for // passing to read(), recv(), or similar. You must call wroteBytes() as soon // as data is written or the buffer will not be aware that data has changed. uint8_t* getWritePtr(uint32_t len) { ensureCanWrite(len); return wBase_; } // Informs the buffer that the client has written 'len' bytes into storage // that had been provided by getWritePtr(). void wroteBytes(uint32_t len); /* * TVirtualTransport provides a default implementation of readAll(). * We want to use the TBufferBase version instead. */ uint32_t readAll(uint8_t* buf, uint32_t len) { return TBufferBase::readAll(buf, len); } //! \brief Get the current buffer size //! \returns the current buffer size uint32_t getBufferSize() const { return bufferSize_; } //! \brief Get the current maximum buffer size //! \returns the current maximum buffer size uint32_t getMaxBufferSize() const { return maxBufferSize_; } //! \brief Change the maximum buffer size //! \param[in] maxSize the new maximum buffer size allowed to grow to //! \throws TTransportException(BAD_ARGS) if maxSize is less than the current buffer size void setMaxBufferSize(uint32_t maxSize) { if (maxSize < bufferSize_) { throw TTransportException(TTransportException::BAD_ARGS, "Maximum buffer size would be less than current buffer size"); } maxBufferSize_ = maxSize; } protected: void swap(TMemoryBuffer& that) { using std::swap; swap(buffer_, that.buffer_); swap(bufferSize_, that.bufferSize_); swap(rBase_, that.rBase_); swap(rBound_, that.rBound_); swap(wBase_, that.wBase_); swap(wBound_, that.wBound_); swap(owner_, that.owner_); } // Make sure there's at least 'len' bytes available for writing. void ensureCanWrite(uint32_t len); // Compute the position and available data for reading. void computeRead(uint32_t len, uint8_t** out_start, uint32_t* out_give); uint32_t readSlow(uint8_t* buf, uint32_t len) override; void writeSlow(const uint8_t* buf, uint32_t len) override; const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) override; // Data buffer uint8_t* buffer_; // Allocated buffer size uint32_t bufferSize_; // Maximum allowed size uint32_t maxBufferSize_; // Is this object the owner of the buffer? bool owner_; // Don't forget to update constrctors, initCommon, and swap if // you add new members. }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TBUFFERTRANSPORTS_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TFDTransport.h0000664000175000017500000000422015167543515023546 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TFDTRANSPORT_H_ #define _THRIFT_TRANSPORT_TFDTRANSPORT_H_ 1 #include #ifdef HAVE_SYS_TIME_H #include #endif #include #include namespace apache { namespace thrift { namespace transport { /** * Dead-simple wrapper around a file descriptor. * */ class TFDTransport : public TVirtualTransport { public: enum ClosePolicy { NO_CLOSE_ON_DESTROY = 0, CLOSE_ON_DESTROY = 1 }; TFDTransport(int fd, ClosePolicy close_policy = NO_CLOSE_ON_DESTROY, std::shared_ptr config = nullptr) : TVirtualTransport(config), fd_(fd), close_policy_(close_policy) { } ~TFDTransport() override { if (close_policy_ == CLOSE_ON_DESTROY) { try { close(); } catch (TTransportException& ex) { TOutput::instance().printf("~TFDTransport TTransportException: '%s'", ex.what()); } } } bool isOpen() const override { return fd_ >= 0; } void open() override {} void close() override; uint32_t read(uint8_t* buf, uint32_t len); void write(const uint8_t* buf, uint32_t len); void setFD(int fd) { fd_ = fd; } int getFD() { return fd_; } protected: int fd_; ClosePolicy close_policy_; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TFDTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TVirtualTransport.h0000664000175000017500000001214015165535636024706 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TVIRTUALTRANSPORT_H_ #define _THRIFT_TRANSPORT_TVIRTUALTRANSPORT_H_ 1 #include namespace apache { namespace thrift { namespace transport { /** * Helper class that provides default implementations of TTransport methods. * * This class provides default implementations of read(), readAll(), write(), * borrow() and consume(). * * In the TTransport base class, each of these methods simply invokes its * virtual counterpart. This class overrides them to always perform the * default behavior, without a virtual function call. * * The primary purpose of this class is to serve as a base class for * TVirtualTransport, and prevent infinite recursion if one of its subclasses * does not override the TTransport implementation of these methods. (Since * TVirtualTransport::read_virt() calls read(), and TTransport::read() calls * read_virt().) */ class TTransportDefaults : public TTransport { public: /* * TTransport *_virt() methods provide reasonable default implementations. * Invoke them non-virtually. */ uint32_t read(uint8_t* buf, uint32_t len) { return this->TTransport::read_virt(buf, len); } uint32_t readAll(uint8_t* buf, uint32_t len) { return this->TTransport::readAll_virt(buf, len); } void write(const uint8_t* buf, uint32_t len) { this->TTransport::write_virt(buf, len); } const uint8_t* borrow(uint8_t* buf, uint32_t* len) { return this->TTransport::borrow_virt(buf, len); } void consume(uint32_t len) { this->TTransport::consume_virt(len); } protected: TTransportDefaults(std::shared_ptr config = nullptr) : TTransport(config) {} }; /** * Helper class to provide polymorphism for subclasses of TTransport. * * This class implements *_virt() methods of TTransport, to call the * non-virtual versions of these functions in the proper subclass. * * To define your own transport class using TVirtualTransport: * 1) Derive your subclass from TVirtualTransport * e.g: class MyTransport : public TVirtualTransport { * 2) Provide your own implementations of read(), readAll(), etc. * These methods should be non-virtual. * * Transport implementations that need to use virtual inheritance when * inheriting from TTransport cannot use TVirtualTransport. * * @author Chad Walters */ template class TVirtualTransport : public Super_ { public: /* * Implementations of the *_virt() functions, to call the subclass's * non-virtual implementation function. */ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return static_cast(this)->read(buf, len); } uint32_t readAll_virt(uint8_t* buf, uint32_t len) override { return static_cast(this)->readAll(buf, len); } void write_virt(const uint8_t* buf, uint32_t len) override { static_cast(this)->write(buf, len); } const uint8_t* borrow_virt(uint8_t* buf, uint32_t* len) override { return static_cast(this)->borrow(buf, len); } void consume_virt(uint32_t len) override { static_cast(this)->consume(len); } /* * Provide a default readAll() implementation that invokes * read() non-virtually. * * Note: subclasses that use TVirtualTransport to derive from another * transport implementation (i.e., not TTransportDefaults) should beware that * this may override any non-default readAll() implementation provided by * the parent transport class. They may need to redefine readAll() to call * the correct parent implementation, if desired. */ uint32_t readAll(uint8_t* buf, uint32_t len) { auto* trans = static_cast(this); return ::apache::thrift::transport::readAll(*trans, buf, len); } protected: TVirtualTransport() : Super_() {} /* * Templatized constructors, to allow arguments to be passed to the Super_ * constructor. Currently we only support 0, 1, or 2 arguments, but * additional versions can be added as needed. */ template TVirtualTransport(Arg_ const& arg) : Super_(arg) {} template TVirtualTransport(Arg1_ const& a1, Arg2_ const& a2) : Super_(a1, a2) {} }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TVIRTUALTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/PlatformSocket.h0000664000175000017500000001050615165535636024160 0ustar00buildbuild00000000000000/* * 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. */ // clang-format off #ifndef _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ # define _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ #ifdef _WIN32 # include # define THRIFT_GET_SOCKET_ERROR ::WSAGetLastError() # define THRIFT_ERRNO (*_errno()) # define THRIFT_EINPROGRESS WSAEINPROGRESS # define THRIFT_EAGAIN WSAEWOULDBLOCK # define THRIFT_EINTR WSAEINTR # define THRIFT_ECONNRESET WSAECONNRESET # define THRIFT_ENOTCONN WSAENOTCONN # define THRIFT_ETIMEDOUT WSAETIMEDOUT # define THRIFT_EWOULDBLOCK WSAEWOULDBLOCK # define THRIFT_EPIPE WSAECONNRESET # define THRIFT_NO_SOCKET_CACHING SO_EXCLUSIVEADDRUSE # define THRIFT_SOCKET SOCKET # define THRIFT_INVALID_SOCKET INVALID_SOCKET # define THRIFT_SOCKETPAIR thrift_socketpair # define THRIFT_FCNTL thrift_fcntl # define THRIFT_O_NONBLOCK 1 # define THRIFT_F_GETFL 0 # define THRIFT_F_SETFL 1 # define THRIFT_GETTIMEOFDAY thrift_gettimeofday # define THRIFT_CLOSESOCKET closesocket # define THRIFT_CLOSE _close # define THRIFT_OPEN _open # define THRIFT_FTRUNCATE _chsize_s # define THRIFT_FSYNC _commit # define THRIFT_LSEEK _lseek # define THRIFT_WRITE _write # define THRIFT_READ _read # define THRIFT_IOCTL_SOCKET ioctlsocket # define THRIFT_IOCTL_SOCKET_NUM_BYTES_TYPE u_long # define THRIFT_FSTAT _fstat # define THRIFT_STAT _stat # ifdef _WIN32_WCE # define THRIFT_GAI_STRERROR(...) thrift_wstr2str(gai_strerrorW(__VA_ARGS__)) # else # define THRIFT_GAI_STRERROR gai_strerrorA # endif # define THRIFT_SSIZET ptrdiff_t # if (_MSC_VER < 1900) # define THRIFT_SNPRINTF _snprintf # else # define THRIFT_SNPRINTF snprintf # endif # define THRIFT_SLEEP_SEC thrift_sleep # define THRIFT_SLEEP_USEC thrift_usleep # define THRIFT_TIMESPEC thrift_timespec # define THRIFT_CTIME_R thrift_ctime_r # define THRIFT_POLL WSAPoll # define THRIFT_POLLFD pollfd # define THRIFT_POLLIN POLLIN # define THRIFT_POLLOUT POLLOUT # define THRIFT_SHUT_RDWR SD_BOTH # if !defined(AI_ADDRCONFIG) # define AI_ADDRCONFIG 0x00000400 # endif #else //not _WIN32 # include # define THRIFT_GET_SOCKET_ERROR errno # define THRIFT_ERRNO errno # define THRIFT_EINTR EINTR # define THRIFT_EINPROGRESS EINPROGRESS # define THRIFT_ECONNRESET ECONNRESET # define THRIFT_ENOTCONN ENOTCONN # define THRIFT_ETIMEDOUT ETIMEDOUT # define THRIFT_EWOULDBLOCK EWOULDBLOCK # define THRIFT_EAGAIN EAGAIN # define THRIFT_EPIPE EPIPE # define THRIFT_NO_SOCKET_CACHING SO_REUSEADDR # define THRIFT_SOCKET int # define THRIFT_INVALID_SOCKET (-1) # define THRIFT_SOCKETPAIR socketpair # define THRIFT_FCNTL fcntl # define THRIFT_O_NONBLOCK O_NONBLOCK # define THRIFT_F_GETFL F_GETFL # define THRIFT_F_SETFL F_SETFL # define THRIFT_GETTIMEOFDAY gettimeofday # define THRIFT_CLOSESOCKET close # define THRIFT_CLOSE close # define THRIFT_OPEN open # define THRIFT_FTRUNCATE ftruncate # define THRIFT_FSYNC fsync # define THRIFT_LSEEK lseek # define THRIFT_WRITE write # define THRIFT_READ read # define THRIFT_IOCTL_SOCKET ioctl # define THRIFT_IOCTL_SOCKET_NUM_BYTES_TYPE int # define THRIFT_STAT stat # define THRIFT_FSTAT fstat # define THRIFT_GAI_STRERROR gai_strerror # define THRIFT_SSIZET ssize_t # define THRIFT_SNPRINTF snprintf # define THRIFT_SLEEP_SEC sleep # define THRIFT_SLEEP_USEC usleep # define THRIFT_TIMESPEC timespec # define THRIFT_CTIME_R ctime_r # define THRIFT_POLL poll # define THRIFT_POLLFD pollfd # define THRIFT_POLLIN POLLIN # define THRIFT_POLLOUT POLLOUT # define THRIFT_SHUT_RDWR SHUT_RDWR #endif #endif // _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TSSLSocket.h0000664000175000017500000003420715167543515023162 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSSLSOCKET_H_ #define _THRIFT_TRANSPORT_TSSLSOCKET_H_ 1 // Put this first to avoid WIN32 build failure #include #include #include #include namespace apache { namespace thrift { namespace transport { class AccessManager; class SSLContext; enum SSLProtocol { SSLTLS = 0, // Supports SSLv2 and SSLv3 handshake but only negotiates at TLSv1_0 or later. //SSLv2 = 1, // HORRIBLY INSECURE! SSLv3 = 2, // Supports SSLv3 only - also horribly insecure! TLSv1_0 = 3, // Supports TLSv1_0 or later. TLSv1_1 = 4, // Supports TLSv1_1 or later. TLSv1_2 = 5, // Supports TLSv1_2 or later. LATEST = TLSv1_2 }; #define TSSL_EINTR 0 #define TSSL_DATA 1 /** * Initialize OpenSSL library. This function, or some other * equivalent function to initialize OpenSSL, must be called before * TSSLSocket is used. If you set TSSLSocketFactory to use manual * OpenSSL initialization, you should call this function or otherwise * ensure OpenSSL is initialized yourself. */ void initializeOpenSSL(); /** * Cleanup OpenSSL library. This function should be called to clean * up OpenSSL after use of OpenSSL functionality is finished. If you * set TSSLSocketFactory to use manual OpenSSL initialization, you * should call this function yourself or ensure that whatever * initialized OpenSSL cleans it up too. */ void cleanupOpenSSL(); /** * OpenSSL implementation for SSL socket interface. */ class TSSLSocket : public TSocket { public: ~TSSLSocket() override; /** * TTransport interface. */ bool isOpen() const override; bool peek() override; void open() override; void close() override; bool hasPendingDataToRead() override; uint32_t read(uint8_t* buf, uint32_t len) override; void write(const uint8_t* buf, uint32_t len) override; uint32_t write_partial(const uint8_t* buf, uint32_t len) override; void flush() override; /** * Set whether to use client or server side SSL handshake protocol. * * @param flag Use server side handshake protocol if true. */ void server(bool flag) { server_ = flag; } /** * Determine whether the SSL socket is server or client mode. */ bool server() const { return server_; } /** * Set AccessManager. * * @param manager Instance of AccessManager */ virtual void access(std::shared_ptr manager) { access_ = manager; } /** * Set eventSafe flag if libevent is used. */ void setLibeventSafe() { eventSafe_ = true; } /** * Determines whether SSL Socket is libevent safe or not. */ bool isLibeventSafe() const { return eventSafe_; } protected: /** * Constructor. */ TSSLSocket(std::shared_ptr ctx, std::shared_ptr config = nullptr); /** * Constructor with an interrupt signal. */ TSSLSocket(std::shared_ptr ctx, std::shared_ptr interruptListener, std::shared_ptr config = nullptr); /** * Constructor, create an instance of TSSLSocket given an existing socket. * * @param socket An existing socket */ TSSLSocket(std::shared_ptr ctx, THRIFT_SOCKET socket, std::shared_ptr config = nullptr); /** * Constructor, create an instance of TSSLSocket given an existing socket that can be interrupted. * * @param socket An existing socket */ TSSLSocket(std::shared_ptr ctx, THRIFT_SOCKET socket, std::shared_ptr interruptListener, std::shared_ptr config = nullptr); /** * Constructor. * * @param host Remote host name * @param port Remote port number */ TSSLSocket(std::shared_ptr ctx, std::string host, int port, std::shared_ptr config = nullptr); /** * Constructor with an interrupt signal. * * @param host Remote host name * @param port Remote port number */ TSSLSocket(std::shared_ptr ctx, std::string host, int port, std::shared_ptr interruptListener, std::shared_ptr config = nullptr); /** * Authorize peer access after SSL handshake completes. */ virtual void authorize(); /** * Initiate SSL handshake if not already initiated. */ void initializeHandshake(); /** * Initiate SSL handshake params. */ void initializeHandshakeParams(); /** * Check if SSL handshake is completed or not. */ bool checkHandshake(); /** * Waits for an socket or shutdown event. * * @throw TTransportException::INTERRUPTED if interrupted is signaled. * * @return TSSL_EINTR if EINTR happened on the underlying socket * TSSL_DATA if data is available on the socket. */ unsigned int waitForEvent(bool wantRead); bool server_; SSL* ssl_; std::shared_ptr ctx_; std::shared_ptr access_; friend class TSSLSocketFactory; private: bool handshakeCompleted_; int readRetryCount_; bool eventSafe_; void init(); }; /** * SSL socket factory. SSL sockets should be created via SSL factory. * The factory will automatically initialize and cleanup openssl as long as * there is a TSSLSocketFactory instantiated, and as long as the static * boolean manualOpenSSLInitialization_ is set to false, the default. * * If you would like to initialize and cleanup openssl yourself, set * manualOpenSSLInitialization_ to true and TSSLSocketFactory will no * longer be responsible for openssl initialization and teardown. * * It is the responsibility of the code using TSSLSocketFactory to * ensure that the factory lifetime exceeds the lifetime of any sockets * it might create. If this is not guaranteed, a socket may call into * openssl after the socket factory has cleaned up openssl! This * guarantee is unnecessary if manualOpenSSLInitialization_ is true, * however, since it would be up to the consuming application instead. */ class TSSLSocketFactory { public: /** * Constructor/Destructor * * @param protocol The SSL/TLS protocol to use. */ TSSLSocketFactory(SSLProtocol protocol = SSLTLS); virtual ~TSSLSocketFactory(); /** * Create an instance of TSSLSocket with a fresh new socket. */ virtual std::shared_ptr createSocket(); /** * Create an instance of TSSLSocket with a fresh new socket, which is interruptable. */ virtual std::shared_ptr createSocket(std::shared_ptr interruptListener); /** * Create an instance of TSSLSocket with the given socket. * * @param socket An existing socket. */ virtual std::shared_ptr createSocket(THRIFT_SOCKET socket); /** * Create an instance of TSSLSocket with the given socket which is interruptable. * * @param socket An existing socket. */ virtual std::shared_ptr createSocket(THRIFT_SOCKET socket, std::shared_ptr interruptListener); /** * Create an instance of TSSLSocket. * * @param host Remote host to be connected to * @param port Remote port to be connected to */ virtual std::shared_ptr createSocket(const std::string& host, int port); /** * Create an instance of TSSLSocket. * * @param host Remote host to be connected to * @param port Remote port to be connected to */ virtual std::shared_ptr createSocket(const std::string& host, int port, std::shared_ptr interruptListener); /** * Set ciphers to be used in SSL handshake process. * * @param ciphers A list of ciphers */ virtual void ciphers(const std::string& enable); /** * Enable/Disable authentication. * * @param required Require peer to present valid certificate if true */ virtual void authenticate(bool required); /** * Load server certificate. * * @param path Path to the certificate file * @param format Certificate file format */ virtual void loadCertificate(const char* path, const char* format = "PEM"); virtual void loadCertificateFromBuffer(const char* aCertificate, const char* format = "PEM"); /** * Load private key. * * @param path Path to the private key file * @param format Private key file format */ virtual void loadPrivateKey(const char* path, const char* format = "PEM"); virtual void loadPrivateKeyFromBuffer(const char* aPrivateKey, const char* format = "PEM"); /** * Load trusted certificates from specified file. * * @param path Path to trusted certificate file */ virtual void loadTrustedCertificates(const char* path, const char* capath = nullptr); virtual void loadTrustedCertificatesFromBuffer(const char* aCertificate, const char* aChain = nullptr); /** * Default randomize method. */ virtual void randomize(); /** * Override default OpenSSL password callback with getPassword(). */ void overrideDefaultPasswordCallback(); /** * Set/Unset server mode. * * @param flag Server mode if true */ virtual void server(bool flag) { server_ = flag; } /** * Determine whether the socket is in server or client mode. * * @return true, if server mode, or, false, if client mode */ virtual bool server() const { return server_; } /** * Set AccessManager. * * @param manager The AccessManager instance */ virtual void access(std::shared_ptr manager) { access_ = manager; } static void setManualOpenSSLInitialization(bool manualOpenSSLInitialization); protected: std::shared_ptr ctx_; /** * Override this method for custom password callback. It may be called * multiple times at any time during a session as necessary. * * @param password Pass collected password to OpenSSL * @param size Maximum length of password including NULL character */ virtual void getPassword(std::string& /* password */, int /* size */) {} private: bool server_; std::shared_ptr access_; static concurrency::Mutex mutex_; static uint64_t count_; static bool manualOpenSSLInitialization_; 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); }; /** * SSL exception. */ class TSSLException : public TTransportException { public: TSSLException(const std::string& message) : TTransportException(TTransportException::INTERNAL_ERROR, message) {} const char* what() const noexcept override { if (message_.empty()) { return "TSSLException"; } else { return message_.c_str(); } } }; /** * Wrap OpenSSL SSL_CTX into a class. */ class SSLContext { public: SSLContext(const SSLProtocol& protocol = SSLTLS); virtual ~SSLContext(); SSL* createSSL(); SSL_CTX* get() { return ctx_; } private: SSL_CTX* ctx_; }; /** * Callback interface for access control. It's meant to verify the remote host. * It's constructed when application starts and set to TSSLSocketFactory * instance. It's passed onto all TSSLSocket instances created by this factory * object. */ class AccessManager { public: enum Decision { DENY = -1, // deny access SKIP = 0, // cannot make decision, move on to next (if any) ALLOW = 1 // allow access }; /** * Destructor */ virtual ~AccessManager() = default; /** * Determine whether the peer should be granted access or not. It's called * once after the SSL handshake completes successfully, before peer certificate * is examined. * * If a valid decision (ALLOW or DENY) is returned, the peer certificate is * not to be verified. * * @param sa Peer IP address * @return True if the peer is trusted, false otherwise */ virtual Decision verify(const sockaddr_storage& /* sa */) noexcept { return DENY; } /** * Determine whether the peer should be granted access or not. It's called * every time a DNS subjectAltName/common name is extracted from peer's * certificate. * * @param host Client mode: host name returned by TSocket::getHost() * Server mode: host name returned by TSocket::getPeerHost() * @param name SubjectAltName or common name extracted from peer certificate * @param size Length of name * @return True if the peer is trusted, false otherwise * * Note: The "name" parameter may be UTF8 encoded. */ virtual Decision verify(const std::string& /* host */, const char* /* name */, int /* size */) noexcept { return DENY; } /** * Determine whether the peer should be granted access or not. It's called * every time an IP subjectAltName is extracted from peer's certificate. * * @param sa Peer IP address retrieved from the underlying socket * @param data IP address extracted from certificate * @param size Length of the IP address * @return True if the peer is trusted, false otherwise */ virtual Decision verify(const sockaddr_storage& /* sa */, const char* /* data */, int /* size */) noexcept { return DENY; } }; typedef AccessManager::Decision Decision; class DefaultClientAccessManager : public AccessManager { public: // AccessManager interface Decision verify(const sockaddr_storage& sa) noexcept override; Decision verify(const std::string& host, const char* name, int size) noexcept override; Decision verify(const sockaddr_storage& sa, const char* data, int size) noexcept override; }; } } } #endif thrift-0.23.0/lib/cpp/src/thrift/transport/TSocketPool.cpp0000664000175000017500000001553715167543515023772 0ustar00buildbuild00000000000000/* * 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 #if __cplusplus >= 201703L #include #endif #include using std::pair; using std::string; using std::vector; namespace apache { namespace thrift { namespace transport { using std::shared_ptr; /** * TSocketPoolServer implementation * */ TSocketPoolServer::TSocketPoolServer() : host_(""), port_(0), socket_(THRIFT_INVALID_SOCKET), lastFailTime_(0), consecutiveFailures_(0) { } /** * Constructor for TSocketPool server */ TSocketPoolServer::TSocketPoolServer(const string& host, int port) : host_(host), port_(port), socket_(THRIFT_INVALID_SOCKET), lastFailTime_(0), consecutiveFailures_(0) { } /** * TSocketPool implementation. * */ TSocketPool::TSocketPool() : TSocket(), numRetries_(1), retryInterval_(60), maxConsecutiveFailures_(1), randomize_(true), alwaysTryLast_(true) { } TSocketPool::TSocketPool(const vector& hosts, const vector& ports) : TSocket(), numRetries_(1), retryInterval_(60), maxConsecutiveFailures_(1), randomize_(true), alwaysTryLast_(true) { if (hosts.size() != ports.size()) { TOutput::instance()("TSocketPool::TSocketPool: hosts.size != ports.size"); throw TTransportException(TTransportException::BAD_ARGS); } for (unsigned int i = 0; i < hosts.size(); ++i) { addServer(hosts[i], ports[i]); } } TSocketPool::TSocketPool(const vector >& servers) : TSocket(), numRetries_(1), retryInterval_(60), maxConsecutiveFailures_(1), randomize_(true), alwaysTryLast_(true) { for (const auto & server : servers) { addServer(server.first, server.second); } } TSocketPool::TSocketPool(const vector >& servers) : TSocket(), servers_(servers), numRetries_(1), retryInterval_(60), maxConsecutiveFailures_(1), randomize_(true), alwaysTryLast_(true) { } TSocketPool::TSocketPool(const string& host, int port) : TSocket(), numRetries_(1), retryInterval_(60), maxConsecutiveFailures_(1), randomize_(true), alwaysTryLast_(true) { addServer(host, port); } TSocketPool::~TSocketPool() { vector >::const_iterator iter = servers_.begin(); vector >::const_iterator iterEnd = servers_.end(); for (; iter != iterEnd; ++iter) { setCurrentServer(*iter); TSocketPool::close(); } } void TSocketPool::addServer(const string& host, int port) { servers_.push_back(std::make_shared(host, port)); } void TSocketPool::addServer(shared_ptr& server) { if (server) { servers_.push_back(server); } } void TSocketPool::setServers(const vector >& servers) { servers_ = servers; } void TSocketPool::getServers(vector >& servers) { servers = servers_; } void TSocketPool::setNumRetries(int numRetries) { numRetries_ = numRetries; } void TSocketPool::setRetryInterval(int retryInterval) { retryInterval_ = retryInterval; } void TSocketPool::setMaxConsecutiveFailures(int maxConsecutiveFailures) { maxConsecutiveFailures_ = maxConsecutiveFailures; } void TSocketPool::setRandomize(bool randomize) { randomize_ = randomize; } void TSocketPool::setAlwaysTryLast(bool alwaysTryLast) { alwaysTryLast_ = alwaysTryLast; } void TSocketPool::setCurrentServer(const shared_ptr& server) { currentServer_ = server; host_ = server->host_; port_ = server->port_; socket_ = server->socket_; } /** * This function throws an exception if socket open fails. When socket * opens fails, the socket in the current server is reset. */ /* TODO: without apcu we ignore a lot of functionality from the php version */ void TSocketPool::open() { size_t numServers = servers_.size(); if (numServers == 0) { socket_ = THRIFT_INVALID_SOCKET; throw TTransportException(TTransportException::NOT_OPEN); } if (isOpen()) { return; } if (randomize_ && numServers > 1) { #if __cplusplus >= 201703L std::random_device rng; std::mt19937 urng(rng()); std::shuffle(servers_.begin(), servers_.end(), urng); #else std::random_shuffle(servers_.begin(), servers_.end()); #endif } for (size_t i = 0; i < numServers; ++i) { shared_ptr& server = servers_[i]; // Impersonate the server socket setCurrentServer(server); if (isOpen()) { // already open means we're done return; } bool retryIntervalPassed = (server->lastFailTime_ == 0); bool isLastServer = alwaysTryLast_ ? (i == (numServers - 1)) : false; if (server->lastFailTime_ > 0) { // The server was marked as down, so check if enough time has elapsed to retry time_t elapsedTime = time(nullptr) - server->lastFailTime_; if (elapsedTime > retryInterval_) { retryIntervalPassed = true; } } if (retryIntervalPassed || isLastServer) { for (int j = 0; j < numRetries_; ++j) { try { TSocket::open(); } catch (const TException &e) { string errStr = "TSocketPool::open failed " + getSocketInfo() + ": " + e.what(); TOutput::instance()(errStr.c_str()); socket_ = THRIFT_INVALID_SOCKET; continue; } // Copy over the opened socket so that we can keep it persistent server->socket_ = socket_; // reset lastFailTime_ is required server->lastFailTime_ = 0; // success return; } ++server->consecutiveFailures_; if (server->consecutiveFailures_ > maxConsecutiveFailures_) { // Mark server as down server->consecutiveFailures_ = 0; server->lastFailTime_ = time(nullptr); } } } TOutput::instance()("TSocketPool::open: all connections failed"); throw TTransportException(TTransportException::NOT_OPEN); } void TSocketPool::close() { TSocket::close(); if (currentServer_) { currentServer_->socket_ = THRIFT_INVALID_SOCKET; } } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TWebSocketServer.h0000664000175000017500000003034015165535636024422 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TWEBSOCKETSERVER_H_ #define _THRIFT_TRANSPORT_TWEBSOCKETSERVER_H_ 1 #include #include #include #include #include #include #include #include #if defined(_MSC_VER) || defined(__MINGW32__) #include #define THRIFT_strncasecmp(str1, str2, len) _strnicmp(str1, str2, len) #define THRIFT_strcasestr(haystack, needle) StrStrIA(haystack, needle) #else #define THRIFT_strncasecmp(str1, str2, len) strncasecmp(str1, str2, len) #define THRIFT_strcasestr(haystack, needle) strcasestr(haystack, needle) #endif #if defined(__CYGWIN__) #include #endif using std::string; namespace apache { namespace thrift { namespace transport { std::string base64Encode(unsigned char* data, int length); template class TWebSocketServer : public THttpServer { public: TWebSocketServer(std::shared_ptr transport, std::shared_ptr config = nullptr) : THttpServer(transport, config) { resetHandshake(); } ~TWebSocketServer() override = default; uint32_t readAll_virt(uint8_t* buf, uint32_t len) override { // If we do not have a good handshake, the client will attempt one. if (!handshakeComplete()) { resetHandshake(); THttpServer::read(buf, len); // If we did not get everything we expected, the handshake failed // and we need to send a 400 response back. if (!handshakeComplete()) { sendBadRequest(); return 0; } // Otherwise, send back the 101 response. THttpServer::flush(); } uint32_t want = len; auto have = readBuffer_.available_read(); // If we have some data in the buffer, copy it out and return it. // We have to return it without attempting to read more, since we aren't // guaranteed that the underlying transport actually has more data, so // attempting to read from it could block. if (have > 0 && have >= want) { return readBuffer_.read(buf, want); } // Read another frame. if (!readFrame()) { // EOF. No frame available. return 0; } // Hand over whatever we have. uint32_t give = (std::min)(want, readBuffer_.available_read()); return readBuffer_.read(buf, give); } void flush() override { resetConsumedMessageSize(); writeFrameHeader(); uint8_t* buffer; uint32_t length; writeBuffer_.getBuffer(&buffer, &length); transport_->write(buffer, length); transport_->flush(); writeBuffer_.resetBuffer(); } protected: std::string getHeader(uint32_t len) override { THRIFT_UNUSED_VARIABLE(len); std::ostringstream h; h << "HTTP/1.1 101 Switching Protocols" << CRLF << "Server: Thrift/" << PACKAGE_VERSION << CRLF << "Upgrade: websocket" << CRLF << "Connection: Upgrade" << CRLF << "Sec-WebSocket-Accept: " << acceptKey_ << CRLF << CRLF; return h.str(); } void parseHeader(char* header) override { char* colon = strchr(header, ':'); if (colon == nullptr) { return; } size_t sz = colon - header; char* value = colon + 1; if (THRIFT_strncasecmp(header, "Upgrade", sz) == 0) { if (THRIFT_strcasestr(value, "websocket") != nullptr) { upgrade_ = true; } } else if (THRIFT_strncasecmp(header, "Connection", sz) == 0) { if (THRIFT_strcasestr(value, "Upgrade") != nullptr) { connection_ = true; } } else if (THRIFT_strncasecmp(header, "Sec-WebSocket-Key", sz) == 0) { std::string toHash = value + 1; toHash += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; unsigned char hash[20]; SHA1((const unsigned char*)toHash.c_str(), toHash.length(), hash); acceptKey_ = base64Encode(hash, 20); secWebSocketKey_ = true; } else if (THRIFT_strncasecmp(header, "Sec-WebSocket-Version", sz) == 0) { if (THRIFT_strcasestr(value, "13") != nullptr) { secWebSocketVersion_ = true; } } } bool parseStatusLine(char* status) override { char* method = status; char* path = strchr(method, ' '); if (path == nullptr) { throw TTransportException(string("Bad Status: ") + status); } *path = '\0'; while (*(++path) == ' ') { }; char* http = strchr(path, ' '); if (http == nullptr) { throw TTransportException(string("Bad Status: ") + status); } *http = '\0'; if (strcmp(method, "GET") == 0) { // GET method ok, looking for content. return true; } throw TTransportException(string("Bad Status (unsupported method): ") + status); } private: enum class CloseCode : uint16_t { NormalClosure = 1000, GoingAway = 1001, ProtocolError = 1002, UnsupportedDataType = 1003, NoStatusCode = 1005, AbnormalClosure = 1006, InvalidData = 1007, PolicyViolation = 1008, MessageTooBig = 1009, ExtensionExpected = 1010, UnexpectedError = 1011, NotSecure = 1015 }; enum class Opcode : uint8_t { Continuation = 0x0, Text = 0x1, Binary = 0x2, Close = 0x8, Ping = 0x9, Pong = 0xA }; void failConnection(CloseCode reason) { writeFrameHeader(Opcode::Close); auto buffer = htons(static_cast(reason)); transport_->write(reinterpret_cast(&buffer), 2); transport_->flush(); transport_->close(); } bool handshakeComplete() { return upgrade_ && connection_ && secWebSocketKey_ && secWebSocketVersion_; } void pong() { writeFrameHeader(Opcode::Pong); uint8_t* buffer; uint32_t size; readBuffer_.getBuffer(&buffer, &size); transport_->write(buffer, size); transport_->flush(); } bool readFrame() { uint8_t headerBuffer[8]; auto read = transport_->read(headerBuffer, 2); if (read < 2) { return false; } // Since Thrift has its own message end marker and we read frame by frame, // it doesn't really matter if the frame is marked as FIN. // Capture it only for debugging only. auto fin = (headerBuffer[0] & 0x80) != 0; THRIFT_UNUSED_VARIABLE(fin); // RSV1, RSV2, RSV3 if ((headerBuffer[0] & 0x70) != 0) { failConnection(CloseCode::ProtocolError); throw TTransportException(TTransportException::CORRUPTED_DATA, "Reserved bits must be zeroes"); } auto opcode = (Opcode)(headerBuffer[0] & 0x0F); // Mask if ((headerBuffer[1] & 0x80) == 0) { failConnection(CloseCode::ProtocolError); throw TTransportException(TTransportException::CORRUPTED_DATA, "Messages from the client must be masked"); } // Read the length uint64_t payloadLength = headerBuffer[1] & 0x7F; if (payloadLength == 126) { read = transport_->read(headerBuffer, 2); if (read < 2) { return false; } payloadLength = ntohs(*reinterpret_cast(headerBuffer)); } else if (payloadLength == 127) { read = transport_->read(headerBuffer, 8); if (read < 8) { return false; } payloadLength = THRIFT_ntohll(*reinterpret_cast(headerBuffer)); if ((payloadLength & 0x8000000000000000) != 0) { failConnection(CloseCode::ProtocolError); throw TTransportException( TTransportException::CORRUPTED_DATA, "The most significant bit of the payload length must be zero"); } } // size_t is smaller than a ulong on a 32-bit system if (payloadLength > UINT32_MAX) { failConnection(CloseCode::MessageTooBig); return false; } auto length = static_cast(payloadLength); if (length > 0) { // Read the masking key read = transport_->read(headerBuffer, 4); if (read < 4) { return false; } readBuffer_.resetBuffer(length); uint8_t* buffer = readBuffer_.getWritePtr(length); read = transport_->read(buffer, length); readBuffer_.wroteBytes(read); if (read < length) { return false; } // Unmask the data for (size_t i = 0; i < length; i++) { buffer[i] ^= headerBuffer[i % 4]; } T_DEBUG("FIN=%d, Opcode=%X, length=%d, payload=%s", fin, opcode, length, binary ? readBuffer_.toHexString() : cast(string) readBuffer_); } switch (opcode) { case Opcode::Close: if (length >= 2) { uint8_t buffer[2]; readBuffer_.read(buffer, 2); CloseCode closeCode = static_cast(ntohs(*reinterpret_cast(buffer))); THRIFT_UNUSED_VARIABLE(closeCode); string closeReason = readBuffer_.readAsString(length - 2); T_DEBUG("Connection closed: %d %s", closeCode, closeReason); } transport_->close(); return false; case Opcode::Ping: pong(); return readFrame(); default: return true; } } void resetHandshake() { connection_ = false; secWebSocketKey_ = false; secWebSocketVersion_ = false; upgrade_ = false; } void sendBadRequest() { std::ostringstream h; h << "HTTP/1.1 400 Bad Request" << CRLF << "Server: Thrift/" << PACKAGE_VERSION << CRLF << CRLF; std::string header = h.str(); transport_->write(reinterpret_cast(header.data()), static_cast(header.length())); transport_->flush(); transport_->close(); } void writeFrameHeader(Opcode opcode = Opcode::Continuation) { uint32_t headerSize = 1; uint32_t length = writeBuffer_.available_read(); if (length < 126) { ++headerSize; } else if (length < 65536) { headerSize += 3; } else { headerSize += 9; } // The server does not mask the response uint8_t* header = static_cast(alloca(headerSize)); if (opcode == Opcode::Continuation) { opcode = binary ? Opcode::Binary : Opcode::Text; } header[0] = static_cast(opcode) | 0x80; if (length < 126) { header[1] = static_cast(length); } else if (length < 65536) { header[1] = 126; *reinterpret_cast(header + 2) = htons(length); } else { header[1] = 127; *reinterpret_cast(header + 2) = THRIFT_htonll(length); } transport_->write(header, headerSize); } // Add constant here to avoid a linker error on Windows constexpr static const char* CRLF = "\r\n"; std::string acceptKey_; bool connection_; bool secWebSocketKey_; bool secWebSocketVersion_; bool upgrade_; }; /** * Wraps a transport into binary WebSocket protocol */ class TBinaryWebSocketServerTransportFactory : public TTransportFactory { public: TBinaryWebSocketServerTransportFactory() = default; ~TBinaryWebSocketServerTransportFactory() override = default; /** * Wraps the transport into a buffered one. */ std::shared_ptr getTransport(std::shared_ptr trans) override { return std::shared_ptr(new TWebSocketServer(trans)); } }; /** * Wraps a transport into text WebSocket protocol */ class TTextWebSocketServerTransportFactory : public TTransportFactory { public: TTextWebSocketServerTransportFactory() = default; ~TTextWebSocketServerTransportFactory() override = default; /** * Wraps the transport into a buffered one. */ std::shared_ptr getTransport(std::shared_ptr trans) override { return std::shared_ptr(new TWebSocketServer(trans)); } }; } // namespace transport } // namespace thrift } // namespace apache #endif thrift-0.23.0/lib/cpp/src/thrift/transport/TSSLSocket.cpp0000664000175000017500000011307715167543515023520 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_ARPA_INET_H #include #endif #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_SYS_POLL_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #define OPENSSL_VERSION_NO_THREAD_ID_BEFORE 0x10000000L #define OPENSSL_ENGINE_CLEANUP_REQUIRED_BEFORE 0x10100000L #include #include #if (OPENSSL_VERSION_NUMBER < OPENSSL_ENGINE_CLEANUP_REQUIRED_BEFORE) #include #endif #include #include #include #include #include #include #include #include using namespace apache::thrift::concurrency; using std::string; struct CRYPTO_dynlock_value { Mutex mutex; }; namespace apache { namespace thrift { namespace transport { // OpenSSL initialization/cleanup static bool openSSLInitialized = false; static boost::shared_array mutexes; static void callbackLocking(int mode, int n, const char*, int) { if (mode & CRYPTO_LOCK) { // assertion of (px != 0) here typically means that a TSSLSocket's lifetime // exceeded the lifetime of the TSSLSocketFactory that created it, and the // TSSLSocketFactory already ran cleanupOpenSSL(), which deleted "mutexes". mutexes[n].lock(); } else { mutexes[n].unlock(); } } #if (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_NO_THREAD_ID_BEFORE) static unsigned long callbackThreadID() { #ifdef _WIN32 return (unsigned long)GetCurrentThreadId(); #else return (unsigned long)pthread_self(); #endif } #endif static CRYPTO_dynlock_value* dyn_create(const char*, int) { return new CRYPTO_dynlock_value; } static void dyn_lock(int mode, struct CRYPTO_dynlock_value* lock, const char*, int) { if (lock != nullptr) { if (mode & CRYPTO_LOCK) { lock->mutex.lock(); } else { lock->mutex.unlock(); } } } static void dyn_destroy(struct CRYPTO_dynlock_value* lock, const char*, int) { delete lock; } void initializeOpenSSL() { if (openSSLInitialized) { return; } openSSLInitialized = true; SSL_library_init(); SSL_load_error_strings(); ERR_load_crypto_strings(); // static locking // newer versions of OpenSSL changed CRYPTO_num_locks - see THRIFT-3878 #ifdef CRYPTO_num_locks mutexes = boost::shared_array(new Mutex[CRYPTO_num_locks()]); #else mutexes = boost::shared_array(new Mutex[ ::CRYPTO_num_locks()]); #endif #if (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_NO_THREAD_ID_BEFORE) CRYPTO_set_id_callback(callbackThreadID); #endif CRYPTO_set_locking_callback(callbackLocking); // dynamic locking CRYPTO_set_dynlock_create_callback(dyn_create); CRYPTO_set_dynlock_lock_callback(dyn_lock); CRYPTO_set_dynlock_destroy_callback(dyn_destroy); } void cleanupOpenSSL() { if (!openSSLInitialized) { return; } openSSLInitialized = false; // https://wiki.openssl.org/index.php/Library_Initialization#Cleanup // we purposefully do NOT call FIPS_mode_set(0) and leave it up to the enclosing application to manage FIPS entirely #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_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) CONF_modules_unload(1); #endif EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); #if OPENSSL_VERSION_NUMBER >= 0x10100000 // Do nothing unless an openssl derivative is detected # if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) // https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_thread_stop.html OPENSSL_thread_stop(); # endif #else // ERR_remove_state() was deprecated in OpenSSL 1.0.0 and ERR_remove_thread_state() // was deprecated in OpenSSL 1.1.0; these functions and should not be used. // https://www.openssl.org/docs/manmaster/man3/ERR_remove_state.html ERR_remove_state(0); #endif ERR_free_strings(); mutexes.reset(); } static void buildErrors(string& message, int errno_copy = 0, int sslerrno = 0); static bool matchName(const char* host, const char* pattern, int size); static char uppercase(char c); // SSLContext implementation SSLContext::SSLContext(const SSLProtocol& protocol) { if (protocol == SSLTLS) { ctx_ = SSL_CTX_new(SSLv23_method()); #ifndef OPENSSL_NO_SSL3 } else if (protocol == SSLv3) { ctx_ = SSL_CTX_new(SSLv3_method()); #endif } else if (protocol == TLSv1_0) { ctx_ = SSL_CTX_new(TLSv1_method()); } else if (protocol == TLSv1_1) { ctx_ = SSL_CTX_new(TLSv1_1_method()); } else if (protocol == TLSv1_2) { ctx_ = SSL_CTX_new(TLSv1_2_method()); } else { /// UNKNOWN PROTOCOL! throw TSSLException("SSL_CTX_new: Unknown protocol"); } if (ctx_ == nullptr) { string errors; buildErrors(errors); throw TSSLException("SSL_CTX_new: " + errors); } SSL_CTX_set_mode(ctx_, SSL_MODE_AUTO_RETRY); // Disable horribly insecure SSLv2 and SSLv3 protocols but allow a handshake // with older clients so they get a graceful denial. if (protocol == SSLTLS) { SSL_CTX_set_options(ctx_, SSL_OP_NO_SSLv2); SSL_CTX_set_options(ctx_, SSL_OP_NO_SSLv3); // THRIFT-3164 } } SSLContext::~SSLContext() { if (ctx_ != nullptr) { SSL_CTX_free(ctx_); ctx_ = nullptr; } } SSL* SSLContext::createSSL() { SSL* ssl = SSL_new(ctx_); if (ssl == nullptr) { string errors; buildErrors(errors); throw TSSLException("SSL_new: " + errors); } return ssl; } // TSSLSocket implementation TSSLSocket::TSSLSocket(std::shared_ptr ctx, std::shared_ptr config) : TSocket(config), server_(false), ssl_(nullptr), ctx_(ctx) { init(); } TSSLSocket::TSSLSocket(std::shared_ptr ctx, std::shared_ptr interruptListener, std::shared_ptr config) : TSocket(config), server_(false), ssl_(nullptr), ctx_(ctx) { init(); interruptListener_ = interruptListener; } TSSLSocket::TSSLSocket(std::shared_ptr ctx, THRIFT_SOCKET socket, std::shared_ptr config) : TSocket(socket, config), server_(false), ssl_(nullptr), ctx_(ctx) { init(); } TSSLSocket::TSSLSocket(std::shared_ptr ctx, THRIFT_SOCKET socket, std::shared_ptr interruptListener, std::shared_ptr config) : TSocket(socket, interruptListener, config), server_(false), ssl_(nullptr), ctx_(ctx) { init(); } TSSLSocket::TSSLSocket(std::shared_ptr ctx, string host, int port, std::shared_ptr config) : TSocket(host, port, config), server_(false), ssl_(nullptr), ctx_(ctx) { init(); } TSSLSocket::TSSLSocket(std::shared_ptr ctx, string host, int port, std::shared_ptr interruptListener, std::shared_ptr config) : TSocket(host, port, config), server_(false), ssl_(nullptr), ctx_(ctx) { init(); interruptListener_ = interruptListener; } TSSLSocket::~TSSLSocket() { close(); } bool TSSLSocket::hasPendingDataToRead() { if (!isOpen()) { return false; } initializeHandshake(); if (!checkHandshake()) throw TSSLException("TSSLSocket::hasPendingDataToRead: Handshake is not completed"); // data may be available in SSL buffers (note: SSL_pending does not have a failure mode) return SSL_pending(ssl_) > 0 || TSocket::hasPendingDataToRead(); } void TSSLSocket::init() { handshakeCompleted_ = false; readRetryCount_ = 0; eventSafe_ = false; } bool TSSLSocket::isOpen() const { if (ssl_ == nullptr || !TSocket::isOpen()) { return false; } int shutdown = SSL_get_shutdown(ssl_); // "!!" is squelching C4800 "forcing bool -> true or false" performance warning bool shutdownReceived = !!(shutdown & SSL_RECEIVED_SHUTDOWN); bool shutdownSent = !!(shutdown & SSL_SENT_SHUTDOWN); if (shutdownReceived && shutdownSent) { return false; } return true; } /* * Note: This method is not libevent safe. */ bool TSSLSocket::peek() { if (!isOpen()) { return false; } initializeHandshake(); if (!checkHandshake()) throw TSSLException("SSL_peek: Handshake is not completed"); int rc; do { uint8_t byte; rc = SSL_peek(ssl_, &byte, 1); if (rc < 0) { int errno_copy = THRIFT_GET_SOCKET_ERROR; int error = SSL_get_error(ssl_, rc); switch (error) { case SSL_ERROR_SYSCALL: if ((errno_copy != THRIFT_EINTR) && (errno_copy != THRIFT_EAGAIN)) { break; } // fallthrough case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: // in the case of SSL_ERROR_SYSCALL we want to wait for an read event again waitForEvent(error != SSL_ERROR_WANT_WRITE); continue; default:;// do nothing } string errors; buildErrors(errors, errno_copy, error); throw TSSLException("SSL_peek: " + errors); } else if (rc == 0) { ERR_clear_error(); break; } else { break; } } while (true); return (rc > 0); } void TSSLSocket::open() { if (isOpen() || server()) { throw TTransportException(TTransportException::BAD_ARGS); } TSocket::open(); } /* * Note: This method is not libevent safe. */ void TSSLSocket::close() { if (ssl_ != nullptr) { try { int rc; int errno_copy = 0; int error = 0; do { rc = SSL_shutdown(ssl_); if (rc <= 0) { errno_copy = THRIFT_GET_SOCKET_ERROR; error = SSL_get_error(ssl_, rc); switch (error) { case SSL_ERROR_SYSCALL: if ((errno_copy != THRIFT_EINTR) && (errno_copy != THRIFT_EAGAIN)) { break; } // fallthrough case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: // in the case of SSL_ERROR_SYSCALL we want to wait for an write/read event again waitForEvent(error == SSL_ERROR_WANT_READ); rc = 2; default:;// do nothing } } } while (rc == 2); if (rc < 0) { string errors; buildErrors(errors, errno_copy, error); TOutput::instance()(("SSL_shutdown: " + errors).c_str()); } } catch (TTransportException& te) { // Don't emit an exception because this method is called by the // destructor. There's also not much that a user can do to recover, so // just clean up as much as possible without throwing, similar to the rc // < 0 case above. TOutput::instance().printf("SSL_shutdown: %s", te.what()); } SSL_free(ssl_); ssl_ = nullptr; handshakeCompleted_ = false; #if OPENSSL_VERSION_NUMBER >= 0x10100000 // Do nothing unless an openssl derivative is detected # if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) // https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_thread_stop.html OPENSSL_thread_stop(); # endif #else // ERR_remove_state() was deprecated in OpenSSL 1.0.0 and ERR_remove_thread_state() // was deprecated in OpenSSL 1.1.0; these functions and should not be used. // https://www.openssl.org/docs/manmaster/man3/ERR_remove_state.html ERR_remove_state(0); #endif } TSocket::close(); } /* * Returns number of bytes read in SSL Socket. * If eventSafe is set, and it may returns 0 bytes then read method * needs to be called again until it is successfull or it throws * exception incase of failure. */ uint32_t TSSLSocket::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); initializeHandshake(); if (!checkHandshake()) throw TTransportException(TTransportException::UNKNOWN, "retry again"); int32_t bytes = 0; while (readRetryCount_ < maxRecvRetries_) { bytes = SSL_read(ssl_, buf, len); int32_t errno_copy = THRIFT_GET_SOCKET_ERROR; int32_t error = SSL_get_error(ssl_, bytes); readRetryCount_++; if (error == SSL_ERROR_NONE) { readRetryCount_ = 0; break; } unsigned int waitEventReturn; bool breakout = false; switch (error) { case SSL_ERROR_ZERO_RETURN: throw TTransportException(TTransportException::END_OF_FILE, "client disconnected"); case SSL_ERROR_SYSCALL: if (errno_copy == 0 && ERR_peek_error() == 0) { breakout = true; break; } if ((errno_copy != THRIFT_EINTR) && (errno_copy != THRIFT_EAGAIN)) { break; } if (readRetryCount_ >= maxRecvRetries_) { // THRIFT_EINTR needs to be handled manually and we can tolerate // a certain number break; } // fallthrough case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if (isLibeventSafe()) { if (readRetryCount_ < maxRecvRetries_) { // THRIFT_EINTR needs to be handled manually and we can tolerate // a certain number throw TTransportException(TTransportException::UNKNOWN, "retry again"); } throw TTransportException(TTransportException::INTERNAL_ERROR, "too much recv retries"); } // in the case of SSL_ERROR_SYSCALL we want to wait for an read event again else if ((waitEventReturn = waitForEvent(error != SSL_ERROR_WANT_WRITE)) == TSSL_EINTR ) { // repeat operation if (readRetryCount_ < maxRecvRetries_) { // THRIFT_EINTR needs to be handled manually and we can tolerate // a certain number continue; } throw TTransportException(TTransportException::INTERNAL_ERROR, "too much recv retries"); } else if (waitEventReturn == TSSL_DATA) { // in case of SSL and huge thrift packets, there may be a number of // socket operations, before any data becomes available by SSL_read(). // Therefore the number of retries should not be increased and // the operation should be repeated. readRetryCount_--; continue; } throw TTransportException(TTransportException::INTERNAL_ERROR, "unkown waitForEvent return value"); default:;// do nothing } if (breakout) { break; } string errors; buildErrors(errors, errno_copy, error); throw TSSLException("SSL_read: " + errors); } return bytes; } void TSSLSocket::write(const uint8_t* buf, uint32_t len) { initializeHandshake(); if (!checkHandshake()) return; // loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX. uint32_t written = 0; while (written < len) { ERR_clear_error(); int32_t bytes = SSL_write(ssl_, &buf[written], len - written); if (bytes <= 0) { int errno_copy = THRIFT_GET_SOCKET_ERROR; int error = SSL_get_error(ssl_, bytes); switch (error) { case SSL_ERROR_SYSCALL: if ((errno_copy != THRIFT_EINTR) && (errno_copy != THRIFT_EAGAIN)) { break; } // fallthrough case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if (isLibeventSafe()) { return; } else { // in the case of SSL_ERROR_SYSCALL we want to wait for an write event again waitForEvent(error == SSL_ERROR_WANT_READ); continue; } default:;// do nothing } string errors; buildErrors(errors, errno_copy, error); throw TSSLException("SSL_write: " + errors); } written += bytes; } } /* * Returns number of bytes written in SSL Socket. * If eventSafe is set, and it may returns 0 bytes then write method * needs to be called again until it is successfull or it throws * exception incase of failure. */ uint32_t TSSLSocket::write_partial(const uint8_t* buf, uint32_t len) { initializeHandshake(); if (!checkHandshake()) return 0; // loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX. uint32_t written = 0; while (written < len) { ERR_clear_error(); int32_t bytes = SSL_write(ssl_, &buf[written], len - written); if (bytes <= 0) { int errno_copy = THRIFT_GET_SOCKET_ERROR; int error = SSL_get_error(ssl_, bytes); switch (error) { case SSL_ERROR_SYSCALL: if ((errno_copy != THRIFT_EINTR) && (errno_copy != THRIFT_EAGAIN)) { break; } // fallthrough case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if (isLibeventSafe()) { return 0; } else { // in the case of SSL_ERROR_SYSCALL we want to wait for an write event again waitForEvent(error == SSL_ERROR_WANT_READ); continue; } default:;// do nothing } string errors; buildErrors(errors, errno_copy, error); throw TSSLException("SSL_write: " + errors); } written += bytes; } return written; } void TSSLSocket::flush() { resetConsumedMessageSize(); // Don't throw exception if not open. Thrift servers close socket twice. if (ssl_ == nullptr) { return; } initializeHandshake(); if (!checkHandshake()) throw TSSLException("BIO_flush: Handshake is not completed"); BIO* bio = SSL_get_wbio(ssl_); if (bio == nullptr) { throw TSSLException("SSL_get_wbio returns nullptr"); } if (BIO_flush(bio) != 1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("BIO_flush: " + errors); } } void TSSLSocket::initializeHandshakeParams() { // set underlying socket to non-blocking int flags; if ((flags = THRIFT_FCNTL(socket_, THRIFT_F_GETFL, 0)) < 0 || THRIFT_FCNTL(socket_, THRIFT_F_SETFL, flags | THRIFT_O_NONBLOCK) < 0) { TOutput::instance().perror("thriftServerEventHandler: set THRIFT_O_NONBLOCK (THRIFT_FCNTL) ", THRIFT_GET_SOCKET_ERROR); ::THRIFT_CLOSESOCKET(socket_); return; } ssl_ = ctx_->createSSL(); SSL_set_fd(ssl_, static_cast(socket_)); } bool TSSLSocket::checkHandshake() { return handshakeCompleted_; } void TSSLSocket::initializeHandshake() { if (!TSocket::isOpen()) { throw TTransportException(TTransportException::NOT_OPEN); } if (checkHandshake()) { return; } if (ssl_ == nullptr) { initializeHandshakeParams(); } int rc; int errno_copy = 0; int error = 0; if (server()) { do { rc = SSL_accept(ssl_); if (rc <= 0) { errno_copy = THRIFT_GET_SOCKET_ERROR; error = SSL_get_error(ssl_, rc); switch (error) { case SSL_ERROR_SYSCALL: if ((errno_copy != THRIFT_EINTR) && (errno_copy != THRIFT_EAGAIN)) { break; } // fallthrough case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if (isLibeventSafe()) { return; } else { // repeat operation // in the case of SSL_ERROR_SYSCALL we want to wait for an write/read event again waitForEvent(error == SSL_ERROR_WANT_READ); rc = 2; } default:;// do nothing } } } while (rc == 2); } else { // OpenSSL < 0.9.8f does not have SSL_set_tlsext_host_name() #if defined(SSL_set_tlsext_host_name) // set the SNI hostname SSL_set_tlsext_host_name(ssl_, getHost().c_str()); #endif do { rc = SSL_connect(ssl_); if (rc <= 0) { errno_copy = THRIFT_GET_SOCKET_ERROR; error = SSL_get_error(ssl_, rc); switch (error) { case SSL_ERROR_SYSCALL: if ((errno_copy != THRIFT_EINTR) && (errno_copy != THRIFT_EAGAIN)) { break; } // fallthrough case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if (isLibeventSafe()) { return; } else { // repeat operation // in the case of SSL_ERROR_SYSCALL we want to wait for an write/read event again waitForEvent(error == SSL_ERROR_WANT_READ); rc = 2; } default:;// do nothing } } } while (rc == 2); } if (rc <= 0) { string fname(server() ? "SSL_accept" : "SSL_connect"); string errors; buildErrors(errors, errno_copy, error); throw TSSLException(fname + ": " + errors); } authorize(); handshakeCompleted_ = true; } void TSSLSocket::authorize() { 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)); } X509* cert = SSL_get_peer_certificate(ssl_); if (cert == nullptr) { // certificate is not present if (SSL_get_verify_mode(ssl_) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { throw TSSLException("authorize: required certificate not present"); } // certificate was optional: didn't intend to authorize remote if (server() && access_ != nullptr) { throw TSSLException("authorize: certificate required for authorization"); } return; } // certificate is present if (access_ == nullptr) { X509_free(cert); return; } // both certificate and access manager are present string host; sockaddr_storage sa; socklen_t saLength = sizeof(sa); if (getpeername(socket_, (sockaddr*)&sa, &saLength) != 0) { sa.ss_family = AF_UNSPEC; } AccessManager::Decision decision = access_->verify(sa); if (decision != AccessManager::SKIP) { X509_free(cert); if (decision != AccessManager::ALLOW) { throw TSSLException("authorize: access denied based on remote IP"); } return; } // extract subjectAlternativeName auto* alternatives = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr); if (alternatives != nullptr) { const int count = sk_GENERAL_NAME_num(alternatives); for (int i = 0; decision == AccessManager::SKIP && i < count; i++) { const GENERAL_NAME* name = sk_GENERAL_NAME_value(alternatives, i); if (name == nullptr) { continue; } char* data = (char*)ASN1_STRING_data(name->d.ia5); int length = ASN1_STRING_length(name->d.ia5); switch (name->type) { case GEN_DNS: if (host.empty()) { host = (server() ? getPeerHost() : getHost()); } decision = access_->verify(host, data, length); break; case GEN_IPADD: decision = access_->verify(sa, data, length); break; } } sk_GENERAL_NAME_pop_free(alternatives, GENERAL_NAME_free); } if (decision != AccessManager::SKIP) { X509_free(cert); if (decision != AccessManager::ALLOW) { throw TSSLException("authorize: access denied"); } return; } // extract commonName X509_NAME* name = X509_get_subject_name(cert); if (name != nullptr) { X509_NAME_ENTRY* entry; unsigned char* utf8; int last = -1; while (decision == AccessManager::SKIP) { last = X509_NAME_get_index_by_NID(name, NID_commonName, last); if (last == -1) break; entry = X509_NAME_get_entry(name, last); if (entry == nullptr) continue; ASN1_STRING* common = X509_NAME_ENTRY_get_data(entry); int size = ASN1_STRING_to_UTF8(&utf8, common); if (host.empty()) { host = (server() ? getPeerHost() : getHost()); } decision = access_->verify(host, (char*)utf8, size); OPENSSL_free(utf8); } } X509_free(cert); if (decision != AccessManager::ALLOW) { throw TSSLException("authorize: cannot authorize peer"); } } /* * Note: This method is not libevent safe. */ unsigned int TSSLSocket::waitForEvent(bool wantRead) { int fdSocket; BIO* bio; if (wantRead) { bio = SSL_get_rbio(ssl_); } else { bio = SSL_get_wbio(ssl_); } if (bio == nullptr) { throw TSSLException("SSL_get_?bio returned nullptr"); } if (BIO_get_fd(bio, &fdSocket) < 0) { throw TSSLException("BIO_get_fd failed"); } struct THRIFT_POLLFD fds[2]; memset(fds, 0, sizeof(fds)); fds[0].fd = fdSocket; // use POLLIN also on write operations too, this is needed for operations // which requires read and write on the socket. fds[0].events = wantRead ? THRIFT_POLLIN : THRIFT_POLLIN | THRIFT_POLLOUT; if (interruptListener_) { fds[1].fd = *(interruptListener_.get()); fds[1].events = THRIFT_POLLIN; } int timeout = -1; if (wantRead && recvTimeout_) { timeout = recvTimeout_; } if (!wantRead && sendTimeout_) { timeout = sendTimeout_; } int ret = THRIFT_POLL(fds, interruptListener_ ? 2 : 1, timeout); if (ret < 0) { // error cases if (THRIFT_GET_SOCKET_ERROR == THRIFT_EINTR) { return TSSL_EINTR; // repeat operation } int errno_copy = THRIFT_GET_SOCKET_ERROR; TOutput::instance().perror("TSSLSocket::read THRIFT_POLL() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy); } else if (ret > 0){ if (fds[1].revents & THRIFT_POLLIN) { throw TTransportException(TTransportException::INTERRUPTED, "Interrupted"); } return TSSL_DATA; } else { throw TTransportException(TTransportException::TIMED_OUT, "THRIFT_POLL (timed out)"); } } // TSSLSocketFactory implementation 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(); } count_++; ctx_ = std::make_shared(protocol); } TSSLSocketFactory::~TSSLSocketFactory() { Guard guard(mutex_); ctx_.reset(); count_--; if (count_ == 0 && didWeInitializeOpenSSL_) { cleanupOpenSSL(); didWeInitializeOpenSSL_ = false; } } std::shared_ptr TSSLSocketFactory::createSocket() { std::shared_ptr ssl(new TSSLSocket(ctx_)); setup(ssl); return ssl; } std::shared_ptr TSSLSocketFactory::createSocket(std::shared_ptr interruptListener) { std::shared_ptr ssl(new TSSLSocket(ctx_, interruptListener)); setup(ssl); return ssl; } std::shared_ptr TSSLSocketFactory::createSocket(THRIFT_SOCKET socket) { std::shared_ptr ssl(new TSSLSocket(ctx_, socket)); setup(ssl); return ssl; } std::shared_ptr TSSLSocketFactory::createSocket(THRIFT_SOCKET socket, std::shared_ptr interruptListener) { std::shared_ptr ssl(new TSSLSocket(ctx_, socket, interruptListener)); setup(ssl); return ssl; } std::shared_ptr TSSLSocketFactory::createSocket(const string& host, int port) { std::shared_ptr ssl(new TSSLSocket(ctx_, host, port)); setup(ssl); return ssl; } std::shared_ptr TSSLSocketFactory::createSocket(const string& host, int port, std::shared_ptr interruptListener) { std::shared_ptr ssl(new TSSLSocket(ctx_, host, port, interruptListener)); setup(ssl); return ssl; } void TSSLSocketFactory::setup(std::shared_ptr ssl) { ssl->server(server()); if (access_ == nullptr && !server()) { access_ = std::shared_ptr(new DefaultClientAccessManager); } if (access_ != nullptr) { ssl->access(access_); } } void TSSLSocketFactory::ciphers(const string& enable) { int rc = SSL_CTX_set_cipher_list(ctx_->get(), enable.c_str()); if (ERR_peek_error() != 0) { string errors; buildErrors(errors); throw TSSLException("SSL_CTX_set_cipher_list: " + errors); } if (rc == 0) { throw TSSLException("None of specified ciphers are supported"); } } void TSSLSocketFactory::authenticate(bool required) { int mode; if (required) { mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE; } else { mode = SSL_VERIFY_NONE; } SSL_CTX_set_verify(ctx_->get(), mode, nullptr); } void TSSLSocketFactory::loadCertificate(const char* path, const char* format) { if (path == nullptr || format == nullptr) { throw TTransportException(TTransportException::BAD_ARGS, "loadCertificateChain: either or is nullptr"); } if (strcmp(format, "PEM") == 0) { if (SSL_CTX_use_certificate_chain_file(ctx_->get(), path) == 0) { int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("SSL_CTX_use_certificate_chain_file: " + errors); } } else { throw TSSLException("Unsupported certificate format: " + string(format)); } } void TSSLSocketFactory::loadCertificateFromBuffer(const char* aCertificate, const char* format) { if (aCertificate == nullptr || format == nullptr) { throw TTransportException(TTransportException::BAD_ARGS, "loadCertificate: either or is nullptr"); } if (strcmp(format, "PEM") == 0) { BIO* mem = BIO_new(BIO_s_mem()); BIO_puts(mem, aCertificate); X509* cert = PEM_read_bio_X509(mem, nullptr, nullptr, nullptr); BIO_free(mem); const int status = SSL_CTX_use_certificate(ctx_->get(), cert); X509_free(cert); if (status != 1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("SSL_CTX_use_certificate: " + errors); } } else { throw TSSLException("Unsupported certificate format: " + string(format)); } } void TSSLSocketFactory::loadPrivateKey(const char* path, const char* format) { if (path == nullptr || format == nullptr) { throw TTransportException(TTransportException::BAD_ARGS, "loadPrivateKey: either or is nullptr"); } if (strcmp(format, "PEM") == 0) { if (SSL_CTX_use_PrivateKey_file(ctx_->get(), path, SSL_FILETYPE_PEM) == 0) { int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("SSL_CTX_use_PrivateKey_file: " + errors); } } } void TSSLSocketFactory::loadPrivateKeyFromBuffer(const char* aPrivateKey, const char* format) { if (aPrivateKey == nullptr || format == nullptr) { throw TTransportException(TTransportException::BAD_ARGS, "loadPrivateKey: either or is nullptr"); } if (strcmp(format, "PEM") == 0) { EVP_PKEY* cert; BIO* mem; mem = BIO_new(BIO_s_mem()); BIO_puts(mem, aPrivateKey); cert = PEM_read_bio_PrivateKey(mem, nullptr, nullptr, nullptr); BIO_free(mem); const int status = SSL_CTX_use_PrivateKey(ctx_->get(), cert); EVP_PKEY_free(cert); if (status == 0) { int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("SSL_CTX_use_PrivateKey: " + errors); } } else { throw TSSLException("Unsupported certificate format: " + string(format)); } } void TSSLSocketFactory::loadTrustedCertificates(const char* path, const char* capath) { if (path == nullptr) { throw TTransportException(TTransportException::BAD_ARGS, "loadTrustedCertificates: is nullptr"); } if (SSL_CTX_load_verify_locations(ctx_->get(), path, capath) == 0) { int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("SSL_CTX_load_verify_locations: " + errors); } } void TSSLSocketFactory::loadTrustedCertificatesFromBuffer(const char* aCertificate, const char* aChain) { if (aCertificate == nullptr) { throw TTransportException(TTransportException::BAD_ARGS, "loadTrustedCertificates: aCertificate is empty"); } X509_STORE* vX509Store = SSL_CTX_get_cert_store(ctx_->get()); BIO* mem = BIO_new(BIO_s_mem()); BIO_puts(mem, aCertificate); X509* cert = PEM_read_bio_X509(mem, nullptr, nullptr, nullptr); BIO_free(mem); const int status = X509_STORE_add_cert(vX509Store, cert); X509_free(cert); if (status != 1) { int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("X509_STORE_add_cert: " + errors); } if (aChain) { mem = BIO_new(BIO_s_mem()); BIO_puts(mem, aChain); cert = PEM_read_bio_X509(mem, nullptr, nullptr, nullptr); BIO_free(mem); // NOTE: The x509 certificate provided to SSL_CTX_add_extra_chain_cert() // will be freed by the library when the SSL_CTX is destroyed. Do not free // the x509 object manually here. if (SSL_CTX_add_extra_chain_cert(ctx_->get(), cert) == 0) { X509_free(cert); int errno_copy = THRIFT_GET_SOCKET_ERROR; string errors; buildErrors(errors, errno_copy); throw TSSLException("X509_STORE_add_cert: " + errors); } } } void TSSLSocketFactory::randomize() { RAND_poll(); } void TSSLSocketFactory::overrideDefaultPasswordCallback() { SSL_CTX_set_default_passwd_cb(ctx_->get(), passwordCallback); SSL_CTX_set_default_passwd_cb_userdata(ctx_->get(), this); } int TSSLSocketFactory::passwordCallback(char* password, int size, int, void* data) { auto* factory = (TSSLSocketFactory*)data; string userPassword; factory->getPassword(userPassword, size); int length = static_cast(userPassword.size()); if (length > size) { length = size; } strncpy(password, userPassword.c_str(), length); userPassword.assign(userPassword.size(), '*'); return length; } void TSSLSocketFactory::setManualOpenSSLInitialization(bool manualOpenSSLInitialization) { manualOpenSSLInitialization_ = manualOpenSSLInitialization; } // extract error messages from error queue void buildErrors(string& errors, int errno_copy, int sslerrno) { unsigned long errorCode; char message[256]; errors.reserve(512); while ((errorCode = ERR_get_error()) != 0) { if (!errors.empty()) { errors += "; "; } const char* reason = ERR_reason_error_string(errorCode); if (reason == nullptr) { THRIFT_SNPRINTF(message, sizeof(message) - 1, "SSL error # %lu", errorCode); reason = message; } errors += reason; } if (errors.empty()) { if (errno_copy != 0) { errors += TOutput::strerror_s(errno_copy); } } if (errors.empty()) { errors = "error code: " + to_string(errno_copy); } if (sslerrno) { errors += " (SSL_error_code = " + to_string(sslerrno) + ")"; if (sslerrno == SSL_ERROR_SYSCALL) { char buf[4096]; int err; while ((err = ERR_get_error()) != 0) { errors += " "; errors += ERR_error_string(err, buf); } } } } /** * Default implementation of AccessManager */ Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa) noexcept { (void)sa; return SKIP; } Decision DefaultClientAccessManager::verify(const string& host, const char* name, int size) noexcept { if (host.empty() || name == nullptr || size <= 0) { return SKIP; } return (matchName(host.c_str(), name, size) ? ALLOW : SKIP); } Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa, const char* data, int size) noexcept { bool match = false; if (sa.ss_family == AF_INET && size == sizeof(in_addr)) { match = (memcmp(&((sockaddr_in*)&sa)->sin_addr, data, size) == 0); } else if (sa.ss_family == AF_INET6 && size == sizeof(in6_addr)) { match = (memcmp(&((sockaddr_in6*)&sa)->sin6_addr, data, size) == 0); } return (match ? ALLOW : SKIP); } /** * Match a name with a pattern. The pattern may include wildcard. A single * wildcard "*" can match up to one component in the domain name. * * @param host Host name, typically the name of the remote host * @param pattern Name retrieved from certificate * @param size Size of "pattern" * @return True, if "host" matches "pattern". False otherwise. */ bool matchName(const char* host, const char* pattern, int size) { bool match = false; int i = 0, j = 0; while (i < size && host[j] != '\0') { if (uppercase(pattern[i]) == uppercase(host[j])) { i++; j++; continue; } if (pattern[i] == '*') { while (host[j] != '.' && host[j] != '\0') { j++; } i++; continue; } break; } if (i == size && host[j] == '\0') { match = true; } return match; } // This is to work around the Turkish locale issue, i.e., // toupper('i') != toupper('I') if locale is "tr_TR" char uppercase(char c) { if ('a' <= c && c <= 'z') { return c + ('A' - 'a'); } return c; } } } } thrift-0.23.0/lib/cpp/src/thrift/transport/TSimpleFileTransport.h0000664000175000017500000000264315165535636025320 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSIMPLEFILETRANSPORT_H_ #define _THRIFT_TRANSPORT_TSIMPLEFILETRANSPORT_H_ 1 #include namespace apache { namespace thrift { namespace transport { /** * Dead-simple wrapper around a file. * * Writeable files are opened with O_CREAT and O_APPEND */ class TSimpleFileTransport : public TFDTransport { public: TSimpleFileTransport(const std::string& path, bool read = true, bool write = false, std::shared_ptr config = nullptr); }; } } } // apache::thrift::transport #endif // _THRIFT_TRANSPORT_TSIMPLEFILETRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TSocketUtils.h0000664000175000017500000001156215165535636023623 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_SOCKETUTILS_H_ #define _THRIFT_TRANSPORT_SOCKETUTILS_H_ 1 #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #include namespace apache { namespace thrift { /** * A helper to resolve hostnames to struct addrinfo's -- and not leak memory. * * Use like this: * * apache::thrift::AddressResolutionHelper addresses("localhost", "80"); * * for (auto addr : addresses.iterate()) { * connect(sock, addr->ai_addr, addr->ai_addrlen); * // ... * } */ struct AddressResolutionHelper { private: struct addrinfo_deleter { void operator()(addrinfo* addr) { ::freeaddrinfo(addr); // frees the whole list } }; public: using PtrOwnedList = std::unique_ptr; struct Iter { using iterator_category = std::forward_iterator_tag; using value_type = const addrinfo*; using difference_type = std::ptrdiff_t; using pointer = value_type*; using reference = value_type&; value_type ptr = nullptr; Iter() = default; Iter(const addrinfo* head) : ptr(head) {} value_type operator*() const { return ptr; } bool operator==(const Iter& other) { return this->ptr == other.ptr; } bool operator!=(const Iter& other) { return this->ptr != other.ptr; } operator bool() { return this->ptr != nullptr; } bool operator!() { return this->ptr == nullptr; } Iter& operator++() { if (ptr == nullptr) { throw std::out_of_range("won't go pass end of linked list"); } ptr = ptr->ai_next; return *this; } Iter operator++(int) { Iter tmp(*this); ++(*this); return tmp; } }; struct gai_error : std::error_category { virtual const char* name() const noexcept override { return "getaddrinfo"; } virtual std::string message(int code) const override { return THRIFT_GAI_STRERROR(code); } }; private: PtrOwnedList gai_results; addrinfo* query(const std::string& host, const std::string& port, int socktype, int flags) { addrinfo hints{}; hints.ai_flags = flags; hints.ai_family = AF_UNSPEC; hints.ai_socktype = socktype; addrinfo* head; int ret = ::getaddrinfo(host.empty() ? NULL : host.c_str(), port.c_str(), &hints, &head); if (ret == 0) { return head; #ifdef _WIN32 } else { throw std::system_error{THRIFT_GET_SOCKET_ERROR, std::system_category()}; #else } else if (ret == EAI_SYSTEM) { throw std::system_error{THRIFT_GET_SOCKET_ERROR, std::system_category()}; } else { throw std::system_error{ret, gai_error()}; #endif } } public: /** * Constructor. May block. Throws errors. * * @param port Port number, or service name, as a string. * @param socktype Socket type, SOCK_STREAM or SOCK_DGRAM. * @param flags Standard getaddrinfo() flags. */ AddressResolutionHelper(const std::string& host, const std::string& port, // pass "25" or "smtp" for port 25 int socktype = SOCK_STREAM, int flags = AI_V4MAPPED | AI_ADDRCONFIG) : gai_results(query(host, port, socktype, flags)) {} AddressResolutionHelper() = default; /** * Manual query. May block. Throws errors. * * @param port Port number, or service name, as a string. * @param socktype Socket type, SOCK_STREAM or SOCK_DGRAM. * @param flags Standard getaddrinfo() flags. */ AddressResolutionHelper& resolve(const std::string& host, const std::string& port, // pass "25" or "smtp" for port 25 int socktype = SOCK_STREAM, int flags = AI_V4MAPPED | AI_ADDRCONFIG) { gai_results.reset(query(host, port, socktype, flags)); return *this; } /** * Return ForwardIterator to struct addrinfo* results. */ Iter iterate() const { return Iter{gai_results.get()}; } }; } // namespace thrift } // namespace apache #endif thrift-0.23.0/lib/cpp/src/thrift/transport/THttpClient.cpp0000664000175000017500000000734715165535636023771 0ustar00buildbuild00000000000000/* * 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 #include #include using std::string; namespace apache { namespace thrift { namespace transport { THttpClient::THttpClient(std::shared_ptr transport, std::string host, std::string path, std::shared_ptr config) : THttpTransport(transport, config), host_(host), path_(path) { } THttpClient::THttpClient(string host, int port, string path, std::shared_ptr config) : THttpTransport(std::shared_ptr(new TSocket(host, port)), config), host_(host), path_(path) { } THttpClient::~THttpClient() = default; void THttpClient::parseHeader(char* header) { char* colon = strchr(header, ':'); if (colon == nullptr) { return; } char* value = colon + 1; if (boost::istarts_with(header, "Transfer-Encoding")) { if (boost::iends_with(value, "chunked")) { chunked_ = true; } } else if (boost::istarts_with(header, "Content-Length")) { chunked_ = false; contentLength_ = atoi(value); } } bool THttpClient::parseStatusLine(char* status) { char* http = status; char* code = strchr(http, ' '); if (code == nullptr) { throw TTransportException(string("Bad Status: ") + status); } *code = '\0'; while (*(code++) == ' ') { }; char* msg = strchr(code, ' '); if (msg == nullptr) { throw TTransportException(string("Bad Status: ") + status); } *msg = '\0'; if (strcmp(code, "200") == 0) { // HTTP 200 = OK, we got the response return true; } else if (strcmp(code, "100") == 0) { // HTTP 100 = continue, just keep reading return false; } else { throw TTransportException(string("Bad Status: ") + status); } } void THttpClient::flush() { resetConsumedMessageSize(); // Fetch the contents of the write buffer uint8_t* buf; uint32_t len; writeBuffer_.getBuffer(&buf, &len); // Construct the HTTP header std::ostringstream h; h << "POST " << path_ << " HTTP/1.1" << CRLF << "Host: " << host_ << CRLF << "Content-Type: application/x-thrift" << CRLF << "Content-Length: " << len << CRLF << "Accept: application/x-thrift" << CRLF << "User-Agent: Thrift/" << PACKAGE_VERSION << " (C++/THttpClient)" << CRLF << CRLF; string header = h.str(); if (header.size() > (std::numeric_limits::max)()) throw TTransportException("Header too big"); // Write the header, then the data, then flush transport_->write((const uint8_t*)header.c_str(), static_cast(header.size())); transport_->write(buf, len); transport_->flush(); // Reset the buffer and header variables writeBuffer_.resetBuffer(); readHeaders_ = true; } void THttpClient::setPath(std::string path) { path_ = path; } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.cpp0000664000175000017500000000411515165535636027066 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace transport { /** * Nonblocking SSL server socket implementation. */ TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(int port, std::shared_ptr factory) : TNonblockingServerSocket(port), factory_(factory) { factory_->server(true); } TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(const std::string& address, int port, std::shared_ptr factory) : TNonblockingServerSocket(address, port), factory_(factory) { factory_->server(true); } TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(int port, int sendTimeout, int recvTimeout, std::shared_ptr factory) : TNonblockingServerSocket(port, sendTimeout, recvTimeout), factory_(factory) { factory_->server(true); } std::shared_ptr TNonblockingSSLServerSocket::createSocket(THRIFT_SOCKET client) { std::shared_ptr tSSLSocket; tSSLSocket = factory_->createSocket(client); tSSLSocket->setLibeventSafe(); return tSSLSocket; } } } } thrift-0.23.0/lib/cpp/src/thrift/transport/TServerTransport.h0000664000175000017500000000722615165535636024537 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSERVERTRANSPORT_H_ #define _THRIFT_TRANSPORT_TSERVERTRANSPORT_H_ 1 #include #include namespace apache { namespace thrift { namespace transport { /** * Server transport framework. A server needs to have some facility for * creating base transports to read/write from. The server is expected * to keep track of TTransport children that it creates for purposes of * controlling their lifetime. */ class TServerTransport { public: virtual ~TServerTransport() = default; /** * Whether this transport is open. */ virtual bool isOpen() const { return false; } /** * Starts the server transport listening for new connections. Prior to this * call most transports will not return anything when accept is called. * * @throws TTransportException if we were unable to listen */ virtual void listen() {} /** * Gets a new dynamically allocated transport object and passes it to the * caller. Note that it is the explicit duty of the caller to free the * allocated object. The returned TTransport object must always be in the * opened state. nullptr should never be returned, instead an Exception should * always be thrown. * * @return A new TTransport object * @throws TTransportException if there is an error */ std::shared_ptr accept() { std::shared_ptr result = acceptImpl(); if (!result) { throw TTransportException("accept() may not return nullptr"); } return result; } /** * For "smart" TServerTransport implementations that work in a multi * threaded context this can be used to break out of an accept() call. * It is expected that the transport will throw a TTransportException * with the INTERRUPTED error code. * * This will not make an attempt to interrupt any TTransport children. */ virtual void interrupt() {} /** * This will interrupt the children created by the server transport. * allowing them to break out of any blocking data reception call. * It is expected that the children will throw a TTransportException * with the INTERRUPTED error code. */ virtual void interruptChildren() {} /** * Utility method * * @return server socket file descriptor * @throw TTransportException If an error occurs */ virtual THRIFT_SOCKET getSocketFD() { return -1; } /** * Closes this transport such that future calls to accept will do nothing. */ virtual void close() = 0; protected: TServerTransport() = default; /** * Subclasses should implement this function for accept. * * @return A newly allocated TTransport object * @throw TTransportException If an error occurs */ virtual std::shared_ptr acceptImpl() = 0; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TSERVERTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TFileTransport.cpp0000664000175000017500000010011215167543515024464 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_SYS_TIME_H #include #else #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #include #include #include #ifdef HAVE_SYS_STAT_H #include #endif #ifdef _WIN32 #include #endif #include #include #include #include namespace apache { namespace thrift { namespace transport { using std::shared_ptr; using std::cerr; using std::string; using namespace apache::thrift::protocol; using namespace apache::thrift::concurrency; TFileTransport::TFileTransport(string path, bool readOnly, std::shared_ptr config) : TTransport(config), readState_(), readBuff_(nullptr), currentEvent_(nullptr), readBuffSize_(DEFAULT_READ_BUFF_SIZE), readTimeout_(NO_TAIL_READ_TIMEOUT), chunkSize_(DEFAULT_CHUNK_SIZE), eventBufferSize_(DEFAULT_EVENT_BUFFER_SIZE), flushMaxUs_(DEFAULT_FLUSH_MAX_US), flushMaxBytes_(DEFAULT_FLUSH_MAX_BYTES), maxEventSize_(DEFAULT_MAX_EVENT_SIZE), maxCorruptedEvents_(DEFAULT_MAX_CORRUPTED_EVENTS), eofSleepTime_(DEFAULT_EOF_SLEEP_TIME_US), corruptedEventSleepTime_(DEFAULT_CORRUPTED_SLEEP_TIME_US), writerThreadIOErrorSleepTime_(DEFAULT_WRITER_THREAD_SLEEP_TIME_US), dequeueBuffer_(nullptr), enqueueBuffer_(nullptr), notFull_(&mutex_), notEmpty_(&mutex_), closing_(false), flushed_(&mutex_), forceFlush_(false), filename_(path), fd_(0), bufferAndThreadInitialized_(false), offset_(0), lastBadChunk_(0), numCorruptedEventsInChunk_(0), readOnly_(readOnly) { threadFactory_.setDetached(false); openLogFile(); } void TFileTransport::resetOutputFile(int fd, string filename, off_t offset) { filename_ = filename; offset_ = offset; // check if current file is still open if (fd_ > 0) { // flush any events in the queue flush(); TOutput::instance().printf("error, current file (%s) not closed", filename_.c_str()); if (-1 == ::THRIFT_CLOSE(fd_)) { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: resetOutputFile() ::close() ", errno_copy); throw TTransportException(TTransportException::UNKNOWN, "TFileTransport: error in file close", errno_copy); } else { // successfully closed fd fd_ = 0; } } if (fd) { fd_ = fd; } else { // open file if the input fd is 0 openLogFile(); } } TFileTransport::~TFileTransport() { // flush the buffer if a writer thread is active if (writerThread_.get()) { // set state to closing closing_ = true; // wake up the writer thread // Since closing_ is true, it will attempt to flush all data, then exit. notEmpty_.notify(); writerThread_->join(); writerThread_.reset(); } if (dequeueBuffer_) { delete dequeueBuffer_; dequeueBuffer_ = nullptr; } if (enqueueBuffer_) { delete enqueueBuffer_; enqueueBuffer_ = nullptr; } if (readBuff_) { delete[] readBuff_; readBuff_ = nullptr; } if (currentEvent_) { delete currentEvent_; currentEvent_ = nullptr; } // close logfile if (fd_ > 0) { if (-1 == ::THRIFT_CLOSE(fd_)) { TOutput::instance().perror("TFileTransport: ~TFileTransport() ::close() ", THRIFT_ERRNO); } else { // successfully closed fd fd_ = 0; } } } bool TFileTransport::initBufferAndWriteThread() { if (bufferAndThreadInitialized_) { T_ERROR("%s", "Trying to double-init TFileTransport"); return false; } if (!writerThread_.get()) { writerThread_ = threadFactory_.newThread( apache::thrift::concurrency::FunctionRunner::create(startWriterThread, this)); writerThread_->start(); } dequeueBuffer_ = new TFileTransportBuffer(eventBufferSize_); enqueueBuffer_ = new TFileTransportBuffer(eventBufferSize_); bufferAndThreadInitialized_ = true; return true; } void TFileTransport::write(const uint8_t* buf, uint32_t len) { if (readOnly_) { throw TTransportException("TFileTransport: attempting to write to file opened readonly"); } enqueueEvent(buf, len); } template struct uniqueDeleter { void operator()(_T *ptr) const { delete ptr; } }; void TFileTransport::enqueueEvent(const uint8_t* buf, uint32_t eventLen) { // can't enqueue more events if file is going to close if (closing_) { return; } // make sure that event size is valid if ((maxEventSize_ > 0) && (eventLen > maxEventSize_)) { T_ERROR("msg size is greater than max event size: %u > %u\n", eventLen, maxEventSize_); return; } if (eventLen == 0) { T_ERROR("%s", "cannot enqueue an empty event"); return; } std::unique_ptr > toEnqueue(new eventInfo()); toEnqueue->eventBuff_ = new uint8_t[(sizeof(uint8_t) * eventLen) + 4]; // first 4 bytes is the event length memcpy(toEnqueue->eventBuff_, (void*)(&eventLen), 4); // actual event contents memcpy(toEnqueue->eventBuff_ + 4, buf, eventLen); toEnqueue->eventSize_ = eventLen + 4; // lock mutex Guard g(mutex_); // make sure that enqueue buffer is initialized and writer thread is running if (!bufferAndThreadInitialized_) { if (!initBufferAndWriteThread()) { return; } } // Can't enqueue while buffer is full while (enqueueBuffer_->isFull()) { notFull_.wait(); } // We shouldn't be trying to enqueue new data while a forced flush is // requested. (Otherwise the writer thread might not ever be able to finish // the flush if more data keeps being enqueued.) assert(!forceFlush_); // add to the buffer eventInfo* pEvent = toEnqueue.release(); if (!enqueueBuffer_->addEvent(pEvent)) { delete pEvent; return; } // signal anybody who's waiting for the buffer to be non-empty notEmpty_.notify(); // this really should be a loop where it makes sure it got flushed // because condition variables can get triggered by the os for no reason // it is probably a non-factor for the time being } bool TFileTransport::swapEventBuffers(const std::chrono::time_point *deadline) { bool swap; Guard g(mutex_); if (!enqueueBuffer_->isEmpty()) { swap = true; } else if (closing_) { // even though there is no data to write, // return immediately if the transport is closing swap = false; } else { if (deadline != nullptr) { // if we were handed a deadline time struct, do a timed wait notEmpty_.waitForTime(*deadline); } else { // just wait until the buffer gets an item notEmpty_.wait(); } // could be empty if we timed out swap = enqueueBuffer_->isEmpty(); } if (swap) { TFileTransportBuffer* temp = enqueueBuffer_; enqueueBuffer_ = dequeueBuffer_; dequeueBuffer_ = temp; } if (swap) { notFull_.notify(); } return swap; } void TFileTransport::writerThread() { bool hasIOError = false; // open file if it is not open if (!fd_) { try { openLogFile(); } catch (...) { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: writerThread() openLogFile() ", errno_copy); fd_ = 0; hasIOError = true; } } // set the offset to the correct value (EOF) if (!hasIOError) { try { seekToEnd(); // throw away any partial events offset_ += readState_.lastDispatchPtr_; if (0 == THRIFT_FTRUNCATE(fd_, offset_)) { readState_.resetAllValues(); } else { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: writerThread() truncate ", errno_copy); hasIOError = true; } } catch (...) { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: writerThread() initialization ", errno_copy); hasIOError = true; } } // Figure out the next time by which a flush must take place auto ts_next_flush = getNextFlushTime(); uint32_t unflushed = 0; while (1) { // this will only be true when the destructor is being invoked if (closing_) { if (hasIOError) { return; } // Try to empty buffers before exit if (enqueueBuffer_->isEmpty() && dequeueBuffer_->isEmpty()) { ::THRIFT_FSYNC(fd_); if (-1 == ::THRIFT_CLOSE(fd_)) { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: writerThread() ::close() ", errno_copy); } else { // fd successfully closed fd_ = 0; } return; } } if (swapEventBuffers(&ts_next_flush)) { eventInfo* outEvent; while (nullptr != (outEvent = dequeueBuffer_->getNext())) { // Remove an event from the buffer and write it out to disk. If there is any IO error, for // instance, // the output file is unmounted or deleted, then this event is dropped. However, the writer // thread // will: (1) sleep for a short while; (2) try to reopen the file; (3) if successful then // start writing // from the end. while (hasIOError) { T_ERROR( "TFileTransport: writer thread going to sleep for %u microseconds due to IO errors", writerThreadIOErrorSleepTime_); THRIFT_SLEEP_USEC(writerThreadIOErrorSleepTime_); if (closing_) { return; } if (!fd_) { ::THRIFT_CLOSE(fd_); fd_ = 0; } try { openLogFile(); seekToEnd(); unflushed = 0; hasIOError = false; T_LOG_OPER( "TFileTransport: log file %s reopened by writer thread during error recovery", filename_.c_str()); } catch (...) { T_ERROR("TFileTransport: unable to reopen log file %s during error recovery", filename_.c_str()); } } // sanity check on event if ((maxEventSize_ > 0) && (outEvent->eventSize_ > maxEventSize_)) { T_ERROR("msg size is greater than max event size: %u > %u\n", outEvent->eventSize_, maxEventSize_); continue; } // If chunking is required, then make sure that msg does not cross chunk boundary if ((outEvent->eventSize_ > 0) && (chunkSize_ != 0)) { // event size must be less than chunk size if (outEvent->eventSize_ > chunkSize_) { T_ERROR("TFileTransport: event size(%u) > chunk size(%u): skipping event", outEvent->eventSize_, chunkSize_); continue; } int64_t chunk1 = offset_ / chunkSize_; int64_t chunk2 = (offset_ + outEvent->eventSize_ - 1) / chunkSize_; // if adding this event will cross a chunk boundary, pad the chunk with zeros if (chunk1 != chunk2) { // refetch the offset to keep in sync offset_ = THRIFT_LSEEK(fd_, 0, SEEK_CUR); auto padding = (int32_t)((offset_ / chunkSize_ + 1) * chunkSize_ - offset_); auto* zeros = new uint8_t[padding]; memset(zeros, '\0', padding); std::unique_ptr array(zeros); if (-1 == ::THRIFT_WRITE(fd_, zeros, padding)) { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: writerThread() error while padding zeros ", errno_copy); hasIOError = true; continue; } unflushed += padding; offset_ += padding; } } // write the dequeued event to the file if (outEvent->eventSize_ > 0) { if (-1 == ::THRIFT_WRITE(fd_, outEvent->eventBuff_, outEvent->eventSize_)) { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: error while writing event ", errno_copy); hasIOError = true; continue; } unflushed += outEvent->eventSize_; offset_ += outEvent->eventSize_; } } dequeueBuffer_->reset(); } if (hasIOError) { continue; } // Local variable to cache the state of forceFlush_. // // We only want to check the value of forceFlush_ once each time around the // loop. If we check it more than once without holding the lock the entire // time, it could have changed state in between. This will result in us // making inconsistent decisions. bool forced_flush = false; { Guard g(mutex_); if (forceFlush_) { if (!enqueueBuffer_->isEmpty()) { // If forceFlush_ is true, we need to flush all available data. // If enqueueBuffer_ is not empty, go back to the start of the loop to // write it out. // // We know the main thread is waiting on forceFlush_ to be cleared, // so no new events will be added to enqueueBuffer_ until we clear // forceFlush_. Therefore the next time around the loop enqueueBuffer_ // is guaranteed to be empty. (I.e., we're guaranteed to make progress // and clear forceFlush_ the next time around the loop.) continue; } forced_flush = true; } } // determine if we need to perform an fsync bool flush = false; if (forced_flush || unflushed > flushMaxBytes_) { flush = true; } else { if (std::chrono::steady_clock::now() > ts_next_flush) { if (unflushed > 0) { flush = true; } else { // If there is no new data since the last fsync, // don't perform the fsync, but do reset the timer. ts_next_flush = getNextFlushTime(); } } } if (flush) { // sync (force flush) file to disk THRIFT_FSYNC(fd_); unflushed = 0; ts_next_flush = getNextFlushTime(); // notify anybody waiting for flush completion if (forced_flush) { Guard g(mutex_); forceFlush_ = false; assert(enqueueBuffer_->isEmpty()); assert(dequeueBuffer_->isEmpty()); flushed_.notifyAll(); } } } } void TFileTransport::flush() { resetConsumedMessageSize(); // file must be open for writing for any flushing to take place if (!writerThread_.get()) { return; } // wait for flush to take place Guard g(mutex_); // Indicate that we are requesting a flush forceFlush_ = true; // Wake up the writer thread so it will perform the flush immediately notEmpty_.notify(); while (forceFlush_) { flushed_.wait(); } } uint32_t TFileTransport::readAll(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); uint32_t have = 0; uint32_t get = 0; while (have < len) { get = read(buf + have, len - have); if (get <= 0) { throw TEOFException(); } have += get; } return have; } bool TFileTransport::peek() { // check if there is an event ready to be read if (!currentEvent_) { currentEvent_ = readEvent(); } // did not manage to read an event from the file. This could have happened // if the timeout expired or there was some other error if (!currentEvent_) { return false; } // check if there is anything to read return (currentEvent_->eventSize_ - currentEvent_->eventBuffPos_) > 0; } uint32_t TFileTransport::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); // check if there an event is ready to be read if (!currentEvent_) { currentEvent_ = readEvent(); } // did not manage to read an event from the file. This could have happened // if the timeout expired or there was some other error if (!currentEvent_) { return 0; } // read as much of the current event as possible int32_t remaining = currentEvent_->eventSize_ - currentEvent_->eventBuffPos_; if (remaining <= (int32_t)len) { // copy over anything thats remaining if (remaining > 0) { memcpy(buf, currentEvent_->eventBuff_ + currentEvent_->eventBuffPos_, remaining); } delete (currentEvent_); currentEvent_ = nullptr; return remaining; } // read as much as possible memcpy(buf, currentEvent_->eventBuff_ + currentEvent_->eventBuffPos_, len); currentEvent_->eventBuffPos_ += len; return len; } // note caller is responsible for freeing returned events eventInfo* TFileTransport::readEvent() { int readTries = 0; if (!readBuff_) { readBuff_ = new uint8_t[readBuffSize_]; } while (1) { // read from the file if read buffer is exhausted if (readState_.bufferPtr_ == readState_.bufferLen_) { // advance the offset pointer offset_ += readState_.bufferLen_; readState_.bufferLen_ = static_cast(::THRIFT_READ(fd_, readBuff_, readBuffSize_)); // if (readState_.bufferLen_) { // T_DEBUG_L(1, "Amount read: %u (offset: %lu)", readState_.bufferLen_, offset_); // } readState_.bufferPtr_ = 0; readState_.lastDispatchPtr_ = 0; // read error if (readState_.bufferLen_ == -1) { readState_.resetAllValues(); TOutput::instance()("TFileTransport: error while reading from file"); throw TTransportException("TFileTransport: error while reading from file"); } else if (readState_.bufferLen_ == 0) { // EOF // wait indefinitely if there is no timeout if (readTimeout_ == TAIL_READ_TIMEOUT) { THRIFT_SLEEP_USEC(eofSleepTime_); continue; } else if (readTimeout_ == NO_TAIL_READ_TIMEOUT) { // reset state readState_.resetState(0); return nullptr; } else if (readTimeout_ > 0) { // timeout already expired once if (readTries > 0) { readState_.resetState(0); return nullptr; } else { THRIFT_SLEEP_USEC(readTimeout_ * 1000); readTries++; continue; } } } } readTries = 0; // attempt to read an event from the buffer while (readState_.bufferPtr_ < readState_.bufferLen_) { if (readState_.readingSize_) { if (readState_.eventSizeBuffPos_ == 0) { if ((offset_ + readState_.bufferPtr_) / chunkSize_ != ((offset_ + readState_.bufferPtr_ + 3) / chunkSize_)) { // skip one byte towards chunk boundary // T_DEBUG_L(1, "Skipping a byte"); readState_.bufferPtr_++; continue; } } readState_.eventSizeBuff_[readState_.eventSizeBuffPos_++] = readBuff_[readState_.bufferPtr_++]; if (readState_.eventSizeBuffPos_ == 4) { if (readState_.getEventSize() == 0) { // 0 length event indicates padding // T_DEBUG_L(1, "Got padding"); readState_.resetState(readState_.lastDispatchPtr_); continue; } // got a valid event readState_.readingSize_ = false; if (readState_.event_) { delete (readState_.event_); } readState_.event_ = new eventInfo(); readState_.event_->eventSize_ = readState_.getEventSize(); // check if the event is corrupted and perform recovery if required if (isEventCorrupted()) { performRecovery(); // start from the top break; } } } else { if (!readState_.event_->eventBuff_) { readState_.event_->eventBuff_ = new uint8_t[readState_.event_->eventSize_]; readState_.event_->eventBuffPos_ = 0; } // take either the entire event or the remaining bytes in the buffer int reclaimBuffer = (std::min)((uint32_t)(readState_.bufferLen_ - readState_.bufferPtr_), readState_.event_->eventSize_ - readState_.event_->eventBuffPos_); // copy data from read buffer into event buffer memcpy(readState_.event_->eventBuff_ + readState_.event_->eventBuffPos_, readBuff_ + readState_.bufferPtr_, reclaimBuffer); // increment position ptrs readState_.event_->eventBuffPos_ += reclaimBuffer; readState_.bufferPtr_ += reclaimBuffer; // check if the event has been read in full if (readState_.event_->eventBuffPos_ == readState_.event_->eventSize_) { // set the completed event to the current event eventInfo* completeEvent = readState_.event_; completeEvent->eventBuffPos_ = 0; readState_.event_ = nullptr; readState_.resetState(readState_.bufferPtr_); // exit criteria return completeEvent; } } } } } bool TFileTransport::isEventCorrupted() { // an error is triggered if: if ((maxEventSize_ > 0) && (readState_.event_->eventSize_ > maxEventSize_)) { // 1. Event size is larger than user-speficied max-event size T_ERROR("Read corrupt event. Event size(%u) greater than max event size (%u)", readState_.event_->eventSize_, maxEventSize_); return true; } else if (readState_.event_->eventSize_ > chunkSize_) { // 2. Event size is larger than chunk size T_ERROR("Read corrupt event. Event size(%u) greater than chunk size (%u)", readState_.event_->eventSize_, chunkSize_); return true; } else if (((offset_ + readState_.bufferPtr_ - 4) / chunkSize_) != ((offset_ + readState_.bufferPtr_ + readState_.event_->eventSize_ - 1) / chunkSize_)) { // 3. size indicates that event crosses chunk boundary T_ERROR("Read corrupt event. Event crosses chunk boundary. Event size:%u Offset:%lu", readState_.event_->eventSize_, static_cast(offset_ + readState_.bufferPtr_ + 4)); return true; } return false; } void TFileTransport::performRecovery() { // perform some kickass recovery uint32_t curChunk = getCurChunk(); if (lastBadChunk_ == curChunk) { numCorruptedEventsInChunk_++; } else { lastBadChunk_ = curChunk; numCorruptedEventsInChunk_ = 1; } if (numCorruptedEventsInChunk_ < maxCorruptedEvents_) { // maybe there was an error in reading the file from disk // seek to the beginning of chunk and try again seekToChunk(curChunk); } else { // just skip ahead to the next chunk if we not already at the last chunk if (curChunk != (getNumChunks() - 1)) { seekToChunk(curChunk + 1); } else if (readTimeout_ == TAIL_READ_TIMEOUT) { // if tailing the file, wait until there is enough data to start // the next chunk while (curChunk == (getNumChunks() - 1)) { THRIFT_SLEEP_USEC(corruptedEventSleepTime_); } seekToChunk(curChunk + 1); } else { // pretty hosed at this stage, rewind the file back to the last successful // point and punt on the error readState_.resetState(readState_.lastDispatchPtr_); currentEvent_ = nullptr; char errorMsg[1024]; sprintf(errorMsg, "TFileTransport: log file corrupted at offset: %lu", static_cast(offset_ + readState_.lastDispatchPtr_)); TOutput::instance()(errorMsg); throw TTransportException(errorMsg); } } } void TFileTransport::seekToChunk(int32_t chunk) { if (fd_ <= 0) { throw TTransportException("File not open"); } int32_t numChunks = getNumChunks(); // file is empty, seeking to chunk is pointless if (numChunks == 0) { return; } // negative indicates reverse seek (from the end) if (chunk < 0) { chunk += numChunks; } // too large a value for reverse seek, just seek to beginning if (chunk < 0) { T_DEBUG("%s", "Incorrect value for reverse seek. Seeking to beginning..."); chunk = 0; } // cannot seek past EOF bool seekToEnd = false; off_t minEndOffset = 0; if (chunk >= numChunks) { T_DEBUG("%s", "Trying to seek past EOF. Seeking to EOF instead..."); seekToEnd = true; chunk = numChunks - 1; // this is the min offset to process events till minEndOffset = ::THRIFT_LSEEK(fd_, 0, SEEK_END); } off_t newOffset = off_t(chunk) * chunkSize_; offset_ = ::THRIFT_LSEEK(fd_, newOffset, SEEK_SET); readState_.resetAllValues(); currentEvent_ = nullptr; if (offset_ == -1) { TOutput::instance()("TFileTransport: lseek error in seekToChunk"); throw TTransportException("TFileTransport: lseek error in seekToChunk"); } // seek to EOF if user wanted to go to last chunk if (seekToEnd) { uint32_t oldReadTimeout = getReadTimeout(); setReadTimeout(NO_TAIL_READ_TIMEOUT); // keep on reading unti the last event at point of seekChunk call shared_ptr event; while ((offset_ + readState_.bufferPtr_) < minEndOffset) { event.reset(readEvent()); if (event.get() == nullptr) { break; } } setReadTimeout(oldReadTimeout); } } void TFileTransport::seekToEnd() { seekToChunk(getNumChunks()); } uint32_t TFileTransport::getNumChunks() { if (fd_ <= 0) { return 0; } struct THRIFT_STAT f_info; int rv = ::THRIFT_FSTAT(fd_, &f_info); if (rv < 0) { int errno_copy = THRIFT_ERRNO; throw TTransportException(TTransportException::UNKNOWN, "TFileTransport::getNumChunks() (fstat)", errno_copy); } if (f_info.st_size > 0) { size_t numChunks = ((f_info.st_size) / chunkSize_) + 1; if (numChunks > (std::numeric_limits::max)()) throw TTransportException("Too many chunks"); return static_cast(numChunks); } // empty file has no chunks return 0; } uint32_t TFileTransport::getCurChunk() { return static_cast(offset_ / chunkSize_); } // Utility Functions void TFileTransport::openLogFile() { #ifndef _WIN32 mode_t mode = readOnly_ ? S_IRUSR | S_IRGRP | S_IROTH : S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; int flags = readOnly_ ? O_RDONLY : O_RDWR | O_CREAT | O_APPEND; #else int mode = readOnly_ ? _S_IREAD : _S_IREAD | _S_IWRITE; int flags = readOnly_ ? _O_RDONLY : _O_RDWR | _O_CREAT | _O_APPEND; #endif fd_ = ::THRIFT_OPEN(filename_.c_str(), flags, mode); offset_ = 0; // make sure open call was successful if (fd_ == -1) { int errno_copy = THRIFT_ERRNO; TOutput::instance().perror("TFileTransport: openLogFile() ::open() file: " + filename_, errno_copy); throw TTransportException(TTransportException::NOT_OPEN, filename_, errno_copy); } } std::chrono::time_point TFileTransport::getNextFlushTime() { return std::chrono::steady_clock::now() + std::chrono::microseconds(flushMaxUs_); } TFileTransportBuffer::TFileTransportBuffer(uint32_t size) : bufferMode_(WRITE), writePoint_(0), readPoint_(0), size_(size) { buffer_ = new eventInfo* [size]; } TFileTransportBuffer::~TFileTransportBuffer() { if (buffer_) { for (uint32_t i = 0; i < writePoint_; i++) { delete buffer_[i]; } delete[] buffer_; buffer_ = nullptr; } } bool TFileTransportBuffer::addEvent(eventInfo* event) { if (bufferMode_ == READ) { TOutput::instance()("Trying to write to a buffer in read mode"); } if (writePoint_ < size_) { buffer_[writePoint_++] = event; return true; } else { // buffer is full return false; } } eventInfo* TFileTransportBuffer::getNext() { if (bufferMode_ == WRITE) { bufferMode_ = READ; } if (readPoint_ < writePoint_) { return buffer_[readPoint_++]; } else { // no more entries return nullptr; } } void TFileTransportBuffer::reset() { if (bufferMode_ == WRITE || writePoint_ > readPoint_) { T_DEBUG("%s", "Resetting a buffer with unread entries"); } // Clean up the old entries for (uint32_t i = 0; i < writePoint_; i++) { delete buffer_[i]; } bufferMode_ = WRITE; writePoint_ = 0; readPoint_ = 0; } bool TFileTransportBuffer::isFull() { return writePoint_ == size_; } bool TFileTransportBuffer::isEmpty() { return writePoint_ == 0; } TFileProcessor::TFileProcessor(shared_ptr processor, shared_ptr protocolFactory, shared_ptr inputTransport) : processor_(processor), inputProtocolFactory_(protocolFactory), outputProtocolFactory_(protocolFactory), inputTransport_(inputTransport) { // default the output transport to a null transport (common case) outputTransport_ = std::make_shared(); } TFileProcessor::TFileProcessor(shared_ptr processor, shared_ptr inputProtocolFactory, shared_ptr outputProtocolFactory, shared_ptr inputTransport) : processor_(processor), inputProtocolFactory_(inputProtocolFactory), outputProtocolFactory_(outputProtocolFactory), inputTransport_(inputTransport) { // default the output transport to a null transport (common case) outputTransport_ = std::make_shared(); } TFileProcessor::TFileProcessor(shared_ptr processor, shared_ptr protocolFactory, shared_ptr inputTransport, shared_ptr outputTransport) : processor_(processor), inputProtocolFactory_(protocolFactory), outputProtocolFactory_(protocolFactory), inputTransport_(inputTransport), outputTransport_(outputTransport) { } void TFileProcessor::process(uint32_t numEvents, bool tail) { shared_ptr inputProtocol = inputProtocolFactory_->getProtocol(inputTransport_); shared_ptr outputProtocol = outputProtocolFactory_->getProtocol(outputTransport_); // set the read timeout to 0 if tailing is required int32_t oldReadTimeout = inputTransport_->getReadTimeout(); if (tail) { // save old read timeout so it can be restored inputTransport_->setReadTimeout(TFileTransport::TAIL_READ_TIMEOUT); } uint32_t numProcessed = 0; while (1) { // bad form to use exceptions for flow control but there is really // no other way around it try { processor_->process(inputProtocol, outputProtocol, nullptr); numProcessed++; if ((numEvents > 0) && (numProcessed == numEvents)) { return; } } catch (TEOFException&) { if (!tail) { break; } } catch (TException& te) { cerr << te.what() << '\n'; break; } } // restore old read timeout if (tail) { inputTransport_->setReadTimeout(oldReadTimeout); } } void TFileProcessor::processChunk() { shared_ptr inputProtocol = inputProtocolFactory_->getProtocol(inputTransport_); shared_ptr outputProtocol = outputProtocolFactory_->getProtocol(outputTransport_); uint32_t curChunk = inputTransport_->getCurChunk(); while (1) { // bad form to use exceptions for flow control but there is really // no other way around it try { processor_->process(inputProtocol, outputProtocol, nullptr); if (curChunk != inputTransport_->getCurChunk()) { break; } } catch (TEOFException&) { break; } catch (TException& te) { cerr << te.what() << '\n'; break; } } } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/THeaderTransport.h0000664000175000017500000002006115165535636024451 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_THEADERTRANSPORT_H_ #define THRIFT_TRANSPORT_THEADERTRANSPORT_H_ 1 #include #include #include #include #include #include #ifdef HAVE_STDINT_H #include #elif HAVE_INTTYPES_H #include #endif #include #include #include #include enum CLIENT_TYPE { THRIFT_HEADER_CLIENT_TYPE = 0, THRIFT_FRAMED_BINARY = 1, THRIFT_UNFRAMED_BINARY = 2, THRIFT_FRAMED_COMPACT = 3, THRIFT_UNFRAMED_COMPACT = 4, THRIFT_UNKNOWN_CLIENT_TYPE = 5, }; namespace apache { namespace thrift { namespace transport { using apache::thrift::protocol::T_COMPACT_PROTOCOL; /** * Header transport. All writes go into an in-memory buffer until flush is * called, at which point the transport writes the length of the entire * binary chunk followed by the data payload. This allows the receiver on the * other end to always do fixed-length reads. * * Subclass TFramedTransport because most of the read/write methods are similar * and need similar buffers. Major changes are readFrame & flush. * * Header Transport *must* be the same transport for both input and * output when used on the server side - client responses should be * the same protocol as those in the request. */ class THeaderTransport : public TVirtualTransport { public: static const int DEFAULT_BUFFER_SIZE = 512u; static const int THRIFT_MAX_VARINT32_BYTES = 5; /// Use default buffer sizes. explicit THeaderTransport(const std::shared_ptr& transport, std::shared_ptr config = nullptr) : TVirtualTransport(transport, config), outTransport_(transport), protoId(T_COMPACT_PROTOCOL), clientType(THRIFT_HEADER_CLIENT_TYPE), seqId(0), flags(0), tBufSize_(0), tBuf_(nullptr) { if (!transport_) throw std::invalid_argument("transport is empty"); initBuffers(); } THeaderTransport(const std::shared_ptr inTransport, const std::shared_ptr outTransport, std::shared_ptr config = nullptr) : TVirtualTransport(inTransport, config), outTransport_(outTransport), protoId(T_COMPACT_PROTOCOL), clientType(THRIFT_HEADER_CLIENT_TYPE), seqId(0), flags(0), tBufSize_(0), tBuf_(nullptr) { if (!transport_) throw std::invalid_argument("inTransport is empty"); if (!outTransport_) throw std::invalid_argument("outTransport is empty"); initBuffers(); } uint32_t readSlow(uint8_t* buf, uint32_t len) override; void flush() override; void resizeTransformBuffer(uint32_t additionalSize = 0); uint16_t getProtocolId() const; void setProtocolId(uint16_t protoId) { this->protoId = protoId; } void resetProtocol(); /** * We know we got a packet in header format here, try to parse the header * * @param headerSize size of the header portion * @param sz Size of the whole message, including header */ void readHeaderFormat(uint16_t headerSize, uint32_t sz); /** * Untransform the data based on the received header flags * On conclusion of function, setReadBuffer is called with the * untransformed data. * * @param ptr ptr to data * @param size of data */ void untransform(uint8_t* ptr, uint32_t sz); /** * Transform the data based on our write transform flags * At conclusion of function the write buffer is set to the * transformed data. * * @param ptr Ptr to data to transform * @param sz Size of data buffer */ void transform(uint8_t* ptr, uint32_t sz); uint16_t getNumTransforms() const { return safe_numeric_cast(writeTrans_.size()); } void setTransform(uint16_t transId) { writeTrans_.push_back(transId); } // Info headers typedef std::map StringToStringMap; // these work with write headers void setHeader(const std::string& key, const std::string& value); void clearHeaders(); StringToStringMap& getWriteHeaders() { return writeHeaders_; } // these work with read headers const StringToStringMap& getHeaders() const { return readHeaders_; } // accessors for seqId int32_t getSequenceNumber() const { return seqId; } void setSequenceNumber(int32_t seqId) { this->seqId = seqId; } enum TRANSFORMS { ZLIB_TRANSFORM = 0x01, }; protected: /** * Reads a frame of input from the underlying stream. * * Returns true if a frame was read successfully, or false on EOF. * (Raises a TTransportException if EOF occurs after a partial frame.) */ bool readFrame() override; void ensureReadBuffer(uint32_t sz); uint32_t getWriteBytes(); void initBuffers() { setReadBuffer(nullptr, 0); setWriteBuffer(wBuf_.get(), wBufSize_); } std::shared_ptr outTransport_; // 0 and 16th bits must be 0 to differentiate from framed & unframed static const uint32_t HEADER_MAGIC = 0x0FFF0000; static const uint32_t HEADER_MASK = 0xFFFF0000; static const uint32_t FLAGS_MASK = 0x0000FFFF; static const uint32_t MAX_FRAME_SIZE = 0x3FFFFFFF; int16_t protoId; uint16_t clientType; uint32_t seqId; uint16_t flags; std::vector readTrans_; std::vector writeTrans_; // Map to use for headers StringToStringMap readHeaders_; StringToStringMap writeHeaders_; /** * Returns the maximum number of bytes that write k/v headers can take */ uint32_t getMaxWriteHeadersSize() const; struct infoIdType { enum idType { // start at 1 to avoid confusing header padding for an infoId KEYVALUE = 1, END // signal the end of infoIds we can handle }; }; // Buffers to use for transform processing uint32_t tBufSize_; std::unique_ptr tBuf_; void readString(uint8_t*& ptr, /* out */ std::string& str, uint8_t const* headerBoundary); void writeString(uint8_t*& ptr, const std::string& str); // Varint utils /** * Read an i16 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 3 bytes. */ uint32_t readVarint16(uint8_t const* ptr, int16_t* i16, uint8_t const* boundary); /** * 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. */ uint32_t readVarint32(uint8_t const* ptr, int32_t* i32, uint8_t const* boundary); /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. */ uint32_t writeVarint32(int32_t n, uint8_t* pkt); /** * Write an i16 as a varint. Results in 1-3 bytes on the wire. */ uint32_t writeVarint16(int16_t n, uint8_t* pkt); }; /** * Wraps a transport into a header one. * */ class THeaderTransportFactory : public TTransportFactory { public: THeaderTransportFactory() = default; ~THeaderTransportFactory() override = default; /** * Wraps the transport into a header one. */ std::shared_ptr getTransport(std::shared_ptr trans) override { return std::shared_ptr(new THeaderTransport(trans)); } }; } } } // apache::thrift::transport #endif // #ifndef THRIFT_TRANSPORT_THEADERTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/THttpTransport.cpp0000664000175000017500000001422315165535636024536 0ustar00buildbuild00000000000000/* * 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 using std::string; namespace apache { namespace thrift { namespace transport { // Yeah, yeah, hacky to put these here, I know. const char* THttpTransport::CRLF = "\r\n"; const int THttpTransport::CRLF_LEN = 2; THttpTransport::THttpTransport(std::shared_ptr transport, std::shared_ptr config) : TVirtualTransport(config), transport_(transport), origin_(""), readHeaders_(true), chunked_(false), chunkedDone_(false), chunkSize_(0), contentLength_(0), httpBuf_(nullptr), httpPos_(0), httpBufLen_(0), httpBufSize_(1024) { init(); } void THttpTransport::init() { httpBuf_ = (char*)std::malloc(httpBufSize_ + 1); if (httpBuf_ == nullptr) { throw std::bad_alloc(); } httpBuf_[httpBufLen_] = '\0'; } THttpTransport::~THttpTransport() { if (httpBuf_ != nullptr) { std::free(httpBuf_); } } uint32_t THttpTransport::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); if (readBuffer_.available_read() == 0) { readBuffer_.resetBuffer(); uint32_t got = readMoreData(); if (got == 0) { return 0; } } return readBuffer_.read(buf, len); } uint32_t THttpTransport::readEnd() { // Read any pending chunked data (footers etc.) if (chunked_) { while (!chunkedDone_) { readChunked(); } } return 0; } uint32_t THttpTransport::readMoreData() { uint32_t size; if (httpPos_ == httpBufLen_) { // Get more data! refill(); } if (readHeaders_) { readHeaders(); } if (chunked_) { size = readChunked(); } else { size = readContent(contentLength_); readHeaders_ = true; } return size; } uint32_t THttpTransport::readChunked() { uint32_t length = 0; char* line = readLine(); uint32_t chunkSize = parseChunkSize(line); if (chunkSize == 0) { readChunkedFooters(); } else { // Read data content length += readContent(chunkSize); // Read trailing CRLF after content readLine(); } return length; } void THttpTransport::readChunkedFooters() { // End of data, read footer lines until a blank one appears while (true) { char* line = readLine(); if (strlen(line) == 0) { chunkedDone_ = true; break; } } } uint32_t THttpTransport::parseChunkSize(char* line) { char* semi = strchr(line, ';'); if (semi != nullptr) { *semi = '\0'; } uint32_t size = 0; sscanf(line, "%x", &size); return size; } uint32_t THttpTransport::readContent(uint32_t size) { uint32_t need = size; while (need > 0) { uint32_t avail = httpBufLen_ - httpPos_; if (avail == 0) { // We have given all the data, reset position to head of the buffer httpPos_ = 0; httpBufLen_ = 0; refill(); // Now have available however much we read avail = httpBufLen_; } uint32_t give = avail; if (need < give) { give = need; } readBuffer_.write((uint8_t*)(httpBuf_ + httpPos_), give); httpPos_ += give; need -= give; } return size; } char* THttpTransport::readLine() { while (true) { char* eol = nullptr; eol = strstr(httpBuf_ + httpPos_, CRLF); // No CRLF yet? if (eol == nullptr) { // Shift whatever we have now to front and refill shift(); refill(); } else { // Return pointer to next line *eol = '\0'; char* line = httpBuf_ + httpPos_; httpPos_ = static_cast((eol - httpBuf_) + CRLF_LEN); return line; } } } void THttpTransport::shift() { if (httpBufLen_ > httpPos_) { // Shift down remaining data and read more uint32_t length = httpBufLen_ - httpPos_; memmove(httpBuf_, httpBuf_ + httpPos_, length); httpBufLen_ = length; } else { httpBufLen_ = 0; } httpPos_ = 0; httpBuf_[httpBufLen_] = '\0'; } void THttpTransport::refill() { uint32_t avail = httpBufSize_ - httpBufLen_; if (avail <= (httpBufSize_ / 4)) { httpBufSize_ *= 2; char* tmpBuf = (char*)std::realloc(httpBuf_, httpBufSize_ + 1); if (tmpBuf == nullptr) { throw std::bad_alloc(); } httpBuf_ = tmpBuf; } // Read more data uint32_t got = transport_->read((uint8_t*)(httpBuf_ + httpBufLen_), httpBufSize_ - httpBufLen_); httpBufLen_ += got; httpBuf_[httpBufLen_] = '\0'; if (got == 0) { throw TTransportException(TTransportException::END_OF_FILE, "Could not refill buffer"); } } void THttpTransport::readHeaders() { // Initialize headers state variables contentLength_ = 0; chunked_ = false; chunkedDone_ = false; chunkSize_ = 0; // Control state flow bool statusLine = true; bool finished = false; // Loop until headers are finished while (true) { char* line = readLine(); if (strlen(line) == 0) { if (finished) { readHeaders_ = false; return; } else { // Must have been an HTTP 100, keep going for another status line statusLine = true; } } else { if (statusLine) { statusLine = false; finished = parseStatusLine(line); } else { parseHeader(line); } } } } void THttpTransport::write(const uint8_t* buf, uint32_t len) { writeBuffer_.write(buf, len); } const std::string THttpTransport::getOrigin() const { std::ostringstream oss; if (!origin_.empty()) { oss << origin_ << ", "; } oss << transport_->getOrigin(); return oss.str(); } } } } thrift-0.23.0/lib/cpp/src/thrift/transport/THttpClient.h0000664000175000017500000000433615165535636023431 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_THTTPCLIENT_H_ #define _THRIFT_TRANSPORT_THTTPCLIENT_H_ 1 #include namespace apache { namespace thrift { namespace transport { /** * @brief Client transport using HTTP. The path is an optional field that is * not required by Thrift HTTP server or client. It can be used i.e. with HTTP * redirection, load balancing or forwarding on the server. */ class THttpClient : public THttpTransport { public: /** * @brief Constructor that wraps an existing transport, but also sets the * host and path. The host and path are not used for the connection but are * set in the HTTP header of the transport. */ THttpClient(std::shared_ptr transport, std::string host = "localhost", std::string path = "/service", std::shared_ptr config = nullptr); /** * @brief Constructor that will create a new socket transport using the host * and port. */ THttpClient(std::string host, int port, std::string path = "", std::shared_ptr config = nullptr); ~THttpClient() override; void flush() override; void setPath(std::string path); protected: std::string host_; std::string path_; void parseHeader(char* header) override; bool parseStatusLine(char* status) override; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_THTTPCLIENT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TTransportException.h0000664000175000017500000000637115165535636025227 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TTRANSPORTEXCEPTION_H_ #define _THRIFT_TRANSPORT_TTRANSPORTEXCEPTION_H_ 1 #include #include #include namespace apache { namespace thrift { namespace transport { /** * Class to encapsulate all the possible types of transport errors that may * occur in various transport systems. This provides a sort of generic * wrapper around the vague UNIX E_ error codes that lets a common code * base of error handling to be used for various types of transports, i.e. * pipes etc. * */ class TTransportException : public apache::thrift::TException { public: /** * Error codes for the various types of exceptions. */ enum TTransportExceptionType { UNKNOWN = 0, NOT_OPEN = 1, TIMED_OUT = 2, END_OF_FILE = 3, INTERRUPTED = 4, BAD_ARGS = 5, CORRUPTED_DATA = 6, INTERNAL_ERROR = 7, CLIENT_DISCONNECT = 8 }; TTransportException() : apache::thrift::TException(), type_(UNKNOWN) {} TTransportException(TTransportExceptionType type) : apache::thrift::TException(), type_(type) {} TTransportException(const std::string& message) : apache::thrift::TException(message), type_(UNKNOWN) {} TTransportException(TTransportExceptionType type, const std::string& message) : apache::thrift::TException(message), type_(type) {} TTransportException(TTransportExceptionType type, const std::string& message, int errno_copy) : apache::thrift::TException(message + ": " + TOutput::strerror_s(errno_copy)), type_(type) {} ~TTransportException() noexcept override = default; /** * Returns an error code that provides information about the type of error * that has occurred. * * @return Error code */ TTransportExceptionType getType() const noexcept { return type_; } const char* what() const noexcept override; protected: /** Just like strerror_r but returns a C++ string object. */ std::string strerror_s(int errno_copy); /** Error code */ TTransportExceptionType type_; }; /** * Legacy code in transport implementations have overflow issues * that need to be enforced. */ template To safe_numeric_cast(From i) { try { return boost::numeric_cast(i); } catch (const std::bad_cast& bc) { throw TTransportException(TTransportException::CORRUPTED_DATA, bc.what()); } } } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TTRANSPORTEXCEPTION_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TPipeServer.cpp0000664000175000017500000004106215167543515023764 0ustar00buildbuild00000000000000/* * 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 #ifdef _WIN32 #include #include #include #include #include #endif //_WIN32 namespace apache { namespace thrift { namespace transport { #ifdef _WIN32 using std::shared_ptr; class TPipeServerImpl : apache::thrift::TNonCopyable { public: TPipeServerImpl() {} virtual ~TPipeServerImpl() {} virtual void interrupt() = 0; virtual std::shared_ptr acceptImpl() = 0; virtual HANDLE getPipeHandle() = 0; virtual HANDLE getWrtPipeHandle() = 0; virtual HANDLE getClientRdPipeHandle() = 0; virtual HANDLE getClientWrtPipeHandle() = 0; virtual HANDLE getNativeWaitHandle() { return nullptr; } }; class TAnonPipeServer : public TPipeServerImpl { public: TAnonPipeServer() { // The anonymous pipe needs to be created first so that the server can // pass the handles on to the client before the serve (acceptImpl) // blocking call. if (!createAnonPipe()) { TOutput::instance().perror("TPipeServer Create(Anon)Pipe failed, GLE=", GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer Create(Anon)Pipe failed"); } } virtual ~TAnonPipeServer() { PipeR_.reset(); PipeW_.reset(); ClientAnonRead_.reset(); ClientAnonWrite_.reset(); } virtual void interrupt() {} // not currently implemented virtual std::shared_ptr acceptImpl(); virtual HANDLE getPipeHandle() { return PipeR_.h; } virtual HANDLE getWrtPipeHandle() { return PipeW_.h; } virtual HANDLE getClientRdPipeHandle() { return ClientAnonRead_.h; } virtual HANDLE getClientWrtPipeHandle() { return ClientAnonWrite_.h; } private: bool createAnonPipe(); TAutoHandle PipeR_; // Anonymous Pipe (R) TAutoHandle PipeW_; // Anonymous Pipe (W) // Client side anonymous pipe handles //? Do we need duplicates to send to client? TAutoHandle ClientAnonRead_; TAutoHandle ClientAnonWrite_; }; class TNamedPipeServer : public TPipeServerImpl { public: TNamedPipeServer(const std::string& pipename, uint32_t bufsize, uint32_t maxconnections, const std::string& securityDescriptor) : stopping_(false), pipename_(pipename), bufsize_(bufsize), maxconns_(maxconnections), securityDescriptor_(securityDescriptor) { connectOverlap_.action = TOverlappedWorkItem::CONNECT; cancelOverlap_.action = TOverlappedWorkItem::CANCELIO; TAutoCrit lock(pipe_protect_); initiateNamedConnect(lock); } virtual ~TNamedPipeServer() {} virtual void interrupt() { TAutoCrit lock(pipe_protect_); cached_client_.reset(); if (Pipe_.h != INVALID_HANDLE_VALUE) { stopping_ = true; cancelOverlap_.h = Pipe_.h; // This should wake up GetOverlappedResult thread_->addWorkItem(&cancelOverlap_); } } virtual std::shared_ptr acceptImpl(); virtual HANDLE getPipeHandle() { return Pipe_.h; } virtual HANDLE getWrtPipeHandle() { return INVALID_HANDLE_VALUE; } virtual HANDLE getClientRdPipeHandle() { return INVALID_HANDLE_VALUE; } virtual HANDLE getClientWrtPipeHandle() { return INVALID_HANDLE_VALUE; } virtual HANDLE getNativeWaitHandle() { return listen_event_.h; } private: bool createNamedPipe(const TAutoCrit &lockProof); void initiateNamedConnect(const TAutoCrit &lockProof); TAutoOverlapThread thread_; TOverlappedWorkItem connectOverlap_; TOverlappedWorkItem cancelOverlap_; bool stopping_; std::string pipename_; std::string securityDescriptor_; uint32_t bufsize_; uint32_t maxconns_; TManualResetEvent listen_event_; TCriticalSection pipe_protect_; // only read or write these variables underneath a locked pipe_protect_ std::shared_ptr cached_client_; TAutoHandle Pipe_; }; HANDLE TPipeServer::getNativeWaitHandle() { if (impl_) return impl_->getNativeWaitHandle(); return nullptr; } //---- Constructors ---- TPipeServer::TPipeServer(const std::string& pipename, uint32_t bufsize) : bufsize_(bufsize), isAnonymous_(false) { setMaxConnections(TPIPE_SERVER_MAX_CONNS_DEFAULT); setPipename(pipename); setSecurityDescriptor(DEFAULT_PIPE_SECURITY); } TPipeServer::TPipeServer(const std::string& pipename, uint32_t bufsize, uint32_t maxconnections) : bufsize_(bufsize), isAnonymous_(false) { setMaxConnections(maxconnections); setPipename(pipename); setSecurityDescriptor(DEFAULT_PIPE_SECURITY); } TPipeServer::TPipeServer(const std::string& pipename, uint32_t bufsize, uint32_t maxconnections, const std::string& securityDescriptor) : bufsize_(bufsize), isAnonymous_(false) { setMaxConnections(maxconnections); setPipename(pipename); setSecurityDescriptor(securityDescriptor); } TPipeServer::TPipeServer(const std::string& pipename) : bufsize_(1024), isAnonymous_(false) { setMaxConnections(TPIPE_SERVER_MAX_CONNS_DEFAULT); setPipename(pipename); setSecurityDescriptor(DEFAULT_PIPE_SECURITY); } TPipeServer::TPipeServer(int bufsize) : bufsize_(bufsize), isAnonymous_(true) { setMaxConnections(1); impl_.reset(new TAnonPipeServer); } TPipeServer::TPipeServer() : bufsize_(1024), isAnonymous_(true) { setMaxConnections(1); impl_.reset(new TAnonPipeServer); } //---- Destructor ---- TPipeServer::~TPipeServer() {} bool TPipeServer::isOpen() const { return (impl_->getPipeHandle() != INVALID_HANDLE_VALUE); } //--------------------------------------------------------- // Transport callbacks //--------------------------------------------------------- void TPipeServer::listen() { if (isAnonymous_) return; impl_.reset(new TNamedPipeServer(pipename_, bufsize_, maxconns_, securityDescriptor_)); } shared_ptr TPipeServer::acceptImpl() { return impl_->acceptImpl(); } shared_ptr TAnonPipeServer::acceptImpl() { // This 0-byte read serves merely as a blocking call. byte buf; DWORD br; int fSuccess = ReadFile(PipeR_.h, // pipe handle &buf, // buffer to receive reply 0, // size of buffer &br, // number of bytes read nullptr); // not overlapped if (!fSuccess && GetLastError() != ERROR_MORE_DATA) { TOutput::instance().perror("TPipeServer unable to initiate pipe comms, GLE=", GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer unable to initiate pipe comms"); } shared_ptr client(new TPipe(PipeR_.h, PipeW_.h)); return client; } void TNamedPipeServer::initiateNamedConnect(const TAutoCrit &lockProof) { if (stopping_) return; if (!createNamedPipe(lockProof)) { TOutput::instance().perror("TPipeServer CreateNamedPipe failed, GLE=", GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer CreateNamedPipe failed"); } // The prior connection has been handled, so close the gate ResetEvent(listen_event_.h); connectOverlap_.reset(nullptr, 0, listen_event_.h); connectOverlap_.h = Pipe_.h; thread_->addWorkItem(&connectOverlap_); // Wait for the client to connect; if it succeeds, the // function returns a nonzero value. If the function returns // zero, GetLastError should return ERROR_PIPE_CONNECTED. if (connectOverlap_.success) { TOutput::instance().printf("Client connected."); cached_client_.reset(new TPipe(Pipe_)); // make sure people know that a connection is ready SetEvent(listen_event_.h); return; } DWORD dwErr = connectOverlap_.last_error; switch (dwErr) { case ERROR_PIPE_CONNECTED: TOutput::instance().printf("Client connected."); cached_client_.reset(new TPipe(Pipe_)); // make sure people know that a connection is ready SetEvent(listen_event_.h); return; case ERROR_IO_PENDING: return; // acceptImpl will do the appropriate WaitForMultipleObjects default: TOutput::instance().perror("TPipeServer ConnectNamedPipe failed, GLE=", dwErr); throw TTransportException(TTransportException::NOT_OPEN, " TPipeServer ConnectNamedPipe failed"); } } shared_ptr TNamedPipeServer::acceptImpl() { { TAutoCrit lock(pipe_protect_); if (cached_client_.get() != nullptr) { shared_ptr client; // zero out cached_client, since we are about to return it. client.swap(cached_client_); // kick off the next connection before returning initiateNamedConnect(lock); return client; // success! } } if (Pipe_.h == INVALID_HANDLE_VALUE) { throw TTransportException(TTransportException::NOT_OPEN, "TNamedPipeServer: someone called accept on a closed pipe server"); } DWORD dwDummy = 0; // For the most part, Pipe_ should be protected with pipe_protect_. We can't // reasonably do that here though without breaking interruptability. However, // this should be safe, though I'm not happy about it. We only need to ensure // that no one writes / modifies Pipe_.h while we are reading it. Well, the // only two things that should be modifying Pipe_ are acceptImpl, the // functions it calls, and the destructor. Those things shouldn't be run // concurrently anyway. So this call is 'really' just a read that may happen // concurrently with interrupt, and that should be fine. if (GetOverlappedResult(Pipe_.h, &connectOverlap_.overlap, &dwDummy, TRUE)) { TAutoCrit lock(pipe_protect_); shared_ptr client; try { client.reset(new TPipe(Pipe_)); } catch (TTransportException& ttx) { if (ttx.getType() == TTransportException::INTERRUPTED) { throw; } TOutput::instance().perror("Client connection failed. TTransportExceptionType=", ttx.getType()); // kick off the next connection before throwing initiateNamedConnect(lock); throw TTransportException(TTransportException::CLIENT_DISCONNECT, ttx.what()); } TOutput::instance().printf("Client connected."); // kick off the next connection before returning initiateNamedConnect(lock); return client; // success! } // if we got here, then we are in an error / shutdown case DWORD gle = GetLastError(); // save error before doing cleanup TOutput::instance().perror("TPipeServer ConnectNamedPipe GLE=", gle); if(gle == ERROR_OPERATION_ABORTED) { TAutoCrit lock(pipe_protect_); // Needed to insure concurrent thread to be out of interrupt. throw TTransportException(TTransportException::INTERRUPTED, "TPipeServer: server interupted"); } throw TTransportException(TTransportException::NOT_OPEN, "TPipeServer: client connection failed"); } void TPipeServer::interrupt() { if (impl_) impl_->interrupt(); } void TPipeServer::close() { impl_.reset(); } bool TNamedPipeServer::createNamedPipe(const TAutoCrit& /*lockProof*/) { PSECURITY_DESCRIPTOR psd = nullptr; ULONG size = 0; if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(securityDescriptor_.c_str(), SDDL_REVISION_1, &psd, &size)) { DWORD lastError = GetLastError(); TOutput::instance().perror("TPipeServer::ConvertStringSecurityDescriptorToSecurityDescriptorA() GLE=", lastError); throw TTransportException( TTransportException::NOT_OPEN, "TPipeServer::ConvertStringSecurityDescriptorToSecurityDescriptorA() failed", lastError); } SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = psd; sa.bInheritHandle = FALSE; // Create an instance of the named pipe TAutoHandle hPipe(CreateNamedPipeA(pipename_.c_str(), // pipe name PIPE_ACCESS_DUPLEX | // read/write access FILE_FLAG_OVERLAPPED, // async mode PIPE_TYPE_BYTE | // byte type pipe PIPE_READMODE_BYTE, // byte read mode maxconns_, // max. instances bufsize_, // output buffer size bufsize_, // input buffer size 0, // client time-out &sa)); // security attributes auto lastError = GetLastError(); if (psd) LocalFree(psd); if (hPipe.h == INVALID_HANDLE_VALUE) { Pipe_.reset(); TOutput::instance().perror("TPipeServer::TCreateNamedPipe() GLE=", lastError); throw TTransportException(TTransportException::NOT_OPEN, "TCreateNamedPipe() failed", lastError); } Pipe_.reset(hPipe.release()); return true; } bool TAnonPipeServer::createAnonPipe() { SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; // security information for pipes if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { TOutput::instance().perror("TPipeServer InitializeSecurityDescriptor (anon) failed, GLE=", GetLastError()); return false; } if (!SetSecurityDescriptorDacl(&sd, true, nullptr, false)) { TOutput::instance().perror("TPipeServer SetSecurityDescriptorDacl (anon) failed, GLE=", GetLastError()); return false; } sa.lpSecurityDescriptor = &sd; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; // allow passing handle to child HANDLE ClientAnonReadH, PipeW_H, ClientAnonWriteH, Pipe_H; if (!CreatePipe(&ClientAnonReadH, &PipeW_H, &sa, 0)) // create stdin pipe { TOutput::instance().perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); return false; } if (!CreatePipe(&Pipe_H, &ClientAnonWriteH, &sa, 0)) // create stdout pipe { TOutput::instance().perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); CloseHandle(ClientAnonReadH); CloseHandle(PipeW_H); return false; } ClientAnonRead_.reset(ClientAnonReadH); ClientAnonWrite_.reset(ClientAnonWriteH); PipeR_.reset(Pipe_H); PipeW_.reset(PipeW_H); return true; } //--------------------------------------------------------- // Accessors //--------------------------------------------------------- std::string TPipeServer::getPipename() { return pipename_; } void TPipeServer::setPipename(const std::string& pipename) { if (pipename.find("\\\\") == std::string::npos) pipename_ = "\\\\.\\pipe\\" + pipename; else pipename_ = pipename; } int TPipeServer::getBufferSize() { return bufsize_; } void TPipeServer::setBufferSize(int bufsize) { bufsize_ = bufsize; } HANDLE TPipeServer::getPipeHandle() { return impl_ ? impl_->getPipeHandle() : INVALID_HANDLE_VALUE; } HANDLE TPipeServer::getWrtPipeHandle() { return impl_ ? impl_->getWrtPipeHandle() : INVALID_HANDLE_VALUE; } HANDLE TPipeServer::getClientRdPipeHandle() { return impl_ ? impl_->getClientRdPipeHandle() : INVALID_HANDLE_VALUE; } HANDLE TPipeServer::getClientWrtPipeHandle() { return impl_ ? impl_->getClientWrtPipeHandle() : INVALID_HANDLE_VALUE; } bool TPipeServer::getAnonymous() { return isAnonymous_; } void TPipeServer::setAnonymous(bool anon) { isAnonymous_ = anon; } void TPipeServer::setSecurityDescriptor(const std::string& securityDescriptor) { securityDescriptor_ = securityDescriptor; } void TPipeServer::setMaxConnections(uint32_t maxconnections) { if (maxconnections == 0) maxconns_ = 1; else if (maxconnections > PIPE_UNLIMITED_INSTANCES) maxconns_ = PIPE_UNLIMITED_INSTANCES; else maxconns_ = maxconnections; } #endif //_WIN32 } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TZlibTransport.h0000664000175000017500000001631615165535636024171 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TZLIBTRANSPORT_H_ #define _THRIFT_TRANSPORT_TZLIBTRANSPORT_H_ 1 #include #include #include #include struct z_stream_s; namespace apache { namespace thrift { namespace transport { class TZlibTransportException : public TTransportException { public: TZlibTransportException(int status, const char* msg) : TTransportException(TTransportException::INTERNAL_ERROR, errorMessage(status, msg)), zlib_status_(status), zlib_msg_(msg == nullptr ? "(null)" : msg) {} ~TZlibTransportException() noexcept override = default; int getZlibStatus() { return zlib_status_; } std::string getZlibMessage() { return zlib_msg_; } static std::string errorMessage(int status, const char* msg) { std::string rv = "zlib error: "; if (msg) { rv += msg; } else { rv += "(no message)"; } rv += " (status = "; rv += to_string(status); rv += ")"; return rv; } int zlib_status_; std::string zlib_msg_; }; /** * This transport uses zlib to compress on write and decompress on read * * TODO(dreiss): Don't do an extra copy of the compressed data if * the underlying transport is TBuffered or TMemory. * */ class TZlibTransport : public TVirtualTransport { public: /** * @param transport The transport to read compressed data from * and write compressed data to. * @param urbuf_size Uncompressed buffer size for reading. * @param crbuf_size Compressed buffer size for reading. * @param uwbuf_size Uncompressed buffer size for writing. * @param cwbuf_size Compressed buffer size for writing. * @param comp_level Compression level (0=none[fast], 6=default, 9=max[slow]). */ TZlibTransport(std::shared_ptr transport, int urbuf_size = DEFAULT_URBUF_SIZE, int crbuf_size = DEFAULT_CRBUF_SIZE, int uwbuf_size = DEFAULT_UWBUF_SIZE, int cwbuf_size = DEFAULT_CWBUF_SIZE, int16_t comp_level = Z_DEFAULT_COMPRESSION, std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(transport), urpos_(0), uwpos_(0), input_ended_(false), output_finished_(false), urbuf_size_(urbuf_size), crbuf_size_(crbuf_size), uwbuf_size_(uwbuf_size), cwbuf_size_(cwbuf_size), urbuf_(nullptr), crbuf_(nullptr), uwbuf_(nullptr), cwbuf_(nullptr), rstream_(nullptr), wstream_(nullptr), comp_level_(comp_level) { if (uwbuf_size_ < MIN_DIRECT_DEFLATE_SIZE) { // Have to copy this into a local because of a linking issue. int minimum = MIN_DIRECT_DEFLATE_SIZE; throw TTransportException(TTransportException::BAD_ARGS, "TZLibTransport: uncompressed write buffer must be at least" + to_string(minimum) + "."); } try { urbuf_ = new uint8_t[urbuf_size]; crbuf_ = new uint8_t[crbuf_size]; uwbuf_ = new uint8_t[uwbuf_size]; cwbuf_ = new uint8_t[cwbuf_size]; // Don't call this outside of the constructor. initZlib(); } catch (...) { delete[] urbuf_; delete[] crbuf_; delete[] uwbuf_; delete[] cwbuf_; throw; } } // Don't call this outside of the constructor. void initZlib(); /** * TZlibTransport destructor. * * Warning: Destroying a TZlibTransport object may discard any written but * unflushed data. You must explicitly call flush() or finish() to ensure * that data is actually written and flushed to the underlying transport. */ ~TZlibTransport() override; bool isOpen() const override; bool peek() override; void open() override { transport_->open(); } void close() override { transport_->close(); } uint32_t read(uint8_t* buf, uint32_t len); void write(const uint8_t* buf, uint32_t len); void flush() override; /** * Finalize the zlib stream. * * This causes zlib to flush any pending write data and write end-of-stream * information, including the checksum. Once finish() has been called, no * new data can be written to the stream. */ void finish(); const uint8_t* borrow(uint8_t* buf, uint32_t* len); void consume(uint32_t len); /** * Verify the checksum at the end of the zlib stream. * * This may only be called after all data has been read. * It verifies the checksum that was written by the finish() call. */ void verifyChecksum(); /** * TODO(someone_smart): Choose smart defaults. */ static const int DEFAULT_URBUF_SIZE = 128; static const int DEFAULT_CRBUF_SIZE = 1024; static const int DEFAULT_UWBUF_SIZE = 128; static const int DEFAULT_CWBUF_SIZE = 1024; std::shared_ptr getUnderlyingTransport() const { return transport_; } protected: inline void checkZlibRv(int status, const char* msg); inline void checkZlibRvNothrow(int status, const char* msg); inline int readAvail() const; void flushToTransport(int flush); void flushToZlib(const uint8_t* buf, int len, int flush); bool readFromZlib(); protected: // Writes smaller than this are buffered up. // Larger (or equal) writes are dumped straight to zlib. static const uint32_t MIN_DIRECT_DEFLATE_SIZE = 32; std::shared_ptr transport_; int urpos_; int uwpos_; /// True iff zlib has reached the end of the input stream. bool input_ended_; /// True iff we have finished the output stream. bool output_finished_; uint32_t urbuf_size_; uint32_t crbuf_size_; uint32_t uwbuf_size_; uint32_t cwbuf_size_; uint8_t* urbuf_; uint8_t* crbuf_; uint8_t* uwbuf_; uint8_t* cwbuf_; struct z_stream_s* rstream_; struct z_stream_s* wstream_; const int comp_level_; }; /** * Wraps a transport into a zlibbed one. * */ class TZlibTransportFactory : public TTransportFactory { public: TZlibTransportFactory() = default; /** * Wraps a transport factory into a zlibbed one. */ TZlibTransportFactory(std::shared_ptr transportFactory); ~TZlibTransportFactory() override = default; std::shared_ptr getTransport(std::shared_ptr trans) override; protected: std::shared_ptr transportFactory_; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TZLIBTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TBufferTransports.cpp0000664000175000017500000003301015167543515025203 0ustar00buildbuild00000000000000/* * 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 using std::string; namespace apache { namespace thrift { namespace transport { uint32_t TBufferedTransport::readSlow(uint8_t* buf, uint32_t len) { auto have = static_cast(rBound_ - rBase_); // We should only take the slow path if we can't satisfy the read // with the data already in the buffer. assert(have < len); // If we have some data in the buffer, copy it out and return it. // We have to return it without attempting to read more, since we aren't // guaranteed that the underlying transport actually has more data, so // attempting to read from it could block. if (have > 0) { memcpy(buf, rBase_, have); setReadBuffer(rBuf_.get(), 0); return have; } // No data is available in our buffer. // Get more from underlying transport up to buffer size. // Note that this makes a lot of sense if len < rBufSize_ // and almost no sense otherwise. TODO(dreiss): Fix that // case (possibly including some readv hotness). setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_)); // Hand over whatever we have. uint32_t give = (std::min)(len, static_cast(rBound_ - rBase_)); memcpy(buf, rBase_, give); rBase_ += give; return give; } void TBufferedTransport::writeSlow(const uint8_t* buf, uint32_t len) { auto have_bytes = static_cast(wBase_ - wBuf_.get()); auto space = static_cast(wBound_ - wBase_); // We should only take the slow path if we can't accommodate the write // with the free space already in the buffer. assert(wBound_ - wBase_ < static_cast(len)); // Now here's the tricky question: should we copy data from buf into our // internal buffer and write it from there, or should we just write out // the current internal buffer in one syscall and write out buf in another. // If our currently buffered data plus buf is at least double our buffer // size, we will have to do two syscalls no matter what (except in the // degenerate case when our buffer is empty), so there is no use copying. // Otherwise, there is sort of a sliding scale. If we have N-1 bytes // buffered and need to write 2, it would be crazy to do two syscalls. // On the other hand, if we have 2 bytes buffered and are writing 2N-3, // we can save a syscall in the short term by loading up our buffer, writing // it out, and copying the rest of the bytes into our buffer. Of course, // if we get another 2-byte write, we haven't saved any syscalls at all, // and have just copied nearly 2N bytes for nothing. Finding a perfect // policy would require predicting the size of future writes, so we're just // going to always eschew syscalls if we have less than 2N bytes to write. // The case where we have to do two syscalls. // This case also covers the case where the buffer is empty, // but it is clearer (I think) to think of it as two separate cases. if ((have_bytes + len >= 2 * wBufSize_) || (have_bytes == 0)) { // TODO(dreiss): writev if (have_bytes > 0) { transport_->write(wBuf_.get(), have_bytes); } transport_->write(buf, len); wBase_ = wBuf_.get(); return; } // Fill up our internal buffer for a write. memcpy(wBase_, buf, space); buf += space; len -= space; transport_->write(wBuf_.get(), wBufSize_); // Copy the rest into our buffer. assert(len < wBufSize_); memcpy(wBuf_.get(), buf, len); wBase_ = wBuf_.get() + len; return; } const uint8_t* TBufferedTransport::borrowSlow(uint8_t* buf, uint32_t* len) { (void)buf; (void)len; // Simply return nullptr. We don't know if there is actually data available on // the underlying transport, so calling read() might block. return nullptr; } void TBufferedTransport::flush() { resetConsumedMessageSize(); // Write out any data waiting in the write buffer. auto have_bytes = static_cast(wBase_ - wBuf_.get()); if (have_bytes > 0) { // Note that we reset wBase_ prior to the underlying write // to ensure we're in a sane state (i.e. internal buffer cleaned) // if the underlying write throws up an exception wBase_ = wBuf_.get(); transport_->write(wBuf_.get(), have_bytes); } // Flush the underlying transport. transport_->flush(); } uint32_t TFramedTransport::readSlow(uint8_t* buf, uint32_t len) { uint32_t want = len; auto have = static_cast(rBound_ - rBase_); // We should only take the slow path if we can't satisfy the read // with the data already in the buffer. assert(have < want); // If we have some data in the buffer, copy it out and return it. // We have to return it without attempting to read more, since we aren't // guaranteed that the underlying transport actually has more data, so // attempting to read from it could block. if (have > 0) { memcpy(buf, rBase_, have); setReadBuffer(rBuf_.get(), 0); return have; } // Read another frame. if (!readFrame()) { // EOF. No frame available. return 0; } // TODO(dreiss): Should we warn when reads cross frames? // Hand over whatever we have. uint32_t give = (std::min)(want, static_cast(rBound_ - rBase_)); memcpy(buf, rBase_, give); rBase_ += give; want -= give; return (len - want); } bool TFramedTransport::readFrame() { // TODO(dreiss): Think about using readv here, even though it would // result in (gasp) read-ahead. // Read the size of the next frame. // We can't use readAll(&sz, sizeof(sz)), since that always throws an // exception on EOF. We want to throw an exception only if EOF occurs after // partial size data. int32_t sz = -1; uint32_t size_bytes_read = 0; while (size_bytes_read < sizeof(sz)) { uint8_t* szp = reinterpret_cast(&sz) + size_bytes_read; uint32_t bytes_read = transport_->read(szp, static_cast(sizeof(sz)) - size_bytes_read); if (bytes_read == 0) { if (size_bytes_read == 0) { // EOF before any data was read. return false; } else { // EOF after a partial frame header. Raise an exception. throw TTransportException(TTransportException::END_OF_FILE, "No more data to read after " "partial frame header."); } } size_bytes_read += bytes_read; } sz = ntohl(sz); if (sz < 0) { throw TTransportException("Frame size has negative value"); } // Check for oversized frame if (sz > static_cast(maxFrameSize_)) throw TTransportException(TTransportException::CORRUPTED_DATA, "Received an oversized frame"); // Read the frame payload, and reset markers. if (sz > static_cast(rBufSize_)) { rBuf_.reset(new uint8_t[sz]); rBufSize_ = sz; } transport_->readAll(rBuf_.get(), sz); setReadBuffer(rBuf_.get(), sz); return true; } void TFramedTransport::writeSlow(const uint8_t* buf, uint32_t len) { // Double buffer size until sufficient. auto have = static_cast(wBase_ - wBuf_.get()); uint32_t new_size = wBufSize_; if (len + have < have /* overflow */ || len + have > 0x7fffffff) { throw TTransportException(TTransportException::BAD_ARGS, "Attempted to write over 2 GB to TFramedTransport."); } while (new_size < len + have) { new_size = new_size > 0 ? new_size * 2 : 1; } // TODO(dreiss): Consider modifying this class to use malloc/free // so we can use realloc here. // Allocate new buffer. auto* new_buf = new uint8_t[new_size]; // Copy the old buffer to the new one. memcpy(new_buf, wBuf_.get(), have); // Now point buf to the new one. wBuf_.reset(new_buf); wBufSize_ = new_size; wBase_ = wBuf_.get() + have; wBound_ = wBuf_.get() + wBufSize_; // Copy the data into the new buffer. memcpy(wBase_, buf, len); wBase_ += len; } void TFramedTransport::flush() { resetConsumedMessageSize(); int32_t sz_hbo, sz_nbo; assert(wBufSize_ > sizeof(sz_nbo)); // Slip the frame size into the start of the buffer. sz_hbo = static_cast(wBase_ - (wBuf_.get() + 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) // prior to the underlying write to ensure we're in a sane state // (i.e. internal buffer cleaned) if the underlying write throws // up an exception wBase_ = wBuf_.get() + sizeof(sz_nbo); // Write size and frame body. transport_->write(wBuf_.get(), static_cast(sizeof(sz_nbo)) + sz_hbo); } // Flush the underlying transport. transport_->flush(); // reclaim write buffer if (wBufSize_ > bufReclaimThresh_) { wBufSize_ = DEFAULT_BUFFER_SIZE; wBuf_.reset(new uint8_t[wBufSize_]); setWriteBuffer(wBuf_.get(), wBufSize_); // reset wBase_ with a pad for the frame size int32_t pad = 0; wBase_ = wBuf_.get() + sizeof(pad); } } uint32_t TFramedTransport::writeEnd() { return static_cast(wBase_ - wBuf_.get()); } const uint8_t* TFramedTransport::borrowSlow(uint8_t* buf, uint32_t* len) { (void)buf; (void)len; // Don't try to be clever with shifting buffers. // If the fast path failed let the protocol use its slow path. // Besides, who is going to try to borrow across messages? return nullptr; } uint32_t TFramedTransport::readEnd() { // include framing bytes auto bytes_read = static_cast(rBound_ - rBuf_.get() + sizeof(uint32_t)); if (rBufSize_ > bufReclaimThresh_) { rBufSize_ = 0; rBuf_.reset(); setReadBuffer(rBuf_.get(), rBufSize_); } resetConsumedMessageSize(); return bytes_read; } void TMemoryBuffer::computeRead(uint32_t len, uint8_t** out_start, uint32_t* out_give) { // Correct rBound_ so we can use the fast path in the future. rBound_ = wBase_; // Decide how much to give. uint32_t give = (std::min)(len, available_read()); *out_start = rBase_; *out_give = give; // Preincrement rBase_ so the caller doesn't have to. rBase_ += give; } uint32_t TMemoryBuffer::readSlow(uint8_t* buf, uint32_t len) { uint8_t* start; uint32_t give; computeRead(len, &start, &give); // Copy into the provided buffer. memcpy(buf, start, give); return give; } uint32_t TMemoryBuffer::readAppendToString(std::string& str, uint32_t len) { // Don't get some stupid assertion failure. if (buffer_ == nullptr) { return 0; } uint8_t* start; uint32_t give; computeRead(len, &start, &give); // Append to the provided string. str.append(reinterpret_cast(start), give); return give; } void TMemoryBuffer::ensureCanWrite(uint32_t len) { // Check available space uint32_t avail = available_write(); if (len <= avail) { return; } if (!owner_) { throw TTransportException("Insufficient space in external MemoryBuffer"); } // Grow the buffer as necessary. Use uint64_t to avoid overflow. const uint64_t current_used = bufferSize_ - avail; const uint64_t required_buffer_size = len + current_used; if (required_buffer_size > maxBufferSize_) { throw TTransportException(TTransportException::BAD_ARGS, "Internal buffer size overflow when requesting a buffer of size " + std::to_string(required_buffer_size)); } // Always grow to the next bigger power of two: const double suggested_buffer_size = std::exp2(std::ceil(std::log2(required_buffer_size))); // Unless the power of two exceeds maxBufferSize_: const uint64_t new_size = static_cast((std::min)(suggested_buffer_size, static_cast(maxBufferSize_))); // Allocate into a new pointer so we don't bork ours if it fails. auto* new_buffer = static_cast(std::realloc(buffer_, static_cast(new_size))); if (new_buffer == nullptr) { throw std::bad_alloc(); } rBase_ = new_buffer + (rBase_ - buffer_); rBound_ = new_buffer + (rBound_ - buffer_); wBase_ = new_buffer + (wBase_ - buffer_); wBound_ = new_buffer + new_size; // Note: with realloc() we do not need to free the previous buffer: buffer_ = new_buffer; bufferSize_ = static_cast(new_size); } void TMemoryBuffer::writeSlow(const uint8_t* buf, uint32_t len) { ensureCanWrite(len); // Copy into the buffer and increment wBase_. memcpy(wBase_, buf, len); wBase_ += len; } void TMemoryBuffer::wroteBytes(uint32_t len) { uint32_t avail = available_write(); if (len > avail) { throw TTransportException("Client wrote more bytes than size of buffer."); } wBase_ += len; } const uint8_t* TMemoryBuffer::borrowSlow(uint8_t* buf, uint32_t* len) { (void)buf; rBound_ = wBase_; if (available_read() >= *len) { *len = available_read(); return rBase_; } return nullptr; } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/THttpServer.h0000664000175000017500000000362015165535636023454 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_THTTPSERVER_H_ #define _THRIFT_TRANSPORT_THTTPSERVER_H_ 1 #include namespace apache { namespace thrift { namespace transport { class THttpServer : public THttpTransport { public: THttpServer(std::shared_ptr transport, std::shared_ptr config = nullptr); ~THttpServer() override; void flush() override; protected: virtual std::string getHeader(uint32_t len); void readHeaders(); void parseHeader(char* header) override; bool parseStatusLine(char* status) override; std::string getTimeRFC1123(); }; /** * Wraps a transport into HTTP protocol */ class THttpServerTransportFactory : public TTransportFactory { public: THttpServerTransportFactory() = default; ~THttpServerTransportFactory() override = default; /** * Wraps the transport into a buffered one. */ std::shared_ptr getTransport(std::shared_ptr trans) override { return std::shared_ptr(new THttpServer(trans)); } }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_THTTPSERVER_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TTransportException.cpp0000664000175000017500000000347415165535636025563 0ustar00buildbuild00000000000000/* * 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 using std::string; namespace apache { namespace thrift { namespace transport { const char* TTransportException::what() const noexcept { if (message_.empty()) { switch (type_) { case UNKNOWN: return "TTransportException: Unknown transport exception"; case NOT_OPEN: return "TTransportException: Transport not open"; case TIMED_OUT: return "TTransportException: Timed out"; case END_OF_FILE: return "TTransportException: End of file"; case INTERRUPTED: return "TTransportException: Interrupted"; case BAD_ARGS: return "TTransportException: Invalid arguments"; case CORRUPTED_DATA: return "TTransportException: Corrupted Data"; case INTERNAL_ERROR: return "TTransportException: Internal error"; default: return "TTransportException: (Invalid exception type)"; } } else { return message_.c_str(); } } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TSocket.h0000664000175000017500000002202015165535636022571 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSOCKET_H_ #define _THRIFT_TRANSPORT_TSOCKET_H_ 1 #include #include #include #include #include #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_NETDB_H #include #endif namespace apache { namespace thrift { namespace transport { /** * TCP Socket implementation of the TTransport interface. * */ class TSocket : public TVirtualTransport { public: /** * Constructs a new socket. Note that this does NOT actually connect the * socket. * */ TSocket(std::shared_ptr config = nullptr); /** * Constructs a new socket. Note that this does NOT actually connect the * socket. * * @param host An IP address or hostname to connect to * @param port The port to connect on */ TSocket(const std::string& host, int port, std::shared_ptr config = nullptr); /** * Constructs a new Unix domain socket. * Note that this does NOT actually connect the socket. * * @param path The Unix domain socket e.g. "/tmp/ThriftTest.binary.thrift" * or a zero-prefixed string to create an abstract domain socket on Linux. */ TSocket(const std::string& path, std::shared_ptr config = nullptr); /** * Destroyes the socket object, closing it if necessary. */ ~TSocket() override; /** * Whether the socket is alive. * * @return Is the socket alive? */ bool isOpen() const override; /** * Checks whether there is more data available in the socket to read. * * This call blocks until at least one byte is available or the socket is closed. */ bool peek() override; /** * Creates and opens the UNIX socket. * * @throws TTransportException If the socket could not connect */ void open() override; /** * Shuts down communications on the socket. */ void close() override; /** * Determines whether there is pending data to read or not. * * This call does not block. * \throws TTransportException of types: * NOT_OPEN means the socket has been closed * UNKNOWN means something unexpected happened * \returns true if there is pending data to read, false otherwise */ virtual bool hasPendingDataToRead(); /** * Reads from the underlying socket. * \returns the number of bytes read or 0 indicates EOF * \throws TTransportException of types: * INTERRUPTED means the socket was interrupted * out of a blocking call * NOT_OPEN means the socket has been closed * TIMED_OUT means the receive timeout expired * UNKNOWN means something unexpected happened */ virtual uint32_t read(uint8_t* buf, uint32_t len); /** * Writes to the underlying socket. Loops until done or fail. */ virtual void write(const uint8_t* buf, uint32_t len); /** * Writes to the underlying socket. Does single send() and returns result. */ virtual uint32_t write_partial(const uint8_t* buf, uint32_t len); /** * Get the host that the socket is connected to * * @return string host identifier */ std::string getHost() const; /** * Get the port that the socket is connected to * * @return int port number */ int getPort() const; /** * Get the Unix domain socket path that the socket is connected to * * @return std::string path */ std::string getPath() const; /** * Whether the socket is a Unix domain socket. This is the same as checking * if getPath() is not empty. * * @return Is the socket a Unix domain socket? */ bool isUnixDomainSocket() const; /** * Set the host that socket will connect to * * @param host host identifier */ void setHost(std::string host); /** * Set the port that socket will connect to * * @param port port number */ void setPort(int port); /** * Set the Unix domain socket path for the socket * * @param path std::string path */ void setPath(std::string path); /** * Controls whether the linger option is set on the socket. * * @param on Whether SO_LINGER is on * @param linger If linger is active, the number of seconds to linger for */ void setLinger(bool on, int linger); /** * Whether to enable/disable Nagle's algorithm. * * @param noDelay Whether or not to disable the algorithm. * @return */ void setNoDelay(bool noDelay); /** * Set the connect timeout */ void setConnTimeout(int ms); /** * Set the receive timeout */ void setRecvTimeout(int ms); /** * Set the send timeout */ void setSendTimeout(int ms); /** * Set the max number of recv retries in case of an THRIFT_EAGAIN * error */ void setMaxRecvRetries(int maxRecvRetries); /** * Set SO_KEEPALIVE */ void setKeepAlive(bool keepAlive); /** * Get socket information formatted as a string */ std::string getSocketInfo() const; /** * Returns the DNS name of the host to which the socket is connected */ std::string getPeerHost() const; /** * Returns the address of the host to which the socket is connected */ std::string getPeerAddress() const; /** * Returns the port of the host to which the socket is connected **/ int getPeerPort() const; /** * Returns the underlying socket file descriptor. */ THRIFT_SOCKET getSocketFD() { return socket_; } /** * (Re-)initialize a TSocket for the supplied descriptor. This is only * intended for use by TNonblockingServer -- other use may result in * unfortunate surprises. * * @param fd the descriptor for an already-connected socket */ void setSocketFD(THRIFT_SOCKET fd); /* * Returns a cached copy of the peer address. */ sockaddr* getCachedAddress(socklen_t* len) const; /** * Sets whether to use a low minimum TCP retransmission timeout. */ static void setUseLowMinRto(bool useLowMinRto); /** * Gets whether to use a low minimum TCP retransmission timeout. */ static bool getUseLowMinRto(); /** * Get the origin the socket is connected to * * @return string peer host identifier and port */ const std::string getOrigin() const override; /** * Constructor to create socket from file descriptor. */ TSocket(THRIFT_SOCKET socket, std::shared_ptr config = nullptr); /** * Constructor to create socket from file descriptor that * can be interrupted safely. */ TSocket(THRIFT_SOCKET socket, std::shared_ptr interruptListener, std::shared_ptr config = nullptr); /** * Set a cache of the peer address (used when trivially available: e.g. * accept() or connect()). Only caches IPV4 and IPV6; unset for others. */ void setCachedAddress(const sockaddr* addr, socklen_t len); protected: /** connect, called by open */ void openConnection(struct addrinfo* res); /** Host to connect to */ std::string host_; /** Port number to connect on */ int port_; /** UNIX domain socket path */ std::string path_; /** Underlying socket handle */ THRIFT_SOCKET socket_; /** Peer hostname */ mutable std::string peerHost_; /** Peer address */ mutable std::string peerAddress_; /** Peer port */ mutable int peerPort_; /** * A shared socket pointer that will interrupt a blocking read if data * becomes available on it */ std::shared_ptr interruptListener_; /** Connect timeout in ms */ int connTimeout_; /** Send timeout in ms */ int sendTimeout_; /** Recv timeout in ms */ int recvTimeout_; /** Keep alive on */ bool keepAlive_; /** Linger on */ bool lingerOn_; /** Linger val */ int lingerVal_; /** Nodelay */ bool noDelay_; /** Recv EGAIN retries */ int maxRecvRetries_; /** Cached peer address */ union { sockaddr_in ipv4; sockaddr_in6 ipv6; } cachedPeerAddr_; /** Whether to use low minimum TCP retransmission timeout */ static bool useLowMinRto_; private: void unix_open(); void local_open(); }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TSOCKET_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/THttpTransport.h0000664000175000017500000000556615165535636024215 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_THTTPTRANSPORT_H_ #define _THRIFT_TRANSPORT_THTTPTRANSPORT_H_ 1 #include #include namespace apache { namespace thrift { namespace transport { /** * HTTP implementation of the thrift transport. This was irritating * to write, but the alternatives in C++ land are daunting. Linking CURL * requires 23 dynamic libraries last time I checked (WTF?!?). All we have * here is a VERY basic HTTP/1.1 client which supports HTTP 100 Continue, * chunked transfer encoding, keepalive, etc. Tested against Apache. */ class THttpTransport : public TVirtualTransport { public: THttpTransport(std::shared_ptr transport, std::shared_ptr config = nullptr); ~THttpTransport() override; void open() override { transport_->open(); } bool isOpen() const override { return transport_->isOpen(); } bool peek() override { return transport_->peek(); } void close() override { transport_->close(); } uint32_t read(uint8_t* buf, uint32_t len); uint32_t readEnd() override; void write(const uint8_t* buf, uint32_t len); void flush() override { resetConsumedMessageSize(); }; const std::string getOrigin() const override; protected: std::shared_ptr transport_; std::string origin_; TMemoryBuffer writeBuffer_; TMemoryBuffer readBuffer_; bool readHeaders_; bool chunked_; bool chunkedDone_; uint32_t chunkSize_; uint32_t contentLength_; char* httpBuf_; uint32_t httpPos_; uint32_t httpBufLen_; uint32_t httpBufSize_; virtual void init(); uint32_t readMoreData(); char* readLine(); void readHeaders(); virtual void parseHeader(char* header) = 0; virtual bool parseStatusLine(char* status) = 0; uint32_t readChunked(); void readChunkedFooters(); uint32_t parseChunkSize(char* line); uint32_t readContent(uint32_t size); void refill(); void shift(); static const char* CRLF; static const int CRLF_LEN; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_THTTPCLIENT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TNonblockingServerTransport.h0000664000175000017500000000600215165535636026712 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TNONBLOCKINGSERVERTRANSPORT_H_ #define _THRIFT_TRANSPORT_TNONBLOCKINGSERVERTRANSPORT_H_ 1 #include #include namespace apache { namespace thrift { namespace transport { /** * Server transport framework. A server needs to have some facility for * creating base transports to read/write from. The server is expected * to keep track of TTransport children that it creates for purposes of * controlling their lifetime. */ class TNonblockingServerTransport { public: virtual ~TNonblockingServerTransport() = default; /** * Starts the server transport listening for new connections. Prior to this * call most transports will not return anything when accept is called. * * @throws TTransportException if we were unable to listen */ virtual void listen() {} /** * Gets a new dynamically allocated transport object and passes it to the * caller. Note that it is the explicit duty of the caller to free the * allocated object. The returned TTransport object must always be in the * opened state. nullptr should never be returned, instead an Exception should * always be thrown. * * @return A new TTransport object * @throws TTransportException if there is an error */ std::shared_ptr accept() { std::shared_ptr result = acceptImpl(); if (!result) { throw TTransportException("accept() may not return nullptr"); } return result; } /** * Utility method * * @return server socket file descriptor * @throw TTransportException If an error occurs */ virtual THRIFT_SOCKET getSocketFD() = 0; virtual int getPort() = 0; virtual int getListenPort() = 0; /** * Closes this transport such that future calls to accept will do nothing. */ virtual void close() = 0; protected: TNonblockingServerTransport() = default; /** * Subclasses should implement this function for accept. * * @return A newly allocated TTransport object * @throw TTransportException If an error occurs */ virtual std::shared_ptr acceptImpl() = 0; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TNONBLOCKINGSERVERTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TSimpleFileTransport.cpp0000664000175000017500000000353715165535636025656 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_SYS_STAT_H #include #endif #include #ifdef _WIN32 #include #endif namespace apache { namespace thrift { namespace transport { TSimpleFileTransport::TSimpleFileTransport(const std::string& path, bool read, bool write, std::shared_ptr config) : TFDTransport(-1, TFDTransport::CLOSE_ON_DESTROY, config) { int flags = 0; if (read && write) { flags = O_RDWR; } else if (read) { flags = O_RDONLY; } else if (write) { flags = O_WRONLY; } else { throw TTransportException("Neither READ nor WRITE specified"); } if (write) { flags |= O_CREAT | O_APPEND; } #ifndef _WIN32 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; #else int mode = _S_IREAD | _S_IWRITE; #endif int fd = ::THRIFT_OPEN(path.c_str(), flags, mode); if (fd < 0) { throw TTransportException("failed to open file for writing: " + path); } setFD(fd); open(); } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/transport/TSSLServerSocket.h0000664000175000017500000000433315165535636024351 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSSLSERVERSOCKET_H_ #define _THRIFT_TRANSPORT_TSSLSERVERSOCKET_H_ 1 #include namespace apache { namespace thrift { namespace transport { class TSSLSocketFactory; /** * Server socket that accepts SSL connections. */ class TSSLServerSocket : public TServerSocket { public: /** * Constructor. Binds to all interfaces. * * @param port Listening port * @param factory SSL socket factory implementation */ TSSLServerSocket(int port, std::shared_ptr factory); /** * Constructor. Binds to the specified address. * * @param address Address to bind to * @param port Listening port * @param factory SSL socket factory implementation */ TSSLServerSocket(const std::string& address, int port, std::shared_ptr factory); /** * Constructor. Binds to all interfaces. * * @param port Listening port * @param sendTimeout Socket send timeout * @param recvTimeout Socket receive timeout * @param factory SSL socket factory implementation */ TSSLServerSocket(int port, int sendTimeout, int recvTimeout, std::shared_ptr factory); protected: std::shared_ptr createSocket(THRIFT_SOCKET socket) override; std::shared_ptr factory_; }; } } } #endif thrift-0.23.0/lib/cpp/src/thrift/transport/TShortReadTransport.h0000664000175000017500000000526415165535636025164 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TSHORTREADTRANSPORT_H_ #define _THRIFT_TRANSPORT_TSHORTREADTRANSPORT_H_ 1 #include #include #include namespace apache { namespace thrift { namespace transport { namespace test { /** * This class is only meant for testing. It wraps another transport. * Calls to read are passed through with some probability. Otherwise, * the read amount is randomly reduced before being passed through. * */ class TShortReadTransport : public TVirtualTransport { public: TShortReadTransport(std::shared_ptr transport, double full_prob, std::shared_ptr config = nullptr) : TVirtualTransport(config), transport_(transport), fullProb_(full_prob) { } bool isOpen() const override { return transport_->isOpen(); } bool peek() override { return transport_->peek(); } void open() override { transport_->open(); } void close() override { transport_->close(); } uint32_t read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); if (len == 0) { return 0; } if (rand() / (double)RAND_MAX >= fullProb_) { len = 1 + rand() % len; } return transport_->read(buf, len); } void write(const uint8_t* buf, uint32_t len) { transport_->write(buf, len); } void flush() override { resetConsumedMessageSize(); transport_->flush(); } const uint8_t* borrow(uint8_t* buf, uint32_t* len) { return transport_->borrow(buf, len); } void consume(uint32_t len) { countConsumedMessageBytes(len); return transport_->consume(len); } std::shared_ptr getUnderlyingTransport() { return transport_; } protected: std::shared_ptr transport_; double fullProb_; }; } } } } // apache::thrift::transport::test #endif // #ifndef _THRIFT_TRANSPORT_TSHORTREADTRANSPORT_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/SocketCommon.h0000664000175000017500000000255115165535636023625 0ustar00buildbuild00000000000000/* * 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. * * @author: David Suárez */ #ifndef THRIFT_SOCKETCOMMON_H #define THRIFT_SOCKETCOMMON_H #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_UN_H #include #endif #ifdef HAVE_AF_UNIX_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #include namespace apache { namespace thrift { namespace transport { socklen_t fillUnixSocketAddr(struct sockaddr_un& address, std::string& path); } } } // apache::thrift::transport #endif //THRIFT_SOCKETCOMMON_H thrift-0.23.0/lib/cpp/src/thrift/transport/TPipe.h0000664000175000017500000000701715165535636022247 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TPIPE_H_ #define _THRIFT_TRANSPORT_TPIPE_H_ 1 #include #include #ifndef _WIN32 #include #endif #ifdef _WIN32 #include #endif #include #ifdef _WIN32 #include #endif namespace apache { namespace thrift { namespace transport { /** * Windows Pipes implementation of the TTransport interface. * Don't destroy a TPipe at global scope, as that will cause a thread join * during DLLMain. That also means that client objects using TPipe shouldn't be at global * scope. */ #ifdef _WIN32 class TPipeImpl; class TPipe : public TVirtualTransport { public: // Constructs a new pipe object. TPipe(std::shared_ptr config = nullptr); // Named pipe constructors - explicit TPipe(HANDLE Pipe, std::shared_ptr config = nullptr); // HANDLE is a void* explicit TPipe(TAutoHandle& Pipe, std::shared_ptr config = nullptr); // this ctor will clear out / move from Pipe // need a const char * overload so string literals don't go to the HANDLE overload explicit TPipe(const char* pipename, std::shared_ptr config = nullptr); explicit TPipe(const std::string& pipename, std::shared_ptr config = nullptr); // Anonymous pipe - TPipe(HANDLE PipeRd, HANDLE PipeWrt, std::shared_ptr config = nullptr); // Destroys the pipe object, closing it if necessary. virtual ~TPipe(); // Returns whether the pipe is open & valid. bool isOpen() const override; // Checks whether more data is available in the pipe. bool peek() override; // Creates and opens the named/anonymous pipe. void open() override; // Shuts down communications on the pipe. void close() override; // Reads from the pipe. virtual uint32_t read(uint8_t* buf, uint32_t len); // Writes to the pipe. virtual void write(const uint8_t* buf, uint32_t len); // Accessors std::string getPipename(); void setPipename(const std::string& pipename); HANDLE getPipeHandle(); // doubles as the read handle for anon pipe void setPipeHandle(HANDLE pipehandle); HANDLE getWrtPipeHandle(); void setWrtPipeHandle(HANDLE pipehandle); long getConnTimeout(); void setConnTimeout(long seconds); // this function is intended to be used in generic / template situations, // so its name needs to be the same as TPipeServer's HANDLE getNativeWaitHandle(); private: std::shared_ptr impl_; std::string pipename_; long TimeoutSeconds_; bool isAnonymous_; }; #else typedef TSocket TPipe; #endif } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TPIPE_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp0000664000175000017500000000400315165535636024676 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace transport { /** * SSL server socket implementation. */ TSSLServerSocket::TSSLServerSocket(int port, std::shared_ptr factory) : TServerSocket(port), factory_(factory) { factory_->server(true); } TSSLServerSocket::TSSLServerSocket(const std::string& address, int port, std::shared_ptr factory) : TServerSocket(address, port), factory_(factory) { factory_->server(true); } TSSLServerSocket::TSSLServerSocket(int port, int sendTimeout, int recvTimeout, std::shared_ptr factory) : TServerSocket(port, sendTimeout, recvTimeout), factory_(factory) { factory_->server(true); } std::shared_ptr TSSLServerSocket::createSocket(THRIFT_SOCKET client) { if (interruptableChildren_) { return factory_->createSocket(client, pChildInterruptSockReader_); } else { return factory_->createSocket(client); } } } } } thrift-0.23.0/lib/cpp/src/thrift/transport/TTransportUtils.h0000664000175000017500000002253315165535636024367 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TTRANSPORTUTILS_H_ #define _THRIFT_TRANSPORT_TTRANSPORTUTILS_H_ 1 #include #include #include #include #include // Include the buffered transports that used to be defined here. #include #include namespace apache { namespace thrift { namespace transport { /** * The null transport is a dummy transport that doesn't actually do anything. * It's sort of an analogy to /dev/null, you can never read anything from it * and it will let you write anything you want to it, though it won't actually * go anywhere. * */ class TNullTransport : public TVirtualTransport { public: TNullTransport() = default; ~TNullTransport() override = default; bool isOpen() const override { return true; } void open() override {} void write(const uint8_t* /* buf */, uint32_t /* len */) { return; } }; /** * TPipedTransport. This transport allows piping of a request from one * transport to another either when readEnd() or writeEnd(). The typical * use case for this is to log a request or a reply to disk. * The underlying buffer expands to a keep a copy of the entire * request/response. * */ class TPipedTransport : virtual public TTransport { public: TPipedTransport(std::shared_ptr srcTrans, std::shared_ptr dstTrans, std::shared_ptr config = nullptr) : TTransport(config), srcTrans_(srcTrans), dstTrans_(dstTrans), rBufSize_(512), rPos_(0), rLen_(0), wBufSize_(512), wLen_(0) { // default is to to pipe the request when readEnd() is called pipeOnRead_ = true; pipeOnWrite_ = false; rBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * rBufSize_); if (rBuf_ == nullptr) { throw std::bad_alloc(); } wBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * wBufSize_); if (wBuf_ == nullptr) { throw std::bad_alloc(); } } TPipedTransport(std::shared_ptr srcTrans, std::shared_ptr dstTrans, uint32_t sz, std::shared_ptr config = nullptr) : TTransport(config), srcTrans_(srcTrans), dstTrans_(dstTrans), rBufSize_(512), rPos_(0), rLen_(0), wBufSize_(sz), wLen_(0) { rBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * rBufSize_); if (rBuf_ == nullptr) { throw std::bad_alloc(); } wBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * wBufSize_); if (wBuf_ == nullptr) { throw std::bad_alloc(); } } ~TPipedTransport() override { std::free(rBuf_); std::free(wBuf_); } bool isOpen() const override { return srcTrans_->isOpen(); } bool peek() override { if (rPos_ >= rLen_) { // Double the size of the underlying buffer if it is full if (rLen_ == rBufSize_) { rBufSize_ *= 2; auto * tmpBuf = (uint8_t*)std::realloc(rBuf_, sizeof(uint8_t) * rBufSize_); if (tmpBuf == nullptr) { throw std::bad_alloc(); } rBuf_ = tmpBuf; } // try to fill up the buffer rLen_ += srcTrans_->read(rBuf_ + rPos_, rBufSize_ - rPos_); } return (rLen_ > rPos_); } void open() override { srcTrans_->open(); } void close() override { srcTrans_->close(); } void setPipeOnRead(bool pipeVal) { pipeOnRead_ = pipeVal; } void setPipeOnWrite(bool pipeVal) { pipeOnWrite_ = pipeVal; } uint32_t read(uint8_t* buf, uint32_t len); uint32_t readEnd() override { if (pipeOnRead_) { dstTrans_->write(rBuf_, rPos_); dstTrans_->flush(); } srcTrans_->readEnd(); // If requests are being pipelined, copy down our read-ahead data, // then reset our state. int read_ahead = rLen_ - rPos_; uint32_t bytes = rPos_; memcpy(rBuf_, rBuf_ + rPos_, read_ahead); rPos_ = 0; rLen_ = read_ahead; return bytes; } void write(const uint8_t* buf, uint32_t len); uint32_t writeEnd() override { if (pipeOnWrite_) { dstTrans_->write(wBuf_, wLen_); dstTrans_->flush(); } return wLen_; } void flush() override; std::shared_ptr getTargetTransport() { return dstTrans_; } /* * Override TTransport *_virt() functions to invoke our implementations. * We cannot use TVirtualTransport to provide these, since we need to inherit * virtually from TTransport. */ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return this->read(buf, len); } void write_virt(const uint8_t* buf, uint32_t len) override { this->write(buf, len); } protected: std::shared_ptr srcTrans_; std::shared_ptr dstTrans_; uint8_t* rBuf_; uint32_t rBufSize_; uint32_t rPos_; uint32_t rLen_; uint8_t* wBuf_; uint32_t wBufSize_; uint32_t wLen_; bool pipeOnRead_; bool pipeOnWrite_; }; /** * Wraps a transport into a pipedTransport instance. * */ class TPipedTransportFactory : public TTransportFactory { public: TPipedTransportFactory() = default; TPipedTransportFactory(std::shared_ptr dstTrans) { initializeTargetTransport(dstTrans); } ~TPipedTransportFactory() override = default; /** * Wraps the base transport into a piped transport. */ std::shared_ptr getTransport(std::shared_ptr srcTrans) override { return std::shared_ptr(new TPipedTransport(srcTrans, dstTrans_)); } virtual void initializeTargetTransport(std::shared_ptr dstTrans) { if (dstTrans_.get() == nullptr) { dstTrans_ = dstTrans; } else { throw TException("Target transport already initialized"); } } protected: std::shared_ptr dstTrans_; }; /** * TPipedFileTransport. This is just like a TTransport, except that * it is a templatized class, so that clients who rely on a specific * TTransport can still access the original transport. * */ class TPipedFileReaderTransport : public TPipedTransport, public TFileReaderTransport { public: TPipedFileReaderTransport(std::shared_ptr srcTrans, std::shared_ptr dstTrans, std::shared_ptr config = nullptr); ~TPipedFileReaderTransport() override; // TTransport functions bool isOpen() const override; bool peek() override; void open() override; void close() override; uint32_t read(uint8_t* buf, uint32_t len); uint32_t readAll(uint8_t* buf, uint32_t len); uint32_t readEnd() override; void write(const uint8_t* buf, uint32_t len); uint32_t writeEnd() override; void flush() override; // TFileReaderTransport functions int32_t getReadTimeout() override; void setReadTimeout(int32_t readTimeout) override; uint32_t getNumChunks() override; uint32_t getCurChunk() override; void seekToChunk(int32_t chunk) override; void seekToEnd() override; /* * Override TTransport *_virt() functions to invoke our implementations. * We cannot use TVirtualTransport to provide these, since we need to inherit * virtually from TTransport. */ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return this->read(buf, len); } uint32_t readAll_virt(uint8_t* buf, uint32_t len) override { return this->readAll(buf, len); } void write_virt(const uint8_t* buf, uint32_t len) override { this->write(buf, len); } protected: // shouldn't be used TPipedFileReaderTransport(); std::shared_ptr srcTrans_; }; /** * Creates a TPipedFileReaderTransport from a filepath and a destination transport * */ class TPipedFileReaderTransportFactory : public TPipedTransportFactory { public: TPipedFileReaderTransportFactory() = default; TPipedFileReaderTransportFactory(std::shared_ptr dstTrans) : TPipedTransportFactory(dstTrans) {} ~TPipedFileReaderTransportFactory() override = default; std::shared_ptr getTransport(std::shared_ptr srcTrans) override { std::shared_ptr pFileReaderTransport = std::dynamic_pointer_cast(srcTrans); if (pFileReaderTransport.get() != nullptr) { return getFileReaderTransport(pFileReaderTransport); } else { return std::shared_ptr(); } } std::shared_ptr getFileReaderTransport( std::shared_ptr srcTrans) { return std::shared_ptr( new TPipedFileReaderTransport(srcTrans, dstTrans_)); } }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TTRANSPORTUTILS_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TNonblockingServerSocket.h0000664000175000017500000001013715165535636026152 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TNONBLOCKINGSERVERSOCKET_H_ #define _THRIFT_TRANSPORT_TNONBLOCKINGSERVERSOCKET_H_ 1 #include #include namespace apache { namespace thrift { namespace transport { class TSocket; /** * Nonblocking Server socket implementation of TNonblockingServerTransport. Wrapper around a unix * socket listen and accept calls. * */ class TNonblockingServerSocket : public TNonblockingServerTransport { public: typedef std::function socket_func_t; const static int DEFAULT_BACKLOG = 1024; /** * Constructor. * * @param port Port number to bind to */ TNonblockingServerSocket(int port); /** * Constructor. * * @param port Port number to bind to * @param sendTimeout Socket send timeout * @param recvTimeout Socket receive timeout */ TNonblockingServerSocket(int port, int sendTimeout, int recvTimeout); /** * Constructor. * * @param address Address to bind to * @param port Port number to bind to */ TNonblockingServerSocket(const std::string& address, int port); /** * Constructor used for unix sockets. * * @param path Pathname for unix socket. */ TNonblockingServerSocket(const std::string& path); ~TNonblockingServerSocket() override; bool isOpen() const; void setSendTimeout(int sendTimeout); void setRecvTimeout(int recvTimeout); void setAcceptBacklog(int accBacklog); void setRetryLimit(int retryLimit); void setRetryDelay(int retryDelay); void setKeepAlive(bool keepAlive) { keepAlive_ = keepAlive; } void setTcpSendBuffer(int tcpSendBuffer); void setTcpRecvBuffer(int tcpRecvBuffer); // listenCallback gets called just before listen, and after all Thrift // setsockopt calls have been made. If you have custom setsockopt // things that need to happen on the listening socket, this is the place to do it. void setListenCallback(const socket_func_t& listenCallback) { listenCallback_ = listenCallback; } // acceptCallback gets called after each accept call, on the newly created socket. // It is called after all Thrift setsockopt calls have been made. If you have // custom setsockopt things that need to happen on the accepted // socket, this is the place to do it. void setAcceptCallback(const socket_func_t& acceptCallback) { acceptCallback_ = acceptCallback; } THRIFT_SOCKET getSocketFD() override { return serverSocket_; } int getPort() override; int getListenPort() override; std::string getPath() const; bool isUnixDomainSocket() const; void listen() override; void close() override; protected: std::shared_ptr acceptImpl() override; virtual std::shared_ptr createSocket(THRIFT_SOCKET client); private: void _setup_sockopts(); void _setup_unixdomain_sockopts(); void _setup_tcp_sockopts(); int port_; int listenPort_; std::string address_; std::string path_; THRIFT_SOCKET serverSocket_; int acceptBacklog_; int sendTimeout_; int recvTimeout_; int retryLimit_; int retryDelay_; int tcpSendBuffer_; int tcpRecvBuffer_; bool keepAlive_; bool listening_; socket_func_t listenCallback_; socket_func_t acceptCallback_; }; } } } // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TNONBLOCKINGSERVERSOCKET_H_ thrift-0.23.0/lib/cpp/src/thrift/transport/TZlibTransport.cpp0000664000175000017500000003131515167543515024515 0ustar00buildbuild00000000000000/* * 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 using std::string; namespace apache { namespace thrift { namespace transport { // Don't call this outside of the constructor. void TZlibTransport::initZlib() { int rv; bool r_init = false; try { rstream_ = new z_stream; wstream_ = new z_stream; rstream_->zalloc = Z_NULL; wstream_->zalloc = Z_NULL; rstream_->zfree = Z_NULL; wstream_->zfree = Z_NULL; rstream_->opaque = Z_NULL; wstream_->opaque = Z_NULL; rstream_->next_in = crbuf_; wstream_->next_in = uwbuf_; rstream_->next_out = urbuf_; wstream_->next_out = cwbuf_; rstream_->avail_in = 0; wstream_->avail_in = 0; rstream_->avail_out = urbuf_size_; wstream_->avail_out = cwbuf_size_; rv = inflateInit(rstream_); checkZlibRv(rv, rstream_->msg); // Have to set this flag so we know whether to de-initialize. r_init = true; rv = deflateInit(wstream_, comp_level_); checkZlibRv(rv, wstream_->msg); } catch (...) { if (r_init) { rv = inflateEnd(rstream_); checkZlibRvNothrow(rv, rstream_->msg); } // There is no way we can get here if wstream_ was initialized. throw; } } inline void TZlibTransport::checkZlibRv(int status, const char* message) { if (status != Z_OK) { throw TZlibTransportException(status, message); } } inline void TZlibTransport::checkZlibRvNothrow(int status, const char* message) { if (status != Z_OK) { string output = "TZlibTransport: zlib failure in destructor: " + TZlibTransportException::errorMessage(status, message); TOutput::instance()(output.c_str()); } } TZlibTransport::~TZlibTransport() { int rv; rv = inflateEnd(rstream_); checkZlibRvNothrow(rv, rstream_->msg); rv = deflateEnd(wstream_); // Z_DATA_ERROR may be returned if the caller has written data, but not // called flush() to actually finish writing the data out to the underlying // transport. The defined TTransport behavior in this case is that this data // may be discarded, so we ignore the error and silently discard the data. // For other erros, log a message. if (rv != Z_DATA_ERROR) { checkZlibRvNothrow(rv, wstream_->msg); } delete[] urbuf_; delete[] crbuf_; delete[] uwbuf_; delete[] cwbuf_; delete rstream_; delete wstream_; } bool TZlibTransport::isOpen() const { return (readAvail() > 0) || (rstream_->avail_in > 0) || transport_->isOpen(); } bool TZlibTransport::peek() { return (readAvail() > 0) || (rstream_->avail_in > 0) || transport_->peek(); } // READING STRATEGY // // We have two buffers for reading: one containing the compressed data (crbuf_) // and one containing the uncompressed data (urbuf_). When read is called, // we repeat the following steps until we have satisfied the request: // - Copy data from urbuf_ into the caller's buffer. // - If we had enough, return. // - If urbuf_ is empty, read some data into it from the underlying transport. // - Inflate data from crbuf_ into urbuf_. // // In standalone objects, we set input_ended_ to true when inflate returns // Z_STREAM_END. This allows to make sure that a checksum was verified. inline int TZlibTransport::readAvail() const { return urbuf_size_ - rstream_->avail_out - urpos_; } uint32_t TZlibTransport::read(uint8_t* buf, uint32_t len) { checkReadBytesAvailable(len); uint32_t need = len; // TODO(dreiss): Skip urbuf on big reads. while (true) { // Copy out whatever we have available, then give them the min of // what we have and what they want, then advance indices. int give = (std::min)((uint32_t)readAvail(), need); memcpy(buf, urbuf_ + urpos_, give); need -= give; buf += give; urpos_ += give; // If they were satisfied, we are done. if (need == 0) { return len; } // If we will need to read from the underlying transport to get more data, // but we already have some data available, return it now. Reading from // the underlying transport may block, and read() is only allowed to block // when no data is available. if (need < len && rstream_->avail_in == 0) { return len - need; } // If we get to this point, we need to get some more data. // If zlib has reported the end of a stream, we can't really do any more. if (input_ended_) { return len - need; } // The uncompressed read buffer is empty, so reset the stream fields. rstream_->next_out = urbuf_; rstream_->avail_out = urbuf_size_; urpos_ = 0; // Call inflate() to uncompress some more data if (!readFromZlib()) { // no data available from underlying transport return len - need; } // Okay. The read buffer should have whatever we can give it now. // Loop back to the start and try to give some more. } } bool TZlibTransport::readFromZlib() { assert(!input_ended_); // If we don't have any more compressed data available, // read some from the underlying transport. if (rstream_->avail_in == 0) { uint32_t got = transport_->read(crbuf_, crbuf_size_); if (got == 0) { return false; } rstream_->next_in = crbuf_; rstream_->avail_in = got; } // We have some compressed data now. Uncompress it. int zlib_rv = inflate(rstream_, Z_SYNC_FLUSH); if (zlib_rv == Z_STREAM_END) { input_ended_ = true; } else { checkZlibRv(zlib_rv, rstream_->msg); } return true; } // WRITING STRATEGY // // We buffer up small writes before sending them to zlib, so our logic is: // - Is the write big? // - Send the buffer to zlib. // - Send this data to zlib. // - Is the write small? // - Is there insufficient space in the buffer for it? // - Send the buffer to zlib. // - Copy the data to the buffer. // // We have two buffers for writing also: the uncompressed buffer (mentioned // above) and the compressed buffer. When sending data to zlib we loop over // the following until the source (uncompressed buffer or big write) is empty: // - Is there no more space in the compressed buffer? // - Write the compressed buffer to the underlying transport. // - Deflate from the source into the compressed buffer. void TZlibTransport::write(const uint8_t* buf, uint32_t len) { if (output_finished_) { throw TTransportException(TTransportException::BAD_ARGS, "write() called after finish()"); } // zlib's "deflate" function has enough logic in it that I think // we're better off (performance-wise) buffering up small writes. if (len > MIN_DIRECT_DEFLATE_SIZE) { flushToZlib(uwbuf_, uwpos_, Z_NO_FLUSH); uwpos_ = 0; flushToZlib(buf, len, Z_NO_FLUSH); } else if (len > 0) { if (uwbuf_size_ - uwpos_ < len) { flushToZlib(uwbuf_, uwpos_, Z_NO_FLUSH); uwpos_ = 0; } memcpy(uwbuf_ + uwpos_, buf, len); uwpos_ += len; } } void TZlibTransport::flush() { if (output_finished_) { throw TTransportException(TTransportException::BAD_ARGS, "flush() called after finish()"); } flushToZlib(uwbuf_, uwpos_, Z_BLOCK); uwpos_ = 0; if(wstream_->avail_out < 6){ transport_->write(cwbuf_, cwbuf_size_ - wstream_->avail_out); wstream_->next_out = cwbuf_; wstream_->avail_out = cwbuf_size_; } flushToTransport(Z_FULL_FLUSH); resetConsumedMessageSize(); } void TZlibTransport::finish() { if (output_finished_) { throw TTransportException(TTransportException::BAD_ARGS, "finish() called more than once"); } flushToTransport(Z_FINISH); } void TZlibTransport::flushToTransport(int flush) { // write pending data in uwbuf_ to zlib flushToZlib(uwbuf_, uwpos_, flush); uwpos_ = 0; // write all available data from zlib to the transport transport_->write(cwbuf_, cwbuf_size_ - wstream_->avail_out); wstream_->next_out = cwbuf_; wstream_->avail_out = cwbuf_size_; // flush the transport transport_->flush(); } void TZlibTransport::flushToZlib(const uint8_t* buf, int len, int flush) { wstream_->next_in = const_cast(buf); wstream_->avail_in = len; while (true) { if ((flush == Z_NO_FLUSH || flush == Z_BLOCK) && wstream_->avail_in == 0) { break; } // If our ouput buffer is full, flush to the underlying transport. if (wstream_->avail_out == 0) { transport_->write(cwbuf_, cwbuf_size_); wstream_->next_out = cwbuf_; wstream_->avail_out = cwbuf_size_; } int zlib_rv = deflate(wstream_, flush); if (flush == Z_FINISH && zlib_rv == Z_STREAM_END) { assert(wstream_->avail_in == 0); output_finished_ = true; break; } checkZlibRv(zlib_rv, wstream_->msg); if ((flush == Z_SYNC_FLUSH || flush == Z_FULL_FLUSH) && wstream_->avail_in == 0 && wstream_->avail_out != 0) { break; } } } const uint8_t* TZlibTransport::borrow(uint8_t* buf, uint32_t* len) { (void)buf; // Don't try to be clever with shifting buffers. // If we have enough data, give a pointer to it, // otherwise let the protcol use its slow path. if (readAvail() >= (int)*len) { *len = (uint32_t)readAvail(); return urbuf_ + urpos_; } return nullptr; } void TZlibTransport::consume(uint32_t len) { countConsumedMessageBytes(len); if (readAvail() >= (int)len) { urpos_ += len; } else { throw TTransportException(TTransportException::BAD_ARGS, "consume did not follow a borrow."); } } void TZlibTransport::verifyChecksum() { // If zlib has already reported the end of the stream, // it has verified the checksum. if (input_ended_) { return; } // This should only be called when reading is complete. // If the caller still has unread data, throw an exception. if (readAvail() > 0) { throw TTransportException(TTransportException::CORRUPTED_DATA, "verifyChecksum() called before end of zlib stream"); } // Reset the rstream fields, in case avail_out is 0. // (Since readAvail() is 0, we know there is no unread data in urbuf_) rstream_->next_out = urbuf_; rstream_->avail_out = urbuf_size_; urpos_ = 0; // Call inflate() // This will throw an exception if the checksum is bad. bool performed_inflate = readFromZlib(); if (!performed_inflate) { // We needed to read from the underlying transport, and the read() call // returned 0. // // Not all TTransport implementations behave the same way here, so we'll // end up with different behavior depending on the underlying transport. // // For some transports (e.g., TFDTransport), read() blocks if no more data // is available. They only return 0 if EOF has been reached, or if the // remote endpoint has closed the connection. For those transports, // verifyChecksum() will block until the checksum becomes available. // // Other transport types (e.g., TMemoryBuffer) always return 0 immediately // if no more data is available. For those transport types, verifyChecksum // will raise the following exception if the checksum is not available from // the underlying transport yet. throw TTransportException(TTransportException::CORRUPTED_DATA, "checksum not available yet in " "verifyChecksum()"); } // If input_ended_ is true now, the checksum has been verified if (input_ended_) { return; } // The caller invoked us before the actual end of the data stream assert(rstream_->avail_out < urbuf_size_); throw TTransportException(TTransportException::CORRUPTED_DATA, "verifyChecksum() called before end of " "zlib stream"); } TZlibTransportFactory::TZlibTransportFactory(std::shared_ptr transportFactory) :transportFactory_(transportFactory) { } std::shared_ptr TZlibTransportFactory::getTransport(std::shared_ptr trans) { if (transportFactory_) { return std::shared_ptr(new TZlibTransport(transportFactory_->getTransport(trans))); } else { return std::shared_ptr(new TZlibTransport(trans)); } } } } } // apache::thrift::transport thrift-0.23.0/lib/cpp/src/thrift/TUuid.h0000664000175000017500000001136415165535636020224 0ustar00buildbuild00000000000000/* * 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_ thrift-0.23.0/lib/cpp/src/thrift/Thrift.h0000664000175000017500000000700115165535636020423 0ustar00buildbuild00000000000000/* * 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_THRIFT_H_ #define _THRIFT_THRIFT_H_ 1 #include #include #include #include #include #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #include #include #include #include #include #include #include #include #include #define THRIFT_UNUSED_VARIABLE(x) ((void)(x)) namespace apache { namespace thrift { class TEnumIterator { public: using iterator_category = std::forward_iterator_tag; using value_type = std::pair; using difference_type = std::ptrdiff_t; using pointer = value_type*; using reference = value_type&; TEnumIterator(int n, int* enums, const char** names) : ii_(0), n_(n), enums_(enums), names_(names) {} int operator++() { return ++ii_; } 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: int ii_; const int n_; int* enums_; const char** names_; }; class TException : public std::exception { public: TException() : message_() {} TException(const std::string& message) : message_(message) {} virtual ~TException() noexcept override = default; const char* what() const noexcept override { if (message_.empty()) { return "Default TException."; } else { return message_.c_str(); } } protected: std::string message_; }; class TDelayedException { public: template static TDelayedException* delayException(const E& e); virtual void throw_it() = 0; virtual ~TDelayedException() = default; }; template class TExceptionWrapper : public TDelayedException { public: TExceptionWrapper(const E& e) : e_(e) {} void throw_it() override { E temp(e_); delete this; throw temp; } private: E e_; }; template TDelayedException* TDelayedException::delayException(const E& e) { return new TExceptionWrapper(e); } #if T_GLOBAL_DEBUG_VIRTUAL > 1 void profile_virtual_call(const std::type_info& info); void profile_generic_protocol(const std::type_info& template_type, const std::type_info& prot_type); void profile_print_info(FILE* f); void profile_print_info(); void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f); #endif } } // apache::thrift #endif // #ifndef _THRIFT_THRIFT_H_ thrift-0.23.0/lib/cpp/src/thrift/thrift_export.h0000664000175000017500000000071415165535636022070 0ustar00buildbuild00000000000000#ifndef THRIFT_EXPORT_H #define THRIFT_EXPORT_H #ifdef THRIFT_STATIC_DEFINE # define THRIFT_EXPORT #elif defined(_MSC_VER ) # ifndef THRIFT_EXPORT # ifdef thrift_EXPORTS /* We are building this library */ # define THRIFT_EXPORT __declspec(dllexport) # else /* We are using this library */ # define THRIFT_EXPORT __declspec(dllimport) # endif # endif #else # define THRIFT_EXPORT #endif #endif /* THRIFT_EXPORT_H */ thrift-0.23.0/lib/cpp/src/thrift/protocol/0000755000175000017500000000000015170007200020624 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/src/thrift/protocol/TList.h0000664000175000017500000000240015165535636022061 0ustar00buildbuild00000000000000/* * 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_TLIST_H_ #define _THRIFT_TLIST_H_ #include namespace apache { namespace thrift { namespace protocol { /** * Helper class that encapsulates list metadata. * */ class TList { public: TList() : elemType_(T_STOP), size_(0) { } TList(TType t = T_STOP, int s = 0) : elemType_(t), size_(s) { } TType elemType_; int size_; }; } } } // apache::thrift::protocol #endif // #ifndef _THRIFT_TLIST_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc0000664000175000017500000006340615167543515024612 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TCOMPACTPROTOCOL_TCC_ #define _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_TCC_ 1 #include #include #include "thrift/config.h" /* * TCompactProtocol::i*ToZigzag depend on the fact that the right shift * operator on a signed integer is an arithmetic (sign-extending) shift. * If this is not the case, the current implementation will not work. * If anyone encounters this error, we can try to figure out the best * way to implement an arithmetic right shift on their platform. */ #if !defined(SIGNED_RIGHT_SHIFT_IS) || !defined(ARITHMETIC_RIGHT_SHIFT) # error "Unable to determine the behavior of a signed right shift" #endif #if SIGNED_RIGHT_SHIFT_IS != ARITHMETIC_RIGHT_SHIFT # error "TCompactProtocol currently only works if a signed right shift is arithmetic" #endif #ifdef __GNUC__ #define UNLIKELY(val) (__builtin_expect((val), 0)) #else #define UNLIKELY(val) (val) #endif namespace apache { namespace thrift { namespace protocol { namespace detail { namespace compact { enum 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_UUID = 0x0D }; const int8_t TTypeToCType[17] = { CT_STOP, // T_STOP 0, // unused CT_BOOLEAN_TRUE, // T_BOOL CT_BYTE, // T_BYTE CT_DOUBLE, // T_DOUBLE 0, // unused CT_I16, // T_I16 0, // unused CT_I32, // T_I32 0, // unused CT_I64, // T_I64 CT_BINARY, // T_STRING CT_STRUCT, // T_STRUCT CT_MAP, // T_MAP CT_SET, // T_SET CT_LIST, // T_LIST CT_UUID, // T_UUID }; }} // end detail::compact namespace template uint32_t TCompactProtocolT::writeMessageBegin( const std::string& name, const TMessageType messageType, const int32_t seqid) { uint32_t wsize = 0; wsize += writeByte(PROTOCOL_ID); wsize += writeByte((VERSION_N & VERSION_MASK) | ((static_cast(messageType) << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); wsize += writeVarint32(seqid); wsize += writeString(name); return wsize; } /** * Write a field header containing the field id and field type. If the * difference between the current field id and the last one is small (< 15), * then the field id will be encoded in the 4 MSB as a delta. Otherwise, the * field id will follow the type header as a zigzag varint. */ template uint32_t TCompactProtocolT::writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) { if (fieldType == T_BOOL) { booleanField_.name = name; booleanField_.fieldType = fieldType; booleanField_.fieldId = fieldId; } else { return writeFieldBeginInternal(name, fieldType, fieldId, -1); } return 0; } /** * Write the STOP symbol so we know there are no more fields in this struct. */ template uint32_t TCompactProtocolT::writeFieldStop() { return writeByte(T_STOP); } /** * Write a struct begin. This doesn't actually put anything on the wire. We * use it as an opportunity to put special placeholder markers on the field * stack so we can get the field id deltas correct. */ template uint32_t TCompactProtocolT::writeStructBegin(const char* name) { (void) name; lastField_.push(lastFieldId_); lastFieldId_ = 0; return 0; } /** * Write a struct end. This doesn't actually put anything on the wire. We use * this as an opportunity to pop the last field from the current struct off * of the field stack. */ template uint32_t TCompactProtocolT::writeStructEnd() { lastFieldId_ = lastField_.top(); lastField_.pop(); return 0; } /** * Write a List header. */ template uint32_t TCompactProtocolT::writeListBegin(const TType elemType, const uint32_t size) { return writeCollectionBegin(elemType, size); } /** * Write a set header. */ template uint32_t TCompactProtocolT::writeSetBegin(const TType elemType, const uint32_t size) { return writeCollectionBegin(elemType, size); } /** * Write a map header. If the map is empty, omit the key and value type * headers, as we don't need any additional information to skip it. */ template uint32_t TCompactProtocolT::writeMapBegin(const TType keyType, const TType valType, const uint32_t size) { uint32_t wsize = 0; if (size == 0) { wsize += writeByte(0); } else { wsize += writeVarint32(size); wsize += writeByte(getCompactType(keyType) << 4 | getCompactType(valType)); } return wsize; } /** * Write a boolean value. Potentially, this could be a boolean field, in * which case the field header info isn't written yet. If so, decide what the * right type header is for the value and then write the field header. * Otherwise, write a single byte. */ template uint32_t TCompactProtocolT::writeBool(const bool value) { uint32_t wsize = 0; if (booleanField_.name != nullptr) { // we haven't written the field header yet wsize += writeFieldBeginInternal(booleanField_.name, booleanField_.fieldType, booleanField_.fieldId, static_cast(value ? detail::compact::CT_BOOLEAN_TRUE : detail::compact::CT_BOOLEAN_FALSE)); booleanField_.name = nullptr; } else { // we're not part of a field, so just write the value wsize += writeByte(static_cast(value ? detail::compact::CT_BOOLEAN_TRUE : detail::compact::CT_BOOLEAN_FALSE)); } return wsize; } template uint32_t TCompactProtocolT::writeByte(const int8_t byte) { trans_->write(reinterpret_cast(&byte), 1); return 1; } /** * Write an i16 as a zigzag varint. */ template uint32_t TCompactProtocolT::writeI16(const int16_t i16) { return writeVarint32(i32ToZigzag(i16)); } /** * Write an i32 as a zigzag varint. */ template uint32_t TCompactProtocolT::writeI32(const int32_t i32) { return writeVarint32(i32ToZigzag(i32)); } /** * Write an i64 as a zigzag varint. */ template uint32_t TCompactProtocolT::writeI64(const int64_t i64) { return writeVarint64(i64ToZigzag(i64)); } /** * Write a double to the wire as 8 bytes. */ template uint32_t TCompactProtocolT::writeDouble(const double dub) { static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)"); static_assert(std::numeric_limits::is_iec559, "std::numeric_limits::is_iec559"); auto bits = bitwise_cast(dub); bits = THRIFT_htolell(bits); trans_->write(reinterpret_cast(&bits), 8); return 8; } /** * Write a string to the wire with a varint size preceding. */ template uint32_t TCompactProtocolT::writeString(const std::string& str) { return writeBinary(str); } template uint32_t TCompactProtocolT::writeBinary(const std::string& str) { if(str.size() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); auto ssize = static_cast(str.size()); uint32_t wsize = writeVarint32(ssize) ; // checking ssize + wsize > uint_max, but we don't want to overflow while checking for overflows. // transforming the check to ssize > uint_max - wsize if(ssize > (std::numeric_limits::max)() - wsize) throw TProtocolException(TProtocolException::SIZE_LIMIT); wsize += 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 // /** * The workhorse of writeFieldBegin. It has the option of doing a * 'type override' of the type header. This is used specifically in the * boolean field case. */ template int32_t TCompactProtocolT::writeFieldBeginInternal( const char* name, const TType fieldType, const int16_t fieldId, int8_t typeOverride) { (void) name; uint32_t wsize = 0; // if there's a type override, use that. int8_t typeToWrite = (typeOverride == -1 ? getCompactType(fieldType) : typeOverride); // check if we can use delta encoding for the field id if (fieldId > lastFieldId_ && fieldId - lastFieldId_ <= 15) { // write them together wsize += writeByte(static_cast((fieldId - lastFieldId_) << 4 | typeToWrite)); } else { // write them separate wsize += writeByte(typeToWrite); wsize += writeI16(fieldId); } lastFieldId_ = fieldId; return wsize; } /** * Abstract method for writing the start of lists and sets. List and sets on * the wire differ only by the type indicator. */ template uint32_t TCompactProtocolT::writeCollectionBegin(const TType elemType, int32_t size) { uint32_t wsize = 0; if (size <= 14) { wsize += writeByte(static_cast(size << 4 | getCompactType(elemType))); } else { wsize += writeByte(0xf0 | getCompactType(elemType)); wsize += writeVarint32(size); } return wsize; } /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. */ template uint32_t TCompactProtocolT::writeVarint32(uint32_t n) { uint8_t buf[5]; uint32_t wsize = 0; while (true) { if ((n & ~0x7F) == 0) { buf[wsize++] = static_cast(n); break; } else { buf[wsize++] = static_cast((n & 0x7F) | 0x80); n >>= 7; } } trans_->write(buf, wsize); return wsize; } /** * Write an i64 as a varint. Results in 1-10 bytes on the wire. */ template uint32_t TCompactProtocolT::writeVarint64(uint64_t n) { uint8_t buf[10]; uint32_t wsize = 0; while (true) { if ((n & ~0x7FL) == 0) { buf[wsize++] = static_cast(n); break; } else { buf[wsize++] = static_cast((n & 0x7F) | 0x80); n >>= 7; } } trans_->write(buf, wsize); return wsize; } /** * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ template uint64_t TCompactProtocolT::i64ToZigzag(const int64_t l) { return (static_cast(l) << 1) ^ (l >> 63); } /** * Convert n into a zigzag int. This allows negative numbers to be * represented compactly as a varint. */ template uint32_t TCompactProtocolT::i32ToZigzag(const int32_t n) { return (static_cast(n) << 1) ^ (n >> 31); } /** * Given a TType value, find the appropriate detail::compact::Types value */ template int8_t TCompactProtocolT::getCompactType(const TType ttype) { return detail::compact::TTypeToCType[ttype]; } // // Reading Methods // /** * Read a message header. */ template uint32_t TCompactProtocolT::readMessageBegin( std::string& name, TMessageType& messageType, int32_t& seqid) { uint32_t rsize = 0; int8_t protocolId; int8_t versionAndType; int8_t version; rsize += readByte(protocolId); if (protocolId != PROTOCOL_ID) { throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol identifier"); } rsize += readByte(versionAndType); version = static_cast(versionAndType & VERSION_MASK); if (version != VERSION_N) { throw TProtocolException(TProtocolException::BAD_VERSION, "Bad protocol version"); } messageType = static_cast((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); rsize += readVarint32(seqid); rsize += readString(name); return rsize; } /** * Read a struct begin. There's nothing on the wire for this, but it is our * opportunity to push a new struct begin marker on the field stack. */ template uint32_t TCompactProtocolT::readStructBegin(std::string& name) { name.clear(); lastField_.push(lastFieldId_); lastFieldId_ = 0; return 0; } /** * Doesn't actually consume any wire data, just removes the last field for * this struct from the field stack. */ template uint32_t TCompactProtocolT::readStructEnd() { lastFieldId_ = lastField_.top(); lastField_.pop(); return 0; } /** * Read a field header off the wire. */ template uint32_t TCompactProtocolT::readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) { (void) name; uint32_t rsize = 0; int8_t byte; int8_t type; rsize += readByte(byte); type = (byte & 0x0f); // if it's a stop, then we can return immediately, as the struct is over. if (type == T_STOP) { fieldType = T_STOP; fieldId = 0; return rsize; } // mask off the 4 MSB of the type header. it could contain a field id delta. 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 = static_cast(lastFieldId_ + modifier); } fieldType = getTType(type); // if this happens to be a boolean field, the value is encoded in the type if (type == detail::compact::CT_BOOLEAN_TRUE || type == detail::compact::CT_BOOLEAN_FALSE) { // save the boolean value in a special instance variable. boolValue_.hasBoolValue = true; boolValue_.boolValue = (type == detail::compact::CT_BOOLEAN_TRUE ? true : false); } // push the new field onto the field stack so we can keep the deltas going. lastFieldId_ = fieldId; return rsize; } /** * Read a map header off the wire. If the size is zero, skip reading the key * and value type. This means that 0-length maps will yield TMaps without the * "correct" types. */ template uint32_t TCompactProtocolT::readMapBegin(TType& keyType, TType& valType, uint32_t& size) { uint32_t rsize = 0; int8_t kvType = 0; int32_t msize = 0; rsize += readVarint32(msize); if (msize != 0) rsize += readByte(kvType); if (msize < 0) { throw TProtocolException(TProtocolException::NEGATIVE_SIZE); } else if (container_limit_ && msize > container_limit_) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } 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); return rsize; } /** * Read a list header off the wire. If the list size is 0-14, the size will * be packed into the element type header. If it's a longer list, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ template uint32_t TCompactProtocolT::readListBegin(TType& elemType, uint32_t& size) { int8_t size_and_type; uint32_t rsize = 0; int32_t lsize; rsize += readByte(size_and_type); lsize = (static_cast(size_and_type) >> 4) & 0x0f; if (lsize == 15) { rsize += readVarint32(lsize); } if (lsize < 0) { throw TProtocolException(TProtocolException::NEGATIVE_SIZE); } else if (container_limit_ && lsize > container_limit_) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } elemType = getTType(static_cast(size_and_type & 0x0f)); size = static_cast(lsize); TList list(elemType, size); checkReadBytesAvailable(list); return rsize; } /** * Read a set header off the wire. If the set size is 0-14, the size will * be packed into the element type header. If it's a longer set, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ template uint32_t TCompactProtocolT::readSetBegin(TType& elemType, uint32_t& size) { return readListBegin(elemType, size); } /** * Read a boolean off the wire. If this is a boolean field, the value should * already have been read during readFieldBegin, so we'll just consume the * pre-stored value. Otherwise, read a byte. */ template uint32_t TCompactProtocolT::readBool(bool& value) { if (boolValue_.hasBoolValue == true) { value = boolValue_.boolValue; boolValue_.hasBoolValue = false; return 0; } else { int8_t val; readByte(val); value = (val == detail::compact::CT_BOOLEAN_TRUE); return 1; } } /** * Read a single byte off the wire. Nothing interesting here. */ template uint32_t TCompactProtocolT::readByte(int8_t& byte) { uint8_t b[1]; trans_->readAll(b, 1); byte = static_cast(b[0]); return 1; } /** * Read an i16 from the wire as a zigzag varint. */ template uint32_t TCompactProtocolT::readI16(int16_t& i16) { int32_t value; uint32_t rsize = readVarint32(value); i16 = static_cast(zigzagToI32(value)); return rsize; } /** * Read an i32 from the wire as a zigzag varint. */ template uint32_t TCompactProtocolT::readI32(int32_t& i32) { int32_t value; uint32_t rsize = readVarint32(value); i32 = zigzagToI32(value); return rsize; } /** * Read an i64 from the wire as a zigzag varint. */ template uint32_t TCompactProtocolT::readI64(int64_t& i64) { int64_t value; uint32_t rsize = readVarint64(value); i64 = zigzagToI64(value); return rsize; } /** * No magic here - just read a double off the wire. */ template uint32_t TCompactProtocolT::readDouble(double& dub) { static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)"); static_assert(std::numeric_limits::is_iec559, "std::numeric_limits::is_iec559"); union { uint64_t bits; uint8_t b[8]; } u; trans_->readAll(u.b, 8); u.bits = THRIFT_letohll(u.bits); dub = bitwise_cast(u.bits); return 8; } template uint32_t TCompactProtocolT::readString(std::string& str) { return readBinary(str); } /** * Read a byte[] from the wire. */ template uint32_t TCompactProtocolT::readBinary(std::string& str) { int32_t rsize = 0; int32_t size; rsize += readVarint32(size); // Catch empty string case if (size == 0) { str.clear(); return rsize; } // Catch error cases if (size < 0) { throw TProtocolException(TProtocolException::NEGATIVE_SIZE); } if (string_limit_ > 0 && size > string_limit_) { 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_, static_cast(size)); if (new_string_buf == nullptr) { throw std::bad_alloc(); } string_buf_ = static_cast(new_string_buf); string_buf_size_ = size; } trans_->readAll(string_buf_, size); str.assign(reinterpret_cast(string_buf_), size); return rsize + static_cast(size); } /** * Read a TUuid from the wire. */ template uint32_t TCompactProtocolT::readUUID(TUuid& uuid) { return trans_->readAll(uuid.begin(), uuid.size()); } /** * 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. */ template uint32_t TCompactProtocolT::readVarint32(int32_t& i32) { int64_t val; uint32_t rsize = readVarint64(val); i32 = static_cast(val); return rsize; } /** * 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. */ template uint32_t TCompactProtocolT::readVarint64(int64_t& i64) { uint32_t rsize = 0; uint64_t val = 0; int shift = 0; uint8_t buf[10]; // 64 bits / (7 bits/byte) = 10 bytes. uint32_t buf_size = sizeof(buf); const uint8_t* borrowed = trans_->borrow(buf, &buf_size); // Fast path. if (borrowed != nullptr) { while (true) { uint8_t byte = borrowed[rsize]; rsize++; val |= static_cast(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { i64 = val; trans_->consume(rsize); return rsize; } // Have to check for invalid data so we don't crash. if (UNLIKELY(rsize == sizeof(buf))) { throw TProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes."); } } } // Slow path. else { while (true) { uint8_t byte; rsize += trans_->readAll(&byte, 1); val |= static_cast(byte & 0x7f) << shift; shift += 7; if (!(byte & 0x80)) { i64 = val; return rsize; } // Might as well check for invalid data on the slow path too. if (UNLIKELY(rsize >= sizeof(buf))) { throw TProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes."); } } } } /** * Convert from zigzag int to int. */ template int32_t TCompactProtocolT::zigzagToI32(uint32_t n) { return (n >> 1) ^ static_cast(-static_cast(n & 1)); } /** * Convert from zigzag long to long. */ template int64_t TCompactProtocolT::zigzagToI64(uint64_t n) { return (n >> 1) ^ static_cast(-static_cast(n & 1)); } template TType TCompactProtocolT::getTType(int8_t type) { switch (type) { case T_STOP: return T_STOP; case detail::compact::CT_BOOLEAN_FALSE: case detail::compact::CT_BOOLEAN_TRUE: return T_BOOL; case detail::compact::CT_BYTE: return T_BYTE; case detail::compact::CT_I16: return T_I16; case detail::compact::CT_I32: return T_I32; case detail::compact::CT_I64: return T_I64; case detail::compact::CT_DOUBLE: return T_DOUBLE; case detail::compact::CT_BINARY: return T_STRING; case detail::compact::CT_LIST: return T_LIST; case detail::compact::CT_SET: return T_SET; case detail::compact::CT_MAP: 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: ") + static_cast(type)); } } // Return the minimum number of bytes a type will consume on the wire template int TCompactProtocolT::getMinSerializedSize(TType type) { switch (type) { case T_STOP: return 1; // T_STOP needs to count itself case T_VOID: return 1; // T_VOID needs to count itself case T_BOOL: return sizeof(int8_t); case T_DOUBLE: return 8; // uses fixedLongToBytes() which always writes 8 bytes case T_BYTE: return sizeof(int8_t); case T_I16: return sizeof(int8_t); // zigzag case T_I32: return sizeof(int8_t); // zigzag case T_I64: return sizeof(int8_t); // zigzag case T_STRING: return sizeof(int8_t); // string length case T_STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP 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"); } } }}} // apache::thrift::protocol #endif // _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_TCC_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc0000664000175000017500000003757615167543515024461 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TBINARYPROTOCOL_TCC_ #define _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ 1 #include #include #include namespace apache { namespace thrift { namespace protocol { template uint32_t TBinaryProtocolT::writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid) { if (this->strict_write_) { int32_t version = (VERSION_1) | ((int32_t)messageType); uint32_t wsize = 0; wsize += writeI32(version); wsize += writeString(name); wsize += writeI32(seqid); return wsize; } else { uint32_t wsize = 0; wsize += writeString(name); wsize += writeByte((int8_t)messageType); wsize += writeI32(seqid); return wsize; } } template uint32_t TBinaryProtocolT::writeMessageEnd() { return 0; } template uint32_t TBinaryProtocolT::writeStructBegin(const char* name) { (void)name; return 0; } template uint32_t TBinaryProtocolT::writeStructEnd() { return 0; } template uint32_t TBinaryProtocolT::writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) { (void)name; uint32_t wsize = 0; wsize += writeByte((int8_t)fieldType); wsize += writeI16(fieldId); return wsize; } template uint32_t TBinaryProtocolT::writeFieldEnd() { return 0; } template uint32_t TBinaryProtocolT::writeFieldStop() { return writeByte((int8_t)T_STOP); } template uint32_t TBinaryProtocolT::writeMapBegin(const TType keyType, const TType valType, const uint32_t size) { uint32_t wsize = 0; wsize += writeByte((int8_t)keyType); wsize += writeByte((int8_t)valType); wsize += writeI32((int32_t)size); return wsize; } template uint32_t TBinaryProtocolT::writeMapEnd() { return 0; } template uint32_t TBinaryProtocolT::writeListBegin(const TType elemType, const uint32_t size) { uint32_t wsize = 0; wsize += writeByte((int8_t)elemType); wsize += writeI32((int32_t)size); return wsize; } template uint32_t TBinaryProtocolT::writeListEnd() { return 0; } template uint32_t TBinaryProtocolT::writeSetBegin(const TType elemType, const uint32_t size) { uint32_t wsize = 0; wsize += writeByte((int8_t)elemType); wsize += writeI32((int32_t)size); return wsize; } template uint32_t TBinaryProtocolT::writeSetEnd() { return 0; } template uint32_t TBinaryProtocolT::writeBool(const bool value) { uint8_t tmp = value ? 1 : 0; this->trans_->write(&tmp, 1); return 1; } template uint32_t TBinaryProtocolT::writeByte(const int8_t byte) { this->trans_->write((uint8_t*)&byte, 1); return 1; } template uint32_t TBinaryProtocolT::writeI16(const int16_t i16) { auto net = (int16_t)ByteOrder_::toWire16(i16); this->trans_->write((uint8_t*)&net, 2); return 2; } template uint32_t TBinaryProtocolT::writeI32(const int32_t i32) { auto net = (int32_t)ByteOrder_::toWire32(i32); this->trans_->write((uint8_t*)&net, 4); return 4; } template uint32_t TBinaryProtocolT::writeI64(const int64_t i64) { auto net = (int64_t)ByteOrder_::toWire64(i64); this->trans_->write((uint8_t*)&net, 8); return 8; } template uint32_t TBinaryProtocolT::writeDouble(const double dub) { static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)"); static_assert(std::numeric_limits::is_iec559, "std::numeric_limits::is_iec559"); auto bits = bitwise_cast(dub); bits = ByteOrder_::toWire64(bits); this->trans_->write((uint8_t*)&bits, 8); return 8; } template template uint32_t TBinaryProtocolT::writeString(const StrType& str) { if (str.size() > static_cast((std::numeric_limits::max)())) throw TProtocolException(TProtocolException::SIZE_LIMIT); auto size = static_cast(str.size()); uint32_t result = writeI32((int32_t)size); if (size > 0) { this->trans_->write((uint8_t*)str.data(), size); } return result + size; } template uint32_t TBinaryProtocolT::writeBinary(const std::string& str) { 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 */ template uint32_t TBinaryProtocolT::readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) { uint32_t result = 0; int32_t sz; result += readI32(sz); if (sz < 0) { // Check for correct version number int32_t version = sz & VERSION_MASK; if (version != VERSION_1) { throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier"); } messageType = (TMessageType)(sz & 0x000000ff); result += readString(name); result += readI32(seqid); } else { if (this->strict_read_) { throw TProtocolException(TProtocolException::BAD_VERSION, "No version identifier... old protocol client in strict mode?"); } else { // Handle pre-versioned input int8_t type; result += readStringBody(name, sz); result += readByte(type); messageType = (TMessageType)type; result += readI32(seqid); } } return result; } template uint32_t TBinaryProtocolT::readMessageEnd() { return 0; } template uint32_t TBinaryProtocolT::readStructBegin(std::string& name) { name.clear(); return 0; } template uint32_t TBinaryProtocolT::readStructEnd() { return 0; } template uint32_t TBinaryProtocolT::readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) { (void)name; uint32_t result = 0; int8_t type; result += readByte(type); fieldType = (TType)type; if (fieldType == T_STOP) { fieldId = 0; return result; } result += readI16(fieldId); return result; } template uint32_t TBinaryProtocolT::readFieldEnd() { return 0; } template uint32_t TBinaryProtocolT::readMapBegin(TType& keyType, TType& valType, uint32_t& size) { int8_t k, v; uint32_t result = 0; int32_t sizei; result += readByte(k); keyType = (TType)k; result += readByte(v); valType = (TType)v; result += readI32(sizei); if (sizei < 0) { throw TProtocolException(TProtocolException::NEGATIVE_SIZE); } else if (this->container_limit_ && sizei > this->container_limit_) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } size = (uint32_t)sizei; TMap map(keyType, valType, size); checkReadBytesAvailable(map); return result; } template uint32_t TBinaryProtocolT::readMapEnd() { return 0; } template uint32_t TBinaryProtocolT::readListBegin(TType& elemType, uint32_t& size) { int8_t e; uint32_t result = 0; int32_t sizei; result += readByte(e); elemType = (TType)e; result += readI32(sizei); if (sizei < 0) { throw TProtocolException(TProtocolException::NEGATIVE_SIZE); } else if (this->container_limit_ && sizei > this->container_limit_) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } size = (uint32_t)sizei; TList list(elemType, size); checkReadBytesAvailable(list); return result; } template uint32_t TBinaryProtocolT::readListEnd() { return 0; } template uint32_t TBinaryProtocolT::readSetBegin(TType& elemType, uint32_t& size) { int8_t e; uint32_t result = 0; int32_t sizei; result += readByte(e); elemType = (TType)e; result += readI32(sizei); if (sizei < 0) { throw TProtocolException(TProtocolException::NEGATIVE_SIZE); } else if (this->container_limit_ && sizei > this->container_limit_) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } size = (uint32_t)sizei; TSet set(elemType, size); checkReadBytesAvailable(set); return result; } template uint32_t TBinaryProtocolT::readSetEnd() { return 0; } template uint32_t TBinaryProtocolT::readBool(bool& value) { uint8_t b[1]; this->trans_->readAll(b, 1); value = *(int8_t*)b != 0; return 1; } template uint32_t TBinaryProtocolT::readByte(int8_t& byte) { uint8_t b[1]; this->trans_->readAll(b, 1); byte = *(int8_t*)b; return 1; } template uint32_t TBinaryProtocolT::readI16(int16_t& i16) { union bytes { uint8_t b[2]; int16_t all; } theBytes; this->trans_->readAll(theBytes.b, 2); i16 = (int16_t)ByteOrder_::fromWire16(theBytes.all); return 2; } template uint32_t TBinaryProtocolT::readI32(int32_t& i32) { union bytes { uint8_t b[4]; int32_t all; } theBytes; this->trans_->readAll(theBytes.b, 4); i32 = (int32_t)ByteOrder_::fromWire32(theBytes.all); return 4; } template uint32_t TBinaryProtocolT::readI64(int64_t& i64) { union bytes { uint8_t b[8]; int64_t all; } theBytes; this->trans_->readAll(theBytes.b, 8); i64 = (int64_t)ByteOrder_::fromWire64(theBytes.all); return 8; } template uint32_t TBinaryProtocolT::readDouble(double& dub) { static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)"); static_assert(std::numeric_limits::is_iec559, "std::numeric_limits::is_iec559"); union bytes { uint8_t b[8]; uint64_t all; } theBytes; this->trans_->readAll(theBytes.b, 8); theBytes.all = ByteOrder_::fromWire64(theBytes.all); dub = bitwise_cast(theBytes.all); return 8; } template template uint32_t TBinaryProtocolT::readString(StrType& str) { uint32_t result; int32_t size; result = readI32(size); return result + readStringBody(str, size); } template 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) { uint32_t result = 0; // Catch error cases if (size < 0) { throw TProtocolException(TProtocolException::NEGATIVE_SIZE); } if (this->string_limit_ > 0 && size > this->string_limit_) { throw TProtocolException(TProtocolException::SIZE_LIMIT); } // Catch empty string case if (size == 0) { str.clear(); return result; } // Try to borrow first uint32_t got = size; const uint8_t* borrow_buf = this->trans_->borrow(nullptr, &got); if (borrow_buf) { str.assign((const char*)borrow_buf, size); this->trans_->consume(size); return size; } // Check against MaxMessageSize before alloc trans_->checkReadBytesAvailable(size); str.resize(size); this->trans_->readAll(reinterpret_cast(&str[0]), size); return (uint32_t)size; } // Return the minimum number of bytes a type will consume on the wire template int TBinaryProtocolT::getMinSerializedSize(TType type) { switch (type) { case T_STOP: return 1; // T_STOP needs to count itself case T_VOID: return 1; // T_VOID needs to count itself case T_BOOL: return sizeof(int8_t); case T_BYTE: return sizeof(int8_t); case T_DOUBLE: return sizeof(double); case T_I16: return sizeof(short); case T_I32: return sizeof(int); case T_I64: return sizeof(long); case T_STRING: return sizeof(int); // string length case T_STRUCT: return 1; // empty struct needs at least 1 byte for the T_STOP 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"); } } } } } // apache::thrift::protocol #endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_TCC_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.h0000664000175000017500000000716415165535636025200 0ustar00buildbuild00000000000000/* * 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_TMULTIPLEXEDPROTOCOL_H_ #define THRIFT_TMULTIPLEXEDPROTOCOL_H_ 1 #include namespace apache { namespace thrift { namespace protocol { using std::shared_ptr; /** * TMultiplexedProtocol is a protocol-independent concrete decorator * that allows a Thrift client to communicate with a multiplexing Thrift server, * by prepending the service name to the function name during function calls. * * \note THIS IS NOT USED BY SERVERS. On the server, use * {@link apache::thrift::TMultiplexedProcessor TMultiplexedProcessor} to handle requests * from a multiplexing client. * * This example uses a single socket transport to invoke two services: * *
* shared_ptr transport(new TSocket("localhost", 9090)); * transport->open(); * * shared_ptr protocol(new TBinaryProtocol(transport)); * * shared_ptr mp1(new TMultiplexedProtocol(protocol, "Calculator")); * shared_ptr service1(new CalculatorClient(mp1)); * * shared_ptr mp2(new TMultiplexedProtocol(protocol, "WeatherReport")); * shared_ptr service2(new WeatherReportClient(mp2)); * * service1->add(2,2); * int temp = service2->getTemperature(); *
* * @see apache::thrift::protocol::TProtocolDecorator */ class TMultiplexedProtocol : public TProtocolDecorator { public: /** * Wrap the specified protocol, allowing it to be used to communicate with a * multiplexing server. The serviceName is required as it is * prepended to the message header so that the multiplexing server can broker * the function call to the proper service. * * \param _protocol Your communication protocol of choice, e.g. TBinaryProtocol. * \param _serviceName The service name of the service communicating via this protocol. */ TMultiplexedProtocol(shared_ptr _protocol, const std::string& _serviceName) : TProtocolDecorator(_protocol), serviceName(_serviceName), separator(":") {} ~TMultiplexedProtocol() override = default; /** * Prepends the service name to the function name, separated by TMultiplexedProtocol::SEPARATOR. * * \param [in] _name The name of the method to be called in the service. * \param [in] _type The type of message * \param [in] _name The sequential id of the message * * \throws TException Passed through from wrapped TProtocol instance. */ uint32_t writeMessageBegin_virt(const std::string& _name, const TMessageType _type, const int32_t _seqid) override; private: const std::string serviceName; const std::string separator; }; } } } #endif // THRIFT_TMULTIPLEXEDPROTOCOL_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TEnum.h0000664000175000017500000000330415165535636022056 0ustar00buildbuild00000000000000/* * 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_ENUM_H_ #define _THRIFT_ENUM_H_ namespace apache { namespace thrift { namespace protocol { /** * Enumerated definition of the types that the Thrift protocol supports. * Take special note of the T_END type which is used specifically to mark * the end of a sequence of fields. */ enum TType { T_STOP = 0, T_VOID = 1, T_BOOL = 2, T_BYTE = 3, T_I08 = 3, T_I16 = 6, T_I32 = 8, T_U64 = 9, T_I64 = 10, T_DOUBLE = 4, T_STRING = 11, T_UTF7 = 11, T_STRUCT = 12, T_MAP = 13, T_SET = 14, T_LIST = 15, T_UUID = 16, }; /** * Enumerated definition of the message types that the Thrift protocol * supports. */ enum TMessageType { T_CALL = 1, T_REPLY = 2, T_EXCEPTION = 3, T_ONEWAY = 4 }; }}} // apache::thrift::protocol #endif // #define _THRIFT_ENUM_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/THeaderProtocol.h0000664000175000017500000001366515167543515024074 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_THEADERPROTOCOL_H_ #define THRIFT_PROTOCOL_THEADERPROTOCOL_H_ 1 #include #include #include #include #include using apache::thrift::transport::THeaderTransport; namespace apache { namespace thrift { namespace protocol { /** * The header protocol for thrift. Reads unframed, framed, header format, * and http * */ class THeaderProtocol : public TVirtualProtocol { protected: public: void resetProtocol(); explicit THeaderProtocol(const std::shared_ptr& trans, uint16_t protoId = T_COMPACT_PROTOCOL) : TVirtualProtocol(std::shared_ptr(new THeaderTransport(trans))), trans_(std::dynamic_pointer_cast(getTransport())), protoId_(protoId) { trans_->setProtocolId(protoId); resetProtocol(); } THeaderProtocol(const std::shared_ptr& inTrans, const std::shared_ptr& outTrans, uint16_t protoId = T_COMPACT_PROTOCOL) : TVirtualProtocol( std::shared_ptr(new THeaderTransport(inTrans, outTrans))), trans_(std::dynamic_pointer_cast(getTransport())), protoId_(protoId) { trans_->setProtocolId(protoId); resetProtocol(); } ~THeaderProtocol() override = default; /** * Functions to work with headers by calling into THeaderTransport */ void setProtocolId(uint16_t protoId) { trans_->setProtocolId(protoId); resetProtocol(); } typedef THeaderTransport::StringToStringMap StringToStringMap; // these work with write headers void setHeader(const std::string& key, const std::string& value) { trans_->setHeader(key, value); } void clearHeaders() { trans_->clearHeaders(); } StringToStringMap& getWriteHeaders() { return trans_->getWriteHeaders(); } // these work with read headers const StringToStringMap& getHeaders() const { return trans_->getHeaders(); } /** * Writing functions. */ /*ol*/ uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqId); /*ol*/ uint32_t writeMessageEnd(); uint32_t writeStructBegin(const char* name); uint32_t writeStructEnd(); uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId); uint32_t writeFieldEnd(); uint32_t writeFieldStop(); uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size); uint32_t writeMapEnd(); uint32_t writeListBegin(const TType elemType, const uint32_t size); uint32_t writeListEnd(); uint32_t writeSetBegin(const TType elemType, const uint32_t size); uint32_t writeSetEnd(); uint32_t writeBool(const bool value); uint32_t writeByte(const int8_t byte); uint32_t writeI16(const int16_t i16); uint32_t writeI32(const int32_t i32); uint32_t writeI64(const int64_t i64); uint32_t writeDouble(const double dub); uint32_t writeString(const std::string& str); uint32_t writeBinary(const std::string& str); uint32_t writeUUID(const TUuid& uuid); /** * Reading functions */ /*ol*/ uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqId); /*ol*/ uint32_t readMessageEnd(); uint32_t readStructBegin(std::string& name); uint32_t readStructEnd(); uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId); uint32_t readFieldEnd(); uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size); uint32_t readMapEnd(); uint32_t readListBegin(TType& elemType, uint32_t& size); uint32_t readListEnd(); uint32_t readSetBegin(TType& elemType, uint32_t& size); uint32_t readSetEnd(); uint32_t readBool(bool& value); // Provide the default readBool() implementation for std::vector using TVirtualProtocol::readBool; uint32_t readByte(int8_t& byte); uint32_t readI16(int16_t& i16); uint32_t readI32(int32_t& i32); uint32_t readI64(int64_t& i64); uint32_t readDouble(double& dub); uint32_t readString(std::string& str); uint32_t readBinary(std::string& binary); uint32_t readUUID(TUuid& uuid); protected: std::shared_ptr trans_; std::shared_ptr proto_; uint32_t protoId_; }; class THeaderProtocolFactory : public TProtocolFactory { public: std::shared_ptr getProtocol(std::shared_ptr trans) override { auto* headerProtocol = new THeaderProtocol(trans, trans, T_BINARY_PROTOCOL); return std::shared_ptr(headerProtocol); } std::shared_ptr getProtocol( std::shared_ptr inTrans, std::shared_ptr outTrans) override { auto* headerProtocol = new THeaderProtocol(inTrans, outTrans, T_BINARY_PROTOCOL); return std::shared_ptr(headerProtocol); } }; } } } // apache::thrift::protocol #endif // #ifndef THRIFT_PROTOCOL_THEADERPROTOCOL_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TVirtualProtocol.h0000664000175000017500000004405115165535636024326 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TVIRTUALPROTOCOL_H_ #define _THRIFT_PROTOCOL_TVIRTUALPROTOCOL_H_ 1 #include namespace apache { namespace thrift { namespace protocol { using apache::thrift::transport::TTransport; /** * Helper class that provides default implementations of TProtocol methods. * * This class provides default implementations of the non-virtual TProtocol * methods. It exists primarily so TVirtualProtocol can derive from it. It * prevents TVirtualProtocol methods from causing infinite recursion if the * non-virtual methods are not overridden by the TVirtualProtocol subclass. * * You probably don't want to use this class directly. Use TVirtualProtocol * instead. */ class TProtocolDefaults : public TProtocol { public: uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) { (void)name; (void)messageType; (void)seqid; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readMessageEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readStructBegin(std::string& name) { (void)name; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readStructEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) { (void)name; (void)fieldType; (void)fieldId; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readFieldEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) { (void)keyType; (void)valType; (void)size; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readMapEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readListBegin(TType& elemType, uint32_t& size) { (void)elemType; (void)size; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readListEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readSetBegin(TType& elemType, uint32_t& size) { (void)elemType; (void)size; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readSetEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readBool(bool& value) { (void)value; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readBool(std::vector::reference value) { (void)value; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readByte(int8_t& byte) { (void)byte; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readI16(int16_t& i16) { (void)i16; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readI32(int32_t& i32) { (void)i32; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readI64(int64_t& i64) { (void)i64; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readDouble(double& dub) { (void)dub; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readString(std::string& str) { (void)str; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t readBinary(std::string& str) { (void)str; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support reading (yet)."); } uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid) { (void)name; (void)messageType; (void)seqid; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeMessageEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeStructBegin(const char* name) { (void)name; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeStructEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) { (void)name; (void)fieldType; (void)fieldId; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeFieldEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeFieldStop() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size) { (void)keyType; (void)valType; (void)size; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeMapEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeListBegin(const TType elemType, const uint32_t size) { (void)elemType; (void)size; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeListEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeSetBegin(const TType elemType, const uint32_t size) { (void)elemType; (void)size; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeSetEnd() { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeBool(const bool value) { (void)value; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeByte(const int8_t byte) { (void)byte; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeI16(const int16_t i16) { (void)i16; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeI32(const int32_t i32) { (void)i32; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeI64(const int64_t i64) { (void)i64; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeDouble(const double dub) { (void)dub; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeString(const std::string& str) { (void)str; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t writeBinary(const std::string& str) { (void)str; throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "this protocol does not support writing (yet)."); } uint32_t skip(TType type) { return ::apache::thrift::protocol::skip(*this, type); } protected: TProtocolDefaults(std::shared_ptr ptrans) : TProtocol(ptrans) {} }; /** * Concrete TProtocol classes should inherit from TVirtualProtocol * so they don't have to manually override virtual methods. */ template class TVirtualProtocol : public Super_ { public: /** * Writing functions. */ uint32_t writeMessageBegin_virt(const std::string& name, const TMessageType messageType, const int32_t seqid) override { return static_cast(this)->writeMessageBegin(name, messageType, seqid); } uint32_t writeMessageEnd_virt() override { return static_cast(this)->writeMessageEnd(); } uint32_t writeStructBegin_virt(const char* name) override { return static_cast(this)->writeStructBegin(name); } uint32_t writeStructEnd_virt() override { return static_cast(this)->writeStructEnd(); } uint32_t writeFieldBegin_virt(const char* name, const TType fieldType, const int16_t fieldId) override { return static_cast(this)->writeFieldBegin(name, fieldType, fieldId); } uint32_t writeFieldEnd_virt() override { return static_cast(this)->writeFieldEnd(); } uint32_t writeFieldStop_virt() override { return static_cast(this)->writeFieldStop(); } uint32_t writeMapBegin_virt(const TType keyType, const TType valType, const uint32_t size) override { return static_cast(this)->writeMapBegin(keyType, valType, size); } uint32_t writeMapEnd_virt() override { return static_cast(this)->writeMapEnd(); } uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) override { return static_cast(this)->writeListBegin(elemType, size); } uint32_t writeListEnd_virt() override { return static_cast(this)->writeListEnd(); } uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) override { return static_cast(this)->writeSetBegin(elemType, size); } uint32_t writeSetEnd_virt() override { return static_cast(this)->writeSetEnd(); } uint32_t writeBool_virt(const bool value) override { return static_cast(this)->writeBool(value); } uint32_t writeByte_virt(const int8_t byte) override { return static_cast(this)->writeByte(byte); } uint32_t writeI16_virt(const int16_t i16) override { return static_cast(this)->writeI16(i16); } uint32_t writeI32_virt(const int32_t i32) override { return static_cast(this)->writeI32(i32); } uint32_t writeI64_virt(const int64_t i64) override { return static_cast(this)->writeI64(i64); } uint32_t writeDouble_virt(const double dub) override { return static_cast(this)->writeDouble(dub); } uint32_t writeString_virt(const std::string& str) override { return static_cast(this)->writeString(str); } uint32_t writeBinary_virt(const std::string& str) override { return static_cast(this)->writeBinary(str); } uint32_t writeUUID_virt(const TUuid& uuid) override { return static_cast(this)->writeUUID(uuid); } /** * Reading functions */ uint32_t readMessageBegin_virt(std::string& name, TMessageType& messageType, int32_t& seqid) override { return static_cast(this)->readMessageBegin(name, messageType, seqid); } uint32_t readMessageEnd_virt() override { return static_cast(this)->readMessageEnd(); } uint32_t readStructBegin_virt(std::string& name) override { return static_cast(this)->readStructBegin(name); } uint32_t readStructEnd_virt() override { return static_cast(this)->readStructEnd(); } uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) override { return static_cast(this)->readFieldBegin(name, fieldType, fieldId); } uint32_t readFieldEnd_virt() override { return static_cast(this)->readFieldEnd(); } uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) override { return static_cast(this)->readMapBegin(keyType, valType, size); } uint32_t readMapEnd_virt() override { return static_cast(this)->readMapEnd(); } uint32_t readListBegin_virt(TType& elemType, uint32_t& size) override { return static_cast(this)->readListBegin(elemType, size); } uint32_t readListEnd_virt() override { return static_cast(this)->readListEnd(); } uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) override { return static_cast(this)->readSetBegin(elemType, size); } uint32_t readSetEnd_virt() override { return static_cast(this)->readSetEnd(); } uint32_t readBool_virt(bool& value) override { return static_cast(this)->readBool(value); } uint32_t readBool_virt(std::vector::reference value) override { return static_cast(this)->readBool(value); } uint32_t readByte_virt(int8_t& byte) override { return static_cast(this)->readByte(byte); } uint32_t readI16_virt(int16_t& i16) override { return static_cast(this)->readI16(i16); } uint32_t readI32_virt(int32_t& i32) override { return static_cast(this)->readI32(i32); } uint32_t readI64_virt(int64_t& i64) override { return static_cast(this)->readI64(i64); } uint32_t readDouble_virt(double& dub) override { return static_cast(this)->readDouble(dub); } uint32_t readString_virt(std::string& str) override { return static_cast(this)->readString(str); } uint32_t readBinary_virt(std::string& str) override { 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); } /* * Provide a default skip() implementation that uses non-virtual read * methods. * * Note: subclasses that use TVirtualProtocol to derive from another protocol * implementation (i.e., not TProtocolDefaults) should beware that this may * override any non-default skip() implementation provided by the parent * transport class. They may need to explicitly redefine skip() to call the * correct parent implementation, if desired. */ uint32_t skip(TType type) { auto* const prot = static_cast(this); return ::apache::thrift::protocol::skip(*prot, type); } /* * Provide a default readBool() implementation for use with * std::vector, that behaves the same as reading into a normal bool. * * Subclasses can override this if desired, but there normally shouldn't * be a need to. */ uint32_t readBool(std::vector::reference value) { bool b = false; uint32_t ret = static_cast(this)->readBool(b); value = b; return ret; } using Super_::readBool; // so we don't hide readBool(bool&) protected: TVirtualProtocol(std::shared_ptr ptrans) : Super_(ptrans) {} }; } } } // apache::thrift::protocol #endif // #define _THRIFT_PROTOCOL_TVIRTUALPROTOCOL_H_ 1 thrift-0.23.0/lib/cpp/src/thrift/protocol/TProtocolTap.h0000664000175000017500000001146515167543515023424 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TPROTOCOLTAP_H_ #define _THRIFT_PROTOCOL_TPROTOCOLTAP_H_ 1 #include namespace apache { namespace thrift { namespace protocol { using apache::thrift::transport::TTransport; /** * Puts a wiretap on a protocol object. Any reads to this class are passed * through to an enclosed protocol object, but also mirrored as write to a * second protocol object. * */ class TProtocolTap : public TVirtualProtocol { public: TProtocolTap(std::shared_ptr source, std::shared_ptr sink) : TVirtualProtocol(source->getTransport()), source_(source), sink_(sink) {} uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) { uint32_t rv = source_->readMessageBegin(name, messageType, seqid); sink_->writeMessageBegin(name, messageType, seqid); return rv; } uint32_t readMessageEnd() { uint32_t rv = source_->readMessageEnd(); sink_->writeMessageEnd(); return rv; } uint32_t readStructBegin(std::string& name) { uint32_t rv = source_->readStructBegin(name); sink_->writeStructBegin(name.c_str()); return rv; } uint32_t readStructEnd() { uint32_t rv = source_->readStructEnd(); sink_->writeStructEnd(); return rv; } uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) { uint32_t rv = source_->readFieldBegin(name, fieldType, fieldId); if (fieldType == T_STOP) { sink_->writeFieldStop(); } else { sink_->writeFieldBegin(name.c_str(), fieldType, fieldId); } return rv; } uint32_t readFieldEnd() { uint32_t rv = source_->readFieldEnd(); sink_->writeFieldEnd(); return rv; } uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) { uint32_t rv = source_->readMapBegin(keyType, valType, size); sink_->writeMapBegin(keyType, valType, size); return rv; } uint32_t readMapEnd() { uint32_t rv = source_->readMapEnd(); sink_->writeMapEnd(); return rv; } uint32_t readListBegin(TType& elemType, uint32_t& size) { uint32_t rv = source_->readListBegin(elemType, size); sink_->writeListBegin(elemType, size); return rv; } uint32_t readListEnd() { uint32_t rv = source_->readListEnd(); sink_->writeListEnd(); return rv; } uint32_t readSetBegin(TType& elemType, uint32_t& size) { uint32_t rv = source_->readSetBegin(elemType, size); sink_->writeSetBegin(elemType, size); return rv; } uint32_t readSetEnd() { uint32_t rv = source_->readSetEnd(); sink_->writeSetEnd(); return rv; } uint32_t readBool(bool& value) { uint32_t rv = source_->readBool(value); sink_->writeBool(value); return rv; } // Provide the default readBool() implementation for std::vector using TVirtualProtocol::readBool; uint32_t readByte(int8_t& byte) { uint32_t rv = source_->readByte(byte); sink_->writeByte(byte); return rv; } uint32_t readI16(int16_t& i16) { uint32_t rv = source_->readI16(i16); sink_->writeI16(i16); return rv; } uint32_t readI32(int32_t& i32) { uint32_t rv = source_->readI32(i32); sink_->writeI32(i32); return rv; } uint32_t readI64(int64_t& i64) { uint32_t rv = source_->readI64(i64); sink_->writeI64(i64); return rv; } uint32_t readDouble(double& dub) { uint32_t rv = source_->readDouble(dub); sink_->writeDouble(dub); return rv; } uint32_t readString(std::string& str) { uint32_t rv = source_->readString(str); sink_->writeString(str); return rv; } uint32_t readBinary(std::string& str) { uint32_t rv = source_->readBinary(str); sink_->writeBinary(str); return rv; } uint32_t readUUID(TUuid& uuid) { uint32_t rv = source_->readUUID(uuid); sink_->writeUUid(uuid); return rv; } private: std::shared_ptr source_; std::shared_ptr sink_; }; } } } // apache::thrift::protocol #endif // #define _THRIFT_PROTOCOL_TPROTOCOLTAP_H_ 1 thrift-0.23.0/lib/cpp/src/thrift/protocol/TBinaryProtocol.h0000664000175000017500000002067115165535636024126 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TBINARYPROTOCOL_H_ #define _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_ 1 #include #include #include namespace apache { namespace thrift { namespace protocol { /** * The default binary protocol for thrift. Writes all data in a very basic * binary format, essentially just spitting out the raw bytes. * */ template class TBinaryProtocolT : public TVirtualProtocol > { public: static const int32_t VERSION_MASK = ((int32_t)0xffff0000); static const int32_t VERSION_1 = ((int32_t)0x80010000); // VERSION_2 (0x80020000) was taken by TDenseProtocol (which has since been removed) TBinaryProtocolT(std::shared_ptr trans) : TVirtualProtocol >(trans), trans_(trans.get()), string_limit_(0), container_limit_(0), strict_read_(false), strict_write_(true) {} TBinaryProtocolT(std::shared_ptr trans, int32_t string_limit, int32_t container_limit, bool strict_read, bool strict_write) : TVirtualProtocol >(trans), trans_(trans.get()), string_limit_(string_limit), container_limit_(container_limit), strict_read_(strict_read), strict_write_(strict_write) {} void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; } void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; } void setStrict(bool strict_read, bool strict_write) { strict_read_ = strict_read; strict_write_ = strict_write; } /** * Writing functions. */ /*ol*/ uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid); /*ol*/ uint32_t writeMessageEnd(); inline uint32_t writeStructBegin(const char* name); inline uint32_t writeStructEnd(); inline uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId); inline uint32_t writeFieldEnd(); inline uint32_t writeFieldStop(); inline uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size); inline uint32_t writeMapEnd(); inline uint32_t writeListBegin(const TType elemType, const uint32_t size); inline uint32_t writeListEnd(); inline uint32_t writeSetBegin(const TType elemType, const uint32_t size); inline uint32_t writeSetEnd(); inline uint32_t writeBool(const bool value); inline uint32_t writeByte(const int8_t byte); inline uint32_t writeI16(const int16_t i16); inline uint32_t writeI32(const int32_t i32); inline uint32_t writeI64(const int64_t i64); inline uint32_t writeDouble(const double dub); template inline uint32_t writeString(const StrType& str); inline uint32_t writeBinary(const std::string& str); inline uint32_t writeUUID(const TUuid& uuid); /** * Reading functions */ /*ol*/ uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid); /*ol*/ uint32_t readMessageEnd(); inline uint32_t readStructBegin(std::string& name); inline uint32_t readStructEnd(); inline uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId); inline uint32_t readFieldEnd(); inline uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size); inline uint32_t readMapEnd(); inline uint32_t readListBegin(TType& elemType, uint32_t& size); inline uint32_t readListEnd(); inline uint32_t readSetBegin(TType& elemType, uint32_t& size); inline uint32_t readSetEnd(); inline uint32_t readBool(bool& value); // Provide the default readBool() implementation for std::vector using TVirtualProtocol >::readBool; inline uint32_t readByte(int8_t& byte); inline uint32_t readI16(int16_t& i16); inline uint32_t readI32(int32_t& i32); inline uint32_t readI64(int64_t& i64); inline uint32_t readDouble(double& dub); template inline uint32_t readString(StrType& str); inline uint32_t readBinary(std::string& str); inline uint32_t readUUID(TUuid& uuid); int getMinSerializedSize(TType type) override; void checkReadBytesAvailable(TSet& set) override { trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); } void checkReadBytesAvailable(TList& list) override { trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); } void checkReadBytesAvailable(TMap& map) override { int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); trans_->checkReadBytesAvailable(map.size_ * elmSize); } protected: template uint32_t readStringBody(StrType& str, int32_t sz); Transport_* trans_; int32_t string_limit_; int32_t container_limit_; // Enforce presence of version identifier bool strict_read_; bool strict_write_; }; typedef TBinaryProtocolT TBinaryProtocol; typedef TBinaryProtocolT TLEBinaryProtocol; /** * Constructs binary protocol handlers */ template class TBinaryProtocolFactoryT : public TProtocolFactory { public: TBinaryProtocolFactoryT() : string_limit_(0), container_limit_(0), strict_read_(false), strict_write_(true) {} TBinaryProtocolFactoryT(int32_t string_limit, int32_t container_limit, bool strict_read, bool strict_write) : string_limit_(string_limit), container_limit_(container_limit), strict_read_(strict_read), strict_write_(strict_write) {} ~TBinaryProtocolFactoryT() override = default; void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; } void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; } void setStrict(bool strict_read, bool strict_write) { strict_read_ = strict_read; strict_write_ = strict_write; } std::shared_ptr getProtocol(std::shared_ptr trans) override { std::shared_ptr specific_trans = std::dynamic_pointer_cast(trans); TProtocol* prot; if (specific_trans) { prot = new TBinaryProtocolT(specific_trans, string_limit_, container_limit_, strict_read_, strict_write_); } else { prot = new TBinaryProtocolT(trans, string_limit_, container_limit_, strict_read_, strict_write_); } return std::shared_ptr(prot); } private: int32_t string_limit_; int32_t container_limit_; bool strict_read_; bool strict_write_; }; typedef TBinaryProtocolFactoryT TBinaryProtocolFactory; typedef TBinaryProtocolFactoryT TLEBinaryProtocolFactory; } } } // apache::thrift::protocol #include #endif // #ifndef _THRIFT_PROTOCOL_TBINARYPROTOCOL_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp0000664000175000017500000001601515167543515024417 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_THEADERPROTOCOL_CPP_ #define THRIFT_PROTOCOL_THEADERPROTOCOL_CPP_ 1 #include #include #include #include #include #include namespace apache { namespace thrift { namespace protocol { void THeaderProtocol::resetProtocol() { if (proto_ && protoId_ == trans_->getProtocolId()) { return; } protoId_ = trans_->getProtocolId(); switch (protoId_) { case T_BINARY_PROTOCOL: proto_ = std::make_shared >(trans_); break; case T_COMPACT_PROTOCOL: proto_ = std::make_shared >(trans_); break; default: throw TApplicationException(TApplicationException::INVALID_PROTOCOL, "Unknown protocol requested"); } } uint32_t THeaderProtocol::writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqId) { resetProtocol(); // Reset in case we changed protocols trans_->setSequenceNumber(seqId); return proto_->writeMessageBegin(name, messageType, seqId); } uint32_t THeaderProtocol::writeMessageEnd() { return proto_->writeMessageEnd(); } uint32_t THeaderProtocol::writeStructBegin(const char* name) { return proto_->writeStructBegin(name); } uint32_t THeaderProtocol::writeStructEnd() { return proto_->writeStructEnd(); } uint32_t THeaderProtocol::writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) { return proto_->writeFieldBegin(name, fieldType, fieldId); } uint32_t THeaderProtocol::writeFieldEnd() { return proto_->writeFieldEnd(); } uint32_t THeaderProtocol::writeFieldStop() { return proto_->writeFieldStop(); } uint32_t THeaderProtocol::writeMapBegin(const TType keyType, const TType valType, const uint32_t size) { return proto_->writeMapBegin(keyType, valType, size); } uint32_t THeaderProtocol::writeMapEnd() { return proto_->writeMapEnd(); } uint32_t THeaderProtocol::writeListBegin(const TType elemType, const uint32_t size) { return proto_->writeListBegin(elemType, size); } uint32_t THeaderProtocol::writeListEnd() { return proto_->writeListEnd(); } uint32_t THeaderProtocol::writeSetBegin(const TType elemType, const uint32_t size) { return proto_->writeSetBegin(elemType, size); } uint32_t THeaderProtocol::writeSetEnd() { return proto_->writeSetEnd(); } uint32_t THeaderProtocol::writeBool(const bool value) { return proto_->writeBool(value); } uint32_t THeaderProtocol::writeByte(const int8_t byte) { return proto_->writeByte(byte); } uint32_t THeaderProtocol::writeI16(const int16_t i16) { return proto_->writeI16(i16); } uint32_t THeaderProtocol::writeI32(const int32_t i32) { return proto_->writeI32(i32); } uint32_t THeaderProtocol::writeI64(const int64_t i64) { return proto_->writeI64(i64); } uint32_t THeaderProtocol::writeDouble(const double dub) { return proto_->writeDouble(dub); } uint32_t THeaderProtocol::writeString(const std::string& str) { return proto_->writeString(str); } uint32_t THeaderProtocol::writeBinary(const std::string& str) { return proto_->writeBinary(str); } uint32_t THeaderProtocol::writeUUID(const TUuid& uuid) { return proto_->writeUUID(uuid); } /** * Reading functions */ uint32_t THeaderProtocol::readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqId) { // Read the next frame, and change protocols if needed try { trans_->resetProtocol(); resetProtocol(); } catch (const TApplicationException& ex) { writeMessageBegin("", T_EXCEPTION, 0); ex.write((TProtocol*)this); writeMessageEnd(); trans_->flush(); // The framing is still good, but we don't know about this protocol. // In the future, this could be made a client-side only error if // connection pooling is used. throw ex; } return proto_->readMessageBegin(name, messageType, seqId); } uint32_t THeaderProtocol::readMessageEnd() { return proto_->readMessageEnd(); } uint32_t THeaderProtocol::readStructBegin(std::string& name) { return proto_->readStructBegin(name); } uint32_t THeaderProtocol::readStructEnd() { return proto_->readStructEnd(); } uint32_t THeaderProtocol::readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) { return proto_->readFieldBegin(name, fieldType, fieldId); } uint32_t THeaderProtocol::readFieldEnd() { return proto_->readFieldEnd(); } uint32_t THeaderProtocol::readMapBegin(TType& keyType, TType& valType, uint32_t& size) { return proto_->readMapBegin(keyType, valType, size); } uint32_t THeaderProtocol::readMapEnd() { return proto_->readMapEnd(); } uint32_t THeaderProtocol::readListBegin(TType& elemType, uint32_t& size) { return proto_->readListBegin(elemType, size); } uint32_t THeaderProtocol::readListEnd() { return proto_->readListEnd(); } uint32_t THeaderProtocol::readSetBegin(TType& elemType, uint32_t& size) { return proto_->readSetBegin(elemType, size); } uint32_t THeaderProtocol::readSetEnd() { return proto_->readSetEnd(); } uint32_t THeaderProtocol::readBool(bool& value) { return proto_->readBool(value); } uint32_t THeaderProtocol::readByte(int8_t& byte) { return proto_->readByte(byte); } uint32_t THeaderProtocol::readI16(int16_t& i16) { return proto_->readI16(i16); } uint32_t THeaderProtocol::readI32(int32_t& i32) { return proto_->readI32(i32); } uint32_t THeaderProtocol::readI64(int64_t& i64) { return proto_->readI64(i64); } uint32_t THeaderProtocol::readDouble(double& dub) { return proto_->readDouble(dub); } uint32_t THeaderProtocol::readString(std::string& str) { return proto_->readString(str); } uint32_t THeaderProtocol::readBinary(std::string& binary) { return proto_->readBinary(binary); } uint32_t THeaderProtocol::readUUID(TUuid& uuid) { return proto_->readUUID(uuid); } } } } // apache::thrift::protocol #endif // #ifndef THRIFT_PROTOCOL_THEADERPROTOCOL_CPP_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TBase64Utils.cpp0000664000175000017500000001106115165535636023551 0ustar00buildbuild00000000000000/* * 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 using std::string; namespace apache { namespace thrift { namespace protocol { static const uint8_t* kBase64EncodeTable = (const uint8_t*)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; void base64_encode(const uint8_t* in, uint32_t len, uint8_t* buf) { buf[0] = kBase64EncodeTable[(in[0] >> 2) & 0x3f]; if (len == 3) { buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)]; buf[2] = kBase64EncodeTable[((in[1] << 2) & 0x3c) | ((in[2] >> 6) & 0x03)]; buf[3] = kBase64EncodeTable[in[2] & 0x3f]; } else if (len == 2) { buf[1] = kBase64EncodeTable[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)]; buf[2] = kBase64EncodeTable[(in[1] << 2) & 0x3c]; } else { // len == 1 buf[1] = kBase64EncodeTable[(in[0] << 4) & 0x30]; } } static const uint8_t kBase64DecodeTable[256] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; void base64_decode(uint8_t* buf, uint32_t len) { buf[0] = (kBase64DecodeTable[buf[0]] << 2) | (kBase64DecodeTable[buf[1]] >> 4); if (len > 2) { buf[1] = ((kBase64DecodeTable[buf[1]] << 4) & 0xf0) | (kBase64DecodeTable[buf[2]] >> 2); if (len > 3) { buf[2] = ((kBase64DecodeTable[buf[2]] << 6) & 0xc0) | (kBase64DecodeTable[buf[3]]); } } } } } } // apache::thrift::protocol thrift-0.23.0/lib/cpp/src/thrift/protocol/TBase64Utils.h0000664000175000017500000000313515165535636023221 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TBASE64UTILS_H_ #define _THRIFT_PROTOCOL_TBASE64UTILS_H_ #include #include namespace apache { namespace thrift { namespace protocol { // in must be at least len bytes // len must be 1, 2, or 3 // buf must be a buffer of at least 4 bytes and may not overlap in // the data is not padded with '='; the caller can do this if desired void base64_encode(const uint8_t* in, uint32_t len, uint8_t* buf); // buf must be a buffer of at least 4 bytes and contain base64 encoded values // buf will be changed to contain output bytes // len is number of bytes to consume from input (must be 2, 3, or 4) // no '=' padding should be included in the input void base64_decode(uint8_t* buf, uint32_t len); } } } // apache::thrift::protocol #endif // #define _THRIFT_PROTOCOL_TBASE64UTILS_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.cpp0000664000175000017500000000311215165535636025520 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace protocol { uint32_t TMultiplexedProtocol::writeMessageBegin_virt(const std::string& _name, const TMessageType _type, const int32_t _seqid) { if (_type == T_CALL || _type == T_ONEWAY) { return TProtocolDecorator::writeMessageBegin_virt(serviceName + separator + _name, _type, _seqid); } else { return TProtocolDecorator::writeMessageBegin_virt(_name, _type, _seqid); } } } } } thrift-0.23.0/lib/cpp/src/thrift/protocol/TDebugProtocol.h0000664000175000017500000001304115165535636023721 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TDEBUGPROTOCOL_H_ #define _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_ 1 #include #include namespace apache { namespace thrift { namespace protocol { /* !!! EXPERIMENTAL CODE !!! This protocol is very much a work in progress. It doesn't handle many cases properly. It throws exceptions in many cases. It probably segfaults in many cases. Bug reports and feature requests are welcome. Complaints are not. :R */ /** * Protocol that prints the payload in a nice human-readable format. * Reading from this protocol is not supported. * */ class TDebugProtocol : public TVirtualProtocol { private: enum write_state_t { UNINIT, STRUCT, LIST, SET, MAP_KEY, MAP_VALUE }; public: TDebugProtocol(std::shared_ptr trans) : TVirtualProtocol(trans), trans_(trans.get()), string_limit_(DEFAULT_STRING_LIMIT), string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE) { write_state_.push_back(UNINIT); } static const int32_t DEFAULT_STRING_LIMIT = 256; static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16; void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; } void setStringPrefixSize(int32_t string_prefix_size) { string_prefix_size_ = string_prefix_size; } uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid); uint32_t writeMessageEnd(); uint32_t writeStructBegin(const char* name); uint32_t writeStructEnd(); uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId); uint32_t writeFieldEnd(); uint32_t writeFieldStop(); uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size); uint32_t writeMapEnd(); uint32_t writeListBegin(const TType elemType, const uint32_t size); uint32_t writeListEnd(); uint32_t writeSetBegin(const TType elemType, const uint32_t size); uint32_t writeSetEnd(); uint32_t writeBool(const bool value); uint32_t writeByte(const int8_t byte); uint32_t writeI16(const int16_t i16); uint32_t writeI32(const int32_t i32); uint32_t writeI64(const int64_t i64); uint32_t writeDouble(const double dub); uint32_t writeString(const std::string& str); uint32_t writeBinary(const std::string& str); uint32_t writeUUID(const TUuid& uuid); private: void indentUp(); void indentDown(); uint32_t writePlain(const std::string& str); uint32_t writeIndented(const std::string& str); uint32_t startItem(); uint32_t endItem(); uint32_t writeItem(const std::string& str); static std::string fieldTypeName(TType type); TTransport* trans_; int32_t string_limit_; int32_t string_prefix_size_; std::string indent_str_; static const int indent_inc = 2; std::vector write_state_; std::vector list_idx_; }; /** * Constructs debug protocol handlers */ class TDebugProtocolFactory : public TProtocolFactory { public: TDebugProtocolFactory() = default; ~TDebugProtocolFactory() override = default; std::shared_ptr getProtocol(std::shared_ptr trans) override { return std::shared_ptr(new TDebugProtocol(trans)); } }; } } } // apache::thrift::protocol // TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this. #include namespace apache { namespace thrift { template std::string ThriftDebugString(const ThriftStruct& ts) { using namespace apache::thrift::transport; using namespace apache::thrift::protocol; auto* buffer = new TMemoryBuffer; std::shared_ptr trans(buffer); TDebugProtocol protocol(trans); ts.write(&protocol); uint8_t* buf; uint32_t size; buffer->getBuffer(&buf, &size); return std::string((char*)buf, (unsigned int)size); } // TODO(dreiss): This is badly broken. Don't use it unless you are me. #if 0 template std::string DebugString(const std::vector& vec) { using namespace apache::thrift::transport; using namespace apache::thrift::protocol; TMemoryBuffer* buffer = new TMemoryBuffer; std::shared_ptr trans(buffer); TDebugProtocol protocol(trans); // I am gross! protocol.writeStructBegin("SomeRandomVector"); // TODO: Fix this with a trait. protocol.writeListBegin((TType)99, vec.size()); typename std::vector::const_iterator it; for (it = vec.begin(); it != vec.end(); ++it) { it->write(&protocol); } protocol.writeListEnd(); uint8_t* buf; uint32_t size; buffer->getBuffer(&buf, &size); return std::string((char*)buf, (unsigned int)size); } #endif // 0 } } // apache::thrift #endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TProtocol.cpp0000664000175000017500000000214515165535636023310 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace protocol { TProtocol::~TProtocol() = default; uint32_t TProtocol::skip_virt(TType type) { return ::apache::thrift::protocol::skip(*this, type); } TProtocolFactory::~TProtocolFactory() = default; }}} // apache::thrift::protocol thrift-0.23.0/lib/cpp/src/thrift/protocol/TProtocolTypes.h0000664000175000017500000000216515165535636024004 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TPROTOCOLTYPES_H_ #define THRIFT_PROTOCOL_TPROTOCOLTYPES_H_ 1 namespace apache { namespace thrift { namespace protocol { enum PROTOCOL_TYPES { T_BINARY_PROTOCOL = 0, T_JSON_PROTOCOL = 1, T_COMPACT_PROTOCOL = 2, }; } } } // apache::thrift::protocol #endif // #define _THRIFT_PROTOCOL_TPROTOCOLTYPES_H_ 1 thrift-0.23.0/lib/cpp/src/thrift/protocol/TProtocol.h0000664000175000017500000005403515167543515022757 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TPROTOCOL_H_ #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1 #ifdef _WIN32 // Including Winsock2.h adds problematic macros like min() and max(). // Try to work around: #ifndef NOMINMAX #define NOMINMAX #define _THRIFT_UNDEF_NOMINMAX #endif #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #define _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #endif // Need to come before any Windows.h includes #include #ifdef _THRIFT_UNDEF_NOMINMAX #undef NOMINMAX #undef _THRIFT_UNDEF_NOMINMAX #endif #ifdef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN #undef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN #endif #endif #include #include #include #include #include #include #include #include #ifdef HAVE_NETINET_IN_H #include #endif #include #include #include #include #include // Use this to get around strict aliasing rules. // For example, uint64_t i = bitwise_cast(returns_double()); // The most obvious implementation is to just cast a pointer, // but that doesn't work. // For a pretty in-depth explanation of the problem, see // http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html template static inline To bitwise_cast(From from) { static_assert(sizeof(From) == sizeof(To), "sizeof(From) == sizeof(To)"); // BAD!!! These are all broken with -O2. //return *reinterpret_cast(&from); // BAD!!! //return *static_cast(static_cast(&from)); // BAD!!! //return *(To*)(void*)&from; // BAD!!! // Super clean and paritally blessed by section 3.9 of the standard. //unsigned char c[sizeof(from)]; //memcpy(c, &from, sizeof(from)); //To to; //memcpy(&to, c, sizeof(c)); //return to; // Slightly more questionable. // Same code emitted by GCC. //To to; //memcpy(&to, &from, sizeof(from)); //return to; // Technically undefined, but almost universally supported, // and the most efficient implementation. union { From f; To t; } u; u.f = from; return u.t; } #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef __ZEPHYR__ # include # define __THRIFT_BYTE_ORDER __BYTE_ORDER__ # define __THRIFT_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ # define __THRIFT_BIG_ENDIAN __ORDER_BIG_ENDIAN__ # if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN # undef bswap_64 # undef bswap_32 # undef bswap_16 # endif #endif #ifndef __THRIFT_BYTE_ORDER # if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) # define __THRIFT_BYTE_ORDER BYTE_ORDER # define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN # define __THRIFT_BIG_ENDIAN BIG_ENDIAN # else # include # if BOOST_ENDIAN_BIG_BYTE # define __THRIFT_BYTE_ORDER 4321 # define __THRIFT_LITTLE_ENDIAN 0 # define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER # elif BOOST_ENDIAN_LITTLE_BYTE # define __THRIFT_BYTE_ORDER 1234 # define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER # define __THRIFT_BIG_ENDIAN 0 # endif # ifdef BOOST_LITTLE_ENDIAN # else # endif # endif #endif #if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN # if !defined(THRIFT_ntohll) # define THRIFT_ntohll(n) (n) # define THRIFT_htonll(n) (n) # endif # if defined(__GNUC__) && defined(__GLIBC__) # include # define THRIFT_htolell(n) bswap_64(n) # define THRIFT_letohll(n) bswap_64(n) # define THRIFT_htolel(n) bswap_32(n) # define THRIFT_letohl(n) bswap_32(n) # define THRIFT_htoles(n) bswap_16(n) # define THRIFT_letohs(n) bswap_16(n) # else /* GNUC & GLIBC */ # define bswap_64(n) \ ( (((n) & 0xff00000000000000ull) >> 56) \ | (((n) & 0x00ff000000000000ull) >> 40) \ | (((n) & 0x0000ff0000000000ull) >> 24) \ | (((n) & 0x000000ff00000000ull) >> 8) \ | (((n) & 0x00000000ff000000ull) << 8) \ | (((n) & 0x0000000000ff0000ull) << 24) \ | (((n) & 0x000000000000ff00ull) << 40) \ | (((n) & 0x00000000000000ffull) << 56) ) # define bswap_32(n) \ ( (((n) & 0xff000000ul) >> 24) \ | (((n) & 0x00ff0000ul) >> 8) \ | (((n) & 0x0000ff00ul) << 8) \ | (((n) & 0x000000fful) << 24) ) # define bswap_16(n) \ ( (((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) # define THRIFT_letohl(n) bswap_32(n) # define THRIFT_htoles(n) bswap_16(n) # define THRIFT_letohs(n) bswap_16(n) # endif /* GNUC & GLIBC */ #elif __THRIFT_BYTE_ORDER == __THRIFT_LITTLE_ENDIAN # define THRIFT_htolell(n) (n) # define THRIFT_letohll(n) (n) # define THRIFT_htolel(n) (n) # define THRIFT_letohl(n) (n) # define THRIFT_htoles(n) (n) # define THRIFT_letohs(n) (n) # if defined(__GNUC__) && defined(__GLIBC__) # include # 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(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) ( (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!" #endif namespace apache { namespace thrift { namespace protocol { using apache::thrift::transport::TTransport; /** * Abstract class for a thrift protocol driver. These are all the methods that * a protocol must implement. Essentially, there must be some way of reading * and writing all the base types, plus a mechanism for writing out structs * with indexed fields. * * TProtocol objects should not be shared across multiple encoding contexts, * as they may need to maintain internal state in some protocols (i.e. XML). * Note that is is acceptable for the TProtocol module to do its own internal * buffered reads/writes to the underlying TTransport where appropriate (i.e. * when parsing an input XML stream, reading should be batched rather than * looking ahead character by character for a close tag). * */ class TProtocol { public: virtual ~TProtocol(); /** * Writing functions. */ virtual uint32_t writeMessageBegin_virt(const std::string& name, const TMessageType messageType, const int32_t seqid) = 0; virtual uint32_t writeMessageEnd_virt() = 0; virtual uint32_t writeStructBegin_virt(const char* name) = 0; virtual uint32_t writeStructEnd_virt() = 0; virtual uint32_t writeFieldBegin_virt(const char* name, const TType fieldType, const int16_t fieldId) = 0; virtual uint32_t writeFieldEnd_virt() = 0; virtual uint32_t writeFieldStop_virt() = 0; virtual uint32_t writeMapBegin_virt(const TType keyType, const TType valType, const uint32_t size) = 0; virtual uint32_t writeMapEnd_virt() = 0; virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) = 0; virtual uint32_t writeListEnd_virt() = 0; virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) = 0; virtual uint32_t writeSetEnd_virt() = 0; virtual uint32_t writeBool_virt(const bool value) = 0; virtual uint32_t writeByte_virt(const int8_t byte) = 0; virtual uint32_t writeI16_virt(const int16_t i16) = 0; virtual uint32_t writeI32_virt(const int32_t i32) = 0; virtual uint32_t writeI64_virt(const int64_t i64) = 0; virtual uint32_t writeDouble_virt(const double dub) = 0; virtual uint32_t writeString_virt(const std::string& str) = 0; 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) { T_VIRTUAL_CALL(); return writeMessageBegin_virt(name, messageType, seqid); } uint32_t writeMessageEnd() { T_VIRTUAL_CALL(); return writeMessageEnd_virt(); } uint32_t writeStructBegin(const char* name) { T_VIRTUAL_CALL(); return writeStructBegin_virt(name); } uint32_t writeStructEnd() { T_VIRTUAL_CALL(); return writeStructEnd_virt(); } uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) { T_VIRTUAL_CALL(); return writeFieldBegin_virt(name, fieldType, fieldId); } uint32_t writeFieldEnd() { T_VIRTUAL_CALL(); return writeFieldEnd_virt(); } uint32_t writeFieldStop() { T_VIRTUAL_CALL(); return writeFieldStop_virt(); } uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size) { T_VIRTUAL_CALL(); return writeMapBegin_virt(keyType, valType, size); } uint32_t writeMapEnd() { T_VIRTUAL_CALL(); return writeMapEnd_virt(); } uint32_t writeListBegin(const TType elemType, const uint32_t size) { T_VIRTUAL_CALL(); return writeListBegin_virt(elemType, size); } uint32_t writeListEnd() { T_VIRTUAL_CALL(); return writeListEnd_virt(); } uint32_t writeSetBegin(const TType elemType, const uint32_t size) { T_VIRTUAL_CALL(); return writeSetBegin_virt(elemType, size); } uint32_t writeSetEnd() { T_VIRTUAL_CALL(); return writeSetEnd_virt(); } uint32_t writeBool(const bool value) { T_VIRTUAL_CALL(); return writeBool_virt(value); } uint32_t writeByte(const int8_t byte) { T_VIRTUAL_CALL(); return writeByte_virt(byte); } uint32_t writeI16(const int16_t i16) { T_VIRTUAL_CALL(); return writeI16_virt(i16); } uint32_t writeI32(const int32_t i32) { T_VIRTUAL_CALL(); return writeI32_virt(i32); } uint32_t writeI64(const int64_t i64) { T_VIRTUAL_CALL(); return writeI64_virt(i64); } uint32_t writeDouble(const double dub) { T_VIRTUAL_CALL(); return writeDouble_virt(dub); } uint32_t writeString(const std::string& str) { T_VIRTUAL_CALL(); return writeString_virt(str); } uint32_t writeBinary(const std::string& str) { T_VIRTUAL_CALL(); return writeBinary_virt(str); } uint32_t writeUUID(const TUuid& uuid) { T_VIRTUAL_CALL(); return writeUUID_virt(uuid); } /** * Reading functions */ virtual uint32_t readMessageBegin_virt(std::string& name, TMessageType& messageType, int32_t& seqid) = 0; virtual uint32_t readMessageEnd_virt() = 0; virtual uint32_t readStructBegin_virt(std::string& name) = 0; virtual uint32_t readStructEnd_virt() = 0; virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) = 0; virtual uint32_t readFieldEnd_virt() = 0; virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) = 0; virtual uint32_t readMapEnd_virt() = 0; virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) = 0; virtual uint32_t readListEnd_virt() = 0; virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) = 0; virtual uint32_t readSetEnd_virt() = 0; virtual uint32_t readBool_virt(bool& value) = 0; virtual uint32_t readBool_virt(std::vector::reference value) = 0; virtual uint32_t readByte_virt(int8_t& byte) = 0; virtual uint32_t readI16_virt(int16_t& i16) = 0; virtual uint32_t readI32_virt(int32_t& i32) = 0; virtual uint32_t readI64_virt(int64_t& i64) = 0; virtual uint32_t readDouble_virt(double& dub) = 0; virtual uint32_t readString_virt(std::string& str) = 0; 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); } uint32_t readMessageEnd() { T_VIRTUAL_CALL(); return readMessageEnd_virt(); } uint32_t readStructBegin(std::string& name) { T_VIRTUAL_CALL(); return readStructBegin_virt(name); } uint32_t readStructEnd() { T_VIRTUAL_CALL(); return readStructEnd_virt(); } uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) { T_VIRTUAL_CALL(); return readFieldBegin_virt(name, fieldType, fieldId); } uint32_t readFieldEnd() { T_VIRTUAL_CALL(); return readFieldEnd_virt(); } uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) { T_VIRTUAL_CALL(); return readMapBegin_virt(keyType, valType, size); } uint32_t readMapEnd() { T_VIRTUAL_CALL(); return readMapEnd_virt(); } uint32_t readListBegin(TType& elemType, uint32_t& size) { T_VIRTUAL_CALL(); return readListBegin_virt(elemType, size); } uint32_t readListEnd() { T_VIRTUAL_CALL(); return readListEnd_virt(); } uint32_t readSetBegin(TType& elemType, uint32_t& size) { T_VIRTUAL_CALL(); return readSetBegin_virt(elemType, size); } uint32_t readSetEnd() { T_VIRTUAL_CALL(); return readSetEnd_virt(); } uint32_t readBool(bool& value) { T_VIRTUAL_CALL(); return readBool_virt(value); } uint32_t readByte(int8_t& byte) { T_VIRTUAL_CALL(); return readByte_virt(byte); } uint32_t readI16(int16_t& i16) { T_VIRTUAL_CALL(); return readI16_virt(i16); } uint32_t readI32(int32_t& i32) { T_VIRTUAL_CALL(); return readI32_virt(i32); } uint32_t readI64(int64_t& i64) { T_VIRTUAL_CALL(); return readI64_virt(i64); } uint32_t readDouble(double& dub) { T_VIRTUAL_CALL(); return readDouble_virt(dub); } uint32_t readString(std::string& str) { T_VIRTUAL_CALL(); return readString_virt(str); } uint32_t readBinary(std::string& str) { T_VIRTUAL_CALL(); 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() * to work with std::vector. */ uint32_t readBool(std::vector::reference value) { T_VIRTUAL_CALL(); return readBool_virt(value); } /** * Method to arbitrarily skip over data. */ uint32_t skip(TType type) { T_VIRTUAL_CALL(); return skip_virt(type); } virtual uint32_t skip_virt(TType type); inline std::shared_ptr getTransport() { return ptrans_; } // TODO: remove these two calls, they are for backwards // compatibility inline std::shared_ptr getInputTransport() { return ptrans_; } inline std::shared_ptr getOutputTransport() { return ptrans_; } // input and output recursion depth are kept separate so that one protocol // can be used concurrently for both input and output. void incrementInputRecursionDepth() { if (recursion_limit_ < ++input_recursion_depth_) { throw TProtocolException(TProtocolException::DEPTH_LIMIT); } } void decrementInputRecursionDepth() { --input_recursion_depth_; } void incrementOutputRecursionDepth() { if (recursion_limit_ < ++output_recursion_depth_) { throw TProtocolException(TProtocolException::DEPTH_LIMIT); } } void decrementOutputRecursionDepth() { --output_recursion_depth_; } uint32_t getRecursionLimit() const {return recursion_limit_;} void setRecurisionLimit(uint32_t depth) {recursion_limit_ = depth;} // Returns the minimum amount of bytes needed to store the smallest possible instance of TType. virtual int getMinSerializedSize(TType type) { THRIFT_UNUSED_VARIABLE(type); return 0; } protected: TProtocol(std::shared_ptr ptrans) : ptrans_(ptrans), input_recursion_depth_(0), output_recursion_depth_(0), recursion_limit_(ptrans->getConfiguration()->getRecursionLimit()) {} virtual void checkReadBytesAvailable(TSet& set) { ptrans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); } virtual void checkReadBytesAvailable(TList& list) { ptrans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); } virtual void checkReadBytesAvailable(TMap& map) { int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); ptrans_->checkReadBytesAvailable(map.size_ * elmSize); } std::shared_ptr ptrans_; private: TProtocol() = default; uint32_t input_recursion_depth_; uint32_t output_recursion_depth_; uint32_t recursion_limit_; }; /** * Constructs input and output protocol objects given transports. */ class TProtocolFactory { public: TProtocolFactory() = default; virtual ~TProtocolFactory(); virtual std::shared_ptr getProtocol(std::shared_ptr trans) = 0; virtual std::shared_ptr getProtocol(std::shared_ptr inTrans, std::shared_ptr outTrans) { (void)outTrans; return getProtocol(inTrans); } }; /** * Dummy protocol class. * * This class does nothing, and should never be instantiated. * It is used only by the generator code. */ class TDummyProtocol : public TProtocol {}; // This is the default / legacy choice struct TNetworkBigEndian { static uint16_t toWire16(uint16_t x) {return htons(x);} static uint32_t toWire32(uint32_t x) {return htonl(x);} static uint64_t toWire64(uint64_t x) {return THRIFT_htonll(x);} static uint16_t fromWire16(uint16_t x) {return ntohs(x);} static uint32_t fromWire32(uint32_t x) {return ntohl(x);} static uint64_t fromWire64(uint64_t x) {return THRIFT_ntohll(x);} }; // On most systems, this will be a bit faster than TNetworkBigEndian struct TNetworkLittleEndian { static uint16_t toWire16(uint16_t x) {return THRIFT_htoles(x);} static uint32_t toWire32(uint32_t x) {return THRIFT_htolel(x);} static uint64_t toWire64(uint64_t x) {return THRIFT_htolell(x);} static uint16_t fromWire16(uint16_t x) {return THRIFT_letohs(x);} static uint32_t fromWire32(uint32_t x) {return THRIFT_letohl(x);} static uint64_t fromWire64(uint64_t x) {return THRIFT_letohll(x);} }; struct TOutputRecursionTracker { TProtocol &prot_; TOutputRecursionTracker(TProtocol &prot) : prot_(prot) { prot_.incrementOutputRecursionDepth(); } ~TOutputRecursionTracker() { prot_.decrementOutputRecursionDepth(); } }; struct TInputRecursionTracker { TProtocol &prot_; TInputRecursionTracker(TProtocol &prot) : prot_(prot) { prot_.incrementInputRecursionDepth(); } ~TInputRecursionTracker() { prot_.decrementInputRecursionDepth(); } }; /** * Helper template for implementing TProtocol::skip(). * * Templatized to avoid having to make virtual function calls. */ template uint32_t skip(Protocol_& prot, TType type) { TInputRecursionTracker tracker(prot); switch (type) { case T_BOOL: { bool boolv; return prot.readBool(boolv); } case T_BYTE: { int8_t bytev = 0; return prot.readByte(bytev); } case T_I16: { int16_t i16; return prot.readI16(i16); } case T_I32: { int32_t i32; return prot.readI32(i32); } case T_I64: { int64_t i64; return prot.readI64(i64); } case T_DOUBLE: { double dub; return prot.readDouble(dub); } case T_STRING: { std::string str; return prot.readBinary(str); } case T_STRUCT: { uint32_t result = 0; std::string name; int16_t fid; TType ftype; result += prot.readStructBegin(name); while (true) { result += prot.readFieldBegin(name, ftype, fid); if (ftype == T_STOP) { break; } result += skip(prot, ftype); result += prot.readFieldEnd(); } result += prot.readStructEnd(); return result; } case T_MAP: { uint32_t result = 0; TType keyType; TType valType; uint32_t i, size; result += prot.readMapBegin(keyType, valType, size); for (i = 0; i < size; i++) { result += skip(prot, keyType); result += skip(prot, valType); } result += prot.readMapEnd(); return result; } case T_SET: { uint32_t result = 0; TType elemType; uint32_t i, size; result += prot.readSetBegin(elemType, size); for (i = 0; i < size; i++) { result += skip(prot, elemType); } result += prot.readSetEnd(); return result; } case T_LIST: { uint32_t result = 0; TType elemType; uint32_t i, size; result += prot.readListBegin(elemType, size); for (i = 0; i < size; i++) { result += skip(prot, elemType); } result += prot.readListEnd(); return result; } case T_UUID: { TUuid uuid; return prot.readUUID(uuid); } default: break; } throw TProtocolException(TProtocolException::INVALID_DATA, "invalid TType"); } }}} // apache::thrift::protocol #endif // #define _THRIFT_PROTOCOL_TPROTOCOL_H_ 1 thrift-0.23.0/lib/cpp/src/thrift/protocol/TSet.h0000664000175000017500000000255115165535636021710 0ustar00buildbuild00000000000000/* * 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_TSET_H_ #define _THRIFT_TSET_H_ #include #include namespace apache { namespace thrift { namespace protocol { /** * Helper class that encapsulates set metadata. * */ class TSet { public: TSet() : elemType_(T_STOP), size_(0) { } TSet(TType t, int s) : elemType_(t), size_(s) { } TSet(TList list) : elemType_(list.elemType_), size_(list.size_) { } TType elemType_; int size_; }; } } } // apache::thrift::protocol #endif // #ifndef _THRIFT_TSET_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp0000664000175000017500000007524315165535636024013 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include using namespace apache::thrift::transport; namespace apache { namespace thrift { namespace protocol { // Static data static const uint8_t kJSONObjectStart = '{'; static const uint8_t kJSONObjectEnd = '}'; static const uint8_t kJSONArrayStart = '['; static const uint8_t kJSONArrayEnd = ']'; static const uint8_t kJSONPairSeparator = ':'; static const uint8_t kJSONElemSeparator = ','; static const uint8_t kJSONBackslash = '\\'; static const uint8_t kJSONStringDelimiter = '"'; static const uint8_t kJSONEscapeChar = 'u'; static const std::string kJSONEscapePrefix("\\u00"); static const uint32_t kThriftVersion1 = 1; static const std::string kThriftNan("NaN"); static const std::string kThriftInfinity("Infinity"); static const std::string kThriftNegativeInfinity("-Infinity"); static const std::string kTypeNameBool("tf"); static const std::string kTypeNameByte("i8"); static const std::string kTypeNameI16("i16"); static const std::string kTypeNameI32("i32"); static const std::string kTypeNameI64("i64"); static const std::string kTypeNameDouble("dbl"); static const std::string kTypeNameStruct("rec"); 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) { case T_BOOL: return kTypeNameBool; case T_BYTE: return kTypeNameByte; case T_I16: return kTypeNameI16; case T_I32: return kTypeNameI32; case T_I64: return kTypeNameI64; case T_DOUBLE: return kTypeNameDouble; case T_STRING: return kTypeNameString; case T_STRUCT: return kTypeNameStruct; case T_MAP: return kTypeNameMap; case T_SET: return kTypeNameSet; case T_LIST: return kTypeNameList; case T_UUID: return kTypeNameUuid; default: throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "Unrecognized type"); } } static TType getTypeIDForTypeName(const std::string& name) { TType result = T_STOP; // Sentinel value if (name.length() > 1) { switch (name[0]) { case 'd': result = T_DOUBLE; break; case 'i': switch (name[1]) { case '8': result = T_BYTE; break; case '1': result = T_I16; break; case '3': result = T_I32; break; case '6': result = T_I64; break; } break; case 'l': result = T_LIST; break; case 'm': result = T_MAP; break; case 'r': result = T_STRUCT; break; case 's': if (name[1] == 't') { result = T_STRING; } else if (name[1] == 'e') { result = T_SET; } break; case 't': result = T_BOOL; break; case 'u': result = T_UUID; break; } } if (result == T_STOP) { throw TProtocolException(TProtocolException::NOT_IMPLEMENTED, "Unrecognized type"); } return result; } // This table describes the handling for the first 0x30 characters // 0 : escape using "\u00xx" notation // 1 : just output index // : escape using "\" notation static const uint8_t kJSONCharTable[0x30] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 }; // This string's characters must match up with the elements in kEscapeCharVals. // I don't have '/' on this list even though it appears on www.json.org -- // it is not in the RFC const static std::string kEscapeChars("\"\\bfnrt"); // The elements of this array must match up with the sequence of characters in // kEscapeChars const static uint8_t kEscapeCharVals[7] = { '"', '\\', '\b', '\f', '\n', '\r', '\t', }; // Static helper functions // Read 1 character from the transport trans and verify that it is the // expected character ch. // Throw a protocol exception if it is not. static uint32_t readSyntaxChar(TJSONProtocol::LookaheadReader& reader, uint8_t ch) { uint8_t ch2 = reader.read(); if (ch2 != ch) { throw TProtocolException(TProtocolException::INVALID_DATA, "Expected \'" + std::string((char*)&ch, 1) + "\'; got \'" + std::string((char*)&ch2, 1) + "\'."); } return 1; } // Return the integer value of a hex character ch. // Throw a protocol exception if the character is not [0-9a-f]. static uint8_t hexVal(uint8_t ch) { if ((ch >= '0') && (ch <= '9')) { return ch - '0'; } else if ((ch >= 'a') && (ch <= 'f')) { return ch - 'a' + 10; } else { throw TProtocolException(TProtocolException::INVALID_DATA, "Expected hex val ([0-9a-f]); got \'" + std::string((char*)&ch, 1) + "\'."); } } // Return the hex character representing the integer val. The value is masked // to make sure it is in the correct range. static uint8_t hexChar(uint8_t val) { val &= 0x0F; if (val < 10) { return val + '0'; } else { return val - 10 + 'a'; } } // Return true if the character ch is in [-+0-9.Ee]; false otherwise static bool isJSONNumeric(uint8_t ch) { switch (ch) { case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'E': case 'e': return true; } return false; } // Return true if the code unit is high surrogate static bool isHighSurrogate(uint16_t val) { return val >= 0xD800 && val <= 0xDBFF; } // Return true if the code unit is low surrogate static bool isLowSurrogate(uint16_t val) { return val >= 0xDC00 && val <= 0xDFFF; } /** * Class to serve as base JSON context and as base class for other context * implementations */ class TJSONContext { public: TJSONContext() = default; virtual ~TJSONContext() = default; /** * Write context data to the transport. Default is to do nothing. */ virtual uint32_t write(TTransport& trans) { (void)trans; return 0; }; /** * Read context data from the transport. Default is to do nothing. */ virtual uint32_t read(TJSONProtocol::LookaheadReader& reader) { (void)reader; return 0; }; /** * Return true if numbers need to be escaped as strings in this context. * Default behavior is to return false. */ virtual bool escapeNum() { return false; } }; // Context class for object member key-value pairs class JSONPairContext : public TJSONContext { public: JSONPairContext() : first_(true), colon_(true) {} uint32_t write(TTransport& trans) override { if (first_) { first_ = false; colon_ = true; return 0; } else { trans.write(colon_ ? &kJSONPairSeparator : &kJSONElemSeparator, 1); colon_ = !colon_; return 1; } } uint32_t read(TJSONProtocol::LookaheadReader& reader) override { if (first_) { first_ = false; colon_ = true; return 0; } else { uint8_t ch = (colon_ ? kJSONPairSeparator : kJSONElemSeparator); colon_ = !colon_; return readSyntaxChar(reader, ch); } } // Numbers must be turned into strings if they are the key part of a pair bool escapeNum() override { return colon_; } private: bool first_; bool colon_; }; // Context class for lists class JSONListContext : public TJSONContext { public: JSONListContext() : first_(true) {} uint32_t write(TTransport& trans) override { if (first_) { first_ = false; return 0; } else { trans.write(&kJSONElemSeparator, 1); return 1; } } uint32_t read(TJSONProtocol::LookaheadReader& reader) override { if (first_) { first_ = false; return 0; } else { return readSyntaxChar(reader, kJSONElemSeparator); } } private: bool first_; }; TJSONProtocol::TJSONProtocol(std::shared_ptr ptrans) : TVirtualProtocol(ptrans), trans_(ptrans.get()), context_(new TJSONContext()), reader_(*ptrans) { } TJSONProtocol::~TJSONProtocol() = default; void TJSONProtocol::pushContext(std::shared_ptr c) { contexts_.push(context_); context_ = c; } void TJSONProtocol::popContext() { context_ = contexts_.top(); contexts_.pop(); } // Write the character ch as a JSON escape sequence ("\u00xx") uint32_t TJSONProtocol::writeJSONEscapeChar(uint8_t ch) { trans_->write((const uint8_t*)kJSONEscapePrefix.c_str(), static_cast(kJSONEscapePrefix.length())); uint8_t outCh = hexChar(ch >> 4); trans_->write(&outCh, 1); outCh = hexChar(ch); trans_->write(&outCh, 1); return 6; } // Write the character ch as part of a JSON string, escaping as appropriate. uint32_t TJSONProtocol::writeJSONChar(uint8_t ch) { if (ch >= 0x30) { if (ch == kJSONBackslash) { // Only special character >= 0x30 is '\' trans_->write(&kJSONBackslash, 1); trans_->write(&kJSONBackslash, 1); return 2; } else { trans_->write(&ch, 1); return 1; } } else { uint8_t outCh = kJSONCharTable[ch]; // Check if regular character, backslash escaped, or JSON escaped if (outCh == 1) { trans_->write(&ch, 1); return 1; } else if (outCh > 1) { trans_->write(&kJSONBackslash, 1); trans_->write(&outCh, 1); return 2; } else { return writeJSONEscapeChar(ch); } } } // Write out the contents of the string str as a JSON string, escaping // characters as appropriate. uint32_t TJSONProtocol::writeJSONString(const std::string& str) { uint32_t result = context_->write(*trans_); result += 2; // For quotes trans_->write(&kJSONStringDelimiter, 1); std::string::const_iterator iter(str.begin()); std::string::const_iterator end(str.end()); while (iter != end) { result += writeJSONChar(*iter++); } trans_->write(&kJSONStringDelimiter, 1); return result; } // Write out the contents of the string as JSON string, base64-encoding // the string's contents, and escaping as appropriate uint32_t TJSONProtocol::writeJSONBase64(const std::string& str) { uint32_t result = context_->write(*trans_); result += 2; // For quotes trans_->write(&kJSONStringDelimiter, 1); uint8_t b[4]; const auto* bytes = (const uint8_t*)str.c_str(); if (str.length() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); auto len = static_cast(str.length()); while (len >= 3) { // Encode 3 bytes at a time base64_encode(bytes, 3, b); trans_->write(b, 4); result += 4; bytes += 3; len -= 3; } if (len) { // Handle remainder base64_encode(bytes, len, b); trans_->write(b, len + 1); result += len + 1; } trans_->write(&kJSONStringDelimiter, 1); return result; } // Convert the given integer type to a JSON number, or a string // if the context requires it (eg: key in a map pair). template uint32_t TJSONProtocol::writeJSONInteger(NumberType num) { uint32_t result = context_->write(*trans_); std::string val(to_string(num)); bool escapeNum = context_->escapeNum(); if (escapeNum) { trans_->write(&kJSONStringDelimiter, 1); result += 1; } if (val.length() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); trans_->write((const uint8_t*)val.c_str(), static_cast(val.length())); result += static_cast(val.length()); if (escapeNum) { trans_->write(&kJSONStringDelimiter, 1); result += 1; } return result; } namespace { std::string doubleToString(double d) { std::ostringstream str; str.imbue(std::locale::classic()); const std::streamsize max_digits10 = 2 + std::numeric_limits::digits10; str.precision(max_digits10); str << d; return str.str(); } } // Convert the given double to a JSON string, which is either the number, // "NaN" or "Infinity" or "-Infinity". uint32_t TJSONProtocol::writeJSONDouble(double num) { uint32_t result = context_->write(*trans_); std::string val; bool special = false; switch (std::fpclassify(num)) { case FP_INFINITE: if (std::signbit(num)) { val = kThriftNegativeInfinity; } else { val = kThriftInfinity; } special = true; break; case FP_NAN: val = kThriftNan; special = true; break; default: val = doubleToString(num); break; } bool escapeNum = special || context_->escapeNum(); if (escapeNum) { trans_->write(&kJSONStringDelimiter, 1); result += 1; } if (val.length() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); trans_->write((const uint8_t*)val.c_str(), static_cast(val.length())); result += static_cast(val.length()); if (escapeNum) { trans_->write(&kJSONStringDelimiter, 1); result += 1; } return result; } uint32_t TJSONProtocol::writeJSONObjectStart() { uint32_t result = context_->write(*trans_); trans_->write(&kJSONObjectStart, 1); pushContext(std::shared_ptr(new JSONPairContext())); return result + 1; } uint32_t TJSONProtocol::writeJSONObjectEnd() { popContext(); trans_->write(&kJSONObjectEnd, 1); return 1; } uint32_t TJSONProtocol::writeJSONArrayStart() { uint32_t result = context_->write(*trans_); trans_->write(&kJSONArrayStart, 1); pushContext(std::shared_ptr(new JSONListContext())); return result + 1; } uint32_t TJSONProtocol::writeJSONArrayEnd() { popContext(); trans_->write(&kJSONArrayEnd, 1); return 1; } uint32_t TJSONProtocol::writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid) { uint32_t result = writeJSONArrayStart(); result += writeJSONInteger(kThriftVersion1); result += writeJSONString(name); result += writeJSONInteger(messageType); result += writeJSONInteger(seqid); return result; } uint32_t TJSONProtocol::writeMessageEnd() { return writeJSONArrayEnd(); } uint32_t TJSONProtocol::writeStructBegin(const char* name) { (void)name; return writeJSONObjectStart(); } uint32_t TJSONProtocol::writeStructEnd() { return writeJSONObjectEnd(); } uint32_t TJSONProtocol::writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) { (void)name; uint32_t result = writeJSONInteger(fieldId); result += writeJSONObjectStart(); result += writeJSONString(getTypeNameForTypeID(fieldType)); return result; } uint32_t TJSONProtocol::writeFieldEnd() { return writeJSONObjectEnd(); } uint32_t TJSONProtocol::writeFieldStop() { return 0; } uint32_t TJSONProtocol::writeMapBegin(const TType keyType, const TType valType, const uint32_t size) { uint32_t result = writeJSONArrayStart(); result += writeJSONString(getTypeNameForTypeID(keyType)); result += writeJSONString(getTypeNameForTypeID(valType)); result += writeJSONInteger((int64_t)size); result += writeJSONObjectStart(); return result; } uint32_t TJSONProtocol::writeMapEnd() { uint32_t result = writeJSONObjectEnd(); result += writeJSONArrayEnd(); return result; } uint32_t TJSONProtocol::writeListBegin(const TType elemType, const uint32_t size) { uint32_t result = writeJSONArrayStart(); result += writeJSONString(getTypeNameForTypeID(elemType)); result += writeJSONInteger((int64_t)size); return result; } uint32_t TJSONProtocol::writeListEnd() { return writeJSONArrayEnd(); } uint32_t TJSONProtocol::writeSetBegin(const TType elemType, const uint32_t size) { uint32_t result = writeJSONArrayStart(); result += writeJSONString(getTypeNameForTypeID(elemType)); result += writeJSONInteger((int64_t)size); return result; } uint32_t TJSONProtocol::writeSetEnd() { return writeJSONArrayEnd(); } uint32_t TJSONProtocol::writeBool(const bool value) { return writeJSONInteger(value); } uint32_t TJSONProtocol::writeByte(const int8_t byte) { // writeByte() must be handled specially because to_string sees // int8_t as a text type instead of an integer type return writeJSONInteger((int16_t)byte); } uint32_t TJSONProtocol::writeI16(const int16_t i16) { return writeJSONInteger(i16); } uint32_t TJSONProtocol::writeI32(const int32_t i32) { return writeJSONInteger(i32); } uint32_t TJSONProtocol::writeI64(const int64_t i64) { return writeJSONInteger(i64); } uint32_t TJSONProtocol::writeDouble(const double dub) { return writeJSONDouble(dub); } uint32_t TJSONProtocol::writeString(const std::string& str) { return writeJSONString(str); } 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 */ // Reads 1 byte and verifies that it matches ch. uint32_t TJSONProtocol::readJSONSyntaxChar(uint8_t ch) { return readSyntaxChar(reader_, ch); } // Decodes the four hex parts of a JSON escaped string character and returns // the UTF-16 code unit via out. uint32_t TJSONProtocol::readJSONEscapeChar(uint16_t* out) { uint8_t b[4]; b[0] = reader_.read(); b[1] = reader_.read(); b[2] = reader_.read(); b[3] = reader_.read(); *out = (hexVal(b[0]) << 12) + (hexVal(b[1]) << 8) + (hexVal(b[2]) << 4) + hexVal(b[3]); return 4; } // Decodes a JSON string, including unescaping, and returns the string via str uint32_t TJSONProtocol::readJSONString(std::string& str, bool skipContext) { uint32_t result = (skipContext ? 0 : context_->read(reader_)); result += readJSONSyntaxChar(kJSONStringDelimiter); std::vector codeunits; uint8_t ch; str.clear(); while (true) { ch = reader_.read(); ++result; if (ch == kJSONStringDelimiter) { break; } if (ch == kJSONBackslash) { ch = reader_.read(); ++result; if (ch == kJSONEscapeChar) { uint16_t cp; result += readJSONEscapeChar(&cp); if (isHighSurrogate(cp)) { codeunits.push_back(cp); } else { if (isLowSurrogate(cp) && codeunits.empty()) { throw TProtocolException(TProtocolException::INVALID_DATA, "Missing UTF-16 high surrogate pair."); } codeunits.push_back(cp); codeunits.push_back(0); str += boost::locale::conv::utf_to_utf(codeunits.data()); codeunits.clear(); } continue; } else { size_t pos = kEscapeChars.find(ch); if (pos == kEscapeChars.npos) { throw TProtocolException(TProtocolException::INVALID_DATA, "Expected control char, got '" + std::string((const char*)&ch, 1) + "'."); } ch = kEscapeCharVals[pos]; } } if (!codeunits.empty()) { throw TProtocolException(TProtocolException::INVALID_DATA, "Missing UTF-16 low surrogate pair."); } str += ch; } if (!codeunits.empty()) { throw TProtocolException(TProtocolException::INVALID_DATA, "Missing UTF-16 low surrogate pair."); } return result; } // Reads a block of base64 characters, decoding it, and returns via str uint32_t TJSONProtocol::readJSONBase64(std::string& str) { std::string tmp; uint32_t result = readJSONString(tmp); auto* b = (uint8_t*)tmp.c_str(); if (tmp.length() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); auto len = static_cast(tmp.length()); str.clear(); // Ignore padding uint32_t padding_count = 0; while (len > 0 && b[len - 1] == '=' && padding_count < 2) { --len; ++padding_count; } while (len >= 4) { base64_decode(b, 4); str.append((const char*)b, 3); b += 4; len -= 4; } // Don't decode if we hit the end or got a single leftover byte (invalid // base64 but legal for skip of regular string type) if (len > 1) { base64_decode(b, len); str.append((const char*)b, len - 1); } return result; } // Reads a sequence of characters, stopping at the first one that is not // a valid JSON numeric character. uint32_t TJSONProtocol::readJSONNumericChars(std::string& str) { uint32_t result = 0; str.clear(); while (true) { uint8_t ch = reader_.peek(); if (!isJSONNumeric(ch)) { break; } reader_.read(); str += ch; ++result; } return result; } namespace { template T fromString(const std::string& s) { T t; std::istringstream str(s); str.imbue(std::locale::classic()); str >> t; if (str.bad() || !str.eof()) throw std::runtime_error(s); return t; } } // Reads a sequence of characters and assembles them into a number, // returning them via num template uint32_t TJSONProtocol::readJSONInteger(NumberType& num) { uint32_t result = context_->read(reader_); if (context_->escapeNum()) { result += readJSONSyntaxChar(kJSONStringDelimiter); } std::string str; result += readJSONNumericChars(str); try { num = fromString(str); } catch (const std::runtime_error&) { throw TProtocolException(TProtocolException::INVALID_DATA, "Expected numeric value; got \"" + str + "\""); } if (context_->escapeNum()) { result += readJSONSyntaxChar(kJSONStringDelimiter); } return result; } // Reads a JSON number or string and interprets it as a double. uint32_t TJSONProtocol::readJSONDouble(double& num) { uint32_t result = context_->read(reader_); std::string str; if (reader_.peek() == kJSONStringDelimiter) { result += readJSONString(str, true); // Check for NaN, Infinity and -Infinity if (str == kThriftNan) { num = HUGE_VAL / HUGE_VAL; // generates NaN } else if (str == kThriftInfinity) { num = HUGE_VAL; } else if (str == kThriftNegativeInfinity) { num = -HUGE_VAL; } else { if (!context_->escapeNum()) { // Throw exception -- we should not be in a string in this case throw TProtocolException(TProtocolException::INVALID_DATA, "Numeric data unexpectedly quoted"); } try { num = fromString(str); } catch (const std::runtime_error&) { throw TProtocolException(TProtocolException::INVALID_DATA, "Expected numeric value; got \"" + str + "\""); } } } else { if (context_->escapeNum()) { // This will throw - we should have had a quote if escapeNum == true readJSONSyntaxChar(kJSONStringDelimiter); } result += readJSONNumericChars(str); try { num = fromString(str); } catch (const std::runtime_error&) { throw TProtocolException(TProtocolException::INVALID_DATA, "Expected numeric value; got \"" + str + "\""); } } return result; } uint32_t TJSONProtocol::readJSONObjectStart() { uint32_t result = context_->read(reader_); result += readJSONSyntaxChar(kJSONObjectStart); pushContext(std::shared_ptr(new JSONPairContext())); return result; } uint32_t TJSONProtocol::readJSONObjectEnd() { uint32_t result = readJSONSyntaxChar(kJSONObjectEnd); popContext(); return result; } uint32_t TJSONProtocol::readJSONArrayStart() { uint32_t result = context_->read(reader_); result += readJSONSyntaxChar(kJSONArrayStart); pushContext(std::shared_ptr(new JSONListContext())); return result; } uint32_t TJSONProtocol::readJSONArrayEnd() { uint32_t result = readJSONSyntaxChar(kJSONArrayEnd); popContext(); return result; } uint32_t TJSONProtocol::readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) { uint32_t result = readJSONArrayStart(); int64_t tmpVal = 0; result += readJSONInteger(tmpVal); if (tmpVal != kThriftVersion1) { throw TProtocolException(TProtocolException::BAD_VERSION, "Message contained bad version."); } result += readJSONString(name); result += readJSONInteger(tmpVal); messageType = (TMessageType)tmpVal; result += readJSONInteger(tmpVal); if (tmpVal > (std::numeric_limits::max)() || tmpVal < (std::numeric_limits::min)()) throw TProtocolException(TProtocolException::INVALID_DATA, "sequence id is not int32_t"); seqid = static_cast(tmpVal); return result; } uint32_t TJSONProtocol::readMessageEnd() { return readJSONArrayEnd(); } uint32_t TJSONProtocol::readStructBegin(std::string& name) { (void)name; return readJSONObjectStart(); } uint32_t TJSONProtocol::readStructEnd() { return readJSONObjectEnd(); } uint32_t TJSONProtocol::readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) { (void)name; uint32_t result = 0; // Check if we hit the end of the list uint8_t ch = reader_.peek(); if (ch == kJSONObjectEnd) { fieldType = apache::thrift::protocol::T_STOP; } else { uint64_t tmpVal = 0; std::string tmpStr; result += readJSONInteger(tmpVal); if (tmpVal > static_cast((std::numeric_limits::max)())) throw TProtocolException(TProtocolException::SIZE_LIMIT); fieldId = static_cast(tmpVal); result += readJSONObjectStart(); result += readJSONString(tmpStr); fieldType = getTypeIDForTypeName(tmpStr); } return result; } uint32_t TJSONProtocol::readFieldEnd() { return readJSONObjectEnd(); } uint32_t TJSONProtocol::readMapBegin(TType& keyType, TType& valType, uint32_t& size) { uint64_t tmpVal = 0; std::string tmpStr; uint32_t result = readJSONArrayStart(); result += readJSONString(tmpStr); keyType = getTypeIDForTypeName(tmpStr); result += readJSONString(tmpStr); valType = getTypeIDForTypeName(tmpStr); result += readJSONInteger(tmpVal); if (tmpVal > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); size = static_cast(tmpVal); result += readJSONObjectStart(); TMap map(keyType, valType, size); checkReadBytesAvailable(map); return result; } uint32_t TJSONProtocol::readMapEnd() { uint32_t result = readJSONObjectEnd(); result += readJSONArrayEnd(); return result; } uint32_t TJSONProtocol::readListBegin(TType& elemType, uint32_t& size) { uint64_t tmpVal = 0; std::string tmpStr; uint32_t result = readJSONArrayStart(); result += readJSONString(tmpStr); elemType = getTypeIDForTypeName(tmpStr); result += readJSONInteger(tmpVal); if (tmpVal > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); size = static_cast(tmpVal); TList list(elemType, size); checkReadBytesAvailable(list); return result; } uint32_t TJSONProtocol::readListEnd() { return readJSONArrayEnd(); } uint32_t TJSONProtocol::readSetBegin(TType& elemType, uint32_t& size) { uint64_t tmpVal = 0; std::string tmpStr; uint32_t result = readJSONArrayStart(); result += readJSONString(tmpStr); elemType = getTypeIDForTypeName(tmpStr); result += readJSONInteger(tmpVal); if (tmpVal > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); size = static_cast(tmpVal); TSet set(elemType, size); checkReadBytesAvailable(set); return result; } uint32_t TJSONProtocol::readSetEnd() { return readJSONArrayEnd(); } uint32_t TJSONProtocol::readBool(bool& value) { return readJSONInteger(value); } // readByte() must be handled properly because boost::lexical cast sees int8_t // as a text type instead of an integer type uint32_t TJSONProtocol::readByte(int8_t& byte) { auto tmp = (int16_t)byte; uint32_t result = readJSONInteger(tmp); if (tmp > 127 || tmp < -128) { throw TProtocolException(TProtocolException::INVALID_DATA, "Expected byte value; got " + to_string(tmp)); } byte = (int8_t)tmp; return result; } uint32_t TJSONProtocol::readI16(int16_t& i16) { return readJSONInteger(i16); } uint32_t TJSONProtocol::readI32(int32_t& i32) { return readJSONInteger(i32); } uint32_t TJSONProtocol::readI64(int64_t& i64) { return readJSONInteger(i64); } uint32_t TJSONProtocol::readDouble(double& dub) { return readJSONDouble(dub); } uint32_t TJSONProtocol::readString(std::string& str) { return readJSONString(str); } 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) { switch (type) { case T_STOP: return 1; // T_STOP needs to count itself case T_VOID: return 1; // T_VOID needs to count itself case T_BOOL: return 1; // written as int case T_BYTE: return 1; case T_DOUBLE: return 1; case T_I16: return 1; case T_I32: return 1; case T_I64: return 1; case T_STRING: return 2; // empty string case T_STRUCT: return 2; // empty struct 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"); } } } } } // apache::thrift::protocol thrift-0.23.0/lib/cpp/src/thrift/protocol/TProtocolDecorator.h0000664000175000017500000001461415165535636024624 0ustar00buildbuild00000000000000/* * 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_TPROTOCOLDECORATOR_H_ #define THRIFT_TPROTOCOLDECORATOR_H_ 1 #include #include namespace apache { namespace thrift { namespace protocol { using std::shared_ptr; /** * TProtocolDecorator forwards all requests to an enclosed * TProtocol instance, providing a way to author concise * concrete decorator subclasses. * *

See p.175 of Design Patterns (by Gamma et al.)

* * @see apache::thrift::protocol::TMultiplexedProtocol */ class TProtocolDecorator : public TProtocol { public: ~TProtocolDecorator() override = default; // Desc: Initializes the protocol decorator object. TProtocolDecorator(shared_ptr proto) : TProtocol(proto->getTransport()), protocol(proto) {} uint32_t writeMessageBegin_virt(const std::string& name, const TMessageType messageType, const int32_t seqid) override { return protocol->writeMessageBegin(name, messageType, seqid); } uint32_t writeMessageEnd_virt() override { return protocol->writeMessageEnd(); } uint32_t writeStructBegin_virt(const char* name) override { return protocol->writeStructBegin(name); } uint32_t writeStructEnd_virt() override { return protocol->writeStructEnd(); } uint32_t writeFieldBegin_virt(const char* name, const TType fieldType, const int16_t fieldId) override { return protocol->writeFieldBegin(name, fieldType, fieldId); } uint32_t writeFieldEnd_virt() override { return protocol->writeFieldEnd(); } uint32_t writeFieldStop_virt() override { return protocol->writeFieldStop(); } uint32_t writeMapBegin_virt(const TType keyType, const TType valType, const uint32_t size) override { return protocol->writeMapBegin(keyType, valType, size); } uint32_t writeMapEnd_virt() override { return protocol->writeMapEnd(); } uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) override { return protocol->writeListBegin(elemType, size); } uint32_t writeListEnd_virt() override { return protocol->writeListEnd(); } uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) override { return protocol->writeSetBegin(elemType, size); } uint32_t writeSetEnd_virt() override { return protocol->writeSetEnd(); } uint32_t writeBool_virt(const bool value) override { return protocol->writeBool(value); } uint32_t writeByte_virt(const int8_t byte) override { return protocol->writeByte(byte); } uint32_t writeI16_virt(const int16_t i16) override { return protocol->writeI16(i16); } uint32_t writeI32_virt(const int32_t i32) override { return protocol->writeI32(i32); } uint32_t writeI64_virt(const int64_t i64) override { return protocol->writeI64(i64); } 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, int32_t& seqid) override { return protocol->readMessageBegin(name, messageType, seqid); } uint32_t readMessageEnd_virt() override { return protocol->readMessageEnd(); } uint32_t readStructBegin_virt(std::string& name) override { return protocol->readStructBegin(name); } uint32_t readStructEnd_virt() override { return protocol->readStructEnd(); } uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) override { return protocol->readFieldBegin(name, fieldType, fieldId); } uint32_t readFieldEnd_virt() override { return protocol->readFieldEnd(); } uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) override { return protocol->readMapBegin(keyType, valType, size); } uint32_t readMapEnd_virt() override { return protocol->readMapEnd(); } uint32_t readListBegin_virt(TType& elemType, uint32_t& size) override { return protocol->readListBegin(elemType, size); } uint32_t readListEnd_virt() override { return protocol->readListEnd(); } uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) override { return protocol->readSetBegin(elemType, size); } uint32_t readSetEnd_virt() override { return protocol->readSetEnd(); } uint32_t readBool_virt(bool& value) override { return protocol->readBool(value); } uint32_t readBool_virt(std::vector::reference value) override { return protocol->readBool(value); } uint32_t readByte_virt(int8_t& byte) override { return protocol->readByte(byte); } uint32_t readI16_virt(int16_t& i16) override { return protocol->readI16(i16); } uint32_t readI32_virt(int32_t& i32) override { return protocol->readI32(i32); } uint32_t readI64_virt(int64_t& i64) override { return protocol->readI64(i64); } uint32_t readDouble_virt(double& dub) override { return protocol->readDouble(dub); } 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; }; } } } #endif // THRIFT_TPROTOCOLDECORATOR_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TProtocolException.h0000664000175000017500000000630015165535636024631 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TPROTOCOLEXCEPTION_H_ #define _THRIFT_PROTOCOL_TPROTOCOLEXCEPTION_H_ 1 #include namespace apache { namespace thrift { namespace protocol { /** * Class to encapsulate all the possible types of protocol errors that may * occur in various protocol systems. This provides a sort of generic * wrapper around the vague UNIX E_ error codes that lets a common code * base of error handling to be used for various types of protocols, i.e. * pipes etc. * */ class TProtocolException : public apache::thrift::TException { public: /** * Error codes for the various types of exceptions. */ enum TProtocolExceptionType { UNKNOWN = 0, INVALID_DATA = 1, NEGATIVE_SIZE = 2, SIZE_LIMIT = 3, BAD_VERSION = 4, NOT_IMPLEMENTED = 5, DEPTH_LIMIT = 6 }; TProtocolException() : apache::thrift::TException(), type_(UNKNOWN) {} TProtocolException(TProtocolExceptionType type) : apache::thrift::TException(), type_(type) {} TProtocolException(const std::string& message) : apache::thrift::TException(message), type_(UNKNOWN) {} TProtocolException(TProtocolExceptionType type, const std::string& message) : apache::thrift::TException(message), type_(type) {} ~TProtocolException() noexcept override = default; /** * Returns an error code that provides information about the type of error * that has occurred. * * @return Error code */ TProtocolExceptionType getType() const { return type_; } const char* what() const noexcept override { if (message_.empty()) { switch (type_) { case UNKNOWN: return "TProtocolException: Unknown protocol exception"; case INVALID_DATA: return "TProtocolException: Invalid data"; case NEGATIVE_SIZE: return "TProtocolException: Negative size"; case SIZE_LIMIT: return "TProtocolException: Exceeded size limit"; case BAD_VERSION: return "TProtocolException: Invalid version"; case NOT_IMPLEMENTED: return "TProtocolException: Not implemented"; case DEPTH_LIMIT: return "TProtocolException: Exceeded depth limit"; default: return "TProtocolException: (Invalid exception type)"; } } else { return message_.c_str(); } } protected: /** * Error code */ TProtocolExceptionType type_; }; } } } // apache::thrift::protocol #endif // #ifndef _THRIFT_PROTOCOL_TPROTOCOLEXCEPTION_H_ thrift-0.23.0/lib/cpp/src/thrift/protocol/TJSONProtocol.h0000664000175000017500000002340415165535636023450 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TJSONPROTOCOL_H_ #define _THRIFT_PROTOCOL_TJSONPROTOCOL_H_ 1 #include #include namespace apache { namespace thrift { namespace protocol { // Forward declaration class TJSONContext; /** * JSON protocol for Thrift. * * Implements a protocol which uses JSON as the wire-format. * * Thrift types are represented as described below: * * 1. Every Thrift integer type is represented as a JSON number. * * 2. Thrift doubles are represented as JSON numbers. Some special values are * represented as strings: * a. "NaN" for not-a-number values * b. "Infinity" for positive infinity * c. "-Infinity" for negative infinity * * 3. Thrift string values are emitted as JSON strings, with appropriate * escaping. * * 4. Thrift binary values are encoded into Base64 and emitted as JSON strings. * The readBinary() method is written such that it will properly skip if * called on a Thrift string (although it will decode garbage data). * * NOTE: Base64 padding is optional for Thrift binary value encoding. So * the readBinary() method needs to decode both input strings with padding * and those without one. * * 5. Thrift structs are represented as JSON objects, with the field ID as the * key, and the field value represented as a JSON object with a single * key-value pair. The key is a short string identifier for that type, * followed by the value. The valid type identifiers are: "tf" for bool, * "i8" for byte, "i16" for 16-bit integer, "i32" for 32-bit integer, "i64" * for 64-bit integer, "dbl" for double-precision loating point, "str" for * string (including binary), "rec" for struct ("records"), "map" for map, * "lst" for list, "set" for set. * * 6. Thrift lists and sets are represented as JSON arrays, with the first * element of the JSON array being the string identifier for the Thrift * element type and the second element of the JSON array being the count of * the Thrift elements. The Thrift elements then follow. * * 7. Thrift maps are represented as JSON arrays, with the first two elements * of the JSON array being the string identifiers for the Thrift key type * and value type, followed by the count of the Thrift pairs, followed by a * JSON object containing the key-value pairs. Note that JSON keys can only * be strings, which means that the key type of the Thrift map should be * restricted to numeric or string types -- in the case of numerics, they * are serialized as strings. * * 8. Thrift messages are represented as JSON arrays, with the protocol * version #, the message name, the message type, and the sequence ID as * the first 4 elements. * * More discussion of the double handling is probably warranted. The aim of * the current implementation is to match as closely as possible the behavior * of Java's Double.toString(), which has no precision loss. Implementors in * other languages should strive to achieve that where possible. I have not * yet verified whether std::istringstream::operator>>, which is doing that * work for me in C++, loses any precision, but I am leaving this as a future * improvement. I may try to provide a C component for this, so that other * languages could bind to the same underlying implementation for maximum * consistency. * */ class TJSONProtocol : public TVirtualProtocol { public: TJSONProtocol(std::shared_ptr ptrans); ~TJSONProtocol() override; private: void pushContext(std::shared_ptr c); void popContext(); uint32_t writeJSONEscapeChar(uint8_t ch); uint32_t writeJSONChar(uint8_t ch); uint32_t writeJSONString(const std::string& str); uint32_t writeJSONBase64(const std::string& str); template uint32_t writeJSONInteger(NumberType num); uint32_t writeJSONDouble(double num); uint32_t writeJSONObjectStart(); uint32_t writeJSONObjectEnd(); uint32_t writeJSONArrayStart(); uint32_t writeJSONArrayEnd(); uint32_t readJSONSyntaxChar(uint8_t ch); uint32_t readJSONEscapeChar(uint16_t* out); uint32_t readJSONString(std::string& str, bool skipContext = false); uint32_t readJSONBase64(std::string& str); uint32_t readJSONNumericChars(std::string& str); template uint32_t readJSONInteger(NumberType& num); uint32_t readJSONDouble(double& num); uint32_t readJSONObjectStart(); uint32_t readJSONObjectEnd(); uint32_t readJSONArrayStart(); uint32_t readJSONArrayEnd(); public: /** * Writing functions. */ uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid); uint32_t writeMessageEnd(); uint32_t writeStructBegin(const char* name); uint32_t writeStructEnd(); uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId); uint32_t writeFieldEnd(); uint32_t writeFieldStop(); uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size); uint32_t writeMapEnd(); uint32_t writeListBegin(const TType elemType, const uint32_t size); uint32_t writeListEnd(); uint32_t writeSetBegin(const TType elemType, const uint32_t size); uint32_t writeSetEnd(); uint32_t writeBool(const bool value); uint32_t writeByte(const int8_t byte); uint32_t writeI16(const int16_t i16); uint32_t writeI32(const int32_t i32); uint32_t writeI64(const int64_t i64); uint32_t writeDouble(const double dub); uint32_t writeString(const std::string& str); uint32_t writeBinary(const std::string& str); uint32_t writeUUID(const TUuid& uuid); /** * Reading functions */ uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid); uint32_t readMessageEnd(); uint32_t readStructBegin(std::string& name); uint32_t readStructEnd(); uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId); uint32_t readFieldEnd(); uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size); uint32_t readMapEnd(); uint32_t readListBegin(TType& elemType, uint32_t& size); uint32_t readListEnd(); uint32_t readSetBegin(TType& elemType, uint32_t& size); uint32_t readSetEnd(); uint32_t readBool(bool& value); // Provide the default readBool() implementation for std::vector using TVirtualProtocol::readBool; uint32_t readByte(int8_t& byte); uint32_t readI16(int16_t& i16); uint32_t readI32(int32_t& i32); uint32_t readI64(int64_t& i64); uint32_t readDouble(double& dub); uint32_t readString(std::string& str); uint32_t readBinary(std::string& str); uint32_t readUUID(TUuid& uuid); int getMinSerializedSize(TType type) override; void checkReadBytesAvailable(TSet& set) override { trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); } void checkReadBytesAvailable(TList& list) override { trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); } void checkReadBytesAvailable(TMap& map) override { int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); trans_->checkReadBytesAvailable(map.size_ * elmSize); } class LookaheadReader { public: LookaheadReader(TTransport& trans) : trans_(&trans), hasData_(false), data_(0) {} uint8_t read() { if (hasData_) { hasData_ = false; } else { trans_->readAll(&data_, 1); } return data_; } uint8_t peek() { if (!hasData_) { trans_->readAll(&data_, 1); } hasData_ = true; return data_; } private: TTransport* trans_; bool hasData_; uint8_t data_; }; private: TTransport* trans_; std::stack > contexts_; std::shared_ptr context_; LookaheadReader reader_; }; /** * Constructs input and output protocol objects given transports. */ class TJSONProtocolFactory : public TProtocolFactory { public: TJSONProtocolFactory() = default; ~TJSONProtocolFactory() override = default; std::shared_ptr getProtocol(std::shared_ptr trans) override { return std::shared_ptr(new TJSONProtocol(trans)); } }; } } } // apache::thrift::protocol // TODO(dreiss): Move part of ThriftJSONString into a .cpp file and remove this. #include namespace apache { namespace thrift { template std::string ThriftJSONString(const ThriftStruct& ts) { using namespace apache::thrift::transport; using namespace apache::thrift::protocol; auto* buffer = new TMemoryBuffer; std::shared_ptr trans(buffer); TJSONProtocol protocol(trans); ts.write(&protocol); uint8_t* buf; uint32_t size; buffer->getBuffer(&buf, &size); return std::string((char*)buf, (unsigned int)size); } } } // apache::thrift #endif // #define _THRIFT_PROTOCOL_TJSONPROTOCOL_H_ 1 thrift-0.23.0/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp0000664000175000017500000002415515165535636024264 0ustar00buildbuild00000000000000/* * 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 #include using std::string; static string byte_to_hex(const uint8_t byte) { char buf[3]; int ret = std::sprintf(buf, "%02x", (int)byte); THRIFT_UNUSED_VARIABLE(ret); assert(ret == 2); assert(buf[2] == '\0'); return buf; } namespace apache { namespace thrift { namespace protocol { string TDebugProtocol::fieldTypeName(TType type) { switch (type) { case T_STOP: return "stop"; case T_VOID: return "void"; case T_BOOL: return "bool"; case T_BYTE: return "byte"; case T_I16: return "i16"; case T_I32: return "i32"; case T_U64: return "u64"; case T_I64: return "i64"; case T_DOUBLE: return "double"; case T_STRING: return "string"; case T_STRUCT: return "struct"; case T_MAP: return "map"; case T_SET: return "set"; case T_LIST: return "list"; case T_UUID: return "uuid"; default: return "unknown"; } } void TDebugProtocol::indentUp() { indent_str_ += string(indent_inc, ' '); } void TDebugProtocol::indentDown() { if (indent_str_.length() < (string::size_type)indent_inc) { throw TProtocolException(TProtocolException::INVALID_DATA); } indent_str_.erase(indent_str_.length() - indent_inc); } uint32_t TDebugProtocol::writePlain(const string& str) { if (str.length() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); trans_->write((uint8_t*)str.data(), static_cast(str.length())); return static_cast(str.length()); } uint32_t TDebugProtocol::writeIndented(const string& str) { if (str.length() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); if (indent_str_.length() > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); uint64_t total_len = indent_str_.length() + str.length(); if (total_len > (std::numeric_limits::max)()) throw TProtocolException(TProtocolException::SIZE_LIMIT); trans_->write((uint8_t*)indent_str_.data(), static_cast(indent_str_.length())); trans_->write((uint8_t*)str.data(), static_cast(str.length())); return static_cast(indent_str_.length() + str.length()); } uint32_t TDebugProtocol::startItem() { uint32_t size; switch (write_state_.back()) { case UNINIT: // XXX figure out what to do here. // throw TProtocolException(TProtocolException::INVALID_DATA); // return writeIndented(str); return 0; case STRUCT: return 0; case SET: return writeIndented(""); case MAP_KEY: return writeIndented(""); case MAP_VALUE: return writePlain(" -> "); case LIST: size = writeIndented("[" + to_string(list_idx_.back()) + "] = "); list_idx_.back()++; return size; default: throw std::logic_error("Invalid enum value."); } } uint32_t TDebugProtocol::endItem() { // uint32_t size; switch (write_state_.back()) { case UNINIT: // XXX figure out what to do here. // throw TProtocolException(TProtocolException::INVALID_DATA); // return writeIndented(str); return 0; case STRUCT: return writePlain(",\n"); case SET: return writePlain(",\n"); case MAP_KEY: write_state_.back() = MAP_VALUE; return 0; case MAP_VALUE: write_state_.back() = MAP_KEY; return writePlain(",\n"); case LIST: return writePlain(",\n"); default: throw std::logic_error("Invalid enum value."); } } uint32_t TDebugProtocol::writeItem(const std::string& str) { uint32_t size = 0; size += startItem(); size += writePlain(str); size += endItem(); return size; } uint32_t TDebugProtocol::writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid) { (void)seqid; string mtype; switch (messageType) { case T_CALL: mtype = "call"; break; case T_REPLY: mtype = "reply"; break; case T_EXCEPTION: mtype = "exn"; break; case T_ONEWAY: mtype = "oneway"; break; } uint32_t size = writeIndented("(" + mtype + ") " + name + "("); indentUp(); return size; } uint32_t TDebugProtocol::writeMessageEnd() { indentDown(); return writeIndented(")\n"); } uint32_t TDebugProtocol::writeStructBegin(const char* name) { uint32_t size = 0; size += startItem(); size += writePlain(string(name) + " {\n"); indentUp(); write_state_.push_back(STRUCT); return size; } uint32_t TDebugProtocol::writeStructEnd() { indentDown(); write_state_.pop_back(); uint32_t size = 0; size += writeIndented("}"); size += endItem(); return size; } uint32_t TDebugProtocol::writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) { // sprintf(id_str, "%02d", fieldId); string id_str = to_string(fieldId); if (id_str.length() == 1) id_str = '0' + id_str; return writeIndented(id_str + ": " + name + " (" + fieldTypeName(fieldType) + ") = "); } uint32_t TDebugProtocol::writeFieldEnd() { assert(write_state_.back() == STRUCT); return 0; } uint32_t TDebugProtocol::writeFieldStop() { return 0; // writeIndented("***STOP***\n"); } uint32_t TDebugProtocol::writeMapBegin(const TType keyType, const TType valType, const uint32_t size) { // TODO(dreiss): Optimize short maps? uint32_t bsize = 0; bsize += startItem(); bsize += writePlain( "map<" + fieldTypeName(keyType) + "," + fieldTypeName(valType) + ">" "[" + to_string(size) + "] {\n"); indentUp(); write_state_.push_back(MAP_KEY); return bsize; } uint32_t TDebugProtocol::writeMapEnd() { indentDown(); write_state_.pop_back(); uint32_t size = 0; size += writeIndented("}"); size += endItem(); return size; } uint32_t TDebugProtocol::writeListBegin(const TType elemType, const uint32_t size) { // TODO(dreiss): Optimize short arrays. uint32_t bsize = 0; bsize += startItem(); bsize += writePlain( "list<" + fieldTypeName(elemType) + ">" "[" + to_string(size) + "] {\n"); indentUp(); write_state_.push_back(LIST); list_idx_.push_back(0); return bsize; } uint32_t TDebugProtocol::writeListEnd() { indentDown(); write_state_.pop_back(); list_idx_.pop_back(); uint32_t size = 0; size += writeIndented("}"); size += endItem(); return size; } uint32_t TDebugProtocol::writeSetBegin(const TType elemType, const uint32_t size) { // TODO(dreiss): Optimize short sets. uint32_t bsize = 0; bsize += startItem(); bsize += writePlain( "set<" + fieldTypeName(elemType) + ">" "[" + to_string(size) + "] {\n"); indentUp(); write_state_.push_back(SET); return bsize; } uint32_t TDebugProtocol::writeSetEnd() { indentDown(); write_state_.pop_back(); uint32_t size = 0; size += writeIndented("}"); size += endItem(); return size; } uint32_t TDebugProtocol::writeBool(const bool value) { return writeItem(value ? "true" : "false"); } uint32_t TDebugProtocol::writeByte(const int8_t byte) { return writeItem("0x" + byte_to_hex(byte)); } uint32_t TDebugProtocol::writeI16(const int16_t i16) { return writeItem(to_string(i16)); } uint32_t TDebugProtocol::writeI32(const int32_t i32) { return writeItem(to_string(i32)); } uint32_t TDebugProtocol::writeI64(const int64_t i64) { return writeItem(to_string(i64)); } uint32_t TDebugProtocol::writeDouble(const double dub) { return writeItem(to_string(dub)); } uint32_t TDebugProtocol::writeString(const string& str) { // XXX Raw/UTF-8? string to_show = str; if (to_show.length() > (string::size_type)string_limit_) { to_show = str.substr(0, string_prefix_size_); to_show += "[...](" + to_string(str.length()) + ")"; } string output = "\""; for (string::const_iterator it = to_show.begin(); it != to_show.end(); ++it) { if (*it == '\\') { output += "\\\\"; } else if (*it == '"') { output += "\\\""; // passing characters <0 to std::isprint causes asserts. isprint takes an // int, so we need to be careful of sign extension } else if (std::isprint((unsigned char)*it)) { output += *it; } else { switch (*it) { case '\a': output += "\\a"; break; case '\b': output += "\\b"; break; case '\f': output += "\\f"; break; case '\n': output += "\\n"; break; case '\r': output += "\\r"; break; case '\t': output += "\\t"; break; case '\v': output += "\\v"; break; default: output += "\\x"; output += byte_to_hex(*it); } } } output += '\"'; return writeItem(output); } 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 thrift-0.23.0/lib/cpp/src/thrift/protocol/TCompactProtocol.h0000664000175000017500000002061315165535636024264 0ustar00buildbuild00000000000000/* * 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_PROTOCOL_TCOMPACTPROTOCOL_H_ #define _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_H_ 1 #include #include #include namespace apache { namespace thrift { namespace protocol { /** * C++ Implementation of the Compact Protocol as described in THRIFT-110 */ template class TCompactProtocolT : public TVirtualProtocol > { public: 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 = static_cast(0xE0u); // 1110 0000 static const int8_t TYPE_BITS = 0x07; // 0000 0111 static const int32_t TYPE_SHIFT_AMOUNT = 5; Transport_* trans_; /** * (Writing) If we encounter a boolean field begin, save the TField here * so it can have the value incorporated. */ struct { const char* name; TType fieldType; int16_t fieldId; } booleanField_; /** * (Reading) If we read a field header, and it's a boolean field, save * the boolean value here so that readBool can use it. */ struct { bool hasBoolValue; bool boolValue; } boolValue_; /** * Used to keep track of the last field for the current and previous structs, * so we can do the delta stuff. */ std::stack lastField_; int16_t lastFieldId_; public: TCompactProtocolT(std::shared_ptr trans) : TVirtualProtocol >(trans), trans_(trans.get()), lastFieldId_(0), string_limit_(0), string_buf_(nullptr), string_buf_size_(0), container_limit_(0) { booleanField_.name = nullptr; boolValue_.hasBoolValue = false; } TCompactProtocolT(std::shared_ptr trans, int32_t string_limit, int32_t container_limit) : TVirtualProtocol >(trans), trans_(trans.get()), lastFieldId_(0), string_limit_(string_limit), string_buf_(nullptr), string_buf_size_(0), container_limit_(container_limit) { booleanField_.name = nullptr; boolValue_.hasBoolValue = false; } ~TCompactProtocolT() override { free(string_buf_); } /** * Writing functions */ virtual uint32_t writeMessageBegin(const std::string& name, const TMessageType messageType, const int32_t seqid); uint32_t writeStructBegin(const char* name); uint32_t writeStructEnd(); uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId); uint32_t writeFieldStop(); uint32_t writeListBegin(const TType elemType, const uint32_t size); uint32_t writeSetBegin(const TType elemType, const uint32_t size); virtual uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size); uint32_t writeBool(const bool value); uint32_t writeByte(const int8_t byte); uint32_t writeI16(const int16_t i16); uint32_t writeI32(const int32_t i32); uint32_t writeI64(const int64_t i64); uint32_t writeDouble(const double dub); uint32_t writeString(const std::string& str); uint32_t writeBinary(const std::string& str); uint32_t writeUUID(const TUuid& str); int getMinSerializedSize(TType type) override; void checkReadBytesAvailable(TSet& set) override { trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); } void checkReadBytesAvailable(TList& list) override { trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); } void checkReadBytesAvailable(TMap& map) override { int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); trans_->checkReadBytesAvailable(map.size_ * elmSize); } /** * These methods are called by structs, but don't actually have any wired * output or purpose */ virtual uint32_t writeMessageEnd() { return 0; } uint32_t writeMapEnd() { return 0; } uint32_t writeListEnd() { return 0; } uint32_t writeSetEnd() { return 0; } uint32_t writeFieldEnd() { return 0; } protected: int32_t writeFieldBeginInternal(const char* name, const TType fieldType, const int16_t fieldId, int8_t typeOverride); uint32_t writeCollectionBegin(const TType elemType, int32_t size); uint32_t writeVarint32(uint32_t n); uint32_t writeVarint64(uint64_t n); uint64_t i64ToZigzag(const int64_t l); uint32_t i32ToZigzag(const int32_t n); inline int8_t getCompactType(const TType ttype); public: uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid); uint32_t readStructBegin(std::string& name); uint32_t readStructEnd(); uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId); uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size); uint32_t readListBegin(TType& elemType, uint32_t& size); uint32_t readSetBegin(TType& elemType, uint32_t& size); uint32_t readBool(bool& value); // Provide the default readBool() implementation for std::vector using TVirtualProtocol >::readBool; uint32_t readByte(int8_t& byte); uint32_t readI16(int16_t& i16); uint32_t readI32(int32_t& i32); uint32_t readI64(int64_t& i64); uint32_t readDouble(double& dub); uint32_t readString(std::string& str); 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. */ uint32_t readMessageEnd() { return 0; } uint32_t readFieldEnd() { return 0; } uint32_t readMapEnd() { return 0; } uint32_t readListEnd() { return 0; } uint32_t readSetEnd() { return 0; } protected: uint32_t readVarint32(int32_t& i32); uint32_t readVarint64(int64_t& i64); int32_t zigzagToI32(uint32_t n); int64_t zigzagToI64(uint64_t n); TType getTType(int8_t type); // Buffer for reading strings, save for the lifetime of the protocol to // avoid memory churn allocating memory on every string read int32_t string_limit_; uint8_t* string_buf_; int32_t string_buf_size_; int32_t container_limit_; }; typedef TCompactProtocolT TCompactProtocol; /** * Constructs compact protocol handlers */ template class TCompactProtocolFactoryT : public TProtocolFactory { public: TCompactProtocolFactoryT() : string_limit_(0), container_limit_(0) {} TCompactProtocolFactoryT(int32_t string_limit, int32_t container_limit) : string_limit_(string_limit), container_limit_(container_limit) {} ~TCompactProtocolFactoryT() override = default; void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; } void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; } std::shared_ptr getProtocol(std::shared_ptr trans) override { std::shared_ptr specific_trans = std::dynamic_pointer_cast(trans); TProtocol* prot; if (specific_trans) { prot = new TCompactProtocolT(specific_trans, string_limit_, container_limit_); } else { prot = new TCompactProtocol(trans, string_limit_, container_limit_); } return std::shared_ptr(prot); } private: int32_t string_limit_; int32_t container_limit_; }; typedef TCompactProtocolFactoryT TCompactProtocolFactory; } } } // apache::thrift::protocol #include #endif thrift-0.23.0/lib/cpp/src/thrift/protocol/TMap.h0000664000175000017500000000246715165535636021700 0ustar00buildbuild00000000000000/* * 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_TMAP_H_ #define _THRIFT_TMAP_H_ #include namespace apache { namespace thrift { namespace protocol { /** * Helper class that encapsulates map metadata. * */ class TMap { public: TMap() : keyType_(T_STOP), valueType_(T_STOP), size_(0) { } TMap(TType k, TType v, int s) : keyType_(k), valueType_(v), size_(s) { } TType keyType_; TType valueType_; int size_; }; } } } // apache::thrift::protocol #endif // #ifndef _THRIFT_TMAP_H_ thrift-0.23.0/lib/cpp/src/thrift/TConfiguration.h0000664000175000017500000000417415165535636022126 0ustar00buildbuild00000000000000/* * 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_TCONFIGURATION_H #define THRIFT_TCONFIGURATION_H namespace apache { namespace thrift { class TConfiguration { public: TConfiguration(int maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE, int maxFrameSize = DEFAULT_MAX_FRAME_SIZE, int recursionLimit = DEFAULT_RECURSION_DEPTH) : maxMessageSize_(maxMessageSize), maxFrameSize_(maxFrameSize), recursionLimit_(recursionLimit) {} const static int DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024; const static int DEFAULT_MAX_FRAME_SIZE = 16384000; // this value is used consistently across all Thrift libraries const static int DEFAULT_RECURSION_DEPTH = 64; inline int getMaxMessageSize() { return maxMessageSize_; } inline void setMaxMessageSize(int maxMessageSize) { maxMessageSize_ = maxMessageSize; } inline int getMaxFrameSize() { return maxFrameSize_; } inline void setMaxFrameSize(int maxFrameSize) { maxFrameSize_ = maxFrameSize; } inline int getRecursionLimit() { return recursionLimit_; } inline void setRecursionLimit(int recursionLimit) { recursionLimit_ = recursionLimit; } private: int maxMessageSize_ = DEFAULT_MAX_MESSAGE_SIZE; int maxFrameSize_ = DEFAULT_MAX_FRAME_SIZE; int recursionLimit_ = DEFAULT_RECURSION_DEPTH; // TODO(someone_smart): add connection and i/o timeouts }; } } // apache::thrift #endif /* THRIFT_TCONFIGURATION_H */ thrift-0.23.0/lib/cpp/src/thrift/VirtualProfiling.cpp0000664000175000017500000003065015165535636023024 0ustar00buildbuild00000000000000/* * 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 // Do nothing if virtual call profiling is not enabled #if T_GLOBAL_DEBUG_VIRTUAL > 1 // TODO: This code only works with g++ (since we rely on the fact // that all std::type_info instances referring to a particular type // always return the exact same pointer value from name().) #ifndef __GNUG__ #error "Thrift virtual function profiling currently only works with gcc" #endif // !__GNUG__ // TODO: We also require glibc for the backtrace() and backtrace_symbols() // functions. #ifndef __GLIBC__ #error "Thrift virtual function profiling currently requires glibc" #endif // !__GLIBC__ #include #include #include #include namespace apache { namespace thrift { using ::apache::thrift::concurrency::Mutex; using ::apache::thrift::concurrency::Guard; static const unsigned int MAX_STACK_DEPTH = 15; /** * A stack trace */ class Backtrace { public: Backtrace(int skip = 0); Backtrace(Backtrace const& bt); void operator=(Backtrace const& bt) { numCallers_ = bt.numCallers_; if (numCallers_ >= 0) { memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*)); } } bool operator==(Backtrace const& bt) const { return (cmp(bt) == 0); } size_t hash() const { intptr_t ret = 0; for (int n = 0; n < numCallers_; ++n) { ret ^= reinterpret_cast(callers_[n]); } return static_cast(ret); } int cmp(Backtrace const& bt) const { int depth_diff = (numCallers_ - bt.numCallers_); if (depth_diff != 0) { return depth_diff; } for (int n = 0; n < numCallers_; ++n) { int diff = reinterpret_cast(callers_[n]) - reinterpret_cast(bt.callers_[n]); if (diff != 0) { return diff; } } return 0; } void print(FILE* f, int indent = 0, int start = 0) const { char** strings = backtrace_symbols(callers_, numCallers_); if (strings) { start += skip_; if (start < 0) { start = 0; } for (int n = start; n < numCallers_; ++n) { fprintf(f, "%*s#%-2d %s\n", indent, "", n, strings[n]); } free(strings); } else { fprintf(f, "%*s\n", indent, ""); } } int getDepth() const { return numCallers_ - skip_; } void* getFrame(int index) const { int adjusted_index = index + skip_; if (adjusted_index < 0 || adjusted_index >= numCallers_) { return nullptr; } return callers_[adjusted_index]; } private: void* callers_[MAX_STACK_DEPTH]; int numCallers_; int skip_; }; // Define the constructors non-inline, so they consistently add a single // frame to the stack trace, regardless of whether optimization is enabled Backtrace::Backtrace(int skip) : skip_(skip + 1) // ignore the constructor itself { numCallers_ = backtrace(callers_, MAX_STACK_DEPTH); if (skip_ > numCallers_) { skip_ = numCallers_; } } Backtrace::Backtrace(Backtrace const& bt) : numCallers_(bt.numCallers_), skip_(bt.skip_) { if (numCallers_ >= 0) { memcpy(callers_, bt.callers_, numCallers_ * sizeof(void*)); } } /** * A backtrace, plus one or two type names */ class Key { public: class Hash { public: size_t operator()(Key const& k) const { return k.hash(); } }; Key(const Backtrace* bt, const std::type_info& type_info) : backtrace_(bt), typeName1_(type_info.name()), typeName2_(nullptr) {} Key(const Backtrace* bt, const std::type_info& type_info1, const std::type_info& type_info2) : backtrace_(bt), typeName1_(type_info1.name()), typeName2_(type_info2.name()) {} Key(const Key& k) : backtrace_(k.backtrace_), typeName1_(k.typeName1_), typeName2_(k.typeName2_) {} void operator=(const Key& k) { backtrace_ = k.backtrace_; typeName1_ = k.typeName1_; typeName2_ = k.typeName2_; } const Backtrace* getBacktrace() const { return backtrace_; } const char* getTypeName() const { return typeName1_; } const char* getTypeName2() const { return typeName2_; } void makePersistent() { // Copy the Backtrace object backtrace_ = new Backtrace(*backtrace_); // NOTE: We don't copy the type name. // The GNU libstdc++ implementation of type_info::name() returns a value // that will be valid for the lifetime of the program. (Although the C++ // standard doesn't guarantee this will be true on all implementations.) } /** * Clean up memory allocated by makePersistent() * * Should only be invoked if makePersistent() has previously been called. * The Key should no longer be used after cleanup() is called. */ void cleanup() { delete backtrace_; backtrace_ = nullptr; } int cmp(const Key& k) const { int ret = backtrace_->cmp(*k.backtrace_); if (ret != 0) { return ret; } // NOTE: We compare just the name pointers. // With GNU libstdc++, every type_info object for the same type points to // exactly the same name string. (Although this isn't guaranteed by the // C++ standard.) ret = k.typeName1_ - typeName1_; if (ret != 0) { return ret; } return k.typeName2_ - typeName2_; } bool operator==(const Key& k) const { return cmp(k) == 0; } size_t hash() const { // NOTE: As above, we just use the name pointer value. // Works with GNU libstdc++, but not guaranteed to be correct on all // implementations. return backtrace_->hash() ^ reinterpret_cast(typeName1_) ^ reinterpret_cast(typeName2_); } private: const Backtrace* backtrace_; const char* typeName1_; const char* typeName2_; }; /** * A functor that determines which of two BacktraceMap entries * has a higher count. */ class CountGreater { public: bool operator()(std::pair bt1, std::pair bt2) const { return bt1.second > bt2.second; } }; typedef __gnu_cxx::hash_map BacktraceMap; /** * A map describing how many times T_VIRTUAL_CALL() has been invoked. */ BacktraceMap virtual_calls; Mutex virtual_calls_mutex; /** * A map describing how many times T_GENERIC_PROTOCOL() has been invoked. */ BacktraceMap generic_calls; Mutex generic_calls_mutex; void _record_backtrace(BacktraceMap* map, const Mutex& mutex, Key* k) { Guard guard(mutex); BacktraceMap::iterator it = map->find(*k); if (it == map->end()) { k->makePersistent(); map->insert(std::make_pair(*k, 1)); } else { // increment the count // NOTE: we could assert if it->second is 0 afterwards, since that would // mean we've wrapped. ++(it->second); } } /** * Record an unnecessary virtual function call. * * This method is invoked by the T_VIRTUAL_CALL() macro. */ void profile_virtual_call(const std::type_info& type) { int const skip = 1; // ignore this frame Backtrace bt(skip); Key k(&bt, type); _record_backtrace(&virtual_calls, virtual_calls_mutex, &k); } /** * Record a call to a template processor with a protocol that is not the one * specified in the template parameter. * * This method is invoked by the T_GENERIC_PROTOCOL() macro. */ void profile_generic_protocol(const std::type_info& template_type, const std::type_info& prot_type) { int const skip = 1; // ignore this frame Backtrace bt(skip); Key k(&bt, template_type, prot_type); _record_backtrace(&generic_calls, generic_calls_mutex, &k); } /** * Print the recorded profiling information to the specified file. */ void profile_print_info(FILE* f) { typedef std::vector > BacktraceVector; CountGreater is_greater; // Grab both locks for the duration of the print operation, // to ensure the output is a consistent snapshot of a single point in time Guard generic_calls_guard(generic_calls_mutex); Guard virtual_calls_guard(virtual_calls_mutex); // print the info from generic_calls, sorted by frequency // // We print the generic_calls info ahead of virtual_calls, since it is more // useful in some cases. All T_GENERIC_PROTOCOL calls can be eliminated // from most programs. Not all T_VIRTUAL_CALLs will be eliminated by // converting to templates. BacktraceVector gp_sorted(generic_calls.begin(), generic_calls.end()); std::sort(gp_sorted.begin(), gp_sorted.end(), is_greater); for (BacktraceVector::const_iterator it = gp_sorted.begin(); it != gp_sorted.end(); ++it) { Key const& key = it->first; size_t const count = it->second; fprintf(f, "T_GENERIC_PROTOCOL: %zu calls to %s with a %s:\n", count, key.getTypeName(), key.getTypeName2()); key.getBacktrace()->print(f, 2); fprintf(f, "\n"); } // print the info from virtual_calls, sorted by frequency BacktraceVector vc_sorted(virtual_calls.begin(), virtual_calls.end()); std::sort(vc_sorted.begin(), vc_sorted.end(), is_greater); for (BacktraceVector::const_iterator it = vc_sorted.begin(); it != vc_sorted.end(); ++it) { Key const& key = it->first; size_t const count = it->second; fprintf(f, "T_VIRTUAL_CALL: %zu calls on %s:\n", count, key.getTypeName()); key.getBacktrace()->print(f, 2); fprintf(f, "\n"); } } /** * Print the recorded profiling information to stdout. */ void profile_print_info() { profile_print_info(stdout); } /** * Write a BacktraceMap as Google CPU profiler binary data. */ static void profile_write_pprof_file(FILE* f, BacktraceMap const& map) { // Write the header uintptr_t header[5] = {0, 3, 0, 0, 0}; fwrite(&header, sizeof(header), 1, f); // Write the profile records for (BacktraceMap::const_iterator it = map.begin(); it != map.end(); ++it) { uintptr_t count = it->second; fwrite(&count, sizeof(count), 1, f); Backtrace const* bt = it->first.getBacktrace(); uintptr_t num_pcs = bt->getDepth(); fwrite(&num_pcs, sizeof(num_pcs), 1, f); for (uintptr_t n = 0; n < num_pcs; ++n) { void* pc = bt->getFrame(n); fwrite(&pc, sizeof(pc), 1, f); } } // Write the trailer uintptr_t trailer[3] = {0, 1, 0}; fwrite(&trailer, sizeof(trailer), 1, f); // Write /proc/self/maps // TODO(simpkins): This only works on linux FILE* proc_maps = fopen("/proc/self/maps", "r"); if (proc_maps) { uint8_t buf[4096]; while (true) { size_t bytes_read = fread(buf, 1, sizeof(buf), proc_maps); if (bytes_read == 0) { break; } fwrite(buf, 1, bytes_read, f); } fclose(proc_maps); } } /** * Write the recorded profiling information as pprof files. * * This writes the information using the Google CPU profiler binary data * format, so it can be analyzed with pprof. Note that information about the * protocol/transport data types cannot be stored in this file format. * * See http://code.google.com/p/google-perftools/ for more details. * * @param gen_calls_f The information about calls to * profile_generic_protocol() will be written to this * file. * @param virtual_calls_f The information about calls to * profile_virtual_call() will be written to this file. */ void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f) { typedef std::vector > BacktraceVector; CountGreater is_greater; // Grab both locks for the duration of the print operation, // to ensure the output is a consistent snapshot of a single point in time Guard generic_calls_guard(generic_calls_mutex); Guard virtual_calls_guard(virtual_calls_mutex); // write the info from generic_calls profile_write_pprof_file(gen_calls_f, generic_calls); // write the info from virtual_calls profile_write_pprof_file(virtual_calls_f, virtual_calls); } } } // apache::thrift #endif // T_GLOBAL_PROFILE_VIRTUAL > 0 thrift-0.23.0/lib/cpp/src/thrift/TProcessor.h0000664000175000017500000001520215165535636021270 0ustar00buildbuild00000000000000/* * 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_TPROCESSOR_H_ #define _THRIFT_TPROCESSOR_H_ 1 #include #include namespace apache { namespace thrift { /** * Virtual interface class that can handle events from the processor. To * use this you should subclass it and implement the methods that you care * about. Your subclass can also store local data that you may care about, * such as additional "arguments" to these methods (stored in the object * instance's state). */ class TProcessorEventHandler { public: virtual ~TProcessorEventHandler() = default; /** * Called before calling other callback methods. * Expected to return some sort of context object. * The return value is passed to all other callbacks * for that function invocation. */ virtual void* getContext(const char* fn_name, void* serverContext) { (void)fn_name; (void)serverContext; return nullptr; } /** * Expected to free resources associated with a context. */ virtual void freeContext(void* ctx, const char* fn_name) { (void)ctx; (void)fn_name; } /** * Called before reading arguments. */ virtual void preRead(void* ctx, const char* fn_name) { (void)ctx; (void)fn_name; } /** * Called between reading arguments and calling the handler. */ virtual void postRead(void* ctx, const char* fn_name, uint32_t bytes) { (void)ctx; (void)fn_name; (void)bytes; } /** * Called between calling the handler and writing the response. */ virtual void preWrite(void* ctx, const char* fn_name) { (void)ctx; (void)fn_name; } /** * Called after writing the response. */ virtual void postWrite(void* ctx, const char* fn_name, uint32_t bytes) { (void)ctx; (void)fn_name; (void)bytes; } /** * Called when an async function call completes successfully. */ virtual void asyncComplete(void* ctx, const char* fn_name) { (void)ctx; (void)fn_name; } /** * Called if the handler throws an undeclared exception. */ virtual void handlerError(void* ctx, const char* fn_name) { (void)ctx; (void)fn_name; } protected: TProcessorEventHandler() = default; }; /** * A helper class used by the generated code to free each context. */ class TProcessorContextFreer { public: TProcessorContextFreer(TProcessorEventHandler* handler, void* context, const char* method) : handler_(handler), context_(context), method_(method) {} ~TProcessorContextFreer() { if (handler_ != nullptr) handler_->freeContext(context_, method_); } void unregister() { handler_ = nullptr; } private: apache::thrift::TProcessorEventHandler* handler_; void* context_; const char* method_; }; /** * A processor is a generic object that acts upon two streams of data, one * an input and the other an output. The definition of this object is loose, * though the typical case is for some sort of server that either generates * responses to an input stream or forwards data from one pipe onto another. * */ class TProcessor { public: virtual ~TProcessor() = default; virtual bool process(std::shared_ptr in, std::shared_ptr out, void* connectionContext) = 0; bool process(std::shared_ptr io, void* connectionContext) { return process(io, io, connectionContext); } std::shared_ptr getEventHandler() const { return eventHandler_; } void setEventHandler(std::shared_ptr eventHandler) { eventHandler_ = eventHandler; } protected: TProcessor() = default; std::shared_ptr eventHandler_; }; /** * This is a helper class to allow std::shared_ptr to be used with handler * pointers returned by the generated handler factories. * * The handler factory classes generated by the thrift compiler return raw * pointers, and factory->releaseHandler() must be called when the handler is * no longer needed. * * A ReleaseHandler object can be instantiated and passed as the second * parameter to a shared_ptr, so that factory->releaseHandler() will be called * when the object is no longer needed, instead of deleting the pointer. */ template class ReleaseHandler { public: ReleaseHandler(const std::shared_ptr& handlerFactory) : handlerFactory_(handlerFactory) {} void operator()(typename HandlerFactory_::Handler* handler) { if (handler) { handlerFactory_->releaseHandler(handler); } } private: std::shared_ptr handlerFactory_; }; struct TConnectionInfo { // The input and output protocols std::shared_ptr input; std::shared_ptr output; // The underlying transport used for the connection // This is the transport that was returned by TServerTransport::accept(), // and it may be different than the transport pointed to by the input and // output protocols. std::shared_ptr transport; }; class TProcessorFactory { public: virtual ~TProcessorFactory() = default; /** * Get the TProcessor to use for a particular connection. * * This method is always invoked in the same thread that the connection was * accepted on. This generally means that this call does not need to be * thread safe, as it will always be invoked from a single thread. */ virtual std::shared_ptr getProcessor(const TConnectionInfo& connInfo) = 0; }; class TSingletonProcessorFactory : public TProcessorFactory { public: TSingletonProcessorFactory(std::shared_ptr processor) : processor_(processor) {} std::shared_ptr getProcessor(const TConnectionInfo&) override { return processor_; } private: std::shared_ptr processor_; }; } } // apache::thrift #endif // #ifndef _THRIFT_TPROCESSOR_H_ thrift-0.23.0/lib/cpp/src/thrift/TDispatchProcessor.h0000664000175000017500000001206015167543515022744 0ustar00buildbuild00000000000000/* * 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_TDISPATCHPROCESSOR_H_ #define _THRIFT_TDISPATCHPROCESSOR_H_ 1 #include namespace apache { namespace thrift { /** * TDispatchProcessor is a helper class to parse the message header then call * another function to dispatch based on the function name. * * Subclasses must implement dispatchCall() to dispatch on the function name. */ template class TDispatchProcessorT : public TProcessor { public: bool process(std::shared_ptr in, std::shared_ptr out, void* connectionContext) override { protocol::TProtocol* inRaw = in.get(); protocol::TProtocol* outRaw = out.get(); // Try to dynamic cast to the template protocol type auto* specificIn = dynamic_cast(inRaw); auto* specificOut = dynamic_cast(outRaw); if (specificIn && specificOut) { return processFast(specificIn, specificOut, connectionContext); } // Log the fact that we have to use the slow path T_GENERIC_PROTOCOL(this, inRaw, specificIn); T_GENERIC_PROTOCOL(this, outRaw, specificOut); std::string fname; protocol::TMessageType mtype; int32_t seqid; inRaw->readMessageBegin(fname, mtype, seqid); // If this doesn't look like a valid call, log an error and return false so // that the server will close the connection. // // (The old generated processor code used to try to skip a T_STRUCT and // continue. However, that seems unsafe.) if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { TOutput::instance().printf("received invalid message type %d from client", mtype); return false; } return this->dispatchCall(inRaw, outRaw, fname, seqid, connectionContext); } protected: bool processFast(Protocol_* in, Protocol_* out, void* connectionContext) { std::string fname; protocol::TMessageType mtype; int32_t seqid; in->readMessageBegin(fname, mtype, seqid); if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { TOutput::instance().printf("received invalid message type %d from client", mtype); return false; } return this->dispatchCallTemplated(in, out, fname, seqid, connectionContext); } /** * dispatchCall() methods must be implemented by subclasses */ virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in, apache::thrift::protocol::TProtocol* out, const std::string& fname, int32_t seqid, void* callContext) = 0; virtual bool dispatchCallTemplated(Protocol_* in, Protocol_* out, const std::string& fname, int32_t seqid, void* callContext) = 0; }; /** * Non-templatized version of TDispatchProcessor, that doesn't bother trying to * perform a dynamic_cast. */ class TDispatchProcessor : public TProcessor { public: bool process(std::shared_ptr in, std::shared_ptr out, void* connectionContext) override { std::string fname; protocol::TMessageType mtype; int32_t seqid; in->readMessageBegin(fname, mtype, seqid); if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { TOutput::instance().printf("received invalid message type %d from client", mtype); return false; } return dispatchCall(in.get(), out.get(), fname, seqid, connectionContext); } protected: virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in, apache::thrift::protocol::TProtocol* out, const std::string& fname, int32_t seqid, void* callContext) = 0; }; // Specialize TDispatchProcessorT for TProtocol and TDummyProtocol just to use // the generic TDispatchProcessor. template <> class TDispatchProcessorT : public TDispatchProcessor {}; template <> class TDispatchProcessorT : public TDispatchProcessor {}; } } // apache::thrift #endif // _THRIFT_TDISPATCHPROCESSOR_H_ thrift-0.23.0/lib/cpp/src/thrift/TBase.h0000664000175000017500000000225615165535636020170 0ustar00buildbuild00000000000000/* * 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_TBASE_H_ #define _THRIFT_TBASE_H_ 1 #include #include namespace apache { namespace thrift { class TBase { public: virtual ~TBase() = default; virtual uint32_t read(protocol::TProtocol* iprot) = 0; virtual uint32_t write(protocol::TProtocol* oprot) const = 0; }; } } // apache::thrift #endif // #ifndef _THRIFT_TBASE_H_ thrift-0.23.0/lib/cpp/src/thrift/TLogging.h0000664000175000017500000002427515167543515020706 0ustar00buildbuild00000000000000/* * 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_TLOGGING_H_ #define _THRIFT_TLOGGING_H_ 1 #include /** * Contains utility macros for debugging and logging. * */ #include #ifdef HAVE_STDINT_H #include #endif /** * T_GLOBAL_DEBUGGING_LEVEL = 0: all debugging turned off, debug macros undefined * T_GLOBAL_DEBUGGING_LEVEL = 1: all debugging turned on */ #define T_GLOBAL_DEBUGGING_LEVEL 0 /** * T_GLOBAL_LOGGING_LEVEL = 0: all logging turned off, logging macros undefined * T_GLOBAL_LOGGING_LEVEL = 1: all logging turned on */ #define T_GLOBAL_LOGGING_LEVEL 1 /** * Standard wrapper around fprintf what will prefix the file name and line * number to the line. Uses T_GLOBAL_DEBUGGING_LEVEL to control whether it is * turned on or off. * * @param format_string */ #if T_GLOBAL_DEBUGGING_LEVEL > 0 #define T_DEBUG(format_string, ...) \ if (T_GLOBAL_DEBUGGING_LEVEL > 0) { \ fprintf(stderr, "[%s,%d] " format_string " \n", __FILE__, __LINE__, __VA_ARGS__); \ } #else #define T_DEBUG(format_string, ...) #endif /** * analogous to T_DEBUG but also prints the time * * @param string format_string input: printf style format string */ #if T_GLOBAL_DEBUGGING_LEVEL > 0 #define T_DEBUG_T(format_string, ...) \ { \ if (T_GLOBAL_DEBUGGING_LEVEL > 0) { \ time_t now; \ char dbgtime[26]; \ time(&now); \ THRIFT_CTIME_R(&now, dbgtime); \ dbgtime[24] = '\0'; \ fprintf(stderr, \ "[%s,%d] [%s] " format_string " \n", \ __FILE__, \ __LINE__, \ dbgtime, \ __VA_ARGS__); \ } \ } #else #define T_DEBUG_T(format_string, ...) #endif /** * analogous to T_DEBUG but uses input level to determine whether or not the string * should be logged. * * @param int level: specified debug level * @param string format_string input: format string */ #define T_DEBUG_L(level, format_string, ...) \ if ((level) > 0) { \ fprintf(stderr, "[%s,%d] " format_string " \n", __FILE__, __LINE__, __VA_ARGS__); \ } /** * Explicit error logging. Prints time, file name and line number * * @param string format_string input: printf style format string */ #define T_ERROR(format_string, ...) \ { \ time_t now; \ char dbgtime[26]; \ time(&now); \ THRIFT_CTIME_R(&now, dbgtime); \ dbgtime[24] = '\0'; \ fprintf(stderr, \ "[%s,%d] [%s] ERROR: " format_string " \n", \ __FILE__, \ __LINE__, \ dbgtime, \ __VA_ARGS__); \ } /** * Analogous to T_ERROR, additionally aborting the process. * WARNING: macro calls abort(), ending program execution * * @param string format_string input: printf style format string */ #define T_ERROR_ABORT(format_string, ...) \ { \ time_t now; \ char dbgtime[26]; \ time(&now); \ THRIFT_CTIME_R(&now, dbgtime); \ dbgtime[24] = '\0'; \ fprintf(stderr, \ "[%s,%d] [%s] ERROR: Going to abort " format_string " \n", \ __FILE__, \ __LINE__, \ dbgtime, \ __VA_ARGS__); \ exit(1); \ } /** * Log input message * * @param string format_string input: printf style format string */ #if T_GLOBAL_LOGGING_LEVEL > 0 #define T_LOG_OPER(format_string, ...) \ { \ if (T_GLOBAL_LOGGING_LEVEL > 0) { \ time_t now; \ char dbgtime[26]; \ time(&now); \ THRIFT_CTIME_R(&now, dbgtime); \ dbgtime[24] = '\0'; \ fprintf(stderr, "[%s] " format_string " \n", dbgtime, __VA_ARGS__); \ } \ } #else #define T_LOG_OPER(format_string, ...) #endif /** * T_GLOBAL_DEBUG_VIRTUAL = 0 or unset: normal operation, * virtual call debug messages disabled * T_GLOBAL_DEBUG_VIRTUAL = 1: log a debug messages whenever an * avoidable virtual call is made * T_GLOBAL_DEBUG_VIRTUAL = 2: record detailed info that can be * printed by calling * apache::thrift::profile_print_info() */ #if T_GLOBAL_DEBUG_VIRTUAL > 1 #define T_VIRTUAL_CALL() ::apache::thrift::profile_virtual_call(typeid(*this)) #define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \ do { \ if (!(specific_prot)) { \ ::apache::thrift::profile_generic_protocol(typeid(*template_class), typeid(*generic_prot)); \ } \ } while (0) #elif T_GLOBAL_DEBUG_VIRTUAL == 1 #define T_VIRTUAL_CALL() fprintf(stderr, "[%s,%d] virtual call\n", __FILE__, __LINE__) #define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) \ do { \ if (!(specific_prot)) { \ fprintf(stderr, "[%s,%d] failed to cast to specific protocol type\n", __FILE__, __LINE__); \ } \ } while (0) #else #define T_VIRTUAL_CALL() #define T_GENERIC_PROTOCOL(template_class, generic_prot, specific_prot) #endif #endif // #ifndef _THRIFT_TLOGGING_H_ thrift-0.23.0/lib/cpp/src/thrift/TPrintTo.h0000664000175000017500000000520115167543515020703 0ustar00buildbuild00000000000000/* * 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_TPRINTTO_H_ #define _THRIFT_TPRINTTO_H_ 1 #include #include #include namespace apache { namespace thrift { // Generic printTo template - streams value directly to output template void printTo(OStream& out, const T& t) { out << t; } // Special handling of i8 datatypes (THRIFT-5272) - cast to int to avoid char output template void printTo(OStream& out, const int8_t& t) { out << static_cast(t); } // Forward declarations for collection types template void printTo(OStream& out, const std::map& m); template void printTo(OStream& out, const std::set& s); template void printTo(OStream& out, const std::vector& t); // Pair support template void printTo(OStream& out, const std::pair& v) { printTo(out, v.first); out << ": "; printTo(out, v.second); } // Iterator range support template void printTo(OStream& out, Iterator beg, Iterator end) { for (Iterator it = beg; it != end; ++it) { if (it != beg) out << ", "; printTo(out, *it); } } // Vector support template void printTo(OStream& out, const std::vector& t) { out << "["; printTo(out, t.begin(), t.end()); out << "]"; } // Map support template void printTo(OStream& out, const std::map& m) { out << "{"; printTo(out, m.begin(), m.end()); out << "}"; } // Set support template void printTo(OStream& out, const std::set& s) { out << "{"; printTo(out, s.begin(), s.end()); out << "}"; } } // namespace thrift } // namespace apache #endif // _THRIFT_TPRINTTO_H_ thrift-0.23.0/lib/cpp/src/thrift/TToString.h0000664000175000017500000000711415165535636021065 0ustar00buildbuild00000000000000/* * 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_TOSTRING_H_ #define _THRIFT_TOSTRING_H_ 1 #include #include #include #include #include #include #include #include namespace apache { namespace thrift { // unnamed namespace to enforce internal linkage - could be done with 'inline' when once have C++17 namespace { const auto default_locale = std::locale("C"); } template std::string to_string(const T& t) { std::ostringstream o; o.imbue(default_locale); o << 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) { std::ostringstream o; o.imbue(default_locale); o.precision(static_cast(std::ceil(static_cast(std::numeric_limits::digits * std::log10(2.0f) + 1)))); o << t; return o.str(); } inline std::string to_string(const double& t) { std::ostringstream o; o.imbue(default_locale); o.precision(static_cast(std::ceil(static_cast(std::numeric_limits::digits * std::log10(2.0f) + 1)))); o << t; return o.str(); } inline std::string to_string(const long double& t) { std::ostringstream o; o.imbue(default_locale); o.precision(static_cast(std::ceil(static_cast(std::numeric_limits::digits * std::log10(2.0f) + 1)))); o << t; return o.str(); } template std::string to_string(const std::map& m); template std::string to_string(const std::set& s); template std::string to_string(const std::vector& t); template std::string to_string(const typename std::pair& v) { std::ostringstream o; o << to_string(v.first) << ": " << to_string(v.second); return o.str(); } template std::string to_string(const T& beg, const T& end) { std::ostringstream o; for (T it = beg; it != end; ++it) { if (it != beg) o << ", "; o << to_string(*it); } return o.str(); } template std::string to_string(const std::vector& t) { std::ostringstream o; o << "[" << to_string(t.begin(), t.end()) << "]"; return o.str(); } template std::string to_string(const std::map& m) { std::ostringstream o; o << "{" << to_string(m.begin(), m.end()) << "}"; return o.str(); } template std::string to_string(const std::set& s) { std::ostringstream o; o << "{" << to_string(s.begin(), s.end()) << "}"; return o.str(); } } } // apache::thrift #endif // _THRIFT_TOSTRING_H_ thrift-0.23.0/lib/cpp/thrift-z.pc.in0000664000175000017500000000176315165535636017434 0ustar00buildbuild00000000000000# # 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. # prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Thrift Description: Thrift Zlib API Version: @VERSION@ Requires: thrift = @VERSION@ Libs: -L${libdir} -lthriftz Cflags: -I${includedir} thrift-0.23.0/lib/cpp/libthrift.vcxproj0000664000175000017500000005053215165535636020336 0ustar00buildbuild00000000000000 Debug-mt Win32 Debug-mt x64 Debug Win32 Debug x64 Release-mt Win32 Release-mt x64 Release Win32 Release x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F} Win32Proj thrift libthrift StaticLibrary true MultiByte v140 StaticLibrary true MultiByte v140 StaticLibrary true MultiByte v140 StaticLibrary true MultiByte v140 StaticLibrary false true MultiByte v140 StaticLibrary false true MultiByte v140 StaticLibrary false true MultiByte v140 StaticLibrary false true MultiByte v140 $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(OPENSSL_ROOT_DIR)\include\;$(IncludePath) NotUsing Level3 Disabled HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;_DEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthrift.pdb MultiThreadedDebugDLL Windows true NotUsing Level3 Disabled HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;_DEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthrift.pdb MultiThreadedDebugDll Windows true NotUsing Level3 Disabled HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebugDll Windows true NotUsing Level3 Disabled HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebugDll Windows true Level3 NotUsing MaxSpeed true true HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;NDEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthrift.pdb MultiThreadedDll Windows true true true Level3 NotUsing MaxSpeed true true HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;NDEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthrift.pdb MultiThreadedDll Windows true true true Level3 NotUsing MaxSpeed true true HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDll Windows true true true Level3 NotUsing MaxSpeed true true HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDll Windows true true true thrift-0.23.0/lib/cpp/thrift-qt5.pc.in0000664000175000017500000000176415165535636017675 0ustar00buildbuild00000000000000# # 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. # prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Thrift Description: Thrift Qt5 API Version: @VERSION@ Requires: thrift = @VERSION@ Libs: -L${libdir} -lthriftqt5 Cflags: -I${includedir} thrift-0.23.0/lib/cpp/test/0000755000175000017500000000000015170007200015653 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/test/ZlibTest.cpp0000664000175000017500000004144315167543515020153 0ustar00buildbuild00000000000000/* * 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 _GNU_SOURCE #define _GNU_SOURCE // needed for getopt_long #endif #if defined(_MSC_VER) && (_MSC_VER <= 1700) // polynomial and std::fill_t warning happens in MSVC 2010, 2013, maybe others // https://svn.boost.org/trac/boost/ticket/11426 #pragma warning(disable:4996) #endif #ifdef HAVE_STDINT_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #include #include #include #include #include #include #include #include #include #include using namespace apache::thrift::transport; using std::shared_ptr; using std::string; boost::mt19937 rng; /* * Utility code */ class SizeGenerator { public: virtual ~SizeGenerator() = default; virtual unsigned int getSize() = 0; }; class ConstantSizeGenerator : public SizeGenerator { public: ConstantSizeGenerator(unsigned int value) : value_(value) {} unsigned int getSize() override { return value_; } private: unsigned int value_; }; class LogNormalSizeGenerator : public SizeGenerator { public: LogNormalSizeGenerator(double mean, double std_dev) : gen_(rng, boost::lognormal_distribution(mean, std_dev)) {} unsigned int getSize() override { // Loop until we get a size of 1 or more while (true) { auto value = static_cast(gen_()); if (value >= 1) { return value; } } } private: boost::variate_generator > gen_; }; boost::shared_array gen_uniform_buffer(uint32_t buf_len, uint8_t c) { auto* buf = new uint8_t[buf_len]; memset(buf, c, buf_len); return boost::shared_array(buf); } boost::shared_array gen_compressible_buffer(uint32_t buf_len) { auto* buf = new uint8_t[buf_len]; // Generate small runs of alternately increasing and decreasing bytes boost::uniform_smallint run_length_distribution(1, 64); boost::uniform_smallint byte_distribution(0, UINT8_MAX); boost::variate_generator > byte_generator(rng, byte_distribution); boost::variate_generator > run_len_generator(rng, run_length_distribution); uint32_t idx = 0; int8_t step = 1; while (idx < buf_len) { uint32_t run_length = run_len_generator(); if (idx + run_length > buf_len) { run_length = buf_len - idx; } uint8_t byte = byte_generator(); for (uint32_t n = 0; n < run_length; ++n) { buf[idx] = byte; ++idx; byte += step; } step *= -1; } return boost::shared_array(buf); } boost::shared_array gen_random_buffer(uint32_t buf_len) { auto* buf = new uint8_t[buf_len]; boost::uniform_smallint distribution(0, UINT8_MAX); boost::variate_generator > generator(rng, distribution); for (uint32_t n = 0; n < buf_len; ++n) { buf[n] = generator(); } return boost::shared_array(buf); } /* * Test functions */ void test_write_then_read(const boost::shared_array buf, uint32_t buf_len) { shared_ptr membuf(new TMemoryBuffer()); shared_ptr zlib_trans(new TZlibTransport(membuf)); zlib_trans->write(buf.get(), buf_len); zlib_trans->finish(); boost::shared_array mirror(new uint8_t[buf_len]); uint32_t got = zlib_trans->readAll(mirror.get(), buf_len); BOOST_REQUIRE_EQUAL(got, buf_len); BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf.get(), buf_len), 0); zlib_trans->verifyChecksum(); } void test_separate_checksum(const boost::shared_array buf, uint32_t buf_len) { // This one is tricky. I separate the last byte of the stream out // into a separate crbuf_. The last byte is part of the checksum, // so the entire read goes fine, but when I go to verify the checksum // it isn't there. The original implementation complained that // the stream was not complete. I'm about to go fix that. // It worked. Awesome. shared_ptr membuf(new TMemoryBuffer()); shared_ptr zlib_trans(new TZlibTransport(membuf)); zlib_trans->write(buf.get(), buf_len); zlib_trans->finish(); string tmp_buf; membuf->appendBufferToString(tmp_buf); zlib_trans.reset(new TZlibTransport(membuf, TZlibTransport::DEFAULT_URBUF_SIZE, static_cast(tmp_buf.length() - 1))); boost::shared_array mirror(new uint8_t[buf_len]); uint32_t got = zlib_trans->readAll(mirror.get(), buf_len); BOOST_REQUIRE_EQUAL(got, buf_len); BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf.get(), buf_len), 0); zlib_trans->verifyChecksum(); } void test_incomplete_checksum(const boost::shared_array buf, uint32_t buf_len) { // Make sure we still get that "not complete" error if // it really isn't complete. shared_ptr membuf(new TMemoryBuffer()); shared_ptr zlib_trans(new TZlibTransport(membuf)); zlib_trans->write(buf.get(), buf_len); zlib_trans->finish(); string tmp_buf; membuf->appendBufferToString(tmp_buf); tmp_buf.erase(tmp_buf.length() - 1); membuf->resetBuffer(const_cast(reinterpret_cast(tmp_buf.data())), static_cast(tmp_buf.length())); boost::shared_array mirror(new uint8_t[buf_len]); uint32_t got = zlib_trans->readAll(mirror.get(), buf_len); BOOST_REQUIRE_EQUAL(got, buf_len); BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf.get(), buf_len), 0); try { zlib_trans->verifyChecksum(); BOOST_ERROR("verifyChecksum() did not report an error"); } catch (TTransportException& ex) { BOOST_CHECK_EQUAL(ex.getType(), TTransportException::CORRUPTED_DATA); } } void test_read_write_mix(const boost::shared_array buf, uint32_t buf_len, const shared_ptr& write_gen, const shared_ptr& read_gen) { // Try it with a mix of read/write sizes. shared_ptr membuf(new TMemoryBuffer()); shared_ptr zlib_trans(new TZlibTransport(membuf)); unsigned int tot; tot = 0; while (tot < buf_len) { uint32_t write_len = write_gen->getSize(); if (tot + write_len > buf_len) { write_len = buf_len - tot; } zlib_trans->write(buf.get() + tot, write_len); tot += write_len; } zlib_trans->finish(); tot = 0; boost::shared_array mirror(new uint8_t[buf_len]); while (tot < buf_len) { uint32_t read_len = read_gen->getSize(); uint32_t expected_read_len = read_len; if (tot + read_len > buf_len) { expected_read_len = buf_len - tot; } uint32_t got = zlib_trans->read(mirror.get() + tot, read_len); BOOST_REQUIRE_LE(got, expected_read_len); BOOST_REQUIRE_NE(got, (uint32_t)0); tot += got; } BOOST_CHECK_EQUAL(memcmp(mirror.get(), buf.get(), buf_len), 0); zlib_trans->verifyChecksum(); } void test_invalid_checksum(const boost::shared_array buf, uint32_t buf_len) { // Verify checksum checking. shared_ptr membuf(new TMemoryBuffer()); shared_ptr zlib_trans(new TZlibTransport(membuf)); zlib_trans->write(buf.get(), buf_len); zlib_trans->finish(); string tmp_buf; membuf->appendBufferToString(tmp_buf); // Modify a byte at the end of the buffer (part of the checksum). // On rare occasions, modifying a byte in the middle of the buffer // isn't caught by the checksum. // // (This happens especially often for the uniform buffer. The // re-inflated data is correct, however. I suspect in this case that // we're more likely to modify bytes that are part of zlib metadata // instead of the actual compressed data.) // // I've also seen some failure scenarios where a checksum failure isn't // reported, but zlib keeps trying to decode past the end of the data. // (When this occurs, verifyChecksum() throws an exception indicating // that the end of the data hasn't been reached.) I haven't seen this // error when only modifying checksum bytes. int index = static_cast(tmp_buf.size() - 1); tmp_buf[index]++; membuf->resetBuffer(const_cast(reinterpret_cast(tmp_buf.data())), static_cast(tmp_buf.length())); boost::shared_array mirror(new uint8_t[buf_len]); try { zlib_trans->readAll(mirror.get(), buf_len); zlib_trans->verifyChecksum(); BOOST_ERROR("verifyChecksum() did not report an error"); } catch (TZlibTransportException& ex) { BOOST_CHECK_EQUAL(ex.getType(), TTransportException::INTERNAL_ERROR); } } void test_write_after_flush(const boost::shared_array buf, uint32_t buf_len) { // write some data shared_ptr membuf(new TMemoryBuffer()); shared_ptr zlib_trans(new TZlibTransport(membuf)); zlib_trans->write(buf.get(), buf_len); // call finish() zlib_trans->finish(); // make sure write() throws an error try { uint8_t write_buf[] = "a"; zlib_trans->write(write_buf, 1); BOOST_ERROR("write() after finish() did not raise an exception"); } catch (TTransportException& ex) { BOOST_CHECK_EQUAL(ex.getType(), TTransportException::BAD_ARGS); } // make sure flush() throws an error try { zlib_trans->flush(); BOOST_ERROR("flush() after finish() did not raise an exception"); } catch (TTransportException& ex) { BOOST_CHECK_EQUAL(ex.getType(), TTransportException::BAD_ARGS); } // make sure finish() throws an error try { zlib_trans->finish(); BOOST_ERROR("finish() after finish() did not raise an exception"); } catch (TTransportException& ex) { BOOST_CHECK_EQUAL(ex.getType(), TTransportException::BAD_ARGS); } } void test_no_write() { // Verify that no data is written to the underlying transport if we // never write data to the TZlibTransport. shared_ptr membuf(new TMemoryBuffer()); { // Create a TZlibTransport object, and immediately destroy it // when it goes out of scope. TZlibTransport w_zlib_trans(membuf); } BOOST_CHECK_EQUAL(membuf->available_read(), (uint32_t)0); } void test_get_underlying_transport() { shared_ptr membuf(new TMemoryBuffer()); shared_ptr zlib_trans(new TZlibTransport(membuf)); BOOST_CHECK_EQUAL(membuf.get(), zlib_trans->getUnderlyingTransport().get()); } /* * Initialization */ #if (BOOST_VERSION >= 105900) #define ADD_TEST_CASE(suite, name, _FUNC, ...) \ do { \ ::std::ostringstream name_ss; \ name_ss << name << "-" << BOOST_STRINGIZE(_FUNC); \ ::std::function test_func = ::std::bind(_FUNC, __VA_ARGS__); \ ::boost::unit_test::test_case* tc \ = ::boost::unit_test::make_test_case(test_func, name_ss.str(), __FILE__, __LINE__); \ (suite)->add(tc); \ } while (0) #else #define ADD_TEST_CASE(suite, name, _FUNC, ...) \ do { \ ::std::ostringstream name_ss; \ name_ss << name << "-" << BOOST_STRINGIZE(_FUNC); \ ::boost::unit_test::test_case* tc \ = ::boost::unit_test::make_test_case(::std::bind(_FUNC, __VA_ARGS__), \ name_ss.str()); \ (suite)->add(tc); \ } while (0) #endif void add_tests(boost::unit_test::test_suite* suite, const boost::shared_array& buf, uint32_t buf_len, const char* name) { ADD_TEST_CASE(suite, name, test_write_then_read, buf, buf_len); ADD_TEST_CASE(suite, name, test_separate_checksum, buf, buf_len); ADD_TEST_CASE(suite, name, test_incomplete_checksum, buf, buf_len); ADD_TEST_CASE(suite, name, test_invalid_checksum, buf, buf_len); ADD_TEST_CASE(suite, name, test_write_after_flush, buf, buf_len); shared_ptr size_32k(new ConstantSizeGenerator(1 << 15)); shared_ptr size_lognormal(new LogNormalSizeGenerator(20, 30)); ADD_TEST_CASE(suite, name << "-constant", test_read_write_mix, buf, buf_len, size_32k, size_32k); ADD_TEST_CASE(suite, name << "-lognormal-write", test_read_write_mix, buf, buf_len, size_lognormal, size_32k); ADD_TEST_CASE(suite, name << "-lognormal-read", test_read_write_mix, buf, buf_len, size_32k, size_lognormal); ADD_TEST_CASE(suite, name << "-lognormal-both", test_read_write_mix, buf, buf_len, size_lognormal, size_lognormal); // Test with a random size distribution, // but use the exact same distribution for reading as for writing. // // Because the SizeGenerator makes a copy of the random number generator, // both SizeGenerators should return the exact same set of values, since they // both start with random number generators in the same state. shared_ptr write_size_gen(new LogNormalSizeGenerator(20, 30)); shared_ptr read_size_gen(new LogNormalSizeGenerator(20, 30)); ADD_TEST_CASE(suite, name << "-lognormal-same-distribution", test_read_write_mix, buf, buf_len, write_size_gen, read_size_gen); } void print_usage(FILE* f, const char* argv0) { fprintf(f, "Usage: %s [boost_options] [options]\n", argv0); fprintf(f, "Options:\n"); fprintf(f, " --seed=, -s \n"); fprintf(f, " --help\n"); } #ifdef BOOST_TEST_DYN_LINK bool init_unit_test_suite() { auto seed = static_cast(time(nullptr)); #ifdef HAVE_INTTYPES_H printf("seed: %" PRIu32 "\n", seed); #endif rng.seed(seed); boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite(); suite->p_name.value = "ZlibTest"; uint32_t buf_len = 1024 * 32; add_tests(suite, gen_uniform_buffer(buf_len, 'a'), buf_len, "uniform"); add_tests(suite, gen_compressible_buffer(buf_len), buf_len, "compressible"); add_tests(suite, gen_random_buffer(buf_len), buf_len, "random"); suite->add(BOOST_TEST_CASE(test_no_write)); suite->add(BOOST_TEST_CASE(test_get_underlying_transport)); return true; } int main( int argc, char* argv[] ) { return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv); } #else boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { THRIFT_UNUSED_VARIABLE(argc); THRIFT_UNUSED_VARIABLE(argv); uint32_t seed = static_cast(time(nullptr)); #ifdef HAVE_INTTYPES_H printf("seed: %" PRIu32 "\n", seed); #endif rng.seed(seed); boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite(); suite->p_name.value = "ZlibTest"; uint32_t buf_len = 1024 * 32; add_tests(suite, gen_uniform_buffer(buf_len, 'a'), buf_len, "uniform"); add_tests(suite, gen_compressible_buffer(buf_len), buf_len, "compressible"); add_tests(suite, gen_random_buffer(buf_len), buf_len, "random"); suite->add(BOOST_TEST_CASE(test_no_write)); return nullptr; } #endif thrift-0.23.0/lib/cpp/test/UnitTestMain.cpp0000664000175000017500000000155215165535636020777 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE thrift #include thrift-0.23.0/lib/cpp/test/TBufferBaseTest.cpp0000664000175000017500000005441115165535636021405 0ustar00buildbuild00000000000000/* * 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 std::shared_ptr; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TBufferedTransport; using apache::thrift::transport::TFramedTransport; using apache::thrift::transport::test::TShortReadTransport; using std::string; // Shamelessly copied from ZlibTransport. TODO: refactor. unsigned int dist[][5000] = { { 1<<15 }, { 5,13,9,1,8,9,11,13,18,48,24,13,21,13,5,11,35,2,4,20,17,72,27,14,15,4,7,26, 12,1,14,9,2,16,29,41,7,24,4,27,14,4,1,4,25,3,6,34,10,8,50,2,14,13,55,29,3, 43,53,49,14,4,10,32,27,48,1,3,1,11,5,17,16,51,17,30,15,11,9,2,2,11,52,12,2, 13,94,1,19,1,38,2,8,43,8,33,7,30,8,17,22,2,15,14,12,34,2,12,6,37,29,74,3, 165,16,11,17,5,14,3,10,7,37,11,24,7,1,3,12,37,8,9,34,17,12,8,21,13,37,1,4, 30,14,78,4,15,2,40,37,17,12,36,82,14,4,1,4,7,17,11,16,88,77,2,3,15,3,34,11, 5,79,22,34,8,4,4,40,22,24,28,9,13,3,34,27,9,16,39,16,39,13,2,4,3,41,26,10,4, 33,4,7,12,5,6,3,10,30,8,21,16,58,19,9,0,47,7,13,11,19,15,7,53,57,2,13,28,22, 3,16,9,25,33,12,40,7,12,64,7,14,24,44,9,2,14,11,2,58,1,26,30,11,9,5,24,7,9, 94,2,10,21,5,5,4,5,6,179,9,18,2,7,13,31,41,17,4,36,3,21,6,26,8,15,18,44,27, 11,9,25,7,0,14,2,12,20,23,13,2,163,9,5,15,65,2,14,6,8,98,11,15,14,34,2,3,10, 22,9,92,7,10,32,67,13,3,4,35,8,2,1,5,0,26,381,7,27,8,2,16,93,4,19,5,8,25,9, 31,14,4,21,5,3,9,22,56,4,18,3,11,18,6,4,3,40,12,16,110,8,35,14,1,18,40,9,12, 14,3,11,7,57,13,18,116,53,19,22,7,16,11,5,8,21,16,1,75,21,20,1,28,2,6,1,7, 19,38,5,6,9,9,4,1,7,55,36,62,5,4,4,24,15,1,12,35,48,20,5,17,1,5,26,15,4,54, 13,5,5,15,5,19,32,29,31,7,6,40,7,80,11,18,8,128,48,6,12,84,13,4,7,2,13,9,16, 17,3,254,1,4,181,8,44,7,6,24,27,9,23,14,34,16,22,25,10,3,3,4,4,12,2,12,6,7, 13,58,13,6,11,19,53,11,66,18,19,10,4,13,2,5,49,58,1,67,7,21,64,14,11,14,8,3, 26,33,91,31,20,7,9,42,39,4,3,55,11,10,0,7,4,75,8,12,0,27,3,8,9,0,12,12,23, 28,23,20,4,13,30,2,22,20,19,30,6,22,2,6,4,24,7,19,55,86,5,33,2,161,6,7,1,62, 13,3,72,12,12,9,7,12,10,5,10,29,1,5,22,13,13,5,2,12,3,7,14,18,2,3,46,21,17, 15,19,3,27,5,16,45,31,10,8,17,18,18,3,7,24,6,55,9,3,6,12,10,12,8,91,9,4,4,4, 27,29,16,5,7,22,43,28,11,14,8,11,28,109,55,71,40,3,8,22,26,15,44,3,25,29,5, 3,32,17,12,3,29,27,25,15,11,8,40,39,38,17,3,9,11,2,32,11,6,20,48,75,27,3,7, 54,12,95,12,7,24,23,2,13,8,15,16,5,12,4,17,7,19,88,2,6,13,115,45,12,21,2,86, 74,9,7,5,16,32,16,2,21,18,6,34,5,18,260,7,12,16,44,19,92,31,7,8,2,9,0,0,15, 8,38,4,8,20,18,2,83,3,3,4,9,5,3,10,3,5,29,15,7,11,8,48,17,23,2,17,4,11,22, 21,64,8,8,4,19,95,0,17,28,9,11,20,71,5,11,18,12,13,45,49,4,1,33,32,23,13,5, 52,2,2,16,3,4,7,12,2,1,12,6,24,1,22,155,21,3,45,4,12,44,26,5,40,36,9,9,8,20, 35,31,3,2,32,50,10,8,37,2,75,35,22,15,192,8,11,23,1,4,29,6,8,8,5,12,18,32,4, 7,12,2,0,0,9,5,48,11,35,3,1,123,6,29,8,11,8,23,51,16,6,63,12,2,5,4,14,2,15, 7,14,3,2,7,17,32,8,8,10,1,23,62,2,49,6,49,47,23,3,20,7,11,39,10,24,6,15,5,5, 11,8,16,36,8,13,20,3,10,44,7,52,7,10,36,6,15,10,5,11,4,14,19,17,10,12,3,6, 23,4,13,94,70,7,36,7,38,7,28,8,4,15,3,19,4,33,39,21,109,4,80,6,40,4,432,4,4, 7,8,3,31,8,28,37,34,10,2,21,5,22,0,7,36,14,12,6,24,1,21,5,9,2,29,20,54,113, 13,31,39,27,6,0,27,4,5,2,43,7,8,57,8,62,7,9,12,22,90,30,6,19,7,10,20,6,5,58, 32,30,41,4,10,25,13,3,8,7,10,2,9,6,151,44,16,12,16,20,8,3,18,11,17,4,10,45, 15,8,56,38,52,25,40,14,4,17,15,8,2,19,7,8,26,30,2,3,180,8,26,17,38,35,5,16, 28,5,15,56,13,14,18,9,15,83,27,3,9,4,11,8,27,27,44,10,12,8,3,48,14,7,9,4,4, 8,4,5,9,122,8,14,12,19,17,21,4,29,63,21,17,10,12,18,47,10,10,53,4,18,16,4,8, 118,9,5,12,9,11,9,3,12,32,3,23,2,15,3,3,30,3,17,235,15,22,9,299,14,17,1,5, 16,8,3,7,3,13,2,7,6,4,8,66,2,13,6,15,16,47,3,36,5,7,10,24,1,9,9,8,13,16,26, 12,7,24,21,18,49,23,39,10,41,4,13,4,27,11,12,12,19,4,147,8,10,9,40,21,2,83, 10,5,6,11,25,9,50,57,40,12,12,21,1,3,24,23,9,3,9,13,2,3,12,57,8,11,13,15,26, 15,10,47,36,4,25,1,5,8,5,4,0,12,49,5,19,4,6,16,14,6,10,69,10,33,29,7,8,61, 12,4,0,3,7,6,3,16,29,27,38,4,21,0,24,3,2,1,19,16,22,2,8,138,11,7,7,3,12,22, 3,16,5,7,3,53,9,10,32,14,5,7,3,6,22,9,59,26,8,7,58,5,16,11,55,7,4,11,146,91, 8,13,18,14,6,8,8,31,26,22,6,11,30,11,30,15,18,31,3,48,17,7,6,4,9,2,25,3,35, 13,13,7,8,4,31,10,8,10,4,3,45,10,23,2,7,259,17,21,13,14,3,26,3,8,27,4,18,9, 66,7,12,5,8,17,4,23,55,41,51,2,32,26,66,4,21,14,12,65,16,22,17,5,14,2,29,24, 7,3,36,2,43,53,86,5,28,4,58,13,49,121,6,2,73,2,1,47,4,2,27,10,35,28,27,10, 17,10,56,7,10,14,28,20,24,40,7,4,7,3,10,11,32,6,6,3,15,11,54,573,2,3,6,2,3, 14,64,4,16,12,16,42,10,26,4,6,11,69,18,27,2,2,17,22,9,13,22,11,6,1,15,49,3, 14,1 }, { 11,11,11,15,47,1,3,1,23,5,8,18,3,23,15,21,1,7,19,10,26,1,17,11,31,21,41,18, 34,4,9,58,19,3,3,36,5,18,13,3,14,4,9,10,4,19,56,15,3,5,3,11,27,9,4,10,13,4, 11,6,9,2,18,3,10,19,11,4,53,4,2,2,3,4,58,16,3,0,5,30,2,11,93,10,2,14,10,6,2, 115,2,25,16,22,38,101,4,18,13,2,145,51,45,15,14,15,13,20,7,24,5,13,14,30,40, 10,4,107,12,24,14,39,12,6,13,20,7,7,11,5,18,18,45,22,6,39,3,2,1,51,9,11,4, 13,9,38,44,8,11,9,15,19,9,23,17,17,17,13,9,9,1,10,4,18,6,2,9,5,27,32,72,8, 37,9,4,10,30,17,20,15,17,66,10,4,73,35,37,6,4,16,117,45,13,4,75,5,24,65,10, 4,9,4,13,46,5,26,29,10,4,4,52,3,13,18,63,6,14,9,24,277,9,88,2,48,27,123,14, 61,7,5,10,8,7,90,3,10,3,3,48,17,13,10,18,33,2,19,36,6,21,1,16,12,5,6,2,16, 15,29,88,28,2,15,6,11,4,6,11,3,3,4,18,9,53,5,4,3,33,8,9,8,6,7,36,9,62,14,2, 1,10,1,16,7,32,7,23,20,11,10,23,2,1,0,9,16,40,2,81,5,22,8,5,4,37,51,37,10, 19,57,11,2,92,31,6,39,10,13,16,8,20,6,9,3,10,18,25,23,12,30,6,2,26,7,64,18, 6,30,12,13,27,7,10,5,3,33,24,99,4,23,4,1,27,7,27,49,8,20,16,3,4,13,9,22,67, 28,3,10,16,3,2,10,4,8,1,8,19,3,85,6,21,1,9,16,2,30,10,33,12,4,9,3,1,60,38,6, 24,32,3,14,3,40,8,34,115,5,9,27,5,96,3,40,6,15,5,8,22,112,5,5,25,17,58,2,7, 36,21,52,1,3,95,12,21,4,11,8,59,24,5,21,4,9,15,8,7,21,3,26,5,11,6,7,17,65, 14,11,10,2,17,5,12,22,4,4,2,21,8,112,3,34,63,35,2,25,1,2,15,65,23,0,3,5,15, 26,27,9,5,48,11,15,4,9,5,33,20,15,1,18,19,11,24,40,10,21,74,6,6,32,30,40,5, 4,7,44,10,25,46,16,12,5,40,7,18,5,18,9,12,8,4,25,5,6,36,4,43,8,9,12,35,17,4, 8,9,11,27,5,10,17,40,8,12,4,18,9,18,12,20,25,39,42,1,24,13,22,15,7,112,35,3, 7,17,33,2,5,5,19,8,4,12,24,14,13,2,1,13,6,5,19,11,7,57,0,19,6,117,48,14,8, 10,51,17,12,14,2,5,8,9,15,4,48,53,13,22,4,25,12,11,19,45,5,2,6,54,22,9,15,9, 13,2,7,11,29,82,16,46,4,26,14,26,40,22,4,26,6,18,13,4,4,20,3,3,7,12,17,8,9, 23,6,20,7,25,23,19,5,15,6,23,15,11,19,11,3,17,59,8,18,41,4,54,23,44,75,13, 20,6,11,2,3,1,13,10,3,7,12,3,4,7,8,30,6,6,7,3,32,9,5,28,6,114,42,13,36,27, 59,6,93,13,74,8,69,140,3,1,17,48,105,6,11,5,15,1,10,10,14,8,53,0,8,24,60,2, 6,35,2,12,32,47,16,17,75,2,5,4,37,28,10,5,9,57,4,59,5,12,13,7,90,5,11,5,24, 22,13,30,1,2,10,9,6,19,3,18,47,2,5,7,9,35,15,3,6,1,21,14,14,18,14,9,12,8,73, 6,19,3,32,9,14,17,17,5,55,23,6,16,28,3,11,48,4,6,6,6,12,16,30,10,30,27,51, 18,29,2,3,15,1,76,0,16,33,4,27,3,62,4,10,2,4,8,15,9,41,26,22,2,4,20,4,49,0, 8,1,57,13,12,39,3,63,10,19,34,35,2,7,8,29,72,4,10,0,77,8,6,7,9,15,21,9,4,1, 20,23,1,9,18,9,15,36,4,7,6,15,5,7,7,40,2,9,22,2,3,20,4,12,34,13,6,18,15,1, 38,20,12,7,16,3,19,85,12,16,18,16,2,17,1,13,8,6,12,15,97,17,12,9,3,21,15,12, 23,44,81,26,30,2,5,17,6,6,0,22,42,19,6,19,41,14,36,7,3,56,7,9,3,2,6,9,69,3, 15,4,30,28,29,7,9,15,17,17,6,1,6,153,9,33,5,12,14,16,28,3,8,7,14,12,4,6,36, 9,24,13,13,4,2,9,15,19,9,53,7,13,4,150,17,9,2,6,12,7,3,5,58,19,58,28,8,14,3, 20,3,0,32,56,7,5,4,27,1,68,4,29,13,5,58,2,9,65,41,27,16,15,12,14,2,10,9,24, 3,2,9,2,2,3,14,32,10,22,3,13,11,4,6,39,17,0,10,5,5,10,35,16,19,14,1,8,63,19, 14,8,56,10,2,12,6,12,6,7,16,2,9,9,12,20,73,25,13,21,17,24,5,32,8,12,25,8,14, 16,5,23,3,7,6,3,11,24,6,30,4,21,13,28,4,6,29,15,5,17,6,26,8,15,8,3,7,7,50, 11,30,6,2,28,56,16,24,25,23,24,89,31,31,12,7,22,4,10,17,3,3,8,11,13,5,3,27, 1,12,1,14,8,10,29,2,5,2,2,20,10,0,31,10,21,1,48,3,5,43,4,5,18,13,5,18,25,34, 18,3,5,22,16,3,4,20,3,9,3,25,6,6,44,21,3,12,7,5,42,3,2,14,4,36,5,3,45,51,15, 9,11,28,9,7,6,6,12,26,5,14,10,11,42,55,13,21,4,28,6,7,23,27,11,1,41,36,0,32, 15,26,2,3,23,32,11,2,15,7,29,26,144,33,20,12,7,21,10,7,11,65,46,10,13,20,32, 4,4,5,19,2,19,15,49,41,1,75,10,11,25,1,2,45,11,8,27,18,10,60,28,29,12,30,19, 16,4,24,11,19,27,17,49,18,7,40,13,19,22,8,55,12,11,3,6,5,11,8,10,22,5,9,9, 25,7,17,7,64,1,24,2,12,17,44,4,12,27,21,11,10,7,47,5,9,13,12,38,27,21,7,29, 7,1,17,3,3,5,48,62,10,3,11,17,15,15,6,3,8,10,8,18,19,13,3,9,7,6,44,9,10,4, 43,8,6,6,14,20,38,24,2,4,5,5,7,5,9,39,8,44,40,9,19,7,3,15,25,2,37,18,15,9,5, 8,32,10,5,18,4,7,46,20,17,23,4,11,16,18,31,11,3,11,1,14,1,25,4,27,13,13,39, 14,6,6,35,6,16,13,11,122,21,15,20,24,10,5,152,15,39,5,20,16,9,14,7,53,6,3,8, 19,63,32,6,2,3,20,1,19,5,13,42,15,4,6,68,31,46,11,38,10,24,5,5,8,9,12,3,35, 46,26,16,2,8,4,74,16,44,4,5,1,16,4,14,23,16,69,15,42,31,14,7,7,6,97,14,40,1, 8,7,34,9,39,19,13,15,10,21,18,10,5,15,38,7,5,12,7,20,15,4,11,6,14,5,17,7,39, 35,36,18,20,26,22,4,2,36,21,64,0,5,9,10,6,4,1,7,3,1,3,3,4,10,20,90,2,22,48, 16,23,2,33,40,1,21,21,17,20,8,8,12,4,83,14,48,4,21,3,9,27,5,11,40,15,9,3,16, 17,9,11,4,24,31,17,3,4,2,11,1,8,4,8,6,41,17,4,13,3,7,17,8,27,5,13,6,10,7,13, 12,18,13,60,18,3,8,1,12,125,2,7,16,2,11,2,4,7,26,5,9,14,14,16,8,14,7,14,6,9, 13,9,6,4,26,35,49,36,55,3,9,6,40,26,23,31,19,41,2,10,31,6,54,5,69,16,7,8,16, 1,5,7,4,22,7,7,5,4,48,11,13,3,98,4,11,19,4,2,14,7,34,7,10,3,2,12,7,6,2,5,118 }, }; uint8_t data[1<<15]; string data_str; void init_data() { static bool initted = false; if (initted) return; initted = true; // Repeatability. Kind of. std::srand(42); for (unsigned char & i : data) { i = (uint8_t)rand(); } data_str.assign((char*)data, sizeof(data)); } BOOST_AUTO_TEST_SUITE( TBufferBaseTest ) BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_GetBuffer ) { init_data(); for (auto & d1 : dist) { TMemoryBuffer buffer(16); int offset = 0; int index = 0; while (offset < 1<<15) { buffer.write(&data[offset], d1[index]); offset += d1[index]; index++; } string output = buffer.getBufferAsString(); BOOST_CHECK_EQUAL(data_str, output); } } BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_Read ) { init_data(); for (auto & d1 : dist) { for (auto & d2 : dist) { TMemoryBuffer buffer(16); uint8_t data_out[1<<15]; int offset; int index; offset = 0; index = 0; while (offset < 1<<15) { buffer.write(&data[offset], d1[index]); offset += d1[index]; index++; } offset = 0; index = 0; while (offset < 1<<15) { unsigned int got = buffer.read(&data_out[offset], d2[index]); BOOST_CHECK_EQUAL(got, d2[index]); offset += d2[index]; index++; } BOOST_CHECK(!memcmp(data, data_out, sizeof(data))); } } } BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_ReadString ) { init_data(); for (auto & d1 : dist) { for (auto & d2 : dist) { TMemoryBuffer buffer(16); string output; int offset; int index; offset = 0; index = 0; while (offset < 1<<15) { buffer.write(&data[offset], d1[index]); offset += d1[index]; index++; } offset = 0; index = 0; while (offset < 1<<15) { unsigned int got = buffer.readAppendToString(output, d2[index]); BOOST_CHECK_EQUAL(got, d2[index]); offset += d2[index]; index++; } BOOST_CHECK_EQUAL(output, data_str); } } } BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_Read_Multi1 ) { init_data(); // Do shorter writes and reads so we don't align to power-of-two boundaries. for (auto & d1 : dist) { for (auto & d2 : dist) { TMemoryBuffer buffer(16); uint8_t data_out[1<<15]; int offset; int index; for (int iter = 0; iter < 6; iter++) { offset = 0; index = 0; while (offset < (1<<15)-42) { buffer.write(&data[offset], d1[index]); offset += d1[index]; index++; } offset = 0; index = 0; while (offset < (1<<15)-42) { buffer.read(&data_out[offset], d2[index]); offset += d2[index]; index++; } BOOST_CHECK(!memcmp(data, data_out, (1<<15)-42)); // Pull out the extra data. buffer.read(data_out, 42); } } } } BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_Read_Multi2 ) { init_data(); // Do shorter writes and reads so we don't align to power-of-two boundaries. // Pull the buffer out of the loop so its state gets worked harder. TMemoryBuffer buffer(16); for (auto & d1 : dist) { for (auto & d2 : dist) { uint8_t data_out[1<<15]; int offset; int index; for (int iter = 0; iter < 6; iter++) { offset = 0; index = 0; while (offset < (1<<15)-42) { buffer.write(&data[offset], d1[index]); offset += d1[index]; index++; } offset = 0; index = 0; while (offset < (1<<15)-42) { buffer.read(&data_out[offset], d2[index]); offset += d2[index]; index++; } BOOST_CHECK(!memcmp(data, data_out, (1<<15)-42)); // Pull out the extra data. buffer.read(data_out, 42); } } } } BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_Read_Incomplete ) { init_data(); // Do shorter writes and reads so we don't align to power-of-two boundaries. // Pull the buffer out of the loop so its state gets worked harder. for (auto & d1 : dist) { for (auto & d2 : dist) { TMemoryBuffer buffer(16); uint8_t data_out[1<<13]; int write_offset = 0; int write_index = 0; unsigned int to_write = (1<<14)-42; while (to_write > 0) { int write_amt = (std::min)(d1[write_index], to_write); buffer.write(&data[write_offset], write_amt); write_offset += write_amt; write_index++; to_write -= write_amt; } int read_offset = 0; int read_index = 0; unsigned int to_read = (1<<13)-42; while (to_read > 0) { int read_amt = (std::min)(d2[read_index], to_read); int got = buffer.read(&data_out[read_offset], read_amt); BOOST_CHECK_EQUAL(got, read_amt); read_offset += read_amt; read_index++; to_read -= read_amt; } BOOST_CHECK(!memcmp(data, data_out, (1<<13)-42)); int second_offset = write_offset; int second_index = write_index-1; unsigned int to_second = (1<<14)+42; while (to_second > 0) { int second_amt = (std::min)(d1[second_index], to_second); //printf("%d\n", second_amt); buffer.write(&data[second_offset], second_amt); second_offset += second_amt; second_index++; to_second -= second_amt; } string output = buffer.getBufferAsString(); BOOST_CHECK_EQUAL(data_str.substr((1<<13)-42), output); } } } BOOST_AUTO_TEST_CASE( test_BufferedTransport_Write ) { init_data(); int sizes[] = { 12, 15, 16, 17, 20, 501, 512, 523, 2000, 2048, 2096, 1<<14, 1<<17, }; for (int size : sizes) { for (auto & d1 : dist) { shared_ptr buffer(new TMemoryBuffer(16)); TBufferedTransport trans(buffer, size); int offset = 0; int index = 0; while (offset < 1<<15) { trans.write(&data[offset], d1[index]); offset += d1[index]; index++; } trans.flush(); string output = buffer->getBufferAsString(); BOOST_CHECK_EQUAL(data_str, output); } } } BOOST_AUTO_TEST_CASE( test_BufferedTransport_Read_Full ) { init_data(); int sizes[] = { 12, 15, 16, 17, 20, 501, 512, 523, 2000, 2048, 2096, 1<<14, 1<<17, }; for (int size : sizes) { for (auto & d1 : dist) { shared_ptr buffer(new TMemoryBuffer(data, sizeof(data))); TBufferedTransport trans(buffer, size); uint8_t data_out[1<<15]; int offset = 0; int index = 0; while (offset < 1<<15) { // Note: this doesn't work with "read" because TBufferedTransport // doesn't try loop over reads, so we get short reads. We don't // check the return value, so that messes us up. trans.readAll(&data_out[offset], d1[index]); offset += d1[index]; index++; } BOOST_CHECK(!memcmp(data, data_out, sizeof(data))); } } } BOOST_AUTO_TEST_CASE( test_BufferedTransport_Read_Short ) { init_data(); int sizes[] = { 12, 15, 16, 17, 20, 501, 512, 523, 2000, 2048, 2096, 1<<14, 1<<17, }; for (int size : sizes) { for (auto & d1 : dist) { shared_ptr buffer(new TMemoryBuffer(data, sizeof(data))); shared_ptr tshort(new TShortReadTransport(buffer, 0.125)); TBufferedTransport trans(buffer, size); uint8_t data_out[1<<15]; int offset = 0; int index = 0; while (offset < 1<<15) { // Note: this doesn't work with "read" because TBufferedTransport // doesn't try loop over reads, so we get short reads. We don't // check the return value, so that messes us up. trans.readAll(&data_out[offset], d1[index]); offset += d1[index]; index++; } BOOST_CHECK(!memcmp(data, data_out, sizeof(data))); } } } BOOST_AUTO_TEST_CASE( test_FramedTransport_Write ) { init_data(); int sizes[] = { 12, 15, 16, 17, 20, 501, 512, 523, 2000, 2048, 2096, 1<<14, 1<<17, }; for (int size : sizes) { for (auto & d1 : dist) { shared_ptr buffer(new TMemoryBuffer(16)); TFramedTransport trans(buffer, size); int offset = 0; int index = 0; while (offset < 1<<15) { trans.write(&data[offset], d1[index]); offset += d1[index]; index++; } trans.flush(); int32_t frame_size = -1; buffer->read(reinterpret_cast(&frame_size), sizeof(frame_size)); frame_size = (int32_t)ntohl((uint32_t)frame_size); BOOST_CHECK_EQUAL(frame_size, 1<<15); BOOST_CHECK_EQUAL(data_str.size(), (unsigned int)frame_size); string output = buffer->getBufferAsString(); BOOST_CHECK_EQUAL(data_str, output); } } } BOOST_AUTO_TEST_CASE( test_FramedTransport_Read ) { init_data(); for (auto & d1 : dist) { uint8_t data_out[1<<15]; shared_ptr buffer(new TMemoryBuffer()); TFramedTransport trans(buffer); int32_t length = sizeof(data); length = (int32_t)htonl((uint32_t)length); buffer->write(reinterpret_cast(&length), sizeof(length)); buffer->write(data, sizeof(data)); int offset = 0; int index = 0; while (offset < 1<<15) { // This should work with read because we have one huge frame. trans.read(&data_out[offset], d1[index]); offset += d1[index]; index++; } BOOST_CHECK(!memcmp(data, data_out, sizeof(data))); } } BOOST_AUTO_TEST_CASE( test_FramedTransport_Write_Read ) { init_data(); int sizes[] = { 12, 15, 16, 17, 20, 501, 512, 523, 2000, 2048, 2096, 1<<14, 1<<17, }; int probs[] = { 1, 2, 4, 8, 16, 32, }; for (int size : sizes) { for (int prob : probs) { for (auto & d1 : dist) { shared_ptr buffer(new TMemoryBuffer(16)); TFramedTransport trans(buffer, size); std::vector data_out(1<<17, 0); std::vector flush_sizes; int write_offset = 0; int write_index = 0; int flush_size = 0; while (write_offset < 1<<15) { trans.write(&data[write_offset], d1[write_index]); write_offset += d1[write_index]; flush_size += d1[write_index]; write_index++; if (flush_size > 0 && rand()%prob == 0) { flush_sizes.push_back(flush_size); flush_size = 0; trans.flush(); } } if (flush_size != 0) { flush_sizes.push_back(flush_size); flush_size = 0; trans.flush(); } int read_offset = 0; int read_index = 0; for (int fsize : flush_sizes) { // We are exploiting an implementation detail of TFramedTransport. // The read buffer starts empty and it will never do more than one // readFrame per read, so we should always get exactly one frame. int got = trans.read(&data_out[read_offset], 1<<15); BOOST_CHECK_EQUAL(got, fsize); read_offset += got; read_index++; } BOOST_CHECK_EQUAL((unsigned int)read_offset, sizeof(data)); BOOST_CHECK(!memcmp(data, &data_out[0], sizeof(data))); } } } } BOOST_AUTO_TEST_CASE( test_FramedTransport_Empty_Flush ) { init_data(); string output1("\x00\x00\x00\x01""a", 5); string output2("\x00\x00\x00\x01""a\x00\x00\x00\x02""bc", 11); shared_ptr buffer(new TMemoryBuffer()); TFramedTransport trans(buffer); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), ""); trans.flush(); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), ""); trans.flush(); trans.flush(); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), ""); trans.write((const uint8_t*)"a", 1); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), ""); trans.flush(); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), output1); trans.flush(); trans.flush(); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), output1); trans.write((const uint8_t*)"bc", 2); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), output1); trans.flush(); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), output2); trans.flush(); trans.flush(); BOOST_CHECK_EQUAL(buffer->getBufferAsString(), output2); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/GenericHelpers.h0000664000175000017500000000736015165535636020762 0ustar00buildbuild00000000000000/* * 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_TEST_GENERICHELPERS_H_ #define _THRIFT_TEST_GENERICHELPERS_H_ 1 #include #include #include #include /* ClassName Helper for cleaner exceptions */ class ClassNames { public: template static const char* getName() { return "Unknown type"; } }; template <> const char* ClassNames::getName() { return "byte"; } template <> const char* ClassNames::getName() { return "short"; } template <> const char* ClassNames::getName() { return "int"; } template <> const char* ClassNames::getName() { return "long"; } template <> const char* ClassNames::getName() { return "double"; } template <> const char* ClassNames::getName() { return "string"; } template <> const char* ClassNames::getName() { return "uuid"; } /* Generic Protocol I/O function for tests */ class GenericIO { public: /* Write functions */ static uint32_t write(std::shared_ptr proto, const int8_t& val) { return proto->writeByte(val); } static uint32_t write(std::shared_ptr proto, const int16_t& val) { return proto->writeI16(val); } static uint32_t write(std::shared_ptr proto, const int32_t& val) { return proto->writeI32(val); } static uint32_t write(std::shared_ptr proto, const double& val) { return proto->writeDouble(val); } static uint32_t write(std::shared_ptr proto, const int64_t& val) { return proto->writeI64(val); } static uint32_t write(std::shared_ptr proto, const std::string& val) { 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); } static uint32_t read(std::shared_ptr proto, int16_t& val) { return proto->readI16(val); } static uint32_t read(std::shared_ptr proto, int32_t& val) { return proto->readI32(val); } static uint32_t read(std::shared_ptr proto, int64_t& val) { return proto->readI64(val); } static uint32_t read(std::shared_ptr proto, double& val) { return proto->readDouble(val); } 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 thrift-0.23.0/lib/cpp/test/EnumTest.cpp0000664000175000017500000000651015165535636020156 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE EnumTest #include #include "gen-cpp/EnumTest_types.h" std::ostream& operator <<(std::ostream& os, const MyEnumWithCustomOstream::type& val) { os << "{" << (int)val << ":CUSTOM!" << "}"; return os; } std::string to_string(const MyEnumWithCustomOstream::type& val) { std::ostringstream os; os << val; return os.str(); } BOOST_AUTO_TEST_SUITE(EnumTest) BOOST_AUTO_TEST_CASE(test_enum_value) { // Check that all the enum values match what we expect BOOST_CHECK_EQUAL(MyEnum1::ME1_0, 0); BOOST_CHECK_EQUAL(MyEnum1::ME1_1, 1); BOOST_CHECK_EQUAL(MyEnum1::ME1_2, 2); BOOST_CHECK_EQUAL(MyEnum1::ME1_3, 3); BOOST_CHECK_EQUAL(MyEnum1::ME1_5, 5); BOOST_CHECK_EQUAL(MyEnum1::ME1_6, 6); BOOST_CHECK_EQUAL(MyEnum2::ME2_0, 0); BOOST_CHECK_EQUAL(MyEnum2::ME2_1, 1); BOOST_CHECK_EQUAL(MyEnum2::ME2_2, 2); BOOST_CHECK_EQUAL(MyEnum3::ME3_0, 0); BOOST_CHECK_EQUAL(MyEnum3::ME3_1, 1); BOOST_CHECK_EQUAL(MyEnum3::ME3_N2, -2); BOOST_CHECK_EQUAL(MyEnum3::ME3_N1, -1); BOOST_CHECK_EQUAL(MyEnum3::ME3_D0, 0); BOOST_CHECK_EQUAL(MyEnum3::ME3_D1, 1); BOOST_CHECK_EQUAL(MyEnum3::ME3_9, 9); BOOST_CHECK_EQUAL(MyEnum3::ME3_10, 10); BOOST_CHECK_EQUAL(MyEnum4::ME4_A, 0x7ffffffd); BOOST_CHECK_EQUAL(MyEnum4::ME4_B, 0x7ffffffe); BOOST_CHECK_EQUAL(MyEnum4::ME4_C, 0x7fffffff); BOOST_CHECK_EQUAL(MyEnum5::e1, 0); BOOST_CHECK_EQUAL(MyEnum5::e2, 42); } template std::string EnumToString(_T e) { std::stringstream ss; ss << e; return ss.str(); } BOOST_AUTO_TEST_CASE(test_enum_ostream) { BOOST_CHECK_EQUAL(EnumToString(MyEnum1::ME1_0), "ME1_0"); BOOST_CHECK_EQUAL(EnumToString(MyEnum5::e2), "e2"); BOOST_CHECK_EQUAL(EnumToString(MyEnum3::ME3_N1), "ME3_N1"); BOOST_CHECK_EQUAL(EnumToString(MyEnumWithCustomOstream::CustoM2), "{2:CUSTOM!}"); // some invalid or unknown value auto uut = static_cast(44); BOOST_CHECK_EQUAL(EnumToString(uut), "44"); } BOOST_AUTO_TEST_CASE(test_enum_to_string) { BOOST_CHECK_EQUAL(::to_string(MyEnum1::ME1_0), "ME1_0"); BOOST_CHECK_EQUAL(::to_string(MyEnum5::e2), "e2"); BOOST_CHECK_EQUAL(::to_string(MyEnum3::ME3_N1), "ME3_N1"); BOOST_CHECK_EQUAL(::to_string(MyEnumWithCustomOstream::CustoM2), "{2:CUSTOM!}"); // some invalid or unknown value auto uut = static_cast(44); BOOST_CHECK_EQUAL(::to_string(uut), "44"); } BOOST_AUTO_TEST_CASE(test_enum_constant) { MyStruct ms; BOOST_CHECK_EQUAL(ms.me2_2, 2); BOOST_CHECK_EQUAL(ms.me3_n2, -2); BOOST_CHECK_EQUAL(ms.me3_d1, 1); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/TUuidTestBoost.cpp0000664000175000017500000000430315165535636021311 0ustar00buildbuild00000000000000/* * 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() thrift-0.23.0/lib/cpp/test/OneWayHTTPTest.cpp0000664000175000017500000001640315165535636021156 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include #include #include #include #include #include "gen-cpp/OneWayService.h" BOOST_AUTO_TEST_SUITE(OneWayHTTPTest) using namespace apache::thrift; using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TBinaryProtocol; using apache::thrift::protocol::TBinaryProtocolFactory; using apache::thrift::protocol::TJSONProtocol; using apache::thrift::protocol::TJSONProtocolFactory; using apache::thrift::server::TThreadedServer; using apache::thrift::server::TServerEventHandler; using apache::thrift::transport::TTransport; using apache::thrift::transport::THttpServer; using apache::thrift::transport::THttpServerTransportFactory; using apache::thrift::transport::THttpClient; using apache::thrift::transport::TBufferedTransport; using apache::thrift::transport::TBufferedTransportFactory; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TServerSocket; using apache::thrift::transport::TSocket; using apache::thrift::transport::TTransportException; using std::shared_ptr; using std::string; namespace utf = boost::unit_test; // Define this env var to enable some logging (in case you need to debug) #undef ENABLE_STDERR_LOGGING class OneWayServiceHandler : public onewaytest::OneWayServiceIf { public: OneWayServiceHandler() = default; void roundTripRPC() override { #ifdef ENABLE_STDERR_LOGGING cerr << "roundTripRPC()" << '\n'; #endif } void oneWayRPC() override { #ifdef ENABLE_STDERR_LOGGING cerr << "oneWayRPC()" << '\n'; #endif } }; class OneWayServiceCloneFactory : virtual public onewaytest::OneWayServiceIfFactory { public: ~OneWayServiceCloneFactory() override = default; onewaytest::OneWayServiceIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) override { (void)connInfo ; return new OneWayServiceHandler; } void releaseHandler( onewaytest::OneWayServiceIf* handler) override { delete handler; } }; class RPC0ThreadClass { public: RPC0ThreadClass(TThreadedServer& server) : server_(server) { } // Constructor ~RPC0ThreadClass() = default; // Destructor void Run() { server_.serve() ; } TThreadedServer& server_ ; } ; using apache::thrift::concurrency::Monitor; using apache::thrift::concurrency::Mutex; using apache::thrift::concurrency::Synchronized; // copied from IntegrationTest class TServerReadyEventHandler : public TServerEventHandler, public Monitor { public: TServerReadyEventHandler() : isListening_(false), accepted_(0) {} ~TServerReadyEventHandler() override = default; void preServe() override { Synchronized sync(*this); isListening_ = true; notify(); } void* createContext(shared_ptr input, shared_ptr output) override { Synchronized sync(*this); ++accepted_; notify(); (void)input; (void)output; return nullptr; } bool isListening() const { return isListening_; } uint64_t acceptedCount() const { return accepted_; } private: bool isListening_; uint64_t accepted_; }; class TBlockableBufferedTransport : public TBufferedTransport { public: TBlockableBufferedTransport(std::shared_ptr transport) : TBufferedTransport(transport, 10240), blocked_(false) { } uint32_t write_buffer_length() { auto have_bytes = static_cast(wBase_ - wBuf_.get()); return have_bytes ; } void block() { blocked_ = true ; #ifdef ENABLE_STDERR_LOGGING cerr << "block flushing\n" ; #endif } void unblock() { blocked_ = false ; #ifdef ENABLE_STDERR_LOGGING cerr << "unblock flushing, buffer is\n<<" << std::string((char *)wBuf_.get(), write_buffer_length()) << ">>\n" ; #endif } void flush() override { if (blocked_) { #ifdef ENABLE_STDERR_LOGGING cerr << "flush was blocked\n" ; #endif return ; } TBufferedTransport::flush() ; } bool blocked_ ; } ; BOOST_AUTO_TEST_CASE( JSON_BufferedHTTP ) { std::shared_ptr ss = std::make_shared(0) ; TThreadedServer server( std::make_shared(std::make_shared()), ss, //port std::make_shared(), std::make_shared()); std::shared_ptr pEventHandler(new TServerReadyEventHandler) ; server.setServerEventHandler(pEventHandler); #ifdef ENABLE_STDERR_LOGGING cerr << "Starting the server...\n"; #endif RPC0ThreadClass t(server) ; boost::thread thread(&RPC0ThreadClass::Run, &t); { Synchronized sync(*(pEventHandler.get())); while (!pEventHandler->isListening()) { pEventHandler->wait(); } } int port = ss->getPort() ; #ifdef ENABLE_STDERR_LOGGING cerr << "port " << port << '\n'; #endif { std::shared_ptr socket(new TSocket("localhost", port)); socket->setRecvTimeout(10000) ; // 1000msec should be enough std::shared_ptr blockable_transport(new TBlockableBufferedTransport(socket)); std::shared_ptr transport(new THttpClient(blockable_transport, "localhost", "/service")); std::shared_ptr protocol(new TJSONProtocol(transport)); onewaytest::OneWayServiceClient client(protocol); transport->open(); client.roundTripRPC(); blockable_transport->block() ; uint32_t size0 = blockable_transport->write_buffer_length() ; client.send_oneWayRPC() ; uint32_t size1 = blockable_transport->write_buffer_length() ; client.send_oneWayRPC() ; uint32_t size2 = blockable_transport->write_buffer_length() ; BOOST_CHECK((size1 - size0) == (size2 - size1)) ; blockable_transport->unblock() ; client.send_roundTripRPC() ; blockable_transport->flush() ; try { client.recv_roundTripRPC() ; } catch (const TTransportException &e) { BOOST_ERROR( "we should not get a transport exception -- this means we failed: " + std::string(e.what()) ) ; } transport->close(); } server.stop(); thread.join() ; #ifdef ENABLE_STDERR_LOGGING cerr << "finished.\n"; #endif } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/TServerIntegrationTest.cpp0000664000175000017500000004610215165535636023051 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE TServerIntegrationTest #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gen-cpp/ParentService.h" #include #include using apache::thrift::concurrency::Guard; using apache::thrift::concurrency::Monitor; using apache::thrift::concurrency::Mutex; using apache::thrift::concurrency::Synchronized; using apache::thrift::protocol::TBinaryProtocol; using apache::thrift::protocol::TBinaryProtocolFactory; using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using apache::thrift::transport::TServerSocket; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TSocket; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TTransportFactory; using apache::thrift::server::TServer; using apache::thrift::server::TServerEventHandler; using apache::thrift::server::TSimpleServer; using apache::thrift::server::TThreadPoolServer; using apache::thrift::server::TThreadedServer; using std::dynamic_pointer_cast; using std::make_shared; using std::shared_ptr; using apache::thrift::test::ParentServiceClient; using apache::thrift::test::ParentServiceIf; using apache::thrift::test::ParentServiceIfFactory; using apache::thrift::test::ParentServiceIfSingletonFactory; using apache::thrift::test::ParentServiceProcessor; using apache::thrift::test::ParentServiceProcessorFactory; using apache::thrift::TProcessor; using apache::thrift::TProcessorFactory; using boost::posix_time::milliseconds; /** * preServe runs after listen() is successful, when we can connect */ class TServerReadyEventHandler : public TServerEventHandler, public Monitor { public: TServerReadyEventHandler() : isListening_(false), accepted_(0) {} ~TServerReadyEventHandler() override = default; void preServe() override { Synchronized sync(*this); isListening_ = true; notify(); } void* createContext(shared_ptr input, shared_ptr output) override { Synchronized sync(*this); ++accepted_; notify(); (void)input; (void)output; return nullptr; } bool isListening() const { return isListening_; } uint64_t acceptedCount() const { return accepted_; } private: bool isListening_; uint64_t accepted_; }; /** * Reusing another generated test, just something to serve up */ class ParentHandler : public ParentServiceIf { public: ParentHandler() : generation_(0) {} int32_t incrementGeneration() override { Guard g(mutex_); return ++generation_; } int32_t getGeneration() override { Guard g(mutex_); return generation_; } void addString(const std::string& s) override { Guard g(mutex_); strings_.push_back(s); } void getStrings(std::vector& _return) override { Guard g(mutex_); _return = strings_; } void getDataWait(std::string& _return, const int32_t length) override { THRIFT_UNUSED_VARIABLE(_return); THRIFT_UNUSED_VARIABLE(length); } void onewayWait() override {} void exceptionWait(const std::string& message) override { THRIFT_UNUSED_VARIABLE(message); } void unexpectedExceptionWait(const std::string& message) override { THRIFT_UNUSED_VARIABLE(message); } protected: Mutex mutex_; int32_t generation_; std::vector strings_; }; void autoSocketCloser(TSocket* pSock) { pSock->close(); delete pSock; } template class TServerIntegrationTestFixture { public: TServerIntegrationTestFixture(const shared_ptr& _processorFactory) : pServer(new TServerType(_processorFactory, shared_ptr( new TServerSocket("localhost", 0)), shared_ptr(new TTransportFactory), shared_ptr(new TBinaryProtocolFactory))), pEventHandler(shared_ptr(new TServerReadyEventHandler)), bStressDone(false), bStressConnectionCount(0), bStressRequestCount(0) { pServer->setServerEventHandler(pEventHandler); } TServerIntegrationTestFixture(const shared_ptr& _processor) : pServer( new TServerType(_processor, shared_ptr(new TServerSocket("localhost", 0)), shared_ptr(new TTransportFactory), shared_ptr(new TBinaryProtocolFactory))), pEventHandler(shared_ptr(new TServerReadyEventHandler)), bStressDone(false), bStressConnectionCount(0), bStressRequestCount(0) { pServer->setServerEventHandler(pEventHandler); } void startServer() { pServerThread.reset(new boost::thread(std::bind(&TServerType::serve, pServer.get()))); // block until listen() completes so clients will be able to connect Synchronized sync(*(pEventHandler.get())); while (!pEventHandler->isListening()) { pEventHandler->wait(); } BOOST_TEST_MESSAGE(" server is listening"); } void blockUntilAccepted(uint64_t numAccepted) { Synchronized sync(*(pEventHandler.get())); while (pEventHandler->acceptedCount() < numAccepted) { pEventHandler->wait(); } BOOST_TEST_MESSAGE(boost::format(" server has accepted %1%") % numAccepted); } void stopServer() { if (pServerThread) { pServer->stop(); BOOST_TEST_MESSAGE(" server stop completed"); pServerThread->join(); BOOST_TEST_MESSAGE(" server thread joined"); pServerThread.reset(); } } ~TServerIntegrationTestFixture() { stopServer(); } /** * Performs a baseline test where some clients are opened and issue a single operation * and then disconnect at different intervals. * \param[in] numToMake the number of concurrent clients * \param[in] expectedHWM the high water mark we expect of concurrency * \param[in] purpose a description of the test for logging purposes */ void baseline(int64_t numToMake, int64_t expectedHWM, const std::string& purpose) { BOOST_TEST_MESSAGE(boost::format("Testing %1%: %2% with %3% clients, expect %4% HWM") % typeid(TServerType).name() % purpose % numToMake % expectedHWM); startServer(); std::vector > holdSockets; std::vector > holdThreads; for (int64_t i = 0; i < numToMake; ++i) { shared_ptr pClientSock(new TSocket("localhost", getServerPort()), autoSocketCloser); holdSockets.push_back(pClientSock); shared_ptr pClientProtocol(new TBinaryProtocol(pClientSock)); ParentServiceClient client(pClientProtocol); pClientSock->open(); client.incrementGeneration(); holdThreads.push_back(shared_ptr( new boost::thread(std::bind(&TServerIntegrationTestFixture::delayClose, this, pClientSock, milliseconds(10 * numToMake))))); } BOOST_CHECK_EQUAL(expectedHWM, pServer->getConcurrentClientCountHWM()); BOOST_FOREACH (shared_ptr pThread, holdThreads) { pThread->join(); } holdThreads.clear(); holdSockets.clear(); stopServer(); } /** * Helper method used to close a connection after a delay. * \param[in] toClose the connection to close * \param[in] after the delay to impose */ void delayClose(shared_ptr toClose, boost::posix_time::time_duration after) { boost::this_thread::sleep(after); toClose->close(); } /** * \returns the server port number */ int getServerPort() { auto* pSock = dynamic_cast(pServer->getServerTransport().get()); if (!pSock) { throw std::logic_error("how come?"); } return pSock->getPort(); } /** * Performs a stress test by spawning threads that connect, do a number of operations * and disconnect, then a random delay, then do it over again. This is done for a fixed * period of time to test for concurrency correctness. * \param[in] numToMake the number of concurrent clients */ void stress(int64_t numToMake, const boost::posix_time::time_duration& duration) { BOOST_TEST_MESSAGE(boost::format("Stress testing %1% with %2% clients for %3% seconds") % typeid(TServerType).name() % numToMake % duration.total_seconds()); startServer(); std::vector > holdThreads; for (int64_t i = 0; i < numToMake; ++i) { holdThreads.push_back(shared_ptr( new boost::thread(std::bind(&TServerIntegrationTestFixture::stressor, this)))); } boost::this_thread::sleep(duration); bStressDone = true; BOOST_TEST_MESSAGE(boost::format(" serviced %1% connections (HWM %2%) totaling %3% requests") % bStressConnectionCount % pServer->getConcurrentClientCountHWM() % bStressRequestCount); BOOST_FOREACH (shared_ptr pThread, holdThreads) { pThread->join(); } holdThreads.clear(); BOOST_CHECK(bStressRequestCount > 0); stopServer(); } /** * Helper method to stress the system */ void stressor() { while (!bStressDone) { shared_ptr pSocket(new TSocket("localhost", getServerPort()), autoSocketCloser); shared_ptr pProtocol(new TBinaryProtocol(pSocket)); ParentServiceClient client(pProtocol); pSocket->open(); bStressConnectionCount.fetch_add(1, std::memory_order_relaxed); for (int i = 0; i < rand() % 1000; ++i) { client.incrementGeneration(); bStressRequestCount.fetch_add(1, std::memory_order_relaxed); } } } shared_ptr pServer; shared_ptr pEventHandler; shared_ptr pServerThread; std::atomic bStressDone; std::atomic bStressConnectionCount; std::atomic bStressRequestCount; }; template class TServerIntegrationProcessorFactoryTestFixture : public TServerIntegrationTestFixture { public: TServerIntegrationProcessorFactoryTestFixture() : TServerIntegrationTestFixture(make_shared( make_shared( make_shared()))) {} }; template class TServerIntegrationProcessorTestFixture : public TServerIntegrationTestFixture { public: TServerIntegrationProcessorTestFixture() : TServerIntegrationTestFixture( make_shared(make_shared())) {} }; BOOST_AUTO_TEST_SUITE(constructors) BOOST_FIXTURE_TEST_CASE(test_simple_factory, TServerIntegrationProcessorFactoryTestFixture) { baseline(3, 1, "factory"); } BOOST_FIXTURE_TEST_CASE(test_simple, TServerIntegrationProcessorTestFixture) { baseline(3, 1, "processor"); } BOOST_FIXTURE_TEST_CASE(test_threaded_factory, TServerIntegrationProcessorFactoryTestFixture) { baseline(10, 10, "factory"); } BOOST_FIXTURE_TEST_CASE(test_threaded, TServerIntegrationProcessorTestFixture) { baseline(10, 10, "processor"); } BOOST_FIXTURE_TEST_CASE(test_threaded_bound, TServerIntegrationProcessorTestFixture) { pServer->setConcurrentClientLimit(4); baseline(10, 4, "limit by server framework"); } BOOST_FIXTURE_TEST_CASE(test_threaded_stress, TServerIntegrationProcessorFactoryTestFixture) { stress(10, boost::posix_time::seconds(3)); } BOOST_FIXTURE_TEST_CASE(test_threadpool_factory, TServerIntegrationProcessorFactoryTestFixture) { pServer->getThreadManager()->threadFactory( shared_ptr( new apache::thrift::concurrency::ThreadFactory)); pServer->getThreadManager()->start(); // thread factory has 4 threads as a default // thread factory however is a bad way to limit concurrent clients // as accept() will be called to grab a 5th client socket, in this case // and then the thread factory will block adding the thread to manage // that client. baseline(10, 5, "limit by thread manager"); } BOOST_FIXTURE_TEST_CASE(test_threadpool, TServerIntegrationProcessorTestFixture) { pServer->getThreadManager()->threadFactory( shared_ptr( new apache::thrift::concurrency::ThreadFactory)); pServer->getThreadManager()->start(); // thread factory has 4 threads as a default // thread factory however is a bad way to limit concurrent clients // as accept() will be called to grab a 5th client socket, in this case // and then the thread factory will block adding the thread to manage // that client. baseline(10, 5, "limit by thread manager"); } BOOST_FIXTURE_TEST_CASE(test_threadpool_bound, TServerIntegrationProcessorTestFixture) { pServer->getThreadManager()->threadFactory( shared_ptr( new apache::thrift::concurrency::ThreadFactory)); pServer->getThreadManager()->start(); pServer->setConcurrentClientLimit(4); baseline(10, 4, "server framework connection limit"); } BOOST_FIXTURE_TEST_CASE(test_threadpool_stress, TServerIntegrationProcessorTestFixture) { pServer->getThreadManager()->threadFactory( shared_ptr( new apache::thrift::concurrency::ThreadFactory)); pServer->getThreadManager()->start(); stress(10, boost::posix_time::seconds(3)); } BOOST_AUTO_TEST_SUITE_END() BOOST_FIXTURE_TEST_SUITE(TServerIntegrationTest, TServerIntegrationProcessorTestFixture) BOOST_AUTO_TEST_CASE(test_stop_with_interruptable_clients_connected) { // This tests THRIFT-2441 new behavior: stopping the server disconnects clients BOOST_TEST_MESSAGE("Testing stop with interruptable clients"); startServer(); shared_ptr pClientSock1(new TSocket("localhost", getServerPort()), autoSocketCloser); pClientSock1->open(); shared_ptr pClientSock2(new TSocket("localhost", getServerPort()), autoSocketCloser); pClientSock2->open(); // Ensure they have been accepted blockUntilAccepted(2); // The test fixture destructor will force the sockets to disconnect // Prior to THRIFT-2441, pServer->stop() would hang until clients disconnected stopServer(); // extra proof the server end disconnected the clients uint8_t buf[1]; BOOST_CHECK_EQUAL(0, pClientSock1->read(&buf[0], 1)); // 0 = disconnected BOOST_CHECK_EQUAL(0, pClientSock2->read(&buf[0], 1)); // 0 = disconnected } BOOST_AUTO_TEST_CASE(test_stop_with_uninterruptable_clients_connected) { // This tests pre-THRIFT-2441 behavior: stopping the server blocks until clients // disconnect. BOOST_TEST_MESSAGE("Testing stop with uninterruptable clients"); dynamic_pointer_cast(pServer->getServerTransport()) ->setInterruptableChildren(false); // returns to pre-THRIFT-2441 behavior startServer(); shared_ptr pClientSock1(new TSocket("localhost", getServerPort()), autoSocketCloser); pClientSock1->open(); shared_ptr pClientSock2(new TSocket("localhost", getServerPort()), autoSocketCloser); pClientSock2->open(); // Ensure they have been accepted blockUntilAccepted(2); boost::thread t1(std::bind(&TServerIntegrationTestFixture::delayClose, this, pClientSock1, milliseconds(250))); boost::thread t2(std::bind(&TServerIntegrationTestFixture::delayClose, this, pClientSock2, milliseconds(250))); // Once the clients disconnect the server will stop stopServer(); BOOST_CHECK(pServer->getConcurrentClientCountHWM() > 0); t1.join(); t2.join(); } BOOST_AUTO_TEST_CASE(test_concurrent_client_limit) { startServer(); BOOST_TEST_MESSAGE("Testing the concurrent client limit"); BOOST_CHECK_EQUAL(INT64_MAX, pServer->getConcurrentClientLimit()); pServer->setConcurrentClientLimit(2); BOOST_CHECK_EQUAL(0, pServer->getConcurrentClientCount()); BOOST_CHECK_EQUAL(2, pServer->getConcurrentClientLimit()); shared_ptr pClientSock1(new TSocket("localhost", getServerPort()), autoSocketCloser); pClientSock1->open(); blockUntilAccepted(1); BOOST_CHECK_EQUAL(1, pServer->getConcurrentClientCount()); shared_ptr pClientSock2(new TSocket("localhost", getServerPort()), autoSocketCloser); pClientSock2->open(); blockUntilAccepted(2); BOOST_CHECK_EQUAL(2, pServer->getConcurrentClientCount()); // a third client cannot connect until one of the other two closes boost::thread t2(std::bind(&TServerIntegrationTestFixture::delayClose, this, pClientSock2, milliseconds(250))); shared_ptr pClientSock3(new TSocket("localhost", getServerPort()), autoSocketCloser); pClientSock2->open(); blockUntilAccepted(2); BOOST_CHECK_EQUAL(2, pServer->getConcurrentClientCount()); BOOST_CHECK_EQUAL(2, pServer->getConcurrentClientCountHWM()); stopServer(); BOOST_CHECK(pServer->getConcurrentClientCountHWM() > 0); t2.join(); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/TNonblockingSSLServerTest.cpp0000664000175000017500000002232415165535636023413 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE TNonblockingSSLServerTest #include #include #include #include "thrift/server/TNonblockingServer.h" #include "thrift/transport/TSSLSocket.h" #include "thrift/transport/TNonblockingSSLServerSocket.h" #include "gen-cpp/ParentService.h" #include #ifdef HAVE_SIGNAL_H #include #endif using namespace apache::thrift; using apache::thrift::concurrency::Guard; using apache::thrift::concurrency::Monitor; using apache::thrift::concurrency::Mutex; using apache::thrift::server::TServerEventHandler; using apache::thrift::transport::TSSLSocketFactory; using apache::thrift::transport::TSSLSocket; struct Handler : public test::ParentServiceIf { void addString(const std::string& s) override { strings_.push_back(s); } void getStrings(std::vector& _return) override { _return = strings_; } std::vector strings_; // dummy overrides not used in this test int32_t incrementGeneration() override { return 0; } int32_t getGeneration() override { return 0; } void getDataWait(std::string&, const int32_t) override {} void onewayWait() override {} void exceptionWait(const std::string&) override {} void unexpectedExceptionWait(const std::string&) override {} }; boost::filesystem::path keyDir; boost::filesystem::path certFile(const std::string& filename) { return keyDir / filename; } struct GlobalFixtureSSL { GlobalFixtureSSL() { using namespace boost::unit_test::framework; for (int i = 0; i < master_test_suite().argc; ++i) { BOOST_TEST_MESSAGE(boost::format("argv[%1%] = \"%2%\"") % i % master_test_suite().argv[i]); } #ifdef __linux__ // OpenSSL calls send() without MSG_NOSIGPIPE so writing to a socket that has // disconnected can cause a SIGPIPE signal... signal(SIGPIPE, SIG_IGN); #endif TSSLSocketFactory::setManualOpenSSLInitialization(true); apache::thrift::transport::initializeOpenSSL(); keyDir = boost::filesystem::current_path().parent_path().parent_path().parent_path() / "test" / "keys"; if (!boost::filesystem::exists(certFile("server.crt"))) { keyDir = boost::filesystem::path(master_test_suite().argv[master_test_suite().argc - 1]); if (!boost::filesystem::exists(certFile("server.crt"))) { throw std::invalid_argument("The last argument to this test must be the directory containing the test certificate(s)."); } } } virtual ~GlobalFixtureSSL() { apache::thrift::transport::cleanupOpenSSL(); #ifdef __linux__ signal(SIGPIPE, SIG_DFL); #endif } }; #if (BOOST_VERSION >= 105900) BOOST_GLOBAL_FIXTURE(GlobalFixtureSSL); #else BOOST_GLOBAL_FIXTURE(GlobalFixtureSSL) #endif std::shared_ptr createServerSocketFactory() { std::shared_ptr pServerSocketFactory; pServerSocketFactory.reset(new TSSLSocketFactory()); pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); pServerSocketFactory->loadCertificate(certFile("server.crt").string().c_str()); pServerSocketFactory->loadPrivateKey(certFile("server.key").string().c_str()); pServerSocketFactory->server(true); return pServerSocketFactory; } std::shared_ptr createClientSocketFactory() { std::shared_ptr pClientSocketFactory; pClientSocketFactory.reset(new TSSLSocketFactory()); pClientSocketFactory->authenticate(true); pClientSocketFactory->loadCertificate(certFile("client.crt").string().c_str()); pClientSocketFactory->loadPrivateKey(certFile("client.key").string().c_str()); pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").string().c_str()); return pClientSocketFactory; } class Fixture { private: struct ListenEventHandler : public TServerEventHandler { public: ListenEventHandler(Mutex* mutex) : listenMonitor_(mutex), ready_(false) {} void preServe() override /* override */ { Guard g(listenMonitor_.mutex()); ready_ = true; listenMonitor_.notify(); } Monitor listenMonitor_; bool ready_; }; struct Runner : public apache::thrift::concurrency::Runnable { int port; std::shared_ptr userEventBase; std::shared_ptr processor; std::shared_ptr server; std::shared_ptr listenHandler; std::shared_ptr pServerSocketFactory; std::shared_ptr socket; Mutex mutex_; Runner():port(0) { listenHandler.reset(new ListenEventHandler(&mutex_)); } void run() override { // When binding to explicit port, allow retrying to workaround bind failures on ports in use int retryCount = port ? 10 : 0; pServerSocketFactory = createServerSocketFactory(); startServer(retryCount); } void readyBarrier() { // block until server is listening and ready to accept connections Guard g(mutex_); while (!listenHandler->ready_) { listenHandler->listenMonitor_.wait(); } } private: void startServer(int retry_count) { try { socket.reset(new transport::TNonblockingSSLServerSocket(port, pServerSocketFactory)); server.reset(new server::TNonblockingServer(processor, socket)); server->setServerEventHandler(listenHandler); server->setNumIOThreads(1); if (userEventBase) { server->registerEvents(userEventBase.get()); } server->serve(); } catch (const transport::TTransportException&) { if (retry_count > 0) { ++port; startServer(retry_count - 1); } else { throw; } } } }; struct EventDeleter { void operator()(event_base* p) { event_base_free(p); } }; protected: Fixture() : processor(new test::ParentServiceProcessor(std::make_shared())) {} ~Fixture() { if (server) { server->stop(); } if (thread) { thread->join(); } } void setEventBase(event_base* user_event_base) { userEventBase_.reset(user_event_base, EventDeleter()); } int startServer(int port) { std::shared_ptr runner(new Runner); runner->port = port; runner->processor = processor; runner->userEventBase = userEventBase_; std::unique_ptr threadFactory( new apache::thrift::concurrency::ThreadFactory(false)); thread = threadFactory->newThread(runner); thread->start(); runner->readyBarrier(); server = runner->server; return runner->port; } bool canCommunicate(int serverPort) { std::shared_ptr pClientSocketFactory = createClientSocketFactory(); std::shared_ptr socket = pClientSocketFactory->createSocket("localhost", serverPort); socket->open(); test::ParentServiceClient client(std::make_shared( std::make_shared(socket))); client.addString("foo"); std::vector strings; client.getStrings(strings); return strings.size() == 1 && !(strings[0].compare("foo")); } private: std::shared_ptr userEventBase_; std::shared_ptr processor; protected: std::shared_ptr server; private: std::shared_ptr thread; }; BOOST_AUTO_TEST_SUITE(TNonblockingSSLServerTest) BOOST_FIXTURE_TEST_CASE(get_specified_port, Fixture) { int specified_port = startServer(12345); BOOST_REQUIRE_GE(specified_port, 12345); BOOST_REQUIRE_EQUAL(server->getListenPort(), specified_port); BOOST_CHECK(canCommunicate(specified_port)); server->stop(); } BOOST_FIXTURE_TEST_CASE(get_assigned_port, Fixture) { int specified_port = startServer(0); BOOST_REQUIRE_EQUAL(specified_port, 0); int assigned_port = server->getListenPort(); BOOST_REQUIRE_NE(assigned_port, 0); BOOST_CHECK(canCommunicate(assigned_port)); server->stop(); } BOOST_FIXTURE_TEST_CASE(provide_event_base, Fixture) { event_base* eb = event_base_new(); setEventBase(eb); startServer(0); // assert that the server works BOOST_CHECK(canCommunicate(server->getListenPort())); #if LIBEVENT_VERSION_NUMBER > 0x02010400 // also assert that the event_base is actually used when it's easy BOOST_CHECK_GT(event_base_get_num_events(eb, EVENT_BASE_COUNT_ADDED), 0); #endif } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/ToStringTest.cpp0000664000175000017500000001171415165535636021025 0ustar00buildbuild00000000000000/* * 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 #include "gen-cpp/ThriftTest_types.h" #include "gen-cpp/OptionalRequiredTest_types.h" #include "gen-cpp/DebugProtoTest_types.h" using apache::thrift::to_string; BOOST_AUTO_TEST_SUITE(ToStringTest) BOOST_AUTO_TEST_CASE(base_types_to_string) { BOOST_CHECK_EQUAL(to_string(10), "10"); BOOST_CHECK_EQUAL(to_string(true), "1"); BOOST_CHECK_EQUAL(to_string('a'), "a"); BOOST_CHECK_EQUAL(to_string(1.2), "1.2"); BOOST_CHECK_EQUAL(to_string("abc"), "abc"); } // NOTE: Currently (as of 2021.08.12) the locale-based tests do not work on // Windows in the AppVeyor Thrift CI build correctly. Therefore disabled on // Windows: #ifndef _WIN32 BOOST_AUTO_TEST_CASE(locale_en_US_int_to_string) { #ifdef _WIN32 std::locale::global(std::locale("en-US.UTF-8")); #else std::locale::global(std::locale("en_US.UTF-8")); #endif BOOST_CHECK_EQUAL(to_string(1000000), "1000000"); } BOOST_AUTO_TEST_CASE(locale_de_DE_floating_point_to_string) { #ifdef _WIN32 std::locale::global(std::locale("de-DE.UTF-8")); #else std::locale::global(std::locale("de_DE.UTF-8")); #endif BOOST_CHECK_EQUAL(to_string(1.5), "1.5"); BOOST_CHECK_EQUAL(to_string(1.5f), "1.5"); BOOST_CHECK_EQUAL(to_string(1.5L), "1.5"); } #endif BOOST_AUTO_TEST_CASE(empty_vector_to_string) { std::vector l; BOOST_CHECK_EQUAL(to_string(l), "[]"); } BOOST_AUTO_TEST_CASE(single_item_vector_to_string) { std::vector l; l.push_back(100); BOOST_CHECK_EQUAL(to_string(l), "[100]"); } BOOST_AUTO_TEST_CASE(multiple_item_vector_to_string) { std::vector l; l.push_back(100); l.push_back(150); BOOST_CHECK_EQUAL(to_string(l), "[100, 150]"); } BOOST_AUTO_TEST_CASE(empty_map_to_string) { std::map m; BOOST_CHECK_EQUAL(to_string(m), "{}"); } BOOST_AUTO_TEST_CASE(single_item_map_to_string) { std::map m; m[12] = "abc"; BOOST_CHECK_EQUAL(to_string(m), "{12: abc}"); } BOOST_AUTO_TEST_CASE(multi_item_map_to_string) { std::map m; m[12] = "abc"; m[31] = "xyz"; BOOST_CHECK_EQUAL(to_string(m), "{12: abc, 31: xyz}"); } BOOST_AUTO_TEST_CASE(empty_set_to_string) { std::set s; BOOST_CHECK_EQUAL(to_string(s), "{}"); } BOOST_AUTO_TEST_CASE(single_item_set_to_string) { std::set s; s.insert('c'); BOOST_CHECK_EQUAL(to_string(s), "{c}"); } BOOST_AUTO_TEST_CASE(multi_item_set_to_string) { std::set s; s.insert('a'); s.insert('z'); BOOST_CHECK_EQUAL(to_string(s), "{a, z}"); } BOOST_AUTO_TEST_CASE(generated_empty_object_to_string) { thrift::test::EmptyStruct e; BOOST_CHECK_EQUAL(to_string(e), "EmptyStruct()"); } BOOST_AUTO_TEST_CASE(generated_single_basic_field_object_to_string) { thrift::test::StructA a; a.__set_s("abcd"); BOOST_CHECK_EQUAL(to_string(a), "StructA(s=abcd)"); } BOOST_AUTO_TEST_CASE(generated_two_basic_fields_object_to_string) { thrift::test::Bonk a; a.__set_message("abcd"); a.__set_type(1234); BOOST_CHECK_EQUAL(to_string(a), "Bonk(message=abcd, type=1234)"); } BOOST_AUTO_TEST_CASE(generated_optional_fields_object_to_string) { thrift::test::Tricky2 a; BOOST_CHECK_EQUAL(to_string(a), "Tricky2(im_optional=)"); a.__set_im_optional(123); BOOST_CHECK_EQUAL(to_string(a), "Tricky2(im_optional=123)"); } BOOST_AUTO_TEST_CASE(generated_nested_object_to_string) { thrift::test::OneField a; BOOST_CHECK_EQUAL(to_string(a), "OneField(field=EmptyStruct())"); } BOOST_AUTO_TEST_CASE(generated_nested_list_object_to_string) { thrift::test::ListBonks l; l.bonk.assign(2, thrift::test::Bonk()); l.bonk[0].__set_message("a"); l.bonk[1].__set_message("b"); BOOST_CHECK_EQUAL(to_string(l), "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() thrift-0.23.0/lib/cpp/test/concurrency/0000775000175000017500000000000015170007202020211 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/test/concurrency/ThreadFactoryTests.h0000664000175000017500000001700415165535636024173 0ustar00buildbuild00000000000000/* * 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 #include #include #include namespace apache { namespace thrift { namespace concurrency { namespace test { using std::shared_ptr; using namespace apache::thrift::concurrency; /** * ThreadManagerTests class * * @version $Id:$ */ class ThreadFactoryTests { public: /** * Reap N threads */ class ReapNTask : public Runnable { public: ReapNTask(Monitor& monitor, int& activeCount) : _monitor(monitor), _count(activeCount) {} void run() override { Synchronized s(_monitor); if (--_count == 0) { _monitor.notify(); } } Monitor& _monitor; int& _count; }; bool reapNThreads(int loop = 1, int count = 10) { ThreadFactory threadFactory = ThreadFactory(); shared_ptr monitor(new Monitor); for (int lix = 0; lix < loop; lix++) { int activeCount = 0; std::vector > threads; int tix; for (tix = 0; tix < count; tix++) { try { ++activeCount; threads.push_back( threadFactory.newThread(shared_ptr(new ReapNTask(*monitor, activeCount)))); } catch (SystemResourceException& e) { std::cout << "\t\t\tfailed to create " << lix* count + tix << " thread " << e.what() << '\n'; throw; } } tix = 0; for (std::vector >::const_iterator thread = threads.begin(); thread != threads.end(); tix++, ++thread) { try { (*thread)->start(); } catch (SystemResourceException& e) { std::cout << "\t\t\tfailed to start " << lix* count + tix << " thread " << e.what() << '\n'; throw; } } { Synchronized s(*monitor); while (activeCount > 0) { monitor->wait(1000); } } std::cout << "\t\t\treaped " << lix* count << " threads" << '\n'; } std::cout << "\t\t\tSuccess!" << '\n'; return true; } class SynchStartTask : public Runnable { public: enum STATE { UNINITIALIZED, STARTING, STARTED, STOPPING, STOPPED }; SynchStartTask(Monitor& monitor, volatile STATE& state) : _monitor(monitor), _state(state) {} void run() override { { Synchronized s(_monitor); if (_state == SynchStartTask::STARTING) { _state = SynchStartTask::STARTED; _monitor.notify(); } } { Synchronized s(_monitor); while (_state == SynchStartTask::STARTED) { _monitor.wait(); } if (_state == SynchStartTask::STOPPING) { _state = SynchStartTask::STOPPED; _monitor.notifyAll(); } } } private: Monitor& _monitor; volatile STATE& _state; }; bool synchStartTest() { Monitor monitor; SynchStartTask::STATE state = SynchStartTask::UNINITIALIZED; shared_ptr task = shared_ptr(new SynchStartTask(monitor, state)); ThreadFactory threadFactory = ThreadFactory(); shared_ptr thread = threadFactory.newThread(task); if (state == SynchStartTask::UNINITIALIZED) { state = SynchStartTask::STARTING; thread->start(); } { Synchronized s(monitor); while (state == SynchStartTask::STARTING) { monitor.wait(); } } assert(state != SynchStartTask::STARTING); { Synchronized s(monitor); try { monitor.wait(100); } catch (TimedOutException&) { } if (state == SynchStartTask::STARTED) { state = SynchStartTask::STOPPING; monitor.notify(); } while (state == SynchStartTask::STOPPING) { monitor.wait(); } } assert(state == SynchStartTask::STOPPED); bool success = true; std::cout << "\t\t\t" << (success ? "Success" : "Failure") << "!" << '\n'; return true; } /** * The only guarantee a monitor timeout can give you is that * it will take "at least" as long as the timeout, no less. * There is absolutely no guarantee around regaining execution * near the timeout. On a busy system (like inside a third party * CI environment) it could take quite a bit longer than the * requested timeout, and that's ok. */ bool monitorTimeoutTest(int64_t count = 1000, int64_t timeout = 2) { Monitor monitor; int64_t startTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); for (int64_t ix = 0; ix < count; ix++) { { Synchronized s(monitor); try { monitor.wait(timeout); } catch (TimedOutException&) { } } } int64_t endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); bool success = (endTime - startTime) >= (count * timeout); std::cout << "\t\t\t" << (success ? "Success" : "Failure") << ": minimum required time to elapse " << count * timeout << "ms; actual elapsed time " << endTime - startTime << "ms" << '\n'; return success; } class FloodTask : public Runnable { public: FloodTask(const size_t id, Monitor& mon) : _id(id), _mon(mon) {} ~FloodTask() override { if (_id % 10000 == 0) { Synchronized sync(_mon); std::cout << "\t\tthread " << _id << " done" << '\n'; } } void run() override { if (_id % 10000 == 0) { Synchronized sync(_mon); std::cout << "\t\tthread " << _id << " started" << '\n'; } } const size_t _id; Monitor& _mon; }; void foo(ThreadFactory* tf) { (void)tf; } bool floodNTest(size_t loop = 1, size_t count = 100000) { bool success = false; Monitor mon; for (size_t lix = 0; lix < loop; lix++) { ThreadFactory threadFactory = ThreadFactory(); threadFactory.setDetached(true); for (size_t tix = 0; tix < count; tix++) { try { shared_ptr task(new FloodTask(lix * count + tix, mon)); shared_ptr thread = threadFactory.newThread(task); thread->start(); } catch (TException& e) { std::cout << "\t\t\tfailed to start " << lix* count + tix << " thread " << e.what() << '\n'; return success; } } Synchronized sync(mon); std::cout << "\t\t\tflooded " << (lix + 1) * count << " threads" << '\n'; success = true; } return success; } }; } } } } // apache::thrift::concurrency::test thrift-0.23.0/lib/cpp/test/concurrency/TimerManagerTests.h0000664000175000017500000002171715165535636024015 0ustar00buildbuild00000000000000/* * 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 #include #include namespace apache { namespace thrift { namespace concurrency { namespace test { using namespace apache::thrift::concurrency; class TimerManagerTests { public: class Task : public Runnable { public: Task(Monitor& monitor, uint64_t timeout) : _timeout(timeout), _startTime(std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count()), _endTime(0), _monitor(monitor), _success(false), _done(false) {} ~Task() override { std::cerr << this << '\n'; } void run() override { _endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); _success = (_endTime - _startTime) >= _timeout; { Synchronized s(_monitor); _done = true; _monitor.notifyAll(); } } int64_t _timeout; int64_t _startTime; int64_t _endTime; Monitor& _monitor; bool _success; bool _done; }; /** * This test creates two tasks and waits for the first to expire within 10% * of the expected expiration time. It then verifies that the timer manager * properly clean up itself and the remaining orphaned timeout task when the * manager goes out of scope and its destructor is called. */ bool test00(uint64_t timeout = 1000LL) { shared_ptr orphanTask = shared_ptr(new TimerManagerTests::Task(_monitor, 10 * timeout)); { TimerManager timerManager; 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" << '\n'; return false; } // Don't create task yet, because its constructor sets the expected completion time, and we // need to delay between inserting the two tasks into the run queue. shared_ptr task; { Synchronized s(_monitor); timerManager.add(orphanTask, 10 * timeout); std::this_thread::sleep_for(std::chrono::milliseconds(timeout)); task.reset(new TimerManagerTests::Task(_monitor, timeout)); timerManager.add(task, timeout); _monitor.wait(); } if (!task->_done) { std::cerr << "task is not done, but it should have executed" << '\n'; return false; } 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" << '\n'; return false; } return true; } /** * This test creates two tasks, removes the first one then waits for the second one. It then * verifies that the timer manager properly clean up itself and the remaining orphaned timeout * task when the manager goes out of scope and its destructor is called. */ bool test01(uint64_t timeout = 1000LL) { TimerManager timerManager; timerManager.threadFactory(shared_ptr(new ThreadFactory())); timerManager.start(); assert(timerManager.state() == TimerManager::STARTED); Synchronized s(_monitor); // Setup the two tasks shared_ptr taskToRemove = shared_ptr(new TimerManagerTests::Task(_monitor, timeout / 2)); timerManager.add(taskToRemove, taskToRemove->_timeout); shared_ptr task = shared_ptr(new TimerManagerTests::Task(_monitor, timeout)); timerManager.add(task, task->_timeout); // Remove one task and wait until the other has completed timerManager.remove(taskToRemove); _monitor.wait(timeout * 2); assert(!taskToRemove->_done); assert(task->_done); return true; } /** * This test creates two tasks with the same callback and another one, then removes the two * duplicated then waits for the last one. It then verifies that the timer manager properly * clean up itself and the remaining orphaned timeout task when the manager goes out of scope * and its destructor is called. */ bool test02(uint64_t timeout = 1000LL) { TimerManager timerManager; timerManager.threadFactory(shared_ptr(new ThreadFactory())); timerManager.start(); assert(timerManager.state() == TimerManager::STARTED); Synchronized s(_monitor); // Setup the one tasks and add it twice shared_ptr taskToRemove = shared_ptr(new TimerManagerTests::Task(_monitor, timeout / 3)); timerManager.add(taskToRemove, taskToRemove->_timeout); timerManager.add(taskToRemove, taskToRemove->_timeout * 2); shared_ptr task = shared_ptr(new TimerManagerTests::Task(_monitor, timeout)); timerManager.add(task, task->_timeout); // Remove the first task (e.g. two timers) and wait until the other has completed timerManager.remove(taskToRemove); _monitor.wait(timeout * 2); assert(!taskToRemove->_done); assert(task->_done); return true; } /** * This test creates two tasks, removes the first one then waits for the second one. It then * verifies that the timer manager properly clean up itself and the remaining orphaned timeout * task when the manager goes out of scope and its destructor is called. */ bool test03(uint64_t timeout = 1000LL) { TimerManager timerManager; timerManager.threadFactory(shared_ptr(new ThreadFactory())); timerManager.start(); assert(timerManager.state() == TimerManager::STARTED); Synchronized s(_monitor); // Setup the two tasks shared_ptr taskToRemove = shared_ptr(new TimerManagerTests::Task(_monitor, timeout / 2)); TimerManager::Timer timer = timerManager.add(taskToRemove, taskToRemove->_timeout); shared_ptr task = shared_ptr(new TimerManagerTests::Task(_monitor, timeout)); timerManager.add(task, task->_timeout); // Remove one task and wait until the other has completed timerManager.remove(timer); _monitor.wait(timeout * 2); assert(!taskToRemove->_done); assert(task->_done); // Verify behavior when removing the removed task try { timerManager.remove(timer); assert(nullptr == "ERROR: This remove should send a NoSuchTaskException exception."); } catch (NoSuchTaskException&) { } return true; } /** * This test creates one task, and tries to remove it after it has expired. */ bool test04(uint64_t timeout = 1000LL) { TimerManager timerManager; timerManager.threadFactory(shared_ptr(new ThreadFactory())); timerManager.start(); assert(timerManager.state() == TimerManager::STARTED); Synchronized s(_monitor); // Setup the task shared_ptr task = shared_ptr(new TimerManagerTests::Task(_monitor, timeout / 10)); TimerManager::Timer timer = timerManager.add(task, task->_timeout); task.reset(); // Wait until the task has completed _monitor.wait(timeout); // Verify behavior when removing the expired task // notify is called inside the task so the task may still // be running when we get here, so we need to loop... for (;;) { try { timerManager.remove(timer); assert(nullptr == "ERROR: This remove should throw NoSuchTaskException, or UncancellableTaskException."); } catch (const NoSuchTaskException&) { break; } catch (const UncancellableTaskException&) { // the thread was still exiting; try again... std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } return true; } friend class TestTask; Monitor _monitor; }; } } } } // apache::thrift::concurrency thrift-0.23.0/lib/cpp/test/concurrency/ThreadManagerTests.h0000664000175000017500000004547215167543515024145 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include namespace apache { namespace thrift { namespace concurrency { namespace test { using namespace apache::thrift::concurrency; static std::deque > m_expired; static void expiredNotifier(std::shared_ptr runnable) { m_expired.push_back(runnable); } static void sleep_(int64_t millisec) { std::this_thread::sleep_for(std::chrono::milliseconds(millisec)); } class ThreadManagerTests { public: class Task : public Runnable { public: Task(Monitor& monitor, size_t& count, int64_t timeout) : _monitor(monitor), _count(count), _timeout(timeout), _startTime(0), _endTime(0), _done(false) {} void run() override { _startTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); sleep_(_timeout); _endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); _done = true; { Synchronized s(_monitor); // std::cout << "Thread " << _count << " completed " << '\n'; _count--; if (_count % 10000 == 0) { _monitor.notify(); } } } Monitor& _monitor; size_t& _count; int64_t _timeout; int64_t _startTime; int64_t _endTime; bool _done; Monitor _sleep; }; /** * Dispatch count tasks, each of which blocks for timeout milliseconds then * completes. Verify that all tasks completed and that thread manager cleans * up properly on delete. */ bool loadTest(size_t count = 100, int64_t timeout = 100LL, size_t workerCount = 4) { Monitor monitor; size_t activeCount = count; shared_ptr threadManager = ThreadManager::newSimpleThreadManager(workerCount); shared_ptr threadFactory = shared_ptr(new ThreadFactory(false)); threadManager->threadFactory(threadFactory); threadManager->start(); std::set > tasks; for (size_t ix = 0; ix < count; ix++) { tasks.insert(shared_ptr( new ThreadManagerTests::Task(monitor, activeCount, timeout))); } int64_t time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); for (auto ix = tasks.begin(); ix != tasks.end(); ix++) { threadManager->add(*ix); } std::cout << "\t\t\t\tloaded " << count << " tasks to execute" << '\n'; { Synchronized s(monitor); while (activeCount > 0) { std::cout << "\t\t\t\tactiveCount = " << activeCount << '\n'; monitor.wait(); } } int64_t time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); int64_t firstTime = 9223372036854775807LL; int64_t lastTime = 0; double averageTime = 0; int64_t minTime = 9223372036854775807LL; int64_t maxTime = 0; for (auto ix = tasks.begin(); ix != tasks.end(); ix++) { shared_ptr task = *ix; int64_t delta = task->_endTime - task->_startTime; assert(delta > 0); if (task->_startTime < firstTime) { firstTime = task->_startTime; } if (task->_endTime > lastTime) { lastTime = task->_endTime; } if (delta < minTime) { minTime = delta; } if (delta > maxTime) { maxTime = delta; } averageTime += delta; } averageTime /= count; std::cout << "\t\t\tfirst start: " << firstTime << " Last end: " << lastTime << " min: " << minTime << "ms max: " << maxTime << "ms average: " << averageTime << "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" << '\n'; return success; } class BlockTask : public Runnable { public: BlockTask(Monitor& entryMonitor, Monitor& blockMonitor, bool& blocked, Monitor& doneMonitor, size_t& count) : _entryMonitor(entryMonitor), _entered(false), _blockMonitor(blockMonitor), _blocked(blocked), _doneMonitor(doneMonitor), _count(count) {} void run() override { { Synchronized s(_entryMonitor); _entered = true; _entryMonitor.notify(); } { Synchronized s(_blockMonitor); while (_blocked) { _blockMonitor.wait(); } } { Synchronized s(_doneMonitor); if (--_count == 0) { _doneMonitor.notify(); } } } Monitor& _entryMonitor; bool _entered; Monitor& _blockMonitor; bool& _blocked; Monitor& _doneMonitor; size_t& _count; }; /** * Block test. Create pendingTaskCountMax tasks. Verify that we block adding the * pendingTaskCountMax + 1th task. Verify that we unblock when a task completes */ bool blockTest(int64_t timeout = 100LL, size_t workerCount = 2) { (void)timeout; bool success = false; try { Monitor entryMonitor; // not used by this test Monitor blockMonitor; bool blocked[] = {true, true, true}; Monitor doneMonitor; size_t pendingTaskMaxCount = workerCount; size_t activeCounts[] = {workerCount, pendingTaskMaxCount, 1}; shared_ptr threadManager = ThreadManager::newSimpleThreadManager(workerCount, pendingTaskMaxCount); shared_ptr threadFactory = shared_ptr(new ThreadFactory()); threadManager->threadFactory(threadFactory); threadManager->start(); std::vector > tasks; tasks.reserve(workerCount + pendingTaskMaxCount); for (size_t ix = 0; ix < workerCount; ix++) { tasks.push_back(shared_ptr( new ThreadManagerTests::BlockTask(entryMonitor, blockMonitor, blocked[0], doneMonitor, activeCounts[0]))); } for (size_t ix = 0; ix < pendingTaskMaxCount; ix++) { tasks.push_back(shared_ptr( new ThreadManagerTests::BlockTask(entryMonitor, blockMonitor, blocked[1], doneMonitor, activeCounts[1]))); } for (auto ix = tasks.begin(); ix != tasks.end(); ix++) { threadManager->add(*ix); } if (!(success = (threadManager->totalTaskCount() == pendingTaskMaxCount + workerCount))) { throw TException("Unexpected pending task count"); } shared_ptr extraTask( new ThreadManagerTests::BlockTask(entryMonitor, blockMonitor, blocked[2], doneMonitor, activeCounts[2])); try { threadManager->add(extraTask, 1); throw TException("Unexpected success adding task in excess of pending task count"); } catch (TooManyPendingTasksException&) { throw TException("Should have timed out adding task in excess of pending task count"); } catch (TimedOutException&) { // Expected result } try { threadManager->add(extraTask, -1); throw TException("Unexpected success adding task in excess of pending task count"); } catch (TimedOutException&) { throw TException("Unexpected timeout adding task in excess of pending task count"); } catch (TooManyPendingTasksException&) { // Expected result } std::cout << "\t\t\t" << "Pending tasks " << threadManager->pendingTaskCount() << '\n'; { Synchronized s(blockMonitor); blocked[0] = false; blockMonitor.notifyAll(); } { Synchronized s(doneMonitor); while (activeCounts[0] != 0) { doneMonitor.wait(); } } std::cout << "\t\t\t" << "Pending tasks " << threadManager->pendingTaskCount() << '\n'; try { threadManager->add(extraTask, 1); } catch (TimedOutException&) { std::cout << "\t\t\t" << "add timed out unexpectedly" << '\n'; throw TException("Unexpected timeout adding task"); } catch (TooManyPendingTasksException&) { std::cout << "\t\t\t" << "add encountered too many pending exepctions" << '\n'; throw TException("Unexpected timeout adding task"); } // Wake up tasks that were pending before and wait for them to complete { Synchronized s(blockMonitor); blocked[1] = false; blockMonitor.notifyAll(); } { Synchronized s(doneMonitor); while (activeCounts[1] != 0) { doneMonitor.wait(); } } // Wake up the extra task and wait for it to complete { Synchronized s(blockMonitor); blocked[2] = false; blockMonitor.notifyAll(); } { Synchronized s(doneMonitor); while (activeCounts[2] != 0) { doneMonitor.wait(); } } threadManager->stop(); if (!(success = (threadManager->totalTaskCount() == 0))) { throw TException("Unexpected total task count"); } } catch (TException& e) { std::cout << "ERROR: " << e.what() << '\n'; } std::cout << "\t\t\t" << (success ? "Success" : "Failure") << '\n'; return success; } bool apiTest() { // prove currentTime has milliseconds granularity since many other things depend on it int64_t a = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); 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." << '\n'; return false; } return apiTestWithThreadFactory(shared_ptr(new ThreadFactory())); } bool apiTestWithThreadFactory(shared_ptr threadFactory) { shared_ptr threadManager = ThreadManager::newSimpleThreadManager(1); threadManager->threadFactory(threadFactory); 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 << '\n'; return false; } } EXPECT(threadManager->workerCount(), 1); EXPECT(threadManager->idleWorkerCount(), 1); EXPECT(threadManager->pendingTaskCount(), 0); std::cout << "\t\t\t\tadd 2nd worker.. " << '\n'; threadManager->addWorker(); EXPECT(threadManager->workerCount(), 2); EXPECT(threadManager->idleWorkerCount(), 2); EXPECT(threadManager->pendingTaskCount(), 0); std::cout << "\t\t\t\tremove 2nd worker.. " << '\n'; threadManager->removeWorker(); EXPECT(threadManager->workerCount(), 1); EXPECT(threadManager->idleWorkerCount(), 1); EXPECT(threadManager->pendingTaskCount(), 0); std::cout << "\t\t\t\tremove 1st worker.. " << '\n'; threadManager->removeWorker(); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); 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 Monitor blockMonitor; // to be signaled to unblock the task bool blocked(true); // set to false before notifying Monitor doneMonitor; // signaled when count reaches zero size_t activeCount = 1; shared_ptr blockingTask( new ThreadManagerTests::BlockTask(entryMonitor, blockMonitor, blocked, doneMonitor, activeCount)); threadManager->add(blockingTask); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); std::cout << "\t\t\t\tadd other task.. " << '\n'; shared_ptr otherTask( new ThreadManagerTests::Task(doneMonitor, activeCount, 0)); threadManager->add(otherTask); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 2); std::cout << "\t\t\t\tremove blocking task specifically.. " << '\n'; threadManager->remove(blockingTask); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); 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" << '\n'; return false; } EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); 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" << '\n'; return false; } std::cout << "\t\t\t\tadd 2 expired tasks and 1 not.." << '\n'; shared_ptr expiredTask( new ThreadManagerTests::Task(doneMonitor, activeCount, 0)); threadManager->add(expiredTask, 0, 1); threadManager->add(blockingTask); // add one that hasn't expired to make sure it gets skipped threadManager->add(expiredTask, 0, 1); // add a second expired to ensure removeExpiredTasks removes both sleep_(50); // make sure enough time elapses for it to expire - the shortest expiration time is 1 millisecond EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 3); EXPECT(threadManager->expiredTaskCount(), 0); 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" << '\n'; return false; } threadManager->removeExpiredTasks(); if (m_expired.size() != 2) { 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" << '\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" << '\n'; return false; } m_expired.clear(); threadManager->remove(blockingTask); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 2); 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.." << '\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" << '\n'; return false; } if (m_expired.front() != expiredTask) { std::cerr << "\t\t\t\t\texpected m_expired to be the expired task" << '\n'; return false; } m_expired.clear(); EXPECT(threadManager->workerCount(), 1); EXPECT(threadManager->idleWorkerCount(), 1); EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 3); std::cout << "\t\t\t\ttry to remove too many workers" << '\n'; try { threadManager->removeWorker(2); std::cerr << "\t\t\t\t\texpected InvalidArgumentException" << '\n'; return false; } catch (const InvalidArgumentException&) { /* expected */ } std::cout << "\t\t\t\tremove worker.. " << '\n'; threadManager->removeWorker(); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); EXPECT(threadManager->expiredTaskCount(), 3); std::cout << "\t\t\t\tadd blocking task.. " << '\n'; threadManager->add(blockingTask); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 1); std::cout << "\t\t\t\tadd worker.. " << '\n'; threadManager->addWorker(); { Synchronized s(entryMonitor); while (!blockingTask->_entered) { entryMonitor.wait(); } } EXPECT(threadManager->workerCount(), 1); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); std::cout << "\t\t\t\tunblock task and remove worker.. " << '\n'; { Synchronized s(blockMonitor); blocked = false; blockMonitor.notifyAll(); } threadManager->removeWorker(); EXPECT(threadManager->workerCount(), 0); EXPECT(threadManager->idleWorkerCount(), 0); EXPECT(threadManager->pendingTaskCount(), 0); std::cout << "\t\t\t\tcleanup.. " << '\n'; blockingTask.reset(); threadManager.reset(); return true; } }; } } } } // apache::thrift::concurrency using namespace apache::thrift::concurrency::test; thrift-0.23.0/lib/cpp/test/concurrency/Tests.cpp0000664000175000017500000001510615165535636022047 0ustar00buildbuild00000000000000/* * 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 "ThreadFactoryTests.h" #include "TimerManagerTests.h" #include "ThreadManagerTests.h" // The test weight, where 10 is 10 times more threads than baseline // and the baseline is optimized for running in valgrind static int WEIGHT = 10; int main(int argc, char** argv) { std::vector args((argc - 1) > 1 ? (argc - 1) : 1); args[0] = "all"; for (int ix = 1; ix < argc; ix++) { args[ix - 1] = std::string(argv[ix]); } if (getenv("VALGRIND") != nullptr) { // lower the scale of every test WEIGHT = 1; } const bool runAll = args[0].compare("all") == 0; if (runAll || args[0].compare("thread-factory") == 0) { ThreadFactoryTests threadFactoryTests; 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 << '\n'; if (!threadFactoryTests.reapNThreads(reapLoops, reapCount)) { std::cerr << "\t\ttThreadFactory reap N threads FAILED" << '\n'; return 1; } 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" << '\n'; return 1; } std::cout << "\t\tThreadFactory synchronous start test" << '\n'; if (!threadFactoryTests.synchStartTest()) { std::cerr << "\t\ttThreadFactory synchronous start FAILED" << '\n'; return 1; } std::cout << "\t\tThreadFactory monitor timeout test" << '\n'; if (!threadFactoryTests.monitorTimeoutTest()) { std::cerr << "\t\ttThreadFactory monitor timeout FAILED" << '\n'; return 1; } } if (runAll || args[0].compare("util") == 0) { std::cout << "Util tests..." << '\n'; 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" << '\n'; time00 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); time01 = time00; size_t count = 0; while (time01 < time00 + 10) { count++; time01 = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); } std::cout << "\t\t\tscall per ms: " << count / (time01 - time00) << '\n'; } if (runAll || args[0].compare("timer-manager") == 0) { std::cout << "TimerManager tests..." << '\n'; std::cout << "\t\tTimerManager test00" << '\n'; TimerManagerTests timerManagerTests; if (!timerManagerTests.test00()) { std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } std::cout << "\t\tTimerManager test01" << '\n'; if (!timerManagerTests.test01()) { std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } std::cout << "\t\tTimerManager test02" << '\n'; if (!timerManagerTests.test02()) { std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } std::cout << "\t\tTimerManager test03" << '\n'; if (!timerManagerTests.test03()) { std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } std::cout << "\t\tTimerManager test04" << '\n'; if (!timerManagerTests.test04()) { std::cerr << "\t\tTimerManager tests FAILED" << '\n'; return 1; } } if (runAll || args[0].compare("thread-manager") == 0) { std::cout << "ThreadManager tests..." << '\n'; { size_t workerCount = 10 * WEIGHT; size_t taskCount = 500 * WEIGHT; int64_t delay = 10LL; ThreadManagerTests threadManagerTests; std::cout << "\t\tThreadManager api test:" << '\n'; if (!threadManagerTests.apiTest()) { std::cerr << "\t\tThreadManager apiTest FAILED" << '\n'; return 1; } std::cout << "\t\tThreadManager load test: worker count: " << workerCount << " task count: " << taskCount << " delay: " << delay << '\n'; if (!threadManagerTests.loadTest(taskCount, delay, workerCount)) { std::cerr << "\t\tThreadManager loadTest FAILED" << '\n'; return 1; } std::cout << "\t\tThreadManager block test: worker count: " << workerCount << " delay: " << delay << '\n'; if (!threadManagerTests.blockTest(delay, workerCount)) { std::cerr << "\t\tThreadManager blockTest FAILED" << '\n'; return 1; } } } if (runAll || args[0].compare("thread-manager-benchmark") == 0) { std::cout << "ThreadManager benchmark tests..." << '\n'; { size_t minWorkerCount = 2; size_t maxWorkerCount = 8; size_t tasksPerWorker = 100 * WEIGHT; int64_t delay = 5LL; for (size_t workerCount = minWorkerCount; workerCount <= maxWorkerCount; workerCount *= 4) { size_t taskCount = workerCount * tasksPerWorker; std::cout << "\t\tThreadManager load test: worker count: " << workerCount << " task count: " << taskCount << " delay: " << delay << '\n'; ThreadManagerTests threadManagerTests; if (!threadManagerTests.loadTest(taskCount, delay, workerCount)) { std::cerr << "\t\tThreadManager loadTest FAILED" << '\n'; return 1; } } } } std::cout << "ALL TESTS PASSED" << '\n'; return 0; } thrift-0.23.0/lib/cpp/test/AnnotationTest.cpp0000664000175000017500000000403315165535636021362 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE AnnotationTest #include #include "gen-cpp/AnnotationTest_types.h" #include #include // Normally thrift generates ostream operators, however // with the annotation "cpp.customostream" one can tell the // compiler they are going to provide their own, and not // emit operator << or printTo(). std::ostream& operator<<(std::ostream& os, const ostr_custom& osc) { os << "{ bar = " << osc.bar << "; }"; return os; } BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE) BOOST_AUTO_TEST_CASE(test_cpp_compiler_generated_ostream_operator) { ostr_default def; def.__set_bar(10); std::stringstream ssd; ssd << def; BOOST_CHECK_EQUAL(ssd.str(), "ostr_default(bar=10)"); } BOOST_AUTO_TEST_CASE(test_cpp_customostream_uses_consuming_application_definition) { ostr_custom cus; cus.__set_bar(10); std::stringstream csd; csd << cus; BOOST_CHECK_EQUAL(csd.str(), "{ bar = 10; }"); } /** * Disabled; see THRIFT-1567 - not sure what it is supposed to do BOOST_AUTO_TEST_CASE(test_cpp_type) { // Check that the "cpp.type" annotation changes "struct foo" to "DenseFoo" // This won't compile if the annotation is mishandled DenseFoo foo; foo.__set_bar(5); } */ BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/TSSLSocketInterruptTest.cpp0000664000175000017500000002534515165535636023134 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #ifdef HAVE_SIGNAL_H #include #endif using apache::thrift::transport::TSSLServerSocket; using apache::thrift::transport::TSSLSocket; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TSSLSocketFactory; using std::static_pointer_cast; using std::shared_ptr; BOOST_AUTO_TEST_SUITE(TSSLSocketInterruptTest) boost::filesystem::path keyDir; boost::filesystem::path certFile(const std::string& filename) { return keyDir / filename; } boost::mutex gMutex; struct GlobalFixtureSSL { GlobalFixtureSSL() { using namespace boost::unit_test::framework; for (int i = 0; i < master_test_suite().argc; ++i) { BOOST_TEST_MESSAGE(boost::format("argv[%1%] = \"%2%\"") % i % master_test_suite().argv[i]); } #ifdef __linux__ // OpenSSL calls send() without MSG_NOSIGPIPE so writing to a socket that has // disconnected can cause a SIGPIPE signal... signal(SIGPIPE, SIG_IGN); #endif TSSLSocketFactory::setManualOpenSSLInitialization(true); apache::thrift::transport::initializeOpenSSL(); keyDir = boost::filesystem::current_path().parent_path().parent_path().parent_path() / "test" / "keys"; if (!boost::filesystem::exists(certFile("server.crt"))) { keyDir = boost::filesystem::path(master_test_suite().argv[master_test_suite().argc - 1]); if (!boost::filesystem::exists(certFile("server.crt"))) { throw std::invalid_argument("The last argument to this test must be the directory containing the test certificate(s)."); } } } virtual ~GlobalFixtureSSL() { apache::thrift::transport::cleanupOpenSSL(); #ifdef __linux__ signal(SIGPIPE, SIG_DFL); #endif } }; #if (BOOST_VERSION >= 105900) BOOST_GLOBAL_FIXTURE(GlobalFixtureSSL); #else BOOST_GLOBAL_FIXTURE(GlobalFixtureSSL) #endif void readerWorker(shared_ptr tt, uint32_t expectedResult) { uint8_t buf[4]; try { tt->read(buf, 1); BOOST_CHECK_EQUAL(expectedResult, tt->read(buf, 4)); } catch (const TTransportException& tx) { BOOST_CHECK_EQUAL(TTransportException::TIMED_OUT, tx.getType()); } } void readerWorkerMustThrow(shared_ptr tt) { try { uint8_t buf[400]; tt->read(buf, 1); tt->read(buf, 400); BOOST_ERROR("should not have gotten here"); } catch (const TTransportException& tx) { BOOST_CHECK_EQUAL(TTransportException::INTERRUPTED, tx.getType()); } } shared_ptr createServerSocketFactory() { shared_ptr pServerSocketFactory; pServerSocketFactory.reset(new TSSLSocketFactory()); pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); pServerSocketFactory->loadCertificate(certFile("server.crt").string().c_str()); pServerSocketFactory->loadPrivateKey(certFile("server.key").string().c_str()); pServerSocketFactory->server(true); return pServerSocketFactory; } shared_ptr createClientSocketFactory() { shared_ptr pClientSocketFactory; pClientSocketFactory.reset(new TSSLSocketFactory()); pClientSocketFactory->authenticate(true); pClientSocketFactory->loadCertificate(certFile("client.crt").string().c_str()); pClientSocketFactory->loadPrivateKey(certFile("client.key").string().c_str()); pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").string().c_str()); return pClientSocketFactory; } BOOST_AUTO_TEST_CASE(test_ssl_interruptable_child_read_while_handshaking) { shared_ptr pServerSocketFactory = createServerSocketFactory(); TSSLServerSocket sock1("localhost", 0, pServerSocketFactory); sock1.listen(); int port = sock1.getPort(); shared_ptr pClientSocketFactory = createClientSocketFactory(); shared_ptr clientSock = pClientSocketFactory->createSocket("localhost", port); clientSock->open(); shared_ptr accepted = sock1.accept(); boost::thread readThread(std::bind(readerWorkerMustThrow, accepted)); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // readThread is practically guaranteed to be blocking now sock1.interruptChildren(); BOOST_CHECK_MESSAGE(readThread.try_join_for(boost::chrono::milliseconds(20)), "server socket interruptChildren did not interrupt child read"); clientSock->close(); accepted->close(); sock1.close(); } BOOST_AUTO_TEST_CASE(test_ssl_interruptable_child_read) { shared_ptr pServerSocketFactory = createServerSocketFactory(); TSSLServerSocket sock1("localhost", 0, pServerSocketFactory); sock1.listen(); int port = sock1.getPort(); shared_ptr pClientSocketFactory = createClientSocketFactory(); shared_ptr clientSock = pClientSocketFactory->createSocket("localhost", port); clientSock->open(); shared_ptr accepted = sock1.accept(); boost::thread readThread(std::bind(readerWorkerMustThrow, accepted)); clientSock->write((const uint8_t*)"0", 1); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // readThread is practically guaranteed to be blocking now sock1.interruptChildren(); BOOST_CHECK_MESSAGE(readThread.try_join_for(boost::chrono::milliseconds(20)), "server socket interruptChildren did not interrupt child read"); accepted->close(); clientSock->close(); sock1.close(); } BOOST_AUTO_TEST_CASE(test_ssl_non_interruptable_child_read) { shared_ptr pServerSocketFactory = createServerSocketFactory(); TSSLServerSocket sock1("localhost", 0, pServerSocketFactory); sock1.setInterruptableChildren(false); // returns to pre-THRIFT-2441 behavior sock1.listen(); int port = sock1.getPort(); shared_ptr pClientSocketFactory = createClientSocketFactory(); shared_ptr clientSock = pClientSocketFactory->createSocket("localhost", port); clientSock->open(); shared_ptr accepted = sock1.accept(); static_pointer_cast(accepted)->setRecvTimeout(1000); boost::thread readThread(std::bind(readerWorker, accepted, 0)); clientSock->write((const uint8_t*)"0", 1); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // readThread is practically guaranteed to be blocking here sock1.interruptChildren(); BOOST_CHECK_MESSAGE(!readThread.try_join_for(boost::chrono::milliseconds(200)), "server socket interruptChildren interrupted child read"); // wait for receive timeout to kick in readThread.join(); accepted->close(); clientSock->close(); sock1.close(); } BOOST_AUTO_TEST_CASE(test_ssl_cannot_change_after_listen) { shared_ptr pServerSocketFactory = createServerSocketFactory(); TSSLServerSocket sock1("localhost", 0, pServerSocketFactory); sock1.listen(); BOOST_CHECK_THROW(sock1.setInterruptableChildren(false), std::logic_error); sock1.close(); } void peekerWorker(shared_ptr tt, bool expectedResult) { uint8_t buf[400]; try { tt->read(buf, 1); BOOST_CHECK_EQUAL(expectedResult, tt->peek()); } catch (const TTransportException& tx) { BOOST_CHECK_EQUAL(TTransportException::TIMED_OUT, tx.getType()); } } void peekerWorkerInterrupt(shared_ptr tt) { uint8_t buf[400]; try { tt->read(buf, 1); tt->peek(); } catch (const TTransportException& tx) { BOOST_CHECK_EQUAL(TTransportException::INTERRUPTED, tx.getType()); } } BOOST_AUTO_TEST_CASE(test_ssl_interruptable_child_peek) { shared_ptr pServerSocketFactory = createServerSocketFactory(); TSSLServerSocket sock1("localhost", 0, pServerSocketFactory); sock1.listen(); int port = sock1.getPort(); shared_ptr pClientSocketFactory = createClientSocketFactory(); shared_ptr clientSock = pClientSocketFactory->createSocket("localhost", port); clientSock->open(); shared_ptr accepted = sock1.accept(); boost::thread peekThread(std::bind(peekerWorkerInterrupt, accepted)); clientSock->write((const uint8_t*)"0", 1); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // peekThread is practically guaranteed to be blocking now sock1.interruptChildren(); BOOST_CHECK_MESSAGE(peekThread.try_join_for(boost::chrono::milliseconds(200)), "server socket interruptChildren did not interrupt child peek"); accepted->close(); clientSock->close(); sock1.close(); } BOOST_AUTO_TEST_CASE(test_ssl_non_interruptable_child_peek) { shared_ptr pServerSocketFactory = createServerSocketFactory(); TSSLServerSocket sock1("localhost", 0, pServerSocketFactory); sock1.setInterruptableChildren(false); // returns to pre-THRIFT-2441 behavior sock1.listen(); int port = sock1.getPort(); shared_ptr pClientSocketFactory = createClientSocketFactory(); shared_ptr clientSock = pClientSocketFactory->createSocket("localhost", port); clientSock->open(); shared_ptr accepted = sock1.accept(); static_pointer_cast(accepted)->setRecvTimeout(1000); boost::thread peekThread(std::bind(peekerWorker, accepted, false)); clientSock->write((const uint8_t*)"0", 1); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // peekThread is practically guaranteed to be blocking now sock1.interruptChildren(); BOOST_CHECK_MESSAGE(!peekThread.try_join_for(boost::chrono::milliseconds(200)), "server socket interruptChildren interrupted child peek"); // wait for the receive timeout to kick in peekThread.join(); accepted->close(); clientSock->close(); sock1.close(); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/Thrift5272.thrift0000664000175000017500000000204715165535636020711 0ustar00buildbuild00000000000000/* * 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, } thrift-0.23.0/lib/cpp/test/OpenSSLManualInitTest.cpp0000664000175000017500000000563615165535636022527 0ustar00buildbuild00000000000000/* * 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. */ // To show that this test actually tests something, you can change // MANUAL_OPENSSL_INIT to 0 to cause automatic OpenSSL init/cleanup, // which will cause the test to fail #define MANUAL_OPENSSL_INIT 1 #ifdef _WIN32 #include #endif #include #include #include using namespace apache::thrift::transport; void make_isolated_sslsocketfactory() { // Here we create an isolated TSSLSocketFactory to ensure the // constructor and destructor of TSSLSocketFactory get run. Thus // without manual initialization normally OpenSSL would be // uninitialized after this function. TSSLSocketFactory factory; } void openssl_init() { #if MANUAL_OPENSSL_INIT TSSLSocketFactory::setManualOpenSSLInitialization(true); initializeOpenSSL(); #endif } void openssl_cleanup() { #if MANUAL_OPENSSL_INIT cleanupOpenSSL(); #endif } void test_openssl_availability() { // Check whether Thrift leaves OpenSSL functionality available after // the last TSSLSocketFactory is destroyed when manual // initialization is set openssl_init(); make_isolated_sslsocketfactory(); // The following function is one that will fail if OpenSSL is // uninitialized. It might also fail on very old versions of // OpenSSL... const EVP_MD* md = EVP_get_digestbyname("SHA256"); BOOST_CHECK(md != nullptr); openssl_cleanup(); } #ifdef BOOST_TEST_DYN_LINK bool init_unit_test_suite() { boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite(); suite->p_name.value = "OpenSSLManualInit"; suite->add(BOOST_TEST_CASE(test_openssl_availability)); return true; } int main( int argc, char* argv[] ) { return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv); } #else boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { THRIFT_UNUSED_VARIABLE(argc); THRIFT_UNUSED_VARIABLE(argv); boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite(); suite->p_name.value = "OpenSSLManualInit"; suite->add(BOOST_TEST_CASE(test_openssl_availability)); return nullptr; } #endifthrift-0.23.0/lib/cpp/test/SecurityTest.cpp0000664000175000017500000002503515165535636021064 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE SecurityTest #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SIGNAL_H #include #endif using apache::thrift::transport::TSSLServerSocket; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TSSLSocket; using apache::thrift::transport::TSSLSocketFactory; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TTransportFactory; using std::bind; using std::shared_ptr; boost::filesystem::path keyDir; boost::filesystem::path certFile(const std::string& filename) { return keyDir / filename; } boost::mutex gMutex; struct GlobalFixture { GlobalFixture() { using namespace boost::unit_test::framework; for (int i = 0; i < master_test_suite().argc; ++i) { BOOST_TEST_MESSAGE(boost::format("argv[%1%] = \"%2%\"") % i % master_test_suite().argv[i]); } #ifdef __linux__ // OpenSSL calls send() without MSG_NOSIGPIPE so writing to a socket that has // disconnected can cause a SIGPIPE signal... signal(SIGPIPE, SIG_IGN); #endif TSSLSocketFactory::setManualOpenSSLInitialization(true); apache::thrift::transport::initializeOpenSSL(); keyDir = boost::filesystem::current_path().parent_path().parent_path().parent_path() / "test" / "keys"; if (!boost::filesystem::exists(certFile("server.crt"))) { keyDir = boost::filesystem::path(master_test_suite().argv[master_test_suite().argc - 1]); if (!boost::filesystem::exists(certFile("server.crt"))) { throw std::invalid_argument("The last argument to this test must be the directory containing the test certificate(s)."); } } } virtual ~GlobalFixture() { apache::thrift::transport::cleanupOpenSSL(); #ifdef __linux__ signal(SIGPIPE, SIG_DFL); #endif } }; #if (BOOST_VERSION >= 105900) BOOST_GLOBAL_FIXTURE(GlobalFixture); #else BOOST_GLOBAL_FIXTURE(GlobalFixture) #endif struct SecurityFixture { void server(apache::thrift::transport::SSLProtocol protocol) { try { boost::mutex::scoped_lock lock(mMutex); shared_ptr pServerSocketFactory; shared_ptr pServerSocket; pServerSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); #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); pServerSocket.reset(new TSSLServerSocket("localhost", 0, pServerSocketFactory)); shared_ptr connectedClient; try { pServerSocket->listen(); mPort = pServerSocket->getPort(); mCVar.notify_one(); lock.unlock(); connectedClient = pServerSocket->accept(); uint8_t buf[2]; buf[0] = 'O'; buf[1] = 'K'; connectedClient->write(&buf[0], 2); connectedClient->flush(); } catch (apache::thrift::transport::TTransportException& ex) { boost::mutex::scoped_lock lock(gMutex); BOOST_TEST_MESSAGE(boost::format("SRV %1% Exception: %2%") % boost::this_thread::get_id() % ex.what()); } if (connectedClient) { connectedClient->close(); connectedClient.reset(); } pServerSocket->close(); pServerSocket.reset(); } catch (std::exception& ex) { BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what()); } } void client(apache::thrift::transport::SSLProtocol protocol) { try { shared_ptr pClientSocketFactory; shared_ptr pClientSocket; 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->loadCertificate(certFile("client.crt").string().c_str()); pClientSocketFactory->loadPrivateKey(certFile("client.key").string().c_str()); pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").string().c_str()); pClientSocket = pClientSocketFactory->createSocket("localhost", mPort); pClientSocket->open(); uint8_t buf[3]; buf[0] = 0; buf[1] = 0; BOOST_CHECK_EQUAL(2, pClientSocket->read(&buf[0], 2)); BOOST_CHECK_EQUAL(0, memcmp(&buf[0], "OK", 2)); mConnected = true; } catch (apache::thrift::transport::TTransportException& ex) { boost::mutex::scoped_lock lock(gMutex); BOOST_TEST_MESSAGE(boost::format("CLI %1% Exception: %2%") % boost::this_thread::get_id() % ex.what()); } if (pClientSocket) { pClientSocket->close(); pClientSocket.reset(); } } catch (std::exception& ex) { BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what()); } } static const char *protocol2str(size_t protocol) { static const char *strings[apache::thrift::transport::LATEST + 1] = { "SSLTLS", "SSLv2", "SSLv3", "TLSv1_0", "TLSv1_1", "TLSv1_2" }; return strings[protocol]; } boost::mutex mMutex; boost::condition_variable mCVar; int mPort; bool mConnected; }; BOOST_FIXTURE_TEST_SUITE(BOOST_TEST_MODULE, SecurityFixture) 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 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, true, true, true }, /* SSLv2 */ { false, false, false, false, false, false }, /* SSLv3 */ { false, false, true, false, false, 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 } }; for (size_t si = 0; si <= apache::thrift::transport::LATEST; ++si) { for (size_t ci = 0; ci <= apache::thrift::transport::LATEST; ++ci) { if (si == 1 || ci == 1) { // Skip all SSLv2 cases - protocol not supported continue; } #ifdef OPENSSL_NO_SSL3 if (si == 2 || ci == 2) { // Skip all SSLv3 cases - protocol not supported continue; } #endif boost::mutex::scoped_lock lock(mMutex); BOOST_TEST_MESSAGE(boost::format("TEST: Server = %1%, Client = %2%") % protocol2str(si) % protocol2str(ci)); mConnected = false; // thread_group manages the thread lifetime - ignore the return value of create_thread boost::thread_group threads; (void)threads.create_thread(bind(&SecurityFixture::server, this, static_cast(si))); mCVar.wait(lock); // wait for listen() to succeed lock.unlock(); (void)threads.create_thread(bind(&SecurityFixture::client, this, static_cast(ci))); threads.join_all(); BOOST_CHECK_MESSAGE(mConnected == matrix[ci][si], boost::format(" Server = %1%, Client = %2% expected mConnected == %3% but was %4%") % protocol2str(si) % protocol2str(ci) % matrix[ci][si] % mConnected); } } } catch (std::exception& ex) { BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what()); } } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/TPipeInterruptTest.cpp0000664000175000017500000000520015165535636022203 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifdef _WIN32 #include #include #include #include #include #include #include #include using apache::thrift::transport::TPipeServer; using apache::thrift::transport::TPipe; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using namespace apache::thrift; BOOST_AUTO_TEST_SUITE(TPipeInterruptTest) // TODO: duplicate the test cases in TSocketInterruptTest for pipes, // once pipes implement interruptChildren BOOST_AUTO_TEST_CASE(test_interrupt_before_accept) { TPipeServer pipe1("TPipeInterruptTest"); pipe1.listen(); pipe1.interrupt(); BOOST_CHECK_THROW(pipe1.accept(), TTransportException); } static void acceptWorker(TPipeServer *pipe) { try { for (;;) { std::shared_ptr temp = pipe->accept(); } } catch (...) {/*just want to make sure nothing crashes*/ } } static void interruptWorker(TPipeServer *pipe) { boost::this_thread::sleep(boost::posix_time::milliseconds(10)); pipe->interrupt(); } BOOST_AUTO_TEST_CASE(stress_pipe_accept_interruption) { int interruptIters = 10; for (int i = 0; i < interruptIters; ++i) { TPipeServer pipeServer("TPipeInterruptTest"); pipeServer.listen(); boost::thread acceptThread(std::bind(acceptWorker, &pipeServer)); boost::thread interruptThread(std::bind(interruptWorker, &pipeServer)); try { for (;;) { TPipe client("TPipeInterruptTest"); client.setConnTimeout(1); client.open(); } } catch (...) { /*just testing for crashes*/ } interruptThread.join(); acceptThread.join(); } } BOOST_AUTO_TEST_SUITE_END() #endif thrift-0.23.0/lib/cpp/test/RenderedDoubleConstantsTest.cpp0000664000175000017500000001541215165535636024033 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define EPSILON 0.0000001 #include #include #include #include "gen-cpp/DoubleConstantsTest_constants.h" using namespace thrift::test; #define BOOST_TEST_MODULE RenderedDoubleConstantsTest #include BOOST_AUTO_TEST_SUITE(RenderedDoubleConstantsTest) BOOST_AUTO_TEST_CASE(test_rendered_double_constants) { const double EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1.0; const double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100.0; const double EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807.0; const double EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807.0; const double EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359; const double EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1; const double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1; const double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308; const double EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43; const double EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308; const double EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43; BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE, EPSILON); BOOST_CHECK_CLOSE( g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE, EPSILON); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST).hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE).hash_code()); BOOST_CHECK( typeid(g_DoubleConstantsTest_constants.DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST) .hash_code() == typeid(EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE).hash_code()); } BOOST_AUTO_TEST_CASE(test_rendered_double_list) { const std::vector EXPECTED_DOUBLE_LIST{1.0,-100.0,100.0,9223372036854775807.0,-9223372036854775807.0, 3.14159265359,1000000.1,-1000000.1,1.7e+308,-1.7e+308,9223372036854775816.43,-9223372036854775816.43}; BOOST_CHECK_EQUAL(g_DoubleConstantsTest_constants.DOUBLE_LIST_TEST.size(), EXPECTED_DOUBLE_LIST.size()); for (unsigned int i = 0; i < EXPECTED_DOUBLE_LIST.size(); ++i) { BOOST_CHECK_CLOSE(g_DoubleConstantsTest_constants.DOUBLE_LIST_TEST[i], EXPECTED_DOUBLE_LIST[i], EPSILON); } } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/Base64Test.cpp0000664000175000017500000000412515165535636020276 0ustar00buildbuild00000000000000/* * 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 using apache::thrift::protocol::base64_encode; using apache::thrift::protocol::base64_decode; BOOST_AUTO_TEST_SUITE(Base64Test) void setupTestData(int i, uint8_t* data, int& len) { len = 0; do { data[len] = (uint8_t)(i & 0xFF); i >>= 8; len++; } while ((len < 3) && (i != 0)); BOOST_ASSERT(i == 0); } void checkEncoding(uint8_t* data, int len) { #ifdef NDEBUG ((void)data); #endif for (int i = 0; i < len; i++) { BOOST_ASSERT(isalnum(data[i]) || data[i] == '/' || data[i] == '+'); } } BOOST_AUTO_TEST_CASE(test_Base64_Encode_Decode) { int len; uint8_t testInput[3]; uint8_t testOutput[4]; // Test all possible encoding / decoding cases given the // three byte limit for base64_encode. for (int i = 0xFFFFFF; i >= 0; i--) { // fill testInput based on i setupTestData(i, testInput, len); // encode the test data, then decode it again base64_encode(testInput, len, testOutput); // verify each byte has a valid Base64 value (alphanumeric or either + or /) checkEncoding(testOutput, len); // decode output and check that it matches input base64_decode(testOutput, len + 1); BOOST_ASSERT(0 == memcmp(testInput, testOutput, len)); } } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/SecurityFromBufferTest.cpp0000664000175000017500000002365015165535636023043 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE SecurityFromBufferTest #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SIGNAL_H #include #endif using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TSSLServerSocket; using apache::thrift::transport::TSSLSocket; using apache::thrift::transport::TSSLSocketFactory; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TTransportFactory; using std::bind; using std::shared_ptr; boost::filesystem::path keyDir; boost::filesystem::path certFile(const std::string& filename) { return keyDir / filename; } std::string certString(const std::string& filename) { std::ifstream ifs(certFile(filename).string()); if(!ifs.is_open() || !ifs.good()) { throw(std::runtime_error("Failed to open key file " + filename + " for reading")); } std::stringstream buffer; buffer << ifs.rdbuf(); return buffer.str(); } boost::mutex gMutex; struct GlobalFixture { GlobalFixture() { using namespace boost::unit_test::framework; for (int i = 0; i < master_test_suite().argc; ++i) { BOOST_TEST_MESSAGE(boost::format("argv[%1%] = \"%2%\"") % i % master_test_suite().argv[i]); } #ifdef __linux__ // OpenSSL calls send() without MSG_NOSIGPIPE so writing to a socket that has // disconnected can cause a SIGPIPE signal... signal(SIGPIPE, SIG_IGN); #endif TSSLSocketFactory::setManualOpenSSLInitialization(true); apache::thrift::transport::initializeOpenSSL(); keyDir = boost::filesystem::current_path().parent_path().parent_path().parent_path() / "test" / "keys"; if (!boost::filesystem::exists(certFile("server.crt"))) { keyDir = boost::filesystem::path(master_test_suite().argv[master_test_suite().argc - 1]); if (!boost::filesystem::exists(certFile("server.crt"))) { throw std::invalid_argument("The last argument to this test must be the directory containing the test certificate(s)."); } } } virtual ~GlobalFixture() { apache::thrift::transport::cleanupOpenSSL(); #ifdef __linux__ signal(SIGPIPE, SIG_DFL); #endif } }; #if (BOOST_VERSION >= 105900) BOOST_GLOBAL_FIXTURE(GlobalFixture); #else BOOST_GLOBAL_FIXTURE(GlobalFixture) #endif struct SecurityFromBufferFixture { void server(apache::thrift::transport::SSLProtocol protocol) { try { boost::mutex::scoped_lock lock(mMutex); shared_ptr pServerSocketFactory; shared_ptr pServerSocket; pServerSocketFactory.reset(new TSSLSocketFactory(static_cast(protocol))); #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); pServerSocket.reset(new TSSLServerSocket("localhost", 0, pServerSocketFactory)); shared_ptr connectedClient; try { pServerSocket->listen(); mPort = pServerSocket->getPort(); mCVar.notify_one(); lock.unlock(); connectedClient = pServerSocket->accept(); uint8_t buf[2]; buf[0] = 'O'; buf[1] = 'K'; connectedClient->write(&buf[0], 2); connectedClient->flush(); } catch (apache::thrift::transport::TTransportException& ex) { boost::mutex::scoped_lock lock(gMutex); BOOST_TEST_MESSAGE(boost::format("SRV %1% Exception: %2%") % boost::this_thread::get_id() % ex.what()); } if (connectedClient) { connectedClient->close(); connectedClient.reset(); } pServerSocket->close(); pServerSocket.reset(); } catch (std::exception& ex) { BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what()); } } void client(apache::thrift::transport::SSLProtocol protocol) { try { shared_ptr pClientSocketFactory; shared_ptr pClientSocket; 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()); pClientSocket = pClientSocketFactory->createSocket("localhost", mPort); pClientSocket->open(); uint8_t buf[3]; buf[0] = 0; buf[1] = 0; BOOST_CHECK_EQUAL(2, pClientSocket->read(&buf[0], 2)); BOOST_CHECK_EQUAL(0, memcmp(&buf[0], "OK", 2)); mConnected = true; } catch (apache::thrift::transport::TTransportException& ex) { boost::mutex::scoped_lock lock(gMutex); BOOST_TEST_MESSAGE(boost::format("CLI %1% Exception: %2%") % boost::this_thread::get_id() % ex.what()); } if (pClientSocket) { pClientSocket->close(); pClientSocket.reset(); } } catch (std::exception& ex) { BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what()); } } static const char* protocol2str(size_t protocol) { static const char* strings[apache::thrift::transport::LATEST + 1] = {"SSLTLS", "SSLv2", "SSLv3", "TLSv1_0", "TLSv1_1", "TLSv1_2"}; return strings[protocol]; } boost::mutex mMutex; boost::condition_variable mCVar; int mPort; bool mConnected; }; BOOST_FIXTURE_TEST_SUITE(BOOST_TEST_MODULE, SecurityFromBufferFixture) 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 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, true, true, true }, /* SSLv2 */ { false, false, false, false, false, false }, /* SSLv3 */ { false, false, true, false, false, 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 } }; for (size_t si = 0; si <= apache::thrift::transport::LATEST; ++si) { for (size_t ci = 0; ci <= apache::thrift::transport::LATEST; ++ci) { if (si == 1 || ci == 1) { // Skip all SSLv2 cases - protocol not supported continue; } #ifdef OPENSSL_NO_SSL3 if (si == 2 || ci == 2) { // Skip all SSLv3 cases - protocol not supported continue; } #endif boost::mutex::scoped_lock lock(mMutex); BOOST_TEST_MESSAGE(boost::format("TEST: Server = %1%, Client = %2%") % protocol2str(si) % protocol2str(ci)); mConnected = false; // thread_group manages the thread lifetime - ignore the return value of create_thread boost::thread_group threads; (void)threads.create_thread(bind(&SecurityFromBufferFixture::server, this, static_cast(si))); mCVar.wait(lock); // wait for listen() to succeed lock.unlock(); (void)threads.create_thread(bind(&SecurityFromBufferFixture::client, this, static_cast(ci))); threads.join_all(); BOOST_CHECK_MESSAGE(mConnected == matrix[ci][si], boost::format(" Server = %1%, Client = %2% expected mConnected == %3% but was %4%") % protocol2str(si) % protocol2str(ci) % matrix[ci][si] % mConnected); } } } catch (std::exception& ex) { BOOST_FAIL(boost::format("%1%: %2%") % typeid(ex).name() % ex.what()); } } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/JSONProtoTest.cpp0000664000175000017500000003561115165535636021053 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define _USE_MATH_DEFINES #include #include #include #include #include #include #include "gen-cpp/DebugProtoTest_types.h" #define BOOST_TEST_MODULE JSONProtoTest #include using namespace thrift::test::debug; using namespace apache::thrift; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::protocol::TJSONProtocol; static std::shared_ptr ooe; void testCaseSetup_1() { ooe.reset(new OneOfEach); ooe->im_true = true; ooe->im_false = false; ooe->a_bite = 0x7f; ooe->integer16 = 27000; ooe->integer32 = 1 << 24; ooe->integer64 = (uint64_t)6000 * 1000 * 1000; ooe->double_precision = M_PI; 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) { testCaseSetup_1(); const std::string expected_result( "{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127},\"4\":{\"i16\":27000}," "\"5\":{\"i32\":16777216},\"6\":{\"i64\":6000000000},\"7\":{\"dbl\":3.1415926" "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]},\"15\":{\"uid\":\"00000000-0000-0000-0000-000000000000\"},\"16\"" ":{\"lst\":[\"uid\",0]}}"); const std::string result(apache::thrift::ThriftJSONString(*ooe)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } static std::shared_ptr n; void testCaseSetup_2() { testCaseSetup_1(); n.reset(new Nesting); n->my_ooe = *ooe; n->my_ooe.integer16 = 16; n->my_ooe.integer32 = 32; n->my_ooe.integer64 = 64; n->my_ooe.double_precision = (std::sqrt(5.0) + 1) / 2; n->my_ooe.some_characters = ":R (me going \"rrrr\")"; n->my_ooe.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"; 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!"; } BOOST_AUTO_TEST_CASE(test_json_proto_2) { testCaseSetup_2(); const std::string expected_result( "{\"1\":{\"rec\":{\"1\":{\"i32\":31337},\"2\":{\"str\":\"I am a bonk... xor" "!\"}}},\"2\":{\"rec\":{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127" "},\"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]},\"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)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } static std::shared_ptr hm; void testCaseSetup_3() { testCaseSetup_2(); hm.reset(new HolyMoley); hm->big.push_back(*ooe); hm->big.push_back(n->my_ooe); hm->big[0].a_bite = 0x22; hm->big[1].a_bite = 0x33; std::vector stage1; stage1.push_back("and a one"); stage1.push_back("and a two"); hm->contain.insert(stage1); stage1.clear(); stage1.push_back("then a one, two"); stage1.push_back("three!"); stage1.push_back("FOUR!!"); hm->contain.insert(stage1); stage1.clear(); hm->contain.insert(stage1); std::vector stage2; hm->bonks["nothing"] = stage2; stage2.resize(stage2.size() + 1); stage2.back().type = 1; stage2.back().message = "Wait."; stage2.resize(stage2.size() + 1); stage2.back().type = 2; stage2.back().message = "What?"; hm->bonks["something"] = stage2; stage2.clear(); stage2.resize(stage2.size() + 1); stage2.back().type = 3; stage2.back().message = "quoth"; stage2.resize(stage2.size() + 1); stage2.back().type = 4; stage2.back().message = "the raven"; stage2.resize(stage2.size() + 1); stage2.back().type = 5; stage2.back().message = "nevermore"; hm->bonks["poe"] = stage2; } BOOST_AUTO_TEST_CASE(test_json_proto_3) { testCaseSetup_3(); const std::string expected_result( "{\"1\":{\"lst\":[\"rec\",2,{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":" "34},\"4\":{\"i16\":27000},\"5\":{\"i32\":16777216},\"6\":{\"i64\":6000000000" "},\"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]},\"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]},\"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" "\"}},{\"1\":{\"i32\":4},\"2\":{\"str\":\"the raven\"}},{\"1\":{\"i32\":5},\"" "2\":{\"str\":\"nevermore\"}}],\"something\":[\"rec\",2,{\"1\":{\"i32\":1},\"" "2\":{\"str\":\"Wait.\"}},{\"1\":{\"i32\":2},\"2\":{\"str\":\"What?\"}}]}]}}" ); const std::string result(apache::thrift::ThriftJSONString(*hm)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_json_proto_4) { testCaseSetup_1(); std::shared_ptr buffer(new TMemoryBuffer()); std::shared_ptr proto(new TJSONProtocol(buffer)); ooe->write(proto.get()); OneOfEach ooe2; ooe2.read(proto.get()); BOOST_TEST_INFO("written: " << *ooe); BOOST_TEST_INFO("read : " << ooe2); BOOST_CHECK(*ooe == ooe2); } BOOST_AUTO_TEST_CASE(test_json_proto_5) { testCaseSetup_3(); std::shared_ptr buffer(new TMemoryBuffer()); std::shared_ptr proto(new TJSONProtocol(buffer)); hm->write(proto.get()); 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; BOOST_CHECK(*hm != hm2); } BOOST_AUTO_TEST_CASE(test_json_proto_6) { Doubles dub; dub.nan = HUGE_VAL / HUGE_VAL; dub.inf = HUGE_VAL; dub.neginf = -HUGE_VAL; dub.repeating = 10.0 / 3.0; dub.big = 1E+305; dub.tiny = 1E-305; dub.zero = 0.0; dub.negzero = -0.0; const std::string expected_result( "{\"1\":{\"dbl\":\"NaN\"},\"2\":{\"dbl\":\"Infinity\"},\"3\":{\"dbl\":\"-Infi" "nity\"},\"4\":{\"dbl\":3.3333333333333335},\"5\":{\"dbl\":9.9999999999999994e+" "304},\"6\":{\"dbl\":1e-305},\"7\":{\"dbl\":0},\"8\":{\"dbl\":-0}}" ); std::shared_ptr buffer(new TMemoryBuffer()); 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), "Expected:\n" << expected_result << "\nGotten:\n" << result_1); } BOOST_AUTO_TEST_CASE(test_json_proto_7) { std::shared_ptr buffer(new TMemoryBuffer()); std::shared_ptr proto(new TJSONProtocol(buffer)); Base64 base; base.a = 123; base.b1 = "1"; base.b2 = "12"; base.b3 = "123"; base.b4 = "1234"; base.b5 = "12345"; base.b6 = "123456"; base.write(proto.get()); Base64 base2; base2.read(proto.get()); BOOST_CHECK(base == base2); } BOOST_AUTO_TEST_CASE(test_json_proto_8) { const char* json_string = "{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127},\"4\":{\"i16\":27000}," "\"5\":{\"i32\":16.77216},\"6\":{\"i64\":6000000000},\"7\":{\"dbl\":3.1415926" "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]}}"; const std::size_t bufSiz = strlen(json_string) * sizeof(char); std::shared_ptr buffer(new TMemoryBuffer( (uint8_t*)(json_string), static_cast(bufSiz))); std::shared_ptr proto(new TJSONProtocol(buffer)); OneOfEach ooe2; BOOST_CHECK_THROW(ooe2.read(proto.get()), apache::thrift::protocol::TProtocolException); } static std::string toHexSequence(const std::string& str) { std::stringstream ss; ss << std::hex << std::setfill('0'); for (std::size_t i = 0; i < str.size(); i++) { ss << "\\x" << int(uint8_t(str[i])); } return ss.str(); } BOOST_AUTO_TEST_CASE(test_json_unicode_escaped) { const char json_string[] = "{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127},\"4\":{\"i16\":27000}," "\"5\":{\"i32\":16},\"6\":{\"i64\":6000000000},\"7\":{\"dbl\":3.1415926" "535897931},\"8\":{\"str\":\"JSON THIS!\"},\"9\":{\"str\":\"\\u0e01 \\ud835\\udd3e\"}," "\"10\":{\"tf\":0},\"11\":{\"str\":\"000000\"},\"12\":{\"lst\"" ":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64" "\",3,1,2,3]}}"; const char* expected_zomg_unicode = "\xe0\xb8\x81 \xf0\x9d\x94\xbe"; std::shared_ptr buffer(new TMemoryBuffer( (uint8_t*)(json_string), sizeof(json_string))); std::shared_ptr proto(new TJSONProtocol(buffer)); OneOfEach ooe2; ooe2.read(proto.get()); BOOST_CHECK_MESSAGE(!ooe2.zomg_unicode.compare(expected_zomg_unicode), "Expected:\n" << toHexSequence(expected_zomg_unicode) << "\nGotten:\n" << toHexSequence(ooe2.zomg_unicode)); } BOOST_AUTO_TEST_CASE(test_json_unicode_escaped_missing_low_surrogate) { const char json_string[] = "{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127},\"4\":{\"i16\":27000}," "\"5\":{\"i32\":16},\"6\":{\"i64\":6000000000},\"7\":{\"dbl\":3.1415926" "535897931},\"8\":{\"str\":\"JSON THIS!\"},\"9\":{\"str\":\"\\ud835\"}," "\"10\":{\"tf\":0},\"11\":{\"str\":\"000000\"},\"12\":{\"lst\"" ":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64" "\",3,1,2,3]}}"; std::shared_ptr buffer(new TMemoryBuffer( (uint8_t*)(json_string), sizeof(json_string))); std::shared_ptr proto(new TJSONProtocol(buffer)); OneOfEach ooe2; BOOST_CHECK_THROW(ooe2.read(proto.get()), apache::thrift::protocol::TProtocolException); } BOOST_AUTO_TEST_CASE(test_json_unicode_escaped_missing_hi_surrogate) { const char json_string[] = "{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127},\"4\":{\"i16\":27000}," "\"5\":{\"i32\":16},\"6\":{\"i64\":6000000000},\"7\":{\"dbl\":3.1415926" "535897931},\"8\":{\"str\":\"JSON THIS!\"},\"9\":{\"str\":\"\\udd3e\"}," "\"10\":{\"tf\":0},\"11\":{\"str\":\"000000\"},\"12\":{\"lst\"" ":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64" "\",3,1,2,3]}}"; std::shared_ptr buffer(new TMemoryBuffer( (uint8_t*)(json_string), sizeof(json_string))); std::shared_ptr proto(new TJSONProtocol(buffer)); OneOfEach ooe2; BOOST_CHECK_THROW(ooe2.read(proto.get()), apache::thrift::protocol::TProtocolException); } BOOST_AUTO_TEST_CASE(test_json_invalid_byte_range) { // Test case for byte values outside valid range const char json_string[] = "\"3\":{\"i8\":849}"; std::shared_ptr buffer(new TMemoryBuffer( (uint8_t*)(json_string), sizeof(json_string))); std::shared_ptr proto(new TJSONProtocol(buffer)); OneOfEach ooe2; BOOST_CHECK_THROW(ooe2.read(proto.get()), apache::thrift::protocol::TProtocolException); } BOOST_AUTO_TEST_CASE(test_json_base64_padding_validation) { auto test_base64_padding = [](const std::string& base64_value) { std::string json_string = "{\"11\":{\"str\":\"" + base64_value + "\"}}"; std::shared_ptr buffer(new TMemoryBuffer( (uint8_t*)(json_string.c_str()), static_cast(json_string.size()))); std::shared_ptr proto(new TJSONProtocol(buffer)); OneOfEach ooe; BOOST_CHECK_NO_THROW(ooe.read(proto.get())); }; // Valid base64 with 1 padding character test_base64_padding("QWE="); // Valid base64 with 2 padding characters test_base64_padding("QQ=="); // Just padding test_base64_padding("="); test_base64_padding("=="); // Malformed base64 with excessive padding (processed conservatively) test_base64_padding("==="); test_base64_padding("===="); } thrift-0.23.0/lib/cpp/test/Benchmark.cpp0000664000175000017500000001465515165535636020315 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifdef HAVE_CONFIG_H #include #endif #include #define _USE_MATH_DEFINES #include #include #include "thrift/protocol/TBinaryProtocol.h" #include "thrift/transport/TBufferTransports.h" #include "gen-cpp/DebugProtoTest_types.h" #ifdef HAVE_SYS_TIME_H #include #endif class Timer { public: timeval vStart; Timer() { THRIFT_GETTIMEOFDAY(&vStart, nullptr); } void start() { THRIFT_GETTIMEOFDAY(&vStart, nullptr); } double frame() { timeval vEnd; THRIFT_GETTIMEOFDAY(&vEnd, nullptr); double dstart = vStart.tv_sec + ((double)vStart.tv_usec / 1000000.0); double dend = vEnd.tv_sec + ((double)vEnd.tv_usec / 1000000.0); return dend - dstart; } }; int main() { using namespace thrift::test::debug; using namespace apache::thrift::transport; using namespace apache::thrift::protocol; using std::cout; OneOfEach ooe; ooe.im_true = true; ooe.im_false = false; ooe.a_bite = 0x7f; ooe.integer16 = 27000; ooe.integer32 = 1 << 24; ooe.integer64 = (uint64_t)6000 * 1000 * 1000; ooe.double_precision = M_PI; 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)); uint8_t* data = nullptr; uint32_t datasize = 0; { buf->resetBuffer(); TBinaryProtocolT prot(buf); double elapsed = 0.0; Timer timer; for (int i = 0; i < num; i++) { ooe.write(&prot); } elapsed = timer.frame(); cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } buf->getBuffer(&data, &datasize); { std::shared_ptr buf2(new TMemoryBuffer(data, datasize)); TBinaryProtocolT prot(buf2); OneOfEach ooe2; double elapsed = 0.0; Timer timer; for (int i = 0; i < num; i++) { ooe2.read(&prot); } elapsed = timer.frame(); cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { buf->resetBuffer(); TBinaryProtocolT prot(buf); double elapsed = 0.0; Timer timer; for (int i = 0; i < num; i++) { ooe.write(&prot); } elapsed = timer.frame(); cout << "Write little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { OneOfEach ooe2; std::shared_ptr buf2(new TMemoryBuffer(data, datasize)); TBinaryProtocolT prot(buf2); double elapsed = 0.0; Timer timer; for (int i = 0; i < num; i++) { ooe2.read(&prot); } elapsed = timer.frame(); cout << " Read little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { buf->resetBuffer(); TBinaryProtocolT prot(buf); double elapsed = 0.0; Timer timer; for (int i = 0; i < num; i++) { ooe.write(&prot); } elapsed = timer.frame(); cout << "Write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { std::shared_ptr buf2(new TMemoryBuffer(data, datasize)); TBinaryProtocolT prot(buf2); OneOfEach ooe2; double elapsed = 0.0; Timer timer; for (int i = 0; i < num; i++) { ooe2.read(&prot); } elapsed = timer.frame(); cout << " Read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } data = nullptr; datasize = 0; num = 10000000; ListDoublePerf listDoublePerf; listDoublePerf.field.reserve(num); for (int x = 0; x < num; ++x) listDoublePerf.field.push_back(double(x)); buf.reset(new TMemoryBuffer(num * 100)); { buf->resetBuffer(); TBinaryProtocolT prot(buf); double elapsed = 0.0; Timer timer; listDoublePerf.write(&prot); elapsed = timer.frame(); cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } buf->getBuffer(&data, &datasize); { std::shared_ptr buf2(new TMemoryBuffer(data, datasize)); TBinaryProtocolT prot(buf2); ListDoublePerf listDoublePerf2; double elapsed = 0.0; Timer timer; listDoublePerf2.read(&prot); elapsed = timer.frame(); cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { buf->resetBuffer(); TBinaryProtocolT prot(buf); double elapsed = 0.0; Timer timer; listDoublePerf.write(&prot); elapsed = timer.frame(); cout << "Double write little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { ListDoublePerf listDoublePerf2; std::shared_ptr buf2(new TMemoryBuffer(data, datasize)); TBinaryProtocolT prot(buf2); double elapsed = 0.0; Timer timer; listDoublePerf2.read(&prot); elapsed = timer.frame(); cout << " Double read little endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { buf->resetBuffer(); TBinaryProtocolT prot(buf); double elapsed = 0.0; Timer timer; listDoublePerf.write(&prot); elapsed = timer.frame(); cout << "Double write big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } { std::shared_ptr buf2(new TMemoryBuffer(data, datasize)); TBinaryProtocolT prot(buf2); ListDoublePerf listDoublePerf2; double elapsed = 0.0; Timer timer; listDoublePerf2.read(&prot); elapsed = timer.frame(); cout << " Double read big endian: " << num / (1000 * elapsed) << " kHz" << '\n'; } return 0; } thrift-0.23.0/lib/cpp/test/SpecializationTest.cpp0000664000175000017500000000605415165535636022233 0ustar00buildbuild00000000000000#define _USE_MATH_DEFINES #include #include #include #include using namespace thrift::test::debug; using namespace apache::thrift::transport; using namespace apache::thrift::protocol; #define BOOST_TEST_MODULE SpecializationTest #include typedef TBinaryProtocolT MyProtocol; // typedef TBinaryProtocolT MyProtocol; BOOST_AUTO_TEST_CASE(test_specialization_1) { OneOfEach ooe; ooe.im_true = true; ooe.im_false = false; ooe.a_bite = 0x7f; ooe.integer16 = 27000; ooe.integer32 = 1 << 24; ooe.integer64 = (uint64_t)6000 * 1000 * 1000; ooe.double_precision = M_PI; 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; n.my_ooe.integer16 = 16; n.my_ooe.integer32 = 32; n.my_ooe.integer64 = 64; n.my_ooe.double_precision = (std::sqrt(5.0) + 1) / 2; n.my_ooe.some_characters = ":R (me going \"rrrr\")"; n.my_ooe.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"; n.my_bonk.type = 31337; n.my_bonk.message = "I am a bonk... xor!"; HolyMoley hm; hm.big.push_back(ooe); hm.big.push_back(n.my_ooe); hm.big[0].a_bite = 0x22; hm.big[1].a_bite = 0x33; std::vector stage1; stage1.push_back("and a one"); stage1.push_back("and a two"); hm.contain.insert(stage1); stage1.clear(); stage1.push_back("then a one, two"); stage1.push_back("three!"); stage1.push_back("FOUR!!"); hm.contain.insert(stage1); stage1.clear(); hm.contain.insert(stage1); std::vector stage2; hm.bonks["nothing"] = stage2; stage2.resize(stage2.size() + 1); stage2.back().type = 1; stage2.back().message = "Wait."; stage2.resize(stage2.size() + 1); stage2.back().type = 2; stage2.back().message = "What?"; hm.bonks["something"] = stage2; stage2.clear(); stage2.resize(stage2.size() + 1); stage2.back().type = 3; stage2.back().message = "quoth"; stage2.resize(stage2.size() + 1); stage2.back().type = 4; stage2.back().message = "the raven"; stage2.resize(stage2.size() + 1); stage2.back().type = 5; stage2.back().message = "nevermore"; hm.bonks["poe"] = stage2; std::shared_ptr buffer(new TMemoryBuffer()); std::shared_ptr proto(new MyProtocol(buffer)); ooe.write(proto.get()); OneOfEach ooe2; ooe2.read(proto.get()); BOOST_TEST_INFO("Write: " << ooe); BOOST_TEST_INFO("Read : " << ooe2); BOOST_CHECK(ooe == ooe2); hm.write(proto.get()); HolyMoley hm2; hm2.read(proto.get()); BOOST_CHECK(hm == hm2); hm2.big[0].a_bite = 0x00; BOOST_CHECK(hm != hm2); } thrift-0.23.0/lib/cpp/test/TServerSocketTest.cpp0000664000175000017500000000452715165535636022023 0ustar00buildbuild00000000000000/* * 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 "TTransportCheckThrow.h" #include using apache::thrift::transport::TServerSocket; using apache::thrift::transport::TSocket; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using std::shared_ptr; BOOST_AUTO_TEST_SUITE(TServerSocketTest) BOOST_AUTO_TEST_CASE(test_bind_to_address) { TServerSocket sock1("localhost", 0); sock1.listen(); BOOST_CHECK(sock1.isOpen()); int port = sock1.getPort(); TSocket clientSock("localhost", port); clientSock.open(); shared_ptr accepted = sock1.accept(); accepted->close(); sock1.close(); 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(); } BOOST_AUTO_TEST_CASE(test_listen_invalid_port) { TServerSocket sock1(-1); TTRANSPORT_CHECK_THROW(sock1.listen(), TTransportException::BAD_ARGS); BOOST_CHECK(!sock1.isOpen()); TServerSocket sock2(65536); TTRANSPORT_CHECK_THROW(sock2.listen(), TTransportException::BAD_ARGS); BOOST_CHECK(!sock1.isOpen()); } BOOST_AUTO_TEST_CASE(test_close_before_listen) { TServerSocket sock1("localhost", 0); sock1.close(); BOOST_CHECK(!sock1.isOpen()); } BOOST_AUTO_TEST_CASE(test_get_port) { TServerSocket sock1("localHost", 888); BOOST_CHECK_EQUAL(888, sock1.getPort()); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/processor/0000775000175000017500000000000015170007202017676 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/test/processor/ServerThread.cpp0000664000175000017500000001135015165535636023025 0ustar00buildbuild00000000000000/* * 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_TEST_SERVERTHREAD_TCC_ #define _THRIFT_TEST_SERVERTHREAD_TCC_ 1 #include "ServerThread.h" #include #include #include #include #include namespace apache { namespace thrift { namespace test { void ServerThread::start() { assert(!running_); running_ = true; helper_.reset(new Helper(this)); // Start the other thread concurrency::ThreadFactory threadFactory; threadFactory.setDetached(false); thread_ = threadFactory.newThread(helper_); thread_->start(); // Wait on the other thread to tell us that it has successfully // bound to the port and started listening (or until an error occurs). concurrency::Synchronized s(serverMonitor_); while (!serving_ && !error_) { serverMonitor_.waitForever(); } if (error_) { throw transport::TTransportException(transport::TTransportException::NOT_OPEN, "failed to bind on server socket"); } } void ServerThread::stop() { if (!running_) { return; } // Tell the server to stop server_->stop(); running_ = false; // Wait for the server thread to exit // // Note: this only works if all client connections have closed. The servers // generally wait for everything to be closed before exiting; there currently // isn't a way to tell them to just exit now, and shut down existing // connections. thread_->join(); } void ServerThread::run() { /* * Try binding to several ports, in case the one we want is already in use. */ port_ = 12345; unsigned int maxRetries = 10; for (unsigned int n = 0; n < maxRetries; ++n) { // Create the server server_ = serverState_->createServer(port_); // Install our helper as the server event handler, so that our // preServe() method will be called once we've successfully bound to // the port and are about to start listening. server_->setServerEventHandler(helper_); try { // Try to serve requests server_->serve(); } catch (const TException&) { // TNonblockingServer throws a generic TException if it fails to bind. // If we get a TException, we'll optimistically assume the bind failed. ++port_; continue; } // Seriously? serve() is pretty lame. If it fails to start serving it // just returns rather than throwing an exception. // // We have to use our preServe() hook to tell if serve() successfully // started serving and is returning because stop() is called, or if it just // failed to start serving in the first place. concurrency::Synchronized s(serverMonitor_); if (serving_) { // Oh good, we started serving and are exiting because // we're trying to stop. serving_ = false; return; } else { // We never started serving, probably because we failed to bind to the // port. Increment the port number and try again. ++port_; continue; } } // We failed to bind on any port. concurrency::Synchronized s(serverMonitor_); error_ = true; serverMonitor_.notify(); } void ServerThread::preServe() { // We bound to the port successfully, and are about to start serving requests serverState_->bindSuccessful(port_); // Set the real server event handler (replacing ourself) std::shared_ptr serverEventHandler = serverState_->getServerEventHandler(); server_->setServerEventHandler(serverEventHandler); // Notify the main thread that we have successfully started serving requests concurrency::Synchronized s(serverMonitor_); serving_ = true; serverMonitor_.notify(); // Invoke preServe() on the real event handler, since we ate // the original preServe() event. if (serverEventHandler) { serverEventHandler->preServe(); } } } } } // apache::thrift::test #endif // _THRIFT_TEST_SERVERTHREAD_TCC_ thrift-0.23.0/lib/cpp/test/processor/ProcessorTest.cpp0000664000175000017500000010322115165535636023245 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * This file contains tests that ensure TProcessorEventHandler and * TServerEventHandler are invoked properly by the various server * implementations. */ #include #include #include #include #include #include #include #include #include #include #include "EventLog.h" #include "ServerThread.h" #include "Handlers.h" #include "gen-cpp/ChildService.h" using namespace apache::thrift; using namespace apache::thrift::concurrency; using namespace apache::thrift::protocol; using namespace apache::thrift::server; using namespace apache::thrift::test; using namespace apache::thrift::transport; using std::string; using std::vector; /* * Traits classes that encapsulate how to create various types of servers. */ class TSimpleServerTraits { public: typedef TSimpleServer ServerType; std::shared_ptr createServer( const std::shared_ptr& processor, uint16_t port, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory) { std::shared_ptr socket(new TServerSocket(port)); return std::shared_ptr( new TSimpleServer(processor, socket, transportFactory, protocolFactory)); } }; class TThreadedServerTraits { public: typedef TThreadedServer ServerType; std::shared_ptr createServer( const std::shared_ptr& processor, uint16_t port, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory) { std::shared_ptr socket(new TServerSocket(port)); return std::shared_ptr( new TThreadedServer(processor, socket, transportFactory, protocolFactory)); } }; class TThreadPoolServerTraits { public: typedef TThreadPoolServer ServerType; std::shared_ptr createServer( const std::shared_ptr& processor, uint16_t port, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory) { std::shared_ptr socket(new TServerSocket(port)); std::shared_ptr threadFactory(new ThreadFactory); std::shared_ptr threadManager = ThreadManager::newSimpleThreadManager(8); threadManager->threadFactory(threadFactory); threadManager->start(); return std::shared_ptr( new TThreadPoolServer(processor, socket, transportFactory, protocolFactory, threadManager)); } }; class TNonblockingServerTraits { public: typedef TNonblockingServer ServerType; std::shared_ptr createServer( const std::shared_ptr& processor, uint16_t port, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory) { // TNonblockingServer automatically uses TFramedTransport. // Raise an exception if the supplied transport factory is not a // TFramedTransportFactory auto* framedFactory = dynamic_cast(transportFactory.get()); if (framedFactory == nullptr) { throw TException("TNonblockingServer must use TFramedTransport"); } std::shared_ptr socket(new TNonblockingServerSocket(port)); std::shared_ptr threadFactory(new ThreadFactory); std::shared_ptr threadManager = ThreadManager::newSimpleThreadManager(8); threadManager->threadFactory(threadFactory); threadManager->start(); return std::shared_ptr( new TNonblockingServer(processor, protocolFactory, socket, threadManager)); } }; class TNonblockingServerNoThreadsTraits { public: typedef TNonblockingServer ServerType; std::shared_ptr createServer( const std::shared_ptr& processor, uint16_t port, const std::shared_ptr& transportFactory, const std::shared_ptr& protocolFactory) { // TNonblockingServer automatically uses TFramedTransport. // Raise an exception if the supplied transport factory is not a // TFramedTransportFactory auto* framedFactory = dynamic_cast(transportFactory.get()); if (framedFactory == nullptr) { throw TException("TNonblockingServer must use TFramedTransport"); } std::shared_ptr socket(new TNonblockingServerSocket(port)); // Use a NULL ThreadManager std::shared_ptr threadManager; return std::shared_ptr( new TNonblockingServer(processor, protocolFactory, socket, threadManager)); } }; /* * Traits classes for controlling if we instantiate templated or generic * protocol factories, processors, clients, etc. * * The goal is to allow the outer test code to select which server type is * being tested, and whether or not we are testing the templated classes, or * the generic classes. * * Each specific test case can control whether we create a child or parent * server, and whether we use TFramedTransport or TBufferedTransport. */ class UntemplatedTraits { public: typedef TBinaryProtocolFactory ProtocolFactory; typedef TBinaryProtocol Protocol; typedef ParentServiceProcessor ParentProcessor; typedef ChildServiceProcessor ChildProcessor; typedef ParentServiceClient ParentClient; typedef ChildServiceClient ChildClient; }; class TemplatedTraits { public: typedef TBinaryProtocolFactoryT ProtocolFactory; typedef TBinaryProtocolT Protocol; typedef ParentServiceProcessorT ParentProcessor; typedef ChildServiceProcessorT ChildProcessor; typedef ParentServiceClientT ParentClient; typedef ChildServiceClientT ChildClient; }; template class ParentServiceTraits { public: typedef typename TemplateTraits_::ParentProcessor Processor; typedef typename TemplateTraits_::ParentClient Client; typedef ParentHandler Handler; typedef typename TemplateTraits_::ProtocolFactory ProtocolFactory; typedef typename TemplateTraits_::Protocol Protocol; }; template class ChildServiceTraits { public: typedef typename TemplateTraits_::ChildProcessor Processor; typedef typename TemplateTraits_::ChildClient Client; typedef ChildHandler Handler; typedef typename TemplateTraits_::ProtocolFactory ProtocolFactory; typedef typename TemplateTraits_::Protocol Protocol; }; // TODO: It would be nicer if the TTransportFactory types defined a typedef, // to allow us to figure out the exact transport type without having to pass it // in as a separate template parameter here. // // It would also be niec if they used covariant return types. Unfortunately, // since they return shared_ptr instead of raw pointers, covariant return types // won't work. template class ServiceState : public ServerState { public: typedef typename ServiceTraits_::Processor Processor; typedef typename ServiceTraits_::Client Client; typedef typename ServiceTraits_::Handler Handler; ServiceState() : port_(0), log_(new EventLog), handler_(new Handler(log_)), processor_(new Processor(handler_)), transportFactory_(new TransportFactory_), protocolFactory_(new typename ServiceTraits_::ProtocolFactory), serverEventHandler_(new ServerEventHandler(log_)), processorEventHandler_(new ProcessorEventHandler(log_)) { processor_->setEventHandler(processorEventHandler_); } std::shared_ptr createServer(uint16_t port) override { ServerTraits_ serverTraits; return serverTraits.createServer(processor_, port, transportFactory_, protocolFactory_); } std::shared_ptr getServerEventHandler() override { return serverEventHandler_; } void bindSuccessful(uint16_t port) override { port_ = port; } uint16_t getPort() const { return port_; } const std::shared_ptr& getLog() const { return log_; } const std::shared_ptr& getHandler() const { return handler_; } std::shared_ptr createClient() { typedef typename ServiceTraits_::Protocol Protocol; std::shared_ptr socket(new TSocket("127.0.0.1", port_)); std::shared_ptr transport(new Transport_(socket)); std::shared_ptr protocol(new Protocol(transport)); transport->open(); std::shared_ptr client(new Client(protocol)); return client; } private: uint16_t port_; std::shared_ptr log_; std::shared_ptr handler_; std::shared_ptr processor_; std::shared_ptr transportFactory_; std::shared_ptr protocolFactory_; std::shared_ptr serverEventHandler_; std::shared_ptr processorEventHandler_; }; /** * Check that there are no more events in the log */ void checkNoEvents(const std::shared_ptr& log) { // Wait for an event with a very short timeout period. We don't expect // anything to be present, so we will normally wait for the full timeout. // On the other hand, a non-zero timeout is nice since it does give a short // window for events to arrive in case there is a problem. Event event = log->waitForEvent(10); BOOST_CHECK_EQUAL(EventLog::ET_LOG_END, event.type); } /** * Check for the events that should be logged when a new connection is created. * * Returns the connection ID allocated by the server. */ uint32_t checkNewConnEvents(const std::shared_ptr& log) { // Check for an ET_CONN_CREATED event Event event = log->waitForEvent(2500); BOOST_CHECK_EQUAL(EventLog::ET_CONN_CREATED, event.type); // Some servers call the processContext() hook immediately. // Others (TNonblockingServer) only call it once a full request is received. // We don't check for it yet, to allow either behavior. return event.connectionId; } /** * Check for the events that should be logged when a connection is closed. */ void checkCloseEvents(const std::shared_ptr& log, uint32_t connId) { // Check for an ET_CONN_DESTROYED event Event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CONN_DESTROYED, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); // Make sure there are no more events checkNoEvents(log); } /** * Check for the events that should be logged when a call is received * and the handler is invoked. * * It does not check for anything after the handler invocation. * * Returns the call ID allocated by the server. */ uint32_t checkCallHandlerEvents(const std::shared_ptr& log, uint32_t connId, EventType callType, const string& callName) { // Call started Event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CALL_STARTED, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callName, event.message); uint32_t callId = event.callId; // Pre-read event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_PRE_READ, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // Post-read event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_POST_READ, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // Handler invocation event = log->waitForEvent(); BOOST_CHECK_EQUAL(callType, event.type); // The handler doesn't have any connection or call context, // so the connectionId and callId in this event aren't valid return callId; } /** * Check for the events that should be after a handler returns. */ void checkCallPostHandlerEvents(const std::shared_ptr& log, uint32_t connId, uint32_t callId, const string& callName) { // Pre-write Event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_PRE_WRITE, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // Post-write event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_POST_WRITE, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // Call finished event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CALL_FINISHED, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // It is acceptable for servers to call processContext() again immediately // to start waiting on the next request. However, some servers wait before // getting either a partial request or the full request before calling // processContext(). We don't check for the next call to processContext() // yet. } /** * Check for the events that should be logged when a call is made. * * This just calls checkCallHandlerEvents() followed by * checkCallPostHandlerEvents(). * * Returns the call ID allocated by the server. */ uint32_t checkCallEvents(const std::shared_ptr& log, uint32_t connId, EventType callType, const string& callName) { uint32_t callId = checkCallHandlerEvents(log, connId, callType, callName); checkCallPostHandlerEvents(log, connId, callId, callName); return callId; } /* * Test functions */ template void testParentService(const std::shared_ptr& state) { std::shared_ptr client = state->createClient(); int32_t gen = client->getGeneration(); int32_t newGen = client->incrementGeneration(); BOOST_CHECK_EQUAL(gen + 1, newGen); newGen = client->getGeneration(); BOOST_CHECK_EQUAL(gen + 1, newGen); client->addString("foo"); client->addString("bar"); client->addString("asdf"); vector strings; client->getStrings(strings); BOOST_REQUIRE_EQUAL(3, strings.size()); BOOST_REQUIRE_EQUAL("foo", strings[0]); BOOST_REQUIRE_EQUAL("bar", strings[1]); BOOST_REQUIRE_EQUAL("asdf", strings[2]); } template void testChildService(const std::shared_ptr& state) { std::shared_ptr client = state->createClient(); // Test calling some of the parent methids via the a child client int32_t gen = client->getGeneration(); int32_t newGen = client->incrementGeneration(); BOOST_CHECK_EQUAL(gen + 1, newGen); newGen = client->getGeneration(); BOOST_CHECK_EQUAL(gen + 1, newGen); // Test some of the child methods client->setValue(10); BOOST_CHECK_EQUAL(10, client->getValue()); BOOST_CHECK_EQUAL(10, client->setValue(99)); BOOST_CHECK_EQUAL(99, client->getValue()); } template void testBasicService() { typedef ServiceState > State; // Start the server std::shared_ptr state(new State); ServerThread serverThread(state, true); testParentService(state); } template void testInheritedService() { typedef ServiceState > State; // Start the server std::shared_ptr state(new State); ServerThread serverThread(state, true); testParentService(state); testChildService(state); } /** * Test to make sure that the TServerEventHandler and TProcessorEventHandler * methods are invoked in the correct order with the actual events. */ template void testEventSequencing() { // We use TBufferedTransport for this test, instead of TFramedTransport. // This way the server will start processing data as soon as it is received, // instead of waiting for the full request. This is necessary so we can // separate the preRead() and postRead() events. typedef ServiceState, TBufferedTransportFactory, TBufferedTransport> State; // Start the server std::shared_ptr state(new State); ServerThread serverThread(state, true); const std::shared_ptr& log = state->getLog(); // Make sure we're at the end of the log checkNoEvents(log); state->getHandler()->prepareTriggeredCall(); // Make sure createContext() is called after a connection has been // established. We open a plain socket instead of creating a client. std::shared_ptr socket(new TSocket("127.0.0.1", state->getPort())); socket->open(); // Make sure the proper events occurred after a new connection uint32_t connId = checkNewConnEvents(log); // Send a message header. We manually construct the request so that we // can test the timing for the preRead() call. string requestName = "getDataWait"; string eventName = "ParentService.getDataWait"; auto seqid = int32_t(time(nullptr)); TBinaryProtocol protocol(socket); protocol.writeMessageBegin(requestName, T_CALL, seqid); socket->flush(); // Make sure we saw the call started and pre-read events Event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CALL_STARTED, event.type); BOOST_CHECK_EQUAL(eventName, event.message); BOOST_CHECK_EQUAL(connId, event.connectionId); uint32_t callId = event.callId; event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_PRE_READ, event.type); BOOST_CHECK_EQUAL(eventName, event.message); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); // Make sure there are no new events checkNoEvents(log); // Send the rest of the request protocol.writeStructBegin("ParentService_getDataNotified_pargs"); protocol.writeFieldBegin("length", apache::thrift::protocol::T_I32, 1); protocol.writeI32(8 * 1024 * 1024); protocol.writeFieldEnd(); protocol.writeFieldStop(); protocol.writeStructEnd(); protocol.writeMessageEnd(); socket->writeEnd(); socket->flush(); // We should then see postRead() event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_POST_READ, event.type); BOOST_CHECK_EQUAL(eventName, event.message); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); // Then the handler should be invoked event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CALL_GET_DATA_WAIT, event.type); // The handler won't respond until we notify it. // Make sure there are no more events. checkNoEvents(log); // Notify the handler that it should return // We just use a global lock for now, since it is easiest state->getHandler()->triggerPendingCalls(); // The handler will log a separate event before it returns event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_WAIT_RETURN, event.type); // We should then see preWrite() event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_PRE_WRITE, event.type); BOOST_CHECK_EQUAL(eventName, event.message); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); // We requested more data than can be buffered, and we aren't reading it, // so the server shouldn't be able to finish its write yet. // Make sure there are no more events. checkNoEvents(log); // Read the response header string responseName; int32_t responseSeqid = 0; apache::thrift::protocol::TMessageType responseType; protocol.readMessageBegin(responseName, responseType, responseSeqid); BOOST_CHECK_EQUAL(responseSeqid, seqid); BOOST_CHECK_EQUAL(requestName, responseName); BOOST_CHECK_EQUAL(responseType, T_REPLY); // Read the body. We just ignore it for now. protocol.skip(T_STRUCT); // Now that we have read, the server should have finished sending the data // and called the postWrite() handler event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_POST_WRITE, event.type); BOOST_CHECK_EQUAL(eventName, event.message); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); // Call finished should be last event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CALL_FINISHED, event.type); BOOST_CHECK_EQUAL(eventName, event.message); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); // There should be no more events checkNoEvents(log); // Close the connection, and make sure we get a connection destroyed event socket->close(); event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CONN_DESTROYED, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); // There should be no more events checkNoEvents(log); } template void testSeparateConnections() { typedef ServiceState > State; // Start the server std::shared_ptr state(new State); ServerThread serverThread(state, true); const std::shared_ptr& log = state->getLog(); // Create a client std::shared_ptr client1 = state->createClient(); // Make sure the expected events were logged uint32_t client1Id = checkNewConnEvents(log); // Create a second client std::shared_ptr client2 = state->createClient(); // Make sure the expected events were logged uint32_t client2Id = checkNewConnEvents(log); // The two connections should have different IDs BOOST_CHECK_NE(client1Id, client2Id); // Make a call, and check for the proper events int32_t value = 5; client1->setValue(value); uint32_t call1 = checkCallEvents(log, client1Id, EventLog::ET_CALL_SET_VALUE, "ChildService.setValue"); // Make a call with client2 int32_t v = client2->getValue(); BOOST_CHECK_EQUAL(value, v); checkCallEvents(log, client2Id, EventLog::ET_CALL_GET_VALUE, "ChildService.getValue"); // Make another call with client1 v = client1->getValue(); BOOST_CHECK_EQUAL(value, v); uint32_t call2 = checkCallEvents(log, client1Id, EventLog::ET_CALL_GET_VALUE, "ChildService.getValue"); BOOST_CHECK_NE(call1, call2); // Close the second client, and check for the appropriate events client2.reset(); checkCloseEvents(log, client2Id); } template void testOnewayCall() { typedef ServiceState > State; // Start the server std::shared_ptr state(new State); ServerThread serverThread(state, true); const std::shared_ptr& log = state->getLog(); // Create a client std::shared_ptr client = state->createClient(); uint32_t connId = checkNewConnEvents(log); // Make a oneway call // It should return immediately, even though the server's handler // won't return right away state->getHandler()->prepareTriggeredCall(); client->onewayWait(); string callName = "ParentService.onewayWait"; uint32_t callId = checkCallHandlerEvents(log, connId, EventLog::ET_CALL_ONEWAY_WAIT, callName); // There shouldn't be any more events checkNoEvents(log); // Trigger the handler to return state->getHandler()->triggerPendingCalls(); // The handler will log an ET_WAIT_RETURN event when it wakes up Event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_WAIT_RETURN, event.type); // Now we should see the async complete event, then call finished event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_ASYNC_COMPLETE, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CALL_FINISHED, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // Destroy the client, and check for connection closed events client.reset(); checkCloseEvents(log, connId); checkNoEvents(log); } template void testExpectedError() { typedef ServiceState > State; // Start the server std::shared_ptr state(new State); ServerThread serverThread(state, true); const std::shared_ptr& log = state->getLog(); // Create a client std::shared_ptr client = state->createClient(); uint32_t connId = checkNewConnEvents(log); // Send the exceptionWait() call state->getHandler()->prepareTriggeredCall(); string message = "test 1234 test"; client->send_exceptionWait(message); string callName = "ParentService.exceptionWait"; uint32_t callId = checkCallHandlerEvents(log, connId, EventLog::ET_CALL_EXCEPTION_WAIT, callName); // There shouldn't be any more events checkNoEvents(log); // Trigger the handler to return state->getHandler()->triggerPendingCalls(); // The handler will log an ET_WAIT_RETURN event when it wakes up Event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_WAIT_RETURN, event.type); // Now receive the response try { client->recv_exceptionWait(); BOOST_FAIL("expected MyError to be thrown"); } catch (const MyError& e) { BOOST_CHECK_EQUAL(message, e.message); // Check if std::exception::what() is handled properly size_t message_pos = string(e.what()).find("TException - service has thrown: MyError"); BOOST_CHECK_NE(message_pos, string::npos); } // Now we should see the events for a normal call finish checkCallPostHandlerEvents(log, connId, callId, callName); // There shouldn't be any more events checkNoEvents(log); // Destroy the client, and check for connection closed events client.reset(); checkCloseEvents(log, connId); checkNoEvents(log); } template void testUnexpectedError() { typedef ServiceState > State; // Start the server std::shared_ptr state(new State); ServerThread serverThread(state, true); const std::shared_ptr& log = state->getLog(); // Create a client std::shared_ptr client = state->createClient(); uint32_t connId = checkNewConnEvents(log); // Send the unexpectedExceptionWait() call state->getHandler()->prepareTriggeredCall(); string message = "1234 test 5678"; client->send_unexpectedExceptionWait(message); string callName = "ParentService.unexpectedExceptionWait"; uint32_t callId = checkCallHandlerEvents(log, connId, EventLog::ET_CALL_UNEXPECTED_EXCEPTION_WAIT, callName); // There shouldn't be any more events checkNoEvents(log); // Trigger the handler to return state->getHandler()->triggerPendingCalls(); // The handler will log an ET_WAIT_RETURN event when it wakes up Event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_WAIT_RETURN, event.type); // Now receive the response try { client->recv_unexpectedExceptionWait(); BOOST_FAIL("expected TApplicationError to be thrown"); } catch (const TApplicationException&) { } // Now we should see a handler error event event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_HANDLER_ERROR, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // pre-write and post-write events aren't generated after a handler error // (Even for non-oneway calls where a response is written.) // // A call finished event is logged when the call context is destroyed event = log->waitForEvent(); BOOST_CHECK_EQUAL(EventLog::ET_CALL_FINISHED, event.type); BOOST_CHECK_EQUAL(connId, event.connectionId); BOOST_CHECK_EQUAL(callId, event.callId); BOOST_CHECK_EQUAL(callName, event.message); // There shouldn't be any more events checkNoEvents(log); // Destroy the client, and check for connection closed events client.reset(); checkCloseEvents(log, connId); checkNoEvents(log); } // Macro to define simple tests that can be used with all server types #define DEFINE_SIMPLE_TESTS(Server, Template) \ BOOST_AUTO_TEST_CASE(Server##_##Template##_basicService) { \ testBasicService(); \ } \ BOOST_AUTO_TEST_CASE(Server##_##Template##_inheritedService) { \ testInheritedService(); \ } \ BOOST_AUTO_TEST_CASE(Server##_##Template##_oneway) { \ testOnewayCall(); \ } \ BOOST_AUTO_TEST_CASE(Server##_##Template##_exception) { \ testExpectedError(); \ } \ BOOST_AUTO_TEST_CASE(Server##_##Template##_unexpectedException) { \ testUnexpectedError(); \ } // Tests that require the server to process multiple connections concurrently // (i.e., not TSimpleServer) #define DEFINE_CONCURRENT_SERVER_TESTS(Server, Template) \ BOOST_AUTO_TEST_CASE(Server##_##Template##_separateConnections) { \ testSeparateConnections(); \ } // The testEventSequencing() test manually generates a request for the server, // and doesn't work with TFramedTransport. Therefore we can't test it with // TNonblockingServer. #define DEFINE_NOFRAME_TESTS(Server, Template) \ BOOST_AUTO_TEST_CASE(Server##_##Template##_eventSequencing) { \ testEventSequencing(); \ } #define DEFINE_TNONBLOCKINGSERVER_TESTS(Server, Template) \ DEFINE_SIMPLE_TESTS(Server, Template) \ DEFINE_CONCURRENT_SERVER_TESTS(Server, Template) #define DEFINE_ALL_SERVER_TESTS(Server, Template) \ DEFINE_SIMPLE_TESTS(Server, Template) \ DEFINE_CONCURRENT_SERVER_TESTS(Server, Template) \ DEFINE_NOFRAME_TESTS(Server, Template) DEFINE_ALL_SERVER_TESTS(TThreadedServer, Templated) DEFINE_ALL_SERVER_TESTS(TThreadedServer, Untemplated) DEFINE_ALL_SERVER_TESTS(TThreadPoolServer, Templated) DEFINE_ALL_SERVER_TESTS(TThreadPoolServer, Untemplated) DEFINE_TNONBLOCKINGSERVER_TESTS(TNonblockingServer, Templated) DEFINE_TNONBLOCKINGSERVER_TESTS(TNonblockingServer, Untemplated) DEFINE_TNONBLOCKINGSERVER_TESTS(TNonblockingServerNoThreads, Templated) DEFINE_TNONBLOCKINGSERVER_TESTS(TNonblockingServerNoThreads, Untemplated) DEFINE_SIMPLE_TESTS(TSimpleServer, Templated) DEFINE_SIMPLE_TESTS(TSimpleServer, Untemplated) DEFINE_NOFRAME_TESTS(TSimpleServer, Templated) DEFINE_NOFRAME_TESTS(TSimpleServer, Untemplated) // TODO: We should test TEventServer in the future. // For now, it is known not to work correctly with TProcessorEventHandler. #ifdef BOOST_TEST_DYN_LINK bool init_unit_test_suite() { ::boost::unit_test::framework::master_test_suite().p_name.value = "ProcessorTest"; return true; } int main( int argc, char* argv[] ) { return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv); } #else ::boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { THRIFT_UNUSED_VARIABLE(argc); THRIFT_UNUSED_VARIABLE(argv); ::boost::unit_test::framework::master_test_suite().p_name.value = "ProcessorTest"; return nullptr; } #endif thrift-0.23.0/lib/cpp/test/processor/EventLog.h0000664000175000017500000000567215165535636021631 0ustar00buildbuild00000000000000/* * 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_TEST_EVENTLOG_H_ #define _THRIFT_TEST_EVENTLOG_H_ 1 #include namespace apache { namespace thrift { namespace test { // Initially I made EventType an enum, but using char* results // in much more readable error messages when there is a mismatch. // It also lets users of EventLog easily define their own new types. // Comparing the literal pointer values should be safe, barring any strange // linking setup that results in duplicate symbols. typedef const char* EventType; struct Event { Event(EventType type, uint32_t connectionId, uint32_t callId, const std::string& message) : type(type), connectionId(connectionId), callId(callId), message(message) {} EventType type; uint32_t connectionId; uint32_t callId; std::string message; }; class EventLog { public: static EventType ET_LOG_END; static EventType ET_CONN_CREATED; static EventType ET_CONN_DESTROYED; static EventType ET_CALL_STARTED; static EventType ET_CALL_FINISHED; static EventType ET_PROCESS; static EventType ET_PRE_READ; static EventType ET_POST_READ; static EventType ET_PRE_WRITE; static EventType ET_POST_WRITE; static EventType ET_ASYNC_COMPLETE; static EventType ET_HANDLER_ERROR; static EventType ET_CALL_INCREMENT_GENERATION; static EventType ET_CALL_GET_GENERATION; static EventType ET_CALL_ADD_STRING; static EventType ET_CALL_GET_STRINGS; static EventType ET_CALL_GET_DATA_WAIT; static EventType ET_CALL_ONEWAY_WAIT; static EventType ET_CALL_UNEXPECTED_EXCEPTION_WAIT; static EventType ET_CALL_EXCEPTION_WAIT; static EventType ET_WAIT_RETURN; static EventType ET_CALL_SET_VALUE; static EventType ET_CALL_GET_VALUE; EventLog(); void append(EventType type, uint32_t connectionId, uint32_t callId, const std::string& message = ""); Event waitForEvent(int64_t timeout = 500); Event waitForConnEvent(uint32_t connId, int64_t timeout = 500); protected: typedef std::list EventList; concurrency::Monitor monitor_; EventList events_; uint32_t id_; static uint32_t nextId_; }; } } } // apache::thrift::test #endif // _THRIFT_TEST_EVENTLOG_H_ thrift-0.23.0/lib/cpp/test/processor/ServerThread.h0000664000175000017500000000732015167543515022471 0ustar00buildbuild00000000000000/* * 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_TEST_SERVERTHREAD_H_ #define _THRIFT_TEST_SERVERTHREAD_H_ 1 #include #include #include #include #include "EventLog.h" namespace apache { namespace thrift { namespace test { /** * A helper class to tell ServerThread how to create the server */ class ServerState { public: virtual ~ServerState() = default; /** * Create a server to listen on the specified port. * * If the server returned fails to bind to the specified port when serve() is * called on it, createServer() may be called again on a different port. */ virtual std::shared_ptr createServer(uint16_t port) = 0; /** * Get the TServerEventHandler to set on the server. * * This is only called after the server successfully binds and is about to * start serving traffic. It is invoked from the server thread, rather than * the main thread. */ virtual std::shared_ptr getServerEventHandler() { return std::shared_ptr(); } /** * This method is called in the server thread after server binding succeeds. * * Subclasses may override this method if they wish to record the final * port that was used for the server. */ virtual void bindSuccessful(uint16_t /*port*/) {} }; /** * ServerThread starts a thrift server running in a separate thread. */ class ServerThread { public: ServerThread(const std::shared_ptr& state, bool autoStart) : port_(0), running_(false), serving_(false), error_(false), serverState_(state) { if (autoStart) { start(); } } void start(); void stop(); uint16_t getPort() const { return port_; } ~ServerThread() { if (running_) { try { stop(); } catch (...) { TOutput::instance().printf("error shutting down server"); } } } protected: // Annoying. thrift forces us to use shared_ptr, so we have to use // a helper class that we can allocate on the heap and give to thrift. // It would be simpler if we could just make Runnable and TServerEventHandler // private base classes of ServerThread. class Helper : public concurrency::Runnable, public server::TServerEventHandler { public: Helper(ServerThread* serverThread) : serverThread_(serverThread) {} void run() override { serverThread_->run(); } void preServe() override { serverThread_->preServe(); } private: ServerThread* serverThread_; }; void run(); void preServe(); std::shared_ptr helper_; uint16_t port_; bool running_; bool serving_; bool error_; concurrency::Monitor serverMonitor_; std::shared_ptr serverState_; std::shared_ptr server_; std::shared_ptr thread_; }; } } } // apache::thrift::test #endif // _THRIFT_TEST_SERVERTHREAD_H_ thrift-0.23.0/lib/cpp/test/processor/proc.thrift0000664000175000017500000000241215165535636022107 0ustar00buildbuild00000000000000/* * 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 apache.thrift.test exception MyError { 1: string message } service ParentService { i32 incrementGeneration() i32 getGeneration() void addString(1: string s) list getStrings() binary getDataWait(1: i32 length) oneway void onewayWait() void exceptionWait(1: string message) throws (2: MyError error) void unexpectedExceptionWait(1: string message) } service ChildService extends ParentService { i32 setValue(1: i32 value) i32 getValue() } thrift-0.23.0/lib/cpp/test/processor/Handlers.h0000664000175000017500000002374415165535636021646 0ustar00buildbuild00000000000000/* * 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_PROCESSOR_TEST_HANDLERS_H_ #define _THRIFT_PROCESSOR_TEST_HANDLERS_H_ 1 #include "EventLog.h" #include "gen-cpp/ParentService.h" #include "gen-cpp/ChildService.h" namespace apache { namespace thrift { namespace test { class ParentHandler : virtual public ParentServiceIf { public: ParentHandler(const std::shared_ptr& log) : triggerMonitor(&mutex_), generation_(0), wait_(false), log_(log) {} int32_t incrementGeneration() override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_INCREMENT_GENERATION, 0, 0); return ++generation_; } int32_t getGeneration() override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_GET_GENERATION, 0, 0); return generation_; } void addString(const std::string& s) override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_ADD_STRING, 0, 0); strings_.push_back(s); } void getStrings(std::vector& _return) override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_GET_STRINGS, 0, 0); _return = strings_; } void getDataWait(std::string& _return, const int32_t length) override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_GET_DATA_WAIT, 0, 0); blockUntilTriggered(); _return.append(length, 'a'); } void onewayWait() override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_ONEWAY_WAIT, 0, 0); blockUntilTriggered(); } void exceptionWait(const std::string& message) override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_EXCEPTION_WAIT, 0, 0); blockUntilTriggered(); MyError e; e.message = message; throw e; } void unexpectedExceptionWait(const std::string& message) override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_UNEXPECTED_EXCEPTION_WAIT, 0, 0); blockUntilTriggered(); MyError e; e.message = message; throw e; } /** * After prepareTriggeredCall() is invoked, calls to any of the *Wait() * functions won't return until triggerPendingCalls() is invoked * * This has to be a separate function invoked by the main test thread * in order to to avoid race conditions. */ void prepareTriggeredCall() { concurrency::Guard g(mutex_); wait_ = true; } /** * Wake up all calls waiting in blockUntilTriggered() */ void triggerPendingCalls() { concurrency::Guard g(mutex_); wait_ = false; triggerMonitor.notifyAll(); } protected: /** * blockUntilTriggered() won't return until triggerPendingCalls() is invoked * in another thread. * * This should only be called when already holding mutex_. */ void blockUntilTriggered() { while (wait_) { triggerMonitor.waitForever(); } // Log an event when we return log_->append(EventLog::ET_WAIT_RETURN, 0, 0); } concurrency::Mutex mutex_; concurrency::Monitor triggerMonitor; int32_t generation_; bool wait_; std::vector strings_; std::shared_ptr log_; }; #ifdef _MSC_VER #pragma warning( push ) #pragma warning (disable : 4250 ) //inheriting methods via dominance #endif class ChildHandler : public ParentHandler, virtual public ChildServiceIf { public: ChildHandler(const std::shared_ptr& log) : ParentHandler(log), value_(0) {} int32_t setValue(const int32_t value) override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_SET_VALUE, 0, 0); int32_t oldValue = value_; value_ = value; return oldValue; } int32_t getValue() override { concurrency::Guard g(mutex_); log_->append(EventLog::ET_CALL_GET_VALUE, 0, 0); return value_; } protected: int32_t value_; }; #ifdef _MSC_VER #pragma warning( pop ) #endif struct ConnContext { public: ConnContext(std::shared_ptr in, std::shared_ptr out, uint32_t id) : input(in), output(out), id(id) {} std::shared_ptr input; std::shared_ptr output; uint32_t id; }; struct CallContext { public: CallContext(ConnContext* context, uint32_t id, const std::string& name) : connContext(context), name(name), id(id) {} ConnContext* connContext; std::string name; uint32_t id; }; class ServerEventHandler : public server::TServerEventHandler { public: ServerEventHandler(const std::shared_ptr& log) : nextId_(1), log_(log) {} void preServe() override {} void* createContext(std::shared_ptr input, std::shared_ptr output) override { ConnContext* context = new ConnContext(input, output, nextId_); ++nextId_; log_->append(EventLog::ET_CONN_CREATED, context->id, 0); return context; } void deleteContext(void* serverContext, std::shared_ptr input, std::shared_ptr output) override { auto* context = reinterpret_cast(serverContext); if (input != context->input) { abort(); } if (output != context->output) { abort(); } log_->append(EventLog::ET_CONN_DESTROYED, context->id, 0); delete context; } void processContext(void* serverContext, std::shared_ptr transport) override { // TODO: We currently don't test the behavior of the processContext() // calls. The various server implementations call processContext() at // slightly different times, and it is too annoying to try and account for // their various differences. // // TThreadedServer, TThreadPoolServer, and TSimpleServer usually wait until // they see the first byte of a request before calling processContext(). // However, they don't wait for the first byte of the very first request, // and instead immediately call processContext() before any data is // received. // // TNonblockingServer always waits until receiving the full request before // calling processContext(). #if 0 ConnContext* context = reinterpret_cast(serverContext); log_->append(EventLog::ET_PROCESS, context->id, 0); #else THRIFT_UNUSED_VARIABLE(serverContext); THRIFT_UNUSED_VARIABLE(transport); #endif } protected: uint32_t nextId_; std::shared_ptr log_; }; class ProcessorEventHandler : public TProcessorEventHandler { public: ProcessorEventHandler(const std::shared_ptr& log) : nextId_(1), log_(log) {} void* getContext(const char* fnName, void* serverContext) override { auto* connContext = reinterpret_cast(serverContext); CallContext* context = new CallContext(connContext, nextId_, fnName); ++nextId_; log_->append(EventLog::ET_CALL_STARTED, connContext->id, context->id, fnName); return context; } void freeContext(void* ctx, const char* fnName) override { auto* context = reinterpret_cast(ctx); checkName(context, fnName); log_->append(EventLog::ET_CALL_FINISHED, context->connContext->id, context->id, fnName); delete context; } void preRead(void* ctx, const char* fnName) override { auto* context = reinterpret_cast(ctx); checkName(context, fnName); log_->append(EventLog::ET_PRE_READ, context->connContext->id, context->id, fnName); } void postRead(void* ctx, const char* fnName, uint32_t bytes) override { THRIFT_UNUSED_VARIABLE(bytes); auto* context = reinterpret_cast(ctx); checkName(context, fnName); log_->append(EventLog::ET_POST_READ, context->connContext->id, context->id, fnName); } void preWrite(void* ctx, const char* fnName) override { auto* context = reinterpret_cast(ctx); checkName(context, fnName); log_->append(EventLog::ET_PRE_WRITE, context->connContext->id, context->id, fnName); } void postWrite(void* ctx, const char* fnName, uint32_t bytes) override { THRIFT_UNUSED_VARIABLE(bytes); auto* context = reinterpret_cast(ctx); checkName(context, fnName); log_->append(EventLog::ET_POST_WRITE, context->connContext->id, context->id, fnName); } void asyncComplete(void* ctx, const char* fnName) override { auto* context = reinterpret_cast(ctx); checkName(context, fnName); log_->append(EventLog::ET_ASYNC_COMPLETE, context->connContext->id, context->id, fnName); } void handlerError(void* ctx, const char* fnName) override { auto* context = reinterpret_cast(ctx); checkName(context, fnName); log_->append(EventLog::ET_HANDLER_ERROR, context->connContext->id, context->id, fnName); } protected: void checkName(const CallContext* context, const char* fnName) { // Note: we can't use BOOST_CHECK_EQUAL here, since the handler runs in a // different thread from the test functions. Just abort if the names are // different if (context->name != fnName) { fprintf(stderr, "call context name mismatch: \"%s\" != \"%s\"\n", context->name.c_str(), fnName); fflush(stderr); abort(); } } uint32_t nextId_; std::shared_ptr log_; }; } } } // apache::thrift::test #endif // _THRIFT_PROCESSOR_TEST_HANDLERS_H_ thrift-0.23.0/lib/cpp/test/processor/EventLog.cpp0000664000175000017500000000701515165535636022155 0ustar00buildbuild00000000000000/* * 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 "EventLog.h" #include #include using namespace apache::thrift::concurrency; namespace { // Define environment variable DEBUG_EVENTLOG to enable debug logging // ex: $ DEBUG_EVENTLOG=1 processor_test static const char * DEBUG_EVENTLOG = getenv("DEBUG_EVENTLOG"); void debug(const char* fmt, ...) { if (DEBUG_EVENTLOG) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); } } } namespace apache { namespace thrift { namespace test { uint32_t EventLog::nextId_ = 0; #define EVENT_TYPE(value) EventType EventLog::value = #value EVENT_TYPE(ET_LOG_END); EVENT_TYPE(ET_CONN_CREATED); EVENT_TYPE(ET_CONN_DESTROYED); EVENT_TYPE(ET_CALL_STARTED); EVENT_TYPE(ET_CALL_FINISHED); EVENT_TYPE(ET_PROCESS); EVENT_TYPE(ET_PRE_READ); EVENT_TYPE(ET_POST_READ); EVENT_TYPE(ET_PRE_WRITE); EVENT_TYPE(ET_POST_WRITE); EVENT_TYPE(ET_ASYNC_COMPLETE); EVENT_TYPE(ET_HANDLER_ERROR); EVENT_TYPE(ET_CALL_INCREMENT_GENERATION); EVENT_TYPE(ET_CALL_GET_GENERATION); EVENT_TYPE(ET_CALL_ADD_STRING); EVENT_TYPE(ET_CALL_GET_STRINGS); EVENT_TYPE(ET_CALL_GET_DATA_WAIT); EVENT_TYPE(ET_CALL_ONEWAY_WAIT); EVENT_TYPE(ET_CALL_EXCEPTION_WAIT); EVENT_TYPE(ET_CALL_UNEXPECTED_EXCEPTION_WAIT); EVENT_TYPE(ET_CALL_SET_VALUE); EVENT_TYPE(ET_CALL_GET_VALUE); EVENT_TYPE(ET_WAIT_RETURN); EventLog::EventLog() { id_ = nextId_++; debug("New log: %d", id_); } void EventLog::append(EventType type, uint32_t connectionId, uint32_t callId, const std::string& message) { Synchronized s(monitor_); debug("%d <-- %u, %u, %s \"%s\"", id_, connectionId, callId, type, message.c_str()); Event e(type, connectionId, callId, message); events_.push_back(e); monitor_.notify(); } Event EventLog::waitForEvent(int64_t timeout) { Synchronized s(monitor_); try { while (events_.empty()) { monitor_.wait(timeout); } } catch (const TimedOutException &) { return Event(ET_LOG_END, 0, 0, ""); } Event event = events_.front(); events_.pop_front(); return event; } Event EventLog::waitForConnEvent(uint32_t connId, int64_t timeout) { Synchronized s(monitor_); auto it = events_.begin(); while (true) { try { // TODO: it would be nicer to honor timeout for the duration of this // call, rather than restarting it for each call to wait(). It shouldn't // be a big problem in practice, though. while (it == events_.end()) { monitor_.wait(timeout); } } catch (const TimedOutException &) { return Event(ET_LOG_END, 0, 0, ""); } if (it->connectionId == connId) { Event event = *it; events_.erase(it); return event; } } } } } } // apache::thrift::test thrift-0.23.0/lib/cpp/test/qt/0000775000175000017500000000000015165535636016330 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/test/qt/CMakeLists.txt0000664000175000017500000000237315165535636021075 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # set(CMAKE_AUTOMOC ON) find_package(Qt5 REQUIRED COMPONENTS Test Network) set(TQTcpServerTest_Qt5_SOURCES TQTcpServerTest.cpp ) add_executable(TQTcpServerTest_Qt5 ${TQTcpServerTest_Qt5_SOURCES}) target_link_libraries(TQTcpServerTest_Qt5 testgencpp_cob) target_link_libraries(TQTcpServerTest_Qt5 thriftqt5) target_link_libraries(TQTcpServerTest_Qt5 thrift) target_link_libraries(TQTcpServerTest_Qt5 Qt5::Test Qt5::Network) add_test(NAME TQTcpServerTest_Qt5 COMMAND TQTcpServerTest_Qt5) thrift-0.23.0/lib/cpp/test/qt/TQTcpServerTest.cpp0000664000175000017500000000704215165535636022061 0ustar00buildbuild00000000000000#define BOOST_TEST_MODULE TQTcpServerTest #include #include #include #include #include #include #ifndef Q_MOC_RUN #include "thrift/protocol/TBinaryProtocol.h" #include "thrift/async/TAsyncProcessor.h" #include "thrift/qt/TQTcpServer.h" #include "thrift/qt/TQIODeviceTransport.h" #include "gen-cpp/ParentService.h" #endif using namespace apache::thrift; struct AsyncHandler : public test::ParentServiceCobSvIf { std::vector strings; void addString(std::function cob, const std::string& s) override { strings.push_back(s); cob(); } void getStrings(std::function const& _return)> cob) override { cob(strings); } // Overrides not used in this test void incrementGeneration(std::function cob) override {} void getGeneration(std::function cob) override {} void getDataWait(std::function cob, const int32_t length) override {} void onewayWait(std::function cob) override {} void exceptionWait( std::function cob, std::function /* exn_cob */, const std::string& message) override {} void unexpectedExceptionWait(std::function cob, const std::string& message) override {} }; class TQTcpServerTest : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void test_communicate(); private: std::shared_ptr serverThread; std::shared_ptr server; std::shared_ptr client; }; void TQTcpServerTest::initTestCase() { // setup server std::shared_ptr serverSocket = std::make_shared(); server.reset(new async::TQTcpServer(serverSocket, std::make_shared( std::make_shared()), std::make_shared())); QVERIFY(serverSocket->listen(QHostAddress::LocalHost)); int port = serverSocket->serverPort(); QVERIFY(port > 0); //setup server thread and move server to it serverThread.reset(new QThread()); serverSocket->moveToThread(serverThread.get()); server->moveToThread(serverThread.get()); serverThread->start(); // setup client std::shared_ptr socket = std::make_shared(); client.reset(new test::ParentServiceClient(std::make_shared( std::make_shared(socket)))); socket->connectToHost(QHostAddress::LocalHost, port); QVERIFY(socket->waitForConnected()); } void TQTcpServerTest::cleanupTestCase() { //first, stop the thread which holds the server serverThread->quit(); serverThread->wait(); // now, it is safe to delete the server server.reset(); // delete thread now serverThread.reset(); // cleanup client client.reset(); } void TQTcpServerTest::test_communicate() { client->addString("foo"); client->addString("bar"); std::vector reply; client->getStrings(reply); QCOMPARE(QString::fromStdString(reply[0]), QString("foo")); QCOMPARE(QString::fromStdString(reply[1]), QString("bar")); } #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) QTEST_GUILESS_MAIN(TQTcpServerTest); #else #undef QT_GUI_LIB QTEST_MAIN(TQTcpServerTest); #endif #include "TQTcpServerTest.moc" thrift-0.23.0/lib/cpp/test/TypedefTest.cpp0000664000175000017500000000224715165535636020655 0ustar00buildbuild00000000000000/* * 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 "gen-cpp/TypedefTest_types.h" BOOST_STATIC_ASSERT((boost::is_same::value)); BOOST_STATIC_ASSERT((boost::is_same::value)); BOOST_STATIC_ASSERT( (boost::is_same::value)); thrift-0.23.0/lib/cpp/test/TFileTransportTest.cpp0000664000175000017500000002550415167543515022173 0ustar00buildbuild00000000000000/* * 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 _GNU_SOURCE #define _GNU_SOURCE // needed for getopt_long #endif #include #ifdef HAVE_SYS_TIME_H #include #endif #include #include #include #ifdef __MINGW32__ #include #include #include #include #include #endif using namespace apache::thrift::transport; /************************************************************************** * Global state **************************************************************************/ static const char* tmp_dir = "/tmp"; class FsyncLog; FsyncLog* fsync_log; /************************************************************************** * Helper code **************************************************************************/ /** * Class to record calls to fsync */ class FsyncLog { public: struct FsyncCall { struct timeval time; int fd; }; typedef std::list CallList; FsyncLog() = default; void fsync(int fd) { FsyncCall call; call.fd = fd; THRIFT_GETTIMEOFDAY(&call.time, nullptr); calls_.push_back(call); } const CallList* getCalls() const { return &calls_; } private: CallList calls_; }; /** * Helper class to clean up temporary files */ class TempFile { public: TempFile(const char* directory, const char* prefix) { #ifdef __MINGW32__ ((void)directory); size_t path_len = strlen(prefix) + 8; path_ = new char[path_len]; snprintf(path_, path_len, "%sXXXXXX", prefix); if (_mktemp_s(path_,path_len) == 0) { fd_ = open(path_,O_CREAT | O_RDWR | O_BINARY,S_IREAD | S_IWRITE); if (fd_ < 0) { throw apache::thrift::TException("_mktemp_s() failed"); } } else { throw apache::thrift::TException("_mktemp_s() failed"); } #else size_t path_len = strlen(directory) + strlen(prefix) + 8; path_ = new char[path_len]; snprintf(path_, path_len, "%s/%sXXXXXX", directory, prefix); fd_ = mkstemp(path_); if (fd_ < 0) { throw apache::thrift::TException("mkstemp() failed"); } #endif } ~TempFile() { unlink(); close(); } const char* getPath() const { return path_; } int getFD() const { return fd_; } void unlink() { if (path_) { ::unlink(path_); delete[] path_; path_ = nullptr; } } void close() { if (fd_ < 0) { return; } ::close(fd_); fd_ = -1; } private: char* path_; int fd_; }; // Use our own version of fsync() for testing. // This returns immediately, so timing in test_destructor() isn't affected by // waiting on the actual filesystem. extern "C" int fsync(int fd) { if (fsync_log) { fsync_log->fsync(fd); } return 0; } int time_diff(const struct timeval* t1, const struct timeval* t2) { return (t2->tv_usec - t1->tv_usec) + (t2->tv_sec - t1->tv_sec) * 1000000; } /************************************************************************** * Test cases **************************************************************************/ /** * Make sure the TFileTransport destructor exits "quickly". * * Previous versions had a bug causing the writer thread not to exit * right away. * * It's kind of lame that we just check to see how long the destructor takes in * wall-clock time. This could result in false failures on slower systems, or * on heavily loaded machines. */ BOOST_AUTO_TEST_CASE(test_destructor) { TempFile f(tmp_dir, "thrift.TFileTransportTest."); unsigned int const NUM_ITERATIONS = 1000; unsigned int num_over = 0; for (unsigned int n = 0; n < NUM_ITERATIONS; ++n) { BOOST_CHECK_EQUAL(0, ftruncate(f.getFD(), 0)); TFileTransport* transport = new TFileTransport(f.getPath()); // write something so that the writer thread gets started transport->write(reinterpret_cast("foo"), 3); // Every other iteration, also call flush(), just in case that potentially // has any effect on how the writer thread wakes up. if (n & 0x1) { transport->flush(); } /* * Time the call to the destructor */ struct timeval start; struct timeval end; THRIFT_GETTIMEOFDAY(&start, nullptr); delete transport; THRIFT_GETTIMEOFDAY(&end, nullptr); int delta = time_diff(&start, &end); // If any attempt takes more than 500ms, treat that as a failure. // Treat this as a fatal failure, so we'll return now instead of // looping over a very slow operation. BOOST_WARN( delta < 500000 ); // Normally, it takes less than 100ms on my dev box. // However, if the box is heavily loaded, some of the test runs // take longer, since we're just waiting for our turn on the CPU. if (delta > 100000) { ++num_over; } } // Make sure fewer than 10% of the runs took longer than 1000us BOOST_WARN(num_over < (NUM_ITERATIONS / 10)); } /** * Make sure setFlushMaxUs() is honored. */ void test_flush_max_us_impl(uint32_t flush_us, uint32_t write_us, uint32_t test_us) { // TFileTransport only calls fsync() if data has been written, // so make sure the write interval is smaller than the flush interval. BOOST_WARN(write_us < flush_us); TempFile f(tmp_dir, "thrift.TFileTransportTest."); // Record calls to fsync() FsyncLog log; fsync_log = &log; TFileTransport* transport = new TFileTransport(f.getPath()); // Don't flush because of # of bytes written transport->setFlushMaxBytes(0xffffffff); uint8_t buf[] = "a"; uint32_t buflen = sizeof(buf); // Set the flush interval transport->setFlushMaxUs(flush_us); // Make one call to write, to start the writer thread now. // (If we just let the thread get created during our test loop, // the thread creation sometimes takes long enough to make the first // fsync interval fail the check.) transport->write(buf, buflen); // Add one entry to the fsync log, just to mark the start time log.fsync(-1); // Loop doing write(), sleep(), ... uint32_t total_time = 0; while (true) { transport->write(buf, buflen); if (total_time > test_us) { break; } usleep(write_us); total_time += write_us; } delete transport; // Stop logging new fsync() calls fsync_log = nullptr; // Examine the fsync() log // // TFileTransport uses pthread_cond_timedwait(), which only has millisecond // resolution. In my testing, it normally wakes up about 1 millisecond late. // However, sometimes it takes a bit longer. Allow 5ms leeway. int max_allowed_delta = flush_us + 5000; const FsyncLog::CallList* calls = log.getCalls(); // We added 1 fsync call above. // Make sure TFileTransport called fsync at least once BOOST_WARN_GE(calls->size(), static_cast(1)); const struct timeval* prev_time = nullptr; for (const auto & call : *calls) { if (prev_time) { int delta = time_diff(prev_time, &call.time); BOOST_WARN( delta < max_allowed_delta ); } prev_time = &call.time; } } BOOST_AUTO_TEST_CASE(test_flush_max_us1) { // fsync every 10ms, write every 5ms, for 500ms test_flush_max_us_impl(10000, 5000, 500000); } BOOST_AUTO_TEST_CASE(test_flush_max_us2) { // fsync every 50ms, write every 20ms, for 500ms test_flush_max_us_impl(50000, 20000, 500000); } BOOST_AUTO_TEST_CASE(test_flush_max_us3) { // fsync every 400ms, write every 300ms, for 1s test_flush_max_us_impl(400000, 300000, 1000000); } /** * Make sure flush() is fast when there is nothing to do. * * TFileTransport used to have a bug where flush() would wait for the fsync * timeout to expire. */ BOOST_AUTO_TEST_CASE(test_noop_flush) { TempFile f(tmp_dir, "thrift.TFileTransportTest."); TFileTransport transport(f.getPath()); // Write something to start the writer thread. uint8_t buf[] = "a"; transport.write(buf, 1); struct timeval start; THRIFT_GETTIMEOFDAY(&start, nullptr); for (unsigned int n = 0; n < 10; ++n) { transport.flush(); struct timeval now; THRIFT_GETTIMEOFDAY(&now, nullptr); // Fail if at any point we've been running for longer than half a second. // (With the buggy code, TFileTransport used to take 3 seconds per flush()) // // Use a fatal fail so we break out early, rather than continuing to make // many more slow flush() calls. int delta = time_diff(&start, &now); BOOST_WARN( delta < 2000000 ); } } /************************************************************************** * General Initialization **************************************************************************/ void print_usage(FILE* f, const char* argv0) { fprintf(f, "Usage: %s [boost_options] [options]\n", argv0); fprintf(f, "Options:\n"); fprintf(f, " --tmp-dir=DIR, -t DIR\n"); fprintf(f, " --help\n"); } void parse_args(int argc, char* argv[]) { struct option long_opts[] = {{"help", false, nullptr, 'h'}, {"tmp-dir", true, nullptr, 't'}, {nullptr, 0, nullptr, 0}}; while (true) { optopt = 1; int optchar = getopt_long(argc, argv, "ht:", long_opts, nullptr); if (optchar == -1) { break; } switch (optchar) { case 't': tmp_dir = optarg; break; case 'h': print_usage(stdout, argv[0]); exit(0); case '?': exit(1); default: // Only happens if someone adds another option to the optarg string, // but doesn't update the switch statement to handle it. fprintf(stderr, "unknown option \"-%c\"\n", optchar); exit(1); } } } #ifdef BOOST_TEST_DYN_LINK static int myArgc = 0; static char **myArgv = nullptr; bool init_unit_test_suite() { boost::unit_test::framework::master_test_suite().p_name.value = "TFileTransportTest"; // Parse arguments parse_args(myArgc,myArgv); return true; } int main( int argc, char* argv[] ) { myArgc = argc; myArgv = argv; return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv); } #else boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { boost::unit_test::framework::master_test_suite().p_name.value = "TFileTransportTest"; // Parse arguments parse_args(argc, argv); return nullptr; } #endif thrift-0.23.0/lib/cpp/test/TNonblockingServerTest.cpp0000664000175000017500000001466215165535636023037 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE TNonblockingServerTest #include #include #include "thrift/concurrency/Monitor.h" #include "thrift/concurrency/Thread.h" #include "thrift/server/TNonblockingServer.h" #include "thrift/transport/TNonblockingServerSocket.h" #include "gen-cpp/ParentService.h" #include using apache::thrift::concurrency::Guard; using apache::thrift::concurrency::Monitor; using apache::thrift::concurrency::Mutex; using apache::thrift::concurrency::ThreadFactory; using apache::thrift::concurrency::Runnable; using apache::thrift::concurrency::Thread; using apache::thrift::concurrency::ThreadFactory; using apache::thrift::server::TServerEventHandler; using std::make_shared; using std::shared_ptr; using namespace apache::thrift; struct Handler : public test::ParentServiceIf { void addString(const std::string& s) override { strings_.push_back(s); } void getStrings(std::vector& _return) override { _return = strings_; } std::vector strings_; // dummy overrides not used in this test int32_t incrementGeneration() override { return 0; } int32_t getGeneration() override { return 0; } void getDataWait(std::string&, const int32_t) override {} void onewayWait() override {} void exceptionWait(const std::string&) override {} void unexpectedExceptionWait(const std::string&) override {} }; class Fixture { private: struct ListenEventHandler : public TServerEventHandler { public: ListenEventHandler(Mutex* mutex) : listenMonitor_(mutex), ready_(false) {} void preServe() override /* override */ { Guard g(listenMonitor_.mutex()); ready_ = true; listenMonitor_.notify(); } Monitor listenMonitor_; bool ready_; }; struct Runner : public Runnable { int port; shared_ptr userEventBase; shared_ptr processor; shared_ptr server; shared_ptr listenHandler; shared_ptr socket; Mutex mutex_; Runner() { port = 0; listenHandler.reset(new ListenEventHandler(&mutex_)); } void run() override { // When binding to explicit port, allow retrying to workaround bind failures on ports in use int retryCount = port ? 10 : 0; startServer(retryCount); } void readyBarrier() { // block until server is listening and ready to accept connections Guard g(mutex_); while (!listenHandler->ready_) { listenHandler->listenMonitor_.wait(); } } private: void startServer(int retry_count) { try { socket.reset(new transport::TNonblockingServerSocket(port)); server.reset(new server::TNonblockingServer(processor, socket)); server->setServerEventHandler(listenHandler); if (userEventBase) { server->registerEvents(userEventBase.get()); } server->serve(); } catch (const transport::TTransportException&) { if (retry_count > 0) { ++port; startServer(retry_count - 1); } else { throw; } } } }; struct EventDeleter { void operator()(event_base* p) { event_base_free(p); } }; protected: Fixture() : processor(new test::ParentServiceProcessor(make_shared())) {} ~Fixture() { if (server) { server->stop(); } if (thread) { thread->join(); } } void setEventBase(event_base* user_event_base) { userEventBase_.reset(user_event_base, EventDeleter()); } int startServer(int port) { shared_ptr runner(new Runner); runner->port = port; runner->processor = processor; runner->userEventBase = userEventBase_; shared_ptr threadFactory( new ThreadFactory(false)); thread = threadFactory->newThread(runner); thread->start(); runner->readyBarrier(); server = runner->server; return runner->port; } bool canCommunicate(int serverPort) { shared_ptr socket(new transport::TSocket("localhost", serverPort)); socket->open(); test::ParentServiceClient client(make_shared( make_shared(socket))); client.addString("foo"); std::vector strings; client.getStrings(strings); return strings.size() == 1 && !(strings[0].compare("foo")); } private: shared_ptr userEventBase_; shared_ptr processor; protected: shared_ptr server; private: shared_ptr thread; }; BOOST_AUTO_TEST_SUITE(TNonblockingServerTest) BOOST_FIXTURE_TEST_CASE(get_specified_port, Fixture) { int specified_port = startServer(12345); BOOST_REQUIRE_GE(specified_port, 12345); BOOST_REQUIRE_EQUAL(server->getListenPort(), specified_port); BOOST_CHECK(canCommunicate(specified_port)); server->stop(); } BOOST_FIXTURE_TEST_CASE(get_assigned_port, Fixture) { int specified_port = startServer(0); BOOST_REQUIRE_EQUAL(specified_port, 0); int assigned_port = server->getListenPort(); BOOST_REQUIRE_NE(assigned_port, 0); BOOST_CHECK(canCommunicate(assigned_port)); server->stop(); } BOOST_FIXTURE_TEST_CASE(provide_event_base, Fixture) { event_base* eb = event_base_new(); setEventBase(eb); startServer(0); // assert that the server works BOOST_CHECK(canCommunicate(server->getListenPort())); #if LIBEVENT_VERSION_NUMBER > 0x02010400 // also assert that the event_base is actually used when it's easy BOOST_CHECK_GT(event_base_get_num_events(eb, EVENT_BASE_COUNT_ADDED), 0); #endif } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/TServerTransportTest.cpp0000664000175000017500000000343315165535636022562 0ustar00buildbuild00000000000000/* * 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 using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using std::shared_ptr; BOOST_AUTO_TEST_SUITE(TServerTransportTest) class TestTTransport : public TTransport {}; class TestTServerTransport : public TServerTransport { public: TestTServerTransport() : valid_(true) {} void close() override {} bool valid_; protected: shared_ptr acceptImpl() override { return valid_ ? std::make_shared() : shared_ptr(); } }; BOOST_AUTO_TEST_CASE(test_positive_accept) { TestTServerTransport uut; BOOST_CHECK(uut.accept()); } BOOST_AUTO_TEST_CASE(test_negative_accept) { TestTServerTransport uut; uut.valid_ = false; BOOST_CHECK_THROW(uut.accept(), TTransportException); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/AllProtocolTests.tcc0000664000175000017500000001770515165535636021666 0ustar00buildbuild00000000000000/* * 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_TEST_GENERICPROTOCOLTEST_TCC_ #define _THRIFT_TEST_GENERICPROTOCOLTEST_TCC_ 1 #include #include #include #include #include #include "GenericHelpers.h" using std::shared_ptr; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; #define ERR_LEN 512 extern char errorMessage[ERR_LEN]; template void testNaked(Val val) { shared_ptr transport(new TMemoryBuffer()); shared_ptr protocol(new TProto(transport)); GenericIO::write(protocol, val); Val out; GenericIO::read(protocol, out); if (out != val) { THRIFT_SNPRINTF(errorMessage, ERR_LEN, "Invalid naked test (type: %s)", ClassNames::getName()); throw TException(errorMessage); } } template void testField(const Val val) { shared_ptr transport(new TMemoryBuffer()); shared_ptr protocol(new TProto(transport)); protocol->writeStructBegin("test_struct"); protocol->writeFieldBegin("test_field", type, (int16_t)15); GenericIO::write(protocol, val); protocol->writeFieldEnd(); protocol->writeStructEnd(); std::string name; TType fieldType; int16_t fieldId; protocol->readStructBegin(name); protocol->readFieldBegin(name, fieldType, fieldId); if (fieldId != 15) { THRIFT_SNPRINTF(errorMessage, ERR_LEN, "Invalid ID (type: %s)", typeid(val).name()); throw TException(errorMessage); } if (fieldType != type) { THRIFT_SNPRINTF(errorMessage, ERR_LEN, "Invalid Field Type (type: %s)", typeid(val).name()); throw TException(errorMessage); } Val out; GenericIO::read(protocol, out); if (out != val) { THRIFT_SNPRINTF(errorMessage, ERR_LEN, "Invalid value read (type: %s)", typeid(val).name()); throw TException(errorMessage); } protocol->readFieldEnd(); protocol->readStructEnd(); } template void testMessage() { struct TMessage { const char* name; TMessageType type; int32_t seqid; } messages[] = {{"short message name", T_CALL, 0}, {"1", T_REPLY, 12345}, {"loooooooooooooooooooooooooooooooooong", T_EXCEPTION, 1 << 16}, {"one way push", T_ONEWAY, 12}, {"Janky", T_CALL, 0}}; const int messages_count = sizeof(messages) / sizeof(TMessage); for (int i = 0; i < messages_count; i++) { shared_ptr transport(new TMemoryBuffer()); shared_ptr protocol(new TProto(transport)); protocol->writeMessageBegin(messages[i].name, messages[i].type, messages[i].seqid); protocol->writeMessageEnd(); std::string name; TMessageType type; int32_t seqid; protocol->readMessageBegin(name, type, seqid); if (name != messages[i].name || type != messages[i].type || seqid != messages[i].seqid) { throw TException("readMessageBegin failed."); } } } template void testProtocol(const char* protoname) { try { testNaked((int8_t)123); for (int32_t i = 0; i < 128; i++) { testField((int8_t)i); testField((int8_t)-i); } testNaked((int16_t)0); testNaked((int16_t)1); testNaked((int16_t)15000); testNaked((int16_t)0x7fff); testNaked((int16_t)-1); testNaked((int16_t)-15000); testNaked((int16_t)-0x7fff); testNaked((std::numeric_limits::min)()); testNaked((std::numeric_limits::max)()); testField((int16_t)0); testField((int16_t)1); testField((int16_t)7); testField((int16_t)150); testField((int16_t)15000); testField((int16_t)0x7fff); testField((int16_t)-1); testField((int16_t)-7); testField((int16_t)-150); testField((int16_t)-15000); testField((int16_t)-0x7fff); testNaked(0); testNaked(1); testNaked(15000); testNaked(0xffff); testNaked(-1); testNaked(-15000); testNaked(-0xffff); testNaked((std::numeric_limits::min)()); testNaked((std::numeric_limits::max)()); testField(0); testField(1); testField(7); testField(150); testField(15000); testField(31337); testField(0xffff); testField(0xffffff); testField(-1); testField(-7); testField(-150); testField(-15000); testField(-0xffff); testField(-0xffffff); testNaked((std::numeric_limits::min)()); testNaked((std::numeric_limits::max)()); testNaked((std::numeric_limits::min)() + 10); testNaked((std::numeric_limits::max)() - 16); testNaked((std::numeric_limits::min)()); testNaked((std::numeric_limits::max)()); testNaked(0); for (int64_t i = 0; i < 62; i++) { testNaked(1LL << i); testNaked(-(1LL << i)); } testField(0); for (int i = 0; i < 62; i++) { testField(1LL << i); testField(-(1LL << i)); } testNaked(123.456); testNaked(""); testNaked("short"); testNaked("borderlinetiny"); 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"); testField("a bit longer than the smallest possible"); testMessage(); printf("%s => OK\n", protoname); } catch (const TException &e) { THRIFT_SNPRINTF(errorMessage, ERR_LEN, "%s => Test FAILED: %s", protoname, e.what()); throw TException(errorMessage); } } #endif thrift-0.23.0/lib/cpp/test/ThriftTest_extras.cpp0000664000175000017500000000221415165535636022075 0ustar00buildbuild00000000000000/* * 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. */ // Extra functions required for ThriftTest_types to work #include #include "gen-cpp/ThriftTest_types.h" namespace thrift { namespace test { bool Insanity::operator<(thrift::test::Insanity const& other) const { using apache::thrift::ThriftDebugString; return ThriftDebugString(*this) < ThriftDebugString(other); } } } thrift-0.23.0/lib/cpp/test/fuzz/0000755000175000017500000000000015170007200016651 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/test/fuzz/FuzzRoundtripJson.cpp0000664000175000017500000000205515165535636023107 0ustar00buildbuild00000000000000/* * 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 "FuzzCommon.tcc" using namespace apache::thrift::protocol; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return apache::thrift::fuzzer::fuzz_roundtrip(data, size); }thrift-0.23.0/lib/cpp/test/fuzz/FuzzRoundtripCompact.cpp0000664000175000017500000000206315165535636023563 0ustar00buildbuild00000000000000/* * 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 "FuzzCommon.tcc" using namespace apache::thrift::protocol; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return apache::thrift::fuzzer::fuzz_roundtrip(data, size); }thrift-0.23.0/lib/cpp/test/fuzz/FuzzRoundtripBinary.cpp0000664000175000017500000000206115165535636023417 0ustar00buildbuild00000000000000/* * 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 "FuzzCommon.tcc" using namespace apache::thrift::protocol; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return apache::thrift::fuzzer::fuzz_roundtrip(data, size); }thrift-0.23.0/lib/cpp/test/fuzz/FuzzParseBinary.cpp0000664000175000017500000000205515165535636022506 0ustar00buildbuild00000000000000/* * 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 "FuzzCommon.tcc" using namespace apache::thrift::protocol; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return apache::thrift::fuzzer::fuzz_parse(data, size); }thrift-0.23.0/lib/cpp/test/fuzz/FuzzCommon.tcc0000664000175000017500000001023415165535636021504 0ustar00buildbuild00000000000000/* * 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_TEST_FUZZ_COMMON_TCC_ #define THRIFT_TEST_FUZZ_COMMON_TCC_ #include #include #include #include #include #include #include #include #include #include "gen-cpp/FuzzTest_types.h" namespace apache { namespace thrift { namespace fuzzer { using namespace apache::thrift::transport; using namespace apache::thrift::protocol; using namespace fuzz; // 10MB message size limit to prevent over-allocation during fuzzing const int FUZZ_MAX_MESSAGE_SIZE = 10 * 1024 * 1024; inline bool is_nan_false_positive(FuzzTest& test1, FuzzTest& test2) { BasicTypes& b1 = test1.basic; BasicTypes& b2 = test2.basic; if (std::isnan(b1.double_field) && std::isnan(b2.double_field)) { b1.double_field = 0.0; b2.double_field = 0.0; } // Check for NaN in containers if they contain doubles // This is a simplified version - may need adjustment based on actual schema return test1 == test2; } // Simple parse-only fuzzer template int fuzz_parse(const uint8_t* data, size_t size) { try { std::shared_ptr config(new TConfiguration(FUZZ_MAX_MESSAGE_SIZE)); std::shared_ptr trans(new TMemoryBuffer(const_cast(data), size, TMemoryBuffer::OBSERVE, config)); std::shared_ptr proto(new ProtocolType(trans)); FuzzTest test; test.read(proto.get()); } catch (const TException&) { // Ignore any Thrift exceptions - they're expected when fuzzing } return 0; } // Roundtrip fuzzer that verifies serialization/deserialization template int fuzz_roundtrip(const uint8_t* data, size_t size) { try { std::shared_ptr config(new TConfiguration(FUZZ_MAX_MESSAGE_SIZE)); // First parse std::shared_ptr trans(new TMemoryBuffer(const_cast(data), size, TMemoryBuffer::OBSERVE, config)); std::shared_ptr proto(new ProtocolType(trans)); FuzzTest test1; test1.read(proto.get()); // Serialize back std::shared_ptr outTrans(new TMemoryBuffer(config)); std::shared_ptr outProto(new ProtocolType(outTrans)); test1.write(outProto.get()); // Get serialized data std::string serialized = outTrans->getBufferAsString(); // Deserialize again std::shared_ptr reTrans(new TMemoryBuffer(config)); reTrans->write((const uint8_t*)serialized.data(), static_cast(serialized.size())); std::shared_ptr reProto(new ProtocolType(reTrans)); FuzzTest test2; test2.read(reProto.get()); // Verify equality if (!(test1 == test2) && !is_nan_false_positive(test1, test2)) { const std::string str1(apache::thrift::ThriftDebugString(test1)); const std::string str2(apache::thrift::ThriftDebugString(test2)); std::cout << "Expected:\n" << str1 << "\nGotten:\n" << str2 << std::endl; throw std::runtime_error("Roundtrip failed"); } } catch (const TException&) { // Ignore any Thrift exceptions - they're expected when fuzzing } return 0; } }}} // apache::thrift::fuzzer #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION __attribute__((weak)) int main(int argc, char** argv) { return 0; } #endif #endif // THRIFT_TEST_FUZZ_COMMON_TCC_ thrift-0.23.0/lib/cpp/test/fuzz/FuzzParseJson.cpp0000664000175000017500000000205215165535636022170 0ustar00buildbuild00000000000000/* * 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 "FuzzCommon.tcc" using namespace apache::thrift::protocol; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return apache::thrift::fuzzer::fuzz_parse(data, size); }thrift-0.23.0/lib/cpp/test/fuzz/CMakeLists.txt0000664000175000017500000001133215167543515021437 0ustar00buildbuild00000000000000# # 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. # # Fuzz testing configuration # Generate FuzzTest code add_custom_command(OUTPUT gen-cpp/FuzzTest_types.cpp gen-cpp/FuzzTest_types.h COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/FuzzTest.thrift ) # Create a library for the generated code add_library(fuzztest_gen gen-cpp/FuzzTest_types.cpp =) target_link_libraries(fuzztest_gen thrift) # Common fuzzing header set(FUZZ_COMMON_HEADERS FuzzCommon.tcc ) # Add fuzzing flags when using Clang if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(FUZZING_FLAGS "-fsanitize=fuzzer,address -g") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FUZZING_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FUZZING_FLAGS}") endif() # Compact protocol fuzzer add_executable(FuzzParseCompact FuzzParseCompact.cpp ${FUZZ_COMMON_HEADERS} ) target_link_libraries(FuzzParseCompact thrift fuzztest_gen ) # Compact protocol roundtrip fuzzer add_executable(FuzzRoundtripCompact FuzzRoundtripCompact.cpp ) target_link_libraries(FuzzRoundtripCompact thrift fuzztest_gen ) # Binary protocol fuzzer add_executable(FuzzParseBinary FuzzParseBinary.cpp ${FUZZ_COMMON_HEADERS} ) target_link_libraries(FuzzParseBinary thrift fuzztest_gen ) # Binary protocol roundtrip fuzzer add_executable(FuzzRoundtripBinary FuzzRoundtripBinary.cpp ) target_link_libraries(FuzzRoundtripBinary thrift fuzztest_gen ) # JSON protocol fuzzer add_executable(FuzzParseJson FuzzParseJson.cpp ${FUZZ_COMMON_HEADERS} ) target_link_libraries(FuzzParseJson thrift fuzztest_gen ) # JSON protocol roundtrip fuzzer add_executable(FuzzRoundtripJson FuzzRoundtripJson.cpp ${FUZZ_COMMON_HEADERS} ) target_link_libraries(FuzzRoundtripJson thrift fuzztest_gen ) # Create directories for fuzzing corpus file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol_roundtrip) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol_roundtrip) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol_roundtrip) # Add test targets that run the fuzzers briefly if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_test(NAME FuzzParseCompact_run COMMAND FuzzParseCompact -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol ) add_test(NAME FuzzRoundtripCompact_run COMMAND FuzzRoundtripCompact -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol_roundtrip ) add_test(NAME FuzzParseBinary_run COMMAND FuzzParseBinary -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol ) add_test(NAME FuzzRoundtripBinary_run COMMAND FuzzRoundtripBinary -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol_roundtrip ) add_test(NAME FuzzParseJson_run COMMAND FuzzParseJson -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol ) add_test(NAME FuzzRoundtripJson_run COMMAND FuzzRoundtripJson -runs=100 ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol_roundtrip ) else() add_test(NAME FuzzParseCompact_run COMMAND FuzzParseCompact ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol ) add_test(NAME FuzzRoundtripCompact_run COMMAND FuzzRoundtripCompact ${CMAKE_CURRENT_BINARY_DIR}/corpus/compact_protocol_roundtrip ) add_test(NAME FuzzParseBinary_run COMMAND FuzzParseBinary ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol ) add_test(NAME FuzzRoundtripBinary_run COMMAND FuzzRoundtripBinary ${CMAKE_CURRENT_BINARY_DIR}/corpus/binary_protocol_roundtrip ) add_test(NAME FuzzParseJson_run COMMAND FuzzParseJson ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol ) add_test(NAME FuzzRoundtripJson_run COMMAND FuzzRoundtripJson ${CMAKE_CURRENT_BINARY_DIR}/corpus/json_protocol_roundtrip ) endif() thrift-0.23.0/lib/cpp/test/fuzz/README.md0000664000175000017500000000255115165535636020164 0ustar00buildbuild00000000000000# C++ Fuzzing README To build the fuzz targets, run `make check` in this directory. The build system uses LLVM's libFuzzer for fuzzing the C++ Thrift implementation. These are standard libFuzzer targets, so you can run them using the standard libFuzzer interface. After building, you can run a fuzzer using: ```bash ./ ``` We currently have six fuzz targets: * FuzzParseBinary -- fuzzes the deserialization of the Binary protocol * FuzzParseCompact -- fuzzes the deserialization of the Compact protocol * FuzzParseJson -- fuzzes the deserialization of the JSON protocol * FuzzRoundtripBinary -- fuzzes the roundtrip of the Binary protocol (i.e. serializes then deserializes and compares the result) * FuzzRoundtripCompact -- fuzzes the roundtrip of the Compact protocol * FuzzRoundtripJson -- fuzzes the roundtrip of the JSON protocol The fuzzers use libFuzzer's built-in mutation engine to generate test cases. Each fuzzer implements the standard `LLVMFuzzerTestOneInput` interface and uses common testing code from `FuzzCommon.tcc`. For more information about libFuzzer and its options, see the [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html). You can also use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these C++ fuzzers, since the wire formats are identical between implementations.thrift-0.23.0/lib/cpp/test/fuzz/FuzzParseCompact.cpp0000664000175000017500000000206015165535636022644 0ustar00buildbuild00000000000000/* * 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 "FuzzCommon.tcc" using namespace apache::thrift::protocol; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return apache::thrift::fuzzer::fuzz_parse(data, size); }thrift-0.23.0/lib/cpp/test/fuzz/Makefile.in0000644000175000017500000013741415170007167020744 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = FuzzParseCompact$(EXEEXT) FuzzParseBinary$(EXEEXT) \ FuzzRoundtripCompact$(EXEEXT) FuzzRoundtripBinary$(EXEEXT) \ FuzzParseJson$(EXEEXT) FuzzRoundtripJson$(EXEEXT) subdir = lib/cpp/test/fuzz ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libfuzztest_gen_la_DEPENDENCIES = \ $(top_builddir)/lib/cpp/libthrift.la am__dirstamp = $(am__leading_dot)dirstamp nodist_libfuzztest_gen_la_OBJECTS = gen-cpp/FuzzTest_types.lo libfuzztest_gen_la_OBJECTS = $(nodist_libfuzztest_gen_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_FuzzParseBinary_OBJECTS = \ FuzzParseBinary-FuzzParseBinary.$(OBJEXT) FuzzParseBinary_OBJECTS = $(am_FuzzParseBinary_OBJECTS) FuzzParseBinary_DEPENDENCIES = libfuzztest_gen.la \ $(top_builddir)/lib/cpp/libthrift.la FuzzParseBinary_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(FuzzParseBinary_CXXFLAGS) $(CXXFLAGS) \ $(FuzzParseBinary_LDFLAGS) $(LDFLAGS) -o $@ am_FuzzParseCompact_OBJECTS = \ FuzzParseCompact-FuzzParseCompact.$(OBJEXT) FuzzParseCompact_OBJECTS = $(am_FuzzParseCompact_OBJECTS) FuzzParseCompact_DEPENDENCIES = libfuzztest_gen.la \ $(top_builddir)/lib/cpp/libthrift.la FuzzParseCompact_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(FuzzParseCompact_CXXFLAGS) $(CXXFLAGS) \ $(FuzzParseCompact_LDFLAGS) $(LDFLAGS) -o $@ am_FuzzParseJson_OBJECTS = FuzzParseJson-FuzzParseJson.$(OBJEXT) FuzzParseJson_OBJECTS = $(am_FuzzParseJson_OBJECTS) FuzzParseJson_DEPENDENCIES = libfuzztest_gen.la \ $(top_builddir)/lib/cpp/libthrift.la FuzzParseJson_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(FuzzParseJson_CXXFLAGS) $(CXXFLAGS) $(FuzzParseJson_LDFLAGS) \ $(LDFLAGS) -o $@ am_FuzzRoundtripBinary_OBJECTS = \ FuzzRoundtripBinary-FuzzRoundtripBinary.$(OBJEXT) FuzzRoundtripBinary_OBJECTS = $(am_FuzzRoundtripBinary_OBJECTS) FuzzRoundtripBinary_DEPENDENCIES = libfuzztest_gen.la \ $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripBinary_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(FuzzRoundtripBinary_CXXFLAGS) $(CXXFLAGS) \ $(FuzzRoundtripBinary_LDFLAGS) $(LDFLAGS) -o $@ am_FuzzRoundtripCompact_OBJECTS = \ FuzzRoundtripCompact-FuzzRoundtripCompact.$(OBJEXT) FuzzRoundtripCompact_OBJECTS = $(am_FuzzRoundtripCompact_OBJECTS) FuzzRoundtripCompact_DEPENDENCIES = libfuzztest_gen.la \ $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripCompact_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(FuzzRoundtripCompact_CXXFLAGS) $(CXXFLAGS) \ $(FuzzRoundtripCompact_LDFLAGS) $(LDFLAGS) -o $@ am_FuzzRoundtripJson_OBJECTS = \ FuzzRoundtripJson-FuzzRoundtripJson.$(OBJEXT) FuzzRoundtripJson_OBJECTS = $(am_FuzzRoundtripJson_OBJECTS) FuzzRoundtripJson_DEPENDENCIES = libfuzztest_gen.la \ $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripJson_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(FuzzRoundtripJson_CXXFLAGS) $(CXXFLAGS) \ $(FuzzRoundtripJson_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Po \ ./$(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Po \ ./$(DEPDIR)/FuzzParseJson-FuzzParseJson.Po \ ./$(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Po \ ./$(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Po \ ./$(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Po \ gen-cpp/$(DEPDIR)/FuzzTest_types.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist_libfuzztest_gen_la_SOURCES) \ $(FuzzParseBinary_SOURCES) $(FuzzParseCompact_SOURCES) \ $(FuzzParseJson_SOURCES) $(FuzzRoundtripBinary_SOURCES) \ $(FuzzRoundtripCompact_SOURCES) $(FuzzRoundtripJson_SOURCES) DIST_SOURCES = $(FuzzParseBinary_SOURCES) $(FuzzParseCompact_SOURCES) \ $(FuzzParseJson_SOURCES) $(FuzzRoundtripBinary_SOURCES) \ $(FuzzRoundtripCompact_SOURCES) $(FuzzRoundtripJson_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc noinst_LTLIBRARIES = libfuzztest_gen.la nodist_libfuzztest_gen_la_SOURCES = \ gen-cpp/FuzzTest_types.cpp \ gen-cpp/FuzzTest_types.h libfuzztest_gen_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la # Common fuzzing headers noinst_HEADERS = FuzzCommon.tcc # Fuzzing executables AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/src -I$(top_srcdir)/lib/cpp/src/thrift -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. FuzzParseCompact_SOURCES = FuzzParseCompact.cpp FuzzCommon.tcc FuzzParseCompact_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzParseCompact_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g @USING_CLANG_TRUE@FuzzParseCompact_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer FuzzRoundtripCompact_SOURCES = FuzzRoundtripCompact.cpp FuzzCommon.tcc FuzzRoundtripCompact_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripCompact_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g @USING_CLANG_TRUE@FuzzRoundtripCompact_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer FuzzParseBinary_SOURCES = FuzzParseBinary.cpp FuzzCommon.tcc FuzzParseBinary_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzParseBinary_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g @USING_CLANG_TRUE@FuzzParseBinary_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer FuzzRoundtripBinary_SOURCES = FuzzRoundtripBinary.cpp FuzzCommon.tcc FuzzRoundtripBinary_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripBinary_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g @USING_CLANG_TRUE@FuzzRoundtripBinary_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer FuzzParseJson_SOURCES = FuzzParseJson.cpp FuzzCommon.tcc FuzzParseJson_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzParseJson_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g @USING_CLANG_TRUE@FuzzParseJson_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer FuzzRoundtripJson_SOURCES = FuzzRoundtripJson.cpp FuzzCommon.tcc FuzzRoundtripJson_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripJson_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g @USING_CLANG_TRUE@FuzzRoundtripJson_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer CLEANFILES = gen-cpp/* EXTRA_DIST = CMakeLists.txt FuzzParseCompact.cpp FuzzParseBinary.cpp FuzzRoundtripCompact.cpp FuzzRoundtripBinary.cpp FuzzParseJson.cpp FuzzRoundtripJson.cpp all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/cpp/test/fuzz/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/cpp/test/fuzz/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gen-cpp/$(am__dirstamp): @$(MKDIR_P) gen-cpp @: > gen-cpp/$(am__dirstamp) gen-cpp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gen-cpp/$(DEPDIR) @: > gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/FuzzTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) libfuzztest_gen.la: $(libfuzztest_gen_la_OBJECTS) $(libfuzztest_gen_la_DEPENDENCIES) $(EXTRA_libfuzztest_gen_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libfuzztest_gen_la_OBJECTS) $(libfuzztest_gen_la_LIBADD) $(LIBS) FuzzParseBinary$(EXEEXT): $(FuzzParseBinary_OBJECTS) $(FuzzParseBinary_DEPENDENCIES) $(EXTRA_FuzzParseBinary_DEPENDENCIES) @rm -f FuzzParseBinary$(EXEEXT) $(AM_V_CXXLD)$(FuzzParseBinary_LINK) $(FuzzParseBinary_OBJECTS) $(FuzzParseBinary_LDADD) $(LIBS) FuzzParseCompact$(EXEEXT): $(FuzzParseCompact_OBJECTS) $(FuzzParseCompact_DEPENDENCIES) $(EXTRA_FuzzParseCompact_DEPENDENCIES) @rm -f FuzzParseCompact$(EXEEXT) $(AM_V_CXXLD)$(FuzzParseCompact_LINK) $(FuzzParseCompact_OBJECTS) $(FuzzParseCompact_LDADD) $(LIBS) FuzzParseJson$(EXEEXT): $(FuzzParseJson_OBJECTS) $(FuzzParseJson_DEPENDENCIES) $(EXTRA_FuzzParseJson_DEPENDENCIES) @rm -f FuzzParseJson$(EXEEXT) $(AM_V_CXXLD)$(FuzzParseJson_LINK) $(FuzzParseJson_OBJECTS) $(FuzzParseJson_LDADD) $(LIBS) FuzzRoundtripBinary$(EXEEXT): $(FuzzRoundtripBinary_OBJECTS) $(FuzzRoundtripBinary_DEPENDENCIES) $(EXTRA_FuzzRoundtripBinary_DEPENDENCIES) @rm -f FuzzRoundtripBinary$(EXEEXT) $(AM_V_CXXLD)$(FuzzRoundtripBinary_LINK) $(FuzzRoundtripBinary_OBJECTS) $(FuzzRoundtripBinary_LDADD) $(LIBS) FuzzRoundtripCompact$(EXEEXT): $(FuzzRoundtripCompact_OBJECTS) $(FuzzRoundtripCompact_DEPENDENCIES) $(EXTRA_FuzzRoundtripCompact_DEPENDENCIES) @rm -f FuzzRoundtripCompact$(EXEEXT) $(AM_V_CXXLD)$(FuzzRoundtripCompact_LINK) $(FuzzRoundtripCompact_OBJECTS) $(FuzzRoundtripCompact_LDADD) $(LIBS) FuzzRoundtripJson$(EXEEXT): $(FuzzRoundtripJson_OBJECTS) $(FuzzRoundtripJson_DEPENDENCIES) $(EXTRA_FuzzRoundtripJson_DEPENDENCIES) @rm -f FuzzRoundtripJson$(EXEEXT) $(AM_V_CXXLD)$(FuzzRoundtripJson_LINK) $(FuzzRoundtripJson_OBJECTS) $(FuzzRoundtripJson_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f gen-cpp/*.$(OBJEXT) -rm -f gen-cpp/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FuzzParseJson-FuzzParseJson.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/FuzzTest_types.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< FuzzParseBinary-FuzzParseBinary.o: FuzzParseBinary.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseBinary_CXXFLAGS) $(CXXFLAGS) -MT FuzzParseBinary-FuzzParseBinary.o -MD -MP -MF $(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Tpo -c -o FuzzParseBinary-FuzzParseBinary.o `test -f 'FuzzParseBinary.cpp' || echo '$(srcdir)/'`FuzzParseBinary.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Tpo $(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzParseBinary.cpp' object='FuzzParseBinary-FuzzParseBinary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseBinary_CXXFLAGS) $(CXXFLAGS) -c -o FuzzParseBinary-FuzzParseBinary.o `test -f 'FuzzParseBinary.cpp' || echo '$(srcdir)/'`FuzzParseBinary.cpp FuzzParseBinary-FuzzParseBinary.obj: FuzzParseBinary.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseBinary_CXXFLAGS) $(CXXFLAGS) -MT FuzzParseBinary-FuzzParseBinary.obj -MD -MP -MF $(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Tpo -c -o FuzzParseBinary-FuzzParseBinary.obj `if test -f 'FuzzParseBinary.cpp'; then $(CYGPATH_W) 'FuzzParseBinary.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzParseBinary.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Tpo $(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzParseBinary.cpp' object='FuzzParseBinary-FuzzParseBinary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseBinary_CXXFLAGS) $(CXXFLAGS) -c -o FuzzParseBinary-FuzzParseBinary.obj `if test -f 'FuzzParseBinary.cpp'; then $(CYGPATH_W) 'FuzzParseBinary.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzParseBinary.cpp'; fi` FuzzParseCompact-FuzzParseCompact.o: FuzzParseCompact.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseCompact_CXXFLAGS) $(CXXFLAGS) -MT FuzzParseCompact-FuzzParseCompact.o -MD -MP -MF $(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Tpo -c -o FuzzParseCompact-FuzzParseCompact.o `test -f 'FuzzParseCompact.cpp' || echo '$(srcdir)/'`FuzzParseCompact.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Tpo $(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzParseCompact.cpp' object='FuzzParseCompact-FuzzParseCompact.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseCompact_CXXFLAGS) $(CXXFLAGS) -c -o FuzzParseCompact-FuzzParseCompact.o `test -f 'FuzzParseCompact.cpp' || echo '$(srcdir)/'`FuzzParseCompact.cpp FuzzParseCompact-FuzzParseCompact.obj: FuzzParseCompact.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseCompact_CXXFLAGS) $(CXXFLAGS) -MT FuzzParseCompact-FuzzParseCompact.obj -MD -MP -MF $(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Tpo -c -o FuzzParseCompact-FuzzParseCompact.obj `if test -f 'FuzzParseCompact.cpp'; then $(CYGPATH_W) 'FuzzParseCompact.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzParseCompact.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Tpo $(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzParseCompact.cpp' object='FuzzParseCompact-FuzzParseCompact.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseCompact_CXXFLAGS) $(CXXFLAGS) -c -o FuzzParseCompact-FuzzParseCompact.obj `if test -f 'FuzzParseCompact.cpp'; then $(CYGPATH_W) 'FuzzParseCompact.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzParseCompact.cpp'; fi` FuzzParseJson-FuzzParseJson.o: FuzzParseJson.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseJson_CXXFLAGS) $(CXXFLAGS) -MT FuzzParseJson-FuzzParseJson.o -MD -MP -MF $(DEPDIR)/FuzzParseJson-FuzzParseJson.Tpo -c -o FuzzParseJson-FuzzParseJson.o `test -f 'FuzzParseJson.cpp' || echo '$(srcdir)/'`FuzzParseJson.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzParseJson-FuzzParseJson.Tpo $(DEPDIR)/FuzzParseJson-FuzzParseJson.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzParseJson.cpp' object='FuzzParseJson-FuzzParseJson.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseJson_CXXFLAGS) $(CXXFLAGS) -c -o FuzzParseJson-FuzzParseJson.o `test -f 'FuzzParseJson.cpp' || echo '$(srcdir)/'`FuzzParseJson.cpp FuzzParseJson-FuzzParseJson.obj: FuzzParseJson.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseJson_CXXFLAGS) $(CXXFLAGS) -MT FuzzParseJson-FuzzParseJson.obj -MD -MP -MF $(DEPDIR)/FuzzParseJson-FuzzParseJson.Tpo -c -o FuzzParseJson-FuzzParseJson.obj `if test -f 'FuzzParseJson.cpp'; then $(CYGPATH_W) 'FuzzParseJson.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzParseJson.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzParseJson-FuzzParseJson.Tpo $(DEPDIR)/FuzzParseJson-FuzzParseJson.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzParseJson.cpp' object='FuzzParseJson-FuzzParseJson.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzParseJson_CXXFLAGS) $(CXXFLAGS) -c -o FuzzParseJson-FuzzParseJson.obj `if test -f 'FuzzParseJson.cpp'; then $(CYGPATH_W) 'FuzzParseJson.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzParseJson.cpp'; fi` FuzzRoundtripBinary-FuzzRoundtripBinary.o: FuzzRoundtripBinary.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripBinary_CXXFLAGS) $(CXXFLAGS) -MT FuzzRoundtripBinary-FuzzRoundtripBinary.o -MD -MP -MF $(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Tpo -c -o FuzzRoundtripBinary-FuzzRoundtripBinary.o `test -f 'FuzzRoundtripBinary.cpp' || echo '$(srcdir)/'`FuzzRoundtripBinary.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Tpo $(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzRoundtripBinary.cpp' object='FuzzRoundtripBinary-FuzzRoundtripBinary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripBinary_CXXFLAGS) $(CXXFLAGS) -c -o FuzzRoundtripBinary-FuzzRoundtripBinary.o `test -f 'FuzzRoundtripBinary.cpp' || echo '$(srcdir)/'`FuzzRoundtripBinary.cpp FuzzRoundtripBinary-FuzzRoundtripBinary.obj: FuzzRoundtripBinary.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripBinary_CXXFLAGS) $(CXXFLAGS) -MT FuzzRoundtripBinary-FuzzRoundtripBinary.obj -MD -MP -MF $(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Tpo -c -o FuzzRoundtripBinary-FuzzRoundtripBinary.obj `if test -f 'FuzzRoundtripBinary.cpp'; then $(CYGPATH_W) 'FuzzRoundtripBinary.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzRoundtripBinary.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Tpo $(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzRoundtripBinary.cpp' object='FuzzRoundtripBinary-FuzzRoundtripBinary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripBinary_CXXFLAGS) $(CXXFLAGS) -c -o FuzzRoundtripBinary-FuzzRoundtripBinary.obj `if test -f 'FuzzRoundtripBinary.cpp'; then $(CYGPATH_W) 'FuzzRoundtripBinary.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzRoundtripBinary.cpp'; fi` FuzzRoundtripCompact-FuzzRoundtripCompact.o: FuzzRoundtripCompact.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripCompact_CXXFLAGS) $(CXXFLAGS) -MT FuzzRoundtripCompact-FuzzRoundtripCompact.o -MD -MP -MF $(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Tpo -c -o FuzzRoundtripCompact-FuzzRoundtripCompact.o `test -f 'FuzzRoundtripCompact.cpp' || echo '$(srcdir)/'`FuzzRoundtripCompact.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Tpo $(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzRoundtripCompact.cpp' object='FuzzRoundtripCompact-FuzzRoundtripCompact.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripCompact_CXXFLAGS) $(CXXFLAGS) -c -o FuzzRoundtripCompact-FuzzRoundtripCompact.o `test -f 'FuzzRoundtripCompact.cpp' || echo '$(srcdir)/'`FuzzRoundtripCompact.cpp FuzzRoundtripCompact-FuzzRoundtripCompact.obj: FuzzRoundtripCompact.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripCompact_CXXFLAGS) $(CXXFLAGS) -MT FuzzRoundtripCompact-FuzzRoundtripCompact.obj -MD -MP -MF $(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Tpo -c -o FuzzRoundtripCompact-FuzzRoundtripCompact.obj `if test -f 'FuzzRoundtripCompact.cpp'; then $(CYGPATH_W) 'FuzzRoundtripCompact.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzRoundtripCompact.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Tpo $(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzRoundtripCompact.cpp' object='FuzzRoundtripCompact-FuzzRoundtripCompact.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripCompact_CXXFLAGS) $(CXXFLAGS) -c -o FuzzRoundtripCompact-FuzzRoundtripCompact.obj `if test -f 'FuzzRoundtripCompact.cpp'; then $(CYGPATH_W) 'FuzzRoundtripCompact.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzRoundtripCompact.cpp'; fi` FuzzRoundtripJson-FuzzRoundtripJson.o: FuzzRoundtripJson.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripJson_CXXFLAGS) $(CXXFLAGS) -MT FuzzRoundtripJson-FuzzRoundtripJson.o -MD -MP -MF $(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Tpo -c -o FuzzRoundtripJson-FuzzRoundtripJson.o `test -f 'FuzzRoundtripJson.cpp' || echo '$(srcdir)/'`FuzzRoundtripJson.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Tpo $(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzRoundtripJson.cpp' object='FuzzRoundtripJson-FuzzRoundtripJson.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripJson_CXXFLAGS) $(CXXFLAGS) -c -o FuzzRoundtripJson-FuzzRoundtripJson.o `test -f 'FuzzRoundtripJson.cpp' || echo '$(srcdir)/'`FuzzRoundtripJson.cpp FuzzRoundtripJson-FuzzRoundtripJson.obj: FuzzRoundtripJson.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripJson_CXXFLAGS) $(CXXFLAGS) -MT FuzzRoundtripJson-FuzzRoundtripJson.obj -MD -MP -MF $(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Tpo -c -o FuzzRoundtripJson-FuzzRoundtripJson.obj `if test -f 'FuzzRoundtripJson.cpp'; then $(CYGPATH_W) 'FuzzRoundtripJson.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzRoundtripJson.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Tpo $(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FuzzRoundtripJson.cpp' object='FuzzRoundtripJson-FuzzRoundtripJson.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(FuzzRoundtripJson_CXXFLAGS) $(CXXFLAGS) -c -o FuzzRoundtripJson-FuzzRoundtripJson.obj `if test -f 'FuzzRoundtripJson.cpp'; then $(CYGPATH_W) 'FuzzRoundtripJson.cpp'; else $(CYGPATH_W) '$(srcdir)/FuzzRoundtripJson.cpp'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf gen-cpp/.libs gen-cpp/_libs style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f gen-cpp/$(DEPDIR)/$(am__dirstamp) -rm -f gen-cpp/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Po -rm -f ./$(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Po -rm -f ./$(DEPDIR)/FuzzParseJson-FuzzParseJson.Po -rm -f ./$(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Po -rm -f ./$(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Po -rm -f ./$(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Po -rm -f gen-cpp/$(DEPDIR)/FuzzTest_types.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/FuzzParseBinary-FuzzParseBinary.Po -rm -f ./$(DEPDIR)/FuzzParseCompact-FuzzParseCompact.Po -rm -f ./$(DEPDIR)/FuzzParseJson-FuzzParseJson.Po -rm -f ./$(DEPDIR)/FuzzRoundtripBinary-FuzzRoundtripBinary.Po -rm -f ./$(DEPDIR)/FuzzRoundtripCompact-FuzzRoundtripCompact.Po -rm -f ./$(DEPDIR)/FuzzRoundtripJson-FuzzRoundtripJson.Po -rm -f gen-cpp/$(DEPDIR)/FuzzTest_types.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am style-am style-local tags tags-am \ uninstall uninstall-am .PRECIOUS: Makefile # Generate thrift files gen-cpp/FuzzTest_types.cpp gen-cpp/FuzzTest_types.h: $(top_srcdir)/test/FuzzTest.thrift $(THRIFT) --gen cpp $< # Ensure generated headers exist before compiling sources that include them FuzzParseCompact.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzParseBinary.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzRoundtripCompact.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzRoundtripBinary.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzParseJson.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzRoundtripJson.$(OBJEXT): gen-cpp/FuzzTest_types.h # Clean target clean-local: $(RM) -rf gen-cpp $(RM) -f $(check_PROGRAMS) $(RM) -f *.o *.lo *.la $(RM) -rf .libs # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/cpp/test/fuzz/Makefile.am0000664000175000017500000000756215170007142020726 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc noinst_LTLIBRARIES = libfuzztest_gen.la nodist_libfuzztest_gen_la_SOURCES = \ gen-cpp/FuzzTest_types.cpp \ gen-cpp/FuzzTest_types.h libfuzztest_gen_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la # Common fuzzing headers noinst_HEADERS = FuzzCommon.tcc # Fuzzing executables AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/src -I$(top_srcdir)/lib/cpp/src/thrift -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. check_PROGRAMS = FuzzParseCompact FuzzParseBinary FuzzRoundtripCompact FuzzRoundtripBinary FuzzParseJson FuzzRoundtripJson FuzzParseCompact_SOURCES = FuzzParseCompact.cpp FuzzCommon.tcc FuzzParseCompact_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzParseCompact_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g if USING_CLANG FuzzParseCompact_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer endif FuzzRoundtripCompact_SOURCES = FuzzRoundtripCompact.cpp FuzzCommon.tcc FuzzRoundtripCompact_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripCompact_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g if USING_CLANG FuzzRoundtripCompact_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer endif FuzzParseBinary_SOURCES = FuzzParseBinary.cpp FuzzCommon.tcc FuzzParseBinary_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzParseBinary_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g if USING_CLANG FuzzParseBinary_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer endif FuzzRoundtripBinary_SOURCES = FuzzRoundtripBinary.cpp FuzzCommon.tcc FuzzRoundtripBinary_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripBinary_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g if USING_CLANG FuzzRoundtripBinary_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer endif FuzzParseJson_SOURCES = FuzzParseJson.cpp FuzzCommon.tcc FuzzParseJson_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzParseJson_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g if USING_CLANG FuzzParseJson_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer endif FuzzRoundtripJson_SOURCES = FuzzRoundtripJson.cpp FuzzCommon.tcc FuzzRoundtripJson_LDADD = libfuzztest_gen.la $(top_builddir)/lib/cpp/libthrift.la FuzzRoundtripJson_CXXFLAGS = $(AM_CXXFLAGS) $(AM_CPPFLAGS) -g if USING_CLANG FuzzRoundtripJson_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer endif # Generate thrift files gen-cpp/FuzzTest_types.cpp gen-cpp/FuzzTest_types.h: $(top_srcdir)/test/FuzzTest.thrift $(THRIFT) --gen cpp $< # Ensure generated headers exist before compiling sources that include them FuzzParseCompact.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzParseBinary.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzRoundtripCompact.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzRoundtripBinary.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzParseJson.$(OBJEXT): gen-cpp/FuzzTest_types.h FuzzRoundtripJson.$(OBJEXT): gen-cpp/FuzzTest_types.h # Clean target clean-local: $(RM) -rf gen-cpp $(RM) -f $(check_PROGRAMS) $(RM) -f *.o *.lo *.la $(RM) -rf .libs CLEANFILES = gen-cpp/* EXTRA_DIST = CMakeLists.txt FuzzParseCompact.cpp FuzzParseBinary.cpp FuzzRoundtripCompact.cpp FuzzRoundtripBinary.cpp FuzzParseJson.cpp FuzzRoundtripJson.cpp thrift-0.23.0/lib/cpp/test/OneWayTest.thrift0000664000175000017500000000273115165535636021173 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace c_glib OneWayTest namespace java onewaytest namespace cpp onewaytest namespace rb Onewaytest namespace perl OneWayTest namespace js OneWayTest namespace st OneWayTest namespace py OneWayTest namespace py.twisted OneWayTest namespace go onewaytest namespace php OneWayTest namespace delphi Onewaytest namespace lua OneWayTest namespace xsd test (uri = 'http://thrift.apache.org/ns/OneWayTest') // a minimal Thrift service, for use in OneWayHTTPTtest.cpp service OneWayService { void roundTripRPC(), oneway void oneWayRPC() } thrift-0.23.0/lib/cpp/test/OptionalRequiredTest.cpp0000664000175000017500000002473315165535636022547 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ #include #include #include #include #include "gen-cpp/OptionalRequiredTest_types.h" #define BOOST_TEST_MODULE OptionalRequiredTest #include using namespace thrift::test; using namespace apache::thrift; using namespace apache::thrift::transport; using namespace apache::thrift::protocol; /* template void trywrite(const Struct& s, bool should_work) { bool worked; try { TBinaryProtocol protocol(std::shared_ptr(new TMemoryBuffer)); s.write(&protocol); worked = true; } catch (TProtocolException & ex) { worked = false; } BOOST_CHECK(worked == should_work); } */ template void write_to_read(const Struct1& w, Struct2& r) { TBinaryProtocol protocol(std::shared_ptr(new TMemoryBuffer)); w.write(&protocol); r.read(&protocol); } BOOST_AUTO_TEST_CASE(test_optional_required_1) { OldSchool o; const std::string expected_result( "OldSchool {\n" " 01: im_int (i16) = 0,\n" " 02: im_str (string) = \"\",\n" " 03: im_big (list) = list[0] {\n" " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(o)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_2_1) { Simple s; const std::string expected_result( "Simple {\n" " 01: im_default (i16) = 0,\n" " 02: im_required (i16) = 0,\n" "}"); const std::string result(apache::thrift::ThriftDebugString(s)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_2_2) { Simple s; s.im_optional = 10; const std::string expected_result( "Simple {\n" " 01: im_default (i16) = 0,\n" " 02: im_required (i16) = 0,\n" "}"); const std::string result(apache::thrift::ThriftDebugString(s)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_2_3) { Simple s; s.im_optional = 10; s.__isset.im_optional = true; const std::string expected_result( "Simple {\n" " 01: im_default (i16) = 0,\n" " 02: im_required (i16) = 0,\n" " 03: im_optional (i16) = 10,\n" "}"); const std::string result(apache::thrift::ThriftDebugString(s)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_2_4) { Simple s; s.__isset.im_optional = true; const std::string expected_result( "Simple {\n" " 01: im_default (i16) = 0,\n" " 02: im_required (i16) = 0,\n" " 03: im_optional (i16) = 0,\n" "}"); const std::string result(apache::thrift::ThriftDebugString(s)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_2_5) { Simple s; s.__isset.im_optional = true; s.im_optional = 10; const std::string expected_result( "Simple {\n" " 01: im_default (i16) = 0,\n" " 02: im_required (i16) = 0,\n" " 03: im_optional (i16) = 10,\n" "}"); const std::string result(apache::thrift::ThriftDebugString(s)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_3) { // assign/copy-construct with non-required fields Simple s1, s2; s1.__isset.im_default = true; s1.__set_im_optional(10); BOOST_CHECK(s1.__isset.im_default); BOOST_CHECK(s1.__isset.im_optional); s2 = s1; BOOST_CHECK(s2.__isset.im_default); BOOST_CHECK(s2.__isset.im_optional); Simple s3(s1); BOOST_CHECK(s3.__isset.im_default); BOOST_CHECK(s3.__isset.im_optional); } BOOST_AUTO_TEST_CASE(test_optional_required_4) { // Write-to-read with optional fields. Simple s1, s2, s3; s1.im_optional = 10; BOOST_CHECK(!s1.__isset.im_default); // BOOST_CHECK(!s1.__isset.im_required); // Compile error. BOOST_CHECK(!s1.__isset.im_optional); write_to_read(s1, s2); BOOST_CHECK(s2.__isset.im_default); // BOOST_CHECK( s2.__isset.im_required); // Compile error. BOOST_CHECK(!s2.__isset.im_optional); BOOST_CHECK(s3.im_optional == 0); s1.__isset.im_optional = true; write_to_read(s1, s3); BOOST_CHECK(s3.__isset.im_default); // BOOST_CHECK( s3.__isset.im_required); // Compile error. BOOST_CHECK(s3.__isset.im_optional); BOOST_CHECK(s3.im_optional == 10); } BOOST_AUTO_TEST_CASE(test_optional_required_5) { // Writing between optional and default. Tricky1 t1; Tricky2 t2; t2.im_optional = 10; write_to_read(t2, t1); write_to_read(t1, t2); BOOST_CHECK(!t1.__isset.im_default); BOOST_CHECK(t2.__isset.im_optional); BOOST_CHECK(t1.im_default == t2.im_optional); BOOST_CHECK(t1.im_default == 0); } BOOST_AUTO_TEST_CASE(test_optional_required_6) { // Writing between default and required. Tricky1 t1; Tricky3 t3; write_to_read(t1, t3); write_to_read(t3, t1); BOOST_CHECK(t1.__isset.im_default); } BOOST_AUTO_TEST_CASE(test_optional_required_7) { // Writing between optional and required. Tricky2 t2; Tricky3 t3; t2.__isset.im_optional = true; write_to_read(t2, t3); write_to_read(t3, t2); } BOOST_AUTO_TEST_CASE(test_optional_required_8) { // Mu-hu-ha-ha-ha! Tricky2 t2; Tricky3 t3; try { write_to_read(t2, t3); abort(); } catch (const TProtocolException&) { } write_to_read(t3, t2); BOOST_CHECK(t2.__isset.im_optional); } BOOST_AUTO_TEST_CASE(test_optional_required_9) { Complex c; const std::string expected_result( "Complex {\n" " 01: cp_default (i16) = 0,\n" " 02: cp_required (i16) = 0,\n" " 04: the_map (map) = map[0] {\n" " },\n" " 05: req_simp (struct) = Simple {\n" " 01: im_default (i16) = 0,\n" " 02: im_required (i16) = 0,\n" " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(c)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_10) { Tricky1 t1; Tricky2 t2; // Compile error. //(void)(t1 == t2); } BOOST_AUTO_TEST_CASE(test_optional_required_11) { OldSchool o1, o2, o3; BOOST_CHECK(o1 == o2); o1.im_int = o2.im_int = 10; BOOST_CHECK(o1 == o2); o1.__isset.im_int = true; o2.__isset.im_int = false; BOOST_CHECK(o1 == o2); o1.im_int = 20; o1.__isset.im_int = false; BOOST_CHECK(o1 != o2); o1.im_int = 10; BOOST_CHECK(o1 == o2); o1.im_str = o2.im_str = "foo"; BOOST_CHECK(o1 == o2); o1.__isset.im_str = o2.__isset.im_str = true; BOOST_CHECK(o1 == o2); std::map mymap; mymap[1] = "bar"; mymap[2] = "baz"; o1.im_big.push_back(std::map()); BOOST_CHECK(o1 != o2); o2.im_big.push_back(std::map()); BOOST_CHECK(o1 == o2); o2.im_big.push_back(mymap); BOOST_CHECK(o1 != o2); o1.im_big.push_back(mymap); BOOST_CHECK(o1 == o2); TBinaryProtocol protocol(std::shared_ptr(new TMemoryBuffer)); o1.write(&protocol); o1.im_big.push_back(mymap); mymap[3] = "qux"; o2.im_big.push_back(mymap); BOOST_CHECK(o1 != o2); o1.im_big.back()[3] = "qux"; BOOST_CHECK(o1 == o2); o3.read(&protocol); o3.im_big.push_back(mymap); BOOST_CHECK(o1 == o3); const std::string expected_result( "OldSchool {\n" " 01: im_int (i16) = 10,\n" " 02: im_str (string) = \"foo\",\n" " 03: im_big (list) = list[3] {\n" " [0] = map[0] {\n" " },\n" " [1] = map[2] {\n" " 1 -> \"bar\",\n" " 2 -> \"baz\",\n" " },\n" " [2] = map[3] {\n" " 1 -> \"bar\",\n" " 2 -> \"baz\",\n" " 3 -> \"qux\",\n" " },\n" " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(o3)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } BOOST_AUTO_TEST_CASE(test_optional_required_12) { Tricky2 t1, t2; BOOST_CHECK(t1.__isset.im_optional == false); BOOST_CHECK(t2.__isset.im_optional == false); BOOST_CHECK(t1 == t2); t1.im_optional = 5; BOOST_CHECK(t1 == t2); t2.im_optional = 5; BOOST_CHECK(t1 == t2); t1.__isset.im_optional = true; BOOST_CHECK(t1 != t2); t2.__isset.im_optional = true; BOOST_CHECK(t1 == t2); t1.im_optional = 10; BOOST_CHECK(t1 != t2); t2.__isset.im_optional = false; BOOST_CHECK(t1 != t2); } BOOST_AUTO_TEST_CASE(test_optional_required_13) { OptionalDefault t1, t2; BOOST_CHECK(t1.__isset.opt_int == true); BOOST_CHECK(t1.__isset.opt_str == true); BOOST_CHECK(t1.opt_int == t2.opt_int); BOOST_CHECK(t1.opt_str == t2.opt_str); write_to_read(t1, t2); BOOST_CHECK(t2.__isset.opt_int == true); BOOST_CHECK(t2.__isset.opt_str == true); BOOST_CHECK(t1.opt_int == t2.opt_int); BOOST_CHECK(t1.opt_str == t2.opt_str); const std::string expected_result( "OptionalDefault {\n" " 01: opt_int (i16) = 1234,\n" " 02: opt_str (string) = \"default\",\n" "}"); const std::string result(apache::thrift::ThriftDebugString(t2)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } thrift-0.23.0/lib/cpp/test/CMakeLists.txt0000664000175000017500000003505315167543515020447 0ustar00buildbuild00000000000000# # 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 tests still require boost include(BoostMacros) REQUIRE_BOOST_HEADERS() set(BOOST_COMPONENTS filesystem thread unit_test_framework chrono) REQUIRE_BOOST_LIBRARIES(BOOST_COMPONENTS) include(ThriftMacros) # Make sure gen-cpp files can be included include_directories("${CMAKE_CURRENT_BINARY_DIR}") # Create the thrift C++ test library set(testgencpp_SOURCES gen-cpp/AnnotationTest_types.cpp gen-cpp/AnnotationTest_types.h gen-cpp/DebugProtoTest_types.cpp gen-cpp/DebugProtoTest_types.h gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h gen-cpp/OptionalRequiredTest_types.cpp gen-cpp/OptionalRequiredTest_types.h gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_types.h gen-cpp/OneWayTest_types.h gen-cpp/OneWayService.cpp 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 ) add_library(testgencpp STATIC ${testgencpp_SOURCES}) set(testgencpp_cob_SOURCES gen-cpp/ChildService.cpp gen-cpp/ChildService.h gen-cpp/EmptyService.cpp gen-cpp/EmptyService.h gen-cpp/ParentService.cpp gen-cpp/ParentService.h gen-cpp/proc_types.cpp gen-cpp/proc_types.h ) add_library(testgencpp_cob STATIC ${testgencpp_cob_SOURCES}) if (WIN32 AND MSVC) add_library(testgencppCLI STATIC ${testgencpp_SOURCES}) set_target_properties(testgencppCLI PROPERTIES COMMON_LANGUAGE_RUNTIME "") endif() add_executable(Benchmark Benchmark.cpp) target_link_libraries(Benchmark testgencpp) target_link_libraries(Benchmark thrift) add_test(NAME Benchmark COMMAND Benchmark) target_link_libraries(Benchmark testgencpp) set(UnitTest_SOURCES UnitTestMain.cpp OneWayHTTPTest.cpp TMemoryBufferTest.cpp TBufferBaseTest.cpp Base64Test.cpp ToStringTest.cpp TypedefTest.cpp TServerSocketTest.cpp TServerTransportTest.cpp ThrifttReadCheckTests.cpp TUuidTest.cpp Thrift5272.cpp ) add_executable(UnitTests ${UnitTest_SOURCES}) target_link_libraries(UnitTests testgencpp ${Boost_LIBRARIES}) target_link_libraries(UnitTests thrift) add_test(NAME UnitTests COMMAND UnitTests) if(MSVC) # Disable C4503: decorated name length exceeded, name was truncated # 'insanity' results in very long decorated names 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 TSSLSocketInterruptTest.cpp ) if (WIN32) list(APPEND TInterruptTest_SOURCES TPipeInterruptTest.cpp ) endif() add_executable(TInterruptTest ${TInterruptTest_SOURCES}) target_link_libraries(TInterruptTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(TInterruptTest thrift) 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") add_executable(TServerIntegrationTest TServerIntegrationTest.cpp) target_link_libraries(TServerIntegrationTest testgencpp_cob ${Boost_LIBRARIES} ) target_link_libraries(TServerIntegrationTest thrift) 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) if(WITH_ZLIB) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") add_executable(TransportTest TransportTest.cpp) target_link_libraries(TransportTest testgencpp ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ) target_link_libraries(TransportTest thrift) target_link_libraries(TransportTest thriftz) add_test(NAME TransportTest COMMAND TransportTest) add_executable(ZlibTest ZlibTest.cpp) target_link_libraries(ZlibTest testgencpp ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ) target_link_libraries(ZlibTest thrift) target_link_libraries(ZlibTest thriftz) add_test(NAME ZlibTest COMMAND ZlibTest) endif(WITH_ZLIB) add_executable(AnnotationTest AnnotationTest.cpp) target_link_libraries(AnnotationTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(AnnotationTest thrift) add_test(NAME AnnotationTest COMMAND AnnotationTest) add_executable(EnumTest EnumTest.cpp) target_link_libraries(EnumTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(EnumTest thrift) add_test(NAME EnumTest COMMAND EnumTest) if(HAVE_GETOPT_H) add_executable(TFileTransportTest TFileTransportTest.cpp) target_link_libraries(TFileTransportTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(TFileTransportTest thrift) add_test(NAME TFileTransportTest COMMAND TFileTransportTest) endif() add_executable(TFDTransportTest TFDTransportTest.cpp) target_link_libraries(TFDTransportTest ${Boost_LIBRARIES} ) target_link_libraries(TFDTransportTest thrift) add_test(NAME TFDTransportTest COMMAND TFDTransportTest) add_executable(TPipedTransportTest TPipedTransportTest.cpp) target_link_libraries(TPipedTransportTest ${Boost_LIBRARIES} ) target_link_libraries(TPipedTransportTest thrift) add_test(NAME TPipedTransportTest COMMAND TPipedTransportTest) set(AllProtocolsTest_SOURCES AllProtocolTests.cpp AllProtocolTests.tcc GenericHelpers.h ) add_executable(AllProtocolsTest ${AllProtocolsTest_SOURCES}) target_link_libraries(AllProtocolsTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(AllProtocolsTest thrift) add_test(NAME AllProtocolsTest COMMAND AllProtocolsTest) # The debug run-time in Windows asserts on isprint() with negative inputs if (NOT MSVC OR (MSVC AND CMAKE_BUILD_TYPE EQUAL "DEBUG")) add_executable(DebugProtoTest DebugProtoTest.cpp) target_link_libraries(DebugProtoTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(DebugProtoTest thrift) add_test(NAME DebugProtoTest COMMAND DebugProtoTest) endif() add_executable(JSONProtoTest JSONProtoTest.cpp) target_link_libraries(JSONProtoTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(JSONProtoTest thrift) add_test(NAME JSONProtoTest COMMAND JSONProtoTest) add_executable(OptionalRequiredTest OptionalRequiredTest.cpp) target_link_libraries(OptionalRequiredTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(OptionalRequiredTest thrift) add_test(NAME OptionalRequiredTest COMMAND OptionalRequiredTest) add_executable(RecursiveTest RecursiveTest.cpp) target_link_libraries(RecursiveTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(RecursiveTest thrift) add_test(NAME RecursiveTest COMMAND RecursiveTest) add_executable(SpecializationTest SpecializationTest.cpp) target_link_libraries(SpecializationTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(SpecializationTest thrift) add_test(NAME SpecializationTest COMMAND SpecializationTest) set(concurrency_test_SOURCES concurrency/Tests.cpp concurrency/ThreadFactoryTests.h concurrency/ThreadManagerTests.h concurrency/TimerManagerTests.h ) add_executable(concurrency_test ${concurrency_test_SOURCES}) target_link_libraries(concurrency_test thrift) add_test(NAME concurrency_test COMMAND concurrency_test) set(link_test_SOURCES link/LinkTest.cpp gen-cpp/ParentService.h link/TemplatedService1.cpp link/TemplatedService2.cpp ) add_executable(link_test ${link_test_SOURCES}) target_link_libraries(link_test testgencpp_cob) target_link_libraries(link_test thrift) target_link_libraries(link_test testgencpp) add_test(NAME link_test COMMAND link_test) if(WITH_LIBEVENT) set(processor_test_SOURCES processor/ProcessorTest.cpp processor/EventLog.cpp processor/ServerThread.cpp processor/EventLog.h processor/Handlers.h processor/ServerThread.h ) add_executable(processor_test ${processor_test_SOURCES}) target_link_libraries(processor_test testgencpp_cob ${Boost_LIBRARIES} ) target_link_libraries(processor_test thriftnb) add_test(NAME processor_test COMMAND processor_test) set(TNonblockingServerTest_SOURCES TNonblockingServerTest.cpp) add_executable(TNonblockingServerTest ${TNonblockingServerTest_SOURCES}) include_directories(${LIBEVENT_INCLUDE_DIRS}) target_link_libraries(TNonblockingServerTest testgencpp_cob ${Boost_LIBRARIES} ) target_link_libraries(TNonblockingServerTest thriftnb) add_test(NAME TNonblockingServerTest COMMAND TNonblockingServerTest) if(OPENSSL_FOUND AND WITH_OPENSSL) set(TNonblockingSSLServerTest_SOURCES TNonblockingSSLServerTest.cpp) add_executable(TNonblockingSSLServerTest ${TNonblockingSSLServerTest_SOURCES}) include_directories(${LIBEVENT_INCLUDE_DIRS}) target_link_libraries(TNonblockingSSLServerTest testgencpp_cob ${Boost_LIBRARIES} ) target_link_libraries(TNonblockingSSLServerTest thriftnb) add_test(NAME TNonblockingSSLServerTest COMMAND TNonblockingSSLServerTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys") endif(OPENSSL_FOUND AND WITH_OPENSSL) endif() if(OPENSSL_FOUND AND WITH_OPENSSL) add_executable(OpenSSLManualInitTest OpenSSLManualInitTest.cpp) target_link_libraries(OpenSSLManualInitTest ${OPENSSL_LIBRARIES} ${Boost_LIBRARIES} ) target_link_libraries(OpenSSLManualInitTest thrift) add_test(NAME OpenSSLManualInitTest COMMAND OpenSSLManualInitTest) add_executable(SecurityTest SecurityTest.cpp) target_link_libraries(SecurityTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(SecurityTest thrift) 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") add_executable(SecurityFromBufferTest SecurityFromBufferTest.cpp) target_link_libraries(SecurityFromBufferTest testgencpp ${Boost_LIBRARIES} ) target_link_libraries(SecurityFromBufferTest thrift) 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") endif() if(WITH_QT5) add_subdirectory(qt) endif() # # Common thrift code generation rules # # files from /test # add_custom_command(OUTPUT gen-cpp/AnnotationTest_constants.cpp gen-cpp/AnnotationTest_constants.h gen-cpp/AnnotationTest_types.cpp gen-cpp/AnnotationTest_types.h gen-cpp/foo_service.cpp gen-cpp/foo_service.h COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/AnnotationTest.thrift ) 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/DebugProtoTest.thrift ) add_custom_command(OUTPUT gen-cpp/EnumTest_types.cpp gen-cpp/EnumTest_types.h COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/EnumTest.thrift ) add_custom_command(OUTPUT gen-cpp/TypedefTest_types.cpp gen-cpp/TypedefTest_types.h COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/TypedefTest.thrift ) add_custom_command(OUTPUT gen-cpp/OptionalRequiredTest_types.cpp gen-cpp/OptionalRequiredTest_types.h COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/OptionalRequiredTest.thrift ) add_custom_command(OUTPUT gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/Recursive.thrift ) add_custom_command(OUTPUT gen-cpp/Service.cpp gen-cpp/StressTest_types.cpp COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/StressTest.thrift ) 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/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 ) thrift-0.23.0/lib/cpp/test/RecursiveTest.cpp0000664000175000017500000000533715165535636021227 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ #include "gen-cpp/Recursive_types.h" #include #include #include #define BOOST_TEST_MODULE RecursiveTest #include using apache::thrift::transport::TMemoryBuffer; using apache::thrift::protocol::TBinaryProtocol; using std::shared_ptr; BOOST_AUTO_TEST_CASE(test_recursive_1) { shared_ptr buf(new TMemoryBuffer()); shared_ptr prot(new TBinaryProtocol(buf)); RecTree tree; RecTree child; tree.children.push_back(child); tree.write(prot.get()); RecTree result; result.read(prot.get()); BOOST_CHECK(tree == result); } BOOST_AUTO_TEST_CASE(test_recursive_2) { shared_ptr buf(new TMemoryBuffer()); shared_ptr prot(new TBinaryProtocol(buf)); RecList l; shared_ptr l2(new RecList); l.nextitem = l2; l.write(prot.get()); RecList resultlist; resultlist.read(prot.get()); BOOST_CHECK(resultlist.nextitem != nullptr); BOOST_CHECK(resultlist.nextitem->nextitem == nullptr); } BOOST_AUTO_TEST_CASE(test_recursive_3) { shared_ptr buf(new TMemoryBuffer()); shared_ptr prot(new TBinaryProtocol(buf)); CoRec c; shared_ptr r(new CoRec2); c.other = r; c.write(prot.get()); c.read(prot.get()); BOOST_CHECK(c.other != nullptr); BOOST_CHECK(c.other->other.other == nullptr); } BOOST_AUTO_TEST_CASE(test_recursive_4) { shared_ptr buf(new TMemoryBuffer()); shared_ptr prot(new TBinaryProtocol(buf)); shared_ptr depthLimit(new RecList); depthLimit->nextitem = depthLimit; BOOST_CHECK_THROW(depthLimit->write(prot.get()), apache::thrift::protocol::TProtocolException); depthLimit->nextitem.reset(); } thrift-0.23.0/lib/cpp/test/TransportTest.cpp0000664000175000017500000011374615167543515021255 0ustar00buildbuild00000000000000/* * 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 #ifdef HAVE_SYS_SOCKET_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if _WIN32 #include #include #endif using namespace apache::thrift::transport; using namespace apache::thrift; static boost::mt19937 rng; void initrand(unsigned int seed) { rng.seed(seed); } class SizeGenerator { public: virtual ~SizeGenerator() = default; virtual uint32_t nextSize() = 0; virtual std::string describe() const = 0; }; class ConstantSizeGenerator : public SizeGenerator { public: ConstantSizeGenerator(uint32_t value) : value_(value) {} uint32_t nextSize() override { return value_; } std::string describe() const override { std::ostringstream desc; desc << value_; return desc.str(); } private: uint32_t value_; }; class RandomSizeGenerator : public SizeGenerator { public: RandomSizeGenerator(uint32_t min, uint32_t max) : generator_(rng, boost::uniform_int(min, max)) {} uint32_t nextSize() override { return generator_(); } std::string describe() const override { std::ostringstream desc; desc << "rand(" << getMin() << ", " << getMax() << ")"; return desc.str(); } uint32_t getMin() const { return (generator_.distribution().min)(); } uint32_t getMax() const { return (generator_.distribution().max)(); } private: boost::variate_generator > generator_; }; /** * This class exists solely to make the TEST_RW() macro easier to use. * - it can be constructed implicitly from an integer * - it can contain either a ConstantSizeGenerator or a RandomSizeGenerator * (TEST_RW can't take a SizeGenerator pointer or reference, since it needs * to make a copy of the generator to bind it to the test function.) */ class GenericSizeGenerator : public SizeGenerator { public: GenericSizeGenerator(uint32_t value) : generator_(new ConstantSizeGenerator(value)) {} GenericSizeGenerator(uint32_t min, uint32_t max) : generator_(new RandomSizeGenerator(min, max)) {} uint32_t nextSize() override { return generator_->nextSize(); } std::string describe() const override { return generator_->describe(); } private: std::shared_ptr generator_; }; /************************************************************************** * Classes to set up coupled transports **************************************************************************/ /** * Helper class to represent a coupled pair of transports. * * Data written to the out transport can be read from the in transport. * * This is used as the base class for the various coupled transport * implementations. It shouldn't be instantiated directly. */ template class CoupledTransports { public: virtual ~CoupledTransports() = default; typedef Transport_ TransportType; CoupledTransports() : in(), out() {} std::shared_ptr in; std::shared_ptr out; private: CoupledTransports(const CoupledTransports&) = delete; CoupledTransports& operator=(const CoupledTransports&) = delete; }; /** * Coupled TMemoryBuffers */ class CoupledMemoryBuffers : public CoupledTransports { public: CoupledMemoryBuffers() : buf(new TMemoryBuffer) { in = buf; out = buf; } std::shared_ptr buf; }; /** * Helper template class for creating coupled transports that wrap * another transport. */ template class CoupledWrapperTransportsT : public CoupledTransports { public: CoupledWrapperTransportsT() { if (inner_.in) { this->in.reset(new WrapperTransport_(inner_.in)); } if (inner_.out) { this->out.reset(new WrapperTransport_(inner_.out)); } } InnerCoupledTransports_ inner_; }; /** * Coupled TBufferedTransports. */ template class CoupledBufferedTransportsT : public CoupledWrapperTransportsT {}; typedef CoupledBufferedTransportsT CoupledBufferedTransports; /** * Coupled TFramedTransports. */ template class CoupledFramedTransportsT : public CoupledWrapperTransportsT {}; typedef CoupledFramedTransportsT CoupledFramedTransports; /** * Coupled TZlibTransports. */ template class CoupledZlibTransportsT : public CoupledWrapperTransportsT {}; typedef CoupledZlibTransportsT CoupledZlibTransports; #ifndef _WIN32 // FD transport doesn't make much sense on Windows. /** * Coupled TFDTransports. */ class CoupledFDTransports : public CoupledTransports { public: CoupledFDTransports() { int pipes[2]; if (pipe(pipes) != 0) { return; } in.reset(new TFDTransport(pipes[0], TFDTransport::CLOSE_ON_DESTROY)); out.reset(new TFDTransport(pipes[1], TFDTransport::CLOSE_ON_DESTROY)); } }; #else /** * Coupled pipe transports */ class CoupledPipeTransports : public CoupledTransports { public: HANDLE hRead; HANDLE hWrite; CoupledPipeTransports() { BOOST_REQUIRE(CreatePipe(&hRead, &hWrite, nullptr, 1048576 * 2)); in.reset(new TPipe(hRead, hWrite)); in->open(); out = in; } }; #endif /** * Coupled TSockets */ class CoupledSocketTransports : public CoupledTransports { public: CoupledSocketTransports() { THRIFT_SOCKET sockets[2] = {0}; if (THRIFT_SOCKETPAIR(PF_UNIX, SOCK_STREAM, 0, sockets) != 0) { return; } in.reset(new TSocket(sockets[0])); out.reset(new TSocket(sockets[1])); out->setSendTimeout(100); } }; // These could be made to work on Windows, but I don't care enough to make it happen #ifndef _WIN32 /** * Coupled TFileTransports */ class CoupledFileTransports : public CoupledTransports { public: CoupledFileTransports() { #ifndef _WIN32 const char* tmp_dir = "/tmp"; #define FILENAME_SUFFIX "/thrift.transport_test" #else const char* tmp_dir = getenv("TMP"); #define FILENAME_SUFFIX "\\thrift.transport_test" #endif // Create a temporary file to use filename.resize(strlen(tmp_dir) + strlen(FILENAME_SUFFIX)); THRIFT_SNPRINTF(&filename[0], filename.size(), "%s" FILENAME_SUFFIX, tmp_dir); #undef FILENAME_SUFFIX { std::ofstream dummy_creation(filename.c_str(), std::ofstream::trunc); } in.reset(new TFileTransport(filename, true)); out.reset(new TFileTransport(filename)); } ~CoupledFileTransports() override { remove(filename.c_str()); } std::string filename; }; #endif /** * Wrapper around another CoupledTransports implementation that exposes the * transports as TTransport pointers. * * This is used since accessing a transport via a "TTransport*" exercises a * different code path than using the base pointer class. As part of the * template code changes, most transport methods are no longer virtual. */ template class CoupledTTransports : public CoupledTransports { public: CoupledTTransports() : transports() { in = transports.in; out = transports.out; } CoupledTransports_ transports; }; /** * Wrapper around another CoupledTransports implementation that exposes the * transports as TBufferBase pointers. * * This can only be instantiated with a transport type that is a subclass of * TBufferBase. */ template class CoupledBufferBases : public CoupledTransports { public: CoupledBufferBases() : transports() { in = transports.in; out = transports.out; } CoupledTransports_ transports; }; /************************************************************************** * Alarm handling code for use in tests that check the transport blocking * semantics. * * If the transport ends up blocking, we don't want to hang forever. We use * SIGALRM to fire schedule signal to wake up and try to write data so the * transport will unblock. * * It isn't really the safest thing in the world to be mucking around with * complicated global data structures in a signal handler. It should probably * be okay though, since we know the main thread should always be blocked in a * read() request when the signal handler is running. **************************************************************************/ struct TriggerInfo { TriggerInfo(int seconds, const std::shared_ptr& transport, uint32_t writeLength) : timeoutSeconds(seconds), transport(transport), writeLength(writeLength), next(nullptr) {} int timeoutSeconds; std::shared_ptr transport; uint32_t writeLength; TriggerInfo* next; }; apache::thrift::concurrency::Monitor g_alarm_monitor; TriggerInfo* g_triggerInfo; unsigned int g_numTriggersFired; bool g_teardown = false; void alarm_handler() { TriggerInfo* info = nullptr; { apache::thrift::concurrency::Synchronized s(g_alarm_monitor); // The alarm timed out, which almost certainly means we're stuck // on a transport that is incorrectly blocked. ++g_numTriggersFired; // Note: we print messages to stdout instead of stderr, since // tools/test/runner only records stdout messages in the failure messages for // boost tests. (boost prints its test info to stdout.) printf("Timeout alarm expired; attempting to unblock transport\n"); if (g_triggerInfo == nullptr) { printf(" trigger stack is empty!\n"); } // Pop off the first TriggerInfo. // If there is another one, schedule an alarm for it. info = g_triggerInfo; g_triggerInfo = info->next; } // Write some data to the transport to hopefully unblock it. auto* buf = new uint8_t[info->writeLength]; memset(buf, 'b', info->writeLength); std::unique_ptr array(buf); info->transport->write(buf, info->writeLength); info->transport->flush(); delete info; } void alarm_handler_wrapper() { int64_t timeout = 0; // timeout of 0 means wait forever while (true) { bool fireHandler = false; { apache::thrift::concurrency::Synchronized s(g_alarm_monitor); if (g_teardown) return; // calculate timeout if (g_triggerInfo == nullptr) { timeout = 0; } else { timeout = g_triggerInfo->timeoutSeconds * 1000; } int waitResult = g_alarm_monitor.waitForTimeRelative(timeout); if (waitResult == THRIFT_ETIMEDOUT) fireHandler = true; } if (fireHandler) alarm_handler(); // calling outside the lock } } /** * Add a trigger to be scheduled "seconds" seconds after the * last currently scheduled trigger. * * (Note that this is not "seconds" from now. That might be more logical, but * would require slightly more complicated sorting, rather than just appending * to the end.) */ void add_trigger(unsigned int seconds, const std::shared_ptr& transport, uint32_t write_len) { auto* info = new TriggerInfo(seconds, transport, write_len); { apache::thrift::concurrency::Synchronized s(g_alarm_monitor); if (g_triggerInfo == nullptr) { // This is the first trigger. // Set g_triggerInfo, and schedule the alarm g_triggerInfo = info; g_alarm_monitor.notify(); } else { // Add this trigger to the end of the list TriggerInfo* prev = g_triggerInfo; while (prev->next) { prev = prev->next; } prev->next = info; } } } void clear_triggers() { TriggerInfo* info = nullptr; { apache::thrift::concurrency::Synchronized s(g_alarm_monitor); info = g_triggerInfo; g_triggerInfo = nullptr; g_numTriggersFired = 0; g_alarm_monitor.notify(); } while (info != nullptr) { TriggerInfo* next = info->next; delete info; info = next; } } void set_trigger(unsigned int seconds, const std::shared_ptr& transport, uint32_t write_len) { clear_triggers(); add_trigger(seconds, transport, write_len); } /************************************************************************** * Test functions **************************************************************************/ /** * Test interleaved write and read calls. * * Generates a buffer totalSize bytes long, then writes it to the transport, * and verifies the written data can be read back correctly. * * Mode of operation: * - call wChunkGenerator to figure out how large of a chunk to write * - call wSizeGenerator to get the size for individual write() calls, * and do this repeatedly until the entire chunk is written. * - call rChunkGenerator to figure out how large of a chunk to read * - call rSizeGenerator to get the size for individual read() calls, * and do this repeatedly until the entire chunk is read. * - repeat until the full buffer is written and read back, * then compare the data read back against the original buffer * * * - If any of the size generators return 0, this means to use the maximum * possible size. * * - If maxOutstanding is non-zero, write chunk sizes will be chosen such that * there are never more than maxOutstanding bytes waiting to be read back. */ template void test_rw(uint32_t totalSize, SizeGenerator& wSizeGenerator, SizeGenerator& rSizeGenerator, SizeGenerator& wChunkGenerator, SizeGenerator& rChunkGenerator, uint32_t maxOutstanding) { CoupledTransports transports; BOOST_REQUIRE(transports.in != nullptr); BOOST_REQUIRE(transports.out != nullptr); boost::shared_array wbuf = boost::shared_array(new uint8_t[totalSize]); boost::shared_array rbuf = boost::shared_array(new uint8_t[totalSize]); // store some data in wbuf for (uint32_t n = 0; n < totalSize; ++n) { wbuf[n] = (n & 0xff); } // clear rbuf memset(rbuf.get(), 0, totalSize); uint32_t total_written = 0; uint32_t total_read = 0; while (total_read < totalSize) { // Determine how large a chunk of data to write uint32_t wchunk_size = wChunkGenerator.nextSize(); if (wchunk_size == 0 || wchunk_size > totalSize - total_written) { wchunk_size = totalSize - total_written; } // Make sure (total_written - total_read) + wchunk_size // is less than maxOutstanding if (maxOutstanding > 0 && wchunk_size > maxOutstanding - (total_written - total_read)) { wchunk_size = maxOutstanding - (total_written - total_read); } // Write the chunk uint32_t chunk_written = 0; while (chunk_written < wchunk_size) { uint32_t write_size = wSizeGenerator.nextSize(); if (write_size == 0 || write_size > wchunk_size - chunk_written) { write_size = wchunk_size - chunk_written; } try { transports.out->write(wbuf.get() + total_written, write_size); } catch (TTransportException& te) { if (te.getType() == TTransportException::TIMED_OUT) break; throw te; } chunk_written += write_size; total_written += write_size; } // Flush the data, so it will be available in the read transport // Don't flush if wchunk_size is 0. (This should only happen if // total_written == totalSize already, and we're only reading now.) if (wchunk_size > 0) { transports.out->flush(); } // Determine how large a chunk of data to read back uint32_t rchunk_size = rChunkGenerator.nextSize(); if (rchunk_size == 0 || rchunk_size > total_written - total_read) { rchunk_size = total_written - total_read; } // Read the chunk uint32_t chunk_read = 0; while (chunk_read < rchunk_size) { uint32_t read_size = rSizeGenerator.nextSize(); if (read_size == 0 || read_size > rchunk_size - chunk_read) { read_size = rchunk_size - chunk_read; } int bytes_read = -1; try { bytes_read = transports.in->read(rbuf.get() + total_read, read_size); } catch (TTransportException& e) { BOOST_FAIL("read(pos=" << total_read << ", size=" << read_size << ") threw exception \"" << e.what() << "\"; written so far: " << total_written << " / " << totalSize << " bytes"); } BOOST_REQUIRE_MESSAGE(bytes_read > 0, "read(pos=" << total_read << ", size=" << read_size << ") returned " << bytes_read << "; written so far: " << total_written << " / " << totalSize << " bytes"); chunk_read += bytes_read; total_read += bytes_read; } } // make sure the data read back is identical to the data written BOOST_CHECK_EQUAL(memcmp(rbuf.get(), wbuf.get(), totalSize), 0); } template void test_read_part_available() { CoupledTransports transports; BOOST_REQUIRE(transports.in != nullptr); BOOST_REQUIRE(transports.out != nullptr); uint8_t write_buf[16]; uint8_t read_buf[16]; memset(write_buf, 'a', sizeof(write_buf)); // Attemping to read 10 bytes when only 9 are available should return 9 // immediately. transports.out->write(write_buf, 9); transports.out->flush(); set_trigger(3, transports.out, 1); uint32_t bytes_read = transports.in->read(read_buf, 10); BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0); BOOST_CHECK_EQUAL(bytes_read, (uint32_t)9); clear_triggers(); } template void test_read_part_available_in_chunks() { CoupledTransports transports; BOOST_REQUIRE(transports.in != nullptr); BOOST_REQUIRE(transports.out != nullptr); uint8_t write_buf[16]; uint8_t read_buf[16]; memset(write_buf, 'a', sizeof(write_buf)); // Write 10 bytes (in a single frame, for transports that use framing) transports.out->write(write_buf, 10); transports.out->flush(); // Read 1 byte, to force the transport to read the frame uint32_t bytes_read = transports.in->read(read_buf, 1); BOOST_CHECK_EQUAL(bytes_read, 1u); // Read more than what is remaining and verify the transport does not block set_trigger(3, transports.out, 1); bytes_read = transports.in->read(read_buf, 10); BOOST_CHECK_EQUAL(g_numTriggersFired, 0u); BOOST_CHECK_EQUAL(bytes_read, 9u); clear_triggers(); } template void test_read_partial_midframe() { CoupledTransports transports; BOOST_REQUIRE(transports.in != nullptr); BOOST_REQUIRE(transports.out != nullptr); uint8_t write_buf[16]; uint8_t read_buf[16]; memset(write_buf, 'a', sizeof(write_buf)); // Attempt to read 10 bytes, when only 9 are available, but after we have // already read part of the data that is available. This exercises a // different code path for several of the transports. // // For transports that add their own framing (e.g., TFramedTransport and // TFileTransport), the two flush calls break up the data in to a 10 byte // frame and a 3 byte frame. The first read then puts us partway through the // first frame, and then we attempt to read past the end of that frame, and // through the next frame, too. // // For buffered transports that perform read-ahead (e.g., // TBufferedTransport), the read-ahead will most likely see all 13 bytes // written on the first read. The next read will then attempt to read past // the end of the read-ahead buffer. // // Flush 10 bytes, then 3 bytes. This creates 2 separate frames for // transports that track framing internally. transports.out->write(write_buf, 10); transports.out->flush(); transports.out->write(write_buf, 3); transports.out->flush(); // Now read 4 bytes, so that we are partway through the written data. uint32_t bytes_read = transports.in->read(read_buf, 4); BOOST_CHECK_EQUAL(bytes_read, (uint32_t)4); // Now attempt to read 10 bytes. Only 9 more are available. // // We should be able to get all 9 bytes, but it might take multiple read // calls, since it is valid for read() to return fewer bytes than requested. // (Most transports do immediately return 9 bytes, but the framing transports // tend to only return to the end of the current frame, which is 6 bytes in // this case.) uint32_t total_read = 0; while (total_read < 9) { set_trigger(3, transports.out, 1); bytes_read = transports.in->read(read_buf, 10); BOOST_REQUIRE_EQUAL(g_numTriggersFired, (unsigned int)0); BOOST_REQUIRE_GT(bytes_read, (uint32_t)0); total_read += bytes_read; BOOST_REQUIRE_LE(total_read, (uint32_t)9); } BOOST_CHECK_EQUAL(total_read, (uint32_t)9); clear_triggers(); } template void test_borrow_part_available() { CoupledTransports transports; BOOST_REQUIRE(transports.in != nullptr); BOOST_REQUIRE(transports.out != nullptr); uint8_t write_buf[16]; uint8_t read_buf[16]; memset(write_buf, 'a', sizeof(write_buf)); // Attemping to borrow 10 bytes when only 9 are available should return nullptr // immediately. transports.out->write(write_buf, 9); transports.out->flush(); set_trigger(3, transports.out, 1); uint32_t borrow_len = 10; const uint8_t* borrowed_buf = transports.in->borrow(read_buf, &borrow_len); BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0); BOOST_CHECK(borrowed_buf == nullptr); clear_triggers(); } template void test_read_none_available() { CoupledTransports transports; BOOST_REQUIRE(transports.in != nullptr); BOOST_REQUIRE(transports.out != nullptr); uint8_t read_buf[16]; // Attempting to read when no data is available should either block until // some data is available, or fail immediately. (e.g., TSocket blocks, // TMemoryBuffer just fails.) // // If the transport blocks, it should succeed once some data is available, // even if less than the amount requested becomes available. set_trigger(1, transports.out, 2); add_trigger(1, transports.out, 8); uint32_t bytes_read = transports.in->read(read_buf, 10); if (bytes_read == 0) { BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0); clear_triggers(); } else { BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)1); BOOST_CHECK_EQUAL(bytes_read, (uint32_t)2); } clear_triggers(); } template void test_borrow_none_available() { CoupledTransports transports; BOOST_REQUIRE(transports.in != nullptr); BOOST_REQUIRE(transports.out != nullptr); uint8_t write_buf[16]; memset(write_buf, 'a', sizeof(write_buf)); // Attempting to borrow when no data is available should fail immediately set_trigger(1, transports.out, 10); uint32_t borrow_len = 10; const uint8_t* borrowed_buf = transports.in->borrow(nullptr, &borrow_len); BOOST_CHECK(borrowed_buf == nullptr); BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0); clear_triggers(); } /************************************************************************** * Test case generation * * Pretty ugly and annoying. This would be much easier if we the unit test * framework didn't force each test to be a separate function. * - Writing a completely separate function definition for each of these would * result in a lot of repetitive boilerplate code. * - Combining many tests into a single function makes it more difficult to * tell precisely which tests failed. It also means you can't get a progress * update after each test, and the tests are already fairly slow. * - Similar registration could be achieved with BOOST_TEST_CASE_TEMPLATE, * but it requires a lot of awkward MPL code, and results in useless test * case names. (The names are generated from std::type_info::name(), which * is compiler-dependent. gcc returns mangled names.) **************************************************************************/ #define ADD_TEST_RW(CoupledTransports, totalSize, ...) \ addTestRW(BOOST_STRINGIZE(CoupledTransports), totalSize, __VA_ARGS__); #define TEST_RW(CoupledTransports, totalSize, ...) \ do { \ /* Add the test as specified, to test the non-virtual function calls */ \ ADD_TEST_RW(CoupledTransports, totalSize, __VA_ARGS__); \ /* \ * Also test using the transport as a TTransport*, to test \ * the read_virt()/write_virt() calls \ */ \ ADD_TEST_RW(CoupledTTransports, totalSize, __VA_ARGS__); \ /* Test wrapping the transport with TBufferedTransport */ \ ADD_TEST_RW(CoupledBufferedTransportsT, totalSize, __VA_ARGS__); \ /* Test wrapping the transport with TFramedTransports */ \ ADD_TEST_RW(CoupledFramedTransportsT, totalSize, __VA_ARGS__); \ /* Test wrapping the transport with TZlibTransport */ \ ADD_TEST_RW(CoupledZlibTransportsT, totalSize, __VA_ARGS__); \ } while (0) #define ADD_TEST_BLOCKING(CoupledTransports) \ addTestBlocking(BOOST_STRINGIZE(CoupledTransports)); #define TEST_BLOCKING_BEHAVIOR(CoupledTransports) \ ADD_TEST_BLOCKING(CoupledTransports); \ ADD_TEST_BLOCKING(CoupledTTransports); \ ADD_TEST_BLOCKING(CoupledBufferedTransportsT); \ ADD_TEST_BLOCKING(CoupledFramedTransportsT); \ ADD_TEST_BLOCKING(CoupledZlibTransportsT); class TransportTestGen { public: TransportTestGen(boost::unit_test::test_suite* suite, float sizeMultiplier) : suite_(suite), sizeMultiplier_(sizeMultiplier) {} void generate() { GenericSizeGenerator rand4k(1, 4096); /* * We do the basically the same set of tests for each transport type, * although we tweak the parameters in some places. */ // TMemoryBuffer tests TEST_RW(CoupledMemoryBuffers, 1024 * 1024, 0, 0); TEST_RW(CoupledMemoryBuffers, 1024 * 256, rand4k, rand4k); TEST_RW(CoupledMemoryBuffers, 1024 * 256, 167, 163); TEST_RW(CoupledMemoryBuffers, 1024 * 16, 1, 1); TEST_RW(CoupledMemoryBuffers, 1024 * 256, 0, 0, rand4k, rand4k); TEST_RW(CoupledMemoryBuffers, 1024 * 256, rand4k, rand4k, rand4k, rand4k); TEST_RW(CoupledMemoryBuffers, 1024 * 256, 167, 163, rand4k, rand4k); TEST_RW(CoupledMemoryBuffers, 1024 * 16, 1, 1, rand4k, rand4k); TEST_BLOCKING_BEHAVIOR(CoupledMemoryBuffers); #ifndef _WIN32 // TFDTransport tests // Since CoupledFDTransports tests with a pipe, writes will block // if there is too much outstanding unread data in the pipe. uint32_t fd_max_outstanding = 4096; TEST_RW(CoupledFDTransports, 1024 * 1024, 0, 0, 0, 0, fd_max_outstanding); TEST_RW(CoupledFDTransports, 1024 * 256, rand4k, rand4k, 0, 0, fd_max_outstanding); TEST_RW(CoupledFDTransports, 1024 * 256, 167, 163, 0, 0, fd_max_outstanding); TEST_RW(CoupledFDTransports, 1024 * 16, 1, 1, 0, 0, fd_max_outstanding); TEST_RW(CoupledFDTransports, 1024 * 256, 0, 0, rand4k, rand4k, fd_max_outstanding); TEST_RW(CoupledFDTransports, 1024 * 256, rand4k, rand4k, rand4k, rand4k, fd_max_outstanding); TEST_RW(CoupledFDTransports, 1024 * 256, 167, 163, rand4k, rand4k, fd_max_outstanding); TEST_RW(CoupledFDTransports, 1024 * 16, 1, 1, rand4k, rand4k, fd_max_outstanding); TEST_BLOCKING_BEHAVIOR(CoupledFDTransports); #else // TPipe tests (WIN32 only) TEST_RW(CoupledPipeTransports, 1024 * 1024, 0, 0); TEST_RW(CoupledPipeTransports, 1024 * 256, rand4k, rand4k); TEST_RW(CoupledPipeTransports, 1024 * 256, 167, 163); TEST_RW(CoupledPipeTransports, 1024 * 16, 1, 1); TEST_RW(CoupledPipeTransports, 1024 * 256, 0, 0, rand4k, rand4k); TEST_RW(CoupledPipeTransports, 1024 * 256, rand4k, rand4k, rand4k, rand4k); TEST_RW(CoupledPipeTransports, 1024 * 256, 167, 163, rand4k, rand4k); TEST_RW(CoupledPipeTransports, 1024 * 16, 1, 1, rand4k, rand4k); TEST_BLOCKING_BEHAVIOR(CoupledPipeTransports); #endif //_WIN32 // TSocket tests uint32_t socket_max_outstanding = 4096; TEST_RW(CoupledSocketTransports, 1024 * 1024, 0, 0, 0, 0, socket_max_outstanding); TEST_RW(CoupledSocketTransports, 1024 * 256, rand4k, rand4k, 0, 0, socket_max_outstanding); TEST_RW(CoupledSocketTransports, 1024 * 256, 167, 163, 0, 0, socket_max_outstanding); // Doh. Apparently writing to a socket has some additional overhead for // each send() call. If we have more than ~400 outstanding 1-byte write // requests, additional send() calls start blocking. TEST_RW(CoupledSocketTransports, 1024 * 16, 1, 1, 0, 0, socket_max_outstanding); TEST_RW(CoupledSocketTransports, 1024 * 256, 0, 0, rand4k, rand4k, socket_max_outstanding); TEST_RW(CoupledSocketTransports, 1024 * 256, rand4k, rand4k, rand4k, rand4k, socket_max_outstanding); TEST_RW(CoupledSocketTransports, 1024 * 256, 167, 163, rand4k, rand4k, socket_max_outstanding); TEST_RW(CoupledSocketTransports, 1024 * 16, 1, 1, rand4k, rand4k, socket_max_outstanding); TEST_BLOCKING_BEHAVIOR(CoupledSocketTransports); // These could be made to work on Windows, but I don't care enough to make it happen #ifndef _WIN32 // TFileTransport tests // We use smaller buffer sizes here, since TFileTransport is fairly slow. // // TFileTransport can't write more than 16MB at once uint32_t max_write_at_once = 1024 * 1024 * 16 - 4; TEST_RW(CoupledFileTransports, 1024 * 1024, max_write_at_once, 0); TEST_RW(CoupledFileTransports, 1024 * 128, rand4k, rand4k); TEST_RW(CoupledFileTransports, 1024 * 128, 167, 163); TEST_RW(CoupledFileTransports, 1024 * 2, 1, 1); TEST_RW(CoupledFileTransports, 1024 * 64, 0, 0, rand4k, rand4k); TEST_RW(CoupledFileTransports, 1024 * 64, rand4k, rand4k, rand4k, rand4k); TEST_RW(CoupledFileTransports, 1024 * 64, 167, 163, rand4k, rand4k); TEST_RW(CoupledFileTransports, 1024 * 2, 1, 1, rand4k, rand4k); TEST_BLOCKING_BEHAVIOR(CoupledFileTransports); #endif // Add some tests that access TBufferedTransport and TFramedTransport // via TTransport pointers and TBufferBase pointers. ADD_TEST_RW(CoupledTTransports, 1024 * 1024, rand4k, rand4k, rand4k, rand4k); ADD_TEST_RW(CoupledBufferBases, 1024 * 1024, rand4k, rand4k, rand4k, rand4k); ADD_TEST_RW(CoupledTTransports, 1024 * 1024, rand4k, rand4k, rand4k, rand4k); ADD_TEST_RW(CoupledBufferBases, 1024 * 1024, rand4k, rand4k, rand4k, rand4k); // Test using TZlibTransport via a TTransport pointer ADD_TEST_RW(CoupledTTransports, 1024 * 1024, rand4k, rand4k, rand4k, rand4k); } #if (BOOST_VERSION >= 105900) #define MAKE_TEST_CASE(_FUNC, _NAME) boost::unit_test::make_test_case(_FUNC, _NAME, __FILE__, __LINE__) #else #define MAKE_TEST_CASE(_FUNC, _NAME) boost::unit_test::make_test_case(_FUNC, _NAME) #endif private: template void addTestRW(const char* transport_name, uint32_t totalSize, GenericSizeGenerator wSizeGen, GenericSizeGenerator rSizeGen, GenericSizeGenerator wChunkSizeGen = 0, GenericSizeGenerator rChunkSizeGen = 0, uint32_t maxOutstanding = 0, uint32_t expectedFailures = 0) { // adjust totalSize by the specified sizeMultiplier_ first totalSize = static_cast(totalSize * sizeMultiplier_); std::ostringstream name; name << transport_name << "::test_rw(" << totalSize << ", " << wSizeGen.describe() << ", " << rSizeGen.describe() << ", " << wChunkSizeGen.describe() << ", " << rChunkSizeGen.describe() << ", " << maxOutstanding << ")"; #if (BOOST_VERSION >= 105900) std::function test_func #else boost::unit_test::callback0<> test_func #endif = std::bind(test_rw, totalSize, wSizeGen, rSizeGen, wChunkSizeGen, rChunkSizeGen, maxOutstanding); suite_->add(MAKE_TEST_CASE(test_func, name.str()), expectedFailures); } template void addTestBlocking(const char* transportName, uint32_t expectedFailures = 0) { char name[1024]; THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_part_available()", transportName); suite_->add(MAKE_TEST_CASE(test_read_part_available, name), expectedFailures); THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_part_available_in_chunks()", transportName); suite_->add(MAKE_TEST_CASE(test_read_part_available_in_chunks, name), expectedFailures); THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_partial_midframe()", transportName); suite_->add(MAKE_TEST_CASE(test_read_partial_midframe, name), expectedFailures); THRIFT_SNPRINTF(name, sizeof(name), "%s::test_read_none_available()", transportName); suite_->add(MAKE_TEST_CASE(test_read_none_available, name), expectedFailures); THRIFT_SNPRINTF(name, sizeof(name), "%s::test_borrow_part_available()", transportName); suite_->add(MAKE_TEST_CASE(test_borrow_part_available, name), expectedFailures); THRIFT_SNPRINTF(name, sizeof(name), "%s::test_borrow_none_available()", transportName); suite_->add(MAKE_TEST_CASE(test_borrow_none_available, name), expectedFailures); } boost::unit_test::test_suite* suite_; // sizeMultiplier_ is configurable via the command line, and allows the // user to adjust between smaller buffers that can be tested quickly, // or larger buffers that more thoroughly exercise the code, but take // longer. float sizeMultiplier_; }; /************************************************************************** * General Initialization **************************************************************************/ struct global_fixture { std::shared_ptr alarmThread_; global_fixture() { #if _WIN32 apache::thrift::transport::TWinsockSingleton::create(); #endif apache::thrift::concurrency::ThreadFactory factory; factory.setDetached(false); alarmThread_ = factory.newThread( apache::thrift::concurrency::FunctionRunner::create(alarm_handler_wrapper)); alarmThread_->start(); } ~global_fixture() { { apache::thrift::concurrency::Synchronized s(g_alarm_monitor); g_teardown = true; g_alarm_monitor.notify(); } alarmThread_->join(); } }; #if (BOOST_VERSION >= 105900) BOOST_GLOBAL_FIXTURE(global_fixture); #else BOOST_GLOBAL_FIXTURE(global_fixture) #endif #ifdef BOOST_TEST_DYN_LINK bool init_unit_test_suite() { struct timeval tv; THRIFT_GETTIMEOFDAY(&tv, nullptr); int seed = tv.tv_sec ^ tv.tv_usec; initrand(seed); boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite(); suite->p_name.value = "TransportTest"; TransportTestGen transport_test_generator(suite, 1); transport_test_generator.generate(); return true; } int main( int argc, char* argv[] ) { return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv); } #else boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { THRIFT_UNUSED_VARIABLE(argc); THRIFT_UNUSED_VARIABLE(argv); struct timeval tv; THRIFT_GETTIMEOFDAY(&tv, nullptr); int seed = tv.tv_sec ^ tv.tv_usec; initrand(seed); boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite(); suite->p_name.value = "TransportTest"; TransportTestGen transport_test_generator(suite, 1); transport_test_generator.generate(); return nullptr; } #endif thrift-0.23.0/lib/cpp/test/ThrifttReadCheckTests.cpp0000664000175000017500000002455415165535636022623 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define MAX_MESSAGE_SIZE 2 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include BOOST_AUTO_TEST_SUITE(ThriftReadCheckExceptionTest) using apache::thrift::TConfiguration; using apache::thrift::protocol::TBinaryProtocol; using apache::thrift::protocol::TCompactProtocol; using apache::thrift::protocol::TJSONProtocol; using apache::thrift::protocol::TType; using apache::thrift::transport::TPipedTransport; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TSimpleFileTransport; using apache::thrift::transport::TFileTransport; using apache::thrift::transport::TFDTransport; using apache::thrift::transport::TTransportException; using apache::thrift::transport::TBufferedTransport; using apache::thrift::transport::TFramedTransport; using std::shared_ptr; using std::string; using std::memset; using namespace apache::thrift; using namespace apache::thrift::protocol; BOOST_AUTO_TEST_CASE(test_tmemorybuffer_read_check_exception) { std::shared_ptr config(new TConfiguration(MAX_MESSAGE_SIZE)); TMemoryBuffer trans_out(config); uint8_t buffer[6] = {1, 2, 3, 4, 5, 6}; trans_out.write((const uint8_t*)buffer, sizeof(buffer)); trans_out.close(); TMemoryBuffer trans_in(config); memset(buffer, 0, sizeof(buffer)); BOOST_CHECK_THROW(trans_in.read(buffer, sizeof(buffer)), TTransportException); trans_in.close(); } BOOST_AUTO_TEST_CASE(test_tpipedtransport_read_check_exception) { std::shared_ptr config(new TConfiguration(MAX_MESSAGE_SIZE)); std::shared_ptr pipe(new TMemoryBuffer); std::shared_ptr underlying(new TMemoryBuffer); std::shared_ptr trans(new TPipedTransport(underlying, pipe, config)); uint8_t buffer[4]; underlying->write((uint8_t*)"abcd", 4); BOOST_CHECK_THROW(trans->read(buffer, sizeof(buffer)), TTransportException); BOOST_CHECK_THROW(trans->readAll(buffer, sizeof(buffer)), TTransportException); trans->readEnd(); pipe->resetBuffer(); underlying->write((uint8_t*)"ef", 2); BOOST_CHECK_THROW(trans->read(buffer, sizeof(buffer)), TTransportException); BOOST_CHECK_THROW(trans->readAll(buffer, sizeof(buffer)), TTransportException); trans->readEnd(); } BOOST_AUTO_TEST_CASE(test_tsimplefiletransport_read_check_exception) { std::shared_ptr config(new TConfiguration(MAX_MESSAGE_SIZE)); TSimpleFileTransport trans_out("data", false, true, config); uint8_t buffer[6] = {1, 2, 3, 4, 5, 6}; trans_out.write((const uint8_t*)buffer, sizeof(buffer)); trans_out.close(); TSimpleFileTransport trans_in("data",true, false, config); memset(buffer, 0, sizeof(buffer)); BOOST_CHECK_THROW(trans_in.read(buffer, sizeof(buffer)), TTransportException); trans_in.close(); remove("./data"); } BOOST_AUTO_TEST_CASE(test_tfiletransport_read_check_exception) { std::shared_ptr config(new TConfiguration(MAX_MESSAGE_SIZE)); TFileTransport trans_out("data", false, config); uint8_t buffer[6] = {1, 2, 3, 4, 5, 6}; trans_out.write((const uint8_t*)buffer, sizeof(buffer)); TFileTransport trans_in("data", false, config); memset(buffer, 0, sizeof(buffer)); BOOST_CHECK_THROW(trans_in.read(buffer, sizeof(buffer)), TTransportException); remove("./data"); } BOOST_AUTO_TEST_CASE(test_tbufferedtransport_read_check_exception) { uint8_t arr[4] = {1, 2, 3, 4}; std::shared_ptr buffer (new TMemoryBuffer(arr, sizeof(arr))); std::shared_ptr config (new TConfiguration(MAX_MESSAGE_SIZE)); std::shared_ptr trans (new TBufferedTransport(buffer, config)); trans->write((const uint8_t*)arr, sizeof(arr)); BOOST_CHECK_THROW(trans->read(arr, sizeof(arr)), TTransportException); } BOOST_AUTO_TEST_CASE(test_tframedtransport_read_check_exception) { uint8_t arr[4] = {1, 2, 3, 4}; std::shared_ptr buffer (new TMemoryBuffer(arr, sizeof(arr))); std::shared_ptr config (new TConfiguration(MAX_MESSAGE_SIZE)); std::shared_ptr trans (new TFramedTransport(buffer, config)); trans->write((const uint8_t*)arr, sizeof(arr)); BOOST_CHECK_THROW(trans->read(arr, sizeof(arr)), TTransportException); } BOOST_AUTO_TEST_CASE(test_tthriftbinaryprotocol_read_check_exception) { std::shared_ptr config (new TConfiguration(MAX_MESSAGE_SIZE)); std::shared_ptr transport(new TMemoryBuffer(config)); std::shared_ptr protocol(new TBinaryProtocol(transport)); uint32_t val = 0; TType elemType = apache::thrift::protocol::T_STOP; TType elemType1 = apache::thrift::protocol::T_STOP; TList list(T_I32, 8); protocol->writeListBegin(list.elemType_, list.size_); protocol->writeListEnd(); BOOST_CHECK_THROW(protocol->readListBegin(elemType, val), TTransportException); protocol->readListEnd(); TSet set(T_I32, 8); 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); protocol->writeMapBegin(map.keyType_, map.valueType_, map.size_); protocol->writeMapEnd(); BOOST_CHECK_THROW(protocol->readMapBegin(elemType, elemType1, val), TTransportException); protocol->readMapEnd(); } BOOST_AUTO_TEST_CASE(test_tthriftcompactprotocol_read_check_exception) { // 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; // 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(); // 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(); // 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) { std::shared_ptr config (new TConfiguration(MAX_MESSAGE_SIZE)); std::shared_ptr transport(new TMemoryBuffer(config)); std::shared_ptr protocol(new TJSONProtocol(transport)); uint32_t val = 0; TType elemType = apache::thrift::protocol::T_STOP; TType elemType1 = apache::thrift::protocol::T_STOP; TList list(T_I32, 8); protocol->writeListBegin(list.elemType_, list.size_); protocol->writeListEnd(); BOOST_CHECK_THROW(protocol->readListBegin(elemType, val), TTransportException); protocol->readListEnd(); TSet set(T_I32, 8); 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); protocol->writeMapBegin(map.keyType_, map.valueType_, map.size_); protocol->writeMapEnd(); BOOST_CHECK_THROW(protocol->readMapBegin(elemType, elemType1, val), TTransportException); protocol->readMapEnd(); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/DebugProtoTest_extras.cpp0000664000175000017500000000210215165535636022703 0ustar00buildbuild00000000000000/* * 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. */ // Extra functions required for DebugProtoTest_types to work #include "gen-cpp/DebugProtoTest_types.h" namespace thrift { namespace test { namespace debug { bool Empty::operator<(Empty const& other) const { (void)other; // It is empty, so all are equal. return false; } } } } thrift-0.23.0/lib/cpp/test/TTransportCheckThrow.h0000664000175000017500000000544015165535636022162 0ustar00buildbuild00000000000000/* * 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. */ #pragma once #define TTRANSPORT_CHECK_THROW(_CALL, _TYPE) \ { \ bool caught = false; \ try { \ (_CALL); \ } catch (TTransportException & ex) { \ BOOST_CHECK_EQUAL(ex.getType(), _TYPE); \ caught = true; \ } \ BOOST_CHECK_MESSAGE(caught, "expected TTransportException but nothing was thrown"); \ } #define TTRANSPORT_REQUIRE_THROW(_CALL, _TYPE) \ { \ bool caught = false; \ try { \ (_CALL); \ } catch (TTransportException & ex) { \ BOOST_REQUIRE_EQUAL(ex.getType(), _TYPE); \ caught = true; \ } \ BOOST_REQUIRE_MESSAGE(caught, "expected TTransportException but nothing was thrown"); \ } thrift-0.23.0/lib/cpp/test/TMemoryBufferTest.cpp0000664000175000017500000003037715165535636022010 0ustar00buildbuild00000000000000/* * 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 #include #include #include #include #include #include "gen-cpp/ThriftTest_types.h" BOOST_AUTO_TEST_SUITE(TMemoryBufferTest) using apache::thrift::protocol::TBinaryProtocol; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::transport::TTransportException; using std::shared_ptr; using std::string; BOOST_AUTO_TEST_CASE(test_read_write_grow) { // Added to test the fix for THRIFT-1248 TMemoryBuffer uut; const int maxSize = 65536; uint8_t verify[maxSize]; std::vector buf; buf.resize(maxSize); for (uint32_t i = 0; i < maxSize; ++i) { buf[i] = static_cast(i); } for (uint32_t i = 1; i < maxSize; i *= 2) { uut.write(&buf[0], i); } for (uint32_t i = 1; i < maxSize; i *= 2) { uut.read(verify, i); BOOST_CHECK_EQUAL(0, ::memcmp(verify, &buf[0], i)); } } BOOST_AUTO_TEST_CASE(test_roundtrip) { shared_ptr strBuffer(new TMemoryBuffer()); shared_ptr binaryProtcol(new TBinaryProtocol(strBuffer)); thrift::test::Xtruct a; a.i32_thing = 10; a.i64_thing = 30; a.string_thing = "holla back a"; a.write(binaryProtcol.get()); std::string serialized = strBuffer->getBufferAsString(); shared_ptr strBuffer2(new TMemoryBuffer()); shared_ptr binaryProtcol2(new TBinaryProtocol(strBuffer2)); strBuffer2->resetBuffer((uint8_t*)serialized.data(), static_cast(serialized.length())); thrift::test::Xtruct a2; a2.read(binaryProtcol2.get()); BOOST_CHECK(a == a2); } BOOST_AUTO_TEST_CASE(test_readAppendToString) { string str1 = "abcd1234"; TMemoryBuffer buf((uint8_t*)str1.data(), static_cast(str1.length()), TMemoryBuffer::COPY); string str3 = "wxyz", str4 = "6789"; buf.readAppendToString(str3, 4); buf.readAppendToString(str4, INT_MAX); BOOST_CHECK(str3 == "wxyzabcd"); BOOST_CHECK(str4 == "67891234"); } BOOST_AUTO_TEST_CASE(test_exceptions) { char data[] = "foo\0bar"; TMemoryBuffer buf1((uint8_t*)data, 7, TMemoryBuffer::OBSERVE); string str = buf1.getBufferAsString(); BOOST_CHECK(str.length() == 7); buf1.resetBuffer(); BOOST_CHECK_THROW(buf1.write((const uint8_t*)"foo", 3), TTransportException); TMemoryBuffer buf2((uint8_t*)data, 7, TMemoryBuffer::COPY); BOOST_CHECK_NO_THROW(buf2.write((const uint8_t*)"bar", 3)); } BOOST_AUTO_TEST_CASE(test_default_maximum_buffer_size) { BOOST_CHECK_EQUAL((std::numeric_limits::max)(), TMemoryBuffer().getMaxBufferSize()); } BOOST_AUTO_TEST_CASE(test_default_buffer_size) { BOOST_CHECK_EQUAL(1024, TMemoryBuffer().getBufferSize()); } BOOST_AUTO_TEST_CASE(test_error_set_max_buffer_size_too_small) { TMemoryBuffer buf; BOOST_CHECK_THROW(buf.setMaxBufferSize(buf.getBufferSize() - 1), TTransportException); } BOOST_AUTO_TEST_CASE(test_observe) { #ifdef _MSC_VER #define N 73 #else constexpr size_t N = 73; #endif constexpr size_t M = 42; uint8_t one_byte = 42; std::vector scratch; auto filler = [=]() { std::array x; // Fill buf_mem with a sequence from 0 to N - 1 std::iota(x.begin(), x.end(), 0); return x; }; static const std::array buf_mem = filler(); BOOST_STATIC_ASSERT(M < N); TMemoryBuffer buf((uint8_t*)&buf_mem.front(), N, TMemoryBuffer::MemoryPolicy::OBSERVE); // Readable BOOST_CHECK_EQUAL(N, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Not writeable BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); // Read some but not all scratch.resize(M); BOOST_CHECK_EQUAL(M, buf.read(&scratch[0], M)); // Check remaining BOOST_CHECK_EQUAL(N - M, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Not writeable BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); // Contents BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), buf_mem.begin() + M); // Readable (drain remaining) scratch.resize(N); BOOST_CHECK_EQUAL(N - M, buf.read(&scratch[M], N - M)); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Not writeable BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); // Contents BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), buf_mem.end()); // Not readable BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(0, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Not writeable BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); /* OBSERVE buffer cannot be reread with the default reset */ buf.resetBuffer(); // Not Readable BOOST_CHECK_EQUAL(0, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Not writeable BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); /* OBSERVE buffers do not auto-resize when written to (implicit) */ /* OBSERVE buffers can be appended-to (implicit) */ } BOOST_AUTO_TEST_CASE(test_copy) { #ifdef _MSC_VER #define N 73 #else constexpr size_t N = 73; #endif constexpr size_t M = 42; uint8_t one_byte = 42; std::vector scratch; auto filler = [&]() { std::array x; // Fill buf_mem with a sequence from 0 to N - 1 std::iota(x.begin(), x.end(), 0); return x; }; static const std::array buf_mem = filler(); BOOST_STATIC_ASSERT(M < N); TMemoryBuffer buf((uint8_t*)&buf_mem.front(), N, TMemoryBuffer::MemoryPolicy::COPY); // Readable BOOST_CHECK_EQUAL(N, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Read some but not all scratch.resize(M); BOOST_CHECK_EQUAL(M, buf.read(&scratch[0], M)); // Check remaining BOOST_CHECK_EQUAL(N - M, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Contents BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), buf_mem.begin() + M); // Readable (drain remaining) scratch.resize(N); BOOST_CHECK_EQUAL(N - M, buf.read(&scratch[M], N - M)); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Contents BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), buf_mem.end()); // Not readable BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(0, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); /* COPY buffer cannot be reread with the default reset */ buf.resetBuffer(); // Not readable BOOST_CHECK_EQUAL(0, buf.available_read()); // Has available write space BOOST_CHECK_EQUAL(N, buf.available_write()); /* COPY buffers auto-resize when written to */ // Not readable BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(0, buf.available_read()); // No available write space BOOST_CHECK_GT(buf.available_write(), 0); // Writeable one_byte = M; BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); // Readable one_byte = 0xff; BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(one_byte, M); /* COPY buffers can be appended-to (and auto-resize) */ buf.resetBuffer((uint8_t*)&buf_mem.front(), N, TMemoryBuffer::MemoryPolicy::COPY); // Appendable one_byte = N + 1; BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); BOOST_CHECK_EQUAL(N, buf.read(&scratch[0], N)); BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), buf_mem.begin() + N); one_byte = 0xff; BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(one_byte, N + 1); } BOOST_AUTO_TEST_CASE(test_take_ownership) { #ifdef _MSC_VER #define N 73 #else constexpr size_t N = 73; #endif constexpr size_t M = 42; uint8_t one_byte = 42; std::vector scratch; auto filler = [&]() { /* TAKE_OWNERSHIP buffers MUST be malloc'ed */ uint8_t* x = static_cast(malloc(N)); // Fill buf_mem with a sequence from 0 to N - 1 std::iota(&x[0], &x[N], 0); return x; }; uint8_t* buf_mem = filler(); BOOST_STATIC_ASSERT(M < N); TMemoryBuffer buf(buf_mem, N, TMemoryBuffer::MemoryPolicy::TAKE_OWNERSHIP); // Readable BOOST_CHECK_EQUAL(N, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Read some but not all scratch.resize(M); BOOST_CHECK_EQUAL(M, buf.read(&scratch[0], M)); // Check remaining BOOST_CHECK_EQUAL(N - M, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Contents BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), &buf_mem[0], &buf_mem[M]); // Readable (drain remaining) scratch.resize(N); BOOST_CHECK_EQUAL(N - M, buf.read(&scratch[M], N - M)); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); // Contents BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), &buf_mem[0], &buf_mem[N]); // Not readable BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(0, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(0, buf.available_write()); /* TAKE_OWNERSHIP buffers auto-resize when written to */ // Not readable BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(0, buf.available_read()); // No available write space BOOST_CHECK_EQUAL(buf.available_write(), 0); // Writeable one_byte = M; BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); // Readable one_byte = 0xff; BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(one_byte, M); /* TAKE_OWNERSHIP buffers can be appended-to (and auto-resize) */ buf_mem = filler(); buf.resetBuffer(buf_mem, N, TMemoryBuffer::MemoryPolicy::COPY); // Appendable one_byte = N + 1; BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); BOOST_CHECK_EQUAL(N, buf.read(&scratch[0], N)); BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), &buf_mem[0], &buf_mem[N]); one_byte = 0xff; BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); BOOST_CHECK_EQUAL(one_byte, N + 1); } BOOST_AUTO_TEST_CASE(test_maximum_buffer_size) { TMemoryBuffer buf; buf.setMaxBufferSize(8192); std::vector small_buff(1); for (size_t i = 0; i < 8192; ++i) { buf.write(&small_buff[0], 1); } BOOST_CHECK_THROW(buf.write(&small_buff[0], 1), TTransportException); } BOOST_AUTO_TEST_CASE(test_buffer_overflow) { TMemoryBuffer buf; std::vector small_buff(1); buf.write(&small_buff[0], 1); BOOST_CHECK_THROW(buf.getWritePtr(std::numeric_limits::max()), TTransportException); } BOOST_AUTO_TEST_CASE(test_memory_buffer_to_get_sizeof_objects) { // This is a demonstration of how to use TMemoryBuffer to determine // the serialized size of a thrift object in the Binary protocol. // See THRIFT-3480 shared_ptr memBuffer(new TMemoryBuffer()); shared_ptr binaryProtcol(new TBinaryProtocol(memBuffer)); thrift::test::Xtruct object; object.i32_thing = 10; object.i64_thing = 30; object.string_thing = "who's your daddy?"; uint32_t size = object.write(binaryProtcol.get()); BOOST_CHECK_EQUAL(47, size); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/TPipedTransportTest.cpp0000664000175000017500000000367115165535636022361 0ustar00buildbuild00000000000000/* * 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 #define BOOST_TEST_MODULE TPipedTransportTest #include using apache::thrift::transport::TTransportException; using apache::thrift::transport::TPipedTransport; using apache::thrift::transport::TMemoryBuffer; using namespace apache::thrift; BOOST_AUTO_TEST_CASE(test_read_write) { std::shared_ptr underlying(new TMemoryBuffer); std::shared_ptr pipe(new TMemoryBuffer); std::shared_ptr trans(new TPipedTransport(underlying, pipe)); uint8_t buffer[4]; underlying->write((uint8_t*)"abcd", 4); trans->readAll(buffer, 2); BOOST_CHECK(std::string((char*)buffer, 2) == "ab"); trans->readEnd(); BOOST_CHECK(pipe->getBufferAsString() == "ab"); pipe->resetBuffer(); underlying->write((uint8_t*)"ef", 2); trans->readAll(buffer, 2); BOOST_CHECK(std::string((char*)buffer, 2) == "cd"); trans->readAll(buffer, 2); BOOST_CHECK(std::string((char*)buffer, 2) == "ef"); trans->readEnd(); BOOST_CHECK(pipe->getBufferAsString() == "cdef"); } thrift-0.23.0/lib/cpp/test/TFDTransportTest.cpp0000664000175000017500000000314315165535636021603 0ustar00buildbuild00000000000000/* * 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 #define BOOST_TEST_MODULE TFDTransportTest #include // Disabled on MSVC because the RTL asserts on an invalid file descriptor // in both debug and release mode; at least in MSVCR100 (Visual Studio 2010) #if !defined(WIN32) using apache::thrift::transport::TTransportException; using apache::thrift::transport::TFDTransport; BOOST_AUTO_TEST_CASE(test_tfdtransport_1) { BOOST_CHECK_NO_THROW(TFDTransport t(256, TFDTransport::CLOSE_ON_DESTROY)); } BOOST_AUTO_TEST_CASE(test_tfdtransport_2) { TFDTransport t(256, TFDTransport::CLOSE_ON_DESTROY); BOOST_CHECK_THROW(t.close(), TTransportException); } #else BOOST_AUTO_TEST_CASE(test_tfdtransport_dummy) { BOOST_CHECK(true); } #endif thrift-0.23.0/lib/cpp/test/TUuidTest.cpp0000664000175000017500000001456015165535636020310 0ustar00buildbuild00000000000000/* * 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() thrift-0.23.0/lib/cpp/test/TUuidTestBoostNoDirective.cpp0000664000175000017500000000566415165535636023460 0ustar00buildbuild00000000000000/* * 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()thrift-0.23.0/lib/cpp/test/AllProtocolTests.cpp0000664000175000017500000000300215165535636021660 0ustar00buildbuild00000000000000/* * 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 #define BOOST_TEST_MODULE AllProtocolTests #include #include "AllProtocolTests.tcc" using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; char errorMessage[ERR_LEN]; BOOST_AUTO_TEST_CASE(test_binary_protocol) { testProtocol("TBinaryProtocol"); } BOOST_AUTO_TEST_CASE(test_little_binary_protocol) { testProtocol("TLEBinaryProtocol"); } BOOST_AUTO_TEST_CASE(test_compact_protocol) { testProtocol("TCompactProtocol"); } thrift-0.23.0/lib/cpp/test/TSocketInterruptTest.cpp0000664000175000017500000001261415165535636022545 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define BOOST_TEST_MODULE TSocketInterruptTest #include #include #include #include #include #include #include using apache::thrift::transport::TServerSocket; using apache::thrift::transport::TSocket; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportException; using namespace apache::thrift; BOOST_AUTO_TEST_SUITE(TSocketInterruptTest) void readerWorker(std::shared_ptr tt, uint32_t expectedResult) { uint8_t buf[4]; BOOST_CHECK_EQUAL(expectedResult, tt->read(buf, 4)); } void readerWorkerMustThrow(std::shared_ptr tt) { try { uint8_t buf[4]; tt->read(buf, 4); BOOST_ERROR("should not have gotten here"); } catch (const TTransportException& tx) { BOOST_CHECK_EQUAL(TTransportException::INTERRUPTED, tx.getType()); } } BOOST_AUTO_TEST_CASE(test_interruptable_child_read) { TServerSocket sock1("localhost", 0); sock1.listen(); BOOST_CHECK(sock1.isOpen()); int port = sock1.getPort(); TSocket clientSock("localhost", port); clientSock.open(); std::shared_ptr accepted = sock1.accept(); boost::thread readThread(std::bind(readerWorkerMustThrow, accepted)); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // readThread is practically guaranteed to be blocking now sock1.interruptChildren(); BOOST_CHECK_MESSAGE(readThread.try_join_for(boost::chrono::milliseconds(200)), "server socket interruptChildren did not interrupt child read"); clientSock.close(); accepted->close(); sock1.close(); } BOOST_AUTO_TEST_CASE(test_non_interruptable_child_read) { TServerSocket sock1("localhost", 0); sock1.setInterruptableChildren(false); // returns to pre-THRIFT-2441 behavior sock1.listen(); int port = sock1.getPort(); TSocket clientSock("localhost", port); clientSock.open(); std::shared_ptr accepted = sock1.accept(); boost::thread readThread(std::bind(readerWorker, accepted, 0)); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // readThread is practically guaranteed to be blocking here sock1.interruptChildren(); BOOST_CHECK_MESSAGE(!readThread.try_join_for(boost::chrono::milliseconds(200)), "server socket interruptChildren interrupted child read"); // only way to proceed is to have the client disconnect clientSock.close(); readThread.join(); accepted->close(); sock1.close(); } BOOST_AUTO_TEST_CASE(test_cannot_change_after_listen) { TServerSocket sock1("localhost", 0); sock1.listen(); BOOST_CHECK_THROW(sock1.setInterruptableChildren(false), std::logic_error); sock1.close(); } void peekerWorker(std::shared_ptr tt, bool expectedResult) { BOOST_CHECK_EQUAL(expectedResult, tt->peek()); } BOOST_AUTO_TEST_CASE(test_interruptable_child_peek) { TServerSocket sock1("localhost", 0); sock1.listen(); int port = sock1.getPort(); TSocket clientSock("localhost", port); clientSock.open(); std::shared_ptr accepted = sock1.accept(); // peek() will return false if child is interrupted boost::thread peekThread(std::bind(peekerWorker, accepted, false)); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // peekThread is practically guaranteed to be blocking now sock1.interruptChildren(); BOOST_CHECK_MESSAGE(peekThread.try_join_for(boost::chrono::milliseconds(200)), "server socket interruptChildren did not interrupt child peek"); clientSock.close(); accepted->close(); sock1.close(); } BOOST_AUTO_TEST_CASE(test_non_interruptable_child_peek) { TServerSocket sock1("localhost", 0); sock1.setInterruptableChildren(false); // returns to pre-THRIFT-2441 behavior sock1.listen(); int port = sock1.getPort(); TSocket clientSock("localhost", port); clientSock.open(); std::shared_ptr accepted = sock1.accept(); // peek() will return false when remote side is closed boost::thread peekThread(std::bind(peekerWorker, accepted, false)); boost::this_thread::sleep(boost::posix_time::milliseconds(50)); // peekThread is practically guaranteed to be blocking now sock1.interruptChildren(); BOOST_CHECK_MESSAGE(!peekThread.try_join_for(boost::chrono::milliseconds(200)), "server socket interruptChildren interrupted child peek"); // only way to proceed is to have the client disconnect clientSock.close(); peekThread.join(); accepted->close(); sock1.close(); } BOOST_AUTO_TEST_SUITE_END() thrift-0.23.0/lib/cpp/test/Makefile.in0000644000175000017500000024250315170007166017741 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = Benchmark$(EXEEXT) concurrency_test$(EXEEXT) \ $(am__EXEEXT_2) check_PROGRAMS = UnitTests$(EXEEXT) UnitTestsUuid$(EXEEXT) \ UnitTestsUuidNoDirective$(EXEEXT) TFDTransportTest$(EXEEXT) \ TPipedTransportTest$(EXEEXT) DebugProtoTest$(EXEEXT) \ JSONProtoTest$(EXEEXT) OptionalRequiredTest$(EXEEXT) \ RecursiveTest$(EXEEXT) SpecializationTest$(EXEEXT) \ AllProtocolsTest$(EXEEXT) TransportTest$(EXEEXT) \ TInterruptTest$(EXEEXT) TServerIntegrationTest$(EXEEXT) \ SecurityTest$(EXEEXT) SecurityFromBufferTest$(EXEEXT) \ ZlibTest$(EXEEXT) TFileTransportTest$(EXEEXT) \ link_test$(EXEEXT) OpenSSLManualInitTest$(EXEEXT) \ EnumTest$(EXEEXT) RenderedDoubleConstantsTest$(EXEEXT) \ AnnotationTest$(EXEEXT) $(am__EXEEXT_1) @AMX_HAVE_LIBEVENT_TRUE@am__append_1 = \ @AMX_HAVE_LIBEVENT_TRUE@ processor_test @AMX_HAVE_LIBEVENT_TRUE@am__append_2 = \ @AMX_HAVE_LIBEVENT_TRUE@ TNonblockingServerTest \ @AMX_HAVE_LIBEVENT_TRUE@ TNonblockingSSLServerTest subdir = lib/cpp/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @AMX_HAVE_LIBEVENT_TRUE@am__EXEEXT_1 = \ @AMX_HAVE_LIBEVENT_TRUE@ TNonblockingServerTest$(EXEEXT) \ @AMX_HAVE_LIBEVENT_TRUE@ TNonblockingSSLServerTest$(EXEEXT) @AMX_HAVE_LIBEVENT_TRUE@am__EXEEXT_2 = processor_test$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) libprocessortest_la_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp nodist_libprocessortest_la_OBJECTS = gen-cpp/ChildService.lo \ gen-cpp/EmptyService.lo gen-cpp/ParentService.lo \ gen-cpp/proc_types.lo libprocessortest_la_OBJECTS = $(nodist_libprocessortest_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libtestgencpp_la_DEPENDENCIES = $(top_builddir)/lib/cpp/libthrift.la nodist_libtestgencpp_la_OBJECTS = gen-cpp/AnnotationTest_types.lo \ gen-cpp/DebugProtoTest_types.lo \ gen-cpp/DoubleConstantsTest_constants.lo \ gen-cpp/EnumTest_types.lo \ gen-cpp/OptionalRequiredTest_types.lo \ gen-cpp/Recursive_types.lo gen-cpp/ThriftTest_types.lo \ gen-cpp/ThriftTest_constants.lo gen-cpp/Thrift5272_types.lo \ gen-cpp/TypedefTest_types.lo gen-cpp/OneWayService.lo \ ThriftTest_extras.lo DebugProtoTest_extras.lo libtestgencpp_la_OBJECTS = $(nodist_libtestgencpp_la_OBJECTS) am_AllProtocolsTest_OBJECTS = AllProtocolTests.$(OBJEXT) AllProtocolsTest_OBJECTS = $(am_AllProtocolsTest_OBJECTS) am__DEPENDENCIES_1 = AllProtocolsTest_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) am_AnnotationTest_OBJECTS = AnnotationTest.$(OBJEXT) AnnotationTest_OBJECTS = $(am_AnnotationTest_OBJECTS) AnnotationTest_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) am_Benchmark_OBJECTS = Benchmark.$(OBJEXT) Benchmark_OBJECTS = $(am_Benchmark_OBJECTS) Benchmark_DEPENDENCIES = libtestgencpp.la am_DebugProtoTest_OBJECTS = DebugProtoTest.$(OBJEXT) DebugProtoTest_OBJECTS = $(am_DebugProtoTest_OBJECTS) DebugProtoTest_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) am_EnumTest_OBJECTS = EnumTest.$(OBJEXT) EnumTest_OBJECTS = $(am_EnumTest_OBJECTS) EnumTest_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) am_JSONProtoTest_OBJECTS = JSONProtoTest.$(OBJEXT) JSONProtoTest_OBJECTS = $(am_JSONProtoTest_OBJECTS) JSONProtoTest_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) am_OpenSSLManualInitTest_OBJECTS = OpenSSLManualInitTest.$(OBJEXT) OpenSSLManualInitTest_OBJECTS = $(am_OpenSSLManualInitTest_OBJECTS) OpenSSLManualInitTest_DEPENDENCIES = \ $(top_builddir)/lib/cpp/libthrift.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_OptionalRequiredTest_OBJECTS = OptionalRequiredTest.$(OBJEXT) OptionalRequiredTest_OBJECTS = $(am_OptionalRequiredTest_OBJECTS) OptionalRequiredTest_DEPENDENCIES = libtestgencpp.la \ $(am__DEPENDENCIES_1) am_RecursiveTest_OBJECTS = RecursiveTest.$(OBJEXT) RecursiveTest_OBJECTS = $(am_RecursiveTest_OBJECTS) RecursiveTest_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) am_RenderedDoubleConstantsTest_OBJECTS = \ RenderedDoubleConstantsTest.$(OBJEXT) RenderedDoubleConstantsTest_OBJECTS = \ $(am_RenderedDoubleConstantsTest_OBJECTS) RenderedDoubleConstantsTest_DEPENDENCIES = libtestgencpp.la \ $(am__DEPENDENCIES_1) am_SecurityFromBufferTest_OBJECTS = SecurityFromBufferTest.$(OBJEXT) SecurityFromBufferTest_OBJECTS = $(am_SecurityFromBufferTest_OBJECTS) SecurityFromBufferTest_DEPENDENCIES = libtestgencpp.la \ libprocessortest.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_SecurityTest_OBJECTS = SecurityTest.$(OBJEXT) SecurityTest_OBJECTS = $(am_SecurityTest_OBJECTS) SecurityTest_DEPENDENCIES = libtestgencpp.la libprocessortest.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_SpecializationTest_OBJECTS = SpecializationTest.$(OBJEXT) SpecializationTest_OBJECTS = $(am_SpecializationTest_OBJECTS) SpecializationTest_DEPENDENCIES = libtestgencpp.la \ $(am__DEPENDENCIES_1) am_TFDTransportTest_OBJECTS = TFDTransportTest.$(OBJEXT) TFDTransportTest_OBJECTS = $(am_TFDTransportTest_OBJECTS) TFDTransportTest_DEPENDENCIES = $(top_builddir)/lib/cpp/libthrift.la \ $(am__DEPENDENCIES_1) am_TFileTransportTest_OBJECTS = TFileTransportTest.$(OBJEXT) TFileTransportTest_OBJECTS = $(am_TFileTransportTest_OBJECTS) TFileTransportTest_DEPENDENCIES = libtestgencpp.la \ $(am__DEPENDENCIES_1) am_TInterruptTest_OBJECTS = TSocketInterruptTest.$(OBJEXT) \ TSSLSocketInterruptTest.$(OBJEXT) TInterruptTest_OBJECTS = $(am_TInterruptTest_OBJECTS) TInterruptTest_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_TNonblockingSSLServerTest_OBJECTS = \ TNonblockingSSLServerTest.$(OBJEXT) TNonblockingSSLServerTest_OBJECTS = \ $(am_TNonblockingSSLServerTest_OBJECTS) TNonblockingSSLServerTest_DEPENDENCIES = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_TNonblockingServerTest_OBJECTS = TNonblockingServerTest.$(OBJEXT) TNonblockingServerTest_OBJECTS = $(am_TNonblockingServerTest_OBJECTS) TNonblockingServerTest_DEPENDENCIES = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_TPipedTransportTest_OBJECTS = TPipedTransportTest.$(OBJEXT) \ TPipeInterruptTest.$(OBJEXT) TPipedTransportTest_OBJECTS = $(am_TPipedTransportTest_OBJECTS) TPipedTransportTest_DEPENDENCIES = libtestgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_TServerIntegrationTest_OBJECTS = TServerIntegrationTest.$(OBJEXT) TServerIntegrationTest_OBJECTS = $(am_TServerIntegrationTest_OBJECTS) TServerIntegrationTest_DEPENDENCIES = libtestgencpp.la \ libprocessortest.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_TransportTest_OBJECTS = TransportTest.$(OBJEXT) TransportTest_OBJECTS = $(am_TransportTest_OBJECTS) TransportTest_DEPENDENCIES = libtestgencpp.la \ $(top_builddir)/lib/cpp/libthriftz.la $(am__DEPENDENCIES_1) am_UnitTests_OBJECTS = UnitTestMain.$(OBJEXT) OneWayHTTPTest.$(OBJEXT) \ TMemoryBufferTest.$(OBJEXT) TBufferBaseTest.$(OBJEXT) \ Base64Test.$(OBJEXT) ToStringTest.$(OBJEXT) \ TypedefTest.$(OBJEXT) TServerSocketTest.$(OBJEXT) \ TServerTransportTest.$(OBJEXT) ThrifttReadCheckTests.$(OBJEXT) \ Thrift5272.$(OBJEXT) TUuidTest.$(OBJEXT) UnitTests_OBJECTS = $(am_UnitTests_OBJECTS) UnitTests_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_UnitTestsUuid_OBJECTS = UnitTestsUuid-UnitTestMain.$(OBJEXT) \ UnitTestsUuid-TUuidTestBoost.$(OBJEXT) UnitTestsUuid_OBJECTS = $(am_UnitTestsUuid_OBJECTS) UnitTestsUuid_DEPENDENCIES = libtestgencpp.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_UnitTestsUuidNoDirective_OBJECTS = UnitTestMain.$(OBJEXT) \ TUuidTestBoostNoDirective.$(OBJEXT) UnitTestsUuidNoDirective_OBJECTS = \ $(am_UnitTestsUuidNoDirective_OBJECTS) UnitTestsUuidNoDirective_DEPENDENCIES = libtestgencpp.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_ZlibTest_OBJECTS = ZlibTest.$(OBJEXT) ZlibTest_OBJECTS = $(am_ZlibTest_OBJECTS) ZlibTest_DEPENDENCIES = libtestgencpp.la \ $(top_builddir)/lib/cpp/libthriftz.la $(am__DEPENDENCIES_1) am_concurrency_test_OBJECTS = concurrency/Tests.$(OBJEXT) concurrency_test_OBJECTS = $(am_concurrency_test_OBJECTS) concurrency_test_DEPENDENCIES = $(top_builddir)/lib/cpp/libthrift.la am_link_test_OBJECTS = link/LinkTest.$(OBJEXT) \ link/TemplatedService1.$(OBJEXT) \ link/TemplatedService2.$(OBJEXT) link_test_OBJECTS = $(am_link_test_OBJECTS) link_test_LDADD = $(LDADD) am_processor_test_OBJECTS = processor/ProcessorTest.$(OBJEXT) \ processor/EventLog.$(OBJEXT) processor/ServerThread.$(OBJEXT) processor_test_OBJECTS = $(am_processor_test_OBJECTS) processor_test_DEPENDENCIES = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/AllProtocolTests.Po \ ./$(DEPDIR)/AnnotationTest.Po ./$(DEPDIR)/Base64Test.Po \ ./$(DEPDIR)/Benchmark.Po ./$(DEPDIR)/DebugProtoTest.Po \ ./$(DEPDIR)/DebugProtoTest_extras.Plo ./$(DEPDIR)/EnumTest.Po \ ./$(DEPDIR)/JSONProtoTest.Po ./$(DEPDIR)/OneWayHTTPTest.Po \ ./$(DEPDIR)/OpenSSLManualInitTest.Po \ ./$(DEPDIR)/OptionalRequiredTest.Po \ ./$(DEPDIR)/RecursiveTest.Po \ ./$(DEPDIR)/RenderedDoubleConstantsTest.Po \ ./$(DEPDIR)/SecurityFromBufferTest.Po \ ./$(DEPDIR)/SecurityTest.Po ./$(DEPDIR)/SpecializationTest.Po \ ./$(DEPDIR)/TBufferBaseTest.Po ./$(DEPDIR)/TFDTransportTest.Po \ ./$(DEPDIR)/TFileTransportTest.Po \ ./$(DEPDIR)/TMemoryBufferTest.Po \ ./$(DEPDIR)/TNonblockingSSLServerTest.Po \ ./$(DEPDIR)/TNonblockingServerTest.Po \ ./$(DEPDIR)/TPipeInterruptTest.Po \ ./$(DEPDIR)/TPipedTransportTest.Po \ ./$(DEPDIR)/TSSLSocketInterruptTest.Po \ ./$(DEPDIR)/TServerIntegrationTest.Po \ ./$(DEPDIR)/TServerSocketTest.Po \ ./$(DEPDIR)/TServerTransportTest.Po \ ./$(DEPDIR)/TSocketInterruptTest.Po ./$(DEPDIR)/TUuidTest.Po \ ./$(DEPDIR)/TUuidTestBoostNoDirective.Po \ ./$(DEPDIR)/Thrift5272.Po ./$(DEPDIR)/ThriftTest_extras.Plo \ ./$(DEPDIR)/ThrifttReadCheckTests.Po \ ./$(DEPDIR)/ToStringTest.Po ./$(DEPDIR)/TransportTest.Po \ ./$(DEPDIR)/TypedefTest.Po ./$(DEPDIR)/UnitTestMain.Po \ ./$(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Po \ ./$(DEPDIR)/UnitTestsUuid-UnitTestMain.Po \ ./$(DEPDIR)/ZlibTest.Po concurrency/$(DEPDIR)/Tests.Po \ gen-cpp/$(DEPDIR)/AnnotationTest_types.Plo \ gen-cpp/$(DEPDIR)/ChildService.Plo \ gen-cpp/$(DEPDIR)/DebugProtoTest_types.Plo \ gen-cpp/$(DEPDIR)/DoubleConstantsTest_constants.Plo \ gen-cpp/$(DEPDIR)/EmptyService.Plo \ gen-cpp/$(DEPDIR)/EnumTest_types.Plo \ gen-cpp/$(DEPDIR)/OneWayService.Plo \ gen-cpp/$(DEPDIR)/OptionalRequiredTest_types.Plo \ gen-cpp/$(DEPDIR)/ParentService.Plo \ gen-cpp/$(DEPDIR)/Recursive_types.Plo \ gen-cpp/$(DEPDIR)/Thrift5272_types.Plo \ gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo \ gen-cpp/$(DEPDIR)/ThriftTest_types.Plo \ gen-cpp/$(DEPDIR)/TypedefTest_types.Plo \ gen-cpp/$(DEPDIR)/proc_types.Plo link/$(DEPDIR)/LinkTest.Po \ link/$(DEPDIR)/TemplatedService1.Po \ link/$(DEPDIR)/TemplatedService2.Po \ processor/$(DEPDIR)/EventLog.Po \ processor/$(DEPDIR)/ProcessorTest.Po \ processor/$(DEPDIR)/ServerThread.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist_libprocessortest_la_SOURCES) \ $(nodist_libtestgencpp_la_SOURCES) $(AllProtocolsTest_SOURCES) \ $(AnnotationTest_SOURCES) $(Benchmark_SOURCES) \ $(DebugProtoTest_SOURCES) $(EnumTest_SOURCES) \ $(JSONProtoTest_SOURCES) $(OpenSSLManualInitTest_SOURCES) \ $(OptionalRequiredTest_SOURCES) $(RecursiveTest_SOURCES) \ $(RenderedDoubleConstantsTest_SOURCES) \ $(SecurityFromBufferTest_SOURCES) $(SecurityTest_SOURCES) \ $(SpecializationTest_SOURCES) $(TFDTransportTest_SOURCES) \ $(TFileTransportTest_SOURCES) $(TInterruptTest_SOURCES) \ $(TNonblockingSSLServerTest_SOURCES) \ $(TNonblockingServerTest_SOURCES) \ $(TPipedTransportTest_SOURCES) \ $(TServerIntegrationTest_SOURCES) $(TransportTest_SOURCES) \ $(UnitTests_SOURCES) $(UnitTestsUuid_SOURCES) \ $(UnitTestsUuidNoDirective_SOURCES) $(ZlibTest_SOURCES) \ $(concurrency_test_SOURCES) $(link_test_SOURCES) \ $(processor_test_SOURCES) DIST_SOURCES = $(AllProtocolsTest_SOURCES) $(AnnotationTest_SOURCES) \ $(Benchmark_SOURCES) $(DebugProtoTest_SOURCES) \ $(EnumTest_SOURCES) $(JSONProtoTest_SOURCES) \ $(OpenSSLManualInitTest_SOURCES) \ $(OptionalRequiredTest_SOURCES) $(RecursiveTest_SOURCES) \ $(RenderedDoubleConstantsTest_SOURCES) \ $(SecurityFromBufferTest_SOURCES) $(SecurityTest_SOURCES) \ $(SpecializationTest_SOURCES) $(TFDTransportTest_SOURCES) \ $(TFileTransportTest_SOURCES) $(TInterruptTest_SOURCES) \ $(TNonblockingSSLServerTest_SOURCES) \ $(TNonblockingServerTest_SOURCES) \ $(TPipedTransportTest_SOURCES) \ $(TServerIntegrationTest_SOURCES) $(TransportTest_SOURCES) \ $(UnitTests_SOURCES) $(UnitTestsUuid_SOURCES) \ $(UnitTestsUuidNoDirective_SOURCES) $(ZlibTest_SOURCES) \ $(concurrency_test_SOURCES) $(link_test_SOURCES) \ $(processor_test_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc SUBDIRS = . fuzz BUILT_SOURCES = gen-cpp/AnnotationTest_types.h \ gen-cpp/DebugProtoTest_types.h \ gen-cpp/EnumTest_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/proc_types.h noinst_LTLIBRARIES = libtestgencpp.la libprocessortest.la nodist_libtestgencpp_la_SOURCES = \ gen-cpp/AnnotationTest_types.cpp \ gen-cpp/AnnotationTest_types.h \ gen-cpp/DebugProtoTest_types.cpp \ gen-cpp/DebugProtoTest_types.h \ gen-cpp/DoubleConstantsTest_constants.cpp \ gen-cpp/DoubleConstantsTest_constants.h \ gen-cpp/EnumTest_types.cpp \ gen-cpp/EnumTest_types.h \ gen-cpp/OptionalRequiredTest_types.cpp \ gen-cpp/OptionalRequiredTest_types.h \ gen-cpp/Recursive_types.cpp \ gen-cpp/Recursive_types.h \ gen-cpp/ThriftTest_types.cpp \ 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 \ gen-cpp/OneWayTest_types.h \ gen-cpp/OneWayService.h \ ThriftTest_extras.cpp \ DebugProtoTest_extras.cpp nodist_libprocessortest_la_SOURCES = \ gen-cpp/ChildService.cpp \ gen-cpp/ChildService.h \ gen-cpp/EmptyService.cpp \ gen-cpp/EmptyService.h \ gen-cpp/ParentService.cpp \ gen-cpp/ParentService.h \ gen-cpp/proc_types.cpp \ gen-cpp/proc_types.h libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la Benchmark_SOURCES = \ Benchmark.cpp Benchmark_LDADD = libtestgencpp.la TESTS_ENVIRONMENT = \ BOOST_TEST_LOG_SINK=tests.xml \ BOOST_TEST_LOG_LEVEL=test_suite \ BOOST_TEST_LOG_FORMAT=XML TESTS = \ $(check_PROGRAMS) UnitTests_SOURCES = \ UnitTestMain.cpp \ OneWayHTTPTest.cpp \ TMemoryBufferTest.cpp \ TBufferBaseTest.cpp \ Base64Test.cpp \ ToStringTest.cpp \ TypedefTest.cpp \ TServerSocketTest.cpp \ TServerTransportTest.cpp \ TTransportCheckThrow.h \ ThrifttReadCheckTests.cpp \ Thrift5272.cpp \ TUuidTest.cpp UnitTests_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_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 TInterruptTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_CHRONO_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) TServerIntegrationTest_SOURCES = \ TServerIntegrationTest.cpp TServerIntegrationTest_LDADD = \ libtestgencpp.la \ libprocessortest.la \ $(BOOST_TEST_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) SecurityTest_SOURCES = \ SecurityTest.cpp SecurityTest_LDADD = \ libtestgencpp.la \ libprocessortest.la \ $(BOOST_TEST_LDADD) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) SecurityFromBufferTest_SOURCES = \ SecurityFromBufferTest.cpp SecurityFromBufferTest_LDADD = \ libtestgencpp.la \ libprocessortest.la \ $(BOOST_TEST_LDADD) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) TransportTest_SOURCES = \ TransportTest.cpp TransportTest_LDADD = \ libtestgencpp.la \ $(top_builddir)/lib/cpp/libthriftz.la \ $(BOOST_TEST_LDADD) \ -lz ZlibTest_SOURCES = \ ZlibTest.cpp ZlibTest_LDADD = \ libtestgencpp.la \ $(top_builddir)/lib/cpp/libthriftz.la \ $(BOOST_TEST_LDADD) \ -lz EnumTest_SOURCES = \ EnumTest.cpp EnumTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) RenderedDoubleConstantsTest_SOURCES = RenderedDoubleConstantsTest.cpp RenderedDoubleConstantsTest_LDADD = libtestgencpp.la $(BOOST_TEST_LDADD) AnnotationTest_SOURCES = \ AnnotationTest.cpp AnnotationTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) TFileTransportTest_SOURCES = \ TFileTransportTest.cpp TFileTransportTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # TFDTransportTest # TFDTransportTest_SOURCES = \ TFDTransportTest.cpp TFDTransportTest_LDADD = \ $(top_builddir)/lib/cpp/libthrift.la \ $(BOOST_TEST_LDADD) # # TPipedTransportTest # TPipedTransportTest_SOURCES = \ TPipedTransportTest.cpp \ TPipeInterruptTest.cpp TPipedTransportTest_LDADD = \ libtestgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(BOOST_TEST_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) # # AllProtocolsTest # AllProtocolsTest_SOURCES = \ AllProtocolTests.cpp \ AllProtocolTests.tcc \ GenericHelpers.h AllProtocolsTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # DebugProtoTest # DebugProtoTest_SOURCES = \ DebugProtoTest.cpp DebugProtoTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # JSONProtoTest # JSONProtoTest_SOURCES = \ JSONProtoTest.cpp JSONProtoTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # TNonblockingServerTest # TNonblockingServerTest_SOURCES = TNonblockingServerTest.cpp TNonblockingServerTest_LDADD = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la \ $(BOOST_TEST_LDADD) \ $(BOOST_LDFLAGS) \ $(LIBEVENT_LIBS) # # TNonblockingSSLServerTest # TNonblockingSSLServerTest_SOURCES = TNonblockingSSLServerTest.cpp TNonblockingSSLServerTest_LDADD = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la \ $(BOOST_TEST_LDADD) \ $(BOOST_LDFLAGS) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_CHRONO_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) \ $(LIBEVENT_LIBS) # # OptionalRequiredTest # OptionalRequiredTest_SOURCES = \ OptionalRequiredTest.cpp OptionalRequiredTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # OptionalRequiredTest # RecursiveTest_SOURCES = \ RecursiveTest.cpp RecursiveTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # SpecializationTest # SpecializationTest_SOURCES = \ SpecializationTest.cpp SpecializationTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) concurrency_test_SOURCES = \ concurrency/Tests.cpp \ concurrency/ThreadFactoryTests.h \ concurrency/ThreadManagerTests.h \ concurrency/TimerManagerTests.h concurrency_test_LDADD = \ $(top_builddir)/lib/cpp/libthrift.la link_test_SOURCES = \ link/LinkTest.cpp \ link/TemplatedService1.cpp \ link/TemplatedService2.cpp processor_test_SOURCES = \ processor/ProcessorTest.cpp \ processor/EventLog.cpp \ processor/ServerThread.cpp \ processor/EventLog.h \ processor/Handlers.h \ processor/ServerThread.h processor_test_LDADD = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la \ $(BOOST_TEST_LDADD) \ $(BOOST_LDFLAGS) \ $(LIBEVENT_LIBS) OpenSSLManualInitTest_SOURCES = \ OpenSSLManualInitTest.cpp OpenSSLManualInitTest_LDADD = \ $(top_builddir)/lib/cpp/libthrift.la \ $(BOOST_TEST_LDADD) \ $(OPENSSL_LDFLAGS) \ $(OPENSSL_LIBS) AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -I$(top_srcdir)/lib/cpp/src/thrift -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. AM_LDFLAGS = $(BOOST_LDFLAGS) AM_CXXFLAGS = -Wall -Wextra -pedantic EXTRA_DIST = \ concurrency \ processor \ qt \ CMakeLists.txt \ DebugProtoTest_extras.cpp \ ThriftTest_extras.cpp \ OneWayTest.thrift \ Thrift5272.thrift all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/cpp/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/cpp/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gen-cpp/$(am__dirstamp): @$(MKDIR_P) gen-cpp @: > gen-cpp/$(am__dirstamp) gen-cpp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gen-cpp/$(DEPDIR) @: > gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/ChildService.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/EmptyService.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/ParentService.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/proc_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) libprocessortest.la: $(libprocessortest_la_OBJECTS) $(libprocessortest_la_DEPENDENCIES) $(EXTRA_libprocessortest_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libprocessortest_la_OBJECTS) $(libprocessortest_la_LIBADD) $(LIBS) gen-cpp/AnnotationTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/DebugProtoTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/DoubleConstantsTest_constants.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/EnumTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/OptionalRequiredTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/Recursive_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/ThriftTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/ThriftTest_constants.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/Thrift5272_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/TypedefTest_types.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) gen-cpp/OneWayService.lo: gen-cpp/$(am__dirstamp) \ gen-cpp/$(DEPDIR)/$(am__dirstamp) libtestgencpp.la: $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_DEPENDENCIES) $(EXTRA_libtestgencpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libtestgencpp_la_OBJECTS) $(libtestgencpp_la_LIBADD) $(LIBS) AllProtocolsTest$(EXEEXT): $(AllProtocolsTest_OBJECTS) $(AllProtocolsTest_DEPENDENCIES) $(EXTRA_AllProtocolsTest_DEPENDENCIES) @rm -f AllProtocolsTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(AllProtocolsTest_OBJECTS) $(AllProtocolsTest_LDADD) $(LIBS) AnnotationTest$(EXEEXT): $(AnnotationTest_OBJECTS) $(AnnotationTest_DEPENDENCIES) $(EXTRA_AnnotationTest_DEPENDENCIES) @rm -f AnnotationTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(AnnotationTest_OBJECTS) $(AnnotationTest_LDADD) $(LIBS) Benchmark$(EXEEXT): $(Benchmark_OBJECTS) $(Benchmark_DEPENDENCIES) $(EXTRA_Benchmark_DEPENDENCIES) @rm -f Benchmark$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(Benchmark_OBJECTS) $(Benchmark_LDADD) $(LIBS) DebugProtoTest$(EXEEXT): $(DebugProtoTest_OBJECTS) $(DebugProtoTest_DEPENDENCIES) $(EXTRA_DebugProtoTest_DEPENDENCIES) @rm -f DebugProtoTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(DebugProtoTest_OBJECTS) $(DebugProtoTest_LDADD) $(LIBS) EnumTest$(EXEEXT): $(EnumTest_OBJECTS) $(EnumTest_DEPENDENCIES) $(EXTRA_EnumTest_DEPENDENCIES) @rm -f EnumTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(EnumTest_OBJECTS) $(EnumTest_LDADD) $(LIBS) JSONProtoTest$(EXEEXT): $(JSONProtoTest_OBJECTS) $(JSONProtoTest_DEPENDENCIES) $(EXTRA_JSONProtoTest_DEPENDENCIES) @rm -f JSONProtoTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(JSONProtoTest_OBJECTS) $(JSONProtoTest_LDADD) $(LIBS) OpenSSLManualInitTest$(EXEEXT): $(OpenSSLManualInitTest_OBJECTS) $(OpenSSLManualInitTest_DEPENDENCIES) $(EXTRA_OpenSSLManualInitTest_DEPENDENCIES) @rm -f OpenSSLManualInitTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(OpenSSLManualInitTest_OBJECTS) $(OpenSSLManualInitTest_LDADD) $(LIBS) OptionalRequiredTest$(EXEEXT): $(OptionalRequiredTest_OBJECTS) $(OptionalRequiredTest_DEPENDENCIES) $(EXTRA_OptionalRequiredTest_DEPENDENCIES) @rm -f OptionalRequiredTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(OptionalRequiredTest_OBJECTS) $(OptionalRequiredTest_LDADD) $(LIBS) RecursiveTest$(EXEEXT): $(RecursiveTest_OBJECTS) $(RecursiveTest_DEPENDENCIES) $(EXTRA_RecursiveTest_DEPENDENCIES) @rm -f RecursiveTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(RecursiveTest_OBJECTS) $(RecursiveTest_LDADD) $(LIBS) RenderedDoubleConstantsTest$(EXEEXT): $(RenderedDoubleConstantsTest_OBJECTS) $(RenderedDoubleConstantsTest_DEPENDENCIES) $(EXTRA_RenderedDoubleConstantsTest_DEPENDENCIES) @rm -f RenderedDoubleConstantsTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(RenderedDoubleConstantsTest_OBJECTS) $(RenderedDoubleConstantsTest_LDADD) $(LIBS) SecurityFromBufferTest$(EXEEXT): $(SecurityFromBufferTest_OBJECTS) $(SecurityFromBufferTest_DEPENDENCIES) $(EXTRA_SecurityFromBufferTest_DEPENDENCIES) @rm -f SecurityFromBufferTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(SecurityFromBufferTest_OBJECTS) $(SecurityFromBufferTest_LDADD) $(LIBS) SecurityTest$(EXEEXT): $(SecurityTest_OBJECTS) $(SecurityTest_DEPENDENCIES) $(EXTRA_SecurityTest_DEPENDENCIES) @rm -f SecurityTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(SecurityTest_OBJECTS) $(SecurityTest_LDADD) $(LIBS) SpecializationTest$(EXEEXT): $(SpecializationTest_OBJECTS) $(SpecializationTest_DEPENDENCIES) $(EXTRA_SpecializationTest_DEPENDENCIES) @rm -f SpecializationTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(SpecializationTest_OBJECTS) $(SpecializationTest_LDADD) $(LIBS) TFDTransportTest$(EXEEXT): $(TFDTransportTest_OBJECTS) $(TFDTransportTest_DEPENDENCIES) $(EXTRA_TFDTransportTest_DEPENDENCIES) @rm -f TFDTransportTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TFDTransportTest_OBJECTS) $(TFDTransportTest_LDADD) $(LIBS) TFileTransportTest$(EXEEXT): $(TFileTransportTest_OBJECTS) $(TFileTransportTest_DEPENDENCIES) $(EXTRA_TFileTransportTest_DEPENDENCIES) @rm -f TFileTransportTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TFileTransportTest_OBJECTS) $(TFileTransportTest_LDADD) $(LIBS) TInterruptTest$(EXEEXT): $(TInterruptTest_OBJECTS) $(TInterruptTest_DEPENDENCIES) $(EXTRA_TInterruptTest_DEPENDENCIES) @rm -f TInterruptTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TInterruptTest_OBJECTS) $(TInterruptTest_LDADD) $(LIBS) TNonblockingSSLServerTest$(EXEEXT): $(TNonblockingSSLServerTest_OBJECTS) $(TNonblockingSSLServerTest_DEPENDENCIES) $(EXTRA_TNonblockingSSLServerTest_DEPENDENCIES) @rm -f TNonblockingSSLServerTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TNonblockingSSLServerTest_OBJECTS) $(TNonblockingSSLServerTest_LDADD) $(LIBS) TNonblockingServerTest$(EXEEXT): $(TNonblockingServerTest_OBJECTS) $(TNonblockingServerTest_DEPENDENCIES) $(EXTRA_TNonblockingServerTest_DEPENDENCIES) @rm -f TNonblockingServerTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TNonblockingServerTest_OBJECTS) $(TNonblockingServerTest_LDADD) $(LIBS) TPipedTransportTest$(EXEEXT): $(TPipedTransportTest_OBJECTS) $(TPipedTransportTest_DEPENDENCIES) $(EXTRA_TPipedTransportTest_DEPENDENCIES) @rm -f TPipedTransportTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TPipedTransportTest_OBJECTS) $(TPipedTransportTest_LDADD) $(LIBS) TServerIntegrationTest$(EXEEXT): $(TServerIntegrationTest_OBJECTS) $(TServerIntegrationTest_DEPENDENCIES) $(EXTRA_TServerIntegrationTest_DEPENDENCIES) @rm -f TServerIntegrationTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TServerIntegrationTest_OBJECTS) $(TServerIntegrationTest_LDADD) $(LIBS) TransportTest$(EXEEXT): $(TransportTest_OBJECTS) $(TransportTest_DEPENDENCIES) $(EXTRA_TransportTest_DEPENDENCIES) @rm -f TransportTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TransportTest_OBJECTS) $(TransportTest_LDADD) $(LIBS) UnitTests$(EXEEXT): $(UnitTests_OBJECTS) $(UnitTests_DEPENDENCIES) $(EXTRA_UnitTests_DEPENDENCIES) @rm -f UnitTests$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(UnitTests_OBJECTS) $(UnitTests_LDADD) $(LIBS) UnitTestsUuid$(EXEEXT): $(UnitTestsUuid_OBJECTS) $(UnitTestsUuid_DEPENDENCIES) $(EXTRA_UnitTestsUuid_DEPENDENCIES) @rm -f UnitTestsUuid$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(UnitTestsUuid_OBJECTS) $(UnitTestsUuid_LDADD) $(LIBS) UnitTestsUuidNoDirective$(EXEEXT): $(UnitTestsUuidNoDirective_OBJECTS) $(UnitTestsUuidNoDirective_DEPENDENCIES) $(EXTRA_UnitTestsUuidNoDirective_DEPENDENCIES) @rm -f UnitTestsUuidNoDirective$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(UnitTestsUuidNoDirective_OBJECTS) $(UnitTestsUuidNoDirective_LDADD) $(LIBS) ZlibTest$(EXEEXT): $(ZlibTest_OBJECTS) $(ZlibTest_DEPENDENCIES) $(EXTRA_ZlibTest_DEPENDENCIES) @rm -f ZlibTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(ZlibTest_OBJECTS) $(ZlibTest_LDADD) $(LIBS) concurrency/$(am__dirstamp): @$(MKDIR_P) concurrency @: > concurrency/$(am__dirstamp) concurrency/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) concurrency/$(DEPDIR) @: > concurrency/$(DEPDIR)/$(am__dirstamp) concurrency/Tests.$(OBJEXT): concurrency/$(am__dirstamp) \ concurrency/$(DEPDIR)/$(am__dirstamp) concurrency_test$(EXEEXT): $(concurrency_test_OBJECTS) $(concurrency_test_DEPENDENCIES) $(EXTRA_concurrency_test_DEPENDENCIES) @rm -f concurrency_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(concurrency_test_OBJECTS) $(concurrency_test_LDADD) $(LIBS) link/$(am__dirstamp): @$(MKDIR_P) link @: > link/$(am__dirstamp) link/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) link/$(DEPDIR) @: > link/$(DEPDIR)/$(am__dirstamp) link/LinkTest.$(OBJEXT): link/$(am__dirstamp) \ link/$(DEPDIR)/$(am__dirstamp) link/TemplatedService1.$(OBJEXT): link/$(am__dirstamp) \ link/$(DEPDIR)/$(am__dirstamp) link/TemplatedService2.$(OBJEXT): link/$(am__dirstamp) \ link/$(DEPDIR)/$(am__dirstamp) link_test$(EXEEXT): $(link_test_OBJECTS) $(link_test_DEPENDENCIES) $(EXTRA_link_test_DEPENDENCIES) @rm -f link_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(link_test_OBJECTS) $(link_test_LDADD) $(LIBS) processor/$(am__dirstamp): @$(MKDIR_P) processor @: > processor/$(am__dirstamp) processor/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) processor/$(DEPDIR) @: > processor/$(DEPDIR)/$(am__dirstamp) processor/ProcessorTest.$(OBJEXT): processor/$(am__dirstamp) \ processor/$(DEPDIR)/$(am__dirstamp) processor/EventLog.$(OBJEXT): processor/$(am__dirstamp) \ processor/$(DEPDIR)/$(am__dirstamp) processor/ServerThread.$(OBJEXT): processor/$(am__dirstamp) \ processor/$(DEPDIR)/$(am__dirstamp) processor_test$(EXEEXT): $(processor_test_OBJECTS) $(processor_test_DEPENDENCIES) $(EXTRA_processor_test_DEPENDENCIES) @rm -f processor_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(processor_test_OBJECTS) $(processor_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f concurrency/*.$(OBJEXT) -rm -f gen-cpp/*.$(OBJEXT) -rm -f gen-cpp/*.lo -rm -f link/*.$(OBJEXT) -rm -f processor/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllProtocolTests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnotationTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64Test.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Benchmark.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DebugProtoTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DebugProtoTest_extras.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EnumTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/JSONProtoTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OneWayHTTPTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OpenSSLManualInitTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionalRequiredTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RecursiveTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RenderedDoubleConstantsTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SecurityFromBufferTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SecurityTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpecializationTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TBufferBaseTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TFDTransportTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TFileTransportTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TMemoryBufferTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TNonblockingSSLServerTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TNonblockingServerTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TPipeInterruptTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TPipedTransportTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TSSLSocketInterruptTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TServerIntegrationTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TServerSocketTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TServerTransportTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TSocketInterruptTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TUuidTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TUuidTestBoostNoDirective.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Thrift5272.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ThriftTest_extras.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ThrifttReadCheckTests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ToStringTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransportTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TypedefTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnitTestMain.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnitTestsUuid-UnitTestMain.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ZlibTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/Tests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/AnnotationTest_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/ChildService.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/DebugProtoTest_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/DoubleConstantsTest_constants.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/EmptyService.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/EnumTest_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/OneWayService.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/OptionalRequiredTest_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/ParentService.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/Recursive_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/Thrift5272_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/ThriftTest_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/TypedefTest_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@gen-cpp/$(DEPDIR)/proc_types.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@link/$(DEPDIR)/LinkTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@link/$(DEPDIR)/TemplatedService1.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@link/$(DEPDIR)/TemplatedService2.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@processor/$(DEPDIR)/EventLog.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@processor/$(DEPDIR)/ProcessorTest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@processor/$(DEPDIR)/ServerThread.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< UnitTestsUuid-UnitTestMain.o: UnitTestMain.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT UnitTestsUuid-UnitTestMain.o -MD -MP -MF $(DEPDIR)/UnitTestsUuid-UnitTestMain.Tpo -c -o UnitTestsUuid-UnitTestMain.o `test -f 'UnitTestMain.cpp' || echo '$(srcdir)/'`UnitTestMain.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/UnitTestsUuid-UnitTestMain.Tpo $(DEPDIR)/UnitTestsUuid-UnitTestMain.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='UnitTestMain.cpp' object='UnitTestsUuid-UnitTestMain.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o UnitTestsUuid-UnitTestMain.o `test -f 'UnitTestMain.cpp' || echo '$(srcdir)/'`UnitTestMain.cpp UnitTestsUuid-UnitTestMain.obj: UnitTestMain.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT UnitTestsUuid-UnitTestMain.obj -MD -MP -MF $(DEPDIR)/UnitTestsUuid-UnitTestMain.Tpo -c -o UnitTestsUuid-UnitTestMain.obj `if test -f 'UnitTestMain.cpp'; then $(CYGPATH_W) 'UnitTestMain.cpp'; else $(CYGPATH_W) '$(srcdir)/UnitTestMain.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/UnitTestsUuid-UnitTestMain.Tpo $(DEPDIR)/UnitTestsUuid-UnitTestMain.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='UnitTestMain.cpp' object='UnitTestsUuid-UnitTestMain.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o UnitTestsUuid-UnitTestMain.obj `if test -f 'UnitTestMain.cpp'; then $(CYGPATH_W) 'UnitTestMain.cpp'; else $(CYGPATH_W) '$(srcdir)/UnitTestMain.cpp'; fi` UnitTestsUuid-TUuidTestBoost.o: TUuidTestBoost.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT UnitTestsUuid-TUuidTestBoost.o -MD -MP -MF $(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Tpo -c -o UnitTestsUuid-TUuidTestBoost.o `test -f 'TUuidTestBoost.cpp' || echo '$(srcdir)/'`TUuidTestBoost.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Tpo $(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TUuidTestBoost.cpp' object='UnitTestsUuid-TUuidTestBoost.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o UnitTestsUuid-TUuidTestBoost.o `test -f 'TUuidTestBoost.cpp' || echo '$(srcdir)/'`TUuidTestBoost.cpp UnitTestsUuid-TUuidTestBoost.obj: TUuidTestBoost.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT UnitTestsUuid-TUuidTestBoost.obj -MD -MP -MF $(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Tpo -c -o UnitTestsUuid-TUuidTestBoost.obj `if test -f 'TUuidTestBoost.cpp'; then $(CYGPATH_W) 'TUuidTestBoost.cpp'; else $(CYGPATH_W) '$(srcdir)/TUuidTestBoost.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Tpo $(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TUuidTestBoost.cpp' object='UnitTestsUuid-TUuidTestBoost.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(UnitTestsUuid_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o UnitTestsUuid-TUuidTestBoost.obj `if test -f 'TUuidTestBoost.cpp'; then $(CYGPATH_W) 'TUuidTestBoost.cpp'; else $(CYGPATH_W) '$(srcdir)/TUuidTestBoost.cpp'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf gen-cpp/.libs gen-cpp/_libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f concurrency/$(DEPDIR)/$(am__dirstamp) -rm -f concurrency/$(am__dirstamp) -rm -f gen-cpp/$(DEPDIR)/$(am__dirstamp) -rm -f gen-cpp/$(am__dirstamp) -rm -f link/$(DEPDIR)/$(am__dirstamp) -rm -f link/$(am__dirstamp) -rm -f processor/$(DEPDIR)/$(am__dirstamp) -rm -f processor/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/AllProtocolTests.Po -rm -f ./$(DEPDIR)/AnnotationTest.Po -rm -f ./$(DEPDIR)/Base64Test.Po -rm -f ./$(DEPDIR)/Benchmark.Po -rm -f ./$(DEPDIR)/DebugProtoTest.Po -rm -f ./$(DEPDIR)/DebugProtoTest_extras.Plo -rm -f ./$(DEPDIR)/EnumTest.Po -rm -f ./$(DEPDIR)/JSONProtoTest.Po -rm -f ./$(DEPDIR)/OneWayHTTPTest.Po -rm -f ./$(DEPDIR)/OpenSSLManualInitTest.Po -rm -f ./$(DEPDIR)/OptionalRequiredTest.Po -rm -f ./$(DEPDIR)/RecursiveTest.Po -rm -f ./$(DEPDIR)/RenderedDoubleConstantsTest.Po -rm -f ./$(DEPDIR)/SecurityFromBufferTest.Po -rm -f ./$(DEPDIR)/SecurityTest.Po -rm -f ./$(DEPDIR)/SpecializationTest.Po -rm -f ./$(DEPDIR)/TBufferBaseTest.Po -rm -f ./$(DEPDIR)/TFDTransportTest.Po -rm -f ./$(DEPDIR)/TFileTransportTest.Po -rm -f ./$(DEPDIR)/TMemoryBufferTest.Po -rm -f ./$(DEPDIR)/TNonblockingSSLServerTest.Po -rm -f ./$(DEPDIR)/TNonblockingServerTest.Po -rm -f ./$(DEPDIR)/TPipeInterruptTest.Po -rm -f ./$(DEPDIR)/TPipedTransportTest.Po -rm -f ./$(DEPDIR)/TSSLSocketInterruptTest.Po -rm -f ./$(DEPDIR)/TServerIntegrationTest.Po -rm -f ./$(DEPDIR)/TServerSocketTest.Po -rm -f ./$(DEPDIR)/TServerTransportTest.Po -rm -f ./$(DEPDIR)/TSocketInterruptTest.Po -rm -f ./$(DEPDIR)/TUuidTest.Po -rm -f ./$(DEPDIR)/TUuidTestBoostNoDirective.Po -rm -f ./$(DEPDIR)/Thrift5272.Po -rm -f ./$(DEPDIR)/ThriftTest_extras.Plo -rm -f ./$(DEPDIR)/ThrifttReadCheckTests.Po -rm -f ./$(DEPDIR)/ToStringTest.Po -rm -f ./$(DEPDIR)/TransportTest.Po -rm -f ./$(DEPDIR)/TypedefTest.Po -rm -f ./$(DEPDIR)/UnitTestMain.Po -rm -f ./$(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Po -rm -f ./$(DEPDIR)/UnitTestsUuid-UnitTestMain.Po -rm -f ./$(DEPDIR)/ZlibTest.Po -rm -f concurrency/$(DEPDIR)/Tests.Po -rm -f gen-cpp/$(DEPDIR)/AnnotationTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/ChildService.Plo -rm -f gen-cpp/$(DEPDIR)/DebugProtoTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/DoubleConstantsTest_constants.Plo -rm -f gen-cpp/$(DEPDIR)/EmptyService.Plo -rm -f gen-cpp/$(DEPDIR)/EnumTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/OneWayService.Plo -rm -f gen-cpp/$(DEPDIR)/OptionalRequiredTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/ParentService.Plo -rm -f gen-cpp/$(DEPDIR)/Recursive_types.Plo -rm -f gen-cpp/$(DEPDIR)/Thrift5272_types.Plo -rm -f gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo -rm -f gen-cpp/$(DEPDIR)/ThriftTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/TypedefTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/proc_types.Plo -rm -f link/$(DEPDIR)/LinkTest.Po -rm -f link/$(DEPDIR)/TemplatedService1.Po -rm -f link/$(DEPDIR)/TemplatedService2.Po -rm -f processor/$(DEPDIR)/EventLog.Po -rm -f processor/$(DEPDIR)/ProcessorTest.Po -rm -f processor/$(DEPDIR)/ServerThread.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/AllProtocolTests.Po -rm -f ./$(DEPDIR)/AnnotationTest.Po -rm -f ./$(DEPDIR)/Base64Test.Po -rm -f ./$(DEPDIR)/Benchmark.Po -rm -f ./$(DEPDIR)/DebugProtoTest.Po -rm -f ./$(DEPDIR)/DebugProtoTest_extras.Plo -rm -f ./$(DEPDIR)/EnumTest.Po -rm -f ./$(DEPDIR)/JSONProtoTest.Po -rm -f ./$(DEPDIR)/OneWayHTTPTest.Po -rm -f ./$(DEPDIR)/OpenSSLManualInitTest.Po -rm -f ./$(DEPDIR)/OptionalRequiredTest.Po -rm -f ./$(DEPDIR)/RecursiveTest.Po -rm -f ./$(DEPDIR)/RenderedDoubleConstantsTest.Po -rm -f ./$(DEPDIR)/SecurityFromBufferTest.Po -rm -f ./$(DEPDIR)/SecurityTest.Po -rm -f ./$(DEPDIR)/SpecializationTest.Po -rm -f ./$(DEPDIR)/TBufferBaseTest.Po -rm -f ./$(DEPDIR)/TFDTransportTest.Po -rm -f ./$(DEPDIR)/TFileTransportTest.Po -rm -f ./$(DEPDIR)/TMemoryBufferTest.Po -rm -f ./$(DEPDIR)/TNonblockingSSLServerTest.Po -rm -f ./$(DEPDIR)/TNonblockingServerTest.Po -rm -f ./$(DEPDIR)/TPipeInterruptTest.Po -rm -f ./$(DEPDIR)/TPipedTransportTest.Po -rm -f ./$(DEPDIR)/TSSLSocketInterruptTest.Po -rm -f ./$(DEPDIR)/TServerIntegrationTest.Po -rm -f ./$(DEPDIR)/TServerSocketTest.Po -rm -f ./$(DEPDIR)/TServerTransportTest.Po -rm -f ./$(DEPDIR)/TSocketInterruptTest.Po -rm -f ./$(DEPDIR)/TUuidTest.Po -rm -f ./$(DEPDIR)/TUuidTestBoostNoDirective.Po -rm -f ./$(DEPDIR)/Thrift5272.Po -rm -f ./$(DEPDIR)/ThriftTest_extras.Plo -rm -f ./$(DEPDIR)/ThrifttReadCheckTests.Po -rm -f ./$(DEPDIR)/ToStringTest.Po -rm -f ./$(DEPDIR)/TransportTest.Po -rm -f ./$(DEPDIR)/TypedefTest.Po -rm -f ./$(DEPDIR)/UnitTestMain.Po -rm -f ./$(DEPDIR)/UnitTestsUuid-TUuidTestBoost.Po -rm -f ./$(DEPDIR)/UnitTestsUuid-UnitTestMain.Po -rm -f ./$(DEPDIR)/ZlibTest.Po -rm -f concurrency/$(DEPDIR)/Tests.Po -rm -f gen-cpp/$(DEPDIR)/AnnotationTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/ChildService.Plo -rm -f gen-cpp/$(DEPDIR)/DebugProtoTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/DoubleConstantsTest_constants.Plo -rm -f gen-cpp/$(DEPDIR)/EmptyService.Plo -rm -f gen-cpp/$(DEPDIR)/EnumTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/OneWayService.Plo -rm -f gen-cpp/$(DEPDIR)/OptionalRequiredTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/ParentService.Plo -rm -f gen-cpp/$(DEPDIR)/Recursive_types.Plo -rm -f gen-cpp/$(DEPDIR)/Thrift5272_types.Plo -rm -f gen-cpp/$(DEPDIR)/ThriftTest_constants.Plo -rm -f gen-cpp/$(DEPDIR)/ThriftTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/TypedefTest_types.Plo -rm -f gen-cpp/$(DEPDIR)/proc_types.Plo -rm -f link/$(DEPDIR)/LinkTest.Po -rm -f link/$(DEPDIR)/TemplatedService1.Po -rm -f link/$(DEPDIR)/TemplatedService2.Po -rm -f processor/$(DEPDIR)/EventLog.Po -rm -f processor/$(DEPDIR)/ProcessorTest.Po -rm -f processor/$(DEPDIR)/ServerThread.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) all check check-am install install-am \ install-exec install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile ThriftTest_extras.o: gen-cpp/ThriftTest_types.h DebugProtoTest_extras.o: gen-cpp/DebugProtoTest_types.h # # 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/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 $< gen-cpp/TypedefTest_types.cpp gen-cpp/TypedefTest_types.h: $(top_srcdir)/test/TypedefTest.thrift $(THRIFT) --gen cpp $< gen-cpp/OptionalRequiredTest_types.cpp gen-cpp/OptionalRequiredTest_types.h: $(top_srcdir)/test/OptionalRequiredTest.thrift $(THRIFT) --gen cpp $< gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h: $(top_srcdir)/test/Recursive.thrift $(THRIFT) --gen cpp $< 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/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 $< clean-local: $(RM) gen-cpp/* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/cpp/test/Thrift5272.cpp0000664000175000017500000000413315165535636020171 0ustar00buildbuild00000000000000/* * 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() thrift-0.23.0/lib/cpp/test/link/0000755000175000017500000000000015170007200016610 5ustar00buildbuild00000000000000thrift-0.23.0/lib/cpp/test/link/TemplatedService2.cpp0000664000175000017500000000174415165535636022675 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * This file is a part of a link test that makes sure generated * templated service headers can be included from multiple * implementation files. */ #include "gen-cpp/ParentService.h" thrift-0.23.0/lib/cpp/test/link/TemplatedService1.cpp0000664000175000017500000000174415165535636022674 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * This file is a part of a link test that makes sure generated * templated service headers can be included from multiple * implementation files. */ #include "gen-cpp/ParentService.h" thrift-0.23.0/lib/cpp/test/link/LinkTest.cpp0000664000175000017500000000151315165535636021102 0ustar00buildbuild00000000000000/* * 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. */ int main(int, char**) { return 0; } thrift-0.23.0/lib/cpp/test/Makefile.am0000664000175000017500000002762315165535636017752 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc SUBDIRS = . SUBDIRS += fuzz BUILT_SOURCES = gen-cpp/AnnotationTest_types.h \ gen-cpp/DebugProtoTest_types.h \ gen-cpp/EnumTest_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/proc_types.h noinst_LTLIBRARIES = libtestgencpp.la libprocessortest.la nodist_libtestgencpp_la_SOURCES = \ gen-cpp/AnnotationTest_types.cpp \ gen-cpp/AnnotationTest_types.h \ gen-cpp/DebugProtoTest_types.cpp \ gen-cpp/DebugProtoTest_types.h \ gen-cpp/DoubleConstantsTest_constants.cpp \ gen-cpp/DoubleConstantsTest_constants.h \ gen-cpp/EnumTest_types.cpp \ gen-cpp/EnumTest_types.h \ gen-cpp/OptionalRequiredTest_types.cpp \ gen-cpp/OptionalRequiredTest_types.h \ gen-cpp/Recursive_types.cpp \ gen-cpp/Recursive_types.h \ gen-cpp/ThriftTest_types.cpp \ 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 \ gen-cpp/OneWayTest_types.h \ gen-cpp/OneWayService.h \ ThriftTest_extras.cpp \ DebugProtoTest_extras.cpp nodist_libprocessortest_la_SOURCES = \ gen-cpp/ChildService.cpp \ gen-cpp/ChildService.h \ gen-cpp/EmptyService.cpp \ gen-cpp/EmptyService.h \ gen-cpp/ParentService.cpp \ gen-cpp/ParentService.h \ gen-cpp/proc_types.cpp \ gen-cpp/proc_types.h ThriftTest_extras.o: gen-cpp/ThriftTest_types.h DebugProtoTest_extras.o: gen-cpp/DebugProtoTest_types.h libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la noinst_PROGRAMS = Benchmark \ concurrency_test Benchmark_SOURCES = \ Benchmark.cpp Benchmark_LDADD = libtestgencpp.la check_PROGRAMS = \ UnitTests \ UnitTestsUuid \ UnitTestsUuidNoDirective \ TFDTransportTest \ TPipedTransportTest \ DebugProtoTest \ JSONProtoTest \ OptionalRequiredTest \ RecursiveTest \ SpecializationTest \ AllProtocolsTest \ TransportTest \ TInterruptTest \ TServerIntegrationTest \ SecurityTest \ SecurityFromBufferTest \ ZlibTest \ TFileTransportTest \ link_test \ OpenSSLManualInitTest \ EnumTest \ RenderedDoubleConstantsTest \ AnnotationTest if AMX_HAVE_LIBEVENT noinst_PROGRAMS += \ processor_test check_PROGRAMS += \ TNonblockingServerTest \ TNonblockingSSLServerTest endif TESTS_ENVIRONMENT= \ BOOST_TEST_LOG_SINK=tests.xml \ BOOST_TEST_LOG_LEVEL=test_suite \ BOOST_TEST_LOG_FORMAT=XML TESTS = \ $(check_PROGRAMS) UnitTests_SOURCES = \ UnitTestMain.cpp \ OneWayHTTPTest.cpp \ TMemoryBufferTest.cpp \ TBufferBaseTest.cpp \ Base64Test.cpp \ ToStringTest.cpp \ TypedefTest.cpp \ TServerSocketTest.cpp \ TServerTransportTest.cpp \ TTransportCheckThrow.h \ ThrifttReadCheckTests.cpp \ Thrift5272.cpp \ TUuidTest.cpp UnitTests_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_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 TInterruptTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_CHRONO_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) TServerIntegrationTest_SOURCES = \ TServerIntegrationTest.cpp TServerIntegrationTest_LDADD = \ libtestgencpp.la \ libprocessortest.la \ $(BOOST_TEST_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) SecurityTest_SOURCES = \ SecurityTest.cpp SecurityTest_LDADD = \ libtestgencpp.la \ libprocessortest.la \ $(BOOST_TEST_LDADD) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) SecurityFromBufferTest_SOURCES = \ SecurityFromBufferTest.cpp SecurityFromBufferTest_LDADD = \ libtestgencpp.la \ libprocessortest.la \ $(BOOST_TEST_LDADD) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) TransportTest_SOURCES = \ TransportTest.cpp TransportTest_LDADD = \ libtestgencpp.la \ $(top_builddir)/lib/cpp/libthriftz.la \ $(BOOST_TEST_LDADD) \ -lz ZlibTest_SOURCES = \ ZlibTest.cpp ZlibTest_LDADD = \ libtestgencpp.la \ $(top_builddir)/lib/cpp/libthriftz.la \ $(BOOST_TEST_LDADD) \ -lz EnumTest_SOURCES = \ EnumTest.cpp EnumTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) RenderedDoubleConstantsTest_SOURCES = RenderedDoubleConstantsTest.cpp RenderedDoubleConstantsTest_LDADD = libtestgencpp.la $(BOOST_TEST_LDADD) AnnotationTest_SOURCES = \ AnnotationTest.cpp AnnotationTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) TFileTransportTest_SOURCES = \ TFileTransportTest.cpp TFileTransportTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # TFDTransportTest # TFDTransportTest_SOURCES = \ TFDTransportTest.cpp TFDTransportTest_LDADD = \ $(top_builddir)/lib/cpp/libthrift.la \ $(BOOST_TEST_LDADD) # # TPipedTransportTest # TPipedTransportTest_SOURCES = \ TPipedTransportTest.cpp \ TPipeInterruptTest.cpp TPipedTransportTest_LDADD = \ libtestgencpp.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(BOOST_TEST_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) # # AllProtocolsTest # AllProtocolsTest_SOURCES = \ AllProtocolTests.cpp \ AllProtocolTests.tcc \ GenericHelpers.h AllProtocolsTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # DebugProtoTest # DebugProtoTest_SOURCES = \ DebugProtoTest.cpp DebugProtoTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # JSONProtoTest # JSONProtoTest_SOURCES = \ JSONProtoTest.cpp JSONProtoTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # TNonblockingServerTest # TNonblockingServerTest_SOURCES = TNonblockingServerTest.cpp TNonblockingServerTest_LDADD = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la \ $(BOOST_TEST_LDADD) \ $(BOOST_LDFLAGS) \ $(LIBEVENT_LIBS) # # TNonblockingSSLServerTest # TNonblockingSSLServerTest_SOURCES = TNonblockingSSLServerTest.cpp TNonblockingSSLServerTest_LDADD = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la \ $(BOOST_TEST_LDADD) \ $(BOOST_LDFLAGS) \ $(BOOST_FILESYSTEM_LDADD) \ $(BOOST_CHRONO_LDADD) \ $(BOOST_SYSTEM_LDADD) \ $(BOOST_THREAD_LDADD) \ $(LIBEVENT_LIBS) # # OptionalRequiredTest # OptionalRequiredTest_SOURCES = \ OptionalRequiredTest.cpp OptionalRequiredTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # OptionalRequiredTest # RecursiveTest_SOURCES = \ RecursiveTest.cpp RecursiveTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) # # SpecializationTest # SpecializationTest_SOURCES = \ SpecializationTest.cpp SpecializationTest_LDADD = \ libtestgencpp.la \ $(BOOST_TEST_LDADD) concurrency_test_SOURCES = \ concurrency/Tests.cpp \ concurrency/ThreadFactoryTests.h \ concurrency/ThreadManagerTests.h \ concurrency/TimerManagerTests.h concurrency_test_LDADD = \ $(top_builddir)/lib/cpp/libthrift.la link_test_SOURCES = \ link/LinkTest.cpp \ link/TemplatedService1.cpp \ link/TemplatedService2.cpp processor_test_SOURCES = \ processor/ProcessorTest.cpp \ processor/EventLog.cpp \ processor/ServerThread.cpp \ processor/EventLog.h \ processor/Handlers.h \ processor/ServerThread.h processor_test_LDADD = libprocessortest.la \ $(top_builddir)/lib/cpp/libthrift.la \ $(top_builddir)/lib/cpp/libthriftnb.la \ $(BOOST_TEST_LDADD) \ $(BOOST_LDFLAGS) \ $(LIBEVENT_LIBS) OpenSSLManualInitTest_SOURCES = \ OpenSSLManualInitTest.cpp OpenSSLManualInitTest_LDADD = \ $(top_builddir)/lib/cpp/libthrift.la \ $(BOOST_TEST_LDADD) \ $(OPENSSL_LDFLAGS) \ $(OPENSSL_LIBS) # # 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/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 $< gen-cpp/TypedefTest_types.cpp gen-cpp/TypedefTest_types.h: $(top_srcdir)/test/TypedefTest.thrift $(THRIFT) --gen cpp $< gen-cpp/OptionalRequiredTest_types.cpp gen-cpp/OptionalRequiredTest_types.h: $(top_srcdir)/test/OptionalRequiredTest.thrift $(THRIFT) --gen cpp $< gen-cpp/Recursive_types.cpp gen-cpp/Recursive_types.h: $(top_srcdir)/test/Recursive.thrift $(THRIFT) --gen cpp $< 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/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 $< AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -I$(top_srcdir)/lib/cpp/src/thrift -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. AM_LDFLAGS = $(BOOST_LDFLAGS) AM_CXXFLAGS = -Wall -Wextra -pedantic clean-local: $(RM) gen-cpp/* distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ concurrency \ processor \ qt \ CMakeLists.txt \ DebugProtoTest_extras.cpp \ ThriftTest_extras.cpp \ OneWayTest.thrift \ Thrift5272.thrift thrift-0.23.0/lib/cpp/test/DebugProtoTest.cpp0000664000175000017500000003030315165535636021321 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define _USE_MATH_DEFINES #include #include "gen-cpp/DebugProtoTest_types.h" #include #include #define BOOST_TEST_MODULE DebugProtoTest #include using namespace thrift::test::debug; static ::std::shared_ptr ooe; void testCaseSetup_1() { ooe.reset(new OneOfEach); ooe->im_true = true; ooe->im_false = false; ooe->a_bite = 0x7f; ooe->integer16 = 27000; ooe->integer32 = 1 << 24; ooe->integer64 = (uint64_t)6000 * 1000 * 1000; ooe->double_precision = M_PI; ooe->some_characters = "Debug THIS!"; ooe->zomg_unicode = "\xd7\n\a\t"; } BOOST_AUTO_TEST_CASE(test_debug_proto_1) { testCaseSetup_1(); const std::string expected_result( "OneOfEach {\n" " 01: im_true (bool) = true,\n" " 02: im_false (bool) = false,\n" " 03: a_bite (byte) = 0x7f,\n" " 04: integer16 (i16) = 27000,\n" " 05: integer32 (i32) = 16777216,\n" " 06: integer64 (i64) = 6000000000,\n" " 07: double_precision (double) = 3.1415926535897931,\n" " 08: some_characters (string) = \"Debug THIS!\",\n" " 09: zomg_unicode (string) = \"\\xd7\\n\\a\\t\",\n" " 10: what_who (bool) = false,\n" " 11: base64 (string) = \"\",\n" " 12: byte_list (list) = list[3] {\n" " [0] = 0x01,\n" " [1] = 0x02,\n" " [2] = 0x03,\n" " },\n" " 13: i16_list (list) = list[3] {\n" " [0] = 1,\n" " [1] = 2,\n" " [2] = 3,\n" " },\n" " 14: i64_list (list) = list[3] {\n" " [0] = 1,\n" " [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)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } static ::std::shared_ptr n; void testCaseSetup_2() { using apache::thrift::TUuid; testCaseSetup_1(); n.reset(new Nesting); n->my_ooe = *ooe; n->my_ooe.integer16 = 16; n->my_ooe.integer32 = 32; n->my_ooe.integer64 = 64; n->my_ooe.double_precision = (std::sqrt(5.0) + 1) / 2; n->my_ooe.some_characters = ":R (me going \"rrrr\")"; n->my_ooe.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"; 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) { testCaseSetup_2(); const std::string expected_result( "Nesting {\n" " 01: my_bonk (struct) = Bonk {\n" " 01: type (i32) = 31337,\n" " 02: message (string) = \"I am a bonk... xor!\",\n" " },\n" " 02: my_ooe (struct) = OneOfEach {\n" " 01: im_true (bool) = true,\n" " 02: im_false (bool) = false,\n" " 03: a_bite (byte) = 0x7f,\n" " 04: integer16 (i16) = 16,\n" " 05: integer32 (i32) = 32,\n" " 06: integer64 (i64) = 64,\n" " 07: double_precision (double) = 1.6180339887498949,\n" " 08: some_characters (string) = \":R (me going \\\"rrrr\\\")\",\n" " 09: zomg_unicode (string) = \"\\xd3\\x80\\xe2\\x85\\xae\\xce\\x9d \\xd" "0\\x9d\\xce\\xbf\\xe2\\x85\\xbf\\xd0\\xbe\\xc9\\xa1\\xd0\\xb3\\xd0\\xb0" "\\xcf\\x81\\xe2\\x84\\x8e \\xce\\x91tt\\xce\\xb1\\xe2\\x85\\xbd\\xce\\xb" "a\\xc7\\x83\\xe2\\x80\\xbc\",\n" " 10: what_who (bool) = false,\n" " 11: base64 (string) = \"\",\n" " 12: byte_list (list) = list[3] {\n" " [0] = 0x01,\n" " [1] = 0x02,\n" " [2] = 0x03,\n" " },\n" " 13: i16_list (list) = list[3] {\n" " [0] = 1,\n" " [1] = 2,\n" " [2] = 3,\n" " },\n" " 14: i64_list (list) = list[3] {\n" " [0] = 1,\n" " [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)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } static ::std::shared_ptr hm; void testCaseSetup_3() { testCaseSetup_2(); hm.reset(new HolyMoley); hm->big.push_back(*ooe); hm->big.push_back(n->my_ooe); hm->big[0].a_bite = 0x22; hm->big[1].a_bite = 0x33; std::vector stage1; stage1.push_back("and a one"); stage1.push_back("and a two"); hm->contain.insert(stage1); stage1.clear(); stage1.push_back("then a one, two"); stage1.push_back("three!"); stage1.push_back("FOUR!!"); hm->contain.insert(stage1); stage1.clear(); hm->contain.insert(stage1); std::vector stage2; hm->bonks["nothing"] = stage2; stage2.resize(stage2.size() + 1); stage2.back().type = 1; stage2.back().message = "Wait."; stage2.resize(stage2.size() + 1); stage2.back().type = 2; stage2.back().message = "What?"; hm->bonks["something"] = stage2; stage2.clear(); stage2.resize(stage2.size() + 1); stage2.back().type = 3; stage2.back().message = "quoth"; stage2.resize(stage2.size() + 1); stage2.back().type = 4; stage2.back().message = "the raven"; stage2.resize(stage2.size() + 1); stage2.back().type = 5; stage2.back().message = "nevermore"; hm->bonks["poe"] = stage2; } BOOST_AUTO_TEST_CASE(test_debug_proto_3) { testCaseSetup_3(); const std::string expected_result( "HolyMoley {\n" " 01: big (list) = list[2] {\n" " [0] = OneOfEach {\n" " 01: im_true (bool) = true,\n" " 02: im_false (bool) = false,\n" " 03: a_bite (byte) = 0x22,\n" " 04: integer16 (i16) = 27000,\n" " 05: integer32 (i32) = 16777216,\n" " 06: integer64 (i64) = 6000000000,\n" " 07: double_precision (double) = 3.1415926535897931,\n" " 08: some_characters (string) = \"Debug THIS!\",\n" " 09: zomg_unicode (string) = \"\\xd7\\n\\a\\t\",\n" " 10: what_who (bool) = false,\n" " 11: base64 (string) = \"\",\n" " 12: byte_list (list) = list[3] {\n" " [0] = 0x01,\n" " [1] = 0x02,\n" " [2] = 0x03,\n" " },\n" " 13: i16_list (list) = list[3] {\n" " [0] = 1,\n" " [1] = 2,\n" " [2] = 3,\n" " },\n" " 14: i64_list (list) = list[3] {\n" " [0] = 1,\n" " [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" " 02: im_false (bool) = false,\n" " 03: a_bite (byte) = 0x33,\n" " 04: integer16 (i16) = 16,\n" " 05: integer32 (i32) = 32,\n" " 06: integer64 (i64) = 64,\n" " 07: double_precision (double) = 1.6180339887498949,\n" " 08: some_characters (string) = \":R (me going \\\"rrrr\\\")\",\n" " 09: zomg_unicode (string) = \"\\xd3\\x80\\xe2\\x85\\xae\\xce\\x9d \\" "xd0\\x9d\\xce\\xbf\\xe2\\x85\\xbf\\xd0\\xbe\\xc9\\xa1\\xd0\\xb3\\xd0\\xb" "0\\xcf\\x81\\xe2\\x84\\x8e \\xce\\x91tt\\xce\\xb1\\xe2\\x85\\xbd\\xce\\x" "ba\\xc7\\x83\\xe2\\x80\\xbc\",\n" " 10: what_who (bool) = false,\n" " 11: base64 (string) = \"\",\n" " 12: byte_list (list) = list[3] {\n" " [0] = 0x01,\n" " [1] = 0x02,\n" " [2] = 0x03,\n" " },\n" " 13: i16_list (list) = list[3] {\n" " [0] = 1,\n" " [1] = 2,\n" " [2] = 3,\n" " },\n" " 14: i64_list (list) = list[3] {\n" " [0] = 1,\n" " [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" " list[0] {\n" " },\n" " list[2] {\n" " [0] = \"and a one\",\n" " [1] = \"and a two\",\n" " },\n" " list[3] {\n" " [0] = \"then a one, two\",\n" " [1] = \"three!\",\n" " [2] = \"FOUR!!\",\n" " },\n" " },\n" " 03: bonks (map) = map[3] {\n" " \"nothing\" -> list[0] {\n" " },\n" " \"poe\" -> list[3] {\n" " [0] = Bonk {\n" " 01: type (i32) = 3,\n" " 02: message (string) = \"quoth\",\n" " },\n" " [1] = Bonk {\n" " 01: type (i32) = 4,\n" " 02: message (string) = \"the raven\",\n" " },\n" " [2] = Bonk {\n" " 01: type (i32) = 5,\n" " 02: message (string) = \"nevermore\",\n" " },\n" " },\n" " \"something\" -> list[2] {\n" " [0] = Bonk {\n" " 01: type (i32) = 1,\n" " 02: message (string) = \"Wait.\",\n" " },\n" " [1] = Bonk {\n" " 01: type (i32) = 2,\n" " 02: message (string) = \"What?\",\n" " },\n" " },\n" " },\n" "}"); const std::string result(apache::thrift::ThriftDebugString(*hm)); BOOST_CHECK_MESSAGE(!expected_result.compare(result), "Expected:\n" << expected_result << "\nGotten:\n" << result); } thrift-0.23.0/lib/cpp/coding_standards.md0000664000175000017500000000034515165535636020557 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) * see .clang-format in root dir for settings of accepted format * clang-format (3.5 or newer) can be used to automaticaly reformat code ('make style' command) thrift-0.23.0/lib/cpp/3rdparty.props0000664000175000017500000000172415165535636017566 0ustar00buildbuild00000000000000 $(THIRD_PARTY)\boost\boost_1_47_0 $(THIRD_PARTY)\openssl\OpenSSL-Win32 $(THIRD_PARTY)\libevent-2.0.21-stable $(BOOST_ROOT) true $(OPENSSL_ROOT_DIR) true $(LIBEVENT_ROOT) true thrift-0.23.0/lib/cpp/thrift.sln0000664000175000017500000000703715165535636016752 0ustar00buildbuild00000000000000 Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libthriftnb", "libthriftnb.vcxproj", "{D8696CCE-7D46-4659-B432-91754A41DEB0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libthrift", "libthrift.vcxproj", "{DD26F57E-60F2-4F37-A616-D219A9BF338F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{006984E0-7CC1-47E2-ACD2-A40FE4D38693}" ProjectSection(SolutionItems) = preProject README.md = README.md EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug-mt|Win32 = Debug-mt|Win32 Debug-mt|x64 = Debug-mt|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 Release-mt|Win32 = Release-mt|Win32 Release-mt|x64 = Release-mt|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug|Win32.ActiveCfg = Debug|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug|Win32.Build.0 = Debug|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug|x64.ActiveCfg = Debug|x64 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug|x64.Build.0 = Debug|x64 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug-mt|Win32.ActiveCfg = Debug-mt|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug-mt|Win32.Build.0 = Debug-mt|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug-mt|x64.ActiveCfg = Debug-mt|x64 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Debug-mt|x64.Build.0 = Debug-mt|x64 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release|Win32.ActiveCfg = Release|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release|Win32.Build.0 = Release|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release|x64.ActiveCfg = Release|x64 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release|x64.Build.0 = Release|x64 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release-mt|Win32.ActiveCfg = Release-mt|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release-mt|Win32.Build.0 = Release-mt|Win32 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release-mt|x64.ActiveCfg = Release-mt|x64 {D8696CCE-7D46-4659-B432-91754A41DEB0}.Release-mt|x64.Build.0 = Release-mt|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug|Win32.ActiveCfg = Debug|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug|Win32.Build.0 = Debug|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug|x64.ActiveCfg = Debug|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug|x64.Build.0 = Debug|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug-mt|Win32.ActiveCfg = Debug-mt|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug-mt|Win32.Build.0 = Debug-mt|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug-mt|x64.ActiveCfg = Debug-mt|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Debug-mt|x64.Build.0 = Debug-mt|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release|Win32.ActiveCfg = Release|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release|Win32.Build.0 = Release|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release|x64.ActiveCfg = Release|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release|x64.Build.0 = Release|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release-mt|Win32.ActiveCfg = Release-mt|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release-mt|Win32.Build.0 = Release-mt|Win32 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release-mt|x64.ActiveCfg = Release-mt|x64 {DD26F57E-60F2-4F37-A616-D219A9BF338F}.Release-mt|x64.Build.0 = Release-mt|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal thrift-0.23.0/lib/cpp/thrift-nb.pc.in0000664000175000017500000000177315165535636017563 0ustar00buildbuild00000000000000# # 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. # prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Thrift Description: Thrift Nonblocking API Version: @VERSION@ Requires: thrift = @VERSION@ Libs: -L${libdir} -lthriftnb Cflags: -I${includedir} thrift-0.23.0/lib/cpp/CMakeLists.txt0000664000175000017500000001572015167543515017467 0ustar00buildbuild00000000000000# # 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. # # Remove the following once lib/cpp no longer depends on boost headers: include(BoostMacros) REQUIRE_BOOST_HEADERS() include_directories(src) if(NOT BUILD_SHARED_LIBS) add_definitions("-DTHRIFT_STATIC_DEFINE") endif() # Create the thrift C++ library 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 src/thrift/async/TConcurrentClientSyncInfo.cpp src/thrift/concurrency/ThreadManager.cpp src/thrift/concurrency/TimerManager.cpp src/thrift/processor/PeekProcessor.cpp src/thrift/protocol/TBase64Utils.cpp src/thrift/protocol/TDebugProtocol.cpp src/thrift/protocol/TJSONProtocol.cpp src/thrift/protocol/TMultiplexedProtocol.cpp src/thrift/protocol/TProtocol.cpp src/thrift/transport/TTransportException.cpp src/thrift/transport/TFDTransport.cpp src/thrift/transport/TSimpleFileTransport.cpp src/thrift/transport/THttpTransport.cpp src/thrift/transport/THttpClient.cpp src/thrift/transport/THttpServer.cpp src/thrift/transport/TSocket.cpp src/thrift/transport/TSocketPool.cpp src/thrift/transport/TServerSocket.cpp src/thrift/transport/TTransportUtils.cpp src/thrift/transport/TBufferTransports.cpp src/thrift/transport/SocketCommon.cpp src/thrift/server/TConnectedClient.cpp src/thrift/server/TServerFramework.cpp src/thrift/server/TSimpleServer.cpp src/thrift/server/TThreadPoolServer.cpp src/thrift/server/TThreadedServer.cpp ) # These files don't work on Windows CE as there is no pipe support # TODO: These files won't work with UNICODE support on windows. If fixed this can be re-added. if (NOT WINCE) list(APPEND thriftcpp_SOURCES src/thrift/transport/TPipe.cpp src/thrift/transport/TPipeServer.cpp src/thrift/transport/TFileTransport.cpp ) endif() if (WIN32) list(APPEND thriftcpp_SOURCES src/thrift/windows/TWinsockSingleton.cpp src/thrift/windows/SocketPair.cpp src/thrift/windows/GetTimeOfDay.cpp src/thrift/windows/WinFcntl.cpp ) if(NOT WINCE) # This file uses pipes so it currently won't work on Windows CE list(APPEND thriftcpp_SOURCES src/thrift/windows/OverlappedSubmissionThread.cpp ) endif() else() # These files evaluate to nothing on Windows, so omit them from the # Windows build list(APPEND thriftcpp_SOURCES src/thrift/VirtualProfiling.cpp src/thrift/server/TServer.cpp ) endif() # If OpenSSL is not found or disabled just ignore the OpenSSL stuff if(OPENSSL_FOUND AND WITH_OPENSSL) list(APPEND thriftcpp_SOURCES src/thrift/transport/TSSLSocket.cpp src/thrift/transport/TSSLServerSocket.cpp src/thrift/transport/TWebSocketServer.h src/thrift/transport/TWebSocketServer.cpp ) if(TARGET OpenSSL::SSL OR TARGET OpenSSL::Crypto) if(TARGET OpenSSL::SSL) list(APPEND SYSLIBS OpenSSL::SSL) endif() if(TARGET OpenSSL::Crypto) list(APPEND SYSLIBS OpenSSL::Crypto) endif() else() include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") list(APPEND SYSLIBS "${OPENSSL_LIBRARIES}") endif() endif() if(UNIX) if(ANDROID) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") else() list(APPEND SYSLIBS pthread) endif() endif() set(thriftcpp_threads_SOURCES src/thrift/concurrency/ThreadFactory.cpp src/thrift/concurrency/Thread.cpp src/thrift/concurrency/Monitor.cpp src/thrift/concurrency/Mutex.cpp ) # Thrift non blocking server set(thriftcppnb_SOURCES src/thrift/server/TNonblockingServer.cpp src/thrift/transport/TNonblockingServerSocket.cpp src/thrift/async/TEvhttpServer.cpp src/thrift/async/TEvhttpClientChannel.cpp ) # If OpenSSL is not found or disabled just ignore the OpenSSL stuff if(OPENSSL_FOUND AND WITH_OPENSSL) list(APPEND thriftcppnb_SOURCES src/thrift/transport/TNonblockingSSLServerSocket.cpp ) endif() # Thrift zlib transport set(thriftcppz_SOURCES src/thrift/transport/TZlibTransport.cpp src/thrift/protocol/THeaderProtocol.cpp src/thrift/transport/THeaderTransport.cpp src/thrift/protocol/THeaderProtocol.cpp src/thrift/transport/THeaderTransport.cpp ) # Contains the thrift specific ADD_LIBRARY_THRIFT macro include(ThriftMacros) ADD_LIBRARY_THRIFT(thrift ${thriftcpp_SOURCES} ${thriftcpp_threads_SOURCES}) target_link_libraries(thrift PUBLIC ${SYSLIBS}) if(WIN32) target_link_libraries(thrift PUBLIC ws2_32) endif() ADD_PKGCONFIG_THRIFT(thrift) if(WITH_LIBEVENT) find_package(Libevent REQUIRED) # Libevent comes with CMake support from upstream include_directories(SYSTEM ${LIBEVENT_INCLUDE_DIRS}) ADD_LIBRARY_THRIFT(thriftnb ${thriftcppnb_SOURCES}) target_link_libraries(thriftnb PUBLIC thrift) if(TARGET libevent::core AND TARGET libevent::extra) # libevent was found via its cmake config, use modern style targets target_link_libraries(thriftnb PUBLIC libevent::core libevent::extra) else() target_link_libraries(thriftnb PUBLIC ${LIBEVENT_LIBRARIES}) endif() if(WIN32) target_link_libraries(thriftnb PUBLIC iphlpapi) endif() ADD_PKGCONFIG_THRIFT(thrift-nb) endif() if(WITH_ZLIB) find_package(ZLIB REQUIRED) ADD_LIBRARY_THRIFT(thriftz ${thriftcppz_SOURCES}) target_link_libraries(thriftz PUBLIC thrift) if(TARGET ZLIB::ZLIB) target_link_libraries(thriftz PUBLIC ZLIB::ZLIB) else() include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS}) target_link_libraries(thriftz PUBLIC ${ZLIB_LIBRARIES}) endif() ADD_PKGCONFIG_THRIFT(thrift-z) endif() if(WITH_QT5) add_subdirectory(src/thrift/qt) ADD_PKGCONFIG_THRIFT(thrift-qt5) endif() if(MSVC) add_definitions("-DUNICODE -D_UNICODE") endif() # Install the headers install(DIRECTORY "src/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}" FILES_MATCHING PATTERN "*.h" PATTERN "*.tcc") # Copy config.h file install(DIRECTORY "${CMAKE_BINARY_DIR}/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}" FILES_MATCHING PATTERN "*.h") if(BUILD_TESTING) add_subdirectory(test) endif() thrift-0.23.0/lib/cpp/README.md0000664000175000017500000003100215165535636016200 0ustar00buildbuild00000000000000Thrift C++ Software Library # License Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. # Using Thrift with C++ The Thrift C++ libraries are built using the GNU tools. Follow the instructions in the top-level README.md In case you do not want to open another README.md file, do this thrift src: ./bootstrap.sh ./configure (--with-boost=/usr/local) make sudo make install Thrift is divided into two libraries. * libthrift - The core Thrift library contains all the core Thrift code. This requires openssl, pthreads, and librt. * libthriftnb - This library contains the Thrift nonblocking server, which uses libevent. To link this library you will also need to link libevent. ## Linking Against Thrift After you build and install Thrift the libraries are installed to /usr/local/lib by default. Make sure this is in your LDPATH. On Linux, the best way to do this is to ensure that /usr/local/lib is in your /etc/ld.so.conf and then run /sbin/ldconfig. Depending upon whether you are linking dynamically or statically and how your build environment it set up, you may need to include additional libraries when linking against thrift, such as librt and/or libpthread. If you are using libthriftnb you will also need libevent. ## Dependencies C++11 is required at a minimum. C++03/C++98 are not supported after version 0.12.0. Boost is required to run the C++ unit tests. It is not necessary to link against the runtime library. libevent (for libthriftnb only) - most linux distributions have dev packages for this: http://monkey.org/~provos/libevent/ # Using Thrift with C++ on Windows Both the autoconf and cmake build systems are able to automatically detect many system configurations without the need to specify library locations, however if you run into problems or want to redirect thrift to build and link against your own provided third party libraries: BOOST_ROOT : For boost, e.g. D:\boost_1_55_0 OPENSSL_ROOT_DIR : For OpenSSL, e.g. D:\OpenSSL-Win32 only required by libthriftnb: LIBEVENT_ROOT_DIR : For Libevent e.g. D:\libevent-2.0.21-stable See /3rdparty.user for more details. The same linking guidelines described above for libthriftnb apply to windows as well. ## Linking Against Thrift You need to link your project that uses thrift against all the thrift dependencies; in the case of libthrift, openssl, pthreads, and librt and for libthriftnb, libevent. In the project properties you must also set HAVE_CONFIG_H as force include the config header: "windows/config.h" ## Dependencies libevent (for libthriftnb only) http://monkey.org/~provos/libevent/ ## Windows version compatibility The Thrift library targets Windows 7 or latter versions. The supports for windows XP and Vista are avaiable until 0.12.0. ## Thrift and the VCPKG Package manager You can download and install thrift using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager: git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh ./vcpkg integrate install ./vcpkg install thrift The thrift port in vcpkg is kept up to date by Microsoft team members and community contributors. The Apache Thrift project is *not* responsible for the vcpkg port. Therefore, if the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. ## Named Pipes Named Pipe transport has been added in the TPipe and TPipeServer classes. This is currently Windows-only. Named pipe transport for *NIX has not been implemented. Domain sockets are a better choice for local IPC under non-Windows OS's. *NIX named pipes only support 1:1 client-server connection. # Thrift/SSL ## Scope This SSL only supports blocking mode socket I/O. It can only be used with TSimpleServer, TThreadedServer, and TThreadPoolServer. ## Implementation There are two main classes TSSLSocketFactory and TSSLSocket. Instances of TSSLSocket are always created from TSSLSocketFactory. ## How to use SSL APIs See the TestClient.cpp and TestServer.cpp files for examples. ### AccessManager (certificate validation) An example of certificate validation can be found in TestServer.cpp. AccessManager defines a callback interface. It has three callback methods: (a) Decision verify(const sockaddr_storage& sa); (b) Decision verify(const string& host, const char* name, int size); (c) Decision verify(const sockaddr_storage& sa, const char* data, int size); After SSL handshake completes, additional checks are conducted. Application is given the chance to decide whether or not to continue the conversation with the remote. Application is queried through the above three "verify" method. They are called at different points of the verification process. Decisions can be one of ALLOW, DENY, and SKIP. ALLOW and DENY means the conversation should be continued or disconnected, respectively. ALLOW and DENY decision stops the verification process. SKIP means there's no decision based on the given input, continue the verification process. First, (a) is called with the remote IP. It is called once at the beginning. "sa" is the IP address of the remote peer. Then, the certificate of remote peer is loaded. SubjectAltName extensions are extracted and sent to application for verification. When a DNS subjectAltName field is extracted, (b) is called. When an IP subjectAltName field is extracted, (c) is called. The "host" in (b) is the value from TSocket::getHost() if this is a client side socket, or TSocket::getPeerHost() if this is a server side socket. The reason is client side socket initiates the connection. TSocket::getHost() is the remote host name. On server side, the remote host name is unknown unless it's retrieved through TSocket::getPeerHost(). Either way, "host" should be the remote host name. Keep in mind, if TSocket::getPeerHost() failed, it would return the remote host name in numeric format. If all subjectAltName extensions were "skipped", the common name field would be checked. It is sent to application through (c), where "sa" is the remote IP address. "data" is the IP address extracted from subjectAltName IP extension, and "size" is the length of the extension data. If any of the above "verify" methods returned a decision ALLOW or DENY, the verification process would be stopped. If any of the above "verify" methods returned SKIP, that decision would be ignored and the verification process would move on till the last item is examined. At that point, if there's still no decision, the connection is terminated. Thread safety, an access manager should not store state information if it's to be used by many SSL sockets. ## SIGPIPE signal Applications running OpenSSL over network connections may crash if SIGPIPE is not ignored. This happens when they receive a connection reset by remote peer exception, which somehow triggers a SIGPIPE signal. If not handled, this signal would kill the application. ## How to run test client/server in SSL mode The server and client expects the followings from the directory /test/ - keys/server.crt - keys/server.key - keys/CA.pem The file names are hard coded in the source code. You need to create these certificates before you can run the test code in SSL mode. Make sure at least one of the followings is included in "keys/server.crt", - subjectAltName, DNS localhost - subjectAltName, IP 127.0.0.1 - common name, localhost Run within /test/ folder, ./cpp/TestServer --ssl & ./cpp/TestClient --ssl If "-h " is used to run client, the above "localhost" in the above keys/server.crt has to be replaced with that host name. ## TSSLSocketFactory::randomize() The default implementation of OpenSSLSocketFactory::randomize() simply calls 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 Support for C++03/C++98 was deprecated. Support for Boost at runtime was deprecated. # Breaking Changes ## 1.0.0 THRIFT-4720: The classes Monitor and TimerManager now use std::chrono::milliseconds for timeout, the methods and functions involving THRIFT_TIMESPEC and timeval have been removed, the related tests have been modified. Support for Windows XP/Vista has been dropped. Support for C++03/C++98 has been dropped. Use version 0.12.0 to support that language level. As a consequence, boost is no longer required as a runtime library depenedency, but is is still required to build the runtime library and to run the unit tests. We will work towards removing boost as a build dependency for folks who just want to build the runtime and not run the tests. This means the header thrift/stdcxx.h has been removed and anything that relied on it has been changed to directly use C++11 concepts. THRIFT-4730: The classes BoostThreadFactory, PosixThreadFactory, StdThreadFactory, and PlatformThreadFactory have been removed, and we will use a ThreadFactory based on C++11 (essentially StdThreadFactory was renamed ThreadFactory). THRIFT-4732: The CMake build options WITH_SHARED_LIBS and WITH_STATIC_LIBS are deprecated. The project no longer performs a side-by-side static and shared build; you tell CMake through BUILD_SHARED_LIBS whether to make shared or static libraries now. This is CMake standard behavior. THRIFT-4735: Qt4 support was removed. THRIFT-4762: Added `const` specifier to `TTransport::getOrigin()`. This changes its function signature. It's recommended to add the `override` specifier in implementations derived from `TTransport`. ## 0.11.0 Older versions of thrift depended on the classes which were used in thrift headers to define interfaces. Thrift now detects C++11 at build time and will prefer to use classes from C++11 instead. You can force the library to build with boost memory classes by defining the preprocessor macro `FORCE_BOOST_SMART_PTR`. (THRIFT-2221) In the pthread mutex implementation, the contention profiling code was enabled by default in all builds. This changed to be disabled by default. (THRIFT-4151) In older releases, if a TSSLSocketFactory's lifetime was not at least as long as the TSSLSockets it created, we silently reverted openssl to unsafe multithread behavior and so the results were undefined. Changes were made in 0.11.0 that cause either an assertion or a core instead of undefined behavior. The lifetime of a TSSLSocketFactory *must* be longer than any TSSLSocket that it creates, otherwise openssl will be cleaned up too early. If the static boolean is set to disable openssl initialization and cleanup and leave it up to the consuming application, this requirement is not needed. (THRIFT-4164) thrift-0.23.0/lib/cpp/libthriftnb.vcxproj0000664000175000017500000004105415165535636020655 0ustar00buildbuild00000000000000 Debug-mt Win32 Debug-mt x64 Debug Win32 Debug x64 Release-mt Win32 Release-mt x64 Release Win32 Release x64 {D8696CCE-7D46-4659-B432-91754A41DEB0} Win32Proj libthriftnb StaticLibrary true MultiByte v140 StaticLibrary true MultiByte v140 StaticLibrary true MultiByte v140 StaticLibrary true MultiByte v140 StaticLibrary false true MultiByte v140 StaticLibrary false true MultiByte v140 StaticLibrary false true MultiByte v140 StaticLibrary false true MultiByte v140 $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;$(BOOST_ROOT)\include;$(BOOST_ROOT)\;$(LIBEVENT_ROOT)\WIN32-Code\;$(LIBEVENT_ROOT)\include;$(LIBEVENT_ROOT)\;$(IncludePath) Level3 Disabled HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;_DEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthriftnb.pdb MultiThreadedDebugDll Windows true Level3 Disabled HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;_DEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthriftnb.pdb MultiThreadedDebugDll Windows true Level3 Disabled HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebugDll Windows true Level3 Disabled HAVE_CONFIG_H=1;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebugDll Windows true Level3 MaxSpeed true true HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;NDEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthriftnb.pdb MultiThreadedDll Windows true true true Level3 MaxSpeed true true HAVE_CONFIG_H=1;WIN32;thrift_EXPORTS;NDEBUG;_LIB;%(PreprocessorDefinitions) $(IntDir)libthriftnb.pdb MultiThreadedDll Windows true true true Level3 MaxSpeed true true HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDll Windows true true true Level3 MaxSpeed true true HAVE_CONFIG_H=1;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDll Windows true true true thrift-0.23.0/lib/cpp/Makefile.in0000644000175000017500000027456415170007166016776 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_TESTS_TRUE@am__append_1 = test @AMX_HAVE_LIBEVENT_TRUE@am__append_2 = libthriftnb.la @AMX_HAVE_LIBEVENT_TRUE@am__append_3 = thrift-nb.pc @AMX_HAVE_ZLIB_TRUE@am__append_4 = libthriftz.la @AMX_HAVE_ZLIB_TRUE@am__append_5 = thrift-z.pc @AMX_HAVE_QT5_TRUE@am__append_6 = libthriftqt5.la @AMX_HAVE_QT5_TRUE@am__append_7 = thrift-qt5.pc @QT5_REDUCE_RELOCATIONS_TRUE@am__append_8 = -fPIC subdir = lib/cpp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(include_async_HEADERS) \ $(include_concurrency_HEADERS) $(include_processor_HEADERS) \ $(include_protocol_HEADERS) $(include_qt_HEADERS) \ $(include_server_HEADERS) $(include_thrift_HEADERS) \ $(include_transport_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = thrift-nb.pc thrift-z.pc thrift-qt5.pc thrift.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(include_asyncdir)" \ "$(DESTDIR)$(include_concurrencydir)" \ "$(DESTDIR)$(include_processordir)" \ "$(DESTDIR)$(include_protocoldir)" \ "$(DESTDIR)$(include_qtdir)" "$(DESTDIR)$(include_serverdir)" \ "$(DESTDIR)$(include_thriftdir)" \ "$(DESTDIR)$(include_transportdir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libthrift_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__dirstamp = $(am__leading_dot)dirstamp am_libthrift_la_OBJECTS = src/thrift/TApplicationException.lo \ src/thrift/TOutput.lo src/thrift/TUuid.lo \ src/thrift/VirtualProfiling.lo \ src/thrift/async/TAsyncChannel.lo \ src/thrift/async/TAsyncProtocolProcessor.lo \ src/thrift/async/TConcurrentClientSyncInfo.lo \ src/thrift/concurrency/ThreadManager.lo \ src/thrift/concurrency/TimerManager.lo \ src/thrift/processor/PeekProcessor.lo \ src/thrift/protocol/TDebugProtocol.lo \ src/thrift/protocol/TJSONProtocol.lo \ src/thrift/protocol/TBase64Utils.lo \ src/thrift/protocol/TMultiplexedProtocol.lo \ src/thrift/protocol/TProtocol.lo \ src/thrift/transport/TTransportException.lo \ src/thrift/transport/TFDTransport.lo \ src/thrift/transport/TFileTransport.lo \ src/thrift/transport/TSimpleFileTransport.lo \ src/thrift/transport/THttpTransport.lo \ src/thrift/transport/THttpClient.lo \ src/thrift/transport/THttpServer.lo \ src/thrift/transport/TSocket.lo src/thrift/transport/TPipe.lo \ src/thrift/transport/TPipeServer.lo \ src/thrift/transport/TSSLSocket.lo \ src/thrift/transport/TSocketPool.lo \ src/thrift/transport/TServerSocket.lo \ src/thrift/transport/TSSLServerSocket.lo \ src/thrift/transport/TNonblockingServerSocket.lo \ src/thrift/transport/TNonblockingSSLServerSocket.lo \ src/thrift/transport/TTransportUtils.lo \ src/thrift/transport/TBufferTransports.lo \ src/thrift/transport/TWebSocketServer.lo \ src/thrift/transport/SocketCommon.lo \ src/thrift/server/TConnectedClient.lo \ src/thrift/server/TServer.lo \ src/thrift/server/TServerFramework.lo \ src/thrift/server/TSimpleServer.lo \ src/thrift/server/TThreadPoolServer.lo \ src/thrift/server/TThreadedServer.lo \ src/thrift/concurrency/Mutex.lo \ src/thrift/concurrency/ThreadFactory.lo \ src/thrift/concurrency/Thread.lo \ src/thrift/concurrency/Monitor.lo libthrift_la_OBJECTS = $(am_libthrift_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libthrift_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libthrift_la_LDFLAGS) $(LDFLAGS) -o $@ libthriftnb_la_LIBADD = am_libthriftnb_la_OBJECTS = \ src/thrift/server/libthriftnb_la-TNonblockingServer.lo \ src/thrift/async/libthriftnb_la-TEvhttpServer.lo \ src/thrift/async/libthriftnb_la-TEvhttpClientChannel.lo libthriftnb_la_OBJECTS = $(am_libthriftnb_la_OBJECTS) libthriftnb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libthriftnb_la_CXXFLAGS) $(CXXFLAGS) \ $(libthriftnb_la_LDFLAGS) $(LDFLAGS) -o $@ @AMX_HAVE_LIBEVENT_TRUE@am_libthriftnb_la_rpath = -rpath $(libdir) libthriftqt5_la_LIBADD = am_libthriftqt5_la_OBJECTS = \ src/thrift/qt/libthriftqt5_la-TQIODeviceTransport.lo \ src/thrift/qt/libthriftqt5_la-TQTcpServer.lo am__objects_1 = src/thrift/qt/libthriftqt5_la-moc__TQTcpServer.lo nodist_libthriftqt5_la_OBJECTS = $(am__objects_1) libthriftqt5_la_OBJECTS = $(am_libthriftqt5_la_OBJECTS) \ $(nodist_libthriftqt5_la_OBJECTS) libthriftqt5_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libthriftqt5_la_CXXFLAGS) $(CXXFLAGS) \ $(libthriftqt5_la_LDFLAGS) $(LDFLAGS) -o $@ @AMX_HAVE_QT5_TRUE@am_libthriftqt5_la_rpath = -rpath $(libdir) libthriftz_la_LIBADD = am_libthriftz_la_OBJECTS = \ src/thrift/transport/libthriftz_la-TZlibTransport.lo \ src/thrift/transport/libthriftz_la-THeaderTransport.lo \ src/thrift/protocol/libthriftz_la-THeaderProtocol.lo libthriftz_la_OBJECTS = $(am_libthriftz_la_OBJECTS) libthriftz_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libthriftz_la_CXXFLAGS) $(CXXFLAGS) $(libthriftz_la_LDFLAGS) \ $(LDFLAGS) -o $@ @AMX_HAVE_ZLIB_TRUE@am_libthriftz_la_rpath = -rpath $(libdir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = src/thrift/$(DEPDIR)/TApplicationException.Plo \ src/thrift/$(DEPDIR)/TOutput.Plo \ src/thrift/$(DEPDIR)/TUuid.Plo \ src/thrift/$(DEPDIR)/VirtualProfiling.Plo \ src/thrift/async/$(DEPDIR)/TAsyncChannel.Plo \ src/thrift/async/$(DEPDIR)/TAsyncProtocolProcessor.Plo \ src/thrift/async/$(DEPDIR)/TConcurrentClientSyncInfo.Plo \ src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpClientChannel.Plo \ src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpServer.Plo \ src/thrift/concurrency/$(DEPDIR)/Monitor.Plo \ src/thrift/concurrency/$(DEPDIR)/Mutex.Plo \ src/thrift/concurrency/$(DEPDIR)/Thread.Plo \ src/thrift/concurrency/$(DEPDIR)/ThreadFactory.Plo \ src/thrift/concurrency/$(DEPDIR)/ThreadManager.Plo \ src/thrift/concurrency/$(DEPDIR)/TimerManager.Plo \ src/thrift/processor/$(DEPDIR)/PeekProcessor.Plo \ src/thrift/protocol/$(DEPDIR)/TBase64Utils.Plo \ src/thrift/protocol/$(DEPDIR)/TDebugProtocol.Plo \ src/thrift/protocol/$(DEPDIR)/TJSONProtocol.Plo \ src/thrift/protocol/$(DEPDIR)/TMultiplexedProtocol.Plo \ src/thrift/protocol/$(DEPDIR)/TProtocol.Plo \ src/thrift/protocol/$(DEPDIR)/libthriftz_la-THeaderProtocol.Plo \ src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQIODeviceTransport.Plo \ src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQTcpServer.Plo \ src/thrift/qt/$(DEPDIR)/libthriftqt5_la-moc__TQTcpServer.Plo \ src/thrift/server/$(DEPDIR)/TConnectedClient.Plo \ src/thrift/server/$(DEPDIR)/TServer.Plo \ src/thrift/server/$(DEPDIR)/TServerFramework.Plo \ src/thrift/server/$(DEPDIR)/TSimpleServer.Plo \ src/thrift/server/$(DEPDIR)/TThreadPoolServer.Plo \ src/thrift/server/$(DEPDIR)/TThreadedServer.Plo \ src/thrift/server/$(DEPDIR)/libthriftnb_la-TNonblockingServer.Plo \ src/thrift/transport/$(DEPDIR)/SocketCommon.Plo \ src/thrift/transport/$(DEPDIR)/TBufferTransports.Plo \ src/thrift/transport/$(DEPDIR)/TFDTransport.Plo \ src/thrift/transport/$(DEPDIR)/TFileTransport.Plo \ src/thrift/transport/$(DEPDIR)/THttpClient.Plo \ src/thrift/transport/$(DEPDIR)/THttpServer.Plo \ src/thrift/transport/$(DEPDIR)/THttpTransport.Plo \ src/thrift/transport/$(DEPDIR)/TNonblockingSSLServerSocket.Plo \ src/thrift/transport/$(DEPDIR)/TNonblockingServerSocket.Plo \ src/thrift/transport/$(DEPDIR)/TPipe.Plo \ src/thrift/transport/$(DEPDIR)/TPipeServer.Plo \ src/thrift/transport/$(DEPDIR)/TSSLServerSocket.Plo \ src/thrift/transport/$(DEPDIR)/TSSLSocket.Plo \ src/thrift/transport/$(DEPDIR)/TServerSocket.Plo \ src/thrift/transport/$(DEPDIR)/TSimpleFileTransport.Plo \ src/thrift/transport/$(DEPDIR)/TSocket.Plo \ src/thrift/transport/$(DEPDIR)/TSocketPool.Plo \ src/thrift/transport/$(DEPDIR)/TTransportException.Plo \ src/thrift/transport/$(DEPDIR)/TTransportUtils.Plo \ src/thrift/transport/$(DEPDIR)/TWebSocketServer.Plo \ src/thrift/transport/$(DEPDIR)/libthriftz_la-THeaderTransport.Plo \ src/thrift/transport/$(DEPDIR)/libthriftz_la-TZlibTransport.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libthrift_la_SOURCES) $(libthriftnb_la_SOURCES) \ $(libthriftqt5_la_SOURCES) $(nodist_libthriftqt5_la_SOURCES) \ $(libthriftz_la_SOURCES) DIST_SOURCES = $(libthrift_la_SOURCES) $(libthriftnb_la_SOURCES) \ $(libthriftqt5_la_SOURCES) $(libthriftz_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(pkgconfig_DATA) HEADERS = $(include_async_HEADERS) $(include_concurrency_HEADERS) \ $(include_processor_HEADERS) $(include_protocol_HEADERS) \ $(include_qt_HEADERS) $(include_server_HEADERS) \ $(include_thrift_HEADERS) $(include_transport_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = . test am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/thrift-nb.pc.in \ $(srcdir)/thrift-qt5.pc.in $(srcdir)/thrift-z.pc.in \ $(srcdir)/thrift.pc.in $(top_srcdir)/depcomp README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = subdir-objects nostdinc SUBDIRS = . $(am__append_1) pkgconfigdir = $(libdir)/pkgconfig lib_LTLIBRARIES = libthrift.la $(am__append_2) $(am__append_4) \ $(am__append_6) pkgconfig_DATA = thrift.pc $(am__append_3) $(am__append_5) \ $(am__append_7) libthrift_la_LDFLAGS = -release $(VERSION) libthrift_la_LIBADD = $(BOOST_LDFLAGS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) AM_CXXFLAGS = -Wall -Wextra -pedantic AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS # Define the source files for the module 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 \ src/thrift/async/TConcurrentClientSyncInfo.cpp \ src/thrift/concurrency/ThreadManager.cpp \ src/thrift/concurrency/TimerManager.cpp \ src/thrift/processor/PeekProcessor.cpp \ src/thrift/protocol/TDebugProtocol.cpp \ src/thrift/protocol/TJSONProtocol.cpp \ src/thrift/protocol/TBase64Utils.cpp \ src/thrift/protocol/TMultiplexedProtocol.cpp \ src/thrift/protocol/TProtocol.cpp \ src/thrift/transport/TTransportException.cpp \ src/thrift/transport/TFDTransport.cpp \ src/thrift/transport/TFileTransport.cpp \ src/thrift/transport/TSimpleFileTransport.cpp \ src/thrift/transport/THttpTransport.cpp \ src/thrift/transport/THttpClient.cpp \ src/thrift/transport/THttpServer.cpp \ src/thrift/transport/TSocket.cpp \ src/thrift/transport/TPipe.cpp \ src/thrift/transport/TPipeServer.cpp \ src/thrift/transport/TSSLSocket.cpp \ src/thrift/transport/TSocketPool.cpp \ src/thrift/transport/TServerSocket.cpp \ src/thrift/transport/TSSLServerSocket.cpp \ src/thrift/transport/TNonblockingServerSocket.cpp \ src/thrift/transport/TNonblockingSSLServerSocket.cpp \ src/thrift/transport/TTransportUtils.cpp \ src/thrift/transport/TBufferTransports.cpp \ src/thrift/transport/TWebSocketServer.cpp \ src/thrift/transport/SocketCommon.cpp \ src/thrift/server/TConnectedClient.cpp \ src/thrift/server/TServer.cpp \ src/thrift/server/TServerFramework.cpp \ src/thrift/server/TSimpleServer.cpp \ src/thrift/server/TThreadPoolServer.cpp \ src/thrift/server/TThreadedServer.cpp \ src/thrift/concurrency/Mutex.cpp \ src/thrift/concurrency/ThreadFactory.cpp \ src/thrift/concurrency/Thread.cpp \ src/thrift/concurrency/Monitor.cpp libthriftnb_la_SOURCES = src/thrift/server/TNonblockingServer.cpp \ src/thrift/async/TEvhttpServer.cpp \ src/thrift/async/TEvhttpClientChannel.cpp libthriftz_la_SOURCES = src/thrift/transport/TZlibTransport.cpp \ src/thrift/transport/THeaderTransport.cpp \ src/thrift/protocol/THeaderProtocol.cpp libthriftqt5_la_MOC = src/thrift/qt/moc__TQTcpServer.cpp nodist_libthriftqt5_la_SOURCES = $(libthriftqt5_la_MOC) libthriftqt5_la_SOURCES = src/thrift/qt/TQIODeviceTransport.cpp \ src/thrift/qt/TQTcpServer.cpp CLEANFILES = $(libthriftqt5_la_MOC) # Flags for the various libraries libthriftnb_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBEVENT_CPPFLAGS) libthriftz_la_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CPPFLAGS) libthriftqt5_la_CPPFLAGS = $(AM_CPPFLAGS) $(QT5_CFLAGS) \ $(am__append_8) libthriftnb_la_CXXFLAGS = $(AM_CXXFLAGS) libthriftz_la_CXXFLAGS = $(AM_CXXFLAGS) libthriftqt5_la_CXXFLAGS = $(AM_CXXFLAGS) libthriftnb_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) libthriftz_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(ZLIB_LDFLAGS) $(ZLIB_LIBS) libthriftqt5_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT5_LIBS) include_thriftdir = $(includedir)/thrift include_thrift_HEADERS = \ $(top_builddir)/config.h \ src/thrift/thrift-config.h \ src/thrift/thrift_export.h \ src/thrift/TDispatchProcessor.h \ src/thrift/TUuid.h \ src/thrift/Thrift.h \ src/thrift/TOutput.h \ src/thrift/TProcessor.h \ src/thrift/TApplicationException.h \ src/thrift/TLogging.h \ src/thrift/TPrintTo.h \ src/thrift/TToString.h \ src/thrift/TBase.h \ src/thrift/TConfiguration.h \ src/thrift/TNonCopyable.h include_concurrencydir = $(include_thriftdir)/concurrency include_concurrency_HEADERS = \ src/thrift/concurrency/Exception.h \ src/thrift/concurrency/Mutex.h \ src/thrift/concurrency/Monitor.h \ src/thrift/concurrency/ThreadFactory.h \ src/thrift/concurrency/Thread.h \ src/thrift/concurrency/ThreadManager.h \ src/thrift/concurrency/TimerManager.h \ src/thrift/concurrency/FunctionRunner.h include_protocoldir = $(include_thriftdir)/protocol include_protocol_HEADERS = \ src/thrift/protocol/TEnum.h \ src/thrift/protocol/TList.h \ src/thrift/protocol/TSet.h \ src/thrift/protocol/TMap.h \ src/thrift/protocol/TBinaryProtocol.h \ src/thrift/protocol/TBinaryProtocol.tcc \ src/thrift/protocol/TCompactProtocol.h \ src/thrift/protocol/TCompactProtocol.tcc \ src/thrift/protocol/TDebugProtocol.h \ src/thrift/protocol/THeaderProtocol.h \ src/thrift/protocol/TBase64Utils.h \ src/thrift/protocol/TJSONProtocol.h \ src/thrift/protocol/TMultiplexedProtocol.h \ src/thrift/protocol/TProtocolDecorator.h \ src/thrift/protocol/TProtocolTap.h \ src/thrift/protocol/TProtocolTypes.h \ src/thrift/protocol/TProtocolException.h \ src/thrift/protocol/TVirtualProtocol.h \ src/thrift/protocol/TProtocol.h include_transportdir = $(include_thriftdir)/transport include_transport_HEADERS = \ src/thrift/transport/PlatformSocket.h \ src/thrift/transport/TFDTransport.h \ src/thrift/transport/TFileTransport.h \ src/thrift/transport/THeaderTransport.h \ src/thrift/transport/TSimpleFileTransport.h \ src/thrift/transport/TServerSocket.h \ src/thrift/transport/TSSLServerSocket.h \ src/thrift/transport/TServerTransport.h \ src/thrift/transport/TNonblockingServerTransport.h \ src/thrift/transport/TNonblockingServerSocket.h \ src/thrift/transport/TNonblockingSSLServerSocket.h \ src/thrift/transport/THttpTransport.h \ src/thrift/transport/THttpClient.h \ src/thrift/transport/THttpServer.h \ src/thrift/transport/TSocket.h \ src/thrift/transport/TSocketUtils.h \ src/thrift/transport/TPipe.h \ src/thrift/transport/TPipeServer.h \ src/thrift/transport/TSSLSocket.h \ src/thrift/transport/TSocketPool.h \ src/thrift/transport/TVirtualTransport.h \ src/thrift/transport/TTransport.h \ src/thrift/transport/TTransportException.h \ src/thrift/transport/TTransportUtils.h \ src/thrift/transport/TBufferTransports.h \ src/thrift/transport/TShortReadTransport.h \ src/thrift/transport/TZlibTransport.h \ src/thrift/transport/TWebSocketServer.h \ src/thrift/transport/SocketCommon.h include_serverdir = $(include_thriftdir)/server include_server_HEADERS = \ src/thrift/server/TConnectedClient.h \ src/thrift/server/TServer.h \ src/thrift/server/TServerFramework.h \ src/thrift/server/TSimpleServer.h \ src/thrift/server/TThreadPoolServer.h \ src/thrift/server/TThreadedServer.h \ src/thrift/server/TNonblockingServer.h include_processordir = $(include_thriftdir)/processor include_processor_HEADERS = \ src/thrift/processor/PeekProcessor.h \ src/thrift/processor/StatsProcessor.h \ src/thrift/processor/TMultiplexedProcessor.h include_asyncdir = $(include_thriftdir)/async include_async_HEADERS = \ src/thrift/async/TAsyncChannel.h \ src/thrift/async/TAsyncDispatchProcessor.h \ src/thrift/async/TAsyncProcessor.h \ src/thrift/async/TAsyncBufferProcessor.h \ src/thrift/async/TAsyncProtocolProcessor.h \ src/thrift/async/TConcurrentClientSyncInfo.h \ src/thrift/async/TEvhttpClientChannel.h \ src/thrift/async/TEvhttpServer.h include_qtdir = $(include_thriftdir)/qt include_qt_HEADERS = \ src/thrift/qt/TQIODeviceTransport.h \ src/thrift/qt/TQTcpServer.h WINDOWS_DIST = \ src/thrift/windows \ thrift.sln \ libthrift.vcxproj \ libthrift.vcxproj.filters \ libthriftnb.vcxproj \ libthriftnb.vcxproj.filters \ 3rdparty.props EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ README.md \ thrift-nb.pc.in \ thrift.pc.in \ thrift-z.pc.in \ thrift-qt5.pc.in \ src/thrift/qt/CMakeLists.txt \ $(WINDOWS_DIST) all: all-recursive .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/cpp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/cpp/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): thrift-nb.pc: $(top_builddir)/config.status $(srcdir)/thrift-nb.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ thrift-z.pc: $(top_builddir)/config.status $(srcdir)/thrift-z.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ thrift-qt5.pc: $(top_builddir)/config.status $(srcdir)/thrift-qt5.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ thrift.pc: $(top_builddir)/config.status $(srcdir)/thrift.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } src/thrift/$(am__dirstamp): @$(MKDIR_P) src/thrift @: > src/thrift/$(am__dirstamp) src/thrift/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/$(DEPDIR) @: > src/thrift/$(DEPDIR)/$(am__dirstamp) src/thrift/TApplicationException.lo: src/thrift/$(am__dirstamp) \ src/thrift/$(DEPDIR)/$(am__dirstamp) src/thrift/TOutput.lo: src/thrift/$(am__dirstamp) \ src/thrift/$(DEPDIR)/$(am__dirstamp) src/thrift/TUuid.lo: src/thrift/$(am__dirstamp) \ src/thrift/$(DEPDIR)/$(am__dirstamp) src/thrift/VirtualProfiling.lo: src/thrift/$(am__dirstamp) \ src/thrift/$(DEPDIR)/$(am__dirstamp) src/thrift/async/$(am__dirstamp): @$(MKDIR_P) src/thrift/async @: > src/thrift/async/$(am__dirstamp) src/thrift/async/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/async/$(DEPDIR) @: > src/thrift/async/$(DEPDIR)/$(am__dirstamp) src/thrift/async/TAsyncChannel.lo: src/thrift/async/$(am__dirstamp) \ src/thrift/async/$(DEPDIR)/$(am__dirstamp) src/thrift/async/TAsyncProtocolProcessor.lo: \ src/thrift/async/$(am__dirstamp) \ src/thrift/async/$(DEPDIR)/$(am__dirstamp) src/thrift/async/TConcurrentClientSyncInfo.lo: \ src/thrift/async/$(am__dirstamp) \ src/thrift/async/$(DEPDIR)/$(am__dirstamp) src/thrift/concurrency/$(am__dirstamp): @$(MKDIR_P) src/thrift/concurrency @: > src/thrift/concurrency/$(am__dirstamp) src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/concurrency/$(DEPDIR) @: > src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) src/thrift/concurrency/ThreadManager.lo: \ src/thrift/concurrency/$(am__dirstamp) \ src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) src/thrift/concurrency/TimerManager.lo: \ src/thrift/concurrency/$(am__dirstamp) \ src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) src/thrift/processor/$(am__dirstamp): @$(MKDIR_P) src/thrift/processor @: > src/thrift/processor/$(am__dirstamp) src/thrift/processor/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/processor/$(DEPDIR) @: > src/thrift/processor/$(DEPDIR)/$(am__dirstamp) src/thrift/processor/PeekProcessor.lo: \ src/thrift/processor/$(am__dirstamp) \ src/thrift/processor/$(DEPDIR)/$(am__dirstamp) src/thrift/protocol/$(am__dirstamp): @$(MKDIR_P) src/thrift/protocol @: > src/thrift/protocol/$(am__dirstamp) src/thrift/protocol/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/protocol/$(DEPDIR) @: > src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/protocol/TDebugProtocol.lo: \ src/thrift/protocol/$(am__dirstamp) \ src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/protocol/TJSONProtocol.lo: \ src/thrift/protocol/$(am__dirstamp) \ src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/protocol/TBase64Utils.lo: \ src/thrift/protocol/$(am__dirstamp) \ src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/protocol/TMultiplexedProtocol.lo: \ src/thrift/protocol/$(am__dirstamp) \ src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/protocol/TProtocol.lo: src/thrift/protocol/$(am__dirstamp) \ src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/$(am__dirstamp): @$(MKDIR_P) src/thrift/transport @: > src/thrift/transport/$(am__dirstamp) src/thrift/transport/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/transport/$(DEPDIR) @: > src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TTransportException.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TFDTransport.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TFileTransport.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TSimpleFileTransport.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/THttpTransport.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/THttpClient.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/THttpServer.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TSocket.lo: src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TPipe.lo: src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TPipeServer.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TSSLSocket.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TSocketPool.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TServerSocket.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TSSLServerSocket.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TNonblockingServerSocket.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TNonblockingSSLServerSocket.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TTransportUtils.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TBufferTransports.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/TWebSocketServer.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/SocketCommon.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/server/$(am__dirstamp): @$(MKDIR_P) src/thrift/server @: > src/thrift/server/$(am__dirstamp) src/thrift/server/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/server/$(DEPDIR) @: > src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/server/TConnectedClient.lo: \ src/thrift/server/$(am__dirstamp) \ src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/server/TServer.lo: src/thrift/server/$(am__dirstamp) \ src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/server/TServerFramework.lo: \ src/thrift/server/$(am__dirstamp) \ src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/server/TSimpleServer.lo: src/thrift/server/$(am__dirstamp) \ src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/server/TThreadPoolServer.lo: \ src/thrift/server/$(am__dirstamp) \ src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/server/TThreadedServer.lo: \ src/thrift/server/$(am__dirstamp) \ src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/concurrency/Mutex.lo: \ src/thrift/concurrency/$(am__dirstamp) \ src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) src/thrift/concurrency/ThreadFactory.lo: \ src/thrift/concurrency/$(am__dirstamp) \ src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) src/thrift/concurrency/Thread.lo: \ src/thrift/concurrency/$(am__dirstamp) \ src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) src/thrift/concurrency/Monitor.lo: \ src/thrift/concurrency/$(am__dirstamp) \ src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) libthrift.la: $(libthrift_la_OBJECTS) $(libthrift_la_DEPENDENCIES) $(EXTRA_libthrift_la_DEPENDENCIES) $(AM_V_CXXLD)$(libthrift_la_LINK) -rpath $(libdir) $(libthrift_la_OBJECTS) $(libthrift_la_LIBADD) $(LIBS) src/thrift/server/libthriftnb_la-TNonblockingServer.lo: \ src/thrift/server/$(am__dirstamp) \ src/thrift/server/$(DEPDIR)/$(am__dirstamp) src/thrift/async/libthriftnb_la-TEvhttpServer.lo: \ src/thrift/async/$(am__dirstamp) \ src/thrift/async/$(DEPDIR)/$(am__dirstamp) src/thrift/async/libthriftnb_la-TEvhttpClientChannel.lo: \ src/thrift/async/$(am__dirstamp) \ src/thrift/async/$(DEPDIR)/$(am__dirstamp) libthriftnb.la: $(libthriftnb_la_OBJECTS) $(libthriftnb_la_DEPENDENCIES) $(EXTRA_libthriftnb_la_DEPENDENCIES) $(AM_V_CXXLD)$(libthriftnb_la_LINK) $(am_libthriftnb_la_rpath) $(libthriftnb_la_OBJECTS) $(libthriftnb_la_LIBADD) $(LIBS) src/thrift/qt/$(am__dirstamp): @$(MKDIR_P) src/thrift/qt @: > src/thrift/qt/$(am__dirstamp) src/thrift/qt/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/thrift/qt/$(DEPDIR) @: > src/thrift/qt/$(DEPDIR)/$(am__dirstamp) src/thrift/qt/libthriftqt5_la-TQIODeviceTransport.lo: \ src/thrift/qt/$(am__dirstamp) \ src/thrift/qt/$(DEPDIR)/$(am__dirstamp) src/thrift/qt/libthriftqt5_la-TQTcpServer.lo: \ src/thrift/qt/$(am__dirstamp) \ src/thrift/qt/$(DEPDIR)/$(am__dirstamp) src/thrift/qt/libthriftqt5_la-moc__TQTcpServer.lo: \ src/thrift/qt/$(am__dirstamp) \ src/thrift/qt/$(DEPDIR)/$(am__dirstamp) libthriftqt5.la: $(libthriftqt5_la_OBJECTS) $(libthriftqt5_la_DEPENDENCIES) $(EXTRA_libthriftqt5_la_DEPENDENCIES) $(AM_V_CXXLD)$(libthriftqt5_la_LINK) $(am_libthriftqt5_la_rpath) $(libthriftqt5_la_OBJECTS) $(libthriftqt5_la_LIBADD) $(LIBS) src/thrift/transport/libthriftz_la-TZlibTransport.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/transport/libthriftz_la-THeaderTransport.lo: \ src/thrift/transport/$(am__dirstamp) \ src/thrift/transport/$(DEPDIR)/$(am__dirstamp) src/thrift/protocol/libthriftz_la-THeaderProtocol.lo: \ src/thrift/protocol/$(am__dirstamp) \ src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) libthriftz.la: $(libthriftz_la_OBJECTS) $(libthriftz_la_DEPENDENCIES) $(EXTRA_libthriftz_la_DEPENDENCIES) $(AM_V_CXXLD)$(libthriftz_la_LINK) $(am_libthriftz_la_rpath) $(libthriftz_la_OBJECTS) $(libthriftz_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f src/thrift/*.$(OBJEXT) -rm -f src/thrift/*.lo -rm -f src/thrift/async/*.$(OBJEXT) -rm -f src/thrift/async/*.lo -rm -f src/thrift/concurrency/*.$(OBJEXT) -rm -f src/thrift/concurrency/*.lo -rm -f src/thrift/processor/*.$(OBJEXT) -rm -f src/thrift/processor/*.lo -rm -f src/thrift/protocol/*.$(OBJEXT) -rm -f src/thrift/protocol/*.lo -rm -f src/thrift/qt/*.$(OBJEXT) -rm -f src/thrift/qt/*.lo -rm -f src/thrift/server/*.$(OBJEXT) -rm -f src/thrift/server/*.lo -rm -f src/thrift/transport/*.$(OBJEXT) -rm -f src/thrift/transport/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/$(DEPDIR)/TApplicationException.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/$(DEPDIR)/TOutput.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/$(DEPDIR)/TUuid.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/$(DEPDIR)/VirtualProfiling.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/async/$(DEPDIR)/TAsyncChannel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/async/$(DEPDIR)/TAsyncProtocolProcessor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/async/$(DEPDIR)/TConcurrentClientSyncInfo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpClientChannel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/concurrency/$(DEPDIR)/Monitor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/concurrency/$(DEPDIR)/Mutex.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/concurrency/$(DEPDIR)/Thread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/concurrency/$(DEPDIR)/ThreadFactory.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/concurrency/$(DEPDIR)/ThreadManager.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/concurrency/$(DEPDIR)/TimerManager.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/processor/$(DEPDIR)/PeekProcessor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/protocol/$(DEPDIR)/TBase64Utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/protocol/$(DEPDIR)/TDebugProtocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/protocol/$(DEPDIR)/TJSONProtocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/protocol/$(DEPDIR)/TMultiplexedProtocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/protocol/$(DEPDIR)/TProtocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/protocol/$(DEPDIR)/libthriftz_la-THeaderProtocol.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQIODeviceTransport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQTcpServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/qt/$(DEPDIR)/libthriftqt5_la-moc__TQTcpServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/server/$(DEPDIR)/TConnectedClient.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/server/$(DEPDIR)/TServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/server/$(DEPDIR)/TServerFramework.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/server/$(DEPDIR)/TSimpleServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/server/$(DEPDIR)/TThreadPoolServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/server/$(DEPDIR)/TThreadedServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/server/$(DEPDIR)/libthriftnb_la-TNonblockingServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/SocketCommon.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TBufferTransports.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TFDTransport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TFileTransport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/THttpClient.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/THttpServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/THttpTransport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TNonblockingSSLServerSocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TNonblockingServerSocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TPipe.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TPipeServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TSSLServerSocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TSSLSocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TServerSocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TSimpleFileTransport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TSocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TSocketPool.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TTransportException.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TTransportUtils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/TWebSocketServer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/libthriftz_la-THeaderTransport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/thrift/transport/$(DEPDIR)/libthriftz_la-TZlibTransport.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< src/thrift/server/libthriftnb_la-TNonblockingServer.lo: src/thrift/server/TNonblockingServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftnb_la_CPPFLAGS) $(CPPFLAGS) $(libthriftnb_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/server/libthriftnb_la-TNonblockingServer.lo -MD -MP -MF src/thrift/server/$(DEPDIR)/libthriftnb_la-TNonblockingServer.Tpo -c -o src/thrift/server/libthriftnb_la-TNonblockingServer.lo `test -f 'src/thrift/server/TNonblockingServer.cpp' || echo '$(srcdir)/'`src/thrift/server/TNonblockingServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/server/$(DEPDIR)/libthriftnb_la-TNonblockingServer.Tpo src/thrift/server/$(DEPDIR)/libthriftnb_la-TNonblockingServer.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/server/TNonblockingServer.cpp' object='src/thrift/server/libthriftnb_la-TNonblockingServer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftnb_la_CPPFLAGS) $(CPPFLAGS) $(libthriftnb_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/server/libthriftnb_la-TNonblockingServer.lo `test -f 'src/thrift/server/TNonblockingServer.cpp' || echo '$(srcdir)/'`src/thrift/server/TNonblockingServer.cpp src/thrift/async/libthriftnb_la-TEvhttpServer.lo: src/thrift/async/TEvhttpServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftnb_la_CPPFLAGS) $(CPPFLAGS) $(libthriftnb_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/async/libthriftnb_la-TEvhttpServer.lo -MD -MP -MF src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpServer.Tpo -c -o src/thrift/async/libthriftnb_la-TEvhttpServer.lo `test -f 'src/thrift/async/TEvhttpServer.cpp' || echo '$(srcdir)/'`src/thrift/async/TEvhttpServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpServer.Tpo src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpServer.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/async/TEvhttpServer.cpp' object='src/thrift/async/libthriftnb_la-TEvhttpServer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftnb_la_CPPFLAGS) $(CPPFLAGS) $(libthriftnb_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/async/libthriftnb_la-TEvhttpServer.lo `test -f 'src/thrift/async/TEvhttpServer.cpp' || echo '$(srcdir)/'`src/thrift/async/TEvhttpServer.cpp src/thrift/async/libthriftnb_la-TEvhttpClientChannel.lo: src/thrift/async/TEvhttpClientChannel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftnb_la_CPPFLAGS) $(CPPFLAGS) $(libthriftnb_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/async/libthriftnb_la-TEvhttpClientChannel.lo -MD -MP -MF src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpClientChannel.Tpo -c -o src/thrift/async/libthriftnb_la-TEvhttpClientChannel.lo `test -f 'src/thrift/async/TEvhttpClientChannel.cpp' || echo '$(srcdir)/'`src/thrift/async/TEvhttpClientChannel.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpClientChannel.Tpo src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpClientChannel.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/async/TEvhttpClientChannel.cpp' object='src/thrift/async/libthriftnb_la-TEvhttpClientChannel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftnb_la_CPPFLAGS) $(CPPFLAGS) $(libthriftnb_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/async/libthriftnb_la-TEvhttpClientChannel.lo `test -f 'src/thrift/async/TEvhttpClientChannel.cpp' || echo '$(srcdir)/'`src/thrift/async/TEvhttpClientChannel.cpp src/thrift/qt/libthriftqt5_la-TQIODeviceTransport.lo: src/thrift/qt/TQIODeviceTransport.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftqt5_la_CPPFLAGS) $(CPPFLAGS) $(libthriftqt5_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/qt/libthriftqt5_la-TQIODeviceTransport.lo -MD -MP -MF src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQIODeviceTransport.Tpo -c -o src/thrift/qt/libthriftqt5_la-TQIODeviceTransport.lo `test -f 'src/thrift/qt/TQIODeviceTransport.cpp' || echo '$(srcdir)/'`src/thrift/qt/TQIODeviceTransport.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQIODeviceTransport.Tpo src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQIODeviceTransport.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/qt/TQIODeviceTransport.cpp' object='src/thrift/qt/libthriftqt5_la-TQIODeviceTransport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftqt5_la_CPPFLAGS) $(CPPFLAGS) $(libthriftqt5_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/qt/libthriftqt5_la-TQIODeviceTransport.lo `test -f 'src/thrift/qt/TQIODeviceTransport.cpp' || echo '$(srcdir)/'`src/thrift/qt/TQIODeviceTransport.cpp src/thrift/qt/libthriftqt5_la-TQTcpServer.lo: src/thrift/qt/TQTcpServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftqt5_la_CPPFLAGS) $(CPPFLAGS) $(libthriftqt5_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/qt/libthriftqt5_la-TQTcpServer.lo -MD -MP -MF src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQTcpServer.Tpo -c -o src/thrift/qt/libthriftqt5_la-TQTcpServer.lo `test -f 'src/thrift/qt/TQTcpServer.cpp' || echo '$(srcdir)/'`src/thrift/qt/TQTcpServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQTcpServer.Tpo src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQTcpServer.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/qt/TQTcpServer.cpp' object='src/thrift/qt/libthriftqt5_la-TQTcpServer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftqt5_la_CPPFLAGS) $(CPPFLAGS) $(libthriftqt5_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/qt/libthriftqt5_la-TQTcpServer.lo `test -f 'src/thrift/qt/TQTcpServer.cpp' || echo '$(srcdir)/'`src/thrift/qt/TQTcpServer.cpp src/thrift/qt/libthriftqt5_la-moc__TQTcpServer.lo: src/thrift/qt/moc__TQTcpServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftqt5_la_CPPFLAGS) $(CPPFLAGS) $(libthriftqt5_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/qt/libthriftqt5_la-moc__TQTcpServer.lo -MD -MP -MF src/thrift/qt/$(DEPDIR)/libthriftqt5_la-moc__TQTcpServer.Tpo -c -o src/thrift/qt/libthriftqt5_la-moc__TQTcpServer.lo `test -f 'src/thrift/qt/moc__TQTcpServer.cpp' || echo '$(srcdir)/'`src/thrift/qt/moc__TQTcpServer.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/qt/$(DEPDIR)/libthriftqt5_la-moc__TQTcpServer.Tpo src/thrift/qt/$(DEPDIR)/libthriftqt5_la-moc__TQTcpServer.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/qt/moc__TQTcpServer.cpp' object='src/thrift/qt/libthriftqt5_la-moc__TQTcpServer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftqt5_la_CPPFLAGS) $(CPPFLAGS) $(libthriftqt5_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/qt/libthriftqt5_la-moc__TQTcpServer.lo `test -f 'src/thrift/qt/moc__TQTcpServer.cpp' || echo '$(srcdir)/'`src/thrift/qt/moc__TQTcpServer.cpp src/thrift/transport/libthriftz_la-TZlibTransport.lo: src/thrift/transport/TZlibTransport.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftz_la_CPPFLAGS) $(CPPFLAGS) $(libthriftz_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/transport/libthriftz_la-TZlibTransport.lo -MD -MP -MF src/thrift/transport/$(DEPDIR)/libthriftz_la-TZlibTransport.Tpo -c -o src/thrift/transport/libthriftz_la-TZlibTransport.lo `test -f 'src/thrift/transport/TZlibTransport.cpp' || echo '$(srcdir)/'`src/thrift/transport/TZlibTransport.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/transport/$(DEPDIR)/libthriftz_la-TZlibTransport.Tpo src/thrift/transport/$(DEPDIR)/libthriftz_la-TZlibTransport.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/transport/TZlibTransport.cpp' object='src/thrift/transport/libthriftz_la-TZlibTransport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftz_la_CPPFLAGS) $(CPPFLAGS) $(libthriftz_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/transport/libthriftz_la-TZlibTransport.lo `test -f 'src/thrift/transport/TZlibTransport.cpp' || echo '$(srcdir)/'`src/thrift/transport/TZlibTransport.cpp src/thrift/transport/libthriftz_la-THeaderTransport.lo: src/thrift/transport/THeaderTransport.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftz_la_CPPFLAGS) $(CPPFLAGS) $(libthriftz_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/transport/libthriftz_la-THeaderTransport.lo -MD -MP -MF src/thrift/transport/$(DEPDIR)/libthriftz_la-THeaderTransport.Tpo -c -o src/thrift/transport/libthriftz_la-THeaderTransport.lo `test -f 'src/thrift/transport/THeaderTransport.cpp' || echo '$(srcdir)/'`src/thrift/transport/THeaderTransport.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/transport/$(DEPDIR)/libthriftz_la-THeaderTransport.Tpo src/thrift/transport/$(DEPDIR)/libthriftz_la-THeaderTransport.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/transport/THeaderTransport.cpp' object='src/thrift/transport/libthriftz_la-THeaderTransport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftz_la_CPPFLAGS) $(CPPFLAGS) $(libthriftz_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/transport/libthriftz_la-THeaderTransport.lo `test -f 'src/thrift/transport/THeaderTransport.cpp' || echo '$(srcdir)/'`src/thrift/transport/THeaderTransport.cpp src/thrift/protocol/libthriftz_la-THeaderProtocol.lo: src/thrift/protocol/THeaderProtocol.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftz_la_CPPFLAGS) $(CPPFLAGS) $(libthriftz_la_CXXFLAGS) $(CXXFLAGS) -MT src/thrift/protocol/libthriftz_la-THeaderProtocol.lo -MD -MP -MF src/thrift/protocol/$(DEPDIR)/libthriftz_la-THeaderProtocol.Tpo -c -o src/thrift/protocol/libthriftz_la-THeaderProtocol.lo `test -f 'src/thrift/protocol/THeaderProtocol.cpp' || echo '$(srcdir)/'`src/thrift/protocol/THeaderProtocol.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/thrift/protocol/$(DEPDIR)/libthriftz_la-THeaderProtocol.Tpo src/thrift/protocol/$(DEPDIR)/libthriftz_la-THeaderProtocol.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/thrift/protocol/THeaderProtocol.cpp' object='src/thrift/protocol/libthriftz_la-THeaderProtocol.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libthriftz_la_CPPFLAGS) $(CPPFLAGS) $(libthriftz_la_CXXFLAGS) $(CXXFLAGS) -c -o src/thrift/protocol/libthriftz_la-THeaderProtocol.lo `test -f 'src/thrift/protocol/THeaderProtocol.cpp' || echo '$(srcdir)/'`src/thrift/protocol/THeaderProtocol.cpp mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf src/thrift/.libs src/thrift/_libs -rm -rf src/thrift/async/.libs src/thrift/async/_libs -rm -rf src/thrift/concurrency/.libs src/thrift/concurrency/_libs -rm -rf src/thrift/processor/.libs src/thrift/processor/_libs -rm -rf src/thrift/protocol/.libs src/thrift/protocol/_libs -rm -rf src/thrift/qt/.libs src/thrift/qt/_libs -rm -rf src/thrift/server/.libs src/thrift/server/_libs -rm -rf src/thrift/transport/.libs src/thrift/transport/_libs install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-include_asyncHEADERS: $(include_async_HEADERS) @$(NORMAL_INSTALL) @list='$(include_async_HEADERS)'; test -n "$(include_asyncdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_asyncdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_asyncdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_asyncdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_asyncdir)" || exit $$?; \ done uninstall-include_asyncHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_async_HEADERS)'; test -n "$(include_asyncdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_asyncdir)'; $(am__uninstall_files_from_dir) install-include_concurrencyHEADERS: $(include_concurrency_HEADERS) @$(NORMAL_INSTALL) @list='$(include_concurrency_HEADERS)'; test -n "$(include_concurrencydir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_concurrencydir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_concurrencydir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_concurrencydir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_concurrencydir)" || exit $$?; \ done uninstall-include_concurrencyHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_concurrency_HEADERS)'; test -n "$(include_concurrencydir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_concurrencydir)'; $(am__uninstall_files_from_dir) install-include_processorHEADERS: $(include_processor_HEADERS) @$(NORMAL_INSTALL) @list='$(include_processor_HEADERS)'; test -n "$(include_processordir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_processordir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_processordir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_processordir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_processordir)" || exit $$?; \ done uninstall-include_processorHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_processor_HEADERS)'; test -n "$(include_processordir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_processordir)'; $(am__uninstall_files_from_dir) install-include_protocolHEADERS: $(include_protocol_HEADERS) @$(NORMAL_INSTALL) @list='$(include_protocol_HEADERS)'; test -n "$(include_protocoldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_protocoldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_protocoldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_protocoldir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_protocoldir)" || exit $$?; \ done uninstall-include_protocolHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_protocol_HEADERS)'; test -n "$(include_protocoldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_protocoldir)'; $(am__uninstall_files_from_dir) install-include_qtHEADERS: $(include_qt_HEADERS) @$(NORMAL_INSTALL) @list='$(include_qt_HEADERS)'; test -n "$(include_qtdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_qtdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_qtdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_qtdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_qtdir)" || exit $$?; \ done uninstall-include_qtHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_qt_HEADERS)'; test -n "$(include_qtdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_qtdir)'; $(am__uninstall_files_from_dir) install-include_serverHEADERS: $(include_server_HEADERS) @$(NORMAL_INSTALL) @list='$(include_server_HEADERS)'; test -n "$(include_serverdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_serverdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_serverdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_serverdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_serverdir)" || exit $$?; \ done uninstall-include_serverHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_server_HEADERS)'; test -n "$(include_serverdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_serverdir)'; $(am__uninstall_files_from_dir) install-include_thriftHEADERS: $(include_thrift_HEADERS) @$(NORMAL_INSTALL) @list='$(include_thrift_HEADERS)'; test -n "$(include_thriftdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_thriftdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_thriftdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_thriftdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_thriftdir)" || exit $$?; \ done uninstall-include_thriftHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_thrift_HEADERS)'; test -n "$(include_thriftdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_thriftdir)'; $(am__uninstall_files_from_dir) install-include_transportHEADERS: $(include_transport_HEADERS) @$(NORMAL_INSTALL) @list='$(include_transport_HEADERS)'; test -n "$(include_transportdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(include_transportdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(include_transportdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(include_transportdir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(include_transportdir)" || exit $$?; \ done uninstall-include_transportHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_transport_HEADERS)'; test -n "$(include_transportdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(include_transportdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(include_asyncdir)" "$(DESTDIR)$(include_concurrencydir)" "$(DESTDIR)$(include_processordir)" "$(DESTDIR)$(include_protocoldir)" "$(DESTDIR)$(include_qtdir)" "$(DESTDIR)$(include_serverdir)" "$(DESTDIR)$(include_thriftdir)" "$(DESTDIR)$(include_transportdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f src/thrift/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/$(am__dirstamp) -rm -f src/thrift/async/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/async/$(am__dirstamp) -rm -f src/thrift/concurrency/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/concurrency/$(am__dirstamp) -rm -f src/thrift/processor/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/processor/$(am__dirstamp) -rm -f src/thrift/protocol/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/protocol/$(am__dirstamp) -rm -f src/thrift/qt/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/qt/$(am__dirstamp) -rm -f src/thrift/server/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/server/$(am__dirstamp) -rm -f src/thrift/transport/$(DEPDIR)/$(am__dirstamp) -rm -f src/thrift/transport/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -f src/thrift/$(DEPDIR)/TApplicationException.Plo -rm -f src/thrift/$(DEPDIR)/TOutput.Plo -rm -f src/thrift/$(DEPDIR)/TUuid.Plo -rm -f src/thrift/$(DEPDIR)/VirtualProfiling.Plo -rm -f src/thrift/async/$(DEPDIR)/TAsyncChannel.Plo -rm -f src/thrift/async/$(DEPDIR)/TAsyncProtocolProcessor.Plo -rm -f src/thrift/async/$(DEPDIR)/TConcurrentClientSyncInfo.Plo -rm -f src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpClientChannel.Plo -rm -f src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpServer.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/Monitor.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/Mutex.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/Thread.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/ThreadFactory.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/ThreadManager.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/TimerManager.Plo -rm -f src/thrift/processor/$(DEPDIR)/PeekProcessor.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TBase64Utils.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TDebugProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TJSONProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TMultiplexedProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/libthriftz_la-THeaderProtocol.Plo -rm -f src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQIODeviceTransport.Plo -rm -f src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQTcpServer.Plo -rm -f src/thrift/qt/$(DEPDIR)/libthriftqt5_la-moc__TQTcpServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TConnectedClient.Plo -rm -f src/thrift/server/$(DEPDIR)/TServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TServerFramework.Plo -rm -f src/thrift/server/$(DEPDIR)/TSimpleServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TThreadPoolServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TThreadedServer.Plo -rm -f src/thrift/server/$(DEPDIR)/libthriftnb_la-TNonblockingServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/SocketCommon.Plo -rm -f src/thrift/transport/$(DEPDIR)/TBufferTransports.Plo -rm -f src/thrift/transport/$(DEPDIR)/TFDTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/TFileTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/THttpClient.Plo -rm -f src/thrift/transport/$(DEPDIR)/THttpServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/THttpTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/TNonblockingSSLServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TNonblockingServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TPipe.Plo -rm -f src/thrift/transport/$(DEPDIR)/TPipeServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSSLServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSSLSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSimpleFileTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSocketPool.Plo -rm -f src/thrift/transport/$(DEPDIR)/TTransportException.Plo -rm -f src/thrift/transport/$(DEPDIR)/TTransportUtils.Plo -rm -f src/thrift/transport/$(DEPDIR)/TWebSocketServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/libthriftz_la-THeaderTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/libthriftz_la-TZlibTransport.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-include_asyncHEADERS \ install-include_concurrencyHEADERS \ install-include_processorHEADERS \ install-include_protocolHEADERS install-include_qtHEADERS \ install-include_serverHEADERS install-include_thriftHEADERS \ install-include_transportHEADERS install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f src/thrift/$(DEPDIR)/TApplicationException.Plo -rm -f src/thrift/$(DEPDIR)/TOutput.Plo -rm -f src/thrift/$(DEPDIR)/TUuid.Plo -rm -f src/thrift/$(DEPDIR)/VirtualProfiling.Plo -rm -f src/thrift/async/$(DEPDIR)/TAsyncChannel.Plo -rm -f src/thrift/async/$(DEPDIR)/TAsyncProtocolProcessor.Plo -rm -f src/thrift/async/$(DEPDIR)/TConcurrentClientSyncInfo.Plo -rm -f src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpClientChannel.Plo -rm -f src/thrift/async/$(DEPDIR)/libthriftnb_la-TEvhttpServer.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/Monitor.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/Mutex.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/Thread.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/ThreadFactory.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/ThreadManager.Plo -rm -f src/thrift/concurrency/$(DEPDIR)/TimerManager.Plo -rm -f src/thrift/processor/$(DEPDIR)/PeekProcessor.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TBase64Utils.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TDebugProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TJSONProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TMultiplexedProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/TProtocol.Plo -rm -f src/thrift/protocol/$(DEPDIR)/libthriftz_la-THeaderProtocol.Plo -rm -f src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQIODeviceTransport.Plo -rm -f src/thrift/qt/$(DEPDIR)/libthriftqt5_la-TQTcpServer.Plo -rm -f src/thrift/qt/$(DEPDIR)/libthriftqt5_la-moc__TQTcpServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TConnectedClient.Plo -rm -f src/thrift/server/$(DEPDIR)/TServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TServerFramework.Plo -rm -f src/thrift/server/$(DEPDIR)/TSimpleServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TThreadPoolServer.Plo -rm -f src/thrift/server/$(DEPDIR)/TThreadedServer.Plo -rm -f src/thrift/server/$(DEPDIR)/libthriftnb_la-TNonblockingServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/SocketCommon.Plo -rm -f src/thrift/transport/$(DEPDIR)/TBufferTransports.Plo -rm -f src/thrift/transport/$(DEPDIR)/TFDTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/TFileTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/THttpClient.Plo -rm -f src/thrift/transport/$(DEPDIR)/THttpServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/THttpTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/TNonblockingSSLServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TNonblockingServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TPipe.Plo -rm -f src/thrift/transport/$(DEPDIR)/TPipeServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSSLServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSSLSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TServerSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSimpleFileTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSocket.Plo -rm -f src/thrift/transport/$(DEPDIR)/TSocketPool.Plo -rm -f src/thrift/transport/$(DEPDIR)/TTransportException.Plo -rm -f src/thrift/transport/$(DEPDIR)/TTransportUtils.Plo -rm -f src/thrift/transport/$(DEPDIR)/TWebSocketServer.Plo -rm -f src/thrift/transport/$(DEPDIR)/libthriftz_la-THeaderTransport.Plo -rm -f src/thrift/transport/$(DEPDIR)/libthriftz_la-TZlibTransport.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: uninstall-include_asyncHEADERS \ uninstall-include_concurrencyHEADERS \ uninstall-include_processorHEADERS \ uninstall-include_protocolHEADERS uninstall-include_qtHEADERS \ uninstall-include_serverHEADERS \ uninstall-include_thriftHEADERS \ uninstall-include_transportHEADERS uninstall-libLTLIBRARIES \ uninstall-pkgconfigDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am \ install-include_asyncHEADERS \ install-include_concurrencyHEADERS \ install-include_processorHEADERS \ install-include_protocolHEADERS install-include_qtHEADERS \ install-include_serverHEADERS install-include_thriftHEADERS \ install-include_transportHEADERS install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-pkgconfigDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am style-am style-local tags tags-am \ uninstall uninstall-am uninstall-include_asyncHEADERS \ uninstall-include_concurrencyHEADERS \ uninstall-include_processorHEADERS \ uninstall-include_protocolHEADERS uninstall-include_qtHEADERS \ uninstall-include_serverHEADERS \ uninstall-include_thriftHEADERS \ uninstall-include_transportHEADERS uninstall-libLTLIBRARIES \ uninstall-pkgconfigDATA .PRECIOUS: Makefile moc__%.cpp: %.h $(QT5_MOC) $(QT5_CFLAGS) $< -o $@ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am style-local: $(CPPSTYLE_CMD) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/cpp/thrift.pc.in0000664000175000017500000000172415165535636017162 0ustar00buildbuild00000000000000# # 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. # prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Thrift Description: Thrift C++ API Version: @VERSION@ Libs: -L${libdir} -lthrift Cflags: -I${includedir} thrift-0.23.0/lib/cpp/Makefile.am0000664000175000017500000003064515167543515016766 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = subdir-objects nostdinc moc__%.cpp: %.h $(QT5_MOC) $(QT5_CFLAGS) $< -o $@ SUBDIRS = . if WITH_TESTS SUBDIRS += test endif pkgconfigdir = $(libdir)/pkgconfig lib_LTLIBRARIES = libthrift.la pkgconfig_DATA = thrift.pc libthrift_la_LDFLAGS = -release $(VERSION) libthrift_la_LIBADD = $(BOOST_LDFLAGS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) ## We only build the extra libraries if we have the dependencies, ## but we install all of the headers unconditionally. if AMX_HAVE_LIBEVENT lib_LTLIBRARIES += libthriftnb.la pkgconfig_DATA += thrift-nb.pc endif if AMX_HAVE_ZLIB lib_LTLIBRARIES += libthriftz.la pkgconfig_DATA += thrift-z.pc endif if AMX_HAVE_QT5 lib_LTLIBRARIES += libthriftqt5.la pkgconfig_DATA += thrift-qt5.pc endif AM_CXXFLAGS = -Wall -Wextra -pedantic AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS # Define the source files for the module 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 \ src/thrift/async/TConcurrentClientSyncInfo.cpp \ src/thrift/concurrency/ThreadManager.cpp \ src/thrift/concurrency/TimerManager.cpp \ src/thrift/processor/PeekProcessor.cpp \ src/thrift/protocol/TDebugProtocol.cpp \ src/thrift/protocol/TJSONProtocol.cpp \ src/thrift/protocol/TBase64Utils.cpp \ src/thrift/protocol/TMultiplexedProtocol.cpp \ src/thrift/protocol/TProtocol.cpp \ src/thrift/transport/TTransportException.cpp \ src/thrift/transport/TFDTransport.cpp \ src/thrift/transport/TFileTransport.cpp \ src/thrift/transport/TSimpleFileTransport.cpp \ src/thrift/transport/THttpTransport.cpp \ src/thrift/transport/THttpClient.cpp \ src/thrift/transport/THttpServer.cpp \ src/thrift/transport/TSocket.cpp \ src/thrift/transport/TPipe.cpp \ src/thrift/transport/TPipeServer.cpp \ src/thrift/transport/TSSLSocket.cpp \ src/thrift/transport/TSocketPool.cpp \ src/thrift/transport/TServerSocket.cpp \ src/thrift/transport/TSSLServerSocket.cpp \ src/thrift/transport/TNonblockingServerSocket.cpp \ src/thrift/transport/TNonblockingSSLServerSocket.cpp \ src/thrift/transport/TTransportUtils.cpp \ src/thrift/transport/TBufferTransports.cpp \ src/thrift/transport/TWebSocketServer.cpp \ src/thrift/transport/SocketCommon.cpp \ src/thrift/server/TConnectedClient.cpp \ src/thrift/server/TServer.cpp \ src/thrift/server/TServerFramework.cpp \ src/thrift/server/TSimpleServer.cpp \ src/thrift/server/TThreadPoolServer.cpp \ src/thrift/server/TThreadedServer.cpp libthrift_la_SOURCES += src/thrift/concurrency/Mutex.cpp \ src/thrift/concurrency/ThreadFactory.cpp \ src/thrift/concurrency/Thread.cpp \ src/thrift/concurrency/Monitor.cpp libthriftnb_la_SOURCES = src/thrift/server/TNonblockingServer.cpp \ src/thrift/async/TEvhttpServer.cpp \ src/thrift/async/TEvhttpClientChannel.cpp libthriftz_la_SOURCES = src/thrift/transport/TZlibTransport.cpp \ src/thrift/transport/THeaderTransport.cpp \ src/thrift/protocol/THeaderProtocol.cpp libthriftqt5_la_MOC = src/thrift/qt/moc__TQTcpServer.cpp nodist_libthriftqt5_la_SOURCES = $(libthriftqt5_la_MOC) libthriftqt5_la_SOURCES = src/thrift/qt/TQIODeviceTransport.cpp \ src/thrift/qt/TQTcpServer.cpp CLEANFILES = $(libthriftqt5_la_MOC) # Flags for the various libraries libthriftnb_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBEVENT_CPPFLAGS) libthriftz_la_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CPPFLAGS) libthriftqt5_la_CPPFLAGS = $(AM_CPPFLAGS) $(QT5_CFLAGS) if QT5_REDUCE_RELOCATIONS libthriftqt5_la_CPPFLAGS += -fPIC endif libthriftnb_la_CXXFLAGS = $(AM_CXXFLAGS) libthriftz_la_CXXFLAGS = $(AM_CXXFLAGS) libthriftqt5_la_CXXFLAGS = $(AM_CXXFLAGS) libthriftnb_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) libthriftz_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(ZLIB_LDFLAGS) $(ZLIB_LIBS) libthriftqt5_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT5_LIBS) include_thriftdir = $(includedir)/thrift include_thrift_HEADERS = \ $(top_builddir)/config.h \ src/thrift/thrift-config.h \ src/thrift/thrift_export.h \ src/thrift/TDispatchProcessor.h \ src/thrift/TUuid.h \ src/thrift/Thrift.h \ src/thrift/TOutput.h \ src/thrift/TProcessor.h \ src/thrift/TApplicationException.h \ src/thrift/TLogging.h \ src/thrift/TPrintTo.h \ src/thrift/TToString.h \ src/thrift/TBase.h \ src/thrift/TConfiguration.h \ src/thrift/TNonCopyable.h include_concurrencydir = $(include_thriftdir)/concurrency include_concurrency_HEADERS = \ src/thrift/concurrency/Exception.h \ src/thrift/concurrency/Mutex.h \ src/thrift/concurrency/Monitor.h \ src/thrift/concurrency/ThreadFactory.h \ src/thrift/concurrency/Thread.h \ src/thrift/concurrency/ThreadManager.h \ src/thrift/concurrency/TimerManager.h \ src/thrift/concurrency/FunctionRunner.h include_protocoldir = $(include_thriftdir)/protocol include_protocol_HEADERS = \ src/thrift/protocol/TEnum.h \ src/thrift/protocol/TList.h \ src/thrift/protocol/TSet.h \ src/thrift/protocol/TMap.h \ src/thrift/protocol/TBinaryProtocol.h \ src/thrift/protocol/TBinaryProtocol.tcc \ src/thrift/protocol/TCompactProtocol.h \ src/thrift/protocol/TCompactProtocol.tcc \ src/thrift/protocol/TDebugProtocol.h \ src/thrift/protocol/THeaderProtocol.h \ src/thrift/protocol/TBase64Utils.h \ src/thrift/protocol/TJSONProtocol.h \ src/thrift/protocol/TMultiplexedProtocol.h \ src/thrift/protocol/TProtocolDecorator.h \ src/thrift/protocol/TProtocolTap.h \ src/thrift/protocol/TProtocolTypes.h \ src/thrift/protocol/TProtocolException.h \ src/thrift/protocol/TVirtualProtocol.h \ src/thrift/protocol/TProtocol.h include_transportdir = $(include_thriftdir)/transport include_transport_HEADERS = \ src/thrift/transport/PlatformSocket.h \ src/thrift/transport/TFDTransport.h \ src/thrift/transport/TFileTransport.h \ src/thrift/transport/THeaderTransport.h \ src/thrift/transport/TSimpleFileTransport.h \ src/thrift/transport/TServerSocket.h \ src/thrift/transport/TSSLServerSocket.h \ src/thrift/transport/TServerTransport.h \ src/thrift/transport/TNonblockingServerTransport.h \ src/thrift/transport/TNonblockingServerSocket.h \ src/thrift/transport/TNonblockingSSLServerSocket.h \ src/thrift/transport/THttpTransport.h \ src/thrift/transport/THttpClient.h \ src/thrift/transport/THttpServer.h \ src/thrift/transport/TSocket.h \ src/thrift/transport/TSocketUtils.h \ src/thrift/transport/TPipe.h \ src/thrift/transport/TPipeServer.h \ src/thrift/transport/TSSLSocket.h \ src/thrift/transport/TSocketPool.h \ src/thrift/transport/TVirtualTransport.h \ src/thrift/transport/TTransport.h \ src/thrift/transport/TTransportException.h \ src/thrift/transport/TTransportUtils.h \ src/thrift/transport/TBufferTransports.h \ src/thrift/transport/TShortReadTransport.h \ src/thrift/transport/TZlibTransport.h \ src/thrift/transport/TWebSocketServer.h \ src/thrift/transport/SocketCommon.h include_serverdir = $(include_thriftdir)/server include_server_HEADERS = \ src/thrift/server/TConnectedClient.h \ src/thrift/server/TServer.h \ src/thrift/server/TServerFramework.h \ src/thrift/server/TSimpleServer.h \ src/thrift/server/TThreadPoolServer.h \ src/thrift/server/TThreadedServer.h \ src/thrift/server/TNonblockingServer.h include_processordir = $(include_thriftdir)/processor include_processor_HEADERS = \ src/thrift/processor/PeekProcessor.h \ src/thrift/processor/StatsProcessor.h \ src/thrift/processor/TMultiplexedProcessor.h include_asyncdir = $(include_thriftdir)/async include_async_HEADERS = \ src/thrift/async/TAsyncChannel.h \ src/thrift/async/TAsyncDispatchProcessor.h \ src/thrift/async/TAsyncProcessor.h \ src/thrift/async/TAsyncBufferProcessor.h \ src/thrift/async/TAsyncProtocolProcessor.h \ src/thrift/async/TConcurrentClientSyncInfo.h \ src/thrift/async/TEvhttpClientChannel.h \ src/thrift/async/TEvhttpServer.h include_qtdir = $(include_thriftdir)/qt include_qt_HEADERS = \ src/thrift/qt/TQIODeviceTransport.h \ src/thrift/qt/TQTcpServer.h WINDOWS_DIST = \ src/thrift/windows \ thrift.sln \ libthrift.vcxproj \ libthrift.vcxproj.filters \ libthriftnb.vcxproj \ libthriftnb.vcxproj.filters \ 3rdparty.props distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ CMakeLists.txt \ coding_standards.md \ README.md \ thrift-nb.pc.in \ thrift.pc.in \ thrift-z.pc.in \ thrift-qt5.pc.in \ src/thrift/qt/CMakeLists.txt \ $(WINDOWS_DIST) style-local: $(CPPSTYLE_CMD) thrift-0.23.0/lib/rb/0000755000175000017500000000000015170007201014516 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/Gemfile.linters0000664000175000017500000000020115167543515017506 0ustar00buildbuild00000000000000source "https://rubygems.org" gem 'rubocop', '~> 1.82.0' gem 'rubocop-performance', '~> 1.26.1' gem 'rubocop-rspec', '~> 3.8.0' thrift-0.23.0/lib/rb/.rubocop.yml0000664000175000017500000000124015167543515017012 0ustar00buildbuild00000000000000plugins: - rubocop-performance - rubocop-rspec AllCops: DisabledByDefault: true SuggestExtensions: false TargetRubyVersion: 2.7 Exclude: - "**/vendor/**/*" Layout/EmptyLines: Enabled: true Layout/EmptyLinesAroundBlockBody: Enabled: true Layout/ExtraSpacing: Enabled: true Layout/IndentationConsistency: Enabled: true Layout/LeadingCommentSpace: Enabled: true Layout/LeadingEmptyLines: Enabled: true Layout/SpaceAfterComma: Enabled: true Layout/SpaceAroundEqualsInParameterDefault: Enabled: true Layout/SpaceInsideBlockBraces: Enabled: true Layout/TrailingEmptyLines: Enabled: true Layout/TrailingWhitespace: Enabled: true thrift-0.23.0/lib/rb/ext/0000775000175000017500000000000015167543515015343 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/ext/binary_protocol_accelerated.c0000664000175000017500000004240615167543515023236 0ustar00buildbuild00000000000000/** * 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 #include #include #include #include VALUE rb_thrift_binary_proto_native_qmark(VALUE self) { return Qtrue; } static int VERSION_1; static int VERSION_MASK; static int TYPE_MASK; static ID rbuf_ivar_id; static void write_byte_direct(VALUE trans, int8_t b) { WRITE(trans, (char*)&b, 1); } static void write_i16_direct(VALUE trans, int16_t value) { char data[2]; data[1] = value; data[0] = (value >> 8); WRITE(trans, data, 2); } static void write_i32_direct(VALUE trans, int32_t value) { char data[4]; data[3] = value; data[2] = (value >> 8); data[1] = (value >> 16); data[0] = (value >> 24); WRITE(trans, data, 4); } static void write_i64_direct(VALUE trans, int64_t value) { char data[8]; data[7] = value; data[6] = (value >> 8); data[5] = (value >> 16); data[4] = (value >> 24); data[3] = (value >> 32); data[2] = (value >> 40); data[1] = (value >> 48); data[0] = (value >> 56); WRITE(trans, data, 8); } static void write_string_direct(VALUE trans, VALUE str) { if (TYPE(str) != T_STRING) { rb_raise(rb_eStandardError, "Value should be a string"); } str = convert_to_utf8_byte_buffer(str); write_i32_direct(trans, (int32_t)RSTRING_LEN(str)); rb_funcall(trans, write_method_id, 1, str); } //-------------------------------- // interface writing methods //-------------------------------- VALUE rb_thrift_binary_proto_write_message_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_write_struct_begin(VALUE self, VALUE name) { return Qnil; } VALUE rb_thrift_binary_proto_write_struct_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_write_field_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_write_map_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_write_list_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_write_set_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_write_message_begin(VALUE self, VALUE name, VALUE type, VALUE seqid) { VALUE trans = GET_TRANSPORT(self); VALUE strict_write = GET_STRICT_WRITE(self); if (strict_write == Qtrue) { write_i32_direct(trans, VERSION_1 | FIX2INT(type)); write_string_direct(trans, name); write_i32_direct(trans, FIX2INT(seqid)); } else { write_string_direct(trans, name); write_byte_direct(trans, FIX2INT(type)); write_i32_direct(trans, FIX2INT(seqid)); } return Qnil; } VALUE rb_thrift_binary_proto_write_field_begin(VALUE self, VALUE name, VALUE type, VALUE id) { VALUE trans = GET_TRANSPORT(self); write_byte_direct(trans, FIX2INT(type)); write_i16_direct(trans, FIX2INT(id)); return Qnil; } VALUE rb_thrift_binary_proto_write_field_stop(VALUE self) { write_byte_direct(GET_TRANSPORT(self), TTYPE_STOP); return Qnil; } VALUE rb_thrift_binary_proto_write_map_begin(VALUE self, VALUE ktype, VALUE vtype, VALUE size) { VALUE trans = GET_TRANSPORT(self); write_byte_direct(trans, FIX2INT(ktype)); write_byte_direct(trans, FIX2INT(vtype)); write_i32_direct(trans, FIX2INT(size)); return Qnil; } VALUE rb_thrift_binary_proto_write_list_begin(VALUE self, VALUE etype, VALUE size) { VALUE trans = GET_TRANSPORT(self); write_byte_direct(trans, FIX2INT(etype)); write_i32_direct(trans, FIX2INT(size)); return Qnil; } VALUE rb_thrift_binary_proto_write_set_begin(VALUE self, VALUE etype, VALUE size) { rb_thrift_binary_proto_write_list_begin(self, etype, size); return Qnil; } VALUE rb_thrift_binary_proto_write_bool(VALUE self, VALUE b) { write_byte_direct(GET_TRANSPORT(self), RTEST(b) ? 1 : 0); return Qnil; } VALUE rb_thrift_binary_proto_write_byte(VALUE self, VALUE byte) { CHECK_NIL(byte); write_byte_direct(GET_TRANSPORT(self), NUM2INT(byte)); return Qnil; } VALUE rb_thrift_binary_proto_write_i16(VALUE self, VALUE i16) { CHECK_NIL(i16); write_i16_direct(GET_TRANSPORT(self), FIX2INT(i16)); return Qnil; } VALUE rb_thrift_binary_proto_write_i32(VALUE self, VALUE i32) { CHECK_NIL(i32); write_i32_direct(GET_TRANSPORT(self), NUM2INT(i32)); return Qnil; } VALUE rb_thrift_binary_proto_write_i64(VALUE self, VALUE i64) { CHECK_NIL(i64); write_i64_direct(GET_TRANSPORT(self), NUM2LL(i64)); return Qnil; } VALUE rb_thrift_binary_proto_write_double(VALUE self, VALUE dub) { CHECK_NIL(dub); // Unfortunately, bitwise_cast doesn't work in C. Bad C! union { double f; int64_t t; } transfer; transfer.f = RFLOAT_VALUE(rb_Float(dub)); write_i64_direct(GET_TRANSPORT(self), transfer.t); return Qnil; } VALUE rb_thrift_binary_proto_write_string(VALUE self, VALUE str) { CHECK_NIL(str); VALUE trans = GET_TRANSPORT(self); write_string_direct(trans, str); return Qnil; } 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, (int32_t)RSTRING_LEN(buf)); rb_funcall(trans, write_method_id, 1, buf); return Qnil; } VALUE rb_thrift_binary_proto_write_uuid(VALUE self, VALUE uuid) { if (NIL_P(uuid) || TYPE(uuid) != T_STRING) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("UUID must be a string"))); } VALUE trans = GET_TRANSPORT(self); char bytes[16]; const char* str = RSTRING_PTR(uuid); long len = RSTRING_LEN(uuid); // Parse UUID string (format: "550e8400-e29b-41d4-a716-446655440000") // Expected length: 36 characters (32 hex + 4 hyphens) if (len != 36 || str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-') { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("Invalid UUID format"))); } // Parse hex string to bytes using direct conversion, skipping hyphens int byte_idx = 0; for (int i = 0; i < len && byte_idx < 16; i++) { if (str[i] == '-') continue; if (i + 1 >= len || str[i + 1] == '-') break; // Convert two hex characters to one byte int high = hex_char_to_int(str[i]); int low = hex_char_to_int(str[i + 1]); if (high < 0 || low < 0) break; bytes[byte_idx++] = (unsigned char)((high << 4) | low); i++; // skip next char since we processed two } if (byte_idx != 16) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("Invalid UUID format"))); } WRITE(trans, bytes, 16); return Qnil; } //--------------------------------------- // interface reading methods //--------------------------------------- VALUE rb_thrift_binary_proto_read_string(VALUE self); VALUE rb_thrift_binary_proto_read_binary(VALUE self); VALUE rb_thrift_binary_proto_read_byte(VALUE self); VALUE rb_thrift_binary_proto_read_i32(VALUE self); VALUE rb_thrift_binary_proto_read_i16(VALUE self); static char read_byte_direct(VALUE self) { VALUE byte = rb_funcall(GET_TRANSPORT(self), read_byte_method_id, 0); return (char)(FIX2INT(byte)); } static int16_t read_i16_direct(VALUE self) { VALUE rbuf = rb_ivar_get(self, rbuf_ivar_id); rb_funcall(GET_TRANSPORT(self), read_into_buffer_method_id, 2, rbuf, INT2FIX(2)); return (int16_t)(((uint8_t)(RSTRING_PTR(rbuf)[1])) | ((uint16_t)((RSTRING_PTR(rbuf)[0]) << 8))); } static int32_t read_i32_direct(VALUE self) { VALUE rbuf = rb_ivar_get(self, rbuf_ivar_id); rb_funcall(GET_TRANSPORT(self), read_into_buffer_method_id, 2, rbuf, INT2FIX(4)); return ((uint8_t)(RSTRING_PTR(rbuf)[3])) | (((uint8_t)(RSTRING_PTR(rbuf)[2])) << 8) | (((uint8_t)(RSTRING_PTR(rbuf)[1])) << 16) | (((uint8_t)(RSTRING_PTR(rbuf)[0])) << 24); } static int64_t read_i64_direct(VALUE self) { VALUE rbuf = rb_ivar_get(self, rbuf_ivar_id); rb_funcall(GET_TRANSPORT(self), read_into_buffer_method_id, 2, rbuf, INT2FIX(8)); uint64_t hi = ((uint8_t)(RSTRING_PTR(rbuf)[3])) | (((uint8_t)(RSTRING_PTR(rbuf)[2])) << 8) | (((uint8_t)(RSTRING_PTR(rbuf)[1])) << 16) | (((uint8_t)(RSTRING_PTR(rbuf)[0])) << 24); uint32_t lo = ((uint8_t)(RSTRING_PTR(rbuf)[7])) | (((uint8_t)(RSTRING_PTR(rbuf)[6])) << 8) | (((uint8_t)(RSTRING_PTR(rbuf)[5])) << 16) | (((uint8_t)(RSTRING_PTR(rbuf)[4])) << 24); return (hi << 32) | lo; } VALUE rb_thrift_binary_proto_read_message_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_read_struct_begin(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_read_struct_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_read_field_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_read_map_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_read_list_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_read_set_end(VALUE self) { return Qnil; } VALUE rb_thrift_binary_proto_read_message_begin(VALUE self) { VALUE strict_read = GET_STRICT_READ(self); VALUE name, seqid; int type; int version = read_i32_direct(self); if (version < 0) { if ((version & VERSION_MASK) != VERSION_1) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_BAD_VERSION), rb_str_new2("Missing version identifier"))); } type = version & TYPE_MASK; name = rb_thrift_binary_proto_read_string(self); seqid = rb_thrift_binary_proto_read_i32(self); } else { if (strict_read == Qtrue) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_BAD_VERSION), rb_str_new2("No version identifier, old protocol client?"))); } name = READ(self, version); type = read_byte_direct(self); seqid = rb_thrift_binary_proto_read_i32(self); } return rb_ary_new3(3, name, INT2FIX(type), seqid); } VALUE rb_thrift_binary_proto_read_field_begin(VALUE self) { int type = read_byte_direct(self); if (type == TTYPE_STOP) { return rb_ary_new3(3, Qnil, INT2FIX(type), INT2FIX(0)); } else { VALUE id = rb_thrift_binary_proto_read_i16(self); return rb_ary_new3(3, Qnil, INT2FIX(type), id); } } VALUE rb_thrift_binary_proto_read_map_begin(VALUE self) { VALUE ktype = rb_thrift_binary_proto_read_byte(self); VALUE vtype = rb_thrift_binary_proto_read_byte(self); VALUE size = rb_thrift_binary_proto_read_i32(self); return rb_ary_new3(3, ktype, vtype, size); } VALUE rb_thrift_binary_proto_read_list_begin(VALUE self) { VALUE etype = rb_thrift_binary_proto_read_byte(self); VALUE size = rb_thrift_binary_proto_read_i32(self); return rb_ary_new3(2, etype, size); } VALUE rb_thrift_binary_proto_read_set_begin(VALUE self) { return rb_thrift_binary_proto_read_list_begin(self); } VALUE rb_thrift_binary_proto_read_bool(VALUE self) { char byte = read_byte_direct(self); return byte != 0 ? Qtrue : Qfalse; } VALUE rb_thrift_binary_proto_read_byte(VALUE self) { return INT2FIX(read_byte_direct(self)); } VALUE rb_thrift_binary_proto_read_i16(VALUE self) { return INT2FIX(read_i16_direct(self)); } VALUE rb_thrift_binary_proto_read_i32(VALUE self) { return INT2NUM(read_i32_direct(self)); } VALUE rb_thrift_binary_proto_read_i64(VALUE self) { return LL2NUM(read_i64_direct(self)); } VALUE rb_thrift_binary_proto_read_double(VALUE self) { union { double f; int64_t t; } transfer; transfer.t = read_i64_direct(self); return rb_float_new(transfer.f); } VALUE rb_thrift_binary_proto_read_string(VALUE self) { VALUE buffer = rb_thrift_binary_proto_read_binary(self); return convert_to_string(buffer); } VALUE rb_thrift_binary_proto_read_binary(VALUE self) { int size = read_i32_direct(self); return READ(self, size); } VALUE rb_thrift_binary_proto_read_uuid(VALUE self) { VALUE data = READ(self, 16); const unsigned char* bytes = (const unsigned char*)RSTRING_PTR(data); // Format as UUID string: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" char uuid_str[37]; char* p = uuid_str; for (int i = 0; i < 16; i++) { *p++ = int_to_hex_char((bytes[i] >> 4) & 0x0F); *p++ = int_to_hex_char(bytes[i] & 0x0F); if (i == 3 || i == 5 || i == 7 || i == 9) { *p++ = '-'; } } *p = '\0'; return rb_str_new(uuid_str, 36); } void Init_binary_protocol_accelerated(void) { VALUE thrift_binary_protocol_class = rb_const_get(thrift_module, rb_intern("BinaryProtocol")); 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); rb_define_method(bpa_class, "native?", rb_thrift_binary_proto_native_qmark, 0); rb_define_method(bpa_class, "write_message_begin", rb_thrift_binary_proto_write_message_begin, 3); rb_define_method(bpa_class, "write_field_begin", rb_thrift_binary_proto_write_field_begin, 3); rb_define_method(bpa_class, "write_field_stop", rb_thrift_binary_proto_write_field_stop, 0); rb_define_method(bpa_class, "write_map_begin", rb_thrift_binary_proto_write_map_begin, 3); rb_define_method(bpa_class, "write_list_begin", rb_thrift_binary_proto_write_list_begin, 2); rb_define_method(bpa_class, "write_set_begin", rb_thrift_binary_proto_write_set_begin, 2); rb_define_method(bpa_class, "write_byte", rb_thrift_binary_proto_write_byte, 1); rb_define_method(bpa_class, "write_bool", rb_thrift_binary_proto_write_bool, 1); rb_define_method(bpa_class, "write_i16", rb_thrift_binary_proto_write_i16, 1); rb_define_method(bpa_class, "write_i32", rb_thrift_binary_proto_write_i32, 1); rb_define_method(bpa_class, "write_i64", rb_thrift_binary_proto_write_i64, 1); rb_define_method(bpa_class, "write_double", rb_thrift_binary_proto_write_double, 1); rb_define_method(bpa_class, "write_string", rb_thrift_binary_proto_write_string, 1); rb_define_method(bpa_class, "write_binary", rb_thrift_binary_proto_write_binary, 1); rb_define_method(bpa_class, "write_uuid", rb_thrift_binary_proto_write_uuid, 1); // unused methods rb_define_method(bpa_class, "write_message_end", rb_thrift_binary_proto_write_message_end, 0); rb_define_method(bpa_class, "write_struct_begin", rb_thrift_binary_proto_write_struct_begin, 1); rb_define_method(bpa_class, "write_struct_end", rb_thrift_binary_proto_write_struct_end, 0); rb_define_method(bpa_class, "write_field_end", rb_thrift_binary_proto_write_field_end, 0); rb_define_method(bpa_class, "write_map_end", rb_thrift_binary_proto_write_map_end, 0); rb_define_method(bpa_class, "write_list_end", rb_thrift_binary_proto_write_list_end, 0); rb_define_method(bpa_class, "write_set_end", rb_thrift_binary_proto_write_set_end, 0); rb_define_method(bpa_class, "read_message_begin", rb_thrift_binary_proto_read_message_begin, 0); rb_define_method(bpa_class, "read_field_begin", rb_thrift_binary_proto_read_field_begin, 0); rb_define_method(bpa_class, "read_map_begin", rb_thrift_binary_proto_read_map_begin, 0); rb_define_method(bpa_class, "read_list_begin", rb_thrift_binary_proto_read_list_begin, 0); rb_define_method(bpa_class, "read_set_begin", rb_thrift_binary_proto_read_set_begin, 0); rb_define_method(bpa_class, "read_byte", rb_thrift_binary_proto_read_byte, 0); rb_define_method(bpa_class, "read_bool", rb_thrift_binary_proto_read_bool, 0); rb_define_method(bpa_class, "read_i16", rb_thrift_binary_proto_read_i16, 0); rb_define_method(bpa_class, "read_i32", rb_thrift_binary_proto_read_i32, 0); rb_define_method(bpa_class, "read_i64", rb_thrift_binary_proto_read_i64, 0); rb_define_method(bpa_class, "read_double", rb_thrift_binary_proto_read_double, 0); rb_define_method(bpa_class, "read_string", rb_thrift_binary_proto_read_string, 0); rb_define_method(bpa_class, "read_binary", rb_thrift_binary_proto_read_binary, 0); rb_define_method(bpa_class, "read_uuid", rb_thrift_binary_proto_read_uuid, 0); // unused methods rb_define_method(bpa_class, "read_message_end", rb_thrift_binary_proto_read_message_end, 0); rb_define_method(bpa_class, "read_struct_begin", rb_thrift_binary_proto_read_struct_begin, 0); rb_define_method(bpa_class, "read_struct_end", rb_thrift_binary_proto_read_struct_end, 0); rb_define_method(bpa_class, "read_field_end", rb_thrift_binary_proto_read_field_end, 0); rb_define_method(bpa_class, "read_map_end", rb_thrift_binary_proto_read_map_end, 0); rb_define_method(bpa_class, "read_list_end", rb_thrift_binary_proto_read_list_end, 0); rb_define_method(bpa_class, "read_set_end", rb_thrift_binary_proto_read_set_end, 0); rbuf_ivar_id = rb_intern("@rbuf"); } thrift-0.23.0/lib/rb/ext/protocol.c0000664000175000017500000000204515167543515017351 0ustar00buildbuild00000000000000/* * 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 VALUE get_protocol_exception(VALUE code, VALUE message) { VALUE args[2]; args[0] = code; args[1] = message; return rb_class_new_instance(2, (VALUE*)&args, protocol_exception_class); } thrift-0.23.0/lib/rb/ext/strlcpy.h0000664000175000017500000000210115165535636017211 0ustar00buildbuild00000000000000/* * 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 #ifndef __has_builtin #define __has_builtin(x) 0 #endif #ifndef HAVE_STRLCPY size_t strlcpy (char *dst, const char *src, size_t dst_sz); #else #if !__has_builtin(strlcpy) extern size_t strlcpy(char *, const char *, size_t); #endif #endif thrift-0.23.0/lib/rb/ext/memory_buffer.h0000664000175000017500000000150015165535636020354 0ustar00buildbuild00000000000000/* * 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. */ void Init_memory_buffer(); thrift-0.23.0/lib/rb/ext/extconf.rb0000664000175000017500000000247115167543515017342 0ustar00buildbuild00000000000000# # 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. # if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ File.open('Makefile', 'w'){ |f| f.puts "all:\n\ninstall:\n" } else require 'mkmf' append_cflags(["-fsigned-char", "-g", "-O2", "-Wall", "-Werror", "-Werror=old-style-definition"]) # Makes all symbols private by default to avoid unintended conflict # with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED # selectively, or entirely remove this flag. append_cflags("-fvisibility=hidden") have_func("strlcpy", "string.h") create_makefile 'thrift_native' end thrift-0.23.0/lib/rb/ext/struct.c0000664000175000017500000005572515167543515017051 0ustar00buildbuild00000000000000/** * 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 "struct.h" #include "constants.h" #include "macros.h" #include "protocol.h" #include "strlcpy.h" VALUE thrift_union_class; ID setfield_id; ID setvalue_id; ID to_s_method_id; ID name_to_id_method_id; static ID sorted_field_ids_method_id; #define IS_CONTAINER(ttype) ((ttype) == TTYPE_MAP || (ttype) == TTYPE_LIST || (ttype) == TTYPE_SET) #define STRUCT_FIELDS(obj) rb_const_get(CLASS_OF(obj), fields_const_id) static VALUE new_container_array(int size) { if (size < 0) { rb_exc_raise( get_protocol_exception( INT2FIX(PROTOERR_NEGATIVE_SIZE), rb_str_new2("Negative container size") ) ); } return rb_ary_new2(size > 1024 ? 1024 : size); } //------------------------------------------- // Writing section //------------------------------------------- // default fn pointers for protocol stuff here VALUE default_write_bool(VALUE protocol, VALUE value) { rb_funcall(protocol, write_boolean_method_id, 1, value); return Qnil; } VALUE default_write_byte(VALUE protocol, VALUE value) { rb_funcall(protocol, write_byte_method_id, 1, value); return Qnil; } VALUE default_write_i16(VALUE protocol, VALUE value) { rb_funcall(protocol, write_i16_method_id, 1, value); return Qnil; } VALUE default_write_i32(VALUE protocol, VALUE value) { rb_funcall(protocol, write_i32_method_id, 1, value); return Qnil; } VALUE default_write_i64(VALUE protocol, VALUE value) { rb_funcall(protocol, write_i64_method_id, 1, value); return Qnil; } VALUE default_write_double(VALUE protocol, VALUE value) { rb_funcall(protocol, write_double_method_id, 1, value); return Qnil; } VALUE default_write_string(VALUE protocol, VALUE value) { rb_funcall(protocol, write_string_method_id, 1, value); return Qnil; } VALUE default_write_uuid(VALUE protocol, VALUE value) { rb_funcall(protocol, write_uuid_method_id, 1, value); return Qnil; } VALUE default_write_binary(VALUE protocol, VALUE value) { rb_funcall(protocol, write_binary_method_id, 1, value); return Qnil; } VALUE default_write_list_begin(VALUE protocol, VALUE etype, VALUE length) { rb_funcall(protocol, write_list_begin_method_id, 2, etype, length); return Qnil; } VALUE default_write_list_end(VALUE protocol) { rb_funcall(protocol, write_list_end_method_id, 0); return Qnil; } VALUE default_write_set_begin(VALUE protocol, VALUE etype, VALUE length) { rb_funcall(protocol, write_set_begin_method_id, 2, etype, length); return Qnil; } VALUE default_write_set_end(VALUE protocol) { rb_funcall(protocol, write_set_end_method_id, 0); return Qnil; } VALUE default_write_map_begin(VALUE protocol, VALUE ktype, VALUE vtype, VALUE length) { rb_funcall(protocol, write_map_begin_method_id, 3, ktype, vtype, length); return Qnil; } VALUE default_write_map_end(VALUE protocol) { rb_funcall(protocol, write_map_end_method_id, 0); return Qnil; } VALUE default_write_struct_begin(VALUE protocol, VALUE struct_name) { rb_funcall(protocol, write_struct_begin_method_id, 1, struct_name); return Qnil; } VALUE default_write_struct_end(VALUE protocol) { rb_funcall(protocol, write_struct_end_method_id, 0); return Qnil; } VALUE default_write_field_begin(VALUE protocol, VALUE name, VALUE type, VALUE id) { rb_funcall(protocol, write_field_begin_method_id, 3, name, type, id); return Qnil; } VALUE default_write_field_end(VALUE protocol) { rb_funcall(protocol, write_field_end_method_id, 0); return Qnil; } VALUE default_write_field_stop(VALUE protocol) { rb_funcall(protocol, write_field_stop_method_id, 0); return Qnil; } VALUE default_read_field_begin(VALUE protocol) { return rb_funcall(protocol, read_field_begin_method_id, 0); } VALUE default_read_field_end(VALUE protocol) { return rb_funcall(protocol, read_field_end_method_id, 0); } VALUE default_read_map_begin(VALUE protocol) { return rb_funcall(protocol, read_map_begin_method_id, 0); } VALUE default_read_map_end(VALUE protocol) { return rb_funcall(protocol, read_map_end_method_id, 0); } VALUE default_read_list_begin(VALUE protocol) { return rb_funcall(protocol, read_list_begin_method_id, 0); } VALUE default_read_list_end(VALUE protocol) { return rb_funcall(protocol, read_list_end_method_id, 0); } VALUE default_read_set_begin(VALUE protocol) { return rb_funcall(protocol, read_set_begin_method_id, 0); } VALUE default_read_set_end(VALUE protocol) { return rb_funcall(protocol, read_set_end_method_id, 0); } VALUE default_read_byte(VALUE protocol) { return rb_funcall(protocol, read_byte_method_id, 0); } VALUE default_read_bool(VALUE protocol) { return rb_funcall(protocol, read_bool_method_id, 0); } VALUE default_read_i16(VALUE protocol) { return rb_funcall(protocol, read_i16_method_id, 0); } VALUE default_read_i32(VALUE protocol) { return rb_funcall(protocol, read_i32_method_id, 0); } VALUE default_read_i64(VALUE protocol) { return rb_funcall(protocol, read_i64_method_id, 0); } VALUE default_read_double(VALUE protocol) { return rb_funcall(protocol, read_double_method_id, 0); } VALUE default_read_string(VALUE protocol) { return rb_funcall(protocol, read_string_method_id, 0); } VALUE default_read_uuid(VALUE protocol) { return rb_funcall(protocol, read_uuid_method_id, 0); } VALUE default_read_binary(VALUE protocol) { return rb_funcall(protocol, read_binary_method_id, 0); } VALUE default_read_struct_begin(VALUE protocol) { return rb_funcall(protocol, read_struct_begin_method_id, 0); } VALUE default_read_struct_end(VALUE protocol) { return rb_funcall(protocol, read_struct_end_method_id, 0); } // end default protocol methods static VALUE rb_thrift_union_write (VALUE self, VALUE protocol); static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol); static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info); VALUE get_field_value(VALUE obj, VALUE field_name) { char name_buf[RSTRING_LEN(field_name) + 2]; name_buf[0] = '@'; strlcpy(&name_buf[1], RSTRING_PTR(field_name), RSTRING_LEN(field_name) + 1); VALUE value = rb_ivar_get(obj, rb_intern(name_buf)); return value; } static void write_container(int ttype, VALUE field_info, VALUE value, VALUE protocol) { long sz, i; if (ttype == TTYPE_MAP) { VALUE keys; VALUE key; VALUE val; Check_Type(value, T_HASH); VALUE key_info = rb_hash_aref(field_info, key_sym); VALUE keytype_value = rb_hash_aref(key_info, type_sym); int keytype = FIX2INT(keytype_value); VALUE value_info = rb_hash_aref(field_info, value_sym); VALUE valuetype_value = rb_hash_aref(value_info, type_sym); int valuetype = FIX2INT(valuetype_value); keys = rb_funcall(value, keys_method_id, 0); sz = RARRAY_LEN(keys); default_write_map_begin(protocol, keytype_value, valuetype_value, INT2FIX(sz)); for (i = 0; i < sz; i++) { key = rb_ary_entry(keys, i); val = rb_hash_aref(value, key); if (IS_CONTAINER(keytype)) { write_container(keytype, key_info, key, protocol); } else { write_anything(keytype, key, protocol, key_info); } if (IS_CONTAINER(valuetype)) { write_container(valuetype, value_info, val, protocol); } else { write_anything(valuetype, val, protocol, value_info); } } default_write_map_end(protocol); } else if (ttype == TTYPE_LIST) { Check_Type(value, T_ARRAY); sz = RARRAY_LEN(value); VALUE element_type_info = rb_hash_aref(field_info, element_sym); VALUE element_type_value = rb_hash_aref(element_type_info, type_sym); int element_type = FIX2INT(element_type_value); default_write_list_begin(protocol, element_type_value, INT2FIX(sz)); for (i = 0; i < sz; ++i) { VALUE val = rb_ary_entry(value, i); if (IS_CONTAINER(element_type)) { write_container(element_type, element_type_info, val, protocol); } else { write_anything(element_type, val, protocol, element_type_info); } } default_write_list_end(protocol); } else if (ttype == TTYPE_SET) { VALUE items; if (TYPE(value) == T_ARRAY) { items = value; } else { if (rb_cSet == CLASS_OF(value)) { items = rb_funcall(value, entries_method_id, 0); } else { Check_Type(value, T_HASH); items = rb_funcall(value, keys_method_id, 0); } } sz = RARRAY_LEN(items); VALUE element_type_info = rb_hash_aref(field_info, element_sym); VALUE element_type_value = rb_hash_aref(element_type_info, type_sym); int element_type = FIX2INT(element_type_value); default_write_set_begin(protocol, element_type_value, INT2FIX(sz)); for (i = 0; i < sz; i++) { VALUE val = rb_ary_entry(items, i); if (IS_CONTAINER(element_type)) { write_container(element_type, element_type_info, val, protocol); } else { write_anything(element_type, val, protocol, element_type_info); } } default_write_set_end(protocol); } else { rb_raise(rb_eNotImpError, "can't write container of type: %d", ttype); } } static void write_anything(int ttype, VALUE value, VALUE protocol, VALUE field_info) { if (ttype == TTYPE_BOOL) { default_write_bool(protocol, value); } else if (ttype == TTYPE_BYTE) { default_write_byte(protocol, value); } else if (ttype == TTYPE_I16) { default_write_i16(protocol, value); } else if (ttype == TTYPE_I32) { default_write_i32(protocol, value); } else if (ttype == TTYPE_I64) { default_write_i64(protocol, value); } else if (ttype == TTYPE_DOUBLE) { default_write_double(protocol, value); } else if (ttype == TTYPE_STRING) { VALUE is_binary = rb_hash_aref(field_info, binary_sym); if (is_binary != Qtrue) { default_write_string(protocol, value); } else { default_write_binary(protocol, value); } } else if (ttype == TTYPE_UUID) { default_write_uuid(protocol, value); } else if (IS_CONTAINER(ttype)) { write_container(ttype, field_info, value, protocol); } else if (ttype == TTYPE_STRUCT) { if (rb_obj_is_kind_of(value, thrift_union_class)) { rb_thrift_union_write(value, protocol); } else { rb_thrift_struct_write(value, protocol); } } else { rb_raise(rb_eNotImpError, "Unknown type for binary_encoding: %d", ttype); } } static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) { // call validate rb_funcall(self, validate_method_id, 0); // write struct begin default_write_struct_begin(protocol, rb_class_name(CLASS_OF(self))); // iterate through all the fields here VALUE struct_fields = STRUCT_FIELDS(self); VALUE sorted_field_ids = rb_funcall(self, sorted_field_ids_method_id, 0); int i = 0; for (i=0; i < RARRAY_LEN(sorted_field_ids); i++) { VALUE field_id = rb_ary_entry(sorted_field_ids, i); VALUE field_info = rb_hash_aref(struct_fields, field_id); VALUE ttype_value = rb_hash_aref(field_info, type_sym); int ttype = FIX2INT(ttype_value); VALUE field_name = rb_hash_aref(field_info, name_sym); VALUE field_value = get_field_value(self, field_name); if (!NIL_P(field_value)) { default_write_field_begin(protocol, field_name, ttype_value, field_id); write_anything(ttype, field_value, protocol, field_info); default_write_field_end(protocol); } } default_write_field_stop(protocol); // write struct end default_write_struct_end(protocol); return Qnil; } //------------------------------------------- // Reading section //------------------------------------------- static VALUE rb_thrift_union_read(VALUE self, VALUE protocol); static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol); static void skip_map_contents(VALUE protocol, VALUE key_type_value, VALUE value_type_value, int size); static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value, int size); static void set_field_value(VALUE obj, VALUE field_name, VALUE value) { char name_buf[RSTRING_LEN(field_name) + 2]; name_buf[0] = '@'; strlcpy(&name_buf[1], RSTRING_PTR(field_name), RSTRING_LEN(field_name)+1); rb_ivar_set(obj, rb_intern(name_buf), value); } // Helper method to skip the contents of a map (assumes the map header has been read). static void skip_map_contents(VALUE protocol, VALUE key_type_value, VALUE value_type_value, int size) { int i; for (i = 0; i < size; i++) { rb_funcall(protocol, skip_method_id, 1, key_type_value); rb_funcall(protocol, skip_method_id, 1, value_type_value); } } // Helper method to skip the contents of a list or set (assumes the list/set header has been read). static void skip_list_or_set_contents(VALUE protocol, VALUE element_type_value, int size) { int i; for (i = 0; i < size; i++) { rb_funcall(protocol, skip_method_id, 1, element_type_value); } } static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) { VALUE result = Qnil; if (ttype == TTYPE_BOOL) { result = default_read_bool(protocol); } else if (ttype == TTYPE_BYTE) { result = default_read_byte(protocol); } else if (ttype == TTYPE_I16) { result = default_read_i16(protocol); } else if (ttype == TTYPE_I32) { result = default_read_i32(protocol); } else if (ttype == TTYPE_I64) { result = default_read_i64(protocol); } else if (ttype == TTYPE_STRING) { VALUE is_binary = rb_hash_aref(field_info, binary_sym); if (is_binary != Qtrue) { result = default_read_string(protocol); } else { result = default_read_binary(protocol); } } else if (ttype == TTYPE_DOUBLE) { result = default_read_double(protocol); } else if (ttype == TTYPE_UUID) { result = default_read_uuid(protocol); } else if (ttype == TTYPE_STRUCT) { VALUE klass = rb_hash_aref(field_info, class_sym); result = rb_class_new_instance(0, NULL, klass); if (rb_obj_is_kind_of(result, thrift_union_class)) { rb_thrift_union_read(result, protocol); } else { rb_thrift_struct_read(result, protocol); } } else if (ttype == TTYPE_MAP) { int i; VALUE map_header = default_read_map_begin(protocol); int key_ttype = FIX2INT(rb_ary_entry(map_header, 0)); int value_ttype = FIX2INT(rb_ary_entry(map_header, 1)); int num_entries = FIX2INT(rb_ary_entry(map_header, 2)); if (num_entries < 0) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_NEGATIVE_SIZE), rb_str_new2("Negative container size"))); } // Check the declared key and value types against the expected ones and skip the map contents // if the types don't match. VALUE key_info = rb_hash_aref(field_info, key_sym); VALUE value_info = rb_hash_aref(field_info, value_sym); if (!NIL_P(key_info) && !NIL_P(value_info)) { int specified_key_type = FIX2INT(rb_hash_aref(key_info, type_sym)); int specified_value_type = FIX2INT(rb_hash_aref(value_info, type_sym)); if (num_entries == 0 || (specified_key_type == key_ttype && specified_value_type == value_ttype)) { result = rb_hash_new(); for (i = 0; i < num_entries; ++i) { VALUE key, val; key = read_anything(protocol, key_ttype, key_info); val = read_anything(protocol, value_ttype, value_info); rb_hash_aset(result, key, val); } } else { skip_map_contents(protocol, INT2FIX(key_ttype), INT2FIX(value_ttype), num_entries); } } else { skip_map_contents(protocol, INT2FIX(key_ttype), INT2FIX(value_ttype), num_entries); } default_read_map_end(protocol); } else if (ttype == TTYPE_LIST) { int i; VALUE list_header = default_read_list_begin(protocol); int element_ttype = FIX2INT(rb_ary_entry(list_header, 0)); int num_elements = FIX2INT(rb_ary_entry(list_header, 1)); // Check the declared element type against the expected one and skip the list contents // if the types don't match. VALUE element_info = rb_hash_aref(field_info, element_sym); if (!NIL_P(element_info)) { int specified_element_type = FIX2INT(rb_hash_aref(element_info, type_sym)); if (specified_element_type == element_ttype) { result = new_container_array(num_elements); for (i = 0; i < num_elements; ++i) { rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym))); } } else { skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements); } } else { skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements); } default_read_list_end(protocol); } else if (ttype == TTYPE_SET) { VALUE items; int i; VALUE set_header = default_read_set_begin(protocol); int element_ttype = FIX2INT(rb_ary_entry(set_header, 0)); int num_elements = FIX2INT(rb_ary_entry(set_header, 1)); // Check the declared element type against the expected one and skip the set contents // if the types don't match. VALUE element_info = rb_hash_aref(field_info, element_sym); if (!NIL_P(element_info)) { int specified_element_type = FIX2INT(rb_hash_aref(element_info, type_sym)); if (specified_element_type == element_ttype) { items = new_container_array(num_elements); for (i = 0; i < num_elements; ++i) { rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym))); } result = rb_class_new_instance(1, &items, rb_cSet); } else { skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements); } } else { skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements); } default_read_set_end(protocol); } else { rb_raise(rb_eNotImpError, "read_anything not implemented for type %d!", ttype); } return result; } static VALUE rb_thrift_struct_read(VALUE self, VALUE protocol) { // read struct begin default_read_struct_begin(protocol); VALUE struct_fields = STRUCT_FIELDS(self); // read each field while (true) { VALUE field_header = default_read_field_begin(protocol); VALUE field_type_value = rb_ary_entry(field_header, 1); int field_type = FIX2INT(field_type_value); if (field_type == TTYPE_STOP) { break; } // make sure we got a type we expected VALUE field_info = rb_hash_aref(struct_fields, rb_ary_entry(field_header, 2)); if (!NIL_P(field_info)) { int specified_type = FIX2INT(rb_hash_aref(field_info, type_sym)); if (field_type == specified_type) { // read the value VALUE name = rb_hash_aref(field_info, name_sym); set_field_value(self, name, read_anything(protocol, field_type, field_info)); } else { rb_funcall(protocol, skip_method_id, 1, field_type_value); } } else { rb_funcall(protocol, skip_method_id, 1, field_type_value); } // read field end default_read_field_end(protocol); } // read struct end default_read_struct_end(protocol); // call validate rb_funcall(self, validate_method_id, 0); return Qnil; } // -------------------------------- // Union section // -------------------------------- static VALUE rb_thrift_union_read(VALUE self, VALUE protocol) { // read struct begin default_read_struct_begin(protocol); VALUE struct_fields = STRUCT_FIELDS(self); VALUE field_header = default_read_field_begin(protocol); VALUE field_type_value = rb_ary_entry(field_header, 1); int field_type = FIX2INT(field_type_value); // make sure we got a type we expected VALUE field_info = rb_hash_aref(struct_fields, rb_ary_entry(field_header, 2)); if (!NIL_P(field_info)) { int specified_type = FIX2INT(rb_hash_aref(field_info, type_sym)); if (field_type == specified_type) { // read the value VALUE name = rb_hash_aref(field_info, name_sym); rb_iv_set(self, "@setfield", rb_str_intern(name)); rb_iv_set(self, "@value", read_anything(protocol, field_type, field_info)); } else { rb_funcall(protocol, skip_method_id, 1, field_type_value); } } else { rb_funcall(protocol, skip_method_id, 1, field_type_value); } // read field end default_read_field_end(protocol); field_header = default_read_field_begin(protocol); field_type_value = rb_ary_entry(field_header, 1); field_type = FIX2INT(field_type_value); if (field_type != TTYPE_STOP) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("too many fields in union!"))); } // read struct end default_read_struct_end(protocol); // call validate rb_funcall(self, validate_method_id, 0); return Qnil; } static VALUE rb_thrift_union_write(VALUE self, VALUE protocol) { // call validate rb_funcall(self, validate_method_id, 0); // write struct begin default_write_struct_begin(protocol, rb_class_name(CLASS_OF(self))); VALUE struct_fields = STRUCT_FIELDS(self); VALUE setfield = rb_ivar_get(self, setfield_id); VALUE setvalue = rb_ivar_get(self, setvalue_id); VALUE field_id = rb_funcall(self, name_to_id_method_id, 1, rb_funcall(setfield, to_s_method_id, 0)); VALUE field_info = rb_hash_aref(struct_fields, field_id); if(NIL_P(field_info)) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("set_field is not valid for this union!"))); } VALUE ttype_value = rb_hash_aref(field_info, type_sym); int ttype = FIX2INT(ttype_value); default_write_field_begin(protocol, setfield, ttype_value, field_id); write_anything(ttype, setvalue, protocol, field_info); default_write_field_end(protocol); default_write_field_stop(protocol); // write struct end default_write_struct_end(protocol); return Qnil; } void Init_struct(void) { VALUE struct_module = rb_const_get(thrift_module, rb_intern("Struct")); rb_define_method(struct_module, "write", rb_thrift_struct_write, 1); rb_define_method(struct_module, "read", rb_thrift_struct_read, 1); thrift_union_class = rb_const_get(thrift_module, rb_intern("Union")); rb_global_variable(&thrift_union_class); rb_define_method(thrift_union_class, "write", rb_thrift_union_write, 1); rb_define_method(thrift_union_class, "read", rb_thrift_union_read, 1); setfield_id = rb_intern("@setfield"); rb_global_variable(&setfield_id); setvalue_id = rb_intern("@value"); rb_global_variable(&setvalue_id); to_s_method_id = rb_intern("to_s"); rb_global_variable(&to_s_method_id); name_to_id_method_id = rb_intern("name_to_id"); rb_global_variable(&name_to_id_method_id); sorted_field_ids_method_id = rb_intern("sorted_field_ids"); rb_global_variable(&sorted_field_ids_method_id); } thrift-0.23.0/lib/rb/ext/strlcpy.c0000664000175000017500000000220315165535636017207 0ustar00buildbuild00000000000000/** * 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 "strlcpy.h" #ifndef HAVE_STRLCPY #define HAVE_STRLCPY size_t strlcpy (char *dst, const char *src, size_t dst_sz) { size_t n; for (n = 0; n < dst_sz; n++) { if ((*dst++ = *src++) == '\0') break; } if (n < dst_sz) return n; if (n > 0) *(dst - 1) = '\0'; return n + strlen (src); } #endif thrift-0.23.0/lib/rb/ext/compact_protocol.c0000664000175000017500000006145715167543515021073 0ustar00buildbuild00000000000000/** * 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 #include #include #include #include #define LAST_ID(obj) FIX2INT(rb_ary_pop(rb_ivar_get(obj, last_field_id))) #define SET_LAST_ID(obj, val) rb_ary_push(rb_ivar_get(obj, last_field_id), val) VALUE rb_thrift_compact_proto_native_qmark(VALUE self) { return Qtrue; } static ID last_field_id; static ID boolean_field_id; static ID bool_value_id; static ID rbuf_ivar_id; static int VERSION; static int VERSION_MASK; static int TYPE_MASK; static int TYPE_BITS; static int TYPE_SHIFT_AMOUNT; static int PROTOCOL_ID; static VALUE thrift_compact_protocol_class; static int CTYPE_BOOLEAN_TRUE = 0x01; static int CTYPE_BOOLEAN_FALSE = 0x02; static int CTYPE_BYTE = 0x03; static int CTYPE_I16 = 0x04; static int CTYPE_I32 = 0x05; static int CTYPE_I64 = 0x06; static int CTYPE_DOUBLE = 0x07; static int CTYPE_BINARY = 0x08; static int CTYPE_LIST = 0x09; static int CTYPE_SET = 0x0A; static int CTYPE_MAP = 0x0B; static int CTYPE_STRUCT = 0x0C; static int CTYPE_UUID = 0x0D; VALUE rb_thrift_compact_proto_write_i16(VALUE self, VALUE i16); // TODO: implement this static int get_compact_type(VALUE type_value) { int type = FIX2INT(type_value); if (type == TTYPE_BOOL) { return CTYPE_BOOLEAN_TRUE; } else if (type == TTYPE_BYTE) { return CTYPE_BYTE; } else if (type == TTYPE_I16) { return CTYPE_I16; } else if (type == TTYPE_I32) { return CTYPE_I32; } else if (type == TTYPE_I64) { return CTYPE_I64; } else if (type == TTYPE_DOUBLE) { return CTYPE_DOUBLE; } else if (type == TTYPE_STRING) { return CTYPE_BINARY; } else if (type == TTYPE_LIST) { return CTYPE_LIST; } else if (type == TTYPE_SET) { return CTYPE_SET; } else if (type == TTYPE_MAP) { return CTYPE_MAP; } else if (type == TTYPE_STRUCT) { return CTYPE_STRUCT; } else if (type == TTYPE_UUID) { return CTYPE_UUID; } else { char str[50]; sprintf(str, "don't know what type: %d", type); rb_raise(rb_eStandardError, "%s", str); return 0; } } static void write_byte_direct(VALUE transport, int8_t b) { WRITE(transport, (char*)&b, 1); } static void write_field_begin_internal(VALUE self, VALUE type, VALUE id_value, VALUE type_override) { int id = FIX2INT(id_value); int last_id = LAST_ID(self); VALUE transport = GET_TRANSPORT(self); // if there's a type override, use that. int8_t type_to_write = RTEST(type_override) ? FIX2INT(type_override) : get_compact_type(type); // check if we can use delta encoding for the field id int diff = id - last_id; if (diff > 0 && diff <= 15) { // write them together write_byte_direct(transport, diff << 4 | (type_to_write & 0x0f)); } else { // write them separate write_byte_direct(transport, type_to_write & 0x0f); rb_thrift_compact_proto_write_i16(self, id_value); } SET_LAST_ID(self, id_value); } static int32_t int_to_zig_zag(int32_t n) { return (n << 1) ^ (n >> 31); } static uint64_t ll_to_zig_zag(int64_t n) { return (n << 1) ^ (n >> 63); } static void write_varint32(VALUE transport, uint32_t n) { while (true) { if ((n & ~0x7F) == 0) { write_byte_direct(transport, n & 0x7f); break; } else { write_byte_direct(transport, (n & 0x7F) | 0x80); n = n >> 7; } } } static void write_varint64(VALUE transport, uint64_t n) { while (true) { if ((n & ~0x7F) == 0) { write_byte_direct(transport, n & 0x7f); break; } else { write_byte_direct(transport, (n & 0x7F) | 0x80); n = n >> 7; } } } static void write_collection_begin(VALUE transport, VALUE elem_type, VALUE size_value) { int size = FIX2INT(size_value); if (size <= 14) { write_byte_direct(transport, size << 4 | get_compact_type(elem_type)); } else { write_byte_direct(transport, 0xf0 | get_compact_type(elem_type)); write_varint32(transport, size); } } //-------------------------------- // interface writing methods //-------------------------------- VALUE rb_thrift_compact_proto_write_i32(VALUE self, VALUE i32); VALUE rb_thrift_compact_proto_write_string(VALUE self, VALUE str); VALUE rb_thrift_compact_proto_write_binary(VALUE self, VALUE buf); VALUE rb_thrift_compact_proto_write_uuid(VALUE self, VALUE uuid); VALUE rb_thrift_compact_proto_write_message_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_write_struct_begin(VALUE self, VALUE name) { rb_ary_push(rb_ivar_get(self, last_field_id), INT2FIX(0)); return Qnil; } VALUE rb_thrift_compact_proto_write_struct_end(VALUE self) { rb_ary_pop(rb_ivar_get(self, last_field_id)); return Qnil; } VALUE rb_thrift_compact_proto_write_field_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_write_map_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_write_list_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_write_set_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_write_message_begin(VALUE self, VALUE name, VALUE type, VALUE seqid) { VALUE transport = GET_TRANSPORT(self); write_byte_direct(transport, PROTOCOL_ID); write_byte_direct(transport, (VERSION & VERSION_MASK) | ((FIX2INT(type) << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); write_varint32(transport, FIX2INT(seqid)); rb_thrift_compact_proto_write_string(self, name); return Qnil; } VALUE rb_thrift_compact_proto_write_field_begin(VALUE self, VALUE name, VALUE type, VALUE id) { if (FIX2INT(type) == TTYPE_BOOL) { // we want to possibly include the value, so we'll wait. rb_ivar_set(self, boolean_field_id, rb_ary_new3(2, type, id)); } else { write_field_begin_internal(self, type, id, Qnil); } return Qnil; } VALUE rb_thrift_compact_proto_write_field_stop(VALUE self) { write_byte_direct(GET_TRANSPORT(self), TTYPE_STOP); return Qnil; } VALUE rb_thrift_compact_proto_write_map_begin(VALUE self, VALUE ktype, VALUE vtype, VALUE size_value) { int size = FIX2INT(size_value); VALUE transport = GET_TRANSPORT(self); if (size == 0) { write_byte_direct(transport, 0); } else { write_varint32(transport, size); write_byte_direct(transport, get_compact_type(ktype) << 4 | get_compact_type(vtype)); } return Qnil; } VALUE rb_thrift_compact_proto_write_list_begin(VALUE self, VALUE etype, VALUE size) { write_collection_begin(GET_TRANSPORT(self), etype, size); return Qnil; } VALUE rb_thrift_compact_proto_write_set_begin(VALUE self, VALUE etype, VALUE size) { write_collection_begin(GET_TRANSPORT(self), etype, size); return Qnil; } VALUE rb_thrift_compact_proto_write_bool(VALUE self, VALUE b) { int8_t type = b == Qtrue ? CTYPE_BOOLEAN_TRUE : CTYPE_BOOLEAN_FALSE; VALUE boolean_field = rb_ivar_get(self, boolean_field_id); if (NIL_P(boolean_field)) { // we're not part of a field, so just write the value. write_byte_direct(GET_TRANSPORT(self), type); } else { // we haven't written the field header yet write_field_begin_internal(self, rb_ary_entry(boolean_field, 0), rb_ary_entry(boolean_field, 1), INT2FIX(type)); rb_ivar_set(self, boolean_field_id, Qnil); } return Qnil; } VALUE rb_thrift_compact_proto_write_byte(VALUE self, VALUE byte) { CHECK_NIL(byte); write_byte_direct(GET_TRANSPORT(self), FIX2INT(byte)); return Qnil; } VALUE rb_thrift_compact_proto_write_i16(VALUE self, VALUE i16) { rb_thrift_compact_proto_write_i32(self, i16); return Qnil; } VALUE rb_thrift_compact_proto_write_i32(VALUE self, VALUE i32) { CHECK_NIL(i32); write_varint32(GET_TRANSPORT(self), int_to_zig_zag(NUM2INT(i32))); return Qnil; } VALUE rb_thrift_compact_proto_write_i64(VALUE self, VALUE i64) { CHECK_NIL(i64); write_varint64(GET_TRANSPORT(self), ll_to_zig_zag(NUM2LL(i64))); return Qnil; } VALUE rb_thrift_compact_proto_write_double(VALUE self, VALUE dub) { CHECK_NIL(dub); // Unfortunately, bitwise_cast doesn't work in C. Bad C! union { double f; int64_t l; } transfer; transfer.f = RFLOAT_VALUE(rb_Float(dub)); char buf[8]; buf[0] = transfer.l & 0xff; buf[1] = (transfer.l >> 8) & 0xff; buf[2] = (transfer.l >> 16) & 0xff; buf[3] = (transfer.l >> 24) & 0xff; buf[4] = (transfer.l >> 32) & 0xff; buf[5] = (transfer.l >> 40) & 0xff; buf[6] = (transfer.l >> 48) & 0xff; buf[7] = (transfer.l >> 56) & 0xff; WRITE(GET_TRANSPORT(self), buf, 8); return Qnil; } VALUE rb_thrift_compact_proto_write_string(VALUE self, VALUE str) { str = convert_to_utf8_byte_buffer(str); rb_thrift_compact_proto_write_binary(self, str); return Qnil; } VALUE rb_thrift_compact_proto_write_binary(VALUE self, VALUE buf) { buf = force_binary_encoding(buf); VALUE transport = GET_TRANSPORT(self); write_varint32(transport, (uint32_t)RSTRING_LEN(buf)); WRITE(transport, StringValuePtr(buf), RSTRING_LEN(buf)); return Qnil; } VALUE rb_thrift_compact_proto_write_uuid(VALUE self, VALUE uuid) { if (NIL_P(uuid) || TYPE(uuid) != T_STRING) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("UUID must be a string"))); } VALUE transport = GET_TRANSPORT(self); char bytes[16]; const char* str = RSTRING_PTR(uuid); long len = RSTRING_LEN(uuid); // Parse UUID string (format: "550e8400-e29b-41d4-a716-446655440000") // Expected length: 36 characters (32 hex + 4 hyphens) if (len != 36 || str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-') { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("Invalid UUID format"))); } // Parse hex string to bytes using direct conversion, skipping hyphens int byte_idx = 0; for (int i = 0; i < len && byte_idx < 16; i++) { if (str[i] == '-') continue; if (i + 1 >= len || str[i + 1] == '-') break; // Convert two hex characters to one byte int high = hex_char_to_int(str[i]); int low = hex_char_to_int(str[i + 1]); if (high < 0 || low < 0) break; bytes[byte_idx++] = (unsigned char)((high << 4) | low); i++; // skip next char since we processed two } if (byte_idx != 16) { rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("Invalid UUID format"))); } WRITE(transport, bytes, 16); return Qnil; } //--------------------------------------- // interface reading methods //--------------------------------------- #define is_bool_type(ctype) (((ctype) & 0x0F) == CTYPE_BOOLEAN_TRUE || ((ctype) & 0x0F) == CTYPE_BOOLEAN_FALSE) VALUE rb_thrift_compact_proto_read_string(VALUE self); VALUE rb_thrift_compact_proto_read_binary(VALUE self); VALUE rb_thrift_compact_proto_read_byte(VALUE self); VALUE rb_thrift_compact_proto_read_i32(VALUE self); VALUE rb_thrift_compact_proto_read_i16(VALUE self); VALUE rb_thrift_compact_proto_read_uuid(VALUE self); static int8_t get_ttype(int8_t ctype) { if (ctype == TTYPE_STOP) { return TTYPE_STOP; } else if (ctype == CTYPE_BOOLEAN_TRUE || ctype == CTYPE_BOOLEAN_FALSE) { return TTYPE_BOOL; } else if (ctype == CTYPE_BYTE) { return TTYPE_BYTE; } else if (ctype == CTYPE_I16) { return TTYPE_I16; } else if (ctype == CTYPE_I32) { return TTYPE_I32; } else if (ctype == CTYPE_I64) { return TTYPE_I64; } else if (ctype == CTYPE_DOUBLE) { return TTYPE_DOUBLE; } else if (ctype == CTYPE_BINARY) { return TTYPE_STRING; } else if (ctype == CTYPE_LIST) { return TTYPE_LIST; } else if (ctype == CTYPE_SET) { return TTYPE_SET; } else if (ctype == CTYPE_MAP) { return TTYPE_MAP; } else if (ctype == CTYPE_STRUCT) { return TTYPE_STRUCT; } else if (ctype == CTYPE_UUID) { return TTYPE_UUID; } else { char str[50]; sprintf(str, "don't know what type: %d", ctype); rb_raise(rb_eStandardError, "%s", str); return 0; } } static char read_byte_direct(VALUE self) { VALUE byte = rb_funcall(GET_TRANSPORT(self), read_byte_method_id, 0); return (char)(FIX2INT(byte)); } static int64_t zig_zag_to_ll(int64_t n) { return (((uint64_t)n) >> 1) ^ -(n & 1); } static int32_t zig_zag_to_int(int32_t n) { return (((uint32_t)n) >> 1) ^ -(n & 1); } static int64_t read_varint64(VALUE self) { int shift = 0; int64_t result = 0; while (true) { int8_t b = read_byte_direct(self); result = result | ((uint64_t)(b & 0x7f) << shift); if ((b & 0x80) != 0x80) { break; } shift += 7; } return result; } static int16_t read_i16(VALUE self) { return zig_zag_to_int((int32_t)read_varint64(self)); } VALUE rb_thrift_compact_proto_read_message_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_read_struct_begin(VALUE self) { rb_ary_push(rb_ivar_get(self, last_field_id), INT2FIX(0)); return Qnil; } VALUE rb_thrift_compact_proto_read_struct_end(VALUE self) { rb_ary_pop(rb_ivar_get(self, last_field_id)); return Qnil; } VALUE rb_thrift_compact_proto_read_field_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_read_map_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_read_list_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_read_set_end(VALUE self) { return Qnil; } VALUE rb_thrift_compact_proto_read_message_begin(VALUE self) { int8_t protocol_id = read_byte_direct(self); if (protocol_id != PROTOCOL_ID) { char buf[100]; int len = sprintf(buf, "Expected protocol id %d but got %d", PROTOCOL_ID, protocol_id); buf[len] = 0; rb_exc_raise(get_protocol_exception(INT2FIX(-1), rb_str_new2(buf))); } int8_t version_and_type = read_byte_direct(self); int8_t version = version_and_type & VERSION_MASK; if (version != VERSION) { char buf[100]; int len = sprintf(buf, "Expected version id %d but got %d", version, VERSION); buf[len] = 0; rb_exc_raise(get_protocol_exception(INT2FIX(-1), rb_str_new2(buf))); } int8_t type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS; 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)); } VALUE rb_thrift_compact_proto_read_field_begin(VALUE self) { int8_t type = read_byte_direct(self); // if it's a stop, then we can return immediately, as the struct is over. if ((type & 0x0f) == TTYPE_STOP) { return rb_ary_new3(3, Qnil, INT2FIX(0), INT2FIX(0)); } else { int field_id = 0; // mask off the 4 MSB of the type header. it could contain a field id delta. uint8_t modifier = ((type & 0xf0) >> 4); if (modifier == 0) { // not a delta. look ahead for the zigzag varint field id. (void) LAST_ID(self); field_id = read_i16(self); } else { // has a delta. add the delta to the last read field id. field_id = LAST_ID(self) + modifier; } // if this happens to be a boolean field, the value is encoded in the type if (is_bool_type(type)) { // save the boolean value in a special instance variable. rb_ivar_set(self, bool_value_id, (type & 0x0f) == CTYPE_BOOLEAN_TRUE ? Qtrue : Qfalse); } // push the new field onto the field stack so we can keep the deltas going. SET_LAST_ID(self, INT2FIX(field_id)); return rb_ary_new3(3, Qnil, INT2FIX(get_ttype(type & 0x0f)), INT2FIX(field_id)); } } VALUE rb_thrift_compact_proto_read_map_begin(VALUE 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)); } 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 = (int32_t)read_varint64(self); } uint8_t type = get_ttype(size_and_type & 0x0f); return rb_ary_new3(2, INT2FIX(type), INT2FIX(size)); } VALUE rb_thrift_compact_proto_read_set_begin(VALUE self) { return rb_thrift_compact_proto_read_list_begin(self); } VALUE rb_thrift_compact_proto_read_bool(VALUE self) { VALUE bool_value = rb_ivar_get(self, bool_value_id); if (NIL_P(bool_value)) { return read_byte_direct(self) == CTYPE_BOOLEAN_TRUE ? Qtrue : Qfalse; } else { rb_ivar_set(self, bool_value_id, Qnil); return bool_value; } } VALUE rb_thrift_compact_proto_read_byte(VALUE self) { return INT2FIX(read_byte_direct(self)); } VALUE rb_thrift_compact_proto_read_i16(VALUE self) { return INT2FIX(read_i16(self)); } VALUE rb_thrift_compact_proto_read_i32(VALUE self) { return INT2NUM(zig_zag_to_int((int32_t)read_varint64(self))); } VALUE rb_thrift_compact_proto_read_i64(VALUE self) { return LL2NUM(zig_zag_to_ll(read_varint64(self))); } VALUE rb_thrift_compact_proto_read_double(VALUE self) { union { double f; int64_t l; } transfer; VALUE rbuf = rb_ivar_get(self, rbuf_ivar_id); rb_funcall(GET_TRANSPORT(self), read_into_buffer_method_id, 2, rbuf, INT2FIX(8)); uint32_t lo = ((uint8_t)(RSTRING_PTR(rbuf)[0])) | (((uint8_t)(RSTRING_PTR(rbuf)[1])) << 8) | (((uint8_t)(RSTRING_PTR(rbuf)[2])) << 16) | (((uint8_t)(RSTRING_PTR(rbuf)[3])) << 24); uint64_t hi = (((uint8_t)(RSTRING_PTR(rbuf)[4]))) | (((uint8_t)(RSTRING_PTR(rbuf)[5])) << 8) | (((uint8_t)(RSTRING_PTR(rbuf)[6])) << 16) | (((uint8_t)(RSTRING_PTR(rbuf)[7])) << 24); transfer.l = (hi << 32) | lo; return rb_float_new(transfer.f); } VALUE rb_thrift_compact_proto_read_string(VALUE self) { VALUE buffer = rb_thrift_compact_proto_read_binary(self); return convert_to_string(buffer); } VALUE rb_thrift_compact_proto_read_binary(VALUE self) { int64_t size = read_varint64(self); return READ(self, size); } VALUE rb_thrift_compact_proto_read_uuid(VALUE self) { VALUE data = READ(self, 16); const unsigned char* bytes = (const unsigned char*)RSTRING_PTR(data); // Format as UUID string: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" char uuid_str[37]; char* p = uuid_str; for (int i = 0; i < 16; i++) { *p++ = int_to_hex_char((bytes[i] >> 4) & 0x0F); *p++ = int_to_hex_char(bytes[i] & 0x0F); if (i == 3 || i == 5 || i == 7 || i == 9) { *p++ = '-'; } } *p = '\0'; return rb_str_new(uuid_str, 36); } static void Init_constants(void) { thrift_compact_protocol_class = rb_const_get(thrift_module, rb_intern("CompactProtocol")); rb_global_variable(&thrift_compact_protocol_class); 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"))); last_field_id = rb_intern("@last_field"); boolean_field_id = rb_intern("@boolean_field"); bool_value_id = rb_intern("@bool_value"); rbuf_ivar_id = rb_intern("@rbuf"); } static void Init_rb_methods(void) { rb_define_method(thrift_compact_protocol_class, "native?", rb_thrift_compact_proto_native_qmark, 0); rb_define_method(thrift_compact_protocol_class, "write_message_begin", rb_thrift_compact_proto_write_message_begin, 3); rb_define_method(thrift_compact_protocol_class, "write_field_begin", rb_thrift_compact_proto_write_field_begin, 3); rb_define_method(thrift_compact_protocol_class, "write_field_stop", rb_thrift_compact_proto_write_field_stop, 0); rb_define_method(thrift_compact_protocol_class, "write_map_begin", rb_thrift_compact_proto_write_map_begin, 3); rb_define_method(thrift_compact_protocol_class, "write_list_begin", rb_thrift_compact_proto_write_list_begin, 2); rb_define_method(thrift_compact_protocol_class, "write_set_begin", rb_thrift_compact_proto_write_set_begin, 2); rb_define_method(thrift_compact_protocol_class, "write_byte", rb_thrift_compact_proto_write_byte, 1); rb_define_method(thrift_compact_protocol_class, "write_bool", rb_thrift_compact_proto_write_bool, 1); rb_define_method(thrift_compact_protocol_class, "write_i16", rb_thrift_compact_proto_write_i16, 1); rb_define_method(thrift_compact_protocol_class, "write_i32", rb_thrift_compact_proto_write_i32, 1); rb_define_method(thrift_compact_protocol_class, "write_i64", rb_thrift_compact_proto_write_i64, 1); rb_define_method(thrift_compact_protocol_class, "write_double", rb_thrift_compact_proto_write_double, 1); rb_define_method(thrift_compact_protocol_class, "write_string", rb_thrift_compact_proto_write_string, 1); rb_define_method(thrift_compact_protocol_class, "write_binary", rb_thrift_compact_proto_write_binary, 1); rb_define_method(thrift_compact_protocol_class, "write_uuid", rb_thrift_compact_proto_write_uuid, 1); rb_define_method(thrift_compact_protocol_class, "write_message_end", rb_thrift_compact_proto_write_message_end, 0); rb_define_method(thrift_compact_protocol_class, "write_struct_begin", rb_thrift_compact_proto_write_struct_begin, 1); rb_define_method(thrift_compact_protocol_class, "write_struct_end", rb_thrift_compact_proto_write_struct_end, 0); rb_define_method(thrift_compact_protocol_class, "write_field_end", rb_thrift_compact_proto_write_field_end, 0); rb_define_method(thrift_compact_protocol_class, "write_map_end", rb_thrift_compact_proto_write_map_end, 0); rb_define_method(thrift_compact_protocol_class, "write_list_end", rb_thrift_compact_proto_write_list_end, 0); rb_define_method(thrift_compact_protocol_class, "write_set_end", rb_thrift_compact_proto_write_set_end, 0); rb_define_method(thrift_compact_protocol_class, "read_message_begin", rb_thrift_compact_proto_read_message_begin, 0); rb_define_method(thrift_compact_protocol_class, "read_field_begin", rb_thrift_compact_proto_read_field_begin, 0); rb_define_method(thrift_compact_protocol_class, "read_map_begin", rb_thrift_compact_proto_read_map_begin, 0); rb_define_method(thrift_compact_protocol_class, "read_list_begin", rb_thrift_compact_proto_read_list_begin, 0); rb_define_method(thrift_compact_protocol_class, "read_set_begin", rb_thrift_compact_proto_read_set_begin, 0); rb_define_method(thrift_compact_protocol_class, "read_byte", rb_thrift_compact_proto_read_byte, 0); rb_define_method(thrift_compact_protocol_class, "read_bool", rb_thrift_compact_proto_read_bool, 0); rb_define_method(thrift_compact_protocol_class, "read_i16", rb_thrift_compact_proto_read_i16, 0); rb_define_method(thrift_compact_protocol_class, "read_i32", rb_thrift_compact_proto_read_i32, 0); rb_define_method(thrift_compact_protocol_class, "read_i64", rb_thrift_compact_proto_read_i64, 0); rb_define_method(thrift_compact_protocol_class, "read_double", rb_thrift_compact_proto_read_double, 0); rb_define_method(thrift_compact_protocol_class, "read_string", rb_thrift_compact_proto_read_string, 0); rb_define_method(thrift_compact_protocol_class, "read_binary", rb_thrift_compact_proto_read_binary, 0); rb_define_method(thrift_compact_protocol_class, "read_uuid", rb_thrift_compact_proto_read_uuid, 0); rb_define_method(thrift_compact_protocol_class, "read_message_end", rb_thrift_compact_proto_read_message_end, 0); rb_define_method(thrift_compact_protocol_class, "read_struct_begin", rb_thrift_compact_proto_read_struct_begin, 0); rb_define_method(thrift_compact_protocol_class, "read_struct_end", rb_thrift_compact_proto_read_struct_end, 0); rb_define_method(thrift_compact_protocol_class, "read_field_end", rb_thrift_compact_proto_read_field_end, 0); rb_define_method(thrift_compact_protocol_class, "read_map_end", rb_thrift_compact_proto_read_map_end, 0); rb_define_method(thrift_compact_protocol_class, "read_list_end", rb_thrift_compact_proto_read_list_end, 0); rb_define_method(thrift_compact_protocol_class, "read_set_end", rb_thrift_compact_proto_read_set_end, 0); } void Init_compact_protocol(void) { Init_constants(); Init_rb_methods(); } thrift-0.23.0/lib/rb/ext/struct.h0000664000175000017500000000156515165535636017052 0ustar00buildbuild00000000000000/* * 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 void Init_struct(); void Init_union(); thrift-0.23.0/lib/rb/ext/bytes.c0000664000175000017500000000242515165535636016643 0ustar00buildbuild00000000000000/** * 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 #ifdef HAVE_RUBY_ENCODING_H #include #endif #include VALUE force_binary_encoding(VALUE buffer) { return rb_funcall(thrift_bytes_module, force_binary_encoding_id, 1, buffer); } VALUE convert_to_utf8_byte_buffer(VALUE string) { return rb_funcall(thrift_bytes_module, convert_to_utf8_byte_buffer_id, 1, string); } VALUE convert_to_string(VALUE utf8_buffer) { return rb_funcall(thrift_bytes_module, convert_to_string_id, 1, utf8_buffer); } thrift-0.23.0/lib/rb/ext/bytes.h0000664000175000017500000000217215165535636016647 0ustar00buildbuild00000000000000/** * 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 /* * A collection of utilities for working with bytes and byte buffers. * * These methods are the native analogies to some of the methods in * Thrift::Bytes (thrift/bytes.rb). */ VALUE force_binary_encoding(VALUE buffer); VALUE convert_to_utf8_byte_buffer(VALUE string); VALUE convert_to_string(VALUE utf8_buffer); thrift-0.23.0/lib/rb/ext/compact_protocol.h0000664000175000017500000000150315165535636021065 0ustar00buildbuild00000000000000/* * 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. */ void Init_compact_protocol(); thrift-0.23.0/lib/rb/ext/protocol.h0000664000175000017500000000243415167543515017360 0ustar00buildbuild00000000000000/* * 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 VALUE get_protocol_exception(VALUE code, VALUE message); // Efficient hex character to integer conversion static inline int hex_char_to_int(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; // invalid hex character } // Efficient integer to hex character conversion static inline char int_to_hex_char(int val) { return val < 10 ? ('0' + val) : ('a' + val - 10); } thrift-0.23.0/lib/rb/ext/thrift_native.c0000664000175000017500000002144715167543515020365 0ustar00buildbuild00000000000000/** * 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 #include // cached classes/modules VALUE rb_cSet; VALUE thrift_module; VALUE thrift_bytes_module; VALUE thrift_types_module; // TType constants int TTYPE_STOP; int TTYPE_BOOL; int TTYPE_BYTE; int TTYPE_I16; int TTYPE_I32; int TTYPE_I64; int TTYPE_DOUBLE; int TTYPE_STRING; int TTYPE_MAP; int TTYPE_SET; int TTYPE_LIST; int TTYPE_STRUCT; int TTYPE_UUID; // method ids ID validate_method_id; ID write_struct_begin_method_id; ID write_struct_end_method_id; ID write_field_begin_method_id; ID write_field_end_method_id; ID write_boolean_method_id; ID write_byte_method_id; ID write_i16_method_id; ID write_i32_method_id; ID write_i64_method_id; ID write_double_method_id; ID write_string_method_id; ID write_uuid_method_id; ID write_binary_method_id; ID write_map_begin_method_id; ID write_map_end_method_id; ID write_list_begin_method_id; ID write_list_end_method_id; ID write_set_begin_method_id; ID write_set_end_method_id; ID read_bool_method_id; ID read_byte_method_id; ID read_i16_method_id; ID read_i32_method_id; ID read_i64_method_id; ID read_string_method_id; ID read_uuid_method_id; ID read_binary_method_id; ID read_double_method_id; ID read_map_begin_method_id; ID read_map_end_method_id; ID read_list_begin_method_id; ID read_list_end_method_id; ID read_set_begin_method_id; ID read_set_end_method_id; ID read_struct_begin_method_id; ID read_struct_end_method_id; ID read_field_begin_method_id; ID read_field_end_method_id; ID keys_method_id; ID entries_method_id; ID write_field_stop_method_id; ID skip_method_id; ID write_method_id; ID read_all_method_id; ID read_into_buffer_method_id; ID force_binary_encoding_id; ID convert_to_utf8_byte_buffer_id; ID convert_to_string_id; // constant ids ID fields_const_id; ID transport_ivar_id; ID strict_read_ivar_id; ID strict_write_ivar_id; // cached symbols VALUE type_sym; VALUE name_sym; VALUE key_sym; VALUE value_sym; VALUE element_sym; VALUE class_sym; VALUE binary_sym; VALUE protocol_exception_class; // protocol errors int PROTOERR_UNKNOWN; int PROTOERR_INVALID_DATA; int PROTOERR_NEGATIVE_SIZE; int PROTOERR_SIZE_LIMIT; int PROTOERR_BAD_VERSION; int PROTOERR_NOT_IMPLEMENTED; int PROTOERR_DEPTH_LIMIT; RUBY_FUNC_EXPORTED void Init_thrift_native(void) { // cached classes thrift_module = rb_const_get(rb_cObject, rb_intern("Thrift")); rb_global_variable(&thrift_module); thrift_bytes_module = rb_const_get(thrift_module, rb_intern("Bytes")); rb_global_variable(&thrift_bytes_module); thrift_types_module = rb_const_get(thrift_module, rb_intern("Types")); rb_global_variable(&thrift_types_module); rb_cSet = rb_const_get(rb_cObject, rb_intern("Set")); rb_global_variable(&rb_cSet); protocol_exception_class = rb_const_get(thrift_module, rb_intern("ProtocolException")); rb_global_variable(&protocol_exception_class); // Init ttype constants TTYPE_BOOL = FIX2INT(rb_const_get(thrift_types_module, rb_intern("BOOL"))); TTYPE_BYTE = FIX2INT(rb_const_get(thrift_types_module, rb_intern("BYTE"))); TTYPE_I16 = FIX2INT(rb_const_get(thrift_types_module, rb_intern("I16"))); TTYPE_I32 = FIX2INT(rb_const_get(thrift_types_module, rb_intern("I32"))); TTYPE_I64 = FIX2INT(rb_const_get(thrift_types_module, rb_intern("I64"))); TTYPE_DOUBLE = FIX2INT(rb_const_get(thrift_types_module, rb_intern("DOUBLE"))); TTYPE_STRING = FIX2INT(rb_const_get(thrift_types_module, rb_intern("STRING"))); TTYPE_MAP = FIX2INT(rb_const_get(thrift_types_module, rb_intern("MAP"))); TTYPE_SET = FIX2INT(rb_const_get(thrift_types_module, rb_intern("SET"))); TTYPE_LIST = FIX2INT(rb_const_get(thrift_types_module, rb_intern("LIST"))); TTYPE_STRUCT = FIX2INT(rb_const_get(thrift_types_module, rb_intern("STRUCT"))); TTYPE_UUID = FIX2INT(rb_const_get(thrift_types_module, rb_intern("UUID"))); // method ids validate_method_id = rb_intern("validate"); write_struct_begin_method_id = rb_intern("write_struct_begin"); write_struct_end_method_id = rb_intern("write_struct_end"); write_field_begin_method_id = rb_intern("write_field_begin"); write_field_end_method_id = rb_intern("write_field_end"); write_boolean_method_id = rb_intern("write_bool"); write_byte_method_id = rb_intern("write_byte"); write_i16_method_id = rb_intern("write_i16"); write_i32_method_id = rb_intern("write_i32"); write_i64_method_id = rb_intern("write_i64"); write_double_method_id = rb_intern("write_double"); write_string_method_id = rb_intern("write_string"); write_uuid_method_id = rb_intern("write_uuid"); write_binary_method_id = rb_intern("write_binary"); write_map_begin_method_id = rb_intern("write_map_begin"); write_map_end_method_id = rb_intern("write_map_end"); write_list_begin_method_id = rb_intern("write_list_begin"); write_list_end_method_id = rb_intern("write_list_end"); write_set_begin_method_id = rb_intern("write_set_begin"); write_set_end_method_id = rb_intern("write_set_end"); read_bool_method_id = rb_intern("read_bool"); read_byte_method_id = rb_intern("read_byte"); read_i16_method_id = rb_intern("read_i16"); read_i32_method_id = rb_intern("read_i32"); read_i64_method_id = rb_intern("read_i64"); read_string_method_id = rb_intern("read_string"); read_uuid_method_id = rb_intern("read_uuid"); read_binary_method_id = rb_intern("read_binary"); read_double_method_id = rb_intern("read_double"); read_map_begin_method_id = rb_intern("read_map_begin"); read_map_end_method_id = rb_intern("read_map_end"); read_list_begin_method_id = rb_intern("read_list_begin"); read_list_end_method_id = rb_intern("read_list_end"); read_set_begin_method_id = rb_intern("read_set_begin"); read_set_end_method_id = rb_intern("read_set_end"); read_struct_begin_method_id = rb_intern("read_struct_begin"); read_struct_end_method_id = rb_intern("read_struct_end"); read_field_begin_method_id = rb_intern("read_field_begin"); read_field_end_method_id = rb_intern("read_field_end"); keys_method_id = rb_intern("keys"); entries_method_id = rb_intern("entries"); write_field_stop_method_id = rb_intern("write_field_stop"); skip_method_id = rb_intern("skip"); write_method_id = rb_intern("write"); read_all_method_id = rb_intern("read_all"); read_into_buffer_method_id = rb_intern("read_into_buffer"); force_binary_encoding_id = rb_intern("force_binary_encoding"); convert_to_utf8_byte_buffer_id = rb_intern("convert_to_utf8_byte_buffer"); convert_to_string_id = rb_intern("convert_to_string"); // constant ids fields_const_id = rb_intern("FIELDS"); transport_ivar_id = rb_intern("@trans"); strict_read_ivar_id = rb_intern("@strict_read"); strict_write_ivar_id = rb_intern("@strict_write"); // cached symbols type_sym = ID2SYM(rb_intern("type")); name_sym = ID2SYM(rb_intern("name")); key_sym = ID2SYM(rb_intern("key")); value_sym = ID2SYM(rb_intern("value")); element_sym = ID2SYM(rb_intern("element")); class_sym = ID2SYM(rb_intern("class")); binary_sym = ID2SYM(rb_intern("binary")); // protocol errors PROTOERR_UNKNOWN = FIX2INT(rb_const_get(protocol_exception_class, rb_intern("UNKNOWN"))); PROTOERR_INVALID_DATA = FIX2INT(rb_const_get(protocol_exception_class, rb_intern("INVALID_DATA"))); PROTOERR_NEGATIVE_SIZE = FIX2INT(rb_const_get(protocol_exception_class, rb_intern("NEGATIVE_SIZE"))); PROTOERR_SIZE_LIMIT = FIX2INT(rb_const_get(protocol_exception_class, rb_intern("SIZE_LIMIT"))); PROTOERR_BAD_VERSION = FIX2INT(rb_const_get(protocol_exception_class, rb_intern("BAD_VERSION"))); PROTOERR_NOT_IMPLEMENTED = FIX2INT(rb_const_get(protocol_exception_class, rb_intern("NOT_IMPLEMENTED"))); PROTOERR_DEPTH_LIMIT = FIX2INT(rb_const_get(protocol_exception_class, rb_intern("DEPTH_LIMIT"))); rb_global_variable(&type_sym); rb_global_variable(&name_sym); rb_global_variable(&key_sym); rb_global_variable(&value_sym); rb_global_variable(&element_sym); rb_global_variable(&class_sym); rb_global_variable(&binary_sym); Init_struct(); Init_binary_protocol_accelerated(); Init_compact_protocol(); Init_memory_buffer(); } thrift-0.23.0/lib/rb/ext/binary_protocol_accelerated.h0000664000175000017500000000151615165535636023243 0ustar00buildbuild00000000000000/* * 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. */ void Init_binary_protocol_accelerated(); thrift-0.23.0/lib/rb/ext/memory_buffer.c0000664000175000017500000001061415167543515020352 0ustar00buildbuild00000000000000/** * 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 ID buf_ivar_id; ID index_ivar_id; ID slice_method_id; int GARBAGE_BUFFER_SIZE; #define GET_BUF(self) rb_ivar_get(self, buf_ivar_id) VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str); VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value); VALUE rb_thrift_memory_buffer_read_byte(VALUE self); VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, VALUE size_value); VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str) { VALUE buf = GET_BUF(self); str = force_binary_encoding(str); rb_str_buf_cat(buf, StringValuePtr(str), RSTRING_LEN(str)); return Qnil; } VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) { int length = FIX2INT(length_value); VALUE index_value = rb_ivar_get(self, index_ivar_id); int index = FIX2INT(index_value); VALUE buf = GET_BUF(self); VALUE data = rb_funcall(buf, slice_method_id, 2, index_value, length_value); index += length; if (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))); index = 0; } rb_ivar_set(self, index_ivar_id, INT2FIX(index)); if (RSTRING_LEN(data) < length) { rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer"); } return data; } VALUE rb_thrift_memory_buffer_read_byte(VALUE self) { VALUE index_value = rb_ivar_get(self, index_ivar_id); int index = FIX2INT(index_value); VALUE buf = GET_BUF(self); if (index >= RSTRING_LEN(buf)) { rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer"); } char byte = RSTRING_PTR(buf)[index++]; 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))); index = 0; } rb_ivar_set(self, index_ivar_id, INT2FIX(index)); int result = (int) byte; return INT2FIX(result); } VALUE rb_thrift_memory_buffer_read_into_buffer(VALUE self, VALUE buffer_value, VALUE size_value) { int i = 0; int size = FIX2INT(size_value); int index; VALUE buf = GET_BUF(self); index = FIX2INT(rb_ivar_get(self, index_ivar_id)); while (i < size) { if (index >= RSTRING_LEN(buf)) { rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer"); } char byte = RSTRING_PTR(buf)[index++]; if (i >= RSTRING_LEN(buffer_value)) { rb_raise(rb_eIndexError, "index %d out of string", i); } ((char*)RSTRING_PTR(buffer_value))[i] = byte; i++; } 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))); index = 0; } rb_ivar_set(self, index_ivar_id, INT2FIX(index)); return INT2FIX(i); } void Init_memory_buffer(void) { VALUE thrift_memory_buffer_class = rb_const_get(thrift_module, rb_intern("MemoryBufferTransport")); rb_define_method(thrift_memory_buffer_class, "write", rb_thrift_memory_buffer_write, 1); rb_define_method(thrift_memory_buffer_class, "read", rb_thrift_memory_buffer_read, 1); rb_define_method(thrift_memory_buffer_class, "read_byte", rb_thrift_memory_buffer_read_byte, 0); rb_define_method(thrift_memory_buffer_class, "read_into_buffer", rb_thrift_memory_buffer_read_into_buffer, 2); buf_ivar_id = rb_intern("@buf"); index_ivar_id = rb_intern("@index"); slice_method_id = rb_intern("slice"); GARBAGE_BUFFER_SIZE = FIX2INT(rb_const_get(thrift_memory_buffer_class, rb_intern("GARBAGE_BUFFER_SIZE"))); } thrift-0.23.0/lib/rb/ext/constants.h0000664000175000017500000000666115167543515017541 0ustar00buildbuild00000000000000/* * 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. */ extern int TTYPE_STOP; extern int TTYPE_BOOL; extern int TTYPE_BYTE; extern int TTYPE_I16; extern int TTYPE_I32; extern int TTYPE_I64; extern int TTYPE_DOUBLE; extern int TTYPE_STRING; extern int TTYPE_MAP; extern int TTYPE_SET; extern int TTYPE_LIST; extern int TTYPE_STRUCT; extern int TTYPE_UUID; extern ID validate_method_id; extern ID write_struct_begin_method_id; extern ID write_struct_end_method_id; extern ID write_field_begin_method_id; extern ID write_field_end_method_id; extern ID write_boolean_method_id; extern ID write_byte_method_id; extern ID write_i16_method_id; extern ID write_i32_method_id; extern ID write_i64_method_id; extern ID write_double_method_id; extern ID write_string_method_id; extern ID write_binary_method_id; extern ID write_map_begin_method_id; extern ID write_map_end_method_id; extern ID write_list_begin_method_id; extern ID write_list_end_method_id; extern ID write_set_begin_method_id; extern ID write_set_end_method_id; extern ID write_uuid_method_id; extern ID read_bool_method_id; extern ID read_byte_method_id; extern ID read_i16_method_id; extern ID read_i32_method_id; extern ID read_i64_method_id; extern ID read_string_method_id; extern ID read_binary_method_id; extern ID read_double_method_id; extern ID read_map_begin_method_id; extern ID read_map_end_method_id; extern ID read_list_begin_method_id; extern ID read_list_end_method_id; extern ID read_set_begin_method_id; extern ID read_set_end_method_id; extern ID read_uuid_method_id; extern ID read_struct_begin_method_id; extern ID read_struct_end_method_id; extern ID read_field_begin_method_id; extern ID read_field_end_method_id; extern ID keys_method_id; extern ID entries_method_id; extern ID write_field_stop_method_id; extern ID skip_method_id; extern ID write_method_id; extern ID read_all_method_id; extern ID read_into_buffer_method_id; extern ID force_binary_encoding_id; extern ID convert_to_utf8_byte_buffer_id; extern ID convert_to_string_id; extern ID fields_const_id; extern ID transport_ivar_id; extern ID strict_read_ivar_id; extern ID strict_write_ivar_id; extern VALUE type_sym; extern VALUE name_sym; extern VALUE key_sym; extern VALUE value_sym; extern VALUE element_sym; extern VALUE class_sym; extern VALUE binary_sym; extern VALUE rb_cSet; extern VALUE thrift_module; extern VALUE thrift_types_module; extern VALUE thrift_bytes_module; extern VALUE class_thrift_protocol; extern VALUE protocol_exception_class; // protocol errors extern int PROTOERR_UNKNOWN; extern int PROTOERR_INVALID_DATA; extern int PROTOERR_NEGATIVE_SIZE; extern int PROTOERR_SIZE_LIMIT; extern int PROTOERR_BAD_VERSION; extern int PROTOERR_NOT_IMPLEMENTED; extern int PROTOERR_DEPTH_LIMIT; thrift-0.23.0/lib/rb/ext/macros.h0000664000175000017500000000311615165535636017004 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #define GET_TRANSPORT(obj) rb_ivar_get(obj, transport_ivar_id) #define GET_STRICT_READ(obj) rb_ivar_get(obj, strict_read_ivar_id) #define GET_STRICT_WRITE(obj) rb_ivar_get(obj, strict_write_ivar_id) #define WRITE(obj, data, length) rb_funcall(obj, write_method_id, 1, rb_str_new(data, length)) #define CHECK_NIL(obj) if (NIL_P(obj)) { rb_raise(rb_eStandardError, "nil argument not allowed!");} #define READ(obj, length) rb_funcall(GET_TRANSPORT(obj), read_all_method_id, 1, INT2FIX(length)) #ifndef RFLOAT_VALUE # define RFLOAT_VALUE(v) RFLOAT(rb_Float(v))->value #endif #ifndef RSTRING_LEN # define RSTRING_LEN(v) RSTRING(rb_String(v))->len #endif #ifndef RSTRING_PTR # define RSTRING_PTR(v) RSTRING(rb_String(v))->ptr #endif #ifndef RARRAY_LEN # define RARRAY_LEN(v) RARRAY(rb_Array(v))->len #endif thrift-0.23.0/lib/rb/test/0000755000175000017500000000000015170007201015475 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/test/fuzz/0000755000175000017500000000000015170007202016474 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_json_protocol.rb0000664000175000017500000000151615167543515025126 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_json_protocol_harness.rb0000664000175000017500000000161215167543515025732 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_parser_fuzzer(Thrift::JsonProtocolFactory, read_message_begin: true)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_compact_protocol.rb0000664000175000017500000000151615167543515025603 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_compact_protocol.rb0000664000175000017500000000151615167543515024667 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb0000664000175000017500000000156515167543515027170 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_roundtrip_fuzzer(Thrift::BinaryProtocolFactory)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_compact_protocol_harness.rb0000664000175000017500000000156315167543515026414 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_parser_fuzzer(Thrift::CompactProtocolFactory)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb0000664000175000017500000000161515167543515026651 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_roundtrip_fuzzer(Thrift::JsonProtocolFactory, read_message_begin: true)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb0000664000175000017500000000157515167543515030571 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_parser_fuzzer(Thrift::BinaryProtocolAcceleratedFactory)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_binary_protocol_harness.rb0000664000175000017500000000156215167543515026251 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_parser_fuzzer(Thrift::BinaryProtocolFactory)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_common.rb0000664000175000017500000000646115167543515021422 0ustar00buildbuild00000000000000# # 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. # $:.unshift File.expand_path('../../lib', __dir__) $:.unshift File.expand_path('../../ext', __dir__) require 'thrift' $:.unshift File.dirname(__FILE__) + "/gen-rb" require 'fuzz_test_constants' require 'coverage' Coverage.start(branches: true) unless Coverage.respond_to?(:running?) && Coverage.running? require 'ruzzy' # Ruzzy.enable_branch_coverage_hooks def ignorable_fuzz_exception?(error) return true if error.is_a?(Thrift::ProtocolException) || error.is_a?(EOFError) || error.is_a?(Encoding::UndefinedConversionError) [ /don't know what (?:c)?type/, /Too many fields for union/, /too big to convert to '(?:int|long)'/, /bignum too big to convert into 'long'/, /negative array size/, /Union fields are not set/ ].any? { |pattern| error.message =~ pattern } end def read_fuzz_test(protocol, read_message_begin) protocol.read_message_begin if read_message_begin obj = Fuzz::FuzzTest.new obj.read(protocol) protocol.read_message_end if read_message_begin obj end def write_fuzz_test(protocol, obj, write_message_begin) if write_message_begin protocol.write_message_begin('fuzz', Thrift::MessageTypes::CALL, 0) end obj.write(protocol) protocol.write_message_end if write_message_begin end def create_parser_fuzzer(protocol_factory_class, read_message_begin: false) lambda do |data| transport = Thrift::MemoryBufferTransport.new(data) protocol = protocol_factory_class.new.get_protocol(transport) read_fuzz_test(protocol, read_message_begin) 0 rescue StandardError => e # We're looking for memory corruption, not Ruby exceptions raise unless ignorable_fuzz_exception?(e) end end def create_roundtrip_fuzzer(protocol_factory_class, read_message_begin: false) lambda do |data| transport = Thrift::MemoryBufferTransport.new(data) protocol = protocol_factory_class.new.get_protocol(transport) obj = read_fuzz_test(protocol, read_message_begin) serialized_data = +"" transport2 = Thrift::MemoryBufferTransport.new(serialized_data) protocol2 = protocol_factory_class.new.get_protocol(transport2) write_fuzz_test(protocol2, obj, read_message_begin) transport3 = Thrift::MemoryBufferTransport.new(serialized_data) protocol3 = protocol_factory_class.new.get_protocol(transport3) deserialized_obj = read_fuzz_test(protocol3, read_message_begin) raise "Roundtrip mismatch" unless obj == deserialized_obj 0 rescue StandardError => e # We're looking for memory corruption, not Ruby exceptions raise unless ignorable_fuzz_exception?(e) end end thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb0000664000175000017500000000160015167543515031472 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_roundtrip_fuzzer(Thrift::BinaryProtocolAcceleratedFactory)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_binary_protocol.rb0000664000175000017500000000151615167543515024525 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb0000664000175000017500000000151615167543515027755 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/README.md0000664000175000017500000001363215167543515020004 0ustar00buildbuild00000000000000# Ruby Fuzzing README The Ruby Thrift implementation uses [Ruzzy](https://github.com/trailofbits/ruzzy) for fuzzing. Ruzzy is a coverage-guided fuzzer for pure Ruby code and Ruby C extensions. We currently have several fuzz targets that test different aspects of the Thrift implementation: - `fuzz_parse_binary_protocol.rb` -- fuzzes deserialization of the Binary protocol - `fuzz_parse_binary_protocol_accelerated.rb` -- fuzzes deserialization of the accelerated Binary protocol - `fuzz_parse_compact_protocol.rb` -- fuzzes deserialization of the Compact protocol - `fuzz_parse_json_protocol.rb` -- fuzzes JSON protocol messages - `fuzz_roundtrip_binary_protocol.rb` -- fuzzes Binary roundtrips (deserialize, serialize, deserialize, compare) - `fuzz_roundtrip_binary_protocol_accelerated.rb` -- fuzzes accelerated Binary roundtrips - `fuzz_roundtrip_compact_protocol.rb` -- fuzzes Compact roundtrips - `fuzz_roundtrip_json_protocol.rb` -- fuzzes JSON message roundtrips The runnable files in this directory are tracer entrypoints. Ruzzy requires that pure Ruby fuzzing starts from a tracer script which then loads a separate harness, so do not invoke the matching `_harness.rb` files directly. The fuzzers use Ruzzy's mutation engine to generate test cases. Each target uses common testing code from `fuzz_common.rb`. For more information about Ruzzy and its options, see the [Ruzzy documentation](https://github.com/trailofbits/ruzzy). You can also use the corpus generator from the Rust implementation to generate initial Binary and Compact corpora that can be reused by the Ruby fuzzers, since those wire formats are identical between implementations. ## Setup Run these commands from the repository root: ```bash apt install -y clang-19 # from https://github.com/trailofbits/ruzzy?tab=readme-ov-file#installing MAKE="make --environment-overrides V=1" \ CC="/usr/bin/clang-19" \ CXX="/usr/bin/clang++-19" \ LDSHARED="/usr/bin/clang-19 -shared" \ LDSHAREDXX="/usr/bin/clang++-19 -shared" \ gem install ruzzy # Validate the fuzz directory. # This generates test/fuzz/gen-rb, syntax-checks the fuzz scripts, # and verifies that Fuzz::FuzzTest loads correctly. make -C lib/rb/test/fuzz check ``` `make -C lib/rb check` now recurses into `lib/rb/test/fuzz`, so the same validation also runs as part of the normal Ruby `make check` flow. ## Running Fuzzers The Makefile in this directory hides the `LD_PRELOAD` and `ASAN_OPTIONS` setup needed by Ruzzy. Pure Ruby targets only need `fuzz-prepare`, which is the same work as `check`: ```bash make -C lib/rb/test/fuzz fuzz-parse-binary make -C lib/rb/test/fuzz fuzz-roundtrip-compact make -C lib/rb/test/fuzz fuzz-parse-json ``` Accelerated targets rebuild `thrift_native` with sanitizer flags first: ```bash make -C lib/rb/test/fuzz fuzz-parse-binary-accelerated make -C lib/rb/test/fuzz fuzz-roundtrip-binary-accelerated ``` Use `CORPUS=...` to point at an input corpus. The path is resolved from `lib/rb`, which matches the old manual commands: ```bash make -C lib/rb/test/fuzz fuzz-parse-binary \ CORPUS=../rs/test/fuzz/corpus/binary make -C lib/rb/test/fuzz fuzz-parse-compact \ CORPUS=../rs/test/fuzz/corpus/compact ``` Use `FUZZ_ARGS=...` for extra libFuzzer-style arguments. For a short local run, the Makefile also provides bounded smoke targets: ```bash make -C lib/rb/test/fuzz fuzz-smoke-parse-binary make -C lib/rb/test/fuzz fuzz-smoke-parse-binary-accelerated \ FUZZ_CC=/usr/bin/clang-19 \ FUZZ_CXX=/usr/bin/clang++-19 ``` If the default `clang` and `clang++` names are not correct for your system, override these variables for accelerated targets: ```bash make -C lib/rb/test/fuzz fuzz-build-ext \ FUZZ_CC=/usr/bin/clang-19 \ FUZZ_CXX=/usr/bin/clang++-19 ``` The underlying manual command from `lib/rb` is still: ```bash # Memory allocation failures are common and low impact (DoS), so skip them for now. # Like Python, the Ruby interpreter leaks data, so ignore these for now. # Ruby recommends disabling sigaltstack. export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0" LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \ ruby test/fuzz/fuzz_parse_binary_protocol.rb ``` ## Rust Corpus Generator We can use the Rust corpus generator to prepare corpora for the Binary and Compact protocol targets. Run it from the repository root: ```bash cargo run --manifest-path lib/rs/test/fuzz/Cargo.toml --bin corpus_generator -- \ --output-dir \ --protocol \ --generate \ --buffer-size \ --random-size ``` Reasonable values (determined empirically): ```bash cargo run --manifest-path lib/rs/test/fuzz/Cargo.toml --bin corpus_generator -- \ --output-dir ./lib/rs/test/fuzz/corpus/binary \ --protocol binary \ --generate 1000 \ --buffer-size 65536 \ --random-size 16384 cargo run --manifest-path lib/rs/test/fuzz/Cargo.toml --bin corpus_generator -- \ --output-dir ./lib/rs/test/fuzz/corpus/compact \ --protocol compact \ --generate 1000 \ --buffer-size 16384 \ --random-size 16384 ``` Then run a matching Ruby target: ```bash make -C lib/rb/test/fuzz fuzz-parse-binary \ CORPUS=../rs/test/fuzz/corpus/binary ``` The Rust corpus generator does not emit JSON protocol inputs, so use it only with the Binary and Compact Ruby targets. ## Troubleshooting If libFuzzer prints `WARNING: no interesting inputs were found so far. Is the code instrumented for coverage?` and quickly shrinks the seed corpus to `corp: 1/1b`, coverage tracing is not active. That usually means the tracer script was bypassed or `ruzzy` was not installed with the expected sanitizer-enabled toolchain. Run the `.rb` files in this directory, not the `_harness.rb` files. If an accelerated target starts using the pure Ruby implementation, rebuild the extension with `make -C lib/rb/test/fuzz fuzz-build-ext ...` and then rerun the accelerated target. thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_json_protocol.rb0000664000175000017500000000151615167543515024212 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/fuzz_tracer.rb0000664000175000017500000000174215167543515021407 0ustar00buildbuild00000000000000# # 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. # require 'ruzzy' def trace_fuzz_target(script_path) harness_path = File.expand_path( "#{File.basename(script_path, '.rb')}_harness.rb", File.dirname(script_path) ) Ruzzy.trace(harness_path) end thrift-0.23.0/lib/rb/test/fuzz/Makefile.in0000644000175000017500000005611415170007167020562 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rb/test/fuzz ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ FUZZ_RB_ROOT = $(top_srcdir)/lib/rb FUZZ_GEN_DIR = $(FUZZ_RB_ROOT)/test/fuzz FUZZ_STUBS = \ $(FUZZ_GEN_DIR)/gen-rb/fuzz_test_constants.rb \ $(FUZZ_GEN_DIR)/gen-rb/fuzz_test_types.rb FUZZ_RUBY_FILES = \ $(srcdir)/fuzz_tracer.rb \ $(srcdir)/fuzz_common.rb \ $(srcdir)/fuzz_parse_binary_protocol.rb \ $(srcdir)/fuzz_parse_binary_protocol_harness.rb \ $(srcdir)/fuzz_parse_binary_protocol_accelerated.rb \ $(srcdir)/fuzz_parse_binary_protocol_accelerated_harness.rb \ $(srcdir)/fuzz_parse_compact_protocol.rb \ $(srcdir)/fuzz_parse_compact_protocol_harness.rb \ $(srcdir)/fuzz_parse_json_protocol.rb \ $(srcdir)/fuzz_parse_json_protocol_harness.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol_harness.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol_accelerated.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol_accelerated_harness.rb \ $(srcdir)/fuzz_roundtrip_compact_protocol.rb \ $(srcdir)/fuzz_roundtrip_compact_protocol_harness.rb \ $(srcdir)/fuzz_roundtrip_json_protocol.rb \ $(srcdir)/fuzz_roundtrip_json_protocol_harness.rb EXTRA_DIST = \ .gitignore \ README.md \ fuzz_common.rb \ fuzz_tracer.rb \ fuzz_parse_binary_protocol.rb \ fuzz_parse_binary_protocol_harness.rb \ fuzz_parse_binary_protocol_accelerated.rb \ fuzz_parse_binary_protocol_accelerated_harness.rb \ fuzz_parse_compact_protocol.rb \ fuzz_parse_compact_protocol_harness.rb \ fuzz_parse_json_protocol.rb \ fuzz_parse_json_protocol_harness.rb \ fuzz_roundtrip_binary_protocol.rb \ fuzz_roundtrip_binary_protocol_harness.rb \ fuzz_roundtrip_binary_protocol_accelerated.rb \ fuzz_roundtrip_binary_protocol_accelerated_harness.rb \ fuzz_roundtrip_compact_protocol.rb \ fuzz_roundtrip_compact_protocol_harness.rb \ fuzz_roundtrip_json_protocol.rb \ fuzz_roundtrip_json_protocol_harness.rb all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rb/test/fuzz/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rb/test/fuzz/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile FUZZ_ASAN_OPTIONS ?= allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0 FUZZ_CC ?= clang FUZZ_CXX ?= clang++ FUZZ_LDSHARED ?= $(FUZZ_CC) -shared FUZZ_LDSHAREDXX ?= $(FUZZ_CXX) -shared FUZZ_CFLAGS ?= -fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g FUZZ_CXXFLAGS ?= -fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g FUZZ_MAKE ?= make FUZZ_MAKEFLAGS ?= --environment-overrides V=1 check: fuzz-prepare fuzz-prepare: $(FUZZ_STUBS) @for script in $(FUZZ_RUBY_FILES); do \ $(RUBY) -c $$script; \ done cd $(FUZZ_RB_ROOT) && \ RUBYLIB="lib:test/fuzz/gen-rb" $(RUBY) -e 'require "thrift"; require "fuzz_test_types"; abort("Fuzz::FuzzTest is missing") unless defined?(Fuzz::FuzzTest)' $(THRIFT): $(MAKE) -C $(top_builddir)/compiler/cpp all $(FUZZ_STUBS): $(top_srcdir)/test/FuzzTest.thrift $(THRIFT) $(MKDIR_P) $(FUZZ_GEN_DIR) $(THRIFT) --gen rb -o $(FUZZ_GEN_DIR) $(top_srcdir)/test/FuzzTest.thrift fuzz-build-ext: cd $(FUZZ_RB_ROOT)/ext && \ env MAKE="$(FUZZ_MAKE) $(FUZZ_MAKEFLAGS)" \ CC="$(FUZZ_CC)" \ CXX="$(FUZZ_CXX)" \ LDSHARED="$(FUZZ_LDSHARED)" \ LDSHAREDXX="$(FUZZ_LDSHAREDXX)" \ CFLAGS="$(FUZZ_CFLAGS)" \ CXXFLAGS="$(FUZZ_CXXFLAGS)" \ $(RUBY) extconf.rb && \ env MAKE="$(FUZZ_MAKE) $(FUZZ_MAKEFLAGS)" \ CC="$(FUZZ_CC)" \ CXX="$(FUZZ_CXX)" \ LDSHARED="$(FUZZ_LDSHARED)" \ LDSHAREDXX="$(FUZZ_LDSHAREDXX)" \ CFLAGS="$(FUZZ_CFLAGS)" \ CXXFLAGS="$(FUZZ_CXXFLAGS)" \ $(FUZZ_MAKE) $(FUZZ_MAKEFLAGS) clean all fuzz-run: fuzz-prepare @test -n "$(TARGET)" || { echo 'Set TARGET='; exit 1; } cd $(FUZZ_RB_ROOT) && \ ASAN_OPTIONS="$(FUZZ_ASAN_OPTIONS)" \ LD_PRELOAD=$$($(RUBY) -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \ $(RUBY) test/fuzz/$(TARGET) $(CORPUS) $(FUZZ_ARGS) fuzz-parse-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_binary_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-parse-binary-accelerated: fuzz-build-ext $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_binary_protocol_accelerated.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-parse-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_compact_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-parse-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_json_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_binary_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-binary-accelerated: fuzz-build-ext $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_binary_protocol_accelerated.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_compact_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_json_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-smoke-parse-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-binary CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-parse-binary-accelerated: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-binary-accelerated CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-parse-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-compact CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-parse-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-json CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-binary CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-binary-accelerated: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-binary-accelerated CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-compact CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-json CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" clean-local: -$(RM) -r $(FUZZ_GEN_DIR)/gen-rb distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb0000664000175000017500000000156615167543515027333 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_common' Ruzzy.fuzz(create_roundtrip_fuzzer(Thrift::CompactProtocolFactory)) thrift-0.23.0/lib/rb/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb0000664000175000017500000000151615167543515027041 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/fuzz_roundtrip_binary_protocol.rb0000664000175000017500000000151615167543515025441 0ustar00buildbuild00000000000000# # 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. # require_relative 'fuzz_tracer' trace_fuzz_target(__FILE__) thrift-0.23.0/lib/rb/test/fuzz/Makefile.am0000664000175000017500000001525315167543515020562 0ustar00buildbuild00000000000000# # 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. # THRIFT = $(top_builddir)/compiler/cpp/thrift FUZZ_RB_ROOT = $(top_srcdir)/lib/rb FUZZ_GEN_DIR = $(FUZZ_RB_ROOT)/test/fuzz FUZZ_STUBS = \ $(FUZZ_GEN_DIR)/gen-rb/fuzz_test_constants.rb \ $(FUZZ_GEN_DIR)/gen-rb/fuzz_test_types.rb FUZZ_RUBY_FILES = \ $(srcdir)/fuzz_tracer.rb \ $(srcdir)/fuzz_common.rb \ $(srcdir)/fuzz_parse_binary_protocol.rb \ $(srcdir)/fuzz_parse_binary_protocol_harness.rb \ $(srcdir)/fuzz_parse_binary_protocol_accelerated.rb \ $(srcdir)/fuzz_parse_binary_protocol_accelerated_harness.rb \ $(srcdir)/fuzz_parse_compact_protocol.rb \ $(srcdir)/fuzz_parse_compact_protocol_harness.rb \ $(srcdir)/fuzz_parse_json_protocol.rb \ $(srcdir)/fuzz_parse_json_protocol_harness.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol_harness.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol_accelerated.rb \ $(srcdir)/fuzz_roundtrip_binary_protocol_accelerated_harness.rb \ $(srcdir)/fuzz_roundtrip_compact_protocol.rb \ $(srcdir)/fuzz_roundtrip_compact_protocol_harness.rb \ $(srcdir)/fuzz_roundtrip_json_protocol.rb \ $(srcdir)/fuzz_roundtrip_json_protocol_harness.rb FUZZ_ASAN_OPTIONS ?= allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0 FUZZ_CC ?= clang FUZZ_CXX ?= clang++ FUZZ_LDSHARED ?= $(FUZZ_CC) -shared FUZZ_LDSHAREDXX ?= $(FUZZ_CXX) -shared FUZZ_CFLAGS ?= -fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g FUZZ_CXXFLAGS ?= -fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g FUZZ_MAKE ?= make FUZZ_MAKEFLAGS ?= --environment-overrides V=1 check: fuzz-prepare fuzz-prepare: $(FUZZ_STUBS) @for script in $(FUZZ_RUBY_FILES); do \ $(RUBY) -c $$script; \ done cd $(FUZZ_RB_ROOT) && \ RUBYLIB="lib:test/fuzz/gen-rb" $(RUBY) -e 'require "thrift"; require "fuzz_test_types"; abort("Fuzz::FuzzTest is missing") unless defined?(Fuzz::FuzzTest)' $(THRIFT): $(MAKE) -C $(top_builddir)/compiler/cpp all $(FUZZ_STUBS): $(top_srcdir)/test/FuzzTest.thrift $(THRIFT) $(MKDIR_P) $(FUZZ_GEN_DIR) $(THRIFT) --gen rb -o $(FUZZ_GEN_DIR) $(top_srcdir)/test/FuzzTest.thrift fuzz-build-ext: cd $(FUZZ_RB_ROOT)/ext && \ env MAKE="$(FUZZ_MAKE) $(FUZZ_MAKEFLAGS)" \ CC="$(FUZZ_CC)" \ CXX="$(FUZZ_CXX)" \ LDSHARED="$(FUZZ_LDSHARED)" \ LDSHAREDXX="$(FUZZ_LDSHAREDXX)" \ CFLAGS="$(FUZZ_CFLAGS)" \ CXXFLAGS="$(FUZZ_CXXFLAGS)" \ $(RUBY) extconf.rb && \ env MAKE="$(FUZZ_MAKE) $(FUZZ_MAKEFLAGS)" \ CC="$(FUZZ_CC)" \ CXX="$(FUZZ_CXX)" \ LDSHARED="$(FUZZ_LDSHARED)" \ LDSHAREDXX="$(FUZZ_LDSHAREDXX)" \ CFLAGS="$(FUZZ_CFLAGS)" \ CXXFLAGS="$(FUZZ_CXXFLAGS)" \ $(FUZZ_MAKE) $(FUZZ_MAKEFLAGS) clean all fuzz-run: fuzz-prepare @test -n "$(TARGET)" || { echo 'Set TARGET='; exit 1; } cd $(FUZZ_RB_ROOT) && \ ASAN_OPTIONS="$(FUZZ_ASAN_OPTIONS)" \ LD_PRELOAD=$$($(RUBY) -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \ $(RUBY) test/fuzz/$(TARGET) $(CORPUS) $(FUZZ_ARGS) fuzz-parse-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_binary_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-parse-binary-accelerated: fuzz-build-ext $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_binary_protocol_accelerated.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-parse-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_compact_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-parse-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_parse_json_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_binary_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-binary-accelerated: fuzz-build-ext $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_binary_protocol_accelerated.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_compact_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-roundtrip-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-run TARGET=fuzz_roundtrip_json_protocol.rb CORPUS="$(CORPUS)" FUZZ_ARGS="$(FUZZ_ARGS)" fuzz-smoke-parse-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-binary CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-parse-binary-accelerated: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-binary-accelerated CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-parse-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-compact CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-parse-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-parse-json CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-binary: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-binary CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-binary-accelerated: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-binary-accelerated CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-compact: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-compact CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" fuzz-smoke-roundtrip-json: $(MAKE) $(AM_MAKEFLAGS) fuzz-roundtrip-json CORPUS="$(CORPUS)" FUZZ_ARGS="-runs=100 $(FUZZ_ARGS)" clean-local: -$(RM) -r $(FUZZ_GEN_DIR)/gen-rb distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ .gitignore \ README.md \ fuzz_common.rb \ fuzz_tracer.rb \ fuzz_parse_binary_protocol.rb \ fuzz_parse_binary_protocol_harness.rb \ fuzz_parse_binary_protocol_accelerated.rb \ fuzz_parse_binary_protocol_accelerated_harness.rb \ fuzz_parse_compact_protocol.rb \ fuzz_parse_compact_protocol_harness.rb \ fuzz_parse_json_protocol.rb \ fuzz_parse_json_protocol_harness.rb \ fuzz_roundtrip_binary_protocol.rb \ fuzz_roundtrip_binary_protocol_harness.rb \ fuzz_roundtrip_binary_protocol_accelerated.rb \ fuzz_roundtrip_binary_protocol_accelerated_harness.rb \ fuzz_roundtrip_compact_protocol.rb \ fuzz_roundtrip_compact_protocol_harness.rb \ fuzz_roundtrip_json_protocol.rb \ fuzz_roundtrip_json_protocol_harness.rb thrift-0.23.0/lib/rb/coding_standards.md0000664000175000017500000000033415167543515020373 0ustar00buildbuild00000000000000## Ruby Coding Standards Please follow: * [Thrift General Coding Standards](/doc/coding_standards.md) * Code Style for Ruby code enforced by RuboCop To check you code for compliance, run: bundle exec rake rubocop thrift-0.23.0/lib/rb/script/0000775000175000017500000000000015167543515016047 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/script/write_struct.rb0000664000175000017500000000177315167543515021142 0ustar00buildbuild00000000000000# # 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. # require "spec/spec_helper" path, factory_class = ARGV factory = eval(factory_class).new ser = Thrift::Serializer.new(factory) File.open(path, "w") do |file| file.write(ser.serialize(Fixtures::COMPACT_PROTOCOL_TEST_STRUCT)) end thrift-0.23.0/lib/rb/script/proto_benchmark.rb0000664000175000017500000000710415167543515021553 0ustar00buildbuild00000000000000# # 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. # require File.dirname(__FILE__) + "/../spec/spec_helper.rb" require "benchmark" # require "ruby-prof" obj = Fixtures::COMPACT_PROTOCOL_TEST_STRUCT HOW_MANY = 1_000 binser = Thrift::Serializer.new bin_data = binser.serialize(obj) bindeser = Thrift::Deserializer.new accel_bin_ser = Thrift::Serializer.new(Thrift::BinaryProtocolAcceleratedFactory.new) accel_bin_deser = Thrift::Deserializer.new(Thrift::BinaryProtocolAcceleratedFactory.new) compact_ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new) compact_data = compact_ser.serialize(obj) compact_deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new) Benchmark.bm(60) do |reporter| reporter.report("binary protocol, write") do HOW_MANY.times do binser.serialize(obj) end end reporter.report("accelerated binary protocol, write") do HOW_MANY.times do accel_bin_ser.serialize(obj) end end reporter.report("compact protocol, write") do # RubyProf.start HOW_MANY.times do compact_ser.serialize(obj) end # result = RubyProf.stop # printer = RubyProf::GraphHtmlPrinter.new(result) # file = File.open("profile.html", "w+") # printer.print(file, 0) # file.close end reporter.report("binary protocol, read") do HOW_MANY.times do bindeser.deserialize(obj, bin_data) end end reporter.report("accelerated binary protocol, read") do HOW_MANY.times do accel_bin_deser.deserialize(obj, bin_data) end end reporter.report("compact protocol, read") do HOW_MANY.times do compact_deser.deserialize(obj, compact_data) end end # f = File.new("/tmp/testfile", "w") # proto = Thrift::BinaryProtocolAccelerated.new(Thrift::IOStreamTransport.new(Thrift::MemoryBufferTransport.new, f)) # reporter.report("accelerated binary protocol, write (to disk)") do # HOW_MANY.times do # obj.write(proto) # end # f.flush # end # f.close # # f = File.new("/tmp/testfile", "r") # proto = Thrift::BinaryProtocolAccelerated.new(Thrift::IOStreamTransport.new(f, Thrift::MemoryBufferTransport.new)) # reporter.report("accelerated binary protocol, read (from disk)") do # HOW_MANY.times do # obj.read(proto) # end # end # f.close # # f = File.new("/tmp/testfile", "w") # reporter.report("compact protocol, write (to disk)") do # proto = Thrift::CompactProtocol.new(Thrift::IOStreamTransport.new(Thrift::MemoryBufferTransport.new, f)) # HOW_MANY.times do # obj.write(proto) # end # f.flush # end # f.close # # f = File.new("/tmp/testfile", "r") # reporter.report("compact protocol, read (from disk)") do # proto = Thrift::CompactProtocol.new(Thrift::IOStreamTransport.new(f, Thrift::MemoryBufferTransport.new)) # HOW_MANY.times do # obj.read(proto) # end # end # f.close end thrift-0.23.0/lib/rb/script/read_struct.rb0000664000175000017500000000256115167543515020717 0ustar00buildbuild00000000000000# # 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. # require "spec/spec_helper" path, factory_class = ARGV factory = eval(factory_class).new deser = Thrift::Deserializer.new(factory) cpts = CompactProtoTestStruct.new CompactProtoTestStruct.constants.each do |const| cpts.instance_variable_set("@#{const}", nil) end data = File.read(path) deser.deserialize(cpts, data) if cpts == Fixtures::COMPACT_PROTOCOL_TEST_STRUCT puts "Object verified successfully!" else puts "Object failed verification! Expected #{Fixtures::COMPACT_PROTOCOL_TEST_STRUCT.inspect} but got #{cpts.inspect}" puts cpts.differences(Fixtures::COMPACT_PROTOCOL_TEST_STRUCT) end thrift-0.23.0/lib/rb/Gemfile0000664000175000017500000000022515170007142016016 0ustar00buildbuild00000000000000source "https://rubygems.org" gemspec # Only required for tests with Rack 2.x on Ruby 4.0+ gem 'cgi' gem 'ostruct' eval_gemfile "Gemfile.linters" thrift-0.23.0/lib/rb/README.md0000664000175000017500000002040615167543515016024 0ustar00buildbuild00000000000000# Thrift Ruby Software Library ## License Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. # Using Thrift with Ruby Ruby bindings for the Apache Thrift RPC system. The gem contains the runtime types, transports, protocols, and servers used by generated Ruby code for both clients and services. ## Compatibility - Ruby MRI >= 2.7 (tested against current supported releases). - JRuby works with the pure-Ruby implementation; the native extension is skipped automatically. - For the repo-wide transport, protocol, and server support matrix, see [Language Feature Matrix](https://github.com/apache/thrift/blob/master/LANGUAGES.md). This README focuses on Ruby-specific behavior and migration notes. ## Installation - Requirements: Ruby >= 2.7. - From RubyGems: `gem install thrift` - From source: `bundle install`, `gem build thrift.gemspec`, then install the resulting `thrift-*.gem`. The native accelerator is built when the gem is installed on supported runtimes. ## Generating Ruby Code The Ruby library does not include the Thrift compiler. Use a compiler built from the root of this repository to generate Ruby bindings: thrift --gen rb path/to/service.thrift # with namespaced modules thrift --gen rb:namespaced --recurse path/to/service.thrift Generated files are typically written to `gen-rb/` and can be required directly from your application. ## Basic Client Usage $:.push File.expand_path('gen-rb', __dir__) require 'thrift' require 'calculator' socket = Thrift::Socket.new('localhost', 9090) transport = Thrift::BufferedTransport.new(socket) protocol = Thrift::BinaryProtocol.new(transport) client = Calculator::Client.new(protocol) transport.open puts client.add(1, 1) transport.close ## Basic Server Usage $:.push File.expand_path('gen-rb', __dir__) require 'thrift' require 'calculator' class CalculatorHandler def add(a, b) a + b end end handler = CalculatorHandler.new processor = Calculator::Processor.new(handler) server_transport = Thrift::ServerSocket.new(9090) transport_factory = Thrift::BufferedTransportFactory.new protocol_factory = Thrift::BinaryProtocolFactory.new server = Thrift::ThreadedServer.new(processor, server_transport, transport_factory, protocol_factory) server.serve ## Development and Tests - `bundle exec rake spec` runs the Ruby specs. It expects a built Thrift compiler at `../../compiler/cpp/thrift`. - `bundle exec rake test` runs the cross-language test suite; it must be executed from a full Thrift checkout. - `bundle exec rake build_ext` (implicit in the tasks above) compiles the optional native extension that accelerates protocols and buffers. ## More Ruby Code - Tutorial client and server: `tutorial/rb/RubyClient.rb` and `tutorial/rb/RubyServer.rb` - Runtime benchmarks: `lib/rb/benchmark` - Protocol benchmark: `test/rb/benchmarks/protocol_benchmark.rb` - Library specs: `lib/rb/spec` - Fuzzing harnesses and notes: `lib/rb/test/fuzz` - Cross-language and integration tests: `test/rb` ## Breaking Changes ### 0.23.0 The documented source-build flow now effectively requires Ruby `2.7+`. The committed development bundle no longer resolves on Ruby `2.6` (`json-2.18.1 requires ruby version >= 2.7`), so building and testing this library from source should be treated as `2.7+`. Generated structs and unions now consistently raise `Thrift::ProtocolException::INVALID_DATA` for invalid payloads such as unset required fields, invalid enum values, or invalid union state. If your application or tests matched older exception types or messages, update them. Regenerated Ruby clients now validate replies more strictly. Mismatched reply message types, method names, or sequence IDs raise `Thrift::ApplicationException::INVALID_MESSAGE_TYPE`, `Thrift::ApplicationException::WRONG_METHOD_NAME`, or `Thrift::ApplicationException::BAD_SEQUENCE_ID`. If you relied on older, looser reply handling in servers, proxies, or tests, regenerate and update those call paths together. Generated Ruby clients have never been safe to share across concurrent threads. A client tracks pending sequence IDs on a single reply stream, so use one client/transport pair per thread or serialize access yourself. Treat `Thrift::ApplicationException::BAD_SEQUENCE_ID` as a correctness bug that needs immediate attention. It means the client read a reply whose sequence ID did not match the next pending request, so the connection may already be out of sync and you may be reading a reply intended for a different call. The most common cause is sharing one client across threads, but a buggy proxy or server can also cause it. ### 0.13.0 Ruby development and CI moved to Ruby `2.4+`, but the runtime still claimed support for older interpreters. Treat Ruby `< 2.4` on the `0.13.x` line as best-effort, not guaranteed. - Historical note for very old releases: the Ruby runtime was rearranged to use more Ruby-like names, and generated files switched to underscored filenames. If you are upgrading very old code, regenerate your Ruby bindings and update any old `T*` constants or legacy require paths such as `TBinaryProtocol` -> `Thrift::BinaryProtocol`. - `rb:namespaced` changes the generated file layout. Flat output from `thrift --gen rb` and namespaced output from `thrift --gen rb:namespaced` use different require paths, so switch them atomically with regenerated code. # --gen rb require 'calculator' # --gen rb:namespaced require 'my_namespace/calculator' ## Migration Notes - If you upgrade across the stricter reply-validation changes, regenerate all Ruby stubs and deploy them with the matching Ruby runtime. Do not mix old generated code, new generated code, and new runtime code on the same client path without testing that combination. - If you receive `Thrift::ApplicationException::BAD_SEQUENCE_ID`, treat the connection as out of sync. Close it, create a new client/transport pair, and investigate the root cause before retrying. - Do not share one generated Ruby client across concurrent threads. Use one client/transport pair per thread, or serialize access to a shared client. - If you switch between `thrift --gen rb` and `thrift --gen rb:namespaced`, regenerate all Ruby output and update `require` paths in the same change. ## Runtime Notes - Loading the `thrift_native` extension changes which implementation you are running. It replaces `Thrift::Struct`, `Thrift::Union`, and `Thrift::CompactProtocol` methods with C implementations in place. `Thrift::BinaryProtocol` remains available in pure Ruby, and the C-backed binary protocol is opt-in through `Thrift::BinaryProtocolAcceleratedFactory` or `Thrift::BinaryProtocolAccelerated` when that class is available. - The native extension is optional. If it cannot be built or loaded, Thrift falls back to the pure-Ruby implementation. This mainly changes performance and implementation details. - JRuby skips the native extension automatically and uses the pure-Ruby path. - Do not share one client instance across concurrent threads. A client tracks request and reply state on a single transport stream. - `Thrift::NonblockingServer` expects framed input. Use `Thrift::FramedTransport` with it on the wire. - Client and server must agree on transport and protocol choices. If you switch to SSL, HTTP, header transport, compact protocol, or namespaced generated code, update both ends together. - HTTPS client transport verifies peers by default, and `Thrift::SSLSocket` performs a hostname check against the host you pass in. thrift-0.23.0/lib/rb/Rakefile0000664000175000017500000001071715170007142016177 0ustar00buildbuild00000000000000# # 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. # require 'rubygems' require 'rake' require 'rake/clean' require 'rspec/core/rake_task' THRIFT = '../../compiler/cpp/thrift' task :default => [:gem] task :spec => [:'gen-rb', :build_ext, :realspec] RSpec::Core::RakeTask.new(:realspec) do |t| t.rspec_opts = ['--color', '--format d'] end RSpec::Core::RakeTask.new(:'spec:rcov') do |t| t.rspec_opts = ['--color', '--format d'] t.rcov = true t.rcov_opts = ['--exclude', '^spec,/gems/'] end desc 'Compile the .thrift files for the specs' task :'gen-rb' => [:'gen-rb:spec', :'gen-rb:namespaced_spec', :'gen-rb:flat_spec', :'gen-rb:benchmark', :'gen-rb:debug_proto', :'gen-rb:constants_demo', :'gen-rb:fuzz'] namespace :'gen-rb' do task :'spec' do dir = File.dirname(__FILE__) + '/spec' sh THRIFT, '--gen', 'rb', '-o', dir, "#{dir}/ThriftSpec.thrift" end task :'namespaced_spec' do dir = File.dirname(__FILE__) + '/spec' sh THRIFT, '--gen', 'rb:namespaced', '--recurse', '-o', dir, "#{dir}/ThriftNamespacedSpec.thrift" sh THRIFT, '--gen', 'rb:namespaced', '--recurse', '-o', dir, "#{dir}/BaseService.thrift" sh THRIFT, '--gen', 'rb:namespaced', '--recurse', '-o', dir, "#{dir}/ExtendedService.thrift" end task :'flat_spec' do dir = File.dirname(__FILE__) + '/spec' FileUtils.mkdir_p("#{dir}/gen-rb/flat") sh THRIFT, '--gen', 'rb', '--recurse', '-out', "#{dir}/gen-rb/flat", "#{dir}/ThriftNamespacedSpec.thrift" end task :'benchmark' do dir = File.dirname(__FILE__) + '/benchmark' sh THRIFT, '--gen', 'rb', '-o', dir, "#{dir}/Benchmark.thrift" end task :'debug_proto' do sh "mkdir", "-p", "test/debug_proto" sh THRIFT, '--gen', 'rb', "-o", "test/debug_proto", "../../test/DebugProtoTest.thrift" end task :'constants_demo' do dir = File.dirname(__FILE__) + '/spec' sh THRIFT, '--gen', 'rb:namespaced', '--recurse', '-o', dir, "../../test/ConstantsDemo.thrift" end task :'fuzz' do dir = File.dirname(__FILE__) + '/test/fuzz' sh "mkdir", "-p", dir sh THRIFT, '--gen', 'rb', '-o', dir, "../../test/FuzzTest.thrift" end end desc "Build the native library" task :build_ext => :'gen-rb' do next if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ next if ENV['SKIP_BUILD_EXT'] == '1' Dir::chdir(File::dirname('ext/extconf.rb')) do unless sh "ruby #{File::basename('ext/extconf.rb')}" $stderr.puts "Failed to run extconf" break end unless sh "make" $stderr.puts "make failed" break end end end desc 'Run the compiler tests (requires full thrift checkout)' task :test do # ensure this is a full thrift checkout and not a tarball of the ruby libs cmd = 'head -1 ../../README.md 2>/dev/null | grep Thrift >/dev/null 2>/dev/null' system(cmd) or fail "rake test requires a full thrift checkout" sh 'make', '-C', File.dirname(__FILE__) + "/../../test/rb", "check" end desc 'Run benchmarking of NonblockingServer' task :benchmark do ruby 'benchmark/benchmark.rb' end begin require "rubocop/rake_task" RuboCop::RakeTask.new rescue LoadError task(:rubocop) { abort "Install the rubocop gem to run a static analysis" } end desc 'Builds the thrift gem' task :gem => [:spec, :build_ext] do unless sh 'gem', 'build', 'thrift.gemspec' $stderr.puts "Failed to build thrift gem" break end end desc 'Install the thrift gem' task :install => [:gem] do unless sh 'gem', 'install', Dir.glob('thrift-*.gem').last $stderr.puts "Failed to install thrift gem" break end end CLEAN.include [ '.bundle', 'benchmark/gen-rb', 'coverage', 'ext/*.{o,bundle,so,dll}', 'ext/mkmf.log', 'ext/Makefile', 'ext/conftest.dSYM', 'ext/thrift_native.bundle.dSYM', 'mkmf.log', 'pkg', 'spec/gen-rb', 'test/debug_proto/gen-rb', 'thrift-*.gem' ] thrift-0.23.0/lib/rb/spec/0000775000175000017500000000000015170007142015456 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/spec/Referenced.thrift0000664000175000017500000000316215165535636020766 0ustar00buildbuild00000000000000/* * 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. */ # # 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 rb OtherNamespace enum SomeEnum { ONE TWO } thrift-0.23.0/lib/rb/spec/header_protocol_spec.rb0000664000175000017500000004205715167543515022215 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require_relative 'support/header_protocol_helper' describe 'HeaderProtocol' do include HeaderProtocolHelper describe Thrift::HeaderProtocol do before(:each) do @buffer = Thrift::MemoryBufferTransport.new @protocol = Thrift::HeaderProtocol.new(@buffer) end it "should provide a to_s" do expect(@protocol.to_s).to match(/header\(compact/) end it "should wrap transport in HeaderTransport" do expect(@protocol.trans).to be_a(Thrift::HeaderTransport) end it "should use existing HeaderTransport if passed" do header_trans = Thrift::HeaderTransport.new(@buffer) protocol = Thrift::HeaderProtocol.new(header_trans) expect(protocol.trans).to equal(header_trans) end describe "header management delegation" do it "should delegate get_headers" do # Write with headers and read back to populate read headers @protocol.set_header("key", "value") @protocol.write_message_begin("test", Thrift::MessageTypes::CALL, 1) @protocol.write_struct_begin("args") @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush # Read back data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) read_protocol.read_message_begin headers = read_protocol.get_headers expect(headers["key"]).to eq("value") end it "should delegate set_header" do expect(@protocol.trans).to receive(:set_header).with("key", "value") @protocol.set_header("key", "value") end it "should delegate clear_headers" do expect(@protocol.trans).to receive(:clear_headers) @protocol.clear_headers end it "should delegate add_transform" do expect(@protocol.trans).to receive(:add_transform).with(Thrift::HeaderTransformID::ZLIB) @protocol.add_transform(Thrift::HeaderTransformID::ZLIB) end end describe "protocol delegation with Binary protocol" do before(:each) do @buffer = Thrift::MemoryBufferTransport.new @protocol = Thrift::HeaderProtocol.new(@buffer, nil, Thrift::HeaderSubprotocolID::BINARY) end it "should write message begin" do @protocol.write_message_begin("test_method", Thrift::MessageTypes::CALL, 123) @protocol.write_message_end @protocol.trans.flush # Verify we can read it back data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) name, type, seqid = read_protocol.read_message_begin expect(name).to eq("test_method") expect(type).to eq(Thrift::MessageTypes::CALL) expect(seqid).to eq(123) end it "should propagate seqid to the outer header frame" do @protocol.write_message_begin("test_method", Thrift::MessageTypes::CALL, 123) @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) expect(data[8, 4].unpack('N').first).to eq(123) end it "should write and read structs" do @protocol.write_message_begin("test", Thrift::MessageTypes::CALL, 1) @protocol.write_struct_begin("TestStruct") @protocol.write_field_begin("field1", Thrift::Types::I32, 1) @protocol.write_i32(42) @protocol.write_field_end @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) read_protocol.read_message_begin read_protocol.read_struct_begin name, type, id = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::I32) expect(id).to eq(1) value = read_protocol.read_i32 expect(value).to eq(42) end it "should write and read all primitive types" do @protocol.write_message_begin("test", Thrift::MessageTypes::CALL, 1) @protocol.write_struct_begin("TestStruct") @protocol.write_field_begin("bool", Thrift::Types::BOOL, 1) @protocol.write_bool(true) @protocol.write_field_end @protocol.write_field_begin("byte", Thrift::Types::BYTE, 2) @protocol.write_byte(127) @protocol.write_field_end @protocol.write_field_begin("i16", Thrift::Types::I16, 3) @protocol.write_i16(32767) @protocol.write_field_end @protocol.write_field_begin("i32", Thrift::Types::I32, 4) @protocol.write_i32(2147483647) @protocol.write_field_end @protocol.write_field_begin("i64", Thrift::Types::I64, 5) @protocol.write_i64(9223372036854775807) @protocol.write_field_end @protocol.write_field_begin("double", Thrift::Types::DOUBLE, 6) @protocol.write_double(3.14159) @protocol.write_field_end @protocol.write_field_begin("string", Thrift::Types::STRING, 7) @protocol.write_string("hello") @protocol.write_field_end @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) read_protocol.read_message_begin read_protocol.read_struct_begin # bool _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::BOOL) expect(read_protocol.read_bool).to eq(true) read_protocol.read_field_end # byte _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::BYTE) expect(read_protocol.read_byte).to eq(127) read_protocol.read_field_end # i16 _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::I16) expect(read_protocol.read_i16).to eq(32767) read_protocol.read_field_end # i32 _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::I32) expect(read_protocol.read_i32).to eq(2147483647) read_protocol.read_field_end # i64 _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::I64) expect(read_protocol.read_i64).to eq(9223372036854775807) read_protocol.read_field_end # double _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::DOUBLE) expect(read_protocol.read_double).to be_within(0.00001).of(3.14159) read_protocol.read_field_end # string _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::STRING) expect(read_protocol.read_string).to eq("hello") read_protocol.read_field_end end end describe "protocol delegation with Compact protocol" do before(:each) do @buffer = Thrift::MemoryBufferTransport.new @protocol = Thrift::HeaderProtocol.new( @buffer, nil, Thrift::HeaderSubprotocolID::COMPACT ) end it "should use Compact protocol" do expect(@protocol.to_s).to match(/header\(compact/) end it "should write and read with Compact protocol" do @protocol.write_message_begin("test", Thrift::MessageTypes::CALL, 1) @protocol.write_struct_begin("Test") @protocol.write_field_begin("field", Thrift::Types::I32, 1) @protocol.write_i32(999) @protocol.write_field_end @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer, nil, Thrift::HeaderSubprotocolID::COMPACT) read_protocol.read_message_begin read_protocol.read_struct_begin _, type, _ = read_protocol.read_field_begin expect(type).to eq(Thrift::Types::I32) expect(read_protocol.read_i32).to eq(999) end end describe "unknown protocol handling" do it "should write an exception response on unknown protocol id" do header_data = +"" header_data << varint32(0x10) header_data << varint32(0) frame = build_header_frame(header_data) buffer = Thrift::MemoryBufferTransport.new(frame) protocol = Thrift::HeaderProtocol.new(buffer) expect { protocol.read_message_begin }.to raise_error(Thrift::ProtocolException) response = buffer.read(buffer.available) expect(response.bytesize).to be > 0 magic = response[4, 2].unpack('n').first expect(magic).to eq(Thrift::HeaderTransport::HEADER_MAGIC) end end describe "protocol auto-detection with legacy frames" do it "should detect framed compact messages" do write_buffer = Thrift::MemoryBufferTransport.new write_protocol = Thrift::CompactProtocol.new(write_buffer) write_protocol.write_message_begin("legacy_framed", Thrift::MessageTypes::CALL, 7) write_protocol.write_struct_begin("Args") write_protocol.write_field_stop write_protocol.write_struct_end write_protocol.write_message_end payload = write_buffer.read(write_buffer.available) framed = [payload.bytesize].pack('N') + payload read_buffer = Thrift::MemoryBufferTransport.new(framed) protocol = Thrift::HeaderProtocol.new(read_buffer) name, type, seqid = protocol.read_message_begin expect(name).to eq("legacy_framed") expect(type).to eq(Thrift::MessageTypes::CALL) expect(seqid).to eq(7) protocol.read_struct_begin _, field_type, _ = protocol.read_field_begin expect(field_type).to eq(Thrift::Types::STOP) protocol.read_struct_end protocol.read_message_end end it "should detect unframed compact messages" do write_buffer = Thrift::MemoryBufferTransport.new write_protocol = Thrift::CompactProtocol.new(write_buffer) write_protocol.write_message_begin("legacy_unframed", Thrift::MessageTypes::CALL, 9) write_protocol.write_struct_begin("Args") write_protocol.write_field_stop write_protocol.write_struct_end write_protocol.write_message_end payload = write_buffer.read(write_buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(payload) protocol = Thrift::HeaderProtocol.new(read_buffer) name, type, seqid = protocol.read_message_begin expect(name).to eq("legacy_unframed") expect(type).to eq(Thrift::MessageTypes::CALL) expect(seqid).to eq(9) protocol.read_struct_begin _, field_type, _ = protocol.read_field_begin expect(field_type).to eq(Thrift::Types::STOP) protocol.read_struct_end protocol.read_message_end end end describe "with compression" do it "should work with ZLIB transform" do @protocol.add_transform(Thrift::HeaderTransformID::ZLIB) @protocol.write_message_begin("compressed_test", Thrift::MessageTypes::CALL, 42) @protocol.write_struct_begin("Args") @protocol.write_field_begin("data", Thrift::Types::STRING, 1) @protocol.write_string("a" * 100) # Compressible data @protocol.write_field_end @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) name, type, seqid = read_protocol.read_message_begin expect(name).to eq("compressed_test") expect(seqid).to eq(42) read_protocol.read_struct_begin _, _, _ = read_protocol.read_field_begin result = read_protocol.read_string expect(result).to eq("a" * 100) end end describe "containers" do it "should write and read lists" do @protocol.write_message_begin("test", Thrift::MessageTypes::CALL, 1) @protocol.write_struct_begin("Test") @protocol.write_field_begin("list", Thrift::Types::LIST, 1) @protocol.write_list_begin(Thrift::Types::I32, 3) @protocol.write_i32(1) @protocol.write_i32(2) @protocol.write_i32(3) @protocol.write_list_end @protocol.write_field_end @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) read_protocol.read_message_begin read_protocol.read_struct_begin _, _, _ = read_protocol.read_field_begin etype, size = read_protocol.read_list_begin expect(etype).to eq(Thrift::Types::I32) expect(size).to eq(3) expect(read_protocol.read_i32).to eq(1) expect(read_protocol.read_i32).to eq(2) expect(read_protocol.read_i32).to eq(3) end it "should write and read maps" do @protocol.write_message_begin("test", Thrift::MessageTypes::CALL, 1) @protocol.write_struct_begin("Test") @protocol.write_field_begin("map", Thrift::Types::MAP, 1) @protocol.write_map_begin(Thrift::Types::STRING, Thrift::Types::I32, 2) @protocol.write_string("a") @protocol.write_i32(1) @protocol.write_string("b") @protocol.write_i32(2) @protocol.write_map_end @protocol.write_field_end @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) read_protocol.read_message_begin read_protocol.read_struct_begin _, _, _ = read_protocol.read_field_begin ktype, vtype, size = read_protocol.read_map_begin expect(ktype).to eq(Thrift::Types::STRING) expect(vtype).to eq(Thrift::Types::I32) expect(size).to eq(2) end it "should write and read sets" do @protocol.write_message_begin("test", Thrift::MessageTypes::CALL, 1) @protocol.write_struct_begin("Test") @protocol.write_field_begin("set", Thrift::Types::SET, 1) @protocol.write_set_begin(Thrift::Types::STRING, 2) @protocol.write_string("x") @protocol.write_string("y") @protocol.write_set_end @protocol.write_field_end @protocol.write_field_stop @protocol.write_struct_end @protocol.write_message_end @protocol.trans.flush data = @buffer.read(@buffer.available) read_buffer = Thrift::MemoryBufferTransport.new(data) read_protocol = Thrift::HeaderProtocol.new(read_buffer) read_protocol.read_message_begin read_protocol.read_struct_begin _, _, _ = read_protocol.read_field_begin etype, size = read_protocol.read_set_begin expect(etype).to eq(Thrift::Types::STRING) expect(size).to eq(2) end end end describe Thrift::HeaderProtocolFactory do it "should create HeaderProtocol" do factory = Thrift::HeaderProtocolFactory.new buffer = Thrift::MemoryBufferTransport.new protocol = factory.get_protocol(buffer) expect(protocol).to be_a(Thrift::HeaderProtocol) end it "should provide a reasonable to_s" do expect(Thrift::HeaderProtocolFactory.new.to_s).to eq("header") end it "should pass configuration to protocol" do factory = Thrift::HeaderProtocolFactory.new(nil, Thrift::HeaderSubprotocolID::COMPACT) buffer = Thrift::MemoryBufferTransport.new protocol = factory.get_protocol(buffer) expect(protocol.to_s).to match(/compact/) end end end thrift-0.23.0/lib/rb/spec/union_spec.rb0000664000175000017500000002462115167543515020171 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Union' do describe Thrift::Union do it "should return nil value in unset union" do union = SpecNamespace::My_union.new expect(union.get_set_field).to eq(nil) expect(union.get_value).to eq(nil) end it "should set a field and be accessible through get_value and the named field accessor" do union = SpecNamespace::My_union.new union.integer32 = 25 expect(union.get_set_field).to eq(:integer32) expect(union.get_value).to eq(25) expect(union.integer32).to eq(25) end it "should work correctly when instantiated with static field constructors" do union = SpecNamespace::My_union.integer32(5) expect(union.get_set_field).to eq(:integer32) expect(union.integer32).to eq(5) end it "should raise for wrong set field" do union = SpecNamespace::My_union.new union.integer32 = 25 expect { union.some_characters }.to raise_error(RuntimeError, "some_characters is not union's set field.") end it "should raise for wrong set field when hash initialized and type checking is off" do Thrift.type_checking = false union = SpecNamespace::My_union.new({incorrect_field: :incorrect}) expect { Thrift::Serializer.new.serialize(union) }.to raise_error(Thrift::ProtocolException, "set_field is not valid for this union!") { |error| expect(error.type).to eq(Thrift::ProtocolException::INVALID_DATA) } end it "should not be equal to nil" do union = SpecNamespace::My_union.new expect(union).not_to eq(nil) end it "should not be equal with an empty String" do union = SpecNamespace::My_union.new expect(union).not_to eq('') end it "should not equate two different unions, i32 vs. string" do union = SpecNamespace::My_union.new(:integer32, 25) other_union = SpecNamespace::My_union.new(:some_characters, "blah!") expect(union).not_to eq(other_union) end it "should properly reset setfield and setvalue" do union = SpecNamespace::My_union.new(:integer32, 25) expect(union.get_set_field).to eq(:integer32) union.some_characters = "blah!" expect(union.get_set_field).to eq(:some_characters) expect(union.get_value).to eq("blah!") expect { union.integer32 }.to raise_error(RuntimeError, "integer32 is not union's set field.") end it "should not equate two different unions with different values" do union = SpecNamespace::My_union.new(:integer32, 25) other_union = SpecNamespace::My_union.new(:integer32, 400) expect(union).not_to eq(other_union) end it "should not equate two different unions with different fields" do union = SpecNamespace::My_union.new(:integer32, 25) other_union = SpecNamespace::My_union.new(:other_i32, 25) expect(union).not_to eq(other_union) end it "should equate two unions with the same UUID value" do union = SpecNamespace::My_union.new(:unique_id, '550e8400-e29b-41d4-a716-446655440000') other_union = SpecNamespace::My_union.new(:unique_id, '550e8400-e29b-41d4-a716-446655440000') expect(union).to eq(other_union) end it "should not equate two unions with different UUID values" do union = SpecNamespace::My_union.new(:unique_id, '550e8400-e29b-41d4-a716-446655440000') other_union = SpecNamespace::My_union.new(:unique_id, '6ba7b810-9dad-11d1-80b4-00c04fd430c8') expect(union).not_to eq(other_union) end it "should not equate UUID union with different field type" do union = SpecNamespace::My_union.new(:unique_id, '550e8400-e29b-41d4-a716-446655440000') other_union = SpecNamespace::My_union.new(:some_characters, '550e8400-e29b-41d4-a716-446655440000') expect(union).not_to eq(other_union) end it "should inspect properly" do union = SpecNamespace::My_union.new(:integer32, 25) expect(union.inspect).to eq("") end it "should not allow setting with instance_variable_set" do union = SpecNamespace::My_union.new(:integer32, 27) union.instance_variable_set(:@some_characters, "hallo!") expect(union.get_set_field).to eq(:integer32) expect(union.get_value).to eq(27) expect { union.some_characters }.to raise_error(RuntimeError, "some_characters is not union's set field.") end it "should serialize to binary correctly" do trans = Thrift::MemoryBufferTransport.new proto = Thrift::BinaryProtocol.new(trans) union = SpecNamespace::My_union.new(:integer32, 25) union.write(proto) other_union = SpecNamespace::My_union.new(:integer32, 25) other_union.read(proto) expect(other_union).to eq(union) end it "should serialize to json correctly" do trans = Thrift::MemoryBufferTransport.new proto = Thrift::JsonProtocol.new(trans) union = SpecNamespace::My_union.new(:integer32, 25) union.write(proto) other_union = SpecNamespace::My_union.new(:integer32, 25) other_union.read(proto) expect(other_union).to eq(union) end it "should raise when validating unset union" do union = SpecNamespace::My_union.new expect { union.validate }.to raise_error(Thrift::ProtocolException, "Union fields are not set.") { |error| expect(error.type).to eq(Thrift::ProtocolException::INVALID_DATA) } other_union = SpecNamespace::My_union.new(:integer32, 1) expect { other_union.validate }.not_to raise_error end it "should validate an enum field properly" do union = SpecNamespace::TestUnion.new(:enum_field, 3) expect(union.get_set_field).to eq(:enum_field) expect { union.validate }.to raise_error(Thrift::ProtocolException, "Invalid value of field enum_field!") { |error| expect(error.type).to eq(Thrift::ProtocolException::INVALID_DATA) } other_union = SpecNamespace::TestUnion.new(:enum_field, 1) expect { other_union.validate }.not_to raise_error end it "should properly serialize and match structs with a union" do union = SpecNamespace::My_union.new(:integer32, 26) swu = SpecNamespace::Struct_with_union.new(:fun_union => union) trans = Thrift::MemoryBufferTransport.new proto = Thrift::CompactProtocol.new(trans) swu.write(proto) other_union = SpecNamespace::My_union.new(:some_characters, "hello there") swu2 = SpecNamespace::Struct_with_union.new(:fun_union => other_union) expect(swu2).not_to eq(swu) swu2.read(proto) expect(swu2).to eq(swu) end it "should support old style constructor" do union = SpecNamespace::My_union.new(:integer32 => 26) expect(union.get_set_field).to eq(:integer32) expect(union.get_value).to eq(26) end it "should not throw an error when inspected and unset" do expect{ SpecNamespace::TestUnion.new().inspect }.not_to raise_error end it "should print enum value name when inspected" do expect(SpecNamespace::My_union.new(:some_enum => SpecNamespace::SomeEnum::ONE).inspect).to eq("") expect(SpecNamespace::My_union.new(:my_map => {SpecNamespace::SomeEnum::ONE => [SpecNamespace::SomeEnum::TWO]}).inspect).to eq("") end it "should offer field? methods" do expect(SpecNamespace::My_union.new.some_enum?).to be_falsey expect(SpecNamespace::My_union.new(:some_enum => SpecNamespace::SomeEnum::ONE).some_enum?).to be_truthy expect(SpecNamespace::My_union.new(:im_true => false).im_true?).to be_truthy expect(SpecNamespace::My_union.new(:im_true => true).im_true?).to be_truthy end it "should pretty print binary fields" do expect(SpecNamespace::TestUnion.new(:binary_field => "\001\002\003").inspect).to eq("") end it "should be comparable" do relationships = [ [0, -1, -1, -1, -1, -1], [1, 0, -1, -1, -1, -1], [1, 1, 0, -1, -1, -1], [1, 1, 1, 0, -1, -1], [1, 1, 1, 1, 0, -1], [1, 1, 1, 1, 1, 0]] objs = [ SpecNamespace::TestUnion.new(:string_field, "blah"), SpecNamespace::TestUnion.new(:string_field, "blahblah"), SpecNamespace::TestUnion.new(:i32_field, 1), SpecNamespace::TestUnion.new(:uuid_field, '550e8400-e29b-41d4-a716-446655440000'), SpecNamespace::TestUnion.new(:uuid_field, '6ba7b810-9dad-11d1-80b4-00c04fd430c8'), SpecNamespace::TestUnion.new()] objs.size.times do |y| objs.size.times do |x| # puts "#{objs[y].inspect} <=> #{objs[x].inspect} should == #{relationships[y][x]}" expect(objs[y] <=> objs[x]).to eq(relationships[y][x]) end end end it "should handle UUID as union value" do union = SpecNamespace::My_union.new union.unique_id = 'ffffffff-ffff-ffff-ffff-ffffffffffff' trans = Thrift::MemoryBufferTransport.new prot = Thrift::CompactProtocol.new(trans) union.write(prot) result = SpecNamespace::My_union.new result.read(prot) expect(result.unique_id).to eq('ffffffff-ffff-ffff-ffff-ffffffffffff') expect(result.get_set_field).to eq(:unique_id) end it "should normalize UUID case in union" do union = SpecNamespace::My_union.new union.unique_id = '550E8400-E29B-41D4-A716-446655440000' trans = Thrift::MemoryBufferTransport.new prot = Thrift::BinaryProtocol.new(trans) union.write(prot) result = SpecNamespace::My_union.new result.read(prot) expect(result.unique_id).to eq('550e8400-e29b-41d4-a716-446655440000') end end end thrift-0.23.0/lib/rb/spec/server_socket_spec.rb0000664000175000017500000000565315167543515021723 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require File.expand_path("#{File.dirname(__FILE__)}/socket_spec_shared") describe 'Thrift::ServerSocket' do describe Thrift::ServerSocket do before(:each) do @socket = Thrift::ServerSocket.new(1234) end it "should create a handle when calling listen" do expect(TCPServer).to receive(:new).with(nil, 1234) @socket.listen end it "should accept an optional host argument" do @socket = Thrift::ServerSocket.new('localhost', 1234) expect(TCPServer).to receive(:new).with('localhost', 1234) @socket.to_s == "server(localhost:1234)" @socket.listen end it "should create a Thrift::Socket to wrap accepted sockets" do handle = double("TCPServer") expect(TCPServer).to receive(:new).with(nil, 1234).and_return(handle) @socket.listen sock = double("sock") expect(sock).to receive(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) expect(handle).to receive(:accept).and_return(sock) trans = double("Socket") expect(Thrift::Socket).to receive(:new).and_return(trans) expect(trans).to receive(:handle=).with(sock) expect(@socket.accept).to eq(trans) end it "should close the handle when closed" do handle = double("TCPServer", :closed? => false) expect(TCPServer).to receive(:new).with(nil, 1234).and_return(handle) @socket.listen expect(handle).to receive(:close) @socket.close end it "should return nil when accepting if there is no handle" do expect(@socket.accept).to be_nil end it "should return true for closed? when appropriate" do handle = double("TCPServer", :closed? => false) allow(TCPServer).to receive(:new).and_return(handle) @socket.listen expect(@socket).not_to be_closed allow(handle).to receive(:close) @socket.close expect(@socket).to be_closed @socket.listen expect(@socket).not_to be_closed allow(handle).to receive(:closed?).and_return(true) expect(@socket).to be_closed end it "should provide a reasonable to_s" do expect(@socket.to_s).to eq("socket(:1234)") end end end thrift-0.23.0/lib/rb/spec/constants_demo_spec.rb0000664000175000017500000001047015167543515022056 0ustar00buildbuild00000000000000# encoding: UTF-8 # # 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. # require 'spec_helper' $:.unshift File.join(File.dirname(__FILE__), *%w[gen-rb/constants_demo]) require 'constants_demo_constants' describe 'ConstantsDemo' do it 'should have correct integer constants' do expect(ConstantsDemo::MyInt).to eq(3) expect(ConstantsDemo::Hex_const).to eq(0x0001F) expect(ConstantsDemo::Negative_hex_constant).to eq(-0x0001F) expect(ConstantsDemo::GEN_ME).to eq(-3523553) end it 'should have correct double constants' do expect(ConstantsDemo::GEn_DUB).to eq(325.532) expect(ConstantsDemo::GEn_DU).to eq(85.2355) expect(ConstantsDemo::E10).to eq(1e+10) expect(ConstantsDemo::E11).to eq(-1e+10) end it 'should have correct string constants' do expect(ConstantsDemo::GEN_STRING).to eq("asldkjasfd") end it 'should have correct uuid constants' do expect(ConstantsDemo::GEN_UUID).to eq("00000000-4444-CCCC-ffff-0123456789ab") expect(ConstantsDemo::GEN_GUID).to eq("00112233-4455-6677-8899-aaBBccDDeeFF") expect(ConstantsDemo::MY_UUID).to eq("00000000-4444-CCCC-ffff-0123456789ab") expect(ConstantsDemo::MY_GUID).to eq("00112233-4455-6677-8899-aaBBccDDeeFF") end it 'should have correct list constants' do expect(ConstantsDemo::GEN_LIST).to be_a(Array) expect(ConstantsDemo::GEN_LIST).to eq([235235, 23598352, 3253523]) end it 'should have correct map constants' do expect(ConstantsDemo::GEN_MAP).to be_a(Hash) expect(ConstantsDemo::GEN_MAP[35532]).to eq(233) expect(ConstantsDemo::GEN_MAP[43523]).to eq(853) expect(ConstantsDemo::GEN_MAP2).to be_a(Hash) expect(ConstantsDemo::GEN_MAP2["hello"]).to eq(233) expect(ConstantsDemo::GEN_MAP2["lkj98d"]).to eq(853) expect(ConstantsDemo::GEN_MAP2['lkjsdf']).to eq(98325) expect(ConstantsDemo::GEN_MAPMAP).to be_a(Hash) expect(ConstantsDemo::GEN_MAPMAP[235]).to be_a(Hash) expect(ConstantsDemo::GEN_MAPMAP[235][532]).to eq(53255) expect(ConstantsDemo::GEN_MAPMAP[235][235]).to eq(235) end it 'should have correct set constants' do expect(ConstantsDemo::GEN_SET).to be_a(Set) expect(ConstantsDemo::GEN_SET.size).to eq(2) expect(ConstantsDemo::GEN_SET.include?(235)).to be true # added twice, but this is a set expect(ConstantsDemo::GEN_SET.include?(53235)).to be true expect(ConstantsDemo::GUID_SET).to be_a(Set) expect(ConstantsDemo::GUID_SET.size).to eq(2) expect(ConstantsDemo::GUID_SET.include?("00112233-4455-6677-8899-aaBBccDDeeFF")).to be true expect(ConstantsDemo::GUID_SET.include?("00000000-4444-CCCC-ffff-0123456789ab")).to be true end it 'should have correct struct constants' do expect(ConstantsDemo::GEN_THING).to be_a(Thrift::Struct) expect(ConstantsDemo::GEN_THING.hello).to eq(325) expect(ConstantsDemo::GEN_THING.goodbye).to eq(325352) expect(ConstantsDemo::GEN_THING.id).to eq("00112233-4455-6677-8899-aaBBccDDeeFF") expect(ConstantsDemo::GEN_THING.my_id).to eq("00000000-4444-CCCC-ffff-0123456789ab") expect(ConstantsDemo::GEN_THING.my_optional_id).to eq("00000000-4444-CCCC-ffff-0123456789ab") expect(ConstantsDemo::GEN_WHAT).to be_a(Hash) expect(ConstantsDemo::GEN_WHAT[35]).to be_a(Thrift::Struct) expect(ConstantsDemo::GEN_WHAT[35].hello).to eq(325) expect(ConstantsDemo::GEN_WHAT[35].goodbye).to eq(325352) expect(ConstantsDemo::GEN_WHAT[35].id).to eq("00000000-4444-CCCC-ffff-0123456789ab") expect(ConstantsDemo::GEN_WHAT[35].my_id).to eq("00000000-4444-CCCC-ffff-0123456789ab") expect(ConstantsDemo::GEN_WHAT[35].my_optional_id).to eq("00000000-4444-CCCC-ffff-0123456789ab") end end thrift-0.23.0/lib/rb/spec/types_spec.rb0000664000175000017500000002033415167543515020202 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe Thrift::Types do before(:each) do Thrift.type_checking = true end after(:each) do Thrift.type_checking = false end context 'type checking' do it "should return the proper name for each type" do expect(Thrift.type_name(Thrift::Types::I16)).to eq("Types::I16") expect(Thrift.type_name(Thrift::Types::VOID)).to eq("Types::VOID") expect(Thrift.type_name(Thrift::Types::LIST)).to eq("Types::LIST") expect(Thrift.type_name(42)).to be_nil end it "should check types properly" do # lambda { Thrift.check_type(nil, Thrift::Types::STOP) }.should raise_error(Thrift::TypeError) expect { Thrift.check_type(3, {:type => Thrift::Types::STOP}, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::VOID}, :foo) }.not_to raise_error expect { Thrift.check_type(3, {:type => Thrift::Types::VOID}, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(true, {:type => Thrift::Types::BOOL}, :foo) }.not_to raise_error expect { Thrift.check_type(3, {:type => Thrift::Types::BOOL}, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(42, {:type => Thrift::Types::BYTE}, :foo) }.not_to raise_error expect { Thrift.check_type(42, {:type => Thrift::Types::I16}, :foo) }.not_to raise_error expect { Thrift.check_type(42, {:type => Thrift::Types::I32}, :foo) }.not_to raise_error expect { Thrift.check_type(42, {:type => Thrift::Types::I64}, :foo) }.not_to raise_error expect { Thrift.check_type(3.14, {:type => Thrift::Types::I32}, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(3.14, {:type => Thrift::Types::DOUBLE}, :foo) }.not_to raise_error expect { Thrift.check_type(3, {:type => Thrift::Types::DOUBLE}, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type("3", {:type => Thrift::Types::STRING}, :foo) }.not_to raise_error expect { Thrift.check_type(3, {:type => Thrift::Types::STRING}, :foo) }.to raise_error(Thrift::TypeError) hello = SpecNamespace::Hello.new expect { Thrift.check_type(hello, {:type => Thrift::Types::STRUCT, :class => SpecNamespace::Hello}, :foo) }.not_to raise_error expect { Thrift.check_type("foo", {:type => Thrift::Types::STRUCT}, :foo) }.to raise_error(Thrift::TypeError) field = {:type => Thrift::Types::MAP, :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::STRING}} expect { Thrift.check_type({1 => "one"}, field, :foo) }.not_to raise_error expect { Thrift.check_type([1], field, :foo) }.to raise_error(Thrift::TypeError) field = {:type => Thrift::Types::LIST, :element => {:type => Thrift::Types::I32}} expect { Thrift.check_type([1], field, :foo) }.not_to raise_error expect { Thrift.check_type({:foo => 1}, field, :foo) }.to raise_error(Thrift::TypeError) field = {:type => Thrift::Types::SET, :element => {:type => Thrift::Types::I32}} expect { Thrift.check_type(Set.new([1, 2]), field, :foo) }.not_to raise_error expect { Thrift.check_type([1, 2], field, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type({:foo => true}, field, :foo) }.to raise_error(Thrift::TypeError) end it "should error out if nil is passed and skip_types is false" do expect { Thrift.check_type(nil, {:type => Thrift::Types::BOOL}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::BYTE}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::I16}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::I32}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::I64}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::DOUBLE}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::STRING}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::STRUCT}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::LIST}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::SET}, :foo, false) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(nil, {:type => Thrift::Types::MAP}, :foo, false) }.to raise_error(Thrift::TypeError) end it "should check element types on containers" do field = {:type => Thrift::Types::LIST, :element => {:type => Thrift::Types::I32}} expect { Thrift.check_type([1, 2], field, :foo) }.not_to raise_error expect { Thrift.check_type([1, nil, 2], field, :foo) }.to raise_error(Thrift::TypeError) field = {:type => Thrift::Types::MAP, :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::STRING}} expect { Thrift.check_type({1 => "one", 2 => "two"}, field, :foo) }.not_to raise_error expect { Thrift.check_type({1 => "one", nil => "nil"}, field, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type({1 => nil, 2 => "two"}, field, :foo) }.to raise_error(Thrift::TypeError) field = {:type => Thrift::Types::SET, :element => {:type => Thrift::Types::I32}} expect { Thrift.check_type(Set.new([1, 2]), field, :foo) }.not_to raise_error expect { Thrift.check_type(Set.new([1, nil, 2]), field, :foo) }.to raise_error(Thrift::TypeError) expect { Thrift.check_type(Set.new([1, 2.3, 2]), field, :foo) }.to raise_error(Thrift::TypeError) field = {:type => Thrift::Types::STRUCT, :class => SpecNamespace::Hello} expect { Thrift.check_type(SpecNamespace::BoolStruct, field, :foo) }.to raise_error(Thrift::TypeError) end it "should give the Thrift::TypeError a readable message" do msg = "Expected Types::STRING, received Integer for field foo" expect { Thrift.check_type(3, {:type => Thrift::Types::STRING}, :foo) }.to raise_error(Thrift::TypeError, msg) msg = "Expected Types::STRING, received Integer for field foo.element" field = {:type => Thrift::Types::LIST, :element => {:type => Thrift::Types::STRING}} expect { Thrift.check_type([3], field, :foo) }.to raise_error(Thrift::TypeError, msg) msg = "Expected Types::I32, received NilClass for field foo.element.key" field = {:type => Thrift::Types::LIST, :element => {:type => Thrift::Types::MAP, :key => {:type => Thrift::Types::I32}, :value => {:type => Thrift::Types::I32}}} expect { Thrift.check_type([{nil => 3}], field, :foo) }.to raise_error(Thrift::TypeError, msg) msg = "Expected Types::I32, received NilClass for field foo.element.value" expect { Thrift.check_type([{1 => nil}], field, :foo) }.to raise_error(Thrift::TypeError, msg) end end end thrift-0.23.0/lib/rb/spec/unix_socket_spec.rb0000664000175000017500000000773115167543515021377 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require File.expand_path("#{File.dirname(__FILE__)}/socket_spec_shared") describe 'UNIXSocket' do describe Thrift::UNIXSocket do before(:each) do @path = '/tmp/thrift_spec_socket' @socket = Thrift::UNIXSocket.new(@path) @handle = double("Handle", :closed? => false) allow(@handle).to receive(:close) allow(::UNIXSocket).to receive(:new).and_return(@handle) end it_should_behave_like "a socket" it "should raise a TransportException when it cannot open a socket" do expect(::UNIXSocket).to receive(:new).and_raise(StandardError) expect { @socket.open }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } end it "should accept an optional timeout" do allow(::UNIXSocket).to receive(:new) expect(Thrift::UNIXSocket.new(@path, 5).timeout).to eq(5) end it "should provide a reasonable to_s" do allow(::UNIXSocket).to receive(:new) expect(Thrift::UNIXSocket.new(@path).to_s).to eq("domain(#{@path})") end end describe Thrift::UNIXServerSocket do before(:each) do @path = '/tmp/thrift_spec_socket' @socket = Thrift::UNIXServerSocket.new(@path) end it "should create a handle when calling listen" do expect(UNIXServer).to receive(:new).with(@path) @socket.listen end it "should create a Thrift::UNIXSocket to wrap accepted sockets" do handle = double("UNIXServer") expect(UNIXServer).to receive(:new).with(@path).and_return(handle) @socket.listen sock = double("sock") expect(handle).to receive(:accept).and_return(sock) trans = double("UNIXSocket") expect(Thrift::UNIXSocket).to receive(:new).and_return(trans) expect(trans).to receive(:handle=).with(sock) expect(@socket.accept).to eq(trans) end it "should close the handle when closed" do handle = double("UNIXServer", :closed? => false) expect(UNIXServer).to receive(:new).with(@path).and_return(handle) @socket.listen expect(handle).to receive(:close) allow(File).to receive(:delete) @socket.close end it "should delete the socket when closed" do handle = double("UNIXServer", :closed? => false) expect(UNIXServer).to receive(:new).with(@path).and_return(handle) @socket.listen allow(handle).to receive(:close) expect(File).to receive(:delete).with(@path) @socket.close end it "should return nil when accepting if there is no handle" do expect(@socket.accept).to be_nil end it "should return true for closed? when appropriate" do handle = double("UNIXServer", :closed? => false) allow(UNIXServer).to receive(:new).and_return(handle) allow(File).to receive(:delete) @socket.listen expect(@socket).not_to be_closed allow(handle).to receive(:close) @socket.close expect(@socket).to be_closed @socket.listen expect(@socket).not_to be_closed allow(handle).to receive(:closed?).and_return(true) expect(@socket).to be_closed end it "should provide a reasonable to_s" do expect(@socket.to_s).to eq("domain(#{@path})") end end end thrift-0.23.0/lib/rb/spec/server_spec.rb0000664000175000017500000001727615167543515020357 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Server' do describe Thrift::BaseServer do before(:each) do @processor = double("Processor") @serverTrans = double("ServerTransport") @trans = double("BaseTransport") @prot = double("BaseProtocol") @server = described_class.new(@processor, @serverTrans, @trans, @prot) end it "should default to BaseTransportFactory and BinaryProtocolFactory when not specified" do @server = Thrift::BaseServer.new(double("Processor"), double("BaseServerTransport")) expect(@server.instance_variable_get(:'@transport_factory')).to be_an_instance_of(Thrift::BaseTransportFactory) expect(@server.instance_variable_get(:'@protocol_factory')).to be_an_instance_of(Thrift::BinaryProtocolFactory) end it "should not serve" do expect { @server.serve() }.to raise_error(NotImplementedError) end it "should provide a reasonable to_s" do expect(@serverTrans).to receive(:to_s).once.and_return("serverTrans") expect(@trans).to receive(:to_s).once.and_return("trans") expect(@prot).to receive(:to_s).once.and_return("prot") expect(@server.to_s).to eq("server(prot(trans(serverTrans)))") end end describe Thrift::SimpleServer do before(:each) do @processor = double("Processor") @serverTrans = double("ServerTransport") @trans = double("BaseTransport") @prot = double("BaseProtocol") @client = double("Client") @server = described_class.new(@processor, @serverTrans, @trans, @prot) end it "should provide a reasonable to_s" do expect(@serverTrans).to receive(:to_s).once.and_return("serverTrans") expect(@trans).to receive(:to_s).once.and_return("trans") expect(@prot).to receive(:to_s).once.and_return("prot") expect(@server.to_s).to eq("simple(server(prot(trans(serverTrans))))") end it "should serve in the main thread" do expect(@serverTrans).to receive(:listen).ordered expect(@serverTrans).to receive(:accept).exactly(3).times.and_return(@client) expect(@trans).to receive(:get_transport).exactly(3).times.with(@client).and_return(@trans) expect(@prot).to receive(:get_protocol).exactly(3).times.with(@trans).and_return(@prot) x = 0 expect(@processor).to receive(:process).exactly(3).times.with(@prot, @prot) do case (x += 1) when 1 then raise Thrift::TransportException when 2 then raise Thrift::ProtocolException when 3 then throw :stop end end expect(@trans).to receive(:close).exactly(3).times expect(@serverTrans).to receive(:close).ordered expect { @server.serve }.to throw_symbol(:stop) end end describe Thrift::ThreadedServer do before(:each) do @processor = double("Processor") @serverTrans = double("ServerTransport") @trans = double("BaseTransport") @prot = double("BaseProtocol") @client = double("Client") @server = described_class.new(@processor, @serverTrans, @trans, @prot) end it "should provide a reasonable to_s" do expect(@serverTrans).to receive(:to_s).once.and_return("serverTrans") expect(@trans).to receive(:to_s).once.and_return("trans") expect(@prot).to receive(:to_s).once.and_return("prot") expect(@server.to_s).to eq("threaded(server(prot(trans(serverTrans))))") end it "should serve using threads" do expect(@serverTrans).to receive(:listen).ordered expect(@serverTrans).to receive(:accept).exactly(3).times.and_return(@client) expect(@trans).to receive(:get_transport).exactly(3).times.with(@client).and_return(@trans) expect(@prot).to receive(:get_protocol).exactly(3).times.with(@trans).and_return(@prot) expect(Thread).to receive(:new).with(@prot, @trans).exactly(3).times.and_yield(@prot, @trans) x = 0 expect(@processor).to receive(:process).exactly(3).times.with(@prot, @prot) do case (x += 1) when 1 then raise Thrift::TransportException when 2 then raise Thrift::ProtocolException when 3 then throw :stop end end expect(@trans).to receive(:close).exactly(3).times expect(@serverTrans).to receive(:close).ordered expect { @server.serve }.to throw_symbol(:stop) end end describe Thrift::ThreadPoolServer do before(:each) do @processor = double("Processor") @server_trans = double("ServerTransport") @trans = double("BaseTransport") @prot = double("BaseProtocol") @client = double("Client") @server = described_class.new(@processor, @server_trans, @trans, @prot) sleep(0.15) end it "should provide a reasonable to_s" do expect(@server_trans).to receive(:to_s).once.and_return("server_trans") expect(@trans).to receive(:to_s).once.and_return("trans") expect(@prot).to receive(:to_s).once.and_return("prot") expect(@server.to_s).to eq("threadpool(server(prot(trans(server_trans))))") end it "should serve inside a thread" do exception_q = @server.instance_variable_get(:@exception_q) expect_any_instance_of(described_class).to receive(:serve) do exception_q.push(StandardError.new('ERROR')) end expect { @server.rescuable_serve }.to(raise_error('ERROR')) sleep(0.15) end it "should avoid running the server twice when retrying rescuable_serve" do exception_q = @server.instance_variable_get(:@exception_q) expect_any_instance_of(described_class).to receive(:serve) do exception_q.push(StandardError.new('ERROR1')) exception_q.push(StandardError.new('ERROR2')) end expect { @server.rescuable_serve }.to(raise_error('ERROR1')) expect { @server.rescuable_serve }.to(raise_error('ERROR2')) end it "should serve using a thread pool" do thread_q = double("SizedQueue") exception_q = double("Queue") @server.instance_variable_set(:@thread_q, thread_q) @server.instance_variable_set(:@exception_q, exception_q) expect(@server_trans).to receive(:listen).ordered expect(thread_q).to receive(:push).with(:token) expect(thread_q).to receive(:pop) expect(Thread).to receive(:new).and_yield expect(@server_trans).to receive(:accept).exactly(3).times.and_return(@client) expect(@trans).to receive(:get_transport).exactly(3).times.and_return(@trans) expect(@prot).to receive(:get_protocol).exactly(3).times.and_return(@prot) x = 0 error = RuntimeError.new("Stopped") expect(@processor).to receive(:process).exactly(3).times.with(@prot, @prot) do case (x += 1) when 1 then raise Thrift::TransportException when 2 then raise Thrift::ProtocolException when 3 then raise error end end expect(@trans).to receive(:close).exactly(3).times expect(exception_q).to receive(:push).with(error).and_throw(:stop) expect(@server_trans).to receive(:close) expect { @server.serve }.to(throw_symbol(:stop)) end end end thrift-0.23.0/lib/rb/spec/struct_spec.rb0000664000175000017500000004114415167543515020364 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Struct' do describe Thrift::Struct do it "should iterate over all fields properly" do fields = {} SpecNamespace::Foo.new.each_field { |fid, field_info| fields[fid] = field_info } expect(fields).to eq(SpecNamespace::Foo::FIELDS) end it "should initialize all fields to defaults" do validate_default_arguments(SpecNamespace::Foo.new) end it "should initialize all fields to defaults and accept a block argument" do SpecNamespace::Foo.new do |f| validate_default_arguments(f) end end def validate_default_arguments(object) expect(object.simple).to eq(53) expect(object.words).to eq("words") expect(object.hello).to eq(SpecNamespace::Hello.new(:greeting => 'hello, world!')) expect(object.ints).to eq([1, 2, 2, 3]) expect(object.complex).to be_nil expect(object.shorts).to eq(Set.new([5, 17, 239])) end it "should not share default values between instances" do begin struct = SpecNamespace::Foo.new struct.ints << 17 expect(SpecNamespace::Foo.new.ints).to eq([1, 2, 2, 3]) ensure # ensure no leakage to other tests SpecNamespace::Foo::FIELDS[4][:default] = [1, 2, 2, 3] end end it "should properly initialize boolean values" do struct = SpecNamespace::BoolStruct.new(:yesno => false) expect(struct.yesno).to be_falsey end it "should have proper == semantics" do expect(SpecNamespace::Foo.new).not_to eq(SpecNamespace::Hello.new) expect(SpecNamespace::Foo.new).to eq(SpecNamespace::Foo.new) expect(SpecNamespace::Foo.new(:simple => 52)).not_to eq(SpecNamespace::Foo.new) end it "should print enum value names in inspect" do expect(SpecNamespace::StructWithSomeEnum.new(:some_enum => SpecNamespace::SomeEnum::ONE).inspect).to eq("") expect(SpecNamespace::StructWithEnumMap.new(:my_map => {SpecNamespace::SomeEnum::ONE => [SpecNamespace::SomeEnum::TWO]}).inspect).to eq("") end it "should pretty print binary fields" do expect(SpecNamespace::Foo2.new(:my_binary => "\001\002\003").inspect).to eq("") end it "should offer field? methods" do expect(SpecNamespace::Foo.new.opt_string?).to be_falsey expect(SpecNamespace::Foo.new(:simple => 52).simple?).to be_truthy expect(SpecNamespace::Foo.new(:my_bool => false).my_bool?).to be_truthy expect(SpecNamespace::Foo.new(:my_bool => true).my_bool?).to be_truthy end it "should be comparable" do s1 = SpecNamespace::StructWithSomeEnum.new(:some_enum => SpecNamespace::SomeEnum::ONE) s2 = SpecNamespace::StructWithSomeEnum.new(:some_enum => SpecNamespace::SomeEnum::TWO) expect(s1 <=> s2).to eq(-1) expect(s2 <=> s1).to eq(1) expect(s1 <=> s1).to eq(0) expect(s1 <=> SpecNamespace::StructWithSomeEnum.new()).to eq(-1) end it "should read itself off the wire" do struct = SpecNamespace::Foo.new prot = Thrift::BaseProtocol.new(double("transport")) expect(prot).to receive(:read_struct_begin).twice expect(prot).to receive(:read_struct_end).twice expect(prot).to receive(:read_field_begin).and_return( ['complex', Thrift::Types::MAP, 5], # Foo ['words', Thrift::Types::STRING, 2], # Foo ['hello', Thrift::Types::STRUCT, 3], # Foo ['greeting', Thrift::Types::STRING, 1], # Hello [nil, Thrift::Types::STOP, 0], # Hello ['simple', Thrift::Types::I32, 1], # Foo ['ints', Thrift::Types::LIST, 4], # Foo ['shorts', Thrift::Types::SET, 6], # Foo [nil, Thrift::Types::STOP, 0] # Hello ) expect(prot).to receive(:read_field_end).exactly(7).times expect(prot).to receive(:read_map_begin).and_return( [Thrift::Types::I32, Thrift::Types::MAP, 2], # complex [Thrift::Types::STRING, Thrift::Types::DOUBLE, 2], # complex/1/value [Thrift::Types::STRING, Thrift::Types::DOUBLE, 1] # complex/2/value ) expect(prot).to receive(:read_map_end).exactly(3).times expect(prot).to receive(:read_list_begin).and_return([Thrift::Types::I32, 4]) expect(prot).to receive(:read_list_end) expect(prot).to receive(:read_set_begin).and_return([Thrift::Types::I16, 2]) expect(prot).to receive(:read_set_end) expect(prot).to receive(:read_i32).and_return( 1, 14, # complex keys 42, # simple 4, 23, 4, 29 # ints ) expect(prot).to receive(:read_string).and_return("pi", "e", "feigenbaum", "apple banana", "what's up?") expect(prot).to receive(:read_double).and_return(Math::PI, Math::E, 4.669201609) expect(prot).to receive(:read_i16).and_return(2, 3) expect(prot).not_to receive(:skip) struct.read(prot) expect(struct.simple).to eq(42) expect(struct.complex).to eq({1 => {"pi" => Math::PI, "e" => Math::E}, 14 => {"feigenbaum" => 4.669201609}}) expect(struct.hello).to eq(SpecNamespace::Hello.new(:greeting => "what's up?")) expect(struct.words).to eq("apple banana") expect(struct.ints).to eq([4, 23, 4, 29]) expect(struct.shorts).to eq(Set.new([3, 2])) end it "rejects negative container sizes while reading" do struct = SpecNamespace::Foo.new prot = Thrift::BaseProtocol.new(double("transport")) expect(prot).to receive(:read_list_begin).and_return([Thrift::Types::I32, -1]) expect { struct.send(:read_field, prot, SpecNamespace::Foo::FIELDS[4]) }.to raise_error(Thrift::ProtocolException, "Negative size") { |error| expect(error.type).to eq(Thrift::ProtocolException::NEGATIVE_SIZE) } end it "does not preallocate arrays from declared list sizes" do struct = SpecNamespace::Foo.new prot = Thrift::BaseProtocol.new(double("transport")) declared_size = 1 << 30 sentinel = RuntimeError.new("stop after first element") expect(prot).to receive(:read_list_begin).and_return([Thrift::Types::I32, declared_size]) expect(prot).to receive(:read_i32).and_raise(sentinel) expect(Array).not_to receive(:new).with(declared_size) expect { struct.send(:read_field, prot, SpecNamespace::Foo::FIELDS[4]) }.to raise_error(sentinel) end it "should serialize false boolean fields correctly" do b = SpecNamespace::BoolStruct.new(:yesno => false) prot = Thrift::BinaryProtocol.new(Thrift::MemoryBufferTransport.new) expect(prot).to receive(:write_bool).with(false) b.write(prot) end it "should skip unexpected fields in structs and use default values" do struct = SpecNamespace::Foo.new prot = Thrift::BaseProtocol.new(double("transport")) expect(prot).to receive(:read_struct_begin) expect(prot).to receive(:read_struct_end) expect(prot).to receive(:read_field_begin).and_return( ['simple', Thrift::Types::I32, 1], ['complex', Thrift::Types::STRUCT, 5], ['thinz', Thrift::Types::MAP, 7], ['foobar', Thrift::Types::I32, 3], ['words', Thrift::Types::STRING, 2], [nil, Thrift::Types::STOP, 0] ) expect(prot).to receive(:read_field_end).exactly(5).times expect(prot).to receive(:read_i32).and_return(42) expect(prot).to receive(:read_string).and_return("foobar") expect(prot).to receive(:skip).with(Thrift::Types::STRUCT) expect(prot).to receive(:skip).with(Thrift::Types::MAP) # prot.should_receive(:read_map_begin).and_return([Thrift::Types::I32, Thrift::Types::I32, 0]) # prot.should_receive(:read_map_end) expect(prot).to receive(:skip).with(Thrift::Types::I32) struct.read(prot) expect(struct.simple).to eq(42) expect(struct.complex).to be_nil expect(struct.words).to eq("foobar") expect(struct.hello).to eq(SpecNamespace::Hello.new(:greeting => 'hello, world!')) expect(struct.ints).to eq([1, 2, 2, 3]) expect(struct.shorts).to eq(Set.new([5, 17, 239])) end it "should write itself to the wire" do prot = Thrift::BaseProtocol.new(double("transport")) # mock("Protocol") expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Foo") expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Hello") expect(prot).to receive(:write_struct_end).twice expect(prot).to receive(:write_field_begin).with('ints', Thrift::Types::LIST, 4) expect(prot).to receive(:write_i32).with(1) expect(prot).to receive(:write_i32).with(2).twice expect(prot).to receive(:write_i32).with(3) expect(prot).to receive(:write_field_begin).with('complex', Thrift::Types::MAP, 5) expect(prot).to receive(:write_i32).with(5) expect(prot).to receive(:write_string).with('foo') expect(prot).to receive(:write_double).with(1.23) expect(prot).to receive(:write_field_begin).with('shorts', Thrift::Types::SET, 6) expect(prot).to receive(:write_i16).with(5) expect(prot).to receive(:write_i16).with(17) expect(prot).to receive(:write_i16).with(239) expect(prot).to receive(:write_field_stop).twice expect(prot).to receive(:write_field_end).exactly(6).times expect(prot).to receive(:write_field_begin).with('simple', Thrift::Types::I32, 1) expect(prot).to receive(:write_i32).with(53) expect(prot).to receive(:write_field_begin).with('hello', Thrift::Types::STRUCT, 3) expect(prot).to receive(:write_field_begin).with('greeting', Thrift::Types::STRING, 1) expect(prot).to receive(:write_string).with('hello, world!') expect(prot).to receive(:write_map_begin).with(Thrift::Types::I32, Thrift::Types::MAP, 1) expect(prot).to receive(:write_map_begin).with(Thrift::Types::STRING, Thrift::Types::DOUBLE, 1) expect(prot).to receive(:write_map_end).twice expect(prot).to receive(:write_list_begin).with(Thrift::Types::I32, 4) expect(prot).to receive(:write_list_end) expect(prot).to receive(:write_set_begin).with(Thrift::Types::I16, 3) expect(prot).to receive(:write_set_end) struct = SpecNamespace::Foo.new struct.words = nil struct.complex = {5 => {"foo" => 1.23}} struct.write(prot) end it "should raise an exception if presented with an unknown container" do # yeah this is silly, but I'm going for code coverage here struct = SpecNamespace::Foo.new expect { struct.send :write_container, nil, nil, {:type => "foo"} }.to raise_error(StandardError, "Not a container type: foo") end it "should support optional type-checking in Thrift::Struct.new" do Thrift.type_checking = true begin expect { SpecNamespace::Hello.new(:greeting => 3) }.to raise_error(Thrift::TypeError, "Expected Types::STRING, received Integer for field greeting") ensure Thrift.type_checking = false end expect { SpecNamespace::Hello.new(:greeting => 3) }.not_to raise_error end it "should support optional type-checking in field accessors" do Thrift.type_checking = true begin hello = SpecNamespace::Hello.new expect { hello.greeting = 3 }.to raise_error(Thrift::TypeError, "Expected Types::STRING, received Integer for field greeting") ensure Thrift.type_checking = false end expect { hello.greeting = 3 }.not_to raise_error end it "should raise an exception when unknown types are given to Thrift::Struct.new" do expect { SpecNamespace::Hello.new(:fish => 'salmon') }.to raise_error(Exception, "Unknown key given to SpecNamespace::Hello.new: fish") end it "should support `raise Xception, 'message'` for Exception structs" do begin raise SpecNamespace::Xception, "something happened" rescue Thrift::Exception => e expect(e.message).to eq("something happened") expect(e.code).to eq(1) # ensure it gets serialized properly, this is the really important part prot = Thrift::BaseProtocol.new(double("trans")) expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Xception") expect(prot).to receive(:write_struct_end) expect(prot).to receive(:write_field_begin).with('message', Thrift::Types::STRING, 1) expect(prot).to receive(:write_string).with("something happened") expect(prot).to receive(:write_field_begin).with('code', Thrift::Types::I32, 2) expect(prot).to receive(:write_i32).with(1) expect(prot).to receive(:write_field_stop) expect(prot).to receive(:write_field_end).twice e.write(prot) end end it "should support the regular initializer for exception structs" do begin raise SpecNamespace::Xception, :message => "something happened", :code => 5 rescue Thrift::Exception => e expect(e.message).to eq("something happened") expect(e.code).to eq(5) prot = Thrift::BaseProtocol.new(double("trans")) expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Xception") expect(prot).to receive(:write_struct_end) expect(prot).to receive(:write_field_begin).with('message', Thrift::Types::STRING, 1) expect(prot).to receive(:write_string).with("something happened") expect(prot).to receive(:write_field_begin).with('code', Thrift::Types::I32, 2) expect(prot).to receive(:write_i32).with(5) expect(prot).to receive(:write_field_stop) expect(prot).to receive(:write_field_end).twice e.write(prot) end end it "should handle UUID fields in structs" do struct = SpecNamespace::Foo.new( simple: 42, words: 'test', opt_uuid: '550e8400-e29b-41d4-a716-446655440000' ) trans = Thrift::MemoryBufferTransport.new prot = Thrift::BinaryProtocol.new(trans) struct.write(prot) result = SpecNamespace::Foo.new result.read(prot) expect(result.simple).to eq(42) expect(result.words).to eq('test') expect(result.opt_uuid).to eq('550e8400-e29b-41d4-a716-446655440000') end it "should handle optional UUID fields when unset" do struct = SpecNamespace::Foo.new(simple: 42, words: 'test') expect(struct.opt_uuid).to be_nil expect(struct.opt_uuid?).to be_falsey end it "should handle list of UUIDs in SimpleList" do uuids = ['550e8400-e29b-41d4-a716-446655440000', '6ba7b810-9dad-11d1-80b4-00c04fd430c8'] struct = SpecNamespace::SimpleList.new(uuids: uuids) trans = Thrift::MemoryBufferTransport.new prot = Thrift::CompactProtocol.new(trans) struct.write(prot) result = SpecNamespace::SimpleList.new result.read(prot) expect(result.uuids).to eq(uuids) end it "should normalize UUID case to lowercase" do struct = SpecNamespace::Foo.new(opt_uuid: '550E8400-E29B-41D4-A716-446655440000') trans = Thrift::MemoryBufferTransport.new prot = Thrift::BinaryProtocol.new(trans) struct.write(prot) result = SpecNamespace::Foo.new result.read(prot) expect(result.opt_uuid).to eq('550e8400-e29b-41d4-a716-446655440000') end it "should handle UUID alongside other types in SimpleList" do struct = SpecNamespace::SimpleList.new( bools: [true, false], i32s: [1, 2, 3], strings: ['hello', 'world'], uuids: ['550e8400-e29b-41d4-a716-446655440000', '00000000-0000-0000-0000-000000000000'] ) trans = Thrift::MemoryBufferTransport.new prot = Thrift::BinaryProtocol.new(trans) struct.write(prot) result = SpecNamespace::SimpleList.new result.read(prot) expect(result.bools).to eq([true, false]) expect(result.i32s).to eq([1, 2, 3]) expect(result.strings).to eq(['hello', 'world']) expect(result.uuids).to eq(['550e8400-e29b-41d4-a716-446655440000', '00000000-0000-0000-0000-000000000000']) end end end thrift-0.23.0/lib/rb/spec/ExtendedService.thrift0000664000175000017500000000161715165535636022010 0ustar00buildbuild00000000000000# 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 rb Extended include "BaseService.thrift" service ExtendedService extends BaseService.BaseService { void ping() } thrift-0.23.0/lib/rb/spec/namespaced_spec.rb0000664000175000017500000000430615167543515021137 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'namespaced generation' do before do require 'namespaced_spec_namespace/namespaced_nonblocking_service' end it "generated the right files" do prefix = File.expand_path("../gen-rb", __FILE__) ["namespaced_spec_namespace/namespaced_nonblocking_service.rb", "namespaced_spec_namespace/thrift_namespaced_spec_constants.rb", "namespaced_spec_namespace/thrift_namespaced_spec_types.rb", "other_namespace/referenced_constants.rb", "other_namespace/referenced_types.rb" ].each do |name| expect(File.exist?(File.join(prefix, name))).to be_truthy end end it "did not generate the wrong files" do prefix = File.expand_path("../gen-rb", __FILE__) ["namespaced_nonblocking_service.rb", "thrift_namespaced_spec_constants.rb", "thrift_namespaced_spec_types.rb", "referenced_constants.rb", "referenced_types.rb" ].each do |name| expect(File.exist?(File.join(prefix, name))).not_to be_truthy end end it "has a service class in the right place" do expect(defined?(NamespacedSpecNamespace::NamespacedNonblockingService)).to be_truthy end it "has a struct in the right place" do expect(defined?(NamespacedSpecNamespace::Hello)).to be_truthy end it "required an included file" do expect(defined?(OtherNamespace::SomeEnum)).to be_truthy end it "extended a service" do require "extended/extended_service" end end thrift-0.23.0/lib/rb/spec/base_protocol_spec.rb0000664000175000017500000002433315167543515021674 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'BaseProtocol' do before(:each) do @trans = double("MockTransport") @prot = Thrift::BaseProtocol.new(@trans) end describe Thrift::BaseProtocol do # most of the methods are stubs, so we can ignore them it "should provide a reasonable to_s" do expect(@trans).to receive(:to_s).once.and_return("trans") expect(@prot.to_s).to eq("trans") end it "should make trans accessible" do expect(@prot.trans).to eql(@trans) end it 'should write out a field nicely (deprecated write_field signature)' do expect(@prot).to receive(:write_field_begin).with('field', 'type', 'fid').ordered expect(@prot).to receive(:write_type).with({:name => 'field', :type => 'type'}, 'value').ordered expect(@prot).to receive(:write_field_end).ordered @prot.write_field('field', 'type', 'fid', 'value') end it 'should write out a field nicely' do expect(@prot).to receive(:write_field_begin).with('field', 'type', 'fid').ordered expect(@prot).to receive(:write_type).with({:name => 'field', :type => 'type', :binary => false}, 'value').ordered expect(@prot).to receive(:write_field_end).ordered @prot.write_field({:name => 'field', :type => 'type', :binary => false}, 'fid', 'value') end it 'should write out the different types (deprecated write_type signature)' do expect(@prot).to receive(:write_bool).with('bool').ordered expect(@prot).to receive(:write_byte).with('byte').ordered expect(@prot).to receive(:write_double).with('double').ordered expect(@prot).to receive(:write_i16).with('i16').ordered expect(@prot).to receive(:write_i32).with('i32').ordered expect(@prot).to receive(:write_i64).with('i64').ordered expect(@prot).to receive(:write_string).with('string').ordered struct = double('Struct') expect(struct).to receive(:write).with(@prot).ordered @prot.write_type(Thrift::Types::BOOL, 'bool') @prot.write_type(Thrift::Types::BYTE, 'byte') @prot.write_type(Thrift::Types::DOUBLE, 'double') @prot.write_type(Thrift::Types::I16, 'i16') @prot.write_type(Thrift::Types::I32, 'i32') @prot.write_type(Thrift::Types::I64, 'i64') @prot.write_type(Thrift::Types::STRING, 'string') @prot.write_type(Thrift::Types::STRUCT, struct) # all other types are not implemented [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type| expect { @prot.write_type(type, type.to_s) }.to raise_error(NotImplementedError) end end it 'should write out the different types' do expect(@prot).to receive(:write_bool).with('bool').ordered expect(@prot).to receive(:write_byte).with('byte').ordered expect(@prot).to receive(:write_double).with('double').ordered expect(@prot).to receive(:write_i16).with('i16').ordered expect(@prot).to receive(:write_i32).with('i32').ordered expect(@prot).to receive(:write_i64).with('i64').ordered expect(@prot).to receive(:write_string).with('string').ordered expect(@prot).to receive(:write_binary).with('binary').ordered struct = double('Struct') expect(struct).to receive(:write).with(@prot).ordered @prot.write_type({:type => Thrift::Types::BOOL}, 'bool') @prot.write_type({:type => Thrift::Types::BYTE}, 'byte') @prot.write_type({:type => Thrift::Types::DOUBLE}, 'double') @prot.write_type({:type => Thrift::Types::I16}, 'i16') @prot.write_type({:type => Thrift::Types::I32}, 'i32') @prot.write_type({:type => Thrift::Types::I64}, 'i64') @prot.write_type({:type => Thrift::Types::STRING}, 'string') @prot.write_type({:type => Thrift::Types::STRING, :binary => true}, 'binary') @prot.write_type({:type => Thrift::Types::STRUCT}, struct) # all other types are not implemented [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST].each do |type| expect { @prot.write_type({:type => type}, type.to_s) }.to raise_error(NotImplementedError) end end it 'should read the different types (deprecated read_type signature)' do expect(@prot).to receive(:read_bool).ordered expect(@prot).to receive(:read_byte).ordered expect(@prot).to receive(:read_i16).ordered expect(@prot).to receive(:read_i32).ordered expect(@prot).to receive(:read_i64).ordered expect(@prot).to receive(:read_double).ordered expect(@prot).to receive(:read_string).ordered @prot.read_type(Thrift::Types::BOOL) @prot.read_type(Thrift::Types::BYTE) @prot.read_type(Thrift::Types::I16) @prot.read_type(Thrift::Types::I32) @prot.read_type(Thrift::Types::I64) @prot.read_type(Thrift::Types::DOUBLE) @prot.read_type(Thrift::Types::STRING) # all other types are not implemented [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type| expect { @prot.read_type(type) }.to raise_error(NotImplementedError) end end it 'should read the different types' do expect(@prot).to receive(:read_bool).ordered expect(@prot).to receive(:read_byte).ordered expect(@prot).to receive(:read_i16).ordered expect(@prot).to receive(:read_i32).ordered expect(@prot).to receive(:read_i64).ordered expect(@prot).to receive(:read_double).ordered expect(@prot).to receive(:read_string).ordered expect(@prot).to receive(:read_binary).ordered @prot.read_type({:type => Thrift::Types::BOOL}) @prot.read_type({:type => Thrift::Types::BYTE}) @prot.read_type({:type => Thrift::Types::I16}) @prot.read_type({:type => Thrift::Types::I32}) @prot.read_type({:type => Thrift::Types::I64}) @prot.read_type({:type => Thrift::Types::DOUBLE}) @prot.read_type({:type => Thrift::Types::STRING}) @prot.read_type({:type => Thrift::Types::STRING, :binary => true}) # all other types are not implemented [Thrift::Types::STOP, Thrift::Types::VOID, Thrift::Types::MAP, Thrift::Types::SET, Thrift::Types::LIST, Thrift::Types::STRUCT].each do |type| expect { @prot.read_type({:type => type}) }.to raise_error(NotImplementedError) end end it "should skip the basic types" do expect(@prot).to receive(:read_bool).ordered expect(@prot).to receive(:read_byte).ordered expect(@prot).to receive(:read_i16).ordered expect(@prot).to receive(:read_i32).ordered expect(@prot).to receive(:read_i64).ordered expect(@prot).to receive(:read_double).ordered expect(@prot).to receive(:read_string).ordered @prot.skip(Thrift::Types::BOOL) @prot.skip(Thrift::Types::BYTE) @prot.skip(Thrift::Types::I16) @prot.skip(Thrift::Types::I32) @prot.skip(Thrift::Types::I64) @prot.skip(Thrift::Types::DOUBLE) @prot.skip(Thrift::Types::STRING) end it "should skip structs" do real_skip = @prot.method(:skip) expect(@prot).to receive(:read_struct_begin).ordered expect(@prot).to receive(:read_field_begin).exactly(4).times.and_return( ['field 1', Thrift::Types::STRING, 1], ['field 2', Thrift::Types::I32, 2], ['field 3', Thrift::Types::MAP, 3], [nil, Thrift::Types::STOP, 0] ) expect(@prot).to receive(:read_field_end).exactly(3).times expect(@prot).to receive(:read_string).exactly(3).times expect(@prot).to receive(:read_i32).ordered expect(@prot).to receive(:read_map_begin).ordered.and_return([Thrift::Types::STRING, Thrift::Types::STRING, 1]) # @prot.should_receive(:read_string).exactly(2).times expect(@prot).to receive(:read_map_end).ordered expect(@prot).to receive(:read_struct_end).ordered real_skip.call(Thrift::Types::STRUCT) end it "should skip maps" do real_skip = @prot.method(:skip) expect(@prot).to receive(:read_map_begin).ordered.and_return([Thrift::Types::STRING, Thrift::Types::STRUCT, 1]) expect(@prot).to receive(:read_string).ordered expect(@prot).to receive(:read_struct_begin).ordered.and_return(["some_struct"]) expect(@prot).to receive(:read_field_begin).ordered.and_return([nil, Thrift::Types::STOP, nil]); expect(@prot).to receive(:read_struct_end).ordered expect(@prot).to receive(:read_map_end).ordered real_skip.call(Thrift::Types::MAP) end it "should skip sets" do real_skip = @prot.method(:skip) expect(@prot).to receive(:read_set_begin).ordered.and_return([Thrift::Types::I64, 9]) expect(@prot).to receive(:read_i64).ordered.exactly(9).times expect(@prot).to receive(:read_set_end) real_skip.call(Thrift::Types::SET) end it "should skip lists" do real_skip = @prot.method(:skip) expect(@prot).to receive(:read_list_begin).ordered.and_return([Thrift::Types::DOUBLE, 11]) expect(@prot).to receive(:read_double).ordered.exactly(11).times expect(@prot).to receive(:read_list_end) real_skip.call(Thrift::Types::LIST) end end describe Thrift::BaseProtocolFactory do it "should raise NotImplementedError" do # returning nil since Protocol is just an abstract class expect { Thrift::BaseProtocolFactory.new.get_protocol(double("MockTransport")) }.to raise_error(NotImplementedError) end it "should provide a reasonable to_s" do expect(Thrift::BaseProtocolFactory.new.to_s).to eq("base") end end end thrift-0.23.0/lib/rb/spec/base_transport_spec.rb0000664000175000017500000003365115167543515022072 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'BaseTransport' do describe Thrift::TransportException do it "should make type accessible" do exc = Thrift::TransportException.new(Thrift::TransportException::ALREADY_OPEN, "msg") expect(exc.type).to eq(Thrift::TransportException::ALREADY_OPEN) expect(exc.message).to eq("msg") end end describe Thrift::BaseTransport do it "should read the specified size" do transport = Thrift::BaseTransport.new expect(transport).to receive(:read).with(40).ordered.and_return("10 letters") expect(transport).to receive(:read).with(30).ordered.and_return("fifteen letters") expect(transport).to receive(:read).with(15).ordered.and_return("more characters") expect(transport.read_all(40)).to eq("10 lettersfifteen lettersmore characters") end it "should stub out the rest of the methods" do # can't test for stubbiness, so just make sure they're defined [:open?, :open, :close, :read, :write, :flush].each do |sym| expect(Thrift::BaseTransport.method_defined?(sym)).to be_truthy end end it "should alias << to write" do expect(Thrift::BaseTransport.instance_method(:<<)).to eq(Thrift::BaseTransport.instance_method(:write)) end it "should provide a reasonable to_s" do expect(Thrift::BaseTransport.new.to_s).to eq("base") end end describe Thrift::BaseServerTransport do it "should stub out its methods" do [:listen, :accept, :close].each do |sym| expect(Thrift::BaseServerTransport.method_defined?(sym)).to be_truthy end end end describe Thrift::BaseTransportFactory do it "should return the transport it's given" do transport = double("Transport") expect(Thrift::BaseTransportFactory.new.get_transport(transport)).to eql(transport) end it "should provide a reasonable to_s" do expect(Thrift::BaseTransportFactory.new.to_s).to eq("base") end end describe Thrift::BufferedTransport do it "should provide a to_s that describes the encapsulation" do trans = double("Transport") expect(trans).to receive(:to_s).and_return("mock") expect(Thrift::BufferedTransport.new(trans).to_s).to eq("buffered(mock)") end it "should pass through everything but write/flush/read" do trans = double("Transport") expect(trans).to receive(:open?).ordered.and_return("+ open?") expect(trans).to receive(:open).ordered.and_return("+ open") expect(trans).to receive(:flush).ordered # from the close expect(trans).to receive(:close).ordered.and_return("+ close") btrans = Thrift::BufferedTransport.new(trans) expect(btrans.open?).to eq("+ open?") expect(btrans.open).to eq("+ open") expect(btrans.close).to eq("+ close") end it "should buffer reads in chunks of #{Thrift::BufferedTransport::DEFAULT_BUFFER}" do trans = double("Transport") expect(trans).to receive(:read).with(Thrift::BufferedTransport::DEFAULT_BUFFER).and_return("lorum ipsum dolor emet") btrans = Thrift::BufferedTransport.new(trans) expect(btrans.read(6)).to eq("lorum ") expect(btrans.read(6)).to eq("ipsum ") expect(btrans.read(6)).to eq("dolor ") expect(btrans.read(6)).to eq("emet") end it "should buffer writes and send them on flush" do trans = double("Transport") btrans = Thrift::BufferedTransport.new(trans) btrans.write("one/") btrans.write("two/") btrans.write("three/") expect(trans).to receive(:write).with("one/two/three/").ordered expect(trans).to receive(:flush).ordered btrans.flush end it "should only send buffered data once" do trans = double("Transport") btrans = Thrift::BufferedTransport.new(trans) btrans.write("one/") btrans.write("two/") btrans.write("three/") expect(trans).to receive(:write).with("one/two/three/") allow(trans).to receive(:flush) btrans.flush # Nothing to flush with no data btrans.flush end it "should flush on close" do trans = double("Transport") expect(trans).to receive(:close) btrans = Thrift::BufferedTransport.new(trans) expect(btrans).to receive(:flush) btrans.close end it "should not write to socket if there's no data" do trans = double("Transport") expect(trans).to receive(:flush) btrans = Thrift::BufferedTransport.new(trans) btrans.flush end end describe Thrift::BufferedTransportFactory do it "should wrap the given transport in a BufferedTransport" do trans = double("Transport") btrans = double("BufferedTransport") expect(Thrift::BufferedTransport).to receive(:new).with(trans).and_return(btrans) expect(Thrift::BufferedTransportFactory.new.get_transport(trans)).to eq(btrans) end it "should provide a reasonable to_s" do expect(Thrift::BufferedTransportFactory.new.to_s).to eq("buffered") end end describe Thrift::FramedTransport do before(:each) do @trans = double("Transport") end it "should provide a to_s that describes the encapsulation" do trans = double("Transport") expect(trans).to receive(:to_s).and_return("mock") expect(Thrift::FramedTransport.new(trans).to_s).to eq("framed(mock)") end it "should pass through open?/open/close" do ftrans = Thrift::FramedTransport.new(@trans) expect(@trans).to receive(:open?).ordered.and_return("+ open?") expect(@trans).to receive(:open).ordered.and_return("+ open") expect(@trans).to receive(:close).ordered.and_return("+ close") expect(ftrans.open?).to eq("+ open?") expect(ftrans.open).to eq("+ open") expect(ftrans.close).to eq("+ close") end it "should pass through read when read is turned off" do ftrans = Thrift::FramedTransport.new(@trans, false, true) expect(@trans).to receive(:read).with(17).ordered.and_return("+ read") expect(ftrans.read(17)).to eq("+ read") end it "should pass through write/flush when write is turned off" do ftrans = Thrift::FramedTransport.new(@trans, true, false) expect(@trans).to receive(:write).with("foo").ordered.and_return("+ write") expect(@trans).to receive(:flush).ordered.and_return("+ flush") expect(ftrans.write("foo")).to eq("+ write") expect(ftrans.flush).to eq("+ flush") end it "should return a full frame if asked for >= the frame's length" do frame = "this is a frame" expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017") expect(@trans).to receive(:read_all).with(frame.length).and_return(frame) expect(Thrift::FramedTransport.new(@trans).read(frame.length + 10)).to eq(frame) end it "should return slices of the frame when asked for < the frame's length" do frame = "this is a frame" expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017") expect(@trans).to receive(:read_all).with(frame.length).and_return(frame) ftrans = Thrift::FramedTransport.new(@trans) expect(ftrans.read(4)).to eq("this") expect(ftrans.read(4)).to eq(" is ") expect(ftrans.read(16)).to eq("a frame") end it "should return nothing if asked for <= 0" do expect(Thrift::FramedTransport.new(@trans).read(-2)).to eq("") end it "should pull a new frame when the first is exhausted" do frame = "this is a frame" frame2 = "yet another frame" expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017", "\000\000\000\021") expect(@trans).to receive(:read_all).with(frame.length).and_return(frame) expect(@trans).to receive(:read_all).with(frame2.length).and_return(frame2) ftrans = Thrift::FramedTransport.new(@trans) expect(ftrans.read(4)).to eq("this") expect(ftrans.read(8)).to eq(" is a fr") expect(ftrans.read(6)).to eq("ame") expect(ftrans.read(4)).to eq("yet ") expect(ftrans.read(16)).to eq("another frame") end it "should buffer writes" do ftrans = Thrift::FramedTransport.new(@trans) expect(@trans).not_to receive(:write) ftrans.write("foo") ftrans.write("bar") ftrans.write("this is a frame") end it "should write slices of the buffer" do ftrans = Thrift::FramedTransport.new(@trans) ftrans.write("foobar", 3) ftrans.write("barfoo", 1) allow(@trans).to receive(:flush) expect(@trans).to receive(:write).with("\000\000\000\004foob") ftrans.flush end it "should flush frames with a 4-byte header" do ftrans = Thrift::FramedTransport.new(@trans) expect(@trans).to receive(:write).with("\000\000\000\035one/two/three/this is a frame").ordered expect(@trans).to receive(:flush).ordered ftrans.write("one/") ftrans.write("two/") ftrans.write("three/") ftrans.write("this is a frame") ftrans.flush end it "should not flush the same buffered data twice" do ftrans = Thrift::FramedTransport.new(@trans) expect(@trans).to receive(:write).with("\000\000\000\007foo/bar") allow(@trans).to receive(:flush) ftrans.write("foo") ftrans.write("/bar") ftrans.flush expect(@trans).to receive(:write).with("\000\000\000\000") ftrans.flush end end describe Thrift::FramedTransportFactory do it "should wrap the given transport in a FramedTransport" do trans = double("Transport") expect(Thrift::FramedTransport).to receive(:new).with(trans) Thrift::FramedTransportFactory.new.get_transport(trans) end it "should provide a reasonable to_s" do expect(Thrift::FramedTransportFactory.new.to_s).to eq("framed") end end describe Thrift::MemoryBufferTransport do before(:each) do @buffer = Thrift::MemoryBufferTransport.new end it "should provide a reasonable to_s" do expect(@buffer.to_s).to eq("memory") end it "should accept a buffer on input and use it directly" do s = "this is a test" @buffer = Thrift::MemoryBufferTransport.new(s) expect(@buffer.read(4)).to eq("this") s.slice!(-4..-1) expect(@buffer.read(@buffer.available)).to eq(" is a ") end it "should always remain open" do expect(@buffer).to be_open @buffer.close expect(@buffer).to be_open end it "should respond to peek and available" do @buffer.write "some data" expect(@buffer.peek).to be_truthy expect(@buffer.available).to eq(9) @buffer.read(4) expect(@buffer.peek).to be_truthy expect(@buffer.available).to eq(5) @buffer.read(5) expect(@buffer.peek).to be_falsey expect(@buffer.available).to eq(0) end it "should be able to reset the buffer" do @buffer.write "test data" @buffer.reset_buffer("foobar") expect(@buffer.available).to eq(6) expect(@buffer.read(@buffer.available)).to eq("foobar") @buffer.reset_buffer expect(@buffer.available).to eq(0) end it "should copy the given string when resetting the buffer" do s = "this is a test" @buffer.reset_buffer(s) expect(@buffer.available).to eq(14) @buffer.read(10) expect(@buffer.available).to eq(4) expect(s).to eq("this is a test") end it "should return from read what was given in write" do @buffer.write "test data" expect(@buffer.read(4)).to eq("test") expect(@buffer.read(@buffer.available)).to eq(" data") @buffer.write "foo" @buffer.write " bar" expect(@buffer.read(@buffer.available)).to eq("foo bar") end it "should throw an EOFError when there isn't enough data in the buffer" do @buffer.reset_buffer("") expect{ @buffer.read(1) }.to raise_error(EOFError) @buffer.reset_buffer("1234") expect{ @buffer.read(5) }.to raise_error(EOFError) end end describe Thrift::IOStreamTransport do before(:each) do @input = double("Input", :closed? => false) @output = double("Output", :closed? => false) @trans = Thrift::IOStreamTransport.new(@input, @output) end it "should provide a reasonable to_s" do expect(@input).to receive(:to_s).and_return("mock_input") expect(@output).to receive(:to_s).and_return("mock_output") expect(@trans.to_s).to eq("iostream(input=mock_input,output=mock_output)") end it "should be open as long as both input or output are open" do expect(@trans).to be_open allow(@input).to receive(:closed?).and_return(true) expect(@trans).to be_open allow(@input).to receive(:closed?).and_return(false) allow(@output).to receive(:closed?).and_return(true) expect(@trans).to be_open allow(@input).to receive(:closed?).and_return(true) expect(@trans).not_to be_open end it "should pass through read/write to input/output" do expect(@input).to receive(:read).with(17).and_return("+ read") expect(@output).to receive(:write).with("foobar").and_return("+ write") expect(@trans.read(17)).to eq("+ read") expect(@trans.write("foobar")).to eq("+ write") end it "should close both input and output when closed" do expect(@input).to receive(:close) expect(@output).to receive(:close) @trans.close end end end thrift-0.23.0/lib/rb/spec/ssl_server_socket_spec.rb0000664000175000017500000000312215167543515022571 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require File.expand_path("#{File.dirname(__FILE__)}/socket_spec_shared") describe 'SSLServerSocket' do describe Thrift::SSLServerSocket do before(:each) do @socket = Thrift::SSLServerSocket.new(1234) end it "should delegate to_io to the underlying SSL server handle" do tcp_server = double("TCPServer") ssl_server = double("SSLServer") allow(TCPServer).to receive(:new).with(nil, 1234).and_return(tcp_server) allow(OpenSSL::SSL::SSLServer).to receive(:new).with(tcp_server, nil).and_return(ssl_server) allow(ssl_server).to receive(:to_io).and_return(tcp_server) @socket.listen expect(@socket.to_io).to eq(tcp_server) end it "should provide a reasonable to_s" do expect(@socket.to_s).to eq("ssl(socket(:1234))") end end end thrift-0.23.0/lib/rb/spec/nonblocking_server_spec.rb0000664000175000017500000002477415170007142022724 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require 'timeout' describe 'NonblockingServer' do class Handler def initialize @queue = Queue.new end attr_accessor :server def greeting(english) if english SpecNamespace::Hello.new else SpecNamespace::Hello.new(:greeting => "Aloha!") end end def block @queue.pop end def unblock(n) n.times { @queue.push true } end def sleep(time) Kernel.sleep time end def shutdown @server.shutdown(0, false) end end class SpecTransport < Thrift::BaseTransport def initialize(transport, queue) @transport = transport @queue = queue @flushed = false end def open? @transport.open? end def open @transport.open end def close @transport.close end def read(sz) @transport.read(sz) end def write(buf, sz = nil) @transport.write(buf, sz) end def flush @queue.push :flushed unless @flushed or @queue.nil? @flushed = true @transport.flush end end class SpecServerSocket < Thrift::ServerSocket def initialize(host, port, queue) super(host, port) @queue = queue end def listen super @queue.push :listen end end describe Thrift::NonblockingServer do before(:each) do @port = 43251 handler = Handler.new processor = SpecNamespace::NonblockingService::Processor.new(handler) queue = Queue.new @transport = SpecServerSocket.new('localhost', @port, queue) transport_factory = Thrift::FramedTransportFactory.new logger = Logger.new(STDERR) logger.level = Logger::WARN @server = Thrift::NonblockingServer.new(processor, @transport, transport_factory, nil, 5, logger) handler.server = @server @server_thread = Thread.new(Thread.current) do |master_thread| begin @server.serve rescue => e p e puts e.backtrace * "\n" master_thread.raise e end end queue.pop @clients = [] @catch_exceptions = false end after(:each) do @clients.each { |client, trans| trans.close } # @server.shutdown(1) @server_thread.kill @transport.close end def setup_client(queue = nil) transport = SpecTransport.new(Thrift::FramedTransport.new(Thrift::Socket.new('localhost', @port)), queue) protocol = Thrift::BinaryProtocol.new(transport) client = SpecNamespace::NonblockingService::Client.new(protocol) transport.open @clients << [client, transport] client end def setup_client_thread(result) queue = Queue.new Thread.new do begin client = setup_client while (cmd = queue.pop) msg, *args = cmd case msg when :block result << client.block when :unblock client.unblock(args.first) when :hello result << client.greeting(true) # ignore result when :sleep client.sleep(args[0] || 0.5) result << :slept when :shutdown client.shutdown when :exit result << :done break end end @clients.each { |c, t| t.close and break if c == client } # close the transport rescue => e raise e unless @catch_exceptions end end queue end it "should handle basic message passing" do client = setup_client expect(client.greeting(true)).to eq(SpecNamespace::Hello.new) expect(client.greeting(false)).to eq(SpecNamespace::Hello.new(:greeting => 'Aloha!')) @server.shutdown end it "should handle concurrent clients" do queue = Queue.new trans_queue = Queue.new 4.times do Thread.new(Thread.current) do |main_thread| begin queue.push setup_client(trans_queue).block rescue => e main_thread.raise e end end end 4.times { trans_queue.pop } setup_client.unblock(4) 4.times { expect(queue.pop).to be_truthy } @server.shutdown end it "should handle messages from more than 5 long-lived connections" do queues = [] result = Queue.new 7.times do |i| queues << setup_client_thread(result) Thread.pass if i == 4 # give the server time to accept connections end client = setup_client # block 4 connections 4.times { |i| queues[i] << :block } queues[4] << :hello queues[5] << :hello queues[6] << :hello 3.times { expect(result.pop).to eq(SpecNamespace::Hello.new) } expect(client.greeting(true)).to eq(SpecNamespace::Hello.new) queues[5] << [:unblock, 4] 4.times { expect(result.pop).to be_truthy } queues[2] << :hello expect(result.pop).to eq(SpecNamespace::Hello.new) expect(client.greeting(false)).to eq(SpecNamespace::Hello.new(:greeting => 'Aloha!')) 7.times { queues.shift << :exit } expect(client.greeting(true)).to eq(SpecNamespace::Hello.new) @server.shutdown end it "should shut down when asked" do # connect first to ensure it's running client = setup_client client.greeting(false) # force a message pass @server.shutdown expect(@server_thread.join(2)).to be_an_instance_of(Thread) end it "should continue processing active messages when shutting down" do result = Queue.new client = setup_client_thread(result) client << :sleep sleep 0.1 # give the server time to start processing the client's message @server.shutdown expect(@server_thread.join(2)).to be_an_instance_of(Thread) expect(result.pop).to eq(:slept) end it "should kill active messages when they don't expire while shutting down" do result = Queue.new client = setup_client_thread(result) client << [:sleep, 10.0] sleep 0.1 # start processing the client's message @server.shutdown(1) @catch_exceptions = true expect(@server_thread.join(3)).not_to be_nil expect(result).to be_empty end it "should allow shutting down in response to a message" do client = setup_client expect(client.greeting(true)).to eq(SpecNamespace::Hello.new) client.shutdown expect(@server_thread.join(2)).not_to be_nil end end describe "#{Thrift::NonblockingServer} with TLS transport" do before(:each) do @port = available_port handler = Handler.new processor = SpecNamespace::NonblockingService::Processor.new(handler) @transport = Thrift::SSLServerSocket.new('localhost', @port, create_server_ssl_context) transport_factory = Thrift::FramedTransportFactory.new logger = Logger.new(STDERR) logger.level = Logger::WARN @server = Thrift::NonblockingServer.new(processor, @transport, transport_factory, nil, 5, logger) handler.server = @server @server_thread = Thread.new(Thread.current) do |master_thread| begin @server.serve rescue => e master_thread.raise e end end @clients = [] wait_until_listening end after(:each) do @clients.each(&:close) @server.shutdown if @server @server_thread.join(2) if @server_thread @transport.close if @transport end it "should handle requests over TLS" do expect(@server_thread).to be_alive client = setup_tls_client expect(client.greeting(true)).to eq(SpecNamespace::Hello.new) @server.shutdown expect(@server_thread.join(2)).to be_an_instance_of(Thread) end def setup_tls_client transport = Thrift::FramedTransport.new( Thrift::SSLSocket.new('localhost', @port, nil, create_client_ssl_context) ) protocol = Thrift::BinaryProtocol.new(transport) client = SpecNamespace::NonblockingService::Client.new(protocol) transport.open @clients << transport client end def wait_until_listening Timeout.timeout(2) do until @transport.handle raise "Server thread exited unexpectedly" unless @server_thread.alive? sleep 0.01 end end end def available_port TCPServer.open('localhost', 0) { |server| server.addr[1] } end def ssl_keys_dir File.expand_path('../../../test/keys', __dir__) end def create_server_ssl_context OpenSSL::SSL::SSLContext.new.tap do |ctx| ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER if ctx.respond_to?(:min_version=) && OpenSSL::SSL.const_defined?(:TLS1_2_VERSION) ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION end ctx.ca_file = File.join(ssl_keys_dir, 'CA.pem') ctx.cert = OpenSSL::X509::Certificate.new(File.read(File.join(ssl_keys_dir, 'server.crt'))) ctx.cert_store = OpenSSL::X509::Store.new ctx.cert_store.add_file(File.join(ssl_keys_dir, 'client.pem')) ctx.key = OpenSSL::PKey::RSA.new(File.read(File.join(ssl_keys_dir, 'server.key'))) end end def create_client_ssl_context OpenSSL::SSL::SSLContext.new.tap do |ctx| ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER if ctx.respond_to?(:min_version=) && OpenSSL::SSL.const_defined?(:TLS1_2_VERSION) ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION end ctx.ca_file = File.join(ssl_keys_dir, 'CA.pem') ctx.cert = OpenSSL::X509::Certificate.new(File.read(File.join(ssl_keys_dir, 'client.crt'))) ctx.cert_store = OpenSSL::X509::Store.new ctx.cert_store.add_file(File.join(ssl_keys_dir, 'server.pem')) ctx.key = OpenSSL::PKey::RSA.new(File.read(File.join(ssl_keys_dir, 'client.key'))) end end end end thrift-0.23.0/lib/rb/spec/http_client_spec.rb0000664000175000017500000001351315167543515021354 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Thrift::HTTPClientTransport' do describe Thrift::HTTPClientTransport do before(:each) do @client = Thrift::HTTPClientTransport.new("http://my.domain.com/path/to/service?param=value") end it "should provide a reasonable to_s" do @client.to_s == "http://my.domain.com/path/to/service?param=value" end it "should always be open" do expect(@client).to be_open @client.close expect(@client).to be_open end it "should post via HTTP and return the results" do @client.write "a test" @client.write " frame" expect(Net::HTTP).to receive(:new).with("my.domain.com", 80) do double("Net::HTTP").tap do |http| expect(http).to receive(:use_ssl=).with(false) expect(http).to receive(:post).with("/path/to/service?param=value", "a test frame", {"Content-Type"=>"application/x-thrift"}) do double("Net::HTTPOK").tap do |response| expect(response).to receive(:body).and_return "data" expect(response).to receive(:code).and_return "200" end end end end @client.flush expect(@client.read(10)).to eq("data") end it "should send custom headers if defined" do @client.write "test" custom_headers = {"Cookie" => "Foo"} headers = {"Content-Type"=>"application/x-thrift"}.merge(custom_headers) @client.add_headers(custom_headers) expect(Net::HTTP).to receive(:new).with("my.domain.com", 80) do double("Net::HTTP").tap do |http| expect(http).to receive(:use_ssl=).with(false) expect(http).to receive(:post).with("/path/to/service?param=value", "test", headers) do double("Net::HTTPOK").tap do |response| expect(response).to receive(:body).and_return "data" expect(response).to receive(:code).and_return "200" end end end end @client.flush end it 'should reset the outbuf on HTTP failures' do @client.write "test" expect(Net::HTTP).to receive(:new).with("my.domain.com", 80) do double("Net::HTTP").tap do |http| expect(http).to receive(:use_ssl=).with(false) expect(http).to receive(:post).with("/path/to/service?param=value", "test", {"Content-Type"=>"application/x-thrift"}) { raise Net::ReadTimeout } end end @client.flush rescue expect(@client.instance_variable_get(:@outbuf)).to eq(Thrift::Bytes.empty_byte_buffer) end it 'should raise TransportError on HTTP failures' do @client.write "test" expect(Net::HTTP).to receive(:new).with("my.domain.com", 80) do double("Net::HTTP").tap do |http| expect(http).to receive(:use_ssl=).with(false) expect(http).to receive(:post).with("/path/to/service?param=value", "test", {"Content-Type"=>"application/x-thrift"}) do double("Net::HTTPOK").tap do |response| expect(response).not_to receive(:body) expect(response).to receive(:code).at_least(:once).and_return "503" end end end end expect { @client.flush }.to raise_error(Thrift::TransportException) end end describe 'ssl enabled' do before(:each) do @service_path = "/path/to/service?param=value" @server_uri = "https://my.domain.com" end it "should use SSL for https" do client = Thrift::HTTPClientTransport.new("#{@server_uri}#{@service_path}") client.write "test" expect(Net::HTTP).to receive(:new).with("my.domain.com", 443) do double("Net::HTTP").tap do |http| expect(http).to receive(:use_ssl=).with(true) expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER) expect(http).to receive(:post).with(@service_path, "test", {"Content-Type" => "application/x-thrift"}) do double("Net::HTTPOK").tap do |response| expect(response).to receive(:body).and_return "data" expect(response).to receive(:code).and_return "200" end end end end client.flush expect(client.read(4)).to eq("data") end it "should set SSL verify mode when specified" do client = Thrift::HTTPClientTransport.new("#{@server_uri}#{@service_path}", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) client.write "test" expect(Net::HTTP).to receive(:new).with("my.domain.com", 443) do double("Net::HTTP").tap do |http| expect(http).to receive(:use_ssl=).with(true) expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE) expect(http).to receive(:post).with(@service_path, "test", {"Content-Type" => "application/x-thrift"}) do double("Net::HTTPOK").tap do |response| expect(response).to receive(:body).and_return "data" expect(response).to receive(:code).and_return "200" end end end end client.flush expect(client.read(4)).to eq("data") end end end thrift-0.23.0/lib/rb/spec/struct_nested_containers_spec.rb0000664000175000017500000001440415167543515024152 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'StructNestedContainers' do def with_type_checking saved_type_checking, Thrift.type_checking = Thrift.type_checking, true begin yield ensure Thrift.type_checking = saved_type_checking end end describe Thrift::Struct do # Nested container tests, see THRIFT-369. it "should support nested lists inside lists" do with_type_checking do a, b = SpecNamespace::NestedListInList.new, SpecNamespace::NestedListInList.new [a, b].each do |thrift_struct| thrift_struct.value = [ [1, 2, 3], [2, 3, 4] ] thrift_struct.validate end expect(a).to eq(b) b.value.push [3, 4, 5] expect(a).not_to eq(b) end end it "should support nested lists inside sets" do with_type_checking do a, b = SpecNamespace::NestedListInSet.new, SpecNamespace::NestedListInSet.new [a, b].each do |thrift_struct| thrift_struct.value = [ [1, 2, 3], [2, 3, 4] ].to_set thrift_struct.validate end expect(a).to eq(b) b.value.add [3, 4, 5] expect(a).not_to eq(b) end end it "should support nested lists in map keys" do with_type_checking do a, b = SpecNamespace::NestedListInMapKey.new, SpecNamespace::NestedListInMapKey.new [a, b].each do |thrift_struct| thrift_struct.value = { [1, 2, 3] => 1, [2, 3, 4] => 2 } thrift_struct.validate end expect(a).to eq(b) b.value[[3, 4, 5]] = 3 expect(a).not_to eq(b) end end it "should support nested lists in map values" do with_type_checking do a, b = SpecNamespace::NestedListInMapValue.new, SpecNamespace::NestedListInMapValue.new [a, b].each do |thrift_struct| thrift_struct.value = { 1 => [1, 2, 3], 2 => [2, 3, 4] } thrift_struct.validate end expect(a).to eq(b) b.value[3] = [3, 4, 5] expect(a).not_to eq(b) end end it "should support nested sets inside lists" do with_type_checking do a, b = SpecNamespace::NestedSetInList.new, SpecNamespace::NestedSetInList.new [a, b].each do |thrift_struct| thrift_struct.value = [ [1, 2, 3].to_set, [2, 3, 4].to_set ] thrift_struct.validate end expect(a).to eq(b) b.value.push([3, 4, 5].to_set) expect(a).not_to eq(b) end end it "should support nested sets inside sets" do with_type_checking do a, b = SpecNamespace::NestedSetInSet.new, SpecNamespace::NestedSetInSet.new [a, b].each do |thrift_struct| thrift_struct.value = [ [1, 2, 3].to_set, [2, 3, 4].to_set ].to_set thrift_struct.validate end expect(a).to eq(b) b.value.add([3, 4, 5].to_set) expect(a).not_to eq(b) end end it "should support nested sets in map keys" do with_type_checking do a, b = SpecNamespace::NestedSetInMapKey.new, SpecNamespace::NestedSetInMapKey.new [a, b].each do |thrift_struct| thrift_struct.value = { [1, 2, 3].to_set => 1, [2, 3, 4].to_set => 2 } thrift_struct.validate end expect(a).to eq(b) b.value[[3, 4, 5].to_set] = 3 expect(a).not_to eq(b) end end it "should support nested sets in map values" do with_type_checking do a, b = SpecNamespace::NestedSetInMapValue.new, SpecNamespace::NestedSetInMapValue.new [a, b].each do |thrift_struct| thrift_struct.value = { 1 => [1, 2, 3].to_set, 2 => [2, 3, 4].to_set } thrift_struct.validate end expect(a).to eq(b) b.value[3] = [3, 4, 5].to_set expect(a).not_to eq(b) end end it "should support nested maps inside lists" do with_type_checking do a, b = SpecNamespace::NestedMapInList.new, SpecNamespace::NestedMapInList.new [a, b].each do |thrift_struct| thrift_struct.value = [ {1 => 2, 3 => 4}, {2 => 3, 4 => 5} ] thrift_struct.validate end expect(a).to eq(b) b.value.push({ 3 => 4, 5 => 6 }) expect(a).not_to eq(b) end end it "should support nested maps inside sets" do with_type_checking do a, b = SpecNamespace::NestedMapInSet.new, SpecNamespace::NestedMapInSet.new [a, b].each do |thrift_struct| thrift_struct.value = [ {1 => 2, 3 => 4}, {2 => 3, 4 => 5} ].to_set thrift_struct.validate end expect(a).to eq(b) b.value.add({ 3 => 4, 5 => 6 }) expect(a).not_to eq(b) end end it "should support nested maps in map keys" do with_type_checking do a, b = SpecNamespace::NestedMapInMapKey.new, SpecNamespace::NestedMapInMapKey.new [a, b].each do |thrift_struct| thrift_struct.value = { { 1 => 2, 3 => 4} => 1, {2 => 3, 4 => 5} => 2 } thrift_struct.validate end expect(a).to eq(b) b.value[{3 => 4, 5 => 6}] = 3 expect(a).not_to eq(b) end end it "should support nested maps in map values" do with_type_checking do a, b = SpecNamespace::NestedMapInMapValue.new, SpecNamespace::NestedMapInMapValue.new [a, b].each do |thrift_struct| thrift_struct.value = { 1 => { 1 => 2, 3 => 4}, 2 => {2 => 3, 4 => 5} } thrift_struct.validate end expect(a).to eq(b) b.value[3] = { 3 => 4, 5 => 6 } expect(a).not_to eq(b) end end end end thrift-0.23.0/lib/rb/spec/ThriftNamespacedSpec.thrift0000664000175000017500000000354115165535636022761 0ustar00buildbuild00000000000000/* * 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. */ # # 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 rb NamespacedSpecNamespace include "Referenced.thrift" struct Hello { 1: string greeting = "hello world" } service NamespacedNonblockingService { Hello greeting(1:bool english) bool block() oneway void unblock(1:i32 n) oneway void shutdown() void sleep(1:double seconds) } thrift-0.23.0/lib/rb/spec/uuid_validation_spec.rb0000664000175000017500000002061715167543515022222 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'UUID Validation' do protocols = [ ['BinaryProtocol', Thrift::BinaryProtocol], ] if defined?(Thrift::BinaryProtocolAccelerated) protocols << ['BinaryProtocolAccelerated', Thrift::BinaryProtocolAccelerated] end protocols << ['CompactProtocol', Thrift::CompactProtocol] protocols << ['JsonProtocol', Thrift::JsonProtocol] protocols.each do |protocol_name, protocol_class| describe protocol_name do before(:each) do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) end context 'valid UUIDs' do it 'should accept lowercase UUIDs' do uuid = '550e8400-e29b-41d4-a716-446655440000' expect { @prot.write_uuid(uuid) }.not_to raise_error result = @prot.read_uuid expect(result).to eq(uuid) end it 'should accept uppercase UUIDs' do uuid = '550E8400-E29B-41D4-A716-446655440000' expect { @prot.write_uuid(uuid) }.not_to raise_error result = @prot.read_uuid # Result should be lowercase expect(result).to eq('550e8400-e29b-41d4-a716-446655440000') end it 'should accept mixed case UUIDs' do uuid = '550e8400-E29B-41d4-A716-446655440000' expect { @prot.write_uuid(uuid) }.not_to raise_error result = @prot.read_uuid expect(result).to eq('550e8400-e29b-41d4-a716-446655440000') end it 'should accept all zeros' do uuid = '00000000-0000-0000-0000-000000000000' expect { @prot.write_uuid(uuid) }.not_to raise_error result = @prot.read_uuid expect(result).to eq(uuid) end it 'should accept all fs' do uuid = 'ffffffff-ffff-ffff-ffff-ffffffffffff' expect { @prot.write_uuid(uuid) }.not_to raise_error result = @prot.read_uuid expect(result).to eq(uuid) end end context 'invalid UUIDs' do def expect_invalid_uuid(value, message) expect { @prot.write_uuid(value) }.to raise_error(Thrift::ProtocolException) do |error| expect(error.type).to eq(Thrift::ProtocolException::INVALID_DATA) expect(error.message).to eq(message) end end it 'should reject nil' do expect_invalid_uuid(nil, 'UUID must be a string') end it 'should reject non-string' do expect_invalid_uuid(12345, 'UUID must be a string') end it 'should reject wrong length' do expect_invalid_uuid('550e8400-e29b-41d4-a716', 'Invalid UUID format') end it 'should reject missing hyphens' do expect_invalid_uuid('550e8400e29b41d4a716446655440000', 'Invalid UUID format') end it 'should reject hyphens in wrong positions' do expect_invalid_uuid('550e840-0e29b-41d4-a716-446655440000', 'Invalid UUID format') end it 'should reject invalid hex characters (g)' do expect_invalid_uuid('550e8400-e29b-41d4-a716-44665544000g', 'Invalid UUID format') end it 'should reject invalid hex characters (z)' do expect_invalid_uuid('z50e8400-e29b-41d4-a716-446655440000', 'Invalid UUID format') end it 'should reject invalid hex characters (space)' do expect_invalid_uuid('550e8400-e29b-41d4-a716-44665544000 ', 'Invalid UUID format') end it 'should reject empty string' do expect_invalid_uuid('', 'Invalid UUID format') end it 'should reject UUID with extra characters' do expect_invalid_uuid('550e8400-e29b-41d4-a716-446655440000x', 'Invalid UUID format') end it 'should reject trailing hyphen' do expect_invalid_uuid('550e8400-e29b-41d4-a716-44665544000-', 'Invalid UUID format') end it 'should reject hyphen inside hex pair' do expect_invalid_uuid('550e8400-e29b-41d4-a716-4466-5544000', 'Invalid UUID format') end end context 'malformed binary data on read' do it 'should raise error on truncated data' do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) # Write only 10 bytes instead of 16 if protocol_class == Thrift::JsonProtocol @trans.write('"00000000-0000-0000-0000"') else @trans.write("\x00" * 10) end expect { @prot.read_uuid }.to raise_error(EOFError) end it 'should raise error on 15 bytes (one byte short)' do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) if protocol_class == Thrift::JsonProtocol @trans.write('"00000000-0000-0000-0000-000000000"') else @trans.write("\x00" * 15) end expect { @prot.read_uuid }.to raise_error(EOFError) end it 'should raise error on empty buffer' do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) expect { @prot.read_uuid }.to raise_error(EOFError) end end context 'multiple UUIDs in sequence' do it 'should handle 10 UUIDs in sequence' do uuids = 10.times.map { |i| sprintf('%08x-0000-0000-0000-000000000000', i) } @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) uuids.each { |uuid| @prot.write_uuid(uuid) } results = 10.times.map { @prot.read_uuid } expect(results).to eq(uuids) end it 'should handle UUIDs interleaved with other types' do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 0) @prot.write_i32(42) @prot.write_uuid('550e8400-e29b-41d4-a716-446655440000') @prot.write_string('test') @prot.write_uuid('6ba7b810-9dad-11d1-80b4-00c04fd430c8') @prot.write_i64(123456789) @prot.write_message_end @prot.read_message_begin expect(@prot.read_i32).to eq(42) expect(@prot.read_uuid).to eq('550e8400-e29b-41d4-a716-446655440000') expect(@prot.read_string).to eq('test') expect(@prot.read_uuid).to eq('6ba7b810-9dad-11d1-80b4-00c04fd430c8') expect(@prot.read_i64).to eq(123456789) @prot.read_message_end end it 'should handle UUIDs in struct fields context' do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) # Simulate struct field headers @prot.write_struct_begin('test') @prot.write_field_begin('uuid1', Thrift::Types::UUID, 1) @prot.write_uuid('550e8400-e29b-41d4-a716-446655440000') @prot.write_field_end @prot.write_field_begin('uuid2', Thrift::Types::UUID, 2) @prot.write_uuid('6ba7b810-9dad-11d1-80b4-00c04fd430c8') @prot.write_field_end @prot.write_field_stop @prot.write_struct_end @prot.read_struct_begin name, type, id = @prot.read_field_begin expect(type).to eq(Thrift::Types::UUID) expect(@prot.read_uuid).to eq('550e8400-e29b-41d4-a716-446655440000') @prot.read_field_end name, type, id = @prot.read_field_begin expect(type).to eq(Thrift::Types::UUID) expect(@prot.read_uuid).to eq('6ba7b810-9dad-11d1-80b4-00c04fd430c8') @prot.read_field_end name, type, id = @prot.read_field_begin expect(type).to eq(Thrift::Types::STOP) end end end end end thrift-0.23.0/lib/rb/spec/ssl_socket_spec.rb0000664000175000017500000000726515167543515021217 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require File.expand_path("#{File.dirname(__FILE__)}/socket_spec_shared") describe 'SSLSocket' do describe Thrift::SSLSocket do before(:each) do @context = OpenSSL::SSL::SSLContext.new @socket = Thrift::SSLSocket.new @simple_socket_handle = double("Handle", :closed? => false) allow(@simple_socket_handle).to receive(:close) allow(@simple_socket_handle).to receive(:connect_nonblock) allow(@simple_socket_handle).to receive(:setsockopt) @handle = double(double("SSLHandle", :connect_nonblock => true, :post_connection_check => true), :closed? => false) allow(@handle).to receive(:connect_nonblock) allow(@handle).to receive(:close) allow(@handle).to receive(:post_connection_check) allow(@handle).to receive(:to_io).and_return(@simple_socket_handle) allow(::Socket).to receive(:new).and_return(@simple_socket_handle) allow(OpenSSL::SSL::SSLSocket).to receive(:new).and_return(@handle) end it_should_behave_like "a socket" it "should raise a TransportException when it cannot open a ssl socket" do expect(::Socket).to receive(:getaddrinfo).with("localhost", 9090, nil, ::Socket::SOCK_STREAM).and_return([[]]) expect { @socket.open }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } end it "should open a ::Socket with default args" do expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(@simple_socket_handle, nil).and_return(@handle) expect(@handle).to receive(:post_connection_check).with('localhost') @socket.open end it "should accept host/port options" do handle = double("Handle", :connect_nonblock => true, :setsockopt => nil) allow(::Socket).to receive(:new).and_return(handle) expect(::Socket).to receive(:getaddrinfo).with("my.domain", 1234, nil, ::Socket::SOCK_STREAM).and_return([[]]) expect(::Socket).to receive(:sockaddr_in) expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(handle, nil).and_return(@handle) expect(@handle).to receive(:post_connection_check).with('my.domain') Thrift::SSLSocket.new('my.domain', 1234, 6000, nil).open end it "should accept an optional timeout" do expect(Thrift::SSLSocket.new('localhost', 8080, 5).timeout).to eq(5) end it "should accept an optional context" do expect(Thrift::SSLSocket.new('localhost', 8080, 5, @context).ssl_context).to eq(@context) end it "should delegate to_io to the underlying SSL socket handle" do @socket.open expect(@socket.to_io).to eq(@simple_socket_handle) end it "should raise IOError when to_io is called on a closed stream" do expect { @socket.to_io }.to raise_error(IOError, 'closed stream') end it "should provide a reasonable to_s" do expect(Thrift::SSLSocket.new('myhost', 8090).to_s).to eq("ssl(socket(myhost:8090))") end end end thrift-0.23.0/lib/rb/spec/binary_protocol_spec_shared.rb0000664000175000017500000003567115167543515023603 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'spec_helper' shared_examples_for 'a binary protocol' do before(:each) do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) end it "should define the proper VERSION_1, VERSION_MASK AND TYPE_MASK" do expect(protocol_class.const_get(:VERSION_MASK)).to eq(0xffff0000) expect(protocol_class.const_get(:VERSION_1)).to eq(0x80010000) expect(protocol_class.const_get(:TYPE_MASK)).to eq(0x000000ff) end it "should make strict_read readable" do expect(@prot.strict_read).to eql(true) end it "should make strict_write readable" do expect(@prot.strict_write).to eql(true) end it "should write the message header" do @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17) expect(@trans.read(@trans.available)).to eq([protocol_class.const_get(:VERSION_1) | Thrift::MessageTypes::CALL, "testMessage".size, "testMessage", 17].pack("NNa11N")) end it "should write the message header without version when writes are not strict" do @prot = protocol_class.new(@trans, true, false) # no strict write @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17) expect(@trans.read(@trans.available)).to eq("\000\000\000\vtestMessage\001\000\000\000\021") end it "should write the message header with a version when writes are strict" do @prot = protocol_class.new(@trans) # strict write @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17) expect(@trans.read(@trans.available)).to eq("\200\001\000\001\000\000\000\vtestMessage\000\000\000\021") end # message footer is a noop it "should write the field header" do @prot.write_field_begin('foo', Thrift::Types::DOUBLE, 3) expect(@trans.read(@trans.available)).to eq([Thrift::Types::DOUBLE, 3].pack("cn")) end # field footer is a noop it "should write the STOP field" do @prot.write_field_stop expect(@trans.read(1)).to eq("\000") end it "should write the map header" do @prot.write_map_begin(Thrift::Types::STRING, Thrift::Types::LIST, 17) expect(@trans.read(@trans.available)).to eq([Thrift::Types::STRING, Thrift::Types::LIST, 17].pack("ccN")); end # map footer is a noop it "should write the list header" do @prot.write_list_begin(Thrift::Types::I16, 42) expect(@trans.read(@trans.available)).to eq([Thrift::Types::I16, 42].pack("cN")) end # list footer is a noop it "should write the set header" do @prot.write_set_begin(Thrift::Types::I16, 42) expect(@trans.read(@trans.available)).to eq([Thrift::Types::I16, 42].pack("cN")) end it "should write a bool" do @prot.write_bool(true) @prot.write_bool(false) expect(@trans.read(@trans.available)).to eq("\001\000") end it "should treat a nil bool as false" do @prot.write_bool(nil) expect(@trans.read(1)).to eq("\000") end it "should write a byte" do # byte is small enough, let's check -128..127 (-128..127).each do |i| @prot.write_byte(i) expect(@trans.read(1)).to eq([i].pack('c')) end end it "should clip numbers out of signed range" do (128..255).each do |i| @prot.write_byte(i) expect(@trans.read(1)).to eq([i].pack('c')) end end it "errors out with a Bignum" do expect { @prot.write_byte(2**65) }.to raise_error(RangeError) end it "should error gracefully when trying to write a nil byte" do expect { @prot.write_byte(nil) }.to raise_error(StandardError, 'nil argument not allowed!') end it "should write an i16" do # try a random scattering of values # include the signed i16 minimum/maximum [-2**15, -1024, 17, 0, -10000, 1723, 2**15-1].each do |i| @prot.write_i16(i) end # and try something out of signed range, it should clip @prot.write_i16(2**15 + 5) expect(@trans.read(@trans.available)).to eq("\200\000\374\000\000\021\000\000\330\360\006\273\177\377\200\005") # a Bignum should error # lambda { @prot.write_i16(2**65) }.should raise_error(RangeError) end it "should error gracefully when trying to write a nil i16" do expect { @prot.write_i16(nil) }.to raise_error(StandardError, 'nil argument not allowed!') end it "should write an i32" do # try a random scattering of values # include the signed i32 minimum/maximum [-2**31, -123123, -2532, -3, 0, 2351235, 12331, 2**31-1].each do |i| @prot.write_i32(i) end # try something out of signed range, it should clip expect(@trans.read(@trans.available)).to eq("\200\000\000\000" + "\377\376\037\r" + "\377\377\366\034" + "\377\377\377\375" + "\000\000\000\000" + "\000#\340\203" + "\000\0000+" + "\177\377\377\377") [2 ** 31 + 5, 2 ** 65 + 5].each do |i| expect { @prot.write_i32(i) }.to raise_error(RangeError) end end it "should error gracefully when trying to write a nil i32" do expect { @prot.write_i32(nil) }.to raise_error(StandardError, 'nil argument not allowed!') end it "should write an i64" do # try a random scattering of values # try the signed i64 minimum/maximum [-2**63, -12356123612323, -23512351, -234, 0, 1231, 2351236, 12361236213, 2**63-1].each do |i| @prot.write_i64(i) end # try something out of signed range, it should clip expect(@trans.read(@trans.available)).to eq(["\200\000\000\000\000\000\000\000", "\377\377\364\303\035\244+]", "\377\377\377\377\376\231:\341", "\377\377\377\377\377\377\377\026", "\000\000\000\000\000\000\000\000", "\000\000\000\000\000\000\004\317", "\000\000\000\000\000#\340\204", "\000\000\000\002\340\311~\365", "\177\377\377\377\377\377\377\377"].join("")) expect { @prot.write_i64(2 ** 65 + 5) }.to raise_error(RangeError) end it "should error gracefully when trying to write a nil i64" do expect { @prot.write_i64(nil) }.to raise_error(StandardError, 'nil argument not allowed!') end it "should write a double" do # try a random scattering of values, including min/max values = [Float::MIN, -1231.15325, -123123.23, -23.23515123, 0, 12351.1325, 523.23, Float::MAX] values.each do |f| @prot.write_double(f) expect(@trans.read(@trans.available)).to eq([f].pack("G")) end end it "should error gracefully when trying to write a nil double" do expect { @prot.write_double(nil) }.to raise_error(StandardError, 'nil argument not allowed!') end it 'should write a string' do str = 'abc' @prot.write_string(str) a = @trans.read(@trans.available) expect(a.encoding).to eq(Encoding::BINARY) expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63]) end it 'should write a string with unicode characters' do str = "abc \u20AC \u20AD".encode('UTF-8') @prot.write_string(str) a = @trans.read(@trans.available) expect(a.encoding).to eq(Encoding::BINARY) expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x0B, 0x61, 0x62, 0x63, 0x20, 0xE2, 0x82, 0xAC, 0x20, 0xE2, 0x82, 0xAD]) end it 'should write should write a string with unicode characters and transcoding' do str = "abc \u20AC".encode('ISO-8859-15') @prot.write_string(str) a = @trans.read(@trans.available) expect(a.encoding).to eq(Encoding::BINARY) expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x07, 0x61, 0x62, 0x63, 0x20, 0xE2, 0x82, 0xAC]) end it 'should write a binary string' do buffer = [0, 1, 2, 3].pack('C*') @prot.write_binary(buffer) a = @trans.read(@trans.available) expect(a.encoding).to eq(Encoding::BINARY) expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03]) end it "should error gracefully when trying to write a nil string" do expect { @prot.write_string(nil) }.to raise_error(StandardError, 'nil argument not allowed!') end it "should error gracefully when trying to write a nil binary" do expect { @prot.write_binary(nil) }.to raise_error(StandardError, 'nil argument not allowed!') end it "should write a uuid" do @prot.write_uuid("00112233-4455-6677-8899-aabbccddeeff") a = @trans.read(@trans.available) expect(a.unpack('C*')).to eq([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]) end it "should read a uuid" do @trans.write([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff].pack('C*')) uuid = @prot.read_uuid expect(uuid).to eq("00112233-4455-6677-8899-aabbccddeeff") end it "should error gracefully when trying to write an invalid uuid" do expect { @prot.write_uuid("invalid") }.to raise_error(Thrift::ProtocolException) end it "should write the message header without version when writes are not strict" do @prot = protocol_class.new(@trans, true, false) # no strict write @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17) expect(@trans.read(@trans.available)).to eq("\000\000\000\vtestMessage\001\000\000\000\021") end it "should write the message header with a version when writes are strict" do @prot = protocol_class.new(@trans) # strict write @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17) expect(@trans.read(@trans.available)).to eq("\200\001\000\001\000\000\000\vtestMessage\000\000\000\021") end # message footer is a noop it "should read a field header" do @trans.write([Thrift::Types::STRING, 3].pack("cn")) expect(@prot.read_field_begin).to eq([nil, Thrift::Types::STRING, 3]) end # field footer is a noop it "should read a stop field" do @trans.write([Thrift::Types::STOP].pack("c")); expect(@prot.read_field_begin).to eq([nil, Thrift::Types::STOP, 0]) end it "should read a map header" do @trans.write([Thrift::Types::DOUBLE, Thrift::Types::I64, 42].pack("ccN")) expect(@prot.read_map_begin).to eq([Thrift::Types::DOUBLE, Thrift::Types::I64, 42]) end # map footer is a noop it "should read a list header" do @trans.write([Thrift::Types::STRING, 17].pack("cN")) expect(@prot.read_list_begin).to eq([Thrift::Types::STRING, 17]) end # list footer is a noop it "should read a set header" do @trans.write([Thrift::Types::STRING, 17].pack("cN")) expect(@prot.read_set_begin).to eq([Thrift::Types::STRING, 17]) end # set footer is a noop it "should read a bool" do @trans.write("\001\000"); expect(@prot.read_bool).to eq(true) expect(@prot.read_bool).to eq(false) end it "should read a byte" do [-128, -57, -3, 0, 17, 24, 127].each do |i| @trans.write([i].pack("c")) expect(@prot.read_byte).to eq(i) end end it "should read an i16" do # try a scattering of values, including min/max [-2**15, -5237, -353, 0, 1527, 2234, 2**15-1].each do |i| @trans.write([i].pack("n")); expect(@prot.read_i16).to eq(i) end end it "should read an i32" do # try a scattering of values, including min/max [-2**31, -235125, -6236, 0, 2351, 123123, 2**31-1].each do |i| @trans.write([i].pack("N")) expect(@prot.read_i32).to eq(i) end end it "should read an i64" do # try a scattering of values, including min/max [-2**63, -123512312, -6346, 0, 32, 2346322323, 2**63-1].each do |i| @trans.write([i >> 32, i & 0xFFFFFFFF].pack("NN")) expect(@prot.read_i64).to eq(i) end end it "should read a double" do # try a random scattering of values, including min/max [Float::MIN, -231231.12351, -323.233513, 0, 123.2351235, 2351235.12351235, Float::MAX].each do |f| @trans.write([f].pack("G")); expect(@prot.read_double).to eq(f) end end it 'should read a string' do # i32 of value 3, followed by three characters/UTF-8 bytes 'a', 'b', 'c' buffer = [0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63].pack('C*') @trans.write(buffer) a = @prot.read_string expect(a).to eq('abc'.encode('UTF-8')) expect(a.encoding).to eq(Encoding::UTF_8) end it 'should read a string containing unicode characters from UTF-8 encoded buffer' do # i32 of value 3, followed by one character U+20AC made up of three bytes buffer = [0x00, 0x00, 0x00, 0x03, 0xE2, 0x82, 0xAC].pack('C*') @trans.write(buffer) a = @prot.read_string expect(a).to eq("\u20AC".encode('UTF-8')) expect(a.encoding).to eq(Encoding::UTF_8) end it 'should read a binary string' do buffer = [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03].pack('C*') @trans.write(buffer) a = @prot.read_binary expect(a).to eq([0x00, 0x01, 0x02, 0x03].pack('C*')) expect(a.encoding).to eq(Encoding::BINARY) end it "should perform a complete rpc with no args or return" do srv_test( proc { |client| client.send_voidMethod() }, proc { |client| expect(client.recv_voidMethod).to eq(nil) } ) end it "should perform a complete rpc with a primitive return type" do srv_test( proc { |client| client.send_primitiveMethod() }, proc { |client| expect(client.recv_primitiveMethod).to eq(1) } ) end it "should perform a complete rpc with a struct return type" do srv_test( proc { |client| client.send_structMethod() }, proc { |client| result = client.recv_structMethod result.set_byte_map = nil result.map_byte_map = nil expect(result).to eq(Fixtures::COMPACT_PROTOCOL_TEST_STRUCT) } ) end def get_socket_connection server = Thrift::ServerSocket.new("localhost", 9090) server.listen clientside = Thrift::Socket.new("localhost", 9090) clientside.open serverside = server.accept [clientside, serverside, server] end def srv_test(firstblock, secondblock) clientside, serverside, server = get_socket_connection clientproto = protocol_class.new(clientside) serverproto = protocol_class.new(serverside) processor = Thrift::Test::Srv::Processor.new(SrvHandler.new) client = Thrift::Test::Srv::Client.new(clientproto, clientproto) # first block firstblock.call(client) processor.process(serverproto, serverproto) # second block secondblock.call(client) ensure clientside.close serverside.close server.close end class SrvHandler def voidMethod() end def primitiveMethod 1 end def structMethod Fixtures::COMPACT_PROTOCOL_TEST_STRUCT end end end thrift-0.23.0/lib/rb/spec/bytes_spec.rb0000664000175000017500000000641415167543515020167 0ustar00buildbuild00000000000000# encoding: UTF-8 # # 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. # require 'spec_helper' describe Thrift::Bytes do describe '.empty_byte_buffer' do it 'should create an empty buffer' do b = Thrift::Bytes.empty_byte_buffer expect(b.length).to eq(0) expect(b.encoding).to eq(Encoding::BINARY) end it 'should create an empty buffer of given size' do b = Thrift::Bytes.empty_byte_buffer 2 expect(b.length).to eq(2) expect(b.getbyte(0)).to eq(0) expect(b.getbyte(1)).to eq(0) expect(b.encoding).to eq(Encoding::BINARY) end end describe '.force_binary_encoding' do it 'should change encoding' do e = 'STRING'.encode('UTF-8') expect(e.encoding).not_to eq(Encoding::BINARY) a = Thrift::Bytes.force_binary_encoding e expect(a.encoding).to eq(Encoding::BINARY) end end describe '.get_string_byte' do it 'should get the byte at index' do s = "\x41\x42" expect(Thrift::Bytes.get_string_byte(s, 0)).to eq(0x41) expect(Thrift::Bytes.get_string_byte(s, 1)).to eq(0x42) end end describe '.set_string_byte' do it 'should set byte value at index' do s = "\x41\x42" Thrift::Bytes.set_string_byte(s, 0, 0x43) expect(s.getbyte(0)).to eq(0x43) expect(s).to eq('CB') end end describe '.convert_to_utf8_byte_buffer' do it 'should convert UTF-8 String to byte buffer' do e = "\u20AC".encode('UTF-8') # a string with euro sign character U+20AC expect(e.length).to eq(1) a = Thrift::Bytes.convert_to_utf8_byte_buffer e expect(a.encoding).to eq(Encoding::BINARY) expect(a.length).to eq(3) expect(a.unpack('C*')).to eq([0xE2, 0x82, 0xAC]) end it 'should convert ISO-8859-15 String to UTF-8 byte buffer' do # Assumptions e = "\u20AC".encode('ISO-8859-15') # a string with euro sign character U+20AC, then converted to ISO-8859-15 expect(e.length).to eq(1) expect(e.unpack('C*')).to eq([0xA4]) # euro sign is a different code point in ISO-8859-15 a = Thrift::Bytes.convert_to_utf8_byte_buffer e expect(a.encoding).to eq(Encoding::BINARY) expect(a.length).to eq(3) expect(a.unpack('C*')).to eq([0xE2, 0x82, 0xAC]) end end describe '.convert_to_string' do it 'should convert UTF-8 byte buffer to a UTF-8 String' do e = [0xE2, 0x82, 0xAC].pack("C*") expect(e.encoding).to eq(Encoding::BINARY) a = Thrift::Bytes.convert_to_string e expect(a.encoding).to eq(Encoding::UTF_8) expect(a).to eq("\u20AC") end end end thrift-0.23.0/lib/rb/spec/binary_protocol_spec.rb0000664000175000017500000000531315167543515022243 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require File.expand_path("#{File.dirname(__FILE__)}/binary_protocol_spec_shared") describe 'BinaryProtocol' do it_should_behave_like 'a binary protocol' def protocol_class Thrift::BinaryProtocol end describe Thrift::BinaryProtocol do before(:each) do @trans = Thrift::MemoryBufferTransport.new @prot = protocol_class.new(@trans) end it "should read a message header" do @trans.write([protocol_class.const_get(:VERSION_1) | Thrift::MessageTypes::REPLY].pack('N')) @trans.write([42].pack('N')) expect(@prot).to receive(:read_string).and_return('testMessage') expect(@prot.read_message_begin).to eq(['testMessage', Thrift::MessageTypes::REPLY, 42]) end it "should raise an exception if the message header has the wrong version" do expect(@prot).to receive(:read_i32).and_return(-1) expect { @prot.read_message_begin }.to raise_error(Thrift::ProtocolException, 'Missing version identifier') do |e| e.type == Thrift::ProtocolException::BAD_VERSION end end it "should raise an exception if the message header does not exist and strict_read is enabled" do expect(@prot).to receive(:read_i32).and_return(42) expect(@prot).to receive(:strict_read).and_return(true) expect { @prot.read_message_begin }.to raise_error(Thrift::ProtocolException, 'No version identifier, old protocol client?') do |e| e.type == Thrift::ProtocolException::BAD_VERSION end end it "should provide a reasonable to_s" do expect(@prot.to_s).to eq("binary(memory)") end end describe Thrift::BinaryProtocolFactory do it "should create a BinaryProtocol" do expect(Thrift::BinaryProtocolFactory.new.get_protocol(double("MockTransport"))).to be_instance_of(Thrift::BinaryProtocol) end it "should provide a reasonable to_s" do expect(Thrift::BinaryProtocolFactory.new.to_s).to eq("binary") end end end thrift-0.23.0/lib/rb/spec/support/0000775000175000017500000000000015167543515017211 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/spec/support/header_protocol_helper.rb0000664000175000017500000000331415167543515024247 0ustar00buildbuild00000000000000# # 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. # module HeaderProtocolHelper def varint32(n) bytes = [] loop do if (n & ~0x7f) == 0 bytes << n break else bytes << ((n & 0x7f) | 0x80) n >>= 7 end end bytes.pack('C*') end def build_header_frame(header_data, payload = Thrift::Bytes.empty_byte_buffer, header_words: nil) header_data = Thrift::Bytes.force_binary_encoding(header_data) if header_words.nil? padding = (4 - (header_data.bytesize % 4)) % 4 header_data += "\x00" * padding header_words = header_data.bytesize / 4 end frame_size = 2 + 2 + 4 + 2 + header_data.bytesize + payload.bytesize frame = Thrift::Bytes.empty_byte_buffer frame << [frame_size].pack('N') frame << [Thrift::HeaderTransport::HEADER_MAGIC].pack('n') frame << [0].pack('n') frame << [0].pack('N') frame << [header_words].pack('n') frame << header_data frame << payload frame end end thrift-0.23.0/lib/rb/spec/client_spec.rb0000664000175000017500000001615015167543515020315 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Client' do class ClientSpec include Thrift::Client end class EmptyArgs def write(_prot) end end before(:each) do @prot = double("MockProtocol") @client = ClientSpec.new(@prot) end describe Thrift::Client do it "should re-use iprot for oprot if not otherwise specified" do expect(@client.instance_variable_get(:'@iprot')).to eql(@prot) expect(@client.instance_variable_get(:'@oprot')).to eql(@prot) end it "should send a test message" do expect(@prot).to receive(:write_message_begin).with('testMessage', Thrift::MessageTypes::CALL, 0) mock_args = double('#') expect(mock_args).to receive(:foo=).with('foo') expect(mock_args).to receive(:bar=).with(42) expect(mock_args).to receive(:write).with(@prot) expect(@prot).to receive(:write_message_end) expect(@prot).to receive(:trans) do double('trans').tap do |trans| expect(trans).to receive(:flush) end end klass = double("TestMessage_args", :new => mock_args) @client.send_message('testMessage', klass, :foo => 'foo', :bar => 42) end it "should increment the sequence id when sending messages" do expect(@prot).to receive(:write_message_begin).with('testMessage', Thrift::MessageTypes::CALL, 0).ordered expect(@prot).to receive(:write_message_begin).with('testMessage2', Thrift::MessageTypes::CALL, 1).ordered expect(@prot).to receive(:write_message_begin).with('testMessage3', Thrift::MessageTypes::CALL, 2).ordered allow(@prot).to receive(:write_message_end) allow(@prot).to receive(:trans).and_return(double("trans", :flush => nil)) args_class = double("ArgsClass", :new => EmptyArgs.new) @client.send_message('testMessage', args_class) @client.send_message('testMessage2', args_class) @client.send_message('testMessage3', args_class) end it "should keep pending reply sequence ids in FIFO order" do expect(@prot).to receive(:write_message_begin).with('first', Thrift::MessageTypes::CALL, 0).ordered expect(@prot).to receive(:write_message_begin).with('second', Thrift::MessageTypes::CALL, 1).ordered allow(@prot).to receive(:write_message_end) allow(@prot).to receive(:trans).and_return(double("trans", :flush => nil)) args_class = double("ArgsClass", :new => EmptyArgs.new) @client.send_message('first', args_class) @client.send_message('second', args_class) expect { @client.validate_message_begin('first', Thrift::MessageTypes::REPLY, 0, 'first') }.not_to raise_error expect { @client.validate_message_begin('second', Thrift::MessageTypes::REPLY, 1, 'second') }.not_to raise_error end it "should receive a test message" do expect(@prot).to receive(:read_message_begin).and_return [nil, Thrift::MessageTypes::CALL, 0] expect(@prot).to receive(:read_message_end) mock_klass = double("#") expect(mock_klass).to receive(:read).with(@prot) @client.receive_message_begin() @client.receive_message(double("MockClass", :new => mock_klass)) end it "should raise BAD_SEQUENCE_ID for mismatched replies" do @client.instance_variable_set(:@pending_seqids, [0]) expect { @client.validate_message_begin('testMessage', Thrift::MessageTypes::REPLY, 1, 'testMessage') }.to raise_error(Thrift::ApplicationException) { |error| expect(error.type).to eq(Thrift::ApplicationException::BAD_SEQUENCE_ID) } end it "should raise WRONG_METHOD_NAME for unexpected replies" do @client.instance_variable_set(:@pending_seqids, [0]) expect { @client.validate_message_begin('otherMessage', Thrift::MessageTypes::REPLY, 0, 'testMessage') }.to raise_error(Thrift::ApplicationException) { |error| expect(error.type).to eq(Thrift::ApplicationException::WRONG_METHOD_NAME) } end it "should raise INVALID_MESSAGE_TYPE for non-reply messages" do @client.instance_variable_set(:@pending_seqids, [0]) expect { @client.validate_message_begin('testMessage', Thrift::MessageTypes::CALL, 0, 'testMessage') }.to raise_error(Thrift::ApplicationException) { |error| expect(error.type).to eq(Thrift::ApplicationException::INVALID_MESSAGE_TYPE) } end it "should raise received application exceptions" do expect(@prot).to receive(:read_message_end) server_exception = Thrift::ApplicationException.new(Thrift::ApplicationException::UNKNOWN, "boom") expect(server_exception).to receive(:read).with(@prot) expect(Thrift::ApplicationException).to receive(:new).and_return(server_exception) @client.instance_variable_set(:@pending_seqids, [0]) expect { @client.validate_message_begin('testMessage', Thrift::MessageTypes::EXCEPTION, 0, 'testMessage') }.to raise_error(Thrift::ApplicationException, "boom") expect(@client.instance_variable_get(:@pending_seqids)).to be_empty end it "should roll sequence ids across the signed int32 boundary" do expect(@prot).to receive(:write_message_begin).with('testMessage', Thrift::MessageTypes::CALL, Thrift::Client::MAX_SEQUENCE_ID).ordered expect(@prot).to receive(:write_message_begin).with('testMessage2', Thrift::MessageTypes::CALL, Thrift::Client::MIN_SEQUENCE_ID).ordered allow(@prot).to receive(:write_message_end) allow(@prot).to receive(:trans).and_return(double("trans", :flush => nil)) @client.instance_variable_set(:@seqid, Thrift::Client::MAX_SEQUENCE_ID) args_class = double("ArgsClass", :new => EmptyArgs.new) @client.send_message('testMessage', args_class) @client.send_message('testMessage2', args_class) end it "should close the transport if an error occurs while sending a message" do allow(@prot).to receive(:write_message_begin) expect(@prot).not_to receive(:write_message_end) mock_args = double("#") expect(mock_args).to receive(:write).with(@prot).and_raise(StandardError) trans = double("MockTransport") allow(@prot).to receive(:trans).and_return(trans) expect(trans).to receive(:close) klass = double("TestMessage_args", :new => mock_args) expect { @client.send_message("testMessage", klass) }.to raise_error(StandardError) end end end thrift-0.23.0/lib/rb/spec/header_transport_spec.rb0000664000175000017500000003304115167543515022401 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require_relative 'support/header_protocol_helper' describe 'HeaderTransport' do include HeaderProtocolHelper describe Thrift::HeaderClientType do it "should define client type constants" do expect(Thrift::HeaderClientType::HEADERS).to eq(0x00) expect(Thrift::HeaderClientType::FRAMED_BINARY).to eq(0x01) expect(Thrift::HeaderClientType::UNFRAMED_BINARY).to eq(0x02) expect(Thrift::HeaderClientType::FRAMED_COMPACT).to eq(0x03) expect(Thrift::HeaderClientType::UNFRAMED_COMPACT).to eq(0x04) end end describe Thrift::HeaderSubprotocolID do it "should define protocol ID constants" do expect(Thrift::HeaderSubprotocolID::BINARY).to eq(0x00) expect(Thrift::HeaderSubprotocolID::COMPACT).to eq(0x02) end end describe Thrift::HeaderTransformID do it "should define transform ID constants" do expect(Thrift::HeaderTransformID::ZLIB).to eq(0x01) end end describe Thrift::HeaderTransport do before(:each) do @underlying = Thrift::MemoryBufferTransport.new @trans = Thrift::HeaderTransport.new(@underlying) end it "should provide a to_s that describes the encapsulation" do expect(@trans.to_s).to eq("header(memory)") end it "should pass through open?/open/close" do mock_transport = double("Transport") expect(mock_transport).to receive(:open?).and_return(true) expect(mock_transport).to receive(:open).and_return(nil) expect(mock_transport).to receive(:close).and_return(nil) trans = Thrift::HeaderTransport.new(mock_transport) expect(trans.open?).to be true trans.open trans.close end describe "header management" do it "should allow setting and getting headers" do @trans.set_header("key1", "value1") @trans.set_header("key2", "value2") # Headers aren't read until we receive data, so write and read back expect(@trans.get_headers).to eq({}) end it "should clear headers" do @trans.set_header("key1", "value1") @trans.clear_headers # Write and flush to verify headers were cleared @trans.write("test") @trans.flush end it "should add transforms" do expect { @trans.add_transform(Thrift::HeaderTransformID::ZLIB) }.not_to raise_error end it "should reject unknown transforms" do expect { @trans.add_transform(999) }.to raise_error(Thrift::TransportException) end end describe "write and flush" do it "should buffer writes" do @trans.write("hello") @trans.write(" world") expect(@underlying.available).to eq(0) end it "should write Header format on flush" do @trans.write("test payload") @trans.flush # Read back the frame data = @underlying.read(@underlying.available) # Should have frame length (4 bytes) + header + payload expect(data.bytesize).to be > 16 # First 4 bytes are frame length frame_size = data[0, 4].unpack('N').first expect(frame_size).to eq(data.bytesize - 4) # Next 2 bytes should be header magic magic = data[4, 2].unpack('n').first expect(magic).to eq(Thrift::HeaderTransport::HEADER_MAGIC) end it "should include headers in frame" do @trans.set_header("test-key", "test-value") @trans.write("payload") @trans.flush # Read back and verify it's larger due to headers data = @underlying.read(@underlying.available) expect(data.bytesize).to be > 30 # Should include header key-value end it "should write the configured sequence id into the frame header" do @trans.sequence_id = 456 @trans.write("payload") @trans.flush data = @underlying.read(@underlying.available) expect(data[8, 4].unpack('N').first).to eq(456) end it "should apply ZLIB transform" do @trans.add_transform(Thrift::HeaderTransformID::ZLIB) original_payload = "a" * 1000 # Compressible data @trans.write(original_payload) @trans.flush data = @underlying.read(@underlying.available) # Compressed frame should be smaller than uncompressed expect(data.bytesize).to be < original_payload.bytesize end end describe "frame size limits" do it "should reject payloads larger than max frame size" do @trans.set_max_frame_size(4) @trans.write("12345") expect { @trans.flush }.to raise_error(Thrift::TransportException, /frame that is too large/) end end describe "read and frame detection" do it "should detect Header format" do # Write a Header frame @trans.write("test data") @trans.flush # Reset for reading written_data = @underlying.read(@underlying.available) read_transport = Thrift::MemoryBufferTransport.new(written_data) read_trans = Thrift::HeaderTransport.new(read_transport) result = read_trans.read(9) expect(result).to eq("test data") end it "should detect framed binary protocol" do # Create a framed binary message payload = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N') payload << "test" frame = [payload.bytesize].pack('N') + payload read_transport = Thrift::MemoryBufferTransport.new(frame) read_trans = Thrift::HeaderTransport.new(read_transport) result = read_trans.read(payload.bytesize) expect(result).to eq(payload) end it "should detect unframed binary protocol" do # Create an unframed binary message (version word first) message = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N') message << "test" read_transport = Thrift::MemoryBufferTransport.new(message) read_trans = Thrift::HeaderTransport.new(read_transport) result = read_trans.read(message.bytesize) expect(result).to eq(message) end it "should read headers from Header frame" do # Write with headers @trans.set_header("request-id", "12345") @trans.write("payload") @trans.flush # Read back written_data = @underlying.read(@underlying.available) read_transport = Thrift::MemoryBufferTransport.new(written_data) read_trans = Thrift::HeaderTransport.new(read_transport) read_trans.read(7) headers = read_trans.get_headers expect(headers["request-id"]).to eq("12345") end it "should decode signed sequence ids from Header frames" do @trans.sequence_id = -2147483648 @trans.write("payload") @trans.flush written_data = @underlying.read(@underlying.available) read_transport = Thrift::MemoryBufferTransport.new(written_data) read_trans = Thrift::HeaderTransport.new(read_transport) expect(read_trans.read(7)).to eq("payload") expect(read_trans.sequence_id).to eq(-2147483648) end it "should decompress ZLIB payload" do # Write with ZLIB @trans.add_transform(Thrift::HeaderTransformID::ZLIB) original = "hello world this is a test" @trans.write(original) @trans.flush # Read back written_data = @underlying.read(@underlying.available) read_transport = Thrift::MemoryBufferTransport.new(written_data) read_trans = Thrift::HeaderTransport.new(read_transport) result = read_trans.read(original.bytesize) expect(result).to eq(original) end end describe "header parsing protections" do it "should reject unreasonable header sizes" do frame = build_header_frame("", Thrift::Bytes.empty_byte_buffer, header_words: 16_384) read_transport = Thrift::MemoryBufferTransport.new(frame) read_trans = Thrift::HeaderTransport.new(read_transport) expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /Header size is unreasonable/) end it "should reject header frames that are too small" do frame = Thrift::Bytes.empty_byte_buffer frame << [9].pack('N') frame << [Thrift::HeaderTransport::HEADER_MAGIC].pack('n') frame << [0].pack('n') frame << [0].pack('N') frame << [0].pack('n') read_transport = Thrift::MemoryBufferTransport.new(frame) read_trans = Thrift::HeaderTransport.new(read_transport) expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /frame is too small/) end it "should reject varints that cross header boundary" do header_data = [0x80, 0x80, 0x80, 0x80].pack('C*') frame = build_header_frame(header_data) read_transport = Thrift::MemoryBufferTransport.new(frame) read_trans = Thrift::HeaderTransport.new(read_transport) expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /header boundary/) end it "should reject strings that exceed header boundary" do header_data = +"" header_data << varint32(Thrift::HeaderSubprotocolID::BINARY) header_data << varint32(0) header_data << varint32(Thrift::HeaderInfoType::KEY_VALUE) header_data << varint32(1) header_data << varint32(10) header_data << "a" frame = build_header_frame(header_data) read_transport = Thrift::MemoryBufferTransport.new(frame) read_trans = Thrift::HeaderTransport.new(read_transport) expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /Info header length exceeds header size/) end end describe "round-trip" do it "should handle complete write-read cycle" do # Write @trans.set_header("trace-id", "abc123") @trans.write("hello world") @trans.flush # Read written_data = @underlying.read(@underlying.available) read_transport = Thrift::MemoryBufferTransport.new(written_data) read_trans = Thrift::HeaderTransport.new(read_transport) result = read_trans.read(11) expect(result).to eq("hello world") expect(read_trans.get_headers["trace-id"]).to eq("abc123") end it "should handle multiple headers" do @trans.set_header("header1", "value1") @trans.set_header("header2", "value2") @trans.set_header("header3", "value3") @trans.write("data") @trans.flush written_data = @underlying.read(@underlying.available) read_transport = Thrift::MemoryBufferTransport.new(written_data) read_trans = Thrift::HeaderTransport.new(read_transport) read_trans.read(4) headers = read_trans.get_headers expect(headers["header1"]).to eq("value1") expect(headers["header2"]).to eq("value2") expect(headers["header3"]).to eq("value3") end it "should handle ZLIB compression round-trip" do @trans.add_transform(Thrift::HeaderTransformID::ZLIB) @trans.set_header("compressed", "true") original = "x" * 500 @trans.write(original) @trans.flush written_data = @underlying.read(@underlying.available) read_transport = Thrift::MemoryBufferTransport.new(written_data) read_trans = Thrift::HeaderTransport.new(read_transport) result = read_trans.read(500) expect(result).to eq(original) expect(read_trans.get_headers["compressed"]).to eq("true") end end describe "client type restrictions" do it "should reject disallowed client types" do # Only allow HEADERS allowed = [Thrift::HeaderClientType::HEADERS] # Create framed binary message payload = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N') frame = [payload.bytesize].pack('N') + payload read_transport = Thrift::MemoryBufferTransport.new(frame) read_trans = Thrift::HeaderTransport.new(read_transport, allowed) expect { read_trans.read(4) }.to raise_error(Thrift::TransportException) end end end describe Thrift::HeaderTransportFactory do it "should wrap transport in HeaderTransport" do mock_transport = double("Transport") factory = Thrift::HeaderTransportFactory.new result = factory.get_transport(mock_transport) expect(result).to be_a(Thrift::HeaderTransport) end it "should provide a reasonable to_s" do expect(Thrift::HeaderTransportFactory.new.to_s).to eq("header") end it "should pass allowed_client_types to transport" do allowed = [Thrift::HeaderClientType::HEADERS] factory = Thrift::HeaderTransportFactory.new(allowed) mock_transport = Thrift::MemoryBufferTransport.new result = factory.get_transport(mock_transport) expect(result).to be_a(Thrift::HeaderTransport) end end end thrift-0.23.0/lib/rb/spec/processor_spec.rb0000664000175000017500000000632115167543515021055 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Processor' do class ProcessorSpec include Thrift::Processor end describe Thrift::Processor do before(:each) do @processor = ProcessorSpec.new(double("MockHandler")) @prot = double("MockProtocol") end def mock_trans(obj) expect(obj).to receive(:trans).ordered do double("trans").tap do |trans| expect(trans).to receive(:flush).ordered end end end it "should call process_ when it receives that message" do expect(@prot).to receive(:read_message_begin).ordered.and_return ['testMessage', Thrift::MessageTypes::CALL, 17] expect(@processor).to receive(:process_testMessage).with(17, @prot, @prot).ordered expect(@processor.process(@prot, @prot)).to eq(true) end it "should raise an ApplicationException when the received message cannot be processed" do expect(@prot).to receive(:read_message_begin).ordered.and_return ['testMessage', Thrift::MessageTypes::CALL, 4] expect(@prot).to receive(:skip).with(Thrift::Types::STRUCT).ordered expect(@prot).to receive(:read_message_end).ordered expect(@prot).to receive(:write_message_begin).with('testMessage', Thrift::MessageTypes::EXCEPTION, 4).ordered e = double(Thrift::ApplicationException) expect(e).to receive(:write).with(@prot).ordered expect(Thrift::ApplicationException).to receive(:new).with(Thrift::ApplicationException::UNKNOWN_METHOD, "Unknown function testMessage").and_return(e) expect(@prot).to receive(:write_message_end).ordered mock_trans(@prot) @processor.process(@prot, @prot) end it "should pass args off to the args class" do args_class = double("MockArgsClass") args = double("#").tap do |args| expect(args).to receive(:read).with(@prot).ordered end expect(args_class).to receive(:new).and_return args expect(@prot).to receive(:read_message_end).ordered expect(@processor.read_args(@prot, args_class)).to eql(args) end it "should write out a reply when asked" do expect(@prot).to receive(:write_message_begin).with('testMessage', Thrift::MessageTypes::REPLY, 23).ordered result = double("MockResult") expect(result).to receive(:write).with(@prot).ordered expect(@prot).to receive(:write_message_end).ordered mock_trans(@prot) @processor.write_result(result, @prot, 'testMessage', 23) end end end thrift-0.23.0/lib/rb/spec/thin_http_server_spec.rb0000664000175000017500000001040115167543515022417 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require 'rack/test' require 'thrift/server/thin_http_server' describe Thrift::ThinHTTPServer do let(:processor) { double('processor') } describe "#initialize" do context "when using the defaults" do it "binds to port 80, with host 0.0.0.0, a path of '/'" do expect(Thin::Server).to receive(:new).with('0.0.0.0', 80, an_instance_of(Rack::Builder)) Thrift::ThinHTTPServer.new(processor) end it 'creates a ThinHTTPServer::RackApplicationContext' do expect(Thrift::ThinHTTPServer::RackApplication).to receive(:for).with("/", processor, an_instance_of(Thrift::BinaryProtocolFactory)).and_return(anything) Thrift::ThinHTTPServer.new(processor) end it "uses the BinaryProtocolFactory" do expect(Thrift::BinaryProtocolFactory).to receive(:new) Thrift::ThinHTTPServer.new(processor) end end context "when using the options" do it 'accepts :ip, :port, :path' do ip = "192.168.0.1" port = 3000 path = "/thin" expect(Thin::Server).to receive(:new).with(ip, port, an_instance_of(Rack::Builder)) Thrift::ThinHTTPServer.new(processor, :ip => ip, :port => port, :path => path) end it 'creates a ThinHTTPServer::RackApplicationContext with a different protocol factory' do expect(Thrift::ThinHTTPServer::RackApplication).to receive(:for).with("/", processor, an_instance_of(Thrift::JsonProtocolFactory)).and_return(anything) Thrift::ThinHTTPServer.new(processor, :protocol_factory => Thrift::JsonProtocolFactory.new) end end end describe "#serve" do it 'starts the Thin server' do underlying_thin_server = double('thin server', :start => true) allow(Thin::Server).to receive(:new).and_return(underlying_thin_server) thin_thrift_server = Thrift::ThinHTTPServer.new(processor) expect(underlying_thin_server).to receive(:start) thin_thrift_server.serve end end end describe Thrift::ThinHTTPServer::RackApplication do include Rack::Test::Methods let(:processor) { double('processor') } let(:protocol_factory) { double('protocol factory') } def app Thrift::ThinHTTPServer::RackApplication.for("/", processor, protocol_factory) end context "404 response" do it 'receives a non-POST' do header('Content-Type', "application/x-thrift") get "/" expect(last_response.status).to eq 404 end it 'receives a header other than application/x-thrift' do header('Content-Type', "application/json") post "/" expect(last_response.status).to eq 404 end end context "200 response" do before do allow(protocol_factory).to receive(:get_protocol) allow(processor).to receive(:process) end it 'creates an IOStreamTransport' do header('Content-Type', "application/x-thrift") expect(Thrift::IOStreamTransport).to receive(:new).with(an_instance_of(Rack::Lint::InputWrapper), an_instance_of(Rack::Response)) post "/" end it 'fetches the right protocol based on the Transport' do header('Content-Type', "application/x-thrift") expect(protocol_factory).to receive(:get_protocol).with(an_instance_of(Thrift::IOStreamTransport)) post "/" end it 'status code 200' do header('Content-Type', "application/x-thrift") post "/" expect(last_response.ok?).to be true end end end thrift-0.23.0/lib/rb/spec/socket_spec_shared.rb0000664000175000017500000001427615167543515021664 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' shared_examples_for "a socket" do it "should open a socket" do expect(@socket.open).to eq(@handle) end it "should be open whenever it has a handle" do expect(@socket).not_to be_open @socket.open expect(@socket).to be_open @socket.handle = nil expect(@socket).not_to be_open @socket.handle = @handle @socket.close expect(@socket).not_to be_open end it "should write data to the handle" do @socket.open expect(@handle).to receive(:write).with("foobar") @socket.write("foobar") expect(@handle).to receive(:write).with("fail").and_raise(StandardError) expect { @socket.write("fail") }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } end it "should raise an error when it cannot read from the handle" do @socket.open expect(@handle).to receive(:readpartial).with(17).and_raise(StandardError) expect { @socket.read(17) }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } end it "should return the data read when reading from the handle works" do @socket.open expect(@handle).to receive(:readpartial).with(17).and_return("test data") expect(@socket.read(17)).to eq("test data") end it "should declare itself as closed when it has an error" do @socket.open expect(@handle).to receive(:write).with("fail").and_raise(StandardError) expect(@socket).to be_open expect { @socket.write("fail") }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } expect(@socket).not_to be_open end it "should raise an error when the stream is closed" do @socket.open allow(@handle).to receive(:closed?).and_return(true) expect(@socket).not_to be_open expect { @socket.write("fail") }.to raise_error(Thrift::TransportException, "closed stream") { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } expect { @socket.read(10) }.to raise_error(Thrift::TransportException, "closed stream") { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } end it "should support the timeout accessor for read" do @socket.timeout = 3 @socket.open expect(@handle).to receive(:read_nonblock).with(17).and_raise(IO::EAGAINWaitReadable) expect(IO).to receive(:select) do |rd, wr, err, timeout| expect(rd).to eq([@handle]) expect(wr).to be_nil expect(err).to be_nil expect(timeout).to be > 0 expect(timeout).to be <= 3 [[@handle], [], []] end expect(@handle).to receive(:read_nonblock).with(17).and_return("test data") expect(@socket.read(17)).to eq("test data") end it "should support the timeout accessor for write" do @socket.timeout = 3 @socket.open write_calls = 0 expect(@handle).to receive(:write_nonblock).exactly(3).times do |chunk| write_calls += 1 case write_calls when 1 expect(chunk).to eq("test data") raise IO::EAGAINWaitWritable when 2 expect(chunk).to eq("test data") 4 when 3 expect(chunk).to eq(" data") 5 end end expect(IO).to receive(:select) do |rd, wr, err, timeout| expect(rd).to be_nil expect(wr).to eq([@handle]) expect(err).to be_nil expect(timeout).to be > 0 expect(timeout).to be <= 3 [[], [@handle], []] end expect(@socket.write("test data")).to eq(9) end it "should raise an error when read times out" do @socket.timeout = 0.5 @socket.open expect(@handle).to receive(:read_nonblock).with(17).and_raise(IO::EAGAINWaitReadable) expect(IO).to receive(:select).once { sleep(0.6); nil } expect { @socket.read(17) }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::TIMED_OUT) } end it "should raise an error when write times out" do @socket.timeout = 0.5 @socket.open expect(@handle).to receive(:write_nonblock).with("test data").and_raise(IO::EAGAINWaitWritable) expect(IO).to receive(:select).once { sleep(0.6); nil } expect { @socket.write("test data") }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::TIMED_OUT) } end it "should read buffered SSL data without waiting on the raw socket again" do @socket.timeout = 1 @socket.open expect(@handle).to receive(:read_nonblock).with(4).ordered.and_raise(IO::EAGAINWaitReadable) expect(IO).to receive(:select).once.ordered do |rd, wr, err, timeout| expect(rd).to eq([@handle]) expect(wr).to be_nil expect(err).to be_nil expect(timeout).to be > 0 expect(timeout).to be <= 1 [[@handle], [], []] end expect(@handle).to receive(:read_nonblock).with(4).ordered.and_return("ABCD") expect(@handle).to receive(:read_nonblock).with(5).ordered.and_return("12345") expect(@socket.read(4)).to eq("ABCD") expect(@socket.read(5)).to eq("12345") end it "should read without timeout using the blocking path" do @socket.timeout = nil @socket.open expect(IO).not_to receive(:select) expect(@handle).not_to receive(:read_nonblock) expect(@handle).to receive(:readpartial).with(4).ordered.and_return("ABCD") expect(@handle).to receive(:readpartial).with(5).ordered.and_return("12345") expect(@socket.read(4)).to eq("ABCD") expect(@socket.read(5)).to eq("12345") end end thrift-0.23.0/lib/rb/spec/json_protocol_spec.rb0000664000175000017500000004473315167543515021741 0ustar00buildbuild00000000000000# encoding: UTF-8 # # 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. # require 'spec_helper' describe 'JsonProtocol' do describe Thrift::JsonProtocol do before(:each) do @trans = Thrift::MemoryBufferTransport.new @prot = Thrift::JsonProtocol.new(@trans) end it "should write json escaped char" do @prot.write_json_escape_char("\n") expect(@trans.read(@trans.available)).to eq('\u000a') @prot.write_json_escape_char(" ") expect(@trans.read(@trans.available)).to eq('\u0020') end it "should write json char" do @prot.write_json_char("\n") expect(@trans.read(@trans.available)).to eq('\\n') @prot.write_json_char(" ") expect(@trans.read(@trans.available)).to eq(' ') @prot.write_json_char("\\") expect(@trans.read(@trans.available)).to eq("\\\\") @prot.write_json_char("@") expect(@trans.read(@trans.available)).to eq('@') end it "should write json string" do @prot.write_json_string("this is a \\ json\nstring") expect(@trans.read(@trans.available)).to eq("\"this is a \\\\ json\\nstring\"") end it "should write json base64" do @prot.write_json_base64("this is a base64 string") expect(@trans.read(@trans.available)).to eq("\"dGhpcyBpcyBhIGJhc2U2NCBzdHJpbmc=\"") end it "should write json integer" do @prot.write_json_integer(45) expect(@trans.read(@trans.available)).to eq("45") @prot.write_json_integer(33000) expect(@trans.read(@trans.available)).to eq("33000") @prot.write_json_integer(3000000000) expect(@trans.read(@trans.available)).to eq("3000000000") @prot.write_json_integer(6000000000) expect(@trans.read(@trans.available)).to eq("6000000000") end it "should write json double" do @prot.write_json_double(12.3) expect(@trans.read(@trans.available)).to eq("12.3") @prot.write_json_double(-3.21) expect(@trans.read(@trans.available)).to eq("-3.21") @prot.write_json_double(((+1.0/0.0)/(+1.0/0.0))) expect(@trans.read(@trans.available)).to eq("\"NaN\"") @prot.write_json_double((+1.0/0.0)) expect(@trans.read(@trans.available)).to eq("\"Infinity\"") @prot.write_json_double((-1.0/0.0)) expect(@trans.read(@trans.available)).to eq("\"-Infinity\"") end it "should write json object start" do @prot.write_json_object_start expect(@trans.read(@trans.available)).to eq("{") end it "should write json object end" do @prot.write_json_object_end expect(@trans.read(@trans.available)).to eq("}") end it "should write json array start" do @prot.write_json_array_start expect(@trans.read(@trans.available)).to eq("[") end it "should write json array end" do @prot.write_json_array_end expect(@trans.read(@trans.available)).to eq("]") end it "should write message begin" do @prot.write_message_begin("name", 12, 32) expect(@trans.read(@trans.available)).to eq("[1,\"name\",12,32") end it "should write message end" do @prot.write_message_end expect(@trans.read(@trans.available)).to eq("]") end it "should write struct begin" do @prot.write_struct_begin("name") expect(@trans.read(@trans.available)).to eq("{") end it "should write struct end" do @prot.write_struct_end expect(@trans.read(@trans.available)).to eq("}") end it "should write field begin" do @prot.write_field_begin("name", Thrift::Types::STRUCT, 32) expect(@trans.read(@trans.available)).to eq("32{\"rec\"") end it "should write field end" do @prot.write_field_end expect(@trans.read(@trans.available)).to eq("}") end it "should write field stop" do @prot.write_field_stop expect(@trans.read(@trans.available)).to eq("") end it "should write map begin" do @prot.write_map_begin(Thrift::Types::STRUCT, Thrift::Types::LIST, 32) expect(@trans.read(@trans.available)).to eq("[\"rec\",\"lst\",32,{") end it "should write map end" do @prot.write_map_end expect(@trans.read(@trans.available)).to eq("}]") end it "should write list begin" do @prot.write_list_begin(Thrift::Types::STRUCT, 32) expect(@trans.read(@trans.available)).to eq("[\"rec\",32") end it "should write list end" do @prot.write_list_end expect(@trans.read(@trans.available)).to eq("]") end it "should write set begin" do @prot.write_set_begin(Thrift::Types::STRUCT, 32) expect(@trans.read(@trans.available)).to eq("[\"rec\",32") end it "should write set end" do @prot.write_set_end expect(@trans.read(@trans.available)).to eq("]") end it "should write bool" do @prot.write_bool(true) expect(@trans.read(@trans.available)).to eq("1") @prot.write_bool(false) expect(@trans.read(@trans.available)).to eq("0") end it "should write byte" do @prot.write_byte(100) expect(@trans.read(@trans.available)).to eq("100") end it "should write i16" do @prot.write_i16(1000) expect(@trans.read(@trans.available)).to eq("1000") end it "should write i32" do @prot.write_i32(3000000000) expect(@trans.read(@trans.available)).to eq("3000000000") end it "should write i64" do @prot.write_i64(6000000000) expect(@trans.read(@trans.available)).to eq("6000000000") end it "should write double" do @prot.write_double(1.23) expect(@trans.read(@trans.available)).to eq("1.23") @prot.write_double(-32.1) expect(@trans.read(@trans.available)).to eq("-32.1") @prot.write_double(((+1.0/0.0)/(+1.0/0.0))) expect(@trans.read(@trans.available)).to eq("\"NaN\"") @prot.write_double((+1.0/0.0)) expect(@trans.read(@trans.available)).to eq("\"Infinity\"") @prot.write_double((-1.0/0.0)) expect(@trans.read(@trans.available)).to eq("\"-Infinity\"") end it 'should write string' do @prot.write_string('this is a test string') a = @trans.read(@trans.available) expect(a).to eq('"this is a test string"'.force_encoding(Encoding::BINARY)) expect(a.encoding).to eq(Encoding::BINARY) end it 'should write string with unicode characters' do @prot.write_string("this is a test string with unicode characters: \u20AC \u20AD") a = @trans.read(@trans.available) expect(a).to eq("\"this is a test string with unicode characters: \u20AC \u20AD\"".force_encoding(Encoding::BINARY)) expect(a.encoding).to eq(Encoding::BINARY) end it "should write binary" do @prot.write_binary("this is a base64 string") expect(@trans.read(@trans.available)).to eq("\"dGhpcyBpcyBhIGJhc2U2NCBzdHJpbmc=\"") end it "should write long binary" do @prot.write_binary((0...256).to_a.pack('C*')) expect(@trans.read(@trans.available)).to eq("\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==\"") end it "should write a uuid" do @prot.write_uuid("00112233-4455-6677-8899-aabbccddeeff") expect(@trans.read(@trans.available)).to eq("\"00112233-4455-6677-8899-aabbccddeeff\"") end it "should get type name for type id" do expect { @prot.get_type_name_for_type_id(Thrift::Types::STOP) }.to raise_error(NotImplementedError) expect { @prot.get_type_name_for_type_id(Thrift::Types::VOID) }.to raise_error(NotImplementedError) expect(@prot.get_type_name_for_type_id(Thrift::Types::BOOL)).to eq("tf") expect(@prot.get_type_name_for_type_id(Thrift::Types::BYTE)).to eq("i8") expect(@prot.get_type_name_for_type_id(Thrift::Types::DOUBLE)).to eq("dbl") expect(@prot.get_type_name_for_type_id(Thrift::Types::I16)).to eq("i16") expect(@prot.get_type_name_for_type_id(Thrift::Types::I32)).to eq("i32") expect(@prot.get_type_name_for_type_id(Thrift::Types::I64)).to eq("i64") expect(@prot.get_type_name_for_type_id(Thrift::Types::STRING)).to eq("str") expect(@prot.get_type_name_for_type_id(Thrift::Types::STRUCT)).to eq("rec") expect(@prot.get_type_name_for_type_id(Thrift::Types::MAP)).to eq("map") expect(@prot.get_type_name_for_type_id(Thrift::Types::SET)).to eq("set") expect(@prot.get_type_name_for_type_id(Thrift::Types::LIST)).to eq("lst") end it "should get type id for type name" do expect { @prot.get_type_id_for_type_name("pp") }.to raise_error(NotImplementedError) expect(@prot.get_type_id_for_type_name("tf")).to eq(Thrift::Types::BOOL) expect(@prot.get_type_id_for_type_name("i8")).to eq(Thrift::Types::BYTE) expect(@prot.get_type_id_for_type_name("dbl")).to eq(Thrift::Types::DOUBLE) expect(@prot.get_type_id_for_type_name("i16")).to eq(Thrift::Types::I16) expect(@prot.get_type_id_for_type_name("i32")).to eq(Thrift::Types::I32) expect(@prot.get_type_id_for_type_name("i64")).to eq(Thrift::Types::I64) expect(@prot.get_type_id_for_type_name("str")).to eq(Thrift::Types::STRING) expect(@prot.get_type_id_for_type_name("rec")).to eq(Thrift::Types::STRUCT) expect(@prot.get_type_id_for_type_name("map")).to eq(Thrift::Types::MAP) expect(@prot.get_type_id_for_type_name("set")).to eq(Thrift::Types::SET) expect(@prot.get_type_id_for_type_name("lst")).to eq(Thrift::Types::LIST) end it "should read json syntax char" do @trans.write('F') expect { @prot.read_json_syntax_char('G') }.to raise_error(Thrift::ProtocolException) @trans.write('H') @prot.read_json_syntax_char('H') end it "should read json escape char" do @trans.write('0054') expect(@prot.read_json_escape_char).to eq('T') @trans.write("\"\\\"\"") expect(@prot.read_json_string(false)).to eq("\"") @trans.write("\"\\\\\"") expect(@prot.read_json_string(false)).to eq("\\") @trans.write("\"\\/\"") expect(@prot.read_json_string(false)).to eq("\/") @trans.write("\"\\b\"") expect(@prot.read_json_string(false)).to eq("\b") @trans.write("\"\\f\"") expect(@prot.read_json_string(false)).to eq("\f") @trans.write("\"\\n\"") expect(@prot.read_json_string(false)).to eq("\n") @trans.write("\"\\r\"") expect(@prot.read_json_string(false)).to eq("\r") @trans.write("\"\\t\"") expect(@prot.read_json_string(false)).to eq("\t") end it "should read json string" do @trans.write("\"\\P") expect { @prot.read_json_string(false) }.to raise_error(Thrift::ProtocolException) @trans.write("\"this is a test string\"") expect(@prot.read_json_string).to eq("this is a test string") end it "should read json base64" do @trans.write("\"dGhpcyBpcyBhIHRlc3Qgc3RyaW5n\"") expect(@prot.read_json_base64).to eq("this is a test string") end it "should is json numeric" do expect(@prot.is_json_numeric("A")).to eq(false) expect(@prot.is_json_numeric("+")).to eq(true) expect(@prot.is_json_numeric("-")).to eq(true) expect(@prot.is_json_numeric(".")).to eq(true) expect(@prot.is_json_numeric("0")).to eq(true) expect(@prot.is_json_numeric("1")).to eq(true) expect(@prot.is_json_numeric("2")).to eq(true) expect(@prot.is_json_numeric("3")).to eq(true) expect(@prot.is_json_numeric("4")).to eq(true) expect(@prot.is_json_numeric("5")).to eq(true) expect(@prot.is_json_numeric("6")).to eq(true) expect(@prot.is_json_numeric("7")).to eq(true) expect(@prot.is_json_numeric("8")).to eq(true) expect(@prot.is_json_numeric("9")).to eq(true) expect(@prot.is_json_numeric("E")).to eq(true) expect(@prot.is_json_numeric("e")).to eq(true) end it "should read json numeric chars" do @trans.write("1.453E45T") expect(@prot.read_json_numeric_chars).to eq("1.453E45") end it "should read json integer" do @trans.write("1.45\"\"") expect { @prot.read_json_integer }.to raise_error(Thrift::ProtocolException) @prot.read_string @trans.write("1453T") expect(@prot.read_json_integer).to eq(1453) end it "should read json double" do @trans.write("1.45e3e01\"\"") expect { @prot.read_json_double }.to raise_error(Thrift::ProtocolException) @prot.read_string @trans.write("\"1.453e01\"") expect { @prot.read_json_double }.to raise_error(Thrift::ProtocolException) @trans.write("1.453e01\"\"") expect(@prot.read_json_double).to eq(14.53) @prot.read_string @trans.write("\"NaN\"") expect(@prot.read_json_double.nan?).to eq(true) @trans.write("\"Infinity\"") expect(@prot.read_json_double).to eq(+1.0/0.0) @trans.write("\"-Infinity\"") expect(@prot.read_json_double).to eq(-1.0/0.0) end it "should read json object start" do @trans.write("{") expect(@prot.read_json_object_start).to eq(nil) end it "should read json object end" do @trans.write("}") expect(@prot.read_json_object_end).to eq(nil) end it "should read json array start" do @trans.write("[") expect(@prot.read_json_array_start).to eq(nil) end it "should read json array end" do @trans.write("]") expect(@prot.read_json_array_end).to eq(nil) end it "should read_message_begin" do @trans.write("[2,") expect { @prot.read_message_begin }.to raise_error(Thrift::ProtocolException) @trans.write("[1,\"name\",12,32\"\"") expect(@prot.read_message_begin).to eq(["name", 12, 32]) end it "should read message end" do @trans.write("]") expect(@prot.read_message_end).to eq(nil) end it "should read struct begin" do @trans.write("{") expect(@prot.read_struct_begin).to eq(nil) end it "should read struct end" do @trans.write("}") expect(@prot.read_struct_end).to eq(nil) end it "should read field begin" do @trans.write("1{\"rec\"") expect(@prot.read_field_begin).to eq([nil, 12, 1]) end it "should read field end" do @trans.write("}") expect(@prot.read_field_end).to eq(nil) end it "should read map begin" do @trans.write("[\"rec\",\"lst\",2,{") expect(@prot.read_map_begin).to eq([12, 15, 2]) end it "should read map end" do @trans.write("}]") expect(@prot.read_map_end).to eq(nil) end it "should read list begin" do @trans.write("[\"rec\",2\"\"") expect(@prot.read_list_begin).to eq([12, 2]) end it "should read list end" do @trans.write("]") expect(@prot.read_list_end).to eq(nil) end it "should read set begin" do @trans.write("[\"rec\",2\"\"") expect(@prot.read_set_begin).to eq([12, 2]) end it "should read set end" do @trans.write("]") expect(@prot.read_set_end).to eq(nil) end it "should read bool" do @trans.write("0\"\"") expect(@prot.read_bool).to eq(false) @prot.read_string @trans.write("1\"\"") expect(@prot.read_bool).to eq(true) end it "should read byte" do @trans.write("60\"\"") expect(@prot.read_byte).to eq(60) end it "should read i16" do @trans.write("1000\"\"") expect(@prot.read_i16).to eq(1000) end it "should read i32" do @trans.write("3000000000\"\"") expect(@prot.read_i32).to eq(3000000000) end it "should read i64" do @trans.write("6000000000\"\"") expect(@prot.read_i64).to eq(6000000000) end it "should read double" do @trans.write("12.23\"\"") expect(@prot.read_double).to eq(12.23) end it 'should read string' do @trans.write('"this is a test string"'.force_encoding(Encoding::BINARY)) a = @prot.read_string expect(a).to eq('this is a test string') expect(a.encoding).to eq(Encoding::UTF_8) end it 'should read string with unicode characters' do @trans.write('"this is a test string with unicode characters: \u20AC \u20AD"'.force_encoding(Encoding::BINARY)) a = @prot.read_string expect(a).to eq("this is a test string with unicode characters: \u20AC \u20AD") expect(a.encoding).to eq(Encoding::UTF_8) end it "should read binary" do @trans.write("\"dGhpcyBpcyBhIHRlc3Qgc3RyaW5n\"") expect(@prot.read_binary).to eq("this is a test string") end it "should read long binary" do @trans.write("\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==\"") expect(@prot.read_binary.bytes.to_a).to eq((0...256).to_a) end it "should read a uuid" do @trans.write("\"00112233-4455-6677-8899-aabbccddeeff\"") expect(@prot.read_uuid).to eq("00112233-4455-6677-8899-aabbccddeeff") end it "should normalize uppercase uuid on read" do @trans.write("\"00112233-4455-6677-8899-AABBCCDDEEFF\"") expect(@prot.read_uuid).to eq("00112233-4455-6677-8899-aabbccddeeff") end it "should provide a reasonable to_s" do expect(@prot.to_s).to eq("json(memory)") end end describe Thrift::JsonProtocolFactory do it "should create a JsonProtocol" do expect(Thrift::JsonProtocolFactory.new.get_protocol(double("MockTransport"))).to be_instance_of(Thrift::JsonProtocol) end it "should provide a reasonable to_s" do expect(Thrift::JsonProtocolFactory.new.to_s).to eq("json") end end end thrift-0.23.0/lib/rb/spec/binary_protocol_accelerated_spec.rb0000664000175000017500000000332015165535636024556 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require File.expand_path("#{File.dirname(__FILE__)}/binary_protocol_spec_shared") if defined? Thrift::BinaryProtocolAccelerated describe 'BinaryProtocolAccelerated' do # since BinaryProtocolAccelerated should be directly equivalent to # BinaryProtocol, we don't need any custom specs! it_should_behave_like 'a binary protocol' def protocol_class Thrift::BinaryProtocolAccelerated end describe Thrift::BinaryProtocolAcceleratedFactory do it "should create a BinaryProtocolAccelerated" do expect(Thrift::BinaryProtocolAcceleratedFactory.new.get_protocol(double("MockTransport"))).to be_instance_of(Thrift::BinaryProtocolAccelerated) end it "should provide a reasonable to_s" do expect(Thrift::BinaryProtocolAcceleratedFactory.new.to_s).to eq("binary-accel") end end end else puts "skipping BinaryProtocolAccelerated spec because it is not defined." end thrift-0.23.0/lib/rb/spec/BaseService.thrift0000664000175000017500000000162315165535636021117 0ustar00buildbuild00000000000000# 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 rb Base struct Hello { 1: string greeting = "hello world" } service BaseService { Hello greeting(1:bool english) } thrift-0.23.0/lib/rb/spec/socket_spec.rb0000664000175000017500000000540715167543515020332 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' require File.expand_path("#{File.dirname(__FILE__)}/socket_spec_shared") describe 'Socket' do describe Thrift::Socket do before(:each) do @socket = Thrift::Socket.new @handle = double("Handle", :closed? => false) allow(@handle).to receive(:close) allow(@handle).to receive(:connect_nonblock) allow(@handle).to receive(:setsockopt) allow(::Socket).to receive(:new).and_return(@handle) end it_should_behave_like "a socket" it "should raise a TransportException when it cannot open a socket" do expect(::Socket).to receive(:getaddrinfo).with("localhost", 9090, nil, ::Socket::SOCK_STREAM).and_return([[]]) expect { @socket.open }.to raise_error(Thrift::TransportException) { |e| expect(e.type).to eq(Thrift::TransportException::NOT_OPEN) } end it "should open a ::Socket with default args" do expect(::Socket).to receive(:new).and_return(double("Handle", :connect_nonblock => true, :setsockopt => nil)) expect(::Socket).to receive(:getaddrinfo).with("localhost", 9090, nil, ::Socket::SOCK_STREAM).and_return([[]]) expect(::Socket).to receive(:sockaddr_in) @socket.to_s == "socket(localhost:9090)" @socket.open end it "should accept host/port options" do expect(::Socket).to receive(:new).and_return(double("Handle", :connect_nonblock => true, :setsockopt => nil)) expect(::Socket).to receive(:getaddrinfo).with("my.domain", 1234, nil, ::Socket::SOCK_STREAM).and_return([[]]) expect(::Socket).to receive(:sockaddr_in) @socket = Thrift::Socket.new('my.domain', 1234).open @socket.to_s == "socket(my.domain:1234)" end it "should accept an optional timeout" do allow(::Socket).to receive(:new) expect(Thrift::Socket.new('localhost', 8080, 5).timeout).to eq(5) end it "should provide a reasonable to_s" do allow(::Socket).to receive(:new) expect(Thrift::Socket.new('myhost', 8090).to_s).to eq("socket(myhost:8090)") end end end thrift-0.23.0/lib/rb/spec/ThriftSpec.thrift0000664000175000017500000001005415167543515020772 0ustar00buildbuild00000000000000/* * 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. */ # # 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 rb SpecNamespace struct Hello { 1: string greeting = "hello world" } enum SomeEnum { ONE TWO } struct StructWithSomeEnum { 1: SomeEnum some_enum; } union TestUnion { /** * A doc string */ 1: string string_field; 2: i32 i32_field; 3: i32 other_i32_field; 4: SomeEnum enum_field; 5: binary binary_field; 6: uuid uuid_field; } struct Foo { 1: i32 simple = 53, 2: string words = "words", 3: Hello hello = {'greeting' : "hello, world!"}, 4: list ints = [1, 2, 2, 3], 5: map> complex, 6: set shorts = [5, 17, 239], 7: optional string opt_string 8: bool my_bool 9: optional uuid opt_uuid } struct Foo2 { 1: binary my_binary } struct BoolStruct { 1: bool yesno = 1 } struct SimpleList { 1: list bools, 2: list bytes, 3: list i16s, 4: list i32s, 5: list i64s, 6: list doubles, 7: list strings, 8: list> maps, 9: list> lists, 10: list> sets, 11: list hellos, 12: list uuids } exception Xception { 1: string message, 2: i32 code = 1 } service NonblockingService { Hello greeting(1:bool english) bool block() oneway void unblock(1:i32 n) oneway void shutdown() void sleep(1:double seconds) } union My_union { 1: bool im_true, 2: byte a_bite, 3: i16 integer16, 4: i32 integer32, 5: i64 integer64, 6: double double_precision, 7: string some_characters, 8: i32 other_i32 9: SomeEnum some_enum; 10: map> my_map; 11: uuid unique_id; } struct Struct_with_union { 1: My_union fun_union 2: i32 integer32 3: string some_characters } struct StructWithEnumMap { 1: map> my_map; } # Nested lists struct NestedListInList { 1: list> value } struct NestedListInSet { 1: set> value } struct NestedListInMapKey { 1: map, byte> value } struct NestedListInMapValue { 1: map> value } # Nested sets struct NestedSetInList { 1: list> value } struct NestedSetInSet { 1: set> value } struct NestedSetInMapKey { 1: map, byte> value } struct NestedSetInMapValue { 1: map> value } # Nested maps struct NestedMapInList { 1: list> value } struct NestedMapInSet { 1: set> value } struct NestedMapInMapKey { 2: map, byte> value } struct NestedMapInMapValue { 2: map> value } thrift-0.23.0/lib/rb/spec/spec_helper.rb0000664000175000017500000000424415167543515020317 0ustar00buildbuild00000000000000# encoding: UTF-8 # # 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. # require 'rubygems' require 'rspec' $:.unshift File.join(File.dirname(__FILE__), *%w[.. ext]) # pretend we already loaded fastthread, otherwise the nonblocking_server_spec # will get screwed up # $" << 'fastthread.bundle' require 'thrift' unless Object.method_defined? :tap # if Object#tap isn't defined, then add it; this should only happen in Ruby < 1.8.7 class Object def tap(&block) block.call(self) self end end end RSpec.configure do |configuration| configuration.before(:each) do Thrift.type_checking = true end end $:.unshift File.join(File.dirname(__FILE__), *%w[.. test debug_proto gen-rb]) require 'srv' require 'debug_proto_test_constants' $:.unshift File.join(File.dirname(__FILE__), *%w[gen-rb]) require 'thrift_spec_types' require 'nonblocking_service' module Fixtures COMPACT_PROTOCOL_TEST_STRUCT = Thrift::Test::COMPACT_TEST.dup COMPACT_PROTOCOL_TEST_STRUCT.a_binary = [0, 1, 2, 3, 4, 5, 6, 7, 8].pack('c*') COMPACT_PROTOCOL_TEST_STRUCT.set_byte_map = nil COMPACT_PROTOCOL_TEST_STRUCT.map_byte_map = nil end $:.unshift File.join(File.dirname(__FILE__), *%w[gen-rb/flat]) if defined?(GC.verify_compaction_references) == 'method' # This method was added in Ruby 3.0.0. Calling it this way asks the GC to # move objects around, helping to find object movement bugs. GC.verify_compaction_references(double_heap: true, toward: :empty) end thrift-0.23.0/lib/rb/spec/exception_spec.rb0000664000175000017500000001412315167543515021033 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Exception' do describe Thrift::Exception do it "should have an accessible message" do e = Thrift::Exception.new("test message") expect(e.message).to eq("test message") end end describe Thrift::ApplicationException do it "should inherit from Thrift::Exception" do expect(Thrift::ApplicationException.superclass).to eq(Thrift::Exception) end it "should have an accessible type and message" do e = Thrift::ApplicationException.new expect(e.type).to eq(Thrift::ApplicationException::UNKNOWN) expect(e.message).to be_nil e = Thrift::ApplicationException.new(Thrift::ApplicationException::UNKNOWN_METHOD, "test message") expect(e.type).to eq(Thrift::ApplicationException::UNKNOWN_METHOD) expect(e.message).to eq("test message") end it "should read a struct off of a protocol" do prot = double("MockProtocol") expect(prot).to receive(:read_struct_begin).ordered expect(prot).to receive(:read_field_begin).exactly(3).times.and_return( ["message", Thrift::Types::STRING, 1], ["type", Thrift::Types::I32, 2], [nil, Thrift::Types::STOP, 0] ) expect(prot).to receive(:read_string).ordered.and_return "test message" expect(prot).to receive(:read_i32).ordered.and_return Thrift::ApplicationException::BAD_SEQUENCE_ID expect(prot).to receive(:read_field_end).exactly(2).times expect(prot).to receive(:read_struct_end).ordered e = Thrift::ApplicationException.new e.read(prot) expect(e.message).to eq("test message") expect(e.type).to eq(Thrift::ApplicationException::BAD_SEQUENCE_ID) end it "should skip bad fields when reading a struct" do prot = double("MockProtocol") expect(prot).to receive(:read_struct_begin).ordered expect(prot).to receive(:read_field_begin).exactly(5).times.and_return( ["type", Thrift::Types::I32, 2], ["type", Thrift::Types::STRING, 2], ["message", Thrift::Types::MAP, 1], ["message", Thrift::Types::STRING, 3], [nil, Thrift::Types::STOP, 0] ) expect(prot).to receive(:read_i32).and_return Thrift::ApplicationException::INVALID_MESSAGE_TYPE expect(prot).to receive(:skip).with(Thrift::Types::STRING).twice expect(prot).to receive(:skip).with(Thrift::Types::MAP) expect(prot).to receive(:read_field_end).exactly(4).times expect(prot).to receive(:read_struct_end).ordered e = Thrift::ApplicationException.new e.read(prot) expect(e.message).to be_nil expect(e.type).to eq(Thrift::ApplicationException::INVALID_MESSAGE_TYPE) end it "should write a Thrift::ApplicationException struct to the oprot" do prot = double("MockProtocol") expect(prot).to receive(:write_struct_begin).with("Thrift::ApplicationException").ordered expect(prot).to receive(:write_field_begin).with("message", Thrift::Types::STRING, 1).ordered expect(prot).to receive(:write_string).with("test message").ordered expect(prot).to receive(:write_field_begin).with("type", Thrift::Types::I32, 2).ordered expect(prot).to receive(:write_i32).with(Thrift::ApplicationException::UNKNOWN_METHOD).ordered expect(prot).to receive(:write_field_end).twice expect(prot).to receive(:write_field_stop).ordered expect(prot).to receive(:write_struct_end).ordered e = Thrift::ApplicationException.new(Thrift::ApplicationException::UNKNOWN_METHOD, "test message") e.write(prot) end it "should skip nil fields when writing to the oprot" do prot = double("MockProtocol") expect(prot).to receive(:write_struct_begin).with("Thrift::ApplicationException").ordered expect(prot).to receive(:write_field_begin).with("message", Thrift::Types::STRING, 1).ordered expect(prot).to receive(:write_string).with("test message").ordered expect(prot).to receive(:write_field_end).ordered expect(prot).to receive(:write_field_stop).ordered expect(prot).to receive(:write_struct_end).ordered e = Thrift::ApplicationException.new(nil, "test message") e.write(prot) prot = double("MockProtocol") expect(prot).to receive(:write_struct_begin).with("Thrift::ApplicationException").ordered expect(prot).to receive(:write_field_begin).with("type", Thrift::Types::I32, 2).ordered expect(prot).to receive(:write_i32).with(Thrift::ApplicationException::BAD_SEQUENCE_ID).ordered expect(prot).to receive(:write_field_end).ordered expect(prot).to receive(:write_field_stop).ordered expect(prot).to receive(:write_struct_end).ordered e = Thrift::ApplicationException.new(Thrift::ApplicationException::BAD_SEQUENCE_ID) e.write(prot) prot = double("MockProtocol") expect(prot).to receive(:write_struct_begin).with("Thrift::ApplicationException").ordered expect(prot).to receive(:write_field_stop).ordered expect(prot).to receive(:write_struct_end).ordered e = Thrift::ApplicationException.new(nil) e.write(prot) end end describe Thrift::ProtocolException do it "should have an accessible type" do prot = Thrift::ProtocolException.new(Thrift::ProtocolException::SIZE_LIMIT, "message") expect(prot.type).to eq(Thrift::ProtocolException::SIZE_LIMIT) expect(prot.message).to eq("message") end end end thrift-0.23.0/lib/rb/spec/compact_protocol_spec.rb0000664000175000017500000001573515167543515022416 0ustar00buildbuild00000000000000# encoding: UTF-8 # # 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. # require 'spec_helper' describe Thrift::CompactProtocol do TESTS = { :byte => (-127..127).to_a, :i16 => (0..14).map { |shift| [1 << shift, -(1 << shift)] }.flatten.sort, :i32 => (0..30).map { |shift| [1 << shift, -(1 << shift)] }.flatten.sort, :i64 => (0..62).map { |shift| [1 << shift, -(1 << shift)] }.flatten.sort, :string => ["", "1", "short", "fourteen123456", "fifteen12345678", "unicode characters: \u20AC \u20AD", "1" * 127, "1" * 3000], :binary => ["", "\001", "\001" * 5, "\001" * 14, "\001" * 15, "\001" * 127, "\001" * 3000], :double => [0.0, 1.0, -1.0, 1.1, -1.1, 10000000.1, 1.0/0.0, -1.0/0.0], :bool => [true, false] } it "should encode and decode naked primitives correctly" do TESTS.each_pair do |primitive_type, test_values| test_values.each do |value| # puts "testing #{value}" if primitive_type == :i64 trans = Thrift::MemoryBufferTransport.new proto = Thrift::CompactProtocol.new(trans) proto.send(writer(primitive_type), value) # puts "buf: #{trans.inspect_buffer}" if primitive_type == :i64 read_back = proto.send(reader(primitive_type)) expect(read_back).to eq(value) end end end it "should encode and decode primitives in fields correctly" do TESTS.each_pair do |primitive_type, test_values| final_primitive_type = primitive_type == :binary ? :string : primitive_type thrift_type = Thrift::Types.const_get(final_primitive_type.to_s.upcase) # puts primitive_type test_values.each do |value| trans = Thrift::MemoryBufferTransport.new proto = Thrift::CompactProtocol.new(trans) proto.write_field_begin(nil, thrift_type, 15) proto.send(writer(primitive_type), value) proto.write_field_end proto = Thrift::CompactProtocol.new(trans) name, type, id = proto.read_field_begin expect(type).to eq(thrift_type) expect(id).to eq(15) read_back = proto.send(reader(primitive_type)) expect(read_back).to eq(value) proto.read_field_end end end end it "should write a uuid" do trans = Thrift::MemoryBufferTransport.new proto = Thrift::CompactProtocol.new(trans) proto.write_uuid("00112233-4455-6677-8899-aabbccddeeff") a = trans.read(trans.available) expect(a.unpack('C*')).to eq([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]) end it "should read a uuid" do trans = Thrift::MemoryBufferTransport.new proto = Thrift::CompactProtocol.new(trans) trans.write([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff].pack('C*')) uuid = proto.read_uuid expect(uuid).to eq("00112233-4455-6677-8899-aabbccddeeff") end it "should error gracefully when trying to write an invalid uuid" do trans = Thrift::MemoryBufferTransport.new proto = Thrift::CompactProtocol.new(trans) expect { proto.write_uuid("invalid") }.to raise_error(Thrift::ProtocolException) end it "should encode and decode a monster struct correctly" do trans = Thrift::MemoryBufferTransport.new proto = Thrift::CompactProtocol.new(trans) struct = Thrift::Test::CompactProtoTestStruct.new # sets and maps don't hash well... not sure what to do here. struct.write(proto) struct2 = Thrift::Test::CompactProtoTestStruct.new struct2.read(proto) expect(struct2).to eq(struct) end it "should make method calls correctly" do client_out_trans = Thrift::MemoryBufferTransport.new client_out_proto = Thrift::CompactProtocol.new(client_out_trans) client_in_trans = Thrift::MemoryBufferTransport.new client_in_proto = Thrift::CompactProtocol.new(client_in_trans) processor = Thrift::Test::Srv::Processor.new(JankyHandler.new) client = Thrift::Test::Srv::Client.new(client_in_proto, client_out_proto) client.send_Janky(1) # puts client_out_trans.inspect_buffer processor.process(client_out_proto, client_in_proto) expect(client.recv_Janky).to eq(2) end it "should round-trip wrapped negative seqids in message headers" do trans = Thrift::MemoryBufferTransport.new writer = Thrift::CompactProtocol.new(trans) writer.write_message_begin("test", Thrift::MessageTypes::CALL, -2147483648) writer.write_message_end reader = Thrift::CompactProtocol.new(trans) name, type, seqid = reader.read_message_begin expect(name).to eq("test") expect(type).to eq(Thrift::MessageTypes::CALL) expect(seqid).to eq(-2147483648) end it "should deal with fields following fields that have non-delta ids" do brcp = Thrift::Test::BreaksRubyCompactProtocol.new( :field1 => "blah", :field2 => Thrift::Test::BigFieldIdStruct.new( :field1 => "string1", :field2 => "string2"), :field3 => 3) ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new) bytes = ser.serialize(brcp) deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new) brcp2 = Thrift::Test::BreaksRubyCompactProtocol.new deser.deserialize(brcp2, bytes) expect(brcp2).to eq(brcp) end it "should deserialize an empty map to an empty hash" do struct = Thrift::Test::SingleMapTestStruct.new(:i32_map => {}) ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new) bytes = ser.serialize(struct) deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new) struct2 = Thrift::Test::SingleMapTestStruct.new deser.deserialize(struct2, bytes) expect(struct).to eq(struct2) end it "should provide a reasonable to_s" do trans = Thrift::MemoryBufferTransport.new expect(Thrift::CompactProtocol.new(trans).to_s).to eq("compact(memory)") end class JankyHandler def Janky(i32arg) i32arg * 2 end end def writer(sym) "write_#{sym.to_s}" end def reader(sym) "read_#{sym.to_s}" end end describe Thrift::CompactProtocolFactory do it "should create a CompactProtocol" do expect(Thrift::CompactProtocolFactory.new.get_protocol(double("MockTransport"))).to be_instance_of(Thrift::CompactProtocol) end it "should provide a reasonable to_s" do expect(Thrift::CompactProtocolFactory.new.to_s).to eq("compact") end end thrift-0.23.0/lib/rb/spec/serializer_spec.rb0000664000175000017500000000630015167543515021204 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'Serializer' do describe Thrift::Serializer do it "should serialize structs to binary by default" do serializer = Thrift::Serializer.new(Thrift::BinaryProtocolAcceleratedFactory.new) data = serializer.serialize(SpecNamespace::Hello.new(:greeting => "'Ello guv'nor!")) expect(data).to eq("\x0B\x00\x01\x00\x00\x00\x0E'Ello guv'nor!\x00") end it "should serialize structs to the given protocol" do protocol = Thrift::BaseProtocol.new(double("transport")) expect(protocol).to receive(:write_struct_begin).with("SpecNamespace::Hello") expect(protocol).to receive(:write_field_begin).with("greeting", Thrift::Types::STRING, 1) expect(protocol).to receive(:write_string).with("Good day") expect(protocol).to receive(:write_field_end) expect(protocol).to receive(:write_field_stop) expect(protocol).to receive(:write_struct_end) protocol_factory = double("ProtocolFactory") allow(protocol_factory).to receive(:get_protocol).and_return(protocol) serializer = Thrift::Serializer.new(protocol_factory) serializer.serialize(SpecNamespace::Hello.new(:greeting => "Good day")) end end describe Thrift::Deserializer do it "should deserialize structs from binary by default" do deserializer = Thrift::Deserializer.new data = "\x0B\x00\x01\x00\x00\x00\x0E'Ello guv'nor!\x00" expect(deserializer.deserialize(SpecNamespace::Hello.new, data)).to eq(SpecNamespace::Hello.new(:greeting => "'Ello guv'nor!")) end it "should deserialize structs from the given protocol" do protocol = Thrift::BaseProtocol.new(double("transport")) expect(protocol).to receive(:read_struct_begin).and_return("SpecNamespace::Hello") expect(protocol).to receive(:read_field_begin).and_return(["greeting", Thrift::Types::STRING, 1], [nil, Thrift::Types::STOP, 0]) expect(protocol).to receive(:read_string).and_return("Good day") expect(protocol).to receive(:read_field_end) expect(protocol).to receive(:read_struct_end) protocol_factory = double("ProtocolFactory") allow(protocol_factory).to receive(:get_protocol).and_return(protocol) deserializer = Thrift::Deserializer.new(protocol_factory) expect(deserializer.deserialize(SpecNamespace::Hello.new, "")).to eq(SpecNamespace::Hello.new(:greeting => "Good day")) end end end thrift-0.23.0/lib/rb/spec/flat_spec.rb0000664000175000017500000000413715165535636017772 0ustar00buildbuild00000000000000# # 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. # require 'spec_helper' describe 'generation' do before do require 'namespaced_nonblocking_service' end it "did not generate the wrong files" do prefix = File.expand_path("../gen-rb/flat", __FILE__) ["namespaced_spec_namespace/namespaced_nonblocking_service.rb", "namespaced_spec_namespace/thrift_namespaced_spec_constants.rb", "namespaced_spec_namespace/thrift_namespaced_spec_types.rb", "other_namespace/referenced_constants.rb", "other_namespace/referenced_types.rb" ].each do |name| expect(File.exist?(File.join(prefix, name))).not_to be_truthy end end it "generated the right files" do prefix = File.expand_path("../gen-rb/flat", __FILE__) ["namespaced_nonblocking_service.rb", "thrift_namespaced_spec_constants.rb", "thrift_namespaced_spec_types.rb", "referenced_constants.rb", "referenced_types.rb" ].each do |name| expect(File.exist?(File.join(prefix, name))).to be_truthy end end it "has a service class in the right place" do expect(defined?(NamespacedSpecNamespace::NamespacedNonblockingService)).to be_truthy end it "has a struct in the right place" do expect(defined?(NamespacedSpecNamespace::Hello)).to be_truthy end it "required an included file" do expect(defined?(OtherNamespace::SomeEnum)).to be_truthy end end thrift-0.23.0/lib/rb/lib/0000775000175000017500000000000015167543515015311 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/lib/thrift.rb0000664000175000017500000000472315167543515017144 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Contains some contributions under the Thrift Software License. # Please see doc/old-thrift-license.txt in the Thrift distribution for # details. $:.unshift File.dirname(__FILE__) require 'thrift/bytes' require 'thrift/exceptions' require 'thrift/types' require 'thrift/processor' require 'thrift/multiplexed_processor' require 'thrift/client' require 'thrift/struct' require 'thrift/union' require 'thrift/struct_union' require 'thrift/uuid' # serializer require 'thrift/serializer/serializer' require 'thrift/serializer/deserializer' # protocol require 'thrift/protocol/base_protocol' require 'thrift/protocol/binary_protocol' require 'thrift/protocol/binary_protocol_accelerated' require 'thrift/protocol/compact_protocol' require 'thrift/protocol/json_protocol' require 'thrift/protocol/multiplexed_protocol' require 'thrift/protocol/header_protocol' # transport require 'thrift/transport/base_transport' require 'thrift/transport/base_server_transport' require 'thrift/transport/socket' require 'thrift/transport/ssl_socket' require 'thrift/transport/server_socket' require 'thrift/transport/ssl_server_socket' require 'thrift/transport/unix_socket' require 'thrift/transport/unix_server_socket' require 'thrift/transport/buffered_transport' require 'thrift/transport/framed_transport' require 'thrift/transport/header_transport' require 'thrift/transport/http_client_transport' require 'thrift/transport/io_stream_transport' require 'thrift/transport/memory_buffer_transport' # server require 'thrift/server/base_server' require 'thrift/server/nonblocking_server' require 'thrift/server/simple_server' require 'thrift/server/threaded_server' require 'thrift/server/thread_pool_server' require 'thrift/thrift_native' thrift-0.23.0/lib/rb/lib/thrift/0000775000175000017500000000000015170007142016572 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/lib/thrift/bytes.rb0000664000175000017500000000644715167543515020277 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # module Thrift # A collection of utilities for working with bytes and byte buffers. module Bytes # Creates and empty byte buffer (String with BINARY encoding) # # size - The Integer size of the buffer (default: nil) to create # # Returns a String with BINARY encoding, filled with null characters # if size is greater than zero def self.empty_byte_buffer(size = nil) if (size && size > 0) "\0".b * size else ''.b end end # Forces the encoding of the buffer to BINARY. If the buffer # passed is frozen, then it will be duplicated. # # buffer - The String to force the encoding of. # # Returns the String passed with an encoding of BINARY; returned # String may be a duplicate. def self.force_binary_encoding(buffer) buffer = buffer.dup if buffer.frozen? buffer.force_encoding(Encoding::BINARY) end # Gets the byte value of a given position in a String. # # string - The String to retrive the byte value from. # index - The Integer location of the byte value to retrieve. # # Returns an Integer value between 0 and 255. def self.get_string_byte(string, index) string.getbyte(index) end # Sets the byte value given to a given index in a String. # # string - The String to set the byte value in. # index - The Integer location to set the byte value at. # byte - The Integer value (0 to 255) to set in the string. # # Returns an Integer value of the byte value to set. def self.set_string_byte(string, index, byte) string.setbyte(index, byte) end # Converts the given String to a UTF-8 byte buffer. # # string - The String to convert. # # Returns a new String with BINARY encoding, containing the UTF-8 # bytes of the original string. def self.convert_to_utf8_byte_buffer(string) if string.encoding != Encoding::UTF_8 # transcode to UTF-8 string = string.encode(Encoding::UTF_8) else # encoding is already UTF-8, but a duplicate is needed string = string.dup end string.force_encoding(Encoding::BINARY) end # Converts the given UTF-8 byte buffer into a String # # utf8_buffer - A String, with BINARY encoding, containing UTF-8 bytes # # Returns a new String with UTF-8 encoding, def self.convert_to_string(utf8_buffer) # duplicate the buffer, force encoding to UTF-8 utf8_buffer.dup.force_encoding(Encoding::UTF_8) end end end thrift-0.23.0/lib/rb/lib/thrift/serializer/0000775000175000017500000000000015167543515020762 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/lib/thrift/serializer/deserializer.rb0000664000175000017500000000215015167543515023767 0ustar00buildbuild00000000000000# # 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. # module Thrift class Deserializer def initialize(protocol_factory = BinaryProtocolFactory.new) @transport = MemoryBufferTransport.new @protocol = protocol_factory.get_protocol(@transport) end def deserialize(base, buffer) @transport.reset_buffer(buffer) base.read(@protocol) base end end end thrift-0.23.0/lib/rb/lib/thrift/serializer/serializer.rb0000664000175000017500000000216615167543515023465 0ustar00buildbuild00000000000000# # 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. # module Thrift class Serializer def initialize(protocol_factory = BinaryProtocolFactory.new) @transport = MemoryBufferTransport.new @protocol = protocol_factory.get_protocol(@transport) end def serialize(base) @transport.reset_buffer base.write(@protocol) @transport.read(@transport.available) end end end thrift-0.23.0/lib/rb/lib/thrift/union.rb0000664000175000017500000001235615167543515020275 0ustar00buildbuild00000000000000# # 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. # module Thrift class Union def initialize(name = nil, value = nil) if name if name.is_a? Hash if name.size > 1 raise "#{self.class} cannot be instantiated with more than one field!" end name, value = name.keys.first, name.values.first end if Thrift.type_checking raise Exception, "#{self.class} does not contain a field named #{name}!" unless name_to_id(name.to_s) end if value.nil? raise Exception, "Union #{self.class} cannot be instantiated with setfield and nil value!" end Thrift.check_type(value, struct_fields[name_to_id(name.to_s)], name) if Thrift.type_checking elsif !value.nil? raise Exception, "Value provided, but no name!" end @setfield = name @value = value end def inspect if get_set_field "<#{self.class} #{@setfield}: #{inspect_field(@value, struct_fields[name_to_id(@setfield.to_s)])}>" else "<#{self.class} >" end end def read(iprot) iprot.read_struct_begin fname, ftype, fid = iprot.read_field_begin handle_message(iprot, fid, ftype) iprot.read_field_end fname, ftype, fid = iprot.read_field_begin unless (ftype == Types::STOP) raise ProtocolException.new(ProtocolException::INVALID_DATA, "Too many fields for union") end iprot.read_struct_end validate end def write(oprot) validate oprot.write_struct_begin(self.class.name) fid = self.name_to_id(@setfield.to_s) field_info = struct_fields[fid] unless field_info raise ProtocolException.new(ProtocolException::INVALID_DATA, "set_field is not valid for this union!") end type = field_info[:type] if is_container? type oprot.write_field_begin(@setfield, type, fid) write_container(oprot, @value, field_info) oprot.write_field_end else oprot.write_field(@setfield, type, fid, @value) end oprot.write_field_stop oprot.write_struct_end end def ==(other) other.equal?(self) || other.instance_of?(self.class) && @setfield == other.get_set_field && @value == other.get_value end alias_method :eql?, :== def hash [self.class.name, @setfield, @value].hash end def self.field_accessor(klass, field_info) klass.send :define_method, field_info[:name] do if field_info[:name].to_sym == @setfield @value else raise RuntimeError, "#{field_info[:name]} is not union's set field." end end klass.send :define_method, "#{field_info[:name]}=" do |value| Thrift.check_type(value, field_info, field_info[:name]) if Thrift.type_checking @setfield = field_info[:name].to_sym @value = value end end def self.qmark_isset_method(klass, field_info) klass.send :define_method, "#{field_info[:name]}?" do get_set_field == field_info[:name].to_sym && !get_value.nil? end end def self.generate_accessors(klass) klass::FIELDS.values.each do |field_info| field_accessor(klass, field_info) qmark_isset_method(klass, field_info) end end # get the symbol that indicates what the currently set field type is. def get_set_field @setfield end # get the current value of this union, regardless of what the set field is. # generally, you should only use this method when you don't know in advance # what field to expect. def get_value @value end def <=>(other) if self.class == other.class if get_set_field == other.get_set_field if get_set_field.nil? 0 else get_value <=> other.get_value end else if get_set_field && other.get_set_field.nil? -1 elsif get_set_field.nil? && other.get_set_field 1 elsif get_set_field.nil? && other.get_set_field.nil? 0 else name_to_id(get_set_field.to_s) <=> name_to_id(other.get_set_field.to_s) end end else self.class <=> other.class end end protected def handle_message(iprot, fid, ftype) field = struct_fields[fid] if field and field[:type] == ftype @value = read_field(iprot, field) name = field[:name].to_sym @setfield = name else iprot.skip(ftype) end end end end thrift-0.23.0/lib/rb/lib/thrift/processor.rb0000664000175000017500000000441415167543515021160 0ustar00buildbuild00000000000000# # 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. # require 'logger' module Thrift module Processor def initialize(handler, logger = nil) @handler = handler if logger.nil? @logger = Logger.new(STDERR) @logger.level = Logger::WARN else @logger = logger end end def process(iprot, oprot) name, type, seqid = iprot.read_message_begin if respond_to?("process_#{name}") begin send("process_#{name}", seqid, iprot, oprot) rescue => e x = ApplicationException.new(ApplicationException::INTERNAL_ERROR, 'Internal error') @logger.debug "Internal error : #{e.message}\n#{e.backtrace.join("\n")}" write_error(x, oprot, name, seqid) end true else iprot.skip(Types::STRUCT) iprot.read_message_end x = ApplicationException.new(ApplicationException::UNKNOWN_METHOD, 'Unknown function '+name) write_error(x, oprot, name, seqid) false end end def read_args(iprot, args_class) args = args_class.new args.read(iprot) iprot.read_message_end args end def write_result(result, oprot, name, seqid) oprot.write_message_begin(name, MessageTypes::REPLY, seqid) result.write(oprot) oprot.write_message_end oprot.trans.flush end def write_error(err, oprot, name, seqid) oprot.write_message_begin(name, MessageTypes::EXCEPTION, seqid) err.write(oprot) oprot.write_message_end oprot.trans.flush end end end thrift-0.23.0/lib/rb/lib/thrift/thrift_native.rb0000664000175000017500000000163315170007142021770 0ustar00buildbuild00000000000000# # 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. # begin require "thrift_native" rescue LoadError puts "Unable to load thrift_native extension. Defaulting to pure Ruby libraries." end thrift-0.23.0/lib/rb/lib/thrift/exceptions.rb0000664000175000017500000000442515167543515021324 0ustar00buildbuild00000000000000# # 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. # module Thrift class Exception < StandardError def initialize(message) super @message = message end attr_reader :message end class ApplicationException < Exception UNKNOWN = 0 UNKNOWN_METHOD = 1 INVALID_MESSAGE_TYPE = 2 WRONG_METHOD_NAME = 3 BAD_SEQUENCE_ID = 4 MISSING_RESULT = 5 INTERNAL_ERROR = 6 PROTOCOL_ERROR = 7 INVALID_TRANSFORM = 8 INVALID_PROTOCOL = 9 UNSUPPORTED_CLIENT_TYPE = 10 attr_reader :type def initialize(type = UNKNOWN, message = nil) super(message) @type = type end def read(iprot) iprot.read_struct_begin while true fname, ftype, fid = iprot.read_field_begin if ftype == Types::STOP break end if fid == 1 and ftype == Types::STRING @message = iprot.read_string elsif fid == 2 and ftype == Types::I32 @type = iprot.read_i32 else iprot.skip(ftype) end iprot.read_field_end end iprot.read_struct_end end def write(oprot) oprot.write_struct_begin('Thrift::ApplicationException') unless @message.nil? oprot.write_field_begin('message', Types::STRING, 1) oprot.write_string(@message) oprot.write_field_end end unless @type.nil? oprot.write_field_begin('type', Types::I32, 2) oprot.write_i32(@type) oprot.write_field_end end oprot.write_field_stop oprot.write_struct_end end end end thrift-0.23.0/lib/rb/lib/thrift/uuid.rb0000664000175000017500000000317515167543515020112 0ustar00buildbuild00000000000000# # 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. # require 'thrift/protocol/base_protocol' module Thrift module UUID UUID_REGEX = /\A[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\z/.freeze def self.validate_uuid!(uuid) unless uuid.is_a?(String) raise ProtocolException.new(ProtocolException::INVALID_DATA, 'UUID must be a string') end unless uuid =~ UUID_REGEX raise ProtocolException.new(ProtocolException::INVALID_DATA, 'Invalid UUID format') end end def self.uuid_bytes(uuid) [uuid.delete('-')].pack('H*') end def self.uuid_from_bytes(bytes) unless bytes.bytesize == 16 raise ProtocolException.new(ProtocolException::INVALID_DATA, 'Invalid UUID data length') end hex = bytes.unpack('H*').first "#{hex[0, 8]}-#{hex[8, 4]}-#{hex[12, 4]}-#{hex[16, 4]}-#{hex[20, 12]}" end end end thrift-0.23.0/lib/rb/lib/thrift/struct.rb0000664000175000017500000001670315167543515020471 0ustar00buildbuild00000000000000# # 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. # require 'set' module Thrift module Struct def initialize(d = {}, &block) # get a copy of the default values to work on, removing defaults in favor of arguments fields_with_defaults = fields_with_default_values.dup # check if the defaults is empty, or if there are no parameters for this # instantiation, and if so, don't bother overriding defaults. unless fields_with_defaults.empty? || d.empty? d.each_key do |name| fields_with_defaults.delete(name.to_s) end end # assign all the user-specified arguments unless d.empty? d.each do |name, value| unless name_to_id(name.to_s) raise Exception, "Unknown key given to #{self.class}.new: #{name}" end Thrift.check_type(value, struct_fields[name_to_id(name.to_s)], name) if Thrift.type_checking instance_variable_set("@#{name}", value) end end # assign all the default values unless fields_with_defaults.empty? fields_with_defaults.each do |name, default_value| instance_variable_set("@#{name}", (default_value.dup rescue default_value)) end end yield self if block_given? end def fields_with_default_values fields_with_default_values = self.class.instance_variable_get(:@fields_with_default_values) unless fields_with_default_values fields_with_default_values = {} struct_fields.each do |fid, field_def| unless field_def[:default].nil? fields_with_default_values[field_def[:name]] = field_def[:default] end end self.class.instance_variable_set(:@fields_with_default_values, fields_with_default_values) end fields_with_default_values end def inspect(skip_optional_nulls = true) fields = [] each_field do |fid, field_info| name = field_info[:name] value = instance_variable_get("@#{name}") unless skip_optional_nulls && field_info[:optional] && value.nil? fields << "#{name}:#{inspect_field(value, field_info)}" end end "<#{self.class} #{fields.join(", ")}>" end def read(iprot) iprot.read_struct_begin loop do fname, ftype, fid = iprot.read_field_begin break if (ftype == Types::STOP) handle_message(iprot, fid, ftype) iprot.read_field_end end iprot.read_struct_end validate end def write(oprot) validate oprot.write_struct_begin(self.class.name) each_field do |fid, field_info| name = field_info[:name] type = field_info[:type] value = instance_variable_get("@#{name}") unless value.nil? if is_container? type oprot.write_field_begin(name, type, fid) write_container(oprot, value, field_info) oprot.write_field_end else oprot.write_field(field_info, fid, value) end end end oprot.write_field_stop oprot.write_struct_end end def ==(other) return false if other.nil? each_field do |fid, field_info| name = field_info[:name] return false unless other.respond_to?(name) && self.send(name) == other.send(name) end true end def eql?(other) self.class == other.class && self == other end # This implementation of hash() is inspired by Apache's Java HashCodeBuilder class. def hash total = 17 each_field do |fid, field_info| name = field_info[:name] value = self.send(name) total = (total * 37 + value.hash) & 0xffffffff end total end def differences(other) diffs = [] unless other.is_a?(self.class) diffs << "Different class!" else each_field do |fid, field_info| name = field_info[:name] diffs << "#{name} differs!" unless self.instance_variable_get("@#{name}") == other.instance_variable_get("@#{name}") end end diffs end def self.field_accessor(klass, field_info) field_name_sym = field_info[:name].to_sym klass.send :attr_reader, field_name_sym klass.send :define_method, "#{field_info[:name]}=" do |value| Thrift.check_type(value, field_info, field_info[:name]) if Thrift.type_checking instance_variable_set("@#{field_name_sym}", value) end end def self.generate_accessors(klass) klass::FIELDS.values.each do |field_info| field_accessor(klass, field_info) qmark_isset_method(klass, field_info) end end def self.qmark_isset_method(klass, field_info) klass.send :define_method, "#{field_info[:name]}?" do !self.send(field_info[:name].to_sym).nil? end end def <=>(other) if self.class == other.class each_field do |fid, field_info| v1 = self.send(field_info[:name]) v1_set = !v1.nil? v2 = other.send(field_info[:name]) v2_set = !v2.nil? if v1_set && !v2_set return -1 elsif !v1_set && v2_set return 1 elsif v1_set && v2_set cmp = v1 <=> v2 if cmp != 0 return cmp end end end 0 else self.class <=> other.class end end protected def self.append_features(mod) if mod.ancestors.include? ::Exception mod.send :class_variable_set, :'@@__thrift_struct_real_initialize', mod.instance_method(:initialize) super # set up our custom initializer so `raise Xception, 'message'` works mod.send :define_method, :struct_initialize, mod.instance_method(:initialize) mod.send :define_method, :initialize, mod.instance_method(:exception_initialize) else super end end def exception_initialize(*args, &block) if args.size == 1 and args.first.is_a? Hash # looks like it's a regular Struct initialize method(:struct_initialize).call(args.first) else # call the Struct initializer first with no args # this will set our field default values method(:struct_initialize).call() # now give it to the exception self.class.send(:class_variable_get, :'@@__thrift_struct_real_initialize').bind(self).call(*args, &block) if args.size > 0 # self.class.instance_method(:initialize).bind(self).call(*args, &block) end end def handle_message(iprot, fid, ftype) field = struct_fields[fid] if field and field[:type] == ftype value = read_field(iprot, field) instance_variable_set("@#{field[:name]}", value) else iprot.skip(ftype) end end end end thrift-0.23.0/lib/rb/lib/thrift/multiplexed_processor.rb0000664000175000017500000000450515167543515023575 0ustar00buildbuild00000000000000# # 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. require 'thrift/protocol/protocol_decorator' require 'thrift/protocol/base_protocol' module Thrift class MultiplexedProcessor def initialize @actual_processors = {} end def register_processor(service_name, processor) @actual_processors[service_name] = processor end def process(iprot, oprot) name, type, seqid = iprot.read_message_begin check_type(type) check_separator(name) service_name, method = name.split(':') processor(service_name).process(StoredMessageProtocol.new(iprot, [method, type, seqid]), oprot) end protected def processor(service_name) if @actual_processors.has_key?(service_name) @actual_processors[service_name] else raise Thrift::Exception.new("Service name not found: #{service_name}. Did you forget to call #{self.class.name}#register_processor?") end end def check_type(type) unless [MessageTypes::CALL, MessageTypes::ONEWAY].include?(type) raise Thrift::Exception.new('This should not have happened!?') end end def check_separator(name) if name.count(':') < 1 raise Thrift::Exception.new("Service name not found in message name: #{name}. Did you forget to use a Thrift::Protocol::MultiplexedProtocol in your client?") end end end class StoredMessageProtocol < BaseProtocol include ProtocolDecorator def initialize(protocol, message_begin) super(protocol) @message_begin = message_begin end def read_message_begin @message_begin end end end thrift-0.23.0/lib/rb/lib/thrift/server/0000775000175000017500000000000015170007142020100 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/lib/thrift/server/base_server.rb0000664000175000017500000000254215167543515022747 0ustar00buildbuild00000000000000# # 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. # module Thrift class BaseServer def initialize(processor, server_transport, transport_factory = nil, protocol_factory = nil) @processor = processor @server_transport = server_transport @transport_factory = transport_factory ? transport_factory : Thrift::BaseTransportFactory.new @protocol_factory = protocol_factory ? protocol_factory : Thrift::BinaryProtocolFactory.new end def serve raise NotImplementedError end def to_s "server(#{@protocol_factory.to_s}(#{@transport_factory.to_s}(#{@server_transport.to_s})))" end end end thrift-0.23.0/lib/rb/lib/thrift/server/mongrel_http_server.rb0000664000175000017500000000417315167543515024541 0ustar00buildbuild00000000000000# # 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. # require 'mongrel' ## Sticks a service on a URL, using mongrel to do the HTTP work # DEPRECATED: Please use Thrift::ThinHTTPServer instead. module Thrift class MongrelHTTPServer < BaseServer class Handler < Mongrel::HttpHandler def initialize(processor, protocol_factory) @processor = processor @protocol_factory = protocol_factory end def process(request, response) if request.params["REQUEST_METHOD"] == "POST" response.start(200) do |head, out| head["Content-Type"] = "application/x-thrift" transport = IOStreamTransport.new request.body, out protocol = @protocol_factory.get_protocol transport @processor.process protocol, protocol end else response.start(404) {} end end end def initialize(processor, opts = {}) Kernel.warn "[DEPRECATION WARNING] `Thrift::MongrelHTTPServer` is deprecated. Please use `Thrift::ThinHTTPServer` instead." port = opts[:port] || 80 ip = opts[:ip] || "0.0.0.0" path = opts[:path] || "" protocol_factory = opts[:protocol_factory] || BinaryProtocolFactory.new @server = Mongrel::HttpServer.new ip, port @server.register "/#{path}", Handler.new(processor, protocol_factory) end def serve @server.run.join end end end thrift-0.23.0/lib/rb/lib/thrift/server/threaded_server.rb0000664000175000017500000000275115167543515023617 0ustar00buildbuild00000000000000# # 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. # require 'thread' module Thrift class ThreadedServer < BaseServer def serve begin @server_transport.listen loop do client = @server_transport.accept trans = @transport_factory.get_transport(client) prot = @protocol_factory.get_protocol(trans) Thread.new(prot, trans) do |p, t| begin loop do @processor.process(p, p) end rescue Thrift::TransportException, Thrift::ProtocolException ensure t.close end end end ensure @server_transport.close end end def to_s "threaded(#{super.to_s})" end end end thrift-0.23.0/lib/rb/lib/thrift/server/thread_pool_server.rb0000664000175000017500000000474615167543515024345 0ustar00buildbuild00000000000000# # 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. # require 'thread' module Thrift class ThreadPoolServer < BaseServer def initialize(processor, server_transport, transport_factory = nil, protocol_factory = nil, num = 20) super(processor, server_transport, transport_factory, protocol_factory) @thread_q = SizedQueue.new(num) @exception_q = Queue.new @running = false end ## exceptions that happen in worker threads will be relayed here and ## must be caught. 'retry' can be used to continue. (threads will ## continue to run while the exception is being handled.) def rescuable_serve Thread.new { serve } unless @running @running = true raise @exception_q.pop end ## exceptions that happen in worker threads simply cause that thread ## to die and another to be spawned in its place. def serve @server_transport.listen begin loop do @thread_q.push(:token) Thread.new do begin loop do client = @server_transport.accept trans = @transport_factory.get_transport(client) prot = @protocol_factory.get_protocol(trans) begin loop do @processor.process(prot, prot) end rescue Thrift::TransportException, Thrift::ProtocolException => e ensure trans.close end end rescue => e @exception_q.push(e) ensure @thread_q.pop # thread died! end end end ensure @server_transport.close end end def to_s "threadpool(#{super.to_s})" end end end thrift-0.23.0/lib/rb/lib/thrift/server/simple_server.rb0000664000175000017500000000262315167543515023326 0ustar00buildbuild00000000000000# # 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. # module Thrift class SimpleServer < BaseServer def serve begin @server_transport.listen loop do client = @server_transport.accept trans = @transport_factory.get_transport(client) prot = @protocol_factory.get_protocol(trans) begin loop do @processor.process(prot, prot) end rescue Thrift::TransportException, Thrift::ProtocolException ensure trans.close end end ensure @server_transport.close end end def to_s "simple(#{super.to_s})" end end end thrift-0.23.0/lib/rb/lib/thrift/server/nonblocking_server.rb0000664000175000017500000002165115170007142024323 0ustar00buildbuild00000000000000# # 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. # require 'logger' require 'thread' module Thrift # this class expects to always use a FramedTransport for reading messages class NonblockingServer < BaseServer def initialize(processor, server_transport, transport_factory = nil, protocol_factory = nil, num = 20, logger = nil) super(processor, server_transport, transport_factory, protocol_factory) @num_threads = num if logger.nil? @logger = Logger.new(STDERR) @logger.level = Logger::WARN else @logger = logger end @shutdown_semaphore = Mutex.new @transport_semaphore = Mutex.new end def serve @logger.info "Starting #{self}" @server_transport.listen @io_manager = start_io_manager begin loop do break if @server_transport.closed? begin rd, = select([@server_transport], nil, nil, 0.1) rescue Errno::EBADF => e # In Ruby 1.9, calling @server_transport.close in shutdown paths causes the select() to raise an # Errno::EBADF. If this happens, ignore it and retry the loop. break end next if rd.nil? socket = @server_transport.accept @logger.debug "Accepted socket: #{socket.inspect}" @io_manager.add_connection socket end rescue IOError => e end # we must be shutting down @logger.info "#{self} is shutting down, goodbye" ensure @transport_semaphore.synchronize do @server_transport.close end @io_manager.ensure_closed unless @io_manager.nil? end def shutdown(timeout = 0, block = true) @shutdown_semaphore.synchronize do return if @is_shutdown @is_shutdown = true end # nonblocking is intended for calling from within a Handler # but we can't change the order of operations here, so lets thread shutdown_proc = lambda do @io_manager.shutdown(timeout) @transport_semaphore.synchronize do @server_transport.close # this will break the accept loop end end if block shutdown_proc.call else Thread.new &shutdown_proc end end private def start_io_manager iom = IOManager.new(@processor, @server_transport, @transport_factory, @protocol_factory, @num_threads, @logger) iom.spawn iom end class IOManager # :nodoc: DEFAULT_BUFFER = 2**20 def initialize(processor, server_transport, transport_factory, protocol_factory, num, logger) @processor = processor @server_transport = server_transport @transport_factory = transport_factory @protocol_factory = protocol_factory @num_threads = num @logger = logger @connections = [] @buffers = Hash.new { |h, k| h[k] = '' } @signal_queue = Queue.new @signal_pipes = IO.pipe @signal_pipes[1].sync = true @worker_queue = Queue.new @shutdown_queue = Queue.new end def add_connection(socket) signal [:connection, socket] end def spawn @iom_thread = Thread.new do @logger.debug "Starting #{self}" run end end def shutdown(timeout = 0) @logger.debug "#{self} is shutting down workers" @worker_queue.clear @num_threads.times { @worker_queue.push [:shutdown] } signal [:shutdown, timeout] @shutdown_queue.pop @signal_pipes[0].close @signal_pipes[1].close @logger.debug "#{self} is shutting down, goodbye" end def ensure_closed kill_worker_threads if @worker_threads @iom_thread.kill end private def run spin_worker_threads loop do rd, = select([@signal_pipes[0], *@connections]) if rd.delete @signal_pipes[0] break if read_signals == :shutdown end rd.each do |fd| begin if fd.handle.eof? remove_connection fd else read_connection fd end rescue Errno::ECONNRESET remove_connection fd end end end join_worker_threads(@shutdown_timeout) ensure @shutdown_queue.push :shutdown end def read_connection(fd) @buffers[fd] << fd.read(DEFAULT_BUFFER) while(frame = slice_frame!(@buffers[fd])) @logger.debug "#{self} is processing a frame" @worker_queue.push [:frame, fd, frame] end end def spin_worker_threads @logger.debug "#{self} is spinning up worker threads" @worker_threads = [] @num_threads.times do @worker_threads << spin_thread end end def spin_thread Worker.new(@processor, @transport_factory, @protocol_factory, @logger, @worker_queue).spawn end def signal(msg) @signal_queue << msg @signal_pipes[1].write " " end def read_signals # clear the signal pipe # note that since read_nonblock is broken in jruby, # we can only read up to a set number of signals at once sigstr = @signal_pipes[0].readpartial(1024) # now read the signals begin sigstr.length.times do signal, obj = @signal_queue.pop(true) case signal when :connection @connections << obj when :shutdown @shutdown_timeout = obj return :shutdown end end rescue ThreadError # out of signals # note that in a perfect world this would never happen, since we're # only reading the number of signals pushed on the pipe, but given the lack # of locks, in theory we could clear the pipe/queue while a new signal is being # placed on the pipe, at which point our next read_signals would hit this error end end def remove_connection(fd) # don't explicitly close it, a thread may still be writing to it @connections.delete fd @buffers.delete fd end def join_worker_threads(shutdown_timeout) start = Time.now @worker_threads.each do |t| if shutdown_timeout > 0 timeout = (start + shutdown_timeout) - Time.now break if timeout <= 0 t.join(timeout) else t.join end end kill_worker_threads end def kill_worker_threads @worker_threads.each do |t| t.kill if t.status end @worker_threads.clear end def slice_frame!(buf) if buf.length >= 4 size = buf.unpack('N').first if buf.length >= size + 4 buf.slice!(0, size + 4) else nil end else nil end end class Worker # :nodoc: def initialize(processor, transport_factory, protocol_factory, logger, queue) @processor = processor @transport_factory = transport_factory @protocol_factory = protocol_factory @logger = logger @queue = queue end def spawn Thread.new do @logger.debug "#{self} is spawning" run end end private def run loop do cmd, *args = @queue.pop case cmd when :shutdown @logger.debug "#{self} is shutting down, goodbye" break when :frame fd, frame = args begin otrans = @transport_factory.get_transport(fd) oprot = @protocol_factory.get_protocol(otrans) membuf = MemoryBufferTransport.new(frame) itrans = @transport_factory.get_transport(membuf) iprot = @protocol_factory.get_protocol(itrans) @processor.process(iprot, oprot) rescue => e @logger.error "#{Thread.current.inspect} raised error: #{e.inspect}\n#{e.backtrace.join("\n")}" end end end end end end end end thrift-0.23.0/lib/rb/lib/thrift/server/thin_http_server.rb0000664000175000017500000000535015167543515024036 0ustar00buildbuild00000000000000# # 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. # require 'rack' require 'thin' ## # Wraps the Thin web server to provide a Thrift server over HTTP. module Thrift class ThinHTTPServer < BaseServer ## # Accepts a Thrift::Processor # Options include: # * :port # * :ip # * :path # * :protocol_factory def initialize(processor, options = {}) port = options[:port] || 80 ip = options[:ip] || "0.0.0.0" path = options[:path] || "/" protocol_factory = options[:protocol_factory] || BinaryProtocolFactory.new app = RackApplication.for(path, processor, protocol_factory) @server = Thin::Server.new(ip, port, app) end ## # Starts the server def serve @server.start end class RackApplication THRIFT_HEADER = "application/x-thrift" def self.for(path, processor, protocol_factory) Rack::Builder.new do use Rack::CommonLogger use Rack::ShowExceptions use Rack::Lint map path do run lambda { |env| request = Rack::Request.new(env) if RackApplication.valid_thrift_request?(request) RackApplication.successful_request(request, processor, protocol_factory).finish else RackApplication.failed_request.finish end } end end end def self.successful_request(rack_request, processor, protocol_factory) response = Rack::Response.new([], 200, {'Content-Type' => THRIFT_HEADER}) transport = IOStreamTransport.new rack_request.body, response protocol = protocol_factory.get_protocol transport processor.process protocol, protocol response end def self.failed_request Rack::Response.new(['Not Found'], 404, {'Content-Type' => THRIFT_HEADER}) end def self.valid_thrift_request?(rack_request) rack_request.post? && rack_request.env["CONTENT_TYPE"] == THRIFT_HEADER end end end end thrift-0.23.0/lib/rb/lib/thrift/struct_union.rb0000664000175000017500000001424715167543515021702 0ustar00buildbuild00000000000000# # 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. # require 'set' module Thrift module Struct_Union def validate_container_size(size) return size unless size < 0 raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') end def name_to_id(name) names_to_ids = self.class.instance_variable_get(:@names_to_ids) unless names_to_ids names_to_ids = {} struct_fields.each do |fid, field_def| names_to_ids[field_def[:name]] = fid end self.class.instance_variable_set(:@names_to_ids, names_to_ids) end names_to_ids[name] end def sorted_field_ids sorted_field_ids = self.class.instance_variable_get(:@sorted_field_ids) unless sorted_field_ids sorted_field_ids = struct_fields.keys.sort self.class.instance_variable_set(:@sorted_field_ids, sorted_field_ids) end sorted_field_ids end def each_field sorted_field_ids.each do |fid| data = struct_fields[fid] yield fid, data end end def read_field(iprot, field = {}) case field[:type] when Types::STRUCT value = field[:class].new value.read(iprot) when Types::MAP key_type, val_type, size = iprot.read_map_begin validate_container_size(size) # Skip the map contents if the declared key or value types don't match the expected ones. if (size != 0 && (key_type != field[:key][:type] || val_type != field[:value][:type])) size.times do iprot.skip(key_type) iprot.skip(val_type) end value = nil else value = {} size.times do k = read_field(iprot, field_info(field[:key])) v = read_field(iprot, field_info(field[:value])) value[k] = v end end iprot.read_map_end when Types::LIST e_type, size = iprot.read_list_begin validate_container_size(size) # Skip the list contents if the declared element type doesn't match the expected one. if (e_type != field[:element][:type]) size.times do iprot.skip(e_type) end value = nil else value = [] size.times do value << read_field(iprot, field_info(field[:element])) end end iprot.read_list_end when Types::SET e_type, size = iprot.read_set_begin validate_container_size(size) # Skip the set contents if the declared element type doesn't match the expected one. if (e_type != field[:element][:type]) size.times do iprot.skip(e_type) end else value = Set.new size.times do element = read_field(iprot, field_info(field[:element])) value << element end end iprot.read_set_end else value = iprot.read_type(field) end value end def write_data(oprot, value, field) if is_container? field[:type] write_container(oprot, value, field) else oprot.write_type(field, value) end end def write_container(oprot, value, field = {}) case field[:type] when Types::MAP oprot.write_map_begin(field[:key][:type], field[:value][:type], value.size) value.each do |k, v| write_data(oprot, k, field[:key]) write_data(oprot, v, field[:value]) end oprot.write_map_end when Types::LIST oprot.write_list_begin(field[:element][:type], value.size) value.each do |elem| write_data(oprot, elem, field[:element]) end oprot.write_list_end when Types::SET oprot.write_set_begin(field[:element][:type], value.size) value.each do |v,| # the , is to preserve compatibility with the old Hash-style sets write_data(oprot, v, field[:element]) end oprot.write_set_end else raise "Not a container type: #{field[:type]}" end end CONTAINER_TYPES = [] CONTAINER_TYPES[Types::LIST] = true CONTAINER_TYPES[Types::MAP] = true CONTAINER_TYPES[Types::SET] = true def is_container?(type) CONTAINER_TYPES[type] end def field_info(field) { :type => field[:type], :class => field[:class], :key => field[:key], :value => field[:value], :element => field[:element] } end def inspect_field(value, field_info) if enum_class = field_info[:enum_class] "#{enum_class.const_get(:VALUE_MAP)[value]} (#{value})" elsif value.is_a? Hash if field_info[:type] == Types::MAP map_buf = [] value.each do |k, v| map_buf << inspect_field(k, field_info[:key]) + ": " + inspect_field(v, field_info[:value]) end "{" + map_buf.join(", ") + "}" else # old-style set inspect_collection(value.keys, field_info) end elsif value.is_a? Array inspect_collection(value, field_info) elsif value.is_a? Set inspect_collection(value, field_info) elsif value.is_a?(String) && field_info[:binary] value.unpack("H*").first else value.inspect end end def inspect_collection(collection, field_info) buf = [] collection.each do |k| buf << inspect_field(k, field_info[:element]) end "[" + buf.join(", ") + "]" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/0000775000175000017500000000000015167543515020645 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/lib/thrift/transport/unix_socket.rb0000664000175000017500000000242515167543515023530 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'socket' module Thrift class UNIXSocket < Socket def initialize(path, timeout = nil) @path = path @timeout = timeout @desc = @path # for read()'s error @handle = nil end def open begin @handle = ::UNIXSocket.new(@path) rescue StandardError raise TransportException.new(TransportException::NOT_OPEN, "Could not open UNIX socket at #{@path}") end end def to_s "domain(#{@path})" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/io_stream_transport.rb0000664000175000017500000000304115167543515025266 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # # Very very simple implementation of wrapping two objects, one with a #read # method and one with a #write method, into a transport for thrift. # # Assumes both objects are open, remain open, don't require flushing, etc. # module Thrift class IOStreamTransport < BaseTransport def initialize(input, output) @input = input @output = output end def open?; not @input.closed? or not @output.closed? end def read(sz); @input.read(sz) end def write(buf); @output.write(Bytes.force_binary_encoding(buf)) end def close; @input.close; @output.close end def to_io; @input end # we're assuming this is used in a IO.select for reading def to_s "iostream(input=#{@input.to_s},output=#{@output.to_s})" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/base_transport.rb0000664000175000017500000000542715167543515024230 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # module Thrift class TransportException < Exception UNKNOWN = 0 NOT_OPEN = 1 ALREADY_OPEN = 2 TIMED_OUT = 3 END_OF_FILE = 4 attr_reader :type def initialize(type = UNKNOWN, message = nil) super(message) @type = type end end module TransportUtils # Deprecated: Use Thrift::Bytes instead def self.get_string_byte(string, index) Bytes.get_string_byte(string, index) end # Deprecated: Use Thrift::Bytes instead def self.set_string_byte(string, index, byte) Bytes.set_string_byte(string, index, byte) end end class BaseTransport def open?; end def open; end def close; end # Reads a number of bytes from the transports. The String returned will have a BINARY (aka ASCII-8BIT) encoding. # # sz - The number of bytes to read from the transport. # # Returns a String acting as a byte buffer. def read(sz) raise NotImplementedError end # Returns an unsigned byte as a Integer in the range (0..255). def read_byte buf = read_all(1) return Bytes.get_string_byte(buf, 0) end # Reads size bytes and copies them into buffer[0..size]. def read_into_buffer(buffer, size) tmp = read_all(size) i = 0 tmp.each_byte do |byte| Bytes.set_string_byte(buffer, i, byte) i += 1 end i end def read_all(size) return Bytes.empty_byte_buffer if size <= 0 buf = read(size) while (buf.length < size) chunk = read(size - buf.length) buf << chunk end buf end # Writes the byte buffer to the transport. The buffer will be forced into BINARY encoding. # # buf - A String acting as a byte buffer. # # Returns nothing. def write(buf); end alias_method :<<, :write def flush; end def to_s "base" end end class BaseTransportFactory def get_transport(trans) return trans end def to_s "base" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/server_socket.rb0000664000175000017500000000335215167543515024053 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'socket' module Thrift class ServerSocket < BaseServerTransport # call-seq: initialize(host = nil, port) def initialize(host_or_port, port = nil) if port @host = host_or_port @port = port else @host = nil @port = host_or_port end @handle = nil end attr_reader :handle def listen @handle = TCPServer.new(@host, @port) end def accept unless @handle.nil? sock = @handle.accept sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) trans = Socket.new trans.handle = sock trans end end def close @handle.close unless @handle.nil? or @handle.closed? @handle = nil end def closed? @handle.nil? or @handle.closed? end def to_io @handle&.to_io || raise(IOError, 'closed stream') end def to_s "socket(#{@host}:#{@port})" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/header_transport.rb0000664000175000017500000004142015167543515024537 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'stringio' require 'zlib' module Thrift # Client type constants for Header protocol module HeaderClientType HEADERS = 0x00 FRAMED_BINARY = 0x01 UNFRAMED_BINARY = 0x02 FRAMED_COMPACT = 0x03 UNFRAMED_COMPACT = 0x04 end # Subprotocol ID constants for Header transport module HeaderSubprotocolID BINARY = 0x00 COMPACT = 0x02 end # Transform ID constants for Header transport module HeaderTransformID ZLIB = 0x01 end # Info header type constants module HeaderInfoType KEY_VALUE = 0x01 end # HeaderTransport implements the THeader framing protocol. # # THeader is a transport that adds headers and supports multiple protocols # and transforms. It can auto-detect and communicate with legacy protocols # (framed/unframed binary/compact) for backward compatibility. # # Wire format: # +----------------------------------------------------------------+ # | LENGTH (4 bytes, big-endian, excludes itself) | # +----------------------------------------------------------------+ # | HEADER MAGIC (2 bytes: 0x0FFF) | FLAGS (2 bytes) | # +----------------------------------------------------------------+ # | SEQUENCE NUMBER (4 bytes) | # +----------------------------------------------------------------+ # | HEADER SIZE/4 (2 bytes) | HEADER DATA (variable)... | # +----------------------------------------------------------------+ # | PAYLOAD (variable) | # +----------------------------------------------------------------+ # class HeaderTransport < BaseTransport # Header magic value (first 2 bytes of header) HEADER_MAGIC = 0x0FFF # Maximum frame size (~1GB) MAX_FRAME_SIZE = 0x3FFFFFFF # Binary protocol version mask and version 1 BINARY_VERSION_MASK = 0xffff0000 BINARY_VERSION_1 = 0x80010000 # Compact protocol ID COMPACT_PROTOCOL_ID = 0x82 COMPACT_VERSION_MASK = 0x1f COMPACT_VERSION = 0x01 attr_reader :protocol_id, :sequence_id, :flags # Creates a new HeaderTransport wrapping the given transport. # # @param transport [BaseTransport] The underlying transport to wrap # @param allowed_client_types [Array] Allowed client types for auto-detection. # Defaults to all types for backward compatibility. # @param default_protocol [Integer] Default protocol ID (BINARY or COMPACT) def initialize(transport, allowed_client_types = nil, default_protocol = HeaderSubprotocolID::COMPACT) @transport = transport @client_type = HeaderClientType::HEADERS @protocol_id = default_protocol @allowed_client_types = allowed_client_types || [ HeaderClientType::HEADERS, HeaderClientType::FRAMED_BINARY, HeaderClientType::UNFRAMED_BINARY, HeaderClientType::FRAMED_COMPACT, HeaderClientType::UNFRAMED_COMPACT ] @read_buffer = StringIO.new(Bytes.empty_byte_buffer) @write_buffer = StringIO.new(Bytes.empty_byte_buffer) @read_headers = {} @write_headers = {} @write_transforms = [] @sequence_id = 0 @flags = 0 @max_frame_size = MAX_FRAME_SIZE end def sequence_id=(sequence_id) if sequence_id < -(2**31) || sequence_id > (2**31) - 1 raise RangeError, "sequence_id must be a signed int32" end @sequence_id = sequence_id end def open? @transport.open? end def open @transport.open end def close @transport.close end # Returns the headers read from the last frame def get_headers @read_headers end # Sets a header to be written with the next flush # # @param key [String] Header key (must be binary string) # @param value [String] Header value (must be binary string) def set_header(key, value) key = Bytes.force_binary_encoding(key.to_s) value = Bytes.force_binary_encoding(value.to_s) @write_headers[key] = value end # Clears all write headers def clear_headers @write_headers.clear end # Adds a transform to apply when writing # # @param transform_id [Integer] Transform ID (e.g., HeaderTransformID::ZLIB) def add_transform(transform_id) unless transform_id == HeaderTransformID::ZLIB raise TransportException.new(TransportException::UNKNOWN, "Unknown transform: #{transform_id}") end @write_transforms << transform_id unless @write_transforms.include?(transform_id) end # Sets the maximum allowed frame size def set_max_frame_size(size) if size <= 0 || size > MAX_FRAME_SIZE raise ArgumentError, "max_frame_size must be > 0 and <= #{MAX_FRAME_SIZE}" end @max_frame_size = size end def read(sz) # Try reading from existing buffer data = @read_buffer.read(sz) data = Bytes.empty_byte_buffer if data.nil? bytes_left = sz - data.bytesize return data if bytes_left == 0 # Handle unframed passthrough - read directly from underlying transport if @client_type == HeaderClientType::UNFRAMED_BINARY || @client_type == HeaderClientType::UNFRAMED_COMPACT return data + @transport.read(bytes_left) end # Need to read the next frame read_frame(bytes_left) additional = @read_buffer.read(bytes_left) data + (additional || Bytes.empty_byte_buffer) end def write(buf) @write_buffer.write(Bytes.force_binary_encoding(buf)) end def flush payload = @write_buffer.string @write_buffer = StringIO.new(Bytes.empty_byte_buffer) return if payload.empty? if payload.bytesize > @max_frame_size raise TransportException.new(TransportException::UNKNOWN, "Attempting to send frame that is too large") end case @client_type when HeaderClientType::HEADERS flush_header_format(payload) when HeaderClientType::FRAMED_BINARY, HeaderClientType::FRAMED_COMPACT flush_framed(payload) when HeaderClientType::UNFRAMED_BINARY, HeaderClientType::UNFRAMED_COMPACT @transport.write(payload) @transport.flush else flush_header_format(payload) end end def to_s "header(#{@transport.to_s})" end # Reads the next frame to detect protocol/client type before decoding. def reset_protocol return unless @read_buffer.nil? || @read_buffer.eof? read_frame(0) end private # Sets the client type after validation def set_client_type(client_type) unless @allowed_client_types.include?(client_type) raise TransportException.new(TransportException::UNKNOWN, "Client type #{client_type} not allowed by server") end @client_type = client_type end # Reads the next frame, detecting client type on first read def read_frame(req_sz) # Read first 4 bytes - could be frame length or protocol magic first_word = @transport.read_all(4) frame_size = first_word.unpack('N').first # Check for unframed binary protocol if (frame_size & BINARY_VERSION_MASK) == BINARY_VERSION_1 set_client_type(HeaderClientType::UNFRAMED_BINARY) @protocol_id = HeaderSubprotocolID::BINARY handle_unframed(first_word, req_sz) return end # Check for unframed compact protocol if Bytes.get_string_byte(first_word, 0) == COMPACT_PROTOCOL_ID && (Bytes.get_string_byte(first_word, 1) & COMPACT_VERSION_MASK) == COMPACT_VERSION set_client_type(HeaderClientType::UNFRAMED_COMPACT) @protocol_id = HeaderSubprotocolID::COMPACT handle_unframed(first_word, req_sz) return end # It's a framed protocol - validate frame size if frame_size > @max_frame_size raise TransportException.new(TransportException::UNKNOWN, "Frame size #{frame_size} exceeds maximum #{@max_frame_size}") end # Read the complete frame frame_data = @transport.read_all(frame_size) frame_buf = StringIO.new(frame_data) # Check the second word for protocol type second_word = frame_buf.read(4) frame_buf.rewind magic = second_word.unpack('n').first if magic == HEADER_MAGIC if frame_size < 10 raise TransportException.new(TransportException::UNKNOWN, "Header transport frame is too small") end set_client_type(HeaderClientType::HEADERS) @read_buffer = parse_header_format(frame_buf) elsif (second_word.unpack('N').first & BINARY_VERSION_MASK) == BINARY_VERSION_1 set_client_type(HeaderClientType::FRAMED_BINARY) @protocol_id = HeaderSubprotocolID::BINARY @read_buffer = frame_buf elsif Bytes.get_string_byte(second_word, 0) == COMPACT_PROTOCOL_ID && (Bytes.get_string_byte(second_word, 1) & COMPACT_VERSION_MASK) == COMPACT_VERSION set_client_type(HeaderClientType::FRAMED_COMPACT) @protocol_id = HeaderSubprotocolID::COMPACT @read_buffer = frame_buf else raise TransportException.new(TransportException::UNKNOWN, "Could not detect client transport type") end end # Handles unframed protocol - puts first_word back in buffer def handle_unframed(first_word, req_sz) bytes_left = req_sz - 4 if bytes_left > 0 rest = @transport.read(bytes_left) @read_buffer = StringIO.new(first_word + rest) else @read_buffer = StringIO.new(first_word) end end # Parses a Header format frame def parse_header_format(buf) # Skip magic (already identified) buf.read(2) # Read flags and sequence ID @flags = buf.read(2).unpack('n').first @sequence_id = signed_int32(buf.read(4).unpack('N').first) # Read header length (in 32-bit words) header_words = buf.read(2).unpack('n').first if header_words >= 16_384 raise TransportException.new(TransportException::UNKNOWN, "Header size is unreasonable") end header_length = header_words * 4 end_of_headers = buf.pos + header_length if end_of_headers > buf.string.bytesize raise TransportException.new(TransportException::UNKNOWN, "Header size exceeds frame size") end # Read protocol ID @protocol_id = read_varint32(buf, end_of_headers) # Read transforms transforms = [] transform_count = read_varint32(buf, end_of_headers) transform_count.times do transform_id = read_varint32(buf, end_of_headers) unless transform_id == HeaderTransformID::ZLIB raise TransportException.new(TransportException::UNKNOWN, "Unknown transform: #{transform_id}") end transforms << transform_id end # Read info headers @read_headers = {} while buf.pos < end_of_headers info_type = read_varint32(buf, end_of_headers) if info_type == 0 # header padding break elsif info_type == HeaderInfoType::KEY_VALUE count = read_varint32(buf, end_of_headers) count.times do key = read_varstring(buf, end_of_headers) value = read_varstring(buf, end_of_headers) @read_headers[key] = value end else # Unknown info type, skip to end of headers break end end # Skip any remaining header padding buf.pos = end_of_headers # Read payload and apply transforms payload = buf.read transforms.each do |transform_id| if transform_id == HeaderTransformID::ZLIB payload = Zlib::Inflate.inflate(payload) end end StringIO.new(payload) end # Flushes data in Header format def flush_header_format(payload) # Apply transforms @write_transforms.each do |transform_id| if transform_id == HeaderTransformID::ZLIB payload = Zlib::Deflate.deflate(payload) end end # Build header data header_buf = StringIO.new(Bytes.empty_byte_buffer) # Protocol ID write_varint32(header_buf, @protocol_id) # Transforms write_varint32(header_buf, @write_transforms.size) @write_transforms.each { |t| write_varint32(header_buf, t) } # Info headers (key-value pairs) unless @write_headers.empty? write_varint32(header_buf, HeaderInfoType::KEY_VALUE) write_varint32(header_buf, @write_headers.size) @write_headers.each do |key, value| write_varstring(header_buf, key) write_varstring(header_buf, value) end @write_headers = {} end # Pad header to 4-byte boundary header_data = header_buf.string padding = (4 - (header_data.bytesize % 4)) % 4 header_data += "\x00" * padding # Calculate total frame size (excludes the 4-byte length field itself) # Frame = magic(2) + flags(2) + seqid(4) + header_len(2) + header_data + payload frame_size = 2 + 2 + 4 + 2 + header_data.bytesize + payload.bytesize # Write complete frame frame = Bytes.empty_byte_buffer frame << [frame_size].pack('N') # Length frame << [HEADER_MAGIC].pack('n') # Magic frame << [@flags].pack('n') # Flags frame << [unsigned_int32(@sequence_id)].pack('N') # Sequence ID frame << [header_data.bytesize / 4].pack('n') # Header length (in 32-bit words) frame << header_data # Header data frame << payload # Payload @transport.write(frame) @transport.flush end # Flushes data in simple framed format (for legacy compatibility) def flush_framed(payload) frame = [payload.bytesize].pack('N') + payload @transport.write(frame) @transport.flush end # Reads a varint32 from the given IO def read_varint32(io, boundary_pos = nil) shift = 0 result = 0 loop do if boundary_pos && io.pos >= boundary_pos raise TransportException.new(TransportException::UNKNOWN, "Trying to read past header boundary") end byte = io.getbyte raise TransportException.new(TransportException::END_OF_FILE, "Unexpected EOF reading varint") if byte.nil? result |= (byte & 0x7f) << shift break if (byte & 0x80) == 0 shift += 7 end result end # Writes a varint32 to the given IO def write_varint32(io, n) loop do if (n & ~0x7F) == 0 io.write([n].pack('C')) break else io.write([(n & 0x7F) | 0x80].pack('C')) n >>= 7 end end end # Reads a varint-prefixed string from the given IO def read_varstring(io, boundary_pos = nil) size = read_varint32(io, boundary_pos) if size < 0 raise TransportException.new(TransportException::UNKNOWN, "Negative string size: #{size}") end if boundary_pos && size > (boundary_pos - io.pos) raise TransportException.new(TransportException::UNKNOWN, "Info header length exceeds header size") end data = io.read(size) if data.nil? || data.bytesize < size raise TransportException.new(TransportException::END_OF_FILE, "Unexpected EOF reading string") end data end # Writes a varint-prefixed string to the given IO def write_varstring(io, value) value = Bytes.force_binary_encoding(value) write_varint32(io, value.bytesize) io.write(value) end def signed_int32(value) value > 0x7fffffff ? value - (2**32) : value end def unsigned_int32(value) value < 0 ? value + (2**32) : value end end # Factory for creating HeaderTransport instances class HeaderTransportFactory < BaseTransportFactory def initialize(allowed_client_types = nil, default_protocol = HeaderSubprotocolID::BINARY) @allowed_client_types = allowed_client_types @default_protocol = default_protocol end def get_transport(transport) HeaderTransport.new(transport, @allowed_client_types, @default_protocol) end def to_s "header" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/http_client_transport.rb0000664000175000017500000000401115167543515025617 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'net/http' require 'net/https' require 'openssl' require 'uri' require 'stringio' module Thrift class HTTPClientTransport < BaseTransport def initialize(url, opts = {}) @url = URI url @headers = {'Content-Type' => 'application/x-thrift'} @outbuf = Bytes.empty_byte_buffer @ssl_verify_mode = opts.fetch(:ssl_verify_mode, OpenSSL::SSL::VERIFY_PEER) end def open?; true end def read(sz); @inbuf.read sz end def write(buf); @outbuf << Bytes.force_binary_encoding(buf) end def add_headers(headers) @headers = @headers.merge(headers) end def flush http = Net::HTTP.new @url.host, @url.port http.use_ssl = @url.scheme == 'https' http.verify_mode = @ssl_verify_mode if @url.scheme == 'https' resp = http.post(@url.request_uri, @outbuf, @headers) raise TransportException.new(TransportException::UNKNOWN, "#{self.class.name} Could not connect to #{@url}, HTTP status code #{resp.code.to_i}") unless (200..299).include?(resp.code.to_i) data = resp.body data = Bytes.force_binary_encoding(data) @inbuf = StringIO.new data ensure @outbuf = Bytes.empty_byte_buffer end def to_s "@{self.url}" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/socket.rb0000664000175000017500000001212115167543515022457 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'socket' module Thrift class Socket < BaseTransport def initialize(host = 'localhost', port = 9090, timeout = nil) @host = host @port = port @timeout = timeout @desc = "#{host}:#{port}" @handle = nil end attr_accessor :handle, :timeout def open for addrinfo in ::Socket::getaddrinfo(@host, @port, nil, ::Socket::SOCK_STREAM) do begin socket = ::Socket.new(addrinfo[4], ::Socket::SOCK_STREAM, 0) socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) sockaddr = ::Socket.sockaddr_in(addrinfo[1], addrinfo[3]) begin socket.connect_nonblock(sockaddr) rescue Errno::EINPROGRESS unless IO.select(nil, [ socket ], nil, @timeout) next end begin socket.connect_nonblock(sockaddr) rescue Errno::EISCONN end end return @handle = socket rescue StandardError => e next end end raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}: #{e}") end def open? !@handle.nil? and !@handle.closed? end def write(str) raise TransportException.new(TransportException::NOT_OPEN, "closed stream") unless open? str = Bytes.force_binary_encoding(str) begin if @timeout.nil? or @timeout == 0 @handle.write(str) else deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + @timeout len = 0 while len < str.length begin len += @handle.write_nonblock(str[len..-1]) rescue IO::WaitWritable wait_for(:write, deadline, str.length) rescue IO::WaitReadable wait_for(:read, deadline, str.length) end end len end rescue TransportException => e # pass this on raise e rescue StandardError => e @handle.close @handle = nil raise TransportException.new(TransportException::NOT_OPEN, e.message) end end def read(sz) raise TransportException.new(TransportException::NOT_OPEN, "closed stream") unless open? begin if @timeout.nil? or @timeout == 0 data = @handle.readpartial(sz) else deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + @timeout data = loop do begin break @handle.read_nonblock(sz) rescue IO::WaitReadable wait_for(:read, deadline, sz) rescue IO::WaitWritable wait_for(:write, deadline, sz) end end end rescue TransportException => e # don't let this get caught by the StandardError handler raise e rescue StandardError => e @handle.close unless @handle.closed? @handle = nil raise TransportException.new(TransportException::NOT_OPEN, e.message) end if (data.nil? or data.length == 0) raise TransportException.new(TransportException::UNKNOWN, "Socket: Could not read #{sz} bytes from #{@desc}") end data end def close @handle.close unless @handle.nil? or @handle.closed? @handle = nil end def to_io @handle&.to_io || raise(IOError, 'closed stream') end def to_s "socket(#{@host}:#{@port})" end private def wait_for(operation, deadline, sz) rd_ary, wr_ary = case operation when :read [[@handle], nil] when :write [nil, [@handle]] else raise ArgumentError, "Unknown IO wait operation: #{operation.inspect}" end loop do remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC) if remaining <= 0 case operation when :read raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out reading #{sz} bytes from #{@desc}") when :write raise TransportException.new(TransportException::TIMED_OUT, "Socket: Timed out writing #{sz} bytes to #{@desc}") end end rd, wr, = IO.select(rd_ary, wr_ary, nil, remaining) return if (rd && !rd.empty?) || (wr && !wr.empty?) end end end end thrift-0.23.0/lib/rb/lib/thrift/transport/buffered_transport.rb0000664000175000017500000000633315167543515025075 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # module Thrift class BufferedTransport < BaseTransport DEFAULT_BUFFER = 4096 def initialize(transport) @transport = transport @wbuf = Bytes.empty_byte_buffer @rbuf = Bytes.empty_byte_buffer @index = 0 end def open? return @transport.open? end def open @transport.open end def close flush @transport.close end def read(sz) @index += sz ret = @rbuf.slice(@index - sz, sz) || Bytes.empty_byte_buffer if ret.length == 0 @rbuf = @transport.read([sz, DEFAULT_BUFFER].max) @index = sz ret = @rbuf.slice(0, sz) || Bytes.empty_byte_buffer end ret end def read_byte # If the read buffer is exhausted, try to read up to DEFAULT_BUFFER more bytes into it. if @index >= @rbuf.size @rbuf = @transport.read(DEFAULT_BUFFER) @index = 0 end # The read buffer has some data now, read a single byte. Using get_string_byte() avoids # allocating a temp string of size 1 unnecessarily. @index += 1 return Bytes.get_string_byte(@rbuf, @index - 1) end # Reads a number of bytes from the transport into the buffer passed. # # buffer - The String (byte buffer) to write data to; this is assumed to have a BINARY encoding. # size - The number of bytes to read from the transport and write to the buffer. # # Returns the number of bytes read. def read_into_buffer(buffer, size) i = 0 while i < size # If the read buffer is exhausted, try to read up to DEFAULT_BUFFER more bytes into it. if @index >= @rbuf.size @rbuf = @transport.read(DEFAULT_BUFFER) @index = 0 end # The read buffer has some data now, so copy bytes over to the output buffer. byte = Bytes.get_string_byte(@rbuf, @index) Bytes.set_string_byte(buffer, i, byte) @index += 1 i += 1 end i end def write(buf) @wbuf << Bytes.force_binary_encoding(buf) end def flush unless @wbuf.empty? @transport.write(@wbuf) @wbuf = Bytes.empty_byte_buffer end @transport.flush end def to_s "buffered(#{@transport.to_s})" end end class BufferedTransportFactory < BaseTransportFactory def get_transport(transport) return BufferedTransport.new(transport) end def to_s "buffered" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/ssl_socket.rb0000664000175000017500000000316415167543515023347 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. module Thrift class SSLSocket < Socket def initialize(host = 'localhost', port = 9090, timeout = nil, ssl_context = nil) super(host, port, timeout) @ssl_context = ssl_context end attr_accessor :ssl_context def open socket = super @handle = OpenSSL::SSL::SSLSocket.new(socket, @ssl_context) begin @handle.connect_nonblock @handle.post_connection_check(@host) @handle rescue IO::WaitReadable IO.select([ @handle ], nil, nil, @timeout) retry rescue IO::WaitWritable IO.select(nil, [ @handle ], nil, @timeout) retry rescue StandardError => e raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}: #{e}") end end def to_s "ssl(#{super.to_s})" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/unix_server_socket.rb0000664000175000017500000000306615167543515025120 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'socket' module Thrift class UNIXServerSocket < BaseServerTransport def initialize(path) @path = path @handle = nil end attr_accessor :handle def listen @handle = ::UNIXServer.new(@path) end def accept unless @handle.nil? sock = @handle.accept trans = UNIXSocket.new(nil) trans.handle = sock trans end end def close if @handle @handle.close unless @handle.closed? @handle = nil # UNIXServer doesn't delete the socket file, so we have to do it ourselves File.delete(@path) end end def closed? @handle.nil? or @handle.closed? end alias to_io handle def to_s "domain(#{@path})" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/framed_transport.rb0000664000175000017500000000622515167543515024551 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # module Thrift class FramedTransport < BaseTransport def initialize(transport, read = true, write = true) @transport = transport @rbuf = Bytes.empty_byte_buffer @wbuf = Bytes.empty_byte_buffer @read = read @write = write @index = 0 end def open? @transport.open? end def open @transport.open end def close @transport.close end def read(sz) return @transport.read(sz) unless @read return Bytes.empty_byte_buffer if sz <= 0 read_frame if @index >= @rbuf.length @index += sz @rbuf.slice(@index - sz, sz) || Bytes.empty_byte_buffer end def read_byte return @transport.read_byte() unless @read read_frame if @index >= @rbuf.length # The read buffer has some data now, read a single byte. Using get_string_byte() avoids # allocating a temp string of size 1 unnecessarily. @index += 1 return Bytes.get_string_byte(@rbuf, @index - 1) end def read_into_buffer(buffer, size) i = 0 while i < size read_frame if @index >= @rbuf.length # The read buffer has some data now, so copy bytes over to the output buffer. byte = Bytes.get_string_byte(@rbuf, @index) Bytes.set_string_byte(buffer, i, byte) @index += 1 i += 1 end i end def write(buf, sz = nil) return @transport.write(buf) unless @write buf = Bytes.force_binary_encoding(buf) @wbuf << (sz ? buf[0...sz] : buf) end # # Writes the output buffer to the stream in the format of a 4-byte length # followed by the actual data. # def flush return @transport.flush unless @write out = [@wbuf.length].pack('N') # Array#pack should return a BINARY encoded String, so it shouldn't be necessary to force encoding out << @wbuf @transport.write(out) @transport.flush @wbuf = Bytes.empty_byte_buffer end def to_s "framed(#{@transport.to_s})" end private def read_frame sz = @transport.read_all(4).unpack('N').first @index = 0 @rbuf = @transport.read_all(sz) end end class FramedTransportFactory < BaseTransportFactory def get_transport(transport) return FramedTransport.new(transport) end def to_s "framed" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/ssl_server_socket.rb0000664000175000017500000000233115167543515024730 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # require 'socket' module Thrift class SSLServerSocket < ServerSocket def initialize(host_or_port, port = nil, ssl_context = nil) super(host_or_port, port) @ssl_context = ssl_context end attr_accessor :ssl_context def listen socket = TCPServer.new(@host, @port) @handle = OpenSSL::SSL::SSLServer.new(socket, @ssl_context) end def to_s "ssl(#{super.to_s})" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/memory_buffer_transport.rb0000664000175000017500000000624715167543515026160 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # module Thrift class MemoryBufferTransport < BaseTransport GARBAGE_BUFFER_SIZE = 4*(2**10) # 4kB # If you pass a string to this, you should #dup that string # unless you want it to be modified by #read and #write #-- # this behavior is no longer required. If you wish to change it # go ahead, just make sure the specs pass def initialize(buffer = nil) @buf = buffer ? Bytes.force_binary_encoding(buffer) : Bytes.empty_byte_buffer @index = 0 end def open? return true end def open end def close end def peek @index < @buf.size end # this method does not use the passed object directly but copies it def reset_buffer(new_buf = '') @buf.replace Bytes.force_binary_encoding(new_buf) @index = 0 end def available @buf.length - @index end def read(len) data = @buf.slice(@index, len) @index += len @index = @buf.size if @index > @buf.size if @index >= GARBAGE_BUFFER_SIZE @buf = @buf.slice(@index..-1) @index = 0 end if data.size < len raise EOFError, "Not enough bytes remain in buffer" end data end def read_byte raise EOFError.new("Not enough bytes remain in buffer") if @index >= @buf.size val = Bytes.get_string_byte(@buf, @index) @index += 1 if @index >= GARBAGE_BUFFER_SIZE @buf = @buf.slice(@index..-1) @index = 0 end val end def read_into_buffer(buffer, size) i = 0 while i < size raise EOFError.new("Not enough bytes remain in buffer") if @index >= @buf.size # The read buffer has some data now, so copy bytes over to the output buffer. byte = Bytes.get_string_byte(@buf, @index) Bytes.set_string_byte(buffer, i, byte) @index += 1 i += 1 end if @index >= GARBAGE_BUFFER_SIZE @buf = @buf.slice(@index..-1) @index = 0 end i end def write(wbuf) @buf << Bytes.force_binary_encoding(wbuf) end def flush end def inspect_buffer out = [] for idx in 0...(@buf.size) # if idx != 0 # out << " " # end if idx == @index out << ">" end out << @buf[idx].ord.to_s(16) end out.join(" ") end def to_s "memory" end end end thrift-0.23.0/lib/rb/lib/thrift/transport/base_server_transport.rb0000664000175000017500000000203615167543515025607 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # module Thrift class BaseServerTransport def listen raise NotImplementedError end def accept raise NotImplementedError end def close; nil; end def closed? raise NotImplementedError end end end thrift-0.23.0/lib/rb/lib/thrift/client.rb0000664000175000017500000000672515167543515020426 0ustar00buildbuild00000000000000# # 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. # module Thrift module Client MIN_SEQUENCE_ID = -(2**31) MAX_SEQUENCE_ID = (2**31) - 1 def initialize(iprot, oprot = nil) @iprot = iprot @oprot = oprot || iprot @seqid = 0 @pending_seqids = [] end def send_message(name, args_class, args = {}) seqid = next_seqid! @oprot.write_message_begin(name, MessageTypes::CALL, seqid) send_message_args(args_class, args) @pending_seqids << seqid end def send_oneway_message(name, args_class, args = {}) @oprot.write_message_begin(name, MessageTypes::ONEWAY, next_seqid!) send_message_args(args_class, args) end def send_message_args(args_class, args) data = args_class.new args.each do |k, v| data.send("#{k.to_s}=", v) end begin data.write(@oprot) rescue StandardError => e @oprot.trans.close raise e end @oprot.write_message_end @oprot.trans.flush end def receive_message_begin() fname, mtype, rseqid = @iprot.read_message_begin [fname, mtype, rseqid] end def reply_seqid(rseqid) expected_seqid = dequeue_pending_seqid !expected_seqid.nil? && rseqid == expected_seqid end def validate_message_begin(fname, mtype, rseqid, expected_name) expected_seqid = dequeue_pending_seqid if mtype == MessageTypes::EXCEPTION raise_application_exception end if mtype != MessageTypes::REPLY raise ApplicationException.new( ApplicationException::INVALID_MESSAGE_TYPE, "#{expected_name} failed: invalid message type" ) end if fname != expected_name raise ApplicationException.new( ApplicationException::WRONG_METHOD_NAME, "#{expected_name} failed: wrong method name" ) end return if !expected_seqid.nil? && rseqid == expected_seqid raise ApplicationException.new( ApplicationException::BAD_SEQUENCE_ID, "#{expected_name} failed: out of sequence response" ) end def receive_message(result_klass) result = result_klass.new result.read(@iprot) @iprot.read_message_end result end def handle_exception(mtype) if mtype == MessageTypes::EXCEPTION dequeue_pending_seqid raise_application_exception end end private def next_seqid! seqid = @seqid @seqid = (seqid == MAX_SEQUENCE_ID) ? MIN_SEQUENCE_ID : seqid + 1 seqid end def dequeue_pending_seqid @pending_seqids.shift end def raise_application_exception x = ApplicationException.new x.read(@iprot) @iprot.read_message_end raise x end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/0000775000175000017500000000000015167543515020452 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/lib/thrift/protocol/binary_protocol_accelerated.rb0000664000175000017500000000310315167543515026515 0ustar00buildbuild00000000000000# # 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. # =begin The only change required for a transport to support BinaryProtocolAccelerated is to implement 2 methods: * borrow(size), which takes an optional argument and returns atleast _size_ bytes from the transport, or the default buffer size if no argument is given * consume!(size), which removes size bytes from the front of the buffer See MemoryBuffer and BufferedTransport for examples. =end module Thrift class BinaryProtocolAcceleratedFactory < BaseProtocolFactory def get_protocol(trans) if (defined? BinaryProtocolAccelerated) BinaryProtocolAccelerated.new(trans) else BinaryProtocol.new(trans) end end def to_s if (defined? BinaryProtocolAccelerated) "binary-accel" else "binary" end end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/base_protocol.rb0000664000175000017500000002336115167543515023637 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # this require is to make generated struct definitions happy require 'set' module Thrift class ProtocolException < Exception UNKNOWN = 0 INVALID_DATA = 1 NEGATIVE_SIZE = 2 SIZE_LIMIT = 3 BAD_VERSION = 4 NOT_IMPLEMENTED = 5 DEPTH_LIMIT = 6 attr_reader :type def initialize(type = UNKNOWN, message = nil) super(message) @type = type end end class BaseProtocol attr_reader :trans def initialize(trans) @trans = trans end def native? puts "wrong method is being called!" false end def write_message_begin(name, type, seqid) raise NotImplementedError end def write_message_end; nil; end def write_struct_begin(name) raise NotImplementedError end def write_struct_end; nil; end def write_field_begin(name, type, id) raise NotImplementedError end def write_field_end; nil; end def write_field_stop raise NotImplementedError end def write_map_begin(ktype, vtype, size) raise NotImplementedError end def write_map_end; nil; end def write_list_begin(etype, size) raise NotImplementedError end def write_list_end; nil; end def write_set_begin(etype, size) raise NotImplementedError end def write_set_end; nil; end def write_bool(bool) raise NotImplementedError end def write_byte(byte) raise NotImplementedError end def write_i16(i16) raise NotImplementedError end def write_i32(i32) raise NotImplementedError end def write_i64(i64) raise NotImplementedError end def write_double(dub) raise NotImplementedError end # Writes a Thrift String. The String passed will be transcoded to UTF-8. # # str - The String to write. # # Raises EncodingError if the transcoding to UTF-8 fails. # # Returns nothing. def write_string(str) raise NotImplementedError end # Writes a Thrift Binary (Thrift String with no encoding). The String passed # will forced into BINARY encoding. # # buf - The String to write. # # Returns nothing. def write_binary(buf) raise NotImplementedError end # Writes a UUID as 16 bytes. # # uuid - The UUID string to write (e.g. "550e8400-e29b-41d4-a716-446655440000"). # # Returns nothing. def write_uuid(uuid) raise NotImplementedError end def read_message_begin raise NotImplementedError end def read_message_end; nil; end def read_struct_begin raise NotImplementedError end def read_struct_end; nil; end def read_field_begin raise NotImplementedError end def read_field_end; nil; end def read_map_begin raise NotImplementedError end def read_map_end; nil; end def read_list_begin raise NotImplementedError end def read_list_end; nil; end def read_set_begin raise NotImplementedError end def read_set_end; nil; end def read_bool raise NotImplementedError end def read_byte raise NotImplementedError end def read_i16 raise NotImplementedError end def read_i32 raise NotImplementedError end def read_i64 raise NotImplementedError end def read_double raise NotImplementedError end # Reads a Thrift String. All Strings will be returned with an Encoding of UTF-8. # # Returns a String. def read_string raise NotImplementedError end # Reads a Thrift Binary (Thrift String without encoding). All Strings will be returned # with an Encoding of BINARY. # # Returns a String. def read_binary raise NotImplementedError end # Reads a UUID as 16 bytes and returns it as a string. # # Returns a String (e.g. "550e8400-e29b-41d4-a716-446655440000"). def read_uuid raise NotImplementedError end # Writes a field based on the field information, field ID and value. # # field_info - A Hash containing the definition of the field: # :name - The name of the field. # :type - The type of the field, which must be a Thrift::Types constant. # :binary - A Boolean flag that indicates if Thrift::Types::STRING is a binary string (string without encoding). # fid - The ID of the field. # value - The field's value to write; object type varies based on :type. # # Returns nothing. def write_field(*args) if args.size == 3 # handles the documented method signature - write_field(field_info, fid, value) field_info = args[0] fid = args[1] value = args[2] elsif args.size == 4 # handles the deprecated method signature - write_field(name, type, fid, value) field_info = {:name => args[0], :type => args[1]} fid = args[2] value = args[3] else raise ArgumentError, "wrong number of arguments (#{args.size} for 3)" end write_field_begin(field_info[:name], field_info[:type], fid) write_type(field_info, value) write_field_end end # Writes a field value based on the field information. # # field_info - A Hash containing the definition of the field: # :type - The Thrift::Types constant that determines how the value is written. # :binary - A Boolean flag that indicates if Thrift::Types::STRING is a binary string (string without encoding). # value - The field's value to write; object type varies based on field_info[:type]. # # Returns nothing. def write_type(field_info, value) # if field_info is a Integer, assume it is a Thrift::Types constant # convert it into a field_info Hash for backwards compatibility if field_info.is_a? Integer field_info = {:type => field_info} end case field_info[:type] when Types::BOOL write_bool(value) when Types::BYTE write_byte(value) when Types::DOUBLE write_double(value) when Types::I16 write_i16(value) when Types::I32 write_i32(value) when Types::I64 write_i64(value) when Types::STRING if field_info[:binary] write_binary(value) else write_string(value) end when Types::UUID write_uuid(value) when Types::STRUCT value.write(self) else raise NotImplementedError end end # Reads a field value based on the field information. # # field_info - A Hash containing the pertinent data to write: # :type - The Thrift::Types constant that determines how the value is written. # :binary - A flag that indicates if Thrift::Types::STRING is a binary string (string without encoding). # # Returns the value read; object type varies based on field_info[:type]. def read_type(field_info) # if field_info is a Integer, assume it is a Thrift::Types constant # convert it into a field_info Hash for backwards compatibility if field_info.is_a? Integer field_info = {:type => field_info} end case field_info[:type] when Types::BOOL read_bool when Types::BYTE read_byte when Types::DOUBLE read_double when Types::I16 read_i16 when Types::I32 read_i32 when Types::I64 read_i64 when Types::STRING if field_info[:binary] read_binary else read_string end when Types::UUID read_uuid else raise NotImplementedError end end def skip(type) case type when Types::BOOL read_bool when Types::BYTE read_byte when Types::I16 read_i16 when Types::I32 read_i32 when Types::I64 read_i64 when Types::DOUBLE read_double when Types::STRING read_string when Types::UUID read_uuid when Types::STRUCT read_struct_begin while true name, type, id = read_field_begin break if type == Types::STOP skip(type) read_field_end end read_struct_end when Types::MAP ktype, vtype, size = read_map_begin size.times do skip(ktype) skip(vtype) end read_map_end when Types::SET etype, size = read_set_begin size.times do skip(etype) end read_set_end when Types::LIST etype, size = read_list_begin size.times do skip(etype) end read_list_end else raise ProtocolException.new(ProtocolException::INVALID_DATA, 'Invalid data') end end def to_s "#{trans.to_s}" end end class BaseProtocolFactory def get_protocol(trans) raise NotImplementedError end def to_s "base" end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/protocol_decorator.rb0000664000175000017500000000734715167543515024715 0ustar00buildbuild00000000000000# # 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. module Thrift module ProtocolDecorator def initialize(protocol) @protocol = protocol end def trans @protocol.trans end def write_message_begin(name, type, seqid) @protocol.write_message_begin end def write_message_end @protocol.write_message_end end def write_struct_begin(name) @protocol.write_struct_begin(name) end def write_struct_end @protocol.write_struct_end end def write_field_begin(name, type, id) @protocol.write_field_begin(name, type, id) end def write_field_end @protocol.write_field_end end def write_field_stop @protocol.write_field_stop end def write_map_begin(ktype, vtype, size) @protocol.write_map_begin(ktype, vtype, size) end def write_map_end @protocol.write_map_end end def write_list_begin(etype, size) @protocol.write_list_begin(etype, size) end def write_list_end @protocol.write_list_end end def write_set_begin(etype, size) @protocol.write_set_begin(etype, size) end def write_set_end @protocol.write_set_end end def write_bool(bool) @protocol.write_bool(bool) end def write_byte(byte) @protocol.write_byte(byte) end def write_i16(i16) @protocol.write_i16(i16) end def write_i32(i32) @protocol.write_i32(i32) end def write_i64(i64) @protocol.write_i64(i64) end def write_double(dub) @protocol.write_double(dub) end def write_string(str) @protocol.write_string(str) end def write_binary(buf) @protocol.write_binary(buf) end def write_uuid(uuid) @protocol.write_uuid(uuid) end def read_message_begin @protocol.read_message_begin end def read_message_end @protocol.read_message_end end def read_struct_begin @protocol.read_struct_begin end def read_struct_end @protocol.read_struct_end end def read_field_begin @protocol.read_field_begin end def read_field_end @protocol.read_field_end end def read_map_begin @protocol.read_map_begin end def read_map_end @protocol.read_map_end end def read_list_begin @protocol.read_list_begin end def read_list_end @protocol.read_list_end end def read_set_begin @protocol.read_set_begin end def read_set_end @protocol.read_set_end end def read_bool @protocol.read_bool end def read_byte @protocol.read_byte end def read_i16 @protocol.read_i16 end def read_i32 @protocol.read_i32 end def read_i64 @protocol.read_i64 end def read_double @protocol.read_double end def read_string @protocol.read_string end def read_binary @protocol.read_binary end def read_uuid @protocol.read_uuid end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/json_protocol.rb0000664000175000017500000004566315167543515023707 0ustar00buildbuild00000000000000# encoding: UTF-8 # # 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. # module Thrift class LookaheadReader def initialize(trans) @trans = trans @hasData = false @data = nil end def read if @hasData @hasData = false else @data = @trans.read(1) end return @data end def peek if !@hasData @data = @trans.read(1) end @hasData = true return @data end end # # Class to serve as base JSON context and as base class for other context # implementations # class JSONContext @@kJSONElemSeparator = ',' # # Write context data to the trans. Default is to do nothing. # def write(trans) end # # Read context data from the trans. Default is to do nothing. # def read(reader) end # # Return true if numbers need to be escaped as strings in this context. # Default behavior is to return false. # def escapeNum return false end end # Context class for object member key-value pairs class JSONPairContext < JSONContext @@kJSONPairSeparator = ':' def initialize @first = true @colon = true end def write(trans) if (@first) @first = false @colon = true else trans.write(@colon ? @@kJSONPairSeparator : @@kJSONElemSeparator) @colon = !@colon end end def read(reader) if (@first) @first = false @colon = true else ch = (@colon ? @@kJSONPairSeparator : @@kJSONElemSeparator) @colon = !@colon JsonProtocol::read_syntax_char(reader, ch) end end # Numbers must be turned into strings if they are the key part of a pair def escapeNum return @colon end end # Context class for lists class JSONListContext < JSONContext def initialize @first = true end def write(trans) if (@first) @first = false else trans.write(@@kJSONElemSeparator) end end def read(reader) if (@first) @first = false else JsonProtocol::read_syntax_char(reader, @@kJSONElemSeparator) end end end class JsonProtocol < BaseProtocol @@kJSONObjectStart = '{' @@kJSONObjectEnd = '}' @@kJSONArrayStart = '[' @@kJSONArrayEnd = ']' @@kJSONNewline = '\n' @@kJSONBackslash = '\\' @@kJSONStringDelimiter = '"' @@kThriftVersion1 = 1 @@kThriftNan = "NaN" @@kThriftInfinity = "Infinity" @@kThriftNegativeInfinity = "-Infinity" def initialize(trans) super(trans) @context = JSONContext.new @contexts = Array.new @reader = LookaheadReader.new(trans) end def get_type_name_for_type_id(id) case id when Types::BOOL "tf" when Types::BYTE "i8" when Types::I16 "i16" when Types::I32 "i32" when Types::I64 "i64" when Types::DOUBLE "dbl" when Types::STRING "str" when Types::STRUCT "rec" when Types::MAP "map" when Types::SET "set" when Types::LIST "lst" when Types::UUID "uid" else raise NotImplementedError end end def get_type_id_for_type_name(name) if (name == "tf") result = Types::BOOL elsif (name == "i8") result = Types::BYTE elsif (name == "i16") result = Types::I16 elsif (name == "i32") result = Types::I32 elsif (name == "i64") result = Types::I64 elsif (name == "dbl") result = Types::DOUBLE elsif (name == "str") result = Types::STRING elsif (name == "rec") result = Types::STRUCT elsif (name == "map") result = Types::MAP elsif (name == "set") result = Types::SET elsif (name == "lst") result = Types::LIST elsif (name == "uid") result = Types::UUID else result = Types::STOP end if (result == Types::STOP) raise NotImplementedError end return result end # Static helper functions # Read 1 character from the trans and verify that it is the expected character ch. # Throw a protocol exception if it is not. def self.read_syntax_char(reader, ch) ch2 = reader.read if (ch2 != ch) raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected \'#{ch}\' got \'#{ch2}\'.") end end # Return true if the character ch is in [-+0-9.Ee]; false otherwise def is_json_numeric(ch) case ch when '+', '-', '.', '0' .. '9', 'E', "e" return true else return false end end def push_context(context) @contexts.push(@context) @context = context end def pop_context @context = @contexts.pop end # Write the character ch as a JSON escape sequence ("\u00xx") def write_json_escape_char(ch) trans.write('\\u') ch_value = ch[0] if (ch_value.kind_of? String) ch_value = ch.bytes.first end trans.write(ch_value.to_s(16).rjust(4, '0')) end # Write the character ch as part of a JSON string, escaping as appropriate. def write_json_char(ch) # This table describes the handling for the first 0x30 characters # 0 : escape using "\u00xx" notation # 1 : just output index # : escape using "\" notation kJSONCharTable = [ # 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, # 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 1 1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 2 ] ch_value = ch[0] if (ch_value.kind_of? String) ch_value = ch.bytes.first end if (ch_value >= 0x30) if (ch == @@kJSONBackslash) # Only special character >= 0x30 is '\' trans.write(@@kJSONBackslash) trans.write(@@kJSONBackslash) else trans.write(ch) end else outCh = kJSONCharTable[ch_value]; # Check if regular character, backslash escaped, or JSON escaped if outCh.kind_of? String trans.write(@@kJSONBackslash) trans.write(outCh) elsif outCh == 1 trans.write(ch) else write_json_escape_char(ch) end end end # Write out the contents of the string str as a JSON string, escaping characters as appropriate. def write_json_string(str) @context.write(trans) trans.write(@@kJSONStringDelimiter) str.split('').each do |ch| write_json_char(ch) end trans.write(@@kJSONStringDelimiter) end # Write out the contents of the string as JSON string, base64-encoding # the string's contents, and escaping as appropriate def write_json_base64(str) @context.write(trans) trans.write(@@kJSONStringDelimiter) trans.write([str].pack('m0')) trans.write(@@kJSONStringDelimiter) end # Convert the given integer type to a JSON number, or a string # if the context requires it (eg: key in a map pair). def write_json_integer(num) @context.write(trans) escapeNum = @context.escapeNum if (escapeNum) trans.write(@@kJSONStringDelimiter) end trans.write(num.to_s); if (escapeNum) trans.write(@@kJSONStringDelimiter) end end # Convert the given double to a JSON string, which is either the number, # "NaN" or "Infinity" or "-Infinity". def write_json_double(num) @context.write(trans) # Normalize output of thrift::to_string for NaNs and Infinities special = false; if (num.nan?) special = true; val = @@kThriftNan; elsif (num.infinite?) special = true; val = @@kThriftInfinity; if (num < 0.0) val = @@kThriftNegativeInfinity; end else val = num.to_s end escapeNum = special || @context.escapeNum if (escapeNum) trans.write(@@kJSONStringDelimiter) end trans.write(val) if (escapeNum) trans.write(@@kJSONStringDelimiter) end end def write_json_object_start @context.write(trans) trans.write(@@kJSONObjectStart) push_context(JSONPairContext.new); end def write_json_object_end pop_context trans.write(@@kJSONObjectEnd) end def write_json_array_start @context.write(trans) trans.write(@@kJSONArrayStart) push_context(JSONListContext.new); end def write_json_array_end pop_context trans.write(@@kJSONArrayEnd) end def write_message_begin(name, type, seqid) write_json_array_start write_json_integer(@@kThriftVersion1) write_json_string(name) write_json_integer(type) write_json_integer(seqid) end def write_message_end write_json_array_end end def write_struct_begin(name) write_json_object_start end def write_struct_end write_json_object_end end def write_field_begin(name, type, id) write_json_integer(id) write_json_object_start write_json_string(get_type_name_for_type_id(type)) end def write_field_end write_json_object_end end def write_field_stop; nil; end def write_map_begin(ktype, vtype, size) write_json_array_start write_json_string(get_type_name_for_type_id(ktype)) write_json_string(get_type_name_for_type_id(vtype)) write_json_integer(size) write_json_object_start end def write_map_end write_json_object_end write_json_array_end end def write_list_begin(etype, size) write_json_array_start write_json_string(get_type_name_for_type_id(etype)) write_json_integer(size) end def write_list_end write_json_array_end end def write_set_begin(etype, size) write_json_array_start write_json_string(get_type_name_for_type_id(etype)) write_json_integer(size) end def write_set_end write_json_array_end end def write_bool(bool) write_json_integer(bool ? 1 : 0) end def write_byte(byte) write_json_integer(byte) end def write_i16(i16) write_json_integer(i16) end def write_i32(i32) write_json_integer(i32) end def write_i64(i64) write_json_integer(i64) end def write_double(dub) write_json_double(dub) end def write_string(str) write_json_string(str) end def write_binary(str) write_json_base64(str) end def write_uuid(uuid) UUID.validate_uuid!(uuid) write_json_string(uuid.downcase) end ## # Reading functions ## # Reads 1 byte and verifies that it matches ch. def read_json_syntax_char(ch) JsonProtocol::read_syntax_char(@reader, ch) end # Decodes the four hex parts of a JSON escaped string character and returns # the character via out. # # Note - this only supports Unicode characters in the BMP (U+0000 to U+FFFF); # characters above the BMP are encoded as two escape sequences (surrogate pairs), # which is not yet implemented def read_json_escape_char str = @reader.read str += @reader.read str += @reader.read str += @reader.read str.hex.chr(Encoding::UTF_8) end # Decodes a JSON string, including unescaping, and returns the string via str def read_json_string(skipContext = false) # This string's characters must match up with the elements in escape_char_vals. # I don't have '/' on this list even though it appears on www.json.org -- # it is not in the RFC -> it is. See RFC 4627 escape_chars = "\"\\/bfnrt" # The elements of this array must match up with the sequence of characters in # escape_chars escape_char_vals = [ "\"", "\\", "\/", "\b", "\f", "\n", "\r", "\t", ] if !skipContext @context.read(@reader) end read_json_syntax_char(@@kJSONStringDelimiter) ch = "" str = "" while (true) ch = @reader.read if (ch == @@kJSONStringDelimiter) break end if (ch == @@kJSONBackslash) ch = @reader.read if (ch == 'u') ch = read_json_escape_char else pos = escape_chars.index(ch); if (pos.nil?) # not found raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected control char, got \'#{ch}\'.") end ch = escape_char_vals[pos] end end str += ch end return str end # Reads a block of base64 characters, decoding it, and returns via str def read_json_base64 str = read_json_string m = str.length % 4 if m != 0 # Add missing padding (4 - m).times do str += '=' end end str.unpack1('m0') end # Reads a sequence of characters, stopping at the first one that is not # a valid JSON numeric character. def read_json_numeric_chars str = "" while (true) ch = @reader.peek if (!is_json_numeric(ch)) break; end ch = @reader.read str += ch end return str end # Reads a sequence of characters and assembles them into a number, # returning them via num def read_json_integer @context.read(@reader) if (@context.escapeNum) read_json_syntax_char(@@kJSONStringDelimiter) end str = read_json_numeric_chars begin num = Integer(str); rescue raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"") end if (@context.escapeNum) read_json_syntax_char(@@kJSONStringDelimiter) end return num end # Reads a JSON number or string and interprets it as a double. def read_json_double @context.read(@reader) num = 0 if (@reader.peek == @@kJSONStringDelimiter) str = read_json_string(true) # Check for NaN, Infinity and -Infinity if (str == @@kThriftNan) num = (+1.0/0.0)/(+1.0/0.0) elsif (str == @@kThriftInfinity) num = +1.0/0.0 elsif (str == @@kThriftNegativeInfinity) num = -1.0/0.0 else if (!@context.escapeNum) # Raise exception -- we should not be in a string in this case raise ProtocolException.new(ProtocolException::INVALID_DATA, "Numeric data unexpectedly quoted") end begin num = Float(str) rescue raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"") end end else if (@context.escapeNum) # This will throw - we should have had a quote if escapeNum == true read_json_syntax_char(@@kJSONStringDelimiter) end str = read_json_numeric_chars begin num = Float(str) rescue raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"") end end return num end def read_json_object_start @context.read(@reader) read_json_syntax_char(@@kJSONObjectStart) push_context(JSONPairContext.new) nil end def read_json_object_end read_json_syntax_char(@@kJSONObjectEnd) pop_context nil end def read_json_array_start @context.read(@reader) read_json_syntax_char(@@kJSONArrayStart) push_context(JSONListContext.new) nil end def read_json_array_end read_json_syntax_char(@@kJSONArrayEnd) pop_context nil end def read_message_begin read_json_array_start version = read_json_integer if (version != @@kThriftVersion1) raise ProtocolException.new(ProtocolException::BAD_VERSION, 'Message contained bad version.') end name = read_json_string message_type = read_json_integer seqid = read_json_integer [name, message_type, seqid] end def read_message_end read_json_array_end nil end def read_struct_begin read_json_object_start nil end def read_struct_end read_json_object_end nil end def read_field_begin # Check if we hit the end of the list ch = @reader.peek if (ch == @@kJSONObjectEnd) field_type = Types::STOP else field_id = read_json_integer read_json_object_start field_type = get_type_id_for_type_name(read_json_string) end [nil, field_type, field_id] end def read_field_end read_json_object_end end def read_map_begin read_json_array_start key_type = get_type_id_for_type_name(read_json_string) val_type = get_type_id_for_type_name(read_json_string) size = read_json_integer read_json_object_start [key_type, val_type, size] end def read_map_end read_json_object_end read_json_array_end end def read_list_begin read_json_array_start [get_type_id_for_type_name(read_json_string), read_json_integer] end def read_list_end read_json_array_end end def read_set_begin read_json_array_start [get_type_id_for_type_name(read_json_string), read_json_integer] end def read_set_end read_json_array_end end def read_bool byte = read_byte byte != 0 end def read_byte read_json_integer end def read_i16 read_json_integer end def read_i32 read_json_integer end def read_i64 read_json_integer end def read_double read_json_double end def read_string read_json_string end def read_binary read_json_base64 end def read_uuid uuid = read_json_string raise EOFError.new if uuid.length < 36 UUID.validate_uuid!(uuid) uuid.tap(&:downcase!) end def to_s "json(#{super.to_s})" end end class JsonProtocolFactory < BaseProtocolFactory def get_protocol(trans) return Thrift::JsonProtocol.new(trans) end def to_s "json" end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/compact_protocol.rb0000664000175000017500000002707315167543515024357 0ustar00buildbuild00000000000000# # 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. # module Thrift class CompactProtocol < BaseProtocol PROTOCOL_ID = [0x82].pack('c').unpack('c').first VERSION = 1 VERSION_MASK = 0x1f TYPE_MASK = 0xE0 TYPE_BITS = 0x07 TYPE_SHIFT_AMOUNT = 5 TSTOP = [nil, Types::STOP, 0] # # All of the on-wire type codes. # class CompactTypes BOOLEAN_TRUE = 0x01 BOOLEAN_FALSE = 0x02 BYTE = 0x03 I16 = 0x04 I32 = 0x05 I64 = 0x06 DOUBLE = 0x07 BINARY = 0x08 LIST = 0x09 SET = 0x0A MAP = 0x0B STRUCT = 0x0C UUID = 0x0D def self.is_bool_type?(b) (b & 0x0f) == BOOLEAN_TRUE || (b & 0x0f) == BOOLEAN_FALSE end COMPACT_TO_TTYPE = { Types::STOP => Types::STOP, BOOLEAN_FALSE => Types::BOOL, BOOLEAN_TRUE => Types::BOOL, BYTE => Types::BYTE, I16 => Types::I16, I32 => Types::I32, I64 => Types::I64, DOUBLE => Types::DOUBLE, BINARY => Types::STRING, LIST => Types::LIST, SET => Types::SET, MAP => Types::MAP, STRUCT => Types::STRUCT, UUID => Types::UUID } TTYPE_TO_COMPACT = { Types::STOP => Types::STOP, Types::BOOL => BOOLEAN_TRUE, Types::BYTE => BYTE, Types::I16 => I16, Types::I32 => I32, Types::I64 => I64, Types::DOUBLE => DOUBLE, Types::STRING => BINARY, Types::LIST => LIST, Types::SET => SET, Types::MAP => MAP, Types::STRUCT => STRUCT, Types::UUID => UUID } def self.get_ttype(compact_type) val = COMPACT_TO_TTYPE[compact_type & 0x0f] raise "don't know what type: #{compact_type & 0x0f}" unless val val end def self.get_compact_type(ttype) val = TTYPE_TO_COMPACT[ttype] raise "don't know what type: #{ttype & 0x0f}" unless val val end end def initialize(transport) super(transport) @last_field = [0] @boolean_value = nil # Pre-allocated read buffer for read_double(). @rbuf = Bytes.empty_byte_buffer(8) end def write_message_begin(name, type, seqid) write_byte(PROTOCOL_ID) write_byte((VERSION & VERSION_MASK) | ((type << TYPE_SHIFT_AMOUNT) & TYPE_MASK)) write_varint32(message_seqid_to_varint32(seqid)) write_string(name) nil end def write_struct_begin(name) @last_field.push(0) nil end def write_struct_end @last_field.pop nil end def write_field_begin(name, type, id) if type == Types::BOOL # we want to possibly include the value, so we'll wait. @boolean_field = [type, id] else write_field_begin_internal(type, id) end nil end # # The workhorse of writeFieldBegin. It has the option of doing a # 'type override' of the type header. This is used specifically in the # boolean field case. # def write_field_begin_internal(type, id, type_override = nil) last_id = @last_field.pop # if there's a type override, use that. typeToWrite = type_override || CompactTypes.get_compact_type(type) # check if we can use delta encoding for the field id if id > last_id && id - last_id <= 15 # write them together write_byte((id - last_id) << 4 | typeToWrite) else # write them separate write_byte(typeToWrite) write_i16(id) end @last_field.push(id) nil end def write_field_stop write_byte(Types::STOP) end def write_map_begin(ktype, vtype, size) if (size == 0) write_byte(0) else write_varint32(size) write_byte(CompactTypes.get_compact_type(ktype) << 4 | CompactTypes.get_compact_type(vtype)) end end def write_list_begin(etype, size) write_collection_begin(etype, size) end def write_set_begin(etype, size) write_collection_begin(etype, size); end def write_bool(bool) type = bool ? CompactTypes::BOOLEAN_TRUE : CompactTypes::BOOLEAN_FALSE unless @boolean_field.nil? # we haven't written the field header yet write_field_begin_internal(@boolean_field.first, @boolean_field.last, type) @boolean_field = nil else # we're not part of a field, so just write the value. write_byte(type) end end def write_byte(byte) @trans.write([byte].pack('c')) end def write_i16(i16) write_varint32(int_to_zig_zag(i16)) end def write_i32(i32) write_varint32(int_to_zig_zag(i32)) end def write_i64(i64) write_varint64(long_to_zig_zag(i64)) end def write_double(dub) @trans.write([dub].pack("G").reverse) end def write_string(str) buf = Bytes.convert_to_utf8_byte_buffer(str) write_binary(buf) end def write_binary(buf) write_varint32(buf.bytesize) @trans.write(buf) end def write_uuid(uuid) UUID.validate_uuid!(uuid) trans.write(UUID.uuid_bytes(uuid)) end def read_message_begin protocol_id = read_byte() if protocol_id != PROTOCOL_ID raise ProtocolException.new("Expected protocol id #{PROTOCOL_ID} but got #{protocol_id}") end version_and_type = read_byte() version = version_and_type & VERSION_MASK if (version != VERSION) raise ProtocolException.new("Expected version #{VERSION} but got #{version}"); end type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS seqid = message_seqid_from_varint32(read_varint32()) messageName = read_string() [messageName, type, seqid] end def read_struct_begin @last_field.push(0) "" end def read_struct_end @last_field.pop() nil end def read_field_begin type = read_byte() # if it's a stop, then we can return immediately, as the struct is over. if (type & 0x0f) == Types::STOP TSTOP else field_id = nil # mask off the 4 MSB of the type header. it could contain a field id delta. modifier = (type & 0xf0) >> 4 if modifier == 0 # not a delta. look ahead for the zigzag varint field id. @last_field.pop field_id = read_i16() else # has a delta. add the delta to the last read field id. field_id = @last_field.pop + modifier end # if this happens to be a boolean field, the value is encoded in the type if CompactTypes.is_bool_type?(type) # save the boolean value in a special instance variable. @bool_value = (type & 0x0f) == CompactTypes::BOOLEAN_TRUE end # push the new field onto the field stack so we can keep the deltas going. @last_field.push(field_id) [nil, CompactTypes.get_ttype(type & 0x0f), field_id] end end def read_map_begin size = read_varint32() key_and_value_type = size == 0 ? 0 : read_byte() [CompactTypes.get_ttype(key_and_value_type >> 4), CompactTypes.get_ttype(key_and_value_type & 0xf), size] end def read_list_begin size_and_type = read_byte() size = (size_and_type >> 4) & 0x0f if size == 15 size = read_varint32() end type = CompactTypes.get_ttype(size_and_type) [type, size] end def read_set_begin read_list_begin end def read_bool unless @bool_value.nil? bv = @bool_value @bool_value = nil bv else read_byte() == CompactTypes::BOOLEAN_TRUE end end def read_byte val = trans.read_byte if (val > 0x7f) val = 0 - ((val - 1) ^ 0xff) end val end def read_i16 zig_zag_to_int(read_varint32()) end def read_i32 zig_zag_to_int(read_varint32()) end def read_i64 zig_zag_to_long(read_varint64()) end def read_double trans.read_into_buffer(@rbuf, 8) val = @rbuf.reverse.unpack('G').first val end def read_string buffer = read_binary Bytes.convert_to_string(buffer) end def read_binary size = read_varint32() trans.read_all(size) end def read_uuid UUID.uuid_from_bytes(trans.read_all(16)) end def to_s "compact(#{super.to_s})" end private # # Abstract method for writing the start of lists and sets. List and sets on # the wire differ only by the type indicator. # def write_collection_begin(elem_type, size) if size <= 14 write_byte(size << 4 | CompactTypes.get_compact_type(elem_type)) else write_byte(0xf0 | CompactTypes.get_compact_type(elem_type)) write_varint32(size) end end def write_varint32(n) # int idx = 0; while true if (n & ~0x7F) == 0 # i32buf[idx++] = (byte)n; write_byte(n) break # return; else # i32buf[idx++] = (byte)((n & 0x7F) | 0x80); write_byte((n & 0x7F) | 0x80) n = n >> 7 end end # trans_.write(i32buf, 0, idx); end SEVEN_BIT_MASK = 0x7F EVERYTHING_ELSE_MASK = ~SEVEN_BIT_MASK def write_varint64(n) while true if (n & EVERYTHING_ELSE_MASK) == 0 # TODO need to find a way to make this into a long... write_byte(n) break else write_byte((n & SEVEN_BIT_MASK) | 0x80) n >>= 7 end end end def read_varint32() read_varint64() end def read_varint64() shift = 0 result = 0 while true b = read_byte() result |= (b & 0x7f) << shift break if (b & 0x80) != 0x80 shift += 7 end result end def int_to_zig_zag(n) (n << 1) ^ (n >> 31) end def long_to_zig_zag(l) # puts "zz encoded #{l} to #{(l << 1) ^ (l >> 63)}" (l << 1) ^ (l >> 63) end def zig_zag_to_int(n) (n >> 1) ^ -(n & 1) end def zig_zag_to_long(n) (n >> 1) ^ -(n & 1) end def message_seqid_to_varint32(seqid) if seqid < -(2**31) || seqid > (2**31) - 1 raise RangeError, "seqid must be a signed int32" end seqid < 0 ? seqid + (2**32) : seqid end def message_seqid_from_varint32(seqid) seqid > 0x7fffffff ? seqid - (2**32) : seqid end end class CompactProtocolFactory < BaseProtocolFactory def get_protocol(trans) CompactProtocol.new(trans) end def to_s "compact" end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/header_protocol.rb0000664000175000017500000001735315167543515024161 0ustar00buildbuild00000000000000# encoding: ascii-8bit # # 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. # module Thrift # HeaderProtocol is a protocol that wraps HeaderTransport and delegates # to either BinaryProtocol or CompactProtocol based on auto-detection. # # It provides access to header management (get_headers, set_header, etc.) # through the underlying HeaderTransport. # # Example usage: # socket = Thrift::Socket.new('localhost', 9090) # protocol = Thrift::HeaderProtocol.new(socket) # client = MyService::Client.new(protocol) # protocol.trans.open # client.some_method() # protocol.trans.close # class HeaderProtocol < BaseProtocol # Creates a new HeaderProtocol. # # @param transport [BaseTransport, HeaderTransport] The transport to wrap. # If not already a HeaderTransport, it will be wrapped in one. # @param allowed_client_types [Array] Allowed client types for auto-detection # @param default_protocol [Integer] Default protocol ID (BINARY or COMPACT) def initialize(transport, allowed_client_types = nil, default_protocol = HeaderSubprotocolID::COMPACT) # Wrap transport in HeaderTransport if not already wrapped if transport.is_a?(HeaderTransport) @header_transport = transport else @header_transport = HeaderTransport.new(transport, allowed_client_types, default_protocol) end @default_protocol = default_protocol @current_protocol_id = default_protocol # Create initial protocol @protocol = create_protocol(@current_protocol_id) end # Returns the HeaderTransport def trans @header_transport end # Returns headers read from the last message def get_headers @header_transport.get_headers end # Sets a header to be sent with the next message def set_header(key, value) @header_transport.set_header(key, value) end # Clears all write headers def clear_headers @header_transport.clear_headers end # Adds a transform (e.g., ZLIB compression) def add_transform(transform_id) @header_transport.add_transform(transform_id) end # Write methods - delegate to underlying protocol def write_message_begin(name, type, seqid) @header_transport.sequence_id = seqid @protocol.write_message_begin(name, type, seqid) end def write_message_end @protocol.write_message_end end def write_struct_begin(name) @protocol.write_struct_begin(name) end def write_struct_end @protocol.write_struct_end end def write_field_begin(name, type, id) @protocol.write_field_begin(name, type, id) end def write_field_end @protocol.write_field_end end def write_field_stop @protocol.write_field_stop end def write_map_begin(ktype, vtype, size) @protocol.write_map_begin(ktype, vtype, size) end def write_map_end @protocol.write_map_end end def write_list_begin(etype, size) @protocol.write_list_begin(etype, size) end def write_list_end @protocol.write_list_end end def write_set_begin(etype, size) @protocol.write_set_begin(etype, size) end def write_set_end @protocol.write_set_end end def write_bool(bool) @protocol.write_bool(bool) end def write_byte(byte) @protocol.write_byte(byte) end def write_i16(i16) @protocol.write_i16(i16) end def write_i32(i32) @protocol.write_i32(i32) end def write_i64(i64) @protocol.write_i64(i64) end def write_double(dub) @protocol.write_double(dub) end def write_string(str) @protocol.write_string(str) end def write_binary(buf) @protocol.write_binary(buf) end def write_uuid(uuid) @protocol.write_uuid(uuid) end # Read methods - delegate to underlying protocol # read_message_begin handles protocol switching after detection def read_message_begin begin @header_transport.reset_protocol reset_protocol_if_needed rescue ProtocolException => ex app_ex = ApplicationException.new(ApplicationException::INVALID_PROTOCOL, ex.message) write_message_begin("", MessageTypes::EXCEPTION, 0) app_ex.write(self) write_message_end @header_transport.flush raise ex end @protocol.read_message_begin end def read_message_end @protocol.read_message_end end def read_struct_begin @protocol.read_struct_begin end def read_struct_end @protocol.read_struct_end end def read_field_begin @protocol.read_field_begin end def read_field_end @protocol.read_field_end end def read_map_begin @protocol.read_map_begin end def read_map_end @protocol.read_map_end end def read_list_begin @protocol.read_list_begin end def read_list_end @protocol.read_list_end end def read_set_begin @protocol.read_set_begin end def read_set_end @protocol.read_set_end end def read_bool @protocol.read_bool end def read_byte @protocol.read_byte end def read_i16 @protocol.read_i16 end def read_i32 @protocol.read_i32 end def read_i64 @protocol.read_i64 end def read_double @protocol.read_double end def read_string @protocol.read_string end def read_binary @protocol.read_binary end def read_uuid @protocol.read_uuid end def to_s "header(#{@protocol.to_s})" end private # Checks if the protocol needs to be switched after reading def reset_protocol_if_needed new_protocol_id = @header_transport.protocol_id if new_protocol_id != @current_protocol_id @protocol = create_protocol(new_protocol_id) @current_protocol_id = new_protocol_id end end # Creates a protocol instance based on protocol ID def create_protocol(protocol_id) case protocol_id when HeaderSubprotocolID::BINARY BinaryProtocol.new(@header_transport) when HeaderSubprotocolID::COMPACT CompactProtocol.new(@header_transport) else raise ProtocolException.new( ProtocolException::INVALID_DATA, "Unknown protocol ID: #{protocol_id}" ) end end end # Factory for creating HeaderProtocol instances class HeaderProtocolFactory < BaseProtocolFactory # Creates a new HeaderProtocolFactory. # # @param allowed_client_types [Array] Allowed client types for auto-detection # @param default_protocol [Integer] Default protocol ID (BINARY or COMPACT) def initialize(allowed_client_types = nil, default_protocol = HeaderSubprotocolID::BINARY) @allowed_client_types = allowed_client_types @default_protocol = default_protocol end def get_protocol(trans) HeaderProtocol.new(trans, @allowed_client_types, @default_protocol) end def to_s "header" end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/binary_protocol.rb0000664000175000017500000001400315167543515024202 0ustar00buildbuild00000000000000# # 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. # module Thrift class BinaryProtocol < BaseProtocol VERSION_MASK = 0xffff0000 VERSION_1 = 0x80010000 TYPE_MASK = 0x000000ff attr_reader :strict_read, :strict_write def initialize(trans, strict_read = true, strict_write = true) super(trans) @strict_read = strict_read @strict_write = strict_write # Pre-allocated read buffer for fixed-size read methods. Needs to be at least 8 bytes long for # read_i64() and read_double(). @rbuf = Bytes.empty_byte_buffer(8) end def write_message_begin(name, type, seqid) # this is necessary because we added (needed) bounds checking to # write_i32, and 0x80010000 is too big for that. if strict_write write_i16(VERSION_1 >> 16) write_i16(type) write_string(name) write_i32(seqid) else write_string(name) write_byte(type) write_i32(seqid) end end def write_struct_begin(name); nil; end def write_field_begin(name, type, id) write_byte(type) write_i16(id) end def write_field_stop write_byte(Thrift::Types::STOP) end def write_map_begin(ktype, vtype, size) write_byte(ktype) write_byte(vtype) write_i32(size) end def write_list_begin(etype, size) write_byte(etype) write_i32(size) end def write_set_begin(etype, size) write_byte(etype) write_i32(size) end def write_bool(bool) write_byte(bool ? 1 : 0) end def write_byte(byte) raise 'nil argument not allowed!' if byte.nil? raise RangeError if byte < -2**31 || byte >= 2**32 trans.write([byte].pack('c')) end def write_i16(i16) raise 'nil argument not allowed!' if i16.nil? trans.write([i16].pack('n')) end def write_i32(i32) raise 'nil argument not allowed!' if i32.nil? raise RangeError if i32 < -2**31 || i32 >= 2**31 trans.write([i32].pack('N')) end def write_i64(i64) raise 'nil argument not allowed!' if i64.nil? raise RangeError if i64 < -2**63 || i64 >= 2**64 hi = i64 >> 32 lo = i64 & 0xffffffff trans.write([hi, lo].pack('N2')) end def write_double(dub) raise 'nil argument not allowed!' if dub.nil? trans.write([dub].pack('G')) end def write_string(str) raise 'nil argument not allowed!' if str.nil? buf = Bytes.convert_to_utf8_byte_buffer(str) write_binary(buf) end def write_binary(buf) raise 'nil argument not allowed!' if buf.nil? write_i32(buf.bytesize) trans.write(buf) end def write_uuid(uuid) UUID.validate_uuid!(uuid) trans.write(UUID.uuid_bytes(uuid)) end def read_message_begin version = read_i32 if version < 0 if (version & VERSION_MASK != VERSION_1) raise ProtocolException.new(ProtocolException::BAD_VERSION, 'Missing version identifier') end type = version & TYPE_MASK name = read_string seqid = read_i32 [name, type, seqid] else if strict_read raise ProtocolException.new(ProtocolException::BAD_VERSION, 'No version identifier, old protocol client?') end name = trans.read_all(version) type = read_byte seqid = read_i32 [name, type, seqid] end end def read_struct_begin; nil; end def read_field_begin type = read_byte if (type == Types::STOP) [nil, type, 0] else id = read_i16 [nil, type, id] end end def read_map_begin ktype = read_byte vtype = read_byte size = read_i32 [ktype, vtype, size] end def read_list_begin etype = read_byte size = read_i32 [etype, size] end def read_set_begin etype = read_byte size = read_i32 [etype, size] end def read_bool byte = read_byte byte != 0 end def read_byte val = trans.read_byte if (val > 0x7f) val = 0 - ((val - 1) ^ 0xff) end val end def read_i16 trans.read_into_buffer(@rbuf, 2) val, = @rbuf.unpack('n') if (val > 0x7fff) val = 0 - ((val - 1) ^ 0xffff) end val end def read_i32 trans.read_into_buffer(@rbuf, 4) val, = @rbuf.unpack('N') if (val > 0x7fffffff) val = 0 - ((val - 1) ^ 0xffffffff) end val end def read_i64 trans.read_into_buffer(@rbuf, 8) hi, lo = @rbuf.unpack('N2') if (hi > 0x7fffffff) hi ^= 0xffffffff lo ^= 0xffffffff 0 - (hi << 32) - lo - 1 else (hi << 32) + lo end end def read_double trans.read_into_buffer(@rbuf, 8) val = @rbuf.unpack('G').first val end def read_string buffer = read_binary Bytes.convert_to_string(buffer) end def read_binary size = read_i32 trans.read_all(size) end def read_uuid UUID.uuid_from_bytes(trans.read_all(16)) end def to_s "binary(#{super.to_s})" end end class BinaryProtocolFactory < BaseProtocolFactory def get_protocol(trans) return Thrift::BinaryProtocol.new(trans) end def to_s "binary" end end end thrift-0.23.0/lib/rb/lib/thrift/protocol/multiplexed_protocol.rb0000664000175000017500000000256115167543515025260 0ustar00buildbuild00000000000000# # 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. require 'thrift/protocol/protocol_decorator' module Thrift class MultiplexedProtocol < BaseProtocol include ProtocolDecorator def initialize(protocol, service_name) super(protocol) @service_name = service_name end def write_message_begin(name, type, seqid) case type when MessageTypes::CALL, MessageTypes::ONEWAY @protocol.write_message_begin("#{@service_name}:#{name}", type, seqid) else @protocol.write_message_begin(name, type, seqid) end end def to_s "multiplexed(#{@service_name=@protocol.to_s})" end end end thrift-0.23.0/lib/rb/lib/thrift/types.rb0000664000175000017500000000550215167543515020304 0ustar00buildbuild00000000000000# # 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. # require 'set' module Thrift module Types STOP = 0 VOID = 1 BOOL = 2 BYTE = 3 DOUBLE = 4 I16 = 6 I32 = 8 I64 = 10 STRING = 11 STRUCT = 12 MAP = 13 SET = 14 LIST = 15 UUID = 16 end class << self attr_accessor :type_checking end class TypeError < Exception end def self.check_type(value, field, name, skip_nil = true) return if value.nil? and skip_nil klasses = case field[:type] when Types::VOID NilClass when Types::BOOL [TrueClass, FalseClass] when Types::BYTE, Types::I16, Types::I32, Types::I64 Integer when Types::DOUBLE Float when Types::STRING String when Types::UUID String when Types::STRUCT [Struct, Union] when Types::MAP Hash when Types::SET Set when Types::LIST Array end valid = klasses && [*klasses].any? { |klass| klass === value } raise TypeError, "Expected #{type_name(field[:type])}, received #{value.class} for field #{name}" unless valid # check elements now case field[:type] when Types::MAP value.each_pair do |k, v| check_type(k, field[:key], "#{name}.key", false) check_type(v, field[:value], "#{name}.value", false) end when Types::SET, Types::LIST value.each do |el| check_type(el, field[:element], "#{name}.element", false) end when Types::STRUCT raise TypeError, "Expected #{field[:class]}, received #{value.class} for field #{name}" unless field[:class] == value.class end end def self.type_name(type) Types.constants.each do |const| return "Types::#{const}" if Types.const_get(const) == type end nil end module MessageTypes CALL = 1 REPLY = 2 EXCEPTION = 3 ONEWAY = 4 end end Thrift.type_checking = false if Thrift.type_checking.nil? thrift-0.23.0/lib/rb/benchmark/0000775000175000017500000000000015167543515016475 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rb/benchmark/benchmark.rb0000664000175000017500000002217715167543515020765 0ustar00buildbuild00000000000000# # 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. # require 'rubygems' $:.unshift File.dirname(__FILE__) + '/../lib' $:.unshift File.dirname(__FILE__) + '/../ext' require 'thrift' require 'stringio' HOST = '127.0.0.1' PORT = 42587 ############### ## Server ############### class Server attr_accessor :serverclass attr_accessor :interpreter attr_accessor :host attr_accessor :port attr_accessor :protocol_type def initialize(opts) @serverclass = opts.fetch(:class, Thrift::NonblockingServer) @interpreter = opts.fetch(:interpreter, "ruby") @host = opts.fetch(:host, ::HOST) @port = opts.fetch(:port, ::PORT) @protocol_type = opts.fetch(:protocol_type, 'binary') @tls = opts.fetch(:tls, false) end def start return if @serverclass == Object args = (File.basename(@interpreter) == "jruby" ? "-J-server" : "") @pipe = IO.popen("#{@interpreter} #{args} #{File.dirname(__FILE__)}/server.rb #{"-tls" if @tls} #{@host} #{@port} #{@serverclass.name} #{@protocol_type}", "r+") Marshal.load(@pipe) # wait until the server has started sleep 0.4 # give the server time to actually start spawning sockets end def shutdown return unless @pipe Marshal.dump(:shutdown, @pipe) begin @pipe.read(10) # block until the server shuts down rescue EOFError end @pipe.close @pipe = nil end end class BenchmarkManager def initialize(opts, server) @socket = opts.fetch(:socket) do @host = opts.fetch(:host, 'localhost') @port = opts.fetch(:port) nil end @num_processes = opts.fetch(:num_processes, 40) @clients_per_process = opts.fetch(:clients_per_process, 10) @calls_per_client = opts.fetch(:calls_per_client, 50) @interpreter = opts.fetch(:interpreter, "ruby") @server = server @log_exceptions = opts.fetch(:log_exceptions, false) @protocol_type = opts.fetch(:protocol_type, 'binary') @tls = opts.fetch(:tls, false) end def run @pool = [] @benchmark_start = Time.now puts "Spawning benchmark processes..." @num_processes.times do spawn sleep 0.02 # space out spawns end collect_output @benchmark_end = Time.now # we know the procs are done here translate_output analyze_output report_output end def spawn pipe = IO.popen("#{@interpreter} #{File.dirname(__FILE__)}/client.rb #{"-log-exceptions" if @log_exceptions} #{"-tls" if @tls} #{@host} #{@port} #{@clients_per_process} #{@calls_per_client} #{@protocol_type}") @pool << pipe end def socket_class if @socket Thrift::UNIXSocket elsif @tls Thrift::SSLSocket else Thrift::Socket end end def collect_output puts "Collecting output..." # read from @pool until all sockets are closed @buffers = Hash.new { |h, k| h[k] = '' } until @pool.empty? rd, = select(@pool) next if rd.nil? rd.each do |fd| begin @buffers[fd] << fd.readpartial(4096) rescue EOFError @pool.delete fd end end end end def translate_output puts "Translating output..." @output = [] @buffers.each do |fd, buffer| strio = StringIO.new(buffer) logs = [] begin loop do logs << Marshal.load(strio) end rescue EOFError @output << logs end end end def analyze_output puts "Analyzing output..." call_times = [] client_times = [] connection_failures = [] connection_errors = [] shortest_call = 0 shortest_client = 0 longest_call = 0 longest_client = 0 @output.each do |logs| cur_call, cur_client = nil logs.each do |tok, time| case tok when :start cur_client = time when :call_start cur_call = time when :call_end delta = time - cur_call call_times << delta longest_call = delta unless longest_call > delta shortest_call = delta if shortest_call == 0 or delta < shortest_call cur_call = nil when :end delta = time - cur_client client_times << delta longest_client = delta unless longest_client > delta shortest_client = delta if shortest_client == 0 or delta < shortest_client cur_client = nil when :connection_failure connection_failures << time when :connection_error connection_errors << time end end end @report = {} @report[:total_calls] = call_times.inject(0.0) { |a, t| a += t } @report[:avg_calls] = @report[:total_calls] / call_times.size @report[:total_clients] = client_times.inject(0.0) { |a, t| a += t } @report[:avg_clients] = @report[:total_clients] / client_times.size @report[:connection_failures] = connection_failures.size @report[:connection_errors] = connection_errors.size @report[:shortest_call] = shortest_call @report[:shortest_client] = shortest_client @report[:longest_call] = longest_call @report[:longest_client] = longest_client @report[:total_benchmark_time] = @benchmark_end - @benchmark_start @report[:fastthread] = $".include?('fastthread.bundle') end def report_output fmt = "%.4f seconds" puts tabulate "%d", [["Server class", "%s"], @server.serverclass == Object ? "" : @server.serverclass], [["Server interpreter", "%s"], @server.interpreter], [["Client interpreter", "%s"], @interpreter], [["Protocol type", "%s"], @protocol_type], [["Socket class", "%s"], socket_class], ["Number of processes", @num_processes], ["Clients per process", @clients_per_process], ["Calls per client", @calls_per_client], [["Using fastthread", "%s"], @report[:fastthread] ? "yes" : "no"] puts failures = (@report[:connection_failures] > 0) tabulate fmt, [["Connection failures", "%d", [:red, :bold]], @report[:connection_failures]], [["Connection errors", "%d", [:red, :bold]], @report[:connection_errors]], ["Average time per call", @report[:avg_calls]], ["Average time per client (%d calls)" % @calls_per_client, @report[:avg_clients]], ["Total time for all calls", @report[:total_calls]], ["Real time for benchmarking", @report[:total_benchmark_time]], ["Shortest call time", @report[:shortest_call]], ["Longest call time", @report[:longest_call]], ["Shortest client time (%d calls)" % @calls_per_client, @report[:shortest_client]], ["Longest client time (%d calls)" % @calls_per_client, @report[:longest_client]] end ANSI = { :reset => 0, :bold => 1, :black => 30, :red => 31, :green => 32, :yellow => 33, :blue => 34, :magenta => 35, :cyan => 36, :white => 37 } def tabulate(fmt, *labels_and_values) labels = labels_and_values.map { |l| Array === l ? l.first : l } label_width = labels.inject(0) { |w, l| l.size > w ? l.size : w } labels_and_values.each do |(l, v)| f = fmt l, f, c = l if Array === l fmtstr = "%-#{label_width+1}s #{f}" if STDOUT.tty? and c and v.to_i > 0 fmtstr = "\e[#{[*c].map { |x| ANSI[x] } * ";"}m" + fmtstr + "\e[#{ANSI[:reset]}m" end puts fmtstr % [l+":", v] end end end def resolve_const(const) const and const.split('::').inject(Object) { |k, c| k.const_get(c) } end puts "Starting server..." protocol_type = ENV['THRIFT_PROTOCOL'] || 'binary' args = {} args[:interpreter] = ENV['THRIFT_SERVER_INTERPRETER'] || ENV['THRIFT_INTERPRETER'] || "ruby" args[:class] = resolve_const(ENV['THRIFT_SERVER']) || Thrift::NonblockingServer args[:host] = ENV['THRIFT_HOST'] || HOST args[:port] = (ENV['THRIFT_PORT'] || PORT).to_i args[:tls] = ENV['THRIFT_TLS'] == 'true' args[:protocol_type] = protocol_type server = Server.new(args) server.start args = {} args[:host] = ENV['THRIFT_HOST'] || HOST args[:port] = (ENV['THRIFT_PORT'] || PORT).to_i args[:tls] = ENV['THRIFT_TLS'] == 'true' args[:num_processes] = (ENV['THRIFT_NUM_PROCESSES'] || 40).to_i args[:clients_per_process] = (ENV['THRIFT_NUM_CLIENTS'] || 5).to_i args[:calls_per_client] = (ENV['THRIFT_NUM_CALLS'] || 50).to_i args[:interpreter] = ENV['THRIFT_CLIENT_INTERPRETER'] || ENV['THRIFT_INTERPRETER'] || "ruby" args[:log_exceptions] = !!ENV['THRIFT_LOG_EXCEPTIONS'] args[:protocol_type] = protocol_type BenchmarkManager.new(args, server).run server.shutdown thrift-0.23.0/lib/rb/benchmark/thin_server.rb0000664000175000017500000000302515167543515021352 0ustar00buildbuild00000000000000# # 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. # $:.unshift File.dirname(__FILE__) + '/../lib' $:.unshift File.dirname(__FILE__) + '/../ext' require 'thrift' $:.unshift File.dirname(__FILE__) + "/gen-rb" require 'benchmark_service' HOST = 'localhost' PORT = 42587 class BenchmarkHandler # 1-based index into the fibonacci sequence def fibonacci(n) seq = [1, 1] 3.upto(n) do seq << seq[-1] + seq[-2] end seq[n-1] # n is 1-based end end handler = BenchmarkHandler.new processor = ThriftBenchmark::BenchmarkService::Processor.new(handler) transport = Thrift::ServerSocket.new(HOST, PORT) transport_factory = Thrift::FramedTransportFactory.new logger = Logger.new(STDERR) logger.level = Logger::WARN Thrift::NonblockingServer.new(processor, transport, transport_factory, nil, 20, logger).serve thrift-0.23.0/lib/rb/benchmark/Benchmark.thrift0000664000175000017500000000154715165535636021623 0ustar00buildbuild00000000000000# # 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 rb ThriftBenchmark service BenchmarkService { i32 fibonacci(1:byte n) } thrift-0.23.0/lib/rb/benchmark/client.rb0000664000175000017500000001010215167543515020272 0ustar00buildbuild00000000000000# # 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. # $:.unshift File.dirname(__FILE__) + '/../lib' $:.unshift File.dirname(__FILE__) + '/../ext' require 'thrift' require 'openssl' $:.unshift File.dirname(__FILE__) + "/gen-rb" require 'benchmark_service' class Client def initialize(host, port, clients_per_process, calls_per_client, log_exceptions, tls, protocol_type) @host = host @port = port @clients_per_process = clients_per_process @calls_per_client = calls_per_client @log_exceptions = log_exceptions @tls = tls @protocol_type = protocol_type || 'binary' end def create_protocol(socket) case @protocol_type when 'binary' transport = Thrift::FramedTransport.new(socket) Thrift::BinaryProtocol.new(transport) when 'compact' transport = Thrift::FramedTransport.new(socket) Thrift::CompactProtocol.new(transport) when 'header' Thrift::HeaderProtocol.new(socket) when 'header-compact' Thrift::HeaderProtocol.new(socket, nil, Thrift::HeaderSubprotocolID::COMPACT) when 'header-zlib' protocol = Thrift::HeaderProtocol.new(socket) protocol.add_transform(Thrift::HeaderTransformID::ZLIB) protocol else transport = Thrift::FramedTransport.new(socket) Thrift::BinaryProtocol.new(transport) end end def run @clients_per_process.times do socket = if @tls ssl_context = OpenSSL::SSL::SSLContext.new.tap do |ctx| ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION keys_dir = File.expand_path("../../../test/keys", __dir__) ctx.ca_file = File.join(keys_dir, "CA.pem") ctx.cert = OpenSSL::X509::Certificate.new(File.open(File.join(keys_dir, "client.crt"))) ctx.cert_store = OpenSSL::X509::Store.new ctx.cert_store.add_file(File.join(keys_dir, 'server.pem')) ctx.key = OpenSSL::PKey::RSA.new(File.open(File.join(keys_dir, "client.key"))) end Thrift::SSLSocket.new(@host, @port, 5, ssl_context) else Thrift::Socket.new(@host, @port, 5) end protocol = create_protocol(socket) transport = protocol.trans client = ThriftBenchmark::BenchmarkService::Client.new(protocol) begin start = Time.now transport.open Marshal.dump [:start, start], STDOUT rescue => e Marshal.dump [:connection_failure, Time.now], STDOUT print_exception e if @log_exceptions else begin @calls_per_client.times do Marshal.dump [:call_start, Time.now], STDOUT client.fibonacci(15) Marshal.dump [:call_end, Time.now], STDOUT end transport.close Marshal.dump [:end, Time.now], STDOUT rescue Thrift::TransportException => e Marshal.dump [:connection_error, Time.now], STDOUT print_exception e if @log_exceptions end end end end def print_exception(e) STDERR.puts "ERROR: #{e.message}" STDERR.puts "\t#{e.backtrace * "\n\t"}" end end log_exceptions = true if ARGV[0] == '-log-exceptions' and ARGV.shift tls = true if ARGV[0] == '-tls' and ARGV.shift host, port, clients_per_process, calls_per_client, protocol_type = ARGV Client.new(host, port.to_i, clients_per_process.to_i, calls_per_client.to_i, log_exceptions, tls, protocol_type).run thrift-0.23.0/lib/rb/benchmark/server.rb0000664000175000017500000000757615167543515020347 0ustar00buildbuild00000000000000# # 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. # $:.unshift File.dirname(__FILE__) + '/../lib' $:.unshift File.dirname(__FILE__) + '/../ext' require 'thrift' require 'openssl' $:.unshift File.dirname(__FILE__) + "/gen-rb" require 'benchmark_service' module Server include Thrift class BenchmarkHandler # 1-based index into the fibonacci sequence def fibonacci(n) seq = [1, 1] 3.upto(n) do seq << seq[-1] + seq[-2] end seq[n-1] # n is 1-based end end def self.create_factories(protocol_type) case protocol_type when 'binary' [FramedTransportFactory.new, BinaryProtocolFactory.new] when 'compact' [FramedTransportFactory.new, CompactProtocolFactory.new] when 'header' [HeaderTransportFactory.new, HeaderProtocolFactory.new] when 'header-compact' [HeaderTransportFactory.new, HeaderProtocolFactory.new(nil, HeaderSubprotocolID::COMPACT)] when 'header-zlib' # Note: Server doesn't add transforms - it mirrors client's transforms [HeaderTransportFactory.new, HeaderProtocolFactory.new] else [FramedTransportFactory.new, BinaryProtocolFactory.new] end end def self.start_server(host, port, serverClass, tls, protocol_type = nil) handler = BenchmarkHandler.new processor = ThriftBenchmark::BenchmarkService::Processor.new(handler) transport = if tls ssl_context = OpenSSL::SSL::SSLContext.new.tap do |ctx| ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION keys_dir = File.expand_path("../../../test/keys", __dir__) ctx.ca_file = File.join(keys_dir, "CA.pem") ctx.cert = OpenSSL::X509::Certificate.new(File.open(File.join(keys_dir, "server.crt"))) ctx.cert_store = OpenSSL::X509::Store.new ctx.cert_store.add_file(File.join(keys_dir, 'client.pem')) ctx.key = OpenSSL::PKey::RSA.new(File.open(File.join(keys_dir, "server.key"))) end Thrift::SSLServerSocket.new(host, port, ssl_context) else ServerSocket.new(host, port) end transport_factory, protocol_factory = create_factories(protocol_type || 'binary') args = [processor, transport, transport_factory, protocol_factory, 20] if serverClass == NonblockingServer logger = Logger.new(STDERR) logger.level = Logger::WARN args << logger end server = serverClass.new(*args) @server_thread = Thread.new do server.serve end @server = server end def self.shutdown return if @server.nil? if @server.respond_to? :shutdown @server.shutdown else @server_thread.kill end end end def resolve_const(const) const and const.split('::').inject(Object) { |k, c| k.const_get(c) } end tls = true if ARGV[0] == '-tls' and ARGV.shift host, port, serverklass, protocol_type = ARGV Server.start_server(host, port.to_i, resolve_const(serverklass), tls, protocol_type) # let our host know that the interpreter has started # ideally we'd wait until the server was serving, but we don't have a hook for that Marshal.dump(:started, STDOUT) STDOUT.flush Marshal.load(STDIN) # wait until we're instructed to shut down Server.shutdown thrift-0.23.0/lib/rb/Makefile.in0000644000175000017500000006123415170007167016604 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_TESTS_TRUE@am__append_1 = test/fuzz subdir = lib/rb ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = . test/fuzz am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . $(am__append_1) EXTRA_DIST = \ .rubocop.yml \ coding_standards.md \ Rakefile \ Gemfile \ Gemfile.linters \ Gemfile.lock \ test/fuzz/.gitignore \ thrift.gemspec \ lib \ ext \ benchmark \ script \ spec \ README.md all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rb/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rb/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook @HAVE_BUNDLER_FALSE@check-local: check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive @HAVE_BUNDLER_FALSE@all-local: all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @HAVE_BUNDLER_FALSE@clean-local: @HAVE_BUNDLER_FALSE@install-exec-hook: clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-exec-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am dist-hook distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile DESTDIR ?= / @HAVE_BUNDLER_TRUE@all-local: @HAVE_BUNDLER_TRUE@ $(BUNDLER) install @HAVE_BUNDLER_TRUE@ $(BUNDLER) exec rake build_ext @HAVE_BUNDLER_TRUE@install-exec-hook: @HAVE_BUNDLER_TRUE@ $(BUNDLER) exec rake install @HAVE_BUNDLER_TRUE@clean-local: @HAVE_BUNDLER_TRUE@ $(BUNDLER) install @HAVE_BUNDLER_TRUE@ $(BUNDLER) exec rake clean @HAVE_BUNDLER_TRUE@ $(RM) -r spec/gen-rb/ @HAVE_BUNDLER_TRUE@check-local: all @HAVE_BUNDLER_TRUE@ $(BUNDLER) install @HAVE_BUNDLER_TRUE@ $(BUNDLER) exec rake dist-hook: $(RM) -r $(distdir)/spec/gen-rb/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rb/Makefile.am0000664000175000017500000000264015170007142016562 0ustar00buildbuild00000000000000# # 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. # DESTDIR ?= / SUBDIRS = . if WITH_TESTS SUBDIRS += test/fuzz endif if HAVE_BUNDLER all-local: $(BUNDLER) install $(BUNDLER) exec rake build_ext install-exec-hook: $(BUNDLER) exec rake install clean-local: $(BUNDLER) install $(BUNDLER) exec rake clean $(RM) -r spec/gen-rb/ check-local: all $(BUNDLER) install $(BUNDLER) exec rake endif dist-hook: $(RM) -r $(distdir)/spec/gen-rb/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ .rubocop.yml \ coding_standards.md \ Rakefile \ Gemfile \ Gemfile.linters \ Gemfile.lock \ test/fuzz/.gitignore \ thrift.gemspec \ lib \ ext \ benchmark \ script \ spec \ README.md thrift-0.23.0/lib/rb/Gemfile.lock0000664000175000017500000000514415170007142016752 0ustar00buildbuild00000000000000PATH remote: . specs: thrift (0.23.0) logger GEM remote: https://rubygems.org/ specs: ast (2.4.3) binding_of_caller (1.0.1) debug_inspector (>= 1.2.0) byebug (11.1.3) cgi (0.5.0) coderay (1.1.3) daemons (1.4.1) debug_inspector (1.2.0) diff-lcs (1.6.2) eventmachine (1.2.7) json (2.18.1) language_server-protocol (3.17.0.5) lint_roller (1.1.0) logger (1.7.0) method_source (0.9.2) ostruct (0.6.3) parallel (1.27.0) parser (3.3.10.1) ast (~> 2.4.1) racc prism (1.9.0) pry (0.11.3) coderay (~> 1.1.0) method_source (~> 0.9.0) pry-byebug (3.8.0) byebug (~> 11.0) pry (~> 0.10) pry-stack_explorer (0.4.9.3) binding_of_caller (>= 0.7) pry (>= 0.9.11) racc (1.8.1) rack (2.2.23) rack-test (0.8.3) rack (>= 1.0, < 3) rainbow (3.1.1) rake (13.3.1) regexp_parser (2.11.3) rspec (3.13.2) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) rspec-mocks (~> 3.13.0) rspec-core (3.13.6) rspec-support (~> 3.13.0) rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-mocks (3.13.7) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.6) rubocop (1.82.1) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) rubocop-ast (>= 1.48.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) rubocop-ast (1.49.0) parser (>= 3.3.7.2) prism (~> 1.7) rubocop-performance (1.26.1) lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) rubocop-ast (>= 1.47.1, < 2.0) rubocop-rspec (3.8.0) lint_roller (~> 1.1) rubocop (~> 1.81) ruby-progressbar (1.13.0) srv (1.0.0) rack (>= 1.3.0) thin (1.8.2) daemons (~> 1.0, >= 1.0.9) eventmachine (~> 1.0, >= 1.0.4) rack (>= 1, < 3) unicode-display_width (3.2.0) unicode-emoji (~> 4.1) unicode-emoji (4.2.0) PLATFORMS arm64-darwin arm64-linux ruby x86_64-darwin x86_64-linux DEPENDENCIES bundler (~> 2.2.34) cgi ostruct pry (~> 0.11.3) pry-byebug (~> 3.6) pry-stack_explorer (~> 0.4.9.2) rack (>= 2.2.23) rack-test (~> 0.8.3) rake (~> 13.3) rspec (~> 3.7) rubocop (~> 1.82.0) rubocop-performance (~> 1.26.1) rubocop-rspec (~> 3.8.0) srv (~> 1.0) thin (~> 1.7) thrift! BUNDLED WITH 2.2.34 thrift-0.23.0/lib/rb/thrift.gemspec0000664000175000017500000000370515170007142017376 0ustar00buildbuild00000000000000# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) Gem::Specification.new do |s| s.name = 'thrift' s.version = '0.23.0' s.authors = ['Apache Thrift Developers'] s.email = ['dev@thrift.apache.org'] s.homepage = 'https://thrift.apache.org' s.summary = %q{Ruby bindings for Apache Thrift} s.description = %q{Ruby bindings for the Apache Thrift RPC system} s.license = 'Apache-2.0' s.extensions = ['ext/extconf.rb'] s.required_ruby_version = '>= 2.4.0' s.rdoc_options = %w[--line-numbers --inline-source --title Thrift --main README] dir = File.expand_path(File.dirname(__FILE__)) s.files = Dir.glob("{lib,spec}/**/*") s.test_files = Dir.glob("{test,spec,benchmark}/**/*") s.executables = Dir.glob("{bin}/**/*") s.extra_rdoc_files = %w[README.md] + Dir.glob("{ext,lib}/**/*.{c,h,rb}") s.require_paths = %w[lib ext] s.add_dependency 'logger' s.add_development_dependency 'bundler', '~> 2.2.34' s.add_development_dependency 'pry', '~> 0.11.3' s.add_development_dependency 'pry-byebug', '~> 3.6' s.add_development_dependency 'pry-stack_explorer', '~> 0.4.9.2' s.add_development_dependency 'rack', '>= 2.2.23' s.add_development_dependency 'rack-test', '~> 0.8.3' s.add_development_dependency 'rake', '~> 13.3' s.add_development_dependency 'rspec', '~> 3.7' s.add_development_dependency 'srv', '~> 1.0' s.add_development_dependency 'thin', '~> 1.7' s.metadata = { 'bug_tracker_uri' => 'https://issues.apache.org/jira/browse/THRIFT', 'changelog_uri' => 'https://github.com/apache/thrift/blob/master/CHANGES.md', 'documentation_uri' => 'https://thrift.apache.org/docs/', 'homepage_uri' => 'https://thrift.apache.org', 'mailing_list_uri' => 'https://thrift.apache.org/mailing', 'source_code_uri' => 'https://github.com/apache/thrift/' } end thrift-0.23.0/lib/js/0000775000175000017500000000000015170007175014543 5ustar00buildbuild00000000000000thrift-0.23.0/lib/js/src/0000775000175000017500000000000015170007142015324 5ustar00buildbuild00000000000000thrift-0.23.0/lib/js/src/thrift.js0000664000175000017500000014013215170007142017163 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /*jshint evil:true*/ /** * The Thrift namespace houses the Apache Thrift JavaScript library * elements providing JavaScript bindings for the Apache Thrift RPC * system. End users will typically only directly make use of the * Transport (TXHRTransport/TWebSocketTransport) and Protocol * (TJSONPRotocol/TBinaryProtocol) constructors. * * Object methods beginning with a __ (e.g. __onOpen()) are internal * and should not be called outside of the object's own methods. * * This library creates one global object: Thrift * Code in this library must never create additional global identifiers, * all features must be scoped within the Thrift namespace. * @namespace * @example * var transport = new Thrift.Transport('http://localhost:8585'); * var protocol = new Thrift.Protocol(transport); * var client = new MyThriftSvcClient(protocol); * var result = client.MyMethod(); */ var Thrift = { /** * Thrift JavaScript library version. * @readonly * @const {string} Version * @memberof Thrift */ Version: '0.23.0', /** * Thrift IDL type string to Id mapping. * @readonly * @property {number} STOP - End of a set of fields. * @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} DOUBLE - 64 bit IEEE 854 floating point. * @property {number} I16 - Signed 16 bit integer. * @property {number} I32 - Signed 32 bit integer. * @property {number} I64 - Signed 64 bit integer. * @property {number} STRING - Array of bytes representing a string of characters. * @property {number} UTF7 - Array of bytes representing a string of UTF7 encoded characters. * @property {number} STRUCT - A multifield type. * @property {number} MAP - A collection type (map/associative-array/dictionary). * @property {number} SET - A collection type (unordered and without repeated values). * @property {number} LIST - A collection type (unordered). * @property {number} UTF8 - Array of bytes representing a string of UTF8 encoded characters. * @property {number} UTF16 - Array of bytes representing a string of UTF16 encoded characters. */ Type: { STOP: 0, VOID: 1, BOOL: 2, BYTE: 3, I08: 3, DOUBLE: 4, I16: 6, I32: 8, I64: 10, STRING: 11, UTF7: 11, STRUCT: 12, MAP: 13, SET: 14, LIST: 15, UTF8: 16, UTF16: 17 }, /** * Thrift RPC message type string to Id mapping. * @readonly * @property {number} CALL - RPC call sent from client to server. * @property {number} REPLY - RPC call normal response from server to client. * @property {number} EXCEPTION - RPC call exception response from server to client. * @property {number} ONEWAY - Oneway RPC call from client to server with no response. */ MessageType: { CALL: 1, REPLY: 2, EXCEPTION: 3, ONEWAY: 4 }, /** * Utility function returning the count of an object's own properties. * @param {object} obj - Object to test. * @returns {number} number of object's own properties */ objectLength: function(obj) { var length = 0; for (var k in obj) { if (obj.hasOwnProperty(k)) { length++; } } return length; }, /** * Utility function to establish prototype inheritance. * @see {@link http://javascript.crockford.com/prototypal.html|Prototypal Inheritance} * @param {function} constructor - Contstructor function to set as derived. * @param {function} superConstructor - Contstructor function to set as base. * @param {string} [name] - Type name to set as name property in derived prototype. */ inherits: function(constructor, superConstructor, name) { function F() {} F.prototype = superConstructor.prototype; constructor.prototype = new F(); constructor.prototype.name = name || ''; } }; /** * Initializes a Thrift TException instance. * @constructor * @augments Error * @param {string} message - The TException message (distinct from the Error message). * @classdesc TException is the base class for all Thrift exceptions types. */ Thrift.TException = function(message) { this.message = message; }; Thrift.inherits(Thrift.TException, Error, 'TException'); /** * Returns the message set on the exception. * @readonly * @returns {string} exception message */ Thrift.TException.prototype.getMessage = function() { return this.message; }; /** * Thrift Application Exception type string to Id mapping. * @readonly * @property {number} UNKNOWN - Unknown/undefined. * @property {number} UNKNOWN_METHOD - Client attempted to call a method unknown to the server. * @property {number} INVALID_MESSAGE_TYPE - Client passed an unknown/unsupported MessageType. * @property {number} WRONG_METHOD_NAME - Unused. * @property {number} BAD_SEQUENCE_ID - Unused in Thrift RPC, used to flag proprietary sequence number errors. * @property {number} MISSING_RESULT - Raised by a server processor if a handler fails to supply the required return result. * @property {number} INTERNAL_ERROR - Something bad happened. * @property {number} PROTOCOL_ERROR - The protocol layer failed to serialize or deserialize data. * @property {number} INVALID_TRANSFORM - Unused. * @property {number} INVALID_PROTOCOL - The protocol (or version) is not supported. * @property {number} UNSUPPORTED_CLIENT_TYPE - Unused. */ Thrift.TApplicationExceptionType = { UNKNOWN: 0, UNKNOWN_METHOD: 1, INVALID_MESSAGE_TYPE: 2, WRONG_METHOD_NAME: 3, BAD_SEQUENCE_ID: 4, MISSING_RESULT: 5, INTERNAL_ERROR: 6, PROTOCOL_ERROR: 7, INVALID_TRANSFORM: 8, INVALID_PROTOCOL: 9, UNSUPPORTED_CLIENT_TYPE: 10 }; /** * Initializes a Thrift TApplicationException instance. * @constructor * @augments Thrift.TException * @param {string} message - The TApplicationException message (distinct from the Error message). * @param {Thrift.TApplicationExceptionType} [code] - The TApplicationExceptionType code. * @classdesc TApplicationException is the exception class used to propagate exceptions from an RPC server back to a calling client. */ Thrift.TApplicationException = function(message, code) { this.message = message; this.code = typeof code === 'number' ? code : 0; }; Thrift.inherits(Thrift.TApplicationException, Thrift.TException, 'TApplicationException'); /** * Read a TApplicationException from the supplied protocol. * @param {object} input - The input protocol to read from. */ Thrift.TApplicationException.prototype.read = function(input) { while (1) { var ret = input.readFieldBegin(); if (ret.ftype == Thrift.Type.STOP) { break; } var fid = ret.fid; switch (fid) { case 1: if (ret.ftype == Thrift.Type.STRING) { ret = input.readString(); this.message = ret.value; } else { ret = input.skip(ret.ftype); } break; case 2: if (ret.ftype == Thrift.Type.I32) { ret = input.readI32(); this.code = ret.value; } else { ret = input.skip(ret.ftype); } break; default: ret = input.skip(ret.ftype); break; } input.readFieldEnd(); } input.readStructEnd(); }; /** * Wite a TApplicationException to the supplied protocol. * @param {object} output - The output protocol to write to. */ Thrift.TApplicationException.prototype.write = function(output) { output.writeStructBegin('TApplicationException'); if (this.message) { output.writeFieldBegin('message', Thrift.Type.STRING, 1); output.writeString(this.getMessage()); output.writeFieldEnd(); } if (this.code) { output.writeFieldBegin('type', Thrift.Type.I32, 2); output.writeI32(this.code); output.writeFieldEnd(); } output.writeFieldStop(); output.writeStructEnd(); }; /** * Returns the application exception code set on the exception. * @readonly * @returns {Thrift.TApplicationExceptionType} exception code */ Thrift.TApplicationException.prototype.getCode = function() { return this.code; }; Thrift.TProtocolExceptionType = { UNKNOWN: 0, INVALID_DATA: 1, NEGATIVE_SIZE: 2, SIZE_LIMIT: 3, BAD_VERSION: 4, NOT_IMPLEMENTED: 5, DEPTH_LIMIT: 6 }; Thrift.TProtocolException = function TProtocolException(type, message) { Error.call(this); if (Error.captureStackTrace !== undefined) { Error.captureStackTrace(this, this.constructor); } this.name = this.constructor.name; this.type = type; this.message = message; }; Thrift.inherits(Thrift.TProtocolException, Thrift.TException, 'TProtocolException'); /** * Constructor Function for the XHR transport. * If you do not specify a url then you must handle XHR operations on * your own. This type can also be constructed using the Transport alias * for backward compatibility. * @constructor * @param {string} [url] - The URL to connect to. * @classdesc The Apache Thrift Transport layer performs byte level I/O * between RPC clients and servers. The JavaScript TXHRTransport object * uses Http[s]/XHR. Target servers must implement the http[s] transport * (see: node.js example server_http.js). * @example * var transport = new Thrift.TXHRTransport("http://localhost:8585"); */ Thrift.Transport = Thrift.TXHRTransport = function(url, options) { this.url = url; this.wpos = 0; this.rpos = 0; this.useCORS = (options && options.useCORS); this.customHeaders = options ? (options.customHeaders ? options.customHeaders : {}): {}; this.send_buf = ''; this.recv_buf = ''; }; Thrift.TXHRTransport.prototype = { /** * Gets the browser specific XmlHttpRequest Object. * @returns {object} the browser XHR interface object */ 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."; }, /** * Sends the current XRH request if the transport was created with a URL * and the async parameter is false. If the transport was not created with * a URL, or the async parameter is True and no callback is provided, 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 {object} callback - Optional async completion callback * @returns {undefined|string} Nothing or the current send buffer. * @throws {string} If XHR fails. */ flush: function(async, callback) { var self = this; if ((async && !callback) || this.url === undefined || this.url === '') { return this.send_buf; } var xreq = this.getXmlHttpRequestObject(); if (xreq.overrideMimeType) { xreq.overrideMimeType('application/vnd.apache.thrift.json; charset=utf-8'); } if (callback) { //Ignore XHR callbacks until the data arrives, then call the // client's callback xreq.onreadystatechange = (function() { var clientCallback = callback; return function() { if (this.readyState == 4 && this.status == 200) { self.setRecvBuffer(this.responseText); clientCallback(); } }; }()); // detect net::ERR_CONNECTION_REFUSED and call the callback. xreq.onerror = (function() { var clientCallback = callback; return function() { clientCallback(); }; }()); } xreq.open('POST', this.url, !!async); // add custom headers Object.keys(self.customHeaders).forEach(function(prop) { xreq.setRequestHeader(prop, self.customHeaders[prop]); }); if (xreq.setRequestHeader) { xreq.setRequestHeader('Accept', 'application/vnd.apache.thrift.json; charset=utf-8'); xreq.setRequestHeader('Content-Type', 'application/vnd.apache.thrift.json; charset=utf-8'); } xreq.send(this.send_buf); if (async && callback) { return; } if (xreq.readyState != 4) { throw 'encountered an unknown ajax ready state: ' + xreq.readyState; } if (xreq.status != 200) { throw 'encountered a unknown request status: ' + xreq.status; } this.recv_buf = xreq.responseText; this.recv_buf_sz = this.recv_buf.length; this.wpos = this.recv_buf.length; this.rpos = 0; }, /** * Creates a jQuery XHR object to be used for a Thrift server call. * @param {object} client - The Thrift Service client object generated by the IDL compiler. * @param {object} postData - The message to send to the server. * @param {function} args - The original call arguments with the success call back at the end. * @param {function} recv_method - The Thrift Service Client receive method for the call. * @returns {object} A new jQuery XHR object. * @throws {string} If the jQuery version is prior to 1.5 or if jQuery is not found. */ jqRequest: function(client, postData, args, recv_method) { if (typeof jQuery === 'undefined' || typeof jQuery.Deferred === 'undefined') { throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests'; } var thriftTransport = this; var jqXHR = jQuery.ajax({ url: this.url, data: postData, type: 'POST', cache: false, contentType: 'application/vnd.apache.thrift.json; charset=utf-8', dataType: 'text thrift', converters: { 'text thrift' : function(responseData) { thriftTransport.setRecvBuffer(responseData); var value = recv_method.call(client); return value; } }, context: client, success: jQuery.makeArray(args).pop(), beforeSend: function (xreq) { Object.keys(thriftTransport.customHeaders).forEach(function (prop) { xreq.setRequestHeader(prop, thriftTransport.customHeaders[prop]); }); } }); return jqXHR; }, /** * Sets the buffer to provide the protocol when deserializing. * @param {string} buf - The buffer to supply the protocol. */ setRecvBuffer: function(buf) { this.recv_buf = buf; this.recv_buf_sz = this.recv_buf.length; this.wpos = this.recv_buf.length; this.rpos = 0; }, /** * Returns true if the transport is open, XHR always returns true. * @readonly * @returns {boolean} Always True. */ isOpen: function() { return true; }, /** * Opens the transport connection, with XHR this is a nop. */ open: function() {}, /** * Closes the transport connection, with XHR this is a nop. */ close: function() {}, /** * Returns the specified number of characters from the response * buffer. * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ read: function(len) { var avail = this.wpos - this.rpos; if (avail === 0) { return ''; } var give = len; if (avail < len) { give = avail; } var ret = this.read_buf.substr(this.rpos, give); this.rpos += give; //clear buf when complete? return ret; }, /** * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ readAll: function() { return this.recv_buf; }, /** * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ write: function(buf) { this.send_buf = buf; }, /** * Returns the send buffer. * @readonly * @returns {string} The send buffer. */ getSendBuffer: function() { return this.send_buf; } }; /** * Constructor Function for the WebSocket transport. * @constructor * @param {string} [url] - The URL to connect to. * @classdesc 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. * (see: node.js example server_http.js). * @example * var transport = new Thrift.TWebSocketTransport("http://localhost:8585"); */ Thrift.TWebSocketTransport = function(url) { this.__reset(url); }; Thrift.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 }, /** * 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 {object} callback - The client completion callback. * @returns {undefined|string} Nothing (undefined) */ 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); if (clientCallback) { clientCallback(); } }; }())); } else { //Queue the send to go out __onOpen this.send_pending.push({ buf: this.send_buf, cb: callback }); } }, __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 = []; } }, __onClose: function(evt) { this.__reset(this.url); }, __onMessage: function(evt) { if (this.callbacks.length) { this.callbacks.shift()(evt.data); } }, __onError: function(evt) { console.log('Thrift WebSocket Error: ' + evt.toString()); this.socket.close(); }, /** * Sets the buffer to use when receiving server responses. * @param {string} buf - The buffer to receive server responses. */ setRecvBuffer: function(buf) { this.recv_buf = buf; this.recv_buf_sz = this.recv_buf.length; this.wpos = this.recv_buf.length; this.rpos = 0; }, /** * Returns true if the transport is open * @readonly * @returns {boolean} */ isOpen: function() { return this.socket && this.socket.readyState == this.socket.OPEN; }, /** * Opens the transport connection */ open: function() { //If OPEN/CONNECTING/CLOSING ignore additional opens if (this.socket && this.socket.readyState != this.socket.CLOSED) { return; } //If there is no socket or the socket is closed: this.socket = new WebSocket(this.url); this.socket.onopen = this.__onOpen.bind(this); this.socket.onmessage = this.__onMessage.bind(this); this.socket.onerror = this.__onError.bind(this); this.socket.onclose = this.__onClose.bind(this); }, /** * Closes the transport connection */ close: function() { this.socket.close(); }, /** * Returns the specified number of characters from the response * buffer. * @param {number} len - The number of characters to return. * @returns {string} Characters sent by the server. */ read: function(len) { var avail = this.wpos - this.rpos; if (avail === 0) { return ''; } var give = len; if (avail < len) { give = avail; } var ret = this.read_buf.substr(this.rpos, give); this.rpos += give; //clear buf when complete? return ret; }, /** * Returns the entire response buffer. * @returns {string} Characters sent by the server. */ readAll: function() { return this.recv_buf; }, /** * Sets the send buffer to buf. * @param {string} buf - The buffer to send. */ write: function(buf) { this.send_buf = buf; }, /** * Returns the send buffer. * @readonly * @returns {string} The send buffer. */ getSendBuffer: function() { return this.send_buf; } }; /** * Initializes a Thrift JSON protocol instance. * @constructor * @param {Thrift.Transport} transport - The transport to serialize to/from. * @classdesc Apache Thrift Protocols perform serialization which enables cross * language RPC. The Protocol type is the JavaScript browser implementation * of the Apache Thrift TJSONProtocol. * @example * var protocol = new Thrift.Protocol(transport); */ Thrift.TJSONProtocol = Thrift.Protocol = function(transport) { this.tstack = []; this.tpos = []; this.transport = transport; }; /** * Thrift IDL type Id to string mapping. * @readonly * @see {@link Thrift.Type} */ Thrift.Protocol.Type = {}; Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"'; Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"'; Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"'; Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"'; Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"'; Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"'; Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"'; Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"'; Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"'; Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"'; Thrift.Protocol.Type[Thrift.Type.SET] = '"set"'; /** * Thrift IDL type string to Id mapping. * @readonly * @see {@link Thrift.Type} */ Thrift.Protocol.RType = {}; Thrift.Protocol.RType.tf = Thrift.Type.BOOL; Thrift.Protocol.RType.i8 = Thrift.Type.BYTE; Thrift.Protocol.RType.i16 = Thrift.Type.I16; Thrift.Protocol.RType.i32 = Thrift.Type.I32; Thrift.Protocol.RType.i64 = Thrift.Type.I64; Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE; Thrift.Protocol.RType.rec = Thrift.Type.STRUCT; Thrift.Protocol.RType.str = Thrift.Type.STRING; Thrift.Protocol.RType.map = Thrift.Type.MAP; Thrift.Protocol.RType.lst = Thrift.Type.LIST; Thrift.Protocol.RType.set = Thrift.Type.SET; /** * The TJSONProtocol version number. * @readonly * @const {number} Version * @memberof Thrift.Protocol */ Thrift.Protocol.Version = 1; Thrift.Protocol.prototype = { /** * Returns the underlying transport. * @readonly * @returns {Thrift.Transport} The underlying transport. */ getTransport: function() { return this.transport; }, /** * Serializes the beginning of a Thrift RPC message. * @param {string} name - The service method to call. * @param {Thrift.MessageType} messageType - The type of method call. * @param {number} seqid - The sequence number of this call (always 0 in Apache Thrift). */ writeMessageBegin: function(name, messageType, seqid) { this.tstack = []; this.tpos = []; this.tstack.push([Thrift.Protocol.Version, '"' + name + '"', messageType, seqid]); }, /** * Serializes the end of a Thrift RPC message. */ writeMessageEnd: function() { var obj = this.tstack.pop(); this.wobj = this.tstack.pop(); this.wobj.push(obj); this.wbuf = '[' + this.wobj.join(',') + ']'; this.transport.write(this.wbuf); }, /** * Serializes the beginning of a struct. * @param {string} name - The name of the struct. */ writeStructBegin: function(name) { this.tpos.push(this.tstack.length); this.tstack.push({}); }, /** * Serializes the end of a struct. */ writeStructEnd: function() { var p = this.tpos.pop(); var struct = this.tstack[p]; var str = '{'; var first = true; for (var key in struct) { if (first) { first = false; } else { str += ','; } str += key + ':' + struct[key]; } str += '}'; this.tstack[p] = str; }, /** * Serializes the beginning of a struct field. * @param {string} name - The name of the field. * @param {Thrift.Protocol.Type} fieldType - The data type of the field. * @param {number} fieldId - The field's unique identifier. */ writeFieldBegin: function(name, fieldType, fieldId) { this.tpos.push(this.tstack.length); this.tstack.push({ 'fieldId': '"' + fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType] }); }, /** * Serializes the end of a field. */ writeFieldEnd: function() { var value = this.tstack.pop(); var fieldInfo = this.tstack.pop(); this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' + fieldInfo.fieldType + ':' + value + '}'; this.tpos.pop(); }, /** * Serializes the end of the set of fields for a struct. */ writeFieldStop: function() { //na }, /** * Serializes the beginning of a map collection. * @param {Thrift.Type} keyType - The data type of the key. * @param {Thrift.Type} valType - The data type of the value. * @param {number} [size] - The number of elements in the map (ignored). */ writeMapBegin: function(keyType, valType, size) { this.tpos.push(this.tstack.length); this.tstack.push([Thrift.Protocol.Type[keyType], Thrift.Protocol.Type[valType], 0]); }, /** * Serializes the end of a map. */ writeMapEnd: function() { var p = this.tpos.pop(); if (p == this.tstack.length) { return; } if ((this.tstack.length - p - 1) % 2 !== 0) { this.tstack.push(''); } var size = (this.tstack.length - p - 1) / 2; this.tstack[p][this.tstack[p].length - 1] = size; var map = '}'; var first = true; while (this.tstack.length > p + 1) { var v = this.tstack.pop(); var k = this.tstack.pop(); if (first) { first = false; } else { map = ',' + map; } if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings map = k + ':' + v + map; } map = '{' + map; this.tstack[p].push(map); this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; }, /** * Serializes the beginning of a list collection. * @param {Thrift.Type} elemType - The data type of the elements. * @param {number} size - The number of elements in the list. */ writeListBegin: function(elemType, size) { this.tpos.push(this.tstack.length); this.tstack.push([Thrift.Protocol.Type[elemType], size]); }, /** * Serializes the end of a list. */ writeListEnd: function() { var p = this.tpos.pop(); while (this.tstack.length > p + 1) { var tmpVal = this.tstack[p + 1]; this.tstack.splice(p + 1, 1); this.tstack[p].push(tmpVal); } this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; }, /** * Serializes the beginning of a set collection. * @param {Thrift.Type} elemType - The data type of the elements. * @param {number} size - The number of elements in the list. */ writeSetBegin: function(elemType, size) { this.tpos.push(this.tstack.length); this.tstack.push([Thrift.Protocol.Type[elemType], size]); }, /** * Serializes the end of a set. */ writeSetEnd: function() { var p = this.tpos.pop(); while (this.tstack.length > p + 1) { var tmpVal = this.tstack[p + 1]; this.tstack.splice(p + 1, 1); this.tstack[p].push(tmpVal); } this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; }, /** Serializes a boolean */ writeBool: function(value) { this.tstack.push(value ? 1 : 0); }, /** Serializes a number */ writeByte: function(i8) { this.tstack.push(i8); }, /** Serializes a number */ writeI16: function(i16) { this.tstack.push(i16); }, /** Serializes a number */ writeI32: function(i32) { this.tstack.push(i32); }, /** Serializes a number */ writeI64: function(i64) { if (typeof i64 === 'number') { this.tstack.push(i64); } else { this.tstack.push(Int64Util.toDecimalString(i64)); } }, /** Serializes a number */ writeDouble: function(dbl) { this.tstack.push(dbl); }, /** Serializes a string */ writeString: function(str) { // We do not encode uri components for wire transfer: if (str === null) { this.tstack.push(null); } else { // 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 double backslash } 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 + '"'); } }, /** Serializes a string */ writeBinary: function(binary) { var str = ''; if (typeof binary == 'string') { str = binary; } else if (binary instanceof Uint8Array) { var arr = binary; for (var i = 0; i < arr.length; ++i) { str += String.fromCharCode(arr[i]); } } else { throw new TypeError('writeBinary only accepts String or Uint8Array.'); } this.tstack.push('"' + btoa(str) + '"'); }, /** @class @name AnonReadMessageBeginReturn @property {string} fname - The name of the service method. @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. * @returns {AnonReadMessageBeginReturn} */ readMessageBegin: function() { this.rstack = []; this.rpos = []; var received = this.transport.readAll(); if (typeof JSONInt64 !== 'undefined' && typeof JSONInt64.parse === 'function') { this.robj = JSONInt64.parse(received); } else if (typeof JSON !== 'undefined' && typeof JSON.parse === 'function') { this.robj = JSON.parse(received); } else if (typeof jQuery !== 'undefined') { this.robj = jQuery.parseJSON(received); } else { this.robj = eval(received); } var r = {}; var version = this.robj.shift(); if (version != Thrift.Protocol.Version) { throw 'Wrong thrift protocol version: ' + version; } r.fname = this.robj.shift(); r.mtype = this.robj.shift(); r.rseqid = this.robj.shift(); //get to the main obj this.rstack.push(this.robj.shift()); return r; }, /** Deserializes the end of a message. */ 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 */ readStructBegin: function(name) { var r = {}; r.fname = ''; //incase this is an array of structs if (this.rstack[this.rstack.length - 1] instanceof Array) { this.rstack.push(this.rstack[this.rstack.length - 1].shift()); } return r; }, /** Deserializes the end of a struct. */ readStructEnd: function() { if (this.rstack[this.rstack.length - 2] instanceof Array) { this.rstack.pop(); } }, /** @class @name AnonReadFieldBeginReturn @property {string} fname - The name of the field (always ''). @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. * @returns {AnonReadFieldBeginReturn} */ readFieldBegin: function() { var r = {}; var fid = -1; var ftype = Thrift.Type.STOP; //get a fieldId for (var f in (this.rstack[this.rstack.length - 1])) { if (f === null) { continue; } fid = parseInt(f, 10); this.rpos.push(this.rstack.length); var field = this.rstack[this.rstack.length - 1][fid]; //remove so we don't see it again delete this.rstack[this.rstack.length - 1][fid]; this.rstack.push(field); break; } 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])) { if (Thrift.Protocol.RType[i] === null) { continue; } ftype = Thrift.Protocol.RType[i]; this.rstack[this.rstack.length - 1] = this.rstack[this.rstack.length - 1][i]; } } r.fname = ''; r.ftype = ftype; r.fid = fid; return r; }, /** Deserializes the end of a field. */ readFieldEnd: function() { var pos = this.rpos.pop(); //get back to the right place in the stack while (this.rstack.length > pos) { this.rstack.pop(); } }, /** @class @name AnonReadMapBeginReturn @property {Thrift.Type} ktype - The data type of the key. @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. * @returns {AnonReadMapBeginReturn} */ readMapBegin: function() { var map = this.rstack.pop(); var first = map.shift(); if (first instanceof Array) { this.rstack.push(map); map = first; first = map.shift(); } var r = {}; r.ktype = Thrift.Protocol.RType[first]; r.vtype = Thrift.Protocol.RType[map.shift()]; r.size = map.shift(); this.rpos.push(this.rstack.length); this.rstack.push(map.shift()); return r; }, /** Deserializes the end of a map. */ readMapEnd: function() { this.readFieldEnd(); }, /** @class @name AnonReadColBeginReturn @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. * @returns {AnonReadColBeginReturn} */ readListBegin: function() { var list = this.rstack[this.rstack.length - 1]; var r = {}; r.etype = Thrift.Protocol.RType[list.shift()]; r.size = list.shift(); this.rpos.push(this.rstack.length); this.rstack.push(list.shift()); return r; }, /** Deserializes the end of a list. */ readListEnd: function() { var pos = this.rpos.pop() - 2; var st = this.rstack; st.pop(); if (st instanceof Array && st.length > pos && st[pos].length > 0) { st.push(st[pos].shift()); } }, /** * Deserializes the beginning of a set. * @returns {AnonReadColBeginReturn} */ readSetBegin: function(elemType, size) { return this.readListBegin(elemType, size); }, /** Deserializes the end of a set. */ readSetEnd: function() { return this.readListEnd(); }, /** 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: function() { var r = this.readI32(); if (r !== null && r.value == '1') { r.value = true; } else { r.value = false; } return r; }, /** Returns the an object with a value property set to the next value found in the protocol buffer */ readByte: function() { return this.readI32(); }, /** Returns the an object with a value property set to the next value found in the protocol buffer */ readI16: function() { return this.readI32(); }, /** Returns the an object with a value property set to the next value found in the protocol buffer */ readI32: function(f) { if (f === undefined) { f = this.rstack[this.rstack.length - 1]; } var r = {}; if (f instanceof Array) { if (f.length === 0) { r.value = undefined; } else { if (!f.isReversed) { f.reverse(); f.isReversed = true; } r.value = f.pop(); } } else if (f instanceof Object) { for (var i in f) { if (i === null) { continue; } this.rstack.push(f[i]); delete f[i]; r.value = i; break; } } else { r.value = f; this.rstack.pop(); } return r; }, /** Returns the an object with a value property set to the next value found in the protocol buffer */ readI64: function(f) { if (f === undefined) { f = this.rstack[this.rstack.length - 1]; } var r = {}; if (f instanceof Array) { if (f.length === 0) { r.value = undefined; } else { if (!f.isReversed) { f.reverse(); f.isReversed = true; } r.value = f.pop(); } } else if (f instanceof Object) { var int64Object = true; var objectKeys = Object.keys(f).sort(); var int64Keys = ['buffer', 'offset']; if (objectKeys.length !== int64Keys.length) { int64Object = false; } for (var it=0; int64Object && it < objectKeys.length; ++it) { if (objectKeys[it] !== int64Keys[it]) { int64Object = false; } } if (int64Object) { r.value = f; } else { for (var i in f) { if (i === null) { continue; } this.rstack.push(f[i]); delete f[i]; r.value = i; break; } } } else { r.value = f; this.rstack.pop(); } return r; }, /** Returns the an object with a value property set to the next value found in the protocol buffer */ readDouble: function() { return this.readI32(); }, /** Returns the an object with a value property set to the next value found in the protocol buffer */ readString: function() { var r = this.readI32(); return r; }, /** Returns the an object with a value property set to the next value found in the protocol buffer */ readBinary: function() { var r = this.readI32(); r.value = atob(r.value); return r; }, /** * Method to arbitrarily skip over data */ skip: function(type) { var ret, i; switch (type) { case Thrift.Type.BOOL: return this.readBool(); case Thrift.Type.BYTE: return this.readByte(); case Thrift.Type.I16: return this.readI16(); case Thrift.Type.I32: return this.readI32(); case Thrift.Type.I64: return this.readI64(); case Thrift.Type.DOUBLE: return this.readDouble(); case Thrift.Type.STRING: return this.readString(); case Thrift.Type.STRUCT: this.readStructBegin(); while (true) { ret = this.readFieldBegin(); if (ret.ftype == Thrift.Type.STOP) { break; } this.skip(ret.ftype); this.readFieldEnd(); } this.readStructEnd(); return null; case Thrift.Type.MAP: ret = this.readMapBegin(); for (i = 0; i < ret.size; i++) { if (i > 0) { if (this.rstack.length > this.rpos[this.rpos.length - 1] + 1) { this.rstack.pop(); } } this.skip(ret.ktype); this.skip(ret.vtype); } this.readMapEnd(); return null; case Thrift.Type.SET: ret = this.readSetBegin(); for (i = 0; i < ret.size; i++) { this.skip(ret.etype); } this.readSetEnd(); return null; case Thrift.Type.LIST: ret = this.readListBegin(); for (i = 0; i < ret.size; i++) { this.skip(ret.etype); } this.readListEnd(); return null; default: throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.INVALID_DATA); } } }; /** * Initializes a MutilplexProtocol Implementation as a Wrapper for Thrift.Protocol * @constructor */ Thrift.MultiplexProtocol = function(srvName, trans, strictRead, strictWrite) { Thrift.Protocol.call(this, trans, strictRead, strictWrite); this.serviceName = srvName; }; Thrift.inherits(Thrift.MultiplexProtocol, Thrift.Protocol, 'multiplexProtocol'); /** Override writeMessageBegin method of prototype*/ Thrift.MultiplexProtocol.prototype.writeMessageBegin = function(name, type, seqid) { if (type === Thrift.MessageType.CALL || type === Thrift.MessageType.ONEWAY) { Thrift.Protocol.prototype.writeMessageBegin.call(this, this.serviceName + ':' + name, type, seqid); } else { Thrift.Protocol.prototype.writeMessageBegin.call(this, name, type, seqid); } }; Thrift.Multiplexer = function() { this.seqid = 0; }; /** Instantiates a multiplexed client for a specific service * @constructor * @param {String} serviceName - The transport to serialize to/from. * @param {Thrift.ServiceClient} SCl - The Service Client Class * @param {Thrift.Transport} transport - Thrift.Transport instance which provides remote host:port * @example * var mp = new Thrift.Multiplexer(); * var transport = new Thrift.Transport("http://localhost:9090/foo.thrift"); * var protocol = new Thrift.Protocol(transport); * var client = mp.createClient('AuthService', AuthServiceClient, transport); */ Thrift.Multiplexer.prototype.createClient = function(serviceName, SCl, transport) { if (SCl.Client) { SCl = SCl.Client; } var self = this; SCl.prototype.new_seqid = function() { self.seqid += 1; return self.seqid; }; var client = new SCl(new Thrift.MultiplexProtocol(serviceName, transport)); return client; }; var copyList, copyMap; copyList = function(lst, types) { if (!lst) {return lst; } var type; if (types.shift === undefined) { type = types; } else { type = types[0]; } var Type = type; 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) { result.push(type(val, types.slice(1))); } else { result.push(new Type(val)); } } return result; }; copyMap = function(obj, types) { if (!obj) {return obj; } var type; if (types.shift === undefined) { type = types; } else { type = types[0]; } var Type = type; 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) { result[prop] = type(val, types.slice(1)); } else { result[prop] = new Type(val); } } } return result; }; Thrift.copyMap = copyMap; Thrift.copyList = copyList; thrift-0.23.0/lib/js/test/0000775000175000017500000000000015170007175015522 5ustar00buildbuild00000000000000thrift-0.23.0/lib/js/test/test.js0000664000175000017500000003527215165535636017064 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ /* * JavaScript test suite for ThriftTest.thrift. These tests * will run against Normal (-gen js) and jQuery (-gen js:jquery) * Apache Thrift interfaces. * * Synchronous blocking calls should be identical in both * Normal and jQuery interfaces. All synchronous tests belong * here. * * Asynchronous success callbacks passed as the last parameter * of an RPC call should be identical in both Normal and jQuery * interfaces. Async success tests belong here. * * Asynchronous exception processing is different in Normal * and jQuery interfaces. Such tests belong in the test-nojq.js * or test-jq.js files respectively. jQuery specific XHR object * tests also belong in test-jq.js. Do not create any jQuery * dependencies in this file or in test-nojq.js * * To compile client code for this test use: * $ thrift -gen js ThriftTest.thrift * -- or -- * $ thrift -gen js:jquery ThriftTest.thrift * * See also: * ++ test-nojq.js for "-gen js" only tests * ++ test-jq.js for "-gen js:jquery" only tests */ const transport = new Thrift.Transport('/service'); const protocol = new Thrift.Protocol(transport); const client = new ThriftTest.ThriftTestClient(protocol); const int64_2_pow_60 = new Int64('1000000000000000'); const int64_minus_2_pow_60 = new Int64('f000000000000000'); // Work around for old API used by QUnitAdapter of jsTestDriver if (typeof QUnit.log == 'function') { // When using real QUnit (fron PhantomJS) log failures to console QUnit.log(function(details) { if (!details.result) { console.log('======== FAIL ========'); console.log('TestName: ' + details.name); if (details.message) console.log(details.message); console.log('Expected: ' + details.expected); console.log('Actual : ' + details.actual); console.log('======================'); } }); } // all Languages in UTF-8 const 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(assert, map1, map2) { 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 = ''; 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 = ''; for (let v = 255; v >= 0; --v) { binary += String.fromCharCode(v); } const arr = new Uint8Array(binary.length); for (let i = 0; i < binary.length; ++i) { arr[i] = binary[i].charCodeAt(); } assert.equal(client.testBinary(arr), binary); }); QUnit.test('String', function(assert) { assert.equal(client.testString(''), ''); assert.equal(client.testString(stringTest), stringTest); 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: !@#$%&()(&%$#{}{}<><><'; 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(0), 0); let int64_2_pow_60_result = client.testI64(int64_2_pow_60); assert.ok(int64_2_pow_60.equals(int64_2_pow_60_result)); let int64_minus_2_pow_60_result = client.testI64(int64_minus_2_pow_60); assert.ok(int64_minus_2_pow_60.equals(int64_minus_2_pow_60_result)); }); QUnit.module('Structured Types'); QUnit.test('Struct', function(assert) { const structTestInput = 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 = 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.equal(JSON.stringify(structTestOutput), JSON.stringify(structTestInput)); }); QUnit.test('Nest', function(assert) { const xtrTestInput = 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 = new ThriftTest.Xtruct2(); nestTestInput.byte_thing = 0x02; nestTestInput.struct_thing = xtrTestInput; nestTestInput.i32_thing = Math.pow(2, 15); const nestTestOutput = 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(JSON.stringify(nestTestOutput), JSON.stringify(nestTestInput)); }); QUnit.test('Map', function(assert) { const mapTestInput = {7: 77, 8: 88, 9: 99}; const mapTestOutput = client.testMap(mapTestInput); for (let key in mapTestOutput) { assert.equal(mapTestOutput[key], mapTestInput[key]); } }); QUnit.test('StringMap', function(assert) { const mapTestInput = { 'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key', 'longValue': stringTest, stringTest: 'long key' }; const mapTestOutput = client.testStringMap(mapTestInput); for (let key in mapTestOutput) { assert.equal(mapTestOutput[key], mapTestInput[key]); } }); QUnit.test('Set', function(assert) { const setTestInput = [1, 2, 3]; assert.ok(client.testSet(setTestInput), setTestInput); }); QUnit.test('List', function(assert) { const listTestInput = [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(69), 69); }); QUnit.test('Skip', function(assert) { const structTestInput = new ThriftTest.Xtruct(); const modifiedClient = new ThriftTest.ThriftTestClient(protocol); modifiedClient.recv_testStruct = function() { const input = modifiedClient.input; const xtruct3 = new ThriftTest.Xtruct3(); input.readMessageBegin(); input.readStructBegin(); // read Xtruct data with Xtruct3 input.readFieldBegin(); xtruct3.read(input); input.readFieldEnd(); // read Thrift.Type.STOP message input.readFieldBegin(); input.readFieldEnd(); input.readStructEnd(); input.readMessageEnd(); return xtruct3; }; structTestInput.string_thing = 'worked'; structTestInput.byte_thing = 0x01; structTestInput.i32_thing = Math.pow(2, 30); structTestInput.i64_thing = int64_2_pow_60; const structTestOutput = modifiedClient.testStruct(structTestInput); assert.equal(structTestOutput instanceof ThriftTest.Xtruct3, true); assert.equal(structTestOutput.string_thing, structTestInput.string_thing); assert.equal(structTestOutput.changed, null); assert.equal(structTestOutput.i32_thing, structTestInput.i32_thing); assert.ok(structTestOutput.i64_thing.equals(structTestInput.i64_thing)); }); QUnit.module('deeper!'); QUnit.test('MapMap', function(assert) { const mapMapTestExpectedResult = { '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 = { 'userMap': { '5': 5, '8': 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 = { '1': { '2': crazy, '3': crazy }, '2': { '6': { 'userMap': null, 'xtructs': null } } }; const res = client.testInsanity(new ThriftTest.Insanity(crazy)); assert.ok(res, JSON.stringify(res)); assert.ok(insanity, JSON.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(); }); }); thrift-0.23.0/lib/js/test/test-int64.js0000664000175000017500000000722615165535636020024 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ // Work around for old API used by QUnitAdapter of jsTestDriver if (typeof QUnit.log == 'function') { // When using real QUnit (fron PhantomJS) log failures to console QUnit.log(function(details) { if (!details.result) { console.log('======== FAIL ========'); console.log('TestName: ' + details.name); if (details.message) console.log(details.message); console.log('Expected: ' + details.expected); console.log('Actual : ' + details.actual); console.log('======================'); } }); } QUnit.module('Int64'); QUnit.test('Int64', function(assert) { console.log('Int64 test -- starts'); const EXPECTED_SMALL_INT64_AS_NUMBER = 42; const EXPECTED_SMALL_INT64 = new Int64(42); const EXPECTED_MAX_JS_SAFE_INT64 = new Int64(Number.MAX_SAFE_INTEGER); const EXPECTED_MIN_JS_SAFE_INT64 = new Int64(Number.MIN_SAFE_INTEGER); const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64 = new Int64("0020000000000000"); // hex-encoded const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64 = new Int64("ffe0000000000000"); // hex-encoded 2's complement const EXPECTED_MAX_SIGNED_INT64 = new Int64("7fffffffffffffff"); // hex-encoded const EXPECTED_MIN_SIGNED_INT64 = new Int64("8000000000000000"); // hex-encoded 2's complement const EXPECTED_INT64_LIST = [ EXPECTED_SMALL_INT64, EXPECTED_MAX_JS_SAFE_INT64, EXPECTED_MIN_JS_SAFE_INT64, EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64, EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64, EXPECTED_MAX_SIGNED_INT64, EXPECTED_MIN_SIGNED_INT64 ]; assert.ok(EXPECTED_SMALL_INT64.equals(Int64Test.SMALL_INT64)); assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(Int64Test.MAX_JS_SAFE_INT64)); assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(Int64Test.MIN_JS_SAFE_INT64)); assert.ok( EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals( Int64Test.MAX_JS_SAFE_PLUS_ONE_INT64 ) ); assert.ok( EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals( Int64Test.MIN_JS_SAFE_MINUS_ONE_INT64 ) ); assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(Int64Test.MAX_SIGNED_INT64)); assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(Int64Test.MIN_SIGNED_INT64)); assert.equal( EXPECTED_SMALL_INT64_AS_NUMBER, Int64Test.SMALL_INT64.toNumber() ); assert.equal( Number.MAX_SAFE_INTEGER, Int64Test.MAX_JS_SAFE_INT64.toNumber() ); assert.equal( Number.MIN_SAFE_INTEGER, Int64Test.MIN_JS_SAFE_INT64.toNumber() ); for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) { assert.ok(EXPECTED_INT64_LIST[i].equals(Int64Test.INT64_LIST[i])); } for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i){ let int64Object = EXPECTED_INT64_LIST[i]; assert.ok(Int64Test.INT64_2_INT64_MAP[JSONInt64.toDecimalString(int64Object)].equals(int64Object)); } console.log('Int64 test -- ends'); }); thrift-0.23.0/lib/js/test/test-deep-constructor.html0000664000175000017500000000455515165535636022712 0ustar00buildbuild00000000000000 Thrift Javascript Bindings: Unit Test

Thrift Javascript Bindings: Deep Constructor Test (JsDeepConstructorTest.thrift)

Valid XHTML 1.0!

thrift-0.23.0/lib/js/test/server_http.js0000664000175000017500000000412415165535636020442 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // This HTTP server is designed to serve the test.html browser // based JavaScript test page (which must be in the current directory). // This server also supplies the Thrift based test service, which depends // on the standard ThriftTest.thrift IDL service (which must be compiled // for Node and browser based JavaScript in ./gen-nodejs and ./gen-js // respectively). // // Using the command flag --es6, this server can be run using nodejs code built // for the es6 environment or for pre-es6 environment. // const thrift = require('../../nodejs/lib/thrift'); const es6Mode = process.argv.includes('--es6'); const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs'; const ThriftTestSvc = require(`./${genFolder}/ThriftTest.js`); const ThriftTestHandler = require('./test_handler').ThriftTestHandler; const ThriftTestSvcOpt = { transport: thrift.TBufferedTransport, protocol: thrift.TJSONProtocol, processor: ThriftTestSvc, handler: ThriftTestHandler }; const ThriftWebServerOptions = { files: __dirname, services: { '/service': ThriftTestSvcOpt } }; const server = thrift.createWebServer(ThriftWebServerOptions); const port = es6Mode ? 8088 : 8089; server.listen(port); console.log(`Serving files from: ${__dirname}`); console.log(`Http/Thrift Server (ES6 mode ${es6Mode}) running on port: ${port}`); thrift-0.23.0/lib/js/test/src/0000775000175000017500000000000015165535636016325 5ustar00buildbuild00000000000000thrift-0.23.0/lib/js/test/src/test/0000775000175000017500000000000015165535636017304 5ustar00buildbuild00000000000000thrift-0.23.0/lib/js/test/src/test/Httpd.java0000664000175000017500000003233515165535636021240 0ustar00buildbuild00000000000000/* * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package test; import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.URLDecoder; import java.util.Locale; import org.apache.http.ConnectionClosedException; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpServerConnection; import org.apache.http.HttpStatus; import org.apache.http.MethodNotSupportedException; import org.apache.http.entity.ContentProducer; import org.apache.http.entity.EntityTemplate; import org.apache.http.entity.FileEntity; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.DefaultHttpServerConnection; import org.apache.http.impl.NoConnectionReuseStrategy; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.BasicHttpProcessor; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.protocol.HttpRequestHandlerRegistry; import org.apache.http.protocol.HttpService; import org.apache.http.util.EntityUtils; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TMemoryBuffer; import thrift.test.ThriftTest; import org.apache.thrift.server.ServerTestBase.TestHandler; import eu.medsea.mimeutil.detector.ExtensionMimeDetector; import eu.medsea.mimeutil.MimeUtil2; import eu.medsea.mimeutil.MimeType; import java.util.Collection; import java.util.Iterator; /** * Basic, yet fully functional and spec compliant, HTTP/1.1 file server. *

* Please note the purpose of this application is demonstrate the usage of * HttpCore APIs. It is NOT intended to demonstrate the most efficient way of * building an HTTP file server. * * */ public class Httpd { public static void main(String[] args) throws Exception { if (args.length < 1) { System.err.println("Please specify document root directory"); System.exit(1); } Thread t = new RequestListenerThread(8088, args[0]); t.setDaemon(false); t.start(); } static class HttpFileHandler implements HttpRequestHandler { private final String docRoot; public HttpFileHandler(final String docRoot) { super(); this.docRoot = docRoot; } public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH); if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) { throw new MethodNotSupportedException(method + " method not supported"); } String target = request.getRequestLine().getUri(); if (request instanceof HttpEntityEnclosingRequest && target.equals("/service")) { HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); byte[] entityContent = EntityUtils.toByteArray(entity); System.out.println("Incoming content: " + new String(entityContent)); final String output = this.thriftRequest(entityContent); System.out.println("Outgoing content: "+output); EntityTemplate body = new EntityTemplate(new ContentProducer() { public void writeTo(final OutputStream outstream) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); writer.write(output); writer.flush(); } }); body.setContentType("text/html; charset=UTF-8"); response.setEntity(body); } else { if(target.indexOf("?") != -1) { target = target.substring(1, target.indexOf("?")); } final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8")); if (!file.exists()) { response.setStatusCode(HttpStatus.SC_NOT_FOUND); EntityTemplate body = new EntityTemplate(new ContentProducer() { public void writeTo(final OutputStream outstream) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); writer.write("

"); writer.write("File "); writer.write(file.getPath()); writer.write(" not found"); writer.write("

"); writer.flush(); } }); body.setContentType("text/html; charset=UTF-8"); response.setEntity(body); System.out.println("File " + file.getPath() + " not found"); } else if (!file.canRead() || file.isDirectory()) { response.setStatusCode(HttpStatus.SC_FORBIDDEN); EntityTemplate body = new EntityTemplate(new ContentProducer() { public void writeTo(final OutputStream outstream) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); writer.write("

"); writer.write("Access denied"); writer.write("

"); writer.flush(); } }); body.setContentType("text/html; charset=UTF-8"); response.setEntity(body); System.out.println("Cannot read file " + file.getPath()); } else { String mimeType = "application/octet-stream"; MimeUtil2 mimeUtil = new MimeUtil2(); synchronized (this) { mimeUtil.registerMimeDetector(ExtensionMimeDetector.class.getName()); } Collection collection = mimeUtil.getMimeTypes(file); Iterator iterator = collection.iterator(); while(iterator.hasNext()) { MimeType mt = iterator.next(); mimeType = mt.getMediaType() + "/" + mt.getSubType(); break; } response.setStatusCode(HttpStatus.SC_OK); FileEntity body = new FileEntity(file, mimeType); response.addHeader("Content-Type", mimeType); response.setEntity(body); System.out.println("Serving file " + file.getPath()); } } } private String thriftRequest(byte[] input){ try{ //Input TMemoryBuffer inbuffer = new TMemoryBuffer(input.length); inbuffer.write(input); TProtocol inprotocol = new TJSONProtocol(inbuffer); //Output TMemoryBuffer outbuffer = new TMemoryBuffer(100); TProtocol outprotocol = new TJSONProtocol(outbuffer); TProcessor processor = new ThriftTest.Processor(new TestHandler()); processor.process(inprotocol, outprotocol); byte[] output = new byte[outbuffer.length()]; outbuffer.readAll(output, 0, output.length); return new String(output,"UTF-8"); }catch(Throwable t){ return "Error:"+t.getMessage(); } } } static class RequestListenerThread extends Thread { private final ServerSocket serversocket; private final HttpParams params; private final HttpService httpService; public RequestListenerThread(int port, final String docroot) throws IOException { this.serversocket = new ServerSocket(port); this.params = new BasicHttpParams(); this.params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 1000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); // Set up the HTTP protocol processor HttpProcessor httpproc = new BasicHttpProcessor(); // Set up request handlers HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry(); reqistry.register("*", new HttpFileHandler(docroot)); // Set up the HTTP service this.httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory()); this.httpService.setParams(this.params); this.httpService.setHandlerResolver(reqistry); } public void run() { System.out.println("Listening on port " + this.serversocket.getLocalPort()); System.out.println("Point your browser to http://localhost:8088/test/test.html"); while (!Thread.interrupted()) { try { // Set up HTTP connection Socket socket = this.serversocket.accept(); DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); System.out.println("Incoming connection from " + socket.getInetAddress()); conn.bind(socket, this.params); // Start worker thread Thread t = new WorkerThread(this.httpService, conn); t.setDaemon(true); t.start(); } catch (InterruptedIOException ex) { break; } catch (IOException e) { System.err.println("I/O error initialising connection thread: " + e.getMessage()); break; } } } } static class WorkerThread extends Thread { private final HttpService httpservice; private final HttpServerConnection conn; public WorkerThread(final HttpService httpservice, final HttpServerConnection conn) { super(); this.httpservice = httpservice; this.conn = conn; } public void run() { System.out.println("New connection thread"); HttpContext context = new BasicHttpContext(null); try { while (!Thread.interrupted() && this.conn.isOpen()) { this.httpservice.handleRequest(this.conn, context); } } catch (ConnectionClosedException ex) { System.err.println("Client closed connection"); } catch (IOException ex) { System.err.println("I/O error: " + ex.getMessage()); } catch (HttpException ex) { System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage()); } finally { try { this.conn.shutdown(); } catch (IOException ignore) { } } } } } thrift-0.23.0/lib/js/test/test-nojq.js0000664000175000017500000000272115165535636020022 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ /* * JavaScript test suite for ThriftTest.thrift. These tests * will run only with normal "-gen js" Apache Thrift interfaces. * To create client code: * $ thrift -gen js ThriftTest.thrift * * See also: * ++ test.js for generic tests * ++ test-jq.js for "-gen js:jquery" only tests */ ////////////////////////////////// //Async exception tests QUnit.module('NojQ Async'); QUnit.test('Xception', function(assert) { assert.expect(2); const done = assert.async(); client.testException('Xception', function(result) { assert.equal(result.errorCode, 1001); assert.equal(result.message, 'Xception'); done(); }); }); thrift-0.23.0/lib/js/test/testws.html0000664000175000017500000000606015165535636017757 0ustar00buildbuild00000000000000 Thrift Javascript Bindings: Unit Test

Thrift Javascript Bindings: Unit Test (ThriftTest.thrift)

thrift-0.23.0/lib/js/test/build.properties0000664000175000017500000000036415165535636020756 0ustar00buildbuild00000000000000# Maven Ant tasks Jar details mvn.ant.task.version=2.1.3 mvn.repo=https://repo1.maven.org/maven2 mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version} mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar thrift-0.23.0/lib/js/test/test.html0000664000175000017500000000536515165535636017414 0ustar00buildbuild00000000000000 Thrift Javascript Bindings: Unit Test

Thrift Javascript Bindings: Unit Test (ThriftTest.thrift)

thrift-0.23.0/lib/js/test/test-double-rendering.js0000664000175000017500000001337115165535636022303 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ /* * JavaScript test suite for double constants inside * DoubleConstantsTest.thrift. These tests will run against Normal (-gen js) * Apache Thrift interfaces. * * To compile client code for this test use: * $ thrift -gen js DoubleConstantsTest.thrift */ // double assertion threshold const EPSILON = 0.0000001; // Work around for old API used by QUnitAdapter of jsTestDriver if (typeof QUnit.log == 'function') { // When using real QUnit (fron PhantomJS) log failures to console QUnit.log(function(details) { if (!details.result) { console.log('======== FAIL ========'); console.log('TestName: ' + details.name); if (details.message) console.log(details.message); console.log('Expected: ' + details.expected); console.log('Actual : ' + details.actual); console.log('======================'); } }); } QUnit.module('Double rendering'); QUnit.test('Double (rendering)', function(assert) { console.log('Double rendering test -- starts'); const EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1; const EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100; const EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807; const EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807; const EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359; const EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1; const EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1; const EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308; const EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43; const EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308; const EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43; assert.ok( Math.abs(EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT - DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT - DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT - DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT - DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS - DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE - DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE - DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE - DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE - DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE - DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST) <= EPSILON); assert.ok( Math.abs( EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE - DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST) <= EPSILON); assert.equal(typeof DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, 'number'); assert.equal(typeof DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, 'number'); const EXPECTED_DOUBLE_LIST = [1,-100,100,9223372036854775807,-9223372036854775807,3.14159265359,1000000.1,-1000000.1,1.7e+308,-1.7e+308, 9223372036854775816.43,-9223372036854775816.43]; assert.equal(DOUBLE_LIST_TEST.length, EXPECTED_DOUBLE_LIST.length); for (let i = 0; i < EXPECTED_DOUBLE_LIST.length; ++i) { assert.ok(Math.abs(EXPECTED_DOUBLE_LIST[i] - DOUBLE_LIST_TEST[i]) <= EPSILON); } console.log('Double rendering test -- ends'); }); thrift-0.23.0/lib/js/test/jsTestDriver.conf0000664000175000017500000000063515165535636021041 0ustar00buildbuild00000000000000server: http://localhost:9876 load: # Qunit adapter - build/js/lib/equiv.js - build/js/lib/QUnitAdapter.js # dependencies - build/js/lib/jquery.js - build/js/thrift.js - gen-js/DoubleConstantsTest_constants.js - gen-js/ThriftTest_types.js - gen-js/ThriftTest.js # the test suite - test.js # redirect to the Java based Thrift testserver proxy: - {matcher: "*", server: " http://localhost:8088"} thrift-0.23.0/lib/js/test/test-int64.html0000664000175000017500000000477115165535636020356 0ustar00buildbuild00000000000000+ Int64 Constants in JS: Unit Test

Int64 Constants in JS: Unit Test

thrift-0.23.0/lib/js/test/server_https.js0000664000175000017500000000447115165535636020632 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ //This HTTP server is designed to server the test.html browser // based JavaScript test page (which must be in the current directory). // This server also supplies the Thrift based test service, which depends // on the standard ThriftTest.thrift IDL service (which must be compiled // for Node and browser based JavaScript in ./gen-nodejs and ./gen-js // respectively). The current directory must also include the browser // support libraries for test.html (jquery.js, qunit.js and qunit.css // in ./build/js/lib). const fs = require('fs'); 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; //Setup the I/O stack options for the ThriftTest service const ThriftTestSvcOpt = { transport: thrift.TBufferedTransport, protocol: thrift.TJSONProtocol, processor: ThriftTestSvc, handler: ThriftTestHandler }; const ThriftWebServerOptions = { files: __dirname, tls: { key: fs.readFileSync('../../../test/keys/server.key'), cert: fs.readFileSync('../../../test/keys/server.crt') }, services: { '/service': ThriftTestSvcOpt } }; const server = thrift.createWebServer(ThriftWebServerOptions); const port = es6Mode ? 8090 : 8091; server.listen(port); console.log(`Serving files from: ${__dirname}`); console.log(`Http/Thrift Server (ES6 mode ${es6Mode}) running on port: ${port}`); thrift-0.23.0/lib/js/test/test-nojq.html0000664000175000017500000000517715165535636020362 0ustar00buildbuild00000000000000 Thrift Javascript Bindings: Unit Test

Thrift Javascript Bindings: Unit Test (ThriftTest.thrift)

thrift-0.23.0/lib/js/test/build.xml0000664000175000017500000002313715165535636017365 0ustar00buildbuild00000000000000 Java Script Test based on Thrift Java Library You need libthrift*.jar and libthrift*test.jar located at ${thrift.java.dir}/build/libs Did you compile Thrift Java library and its test suite by "make check"? Thrift compiler is missing ! check if Xvfb is available: check if phantomjs is available: Running Unit Tests with headless browser! check if gjslint is available: thrift-0.23.0/lib/js/test/test-es6.html0000664000175000017500000000606315165535636020103 0ustar00buildbuild00000000000000 Thrift Javascript Bindings: Unit Test

Thrift Javascript Bindings: Unit Test (ThriftTest.thrift)

thrift-0.23.0/lib/js/test/deep-constructor.test.js0000664000175000017500000001407015167543515022351 0ustar00buildbuild00000000000000/* * 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. */ function serialize(data) { const transport = new Thrift.Transport('/service'); const protocol = new Thrift.Protocol(transport); protocol.writeMessageBegin('', 0, 0); data.write(protocol); protocol.writeMessageEnd(); return transport.send_buf; } function deserialize(serialized, type) { const transport = new Thrift.Transport('/service'); transport.setRecvBuffer(serialized); const protocol = new Thrift.Protocol(transport); protocol.readMessageBegin(); const data = new type(); data.read(protocol); protocol.readMessageEnd(); return data; } function createThriftObj() { return new Complex({ struct_field: new Simple({value: 'a'}), struct_list_field: [ new Simple({value: 'b'}), new Simple({value: 'c'}) ], struct_set_field: [ new Simple({value: 'd'}), new Simple({value: 'e'}) ], struct_map_field: { A: new Simple({value: 'f'}), B: new Simple({value: 'g'}) }, struct_nested_containers_field: [ [ { C: [ new Simple({value: 'h'}), new Simple({value: 'i'}) ] } ] ], struct_nested_containers_field2: { D: [ { DA: new Simple({value: 'j'}) }, { DB: new Simple({value: 'k'}) } ] }, list_of_list_field: [ ['one', 'two'], ['three', 'four'], ['five', 'six'] ] } ); } function createJsObj() { return { struct_field: {value: 'a'}, struct_list_field: [ {value: 'b'}, {value: 'c'} ], struct_set_field: [ {value: 'd'}, {value: 'e'} ], struct_map_field: { A: {value: 'f'}, B: {value: 'g'} }, struct_nested_containers_field: [ [ { C: [ {value: 'h'}, {value: 'i'} ] } ] ], struct_nested_containers_field2: { D: [ { DA: {value: 'j'} }, { DB: {value: 'k'} } ] }, list_of_list_field: [ ['one', 'two'], ['three', 'four'], ['five', 'six'] ] }; } function assertValues(obj, assert) { assert.equal(obj.struct_field.value, 'a'); assert.equal(obj.struct_list_field[0].value, 'b'); assert.equal(obj.struct_list_field[1].value, 'c'); assert.equal(obj.struct_set_field[0].value, 'd'); assert.equal(obj.struct_set_field[1].value, 'e'); assert.equal(obj.struct_map_field.A.value, 'f'); assert.equal(obj.struct_map_field.B.value, 'g'); assert.equal(obj.struct_nested_containers_field[0][0].C[0].value, 'h'); assert.equal(obj.struct_nested_containers_field[0][0].C[1].value, 'i'); assert.equal(obj.struct_nested_containers_field2.D[0].DA.value, 'j'); assert.equal(obj.struct_nested_containers_field2.D[1].DB.value, 'k'); assert.equal(obj.list_of_list_field[0][0], 'one'); assert.equal(obj.list_of_list_field[0][1], 'two'); assert.equal(obj.list_of_list_field[1][0], 'three'); assert.equal(obj.list_of_list_field[1][1], 'four'); assert.equal(obj.list_of_list_field[2][0], 'five'); assert.equal(obj.list_of_list_field[2][1], 'six'); } const cases = { 'Serialize/deserialize simple struct should return equal object': function(assert) { const tObj = new Simple({value: 'a'}); const received = deserialize(serialize(tObj), Simple); assert.ok(tObj !== received); assert.deepEqual(received, tObj); }, 'Serialize/deserialize should return equal object': function(assert) { const tObj = createThriftObj(); const received = deserialize(serialize(tObj), Complex); assert.ok(tObj !== received); assert.deepEqual(received, tObj); }, '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 Complex(createJsObj()); assertValues(tObj2, assert); assert.equal(serialize(tObj2), serialize(tObj1)); }, 'Modifications to args object should not affect constructed Thrift object': function(assert) { const args = createJsObj(); assertValues(args, assert); const tObj = new 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); }, 'nulls are ok': function(assert) { const tObj = new 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 }); const received = deserialize(serialize(tObj), Complex); assert.ok(tObj !== received); assert.deepEqual(tObj, received); } }; Object.keys(cases).forEach(function(caseName) { QUnit.test(caseName, cases[caseName]); }); thrift-0.23.0/lib/js/test/README.md0000664000175000017500000000532715165535636017024 0ustar00buildbuild00000000000000Thrift Javascript Library ========================= This browser based Apache Thrift implementation supports RPC clients using the JSON protocol over Http[s] with XHR and WebSocket. License ------- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Test Servers ------------ drwxr-xr-x 2 randy randy 4096 Feb 8 15:44 sec -rw-r--r-- 1 randy randy 2183 Feb 9 04:01 server_http.js -rw-r--r-- 1 randy randy 2386 Feb 9 05:39 server_https.js server_http.js is a Node.js web server which support the standard Apache Thrift test suite (thrift/test/ThriftTest.thrift). The server supports Apache Thrift XHR and WebSocket clients. server_https.js is the same but uses SSL/TLS. The server key and cert are pulled from the thrift/test/keys folder. Both of these servers support WebSocket (the http: supports ws:, and the https: support wss:). To run the client test with the Java test server use: $ make check (requires the Apache Thrift Java branch and make check must have been run in thrift/lib/java previously). To run the client tests with the Node servers run the grunt build in the parent js directory (see README there). Test Clients ------------ -rw-r--r-- 1 randy randy 13558 Feb 9 07:18 test-async.js -rw-r--r-- 1 randy randy 5724 Feb 9 03:45 test_handler.js -rwxr-xr-x 1 randy randy 2719 Feb 9 06:04 test.html -rw-r--r-- 1 randy randy 4611 Feb 9 06:05 test-jq.js -rwxr-xr-x 1 randy randy 12153 Feb 9 06:04 test.js -rw-r--r-- 1 randy randy 2593 Feb 9 06:16 test-nojq.html -rw-r--r-- 1 randy randy 1450 Feb 9 06:14 test-nojq.js -rw-r--r-- 1 randy randy 2847 Feb 9 06:31 testws.html There are three html test driver files, all of which are QUnit based. test.html tests the Apache Thrift jQuery generated code (thrift -gen js:jquery). The test-nojq.html runs almost identical tests against normal JavaScript builds (thrift -gen js). Both of the previous tests use the XHR transport. The testws.html runs similar tests using the WebSocket transport. The test*.js files are loaded by the html drivers and contain the actual Apache Thrift tests. thrift-0.23.0/lib/js/test/phantom-client.js0000664000175000017500000003270215165535636021022 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ (function() { 'use strict'; // Rudimentary test helper functions // TODO: Return error code based on kind of errors rather than throw var ok = function(t, msg) { if (!t) { console.log('*** FAILED ***'); throw new Error(msg); } }; var equal = function(a, b) { if (a !== b) { console.log('*** FAILED ***'); throw new Error(); } }; var test = function(name, f) { console.log('TEST : ' + name); f(); console.log('OK\n'); }; var parseArgs = function(args) { var skips = [ '--transport=http', '--protocol=json' ]; var opts = { port: '9090' // protocol: 'json', }; var keys = {}; for (var key in opts) { keys['--' + key + '='] = key; } for (var i in args) { var arg = args[i]; if (skips.indexOf(arg) != -1) { continue; } var hit = false; for (var k in keys) { if (arg.slice(0, k.length) === k) { opts[keys[k]] = arg.slice(k.length); hit = true; break; } } if (!hit) { throw new Error('Unknown argument: ' + arg); } } opts.port = parseInt(opts.port, 10); if (!opts.port || opts.port < 1 || opts.port > 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('src/thrift.js'); phantom.page.injectJs('test/gen-js/ThriftTest_types.js'); phantom.page.injectJs('test/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 = ''; for (var v = 255; v >= 0; --v) { binary += String.fromCharCode(v); } equal(client.testBinary(binary), binary); }); test('Binary (Uint8Array)', function() { var binary = ''; 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(); } equal(client.testBinary(arr), 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(0), 0); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately equal(client.testI64(Math.pow(2, 52)), Math.pow(2, 52)); equal(client.testI64(-Math.pow(2, 52)), -Math.pow(2, 52)); }); test('Struct', function() { var structTestInput = new ThriftTest.Xtruct(); structTestInput.string_thing = 'worked'; structTestInput.byte_thing = 0x01; structTestInput.i32_thing = Math.pow(2, 30); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately structTestInput.i64_thing = Math.pow(2, 52); var structTestOutput = 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 = new ThriftTest.Xtruct(); xtrTestInput.string_thing = 'worked'; xtrTestInput.byte_thing = 0x01; xtrTestInput.i32_thing = Math.pow(2, 30); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately xtrTestInput.i64_thing = Math.pow(2, 52); var nestTestInput = 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 = {7: 77, 8: 88, 9: 99}; var mapTestOutput = client.testMap(mapTestInput); for (var key in mapTestOutput) { equal(mapTestOutput[key], mapTestInput[key]); } }); test('StringMap', function() { var mapTestInput = { 'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key', 'longValue': stringTest, stringTest: 'long key' }; var mapTestOutput = client.testStringMap(mapTestInput); for (var key in mapTestOutput) { equal(mapTestOutput[key], mapTestInput[key]); } }); test('Set', function() { var setTestInput = [1, 2, 3]; ok(client.testSet(setTestInput), setTestInput); }); test('List', function() { var listTestInput = [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(69), 69); }); test('Skip', function() { var structTestInput = new ThriftTest.Xtruct(); var modifiedClient = new ThriftTest.ThriftTestClient(protocol); modifiedClient.recv_testStruct = function() { var input = modifiedClient.input; var xtruct3 = new ThriftTest.Xtruct3(); input.readMessageBegin(); input.readStructBegin(); // read Xtruct data with Xtruct3 input.readFieldBegin(); xtruct3.read(input); input.readFieldEnd(); // read Thrift.Type.STOP message input.readFieldBegin(); input.readFieldEnd(); input.readStructEnd(); input.readMessageEnd(); return xtruct3; }; structTestInput.string_thing = 'worked'; structTestInput.byte_thing = 0x01; structTestInput.i32_thing = Math.pow(2, 30); structTestInput.i64_thing = Math.pow(2, 52); var structTestOutput = modifiedClient.testStruct(structTestInput); equal(structTestOutput instanceof ThriftTest.Xtruct3, true); equal(structTestOutput.string_thing, structTestInput.string_thing); equal(structTestOutput.changed, null); equal(structTestOutput.i32_thing, structTestInput.i32_thing); equal(structTestOutput.i64_thing, structTestInput.i64_thing); }); test('MapMap', function() { var mapMapTestExpectedResult = { '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); } catch (e) { equal(e.errorCode, 1001); equal(e.message, 'Xception'); } }); test('no Exception', function() { try { client.testException('no Exception'); } catch (e) { ok(false); } }); test('TException', function() { try { client.testException('TException'); ok(false); } catch (e) { ok(ok); } }); var crazy = { 'userMap': { '5': 5, '8': 8 }, 'xtructs': [{ 'string_thing': 'Goodbye4', 'byte_thing': 4, 'i32_thing': 4, 'i64_thing': 4 }, { 'string_thing': 'Hello2', 'byte_thing': 2, 'i32_thing': 2, 'i64_thing': 2 }] }; test('Insanity', function() { var insanity = { '1': { '2': crazy, '3': crazy }, '2': { '6': { 'userMap': null, 'xtructs': null } } }; 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); } })(); thrift-0.23.0/lib/js/test/phantomjs-qunit.js0000664000175000017500000000700215165535636021234 0ustar00buildbuild00000000000000/*jshint evil:true*/ /* This file is only used by the test suite. * * Origin: https://github.com/ariya/phantomjs/blob/master/examples/run-qunit.js * License: https://github.com/ariya/phantomjs/blob/master/LICENSE.BSD * * Inclusion into Apache products is allowed according to http://www.apache.org/legal/3party.html */ var system = require('system'); /** * Wait until the test condition is true or a timeout occurs. Useful for waiting * on a server response or for a ui change (fadeIn, etc.) to occur. * * @param testFx javascript condition that evaluates to a boolean, * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or * as a callback function. * @param onReady what to do when testFx condition is fulfilled, * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or * as a callback function. * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. */ function waitFor(testFx, onReady, timeOutMillis) { var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timout is 3s start = new Date().getTime(), condition = false, interval = setInterval(function() { if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { // If not time-out yet and condition not yet fulfilled condition = (typeof(testFx) === 'string' ? eval(testFx) : testFx()); //< defensive code } else { if (!condition) { // If condition still not fulfilled (timeout but condition is 'false') console.log("'waitFor()' timeout"); phantom.exit(1); } else { // Condition fulfilled (timeout and/or condition is 'true') console.log("'waitFor()' finished in " + (new Date().getTime() - start) + 'ms.'); if (typeof(onReady) === 'string') { eval(onReady); } else { onReady(); //< Do what it's supposed to do once the condition is fulfilled } clearInterval(interval); //< Stop this interval } } }, 100); //< repeat check every 250ms } if (system.args.length === 1 || system.args.length > 3) { console.log('Usage: phantomjs phantomjs-qunit.js URL'); phantom.exit(1); } var page = new WebPage(); // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") page.onConsoleMessage = function(msg) { console.log(msg); }; page.open(system.args[1], function(status) { if (status !== 'success') { console.log('Unable to access network'); phantom.exit(1); } else { waitFor(function() { return page.evaluate(function() { var el = document.getElementById('qunit-testresult'); if (el && el.innerText.match('completed')) { return true; } return false; }); }, function() { var failedNum = page.evaluate(function() { var el = document.getElementById('qunit-testresult'); console.log(el.innerText); try { return el.getElementsByClassName('failed')[0].innerHTML; } catch (e) { } return 10000; }); phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0); }); } }); thrift-0.23.0/lib/js/test/Makefile0000644000175000017500000004404715170007175017171 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/js/test/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/js/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/js/test abs_srcdir = /thrift/src/lib/js/test abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/js/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/js/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-am check-local clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile export CLASSPATH # Make sure this doesn't fail if ant is not configured. 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 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/js/test/test-jq.js0000664000175000017500000001102715165535636017464 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ /* * JavaScript test suite for ThriftTest.thrift. These tests * will run only with jQuery (-gen js:jquery) Apache Thrift * interfaces. To create client code: * $ thrift -gen js:jquery ThriftTest.thrift * * See also: * ++ test.js for generic tests * ++ test-nojq.js for "-gen js" only tests */ ////////////////////////////////// //jQuery asynchronous tests jQuery.ajaxSetup({ timeout: 0 }); QUnit.module('jQ Async Manual'); QUnit.test('testI32', function(assert) { assert.expect(2); const done = assert.async(2); const transport = new Thrift.Transport(); const protocol = new Thrift.Protocol(transport); const client = new ThriftTest.ThriftTestClient(protocol); const jqxhr = jQuery.ajax({ url: '/service', data: client.send_testI32(Math.pow(-2, 31)), type: 'POST', cache: false, dataType: 'text', success: function(res) { transport.setRecvBuffer(res); assert.equal(client.recv_testI32(), Math.pow(-2, 31)); done(); }, error: function() { assert.ok(false); }, complete: function() { assert.ok(true); done(); } }); }); QUnit.test('testI64', function(assert) { assert.expect(2); const done = assert.async(2); const transport = new Thrift.Transport(); const protocol = new Thrift.Protocol(transport); const client = new ThriftTest.ThriftTestClient(protocol); jQuery.ajax({ url: '/service', //This is usually 2^61 but JS cannot represent anything over 2^52 accurately data: client.send_testI64(Math.pow(-2, 52)), type: 'POST', cache: false, dataType: 'text', success: function(res) { transport.setRecvBuffer(res); //This is usually 2^61 but JS cannot represent anything over 2^52 accurately assert.equal(client.recv_testI64(), Math.pow(-2, 52)); done(); }, error: function() { assert.ok(false); }, complete: function() { assert.ok(true); done(); } }); }); QUnit.module('jQ Async'); QUnit.test('I32', function(assert) { assert.expect(3); const done = assert.async(3); client.testI32(Math.pow(2, 30), function(result) { assert.equal(result, Math.pow(2, 30)); done(); }); const jqxhr = client.testI32(Math.pow(-2, 31), function(result) { assert.equal(result, Math.pow(-2, 31)); done(); }); jqxhr.success(function(result) { assert.equal(result, Math.pow(-2, 31)); done(); }); }); QUnit.test('I64', function(assert) { assert.expect(4); const done = assert.async(4); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately client.testI64(Math.pow(2, 52), function(result) { assert.equal(result, Math.pow(2, 52)); done(); }); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately client.testI64(Math.pow(-2, 52), function(result) { assert.equal(result, Math.pow(-2, 52)); done(); }) .error(function(xhr, status, e) { assert.ok(false, e.message); }) .success(function(result) { //This is usually 2^60 but JS cannot represent anything over 2^52 accurately assert.equal(result, Math.pow(-2, 52)); done(); }) .complete(function() { assert.ok(true); done(); }); }); QUnit.test('Xception', function(assert) { assert.expect(2); const done = assert.async(2); const dfd = client.testException('Xception', function(result) { assert.ok(false); done(); }) .error(function(xhr, status, e) { assert.equal(e.errorCode, 1001); assert.equal(e.message, 'Xception'); done(); $(document).ajaxError( function() { done(); } ); }); }); thrift-0.23.0/lib/js/test/test-async.js0000664000175000017500000003061715165535636020175 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ /* * Fully Async JavaScript test suite for ThriftTest.thrift. * These tests are designed to exercise the WebSocket transport * (which is exclusively async). * * To compile client code for this test use: * $ thrift -gen js ThriftTest.thrift */ // all Languages in UTF-8 const 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(assert, map1, map2) { 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.expect(1); const done = assert.async(); client.testVoid(function(result) { assert.equal(result, undefined); done(); }); }); QUnit.test('String', function(assert) { assert.expect(3); const done = assert.async(3); client.testString('', function(result) { assert.equal(result, ''); done(); }); client.testString(stringTest, function(result) { assert.equal(result, stringTest); done(); }); 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: !@#$%&()(&%$#{}{}<><><'; client.testString(specialCharacters, function(result) { assert.equal(result, specialCharacters); done(); }); }); QUnit.test('Double', function(assert) { assert.expect(4); const done = assert.async(4); client.testDouble(0, function(result) { assert.equal(result, 0); done(); }); client.testDouble(-1, function(result) { assert.equal(result, -1); done(); }); client.testDouble(3.14, function(result) { assert.equal(result, 3.14); done(); }); client.testDouble(Math.pow(2, 60), function(result) { assert.equal(result, Math.pow(2, 60)); done(); }); }); // TODO: add testBinary() QUnit.test('Byte', function(assert) { assert.expect(2); const done = assert.async(2); client.testByte(0, function(result) { assert.equal(result, 0); done(); }); client.testByte(0x01, function(result) { assert.equal(result, 0x01); done(); }); }); QUnit.test('I32', function(assert) { assert.expect(3); const done = assert.async(3); client.testI32(0, function(result) { assert.equal(result, 0); done(); }); client.testI32(Math.pow(2, 30), function(result) { assert.equal(result, Math.pow(2, 30)); done(); }); client.testI32(-Math.pow(2, 30), function(result) { assert.equal(result, -Math.pow(2, 30)); done(); }); }); QUnit.test('I64', function(assert) { assert.expect(3); const done = assert.async(3); client.testI64(0, function(result) { assert.equal(result, 0); done(); }); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately client.testI64(Math.pow(2, 52), function(result) { assert.equal(result, Math.pow(2, 52)); done(); }); client.testI64(-Math.pow(2, 52), function(result) { assert.equal(result, -Math.pow(2, 52)); done(); }); }); QUnit.module('Structured Types'); QUnit.test('Struct', function(assert) { assert.expect(5); const done = assert.async(); const structTestInput = new ThriftTest.Xtruct(); structTestInput.string_thing = 'worked'; structTestInput.byte_thing = 0x01; structTestInput.i32_thing = Math.pow(2, 30); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately structTestInput.i64_thing = Math.pow(2, 52); client.testStruct(structTestInput, function(result) { assert.equal(result.string_thing, structTestInput.string_thing); assert.equal(result.byte_thing, structTestInput.byte_thing); assert.equal(result.i32_thing, structTestInput.i32_thing); assert.equal(result.i64_thing, structTestInput.i64_thing); assert.equal(JSON.stringify(result), JSON.stringify(structTestInput)); done(); }); }); QUnit.test('Nest', function(assert) { assert.expect(7); const done = assert.async(); const xtrTestInput = new ThriftTest.Xtruct(); xtrTestInput.string_thing = 'worked'; xtrTestInput.byte_thing = 0x01; xtrTestInput.i32_thing = Math.pow(2, 30); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately xtrTestInput.i64_thing = Math.pow(2, 52); const nestTestInput = new ThriftTest.Xtruct2(); nestTestInput.byte_thing = 0x02; nestTestInput.struct_thing = xtrTestInput; nestTestInput.i32_thing = Math.pow(2, 15); client.testNest(nestTestInput, function(result) { assert.equal(result.byte_thing, nestTestInput.byte_thing); assert.equal(result.struct_thing.string_thing, nestTestInput.struct_thing.string_thing); assert.equal(result.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing); assert.equal(result.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing); assert.equal(result.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing); assert.equal(result.i32_thing, nestTestInput.i32_thing); assert.equal(JSON.stringify(result), JSON.stringify(nestTestInput)); done(); }); }); QUnit.test('Map', function(assert) { assert.expect(3); const done = assert.async(); const mapTestInput = {7: 77, 8: 88, 9: 99}; client.testMap(mapTestInput, function(result) { for (let key in result) { assert.equal(result[key], mapTestInput[key]); } done(); }); }); QUnit.test('StringMap', function(assert) { assert.expect(6); const done = assert.async(); const mapTestInput = { 'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key', 'longValue': stringTest, stringTest: 'long key' }; client.testStringMap(mapTestInput, function(result) { for (let key in result) { assert.equal(result[key], mapTestInput[key]); } done(); }); }); QUnit.test('Set', function(assert) { assert.expect(1); const done = assert.async(); const setTestInput = [1, 2, 3]; client.testSet(setTestInput, function(result) { assert.ok(result, setTestInput); done(); }); }); QUnit.test('List', function(assert) { assert.expect(1); const done = assert.async(); const listTestInput = [1, 2, 3]; client.testList(listTestInput, function(result) { assert.ok(result, listTestInput); done(); }); }); QUnit.test('Enum', function(assert) { assert.expect(1); const done = assert.async(); client.testEnum(ThriftTest.Numberz.ONE, function(result) { assert.equal(result, ThriftTest.Numberz.ONE); done(); }); }); QUnit.test('TypeDef', function(assert) { assert.expect(1); const done = assert.async(); client.testTypedef(69, function(result) { assert.equal(result, 69); done(); }); }); QUnit.module('deeper!'); QUnit.test('MapMap', function(assert) { assert.expect(16); const done = assert.async(); const mapMapTestExpectedResult = { '4': {'1': 1, '2': 2, '3': 3, '4': 4}, '-4': {'-4': -4, '-3': -3, '-2': -2, '-1': -1} }; client.testMapMap(1, function(result) { for (let key in result) { for (let key2 in result[key]) { assert.equal(result[key][key2], mapMapTestExpectedResult[key][key2]); } } checkRecursively(assert, result, mapMapTestExpectedResult); done(); }); }); QUnit.module('Exception'); QUnit.test('Xception', function(assert) { assert.expect(2); const done = assert.async(); client.testException('Xception', function(e) { assert.equal(e.errorCode, 1001); assert.equal(e.message, 'Xception'); done(); }); }); QUnit.test('no Exception', function(assert) { assert.expect(1); const done = assert.async(); client.testException('no Exception', function(e) { assert.ok(!e); done(); }); }); QUnit.module('Insanity'); QUnit.test('testInsanity', function(assert) { assert.expect(24); const done = assert.async(); const insanity = { '1': { '2': { 'userMap': { '5': 5, '8': 8 }, 'xtructs': [{ 'string_thing': 'Goodbye4', 'byte_thing': 4, 'i32_thing': 4, 'i64_thing': 4 }, { 'string_thing': 'Hello2', 'byte_thing': 2, 'i32_thing': 2, 'i64_thing': 2 } ] }, '3': { 'userMap': { '5': 5, '8': 8 }, 'xtructs': [{ 'string_thing': 'Goodbye4', 'byte_thing': 4, 'i32_thing': 4, 'i64_thing': 4 }, { 'string_thing': 'Hello2', 'byte_thing': 2, 'i32_thing': 2, 'i64_thing': 2 } ] } }, '2': { '6': { 'userMap': null, 'xtructs': null } } }; client.testInsanity(new ThriftTest.Insanity(), function(res) { assert.ok(res, JSON.stringify(res)); assert.ok(insanity, JSON.stringify(insanity)); checkRecursively(assert, res, insanity); done(); }); }); QUnit.module('Oneway'); QUnit.test('testOneway', function(assert) { assert.expect(1); const done = assert.async(); client.testOneway(1, function(result) { assert.equal(result, undefined); done(); }); }); thrift-0.23.0/lib/js/test/Makefile.in0000644000175000017500000004276515170007167017604 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/js/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/js/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/js/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-am check-local clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile export CLASSPATH # Make sure this doesn't fail if ant is not configured. 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 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/js/test/test-es6.js0000664000175000017500000003133515165535636017553 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* jshint -W100 */ /* * Fully Async JavaScript test suite for ThriftTest.thrift. * These tests are designed to exercise the WebSocket transport * (which is exclusively async). * * To compile client code for this test use: * $ thrift -gen js:es6 ThriftTest.thrift */ // all Languages in UTF-8 const 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(assert, map1, map2) { if (typeof map1 !== 'function' && typeof map2 !== 'function') { if (!map1 || typeof map1 !== 'object') { assert.equal(map1, map2); } else { for (var key in map1) { checkRecursively(assert, map1[key], map2[key]); } } } } QUnit.module('Base Types'); QUnit.test('Void', function( assert ) { assert.expect(1); const done = assert.async(); client.testVoid().then(function(result) { assert.equal(result, undefined); done(); }); }); QUnit.test('String', function( assert ) { assert.expect(3); const done = assert.async(3); client.testString('').then(function(result) { assert.equal(result, ''); done(); }); client.testString(stringTest).then(function(result) { assert.equal(result, stringTest); done(); }); 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: !@#$%&()(&%$#{}{}<><><'; client.testString(specialCharacters).then(function(result) { assert.equal(result, specialCharacters); done(); }); }); QUnit.test('Double', function( assert ) { assert.expect(4); const done = assert.async(4); client.testDouble(0).then(function(result) { assert.equal(result, 0); done(); }); client.testDouble(-1).then(function(result) { assert.equal(result, -1); done(); }); client.testDouble(3.14).then(function(result) { assert.equal(result, 3.14); done(); }); client.testDouble(Math.pow(2, 60)).then(function(result) { assert.equal(result, Math.pow(2, 60)); done(); }); }); // TODO: add testBinary() QUnit.test('Byte', function( assert ) { assert.expect(2); const done = assert.async(2); client.testByte(0).then(function(result) { assert.equal(result, 0); done(); }); client.testByte(0x01).then(function(result) { assert.equal(result, 0x01); done(); }); }); QUnit.test('I32', function( assert ) { assert.expect(3); const done = assert.async(3); client.testI32(0).then(function(result) { assert.equal(result, 0); done(); }); client.testI32(Math.pow(2, 30)).then(function(result) { assert.equal(result, Math.pow(2, 30)); done(); }); client.testI32(-Math.pow(2, 30)).then(function(result) { assert.equal(result, -Math.pow(2, 30)); done(); }); }); QUnit.test('I64', function( assert ) { assert.expect(3); const done = assert.async(3); client.testI64(0).then(function(result) { assert.equal(result, 0); done(); }); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately client.testI64(Math.pow(2, 52)).then(function(result) { assert.equal(result, Math.pow(2, 52)); done(); }); client.testI64(-Math.pow(2, 52)).then(function(result) { assert.equal(result, -Math.pow(2, 52)); done(); }); }); QUnit.module('Structured Types'); QUnit.test('Struct', function( assert ) { assert.expect(5); const done = assert.async(); var structTestInput = new ThriftTest.Xtruct(); structTestInput.string_thing = 'worked'; structTestInput.byte_thing = 0x01; structTestInput.i32_thing = Math.pow(2, 30); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately structTestInput.i64_thing = Math.pow(2, 52); client.testStruct(structTestInput).then(function(result) { assert.equal(result.string_thing, structTestInput.string_thing); assert.equal(result.byte_thing, structTestInput.byte_thing); assert.equal(result.i32_thing, structTestInput.i32_thing); assert.equal(result.i64_thing, structTestInput.i64_thing); assert.equal(JSON.stringify(result), JSON.stringify(structTestInput)); done(); }); }); QUnit.test('Nest', function( assert ) { assert.expect(7); const done = assert.async(); var xtrTestInput = new ThriftTest.Xtruct(); xtrTestInput.string_thing = 'worked'; xtrTestInput.byte_thing = 0x01; xtrTestInput.i32_thing = Math.pow(2, 30); //This is usually 2^60 but JS cannot represent anything over 2^52 accurately xtrTestInput.i64_thing = Math.pow(2, 52); var nestTestInput = new ThriftTest.Xtruct2(); nestTestInput.byte_thing = 0x02; nestTestInput.struct_thing = xtrTestInput; nestTestInput.i32_thing = Math.pow(2, 15); client.testNest(nestTestInput).then(function(result) { assert.equal(result.byte_thing, nestTestInput.byte_thing); assert.equal(result.struct_thing.string_thing, nestTestInput.struct_thing.string_thing); assert.equal(result.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing); assert.equal(result.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing); assert.equal(result.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing); assert.equal(result.i32_thing, nestTestInput.i32_thing); assert.equal(JSON.stringify(result), JSON.stringify(nestTestInput)); done(); }); }); QUnit.test('Map', function( assert ) { assert.expect(3); const done = assert.async(); var mapTestInput = {7: 77, 8: 88, 9: 99}; client.testMap(mapTestInput).then(function(result) { for (var key in result) { assert.equal(result[key], mapTestInput[key]); } done(); }); }); QUnit.test('StringMap', function( assert ) { assert.expect(6); const done = assert.async(); var mapTestInput = { 'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key', 'longValue': stringTest, stringTest: 'long key' }; client.testStringMap(mapTestInput).then(function(result) { for (var key in result) { assert.equal(result[key], mapTestInput[key]); } done(); }); }); QUnit.test('Set', function( assert ) { assert.expect(1); const done = assert.async(); var setTestInput = [1, 2, 3]; client.testSet(setTestInput).then(function(result) { assert.ok(result, setTestInput); done(); }); }); QUnit.test('List', function( assert ) { assert.expect(1); const done = assert.async(); var listTestInput = [1, 2, 3]; client.testList(listTestInput).then(function(result) { assert.ok(result, listTestInput); done(); }); }); QUnit.test('Enum', function( assert ) { assert.expect(1); const done = assert.async(); client.testEnum(ThriftTest.Numberz.ONE).then(function(result) { assert.equal(result, ThriftTest.Numberz.ONE); done(); }); }); QUnit.test('TypeDef', function( assert ) { assert.expect(1); const done = assert.async(); client.testTypedef(69).then(function(result) { assert.equal(result, 69); done(); }); }); QUnit.module('deeper!'); QUnit.test('MapMap', function( assert ) { assert.expect(16); const done = assert.async(); var mapMapTestExpectedResult = { '4': {'1': 1, '2': 2, '3': 3, '4': 4}, '-4': {'-4': -4, '-3': -3, '-2': -2, '-1': -1} }; client.testMapMap(1).then(function(result) { for (var key in result) { for (var key2 in result[key]) { assert.equal(result[key][key2], mapMapTestExpectedResult[key][key2]); } } checkRecursively(assert, result, mapMapTestExpectedResult); done(); }); }); QUnit.module('Exception'); QUnit.test('Xception', function( assert ) { assert.expect(2); const done = assert.async(); client.testException('Xception').then(function(res) { assert.ok(false); }).catch(function(e) { console.log(`Exception exception e`); console.log(e); console.log(JSON.stringify(e, null, 2)); assert.equal(e.errorCode, 1001); assert.equal(e.message, 'Xception'); done(); }); }); QUnit.test('no Exception', function( assert ) { assert.expect(1); const done = assert.async(); client.testException('no Exception').then(function(e) { assert.ok(!e); done(); }); }); QUnit.module('Insanity'); QUnit.test('testInsanity', function( assert ) { assert.expect(24); const done = assert.async(); var insanity = { '1': { '2': { 'userMap': { '5': 5, '8': 8 }, 'xtructs': [{ 'string_thing': 'Goodbye4', 'byte_thing': 4, 'i32_thing': 4, 'i64_thing': 4 }, { 'string_thing': 'Hello2', 'byte_thing': 2, 'i32_thing': 2, 'i64_thing': 2 } ] }, '3': { 'userMap': { '5': 5, '8': 8 }, 'xtructs': [{ 'string_thing': 'Goodbye4', 'byte_thing': 4, 'i32_thing': 4, 'i64_thing': 4 }, { 'string_thing': 'Hello2', 'byte_thing': 2, 'i32_thing': 2, 'i64_thing': 2 } ] } }, '2': { '6': { 'userMap': null, 'xtructs': null } } }; client.testInsanity(new ThriftTest.Insanity()).then(function(res) { assert.ok(res, JSON.stringify(res)); assert.ok(insanity, JSON.stringify(insanity)); checkRecursively(assert, res, insanity); done(); }); }); QUnit.module('Oneway'); QUnit.test('testOneway', function( assert ) { assert.expect(1); const done = assert.async(); client.testOneway(1).then(function(result) { assert.equal(result, undefined); done(); }); }); thrift-0.23.0/lib/js/test/Makefile.am0000664000175000017500000000202515165535636017571 0ustar00buildbuild00000000000000# # 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. # export CLASSPATH # Make sure this doesn't fail if ant is not configured. 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 thrift-0.23.0/lib/js/test/test_handler.js0000664000175000017500000001332215165535636020551 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * 'License'); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ //This is the server side Node test handler for the standard // Apache Thrift test service. const es6Mode = process.argv.includes('--es6'); const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs'; const ttypes = require(`./${genFolder}/ThriftTest_types`); const TException = require('../../nodejs/lib/thrift').TException; const Int64 = require('node-int64'); exports.ThriftTestHandler = { testVoid: function(result) { console.log('testVoid()'); result(null); }, testString: function(thing, result) { console.log('testString(\'' + thing + '\')'); result(null, thing); }, testByte: function(thing, result) { console.log('testByte(' + thing + ')'); result(null, thing); }, testI32: function(thing, result) { console.log('testI32(' + thing + ')'); result(null, thing); }, testI64: function(thing, result) { console.log('testI64(' + thing + ')'); result(null, thing); }, testDouble: function(thing, result) { console.log('testDouble(' + thing + ')'); result(null, thing); }, testBinary: function(thing, result) { console.log('testBinary(\'' + thing + '\')'); result(null, thing); }, testStruct: function(thing, result) { console.log('testStruct('); console.log(thing); console.log(')'); result(null, thing); }, testNest: function(nest, result) { console.log('testNest('); console.log(nest); console.log(')'); result(null, nest); }, testMap: function(thing, result) { console.log('testMap('); console.log(thing); console.log(')'); result(null, thing); }, testStringMap: function(thing, result) { console.log('testStringMap('); console.log(thing); console.log(')'); result(null, thing); }, testSet: function(thing, result) { console.log('testSet('); console.log(thing); console.log(')'); result(null, thing); }, testList: function(thing, result) { console.log('testList('); console.log(thing); console.log(')'); result(null, thing); }, testEnum: function(thing, result) { console.log('testEnum(' + thing + ')'); result(null, thing); }, testTypedef: function(thing, result) { console.log('testTypedef(' + thing + ')'); result(null, thing); }, testMapMap: function(hello, result) { console.log('testMapMap(' + hello + ')'); const mapmap = []; const pos = []; const neg = []; for (let i = 1; i < 5; i++) { pos[i] = i; neg[-i] = -i; } mapmap[4] = pos; mapmap[-4] = neg; result(null, mapmap); }, testInsanity: function(argument, result) { console.log('testInsanity('); console.log(argument); console.log(')'); const hello = new ttypes.Xtruct(); hello.string_thing = 'Hello2'; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = new Int64(2); const goodbye = new ttypes.Xtruct(); goodbye.string_thing = 'Goodbye4'; goodbye.byte_thing = 4; goodbye.i32_thing = 4; goodbye.i64_thing = new Int64(4); const crazy = new ttypes.Insanity(); crazy.userMap = []; crazy.userMap[ttypes.Numberz.EIGHT] = 8; crazy.userMap[ttypes.Numberz.FIVE] = 5; crazy.xtructs = [goodbye, hello]; const first_map = []; const second_map = []; first_map[ttypes.Numberz.TWO] = crazy; first_map[ttypes.Numberz.THREE] = crazy; const looney = new ttypes.Insanity(); second_map[ttypes.Numberz.SIX] = looney; const insane = []; insane[1] = first_map; insane[2] = second_map; console.log('insane result:'); console.log(insane); result(null, insane); }, testMulti: function(arg0, arg1, arg2, arg3, arg4, arg5, result) { console.log('testMulti()'); const hello = new ttypes.Xtruct(); hello.string_thing = 'Hello2'; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = arg2; result(null, hello); }, testException: function(arg, result) { console.log('testException(' + arg + ')'); if (arg === 'Xception') { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = arg; result(x); } else if (arg === 'TException') { result(new TException(arg)); } else { result(null); } }, testMultiException: function(arg0, arg1, result) { console.log('testMultiException(' + arg0 + ', ' + arg1 + ')'); if (arg0 === ('Xception')) { const x = new ttypes.Xception(); x.errorCode = 1001; x.message = 'This is an Xception'; result(x); } else if (arg0 === ('Xception2')) { const x2 = new ttypes.Xception2(); x2.errorCode = 2002; x2.struct_thing = new ttypes.Xtruct(); x2.struct_thing.string_thing = 'This is an Xception2'; result(x2); } const res = new ttypes.Xtruct(); res.string_thing = arg1; result(null, res); }, testOneway: function(sleepFor, result) { console.log('testOneway(' + sleepFor + ') => JavaScript (like Rust) never sleeps!'); } }; //ThriftTestSvcHandler thrift-0.23.0/lib/js/test/test-double-rendering.html0000664000175000017500000000502415165535636022627 0ustar00buildbuild00000000000000+ Rendering Double Constants in JS: Unit Test

Rendering Double Constants in JS: Unit Test

thrift-0.23.0/lib/js/coding_standards.md0000664000175000017500000000010315165535636020401 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/js/Gruntfile.js0000664000175000017500000002363015167543515017055 0ustar00buildbuild00000000000000/* * 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. */ //To build dist/thrift.js, dist/thrift.min.js and doc/* //run grunt at the command line in this directory. //Prerequisites: // Node Setup - nodejs.org // Grunt Setup - npm install //reads the ./package.json and installs project dependencies // Run grunt - npx grunt // uses project-local installed version of grunt (from package.json) module.exports = function (grunt) { "use strict"; grunt.initConfig({ pkg: grunt.file.readJSON("package.json"), concat: { options: { separator: ";", }, dist: { src: ["src/**/*.js"], dest: "dist/<%= pkg.name %>.js", }, }, jsdoc: { dist: { src: ["src/*.js", "./README.md"], options: { destination: "doc", }, }, }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n', }, dist: { files: { "dist/<%= pkg.name %>.min.js": ["<%= concat.dist.dest %>"], }, }, }, shell: { InstallThriftJS: { command: "cp src/thrift.js test/build/js/thrift.js", }, InstallThriftNodeJSDep: { command: "cd ../.. && npm install", }, InstallTestLibs: { command: "cd test && ant download_jslibs", }, ThriftGen: { command: [ '"../../compiler/cpp/thrift" -gen js --out test/gen-js ../../test/v0.16/ThriftTest.thrift', '"../../compiler/cpp/thrift" -gen js --out test/gen-js ../../test/JsDeepConstructorTest.thrift', '"../../compiler/cpp/thrift" -gen js:jquery --out test/gen-js-jquery ../../test/v0.16/ThriftTest.thrift', '"../../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(" && "), }, ThriftGenJQ: { 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", }, ThriftBrowserifyNodeInt64: { command: [ "./node_modules/browserify/bin/cmd.js ./node_modules/node-int64/Int64.js -s Int64 -o test/build/js/lib/Int64.js", "./node_modules/browserify/bin/cmd.js ../nodejs/lib/thrift/int64_util.js -s Int64Util -o test/build/js/lib/Int64Util.js", "./node_modules/browserify/bin/cmd.js ./node_modules/json-int64/index.js -s JSONInt64 -o test/build/js/lib/JSONInt64.js", ].join(" && "), }, ThriftGenInt64: { command: "../../compiler/cpp/thrift -gen js -o test ../../test/Int64Test.thrift", }, ThriftGenDoubleConstants: { command: "../../compiler/cpp/thrift -gen js -o test ../../test/DoubleConstantsTest.thrift", }, ThriftTestServer: { options: { async: true, execOptions: { cwd: "./test", env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, }, }, command: "node server_http.js", }, ThriftTestServerES6: { options: { async: true, execOptions: { cwd: "./test", env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, }, }, command: "node server_http.js --es6", }, ThriftTestServer_TLS: { options: { async: true, execOptions: { cwd: "./test", env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, }, }, command: "node server_https.js", }, ThriftTestServerES6_TLS: { options: { async: true, execOptions: { cwd: "./test", env: { NODE_PATH: "../../nodejs/lib:../../../node_modules" }, }, }, command: "node server_https.js --es6", }, }, qunit: { ThriftJS: { options: { urls: ["http://localhost:8089/test-nojq.html"], puppeteer: { headless: true, args: ["--no-sandbox"], }, }, }, ThriftJSJQ: { options: { urls: ["http://localhost:8089/test.html"], puppeteer: { headless: true, args: ["--no-sandbox"], }, }, }, ThriftJS_DoubleRendering: { options: { urls: ["http://localhost:8089/test-double-rendering.html"], puppeteer: { headless: true, args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, }, }, ThriftJS_Int64: { options: { urls: ["http://localhost:8089/test-int64.html"], puppeteer: { headless: true, args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, }, }, ThriftWS: { options: { urls: ["http://localhost:8089/testws.html"], puppeteer: { headless: true, args: ["--no-sandbox"], }, }, }, ThriftJS_TLS: { options: { urls: ["https://localhost:8091/test-nojq.html"], puppeteer: { headless: true, args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, }, }, ThriftJSJQ_TLS: { options: { urls: ["https://localhost:8091/test.html"], puppeteer: { headless: true, args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, }, }, ThriftWS_TLS: { options: { urls: ["https://localhost:8091/testws.html"], puppeteer: { headless: true, args: ["--no-sandbox"], ignoreHTTPSErrors: true, }, }, }, ThriftDeepConstructor: { options: { urls: ["http://localhost:8089/test-deep-constructor.html"], puppeteer: { headless: true, args: ["--no-sandbox"], }, }, }, ThriftWSES6: { options: { urls: ["http://localhost:8088/test-es6.html"], puppeteer: { headless: true, args: ["--no-sandbox"], }, }, }, }, jshint: { // The main Thrift library file. not es6 yet :( lib: { src: ["src/**/*.js"], }, // The test files use es6 test: { src: ["Gruntfile.js", "test/*.js"], options: { esversion: 6, }, }, gen_js_code: { src: ["test/gen-js/*.js", "test/gen-js-jquery/*.js"], }, gen_es6_code: { src: ["test/gen-js-es6/*.js"], options: { esversion: 6, }, }, gen_node_code: { src: ["test/gen-nodejs/*.js"], options: { node: true, }, }, gen_node_es6_code: { 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.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("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("default", ["test", "concat", "uglify", "jsdoc"]); }; thrift-0.23.0/lib/js/package.json0000664000175000017500000000157115170007142017027 0ustar00buildbuild00000000000000{ "name": "thrift", "version": "0.23.0", "description": "Thrift is a software framework for scalable cross-language services development.", "main": "./src/thrift", "author": { "name": "Apache Thrift Developers", "email": "dev@thrift.apache.org" }, "bugs": "https://issues.apache.org/jira/projects/THRIFT/summary", "homepage": "http://thrift.apache.org", "repository": "https://github.com/apache/thrift", "license": "Apache-2.0", "devDependencies": { "browserify": "~16.5", "grunt": "^1.4.1", "grunt-cli": "^1.4.3", "grunt-contrib-concat": "~1.0", "grunt-contrib-jshint": "~3.2", "grunt-contrib-qunit": "~3.1", "grunt-contrib-uglify": "~4.0", "grunt-jsdoc": "~2.4", "grunt-shell-spawn": "~0.4", "jsdoc": "^3.6.7", "jslint": "~0.12.1", "json-int64": "~1.0.2", "node-int64": "~0.4.0", "nopt": "~4.0" } } thrift-0.23.0/lib/js/CMakeLists.txt0000664000175000017500000000431215165535636017317 0ustar00buildbuild00000000000000# # 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. # if(NOT JAVASCRIPT_INSTALL_DIR) if(IS_ABSOLUTE "${LIB_INSTALL_DIR}") set(JAVASCRIPT_INSTALL_DIR "${LIB_INSTALL_DIR}/js") else() set(JAVASCRIPT_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/js") endif() endif() if(IS_ABSOLUTE "${DOC_INSTALL_DIR}") set(JAVASCRIPT_DOC_INSTALL_DIR "${DOC_INSTALL_DIR}/js") else() set(JAVASCRIPT_DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${DOC_INSTALL_DIR}/js") endif() add_custom_target(ThriftJavascriptPreDeps ALL COMMENT "Installing Javascript dependencies using npm" DEPENDS copy-thrift-compiler COMMAND npm install WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) file(GLOB_RECURSE THRIFTJAVASCRIPT_SOURCES LIST_DIRECTORIES false "${CMAKE_CURRENT_SOURCE_DIR}/*") list(FILTER THRIFTJAVASCRIPT_SOURCES EXCLUDE REGEX ".*/(dist|doc)/.*") add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/dist/thrift.js" COMMENT "Building Javascript library using npx Grunt wrapper" DEPENDS ThriftJavascriptPreDeps ${THRIFTJAVASCRIPT_SOURCES} COMMAND npx grunt WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) add_custom_target(ThriftJavascript ALL DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/dist/thrift.js") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/dist/" DESTINATION "${JAVASCRIPT_INSTALL_DIR}" FILES_MATCHING PATTERN "thrift*.js") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/doc/" DESTINATION "${JAVASCRIPT_DOC_INSTALL_DIR}") thrift-0.23.0/lib/js/package-lock.json0000664000175000017500000046710015170007142017761 0ustar00buildbuild00000000000000{ "name": "thrift", "version": "0.23.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "thrift", "version": "0.23.0", "license": "Apache-2.0", "devDependencies": { "browserify": "~16.5", "grunt": "^1.4.1", "grunt-cli": "^1.4.3", "grunt-contrib-concat": "~1.0", "grunt-contrib-jshint": "~3.2", "grunt-contrib-qunit": "~3.1", "grunt-contrib-uglify": "~4.0", "grunt-jsdoc": "~2.4", "grunt-shell-spawn": "~0.4", "jsdoc": "^3.6.7", "jslint": "~0.12.1", "json-int64": "~1.0.2", "node-int64": "~0.4.0", "nopt": "~4.0" } }, "node_modules/@babel/parser": { "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@types/linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", "dev": true }, "node_modules/@types/markdown-it": { "version": "12.2.3", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", "dev": true, "dependencies": { "@types/linkify-it": "*", "@types/mdurl": "*" } }, "node_modules/@types/mdurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", "dev": true }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-node": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", "dev": true, "dependencies": { "acorn": "^7.0.0", "acorn-walk": "^7.0.0", "xtend": "^4.0.2" } }, "node_modules/acorn-walk": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/argparse/node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "node_modules/array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "safer-buffer": "^2.1.0" } }, "node_modules/assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "dev": true, "dependencies": { "object-assign": "^4.1.1", "util": "0.10.3" } }, "node_modules/assert/node_modules/inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", "dev": true }, "node_modules/assert/node_modules/util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "dependencies": { "inherits": "2.0.1" } }, "node_modules/async": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, "node_modules/async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "dev": true }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "node_modules/base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", "dev": true }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, "node_modules/bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { "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.1.1" }, "engines": { "node": ">=8" } }, "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, "node_modules/browser-pack": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", "dev": true, "dependencies": { "combine-source-map": "~0.8.0", "defined": "^1.0.0", "JSONStream": "^1.0.3", "safe-buffer": "^5.1.1", "through2": "^2.0.0", "umd": "^3.0.0" }, "bin": { "browser-pack": "bin/cmd.js" } }, "node_modules/browser-resolve": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", "dev": true, "dependencies": { "resolve": "1.1.7" } }, "node_modules/browserify": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.0.tgz", "integrity": "sha512-6bfI3cl76YLAnCZ75AGu/XPOsqUhRyc0F/olGIJeCxtfxF2HvPKEcmjU9M8oAPxl4uBY1U7Nry33Q6koV3f2iw==", "dev": true, "dependencies": { "assert": "^1.4.0", "browser-pack": "^6.0.1", "browser-resolve": "^1.11.0", "browserify-zlib": "~0.2.0", "buffer": "^5.0.2", "cached-path-relative": "^1.0.0", "concat-stream": "^1.6.0", "console-browserify": "^1.1.0", "constants-browserify": "~1.0.0", "crypto-browserify": "^3.0.0", "defined": "^1.0.0", "deps-sort": "^2.0.0", "domain-browser": "^1.2.0", "duplexer2": "~0.1.2", "events": "^2.0.0", "glob": "^7.1.0", "has": "^1.0.0", "htmlescape": "^1.1.0", "https-browserify": "^1.0.0", "inherits": "~2.0.1", "insert-module-globals": "^7.0.0", "JSONStream": "^1.0.3", "labeled-stream-splicer": "^2.0.0", "mkdirp": "^0.5.0", "module-deps": "^6.0.0", "os-browserify": "~0.3.0", "parents": "^1.0.1", "path-browserify": "~0.0.0", "process": "~0.11.0", "punycode": "^1.3.2", "querystring-es3": "~0.2.0", "read-only-stream": "^2.0.0", "readable-stream": "^2.0.2", "resolve": "^1.1.4", "shasum": "^1.0.0", "shell-quote": "^1.6.1", "stream-browserify": "^2.0.0", "stream-http": "^3.0.0", "string_decoder": "^1.1.1", "subarg": "^1.0.0", "syntax-error": "^1.1.1", "through2": "^2.0.0", "timers-browserify": "^1.0.1", "tty-browserify": "0.0.1", "url": "~0.11.0", "util": "~0.10.1", "vm-browserify": "^1.0.0", "xtend": "^4.0.0" }, "bin": { "browserify": "bin/cmd.js" }, "engines": { "node": ">= 0.8" } }, "node_modules/browserify-aes": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.3", "inherits": "^2.0.1", "safe-buffer": "^5.0.1" } }, "node_modules/browserify-cipher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "dependencies": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", "evp_bytestokey": "^1.0.0" } }, "node_modules/browserify-des": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, "dependencies": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, "node_modules/browserify-rsa": { "version": "4.1.0", "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "dependencies": { "bn.js": "^5.0.0", "randombytes": "^2.0.1" } }, "node_modules/browserify-rsa/node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", "dev": true }, "node_modules/browserify-sign": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", "dev": true, "dependencies": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "elliptic": "^6.5.4", "inherits": "^2.0.4", "parse-asn1": "^5.1.6", "readable-stream": "^3.6.2", "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 4" } }, "node_modules/browserify-sign/node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", "dev": true }, "node_modules/browserify-sign/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/browserify-sign/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/browserify-sign/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/browserify-sign/node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "dependencies": { "pako": "~1.0.5" } }, "node_modules/browserify/node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/browserify/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/browserify/node_modules/readable-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/browserify/node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/browserify/node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true }, "node_modules/buffer": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", "dev": true, "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" } }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true, "engines": { "node": "*" } }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "node_modules/buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", "dev": true }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, "node_modules/builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, "node_modules/cached-path-relative": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", "dev": true }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/call-bound": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, "dependencies": { "lodash": "^4.17.15" }, "engines": { "node": ">= 10" } }, "node_modules/chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/cipher-base": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/cipher-base/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/cipher-base/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/cli": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", "integrity": "sha512-41U72MB56TfUMGndAKK8vJ78eooOD4Z5NOL4xEfjc0c23s+6EYKXlXsmACBVclLP1yOfWCgEganVzddVrSNoTg==", "dev": true, "dependencies": { "exit": "0.1.2", "glob": "^7.1.1" }, "engines": { "node": ">=0.2.5" } }, "node_modules/cli/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "node_modules/colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true, "engines": { "node": ">=0.1.90" } }, "node_modules/combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "dev": true, "dependencies": { "convert-source-map": "~1.1.0", "inline-source-map": "~0.6.0", "lodash.memoize": "~3.0.3", "source-map": "~0.5.3" } }, "node_modules/commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "node_modules/concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "engines": [ "node >= 0.8" ], "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "node_modules/concat-stream/node_modules/readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/concat-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "dependencies": { "date-now": "^0.1.4" } }, "node_modules/constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, "node_modules/convert-source-map": { "version": "1.1.3", "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", "dev": true }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "node_modules/create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "dependencies": { "bn.js": "^4.1.0", "elliptic": "^6.0.0" } }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", "md5.js": "^1.3.4", "ripemd160": "^2.0.1", "sha.js": "^2.4.0" } }, "node_modules/create-hmac": { "version": "1.1.7", "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", "inherits": "^2.0.1", "ripemd160": "^2.0.0", "safe-buffer": "^5.0.1", "sha.js": "^2.4.8" } }, "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/cross-spawn/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/crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "dependencies": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", "create-ecdh": "^4.0.0", "create-hash": "^1.1.0", "create-hmac": "^1.1.0", "diffie-hellman": "^5.0.0", "inherits": "^2.0.1", "pbkdf2": "^3.0.3", "public-encrypt": "^4.0.0", "randombytes": "^2.0.0", "randomfill": "^1.0.3" }, "engines": { "node": "*" } }, "node_modules/dash-ast": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", "dev": true }, "node_modules/date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true, "engines": { "node": "*" } }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, "node_modules/deps-sort": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", "dev": true, "dependencies": { "JSONStream": "^1.0.3", "shasum-object": "^1.0.0", "subarg": "^1.0.0", "through2": "^2.0.0" }, "bin": { "deps-sort": "bin/cmd.js" } }, "node_modules/des.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", "dev": true, "dependencies": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" } }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", "dev": true, "dependencies": { "acorn-node": "^1.6.1", "defined": "^1.0.0", "minimist": "^1.1.1" }, "bin": { "detective": "bin/detective.js" }, "engines": { "node": ">=0.8.0" } }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "dependencies": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" } }, "node_modules/dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, "dependencies": { "domelementtype": "^2.0.1", "entities": "^2.0.0" } }, "node_modules/dom-serializer/node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } ] }, "node_modules/dom-serializer/node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true, "engines": { "node": ">=0.4", "npm": ">=1.2" } }, "node_modules/domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, "node_modules/domhandler": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", "dev": true, "dependencies": { "domelementtype": "1" } }, "node_modules/domutils": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", "dev": true, "dependencies": { "dom-serializer": "0", "domelementtype": "1" } }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "dependencies": { "readable-stream": "^2.0.2" } }, "node_modules/duplexer2/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/duplexer2/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/elliptic": { "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", "hash.js": "^1.0.0", "hmac-drbg": "^1.0.1", "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" } }, "node_modules/elliptic/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, "node_modules/elliptic/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/entities": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", "dev": true }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es6-promise": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", "dev": true }, "node_modules/es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "dependencies": { "es6-promise": "^4.0.3" } }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", "dev": true }, "node_modules/events": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", "dev": true, "engines": { "node": ">=0.4.x" } }, "node_modules/evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" } }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "dependencies": { "homedir-polyfill": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "node_modules/extract-zip": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", "dev": true, "dependencies": { "concat-stream": "^1.6.2", "debug": "^2.6.9", "mkdirp": "^0.5.4", "yauzl": "^2.10.0" }, "bin": { "extract-zip": "cli.js" } }, "node_modules/fast-safe-stringify": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", "dev": true }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "dependencies": { "pend": "~1.2.0" } }, "node_modules/figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5", "object-assign": "^4.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fill-range": { "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" }, "engines": { "node": ">=8" } }, "node_modules/findup-sync": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", "dev": true, "dependencies": { "glob": "~5.0.0" }, "engines": { "node": ">= 0.6.0" } }, "node_modules/findup-sync/node_modules/glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "dependencies": { "inflight": "^1.0.4", "inherits": "2", "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" } }, "node_modules/fined": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, "dependencies": { "expand-tilde": "^2.0.2", "is-plain-object": "^2.0.3", "object.defaults": "^1.1.0", "object.pick": "^1.2.0", "parse-filepath": "^1.0.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/flagged-respawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true, "engines": { "node": ">= 0.10" } }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/for-own": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "dependencies": { "for-in": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-assigned-identifiers": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", "dev": true }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/getobject": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/glob": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.2", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" } }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/global-prefix": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" }, "engines": { "node": ">=0.10.0" } }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, "node_modules/grunt": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "dev": true, "dependencies": { "dateformat": "~3.0.3", "eventemitter2": "~0.4.13", "exit": "~0.1.2", "findup-sync": "~0.3.0", "glob": "~7.1.6", "grunt-cli": "~1.4.3", "grunt-known-options": "~2.0.0", "grunt-legacy-log": "~3.0.0", "grunt-legacy-util": "~2.0.1", "iconv-lite": "~0.4.13", "js-yaml": "~3.14.0", "minimatch": "~3.0.4", "mkdirp": "~1.0.4", "nopt": "~3.0.6", "rimraf": "~3.0.2" }, "bin": { "grunt": "bin/grunt" }, "engines": { "node": ">=8" } }, "node_modules/grunt-cli": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", "dev": true, "dependencies": { "grunt-known-options": "~2.0.0", "interpret": "~1.1.0", "liftup": "~3.0.1", "nopt": "~4.0.1", "v8flags": "~3.2.0" }, "bin": { "grunt": "bin/grunt" }, "engines": { "node": ">=10" } }, "node_modules/grunt-contrib-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz", "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=", "dev": true, "dependencies": { "chalk": "^1.0.0", "source-map": "^0.5.3" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { "grunt": ">=0.4.0" } }, "node_modules/grunt-contrib-concat/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-contrib-concat/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-contrib-concat/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/grunt-contrib-jshint": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.2.0.tgz", "integrity": "sha512-pcXWCSZWfoMSvcV4BwH21TUtLtcX0Ms8IGuOPIcLeXK3fud9KclY7iqMKY94jFx8TxZzh028YYtpR+io8DiEaQ==", "dev": true, "dependencies": { "chalk": "~4.1.2", "hooker": "^0.2.3", "jshint": "~2.13.4" }, "engines": { "node": ">=10" } }, "node_modules/grunt-contrib-jshint/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/grunt-contrib-jshint/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/grunt-contrib-jshint/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/grunt-contrib-jshint/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/grunt-contrib-jshint/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/grunt-contrib-jshint/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": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/grunt-contrib-qunit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-3.1.0.tgz", "integrity": "sha512-mdk8UltH6mxCD63E0hTXMAts42DOi4z4bBBrY7qnuHiShflMF7IueSMYe0zWaZ2dO8mgujh57Zfny2EbigJhRg==", "dev": true, "dependencies": { "eventemitter2": "^5.0.1", "p-each-series": "^1.0.0", "puppeteer": "^1.11.0" }, "engines": { "node": ">=6" } }, "node_modules/grunt-contrib-qunit/node_modules/eventemitter2": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=", "dev": true }, "node_modules/grunt-contrib-uglify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-4.0.1.tgz", "integrity": "sha512-dwf8/+4uW1+7pH72WButOEnzErPGmtUvc8p08B0eQS/6ON0WdeQu0+WFeafaPTbbY1GqtS25lsHWaDeiTQNWPg==", "dev": true, "dependencies": { "chalk": "^2.4.1", "maxmin": "^2.1.0", "uglify-js": "^3.5.0", "uri-path": "^1.0.0" }, "engines": { "node": ">=6" } }, "node_modules/grunt-jsdoc": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.4.1.tgz", "integrity": "sha512-S0zxU0wDewRu7z+vijEItOWe/UttxWVmvz0qz2ZVcAYR2GpXjsiski2CAVN0b18t2qeVLdmxZkJaEWCOsKzcAw==", "dev": true, "dependencies": { "cross-spawn": "^7.0.1", "jsdoc": "^3.6.3" }, "bin": { "grunt-jsdoc": "bin/grunt-jsdoc" }, "engines": { "node": ">= 8.12.0" } }, "node_modules/grunt-known-options": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/grunt-legacy-log": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", "dev": true, "dependencies": { "colors": "~1.1.2", "grunt-legacy-log-utils": "~2.1.0", "hooker": "~0.2.3", "lodash": "~4.17.19" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/grunt-legacy-log-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", "dev": true, "dependencies": { "chalk": "~4.1.0", "lodash": "~4.17.19" }, "engines": { "node": ">=10" } }, "node_modules/grunt-legacy-log-utils/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/grunt-legacy-log-utils/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/grunt-legacy-log-utils/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/grunt-legacy-log-utils/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/grunt-legacy-log-utils/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/grunt-legacy-log-utils/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": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/grunt-legacy-util": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", "dev": true, "dependencies": { "async": "~3.2.0", "exit": "~0.1.2", "getobject": "~1.0.0", "hooker": "~0.2.3", "lodash": "~4.17.21", "underscore.string": "~3.3.5", "which": "~2.0.2" }, "engines": { "node": ">=10" } }, "node_modules/grunt-legacy-util/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/grunt-shell-spawn": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/grunt-shell-spawn/-/grunt-shell-spawn-0.4.0.tgz", "integrity": "sha512-lfYvEQjbO1Wv+1Fk3d3XlcEpuQjyXiErZMkiz/i/tDQeMHHGF1LziqA4ZcietBAo/bM2RHdEEUJfnNWt1VRMwQ==", "dev": true, "dependencies": { "grunt": ">=0.4.x" }, "bin": { "grunt-shell-spawn": "bin/grunt-shell-spawn" }, "engines": { "node": ">=4" } }, "node_modules/grunt/node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/grunt/node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/grunt/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" } }, "node_modules/grunt/node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/grunt/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gzip-size": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", "dev": true, "dependencies": { "duplexer": "^0.1.1" }, "engines": { "node": ">=0.12.0" } }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { "function-bind": "^1.1.1" }, "engines": { "node": ">= 0.4.0" } }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hash-base": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" }, "engines": { "node": ">=4" } }, "node_modules/hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" } }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.1" } }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "dependencies": { "parse-passwd": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/hooker": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", "dev": true, "engines": { "node": "*" } }, "node_modules/htmlescape": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", "dev": true, "engines": { "node": ">=0.10" } }, "node_modules/htmlparser2": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", "dev": true, "dependencies": { "domelementtype": "1", "domhandler": "2.3", "domutils": "1.5", "entities": "1.0", "readable-stream": "1.1" } }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, "node_modules/https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "dependencies": { "agent-base": "^4.3.0", "debug": "^3.1.0" }, "engines": { "node": ">= 4.5.0" } }, "node_modules/https-proxy-agent/node_modules/agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "dependencies": { "es6-promisify": "^5.0.0" }, "engines": { "node": ">= 4.0.0" } }, "node_modules/https-proxy-agent/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/https-proxy-agent/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/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", "dev": true }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "node_modules/inline-source-map": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "dev": true, "dependencies": { "source-map": "~0.5.3" } }, "node_modules/insert-module-globals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", "dev": true, "dependencies": { "acorn-node": "^1.5.2", "combine-source-map": "^0.8.0", "concat-stream": "^1.6.1", "is-buffer": "^1.1.0", "JSONStream": "^1.0.3", "path-is-absolute": "^1.0.1", "process": "~0.11.0", "through2": "^2.0.0", "undeclared-identifiers": "^1.1.2", "xtend": "^4.0.0" }, "bin": { "insert-module-globals": "bin/cmd.js" } }, "node_modules/interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, "node_modules/is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "dependencies": { "has": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, "engines": { "node": ">=0.10.0" } }, "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": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "dependencies": { "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "dependencies": { "is-unc-path": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-typed-array": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "dependencies": { "unc-path-regex": "^0.1.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/js-yaml": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/js2xmlparser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "dev": true, "dependencies": { "xmlcreate": "^2.0.4" } }, "node_modules/jsdoc": { "version": "3.6.11", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.11.tgz", "integrity": "sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==", "dev": true, "dependencies": { "@babel/parser": "^7.9.4", "@types/markdown-it": "^12.2.3", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", "markdown-it": "^12.3.2", "markdown-it-anchor": "^8.4.1", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", "underscore": "~1.13.2" }, "bin": { "jsdoc": "jsdoc.js" }, "engines": { "node": ">=12.0.0" } }, "node_modules/jsdoc/node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/jsdoc/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" } }, "node_modules/jshint": { "version": "2.13.5", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.5.tgz", "integrity": "sha512-dB2n1w3OaQ35PLcBGIWXlszjbPZwsgZoxsg6G8PtNf2cFMC1l0fObkYLUuXqTTdi6tKw4sAjfUseTdmDMHQRcg==", "dev": true, "dependencies": { "cli": "~1.0.0", "console-browserify": "1.1.x", "exit": "0.1.x", "htmlparser2": "3.8.x", "lodash": "~4.17.21", "minimatch": "~3.0.2", "strip-json-comments": "1.0.x" }, "bin": { "jshint": "bin/jshint" } }, "node_modules/jshint/node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/jshint/node_modules/strip-json-comments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", "integrity": "sha512-AOPG8EBc5wAikaG1/7uFCNFJwnKOuQwFTpYBdTW6OvWHeZBQBrAA/amefHGrEiOnCPcLFZK6FUPtWVKpQVIRgg==", "dev": true, "bin": { "strip-json-comments": "cli.js" }, "engines": { "node": ">=0.8.0" } }, "node_modules/jslint": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/jslint/-/jslint-0.12.1.tgz", "integrity": "sha512-q5iHswjOmJffbsGVq/1umGh4YBxb5pCArNHCZeHpkuVDDKM6IldqUn4hLehKSwQr7Bn07VXjD34Lx3nw+6j8eA==", "dev": true, "dependencies": { "exit": "~0.1.2", "glob": "~7.1.3", "nopt": "~4.0.1", "readable-stream": "~2.1.5" }, "bin": { "jslint": "bin/jslint.js" }, "engines": { "node": ">=0.8.0" } }, "node_modules/jslint/node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/jslint/node_modules/process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "node_modules/jslint/node_modules/readable-stream": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", "dev": true, "dependencies": { "buffer-shims": "^1.0.0", "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", "string_decoder": "~0.10.x", "util-deprecate": "~1.0.1" } }, "node_modules/json-int64": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-int64/-/json-int64-1.0.2.tgz", "integrity": "sha512-uGrIXtRehbksM17S2lJRLPljufK52KL2ewbJi0xgcRPONoRLXa4yAUIKAUxF69dbnqIoBu33fB28MAWSxupB8Q==", "dev": true, "dependencies": { "node-int64": "0.4.0" } }, "node_modules/json-stable-stringify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", "dev": true, "dependencies": { "jsonify": "~0.0.0" } }, "node_modules/jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true, "engines": { "node": "*" } }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true, "engines": [ "node >= 0.2.0" ] }, "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" }, "bin": { "JSONStream": "bin.js" }, "engines": { "node": "*" } }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, "dependencies": { "graceful-fs": "^4.1.9" } }, "node_modules/labeled-stream-splicer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", "dev": true, "dependencies": { "inherits": "^2.0.1", "stream-splicer": "^2.0.0" } }, "node_modules/liftup": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", "dev": true, "dependencies": { "extend": "^3.0.2", "findup-sync": "^4.0.0", "fined": "^1.2.0", "flagged-respawn": "^1.0.1", "is-plain-object": "^2.0.4", "object.map": "^1.0.1", "rechoir": "^0.7.0", "resolve": "^1.19.0" }, "engines": { "node": ">=10" } }, "node_modules/liftup/node_modules/findup-sync": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", "dev": true, "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.0", "micromatch": "^4.0.2", "resolve-dir": "^1.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/liftup/node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dev": true, "dependencies": { "uc.micro": "^1.0.1" } }, "node_modules/lodash": { "version": "4.17.23", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, "node_modules/lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", "dev": true }, "node_modules/make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "dependencies": { "kind-of": "^6.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/markdown-it": { "version": "12.3.2", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dev": true, "dependencies": { "argparse": "^2.0.1", "entities": "~2.1.0", "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, "bin": { "markdown-it": "bin/markdown-it.js" } }, "node_modules/markdown-it-anchor": { "version": "8.6.5", "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.5.tgz", "integrity": "sha512-PI1qEHHkTNWT+X6Ip9w+paonfIQ+QZP9sCeMYi47oqhH+EsW8CrJ8J7CzV19QVOj6il8ATGbK2nTECj22ZHGvQ==", "dev": true, "peerDependencies": { "@types/markdown-it": "*", "markdown-it": "*" } }, "node_modules/markdown-it/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/markdown-it/node_modules/entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/marked": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", "dev": true, "bin": { "marked": "bin/marked.js" }, "engines": { "node": ">= 12" } }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/maxmin": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-2.1.0.tgz", "integrity": "sha1-TTsiCQPZXu5+t6x/qGTnLcCaMWY=", "dev": true, "dependencies": { "chalk": "^1.0.0", "figures": "^1.0.1", "gzip-size": "^3.0.0", "pretty-bytes": "^3.0.0" }, "engines": { "node": ">=0.12" } }, "node_modules/maxmin/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/maxmin/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", "dev": true }, "node_modules/micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { "braces": "^3.0.1", "picomatch": "^2.2.3" }, "engines": { "node": ">=8.6" } }, "node_modules/miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "brorand": "^1.0.1" }, "bin": { "miller-rabin": "bin/miller-rabin" } }, "node_modules/mime": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true, "bin": { "mime": "cli.js" }, "engines": { "node": ">=4.0.0" } }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", "dev": true }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "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/module-deps": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.2.tgz", "integrity": "sha512-a9y6yDv5u5I4A+IPHTnqFxcaKr4p50/zxTjcQJaX2ws9tN/W6J6YXnEKhqRyPhl494dkcxx951onSKVezmI+3w==", "dev": true, "dependencies": { "browser-resolve": "^1.7.0", "cached-path-relative": "^1.0.2", "concat-stream": "~1.6.0", "defined": "^1.0.0", "detective": "^5.2.0", "duplexer2": "^0.1.2", "inherits": "^2.0.1", "JSONStream": "^1.0.3", "parents": "^1.0.0", "readable-stream": "^2.0.2", "resolve": "^1.4.0", "stream-combiner2": "^1.1.1", "subarg": "^1.0.0", "through2": "^2.0.0", "xtend": "^4.0.0" }, "bin": { "module-deps": "bin/cmd.js" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/module-deps/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/module-deps/node_modules/resolve": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "dev": true, "dependencies": { "path-parse": "^1.0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/module-deps/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "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/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, "node_modules/nopt": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "dependencies": { "abbrev": "1", "osenv": "^0.1.4" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "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.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "dev": true, "dependencies": { "array-each": "^1.0.1", "array-slice": "^1.0.0", "for-own": "^1.0.0", "isobject": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", "dev": true, "dependencies": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "dependencies": { "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "dependencies": { "wrappy": "1" } }, "node_modules/os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "engines": { "node": ">=0.10.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/osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" } }, "node_modules/p-each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", "dev": true, "dependencies": { "p-reduce": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, "node_modules/parents": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", "dev": true, "dependencies": { "path-platform": "~0.11.15" } }, "node_modules/parse-asn1": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "dependencies": { "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", "evp_bytestokey": "^1.0.0", "pbkdf2": "^3.0.3", "safe-buffer": "^5.1.1" } }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" }, "engines": { "node": ">=0.8" } }, "node_modules/parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/path-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "engines": { "node": ">=0.10.0" } }, "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/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-platform": { "version": "0.11.15", "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "dependencies": { "path-root-regex": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/pbkdf2": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", "dev": true, "license": "MIT", "dependencies": { "create-hash": "~1.1.3", "create-hmac": "^1.1.7", "ripemd160": "=2.0.1", "safe-buffer": "^5.2.1", "sha.js": "^2.4.11", "to-buffer": "^1.2.0" }, "engines": { "node": ">=0.12" } }, "node_modules/pbkdf2/node_modules/create-hash": { "version": "1.1.3", "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", "dev": true, "license": "MIT", "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", "ripemd160": "^2.0.0", "sha.js": "^2.4.0" } }, "node_modules/pbkdf2/node_modules/hash-base": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.1" } }, "node_modules/pbkdf2/node_modules/ripemd160": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", "dev": true, "license": "MIT", "dependencies": { "hash-base": "^2.0.0", "inherits": "^2.0.1" } }, "node_modules/pbkdf2/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, "node_modules/picomatch": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/pretty-bytes": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz", "integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=", "dev": true, "dependencies": { "number-is-nan": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true, "engines": { "node": ">= 0.6.0" } }, "node_modules/process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", "dev": true }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" } }, "node_modules/punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, "node_modules/puppeteer": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", "deprecated": "< 19.4.0 is no longer supported", "dev": true, "hasInstallScript": true, "dependencies": { "debug": "^4.1.0", "extract-zip": "^1.6.6", "https-proxy-agent": "^2.2.1", "mime": "^2.0.3", "progress": "^2.0.1", "proxy-from-env": "^1.0.0", "rimraf": "^2.6.1", "ws": "^6.1.0" }, "engines": { "node": ">=6.4.0" } }, "node_modules/puppeteer/node_modules/debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/puppeteer/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "dev": true, "engines": { "node": ">=0.4.x" } }, "node_modules/querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true, "engines": { "node": ">=0.4.x" } }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/randomfill": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "dependencies": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" } }, "node_modules/read-only-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "dependencies": { "readable-stream": "^2.0.2" } }, "node_modules/read-only-stream/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/read-only-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/readable-stream/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "node_modules/rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", "dev": true, "dependencies": { "resolve": "^1.9.0" }, "engines": { "node": ">= 0.10" } }, "node_modules/rechoir/node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/requizzle": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", "dev": true, "dependencies": { "lodash": "^4.17.14" } }, "node_modules/resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true }, "node_modules/resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "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/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/sha.js": { "version": "2.4.12", "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "dev": true, "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" }, "engines": { "node": ">= 0.10" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/sha.js/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/sha.js/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/shasum": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "dev": true, "dependencies": { "json-stable-stringify": "~0.0.0", "sha.js": "~2.4.4" } }, "node_modules/shasum-object": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", "dev": true, "dependencies": { "fast-safe-stringify": "^2.0.7" } }, "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/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/shell-quote": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, "node_modules/simple-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", "dev": true }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, "node_modules/stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "dependencies": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" } }, "node_modules/stream-browserify/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/stream-browserify/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true, "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, "node_modules/stream-combiner2/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/stream-combiner2/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/stream-http": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.1.0.tgz", "integrity": "sha512-cuB6RgO7BqC4FBYzmnvhob5Do3wIdIsXAgGycHJnW+981gHqoYcYz9lqjJrk8WXRddbwPuqPYRl+bag6mYv4lw==", "dev": true, "dependencies": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.1", "readable-stream": "^3.0.6", "xtend": "^4.0.0" } }, "node_modules/stream-http/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/stream-http/node_modules/safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true }, "node_modules/stream-http/node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/stream-splicer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", "dev": true, "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.2" } }, "node_modules/stream-splicer/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/stream-splicer/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "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" } }, "node_modules/subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "dev": true, "dependencies": { "minimist": "^1.1.0" } }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/syntax-error": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "dev": true, "dependencies": { "acorn-node": "^1.2.0" } }, "node_modules/taffydb": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", "integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==", "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/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "node_modules/through2/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/through2/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/timers-browserify": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "dev": true, "dependencies": { "process": "~0.11.0" }, "engines": { "node": ">=0.6.0" } }, "node_modules/to-buffer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", "dev": true, "license": "MIT", "dependencies": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", "typed-array-buffer": "^1.0.3" }, "engines": { "node": ">= 0.4" } }, "node_modules/to-buffer/node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, "node_modules/to-buffer/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", "dev": true }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", "dev": true }, "node_modules/uglify-js": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "dev": true, "dependencies": { "commander": "~2.20.0", "source-map": "~0.6.1" }, "bin": { "uglifyjs": "bin/uglifyjs" }, "engines": { "node": ">=0.8.0" } }, "node_modules/uglify-js/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/umd": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", "dev": true, "bin": { "umd": "bin/cli.js" } }, "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/undeclared-identifiers": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", "dev": true, "dependencies": { "acorn-node": "^1.3.0", "dash-ast": "^1.0.0", "get-assigned-identifiers": "^1.2.0", "simple-concat": "^1.0.0", "xtend": "^4.0.1" }, "bin": { "undeclared-identifiers": "bin.js" } }, "node_modules/underscore": { "version": "1.13.6", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, "node_modules/underscore.string": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", "dev": true, "dependencies": { "sprintf-js": "^1.1.1", "util-deprecate": "^1.0.2" }, "engines": { "node": "*" } }, "node_modules/uri-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", "dev": true, "engines": { "node": ">= 0.10" } }, "node_modules/url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" } }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true }, "node_modules/util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", "dev": true, "dependencies": { "inherits": "2.0.3" } }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "node_modules/v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", "dev": true, "dependencies": { "homedir-polyfill": "^1.0.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/which-typed-array": { "version": "1.1.19", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "node_modules/ws": { "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" } }, "node_modules/xmlcreate": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, "engines": { "node": ">=0.4" } }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } } } } thrift-0.23.0/lib/js/README.md0000664000175000017500000001072015165535636016036 0ustar00buildbuild00000000000000Thrift Javascript Library ========================= This browser based Apache Thrift implementation supports RPC clients using the JSON protocol over Http[s] with XHR and WebSocket. License ------- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Grunt Build ------------ This is the base directory for the Apache Thrift JavaScript library. This directory contains a Gruntfile.js and a package.json. Many of the build and test tools used here require a recent version of Node.js to be installed. To install the support files for the Grunt build tool execute the command: npm install This reads the package.json and pulls in the appropriate sources from the internet. To build the JavaScript branch of Apache Thrift execute the command: npx grunt This runs the grunt build tool (from within `./node_modules/.bin/`), linting all of the source files, setting up and running the tests, concatenating and minifying the main libraries and generating the html documentation. Tree ---- The following directories are present (some only after the grunt build): /src - The JavaScript Apache Thrift source /doc - HTML documentation /dist - Distribution files (thrift.js and thrift.min.js) /test - Various tests, this is a good place to look for example code /node_modules - Build support files installed by npm Example JavaScript Client and Server ------------------------------------ The listing below demonstrates a simple browser based JavaScript Thrift client and Node.js JavaScript server for the hello_svc service. ### hello.thrift - Service IDL ### build with: $ thrift -gen js -gen js:node hello.thrift service hello_svc { string get_message(1: string name) } ### hello.html - Browser Client Hello Thrift Name:
### hello.js - Node Server var thrift = require('thrift'); var hello_svc = require('./gen-nodejs/hello_svc.js'); var hello_handler = { get_message: function(name, result) { var msg = "Hello " + name + "!"; result(null, msg); } } var hello_svc_opt = { transport: thrift.TBufferedTransport, protocol: thrift.TJSONProtocol, processor: hello_svc, handler: hello_handler }; var server_opt = { staticFilePath: ".", services: { "/hello": hello_svc_opt } } var server = Thrift.createWebServer(server_opt); var port = 9099; server.listen(port); console.log("Http/Thrift Server running on port: " + port); TypeScript ------------------------------------ TypeScript definition files can also be generated by running: thrift --gen js:ts file.thrift # Breaking Changes ## 0.13.0 1. 64-bit integer constants are now generatd using node-int64 e.g.: var x = new Int64("7fffffffffffffff"); thrift-0.23.0/lib/js/Makefile0000644000175000017500000006157015170007175016212 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/js/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Make sure this doesn't fail if ant is not configured. # We call npm install twice to work around older npm issues # (note these issues may no longer be present, but it is ok) # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu subdir = lib/js ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = test am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/js abs_srcdir = /thrift/src/lib/js abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. SUBDIRS = test EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ package.json \ package-lock.json \ CMakeLists.txt \ README.md \ src \ test all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/js/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/js/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook #check-local: check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am dist-hook distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile prereq: $(NPM) install || $(NPM) install $(NPM) list check-local: prereq all ./node_modules/.bin/grunt doc: prereq ./node_modules/.bin/grunt jsdoc clean-local: $(RM) -r dist $(RM) -r doc $(RM) -r node_modules $(RM) -r test/build/ $(RM) -r test/gen-*/ dist-hook: $(RM) -r $(distdir)/dist/ $(RM) -r $(distdir)/doc/ $(RM) -r $(distdir)/node_modules/ $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/js/Makefile.in0000644000175000017500000006074515170007167016623 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Make sure this doesn't fail if ant is not configured. # We call npm install twice to work around older npm issues # (note these issues may no longer be present, but it is ok) # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/js ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = test am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @HAVE_NPM_TRUE@SUBDIRS = test EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ package.json \ package-lock.json \ CMakeLists.txt \ README.md \ src \ test all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/js/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/js/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook @HAVE_NPM_FALSE@check-local: check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am dist-hook distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile @HAVE_NPM_TRUE@prereq: @HAVE_NPM_TRUE@ $(NPM) install || $(NPM) install @HAVE_NPM_TRUE@ $(NPM) list @HAVE_NPM_TRUE@check-local: prereq all @HAVE_NPM_TRUE@ ./node_modules/.bin/grunt @HAVE_NPM_TRUE@doc: prereq @HAVE_NPM_TRUE@ ./node_modules/.bin/grunt jsdoc clean-local: $(RM) -r dist $(RM) -r doc $(RM) -r node_modules $(RM) -r test/build/ $(RM) -r test/gen-*/ dist-hook: $(RM) -r $(distdir)/dist/ $(RM) -r $(distdir)/doc/ $(RM) -r $(distdir)/node_modules/ $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/js/Makefile.am0000664000175000017500000000311515165535636016613 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Make sure this doesn't fail if ant is not configured. # We call npm install twice to work around older npm issues # (note these issues may no longer be present, but it is ok) # if HAVE_NPM SUBDIRS = test prereq: $(NPM) install || $(NPM) install $(NPM) list check-local: prereq all ./node_modules/.bin/grunt doc: prereq ./node_modules/.bin/grunt jsdoc endif clean-local: $(RM) -r dist $(RM) -r doc $(RM) -r node_modules $(RM) -r test/build/ $(RM) -r test/gen-*/ dist-hook: $(RM) -r $(distdir)/dist/ $(RM) -r $(distdir)/doc/ $(RM) -r $(distdir)/node_modules/ $(RM) -r $(distdir)/test/build/ $(RM) -r $(distdir)/test/gen-*/ distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ coding_standards.md \ Gruntfile.js \ package.json \ package-lock.json \ CMakeLists.txt \ README.md \ src \ test thrift-0.23.0/lib/rs/0000755000175000017500000000000015170007201014537 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/src/0000775000175000017500000000000015165535636015356 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/src/errors.rs0000664000175000017500000005313015165535636017242 0ustar00buildbuild00000000000000// 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. use std::convert::TryFrom; use std::convert::{From, Into}; use std::fmt::{Debug, Display, Formatter}; use std::{error, fmt, io, string}; use crate::protocol::{ TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType, }; // FIXME: should all my error structs impl error::Error as well? // FIXME: should all fields in TransportError, ProtocolError and ApplicationError be optional? /// Error type returned by all runtime library functions. /// /// `thrift::Error` is used throughout this crate as well as in auto-generated /// Rust code. It consists of four variants defined by convention across Thrift /// implementations: /// /// 1. `Transport`: errors encountered while operating on I/O channels /// 2. `Protocol`: errors encountered during runtime-library processing /// 3. `Application`: errors encountered within auto-generated code /// 4. `User`: IDL-defined exception structs /// /// The `Application` variant also functions as a catch-all: all handler errors /// are automatically turned into application errors. /// /// All error variants except `Error::User` take an eponymous struct with two /// required fields: /// /// 1. `kind`: variant-specific enum identifying the error sub-type /// 2. `message`: human-readable error info string /// /// `kind` is defined by convention while `message` is freeform. If none of the /// enumerated kinds are suitable use `Unknown`. /// /// To simplify error creation convenience constructors are defined for all /// variants, and conversions from their structs (`thrift::TransportError`, /// `thrift::ProtocolError` and `thrift::ApplicationError` into `thrift::Error`. /// /// # Examples /// /// Create a `TransportError`. /// /// ``` /// use thrift::{TransportError, TransportErrorKind}; /// /// // explicit /// let err0: thrift::Result<()> = Err( /// thrift::Error::Transport( /// TransportError { /// kind: TransportErrorKind::TimedOut, /// message: format!("connection to server timed out") /// } /// ) /// ); /// /// // use conversion /// let err1: thrift::Result<()> = Err( /// thrift::Error::from( /// TransportError { /// kind: TransportErrorKind::TimedOut, /// message: format!("connection to server timed out") /// } /// ) /// ); /// /// // use struct constructor /// let err2: thrift::Result<()> = Err( /// thrift::Error::Transport( /// TransportError::new( /// TransportErrorKind::TimedOut, /// "connection to server timed out" /// ) /// ) /// ); /// /// /// // use error variant constructor /// let err3: thrift::Result<()> = Err( /// thrift::new_transport_error( /// TransportErrorKind::TimedOut, /// "connection to server timed out" /// ) /// ); /// ``` /// /// Create an error from a string. /// /// ``` /// use thrift::{ApplicationError, ApplicationErrorKind}; /// /// // we just use `From::from` to convert a `String` into a `thrift::Error` /// let err0: thrift::Result<()> = Err( /// thrift::Error::from("This is an error") /// ); /// /// // err0 is equivalent to... /// let err1: thrift::Result<()> = Err( /// thrift::Error::Application( /// ApplicationError { /// kind: ApplicationErrorKind::Unknown, /// message: format!("This is an error") /// } /// ) /// ); /// ``` /// /// Return an IDL-defined exception. /// /// ```text /// // Thrift IDL exception definition. /// exception Xception { /// 1: i32 errorCode, /// 2: string message /// } /// ``` /// /// ``` /// use std::error::Error; /// use std::fmt; /// use std::fmt::{Display, Formatter}; /// /// // auto-generated by the Thrift compiler /// #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] /// pub struct Xception { /// pub error_code: Option, /// pub message: Option, /// } /// /// // auto-generated by the Thrift compiler /// impl Error for Xception { } /// /// // auto-generated by the Thrift compiler /// impl From for thrift::Error { /// fn from(e: Xception) -> Self { /// thrift::Error::User(Box::new(e)) /// } /// } /// /// // auto-generated by the Thrift compiler /// impl Display for Xception { /// fn fmt(&self, f: &mut Formatter) -> fmt::Result { /// write!(f, "remote service threw Xception") /// } /// } /// /// // in user code... /// let err: thrift::Result<()> = Err( /// thrift::Error::from(Xception { error_code: Some(1), message: None }) /// ); /// ``` pub enum Error { /// Errors encountered while operating on I/O channels. /// /// These include *connection closed* and *bind failure*. Transport(TransportError), /// Errors encountered during runtime-library processing. /// /// These include *message too large* and *unsupported protocol version*. Protocol(ProtocolError), /// Errors encountered within auto-generated code, or when incoming /// or outgoing messages violate the Thrift spec. /// /// These include *out-of-order messages* and *missing required struct /// fields*. /// /// This variant also functions as a catch-all: errors from handler /// functions are automatically returned as an `ApplicationError`. Application(ApplicationError), /// IDL-defined exception structs. User(Box), } impl Error { /// Create an `ApplicationError` from its wire representation. /// /// Application code **should never** call this method directly. pub fn read_application_error_from_in_protocol( i: &mut dyn TInputProtocol, ) -> crate::Result { let mut message = "general remote error".to_owned(); let mut kind = ApplicationErrorKind::Unknown; i.read_struct_begin()?; loop { let field_ident = i.read_field_begin()?; if field_ident.field_type == TType::Stop { break; } let id = field_ident .id .expect("sender should always specify id for non-STOP field"); match id { 1 => { let remote_message = i.read_string()?; i.read_field_end()?; message = remote_message; } 2 => { let remote_type_as_int = i.read_i32()?; let remote_kind: ApplicationErrorKind = TryFrom::try_from(remote_type_as_int) .unwrap_or(ApplicationErrorKind::Unknown); i.read_field_end()?; kind = remote_kind; } _ => { i.skip(field_ident.field_type)?; } } } i.read_struct_end()?; Ok(ApplicationError { kind, message }) } /// Convert an `ApplicationError` into its wire representation and write /// it to the remote. /// /// Application code **should never** call this method directly. pub fn write_application_error_to_out_protocol( e: &ApplicationError, o: &mut dyn TOutputProtocol, ) -> crate::Result<()> { o.write_struct_begin(&TStructIdentifier { name: "TApplicationException".to_owned(), })?; let message_field = TFieldIdentifier::new("message", TType::String, 1); let type_field = TFieldIdentifier::new("type", TType::I32, 2); o.write_field_begin(&message_field)?; o.write_string(&e.message)?; o.write_field_end()?; o.write_field_begin(&type_field)?; o.write_i32(e.kind as i32)?; o.write_field_end()?; o.write_field_stop()?; o.write_struct_end()?; o.flush() } } impl error::Error for Error {} impl Debug for Error { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match *self { Error::Transport(ref e) => Debug::fmt(e, f), Error::Protocol(ref e) => Debug::fmt(e, f), Error::Application(ref e) => Debug::fmt(e, f), Error::User(ref e) => Debug::fmt(e, f), } } } impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match *self { Error::Transport(ref e) => Display::fmt(e, f), Error::Protocol(ref e) => Display::fmt(e, f), Error::Application(ref e) => Display::fmt(e, f), Error::User(ref e) => Display::fmt(e, f), } } } impl From for Error { fn from(s: String) -> Self { Error::Application(ApplicationError { kind: ApplicationErrorKind::Unknown, message: s, }) } } impl<'a> From<&'a str> for Error { fn from(s: &'a str) -> Self { Error::Application(ApplicationError { kind: ApplicationErrorKind::Unknown, message: String::from(s), }) } } impl From for Error { fn from(e: TransportError) -> Self { Error::Transport(e) } } impl From for Error { fn from(e: ProtocolError) -> Self { Error::Protocol(e) } } impl From for Error { fn from(e: ApplicationError) -> Self { Error::Application(e) } } /// Create a new `Error` instance of type `Transport` that wraps a /// `TransportError`. pub fn new_transport_error>(kind: TransportErrorKind, message: S) -> Error { Error::Transport(TransportError::new(kind, message)) } /// Information about I/O errors. #[derive(Debug, Eq, PartialEq)] pub struct TransportError { /// I/O error variant. /// /// If a specific `TransportErrorKind` does not apply use /// `TransportErrorKind::Unknown`. pub kind: TransportErrorKind, /// Human-readable error message. pub message: String, } impl TransportError { /// Create a new `TransportError`. pub fn new>(kind: TransportErrorKind, message: S) -> TransportError { TransportError { kind, message: message.into(), } } } /// I/O error categories. /// /// This list may grow, and it is not recommended to match against it. #[non_exhaustive] #[derive(Clone, Copy, Eq, Debug, PartialEq)] pub enum TransportErrorKind { /// Catch-all I/O error. Unknown = 0, /// An I/O operation was attempted when the transport channel was not open. NotOpen = 1, /// The transport channel cannot be opened because it was opened previously. AlreadyOpen = 2, /// An I/O operation timed out. TimedOut = 3, /// A read could not complete because no bytes were available. EndOfFile = 4, /// An invalid (buffer/message) size was requested or received. NegativeSize = 5, /// Too large a buffer or message size was requested or received. SizeLimit = 6, } impl Display for TransportError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let error_text = match self.kind { TransportErrorKind::Unknown => "transport error", TransportErrorKind::NotOpen => "not open", TransportErrorKind::AlreadyOpen => "already open", TransportErrorKind::TimedOut => "timed out", TransportErrorKind::EndOfFile => "end of file", TransportErrorKind::NegativeSize => "negative size message", TransportErrorKind::SizeLimit => "message too long", }; write!(f, "{}", error_text) } } impl TryFrom for TransportErrorKind { type Error = Error; fn try_from(from: i32) -> Result { match from { 0 => Ok(TransportErrorKind::Unknown), 1 => Ok(TransportErrorKind::NotOpen), 2 => Ok(TransportErrorKind::AlreadyOpen), 3 => Ok(TransportErrorKind::TimedOut), 4 => Ok(TransportErrorKind::EndOfFile), 5 => Ok(TransportErrorKind::NegativeSize), 6 => Ok(TransportErrorKind::SizeLimit), _ => Err(Error::Protocol(ProtocolError { kind: ProtocolErrorKind::Unknown, message: format!("cannot convert {} to TransportErrorKind", from), })), } } } impl From for Error { fn from(err: io::Error) -> Self { match err.kind() { io::ErrorKind::ConnectionReset | io::ErrorKind::ConnectionRefused | io::ErrorKind::NotConnected => Error::Transport(TransportError { kind: TransportErrorKind::NotOpen, message: err.to_string(), }), io::ErrorKind::AlreadyExists => Error::Transport(TransportError { kind: TransportErrorKind::AlreadyOpen, message: err.to_string(), }), io::ErrorKind::TimedOut => Error::Transport(TransportError { kind: TransportErrorKind::TimedOut, message: err.to_string(), }), io::ErrorKind::UnexpectedEof => Error::Transport(TransportError { kind: TransportErrorKind::EndOfFile, message: err.to_string(), }), _ => { Error::Transport(TransportError { kind: TransportErrorKind::Unknown, message: err.to_string(), // FIXME: use io error's debug string }) } } } } impl From for Error { fn from(err: uuid::Error) -> Self { Error::Protocol(ProtocolError { kind: ProtocolErrorKind::InvalidData, message: err.to_string(), // FIXME: use fmt::Error's debug string }) } } impl From for Error { fn from(err: string::FromUtf8Error) -> Self { Error::Protocol(ProtocolError { kind: ProtocolErrorKind::InvalidData, message: err.to_string(), // FIXME: use fmt::Error's debug string }) } } /// Create a new `Error` instance of type `Protocol` that wraps a /// `ProtocolError`. pub fn new_protocol_error>(kind: ProtocolErrorKind, message: S) -> Error { Error::Protocol(ProtocolError::new(kind, message)) } /// Information about errors that occur in the runtime library. #[derive(Debug, Eq, PartialEq)] pub struct ProtocolError { /// Protocol error variant. /// /// If a specific `ProtocolErrorKind` does not apply use /// `ProtocolErrorKind::Unknown`. pub kind: ProtocolErrorKind, /// Human-readable error message. pub message: String, } impl ProtocolError { /// Create a new `ProtocolError`. pub fn new>(kind: ProtocolErrorKind, message: S) -> ProtocolError { ProtocolError { kind, message: message.into(), } } } /// Runtime library error categories. /// /// This list may grow, and it is not recommended to match against it. #[non_exhaustive] #[derive(Clone, Copy, Eq, Debug, PartialEq)] pub enum ProtocolErrorKind { /// Catch-all runtime-library error. Unknown = 0, /// An invalid argument was supplied to a library function, or invalid data /// was received from a Thrift endpoint. InvalidData = 1, /// An invalid size was received in an encoded field. NegativeSize = 2, /// Thrift message or field was too long. SizeLimit = 3, /// Unsupported or unknown Thrift protocol version. BadVersion = 4, /// Unsupported Thrift protocol, server or field type. NotImplemented = 5, /// Reached the maximum nested depth to which an encoded Thrift field could /// be skipped. DepthLimit = 6, } impl Display for ProtocolError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let error_text = match self.kind { ProtocolErrorKind::Unknown => "protocol error", ProtocolErrorKind::InvalidData => "bad data", ProtocolErrorKind::NegativeSize => "negative message size", ProtocolErrorKind::SizeLimit => "message too long", ProtocolErrorKind::BadVersion => "invalid thrift version", ProtocolErrorKind::NotImplemented => "not implemented", ProtocolErrorKind::DepthLimit => "maximum skip depth reached", }; write!(f, "{}", error_text) } } impl TryFrom for ProtocolErrorKind { type Error = Error; fn try_from(from: i32) -> Result { match from { 0 => Ok(ProtocolErrorKind::Unknown), 1 => Ok(ProtocolErrorKind::InvalidData), 2 => Ok(ProtocolErrorKind::NegativeSize), 3 => Ok(ProtocolErrorKind::SizeLimit), 4 => Ok(ProtocolErrorKind::BadVersion), 5 => Ok(ProtocolErrorKind::NotImplemented), 6 => Ok(ProtocolErrorKind::DepthLimit), _ => Err(Error::Protocol(ProtocolError { kind: ProtocolErrorKind::Unknown, message: format!("cannot convert {} to ProtocolErrorKind", from), })), } } } /// Create a new `Error` instance of type `Application` that wraps an /// `ApplicationError`. pub fn new_application_error>(kind: ApplicationErrorKind, message: S) -> Error { Error::Application(ApplicationError::new(kind, message)) } /// Information about errors in auto-generated code or in user-implemented /// service handlers. #[derive(Debug, Eq, PartialEq)] pub struct ApplicationError { /// Application error variant. /// /// If a specific `ApplicationErrorKind` does not apply use /// `ApplicationErrorKind::Unknown`. pub kind: ApplicationErrorKind, /// Human-readable error message. pub message: String, } impl ApplicationError { /// Create a new `ApplicationError`. pub fn new>(kind: ApplicationErrorKind, message: S) -> ApplicationError { ApplicationError { kind, message: message.into(), } } } /// Auto-generated or user-implemented code error categories. /// /// This list may grow, and it is not recommended to match against it. #[non_exhaustive] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ApplicationErrorKind { /// Catch-all application error. Unknown = 0, /// Made service call to an unknown service method. UnknownMethod = 1, /// Received an unknown Thrift message type. That is, not one of the /// `thrift::protocol::TMessageType` variants. InvalidMessageType = 2, /// Method name in a service reply does not match the name of the /// receiving service method. WrongMethodName = 3, /// Received an out-of-order Thrift message. BadSequenceId = 4, /// Service reply is missing required fields. MissingResult = 5, /// Auto-generated code failed unexpectedly. InternalError = 6, /// Thrift protocol error. When possible use `Error::ProtocolError` with a /// specific `ProtocolErrorKind` instead. ProtocolError = 7, /// *Unknown*. Included only for compatibility with existing Thrift implementations. InvalidTransform = 8, // ?? /// Thrift endpoint requested, or is using, an unsupported encoding. InvalidProtocol = 9, // ?? /// Thrift endpoint requested, or is using, an unsupported auto-generated client type. UnsupportedClientType = 10, // ?? } impl Display for ApplicationError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let error_text = match self.kind { ApplicationErrorKind::Unknown => "service error", ApplicationErrorKind::UnknownMethod => "unknown service method", ApplicationErrorKind::InvalidMessageType => "wrong message type received", ApplicationErrorKind::WrongMethodName => "unknown method reply received", ApplicationErrorKind::BadSequenceId => "out of order sequence id", ApplicationErrorKind::MissingResult => "missing method result", ApplicationErrorKind::InternalError => "remote service threw exception", ApplicationErrorKind::ProtocolError => "protocol error", ApplicationErrorKind::InvalidTransform => "invalid transform", ApplicationErrorKind::InvalidProtocol => "invalid protocol requested", ApplicationErrorKind::UnsupportedClientType => "unsupported protocol client", }; write!(f, "{}", error_text) } } impl TryFrom for ApplicationErrorKind { type Error = Error; fn try_from(from: i32) -> Result { match from { 0 => Ok(ApplicationErrorKind::Unknown), 1 => Ok(ApplicationErrorKind::UnknownMethod), 2 => Ok(ApplicationErrorKind::InvalidMessageType), 3 => Ok(ApplicationErrorKind::WrongMethodName), 4 => Ok(ApplicationErrorKind::BadSequenceId), 5 => Ok(ApplicationErrorKind::MissingResult), 6 => Ok(ApplicationErrorKind::InternalError), 7 => Ok(ApplicationErrorKind::ProtocolError), 8 => Ok(ApplicationErrorKind::InvalidTransform), 9 => Ok(ApplicationErrorKind::InvalidProtocol), 10 => Ok(ApplicationErrorKind::UnsupportedClientType), _ => Err(Error::Application(ApplicationError { kind: ApplicationErrorKind::Unknown, message: format!("cannot convert {} to ApplicationErrorKind", from), })), } } } thrift-0.23.0/lib/rs/src/lib.rs0000664000175000017500000000576615165535636016510 0ustar00buildbuild00000000000000// 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. //! Rust runtime library for the Apache Thrift RPC system. //! //! This crate implements the components required to build a working //! Thrift server and client. It is divided into the following modules: //! //! 1. errors //! 2. configuration //! 3. protocol //! 4. transport //! 5. server //! 6. autogen //! //! The modules are layered as shown in the diagram below. The `autogen'd` //! layer is generated by the Thrift compiler's Rust plugin. It uses the //! types and functions defined in this crate to serialize and deserialize //! messages and implement RPC. Users interact with these types and services //! by writing their own code that uses the auto-generated clients and //! servers. //! //! ```text //! +-----------+ //! | user app | //! +-----------+ //! | autogen'd | (uses errors, autogen) //! +-----------+ //! | protocol | //! +-----------+ //! | transport | //! +-----------+ //! ``` //! //! # Tutorial //! //! For an example of how to setup a simple client and server using this crate //! see the [tutorial]. //! //! [tutorial]: https://github.com/apache/thrift/tree/master/tutorial/rs #![crate_type = "lib"] #![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: // https://danielkeep.github.io/quick-intro-to-macros.html#some-more-gotchas /// Assert that an expression returning a `Result` is a success. If it is, /// return the value contained in the result, i.e. `expr.unwrap()`. #[cfg(test)] macro_rules! assert_success { ($e: expr) => {{ let res = $e; assert!(res.is_ok()); res.unwrap() }}; } pub mod protocol; #[cfg(feature = "server")] pub mod server; pub mod transport; mod errors; pub use crate::errors::*; mod autogen; pub use crate::autogen::*; mod configuration; pub use crate::configuration::*; /// Result type returned by all runtime library functions. /// /// As is convention this is a typedef of `std::result::Result` /// with `E` defined as the `thrift::Error` type. pub type Result = std::result::Result; // Re-export ordered-float, since it is used by the generator // FIXME: check the guidance around type reexports pub use ordered_float::OrderedFloat; thrift-0.23.0/lib/rs/src/server/0000775000175000017500000000000015165535636016664 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/src/server/multiplexed.rs0000664000175000017500000003121515165535636021570 0ustar00buildbuild00000000000000// 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. use log::debug; use std::collections::HashMap; use std::convert::Into; use std::fmt; use std::fmt::{Debug, Formatter}; use std::sync::{Arc, Mutex}; use crate::protocol::{TInputProtocol, TMessageIdentifier, TOutputProtocol, TStoredInputProtocol}; use super::{handle_process_result, TProcessor}; const MISSING_SEPARATOR_AND_NO_DEFAULT: &str = "missing service separator and no default processor set"; type ThreadSafeProcessor = Box; /// A `TProcessor` that can demux service calls to multiple underlying /// Thrift services. /// /// Users register service-specific `TProcessor` instances with a /// `TMultiplexedProcessor`, and then register that processor with a server /// implementation. Following that, all incoming service calls are automatically /// routed to the service-specific `TProcessor`. /// /// A `TMultiplexedProcessor` can only handle messages sent by a /// `TMultiplexedOutputProtocol`. #[derive(Default)] pub struct TMultiplexedProcessor { stored: Mutex, } #[derive(Default)] struct StoredProcessors { processors: HashMap>, default_processor: Option>, } impl TMultiplexedProcessor { /// Create a new `TMultiplexedProcessor` with no registered service-specific /// processors. pub fn new() -> TMultiplexedProcessor { TMultiplexedProcessor { stored: Mutex::new(StoredProcessors { processors: HashMap::new(), default_processor: None, }), } } /// Register a service-specific `processor` for the service named /// `service_name`. This implementation is also backwards-compatible with /// non-multiplexed clients. Set `as_default` to `true` to allow /// non-namespaced requests to be dispatched to a default processor. /// /// Returns success if a new entry was inserted. Returns an error if: /// * A processor exists for `service_name` /// * You attempt to register a processor as default, and an existing default exists #[allow(clippy::map_entry)] pub fn register>( &mut self, service_name: S, processor: Box, as_default: bool, ) -> crate::Result<()> { let mut stored = self.stored.lock().unwrap(); let name = service_name.into(); if !stored.processors.contains_key(&name) { let processor = Arc::new(processor); if as_default { if stored.default_processor.is_none() { stored.processors.insert(name, processor.clone()); stored.default_processor = Some(processor.clone()); Ok(()) } else { Err("cannot reset default processor".into()) } } else { stored.processors.insert(name, processor); Ok(()) } } else { Err(format!("cannot overwrite existing processor for service {}", name).into()) } } fn process_message( &self, msg_ident: &TMessageIdentifier, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol, ) -> crate::Result<()> { let (svc_name, svc_call) = split_ident_name(&msg_ident.name); debug!("routing svc_name {:?} svc_call {}", &svc_name, &svc_call); let processor: Option> = { let stored = self.stored.lock().unwrap(); if let Some(name) = svc_name { stored.processors.get(name).cloned() } else { stored.default_processor.clone() } }; match processor { Some(arc) => { let new_msg_ident = TMessageIdentifier::new( svc_call, msg_ident.message_type, msg_ident.sequence_number, ); let mut proxy_i_prot = TStoredInputProtocol::new(i_prot, new_msg_ident); (*arc).process(&mut proxy_i_prot, o_prot) } None => Err(missing_processor_message(svc_name).into()), } } } impl TProcessor for TMultiplexedProcessor { fn process( &self, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol, ) -> crate::Result<()> { let msg_ident = i_prot.read_message_begin()?; debug!("process incoming msg id:{:?}", &msg_ident); let res = self.process_message(&msg_ident, i_prot, o_prot); handle_process_result(&msg_ident, res, o_prot) } } impl Debug for TMultiplexedProcessor { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let stored = self.stored.lock().unwrap(); write!( f, "TMultiplexedProcess {{ registered_count: {:?} default: {:?} }}", stored.processors.keys().len(), stored.default_processor.is_some() ) } } fn split_ident_name(ident_name: &str) -> (Option<&str>, &str) { ident_name .find(':') .map(|pos| { let (svc_name, svc_call) = ident_name.split_at(pos); let (_, svc_call) = svc_call.split_at(1); // remove colon from service call name (Some(svc_name), svc_call) }) .unwrap_or((None, ident_name)) } fn missing_processor_message(svc_name: Option<&str>) -> String { match svc_name { Some(name) => format!("no processor found for service {}", name), None => MISSING_SEPARATOR_AND_NO_DEFAULT.to_owned(), } } #[cfg(test)] mod tests { use std::convert::Into; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use crate::protocol::{ TBinaryInputProtocol, TBinaryOutputProtocol, TMessageIdentifier, TMessageType, }; use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf}; use crate::{ApplicationError, ApplicationErrorKind}; use super::*; #[test] fn should_split_name_into_proper_separator_and_service_call() { let ident_name = "foo:bar_call"; let (serv, call) = split_ident_name(ident_name); assert_eq!(serv, Some("foo")); assert_eq!(call, "bar_call"); } #[test] fn should_return_full_ident_if_no_separator_exists() { let ident_name = "bar_call"; let (serv, call) = split_ident_name(ident_name); assert_eq!(serv, None); assert_eq!(call, "bar_call"); } #[test] fn should_write_error_if_no_separator_found_and_no_default_processor_exists() { let (mut i, mut o) = build_objects(); let sent_ident = TMessageIdentifier::new("foo", TMessageType::Call, 10); o.write_message_begin(&sent_ident).unwrap(); o.flush().unwrap(); o.transport.copy_write_buffer_to_read_buffer(); o.transport.empty_write_buffer(); let p = TMultiplexedProcessor::new(); p.process(&mut i, &mut o).unwrap(); // at this point an error should be written out i.transport.set_readable_bytes(&o.transport.write_bytes()); let rcvd_ident = i.read_message_begin().unwrap(); let expected_ident = TMessageIdentifier::new("foo", TMessageType::Exception, 10); assert_eq!(rcvd_ident, expected_ident); let rcvd_err = crate::Error::read_application_error_from_in_protocol(&mut i).unwrap(); let expected_err = ApplicationError::new( ApplicationErrorKind::Unknown, MISSING_SEPARATOR_AND_NO_DEFAULT, ); assert_eq!(rcvd_err, expected_err); } #[test] fn should_write_error_if_separator_exists_and_no_processor_found() { let (mut i, mut o) = build_objects(); let sent_ident = TMessageIdentifier::new("missing:call", TMessageType::Call, 10); o.write_message_begin(&sent_ident).unwrap(); o.flush().unwrap(); o.transport.copy_write_buffer_to_read_buffer(); o.transport.empty_write_buffer(); let p = TMultiplexedProcessor::new(); p.process(&mut i, &mut o).unwrap(); // at this point an error should be written out i.transport.set_readable_bytes(&o.transport.write_bytes()); let rcvd_ident = i.read_message_begin().unwrap(); let expected_ident = TMessageIdentifier::new("missing:call", TMessageType::Exception, 10); assert_eq!(rcvd_ident, expected_ident); let rcvd_err = crate::Error::read_application_error_from_in_protocol(&mut i).unwrap(); let expected_err = ApplicationError::new( ApplicationErrorKind::Unknown, missing_processor_message(Some("missing")), ); assert_eq!(rcvd_err, expected_err); } #[derive(Default)] struct Service { pub invoked: Arc, } impl TProcessor for Service { fn process( &self, _: &mut dyn TInputProtocol, _: &mut dyn TOutputProtocol, ) -> crate::Result<()> { let res = self.invoked .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed); if res.is_ok() { Ok(()) } else { Err("failed swap".into()) } } } #[test] fn should_route_call_to_correct_processor() { let (mut i, mut o) = build_objects(); // build the services let svc_1 = Service { invoked: Arc::new(AtomicBool::new(false)), }; let atm_1 = svc_1.invoked.clone(); let svc_2 = Service { invoked: Arc::new(AtomicBool::new(false)), }; let atm_2 = svc_2.invoked.clone(); // register them let mut p = TMultiplexedProcessor::new(); p.register("service_1", Box::new(svc_1), false).unwrap(); p.register("service_2", Box::new(svc_2), false).unwrap(); // make the service call let sent_ident = TMessageIdentifier::new("service_1:call", TMessageType::Call, 10); o.write_message_begin(&sent_ident).unwrap(); o.flush().unwrap(); o.transport.copy_write_buffer_to_read_buffer(); o.transport.empty_write_buffer(); p.process(&mut i, &mut o).unwrap(); // service 1 should have been invoked, not service 2 assert!(atm_1.load(Ordering::Relaxed)); assert!(!atm_2.load(Ordering::Relaxed)); } #[test] fn should_route_call_to_correct_processor_if_no_separator_exists_and_default_processor_set() { let (mut i, mut o) = build_objects(); // build the services let svc_1 = Service { invoked: Arc::new(AtomicBool::new(false)), }; let atm_1 = svc_1.invoked.clone(); let svc_2 = Service { invoked: Arc::new(AtomicBool::new(false)), }; let atm_2 = svc_2.invoked.clone(); // register them let mut p = TMultiplexedProcessor::new(); p.register("service_1", Box::new(svc_1), false).unwrap(); p.register("service_2", Box::new(svc_2), true).unwrap(); // second processor is default // make the service call (it's an old client, so we have to be backwards compatible) let sent_ident = TMessageIdentifier::new("old_call", TMessageType::Call, 10); o.write_message_begin(&sent_ident).unwrap(); o.flush().unwrap(); o.transport.copy_write_buffer_to_read_buffer(); o.transport.empty_write_buffer(); p.process(&mut i, &mut o).unwrap(); // service 2 should have been invoked, not service 1 assert!(!atm_1.load(Ordering::Relaxed)); assert!(atm_2.load(Ordering::Relaxed)); } fn build_objects() -> ( TBinaryInputProtocol>, TBinaryOutputProtocol>, ) { let c = TBufferChannel::with_capacity(128, 128); let (r_c, w_c) = c.split().unwrap(); ( TBinaryInputProtocol::new(r_c, true), TBinaryOutputProtocol::new(w_c, true), ) } } thrift-0.23.0/lib/rs/src/server/threaded.rs0000664000175000017500000002371515165535636021022 0ustar00buildbuild00000000000000// 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. use log::warn; use std::net::{TcpListener, ToSocketAddrs}; use std::sync::Arc; use threadpool::ThreadPool; #[cfg(unix)] use std::os::unix::net::UnixListener; #[cfg(unix)] use std::path::Path; use crate::protocol::{ TInputProtocol, TInputProtocolFactory, TOutputProtocol, TOutputProtocolFactory, }; use crate::transport::{TIoChannel, TReadTransportFactory, TTcpChannel, TWriteTransportFactory}; use crate::{ApplicationError, ApplicationErrorKind}; use super::TProcessor; use crate::TransportErrorKind; /// Fixed-size thread-pool blocking Thrift server. /// /// A `TServer` listens on a given address and submits accepted connections /// to an **unbounded** queue. Connections from this queue are serviced by /// the first available worker thread from a **fixed-size** thread pool. Each /// accepted connection is handled by that worker thread, and communication /// over this thread occurs sequentially and synchronously (i.e. calls block). /// Accepted connections have an input half and an output half, each of which /// uses a `TTransport` and `TInputProtocol`/`TOutputProtocol` to translate /// messages to and from byes. Any combination of `TInputProtocol`, `TOutputProtocol` /// and `TTransport` may be used. /// /// # Examples /// /// Creating and running a `TServer` using Thrift-compiler-generated /// service code. /// /// ```no_run /// use thrift::protocol::{TInputProtocolFactory, TOutputProtocolFactory}; /// use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory}; /// use thrift::protocol::{TInputProtocol, TOutputProtocol}; /// use thrift::transport::{TBufferedReadTransportFactory, TBufferedWriteTransportFactory, /// TReadTransportFactory, TWriteTransportFactory}; /// use thrift::server::{TProcessor, TServer}; /// /// // /// // auto-generated /// // /// /// // processor for `SimpleService` /// struct SimpleServiceSyncProcessor; /// impl SimpleServiceSyncProcessor { /// fn new(processor: H) -> SimpleServiceSyncProcessor { /// unimplemented!(); /// } /// } /// /// // `TProcessor` implementation for `SimpleService` /// impl TProcessor for SimpleServiceSyncProcessor { /// fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol) -> thrift::Result<()> { /// unimplemented!(); /// } /// } /// /// // service functions for SimpleService /// trait SimpleServiceSyncHandler { /// fn service_call(&self) -> thrift::Result<()>; /// } /// /// // /// // user-code follows /// // /// /// // define a handler that will be invoked when `service_call` is received /// struct SimpleServiceHandlerImpl; /// impl SimpleServiceSyncHandler for SimpleServiceHandlerImpl { /// fn service_call(&self) -> thrift::Result<()> { /// unimplemented!(); /// } /// } /// /// // instantiate the processor /// let processor = SimpleServiceSyncProcessor::new(SimpleServiceHandlerImpl {}); /// /// // instantiate the server /// let i_tr_fact: Box = Box::new(TBufferedReadTransportFactory::new()); /// let i_pr_fact: Box = Box::new(TBinaryInputProtocolFactory::new()); /// let o_tr_fact: Box = Box::new(TBufferedWriteTransportFactory::new()); /// let o_pr_fact: Box = Box::new(TBinaryOutputProtocolFactory::new()); /// /// let mut server = TServer::new( /// i_tr_fact, /// i_pr_fact, /// o_tr_fact, /// o_pr_fact, /// processor, /// 10 /// ); /// /// // start listening for incoming connections /// match server.listen("127.0.0.1:8080") { /// Ok(_) => println!("listen completed"), /// Err(e) => println!("listen failed with error {:?}", e), /// } /// ``` #[derive(Debug)] pub struct TServer where PRC: TProcessor + Send + Sync + 'static, RTF: TReadTransportFactory + 'static, IPF: TInputProtocolFactory + 'static, WTF: TWriteTransportFactory + 'static, OPF: TOutputProtocolFactory + 'static, { r_trans_factory: RTF, i_proto_factory: IPF, w_trans_factory: WTF, o_proto_factory: OPF, processor: Arc, worker_pool: ThreadPool, } impl TServer where PRC: TProcessor + Send + Sync + 'static, RTF: TReadTransportFactory + 'static, IPF: TInputProtocolFactory + 'static, WTF: TWriteTransportFactory + 'static, OPF: TOutputProtocolFactory + 'static, { /// Create a `TServer`. /// /// Each accepted connection has an input and output half, each of which /// requires a `TTransport` and `TProtocol`. `TServer` uses /// `read_transport_factory` and `input_protocol_factory` to create /// implementations for the input, and `write_transport_factory` and /// `output_protocol_factory` to create implementations for the output. pub fn new( read_transport_factory: RTF, input_protocol_factory: IPF, write_transport_factory: WTF, output_protocol_factory: OPF, processor: PRC, num_workers: usize, ) -> TServer { TServer { r_trans_factory: read_transport_factory, i_proto_factory: input_protocol_factory, w_trans_factory: write_transport_factory, o_proto_factory: output_protocol_factory, processor: Arc::new(processor), worker_pool: ThreadPool::with_name("Thrift service processor".to_owned(), num_workers), } } /// Listen for incoming connections on `listen_address`. /// /// `listen_address` should implement `ToSocketAddrs` trait. /// /// Return `()` if successful. /// /// Return `Err` when the server cannot bind to `listen_address` or there /// is an unrecoverable error. pub fn listen(&mut self, listen_address: A) -> crate::Result<()> { let listener = TcpListener::bind(listen_address)?; for stream in listener.incoming() { match stream { Ok(s) => { s.set_nodelay(true).ok(); let channel = TTcpChannel::with_stream(s); self.handle_stream(channel)?; } Err(e) => { warn!("failed to accept remote connection with error {:?}", e); } } } Err(crate::Error::Application(ApplicationError { kind: ApplicationErrorKind::Unknown, message: "aborted listen loop".into(), })) } /// Listen for incoming connections on `listen_path`. /// /// `listen_path` should implement `AsRef` trait. /// /// Return `()` if successful. /// /// Return `Err` when the server cannot bind to `listen_path` or there /// is an unrecoverable error. #[cfg(unix)] pub fn listen_uds>(&mut self, listen_path: P) -> crate::Result<()> { let listener = UnixListener::bind(listen_path)?; for stream in listener.incoming() { match stream { Ok(s) => { self.handle_stream(s)?; } Err(e) => { warn!( "failed to accept connection via unix domain socket with error {:?}", e ); } } } Err(crate::Error::Application(ApplicationError { kind: ApplicationErrorKind::Unknown, message: "aborted listen loop".into(), })) } fn handle_stream(&mut self, stream: S) -> crate::Result<()> { let (i_prot, o_prot) = self.new_protocols_for_connection(stream)?; let processor = self.processor.clone(); self.worker_pool .execute(move || handle_incoming_connection(processor, i_prot, o_prot)); Ok(()) } fn new_protocols_for_connection( &mut self, stream: S, ) -> crate::Result<( Box, Box, )> { // split it into two - one to be owned by the // input tran/proto and the other by the output let (r_chan, w_chan) = stream.split()?; // input protocol and transport let r_tran = self.r_trans_factory.create(Box::new(r_chan)); let i_prot = self.i_proto_factory.create(r_tran); // output protocol and transport let w_tran = self.w_trans_factory.create(Box::new(w_chan)); let o_prot = self.o_proto_factory.create(w_tran); Ok((i_prot, o_prot)) } } fn handle_incoming_connection( processor: Arc, i_prot: Box, o_prot: Box, ) where PRC: TProcessor, { let mut i_prot = i_prot; let mut o_prot = o_prot; loop { match processor.process(&mut *i_prot, &mut *o_prot) { Ok(()) => {} Err(err) => { match err { crate::Error::Transport(ref transport_err) if transport_err.kind == TransportErrorKind::EndOfFile => {} other => warn!("processor completed with error: {:?}", other), } break; } } } } thrift-0.23.0/lib/rs/src/server/mod.rs0000664000175000017500000001016215165535636020011 0ustar00buildbuild00000000000000// 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. //! Types used to implement a Thrift server. use crate::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol}; use crate::{ApplicationError, ApplicationErrorKind}; mod multiplexed; mod threaded; pub use self::multiplexed::TMultiplexedProcessor; pub use self::threaded::TServer; /// Handles incoming Thrift messages and dispatches them to the user-defined /// handler functions. /// /// An implementation is auto-generated for each Thrift service. When used by a /// server (for example, a `TSimpleServer`), it will demux incoming service /// calls and invoke the corresponding user-defined handler function. /// /// # Examples /// /// Create and start a server using the auto-generated `TProcessor` for /// a Thrift service `SimpleService`. /// /// ```no_run /// use thrift::protocol::{TInputProtocol, TOutputProtocol}; /// use thrift::server::TProcessor; /// /// // /// // auto-generated /// // /// /// // processor for `SimpleService` /// struct SimpleServiceSyncProcessor; /// impl SimpleServiceSyncProcessor { /// fn new(processor: H) -> SimpleServiceSyncProcessor { /// unimplemented!(); /// } /// } /// /// // `TProcessor` implementation for `SimpleService` /// impl TProcessor for SimpleServiceSyncProcessor { /// fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol) -> thrift::Result<()> { /// unimplemented!(); /// } /// } /// /// // service functions for SimpleService /// trait SimpleServiceSyncHandler { /// fn service_call(&self) -> thrift::Result<()>; /// } /// /// // /// // user-code follows /// // /// /// // define a handler that will be invoked when `service_call` is received /// struct SimpleServiceHandlerImpl; /// impl SimpleServiceSyncHandler for SimpleServiceHandlerImpl { /// fn service_call(&self) -> thrift::Result<()> { /// unimplemented!(); /// } /// } /// /// // instantiate the processor /// let processor = SimpleServiceSyncProcessor::new(SimpleServiceHandlerImpl {}); /// /// // at this point you can pass the processor to the server /// // let server = TServer::new(..., processor); /// ``` pub trait TProcessor { /// Process a Thrift service call. /// /// Reads arguments from `i`, executes the user's handler code, and writes /// the response to `o`. /// /// Returns `()` if the handler was executed; `Err` otherwise. fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol) -> crate::Result<()>; } /// Convenience function used in generated `TProcessor` implementations to /// return an `ApplicationError` if thrift message processing failed. pub fn handle_process_result( msg_ident: &TMessageIdentifier, res: crate::Result<()>, o_prot: &mut dyn TOutputProtocol, ) -> crate::Result<()> { if let Err(e) = res { let e = match e { crate::Error::Application(a) => a, _ => ApplicationError::new(ApplicationErrorKind::Unknown, format!("{:?}", e)), }; let ident = TMessageIdentifier::new( msg_ident.name.clone(), TMessageType::Exception, msg_ident.sequence_number, ); o_prot.write_message_begin(&ident)?; crate::Error::write_application_error_to_out_protocol(&e, o_prot)?; o_prot.write_message_end()?; o_prot.flush() } else { Ok(()) } } thrift-0.23.0/lib/rs/src/transport/0000775000175000017500000000000015167543515017407 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/src/transport/socket.rs0000664000175000017500000001251215167543515021246 0ustar00buildbuild00000000000000// 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. use std::convert::From; use std::io; use std::io::{ErrorKind, Read, Write}; use std::net::{Shutdown, TcpStream, ToSocketAddrs}; #[cfg(unix)] use std::os::unix::net::UnixStream; use super::{ReadHalf, TIoChannel, WriteHalf}; use crate::{new_transport_error, TransportErrorKind}; /// Bidirectional TCP/IP channel. /// /// # Examples /// /// Create a `TTcpChannel`. /// /// ```no_run /// use std::io::{Read, Write}; /// use thrift::transport::TTcpChannel; /// /// let mut c = TTcpChannel::new(); /// c.open("localhost:9090").unwrap(); /// /// let mut buf = vec![0u8; 4]; /// c.read(&mut buf).unwrap(); /// c.write(&vec![0, 1, 2]).unwrap(); /// ``` /// /// Create a `TTcpChannel` by wrapping an existing `TcpStream`. /// /// ```no_run /// use std::io::{Read, Write}; /// use std::net::TcpStream; /// use thrift::transport::TTcpChannel; /// /// let stream = TcpStream::connect("127.0.0.1:9189").unwrap(); /// stream.set_nodelay(true).unwrap(); /// /// // no need to call c.open() since we've already connected above /// let mut c = TTcpChannel::with_stream(stream); /// /// let mut buf = vec![0u8; 4]; /// c.read(&mut buf).unwrap(); /// c.write(&vec![0, 1, 2]).unwrap(); /// ``` #[derive(Debug, Default)] pub struct TTcpChannel { stream: Option, } impl TTcpChannel { /// Create an uninitialized `TTcpChannel`. /// /// The returned instance must be opened using `TTcpChannel::open(...)` /// before it can be used. pub fn new() -> TTcpChannel { TTcpChannel { stream: None } } /// Create a `TTcpChannel` that wraps an existing `TcpStream`. /// /// The passed-in stream is assumed to have been opened before being wrapped /// by the created `TTcpChannel` instance. pub fn with_stream(stream: TcpStream) -> TTcpChannel { TTcpChannel { stream: Some(stream), } } /// Connect to `remote_address`, which should implement `ToSocketAddrs` trait. pub fn open(&mut self, remote_address: A) -> crate::Result<()> { if self.stream.is_some() { Err(new_transport_error( TransportErrorKind::AlreadyOpen, "tcp connection previously opened", )) } else { match TcpStream::connect(&remote_address) { Ok(s) => { s.set_nodelay(true)?; self.stream = Some(s); Ok(()) } Err(e) => Err(From::from(e)), } } } /// Shut down this channel. /// /// Both send and receive halves are closed, and this instance can no /// longer be used to communicate with another endpoint. pub fn close(&mut self) -> crate::Result<()> { self.if_set(|s| s.shutdown(Shutdown::Both)) .map_err(From::from) } fn if_set(&mut self, mut stream_operation: F) -> io::Result where F: FnMut(&mut TcpStream) -> io::Result, { if let Some(ref mut s) = self.stream { stream_operation(s) } else { Err(io::Error::new( ErrorKind::NotConnected, "tcp endpoint not connected", )) } } } impl TIoChannel for TTcpChannel { fn split(self) -> crate::Result<(ReadHalf, WriteHalf)> where Self: Sized, { let mut s = self; s.stream .as_mut() .and_then(|s| s.try_clone().ok()) .map(|cloned| { let read_half = ReadHalf::new(TTcpChannel { stream: s.stream.take(), }); let write_half = WriteHalf::new(TTcpChannel { stream: Some(cloned), }); (read_half, write_half) }) .ok_or_else(|| { new_transport_error( TransportErrorKind::Unknown, "cannot clone underlying tcp stream", ) }) } } impl Read for TTcpChannel { fn read(&mut self, b: &mut [u8]) -> io::Result { self.if_set(|s| s.read(b)) } } impl Write for TTcpChannel { fn write(&mut self, b: &[u8]) -> io::Result { self.if_set(|s| s.write(b)) } fn flush(&mut self) -> io::Result<()> { self.if_set(|s| s.flush()) } } #[cfg(unix)] impl TIoChannel for UnixStream { fn split(self) -> crate::Result<(ReadHalf, WriteHalf)> where Self: Sized, { let socket_rx = self.try_clone().unwrap(); Ok((ReadHalf::new(self), WriteHalf::new(socket_rx))) } } thrift-0.23.0/lib/rs/src/transport/framed.rs0000664000175000017500000003552515165535636021230 0ustar00buildbuild00000000000000// 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. use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use std::cmp; use std::io; use std::io::{Read, Write}; use super::{TReadTransport, TReadTransportFactory, TWriteTransport, TWriteTransportFactory}; use crate::TConfiguration; /// Default capacity of the read buffer in bytes. const READ_CAPACITY: usize = 4096; /// Default capacity of the write buffer in bytes. const WRITE_CAPACITY: usize = 4096; /// Transport that reads framed messages. /// /// A `TFramedReadTransport` maintains a fixed-size internal read buffer. /// On a call to `TFramedReadTransport::read(...)` one full message - both /// fixed-length header and bytes - is read from the wrapped channel and /// buffered. Subsequent read calls are serviced from the internal buffer /// until it is exhausted, at which point the next full message is read /// from the wrapped channel. /// /// # Examples /// /// Create and use a `TFramedReadTransport`. /// /// ```no_run /// use std::io::Read; /// use thrift::transport::{TFramedReadTransport, TTcpChannel}; /// /// let mut c = TTcpChannel::new(); /// c.open("localhost:9090").unwrap(); /// /// let mut t = TFramedReadTransport::new(c); /// /// t.read(&mut vec![0u8; 1]).unwrap(); /// ``` #[derive(Debug)] pub struct TFramedReadTransport where C: Read, { buf: Vec, pos: usize, cap: usize, chan: C, config: TConfiguration, } impl TFramedReadTransport where C: Read, { /// Create a `TFramedReadTransport` with a default-sized /// internal read buffer that wraps the given `TIoChannel`. pub fn new(channel: C) -> TFramedReadTransport { TFramedReadTransport::with_capacity(READ_CAPACITY, channel) } /// Create a `TFramedTransport` with an internal read buffer /// of size `read_capacity` that wraps the given `TIoChannel`. pub fn with_capacity(read_capacity: usize, channel: C) -> TFramedReadTransport { TFramedReadTransport { buf: vec![0; read_capacity], // FIXME: do I actually have to do this? pos: 0, cap: 0, chan: channel, config: TConfiguration::default(), } } } impl Read for TFramedReadTransport where C: Read, { fn read(&mut self, b: &mut [u8]) -> io::Result { if self.cap - self.pos == 0 { let frame_size_bytes = self.chan.read_i32::()?; if frame_size_bytes < 0 { return Err(io::Error::new( io::ErrorKind::InvalidData, format!("Negative frame size: {}", frame_size_bytes), )); } let message_size = frame_size_bytes as usize; if let Some(max_frame) = self.config.max_frame_size() { if message_size > max_frame { return Err(io::Error::new( io::ErrorKind::InvalidData, format!( "Frame size {} exceeds maximum allowed size of {}", message_size, max_frame ), )); } } let buf_capacity = cmp::max(message_size, READ_CAPACITY); self.buf.resize(buf_capacity, 0); self.chan.read_exact(&mut self.buf[..message_size])?; self.cap = message_size; self.pos = 0; } let nread = cmp::min(b.len(), self.cap - self.pos); b[..nread].clone_from_slice(&self.buf[self.pos..self.pos + nread]); self.pos += nread; Ok(nread) } } /// Factory for creating instances of `TFramedReadTransport`. #[derive(Default)] pub struct TFramedReadTransportFactory; impl TFramedReadTransportFactory { pub fn new() -> TFramedReadTransportFactory { TFramedReadTransportFactory {} } } impl TReadTransportFactory for TFramedReadTransportFactory { /// Create a `TFramedReadTransport`. fn create(&self, channel: Box) -> Box { Box::new(TFramedReadTransport::new(channel)) } } /// Transport that writes framed messages. /// /// A `TFramedWriteTransport` maintains a fixed-size internal write buffer. All /// writes are made to this buffer and are sent to the wrapped channel only /// when `TFramedWriteTransport::flush()` is called. On a flush a fixed-length /// header with a count of the buffered bytes is written, followed by the bytes /// themselves. /// /// # Examples /// /// Create and use a `TFramedWriteTransport`. /// /// ```no_run /// use std::io::Write; /// use thrift::transport::{TFramedWriteTransport, TTcpChannel}; /// /// let mut c = TTcpChannel::new(); /// c.open("localhost:9090").unwrap(); /// /// let mut t = TFramedWriteTransport::new(c); /// /// t.write(&[0x00]).unwrap(); /// t.flush().unwrap(); /// ``` #[derive(Debug)] pub struct TFramedWriteTransport where C: Write, { buf: Vec, channel: C, } impl TFramedWriteTransport where C: Write, { /// Create a `TFramedWriteTransport` with default-sized internal /// write buffer that wraps the given `TIoChannel`. pub fn new(channel: C) -> TFramedWriteTransport { TFramedWriteTransport::with_capacity(WRITE_CAPACITY, channel) } /// Create a `TFramedWriteTransport` with an internal write buffer /// of size `write_capacity` that wraps the given `TIoChannel`. pub fn with_capacity(write_capacity: usize, channel: C) -> TFramedWriteTransport { TFramedWriteTransport { buf: Vec::with_capacity(write_capacity), channel, } } } impl Write for TFramedWriteTransport where C: Write, { fn write(&mut self, b: &[u8]) -> io::Result { let current_capacity = self.buf.capacity(); let available_space = current_capacity - self.buf.len(); if b.len() > available_space { let additional_space = cmp::max(b.len() - available_space, current_capacity); self.buf.reserve(additional_space); } self.buf.extend_from_slice(b); Ok(b.len()) } fn flush(&mut self) -> io::Result<()> { let message_size = self.buf.len(); if let 0 = message_size { return Ok(()); } else { self.channel.write_i32::(message_size as i32)?; } // will spin if the underlying channel can't be written to let mut byte_index = 0; while byte_index < message_size { let nwrite = self.channel.write(&self.buf[byte_index..message_size])?; byte_index = cmp::min(byte_index + nwrite, message_size); } let buf_capacity = cmp::min(self.buf.capacity(), WRITE_CAPACITY); self.buf.resize(buf_capacity, 0); self.buf.clear(); self.channel.flush() } } /// Factory for creating instances of `TFramedWriteTransport`. #[derive(Default)] pub struct TFramedWriteTransportFactory; impl TFramedWriteTransportFactory { pub fn new() -> TFramedWriteTransportFactory { TFramedWriteTransportFactory {} } } impl TWriteTransportFactory for TFramedWriteTransportFactory { /// Create a `TFramedWriteTransport`. fn create(&self, channel: Box) -> Box { Box::new(TFramedWriteTransport::new(channel)) } } #[cfg(test)] mod tests { use super::*; use crate::transport::mem::TBufferChannel; // FIXME: test a forced reserve #[test] fn must_read_message_smaller_than_initial_buffer_size() { let c = TBufferChannel::with_capacity(10, 10); let mut t = TFramedReadTransport::with_capacity(8, c); t.chan.set_readable_bytes(&[ 0x00, 0x00, 0x00, 0x04, /* message size */ 0x00, 0x01, 0x02, 0x03, /* message body */ ]); let mut buf = vec![0; 8]; // we've read exactly 4 bytes assert_eq!(t.read(&mut buf).unwrap(), 4); assert_eq!(&buf[..4], &[0x00, 0x01, 0x02, 0x03]); } #[test] fn must_read_message_greater_than_initial_buffer_size() { let c = TBufferChannel::with_capacity(10, 10); let mut t = TFramedReadTransport::with_capacity(2, c); t.chan.set_readable_bytes(&[ 0x00, 0x00, 0x00, 0x04, /* message size */ 0x00, 0x01, 0x02, 0x03, /* message body */ ]); let mut buf = vec![0; 8]; // we've read exactly 4 bytes assert_eq!(t.read(&mut buf).unwrap(), 4); assert_eq!(&buf[..4], &[0x00, 0x01, 0x02, 0x03]); } #[test] fn must_read_multiple_messages_in_sequence_correctly() { let c = TBufferChannel::with_capacity(10, 10); let mut t = TFramedReadTransport::with_capacity(2, c); // // 1st message // t.chan.set_readable_bytes(&[ 0x00, 0x00, 0x00, 0x04, /* message size */ 0x00, 0x01, 0x02, 0x03, /* message body */ ]); let mut buf = vec![0; 8]; // we've read exactly 4 bytes assert_eq!(t.read(&mut buf).unwrap(), 4); assert_eq!(&buf, &[0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00]); // // 2nd message // t.chan.set_readable_bytes(&[ 0x00, 0x00, 0x00, 0x01, /* message size */ 0x04, /* message body */ ]); let mut buf = vec![0; 8]; // we've read exactly 1 byte assert_eq!(t.read(&mut buf).unwrap(), 1); assert_eq!(&buf, &[0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); } #[test] fn must_write_message_smaller_than_buffer_size() { let mem = TBufferChannel::with_capacity(0, 0); let mut t = TFramedWriteTransport::with_capacity(20, mem); let b = vec![0; 10]; // should have written 10 bytes assert_eq!(t.write(&b).unwrap(), 10); } #[test] fn must_return_zero_if_caller_calls_write_with_empty_buffer() { let mem = TBufferChannel::with_capacity(0, 10); let mut t = TFramedWriteTransport::with_capacity(10, mem); let expected: [u8; 0] = []; assert_eq!(t.write(&[]).unwrap(), 0); assert_eq_transport_written_bytes!(t, expected); } #[test] fn must_write_to_inner_transport_on_flush() { let mem = TBufferChannel::with_capacity(10, 10); let mut t = TFramedWriteTransport::new(mem); let b: [u8; 5] = [0x00, 0x01, 0x02, 0x03, 0x04]; assert_eq!(t.write(&b).unwrap(), 5); assert_eq_transport_num_written_bytes!(t, 0); assert!(t.flush().is_ok()); let expected_bytes = [ 0x00, 0x00, 0x00, 0x05, /* message size */ 0x00, 0x01, 0x02, 0x03, 0x04, /* message body */ ]; assert_eq_transport_written_bytes!(t, expected_bytes); } #[test] fn must_write_message_greater_than_buffer_size_00() { let mem = TBufferChannel::with_capacity(0, 10); // IMPORTANT: DO **NOT** CHANGE THE WRITE_CAPACITY OR THE NUMBER OF BYTES TO BE WRITTEN! // these lengths were chosen to be just long enough // that doubling the capacity is a **worse** choice than // simply resizing the buffer to b.len() let mut t = TFramedWriteTransport::with_capacity(1, mem); let b = [0x00, 0x01, 0x02]; // should have written 3 bytes assert_eq!(t.write(&b).unwrap(), 3); assert_eq_transport_num_written_bytes!(t, 0); assert!(t.flush().is_ok()); let expected_bytes = [ 0x00, 0x00, 0x00, 0x03, /* message size */ 0x00, 0x01, 0x02, /* message body */ ]; assert_eq_transport_written_bytes!(t, expected_bytes); } #[test] fn must_write_message_greater_than_buffer_size_01() { let mem = TBufferChannel::with_capacity(0, 10); // IMPORTANT: DO **NOT** CHANGE THE WRITE_CAPACITY OR THE NUMBER OF BYTES TO BE WRITTEN! // these lengths were chosen to be just long enough // that doubling the capacity is a **better** choice than // simply resizing the buffer to b.len() let mut t = TFramedWriteTransport::with_capacity(2, mem); let b = [0x00, 0x01, 0x02]; // should have written 3 bytes assert_eq!(t.write(&b).unwrap(), 3); assert_eq_transport_num_written_bytes!(t, 0); assert!(t.flush().is_ok()); let expected_bytes = [ 0x00, 0x00, 0x00, 0x03, /* message size */ 0x00, 0x01, 0x02, /* message body */ ]; assert_eq_transport_written_bytes!(t, expected_bytes); } #[test] fn must_return_error_if_nothing_can_be_written_to_inner_transport_on_flush() { let mem = TBufferChannel::with_capacity(0, 0); let mut t = TFramedWriteTransport::with_capacity(1, mem); let b = vec![0; 10]; // should have written 10 bytes assert_eq!(t.write(&b).unwrap(), 10); // let's flush let r = t.flush(); // this time we'll error out because the flush can't write to the underlying channel assert!(r.is_err()); } #[test] fn must_write_successfully_after_flush() { // IMPORTANT: write capacity *MUST* be greater // than message sizes used in this test + 4-byte frame header let mem = TBufferChannel::with_capacity(0, 10); let mut t = TFramedWriteTransport::with_capacity(5, mem); // write and flush let first_message: [u8; 5] = [0x00, 0x01, 0x02, 0x03, 0x04]; assert_eq!(t.write(&first_message).unwrap(), 5); assert!(t.flush().is_ok()); let mut expected = Vec::new(); expected.write_all(&[0x00, 0x00, 0x00, 0x05]).unwrap(); // message size expected.extend_from_slice(&first_message); // check the flushed bytes assert_eq!(t.channel.write_bytes(), expected); // reset our underlying transport t.channel.empty_write_buffer(); let second_message: [u8; 3] = [0x05, 0x06, 0x07]; assert_eq!(t.write(&second_message).unwrap(), 3); assert!(t.flush().is_ok()); expected.clear(); expected.write_all(&[0x00, 0x00, 0x00, 0x03]).unwrap(); // message size expected.extend_from_slice(&second_message); // check the flushed bytes assert_eq!(t.channel.write_bytes(), expected); } } thrift-0.23.0/lib/rs/src/transport/mem.rs0000664000175000017500000003307015165535636020541 0ustar00buildbuild00000000000000// 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. use std::cmp; use std::io; use std::sync::{Arc, Mutex}; use super::{ReadHalf, TIoChannel, WriteHalf}; /// In-memory read and write channel with fixed-size read and write buffers. /// /// On a `write` bytes are written to the internal write buffer. Writes are no /// longer accepted once this buffer is full. Callers must `empty_write_buffer()` /// before subsequent writes are accepted. /// /// You can set readable bytes in the internal read buffer by filling it with /// `set_readable_bytes(...)`. Callers can then read until the buffer is /// depleted. No further reads are accepted until the internal read buffer is /// replenished again. #[derive(Clone, Debug)] pub struct TBufferChannel { read: Arc>, write: Arc>, } #[derive(Debug)] struct ReadData { buf: Box<[u8]>, pos: usize, idx: usize, cap: usize, } #[derive(Debug)] struct WriteData { buf: Box<[u8]>, pos: usize, cap: usize, } impl TBufferChannel { /// Constructs a new, empty `TBufferChannel` with the given /// read buffer capacity and write buffer capacity. pub fn with_capacity(read_capacity: usize, write_capacity: usize) -> TBufferChannel { TBufferChannel { read: Arc::new(Mutex::new(ReadData { buf: vec![0; read_capacity].into_boxed_slice(), idx: 0, pos: 0, cap: read_capacity, })), write: Arc::new(Mutex::new(WriteData { buf: vec![0; write_capacity].into_boxed_slice(), pos: 0, cap: write_capacity, })), } } /// Return a copy of the bytes held by the internal read buffer. /// Returns an empty vector if no readable bytes are present. pub fn read_bytes(&self) -> Vec { let rdata = self.read.as_ref().lock().unwrap(); let mut buf = vec![0u8; rdata.idx]; buf.copy_from_slice(&rdata.buf[..rdata.idx]); buf } // FIXME: do I really need this API call? // FIXME: should this simply reset to the last set of readable bytes? /// Reset the number of readable bytes to zero. /// /// Subsequent calls to `read` will return nothing. pub fn empty_read_buffer(&mut self) { let mut rdata = self.read.as_ref().lock().unwrap(); rdata.pos = 0; rdata.idx = 0; } /// Copy bytes from the source buffer `buf` into the internal read buffer, /// overwriting any existing bytes. Returns the number of bytes copied, /// which is `min(buf.len(), internal_read_buf.len())`. pub fn set_readable_bytes(&mut self, buf: &[u8]) -> usize { self.empty_read_buffer(); let mut rdata = self.read.as_ref().lock().unwrap(); let max_bytes = cmp::min(rdata.cap, buf.len()); rdata.buf[..max_bytes].clone_from_slice(&buf[..max_bytes]); rdata.idx = max_bytes; max_bytes } /// Return a copy of the bytes held by the internal write buffer. /// Returns an empty vector if no bytes were written. pub fn write_bytes(&self) -> Vec { let wdata = self.write.as_ref().lock().unwrap(); let mut buf = vec![0u8; wdata.pos]; buf.copy_from_slice(&wdata.buf[..wdata.pos]); buf } /// Resets the internal write buffer, making it seem like no bytes were /// written. Calling `write_buffer` after this returns an empty vector. pub fn empty_write_buffer(&mut self) { let mut wdata = self.write.as_ref().lock().unwrap(); wdata.pos = 0; } /// Overwrites the contents of the read buffer with the contents of the /// write buffer. The write buffer is emptied after this operation. pub fn copy_write_buffer_to_read_buffer(&mut self) { // FIXME: redo this entire method let buf = { let wdata = self.write.as_ref().lock().unwrap(); let b = &wdata.buf[..wdata.pos]; let mut b_ret = vec![0; b.len()]; b_ret.copy_from_slice(b); b_ret }; let bytes_copied = self.set_readable_bytes(&buf); assert_eq!(bytes_copied, buf.len()); self.empty_write_buffer(); } } impl TIoChannel for TBufferChannel { fn split(self) -> crate::Result<(ReadHalf, WriteHalf)> where Self: Sized, { Ok(( ReadHalf { handle: TBufferChannel { read: self.read.clone(), write: self.write.clone(), }, }, WriteHalf { handle: TBufferChannel { read: self.read.clone(), // NOTE: not cloning here, since this is the last statement // in this method and `write` can take ownership of `self.write` write: self.write, }, }, )) } } impl io::Read for TBufferChannel { fn read(&mut self, buf: &mut [u8]) -> io::Result { let mut rdata = self.read.as_ref().lock().unwrap(); let nread = cmp::min(buf.len(), rdata.idx - rdata.pos); buf[..nread].clone_from_slice(&rdata.buf[rdata.pos..rdata.pos + nread]); rdata.pos += nread; Ok(nread) } } impl io::Write for TBufferChannel { fn write(&mut self, buf: &[u8]) -> io::Result { let mut wdata = self.write.as_ref().lock().unwrap(); let nwrite = cmp::min(buf.len(), wdata.cap - wdata.pos); let (start, end) = (wdata.pos, wdata.pos + nwrite); wdata.buf[start..end].clone_from_slice(&buf[..nwrite]); wdata.pos += nwrite; Ok(nwrite) } fn flush(&mut self) -> io::Result<()> { Ok(()) // nothing to do on flush } } #[cfg(test)] mod tests { use std::io::{Read, Write}; use super::TBufferChannel; #[test] fn must_empty_write_buffer() { let mut t = TBufferChannel::with_capacity(0, 1); let bytes_to_write: [u8; 1] = [0x01]; let result = t.write(&bytes_to_write); assert_eq!(result.unwrap(), 1); assert_eq!(&t.write_bytes(), &bytes_to_write); t.empty_write_buffer(); assert_eq!(t.write_bytes().len(), 0); } #[test] fn must_accept_writes_after_buffer_emptied() { let mut t = TBufferChannel::with_capacity(0, 2); let bytes_to_write: [u8; 2] = [0x01, 0x02]; // first write (all bytes written) let result = t.write(&bytes_to_write); assert_eq!(result.unwrap(), 2); assert_eq!(&t.write_bytes(), &bytes_to_write); // try write again (nothing should be written) let result = t.write(&bytes_to_write); assert_eq!(result.unwrap(), 0); assert_eq!(&t.write_bytes(), &bytes_to_write); // still the same as before // now reset the buffer t.empty_write_buffer(); assert_eq!(t.write_bytes().len(), 0); // now try write again - the write should succeed let result = t.write(&bytes_to_write); assert_eq!(result.unwrap(), 2); assert_eq!(&t.write_bytes(), &bytes_to_write); } #[test] fn must_accept_multiple_writes_until_buffer_is_full() { let mut t = TBufferChannel::with_capacity(0, 10); // first write (all bytes written) let bytes_to_write_0: [u8; 2] = [0x01, 0x41]; let write_0_result = t.write(&bytes_to_write_0); assert_eq!(write_0_result.unwrap(), 2); assert_eq!(t.write_bytes(), &bytes_to_write_0); // second write (all bytes written, starting at index 2) let bytes_to_write_1: [u8; 7] = [0x24, 0x41, 0x32, 0x33, 0x11, 0x98, 0xAF]; let write_1_result = t.write(&bytes_to_write_1); assert_eq!(write_1_result.unwrap(), 7); assert_eq!(&t.write_bytes()[2..], &bytes_to_write_1); // third write (only 1 byte written - that's all we have space for) let bytes_to_write_2: [u8; 3] = [0xBF, 0xDA, 0x98]; let write_2_result = t.write(&bytes_to_write_2); assert_eq!(write_2_result.unwrap(), 1); assert_eq!(&t.write_bytes()[9..], &bytes_to_write_2[0..1]); // how does this syntax work?! // fourth write (no writes are accepted) let bytes_to_write_3: [u8; 3] = [0xBF, 0xAA, 0xFD]; let write_3_result = t.write(&bytes_to_write_3); assert_eq!(write_3_result.unwrap(), 0); // check the full write buffer let mut expected: Vec = Vec::with_capacity(10); expected.extend_from_slice(&bytes_to_write_0); expected.extend_from_slice(&bytes_to_write_1); expected.extend_from_slice(&bytes_to_write_2[0..1]); assert_eq!(t.write_bytes(), &expected[..]); } #[test] fn must_empty_read_buffer() { let mut t = TBufferChannel::with_capacity(1, 0); let bytes_to_read: [u8; 1] = [0x01]; let result = t.set_readable_bytes(&bytes_to_read); assert_eq!(result, 1); assert_eq!(t.read_bytes(), &bytes_to_read); t.empty_read_buffer(); assert_eq!(t.read_bytes().len(), 0); } #[test] fn must_allow_readable_bytes_to_be_set_after_read_buffer_emptied() { let mut t = TBufferChannel::with_capacity(1, 0); let bytes_to_read_0: [u8; 1] = [0x01]; let result = t.set_readable_bytes(&bytes_to_read_0); assert_eq!(result, 1); assert_eq!(t.read_bytes(), &bytes_to_read_0); t.empty_read_buffer(); assert_eq!(t.read_bytes().len(), 0); let bytes_to_read_1: [u8; 1] = [0x02]; let result = t.set_readable_bytes(&bytes_to_read_1); assert_eq!(result, 1); assert_eq!(t.read_bytes(), &bytes_to_read_1); } #[test] fn must_accept_multiple_reads_until_all_bytes_read() { let mut t = TBufferChannel::with_capacity(10, 0); let readable_bytes: [u8; 10] = [0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0x00, 0x1A, 0x2B, 0x3C, 0x4D]; // check that we're able to set the bytes to be read let result = t.set_readable_bytes(&readable_bytes); assert_eq!(result, 10); assert_eq!(t.read_bytes(), &readable_bytes); // first read let mut read_buf_0 = vec![0; 5]; let read_result = t.read(&mut read_buf_0); assert_eq!(read_result.unwrap(), 5); assert_eq!(read_buf_0.as_slice(), &(readable_bytes[0..5])); // second read let mut read_buf_1 = vec![0; 4]; let read_result = t.read(&mut read_buf_1); assert_eq!(read_result.unwrap(), 4); assert_eq!(read_buf_1.as_slice(), &(readable_bytes[5..9])); // third read (only 1 byte remains to be read) let mut read_buf_2 = vec![0; 3]; let read_result = t.read(&mut read_buf_2); assert_eq!(read_result.unwrap(), 1); read_buf_2.truncate(1); // FIXME: does the caller have to do this? assert_eq!(read_buf_2.as_slice(), &(readable_bytes[9..])); // fourth read (nothing should be readable) let mut read_buf_3 = vec![0; 10]; let read_result = t.read(&mut read_buf_3); assert_eq!(read_result.unwrap(), 0); read_buf_3.truncate(0); // check that all the bytes we received match the original (again!) let mut bytes_read = Vec::with_capacity(10); bytes_read.extend_from_slice(&read_buf_0); bytes_read.extend_from_slice(&read_buf_1); bytes_read.extend_from_slice(&read_buf_2); bytes_read.extend_from_slice(&read_buf_3); assert_eq!(&bytes_read, &readable_bytes); } #[test] fn must_allow_reads_to_succeed_after_read_buffer_replenished() { let mut t = TBufferChannel::with_capacity(3, 0); let readable_bytes_0: [u8; 3] = [0x02, 0xAB, 0x33]; // check that we're able to set the bytes to be read let result = t.set_readable_bytes(&readable_bytes_0); assert_eq!(result, 3); assert_eq!(t.read_bytes(), &readable_bytes_0); let mut read_buf = vec![0; 4]; // drain the read buffer let read_result = t.read(&mut read_buf); assert_eq!(read_result.unwrap(), 3); assert_eq!(t.read_bytes(), &read_buf[0..3]); // check that a subsequent read fails let read_result = t.read(&mut read_buf); assert_eq!(read_result.unwrap(), 0); // we don't modify the read buffer on failure let mut expected_bytes = Vec::with_capacity(4); expected_bytes.extend_from_slice(&readable_bytes_0); expected_bytes.push(0x00); assert_eq!(&read_buf, &expected_bytes); // replenish the read buffer again let readable_bytes_1: [u8; 2] = [0x91, 0xAA]; // check that we're able to set the bytes to be read let result = t.set_readable_bytes(&readable_bytes_1); assert_eq!(result, 2); assert_eq!(t.read_bytes(), &readable_bytes_1); // read again let read_result = t.read(&mut read_buf); assert_eq!(read_result.unwrap(), 2); assert_eq!(t.read_bytes(), &read_buf[0..2]); } } thrift-0.23.0/lib/rs/src/transport/buffered.rs0000664000175000017500000003521015165535636021543 0ustar00buildbuild00000000000000// 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. use std::cmp; use std::io; use std::io::{Read, Write}; use super::{TReadTransport, TReadTransportFactory, TWriteTransport, TWriteTransportFactory}; /// Default capacity of the read buffer in bytes. const READ_CAPACITY: usize = 4096; /// Default capacity of the write buffer in bytes.. const WRITE_CAPACITY: usize = 4096; /// Transport that reads messages via an internal buffer. /// /// A `TBufferedReadTransport` maintains a fixed-size internal read buffer. /// On a call to `TBufferedReadTransport::read(...)` one full message - both /// fixed-length header and bytes - is read from the wrapped channel and buffered. /// Subsequent read calls are serviced from the internal buffer until it is /// exhausted, at which point the next full message is read from the wrapped /// channel. /// /// # Examples /// /// Create and use a `TBufferedReadTransport`. /// /// ```no_run /// use std::io::Read; /// use thrift::transport::{TBufferedReadTransport, TTcpChannel}; /// /// let mut c = TTcpChannel::new(); /// c.open("localhost:9090").unwrap(); /// /// let mut t = TBufferedReadTransport::new(c); /// /// t.read(&mut vec![0u8; 1]).unwrap(); /// ``` #[derive(Debug)] pub struct TBufferedReadTransport where C: Read, { buf: Box<[u8]>, pos: usize, cap: usize, chan: C, } impl TBufferedReadTransport where C: Read, { /// Create a `TBufferedTransport` with default-sized internal read and /// write buffers that wraps the given `TIoChannel`. pub fn new(channel: C) -> TBufferedReadTransport { TBufferedReadTransport::with_capacity(READ_CAPACITY, channel) } /// Create a `TBufferedTransport` with an internal read buffer of size /// `read_capacity` and an internal write buffer of size /// `write_capacity` that wraps the given `TIoChannel`. pub fn with_capacity(read_capacity: usize, channel: C) -> TBufferedReadTransport { TBufferedReadTransport { buf: vec![0; read_capacity].into_boxed_slice(), pos: 0, cap: 0, chan: channel, } } fn get_bytes(&mut self) -> io::Result<&[u8]> { if self.cap - self.pos == 0 { self.pos = 0; self.cap = self.chan.read(&mut self.buf)?; } Ok(&self.buf[self.pos..self.cap]) } fn consume(&mut self, consumed: usize) { // TODO: was a bug here += <-- test somehow self.pos = cmp::min(self.cap, self.pos + consumed); } } impl Read for TBufferedReadTransport where C: Read, { fn read(&mut self, buf: &mut [u8]) -> io::Result { let mut bytes_read = 0; loop { let nread = { let avail_bytes = self.get_bytes()?; let avail_space = buf.len() - bytes_read; let nread = cmp::min(avail_space, avail_bytes.len()); buf[bytes_read..(bytes_read + nread)].copy_from_slice(&avail_bytes[..nread]); nread }; self.consume(nread); bytes_read += nread; if bytes_read == buf.len() || nread == 0 { break; } } Ok(bytes_read) } } /// Factory for creating instances of `TBufferedReadTransport`. #[derive(Default)] pub struct TBufferedReadTransportFactory; impl TBufferedReadTransportFactory { pub fn new() -> TBufferedReadTransportFactory { TBufferedReadTransportFactory {} } } impl TReadTransportFactory for TBufferedReadTransportFactory { /// Create a `TBufferedReadTransport`. fn create(&self, channel: Box) -> Box { Box::new(TBufferedReadTransport::new(channel)) } } /// Transport that writes messages via an internal buffer. /// /// A `TBufferedWriteTransport` maintains a fixed-size internal write buffer. /// All writes are made to this buffer and are sent to the wrapped channel only /// when `TBufferedWriteTransport::flush()` is called. On a flush a fixed-length /// header with a count of the buffered bytes is written, followed by the bytes /// themselves. /// /// # Examples /// /// Create and use a `TBufferedWriteTransport`. /// /// ```no_run /// use std::io::Write; /// use thrift::transport::{TBufferedWriteTransport, TTcpChannel}; /// /// let mut c = TTcpChannel::new(); /// c.open("localhost:9090").unwrap(); /// /// let mut t = TBufferedWriteTransport::new(c); /// /// t.write(&[0x00]).unwrap(); /// t.flush().unwrap(); /// ``` #[derive(Debug)] pub struct TBufferedWriteTransport where C: Write, { buf: Vec, cap: usize, channel: C, } impl TBufferedWriteTransport where C: Write, { /// Create a `TBufferedTransport` with default-sized internal read and /// write buffers that wraps the given `TIoChannel`. pub fn new(channel: C) -> TBufferedWriteTransport { TBufferedWriteTransport::with_capacity(WRITE_CAPACITY, channel) } /// Create a `TBufferedTransport` with an internal read buffer of size /// `read_capacity` and an internal write buffer of size /// `write_capacity` that wraps the given `TIoChannel`. pub fn with_capacity(write_capacity: usize, channel: C) -> TBufferedWriteTransport { assert!( write_capacity > 0, "write buffer size must be a positive integer" ); TBufferedWriteTransport { buf: Vec::with_capacity(write_capacity), cap: write_capacity, channel, } } } impl Write for TBufferedWriteTransport where C: Write, { fn write(&mut self, buf: &[u8]) -> io::Result { if !buf.is_empty() { let mut avail_bytes; loop { avail_bytes = cmp::min(buf.len(), self.cap - self.buf.len()); if avail_bytes == 0 { self.flush()?; } else { break; } } let avail_bytes = avail_bytes; self.buf.extend_from_slice(&buf[..avail_bytes]); assert!(self.buf.len() <= self.cap, "copy overflowed buffer"); Ok(avail_bytes) } else { Ok(0) } } fn flush(&mut self) -> io::Result<()> { self.channel.write_all(&self.buf)?; self.channel.flush()?; self.buf.clear(); Ok(()) } } /// Factory for creating instances of `TBufferedWriteTransport`. #[derive(Default)] pub struct TBufferedWriteTransportFactory; impl TBufferedWriteTransportFactory { pub fn new() -> TBufferedWriteTransportFactory { TBufferedWriteTransportFactory {} } } impl TWriteTransportFactory for TBufferedWriteTransportFactory { /// Create a `TBufferedWriteTransport`. fn create(&self, channel: Box) -> Box { Box::new(TBufferedWriteTransport::new(channel)) } } #[cfg(test)] mod tests { use std::io::{Read, Write}; use super::*; use crate::transport::TBufferChannel; #[test] fn must_return_zero_if_read_buffer_is_empty() { let mem = TBufferChannel::with_capacity(10, 0); let mut t = TBufferedReadTransport::with_capacity(10, mem); let mut b = vec![0; 10]; let read_result = t.read(&mut b); assert_eq!(read_result.unwrap(), 0); } #[test] fn must_return_zero_if_caller_reads_into_zero_capacity_buffer() { let mem = TBufferChannel::with_capacity(10, 0); let mut t = TBufferedReadTransport::with_capacity(10, mem); let read_result = t.read(&mut []); assert_eq!(read_result.unwrap(), 0); } #[test] fn must_return_zero_if_nothing_more_can_be_read() { let mem = TBufferChannel::with_capacity(4, 0); let mut t = TBufferedReadTransport::with_capacity(4, mem); t.chan.set_readable_bytes(&[0, 1, 2, 3]); // read buffer is exactly the same size as bytes available let mut buf = vec![0u8; 4]; let read_result = t.read(&mut buf); // we've read exactly 4 bytes assert_eq!(read_result.unwrap(), 4); assert_eq!(&buf, &[0, 1, 2, 3]); // try read again let buf_again = vec![0u8; 4]; let read_result = t.read(&mut buf); // this time, 0 bytes and we haven't changed the buffer assert_eq!(read_result.unwrap(), 0); assert_eq!(&buf_again, &[0, 0, 0, 0]) } #[test] fn must_fill_user_buffer_with_only_as_many_bytes_as_available() { let mem = TBufferChannel::with_capacity(4, 0); let mut t = TBufferedReadTransport::with_capacity(4, mem); t.chan.set_readable_bytes(&[0, 1, 2, 3]); // read buffer is much larger than the bytes available let mut buf = vec![0u8; 8]; let read_result = t.read(&mut buf); // we've read exactly 4 bytes assert_eq!(read_result.unwrap(), 4); assert_eq!(&buf[..4], &[0, 1, 2, 3]); // try read again let read_result = t.read(&mut buf[4..]); // this time, 0 bytes and we haven't changed the buffer assert_eq!(read_result.unwrap(), 0); assert_eq!(&buf, &[0, 1, 2, 3, 0, 0, 0, 0]) } #[test] fn must_read_successfully() { // this test involves a few loops within the buffered transport // itself where it has to drain the underlying transport in order // to service a read // we have a much smaller buffer than the // underlying transport has bytes available let mem = TBufferChannel::with_capacity(10, 0); let mut t = TBufferedReadTransport::with_capacity(2, mem); // fill the underlying transport's byte buffer let mut readable_bytes = [0u8; 10]; for (i, b) in readable_bytes.iter_mut().enumerate() { *b = i as u8; } t.chan.set_readable_bytes(&readable_bytes); // we ask to read into a buffer that's much larger // than the one the buffered transport has; as a result // it's going to have to keep asking the underlying // transport for more bytes let mut buf = [0u8; 8]; let read_result = t.read(&mut buf); // we should have read 8 bytes assert_eq!(read_result.unwrap(), 8); assert_eq!(&buf, &[0, 1, 2, 3, 4, 5, 6, 7]); // let's clear out the buffer and try read again for b in &mut buf { *b = 0; } let read_result = t.read(&mut buf); // this time we were only able to read 2 bytes // (all that's remaining from the underlying transport) // let's also check that the remaining bytes are untouched assert_eq!(read_result.unwrap(), 2); assert_eq!(&buf[0..2], &[8, 9]); assert_eq!(&buf[2..], &[0, 0, 0, 0, 0, 0]); // try read again (we should get 0) // and all the existing bytes were untouched let read_result = t.read(&mut buf); assert_eq!(read_result.unwrap(), 0); assert_eq!(&buf[0..2], &[8, 9]); assert_eq!(&buf[2..], &[0, 0, 0, 0, 0, 0]); } #[test] fn must_return_error_when_nothing_can_be_written_to_underlying_channel() { let mem = TBufferChannel::with_capacity(0, 0); let mut t = TBufferedWriteTransport::with_capacity(1, mem); let b = vec![0; 10]; let r = t.write(&b); // should have written 1 byte assert_eq!(r.unwrap(), 1); // let's try again... let r = t.write(&b[1..]); // this time we'll error out because the auto-flush failed assert!(r.is_err()); } #[test] fn must_return_zero_if_caller_calls_write_with_empty_buffer() { let mem = TBufferChannel::with_capacity(0, 10); let mut t = TBufferedWriteTransport::with_capacity(10, mem); let r = t.write(&[]); let expected: [u8; 0] = []; assert_eq!(r.unwrap(), 0); assert_eq_transport_written_bytes!(t, expected); } #[test] fn must_auto_flush_if_write_buffer_full() { let mem = TBufferChannel::with_capacity(0, 8); let mut t = TBufferedWriteTransport::with_capacity(4, mem); let b0 = [0x00, 0x01, 0x02, 0x03]; let b1 = [0x04, 0x05, 0x06, 0x07]; // write the first 4 bytes; we've now filled the transport's write buffer let r = t.write(&b0); assert_eq!(r.unwrap(), 4); // try write the next 4 bytes; this causes the transport to auto-flush the first 4 bytes let r = t.write(&b1); assert_eq!(r.unwrap(), 4); // check that in writing the second 4 bytes we auto-flushed the first 4 bytes assert_eq_transport_num_written_bytes!(t, 4); assert_eq_transport_written_bytes!(t, b0); t.channel.empty_write_buffer(); // now flush the transport to push the second 4 bytes to the underlying channel assert!(t.flush().is_ok()); // check that we wrote out the second 4 bytes assert_eq_transport_written_bytes!(t, b1); } #[test] fn must_write_to_inner_transport_on_flush() { let mem = TBufferChannel::with_capacity(10, 10); let mut t = TBufferedWriteTransport::new(mem); let b: [u8; 5] = [0, 1, 2, 3, 4]; assert_eq!(t.write(&b).unwrap(), 5); assert_eq_transport_num_written_bytes!(t, 0); assert!(t.flush().is_ok()); assert_eq_transport_written_bytes!(t, b); } #[test] fn must_write_successfully_after_flush() { let mem = TBufferChannel::with_capacity(0, 5); let mut t = TBufferedWriteTransport::with_capacity(5, mem); // write and flush let b: [u8; 5] = [0, 1, 2, 3, 4]; assert_eq!(t.write(&b).unwrap(), 5); assert!(t.flush().is_ok()); // check the flushed bytes assert_eq_transport_written_bytes!(t, b); // reset our underlying transport t.channel.empty_write_buffer(); // write and flush again assert_eq!(t.write(&b).unwrap(), 5); assert!(t.flush().is_ok()); // check the flushed bytes assert_eq_transport_written_bytes!(t, b); } } thrift-0.23.0/lib/rs/src/transport/mod.rs0000664000175000017500000001727215165535636020550 0ustar00buildbuild00000000000000// 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. //! Types used to send and receive bytes over an I/O channel. //! //! The core types are the `TReadTransport`, `TWriteTransport` and the //! `TIoChannel` traits, through which `TInputProtocol` or //! `TOutputProtocol` can receive and send primitives over the wire. While //! `TInputProtocol` and `TOutputProtocol` instances deal with language primitives //! the types in this module understand only bytes. use std::io; use std::io::{Read, Write}; use std::ops::{Deref, DerefMut}; #[cfg(test)] macro_rules! assert_eq_transport_num_written_bytes { ($transport:ident, $num_written_bytes:expr) => {{ assert_eq!($transport.channel.write_bytes().len(), $num_written_bytes); }}; } #[cfg(test)] macro_rules! assert_eq_transport_written_bytes { ($transport:ident, $expected_bytes:ident) => {{ assert_eq!($transport.channel.write_bytes(), &$expected_bytes); }}; } mod buffered; mod framed; mod mem; mod socket; pub use self::buffered::{ TBufferedReadTransport, TBufferedReadTransportFactory, TBufferedWriteTransport, TBufferedWriteTransportFactory, }; pub use self::framed::{ TFramedReadTransport, TFramedReadTransportFactory, TFramedWriteTransport, TFramedWriteTransportFactory, }; pub use self::mem::TBufferChannel; pub use self::socket::TTcpChannel; /// Identifies a transport used by a `TInputProtocol` to receive bytes. pub trait TReadTransport: Read {} /// Helper type used by a server to create `TReadTransport` instances for /// accepted client connections. pub trait TReadTransportFactory { /// Create a `TTransport` that wraps a channel over which bytes are to be read. fn create(&self, channel: Box) -> Box; } /// Identifies a transport used by `TOutputProtocol` to send bytes. pub trait TWriteTransport: Write {} /// Helper type used by a server to create `TWriteTransport` instances for /// accepted client connections. pub trait TWriteTransportFactory { /// Create a `TTransport` that wraps a channel over which bytes are to be sent. fn create(&self, channel: Box) -> Box; } impl TReadTransport for T where T: Read {} impl TWriteTransport for T where T: Write {} // FIXME: implement the Debug trait for boxed transports impl TReadTransportFactory for Box where T: TReadTransportFactory + ?Sized, { fn create(&self, channel: Box) -> Box { (**self).create(channel) } } impl TWriteTransportFactory for Box where T: TWriteTransportFactory + ?Sized, { fn create(&self, channel: Box) -> Box { (**self).create(channel) } } /// Identifies a splittable bidirectional I/O channel used to send and receive bytes. pub trait TIoChannel: Read + Write { /// Split the channel into a readable half and a writable half, where the /// readable half implements `io::Read` and the writable half implements /// `io::Write`. Returns `None` if the channel was not initialized, or if it /// cannot be split safely. /// /// Returned halves may share the underlying OS channel or buffer resources. /// Implementations **should ensure** that these two halves can be safely /// used independently by concurrent threads. fn split( self, ) -> crate::Result<( crate::transport::ReadHalf, crate::transport::WriteHalf, )> where Self: Sized; } /// The readable half of an object returned from `TIoChannel::split`. #[derive(Debug)] pub struct ReadHalf where C: Read, { handle: C, } /// The writable half of an object returned from `TIoChannel::split`. #[derive(Debug)] pub struct WriteHalf where C: Write, { handle: C, } impl ReadHalf where C: Read, { /// Create a `ReadHalf` associated with readable `handle` pub fn new(handle: C) -> ReadHalf { ReadHalf { handle } } } impl WriteHalf where C: Write, { /// Create a `WriteHalf` associated with writable `handle` pub fn new(handle: C) -> WriteHalf { WriteHalf { handle } } } impl Read for ReadHalf where C: Read, { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.handle.read(buf) } } impl Write for WriteHalf where C: Write, { fn write(&mut self, buf: &[u8]) -> io::Result { self.handle.write(buf) } fn flush(&mut self) -> io::Result<()> { self.handle.flush() } } impl Deref for ReadHalf where C: Read, { type Target = C; fn deref(&self) -> &Self::Target { &self.handle } } impl DerefMut for ReadHalf where C: Read, { fn deref_mut(&mut self) -> &mut C { &mut self.handle } } impl Deref for WriteHalf where C: Write, { type Target = C; fn deref(&self) -> &Self::Target { &self.handle } } impl DerefMut for WriteHalf where C: Write, { fn deref_mut(&mut self) -> &mut C { &mut self.handle } } #[cfg(test)] mod tests { use std::io::Cursor; use super::*; #[test] fn must_create_usable_read_channel_from_concrete_read_type() { let r = Cursor::new([0, 1, 2]); let _ = TBufferedReadTransport::new(r); } #[test] fn must_create_usable_read_channel_from_boxed_read() { let r: Box = Box::new(Cursor::new([0, 1, 2])); let _ = TBufferedReadTransport::new(r); } #[test] fn must_create_usable_write_channel_from_concrete_write_type() { let w = vec![0u8; 10]; let _ = TBufferedWriteTransport::new(w); } #[test] fn must_create_usable_write_channel_from_boxed_write() { let w: Box = Box::new(vec![0u8; 10]); let _ = TBufferedWriteTransport::new(w); } #[test] fn must_create_usable_read_transport_from_concrete_read_transport() { let r = Cursor::new([0, 1, 2]); let mut t = TBufferedReadTransport::new(r); takes_read_transport(&mut t) } #[test] fn must_create_usable_read_transport_from_boxed_read() { let r = Cursor::new([0, 1, 2]); let mut t: Box = Box::new(TBufferedReadTransport::new(r)); takes_read_transport(&mut t) } #[test] fn must_create_usable_write_transport_from_concrete_write_transport() { let w = vec![0u8; 10]; let mut t = TBufferedWriteTransport::new(w); takes_write_transport(&mut t) } #[test] fn must_create_usable_write_transport_from_boxed_write() { let w = vec![0u8; 10]; let mut t: Box = Box::new(TBufferedWriteTransport::new(w)); takes_write_transport(&mut t) } fn takes_read_transport(t: &mut R) where R: TReadTransport, { t.bytes(); } fn takes_write_transport(t: &mut W) where W: TWriteTransport, { t.flush().unwrap(); } } thrift-0.23.0/lib/rs/src/autogen.rs0000664000175000017500000000414115165535636017366 0ustar00buildbuild00000000000000// 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. //! Thrift compiler auto-generated support. //! //! //! Types and functions used internally by the Thrift compiler's Rust plugin //! to implement required functionality. Users should never have to use code //! in this module directly. use crate::protocol::{TInputProtocol, TOutputProtocol}; /// Specifies the minimum functionality an auto-generated client should provide /// to communicate with a Thrift server. pub trait TThriftClient { /// Returns the input protocol used to read serialized Thrift messages /// from the Thrift server. fn i_prot_mut(&mut self) -> &mut dyn TInputProtocol; /// Returns the output protocol used to write serialized Thrift messages /// to the Thrift server. fn o_prot_mut(&mut self) -> &mut dyn TOutputProtocol; /// Returns the sequence number of the last message written to the Thrift /// server. Returns `0` if no messages have been written. Sequence /// numbers should *never* be negative, and this method returns an `i32` /// simply because the Thrift protocol encodes sequence numbers as `i32` on /// the wire. fn sequence_number(&self) -> i32; // FIXME: consider returning a u32 /// Increments the sequence number, indicating that a message with that /// number has been sent to the Thrift server. fn increment_sequence_number(&mut self) -> i32; } thrift-0.23.0/lib/rs/src/protocol/0000775000175000017500000000000015167543515017214 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/src/protocol/stored.rs0000664000175000017500000001476415165535636021101 0ustar00buildbuild00000000000000// 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. use std::convert::Into; use super::{ TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier, TSetIdentifier, TStructIdentifier, }; use crate::ProtocolErrorKind; /// `TInputProtocol` required to use a `TMultiplexedProcessor`. /// /// A `TMultiplexedProcessor` reads incoming message identifiers to determine to /// which `TProcessor` requests should be forwarded. However, once read, those /// message identifier bytes are no longer on the wire. Since downstream /// processors expect to read message identifiers from the given input protocol /// we need some way of supplying a `TMessageIdentifier` with the service-name /// stripped. This implementation stores the received `TMessageIdentifier` /// (without the service name) and passes it to the wrapped `TInputProtocol` /// when `TInputProtocol::read_message_begin(...)` is called. It delegates all /// other calls directly to the wrapped `TInputProtocol`. /// /// This type **should not** be used by application code. /// /// # Examples /// /// Create and use a `TStoredInputProtocol`. /// /// ```no_run /// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol}; /// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol}; /// use thrift::server::TProcessor; /// use thrift::transport::{TIoChannel, TTcpChannel}; /// /// // sample processor /// struct ActualProcessor; /// impl TProcessor for ActualProcessor { /// fn process( /// &self, /// _: &mut dyn TInputProtocol, /// _: &mut dyn TOutputProtocol /// ) -> thrift::Result<()> { /// unimplemented!() /// } /// } /// let processor = ActualProcessor {}; /// /// // construct the shared transport /// let mut channel = TTcpChannel::new(); /// channel.open("localhost:9090").unwrap(); /// /// let (i_chan, o_chan) = channel.split().unwrap(); /// /// // construct the actual input and output protocols /// let mut i_prot = TBinaryInputProtocol::new(i_chan, true); /// let mut o_prot = TBinaryOutputProtocol::new(o_chan, true); /// /// // message identifier received from remote and modified to remove the service name /// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1); /// /// // construct the proxy input protocol /// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident); /// let res = processor.process(&mut proxy_i_prot, &mut o_prot); /// ``` // FIXME: implement Debug pub struct TStoredInputProtocol<'a> { inner: &'a mut dyn TInputProtocol, 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` /// `TInputProtocol`. `message_ident` is the modified message identifier - /// with service name stripped - that will be passed to /// `wrapped.read_message_begin(...)`. pub fn new( wrapped: &mut dyn TInputProtocol, message_ident: TMessageIdentifier, ) -> TStoredInputProtocol<'_> { TStoredInputProtocol { inner: wrapped, message_ident: message_ident.into(), } } } // 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(|| { crate::errors::new_protocol_error( ProtocolErrorKind::Unknown, "message identifier already read", ) }) } fn read_message_end(&mut self) -> crate::Result<()> { self.inner.read_message_end() } fn read_struct_begin(&mut self) -> crate::Result> { self.inner.read_struct_begin() } fn read_struct_end(&mut self) -> crate::Result<()> { self.inner.read_struct_end() } fn read_field_begin(&mut self) -> crate::Result { self.inner.read_field_begin() } fn read_field_end(&mut self) -> crate::Result<()> { self.inner.read_field_end() } fn read_bytes(&mut self) -> crate::Result> { self.inner.read_bytes() } fn read_bool(&mut self) -> crate::Result { self.inner.read_bool() } fn read_i8(&mut self) -> crate::Result { self.inner.read_i8() } fn read_i16(&mut self) -> crate::Result { self.inner.read_i16() } fn read_i32(&mut self) -> crate::Result { self.inner.read_i32() } fn read_i64(&mut self) -> crate::Result { self.inner.read_i64() } fn read_double(&mut self) -> crate::Result { self.inner.read_double() } fn read_uuid(&mut self) -> crate::Result { self.inner.read_uuid() } fn read_string(&mut self) -> crate::Result { self.inner.read_string() } fn read_list_begin(&mut self) -> crate::Result { self.inner.read_list_begin() } fn read_list_end(&mut self) -> crate::Result<()> { self.inner.read_list_end() } fn read_set_begin(&mut self) -> crate::Result { self.inner.read_set_begin() } fn read_set_end(&mut self) -> crate::Result<()> { self.inner.read_set_end() } fn read_map_begin(&mut self) -> crate::Result { self.inner.read_map_begin() } fn read_map_end(&mut self) -> crate::Result<()> { self.inner.read_map_end() } // utility // fn read_byte(&mut self) -> crate::Result { self.inner.read_byte() } } thrift-0.23.0/lib/rs/src/protocol/binary.rs0000664000175000017500000011412215165535636021052 0ustar00buildbuild00000000000000// 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. use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; use std::convert::{From, TryFrom}; use super::{ TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, }; use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType}; use crate::transport::{TReadTransport, TWriteTransport}; use crate::{ProtocolError, ProtocolErrorKind, TConfiguration}; const BINARY_PROTOCOL_VERSION_1: u32 = 0x8001_0000; /// Read messages encoded in the Thrift simple binary encoding. /// /// There are two available modes: `strict` and `non-strict`, where the /// `non-strict` version does not check for the protocol version in the /// received message header. /// /// # Examples /// /// Create and use a `TBinaryInputProtocol`. /// /// ```no_run /// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("localhost:9090").unwrap(); /// /// let mut protocol = TBinaryInputProtocol::new(channel, true); /// /// let recvd_bool = protocol.read_bool().unwrap(); /// let recvd_string = protocol.read_string().unwrap(); /// ``` #[derive(Debug)] pub struct TBinaryInputProtocol where T: TReadTransport, { strict: bool, pub transport: T, // FIXME: shouldn't be public config: TConfiguration, recursion_depth: usize, } impl TBinaryInputProtocol where T: TReadTransport, { /// Create a `TBinaryInputProtocol` that reads bytes from `transport`. /// /// Set `strict` to `true` if all incoming messages contain the protocol /// version number in the protocol header. pub fn new(transport: T, strict: bool) -> Self { Self::with_config(transport, strict, TConfiguration::default()) } pub fn with_config(transport: T, strict: bool, config: TConfiguration) -> Self { TBinaryInputProtocol { strict, transport, config, recursion_depth: 0, } } fn check_recursion_depth(&self) -> crate::Result<()> { if let Some(limit) = self.config.max_recursion_depth() { if self.recursion_depth >= limit { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::DepthLimit, format!("Maximum recursion depth {} exceeded", limit), ))); } } Ok(()) } } impl TInputProtocol for TBinaryInputProtocol where T: TReadTransport, { #[allow(clippy::collapsible_if)] fn read_message_begin(&mut self) -> crate::Result { // TODO: Once specialization is stable, call the message size tracking here let mut first_bytes = vec![0; 4]; self.transport.read_exact(&mut first_bytes[..])?; // the thrift version header is intentionally negative // so the first check we'll do is see if the sign bit is set // and if so - assume it's the protocol-version header if (first_bytes[0] & 0x80) != 0 { // apparently we got a protocol-version header - check // it, and if it matches, read the rest of the fields if first_bytes[0..2] != [0x80, 0x01] { Err(crate::Error::Protocol(ProtocolError { kind: ProtocolErrorKind::BadVersion, message: format!("received bad version: {:?}", &first_bytes[0..2]), })) } else { let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?; let name = self.read_string()?; let sequence_number = self.read_i32()?; Ok(TMessageIdentifier::new(name, message_type, sequence_number)) } } else { // apparently we didn't get a protocol-version header, // which happens if the sender is not using the strict protocol if self.strict { // we're in strict mode however, and that always // requires the protocol-version header to be written first Err(crate::Error::Protocol(ProtocolError { kind: ProtocolErrorKind::BadVersion, message: format!("received bad version: {:?}", &first_bytes[0..2]), })) } else { // in the non-strict version the first message field // is the message name. strings (byte arrays) are length-prefixed, // so we've just read the length in the first 4 bytes let name_size = BigEndian::read_i32(&first_bytes) as usize; let mut name_buf: Vec = vec![0; name_size]; self.transport.read_exact(&mut name_buf)?; let name = String::from_utf8(name_buf)?; // read the rest of the fields let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?; let sequence_number = self.read_i32()?; Ok(TMessageIdentifier::new(name, message_type, sequence_number)) } } } fn read_message_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_struct_begin(&mut self) -> crate::Result> { self.check_recursion_depth()?; self.recursion_depth += 1; Ok(None) } fn read_struct_end(&mut self) -> crate::Result<()> { self.recursion_depth -= 1; Ok(()) } fn read_field_begin(&mut self) -> crate::Result { let field_type_byte = self.read_byte()?; let field_type = field_type_from_u8(field_type_byte)?; let id = match field_type { TType::Stop => Ok(0), _ => self.read_i16(), }?; Ok(TFieldIdentifier::new::, String, i16>( None, field_type, id, )) } fn read_field_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_bytes(&mut self) -> crate::Result> { let num_bytes = self.transport.read_i32::()?; if num_bytes < 0 { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::NegativeSize, format!("Negative byte array size: {}", num_bytes), ))); } if let Some(max_size) = self.config.max_string_size() { if num_bytes as usize > max_size { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::SizeLimit, format!( "Byte array size {} exceeds maximum allowed size of {}", num_bytes, max_size ), ))); } } let mut buf = vec![0u8; num_bytes as usize]; self.transport .read_exact(&mut buf) .map(|_| buf) .map_err(From::from) } fn read_bool(&mut self) -> crate::Result { let b = self.read_i8()?; match b { 0 => Ok(false), _ => Ok(true), } } fn read_i8(&mut self) -> crate::Result { self.transport.read_i8().map_err(From::from) } fn read_i16(&mut self) -> crate::Result { self.transport.read_i16::().map_err(From::from) } fn read_i32(&mut self) -> crate::Result { self.transport.read_i32::().map_err(From::from) } fn read_i64(&mut self) -> crate::Result { self.transport.read_i64::().map_err(From::from) } fn read_double(&mut self) -> crate::Result { self.transport.read_f64::().map_err(From::from) } fn read_uuid(&mut self) -> crate::Result { let mut buf = [0u8; 16]; self.transport .read_exact(&mut buf) .map(|_| uuid::Uuid::from_bytes(buf)) .map_err(From::from) } fn read_string(&mut self) -> crate::Result { let bytes = self.read_bytes()?; String::from_utf8(bytes).map_err(From::from) } fn read_list_begin(&mut self) -> crate::Result { let element_type: TType = self.read_byte().and_then(field_type_from_u8)?; let size = self.read_i32()?; let min_element_size = self.min_serialized_size(element_type); super::check_container_size(&self.config, size, min_element_size)?; Ok(TListIdentifier::new(element_type, size)) } fn read_list_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_set_begin(&mut self) -> crate::Result { let element_type: TType = self.read_byte().and_then(field_type_from_u8)?; let size = self.read_i32()?; let min_element_size = self.min_serialized_size(element_type); super::check_container_size(&self.config, size, min_element_size)?; Ok(TSetIdentifier::new(element_type, size)) } fn read_set_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_map_begin(&mut self) -> crate::Result { let key_type: TType = self.read_byte().and_then(field_type_from_u8)?; let value_type: TType = self.read_byte().and_then(field_type_from_u8)?; let size = self.read_i32()?; let key_min_size = self.min_serialized_size(key_type); let value_min_size = self.min_serialized_size(value_type); let element_size = key_min_size + value_min_size; super::check_container_size(&self.config, size, element_size)?; Ok(TMapIdentifier::new(key_type, value_type, size)) } fn read_map_end(&mut self) -> crate::Result<()> { Ok(()) } // utility // fn read_byte(&mut self) -> crate::Result { self.transport.read_u8().map_err(From::from) } fn min_serialized_size(&self, field_type: TType) -> usize { match field_type { TType::Stop => 1, // 1 byte minimum TType::Void => 1, // 1 byte minimum TType::Bool => 1, // 1 byte TType::I08 => 1, // 1 byte TType::Double => 8, // 8 bytes TType::I16 => 2, // 2 bytes TType::I32 => 4, // 4 bytes TType::I64 => 8, // 8 bytes TType::String => 4, // 4 bytes for length prefix TType::Struct => 1, // 1 byte minimum (stop field) TType::Map => 4, // 4 bytes size TType::Set => 4, // 4 bytes size TType::List => 4, // 4 bytes size TType::Uuid => 16, // 16 bytes TType::Utf7 => 1, // 1 byte } } } /// Factory for creating instances of `TBinaryInputProtocol`. #[derive(Default)] pub struct TBinaryInputProtocolFactory; impl TBinaryInputProtocolFactory { /// Create a `TBinaryInputProtocolFactory`. pub fn new() -> TBinaryInputProtocolFactory { TBinaryInputProtocolFactory {} } } impl TInputProtocolFactory for TBinaryInputProtocolFactory { fn create(&self, transport: Box) -> Box { Box::new(TBinaryInputProtocol::new(transport, true)) } } /// Write messages using the Thrift simple binary encoding. /// /// There are two available modes: `strict` and `non-strict`, where the /// `strict` version writes the protocol version number in the outgoing message /// header and the `non-strict` version does not. /// /// # Examples /// /// Create and use a `TBinaryOutputProtocol`. /// /// ```no_run /// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("localhost:9090").unwrap(); /// /// let mut protocol = TBinaryOutputProtocol::new(channel, true); /// /// protocol.write_bool(true).unwrap(); /// protocol.write_string("test_string").unwrap(); /// ``` #[derive(Debug)] pub struct TBinaryOutputProtocol where T: TWriteTransport, { strict: bool, pub transport: T, // FIXME: do not make public; only public for testing! } impl TBinaryOutputProtocol where T: TWriteTransport, { /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`. /// /// Set `strict` to `true` if all outgoing messages should contain the /// protocol version number in the protocol header. pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol { TBinaryOutputProtocol { strict, transport } } } impl TOutputProtocol for TBinaryOutputProtocol where T: TWriteTransport, { fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> { if self.strict { let message_type: u8 = identifier.message_type.into(); let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32); self.transport.write_u32::(header)?; self.write_string(&identifier.name)?; self.write_i32(identifier.sequence_number) } else { self.write_string(&identifier.name)?; self.write_byte(identifier.message_type.into())?; self.write_i32(identifier.sequence_number) } } fn write_message_end(&mut self) -> crate::Result<()> { Ok(()) } fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> { Ok(()) } fn write_struct_end(&mut self) -> crate::Result<()> { Ok(()) } fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> { if identifier.id.is_none() && identifier.field_type != TType::Stop { return Err(crate::Error::Protocol(ProtocolError { kind: ProtocolErrorKind::Unknown, message: format!( "cannot write identifier {:?} without sequence number", &identifier ), })); } self.write_byte(field_type_to_u8(identifier.field_type))?; if let Some(id) = identifier.id { self.write_i16(id) } else { Ok(()) } } fn write_field_end(&mut self) -> crate::Result<()> { Ok(()) } fn write_field_stop(&mut self) -> crate::Result<()> { self.write_byte(field_type_to_u8(TType::Stop)) } fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> { self.write_i32(b.len() as i32)?; self.transport.write_all(b).map_err(From::from) } fn write_bool(&mut self, b: bool) -> crate::Result<()> { if b { self.write_i8(1) } else { self.write_i8(0) } } fn write_i8(&mut self, i: i8) -> crate::Result<()> { self.transport.write_i8(i).map_err(From::from) } fn write_i16(&mut self, i: i16) -> crate::Result<()> { self.transport.write_i16::(i).map_err(From::from) } fn write_i32(&mut self, i: i32) -> crate::Result<()> { self.transport.write_i32::(i).map_err(From::from) } fn write_i64(&mut self, i: i64) -> crate::Result<()> { self.transport.write_i64::(i).map_err(From::from) } fn write_double(&mut self, d: f64) -> crate::Result<()> { self.transport.write_f64::(d).map_err(From::from) } fn write_string(&mut self, s: &str) -> crate::Result<()> { self.write_bytes(s.as_bytes()) } fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> { self.transport .write_all(uuid.as_bytes()) .map_err(From::from) } fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> { self.write_byte(field_type_to_u8(identifier.element_type))?; self.write_i32(identifier.size) } fn write_list_end(&mut self) -> crate::Result<()> { Ok(()) } fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> { self.write_byte(field_type_to_u8(identifier.element_type))?; self.write_i32(identifier.size) } fn write_set_end(&mut self) -> crate::Result<()> { Ok(()) } fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> { let key_type = identifier .key_type .expect("map identifier to write should contain key type"); self.write_byte(field_type_to_u8(key_type))?; let val_type = identifier .value_type .expect("map identifier to write should contain value type"); self.write_byte(field_type_to_u8(val_type))?; self.write_i32(identifier.size) } fn write_map_end(&mut self) -> crate::Result<()> { Ok(()) } fn flush(&mut self) -> crate::Result<()> { self.transport.flush().map_err(From::from) } // utility // fn write_byte(&mut self, b: u8) -> crate::Result<()> { self.transport.write_u8(b).map_err(From::from) } } /// Factory for creating instances of `TBinaryOutputProtocol`. #[derive(Default)] pub struct TBinaryOutputProtocolFactory; impl TBinaryOutputProtocolFactory { /// Create a `TBinaryOutputProtocolFactory`. pub fn new() -> TBinaryOutputProtocolFactory { TBinaryOutputProtocolFactory {} } } impl TOutputProtocolFactory for TBinaryOutputProtocolFactory { fn create( &self, transport: Box, ) -> Box { Box::new(TBinaryOutputProtocol::new(transport, true)) } } fn field_type_to_u8(field_type: TType) -> u8 { match field_type { TType::Stop => 0x00, TType::Void => 0x01, TType::Bool => 0x02, TType::I08 => 0x03, // equivalent to TType::Byte TType::Double => 0x04, TType::I16 => 0x06, TType::I32 => 0x08, TType::I64 => 0x0A, TType::String | TType::Utf7 => 0x0B, TType::Struct => 0x0C, TType::Map => 0x0D, TType::Set => 0x0E, TType::List => 0x0F, TType::Uuid => 0x10, } } fn field_type_from_u8(b: u8) -> crate::Result { match b { 0x00 => Ok(TType::Stop), 0x01 => Ok(TType::Void), 0x02 => Ok(TType::Bool), 0x03 => Ok(TType::I08), // Equivalent to TType::Byte 0x04 => Ok(TType::Double), 0x06 => Ok(TType::I16), 0x08 => Ok(TType::I32), 0x0A => Ok(TType::I64), 0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string 0x0C => Ok(TType::Struct), 0x0D => Ok(TType::Map), 0x0E => Ok(TType::Set), 0x0F => Ok(TType::List), 0x10 => Ok(TType::Uuid), unkn => Err(crate::Error::Protocol(ProtocolError { kind: ProtocolErrorKind::InvalidData, message: format!("cannot convert {} to TType", unkn), })), } } #[cfg(test)] mod tests { use super::*; use crate::protocol::{ TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType, }; use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf}; #[test] fn must_write_strict_message_call_begin() { let (_, mut o_prot) = test_objects(true); let ident = TMessageIdentifier::new("test", TMessageType::Call, 1); assert!(o_prot.write_message_begin(&ident).is_ok()); #[rustfmt::skip] let expected: [u8; 16] = [ 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x01, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_write_non_strict_message_call_begin() { let (_, mut o_prot) = test_objects(false); let ident = TMessageIdentifier::new("test", TMessageType::Call, 1); assert!(o_prot.write_message_begin(&ident).is_ok()); #[rustfmt::skip] let expected: [u8; 13] = [ 0x00, 0x00, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x01, 0x00, 0x00, 0x00, 0x01, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_write_strict_message_reply_begin() { let (_, mut o_prot) = test_objects(true); let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10); assert!(o_prot.write_message_begin(&ident).is_ok()); #[rustfmt::skip] let expected: [u8; 16] = [ 0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x0A, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_write_non_strict_message_reply_begin() { let (_, mut o_prot) = test_objects(false); let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10); assert!(o_prot.write_message_begin(&ident).is_ok()); #[rustfmt::skip] let expected: [u8; 13] = [ 0x00, 0x00, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x02, 0x00, 0x00, 0x00, 0x0A, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_strict_message_begin() { let (mut i_prot, mut o_prot) = test_objects(true); let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1); assert!(o_prot.write_message_begin(&sent_ident).is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let received_ident = assert_success!(i_prot.read_message_begin()); assert_eq!(&received_ident, &sent_ident); } #[test] fn must_round_trip_non_strict_message_begin() { let (mut i_prot, mut o_prot) = test_objects(false); let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1); assert!(o_prot.write_message_begin(&sent_ident).is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let received_ident = assert_success!(i_prot.read_message_begin()); assert_eq!(&received_ident, &sent_ident); } #[test] fn must_write_message_end() { assert_no_write(|o| o.write_message_end(), true); } #[test] fn must_write_struct_begin() { assert_no_write( |o| o.write_struct_begin(&TStructIdentifier::new("foo")), true, ); } #[test] fn must_write_struct_end() { assert_no_write(|o| o.write_struct_end(), true); } #[test] fn must_write_field_begin() { let (_, mut o_prot) = test_objects(true); assert!(o_prot .write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22)) .is_ok()); let expected: [u8; 3] = [0x0B, 0x00, 0x16]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_field_begin() { let (mut i_prot, mut o_prot) = test_objects(true); let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20); assert!(o_prot.write_field_begin(&sent_field_ident).is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let expected_ident = TFieldIdentifier { name: None, field_type: TType::I64, id: Some(20), }; // no name let received_ident = assert_success!(i_prot.read_field_begin()); assert_eq!(&received_ident, &expected_ident); } #[test] fn must_write_stop_field() { let (_, mut o_prot) = test_objects(true); assert!(o_prot.write_field_stop().is_ok()); let expected: [u8; 1] = [0x00]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_field_stop() { let (mut i_prot, mut o_prot) = test_objects(true); assert!(o_prot.write_field_stop().is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let expected_ident = TFieldIdentifier { name: None, field_type: TType::Stop, id: Some(0), }; // we get id 0 let received_ident = assert_success!(i_prot.read_field_begin()); assert_eq!(&received_ident, &expected_ident); } #[test] fn must_write_field_end() { assert_no_write(|o| o.write_field_end(), true); } #[test] fn must_write_list_begin() { let (_, mut o_prot) = test_objects(true); assert!(o_prot .write_list_begin(&TListIdentifier::new(TType::Bool, 5)) .is_ok()); let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_list_begin() { let (mut i_prot, mut o_prot) = test_objects(true); let ident = TListIdentifier::new(TType::I32, 4); assert!(o_prot.write_list_begin(&ident).is_ok()); assert!(o_prot.write_i32(10).is_ok()); assert!(o_prot.write_i32(20).is_ok()); assert!(o_prot.write_i32(30).is_ok()); assert!(o_prot.write_i32(40).is_ok()); assert!(o_prot.write_list_end().is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let received_ident = assert_success!(i_prot.read_list_begin()); assert_eq!(&received_ident, &ident); assert_eq!(i_prot.read_i32().unwrap(), 10); assert_eq!(i_prot.read_i32().unwrap(), 20); assert_eq!(i_prot.read_i32().unwrap(), 30); assert_eq!(i_prot.read_i32().unwrap(), 40); assert!(i_prot.read_list_end().is_ok()); } #[test] fn must_write_list_end() { assert_no_write(|o| o.write_list_end(), true); } #[test] fn must_write_set_begin() { let (_, mut o_prot) = test_objects(true); assert!(o_prot .write_set_begin(&TSetIdentifier::new(TType::I16, 7)) .is_ok()); let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_set_begin() { let (mut i_prot, mut o_prot) = test_objects(true); let ident = TSetIdentifier::new(TType::I64, 3); assert!(o_prot.write_set_begin(&ident).is_ok()); assert!(o_prot.write_i64(123).is_ok()); assert!(o_prot.write_i64(456).is_ok()); assert!(o_prot.write_i64(789).is_ok()); assert!(o_prot.write_set_end().is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let received_ident_result = i_prot.read_set_begin(); assert!(received_ident_result.is_ok()); assert_eq!(&received_ident_result.unwrap(), &ident); assert_eq!(i_prot.read_i64().unwrap(), 123); assert_eq!(i_prot.read_i64().unwrap(), 456); assert_eq!(i_prot.read_i64().unwrap(), 789); assert!(i_prot.read_set_end().is_ok()); } #[test] fn must_write_set_end() { assert_no_write(|o| o.write_set_end(), true); } #[test] fn must_write_map_begin() { let (_, mut o_prot) = test_objects(true); assert!(o_prot .write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32)) .is_ok()); let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_map_begin() { let (mut i_prot, mut o_prot) = test_objects(true); let ident = TMapIdentifier::new(TType::String, TType::I32, 2); assert!(o_prot.write_map_begin(&ident).is_ok()); assert!(o_prot.write_string("key1").is_ok()); assert!(o_prot.write_i32(100).is_ok()); assert!(o_prot.write_string("key2").is_ok()); assert!(o_prot.write_i32(200).is_ok()); assert!(o_prot.write_map_end().is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let received_ident = assert_success!(i_prot.read_map_begin()); assert_eq!(&received_ident, &ident); assert_eq!(i_prot.read_string().unwrap(), "key1"); assert_eq!(i_prot.read_i32().unwrap(), 100); assert_eq!(i_prot.read_string().unwrap(), "key2"); assert_eq!(i_prot.read_i32().unwrap(), 200); assert!(i_prot.read_map_end().is_ok()); } #[test] fn must_write_map_end() { assert_no_write(|o| o.write_map_end(), true); } #[test] fn must_write_bool_true() { let (_, mut o_prot) = test_objects(true); assert!(o_prot.write_bool(true).is_ok()); let expected: [u8; 1] = [0x01]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_write_bool_false() { let (_, mut o_prot) = test_objects(true); assert!(o_prot.write_bool(false).is_ok()); let expected: [u8; 1] = [0x00]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_bool_true() { let (mut i_prot, _) = test_objects(true); set_readable_bytes!(i_prot, &[0x01]); let read_bool = assert_success!(i_prot.read_bool()); assert!(read_bool); } #[test] fn must_read_bool_false() { let (mut i_prot, _) = test_objects(true); set_readable_bytes!(i_prot, &[0x00]); let read_bool = assert_success!(i_prot.read_bool()); assert!(!read_bool); } #[test] fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() { let (mut i_prot, _) = test_objects(true); set_readable_bytes!(i_prot, &[0xAC]); let read_bool = assert_success!(i_prot.read_bool()); assert!(read_bool); } #[test] fn must_write_bytes() { let (_, mut o_prot) = test_objects(true); let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF]; assert!(o_prot.write_bytes(&bytes).is_ok()); let buf = o_prot.transport.write_bytes(); assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length assert_eq!(&buf[4..], bytes); // actual bytes } #[test] fn must_write_uuid() { let (_, mut o_prot) = test_objects(true); let uuid = uuid::Uuid::new_v4(); assert!(o_prot.write_uuid(&uuid).is_ok()); let buf = o_prot.transport.write_bytes(); assert_eq!(&buf, uuid.as_bytes()); } #[test] fn must_round_trip_uuid() { let (mut i_prot, mut o_prot) = test_objects(true); let uuid = uuid::uuid!("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"); assert!(o_prot.write_uuid(&uuid).is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let received_uuid = assert_success!(i_prot.read_uuid()); assert_eq!(&received_uuid, &uuid); } #[test] fn must_round_trip_bytes() { let (mut i_prot, mut o_prot) = test_objects(true); #[rustfmt::skip] let bytes: [u8; 25] = [ 0x20, 0xFD, 0x18, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF, 0x34, 0xDC, 0x98, 0xA4, 0x6D, 0xF3, 0x99, 0xB4, 0xB7, 0xD4, 0x9C, 0xA5, 0xB3, 0xC9, 0x88, ]; assert!(o_prot.write_bytes(&bytes).is_ok()); copy_write_buffer_to_read_buffer!(o_prot); let received_bytes = assert_success!(i_prot.read_bytes()); assert_eq!(&received_bytes, &bytes); } fn test_objects( strict: bool, ) -> ( TBinaryInputProtocol>, TBinaryOutputProtocol>, ) { let mem = TBufferChannel::with_capacity(200, 200); let (r_mem, w_mem) = mem.split().unwrap(); let i_prot = TBinaryInputProtocol::new(r_mem, strict); let o_prot = TBinaryOutputProtocol::new(w_mem, strict); (i_prot, o_prot) } fn assert_no_write(mut write_fn: F, strict: bool) where F: FnMut(&mut TBinaryOutputProtocol>) -> crate::Result<()>, { let (_, mut o_prot) = test_objects(strict); assert!(write_fn(&mut o_prot).is_ok()); assert_eq!(o_prot.transport.write_bytes().len(), 0); } #[test] fn must_enforce_recursion_depth_limit() { let mem = TBufferChannel::with_capacity(40, 40); let (r_mem, _) = mem.split().unwrap(); let config = TConfiguration::builder() .max_recursion_depth(Some(2)) .build() .unwrap(); let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config); assert!(i_prot.read_struct_begin().is_ok()); assert_eq!(i_prot.recursion_depth, 1); assert!(i_prot.read_struct_begin().is_ok()); assert_eq!(i_prot.recursion_depth, 2); let result = i_prot.read_struct_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::DepthLimit); } _ => panic!("Expected protocol error with DepthLimit"), } assert!(i_prot.read_struct_end().is_ok()); assert_eq!(i_prot.recursion_depth, 1); assert!(i_prot.read_struct_end().is_ok()); assert_eq!(i_prot.recursion_depth, 0); } #[test] fn must_reject_negative_container_sizes() { let mem = TBufferChannel::with_capacity(40, 40); let (r_mem, mut w_mem) = mem.split().unwrap(); let mut i_prot = TBinaryInputProtocol::new(r_mem, true); w_mem.set_readable_bytes(&[0x0F, 0xFF, 0xFF, 0xFF, 0xFF]); let result = i_prot.read_list_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::NegativeSize); } _ => panic!("Expected protocol error with NegativeSize"), } } #[test] fn must_enforce_container_size_limit() { let mem = TBufferChannel::with_capacity(40, 40); let (r_mem, mut w_mem) = mem.split().unwrap(); let config = TConfiguration::builder() .max_container_size(Some(100)) .build() .unwrap(); let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config); w_mem.set_readable_bytes(&[0x0F, 0x00, 0x00, 0x00, 0xC8]); let result = i_prot.read_list_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::SizeLimit); assert!(e .message .contains("Container size 200 exceeds maximum allowed size of 100")); } _ => panic!("Expected protocol error with SizeLimit"), } } #[test] fn must_allow_containers_within_limit() { let mem = TBufferChannel::with_capacity(200, 200); let (r_mem, mut w_mem) = mem.split().unwrap(); // Create protocol with container limit of 100 let config = TConfiguration::builder() .max_container_size(Some(100)) .build() .unwrap(); let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config); let mut data = vec![0x08]; // TType::I32 data.extend_from_slice(&5i32.to_be_bytes()); // size = 5 for i in 1i32..=5i32 { data.extend_from_slice(&(i * 10).to_be_bytes()); } w_mem.set_readable_bytes(&data); let result = i_prot.read_list_begin(); assert!(result.is_ok()); let list_ident = result.unwrap(); assert_eq!(list_ident.size, 5); assert_eq!(list_ident.element_type, TType::I32); } #[test] fn must_enforce_string_size_limit() { let mem = TBufferChannel::with_capacity(100, 100); let (r_mem, mut w_mem) = mem.split().unwrap(); let config = TConfiguration::builder() .max_string_size(Some(1000)) .build() .unwrap(); let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config); w_mem.set_readable_bytes(&[0x00, 0x00, 0x07, 0xD0]); let result = i_prot.read_string(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::SizeLimit); assert!(e .message .contains("Byte array size 2000 exceeds maximum allowed size of 1000")); } _ => panic!("Expected protocol error with SizeLimit"), } } #[test] fn must_allow_strings_within_limit() { let mem = TBufferChannel::with_capacity(100, 100); let (r_mem, mut w_mem) = mem.split().unwrap(); let config = TConfiguration::builder() .max_string_size(Some(1000)) .build() .unwrap(); let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config); w_mem.set_readable_bytes(&[0x00, 0x00, 0x00, 0x05, b'h', b'e', b'l', b'l', b'o']); let result = i_prot.read_string(); assert!(result.is_ok()); assert_eq!(result.unwrap(), "hello"); } } thrift-0.23.0/lib/rs/src/protocol/compact.rs0000664000175000017500000032714615167543515021225 0ustar00buildbuild00000000000000// 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. use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use integer_encoding::{VarIntReader, VarIntWriter}; use std::convert::{From, TryFrom}; use std::io; use super::{ TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, }; use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType}; use crate::transport::{TReadTransport, TWriteTransport}; use crate::{ProtocolError, ProtocolErrorKind, TConfiguration}; const COMPACT_PROTOCOL_ID: u8 = 0x82; const COMPACT_VERSION: u8 = 0x01; const COMPACT_VERSION_MASK: u8 = 0x1F; /// Read messages encoded in the Thrift compact protocol. /// /// # Examples /// /// Create and use a `TCompactInputProtocol`. /// /// ```no_run /// use thrift::protocol::{TCompactInputProtocol, TInputProtocol}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("localhost:9090").unwrap(); /// /// let mut protocol = TCompactInputProtocol::new(channel); /// /// let recvd_bool = protocol.read_bool().unwrap(); /// let recvd_string = protocol.read_string().unwrap(); /// ``` #[derive(Debug)] pub struct TCompactInputProtocol where T: TReadTransport, { // Identifier of the last field deserialized for a struct. last_read_field_id: i16, // Stack of the last read field ids (a new entry is added each time a nested struct is read). read_field_id_stack: Vec, // Boolean value for a field. // Saved because boolean fields and their value are encoded in a single byte, // and reading the field only occurs after the field id is read. pending_read_bool_value: Option, // Underlying transport used for byte-level operations. transport: T, // Configuration config: TConfiguration, // Current recursion depth recursion_depth: usize, } impl TCompactInputProtocol where T: TReadTransport, { /// Create a `TCompactInputProtocol` that reads bytes from `transport`. pub fn new(transport: T) -> TCompactInputProtocol { Self::with_config(transport, TConfiguration::default()) } /// Create a `TCompactInputProtocol` with custom configuration. pub fn with_config(transport: T, config: TConfiguration) -> TCompactInputProtocol { TCompactInputProtocol { last_read_field_id: 0, read_field_id_stack: Vec::new(), pending_read_bool_value: None, transport, config, recursion_depth: 0, } } fn read_list_set_begin(&mut self) -> crate::Result<(TType, i32)> { let header = self.read_byte()?; let element_type = collection_u8_to_type(header & 0x0F)?; let possible_element_count = (header & 0xF0) >> 4; let element_count = if possible_element_count != 15 { // high bits set high if count and type encoded separately possible_element_count as i32 } else { self.transport.read_varint::()? as i32 }; let min_element_size = self.min_serialized_size(element_type); super::check_container_size(&self.config, element_count, min_element_size)?; Ok((element_type, element_count)) } fn check_recursion_depth(&self) -> crate::Result<()> { if let Some(limit) = self.config.max_recursion_depth() { if self.recursion_depth >= limit { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::DepthLimit, format!("Maximum recursion depth {} exceeded", limit), ))); } } Ok(()) } } impl TInputProtocol for TCompactInputProtocol where T: TReadTransport, { fn read_message_begin(&mut self) -> crate::Result { // TODO: Once specialization is stable, call the message size tracking here let compact_id = self.read_byte()?; if compact_id != COMPACT_PROTOCOL_ID { Err(crate::Error::Protocol(crate::ProtocolError { kind: crate::ProtocolErrorKind::BadVersion, message: format!("invalid compact protocol header {:?}", compact_id), })) } else { Ok(()) }?; let type_and_byte = self.read_byte()?; let received_version = type_and_byte & COMPACT_VERSION_MASK; if received_version != COMPACT_VERSION { Err(crate::Error::Protocol(crate::ProtocolError { kind: crate::ProtocolErrorKind::BadVersion, message: format!( "cannot process compact protocol version {:?}", received_version ), })) } else { Ok(()) }?; // NOTE: unsigned right shift will pad with 0s let message_type: TMessageType = TMessageType::try_from(type_and_byte >> 5)?; // writing side wrote signed sequence number as u32 to avoid zigzag encoding let sequence_number = self.transport.read_varint::()? as i32; let service_call_name = self.read_string()?; self.last_read_field_id = 0; Ok(TMessageIdentifier::new( service_call_name, message_type, sequence_number, )) } fn read_message_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_struct_begin(&mut self) -> crate::Result> { self.check_recursion_depth()?; self.recursion_depth += 1; self.read_field_id_stack.push(self.last_read_field_id); self.last_read_field_id = 0; Ok(None) } fn read_struct_end(&mut self) -> crate::Result<()> { self.recursion_depth -= 1; self.last_read_field_id = self .read_field_id_stack .pop() .expect("should have previous field ids"); Ok(()) } fn read_field_begin(&mut self) -> crate::Result { // we can read at least one byte, which is: // - the type // - the field delta and the type let field_type = self.read_byte()?; let field_delta = (field_type & 0xF0) >> 4; let field_type = match field_type & 0x0F { 0x01 => { self.pending_read_bool_value = Some(true); Ok(TType::Bool) } 0x02 => { self.pending_read_bool_value = Some(false); Ok(TType::Bool) } ttu8 => u8_to_type(ttu8), }?; match field_type { TType::Stop => Ok( TFieldIdentifier::new::, String, Option>( None, TType::Stop, None, ), ), _ => { if field_delta != 0 { self.last_read_field_id = self .last_read_field_id .checked_add(field_delta as i16) .ok_or_else(|| { crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::InvalidData, "field id overflow", )) })?; } else { self.last_read_field_id = self.read_i16()?; }; Ok(TFieldIdentifier { name: None, field_type, id: Some(self.last_read_field_id), }) } } } fn read_field_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_bool(&mut self) -> crate::Result { match self.pending_read_bool_value.take() { Some(b) => Ok(b), 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 { kind: crate::ProtocolErrorKind::InvalidData, message: format!("cannot convert {} into bool", unkn), })), } } } } fn read_bytes(&mut self) -> crate::Result> { let len = self.transport.read_varint::()?; if let Some(max_size) = self.config.max_string_size() { if len as usize > max_size { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::SizeLimit, format!( "Byte array size {} exceeds maximum allowed size of {}", len, max_size ), ))); } } let mut buf = vec![0u8; len as usize]; self.transport .read_exact(&mut buf) .map_err(From::from) .map(|_| buf) } fn read_i8(&mut self) -> crate::Result { self.read_byte().map(|i| i as i8) } fn read_i16(&mut self) -> crate::Result { self.transport.read_varint::().map_err(From::from) } fn read_i32(&mut self) -> crate::Result { self.transport.read_varint::().map_err(From::from) } fn read_i64(&mut self) -> crate::Result { self.transport.read_varint::().map_err(From::from) } fn read_double(&mut self) -> crate::Result { self.transport .read_f64::() .map_err(From::from) } fn read_uuid(&mut self) -> crate::Result { let mut buf = [0u8; 16]; self.transport .read_exact(&mut buf) .map(|_| uuid::Uuid::from_bytes(buf)) .map_err(From::from) } fn read_string(&mut self) -> crate::Result { let bytes = self.read_bytes()?; String::from_utf8(bytes).map_err(From::from) } fn read_list_begin(&mut self) -> crate::Result { let (element_type, element_count) = self.read_list_set_begin()?; Ok(TListIdentifier::new(element_type, element_count)) } fn read_list_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_set_begin(&mut self) -> crate::Result { let (element_type, element_count) = self.read_list_set_begin()?; Ok(TSetIdentifier::new(element_type, element_count)) } fn read_set_end(&mut self) -> crate::Result<()> { Ok(()) } fn read_map_begin(&mut self) -> crate::Result { let element_count = self.transport.read_varint::()? as i32; if element_count == 0 { Ok(TMapIdentifier::new(None, None, 0)) } else { let type_header = self.read_byte()?; let key_type = collection_u8_to_type((type_header & 0xF0) >> 4)?; let val_type = collection_u8_to_type(type_header & 0x0F)?; let key_min_size = self.min_serialized_size(key_type); let value_min_size = self.min_serialized_size(val_type); let element_size = key_min_size + value_min_size; super::check_container_size(&self.config, element_count, element_size)?; Ok(TMapIdentifier::new(key_type, val_type, element_count)) } } fn read_map_end(&mut self) -> crate::Result<()> { Ok(()) } // utility // fn read_byte(&mut self) -> crate::Result { let mut buf = [0u8; 1]; self.transport .read_exact(&mut buf) .map_err(From::from) .map(|_| buf[0]) } fn min_serialized_size(&self, field_type: TType) -> usize { compact_protocol_min_serialized_size(field_type) } } pub(crate) fn compact_protocol_min_serialized_size(field_type: TType) -> usize { match field_type { TType::Stop => 1, // 1 byte TType::Void => 1, // 1 byte TType::Bool => 1, // 1 byte TType::I08 => 1, // 1 byte TType::Double => 8, // 8 bytes (not varint encoded) TType::I16 => 1, // 1 byte minimum (varint) TType::I32 => 1, // 1 byte minimum (varint) TType::I64 => 1, // 1 byte minimum (varint) TType::String => 1, // 1 byte minimum for length (varint) TType::Struct => 1, // 1 byte minimum (stop field) TType::Map => 1, // 1 byte minimum TType::Set => 1, // 1 byte minimum TType::List => 1, // 1 byte minimum TType::Uuid => 16, // 16 bytes TType::Utf7 => 1, // 1 byte } } impl io::Seek for TCompactInputProtocol where T: io::Seek + TReadTransport, { fn seek(&mut self, pos: io::SeekFrom) -> io::Result { self.transport.seek(pos) } } /// Factory for creating instances of `TCompactInputProtocol`. #[derive(Default)] pub struct TCompactInputProtocolFactory; impl TCompactInputProtocolFactory { /// Create a `TCompactInputProtocolFactory`. pub fn new() -> TCompactInputProtocolFactory { TCompactInputProtocolFactory {} } } impl TInputProtocolFactory for TCompactInputProtocolFactory { fn create(&self, transport: Box) -> Box { Box::new(TCompactInputProtocol::new(transport)) } } /// Write messages using the Thrift compact protocol. /// /// # Examples /// /// Create and use a `TCompactOutputProtocol`. /// /// ```no_run /// use thrift::protocol::{TCompactOutputProtocol, TOutputProtocol}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("localhost:9090").unwrap(); /// /// let mut protocol = TCompactOutputProtocol::new(channel); /// /// protocol.write_bool(true).unwrap(); /// protocol.write_string("test_string").unwrap(); /// ``` #[derive(Debug)] pub struct TCompactOutputProtocol where T: TWriteTransport, { // Identifier of the last field serialized for a struct. last_write_field_id: i16, // Stack of the last written field ids (new entry added each time a nested struct is written). write_field_id_stack: Vec, // Field identifier of the boolean field to be written. // Saved because boolean fields and their value are encoded in a single byte pending_write_bool_field_identifier: Option, // Underlying transport used for byte-level operations. transport: T, } impl TCompactOutputProtocol where T: TWriteTransport, { /// Create a `TCompactOutputProtocol` that writes bytes to `transport`. pub fn new(transport: T) -> TCompactOutputProtocol { TCompactOutputProtocol { last_write_field_id: 0, write_field_id_stack: Vec::new(), pending_write_bool_field_identifier: None, transport, } } // FIXME: field_type as unconstrained u8 is bad fn write_field_header(&mut self, field_type: u8, field_id: i16) -> crate::Result<()> { let field_delta = field_id - self.last_write_field_id; if field_delta > 0 && field_delta < 15 { self.write_byte(((field_delta as u8) << 4) | field_type)?; } else { self.write_byte(field_type)?; self.write_i16(field_id)?; } self.last_write_field_id = field_id; Ok(()) } fn write_list_set_begin( &mut self, element_type: TType, element_count: i32, ) -> crate::Result<()> { let elem_identifier = collection_type_to_u8(element_type); if element_count <= 14 { let header = ((element_count as u8) << 4) | elem_identifier; self.write_byte(header) } else { let header = 0xF0 | elem_identifier; self.write_byte(header)?; // element count is strictly positive as per the spec, so // cast i32 as u32 so that varint writing won't use zigzag encoding self.transport .write_varint(element_count as u32) .map_err(From::from) .map(|_| ()) } } fn assert_no_pending_bool_write(&self) { if let Some(ref f) = self.pending_write_bool_field_identifier { panic!("pending bool field {:?} not written", f) } } } impl TOutputProtocol for TCompactOutputProtocol where T: TWriteTransport, { fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> { self.write_byte(COMPACT_PROTOCOL_ID)?; self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?; // cast i32 as u32 so that varint writing won't use zigzag encoding self.transport .write_varint(identifier.sequence_number as u32)?; self.write_string(&identifier.name)?; Ok(()) } fn write_message_end(&mut self) -> crate::Result<()> { self.assert_no_pending_bool_write(); Ok(()) } fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> { self.write_field_id_stack.push(self.last_write_field_id); self.last_write_field_id = 0; Ok(()) } fn write_struct_end(&mut self) -> crate::Result<()> { self.assert_no_pending_bool_write(); self.last_write_field_id = self .write_field_id_stack .pop() .expect("should have previous field ids"); Ok(()) } fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> { match identifier.field_type { TType::Bool => { if self.pending_write_bool_field_identifier.is_some() { panic!( "should not have a pending bool while writing another bool with id: \ {:?}", identifier ) } self.pending_write_bool_field_identifier = Some(identifier.clone()); Ok(()) } _ => { let field_type = type_to_u8(identifier.field_type); let field_id = identifier.id.expect("non-stop field should have field id"); self.write_field_header(field_type, field_id) } } } fn write_field_end(&mut self) -> crate::Result<()> { self.assert_no_pending_bool_write(); Ok(()) } fn write_field_stop(&mut self) -> crate::Result<()> { self.assert_no_pending_bool_write(); self.write_byte(type_to_u8(TType::Stop)) } fn write_bool(&mut self, b: bool) -> crate::Result<()> { match self.pending_write_bool_field_identifier.take() { Some(pending) => { let field_id = pending.id.expect("bool field should have a field id"); let field_type_as_u8 = if b { 0x01 } else { 0x02 }; self.write_field_header(field_type_as_u8, field_id) } None => { if b { self.write_byte(0x01) } else { self.write_byte(0x02) } } } } fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> { // length is strictly positive as per the spec, so // cast i32 as u32 so that varint writing won't use zigzag encoding self.transport.write_varint(b.len() as u32)?; self.transport.write_all(b).map_err(From::from) } fn write_i8(&mut self, i: i8) -> crate::Result<()> { self.write_byte(i as u8) } fn write_i16(&mut self, i: i16) -> crate::Result<()> { self.transport .write_varint(i) .map_err(From::from) .map(|_| ()) } fn write_i32(&mut self, i: i32) -> crate::Result<()> { self.transport .write_varint(i) .map_err(From::from) .map(|_| ()) } fn write_i64(&mut self, i: i64) -> crate::Result<()> { self.transport .write_varint(i) .map_err(From::from) .map(|_| ()) } fn write_double(&mut self, d: f64) -> crate::Result<()> { self.transport .write_f64::(d) .map_err(From::from) } fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> { self.transport .write_all(uuid.as_bytes()) .map_err(From::from) } fn write_string(&mut self, s: &str) -> crate::Result<()> { self.write_bytes(s.as_bytes()) } fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> { self.write_list_set_begin(identifier.element_type, identifier.size) } fn write_list_end(&mut self) -> crate::Result<()> { Ok(()) } fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> { self.write_list_set_begin(identifier.element_type, identifier.size) } fn write_set_end(&mut self) -> crate::Result<()> { Ok(()) } fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> { if identifier.size == 0 { self.write_byte(0) } else { // element count is strictly positive as per the spec, so // cast i32 as u32 so that varint writing won't use zigzag encoding self.transport.write_varint(identifier.size as u32)?; let key_type = identifier .key_type .expect("map identifier to write should contain key type"); let key_type_byte = collection_type_to_u8(key_type) << 4; let val_type = identifier .value_type .expect("map identifier to write should contain value type"); let val_type_byte = collection_type_to_u8(val_type); let map_type_header = key_type_byte | val_type_byte; self.write_byte(map_type_header) } } fn write_map_end(&mut self) -> crate::Result<()> { Ok(()) } fn flush(&mut self) -> crate::Result<()> { self.transport.flush().map_err(From::from) } // utility // fn write_byte(&mut self, b: u8) -> crate::Result<()> { self.transport.write(&[b]).map_err(From::from).map(|_| ()) } } /// Factory for creating instances of `TCompactOutputProtocol`. #[derive(Default)] pub struct TCompactOutputProtocolFactory; impl TCompactOutputProtocolFactory { /// Create a `TCompactOutputProtocolFactory`. pub fn new() -> TCompactOutputProtocolFactory { TCompactOutputProtocolFactory {} } } impl TOutputProtocolFactory for TCompactOutputProtocolFactory { fn create( &self, transport: Box, ) -> Box { Box::new(TCompactOutputProtocol::new(transport)) } } fn collection_type_to_u8(field_type: TType) -> u8 { match field_type { TType::Bool => 0x01, f => type_to_u8(f), } } fn type_to_u8(field_type: TType) -> u8 { match field_type { TType::Stop => 0x00, TType::I08 => 0x03, // equivalent to TType::Byte TType::I16 => 0x04, TType::I32 => 0x05, TType::I64 => 0x06, TType::Double => 0x07, TType::String => 0x08, TType::List => 0x09, TType::Set => 0x0A, TType::Map => 0x0B, TType::Struct => 0x0C, TType::Uuid => 0x0D, _ => panic!("should not have attempted to convert {} to u8", field_type), } } fn collection_u8_to_type(b: u8) -> crate::Result { match b { // 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), } } fn u8_to_type(b: u8) -> crate::Result { match b { 0x00 => Ok(TType::Stop), 0x03 => Ok(TType::I08), // equivalent to TType::Byte 0x04 => Ok(TType::I16), 0x05 => Ok(TType::I32), 0x06 => Ok(TType::I64), 0x07 => Ok(TType::Double), 0x08 => Ok(TType::String), 0x09 => Ok(TType::List), 0x0A => Ok(TType::Set), 0x0B => Ok(TType::Map), 0x0C => Ok(TType::Struct), 0x0D => Ok(TType::Uuid), unkn => Err(crate::Error::Protocol(crate::ProtocolError { kind: crate::ProtocolErrorKind::InvalidData, message: format!("cannot convert {} into TType", unkn), })), } } #[cfg(test)] mod tests { use crate::protocol::{ TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType, }; use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf}; use super::*; #[test] fn must_write_message_begin_largest_maximum_positive_sequence_number() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "bar", TMessageType::Reply, i32::MAX ))); #[rustfmt::skip] let expected: [u8; 11] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0xFF, 0xFF, 0xFF, 0xFF, 0x07, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_largest_maximum_positive_sequence_number() { let (mut i_prot, _) = test_objects(); #[rustfmt::skip] let source_bytes: [u8; 11] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0xFF, 0xFF, 0xFF, 0xFF, 0x07, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("bar", TMessageType::Reply, i32::MAX); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_write_message_begin_positive_sequence_number_0() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "foo", TMessageType::Call, 431 ))); #[rustfmt::skip] let expected: [u8; 8] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0xAF, 0x03, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F /* "foo" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_positive_sequence_number_0() { let (mut i_prot, _) = test_objects(); #[rustfmt::skip] let source_bytes: [u8; 8] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0xAF, 0x03, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F /* "foo" */, ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("foo", TMessageType::Call, 431); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_write_message_begin_positive_sequence_number_1() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "bar", TMessageType::Reply, 991_828 ))); #[rustfmt::skip] let expected: [u8; 9] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0xD4, 0xC4, 0x3C, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_positive_sequence_number_1() { let (mut i_prot, _) = test_objects(); #[rustfmt::skip] let source_bytes: [u8; 9] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0xD4, 0xC4, 0x3C, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("bar", TMessageType::Reply, 991_828); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_write_message_begin_zero_sequence_number() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "bar", TMessageType::Reply, 0 ))); #[rustfmt::skip] let expected: [u8; 7] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0x00, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_zero_sequence_number() { let (mut i_prot, _) = test_objects(); #[rustfmt::skip] let source_bytes: [u8; 7] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0x00, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("bar", TMessageType::Reply, 0); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_write_message_begin_largest_minimum_negative_sequence_number() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "bar", TMessageType::Reply, i32::MIN ))); // two's complement notation of i32::MIN = 1000_0000_0000_0000_0000_0000_0000_0000 #[rustfmt::skip] let expected: [u8; 11] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0x80, 0x80, 0x80, 0x80, 0x08, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_largest_minimum_negative_sequence_number() { let (mut i_prot, _) = test_objects(); // two's complement notation of i32::MIN = 1000_0000_0000_0000_0000_0000_0000_0000 #[rustfmt::skip] let source_bytes: [u8; 11] = [ 0x82, /* protocol ID */ 0x41, /* message type | protocol version */ 0x80, 0x80, 0x80, 0x80, 0x08, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x62, 0x61, 0x72 /* "bar" */, ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("bar", TMessageType::Reply, i32::MIN); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_write_message_begin_negative_sequence_number_0() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "foo", TMessageType::Call, -431 ))); // signed two's complement of -431 = 1111_1111_1111_1111_1111_1110_0101_0001 #[rustfmt::skip] let expected: [u8; 11] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0xD1, 0xFC, 0xFF, 0xFF, 0x0F, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F /* "foo" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_negative_sequence_number_0() { let (mut i_prot, _) = test_objects(); // signed two's complement of -431 = 1111_1111_1111_1111_1111_1110_0101_0001 #[rustfmt::skip] let source_bytes: [u8; 11] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0xD1, 0xFC, 0xFF, 0xFF, 0x0F, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F /* "foo" */, ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("foo", TMessageType::Call, -431); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_write_message_begin_negative_sequence_number_1() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "foo", TMessageType::Call, -73_184_125 ))); // signed two's complement of -73184125 = 1111_1011_1010_0011_0100_1100_1000_0011 #[rustfmt::skip] let expected: [u8; 11] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0x83, 0x99, 0x8D, 0xDD, 0x0F, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F /* "foo" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_negative_sequence_number_1() { let (mut i_prot, _) = test_objects(); // signed two's complement of -73184125 = 1111_1011_1010_0011_0100_1100_1000_0011 #[rustfmt::skip] let source_bytes: [u8; 11] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0x83, 0x99, 0x8D, 0xDD, 0x0F, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F /* "foo" */, ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("foo", TMessageType::Call, -73_184_125); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_write_message_begin_negative_sequence_number_2() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new( "foo", TMessageType::Call, -1_073_741_823 ))); // signed two's complement of -1073741823 = 1100_0000_0000_0000_0000_0000_0000_0001 #[rustfmt::skip] let expected: [u8; 11] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0x81, 0x80, 0x80, 0x80, 0x0C, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F /* "foo" */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_message_begin_negative_sequence_number_2() { let (mut i_prot, _) = test_objects(); // signed two's complement of -1073741823 = 1100_0000_0000_0000_0000_0000_0000_0001 #[rustfmt::skip] let source_bytes: [u8; 11] = [ 0x82, /* protocol ID */ 0x21, /* message type | protocol version */ 0x81, 0x80, 0x80, 0x80, 0x0C, /* non-zig-zag varint sequence number */ 0x03, /* message-name length */ 0x66, 0x6F, 0x6F, /* "foo" */ ]; i_prot.transport.set_readable_bytes(&source_bytes); let expected = TMessageIdentifier::new("foo", TMessageType::Call, -1_073_741_823); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&expected, &res); } #[test] fn must_round_trip_upto_i64_maxvalue() { // See https://issues.apache.org/jira/browse/THRIFT-5131 for i in 0..64 { let (mut i_prot, mut o_prot) = test_objects(); let val: i64 = ((1u64 << i) - 1) as i64; o_prot .write_field_begin(&TFieldIdentifier::new("val", TType::I64, 1)) .unwrap(); o_prot.write_i64(val).unwrap(); o_prot.write_field_end().unwrap(); o_prot.flush().unwrap(); copy_write_buffer_to_read_buffer!(o_prot); i_prot.read_field_begin().unwrap(); assert_eq!(val, i_prot.read_i64().unwrap()); } } #[test] fn must_round_trip_message_begin() { let (mut i_prot, mut o_prot) = test_objects(); let ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1_283_948); assert_success!(o_prot.write_message_begin(&ident)); copy_write_buffer_to_read_buffer!(o_prot); let res = assert_success!(i_prot.read_message_begin()); assert_eq!(&res, &ident); } #[test] fn must_write_message_end() { assert_no_write(|o| o.write_message_end()); } // NOTE: structs and fields are tested together // #[test] fn must_write_struct_with_delta_fields() { let (_, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with tiny field ids // since they're small the field ids will be encoded as deltas // since this is the first field (and it's zero) it gets the full varint write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 0))); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I16, 4))); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::List, 9))); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 5] = [ 0x03, /* field type */ 0x00, /* first field id */ 0x44, /* field delta (4) | field type */ 0x59, /* field delta (5) | field type */ 0x00 /* field stop */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_struct_with_delta_fields() { let (mut i_prot, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with tiny field ids // since they're small the field ids will be encoded as deltas // since this is the first field (and it's zero) it gets the full varint write let field_ident_1 = TFieldIdentifier::new("foo", TType::I08, 0); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta let field_ident_2 = TFieldIdentifier::new("foo", TType::I16, 4); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta let field_ident_3 = TFieldIdentifier::new("foo", TType::List, 9); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read the struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_struct_with_non_zero_initial_field_and_delta_fields() { let (_, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with tiny field ids // since they're small the field ids will be encoded as deltas // gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 1))); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2))); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 6))); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 4] = [ 0x15, /* field delta (1) | field type */ 0x1A, /* field delta (1) | field type */ 0x48, /* field delta (4) | field type */ 0x00 /* field stop */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_struct_with_non_zero_initial_field_and_delta_fields() { let (mut i_prot, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with tiny field ids // since they're small the field ids will be encoded as deltas // gets a delta write let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 1); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta let field_ident_2 = TFieldIdentifier::new("foo", TType::Set, 2); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it can be encoded as a delta let field_ident_3 = TFieldIdentifier::new("foo", TType::String, 6); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read the struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_struct_with_long_fields() { let (_, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with field ids that cannot be encoded as deltas // since this is the first field (and it's zero) it gets the full varint write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 0))); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 16))); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 99))); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 8] = [ 0x05, /* field type */ 0x00, /* first field id */ 0x06, /* field type */ 0x20, /* zig-zag varint field id */ 0x0A, /* field type */ 0xC6, 0x01, /* zig-zag varint field id */ 0x00 /* field stop */, ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_struct_with_long_fields() { let (mut i_prot, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with field ids that cannot be encoded as deltas // since this is the first field (and it's zero) it gets the full varint write let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 0); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint let field_ident_2 = TFieldIdentifier::new("foo", TType::I64, 16); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 99); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read the struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_struct_with_mix_of_long_and_delta_fields() { let (_, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with field ids that cannot be encoded as deltas // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1))); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9))); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 1000))); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2001))); assert_success!(o_prot.write_field_end()); // since this is only 3 up from the previous it is recorded as a delta assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2004))); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 10] = [ 0x16, /* field delta (1) | field type */ 0x85, /* field delta (8) | field type */ 0x0A, /* field type */ 0xD0, 0x0F, /* zig-zag varint field id */ 0x0A, /* field type */ 0xA2, 0x1F, /* zig-zag varint field id */ 0x3A, /* field delta (3) | field type */ 0x00 /* field stop */, ]; assert_eq_written_bytes!(o_prot, expected); } #[allow(clippy::cognitive_complexity)] #[test] fn must_round_trip_struct_with_mix_of_long_and_delta_fields() { let (mut i_prot, mut o_prot) = test_objects(); // no bytes should be written however let struct_ident = TStructIdentifier::new("foo"); assert_success!(o_prot.write_struct_begin(&struct_ident)); // write three fields with field ids that cannot be encoded as deltas // since the delta is > 0 and < 15 it gets a delta write let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it gets a delta write let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 1000); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // since this delta is > 15 it is encoded as a zig-zag varint let field_ident_4 = TFieldIdentifier::new("foo", TType::Set, 2001); assert_success!(o_prot.write_field_begin(&field_ident_4)); assert_success!(o_prot.write_field_end()); // since this is only 3 up from the previous it is recorded as a delta let field_ident_5 = TFieldIdentifier::new("foo", TType::Set, 2004); assert_success!(o_prot.write_field_begin(&field_ident_5)); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read the struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, ..field_ident_4 } ); assert_success!(i_prot.read_field_end()); let read_ident_5 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_5, TFieldIdentifier { name: None, ..field_ident_5 } ); assert_success!(i_prot.read_field_end()); let read_ident_6 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_6, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_nested_structs_0() { // last field of the containing struct is a delta // first field of the the contained struct is a delta let (_, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1))); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9))); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 7))); assert_success!(o_prot.write_field_end()); // contained struct // since this delta > 15 it gets a full write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24))); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 7] = [ 0x16, /* field delta (1) | field type */ 0x85, /* field delta (8) | field type */ 0x73, /* field delta (7) | field type */ 0x07, /* field type */ 0x30, /* zig-zag varint field id */ 0x00, /* field stop - contained */ 0x00 /* field stop - containing */, ]; assert_eq_written_bytes!(o_prot, expected); } #[allow(clippy::cognitive_complexity)] #[test] fn must_round_trip_nested_structs_0() { // last field of the containing struct is a delta // first field of the the contained struct is a delta let (mut i_prot, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 0 and < 15 it gets a delta write let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_3 = TFieldIdentifier::new("foo", TType::I08, 7); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // contained struct // since this delta > 15 it gets a full write let field_ident_4 = TFieldIdentifier::new("foo", TType::Double, 24); assert_success!(o_prot.write_field_begin(&field_ident_4)); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read containing struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); // read contained struct back assert_success!(i_prot.read_struct_begin()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, ..field_ident_4 } ); assert_success!(i_prot.read_field_end()); // end contained struct let read_ident_6 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_6, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); // end containing struct let read_ident_7 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_7, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_nested_structs_1() { // last field of the containing struct is a delta // first field of the the contained struct is a full write let (_, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1))); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9))); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since this delta > 15 it gets a full write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24))); assert_success!(o_prot.write_field_end()); // contained struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27))); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 7] = [ 0x16, /* field delta (1) | field type */ 0x85, /* field delta (8) | field type */ 0x07, /* field type */ 0x30, /* zig-zag varint field id */ 0x33, /* field delta (3) | field type */ 0x00, /* field stop - contained */ 0x00 /* field stop - containing */, ]; assert_eq_written_bytes!(o_prot, expected); } #[allow(clippy::cognitive_complexity)] #[test] fn must_round_trip_nested_structs_1() { // last field of the containing struct is a delta // first field of the the contained struct is a full write let (mut i_prot, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 0 and < 15 it gets a delta write let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since this delta > 15 it gets a full write let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 24); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // contained struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27); assert_success!(o_prot.write_field_begin(&field_ident_4)); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read containing struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); // read contained struct back assert_success!(i_prot.read_struct_begin()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, ..field_ident_4 } ); assert_success!(i_prot.read_field_end()); // end contained struct let read_ident_6 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_6, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); // end containing struct let read_ident_7 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_7, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_nested_structs_2() { // last field of the containing struct is a full write // first field of the the contained struct is a delta write let (_, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1))); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 15 it gets a full write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21))); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since this delta > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 7))); assert_success!(o_prot.write_field_end()); // contained struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 10))); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 7] = [ 0x16, /* field delta (1) | field type */ 0x08, /* field type */ 0x2A, /* zig-zag varint field id */ 0x77, /* field delta(7) | field type */ 0x33, /* field delta (3) | field type */ 0x00, /* field stop - contained */ 0x00 /* field stop - containing */, ]; assert_eq_written_bytes!(o_prot, expected); } #[allow(clippy::cognitive_complexity)] #[test] fn must_round_trip_nested_structs_2() { let (mut i_prot, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 15 it gets a full write let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since this delta > 0 and < 15 it gets a delta write let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 7); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // contained struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 10); assert_success!(o_prot.write_field_begin(&field_ident_4)); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read containing struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); // read contained struct back assert_success!(i_prot.read_struct_begin()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, ..field_ident_4 } ); assert_success!(i_prot.read_field_end()); // end contained struct let read_ident_6 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_6, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); // end containing struct let read_ident_7 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_7, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_nested_structs_3() { // last field of the containing struct is a full write // first field of the the contained struct is a full write let (_, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1))); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 15 it gets a full write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21))); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since this delta > 15 it gets a full write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 21))); assert_success!(o_prot.write_field_end()); // contained struct // since the delta is > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27))); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 8] = [ 0x16, /* field delta (1) | field type */ 0x08, /* field type */ 0x2A, /* zig-zag varint field id */ 0x07, /* field type */ 0x2A, /* zig-zag varint field id */ 0x63, /* field delta (6) | field type */ 0x00, /* field stop - contained */ 0x00 /* field stop - containing */, ]; assert_eq_written_bytes!(o_prot, expected); } #[allow(clippy::cognitive_complexity)] #[test] fn must_round_trip_nested_structs_3() { // last field of the containing struct is a full write // first field of the the contained struct is a full write let (mut i_prot, mut o_prot) = test_objects(); // start containing struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // containing struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_field_end()); // containing struct // since this delta > 15 it gets a full write let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_field_end()); // start contained struct assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // contained struct // since this delta > 15 it gets a full write let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 21); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_field_end()); // contained struct // since the delta is > 0 and < 15 it gets a delta write let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27); assert_success!(o_prot.write_field_begin(&field_ident_4)); assert_success!(o_prot.write_field_end()); // end contained struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); // end containing struct assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read containing struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); assert_success!(i_prot.read_field_end()); // read contained struct back assert_success!(i_prot.read_struct_begin()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, ..field_ident_4 } ); assert_success!(i_prot.read_field_end()); // end contained struct let read_ident_6 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_6, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); // end containing struct let read_ident_7 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_7, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] fn must_write_bool_field() { let (_, mut o_prot) = test_objects(); // no bytes should be written however assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); // write three fields with field ids that cannot be encoded as deltas // since the delta is > 0 and < 16 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1))); assert_success!(o_prot.write_bool(true)); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it gets a delta write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 9))); assert_success!(o_prot.write_bool(false)); assert_success!(o_prot.write_field_end()); // since this delta > 15 it gets a full write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 26))); assert_success!(o_prot.write_bool(true)); assert_success!(o_prot.write_field_end()); // since this delta > 15 it gets a full write assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 45))); assert_success!(o_prot.write_bool(false)); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); #[rustfmt::skip] let expected: [u8; 7] = [ 0x11, /* field delta (1) | true */ 0x82, /* field delta (8) | false */ 0x01, /* true */ 0x34, /* field id */ 0x02, /* false */ 0x5A, /* field id */ 0x00 /* stop field */, ]; assert_eq_written_bytes!(o_prot, expected); } #[allow(clippy::cognitive_complexity)] #[test] fn must_round_trip_bool_field() { let (mut i_prot, mut o_prot) = test_objects(); // no bytes should be written however let struct_ident = TStructIdentifier::new("foo"); assert_success!(o_prot.write_struct_begin(&struct_ident)); // write two fields // since the delta is > 0 and < 16 it gets a delta write let field_ident_1 = TFieldIdentifier::new("foo", TType::Bool, 1); assert_success!(o_prot.write_field_begin(&field_ident_1)); assert_success!(o_prot.write_bool(true)); assert_success!(o_prot.write_field_end()); // since this delta > 0 and < 15 it gets a delta write let field_ident_2 = TFieldIdentifier::new("foo", TType::Bool, 9); assert_success!(o_prot.write_field_begin(&field_ident_2)); assert_success!(o_prot.write_bool(false)); assert_success!(o_prot.write_field_end()); // since this delta > 15 it gets a full write let field_ident_3 = TFieldIdentifier::new("foo", TType::Bool, 26); assert_success!(o_prot.write_field_begin(&field_ident_3)); assert_success!(o_prot.write_bool(true)); assert_success!(o_prot.write_field_end()); // since this delta > 15 it gets a full write let field_ident_4 = TFieldIdentifier::new("foo", TType::Bool, 45); assert_success!(o_prot.write_field_begin(&field_ident_4)); assert_success!(o_prot.write_bool(false)); assert_success!(o_prot.write_field_end()); // now, finish the struct off assert_success!(o_prot.write_field_stop()); assert_success!(o_prot.write_struct_end()); copy_write_buffer_to_read_buffer!(o_prot); // read the struct back assert_success!(i_prot.read_struct_begin()); let read_ident_1 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_1, TFieldIdentifier { name: None, ..field_ident_1 } ); let read_value_1 = assert_success!(i_prot.read_bool()); assert!(read_value_1); assert_success!(i_prot.read_field_end()); let read_ident_2 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_2, TFieldIdentifier { name: None, ..field_ident_2 } ); let read_value_2 = assert_success!(i_prot.read_bool()); assert!(!read_value_2); assert_success!(i_prot.read_field_end()); let read_ident_3 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_3, TFieldIdentifier { name: None, ..field_ident_3 } ); let read_value_3 = assert_success!(i_prot.read_bool()); assert!(read_value_3); assert_success!(i_prot.read_field_end()); let read_ident_4 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_4, TFieldIdentifier { name: None, ..field_ident_4 } ); let read_value_4 = assert_success!(i_prot.read_bool()); assert!(!read_value_4); assert_success!(i_prot.read_field_end()); let read_ident_5 = assert_success!(i_prot.read_field_begin()); assert_eq!( read_ident_5, TFieldIdentifier { name: None, field_type: TType::Stop, id: None, } ); assert_success!(i_prot.read_struct_end()); } #[test] #[should_panic] fn must_fail_if_write_field_end_without_writing_bool_value() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1))); o_prot.write_field_end().unwrap(); } #[test] #[should_panic] fn must_fail_if_write_stop_field_without_writing_bool_value() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1))); o_prot.write_field_stop().unwrap(); } #[test] #[should_panic] fn must_fail_if_write_struct_end_without_writing_bool_value() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo"))); assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1))); o_prot.write_struct_end().unwrap(); } #[test] #[should_panic] fn must_fail_if_write_struct_end_without_any_fields() { let (_, mut o_prot) = test_objects(); o_prot.write_struct_end().unwrap(); } #[test] fn must_write_field_end() { assert_no_write(|o| o.write_field_end()); } #[test] fn must_write_small_sized_list_begin() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_list_begin(&TListIdentifier::new(TType::I64, 4))); let expected: [u8; 1] = [0x46 /* size | elem_type */]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_small_sized_list_begin() { let (mut i_prot, mut o_prot) = test_objects(); let ident = TListIdentifier::new(TType::I32, 3); assert_success!(o_prot.write_list_begin(&ident)); assert_success!(o_prot.write_i32(100)); assert_success!(o_prot.write_i32(200)); assert_success!(o_prot.write_i32(300)); assert_success!(o_prot.write_list_end()); copy_write_buffer_to_read_buffer!(o_prot); let res = assert_success!(i_prot.read_list_begin()); assert_eq!(&res, &ident); assert_eq!(i_prot.read_i32().unwrap(), 100); assert_eq!(i_prot.read_i32().unwrap(), 200); assert_eq!(i_prot.read_i32().unwrap(), 300); assert_success!(i_prot.read_list_end()); } #[test] fn must_write_large_sized_list_begin() { let (_, mut o_prot) = test_objects(); let res = o_prot.write_list_begin(&TListIdentifier::new(TType::List, 9999)); assert!(res.is_ok()); let expected: [u8; 3] = [ 0xF9, /* 0xF0 | elem_type */ 0x8F, 0x4E, /* size as varint */ ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_large_sized_list_begin() { let (mut i_prot, mut o_prot) = test_objects_no_limits(); let ident = TListIdentifier::new(TType::Set, 47381); assert_success!(o_prot.write_list_begin(&ident)); copy_write_buffer_to_read_buffer!(o_prot); let res = assert_success!(i_prot.read_list_begin()); assert_eq!(&res, &ident); } #[test] fn must_write_list_end() { assert_no_write(|o| o.write_list_end()); } #[test] fn must_write_small_sized_set_begin() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Struct, 2))); let expected: [u8; 1] = [0x2C /* size | elem_type */]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_small_sized_set_begin() { let (mut i_prot, mut o_prot) = test_objects(); let ident = TSetIdentifier::new(TType::I16, 3); assert_success!(o_prot.write_set_begin(&ident)); assert_success!(o_prot.write_i16(111)); assert_success!(o_prot.write_i16(222)); assert_success!(o_prot.write_i16(333)); assert_success!(o_prot.write_set_end()); copy_write_buffer_to_read_buffer!(o_prot); let res = assert_success!(i_prot.read_set_begin()); assert_eq!(&res, &ident); assert_eq!(i_prot.read_i16().unwrap(), 111); assert_eq!(i_prot.read_i16().unwrap(), 222); assert_eq!(i_prot.read_i16().unwrap(), 333); assert_success!(i_prot.read_set_end()); } #[test] fn must_write_large_sized_set_begin() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Double, 23891))); let expected: [u8; 4] = [ 0xF7, /* 0xF0 | elem_type */ 0xD3, 0xBA, 0x01, /* size as varint */ ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_large_sized_set_begin() { let (mut i_prot, mut o_prot) = test_objects_no_limits(); let ident = TSetIdentifier::new(TType::Map, 3_928_429); assert_success!(o_prot.write_set_begin(&ident)); copy_write_buffer_to_read_buffer!(o_prot); let res = assert_success!(i_prot.read_set_begin()); assert_eq!(&res, &ident); } #[test] fn must_write_set_end() { assert_no_write(|o| o.write_set_end()); } #[test] fn must_write_zero_sized_map_begin() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::String, TType::I32, 0))); let expected: [u8; 1] = [0x00]; // since size is zero we don't write anything assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_read_zero_sized_map_begin() { let (mut i_prot, mut o_prot) = test_objects(); assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::I32, 0))); copy_write_buffer_to_read_buffer!(o_prot); let res = assert_success!(i_prot.read_map_begin()); assert_eq!( &res, &TMapIdentifier { key_type: None, value_type: None, size: 0, } ); } #[test] fn must_write_map_begin() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_map_begin(&TMapIdentifier::new( TType::Double, TType::String, 238 ))); let expected: [u8; 3] = [ 0xEE, 0x01, /* size as varint */ 0x78, /* key type | val type */ ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_map_begin() { let (mut i_prot, mut o_prot) = test_objects_no_limits(); let ident = TMapIdentifier::new(TType::Map, TType::List, 1_928_349); assert_success!(o_prot.write_map_begin(&ident)); copy_write_buffer_to_read_buffer!(o_prot); let res = assert_success!(i_prot.read_map_begin()); assert_eq!(&res, &ident); } #[test] fn must_write_map_end() { assert_no_write(|o| o.write_map_end()); } #[test] fn must_write_map_with_bool_key_and_value() { let (_, mut o_prot) = test_objects(); assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Bool, TType::Bool, 1))); assert_success!(o_prot.write_bool(true)); assert_success!(o_prot.write_bool(false)); assert_success!(o_prot.write_map_end()); let expected: [u8; 4] = [ 0x01, /* size as varint */ 0x11, /* key type | val type */ 0x01, /* key: true */ 0x02, /* val: false */ ]; assert_eq_written_bytes!(o_prot, expected); } #[test] fn must_round_trip_map_with_bool_value() { let (mut i_prot, mut o_prot) = test_objects(); let map_ident = TMapIdentifier::new(TType::Bool, TType::Bool, 2); assert_success!(o_prot.write_map_begin(&map_ident)); assert_success!(o_prot.write_bool(true)); assert_success!(o_prot.write_bool(false)); assert_success!(o_prot.write_bool(false)); assert_success!(o_prot.write_bool(true)); assert_success!(o_prot.write_map_end()); copy_write_buffer_to_read_buffer!(o_prot); // map header let rcvd_ident = assert_success!(i_prot.read_map_begin()); assert_eq!(&rcvd_ident, &map_ident); // key 1 let b = assert_success!(i_prot.read_bool()); assert!(b); // val 1 let b = assert_success!(i_prot.read_bool()); assert!(!b); // key 2 let b = assert_success!(i_prot.read_bool()); assert!(!b); // val 2 let b = assert_success!(i_prot.read_bool()); assert!(b); // map end assert_success!(i_prot.read_map_end()); } #[test] fn must_read_map_end() { let (mut i_prot, _) = test_objects(); assert!(i_prot.read_map_end().is_ok()); // will blow up if we try to read from empty buffer } fn test_objects() -> ( TCompactInputProtocol>, TCompactOutputProtocol>, ) { let mem = TBufferChannel::with_capacity(200, 200); let (r_mem, w_mem) = mem.split().unwrap(); let i_prot = TCompactInputProtocol::new(r_mem); let o_prot = TCompactOutputProtocol::new(w_mem); (i_prot, o_prot) } fn test_objects_no_limits() -> ( TCompactInputProtocol>, TCompactOutputProtocol>, ) { let mem = TBufferChannel::with_capacity(200, 200); let (r_mem, w_mem) = mem.split().unwrap(); let i_prot = TCompactInputProtocol::with_config(r_mem, TConfiguration::no_limits()); let o_prot = TCompactOutputProtocol::new(w_mem); (i_prot, o_prot) } #[test] fn must_read_write_double() { let (mut i_prot, mut o_prot) = test_objects(); #[allow(clippy::approx_constant)] let double = 3.141_592_653_589_793; o_prot.write_double(double).unwrap(); copy_write_buffer_to_read_buffer!(o_prot); let read_double = i_prot.read_double().unwrap(); assert!((read_double - double).abs() < f64::EPSILON); } #[test] fn must_encode_double_as_other_langs() { let (_, mut o_prot) = test_objects(); let expected = [24, 45, 68, 84, 251, 33, 9, 64]; #[allow(clippy::approx_constant)] let double = 3.141_592_653_589_793; o_prot.write_double(double).unwrap(); assert_eq_written_bytes!(o_prot, expected); } fn assert_no_write(mut write_fn: F) where F: FnMut(&mut TCompactOutputProtocol>) -> crate::Result<()>, { let (_, mut o_prot) = test_objects(); 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()); } #[test] fn must_enforce_recursion_depth_limit() { let channel = TBufferChannel::with_capacity(100, 100); // Create a configuration with a small recursion limit let config = TConfiguration::builder() .max_recursion_depth(Some(2)) .build() .unwrap(); let mut protocol = TCompactInputProtocol::with_config(channel, config); // First struct - should succeed assert!(protocol.read_struct_begin().is_ok()); // Second struct - should succeed (at limit) assert!(protocol.read_struct_begin().is_ok()); // Third struct - should fail (exceeds limit) let result = protocol.read_struct_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::DepthLimit); } _ => panic!("Expected protocol error with DepthLimit"), } } #[test] fn must_check_container_size_overflow() { // Configure a small message size limit let config = TConfiguration::builder() .max_message_size(Some(1000)) .max_frame_size(Some(1000)) .build() .unwrap(); let transport = TBufferChannel::with_capacity(100, 0); let mut i_prot = TCompactInputProtocol::with_config(transport, config); // Write a list header that would require more memory than message size limit // List of 100 UUIDs (16 bytes each) = 1600 bytes > 1000 limit i_prot.transport.set_readable_bytes(&[ 0xFD, // element type UUID (0x0D) | count in next bytes (0xF0) 0x64, // varint 100 ]); let result = i_prot.read_list_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::SizeLimit); assert!(e .message .contains("1600 bytes, exceeding message size limit of 1000")); } _ => panic!("Expected protocol error with SizeLimit"), } } #[test] fn must_reject_negative_container_sizes() { let mut channel = TBufferChannel::with_capacity(100, 100); let mut protocol = TCompactInputProtocol::new(channel.clone()); // Write header with negative size when decoded // In compact protocol, lists/sets use a header byte followed by size // We'll use 0x0F for element type and then a varint-encoded negative number channel.set_readable_bytes(&[ 0xF0, // Header: 15 in upper nibble (triggers varint read), List type in lower 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, // Varint encoding of -1 ]); let result = protocol.read_list_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::NegativeSize); } _ => panic!("Expected protocol error with NegativeSize"), } } #[test] fn must_enforce_container_size_limit() { let channel = TBufferChannel::with_capacity(100, 100); let (r_channel, mut w_channel) = channel.split().unwrap(); // Create protocol with explicit container size limit let config = TConfiguration::builder() .max_container_size(Some(1000)) .build() .unwrap(); let mut protocol = TCompactInputProtocol::with_config(r_channel, config); // Write header with large size // Compact protocol: 0xF0 means size >= 15 is encoded as varint // Then we write a varint encoding 10000 (exceeds our limit of 1000) w_channel.set_readable_bytes(&[ 0xF0, // Header: 15 in upper nibble (triggers varint read), element type in lower 0x90, 0x4E, // Varint encoding of 10000 ]); let result = protocol.read_list_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::SizeLimit); assert!(e.message.contains("exceeds maximum allowed size")); } _ => panic!("Expected protocol error with SizeLimit"), } } #[test] fn must_handle_varint_size_overflow() { // Test that compact protocol properly handles varint-encoded sizes that would cause overflow let mut channel = TBufferChannel::with_capacity(100, 100); let mut protocol = TCompactInputProtocol::new(channel.clone()); // Create input that encodes a very large size using varint encoding // 0xFA = list header with size >= 15 (so size follows as varint) // Then multiple 0xFF bytes which in varint encoding create a very large number channel.set_readable_bytes(&[ 0xFA, // List header: size >= 15, element type = 0x0A 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, // Varint encoding of a huge number ]); let result = protocol.read_list_begin(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { // The varint decoder might interpret this as negative, which is also fine assert!( e.kind == ProtocolErrorKind::SizeLimit || e.kind == ProtocolErrorKind::NegativeSize, "Expected SizeLimit or NegativeSize but got {:?}", e.kind ); } _ => panic!("Expected protocol error"), } } #[test] fn must_enforce_string_size_limit() { let channel = TBufferChannel::with_capacity(100, 100); let (r_channel, mut w_channel) = channel.split().unwrap(); // Create protocol with string limit of 100 bytes let config = TConfiguration::builder() .max_string_size(Some(100)) .build() .unwrap(); let mut protocol = TCompactInputProtocol::with_config(r_channel, config); // Write a varint-encoded string size that exceeds the limit w_channel.set_readable_bytes(&[ 0xC8, 0x01, // Varint encoding of 200 ]); let result = protocol.read_string(); assert!(result.is_err()); match result { Err(crate::Error::Protocol(e)) => { assert_eq!(e.kind, ProtocolErrorKind::SizeLimit); assert!(e.message.contains("exceeds maximum allowed size")); } _ => panic!("Expected protocol error with SizeLimit"), } } #[test] fn must_allow_no_limit_configuration() { let channel = TBufferChannel::with_capacity(40, 40); let config = TConfiguration::no_limits(); let mut protocol = TCompactInputProtocol::with_config(channel, config); // Should be able to nest structs deeply without limit for _ in 0..100 { assert!(protocol.read_struct_begin().is_ok()); } for _ in 0..100 { assert!(protocol.read_struct_end().is_ok()); } } #[test] fn must_allow_containers_within_limit() { let channel = TBufferChannel::with_capacity(200, 200); let (r_channel, mut w_channel) = channel.split().unwrap(); // Create protocol with container limit of 100 let config = TConfiguration::builder() .max_container_size(Some(100)) .build() .unwrap(); let mut protocol = TCompactInputProtocol::with_config(r_channel, config); // Write a list with 5 i32 elements (well within limit of 100) // Compact protocol: size < 15 is encoded in header w_channel.set_readable_bytes(&[ 0x55, // Header: size=5, element type=5 (i32) // 5 varint-encoded i32 values 0x0A, // 10 0x14, // 20 0x1E, // 30 0x28, // 40 0x32, // 50 ]); let result = protocol.read_list_begin(); assert!(result.is_ok()); let list_ident = result.unwrap(); assert_eq!(list_ident.size, 5); assert_eq!(list_ident.element_type, TType::I32); } #[test] fn must_allow_strings_within_limit() { let channel = TBufferChannel::with_capacity(100, 100); let (r_channel, mut w_channel) = channel.split().unwrap(); let config = TConfiguration::builder() .max_string_size(Some(1000)) .build() .unwrap(); let mut protocol = TCompactInputProtocol::with_config(r_channel, config); // Write a string "hello" (5 bytes, well within limit) w_channel.set_readable_bytes(&[ 0x05, // Varint-encoded length: 5 b'h', b'e', b'l', b'l', b'o', ]); let result = protocol.read_string(); assert!(result.is_ok()); assert_eq!(result.unwrap(), "hello"); } } thrift-0.23.0/lib/rs/src/protocol/multiplexed.rs0000664000175000017500000001707015165535636022126 0ustar00buildbuild00000000000000// 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. use super::{ TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, }; /// `TOutputProtocol` that prefixes the service name to all outgoing Thrift /// messages. /// /// A `TMultiplexedOutputProtocol` should be used when multiple Thrift services /// send messages over a single I/O channel. By prefixing service identifiers /// to outgoing messages receivers are able to demux them and route them to the /// appropriate service processor. Rust receivers must use a `TMultiplexedProcessor` /// to process incoming messages, while other languages must use their /// corresponding multiplexed processor implementations. /// /// For example, given a service `TestService` and a service call `test_call`, /// this implementation would identify messages as originating from /// `TestService:test_call`. /// /// # Examples /// /// Create and use a `TMultiplexedOutputProtocol`. /// /// ```no_run /// use thrift::protocol::{TMessageIdentifier, TMessageType, TOutputProtocol}; /// use thrift::protocol::{TBinaryOutputProtocol, TMultiplexedOutputProtocol}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("localhost:9090").unwrap(); /// /// let protocol = TBinaryOutputProtocol::new(channel, true); /// let mut protocol = TMultiplexedOutputProtocol::new("service_name", protocol); /// /// let ident = TMessageIdentifier::new("svc_call", TMessageType::Call, 1); /// protocol.write_message_begin(&ident).unwrap(); /// ``` #[derive(Debug)] pub struct TMultiplexedOutputProtocol

where P: TOutputProtocol, { service_name: String, inner: P, } impl

TMultiplexedOutputProtocol

where P: TOutputProtocol, { /// Create a `TMultiplexedOutputProtocol` that identifies outgoing messages /// as originating from a service named `service_name` and sends them over /// the `wrapped` `TOutputProtocol`. Outgoing messages are encoded and sent /// by `wrapped`, not by this instance. pub fn new(service_name: &str, wrapped: P) -> TMultiplexedOutputProtocol

{ TMultiplexedOutputProtocol { service_name: service_name.to_owned(), inner: wrapped, } } } // FIXME: avoid passthrough methods impl

TOutputProtocol for TMultiplexedOutputProtocol

where P: TOutputProtocol, { fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> { match identifier.message_type { // FIXME: is there a better way to override identifier here? TMessageType::Call | TMessageType::OneWay => { let identifier = TMessageIdentifier { name: format!("{}:{}", self.service_name, identifier.name), ..*identifier }; self.inner.write_message_begin(&identifier) } _ => self.inner.write_message_begin(identifier), } } fn write_message_end(&mut self) -> crate::Result<()> { self.inner.write_message_end() } fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()> { self.inner.write_struct_begin(identifier) } fn write_struct_end(&mut self) -> crate::Result<()> { self.inner.write_struct_end() } fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> { self.inner.write_field_begin(identifier) } fn write_field_end(&mut self) -> crate::Result<()> { self.inner.write_field_end() } fn write_field_stop(&mut self) -> crate::Result<()> { self.inner.write_field_stop() } fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> { self.inner.write_bytes(b) } fn write_bool(&mut self, b: bool) -> crate::Result<()> { self.inner.write_bool(b) } fn write_i8(&mut self, i: i8) -> crate::Result<()> { self.inner.write_i8(i) } fn write_i16(&mut self, i: i16) -> crate::Result<()> { self.inner.write_i16(i) } fn write_i32(&mut self, i: i32) -> crate::Result<()> { self.inner.write_i32(i) } fn write_i64(&mut self, i: i64) -> crate::Result<()> { self.inner.write_i64(i) } fn write_double(&mut self, d: f64) -> crate::Result<()> { self.inner.write_double(d) } fn write_string(&mut self, s: &str) -> crate::Result<()> { self.inner.write_string(s) } fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> { self.inner.write_uuid(uuid) } fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> { self.inner.write_list_begin(identifier) } fn write_list_end(&mut self) -> crate::Result<()> { self.inner.write_list_end() } fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> { self.inner.write_set_begin(identifier) } fn write_set_end(&mut self) -> crate::Result<()> { self.inner.write_set_end() } fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> { self.inner.write_map_begin(identifier) } fn write_map_end(&mut self) -> crate::Result<()> { self.inner.write_map_end() } fn flush(&mut self) -> crate::Result<()> { self.inner.flush() } // utility // fn write_byte(&mut self, b: u8) -> crate::Result<()> { self.inner.write_byte(b) } } #[cfg(test)] mod tests { use crate::protocol::{ TBinaryOutputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol, }; use crate::transport::{TBufferChannel, TIoChannel, WriteHalf}; use super::*; #[test] fn must_write_message_begin_with_prefixed_service_name() { let mut o_prot = test_objects(); let ident = TMessageIdentifier::new("bar", TMessageType::Call, 2); assert_success!(o_prot.write_message_begin(&ident)); #[rustfmt::skip] let expected: [u8; 19] = [ 0x80, 0x01, /* protocol identifier */ 0x00, 0x01, /* message type */ 0x00, 0x00, 0x00, 0x07, 0x66, 0x6F, 0x6F, /* "foo" */ 0x3A, /* ":" */ 0x62, 0x61, 0x72, /* "bar" */ 0x00, 0x00, 0x00, 0x02 /* sequence number */, ]; assert_eq!(o_prot.inner.transport.write_bytes(), expected); } fn test_objects() -> TMultiplexedOutputProtocol>> { let c = TBufferChannel::with_capacity(40, 40); let (_, w_chan) = c.split().unwrap(); let prot = TBinaryOutputProtocol::new(w_chan, true); TMultiplexedOutputProtocol::new("foo", prot) } } thrift-0.23.0/lib/rs/src/protocol/mod.rs0000664000175000017500000011151315167543515020343 0ustar00buildbuild00000000000000// 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. //! Types used to send and receive primitives between a Thrift client and server. //! //! # Examples //! //! Create and use a `TInputProtocol`. //! //! ```no_run //! use thrift::protocol::{TBinaryInputProtocol, TInputProtocol}; //! use thrift::transport::TTcpChannel; //! //! // create the I/O channel //! let mut channel = TTcpChannel::new(); //! channel.open("127.0.0.1:9090").unwrap(); //! //! // create the protocol to decode bytes into types //! let mut protocol = TBinaryInputProtocol::new(channel, true); //! //! // read types from the wire //! let field_identifier = protocol.read_field_begin().unwrap(); //! let field_contents = protocol.read_string().unwrap(); //! let field_end = protocol.read_field_end().unwrap(); //! ``` //! //! Create and use a `TOutputProtocol`. //! //! ```no_run //! use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType}; //! use thrift::transport::TTcpChannel; //! //! // create the I/O channel //! let mut channel = TTcpChannel::new(); //! channel.open("127.0.0.1:9090").unwrap(); //! //! // create the protocol to encode types into bytes //! let mut protocol = TBinaryOutputProtocol::new(channel, true); //! //! // write types //! protocol.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap(); //! protocol.write_string("foo").unwrap(); //! protocol.write_field_end().unwrap(); //! ``` use std::convert::{From, TryFrom}; use std::fmt; use std::fmt::{Display, Formatter}; use crate::transport::{TReadTransport, TWriteTransport}; use crate::{ProtocolError, ProtocolErrorKind, TConfiguration}; #[cfg(test)] macro_rules! assert_eq_written_bytes { ($o_prot:ident, $expected_bytes:ident) => {{ assert_eq!($o_prot.transport.write_bytes(), &$expected_bytes); }}; } // FIXME: should take both read and write #[cfg(test)] macro_rules! copy_write_buffer_to_read_buffer { ($o_prot:ident) => {{ $o_prot.transport.copy_write_buffer_to_read_buffer(); }}; } #[cfg(test)] macro_rules! set_readable_bytes { ($i_prot:ident, $bytes:expr) => { $i_prot.transport.set_readable_bytes($bytes); }; } mod binary; mod compact; mod multiplexed; mod stored; pub use self::binary::{ TBinaryInputProtocol, TBinaryInputProtocolFactory, TBinaryOutputProtocol, TBinaryOutputProtocolFactory, }; pub use self::compact::{ TCompactInputProtocol, TCompactInputProtocolFactory, TCompactOutputProtocol, TCompactOutputProtocolFactory, }; pub use self::multiplexed::TMultiplexedOutputProtocol; pub use self::stored::TStoredInputProtocol; /// Reads and writes the struct to Thrift protocols. /// /// It is implemented in generated code for Thrift `struct`, `union`, and `enum` types. pub trait TSerializable: Sized { fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> crate::Result; fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> crate::Result<()>; } // Default maximum depth to which `TInputProtocol::skip` will skip a Thrift // field. A default is necessary because Thrift structs or collections may // contain nested structs and collections, which could result in indefinite // recursion. const MAXIMUM_SKIP_DEPTH: i8 = 64; /// Converts a stream of bytes into Thrift identifiers, primitives, /// containers, or structs. /// /// This trait does not deal with higher-level Thrift concepts like structs or /// exceptions - only with primitives and message or container boundaries. Once /// bytes are read they are deserialized and an identifier (for example /// `TMessageIdentifier`) or a primitive is returned. /// /// All methods return a `thrift::Result`. If an `Err` is returned the protocol /// instance and its underlying transport should be terminated. /// /// # Examples /// /// Create and use a `TInputProtocol` /// /// ```no_run /// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("127.0.0.1:9090").unwrap(); /// /// let mut protocol = TBinaryInputProtocol::new(channel, true); /// /// let field_identifier = protocol.read_field_begin().unwrap(); /// let field_contents = protocol.read_string().unwrap(); /// let field_end = protocol.read_field_end().unwrap(); /// ``` pub trait TInputProtocol { /// Read the beginning of a Thrift message. fn read_message_begin(&mut self) -> crate::Result; /// Read the end of a Thrift message. fn read_message_end(&mut self) -> crate::Result<()>; /// Read the beginning of a Thrift struct. fn read_struct_begin(&mut self) -> crate::Result>; /// Read the end of a Thrift struct. fn read_struct_end(&mut self) -> crate::Result<()>; /// Read the beginning of a Thrift struct field. fn read_field_begin(&mut self) -> crate::Result; /// Read the end of a Thrift struct field. fn read_field_end(&mut self) -> crate::Result<()>; /// Read a bool. fn read_bool(&mut self) -> crate::Result; /// Read a fixed-length byte array. fn read_bytes(&mut self) -> crate::Result>; /// Read a word. fn read_i8(&mut self) -> crate::Result; /// Read a 16-bit signed integer. fn read_i16(&mut self) -> crate::Result; /// Read a 32-bit signed integer. fn read_i32(&mut self) -> crate::Result; /// Read a 64-bit signed integer. fn read_i64(&mut self) -> crate::Result; /// Read a 64-bit float. fn read_double(&mut self) -> crate::Result; /// Read a UUID. fn read_uuid(&mut self) -> crate::Result; /// Read a fixed-length string (not null terminated). fn read_string(&mut self) -> crate::Result; /// Read the beginning of a list. fn read_list_begin(&mut self) -> crate::Result; /// Read the end of a list. fn read_list_end(&mut self) -> crate::Result<()>; /// Read the beginning of a set. fn read_set_begin(&mut self) -> crate::Result; /// Read the end of a set. fn read_set_end(&mut self) -> crate::Result<()>; /// Read the beginning of a map. fn read_map_begin(&mut self) -> crate::Result; /// Read the end of a map. fn read_map_end(&mut self) -> crate::Result<()>; /// Skip a field with type `field_type` recursively until the default /// maximum skip depth is reached. fn skip(&mut self, field_type: TType) -> crate::Result<()> { self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH) } /// Skip a field with type `field_type` recursively up to `depth` levels. fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> { if depth == 0 { return Err(crate::Error::Protocol(ProtocolError { kind: ProtocolErrorKind::DepthLimit, message: format!("cannot parse past {:?}", field_type), })); } match field_type { TType::Bool => self.read_bool().map(|_| ()), TType::I08 => self.read_i8().map(|_| ()), TType::I16 => self.read_i16().map(|_| ()), TType::I32 => self.read_i32().map(|_| ()), TType::I64 => self.read_i64().map(|_| ()), TType::Double => self.read_double().map(|_| ()), TType::String => self.read_bytes().map(|_| ()), TType::Uuid => self.read_uuid().map(|_| ()), TType::Struct => { self.read_struct_begin()?; loop { let field_ident = self.read_field_begin()?; if field_ident.field_type == TType::Stop { break; } self.skip_till_depth(field_ident.field_type, depth - 1)?; } self.read_struct_end() } TType::List => { let list_ident = self.read_list_begin()?; for _ in 0..list_ident.size { self.skip_till_depth(list_ident.element_type, depth - 1)?; } self.read_list_end() } TType::Set => { let set_ident = self.read_set_begin()?; for _ in 0..set_ident.size { self.skip_till_depth(set_ident.element_type, depth - 1)?; } self.read_set_end() } TType::Map => { let map_ident = self.read_map_begin()?; for _ in 0..map_ident.size { let key_type = map_ident .key_type .expect("non-zero sized map should contain key type"); let val_type = map_ident .value_type .expect("non-zero sized map should contain value type"); self.skip_till_depth(key_type, depth - 1)?; self.skip_till_depth(val_type, depth - 1)?; } self.read_map_end() } u => Err(crate::Error::Protocol(ProtocolError { kind: ProtocolErrorKind::Unknown, message: format!("cannot skip field type {:?}", &u), })), } } // utility (DO NOT USE IN GENERATED CODE!!!!) // /// Read an unsigned byte. /// /// This method should **never** be used in generated code. fn read_byte(&mut self) -> crate::Result; /// Get the minimum number of bytes a type will consume on the wire. /// This picks the minimum possible across all protocols (so currently matches the compact protocol). /// /// This is used for pre-allocation size checks. /// The actual data may be larger (e.g., for strings, lists, etc.). fn min_serialized_size(&self, field_type: TType) -> usize { self::compact::compact_protocol_min_serialized_size(field_type) } } /// Converts Thrift identifiers, primitives, containers or structs into a /// stream of bytes. /// /// This trait does not deal with higher-level Thrift concepts like structs or /// exceptions - only with primitives and message or container boundaries. /// Write methods take an identifier (for example, `TMessageIdentifier`) or a /// primitive. Any or all of the fields in an identifier may be omitted when /// writing to the transport. Write methods may even be noops. All of this is /// transparent to the caller; as long as a matching `TInputProtocol` /// implementation is used, received messages will be decoded correctly. /// /// All methods return a `thrift::Result`. If an `Err` is returned the protocol /// instance and its underlying transport should be terminated. /// /// # Examples /// /// Create and use a `TOutputProtocol` /// /// ```no_run /// use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("127.0.0.1:9090").unwrap(); /// /// let mut protocol = TBinaryOutputProtocol::new(channel, true); /// /// protocol.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap(); /// protocol.write_string("foo").unwrap(); /// protocol.write_field_end().unwrap(); /// ``` pub trait TOutputProtocol { /// Write the beginning of a Thrift message. fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()>; /// Write the end of a Thrift message. fn write_message_end(&mut self) -> crate::Result<()>; /// Write the beginning of a Thrift struct. fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()>; /// Write the end of a Thrift struct. fn write_struct_end(&mut self) -> crate::Result<()>; /// Write the beginning of a Thrift field. fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()>; /// Write the end of a Thrift field. fn write_field_end(&mut self) -> crate::Result<()>; /// Write a STOP field indicating that all the fields in a struct have been /// written. fn write_field_stop(&mut self) -> crate::Result<()>; /// Write a bool. fn write_bool(&mut self, b: bool) -> crate::Result<()>; /// Write a fixed-length byte array. fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()>; /// Write an 8-bit signed integer. fn write_i8(&mut self, i: i8) -> crate::Result<()>; /// Write a 16-bit signed integer. fn write_i16(&mut self, i: i16) -> crate::Result<()>; /// Write a 32-bit signed integer. fn write_i32(&mut self, i: i32) -> crate::Result<()>; /// Write a 64-bit signed integer. fn write_i64(&mut self, i: i64) -> crate::Result<()>; /// Write a 64-bit float. fn write_double(&mut self, d: f64) -> crate::Result<()>; /// Write a UUID fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()>; /// Write a fixed-length string. fn write_string(&mut self, s: &str) -> crate::Result<()>; /// Write the beginning of a list. fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()>; /// Write the end of a list. fn write_list_end(&mut self) -> crate::Result<()>; /// Write the beginning of a set. fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()>; /// Write the end of a set. fn write_set_end(&mut self) -> crate::Result<()>; /// Write the beginning of a map. fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()>; /// Write the end of a map. fn write_map_end(&mut self) -> crate::Result<()>; /// Flush buffered bytes to the underlying transport. fn flush(&mut self) -> crate::Result<()>; // utility (DO NOT USE IN GENERATED CODE!!!!) // /// Write an unsigned byte. /// /// This method should **never** be used in generated code. fn write_byte(&mut self, b: u8) -> crate::Result<()>; // FIXME: REMOVE } impl

TInputProtocol for Box

where P: TInputProtocol + ?Sized, { fn read_message_begin(&mut self) -> crate::Result { (**self).read_message_begin() } fn read_message_end(&mut self) -> crate::Result<()> { (**self).read_message_end() } fn read_struct_begin(&mut self) -> crate::Result> { (**self).read_struct_begin() } fn read_struct_end(&mut self) -> crate::Result<()> { (**self).read_struct_end() } fn read_field_begin(&mut self) -> crate::Result { (**self).read_field_begin() } fn read_field_end(&mut self) -> crate::Result<()> { (**self).read_field_end() } fn read_bool(&mut self) -> crate::Result { (**self).read_bool() } fn read_bytes(&mut self) -> crate::Result> { (**self).read_bytes() } fn read_i8(&mut self) -> crate::Result { (**self).read_i8() } fn read_i16(&mut self) -> crate::Result { (**self).read_i16() } fn read_i32(&mut self) -> crate::Result { (**self).read_i32() } fn read_i64(&mut self) -> crate::Result { (**self).read_i64() } fn read_double(&mut self) -> crate::Result { (**self).read_double() } fn read_uuid(&mut self) -> crate::Result { (**self).read_uuid() } fn read_string(&mut self) -> crate::Result { (**self).read_string() } fn read_list_begin(&mut self) -> crate::Result { (**self).read_list_begin() } fn read_list_end(&mut self) -> crate::Result<()> { (**self).read_list_end() } fn read_set_begin(&mut self) -> crate::Result { (**self).read_set_begin() } fn read_set_end(&mut self) -> crate::Result<()> { (**self).read_set_end() } fn read_map_begin(&mut self) -> crate::Result { (**self).read_map_begin() } fn read_map_end(&mut self) -> crate::Result<()> { (**self).read_map_end() } fn read_byte(&mut self) -> crate::Result { (**self).read_byte() } fn min_serialized_size(&self, field_type: TType) -> usize { (**self).min_serialized_size(field_type) } } impl

TOutputProtocol for Box

where P: TOutputProtocol + ?Sized, { fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> { (**self).write_message_begin(identifier) } fn write_message_end(&mut self) -> crate::Result<()> { (**self).write_message_end() } fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()> { (**self).write_struct_begin(identifier) } fn write_struct_end(&mut self) -> crate::Result<()> { (**self).write_struct_end() } fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> { (**self).write_field_begin(identifier) } fn write_field_end(&mut self) -> crate::Result<()> { (**self).write_field_end() } fn write_field_stop(&mut self) -> crate::Result<()> { (**self).write_field_stop() } fn write_bool(&mut self, b: bool) -> crate::Result<()> { (**self).write_bool(b) } fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> { (**self).write_bytes(b) } fn write_i8(&mut self, i: i8) -> crate::Result<()> { (**self).write_i8(i) } fn write_i16(&mut self, i: i16) -> crate::Result<()> { (**self).write_i16(i) } fn write_i32(&mut self, i: i32) -> crate::Result<()> { (**self).write_i32(i) } fn write_i64(&mut self, i: i64) -> crate::Result<()> { (**self).write_i64(i) } fn write_double(&mut self, d: f64) -> crate::Result<()> { (**self).write_double(d) } fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> { (**self).write_uuid(uuid) } fn write_string(&mut self, s: &str) -> crate::Result<()> { (**self).write_string(s) } fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> { (**self).write_list_begin(identifier) } fn write_list_end(&mut self) -> crate::Result<()> { (**self).write_list_end() } fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> { (**self).write_set_begin(identifier) } fn write_set_end(&mut self) -> crate::Result<()> { (**self).write_set_end() } fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> { (**self).write_map_begin(identifier) } fn write_map_end(&mut self) -> crate::Result<()> { (**self).write_map_end() } fn flush(&mut self) -> crate::Result<()> { (**self).flush() } fn write_byte(&mut self, b: u8) -> crate::Result<()> { (**self).write_byte(b) } } /// Helper type used by servers to create `TInputProtocol` instances for /// accepted client connections. /// /// # Examples /// /// Create a `TInputProtocolFactory` and use it to create a `TInputProtocol`. /// /// ```no_run /// use thrift::protocol::{TBinaryInputProtocolFactory, TInputProtocolFactory}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("127.0.0.1:9090").unwrap(); /// /// let factory = TBinaryInputProtocolFactory::new(); /// let protocol = factory.create(Box::new(channel)); /// ``` pub trait TInputProtocolFactory { /// Create a `TInputProtocol` that reads bytes from `transport`. fn create(&self, transport: Box) -> Box; } impl TInputProtocolFactory for Box where T: TInputProtocolFactory + ?Sized, { fn create(&self, transport: Box) -> Box { (**self).create(transport) } } /// Helper type used by servers to create `TOutputProtocol` instances for /// accepted client connections. /// /// # Examples /// /// Create a `TOutputProtocolFactory` and use it to create a `TOutputProtocol`. /// /// ```no_run /// use thrift::protocol::{TBinaryOutputProtocolFactory, TOutputProtocolFactory}; /// use thrift::transport::TTcpChannel; /// /// let mut channel = TTcpChannel::new(); /// channel.open("127.0.0.1:9090").unwrap(); /// /// let factory = TBinaryOutputProtocolFactory::new(); /// let protocol = factory.create(Box::new(channel)); /// ``` pub trait TOutputProtocolFactory { /// Create a `TOutputProtocol` that writes bytes to `transport`. fn create(&self, transport: Box) -> Box; } impl TOutputProtocolFactory for Box where T: TOutputProtocolFactory + ?Sized, { fn create( &self, transport: Box, ) -> Box { (**self).create(transport) } } /// Thrift message identifier. #[derive(Clone, Debug, Eq, PartialEq)] pub struct TMessageIdentifier { /// Service call the message is associated with. pub name: String, /// Message type. pub message_type: TMessageType, /// Ordered sequence number identifying the message. pub sequence_number: i32, } impl TMessageIdentifier { /// Create a `TMessageIdentifier` for a Thrift service-call named `name` /// with message type `message_type` and sequence number `sequence_number`. pub fn new>( name: S, message_type: TMessageType, sequence_number: i32, ) -> TMessageIdentifier { TMessageIdentifier { name: name.into(), message_type, sequence_number, } } } /// Thrift struct identifier. #[derive(Clone, Debug, Eq, PartialEq)] pub struct TStructIdentifier { /// Name of the encoded Thrift struct. pub name: String, } impl TStructIdentifier { /// Create a `TStructIdentifier` for a struct named `name`. pub fn new>(name: S) -> TStructIdentifier { TStructIdentifier { name: name.into() } } } /// Thrift field identifier. #[derive(Clone, Debug, Eq, PartialEq)] pub struct TFieldIdentifier { /// Name of the Thrift field. /// /// `None` if it's not sent over the wire. pub name: Option, /// Field type. /// /// This may be a primitive, container, or a struct. pub field_type: TType, /// Thrift field id. /// /// `None` only if `field_type` is `TType::Stop`. pub id: Option, } impl TFieldIdentifier { /// Create a `TFieldIdentifier` for a field named `name` with type /// `field_type` and field id `id`. /// /// `id` should be `None` if `field_type` is `TType::Stop`. pub fn new(name: N, field_type: TType, id: I) -> TFieldIdentifier where N: Into>, S: Into, I: Into>, { TFieldIdentifier { name: name.into().map(|n| n.into()), field_type, id: id.into(), } } } /// Thrift list identifier. #[derive(Clone, Debug, Eq, PartialEq)] pub struct TListIdentifier { /// Type of the elements in the list. pub element_type: TType, /// Number of elements in the list. pub size: i32, } impl TListIdentifier { /// Create a `TListIdentifier` for a list with `size` elements of type /// `element_type`. pub fn new(element_type: TType, size: i32) -> TListIdentifier { TListIdentifier { element_type, size } } } /// Thrift set identifier. #[derive(Clone, Debug, Eq, PartialEq)] pub struct TSetIdentifier { /// Type of the elements in the set. pub element_type: TType, /// Number of elements in the set. pub size: i32, } impl TSetIdentifier { /// Create a `TSetIdentifier` for a set with `size` elements of type /// `element_type`. pub fn new(element_type: TType, size: i32) -> TSetIdentifier { TSetIdentifier { element_type, size } } } /// Thrift map identifier. #[derive(Clone, Debug, Eq, PartialEq)] pub struct TMapIdentifier { /// Map key type. pub key_type: Option, /// Map value type. pub value_type: Option, /// Number of entries in the map. pub size: i32, } impl TMapIdentifier { /// Create a `TMapIdentifier` for a map with `size` entries of type /// `key_type -> value_type`. pub fn new(key_type: K, value_type: V, size: i32) -> TMapIdentifier where K: Into>, V: Into>, { TMapIdentifier { key_type: key_type.into(), value_type: value_type.into(), size, } } } /// Thrift message types. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum TMessageType { /// Service-call request. Call, /// Service-call response. Reply, /// Unexpected error in the remote service. Exception, /// One-way service-call request (no response is expected). OneWay, } impl Display for TMessageType { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match *self { TMessageType::Call => write!(f, "Call"), TMessageType::Reply => write!(f, "Reply"), TMessageType::Exception => write!(f, "Exception"), TMessageType::OneWay => write!(f, "OneWay"), } } } impl From for u8 { fn from(message_type: TMessageType) -> Self { match message_type { TMessageType::Call => 0x01, TMessageType::Reply => 0x02, TMessageType::Exception => 0x03, TMessageType::OneWay => 0x04, } } } impl TryFrom for TMessageType { type Error = crate::Error; fn try_from(b: u8) -> Result { match b { 0x01 => Ok(TMessageType::Call), 0x02 => Ok(TMessageType::Reply), 0x03 => Ok(TMessageType::Exception), 0x04 => Ok(TMessageType::OneWay), unkn => Err(crate::Error::Protocol(ProtocolError { kind: ProtocolErrorKind::InvalidData, message: format!("cannot convert {} to TMessageType", unkn), })), } } } /// Thrift struct-field types. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum TType { /// Indicates that there are no more serialized fields in this Thrift struct. Stop, /// Void (`()`) field. Void, /// Boolean. Bool, /// Signed 8-bit int. I08, /// Double-precision number. Double, /// Signed 16-bit int. I16, /// Signed 32-bit int. I32, /// Signed 64-bit int. I64, /// UTF-8 string. String, /// UTF-7 string. *Unsupported*. Utf7, /// Thrift struct. Struct, /// Map. Map, /// Set. Set, /// List. List, /// Uuid. Uuid, } impl Display for TType { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match *self { TType::Stop => write!(f, "STOP"), TType::Void => write!(f, "void"), TType::Bool => write!(f, "bool"), TType::I08 => write!(f, "i08"), TType::Double => write!(f, "double"), TType::I16 => write!(f, "i16"), TType::I32 => write!(f, "i32"), TType::I64 => write!(f, "i64"), TType::String => write!(f, "string"), TType::Utf7 => write!(f, "UTF7"), TType::Struct => write!(f, "struct"), TType::Map => write!(f, "map"), TType::Set => write!(f, "set"), TType::List => write!(f, "list"), TType::Uuid => write!(f, "UUID"), } } } /// Compare the expected message sequence number `expected` with the received /// message sequence number `actual`. /// /// Return `()` if `actual == expected`, `Err` otherwise. pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> crate::Result<()> { if expected == actual { Ok(()) } else { Err(crate::Error::Application(crate::ApplicationError { kind: crate::ApplicationErrorKind::BadSequenceId, message: format!("expected {} got {}", expected, actual), })) } } /// Compare the expected service-call name `expected` with the received /// service-call name `actual`. /// /// Return `()` if `actual == expected`, `Err` otherwise. pub fn verify_expected_service_call(expected: &str, actual: &str) -> crate::Result<()> { if expected == actual { Ok(()) } else { Err(crate::Error::Application(crate::ApplicationError { kind: crate::ApplicationErrorKind::WrongMethodName, message: format!("expected {} got {}", expected, actual), })) } } /// Compare the expected message type `expected` with the received message type /// `actual`. /// /// Return `()` if `actual == expected`, `Err` otherwise. pub fn verify_expected_message_type( expected: TMessageType, actual: TMessageType, ) -> crate::Result<()> { if expected == actual { Ok(()) } else { Err(crate::Error::Application(crate::ApplicationError { kind: crate::ApplicationErrorKind::InvalidMessageType, message: format!("expected {} got {}", expected, actual), })) } } /// Check if a required Thrift struct field exists. /// /// Return `()` if it does, `Err` otherwise. pub fn verify_required_field_exists(field_name: &str, field: &Option) -> crate::Result<()> { match *field { Some(_) => Ok(()), None => Err(crate::Error::Protocol(crate::ProtocolError { kind: crate::ProtocolErrorKind::Unknown, message: format!("missing required field {}", field_name), })), } } /// Common container size validation used by all protocols. /// /// Checks that: /// - Container size is not negative /// - Container size doesn't exceed configured maximum /// - Container size * element size doesn't overflow /// - Container memory requirements don't exceed message size limit pub(crate) fn check_container_size( config: &TConfiguration, container_size: i32, element_size: usize, ) -> crate::Result<()> { // Check for negative size if container_size < 0 { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::NegativeSize, format!("Negative container size: {}", container_size), ))); } let size_as_usize = container_size as usize; // Check against configured max container size if let Some(max_size) = config.max_container_size() { if size_as_usize > max_size { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::SizeLimit, format!( "Container size {} exceeds maximum allowed size of {}", container_size, max_size ), ))); } } // Check for potential overflow if let Some(min_bytes_needed) = size_as_usize.checked_mul(element_size) { // TODO: When Rust trait specialization stabilizes, we can add more precise checks // for transports that track exact remaining bytes. For now, we use the message // size limit as a best-effort check. if let Some(max_message_size) = config.max_message_size() { if min_bytes_needed > max_message_size { return Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::SizeLimit, format!( "Container would require {} bytes, exceeding message size limit of {}", min_bytes_needed, max_message_size ), ))); } } Ok(()) } else { Err(crate::Error::Protocol(ProtocolError::new( ProtocolErrorKind::SizeLimit, format!( "Container size {} with element size {} bytes would result in overflow", container_size, element_size ), ))) } } /// Extract the field id from a Thrift field identifier. /// /// `field_ident` must *not* have `TFieldIdentifier.field_type` of type `TType::Stop`. /// /// Return `TFieldIdentifier.id` if an id exists, `Err` otherwise. pub fn field_id(field_ident: &TFieldIdentifier) -> crate::Result { field_ident.id.ok_or_else(|| { crate::Error::Protocol(crate::ProtocolError { kind: crate::ProtocolErrorKind::Unknown, message: format!("missing field id in {:?}", field_ident), }) }) } #[cfg(test)] mod tests { use std::io::Cursor; use super::*; use crate::transport::{TReadTransport, TWriteTransport}; #[test] fn must_create_usable_input_protocol_from_concrete_input_protocol() { let r: Box = Box::new(Cursor::new([0, 1, 2])); let mut t = TCompactInputProtocol::new(r); takes_input_protocol(&mut t) } #[test] fn must_create_usable_input_protocol_from_boxed_input() { let r: Box = Box::new(Cursor::new([0, 1, 2])); let mut t: Box = Box::new(TCompactInputProtocol::new(r)); takes_input_protocol(&mut t) } #[test] fn must_create_usable_output_protocol_from_concrete_output_protocol() { let w: Box = Box::new(vec![0u8; 10]); let mut t = TCompactOutputProtocol::new(w); takes_output_protocol(&mut t) } #[test] fn must_create_usable_output_protocol_from_boxed_output() { let w: Box = Box::new(vec![0u8; 10]); let mut t: Box = Box::new(TCompactOutputProtocol::new(w)); takes_output_protocol(&mut t) } fn takes_input_protocol(t: &mut R) where R: TInputProtocol, { t.read_byte().unwrap(); } fn takes_output_protocol(t: &mut W) where W: TOutputProtocol, { t.flush().unwrap(); } // Test unknown binary fields are skipped without error (THRIFT-5928) fn build_struct_with_unknown_binary_field(payload: &[u8]) -> Vec { let mut buf = Vec::new(); buf.push(0x0A); // field 1: TType::I64 buf.extend_from_slice(&1_i16.to_be_bytes()); buf.extend_from_slice(&42_i64.to_be_bytes()); buf.push(0x0B); // field 99: TType::String (same wire type for binary) buf.extend_from_slice(&99_i16.to_be_bytes()); buf.extend_from_slice(&(payload.len() as i32).to_be_bytes()); buf.extend_from_slice(payload); buf.push(0x00); // stop buf } fn read_struct_skipping_unknown(data: &[u8]) -> crate::Result { let cursor = Cursor::new(data.to_vec()); let mut proto = TBinaryInputProtocol::new(cursor, true); proto.read_struct_begin()?; let mut known_value: Option = None; loop { let field = proto.read_field_begin()?; if field.field_type == TType::Stop { break; } match field.id { Some(1) if field.field_type == TType::I64 => { known_value = Some(proto.read_i64()?); } _ => { proto.skip(field.field_type)?; } } proto.read_field_end()?; } proto.read_struct_end()?; known_value.ok_or_else(|| { crate::Error::Protocol(crate::ProtocolError { kind: crate::ProtocolErrorKind::InvalidData, message: "missing known field".to_string(), }) }) } #[test] fn must_skip_binary_field_with_non_utf8_bytes() { let non_utf8: Vec = vec![ 0x04, 0xFF, 0xFE, 0x80, 0x90, 0xAB, 0xCD, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE, ]; assert!(String::from_utf8(non_utf8.clone()).is_err()); let data = build_struct_with_unknown_binary_field(&non_utf8); let result = read_struct_skipping_unknown(&data); assert!(result.is_ok(), "skip() failed on non-UTF-8 binary: {:?}", result.err()); assert_eq!(result.unwrap(), 42); } #[test] fn must_skip_valid_utf8_string_field() { let data = build_struct_with_unknown_binary_field(b"hello world"); assert_eq!(read_struct_skipping_unknown(&data).unwrap(), 42); } #[test] fn must_skip_empty_binary_field() { let data = build_struct_with_unknown_binary_field(&[]); assert_eq!(read_struct_skipping_unknown(&data).unwrap(), 42); } } thrift-0.23.0/lib/rs/src/configuration.rs0000664000175000017500000001302115165535636020570 0ustar00buildbuild00000000000000// 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. /// Configuration for Thrift protocols. #[derive(Debug, Clone)] pub struct TConfiguration { max_message_size: Option, max_frame_size: Option, max_recursion_depth: Option, max_container_size: Option, max_string_size: Option, } impl TConfiguration { // this value is used consistently across all Thrift libraries pub const DEFAULT_MAX_MESSAGE_SIZE: usize = 100 * 1024 * 1024; // this value is used consistently across all Thrift libraries pub const DEFAULT_MAX_FRAME_SIZE: usize = 16_384_000; pub const DEFAULT_RECURSION_LIMIT: usize = 64; pub const DEFAULT_CONTAINER_LIMIT: Option = None; pub const DEFAULT_STRING_LIMIT: usize = 100 * 1024 * 1024; pub fn no_limits() -> Self { Self { max_message_size: None, max_frame_size: None, max_recursion_depth: None, max_container_size: None, max_string_size: None, } } pub fn max_message_size(&self) -> Option { self.max_message_size } pub fn max_frame_size(&self) -> Option { self.max_frame_size } pub fn max_recursion_depth(&self) -> Option { self.max_recursion_depth } pub fn max_container_size(&self) -> Option { self.max_container_size } pub fn max_string_size(&self) -> Option { self.max_string_size } pub fn builder() -> TConfigurationBuilder { TConfigurationBuilder::default() } } impl Default for TConfiguration { fn default() -> Self { Self { max_message_size: Some(Self::DEFAULT_MAX_MESSAGE_SIZE), max_frame_size: Some(Self::DEFAULT_MAX_FRAME_SIZE), max_recursion_depth: Some(Self::DEFAULT_RECURSION_LIMIT), max_container_size: Self::DEFAULT_CONTAINER_LIMIT, max_string_size: Some(Self::DEFAULT_STRING_LIMIT), } } } #[derive(Debug, Default)] pub struct TConfigurationBuilder { config: TConfiguration, } impl TConfigurationBuilder { pub fn max_message_size(mut self, limit: Option) -> Self { self.config.max_message_size = limit; self } pub fn max_frame_size(mut self, limit: Option) -> Self { self.config.max_frame_size = limit; self } pub fn max_recursion_depth(mut self, limit: Option) -> Self { self.config.max_recursion_depth = limit; self } pub fn max_container_size(mut self, limit: Option) -> Self { self.config.max_container_size = limit; self } pub fn max_string_size(mut self, limit: Option) -> Self { self.config.max_string_size = limit; self } pub fn build(self) -> crate::Result { if let (Some(frame_size), Some(message_size)) = (self.config.max_frame_size, self.config.max_message_size) { if frame_size > message_size { // FIXME: This should probably be a different error type. return Err(crate::Error::Application(crate::ApplicationError::new( crate::ApplicationErrorKind::Unknown, format!( "Invalid configuration: max_frame_size ({}) cannot exceed max_message_size ({})", frame_size, message_size ), ))); } } Ok(self.config) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_custom_configuration_builder() { let config = TConfiguration::builder() .max_message_size(Some(1024)) .max_frame_size(Some(512)) .max_recursion_depth(Some(10)) .max_container_size(Some(100)) .max_string_size(Some(256)) .build() .unwrap(); assert_eq!(config.max_message_size(), Some(1024)); assert_eq!(config.max_frame_size(), Some(512)); assert_eq!(config.max_recursion_depth(), Some(10)); assert_eq!(config.max_container_size(), Some(100)); assert_eq!(config.max_string_size(), Some(256)); } #[test] fn test_invalid_configuration() { // Test that builder catches invalid configurations let result = TConfiguration::builder() .max_frame_size(Some(1000)) .max_message_size(Some(500)) // frame size > message size is invalid .build(); assert!(result.is_err()); match result { Err(crate::Error::Application(e)) => { assert!(e.message.contains("max_frame_size")); assert!(e.message.contains("cannot exceed max_message_size")); } _ => panic!("Expected Application error"), } } } thrift-0.23.0/lib/rs/release.sh0000775000175000017500000000137515165535636016554 0ustar00buildbuild00000000000000#!/bin/bash set -o errexit set -o pipefail set -o nounset if ! [[ $# -eq 1 && $1 =~ ^[0-9](\.[0-9][0-9]*){2}$ ]]; then (>&2 echo "Usage: ./publish-crate.sh [THRIFT_RELEASE_VERSION] ") (>&2 echo " THRIFT_RELEASE_VERSION is in semantic versioning format, i.e. #.##.##") exit 1 fi THRIFT_RELEASE_VERSION=${1:-} echo "Updating Cargo.toml to ${THRIFT_RELEASE_VERSION}" sed -i.old -e "s/^version = .*$/version = \"${THRIFT_RELEASE_VERSION}\"/g" Cargo.toml rm Cargo.toml.old echo "Committing updated Cargo.toml" git add Cargo.toml git commit -m "Update thrift crate version to ${THRIFT_RELEASE_VERSION}" -m "Client: rs" echo "Packaging and releasing rust thrift crate with version ${THRIFT_RELEASE_VERSION}" cargo clean cargo package cargo publish thrift-0.23.0/lib/rs/test_recursive/0000755000175000017500000000000015170007201017605 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test_recursive/src/0000755000175000017500000000000015170007201020374 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test_recursive/src/maintenance/0000755000175000017500000000000015170007201022656 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift0000664000175000017500000000256215165535636030044 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace rs maintenance include "Buses.thrift" include "LightRail.thrift" include "Streetcars.thrift" include "Transporters.thrift" service BigBarn extends Streetcars.Barn { Streetcars.Streetcar addStreetcar(1: Streetcars.Route route) } service MultimodalFacility extends Buses.Garage { Transporters.SingleVehicleTransporter buildTransporter(1: string source, 2: string destination, 3: Transporters.FlatcarConsist consist) }thrift-0.23.0/lib/rs/test_recursive/src/maintenance/Makefile.in0000644000175000017500000006000315170007167024735 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rs/test_recursive/src/maintenance ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . EXTRA_DIST = \ mod.rs \ MaintenanceFacility.thrift all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test_recursive/src/maintenance/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test_recursive/src/maintenance/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: ../Vehicles.thrift ../transit/Buses.thrift ../transit/Trains.thrift ../transit/Transporters.thrift ../transit/services/CityServices.thrift ../transit/light/LightRail.thrift ../transit/light/Streetcars.thrift $(THRIFT) $(THRIFT) -I . -I ../ -I ../transit -I ../transit/services -I ../transit/light -out . --gen rs MaintenanceFacility.thrift check: stubs clean-local: -$(RM) maintenance_facility.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test_recursive/src/maintenance/mod.rs0000664000175000017500000000147415165535636024041 0ustar00buildbuild00000000000000// 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. pub mod maintenance_facility; thrift-0.23.0/lib/rs/test_recursive/src/maintenance/Makefile.am0000664000175000017500000000251115165535636024741 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . THRIFT = $(top_builddir)/compiler/cpp/thrift stubs: ../Vehicles.thrift ../transit/Buses.thrift ../transit/Trains.thrift ../transit/Transporters.thrift ../transit/services/CityServices.thrift ../transit/light/LightRail.thrift ../transit/light/Streetcars.thrift $(THRIFT) $(THRIFT) -I . -I ../ -I ../transit -I ../transit/services -I ../transit/light -out . --gen rs MaintenanceFacility.thrift check: stubs clean-local: -$(RM) maintenance_facility.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ mod.rs \ MaintenanceFacility.thrift thrift-0.23.0/lib/rs/test_recursive/src/transit/0000755000175000017500000000000015170007201022060 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test_recursive/src/transit/Buses.thrift0000664000175000017500000000307015165535636024413 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace rs transit include "CityServices.thrift" include "Vehicles.thrift" const Vehicles.Capacity DEFAULT4WHEELCAPACITY = 30 enum Powertrain { DIESEL = 0 BIO_DIESEL = 1 COMPRESSED_NATURAL_GAS = 2 TROLLEY = 3 HYBRID = 4 BATTERY = 5 } struct Bus { 1: Vehicles.VehicleIdentifier identifier 2: Vehicles.Capacity capacity 3: Powertrain powertrain 4: list materials } struct Route { 1: string routeId 2: list improvements } service Garage { Bus upgradeBus(1: Bus bus) list improvementsForRoute(1: Route route) }thrift-0.23.0/lib/rs/test_recursive/src/transit/light/0000755000175000017500000000000015170007201023167 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test_recursive/src/transit/light/LightRail.thrift0000664000175000017500000000256215165535636026325 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ include "CityServices.thrift" include "Trains.thrift" include "Vehicles.thrift" namespace rs transit.light struct Lrt { 1: list materials 2: Trains.Locomotive locomotive } enum Route { EglintonCrosstown = 0 FinchWest = 1 } struct Line { 1: Lrt lrt 2: Route route 3: list improvements = [] // ABSOLUTELY NONE BY DEFAULT! } service Msf { Lrt fixLrt(1: Lrt lrt) }thrift-0.23.0/lib/rs/test_recursive/src/transit/light/Streetcars.thrift0000664000175000017500000000336515165535636026567 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ include "CityServices.thrift" include "Trains.thrift" include "Vehicles.thrift" namespace rs transit.light struct CLRV { 1: list materials 2: Trains.Locomotive locomotive } struct Flexity { 1: list materials 2: Trains.Locomotive locomotive } union RollingStock { 1: CLRV clrv 2: Flexity flexity } enum RouteNumber { Queen = 501 Downtowner = 502 Kingston = 503 King = 504 Dundas = 505 Carlton = 506 Lakeshore = 508 Harbourfront = 509 Spadina = 510 Bathurst = 511 StClair = 512 } struct Route { 1: RouteNumber id 2: list improvements = [] // ABSOLUTELY NONE! } struct Streetcar { 1: i16 id 2: RollingStock stock 3: Route route } service Barn { Streetcar upgradeStreetcar(1: Streetcar streetcar) }thrift-0.23.0/lib/rs/test_recursive/src/transit/light/Makefile.in0000644000175000017500000005774215170007167025266 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rs/test_recursive/src/transit/light ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . EXTRA_DIST = \ mod.rs \ LightRail.thrift \ Streetcars.thrift all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test_recursive/src/transit/light/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test_recursive/src/transit/light/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: ../../Vehicles.thrift ../Trains.thrift ../services/CityServices.thrift LightRail.thrift Streetcars.thrift $(THRIFT) $(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs LightRail.thrift $(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs Streetcars.thrift check: stubs clean-local: -$(RM) light_rail.rs -$(RM) streetcars.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test_recursive/src/transit/light/mod.rs0000664000175000017500000000150615165535636024346 0ustar00buildbuild00000000000000// 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. pub mod light_rail; pub mod streetcars; thrift-0.23.0/lib/rs/test_recursive/src/transit/light/Makefile.am0000664000175000017500000000244215165535636025255 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . THRIFT = $(top_builddir)/compiler/cpp/thrift stubs: ../../Vehicles.thrift ../Trains.thrift ../services/CityServices.thrift LightRail.thrift Streetcars.thrift $(THRIFT) $(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs LightRail.thrift $(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs Streetcars.thrift check: stubs clean-local: -$(RM) light_rail.rs -$(RM) streetcars.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ mod.rs \ LightRail.thrift \ Streetcars.thrift thrift-0.23.0/lib/rs/test_recursive/src/transit/Trains.thrift0000664000175000017500000000214415165535636024573 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace rs transit enum Locomotive { Steam = 0 ElectricPole = 1 ElectricPantograph = 2 ElectricThirdRail = 3 DieselMechanical = 4 DieselElectric = 5 } thrift-0.23.0/lib/rs/test_recursive/src/transit/Transporters.thrift0000664000175000017500000000236615165535636026047 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace rs transit include "Buses.thrift" include "LightRail.thrift" include "Streetcars.thrift" union FlatcarConsist { 1: LightRail.Lrt lrt 2: Streetcars.Streetcar streetcar 3: Buses.Bus bus } struct SingleVehicleTransporter { 1: FlatcarConsist consist 2: string source 3: string destination } thrift-0.23.0/lib/rs/test_recursive/src/transit/services/0000755000175000017500000000000015170007201023703 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test_recursive/src/transit/services/Makefile.in0000644000175000017500000005740115170007167025772 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rs/test_recursive/src/transit/services ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . EXTRA_DIST = \ mod.rs \ CityServices.thrift all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test_recursive/src/transit/services/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test_recursive/src/transit/services/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: CityServices.thrift $(THRIFT) $(THRIFT) -I . -out . --gen rs CityServices.thrift check: stubs clean-local: -$(RM) city_services.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test_recursive/src/transit/services/mod.rs0000664000175000017500000000146515165535636025066 0ustar00buildbuild00000000000000// 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. pub mod city_services; thrift-0.23.0/lib/rs/test_recursive/src/transit/services/CityServices.thrift0000664000175000017500000000206015165535636027567 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ namespace rs transit.services enum TransitImprovements { TransitSignalPriority = 1 DedicatedRightOfWay = 2 } thrift-0.23.0/lib/rs/test_recursive/src/transit/services/Makefile.am0000664000175000017500000000207015165535636025766 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . THRIFT = $(top_builddir)/compiler/cpp/thrift stubs: CityServices.thrift $(THRIFT) $(THRIFT) -I . -out . --gen rs CityServices.thrift check: stubs clean-local: -$(RM) city_services.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ mod.rs \ CityServices.thrift thrift-0.23.0/lib/rs/test_recursive/src/transit/Makefile.in0000644000175000017500000006026015170007167024144 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rs/test_recursive/src/transit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # intentionally added a cyclic dependency between '.' and 'light' SUBDIRS = . light services EXTRA_DIST = \ mod.rs \ Buses.thrift \ Trains.thrift \ Transporters.thrift all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test_recursive/src/transit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test_recursive/src/transit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: ../Vehicles.thrift Buses.thrift Trains.thrift Transporters.thrift services/CityServices.thrift light/LightRail.thrift light/Streetcars.thrift $(THRIFT) $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Buses.thrift $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Trains.thrift $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Transporters.thrift check: stubs clean-local: -$(RM) buses.rs -$(RM) trains.rs -$(RM) transporters.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test_recursive/src/transit/mod.rs0000664000175000017500000000156415165535636023243 0ustar00buildbuild00000000000000// 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. pub mod buses; pub mod light; pub mod services; pub mod trains; pub mod transporters; thrift-0.23.0/lib/rs/test_recursive/src/transit/Makefile.am0000664000175000017500000000300115165535636024136 0ustar00buildbuild00000000000000# # 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. # # intentionally added a cyclic dependency between '.' and 'light' SUBDIRS = . light services THRIFT = $(top_builddir)/compiler/cpp/thrift stubs: ../Vehicles.thrift Buses.thrift Trains.thrift Transporters.thrift services/CityServices.thrift light/LightRail.thrift light/Streetcars.thrift $(THRIFT) $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Buses.thrift $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Trains.thrift $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Transporters.thrift check: stubs clean-local: -$(RM) buses.rs -$(RM) trains.rs -$(RM) transporters.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ mod.rs \ Buses.thrift \ Trains.thrift \ Transporters.thrift thrift-0.23.0/lib/rs/test_recursive/src/lib.rs0000664000175000017500000002342515165535636021546 0ustar00buildbuild00000000000000// 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. #![allow(dead_code)] pub mod maintenance; pub mod transit; pub mod vehicles; mod server { use crate::maintenance::maintenance_facility::{ BigBarnSyncHandler, MultimodalFacilitySyncHandler, }; use crate::transit::buses::{Bus, GarageSyncHandler}; use crate::transit::buses::{Powertrain, Route as BusRoute}; use crate::transit::light::streetcars::{ BarnSyncHandler, Flexity, RollingStock, Route, RouteNumber, Streetcar, }; use crate::transit::services::city_services::TransitImprovements; use crate::transit::trains::Locomotive; use crate::transit::transporters::{FlatcarConsist, SingleVehicleTransporter}; use crate::vehicles::Material; use thrift::Result; // // implement a whole bunch of handler methods just to make sure I can, and that everything compiles // pub struct AllInOneHandler; impl BigBarnSyncHandler for AllInOneHandler { fn handle_add_streetcar(&self, route: Route) -> Result { if let Some(route_number) = route.id { match route_number { RouteNumber::LAKESHORE => Ok(Streetcar { id: Some(4417), stock: Some(RollingStock::Flexity(Flexity { materials: Some(vec![Material::STEEL, Material::ALUMINUM]), locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH), })), route: Some(Route { id: Some(RouteNumber::LAKESHORE), improvements: None, }), }), _ => Err(thrift::Error::from(format!( "Cannot create streetcar for route number {}", route_number.0 ))), } } else { Err(thrift::Error::from("Can't add a streetcar")) } } } impl BarnSyncHandler for AllInOneHandler { fn handle_upgrade_streetcar(&self, streetcar: Streetcar) -> Result { if let Some(rolling_stock) = streetcar.stock { match rolling_stock { RollingStock::Clrv(_) => Ok(Streetcar { stock: Some(RollingStock::Flexity(Flexity { materials: Some(vec![Material::STEEL, Material::ALUMINUM]), locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH), })), ..streetcar }), RollingStock::Flexity(_) => { Err(thrift::Error::from("Streetcar already upgraded")) } } } else { Err(thrift::Error::from("Can't upgrade streetcar")) } } } impl MultimodalFacilitySyncHandler for AllInOneHandler { fn handle_build_transporter( &self, source: String, destination: String, consist: FlatcarConsist, ) -> Result { Ok(SingleVehicleTransporter { consist: Some(consist), source: Some(source), destination: Some(destination), }) } } impl GarageSyncHandler for AllInOneHandler { fn handle_upgrade_bus(&self, bus: Bus) -> Result { if let Some(p) = bus.powertrain { match p { Powertrain::COMPRESSED_NATURAL_GAS => Ok(Bus { powertrain: Some(Powertrain::DIESEL), ..bus }), _ => Err(thrift::Error::from("Cannot upgrade from this powertrain")), } } else { Err(thrift::Error::from("Cannot upgrade bus")) } } fn handle_improvements_for_route( &self, route: BusRoute, ) -> Result> { Ok(route .improvements .expect("Expecting a list of improvements")) } } } #[cfg(test)] mod tests { // // TODO: consider using the generated client/server and doing a round-trip // use crate::server::AllInOneHandler; use crate::transit::buses::{Bus, Powertrain, Route as BusRoute, DEFAULT4WHEELCAPACITY}; use crate::transit::light::light_rail::Lrt; use crate::transit::light::streetcars::{ BarnSyncHandler, Flexity, RollingStock, Route, RouteNumber, Streetcar, CLRV, }; use crate::transit::services::city_services::TransitImprovements; use crate::transit::trains::Locomotive; use crate::transit::transporters::{FlatcarConsist, SingleVehicleTransporter}; use crate::vehicles::{Material, VehicleIdentifier}; use crate::maintenance::maintenance_facility::{ BigBarnSyncHandler, MultimodalFacilitySyncHandler, }; use crate::transit::buses::GarageSyncHandler; #[test] fn handle_add_streetcar_compiles_and_returns_expected_value() { let expected = Streetcar { id: Some(4417), stock: Some(RollingStock::Flexity(Flexity { materials: Some(vec![Material::STEEL, Material::ALUMINUM]), locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH), })), route: Some(Route { id: Some(RouteNumber::LAKESHORE), improvements: None, }), }; let handler = AllInOneHandler {}; let actual = handler .handle_add_streetcar(Route { id: Some(RouteNumber::LAKESHORE), improvements: None, }) .expect("Expected a result"); assert_eq!(expected, actual) } #[test] fn handle_upgrade_streetcar_compiles_and_returns_expected_value() { let input = Streetcar { stock: Some(RollingStock::Clrv(CLRV { materials: Some(vec![Material::STEEL, Material::ALUMINUM]), locomotive: Some(Locomotive::ELECTRIC_POLE), })), id: Some(4415), route: Some(Route { id: Some(RouteNumber::SPADINA), improvements: Some(vec![TransitImprovements::DEDICATED_RIGHT_OF_WAY]), }), }; let expected = Streetcar { stock: Some(RollingStock::Flexity(Flexity { materials: Some(vec![Material::STEEL, Material::ALUMINUM]), locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH), })), id: Some(4415), route: Some(Route { id: Some(RouteNumber::SPADINA), improvements: Some(vec![TransitImprovements::DEDICATED_RIGHT_OF_WAY]), }), }; let handler = AllInOneHandler {}; let actual = handler .handle_upgrade_streetcar(input) .expect("Expected an upgraded streetcar"); assert_eq!(expected, actual) } #[test] fn handle_build_transporter_compiles_and_returns_expected_value() { let consist = FlatcarConsist::Lrt(Lrt { materials: Some(vec![Material::STEEL, Material::ALUMINUM]), locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH), }); let expected = SingleVehicleTransporter { consist: Some(consist.clone()), source: Some("905".to_owned()), destination: Some("416".to_owned()), }; let handler = AllInOneHandler {}; let actual = handler .handle_build_transporter("905".to_owned(), "416".to_owned(), consist) .expect("Expected a transporter"); assert_eq!(expected, actual) } #[test] fn handle_upgrade_bus_compiles_and_returns_expected_value() { let bus = Bus { identifier: Some(VehicleIdentifier { manufacturer: Some("Orion".to_owned()), model: Some("Orion 07.501 NG HEV".to_owned()), qualifiers: None, }), capacity: Some(DEFAULT4WHEELCAPACITY), powertrain: Some(Powertrain::COMPRESSED_NATURAL_GAS), materials: Some(vec![Material::STEEL, Material::ALUMINUM]), }; let expected = Bus { powertrain: Some(Powertrain::DIESEL), ..(bus.clone()) }; let handler = AllInOneHandler {}; let actual = handler .handle_upgrade_bus(bus) .expect("Expected improved bus"); assert_eq!(expected, actual) } #[test] fn handle_improvements_for_route_compiles_and_returns_expected_value() { let expected = vec![TransitImprovements::TRANSIT_SIGNAL_PRIORITY]; let bus_route = BusRoute { route_id: Some("320".to_owned()), improvements: Some(expected.clone()), }; let handler = AllInOneHandler {}; let actual = handler .handle_improvements_for_route(bus_route) .expect("Expected list of transit improvements"); assert_eq!(expected, actual) } } thrift-0.23.0/lib/rs/test_recursive/src/Vehicles.thrift0000664000175000017500000000214715165535636023414 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ typedef i16 Capacity enum Material { Steel = 0 Aluminum = 1 } struct VehicleIdentifier { 1: string manufacturer 2: string model 3: list qualifiers } thrift-0.23.0/lib/rs/test_recursive/src/Makefile.in0000644000175000017500000005732115170007167022464 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rs/test_recursive/src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . transit maintenance EXTRA_DIST = \ lib.rs \ Vehicles.thrift all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test_recursive/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test_recursive/src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: Vehicles.thrift $(THRIFT) $(THRIFT) -I . -out . --gen rs Vehicles.thrift check: stubs clean-local: -$(RM) vehicles.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test_recursive/src/Makefile.am0000664000175000017500000000207315165535636022462 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . transit maintenance THRIFT = $(top_builddir)/compiler/cpp/thrift stubs: Vehicles.thrift $(THRIFT) $(THRIFT) -I . -out . --gen rs Vehicles.thrift check: stubs clean-local: -$(RM) vehicles.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ lib.rs \ Vehicles.thrift thrift-0.23.0/lib/rs/test_recursive/Cargo.toml0000664000175000017500000000043715165535636021571 0ustar00buildbuild00000000000000[package] name = "thrift_4098_custom_rust_namespace_support" description = "Test namespace support in generated thrift files using recursive Make generation" version = "0.1.0" authors = ["Allen George "] edition = "2021" [dependencies] thrift = { path = "../" } thrift-0.23.0/lib/rs/test_recursive/Makefile.in0000644000175000017500000005724415170007167021701 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rs/test_recursive ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src EXTRA_DIST = \ Cargo.toml all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test_recursive/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test_recursive/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile check: $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build $(CARGO) test clean-local: $(CARGO) clean -$(RM) Cargo.lock distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test_recursive/Makefile.am0000664000175000017500000000200715165535636021670 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = src check: $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build $(CARGO) test clean-local: $(CARGO) clean -$(RM) Cargo.lock distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ Cargo.toml thrift-0.23.0/lib/rs/RELEASING.md0000664000175000017500000000354315165535636016427 0ustar00buildbuild00000000000000# Publishing the thrift crate Publishing the Rust thrift crate is straightforward, and involves two major steps: 1. Setting up your [crates.io](https://www.crates.io) account _(one-time)_ 2. Packaging/publishing the Rust thrift crate itself ## Set up your crates.io account (one-time) 1. Go to [crates.io](https://www.crates.io) and click the `Log In` button at the top right. Log in **as the Github user with write permissions to the thrift repo!** 2. Click your user icon button at the top right and select `Account Settings`. 3. Click `New Token` next to `API Access`. This generates a new API key that cargo uses to publish packages to crates.io. Store this API key somewhere safe. If you will only use this Github account to publish crates to crates.io you can follow the instructions to save the generated key to `~/.cargo/credentials`. ## Package and Publish You can use the automated script or run the release steps manually. **Important**: `cargo` expects that version numbers follow the semantic versioning format. This means that `THRIFT_RELEASE_VERSION` must have a major, minor and patch number, i.e., must be in the form `#.##.##`. #### Automated Run `./release.sh [THRIFT_RELEASE_VERSION]`. _Requires you to have stored your credentials in `~/.cargo/credentials`._ #### Manual 1. Edit `Cargo.toml` and update the `version = 1.0` key to `version = [THRIFT_RELEASE_VERSION]` 2. `git add Cargo.toml` 3. `git commit -m "Update thrift crate version to [THRIFT_RELEASE_VERSION]" -m "Client: rs"` 4. `cargo login` _(not required if you have stored your credentials in `~/.cargo/credentials`)_ 5. `cargo clean` 6. `cargo package` This step fails if there are any uncommitted or ignored files. Do **not** use the `--allow-dirty` flag! Instead, add the highlighted files as entries in the `Cargo.toml` `exclude` key. 7. `cargo publish` thrift-0.23.0/lib/rs/test/0000755000175000017500000000000015170007201015516 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/thrifts/0000755000175000017500000000000015170007201017201 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/thrifts/Ultimate.thrift0000664000175000017500000000355015165535636022242 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ include "Midlayer.thrift" enum Drink { WATER, WHISKEY, WINE, scotch, // intentionally poorly cased LATE_HARVEST_WINE, India_Pale_Ale, // intentionally poorly cased apple_cider, // intentially poorly cased belgian_Ale, // intentionally poorly cased Canadian_whisky, // intentionally poorly cased } const map RankedPies = { 1: Midlayer.Pie.PUMPKIN, 2: Midlayer.Pie.STRAWBERRY_RHUBARB, 3: Midlayer.Pie.apple, 4: Midlayer.Pie.mississippi_mud, 5: Midlayer.Pie.coconut_Cream, 6: Midlayer.Pie.Key_Lime, } struct FullMeal { 1: required Midlayer.Meal meal 2: required Midlayer.Dessert dessert } struct FullMealAndDrinks { 1: required FullMeal fullMeal 2: optional Drink drink } service FullMealService extends Midlayer.MealService { FullMeal fullMeal() } service FullMealAndDrinksService extends FullMealService { FullMealAndDrinks fullMealAndDrinks() Midlayer.Pie bestPie() } thrift-0.23.0/lib/rs/test/thrifts/Base_Two.thrift0000664000175000017500000000247315165535636022164 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ const i32 WaterWeight = 200 enum brothType { Miso, shouyu, } struct Ramen { 1: optional string ramenType 2: required i32 noodleCount 3: brothType broth } struct Napkin { // empty } service NapkinService { Napkin napkin() } service RamenService extends NapkinService { Ramen ramen(1: i32 requestedNoodleCount) } /* const struct CookedRamen = { "bar": 10 } */ thrift-0.23.0/lib/rs/test/thrifts/Base_One.thrift0000664000175000017500000000421215165535636022125 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ typedef i64 Temperature typedef i8 Size typedef string Location const i32 BoilingPoint = 100 const list Temperatures = [10, 11, 22, 33] // IMPORTANT: temps should end with ".0" because this tests // that we don't have a problem with const float list generation const list CommonTemperatures = [300.0, 450.0] const double MealsPerDay = 2.5; const string DefaultRecipeName = "Soup-rise of the Day" const binary DefaultRecipeBinary = "Soup-rise of the 01010101" struct Noodle { 1: string flourType 2: Temperature cookTemp } struct Spaghetti { 1: optional list noodles } const Noodle SpeltNoodle = { "flourType": "spelt", "cookTemp": 110 } struct MeasuringSpoon { 1: Size size } struct MeasuringCup { 1: double millis } union MeasuringAids { 1: MeasuringSpoon spoon 2: MeasuringCup cup } struct CookingTemperatures { 1: set commonTemperatures 2: list usedTemperatures 3: map fahrenheitToCentigradeConversions } struct Recipe { 1: string recipeName 2: string cuisine 3: i8 page 4: uuid recipeId } union CookingTools { 1: set measuringSpoons 2: map measuringCups, 3: list recipes } thrift-0.23.0/lib/rs/test/thrifts/Midlayer.thrift0000664000175000017500000000362015165535636022222 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * Contains some contributions under the Thrift Software License. * Please see doc/old-thrift-license.txt in the Thrift distribution for * details. */ include "Base_One.thrift" include "Base_Two.thrift" const i32 WaterBoilingPoint = Base_One.BoilingPoint const map TemperatureNames = { "freezing": 0, "boiling": 100 } const map, map, string>> MyConstNestedMap = { [0, 1, 2, 3]: { ["foo"]: "bar" }, [20]: { ["nut", "ton"] : "bar" }, [30, 40]: { ["bouncy", "tinkly"]: "castle" } } const list> MyConstNestedList = [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ] const set> MyConstNestedSet = [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ] enum Pie { PUMPKIN, apple, // intentionally poorly cased STRAWBERRY_RHUBARB, Key_Lime, // intentionally poorly cased coconut_Cream, // intentionally poorly cased mississippi_mud, // intentionally poorly cased } struct Meal { 1: Base_One.Noodle noodle 2: Base_Two.Ramen ramen } union Dessert { 1: string port 2: string iceWine } service MealService extends Base_Two.RamenService { Meal meal() } thrift-0.23.0/lib/rs/test/src/0000755000175000017500000000000015170007201016305 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/src/bin/0000755000175000017500000000000015170007201017055 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/src/bin/kitchen_sink_client.rs0000664000175000017500000002223015165535636023461 0ustar00buildbuild00000000000000// 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. use clap::{clap_app, value_t}; use log::*; use std::convert::Into; use std::net::TcpStream; use std::net::ToSocketAddrs; #[cfg(unix)] use std::os::unix::net::UnixStream; #[cfg(unix)] use std::path::Path; use kitchen_sink::base_two::{TNapkinServiceSyncClient, TRamenServiceSyncClient}; use kitchen_sink::midlayer::{MealServiceSyncClient, TMealServiceSyncClient}; use kitchen_sink::recursive; use kitchen_sink::recursive::{CoRec, CoRec2, RecList, RecTree, TTestServiceSyncClient}; use kitchen_sink::ultimate::{FullMealServiceSyncClient, TFullMealServiceSyncClient}; use thrift::protocol::{ TBinaryInputProtocol, TBinaryOutputProtocol, TCompactInputProtocol, TCompactOutputProtocol, TInputProtocol, TOutputProtocol, }; use thrift::transport::{TFramedReadTransport, TFramedWriteTransport, TIoChannel, TTcpChannel}; type IoProtocol = (Box, Box); fn main() { match run() { Ok(()) => println!("kitchen sink client completed successfully"), Err(e) => { println!("kitchen sink client failed with error {:?}", e); std::process::exit(1); } } } fn run() -> thrift::Result<()> { let matches = clap_app!(rust_kitchen_sink_client => (version: "0.1.0") (author: "Apache Thrift Developers ") (about: "Thrift Rust kitchen sink client") (@arg host: --host +takes_value "Host on which the Thrift test server is located") (@arg port: --port +takes_value "Port on which the Thrift test server is listening") (@arg domain_socket: --("domain-socket") + takes_value "Unix Domain Socket on which the Thrift test server is listening") (@arg protocol: --protocol +takes_value "Thrift protocol implementation to use (\"binary\", \"compact\")") (@arg service: --service +takes_value "Service type to contact (\"part\", \"full\", \"recursive\")") ) .get_matches(); let host = matches.value_of("host").unwrap_or("127.0.0.1"); let port = value_t!(matches, "port", u16).unwrap_or(9090); let domain_socket = matches.value_of("domain_socket"); let protocol = matches.value_of("protocol").unwrap_or("compact"); let service = matches.value_of("service").unwrap_or("part"); let (i_prot, o_prot) = match domain_socket { None => { let listen_address = format!("{}:{}", host, port); info!("Client binds to {} with {}", listen_address, protocol); bind(listen_address, protocol)? } Some(domain_socket) => { info!("Client binds to {} (UDS) with {}", domain_socket, protocol); bind_uds(domain_socket, protocol)? } }; run_client(service, i_prot, o_prot) } fn bind(listen_address: A, protocol: &str) -> Result { let stream = TcpStream::connect(listen_address)?; let channel = TTcpChannel::with_stream(stream); let (i_prot, o_prot) = build(channel, protocol)?; Ok((i_prot, o_prot)) } #[cfg(unix)] fn bind_uds>(domain_socket: P, protocol: &str) -> Result { let stream = UnixStream::connect(domain_socket)?; let (i_prot, o_prot) = build(stream, protocol)?; Ok((i_prot, o_prot)) } fn build( channel: C, protocol: &str, ) -> thrift::Result<(Box, Box)> { let (i_chan, o_chan) = channel.split()?; let (i_tran, o_tran) = ( TFramedReadTransport::new(i_chan), TFramedWriteTransport::new(o_chan), ); let (i_prot, o_prot): (Box, Box) = match protocol { "binary" => ( Box::new(TBinaryInputProtocol::new(i_tran, true)), Box::new(TBinaryOutputProtocol::new(o_tran, true)), ), "compact" => ( Box::new(TCompactInputProtocol::new(i_tran)), Box::new(TCompactOutputProtocol::new(o_tran)), ), unmatched => return Err(format!("unsupported protocol {}", unmatched).into()), }; Ok((i_prot, o_prot)) } fn run_client( service: &str, i_prot: Box, o_prot: Box, ) -> thrift::Result<()> { match service { "full" => exec_full_meal_client(i_prot, o_prot), "part" => exec_meal_client(i_prot, o_prot), "recursive" => exec_recursive_client(i_prot, o_prot), _ => Err(thrift::Error::from(format!( "unknown service type {}", service ))), } } fn exec_meal_client( i_prot: Box, o_prot: Box, ) -> thrift::Result<()> { let mut client = MealServiceSyncClient::new(i_prot, o_prot); // client.full_meal(); // <-- IMPORTANT: if you uncomment this, compilation *should* fail // this is because the MealService struct does not contain the appropriate service marker // only the following three calls work execute_call("part", "ramen", || client.ramen(50)).map(|_| ())?; execute_call("part", "meal", || client.meal()).map(|_| ())?; execute_call("part", "napkin", || client.napkin()).map(|_| ())?; Ok(()) } fn exec_full_meal_client( i_prot: Box, o_prot: Box, ) -> thrift::Result<()> { let mut client = FullMealServiceSyncClient::new(i_prot, o_prot); execute_call("full", "ramen", || client.ramen(100)).map(|_| ())?; execute_call("full", "meal", || client.meal()).map(|_| ())?; execute_call("full", "napkin", || client.napkin()).map(|_| ())?; execute_call("full", "full meal", || client.full_meal()).map(|_| ())?; Ok(()) } fn exec_recursive_client( i_prot: Box, o_prot: Box, ) -> thrift::Result<()> { let mut client = recursive::TestServiceSyncClient::new(i_prot, o_prot); let tree = RecTree { children: Some(vec![Box::new(RecTree { children: Some(vec![ Box::new(RecTree { children: None, item: Some(3), }), Box::new(RecTree { children: None, item: Some(4), }), ]), item: Some(2), })]), item: Some(1), }; let expected_tree = RecTree { children: Some(vec![Box::new(RecTree { children: Some(vec![ Box::new(RecTree { children: Some(Vec::new()), // remote returns an empty list item: Some(3), }), Box::new(RecTree { children: Some(Vec::new()), // remote returns an empty list item: Some(4), }), ]), item: Some(2), })]), item: Some(1), }; let returned_tree = execute_call("recursive", "echo_tree", || client.echo_tree(tree.clone()))?; if returned_tree != expected_tree { return Err(format!( "mismatched recursive tree {:?} {:?}", expected_tree, returned_tree ) .into()); } let list = RecList { nextitem: Some(Box::new(RecList { nextitem: Some(Box::new(RecList { nextitem: None, item: Some(3), })), item: Some(2), })), item: Some(1), }; let returned_list = execute_call("recursive", "echo_list", || client.echo_list(list.clone()))?; if returned_list != list { return Err(format!("mismatched recursive list {:?} {:?}", list, returned_list).into()); } let co_rec = CoRec { other: Some(Box::new(CoRec2 { other: Some(CoRec { other: Some(Box::new(CoRec2 { other: None })), }), })), }; let returned_co_rec = execute_call("recursive", "echo_co_rec", || { client.echo_co_rec(co_rec.clone()) })?; if returned_co_rec != co_rec { return Err(format!("mismatched co_rec {:?} {:?}", co_rec, returned_co_rec).into()); } Ok(()) } fn execute_call(service_type: &str, call_name: &str, mut f: F) -> thrift::Result where F: FnMut() -> thrift::Result, { let res = f(); match res { Ok(_) => println!("{}: completed {} call", service_type, call_name), Err(ref e) => println!( "{}: failed {} call with error {:?}", service_type, call_name, e ), } res } thrift-0.23.0/lib/rs/test/src/bin/kitchen_sink_server.rs0000664000175000017500000002447415165535636023525 0ustar00buildbuild00000000000000// 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. use clap::{clap_app, value_t}; use log::*; use thrift::protocol::{ TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory, TCompactInputProtocolFactory, TCompactOutputProtocolFactory, TInputProtocolFactory, TOutputProtocolFactory, }; use thrift::server::TServer; use thrift::transport::{ TFramedReadTransportFactory, TFramedWriteTransportFactory, TReadTransportFactory, TWriteTransportFactory, }; use crate::Socket::{ListenAddress, UnixDomainSocket}; use kitchen_sink::base_one::Noodle; use kitchen_sink::base_two::{ BrothType, Napkin, NapkinServiceSyncHandler, Ramen, RamenServiceSyncHandler, }; use kitchen_sink::midlayer::{ Dessert, Meal, MealServiceSyncHandler, MealServiceSyncProcessor, Pie, }; use kitchen_sink::recursive; use kitchen_sink::ultimate::FullMealAndDrinksServiceSyncHandler; use kitchen_sink::ultimate::{ Drink, FullMeal, FullMealAndDrinks, FullMealAndDrinksServiceSyncProcessor, FullMealServiceSyncHandler, }; enum Socket { ListenAddress(String), UnixDomainSocket(String), } fn main() { match run() { Ok(()) => println!("kitchen sink server completed successfully"), Err(e) => { println!("kitchen sink server failed with error {:?}", e); std::process::exit(1); } } } fn run() -> thrift::Result<()> { let matches = clap_app!(rust_kitchen_sink_server => (version: "0.1.0") (author: "Apache Thrift Developers ") (about: "Thrift Rust kitchen sink test server") (@arg port: --port +takes_value "Port on which the Thrift test server listens") (@arg domain_socket: --("domain-socket") + takes_value "Unix Domain Socket on which the Thrift test server listens") (@arg protocol: --protocol +takes_value "Thrift protocol implementation to use (\"binary\", \"compact\")") (@arg service: --service +takes_value "Service type to contact (\"part\", \"full\", \"recursive\")") ) .get_matches(); let port = value_t!(matches, "port", u16).unwrap_or(9090); let domain_socket = matches.value_of("domain_socket"); let protocol = matches.value_of("protocol").unwrap_or("compact"); let service = matches.value_of("service").unwrap_or("part"); let listen_address = format!("127.0.0.1:{}", port); let socket = match domain_socket { None => { info!("Server is binding to {}", listen_address); Socket::ListenAddress(listen_address) } Some(domain_socket) => { info!("Server is binding to {} (UDS)", domain_socket); Socket::UnixDomainSocket(domain_socket.to_string()) } }; let r_transport_factory = TFramedReadTransportFactory::new(); let w_transport_factory = TFramedWriteTransportFactory::new(); let (i_protocol_factory, o_protocol_factory): ( Box, Box, ) = match protocol { "binary" => ( Box::new(TBinaryInputProtocolFactory::new()), Box::new(TBinaryOutputProtocolFactory::new()), ), "compact" => ( Box::new(TCompactInputProtocolFactory::new()), Box::new(TCompactOutputProtocolFactory::new()), ), unknown => { return Err(format!("unsupported transport type {}", unknown).into()); } }; // FIXME: should processor be boxed as well? // // [sigh] I hate Rust generics implementation // // I would have preferred to build a server here, return it, and then do // the common listen-and-handle stuff, but since the server doesn't have a // common type (because each match arm instantiates a server with a // different processor) this isn't possible. // // Since what I'm doing is uncommon I'm just going to duplicate the code match service { "part" => run_meal_server( socket, r_transport_factory, i_protocol_factory, w_transport_factory, o_protocol_factory, ), "full" => run_full_meal_server( socket, r_transport_factory, i_protocol_factory, w_transport_factory, o_protocol_factory, ), "recursive" => run_recursive_server( socket, r_transport_factory, i_protocol_factory, w_transport_factory, o_protocol_factory, ), unknown => Err(format!("unsupported service type {}", unknown).into()), } } fn run_meal_server( socket: Socket, r_transport_factory: RTF, i_protocol_factory: IPF, w_transport_factory: WTF, o_protocol_factory: OPF, ) -> thrift::Result<()> where RTF: TReadTransportFactory + 'static, IPF: TInputProtocolFactory + 'static, WTF: TWriteTransportFactory + 'static, OPF: TOutputProtocolFactory + 'static, { let processor = MealServiceSyncProcessor::new(PartHandler {}); let mut server = TServer::new( r_transport_factory, i_protocol_factory, w_transport_factory, o_protocol_factory, processor, 1, ); match socket { ListenAddress(listen_address) => server.listen(listen_address), UnixDomainSocket(s) => server.listen_uds(s), } } fn run_full_meal_server( socket: Socket, r_transport_factory: RTF, i_protocol_factory: IPF, w_transport_factory: WTF, o_protocol_factory: OPF, ) -> thrift::Result<()> where RTF: TReadTransportFactory + 'static, IPF: TInputProtocolFactory + 'static, WTF: TWriteTransportFactory + 'static, OPF: TOutputProtocolFactory + 'static, { let processor = FullMealAndDrinksServiceSyncProcessor::new(FullHandler {}); let mut server = TServer::new( r_transport_factory, i_protocol_factory, w_transport_factory, o_protocol_factory, processor, 1, ); match socket { ListenAddress(listen_address) => server.listen(listen_address), UnixDomainSocket(s) => server.listen_uds(s), } } struct PartHandler; impl MealServiceSyncHandler for PartHandler { fn handle_meal(&self) -> thrift::Result { println!("part: handling meal call"); Ok(meal()) } } impl RamenServiceSyncHandler for PartHandler { fn handle_ramen(&self, _: i32) -> thrift::Result { println!("part: handling ramen call"); Ok(ramen()) } } impl NapkinServiceSyncHandler for PartHandler { fn handle_napkin(&self) -> thrift::Result { println!("part: handling napkin call"); Ok(napkin()) } } // full service // struct FullHandler; impl FullMealAndDrinksServiceSyncHandler for FullHandler { fn handle_full_meal_and_drinks(&self) -> thrift::Result { println!("full_meal_and_drinks: handling full meal and drinks call"); Ok(FullMealAndDrinks::new(full_meal(), Drink::CANADIAN_WHISKY)) } fn handle_best_pie(&self) -> thrift::Result { println!("full_meal_and_drinks: handling pie call"); Ok(Pie::MISSISSIPPI_MUD) // I prefer Pie::Pumpkin, but I have to check that casing works } } impl FullMealServiceSyncHandler for FullHandler { fn handle_full_meal(&self) -> thrift::Result { println!("full: handling full meal call"); Ok(full_meal()) } } impl MealServiceSyncHandler for FullHandler { fn handle_meal(&self) -> thrift::Result { println!("full: handling meal call"); Ok(meal()) } } impl RamenServiceSyncHandler for FullHandler { fn handle_ramen(&self, _: i32) -> thrift::Result { println!("full: handling ramen call"); Ok(ramen()) } } impl NapkinServiceSyncHandler for FullHandler { fn handle_napkin(&self) -> thrift::Result { println!("full: handling napkin call"); Ok(napkin()) } } fn full_meal() -> FullMeal { FullMeal::new(meal(), Dessert::Port("Graham's Tawny".to_owned())) } fn meal() -> Meal { Meal::new(noodle(), ramen()) } fn noodle() -> Noodle { Noodle::new("spelt".to_owned(), 100) } fn ramen() -> Ramen { Ramen::new("Mr Ramen".to_owned(), 72, BrothType::MISO) } fn napkin() -> Napkin { Napkin {} } fn run_recursive_server( socket: Socket, r_transport_factory: RTF, i_protocol_factory: IPF, w_transport_factory: WTF, o_protocol_factory: OPF, ) -> thrift::Result<()> where RTF: TReadTransportFactory + 'static, IPF: TInputProtocolFactory + 'static, WTF: TWriteTransportFactory + 'static, OPF: TOutputProtocolFactory + 'static, { let processor = recursive::TestServiceSyncProcessor::new(RecursiveTestServerHandler {}); let mut server = TServer::new( r_transport_factory, i_protocol_factory, w_transport_factory, o_protocol_factory, processor, 1, ); match socket { ListenAddress(listen_address) => server.listen(listen_address), UnixDomainSocket(s) => server.listen_uds(s), } } struct RecursiveTestServerHandler; impl recursive::TestServiceSyncHandler for RecursiveTestServerHandler { fn handle_echo_tree(&self, tree: recursive::RecTree) -> thrift::Result { println!("{:?}", tree); Ok(tree) } fn handle_echo_list(&self, lst: recursive::RecList) -> thrift::Result { println!("{:?}", lst); Ok(lst) } fn handle_echo_co_rec(&self, item: recursive::CoRec) -> thrift::Result { println!("{:?}", item); Ok(item) } } thrift-0.23.0/lib/rs/test/src/lib.rs0000664000175000017500000000305315165535636017452 0ustar00buildbuild00000000000000// 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. pub mod base_one; pub mod base_two; pub mod midlayer; pub mod recursive; pub mod ultimate; #[cfg(test)] mod tests { use std::default::Default; use super::*; #[test] fn must_be_able_to_use_constructor() { let _ = midlayer::Meal::new(Some(base_one::Noodle::default()), None); } #[test] fn must_be_able_to_use_constructor_with_no_fields() { let _ = midlayer::Meal::new(None, None); } #[test] fn must_be_able_to_use_constructor_without_option_wrap() { let _ = midlayer::Meal::new(base_one::Noodle::default(), None); } #[test] fn must_be_able_to_use_defaults() { let _ = midlayer::Meal { noodle: Some(base_one::Noodle::default()), ..Default::default() }; } } thrift-0.23.0/lib/rs/test/fuzz/0000755000175000017500000000000015170007202016515 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/fuzz/bin/0000755000175000017500000000000015170007201017264 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/fuzz/bin/corpus_generator.rs0000664000175000017500000001413515167543515023244 0ustar00buildbuild00000000000000// 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. use arbitrary::{Arbitrary, Unstructured}; use clap::Parser; use std::fs::{self, File}; use std::io::Read; use std::path::Path; use thrift::protocol::{ TBinaryOutputProtocol, TCompactOutputProtocol, TOutputProtocol, TSerializable, }; use thrift::transport::TBufferChannel; use thrift_fuzz::fuzz_test::FuzzTest; #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Args { /// Input directory containing raw binary files (mutually exclusive with --generate) #[arg(short, long, group = "input")] input_dir: Option, /// Number of random files to generate (mutually exclusive with --input-dir) #[arg(short, long, group = "input")] generate: Option, /// Output directory for serialized FuzzTest files #[arg(short, long)] output_dir: String, /// Protocol to use for serialization (binary or compact) #[arg(short, long)] protocol: String, /// Buffer size for serialization (default: 65536) #[arg(short, long, default_value = "65536")] buffer_size: usize, /// Size of random byte vector for generation (default: 16384) #[arg(long, default_value = "16384")] random_size: usize, } fn serialize_fuzz_test( fuzz_test: &FuzzTest, protocol: &str, buffer_size: usize, ) -> Result, Box> { let mut mem = TBufferChannel::with_capacity(buffer_size, buffer_size); match protocol { "binary" => { let mut out_protocol = TBinaryOutputProtocol::new(&mut mem, true); fuzz_test.write_to_out_protocol(&mut out_protocol)?; out_protocol.flush()?; } "compact" => { let mut out_protocol = TCompactOutputProtocol::new(&mut mem); fuzz_test.write_to_out_protocol(&mut out_protocol)?; out_protocol.flush()?; } _ => return Err("Invalid protocol specified. Use 'binary' or 'compact'".into()), } Ok(mem.write_bytes().to_vec()) } fn convert_corpus_file( input_path: &Path, output_dir: &Path, protocol: &str, buffer_size: usize, ) -> Result<(), Box> { // Read input file let mut input_file = File::open(input_path)?; let mut input_data = Vec::new(); input_file.read_to_end(&mut input_data)?; // Create Unstructured instance for arbitrary let mut unstructured = Unstructured::new(&input_data); // Generate FuzzTest instance if let Ok(fuzz_test) = FuzzTest::arbitrary(&mut unstructured) { // Create output file path let file_name = input_path .file_name() .ok_or("Invalid input filename")? .to_str() .ok_or("Invalid UTF-8 in filename")?; let output_path = output_dir.join(file_name); // Serialize and write to file let serialized_data = serialize_fuzz_test(&fuzz_test, protocol, buffer_size)?; fs::write(output_path, serialized_data)?; } Ok(()) } fn generate_random_file( output_dir: &Path, index: usize, protocol: &str, buffer_size: usize, random_size: usize, ) -> Result<(), Box> { // Generate random bytes let random_bytes: Vec = (0..random_size).map(|_| rand::random::()).collect(); // Create Unstructured instance for arbitrary let mut unstructured = Unstructured::new(&random_bytes); // Generate FuzzTest instance if let Ok(fuzz_test) = FuzzTest::arbitrary(&mut unstructured) { // Create output file path with index let output_path = output_dir.join(format!("generated_{index}.bin")); // Serialize and write to file let serialized_data = serialize_fuzz_test(&fuzz_test, protocol, buffer_size)?; fs::write(output_path, serialized_data)?; } Ok(()) } fn main() -> Result<(), Box> { let args = Args::parse(); // Validate protocol if args.protocol != "binary" && args.protocol != "compact" { return Err("Invalid protocol specified. Use 'binary' or 'compact'".into()); } // Create output directory if it doesn't exist fs::create_dir_all(&args.output_dir)?; match (args.input_dir, args.generate) { (Some(input_dir), None) => { // Process each file in the input directory for entry in fs::read_dir(&input_dir)? { let entry = entry?; let path = entry.path(); if path.is_file() { if let Err(e) = convert_corpus_file( &path, Path::new(&args.output_dir), &args.protocol, args.buffer_size, ) { eprintln!("Error processing file {path:?}: {e}"); } } } } (None, Some(num_files)) => { // Generate random files for i in 0..num_files { if let Err(e) = generate_random_file( Path::new(&args.output_dir), i, &args.protocol, args.buffer_size, args.random_size, ) { eprintln!("Error generating file {i}: {e}"); } } } _ => return Err("Must specify either --input-dir or --generate".into()), } Ok(()) } thrift-0.23.0/lib/rs/test/fuzz/Cargo.toml0000664000175000017500000000414315165535636020476 0ustar00buildbuild00000000000000# 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] name = "thrift-fuzz" version = "0.0.0" publish = false edition = "2021" [package.metadata] cargo-fuzz = true [lib] path = "lib/mod.rs" [dependencies] libfuzzer-sys = "0.4" uuid = { version = "1", features = ["arbitrary"] } arbitrary = { version = "1", features = ["derive"] } ordered-float = { version = "4.6.0", features = ["arbitrary"] } clap = { version = "4.5", features = ["derive"] } rand = "0.9" [dependencies.thrift] path = "../../../../lib/rs" [[bin]] name = "corpus_generator" path = "bin/corpus_generator.rs" [[bin]] name = "parse_compact" path = "fuzz_targets/parse_compact.rs" test = false doc = false bench = false [[bin]] name = "parse_binary" path = "fuzz_targets/parse_binary.rs" test = false doc = false bench = false [[bin]] name = "roundtrip_binary" path = "fuzz_targets/roundtrip_binary.rs" test = false doc = false bench = false [[bin]] name = "roundtrip_compact" path = "fuzz_targets/roundtrip_compact.rs" test = false doc = false bench = false # TODO (THRIFT-5891): Enable these once we fix round-trip correctness. # [[bin]] # name = "structured_roundtrip_compact" # path = "fuzz_targets/structured_roundtrip_compact.rs" # test = false # doc = false # bench = false # [[bin]] # name = "structured_roundtrip_binary" # path = "fuzz_targets/structured_roundtrip_binary.rs" # test = false # doc = false # bench = falsethrift-0.23.0/lib/rs/test/fuzz/README.md0000664000175000017500000000327215165535636020027 0ustar00buildbuild00000000000000# Rust fuzzing README To build the fuzz targets, simply run `make check` in this directory These are standard cargo fuzz targets, so you can use the [standard cargo fuzz commands](https://rust-fuzz.github.io/book/introduction.html) to build and run them. You can also build with cargo fuzz directly after the initial build with `make check`, e.g. run `cargo fuzz run $fuzzer_name` We currently have six fuzz targets: * parse_compact -- fuzzes the deserialization of the Compact protocol * parse_binary -- fuzzes the deserialization of the Binary protocol * roundtrip_compact -- fuzzes the roundtrip of the Compact protocol (i.e. serializes and then deserializes and compares the result to the original) * roundtrip_binary -- fuzzes the roundtrip of the Binary protocol * structured_roundtrip_compact -- roundtrip, but starts from a valid compact thrift structure * structured_roundtrip_binary -- roundtrip, but starts from a valid binary thrift structure Some of the roundtrip fuzzers are structure aware, i.e. they generate mostly valid thrift structures, so we can also test serialization in addition to deserialization. We do have non structure aware roundtrip fuzzers as well, to match what's present in other languages (and also handle some corner cases). We also have a corpus generator script that can be used to generate a corpus of fuzz inputs. It can be run with `cargo run --bin corpus_generator -- --output-dir --protocol --buffer-size --random-size `. This is useful for generating corpora for the parsing fuzzers, and can be used across all languages (for cases where the other languages don't have good native structure aware fuzzing support).thrift-0.23.0/lib/rs/test/fuzz/lib/0000755000175000017500000000000015170007201017262 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/fuzz/lib/mod.rs0000664000175000017500000000146115165535636020441 0ustar00buildbuild00000000000000// 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. pub mod fuzz_test; thrift-0.23.0/lib/rs/test/fuzz/Makefile.in0000644000175000017500000004427615170007167020611 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/rs/test/fuzz ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ Cargo.toml \ lib/mod.rs \ fuzz_targets/parse_compact.rs \ fuzz_targets/parse_binary.rs \ fuzz_targets/roundtrip_binary.rs \ fuzz_targets/roundtrip_compact.rs \ fuzz_targets/structured_roundtrip_compact.rs \ fuzz_targets/structured_roundtrip_binary.rs \ bin/corpus_generator.rs all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test/fuzz/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test/fuzz/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags-am uninstall uninstall-am .PRECIOUS: Makefile # These sed commands are needed to work around the fact that the generator doesn't # support the arbitrary crate yet. stubs: $(top_builddir)/test/FuzzTest.thrift $(THRIFT) $(THRIFT) -out lib/ --gen rs $(top_builddir)/test/FuzzTest.thrift sed -i 's/thrift::OrderedFloat/ordered_float::OrderedFloat/g' lib/fuzz_test.rs sed -i 's/derive(/derive(arbitrary::Arbitrary, /g' lib/fuzz_test.rs check: stubs $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build clean-local: $(CARGO) clean -$(RM) Cargo.lock -$(RM) -r target/ -$(RM) -r corpus/ -$(RM) -r artifacts/ -$(RM) -r coverage/ -$(RM) lib/fuzz_test.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test/fuzz/fuzz_targets/0000755000175000017500000000000015170007201021243 5ustar00buildbuild00000000000000thrift-0.23.0/lib/rs/test/fuzz/fuzz_targets/structured_roundtrip_compact.rs0000664000175000017500000000354215165535636027665 0ustar00buildbuild00000000000000// 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. #![no_main] use thrift::protocol::{ TCompactInputProtocol, TCompactOutputProtocol, TOutputProtocol, TSerializable, }; use thrift::transport::TBufferChannel; use thrift_fuzz::fuzz_test::FuzzTest; const BUFFER_CAPACITY: usize = 65536; fn run(input: FuzzTest) -> thrift::Result<()> { // TODO: Figure out a way to do this without hardcoding the buffer size // Serialize let mut mem = TBufferChannel::with_capacity(BUFFER_CAPACITY, BUFFER_CAPACITY); let mut out_protocol = TCompactOutputProtocol::new(&mut mem); input.write_to_out_protocol(&mut out_protocol)?; out_protocol.flush()?; // Get the serialized bytes let serialized = mem.write_bytes(); // Deserialize let mut mem = TBufferChannel::with_capacity(serialized.len(), serialized.len()); mem.set_readable_bytes(&serialized); let mut in_protocol = TCompactInputProtocol::new(mem); let obj = FuzzTest::read_from_in_protocol(&mut in_protocol)?; assert_eq!(input, obj); Ok(()) } use libfuzzer_sys::fuzz_target; fuzz_target!(|input: FuzzTest| { let _ = run(input); }); thrift-0.23.0/lib/rs/test/fuzz/fuzz_targets/roundtrip_binary.rs0000664000175000017500000000467615165535636025250 0ustar00buildbuild00000000000000// 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. #![no_main] use thrift::protocol::{ TBinaryInputProtocol, TBinaryOutputProtocol, TOutputProtocol, TSerializable, }; use thrift::transport::TBufferChannel; use thrift::TConfiguration; use thrift_fuzz::fuzz_test::FuzzTest; fn run(data: &[u8]) -> thrift::Result<()> { // Add some limits to optimize fuzzing let config = TConfiguration::builder() .max_message_size(Some(data.len())) .max_frame_size(Some(data.len())) .max_container_size(Some(1024)) .max_string_size(Some(data.len())) .build() .unwrap(); // First try to deserialize the raw input bytes let mut mem = TBufferChannel::with_capacity(data.len(), data.len()); mem.set_readable_bytes(data); let mut protocol = TBinaryInputProtocol::with_config(mem, true /* strict */, config.clone()); let input = FuzzTest::read_from_in_protocol(&mut protocol)?; // Now do the roundtrip test with the successfully deserialized object let mut mem = TBufferChannel::with_capacity(data.len(), data.len()); let mut out_protocol = TBinaryOutputProtocol::new(&mut mem, true); input.write_to_out_protocol(&mut out_protocol)?; out_protocol.flush()?; // Get the serialized bytes let serialized = mem.write_bytes(); // Deserialize again let mut mem = TBufferChannel::with_capacity(serialized.len(), serialized.len()); mem.set_readable_bytes(&serialized); let mut in_protocol = TBinaryInputProtocol::with_config(mem, true, config); let obj = FuzzTest::read_from_in_protocol(&mut in_protocol)?; assert_eq!(input, obj); Ok(()) } use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { let _ = run(data); }); thrift-0.23.0/lib/rs/test/fuzz/fuzz_targets/roundtrip_compact.rs0000664000175000017500000000463415165535636025404 0ustar00buildbuild00000000000000// 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. #![no_main] use thrift::protocol::{ TCompactInputProtocol, TCompactOutputProtocol, TOutputProtocol, TSerializable, }; use thrift::transport::TBufferChannel; use thrift::TConfiguration; use thrift_fuzz::fuzz_test::FuzzTest; fn run(data: &[u8]) -> thrift::Result<()> { // Add some limits to optimize fuzzing let config = TConfiguration::builder() .max_message_size(Some(data.len())) .max_frame_size(Some(data.len())) .max_container_size(Some(1024)) .max_string_size(Some(data.len())) .build() .unwrap(); // First try to deserialize the raw input bytes let mut mem = TBufferChannel::with_capacity(data.len(), data.len()); mem.set_readable_bytes(data); let mut protocol = TCompactInputProtocol::with_config(mem, config.clone()); let input = FuzzTest::read_from_in_protocol(&mut protocol)?; // Now do the roundtrip test with the successfully deserialized object let mut mem = TBufferChannel::with_capacity(data.len(), data.len()); let mut out_protocol = TCompactOutputProtocol::new(&mut mem); input.write_to_out_protocol(&mut out_protocol)?; out_protocol.flush()?; // Get the serialized bytes let serialized = mem.write_bytes(); // Deserialize again let mut mem = TBufferChannel::with_capacity(serialized.len(), serialized.len()); mem.set_readable_bytes(&serialized); let mut in_protocol = TCompactInputProtocol::with_config(mem, config); let obj = FuzzTest::read_from_in_protocol(&mut in_protocol)?; assert_eq!(input, obj); Ok(()) } use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { let _ = run(data); }); thrift-0.23.0/lib/rs/test/fuzz/fuzz_targets/parse_binary.rs0000664000175000017500000000332015165535636024315 0ustar00buildbuild00000000000000// 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. #![no_main] use thrift::protocol::TBinaryInputProtocol; use thrift::protocol::TSerializable; use thrift::transport::TBufferChannel; use thrift::TConfiguration; use thrift_fuzz::fuzz_test::FuzzTest; fn run(data: &[u8]) -> thrift::Result { // Add some limits to optimize fuzzing let config = TConfiguration::builder() .max_message_size(Some(data.len())) .max_frame_size(Some(data.len())) .max_container_size(Some(1024)) .max_string_size(Some(data.len())) .build() .unwrap(); // Create a buffer channel with enough capacity for our data let mut mem = TBufferChannel::with_capacity(data.len(), data.len()); mem.set_readable_bytes(data); let mut protocol = TBinaryInputProtocol::with_config(mem, true /* strict */, config); FuzzTest::read_from_in_protocol(&mut protocol) } use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { let _ = run(data); }); thrift-0.23.0/lib/rs/test/fuzz/fuzz_targets/parse_compact.rs0000664000175000017500000000327715165535636024472 0ustar00buildbuild00000000000000// 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. #![no_main] use thrift::protocol::TCompactInputProtocol; use thrift::protocol::TSerializable; use thrift::transport::TBufferChannel; use thrift::TConfiguration; use thrift_fuzz::fuzz_test::FuzzTest; fn run(data: &[u8]) -> thrift::Result { // Add some limits to optimize fuzzing let config = TConfiguration::builder() .max_message_size(Some(data.len())) .max_frame_size(Some(data.len())) .max_container_size(Some(1024)) .max_string_size(Some(data.len())) .build() .unwrap(); // Create a buffer channel with enough capacity for our data let mut mem = TBufferChannel::with_capacity(data.len(), data.len()); mem.set_readable_bytes(data); let mut protocol = TCompactInputProtocol::with_config(mem, config); FuzzTest::read_from_in_protocol(&mut protocol) } use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { let _ = run(data); }); thrift-0.23.0/lib/rs/test/fuzz/fuzz_targets/structured_roundtrip_binary.rs0000664000175000017500000000355215165535636027524 0ustar00buildbuild00000000000000// 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. #![no_main] use thrift::protocol::{ TBinaryInputProtocol, TBinaryOutputProtocol, TOutputProtocol, TSerializable, }; use thrift::transport::TBufferChannel; use thrift_fuzz::fuzz_test::FuzzTest; const BUFFER_CAPACITY: usize = 65536; fn run(input: FuzzTest) -> thrift::Result<()> { // TODO: Figure out a way to do this without hardcoding the buffer size // Serialize let mut mem = TBufferChannel::with_capacity(BUFFER_CAPACITY, BUFFER_CAPACITY); let mut out_protocol = TBinaryOutputProtocol::new(&mut mem, true); input.write_to_out_protocol(&mut out_protocol)?; out_protocol.flush()?; // Get the serialized bytes let serialized = mem.write_bytes(); // Deserialize let mut mem = TBufferChannel::with_capacity(serialized.len(), serialized.len()); mem.set_readable_bytes(&serialized); let mut in_protocol = TBinaryInputProtocol::new(mem, true); let obj = FuzzTest::read_from_in_protocol(&mut in_protocol)?; assert_eq!(input, obj); Ok(()) } use libfuzzer_sys::fuzz_target; fuzz_target!(|input: FuzzTest| { let _ = run(input); }); thrift-0.23.0/lib/rs/test/fuzz/Makefile.am0000664000175000017500000000343615165535636020606 0ustar00buildbuild00000000000000# # 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. # THRIFT = $(top_builddir)/compiler/cpp/thrift # These sed commands are needed to work around the fact that the generator doesn't # support the arbitrary crate yet. stubs: $(top_builddir)/test/FuzzTest.thrift $(THRIFT) $(THRIFT) -out lib/ --gen rs $(top_builddir)/test/FuzzTest.thrift sed -i 's/thrift::OrderedFloat/ordered_float::OrderedFloat/g' lib/fuzz_test.rs sed -i 's/derive(/derive(arbitrary::Arbitrary, /g' lib/fuzz_test.rs check: stubs $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build clean-local: $(CARGO) clean -$(RM) Cargo.lock -$(RM) -r target/ -$(RM) -r corpus/ -$(RM) -r artifacts/ -$(RM) -r coverage/ -$(RM) lib/fuzz_test.rs distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ Cargo.toml \ lib/mod.rs \ fuzz_targets/parse_compact.rs \ fuzz_targets/parse_binary.rs \ fuzz_targets/roundtrip_binary.rs \ fuzz_targets/roundtrip_compact.rs \ fuzz_targets/structured_roundtrip_compact.rs \ fuzz_targets/structured_roundtrip_binary.rs \ bin/corpus_generator.rs thrift-0.23.0/lib/rs/test/Cargo.toml0000664000175000017500000000042615165535636017500 0ustar00buildbuild00000000000000[package] name = "kitchen-sink" version = "0.1.0" edition = "2021" license = "Apache-2.0" authors = ["Apache Thrift Developers "] publish = false [dependencies] clap = "~2.33" bitflags = "=1.2" log = "0.4" uuid = "1" [dependencies.thrift] path = "../" thrift-0.23.0/lib/rs/test/Makefile.in0000644000175000017500000006137715170007167017614 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_TESTS_TRUE@am__append_1 = fuzz subdir = lib/rs/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = . fuzz am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = $(top_builddir)/compiler/cpp/thrift TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . $(am__append_1) EXTRA_DIST = \ Cargo.toml \ thrifts/Base_One.thrift \ thrifts/Base_Two.thrift \ thrifts/Midlayer.thrift \ thrifts/Ultimate.thrift \ src/lib.rs \ src/bin/kitchen_sink_server.rs \ src/bin/kitchen_sink_client.rs all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile stubs: thrifts/Base_One.thrift thrifts/Base_Two.thrift thrifts/Midlayer.thrift thrifts/Ultimate.thrift $(top_builddir)/test/Recursive.thrift $(THRIFT) $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Base_One.thrift $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Base_Two.thrift $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Midlayer.thrift $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Ultimate.thrift $(THRIFT) -out src --gen rs $(top_builddir)/test/Recursive.thrift $(THRIFT) -out src --gen rs $(top_builddir)/test/Identifiers.thrift #THRIFT-4953 check: stubs $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build $(CARGO) test [ -d bin ] || mkdir bin cp target/debug/kitchen_sink_server bin/kitchen_sink_server cp target/debug/kitchen_sink_client bin/kitchen_sink_client clean-local: $(CARGO) clean -$(RM) Cargo.lock -$(RM) src/base_one.rs -$(RM) src/base_two.rs -$(RM) src/midlayer.rs -$(RM) src/ultimate.rs -$(RM) src/recursive.rs -$(RM) src/identifiers.rs -$(RM) -r bin distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/test/Makefile.am0000664000175000017500000000421015165535636017577 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . if WITH_TESTS SUBDIRS += fuzz endif THRIFT = $(top_builddir)/compiler/cpp/thrift stubs: thrifts/Base_One.thrift thrifts/Base_Two.thrift thrifts/Midlayer.thrift thrifts/Ultimate.thrift $(top_builddir)/test/Recursive.thrift $(THRIFT) $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Base_One.thrift $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Base_Two.thrift $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Midlayer.thrift $(THRIFT) -I ./thrifts -out src --gen rs thrifts/Ultimate.thrift $(THRIFT) -out src --gen rs $(top_builddir)/test/Recursive.thrift $(THRIFT) -out src --gen rs $(top_builddir)/test/Identifiers.thrift #THRIFT-4953 check: stubs $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build $(CARGO) test [ -d bin ] || mkdir bin cp target/debug/kitchen_sink_server bin/kitchen_sink_server cp target/debug/kitchen_sink_client bin/kitchen_sink_client clean-local: $(CARGO) clean -$(RM) Cargo.lock -$(RM) src/base_one.rs -$(RM) src/base_two.rs -$(RM) src/midlayer.rs -$(RM) src/ultimate.rs -$(RM) src/recursive.rs -$(RM) src/identifiers.rs -$(RM) -r bin distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ Cargo.toml \ thrifts/Base_One.thrift \ thrifts/Base_Two.thrift \ thrifts/Midlayer.thrift \ thrifts/Ultimate.thrift \ src/lib.rs \ src/bin/kitchen_sink_server.rs \ src/bin/kitchen_sink_client.rs thrift-0.23.0/lib/rs/LICENSE0000664000175000017500000003701115167543515015573 0ustar00buildbuild00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. -------------------------------------------------- SOFTWARE DISTRIBUTED WITH THRIFT: The Apache Thrift software includes a number of subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the following licenses. -------------------------------------------------- Portions of the following files are licensed under the MIT License: lib/erl/src/Makefile.am Please see doc/otp-base-license.txt for the full terms of this license. -------------------------------------------------- For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components: # Copyright (c) 2007 Thomas Porschberg # # Copying and distribution of this file, with or without # modification, are permitted in any medium without royalty provided # the copyright notice and this notice are preserved. -------------------------------------------------- For the lib/nodejs/lib/thrift/json_parse.js: /* json_parse.js 2015-05-02 Public Domain. NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. */ (By Douglas Crockford ) -------------------------------------------------- For lib/cpp/src/thrift/windows/SocketPair.cpp /* socketpair.c * Copyright 2007 by Nathan C. Myers ; some rights reserved. * This code is Free Software. It may be copied freely, in original or * modified form, subject only to the restrictions that (1) the author is * relieved from all responsibilities for any use for any purpose, and (2) * this copyright notice must be retained, unchanged, in its entirety. If * for any reason the author might be held responsible for any consequences * of copying or use, license is withheld. */ -------------------------------------------------- For lib/py/compat/win32/stdint.h // ISO C9x compliant stdint.h for Microsoft Visual Studio // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 // // Copyright (c) 2006-2008 Alexander Chemeris // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The name of the author may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// -------------------------------------------------- Codegen template in t_html_generator.h * Bootstrap v2.0.3 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. --------------------------------------------------- For t_cl_generator.cc * Copyright (c) 2008- Patrick Collison * Copyright (c) 2006- Facebook --------------------------------------------------- --------------------------------------------------- For compiler/cpp/src/thrift/generate/sha256.h SHA-256 implementation by Brad Conte (brad AT bradconte.com). Source: https://github.com/B-Con/crypto-algorithms The author has placed this code in the public domain (no copyright claimed). No algorithmic changes were made; the file was adapted to a C++ header-only form for inclusion in the Thrift compiler. thrift-0.23.0/lib/rs/NOTICE0000664000175000017500000000025615165535636015476 0ustar00buildbuild00000000000000Apache Thrift Copyright (C) 2006 - 2019, The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). thrift-0.23.0/lib/rs/Cargo.toml0000664000175000017500000000136315170007142016500 0ustar00buildbuild00000000000000[package] name = "thrift" description = "Rust bindings for the Apache Thrift RPC system" edition = "2021" version = "0.23.0" license = "Apache-2.0" authors = ["Apache Thrift Developers "] homepage = "http://thrift.apache.org" documentation = "https://docs.rs/thrift" repository = "https://github.com/apache/thrift/tree/master/lib/rs" readme = "README.md" exclude = ["Makefile*", "test/**", "*.iml"] keywords = ["thrift"] [dependencies] byteorder = "1.3" integer-encoding = "3.0.3" uuid = "1" log = {version = "0.4", optional = true} ordered-float = "3.0" threadpool = {version = "1.7", optional = true} [features] default = ["server"] server = ["threadpool", "log"] [dev-dependencies] uuid = { version = "*", features = ["v4"] } thrift-0.23.0/lib/rs/README.md0000664000175000017500000001472715165535636016061 0ustar00buildbuild00000000000000# Rust Thrift library ## Overview This crate implements the components required to build a working Thrift server and client. It is divided into the following modules: 1. errors 2. protocol 3. transport 4. server 5. autogen The modules are layered as shown. The `generated` layer is code generated by the Thrift compiler's Rust plugin. It uses the components defined in this crate to serialize and deserialize types and implement RPC. Users interact with these types and services by writing their own code on top. ```text +-----------+ | app dev | +-----------+ | generated | <-> errors/results +-----------+ | protocol | +-----------+ | transport | +-----------+ ``` ## Using this crate Add `thrift = "x.y.z"` to your `Cargo.toml`, where `x.y.z` is the version of the Thrift compiler you're using. ## API Documentation Full [Rustdoc](https://docs.rs/thrift/) ## Compatibility The Rust library and auto-generated code targets Rust versions 1.28+. It does not currently use any Rust 2021 features. ### Breaking Changes Breaking changes are minimized. When they are made they will be outlined below with transition guidelines. ##### Thrift 0.15.0 * **[THRIFT-5360]** - No longer define OR generate `description()` methods for `Error` types. `Error.description()` was soft-deprecated in 1.27, and deprecated as of 1.41. Library error types also do not implement `Error.description()`. Also, as a result of this change the generated Rust representation of an Error no longer implements the `Error.description()` method. Instead, it generates a `Display` impl with the same information. For example: ```thrift exception Xception { 1: i32 errorCode, 2: string message } ``` used to generate: ```rust use std::error::Error; use std::fmt; use std::fmt::{Display, Formatter}; // auto-generated by the Thrift compiler #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Xception { pub error_code: Option, pub message: Option, } // auto-generated by the Thrift compiler impl Error for Xception { fn description(&self) -> &str { "remote service threw Xception" } } // auto-generated by the Thrift compiler impl From for thrift::Error { fn from(e: Xception) -> Self { thrift::Error::User(Box::new(e)) } } // auto-generated by the Thrift compiler impl Display for Xception { fn fmt(&self, f: &mut Formatter) -> fmt::Result { self.description().format(f) } } ``` It *now* generates: ```rust use std::error::Error; use std::fmt; use std::fmt::{Display, Formatter}; // auto-generated by the Thrift compiler #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Xception { pub error_code: Option, pub message: Option, } // auto-generated by the Thrift compiler impl Error for Xception { } // auto-generated by the Thrift compiler impl From for thrift::Error { fn from(e: Xception) -> Self { thrift::Error::User(Box::new(e)) } } // auto-generated by the Thrift compiler impl Display for Xception { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "remote service threw Xception") } } ``` * **[THRIFT-5314]** - Generate enums implementations that are forward compatible (i.e. don't error on unknown values) As a result of this change the Rust representation of an enum changes from a standard Rust enum into a newtype struct with associated constants. For example: ```thrift // THRIFT enum Operation { ADD, SUBTRACT, MULTIPLY, DIVIDE, } ``` used to generate: ```rust // OLD AUTO-GENERATED RUST pub enum Operation { Add, Subtract, Multiply, Divide, } ``` It *now* generates: ```rust // NEW AUTO-GENERATED RUST pub struct Operation(pub i32); impl Operation { pub const ADD: Operation = Operation(0); pub const SUBTRACT: Operation = Operation(1); pub const MULTIPLY: Operation = Operation(2); pub const DIVIDE: Operation = Operation(3); } ``` ##### Thrift 0.14.0 * **[THRIFT-5158]** - Rust library and generator now support Rust 2021 only. Required rust 1.65.0 or higher The Rust `thrift` library was updated to Rust 2021 via `cargo fix --edition`. All test code in the repo was updated as well. The code generator was also updated to support Rust 2021 only. ##### Thrift 0.13.0 * **[THRIFT-4536]** - Use TryFrom from std, required rust 1.34.0 or higher Previously TryFrom was from try_from crate, it is now from the std library, but this functionality is only available in rust 1.34.0. Additionally, ordered-float is now re-exported under the thrift module to reduce possible dependency mismatches. ##### Thrift 0.12.0 * **[THRIFT-4529]** - Rust enum variants are now camel-cased instead of uppercased to conform to Rust naming conventions Previously, enum variants were uppercased in the auto-generated code. For example, the following thrift enum: ```thrift // THRIFT enum Operation { ADD, SUBTRACT, MULTIPLY, DIVIDE, } ``` used to generate: ```rust // OLD AUTO-GENERATED RUST pub enum Operation { ADD, SUBTRACT, MULTIPLY, DIVIDE, } ``` It *now* generates: ```rust // NEW AUTO-GENERATED RUST pub enum Operation { Add, Subtract, Multiply, Divide, } ``` You will have to change all enum variants in your code to use camel-cased names. This should be a search and replace. ## Contributing Bug reports and PRs are always welcome! Please see the [Thrift website](https://thrift.apache.org/) for more details. Thrift Rust support requires code in several directories: * `compiler/cpp/src/thrift/generate/t_rs_generator.cc`: binding code generator * `lib/rs`: runtime library * `lib/rs/test`: supplemental tests * `tutorial/rs`: tutorial client and server * `test/rs`: cross-language test client and server All library code, test code and auto-generated code compiles and passes clippy without warnings. All new code must do the same! When making changes ensure that: * `rustc` does does output any warnings * `clippy` with default settings does not output any warnings (includes auto-generated code) * `cargo test` is successful * `make precross` and `make check` are successful * `tutorial/bin/tutorial_client` and `tutorial/bin/tutorial_server` communicate thrift-0.23.0/lib/rs/Makefile.in0000644000175000017500000006052115170007167016623 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_TESTS_TRUE@am__append_1 = test test_recursive subdir = lib/rs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = . test test_recursive am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . $(am__append_1) EXTRA_DIST = \ src \ Cargo.toml \ README.md \ release.sh \ test/fuzz/.gitignore \ NOTICE \ LICENSE \ RELEASING.md all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/rs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/rs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am check-local clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ style-am style-local tags tags-am uninstall uninstall-am .PRECIOUS: Makefile install: @echo '##############################################################' @echo '##############################################################' @echo 'The Rust client library should be installed via a Cargo.toml dependency - please see /lib/rs/README.md' @echo '##############################################################' @echo '##############################################################' check-local: $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) test all-local: $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build clean-local: $(CARGO) clean -$(RM) Cargo.lock distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/rs/Makefile.am0000664000175000017500000000322515170007142016603 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = . if WITH_TESTS SUBDIRS += test SUBDIRS += test_recursive endif install: @echo '##############################################################' @echo '##############################################################' @echo 'The Rust client library should be installed via a Cargo.toml dependency - please see /lib/rs/README.md' @echo '##############################################################' @echo '##############################################################' check-local: $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) test all-local: $(CARGO) fmt --all -- --check $(CARGO) clippy --all -- -D warnings $(CARGO) build clean-local: $(CARGO) clean -$(RM) Cargo.lock distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ src \ Cargo.toml \ README.md \ release.sh \ test/fuzz/.gitignore \ NOTICE \ LICENSE \ RELEASING.md thrift-0.23.0/lib/Makefile.am0000664000175000017500000000374015165535636016203 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # SUBDIRS = json xml PRECROSS_TARGET = if WITH_CPP SUBDIRS += cpp endif if WITH_C_GLIB SUBDIRS += c_glib endif if WITH_JAVA SUBDIRS += java PRECROSS_TARGET += precross-java # JavaScript unit test depends on java # so test only if java, ant & co is available SUBDIRS += js endif if WITH_KOTLIN SUBDIRS += kotlin PRECROSS_TARGET += precross-kotlin endif if WITH_PYTHON SUBDIRS += py endif if WITH_ERLANG SUBDIRS += erl endif if WITH_RUBY SUBDIRS += rb endif if WITH_PERL SUBDIRS += perl endif if WITH_PHP SUBDIRS += php endif if WITH_DART SUBDIRS += dart endif if WITH_DOTNET SUBDIRS += netstd endif if WITH_GO SUBDIRS += go endif if WITH_D SUBDIRS += d PRECROSS_TARGET += precross-d endif if WITH_NODEJS SUBDIRS += nodejs PRECROSS_TARGET += precross-nodejs SUBDIRS += nodets endif if WITH_LUA SUBDIRS += lua endif if WITH_RS SUBDIRS += rs endif if WITH_CL SUBDIRS += cl endif if WITH_SWIFT SUBDIRS += swift endif # All of the libs that don't use Automake need to go in here # so they will end up in our release tarballs. distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ d \ dart \ delphi \ haxe \ javame \ js \ ocaml \ st \ ts precross-%: $(MAKE) -C $* precross precross: $(PRECROSS_TARGET) thrift-0.23.0/lib/d/0000775000175000017500000000000015170007175014352 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/0000775000175000017500000000000015165535636015155 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/0000775000175000017500000000000015170007142016433 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/internal/0000775000175000017500000000000015165535636020271 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/internal/resource_pool.d0000664000175000017500000002643215165535636023325 0ustar00buildbuild00000000000000/* * 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. */ module thrift.internal.resource_pool; import core.time : Duration, dur, TickDuration; import std.algorithm : minPos, reduce, remove; import std.array : array, empty; import std.exception : enforce; import std.conv : to; import std.random : randomCover, rndGen; import std.range : zip; import thrift.internal.algorithm : removeEqual; /** * A pool of resources, which can be iterated over, and where resources that * have failed too often can be temporarily disabled. * * This class is oblivious to the actual resource type managed. */ final class TResourcePool(Resource) { /** * Constructs a new instance. * * Params: * resources = The initial members of the pool. */ this(Resource[] resources) { resources_ = resources; } /** * Adds a resource to the pool. */ void add(Resource resource) { resources_ ~= resource; } /** * Removes a resource from the pool. * * Returns: Whether the resource could be found in the pool. */ bool remove(Resource resource) { auto oldLength = resources_.length; resources_ = removeEqual(resources_, resource); return resources_.length < oldLength; } /** * Returns an »enriched« input range to iterate over the pool members. */ static struct Range { /** * Whether the range is empty. * * This is the case if all members of the pool have been popped (or skipped * because they were disabled) and TResourcePool.cycle is false, or there * is no element to return in cycle mode because all have been temporarily * disabled. */ bool empty() @property { // If no resources are in the pool, the range will never become non-empty. if (resources_.empty) return true; // If we already got the next resource in the cache, it doesn't matter // whether there are more. if (cached_) return false; size_t examineCount; if (parent_.cycle) { // We want to check all the resources, but not iterate more than once // to avoid spinning in a loop if nothing is available. examineCount = resources_.length; } else { // When not in cycle mode, we just iterate the list exactly once. If all // items have been consumed, the interval below is empty. examineCount = resources_.length - nextIndex_; } foreach (i; 0 .. examineCount) { auto r = resources_[(nextIndex_ + i) % resources_.length]; auto fi = r in parent_.faultInfos_; if (fi && fi.resetTime != fi.resetTime.init) { if (fi.resetTime < parent_.getCurrentTick_()) { // The timeout expired, remove the resource from the list and go // ahead trying it. parent_.faultInfos_.remove(r); } else { // The timeout didn't expire yet, try the next resource. continue; } } cache_ = r; cached_ = true; nextIndex_ = nextIndex_ + i + 1; return false; } // If we get here, all resources are currently inactive or the non-cycle // pool has been exhausted, so there is nothing we can do. nextIndex_ = nextIndex_ + examineCount; return true; } /** * Returns the first resource in the range. */ Resource front() @property { enforce(!empty); return cache_; } /** * Removes the first resource from the range. * * Usually, this is combined with a call to TResourcePool.recordSuccess() * or recordFault(). */ void popFront() { enforce(!empty); cached_ = false; } /** * Returns whether the range will become non-empty at some point in the * future, and provides additional information when this will happen and * what will be the next resource. * * Makes only sense to call on empty ranges. * * Params: * next = The next resource that will become available. * waitTime = The duration until that resource will become available. */ bool willBecomeNonempty(out Resource next, out Duration waitTime) { // If no resources are in the pool, the range will never become non-empty. if (resources_.empty) return false; // If cycle mode is not enabled, a range never becomes non-empty after // being empty once, because all the elements have already been // used/skipped in order to become empty. if (!parent_.cycle) return false; auto fi = parent_.faultInfos_; auto nextPair = minPos!"a[1].resetTime < b[1].resetTime"( zip(fi.keys, fi.values) ).front; next = nextPair[0]; waitTime = to!Duration(nextPair[1].resetTime - parent_.getCurrentTick_()); return true; } private: this(TResourcePool parent, Resource[] resources) { parent_ = parent; resources_ = resources; } TResourcePool parent_; /// All available resources. We keep a copy of it as to not get confused /// when resources are added to/removed from the parent pool. Resource[] resources_; /// After we have determined the next element in empty(), we store it here. Resource cache_; /// Whether there is currently something in the cache. bool cached_; /// The index to start searching from at the next call to empty(). size_t nextIndex_; } /// Ditto Range opSlice() { auto res = resources_; if (permute) { res = array(randomCover(res, rndGen)); } return Range(this, res); } /** * Records a success for an operation on the given resource, cancelling a * fault streak, if any. */ void recordSuccess(Resource resource) { if (resource in faultInfos_) { faultInfos_.remove(resource); } } /** * Records a fault for the given resource. * * If a resource fails consecutively for more than faultDisableCount times, * it is temporarily disabled (no longer considered) until * faultDisableDuration has passed. */ void recordFault(Resource resource) { auto fi = resource in faultInfos_; if (!fi) { faultInfos_[resource] = FaultInfo(); fi = resource in faultInfos_; } ++fi.count; if (fi.count >= faultDisableCount) { // If the resource has hit the fault count limit, disable it for // specified duration. fi.resetTime = getCurrentTick_() + cast(TickDuration)faultDisableDuration; } } /** * Whether to randomly permute the order of the resources in the pool when * taking a range using opSlice(). * * This can be used e.g. as a simple form of load balancing. */ bool permute = true; /** * Whether to keep iterating over the pool members after all have been * returned/have failed once. */ bool cycle = false; /** * The number of consecutive faults after which a resource is disabled until * faultDisableDuration has passed. Zero to never disable resources. * * Defaults to zero. */ ushort faultDisableCount = 0; /** * The duration for which a resource is no longer considered after it has * failed too often. * * Defaults to one second. */ Duration faultDisableDuration = dur!"seconds"(1); private: Resource[] resources_; FaultInfo[Resource] faultInfos_; /// Function to get the current timestamp from some monotonic system clock. /// /// This is overridable to be able to write timing-insensitive unit tests. /// The extra indirection should not matter much performance-wise compared to /// the actual system call, and by its very nature thisshould not be on a hot /// path anyway. typeof(&TickDuration.currSystemTick) getCurrentTick_ = &TickDuration.currSystemTick; } private { struct FaultInfo { ushort count; TickDuration resetTime; } } unittest { auto pool = new TResourcePool!Object([]); enforce(pool[].empty); Object dummyRes; Duration dummyDur; enforce(!pool[].willBecomeNonempty(dummyRes, dummyDur)); } unittest { import std.datetime; import thrift.base; auto a = new Object; auto b = new Object; auto c = new Object; auto objs = [a, b, c]; auto pool = new TResourcePool!Object(objs); pool.permute = false; static Duration fakeClock; pool.getCurrentTick_ = () => cast(TickDuration)fakeClock; Object dummyRes = void; Duration dummyDur = void; { auto r = pool[]; foreach (i, o; objs) { enforce(!r.empty); enforce(r.front == o); r.popFront(); } enforce(r.empty); enforce(!r.willBecomeNonempty(dummyRes, dummyDur)); } { pool.faultDisableCount = 2; enforce(pool[].front == a); pool.recordFault(a); enforce(pool[].front == a); pool.recordSuccess(a); enforce(pool[].front == a); pool.recordFault(a); enforce(pool[].front == a); pool.recordFault(a); auto r = pool[]; enforce(r.front == b); r.popFront(); enforce(r.front == c); r.popFront(); enforce(r.empty); enforce(!r.willBecomeNonempty(dummyRes, dummyDur)); fakeClock += 2.seconds; // Not in cycle mode, has to be still empty after the timeouts expired. enforce(r.empty); enforce(!r.willBecomeNonempty(dummyRes, dummyDur)); foreach (o; objs) pool.recordSuccess(o); } { pool.faultDisableCount = 1; pool.recordFault(a); pool.recordFault(b); pool.recordFault(c); auto r = pool[]; enforce(r.empty); enforce(!r.willBecomeNonempty(dummyRes, dummyDur)); foreach (o; objs) pool.recordSuccess(o); } pool.cycle = true; { auto r = pool[]; foreach (o; objs ~ objs) { enforce(!r.empty); enforce(r.front == o); r.popFront(); } } { pool.faultDisableCount = 2; enforce(pool[].front == a); pool.recordFault(a); enforce(pool[].front == a); pool.recordSuccess(a); enforce(pool[].front == a); pool.recordFault(a); enforce(pool[].front == a); pool.recordFault(a); auto r = pool[]; enforce(r.front == b); r.popFront(); enforce(r.front == c); r.popFront(); enforce(r.front == b); fakeClock += 2.seconds; r.popFront(); enforce(r.front == c); r.popFront(); enforce(r.front == a); enforce(pool[].front == a); foreach (o; objs) pool.recordSuccess(o); } { pool.faultDisableCount = 1; pool.recordFault(a); fakeClock += 1.msecs; pool.recordFault(b); fakeClock += 1.msecs; pool.recordFault(c); auto r = pool[]; enforce(r.empty); // Make sure willBecomeNonempty gets the order right. enforce(r.willBecomeNonempty(dummyRes, dummyDur)); enforce(dummyRes == a); enforce(dummyDur > Duration.zero); foreach (o; objs) pool.recordSuccess(o); } } thrift-0.23.0/lib/d/src/thrift/internal/ctfe.d0000664000175000017500000000526115165535636021363 0ustar00buildbuild00000000000000/* * 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. */ module thrift.internal.ctfe; import std.conv : to; import std.traits; /* * Simple eager join() for strings, std.algorithm.join isn't CTFEable yet. */ string ctfeJoin(string[] strings, string separator = ", ") { string result; if (strings.length > 0) { result ~= strings[0]; foreach (s; strings[1..$]) { result ~= separator ~ s; } } return result; } /* * A very primitive to!string() implementation for floating point numbers that * is evaluatable at compile time. * * There is a wealth of problems associated with the algorithm used (e.g. 5.0 * prints as 4.999…, incorrect rounding, etc.), but a better alternative should * be included with the D standard library instead of implementing it here. */ string ctfeToString(T)(T val) if (isFloatingPoint!T) { if (val is T.nan) return "nan"; if (val is T.infinity) return "inf"; if (val is -T.infinity) return "-inf"; if (val is 0.0) return "0"; if (val is -0.0) return "-0"; auto b = val; string result; if (b < 0) { result ~= '-'; b *= -1; } short magnitude; while (b >= 10) { ++magnitude; b /= 10; } while (b < 1) { --magnitude; b *= 10; } foreach (i; 0 .. T.dig) { if (i == 1) result ~= '.'; auto first = cast(ubyte)b; result ~= to!string(first); b -= first; import std.math; if (b < pow(10.0, i - T.dig)) break; b *= 10; } if (magnitude != 0) result ~= "e" ~ to!string(magnitude); return result; } unittest { import std.algorithm; static assert(ctfeToString(double.infinity) == "inf"); static assert(ctfeToString(-double.infinity) == "-inf"); static assert(ctfeToString(double.nan) == "nan"); static assert(ctfeToString(0.0) == "0"); static assert(ctfeToString(-0.0) == "-0"); static assert(ctfeToString(2.5) == "2.5"); static assert(ctfeToString(3.1415).startsWith("3.141")); static assert(ctfeToString(2e-200) == "2e-200"); } thrift-0.23.0/lib/d/src/thrift/internal/socket.d0000664000175000017500000000641715165535636021736 0ustar00buildbuild00000000000000/* * 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. */ /** * Abstractions over OS-dependent socket functionality. */ module thrift.internal.socket; import std.conv : to; // FreeBSD and OS X return -1 and set ECONNRESET if socket was closed by // the other side, we need to check for that before throwing an exception. version (FreeBSD) { enum connresetOnPeerShutdown = true; } else version (OSX) { enum connresetOnPeerShutdown = true; } else { enum connresetOnPeerShutdown = false; } version (Windows) { import core.sys.windows.winsock2 : WSAGetLastError, WSAEINTR, WSAEWOULDBLOCK; import std.windows.syserror : sysErrorString; // These are unfortunately not defined in std.c.windows.winsock, see // http://msdn.microsoft.com/en-us/library/ms740668.aspx. enum WSAECONNRESET = 10054; enum WSAENOTCONN = 10057; enum WSAETIMEDOUT = 10060; } else { import core.stdc.errno : errno, EAGAIN, ECONNRESET, EINPROGRESS, EINTR, ENOTCONN, EPIPE; import core.stdc.string : strerror; } /* * CONNECT_INPROGRESS_ERRNO: set by connect() for non-blocking sockets if the * connection could not be immediately established. * INTERRUPTED_ERRNO: set when blocking system calls are interrupted by * signals or similar. * TIMEOUT_ERRNO: set when a socket timeout has been exceeded. * WOULD_BLOCK_ERRNO: set when send/recv would block on non-blocking sockets. * * isSocetCloseErrno(errno): returns true if errno indicates that the socket * is logically in closed state now. */ version (Windows) { alias WSAGetLastError getSocketErrno; enum CONNECT_INPROGRESS_ERRNO = WSAEWOULDBLOCK; enum INTERRUPTED_ERRNO = WSAEINTR; enum TIMEOUT_ERRNO = WSAETIMEDOUT; enum WOULD_BLOCK_ERRNO = WSAEWOULDBLOCK; bool isSocketCloseErrno(typeof(getSocketErrno()) errno) { return (errno == WSAECONNRESET || errno == WSAENOTCONN); } } else { alias errno getSocketErrno; enum CONNECT_INPROGRESS_ERRNO = EINPROGRESS; enum INTERRUPTED_ERRNO = EINTR; enum WOULD_BLOCK_ERRNO = EAGAIN; // TODO: The C++ TSocket implementation mentions that EAGAIN can also be // set (undocumentedly) in out of resource conditions; it would be a good // idea to contact the original authors of the C++ code for details and adapt // the code accordingly. enum TIMEOUT_ERRNO = EAGAIN; bool isSocketCloseErrno(typeof(getSocketErrno()) errno) { return (errno == EPIPE || errno == ECONNRESET || errno == ENOTCONN); } } string socketErrnoString(uint errno) { version (Windows) { return sysErrorString(errno); } else { return to!string(strerror(errno)); } } thrift-0.23.0/lib/d/src/thrift/internal/traits.d0000664000175000017500000000245615165535636021753 0ustar00buildbuild00000000000000/* * 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. */ module thrift.internal.traits; import std.traits; /** * Adds »nothrow« to the type of the passed function pointer/delegate, if it * is not already present. * * Technically, assumeNothrow just performs a cast, but using it has the * advantage of being explicitly about the operation that is performed. */ auto assumeNothrow(T)(T t) if (isFunctionPointer!T || isDelegate!T) { enum attrs = functionAttributes!T | FunctionAttribute.nothrow_; return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; } thrift-0.23.0/lib/d/src/thrift/internal/endian.d0000664000175000017500000000417415165535636021702 0ustar00buildbuild00000000000000/* * 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. */ /* * Simple helpers for handling typical byte order-related issues. */ module thrift.internal.endian; import core.bitop : bswap; import std.traits : isIntegral; union IntBuf(T) { ubyte[T.sizeof] bytes; T value; } T byteSwap(T)(T t) pure nothrow @trusted if (isIntegral!T) { static if (T.sizeof == 2) { return cast(T)((t & 0xff) << 8) | cast(T)((t & 0xff00) >> 8); } else static if (T.sizeof == 4) { return cast(T)bswap(cast(uint)t); } else static if (T.sizeof == 8) { return cast(T)byteSwap(cast(uint)(t & 0xffffffff)) << 32 | cast(T)bswap(cast(uint)(t >> 32)); } else static assert(false, "Type of size " ~ to!string(T.sizeof) ~ " not supported."); } T doNothing(T)(T val) { return val; } version (BigEndian) { alias doNothing hostToNet; alias doNothing netToHost; alias byteSwap hostToLe; alias byteSwap leToHost; } else { alias byteSwap hostToNet; alias byteSwap netToHost; alias doNothing hostToLe; alias doNothing leToHost; } unittest { import std.exception; IntBuf!short s; s.bytes = [1, 2]; s.value = byteSwap(s.value); enforce(s.bytes == [2, 1]); IntBuf!int i; i.bytes = [1, 2, 3, 4]; i.value = byteSwap(i.value); enforce(i.bytes == [4, 3, 2, 1]); IntBuf!long l; l.bytes = [1, 2, 3, 4, 5, 6, 7, 8]; l.value = byteSwap(l.value); enforce(l.bytes == [8, 7, 6, 5, 4, 3, 2, 1]); } thrift-0.23.0/lib/d/src/thrift/internal/test/0000775000175000017500000000000015165535636021250 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/internal/test/server.d0000664000175000017500000000707515165535636022734 0ustar00buildbuild00000000000000/* * 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. */ module thrift.internal.test.server; import core.sync.condition; import core.sync.mutex; import core.thread : Thread; import std.datetime; import std.exception : enforce; import std.typecons : WhiteHole; import std.variant : Variant; import thrift.protocol.base; import thrift.protocol.binary; import thrift.protocol.processor; import thrift.server.base; import thrift.server.transport.socket; import thrift.transport.base; import thrift.util.cancellation; version(unittest): /** * Tests if serving is stopped correctly if the cancellation passed to serve() * is triggered. * * Because the tests are run many times in a loop, this is indirectly also a * test whether socket, etc. handles are cleaned up correctly, because the * application will likely run out of handles otherwise. */ void testServeCancel(Server)(void delegate(Server) serverSetup = null) if ( is(Server : TServer) ) { auto proc = new WhiteHole!TProcessor; auto tf = new TTransportFactory; auto pf = new TBinaryProtocolFactory!(); // Need a special case for TNonblockingServer which doesn't use // TServerTransport. static if (__traits(compiles, new Server(proc, 0, tf, pf))) { auto server = new Server(proc, 0, tf, pf); } else { auto server = new Server(proc, new TServerSocket(0), tf, pf); } // On Windows, we use TCP sockets to replace socketpair(). Since they stay // in TIME_WAIT for some time even if they are properly closed, we have to use // a lower number of iterations to avoid running out of ports/buffer space. version (Windows) { enum ITERATIONS = 100; } else { enum ITERATIONS = 10000; } if (serverSetup) serverSetup(server); auto servingMutex = new Mutex; auto servingCondition = new Condition(servingMutex); auto doneMutex = new Mutex; auto doneCondition = new Condition(doneMutex); class CancellingHandler : TServerEventHandler { void preServe() { synchronized (servingMutex) { servingCondition.notifyAll(); } } Variant createContext(TProtocol input, TProtocol output) { return Variant.init; } void deleteContext(Variant serverContext, TProtocol input, TProtocol output) {} void preProcess(Variant serverContext, TTransport transport) {} } server.eventHandler = new CancellingHandler; foreach (i; 0 .. ITERATIONS) { synchronized (servingMutex) { auto cancel = new TCancellationOrigin; synchronized (doneMutex) { auto serverThread = new Thread({ server.serve(cancel); synchronized (doneMutex) { doneCondition.notifyAll(); } }); serverThread.isDaemon = true; serverThread.start(); servingCondition.wait(); cancel.trigger(); enforce(doneCondition.wait(dur!"msecs"(3*1000))); serverThread.join(); } } } } thrift-0.23.0/lib/d/src/thrift/internal/test/protocol.d0000664000175000017500000001152715165535636023264 0ustar00buildbuild00000000000000/* * 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. */ module thrift.internal.test.protocol; import std.exception; import thrift.transport.memory; import thrift.protocol.base; version (unittest): void testContainerSizeLimit(Protocol)() if (isTProtocol!Protocol) { auto buffer = new TMemoryBuffer; auto prot = new Protocol(buffer); // Make sure reading fails if a container larger than the size limit is read. prot.containerSizeLimit = 3; { prot.writeListBegin(TList(TType.I32, 4)); prot.writeI32(0); // Make sure size can be read e.g. for JSON protocol. prot.reset(); auto e = cast(TProtocolException)collectException(prot.readListBegin()); enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT); prot.reset(); buffer.reset(); } { prot.writeMapBegin(TMap(TType.I32, TType.I32, 4)); prot.writeI32(0); // Make sure size can be read e.g. for JSON protocol. prot.reset(); auto e = cast(TProtocolException)collectException(prot.readMapBegin()); enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT); prot.reset(); buffer.reset(); } { prot.writeSetBegin(TSet(TType.I32, 4)); prot.writeI32(0); // Make sure size can be read e.g. for JSON protocol. prot.reset(); auto e = cast(TProtocolException)collectException(prot.readSetBegin()); enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT); prot.reset(); buffer.reset(); } // Make sure reading works if the containers are smaller than the limit or // no limit is set. foreach (limit; [3, 0, -1]) { prot.containerSizeLimit = limit; { prot.writeListBegin(TList(TType.I32, 2)); prot.writeI32(0); prot.writeI32(1); prot.writeListEnd(); prot.reset(); auto list = prot.readListBegin(); enforce(list.elemType == TType.I32); enforce(list.size == 2); enforce(prot.readI32() == 0); enforce(prot.readI32() == 1); prot.readListEnd(); prot.reset(); buffer.reset(); } { prot.writeMapBegin(TMap(TType.I32, TType.I32, 2)); prot.writeI32(0); prot.writeI32(1); prot.writeI32(2); prot.writeI32(3); prot.writeMapEnd(); prot.reset(); auto map = prot.readMapBegin(); enforce(map.keyType == TType.I32); enforce(map.valueType == TType.I32); enforce(map.size == 2); enforce(prot.readI32() == 0); enforce(prot.readI32() == 1); enforce(prot.readI32() == 2); enforce(prot.readI32() == 3); prot.readMapEnd(); prot.reset(); buffer.reset(); } { prot.writeSetBegin(TSet(TType.I32, 2)); prot.writeI32(0); prot.writeI32(1); prot.writeSetEnd(); prot.reset(); auto set = prot.readSetBegin(); enforce(set.elemType == TType.I32); enforce(set.size == 2); enforce(prot.readI32() == 0); enforce(prot.readI32() == 1); prot.readSetEnd(); prot.reset(); buffer.reset(); } } } void testStringSizeLimit(Protocol)() if (isTProtocol!Protocol) { auto buffer = new TMemoryBuffer; auto prot = new Protocol(buffer); // Make sure reading fails if a string larger than the size limit is read. prot.stringSizeLimit = 3; { prot.writeString("asdf"); prot.reset(); auto e = cast(TProtocolException)collectException(prot.readString()); enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT); prot.reset(); buffer.reset(); } { prot.writeBinary([1, 2, 3, 4]); prot.reset(); auto e = cast(TProtocolException)collectException(prot.readBinary()); enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT); prot.reset(); buffer.reset(); } // Make sure reading works if the containers are smaller than the limit or // no limit is set. foreach (limit; [3, 0, -1]) { prot.containerSizeLimit = limit; { prot.writeString("as"); prot.reset(); enforce(prot.readString() == "as"); prot.reset(); buffer.reset(); } { prot.writeBinary([1, 2]); prot.reset(); enforce(prot.readBinary() == [1, 2]); prot.reset(); buffer.reset(); } } } thrift-0.23.0/lib/d/src/thrift/internal/ssl.d0000664000175000017500000001712615165535636021246 0ustar00buildbuild00000000000000/* * 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. */ module thrift.internal.ssl; import core.memory : GC; import core.stdc.config; import core.stdc.errno : errno; import core.stdc.string : strerror; import deimos.openssl.err; import deimos.openssl.ssl; import deimos.openssl.x509v3; import std.array : empty, appender; import std.conv : to; import std.socket : Address; import thrift.transport.ssl; /** * Checks if the peer is authorized after the SSL handshake has been * completed on the given conncetion and throws an TSSLException if not. * * Params: * ssl = The SSL connection to check. * accessManager = The access manager to check the peer againts. * peerAddress = The (IP) address of the peer. * hostName = The host name of the peer. */ void authorize(SSL* ssl, TAccessManager accessManager, Address peerAddress, lazy string hostName ) { alias TAccessManager.Decision Decision; auto rc = SSL_get_verify_result(ssl); if (rc != X509_V_OK) { throw new TSSLException("SSL_get_verify_result(): " ~ to!string(X509_verify_cert_error_string(rc))); } auto cert = SSL_get_peer_certificate(ssl); if (cert is null) { // Certificate is not present. if (SSL_get_verify_mode(ssl) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { throw new TSSLException( "Authorize: Required certificate not present."); } // If we don't have an access manager set, we don't intend to authorize // the client, so everything's fine. if (accessManager) { throw new TSSLException( "Authorize: Certificate required for authorization."); } return; } if (accessManager is null) { // No access manager set, can return immediately as the cert is valid // and all peers are authorized. X509_free(cert); return; } // both certificate and access manager are present auto decision = accessManager.verify(peerAddress); if (decision != Decision.SKIP) { X509_free(cert); if (decision != Decision.ALLOW) { throw new TSSLException("Authorize: Access denied based on remote IP."); } return; } // Check subjectAltName(s), if present. auto alternatives = cast(STACK_OF!(GENERAL_NAME)*) X509_get_ext_d2i(cert, NID_subject_alt_name, null, null); version(use_openssl_1_0_x) { enum _GEN_DNS = GENERAL_NAME.GEN_DNS; enum _GEN_IPADD = GENERAL_NAME.GEN_IPADD; } else version(use_openssl_1_1_x) { enum _GEN_DNS = GEN_DNS; enum _GEN_IPADD = GEN_IPADD; } else { static assert(false, `Must have version either use_openssl_1_0_x or use_openssl_1_1_x defined, e.g. "subConfigurations": { "apache-thrift": "use_openssl_1_0" }`); } if (alternatives != null) { auto count = sk_GENERAL_NAME_num(alternatives); for (int i = 0; decision == Decision.SKIP && i < count; i++) { auto name = sk_GENERAL_NAME_value(alternatives, i); if (name is null) { continue; } auto data = ASN1_STRING_data(name.d.ia5); auto length = ASN1_STRING_length(name.d.ia5); switch (name.type) { case _GEN_DNS: decision = accessManager.verify(hostName, cast(char[])data[0 .. length]); break; case _GEN_IPADD: decision = accessManager.verify(peerAddress, data[0 .. length]); break; default: // Do nothing. } } // DMD @@BUG@@: Empty template arguments parens should not be needed. sk_GENERAL_NAME_pop_free!()(alternatives, &GENERAL_NAME_free); } // If we are alredy done, return. if (decision != Decision.SKIP) { X509_free(cert); if (decision != Decision.ALLOW) { throw new TSSLException("Authorize: Access denied."); } return; } // Check commonName. auto name = X509_get_subject_name(cert); if (name !is null) { X509_NAME_ENTRY* entry; char* utf8; int last = -1; while (decision == Decision.SKIP) { last = X509_NAME_get_index_by_NID(name, NID_commonName, last); if (last == -1) break; entry = X509_NAME_get_entry(name, last); if (entry is null) continue; auto common = X509_NAME_ENTRY_get_data(entry); auto size = ASN1_STRING_to_UTF8(&utf8, common); decision = accessManager.verify(hostName, utf8[0 .. size]); CRYPTO_free(utf8); } } X509_free(cert); if (decision != Decision.ALLOW) { throw new TSSLException("Authorize: Could not authorize peer."); } } /* * OpenSSL error information used for storing D exceptions on the OpenSSL * error stack. */ enum ERR_LIB_D_EXCEPTION = ERR_LIB_USER; enum ERR_F_D_EXCEPTION = 0; // function id - what to use here? enum ERR_R_D_EXCEPTION = 1234; // 99 and above are reserved for applications enum ERR_FILE_D_EXCEPTION = "d_exception"; enum ERR_LINE_D_EXCEPTION = 0; enum ERR_FLAGS_D_EXCEPTION = 0; /** * Returns an exception for the last. * * Params: * location = An optional "location" to add to the error message (typically * the last SSL API call). */ Exception getSSLException(string location = null, string clientFile = __FILE__, size_t clientLine = __LINE__ ) { // We can return either an exception saved from D BIO code, or a "true" // OpenSSL error. Because there can possibly be more than one error on the // error stack, we have to fetch all of them, and pick the last, i.e. newest // one. We concatenate multiple successive OpenSSL error messages into a // single one, but always just return the last D expcetion. string message; // Probably better use an Appender here. bool hadMessage; Exception exception; void initMessage() { message.destroy(); hadMessage = false; if (!location.empty) { message ~= location; message ~= ": "; } } initMessage(); auto errn = errno; const(char)* file = void; int line = void; const(char)* data = void; int flags = void; c_ulong code = void; while ((code = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { if (ERR_GET_REASON(code) == ERR_R_D_EXCEPTION) { initMessage(); GC.removeRoot(cast(void*)data); exception = cast(Exception)data; } else { exception = null; if (hadMessage) { message ~= ", "; } auto reason = ERR_reason_error_string(code); if (reason) { message ~= "SSL error: " ~ to!string(reason); } else { message ~= "SSL error #" ~ to!string(code); } hadMessage = true; } } // If the last item from the stack was a D exception, throw it. if (exception) return exception; // We are dealing with an OpenSSL error that doesn't root in a D exception. if (!hadMessage) { // If we didn't get an actual error from the stack yet, try errno. string errnString; if (errn != 0) { errnString = to!string(strerror(errn)); } if (errnString.empty) { message ~= "Unknown error"; } else { message ~= errnString; } } message ~= "."; return new TSSLException(message, clientFile, clientLine); } thrift-0.23.0/lib/d/src/thrift/internal/codegen.d0000664000175000017500000003120015165535636022036 0ustar00buildbuild00000000000000/* * 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. */ module thrift.internal.codegen; import std.algorithm : canFind; import std.traits : InterfacesTuple, isSomeFunction, isSomeString; import std.typetuple : staticIndexOf, staticMap, NoDuplicates, TypeTuple; import thrift.codegen.base; /** * Removes all type qualifiers from T. * * In contrast to std.traits.Unqual, FullyUnqual also removes qualifiers from * array elements (e.g. immutable(byte[]) -> byte[], not immutable(byte)[]), * excluding strings (string isn't reduced to char[]). */ template FullyUnqual(T) { static if (is(T _ == const(U), U)) { alias FullyUnqual!U FullyUnqual; } else static if (is(T _ == immutable(U), U)) { alias FullyUnqual!U FullyUnqual; } else static if (is(T _ == shared(U), U)) { alias FullyUnqual!U FullyUnqual; } else static if (is(T _ == U[], U) && !isSomeString!T) { alias FullyUnqual!(U)[] FullyUnqual; } else static if (is(T _ == V[K], K, V)) { alias FullyUnqual!(V)[FullyUnqual!K] FullyUnqual; } else { alias T FullyUnqual; } } /** * true if null can be assigned to the passed type, false if not. */ template isNullable(T) { enum isNullable = __traits(compiles, { T t = null; }); } template isStruct(T) { enum isStruct = is(T == struct); } template isException(T) { enum isException = is(T : Exception); } template isEnum(T) { enum isEnum = is(T == enum); } /** * Aliases itself to T.name. */ template GetMember(T, string name) { mixin("alias T." ~ name ~ " GetMember;"); } /** * Aliases itself to typeof(symbol). */ template TypeOf(alias symbol) { alias typeof(symbol) TypeOf; } /** * Aliases itself to the type of the T member called name. */ alias Compose!(TypeOf, GetMember) MemberType; /** * Returns the field metadata array for T if any, or an empty array otherwise. */ template getFieldMeta(T) if (isStruct!T || isException!T) { static if (is(typeof(T.fieldMeta) == TFieldMeta[])) { enum getFieldMeta = T.fieldMeta; } else { enum TFieldMeta[] getFieldMeta = []; } } /** * Merges the field metadata array for D with the passed array. */ template mergeFieldMeta(T, alias fieldMetaData = cast(TFieldMeta[])null) { // Note: We don't use getFieldMeta here to avoid bug if it is instantiated // from TIsSetFlags, see comment there. static if (is(typeof(T.fieldMeta) == TFieldMeta[])) { enum mergeFieldMeta = T.fieldMeta ~ fieldMetaData; } else { enum TFieldMeta[] mergeFieldMeta = fieldMetaData; } } /** * Returns the field requirement level for T.name. */ template memberReq(T, string name, alias fieldMetaData = cast(TFieldMeta[])null) { enum memberReq = memberReqImpl!(T, name, fieldMetaData).result; } private { import std.algorithm : find; // DMD @@BUG@@: Missing import leads to failing build without error // message in unittest/debug/thrift/codegen/async_client. import std.array : empty, front; template memberReqImpl(T, string name, alias fieldMetaData) { enum meta = find!`a.name == b`(mergeFieldMeta!(T, fieldMetaData), name); static if (meta.empty || meta.front.req == TReq.AUTO) { static if (isNullable!(MemberType!(T, name))) { enum result = TReq.OPTIONAL; } else { enum result = TReq.REQUIRED; } } else { enum result = meta.front.req; } } } template notIgnored(T, string name, alias fieldMetaData = cast(TFieldMeta[])null) { enum notIgnored = memberReq!(T, name, fieldMetaData) != TReq.IGNORE; } /** * Returns the method metadata array for T if any, or an empty array otherwise. */ template getMethodMeta(T) if (isService!T) { static if (is(typeof(T.methodMeta) == TMethodMeta[])) { enum getMethodMeta = T.methodMeta; } else { enum TMethodMeta[] getMethodMeta = []; } } /** * true if T.name is a member variable. Exceptions include methods, static * members, artifacts like package aliases, … */ template isValueMember(T, string name) { static if (!is(MemberType!(T, name))) { enum isValueMember = false; } else static if ( is(MemberType!(T, name) == void) || isSomeFunction!(MemberType!(T, name)) || __traits(compiles, { return mixin("T." ~ name); }()) ) { enum isValueMember = false; } else { enum isValueMember = true; } } /** * Returns a tuple containing the names of the fields of T, not including * inherited fields. If a member is marked as TReq.IGNORE, it is not included * as well. */ template FieldNames(T, alias fieldMetaData = cast(TFieldMeta[])null) { alias StaticFilter!( All!( doesNotReadMembers, PApply!(isValueMember, T), PApply!(notIgnored, T, PApplySkip, fieldMetaData) ), __traits(derivedMembers, T) ) FieldNames; } /* * true if the passed member name is not a method generated by the * TStructHelpers template that in its implementations queries the struct * members. * * Kludge used internally to break a cycle caused a DMD forward reference * regression, see THRIFT-2130. */ enum doesNotReadMembers(string name) = !["opEquals", "thriftOpEqualsImpl", "toString", "thriftToStringImpl"].canFind(name); template derivedMembers(T) { alias TypeTuple!(__traits(derivedMembers, T)) derivedMembers; } template AllMemberMethodNames(T) if (isService!T) { alias NoDuplicates!( FilterMethodNames!( T, staticMap!( derivedMembers, TypeTuple!(T, InterfacesTuple!T) ) ) ) AllMemberMethodNames; } template FilterMethodNames(T, MemberNames...) { alias StaticFilter!( CompilesAndTrue!( Compose!(isSomeFunction, TypeOf, PApply!(GetMember, T)) ), MemberNames ) FilterMethodNames; } /** * Returns a type tuple containing only the elements of T for which the * eponymous template predicate pred is true. * * Example: * --- * alias StaticFilter!(isIntegral, int, string, long, float[]) Filtered; * static assert(is(Filtered == TypeTuple!(int, long))); * --- */ template StaticFilter(alias pred, T...) { static if (T.length == 0) { alias TypeTuple!() StaticFilter; } else static if (pred!(T[0])) { alias TypeTuple!(T[0], StaticFilter!(pred, T[1 .. $])) StaticFilter; } else { alias StaticFilter!(pred, T[1 .. $]) StaticFilter; } } /** * Binds the first n arguments of a template to a particular value (where n is * the number of arguments passed to PApply). * * The passed arguments are always applied starting from the left. However, * the special PApplySkip marker template can be used to indicate that an * argument should be skipped, so that e.g. the first and third argument * to a template can be fixed, but the second and remaining arguments would * still be left undefined. * * Skipping a number of parameters, but not providing enough arguments to * assign all of them during instantiation of the resulting template is an * error. * * Example: * --- * struct Foo(T, U, V) {} * alias PApply!(Foo, int, long) PartialFoo; * static assert(is(PartialFoo!float == Foo!(int, long, float))); * * alias PApply!(Test, int, PApplySkip, float) SkippedTest; * static assert(is(SkippedTest!long == Test!(int, long, float))); * --- */ template PApply(alias Target, T...) { template PApply(U...) { alias Target!(PApplyMergeArgs!(ConfinedTuple!T, U).Result) PApply; } } /// Ditto. template PApplySkip() {} private template PApplyMergeArgs(alias Preset, Args...) { static if (Preset.length == 0) { alias Args Result; } else { enum nextSkip = staticIndexOf!(PApplySkip, Preset.Tuple); static if (nextSkip == -1) { alias TypeTuple!(Preset.Tuple, Args) Result; } else static if (Args.length == 0) { // Have to use a static if clause instead of putting the condition // directly into the assert to avoid DMD trying to access Args[0] // nevertheless below. static assert(false, "PArgsSkip encountered, but no argument left to bind."); } else { alias TypeTuple!( Preset.Tuple[0 .. nextSkip], Args[0], PApplyMergeArgs!( ConfinedTuple!(Preset.Tuple[nextSkip + 1 .. $]), Args[1 .. $] ).Result ) Result; } } } unittest { struct Test(T, U, V) {} alias PApply!(Test, int, long) PartialTest; static assert(is(PartialTest!float == Test!(int, long, float))); alias PApply!(Test, int, PApplySkip, float) SkippedTest; static assert(is(SkippedTest!long == Test!(int, long, float))); alias PApply!(Test, int, PApplySkip, PApplySkip) TwoSkipped; static assert(!__traits(compiles, TwoSkipped!long)); } /** * Composes a number of templates. The result is a template equivalent to * all the passed templates evaluated from right to left, akin to the * mathematical function composition notation: Instantiating Compose!(A, B, C) * is the same as instantiating A!(B!(C!(…))). * * This is especially useful for creating a template to use with staticMap/ * StaticFilter, as demonstrated below. * * Example: * --- * template AllMethodNames(T) { * alias StaticFilter!( * CompilesAndTrue!( * Compose!(isSomeFunction, TypeOf, PApply!(GetMember, T)) * ), * __traits(allMembers, T) * ) AllMethodNames; * } * * pragma(msg, AllMethodNames!Object); * --- */ template Compose(T...) { static if (T.length == 0) { template Compose(U...) { alias U Compose; } } else { template Compose(U...) { alias Instantiate!(T[0], Instantiate!(.Compose!(T[1 .. $]), U)) Compose; } } } /** * Instantiates the given template with the given list of parameters. * * Used to work around syntactic limiations of D with regard to instantiating * a template from a type tuple (e.g. T[0]!(...) is not valid) or a template * returning another template (e.g. Foo!(Bar)!(Baz) is not allowed). */ template Instantiate(alias Template, Params...) { alias Template!Params Instantiate; } /** * Combines several template predicates using logical AND, i.e. instantiating * All!(a, b, c) with parameters P for some templates a, b, c is equivalent to * a!P && b!P && c!P. * * The templates are evaluated from left to right, aborting evaluation in a * shurt-cut manner if a false result is encountered, in which case the latter * instantiations do not need to compile. */ template All(T...) { static if (T.length == 0) { template All(U...) { enum All = true; } } else { template All(U...) { static if (Instantiate!(T[0], U)) { alias Instantiate!(.All!(T[1 .. $]), U) All; } else { enum All = false; } } } } /** * Combines several template predicates using logical OR, i.e. instantiating * Any!(a, b, c) with parameters P for some templates a, b, c is equivalent to * a!P || b!P || c!P. * * The templates are evaluated from left to right, aborting evaluation in a * shurt-cut manner if a true result is encountered, in which case the latter * instantiations do not need to compile. */ template Any(T...) { static if (T.length == 0) { template Any(U...) { enum Any = false; } } else { template Any(U...) { static if (Instantiate!(T[0], U)) { enum Any = true; } else { alias Instantiate!(.Any!(T[1 .. $]), U) Any; } } } } template ConfinedTuple(T...) { alias T Tuple; enum length = T.length; } /* * foreach (Item; Items) { * List = Operator!(Item, List); * } * where Items is a ConfinedTuple and List is a type tuple. */ template ForAllWithList(alias Items, alias Operator, List...) if ( is(typeof(Items.length) : size_t) ){ static if (Items.length == 0) { alias List ForAllWithList; } else { alias .ForAllWithList!( ConfinedTuple!(Items.Tuple[1 .. $]), Operator, Operator!(Items.Tuple[0], List) ) ForAllWithList; } } /** * Wraps the passed template predicate so it returns true if it compiles and * evaluates to true, false it it doesn't compile or evaluates to false. */ template CompilesAndTrue(alias T) { template CompilesAndTrue(U...) { static if (is(typeof(T!U) : bool)) { enum bool CompilesAndTrue = T!U; } else { enum bool CompilesAndTrue = false; } } } thrift-0.23.0/lib/d/src/thrift/internal/ssl_bio.d0000664000175000017500000001231215165535636022067 0ustar00buildbuild00000000000000/* * 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. */ /** * Provides a SSL BIO implementation wrapping a Thrift transport. * * This way, SSL I/O can be relayed over Thrift transport without introducing * an additional layer of buffering, especially for the non-blocking * transports. * * For the Thrift transport incarnations of the SSL entities, "tt" is used as * prefix for clarity. */ module thrift.internal.ssl_bio; import core.stdc.config; import core.stdc.string : strlen; import core.memory : GC; import deimos.openssl.bio; import deimos.openssl.err; import thrift.base; import thrift.internal.ssl; import thrift.transport.base; /** * Creates an SSL BIO object wrapping the given transport. * * Exceptions thrown by the transport are pushed onto the OpenSSL error stack, * using the location/reason values from thrift.internal.ssl.ERR_*_D_EXCEPTION. * * The transport is assumed to be ready for reading and writing when the BIO * functions are called, it is not opened by the implementation. * * Params: * transport = The transport to wrap. * closeTransport = Whether the close the transport when the SSL BIO is * closed. */ BIO* createTTransportBIO(TTransport transport, bool closeTransport) { auto result = BIO_new(cast(BIO_METHOD*)&ttBioMethod); if (!result) return null; GC.addRoot(cast(void*)transport); BIO_set_fd(result, closeTransport, cast(c_long)cast(void*)transport); return result; } private { // Helper to get the Thrift transport assigned with the given BIO. TTransport trans(BIO* b) nothrow { auto result = cast(TTransport)b.ptr; assert(result); return result; } void setError(Exception e) nothrow { ERR_put_error(ERR_LIB_D_EXCEPTION, ERR_F_D_EXCEPTION, ERR_R_D_EXCEPTION, ERR_FILE_D_EXCEPTION, ERR_LINE_D_EXCEPTION); try { GC.addRoot(cast(void*)e); } catch (Throwable) {} ERR_set_error_data(cast(char*)e, ERR_FLAGS_D_EXCEPTION); } extern(C) int ttWrite(BIO* b, const(char)* data, int length) nothrow { assert(b); if (!data || length <= 0) return 0; try { trans(b).write((cast(ubyte*)data)[0 .. length]); return length; } catch (Exception e) { setError(e); return -1; } } extern(C) int ttRead(BIO* b, char* data, int length) nothrow { assert(b); if (!data || length <= 0) return 0; try { return cast(int)trans(b).read((cast(ubyte*)data)[0 .. length]); } catch (Exception e) { setError(e); return -1; } } extern(C) int ttPuts(BIO* b, const(char)* str) nothrow { return ttWrite(b, str, cast(int)strlen(str)); } extern(C) c_long ttCtrl(BIO* b, int cmd, c_long num, void* ptr) nothrow { assert(b); switch (cmd) { case BIO_C_SET_FD: // Note that close flag and "fd" are actually reversed here because we // need 64 bit width for the pointer – should probably drop BIO_set_fd // altogether. ttDestroy(b); b.ptr = cast(void*)num; b.shutdown = cast(int)ptr; b.init_ = 1; return 1; case BIO_C_GET_FD: if (!b.init_) return -1; *(cast(void**)ptr) = b.ptr; return cast(c_long)b.ptr; case BIO_CTRL_GET_CLOSE: return b.shutdown; case BIO_CTRL_SET_CLOSE: b.shutdown = cast(int)num; return 1; case BIO_CTRL_FLUSH: try { trans(b).flush(); return 1; } catch (Exception e) { setError(e); return -1; } case BIO_CTRL_DUP: // Seems like we have nothing to do on duplication, but couldn't find // any documentation if this actually ever happens during normal SSL // usage. return 1; default: return 0; } } extern(C) int ttCreate(BIO* b) nothrow { assert(b); b.init_ = 0; b.num = 0; // User-defined number field, unused here. b.ptr = null; b.flags = 0; return 1; } extern(C) int ttDestroy(BIO* b) nothrow { if (!b) return 0; int rc = 1; if (b.shutdown) { if (b.init_) { try { trans(b).close(); GC.removeRoot(cast(void*)trans(b)); b.ptr = null; } catch (Exception e) { setError(e); rc = -1; } } b.init_ = 0; b.flags = 0; } return rc; } immutable BIO_METHOD ttBioMethod = { BIO_TYPE_SOURCE_SINK, "TTransport", &ttWrite, &ttRead, &ttPuts, null, // gets &ttCtrl, &ttCreate, &ttDestroy, null // callback_ctrl }; } thrift-0.23.0/lib/d/src/thrift/internal/algorithm.d0000664000175000017500000000224415165535636022426 0ustar00buildbuild00000000000000/** * Contains a modified version of std.algorithm.remove that doesn't take an * alias parameter to avoid DMD @@BUG6395@@. */ module thrift.internal.algorithm; import std.algorithm : move; import std.exception; import std.functional; import std.range; import std.traits; enum SwapStrategy { unstable, semistable, stable, } Range removeEqual(SwapStrategy s = SwapStrategy.stable, Range, E)(Range range, E e) if (isBidirectionalRange!Range) { auto result = range; static if (s != SwapStrategy.stable) { for (;!range.empty;) { if (range.front !is e) { range.popFront; continue; } move(range.back, range.front); range.popBack; result.popBack; } } else { auto tgt = range; for (; !range.empty; range.popFront) { if (range.front is e) { // yank this guy result.popBack; continue; } // keep this guy move(range.front, tgt.front); tgt.popFront; } } return result; } thrift-0.23.0/lib/d/src/thrift/index.d0000664000175000017500000000314515165535636017734 0ustar00buildbuild00000000000000Ddoc

Package overview

$(D_CODE thrift.async)
Support infrastructure for handling client-side asynchronous operations using non-blocking I/O and coroutines.
$(D_CODE thrift.codegen)

Templates used for generating Thrift clients/processors from regular D struct and interface definitions.

Note: Several artifacts in these modules have options for specifying the exact protocol types used. In this case, the amount of virtual calls can be greatly reduced and as a result, the code also can be optimized better. If performance is not a concern or the actual protocol type is not known at compile time, these parameters can just be left at their defaults.

$(D_CODE thrift.internal)
Internal helper modules used by the Thrift library. This package is not part of the public API, and no stability guarantees are given whatsoever.
$(D_CODE thrift.protocol)
The Thrift protocol implemtations which specify how to pass messages over a TTransport.
$(D_CODE thrift.server)
Generic Thrift server implementations handling clients over a TTransport interface and forwarding requests to a TProcessor (which is in turn usually provided by thrift.codegen).
$(D_CODE thrift.transport)
The TTransport data source/sink interface used in the Thrift library and its imiplementations.
$(D_CODE thrift.util)
General-purpose utility modules not specific to Thrift, part of the public API.
Macros: TITLE = Thrift D Software Library thrift-0.23.0/lib/d/src/thrift/base.d0000664000175000017500000000713115170007142017514 0ustar00buildbuild00000000000000/* * 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. */ module thrift.base; /** * Common base class for all Thrift exceptions. */ class TException : Exception { /// this(string msg = "", string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } } /** * An operation failed because one or more sub-tasks failed. */ class TCompoundOperationException : TException { /// this(string msg, Exception[] exceptions, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); this.exceptions = exceptions; } /// The exceptions thrown by the children of the operation. If applicable, /// the list is ordered in the same way the exceptions occurred. Exception[] exceptions; } /// 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.23.0"; /** * Functions used for logging inside Thrift. * * By default, the formatted messages are written to stdout/stderr, but this * behavior can be overwritten by providing custom g_{Info, Error}LogSink * handlers. * * Examples: * --- * logInfo("An informative message."); * logError("Some error occurred: %s", e); * --- */ alias logFormatted!g_infoLogSink logInfo; alias logFormatted!g_errorLogSink logError; /// Ditto /** * Error and info log message sinks. * * These delegates are called with the log message passed as const(char)[] * argument, and can be overwritten to hook the Thrift libraries up with a * custom logging system. By default, they forward all output to stdout/stderr. */ __gshared void delegate(const(char)[]) g_infoLogSink; __gshared void delegate(const(char)[]) g_errorLogSink; /// Ditto shared static this() { import std.stdio; g_infoLogSink = (const(char)[] text) { stdout.writeln(text); }; g_errorLogSink = (const(char)[] text) { stderr.writeln(text); }; } // This should be private, if it could still be used through the aliases then. template logFormatted(alias target) { void logFormatted(string file = __FILE__, int line = __LINE__, T...)(string fmt, T args) if ( __traits(compiles, { target(""); }) ) { import std.format, std.stdio; if (target !is null) { scope(exit) g_formatBuffer.clear(); // Phobos @@BUG@@: If the empty string put() is removed, Appender.data // stays empty. g_formatBuffer.put(""); formattedWrite(g_formatBuffer, "%s:%s: ", file, line); static if (T.length == 0) { g_formatBuffer.put(fmt); } else { formattedWrite(g_formatBuffer, fmt, args); } target(g_formatBuffer.data); } } } private { // Use a global, but thread-local buffer for constructing log messages. import std.array : Appender; Appender!(char[]) g_formatBuffer; } thrift-0.23.0/lib/d/src/thrift/server/0000775000175000017500000000000015165535636017763 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/server/nonblocking.d0000664000175000017500000012726015165535636022443 0ustar00buildbuild00000000000000/* * 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. */ /** * A non-blocking server implementation that operates a set of I/O threads (by * default only one) and either does processing »in-line« or off-loads it to a * task pool. * * It *requires* TFramedTransport to be used on the client side, as it expects * a 4 byte length indicator and writes out responses using the same framing. * * Because I/O is done asynchronous/event based, unfortunately * TServerTransport can't be used. * * This implementation is based on the C++ one, with the exception of request * timeouts and the drain task queue overload handling strategy not being * implemented yet. */ // This really should use a D non-blocking I/O library, once one becomes // available. module thrift.server.nonblocking; import core.atomic : atomicLoad, atomicStore, atomicOp; import core.exception : onOutOfMemoryError; import core.memory : GC; import core.sync.mutex; import core.stdc.stdlib : free, realloc; import core.time : Duration, dur; import core.thread : Thread, ThreadGroup; import deimos.event2.event; import std.array : empty; import std.conv : emplace, to; import std.exception : enforce; import std.parallelism : TaskPool, task; import std.socket : Socket, socketPair, SocketAcceptException, SocketException, TcpSocket; import std.variant : Variant; import thrift.base; import thrift.internal.endian; import thrift.internal.socket; import thrift.internal.traits; import thrift.protocol.base; import thrift.protocol.binary; import thrift.protocol.processor; import thrift.server.base; import thrift.server.transport.socket; import thrift.transport.base; import thrift.transport.memory; import thrift.transport.range; import thrift.transport.socket; import thrift.util.cancellation; /** * Possible actions taken on new incoming connections when the server is * overloaded. */ enum TOverloadAction { /// Do not take any special actions while the server is overloaded, just /// continue accepting connections. NONE, /// Immediately drop new connections after they have been accepted if the /// server is overloaded. CLOSE_ON_ACCEPT } /// class TNonblockingServer : TServer { /// this(TProcessor processor, ushort port, TTransportFactory transportFactory, TProtocolFactory protocolFactory, TaskPool taskPool = null ) { this(new TSingletonProcessorFactory(processor), port, transportFactory, transportFactory, protocolFactory, protocolFactory, taskPool); } /// this(TProcessorFactory processorFactory, ushort port, TTransportFactory transportFactory, TProtocolFactory protocolFactory, TaskPool taskPool = null ) { this(processorFactory, port, transportFactory, transportFactory, protocolFactory, protocolFactory, taskPool); } /// this( TProcessor processor, ushort port, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TaskPool taskPool = null ) { this(new TSingletonProcessorFactory(processor), port, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory, taskPool); } /// this( TProcessorFactory processorFactory, ushort port, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TaskPool taskPool = null ) { super(processorFactory, null, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); port_ = port; this.taskPool = taskPool; connectionMutex_ = new Mutex; connectionStackLimit = DEFAULT_CONNECTION_STACK_LIMIT; maxActiveProcessors = DEFAULT_MAX_ACTIVE_PROCESSORS; maxConnections = DEFAULT_MAX_CONNECTIONS; overloadHysteresis = DEFAULT_OVERLOAD_HYSTERESIS; overloadAction = DEFAULT_OVERLOAD_ACTION; writeBufferDefaultSize = DEFAULT_WRITE_BUFFER_DEFAULT_SIZE; idleReadBufferLimit = DEFAULT_IDLE_READ_BUFFER_LIMIT; idleWriteBufferLimit = DEFAULT_IDLE_WRITE_BUFFER_LIMIT; resizeBufferEveryN = DEFAULT_RESIZE_BUFFER_EVERY_N; maxFrameSize = DEFAULT_MAX_FRAME_SIZE; numIOThreads_ = DEFAULT_NUM_IO_THREADS; } override void serve(TCancellation cancellation = null) { if (cancellation && cancellation.triggered) return; // Initialize the listening socket. // TODO: SO_KEEPALIVE, TCP_LOW_MIN_RTO, etc. listenSocket_ = makeSocketAndListen(port_, TServerSocket.ACCEPT_BACKLOG, BIND_RETRY_LIMIT, BIND_RETRY_DELAY, 0, 0, ipv6Only_); listenSocket_.blocking = false; logInfo("Using %s I/O thread(s).", numIOThreads_); if (taskPool_) { logInfo("Using task pool with size: %s.", numIOThreads_, taskPool_.size); } assert(numIOThreads_ > 0); assert(ioLoops_.empty); foreach (id; 0 .. numIOThreads_) { // The IO loop on the first IO thread (this thread, i.e. the one serve() // is called from) also accepts new connections. auto listenSocket = (id == 0 ? listenSocket_ : null); ioLoops_ ~= new IOLoop(this, listenSocket); } if (cancellation) { cancellation.triggering.addCallback({ foreach (i, loop; ioLoops_) loop.stop(); // Stop accepting new connections right away. listenSocket_.close(); listenSocket_ = null; }); } // Start the IO helper threads for all but the first loop, which we will run // ourselves. Note that the threads run forever, only terminating if stop() // is called. auto threads = new ThreadGroup(); foreach (loop; ioLoops_[1 .. $]) { auto t = new Thread(&loop.run); threads.add(t); t.start(); } if (eventHandler) eventHandler.preServe(); // Run the primary (listener) IO thread loop in our main thread; this will // block until the server is shutting down. ioLoops_[0].run(); // Ensure all threads are finished before leaving serve(). threads.joinAll(); ioLoops_ = null; } /** * Returns the number of currently active connections, i.e. open sockets. */ size_t numConnections() const @property { return numConnections_; } /** * Returns the number of connection objects allocated, but not in use. */ size_t numIdleConnections() const @property { return connectionStack_.length; } /** * Return count of number of connections which are currently processing. * * This is defined as a connection where all data has been received, and the * processor was invoked but has not yet completed. */ size_t numActiveProcessors() const @property { return numActiveProcessors_; } /// Number of bind() retries. enum BIND_RETRY_LIMIT = 0; /// Duration between bind() retries. enum BIND_RETRY_DELAY = dur!"hnsecs"(0); /// Whether to listen on IPv6 only, if IPv6 support is detected // (default: false). void ipv6Only(bool value) @property { ipv6Only_ = value; } /** * The task pool to use for processing requests. If null, no additional * threads are used and request are processed »inline«. * * Can safely be set even when the server is already running. */ TaskPool taskPool() @property { return taskPool_; } /// ditto void taskPool(TaskPool pool) @property { taskPool_ = pool; } /** * Hysteresis for overload state. * * This is the fraction of the overload value that needs to be reached * before the overload state is cleared. It must be between 0 and 1, * practical choices probably lie between 0.5 and 0.9. */ double overloadHysteresis() const @property { return overloadHysteresis_; } /// Ditto void overloadHysteresis(double value) @property { enforce(0 < value && value <= 1, "Invalid value for overload hysteresis: " ~ to!string(value)); overloadHysteresis_ = value; } /// Ditto enum DEFAULT_OVERLOAD_HYSTERESIS = 0.8; /** * The action which will be taken on overload. */ TOverloadAction overloadAction; /// Ditto enum DEFAULT_OVERLOAD_ACTION = TOverloadAction.NONE; /** * The write buffer is initialized (and when idleWriteBufferLimit_ is checked * and found to be exceeded, reinitialized) to this size. */ size_t writeBufferDefaultSize; /// Ditto enum size_t DEFAULT_WRITE_BUFFER_DEFAULT_SIZE = 1024; /** * Max read buffer size for an idle Connection. When we place an idle * Connection into connectionStack_ or on every resizeBufferEveryN_ calls, * we will free the buffer (such that it will be reinitialized by the next * received frame) if it has exceeded this limit. 0 disables this check. */ size_t idleReadBufferLimit; /// Ditto enum size_t DEFAULT_IDLE_READ_BUFFER_LIMIT = 1024; /** * Max write buffer size for an idle connection. When we place an idle * Connection into connectionStack_ or on every resizeBufferEveryN_ calls, * we ensure that its write buffer is <= to this size; otherwise we * replace it with a new one of writeBufferDefaultSize_ bytes to ensure that * idle connections don't hog memory. 0 disables this check. */ size_t idleWriteBufferLimit; /// Ditto enum size_t DEFAULT_IDLE_WRITE_BUFFER_LIMIT = 1024; /** * Every N calls we check the buffer size limits on a connected Connection. * 0 disables (i.e. the checks are only done when a connection closes). */ uint resizeBufferEveryN; /// Ditto enum uint DEFAULT_RESIZE_BUFFER_EVERY_N = 512; /// Limit for how many Connection objects to cache. size_t connectionStackLimit; /// Ditto enum size_t DEFAULT_CONNECTION_STACK_LIMIT = 1024; /// Limit for number of open connections before server goes into overload /// state. size_t maxConnections; /// Ditto enum size_t DEFAULT_MAX_CONNECTIONS = int.max; /// Limit for number of connections processing or waiting to process size_t maxActiveProcessors; /// Ditto enum size_t DEFAULT_MAX_ACTIVE_PROCESSORS = int.max; /// Maximum frame size, in bytes. /// /// If a client tries to send a message larger than this limit, its /// connection will be closed. This helps to avoid allocating huge buffers /// on bogous input. uint maxFrameSize; /// Ditto enum uint DEFAULT_MAX_FRAME_SIZE = 256 * 1024 * 1024; size_t numIOThreads() @property { return numIOThreads_; } void numIOThreads(size_t value) @property { enforce(value >= 1, new TException("Must use at least one I/O thread.")); numIOThreads_ = value; } enum DEFAULT_NUM_IO_THREADS = 1; private: /** * C callback wrapper around acceptConnections(). Expects the custom argument * to be the this pointer of the associated server instance. */ extern(C) static void acceptConnectionsCallback(int fd, short which, void* serverThis ) { (cast(TNonblockingServer)serverThis).acceptConnections(fd, which); } /** * Called by libevent (IO loop 0/serve() thread only) when something * happened on the listening socket. */ void acceptConnections(int fd, short eventFlags) { if (atomicLoad(ioLoops_[0].shuttingDown_)) return; assert(!!listenSocket_, "Server should be shutting down if listen socket is null."); assert(fd == listenSocket_.handle); assert(eventFlags & EV_READ); // Accept as many new clients as possible, even though libevent signaled // only one. This helps the number of calls into libevent space. while (true) { // It is lame to use exceptions for regular control flow (failing is // excepted due to non-blocking mode of operation), but that's the // interface std.socket offers… Socket clientSocket; try { clientSocket = listenSocket_.accept(); } catch (SocketAcceptException e) { if (e.errorCode != WOULD_BLOCK_ERRNO) { logError("Error accepting connection: %s", e); } break; } // If the server is overloaded, this is the point to take the specified // action. if (overloadAction != TOverloadAction.NONE && checkOverloaded()) { nConnectionsDropped_++; nTotalConnectionsDropped_++; if (overloadAction == TOverloadAction.CLOSE_ON_ACCEPT) { clientSocket.close(); return; } } try { clientSocket.blocking = false; } catch (SocketException e) { logError("Couldn't set client socket to non-blocking mode: %s", e); clientSocket.close(); return; } // Create a new Connection for this client socket. Connection conn = void; IOLoop loop = void; bool thisThread = void; synchronized (connectionMutex_) { // Assign an I/O loop to the connection (round-robin). assert(nextIOLoop_ >= 0); assert(nextIOLoop_ < ioLoops_.length); auto selectedThreadIdx = nextIOLoop_; nextIOLoop_ = (nextIOLoop_ + 1) % ioLoops_.length; loop = ioLoops_[selectedThreadIdx]; thisThread = (selectedThreadIdx == 0); // Check the connection stack to see if we can re-use an existing one. if (connectionStack_.empty) { ++numConnections_; conn = new Connection(clientSocket, loop); // Make sure the connection does not get collected while it is active, // i.e. hooked up with libevent. GC.addRoot(cast(void*)conn); } else { conn = connectionStack_[$ - 1]; connectionStack_ = connectionStack_[0 .. $ - 1]; connectionStack_.assumeSafeAppend(); conn.init(clientSocket, loop); } } loop.addConnection(); // Either notify the ioThread that is assigned this connection to // start processing, or if it is us, we'll just ask this // connection to do its initial state change here. // // (We need to avoid writing to our own notification pipe, to // avoid possible deadlocks if the pipe is full.) if (thisThread) { conn.transition(); } else { loop.notifyCompleted(conn); } } } /// Increment the count of connections currently processing. void incrementActiveProcessors() { atomicOp!"+="(numActiveProcessors_, 1); } /// Decrement the count of connections currently processing. void decrementActiveProcessors() { assert(numActiveProcessors_ > 0); atomicOp!"-="(numActiveProcessors_, 1); } /** * Determines if the server is currently overloaded. * * If the number of open connections or »processing« connections is over the * respective limit, the server will enter overload handling mode and a * warning will be logged. If below values are below the hysteresis curve, * this will cause the server to exit it again. * * Returns: Whether the server is currently overloaded. */ bool checkOverloaded() { auto activeConnections = numConnections_ - connectionStack_.length; if (numActiveProcessors_ > maxActiveProcessors || activeConnections > maxConnections) { if (!overloaded_) { logInfo("Entering overloaded state."); overloaded_ = true; } } else { if (overloaded_ && (numActiveProcessors_ <= overloadHysteresis_ * maxActiveProcessors) && (activeConnections <= overloadHysteresis_ * maxConnections)) { logInfo("Exiting overloaded state, %s connection(s) dropped (% total).", nConnectionsDropped_, nTotalConnectionsDropped_); nConnectionsDropped_ = 0; overloaded_ = false; } } return overloaded_; } /** * Marks a connection as inactive and either puts it back into the * connection pool or leaves it for garbage collection. */ void disposeConnection(Connection connection) { synchronized (connectionMutex_) { if (!connectionStackLimit || (connectionStack_.length < connectionStackLimit)) { connection.checkIdleBufferLimit(idleReadBufferLimit, idleWriteBufferLimit); connectionStack_ ~= connection; } else { assert(numConnections_ > 0); --numConnections_; // Leave the connection object for collection now. GC.removeRoot(cast(void*)connection); } } } /// Socket used to listen for connections and accepting them. Socket listenSocket_; /// Port to listen on. ushort port_; /// Whether to listen on IPv6 only. bool ipv6Only_; /// The total number of connections existing, both active and idle. size_t numConnections_; /// The number of connections which are currently waiting for the processor /// to return. shared size_t numActiveProcessors_; /// Hysteresis for leaving overload state. double overloadHysteresis_; /// Whether the server is currently overloaded. bool overloaded_; /// Number of connections dropped since the server entered the current /// overloaded state. uint nConnectionsDropped_; /// Number of connections dropped due to overload since the server started. ulong nTotalConnectionsDropped_; /// The task pool used for processing requests. TaskPool taskPool_; /// Number of IO threads this server will use (>= 1). size_t numIOThreads_; /// The IOLoops among which socket handling work is distributed. IOLoop[] ioLoops_; /// The index of the loop in ioLoops_ which will handle the next accepted /// connection. size_t nextIOLoop_; /// All the connection objects which have been created but are not currently /// in use. When a connection is closed, it it placed here to enable object /// (resp. buffer) reuse. Connection[] connectionStack_; /// This mutex protects the connection stack. Mutex connectionMutex_; } private { /* * Encapsulates a libevent event loop. * * The design is a bit of a mess, since the first loop is actually run on the * server thread itself and is special because it is the only instance for * which listenSocket_ is not null. */ final class IOLoop { /** * Creates a new instance and set up the event base. * * If listenSocket is not null, the thread will also accept new * connections itself. */ this(TNonblockingServer server, Socket listenSocket) { server_ = server; listenSocket_ = listenSocket; initMutex_ = new Mutex; } /** * Runs the event loop; only returns after a call to stop(). */ void run() { assert(!atomicLoad(initialized_), "IOLoop already running?!"); synchronized (initMutex_) { if (atomicLoad(shuttingDown_)) return; atomicStore(initialized_, true); assert(!eventBase_); eventBase_ = event_base_new(); if (listenSocket_) { // Log the libevent version and backend. logInfo("libevent version %s, using method %s.", to!string(event_get_version()), to!string(event_base_get_method(eventBase_))); // Register the event for the listening socket. listenEvent_ = event_new(eventBase_, cast(evutil_socket_t)listenSocket_.handle, EV_READ | EV_PERSIST | EV_ET, assumeNothrow(&TNonblockingServer.acceptConnectionsCallback), cast(void*)server_); if (event_add(listenEvent_, null) == -1) { throw new TException("event_add for the listening socket event failed."); } } auto pair = socketPair(); foreach (s; pair) s.blocking = false; completionSendSocket_ = pair[0]; completionReceiveSocket_ = pair[1]; // Register an event for the task completion notification socket. completionEvent_ = event_new(eventBase_, cast(evutil_socket_t)completionReceiveSocket_.handle, EV_READ | EV_PERSIST | EV_ET, assumeNothrow(&completedCallback), cast(void*)this); if (event_add(completionEvent_, null) == -1) { throw new TException("event_add for the notification socket failed."); } } // Run libevent engine, returns only after stop(). event_base_dispatch(eventBase_); if (listenEvent_) { event_free(listenEvent_); listenEvent_ = null; } event_free(completionEvent_); completionEvent_ = null; completionSendSocket_.close(); completionSendSocket_ = null; completionReceiveSocket_.close(); completionReceiveSocket_ = null; event_base_free(eventBase_); eventBase_ = null; atomicStore(shuttingDown_, false); initialized_ = false; } /** * Adds a new connection handled by this loop. */ void addConnection() { ++numActiveConnections_; } /** * Disposes a connection object (typically after it has been closed). */ void disposeConnection(Connection conn) { server_.disposeConnection(conn); assert(numActiveConnections_ > 0); --numActiveConnections_; if (numActiveConnections_ == 0) { if (atomicLoad(shuttingDown_)) { event_base_loopbreak(eventBase_); } } } /** * Notifies the event loop that the current step (initialization, * processing of a request) on a certain connection has been completed. * * This function is thread-safe, but should never be called from the * thread running the loop itself. */ void notifyCompleted(Connection conn) { assert(!!completionSendSocket_); auto bytesSent = completionSendSocket_.send(cast(ubyte[])((&conn)[0 .. 1])); if (bytesSent != Connection.sizeof) { logError("Sending completion notification failed, connection will " ~ "not be properly terminated."); } } /** * Exits the event loop after all currently active connections have been * closed. * * This function is thread-safe. */ void stop() { // There is a bug in either libevent or its documentation, having no // events registered doesn't actually terminate the loop, because // event_base_new() registers some internal one by calling // evthread_make_base_notifiable(). // Due to this, we can't simply remove all events and expect the event // loop to terminate. Instead, we ping the event loop using a null // completion message. This way, we make sure to wake up the libevent // thread if it not currently processing any connections. It will break // out of the loop in disposeConnection() after the last active // connection has been closed. synchronized (initMutex_) { atomicStore(shuttingDown_, true); if (atomicLoad(initialized_)) notifyCompleted(null); } } private: /** * C callback to call completed() from libevent. * * Expects the custom argument to be the this pointer of the associated * IOLoop instance. */ extern(C) static void completedCallback(int fd, short what, void* loopThis) { assert(what & EV_READ); auto loop = cast(IOLoop)loopThis; assert(fd == loop.completionReceiveSocket_.handle); loop.completed(); } /** * Reads from the completion receive socket and appropriately transitions * the connections and shuts down the loop if requested. */ void completed() { Connection connection; ptrdiff_t bytesRead; while (true) { bytesRead = completionReceiveSocket_.receive( cast(ubyte[])((&connection)[0 .. 1])); if (bytesRead < 0) { auto errno = getSocketErrno(); if (errno != WOULD_BLOCK_ERRNO) { logError("Reading from completion socket failed, some connection " ~ "will never be properly terminated: %s", socketErrnoString(errno)); } } if (bytesRead != Connection.sizeof) break; if (!connection) { assert(atomicLoad(shuttingDown_)); if (numActiveConnections_ == 0) { event_base_loopbreak(eventBase_); } continue; } connection.transition(); } if (bytesRead > 0) { logError("Unexpected partial read from completion socket " ~ "(%s bytes instead of %s).", bytesRead, Connection.sizeof); } } /// associated server TNonblockingServer server_; /// The managed listening socket, if any. Socket listenSocket_; /// The libevent event base for the loop. event_base* eventBase_; /// Triggered on listen socket events. event* listenEvent_; /// Triggered on completion receive socket events. event* completionEvent_; /// Socket used to send completion notification messages. Paired with /// completionReceiveSocket_. Socket completionSendSocket_; /// Socket used to send completion notification messages. Paired with /// completionSendSocket_. Socket completionReceiveSocket_; /// Whether the server is currently shutting down (i.e. the cancellation has /// been triggered, but not all client connections have been closed yet). shared bool shuttingDown_; /// The number of currently active client connections. size_t numActiveConnections_; /// Guards loop startup so that the loop can be reliably shut down even if /// another thread has just started to execute run(). Locked during /// initialization in run(). When unlocked, the completion mechanism is /// expected to be fully set up. Mutex initMutex_; shared bool initialized_; /// Ditto } /* * I/O states a socket can be in. */ enum SocketState { RECV_FRAME_SIZE, /// The frame size is received. RECV, /// The payload is received. SEND /// The response is written back out. } /* * States a connection can be in. */ enum ConnectionState { INIT, /// The connection will be initialized. READ_FRAME_SIZE, /// The four frame size bytes are being read. READ_REQUEST, /// The request payload itself is being read. WAIT_PROCESSOR, /// The connection waits for the processor to finish. SEND_RESULT /// The result is written back out. } /* * A connection that is handled via libevent. * * Data received is buffered until the request is complete (returning back to * libevent if not), at which point the processor is invoked. */ final class Connection { /** * Constructs a new instance. * * To reuse a connection object later on, the init() function can be used * to the same effect on the internal state. */ this(Socket socket, IOLoop loop) { // The input and output transport objects are reused between clients // connections, so initialize them here rather than in init(). inputTransport_ = new TInputRangeTransport!(ubyte[])([]); outputTransport_ = new TMemoryBuffer(loop.server_.writeBufferDefaultSize); init(socket, loop); } /** * Initializes the connection. * * Params: * socket = The socket to work on. * eventFlags = Any flags to pass to libevent. * s = The server this connection is part of. */ void init(Socket socket, IOLoop loop) { // TODO: This allocation could be avoided. socket_ = new TSocket(socket); loop_ = loop; server_ = loop_.server_; connState_ = ConnectionState.INIT; eventFlags_ = 0; readBufferPos_ = 0; readWant_ = 0; writeBuffer_ = null; writeBufferPos_ = 0; largestWriteBufferSize_ = 0; socketState_ = SocketState.RECV_FRAME_SIZE; callsSinceResize_ = 0; factoryInputTransport_ = server_.inputTransportFactory.getTransport(inputTransport_); factoryOutputTransport_ = server_.outputTransportFactory.getTransport(outputTransport_); inputProtocol_ = server_.inputProtocolFactory.getProtocol(factoryInputTransport_); outputProtocol_ = server_.outputProtocolFactory.getProtocol(factoryOutputTransport_); if (server_.eventHandler) { connectionContext_ = server_.eventHandler.createContext(inputProtocol_, outputProtocol_); } auto info = TConnectionInfo(inputProtocol_, outputProtocol_, socket_); processor_ = server_.processorFactory.getProcessor(info); } ~this() { free(readBuffer_); if (event_) { event_free(event_); event_ = null; } } /** * Check buffers against the size limits and shrink them if exceeded. * * Params: * readLimit = Read buffer size limit (in bytes, 0 to ignore). * writeLimit = Write buffer size limit (in bytes, 0 to ignore). */ void checkIdleBufferLimit(size_t readLimit, size_t writeLimit) { if (readLimit > 0 && readBufferSize_ > readLimit) { free(readBuffer_); readBuffer_ = null; readBufferSize_ = 0; } if (writeLimit > 0 && largestWriteBufferSize_ > writeLimit) { // just start over outputTransport_.reset(server_.writeBufferDefaultSize); largestWriteBufferSize_ = 0; } } /** * Transitions the connection to the next state. * * This is called e.g. when the request has been read completely or all * the data has been written back. */ void transition() { assert(!!loop_); assert(!!server_); // Switch upon the state that we are currently in and move to a new state final switch (connState_) { case ConnectionState.READ_REQUEST: // We are done reading the request, package the read buffer into transport // and get back some data from the dispatch function inputTransport_.reset(readBuffer_[0 .. readBufferPos_]); outputTransport_.reset(); // Prepend four bytes of blank space to the buffer so we can // write the frame size there later. // Strictly speaking, we wouldn't have to write anything, just // increment the TMemoryBuffer writeOffset_. This would yield a tiny // performance gain. ubyte[4] space = void; outputTransport_.write(space); server_.incrementActiveProcessors(); taskPool_ = server_.taskPool; if (taskPool_) { // Create a new task and add it to the task pool queue. auto processingTask = task!processRequest(this); connState_ = ConnectionState.WAIT_PROCESSOR; taskPool_.put(processingTask); // We don't want to process any more data while the task is active. unregisterEvent(); return; } // Just process it right now if there is no task pool set. processRequest(this); goto case; case ConnectionState.WAIT_PROCESSOR: // We have now finished processing the request, set the frame size // for the outputTransport_ contents and set everything up to write // it out via libevent. server_.decrementActiveProcessors(); // Acquire the data written to the transport. // KLUDGE: To avoid copying, we simply cast the const away and // modify the internal buffer of the TMemoryBuffer – works with the // current implementation, but isn't exactly beautiful. writeBuffer_ = cast(ubyte[])outputTransport_.getContents(); assert(writeBuffer_.length >= 4, "The write buffer should have " ~ "least the initially added dummy length bytes."); if (writeBuffer_.length == 4) { // The request was one-way, no response to write. goto case ConnectionState.INIT; } // Write the frame size into the four bytes reserved for it. auto size = hostToNet(cast(uint)(writeBuffer_.length - 4)); writeBuffer_[0 .. 4] = cast(ubyte[])((&size)[0 .. 1]); writeBufferPos_ = 0; socketState_ = SocketState.SEND; connState_ = ConnectionState.SEND_RESULT; registerEvent(EV_WRITE | EV_PERSIST); return; case ConnectionState.SEND_RESULT: // The result has been sent back to the client, we don't need the // buffers anymore. if (writeBuffer_.length > largestWriteBufferSize_) { largestWriteBufferSize_ = writeBuffer_.length; } if (server_.resizeBufferEveryN > 0 && ++callsSinceResize_ >= server_.resizeBufferEveryN ) { checkIdleBufferLimit(server_.idleReadBufferLimit, server_.idleWriteBufferLimit); callsSinceResize_ = 0; } goto case; case ConnectionState.INIT: writeBuffer_ = null; writeBufferPos_ = 0; socketState_ = SocketState.RECV_FRAME_SIZE; connState_ = ConnectionState.READ_FRAME_SIZE; readBufferPos_ = 0; registerEvent(EV_READ | EV_PERSIST); return; case ConnectionState.READ_FRAME_SIZE: // We just read the request length, set up the buffers for reading // the payload. if (readWant_ > readBufferSize_) { // The current buffer is too small, exponentially grow the buffer // until it is big enough. if (readBufferSize_ == 0) { readBufferSize_ = 1; } auto newSize = readBufferSize_; while (readWant_ > newSize) { newSize *= 2; } auto newBuffer = cast(ubyte*)realloc(readBuffer_, newSize); if (!newBuffer) onOutOfMemoryError(); readBuffer_ = newBuffer; readBufferSize_ = newSize; } readBufferPos_= 0; socketState_ = SocketState.RECV; connState_ = ConnectionState.READ_REQUEST; return; } } private: /** * C callback to call workSocket() from libevent. * * Expects the custom argument to be the this pointer of the associated * connection. */ extern(C) static void workSocketCallback(int fd, short flags, void* connThis) { auto conn = cast(Connection)connThis; assert(fd == conn.socket_.socketHandle); conn.workSocket(); } /** * Invoked by libevent when something happens on the socket. */ void workSocket() { final switch (socketState_) { case SocketState.RECV_FRAME_SIZE: // If some bytes have already been read, they have been kept in // readWant_. auto frameSize = readWant_; try { // Read from the socket auto bytesRead = socket_.read( (cast(ubyte[])((&frameSize)[0 .. 1]))[readBufferPos_ .. $]); if (bytesRead == 0) { // Couldn't read anything, but we have been notified – client // has disconnected. close(); return; } readBufferPos_ += bytesRead; } catch (TTransportException te) { logError("Failed to read frame size from client connection: %s", te); close(); return; } if (readBufferPos_ < frameSize.sizeof) { // Frame size not complete yet, save the current buffer in // readWant_ so that the remaining bytes can be read later. readWant_ = frameSize; return; } auto size = netToHost(frameSize); if (size > server_.maxFrameSize) { logError("Frame size too large (%s > %s), client %s not using " ~ "TFramedTransport?", size, server_.maxFrameSize, socket_.getPeerAddress().toHostNameString()); close(); return; } readWant_ = size; // Now we know the frame size, set everything up for reading the // payload. transition(); return; case SocketState.RECV: // If we already got all the data, we should be in the SEND state. assert(readBufferPos_ < readWant_); size_t bytesRead; try { // Read as much as possible from the socket. bytesRead = socket_.read(readBuffer_[readBufferPos_ .. readWant_]); } catch (TTransportException te) { logError("Failed to read from client socket: %s", te); close(); return; } if (bytesRead == 0) { // We were notified, but no bytes could be read -> the client // disconnected. close(); return; } readBufferPos_ += bytesRead; assert(readBufferPos_ <= readWant_); if (readBufferPos_ == readWant_) { // The payload has been read completely, move on. transition(); } return; case SocketState.SEND: assert(writeBufferPos_ <= writeBuffer_.length); if (writeBufferPos_ == writeBuffer_.length) { // Nothing left to send – this shouldn't happen, just move on. logInfo("WARNING: In send state, but no data to send.\n"); transition(); return; } size_t bytesSent; try { bytesSent = socket_.writeSome(writeBuffer_[writeBufferPos_ .. $]); } catch (TTransportException te) { logError("Failed to write to client socket: %s", te); close(); return; } writeBufferPos_ += bytesSent; assert(writeBufferPos_ <= writeBuffer_.length); if (writeBufferPos_ == writeBuffer_.length) { // The whole response has been written out, we are done. transition(); } return; } } /** * Registers a libevent event for workSocket() with the passed flags, * unregistering the previous one (if any). */ void registerEvent(short eventFlags) { if (eventFlags_ == eventFlags) { // Nothing to do if flags are the same. return; } // Delete the previously existing event. unregisterEvent(); eventFlags_ = eventFlags; if (eventFlags == 0) return; if (!event_) { // If the event was not already allocated, do it now. event_ = event_new(loop_.eventBase_, cast(evutil_socket_t)socket_.socketHandle, eventFlags_, assumeNothrow(&workSocketCallback), cast(void*)this); } else { event_assign(event_, loop_.eventBase_, cast(evutil_socket_t)socket_.socketHandle, eventFlags_, assumeNothrow(&workSocketCallback), cast(void*)this); } // Add the event if (event_add(event_, null) == -1) { logError("event_add() for client socket failed."); } } /** * Unregisters the current libevent event, if any. */ void unregisterEvent() { if (event_ && eventFlags_ != 0) { eventFlags_ = 0; if (event_del(event_) == -1) { logError("event_del() for client socket failed."); return; } } } /** * Closes this connection and returns it back to the server. */ void close() { unregisterEvent(); if (server_.eventHandler) { server_.eventHandler.deleteContext( connectionContext_, inputProtocol_, outputProtocol_); } // Close the socket socket_.close(); // close any factory produced transports. factoryInputTransport_.close(); factoryOutputTransport_.close(); // This connection object can now be reused. loop_.disposeConnection(this); } /// The server this connection belongs to. TNonblockingServer server_; /// The task pool used for this connection. This is cached instead of /// directly using server_.taskPool to avoid confusion if it is changed in /// another thread while the request is processed. TaskPool taskPool_; /// The I/O thread handling this connection. IOLoop loop_; /// The socket managed by this connection. TSocket socket_; /// The libevent object used for registering the workSocketCallback. event* event_; /// Libevent flags short eventFlags_; /// Socket mode SocketState socketState_; /// Application state ConnectionState connState_; /// The size of the frame to read. If still in READ_FRAME_SIZE state, some /// of the bytes might not have been written, and the value might still be /// in network byte order. An uint (not a size_t) because the frame size on /// the wire is specified as one. uint readWant_; /// The position in the read buffer, i.e. the number of payload bytes /// already received from the socket in READ_REQUEST state, resp. the /// number of size bytes in READ_FRAME_SIZE state. uint readBufferPos_; /// Read buffer ubyte* readBuffer_; /// Read buffer size size_t readBufferSize_; /// Write buffer ubyte[] writeBuffer_; /// How far through writing are we? size_t writeBufferPos_; /// Largest size of write buffer seen since buffer was constructed size_t largestWriteBufferSize_; /// Number of calls since the last time checkIdleBufferLimit has been /// invoked (see TServer.resizeBufferEveryN). uint callsSinceResize_; /// Base transports the processor reads from/writes to. TInputRangeTransport!(ubyte[]) inputTransport_; TMemoryBuffer outputTransport_; /// The actual transports passed to the processor obtained via the /// transport factory. TTransport factoryInputTransport_; TTransport factoryOutputTransport_; /// Ditto /// Input/output protocols, connected to factory{Input, Output}Transport. TProtocol inputProtocol_; TProtocol outputProtocol_; /// Ditto. /// Connection context optionally created by the server event handler. Variant connectionContext_; /// The processor used for this connection. TProcessor processor_; } } /* * The request processing function, which invokes the processor for the server * for all the RPC messages received over a connection. * * Must be public because it is passed as alias to std.parallelism.task(). */ void processRequest(Connection connection) { try { while (true) { with (connection) { if (server_.eventHandler) { server_.eventHandler.preProcess(connectionContext_, socket_); } if (!processor_.process(inputProtocol_, outputProtocol_, connectionContext_) || !inputProtocol_.transport.peek() ) { // Something went fundamentally wrong or there is nothing more to // process, close the connection. break; } } } } catch (TTransportException ttx) { logError("Client died: %s", ttx); } catch (Exception e) { logError("Uncaught exception: %s", e); } if (connection.taskPool_) connection.loop_.notifyCompleted(connection); } unittest { import thrift.internal.test.server; // Temporarily disable info log output in order not to spam the test results // with startup info messages. auto oldInfoLogSink = g_infoLogSink; g_infoLogSink = null; scope (exit) g_infoLogSink = oldInfoLogSink; // Test in-line processing shutdown with one as well as several I/O threads. testServeCancel!(TNonblockingServer)(); testServeCancel!(TNonblockingServer)((TNonblockingServer s) { s.numIOThreads = 4; }); // Test task pool processing shutdown with one as well as several I/O threads. auto tp = new TaskPool(4); tp.isDaemon = true; testServeCancel!(TNonblockingServer)((TNonblockingServer s) { s.taskPool = tp; }); testServeCancel!(TNonblockingServer)((TNonblockingServer s) { s.taskPool = tp; s.numIOThreads = 4; }); } thrift-0.23.0/lib/d/src/thrift/server/simple.d0000664000175000017500000001307615165535636021430 0ustar00buildbuild00000000000000/* * 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. */ module thrift.server.simple; import std.variant : Variant; import thrift.base; import thrift.protocol.base; import thrift.protocol.processor; import thrift.server.base; import thrift.server.transport.base; import thrift.transport.base; import thrift.util.cancellation; /** * The most basic server. * * It is single-threaded and after it accepts a connections, it processes * requests on it until it closes, then waiting for the next connection. * * It is not so much of use in production than it is for writing unittests, or * as an example on how to provide a custom TServer implementation. */ class TSimpleServer : TServer { /// this( TProcessor processor, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory ) { super(processor, serverTransport, transportFactory, protocolFactory); } /// this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory ) { super(processorFactory, serverTransport, transportFactory, protocolFactory); } /// this( TProcessor processor, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory ) { super(processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); } this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory ) { super(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); } override void serve(TCancellation cancellation = null) { serverTransport_.listen(); if (eventHandler) eventHandler.preServe(); while (true) { TTransport client; TTransport inputTransport; TTransport outputTransport; TProtocol inputProtocol; TProtocol outputProtocol; try { client = serverTransport_.accept(cancellation); scope(failure) client.close(); inputTransport = inputTransportFactory_.getTransport(client); scope(failure) inputTransport.close(); outputTransport = outputTransportFactory_.getTransport(client); scope(failure) outputTransport.close(); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); } catch (TCancelledException tcx) { break; } catch (TTransportException ttx) { logError("TServerTransport failed on accept: %s", ttx); continue; } catch (TException tx) { logError("Caught TException on accept: %s", tx); continue; } auto info = TConnectionInfo(inputProtocol, outputProtocol, client); auto processor = processorFactory_.getProcessor(info); Variant connectionContext; if (eventHandler) { connectionContext = eventHandler.createContext(inputProtocol, outputProtocol); } try { while (true) { if (eventHandler) { eventHandler.preProcess(connectionContext, client); } if (!processor.process(inputProtocol, outputProtocol, connectionContext) || !inputProtocol.transport.peek() ) { // Something went fundamentlly wrong or there is nothing more to // process, close the connection. break; } } } catch (TTransportException ttx) { if (ttx.type() != TTransportException.Type.END_OF_FILE) { logError("Client died unexpectedly: %s", ttx); } } catch (Exception e) { logError("Uncaught exception: %s", e); } if (eventHandler) { eventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol); } try { inputTransport.close(); } catch (TTransportException ttx) { logError("Input close failed: %s", ttx); } try { outputTransport.close(); } catch (TTransportException ttx) { logError("Output close failed: %s", ttx); } try { client.close(); } catch (TTransportException ttx) { logError("Client close failed: %s", ttx); } } try { serverTransport_.close(); } catch (TServerTransportException e) { logError("Server transport failed to close(): %s", e); } } } unittest { import thrift.internal.test.server; testServeCancel!TSimpleServer(); } thrift-0.23.0/lib/d/src/thrift/server/base.d0000664000175000017500000001260215165535636021043 0ustar00buildbuild00000000000000/* * 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. */ module thrift.server.base; import std.variant : Variant; import thrift.protocol.base; import thrift.protocol.binary; import thrift.protocol.processor; import thrift.server.transport.base; import thrift.transport.base; import thrift.util.cancellation; /** * Base class for all Thrift servers. * * By setting the eventHandler property to a TServerEventHandler * implementation, custom code can be integrated into the processing pipeline, * which can be used e.g. for gathering statistics. */ class TServer { /** * Starts serving. * * Blocks until the server finishes, i.e. a serious problem occurred or the * cancellation request has been triggered. * * Server implementations are expected to implement cancellation in a best- * effort way – usually, it should be possible to immediately stop accepting * connections and return after all currently active clients have been * processed, but this might not be the case for every conceivable * implementation. */ abstract void serve(TCancellation cancellation = null); /// The server event handler to notify. Null by default. TServerEventHandler eventHandler; protected: this( TProcessor processor, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory ) { this(processor, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory); } this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory ) { this(processorFactory, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory); } this( TProcessor processor, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory ) { this(new TSingletonProcessorFactory(processor), serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); } this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory ) { import std.exception; import thrift.base; enforce(inputTransportFactory, new TException("Input transport factory must not be null.")); enforce(outputTransportFactory, new TException("Output transport factory must not be null.")); enforce(inputProtocolFactory, new TException("Input protocol factory must not be null.")); enforce(outputProtocolFactory, new TException("Output protocol factory must not be null.")); processorFactory_ = processorFactory; serverTransport_ = serverTransport; inputTransportFactory_ = inputTransportFactory; outputTransportFactory_ = outputTransportFactory; inputProtocolFactory_ = inputProtocolFactory; outputProtocolFactory_ = outputProtocolFactory; } TProcessorFactory processorFactory_; TServerTransport serverTransport_; TTransportFactory inputTransportFactory_; TTransportFactory outputTransportFactory_; TProtocolFactory inputProtocolFactory_; TProtocolFactory outputProtocolFactory_; public: @property TProcessorFactory processorFactory() { return processorFactory_; } @property TServerTransport serverTransport() { return serverTransport_; } @property TTransportFactory inputTransportFactory() { return inputTransportFactory_; } @property TTransportFactory outputTransportFactory() { return outputTransportFactory_; } @property TProtocolFactory inputProtocolFactory() { return inputProtocolFactory_; } @property TProtocolFactory outputProtocolFactory() { return outputProtocolFactory_; } } /** * Handles events from a TServer core. */ interface TServerEventHandler { /** * Called before the server starts accepting connections. */ void preServe(); /** * Called when a new client has connected and processing is about to begin. */ Variant createContext(TProtocol input, TProtocol output); /** * Called when request handling for a client has been finished – can be used * to perform clean up work. */ void deleteContext(Variant serverContext, TProtocol input, TProtocol output); /** * Called when the processor for a client call is about to be invoked. */ void preProcess(Variant serverContext, TTransport transport); } thrift-0.23.0/lib/d/src/thrift/server/threaded.d0000664000175000017500000001436715165535636021723 0ustar00buildbuild00000000000000/* * 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. */ module thrift.server.threaded; import core.thread; import std.variant : Variant; import thrift.base; import thrift.protocol.base; import thrift.protocol.processor; import thrift.server.base; import thrift.server.transport.base; import thrift.transport.base; import thrift.util.cancellation; /** * A simple threaded server which spawns a new thread per connection. */ class TThreadedServer : TServer { /// this( TProcessor processor, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory ) { super(processor, serverTransport, transportFactory, protocolFactory); } /// this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory ) { super(processorFactory, serverTransport, transportFactory, protocolFactory); } /// this( TProcessor processor, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory ) { super(processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); } /// this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory ) { super(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); } override void serve(TCancellation cancellation = null) { try { // Start the server listening serverTransport_.listen(); } catch (TTransportException ttx) { logError("listen() failed: %s", ttx); return; } if (eventHandler) eventHandler.preServe(); auto workerThreads = new ThreadGroup(); while (true) { TTransport client; TTransport inputTransport; TTransport outputTransport; TProtocol inputProtocol; TProtocol outputProtocol; try { client = serverTransport_.accept(cancellation); scope(failure) client.close(); inputTransport = inputTransportFactory_.getTransport(client); scope(failure) inputTransport.close(); outputTransport = outputTransportFactory_.getTransport(client); scope(failure) outputTransport.close(); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); } catch (TCancelledException tce) { break; } catch (TTransportException ttx) { logError("TServerTransport failed on accept: %s", ttx); continue; } catch (TException tx) { logError("Caught TException on accept: %s", tx); continue; } auto info = TConnectionInfo(inputProtocol, outputProtocol, client); auto processor = processorFactory_.getProcessor(info); auto worker = new WorkerThread(client, inputProtocol, outputProtocol, processor, eventHandler); workerThreads.add(worker); worker.start(); } try { serverTransport_.close(); } catch (TServerTransportException e) { logError("Server transport failed to close: %s", e); } workerThreads.joinAll(); } } // The worker thread handling a client connection. private class WorkerThread : Thread { this(TTransport client, TProtocol inputProtocol, TProtocol outputProtocol, TProcessor processor, TServerEventHandler eventHandler) { client_ = client; inputProtocol_ = inputProtocol; outputProtocol_ = outputProtocol; processor_ = processor; eventHandler_ = eventHandler; super(&run); } void run() { Variant connectionContext; if (eventHandler_) { connectionContext = eventHandler_.createContext(inputProtocol_, outputProtocol_); } try { while (true) { if (eventHandler_) { eventHandler_.preProcess(connectionContext, client_); } if (!processor_.process(inputProtocol_, outputProtocol_, connectionContext) || !inputProtocol_.transport.peek() ) { // Something went fundamentlly wrong or there is nothing more to // process, close the connection. break; } } } catch (TTransportException ttx) { if (ttx.type() != TTransportException.Type.END_OF_FILE) { logError("Client died unexpectedly: %s", ttx); } } catch (Exception e) { logError("Uncaught exception: %s", e); } if (eventHandler_) { eventHandler_.deleteContext(connectionContext, inputProtocol_, outputProtocol_); } try { inputProtocol_.transport.close(); } catch (TTransportException ttx) { logError("Input close failed: %s", ttx); } try { outputProtocol_.transport.close(); } catch (TTransportException ttx) { logError("Output close failed: %s", ttx); } try { client_.close(); } catch (TTransportException ttx) { logError("Client close failed: %s", ttx); } } private: TTransport client_; TProtocol inputProtocol_; TProtocol outputProtocol_; TProcessor processor_; TServerEventHandler eventHandler_; } unittest { import thrift.internal.test.server; testServeCancel!TThreadedServer(); } thrift-0.23.0/lib/d/src/thrift/server/taskpool.d0000664000175000017500000002240415165535636021766 0ustar00buildbuild00000000000000/* * 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. */ module thrift.server.taskpool; import core.sync.condition; import core.sync.mutex; import std.exception : enforce; import std.parallelism; import std.variant : Variant; import thrift.base; import thrift.protocol.base; import thrift.protocol.processor; import thrift.server.base; import thrift.server.transport.base; import thrift.transport.base; import thrift.util.cancellation; /** * A server which dispatches client requests to a std.parallelism TaskPool. */ class TTaskPoolServer : TServer { /// this( TProcessor processor, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory, TaskPool taskPool = null ) { this(processor, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, taskPool); } /// this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory, TaskPool taskPool = null ) { this(processorFactory, serverTransport, transportFactory, transportFactory, protocolFactory, protocolFactory, taskPool); } /// this( TProcessor processor, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TaskPool taskPool = null ) { this(new TSingletonProcessorFactory(processor), serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); } /// this( TProcessorFactory processorFactory, TServerTransport serverTransport, TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TaskPool taskPool = null ) { super(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory); if (taskPool) { this.taskPool = taskPool; } else { auto ptp = std.parallelism.taskPool; if (ptp.size > 0) { taskPool_ = ptp; } else { // If the global task pool is empty (default on a single-core machine), // create a new one with a single worker thread. The rationale for this // is to avoid that an application which worked fine with no task pool // explicitly set on the multi-core developer boxes suddenly fails on a // single-core user machine. taskPool_ = new TaskPool(1); taskPool_.isDaemon = true; } } } override void serve(TCancellation cancellation = null) { serverTransport_.listen(); if (eventHandler) eventHandler.preServe(); auto queueState = QueueState(); while (true) { // Check if we can still handle more connections. if (maxActiveConns) { synchronized (queueState.mutex) { while (queueState.activeConns >= maxActiveConns) { queueState.connClosed.wait(); } } } TTransport client; TTransport inputTransport; TTransport outputTransport; TProtocol inputProtocol; TProtocol outputProtocol; try { client = serverTransport_.accept(cancellation); scope(failure) client.close(); inputTransport = inputTransportFactory_.getTransport(client); scope(failure) inputTransport.close(); outputTransport = outputTransportFactory_.getTransport(client); scope(failure) outputTransport.close(); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); } catch (TCancelledException tce) { break; } catch (TTransportException ttx) { logError("TServerTransport failed on accept: %s", ttx); continue; } catch (TException tx) { logError("Caught TException on accept: %s", tx); continue; } auto info = TConnectionInfo(inputProtocol, outputProtocol, client); auto processor = processorFactory_.getProcessor(info); synchronized (queueState.mutex) { ++queueState.activeConns; } taskPool_.put(task!worker(queueState, client, inputProtocol, outputProtocol, processor, eventHandler)); } // First, stop accepting new connections. try { serverTransport_.close(); } catch (TServerTransportException e) { logError("Server transport failed to close: %s", e); } // Then, wait until all active connections are finished. synchronized (queueState.mutex) { while (queueState.activeConns > 0) { queueState.connClosed.wait(); } } } /** * Sets the task pool to use. * * By default, the global std.parallelism taskPool instance is used, which * might not be appropriate for many applications, e.g. where tuning the * number of worker threads is desired. (On single-core systems, a private * task pool with a single thread is used by default, since the global * taskPool instance has no worker threads then.) * * Note: TTaskPoolServer expects that tasks are never dropped from the pool, * e.g. by calling TaskPool.close() while there are still tasks in the * queue. If this happens, serve() will never return. */ void taskPool(TaskPool pool) @property { enforce(pool !is null, "Cannot use a null task pool."); enforce(pool.size > 0, "Cannot use a task pool with no worker threads."); taskPool_ = pool; } /** * The maximum number of client connections open at the same time. Zero for * no limit, which is the default. * * If this limit is reached, no clients are accept()ed from the server * transport any longer until another connection has been closed again. */ size_t maxActiveConns; protected: TaskPool taskPool_; } // Cannot be private as worker has to be passed as alias parameter to // another module. // private { /* * The state of the »connection queue«, i.e. used for keeping track of how * many client connections are currently processed. */ struct QueueState { /// Protects the queue state. Mutex mutex; /// The number of active connections (from the time they are accept()ed /// until they are closed when the worked task finishes). size_t activeConns; /// Signals that the number of active connections has been decreased, i.e. /// that a connection has been closed. Condition connClosed; /// Returns an initialized instance. static QueueState opCall() { QueueState q; q.mutex = new Mutex; q.connClosed = new Condition(q.mutex); return q; } } void worker(ref QueueState queueState, TTransport client, TProtocol inputProtocol, TProtocol outputProtocol, TProcessor processor, TServerEventHandler eventHandler) { scope (exit) { synchronized (queueState.mutex) { assert(queueState.activeConns > 0); --queueState.activeConns; queueState.connClosed.notifyAll(); } } Variant connectionContext; if (eventHandler) { connectionContext = eventHandler.createContext(inputProtocol, outputProtocol); } try { while (true) { if (eventHandler) { eventHandler.preProcess(connectionContext, client); } if (!processor.process(inputProtocol, outputProtocol, connectionContext) || !inputProtocol.transport.peek() ) { // Something went fundamentlly wrong or there is nothing more to // process, close the connection. break; } } } catch (TTransportException ttx) { if (ttx.type() != TTransportException.Type.END_OF_FILE) { logError("Client died unexpectedly: %s", ttx); } } catch (Exception e) { logError("Uncaught exception: %s", e); } if (eventHandler) { eventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol); } try { inputProtocol.transport.close(); } catch (TTransportException ttx) { logError("Input close failed: %s", ttx); } try { outputProtocol.transport.close(); } catch (TTransportException ttx) { logError("Output close failed: %s", ttx); } try { client.close(); } catch (TTransportException ttx) { logError("Client close failed: %s", ttx); } } // } unittest { import thrift.internal.test.server; testServeCancel!TTaskPoolServer(); } thrift-0.23.0/lib/d/src/thrift/server/transport/0000775000175000017500000000000015165535636022017 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/server/transport/socket.d0000664000175000017500000002572215165535636023464 0ustar00buildbuild00000000000000/* * 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. */ module thrift.server.transport.socket; import core.thread : dur, Duration, Thread; import core.stdc.string : strerror; import std.array : empty; import std.conv : text, to; import std.exception : enforce; import std.socket; import thrift.base; import thrift.internal.socket; import thrift.server.transport.base; import thrift.transport.base; import thrift.transport.socket; import thrift.util.awaitable; import thrift.util.cancellation; private alias TServerTransportException STE; /** * Server socket implementation of TServerTransport. * * Maps to std.socket listen()/accept(); only provides TCP/IP sockets (i.e. no * Unix sockets) for now, because they are not supported in std.socket. */ class TServerSocket : TServerTransport { /** * Constructs a new instance. * * Params: * port = The TCP port to listen at (host is always 0.0.0.0). * sendTimeout = The socket sending timeout. * recvTimout = The socket receiving timeout. */ this(ushort port, Duration sendTimeout = dur!"hnsecs"(0), Duration recvTimeout = dur!"hnsecs"(0)) { port_ = port; sendTimeout_ = sendTimeout; recvTimeout_ = recvTimeout; cancellationNotifier_ = new TSocketNotifier; socketSet_ = new SocketSet; } /// The port the server socket listens at. ushort port() const @property { return port_; } /// The socket sending timeout, zero to block infinitely. void sendTimeout(Duration sendTimeout) @property { sendTimeout_ = sendTimeout; } /// The socket receiving timeout, zero to block infinitely. void recvTimeout(Duration recvTimeout) @property { recvTimeout_ = recvTimeout; } /// The maximum number of listening retries if it fails. void retryLimit(ushort retryLimit) @property { retryLimit_ = retryLimit; } /// The delay between a listening attempt failing and retrying it. void retryDelay(Duration retryDelay) @property { retryDelay_ = retryDelay; } /// The size of the TCP send buffer, in bytes. void tcpSendBuffer(int tcpSendBuffer) @property { tcpSendBuffer_ = tcpSendBuffer; } /// The size of the TCP receiving buffer, in bytes. void tcpRecvBuffer(int tcpRecvBuffer) @property { tcpRecvBuffer_ = tcpRecvBuffer; } /// Whether to listen on IPv6 only, if IPv6 support is detected /// (default: false). void ipv6Only(bool value) @property { ipv6Only_ = value; } override void listen() { enforce(!isListening, new STE(STE.Type.ALREADY_LISTENING)); serverSocket_ = makeSocketAndListen(port_, ACCEPT_BACKLOG, retryLimit_, retryDelay_, tcpSendBuffer_, tcpRecvBuffer_, ipv6Only_); } override void close() { enforce(isListening, new STE(STE.Type.NOT_LISTENING)); serverSocket_.shutdown(SocketShutdown.BOTH); serverSocket_.close(); serverSocket_ = null; } override bool isListening() @property { return serverSocket_ !is null; } /// Number of connections listen() backlogs. enum ACCEPT_BACKLOG = 1024; override TTransport accept(TCancellation cancellation = null) { enforce(isListening, new STE(STE.Type.NOT_LISTENING)); if (cancellation) cancellationNotifier_.attach(cancellation.triggering); scope (exit) if (cancellation) cancellationNotifier_.detach(); // Too many EINTRs is a fault condition and would need to be handled // manually by our caller, but we can tolerate a certain number. enum MAX_EINTRS = 10; uint numEintrs; while (true) { socketSet_.reset(); socketSet_.add(serverSocket_); socketSet_.add(cancellationNotifier_.socket); auto ret = Socket.select(socketSet_, null, null); enforce(ret != 0, new STE("Socket.select() returned 0.", STE.Type.RESOURCE_FAILED)); if (ret < 0) { // Select itself failed, check if it was just due to an interrupted // syscall. if (getSocketErrno() == INTERRUPTED_ERRNO) { if (numEintrs++ < MAX_EINTRS) { continue; } else { throw new STE("Socket.select() was interrupted by a signal (EINTR) " ~ "more than " ~ to!string(MAX_EINTRS) ~ " times.", STE.Type.RESOURCE_FAILED ); } } throw new STE("Unknown error on Socket.select(): " ~ socketErrnoString(getSocketErrno()), STE.Type.RESOURCE_FAILED); } else { // Check for a ping on the interrupt socket. if (socketSet_.isSet(cancellationNotifier_.socket)) { cancellation.throwIfTriggered(); } // Check for the actual server socket having a connection waiting. if (socketSet_.isSet(serverSocket_)) { break; } } } try { auto client = createTSocket(serverSocket_.accept()); client.sendTimeout = sendTimeout_; client.recvTimeout = recvTimeout_; return client; } catch (SocketException e) { throw new STE("Unknown error on accepting: " ~ to!string(e), STE.Type.RESOURCE_FAILED); } } protected: /** * Allows derived classes to create a different TSocket type. */ TSocket createTSocket(Socket socket) { return new TSocket(socket); } private: ushort port_; Duration sendTimeout_; Duration recvTimeout_; ushort retryLimit_; Duration retryDelay_; uint tcpSendBuffer_; uint tcpRecvBuffer_; bool ipv6Only_; Socket serverSocket_; TSocketNotifier cancellationNotifier_; // Keep socket set between accept() calls to avoid reallocating. SocketSet socketSet_; } Socket makeSocketAndListen(ushort port, int backlog, ushort retryLimit, Duration retryDelay, uint tcpSendBuffer = 0, uint tcpRecvBuffer = 0, bool ipv6Only = false ) { Address localAddr; try { // null represents the wildcard address. auto addrInfos = getAddressInfo(null, to!string(port), AddressInfoFlags.PASSIVE, SocketType.STREAM, ProtocolType.TCP); foreach (i, ai; addrInfos) { // Prefer to bind to IPv6 addresses, because then IPv4 is listened to as // well, but not the other way round. if (ai.family == AddressFamily.INET6 || i == (addrInfos.length - 1)) { localAddr = ai.address; break; } } } catch (Exception e) { throw new STE("Could not determine local address to listen on.", STE.Type.RESOURCE_FAILED, __FILE__, __LINE__, e); } Socket socket; try { socket = new Socket(localAddr.addressFamily, SocketType.STREAM, ProtocolType.TCP); } catch (SocketException e) { throw new STE("Could not create accepting socket: " ~ to!string(e), STE.Type.RESOURCE_FAILED); } try { socket.setOption(SocketOptionLevel.IPV6, SocketOption.IPV6_V6ONLY, ipv6Only); } catch (SocketException e) { // This is somewhat expected on older systems (e.g. pre-Vista Windows), // which do not support the IPV6_V6ONLY flag yet. Racy flag just to avoid // log spew in unit tests. shared static warned = false; if (!warned) { logError("Could not set IPV6_V6ONLY socket option: %s", e); warned = true; } } alias SocketOptionLevel.SOCKET lvlSock; // Prevent 2 maximum segement lifetime delay on accept. try { socket.setOption(lvlSock, SocketOption.REUSEADDR, true); } catch (SocketException e) { throw new STE("Could not set REUSEADDR socket option: " ~ to!string(e), STE.Type.RESOURCE_FAILED); } // Set TCP buffer sizes. if (tcpSendBuffer > 0) { try { socket.setOption(lvlSock, SocketOption.SNDBUF, tcpSendBuffer); } catch (SocketException e) { throw new STE("Could not set socket send buffer size: " ~ to!string(e), STE.Type.RESOURCE_FAILED); } } if (tcpRecvBuffer > 0) { try { socket.setOption(lvlSock, SocketOption.RCVBUF, tcpRecvBuffer); } catch (SocketException e) { throw new STE("Could not set receive send buffer size: " ~ to!string(e), STE.Type.RESOURCE_FAILED); } } // Turn linger off to avoid blocking on socket close. try { Linger l; l.on = 0; l.time = 0; socket.setOption(lvlSock, SocketOption.LINGER, l); } catch (SocketException e) { throw new STE("Could not disable socket linger: " ~ to!string(e), STE.Type.RESOURCE_FAILED); } // Set TCP_NODELAY. try { socket.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, true); } catch (SocketException e) { throw new STE("Could not disable Nagle's algorithm: " ~ to!string(e), STE.Type.RESOURCE_FAILED); } ushort retries; while (true) { try { socket.bind(localAddr); break; } catch (SocketException) {} // If bind() worked, we breaked outside the loop above. retries++; if (retries < retryLimit) { Thread.sleep(retryDelay); } else { throw new STE(text("Could not bind to address: ", localAddr), STE.Type.RESOURCE_FAILED); } } socket.listen(backlog); return socket; } unittest { // Test interrupt(). { auto sock = new TServerSocket(0); sock.listen(); scope (exit) sock.close(); auto cancellation = new TCancellationOrigin; auto intThread = new Thread({ // Sleep for a bit until the socket is accepting. Thread.sleep(dur!"msecs"(50)); cancellation.trigger(); }); intThread.start(); import std.exception; assertThrown!TCancelledException(sock.accept(cancellation)); } // Test receive() timeout on accepted client sockets. { immutable port = 11122; auto timeout = dur!"msecs"(500); auto serverSock = new TServerSocket(port, timeout, timeout); serverSock.listen(); scope (exit) serverSock.close(); auto clientSock = new TSocket("127.0.0.1", port); clientSock.open(); scope (exit) clientSock.close(); shared bool hasTimedOut; auto recvThread = new Thread({ auto sock = serverSock.accept(); ubyte[1] data; try { sock.read(data); } catch (TTransportException e) { if (e.type == TTransportException.Type.TIMED_OUT) { hasTimedOut = true; } else { import std.stdio; stderr.writeln(e); } } }); recvThread.isDaemon = true; recvThread.start(); // Wait for the timeout, with a little bit of spare time. Thread.sleep(timeout + dur!"msecs"(50)); enforce(hasTimedOut, "Client socket receive() blocked for longer than recvTimeout."); } } thrift-0.23.0/lib/d/src/thrift/server/transport/base.d0000664000175000017500000000756515165535636023113 0ustar00buildbuild00000000000000/* * 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. */ module thrift.server.transport.base; import thrift.base; import thrift.transport.base; import thrift.util.cancellation; /** * Some kind of I/O device enabling servers to listen for incoming client * connections and communicate with them via a TTransport interface. */ interface TServerTransport { /** * Starts listening for server connections. * * Just as simliar functions commonly found in socket libraries, this * function does not block. * * If the socket is already listening, nothing happens. * * Throws: TServerTransportException if listening failed or the transport * was already listening. */ void listen(); /** * Closes the server transport, causing it to stop listening. * * Throws: TServerTransportException if the transport was not listening. */ void close(); /** * Returns whether the server transport is currently listening. */ bool isListening() @property; /** * Accepts a client connection and returns an opened TTransport for it, * never returning null. * * Blocks until a client connection is available. * * Params: * cancellation = If triggered, requests the call to stop blocking and * return with a TCancelledException. Implementations are free to * ignore this if they cannot provide a reasonable. * * Throws: TServerTransportException if accepting failed, * TCancelledException if it was cancelled. */ TTransport accept(TCancellation cancellation = null) out (result) { assert(result !is null); } } /** * Server transport exception. */ class TServerTransportException : TException { /** * Error codes for the various types of exceptions. */ enum Type { /// UNKNOWN, /// The server socket is not listening, but excepted to be. NOT_LISTENING, /// The server socket is already listening, but expected not to be. ALREADY_LISTENING, /// An operation on the primary underlying resource, e.g. a socket used /// for accepting connections, failed. RESOURCE_FAILED } /// this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this(errorMsg(type), type, file, line, next); } /// this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this(msg, Type.UNKNOWN, file, line, next); } /// this(string msg, Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); type_ = type; } /// Type type() const nothrow @property { return type_; } protected: Type type_; private: string errorMsg(Type type) { string msg = "TTransportException: "; switch (type) { case Type.UNKNOWN: msg ~= "Unknown server transport exception"; break; case Type.NOT_LISTENING: msg ~= "Server transport not listening"; break; case Type.ALREADY_LISTENING: msg ~= "Server transport already listening"; break; case Type.RESOURCE_FAILED: msg ~= "An underlying resource failed"; break; default: msg ~= "(Invalid exception type)"; break; } return msg; } } thrift-0.23.0/lib/d/src/thrift/server/transport/ssl.d0000664000175000017500000000527715165535636023000 0ustar00buildbuild00000000000000/* * 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. */ module thrift.server.transport.ssl; import std.datetime : Duration; import std.exception : enforce; import std.socket : Socket; import thrift.server.transport.socket; import thrift.transport.base; import thrift.transport.socket; import thrift.transport.ssl; /** * A server transport implementation using SSL-encrypted sockets. * * Note: * On Posix systems which do not have the BSD-specific SO_NOSIGPIPE flag, you * might want to ignore the SIGPIPE signal, as OpenSSL might try to write to * a closed socket if the peer disconnects abruptly: * --- * import core.stdc.signal; * import core.sys.posix.signal; * signal(SIGPIPE, SIG_IGN); * --- * * See: thrift.transport.ssl. */ class TSSLServerSocket : TServerSocket { /** * Creates a new TSSLServerSocket. * * Params: * port = The port on which to listen. * sslContext = The TSSLContext to use for creating client * sockets. Must be in server-side mode. */ this(ushort port, TSSLContext sslContext) { super(port); setSSLContext(sslContext); } /** * Creates a new TSSLServerSocket. * * Params: * port = The port on which to listen. * sendTimeout = The send timeout to set on the client sockets. * recvTimeout = The receive timeout to set on the client sockets. * sslContext = The TSSLContext to use for creating client * sockets. Must be in server-side mode. */ this(ushort port, Duration sendTimeout, Duration recvTimeout, TSSLContext sslContext) { super(port, sendTimeout, recvTimeout); setSSLContext(sslContext); } protected: override TSocket createTSocket(Socket socket) { return new TSSLSocket(sslContext_, socket); } private: void setSSLContext(TSSLContext sslContext) { enforce(sslContext.serverSide, new TTransportException( "Need server-side SSL socket factory for TSSLServerSocket")); sslContext_ = sslContext; } TSSLContext sslContext_; } thrift-0.23.0/lib/d/src/thrift/codegen/0000775000175000017500000000000015165535636020061 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/codegen/processor.d0000664000175000017500000004172615165535636022257 0ustar00buildbuild00000000000000/* * 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. */ module thrift.codegen.processor; import std.algorithm : find; import std.array : empty, front; import std.conv : to; import std.traits : ParameterTypeTuple, ReturnType, Unqual; import std.typetuple : allSatisfy, TypeTuple; import std.variant : Variant; import thrift.base; import thrift.codegen.base; import thrift.internal.codegen; import thrift.internal.ctfe; import thrift.protocol.base; import thrift.protocol.processor; /** * Service processor for Interface, which implements TProcessor by * synchronously forwarding requests for the service methods to a handler * implementing Interface. * * The generated class implements TProcessor and additionally allows a * TProcessorEventHandler to be specified via the public eventHandler property. * The constructor takes a single argument of type Interface, which is the * handler to forward the requests to: * --- * this(Interface iface); * TProcessorEventHandler eventHandler; * --- * * If Interface is derived from another service BaseInterface, this class is * also derived from TServiceProcessor!BaseInterface. * * The optional Protocols template tuple parameter can be used to specify * one or more TProtocol implementations to specifically generate code for. If * the actual types of the protocols passed to process() at runtime match one * of the items from the list, the optimized code paths are taken, otherwise, * a generic TProtocol version is used as fallback. For cases where the input * and output protocols differ, TProtocolPair!(InputProtocol, OutputProtocol) * can be used in the Protocols list: * --- * interface FooService { void foo(); } * class FooImpl { override void foo {} } * * // Provides fast path if TBinaryProtocol!TBufferedTransport is used for * // both input and output: * alias TServiceProcessor!(FooService, TBinaryProtocol!TBufferedTransport) * BinaryProcessor; * * auto proc = new BinaryProcessor(new FooImpl()); * * // Low overhead. * proc.process(tBinaryProtocol(tBufferTransport(someSocket))); * * // Not in the specialization list – higher overhead. * proc.process(tBinaryProtocol(tFramedTransport(someSocket))); * * // Same as above, but optimized for the Compact protocol backed by a * // TPipedTransport for input and a TBufferedTransport for output. * alias TServiceProcessor!(FooService, TProtocolPair!( * TCompactProtocol!TPipedTransport, TCompactProtocol!TBufferedTransport) * ) MixedProcessor; * --- */ template TServiceProcessor(Interface, Protocols...) if ( isService!Interface && allSatisfy!(isTProtocolOrPair, Protocols) ) { mixin({ static if (is(Interface BaseInterfaces == super) && BaseInterfaces.length > 0) { static assert(BaseInterfaces.length == 1, "Services cannot be derived from more than one parent."); string code = "class TServiceProcessor : " ~ "TServiceProcessor!(BaseService!Interface) {\n"; code ~= "private Interface iface_;\n"; string constructorCode = "this(Interface iface) {\n"; constructorCode ~= "super(iface);\n"; constructorCode ~= "iface_ = iface;\n"; } else { string code = "class TServiceProcessor : TProcessor {"; code ~= q{ override bool process(TProtocol iprot, TProtocol oprot, Variant context = Variant() ) { auto msg = iprot.readMessageBegin(); void writeException(TApplicationException e) { oprot.writeMessageBegin(TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); e.write(oprot); oprot.writeMessageEnd(); oprot.transport.writeEnd(); oprot.transport.flush(); } if (msg.type != TMessageType.CALL && msg.type != TMessageType.ONEWAY) { skip(iprot, TType.STRUCT); iprot.readMessageEnd(); iprot.transport.readEnd(); writeException(new TApplicationException( TApplicationException.Type.INVALID_MESSAGE_TYPE)); return false; } auto dg = msg.name in processMap_; if (!dg) { skip(iprot, TType.STRUCT); iprot.readMessageEnd(); iprot.transport.readEnd(); writeException(new TApplicationException("Invalid method name: '" ~ msg.name ~ "'.", TApplicationException.Type.INVALID_MESSAGE_TYPE)); return false; } (*dg)(msg.seqid, iprot, oprot, context); return true; } TProcessorEventHandler eventHandler; alias void delegate(int, TProtocol, TProtocol, Variant) ProcessFunc; protected ProcessFunc[string] processMap_; private Interface iface_; }; string constructorCode = "this(Interface iface) {\n"; constructorCode ~= "iface_ = iface;\n"; } // Generate the handling code for each method, consisting of the dispatch // function, registering it in the constructor, and the actual templated // handler function. foreach (methodName; FilterMethodNames!(Interface, __traits(derivedMembers, Interface)) ) { // Register the processing function in the constructor. immutable procFuncName = "process_" ~ methodName; immutable dispatchFuncName = procFuncName ~ "_protocolDispatch"; constructorCode ~= "processMap_[`" ~ methodName ~ "`] = &" ~ dispatchFuncName ~ ";\n"; bool methodMetaFound; TMethodMeta methodMeta; static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) { enum meta = find!`a.name == b`(Interface.methodMeta, methodName); if (!meta.empty) { methodMetaFound = true; methodMeta = meta.front; } } // The dispatch function to call the specialized handler functions. We // test the protocols if they can be converted to one of the passed // protocol types, and if not, fall back to the generic TProtocol // version of the processing function. code ~= "void " ~ dispatchFuncName ~ "(int seqid, TProtocol iprot, TProtocol oprot, Variant context) {\n"; code ~= "foreach (Protocol; TypeTuple!(Protocols, TProtocol)) {\n"; code ~= q{ static if (is(Protocol _ : TProtocolPair!(I, O), I, O)) { alias I IProt; alias O OProt; } else { alias Protocol IProt; alias Protocol OProt; } auto castedIProt = cast(IProt)iprot; auto castedOProt = cast(OProt)oprot; }; code ~= "if (castedIProt && castedOProt) {\n"; code ~= procFuncName ~ "!(IProt, OProt)(seqid, castedIProt, castedOProt, context);\n"; code ~= "return;\n"; code ~= "}\n"; code ~= "}\n"; code ~= "throw new TException(`Internal error: Null iprot/oprot " ~ "passed to processor protocol dispatch function.`);\n"; code ~= "}\n"; // The actual handler function, templated on the input and output // protocol types. code ~= "void " ~ procFuncName ~ "(IProt, OProt)(int seqid, IProt " ~ "iprot, OProt oprot, Variant connectionContext) " ~ "if (isTProtocol!IProt && isTProtocol!OProt) {\n"; code ~= "TArgsStruct!(Interface, `" ~ methodName ~ "`) args;\n"; // Store the (qualified) method name in a manifest constant to avoid // having to litter the code below with lots of string manipulation. code ~= "enum methodName = `" ~ methodName ~ "`;\n"; code ~= q{ enum qName = Interface.stringof ~ "." ~ methodName; Variant callContext; if (eventHandler) { callContext = eventHandler.createContext(qName, connectionContext); } scope (exit) { if (eventHandler) { eventHandler.deleteContext(callContext, qName); } } if (eventHandler) eventHandler.preRead(callContext, qName); args.read(iprot); iprot.readMessageEnd(); iprot.transport.readEnd(); if (eventHandler) eventHandler.postRead(callContext, qName); }; code ~= "TResultStruct!(Interface, `" ~ methodName ~ "`) result;\n"; code ~= "try {\n"; // Generate the parameter list to pass to the called iface function. string[] paramList; foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) { string paramName; if (methodMetaFound && i < methodMeta.params.length) { paramName = methodMeta.params[i].name; } else { paramName = "param" ~ to!string(i + 1); } paramList ~= "args." ~ paramName; } immutable call = "iface_." ~ methodName ~ "(" ~ ctfeJoin(paramList) ~ ")"; if (is(ReturnType!(mixin("Interface." ~ methodName)) == void)) { code ~= call ~ ";\n"; } else { code ~= "result.set!`success`(" ~ call ~ ");\n"; } // If this is not a oneway method, generate the receiving code. if (!methodMetaFound || methodMeta.type != TMethodType.ONEWAY) { if (methodMetaFound) { foreach (e; methodMeta.exceptions) { code ~= "} catch (Interface." ~ e.type ~ " " ~ e.name ~ ") {\n"; code ~= "result.set!`" ~ e.name ~ "`(" ~ e.name ~ ");\n"; } } code ~= "}\n"; code ~= q{ catch (Exception e) { if (eventHandler) { eventHandler.handlerError(callContext, qName, e); } auto x = new TApplicationException(to!string(e)); oprot.writeMessageBegin( TMessage(methodName, TMessageType.EXCEPTION, seqid)); x.write(oprot); oprot.writeMessageEnd(); oprot.transport.writeEnd(); oprot.transport.flush(); return; } if (eventHandler) eventHandler.preWrite(callContext, qName); oprot.writeMessageBegin(TMessage(methodName, TMessageType.REPLY, seqid)); result.write(oprot); oprot.writeMessageEnd(); oprot.transport.writeEnd(); oprot.transport.flush(); if (eventHandler) eventHandler.postWrite(callContext, qName); }; } else { // For oneway methods, we obviously cannot notify the client of any // exceptions, just call the event handler if one is set. code ~= "}\n"; code ~= q{ catch (Exception e) { if (eventHandler) { eventHandler.handlerError(callContext, qName, e); } return; } if (eventHandler) eventHandler.onewayComplete(callContext, qName); }; } code ~= "}\n"; } code ~= constructorCode ~ "}\n"; code ~= "}\n"; return code; }()); } /** * A struct representing the arguments of a Thrift method call. * * There should usually be no reason to use this directly without the help of * TServiceProcessor, but it is documented publicly to help debugging in case * of CTFE errors. * * Consider this example: * --- * interface Foo { * int bar(string a, bool b); * * enum methodMeta = [ * TMethodMeta("bar", [TParamMeta("a", 1), TParamMeta("b", 2)]) * ]; * } * * alias TArgsStruct!(Foo, "bar") FooBarArgs; * --- * * The definition of FooBarArgs is equivalent to: * --- * struct FooBarArgs { * string a; * bool b; * * mixin TStructHelpers!([TFieldMeta("a", 1, TReq.OPT_IN_REQ_OUT), * TFieldMeta("b", 2, TReq.OPT_IN_REQ_OUT)]); * } * --- * * If the TVerboseCodegen version is defined, a warning message is issued at * compilation if no TMethodMeta for Interface.methodName is found. */ template TArgsStruct(Interface, string methodName) { static assert(is(typeof(mixin("Interface." ~ methodName))), "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'."); mixin({ bool methodMetaFound; TMethodMeta methodMeta; static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) { auto meta = find!`a.name == b`(Interface.methodMeta, methodName); if (!meta.empty) { methodMetaFound = true; methodMeta = meta.front; } } string memberCode; string[] fieldMetaCodes; foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) { // If we have no meta information, just use param1, param2, etc. as // field names, it shouldn't really matter anyway. 1-based »indexing« // is used to match the common scheme in the Thrift world. string memberId; string memberName; if (methodMetaFound && i < methodMeta.params.length) { memberId = to!string(methodMeta.params[i].id); memberName = methodMeta.params[i].name; } else { memberId = to!string(i + 1); memberName = "param" ~ to!string(i + 1); } // Unqual!() is needed to generate mutable fields for ref const() // struct parameters. memberCode ~= "Unqual!(ParameterTypeTuple!(Interface." ~ methodName ~ ")[" ~ to!string(i) ~ "])" ~ memberName ~ ";\n"; fieldMetaCodes ~= "TFieldMeta(`" ~ memberName ~ "`, " ~ memberId ~ ", TReq.OPT_IN_REQ_OUT)"; } string code = "struct TArgsStruct {\n"; code ~= memberCode; version (TVerboseCodegen) { if (!methodMetaFound && ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0) { code ~= "pragma(msg, `[thrift.codegen.processor.TArgsStruct] Warning: No " ~ "meta information for method '" ~ methodName ~ "' in service '" ~ Interface.stringof ~ "' found.`);\n"; } } immutable fieldMetaCode = fieldMetaCodes.empty ? "" : "[" ~ ctfeJoin(fieldMetaCodes) ~ "]"; code ~= "mixin TStructHelpers!(" ~ fieldMetaCode ~ ");\n"; code ~= "}\n"; return code; }()); } /** * A struct representing the result of a Thrift method call. * * It contains a field called "success" for the return value of the function * (with id 0), and additional fields for the exceptions declared for the * method, if any. * * There should usually be no reason to use this directly without the help of * TServiceProcessor, but it is documented publicly to help debugging in case * of CTFE errors. * * Consider the following example: * --- * interface Foo { * int bar(string a); * * alias .FooException FooException; * * enum methodMeta = [ * TMethodMeta("bar", * [TParamMeta("a", 1)], * [TExceptionMeta("fooe", 1, "FooException")] * ) * ]; * } * alias TResultStruct!(Foo, "bar") FooBarResult; * --- * * The definition of FooBarResult is equivalent to: * --- * struct FooBarResult { * int success; * FooException fooe; * * mixin(TStructHelpers!([TFieldMeta("success", 0, TReq.OPTIONAL), * TFieldMeta("fooe", 1, TReq.OPTIONAL)])); * } * --- * * If the TVerboseCodegen version is defined, a warning message is issued at * compilation if no TMethodMeta for Interface.methodName is found. */ template TResultStruct(Interface, string methodName) { static assert(is(typeof(mixin("Interface." ~ methodName))), "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'."); mixin({ string code = "struct TResultStruct {\n"; string[] fieldMetaCodes; static if (!is(ReturnType!(mixin("Interface." ~ methodName)) == void)) { code ~= "ReturnType!(Interface." ~ methodName ~ ") success;\n"; fieldMetaCodes ~= "TFieldMeta(`success`, 0, TReq.OPTIONAL)"; } bool methodMetaFound; static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) { auto meta = find!`a.name == b`(Interface.methodMeta, methodName); if (!meta.empty) { foreach (e; meta.front.exceptions) { code ~= "Interface." ~ e.type ~ " " ~ e.name ~ ";\n"; fieldMetaCodes ~= "TFieldMeta(`" ~ e.name ~ "`, " ~ to!string(e.id) ~ ", TReq.OPTIONAL)"; } methodMetaFound = true; } } version (TVerboseCodegen) { if (!methodMetaFound && ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0) { code ~= "pragma(msg, `[thrift.codegen.processor.TResultStruct] Warning: No " ~ "meta information for method '" ~ methodName ~ "' in service '" ~ Interface.stringof ~ "' found.`);\n"; } } immutable fieldMetaCode = fieldMetaCodes.empty ? "" : "[" ~ ctfeJoin(fieldMetaCodes) ~ "]"; code ~= "mixin TStructHelpers!(" ~ fieldMetaCode ~ ");\n"; code ~= "}\n"; return code; }()); } thrift-0.23.0/lib/d/src/thrift/codegen/async_client.d0000664000175000017500000002232715165535636022707 0ustar00buildbuild00000000000000/* * 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. */ module thrift.codegen.async_client; import std.conv : text, to; import std.traits : ParameterStorageClass, ParameterStorageClassTuple, ParameterTypeTuple, ReturnType; import thrift.base; import thrift.async.base; import thrift.codegen.base; import thrift.codegen.client; import thrift.internal.codegen; import thrift.internal.ctfe; import thrift.protocol.base; import thrift.transport.base; import thrift.util.cancellation; import thrift.util.future; /** * Asynchronous Thrift service client which returns the results as TFutures an * uses a TAsyncManager to perform the actual work. * * TAsyncClientBase serves as a supertype for all TAsyncClients for the same * service, which might be instantiated with different concrete protocol types * (there is no covariance for template type parameters), and extends * TFutureInterface!Interface. If Interface is derived from another service * BaseInterface, it also extends TAsyncClientBase!BaseInterface. * * TAsyncClient implements TAsyncClientBase and offers two constructors with * the following signatures: * --- * this(TAsyncTransport trans, TTransportFactory tf, TProtocolFactory pf); * this(TAsyncTransport trans, TTransportFactory itf, TTransportFactory otf, * TProtocolFactory ipf, TProtocolFactory opf); * --- * * Again, if Interface represents a derived Thrift service, * TAsyncClient!Interface is also derived from TAsyncClient!BaseInterface. * * TAsyncClient can exclusively be used with TAsyncTransports, as it needs to * access the associated TAsyncManager. To set up any wrapper transports * (e.g. buffered, framed) on top of it and to instanciate the protocols to use, * TTransportFactory and TProtocolFactory instances are passed to the * constructors – the three argument constructor is a shortcut if the same * transport and protocol are to be used for both input and output, which is * the most common case. * * If the same transport factory is passed for both input and output transports, * only a single wrapper transport will be created and used for both directions. * This allows easy implementation of protocols like SSL. * * Just as TClient does, TAsyncClient also takes two optional template * arguments which can be used for specifying the actual TProtocol * implementation used for optimization purposes, as virtual calls can * completely be eliminated then. If the actual types of the protocols * instantiated by the factories used does not match the ones statically * specified in the template parameters, a TException is thrown during * construction. * * Example: * --- * // A simple Thrift service. * interface Foo { int foo(); } * * // Create a TAsyncSocketManager – thrift.async.libevent is used for this * // example. * auto manager = new TLibeventAsyncManager; * * // Set up an async transport to use. * auto socket = new TAsyncSocket(manager, host, port); * * // Create a client instance. * auto client = new TAsyncClient!Foo( * socket, * new TBufferedTransportFactory, // Wrap the socket in a TBufferedTransport. * new TBinaryProtocolFactory!() // Use the Binary protocol. * ); * * // Call foo and use the returned future. * auto result = client.foo(); * pragma(msg, typeof(result)); // TFuture!int * int resultValue = result.waitGet(); // Waits until the result is available. * --- */ interface TAsyncClientBase(Interface) if (isBaseService!Interface) : TFutureInterface!Interface { /** * The underlying TAsyncTransport used by this client instance. */ TAsyncTransport transport() @property; } /// Ditto interface TAsyncClientBase(Interface) if (isDerivedService!Interface) : TAsyncClientBase!(BaseService!Interface), TFutureInterface!Interface {} /// Ditto template TAsyncClient(Interface, InputProtocol = TProtocol, OutputProtocol = void) if ( isService!Interface && isTProtocol!InputProtocol && (isTProtocol!OutputProtocol || is(OutputProtocol == void)) ) { mixin({ static if (isDerivedService!Interface) { string code = "class TAsyncClient : " ~ "TAsyncClient!(BaseService!Interface, InputProtocol, OutputProtocol), " ~ "TAsyncClientBase!Interface {\n"; code ~= q{ this(TAsyncTransport trans, TTransportFactory tf, TProtocolFactory pf) { this(trans, tf, tf, pf, pf); } this(TAsyncTransport trans, TTransportFactory itf, TTransportFactory otf, TProtocolFactory ipf, TProtocolFactory opf ) { super(trans, itf, otf, ipf, opf); client_ = new typeof(client_)(iprot_, oprot_); } private TClient!(Interface, IProt, OProt) client_; }; } else { string code = "class TAsyncClient : TAsyncClientBase!Interface {"; code ~= q{ alias InputProtocol IProt; static if (isTProtocol!OutputProtocol) { alias OutputProtocol OProt; } else { static assert(is(OutputProtocol == void)); alias InputProtocol OProt; } this(TAsyncTransport trans, TTransportFactory tf, TProtocolFactory pf) { this(trans, tf, tf, pf, pf); } this(TAsyncTransport trans, TTransportFactory itf, TTransportFactory otf, TProtocolFactory ipf, TProtocolFactory opf ) { import std.exception; transport_ = trans; auto ip = itf.getTransport(trans); TTransport op = void; if (itf == otf) { op = ip; } else { op = otf.getTransport(trans); } auto iprot = ipf.getProtocol(ip); iprot_ = cast(IProt)iprot; enforce(iprot_, new TException(text("Input protocol not of the " ~ "specified concrete type (", IProt.stringof, ")."))); auto oprot = opf.getProtocol(op); oprot_ = cast(OProt)oprot; enforce(oprot_, new TException(text("Output protocol not of the " ~ "specified concrete type (", OProt.stringof, ")."))); client_ = new typeof(client_)(iprot_, oprot_); } override TAsyncTransport transport() @property { return transport_; } protected TAsyncTransport transport_; protected IProt iprot_; protected OProt oprot_; private TClient!(Interface, IProt, OProt) client_; }; } foreach (methodName; FilterMethodNames!(Interface, __traits(derivedMembers, Interface)) ) { string[] paramList; string[] paramNames; foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) { immutable paramName = "param" ~ to!string(i + 1); immutable storage = ParameterStorageClassTuple!( mixin("Interface." ~ methodName))[i]; paramList ~= ((storage & ParameterStorageClass.ref_) ? "ref " : "") ~ "ParameterTypeTuple!(Interface." ~ methodName ~ ")[" ~ to!string(i) ~ "] " ~ paramName; paramNames ~= paramName; } paramList ~= "TCancellation cancellation = null"; immutable returnTypeCode = "ReturnType!(Interface." ~ methodName ~ ")"; code ~= "TFuture!(" ~ returnTypeCode ~ ") " ~ methodName ~ "(" ~ ctfeJoin(paramList) ~ ") {\n"; // Create the future instance that will repesent the result. code ~= "auto promise = new TPromise!(" ~ returnTypeCode ~ ");\n"; // Prepare delegate which executes the TClient method call. code ~= "auto work = {\n"; code ~= "try {\n"; code ~= "static if (is(ReturnType!(Interface." ~ methodName ~ ") == void)) {\n"; code ~= "client_." ~ methodName ~ "(" ~ ctfeJoin(paramNames) ~ ");\n"; code ~= "promise.succeed();\n"; code ~= "} else {\n"; code ~= "auto result = client_." ~ methodName ~ "(" ~ ctfeJoin(paramNames) ~ ");\n"; code ~= "promise.succeed(result);\n"; code ~= "}\n"; code ~= "} catch (Exception e) {\n"; code ~= "promise.fail(e);\n"; code ~= "}\n"; code ~= "};\n"; // If the request is cancelled, set the result promise to cancelled // as well. This could be moved into an additional TAsyncWorkItem // delegate parameter. code ~= q{ if (cancellation) { cancellation.triggering.addCallback({ promise.cancel(); }); } }; // Enqueue the work item and immediately return the promise (resp. its // future interface). code ~= "transport_.asyncManager.execute(transport_, work, cancellation);\n"; code ~= "return promise;\n"; code ~= "}\n"; } code ~= "}\n"; return code; }()); } thrift-0.23.0/lib/d/src/thrift/codegen/async_client_pool.d0000664000175000017500000006707115165535636023745 0ustar00buildbuild00000000000000/* * 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. */ /** * Utilities for asynchronously querying multiple servers, building on * TAsyncClient. * * Terminology note: The names of the artifacts defined in this module are * derived from »client pool«, because they operate on a pool of * TAsyncClients. However, from a architectural point of view, they often * represent a pool of hosts a Thrift client application communicates with * using RPC calls. */ module thrift.codegen.async_client_pool; import core.sync.mutex; import core.time : Duration, dur; import std.algorithm : map; import std.array : array, empty; import std.exception : enforce; import std.traits : ParameterTypeTuple, ReturnType; import thrift.base; import thrift.codegen.base; import thrift.codegen.async_client; import thrift.internal.algorithm; import thrift.internal.codegen; import thrift.util.awaitable; import thrift.util.cancellation; import thrift.util.future; import thrift.internal.resource_pool; /** * Represents a generic client pool which implements TFutureInterface!Interface * using multiple TAsyncClients. */ interface TAsyncClientPoolBase(Interface) if (isService!Interface) : TFutureInterface!Interface { /// Shorthand for the client type this pool operates on. alias TAsyncClientBase!Interface Client; /** * Adds a client to the pool. */ void addClient(Client client); /** * Removes a client from the pool. * * Returns: Whether the client was found in the pool. */ bool removeClient(Client client); /** * Called to determine whether an exception comes from a client from the * pool not working properly, or if it an exception thrown at the * application level. * * If the delegate returns true, the server/connection is considered to be * at fault, if it returns false, the exception is just passed on to the * caller. * * By default, returns true for instances of TTransportException and * TApplicationException, false otherwise. */ bool delegate(Exception) rpcFaultFilter() const @property; void rpcFaultFilter(bool delegate(Exception)) @property; /// Ditto /** * Whether to open the underlying transports of a client before trying to * execute a method if they are not open. This is usually desirable * because it allows e.g. to automatically reconnect to a remote server * if the network connection is dropped. * * Defaults to true. */ bool reopenTransports() const @property; void reopenTransports(bool) @property; /// Ditto } immutable bool delegate(Exception) defaultRpcFaultFilter; shared static this() { defaultRpcFaultFilter = (Exception e) { import thrift.protocol.base; import thrift.transport.base; return ( (cast(TTransportException)e !is null) || (cast(TApplicationException)e !is null) ); }; } /** * A TAsyncClientPoolBase implementation which queries multiple servers in a * row until a request succeeds, the result of which is then returned. * * The definition of »success« can be customized using the rpcFaultFilter() * delegate property. If it is non-null and calling it for an exception set by * a failed method invocation returns true, the error is considered to be * caused by the RPC layer rather than the application layer, and the next * server in the pool is tried. If there are no more clients to try, the * operation is marked as failed with a TCompoundOperationException. * * If a TAsyncClient in the pool fails with an RPC exception for a number of * consecutive tries, it is temporarily disabled (not tried any longer) for * a certain duration. Both the limit and the timeout can be configured. If all * clients fail (and keepTrying is false), the operation fails with a * TCompoundOperationException which contains the collected RPC exceptions. */ final class TAsyncClientPool(Interface) if (isService!Interface) : TAsyncClientPoolBase!Interface { /// this(Client[] clients) { pool_ = new TResourcePool!Client(clients); rpcFaultFilter_ = defaultRpcFaultFilter; reopenTransports_ = true; } /+override+/ void addClient(Client client) { pool_.add(client); } /+override+/ bool removeClient(Client client) { return pool_.remove(client); } /** * Whether to keep trying to find a working client if all have failed in a * row. * * Defaults to false. */ bool keepTrying() const @property { return pool_.cycle; } /// Ditto void keepTrying(bool value) @property { pool_.cycle = value; } /** * Whether to use a random permutation of the client pool on every call to * execute(). This can be used e.g. as a simple form of load balancing. * * Defaults to true. */ bool permuteClients() const @property { return pool_.permute; } /// Ditto void permuteClients(bool value) @property { pool_.permute = value; } /** * The number of consecutive faults after which a client is disabled until * faultDisableDuration has passed. 0 to never disable clients. * * Defaults to 0. */ ushort faultDisableCount() const @property { return pool_.faultDisableCount; } /// Ditto void faultDisableCount(ushort value) @property { pool_.faultDisableCount = value; } /** * The duration for which a client is no longer considered after it has * failed too often. * * Defaults to one second. */ Duration faultDisableDuration() const @property { return pool_.faultDisableDuration; } /// Ditto void faultDisableDuration(Duration value) @property { pool_.faultDisableDuration = value; } /+override+/ bool delegate(Exception) rpcFaultFilter() const @property { return rpcFaultFilter_; } /+override+/ void rpcFaultFilter(bool delegate(Exception) value) @property { rpcFaultFilter_ = value; } /+override+/ bool reopenTransports() const @property { return reopenTransports_; } /+override+/ void reopenTransports(bool value) @property { reopenTransports_ = value; } mixin(fallbackPoolForwardCode!Interface()); protected: // The actual worker implementation to which RPC method calls are forwarded. auto executeOnPool(string method, Args...)(Args args, TCancellation cancellation ) { auto clients = pool_[]; if (clients.empty) { throw new TException("No clients available to try."); } auto promise = new TPromise!(ReturnType!(MemberType!(Interface, method))); Exception[] rpcExceptions; void tryNext() { while (clients.empty) { Client next; Duration waitTime; if (clients.willBecomeNonempty(next, waitTime)) { if (waitTime > dur!"hnsecs"(0)) { if (waitTime < dur!"usecs"(10)) { import core.thread; Thread.sleep(waitTime); } else { next.transport.asyncManager.delay(waitTime, { tryNext(); }); return; } } } else { promise.fail(new TCompoundOperationException("All clients failed.", rpcExceptions)); return; } } auto client = clients.front; clients.popFront; if (reopenTransports) { if (!client.transport.isOpen) { try { client.transport.open(); } catch (Exception e) { pool_.recordFault(client); tryNext(); return; } } } auto future = mixin("client." ~ method)(args, cancellation); future.completion.addCallback({ if (future.status == TFutureStatus.CANCELLED) { promise.cancel(); return; } auto e = future.getException(); if (e) { if (rpcFaultFilter_ && rpcFaultFilter_(e)) { pool_.recordFault(client); rpcExceptions ~= e; tryNext(); return; } } pool_.recordSuccess(client); promise.complete(future); }); } tryNext(); return promise; } private: TResourcePool!Client pool_; bool delegate(Exception) rpcFaultFilter_; bool reopenTransports_; } /** * TAsyncClientPool construction helper to avoid having to explicitly * specify the interface type, i.e. to allow the constructor being called * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)). */ TAsyncClientPool!Interface tAsyncClientPool(Interface)( TAsyncClientBase!Interface[] clients ) if (isService!Interface) { return new typeof(return)(clients); } private { // Cannot use an anonymous delegate literal for this because they aren't // allowed in class scope. string fallbackPoolForwardCode(Interface)() { string code = ""; foreach (methodName; AllMemberMethodNames!Interface) { enum qn = "Interface." ~ methodName; code ~= "TFuture!(ReturnType!(" ~ qn ~ ")) " ~ methodName ~ "(ParameterTypeTuple!(" ~ qn ~ ") args, TCancellation cancellation = null) {\n"; code ~= "return executeOnPool!(`" ~ methodName ~ "`)(args, cancellation);\n"; code ~= "}\n"; } return code; } } /** * A TAsyncClientPoolBase implementation which queries multiple servers at * the same time and returns the first success response. * * The definition of »success« can be customized using the rpcFaultFilter() * delegate property. If it is non-null and calling it for an exception set by * a failed method invocation returns true, the error is considered to be * caused by the RPC layer rather than the application layer, and the next * server in the pool is tried. If all clients fail, the operation is marked * as failed with a TCompoundOperationException. */ final class TAsyncFastestClientPool(Interface) if (isService!Interface) : TAsyncClientPoolBase!Interface { /// this(Client[] clients) { clients_ = clients; rpcFaultFilter_ = defaultRpcFaultFilter; reopenTransports_ = true; } /+override+/ void addClient(Client client) { clients_ ~= client; } /+override+/ bool removeClient(Client client) { auto oldLength = clients_.length; clients_ = removeEqual(clients_, client); return clients_.length < oldLength; } /+override+/ bool delegate(Exception) rpcFaultFilter() const @property { return rpcFaultFilter_; } /+override+/ void rpcFaultFilter(bool delegate(Exception) value) @property { rpcFaultFilter_ = value; } /+override+/bool reopenTransports() const @property { return reopenTransports_; } /+override+/ void reopenTransports(bool value) @property { reopenTransports_ = value; } mixin(fastestPoolForwardCode!Interface()); private: Client[] clients_; bool delegate(Exception) rpcFaultFilter_; bool reopenTransports_; } /** * TAsyncFastestClientPool construction helper to avoid having to explicitly * specify the interface type, i.e. to allow the constructor being called * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)). */ TAsyncFastestClientPool!Interface tAsyncFastestClientPool(Interface)( TAsyncClientBase!Interface[] clients ) if (isService!Interface) { return new typeof(return)(clients); } private { // Cannot use an anonymous delegate literal for this because they aren't // allowed in class scope. string fastestPoolForwardCode(Interface)() { string code = ""; foreach (methodName; AllMemberMethodNames!Interface) { enum qn = "Interface." ~ methodName; code ~= "TFuture!(ReturnType!(" ~ qn ~ ")) " ~ methodName ~ "(ParameterTypeTuple!(" ~ qn ~ ") args, " ~ "TCancellation cancellation = null) {\n"; code ~= "enum methodName = `" ~ methodName ~ "`;\n"; code ~= q{ alias ReturnType!(MemberType!(Interface, methodName)) ResultType; auto childCancellation = new TCancellationOrigin; TFuture!ResultType[] futures; futures.reserve(clients_.length); foreach (c; clients_) { if (reopenTransports) { if (!c.transport.isOpen) { try { c.transport.open(); } catch (Exception e) { continue; } } } futures ~= mixin("c." ~ methodName)(args, childCancellation); } return new FastestPoolJob!(ResultType)( futures, rpcFaultFilter, cancellation, childCancellation); }; code ~= "}\n"; } return code; } final class FastestPoolJob(Result) : TFuture!Result { this(TFuture!Result[] poolFutures, bool delegate(Exception) rpcFaultFilter, TCancellation cancellation, TCancellationOrigin childCancellation ) { resultPromise_ = new TPromise!Result; poolFutures_ = poolFutures; rpcFaultFilter_ = rpcFaultFilter; childCancellation_ = childCancellation; foreach (future; poolFutures) { future.completion.addCallback({ auto f = future; return { completionCallback(f); }; }()); if (future.status != TFutureStatus.RUNNING) { // If the current future is already completed, we are done, don't // bother adding callbacks for the others (they would just return // immediately after acquiring the lock). return; } } if (cancellation) { cancellation.triggering.addCallback({ resultPromise_.cancel(); childCancellation.trigger(); }); } } TFutureStatus status() const @property { return resultPromise_.status; } TAwaitable completion() @property { return resultPromise_.completion; } Result get() { return resultPromise_.get(); } Exception getException() { return resultPromise_.getException(); } private: void completionCallback(TFuture!Result future) { synchronized { if (future.status == TFutureStatus.CANCELLED) { assert(resultPromise_.status != TFutureStatus.RUNNING); return; } if (resultPromise_.status != TFutureStatus.RUNNING) { // The operation has already been completed. This can happen if // another client completed first, but this callback was already // waiting for the lock when it called cancel(). return; } if (future.status == TFutureStatus.FAILED) { auto e = future.getException(); if (rpcFaultFilter_ && rpcFaultFilter_(e)) { rpcExceptions_ ~= e; if (rpcExceptions_.length == poolFutures_.length) { resultPromise_.fail(new TCompoundOperationException( "All child operations failed, unable to retrieve a result.", rpcExceptions_ )); } return; } } // Store the result to the target promise. resultPromise_.complete(future); // Cancel the other futures, we would just discard their results. // Note: We do this after we have stored the results to our promise, // see the assert at the top of the function. childCancellation_.trigger(); } } TPromise!Result resultPromise_; TFuture!Result[] poolFutures_; Exception[] rpcExceptions_; bool delegate(Exception) rpcFaultFilter_; TCancellationOrigin childCancellation_; } } /** * Allows easily aggregating results from a number of TAsyncClients. * * Contrary to TAsync{Fallback, Fastest}ClientPool, this class does not * simply implement TFutureInterface!Interface. It manages a pool of clients, * but allows the user to specify a custom accumulator function to use or to * iterate over the results using a TFutureAggregatorRange. * * For each service method, TAsyncAggregator offers a method * accepting the same arguments, and an optional TCancellation instance, just * like with TFutureInterface. The return type, however, is a proxy object * that offers the following methods: * --- * /++ * + Returns a thrift.util.future.TFutureAggregatorRange for the results of * + the client pool method invocations. * + * + The [] (slicing) operator can also be used to obtain the range. * + * + Params: * + timeout = A timeout to pass to the TFutureAggregatorRange constructor, * + defaults to zero (no timeout). * +/ * TFutureAggregatorRange!ReturnType range(Duration timeout = dur!"hnsecs"(0)); * auto opSlice() { return range(); } /// Ditto * * /++ * + Returns a future that gathers the results from the clients in the pool * + and invokes a user-supplied accumulator function on them, returning its * + return value to the client. * + * + In addition to the TFuture!AccumulatedType interface (where * + AccumulatedType is the return type of the accumulator function), the * + returned object also offers two additional methods, finish() and * + finishGet(): By default, the accumulator functions is called after all * + the results from the pool clients have become available. Calling finish() * + causes the accumulator future to stop waiting for other results and * + immediately invoking the accumulator function on the results currently * + available. If all results are already available, finish() is a no-op. * + finishGet() is a convenience shortcut for combining it with * + a call to get() immediately afterwards, like waitGet() is for wait(). * + * + The acc alias can point to any callable accepting either an array of * + return values or an array of return values and an array of exceptions; * + see isAccumulator!() for details. The default accumulator concatenates * + return values that can be concatenated with each others (e.g. arrays), * + and simply returns an array of values otherwise, failing with a * + TCompoundOperationException no values were returned. * + * + The accumulator function is not executed in any of the async manager * + worker threads associated with the async clients, but instead it is * + invoked when the actual result is requested for the first time after the * + operation has been completed. This also includes checking the status * + of the operation once it is no longer running, since the accumulator * + has to be run to determine whether the operation succeeded or failed. * +/ * auto accumulate(alias acc = defaultAccumulator)() if (isAccumulator!acc); * --- * * Example: * --- * // Some Thrift service. * interface Foo { * int foo(string name); * byte[] bar(); * } * * // Create the aggregator pool – client0, client1, client2 are some * // TAsyncClient!Foo instances, but in theory could also be other * // TFutureInterface!Foo implementations (e.g. some async client pool). * auto pool = new TAsyncAggregator!Foo([client0, client1, client2]); * * foreach (val; pool.foo("baz").range(dur!"seconds"(1))) { * // Process all the results that are available before a second has passed, * // in the order they arrive. * writeln(val); * } * * auto sumRoots = pool.foo("baz").accumulate!((int[] vals, Exceptions[] exs){ * if (vals.empty) { * throw new TCompoundOperationException("All clients failed", exs); * } * * // Just to illustrate that the type of the values can change, convert the * // numbers to double and sum up their roots. * double result = 0; * foreach (v; vals) result += sqrt(cast(double)v); * return result; * })(); * * // Wait up to three seconds for the result, and then accumulate what has * // arrived so far. * sumRoots.completion.wait(dur!"seconds"(3)); * writeln(sumRoots.finishGet()); * * // For scalars, the default accumulator returns an array of the values. * pragma(msg, typeof(pool.foo("").accumulate().get()); // int[]. * * // For lists, etc., it concatenates the results together. * pragma(msg, typeof(pool.bar().accumulate().get())); // byte[]. * --- * * Note: For the accumulate!() interface, you might currently hit a »cannot use * local '…' as parameter to non-global template accumulate«-error, see * $(DMDBUG 5710, DMD issue 5710). If your accumulator function does not need * to access the surrounding scope, you might want to use a function literal * instead of a delegate to avoid the issue. */ class TAsyncAggregator(Interface) if (isBaseService!Interface) { /// Shorthand for the client type this instance operates on. alias TAsyncClientBase!Interface Client; /// this(Client[] clients) { clients_ = clients; } /// Whether to open the underlying transports of a client before trying to /// execute a method if they are not open. This is usually desirable /// because it allows e.g. to automatically reconnect to a remote server /// if the network connection is dropped. /// /// Defaults to true. bool reopenTransports = true; mixin AggregatorOpDispatch!(); private: Client[] clients_; } /// Ditto class TAsyncAggregator(Interface) if (isDerivedService!Interface) : TAsyncAggregator!(BaseService!Interface) { /// Shorthand for the client type this instance operates on. alias TAsyncClientBase!Interface Client; /// this(Client[] clients) { super(cast(TAsyncClientBase!(BaseService!Interface)[])clients); } mixin AggregatorOpDispatch!(); } /** * Whether fun is a valid accumulator function for values of type ValueType. * * For this to be true, fun must be a callable matching one of the following * argument lists: * --- * fun(ValueType[] values); * fun(ValueType[] values, Exception[] exceptions); * --- * * The second version is passed the collected array exceptions from all the * clients in the pool. * * The return value of the accumulator function is passed to the client (via * the result future). If it throws an exception, the operation is marked as * failed with the given exception instead. */ template isAccumulator(ValueType, alias fun) { enum isAccumulator = is(typeof(fun(cast(ValueType[])[]))) || is(typeof(fun(cast(ValueType[])[], cast(Exception[])[]))); } /** * TAsyncAggregator construction helper to avoid having to explicitly * specify the interface type, i.e. to allow the constructor being called * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)). */ TAsyncAggregator!Interface tAsyncAggregator(Interface)( TAsyncClientBase!Interface[] clients ) if (isService!Interface) { return new typeof(return)(clients); } private { mixin template AggregatorOpDispatch() { auto opDispatch(string name, Args...)(Args args) if ( is(typeof(mixin("Interface.init." ~ name)(args))) ) { alias ReturnType!(MemberType!(Interface, name)) ResultType; auto childCancellation = new TCancellationOrigin; TFuture!ResultType[] futures; futures.reserve(clients_.length); foreach (c; cast(Client[])clients_) { if (reopenTransports) { if (!c.transport.isOpen) { try { c.transport.open(); } catch (Exception e) { continue; } } } futures ~= mixin("c." ~ name)(args, childCancellation); } return AggregationResult!ResultType(futures, childCancellation); } } struct AggregationResult(T) { auto opSlice() { return range(); } auto range(Duration timeout = dur!"hnsecs"(0)) { return tFutureAggregatorRange(futures_, childCancellation_, timeout); } auto accumulate(alias acc = defaultAccumulator)() if (isAccumulator!(T, acc)) { return new AccumulatorJob!(T, acc)(futures_, childCancellation_); } private: TFuture!T[] futures_; TCancellationOrigin childCancellation_; } auto defaultAccumulator(T)(T[] values, Exception[] exceptions) { if (values.empty) { throw new TCompoundOperationException("All clients failed", exceptions); } static if (is(typeof(T.init ~ T.init))) { import std.algorithm; return reduce!"a ~ b"(values); } else { return values; } } final class AccumulatorJob(T, alias accumulator) if ( isAccumulator!(T, accumulator) ) : TFuture!(AccumulatorResult!(T, accumulator)) { this(TFuture!T[] futures, TCancellationOrigin childCancellation) { futures_ = futures; childCancellation_ = childCancellation; resultMutex_ = new Mutex; completionEvent_ = new TOneshotEvent; foreach (future; futures) { future.completion.addCallback({ auto f = future; return { synchronized (resultMutex_) { if (f.status == TFutureStatus.CANCELLED) { if (!finished_) { status_ = TFutureStatus.CANCELLED; finished_ = true; } return; } if (f.status == TFutureStatus.FAILED) { exceptions_ ~= f.getException(); } else { results_ ~= f.get(); } if (results_.length + exceptions_.length == futures_.length) { finished_ = true; completionEvent_.trigger(); } } }; }()); } } TFutureStatus status() @property { synchronized (resultMutex_) { if (!finished_) return TFutureStatus.RUNNING; if (status_ != TFutureStatus.RUNNING) return status_; try { result_ = invokeAccumulator!accumulator(results_, exceptions_); status_ = TFutureStatus.SUCCEEDED; } catch (Exception e) { exception_ = e; status_ = TFutureStatus.FAILED; } return status_; } } TAwaitable completion() @property { return completionEvent_; } AccumulatorResult!(T, accumulator) get() { auto s = status; enforce(s != TFutureStatus.RUNNING, new TFutureException("Operation not yet completed.")); if (s == TFutureStatus.CANCELLED) throw new TCancelledException; if (s == TFutureStatus.FAILED) throw exception_; return result_; } Exception getException() { auto s = status; enforce(s != TFutureStatus.RUNNING, new TFutureException("Operation not yet completed.")); if (s == TFutureStatus.CANCELLED) throw new TCancelledException; if (s == TFutureStatus.SUCCEEDED) { return null; } return exception_; } void finish() { synchronized (resultMutex_) { if (!finished_) { finished_ = true; childCancellation_.trigger(); completionEvent_.trigger(); } } } auto finishGet() { finish(); return get(); } private: TFuture!T[] futures_; TCancellationOrigin childCancellation_; bool finished_; T[] results_; Exception[] exceptions_; TFutureStatus status_; Mutex resultMutex_; union { AccumulatorResult!(T, accumulator) result_; Exception exception_; } TOneshotEvent completionEvent_; } auto invokeAccumulator(alias accumulator, T)( T[] values, Exception[] exceptions ) if ( isAccumulator!(T, accumulator) ) { static if (is(typeof(accumulator(values, exceptions)))) { return accumulator(values, exceptions); } else { return accumulator(values); } } template AccumulatorResult(T, alias acc) { alias typeof(invokeAccumulator!acc(cast(T[])[], cast(Exception[])[])) AccumulatorResult; } } thrift-0.23.0/lib/d/src/thrift/codegen/client.d0000664000175000017500000004004215165535636021504 0ustar00buildbuild00000000000000/* * 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. */ module thrift.codegen.client; import std.algorithm : find; import std.array : empty, front; import std.conv : to; import std.traits : isSomeFunction, ParameterStorageClass, ParameterStorageClassTuple, ParameterTypeTuple, ReturnType; import thrift.codegen.base; import thrift.internal.codegen; import thrift.internal.ctfe; import thrift.protocol.base; /** * Thrift service client, which implements an interface by synchronously * calling a server over a TProtocol. * * TClientBase simply extends Interface with generic input/output protocol * properties to serve as a supertype for all TClients for the same service, * which might be instantiated with different concrete protocol types (there * is no covariance for template type parameters). If Interface is derived * from another interface BaseInterface, it also extends * TClientBase!BaseInterface. * * TClient is the class that actually implements TClientBase. Just as * TClientBase, it is also derived from TClient!BaseInterface for inheriting * services. * * TClient takes two optional template arguments which can be used for * specifying the actual TProtocol implementation used for optimization * purposes, as virtual calls can completely be eliminated then. If * OutputProtocol is not specified, it is assumed to be the same as * InputProtocol. The protocol properties defined by TClientBase are exposed * with their concrete type (return type covariance). * * In addition to implementing TClientBase!Interface, TClient offers the * following constructors: * --- * this(InputProtocol iprot, OutputProtocol oprot); * // Only if is(InputProtocol == OutputProtocol), to use the same protocol * // for both input and output: * this(InputProtocol prot); * --- * * The sequence id of the method calls starts at zero and is automatically * incremented. */ interface TClientBase(Interface) if (isBaseService!Interface) : Interface { /** * The input protocol used by the client. */ TProtocol inputProtocol() @property; /** * The output protocol used by the client. */ TProtocol outputProtocol() @property; } /// Ditto interface TClientBase(Interface) if (isDerivedService!Interface) : TClientBase!(BaseService!Interface), Interface {} /// Ditto template TClient(Interface, InputProtocol = TProtocol, OutputProtocol = void) if ( isService!Interface && isTProtocol!InputProtocol && (isTProtocol!OutputProtocol || is(OutputProtocol == void)) ) { mixin({ static if (isDerivedService!Interface) { string code = "class TClient : TClient!(BaseService!Interface, " ~ "InputProtocol, OutputProtocol), TClientBase!Interface {\n"; code ~= q{ this(IProt iprot, OProt oprot) { super(iprot, oprot); } static if (is(IProt == OProt)) { this(IProt prot) { super(prot); } } // DMD @@BUG@@: If these are not present in this class (would be) // inherited anyway, »not implemented« errors are raised. override IProt inputProtocol() @property { return super.inputProtocol; } override OProt outputProtocol() @property { return super.outputProtocol; } }; } else { string code = "class TClient : TClientBase!Interface {"; code ~= q{ alias InputProtocol IProt; static if (isTProtocol!OutputProtocol) { alias OutputProtocol OProt; } else { static assert(is(OutputProtocol == void)); alias InputProtocol OProt; } this(IProt iprot, OProt oprot) { iprot_ = iprot; oprot_ = oprot; } static if (is(IProt == OProt)) { this(IProt prot) { this(prot, prot); } } IProt inputProtocol() @property { return iprot_; } OProt outputProtocol() @property { return oprot_; } protected IProt iprot_; protected OProt oprot_; protected int seqid_; }; } foreach (methodName; __traits(derivedMembers, Interface)) { static if (isSomeFunction!(mixin("Interface." ~ methodName))) { bool methodMetaFound; TMethodMeta methodMeta; static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) { enum meta = find!`a.name == b`(Interface.methodMeta, methodName); if (!meta.empty) { methodMetaFound = true; methodMeta = meta.front; } } // Generate the code for sending. string[] paramList; string paramAssignCode; foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) { // Use the param name speficied in the meta information if any – // just cosmetics in this case. string paramName; if (methodMetaFound && i < methodMeta.params.length) { paramName = methodMeta.params[i].name; } else { paramName = "param" ~ to!string(i + 1); } immutable storage = ParameterStorageClassTuple!( mixin("Interface." ~ methodName))[i]; paramList ~= ((storage & ParameterStorageClass.ref_) ? "ref " : "") ~ "ParameterTypeTuple!(Interface." ~ methodName ~ ")[" ~ to!string(i) ~ "] " ~ paramName; paramAssignCode ~= "args." ~ paramName ~ " = &" ~ paramName ~ ";\n"; } code ~= "ReturnType!(Interface." ~ methodName ~ ") " ~ methodName ~ "(" ~ ctfeJoin(paramList) ~ ") {\n"; code ~= "immutable methodName = `" ~ methodName ~ "`;\n"; immutable paramStructType = "TPargsStruct!(Interface, `" ~ methodName ~ "`)"; code ~= paramStructType ~ " args = " ~ paramStructType ~ "();\n"; code ~= paramAssignCode; code ~= "oprot_.writeMessageBegin(TMessage(`" ~ methodName ~ "`, "; code ~= ((methodMetaFound && methodMeta.type == TMethodType.ONEWAY) ? "TMessageType.ONEWAY" : "TMessageType.CALL"); code ~= ", ++seqid_));\n"; code ~= "args.write(oprot_);\n"; code ~= "oprot_.writeMessageEnd();\n"; code ~= "oprot_.transport.flush();\n"; // If this is not a oneway method, generate the receiving code. if (!methodMetaFound || methodMeta.type != TMethodType.ONEWAY) { code ~= "TPresultStruct!(Interface, `" ~ methodName ~ "`) result;\n"; if (!is(ReturnType!(mixin("Interface." ~ methodName)) == void)) { code ~= "ReturnType!(Interface." ~ methodName ~ ") _return;\n"; code ~= "result.success = &_return;\n"; } // TODO: The C++ implementation checks for matching method name here, // should we do as well? code ~= q{ auto msg = iprot_.readMessageBegin(); scope (exit) { iprot_.readMessageEnd(); iprot_.transport.readEnd(); } if (msg.type == TMessageType.EXCEPTION) { auto x = new TApplicationException(null); x.read(iprot_); iprot_.transport.readEnd(); throw x; } if (msg.type != TMessageType.REPLY) { skip(iprot_, TType.STRUCT); iprot_.transport.readEnd(); } if (msg.seqid != seqid_) { throw new TApplicationException( methodName ~ " failed: Out of sequence response.", TApplicationException.Type.BAD_SEQUENCE_ID ); } result.read(iprot_); }; if (methodMetaFound) { foreach (e; methodMeta.exceptions) { code ~= "if (result.isSet!`" ~ e.name ~ "`) throw result." ~ e.name ~ ";\n"; } } if (!is(ReturnType!(mixin("Interface." ~ methodName)) == void)) { code ~= q{ if (result.isSet!`success`) return _return; throw new TApplicationException( methodName ~ " failed: Unknown result.", TApplicationException.Type.MISSING_RESULT ); }; } } code ~= "}\n"; } } code ~= "}\n"; return code; }()); } /** * TClient construction helper to avoid having to explicitly specify * the protocol types, i.e. to allow the constructor being called using IFTI * (see $(DMDBUG 6082, D Bugzilla enhancement requet 6082)). */ TClient!(Interface, Prot) tClient(Interface, Prot)(Prot prot) if ( isService!Interface && isTProtocol!Prot ) { return new TClient!(Interface, Prot)(prot); } /// Ditto TClient!(Interface, IProt, Oprot) tClient(Interface, IProt, OProt) (IProt iprot, OProt oprot) if ( isService!Interface && isTProtocol!IProt && isTProtocol!OProt ) { return new TClient!(Interface, IProt, OProt)(iprot, oprot); } /** * Represents the arguments of a Thrift method call, as pointers to the (const) * parameter type to avoid copying. * * There should usually be no reason to use this struct directly without the * help of TClient, but it is documented publicly to help debugging in case * of CTFE errors. * * Consider this example: * --- * interface Foo { * int bar(string a, bool b); * * enum methodMeta = [ * TMethodMeta("bar", [TParamMeta("a", 1), TParamMeta("b", 2)]) * ]; * } * * alias TPargsStruct!(Foo, "bar") FooBarPargs; * --- * * The definition of FooBarPargs is equivalent to (ignoring the necessary * metadata to assign the field IDs): * --- * struct FooBarPargs { * const(string)* a; * const(bool)* b; * * void write(Protocol)(Protocol proto) const if (isTProtocol!Protocol); * } * --- */ template TPargsStruct(Interface, string methodName) { static assert(is(typeof(mixin("Interface." ~ methodName))), "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'."); mixin({ bool methodMetaFound; TMethodMeta methodMeta; static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) { auto meta = find!`a.name == b`(Interface.methodMeta, methodName); if (!meta.empty) { methodMetaFound = true; methodMeta = meta.front; } } string memberCode; string[] fieldMetaCodes; foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) { // If we have no meta information, just use param1, param2, etc. as // field names, it shouldn't really matter anyway. 1-based »indexing« // is used to match the common scheme in the Thrift world. string memberId; string memberName; if (methodMetaFound && i < methodMeta.params.length) { memberId = to!string(methodMeta.params[i].id); memberName = methodMeta.params[i].name; } else { memberId = to!string(i + 1); memberName = "param" ~ to!string(i + 1); } // Workaround for DMD @@BUG@@ 6056: make an intermediary alias for the // parameter type, and declare the member using const(memberNameType)*. memberCode ~= "alias ParameterTypeTuple!(Interface." ~ methodName ~ ")[" ~ to!string(i) ~ "] " ~ memberName ~ "Type;\n"; memberCode ~= "const(" ~ memberName ~ "Type)* " ~ memberName ~ ";\n"; fieldMetaCodes ~= "TFieldMeta(`" ~ memberName ~ "`, " ~ memberId ~ ", TReq.OPT_IN_REQ_OUT)"; } string code = "struct TPargsStruct {\n"; code ~= memberCode; version (TVerboseCodegen) { if (!methodMetaFound && ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0) { code ~= "pragma(msg, `[thrift.codegen.base.TPargsStruct] Warning: No " ~ "meta information for method '" ~ methodName ~ "' in service '" ~ Interface.stringof ~ "' found.`);\n"; } } code ~= "void write(P)(P proto) const if (isTProtocol!P) {\n"; code ~= "writeStruct!(typeof(this), P, [" ~ ctfeJoin(fieldMetaCodes) ~ "], true)(this, proto);\n"; code ~= "}\n"; code ~= "}\n"; return code; }()); } /** * Represents the result of a Thrift method call, using a pointer to the return * value to avoid copying. * * There should usually be no reason to use this struct directly without the * help of TClient, but it is documented publicly to help debugging in case * of CTFE errors. * * Consider this example: * --- * interface Foo { * int bar(string a); * * alias .FooException FooException; * * enum methodMeta = [ * TMethodMeta("bar", * [TParamMeta("a", 1)], * [TExceptionMeta("fooe", 1, "FooException")] * ) * ]; * } * alias TPresultStruct!(Foo, "bar") FooBarPresult; * --- * * The definition of FooBarPresult is equivalent to (ignoring the necessary * metadata to assign the field IDs): * --- * struct FooBarPresult { * int* success; * Foo.FooException fooe; * * struct IsSetFlags { * bool success; * } * IsSetFlags isSetFlags; * * bool isSet(string fieldName)() const @property; * void read(Protocol)(Protocol proto) if (isTProtocol!Protocol); * } * --- */ template TPresultStruct(Interface, string methodName) { static assert(is(typeof(mixin("Interface." ~ methodName))), "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'."); mixin({ string code = "struct TPresultStruct {\n"; string[] fieldMetaCodes; alias ReturnType!(mixin("Interface." ~ methodName)) ResultType; static if (!is(ResultType == void)) { code ~= q{ ReturnType!(mixin("Interface." ~ methodName))* success; }; fieldMetaCodes ~= "TFieldMeta(`success`, 0, TReq.OPTIONAL)"; static if (!isNullable!ResultType) { code ~= q{ struct IsSetFlags { bool success; } IsSetFlags isSetFlags; }; fieldMetaCodes ~= "TFieldMeta(`isSetFlags`, 0, TReq.IGNORE)"; } } bool methodMetaFound; static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) { auto meta = find!`a.name == b`(Interface.methodMeta, methodName); if (!meta.empty) { foreach (e; meta.front.exceptions) { code ~= "Interface." ~ e.type ~ " " ~ e.name ~ ";\n"; fieldMetaCodes ~= "TFieldMeta(`" ~ e.name ~ "`, " ~ to!string(e.id) ~ ", TReq.OPTIONAL)"; } methodMetaFound = true; } } version (TVerboseCodegen) { if (!methodMetaFound && ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0) { code ~= "pragma(msg, `[thrift.codegen.base.TPresultStruct] Warning: No " ~ "meta information for method '" ~ methodName ~ "' in service '" ~ Interface.stringof ~ "' found.`);\n"; } } code ~= q{ bool isSet(string fieldName)() const @property if ( is(MemberType!(typeof(this), fieldName)) ) { static if (fieldName == "success") { static if (isNullable!(typeof(*success))) { return *success !is null; } else { return isSetFlags.success; } } else { // We are dealing with an exception member, which, being a nullable // type (exceptions are always classes), has no isSet flag. return __traits(getMember, this, fieldName) !is null; } } }; code ~= "void read(P)(P proto) if (isTProtocol!P) {\n"; code ~= "readStruct!(typeof(this), P, [" ~ ctfeJoin(fieldMetaCodes) ~ "], true)(this, proto);\n"; code ~= "}\n"; code ~= "}\n"; return code; }()); } thrift-0.23.0/lib/d/src/thrift/codegen/base.d0000664000175000017500000010053015165535636021137 0ustar00buildbuild00000000000000/* * 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. */ /** * Code generation metadata and templates used for implementing struct * serialization. * * Many templates can be customized using field meta data, which is read from * a manifest constant member of the given type called fieldMeta (if present), * and is concatenated with the elements from the optional fieldMetaData * template alias parameter. * * Some code generation templates take account of the optional TVerboseCodegen * version declaration, which causes warning messages to be emitted if no * metadata for a field/method has been found and the default behavior is * used instead. If this version is not defined, the templates just silently * behave like the Thrift compiler does in this situation, i.e. automatically * assign negative ids (starting at -1) for fields and assume TReq.AUTO as * requirement level. */ // Implementation note: All the templates in here taking a field metadata // parameter should ideally have a constraint that restricts the alias to // TFieldMeta[]-typed values, but the is() expressions seems to always fail. module thrift.codegen.base; import std.algorithm : find; import std.array : empty, front; import std.conv : to; import std.exception : enforce; import std.traits : BaseTypeTuple, isPointer, isSomeFunction, PointerTarget, ReturnType; import thrift.base; import thrift.internal.codegen; import thrift.protocol.base; import thrift.util.hashset; /* * Thrift struct/service meta data, which is used to store information from * the interface definition files not representable in plain D, i.e. field * requirement levels, Thrift field IDs, etc. */ /** * Struct field requirement levels. */ enum TReq { /// Detect the requiredness from the field type: if it is nullable, treat /// the field as optional, if it is non-nullable, treat the field as /// required. This is the default used for handling structs not generated /// from an IDL file, and never emitted by the Thrift compiler. TReq.AUTO /// shouldn't be specified explicitly. // Implementation note: thrift.codegen templates use // thrift.internal.codegen.memberReq to resolve AUTO to REQUIRED/OPTIONAL // instead of handling it directly. AUTO, /// The field is treated as optional when deserializing/receiving the struct /// and as required when serializing/sending. This is the Thrift default if /// neither "required" nor "optional" are specified in the IDL file. OPT_IN_REQ_OUT, /// The field is optional. OPTIONAL, /// The field is required. REQUIRED, /// Ignore the struct field when serializing/deserializing. IGNORE } /** * The way how methods are called. */ enum TMethodType { /// Called in the normal two-way scheme consisting of a request and a /// response. REGULAR, /// A fire-and-forget one-way method, where no response is sent and the /// client immediately returns. ONEWAY } /** * Compile-time metadata for a struct field. */ struct TFieldMeta { /// The name of the field. Used for matching a TFieldMeta with the actual /// D struct member during code generation. string name; /// The (Thrift) id of the field. short id; /// Whether the field is requried. TReq req; /// A code string containing a D expression for the default value, if there /// is one. string defaultValue; } /** * Compile-time metadata for a service method. */ struct TMethodMeta { /// The name of the method. Used for matching a TMethodMeta with the actual /// method during code generation. string name; /// Meta information for the parameteres. TParamMeta[] params; /// Specifies which exceptions can be thrown by the method. All other /// exceptions are converted to a TApplicationException instead. TExceptionMeta[] exceptions; /// The fundamental type of the method. TMethodType type; } /** * Compile-time metadata for a service method parameter. */ struct TParamMeta { /// The name of the parameter. Contrary to TFieldMeta, it only serves /// decorative purposes here. string name; /// The Thrift id of the parameter in the param struct. short id; /// A code string containing a D expression for the default value for the /// parameter, if any. string defaultValue; } /** * Compile-time metadata for a service method exception annotation. */ struct TExceptionMeta { /// The name of the exception »return value«. Contrary to TFieldMeta, it /// only serves decorative purposes here, as it is only used in code not /// visible to processor implementations/service clients. string name; /// The Thrift id of the exception field in the return value struct. short id; /// The name of the exception type. string type; } /** * A pair of two TPorotocols. To be used in places where a list of protocols * is expected, for specifying different protocols for input and output. */ struct TProtocolPair(InputProtocol, OutputProtocol) if ( isTProtocol!InputProtocol && isTProtocol!OutputProtocol ) {} /** * true if T is a TProtocolPair. */ template isTProtocolPair(T) { static if (is(T _ == TProtocolPair!(I, O), I, O)) { enum isTProtocolPair = true; } else { enum isTProtocolPair = false; } } unittest { static assert(isTProtocolPair!(TProtocolPair!(TProtocol, TProtocol))); static assert(!isTProtocolPair!TProtocol); } /** * true if T is a TProtocol or a TProtocolPair. */ template isTProtocolOrPair(T) { enum isTProtocolOrPair = isTProtocol!T || isTProtocolPair!T; } unittest { static assert(isTProtocolOrPair!TProtocol); static assert(isTProtocolOrPair!(TProtocolPair!(TProtocol, TProtocol))); static assert(!isTProtocolOrPair!void); } /** * true if T represents a Thrift service. */ template isService(T) { enum isService = isBaseService!T || isDerivedService!T; } /** * true if T represents a Thrift service not derived from another service. */ template isBaseService(T) { static if(is(T _ == interface) && (!is(T TBases == super) || TBases.length == 0) ) { enum isBaseService = true; } else { enum isBaseService = false; } } /** * true if T represents a Thrift service derived from another service. */ template isDerivedService(T) { static if(is(T _ == interface) && is(T TBases == super) && TBases.length == 1 ) { enum isDerivedService = isService!(TBases[0]); } else { enum isDerivedService = false; } } /** * For derived services, gets the base service interface. */ template BaseService(T) if (isDerivedService!T) { alias BaseTypeTuple!T[0] BaseService; } /* * Code generation templates. */ /** * Mixin template defining additional helper methods for using a struct with * Thrift, and a member called isSetFlags if the struct contains any fields * for which an »is set« flag is needed. * * It can only be used inside structs or Exception classes. * * For example, consider the following struct definition: * --- * struct Foo { * string a; * int b; * int c; * * mixin TStructHelpers!([ * TFieldMeta("a", 1), // Implicitly optional (nullable). * TFieldMeta("b", 2), // Implicitly required (non-nullable). * TFieldMeta("c", 3, TReq.REQUIRED, "4") * ]); * } * --- * * TStructHelper adds the following methods to the struct: * --- * /++ * + Sets member fieldName to the given value and marks it as set. * + * + Examples: * + --- * + auto f = Foo(); * + f.set!"b"(12345); * + assert(f.isSet!"b"); * + --- * +/ * void set(string fieldName)(MemberType!(This, fieldName) value); * * /++ * + Resets member fieldName to the init property of its type and marks it as * + not set. * + * + Examples: * + --- * + // Set f.b to some value. * + auto f = Foo(); * + f.set!"b"(12345); * + * + f.unset!b(); * + * + // f.b is now unset again. * + assert(!f.isSet!"b"); * + --- * +/ * void unset(string fieldName)(); * * /++ * + Returns whether member fieldName is set. * + * + Examples: * + --- * + auto f = Foo(); * + assert(!f.isSet!"b"); * + f.set!"b"(12345); * + assert(f.isSet!"b"); * + --- * +/ * bool isSet(string fieldName)() const @property; * * /++ * + Returns a string representation of the struct. * + * + Examples: * + --- * + auto f = Foo(); * + f.a = "a string"; * + assert(f.toString() == `Foo("a string", 0 (unset), 4)`); * + --- * +/ * string toString() const; * * /++ * + Deserializes the struct, setting its members to the values read from the * + protocol. Forwards to readStruct(this, proto); * +/ * void read(Protocol)(Protocol proto) if (isTProtocol!Protocol); * * /++ * + Serializes the struct to the target protocol. Forwards to * + writeStruct(this, proto); * +/ * void write(Protocol)(Protocol proto) const if (isTProtocol!Protocol); * --- * * Additionally, an opEquals() implementation is provided which simply * compares all fields, but disregards the is set struct, if any (the exact * signature obviously differs between structs and exception classes). The * metadata is stored in a manifest constant called fieldMeta. * * Note: To set the default values for fields where one has been specified in * the field metadata, a parameterless static opCall is generated, because D * does not allow parameterless (default) constructors for structs. Thus, be * always to use to initialize structs: * --- * Foo foo; // Wrong! * auto foo = Foo(); // Correct. * --- */ mixin template TStructHelpers(alias fieldMetaData = cast(TFieldMeta[])null) if ( is(typeof(fieldMetaData) : TFieldMeta[]) ) { import std.algorithm : any; import thrift.codegen.base; import thrift.internal.codegen : isNullable, MemberType, mergeFieldMeta, FieldNames; import thrift.protocol.base : TProtocol, isTProtocol; alias typeof(this) This; static assert(is(This == struct) || is(This : Exception), "TStructHelpers can only be used inside a struct or an Exception class."); static if (TIsSetFlags!(This, fieldMetaData).tupleof.length > 0) { // If we need to keep isSet flags around, create an instance of the // container struct. TIsSetFlags!(This, fieldMetaData) isSetFlags; enum fieldMeta = fieldMetaData ~ [TFieldMeta("isSetFlags", 0, TReq.IGNORE)]; } else { enum fieldMeta = fieldMetaData; } void set(string fieldName)(MemberType!(This, fieldName) value) if ( is(MemberType!(This, fieldName)) ) { __traits(getMember, this, fieldName) = value; static if (is(typeof(mixin("this.isSetFlags." ~ fieldName)) : bool)) { __traits(getMember, this.isSetFlags, fieldName) = true; } } void unset(string fieldName)() if (is(MemberType!(This, fieldName))) { static if (is(typeof(mixin("this.isSetFlags." ~ fieldName)) : bool)) { __traits(getMember, this.isSetFlags, fieldName) = false; } __traits(getMember, this, fieldName) = MemberType!(This, fieldName).init; } bool isSet(string fieldName)() const @property if ( is(MemberType!(This, fieldName)) ) { static if (isNullable!(MemberType!(This, fieldName))) { return __traits(getMember, this, fieldName) !is null; } else static if (is(typeof(mixin("this.isSetFlags." ~ fieldName)) : bool)) { return __traits(getMember, this.isSetFlags, fieldName); } else { // This is a required field, which is always set. return true; } } static if (is(This _ == class)) { override string toString() const { return thriftToStringImpl(); } override bool opEquals(Object other) const { auto rhs = cast(This)other; if (rhs) { return thriftOpEqualsImpl(rhs); } return (cast()super).opEquals(other); } override size_t toHash() const { return thriftToHashImpl(); } } else { string toString() const { return thriftToStringImpl(); } bool opEquals(ref const This other) const { return thriftOpEqualsImpl(other); } size_t toHash() const @safe nothrow { return thriftToHashImpl(); } } private string thriftToStringImpl() const { import std.conv : to; string result = This.stringof ~ "("; mixin({ string code = ""; bool first = true; foreach (name; FieldNames!(This, fieldMeta)) { if (first) { first = false; } else { code ~= "result ~= `, `;\n"; } code ~= "result ~= `" ~ name ~ ": ` ~ to!string(cast()this." ~ name ~ ");\n"; code ~= "if (!isSet!q{" ~ name ~ "}) {\n"; code ~= "result ~= ` (unset)`;\n"; code ~= "}\n"; } return code; }()); result ~= ")"; return result; } private bool thriftOpEqualsImpl(const ref This rhs) const { foreach (name; FieldNames!This) { if (mixin("this." ~ name) != mixin("rhs." ~ name)) return false; } return true; } private size_t thriftToHashImpl() const @trusted nothrow { size_t hash = 0; foreach (i, _; this.tupleof) { auto val = this.tupleof[i]; hash += typeid(val).getHash(&val); } return hash; } static if (any!`!a.defaultValue.empty`(mergeFieldMeta!(This, fieldMetaData))) { static if (is(This _ == class)) { this() { mixin(thriftFieldInitCode!(mergeFieldMeta!(This, fieldMetaData))("this")); } } else { // DMD @@BUG@@: Have to use auto here to avoid »no size yet for forward // reference« errors. static auto opCall() { auto result = This.init; mixin(thriftFieldInitCode!(mergeFieldMeta!(This, fieldMetaData))("result")); return result; } } } void read(Protocol)(Protocol proto) if (isTProtocol!Protocol) { // Need to explicitly specify fieldMetaData here, since it isn't already // picked up in some situations (e.g. the TArgs struct for methods with // multiple parameters in async_test_servers) otherwise. Due to a DMD // @@BUG@@, we need to explicitly specify the other template parameters // as well. readStruct!(This, Protocol, fieldMetaData, false)(this, proto); } void write(Protocol)(Protocol proto) const if (isTProtocol!Protocol) { writeStruct!(This, Protocol, fieldMetaData, false)(this, proto); } } // DMD @@BUG@@: Having this inside TStructHelpers leads to weird lookup errors // (e.g. for std.arry.empty). string thriftFieldInitCode(alias fieldMeta)(string thisName) { string code = ""; foreach (field; fieldMeta) { if (field.defaultValue.empty) continue; code ~= thisName ~ "." ~ field.name ~ " = " ~ field.defaultValue ~ ";\n"; } return code; } unittest { // Cannot make this nested in the unittest block due to a »no size yet for // forward reference« error. static struct Foo { string a; int b; int c; mixin TStructHelpers!([ TFieldMeta("a", 1), TFieldMeta("b", 2, TReq.OPT_IN_REQ_OUT), TFieldMeta("c", 3, TReq.REQUIRED, "4") ]); } auto f = Foo(); f.set!"b"(12345); assert(f.isSet!"b"); f.unset!"b"(); assert(!f.isSet!"b"); f.set!"b"(12345); assert(f.isSet!"b"); f.unset!"b"(); f.a = "a string"; assert(f.toString() == `Foo(a: a string, b: 0 (unset), c: 4)`); } /** * Generates an eponymous struct with boolean flags for the non-required * non-nullable fields of T. * * Nullable fields are just set to null to signal »not set«, so no flag is * emitted for them, even if they are optional. * * In most cases, you do not want to use this directly, but via TStructHelpers * instead. */ template TIsSetFlags(T, alias fieldMetaData) { mixin({ string code = "struct TIsSetFlags {\n"; foreach (meta; fieldMetaData) { code ~= "static if (!is(MemberType!(T, `" ~ meta.name ~ "`))) {\n"; code ~= q{ static assert(false, "Field '" ~ meta.name ~ "' referenced in metadata not present in struct '" ~ T.stringof ~ "'."); }; code ~= "}"; if (meta.req == TReq.OPTIONAL || meta.req == TReq.OPT_IN_REQ_OUT) { code ~= "else static if (!isNullable!(MemberType!(T, `" ~ meta.name ~ "`))) {\n"; code ~= " bool " ~ meta.name ~ ";\n"; code ~= "}\n"; } } code ~= "}"; return code; }()); } /** * Deserializes a Thrift struct from a protocol. * * Using the Protocol template parameter, the concrete TProtocol to use can be * be specified. If the pointerStruct parameter is set to true, the struct * fields are expected to be pointers to the actual data. This is used * internally (combined with TPResultStruct) and usually should not be used in * user code. * * This is a free function to make it possible to read exisiting structs from * the wire without altering their definitions. */ void readStruct(T, Protocol, alias fieldMetaData = cast(TFieldMeta[])null, bool pointerStruct = false)(auto ref T s, Protocol p) if (isTProtocol!Protocol) { mixin({ string code; // Check that all fields for which there is meta info are actually in the // passed struct type. foreach (field; mergeFieldMeta!(T, fieldMetaData)) { code ~= "static assert(is(MemberType!(T, `" ~ field.name ~ "`)));\n"; } // Returns the code string for reading a value of type F off the wire and // assigning it to v. The level parameter is used to make sure that there // are no conflicting variable names on recursive calls. string readValueCode(ValueType)(string v, size_t level = 0) { // Some non-ambigous names to use (shadowing is not allowed in D). immutable i = "i" ~ to!string(level); immutable elem = "elem" ~ to!string(level); immutable key = "key" ~ to!string(level); immutable list = "list" ~ to!string(level); immutable map = "map" ~ to!string(level); immutable set = "set" ~ to!string(level); immutable value = "value" ~ to!string(level); alias FullyUnqual!ValueType F; static if (is(F == bool)) { return v ~ " = p.readBool();"; } else static if (is(F == byte)) { return v ~ " = p.readByte();"; } else static if (is(F == double)) { return v ~ " = p.readDouble();"; } else static if (is(F == short)) { return v ~ " = p.readI16();"; } else static if (is(F == int)) { return v ~ " = p.readI32();"; } else static if (is(F == long)) { return v ~ " = p.readI64();"; } else static if (is(F : string)) { return v ~ " = p.readString();"; } else static if (is(F == enum)) { return v ~ " = cast(typeof(" ~ v ~ "))p.readI32();"; } else static if (is(F _ : E[], E)) { return "{\n" ~ "auto " ~ list ~ " = p.readListBegin();\n" ~ // TODO: Check element type here? v ~ " = new typeof(" ~ v ~ "[0])[" ~ list ~ ".size];\n" ~ "foreach (" ~ i ~ "; 0 .. " ~ list ~ ".size) {\n" ~ readValueCode!E(v ~ "[" ~ i ~ "]", level + 1) ~ "\n" ~ "}\n" ~ "p.readListEnd();\n" ~ "}"; } else static if (is(F _ : V[K], K, V)) { return "{\n" ~ "auto " ~ map ~ " = p.readMapBegin();" ~ v ~ " = null;\n" ~ // TODO: Check key/value types here? "foreach (" ~ i ~ "; 0 .. " ~ map ~ ".size) {\n" ~ "FullyUnqual!(typeof(" ~ v ~ ".keys[0])) " ~ key ~ ";\n" ~ readValueCode!K(key, level + 1) ~ "\n" ~ "typeof(" ~ v ~ ".values[0]) " ~ value ~ ";\n" ~ readValueCode!V(value, level + 1) ~ "\n" ~ v ~ "[cast(typeof(" ~ v ~ ".keys[0]))" ~ key ~ "] = " ~ value ~ ";\n" ~ "}\n" ~ "p.readMapEnd();" ~ "}"; } else static if (is(F _ : HashSet!(E), E)) { return "{\n" ~ "auto " ~ set ~ " = p.readSetBegin();" ~ // TODO: Check element type here? v ~ " = new typeof(" ~ v ~ ")();\n" ~ "foreach (" ~ i ~ "; 0 .. " ~ set ~ ".size) {\n" ~ "typeof(" ~ v ~ "[][0]) " ~ elem ~ ";\n" ~ readValueCode!E(elem, level + 1) ~ "\n" ~ v ~ " ~= " ~ elem ~ ";\n" ~ "}\n" ~ "p.readSetEnd();" ~ "}"; } else static if (is(F == struct) || is(F : TException)) { static if (is(F == struct)) { auto result = v ~ " = typeof(" ~ v ~ ")();\n"; } else { auto result = v ~ " = new typeof(" ~ v ~ ")();\n"; } static if (__traits(compiles, F.init.read(TProtocol.init))) { result ~= v ~ ".read(p);"; } else { result ~= "readStruct(" ~ v ~ ", p);"; } return result; } else { static assert(false, "Cannot represent type in Thrift: " ~ F.stringof); } } string readFieldCode(FieldType)(string name, short id, TReq req) { static if (pointerStruct && isPointer!FieldType) { immutable v = "(*s." ~ name ~ ")"; alias PointerTarget!FieldType F; } else { immutable v = "s." ~ name; alias FieldType F; } string code = "case " ~ to!string(id) ~ ":\n"; code ~= "if (f.type == " ~ dToTTypeString!F ~ ") {\n"; code ~= readValueCode!F(v) ~ "\n"; if (req == TReq.REQUIRED) { // For required fields, set the corresponding local isSet variable. code ~= "isSet_" ~ name ~ " = true;\n"; } else if (!isNullable!F){ code ~= "s.isSetFlags." ~ name ~ " = true;\n"; } code ~= "} else skip(p, f.type);\n"; code ~= "break;\n"; return code; } // Code for the local boolean flags used to make sure required fields have // been found. string isSetFlagCode = ""; // Code for checking whether the flags for the required fields are true. string isSetCheckCode = ""; /// Code for the case statements storing the fields to the result struct. string readMembersCode = ""; // The last automatically assigned id – fields with no meta information // are assigned (in lexical order) descending negative ids, starting with // -1, just like the Thrift compiler does. short lastId; foreach (name; FieldNames!T) { enum req = memberReq!(T, name, fieldMetaData); if (req == TReq.REQUIRED) { // For required fields, generate local bool flags to keep track // whether the field has been encountered. immutable n = "isSet_" ~ name; isSetFlagCode ~= "bool " ~ n ~ ";\n"; isSetCheckCode ~= "enforce(" ~ n ~ ", new TProtocolException(" ~ "`Required field '" ~ name ~ "' not found in serialized data`, " ~ "TProtocolException.Type.INVALID_DATA));\n"; } enum meta = find!`a.name == b`(mergeFieldMeta!(T, fieldMetaData), name); static if (meta.empty) { --lastId; version (TVerboseCodegen) { code ~= "pragma(msg, `[thrift.codegen.base.readStruct] Warning: No " ~ "meta information for field '" ~ name ~ "' in struct '" ~ T.stringof ~ "'. Assigned id: " ~ to!string(lastId) ~ ".`);\n"; } readMembersCode ~= readFieldCode!(MemberType!(T, name))( name, lastId, req); } else static if (req != TReq.IGNORE) { readMembersCode ~= readFieldCode!(MemberType!(T, name))( name, meta.front.id, req); } } code ~= isSetFlagCode; code ~= "p.readStructBegin();\n"; code ~= "while (true) {\n"; code ~= "auto f = p.readFieldBegin();\n"; code ~= "if (f.type == TType.STOP) break;\n"; code ~= "switch(f.id) {\n"; code ~= readMembersCode; code ~= "default: skip(p, f.type);\n"; code ~= "}\n"; code ~= "p.readFieldEnd();\n"; code ~= "}\n"; code ~= "p.readStructEnd();\n"; code ~= isSetCheckCode; return code; }()); } /** * Serializes a struct to the target protocol. * * Using the Protocol template parameter, the concrete TProtocol to use can be * be specified. If the pointerStruct parameter is set to true, the struct * fields are expected to be pointers to the actual data. This is used * internally (combined with TPargsStruct) and usually should not be used in * user code. * * This is a free function to make it possible to read exisiting structs from * the wire without altering their definitions. */ void writeStruct(T, Protocol, alias fieldMetaData = cast(TFieldMeta[])null, bool pointerStruct = false) (const T s, Protocol p) if (isTProtocol!Protocol) { mixin({ // Check that all fields for which there is meta info are actually in the // passed struct type. string code = ""; foreach (field; mergeFieldMeta!(T, fieldMetaData)) { code ~= "static assert(is(MemberType!(T, `" ~ field.name ~ "`)));\n"; } // Check that required nullable members are non-null. // WORKAROUND: To stop LDC from emitting the manifest constant »meta« below // into the writeStruct function body this is inside the string mixin // block – the code wouldn't depend on it (this is an LDC bug, and because // of it a new array would be allocated on each method invocation at runtime). foreach (name; StaticFilter!( Compose!(isNullable, PApply!(MemberType, T)), FieldNames!T )) { static if (memberReq!(T, name, fieldMetaData) == TReq.REQUIRED) { code ~= "enforce(__traits(getMember, s, `" ~ name ~ "`) !is null, new TException(`Required field '" ~ name ~ "' is null.`));\n"; } } return code; }()); p.writeStructBegin(TStruct(T.stringof)); mixin({ string writeValueCode(ValueType)(string v, size_t level = 0) { // Some non-ambigous names to use (shadowing is not allowed in D). immutable elem = "elem" ~ to!string(level); immutable key = "key" ~ to!string(level); immutable value = "value" ~ to!string(level); alias FullyUnqual!ValueType F; static if (is(F == bool)) { return "p.writeBool(" ~ v ~ ");"; } else static if (is(F == byte)) { return "p.writeByte(" ~ v ~ ");"; } else static if (is(F == double)) { return "p.writeDouble(" ~ v ~ ");"; } else static if (is(F == short)) { return "p.writeI16(" ~ v ~ ");"; } else static if (is(F == int)) { return "p.writeI32(" ~ v ~ ");"; } else static if (is(F == long)) { return "p.writeI64(" ~ v ~ ");"; } else static if (is(F : string)) { return "p.writeString(" ~ v ~ ");"; } else static if (is(F == enum)) { return "p.writeI32(cast(int)" ~ v ~ ");"; } else static if (is(F _ : E[], E)) { return "p.writeListBegin(TList(" ~ dToTTypeString!E ~ ", " ~ v ~ ".length));\n" ~ "foreach (" ~ elem ~ "; " ~ v ~ ") {\n" ~ writeValueCode!E(elem, level + 1) ~ "\n" ~ "}\n" ~ "p.writeListEnd();"; } else static if (is(F _ : V[K], K, V)) { return "p.writeMapBegin(TMap(" ~ dToTTypeString!K ~ ", " ~ dToTTypeString!V ~ ", " ~ v ~ ".length));\n" ~ "foreach (" ~ key ~ ", " ~ value ~ "; " ~ v ~ ") {\n" ~ writeValueCode!K(key, level + 1) ~ "\n" ~ writeValueCode!V(value, level + 1) ~ "\n" ~ "}\n" ~ "p.writeMapEnd();"; } else static if (is(F _ : HashSet!E, E)) { return "p.writeSetBegin(TSet(" ~ dToTTypeString!E ~ ", " ~ v ~ ".length));\n" ~ "foreach (" ~ elem ~ "; " ~ v ~ "[]) {\n" ~ writeValueCode!E(elem, level + 1) ~ "\n" ~ "}\n" ~ "p.writeSetEnd();"; } else static if (is(F == struct) || is(F : TException)) { static if (__traits(compiles, F.init.write(TProtocol.init))) { return v ~ ".write(p);"; } else { return "writeStruct(" ~ v ~ ", p);"; } } else { static assert(false, "Cannot represent type in Thrift: " ~ F.stringof); } } string writeFieldCode(FieldType)(string name, short id, TReq req) { string code; if (!pointerStruct && req == TReq.OPTIONAL) { code ~= "if (s.isSet!`" ~ name ~ "`) {\n"; } static if (pointerStruct && isPointer!FieldType) { immutable v = "(*s." ~ name ~ ")"; alias PointerTarget!FieldType F; } else { immutable v = "s." ~ name; alias FieldType F; } code ~= "p.writeFieldBegin(TField(`" ~ name ~ "`, " ~ dToTTypeString!F ~ ", " ~ to!string(id) ~ "));\n"; code ~= writeValueCode!F(v) ~ "\n"; code ~= "p.writeFieldEnd();\n"; if (!pointerStruct && req == TReq.OPTIONAL) { code ~= "}\n"; } return code; } // The last automatically assigned id – fields with no meta information // are assigned (in lexical order) descending negative ids, starting with // -1, just like the Thrift compiler does. short lastId; string code = ""; foreach (name; FieldNames!T) { alias MemberType!(T, name) F; enum req = memberReq!(T, name, fieldMetaData); enum meta = find!`a.name == b`(mergeFieldMeta!(T, fieldMetaData), name); if (meta.empty) { --lastId; version (TVerboseCodegen) { code ~= "pragma(msg, `[thrift.codegen.base.writeStruct] Warning: No " ~ "meta information for field '" ~ name ~ "' in struct '" ~ T.stringof ~ "'. Assigned id: " ~ to!string(lastId) ~ ".`);\n"; } code ~= writeFieldCode!F(name, lastId, req); } else if (req != TReq.IGNORE) { code ~= writeFieldCode!F(name, meta.front.id, req); } } return code; }()); p.writeFieldStop(); p.writeStructEnd(); } unittest { // Ensure that the generated code at least compiles for the basic field type // combinations. Functionality checks are covered by the rest of the test // suite. static struct Test { // Non-nullable. int a1; int a2; int a3; int a4; // Nullable. string b1; string b2; string b3; string b4; mixin TStructHelpers!([ TFieldMeta("a1", 1, TReq.OPT_IN_REQ_OUT), TFieldMeta("a2", 2, TReq.OPTIONAL), TFieldMeta("a3", 3, TReq.REQUIRED), TFieldMeta("a4", 4, TReq.IGNORE), TFieldMeta("b1", 5, TReq.OPT_IN_REQ_OUT), TFieldMeta("b2", 6, TReq.OPTIONAL), TFieldMeta("b3", 7, TReq.REQUIRED), TFieldMeta("b4", 8, TReq.IGNORE), ]); } static assert(__traits(compiles, { Test t; t.read(cast(TProtocol)null); })); static assert(__traits(compiles, { Test t; t.write(cast(TProtocol)null); })); } // Ensure opEquals and toHash consistency. unittest { struct TestEquals { int a1; mixin TStructHelpers!([ TFieldMeta("a1", 1, TReq.OPT_IN_REQ_OUT), ]); } TestEquals a, b; assert(a == b); assert(a.toHash() == b.toHash()); a.a1 = 42; assert(a != b); assert(a.toHash() != b.toHash()); b.a1 = 42; assert(a == b); assert(a.toHash() == b.toHash()); } private { /* * Returns a D code string containing the matching TType value for a passed * D type, e.g. dToTTypeString!byte == "TType.BYTE". */ template dToTTypeString(T) { static if (is(FullyUnqual!T == bool)) { enum dToTTypeString = "TType.BOOL"; } else static if (is(FullyUnqual!T == byte)) { enum dToTTypeString = "TType.BYTE"; } else static if (is(FullyUnqual!T == double)) { enum dToTTypeString = "TType.DOUBLE"; } else static if (is(FullyUnqual!T == short)) { enum dToTTypeString = "TType.I16"; } else static if (is(FullyUnqual!T == int)) { enum dToTTypeString = "TType.I32"; } else static if (is(FullyUnqual!T == long)) { enum dToTTypeString = "TType.I64"; } else static if (is(FullyUnqual!T : string)) { enum dToTTypeString = "TType.STRING"; } else static if (is(FullyUnqual!T == enum)) { enum dToTTypeString = "TType.I32"; } else static if (is(FullyUnqual!T _ : U[], U)) { enum dToTTypeString = "TType.LIST"; } else static if (is(FullyUnqual!T _ : V[K], K, V)) { enum dToTTypeString = "TType.MAP"; } else static if (is(FullyUnqual!T _ : HashSet!E, E)) { enum dToTTypeString = "TType.SET"; } else static if (is(FullyUnqual!T == struct)) { enum dToTTypeString = "TType.STRUCT"; } else static if (is(FullyUnqual!T : TException)) { enum dToTTypeString = "TType.STRUCT"; } else { static assert(false, "Cannot represent type in Thrift: " ~ T.stringof); } } } thrift-0.23.0/lib/d/src/thrift/codegen/idlgen.d0000664000175000017500000005224515165535636021500 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * Contains experimental functionality for generating Thrift IDL files * (.thrift) from existing D data structures, i.e. the reverse of what the * Thrift compiler does. */ module thrift.codegen.idlgen; import std.algorithm : find; import std.array : empty, front; import std.conv : to; import std.traits : EnumMembers, isSomeFunction, OriginalType, ParameterTypeTuple, ReturnType; import std.typetuple : allSatisfy, staticIndexOf, staticMap, NoDuplicates, TypeTuple; import thrift.base; import thrift.codegen.base; import thrift.internal.codegen; import thrift.internal.ctfe; import thrift.util.hashset; /** * True if the passed type is a Thrift entity (struct, exception, enum, * service). */ alias Any!(isStruct, isException, isEnum, isService) isThriftEntity; /** * Returns an IDL string describing the passed »root« entities and all types * they depend on. */ template idlString(Roots...) if (allSatisfy!(isThriftEntity, Roots)) { enum idlString = idlStringImpl!Roots.result; } private { template idlStringImpl(Roots...) if (allSatisfy!(isThriftEntity, Roots)) { alias ForAllWithList!( ConfinedTuple!(StaticFilter!(isService, Roots)), AddBaseServices ) Services; alias TypeTuple!( StaticFilter!(isEnum, Roots), ForAllWithList!( ConfinedTuple!( StaticFilter!(Any!(isException, isStruct), Roots), staticMap!(CompositeTypeDeps, staticMap!(ServiceTypeDeps, Services)) ), AddStructWithDeps ) ) Types; enum result = ctfeJoin( [ staticMap!( enumIdlString, StaticFilter!(isEnum, Types) ), staticMap!( structIdlString, StaticFilter!(Any!(isStruct, isException), Types) ), staticMap!( serviceIdlString, Services ) ], "\n" ); } template ServiceTypeDeps(T) if (isService!T) { alias staticMap!( PApply!(MethodTypeDeps, T), FilterMethodNames!(T, __traits(derivedMembers, T)) ) ServiceTypeDeps; } template MethodTypeDeps(T, string name) if ( isService!T && isSomeFunction!(MemberType!(T, name)) ) { alias TypeTuple!( ReturnType!(MemberType!(T, name)), ParameterTypeTuple!(MemberType!(T, name)), ExceptionTypes!(T, name) ) MethodTypeDeps; } template ExceptionTypes(T, string name) if ( isService!T && isSomeFunction!(MemberType!(T, name)) ) { mixin({ enum meta = find!`a.name == b`(getMethodMeta!T, name); if (meta.empty) return "alias TypeTuple!() ExceptionTypes;"; string result = "alias TypeTuple!("; foreach (i, e; meta.front.exceptions) { if (i > 0) result ~= ", "; result ~= "mixin(`T." ~ e.type ~ "`)"; } result ~= ") ExceptionTypes;"; return result; }()); } template AddBaseServices(T, List...) { static if (staticIndexOf!(T, List) == -1) { alias NoDuplicates!(BaseServices!T, List) AddBaseServices; } else { alias List AddStructWithDeps; } } unittest { interface A {} interface B : A {} interface C : B {} interface D : A {} static assert(is(AddBaseServices!(C) == TypeTuple!(A, B, C))); static assert(is(ForAllWithList!(ConfinedTuple!(C, D), AddBaseServices) == TypeTuple!(A, D, B, C))); } template BaseServices(T, Rest...) if (isService!T) { static if (isDerivedService!T) { alias BaseServices!(BaseService!T, T, Rest) BaseServices; } else { alias TypeTuple!(T, Rest) BaseServices; } } template AddStructWithDeps(T, List...) { static if (staticIndexOf!(T, List) == -1) { // T is not already in the List, so add T and the types it depends on in // the front. Because with the Thrift compiler types can only depend on // other types that have already been defined, we collect all the // dependencies, prepend them to the list, and then prune the duplicates // (keeping the first occurrences). If this requirement should ever be // dropped from Thrift, this could be easily adapted to handle circular // dependencies by passing TypeTuple!(T, List) to ForAllWithList instead // of appending List afterwards, and removing the now unnecessary // NoDuplicates. alias NoDuplicates!( ForAllWithList!( ConfinedTuple!( staticMap!( CompositeTypeDeps, staticMap!( PApply!(MemberType, T), FieldNames!T ) ) ), .AddStructWithDeps, T ), List ) AddStructWithDeps; } else { alias List AddStructWithDeps; } } version (unittest) { struct A {} struct B { A a; int b; A c; string d; } struct C { B b; A a; } static assert(is(AddStructWithDeps!C == TypeTuple!(A, B, C))); struct D { C c; mixin TStructHelpers!([TFieldMeta("c", 0, TReq.IGNORE)]); } static assert(is(AddStructWithDeps!D == TypeTuple!(D))); } version (unittest) { // Circles in the type dependency graph are not allowed in Thrift, but make // sure we fail in a sane way instead of crashing the compiler. struct Rec1 { Rec2[] other; } struct Rec2 { Rec1[] other; } static assert(!__traits(compiles, AddStructWithDeps!Rec1)); } /* * Returns the non-primitive types T directly depends on. * * For example, CompositeTypeDeps!int would yield an empty type tuple, * CompositeTypeDeps!SomeStruct would give SomeStruct, and * CompositeTypeDeps!(A[B]) both CompositeTypeDeps!A and CompositeTypeDeps!B. */ template CompositeTypeDeps(T) { static if (is(FullyUnqual!T == bool) || is(FullyUnqual!T == byte) || is(FullyUnqual!T == short) || is(FullyUnqual!T == int) || is(FullyUnqual!T == long) || is(FullyUnqual!T : string) || is(FullyUnqual!T == double) || is(FullyUnqual!T == void) ) { alias TypeTuple!() CompositeTypeDeps; } else static if (is(FullyUnqual!T _ : U[], U)) { alias CompositeTypeDeps!U CompositeTypeDeps; } else static if (is(FullyUnqual!T _ : HashSet!E, E)) { alias CompositeTypeDeps!E CompositeTypeDeps; } else static if (is(FullyUnqual!T _ : V[K], K, V)) { alias TypeTuple!(CompositeTypeDeps!K, CompositeTypeDeps!V) CompositeTypeDeps; } else static if (is(FullyUnqual!T == enum) || is(FullyUnqual!T == struct) || is(FullyUnqual!T : TException) ) { alias TypeTuple!(FullyUnqual!T) CompositeTypeDeps; } else { static assert(false, "Cannot represent type in Thrift: " ~ T.stringof); } } } /** * Returns an IDL string describing the passed service. IDL code for any type * dependcies is not included. */ template serviceIdlString(T) if (isService!T) { enum serviceIdlString = { string result = "service " ~ T.stringof; static if (isDerivedService!T) { result ~= " extends " ~ BaseService!T.stringof; } result ~= " {\n"; foreach (methodName; FilterMethodNames!(T, __traits(derivedMembers, T))) { result ~= " "; enum meta = find!`a.name == b`(T.methodMeta, methodName); static if (!meta.empty && meta.front.type == TMethodType.ONEWAY) { result ~= "oneway "; } alias ReturnType!(MemberType!(T, methodName)) RT; static if (is(RT == void)) { // We special-case this here instead of adding void to dToIdlType to // avoid accepting things like void[]. result ~= "void "; } else { result ~= dToIdlType!RT ~ " "; } result ~= methodName ~ "("; short lastId; foreach (i, ParamType; ParameterTypeTuple!(MemberType!(T, methodName))) { static if (!meta.empty && i < meta.front.params.length) { enum havePM = true; } else { enum havePM = false; } short id; static if (havePM) { id = meta.front.params[i].id; } else { id = --lastId; } string paramName; static if (havePM) { paramName = meta.front.params[i].name; } else { paramName = "param" ~ to!string(i + 1); } result ~= to!string(id) ~ ": " ~ dToIdlType!ParamType ~ " " ~ paramName; static if (havePM && !meta.front.params[i].defaultValue.empty) { result ~= " = " ~ dToIdlConst(mixin(meta.front.params[i].defaultValue)); } else { // Unfortunately, getting the default value for parameters from a // function alias isn't possible – we can't transfer the default // value to the IDL e.g. for interface Foo { void foo(int a = 5); } // without the user explicitly declaring it in metadata. } result ~= ", "; } result ~= ")"; static if (!meta.empty && !meta.front.exceptions.empty) { result ~= " throws ("; foreach (e; meta.front.exceptions) { result ~= to!string(e.id) ~ ": " ~ e.type ~ " " ~ e.name ~ ", "; } result ~= ")"; } result ~= ",\n"; } result ~= "}\n"; return result; }(); } /** * Returns an IDL string describing the passed enum. IDL code for any type * dependcies is not included. */ template enumIdlString(T) if (isEnum!T) { enum enumIdlString = { static assert(is(OriginalType!T : long), "Can only have integer enums in Thrift (not " ~ OriginalType!T.stringof ~ ", for " ~ T.stringof ~ ")."); string result = "enum " ~ T.stringof ~ " {\n"; foreach (name; __traits(derivedMembers, T)) { result ~= " " ~ name ~ " = " ~ dToIdlConst(GetMember!(T, name)) ~ ",\n"; } result ~= "}\n"; return result; }(); } /** * Returns an IDL string describing the passed struct. IDL code for any type * dependcies is not included. */ template structIdlString(T) if (isStruct!T || isException!T) { enum structIdlString = { mixin({ string code = ""; foreach (field; getFieldMeta!T) { code ~= "static assert(is(MemberType!(T, `" ~ field.name ~ "`)));\n"; } return code; }()); string result; static if (isException!T) { result = "exception "; } else { result = "struct "; } result ~= T.stringof ~ " {\n"; // The last automatically assigned id – fields with no meta information // are assigned (in lexical order) descending negative ids, starting with // -1, just like the Thrift compiler does. short lastId; foreach (name; FieldNames!T) { enum meta = find!`a.name == b`(getFieldMeta!T, name); static if (meta.empty || meta.front.req != TReq.IGNORE) { short id; static if (meta.empty) { id = --lastId; } else { id = meta.front.id; } result ~= " " ~ to!string(id) ~ ":"; static if (!meta.empty) { result ~= dToIdlReq(meta.front.req); } result ~= " " ~ dToIdlType!(MemberType!(T, name)) ~ " " ~ name; static if (!meta.empty && !meta.front.defaultValue.empty) { result ~= " = " ~ dToIdlConst(mixin(meta.front.defaultValue)); } else static if (__traits(compiles, fieldInitA!(T, name))) { static if (is(typeof(fieldInitA!(T, name))) && !is(typeof(fieldInitA!(T, name)) == void) ) { result ~= " = " ~ dToIdlConst(fieldInitA!(T, name)); } } else static if (is(typeof(fieldInitB!(T, name))) && !is(typeof(fieldInitB!(T, name)) == void) ) { result ~= " = " ~ dToIdlConst(fieldInitB!(T, name)); } result ~= ",\n"; } } result ~= "}\n"; return result; }(); } private { // This very convoluted way of doing things was chosen because putting the // static if directly into structIdlString caused »not evaluatable at compile // time« errors to slip through even though typeof() was used, resp. the // condition to be true even though the value couldn't actually be read at // compile time due to a @@BUG@@ in DMD 2.055. // The extra »compiled« field in fieldInitA is needed because we must not try // to use != if !is compiled as well (but was false), e.g. for floating point // types. template fieldInitA(T, string name) { static if (mixin("T.init." ~ name) !is MemberType!(T, name).init) { enum fieldInitA = mixin("T.init." ~ name); } } template fieldInitB(T, string name) { static if (mixin("T.init." ~ name) != MemberType!(T, name).init) { enum fieldInitB = mixin("T.init." ~ name); } } template dToIdlType(T) { static if (is(FullyUnqual!T == bool)) { enum dToIdlType = "bool"; } else static if (is(FullyUnqual!T == byte)) { enum dToIdlType = "byte"; } else static if (is(FullyUnqual!T == double)) { enum dToIdlType = "double"; } else static if (is(FullyUnqual!T == short)) { enum dToIdlType = "i16"; } else static if (is(FullyUnqual!T == int)) { enum dToIdlType = "i32"; } else static if (is(FullyUnqual!T == long)) { enum dToIdlType = "i64"; } else static if (is(FullyUnqual!T : string)) { enum dToIdlType = "string"; } else static if (is(FullyUnqual!T _ : U[], U)) { enum dToIdlType = "list<" ~ dToIdlType!U ~ ">"; } else static if (is(FullyUnqual!T _ : V[K], K, V)) { enum dToIdlType = "map<" ~ dToIdlType!K ~ ", " ~ dToIdlType!V ~ ">"; } else static if (is(FullyUnqual!T _ : HashSet!E, E)) { enum dToIdlType = "set<" ~ dToIdlType!E ~ ">"; } else static if (is(FullyUnqual!T == struct) || is(FullyUnqual!T == enum) || is(FullyUnqual!T : TException) ) { enum dToIdlType = FullyUnqual!(T).stringof; } else { static assert(false, "Cannot represent type in Thrift: " ~ T.stringof); } } string dToIdlReq(TReq req) { switch (req) { case TReq.REQUIRED: return " required"; case TReq.OPTIONAL: return " optional"; default: return ""; } } string dToIdlConst(T)(T value) { static if (is(FullyUnqual!T == bool)) { return value ? "1" : "0"; } else static if (is(FullyUnqual!T == byte) || is(FullyUnqual!T == short) || is(FullyUnqual!T == int) || is(FullyUnqual!T == long) ) { return to!string(value); } else static if (is(FullyUnqual!T : string)) { return `"` ~ to!string(value) ~ `"`; } else static if (is(FullyUnqual!T == double)) { return ctfeToString(value); } else static if (is(FullyUnqual!T _ : U[], U) || is(FullyUnqual!T _ : HashSet!E, E) ) { string result = "["; foreach (e; value) { result ~= dToIdlConst(e) ~ ", "; } result ~= "]"; return result; } else static if (is(FullyUnqual!T _ : V[K], K, V)) { string result = "{"; foreach (key, val; value) { result ~= dToIdlConst(key) ~ ": " ~ dToIdlConst(val) ~ ", "; } result ~= "}"; return result; } else static if (is(FullyUnqual!T == enum)) { import std.conv; import std.traits; return to!string(cast(OriginalType!T)value); } else static if (is(FullyUnqual!T == struct) || is(FullyUnqual!T : TException) ) { string result = "{"; foreach (name; __traits(derivedMembers, T)) { static if (memberReq!(T, name) != TReq.IGNORE) { result ~= name ~ ": " ~ dToIdlConst(mixin("value." ~ name)) ~ ", "; } } result ~= "}"; return result; } else { static assert(false, "Cannot represent type in Thrift: " ~ T.stringof); } } } version (unittest) { enum Foo { a = 1, b = 10, c = 5 } static assert(enumIdlString!Foo == `enum Foo { a = 1, b = 10, c = 5, } `); } version (unittest) { struct WithoutMeta { string a; int b; } struct WithDefaults { string a = "asdf"; double b = 3.1415; WithoutMeta c; mixin TStructHelpers!([ TFieldMeta("c", 1, TReq.init, `WithoutMeta("foo", 3)`) ]); } // These are from DebugProtoTest.thrift. struct OneOfEach { bool im_true; bool im_false; byte a_bite; short integer16; int integer32; long integer64; double double_precision; string some_characters; string zomg_unicode; bool what_who; string base64; byte[] byte_list; short[] i16_list; long[] i64_list; mixin TStructHelpers!([ TFieldMeta(`im_true`, 1), TFieldMeta(`im_false`, 2), TFieldMeta(`a_bite`, 3, TReq.OPT_IN_REQ_OUT, q{cast(byte)127}), TFieldMeta(`integer16`, 4, TReq.OPT_IN_REQ_OUT, q{cast(short)32767}), TFieldMeta(`integer32`, 5), TFieldMeta(`integer64`, 6, TReq.OPT_IN_REQ_OUT, q{10000000000L}), TFieldMeta(`double_precision`, 7), TFieldMeta(`some_characters`, 8), TFieldMeta(`zomg_unicode`, 9), TFieldMeta(`what_who`, 10), TFieldMeta(`base64`, 11), TFieldMeta(`byte_list`, 12, TReq.OPT_IN_REQ_OUT, q{{ byte[] v; v ~= cast(byte)1; v ~= cast(byte)2; v ~= cast(byte)3; return v; }()}), TFieldMeta(`i16_list`, 13, TReq.OPT_IN_REQ_OUT, q{{ short[] v; v ~= cast(short)1; v ~= cast(short)2; v ~= cast(short)3; return v; }()}), TFieldMeta(`i64_list`, 14, TReq.OPT_IN_REQ_OUT, q{{ long[] v; v ~= 1L; v ~= 2L; v ~= 3L; return v; }()}) ]); } struct Bonk { int type; string message; mixin TStructHelpers!([ TFieldMeta(`type`, 1), TFieldMeta(`message`, 2) ]); } struct HolyMoley { OneOfEach[] big; HashSet!(string[]) contain; Bonk[][string] bonks; mixin TStructHelpers!([ TFieldMeta(`big`, 1), TFieldMeta(`contain`, 2), TFieldMeta(`bonks`, 3) ]); } static assert(structIdlString!WithoutMeta == `struct WithoutMeta { -1: string a, -2: i32 b, } `); import std.algorithm; static assert(structIdlString!WithDefaults.startsWith( `struct WithDefaults { -1: string a = "asdf", -2: double b = 3.141`)); static assert(structIdlString!WithDefaults.endsWith( `1: WithoutMeta c = {a: "foo", b: 3, }, } `)); static assert(structIdlString!OneOfEach == `struct OneOfEach { 1: bool im_true, 2: bool im_false, 3: byte a_bite = 127, 4: i16 integer16 = 32767, 5: i32 integer32, 6: i64 integer64 = 10000000000, 7: double double_precision, 8: string some_characters, 9: string zomg_unicode, 10: bool what_who, 11: string base64, 12: list byte_list = [1, 2, 3, ], 13: list i16_list = [1, 2, 3, ], 14: list i64_list = [1, 2, 3, ], } `); static assert(structIdlString!Bonk == `struct Bonk { 1: i32 type, 2: string message, } `); static assert(structIdlString!HolyMoley == `struct HolyMoley { 1: list big, 2: set> contain, 3: map> bonks, } `); } version (unittest) { class ExceptionWithAMap : TException { string blah; string[string] map_field; mixin TStructHelpers!([ TFieldMeta(`blah`, 1), TFieldMeta(`map_field`, 2) ]); } interface Srv { void voidMethod(); int primitiveMethod(); OneOfEach structMethod(); void methodWithDefaultArgs(int something); void onewayMethod(); void exceptionMethod(); alias .ExceptionWithAMap ExceptionWithAMap; enum methodMeta = [ TMethodMeta(`methodWithDefaultArgs`, [TParamMeta(`something`, 1, q{2})] ), TMethodMeta(`onewayMethod`, [], [], TMethodType.ONEWAY ), TMethodMeta(`exceptionMethod`, [], [ TExceptionMeta("a", 1, "ExceptionWithAMap"), TExceptionMeta("b", 2, "ExceptionWithAMap") ] ) ]; } interface ChildSrv : Srv { int childMethod(int arg); } static assert(idlString!ChildSrv == `exception ExceptionWithAMap { 1: string blah, 2: map map_field, } struct OneOfEach { 1: bool im_true, 2: bool im_false, 3: byte a_bite = 127, 4: i16 integer16 = 32767, 5: i32 integer32, 6: i64 integer64 = 10000000000, 7: double double_precision, 8: string some_characters, 9: string zomg_unicode, 10: bool what_who, 11: string base64, 12: list byte_list = [1, 2, 3, ], 13: list i16_list = [1, 2, 3, ], 14: list i64_list = [1, 2, 3, ], } service Srv { void voidMethod(), i32 primitiveMethod(), OneOfEach structMethod(), void methodWithDefaultArgs(1: i32 something = 2, ), oneway void onewayMethod(), void exceptionMethod() throws (1: ExceptionWithAMap a, 2: ExceptionWithAMap b, ), } service ChildSrv extends Srv { i32 childMethod(-1: i32 param1, ), } `); } thrift-0.23.0/lib/d/src/thrift/codegen/client_pool.d0000664000175000017500000001712515165535636022543 0ustar00buildbuild00000000000000/* * 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. */ module thrift.codegen.client_pool; import core.time : dur, Duration, TickDuration; import std.traits : ParameterTypeTuple, ReturnType; import thrift.base; import thrift.codegen.base; import thrift.codegen.client; import thrift.internal.codegen; import thrift.internal.resource_pool; /** * Manages a pool of TClients for the given interface, forwarding RPC calls to * members of the pool. * * If a request fails, another client from the pool is tried, and optionally, * a client is disabled for a configurable amount of time if it fails too * often. If all clients fail (and keepTrying is false), a * TCompoundOperationException is thrown, containing all the collected RPC * exceptions. */ class TClientPool(Interface) if (isService!Interface) : Interface { /// Shorthand for TClientBase!Interface, the client type this instance /// operates on. alias TClientBase!Interface Client; /** * Creates a new instance and adds the given clients to the pool. */ this(Client[] clients) { pool_ = new TResourcePool!Client(clients); rpcFaultFilter = (Exception e) { import thrift.protocol.base; import thrift.transport.base; return ( (cast(TTransportException)e !is null) || (cast(TApplicationException)e !is null) ); }; } /** * Executes an operation on the first currently active client. * * If the operation fails (throws an exception for which rpcFaultFilter is * true), the failure is recorded and the next client in the pool is tried. * * Throws: Any non-rpc exception that occurs, a TCompoundOperationException * if all clients failed with an rpc exception (if keepTrying is false). * * Example: * --- * interface Foo { string bar(); } * auto poolClient = tClientPool([tClient!Foo(someProtocol)]); * auto result = poolClient.execute((c){ return c.bar(); }); * --- */ ResultType execute(ResultType)(scope ResultType delegate(Client) work) { return executeOnPool!Client(work); } /** * Adds a client to the pool. */ void addClient(Client client) { pool_.add(client); } /** * Removes a client from the pool. * * Returns: Whether the client was found in the pool. */ bool removeClient(Client client) { return pool_.remove(client); } mixin(poolForwardCode!Interface()); /// Whether to open the underlying transports of a client before trying to /// execute a method if they are not open. This is usually desirable /// because it allows e.g. to automatically reconnect to a remote server /// if the network connection is dropped. /// /// Defaults to true. bool reopenTransports = true; /// Called to determine whether an exception comes from a client from the /// pool not working properly, or if it an exception thrown at the /// application level. /// /// If the delegate returns true, the server/connection is considered to be /// at fault, if it returns false, the exception is just passed on to the /// caller. /// /// By default, returns true for instances of TTransportException and /// TApplicationException, false otherwise. bool delegate(Exception) rpcFaultFilter; /** * Whether to keep trying to find a working client if all have failed in a * row. * * Defaults to false. */ bool keepTrying() const @property { return pool_.cycle; } /// Ditto void keepTrying(bool value) @property { pool_.cycle = value; } /** * Whether to use a random permutation of the client pool on every call to * execute(). This can be used e.g. as a simple form of load balancing. * * Defaults to true. */ bool permuteClients() const @property { return pool_.permute; } /// Ditto void permuteClients(bool value) @property { pool_.permute = value; } /** * The number of consecutive faults after which a client is disabled until * faultDisableDuration has passed. 0 to never disable clients. * * Defaults to 0. */ ushort faultDisableCount() @property { return pool_.faultDisableCount; } /// Ditto void faultDisableCount(ushort value) @property { pool_.faultDisableCount = value; } /** * The duration for which a client is no longer considered after it has * failed too often. * * Defaults to one second. */ Duration faultDisableDuration() @property { return pool_.faultDisableDuration; } /// Ditto void faultDisableDuration(Duration value) @property { pool_.faultDisableDuration = value; } protected: ResultType executeOnPool(ResultType)(scope ResultType delegate(Client) work) { auto clients = pool_[]; if (clients.empty) { throw new TException("No clients available to try."); } while (true) { Exception[] rpcExceptions; while (!clients.empty) { auto c = clients.front; clients.popFront; try { scope (success) { pool_.recordSuccess(c); } if (reopenTransports) { c.inputProtocol.transport.open(); c.outputProtocol.transport.open(); } return work(c); } catch (Exception e) { if (rpcFaultFilter && rpcFaultFilter(e)) { pool_.recordFault(c); rpcExceptions ~= e; } else { // We are dealing with a normal exception thrown by the // server-side method, just pass it on. As far as we are // concerned, the method call succeeded. pool_.recordSuccess(c); throw e; } } } // If we get here, no client succeeded during the current iteration. Duration waitTime; Client dummy; if (clients.willBecomeNonempty(dummy, waitTime)) { if (waitTime > dur!"hnsecs"(0)) { import core.thread; Thread.sleep(waitTime); } } else { throw new TCompoundOperationException("All clients failed.", rpcExceptions); } } } private: TResourcePool!Client pool_; } private { // Cannot use an anonymous delegate literal for this because they aren't // allowed in class scope. string poolForwardCode(Interface)() { string code = ""; foreach (methodName; AllMemberMethodNames!Interface) { enum qn = "Interface." ~ methodName; code ~= "ReturnType!(" ~ qn ~ ") " ~ methodName ~ "(ParameterTypeTuple!(" ~ qn ~ ") args) {\n"; code ~= "return executeOnPool((Client c){ return c." ~ methodName ~ "(args); });\n"; code ~= "}\n"; } return code; } } /** * TClientPool construction helper to avoid having to explicitly specify * the interface type, i.e. to allow the constructor being called using IFTI * (see $(DMDBUG 6082, D Bugzilla enhancement requet 6082)). */ TClientPool!Interface tClientPool(Interface)( TClientBase!Interface[] clients ) if (isService!Interface) { return new typeof(return)(clients); } thrift-0.23.0/lib/d/src/thrift/async/0000775000175000017500000000000015165535636017572 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/async/socket.d0000664000175000017500000002660015165535636021233 0ustar00buildbuild00000000000000/* * 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. */ module thrift.async.socket; import core.thread : Fiber; import core.time : dur, Duration; import std.array : empty; import std.conv : to; import std.exception : enforce; import std.socket; import thrift.base; import thrift.async.base; import thrift.transport.base; import thrift.transport.socket : TSocketBase; import thrift.internal.endian; import thrift.internal.socket; version (Windows) { import core.sys.windows.winsock2 : connect; } else version (Posix) { import core.sys.posix.sys.socket : connect; } else static assert(0, "Don't know connect on this platform."); version (OSX) { import core.stdc.errno : ECONNRESET; } version (Win32) { import core.stdc.config : __c_long; } /** * Non-blocking socket implementation of the TTransport interface. * * Whenever a socket operation would block, TAsyncSocket registers a callback * with the specified TAsyncSocketManager and yields. * * As for thrift.transport.socket, due to the limitations of std.socket, * currently only TCP/IP sockets are supported (i.e. Unix domain sockets are * not). */ class TAsyncSocket : TSocketBase, TAsyncTransport { /** * Constructor that takes an already created, connected (!) socket. * * Params: * asyncManager = The TAsyncSocketManager to use for non-blocking I/O. * socket = Already created, connected socket object. Will be switched to * non-blocking mode if it isn't already. */ this(TAsyncSocketManager asyncManager, Socket socket) { asyncManager_ = asyncManager; socket.blocking = false; super(socket); } /** * Creates a new unconnected socket that will connect to the given host * on the given port. * * Params: * asyncManager = The TAsyncSocketManager to use for non-blocking I/O. * host = Remote host. * port = Remote port. */ this(TAsyncSocketManager asyncManager, string host, ushort port) { asyncManager_ = asyncManager; super(host, port); } override TAsyncManager asyncManager() @property { return asyncManager_; } /** * Asynchronously connects the socket. * * Completes without blocking and defers further operations on the socket * until the connection is established. If connecting fails, this is * currently not indicated in any way other than every call to read/write * failing. */ override void open() { if (isOpen) return; enforce(!host_.empty, new TTransportException( "Cannot open null host.", TTransportException.Type.NOT_OPEN)); enforce(port_ != 0, new TTransportException( "Cannot open with null port.", TTransportException.Type.NOT_OPEN)); // Cannot use std.socket.Socket.connect here because it hides away // EINPROGRESS/WSAWOULDBLOCK. Address addr; try { // Currently, we just go with the first address returned, could be made // more intelligent though – IPv6? addr = getAddress(host_, port_)[0]; } catch (Exception e) { throw new TTransportException(`Unable to resolve host "` ~ host_ ~ `".`, TTransportException.Type.NOT_OPEN, __FILE__, __LINE__, e); } socket_ = new TcpSocket(addr.addressFamily); socket_.blocking = false; setSocketOpts(); auto errorCode = connect(socket_.handle, addr.name(), addr.nameLen()); if (errorCode == 0) { // If the connection could be established immediately, just return. I // don't know if this ever happens. return; } auto errno = getSocketErrno(); if (errno != CONNECT_INPROGRESS_ERRNO) { throw new TTransportException(`Could not establish connection to "` ~ host_ ~ `": ` ~ socketErrnoString(errno), TTransportException.Type.NOT_OPEN); } // This is the expected case: connect() signalled that the connection // is being established in the background. Queue up a work item with the // async manager which just defers any other operations on this // TAsyncSocket instance until the socket is ready. asyncManager_.execute(this, { auto fiber = Fiber.getThis(); TAsyncEventReason reason = void; asyncManager_.addOneshotListener(socket_, TAsyncEventType.WRITE, connectTimeout, scopedDelegate((TAsyncEventReason r){ reason = r; fiber.call(); }) ); Fiber.yield(); if (reason == TAsyncEventReason.TIMED_OUT) { // Close the connection, so that subsequent work items fail immediately. closeImmediately(); return; } version (Win32) { __c_long errorCode = void; } else { int errorCode = void; } socket_.getOption(SocketOptionLevel.SOCKET, cast(SocketOption)SO_ERROR, errorCode); if (errorCode) { logInfo("Could not connect TAsyncSocket: %s", socketErrnoString(errorCode)); // Close the connection, so that subsequent work items fail immediately. closeImmediately(); return; } } ); } /** * Closes the socket. * * Will block until all currently active operations are finished before the * socket is closed. */ override void close() { if (!isOpen) return; import core.sync.condition; import core.sync.mutex; auto doneMutex = new Mutex; auto doneCond = new Condition(doneMutex); synchronized (doneMutex) { asyncManager_.execute(this, scopedDelegate( { closeImmediately(); synchronized (doneMutex) doneCond.notifyAll(); } ) ); doneCond.wait(); } } override bool peek() { if (!isOpen) return false; ubyte buf; auto r = socket_.receive((&buf)[0..1], SocketFlags.PEEK); if (r == Socket.ERROR) { auto lastErrno = getSocketErrno(); static if (connresetOnPeerShutdown) { if (lastErrno == ECONNRESET) { closeImmediately(); return false; } } throw new TTransportException("Peeking into socket failed: " ~ socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN); } return (r > 0); } override size_t read(ubyte[] buf) { enforce(isOpen, new TTransportException( "Cannot read if socket is not open.", TTransportException.Type.NOT_OPEN)); typeof(getSocketErrno()) lastErrno; auto r = yieldOnBlock(socket_.receive(cast(void[])buf), TAsyncEventType.READ); // If recv went fine, immediately return. if (r >= 0) return r; // Something went wrong, find out how to handle it. lastErrno = getSocketErrno(); static if (connresetOnPeerShutdown) { // See top comment. if (lastErrno == ECONNRESET) { return 0; } } throw new TTransportException("Receiving from socket failed: " ~ socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN); } override void write(in ubyte[] buf) { size_t sent; while (sent < buf.length) { sent += writeSome(buf[sent .. $]); } assert(sent == buf.length); } override size_t writeSome(in ubyte[] buf) { enforce(isOpen, new TTransportException( "Cannot write if socket is not open.", TTransportException.Type.NOT_OPEN)); auto r = yieldOnBlock(socket_.send(buf), TAsyncEventType.WRITE); // Everything went well, just return the number of bytes written. if (r > 0) return r; // Handle error conditions. if (r < 0) { auto lastErrno = getSocketErrno(); auto type = TTransportException.Type.UNKNOWN; if (isSocketCloseErrno(lastErrno)) { type = TTransportException.Type.NOT_OPEN; closeImmediately(); } throw new TTransportException("Sending to socket failed: " ~ socketErrnoString(lastErrno), type); } // send() should never return 0. throw new TTransportException("Sending to socket failed (0 bytes written).", TTransportException.Type.UNKNOWN); } /// The amount of time in which a conncetion must be established before the /// open() call times out. Duration connectTimeout = dur!"seconds"(5); private: void closeImmediately() { socket_.close(); socket_ = null; } T yieldOnBlock(T)(lazy T call, TAsyncEventType eventType) { while (true) { auto result = call(); if (result != Socket.ERROR || getSocketErrno() != WOULD_BLOCK_ERRNO) return result; // We got an EAGAIN result, register a callback to return here once some // event happens and yield. Duration timeout = void; final switch (eventType) { case TAsyncEventType.READ: timeout = recvTimeout_; break; case TAsyncEventType.WRITE: timeout = sendTimeout_; break; } auto fiber = Fiber.getThis(); assert(fiber, "Current fiber null – not running in TAsyncManager?"); TAsyncEventReason eventReason = void; asyncManager_.addOneshotListener(socket_, eventType, timeout, scopedDelegate((TAsyncEventReason reason) { eventReason = reason; fiber.call(); }) ); // Yields execution back to the async manager, will return back here once // the above listener is called. Fiber.yield(); if (eventReason == TAsyncEventReason.TIMED_OUT) { // If we are cancelling the request due to a timed out operation, the // connection is in an undefined state, because the server could decide // to send the requested data later, or we could have already been half- // way into writing a request. Thus, we close the connection to make any // possibly queued up work items fail immediately. Besides, the server // is not very likely to immediately recover after a socket-level // timeout has expired anyway. closeImmediately(); throw new TTransportException("Timed out while waiting for socket " ~ "to get ready to " ~ to!string(eventType) ~ ".", TTransportException.Type.TIMED_OUT); } } } /// The TAsyncSocketManager to use for non-blocking I/O. TAsyncSocketManager asyncManager_; } private { // std.socket doesn't include SO_ERROR for reasons unknown. version (linux) { enum SO_ERROR = 4; } else version (OSX) { enum SO_ERROR = 0x1007; } else version (FreeBSD) { enum SO_ERROR = 0x1007; } else version (Windows) { import core.sys.windows.winsock2 : SO_ERROR; } else static assert(false, "Don't know SO_ERROR on this platform."); // This hack forces a delegate literal to be scoped, even if it is passed to // a function accepting normal delegates as well. DMD likes to allocate the // context on the heap anyway, but it seems to work for LDC. import std.traits : isDelegate; auto scopedDelegate(D)(scope D d) if (isDelegate!D) { return d; } } thrift-0.23.0/lib/d/src/thrift/async/libevent.d0000664000175000017500000003562415165535636021561 0ustar00buildbuild00000000000000/* * 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. */ module thrift.async.libevent; import core.atomic; import core.time : Duration, dur; import core.exception : onOutOfMemoryError; import core.memory : GC; import core.thread : Fiber, Thread; import core.sync.condition; import core.sync.mutex; import core.stdc.stdlib : free, malloc; import deimos.event2.event; import std.array : empty, front, popFront; import std.conv : text, to; import std.exception : enforce; import std.socket : Socket, socketPair; import thrift.base; import thrift.async.base; import thrift.internal.socket; import thrift.internal.traits; import thrift.util.cancellation; // To avoid DMD @@BUG6395@@. import thrift.internal.algorithm; /** * A TAsyncManager implementation based on libevent. * * The libevent loop for handling non-blocking sockets is run in a background * thread, which is lazily spawned. The thread is not daemonized to avoid * crashes on program shutdown, it is only stopped when the manager instance * is destroyed. So, to ensure a clean program teardown, either make sure this * instance gets destroyed (e.g. by using scope), or manually call stop() at * the end. */ class TLibeventAsyncManager : TAsyncSocketManager { this() { eventBase_ = event_base_new(); // Set up the socket pair for transferring control messages to the event // loop. auto pair = socketPair(); controlSendSocket_ = pair[0]; controlReceiveSocket_ = pair[1]; controlReceiveSocket_.blocking = false; // Register an event for receiving control messages. controlReceiveEvent_ = event_new(eventBase_, cast(evutil_socket_t)controlReceiveSocket_.handle, EV_READ | EV_PERSIST | EV_ET, assumeNothrow(&controlMsgReceiveCallback), cast(void*)this); event_add(controlReceiveEvent_, null); queuedCountMutex_ = new Mutex; zeroQueuedCondition_ = new Condition(queuedCountMutex_); } ~this() { // stop() should be safe to call, because either we don't have a worker // thread running and it is a no-op anyway, or it is guaranteed to be // still running (blocked in event_base_loop), and thus guaranteed not to // be garbage collected yet. stop(dur!"hnsecs"(0)); event_free(controlReceiveEvent_); event_base_free(eventBase_); eventBase_ = null; } override void execute(TAsyncTransport transport, Work work, TCancellation cancellation = null ) { if (cancellation && cancellation.triggered) return; // Keep track that there is a new work item to be processed. incrementQueuedCount(); ensureWorkerThreadRunning(); // We should be able to send the control message as a whole – we currently // assume to be able to receive it at once as well. If this proves to be // unstable (e.g. send could possibly return early if the receiving buffer // is full and the blocking call gets interrupted by a signal), it could // be changed to a more sophisticated scheme. // Make sure the delegate context doesn't get GCd while the work item is // on the wire. GC.addRoot(work.ptr); // Send work message. sendControlMsg(ControlMsg(MsgType.WORK, work, transport)); if (cancellation) { cancellation.triggering.addCallback({ sendControlMsg(ControlMsg(MsgType.CANCEL, work, transport)); }); } } override void delay(Duration duration, void delegate() work) { incrementQueuedCount(); ensureWorkerThreadRunning(); const tv = toTimeval(duration); // DMD @@BUG@@: Cannot deduce T to void delegate() here. registerOneshotEvent!(void delegate())( -1, 0, assumeNothrow(&delayCallback), &tv, { work(); decrementQueuedCount(); } ); } override bool stop(Duration waitFinishTimeout = dur!"hnsecs"(-1)) { bool cleanExit = true; synchronized (this) { if (workerThread_) { synchronized (queuedCountMutex_) { if (waitFinishTimeout > dur!"hnsecs"(0)) { if (queuedCount_ > 0) { zeroQueuedCondition_.wait(waitFinishTimeout); } } else if (waitFinishTimeout < dur!"hnsecs"(0)) { while (queuedCount_ > 0) zeroQueuedCondition_.wait(); } else { // waitFinishTimeout is zero, immediately exit in all cases. } cleanExit = (queuedCount_ == 0); } event_base_loopbreak(eventBase_); sendControlMsg(ControlMsg(MsgType.SHUTDOWN)); workerThread_.join(); workQueues_ = null; // We have nuked all currently enqueued items, so set the count to // zero. This is safe to do without locking, since the worker thread // is down. queuedCount_ = 0; atomicStore(*(cast(shared)&workerThread_), cast(shared(Thread))null); } } return cleanExit; } override void addOneshotListener(Socket socket, TAsyncEventType eventType, TSocketEventListener listener ) { addOneshotListenerImpl(socket, eventType, null, listener); } override void addOneshotListener(Socket socket, TAsyncEventType eventType, Duration timeout, TSocketEventListener listener ) { if (timeout <= dur!"hnsecs"(0)) { addOneshotListenerImpl(socket, eventType, null, listener); } else { // This is not really documented well, but libevent does not require to // keep the timeval around after the event was added. auto tv = toTimeval(timeout); addOneshotListenerImpl(socket, eventType, &tv, listener); } } private: alias void delegate() Work; void addOneshotListenerImpl(Socket socket, TAsyncEventType eventType, const(timeval)* timeout, TSocketEventListener listener ) { registerOneshotEvent(cast(evutil_socket_t)socket.handle, libeventEventType(eventType), assumeNothrow(&socketCallback), timeout, listener); } void registerOneshotEvent(T)(evutil_socket_t fd, short type, event_callback_fn callback, const(timeval)* timeout, T payload ) { // Create a copy of the payload on the C heap. auto payloadMem = malloc(payload.sizeof); if (!payloadMem) onOutOfMemoryError(); (cast(T*)payloadMem)[0 .. 1] = payload; GC.addRange(payloadMem, payload.sizeof); auto result = event_base_once(eventBase_, fd, type, callback, payloadMem, timeout); // Assuming that we didn't get our arguments wrong above, the only other // situation in which event_base_once can fail is when it can't allocate // memory. if (result != 0) onOutOfMemoryError(); } enum MsgType : ubyte { SHUTDOWN, WORK, CANCEL } struct ControlMsg { MsgType type; Work work; TAsyncTransport transport; } /** * Starts the worker thread if it is not already running. */ void ensureWorkerThreadRunning() { // Technically, only half barriers would be required here, but adding the // argument seems to trigger a DMD template argument deduction @@BUG@@. if (!atomicLoad(*(cast(shared)&workerThread_))) { synchronized (this) { if (!workerThread_) { auto thread = new Thread({ event_base_loop(eventBase_, 0); }); thread.start(); atomicStore(*(cast(shared)&workerThread_), cast(shared)thread); } } } } /** * Sends a control message to the worker thread. */ void sendControlMsg(const(ControlMsg) msg) { auto result = controlSendSocket_.send((&msg)[0 .. 1]); enum size = msg.sizeof; enforce(result == size, new TException(text( "Sending control message of type ", msg.type, " failed (", result, " bytes instead of ", size, " transmitted)."))); } /** * Receives messages from the control message socket and acts on them. Called * from the worker thread. */ void receiveControlMsg() { // Read as many new work items off the socket as possible (at least one // should be available, as we got notified by libevent). ControlMsg msg; ptrdiff_t bytesRead; while (true) { bytesRead = controlReceiveSocket_.receive(cast(ubyte[])((&msg)[0 .. 1])); if (bytesRead < 0) { auto errno = getSocketErrno(); if (errno != WOULD_BLOCK_ERRNO) { logError("Reading control message, some work item will possibly " ~ "never be executed: %s", socketErrnoString(errno)); } } if (bytesRead != msg.sizeof) break; // Everything went fine, we received a new control message. final switch (msg.type) { case MsgType.SHUTDOWN: // The message was just intended to wake us up for shutdown. break; case MsgType.CANCEL: // When processing a cancellation, we must not touch the first item, // since it is already being processed. auto queue = workQueues_[msg.transport]; if (queue.length > 0) { workQueues_[msg.transport] = [queue[0]] ~ removeEqual(queue[1 .. $], msg.work); } break; case MsgType.WORK: // Now that the work item is back in the D world, we don't need the // extra GC root for the context pointer anymore (see execute()). GC.removeRoot(msg.work.ptr); // Add the work item to the queue and execute it. auto queue = msg.transport in workQueues_; if (queue is null || (*queue).empty) { // If the queue is empty, add the new work item to the queue as well, // but immediately start executing it. workQueues_[msg.transport] = [msg.work]; executeWork(msg.transport, msg.work); } else { (*queue) ~= msg.work; } break; } } // If the last read was successful, but didn't read enough bytes, we got // a problem. if (bytesRead > 0) { logError("Unexpected partial control message read (%s byte(s) " ~ "instead of %s), some work item will possibly never be executed.", bytesRead, msg.sizeof); } } /** * Executes the given work item and all others enqueued for the same * transport in a new fiber. Called from the worker thread. */ void executeWork(TAsyncTransport transport, Work work) { (new Fiber({ auto item = work; while (true) { try { // Execute the actual work. It will possibly add listeners to the // event loop and yield away if it has to wait for blocking // operations. It is quite possible that another fiber will modify // the work queue for the current transport. item(); } catch (Exception e) { // This should never happen, just to be sure the worker thread // doesn't stop working in mysterious ways because of an unhandled // exception. logError("Exception thrown by work item: %s", e); } // Remove the item from the work queue. // Note: Due to the value semantics of array slices, we have to // re-lookup this on every iteration. This could be solved, but I'd // rather replace this directly with a queue type once one becomes // available in Phobos. auto queue = workQueues_[transport]; assert(queue.front == item); queue.popFront(); workQueues_[transport] = queue; // Now that the work item is done, no longer count it as queued. decrementQueuedCount(); if (queue.empty) break; // If the queue is not empty, execute the next waiting item. item = queue.front; } })).call(); } /** * Increments the amount of queued items. */ void incrementQueuedCount() { synchronized (queuedCountMutex_) { ++queuedCount_; } } /** * Decrements the amount of queued items. */ void decrementQueuedCount() { synchronized (queuedCountMutex_) { assert(queuedCount_ > 0); --queuedCount_; if (queuedCount_ == 0) { zeroQueuedCondition_.notifyAll(); } } } static extern(C) void controlMsgReceiveCallback(evutil_socket_t, short, void *managerThis ) { (cast(TLibeventAsyncManager)managerThis).receiveControlMsg(); } static extern(C) void socketCallback(evutil_socket_t, short flags, void *arg ) { auto reason = (flags & EV_TIMEOUT) ? TAsyncEventReason.TIMED_OUT : TAsyncEventReason.NORMAL; (*(cast(TSocketEventListener*)arg))(reason); GC.removeRange(arg); destroy(arg); free(arg); } static extern(C) void delayCallback(evutil_socket_t, short flags, void *arg ) { assert(flags & EV_TIMEOUT); (*(cast(void delegate()*)arg))(); GC.removeRange(arg); destroy(arg); free(arg); } Thread workerThread_; event_base* eventBase_; /// The socket used for receiving new work items in the event loop. Paired /// with controlSendSocket_. Invalid (i.e. TAsyncWorkItem.init) items are /// ignored and can be used to wake up the worker thread. Socket controlReceiveSocket_; event* controlReceiveEvent_; /// The socket used to send new work items to the event loop. It is /// expected that work items can always be read at once from it, i.e. that /// there will never be short reads. Socket controlSendSocket_; /// Queued up work delegates for async transports. This also includes /// currently active ones, they are removed from the queue on completion, /// which is relied on by the control message receive fiber (the main one) /// to decide whether to immediately start executing items or not. // TODO: This should really be of some queue type, not an array slice, but // std.container doesn't have anything. Work[][TAsyncTransport] workQueues_; /// The total number of work items not yet finished (queued and currently /// executed) and delays not yet executed. uint queuedCount_; /// Protects queuedCount_. Mutex queuedCountMutex_; /// Triggered when queuedCount_ reaches zero, protected by queuedCountMutex_. Condition zeroQueuedCondition_; } private { timeval toTimeval(const(Duration) dur) { timeval tv; dur.split!("seconds", "usecs")(tv.tv_sec, tv.tv_usec); return tv; } /** * Returns the libevent flags combination to represent a given TAsyncEventType. */ short libeventEventType(TAsyncEventType type) { final switch (type) { case TAsyncEventType.READ: return EV_READ | EV_ET; case TAsyncEventType.WRITE: return EV_WRITE | EV_ET; } } } thrift-0.23.0/lib/d/src/thrift/async/base.d0000664000175000017500000002120115165535636020645 0ustar00buildbuild00000000000000/* * 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. */ /** * Defines the interface used for client-side handling of asynchronous * I/O operations, based on coroutines. * * The main piece of the »client side« (e.g. for TAsyncClient users) of the * API is TFuture, which represents an asynchronously executed operation, * which can have a return value, throw exceptions, and which can be waited * upon. * * On the »implementation side«, the idea is that by using a TAsyncTransport * instead of a normal TTransport and executing the work through a * TAsyncManager, the same code as for synchronous I/O can be used for * asynchronous operation as well, for example: * * --- * auto socket = new TAsyncSocket(someTAsyncSocketManager(), host, port); * // … * socket.asyncManager.execute(socket, { * SomeThriftStruct s; * * // Waiting for socket I/O will not block an entire thread but cause * // the async manager to execute another task in the meantime, because * // we are using TAsyncSocket instead of TSocket. * s.read(socket); * * // Do something with s, e.g. set a TPromise result to it. * writeln(s); * }); * --- */ module thrift.async.base; import core.time : Duration, dur; import std.socket/+ : Socket+/; // DMD @@BUG314@@ import thrift.base; import thrift.transport.base; import thrift.util.cancellation; /** * Manages one or more asynchronous transport resources (e.g. sockets in the * case of TAsyncSocketManager) and allows work items to be submitted for them. * * Implementations will typically run one or more background threads for * executing the work, which is one of the reasons for a TAsyncManager to be * used. Each work item is run in its own fiber and is expected to yield() away * while waiting for time-consuming operations. * * The second important purpose of TAsyncManager is to serialize access to * the transport resources – without taking care of that, e.g. issuing multiple * RPC calls over the same connection in rapid succession would likely lead to * more than one request being written at the same time, causing only garbage * to arrive at the remote end. * * All methods are thread-safe. */ interface TAsyncManager { /** * Submits a work item to be executed asynchronously. * * Access to asnyc transports is serialized – if two work items associated * with the same transport are submitted, the second delegate will not be * invoked until the first has returned, even it the latter context-switches * away (because it is waiting for I/O) and the async manager is idle * otherwise. * * Optionally, a TCancellation instance can be specified. If present, * triggering it will be considered a request to cancel the work item, if it * is still waiting for the associated transport to become available. * Delegates which are already being processed (i.e. waiting for I/O) are not * affected because this would bring the connection into an undefined state * (as probably half-written request or a half-read response would be left * behind). * * Params: * transport = The TAsyncTransport the work delegate will operate on. Must * be associated with this TAsyncManager instance. * work = The operations to execute on the given transport. Must never * throw, errors should be handled in another way. nothrow semantics are * difficult to enforce in combination with fibres though, so currently * exceptions are just swallowed by TAsyncManager implementations. * cancellation = If set, can be used to request cancellatinon of this work * item if it is still waiting to be executed. * * Note: The work item will likely be executed in a different thread, so make * sure the code it relies on is thread-safe. An exception are the async * transports themselves, to which access is serialized as noted above. */ void execute(TAsyncTransport transport, void delegate() work, TCancellation cancellation = null ) in { assert(transport.asyncManager is this, "The given transport must be associated with this TAsyncManager."); } /** * Submits a delegate to be executed after a certain amount of time has * passed. * * The actual amount of time elapsed can be higher if the async manager * instance is busy and thus should not be relied on. The * * Params: * duration = The amount of time to wait before starting to execute the * work delegate. * work = The code to execute after the specified amount of time has passed. * * Example: * --- * // A very basic example – usually, the actuall work item would enqueue * // some async transport operation. * auto asyncMangager = someAsyncManager(); * * TFuture!int calculate() { * // Create a promise and asynchronously set its value after three * // seconds have passed. * auto promise = new TPromise!int; * asyncManager.delay(dur!"seconds"(3), { * promise.succeed(42); * }); * * // Immediately return it to the caller. * return promise; * } * * // This will wait until the result is available and then print it. * writeln(calculate().waitGet()); * --- */ void delay(Duration duration, void delegate() work); /** * Shuts down all background threads or other facilities that might have * been started in order to execute work items. This function is typically * called during program shutdown. * * If there are still tasks to be executed when the timeout expires, any * currently executed work items will never receive any notifications * for async transports managed by this instance, queued work items will * be silently dropped, and implementations are allowed to leak resources. * * Params: * waitFinishTimeout = If positive, waits for all work items to be * finished for the specified amount of time, if negative, waits for * completion without ever timing out, if zero, immediately shuts down * the background facilities. */ bool stop(Duration waitFinishTimeout = dur!"hnsecs"(-1)); } /** * A TTransport which uses a TAsyncManager to schedule non-blocking operations. * * The actual type of device is not specified; typically, implementations will * depend on an interface derived from TAsyncManager to be notified of changes * in the transport state. * * The peeking, reading, writing and flushing methods must always be called * from within the associated async manager. */ interface TAsyncTransport : TTransport { /** * The TAsyncManager associated with this transport. */ TAsyncManager asyncManager() @property; } /** * A TAsyncManager providing notificiations for socket events. */ interface TAsyncSocketManager : TAsyncManager { /** * Adds a listener that is triggered once when an event of the specified type * occurs, and removed afterwards. * * Params: * socket = The socket to listen for events at. * eventType = The type of the event to listen for. * timeout = The period of time after which the listener will be called * with TAsyncEventReason.TIMED_OUT if no event happened. * listener = The delegate to call when an event happened. */ void addOneshotListener(Socket socket, TAsyncEventType eventType, Duration timeout, TSocketEventListener listener); /// Ditto void addOneshotListener(Socket socket, TAsyncEventType eventType, TSocketEventListener listener); } /** * Types of events that can happen for an asynchronous transport. */ enum TAsyncEventType { READ, /// New data became available to read. WRITE /// The transport became ready to be written to. } /** * The type of the delegates used to register socket event handlers. */ alias void delegate(TAsyncEventReason callReason) TSocketEventListener; /** * The reason a listener was called. */ enum TAsyncEventReason : byte { NORMAL, /// The event listened for was triggered normally. TIMED_OUT /// A timeout for the event was set, and it expired. } thrift-0.23.0/lib/d/src/thrift/async/ssl.d0000664000175000017500000002067215165535636020547 0ustar00buildbuild00000000000000/* * 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. */ module thrift.async.ssl; import core.thread : Fiber; import core.time : Duration; import std.array : empty; import std.conv : to; import std.exception : enforce; import std.socket; import deimos.openssl.err; import deimos.openssl.ssl; import thrift.base; import thrift.async.base; import thrift.async.socket; import thrift.internal.ssl; import thrift.internal.ssl_bio; import thrift.transport.base; import thrift.transport.ssl; /** * Provides SSL/TLS encryption for async sockets. * * This implementation should be considered experimental, as it context-switches * between fibers from within OpenSSL calls, and the safety of this has not yet * been verified. * * For obvious reasons (the SSL connection is stateful), more than one instance * should never be used on a given socket at the same time. */ // Note: This could easily be extended to other transports in the future as well. // There are only two parts of the implementation which don't work with a generic // TTransport: 1) the certificate verification, for which peer name/address are // needed from the socket, and 2) the connection shutdown, where the associated // async manager is needed because close() is not usually called from within a // work item. final class TAsyncSSLSocket : TBaseTransport { /** * Constructor. * * Params: * context = The SSL socket context to use. A reference to it is stored so * that it does not get cleaned up while the socket is used. * transport = The underlying async network transport to use for * communication. */ this(TAsyncSocket underlyingSocket, TSSLContext context) { socket_ = underlyingSocket; context_ = context; serverSide_ = context.serverSide; accessManager_ = context.accessManager; } override bool isOpen() @property { if (ssl_ is null || !socket_.isOpen) return false; auto shutdown = SSL_get_shutdown(ssl_); bool shutdownReceived = (shutdown & SSL_RECEIVED_SHUTDOWN) != 0; bool shutdownSent = (shutdown & SSL_SENT_SHUTDOWN) != 0; return !(shutdownReceived && shutdownSent); } override bool peek() { if (!isOpen) return false; checkHandshake(); byte bt = void; auto rc = SSL_peek(ssl_, &bt, bt.sizeof); sslEnforce(rc >= 0, "SSL_peek"); if (rc == 0) { ERR_clear_error(); } return (rc > 0); } override void open() { enforce(!serverSide_, "Cannot open a server-side SSL socket."); if (isOpen) return; if (ssl_) { // If the underlying socket was automatically closed because of an error // (i.e. close() was called from inside a socket method), we can land // here with the SSL object still allocated; delete it here. cleanupSSL(); } socket_.open(); } override void close() { if (!isOpen) return; if (ssl_ !is null) { // SSL needs to send/receive data over the socket as part of the shutdown // protocol, so we must execute the calls in the context of the associated // async manager. On the other hand, TTransport clients expect the socket // to be closed when close() returns, so we have to block until the // shutdown work item has been executed. import core.sync.condition; import core.sync.mutex; int rc = void; auto doneMutex = new Mutex; auto doneCond = new Condition(doneMutex); synchronized (doneMutex) { socket_.asyncManager.execute(socket_, { rc = SSL_shutdown(ssl_); if (rc == 0) { rc = SSL_shutdown(ssl_); } synchronized (doneMutex) doneCond.notifyAll(); }); doneCond.wait(); } if (rc < 0) { // Do not throw an exception here as leaving the transport "open" will // probably produce only more errors, and the chance we can do // something about the error e.g. by retrying is very low. logError("Error while shutting down SSL: %s", getSSLException()); } cleanupSSL(); } socket_.close(); } override size_t read(ubyte[] buf) { checkHandshake(); auto rc = SSL_read(ssl_, buf.ptr, cast(int)buf.length); sslEnforce(rc >= 0, "SSL_read"); return rc; } override void write(in ubyte[] buf) { checkHandshake(); // Loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX. size_t written = 0; while (written < buf.length) { auto bytes = SSL_write(ssl_, buf.ptr + written, cast(int)(buf.length - written)); sslEnforce(bytes > 0, "SSL_write"); written += bytes; } } override void flush() { checkHandshake(); auto bio = SSL_get_wbio(ssl_); enforce(bio !is null, new TSSLException("SSL_get_wbio returned null")); auto rc = BIO_flush(bio); sslEnforce(rc == 1, "BIO_flush"); } /** * Whether to use client or server side SSL handshake protocol. */ bool serverSide() @property const { return serverSide_; } /// Ditto void serverSide(bool value) @property { serverSide_ = value; } /** * The access manager to use. */ void accessManager(TAccessManager value) @property { accessManager_ = value; } private: /** * If the condition is false, cleans up the SSL connection and throws the * exception for the last SSL error. */ void sslEnforce(bool condition, string location) { if (!condition) { // We need to fetch the error first, as the error stack will be cleaned // when shutting down SSL. auto e = getSSLException(location); cleanupSSL(); throw e; } } /** * Frees the SSL connection object and clears the SSL error state. */ void cleanupSSL() { SSL_free(ssl_); ssl_ = null; ERR_remove_state(0); } /** * Makes sure the SSL connection is up and running, and initializes it if not. */ void checkHandshake() { enforce(socket_.isOpen, new TTransportException( TTransportException.Type.NOT_OPEN)); if (ssl_ !is null) return; ssl_ = context_.createSSL(); auto bio = createTTransportBIO(socket_, false); SSL_set_bio(ssl_, bio, bio); int rc = void; if (serverSide_) { rc = SSL_accept(ssl_); } else { rc = SSL_connect(ssl_); } enforce(rc > 0, getSSLException()); auto addr = socket_.getPeerAddress(); authorize(ssl_, accessManager_, addr, (serverSide_ ? addr.toHostNameString() : socket_.host)); } TAsyncSocket socket_; bool serverSide_; SSL* ssl_; TSSLContext context_; TAccessManager accessManager_; } /** * Wraps passed TAsyncSocket instances into TAsyncSSLSockets. * * Typically used with TAsyncClient. As an unfortunate consequence of the * async client design, the passed transports cannot be statically verified to * be of type TAsyncSocket. Instead, the type is verified at runtime – if a * transport of an unexpected type is passed to getTransport(), it fails, * throwing a TTransportException. * * Example: * --- * auto context = nwe TSSLContext(); * ... // Configure SSL context. * auto factory = new TAsyncSSLSocketFactory(context); * * auto socket = new TAsyncSocket(someAsyncManager, host, port); * socket.open(); * * auto client = new TAsyncClient!Service(transport, factory, * new TBinaryProtocolFactory!()); * --- */ class TAsyncSSLSocketFactory : TTransportFactory { /// this(TSSLContext context) { context_ = context; } override TAsyncSSLSocket getTransport(TTransport transport) { auto socket = cast(TAsyncSocket)transport; enforce(socket, new TTransportException( "TAsyncSSLSocketFactory requires a TAsyncSocket to work on, not a " ~ to!string(typeid(transport)) ~ ".", TTransportException.Type.INTERNAL_ERROR )); return new TAsyncSSLSocket(socket, context_); } private: TSSLContext context_; } thrift-0.23.0/lib/d/src/thrift/transport/0000775000175000017500000000000015165535636020511 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/transport/socket.d0000664000175000017500000003101215165535636022143 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.socket; import core.thread : Thread; import core.time : dur, Duration; import std.array : empty; import std.conv : text, to; import std.exception : enforce; import std.socket; import thrift.base; import thrift.transport.base; import thrift.internal.socket; version (Windows) { import core.sys.windows.winsock2 : WSAECONNRESET; enum ECONNRESET = WSAECONNRESET; } else version (Posix) { import core.stdc.errno : ECONNRESET; } else static assert(0, "Don't know ECONNRESET on this platform."); /** * Common parts of a socket TTransport implementation, regardless of how the * actual I/O is performed (sync/async). */ abstract class TSocketBase : TBaseTransport { /** * Constructor that takes an already created, connected (!) socket. * * Params: * socket = Already created, connected socket object. */ this(Socket socket) { socket_ = socket; setSocketOpts(); } /** * Creates a new unconnected socket that will connect to the given host * on the given port. * * Params: * host = Remote host. * port = Remote port. */ this(string host, ushort port) { host_ = host; port_ = port; } /** * Checks whether the socket is connected. */ override bool isOpen() @property { return socket_ !is null; } /** * Writes as much data to the socket as there can be in a single OS call. * * Params: * buf = Data to write. * * Returns: The actual number of bytes written. Never more than buf.length. */ abstract size_t writeSome(in ubyte[] buf) out (written) { // DMD @@BUG@@: Enabling this e.g. fails the contract in the // async_test_server, because buf.length evaluates to 0 here, even though // in the method body it correctly is 27 (equal to the return value). version (none) assert(written <= buf.length, text("Implementation wrote " ~ "more data than requested to?! (", written, " vs. ", buf.length, ")")); } body { assert(0, "DMD bug? – Why would contracts work for interfaces, but not " ~ "for abstract methods? " ~ "(Error: function […] in and out contracts require function body"); } /** * Returns the actual address of the peer the socket is connected to. * * In contrast, the host and port properties contain the address used to * establish the connection, and are not updated after the connection. * * The socket must be open when calling this. */ Address getPeerAddress() { enforce(isOpen, new TTransportException("Cannot get peer host for " ~ "closed socket.", TTransportException.Type.NOT_OPEN)); if (!peerAddress_) { peerAddress_ = socket_.remoteAddress(); assert(peerAddress_); } return peerAddress_; } /** * The host the socket is connected to or will connect to. Null if an * already connected socket was used to construct the object. */ string host() const @property { return host_; } /** * The port the socket is connected to or will connect to. Zero if an * already connected socket was used to construct the object. */ ushort port() const @property { return port_; } /// The socket send timeout. Duration sendTimeout() const @property { return sendTimeout_; } /// Ditto void sendTimeout(Duration value) @property { sendTimeout_ = value; } /// The socket receiving timeout. Values smaller than 500 ms are not /// supported on Windows. Duration recvTimeout() const @property { return recvTimeout_; } /// Ditto void recvTimeout(Duration value) @property { recvTimeout_ = value; } /** * Returns the OS handle of the underlying socket. * * Should not usually be used directly, but access to it can be necessary * to interface with C libraries. */ typeof(socket_.handle()) socketHandle() @property { return socket_.handle(); } protected: /** * Sets the needed socket options. */ void setSocketOpts() { try { alias SocketOptionLevel.SOCKET lvlSock; Linger l; l.on = 0; l.time = 0; socket_.setOption(lvlSock, SocketOption.LINGER, l); } catch (SocketException e) { logError("Could not set socket option: %s", e); } // Just try to disable Nagle's algorithm – this will fail if we are passed // in a non-TCP socket via the Socket-accepting constructor. try { socket_.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, true); } catch (SocketException e) {} } /// Remote host. string host_; /// Remote port. ushort port_; /// Timeout for sending. Duration sendTimeout_; /// Timeout for receiving. Duration recvTimeout_; /// Cached peer address. Address peerAddress_; /// Cached peer host name. string peerHost_; /// Cached peer port. ushort peerPort_; /// Wrapped socket object. Socket socket_; } /** * Socket implementation of the TTransport interface. * * Due to the limitations of std.socket, currently only TCP/IP sockets are * supported (i.e. Unix domain sockets are not). */ class TSocket : TSocketBase { /// this(Socket socket) { super(socket); } /// this(string host, ushort port) { super(host, port); } /** * Connects the socket. */ override void open() { if (isOpen) return; enforce(!host_.empty, new TTransportException( "Cannot open socket to null host.", TTransportException.Type.NOT_OPEN)); enforce(port_ != 0, new TTransportException( "Cannot open socket to port zero.", TTransportException.Type.NOT_OPEN)); Address[] addrs; try { addrs = getAddress(host_, port_); } catch (SocketException e) { throw new TTransportException("Could not resolve given host string.", TTransportException.Type.NOT_OPEN, __FILE__, __LINE__, e); } Exception[] errors; foreach (addr; addrs) { try { socket_ = new TcpSocket(addr.addressFamily); setSocketOpts(); socket_.connect(addr); break; } catch (SocketException e) { errors ~= e; } } if (errors.length == addrs.length) { socket_ = null; // Need to throw a TTransportException to abide the TTransport API. import std.algorithm, std.range; throw new TTransportException( text("Failed to connect to ", host_, ":", port_, "."), TTransportException.Type.NOT_OPEN, __FILE__, __LINE__, new TCompoundOperationException( text( "All addresses tried failed (", joiner(map!q{text(a[0], `: "`, a[1].msg, `"`)}(zip(addrs, errors)), ", "), ")." ), errors ) ); } } /** * Closes the socket. */ override void close() { if (!isOpen) return; socket_.close(); socket_ = null; } override bool peek() { if (!isOpen) return false; ubyte buf; auto r = socket_.receive((&buf)[0 .. 1], SocketFlags.PEEK); if (r == -1) { auto lastErrno = getSocketErrno(); static if (connresetOnPeerShutdown) { if (lastErrno == ECONNRESET) { close(); return false; } } throw new TTransportException("Peeking into socket failed: " ~ socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN); } return (r > 0); } override size_t read(ubyte[] buf) { enforce(isOpen, new TTransportException( "Cannot read if socket is not open.", TTransportException.Type.NOT_OPEN)); typeof(getSocketErrno()) lastErrno; ushort tries; while (tries++ <= maxRecvRetries_) { auto r = socket_.receive(cast(void[])buf); // If recv went fine, immediately return. if (r >= 0) return r; // Something went wrong, find out how to handle it. lastErrno = getSocketErrno(); if (lastErrno == INTERRUPTED_ERRNO) { // If the syscall was interrupted, just try again. continue; } static if (connresetOnPeerShutdown) { // See top comment. if (lastErrno == ECONNRESET) { return 0; } } // Not an error which is handled in a special way, just leave the loop. break; } if (isSocketCloseErrno(lastErrno)) { close(); throw new TTransportException("Receiving failed, closing socket: " ~ socketErrnoString(lastErrno), TTransportException.Type.NOT_OPEN); } else if (lastErrno == TIMEOUT_ERRNO) { throw new TTransportException(TTransportException.Type.TIMED_OUT); } else { throw new TTransportException("Receiving from socket failed: " ~ socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN); } } override void write(in ubyte[] buf) { size_t sent; while (sent < buf.length) { auto b = writeSome(buf[sent .. $]); if (b == 0) { // This should only happen if the timeout set with SO_SNDTIMEO expired. throw new TTransportException("send() timeout expired.", TTransportException.Type.TIMED_OUT); } sent += b; } assert(sent == buf.length); } override size_t writeSome(in ubyte[] buf) { enforce(isOpen, new TTransportException( "Cannot write if file is not open.", TTransportException.Type.NOT_OPEN)); auto r = socket_.send(buf); // Everything went well, just return the number of bytes written. if (r > 0) return r; // Handle error conditions. if (r < 0) { auto lastErrno = getSocketErrno(); if (lastErrno == WOULD_BLOCK_ERRNO) { // Not an exceptional error per se – even with blocking sockets, // EAGAIN apparently is returned sometimes on out-of-resource // conditions (see the C++ implementation for details). Also, this // allows using TSocket with non-blocking sockets e.g. in // TNonblockingServer. return 0; } auto type = TTransportException.Type.UNKNOWN; if (isSocketCloseErrno(lastErrno)) { type = TTransportException.Type.NOT_OPEN; close(); } throw new TTransportException("Sending to socket failed: " ~ socketErrnoString(lastErrno), type); } // send() should never return 0. throw new TTransportException("Sending to socket failed (0 bytes written).", TTransportException.Type.UNKNOWN); } override void sendTimeout(Duration value) @property { super.sendTimeout(value); setTimeout(SocketOption.SNDTIMEO, value); } override void recvTimeout(Duration value) @property { super.recvTimeout(value); setTimeout(SocketOption.RCVTIMEO, value); } /** * Maximum number of retries for receiving from socket on read() in case of * EAGAIN/EINTR. */ ushort maxRecvRetries() @property const { return maxRecvRetries_; } /// Ditto void maxRecvRetries(ushort value) @property { maxRecvRetries_ = value; } /// Ditto enum DEFAULT_MAX_RECV_RETRIES = 5; protected: override void setSocketOpts() { super.setSocketOpts(); setTimeout(SocketOption.SNDTIMEO, sendTimeout_); setTimeout(SocketOption.RCVTIMEO, recvTimeout_); } void setTimeout(SocketOption type, Duration value) { assert(type == SocketOption.SNDTIMEO || type == SocketOption.RCVTIMEO); version (Win32) { if (value > dur!"hnsecs"(0) && value < dur!"msecs"(500)) { logError( "Socket %s timeout of %s ms might be raised to 500 ms on Windows.", (type == SocketOption.SNDTIMEO) ? "send" : "receive", value.total!"msecs" ); } } if (socket_) { try { socket_.setOption(SocketOptionLevel.SOCKET, type, value); } catch (SocketException e) { throw new TTransportException( "Could not set timeout.", TTransportException.Type.UNKNOWN, __FILE__, __LINE__, e ); } } } /// Maximum number of recv() retries. ushort maxRecvRetries_ = DEFAULT_MAX_RECV_RETRIES; } thrift-0.23.0/lib/d/src/thrift/transport/buffered.d0000664000175000017500000001462215165535636022445 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.buffered; import std.algorithm : min; import std.array : empty; import std.exception : enforce; import thrift.transport.base; /** * Wraps another transport and buffers reads and writes until the internal * buffers are exhausted, at which point new data is fetched resp. the * accumulated data is written out at once. */ final class TBufferedTransport : TBaseTransport { /** * Constructs a new instance, using the default buffer sizes. * * Params: * transport = The underlying transport to wrap. */ this(TTransport transport) { this(transport, DEFAULT_BUFFER_SIZE); } /** * Constructs a new instance, using the specified buffer size. * * Params: * transport = The underlying transport to wrap. * bufferSize = The size of the read and write buffers to use, in bytes. */ this(TTransport transport, size_t bufferSize) { this(transport, bufferSize, bufferSize); } /** * Constructs a new instance, using the specified buffer size. * * Params: * transport = The underlying transport to wrap. * readBufferSize = The size of the read buffer to use, in bytes. * writeBufferSize = The size of the write buffer to use, in bytes. */ this(TTransport transport, size_t readBufferSize, size_t writeBufferSize) { transport_ = transport; readBuffer_ = new ubyte[readBufferSize]; writeBuffer_ = new ubyte[writeBufferSize]; writeAvail_ = writeBuffer_; } /// The default size of the read/write buffers, in bytes. enum int DEFAULT_BUFFER_SIZE = 512; override bool isOpen() @property { return transport_.isOpen(); } override bool peek() { if (readAvail_.empty) { // If there is nothing available to read, see if we can get something // from the underlying transport. auto bytesRead = transport_.read(readBuffer_); readAvail_ = readBuffer_[0 .. bytesRead]; } return !readAvail_.empty; } override void open() { transport_.open(); } override void close() { if (!isOpen) return; flush(); transport_.close(); } override size_t read(ubyte[] buf) { if (readAvail_.empty) { // No data left in our buffer, fetch some from the underlying transport. if (buf.length > readBuffer_.length) { // If the amount of data requested is larger than our reading buffer, // directly read to the passed buffer. This probably doesn't occur too // often in practice (and even if it does, the underlying transport // probably cannot fulfill the request at once anyway), but it can't // harm to try… return transport_.read(buf); } auto bytesRead = transport_.read(readBuffer_); readAvail_ = readBuffer_[0 .. bytesRead]; } // Hand over whatever we have. auto give = min(readAvail_.length, buf.length); buf[0 .. give] = readAvail_[0 .. give]; readAvail_ = readAvail_[give .. $]; return give; } /** * Shortcut version of readAll. */ override void readAll(ubyte[] buf) { if (readAvail_.length >= buf.length) { buf[] = readAvail_[0 .. buf.length]; readAvail_ = readAvail_[buf.length .. $]; return; } super.readAll(buf); } override void write(in ubyte[] buf) { if (writeAvail_.length >= buf.length) { // If the data fits in the buffer, just save it there. writeAvail_[0 .. buf.length] = buf; writeAvail_ = writeAvail_[buf.length .. $]; return; } // We have to decide if we copy data from buf to our internal buffer, or // just directly write them out. The same considerations about avoiding // syscalls as for C++ apply here. auto bytesAvail = writeAvail_.ptr - writeBuffer_.ptr; if ((bytesAvail + buf.length >= 2 * writeBuffer_.length) || (bytesAvail == 0)) { // We would immediately need two syscalls anyway (or we don't have // anything) in our buffer to write, so just write out both buffers. if (bytesAvail > 0) { transport_.write(writeBuffer_[0 .. bytesAvail]); writeAvail_ = writeBuffer_; } transport_.write(buf); return; } // Fill up our internal buffer for a write. writeAvail_[] = buf[0 .. writeAvail_.length]; auto left = buf[writeAvail_.length .. $]; transport_.write(writeBuffer_); // Copy the rest into our buffer. writeBuffer_[0 .. left.length] = left[]; writeAvail_ = writeBuffer_[left.length .. $]; } override void flush() { // Write out any data waiting in the write buffer. auto bytesAvail = writeAvail_.ptr - writeBuffer_.ptr; if (bytesAvail > 0) { // Note that we reset writeAvail_ prior to calling the underlying protocol // to make sure the buffer is cleared even if the transport throws an // exception. writeAvail_ = writeBuffer_; transport_.write(writeBuffer_[0 .. bytesAvail]); } // Flush the underlying transport. transport_.flush(); } override const(ubyte)[] borrow(ubyte* buf, size_t len) { if (len <= readAvail_.length) { return readAvail_; } return null; } override void consume(size_t len) { enforce(len <= readBuffer_.length, new TTransportException( "Invalid consume length.", TTransportException.Type.BAD_ARGS)); readAvail_ = readAvail_[len .. $]; } /** * The wrapped transport. */ TTransport underlyingTransport() @property { return transport_; } private: TTransport transport_; ubyte[] readBuffer_; ubyte[] writeBuffer_; ubyte[] readAvail_; ubyte[] writeAvail_; } /** * Wraps given transports into TBufferedTransports. */ alias TWrapperTransportFactory!TBufferedTransport TBufferedTransportFactory; thrift-0.23.0/lib/d/src/thrift/transport/websocket.d0000664000175000017500000002574315165535636022657 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.websocket; import std.algorithm; import std.algorithm.searching; import std.base64; import std.bitmanip; import std.conv; import std.digest.sha; import std.stdio; import std.string; import std.uni; import thrift.base : VERSION; import thrift.transport.base; import thrift.transport.http; /** * WebSocket server transport. */ final class TServerWebSocketTransport(bool binary) : THttpTransport { /** * Constructs a new instance. * * Param: * transport = The underlying transport used for the actual I/O. */ this(TTransport transport) { super(transport); transport_ = transport; } override size_t read(ubyte[] buf) { // If we do not have a good handshake, the client will attempt one. if (!handshakeComplete) { resetHandshake(); super.read(buf); // If we did not get everything we expected, the handshake failed // and we need to send a 400 response back. if (!handshakeComplete) { sendBadRequest(); return 0; } // Otherwise, send back the 101 response. super.flush(); } // If the buffer is empty, read a new frame off the wire. if (readBuffer_.empty) { if (!readFrame()) { return 0; } } auto size = min(readBuffer_.length, buf.length); buf[0..size] = readBuffer_[0..size]; readBuffer_ = readBuffer_[size..$]; return size; } override void write(in ubyte[] buf) { writeBuffer_ ~= buf; } override void flush() { if (writeBuffer_.empty) { return; } // Properly reset the write buffer even some of the protocol operations go // wrong. scope (exit) { writeBuffer_.length = 0; writeBuffer_.assumeSafeAppend(); } writeFrameHeader(); transport_.write(writeBuffer_); transport_.flush(); } protected: override string getHeader(size_t dataLength) { return "HTTP/1.1 101 Switching Protocols\r\n" ~ "Server: Thrift/" ~ VERSION ~ "\r\n" ~ "Upgrade: websocket\r\n" ~ "Connection: Upgrade\r\n" ~ "Sec-WebSocket-Accept: " ~ acceptKey_ ~ "\r\n" ~ "\r\n"; } override void parseHeader(const(ubyte)[] header) { auto split = findSplit(header, [':']); if (split[1].empty) { // No colon found. return; } static bool compToLower(ubyte a, ubyte b) { return toLower(a) == toLower(b); } if (startsWith!compToLower(split[0], cast(ubyte[])"upgrade")) { auto upgrade = stripLeft(cast(const(char)[])split[2]); upgrade_ = sicmp(upgrade, "websocket") == 0; } else if (startsWith!compToLower(split[0], cast(ubyte[])"connection")) { auto connection = stripLeft(cast(const(char)[])split[2]); connection_ = canFind(connection.toLower, "upgrade"); } else if (startsWith!compToLower(split[0], cast(ubyte[])"sec-websocket-key")) { auto secWebSocketKey = stripLeft(cast(const(char)[])split[2]); auto hash = sha1Of(secWebSocketKey ~ WEBSOCKET_GUID); acceptKey_ = Base64.encode(hash); secWebSocketKey_ = true; } else if (startsWith!compToLower(split[0], cast(ubyte[])"sec-websocket-version")) { auto secWebSocketVersion = stripLeft(cast(const(char)[])split[2]); secWebSocketVersion_ = sicmp(secWebSocketVersion, "13") == 0; } } override bool parseStatusLine(const(ubyte)[] status) { // Method SP Request-URI SP HTTP-Version CRLF. auto split = findSplit(status, [' ']); if (split[1].empty) { throw new TTransportException("Bad status: " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } auto uriVersion = split[2][countUntil!"a != b"(split[2], ' ') .. $]; if (!canFind(uriVersion, ' ')) { throw new TTransportException("Bad status: " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } if (split[0] == "GET") { // GET method ok, looking for content. return true; } throw new TTransportException("Bad status (unsupported method): " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } private: @property bool handshakeComplete() { return upgrade_ && connection_ && secWebSocketKey_ && secWebSocketVersion_; } void failConnection(CloseCode reason) { writeFrameHeader(Opcode.Close); transport_.write(nativeToBigEndian!ushort(reason)); transport_.flush(); transport_.close(); } void pong() { writeFrameHeader(Opcode.Pong); transport_.write(readBuffer_); transport_.flush(); } bool readFrame() { ubyte[8] headerBuffer; auto read = transport_.read(headerBuffer[0..2]); if (read < 2) { return false; } // Since Thrift has its own message end marker and we read frame by frame, // it doesn't really matter if the frame is marked as FIN. // Capture it only for debugging only. debug auto fin = (headerBuffer[0] & 0x80) != 0; // RSV1, RSV2, RSV3 if ((headerBuffer[0] & 0x70) != 0) { failConnection(CloseCode.ProtocolError); throw new TTransportException("Reserved bits must be zeroes", TTransportException.Type.CORRUPTED_DATA); } Opcode opcode; try { opcode = to!Opcode(headerBuffer[0] & 0x0F); } catch (ConvException) { failConnection(CloseCode.ProtocolError); throw new TTransportException("Unknown opcode", TTransportException.Type.CORRUPTED_DATA); } // Mask if ((headerBuffer[1] & 0x80) == 0) { failConnection(CloseCode.ProtocolError); throw new TTransportException("Messages from the client must be masked", TTransportException.Type.CORRUPTED_DATA); } // Read the length ulong payloadLength = headerBuffer[1] & 0x7F; if (payloadLength == 126) { read = transport_.read(headerBuffer[0..2]); if (read < 2) { return false; } payloadLength = bigEndianToNative!ushort(headerBuffer[0..2]); } else if (payloadLength == 127) { read = transport_.read(headerBuffer); if (read < headerBuffer.length) { return false; } payloadLength = bigEndianToNative!ulong(headerBuffer); if ((payloadLength & 0x8000000000000000) != 0) { failConnection(CloseCode.ProtocolError); throw new TTransportException("The most significant bit of the payload length must be zero", TTransportException.Type.CORRUPTED_DATA); } } // size_t is smaller than a ulong on a 32-bit system static if (size_t.max < ulong.max) { if(payloadLength > size_t.max) { failConnection(CloseCode.MessageTooBig); return false; } } auto length = cast(size_t)payloadLength; if (length > 0) { // Read the masking key read = transport_.read(headerBuffer[0..4]); if (read < 4) { return false; } readBuffer_ = new ubyte[](length); read = transport_.read(readBuffer_); if (read < length) { return false; } // Unmask the data for (size_t i = 0; i < length; i++) { readBuffer_[i] ^= headerBuffer[i % 4]; } debug writef("FIN=%d, Opcode=%X, length=%d, payload=%s\n", fin, opcode, length, binary ? readBuffer_.toHexString() : cast(string)readBuffer_); } switch (opcode) { case Opcode.Close: debug { if (length >= 2) { CloseCode closeCode; try { closeCode = to!CloseCode(bigEndianToNative!ushort(readBuffer_[0..2])); } catch (ConvException) { closeCode = CloseCode.NoStatusCode; } string closeReason; if (length == 2) { closeReason = to!string(cast(CloseCode)closeCode); } else { closeReason = cast(string)readBuffer_[2..$]; } writef("Connection closed: %d %s\n", closeCode, closeReason); } } transport_.close(); return false; case Opcode.Ping: pong(); return readFrame(); default: return true; } } void resetHandshake() { connection_ = false; secWebSocketKey_ = false; secWebSocketVersion_ = false; upgrade_ = false; } void sendBadRequest() { auto header = "HTTP/1.1 400 Bad Request\r\n" ~ "Server: Thrift/" ~ VERSION ~ "\r\n" ~ "\r\n"; transport_.write(cast(const(ubyte[]))header); transport_.flush(); transport_.close(); } void writeFrameHeader(Opcode opcode = Opcode.Continuation) { size_t headerSize = 1; if (writeBuffer_.length < 126) { ++headerSize; } else if (writeBuffer_.length < 65536) { headerSize += 3; } else { headerSize += 9; } // The server does not mask the response ubyte[] header = new ubyte[headerSize]; if (opcode == Opcode.Continuation) { header[0] = binary ? Opcode.Binary : Opcode.Text; } else { header[0] = opcode; } header[0] |= 0x80; if (writeBuffer_.length < 126) { header[1] = cast(ubyte)writeBuffer_.length; } else if (writeBuffer_.length < 65536) { header[1] = 126; header[2..4] = nativeToBigEndian(cast(ushort)writeBuffer_.length); } else { header[1] = 127; header[2..10] = nativeToBigEndian(cast(ulong)writeBuffer_.length); } transport_.write(header); } enum WEBSOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; TTransport transport_; string acceptKey_; bool connection_; bool secWebSocketKey_; bool secWebSocketVersion_; bool upgrade_; ubyte[] readBuffer_; ubyte[] writeBuffer_; } class TServerWebSocketTransportFactory(bool binary) : TTransportFactory { override TTransport getTransport(TTransport trans) { return new TServerWebSocketTransport!binary(trans); } } alias TServerBinaryWebSocketTransportFactory = TServerWebSocketTransportFactory!true; alias TServerTextWebSocketTransportFactory = TServerWebSocketTransportFactory!false; private enum CloseCode : ushort { NormalClosure = 1000, GoingAway = 1001, ProtocolError = 1002, UnsupportedDataType = 1003, NoStatusCode = 1005, AbnormalClosure = 1006, InvalidData = 1007, PolicyViolation = 1008, MessageTooBig = 1009, ExtensionExpected = 1010, UnexpectedError = 1011, NotSecure = 1015 } private enum Opcode : ubyte { Continuation = 0x0, Text = 0x1, Binary = 0x2, Close = 0x8, Ping = 0x9, Pong = 0xA } thrift-0.23.0/lib/d/src/thrift/transport/file.d0000664000175000017500000007603415165535636021607 0ustar00buildbuild00000000000000/* * 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. */ /** * Transports for reading from/writing to Thrift »log files«. * * These transports are not »stupid« sources and sinks just reading and * writing bytes from a file verbatim, but organize the contents in the form * of so-called »events«, which refers to the data written between two flush() * calls. * * Chunking is supported, events are guaranteed to never span chunk boundaries. * As a consequence, an event can never be larger than the chunk size. The * chunk size used is not saved with the file, so care has to be taken to make * sure the same chunk size is used for reading and writing. */ module thrift.transport.file; import core.thread : Thread; import std.array : empty; import std.algorithm : min, max; import std.concurrency; import std.conv : to; import std.datetime : dur, Duration; import std.datetime.stopwatch : AutoStart, StopWatch; import std.exception; import std.stdio : File; import thrift.base; import thrift.transport.base; /// The default chunk size, in bytes. enum DEFAULT_CHUNK_SIZE = 16 * 1024 * 1024; /// The type used to represent event sizes in the file. alias uint EventSize; version (BigEndian) { static assert(false, "Little endian byte order is assumed in thrift.transport.file."); } /** * A transport used to read log files. It can never be written to, calling * write() throws. * * Contrary to the C++ design, explicitly opening the transport/file before * using is necessary to allow manually closing the file without relying on the * object lifetime. Otherwise, it's a straight port of the C++ implementation. */ final class TFileReaderTransport : TBaseTransport { /** * Creates a new file writer transport. * * Params: * path = Path of the file to opperate on. */ this(string path) { path_ = path; chunkSize_ = DEFAULT_CHUNK_SIZE; readBufferSize_ = DEFAULT_READ_BUFFER_SIZE; readTimeout_ = DEFAULT_READ_TIMEOUT; corruptedEventSleepDuration_ = DEFAULT_CORRUPTED_EVENT_SLEEP_DURATION; maxEventSize = DEFAULT_MAX_EVENT_SIZE; } override bool isOpen() @property { return isOpen_; } override bool peek() { if (!isOpen) return false; // If there is no event currently processed, try fetching one from the // file. if (!currentEvent_) { currentEvent_ = readEvent(); if (!currentEvent_) { // Still nothing there, couldn't read a new event. return false; } } // check if there is anything to read return (currentEvent_.length - currentEventPos_) > 0; } override void open() { if (isOpen) return; try { file_ = File(path_, "rb"); } catch (Exception e) { throw new TTransportException("Error on opening input file.", TTransportException.Type.NOT_OPEN, __FILE__, __LINE__, e); } isOpen_ = true; } override void close() { if (!isOpen) return; file_.close(); isOpen_ = false; readState_.resetAllValues(); } override size_t read(ubyte[] buf) { enforce(isOpen, new TTransportException( "Cannot read if file is not open.", TTransportException.Type.NOT_OPEN)); // If there is no event currently processed, try fetching one from the // file. if (!currentEvent_) { currentEvent_ = readEvent(); if (!currentEvent_) { // Still nothing there, couldn't read a new event. return 0; } } auto len = buf.length; auto remaining = currentEvent_.length - currentEventPos_; if (remaining <= len) { // If less than the requested length is available, read as much as // possible. buf[0 .. remaining] = currentEvent_[currentEventPos_ .. $]; currentEvent_ = null; currentEventPos_ = 0; return remaining; } // There will still be data left in the buffer after reading, pass out len // bytes. buf[] = currentEvent_[currentEventPos_ .. currentEventPos_ + len]; currentEventPos_ += len; return len; } ulong getNumChunks() { enforce(isOpen, new TTransportException( "Cannot get number of chunks if file not open.", TTransportException.Type.NOT_OPEN)); try { auto fileSize = file_.size(); if (fileSize == 0) { // Empty files have no chunks. return 0; } return ((fileSize)/chunkSize_) + 1; } catch (Exception e) { throw new TTransportException("Error getting file size.", __FILE__, __LINE__, e); } } ulong getCurChunk() { return offset_ / chunkSize_; } void seekToChunk(long chunk) { enforce(isOpen, new TTransportException( "Cannot get number of chunks if file not open.", TTransportException.Type.NOT_OPEN)); auto numChunks = getNumChunks(); if (chunk < 0) { // Count negative indices from the end. chunk += numChunks; } if (chunk < 0) { logError("Incorrect chunk number for reverse seek, seeking to " ~ "beginning instead: %s", chunk); chunk = 0; } bool seekToEnd; long minEndOffset; if (chunk >= numChunks) { logError("Trying to seek to non-existing chunk, seeking to " ~ "end of file instead: %s", chunk); seekToEnd = true; chunk = numChunks - 1; // this is the min offset to process events till minEndOffset = file_.size(); } readState_.resetAllValues(); currentEvent_ = null; try { file_.seek(chunk * chunkSize_); offset_ = chunk * chunkSize_; } catch (Exception e) { throw new TTransportException("Error seeking to chunk", __FILE__, __LINE__, e); } if (seekToEnd) { // Never wait on the end of the file for new content, we just want to // find the last one. auto oldReadTimeout = readTimeout_; scope (exit) readTimeout_ = oldReadTimeout; readTimeout_ = dur!"hnsecs"(0); // Keep on reading unti the last event at point of seekToChunk call. while ((offset_ + readState_.bufferPos_) < minEndOffset) { if (readEvent() is null) { break; } } } } void seekToEnd() { seekToChunk(getNumChunks()); } /** * The size of the chunks the file is divided into, in bytes. */ ulong chunkSize() @property const { return chunkSize_; } /// ditto void chunkSize(ulong value) @property { enforce(!isOpen, new TTransportException( "Cannot set chunk size after TFileReaderTransport has been opened.")); enforce(value > EventSize.sizeof, new TTransportException("Chunks must " ~ "be large enough to accommodate at least a single byte of payload data.")); chunkSize_ = value; } /** * If positive, wait the specified duration for new data when arriving at * end of file. If negative, wait forever (tailing mode), waking up to check * in the specified interval. If zero, do not wait at all. * * Defaults to 500 ms. */ Duration readTimeout() @property const { return readTimeout_; } /// ditto void readTimeout(Duration value) @property { readTimeout_ = value; } /// ditto enum DEFAULT_READ_TIMEOUT = dur!"msecs"(500); /** * Read buffer size, in bytes. * * Defaults to 1 MiB. */ size_t readBufferSize() @property const { return readBufferSize_; } /// ditto void readBufferSize(size_t value) @property { if (readBuffer_) { enforce(value <= readBufferSize_, "Cannot shrink read buffer after first read."); readBuffer_.length = value; } readBufferSize_ = value; } /// ditto enum DEFAULT_READ_BUFFER_SIZE = 1 * 1024 * 1024; /** * Arbitrary event size limit, in bytes. Must be smaller than chunk size. * * Defaults to zero (no limit). */ size_t maxEventSize() @property const { return maxEventSize_; } /// ditto void maxEventSize(size_t value) @property { enforce(value <= chunkSize_ - EventSize.sizeof, "Events cannot span " ~ "mutiple chunks, maxEventSize must be smaller than chunk size."); maxEventSize_ = value; } /// ditto enum DEFAULT_MAX_EVENT_SIZE = 0; /** * The interval at which the thread wakes up to check for the next chunk * in tailing mode. * * Defaults to one second. */ Duration corruptedEventSleepDuration() const { return corruptedEventSleepDuration_; } /// ditto void corruptedEventSleepDuration(Duration value) { corruptedEventSleepDuration_ = value; } /// ditto enum DEFAULT_CORRUPTED_EVENT_SLEEP_DURATION = dur!"seconds"(1); /** * The maximum number of corrupted events tolerated before the whole chunk * is skipped. * * Defaults to zero. */ uint maxCorruptedEvents() @property const { return maxCorruptedEvents_; } /// ditto void maxCorruptedEvents(uint value) @property { maxCorruptedEvents_ = value; } /// ditto enum DEFAULT_MAX_CORRUPTED_EVENTS = 0; private: ubyte[] readEvent() { if (!readBuffer_) { readBuffer_ = new ubyte[readBufferSize_]; } bool timeoutExpired; while (1) { // read from the file if read buffer is exhausted if (readState_.bufferPos_ == readState_.bufferLen_) { // advance the offset pointer offset_ += readState_.bufferLen_; try { // Need to clear eof flag before reading, otherwise tailing a file // does not work. file_.clearerr(); auto usedBuf = file_.rawRead(readBuffer_); readState_.bufferLen_ = usedBuf.length; } catch (Exception e) { readState_.resetAllValues(); throw new TTransportException("Error while reading from file", __FILE__, __LINE__, e); } readState_.bufferPos_ = 0; readState_.lastDispatchPos_ = 0; if (readState_.bufferLen_ == 0) { // Reached end of file. if (readTimeout_ < dur!"hnsecs"(0)) { // Tailing mode, sleep for the specified duration and try again. Thread.sleep(-readTimeout_); continue; } else if (readTimeout_ == dur!"hnsecs"(0) || timeoutExpired) { // Either no timeout set, or it has already expired. readState_.resetState(0); return null; } else { // Timeout mode, sleep for the specified amount of time and retry. Thread.sleep(readTimeout_); timeoutExpired = true; continue; } } } // Attempt to read an event from the buffer. while (readState_.bufferPos_ < readState_.bufferLen_) { if (readState_.readingSize_) { if (readState_.eventSizeBuffPos_ == 0) { if ((offset_ + readState_.bufferPos_)/chunkSize_ != ((offset_ + readState_.bufferPos_ + 3)/chunkSize_)) { readState_.bufferPos_++; continue; } } readState_.eventSizeBuff_[readState_.eventSizeBuffPos_++] = readBuffer_[readState_.bufferPos_++]; if (readState_.eventSizeBuffPos_ == 4) { auto size = (cast(uint[])readState_.eventSizeBuff_)[0]; if (size == 0) { // This is part of the zero padding between chunks. readState_.resetState(readState_.lastDispatchPos_); continue; } // got a valid event readState_.readingSize_ = false; readState_.eventLen_ = size; readState_.eventPos_ = 0; // check if the event is corrupted and perform recovery if required if (isEventCorrupted()) { performRecovery(); // start from the top break; } } } else { if (!readState_.event_) { readState_.event_ = new ubyte[readState_.eventLen_]; } // take either the entire event or the remaining bytes in the buffer auto reclaimBuffer = min(readState_.bufferLen_ - readState_.bufferPos_, readState_.eventLen_ - readState_.eventPos_); // copy data from read buffer into event buffer readState_.event_[ readState_.eventPos_ .. readState_.eventPos_ + reclaimBuffer ] = readBuffer_[ readState_.bufferPos_ .. readState_.bufferPos_ + reclaimBuffer ]; // increment position ptrs readState_.eventPos_ += reclaimBuffer; readState_.bufferPos_ += reclaimBuffer; // check if the event has been read in full if (readState_.eventPos_ == readState_.eventLen_) { // Reset the read state and return the completed event. auto completeEvent = readState_.event_; readState_.event_ = null; readState_.resetState(readState_.bufferPos_); return completeEvent; } } } } } bool isEventCorrupted() { if ((maxEventSize_ > 0) && (readState_.eventLen_ > maxEventSize_)) { // Event size is larger than user-speficied max-event size logError("Corrupt event read: Event size (%s) greater than max " ~ "event size (%s)", readState_.eventLen_, maxEventSize_); return true; } else if (readState_.eventLen_ > chunkSize_) { // Event size is larger than chunk size logError("Corrupt event read: Event size (%s) greater than chunk " ~ "size (%s)", readState_.eventLen_, chunkSize_); return true; } else if (((offset_ + readState_.bufferPos_ - EventSize.sizeof) / chunkSize_) != ((offset_ + readState_.bufferPos_ + readState_.eventLen_ - EventSize.sizeof) / chunkSize_)) { // Size indicates that event crosses chunk boundary logError("Read corrupt event. Event crosses chunk boundary. " ~ "Event size: %s. Offset: %s", readState_.eventLen_, (offset_ + readState_.bufferPos_ + EventSize.sizeof) ); return true; } return false; } void performRecovery() { // perform some kickass recovery auto curChunk = getCurChunk(); if (lastBadChunk_ == curChunk) { numCorruptedEventsInChunk_++; } else { lastBadChunk_ = curChunk; numCorruptedEventsInChunk_ = 1; } if (numCorruptedEventsInChunk_ < maxCorruptedEvents_) { // maybe there was an error in reading the file from disk // seek to the beginning of chunk and try again seekToChunk(curChunk); } else { // Just skip ahead to the next chunk if we not already at the last chunk. if (curChunk != (getNumChunks() - 1)) { seekToChunk(curChunk + 1); } else if (readTimeout_ < dur!"hnsecs"(0)) { // We are in tailing mode, wait until there is enough data to start // the next chunk. while(curChunk == (getNumChunks() - 1)) { Thread.sleep(corruptedEventSleepDuration_); } seekToChunk(curChunk + 1); } else { // Pretty hosed at this stage, rewind the file back to the last // successful point and punt on the error. readState_.resetState(readState_.lastDispatchPos_); currentEvent_ = null; currentEventPos_ = 0; throw new TTransportException("File corrupted at offset: " ~ to!string(offset_ + readState_.lastDispatchPos_), TTransportException.Type.CORRUPTED_DATA); } } } string path_; File file_; bool isOpen_; long offset_; ubyte[] currentEvent_; size_t currentEventPos_; ulong chunkSize_; Duration readTimeout_; size_t maxEventSize_; // Read buffer – lazily allocated on the first read(). ubyte[] readBuffer_; size_t readBufferSize_; static struct ReadState { ubyte[] event_; size_t eventLen_; size_t eventPos_; // keep track of event size ubyte[4] eventSizeBuff_; ubyte eventSizeBuffPos_; bool readingSize_ = true; // read buffer variables size_t bufferPos_; size_t bufferLen_; // last successful dispatch point size_t lastDispatchPos_; void resetState(size_t lastDispatchPos) { readingSize_ = true; eventSizeBuffPos_ = 0; lastDispatchPos_ = lastDispatchPos; } void resetAllValues() { resetState(0); bufferPos_ = 0; bufferLen_ = 0; event_ = null; } } ReadState readState_; ulong lastBadChunk_; uint maxCorruptedEvents_; uint numCorruptedEventsInChunk_; Duration corruptedEventSleepDuration_; } /** * A transport used to write log files. It can never be read from, calling * read() throws. * * Contrary to the C++ design, explicitly opening the transport/file before * using is necessary to allow manually closing the file without relying on the * object lifetime. */ final class TFileWriterTransport : TBaseTransport { /** * Creates a new file writer transport. * * Params: * path = Path of the file to opperate on. */ this(string path) { path_ = path; chunkSize_ = DEFAULT_CHUNK_SIZE; eventBufferSize_ = DEFAULT_EVENT_BUFFER_SIZE; ioErrorSleepDuration = DEFAULT_IO_ERROR_SLEEP_DURATION; maxFlushBytes_ = DEFAULT_MAX_FLUSH_BYTES; maxFlushInterval_ = DEFAULT_MAX_FLUSH_INTERVAL; } override bool isOpen() @property { return isOpen_; } /** * A file writer transport can never be read from. */ override bool peek() { return false; } override void open() { if (isOpen) return; writerThread_ = spawn( &writerThread, path_, chunkSize_, maxFlushBytes_, maxFlushInterval_, ioErrorSleepDuration_ ); setMaxMailboxSize(writerThread_, eventBufferSize_, OnCrowding.block); isOpen_ = true; } /** * Closes the transport, i.e. the underlying file and the writer thread. */ override void close() { if (!isOpen) return; send(writerThread_, ShutdownMessage(), thisTid); receive((ShutdownMessage msg, Tid tid){}); isOpen_ = false; } /** * Enqueues the passed slice of data for writing and immediately returns. * write() only blocks if the event buffer has been exhausted. * * The transport must be open when calling this. * * Params: * buf = Slice of data to write. */ override void write(in ubyte[] buf) { enforce(isOpen, new TTransportException( "Cannot write to non-open file.", TTransportException.Type.NOT_OPEN)); if (buf.empty) { logError("Cannot write empty event, skipping."); return; } auto maxSize = chunkSize - EventSize.sizeof; enforce(buf.length <= maxSize, new TTransportException( "Cannot write more than " ~ to!string(maxSize) ~ "bytes at once due to chunk size.")); send(writerThread_, buf.idup); } /** * Flushes any pending data to be written. * * The transport must be open when calling this. * * Throws: TTransportException if an error occurs. */ override void flush() { enforce(isOpen, new TTransportException( "Cannot flush file if not open.", TTransportException.Type.NOT_OPEN)); send(writerThread_, FlushMessage(), thisTid); receive((FlushMessage msg, Tid tid){}); } /** * The size of the chunks the file is divided into, in bytes. * * A single event (write call) never spans multiple chunks – this * effectively limits the event size to chunkSize - EventSize.sizeof. */ ulong chunkSize() @property { return chunkSize_; } /// ditto void chunkSize(ulong value) @property { enforce(!isOpen, new TTransportException( "Cannot set chunk size after TFileWriterTransport has been opened.")); chunkSize_ = value; } /** * The maximum number of write() calls buffered, or zero for no limit. * * If the buffer is exhausted, write() will block until space becomes * available. */ size_t eventBufferSize() @property { return eventBufferSize_; } /// ditto void eventBufferSize(size_t value) @property { eventBufferSize_ = value; if (isOpen) { setMaxMailboxSize(writerThread_, value, OnCrowding.throwException); } } /// ditto enum DEFAULT_EVENT_BUFFER_SIZE = 10_000; /** * Maximum number of bytes buffered before writing and flushing the file * to disk. * * Currently cannot be set after the first call to write(). */ size_t maxFlushBytes() @property { return maxFlushBytes_; } /// ditto void maxFlushBytes(size_t value) @property { maxFlushBytes_ = value; if (isOpen) { send(writerThread_, FlushBytesMessage(value)); } } /// ditto enum DEFAULT_MAX_FLUSH_BYTES = 1000 * 1024; /** * Maximum interval between flushing the file to disk. * * Currenlty cannot be set after the first call to write(). */ Duration maxFlushInterval() @property { return maxFlushInterval_; } /// ditto void maxFlushInterval(Duration value) @property { maxFlushInterval_ = value; if (isOpen) { send(writerThread_, FlushIntervalMessage(value)); } } /// ditto enum DEFAULT_MAX_FLUSH_INTERVAL = dur!"seconds"(3); /** * When the writer thread encounteres an I/O error, it goes pauses for a * short time before trying to reopen the output file. This controls the * sleep duration. */ Duration ioErrorSleepDuration() @property { return ioErrorSleepDuration_; } /// ditto void ioErrorSleepDuration(Duration value) @property { ioErrorSleepDuration_ = value; if (isOpen) { send(writerThread_, FlushIntervalMessage(value)); } } /// ditto enum DEFAULT_IO_ERROR_SLEEP_DURATION = dur!"msecs"(500); private: string path_; ulong chunkSize_; size_t eventBufferSize_; Duration ioErrorSleepDuration_; size_t maxFlushBytes_; Duration maxFlushInterval_; bool isOpen_; Tid writerThread_; } private { // Signals that the file should be flushed on disk. Sent to the writer // thread and sent back along with the tid for confirmation. struct FlushMessage {} // Signals that the writer thread should close the file and shut down. Sent // to the writer thread and sent back along with the tid for confirmation. struct ShutdownMessage {} struct FlushBytesMessage { size_t value; } struct FlushIntervalMessage { Duration value; } struct IoErrorSleepDurationMessage { Duration value; } void writerThread( string path, ulong chunkSize, size_t maxFlushBytes, Duration maxFlushInterval, Duration ioErrorSleepDuration ) { bool errorOpening; File file; ulong offset; try { // Open file in appending and binary mode. file = File(path, "ab"); offset = file.tell(); } catch (Exception e) { logError("Error on opening output file in writer thread: %s", e); errorOpening = true; } auto flushTimer = StopWatch(AutoStart.yes); size_t unflushedByteCount; Tid shutdownRequestTid; bool shutdownRequested; while (true) { if (shutdownRequested) break; bool forceFlush; Tid flushRequestTid; receiveTimeout(max(dur!"hnsecs"(0), maxFlushInterval - flushTimer.peek()), (immutable(ubyte)[] data) { while (errorOpening) { logError("Writer thread going to sleep for %s µs due to IO errors", ioErrorSleepDuration.total!"usecs"); // Sleep for ioErrorSleepDuration, being ready to be interrupted // by shutdown requests. auto timedOut = receiveTimeout(ioErrorSleepDuration, (ShutdownMessage msg, Tid tid){ shutdownRequestTid = tid; }); if (!timedOut) { // We got a shutdown request, just drop all events and exit the // main loop as to not block application shutdown with our tries // which we must assume to fail. break; } try { file = File(path, "ab"); unflushedByteCount = 0; errorOpening = false; logError("Output file %s reopened during writer thread error " ~ "recovery", path); } catch (Exception e) { logError("Unable to reopen output file %s during writer " ~ "thread error recovery", path); } } // Make sure the event does not cross the chunk boundary by writing // a padding consisting of zeroes if it would. auto chunk1 = offset / chunkSize; auto chunk2 = (offset + EventSize.sizeof + data.length - 1) / chunkSize; if (chunk1 != chunk2) { // TODO: The C++ implementation refetches the offset here to »keep // in sync« – why would this be needed? auto padding = cast(size_t) ((((offset / chunkSize) + 1) * chunkSize) - offset); auto zeroes = new ubyte[padding]; file.rawWrite(zeroes); unflushedByteCount += padding; offset += padding; } // TODO: 2 syscalls here, is this a problem performance-wise? // Probably abysmal performance on Windows due to rawWrite // implementation. uint len = cast(uint)data.length; file.rawWrite(cast(ubyte[])(&len)[0..1]); file.rawWrite(data); auto bytesWritten = EventSize.sizeof + data.length; unflushedByteCount += bytesWritten; offset += bytesWritten; }, (FlushBytesMessage msg) { maxFlushBytes = msg.value; }, (FlushIntervalMessage msg) { maxFlushInterval = msg.value; }, (IoErrorSleepDurationMessage msg) { ioErrorSleepDuration = msg.value; }, (FlushMessage msg, Tid tid) { forceFlush = true; flushRequestTid = tid; }, (OwnerTerminated msg) { shutdownRequested = true; }, (ShutdownMessage msg, Tid tid) { shutdownRequested = true; shutdownRequestTid = tid; } ); if (errorOpening) continue; bool flush; if (forceFlush || shutdownRequested || unflushedByteCount > maxFlushBytes) { flush = true; } else if (cast(Duration)flushTimer.peek() > maxFlushInterval) { if (unflushedByteCount == 0) { // If the flush timer is due, but no data has been written, don't // needlessly fsync, but do reset the timer. flushTimer.reset(); } else { flush = true; } } if (flush) { file.flush(); flushTimer.reset(); unflushedByteCount = 0; if (forceFlush) send(flushRequestTid, FlushMessage(), thisTid); } } file.close(); if (shutdownRequestTid != Tid.init) { send(shutdownRequestTid, ShutdownMessage(), thisTid); } } } version (unittest) { import core.memory : GC; import std.file; } unittest { void tryRemove(string fileName) { try { remove(fileName); } catch (Exception) {} } immutable fileName = "unittest.dat.tmp"; enforce(!exists(fileName), "Unit test output file " ~ fileName ~ " already exists."); /* * Check the most basic reading/writing operations. */ { scope (exit) tryRemove(fileName); auto writer = new TFileWriterTransport(fileName); writer.open(); scope (exit) writer.close(); writer.write([1, 2]); writer.write([3, 4]); writer.write([5, 6, 7]); writer.flush(); auto reader = new TFileReaderTransport(fileName); reader.open(); scope (exit) reader.close(); auto buf = new ubyte[7]; reader.readAll(buf); enforce(buf == [1, 2, 3, 4, 5, 6, 7]); } /* * Check that chunking works as expected. */ { scope (exit) tryRemove(fileName); static assert(EventSize.sizeof == 4); enum CHUNK_SIZE = 10; // Write some contents to the file. { auto writer = new TFileWriterTransport(fileName); writer.chunkSize = CHUNK_SIZE; writer.open(); scope (exit) writer.close(); writer.write([0xde]); writer.write([0xad]); // Chunk boundary here. writer.write([0xbe]); // The next write doesn't fit in the five bytes remaining, so we expect // padding zero bytes to be written. writer.write([0xef, 0x12]); try { writer.write(new ubyte[CHUNK_SIZE]); enforce(false, "Could write event not fitting in a single chunk."); } catch (TTransportException e) {} writer.flush(); } // Check the raw contents of the file to see if chunk padding was written // as expected. auto file = File(fileName, "r"); enforce(file.size == 26); auto written = new ubyte[26]; file.rawRead(written); enforce(written == [ 1, 0, 0, 0, 0xde, 1, 0, 0, 0, 0xad, 1, 0, 0, 0, 0xbe, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0xef, 0x12 ]); // Read the data back in, getting all the events at once. { auto reader = new TFileReaderTransport(fileName); reader.chunkSize = CHUNK_SIZE; reader.open(); scope (exit) reader.close(); auto buf = new ubyte[5]; reader.readAll(buf); enforce(buf == [0xde, 0xad, 0xbe, 0xef, 0x12]); } } /* * Make sure that close() exits "quickly", i.e. that there is no problem * with the worker thread waking up. */ { import std.conv : text; enum NUM_ITERATIONS = 1000; uint numOver = 0; foreach (n; 0 .. NUM_ITERATIONS) { scope (exit) tryRemove(fileName); auto transport = new TFileWriterTransport(fileName); transport.open(); // Write something so that the writer thread gets started. transport.write(cast(ubyte[])"foo"); // Every other iteration, also call flush(), just in case that potentially // has any effect on how the writer thread wakes up. if (n & 0x1) { transport.flush(); } // Time the call to close(). auto sw = StopWatch(AutoStart.yes); transport.close(); sw.stop(); // If any attempt takes more than 500ms, treat that as a fatal failure to // avoid looping over a potentially very slow operation. enforce(sw.peek().total!"msecs" < 1500, text("close() took ", sw.peek().total!"msecs", "ms.")); // Normally, it takes less than 5ms on my dev box. // However, if the box is heavily loaded, some of the test runs can take // longer. Additionally, on a Windows Server 2008 instance running in // a VirtualBox VM, it has been observed that about a quarter of the runs // takes (217 ± 1) ms, for reasons not yet known. if (sw.peek().total!"msecs" > 50) { ++numOver; } // Force garbage collection runs every now and then to make sure we // don't run out of OS thread handles. if (!(n % 100)) GC.collect(); } // Make sure fewer than a third of the runs took longer than 5ms. enforce(numOver < NUM_ITERATIONS / 3, text(numOver, " iterations took more than 10 ms.")); } } thrift-0.23.0/lib/d/src/thrift/transport/base.d0000664000175000017500000002552415165535636021600 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.base; import core.stdc.string : strerror; import std.conv : text; import thrift.base; /** * An entity data can be read from and/or written to. * * A TTransport implementation may capable of either reading or writing, but * not necessarily both. */ interface TTransport { /** * Whether this transport is open. * * If a transport is closed, it can be opened by calling open(), and vice * versa for close(). * * While a transport should always be open when trying to read/write data, * the related functions do not necessarily fail when called for a closed * transport. Situations like this could occur e.g. with a wrapper * transport which buffers data when the underlying transport has already * been closed (possibly because the connection was abruptly closed), but * there is still data left to be read in the buffers. This choice has been * made to simplify transport implementations, in terms of both code * complexity and runtime overhead. */ bool isOpen() @property; /** * Tests whether there is more data to read or if the remote side is * still open. * * A typical use case would be a server checking if it should process * another request on the transport. */ bool peek(); /** * Opens the transport for communications. * * If the transport is already open, nothing happens. * * Throws: TTransportException if opening fails. */ void open(); /** * Closes the transport. * * If the transport is not open, nothing happens. * * Throws: TTransportException if closing fails. */ void close(); /** * Attempts to fill the given buffer by reading data. * * For potentially blocking data sources (e.g. sockets), read() will only * block if no data is available at all. If there is some data available, * but waiting for new data to arrive would be required to fill the whole * buffer, the readily available data will be immediately returned – use * readAll() if you want to wait until the whole buffer is filled. * * Params: * buf = Slice to use as buffer. * * Returns: How many bytes were actually read * * Throws: TTransportException if an error occurs. */ size_t read(ubyte[] buf); /** * Fills the given buffer by reading data into it, failing if not enough * data is available. * * Params: * buf = Slice to use as buffer. * * Throws: TTransportException if insufficient data is available or reading * fails altogether. */ void readAll(ubyte[] buf); /** * Must be called by clients when read is completed. * * Implementations can choose to perform a transport-specific action, e.g. * logging the request to a file. * * Returns: The number of bytes read if available, 0 otherwise. */ size_t readEnd(); /** * Writes the passed slice of data. * * Note: You must call flush() to ensure the data is actually written, * and available to be read back in the future. Destroying a TTransport * object does not automatically flush pending data – if you destroy a * TTransport object with written but unflushed data, that data may be * discarded. * * Params: * buf = Slice of data to write. * * Throws: TTransportException if an error occurs. */ void write(in ubyte[] buf); /** * Must be called by clients when write is completed. * * Implementations can choose to perform a transport-specific action, e.g. * logging the request to a file. * * Returns: The number of bytes written if available, 0 otherwise. */ size_t writeEnd(); /** * Flushes any pending data to be written. * * Must be called before destruction to ensure writes are actually complete, * otherwise pending data may be discarded. Typically used with buffered * transport mechanisms. * * Throws: TTransportException if an error occurs. */ void flush(); /** * Attempts to return a slice of len bytes of incoming data, * possibly copied into buf, not consuming them (i.e.: a later read will * return the same data). * * This method is meant to support protocols that need to read variable- * length fields. They can attempt to borrow the maximum amount of data that * they will need, then consume() what they actually use. Some * transports will not support this method and others will fail occasionally, * so protocols must be prepared to fall back to read() if * borrow fails. * * The transport must be open when calling this. * * Params: * buf = A buffer where the data can be stored if needed, or null to * indicate that the caller is not supplying storage, but would like a * slice of an internal buffer, if available. * len = The number of bytes to borrow. * * Returns: If the borrow succeeds, a slice containing the borrowed data, * null otherwise. The slice will be at least as long as requested, but * may be longer if the returned slice points into an internal buffer * rather than buf. * * Throws: TTransportException if an error occurs. */ const(ubyte)[] borrow(ubyte* buf, size_t len) out (result) { // FIXME: Commented out because len gets corrupted in // thrift.transport.memory borrow() unittest. version(none) assert(result is null || result.length >= len, "Buffer returned by borrow() too short."); } /** * Remove len bytes from the transport. This must always follow a borrow * of at least len bytes, and should always succeed. * * The transport must be open when calling this. * * Params: * len = Number of bytes to consume. * * Throws: TTransportException if an error occurs. */ void consume(size_t len); } /** * Provides basic fall-back implementations of the TTransport interface. */ class TBaseTransport : TTransport { override bool isOpen() @property { return false; } override bool peek() { return isOpen; } override void open() { throw new TTransportException("Cannot open TBaseTransport.", TTransportException.Type.NOT_IMPLEMENTED); } override void close() { throw new TTransportException("Cannot close TBaseTransport.", TTransportException.Type.NOT_IMPLEMENTED); } override size_t read(ubyte[] buf) { throw new TTransportException("Cannot read from a TBaseTransport.", TTransportException.Type.NOT_IMPLEMENTED); } override void readAll(ubyte[] buf) { size_t have; while (have < buf.length) { size_t get = read(buf[have..$]); if (get <= 0) { throw new TTransportException(text("Could not readAll() ", buf.length, " bytes as no more data was available after ", have, " bytes."), TTransportException.Type.END_OF_FILE); } have += get; } } override size_t readEnd() { // Do nothing by default, not needed by all implementations. return 0; } override void write(in ubyte[] buf) { throw new TTransportException("Cannot write to a TBaseTransport.", TTransportException.Type.NOT_IMPLEMENTED); } override size_t writeEnd() { // Do nothing by default, not needed by all implementations. return 0; } override void flush() { // Do nothing by default, not needed by all implementations. } override const(ubyte)[] borrow(ubyte* buf, size_t len) { // borrow() is allowed to fail anyway, so just return null. return null; } override void consume(size_t len) { throw new TTransportException("Cannot consume from a TBaseTransport.", TTransportException.Type.NOT_IMPLEMENTED); } protected: this() {} } /** * Makes a TTransport which wraps a given source transport in some way. * * A common use case is inside server implementations, where the raw client * connections accepted from e.g. TServerSocket need to be wrapped into * buffered or compressed transports. */ class TTransportFactory { /** * Default implementation does nothing, just returns the transport given. */ TTransport getTransport(TTransport trans) { return trans; } } /** * Transport factory for transports which simply wrap an underlying TTransport * without requiring additional configuration. */ class TWrapperTransportFactory(T) if ( is(T : TTransport) && __traits(compiles, new T(TTransport.init)) ) : TTransportFactory { override T getTransport(TTransport trans) { return new T(trans); } } /** * Transport-level exception. */ class TTransportException : TException { /** * Error codes for the various types of exceptions. */ enum Type { UNKNOWN, /// NOT_OPEN, /// TIMED_OUT, /// END_OF_FILE, /// INTERRUPTED, /// BAD_ARGS, /// CORRUPTED_DATA, /// INTERNAL_ERROR, /// NOT_IMPLEMENTED /// } /// this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { static string msgForType(Type type) { switch (type) { case Type.UNKNOWN: return "Unknown transport exception"; case Type.NOT_OPEN: return "Transport not open"; case Type.TIMED_OUT: return "Timed out"; case Type.END_OF_FILE: return "End of file"; case Type.INTERRUPTED: return "Interrupted"; case Type.BAD_ARGS: return "Invalid arguments"; case Type.CORRUPTED_DATA: return "Corrupted Data"; case Type.INTERNAL_ERROR: return "Internal error"; case Type.NOT_IMPLEMENTED: return "Not implemented"; default: return "(Invalid exception type)"; } } this(msgForType(type), type, file, line, next); } /// this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this(msg, Type.UNKNOWN, file, line, next); } /// this(string msg, Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); type_ = type; } /// Type type() const nothrow @property { return type_; } protected: Type type_; } /** * Meta-programming helper returning whether the passed type is a TTransport * implementation. */ template isTTransport(T) { enum isTTransport = is(T : TTransport); } thrift-0.23.0/lib/d/src/thrift/transport/http.d0000664000175000017500000003026415165535636021642 0ustar00buildbuild00000000000000/* * 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. */ /** * HTTP tranpsort implementation, modelled after the C++ one. * * Unfortunately, libcurl is quite heavyweight and supports only client-side * applications. This is an implementation of the basic HTTP/1.1 parts * supporting HTTP 100 Continue, chunked transfer encoding, keepalive, etc. */ module thrift.transport.http; import std.algorithm : canFind, countUntil, endsWith, findSplit, min, startsWith; import std.ascii : toLower; import std.array : empty; import std.conv : parse, to; import std.datetime : Clock, UTC; import std.string : stripLeft; import thrift.base : VERSION; import thrift.transport.base; import thrift.transport.memory; import thrift.transport.socket; /** * Base class for both client- and server-side HTTP transports. */ abstract class THttpTransport : TBaseTransport { this(TTransport transport) { transport_ = transport; readHeaders_ = true; httpBuf_ = new ubyte[HTTP_BUFFER_SIZE]; httpBufRemaining_ = httpBuf_[0 .. 0]; readBuffer_ = new TMemoryBuffer; writeBuffer_ = new TMemoryBuffer; } override bool isOpen() { return transport_.isOpen(); } override bool peek() { return transport_.peek(); } override void open() { transport_.open(); } override void close() { transport_.close(); } override size_t read(ubyte[] buf) { if (!readBuffer_.peek()) { readBuffer_.reset(); if (!refill()) return 0; if (readHeaders_) { readHeaders(); } size_t got; if (chunked_) { got = readChunked(); } else { got = readContent(contentLength_); } readHeaders_ = true; if (got == 0) return 0; } return readBuffer_.read(buf); } override size_t readEnd() { // Read any pending chunked data (footers etc.) if (chunked_) { while (!chunkedDone_) { readChunked(); } } return 0; } override void write(in ubyte[] buf) { writeBuffer_.write(buf); } override void flush() { auto data = writeBuffer_.getContents(); string header = getHeader(data.length); transport_.write(cast(const(ubyte)[]) header); transport_.write(data); transport_.flush(); // Reset the buffer and header variables. writeBuffer_.reset(); readHeaders_ = true; } /** * The size of the buffer to read HTTP requests into, in bytes. Will expand * as required. */ enum HTTP_BUFFER_SIZE = 1024; protected: abstract string getHeader(size_t dataLength); abstract bool parseStatusLine(const(ubyte)[] status); void parseHeader(const(ubyte)[] header) { auto split = findSplit(header, [':']); if (split[1].empty) { // No colon found. return; } static bool compToLower(ubyte a, ubyte b) { return toLower(cast(char)a) == toLower(cast(char)b); } if (startsWith!compToLower(split[0], cast(ubyte[])"transfer-encoding")) { if (endsWith!compToLower(split[2], cast(ubyte[])"chunked")) { chunked_ = true; } } else if (startsWith!compToLower(split[0], cast(ubyte[])"content-length")) { chunked_ = false; auto lengthString = stripLeft(cast(const(char)[])split[2]); contentLength_ = parse!size_t(lengthString); } } private: ubyte[] readLine() { while (true) { auto split = findSplit(httpBufRemaining_, cast(ubyte[])"\r\n"); if (split[1].empty) { // No CRLF yet, move whatever we have now to front and refill. if (httpBufRemaining_.empty) { httpBufRemaining_ = httpBuf_[0 .. 0]; } else { httpBuf_[0 .. httpBufRemaining_.length] = httpBufRemaining_; httpBufRemaining_ = httpBuf_[0 .. httpBufRemaining_.length]; } if (!refill()) { auto buf = httpBufRemaining_; httpBufRemaining_ = httpBufRemaining_[$ - 1 .. $ - 1]; return buf; } } else { // Set the remaining buffer to the part after \r\n and return the part // (line) before it. httpBufRemaining_ = split[2]; return split[0]; } } } void readHeaders() { // Initialize headers state variables contentLength_ = 0; chunked_ = false; chunkedDone_ = false; chunkSize_ = 0; // Control state flow bool statusLine = true; bool finished; // Loop until headers are finished while (true) { auto line = readLine(); if (line.length == 0) { if (finished) { readHeaders_ = false; return; } else { // Must have been an HTTP 100, keep going for another status line statusLine = true; } } else { if (statusLine) { statusLine = false; finished = parseStatusLine(line); } else { parseHeader(line); } } } } size_t readChunked() { size_t length; auto line = readLine(); size_t chunkSize; try { auto charLine = cast(char[])line; chunkSize = parse!size_t(charLine, 16); } catch (Exception e) { throw new TTransportException("Invalid chunk size: " ~ to!string(line), TTransportException.Type.CORRUPTED_DATA); } if (chunkSize == 0) { readChunkedFooters(); } else { // Read data content length += readContent(chunkSize); // Read trailing CRLF after content readLine(); } return length; } void readChunkedFooters() { while (true) { auto line = readLine(); if (line.length == 0) { chunkedDone_ = true; break; } } } size_t readContent(size_t size) { auto need = size; while (need > 0) { if (httpBufRemaining_.length == 0) { // We have given all the data, reset position to head of the buffer. httpBufRemaining_ = httpBuf_[0 .. 0]; if (!refill()) return size - need; } auto give = min(httpBufRemaining_.length, need); readBuffer_.write(cast(ubyte[])httpBufRemaining_[0 .. give]); httpBufRemaining_ = httpBufRemaining_[give .. $]; need -= give; } return size; } bool refill() { // Is there a nicer way to do this? auto indexBegin = httpBufRemaining_.ptr - httpBuf_.ptr; auto indexEnd = indexBegin + httpBufRemaining_.length; if (httpBuf_.length - indexEnd <= (httpBuf_.length / 4)) { httpBuf_.length *= 2; } // Read more data. auto got = transport_.read(cast(ubyte[])httpBuf_[indexEnd .. $]); if (got == 0) return false; httpBufRemaining_ = httpBuf_[indexBegin .. indexEnd + got]; return true; } TTransport transport_; TMemoryBuffer writeBuffer_; TMemoryBuffer readBuffer_; bool readHeaders_; bool chunked_; bool chunkedDone_; size_t chunkSize_; size_t contentLength_; ubyte[] httpBuf_; ubyte[] httpBufRemaining_; } /** * HTTP client transport. */ final class TClientHttpTransport : THttpTransport { /** * Constructs a client http transport operating on the passed underlying * transport. * * Params: * transport = The underlying transport used for the actual I/O. * host = The HTTP host string. * path = The HTTP path string. */ this(TTransport transport, string host, string path) { super(transport); host_ = host; path_ = path; } /** * Convenience overload for constructing a client HTTP transport using a * TSocket connecting to the specified host and port. * * Params: * host = The server to connect to, also used as HTTP host string. * port = The port to connect to. * path = The HTTP path string. */ this(string host, ushort port, string path) { this(new TSocket(host, port), host, path); } protected: override string getHeader(size_t dataLength) { return "POST " ~ path_ ~ " HTTP/1.1\r\n" ~ "Host: " ~ host_ ~ "\r\n" ~ "Content-Type: application/x-thrift\r\n" ~ "Content-Length: " ~ to!string(dataLength) ~ "\r\n" ~ "Accept: application/x-thrift\r\n" ~ "User-Agent: Thrift/" ~ VERSION ~ " (D/TClientHttpTransport)\r\n" ~ "\r\n"; } override bool parseStatusLine(const(ubyte)[] status) { // HTTP-Version SP Status-Code SP Reason-Phrase CRLF auto firstSplit = findSplit(status, [' ']); if (firstSplit[1].empty) { throw new TTransportException("Bad status: " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } auto codeReason = firstSplit[2][countUntil!"a != b"(firstSplit[2], ' ') .. $]; auto secondSplit = findSplit(codeReason, [' ']); if (secondSplit[1].empty) { throw new TTransportException("Bad status: " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } if (secondSplit[0] == "200") { // HTTP 200 = OK, we got the response return true; } else if (secondSplit[0] == "100") { // HTTP 100 = continue, just keep reading return false; } throw new TTransportException("Bad status (unhandled status code): " ~ to!string(cast(const(char[]))status), TTransportException.Type.CORRUPTED_DATA); } private: string host_; string path_; } /** * HTTP server transport. */ final class TServerHttpTransport : THttpTransport { /** * Constructs a new instance. * * Param: * transport = The underlying transport used for the actual I/O. */ this(TTransport transport) { super(transport); } protected: override string getHeader(size_t dataLength) { return "HTTP/1.1 200 OK\r\n" ~ "Date: " ~ getRFC1123Time() ~ "\r\n" ~ "Server: Thrift/" ~ VERSION ~ "\r\n" ~ "Content-Type: application/x-thrift\r\n" ~ "Content-Length: " ~ to!string(dataLength) ~ "\r\n" ~ "Connection: Keep-Alive\r\n" ~ "\r\n"; } override bool parseStatusLine(const(ubyte)[] status) { // Method SP Request-URI SP HTTP-Version CRLF. auto split = findSplit(status, [' ']); if (split[1].empty) { throw new TTransportException("Bad status: " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } auto uriVersion = split[2][countUntil!"a != b"(split[2], ' ') .. $]; if (!canFind(uriVersion, ' ')) { throw new TTransportException("Bad status: " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } if (split[0] == "POST") { // POST method ok, looking for content. return true; } throw new TTransportException("Bad status (unsupported method): " ~ to!string(status), TTransportException.Type.CORRUPTED_DATA); } } /** * Wraps a transport into a HTTP server protocol. */ alias TWrapperTransportFactory!TServerHttpTransport TServerHttpTransportFactory; private { import std.string : format; string getRFC1123Time() { auto sysTime = Clock.currTime(UTC()); auto dayName = capMemberName(sysTime.dayOfWeek); auto monthName = capMemberName(sysTime.month); return format("%s, %s %s %s %s:%s:%s GMT", dayName, sysTime.day, monthName, sysTime.year, sysTime.hour, sysTime.minute, sysTime.second); } import std.ascii : toUpper; import std.traits : EnumMembers; string capMemberName(T)(T val) if (is(T == enum)) { foreach (i, e; EnumMembers!T) { enum name = __traits(derivedMembers, T)[i]; enum capName = cast(char) toUpper(name[0]) ~ name [1 .. $]; if (val == e) { return capName; } } throw new Exception("Not a member of " ~ T.stringof ~ ": " ~ to!string(val)); } unittest { enum Foo { bar, bAZ } import std.exception; enforce(capMemberName(Foo.bar) == "Bar"); enforce(capMemberName(Foo.bAZ) == "BAZ"); } } thrift-0.23.0/lib/d/src/thrift/transport/framed.d0000664000175000017500000002241715165535636022122 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.framed; import core.bitop : bswap; import std.algorithm : min; import std.array : empty; import std.exception : enforce; import thrift.transport.base; /** * Framed transport. * * All writes go into an in-memory buffer until flush is called, at which point * the transport writes the length of the entire binary chunk followed by the * data payload. The receiver on the other end then performs a single * »fixed-length« read to get the whole message off the wire. */ final class TFramedTransport : TBaseTransport { /** * Constructs a new framed transport. * * Params: * transport = The underlying transport to wrap. */ this(TTransport transport) { transport_ = transport; } /** * Returns the wrapped transport. */ TTransport underlyingTransport() @property { return transport_; } override bool isOpen() @property { return transport_.isOpen; } override bool peek() { return rBuf_.length > 0 || transport_.peek(); } override void open() { transport_.open(); } override void close() { flush(); transport_.close(); } /** * Attempts to read data into the given buffer, stopping when the buffer is * exhausted or the frame end is reached. * * TODO: Contrary to the C++ implementation, this never does cross-frame * reads – is there actually a valid use case for that? * * Params: * buf = Slice to use as buffer. * * Returns: How many bytes were actually read. * * Throws: TTransportException if an error occurs. */ override size_t read(ubyte[] buf) { // If the buffer is empty, read a new frame off the wire. if (rBuf_.empty) { bool gotFrame = readFrame(); if (!gotFrame) return 0; } auto size = min(rBuf_.length, buf.length); buf[0..size] = rBuf_[0..size]; rBuf_ = rBuf_[size..$]; return size; } override void write(in ubyte[] buf) { wBuf_ ~= buf; } override void flush() { if (wBuf_.empty) return; // Properly reset the write buffer even some of the protocol operations go // wrong. scope (exit) { wBuf_.length = 0; wBuf_.assumeSafeAppend(); } int len = bswap(cast(int)wBuf_.length); transport_.write(cast(ubyte[])(&len)[0..1]); transport_.write(wBuf_); transport_.flush(); } override const(ubyte)[] borrow(ubyte* buf, size_t len) { if (len <= rBuf_.length) { return rBuf_; } else { // Don't try attempting cross-frame borrows, trying that does not make // much sense anyway. return null; } } override void consume(size_t len) { enforce(len <= rBuf_.length, new TTransportException( "Invalid consume length", TTransportException.Type.BAD_ARGS)); rBuf_ = rBuf_[len .. $]; } private: bool readFrame() { // Read the size of the next frame. We can't use readAll() since that // always throws an exception on EOF, but want to throw an exception only // if EOF occurs after partial size data. int size; size_t size_read; while (size_read < size.sizeof) { auto data = (cast(ubyte*)&size)[size_read..size.sizeof]; auto read = transport_.read(data); if (read == 0) { if (size_read == 0) { // EOF before any data was read. return false; } else { // EOF after a partial frame header – illegal. throw new TTransportException( "No more data to read after partial frame header", TTransportException.Type.END_OF_FILE ); } } size_read += read; } size = bswap(size); enforce(size >= 0, new TTransportException("Frame size has negative value", TTransportException.Type.CORRUPTED_DATA)); // TODO: Benchmark this. rBuf_.length = size; rBuf_.assumeSafeAppend(); transport_.readAll(rBuf_); return true; } TTransport transport_; ubyte[] rBuf_; ubyte[] wBuf_; } /** * Wraps given transports into TFramedTransports. */ alias TWrapperTransportFactory!TFramedTransport TFramedTransportFactory; version (unittest) { import std.random : Mt19937, uniform; import thrift.transport.memory; } // Some basic random testing, always starting with the same seed for // deterministic unit test results – more tests in transport_test. unittest { auto randGen = Mt19937(42); // 32 kiB of data to work with. auto data = new ubyte[1 << 15]; foreach (ref b; data) { b = uniform!"[]"(cast(ubyte)0, cast(ubyte)255, randGen); } // Generate a list of chunk sizes to split the data into. A uniform // distribution is not quite realistic, but std.random doesn't have anything // else yet. enum MAX_FRAME_LENGTH = 512; auto chunkSizesList = new size_t[][2]; foreach (ref chunkSizes; chunkSizesList) { size_t sum; while (true) { auto curLen = uniform(0, MAX_FRAME_LENGTH, randGen); sum += curLen; if (sum > data.length) break; chunkSizes ~= curLen; } } chunkSizesList ~= [data.length]; // Also test whole chunk at once. // Test writing data. { foreach (chunkSizes; chunkSizesList) { auto buf = new TMemoryBuffer; auto framed = new TFramedTransport(buf); auto remainingData = data; foreach (chunkSize; chunkSizes) { framed.write(remainingData[0..chunkSize]); remainingData = remainingData[chunkSize..$]; } framed.flush(); auto writtenData = data[0..($ - remainingData.length)]; auto actualData = buf.getContents(); // Check frame size. int frameSize = bswap((cast(int[])(actualData[0..int.sizeof]))[0]); enforce(frameSize == writtenData.length); // Check actual data. enforce(actualData[int.sizeof..$] == writtenData); } } // Test reading data. { foreach (chunkSizes; chunkSizesList) { auto buf = new TMemoryBuffer; auto size = bswap(cast(int)data.length); buf.write(cast(ubyte[])(&size)[0..1]); buf.write(data); auto framed = new TFramedTransport(buf); ubyte[] readData; readData.reserve(data.length); foreach (chunkSize; chunkSizes) { // This should work with read because we have one huge frame. auto oldReadLen = readData.length; readData.length += chunkSize; framed.read(readData[oldReadLen..$]); } enforce(readData == data[0..readData.length]); } } // Test combined reading/writing of multiple frames. foreach (flushProbability; [1, 2, 4, 8, 16, 32]) { foreach (chunkSizes; chunkSizesList) { auto buf = new TMemoryBuffer; auto framed = new TFramedTransport(buf); size_t[] frameSizes; // Write the data. size_t frameSize; auto remainingData = data; foreach (chunkSize; chunkSizes) { framed.write(remainingData[0..chunkSize]); remainingData = remainingData[chunkSize..$]; frameSize += chunkSize; if (frameSize > 0 && uniform(0, flushProbability, randGen) == 0) { frameSizes ~= frameSize; frameSize = 0; framed.flush(); } } if (frameSize > 0) { frameSizes ~= frameSize; frameSize = 0; framed.flush(); } // Read it back. auto readData = new ubyte[data.length - remainingData.length]; auto remainToRead = readData; foreach (fSize; frameSizes) { // We are exploiting an implementation detail of TFramedTransport: // The read buffer starts empty and it will never return more than one // frame per read, so by just requesting all of the data, we should // always get exactly one frame. auto got = framed.read(remainToRead); enforce(got == fSize); remainToRead = remainToRead[fSize..$]; } enforce(remainToRead.empty); enforce(readData == data[0..readData.length]); } } } // Test flush()ing an empty buffer. unittest { auto buf = new TMemoryBuffer(); auto framed = new TFramedTransport(buf); immutable out1 = [0, 0, 0, 1, 'a']; immutable out2 = [0, 0, 0, 1, 'a', 0, 0, 0, 2, 'b', 'c']; framed.flush(); enforce(buf.getContents() == []); framed.flush(); framed.flush(); enforce(buf.getContents() == []); framed.write(cast(ubyte[])"a"); enforce(buf.getContents() == []); framed.flush(); enforce(buf.getContents() == out1); framed.flush(); framed.flush(); enforce(buf.getContents() == out1); framed.write(cast(ubyte[])"bc"); enforce(buf.getContents() == out1); framed.flush(); enforce(buf.getContents() == out2); framed.flush(); framed.flush(); enforce(buf.getContents() == out2); } thrift-0.23.0/lib/d/src/thrift/transport/ssl.d0000664000175000017500000004545515165535636021474 0ustar00buildbuild00000000000000/* * 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. */ /** * OpenSSL socket implementation, in large parts ported from C++. */ module thrift.transport.ssl; import core.exception : onOutOfMemoryError; import core.stdc.errno : errno, EINTR; import core.sync.mutex : Mutex; import core.memory : GC; import core.stdc.config; import core.stdc.stdlib : free, malloc; import std.ascii : toUpper; import std.array : empty, front, popFront; import std.conv : emplace, to; import std.exception : enforce; import std.socket : Address, InternetAddress, Internet6Address, Socket; import std.string : toStringz; import deimos.openssl.err; import deimos.openssl.rand; import deimos.openssl.ssl; import deimos.openssl.x509v3; import thrift.base; import thrift.internal.ssl; import thrift.transport.base; import thrift.transport.socket; /** * SSL encrypted socket implementation using OpenSSL. * * Note: * On Posix systems which do not have the BSD-specific SO_NOSIGPIPE flag, you * might want to ignore the SIGPIPE signal, as OpenSSL might try to write to * a closed socket if the peer disconnects abruptly: * --- * import core.stdc.signal; * import core.sys.posix.signal; * signal(SIGPIPE, SIG_IGN); * --- */ final class TSSLSocket : TSocket { /** * Creates an instance that wraps an already created, connected (!) socket. * * Params: * context = The SSL socket context to use. A reference to it is stored so * that it doesn't get cleaned up while the socket is used. * socket = Already created, connected socket object. */ this(TSSLContext context, Socket socket) { super(socket); context_ = context; serverSide_ = context.serverSide; accessManager_ = context.accessManager; } /** * Creates a new unconnected socket that will connect to the given host * on the given port. * * Params: * context = The SSL socket context to use. A reference to it is stored so * that it doesn't get cleaned up while the socket is used. * host = Remote host. * port = Remote port. */ this(TSSLContext context, string host, ushort port) { super(host, port); context_ = context; serverSide_ = context.serverSide; accessManager_ = context.accessManager; } override bool isOpen() @property { if (ssl_ is null || !super.isOpen()) return false; auto shutdown = SSL_get_shutdown(ssl_); bool shutdownReceived = (shutdown & SSL_RECEIVED_SHUTDOWN) != 0; bool shutdownSent = (shutdown & SSL_SENT_SHUTDOWN) != 0; return !(shutdownReceived && shutdownSent); } override bool peek() { if (!isOpen) return false; checkHandshake(); byte bt; auto rc = SSL_peek(ssl_, &bt, bt.sizeof); enforce(rc >= 0, getSSLException("SSL_peek")); if (rc == 0) { ERR_clear_error(); } return (rc > 0); } override void open() { enforce(!serverSide_, "Cannot open a server-side SSL socket."); if (isOpen) return; super.open(); } override void close() { if (!isOpen) return; if (ssl_ !is null) { // Two-step SSL shutdown. auto rc = SSL_shutdown(ssl_); if (rc == 0) { rc = SSL_shutdown(ssl_); } if (rc < 0) { // Do not throw an exception here as leaving the transport "open" will // probably produce only more errors, and the chance we can do // something about the error e.g. by retrying is very low. logError("Error shutting down SSL: %s", getSSLException()); } SSL_free(ssl_); ssl_ = null; ERR_remove_state(0); } super.close(); } override size_t read(ubyte[] buf) { checkHandshake(); int bytes; foreach (_; 0 .. maxRecvRetries) { bytes = SSL_read(ssl_, buf.ptr, cast(int)buf.length); if (bytes >= 0) break; auto errnoCopy = errno; if (SSL_get_error(ssl_, bytes) == SSL_ERROR_SYSCALL) { if (ERR_get_error() == 0 && errnoCopy == EINTR) { // FIXME: Windows. continue; } } throw getSSLException("SSL_read"); } return bytes; } override void write(in ubyte[] buf) { checkHandshake(); // Loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX. size_t written = 0; while (written < buf.length) { auto bytes = SSL_write(ssl_, buf.ptr + written, cast(int)(buf.length - written)); if (bytes <= 0) { throw getSSLException("SSL_write"); } written += bytes; } } override void flush() { checkHandshake(); auto bio = SSL_get_wbio(ssl_); enforce(bio !is null, new TSSLException("SSL_get_wbio returned null")); auto rc = BIO_flush(bio); enforce(rc == 1, getSSLException("BIO_flush")); } /** * Whether to use client or server side SSL handshake protocol. */ bool serverSide() @property const { return serverSide_; } /// Ditto void serverSide(bool value) @property { serverSide_ = value; } /** * The access manager to use. */ void accessManager(TAccessManager value) @property { accessManager_ = value; } private: void checkHandshake() { enforce(super.isOpen(), new TTransportException( TTransportException.Type.NOT_OPEN)); if (ssl_ !is null) return; ssl_ = context_.createSSL(); SSL_set_fd(ssl_, cast(int)socketHandle); int rc; if (serverSide_) { rc = SSL_accept(ssl_); } else { rc = SSL_connect(ssl_); } enforce(rc > 0, getSSLException()); authorize(ssl_, accessManager_, getPeerAddress(), (serverSide_ ? getPeerAddress().toHostNameString() : host)); } bool serverSide_; SSL* ssl_; TSSLContext context_; TAccessManager accessManager_; } /** * Represents an OpenSSL context with certification settings, etc. and handles * initialization/teardown. * * OpenSSL is initialized when the first instance of this class is created * and shut down when the last one is destroyed (thread-safe). */ class TSSLContext { this() { initMutex_.lock(); scope(exit) initMutex_.unlock(); if (count_ == 0) { initializeOpenSSL(); randomize(); } count_++; static if (OPENSSL_VERSION_NUMBER >= 0x1010000f) { // OPENSSL_VERSION_AT_LEAST(1, 1)) { ctx_ = SSL_CTX_new(TLS_method()); } else { ctx_ = SSL_CTX_new(SSLv23_method()); SSL_CTX_set_options(ctx_, SSL_OP_NO_SSLv2); } SSL_CTX_set_options(ctx_, SSL_OP_NO_SSLv3); // THRIFT-3164 enforce(ctx_, getSSLException("SSL_CTX_new")); SSL_CTX_set_mode(ctx_, SSL_MODE_AUTO_RETRY); } ~this() { initMutex_.lock(); scope(exit) initMutex_.unlock(); if (ctx_ !is null) { SSL_CTX_free(ctx_); ctx_ = null; } count_--; if (count_ == 0) { cleanupOpenSSL(); } } /** * Ciphers to be used in SSL handshake process. * * The string must be in the colon-delimited OpenSSL notation described in * ciphers(1), for example: "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH". */ void ciphers(string enable) @property { auto rc = SSL_CTX_set_cipher_list(ctx_, toStringz(enable)); enforce(ERR_peek_error() == 0, getSSLException("SSL_CTX_set_cipher_list")); enforce(rc > 0, new TSSLException("None of specified ciphers are supported")); } /** * Whether peer is required to present a valid certificate. */ void authenticate(bool required) @property { int mode; if (required) { mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE; } else { mode = SSL_VERIFY_NONE; } SSL_CTX_set_verify(ctx_, mode, null); } /** * Load server certificate. * * Params: * path = Path to the certificate file. * format = Certificate file format. Defaults to PEM, which is currently * the only one supported. */ void loadCertificate(string path, string format = "PEM") { enforce(path !is null && format !is null, new TTransportException( "loadCertificateChain: either or is null", TTransportException.Type.BAD_ARGS)); if (format == "PEM") { enforce(SSL_CTX_use_certificate_chain_file(ctx_, toStringz(path)), getSSLException( `Could not load SSL server certificate from file "` ~ path ~ `"` ) ); } else { throw new TSSLException("Unsupported certificate format: " ~ format); } } /* * Load private key. * * Params: * path = Path to the certificate file. * format = Private key file format. Defaults to PEM, which is currently * the only one supported. */ void loadPrivateKey(string path, string format = "PEM") { enforce(path !is null && format !is null, new TTransportException( "loadPrivateKey: either or is NULL", TTransportException.Type.BAD_ARGS)); if (format == "PEM") { enforce(SSL_CTX_use_PrivateKey_file(ctx_, toStringz(path), SSL_FILETYPE_PEM), getSSLException( `Could not load SSL private key from file "` ~ path ~ `"` ) ); } else { throw new TSSLException("Unsupported certificate format: " ~ format); } } /** * Load trusted certificates from specified file (in PEM format). * * Params. * path = Path to the file containing the trusted certificates. */ void loadTrustedCertificates(string path) { enforce(path !is null, new TTransportException( "loadTrustedCertificates: is NULL", TTransportException.Type.BAD_ARGS)); enforce(SSL_CTX_load_verify_locations(ctx_, toStringz(path), null), getSSLException( `Could not load SSL trusted certificate list from file "` ~ path ~ `"` ) ); } /** * Called during OpenSSL initialization to seed the OpenSSL entropy pool. * * Defaults to simply calling RAND_poll(), but it can be overwritten if a * different, perhaps more secure implementation is desired. */ void randomize() { RAND_poll(); } /** * Whether to use client or server side SSL handshake protocol. */ bool serverSide() @property const { return serverSide_; } /// Ditto void serverSide(bool value) @property { serverSide_ = value; } /** * The access manager to use. */ TAccessManager accessManager() @property { if (!serverSide_ && !accessManager_) { accessManager_ = new TDefaultClientAccessManager; } return accessManager_; } /// Ditto void accessManager(TAccessManager value) @property { accessManager_ = value; } SSL* createSSL() out (result) { assert(result); } body { auto result = SSL_new(ctx_); enforce(result, getSSLException("SSL_new")); return result; } protected: /** * Override this method for custom password callback. It may be called * multiple times at any time during a session as necessary. * * Params: * size = Maximum length of password, including null byte. */ string getPassword(int size) nothrow out(result) { assert(result.length < size); } body { return ""; } /** * Notifies OpenSSL to use getPassword() instead of the default password * callback with getPassword(). */ void overrideDefaultPasswordCallback() { SSL_CTX_set_default_passwd_cb(ctx_, &passwordCallback); SSL_CTX_set_default_passwd_cb_userdata(ctx_, cast(void*)this); } SSL_CTX* ctx_; private: bool serverSide_; TAccessManager accessManager_; shared static this() { initMutex_ = new Mutex(); } static void initializeOpenSSL() { if (initialized_) { return; } initialized_ = true; static if (OPENSSL_VERSION_NUMBER < 0x1010000f) { // OPENSSL_VERSION_BEFORE(1, 1)) { SSL_library_init(); SSL_load_error_strings(); mutexes_ = new Mutex[CRYPTO_num_locks()]; foreach (ref m; mutexes_) { m = new Mutex; } import thrift.internal.traits; // As per the OpenSSL threads manpage, this isn't needed on Windows. version (Posix) { CRYPTO_set_id_callback(assumeNothrow(&threadIdCallback)); } CRYPTO_set_locking_callback(assumeNothrow(&lockingCallback)); CRYPTO_set_dynlock_create_callback(assumeNothrow(&dynlockCreateCallback)); CRYPTO_set_dynlock_lock_callback(assumeNothrow(&dynlockLockCallback)); CRYPTO_set_dynlock_destroy_callback(assumeNothrow(&dynlockDestroyCallback)); } } static void cleanupOpenSSL() { if (!initialized_) return; initialized_ = false; static if (OPENSSL_VERSION_NUMBER < 0x1010000f) { // OPENSSL_VERSION_BEFORE(1, 1)) { CRYPTO_set_locking_callback(null); CRYPTO_set_dynlock_create_callback(null); CRYPTO_set_dynlock_lock_callback(null); CRYPTO_set_dynlock_destroy_callback(null); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); ERR_remove_state(0); } } static extern(C) { version (Posix) { import core.sys.posix.pthread : pthread_self; c_ulong threadIdCallback() { return cast(c_ulong)pthread_self(); } } void lockingCallback(int mode, int n, const(char)* file, int line) { if (mode & CRYPTO_LOCK) { mutexes_[n].lock(); } else { mutexes_[n].unlock(); } } CRYPTO_dynlock_value* dynlockCreateCallback(const(char)* file, int line) { enum size = __traits(classInstanceSize, Mutex); auto mem = malloc(size)[0 .. size]; if (!mem) onOutOfMemoryError(); GC.addRange(mem.ptr, size); auto mutex = emplace!Mutex(mem); return cast(CRYPTO_dynlock_value*)mutex; } void dynlockLockCallback(int mode, CRYPTO_dynlock_value* l, const(char)* file, int line) { if (l is null) return; if (mode & CRYPTO_LOCK) { (cast(Mutex)l).lock(); } else { (cast(Mutex)l).unlock(); } } void dynlockDestroyCallback(CRYPTO_dynlock_value* l, const(char)* file, int line) { GC.removeRange(l); destroy(cast(Mutex)l); free(l); } int passwordCallback(char* password, int size, int, void* data) nothrow { auto context = cast(TSSLContext) data; auto userPassword = context.getPassword(size); auto len = userPassword.length; if (len > size) { len = size; } password[0 .. len] = userPassword[0 .. len]; // TODO: \0 handling correct? return cast(int)len; } } static __gshared bool initialized_; static __gshared Mutex initMutex_; static __gshared Mutex[] mutexes_; static __gshared uint count_; } /** * Decides whether a remote host is legitimate or not. * * It is usually set at a TSSLContext, which then passes it to all the created * TSSLSockets. */ class TAccessManager { /// enum Decision { DENY = -1, /// Deny access. SKIP = 0, /// Cannot decide, move on to next check (deny if last). ALLOW = 1 /// Allow access. } /** * Determines whether a peer should be granted access or not based on its * IP address. * * Called once after SSL handshake is completes successfully and before peer * certificate is examined. * * If a valid decision (ALLOW or DENY) is returned, the peer certificate * will not be verified. */ Decision verify(Address address) { return Decision.DENY; } /** * Determines whether a peer should be granted access or not based on a * name from its certificate. * * Called every time a DNS subjectAltName/common name is extracted from the * peer's certificate. * * Params: * host = The actual host name string from the socket connection. * certHost = A host name string from the certificate. */ Decision verify(string host, const(char)[] certHost) { return Decision.DENY; } /** * Determines whether a peer should be granted access or not based on an IP * address from its certificate. * * Called every time an IP subjectAltName is extracted from the peer's * certificate. * * Params: * address = The actual address from the socket connection. * certHost = A host name string from the certificate. */ Decision verify(Address address, ubyte[] certAddress) { return Decision.DENY; } } /** * Default access manager implementation, which just checks the host name * resp. IP address of the connection against the certificate. */ class TDefaultClientAccessManager : TAccessManager { override Decision verify(Address address) { return Decision.SKIP; } override Decision verify(string host, const(char)[] certHost) { if (host.empty || certHost.empty) { return Decision.SKIP; } return (matchName(host, certHost) ? Decision.ALLOW : Decision.SKIP); } override Decision verify(Address address, ubyte[] certAddress) { bool match; if (certAddress.length == 4) { if (auto ia = cast(InternetAddress)address) { match = ((cast(ubyte*)ia.addr())[0 .. 4] == certAddress[]); } } else if (certAddress.length == 16) { if (auto ia = cast(Internet6Address)address) { match = (ia.addr() == certAddress[]); } } return (match ? Decision.ALLOW : Decision.SKIP); } } private { /** * Matches a name with a pattern. The pattern may include wildcard. A single * wildcard "*" can match up to one component in the domain name. * * Params: * host = Host name to match, typically the SSL remote peer. * pattern = Host name pattern, typically from the SSL certificate. * * Returns: true if host matches pattern, false otherwise. */ bool matchName(const(char)[] host, const(char)[] pattern) { while (!host.empty && !pattern.empty) { if (toUpper(pattern.front) == toUpper(host.front)) { host.popFront; pattern.popFront; } else if (pattern.front == '*') { while (!host.empty && host.front != '.') { host.popFront; } pattern.popFront; } else { break; } } return (host.empty && pattern.empty); } unittest { enforce(matchName("thrift.apache.org", "*.apache.org")); enforce(!matchName("thrift.apache.org", "apache.org")); enforce(matchName("thrift.apache.org", "thrift.*.*")); enforce(matchName("", "")); enforce(!matchName("", "*")); } } /** * SSL-level exception. */ class TSSLException : TTransportException { /// this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, TTransportException.Type.INTERNAL_ERROR, file, line, next); } } thrift-0.23.0/lib/d/src/thrift/transport/memory.d0000664000175000017500000001456315165535636022177 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.memory; import core.exception : onOutOfMemoryError; import core.stdc.stdlib : free, realloc; import std.algorithm : min; import std.conv : text; import thrift.transport.base; /** * A transport that simply reads from and writes to an in-memory buffer. Every * time you call write on it, the data is simply placed into a buffer, and * every time you call read, data is consumed from that buffer. * * Currently, the storage for written data is never reclaimed, even if the * buffer contents have already been read out again. */ final class TMemoryBuffer : TBaseTransport { /** * Constructs a new memory transport with an empty internal buffer. */ this() {} /** * Constructs a new memory transport with an empty internal buffer, * reserving space for capacity bytes in advance. * * If the amount of data which will be written to the buffer is already * known on construction, this can better performance over the default * constructor because reallocations can be avoided. * * If the preallocated buffer is exhausted, data can still be written to the * transport, but reallocations will happen. * * Params: * capacity = Size of the initially reserved buffer (in bytes). */ this(size_t capacity) { reset(capacity); } /** * Constructs a new memory transport initially containing the passed data. * * For now, the passed buffer is not intelligently used, the data is just * copied to the internal buffer. * * Params: * buffer = Initial contents available to be read. */ this(in ubyte[] contents) { auto size = contents.length; reset(size); buffer_[0 .. size] = contents[]; writeOffset_ = size; } /** * Destructor, frees the internally allocated buffer. */ ~this() { free(buffer_); } /** * Returns a read-only view of the current buffer contents. * * Note: For performance reasons, the returned slice is only valid for the * life of this object, and may be invalidated on the next write() call at * will – you might want to immediately .dup it if you intend to keep it * around. */ const(ubyte)[] getContents() { return buffer_[readOffset_ .. writeOffset_]; } /** * A memory transport is always open. */ override bool isOpen() @property { return true; } override bool peek() { return writeOffset_ - readOffset_ > 0; } /** * Opening is a no-op() for a memory buffer. */ override void open() {} /** * Closing is a no-op() for a memory buffer, it is always open. */ override void close() {} override size_t read(ubyte[] buf) { auto size = min(buf.length, writeOffset_ - readOffset_); buf[0 .. size] = buffer_[readOffset_ .. readOffset_ + size]; readOffset_ += size; return size; } /** * Shortcut version of readAll() – using this over TBaseTransport.readAll() * can give us a nice speed increase because gives us a nice speed increase * because it is typically a very hot path during deserialization. */ override void readAll(ubyte[] buf) { auto available = writeOffset_ - readOffset_; if (buf.length > available) { throw new TTransportException(text("Cannot readAll() ", buf.length, " bytes of data because only ", available, " bytes are available."), TTransportException.Type.END_OF_FILE); } buf[] = buffer_[readOffset_ .. readOffset_ + buf.length]; readOffset_ += buf.length; } override void write(in ubyte[] buf) { auto need = buf.length; if (bufferLen_ - writeOffset_ < need) { // Exponential growth. auto newLen = bufferLen_ + 1; while (newLen - writeOffset_ < need) newLen *= 2; cRealloc(buffer_, newLen); bufferLen_ = newLen; } buffer_[writeOffset_ .. writeOffset_ + need] = buf[]; writeOffset_ += need; } override const(ubyte)[] borrow(ubyte* buf, size_t len) { if (len <= writeOffset_ - readOffset_) { return buffer_[readOffset_ .. writeOffset_]; } else { return null; } } override void consume(size_t len) { readOffset_ += len; } void reset() { readOffset_ = 0; writeOffset_ = 0; } void reset(size_t capacity) { readOffset_ = 0; writeOffset_ = 0; if (bufferLen_ < capacity) { cRealloc(buffer_, capacity); bufferLen_ = capacity; } } private: ubyte* buffer_; size_t bufferLen_; size_t readOffset_; size_t writeOffset_; } private { void cRealloc(ref ubyte* data, size_t newSize) { auto result = realloc(data, newSize); if (result is null) onOutOfMemoryError(); data = cast(ubyte*)result; } } version (unittest) { import std.exception; } unittest { auto a = new TMemoryBuffer(5); immutable(ubyte[]) testData = [1, 2, 3, 4]; auto buf = new ubyte[testData.length]; enforce(a.isOpen); // a should be empty. enforce(!a.peek()); enforce(a.read(buf) == 0); assertThrown!TTransportException(a.readAll(buf)); // Write some data and read it back again. a.write(testData); enforce(a.peek()); enforce(a.getContents() == testData); enforce(a.read(buf) == testData.length); enforce(buf == testData); // a should be empty again. enforce(!a.peek()); enforce(a.read(buf) == 0); assertThrown!TTransportException(a.readAll(buf)); // Test the constructor which directly accepts initial data. auto b = new TMemoryBuffer(testData); enforce(b.isOpen); enforce(b.peek()); enforce(b.getContents() == testData); // Test borrow(). auto borrowed = b.borrow(null, testData.length); enforce(borrowed == testData); enforce(b.peek()); b.consume(testData.length); enforce(!b.peek()); } thrift-0.23.0/lib/d/src/thrift/transport/piped.d0000664000175000017500000001306015165535636021757 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.piped; import thrift.transport.base; import thrift.transport.memory; /** * Pipes data request from one transport to another when readEnd() * or writeEnd() is called. * * A typical use case would be to log requests on e.g. a socket to * disk (i. e. pipe them to a TFileWriterTransport). * * The implementation keeps an internal buffer which expands to * hold the whole amount of data read/written until the corresponding *End() * method is called. * * Contrary to the C++ implementation, this doesn't introduce yet another layer * of input/output buffering, all calls are passed to the underlying source * transport verbatim. */ final class TPipedTransport(Source = TTransport) if ( isTTransport!Source ) : TBaseTransport { /// The default initial buffer size if not explicitly specified, in bytes. enum DEFAULT_INITIAL_BUFFER_SIZE = 512; /** * Constructs a new instance. * * By default, only reads are piped (pipeReads = true, pipeWrites = false). * * Params: * srcTrans = The transport to which all requests are forwarded. * dstTrans = The transport the read/written data is copied to. * initialBufferSize = The default size of the read/write buffers, for * performance tuning. */ this(Source srcTrans, TTransport dstTrans, size_t initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE ) { srcTrans_ = srcTrans; dstTrans_ = dstTrans; readBuffer_ = new TMemoryBuffer(initialBufferSize); writeBuffer_ = new TMemoryBuffer(initialBufferSize); pipeReads_ = true; pipeWrites_ = false; } bool pipeReads() @property const { return pipeReads_; } void pipeReads(bool value) @property { if (!value) { readBuffer_.reset(); } pipeReads_ = value; } bool pipeWrites() @property const { return pipeWrites_; } void pipeWrites(bool value) @property { if (!value) { writeBuffer_.reset(); } pipeWrites_ = value; } override bool isOpen() { return srcTrans_.isOpen(); } override bool peek() { return srcTrans_.peek(); } override void open() { srcTrans_.open(); } override void close() { srcTrans_.close(); } override size_t read(ubyte[] buf) { auto bytesRead = srcTrans_.read(buf); if (pipeReads_) { readBuffer_.write(buf[0 .. bytesRead]); } return bytesRead; } override size_t readEnd() { if (pipeReads_) { auto data = readBuffer_.getContents(); dstTrans_.write(data); dstTrans_.flush(); readBuffer_.reset(); srcTrans_.readEnd(); // Return data.length instead of the readEnd() result of the source // transports because it might not be available from it. return data.length; } return srcTrans_.readEnd(); } override void write(in ubyte[] buf) { if (pipeWrites_) { writeBuffer_.write(buf); } srcTrans_.write(buf); } override size_t writeEnd() { if (pipeWrites_) { auto data = writeBuffer_.getContents(); dstTrans_.write(data); dstTrans_.flush(); writeBuffer_.reset(); srcTrans_.writeEnd(); // Return data.length instead of the readEnd() result of the source // transports because it might not be available from it. return data.length; } return srcTrans_.writeEnd(); } override void flush() { srcTrans_.flush(); } private: Source srcTrans_; TTransport dstTrans_; TMemoryBuffer readBuffer_; TMemoryBuffer writeBuffer_; bool pipeReads_; bool pipeWrites_; } /** * TPipedTransport construction helper to avoid having to explicitly * specify the transport types, i.e. to allow the constructor being called * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)). */ TPipedTransport!Source tPipedTransport(Source)( Source srcTrans, TTransport dstTrans ) if (isTTransport!Source) { return new typeof(return)(srcTrans, dstTrans); } version (unittest) { // DMD @@BUG@@: UFCS for std.array.empty doesn't work when import is moved // into unittest block. import std.array; import std.exception : enforce; } unittest { auto underlying = new TMemoryBuffer; auto pipeTarget = new TMemoryBuffer; auto trans = tPipedTransport(underlying, pipeTarget); underlying.write(cast(ubyte[])"abcd"); ubyte[4] buffer; trans.readAll(buffer[0 .. 2]); enforce(buffer[0 .. 2] == "ab"); enforce(pipeTarget.getContents().empty); trans.readEnd(); enforce(pipeTarget.getContents() == "ab"); pipeTarget.reset(); underlying.write(cast(ubyte[])"ef"); trans.readAll(buffer[0 .. 2]); enforce(buffer[0 .. 2] == "cd"); enforce(pipeTarget.getContents().empty); trans.readAll(buffer[0 .. 2]); enforce(buffer[0 .. 2] == "ef"); enforce(pipeTarget.getContents().empty); trans.readEnd(); enforce(pipeTarget.getContents() == "cdef"); } thrift-0.23.0/lib/d/src/thrift/transport/range.d0000664000175000017500000000751715165535636021764 0ustar00buildbuild00000000000000/* * 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. */ /** * Transports which operate on generic D ranges. */ module thrift.transport.range; import std.array : empty; import std.range; import std.traits : Unqual; import thrift.transport.base; /** * Adapts an ubyte input range for reading via the TTransport interface. * * The case where R is a plain ubyte[] is reasonably optimized, so a possible * use case for TInputRangeTransport would be to deserialize some data held in * a memory buffer. */ final class TInputRangeTransport(R) if ( isInputRange!(Unqual!R) && is(ElementType!R : const(ubyte)) ) : TBaseTransport { /** * Constructs a new instance. * * Params: * data = The input range to use as data. */ this(R data) { data_ = data; } /** * An input range transport is always open. */ override bool isOpen() @property { return true; } override bool peek() { return !data_.empty; } /** * Opening is a no-op() for an input range transport. */ override void open() {} /** * Closing is a no-op() for a memory buffer. */ override void close() {} override size_t read(ubyte[] buf) { auto data = data_.take(buf.length); auto bytes = data.length; static if (is(typeof(R.init[1 .. 2]) : const(ubyte)[])) { // put() is currently unnecessarily slow if both ranges are sliceable. buf[0 .. bytes] = data[]; data_ = data_[bytes .. $]; } else { buf.put(data); } return bytes; } /** * Shortcut version of readAll() for slicable ranges. * * Because readAll() is typically a very hot path during deserialization, * using this over TBaseTransport.readAll() gives us a nice increase in * speed due to the reduced amount of indirections. */ override void readAll(ubyte[] buf) { static if (is(typeof(R.init[1 .. 2]) : const(ubyte)[])) { if (buf.length <= data_.length) { buf[] = data_[0 .. buf.length]; data_ = data_[buf.length .. $]; return; } } super.readAll(buf); } override const(ubyte)[] borrow(ubyte* buf, size_t len) { static if (is(R : const(ubyte)[])) { // Can only borrow if our data type is actually an ubyte array. if (len <= data_.length) { return data_; } } return null; } override void consume(size_t len) { static if (is(R : const(ubyte)[])) { if (len > data_.length) { throw new TTransportException("Invalid consume length", TTransportException.Type.BAD_ARGS); } data_ = data_[len .. $]; } else { super.consume(len); } } /** * Sets a new data range to use. */ void reset(R data) { data_ = data; } private: R data_; } /** * TInputRangeTransport construction helper to avoid having to explicitly * specify the argument type, i.e. to allow the constructor being called using * IFTI (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D * Bugzilla enhancement requet 6082)). */ TInputRangeTransport!R tInputRangeTransport(R)(R data) if ( is (TInputRangeTransport!R) ) { return new TInputRangeTransport!R(data); } thrift-0.23.0/lib/d/src/thrift/transport/zlib.d0000664000175000017500000003402715165535636021624 0ustar00buildbuild00000000000000/* * 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. */ module thrift.transport.zlib; import core.bitop : bswap; import etc.c.zlib; import std.algorithm : min; import std.array : empty; import std.conv : to; import std.exception : enforce; import thrift.base; import thrift.transport.base; /** * zlib transport. Compresses (deflates) data before writing it to the * underlying transport, and decompresses (inflates) it after reading. */ final class TZlibTransport : TBaseTransport { // These defaults have yet to be optimized. enum DEFAULT_URBUF_SIZE = 128; enum DEFAULT_CRBUF_SIZE = 1024; enum DEFAULT_UWBUF_SIZE = 128; enum DEFAULT_CWBUF_SIZE = 1024; /** * Constructs a new zlib transport. * * Params: * transport = The underlying transport to wrap. * urbufSize = The size of the uncompressed reading buffer, in bytes. * crbufSize = The size of the compressed reading buffer, in bytes. * uwbufSize = The size of the uncompressed writing buffer, in bytes. * cwbufSize = The size of the compressed writing buffer, in bytes. */ this( TTransport transport, size_t urbufSize = DEFAULT_URBUF_SIZE, size_t crbufSize = DEFAULT_CRBUF_SIZE, size_t uwbufSize = DEFAULT_UWBUF_SIZE, size_t cwbufSize = DEFAULT_CWBUF_SIZE ) { transport_ = transport; enforce(uwbufSize >= MIN_DIRECT_DEFLATE_SIZE, new TTransportException( "TZLibTransport: uncompressed write buffer must be at least " ~ to!string(MIN_DIRECT_DEFLATE_SIZE) ~ "bytes in size.", TTransportException.Type.BAD_ARGS)); urbuf_ = new ubyte[urbufSize]; crbuf_ = new ubyte[crbufSize]; uwbuf_ = new ubyte[uwbufSize]; cwbuf_ = new ubyte[cwbufSize]; rstream_ = new z_stream; rstream_.next_in = crbuf_.ptr; rstream_.avail_in = 0; rstream_.next_out = urbuf_.ptr; rstream_.avail_out = to!uint(urbuf_.length); wstream_ = new z_stream; wstream_.next_in = uwbuf_.ptr; wstream_.avail_in = 0; wstream_.next_out = cwbuf_.ptr; wstream_.avail_out = to!uint(crbuf_.length); zlibEnforce(inflateInit(rstream_), rstream_); scope (failure) { zlibLogError(inflateEnd(rstream_), rstream_); } zlibEnforce(deflateInit(wstream_, Z_DEFAULT_COMPRESSION), wstream_); } ~this() { zlibLogError(inflateEnd(rstream_), rstream_); auto result = deflateEnd(wstream_); // Z_DATA_ERROR may indicate unflushed data, so just ignore it. if (result != Z_DATA_ERROR) { zlibLogError(result, wstream_); } } /** * Returns the wrapped transport. */ TTransport underlyingTransport() @property { return transport_; } override bool isOpen() @property { return readAvail > 0 || transport_.isOpen; } override bool peek() { return readAvail > 0 || transport_.peek(); } override void open() { transport_.open(); } override void close() { transport_.close(); } override size_t read(ubyte[] buf) { // The C++ implementation suggests to skip urbuf on big reads in future // versions, we would benefit from it as well. auto origLen = buf.length; while (true) { auto give = min(readAvail, buf.length); // If std.range.put was optimized for slicable ranges, it could be used // here as well. buf[0 .. give] = urbuf_[urpos_ .. urpos_ + give]; buf = buf[give .. $]; urpos_ += give; auto need = buf.length; if (need == 0) { // We could manage to get the all the data requested. return origLen; } if (inputEnded_ || (need < origLen && rstream_.avail_in == 0)) { // We didn't fill buf completely, but there is no more data available. return origLen - need; } // Refill our buffer by reading more data through zlib. rstream_.next_out = urbuf_.ptr; rstream_.avail_out = to!uint(urbuf_.length); urpos_ = 0; if (!readFromZlib()) { // Couldn't get more data from the underlying transport. return origLen - need; } } } override void write(in ubyte[] buf) { enforce(!outputFinished_, new TTransportException( "write() called after finish()", TTransportException.Type.BAD_ARGS)); auto len = buf.length; if (len > MIN_DIRECT_DEFLATE_SIZE) { flushToZlib(uwbuf_[0 .. uwpos_], Z_NO_FLUSH); uwpos_ = 0; flushToZlib(buf, Z_NO_FLUSH); } else if (len > 0) { if (uwbuf_.length - uwpos_ < len) { flushToZlib(uwbuf_[0 .. uwpos_], Z_NO_FLUSH); uwpos_ = 0; } uwbuf_[uwpos_ .. uwpos_ + len] = buf[]; uwpos_ += len; } } override void flush() { enforce(!outputFinished_, new TTransportException( "flush() called after finish()", TTransportException.Type.BAD_ARGS)); flushToTransport(Z_SYNC_FLUSH); } override const(ubyte)[] borrow(ubyte* buf, size_t len) { if (len <= readAvail) { return urbuf_[urpos_ .. $]; } return null; } override void consume(size_t len) { enforce(readAvail >= len, new TTransportException( "consume() did not follow a borrow().", TTransportException.Type.BAD_ARGS)); urpos_ += len; } /** * Finalize the zlib stream. * * This causes zlib to flush any pending write data and write end-of-stream * information, including the checksum. Once finish() has been called, no * new data can be written to the stream. */ void finish() { enforce(!outputFinished_, new TTransportException( "flush() called on already finished TZlibTransport", TTransportException.Type.BAD_ARGS)); flushToTransport(Z_FINISH); } /** * Verify the checksum at the end of the zlib stream (by finish()). * * May only be called after all data has been read. * * Throws: TTransportException when the checksum is corrupted or there is * still unread data left. */ void verifyChecksum() { // If zlib has already reported the end of the stream, the checksum has // been verified, no. if (inputEnded_) return; enforce(!readAvail, new TTransportException( "verifyChecksum() called before end of zlib stream", TTransportException.Type.CORRUPTED_DATA)); rstream_.next_out = urbuf_.ptr; rstream_.avail_out = to!uint(urbuf_.length); urpos_ = 0; // readFromZlib() will throw an exception if the checksum is bad. enforce(readFromZlib(), new TTransportException( "checksum not available yet in verifyChecksum()", TTransportException.Type.CORRUPTED_DATA)); enforce(inputEnded_, new TTransportException( "verifyChecksum() called before end of zlib stream", TTransportException.Type.CORRUPTED_DATA)); // If we get here, we are at the end of the stream and thus zlib has // successfully verified the checksum. } private: size_t readAvail() const @property { return urbuf_.length - rstream_.avail_out - urpos_; } bool readFromZlib() { assert(!inputEnded_); if (rstream_.avail_in == 0) { // zlib has used up all the compressed data we provided in crbuf, read // some more from the underlying transport. auto got = transport_.read(crbuf_); if (got == 0) return false; rstream_.next_in = crbuf_.ptr; rstream_.avail_in = to!uint(got); } // We have some compressed data now, uncompress it. auto zlib_result = inflate(rstream_, Z_SYNC_FLUSH); if (zlib_result == Z_STREAM_END) { inputEnded_ = true; } else { zlibEnforce(zlib_result, rstream_); } return true; } void flushToTransport(int type) { // Compress remaining data in uwbuf_ to cwbuf_. flushToZlib(uwbuf_[0 .. uwpos_], type); uwpos_ = 0; // Write all compressed data to the transport. transport_.write(cwbuf_[0 .. $ - wstream_.avail_out]); wstream_.next_out = cwbuf_.ptr; wstream_.avail_out = to!uint(cwbuf_.length); // Flush the transport. transport_.flush(); } void flushToZlib(in ubyte[] buf, int type) { wstream_.next_in = cast(ubyte*)buf.ptr; // zlib only reads, cast is safe. wstream_.avail_in = to!uint(buf.length); while (true) { if (type == Z_NO_FLUSH && wstream_.avail_in == 0) { break; } if (wstream_.avail_out == 0) { // cwbuf has been exhausted by zlib, flush to the underlying transport. transport_.write(cwbuf_); wstream_.next_out = cwbuf_.ptr; wstream_.avail_out = to!uint(cwbuf_.length); } auto zlib_result = deflate(wstream_, type); if (type == Z_FINISH && zlib_result == Z_STREAM_END) { assert(wstream_.avail_in == 0); outputFinished_ = true; break; } zlibEnforce(zlib_result, wstream_); if ((type == Z_SYNC_FLUSH || type == Z_FULL_FLUSH) && wstream_.avail_in == 0 && wstream_.avail_out != 0) { break; } } } static void zlibEnforce(int status, z_stream* stream) { if (status != Z_OK) { throw new TZlibException(status, stream.msg); } } static void zlibLogError(int status, z_stream* stream) { if (status != Z_OK) { logError("TZlibTransport: zlib failure in destructor: %s", TZlibException.errorMessage(status, stream.msg)); } } // Writes smaller than this are buffered up (due to zlib handling overhead). // Larger (or equal) writes are dumped straight to zlib. enum MIN_DIRECT_DEFLATE_SIZE = 32; TTransport transport_; z_stream* rstream_; z_stream* wstream_; /// Whether zlib has reached the end of the input stream. bool inputEnded_; /// Whether the output stream was already finish()ed. bool outputFinished_; /// Compressed input data buffer. ubyte[] crbuf_; /// Uncompressed input data buffer. ubyte[] urbuf_; size_t urpos_; /// Uncompressed output data buffer (where small writes are accumulated /// before handing over to zlib). ubyte[] uwbuf_; size_t uwpos_; /// Compressed output data buffer (filled by zlib, we flush it to the /// underlying transport). ubyte[] cwbuf_; } /** * Wraps given transports into TZlibTransports. */ alias TWrapperTransportFactory!TZlibTransport TZlibTransportFactory; /** * An INTERNAL_ERROR-type TTransportException originating from an error * signaled by zlib. */ class TZlibException : TTransportException { this(int statusCode, const(char)* msg) { super(errorMessage(statusCode, msg), TTransportException.Type.INTERNAL_ERROR); zlibStatusCode = statusCode; zlibMsg = msg ? to!string(msg) : "(null)"; } int zlibStatusCode; string zlibMsg; static string errorMessage(int statusCode, const(char)* msg) { string result = "zlib error: "; if (msg) { result ~= to!string(msg); } else { result ~= "(no message)"; } result ~= " (status code = " ~ to!string(statusCode) ~ ")"; return result; } } version (unittest) { import std.exception : collectException; import thrift.transport.memory; } // Make sure basic reading/writing works. unittest { auto buf = new TMemoryBuffer; auto zlib = new TZlibTransport(buf); immutable ubyte[] data = [1, 2, 3, 4, 5]; zlib.write(data); zlib.finish(); auto result = new ubyte[data.length]; zlib.readAll(result); enforce(data == result); zlib.verifyChecksum(); } // Make sure there is no data is written if write() is never called. unittest { auto buf = new TMemoryBuffer; { scope zlib = new TZlibTransport(buf); } enforce(buf.getContents().length == 0); } // Make sure calling write()/flush()/finish() again after finish() throws. unittest { auto buf = new TMemoryBuffer; auto zlib = new TZlibTransport(buf); zlib.write([1, 2, 3, 4, 5]); zlib.finish(); auto ex = collectException!TTransportException(zlib.write([6])); enforce(ex && ex.type == TTransportException.Type.BAD_ARGS); ex = collectException!TTransportException(zlib.flush()); enforce(ex && ex.type == TTransportException.Type.BAD_ARGS); ex = collectException!TTransportException(zlib.finish()); enforce(ex && ex.type == TTransportException.Type.BAD_ARGS); } // Make sure verifying the checksum works even if it requires starting a new // reading buffer after reading the payload has already been completed. unittest { auto buf = new TMemoryBuffer; auto zlib = new TZlibTransport(buf); immutable ubyte[] data = [1, 2, 3, 4, 5]; zlib.write(data); zlib.finish(); zlib = new TZlibTransport(buf, TZlibTransport.DEFAULT_URBUF_SIZE, buf.getContents().length - 1); // The last byte belongs to the checksum. auto result = new ubyte[data.length]; zlib.readAll(result); enforce(data == result); zlib.verifyChecksum(); } // Make sure verifyChecksum() throws if we messed with the checksum. unittest { import std.stdio; import thrift.transport.range; auto buf = new TMemoryBuffer; auto zlib = new TZlibTransport(buf); immutable ubyte[] data = [1, 2, 3, 4, 5]; zlib.write(data); zlib.finish(); void testCorrupted(const(ubyte)[] corruptedData) { auto reader = new TZlibTransport(tInputRangeTransport(corruptedData)); auto result = new ubyte[data.length]; try { reader.readAll(result); // If it does read without complaining, the result should be correct. enforce(result == data); } catch (TZlibException e) {} auto ex = collectException!TTransportException(reader.verifyChecksum()); enforce(ex && ex.type == TTransportException.Type.CORRUPTED_DATA); } testCorrupted(buf.getContents()[0 .. $ - 1]); auto modified = buf.getContents().dup; ++modified[$ - 1]; testCorrupted(modified); } thrift-0.23.0/lib/d/src/thrift/protocol/0000775000175000017500000000000015165535636020316 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/protocol/processor.d0000664000175000017500000001041715165535636022505 0ustar00buildbuild00000000000000/* * 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. */ module thrift.protocol.processor; // Use selective import once DMD @@BUG314@@ is fixed. import std.variant /+ : Variant +/; import thrift.protocol.base; import thrift.transport.base; /** * A processor is a generic object which operates upon an input stream and * writes to some output stream. * * The definition of this object is loose, though the typical case is for some * sort of server that either generates responses to an input stream or * forwards data from one pipe onto another. * * An implementation can optionally allow one or more TProcessorEventHandlers * to be attached, providing an interface to hook custom code into the * handling process, which can be used e.g. for gathering statistics. */ interface TProcessor { /// bool process(TProtocol iprot, TProtocol oprot, Variant connectionContext = Variant() ) in { assert(iprot); assert(oprot); } /// final bool process(TProtocol prot, Variant connectionContext = Variant()) { return process(prot, prot, connectionContext); } } /** * Handles events from a processor. */ interface TProcessorEventHandler { /** * Called before calling other callback methods. * * Expected to return some sort of »call context«, which is passed to all * other callbacks for that function invocation. */ Variant createContext(string methodName, Variant connectionContext); /** * Called when handling the method associated with a context has been * finished – can be used to perform clean up work. */ void deleteContext(Variant callContext, string methodName); /** * Called before reading arguments. */ void preRead(Variant callContext, string methodName); /** * Called between reading arguments and calling the handler. */ void postRead(Variant callContext, string methodName); /** * Called between calling the handler and writing the response. */ void preWrite(Variant callContext, string methodName); /** * Called after writing the response. */ void postWrite(Variant callContext, string methodName); /** * Called when handling a one-way function call is completed successfully. */ void onewayComplete(Variant callContext, string methodName); /** * Called if the handler throws an undeclared exception. */ void handlerError(Variant callContext, string methodName, Exception e); } struct TConnectionInfo { /// The input and output protocols. TProtocol input; TProtocol output; /// Ditto. /// The underlying transport used for the connection /// This is the transport that was returned by TServerTransport.accept(), /// and it may be different than the transport pointed to by the input and /// output protocols. TTransport transport; } interface TProcessorFactory { /** * Get the TProcessor to use for a particular connection. * * This method is always invoked in the same thread that the connection was * accepted on, which is always the same thread for all current server * implementations. */ TProcessor getProcessor(ref const(TConnectionInfo) connInfo); } /** * The default processor factory which always returns the same instance. */ class TSingletonProcessorFactory : TProcessorFactory { /** * Creates a new instance. * * Params: * processor = The processor object to return from getProcessor(). */ this(TProcessor processor) { processor_ = processor; } override TProcessor getProcessor(ref const(TConnectionInfo) connInfo) { return processor_; } private: TProcessor processor_; } thrift-0.23.0/lib/d/src/thrift/protocol/binary.d0000664000175000017500000002505515165535636021756 0ustar00buildbuild00000000000000/* * 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. */ module thrift.protocol.binary; import std.array : uninitializedArray; import std.typetuple : allSatisfy, TypeTuple; import thrift.protocol.base; import thrift.transport.base; import thrift.internal.endian; /** * TProtocol implementation of the Binary Thrift protocol. */ final class TBinaryProtocol(Transport = TTransport) if ( isTTransport!Transport ) : TProtocol { /** * Constructs a new instance. * * Params: * trans = The transport to use. * containerSizeLimit = If positive, the container size is limited to the * given number of items. * stringSizeLimit = If positive, the string length is limited to the * given number of bytes. * strictRead = If false, old peers which do not include the protocol * version are tolerated. * strictWrite = Whether to include the protocol version in the header. */ this(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0, bool strictRead = false, bool strictWrite = true ) { trans_ = trans; this.containerSizeLimit = containerSizeLimit; this.stringSizeLimit = stringSizeLimit; this.strictRead = strictRead; this.strictWrite = strictWrite; } Transport transport() @property { return trans_; } void reset() {} /** * If false, old peers which do not include the protocol version in the * message header are tolerated. * * Defaults to false. */ bool strictRead; /** * Whether to include the protocol version in the message header (older * versions didn't). * * Defaults to true. */ bool strictWrite; /** * If positive, limits the number of items of deserialized containers to the * given amount. * * This is useful to avoid allocating excessive amounts of memory when broken * data is received. If the limit is exceeded, a SIZE_LIMIT-type * TProtocolException is thrown. * * Defaults to zero (no limit). */ int containerSizeLimit; /** * If positive, limits the length of deserialized strings/binary data to the * given number of bytes. * * This is useful to avoid allocating excessive amounts of memory when broken * data is received. If the limit is exceeded, a SIZE_LIMIT-type * TProtocolException is thrown. * * Defaults to zero (no limit). */ int stringSizeLimit; /* * Writing methods. */ void writeBool(bool b) { writeByte(b ? 1 : 0); } void writeByte(byte b) { trans_.write((cast(ubyte*)&b)[0 .. 1]); } void writeI16(short i16) { short net = hostToNet(i16); trans_.write((cast(ubyte*)&net)[0 .. 2]); } void writeI32(int i32) { int net = hostToNet(i32); trans_.write((cast(ubyte*)&net)[0 .. 4]); } void writeI64(long i64) { long net = hostToNet(i64); trans_.write((cast(ubyte*)&net)[0 .. 8]); } void writeDouble(double dub) { static assert(double.sizeof == ulong.sizeof); auto bits = hostToNet(*cast(ulong*)(&dub)); trans_.write((cast(ubyte*)&bits)[0 .. 8]); } void writeString(string str) { writeBinary(cast(ubyte[])str); } void writeBinary(ubyte[] buf) { assert(buf.length <= int.max); writeI32(cast(int)buf.length); trans_.write(buf); } void writeMessageBegin(TMessage message) { if (strictWrite) { int versn = VERSION_1 | message.type; writeI32(versn); writeString(message.name); writeI32(message.seqid); } else { writeString(message.name); writeByte(message.type); writeI32(message.seqid); } } void writeMessageEnd() {} void writeStructBegin(TStruct tstruct) {} void writeStructEnd() {} void writeFieldBegin(TField field) { writeByte(field.type); writeI16(field.id); } void writeFieldEnd() {} void writeFieldStop() { writeByte(TType.STOP); } void writeListBegin(TList list) { assert(list.size <= int.max); writeByte(list.elemType); writeI32(cast(int)list.size); } void writeListEnd() {} void writeMapBegin(TMap map) { assert(map.size <= int.max); writeByte(map.keyType); writeByte(map.valueType); writeI32(cast(int)map.size); } void writeMapEnd() {} void writeSetBegin(TSet set) { assert(set.size <= int.max); writeByte(set.elemType); writeI32(cast(int)set.size); } void writeSetEnd() {} /* * Reading methods. */ bool readBool() { return readByte() != 0; } byte readByte() { ubyte[1] b = void; trans_.readAll(b); return cast(byte)b[0]; } short readI16() { IntBuf!short b = void; trans_.readAll(b.bytes); return netToHost(b.value); } int readI32() { IntBuf!int b = void; trans_.readAll(b.bytes); return netToHost(b.value); } long readI64() { IntBuf!long b = void; trans_.readAll(b.bytes); return netToHost(b.value); } double readDouble() { IntBuf!long b = void; trans_.readAll(b.bytes); b.value = netToHost(b.value); return *cast(double*)(&b.value); } string readString() { return cast(string)readBinary(); } ubyte[] readBinary() { return readBinaryBody(readSize(stringSizeLimit)); } TMessage readMessageBegin() { TMessage msg = void; int size = readI32(); if (size < 0) { int versn = size & VERSION_MASK; if (versn != VERSION_1) { throw new TProtocolException("Bad protocol version.", TProtocolException.Type.BAD_VERSION); } msg.type = cast(TMessageType)(size & MESSAGE_TYPE_MASK); msg.name = readString(); msg.seqid = readI32(); } else { if (strictRead) { throw new TProtocolException( "Protocol version missing, old client?", TProtocolException.Type.BAD_VERSION); } else { if (size < 0) { throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE); } msg.name = cast(string)readBinaryBody(size); msg.type = cast(TMessageType)(readByte()); msg.seqid = readI32(); } } return msg; } void readMessageEnd() {} TStruct readStructBegin() { return TStruct(); } void readStructEnd() {} TField readFieldBegin() { TField f = void; f.name = null; f.type = cast(TType)readByte(); if (f.type == TType.STOP) return f; f.id = readI16(); return f; } void readFieldEnd() {} TList readListBegin() { return TList(cast(TType)readByte(), readSize(containerSizeLimit)); } void readListEnd() {} TMap readMapBegin() { return TMap(cast(TType)readByte(), cast(TType)readByte(), readSize(containerSizeLimit)); } void readMapEnd() {} TSet readSetBegin() { return TSet(cast(TType)readByte(), readSize(containerSizeLimit)); } void readSetEnd() {} private: ubyte[] readBinaryBody(int size) { if (size == 0) { return null; } auto buf = uninitializedArray!(ubyte[])(size); trans_.readAll(buf); return buf; } int readSize(int limit) { auto size = readI32(); if (size < 0) { throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE); } else if (limit > 0 && size > limit) { throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT); } return size; } enum MESSAGE_TYPE_MASK = 0x000000ff; enum VERSION_MASK = 0xffff0000; enum VERSION_1 = 0x80010000; Transport trans_; } /** * TBinaryProtocol construction helper to avoid having to explicitly specify * the transport type, i.e. to allow the constructor being called using IFTI * (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D Bugzilla * enhancement requet 6082)). */ TBinaryProtocol!Transport tBinaryProtocol(Transport)(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0, bool strictRead = false, bool strictWrite = true ) if (isTTransport!Transport) { return new TBinaryProtocol!Transport(trans, containerSizeLimit, stringSizeLimit, strictRead, strictWrite); } unittest { import std.exception; import thrift.transport.memory; // Check the message header format. auto buf = new TMemoryBuffer; auto binary = tBinaryProtocol(buf); binary.writeMessageBegin(TMessage("foo", TMessageType.CALL, 0)); auto header = new ubyte[15]; buf.readAll(header); enforce(header == [ 128, 1, 0, 1, // Version 1, TMessageType.CALL 0, 0, 0, 3, // Method name length 102, 111, 111, // Method name ("foo") 0, 0, 0, 0, // Sequence id ]); } unittest { import thrift.internal.test.protocol; testContainerSizeLimit!(TBinaryProtocol!())(); testStringSizeLimit!(TBinaryProtocol!())(); } /** * TProtocolFactory creating a TBinaryProtocol instance for passed in * transports. * * The optional Transports template tuple parameter can be used to specify * one or more TTransport implementations to specifically instantiate * TBinaryProtocol for. If the actual transport types encountered at * runtime match one of the transports in the list, a specialized protocol * instance is created. Otherwise, a generic TTransport version is used. */ class TBinaryProtocolFactory(Transports...) if ( allSatisfy!(isTTransport, Transports) ) : TProtocolFactory { /// this (int containerSizeLimit = 0, int stringSizeLimit = 0, bool strictRead = false, bool strictWrite = true ) { strictRead_ = strictRead; strictWrite_ = strictWrite; containerSizeLimit_ = containerSizeLimit; stringSizeLimit_ = stringSizeLimit; } TProtocol getProtocol(TTransport trans) const { foreach (Transport; TypeTuple!(Transports, TTransport)) { auto concreteTrans = cast(Transport)trans; if (concreteTrans) { return new TBinaryProtocol!Transport(concreteTrans, containerSizeLimit_, stringSizeLimit_, strictRead_, strictWrite_); } } throw new TProtocolException( "Passed null transport to TBinaryProtocolFactoy."); } protected: bool strictRead_; bool strictWrite_; int containerSizeLimit_; int stringSizeLimit_; } thrift-0.23.0/lib/d/src/thrift/protocol/base.d0000664000175000017500000002573015165535636021404 0ustar00buildbuild00000000000000/* * 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. */ /** * Defines the basic interface for a Thrift protocol and associated exception * types. * * Most parts of the protocol API are typically not used in client code, as * the actual serialization code is generated by thrift.codegen.* – the only * interesting thing usually is that there are protocols which can be created * from transports and passed around. */ module thrift.protocol.base; import thrift.base; import thrift.transport.base; /** * The field types Thrift protocols support. */ enum TType : byte { STOP = 0, /// Used to mark the end of a sequence of fields. VOID = 1, /// BOOL = 2, /// BYTE = 3, /// DOUBLE = 4, /// I16 = 6, /// I32 = 8, /// I64 = 10, /// STRING = 11, /// STRUCT = 12, /// MAP = 13, /// SET = 14, /// LIST = 15 /// } /** * Types of Thrift RPC messages. */ enum TMessageType : byte { CALL = 1, /// Call of a normal, two-way RPC method. REPLY = 2, /// Reply to a normal method call. EXCEPTION = 3, /// Reply to a method call if target raised a TApplicationException. ONEWAY = 4 /// Call of a one-way RPC method which is not followed by a reply. } /** * Descriptions of Thrift entities. */ struct TField { string name; TType type; short id; } /// ditto struct TList { TType elemType; size_t size; } /// ditto struct TMap { TType keyType; TType valueType; size_t size; } /// ditto struct TMessage { string name; TMessageType type; int seqid; } /// ditto struct TSet { TType elemType; size_t size; } /// ditto struct TStruct { string name; } /** * Interface for a Thrift protocol implementation. Essentially, it defines * a way of reading and writing all the base types, plus a mechanism for * writing out structs with indexed fields. * * TProtocol objects should not be shared across multiple encoding contexts, * as they may need to maintain internal state in some protocols (e.g. JSON). * Note that is is acceptable for the TProtocol module to do its own internal * buffered reads/writes to the underlying TTransport where appropriate (i.e. * when parsing an input XML stream, reading could be batched rather than * looking ahead character by character for a close tag). */ interface TProtocol { /// The underlying transport used by the protocol. TTransport transport() @property; /* * Writing methods. */ void writeBool(bool b); /// void writeByte(byte b); /// void writeI16(short i16); /// void writeI32(int i32); /// void writeI64(long i64); /// void writeDouble(double dub); /// void writeString(string str); /// void writeBinary(ubyte[] buf); /// void writeMessageBegin(TMessage message); /// void writeMessageEnd(); /// void writeStructBegin(TStruct tstruct); /// void writeStructEnd(); /// void writeFieldBegin(TField field); /// void writeFieldEnd(); /// void writeFieldStop(); /// void writeListBegin(TList list); /// void writeListEnd(); /// void writeMapBegin(TMap map); /// void writeMapEnd(); /// void writeSetBegin(TSet set); /// void writeSetEnd(); /// /* * Reading methods. */ bool readBool(); /// byte readByte(); /// short readI16(); /// int readI32(); /// long readI64(); /// double readDouble(); /// string readString(); /// ubyte[] readBinary(); /// TMessage readMessageBegin(); /// void readMessageEnd(); /// TStruct readStructBegin(); /// void readStructEnd(); /// TField readFieldBegin(); /// void readFieldEnd(); /// TList readListBegin(); /// void readListEnd(); /// TMap readMapBegin(); /// void readMapEnd(); /// TSet readSetBegin(); /// void readSetEnd(); /// /** * Reset any internal state back to a blank slate, if the protocol is * stateful. */ void reset(); } /** * true if T is a TProtocol. */ template isTProtocol(T) { enum isTProtocol = is(T : TProtocol); } unittest { static assert(isTProtocol!TProtocol); static assert(!isTProtocol!void); } /** * Creates a protocol operating on a given transport. */ interface TProtocolFactory { /// TProtocol getProtocol(TTransport trans); } /** * A protocol-level exception. */ class TProtocolException : TException { /// The possible exception types. enum Type { UNKNOWN, /// INVALID_DATA, /// NEGATIVE_SIZE, /// SIZE_LIMIT, /// BAD_VERSION, /// NOT_IMPLEMENTED, /// DEPTH_LIMIT /// } /// this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { static string msgForType(Type type) { switch (type) { case Type.UNKNOWN: return "Unknown protocol exception"; case Type.INVALID_DATA: return "Invalid data"; case Type.NEGATIVE_SIZE: return "Negative size"; case Type.SIZE_LIMIT: return "Exceeded size limit"; case Type.BAD_VERSION: return "Invalid version"; case Type.NOT_IMPLEMENTED: return "Not implemented"; case Type.DEPTH_LIMIT: return "Exceeded size limit"; default: return "(Invalid exception type)"; } } this(msgForType(type), type, file, line, next); } /// this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this(msg, Type.UNKNOWN, file, line, next); } /// this(string msg, Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); type_ = type; } /// Type type() const @property { return type_; } protected: Type type_; } /** * Skips a field of the given type on the protocol. * * The main purpose of skip() is to allow treating struct and container types, * (where multiple primitive types have to be skipped) the same as scalar types * in generated code. */ void skip(Protocol)(Protocol prot, TType type) if (is(Protocol : TProtocol)) { switch (type) { case TType.BOOL: prot.readBool(); break; case TType.BYTE: prot.readByte(); break; case TType.I16: prot.readI16(); break; case TType.I32: prot.readI32(); break; case TType.I64: prot.readI64(); break; case TType.DOUBLE: prot.readDouble(); break; case TType.STRING: prot.readBinary(); break; case TType.STRUCT: prot.readStructBegin(); while (true) { auto f = prot.readFieldBegin(); if (f.type == TType.STOP) break; skip(prot, f.type); prot.readFieldEnd(); } prot.readStructEnd(); break; case TType.LIST: auto l = prot.readListBegin(); foreach (i; 0 .. l.size) { skip(prot, l.elemType); } prot.readListEnd(); break; case TType.MAP: auto m = prot.readMapBegin(); foreach (i; 0 .. m.size) { skip(prot, m.keyType); skip(prot, m.valueType); } prot.readMapEnd(); break; case TType.SET: auto s = prot.readSetBegin(); foreach (i; 0 .. s.size) { skip(prot, s.elemType); } prot.readSetEnd(); break; default: throw new TProtocolException(TProtocolException.Type.INVALID_DATA); } } /** * Application-level exception. * * It is thrown if an RPC call went wrong on the application layer, e.g. if * the receiver does not know the method name requested or a method invoked by * the service processor throws an exception not part of the Thrift API. */ class TApplicationException : TException { /// The possible exception types. enum Type { UNKNOWN = 0, /// UNKNOWN_METHOD = 1, /// INVALID_MESSAGE_TYPE = 2, /// WRONG_METHOD_NAME = 3, /// BAD_SEQUENCE_ID = 4, /// MISSING_RESULT = 5, /// INTERNAL_ERROR = 6, /// PROTOCOL_ERROR = 7, /// INVALID_TRANSFORM = 8, /// INVALID_PROTOCOL = 9, /// UNSUPPORTED_CLIENT_TYPE = 10 /// } /// this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { static string msgForType(Type type) { switch (type) { case Type.UNKNOWN: return "Unknown application exception"; case Type.UNKNOWN_METHOD: return "Unknown method"; case Type.INVALID_MESSAGE_TYPE: return "Invalid message type"; case Type.WRONG_METHOD_NAME: return "Wrong method name"; case Type.BAD_SEQUENCE_ID: return "Bad sequence identifier"; case Type.MISSING_RESULT: return "Missing result"; case Type.INTERNAL_ERROR: return "Internal error"; case Type.PROTOCOL_ERROR: return "Protocol error"; case Type.INVALID_TRANSFORM: return "Invalid transform"; case Type.INVALID_PROTOCOL: return "Invalid protocol"; case Type.UNSUPPORTED_CLIENT_TYPE: return "Unsupported client type"; default: return "(Invalid exception type)"; } } this(msgForType(type), type, file, line, next); } /// this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { this(msg, Type.UNKNOWN, file, line, next); } /// this(string msg, Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); type_ = type; } /// Type type() @property const { return type_; } // TODO: Replace hand-written read()/write() with thrift.codegen templates. /// void read(TProtocol iprot) { iprot.readStructBegin(); while (true) { auto f = iprot.readFieldBegin(); if (f.type == TType.STOP) break; switch (f.id) { case 1: if (f.type == TType.STRING) { msg = iprot.readString(); } else { skip(iprot, f.type); } break; case 2: if (f.type == TType.I32) { type_ = cast(Type)iprot.readI32(); } else { skip(iprot, f.type); } break; default: skip(iprot, f.type); break; } } iprot.readStructEnd(); } /// void write(TProtocol oprot) const { oprot.writeStructBegin(TStruct("TApplicationException")); if (msg != null) { oprot.writeFieldBegin(TField("message", TType.STRING, 1)); oprot.writeString(msg); oprot.writeFieldEnd(); } oprot.writeFieldBegin(TField("type", TType.I32, 2)); oprot.writeI32(type_); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } private: Type type_; } thrift-0.23.0/lib/d/src/thrift/protocol/json.d0000664000175000017500000006332715165535636021447 0ustar00buildbuild00000000000000/* * 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. */ module thrift.protocol.json; import std.algorithm; import std.array; import std.base64; import std.conv; import std.range; import std.string : format; import std.traits : isIntegral; import std.typetuple : allSatisfy, TypeTuple; import std.utf : toUTF8; import thrift.protocol.base; import thrift.transport.base; alias Base64Impl!('+', '/', Base64.NoPadding) Base64NoPad; /** * Implementation of the Thrift JSON protocol. */ final class TJsonProtocol(Transport = TTransport) if ( isTTransport!Transport ) : TProtocol { /** * Constructs a new instance. * * Params: * trans = The transport to use. * containerSizeLimit = If positive, the container size is limited to the * given number of items. * stringSizeLimit = If positive, the string length is limited to the * given number of bytes. */ this(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0) { trans_ = trans; this.containerSizeLimit = containerSizeLimit; this.stringSizeLimit = stringSizeLimit; context_ = new Context(); reader_ = new LookaheadReader(trans); } Transport transport() @property { return trans_; } void reset() { destroy(contextStack_); context_ = new Context(); reader_ = new LookaheadReader(trans_); } /** * If positive, limits the number of items of deserialized containers to the * given amount. * * This is useful to avoid allocating excessive amounts of memory when broken * data is received. If the limit is exceeded, a SIZE_LIMIT-type * TProtocolException is thrown. * * Defaults to zero (no limit). */ int containerSizeLimit; /** * If positive, limits the length of deserialized strings/binary data to the * given number of bytes. * * This is useful to avoid allocating excessive amounts of memory when broken * data is received. If the limit is exceeded, a SIZE_LIMIT-type * TProtocolException is thrown. * * Note: For binary data, the limit applies to the length of the * Base64-encoded string data, not the resulting byte array. * * Defaults to zero (no limit). */ int stringSizeLimit; /* * Writing methods. */ void writeBool(bool b) { writeJsonInteger(b ? 1 : 0); } void writeByte(byte b) { writeJsonInteger(b); } void writeI16(short i16) { writeJsonInteger(i16); } void writeI32(int i32) { writeJsonInteger(i32); } void writeI64(long i64) { writeJsonInteger(i64); } void writeDouble(double dub) { context_.write(trans_); string value; if (dub is double.nan) { value = NAN_STRING; } else if (dub is double.infinity) { value = INFINITY_STRING; } else if (dub is -double.infinity) { value = NEG_INFINITY_STRING; } bool escapeNum = value !is null || context_.escapeNum; if (value is null) { /* precision is 17 */ value = format("%.17g", dub); } if (escapeNum) trans_.write(STRING_DELIMITER); trans_.write(cast(ubyte[])value); if (escapeNum) trans_.write(STRING_DELIMITER); } void writeString(string str) { context_.write(trans_); trans_.write(STRING_DELIMITER); foreach (c; str) { writeJsonChar(c); } trans_.write(STRING_DELIMITER); } void writeBinary(ubyte[] buf) { context_.write(trans_); trans_.write(STRING_DELIMITER); ubyte[4] b; while (!buf.empty) { auto toWrite = take(buf, 3); Base64NoPad.encode(toWrite, b[]); trans_.write(b[0 .. toWrite.length + 1]); buf.popFrontN(toWrite.length); } trans_.write(STRING_DELIMITER); } void writeMessageBegin(TMessage msg) { writeJsonArrayBegin(); writeJsonInteger(THRIFT_JSON_VERSION); writeString(msg.name); writeJsonInteger(cast(byte)msg.type); writeJsonInteger(msg.seqid); } void writeMessageEnd() { writeJsonArrayEnd(); } void writeStructBegin(TStruct tstruct) { writeJsonObjectBegin(); } void writeStructEnd() { writeJsonObjectEnd(); } void writeFieldBegin(TField field) { writeJsonInteger(field.id); writeJsonObjectBegin(); writeString(getNameFromTType(field.type)); } void writeFieldEnd() { writeJsonObjectEnd(); } void writeFieldStop() {} void writeListBegin(TList list) { writeJsonArrayBegin(); writeString(getNameFromTType(list.elemType)); writeJsonInteger(list.size); } void writeListEnd() { writeJsonArrayEnd(); } void writeMapBegin(TMap map) { writeJsonArrayBegin(); writeString(getNameFromTType(map.keyType)); writeString(getNameFromTType(map.valueType)); writeJsonInteger(map.size); writeJsonObjectBegin(); } void writeMapEnd() { writeJsonObjectEnd(); writeJsonArrayEnd(); } void writeSetBegin(TSet set) { writeJsonArrayBegin(); writeString(getNameFromTType(set.elemType)); writeJsonInteger(set.size); } void writeSetEnd() { writeJsonArrayEnd(); } /* * Reading methods. */ bool readBool() { return readJsonInteger!byte() ? true : false; } byte readByte() { return readJsonInteger!byte(); } short readI16() { return readJsonInteger!short(); } int readI32() { return readJsonInteger!int(); } long readI64() { return readJsonInteger!long(); } double readDouble() { context_.read(reader_); if (reader_.peek() == STRING_DELIMITER) { auto str = readJsonString(true); if (str == NAN_STRING) { return double.nan; } if (str == INFINITY_STRING) { return double.infinity; } if (str == NEG_INFINITY_STRING) { return -double.infinity; } if (!context_.escapeNum) { // Throw exception -- we should not be in a string in this case throw new TProtocolException("Numeric data unexpectedly quoted", TProtocolException.Type.INVALID_DATA); } try { return to!double(str); } catch (ConvException e) { throw new TProtocolException(`Expected numeric value; got "` ~ str ~ `".`, TProtocolException.Type.INVALID_DATA); } } else { if (context_.escapeNum) { // This will throw - we should have had a quote if escapeNum == true readJsonSyntaxChar(STRING_DELIMITER); } auto str = readJsonNumericChars(); try { return to!double(str); } catch (ConvException e) { throw new TProtocolException(`Expected numeric value; got "` ~ str ~ `".`, TProtocolException.Type.INVALID_DATA); } } } string readString() { return readJsonString(false); } ubyte[] readBinary() { return Base64NoPad.decode(readString()); } TMessage readMessageBegin() { TMessage msg = void; readJsonArrayBegin(); auto ver = readJsonInteger!short(); if (ver != THRIFT_JSON_VERSION) { throw new TProtocolException("Message contained bad version.", TProtocolException.Type.BAD_VERSION); } msg.name = readString(); msg.type = cast(TMessageType)readJsonInteger!byte(); msg.seqid = readJsonInteger!short(); return msg; } void readMessageEnd() { readJsonArrayEnd(); } TStruct readStructBegin() { readJsonObjectBegin(); return TStruct(); } void readStructEnd() { readJsonObjectEnd(); } TField readFieldBegin() { TField f = void; f.name = null; auto ch = reader_.peek(); if (ch == OBJECT_END) { f.type = TType.STOP; } else { f.id = readJsonInteger!short(); readJsonObjectBegin(); f.type = getTTypeFromName(readString()); } return f; } void readFieldEnd() { readJsonObjectEnd(); } TList readListBegin() { readJsonArrayBegin(); auto type = getTTypeFromName(readString()); auto size = readContainerSize(); return TList(type, size); } void readListEnd() { readJsonArrayEnd(); } TMap readMapBegin() { readJsonArrayBegin(); auto keyType = getTTypeFromName(readString()); auto valueType = getTTypeFromName(readString()); auto size = readContainerSize(); readJsonObjectBegin(); return TMap(keyType, valueType, size); } void readMapEnd() { readJsonObjectEnd(); readJsonArrayEnd(); } TSet readSetBegin() { readJsonArrayBegin(); auto type = getTTypeFromName(readString()); auto size = readContainerSize(); return TSet(type, size); } void readSetEnd() { readJsonArrayEnd(); } private: void pushContext(Context c) { contextStack_ ~= context_; context_ = c; } void popContext() { context_ = contextStack_.back; contextStack_.popBack(); contextStack_.assumeSafeAppend(); } /* * Writing functions */ // Write the character ch as a Json escape sequence ("\u00xx") void writeJsonEscapeChar(ubyte ch) { trans_.write(ESCAPE_PREFIX); trans_.write(ESCAPE_PREFIX); auto outCh = hexChar(cast(ubyte)(ch >> 4)); trans_.write((&outCh)[0 .. 1]); outCh = hexChar(ch); trans_.write((&outCh)[0 .. 1]); } // Write the character ch as part of a Json string, escaping as appropriate. void writeJsonChar(ubyte ch) { if (ch >= 0x30) { if (ch == '\\') { // Only special character >= 0x30 is '\' trans_.write(BACKSLASH); trans_.write(BACKSLASH); } else { trans_.write((&ch)[0 .. 1]); } } else { auto outCh = kJsonCharTable[ch]; // Check if regular character, backslash escaped, or Json escaped if (outCh == 1) { trans_.write((&ch)[0 .. 1]); } else if (outCh > 1) { trans_.write(BACKSLASH); trans_.write((&outCh)[0 .. 1]); } else { writeJsonEscapeChar(ch); } } } // Convert the given integer type to a Json number, or a string // if the context requires it (eg: key in a map pair). void writeJsonInteger(T)(T num) if (isIntegral!T) { context_.write(trans_); auto escapeNum = context_.escapeNum(); if (escapeNum) trans_.write(STRING_DELIMITER); trans_.write(cast(ubyte[])to!string(num)); if (escapeNum) trans_.write(STRING_DELIMITER); } void writeJsonObjectBegin() { context_.write(trans_); trans_.write(OBJECT_BEGIN); pushContext(new PairContext()); } void writeJsonObjectEnd() { popContext(); trans_.write(OBJECT_END); } void writeJsonArrayBegin() { context_.write(trans_); trans_.write(ARRAY_BEGIN); pushContext(new ListContext()); } void writeJsonArrayEnd() { popContext(); trans_.write(ARRAY_END); } /* * Reading functions */ int readContainerSize() { auto size = readJsonInteger!int(); if (size < 0) { throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE); } else if (containerSizeLimit > 0 && size > containerSizeLimit) { throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT); } return size; } void readJsonSyntaxChar(ubyte[1] ch) { return readSyntaxChar(reader_, ch); } wchar readJsonEscapeChar() { auto a = reader_.read(); auto b = reader_.read(); auto c = reader_.read(); auto d = reader_.read(); return cast(ushort)( (hexVal(a[0]) << 12) + (hexVal(b[0]) << 8) + (hexVal(c[0]) << 4) + hexVal(d[0]) ); } string readJsonString(bool skipContext = false) { if (!skipContext) context_.read(reader_); readJsonSyntaxChar(STRING_DELIMITER); auto buffer = appender!string(); wchar[] wchs; int bytesRead; while (true) { auto ch = reader_.read(); if (ch == STRING_DELIMITER) { break; } ++bytesRead; if (stringSizeLimit > 0 && bytesRead > stringSizeLimit) { throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT); } if (ch == BACKSLASH) { ch = reader_.read(); if (ch == ESCAPE_CHAR) { auto wch = readJsonEscapeChar(); if (wch >= 0xD800 && wch <= 0xDBFF) { wchs ~= wch; } else if (wch >= 0xDC00 && wch <= 0xDFFF && wchs.length == 0) { throw new TProtocolException("Missing UTF-16 high surrogate.", TProtocolException.Type.INVALID_DATA); } else { wchs ~= wch; buffer.put(wchs.toUTF8); wchs = []; } continue; } else { auto pos = countUntil(kEscapeChars[], ch[0]); if (pos == -1) { throw new TProtocolException("Expected control char, got '" ~ cast(char)ch[0] ~ "'.", TProtocolException.Type.INVALID_DATA); } ch = kEscapeCharVals[pos]; } } if (wchs.length != 0) { throw new TProtocolException("Missing UTF-16 low surrogate.", TProtocolException.Type.INVALID_DATA); } buffer.put(ch[0]); } if (wchs.length != 0) { throw new TProtocolException("Missing UTF-16 low surrogate.", TProtocolException.Type.INVALID_DATA); } return buffer.data; } // Reads a sequence of characters, stopping at the first one that is not // a valid Json numeric character. string readJsonNumericChars() { string str; while (true) { auto ch = reader_.peek(); if (!isJsonNumeric(ch[0])) { break; } reader_.read(); str ~= ch; } return str; } // Reads a sequence of characters and assembles them into a number, // returning them via num T readJsonInteger(T)() if (isIntegral!T) { context_.read(reader_); if (context_.escapeNum()) { readJsonSyntaxChar(STRING_DELIMITER); } auto str = readJsonNumericChars(); T num; try { num = to!T(str); } catch (ConvException e) { throw new TProtocolException(`Expected numeric value, got "` ~ str ~ `".`, TProtocolException.Type.INVALID_DATA); } if (context_.escapeNum()) { readJsonSyntaxChar(STRING_DELIMITER); } return num; } void readJsonObjectBegin() { context_.read(reader_); readJsonSyntaxChar(OBJECT_BEGIN); pushContext(new PairContext()); } void readJsonObjectEnd() { readJsonSyntaxChar(OBJECT_END); popContext(); } void readJsonArrayBegin() { context_.read(reader_); readJsonSyntaxChar(ARRAY_BEGIN); pushContext(new ListContext()); } void readJsonArrayEnd() { readJsonSyntaxChar(ARRAY_END); popContext(); } static { final class LookaheadReader { this(Transport trans) { trans_ = trans; } ubyte[1] read() { if (hasData_) { hasData_ = false; } else { trans_.readAll(data_); } return data_; } ubyte[1] peek() { if (!hasData_) { trans_.readAll(data_); hasData_ = true; } return data_; } private: Transport trans_; bool hasData_; ubyte[1] data_; } /* * Class to serve as base Json context and as base class for other context * implementations */ class Context { /** * Write context data to the transport. Default is to do nothing. */ void write(Transport trans) {} /** * Read context data from the transport. Default is to do nothing. */ void read(LookaheadReader reader) {} /** * Return true if numbers need to be escaped as strings in this context. * Default behavior is to return false. */ bool escapeNum() @property { return false; } } // Context class for object member key-value pairs class PairContext : Context { this() { first_ = true; colon_ = true; } override void write(Transport trans) { if (first_) { first_ = false; colon_ = true; } else { trans.write(colon_ ? PAIR_SEP : ELEM_SEP); colon_ = !colon_; } } override void read(LookaheadReader reader) { if (first_) { first_ = false; colon_ = true; } else { auto ch = (colon_ ? PAIR_SEP : ELEM_SEP); colon_ = !colon_; return readSyntaxChar(reader, ch); } } // Numbers must be turned into strings if they are the key part of a pair override bool escapeNum() @property { return colon_; } private: bool first_; bool colon_; } class ListContext : Context { this() { first_ = true; } override void write(Transport trans) { if (first_) { first_ = false; } else { trans.write(ELEM_SEP); } } override void read(LookaheadReader reader) { if (first_) { first_ = false; } else { readSyntaxChar(reader, ELEM_SEP); } } private: bool first_; } // Read 1 character from the transport trans and verify that it is the // expected character ch. // Throw a protocol exception if it is not. void readSyntaxChar(LookaheadReader reader, ubyte[1] ch) { auto ch2 = reader.read(); if (ch2 != ch) { throw new TProtocolException("Expected '" ~ cast(char)ch[0] ~ "', got '" ~ cast(char)ch2[0] ~ "'.", TProtocolException.Type.INVALID_DATA); } } } // Probably need to implement a better stack at some point. Context[] contextStack_; Context context_; Transport trans_; LookaheadReader reader_; } /** * TJsonProtocol construction helper to avoid having to explicitly specify * the transport type, i.e. to allow the constructor being called using IFTI * (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D Bugzilla * enhancement requet 6082)). */ TJsonProtocol!Transport tJsonProtocol(Transport)(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0 ) if (isTTransport!Transport) { return new TJsonProtocol!Transport(trans, containerSizeLimit, stringSizeLimit); } unittest { import std.exception; import thrift.transport.memory; // Check the message header format. auto buf = new TMemoryBuffer; auto json = tJsonProtocol(buf); json.writeMessageBegin(TMessage("foo", TMessageType.CALL, 0)); json.writeMessageEnd(); auto header = new ubyte[13]; buf.readAll(header); enforce(cast(char[])header == `[1,"foo",1,0]`); } unittest { import std.exception; import thrift.transport.memory; // Check that short binary data is read correctly (the Thrift JSON format // does not include padding chars in the Base64 encoded data). auto buf = new TMemoryBuffer; auto json = tJsonProtocol(buf); json.writeBinary([1, 2]); json.reset(); enforce(json.readBinary() == [1, 2]); } unittest { import std.exception; import thrift.transport.memory; auto buf = new TMemoryBuffer(cast(ubyte[])"\"\\u0e01 \\ud835\\udd3e\""); auto json = tJsonProtocol(buf); auto str = json.readString(); enforce(str == "ภð”¾"); } unittest { // Thrown if low surrogate is missing. import std.exception; import thrift.transport.memory; auto buf = new TMemoryBuffer(cast(ubyte[])"\"\\u0e01 \\ud835\""); auto json = tJsonProtocol(buf); assertThrown!TProtocolException(json.readString()); } unittest { // Thrown if high surrogate is missing. import std.exception; import thrift.transport.memory; auto buf = new TMemoryBuffer(cast(ubyte[])"\"\\u0e01 \\udd3e\""); auto json = tJsonProtocol(buf); assertThrown!TProtocolException(json.readString()); } unittest { import thrift.internal.test.protocol; testContainerSizeLimit!(TJsonProtocol!())(); testStringSizeLimit!(TJsonProtocol!())(); } /** * TProtocolFactory creating a TJsonProtocol instance for passed in * transports. * * The optional Transports template tuple parameter can be used to specify * one or more TTransport implementations to specifically instantiate * TJsonProtocol for. If the actual transport types encountered at * runtime match one of the transports in the list, a specialized protocol * instance is created. Otherwise, a generic TTransport version is used. */ class TJsonProtocolFactory(Transports...) if ( allSatisfy!(isTTransport, Transports) ) : TProtocolFactory { TProtocol getProtocol(TTransport trans) const { foreach (Transport; TypeTuple!(Transports, TTransport)) { auto concreteTrans = cast(Transport)trans; if (concreteTrans) { auto p = new TJsonProtocol!Transport(concreteTrans); return p; } } throw new TProtocolException( "Passed null transport to TJsonProtocolFactoy."); } } private { immutable ubyte[1] OBJECT_BEGIN = '{'; immutable ubyte[1] OBJECT_END = '}'; immutable ubyte[1] ARRAY_BEGIN = '['; immutable ubyte[1] ARRAY_END = ']'; immutable ubyte[1] NEWLINE = '\n'; immutable ubyte[1] PAIR_SEP = ':'; immutable ubyte[1] ELEM_SEP = ','; immutable ubyte[1] BACKSLASH = '\\'; immutable ubyte[1] STRING_DELIMITER = '"'; immutable ubyte[1] ZERO_CHAR = '0'; immutable ubyte[1] ESCAPE_CHAR = 'u'; immutable ubyte[4] ESCAPE_PREFIX = cast(ubyte[4])r"\u00"; enum THRIFT_JSON_VERSION = 1; immutable NAN_STRING = "NaN"; immutable INFINITY_STRING = "Infinity"; immutable NEG_INFINITY_STRING = "-Infinity"; string getNameFromTType(TType typeID) { final switch (typeID) { case TType.BOOL: return "tf"; case TType.BYTE: return "i8"; case TType.I16: return "i16"; case TType.I32: return "i32"; case TType.I64: return "i64"; case TType.DOUBLE: return "dbl"; case TType.STRING: return "str"; case TType.STRUCT: return "rec"; case TType.MAP: return "map"; case TType.LIST: return "lst"; case TType.SET: return "set"; case TType.STOP: goto case; case TType.VOID: assert(false, "Invalid type passed."); } } TType getTTypeFromName(string name) { TType result; if (name.length > 1) { switch (name[0]) { case 'd': result = TType.DOUBLE; break; case 'i': switch (name[1]) { case '8': result = TType.BYTE; break; case '1': result = TType.I16; break; case '3': result = TType.I32; break; case '6': result = TType.I64; break; default: // Do nothing. } break; case 'l': result = TType.LIST; break; case 'm': result = TType.MAP; break; case 'r': result = TType.STRUCT; break; case 's': if (name[1] == 't') { result = TType.STRING; } else if (name[1] == 'e') { result = TType.SET; } break; case 't': result = TType.BOOL; break; default: // Do nothing. } } if (result == TType.STOP) { throw new TProtocolException("Unrecognized type", TProtocolException.Type.NOT_IMPLEMENTED); } return result; } // This table describes the handling for the first 0x30 characters // 0 : escape using "\u00xx" notation // 1 : just output index // : escape using "\" notation immutable ubyte[0x30] kJsonCharTable = [ // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0, 0, 0, 0, 0, 0, 0, 0,'b','t','n', 0,'f','r', 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 1, 1,'"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 ]; // This string's characters must match up with the elements in kEscapeCharVals. // I don't have '/' on this list even though it appears on www.json.org -- // it is not in the RFC immutable kEscapeChars = cast(ubyte[7]) `"\\bfnrt`; // The elements of this array must match up with the sequence of characters in // kEscapeChars immutable ubyte[7] kEscapeCharVals = [ '"', '\\', '\b', '\f', '\n', '\r', '\t', ]; // Return the integer value of a hex character ch. // Throw a protocol exception if the character is not [0-9a-f]. ubyte hexVal(ubyte ch) { if ((ch >= '0') && (ch <= '9')) { return cast(ubyte)(ch - '0'); } else if ((ch >= 'a') && (ch <= 'f')) { return cast(ubyte)(ch - 'a' + 10); } else { throw new TProtocolException("Expected hex val ([0-9a-f]), got '" ~ ch ~ "'.", TProtocolException.Type.INVALID_DATA); } } // Return the hex character representing the integer val. The value is masked // to make sure it is in the correct range. ubyte hexChar(ubyte val) { val &= 0x0F; if (val < 10) { return cast(ubyte)(val + '0'); } else { return cast(ubyte)(val - 10 + 'a'); } } // Return true if the character ch is in [-+0-9.Ee]; false otherwise bool isJsonNumeric(ubyte ch) { switch (ch) { case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'E': case 'e': return true; default: return false; } } } thrift-0.23.0/lib/d/src/thrift/protocol/compact.d0000664000175000017500000004174215165535636022121 0ustar00buildbuild00000000000000/* * 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. */ module thrift.protocol.compact; import std.array : uninitializedArray; import std.typetuple : allSatisfy, TypeTuple; import thrift.protocol.base; import thrift.transport.base; import thrift.internal.endian; /** * D implementation of the Compact protocol. * * See THRIFT-110 for a protocol description. This implementation is based on * the C++ one. */ final class TCompactProtocol(Transport = TTransport) if ( isTTransport!Transport ) : TProtocol { /** * Constructs a new instance. * * Params: * trans = The transport to use. * containerSizeLimit = If positive, the container size is limited to the * given number of items. * stringSizeLimit = If positive, the string length is limited to the * given number of bytes. */ this(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0) { trans_ = trans; this.containerSizeLimit = containerSizeLimit; this.stringSizeLimit = stringSizeLimit; } Transport transport() @property { return trans_; } void reset() { lastFieldId_ = 0; fieldIdStack_ = null; booleanField_ = TField.init; hasBoolValue_ = false; } /** * If positive, limits the number of items of deserialized containers to the * given amount. * * This is useful to avoid allocating excessive amounts of memory when broken * data is received. If the limit is exceeded, a SIZE_LIMIT-type * TProtocolException is thrown. * * Defaults to zero (no limit). */ int containerSizeLimit; /** * If positive, limits the length of deserialized strings/binary data to the * given number of bytes. * * This is useful to avoid allocating excessive amounts of memory when broken * data is received. If the limit is exceeded, a SIZE_LIMIT-type * TProtocolException is thrown. * * Defaults to zero (no limit). */ int stringSizeLimit; /* * Writing methods. */ void writeBool(bool b) { if (booleanField_.name !is null) { // we haven't written the field header yet writeFieldBeginInternal(booleanField_, b ? CType.BOOLEAN_TRUE : CType.BOOLEAN_FALSE); booleanField_.name = null; } else { // we're not part of a field, so just write the value writeByte(b ? CType.BOOLEAN_TRUE : CType.BOOLEAN_FALSE); } } void writeByte(byte b) { trans_.write((cast(ubyte*)&b)[0..1]); } void writeI16(short i16) { writeVarint32(i32ToZigzag(i16)); } void writeI32(int i32) { writeVarint32(i32ToZigzag(i32)); } void writeI64(long i64) { writeVarint64(i64ToZigzag(i64)); } void writeDouble(double dub) { ulong bits = hostToLe(*cast(ulong*)(&dub)); trans_.write((cast(ubyte*)&bits)[0 .. 8]); } void writeString(string str) { writeBinary(cast(ubyte[])str); } void writeBinary(ubyte[] buf) { assert(buf.length <= int.max); writeVarint32(cast(int)buf.length); trans_.write(buf); } void writeMessageBegin(TMessage msg) { writeByte(cast(byte)PROTOCOL_ID); writeByte(cast(byte)((VERSION_N & VERSION_MASK) | ((cast(int)msg.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK))); writeVarint32(msg.seqid); writeString(msg.name); } void writeMessageEnd() {} void writeStructBegin(TStruct tstruct) { fieldIdStack_ ~= lastFieldId_; lastFieldId_ = 0; } void writeStructEnd() { lastFieldId_ = fieldIdStack_[$ - 1]; fieldIdStack_ = fieldIdStack_[0 .. $ - 1]; fieldIdStack_.assumeSafeAppend(); } void writeFieldBegin(TField field) { if (field.type == TType.BOOL) { booleanField_.name = field.name; booleanField_.type = field.type; booleanField_.id = field.id; } else { return writeFieldBeginInternal(field); } } void writeFieldEnd() {} void writeFieldStop() { writeByte(TType.STOP); } void writeListBegin(TList list) { writeCollectionBegin(list.elemType, list.size); } void writeListEnd() {} void writeMapBegin(TMap map) { if (map.size == 0) { writeByte(0); } else { assert(map.size <= int.max); writeVarint32(cast(int)map.size); writeByte(cast(byte)(toCType(map.keyType) << 4 | toCType(map.valueType))); } } void writeMapEnd() {} void writeSetBegin(TSet set) { writeCollectionBegin(set.elemType, set.size); } void writeSetEnd() {} /* * Reading methods. */ bool readBool() { if (hasBoolValue_ == true) { hasBoolValue_ = false; return boolValue_; } return readByte() == CType.BOOLEAN_TRUE; } byte readByte() { ubyte[1] b = void; trans_.readAll(b); return cast(byte)b[0]; } short readI16() { return cast(short)zigzagToI32(readVarint32()); } int readI32() { return zigzagToI32(readVarint32()); } long readI64() { return zigzagToI64(readVarint64()); } double readDouble() { IntBuf!long b = void; trans_.readAll(b.bytes); b.value = leToHost(b.value); return *cast(double*)(&b.value); } string readString() { return cast(string)readBinary(); } ubyte[] readBinary() { auto size = readVarint32(); checkSize(size, stringSizeLimit); if (size == 0) { return null; } auto buf = uninitializedArray!(ubyte[])(size); trans_.readAll(buf); return buf; } TMessage readMessageBegin() { TMessage msg = void; auto protocolId = readByte(); if (protocolId != cast(byte)PROTOCOL_ID) { throw new TProtocolException("Bad protocol identifier", TProtocolException.Type.BAD_VERSION); } auto versionAndType = readByte(); auto ver = versionAndType & VERSION_MASK; if (ver != VERSION_N) { throw new TProtocolException("Bad protocol version", TProtocolException.Type.BAD_VERSION); } msg.type = cast(TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS); msg.seqid = readVarint32(); msg.name = readString(); return msg; } void readMessageEnd() {} TStruct readStructBegin() { fieldIdStack_ ~= lastFieldId_; lastFieldId_ = 0; return TStruct(); } void readStructEnd() { lastFieldId_ = fieldIdStack_[$ - 1]; fieldIdStack_ = fieldIdStack_[0 .. $ - 1]; } TField readFieldBegin() { TField f = void; f.name = null; auto bite = readByte(); auto type = cast(CType)(bite & 0x0f); if (type == CType.STOP) { // Struct stop byte, nothing more to do. f.id = 0; f.type = TType.STOP; return f; } // Mask off the 4 MSB of the type header, which could contain a field id // delta. auto modifier = cast(short)((bite & 0xf0) >> 4); if (modifier > 0) { f.id = cast(short)(lastFieldId_ + modifier); } else { // Delta encoding not used, just read the id as usual. f.id = readI16(); } f.type = getTType(type); if (type == CType.BOOLEAN_TRUE || type == CType.BOOLEAN_FALSE) { // For boolean fields, the value is encoded in the type – keep it around // for the readBool() call. hasBoolValue_ = true; boolValue_ = (type == CType.BOOLEAN_TRUE ? true : false); } lastFieldId_ = f.id; return f; } void readFieldEnd() {} TList readListBegin() { auto sizeAndType = readByte(); auto lsize = (sizeAndType >> 4) & 0xf; if (lsize == 0xf) { lsize = readVarint32(); } checkSize(lsize, containerSizeLimit); TList l = void; l.elemType = getTType(cast(CType)(sizeAndType & 0x0f)); l.size = cast(size_t)lsize; return l; } void readListEnd() {} TMap readMapBegin() { TMap m = void; auto size = readVarint32(); ubyte kvType; if (size != 0) { kvType = readByte(); } checkSize(size, containerSizeLimit); m.size = size; m.keyType = getTType(cast(CType)(kvType >> 4)); m.valueType = getTType(cast(CType)(kvType & 0xf)); return m; } void readMapEnd() {} TSet readSetBegin() { auto sizeAndType = readByte(); auto lsize = (sizeAndType >> 4) & 0xf; if (lsize == 0xf) { lsize = readVarint32(); } checkSize(lsize, containerSizeLimit); TSet s = void; s.elemType = getTType(cast(CType)(sizeAndType & 0xf)); s.size = cast(size_t)lsize; return s; } void readSetEnd() {} private: void writeFieldBeginInternal(TField field, byte typeOverride = -1) { // If there's a type override, use that. auto typeToWrite = (typeOverride == -1 ? toCType(field.type) : typeOverride); // check if we can use delta encoding for the field id if (field.id > lastFieldId_ && (field.id - lastFieldId_) <= 15) { // write them together writeByte(cast(byte)((field.id - lastFieldId_) << 4 | typeToWrite)); } else { // write them separate writeByte(cast(byte)typeToWrite); writeI16(field.id); } lastFieldId_ = field.id; } void writeCollectionBegin(TType elemType, size_t size) { if (size <= 14) { writeByte(cast(byte)(size << 4 | toCType(elemType))); } else { assert(size <= int.max); writeByte(cast(byte)(0xf0 | toCType(elemType))); writeVarint32(cast(int)size); } } void writeVarint32(uint n) { ubyte[5] buf = void; ubyte wsize; while (true) { if ((n & ~0x7F) == 0) { buf[wsize++] = cast(ubyte)n; break; } else { buf[wsize++] = cast(ubyte)((n & 0x7F) | 0x80); n >>= 7; } } trans_.write(buf[0 .. wsize]); } /* * Write an i64 as a varint. Results in 1-10 bytes on the wire. */ void writeVarint64(ulong n) { ubyte[10] buf = void; ubyte wsize; while (true) { if ((n & ~0x7FL) == 0) { buf[wsize++] = cast(ubyte)n; break; } else { buf[wsize++] = cast(ubyte)((n & 0x7F) | 0x80); n >>= 7; } } trans_.write(buf[0 .. wsize]); } /* * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ ulong i64ToZigzag(long l) { return (l << 1) ^ (l >> 63); } /* * Convert n into a zigzag int. This allows negative numbers to be * represented compactly as a varint. */ uint i32ToZigzag(int n) { return (n << 1) ^ (n >> 31); } CType toCType(TType type) { final switch (type) { case TType.STOP: return CType.STOP; case TType.BOOL: return CType.BOOLEAN_TRUE; case TType.BYTE: return CType.BYTE; case TType.DOUBLE: return CType.DOUBLE; case TType.I16: return CType.I16; case TType.I32: return CType.I32; case TType.I64: return CType.I64; case TType.STRING: return CType.BINARY; case TType.STRUCT: return CType.STRUCT; case TType.MAP: return CType.MAP; case TType.SET: return CType.SET; case TType.LIST: return CType.LIST; case TType.VOID: assert(false, "Invalid type passed."); } } int readVarint32() { return cast(int)readVarint64(); } long readVarint64() { ulong val; ubyte shift; ubyte[10] buf = void; // 64 bits / (7 bits/byte) = 10 bytes. auto bufSize = buf.sizeof; auto borrowed = trans_.borrow(buf.ptr, bufSize); ubyte rsize; if (borrowed) { // Fast path. while (true) { auto bite = borrowed[rsize]; rsize++; val |= cast(ulong)(bite & 0x7f) << shift; shift += 7; if (!(bite & 0x80)) { trans_.consume(rsize); return val; } // Have to check for invalid data so we don't crash. if (rsize == buf.sizeof) { throw new TProtocolException(TProtocolException.Type.INVALID_DATA, "Variable-length int over 10 bytes."); } } } else { // Slow path. while (true) { ubyte[1] bite; trans_.readAll(bite); ++rsize; val |= cast(ulong)(bite[0] & 0x7f) << shift; shift += 7; if (!(bite[0] & 0x80)) { return val; } // Might as well check for invalid data on the slow path too. if (rsize >= buf.sizeof) { throw new TProtocolException(TProtocolException.Type.INVALID_DATA, "Variable-length int over 10 bytes."); } } } } /* * Convert from zigzag int to int. */ int zigzagToI32(uint n) { return (n >> 1) ^ -(n & 1); } /* * Convert from zigzag long to long. */ long zigzagToI64(ulong n) { return (n >> 1) ^ -(n & 1); } TType getTType(CType type) { final switch (type) { case CType.STOP: return TType.STOP; case CType.BOOLEAN_FALSE: return TType.BOOL; case CType.BOOLEAN_TRUE: return TType.BOOL; case CType.BYTE: return TType.BYTE; case CType.I16: return TType.I16; case CType.I32: return TType.I32; case CType.I64: return TType.I64; case CType.DOUBLE: return TType.DOUBLE; case CType.BINARY: return TType.STRING; case CType.LIST: return TType.LIST; case CType.SET: return TType.SET; case CType.MAP: return TType.MAP; case CType.STRUCT: return TType.STRUCT; } } void checkSize(int size, int limit) { if (size < 0) { throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE); } else if (limit > 0 && size > limit) { throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT); } } enum PROTOCOL_ID = 0x82; enum VERSION_N = 1; enum VERSION_MASK = 0b0001_1111; enum TYPE_MASK = 0b1110_0000; enum TYPE_BITS = 0b0000_0111; enum TYPE_SHIFT_AMOUNT = 5; // Probably need to implement a better stack at some point. short[] fieldIdStack_; short lastFieldId_; TField booleanField_; bool hasBoolValue_; bool boolValue_; Transport trans_; } /** * TCompactProtocol construction helper to avoid having to explicitly specify * the transport type, i.e. to allow the constructor being called using IFTI * (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D Bugzilla * enhancement requet 6082)). */ TCompactProtocol!Transport tCompactProtocol(Transport)(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0 ) if (isTTransport!Transport) { return new TCompactProtocol!Transport(trans, containerSizeLimit, stringSizeLimit); } private { enum CType : ubyte { STOP = 0x0, BOOLEAN_TRUE = 0x1, BOOLEAN_FALSE = 0x2, BYTE = 0x3, I16 = 0x4, I32 = 0x5, I64 = 0x6, DOUBLE = 0x7, BINARY = 0x8, LIST = 0x9, SET = 0xa, MAP = 0xb, STRUCT = 0xc } static assert(CType.max <= 0xf, "Compact protocol wire type representation must fit into 4 bits."); } unittest { import std.exception; import thrift.transport.memory; // Check the message header format. auto buf = new TMemoryBuffer; auto compact = tCompactProtocol(buf); compact.writeMessageBegin(TMessage("foo", TMessageType.CALL, 0)); auto header = new ubyte[7]; buf.readAll(header); enforce(header == [ 130, // Protocol id. 33, // Version/type byte. 0, // Sequence id. 3, 102, 111, 111 // Method name. ]); } unittest { import thrift.internal.test.protocol; testContainerSizeLimit!(TCompactProtocol!())(); testStringSizeLimit!(TCompactProtocol!())(); } /** * TProtocolFactory creating a TCompactProtocol instance for passed in * transports. * * The optional Transports template tuple parameter can be used to specify * one or more TTransport implementations to specifically instantiate * TCompactProtocol for. If the actual transport types encountered at * runtime match one of the transports in the list, a specialized protocol * instance is created. Otherwise, a generic TTransport version is used. */ class TCompactProtocolFactory(Transports...) if ( allSatisfy!(isTTransport, Transports) ) : TProtocolFactory { /// this(int containerSizeLimit = 0, int stringSizeLimit = 0) { containerSizeLimit_ = 0; stringSizeLimit_ = 0; } TProtocol getProtocol(TTransport trans) const { foreach (Transport; TypeTuple!(Transports, TTransport)) { auto concreteTrans = cast(Transport)trans; if (concreteTrans) { return new TCompactProtocol!Transport(concreteTrans); } } throw new TProtocolException( "Passed null transport to TCompactProtocolFactory."); } int containerSizeLimit_; int stringSizeLimit_; } thrift-0.23.0/lib/d/src/thrift/util/0000775000175000017500000000000015165535636017432 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/src/thrift/util/future.d0000664000175000017500000003736215165535636021124 0ustar00buildbuild00000000000000/* * 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. */ module thrift.util.future; import core.atomic; import core.sync.condition; import core.sync.mutex; import core.time : Duration; import std.array : empty, front, popFront; import std.conv : to; import std.exception : enforce; import std.traits : BaseTypeTuple, isSomeFunction, ParameterTypeTuple, ReturnType; import thrift.base; import thrift.util.awaitable; import thrift.util.cancellation; /** * Represents an operation which is executed asynchronously and the result of * which will become available at some point in the future. * * Once a operation is completed, the result of the operation can be fetched * via the get() family of methods. There are three possible cases: Either the * operation succeeded, then its return value is returned, or it failed by * throwing, in which case the exception is rethrown, or it was cancelled * before, then a TCancelledException is thrown. There might be TFuture * implementations which never possibly enter the cancelled state. * * All methods are thread-safe, but keep in mind that any exception object or * result (if it is a reference type, of course) is shared between all * get()-family invocations. */ interface TFuture(ResultType) { /** * The status the operation is currently in. * * An operation starts out in RUNNING status, and changes state to one of the * others at most once afterwards. */ TFutureStatus status() @property; /** * A TAwaitable triggered when the operation leaves the RUNNING status. */ TAwaitable completion() @property; /** * Convenience shorthand for waiting until the result is available and then * get()ing it. * * If the operation has already completed, the result is immediately * returned. * * The result of this method is »alias this«'d to the interface, so that * TFuture can be used as a drop-in replacement for a simple value in * synchronous code. */ final ResultType waitGet() { completion.wait(); return get(); } final @property auto waitGetProperty() { return waitGet(); } alias waitGetProperty this; /** * Convenience shorthand for waiting until the result is available and then * get()ing it. * * If the operation completes in time, returns its result (resp. throws an * exception for the failed/cancelled cases). If not, throws a * TFutureException. */ final ResultType waitGet(Duration timeout) { enforce(completion.wait(timeout), new TFutureException( "Operation did not complete in time.")); return get(); } /** * Returns the result of the operation. * * Throws: TFutureException if the operation has been cancelled, * TCancelledException if it is not yet done; the set exception if it * failed. */ ResultType get(); /** * Returns the captured exception if the operation failed, or null otherwise. * * Throws: TFutureException if not yet done, TCancelledException if the * operation has been cancelled. */ Exception getException(); } /** * The states the operation offering a future interface can be in. */ enum TFutureStatus : byte { RUNNING, /// The operation is still running. SUCCEEDED, /// The operation completed without throwing an exception. FAILED, /// The operation completed by throwing an exception. CANCELLED /// The operation was cancelled. } /** * A TFuture covering the simple but common case where the result is simply * set by a call to succeed()/fail(). * * All methods are thread-safe, but usually, succeed()/fail() are only called * from a single thread (different from the thread(s) waiting for the result * using the TFuture interface, though). */ class TPromise(ResultType) : TFuture!ResultType { this() { statusMutex_ = new Mutex; completionEvent_ = new TOneshotEvent; } override S status() const @property { return atomicLoad(status_); } override TAwaitable completion() @property { return completionEvent_; } override ResultType get() { auto s = atomicLoad(status_); enforce(s != S.RUNNING, new TFutureException("Operation not yet completed.")); if (s == S.CANCELLED) throw new TCancelledException; if (s == S.FAILED) throw exception_; static if (!is(ResultType == void)) { return result_; } } override Exception getException() { auto s = atomicLoad(status_); enforce(s != S.RUNNING, new TFutureException("Operation not yet completed.")); if (s == S.CANCELLED) throw new TCancelledException; if (s == S.SUCCEEDED) return null; return exception_; } static if (!is(ResultType == void)) { /** * Sets the result of the operation, marks it as done, and notifies any * waiters. * * If the operation has been cancelled before, nothing happens. * * Throws: TFutureException if the operation is already completed. */ void succeed(ResultType result) { synchronized (statusMutex_) { auto s = atomicLoad(status_); if (s == S.CANCELLED) return; enforce(s == S.RUNNING, new TFutureException("Operation already completed.")); result_ = result; atomicStore(status_, S.SUCCEEDED); } completionEvent_.trigger(); } } else { void succeed() { synchronized (statusMutex_) { auto s = atomicLoad(status_); if (s == S.CANCELLED) return; enforce(s == S.RUNNING, new TFutureException("Operation already completed.")); atomicStore(status_, S.SUCCEEDED); } completionEvent_.trigger(); } } /** * Marks the operation as failed with the specified exception and notifies * any waiters. * * If the operation was already cancelled, nothing happens. * * Throws: TFutureException if the operation is already completed. */ void fail(Exception exception) { synchronized (statusMutex_) { auto status = atomicLoad(status_); if (status == S.CANCELLED) return; enforce(status == S.RUNNING, new TFutureException("Operation already completed.")); exception_ = exception; atomicStore(status_, S.FAILED); } completionEvent_.trigger(); } /** * Marks this operation as completed and takes over the outcome of another * TFuture of the same type. * * If this operation was already cancelled, nothing happens. If the other * operation was cancelled, this operation is marked as failed with a * TCancelledException. * * Throws: TFutureException if the passed in future was not completed or * this operation is already completed. */ void complete(TFuture!ResultType future) { synchronized (statusMutex_) { auto status = atomicLoad(status_); if (status == S.CANCELLED) return; enforce(status == S.RUNNING, new TFutureException("Operation already completed.")); enforce(future.status != S.RUNNING, new TFutureException( "The passed TFuture is not yet completed.")); status = future.status; if (status == S.CANCELLED) { status = S.FAILED; exception_ = new TCancelledException; } else if (status == S.FAILED) { exception_ = future.getException(); } else static if (!is(ResultType == void)) { result_ = future.get(); } atomicStore(status_, status); } completionEvent_.trigger(); } /** * Marks this operation as cancelled and notifies any waiters. * * If the operation is already completed, nothing happens. */ void cancel() { synchronized (statusMutex_) { auto status = atomicLoad(status_); if (status == S.RUNNING) atomicStore(status_, S.CANCELLED); } completionEvent_.trigger(); } private: // Convenience alias because TFutureStatus is ubiquitous in this class. alias TFutureStatus S; // The status the promise is currently in. shared S status_; union { static if (!is(ResultType == void)) { // Set if status_ is SUCCEEDED. ResultType result_; } // Set if status_ is FAILED. Exception exception_; } // Protects status_. // As for result_ and exception_: They are only set once, while status_ is // still RUNNING, so given that the operation has already completed, reading // them is safe without holding some kind of lock. Mutex statusMutex_; // Triggered when the event completes. TOneshotEvent completionEvent_; } /// class TFutureException : TException { /// this(string msg = "", string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } } /** * Creates an interface that is similar to a given one, but accepts an * additional, optional TCancellation parameter each method, and returns * TFutures instead of plain return values. * * For example, given the following declarations: * --- * interface Foo { * void bar(); * string baz(int a); * } * alias TFutureInterface!Foo FutureFoo; * --- * * FutureFoo would be equivalent to: * --- * interface FutureFoo { * TFuture!void bar(TCancellation cancellation = null); * TFuture!string baz(int a, TCancellation cancellation = null); * } * --- */ template TFutureInterface(Interface) if (is(Interface _ == interface)) { mixin({ string code = "interface TFutureInterface \n"; static if (is(Interface Bases == super) && Bases.length > 0) { code ~= ": "; foreach (i; 0 .. Bases.length) { if (i > 0) code ~= ", "; code ~= "TFutureInterface!(BaseTypeTuple!Interface[" ~ to!string(i) ~ "]) "; } } code ~= "{\n"; foreach (methodName; __traits(derivedMembers, Interface)) { enum qn = "Interface." ~ methodName; static if (isSomeFunction!(mixin(qn))) { code ~= "TFuture!(ReturnType!(" ~ qn ~ ")) " ~ methodName ~ "(ParameterTypeTuple!(" ~ qn ~ "), TCancellation cancellation = null);\n"; } } code ~= "}\n"; return code; }()); } /** * An input range that aggregates results from multiple asynchronous operations, * returning them in the order they arrive. * * Additionally, a timeout can be set after which results from not yet finished * futures will no longer be waited for, e.g. to ensure the time it takes to * iterate over a set of results is limited. */ final class TFutureAggregatorRange(T) { /** * Constructs a new instance. * * Params: * futures = The set of futures to collect results from. * timeout = If positive, not yet finished futures will be cancelled and * their results will not be taken into account. */ this(TFuture!T[] futures, TCancellationOrigin childCancellation, Duration timeout = dur!"hnsecs"(0) ) { if (timeout > dur!"hnsecs"(0)) { timeoutSysTick_ = TickDuration.currSystemTick + TickDuration.from!"hnsecs"(timeout.total!"hnsecs"); } else { timeoutSysTick_ = TickDuration(0); } queueMutex_ = new Mutex; queueNonEmptyCondition_ = new Condition(queueMutex_); futures_ = futures; childCancellation_ = childCancellation; foreach (future; futures_) { future.completion.addCallback({ auto f = future; return { if (f.status == TFutureStatus.CANCELLED) return; assert(f.status != TFutureStatus.RUNNING); synchronized (queueMutex_) { completedQueue_ ~= f; if (completedQueue_.length == 1) { queueNonEmptyCondition_.notifyAll(); } } }; }()); } } /** * Whether the range is empty. * * This is the case if the results from the completed futures not having * failed have already been popped and either all future have been finished * or the timeout has expired. * * Potentially blocks until a new result is available or the timeout has * expired. */ bool empty() @property { if (finished_) return true; if (bufferFilled_) return false; while (true) { TFuture!T future; synchronized (queueMutex_) { // The while loop is just being cautious about spurious wakeups, in // case they should be possible. while (completedQueue_.empty) { auto remaining = to!Duration(timeoutSysTick_ - TickDuration.currSystemTick); if (remaining <= dur!"hnsecs"(0)) { // No time left, but still no element received – we are empty now. finished_ = true; childCancellation_.trigger(); return true; } queueNonEmptyCondition_.wait(remaining); } future = completedQueue_.front; completedQueue_.popFront(); } ++completedCount_; if (completedCount_ == futures_.length) { // This was the last future in the list, there is no possibility // another result could ever become available. finished_ = true; } if (future.status == TFutureStatus.FAILED) { // This one failed, loop again and try getting another item from // the queue. exceptions_ ~= future.getException(); } else { resultBuffer_ = future.get(); bufferFilled_ = true; return false; } } } /** * Returns the first element from the range. * * Potentially blocks until a new result is available or the timeout has * expired. * * Throws: TException if the range is empty. */ T front() { enforce(!empty, new TException( "Cannot get front of an empty future aggregator range.")); return resultBuffer_; } /** * Removes the first element from the range. * * Potentially blocks until a new result is available or the timeout has * expired. * * Throws: TException if the range is empty. */ void popFront() { enforce(!empty, new TException( "Cannot pop front of an empty future aggregator range.")); bufferFilled_ = false; } /** * The number of futures the result of which has been returned or which have * failed so far. */ size_t completedCount() @property const { return completedCount_; } /** * The exceptions collected from failed TFutures so far. */ Exception[] exceptions() @property { return exceptions_; } private: TFuture!T[] futures_; TCancellationOrigin childCancellation_; // The system tick this operation will time out, or zero if no timeout has // been set. TickDuration timeoutSysTick_; bool finished_; bool bufferFilled_; T resultBuffer_; Exception[] exceptions_; size_t completedCount_; // The queue of completed futures. This (and the associated condition) are // the only parts of this class that are accessed by multiple threads. TFuture!T[] completedQueue_; Mutex queueMutex_; Condition queueNonEmptyCondition_; } /** * TFutureAggregatorRange construction helper to avoid having to explicitly * specify the value type, i.e. to allow the constructor being called using IFTI * (see $(DMDBUG 6082, D Bugzilla enhancement requet 6082)). */ TFutureAggregatorRange!T tFutureAggregatorRange(T)(TFuture!T[] futures, TCancellationOrigin childCancellation, Duration timeout = dur!"hnsecs"(0) ) { return new TFutureAggregatorRange!T(futures, childCancellation, timeout); } thrift-0.23.0/lib/d/src/thrift/util/cancellation.d0000664000175000017500000000614615165535636022242 0ustar00buildbuild00000000000000/* * 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. */ module thrift.util.cancellation; import core.atomic; import thrift.base; import thrift.util.awaitable; /** * A cancellation request for asynchronous or blocking synchronous operations. * * It is passed to the entity creating an operation, which will usually monitor * it either by polling or by adding event handlers, and cancel the operation * if it is triggered. * * For synchronous operations, this usually means either throwing a * TCancelledException or immediately returning, depending on whether * cancellation is an expected part of the task outcome or not. For * asynchronous operations, cancellation typically entails stopping background * work and cancelling a result future, if not already completed. * * An operation accepting a TCancellation does not need to guarantee that it * will actually be able to react to the cancellation request. */ interface TCancellation { /** * Whether the cancellation request has been triggered. */ bool triggered() const @property; /** * Throws a TCancelledException if the cancellation request has already been * triggered. */ void throwIfTriggered() const; /** * A TAwaitable that can be used to wait for cancellation triggering. */ TAwaitable triggering() @property; } /** * The origin of a cancellation request, which provides a way to actually * trigger it. * * This design allows operations to pass the TCancellation on to sub-tasks, * while making sure that the cancellation can only be triggered by the * »outermost« instance waiting for the result. */ final class TCancellationOrigin : TCancellation { this() { event_ = new TOneshotEvent; } /** * Triggers the cancellation request. */ void trigger() { atomicStore(triggered_, true); event_.trigger(); } /+override+/ bool triggered() const @property { return atomicLoad(triggered_); } /+override+/ void throwIfTriggered() const { if (triggered) throw new TCancelledException; } /+override+/ TAwaitable triggering() @property { return event_; } private: shared bool triggered_; TOneshotEvent event_; } /// class TCancelledException : TException { /// this(string msg = null, string file = __FILE__, size_t line = __LINE__, Throwable next = null ) { super(msg ? msg : "The operation has been cancelled.", file, line, next); } } thrift-0.23.0/lib/d/src/thrift/util/hashset.d0000664000175000017500000000705615165535636021246 0ustar00buildbuild00000000000000/* * 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. */ module thrift.util.hashset; import std.algorithm : joiner, map; import std.conv : to; import std.traits : isImplicitlyConvertible, ParameterTypeTuple; import std.range : ElementType, isInputRange; struct Void {} /** * A quickly hacked together hash set implementation backed by built-in * associative arrays to have something to compile Thrift's set<> to until * std.container gains something suitable. */ // Note: The funky pointer casts (i.e. *(cast(immutable(E)*)&e) instead of // just cast(immutable(E))e) are a workaround for LDC 2 compatibility. final class HashSet(E) { /// this() {} /// this(E[] elems...) { insert(elems); } /// void insert(Stuff)(Stuff stuff) if (isImplicitlyConvertible!(Stuff, E)) { aa_[*(cast(immutable(E)*)&stuff)] = Void.init; } /// void insert(Stuff)(Stuff stuff) if ( isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, E) ) { foreach (e; stuff) { aa_[*(cast(immutable(E)*)&e)] = Void.init; } } /// void opOpAssign(string op : "~", Stuff)(Stuff stuff) { insert(stuff); } /// void remove(E e) { aa_.remove(*(cast(immutable(E)*)&e)); } alias remove removeKey; /// void removeAll() { aa_ = null; } /// size_t length() @property const { return aa_.length; } /// size_t empty() @property const { return !aa_.length; } /// bool opBinaryRight(string op : "in")(E e) const { return (e in aa_) !is null; } /// auto opSlice() const { // TODO: Implement using AA key range once available in release DMD/druntime // to avoid allocation. return cast(E[])(aa_.keys); } /// override string toString() const { // Only provide toString() if to!string() is available for E (exceptions are // e.g. delegates). static if (is(typeof(to!string(E.init)) : string)) { return "{" ~ to!string(joiner(map!`to!string(a)`(aa_.keys), ", ")) ~ "}"; } else { // Cast to work around Object not being const-correct. return (cast()super).toString(); } } /// override bool opEquals(Object other) const { auto rhs = cast(const(HashSet))other; if (rhs) { return aa_ == rhs.aa_; } // Cast to work around Object not being const-correct. return (cast()super).opEquals(other); } private: Void[immutable(E)] aa_; } /// Ditto auto hashSet(E)(E[] elems...) { return new HashSet!E(elems); } unittest { import std.exception; auto a = hashSet(1, 2, 2, 3); enforce(a.length == 3); enforce(2 in a); enforce(5 !in a); enforce(a.toString().length == 9); a.remove(2); enforce(a.length == 2); enforce(2 !in a); a.removeAll(); enforce(a.empty); enforce(a.toString() == "{}"); void delegate() dg; auto b = hashSet(dg); static assert(__traits(compiles, b.toString())); } thrift-0.23.0/lib/d/src/thrift/util/awaitable.d0000664000175000017500000001301215165535636021525 0ustar00buildbuild00000000000000/* * 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. */ module thrift.util.awaitable; import core.sync.condition; import core.sync.mutex; import core.time : Duration; import std.exception : enforce; import std.socket/+ : Socket, socketPair+/; // DMD @@BUG314@@ import thrift.base; // To avoid DMD @@BUG6395@@. import thrift.internal.algorithm; /** * An event that can occur at some point in the future and which can be * awaited, either by blocking until it occurs, or by registering a callback * delegate. */ interface TAwaitable { /** * Waits until the event occurs. * * Calling wait() for an event that has already occurred is a no-op. */ void wait(); /** * Waits until the event occurs or the specified timeout expires. * * Calling wait() for an event that has already occurred is a no-op. * * Returns: Whether the event was triggered before the timeout expired. */ bool wait(Duration timeout); /** * Registers a callback that is called if the event occurs. * * The delegate will likely be invoked from a different thread, and is * expected not to perform expensive work as it will usually be invoked * synchronously by the notifying thread. The order in which registered * callbacks are invoked is not specified. * * The callback must never throw, but nothrow semantics are difficult to * enforce, so currently exceptions are just swallowed by * TAwaitable implementations. * * If the event has already occurred, the delegate is immediately executed * in the current thread. */ void addCallback(void delegate() dg); /** * Removes a previously added callback. * * Returns: Whether the callback could be found in the list, i.e. whether it * was previously added. */ bool removeCallback(void delegate() dg); } /** * A simple TAwaitable event triggered by just calling a trigger() method. */ class TOneshotEvent : TAwaitable { this() { mutex_ = new Mutex; condition_ = new Condition(mutex_); } override void wait() { synchronized (mutex_) { while (!triggered_) condition_.wait(); } } override bool wait(Duration timeout) { synchronized (mutex_) { if (triggered_) return true; condition_.wait(timeout); return triggered_; } } override void addCallback(void delegate() dg) { mutex_.lock(); scope (failure) mutex_.unlock(); callbacks_ ~= dg; if (triggered_) { mutex_.unlock(); dg(); return; } mutex_.unlock(); } override bool removeCallback(void delegate() dg) { synchronized (mutex_) { auto oldLength = callbacks_.length; callbacks_ = removeEqual(callbacks_, dg); return callbacks_.length < oldLength; } } /** * Triggers the event. * * Any registered event callbacks are executed synchronously before the * function returns. */ void trigger() { synchronized (mutex_) { if (!triggered_) { triggered_ = true; condition_.notifyAll(); foreach (c; callbacks_) c(); } } } private: bool triggered_; Mutex mutex_; Condition condition_; void delegate()[] callbacks_; } /** * Translates TAwaitable events into dummy messages on a socket that can be * used e.g. to wake up from a select() call. */ final class TSocketNotifier { this() { auto socks = socketPair(); foreach (s; socks) s.blocking = false; sendSocket_ = socks[0]; recvSocket_ = socks[1]; } /** * The socket the messages will be sent to. */ Socket socket() @property { return recvSocket_; } /** * Atatches the socket notifier to the specified awaitable, causing it to * write a byte to the notification socket when the awaitable callbacks are * invoked. * * If the event has already been triggered, the dummy byte is written * immediately to the socket. * * A socket notifier can only be attached to a single awaitable at a time. * * Throws: TException if the socket notifier is already attached. */ void attach(TAwaitable awaitable) { enforce(!awaitable_, new TException("Already attached.")); awaitable.addCallback(¬ify); awaitable_ = awaitable; } /** * Detaches the socket notifier from the awaitable it is currently attached * to. * * Throws: TException if the socket notifier is not currently attached. */ void detach() { enforce(awaitable_, new TException("Not attached.")); // Soak up any not currently read notification bytes. ubyte[1] dummy = void; while (recvSocket_.receive(dummy) != Socket.ERROR) {} auto couldRemove = awaitable_.removeCallback(¬ify); assert(couldRemove); awaitable_ = null; } private: void notify() { ubyte[1] zero; sendSocket_.send(zero); } TAwaitable awaitable_; Socket sendSocket_; Socket recvSocket_; } thrift-0.23.0/lib/d/test/0000775000175000017500000000000015170007175015331 5ustar00buildbuild00000000000000thrift-0.23.0/lib/d/test/thrift_test_runner.sh0000775000175000017500000000601515165535636021636 0ustar00buildbuild00000000000000#!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Runs the D ThriftTest client and servers for all combinations of transport, # protocol, SSL-mode and server type. # Pass -k to keep going after failed tests. CUR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" protocols="binary compact json" # TODO: fix and enable http # transports="buffered framed raw http" transports="buffered framed raw" servers="simple taskpool threaded" framed_only_servers="nonblocking pooledNonblocking" # Don't leave any server instances behind when interrupted (e.g. by Ctrl+C) # or terminated. trap "kill $(jobs -p) 2>/dev/null" INT TERM echo "THRIFT-4905 & THRIFT-5608: SSL tests are disabled. Fix them." for protocol in $protocols; do # TODO: fix and enable ssl # for ssl in "" " --ssl"; do for ssl in ""; do for transport in $transports; do for server in $servers $framed_only_servers; do case $framed_only_servers in *$server*) if [ $transport != "framed" ] || [ $ssl != "" ]; then continue; fi;; esac args="--transport=$transport --protocol=$protocol$ssl" ${CUR}/thrift_test_server $args --server-type=$server > /dev/null & server_pid=$! # Give the server some time to get up and check if it runs (yes, this # is a huge kludge, should add a connect timeout to test client). client_rc=-1 if [ "$server" = "taskpool" ]; then sleep 0.5 else sleep 0.02 fi kill -0 $server_pid 2>/dev/null if [ $? -eq 0 ]; then ${CUR}/thrift_test_client $args --numTests=10 > /dev/null client_rc=$? # Temporarily redirect stderr to null to avoid job control messages, # restore it afterwards. exec 3>&2 exec 2>/dev/null kill $server_pid exec 3>&2 fi # Get the server exit code (wait should immediately return). wait $server_pid server_rc=$? if [ $client_rc -ne 0 -o $server_rc -eq 1 ]; then echo -e "\nTests failed for: $args --server-type=$server" failed="true" if [ "$1" != "-k" ]; then exit 1 fi else echo -n "." fi done done done done echo if [ -z "$failed" ]; then echo "All tests passed." fi thrift-0.23.0/lib/d/test/async_test_runner.sh0000775000175000017500000000221715165535636021453 0ustar00buildbuild00000000000000#!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # CUR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Runs the async test in both SSL and non-SSL mode. ${CUR}/async_test > /dev/null || exit 1 echo "Non-SSL tests done." # THRIFT-4905: disabled the following test as it deadlocks / hangs # ${CUR}/async_test --ssl > /dev/null || exit 1 # echo "SSL tests done." echo "THRIFT-4905: SSL tests are disabled. Fix them." thrift-0.23.0/lib/d/test/serialization_benchmark.d0000664000175000017500000000355115165535636022405 0ustar00buildbuild00000000000000/** * An implementation of the mini serialization benchmark also available for * C++ and Java. * * For meaningful results, you might want to make sure that * the Thrift library is compiled with release build flags, * e.g. by including the source files with the build instead * of linking libthriftd: * dmd -w -O -release -inline -I../src -Igen-d -ofserialization_benchmark \ $(find ../src/thrift -name '*.d' -not -name index.d) \ gen-d/DebugProtoTest_types.d serialization_benchmark.d */ module serialization_benchmark; import std.datetime.stopwatch : AutoStart, StopWatch; import std.math : PI; import std.stdio; import thrift.protocol.binary; import thrift.transport.memory; import thrift.transport.range; import DebugProtoTest_types; void main() { auto buf = new TMemoryBuffer; enum ITERATIONS = 10_000_000; { auto ooe = OneOfEach(); ooe.im_true = true; ooe.im_false = false; ooe.a_bite = 0x7f; ooe.integer16 = 27_000; ooe.integer32 = 1 << 24; ooe.integer64 = 6_000_000_000; ooe.double_precision = PI; ooe.some_characters = "JSON THIS! \"\1"; ooe.zomg_unicode = "\xd7\n\a\t"; ooe.base64 = "\1\2\3\255"; auto prot = tBinaryProtocol(buf); auto sw = StopWatch(AutoStart.yes); foreach (i; 0 .. ITERATIONS) { buf.reset(120); ooe.write(prot); } sw.stop(); auto msecs = sw.peek().total!"msecs"; writefln("Write: %s ms (%s kHz)", msecs, ITERATIONS / msecs); } auto data = buf.getContents().dup; { auto readBuf = tInputRangeTransport(data); auto prot = tBinaryProtocol(readBuf); auto ooe = OneOfEach(); auto sw = StopWatch(AutoStart.yes); foreach (i; 0 .. ITERATIONS) { readBuf.reset(data); ooe.read(prot); } sw.stop(); auto msecs = sw.peek().total!"msecs"; writefln(" Read: %s ms (%s kHz)", msecs, ITERATIONS / msecs); } } thrift-0.23.0/lib/d/test/transport_test.d0000664000175000017500000005412015165535636020607 0ustar00buildbuild00000000000000/* * 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. */ /** * Exercises various transports, combined with the buffered/framed wrappers. * * Originally ported from the C++ version, with Windows support code added. */ module transport_test; import core.atomic; import core.time : Duration; import core.thread : Thread; import std.conv : to; import std.datetime; import std.exception : enforce; static import std.file; import std.getopt; import std.random : rndGen, uniform, unpredictableSeed; import std.socket; import std.stdio; import std.string; import std.typetuple; import thrift.transport.base; import thrift.transport.buffered; import thrift.transport.framed; import thrift.transport.file; import thrift.transport.http; import thrift.transport.memory; import thrift.transport.socket; import thrift.transport.zlib; /* * Size generation helpers – used to be able to run the same testing code * with both constant and random total/chunk sizes. */ interface SizeGenerator { size_t nextSize(); string toString(); } class ConstantSizeGenerator : SizeGenerator { this(size_t value) { value_ = value; } override size_t nextSize() { return value_; } override string toString() const { return to!string(value_); } private: size_t value_; } class RandomSizeGenerator : SizeGenerator { this(size_t min, size_t max) { min_ = min; max_ = max; } override size_t nextSize() { return uniform!"[]"(min_, max_); } override string toString() const { return format("rand(%s, %s)", min_, max_); } size_t min() const @property { return min_; } size_t max() const @property { return max_; } private: size_t min_; size_t max_; } /* * Classes to set up coupled transports */ /** * Helper class to represent a coupled pair of transports. * * Data written to the output transport can be read from the input transport. * * This is used as the base class for the various coupled transport * implementations. It shouldn't be used directly. */ class CoupledTransports(Transport) if (isTTransport!Transport) { Transport input; Transport output; } template isCoupledTransports(T) { static if (is(T _ : CoupledTransports!U, U)) { enum isCoupledTransports = true; } else { enum isCoupledTransports = false; } } /** * Helper template class for creating coupled transports that wrap * another transport. */ class CoupledWrapperTransports(WrapperTransport, InnerCoupledTransports) if ( isTTransport!WrapperTransport && isCoupledTransports!InnerCoupledTransports ) : CoupledTransports!WrapperTransport { this() { inner_ = new InnerCoupledTransports(); if (inner_.input) { input = new WrapperTransport(inner_.input); } if (inner_.output) { output = new WrapperTransport(inner_.output); } } ~this() { destroy(inner_); } private: InnerCoupledTransports inner_; } import thrift.internal.codegen : PApply; alias PApply!(CoupledWrapperTransports, TBufferedTransport) CoupledBufferedTransports; alias PApply!(CoupledWrapperTransports, TFramedTransport) CoupledFramedTransports; alias PApply!(CoupledWrapperTransports, TZlibTransport) CoupledZlibTransports; /** * Coupled TMemoryBuffers. */ class CoupledMemoryBuffers : CoupledTransports!TMemoryBuffer { this() { buf = new TMemoryBuffer; input = buf; output = buf; } TMemoryBuffer buf; } /** * Coupled TSockets. */ class CoupledSocketTransports : CoupledTransports!TSocket { this() { auto sockets = socketPair(); input = new TSocket(sockets[0]); output = new TSocket(sockets[1]); } ~this() { input.close(); output.close(); } } /** * Coupled TFileTransports */ class CoupledFileTransports : CoupledTransports!TTransport { this() { // We actually need the file name of the temp file here, so we can't just // use the usual tempfile facilities. do { fileName_ = tmpDir ~ "/thrift.transport_test." ~ to!string(rndGen().front); rndGen().popFront(); } while (std.file.exists(fileName_)); writefln("Using temp file: %s", fileName_); auto writer = new TFileWriterTransport(fileName_); writer.open(); output = writer; // Wait until the file has been created. writer.flush(); auto reader = new TFileReaderTransport(fileName_); reader.open(); reader.readTimeout(dur!"msecs"(-1)); input = reader; } ~this() { input.close(); output.close(); std.file.remove(fileName_); } static string tmpDir; private: string fileName_; } /* * Test functions */ /** * Test interleaved write and read calls. * * Generates a buffer totalSize bytes long, then writes it to the transport, * and verifies the written data can be read back correctly. * * Mode of operation: * - call wChunkGenerator to figure out how large of a chunk to write * - call wSizeGenerator to get the size for individual write() calls, * and do this repeatedly until the entire chunk is written. * - call rChunkGenerator to figure out how large of a chunk to read * - call rSizeGenerator to get the size for individual read() calls, * and do this repeatedly until the entire chunk is read. * - repeat until the full buffer is written and read back, * then compare the data read back against the original buffer * * * - If any of the size generators return 0, this means to use the maximum * possible size. * * - If maxOutstanding is non-zero, write chunk sizes will be chosen such that * there are never more than maxOutstanding bytes waiting to be read back. */ void testReadWrite(CoupledTransports)( size_t totalSize, SizeGenerator wSizeGenerator, SizeGenerator rSizeGenerator, SizeGenerator wChunkGenerator, SizeGenerator rChunkGenerator, size_t maxOutstanding ) if ( isCoupledTransports!CoupledTransports ) { scope transports = new CoupledTransports; assert(transports.input); assert(transports.output); auto wbuf = new ubyte[totalSize]; auto rbuf = new ubyte[totalSize]; // Store some data in wbuf. foreach (i, ref b; wbuf) { b = i & 0xff; } size_t totalWritten; size_t totalRead; while (totalRead < totalSize) { // Determine how large a chunk of data to write. auto wChunkSize = wChunkGenerator.nextSize(); if (wChunkSize == 0 || wChunkSize > totalSize - totalWritten) { wChunkSize = totalSize - totalWritten; } // Make sure (totalWritten - totalRead) + wChunkSize is less than // maxOutstanding. if (maxOutstanding > 0 && wChunkSize > maxOutstanding - (totalWritten - totalRead)) { wChunkSize = maxOutstanding - (totalWritten - totalRead); } // Write the chunk. size_t chunkWritten = 0; while (chunkWritten < wChunkSize) { auto writeSize = wSizeGenerator.nextSize(); if (writeSize == 0 || writeSize > wChunkSize - chunkWritten) { writeSize = wChunkSize - chunkWritten; } transports.output.write(wbuf[totalWritten .. totalWritten + writeSize]); chunkWritten += writeSize; totalWritten += writeSize; } // Flush the data, so it will be available in the read transport // Don't flush if wChunkSize is 0. (This should only happen if // totalWritten == totalSize already, and we're only reading now.) if (wChunkSize > 0) { transports.output.flush(); } // Determine how large a chunk of data to read back. auto rChunkSize = rChunkGenerator.nextSize(); if (rChunkSize == 0 || rChunkSize > totalWritten - totalRead) { rChunkSize = totalWritten - totalRead; } // Read the chunk. size_t chunkRead; while (chunkRead < rChunkSize) { auto readSize = rSizeGenerator.nextSize(); if (readSize == 0 || readSize > rChunkSize - chunkRead) { readSize = rChunkSize - chunkRead; } size_t bytesRead; try { bytesRead = transports.input.read( rbuf[totalRead .. totalRead + readSize]); } catch (TTransportException e) { throw new Exception(format(`read(pos = %s, size = %s) threw ` ~ `exception "%s"; written so far: %s/%s bytes`, totalRead, readSize, e.msg, totalWritten, totalSize)); } enforce(bytesRead > 0, format(`read(pos = %s, size = %s) returned %s; ` ~ `written so far: %s/%s bytes`, totalRead, readSize, bytesRead, totalWritten, totalSize)); chunkRead += bytesRead; totalRead += bytesRead; } } // make sure the data read back is identical to the data written if (rbuf != wbuf) { stderr.writefln("%s vs. %s", wbuf[$ - 4 .. $], rbuf[$ - 4 .. $]); stderr.writefln("rbuf: %s vs. wbuf: %s", rbuf.length, wbuf.length); } enforce(rbuf == wbuf); } void testReadPartAvailable(CoupledTransports)() if ( isCoupledTransports!CoupledTransports ) { scope transports = new CoupledTransports; assert(transports.input); assert(transports.output); ubyte[10] writeBuf = 'a'; ubyte[10] readBuf; // Attemping to read 10 bytes when only 9 are available should return 9 // immediately. transports.output.write(writeBuf[0 .. 9]); transports.output.flush(); auto t = Trigger(dur!"seconds"(3), transports.output, 1); auto bytesRead = transports.input.read(readBuf); enforce(t.fired == 0); enforce(bytesRead == 9); } void testReadPartialMidframe(CoupledTransports)() if ( isCoupledTransports!CoupledTransports ) { scope transports = new CoupledTransports; assert(transports.input); assert(transports.output); ubyte[13] writeBuf = 'a'; ubyte[14] readBuf; // Attempt to read 10 bytes, when only 9 are available, but after we have // already read part of the data that is available. This exercises a // different code path for several of the transports. // // For transports that add their own framing (e.g., TFramedTransport and // TFileTransport), the two flush calls break up the data in to a 10 byte // frame and a 3 byte frame. The first read then puts us partway through the // first frame, and then we attempt to read past the end of that frame, and // through the next frame, too. // // For buffered transports that perform read-ahead (e.g., // TBufferedTransport), the read-ahead will most likely see all 13 bytes // written on the first read. The next read will then attempt to read past // the end of the read-ahead buffer. // // Flush 10 bytes, then 3 bytes. This creates 2 separate frames for // transports that track framing internally. transports.output.write(writeBuf[0 .. 10]); transports.output.flush(); transports.output.write(writeBuf[10 .. 13]); transports.output.flush(); // Now read 4 bytes, so that we are partway through the written data. auto bytesRead = transports.input.read(readBuf[0 .. 4]); enforce(bytesRead == 4); // Now attempt to read 10 bytes. Only 9 more are available. // // We should be able to get all 9 bytes, but it might take multiple read // calls, since it is valid for read() to return fewer bytes than requested. // (Most transports do immediately return 9 bytes, but the framing transports // tend to only return to the end of the current frame, which is 6 bytes in // this case.) size_t totalRead = 0; while (totalRead < 9) { auto t = Trigger(dur!"seconds"(3), transports.output, 1); bytesRead = transports.input.read(readBuf[4 + totalRead .. 14]); enforce(t.fired == 0); enforce(bytesRead > 0); totalRead += bytesRead; enforce(totalRead <= 9); } enforce(totalRead == 9); } void testBorrowPartAvailable(CoupledTransports)() if ( isCoupledTransports!CoupledTransports ) { scope transports = new CoupledTransports; assert(transports.input); assert(transports.output); ubyte[9] writeBuf = 'a'; ubyte[10] readBuf; // Attemping to borrow 10 bytes when only 9 are available should return NULL // immediately. transports.output.write(writeBuf); transports.output.flush(); auto t = Trigger(dur!"seconds"(3), transports.output, 1); auto borrowLen = readBuf.length; auto borrowedBuf = transports.input.borrow(readBuf.ptr, borrowLen); enforce(t.fired == 0); enforce(borrowedBuf is null); } void testReadNoneAvailable(CoupledTransports)() if ( isCoupledTransports!CoupledTransports ) { scope transports = new CoupledTransports; assert(transports.input); assert(transports.output); // Attempting to read when no data is available should either block until // some data is available, or fail immediately. (e.g., TSocket blocks, // TMemoryBuffer just fails.) // // If the transport blocks, it should succeed once some data is available, // even if less than the amount requested becomes available. ubyte[10] readBuf; auto t = Trigger(dur!"seconds"(1), transports.output, 2); t.add(dur!"seconds"(1), transports.output, 8); auto bytesRead = transports.input.read(readBuf); if (bytesRead == 0) { enforce(t.fired == 0); } else { enforce(t.fired == 1); enforce(bytesRead == 2); } } void testBorrowNoneAvailable(CoupledTransports)() if ( isCoupledTransports!CoupledTransports ) { scope transports = new CoupledTransports; assert(transports.input); assert(transports.output); ubyte[16] writeBuf = 'a'; // Attempting to borrow when no data is available should fail immediately auto t = Trigger(dur!"seconds"(1), transports.output, 10); auto borrowLen = 10; auto borrowedBuf = transports.input.borrow(null, borrowLen); enforce(borrowedBuf is null); enforce(t.fired == 0); } void doRwTest(CoupledTransports)( size_t totalSize, SizeGenerator wSizeGen, SizeGenerator rSizeGen, SizeGenerator wChunkSizeGen = new ConstantSizeGenerator(0), SizeGenerator rChunkSizeGen = new ConstantSizeGenerator(0), size_t maxOutstanding = 0 ) if ( isCoupledTransports!CoupledTransports ) { totalSize = cast(size_t)(totalSize * g_sizeMultiplier); scope(failure) { writefln("Test failed for %s: testReadWrite(%s, %s, %s, %s, %s, %s)", CoupledTransports.stringof, totalSize, wSizeGen, rSizeGen, wChunkSizeGen, rChunkSizeGen, maxOutstanding); } testReadWrite!CoupledTransports(totalSize, wSizeGen, rSizeGen, wChunkSizeGen, rChunkSizeGen, maxOutstanding); } void doBlockingTest(CoupledTransports)() if ( isCoupledTransports!CoupledTransports ) { void writeFailure(string name) { writefln("Test failed for %s: %s()", CoupledTransports.stringof, name); } { scope(failure) writeFailure("testReadPartAvailable"); testReadPartAvailable!CoupledTransports(); } { scope(failure) writeFailure("testReadPartialMidframe"); testReadPartialMidframe!CoupledTransports(); } { scope(failure) writeFailure("testReadNoneAvaliable"); testReadNoneAvailable!CoupledTransports(); } { scope(failure) writeFailure("testBorrowPartAvailable"); testBorrowPartAvailable!CoupledTransports(); } { scope(failure) writeFailure("testBorrowNoneAvailable"); testBorrowNoneAvailable!CoupledTransports(); } } SizeGenerator getGenerator(T)(T t) { static if (is(T : SizeGenerator)) { return t; } else { return new ConstantSizeGenerator(t); } } template WrappedTransports(T) if (isCoupledTransports!T) { alias TypeTuple!( T, CoupledBufferedTransports!T, CoupledFramedTransports!T, CoupledZlibTransports!T ) WrappedTransports; } void testRw(C, R, S)( size_t totalSize, R wSize, S rSize ) if ( isCoupledTransports!C && is(typeof(getGenerator(wSize))) && is(typeof(getGenerator(rSize))) ) { testRw!C(totalSize, wSize, rSize, 0, 0, 0); } void testRw(C, R, S, T, U)( size_t totalSize, R wSize, S rSize, T wChunkSize, U rChunkSize, size_t maxOutstanding = 0 ) if ( isCoupledTransports!C && is(typeof(getGenerator(wSize))) && is(typeof(getGenerator(rSize))) && is(typeof(getGenerator(wChunkSize))) && is(typeof(getGenerator(rChunkSize))) ) { foreach (T; WrappedTransports!C) { doRwTest!T( totalSize, getGenerator(wSize), getGenerator(rSize), getGenerator(wChunkSize), getGenerator(rChunkSize), maxOutstanding ); } } void testBlocking(C)() if (isCoupledTransports!C) { foreach (T; WrappedTransports!C) { doBlockingTest!T(); } } // A quick hack, for the sake of brevity… float g_sizeMultiplier = 1; version (Posix) { immutable defaultTempDir = "/tmp"; } else version (Windows) { import core.sys.windows.windows; extern(Windows) DWORD GetTempPathA(DWORD nBufferLength, LPTSTR lpBuffer); string defaultTempDir() @property { char[MAX_PATH + 1] dir; enforce(GetTempPathA(dir.length, dir.ptr)); return to!string(dir.ptr)[0 .. $ - 1]; } } else static assert(false); void main(string[] args) { int seed = unpredictableSeed(); string tmpDir = defaultTempDir; getopt(args, "seed", &seed, "size-multiplier", &g_sizeMultiplier, "tmp-dir", &tmpDir); enforce(g_sizeMultiplier >= 0, "Size multiplier must not be negative."); writefln("Using seed: %s", seed); rndGen().seed(seed); CoupledFileTransports.tmpDir = tmpDir; auto rand4k = new RandomSizeGenerator(1, 4096); /* * We do the basically the same set of tests for each transport type, * although we tweak the parameters in some places. */ // TMemoryBuffer tests testRw!CoupledMemoryBuffers(1024 * 1024, 0, 0); testRw!CoupledMemoryBuffers(1024 * 256, rand4k, rand4k); testRw!CoupledMemoryBuffers(1024 * 256, 167, 163); testRw!CoupledMemoryBuffers(1024 * 16, 1, 1); testRw!CoupledMemoryBuffers(1024 * 256, 0, 0, rand4k, rand4k); testRw!CoupledMemoryBuffers(1024 * 256, rand4k, rand4k, rand4k, rand4k); testRw!CoupledMemoryBuffers(1024 * 256, 167, 163, rand4k, rand4k); testRw!CoupledMemoryBuffers(1024 * 16, 1, 1, rand4k, rand4k); testBlocking!CoupledMemoryBuffers(); // TSocket tests enum socketMaxOutstanding = 4096; testRw!CoupledSocketTransports(1024 * 1024, 0, 0, 0, 0, socketMaxOutstanding); testRw!CoupledSocketTransports(1024 * 256, rand4k, rand4k, 0, 0, socketMaxOutstanding); testRw!CoupledSocketTransports(1024 * 256, 167, 163, 0, 0, socketMaxOutstanding); // Doh. Apparently writing to a socket has some additional overhead for // each send() call. If we have more than ~400 outstanding 1-byte write // requests, additional send() calls start blocking. testRw!CoupledSocketTransports(1024 * 16, 1, 1, 0, 0, 250); testRw!CoupledSocketTransports(1024 * 256, 0, 0, rand4k, rand4k, socketMaxOutstanding); testRw!CoupledSocketTransports(1024 * 256, rand4k, rand4k, rand4k, rand4k, socketMaxOutstanding); testRw!CoupledSocketTransports(1024 * 256, 167, 163, rand4k, rand4k, socketMaxOutstanding); testRw!CoupledSocketTransports(1024 * 16, 1, 1, rand4k, rand4k, 250); testBlocking!CoupledSocketTransports(); // File transport tests. // Cannot write more than the frame size at once. enum maxWriteAtOnce = 1024 * 1024 * 16 - 4; testRw!CoupledFileTransports(1024 * 1024, maxWriteAtOnce, 0); testRw!CoupledFileTransports(1024 * 256, rand4k, rand4k); testRw!CoupledFileTransports(1024 * 256, 167, 163); testRw!CoupledFileTransports(1024 * 16, 1, 1); testRw!CoupledFileTransports(1024 * 256, 0, 0, rand4k, rand4k); testRw!CoupledFileTransports(1024 * 256, rand4k, rand4k, rand4k, rand4k); testRw!CoupledFileTransports(1024 * 256, 167, 163, rand4k, rand4k); testRw!CoupledFileTransports(1024 * 16, 1, 1, rand4k, rand4k); testBlocking!CoupledFileTransports(); } /* * Timer handling code for use in tests that check the transport blocking * semantics. * * The implementation has been hacked together in a hurry and wastes a lot of * threads, but speed should not be the concern here. */ struct Trigger { this(Duration timeout, TTransport transport, size_t writeLength) { mutex_ = new Mutex; cancelCondition_ = new Condition(mutex_); info_ = new Info(timeout, transport, writeLength); startThread(); } ~this() { synchronized (mutex_) { info_ = null; cancelCondition_.notifyAll(); } if (thread_) thread_.join(); } @disable this(this) { assert(0); } void add(Duration timeout, TTransport transport, size_t writeLength) { synchronized (mutex_) { auto info = new Info(timeout, transport, writeLength); if (info_) { auto prev = info_; while (prev.next) prev = prev.next; prev.next = info; } else { info_ = info; startThread(); } } } @property short fired() { return atomicLoad(fired_); } private: void timerThread() { // KLUDGE: Make sure the std.concurrency mbox is initialized on the timer // thread to be able to unblock the file transport. import std.concurrency; thisTid; synchronized (mutex_) { while (info_) { auto cancelled = cancelCondition_.wait(info_.timeout); if (cancelled) { info_ = null; break; } atomicOp!"+="(fired_, 1); // Write some data to the transport to unblock it. auto buf = new ubyte[info_.writeLength]; buf[] = 'b'; info_.transport.write(buf); info_.transport.flush(); info_ = info_.next; } } thread_ = null; } void startThread() { thread_ = new Thread(&timerThread); thread_.start(); } struct Info { this(Duration timeout, TTransport transport, size_t writeLength) { this.timeout = timeout; this.transport = transport; this.writeLength = writeLength; } Duration timeout; TTransport transport; size_t writeLength; Info* next; } Info* info_; Thread thread_; shared short fired_; import core.sync.mutex; Mutex mutex_; import core.sync.condition; Condition cancelCondition_; } thrift-0.23.0/lib/d/test/async_test.d0000664000175000017500000003016415165535636017672 0ustar00buildbuild00000000000000/* * 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 enforced by applicable 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. */ module async_test; import core.atomic; import core.sync.condition : Condition; import core.sync.mutex : Mutex; import core.thread : dur, Thread, ThreadGroup; import std.conv : text; import std.datetime; import std.getopt; import std.exception : collectException, enforce; import std.parallelism : TaskPool; import std.stdio; import std.string; import std.variant : Variant; import thrift.base; import thrift.async.base; import thrift.async.libevent; import thrift.async.socket; import thrift.async.ssl; import thrift.codegen.async_client; import thrift.codegen.async_client_pool; import thrift.codegen.base; import thrift.codegen.processor; import thrift.protocol.base; import thrift.protocol.binary; import thrift.server.base; import thrift.server.simple; import thrift.server.transport.socket; import thrift.server.transport.ssl; import thrift.transport.base; import thrift.transport.buffered; import thrift.transport.ssl; import thrift.util.cancellation; version (Posix) { import core.stdc.signal; import core.sys.posix.signal; // Disable SIGPIPE because SSL server will write to broken socket after // client disconnected (see TSSLSocket docs). shared static this() { signal(SIGPIPE, SIG_IGN); } } interface AsyncTest { string echo(string value); string delayedEcho(string value, long milliseconds); void fail(string reason); void delayedFail(string reason, long milliseconds); enum methodMeta = [ TMethodMeta("fail", [], [TExceptionMeta("ate", 1, "AsyncTestException")]), TMethodMeta("delayedFail", [], [TExceptionMeta("ate", 1, "AsyncTestException")]) ]; alias .AsyncTestException AsyncTestException; } class AsyncTestException : TException { string reason; mixin TStructHelpers!(); } void main(string[] args) { ushort port = 9090; ushort managerCount = 2; ushort serversPerManager = 5; ushort threadsPerServer = 10; uint iterations = 10; bool ssl; bool trace; getopt(args, "iterations", &iterations, "managers", &managerCount, "port", &port, "servers-per-manager", &serversPerManager, "ssl", &ssl, "threads-per-server", &threadsPerServer, "trace", &trace, ); TTransportFactory clientTransportFactory; TSSLContext serverSSLContext; if (ssl) { auto clientSSLContext = new TSSLContext(); with (clientSSLContext) { authenticate = true; ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"; loadTrustedCertificates("../../../test/keys/CA.pem"); } clientTransportFactory = new TAsyncSSLSocketFactory(clientSSLContext); serverSSLContext = new TSSLContext(); with (serverSSLContext) { serverSide = true; ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"; loadCertificate("../../../test/keys/server.crt"); loadPrivateKey("../../../test/keys/server.key"); } } else { clientTransportFactory = new TBufferedTransportFactory; } auto serverCancel = new TCancellationOrigin; scope(exit) { writeln("Triggering server shutdown..."); serverCancel.trigger(); writeln("done."); } auto managers = new TLibeventAsyncManager[managerCount]; scope (exit) foreach (ref m; managers) destroy(m); auto clientsThreads = new ThreadGroup; foreach (managerIndex, ref manager; managers) { manager = new TLibeventAsyncManager; foreach (serverIndex; 0 .. serversPerManager) { auto currentPort = cast(ushort) (port + managerIndex * serversPerManager + serverIndex); // Start the server and wait until it is up and running. auto servingMutex = new Mutex; auto servingCondition = new Condition(servingMutex); auto handler = new PreServeNotifyHandler(servingMutex, servingCondition); synchronized (servingMutex) { (new ServerThread!TSimpleServer(currentPort, serverSSLContext, trace, serverCancel, handler)).start(); servingCondition.wait(); } // We only run the timing tests for the first server on each async // manager, so that we don't get spurious timing errors becaue of // ordering issues. auto runTimingTests = (serverIndex == 0); auto c = new ClientsThread(manager, currentPort, clientTransportFactory, threadsPerServer, iterations, runTimingTests, trace); clientsThreads.add(c); c.start(); } } clientsThreads.joinAll(); } class AsyncTestHandler : AsyncTest { this(bool trace) { trace_ = trace; } override string echo(string value) { if (trace_) writefln(`echo("%s")`, value); return value; } override string delayedEcho(string value, long milliseconds) { if (trace_) writef(`delayedEcho("%s", %s ms)... `, value, milliseconds); Thread.sleep(dur!"msecs"(milliseconds)); if (trace_) writeln("returning."); return value; } override void fail(string reason) { if (trace_) writefln(`fail("%s")`, reason); auto ate = new AsyncTestException; ate.reason = reason; throw ate; } override void delayedFail(string reason, long milliseconds) { if (trace_) writef(`delayedFail("%s", %s ms)... `, reason, milliseconds); Thread.sleep(dur!"msecs"(milliseconds)); if (trace_) writeln("returning."); auto ate = new AsyncTestException; ate.reason = reason; throw ate; } private: bool trace_; AsyncTestException ate_; } class PreServeNotifyHandler : TServerEventHandler { this(Mutex servingMutex, Condition servingCondition) { servingMutex_ = servingMutex; servingCondition_ = servingCondition; } void preServe() { synchronized (servingMutex_) { servingCondition_.notifyAll(); } } Variant createContext(TProtocol input, TProtocol output) { return Variant.init; } void deleteContext(Variant serverContext, TProtocol input, TProtocol output) {} void preProcess(Variant serverContext, TTransport transport) {} private: Mutex servingMutex_; Condition servingCondition_; } class ServerThread(ServerType) : Thread { this(ushort port, TSSLContext sslContext, bool trace, TCancellation cancellation, TServerEventHandler eventHandler ) { port_ = port; sslContext_ = sslContext; trace_ = trace; cancellation_ = cancellation; eventHandler_ = eventHandler; super(&run); } void run() { TServerSocket serverSocket; if (sslContext_) { serverSocket = new TSSLServerSocket(port_, sslContext_); } else { serverSocket = new TServerSocket(port_); } auto transportFactory = new TBufferedTransportFactory; auto protocolFactory = new TBinaryProtocolFactory!(); auto processor = new TServiceProcessor!AsyncTest(new AsyncTestHandler(trace_)); auto server = new ServerType(processor, serverSocket, transportFactory, protocolFactory); server.eventHandler = eventHandler_; writefln("Starting server on port %s...", port_); server.serve(cancellation_); writefln("Server thread on port %s done.", port_); } private: ushort port_; bool trace_; TCancellation cancellation_; TSSLContext sslContext_; TServerEventHandler eventHandler_; } class ClientsThread : Thread { this(TAsyncSocketManager manager, ushort port, TTransportFactory tf, ushort threads, uint iterations, bool runTimingTests, bool trace ) { manager_ = manager; port_ = port; transportFactory_ = tf; threads_ = threads; iterations_ = iterations; runTimingTests_ = runTimingTests; trace_ = trace; super(&run); } void run() { auto transport = new TAsyncSocket(manager_, "localhost", port_); { auto client = new TAsyncClient!AsyncTest( transport, transportFactory_, new TBinaryProtocolFactory!() ); transport.open(); auto clientThreads = new ThreadGroup; foreach (clientId; 0 .. threads_) { clientThreads.create({ auto c = clientId; return { foreach (i; 0 .. iterations_) { immutable id = text(port_, ":", c, ":", i); { if (trace_) writefln(`Calling echo("%s")... `, id); auto a = client.echo(id); enforce(a == id); if (trace_) writefln(`echo("%s") done.`, id); } { if (trace_) writefln(`Calling fail("%s")... `, id); auto a = cast(AsyncTestException)collectException(client.fail(id).waitGet()); enforce(a && a.reason == id); if (trace_) writefln(`fail("%s") done.`, id); } } }; }()); } clientThreads.joinAll(); transport.close(); } if (runTimingTests_) { auto client = new TAsyncClient!AsyncTest( transport, transportFactory_, new TBinaryProtocolFactory!TBufferedTransport ); // Temporarily redirect error logs to stdout, as SSL errors on the server // side are expected when the client terminates aburptly (as is the case // in the timeout test). auto oldErrorLogSink = g_errorLogSink; g_errorLogSink = g_infoLogSink; scope (exit) g_errorLogSink = oldErrorLogSink; foreach (i; 0 .. iterations_) { transport.open(); immutable id = text(port_, ":", i); { if (trace_) writefln(`Calling delayedEcho("%s", 100 ms)...`, id); auto a = client.delayedEcho(id, 100); enforce(!a.completion.wait(dur!"usecs"(1)), text("wait() succeeded early (", a.get(), ", ", id, ").")); enforce(!a.completion.wait(dur!"usecs"(1)), text("wait() succeeded early (", a.get(), ", ", id, ").")); enforce(a.completion.wait(dur!"msecs"(200)), text("wait() didn't succeed as expected (", id, ").")); enforce(a.get() == id); if (trace_) writefln(`... delayedEcho("%s") done.`, id); } { if (trace_) writefln(`Calling delayedFail("%s", 100 ms)... `, id); auto a = client.delayedFail(id, 100); enforce(!a.completion.wait(dur!"usecs"(1)), text("wait() succeeded early (", id, ", ", collectException(a.get()), ").")); enforce(!a.completion.wait(dur!"usecs"(1)), text("wait() succeeded early (", id, ", ", collectException(a.get()), ").")); enforce(a.completion.wait(dur!"msecs"(200)), text("wait() didn't succeed as expected (", id, ").")); auto e = cast(AsyncTestException)collectException(a.get()); enforce(e && e.reason == id); if (trace_) writefln(`... delayedFail("%s") done.`, id); } { transport.recvTimeout = dur!"msecs"(50); if (trace_) write(`Calling delayedEcho("socketTimeout", 100 ms)... `); auto a = client.delayedEcho("socketTimeout", 100); auto e = cast(TTransportException)collectException(a.waitGet()); enforce(e, text("Operation didn't fail as expected (", id, ").")); enforce(e.type == TTransportException.Type.TIMED_OUT, text("Wrong timeout exception type (", id, "): ", e)); if (trace_) writeln(`timed out as expected.`); // Wait until the server thread reset before the next iteration. Thread.sleep(dur!"msecs"(50)); transport.recvTimeout = dur!"hnsecs"(0); } transport.close(); } } writefln("Clients thread for port %s done.", port_); } TAsyncSocketManager manager_; ushort port_; TTransportFactory transportFactory_; ushort threads_; uint iterations_; bool runTimingTests_; bool trace_; } thrift-0.23.0/lib/d/test/stress_test_server.d0000664000175000017500000000537715165535636021476 0ustar00buildbuild00000000000000/* * 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. */ module stress_test_server; import std.getopt; import std.parallelism : totalCPUs; import std.stdio; import std.typetuple; import thrift.codegen.processor; import thrift.protocol.binary; import thrift.server.base; import thrift.server.transport.socket; import thrift.transport.buffered; import thrift.transport.memory; import thrift.transport.socket; import thrift.util.hashset; import test_utils; import thrift.test.stress.Service; class ServiceHandler : Service { void echoVoid() { return; } byte echoByte(byte arg) { return arg; } int echoI32(int arg) { return arg; } long echoI64(long arg) { return arg; } byte[] echoList(byte[] arg) { return arg; } HashSet!byte echoSet(HashSet!byte arg) { return arg; } byte[byte] echoMap(byte[byte] arg) { return arg; } string echoString(string arg) { if (arg != "hello") { stderr.writefln(`Wrong string received: %s instead of "hello"`, arg); throw new Exception("Wrong string received."); } return arg; } } void main(string[] args) { ushort port = 9091; auto serverType = ServerType.threaded; TransportType transportType; size_t numIOThreads = 1; size_t taskPoolSize = totalCPUs; getopt(args, "port", &port, "server-type", &serverType, "transport-type", &transportType, "task-pool-size", &taskPoolSize, "num-io-threads", &numIOThreads); alias TypeTuple!(TBufferedTransport, TMemoryBuffer) AvailableTransports; auto processor = new TServiceProcessor!(Service, staticMap!(TBinaryProtocol, AvailableTransports))(new ServiceHandler()); auto serverSocket = new TServerSocket(port); auto transportFactory = createTransportFactory(transportType); auto protocolFactory = new TBinaryProtocolFactory!AvailableTransports; auto server = createServer(serverType, taskPoolSize, numIOThreads, processor, serverSocket, transportFactory, protocolFactory); writefln("Starting %s %s StressTest server on port %s...", transportType, serverType, port); server.serve(); writeln("done."); } thrift-0.23.0/lib/d/test/thrift_test_common.d0000664000175000017500000000362215165535636021424 0ustar00buildbuild00000000000000module thrift_test_common; import std.stdio; import thrift.test.ThriftTest_types; enum ProtocolType { binary, compact, json } void writeInsanityReturn(in Insanity[Numberz][UserId] insane) { write("{"); foreach(key1, value1; insane) { writef("%s => {", key1); foreach(key2, value2; value1) { writef("%s => {", key2); write("{"); foreach(key3, value3; value2.userMap) { writef("%s => %s, ", key3, value3); } write("}, "); write("{"); foreach (x; value2.xtructs) { writef("{\"%s\", %s, %s, %s}, ", x.string_thing, x.byte_thing, x.i32_thing, x.i64_thing); } write("}"); write("}, "); } write("}, "); } write("}"); } Insanity[Numberz][UserId] testInsanityReturn; int[int][int] testMapMapReturn; static this() { testInsanityReturn = { Insanity[Numberz][UserId] insane; Xtruct hello; hello.string_thing = "Hello2"; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = 2; Xtruct goodbye; goodbye.string_thing = "Goodbye4"; goodbye.byte_thing = 4; goodbye.i32_thing = 4; goodbye.i64_thing = 4; Insanity crazy; crazy.userMap[Numberz.EIGHT] = 8; crazy.xtructs ~= goodbye; Insanity looney; // The C++ TestServer also assigns these to crazy, but that is probably // an oversight. looney.userMap[Numberz.FIVE] = 5; looney.xtructs ~= hello; Insanity[Numberz] first_map; first_map[Numberz.TWO] = crazy; first_map[Numberz.THREE] = crazy; insane[1] = first_map; Insanity[Numberz] second_map; second_map[Numberz.SIX] = looney; insane[2] = second_map; return insane; }(); testMapMapReturn = { int[int] pos; int[int] neg; for (int i = 1; i < 5; i++) { pos[i] = i; neg[-i] = -i; } int[int][int] result; result[4] = pos; result[-4] = neg; return result; }(); } thrift-0.23.0/lib/d/test/thrift_test_server.d0000664000175000017500000002353715165535636021451 0ustar00buildbuild00000000000000/* * 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. */ module thrift_test_server; import core.stdc.errno : errno; import core.stdc.signal : signal, SIGINT, SIG_DFL, SIG_ERR; import core.thread : dur, Thread; import std.algorithm; import std.exception : enforce; import std.getopt; import std.parallelism : totalCPUs; import std.string; import std.stdio; import std.typetuple : TypeTuple, staticMap; import thrift.base; import thrift.codegen.processor; import thrift.protocol.base; import thrift.protocol.binary; import thrift.protocol.compact; import thrift.protocol.json; import thrift.server.base; import thrift.server.transport.socket; import thrift.server.transport.ssl; import thrift.transport.base; import thrift.transport.buffered; import thrift.transport.framed; import thrift.transport.http; import thrift.transport.zlib; import thrift.transport.ssl; import thrift.util.cancellation; import thrift.util.hashset; import test_utils; import thrift_test_common; import thrift.test.ThriftTest_types; import thrift.test.ThriftTest; class TestHandler : ThriftTest { this(bool trace) { trace_ = trace; } override void testVoid() { if (trace_) writeln("testVoid()"); } override string testString(string thing) { if (trace_) writefln("testString(\"%s\")", thing); return thing; } override byte testByte(byte thing) { if (trace_) writefln("testByte(%s)", thing); return thing; } override int testI32(int thing) { if (trace_) writefln("testI32(%s)", thing); return thing; } override long testI64(long thing) { if (trace_) writefln("testI64(%s)", thing); return thing; } override double testDouble(double thing) { if (trace_) writefln("testDouble(%s)", thing); return thing; } override string testBinary(string thing) { if (trace_) writefln("testBinary(\"%s\")", thing); return thing; } override bool testBool(bool thing) { if (trace_) writefln("testBool(\"%s\")", thing); return thing; } override Xtruct testStruct(ref const(Xtruct) thing) { if (trace_) writefln("testStruct({\"%s\", %s, %s, %s})", thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing); return thing; } override Xtruct2 testNest(ref const(Xtruct2) nest) { auto thing = nest.struct_thing; if (trace_) writefln("testNest({%s, {\"%s\", %s, %s, %s}, %s})", nest.byte_thing, thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing, nest.i32_thing); return nest; } override int[int] testMap(int[int] thing) { if (trace_) writefln("testMap({%s})", thing); return thing; } override HashSet!int testSet(HashSet!int thing) { if (trace_) writefln("testSet({%s})", join(map!`to!string(a)`(thing[]), ", ")); return thing; } override int[] testList(int[] thing) { if (trace_) writefln("testList(%s)", thing); return thing; } override Numberz testEnum(Numberz thing) { if (trace_) writefln("testEnum(%s)", thing); return thing; } override UserId testTypedef(UserId thing) { if (trace_) writefln("testTypedef(%s)", thing); return thing; } override string[string] testStringMap(string[string] thing) { if (trace_) writefln("testStringMap(%s)", thing); return thing; } override int[int][int] testMapMap(int hello) { if (trace_) writefln("testMapMap(%s)", hello); return testMapMapReturn; } override Insanity[Numberz][UserId] testInsanity(ref const(Insanity) argument) { if (trace_) writeln("testInsanity()"); Insanity[Numberz][UserId] ret; Insanity[Numberz] m1; Insanity[Numberz] m2; Insanity tmp; tmp = cast(Insanity)argument; m1[Numberz.TWO] = tmp; m1[Numberz.THREE] = tmp; m2[Numberz.SIX] = Insanity(); ret[1] = m1; ret[2] = m2; return ret; } override Xtruct testMulti(byte arg0, int arg1, long arg2, string[short] arg3, Numberz arg4, UserId arg5) { if (trace_) writeln("testMulti()"); return Xtruct("Hello2", arg0, arg1, arg2); } override void testException(string arg) { if (trace_) writefln("testException(%s)", arg); if (arg == "Xception") { auto e = new Xception(); e.errorCode = 1001; e.message = arg; throw e; } else if (arg == "TException") { throw new TException(); } else if (arg == "ApplicationException") { throw new TException(); } } override Xtruct testMultiException(string arg0, string arg1) { if (trace_) writefln("testMultiException(%s, %s)", arg0, arg1); if (arg0 == "Xception") { auto e = new Xception(); e.errorCode = 1001; e.message = "This is an Xception"; throw e; } else if (arg0 == "Xception2") { auto e = new Xception2(); e.errorCode = 2002; e.struct_thing.string_thing = "This is an Xception2"; throw e; } else { return Xtruct(arg1); } } override void testOneway(int sleepFor) { if (trace_) writefln("testOneway(%s): Sleeping...", sleepFor); Thread.sleep(dur!"seconds"(sleepFor)); if (trace_) writefln("testOneway(%s): done sleeping!", sleepFor); } private: bool trace_; } shared(bool) gShutdown = false; nothrow @nogc extern(C) void handleSignal(int sig) { gShutdown = true; } // Runs a thread that waits for shutdown to be // signaled and then triggers cancellation, // causing the server to stop. While we could // use a signalfd for this purpose, we are instead // opting for a busy waiting scheme for maximum // portability since signalfd is a linux thing. class ShutdownThread : Thread { this(TCancellationOrigin cancellation) { cancellation_ = cancellation; super(&run); } private: void run() { while (!gShutdown) { Thread.sleep(dur!("msecs")(25)); } cancellation_.trigger(); } TCancellationOrigin cancellation_; } void main(string[] args) { ushort port = 9090; ServerType serverType; ProtocolType protocolType; size_t numIOThreads = 1; TransportType transportType; bool ssl = false; bool zlib = false; bool trace = true; size_t taskPoolSize = totalCPUs; getopt(args, "port", &port, "protocol", &protocolType, "server-type", &serverType, "ssl", &ssl, "zlib", &zlib, "num-io-threads", &numIOThreads, "task-pool-size", &taskPoolSize, "trace", &trace, "transport", &transportType); if (serverType == ServerType.nonblocking || serverType == ServerType.pooledNonblocking ) { enforce(transportType == TransportType.framed, "Need to use framed transport with non-blocking server."); enforce(!ssl, "The non-blocking server does not support SSL yet."); // Don't wrap the contents into another layer of framing. transportType = TransportType.raw; } version (ThriftTestTemplates) { // Only exercise the specialized template code paths if explicitly enabled // to reduce memory consumption on regular test suite runs – there should // not be much that can go wrong with that specifically anyway. alias TypeTuple!(TBufferedTransport, TFramedTransport, TServerHttpTransport) AvailableTransports; alias TypeTuple!( staticMap!(TBinaryProtocol, AvailableTransports), staticMap!(TCompactProtocol, AvailableTransports) ) AvailableProtocols; } else { alias TypeTuple!() AvailableTransports; alias TypeTuple!() AvailableProtocols; } TProtocolFactory protocolFactory; final switch (protocolType) { case ProtocolType.binary: protocolFactory = new TBinaryProtocolFactory!AvailableTransports; break; case ProtocolType.compact: protocolFactory = new TCompactProtocolFactory!AvailableTransports; break; case ProtocolType.json: protocolFactory = new TJsonProtocolFactory!AvailableTransports; break; } auto processor = new TServiceProcessor!(ThriftTest, AvailableProtocols)( new TestHandler(trace)); TServerSocket serverSocket; if (ssl) { auto sslContext = new TSSLContext(); sslContext.serverSide = true; sslContext.loadCertificate("../../../test/keys/server.crt"); sslContext.loadPrivateKey("../../../test/keys/server.key"); sslContext.ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"; serverSocket = new TSSLServerSocket(port, sslContext); } else { serverSocket = new TServerSocket(port); } auto transportFactory = createTransportFactory(transportType); auto server = createServer(serverType, numIOThreads, taskPoolSize, processor, serverSocket, transportFactory, protocolFactory); // Set up SIGINT signal handling enforce(signal(SIGINT, &handleSignal) != SIG_ERR, "Could not replace the SIGINT signal handler: errno {0}".format(errno())); // Set up a server cancellation trigger auto cancel = new TCancellationOrigin(); // Set up a listener for the shutdown condition - this will // wake up when the signal occurs and trigger cancellation. auto shutdown = new ShutdownThread(cancel); shutdown.start(); // Serve from this thread; the signal will stop the server // and control will return here writefln("Starting %s/%s %s ThriftTest server %son port %s...", protocolType, transportType, serverType, ssl ? "(using SSL) ": "", port); server.serve(cancel); shutdown.join(); signal(SIGINT, SIG_DFL); writeln("done."); } thrift-0.23.0/lib/d/test/Makefile0000644000175000017500000005747415170007175017010 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/d/test/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu am__append_1 = $(DMD_LIBEVENT_FLAGS) ../$(D_EVENT_LIB_NAME) am__append_2 = $(DMD_OPENSSL_FLAGS) ../$(D_SSL_LIB_NAME) subdir = lib/d/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/d/test abs_srcdir = /thrift/src/lib/d/test abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. AUTOMAKE_OPTIONS = serial-tests # Thrift compiler rules debug_proto_gen = $(addprefix gen-d/, DebugProtoTest_types.d) stress_test_gen = $(addprefix gen-d/thrift/test/stress/, Service.d \ StressTest_types.d) thrift_test_gen = $(addprefix gen-d/thrift/test/, SecondService.d \ ThriftTest.d ThriftTest_constants.d ThriftTest_types.d) # The actual test targets. # There just must be some way to reassign a variable without warnings in # Automake... targets__ = async_test client_pool_test serialization_benchmark \ stress_test_server thrift_test_client thrift_test_server transport_test ran_tests__ = client_pool_test \ transport_test \ async_test_runner.sh \ thrift_test_runner.sh libevent_dependent_targets = async_test_client client_pool_test \ stress_test_server thrift_test_server libevent_dependent_ran_tests = client_pool_test async_test_runner.sh thrift_test_runner.sh openssl_dependent_targets = async_test thrift_test_client thrift_test_server openssl_dependent_ran_tests = async_test_runner.sh thrift_test_runner.sh d_test_flags = $(am__append_1) $(am__append_2) -w -wi -O -release \ -inline -I$(top_srcdir)/lib/d/src -Igen-d \ $(top_builddir)/lib/d/$(D_LIB_NAME) #targets_ = $(filter-out $(libevent_dependent_targets), $(targets__)) targets_ = $(targets__) #ran_tests_ = $(filter-out $(libevent_dependent_ran_tests), $(ran_tests__)) ran_tests_ = $(ran_tests__) #targets = $(filter-out $(openssl_dependent_targets), $(targets_)) targets = $(targets_) #ran_tests = $(filter-out $(openssl_dependent_ran_tests), $(ran_tests_)) ran_tests = $(ran_tests_) TESTS = $(ran_tests) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/d/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/d/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-TESTS check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile $(debug_proto_gen): $(top_srcdir)/test/v0.16/DebugProtoTest.thrift $(THRIFT) --gen d -nowarn $< $(stress_test_gen): $(top_srcdir)/test/StressTest.thrift $(THRIFT) --gen d $< $(thrift_test_gen): $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT) --gen d $< distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am async_test client_pool_test transport_test: %: %.d $(DMD) $(d_test_flags) -of$@ $^ serialization_benchmark: %: %.d $(debug_proto_gen) $(DMD) $(d_test_flags) -of$@ $^ stress_test_server: %: %.d test_utils.d $(stress_test_gen) $(DMD) $(d_test_flags) -of$@ $^ thrift_test_client: %: %.d thrift_test_common.d $(thrift_test_gen) $(DMD) $(d_test_flags) -of$@ $^ thrift_test_server: %: %.d thrift_test_common.d test_utils.d $(thrift_test_gen) $(DMD) $(d_test_flags) -of$@ $^ check-local: $(targets) clean-local: $(RM) -rf gen-d $(targets) $(addsuffix .o, $(targets)) # Tests ran as part of make check. async_test_runner.sh: async_test thrift_test_runner.sh: thrift_test_client thrift_test_server precross: $(targets) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/d/test/client_pool_test.d0000664000175000017500000003332515165535636021066 0ustar00buildbuild00000000000000/* * 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. */ module client_pool_test; import core.sync.semaphore : Semaphore; import core.time : Duration, dur; import core.thread : Thread; import std.algorithm; import std.array; import std.conv; import std.exception; import std.getopt; import std.range; import std.stdio; import std.typecons; import std.variant : Variant; import thrift.base; import thrift.async.libevent; import thrift.async.socket; import thrift.codegen.base; import thrift.codegen.async_client; import thrift.codegen.async_client_pool; import thrift.codegen.client; import thrift.codegen.client_pool; import thrift.codegen.processor; import thrift.protocol.base; import thrift.protocol.binary; import thrift.server.base; import thrift.server.simple; import thrift.server.transport.socket; import thrift.transport.base; import thrift.transport.buffered; import thrift.transport.socket; import thrift.util.cancellation; import thrift.util.future; // We use this as our RPC-layer exception here to make sure socket/… problems // (that would usually considered to be RPC layer faults) cause the tests to // fail, even though we are testing the RPC exception handling. class TestServiceException : TException { int port; } interface TestService { int getPort(); alias .TestServiceException TestServiceException; enum methodMeta = [TMethodMeta("getPort", [], [TExceptionMeta("a", 1, "TestServiceException")])]; } // Use some derived service, just to check that the pools handle inheritance // correctly. interface ExTestService : TestService { int[] getPortInArray(); enum methodMeta = [TMethodMeta("getPortInArray", [], [TExceptionMeta("a", 1, "TestServiceException")])]; } class ExTestHandler : ExTestService { this(ushort port, Duration delay, bool failing, bool trace) { this.port = port; this.delay = delay; this.failing = failing; this.trace = trace; } override int getPort() { if (trace) { stderr.writefln("getPort() called on %s (delay: %s, failing: %s)", port, delay, failing); } sleep(); failIfEnabled(); return port; } override int[] getPortInArray() { return [getPort()]; } ushort port; Duration delay; bool failing; bool trace; private: void sleep() { if (delay > dur!"hnsecs"(0)) Thread.sleep(delay); } void failIfEnabled() { if (!failing) return; auto e = new TestServiceException; e.port = port; throw e; } } class ServerPreServeHandler : TServerEventHandler { this(Semaphore sem) { sem_ = sem; } override void preServe() { sem_.notify(); } Variant createContext(TProtocol input, TProtocol output) { return Variant.init; } void deleteContext(Variant serverContext, TProtocol input, TProtocol output) {} void preProcess(Variant serverContext, TTransport transport) {} private: Semaphore sem_; } class ServerThread : Thread { this(ExTestHandler handler, ServerPreServeHandler serverHandler, TCancellation cancellation) { super(&run); handler_ = handler; cancellation_ = cancellation; serverHandler_ = serverHandler; } private: void run() { try { auto protocolFactory = new TBinaryProtocolFactory!(); auto processor = new TServiceProcessor!ExTestService(handler_); auto serverTransport = new TServerSocket(handler_.port); serverTransport.recvTimeout = dur!"seconds"(3); auto transportFactory = new TBufferedTransportFactory; auto server = new TSimpleServer(processor, serverTransport, transportFactory, protocolFactory); server.eventHandler = serverHandler_; server.serve(cancellation_); } catch (Exception e) { writefln("Server thread on port %s failed: %s", handler_.port, e); } } ExTestHandler handler_; ServerPreServeHandler serverHandler_; TCancellation cancellation_; } void main(string[] args) { bool trace; ushort port = 9090; getopt(args, "port", &port, "trace", &trace); auto serverCancellation = new TCancellationOrigin; scope (exit) serverCancellation.trigger(); immutable ports = cast(immutable)array(map!"cast(ushort)a"(iota(port, port + 6))); // semaphore that will be incremented whenever each server thread has bound and started listening Semaphore sem = new Semaphore(0); version (none) { // Cannot use this due to multiple DMD @@BUG@@s: // 1. »function D main is a nested function and cannot be accessed from array« // when calling array() on the result of the outer map() – would have to // manually do the eager evaluation/array conversion. // 2. »Zip.opSlice cannot get frame pointer to map« for the delay argument, // can be worked around by calling array() on the map result first. // 3. Even when using the workarounds for the last two points, the DMD-built // executable crashes when building without (sic!) inlining enabled, // the backtrace points into the first delegate literal. auto handlers = array(map!((args){ return new ExTestHandler(args._0, args._1, args._2, trace); })(zip( ports, map!((a){ return dur!`msecs`(a); })([1, 10, 100, 1, 10, 100]), [false, false, false, true, true, true] ))); } else { auto handlers = [ new ExTestHandler(cast(ushort)(port + 0), dur!"msecs"(1), false, trace), new ExTestHandler(cast(ushort)(port + 1), dur!"msecs"(10), false, trace), new ExTestHandler(cast(ushort)(port + 2), dur!"msecs"(100), false, trace), new ExTestHandler(cast(ushort)(port + 3), dur!"msecs"(1), true, trace), new ExTestHandler(cast(ushort)(port + 4), dur!"msecs"(10), true, trace), new ExTestHandler(cast(ushort)(port + 5), dur!"msecs"(100), true, trace) ]; } // Fire up the server threads. foreach (h; handlers) (new ServerThread(h, new ServerPreServeHandler(sem), serverCancellation)).start(); // wait until all the handlers signal that they're ready to serve foreach (h; handlers) (sem.wait(dur!`seconds`(1))); syncClientPoolTest(ports, handlers); asyncClientPoolTest(ports, handlers); asyncFastestClientPoolTest(ports, handlers); asyncAggregatorTest(ports, handlers); } void syncClientPoolTest(const(ushort)[] ports, ExTestHandler[] handlers) { auto clients = array(map!((a){ return cast(TClientBase!ExTestService)tClient!ExTestService( tBinaryProtocol(new TSocket("127.0.0.1", a)) ); })(ports)); scope(exit) foreach (c; clients) c.outputProtocol.transport.close(); // Try the case where the first client succeeds. { enforce(makePool(clients).getPort() == ports[0]); } // Try the case where all clients fail. { auto pool = makePool(clients[3 .. $]); auto e = cast(TCompoundOperationException)collectException(pool.getPort()); enforce(e); enforce(equal(map!"a.port"(cast(TestServiceException[])e.exceptions), ports[3 .. $])); } // Try the case where the first clients fail, but a later one succeeds. { auto pool = makePool(clients[3 .. $] ~ clients[0 .. 3]); enforce(pool.getPortInArray() == [ports[0]]); } // Make sure a client is properly deactivated when it has failed too often. { auto pool = makePool(clients); pool.faultDisableCount = 1; pool.faultDisableDuration = dur!"msecs"(50); handlers[0].failing = true; enforce(pool.getPort() == ports[1]); handlers[0].failing = false; enforce(pool.getPort() == ports[1]); Thread.sleep(dur!"msecs"(50)); enforce(pool.getPort() == ports[0]); } } auto makePool(TClientBase!ExTestService[] clients) { auto p = tClientPool(clients); p.permuteClients = false; p.rpcFaultFilter = (Exception e) { return (cast(TestServiceException)e !is null); }; return p; } void asyncClientPoolTest(const(ushort)[] ports, ExTestHandler[] handlers) { auto manager = new TLibeventAsyncManager; scope (exit) manager.stop(dur!"hnsecs"(0)); auto clients = makeAsyncClients(manager, ports); scope(exit) foreach (c; clients) c.transport.close(); // Try the case where the first client succeeds. { enforce(makeAsyncPool(clients).getPort() == ports[0]); } // Try the case where all clients fail. { auto pool = makeAsyncPool(clients[3 .. $]); auto e = cast(TCompoundOperationException)collectException(pool.getPort().waitGet()); enforce(e); enforce(equal(map!"a.port"(cast(TestServiceException[])e.exceptions), ports[3 .. $])); } // Try the case where the first clients fail, but a later one succeeds. { auto pool = makeAsyncPool(clients[3 .. $] ~ clients[0 .. 3]); enforce(pool.getPortInArray() == [ports[0]]); } // Make sure a client is properly deactivated when it has failed too often. { auto pool = makeAsyncPool(clients); pool.faultDisableCount = 1; pool.faultDisableDuration = dur!"msecs"(50); handlers[0].failing = true; enforce(pool.getPort() == ports[1]); handlers[0].failing = false; enforce(pool.getPort() == ports[1]); Thread.sleep(dur!"msecs"(50)); enforce(pool.getPort() == ports[0]); } } auto makeAsyncPool(TAsyncClientBase!ExTestService[] clients) { auto p = tAsyncClientPool(clients); p.permuteClients = false; p.rpcFaultFilter = (Exception e) { return (cast(TestServiceException)e !is null); }; return p; } auto makeAsyncClients(TLibeventAsyncManager manager, in ushort[] ports) { // DMD @@BUG@@ workaround: Using array on the lazyHandlers map result leads // to »function D main is a nested function and cannot be accessed from array«. // Thus, we manually do the array conversion. auto lazyClients = map!((a){ return new TAsyncClient!ExTestService( new TAsyncSocket(manager, "127.0.0.1", a), new TBufferedTransportFactory, new TBinaryProtocolFactory!(TBufferedTransport) ); })(ports); TAsyncClientBase!ExTestService[] clients; foreach (c; lazyClients) clients ~= c; return clients; } void asyncFastestClientPoolTest(const(ushort)[] ports, ExTestHandler[] handlers) { auto manager = new TLibeventAsyncManager; scope (exit) manager.stop(dur!"hnsecs"(0)); auto clients = makeAsyncClients(manager, ports); scope(exit) foreach (c; clients) c.transport.close(); // Make sure the fastest client wins, even if they are called in some other // order. { auto result = makeAsyncFastestPool(array(retro(clients))).getPort().waitGet(); enforce(result == ports[0]); } // Try the case where all clients fail. { auto pool = makeAsyncFastestPool(clients[3 .. $]); auto e = cast(TCompoundOperationException)collectException(pool.getPort().waitGet()); enforce(e); enforce(equal(map!"a.port"(cast(TestServiceException[])e.exceptions), ports[3 .. $])); } // Try the case where the first clients fail, but a later one succeeds. { auto pool = makeAsyncFastestPool(clients[1 .. $]); enforce(pool.getPortInArray() == [ports[1]]); } } auto makeAsyncFastestPool(TAsyncClientBase!ExTestService[] clients) { auto p = tAsyncFastestClientPool(clients); p.rpcFaultFilter = (Exception e) { return (cast(TestServiceException)e !is null); }; return p; } void asyncAggregatorTest(const(ushort)[] ports, ExTestHandler[] handlers) { auto manager = new TLibeventAsyncManager; scope (exit) manager.stop(dur!"hnsecs"(0)); auto clients = makeAsyncClients(manager, ports); scope(exit) foreach (c; clients) c.transport.close(); auto aggregator = tAsyncAggregator( cast(TAsyncClientBase!ExTestService[])clients); // Test aggregator range interface. { auto range = aggregator.getPort().range(dur!"msecs"(50)); enforce(equal(range, ports[0 .. 2][])); enforce(equal(map!"a.port"(cast(TestServiceException[])range.exceptions), ports[3 .. $ - 1])); enforce(range.completedCount == 4); } // Test default accumulator for scalars. { auto fullResult = aggregator.getPort().accumulate(); enforce(fullResult.waitGet() == ports[0 .. 3]); auto partialResult = aggregator.getPort().accumulate(); Thread.sleep(dur!"msecs"(20)); enforce(partialResult.finishGet() == ports[0 .. 2]); } // Test default accumulator for arrays. { auto fullResult = aggregator.getPortInArray().accumulate(); enforce(fullResult.waitGet() == ports[0 .. 3]); auto partialResult = aggregator.getPortInArray().accumulate(); Thread.sleep(dur!"msecs"(20)); enforce(partialResult.finishGet() == ports[0 .. 2]); } // Test custom accumulator. { auto fullResult = aggregator.getPort().accumulate!(function(int[] results){ return reduce!"a + b"(results); })(); enforce(fullResult.waitGet() == ports[0] + ports[1] + ports[2]); auto partialResult = aggregator.getPort().accumulate!( function(int[] results, Exception[] exceptions) { // Return a tuple of the parameters so we can check them outside of // this function (to verify the values, we need access to »ports«, but // due to DMD @@BUG5710@@, we can't use a delegate literal).f return tuple(results, exceptions); } )(); Thread.sleep(dur!"msecs"(20)); auto resultTuple = partialResult.finishGet(); enforce(resultTuple[0] == ports[0 .. 2]); enforce(equal(map!"a.port"(cast(TestServiceException[])resultTuple[1]), ports[3 .. $ - 1])); } } thrift-0.23.0/lib/d/test/Makefile.in0000644000175000017500000005677515170007167017421 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_D_EVENT_TESTS_TRUE@am__append_1 = $(DMD_LIBEVENT_FLAGS) ../$(D_EVENT_LIB_NAME) @WITH_D_SSL_TESTS_TRUE@am__append_2 = $(DMD_OPENSSL_FLAGS) ../$(D_SSL_LIB_NAME) subdir = lib/d/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = serial-tests # Thrift compiler rules debug_proto_gen = $(addprefix gen-d/, DebugProtoTest_types.d) stress_test_gen = $(addprefix gen-d/thrift/test/stress/, Service.d \ StressTest_types.d) thrift_test_gen = $(addprefix gen-d/thrift/test/, SecondService.d \ ThriftTest.d ThriftTest_constants.d ThriftTest_types.d) # The actual test targets. # There just must be some way to reassign a variable without warnings in # Automake... targets__ = async_test client_pool_test serialization_benchmark \ stress_test_server thrift_test_client thrift_test_server transport_test ran_tests__ = client_pool_test \ transport_test \ async_test_runner.sh \ thrift_test_runner.sh libevent_dependent_targets = async_test_client client_pool_test \ stress_test_server thrift_test_server libevent_dependent_ran_tests = client_pool_test async_test_runner.sh thrift_test_runner.sh openssl_dependent_targets = async_test thrift_test_client thrift_test_server openssl_dependent_ran_tests = async_test_runner.sh thrift_test_runner.sh d_test_flags = $(am__append_1) $(am__append_2) -w -wi -O -release \ -inline -I$(top_srcdir)/lib/d/src -Igen-d \ $(top_builddir)/lib/d/$(D_LIB_NAME) @WITH_D_EVENT_TESTS_FALSE@targets_ = $(filter-out $(libevent_dependent_targets), $(targets__)) @WITH_D_EVENT_TESTS_TRUE@targets_ = $(targets__) @WITH_D_EVENT_TESTS_FALSE@ran_tests_ = $(filter-out $(libevent_dependent_ran_tests), $(ran_tests__)) @WITH_D_EVENT_TESTS_TRUE@ran_tests_ = $(ran_tests__) @WITH_D_SSL_TESTS_FALSE@targets = $(filter-out $(openssl_dependent_targets), $(targets_)) @WITH_D_SSL_TESTS_TRUE@targets = $(targets_) @WITH_D_SSL_TESTS_FALSE@ran_tests = $(filter-out $(openssl_dependent_ran_tests), $(ran_tests_)) @WITH_D_SSL_TESTS_TRUE@ran_tests = $(ran_tests_) TESTS = $(ran_tests) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/d/test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/d/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs style-local: tags TAGS: ctags CTAGS: cscope cscopelist: check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: style: style-am style-am: style-local uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-TESTS check-am check-local clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am style-am style-local \ tags-am uninstall uninstall-am .PRECIOUS: Makefile $(debug_proto_gen): $(top_srcdir)/test/v0.16/DebugProtoTest.thrift $(THRIFT) --gen d -nowarn $< $(stress_test_gen): $(top_srcdir)/test/StressTest.thrift $(THRIFT) --gen d $< $(thrift_test_gen): $(top_srcdir)/test/v0.16/ThriftTest.thrift $(THRIFT) --gen d $< distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am async_test client_pool_test transport_test: %: %.d $(DMD) $(d_test_flags) -of$@ $^ serialization_benchmark: %: %.d $(debug_proto_gen) $(DMD) $(d_test_flags) -of$@ $^ stress_test_server: %: %.d test_utils.d $(stress_test_gen) $(DMD) $(d_test_flags) -of$@ $^ thrift_test_client: %: %.d thrift_test_common.d $(thrift_test_gen) $(DMD) $(d_test_flags) -of$@ $^ thrift_test_server: %: %.d thrift_test_common.d test_utils.d $(thrift_test_gen) $(DMD) $(d_test_flags) -of$@ $^ check-local: $(targets) clean-local: $(RM) -rf gen-d $(targets) $(addsuffix .o, $(targets)) # Tests ran as part of make check. async_test_runner.sh: async_test thrift_test_runner.sh: thrift_test_client thrift_test_server precross: $(targets) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/d/test/Makefile.am0000664000175000017500000000700015165535636017376 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = serial-tests # Thrift compiler rules debug_proto_gen = $(addprefix gen-d/, DebugProtoTest_types.d) $(debug_proto_gen): $(top_srcdir)/test/v0.16/DebugProtoTest.thrift $(THRIFT) --gen d -nowarn $< stress_test_gen = $(addprefix gen-d/thrift/test/stress/, Service.d \ StressTest_types.d) $(stress_test_gen): $(top_srcdir)/test/StressTest.thrift $(THRIFT) --gen d $< thrift_test_gen = $(addprefix gen-d/thrift/test/, SecondService.d \ ThriftTest.d ThriftTest_constants.d ThriftTest_types.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 # Automake... targets__ = async_test client_pool_test serialization_benchmark \ stress_test_server thrift_test_client thrift_test_server transport_test ran_tests__ = client_pool_test \ transport_test \ async_test_runner.sh \ thrift_test_runner.sh libevent_dependent_targets = async_test_client client_pool_test \ stress_test_server thrift_test_server libevent_dependent_ran_tests = client_pool_test async_test_runner.sh thrift_test_runner.sh openssl_dependent_targets = async_test thrift_test_client thrift_test_server openssl_dependent_ran_tests = async_test_runner.sh thrift_test_runner.sh d_test_flags = if WITH_D_EVENT_TESTS d_test_flags += $(DMD_LIBEVENT_FLAGS) ../$(D_EVENT_LIB_NAME) targets_ = $(targets__) ran_tests_ = $(ran_tests__) else targets_ = $(filter-out $(libevent_dependent_targets), $(targets__)) ran_tests_ = $(filter-out $(libevent_dependent_ran_tests), $(ran_tests__)) endif if WITH_D_SSL_TESTS d_test_flags += $(DMD_OPENSSL_FLAGS) ../$(D_SSL_LIB_NAME) targets = $(targets_) ran_tests = $(ran_tests_) else targets = $(filter-out $(openssl_dependent_targets), $(targets_)) ran_tests = $(filter-out $(openssl_dependent_ran_tests), $(ran_tests_)) endif d_test_flags += -w -wi -O -release -inline -I$(top_srcdir)/lib/d/src -Igen-d \ $(top_builddir)/lib/d/$(D_LIB_NAME) async_test client_pool_test transport_test: %: %.d $(DMD) $(d_test_flags) -of$@ $^ serialization_benchmark: %: %.d $(debug_proto_gen) $(DMD) $(d_test_flags) -of$@ $^ stress_test_server: %: %.d test_utils.d $(stress_test_gen) $(DMD) $(d_test_flags) -of$@ $^ thrift_test_client: %: %.d thrift_test_common.d $(thrift_test_gen) $(DMD) $(d_test_flags) -of$@ $^ thrift_test_server: %: %.d thrift_test_common.d test_utils.d $(thrift_test_gen) $(DMD) $(d_test_flags) -of$@ $^ check-local: $(targets) clean-local: $(RM) -rf gen-d $(targets) $(addsuffix .o, $(targets)) # Tests ran as part of make check. async_test_runner.sh: async_test thrift_test_runner.sh: thrift_test_client thrift_test_server TESTS = $(ran_tests) precross: $(targets) thrift-0.23.0/lib/d/test/test_utils.d0000664000175000017500000000615415165535636017717 0ustar00buildbuild00000000000000/* * 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. */ /** * Various helpers used by more than a single test. */ module test_utils; import std.parallelism : TaskPool; import thrift.protocol.base; import thrift.protocol.processor; import thrift.server.base; import thrift.server.nonblocking; import thrift.server.simple; import thrift.server.taskpool; import thrift.server.threaded; import thrift.server.transport.socket; import thrift.transport.base; import thrift.transport.buffered; import thrift.transport.framed; import thrift.transport.http; import thrift.transport.zlib; // This is a likely victim of @@BUG4744@@ when used with command argument // parsing. enum ServerType { simple, nonblocking, pooledNonblocking, taskpool, threaded } TServer createServer(ServerType type, size_t taskPoolSize, size_t numIOThreads, TProcessor processor, TServerSocket serverTransport, TTransportFactory transportFactory, TProtocolFactory protocolFactory) { final switch (type) { case ServerType.simple: return new TSimpleServer(processor, serverTransport, transportFactory, protocolFactory); case ServerType.nonblocking: auto nb = new TNonblockingServer(processor, serverTransport.port, transportFactory, protocolFactory); nb.numIOThreads = numIOThreads; return nb; case ServerType.pooledNonblocking: auto nb = new TNonblockingServer(processor, serverTransport.port, transportFactory, protocolFactory, new TaskPool(taskPoolSize)); nb.numIOThreads = numIOThreads; return nb; case ServerType.taskpool: auto tps = new TTaskPoolServer(processor, serverTransport, transportFactory, protocolFactory); tps.taskPool = new TaskPool(taskPoolSize); return tps; case ServerType.threaded: return new TThreadedServer(processor, serverTransport, transportFactory, protocolFactory); } } enum TransportType { buffered, framed, http, zlib, raw } TTransportFactory createTransportFactory(TransportType type) { final switch (type) { case TransportType.buffered: return new TBufferedTransportFactory; case TransportType.framed: return new TFramedTransportFactory; case TransportType.http: return new TServerHttpTransportFactory; case TransportType.zlib: return new TZlibTransportFactory; case TransportType.raw: return new TTransportFactory; } } thrift-0.23.0/lib/d/test/thrift_test_client.d0000664000175000017500000002701615165535636021415 0ustar00buildbuild00000000000000/* * 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. */ module thrift_test_client; import std.conv; import std.datetime.stopwatch; import std.exception : enforce; import std.getopt; import std.stdio; import std.string; import std.traits; import thrift.base; import thrift.codegen.client; import thrift.protocol.base; import thrift.protocol.binary; import thrift.protocol.compact; import thrift.protocol.json; import thrift.transport.base; import thrift.transport.buffered; import thrift.transport.framed; import thrift.transport.http; import thrift.transport.zlib; import thrift.transport.socket; import thrift.transport.ssl; import thrift.util.hashset; import thrift_test_common; import thrift.test.ThriftTest; import thrift.test.ThriftTest_types; enum TransportType { buffered, framed, http, zlib, raw } TProtocol createProtocol(T)(T trans, ProtocolType type) { final switch (type) { case ProtocolType.binary: return tBinaryProtocol(trans); case ProtocolType.compact: return tCompactProtocol(trans); case ProtocolType.json: return tJsonProtocol(trans); } } void main(string[] args) { string host = "localhost"; ushort port = 9090; uint numTests = 1; bool ssl; ProtocolType protocolType; TransportType transportType; bool zlib; bool trace; getopt(args, "numTests|n", &numTests, "protocol", &protocolType, "ssl", &ssl, "transport", &transportType, "zlib", &zlib, "trace", &trace, "port", &port, "host", (string _, string value) { auto parts = split(value, ":"); if (parts.length > 1) { // IPv6 addresses can contain colons, so take the last part for the // port. host = join(parts[0 .. $ - 1], ":"); port = to!ushort(parts[$ - 1]); } else { host = value; } } ); port = to!ushort(port); TSocket socket; if (ssl) { auto sslContext = new TSSLContext(); sslContext.ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"; sslContext.authenticate = true; sslContext.loadTrustedCertificates("../../../test/keys/CA.pem"); socket = new TSSLSocket(sslContext, host, port); } else { socket = new TSocket(host, port); } TTransport transport; final switch (transportType) { case TransportType.buffered: transport = new TBufferedTransport(socket); break; case TransportType.framed: transport = new TFramedTransport(socket); break; case TransportType.http: transport = new TClientHttpTransport(socket, host, "/service"); break; case TransportType.zlib: transport = new TZlibTransport(socket); break; case TransportType.raw: transport = socket; break; } if (zlib && transportType != TransportType.zlib) { transport = new TZlibTransport(socket); } TProtocol protocol = createProtocol(transport, protocolType); auto client = tClient!ThriftTest(protocol); ulong time_min; ulong time_max; ulong time_tot; StopWatch sw; foreach(test; 0 .. numTests) { sw.start(); protocol.transport.open(); if (trace) writefln("Test #%s, connect %s:%s", test + 1, host, port); if (trace) write("testVoid()"); client.testVoid(); if (trace) writeln(" = void"); if (trace) write("testString(\"Test\")"); string s = client.testString("Test"); if (trace) writefln(" = \"%s\"", s); enforce(s == "Test"); if (trace) write("testByte(1)"); byte u8 = client.testByte(1); if (trace) writefln(" = %s", u8); enforce(u8 == 1); if (trace) write("testI32(-1)"); int i32 = client.testI32(-1); if (trace) writefln(" = %s", i32); enforce(i32 == -1); if (trace) write("testI64(-34359738368)"); long i64 = client.testI64(-34359738368L); if (trace) writefln(" = %s", i64); enforce(i64 == -34359738368L); if (trace) write("testDouble(-5.2098523)"); double dub = client.testDouble(-5.2098523); if (trace) writefln(" = %s", dub); enforce(dub == -5.2098523); // TODO: add testBinary() call Xtruct out1; out1.string_thing = "Zero"; out1.byte_thing = 1; out1.i32_thing = -3; out1.i64_thing = -5; if (trace) writef("testStruct(%s)", out1); auto in1 = client.testStruct(out1); if (trace) writefln(" = %s", in1); enforce(in1 == out1); if (trace) write("testNest({1, {\"Zero\", 1, -3, -5}), 5}"); Xtruct2 out2; out2.byte_thing = 1; out2.struct_thing = out1; out2.i32_thing = 5; auto in2 = client.testNest(out2); in1 = in2.struct_thing; if (trace) writefln(" = {%s, {\"%s\", %s, %s, %s}, %s}", in2.byte_thing, in1.string_thing, in1.byte_thing, in1.i32_thing, in1.i64_thing, in2.i32_thing); enforce(in2 == out2); int[int] mapout; for (int i = 0; i < 5; ++i) { mapout[i] = i - 10; } if (trace) writef("testMap({%s})", mapout); auto mapin = client.testMap(mapout); if (trace) writefln(" = {%s}", mapin); enforce(mapin == mapout); auto setout = new HashSet!int; for (int i = -2; i < 3; ++i) { setout ~= i; } if (trace) writef("testSet(%s)", setout); auto setin = client.testSet(setout); if (trace) writefln(" = %s", setin); enforce(setin == setout); int[] listout; for (int i = -2; i < 3; ++i) { listout ~= i; } if (trace) writef("testList(%s)", listout); auto listin = client.testList(listout); if (trace) writefln(" = %s", listin); enforce(listin == listout); { if (trace) write("testEnum(ONE)"); auto ret = client.testEnum(Numberz.ONE); if (trace) writefln(" = %s", ret); enforce(ret == Numberz.ONE); if (trace) write("testEnum(TWO)"); ret = client.testEnum(Numberz.TWO); if (trace) writefln(" = %s", ret); enforce(ret == Numberz.TWO); if (trace) write("testEnum(THREE)"); ret = client.testEnum(Numberz.THREE); if (trace) writefln(" = %s", ret); enforce(ret == Numberz.THREE); if (trace) write("testEnum(FIVE)"); ret = client.testEnum(Numberz.FIVE); if (trace) writefln(" = %s", ret); enforce(ret == Numberz.FIVE); if (trace) write("testEnum(EIGHT)"); ret = client.testEnum(Numberz.EIGHT); if (trace) writefln(" = %s", ret); enforce(ret == Numberz.EIGHT); } if (trace) write("testTypedef(309858235082523)"); UserId uid = client.testTypedef(309858235082523L); if (trace) writefln(" = %s", uid); enforce(uid == 309858235082523L); if (trace) write("testMapMap(1)"); auto mm = client.testMapMap(1); if (trace) writefln(" = {%s}", mm); // Simply doing == doesn't seem to work for nested AAs. foreach (key, value; mm) { enforce(testMapMapReturn[key] == value); } foreach (key, value; testMapMapReturn) { enforce(mm[key] == value); } Insanity insane; insane.userMap[Numberz.FIVE] = 5000; Xtruct truck; truck.string_thing = "Truck"; truck.byte_thing = 8; truck.i32_thing = 8; truck.i64_thing = 8; insane.xtructs ~= truck; if (trace) write("testInsanity()"); auto whoa = client.testInsanity(insane); if (trace) writefln(" = %s", whoa); // Commented for now, this is cumbersome to write without opEqual getting // called on AA comparison. // enforce(whoa == testInsanityReturn); { try { if (trace) write("client.testException(\"Xception\") =>"); client.testException("Xception"); if (trace) writeln(" void\nFAILURE"); throw new Exception("testException failed."); } catch (Xception e) { if (trace) writefln(" {%s, \"%s\"}", e.errorCode, e.message); } try { if (trace) write("client.testException(\"TException\") =>"); client.testException("Xception"); if (trace) writeln(" void\nFAILURE"); throw new Exception("testException failed."); } catch (TException e) { if (trace) writefln(" {%s}", e.msg); } try { if (trace) write("client.testException(\"success\") =>"); client.testException("success"); if (trace) writeln(" void"); } catch (Exception e) { if (trace) writeln(" exception\nFAILURE"); throw new Exception("testException failed."); } } { try { if (trace) write("client.testMultiException(\"Xception\", \"test 1\") =>"); auto result = client.testMultiException("Xception", "test 1"); if (trace) writeln(" result\nFAILURE"); throw new Exception("testMultiException failed."); } catch (Xception e) { if (trace) writefln(" {%s, \"%s\"}", e.errorCode, e.message); } try { if (trace) write("client.testMultiException(\"Xception2\", \"test 2\") =>"); auto result = client.testMultiException("Xception2", "test 2"); if (trace) writeln(" result\nFAILURE"); throw new Exception("testMultiException failed."); } catch (Xception2 e) { if (trace) writefln(" {%s, {\"%s\"}}", e.errorCode, e.struct_thing.string_thing); } try { if (trace) writef("client.testMultiException(\"success\", \"test 3\") =>"); auto result = client.testMultiException("success", "test 3"); if (trace) writefln(" {{\"%s\"}}", result.string_thing); } catch (Exception e) { if (trace) writeln(" exception\nFAILURE"); throw new Exception("testMultiException failed."); } } // Do not run oneway test when doing multiple iterations, as it blocks the // server for three seconds. if (numTests == 1) { if (trace) writef("client.testOneway(3) =>"); auto onewayWatch = StopWatch(AutoStart.yes); client.testOneway(3); onewayWatch.stop(); if (onewayWatch.peek.total!"msecs" > 200) { if (trace) { writefln(" FAILURE - took %s ms", onewayWatch.peek.total!"usecs" / 1000.0); } throw new Exception("testOneway failed."); } else { if (trace) { writefln(" success - took %s ms", onewayWatch.peek.total!"usecs" / 1000.0); } } // Redo a simple test after the oneway to make sure we aren't "off by // one", which would be the case if the server treated oneway methods // like normal ones. if (trace) write("re-test testI32(-1)"); i32 = client.testI32(-1); if (trace) writefln(" = %s", i32); } // Time metering. sw.stop(); immutable tot = sw.peek.total!"usecs" ; if (trace) writefln("Total time: %s us\n", tot); time_tot += tot; if (time_min == 0 || tot < time_min) { time_min = tot; } if (tot > time_max) { time_max = tot; } protocol.transport.close(); sw.reset(); } writeln("All tests done."); if (numTests > 1) { auto time_avg = time_tot / numTests; writefln("Min time: %s us", time_min); writefln("Max time: %s us", time_max); writefln("Avg time: %s us", time_avg); } } thrift-0.23.0/lib/d/coding_standards.md0000664000175000017500000000010315165535636020210 0ustar00buildbuild00000000000000Please follow [General Coding Standards](/doc/coding_standards.md) thrift-0.23.0/lib/d/README.md0000664000175000017500000000344015165535636015646 0ustar00buildbuild00000000000000Thrift D Software Library ========================= License ------- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Testing ------- D support in Thrift is covered by two sets of tests: first, the unit test blocks contained in the D source files, and second, the more extensive testing applications in the test/ subdirectory, which also make use of the Thrift compiler. Both are built when running "make check", but only the unit tests are immediately run, however – the separate test cases typically run longer or require manual intervention. It might also be prudent to run the independent tests, which typically consist of a server and a client part, against the other language implementations. To build the unit tests on Windows, the easiest way might be to manually create a file containing an empty main() and invoke the compiler by running the following in the src/ directory (PowerShell syntax): dmd -ofunittest -unittest -w $(dir -r -filter '*.d' -name) Async and SSL ------------- Using SSL with async is experimental (always has been) and the unit test "async_test --ssl" hangs. Use at your own risk. thrift-0.23.0/lib/d/Makefile0000644000175000017500000012736115170007175016022 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # lib/d/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # 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. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/thrift pkgincludedir = $(includedir)/thrift pkglibdir = $(libdir)/thrift pkglibexecdir = $(libexecdir)/thrift am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu am__append_1 = test am__append_2 = $(D_EVENT_LIB_NAME) am__append_3 = $(D_SSL_LIB_NAME) am__append_4 = $(DMD_LIBEVENT_FLAGS) am__append_5 = $(DMD_OPENSSL_FLAGS) subdir = lib/d ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(d_asyncdir)" \ "$(DESTDIR)$(d_codegendir)" "$(DESTDIR)$(d_internaldir)" \ "$(DESTDIR)$(d_protocoldir)" "$(DESTDIR)$(d_serverdir)" \ "$(DESTDIR)$(d_servertransportdir)" "$(DESTDIR)$(d_testdir)" \ "$(DESTDIR)$(d_thriftdir)" "$(DESTDIR)$(d_transportdir)" \ "$(DESTDIR)$(d_utildir)" DATA = $(d_async_DATA) $(d_codegen_DATA) $(d_internal_DATA) \ $(d_protocol_DATA) $(d_server_DATA) $(d_servertransport_DATA) \ $(d_test_DATA) $(d_thrift_DATA) $(d_transport_DATA) \ $(d_util_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } DIST_SUBDIRS = . test am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = ${SHELL} '/thrift/src/missing' aclocal-1.16 ALLOCA = AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 1 ANT = /usr/bin/ant ANT_FLAGS = AR = ar AUTOCONF = ${SHELL} '/thrift/src/missing' autoconf AUTOHEADER = ${SHELL} '/thrift/src/missing' autoheader AUTOMAKE = ${SHELL} '/thrift/src/missing' automake-1.16 AWK = mawk BISON = bison BOOST_CHRONO_LDADD = /usr/lib/x86_64-linux-gnu/libboost_chrono.a BOOST_CPPFLAGS = -I/usr/include BOOST_FILESYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_filesystem.a BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu BOOST_LIB_DIR = /usr/lib/x86_64-linux-gnu BOOST_SYSTEM_LDADD = /usr/lib/x86_64-linux-gnu/libboost_system.a BOOST_TEST_LDADD = /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.a BOOST_THREAD_LDADD = /usr/lib/x86_64-linux-gnu/libboost_thread.a BUNDLER = /usr/bin/bundle CARGO = /home/build/.cargo/bin/cargo CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CLASSPATH = CPP = gcc -E CPPFLAGS = CPPSTYLE_CMD = find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \; CSCOPE = cscope CTAGS = ctags CXX = g++ -std=c++11 CXXCPP = g++ -E -std=c++11 CXXDEPMODE = depmode=gcc3 CXXFLAGS = -g -O2 CYGPATH_W = echo DART = /usr/lib/dart/bin/dart DARTPUB = /usr/lib/dart/bin/pub DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DMD = dmd DMD_LIBEVENT_FLAGS = -L-fuse-ld=gold -L-levent DMD_OF_DIRSEP = / DMD_OPENSSL_FLAGS = -L-fuse-ld=gold -L-lssl -L-lcrypto DOTNETCORE = /usr/bin/dotnet DOTNETCORE_VERSION = 10.0.105 DSYMUTIL = DUMPBIN = D_EVENT_LIB_NAME = libthriftd-event.a D_IMPORT_PREFIX = ${prefix}/include/d2 D_LIB_NAME = libthriftd.a D_SSL_LIB_NAME = libthriftd-ssl.a ECHO_C = ECHO_N = -n ECHO_T = EGREP = /usr/bin/grep -E ENABLE_COVERAGE = 2 ERL = /usr/local/lib/otp/bin/erl ERLANG_INSTALL_LIB_DIR = /usr/local/lib/otp/lib ERLANG_INSTALL_LIB_DIR_thrift = ${ERLANG_INSTALL_LIB_DIR}/thrift-0.23.0 ERLANG_LIB_DIR = /usr/local/lib/otp/lib ERLC = /usr/local/lib/otp/bin/erlc ERLCFLAGS = ETAGS = etags EXEEXT = FGREP = /usr/bin/grep -F GCOV_CFLAGS = GCOV_CXXFLAGS = GCOV_LDFLAGS = GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GLIB_LIBS = -lglib-2.0 GO = /usr/local/bin/go GOBJECT_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include GOBJECT_LIBS = -lgobject-2.0 -lglib-2.0 GRADLE = /usr/local/bin/gradle GRADLE_OPTS = GREP = /usr/bin/grep GSETTINGS = /usr/bin/gsettings HAVE_CXX11 = 1 HAXE = /opt/haxe/haxe HAXE_VERSION = 4.2.1+bf9ff69 INSTALL = /usr/bin/install -c INSTALLDIRS = vendor INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s JAVA_PREFIX = /usr/local/lib LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = LEX = flex LEXLIB = LEX_OUTPUT_ROOT = lex.yy LIBEVENT_CPPFLAGS = LIBEVENT_LDFLAGS = LIBEVENT_LIBS = -levent LIBOBJS = LIBS = -lrt -lpthread LIBTOOL = $(SHELL) $(top_builddir)/libtool LIPO = LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = LUA = /usr/bin/lua LUA_EXEC_PREFIX = ${exec_prefix} LUA_INCLUDE = -I/usr/include/lua5.4 LUA_LIB = -llua5.4 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} LUA_SHORT_VERSION = 54 LUA_VERSION = 5.4 MAKEINFO = ${SHELL} '/thrift/src/missing' makeinfo MANIFEST_TOOL = : MAYBE_CL = cl MAYBE_CPP = cpp MAYBE_C_GLIB = c_glib MAYBE_D = d MAYBE_DART = dart MAYBE_ERLANG = erl MAYBE_GO = go MAYBE_JAVA = java MAYBE_KOTLIN = kotlin MAYBE_LUA = lua MAYBE_NETSTD = netstd MAYBE_NODEJS = nodejs MAYBE_NODETS = nodets MAYBE_PERL = perl MAYBE_PHP = php MAYBE_PY3 = py3 MAYBE_PYTHON = py MAYBE_RS = rs MAYBE_RUBY = rb MAYBE_SWIFT = swift MKDIR_P = /usr/bin/mkdir -p NM = /usr/bin/nm -B NMEDIT = NODEJS = /usr/bin/nodejs NODETS = /usr/bin/node NPM = /usr/bin/npm OBJDUMP = objdump OBJEXT = o OPENSSL_INCLUDES = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OTOOL = OTOOL64 = PACKAGE = thrift PACKAGE_BUGREPORT = PACKAGE_NAME = thrift PACKAGE_STRING = thrift 0.23.0 PACKAGE_TARNAME = thrift PACKAGE_URL = PACKAGE_VERSION = 0.23.0 PATH_SEPARATOR = : PERL = /usr/bin/perl PERL_PREFIX = /usr/local PHP = /usr/bin/php PHP_CONFIG = /usr/bin/php-config PHP_CONFIG_PREFIX = /etc/php.d PHP_PREFIX = /usr/lib/php PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PYTHON = /usr/bin/python3 PYTHON3 = /usr/bin/python3 PYTHON_EXEC_PREFIX = ${exec_prefix} PYTHON_PLATFORM = linux PYTHON_PREFIX = ${prefix} PYTHON_VERSION = 3.10 PY_PREFIX = /usr QT5_CFLAGS = -DQT_NETWORK_LIB -DQT_CORE_LIB -I/usr/include/x86_64-linux-gnu/qt5/QtNetwork -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I/usr/include/x86_64-linux-gnu/qt5 QT5_LIBS = -lQt5Network -lQt5Core QT5_MOC = /usr/bin/moc RANLIB = ranlib REBAR = /usr/local/bin/rebar3 RUBY = /usr/bin/ruby RUBY_PREFIX = RUSTC = /home/build/.cargo/bin/rustc SBCL = /usr/local/bin/sbcl SED = /usr/bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SWIFT = /usr/share/swift/usr/bin/swift THRIFT = /thrift/src/compiler/cpp/thrift TRIAL = /usr/local/bin/trial VERSION = 0.23.0 YACC = bison -y YFLAGS = ZLIB_CPPFLAGS = ZLIB_LDFLAGS = ZLIB_LIBS = -lz abs_builddir = /thrift/src/lib/d abs_srcdir = /thrift/src/lib/d abs_top_builddir = /thrift/src abs_top_srcdir = /thrift/src ac_ct_AR = ar ac_ct_CC = gcc ac_ct_CXX = g++ ac_ct_DUMPBIN = am__include = include am__leading_dot = . am__quote = am__tar = tar --hard-dereference --format=ustar -chf - "$$tardir" am__untar = tar -xf - bindir = ${exec_prefix}/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = ${datarootdir} datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} exec_prefix = ${prefix} golang_version = go version go1.25.0 linux/amd64 have_prog_bison = yes host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /thrift/src/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var luadir = ${prefix}/share/lua/5.4 luaexecdir = ${exec_prefix}/lib/lua/5.4 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} pkgluadir = ${luadir}/thrift pkgluaexecdir = ${luaexecdir}/thrift pkgpyexecdir = ${pyexecdir}/thrift pkgpythondir = ${pythondir}/thrift prefix = /usr/local program_transform_name = s,x,x, psdir = ${docdir} pyexecdir = ${PYTHON_EXEC_PREFIX}/lib/python3.10/site-packages pythondir = ${PYTHON_PREFIX}/lib/python3.10/site-packages runstatedir = ${localstatedir}/run rustc_version = rustc 1.83.0 (90b35a623 2024-11-26) sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . subdirs = lib/php/src/ext/thrift_protocol sysconfdir = ${prefix}/etc target_alias = top_build_prefix = ../../ top_builddir = ../.. top_srcdir = ../.. AUTOMAKE_OPTIONS = serial-tests SUBDIRS = . $(am__append_1) # # Enumeration of all the public and private modules. # # We unconditionally install all of them, even if libevent or OpenSSL are # not available, but build the respective libraries only if the Deimos headers # could be found. # d_thriftmodules = $(addprefix thrift/, base) d_thriftdir = $(D_IMPORT_PREFIX)/thrift d_thrift_DATA = $(addprefix src/, $(addsuffix .d, $(d_thriftmodules))) d_asyncmodules = $(addprefix thrift/async/, base libevent socket ssl) d_asyncdir = $(d_thriftdir)/async d_async_DATA = $(addprefix src/, $(addsuffix .d, $(d_asyncmodules))) d_codegenmodules = $(addprefix thrift/codegen/, async_client \ async_client_pool base client client_pool processor) #d_codegenmodules = $(addprefix thrift/codegen/, async_client \ # async_client_pool base client client_pool idlgen processor) d_codegendir = $(d_thriftdir)/codegen d_codegen_DATA = $(addprefix src/, $(addsuffix .d, $(d_codegenmodules))) d_protocolmodules = $(addprefix thrift/protocol/, base binary compact json \ processor) d_protocoldir = $(d_thriftdir)/protocol d_protocol_DATA = $(addprefix src/, $(addsuffix .d, $(d_protocolmodules))) d_servermodules = $(addprefix thrift/server/, base simple nonblocking \ taskpool threaded) d_serverdir = $(d_thriftdir)/server d_server_DATA = $(addprefix src/, $(addsuffix .d, $(d_servermodules))) d_servertransportmodules = $(addprefix thrift/server/transport/, base socket ssl) d_servertransportdir = $(d_thriftdir)/server/transport d_servertransport_DATA = $(addprefix src/, $(addsuffix .d, \ $(d_servertransportmodules))) d_transportmodules = $(addprefix thrift/transport/, base buffered file \ framed http memory piped range socket ssl zlib) d_transportdir = $(d_thriftdir)/transport d_transport_DATA = $(addprefix src/, $(addsuffix .d, $(d_transportmodules))) d_utilmodules = $(addprefix thrift/util/, awaitable cancellation future \ hashset) d_utildir = $(d_thriftdir)/util d_util_DATA = $(addprefix src/, $(addsuffix .d, $(d_utilmodules))) d_internalmodules = $(addprefix thrift/internal/, algorithm codegen ctfe \ endian resource_pool socket ssl ssl_bio traits) d_internaldir = $(d_thriftdir)/internal d_internal_DATA = $(addprefix src/, $(addsuffix .d, $(d_internalmodules))) d_testmodules = $(addprefix thrift/internal/test/, protocol server) d_testdir = $(d_internaldir)/test d_test_DATA = $(addprefix src/, $(addsuffix .d, $(d_testmodules))) d_publicmodules = $(d_thriftmodules) $(d_asyncmodules) \ $(d_codegenmodules) $(d_protocolmodules) $(d_servermodules) \ $(d_servertransportmodules) $(d_transportmodules) $(d_utilmodules) d_publicsources = $(addprefix src/, $(addsuffix .d, $(d_publicmodules))) d_modules = $(d_publicmodules) $(d_internalmodules) $(d_testmodules) # List modules with external dependencies and remove them from the main list d_libevent_dependent_modules = thrift/async/libevent thrift/server/nonblocking d_openssl_dependent_modules = thrift/async/ssl thrift/internal/ssl \ thrift/internal/ssl_bio thrift/transport/ssl thrift/server/transport/ssl d_main_modules = $(filter-out $(d_libevent_dependent_modules) \ $(d_openssl_dependent_modules),$(d_modules)) d_lib_flags = -w -wi -Isrc -lib -version=use_openssl_1_0_x all_targets = $(am__append_2) $(am__append_3) $(D_LIB_NAME) # # Unit tests (built both in debug and release mode). # d_test_flags = -unittest -w -wi -I$(top_srcdir)/lib/d/src \ -version=use_openssl_1_0_x $(am__append_4) $(am__append_5) # There just must be some way to reassign a variable without warnings in # Automake... d_test_modules__ = $(d_modules) #d_test_modules_ = $(filter-out $(d_libevent_dependent_modules), $(d_test_modules__)) d_test_modules_ = $(d_test_modules__) #d_test_modules = $(filter-out $(d_openssl_dependent_modules), $(d_test_modules_)) d_test_modules = $(d_test_modules_) TESTS = $(addprefix unittest/debug/, $(d_test_modules)) \ $(addprefix unittest/release/, $(d_test_modules)) EXTRA_DIST = \ src \ test \ README.md all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/d/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/d/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-d_asyncDATA: $(d_async_DATA) @$(NORMAL_INSTALL) @list='$(d_async_DATA)'; test -n "$(d_asyncdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_asyncdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_asyncdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_asyncdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_asyncdir)" || exit $$?; \ done uninstall-d_asyncDATA: @$(NORMAL_UNINSTALL) @list='$(d_async_DATA)'; test -n "$(d_asyncdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_asyncdir)'; $(am__uninstall_files_from_dir) install-d_codegenDATA: $(d_codegen_DATA) @$(NORMAL_INSTALL) @list='$(d_codegen_DATA)'; test -n "$(d_codegendir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_codegendir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_codegendir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_codegendir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_codegendir)" || exit $$?; \ done uninstall-d_codegenDATA: @$(NORMAL_UNINSTALL) @list='$(d_codegen_DATA)'; test -n "$(d_codegendir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_codegendir)'; $(am__uninstall_files_from_dir) install-d_internalDATA: $(d_internal_DATA) @$(NORMAL_INSTALL) @list='$(d_internal_DATA)'; test -n "$(d_internaldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_internaldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_internaldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_internaldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_internaldir)" || exit $$?; \ done uninstall-d_internalDATA: @$(NORMAL_UNINSTALL) @list='$(d_internal_DATA)'; test -n "$(d_internaldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_internaldir)'; $(am__uninstall_files_from_dir) install-d_protocolDATA: $(d_protocol_DATA) @$(NORMAL_INSTALL) @list='$(d_protocol_DATA)'; test -n "$(d_protocoldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_protocoldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_protocoldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_protocoldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_protocoldir)" || exit $$?; \ done uninstall-d_protocolDATA: @$(NORMAL_UNINSTALL) @list='$(d_protocol_DATA)'; test -n "$(d_protocoldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_protocoldir)'; $(am__uninstall_files_from_dir) install-d_serverDATA: $(d_server_DATA) @$(NORMAL_INSTALL) @list='$(d_server_DATA)'; test -n "$(d_serverdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_serverdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_serverdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_serverdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_serverdir)" || exit $$?; \ done uninstall-d_serverDATA: @$(NORMAL_UNINSTALL) @list='$(d_server_DATA)'; test -n "$(d_serverdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_serverdir)'; $(am__uninstall_files_from_dir) install-d_servertransportDATA: $(d_servertransport_DATA) @$(NORMAL_INSTALL) @list='$(d_servertransport_DATA)'; test -n "$(d_servertransportdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_servertransportdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_servertransportdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_servertransportdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_servertransportdir)" || exit $$?; \ done uninstall-d_servertransportDATA: @$(NORMAL_UNINSTALL) @list='$(d_servertransport_DATA)'; test -n "$(d_servertransportdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_servertransportdir)'; $(am__uninstall_files_from_dir) install-d_testDATA: $(d_test_DATA) @$(NORMAL_INSTALL) @list='$(d_test_DATA)'; test -n "$(d_testdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_testdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_testdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_testdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_testdir)" || exit $$?; \ done uninstall-d_testDATA: @$(NORMAL_UNINSTALL) @list='$(d_test_DATA)'; test -n "$(d_testdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_testdir)'; $(am__uninstall_files_from_dir) install-d_thriftDATA: $(d_thrift_DATA) @$(NORMAL_INSTALL) @list='$(d_thrift_DATA)'; test -n "$(d_thriftdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_thriftdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_thriftdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_thriftdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_thriftdir)" || exit $$?; \ done uninstall-d_thriftDATA: @$(NORMAL_UNINSTALL) @list='$(d_thrift_DATA)'; test -n "$(d_thriftdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_thriftdir)'; $(am__uninstall_files_from_dir) install-d_transportDATA: $(d_transport_DATA) @$(NORMAL_INSTALL) @list='$(d_transport_DATA)'; test -n "$(d_transportdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_transportdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_transportdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_transportdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_transportdir)" || exit $$?; \ done uninstall-d_transportDATA: @$(NORMAL_UNINSTALL) @list='$(d_transport_DATA)'; test -n "$(d_transportdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_transportdir)'; $(am__uninstall_files_from_dir) install-d_utilDATA: $(d_util_DATA) @$(NORMAL_INSTALL) @list='$(d_util_DATA)'; test -n "$(d_utildir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_utildir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_utildir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_utildir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_utildir)" || exit $$?; \ done uninstall-d_utilDATA: @$(NORMAL_UNINSTALL) @list='$(d_util_DATA)'; test -n "$(d_utildir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_utildir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile $(DATA) all-local installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(d_asyncdir)" "$(DESTDIR)$(d_codegendir)" "$(DESTDIR)$(d_internaldir)" "$(DESTDIR)$(d_protocoldir)" "$(DESTDIR)$(d_serverdir)" "$(DESTDIR)$(d_servertransportdir)" "$(DESTDIR)$(d_testdir)" "$(DESTDIR)$(d_thriftdir)" "$(DESTDIR)$(d_transportdir)" "$(DESTDIR)$(d_utildir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-d_asyncDATA install-d_codegenDATA \ install-d_internalDATA install-d_protocolDATA \ install-d_serverDATA install-d_servertransportDATA \ install-d_testDATA install-d_thriftDATA \ install-d_transportDATA install-d_utilDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: uninstall-d_asyncDATA uninstall-d_codegenDATA \ uninstall-d_internalDATA uninstall-d_protocolDATA \ uninstall-d_serverDATA uninstall-d_servertransportDATA \ uninstall-d_testDATA uninstall-d_thriftDATA \ uninstall-d_transportDATA uninstall-d_utilDATA .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-TESTS check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-d_asyncDATA install-d_codegenDATA \ install-d_internalDATA install-d_protocolDATA \ install-d_serverDATA install-d_servertransportDATA \ install-d_testDATA install-d_thriftDATA \ install-d_transportDATA install-d_utilDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am uninstall-d_asyncDATA uninstall-d_codegenDATA \ uninstall-d_internalDATA uninstall-d_protocolDATA \ uninstall-d_serverDATA uninstall-d_servertransportDATA \ uninstall-d_testDATA uninstall-d_thriftDATA \ uninstall-d_transportDATA uninstall-d_utilDATA .PRECIOUS: Makefile # # libevent-dependent modules. # $(D_EVENT_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_libevent_dependent_modules))) $(DMD) -of$(D_EVENT_LIB_NAME) $(d_lib_flags) $^ # # OpenSSL-dependent modules. # $(D_SSL_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_openssl_dependent_modules))) $(DMD) -of$(D_SSL_LIB_NAME) $(d_lib_flags) $^ # # Main library target. # $(D_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_main_modules))) $(DMD) -of$(D_LIB_NAME) $(d_lib_flags) $^ # # Documentation target (requires Dil). # docs: $(d_publicsources) src/thrift/index.d dil ddoc docs -hl --kandil $^ # # Hook custom library targets into the automake all/install targets. # all-local: $(all_targets) install-exec-local: $(INSTALL_PROGRAM) $(all_targets) $(DESTDIR)$(libdir) clean-local: $(RM) -r docs $(RM) $(D_LIB_NAME) $(RM) $(D_EVENT_LIB_NAME) $(RM) $(D_SSL_LIB_NAME) $(RM) -r test/gen-d $(RM) -r unittest unittest/emptymain.d: unittest/.directory @echo 'void main(){}' >$@ unittest/.directory: mkdir -p unittest || exists unittest touch $@ unittest/debug/%: src/%.d $(all_targets) unittest/emptymain.d $(DMD) -g -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^ unittest/release/%: src/%.d $(all_targets) unittest/emptymain.d $(DMD) -O -release -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^ precross: all-local $(MAKE) -C test precross distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/d/Makefile.in0000644000175000017500000012702415170007167016424 0ustar00buildbuild00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # 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. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_TESTS_TRUE@am__append_1 = test @HAVE_DEIMOS_EVENT2_TRUE@am__append_2 = $(D_EVENT_LIB_NAME) @HAVE_DEIMOS_OPENSSL_TRUE@am__append_3 = $(D_SSL_LIB_NAME) @WITH_D_EVENT_TESTS_TRUE@am__append_4 = $(DMD_LIBEVENT_FLAGS) @WITH_D_SSL_TESTS_TRUE@am__append_5 = $(DMD_OPENSSL_FLAGS) subdir = lib/d ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/aclocal/ac_prog_bison.m4 \ $(top_srcdir)/aclocal/ax_boost_base.m4 \ $(top_srcdir)/aclocal/ax_check_openssl.m4 \ $(top_srcdir)/aclocal/ax_compare_version.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/aclocal/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/aclocal/ax_dmd.m4 \ $(top_srcdir)/aclocal/ax_javac_and_java.m4 \ $(top_srcdir)/aclocal/ax_lib_event.m4 \ $(top_srcdir)/aclocal/ax_lib_zlib.m4 \ $(top_srcdir)/aclocal/ax_lua.m4 \ $(top_srcdir)/aclocal/ax_prog_dotnetcore_version.m4 \ $(top_srcdir)/aclocal/ax_prog_haxe_version.m4 \ $(top_srcdir)/aclocal/ax_prog_perl_modules.m4 \ $(top_srcdir)/aclocal/ax_signed_right_shift.m4 \ $(top_srcdir)/aclocal/ax_thrift_internal.m4 \ $(top_srcdir)/aclocal/libtool.m4 \ $(top_srcdir)/aclocal/ltoptions.m4 \ $(top_srcdir)/aclocal/ltsugar.m4 \ $(top_srcdir)/aclocal/ltversion.m4 \ $(top_srcdir)/aclocal/lt~obsolete.m4 \ $(top_srcdir)/aclocal/tar.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/lib/cpp/src/thrift/config.h \ $(top_builddir)/lib/c_glib/src/thrift/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(d_asyncdir)" \ "$(DESTDIR)$(d_codegendir)" "$(DESTDIR)$(d_internaldir)" \ "$(DESTDIR)$(d_protocoldir)" "$(DESTDIR)$(d_serverdir)" \ "$(DESTDIR)$(d_servertransportdir)" "$(DESTDIR)$(d_testdir)" \ "$(DESTDIR)$(d_thriftdir)" "$(DESTDIR)$(d_transportdir)" \ "$(DESTDIR)$(d_utildir)" DATA = $(d_async_DATA) $(d_codegen_DATA) $(d_internal_DATA) \ $(d_protocol_DATA) $(d_server_DATA) $(d_servertransport_DATA) \ $(d_test_DATA) $(d_thrift_DATA) $(d_transport_DATA) \ $(d_util_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__extra_recursive_targets = style-recursive am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } DIST_SUBDIRS = . test am__DIST_COMMON = $(srcdir)/Makefile.in README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ANT = @ANT@ ANT_FLAGS = @ANT_FLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ BOOST_CHRONO_LDADD = @BOOST_CHRONO_LDADD@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_FILESYSTEM_LDADD = @BOOST_FILESYSTEM_LDADD@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_LIB_DIR = @BOOST_LIB_DIR@ BOOST_SYSTEM_LDADD = @BOOST_SYSTEM_LDADD@ BOOST_TEST_LDADD = @BOOST_TEST_LDADD@ BOOST_THREAD_LDADD = @BOOST_THREAD_LDADD@ BUNDLER = @BUNDLER@ CARGO = @CARGO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CLASSPATH = @CLASSPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPPSTYLE_CMD = @CPPSTYLE_CMD@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DART = @DART@ DARTPUB = @DARTPUB@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DMD = @DMD@ DMD_LIBEVENT_FLAGS = @DMD_LIBEVENT_FLAGS@ DMD_OF_DIRSEP = @DMD_OF_DIRSEP@ DMD_OPENSSL_FLAGS = @DMD_OPENSSL_FLAGS@ DOTNETCORE = @DOTNETCORE@ DOTNETCORE_VERSION = @DOTNETCORE_VERSION@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ D_EVENT_LIB_NAME = @D_EVENT_LIB_NAME@ D_IMPORT_PREFIX = @D_IMPORT_PREFIX@ D_LIB_NAME = @D_LIB_NAME@ D_SSL_LIB_NAME = @D_SSL_LIB_NAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENABLE_COVERAGE = @ENABLE_COVERAGE@ ERL = @ERL@ ERLANG_INSTALL_LIB_DIR = @ERLANG_INSTALL_LIB_DIR@ ERLANG_INSTALL_LIB_DIR_thrift = @ERLANG_INSTALL_LIB_DIR_thrift@ ERLANG_LIB_DIR = @ERLANG_LIB_DIR@ ERLC = @ERLC@ ERLCFLAGS = @ERLCFLAGS@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GCOV_CFLAGS = @GCOV_CFLAGS@ GCOV_CXXFLAGS = @GCOV_CXXFLAGS@ GCOV_LDFLAGS = @GCOV_LDFLAGS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GO = @GO@ GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ GOBJECT_LIBS = @GOBJECT_LIBS@ GRADLE = @GRADLE@ GRADLE_OPTS = @GRADLE_OPTS@ GREP = @GREP@ GSETTINGS = @GSETTINGS@ HAVE_CXX11 = @HAVE_CXX11@ HAXE = @HAXE@ HAXE_VERSION = @HAXE_VERSION@ INSTALL = @INSTALL@ INSTALLDIRS = @INSTALLDIRS@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA_PREFIX = @JAVA_PREFIX@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBEVENT_CPPFLAGS = @LIBEVENT_CPPFLAGS@ LIBEVENT_LDFLAGS = @LIBEVENT_LDFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MAYBE_CL = @MAYBE_CL@ MAYBE_CPP = @MAYBE_CPP@ MAYBE_C_GLIB = @MAYBE_C_GLIB@ MAYBE_D = @MAYBE_D@ MAYBE_DART = @MAYBE_DART@ MAYBE_ERLANG = @MAYBE_ERLANG@ MAYBE_GO = @MAYBE_GO@ MAYBE_JAVA = @MAYBE_JAVA@ MAYBE_KOTLIN = @MAYBE_KOTLIN@ MAYBE_LUA = @MAYBE_LUA@ MAYBE_NETSTD = @MAYBE_NETSTD@ MAYBE_NODEJS = @MAYBE_NODEJS@ MAYBE_NODETS = @MAYBE_NODETS@ MAYBE_PERL = @MAYBE_PERL@ MAYBE_PHP = @MAYBE_PHP@ MAYBE_PY3 = @MAYBE_PY3@ MAYBE_PYTHON = @MAYBE_PYTHON@ MAYBE_RS = @MAYBE_RS@ MAYBE_RUBY = @MAYBE_RUBY@ MAYBE_SWIFT = @MAYBE_SWIFT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NODEJS = @NODEJS@ NODETS = @NODETS@ NPM = @NPM@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PERL_PREFIX = @PERL_PREFIX@ PHP = @PHP@ PHP_CONFIG = @PHP_CONFIG@ PHP_CONFIG_PREFIX = @PHP_CONFIG_PREFIX@ PHP_PREFIX = @PHP_PREFIX@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PYTHON = @PYTHON@ PYTHON3 = @PYTHON3@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ PY_PREFIX = @PY_PREFIX@ QT5_CFLAGS = @QT5_CFLAGS@ QT5_LIBS = @QT5_LIBS@ QT5_MOC = @QT5_MOC@ RANLIB = @RANLIB@ REBAR = @REBAR@ RUBY = @RUBY@ RUBY_PREFIX = @RUBY_PREFIX@ RUSTC = @RUSTC@ SBCL = @SBCL@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIFT = @SWIFT@ THRIFT = @THRIFT@ TRIAL = @TRIAL@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ golang_version = @golang_version@ have_prog_bison = @have_prog_bison@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ rustc_version = @rustc_version@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = serial-tests SUBDIRS = . $(am__append_1) # # Enumeration of all the public and private modules. # # We unconditionally install all of them, even if libevent or OpenSSL are # not available, but build the respective libraries only if the Deimos headers # could be found. # d_thriftmodules = $(addprefix thrift/, base) d_thriftdir = $(D_IMPORT_PREFIX)/thrift d_thrift_DATA = $(addprefix src/, $(addsuffix .d, $(d_thriftmodules))) d_asyncmodules = $(addprefix thrift/async/, base libevent socket ssl) d_asyncdir = $(d_thriftdir)/async d_async_DATA = $(addprefix src/, $(addsuffix .d, $(d_asyncmodules))) d_codegenmodules = $(addprefix thrift/codegen/, async_client \ async_client_pool base client client_pool processor) #d_codegenmodules = $(addprefix thrift/codegen/, async_client \ # async_client_pool base client client_pool idlgen processor) d_codegendir = $(d_thriftdir)/codegen d_codegen_DATA = $(addprefix src/, $(addsuffix .d, $(d_codegenmodules))) d_protocolmodules = $(addprefix thrift/protocol/, base binary compact json \ processor) d_protocoldir = $(d_thriftdir)/protocol d_protocol_DATA = $(addprefix src/, $(addsuffix .d, $(d_protocolmodules))) d_servermodules = $(addprefix thrift/server/, base simple nonblocking \ taskpool threaded) d_serverdir = $(d_thriftdir)/server d_server_DATA = $(addprefix src/, $(addsuffix .d, $(d_servermodules))) d_servertransportmodules = $(addprefix thrift/server/transport/, base socket ssl) d_servertransportdir = $(d_thriftdir)/server/transport d_servertransport_DATA = $(addprefix src/, $(addsuffix .d, \ $(d_servertransportmodules))) d_transportmodules = $(addprefix thrift/transport/, base buffered file \ framed http memory piped range socket ssl zlib) d_transportdir = $(d_thriftdir)/transport d_transport_DATA = $(addprefix src/, $(addsuffix .d, $(d_transportmodules))) d_utilmodules = $(addprefix thrift/util/, awaitable cancellation future \ hashset) d_utildir = $(d_thriftdir)/util d_util_DATA = $(addprefix src/, $(addsuffix .d, $(d_utilmodules))) d_internalmodules = $(addprefix thrift/internal/, algorithm codegen ctfe \ endian resource_pool socket ssl ssl_bio traits) d_internaldir = $(d_thriftdir)/internal d_internal_DATA = $(addprefix src/, $(addsuffix .d, $(d_internalmodules))) d_testmodules = $(addprefix thrift/internal/test/, protocol server) d_testdir = $(d_internaldir)/test d_test_DATA = $(addprefix src/, $(addsuffix .d, $(d_testmodules))) d_publicmodules = $(d_thriftmodules) $(d_asyncmodules) \ $(d_codegenmodules) $(d_protocolmodules) $(d_servermodules) \ $(d_servertransportmodules) $(d_transportmodules) $(d_utilmodules) d_publicsources = $(addprefix src/, $(addsuffix .d, $(d_publicmodules))) d_modules = $(d_publicmodules) $(d_internalmodules) $(d_testmodules) # List modules with external dependencies and remove them from the main list d_libevent_dependent_modules = thrift/async/libevent thrift/server/nonblocking d_openssl_dependent_modules = thrift/async/ssl thrift/internal/ssl \ thrift/internal/ssl_bio thrift/transport/ssl thrift/server/transport/ssl d_main_modules = $(filter-out $(d_libevent_dependent_modules) \ $(d_openssl_dependent_modules),$(d_modules)) d_lib_flags = -w -wi -Isrc -lib -version=use_openssl_1_0_x all_targets = $(am__append_2) $(am__append_3) $(D_LIB_NAME) # # Unit tests (built both in debug and release mode). # d_test_flags = -unittest -w -wi -I$(top_srcdir)/lib/d/src \ -version=use_openssl_1_0_x $(am__append_4) $(am__append_5) # There just must be some way to reassign a variable without warnings in # Automake... d_test_modules__ = $(d_modules) @WITH_D_EVENT_TESTS_FALSE@d_test_modules_ = $(filter-out $(d_libevent_dependent_modules), $(d_test_modules__)) @WITH_D_EVENT_TESTS_TRUE@d_test_modules_ = $(d_test_modules__) @WITH_D_SSL_TESTS_FALSE@d_test_modules = $(filter-out $(d_openssl_dependent_modules), $(d_test_modules_)) @WITH_D_SSL_TESTS_TRUE@d_test_modules = $(d_test_modules_) TESTS = $(addprefix unittest/debug/, $(d_test_modules)) \ $(addprefix unittest/release/, $(d_test_modules)) EXTRA_DIST = \ src \ test \ README.md all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/d/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign lib/d/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-d_asyncDATA: $(d_async_DATA) @$(NORMAL_INSTALL) @list='$(d_async_DATA)'; test -n "$(d_asyncdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_asyncdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_asyncdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_asyncdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_asyncdir)" || exit $$?; \ done uninstall-d_asyncDATA: @$(NORMAL_UNINSTALL) @list='$(d_async_DATA)'; test -n "$(d_asyncdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_asyncdir)'; $(am__uninstall_files_from_dir) install-d_codegenDATA: $(d_codegen_DATA) @$(NORMAL_INSTALL) @list='$(d_codegen_DATA)'; test -n "$(d_codegendir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_codegendir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_codegendir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_codegendir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_codegendir)" || exit $$?; \ done uninstall-d_codegenDATA: @$(NORMAL_UNINSTALL) @list='$(d_codegen_DATA)'; test -n "$(d_codegendir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_codegendir)'; $(am__uninstall_files_from_dir) install-d_internalDATA: $(d_internal_DATA) @$(NORMAL_INSTALL) @list='$(d_internal_DATA)'; test -n "$(d_internaldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_internaldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_internaldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_internaldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_internaldir)" || exit $$?; \ done uninstall-d_internalDATA: @$(NORMAL_UNINSTALL) @list='$(d_internal_DATA)'; test -n "$(d_internaldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_internaldir)'; $(am__uninstall_files_from_dir) install-d_protocolDATA: $(d_protocol_DATA) @$(NORMAL_INSTALL) @list='$(d_protocol_DATA)'; test -n "$(d_protocoldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_protocoldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_protocoldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_protocoldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_protocoldir)" || exit $$?; \ done uninstall-d_protocolDATA: @$(NORMAL_UNINSTALL) @list='$(d_protocol_DATA)'; test -n "$(d_protocoldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_protocoldir)'; $(am__uninstall_files_from_dir) install-d_serverDATA: $(d_server_DATA) @$(NORMAL_INSTALL) @list='$(d_server_DATA)'; test -n "$(d_serverdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_serverdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_serverdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_serverdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_serverdir)" || exit $$?; \ done uninstall-d_serverDATA: @$(NORMAL_UNINSTALL) @list='$(d_server_DATA)'; test -n "$(d_serverdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_serverdir)'; $(am__uninstall_files_from_dir) install-d_servertransportDATA: $(d_servertransport_DATA) @$(NORMAL_INSTALL) @list='$(d_servertransport_DATA)'; test -n "$(d_servertransportdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_servertransportdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_servertransportdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_servertransportdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_servertransportdir)" || exit $$?; \ done uninstall-d_servertransportDATA: @$(NORMAL_UNINSTALL) @list='$(d_servertransport_DATA)'; test -n "$(d_servertransportdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_servertransportdir)'; $(am__uninstall_files_from_dir) install-d_testDATA: $(d_test_DATA) @$(NORMAL_INSTALL) @list='$(d_test_DATA)'; test -n "$(d_testdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_testdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_testdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_testdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_testdir)" || exit $$?; \ done uninstall-d_testDATA: @$(NORMAL_UNINSTALL) @list='$(d_test_DATA)'; test -n "$(d_testdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_testdir)'; $(am__uninstall_files_from_dir) install-d_thriftDATA: $(d_thrift_DATA) @$(NORMAL_INSTALL) @list='$(d_thrift_DATA)'; test -n "$(d_thriftdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_thriftdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_thriftdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_thriftdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_thriftdir)" || exit $$?; \ done uninstall-d_thriftDATA: @$(NORMAL_UNINSTALL) @list='$(d_thrift_DATA)'; test -n "$(d_thriftdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_thriftdir)'; $(am__uninstall_files_from_dir) install-d_transportDATA: $(d_transport_DATA) @$(NORMAL_INSTALL) @list='$(d_transport_DATA)'; test -n "$(d_transportdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_transportdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_transportdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_transportdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_transportdir)" || exit $$?; \ done uninstall-d_transportDATA: @$(NORMAL_UNINSTALL) @list='$(d_transport_DATA)'; test -n "$(d_transportdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_transportdir)'; $(am__uninstall_files_from_dir) install-d_utilDATA: $(d_util_DATA) @$(NORMAL_INSTALL) @list='$(d_util_DATA)'; test -n "$(d_utildir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(d_utildir)'"; \ $(MKDIR_P) "$(DESTDIR)$(d_utildir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(d_utildir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(d_utildir)" || exit $$?; \ done uninstall-d_utilDATA: @$(NORMAL_UNINSTALL) @list='$(d_util_DATA)'; test -n "$(d_utildir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(d_utildir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" style-local: ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile $(DATA) all-local installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(d_asyncdir)" "$(DESTDIR)$(d_codegendir)" "$(DESTDIR)$(d_internaldir)" "$(DESTDIR)$(d_protocoldir)" "$(DESTDIR)$(d_serverdir)" "$(DESTDIR)$(d_servertransportdir)" "$(DESTDIR)$(d_testdir)" "$(DESTDIR)$(d_thriftdir)" "$(DESTDIR)$(d_transportdir)" "$(DESTDIR)$(d_utildir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-d_asyncDATA install-d_codegenDATA \ install-d_internalDATA install-d_protocolDATA \ install-d_serverDATA install-d_servertransportDATA \ install-d_testDATA install-d_thriftDATA \ install-d_transportDATA install-d_utilDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-exec-local install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: style: style-recursive style-am: style-local uninstall-am: uninstall-d_asyncDATA uninstall-d_codegenDATA \ uninstall-d_internalDATA uninstall-d_protocolDATA \ uninstall-d_serverDATA uninstall-d_servertransportDATA \ uninstall-d_testDATA uninstall-d_thriftDATA \ uninstall-d_transportDATA uninstall-d_utilDATA .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-TESTS check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags ctags-am distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-d_asyncDATA install-d_codegenDATA \ install-d_internalDATA install-d_protocolDATA \ install-d_serverDATA install-d_servertransportDATA \ install-d_testDATA install-d_thriftDATA \ install-d_transportDATA install-d_utilDATA install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-local install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am style-am style-local tags tags-am uninstall \ uninstall-am uninstall-d_asyncDATA uninstall-d_codegenDATA \ uninstall-d_internalDATA uninstall-d_protocolDATA \ uninstall-d_serverDATA uninstall-d_servertransportDATA \ uninstall-d_testDATA uninstall-d_thriftDATA \ uninstall-d_transportDATA uninstall-d_utilDATA .PRECIOUS: Makefile # # libevent-dependent modules. # @HAVE_DEIMOS_EVENT2_TRUE@$(D_EVENT_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_libevent_dependent_modules))) @HAVE_DEIMOS_EVENT2_TRUE@ $(DMD) -of$(D_EVENT_LIB_NAME) $(d_lib_flags) $^ # # OpenSSL-dependent modules. # @HAVE_DEIMOS_OPENSSL_TRUE@$(D_SSL_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_openssl_dependent_modules))) @HAVE_DEIMOS_OPENSSL_TRUE@ $(DMD) -of$(D_SSL_LIB_NAME) $(d_lib_flags) $^ # # Main library target. # $(D_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_main_modules))) $(DMD) -of$(D_LIB_NAME) $(d_lib_flags) $^ # # Documentation target (requires Dil). # docs: $(d_publicsources) src/thrift/index.d dil ddoc docs -hl --kandil $^ # # Hook custom library targets into the automake all/install targets. # all-local: $(all_targets) install-exec-local: $(INSTALL_PROGRAM) $(all_targets) $(DESTDIR)$(libdir) clean-local: $(RM) -r docs $(RM) $(D_LIB_NAME) $(RM) $(D_EVENT_LIB_NAME) $(RM) $(D_SSL_LIB_NAME) $(RM) -r test/gen-d $(RM) -r unittest unittest/emptymain.d: unittest/.directory @echo 'void main(){}' >$@ unittest/.directory: mkdir -p unittest || exists unittest touch $@ unittest/debug/%: src/%.d $(all_targets) unittest/emptymain.d $(DMD) -g -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^ unittest/release/%: src/%.d $(all_targets) unittest/emptymain.d $(DMD) -O -release -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^ precross: all-local $(MAKE) -C test precross distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: thrift-0.23.0/lib/d/Makefile.am0000664000175000017500000001445215165535636016430 0ustar00buildbuild00000000000000# # 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. # AUTOMAKE_OPTIONS = serial-tests SUBDIRS = . if WITH_TESTS SUBDIRS += test endif # # Enumeration of all the public and private modules. # # We unconditionally install all of them, even if libevent or OpenSSL are # not available, but build the respective libraries only if the Deimos headers # could be found. # d_thriftmodules = $(addprefix thrift/, base) d_thriftdir = $(D_IMPORT_PREFIX)/thrift d_thrift_DATA = $(addprefix src/, $(addsuffix .d, $(d_thriftmodules))) d_asyncmodules = $(addprefix thrift/async/, base libevent socket ssl) d_asyncdir = $(d_thriftdir)/async d_async_DATA = $(addprefix src/, $(addsuffix .d, $(d_asyncmodules))) d_codegenmodules = $(addprefix thrift/codegen/, async_client \ async_client_pool base client client_pool processor) #d_codegenmodules = $(addprefix thrift/codegen/, async_client \ # async_client_pool base client client_pool idlgen processor) d_codegendir = $(d_thriftdir)/codegen d_codegen_DATA = $(addprefix src/, $(addsuffix .d, $(d_codegenmodules))) d_protocolmodules = $(addprefix thrift/protocol/, base binary compact json \ processor) d_protocoldir = $(d_thriftdir)/protocol d_protocol_DATA = $(addprefix src/, $(addsuffix .d, $(d_protocolmodules))) d_servermodules = $(addprefix thrift/server/, base simple nonblocking \ taskpool threaded) d_serverdir = $(d_thriftdir)/server d_server_DATA = $(addprefix src/, $(addsuffix .d, $(d_servermodules))) d_servertransportmodules = $(addprefix thrift/server/transport/, base socket ssl) d_servertransportdir = $(d_thriftdir)/server/transport d_servertransport_DATA = $(addprefix src/, $(addsuffix .d, \ $(d_servertransportmodules))) d_transportmodules = $(addprefix thrift/transport/, base buffered file \ framed http memory piped range socket ssl zlib) d_transportdir = $(d_thriftdir)/transport d_transport_DATA = $(addprefix src/, $(addsuffix .d, $(d_transportmodules))) d_utilmodules = $(addprefix thrift/util/, awaitable cancellation future \ hashset) d_utildir = $(d_thriftdir)/util d_util_DATA = $(addprefix src/, $(addsuffix .d, $(d_utilmodules))) d_internalmodules = $(addprefix thrift/internal/, algorithm codegen ctfe \ endian resource_pool socket ssl ssl_bio traits) d_internaldir = $(d_thriftdir)/internal d_internal_DATA = $(addprefix src/, $(addsuffix .d, $(d_internalmodules))) d_testmodules = $(addprefix thrift/internal/test/, protocol server) d_testdir = $(d_internaldir)/test d_test_DATA = $(addprefix src/, $(addsuffix .d, $(d_testmodules))) d_publicmodules = $(d_thriftmodules) $(d_asyncmodules) \ $(d_codegenmodules) $(d_protocolmodules) $(d_servermodules) \ $(d_servertransportmodules) $(d_transportmodules) $(d_utilmodules) d_publicsources = $(addprefix src/, $(addsuffix .d, $(d_publicmodules))) d_modules = $(d_publicmodules) $(d_internalmodules) $(d_testmodules) # List modules with external dependencies and remove them from the main list d_libevent_dependent_modules = thrift/async/libevent thrift/server/nonblocking d_openssl_dependent_modules = thrift/async/ssl thrift/internal/ssl \ thrift/internal/ssl_bio thrift/transport/ssl thrift/server/transport/ssl d_main_modules = $(filter-out $(d_libevent_dependent_modules) \ $(d_openssl_dependent_modules),$(d_modules)) d_lib_flags = -w -wi -Isrc -lib -version=use_openssl_1_0_x all_targets = # # libevent-dependent modules. # if HAVE_DEIMOS_EVENT2 $(D_EVENT_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_libevent_dependent_modules))) $(DMD) -of$(D_EVENT_LIB_NAME) $(d_lib_flags) $^ all_targets += $(D_EVENT_LIB_NAME) endif # # OpenSSL-dependent modules. # if HAVE_DEIMOS_OPENSSL $(D_SSL_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_openssl_dependent_modules))) $(DMD) -of$(D_SSL_LIB_NAME) $(d_lib_flags) $^ all_targets += $(D_SSL_LIB_NAME) endif # # Main library target. # $(D_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_main_modules))) $(DMD) -of$(D_LIB_NAME) $(d_lib_flags) $^ all_targets += $(D_LIB_NAME) # # Documentation target (requires Dil). # docs: $(d_publicsources) src/thrift/index.d dil ddoc docs -hl --kandil $^ # # Hook custom library targets into the automake all/install targets. # all-local: $(all_targets) install-exec-local: $(INSTALL_PROGRAM) $(all_targets) $(DESTDIR)$(libdir) clean-local: $(RM) -r docs $(RM) $(D_LIB_NAME) $(RM) $(D_EVENT_LIB_NAME) $(RM) $(D_SSL_LIB_NAME) $(RM) -r test/gen-d $(RM) -r unittest # # Unit tests (built both in debug and release mode). # d_test_flags = -unittest -w -wi -I$(top_srcdir)/lib/d/src -version=use_openssl_1_0_x # There just must be some way to reassign a variable without warnings in # Automake... d_test_modules__ = $(d_modules) if WITH_D_EVENT_TESTS d_test_flags += $(DMD_LIBEVENT_FLAGS) d_test_modules_ = $(d_test_modules__) else d_test_modules_ = $(filter-out $(d_libevent_dependent_modules), $(d_test_modules__)) endif if WITH_D_SSL_TESTS d_test_flags += $(DMD_OPENSSL_FLAGS) d_test_modules = $(d_test_modules_) else d_test_modules = $(filter-out $(d_openssl_dependent_modules), $(d_test_modules_)) endif unittest/emptymain.d: unittest/.directory @echo 'void main(){}' >$@ unittest/.directory: mkdir -p unittest || exists unittest touch $@ unittest/debug/%: src/%.d $(all_targets) unittest/emptymain.d $(DMD) -g -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^ unittest/release/%: src/%.d $(all_targets) unittest/emptymain.d $(DMD) -O -release -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^ TESTS = $(addprefix unittest/debug/, $(d_test_modules)) \ $(addprefix unittest/release/, $(d_test_modules)) precross: all-local $(MAKE) -C test precross distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = \ src \ test \ README.md thrift-0.23.0/ApacheThrift.nuspec0000664000175000017500000000343215170007142017136 0ustar00buildbuild00000000000000 ApacheThrift 0.23.0 Apache Thrift 0.23.0 Apache Thrift Developers Apache Software Foundation Apache-2.0 http://thrift.apache.org/ true Apache Thrift .NET Library Contains runtime libraries from lib/netstd for netstandard2.0 framework development. Apache Thrift RPC thrift-0.23.0/rust-toolchain0000664000175000017500000000000715165535636016270 0ustar00buildbuild000000000000001.83.0 thrift-0.23.0/contrib/0000775000175000017500000000000015170007142015013 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/0000775000175000017500000000000015170007142020713 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/0000775000175000017500000000000015165535636021524 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/0000775000175000017500000000000015165535636022450 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/0000775000175000017500000000000015165535636023371 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/0000775000175000017500000000000015165535636024160 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/apache/0000775000175000017500000000000015165535636025401 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/0000775000175000017500000000000015165535636026701 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/0000775000175000017500000000000015167543515030004 5ustar00buildbuild00000000000000AbstractThriftMojo.java0000664000175000017500000003612515165535636034353 0ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.maven; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.io.RawInputStreamFacade; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Sets.newHashSet; import static java.lang.String.format; import static java.util.Arrays.asList; import static java.util.Collections.list; import static org.codehaus.plexus.util.FileUtils.cleanDirectory; import static org.codehaus.plexus.util.FileUtils.copyStreamToFile; import static org.codehaus.plexus.util.FileUtils.getFiles; /** * Abstract Mojo implementation. *

* This class is extended by {@link org.apache.thrift.maven.ThriftCompileMojo} and * {@link org.apache.thrift.maven.ThriftTestCompileMojo} in order to override the specific configuration for * compiling the main or test classes respectively. */ abstract class AbstractThriftMojo extends AbstractMojo { private static final String THRIFT_FILE_SUFFIX = ".thrift"; private static final String DEFAULT_INCLUDES = "**/*" + THRIFT_FILE_SUFFIX; /** * The current Maven project. * * @parameter default-value="${project}" * @readonly * @required */ protected MavenProject project; /** * A helper used to add resources to the project. * * @component * @required */ protected MavenProjectHelper projectHelper; /** * This is the path to the {@code thrift} executable. By default it will search the {@code $PATH}. * * @parameter default-value="thrift" * @required */ private String thriftExecutable; /** * This string is passed to the {@code --gen} option of the {@code thrift} parameter. By default * it will generate Java output. The main reason for this option is to be able to add options * to the Java generator - if you generate something else, you're on your own. * * @parameter default-value="java" */ private String generator; /** * @parameter */ private File[] additionalThriftPathElements = new File[]{}; /** * Since {@code thrift} cannot access jars, thrift files in dependencies are extracted to this location * and deleted on exit. This directory is always cleaned during execution. * * @parameter default-value="${project.build.directory}/thrift-dependencies" * @required */ private File temporaryThriftFileDirectory; /** * This is the path to the local maven {@code repository}. * * @parameter default-value="${localRepository}" * @required */ protected ArtifactRepository localRepository; /** * Set this to {@code false} to disable hashing of dependent jar paths. *

* This plugin expands jars on the classpath looking for embedded .thrift files. * Normally these paths are hashed (MD5) to avoid issues with long file names on windows. * However if this property is set to {@code false} longer paths will be used. * * @parameter default-value="true" * @required */ protected boolean hashDependentPaths; /** * @parameter */ private Set includes = ImmutableSet.of(DEFAULT_INCLUDES); /** * @parameter */ private Set excludes = ImmutableSet.of(); /** * @parameter */ private long staleMillis = 0; /** * @parameter */ private boolean checkStaleness = false; /** * Executes the mojo. */ public void execute() throws MojoExecutionException, MojoFailureException { checkParameters(); final File thriftSourceRoot = getThriftSourceRoot(); if (thriftSourceRoot.exists()) { try { ImmutableSet thriftFiles = findThriftFilesInDirectory(thriftSourceRoot); final File outputDirectory = getOutputDirectory(); ImmutableSet outputFiles = findGeneratedFilesInDirectory(getOutputDirectory()); if (thriftFiles.isEmpty()) { getLog().info("No thrift files to compile."); } else if (checkStaleness && ((lastModified(thriftFiles) + staleMillis) < lastModified(outputFiles))) { getLog().info("Skipping compilation because target directory newer than sources."); attachFiles(); } else { ImmutableSet derivedThriftPathElements = makeThriftPathFromJars(temporaryThriftFileDirectory, getDependencyArtifactFiles()); outputDirectory.mkdirs(); // Quick fix to fix issues with two mvn installs in a row (ie no clean) // cleanDirectory(outputDirectory); Thrift thrift = new Thrift.Builder(thriftExecutable, outputDirectory) .setGenerator(generator) .addThriftPathElement(thriftSourceRoot) .addThriftPathElements(derivedThriftPathElements) .addThriftPathElements(asList(additionalThriftPathElements)) .addThriftFiles(thriftFiles) .build(); final int exitStatus = thrift.compile(); if (exitStatus != 0) { getLog().error("thrift failed output: " + thrift.getOutput()); getLog().error("thrift failed error: " + thrift.getError()); throw new MojoFailureException( "thrift did not exit cleanly. Review output for more information."); } attachFiles(); } } catch (IOException e) { throw new MojoExecutionException("An IO error occurred", e); } catch (IllegalArgumentException e) { throw new MojoFailureException("thrift failed to execute because: " + e.getMessage(), e); } catch (CommandLineException e) { throw new MojoExecutionException("An error occurred while invoking thrift.", e); } } else { getLog().info(format("%s does not exist. Review the configuration or consider disabling the plugin.", thriftSourceRoot)); } } ImmutableSet findGeneratedFilesInDirectory(File directory) throws IOException { if (directory == null || !directory.isDirectory()) return ImmutableSet.of(); List javaFilesInDirectory = getFiles(directory, "**/*.java", null); return ImmutableSet.copyOf(javaFilesInDirectory); } private long lastModified(ImmutableSet files) { long result = 0; for (File file : files) { if (file.lastModified() > result) result = file.lastModified(); } return result; } private void checkParameters() { checkNotNull(project, "project"); checkNotNull(projectHelper, "projectHelper"); checkNotNull(thriftExecutable, "thriftExecutable"); checkNotNull(generator, "generator"); final File thriftSourceRoot = getThriftSourceRoot(); checkNotNull(thriftSourceRoot); checkArgument(!thriftSourceRoot.isFile(), "thriftSourceRoot is a file, not a directory"); checkNotNull(temporaryThriftFileDirectory, "temporaryThriftFileDirectory"); checkState(!temporaryThriftFileDirectory.isFile(), "temporaryThriftFileDirectory is a file, not a directory"); final File outputDirectory = getOutputDirectory(); checkNotNull(outputDirectory); checkState(!outputDirectory.isFile(), "the outputDirectory is a file, not a directory"); } protected abstract File getThriftSourceRoot(); protected abstract List getDependencyArtifacts(); protected abstract File getOutputDirectory(); protected abstract void attachFiles(); /** * Gets the {@link File} for each dependency artifact. * * @return A set of all dependency artifacts. */ private ImmutableSet getDependencyArtifactFiles() { Set dependencyArtifactFiles = newHashSet(); for (Artifact artifact : getDependencyArtifacts()) { dependencyArtifactFiles.add(artifact.getFile()); } return ImmutableSet.copyOf(dependencyArtifactFiles); } /** * @throws IOException */ ImmutableSet makeThriftPathFromJars(File temporaryThriftFileDirectory, Iterable classpathElementFiles) throws IOException, MojoExecutionException { checkNotNull(classpathElementFiles, "classpathElementFiles"); // clean the temporary directory to ensure that stale files aren't used if (temporaryThriftFileDirectory.exists()) { cleanDirectory(temporaryThriftFileDirectory); } Set thriftDirectories = newHashSet(); for (File classpathElementFile : classpathElementFiles) { // for some reason under IAM, we receive poms as dependent files // I am excluding .xml rather than including .jar as there may be other extensions in use (sar, har, zip) if (classpathElementFile.isFile() && classpathElementFile.canRead() && !classpathElementFile.getName().endsWith(".xml")) { // create the jar file. the constructor validates. JarFile classpathJar; try { classpathJar = new JarFile(classpathElementFile); } catch (IOException e) { throw new IllegalArgumentException(format( "%s was not a readable artifact", classpathElementFile)); } /** * Copy each .thrift file found in the JAR into a temporary directory, preserving the * directory path it had relative to its containing JAR. Add the resulting root directory * (unique for each JAR processed) to the set of thrift include directories to use when * compiling. */ for (JarEntry jarEntry : list(classpathJar.entries())) { final String jarEntryName = jarEntry.getName(); if (jarEntry.getName().endsWith(THRIFT_FILE_SUFFIX)) { final String truncatedJarPath = truncatePath(classpathJar.getName()); final File thriftRootDirectory = new File(temporaryThriftFileDirectory, truncatedJarPath); final File uncompressedCopy = new File(thriftRootDirectory, jarEntryName); uncompressedCopy.getParentFile().mkdirs(); copyStreamToFile(new RawInputStreamFacade(classpathJar .getInputStream(jarEntry)), uncompressedCopy); thriftDirectories.add(thriftRootDirectory); } } } else if (classpathElementFile.isDirectory()) { File[] thriftFiles = classpathElementFile.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(THRIFT_FILE_SUFFIX); } }); if (thriftFiles.length > 0) { thriftDirectories.add(classpathElementFile); } } } return ImmutableSet.copyOf(thriftDirectories); } ImmutableSet findThriftFilesInDirectory(File directory) throws IOException { checkNotNull(directory); checkArgument(directory.isDirectory(), "%s is not a directory", directory); List thriftFilesInDirectory = getFiles(directory, Joiner.on(",").join(includes), Joiner.on(",").join(excludes)); return ImmutableSet.copyOf(thriftFilesInDirectory); } /** * Truncates the path of jar files so that they are relative to the local repository. * * @param jarPath the full path of a jar file. * @return the truncated path relative to the local repository or root of the drive. */ String truncatePath(final String jarPath) throws MojoExecutionException { if (hashDependentPaths) { try { return toHexString(MessageDigest.getInstance("MD5").digest(jarPath.getBytes())); } catch (NoSuchAlgorithmException e) { throw new MojoExecutionException("Failed to expand dependent jar", e); } } String repository = localRepository.getBasedir().replace('\\', '/'); if (!repository.endsWith("/")) { repository += "/"; } String path = jarPath.replace('\\', '/'); int repositoryIndex = path.indexOf(repository); if (repositoryIndex != -1) { path = path.substring(repositoryIndex + repository.length()); } // By now the path should be good, but do a final check to fix windows machines. int colonIndex = path.indexOf(':'); if (colonIndex != -1) { // 2 = :\ in C:\ path = path.substring(colonIndex + 2); } return path; } private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); public static String toHexString(byte[] byteArray) { final StringBuilder hexString = new StringBuilder(2 * byteArray.length); for (final byte b : byteArray) { hexString.append(HEX_CHARS[(b & 0xF0) >> 4]).append(HEX_CHARS[b & 0x0F]); } return hexString.toString(); } } ThriftCompileMojo.java0000664000175000017500000000502215167543515034165 0ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.maven; import java.io.File; import java.util.List; import org.apache.maven.artifact.Artifact; import com.google.common.collect.ImmutableList; /** * This mojo executes the {@code thrift} compiler for generating java sources * from thrift definitions. It also searches dependency artifacts for * thrift files and includes them in the thriftPath so that they can be * referenced. Finally, it adds the thrift files to the project as resources so * that they are included in the final artifact. * * @phase generate-sources * @threadSafe * @goal compile * @requiresDependencyResolution compile */ public final class ThriftCompileMojo extends AbstractThriftMojo { /** * The source directories containing the sources to be compiled. * * @parameter default-value="${basedir}/src/main/thrift" * @required */ private File thriftSourceRoot; /** * This is the directory into which the {@code .java} will be created. * * @parameter default-value="${project.build.directory}/generated-sources/thrift" * @required */ private File outputDirectory; @Override protected List getDependencyArtifacts() { List compileArtifacts = project.getCompileArtifacts(); return compileArtifacts; } @Override protected File getOutputDirectory() { return outputDirectory; } @Override protected File getThriftSourceRoot() { return thriftSourceRoot; } @Override protected void attachFiles() { project.addCompileSourceRoot(outputDirectory.getAbsolutePath()); projectHelper.addResource(project, thriftSourceRoot.getAbsolutePath(), ImmutableList.of("**/*.thrift"), null); } } ThriftTestCompileMojo.java0000664000175000017500000000577515167543515035044 0ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.maven; import java.io.File; import java.util.List; import org.apache.maven.artifact.Artifact; import com.google.common.collect.ImmutableList; import org.apache.maven.artifact.repository.ArtifactRepository; /** * @phase generate-test-sources * @threadSafe * @goal testCompile * @requiresDependencyResolution test */ public final class ThriftTestCompileMojo extends AbstractThriftMojo { /** * The source directories containing the sources to be compiled. * * @parameter default-value="${basedir}/src/test/thrift" * @required */ private File thriftTestSourceRoot; /** * This is the directory into which the {@code .java} will be created. * * @parameter default-value="${project.build.directory}/generated-test-sources/thrift" * @required */ private File outputDirectory; @Override protected void attachFiles() { project.addTestCompileSourceRoot(outputDirectory.getAbsolutePath()); projectHelper.addTestResource(project, thriftTestSourceRoot.getAbsolutePath(), ImmutableList.of("**/*.thrift"), null); } @Override protected List getDependencyArtifacts() { // TODO(gak): maven-project needs generics @SuppressWarnings("unchecked") List testArtifacts = project.getTestArtifacts(); return testArtifacts; } @Override protected File getOutputDirectory() { return outputDirectory; } @Override protected File getThriftSourceRoot() { return thriftTestSourceRoot; } /** * Set the local maven ArtifactRepository. Exposed only to allow testing outside of Maven itself. * * @param localRepository local ArtifactRepository */ public void setLocalMavenRepository(final ArtifactRepository localRepository) { this.localRepository = localRepository; } /** * Set the option to hash dependent JAR paths. Exposed only to allow testing outside of Maven itself. * * @param hashDependentPaths whether or not to hash paths to dependent JARs */ public void setHashDependentPaths(final boolean hashDependentPaths) { this.hashDependentPaths = hashDependentPaths; } } thrift-0.23.0/contrib/thrift-maven-plugin/src/main/java/org/apache/thrift/maven/Thrift.java0000664000175000017500000002376515165535636032127 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.maven; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.Commandline; import java.io.File; import java.util.List; import java.util.Set; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Lists.newLinkedList; import static com.google.common.collect.Sets.newHashSet; /** * This class represents an invokable configuration of the {@code thrift} * compiler. The actual executable is invoked using the plexus * {@link Commandline}. *

* This class currently only supports generating java source files. */ final class Thrift { final static String GENERATED_JAVA = "gen-java"; private final String executable; private final String generator; private final ImmutableSet thriftPathElements; private final ImmutableSet thriftFiles; private final File javaOutputDirectory; private final CommandLineUtils.StringStreamConsumer output; private final CommandLineUtils.StringStreamConsumer error; /** * Constructs a new instance. This should only be used by the {@link Builder}. * * @param executable The path to the {@code thrift} executable. * @param generator The value for the {@code --gen} option. * @param thriftPath The directories in which to search for imports. * @param thriftFiles The thrift source files to compile. * @param javaOutputDirectory The directory into which the java source files * will be generated. */ private Thrift(String executable, String generator, ImmutableSet thriftPath, ImmutableSet thriftFiles, File javaOutputDirectory) { this.executable = checkNotNull(executable, "executable"); this.generator = checkNotNull(generator, "generator"); this.thriftPathElements = checkNotNull(thriftPath, "thriftPath"); this.thriftFiles = checkNotNull(thriftFiles, "thriftFiles"); this.javaOutputDirectory = checkNotNull(javaOutputDirectory, "javaOutputDirectory"); this.error = new CommandLineUtils.StringStreamConsumer(); this.output = new CommandLineUtils.StringStreamConsumer(); } /** * Invokes the {@code thrift} compiler using the configuration specified at * construction. * * @return The exit status of {@code thrift}. * @throws CommandLineException */ public int compile() throws CommandLineException { for (File thriftFile : thriftFiles) { Commandline cl = new Commandline(); cl.setExecutable(executable); cl.addArguments(buildThriftCommand(thriftFile).toArray(new String[]{})); final int result = CommandLineUtils.executeCommandLine(cl, null, output, error); if (result != 0) { return result; } } // result will always be 0 here. return 0; } /** * Creates the command line arguments. *

* This method has been made visible for testing only. * * @param thriftFile * @return A list consisting of the executable followed by any arguments. */ ImmutableList buildThriftCommand(final File thriftFile) { final List command = newLinkedList(); // add the executable for (File thriftPathElement : thriftPathElements) { command.add("-I"); command.add(thriftPathElement.toString()); } command.add("-out"); command.add(javaOutputDirectory.toString()); command.add("--gen"); command.add(generator); command.add(thriftFile.toString()); return ImmutableList.copyOf(command); } /** * @return the output */ public String getOutput() { return output.getOutput(); } /** * @return the error */ public String getError() { return error.getOutput(); } /** * This class builds {@link Thrift} instances. */ static final class Builder { private final String executable; private final File javaOutputDirectory; private Set thriftPathElements; private Set thriftFiles; private String generator; /** * Constructs a new builder. The two parameters are present as they are * required for all {@link Thrift} instances. * * @param executable The path to the {@code thrift} executable. * @param javaOutputDirectory The directory into which the java source files * will be generated. * @throws NullPointerException If either of the arguments are {@code null}. * @throws IllegalArgumentException If the {@code javaOutputDirectory} is * not a directory. */ public Builder(String executable, File javaOutputDirectory) { this.executable = checkNotNull(executable, "executable"); this.javaOutputDirectory = checkNotNull(javaOutputDirectory); checkArgument(javaOutputDirectory.isDirectory()); this.thriftFiles = newHashSet(); this.thriftPathElements = newHashSet(); } /** * Adds a thrift file to be compiled. Thrift files must be on the thriftpath * and this method will fail if a thrift file is added without first adding a * parent directory to the thriftpath. * * @param thriftFile * @return The builder. * @throws IllegalStateException If a thrift file is added without first * adding a parent directory to the thriftpath. * @throws NullPointerException If {@code thriftFile} is {@code null}. */ public Builder addThriftFile(File thriftFile) { checkNotNull(thriftFile); checkArgument(thriftFile.isFile()); checkArgument(thriftFile.getName().endsWith(".thrift")); checkThriftFileIsInThriftPath(thriftFile); thriftFiles.add(thriftFile); return this; } /** * Adds the option string for the Thrift executable's {@code --gen} parameter. * * @param generator * @return The builder * @throws NullPointerException If {@code generator} is {@code null}. */ public Builder setGenerator(String generator) { checkNotNull(generator); this.generator = generator; return this; } private void checkThriftFileIsInThriftPath(File thriftFile) { assert thriftFile.isFile(); checkState(checkThriftFileIsInThriftPathHelper(thriftFile.getParentFile())); } private boolean checkThriftFileIsInThriftPathHelper(File directory) { assert directory.isDirectory(); if (thriftPathElements.contains(directory)) { return true; } else { final File parentDirectory = directory.getParentFile(); return (parentDirectory == null) ? false : checkThriftFileIsInThriftPathHelper(parentDirectory); } } /** * @see #addThriftFile(File) */ public Builder addThriftFiles(Iterable thriftFiles) { for (File thriftFile : thriftFiles) { addThriftFile(thriftFile); } return this; } /** * Adds the {@code thriftPathElement} to the thriftPath. * * @param thriftPathElement A directory to be searched for imported thrift message * buffer definitions. * @return The builder. * @throws NullPointerException If {@code thriftPathElement} is {@code null}. * @throws IllegalArgumentException If {@code thriftPathElement} is not a * directory. */ public Builder addThriftPathElement(File thriftPathElement) { checkNotNull(thriftPathElement); checkArgument(thriftPathElement.isDirectory()); thriftPathElements.add(thriftPathElement); return this; } /** * @see #addThriftPathElement(File) */ public Builder addThriftPathElements(Iterable thriftPathElements) { for (File thriftPathElement : thriftPathElements) { addThriftPathElement(thriftPathElement); } return this; } /** * @return A configured {@link Thrift} instance. * @throws IllegalStateException If no thrift files have been added. */ public Thrift build() { checkState(!thriftFiles.isEmpty()); return new Thrift(executable, generator, ImmutableSet.copyOf(thriftPathElements), ImmutableSet.copyOf(thriftFiles), javaOutputDirectory); } } } thrift-0.23.0/contrib/thrift-maven-plugin/src/test/0000775000175000017500000000000015165535636022503 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/resources/0000775000175000017500000000000015165535636024515 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/resources/idl/0000775000175000017500000000000015165535636025265 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/resources/idl/tutorial.thrift0000664000175000017500000001140615165535636030354 0ustar00buildbuild00000000000000/* * 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. */ # Thrift Tutorial # Mark Slee (mcslee@facebook.com) # # This file aims to teach you how to use Thrift, in a .thrift file. Neato. The # first thing to notice is that .thrift files support standard shell comments. # This lets you make your thrift file executable and include your Thrift build # step on the top line. And you can place comments like this anywhere you like. # # Before running this file, you will need to have installed the thrift compiler # into /usr/local/bin. /** * The first thing to know about are types. The available types in Thrift are: * * bool Boolean, one byte * byte Signed byte * i16 Signed 16-bit integer * i32 Signed 32-bit integer * i64 Signed 64-bit integer * double 64-bit floating point value * string String * binary Blob (byte array) * map Map from one type to another * list Ordered list of one type * set Set of unique elements of one type * * Did you also notice that Thrift supports C style comments? */ // Just in case you were wondering... yes. We support simple C comments too. /** * Thrift files can reference other Thrift files to include common struct * and service definitions. These are found using the current path, or by * searching relative to any paths specified with the -I compiler flag. * * Included objects are accessed using the name of the .thrift file as a * prefix. i.e. shared.SharedObject */ include "shared.thrift" /** * Thrift files can namespace, package, or prefix their output in various * target languages. */ namespace cpp tutorial namespace java tutorial namespace php tutorial namespace perl tutorial namespace smalltalk.category Thrift.Tutorial /** * Thrift lets you do typedefs to get pretty names for your types. Standard * C style here. */ typedef i32 MyInteger /** * Thrift also lets you define constants for use across languages. Complex * types and structs are specified using JSON notation. */ const i32 INT32CONSTANT = 9853 const map MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} /** * You can define enums, which are just 32 bit integers. Values are optional * and start at 1 if not supplied, C style again. */ enum Operation { ADD = 1, SUBTRACT = 2, MULTIPLY = 3, DIVIDE = 4 } /** * Structs are the basic complex data structures. They are comprised of fields * which each have an integer identifier, a type, a symbolic name, and an * optional default value. * * Fields can be declared "optional", which ensures they will not be included * in the serialized output if they aren't set. Note that this requires some * manual management in some languages. */ struct Work { 1: i32 num1 = 0, 2: i32 num2, 3: Operation op, 4: optional string comment, } /** * Structs can also be exceptions, if they are nasty. */ exception InvalidOperation { 1: i32 what, 2: string why } /** * Ahh, now onto the cool part, defining a service. Services just need a name * and can optionally inherit from another service using the extends keyword. */ service Calculator extends shared.SharedService { /** * A method definition looks like C code. It has a return type, arguments, * and optionally a list of exceptions that it may throw. Note that argument * lists and exception lists are specified using the exact same syntax as * field lists in struct or exception definitions. */ void ping(), i32 add(1:i32 num1, 2:i32 num2), i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), /** * This method has a oneway modifier. That means the client only makes * a request and does not listen for any response at all. Oneway methods * must be void. */ oneway void zip() } /** * That just about covers the basics. Take a look in the test/ folder for more * detailed examples. After you run this file, your generated code shows up * in folders with names gen-. The generated code isn't too scary * to look at. It even has pretty indentation. */ thrift-0.23.0/contrib/thrift-maven-plugin/src/test/resources/idl/shared.thrift0000664000175000017500000000211215165535636027751 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * This Thrift file can be included by other Thrift files that want to share * these definitions. */ namespace cpp shared namespace java shared namespace perl shared struct SharedStruct { 1: i32 key 2: string value } service SharedService { SharedStruct getStruct(1: i32 key) } thrift-0.23.0/contrib/thrift-maven-plugin/src/test/java/0000775000175000017500000000000015165535636023424 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/java/org/0000775000175000017500000000000015165535636024213 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/java/org/apache/0000775000175000017500000000000015165535636025434 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/0000775000175000017500000000000015165535636026734 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/0000775000175000017500000000000015165535636030042 5ustar00buildbuild00000000000000TestAbstractThriftMojo.java0000664000175000017500000001054515165535636035244 0ustar00buildbuild00000000000000thrift-0.23.0/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.maven; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.maven.artifact.repository.ArtifactRepository; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import java.io.File; import java.util.Set; import static junit.framework.TestCase.assertEquals; public class TestAbstractThriftMojo { private ThriftTestCompileMojo mojo; private File testRootDir; private ArtifactRepository mavenRepository; @Before public void setUp() throws Exception { final File tmpDir = new File(System.getProperty("java.io.tmpdir")); testRootDir = new File(tmpDir, "thrift-test"); // the truncatePath method assumes a maven repository, but it only cares about the base dir mavenRepository = Mockito.mock(ArtifactRepository.class); Mockito.when(mavenRepository.getBasedir()).thenReturn("/test/maven/repo/basedir"); mojo = new ThriftTestCompileMojo(); mojo.setLocalMavenRepository(mavenRepository); } @Test public void testMakeThriftPathFromJars() throws Throwable { final File temporaryThriftFileDirectory = testRootDir; // The SharedIdl.jar file contains the same idl/shared.thrift and idl/tutorial.thrift hierarchy // used by other tests. It's used here to represent a dependency of the project maven is building, // one that is contributing .thrift IDL files as well as any other artifacts. final Iterable classpathElementFiles = Lists.newArrayList( new File("target/SharedIdl.jar") ); final Set thriftDirectories = mojo.makeThriftPathFromJars(temporaryThriftFileDirectory, classpathElementFiles); // The results should be a path to a directory named after the JAR itself (assuming no path hashing, // but see below for a separate test of that) representing the root of a hierarchy containing thrift // files, suitable for providing to the thrift compiler as an include directory. In this case, that // means it points to the directory containing the "idl" hierarchy rather than to the idl directory // itself. final Set expected = Sets.newHashSet( new File(testRootDir, "target/SharedIdl.jar") ); assertEquals("makeThriftPathFromJars should return thrift IDL base path from within JAR", expected, thriftDirectories); } @Test public void testTruncatePath() throws Throwable { // JAR path is unrelated to maven repo, and should be unchanged assertEquals("/path/to/somejar.jar", mojo.truncatePath("/path/to/somejar.jar")); // JAR path is within maven repo, and should be made relative to the repo assertEquals("path/to/somejar.jar", mojo.truncatePath("/test/maven/repo/basedir/path/to/somejar.jar")); // JAR path contains forward slashes that should be normalized assertEquals("/path/to/somejar.jar", mojo.truncatePath("\\path\\to\\somejar.jar")); } @Test public void testTruncatePathWithDependentPathHashing() throws Throwable { mojo.setHashDependentPaths(true); // hashDependentPaths set to true, the JAR path is immediately hashed (MD5) and converted to a hex string assertEquals("1c85950987b23493462cf3c261d9510a", mojo.truncatePath("/path/to/somejar.jar")); assertEquals("39fc2b4c34cb6cb0da38bed5d8b5fc67", mojo.truncatePath("/test/maven/repo/basedir/path/to/somejar.jar")); assertEquals("25b6924f5b0e19486d0ff88448e999d5", mojo.truncatePath("\\path\\to\\somejar.jar")); } } thrift-0.23.0/contrib/thrift-maven-plugin/src/test/java/org/apache/thrift/maven/TestThrift.java0000664000175000017500000001323715165535636033013 0ustar00buildbuild00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.maven; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.cli.CommandLineException; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.File; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class TestThrift { private File testRootDir; private File idlDir; private File genJavaDir; private Thrift.Builder builder; @Before public void setup() throws Exception { final File tmpDir = new File(System.getProperty("java.io.tmpdir")); testRootDir = new File(tmpDir, "thrift-test"); if (testRootDir.exists()) { FileUtils.cleanDirectory(testRootDir); } else { assertTrue("Failed to create output directory for test: " + testRootDir.getPath(), testRootDir.mkdir()); } File testResourceDir = new File("src/test/resources"); assertTrue("Unable to find test resources", testRootDir.exists()); String thriftExecutable = System.getProperty("thriftExecutable", "thrift"); if (!(new File(thriftExecutable).exists())) { thriftExecutable = "thrift"; } System.out.println("Thrift compiler: " + thriftExecutable); idlDir = new File(testResourceDir, "idl"); genJavaDir = new File(testRootDir, Thrift.GENERATED_JAVA); builder = new Thrift.Builder(thriftExecutable, testRootDir); builder .setGenerator("java") .addThriftPathElement(idlDir); } @Test public void testThriftCompile() throws Exception { executeThriftCompile(); } @Test public void testThriftCompileWithGeneratorOption() throws Exception { builder.setGenerator("java:private_members"); executeThriftCompile(); } private void executeThriftCompile() throws CommandLineException { final File thriftFile = new File(idlDir, "shared.thrift"); builder.addThriftFile(thriftFile); final Thrift thrift = builder.build(); assertTrue("File not found: shared.thrift", thriftFile.exists()); assertFalse("gen-java directory should not exist", genJavaDir.exists()); // execute the compile final int result = thrift.compile(); assertEquals(0, result); assertFalse("gen-java directory was not removed", genJavaDir.exists()); assertTrue("generated java code doesn't exist", new File(testRootDir, "shared/SharedService.java").exists()); } @Test public void testThriftMultipleFileCompile() throws Exception { final File sharedThrift = new File(idlDir, "shared.thrift"); final File tutorialThrift = new File(idlDir, "tutorial.thrift"); builder.addThriftFile(sharedThrift); builder.addThriftFile(tutorialThrift); final Thrift thrift = builder.build(); assertTrue("File not found: shared.thrift", sharedThrift.exists()); assertFalse("gen-java directory should not exist", genJavaDir.exists()); // execute the compile final int result = thrift.compile(); assertEquals(0, result); assertFalse("gen-java directory was not removed", genJavaDir.exists()); assertTrue("generated java code doesn't exist", new File(testRootDir, "shared/SharedService.java").exists()); assertTrue("generated java code doesn't exist", new File(testRootDir, "tutorial/InvalidOperation.java").exists()); } @Test public void testBadCompile() throws Exception { final File thriftFile = new File(testRootDir, "missing.thrift"); builder.addThriftPathElement(testRootDir); // Hacking around checks in addThrift file. assertTrue(thriftFile.createNewFile()); builder.addThriftFile(thriftFile); assertTrue(thriftFile.delete()); final Thrift thrift = builder.build(); assertTrue(!thriftFile.exists()); assertFalse("gen-java directory should not exist", genJavaDir.exists()); // execute the compile final int result = thrift.compile(); assertEquals(1, result); } @Test public void testFileInPathPreCondition() throws Exception { final File thriftFile = new File(testRootDir, "missing.thrift"); // Hacking around checks in addThrift file. assertTrue(thriftFile.createNewFile()); try { builder.addThriftFile(thriftFile); fail("Expected IllegalStateException"); } catch (IllegalStateException e) { } } @After public void cleanup() throws Exception { if (testRootDir.exists()) { FileUtils.cleanDirectory(testRootDir); assertTrue("Failed to delete output directory for test: " + testRootDir.getPath(), testRootDir.delete()); } } } thrift-0.23.0/contrib/thrift-maven-plugin/pom.xml0000664000175000017500000001005115170007142022225 0ustar00buildbuild00000000000000 4.0.0 org.apache apache 23 org.apache.thrift thrift-maven-plugin maven-plugin thrift-maven-plugin 0.23.0 1.8 1.8 ${basedir}/../.. ${thrift.root}/compiler/cpp/thrift ${thrift.root}/test org.apache.maven.plugins maven-compiler-plugin org.apache.maven.plugins maven-surefire-plugin ${argLine} ${thrift.compiler} org.apache.maven.plugins maven-antrun-plugin generate-jar-for-test generate-test-resources run junit junit 4.13.1 test org.apache.maven maven-plugin-api 3.9.8 org.apache.maven maven-core 3.9.8 com.google.guava guava 32.0.1-jre org.codehaus.plexus plexus-utils 4.0.3 org.mockito mockito-all 1.10.19 test jdk9+ [9,) --add-opens=java.base/java.lang=ALL-UNNAMED thrift-0.23.0/contrib/Rebus/0000775000175000017500000000000015165535636016115 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/Rebus/ServiceImpl/0000775000175000017500000000000015165535636020337 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/Rebus/ServiceImpl/Server.cs0000664000175000017500000001054115165535636022135 0ustar00buildbuild00000000000000/** * 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 Rebus; using Rebus.Configuration; using Rebus.Messages; using Rebus.RabbitMQ; using System; using System.Collections.Generic; using System.IO; using Thrift.Protocol; using Thrift.Transport; /* * The server implements the BasicMathServer service . * All results are sent back to the client via the BasicMathClient service */ namespace RebusSample.Server { // handler to be registered with Rebus class MathRequestCallHandler : IHandleMessages { public void Handle(MathRequestCall message) { // Thrift protocol/transport stack var stm = new MemoryStream(message.rawBytes); var trns = new TStreamTransport(stm, null); var prot = new TBinaryProtocol(trns); // create a processor and let him handle the call var hndl = new MathRequestsHandler(); var proc = new BasicMathServer.Processor(hndl); proc.Process(prot, null); // oneway only } } // serves incoming calculation requests internal class MathRequestsHandler : BasicMathServer.Iface { public void Ping(long value) { var client = new MathResponseClient("localhost"); client.Pong(value); } public void DoTheMath(int arg1, int arg2) { var client = new MathResponseClient("localhost"); if( arg2 != 0) client.FourResults( arg1+arg2, arg1*arg2, arg1-arg2, arg1/arg2); else client.ThreeResults( arg1+arg2, arg1*arg2, arg1-arg2); } } // provides the client-side interface for calculation responses internal class MathResponseClient : BasicMathClient.Iface { private BuiltinContainerAdapter MQAdapter; public MathResponseClient(string server) { MQAdapter = new BuiltinContainerAdapter(); Configure.With(MQAdapter) .Transport(t => t.UseRabbitMqInOneWayMode("amqp://" + server)) // we need send only .MessageOwnership(o => o.FromRebusConfigurationSection()) .CreateBus().Start(); } public void SerializeThriftCall(Action action) { // Thrift protocol/transport stack var stm = new MemoryStream(); var trns = new TStreamTransport(null, stm); var prot = new TBinaryProtocol(trns); // serialize the call into a bunch of bytes var client = new BasicMathClient.Client(prot); if (action != null) action(client); else throw new ArgumentException("action must not be null"); // make sure everything is written to the MemoryStream trns.Flush(); // send the message var msg = new MathResponseCall() { rawBytes = stm.ToArray() }; MQAdapter.Bus.Send(msg); } public void Pong(long value) { SerializeThriftCall(client => { client.Pong(value); }); } public void ThreeResults(int added, int multiplied, int suctracted) { SerializeThriftCall(client => { client.ThreeResults(added, multiplied, suctracted); }); } public void FourResults(int added, int multiplied, int suctracted, int divided) { SerializeThriftCall(client => { client.FourResults(added, multiplied, suctracted, divided); }); } } } thrift-0.23.0/contrib/Rebus/ServiceImpl/Both.cs0000664000175000017500000000227115165535636021564 0ustar00buildbuild00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using System; namespace RebusSample { // generic data container for serialized Thrift calls public class GenericThriftServiceCall { public byte[] rawBytes; } // specific containers (one per Thrift service) to leverage Rebus' handler routing public class MathRequestCall : GenericThriftServiceCall { } public class MathResponseCall : GenericThriftServiceCall { } }thrift-0.23.0/contrib/Rebus/ServiceImpl/Client.cs0000664000175000017500000001161615165535636022111 0ustar00buildbuild00000000000000/** * 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 Rebus; using Rebus.Configuration; using Rebus.Messages; using Rebus.RabbitMQ; using System; using System.Collections.Generic; using System.IO; using Thrift.Protocol; using Thrift.Transport; /* * The client emits calls to BasicMathServers * * The client implements the BasicMathClient service. * If the server has processed our request, we get the results back through this service */ namespace RebusSample.Client { // handler to be registered with Rebus class MathResponseCallHandler : IHandleMessages { public void Handle(MathResponseCall message) { // Thrift protocol/transport stack var stm = new MemoryStream(message.rawBytes); var trns = new TStreamTransport(stm, null); var prot = new TBinaryProtocol(trns); // create a processor and let him handle the call var hndl = new MathResponsesHandler(); var proc = new BasicMathClient.Processor(hndl); proc.Process(prot, null); // oneway only } } // serves incoming responses with calculation results internal class MathResponsesHandler : BasicMathClient.Iface { public void FourResults(int added, int multiplied, int subtracted, int divided) { Console.WriteLine("added = {0}", added); Console.WriteLine("multiplied= {0}", multiplied); Console.WriteLine("subtracted = {0}", subtracted); Console.WriteLine("divided = {0}", divided); PingAndDoAnotherCalculation(); } public void ThreeResults(int added, int multiplied, int subtracted) { Console.WriteLine("added = {0}", added); Console.WriteLine("multiplied= {0}", multiplied); Console.WriteLine("subtracted = {0}", subtracted); Console.WriteLine("DIV/0 error during division"); PingAndDoAnotherCalculation(); } public void Pong(long value) { var latency = DateTime.Now.Ticks - value; Console.WriteLine("Ping took {0} ms", new DateTime(latency).Millisecond); } private void PingAndDoAnotherCalculation() { var random = new Random(); var client = new MathRequestClient("localhost"); client.Ping(DateTime.Now.Ticks); client.DoTheMath(random.Next(), random.Next()); } } // provides the client-side interface for calculation requests internal class MathRequestClient : BasicMathServer.Iface { private BuiltinContainerAdapter MQAdapter; public MathRequestClient(string server) { MQAdapter = new BuiltinContainerAdapter(); Configure.With(MQAdapter) .Transport(t => t.UseRabbitMqInOneWayMode("amqp://" + server)) // we need send only .MessageOwnership(o => o.FromRebusConfigurationSection()) .CreateBus().Start(); } public void SerializeThriftCall(Action action) { // Thrift protocol/transport stack var stm = new MemoryStream(); var trns = new TStreamTransport(null, stm); var prot = new TBinaryProtocol(trns); // serialize the call into a bunch of bytes var client = new BasicMathServer.Client(prot); if( action != null) action(client); else throw new ArgumentException("action must not be null"); // make sure everything is written to the MemoryStream trns.Flush(); // send the message var msg = new MathRequestCall() { rawBytes = stm.ToArray() }; MQAdapter.Bus.Send(msg); } public void Ping(long value) { SerializeThriftCall(client => { client.Ping(value); }); } public void DoTheMath( int arg1, int arg2) { SerializeThriftCall(client => { client.DoTheMath(arg1, arg2); }); } } } thrift-0.23.0/contrib/Rebus/Properties/0000775000175000017500000000000015170007142020227 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/Rebus/Properties/AssemblyInfo.cs0000664000175000017500000000256215170007142023156 0ustar00buildbuild00000000000000/** * 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; [assembly: AssemblyTitle("RebusSample")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RebusSample")] [assembly: AssemblyCopyright("Copyright © 2014")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("0af10984-40d3-453d-b1e5-421529e8c7e2")] [assembly: AssemblyVersion("0.23.0.0")] [assembly: AssemblyFileVersion("0.23.0.0")] thrift-0.23.0/contrib/Rebus/App.config0000664000175000017500000000251415165535636020026 0ustar00buildbuild00000000000000

thrift-0.23.0/contrib/Rebus/RebusSample.sln0000664000175000017500000000265015165535636021060 0ustar00buildbuild00000000000000 Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.30110.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RebusSample", "RebusSample.csproj", "{264E2126-EDE0-4B47-89C1-B397B25BB13D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "..\..\lib\csharp\src\Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Debug|Any CPU.Build.0 = Debug|Any CPU {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Release|Any CPU.ActiveCfg = Release|Any CPU {264E2126-EDE0-4B47-89C1-B397B25BB13D}.Release|Any CPU.Build.0 = Release|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal thrift-0.23.0/contrib/Rebus/Program.cs0000664000175000017500000000537515165535636020065 0ustar00buildbuild00000000000000/** * 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 Rebus.Configuration; using Rebus.RabbitMQ; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using RebusSample.Client; using RebusSample.Server; namespace RebusSample { class Program { static BuiltinContainerAdapter StartRequestServer(string server) { // client Rebus configuration var adapter = new BuiltinContainerAdapter(); Configure.With(adapter) .Transport(t => t.UseRabbitMq("amqp://" + server, "MathRequests", "MathRequestErrors")) .MessageOwnership(o => o.FromRebusConfigurationSection()) .CreateBus().Start(); // register all relevant message handlers adapter.Register(typeof(MathRequestCallHandler)); return adapter; } static BuiltinContainerAdapter StartResponseServer(string server) { // client Rebus configuration var adapter = new BuiltinContainerAdapter(); Configure.With(adapter) .Transport(t => t.UseRabbitMq("amqp://" + server, "MathResponses", "MathResponseErrors")) .MessageOwnership(o => o.FromRebusConfigurationSection()) .CreateBus().Start(); // register all relevant message handlers adapter.Register(typeof(MathResponseCallHandler)); return adapter; } static void Main(string[] args) { string server = "localhost"; // start all servers var req = StartRequestServer(server); var rsp = StartResponseServer(server); // send the first message var random = new Random(); var client = new MathRequestClient(server); client.DoTheMath(random.Next(), random.Next()); // now what? Console.Write("Hit to stop ... "); Console.ReadLine(); } } } thrift-0.23.0/contrib/Rebus/RebusSample.csproj0000664000175000017500000001054415165535636021565 0ustar00buildbuild00000000000000 Debug AnyCPU {264E2126-EDE0-4B47-89C1-B397B25BB13D} Exe Properties RebusSample RebusSample v4.5 512 AnyCPU true full false bin\Debug\ DEBUG;TRACE prompt 4 AnyCPU pdbonly true bin\Release\ TRACE prompt 4 ..\..\..\..\..\Toolbox\ServiceBus\3rdparty\rabbitmq-dotnet-client-3.2.1-dotnet-3.0\bin\RabbitMQ.Client.dll ..\..\..\..\..\Toolbox\ServiceBus\3rdparty\Rebus-master\deploy\NET40\Rebus.dll ..\..\..\..\..\Toolbox\ServiceBus\3rdparty\Rebus-master\deploy\NET40\Rebus.RabbitMQ.dll {499eb63c-d74c-47e8-ae48-a2fc94538e9d} Thrift cd $(ProjectDir) if not exist gen-csharp\*.cs thrift -gen csharp sample.thrift thrift-0.23.0/contrib/Rebus/sample.thrift0000664000175000017500000000223115165535636020616 0ustar00buildbuild00000000000000/** * 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. */ service BasicMathServer { oneway void DoTheMath( 1: i32 arg1, 2: i32 arg2) oneway void Ping(1: i64 value) } service BasicMathClient { oneway void ThreeResults( 1 : i32 added, 2 : i32 multiplied, 3 : i32 subtracted); oneway void FourResults( 1 : i32 added, 2 : i32 multiplied, 3 : i32 subtracted, 4 : i32 divided); oneway void Pong(1: i64 value) } thrift-0.23.0/contrib/Rebus/README.md0000664000175000017500000000227615165535636017403 0ustar00buildbuild00000000000000Sample code for the combination of Thrift with Rebus. Rebus is a .NET service bus, similar to NServiceBus, but more lightweight. It ihas been mainly written by Mogens Heller Grabe and is currently hosted on GitHub (https://github.com/rebus-org/Rebus) As with all ServiceBus or MQ scenarios, due to the highly asynchronous operations it is recommended to do all calls as "oneway void" calls. The configuration can be done via App.Config, via code or even mixed from both locations. Refer to the Rebus documentation for further details. For this example, since we are effectively implementing two queue listeners in only one single process, we do configuration of incoming and error queues in the code. If you want to communicate with non-NET languages, you may need a customized serializer as well, in order to override Rebus' default wire format. Please refer to the Rebus docs on how to do that (it's not that hard, really). Additional requirements: - RabbitMQ .NET client (see nuget) Deprecation notice: Csharp is not a supported Apache Thrift target anymore. Instead netstd is the recommended replacement. This code is left "as is" for educational purposes unless someone converts it to netstd thrift-0.23.0/contrib/thrift.spec0000664000175000017500000001377215170007142017201 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # %define without_java 1 %define without_python 1 %define without_tests 1 %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} Name: thrift License: Apache License v2.0 Group: Development Summary: RPC and serialization framework Version: 0.23.0 Release: 0 URL: http://thrift.apache.org Packager: Thrift Developers Source0: %{name}-%{version}.tar.gz BuildRequires: gcc >= 3.4.6 BuildRequires: gcc-c++ %if 0%{!?without_java:1} BuildRequires: java-devel >= 0:1.5.0 BuildRequires: ant >= 0:1.6.5 %endif %if 0%{!?without_python:1} BuildRequires: python-devel %endif %if 0%{!?without_ruby:1} %define gem_name %{name} BuildRequires: ruby-devel BuildRequires: rubygems-devel %endif BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %description Thrift is a software framework for scalable cross-language services development. It combines a powerful software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, C#, Python, Ruby, Perl, PHP, Smalltalk, Erlang, OCaml, Haskell, and other languages. %files %defattr(-,root,root) %{_bindir}/thrift %package lib-cpp Summary: Thrift C++ library Group: Libraries %description lib-cpp C++ libraries for Thrift. %files lib-cpp %defattr(-,root,root) %{_libdir}/libthrift*.so.* %{_libdir}/libthrift*.so %package lib-cpp-devel Summary: Thrift C++ library development files Group: Libraries Requires: %{name} = %{version}-%{release} Requires: boost-devel %if 0%{!?without_libevent:1} Requires: libevent-devel >= 1.2 %endif %if 0%{!?without_zlib:1} Requires: zlib-devel %endif %description lib-cpp-devel C++ static libraries and headers for Thrift. %files lib-cpp-devel %defattr(-,root,root) %{_includedir}/thrift/ %{_libdir}/libthrift*.*a %{_libdir}/pkgconfig/thrift*.pc %if 0%{!?without_java:1} %package lib-java Summary: Thrift Java library Group: Libraries Requires: java >= 0:1.5.0 %description lib-java Java libraries for Thrift. %files lib-java %defattr(-,root,root) %{_javadir}/* %endif %if 0%{!?without_python:1} %package lib-python Summary: Thrift Python library Group: Libraries %description lib-python Python libraries for Thrift. %files lib-python %defattr(-,root,root) %{python_sitearch}/* %endif %if 0%{!?without_ruby:1} %package -n rubygem-%{gem_name} Summary: Thrift Ruby library Group: Libraries Obsoletes: %{name}-lib-ruby %description -n rubygem-%{gem_name} Ruby libraries for Thrift. %files -n rubygem-%{gem_name} %defattr(-,root,root) %{gem_dir}/* %endif %if 0%{!?without_php:1} %package lib-php Summary: Thrift PHP library Group: Libraries %description lib-php PHP libraries for Thrift. %files lib-php %defattr(-,root,root) /usr/lib/php/* %endif %prep %setup -q %build [[ -e Makefile.in ]] || ./bootstrap.sh export GEM_HOME=${PWD}/.gem-home export RUBYLIB=${PWD}/lib/rb/lib %configure \ %{?without_libevent: --without-libevent } \ %{?without_zlib: --without-zlib } \ %{?without_tests: --without-tests } \ %{?without_java: --without-java } \ %{?without_python: --without-python } \ %{?without_ruby: --without-ruby } \ %{?without_php: --without-php } \ %{!?without_php: PHP_PREFIX=${RPM_BUILD_ROOT}/usr/lib/php } \ --without-erlang \ %if 0%{!?without_ruby:1} eval $(grep "^WITH_RUBY_TRUE" config.log) if [[ "${WITH_RUBY_TRUE}" != "" ]]; then set +x echo "" echo "configure determined that ruby requirements are missing (bundler gem?), either install missing components" >&2 echo "or disable the ruby sub-packages as follows:" >&2 echo " rpmbuild -D'%without_ruby 1' ..." >&2 echo "" exit 1 fi %endif make %{?_smp_mflags} %if 0%{!?without_java:1} cd lib/java %ant cd ../.. %endif %if 0%{!?without_python:1} cd lib/py CFLAGS="%{optflags}" %{__python} setup.py build cd ../.. %endif %if 0%{!?without_ruby:1} %gem_install -n lib/rb/thrift*.gem %endif %install export GEM_HOME=${PWD}/.gem-home export RUBYLIB=${PWD}/lib/rb/lib %makeinstall ln -s libthrift-%{version}.so ${RPM_BUILD_ROOT}%{_libdir}/libthrift.so.0 ln -s libthriftnb-%{version}.so ${RPM_BUILD_ROOT}%{_libdir}/libthriftnb.so.0 ln -s libthriftz-%{version}.so ${RPM_BUILD_ROOT}%{_libdir}/libthriftz.so.0 %if 0%{!?without_java:1} mkdir -p $RPM_BUILD_ROOT%{_javadir} cp -p lib/java/build/*.jar $RPM_BUILD_ROOT%{_javadir} %endif %if 0%{!?without_python:1} cd lib/py %{__python} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT cd ../.. %endif %if 0%{!?without_ruby:1} mkdir -p %{buildroot}%{gem_dir} cp -a ./%{gem_dir}/* %{buildroot}%{gem_dir}/ %endif %clean rm -rf ${RPM_BUILD_ROOT} %post umask 007 /sbin/ldconfig > /dev/null 2>&1 %postun umask 007 /sbin/ldconfig > /dev/null 2>&1 %changelog * Wed Aug 21 2013 Thrift Dev - Thrift 0.9.1 release. * Wed Oct 10 2012 Thrift Dev - Thrift 0.9.0 release. thrift-0.23.0/contrib/thrift.vim0000664000175000017500000000543615165535636017062 0ustar00buildbuild00000000000000" Vim syntax file " Language: Thrift " Maintainer: Martin Smith " Last Change: $Date: $ " Copy to ~/.vim/ " Add to ~/.vimrc " au BufRead,BufNewFile *.thrift set filetype=thrift " au! Syntax thrift source ~/.vim/thrift.vim " " $Id: $ " " 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. " if version < 600 syntax clear elseif exists("b:current_syntax") finish endif " Todo syn keyword thriftTodo TODO todo FIXME fixme XXX xxx contained " Comments syn match thriftComment "#.*" contains=thriftTodo syn region thriftComment start="/\*" end="\*/" contains=thriftTodo syn match thriftComment "//.\{-}\(?>\|$\)\@=" " String syn region thriftStringDouble matchgroup=None start=+"+ end=+"+ " Number syn match thriftNumber "-\=\<\d\+\>" contained " Keywords syn keyword thriftKeyword namespace syn keyword thriftKeyword xsd_all xsd_optional xsd_nillable xsd_attrs syn keyword thriftKeyword include cpp_include cpp_type const optional required syn keyword thriftBasicTypes void bool byte i8 i16 i32 i64 double string binary syn keyword thriftStructure map list set struct typedef exception enum throws union " Special syn match thriftSpecial "\d\+:" " Structure syn keyword thriftStructure service oneway extends "async" { return tok_async; } "exception" { return tok_xception; } "extends" { return tok_extends; } "throws" { return tok_throws; } "service" { return tok_service; } "enum" { return tok_enum; } "const" { return tok_const; } if version >= 508 || !exists("did_thrift_syn_inits") if version < 508 let did_thrift_syn_inits = 1 command! -nargs=+ HiLink hi link else command! -nargs=+ HiLink hi def link endif HiLink thriftComment Comment HiLink thriftKeyword Special HiLink thriftBasicTypes Type HiLink thriftStructure StorageClass HiLink thriftTodo Todo HiLink thriftString String HiLink thriftNumber Number HiLink thriftSpecial Special HiLink thriftStructure Structure delcommand HiLink endif let b:current_syntax = "thrift" thrift-0.23.0/contrib/thrift.el0000664000175000017500000001236115165535636016662 0ustar00buildbuild00000000000000;;; thrift.el --- Major mode for Apache Thrift files ;; Keywords: files ;; 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. ;; ;;; Commentary: ;; ;;; Code: (require 'font-lock) (defvar thrift-mode-hook nil) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.thrift\\'" . thrift-mode)) (defvar thrift-indent-level 2 "Defines 2 spaces for thrift indentation.") ;; syntax coloring (defconst thrift-font-lock-keywords (list '("\\<\\(include\\|struct\\|exception\\|typedef\\|const\\|enum\\|service\\|extends\\|void\\|oneway\\|throws\\|optional\\|required\\)\\>" . font-lock-keyword-face) ;; keywords '("\\<\\(bool\\|byte\\|i16\\|i32\\|i64\\|double\\|string\\|binary\\|map\\|list\\|set\\)\\>" . font-lock-type-face) ;; built-in types '("\\<\\([0-9]+\\)\\>" . font-lock-variable-name-face) ;; ordinals '("\\<\\(\\w+\\)\\s-*(" (1 font-lock-function-name-face)) ;; functions ) "Thrift Keywords.") ;; indentation (defun thrift-indent-line () "Indent current line as Thrift code." (interactive) (beginning-of-line) (if (bobp) (indent-line-to 0) (let ((not-indented t) cur-indent) (if (looking-at "^[ \t]*\\(}\\|throws\\)") (if (looking-at "^[ \t]*}") (progn (save-excursion (forward-line -1) (setq cur-indent (- (current-indentation) thrift-indent-level))) (if (< cur-indent 0) (setq cur-indent 0))) (progn (save-excursion (forward-line -1) (if (looking-at "^[ \t]*[\\.<>[:word:]]+[ \t]+[\\.<>[:word:]]+[ \t]*(") (setq cur-indent (+ (current-indentation) thrift-indent-level)) (setq cur-indent (current-indentation)))))) (save-excursion (while not-indented (forward-line -1) (if (looking-at "^[ \t]*}") (progn (setq cur-indent (current-indentation)) (setq not-indented nil)) (if (looking-at "^.*{[^}]*$") (progn (setq cur-indent (+ (current-indentation) thrift-indent-level)) (setq not-indented nil)) (if (bobp) (setq not-indented nil))) (if (looking-at "^[ \t]*throws") (progn (setq cur-indent (- (current-indentation) thrift-indent-level)) (if (< cur-indent 0) (setq cur-indent 0)) (setq not-indented nil)) (if (bobp) (setq not-indented nil))) (if (looking-at "^[ \t]*[\\.<>[:word:]]+[ \t]+[\\.<>[:word:]]+[ \t]*([^)]*$") (progn (setq cur-indent (+ (current-indentation) thrift-indent-level)) (setq not-indented nil)) (if (bobp) (setq not-indented nil))) (if (looking-at "^[ \t]*\\/\\*") (progn (setq cur-indent (+ (current-indentation) 1)) (setq not-indented nil)) (if (bobp) (setq not-indented nil))) (if (looking-at "^[ \t]*\\*\\/") (progn (setq cur-indent (- (current-indentation) 1)) (setq not-indented nil)) (if (bobp) (setq not-indented nil))) )))) (if cur-indent (indent-line-to cur-indent) (indent-line-to 0))))) ;; C/C++- and sh-style comments; also allowing underscore in words (defvar thrift-mode-syntax-table (let ((thrift-mode-syntax-table (make-syntax-table))) (modify-syntax-entry ?_ "w" thrift-mode-syntax-table) (modify-syntax-entry ?# "<" thrift-mode-syntax-table) ; sh-style comments (modify-syntax-entry ?/ ". 124" thrift-mode-syntax-table) ; c/c++-style comments (modify-syntax-entry ?* ". 23b" thrift-mode-syntax-table) (modify-syntax-entry ?\n ">" thrift-mode-syntax-table) thrift-mode-syntax-table) "Syntax table for thrift-mode") ;;;###autoload (defun thrift-mode () "Mode for editing Thrift files." (interactive) (kill-all-local-variables) (set-syntax-table thrift-mode-syntax-table) (set (make-local-variable 'font-lock-defaults) '(thrift-font-lock-keywords)) (setq major-mode 'thrift-mode) (setq mode-name "Thrift") (run-hooks 'thrift-mode-hook) (set (make-local-variable 'indent-line-function) 'thrift-indent-line) ) (provide 'thrift) ;;; thrift.el ends here thrift-0.23.0/contrib/thrift_dump.cpp0000664000175000017500000000514215165535636020070 0ustar00buildbuild00000000000000/* * 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 #include #include using namespace std; using boost::shared_ptr; using namespace apache::thrift::transport; using namespace apache::thrift::protocol; void usage() { fprintf(stderr, "usage: thrift_dump {-b|-f|-s} < input > ouput\n" " -b TBufferedTransport messages\n" " -f TFramedTransport messages\n" " -s Raw structures\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { if (argc != 2) { usage(); } shared_ptr stdin_trans(new TFDTransport(STDIN_FILENO)); shared_ptr itrans; if (argv[1] == std::string("-b") || argv[1] == std::string("-s")) { itrans.reset(new TBufferedTransport(stdin_trans)); } else if (argv[1] == std::string("-f")) { itrans.reset(new TFramedTransport(stdin_trans)); } else { usage(); } shared_ptr iprot(new TBinaryProtocol(itrans)); shared_ptr oprot( new TDebugProtocol( shared_ptr(new TBufferedTransport( shared_ptr(new TFDTransport(STDOUT_FILENO)))))); TProtocolTap tap(iprot, oprot); try { if (argv[1] == std::string("-s")) { for (;;) { tap.skip(T_STRUCT); } } else { std::string name; TMessageType messageType; int32_t seqid; for (;;) { tap.readMessageBegin(name, messageType, seqid); tap.skip(T_STRUCT); tap.readMessageEnd(); } } } catch (TProtocolException exn) { cout << "Protocol Exception: " << exn.what() << '\n'; } catch (...) { oprot->getTransport()->flush(); } cout << '\n'; return 0; } thrift-0.23.0/contrib/zeromq/0000775000175000017500000000000015167543515016347 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/zeromq/test-server.cpp0000664000175000017500000000173015165535636021342 0ustar00buildbuild00000000000000#include "zmq.hpp" #include "TZmqServer.h" #include "Storage.h" using apache::thrift::std::shared_ptr; using apache::thrift::TProcessor; using apache::thrift::server::TZmqServer; using apache::thrift::server::TZmqMultiServer; class StorageHandler : virtual public StorageIf { public: StorageHandler() : value_(0) {} void incr(const int32_t amount) { value_ += amount; } int32_t get() { return value_; } private: int32_t value_; }; int main(int argc, char *argv[]) { shared_ptr handler(new StorageHandler()); shared_ptr processor(new StorageProcessor(handler)); zmq::context_t ctx(1); TZmqServer reqrep_server(processor, ctx, "tcp://0.0.0.0:9090", ZMQ_REP); TZmqServer oneway_server(processor, ctx, "tcp://0.0.0.0:9091", ZMQ_PULL); TZmqMultiServer multiserver; multiserver.servers().push_back(&reqrep_server); multiserver.servers().push_back(&oneway_server); multiserver.serveForever(); return 0; } thrift-0.23.0/contrib/zeromq/test-receiver.cpp0000664000175000017500000000146115165535636021641 0ustar00buildbuild00000000000000#include "zmq.hpp" #include "TZmqServer.h" #include "Storage.h" using apache::thrift::std::shared_ptr; using apache::thrift::TProcessor; using apache::thrift::server::TZmqServer; using apache::thrift::server::TZmqMultiServer; class StorageHandler : virtual public StorageIf { public: StorageHandler() : value_(0) {} void incr(const int32_t amount) { value_ += amount; printf("value_: %i\n", value_) ; } int32_t get() { return value_; } private: int32_t value_; }; int main(int argc, char *argv[]) { shared_ptr handler(new StorageHandler()); shared_ptr processor(new StorageProcessor(handler)); zmq::context_t ctx(1); TZmqServer oneway_server(processor, ctx, "epgm://eth0;239.192.1.1:5555", ZMQ_SUB); oneway_server.serve(); return 0; } thrift-0.23.0/contrib/zeromq/TZmqClient.cpp0000664000175000017500000000273515165535636021117 0ustar00buildbuild00000000000000/* * 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 "TZmqClient.h" #include namespace apache { namespace thrift { namespace transport { uint32_t TZmqClient::read_virt(uint8_t* buf, uint32_t len) { if (rbuf_.available_read() == 0) { (void)sock_.recv(&msg_); rbuf_.resetBuffer((uint8_t*)msg_.data(), msg_.size()); } return rbuf_.read(buf, len); } void TZmqClient::write_virt(const uint8_t* buf, uint32_t len) { return wbuf_.write(buf, len); } uint32_t TZmqClient::writeEnd() { uint8_t* buf; uint32_t size; wbuf_.getBuffer(&buf, &size); zmq::message_t msg(size); std::memcpy(msg.data(), buf, size); (void)sock_.send(msg); wbuf_.resetBuffer(true); return size; } }}} // apache::thrift::transport thrift-0.23.0/contrib/zeromq/test-client.py0000775000175000017500000000145015165535636021162 0ustar00buildbuild00000000000000#!/usr/bin/env python import sys import time import zmq import TZmqClient import thrift.protocol.TBinaryProtocol import storage.ttypes import storage.Storage def main(args): endpoint = "tcp://127.0.0.1:9090" socktype = zmq.REQ incr = 0 if len(args) > 1: incr = int(args[1]) if incr: socktype = zmq.PUSH endpoint = "tcp://127.0.0.1:9091" ctx = zmq.Context() transport = TZmqClient.TZmqClient(ctx, endpoint, socktype) protocol = thrift.protocol.TBinaryProtocol.TBinaryProtocolAccelerated(transport) client = storage.Storage.Client(protocol) transport.open() if incr: client.incr(incr) time.sleep(0.05) else: value = client.get() print(value) if __name__ == "__main__": main(sys.argv) thrift-0.23.0/contrib/zeromq/TZmqServer.py0000664000175000017500000000522515165535636021012 0ustar00buildbuild00000000000000# # 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 logging import zmq import thrift.server.TServer import thrift.transport.TTransport class TZmqServer(thrift.server.TServer.TServer): def __init__(self, processor, ctx, endpoint, sock_type): thrift.server.TServer.TServer.__init__(self, processor, None) self.zmq_type = sock_type self.socket = ctx.socket(sock_type) self.socket.bind(endpoint) def serveOne(self): msg = self.socket.recv() itrans = thrift.transport.TTransport.TMemoryBuffer(msg) otrans = thrift.transport.TTransport.TMemoryBuffer() iprot = self.inputProtocolFactory.getProtocol(itrans) oprot = self.outputProtocolFactory.getProtocol(otrans) try: self.processor.process(iprot, oprot) except Exception: logging.exception("Exception while processing request") # Fall through and send back a response, even if empty or incomplete. if self.zmq_type == zmq.REP: msg = otrans.getvalue() self.socket.send(msg) def serve(self): while True: self.serveOne() class TZmqMultiServer(object): def __init__(self): self.servers = [] def serveOne(self, timeout=-1): self._serveActive(self._setupPoll(), timeout) def serveForever(self): poll_info = self._setupPoll() while True: self._serveActive(poll_info, -1) def _setupPoll(self): server_map = {} poller = zmq.Poller() for server in self.servers: server_map[server.socket] = server poller.register(server.socket, zmq.POLLIN) return (server_map, poller) def _serveActive(self, poll_info, timeout): (server_map, poller) = poll_info ready = dict(poller.poll()) for sock, state in ready.items(): assert (state & zmq.POLLIN) != 0 server_map[sock].serveOne() thrift-0.23.0/contrib/zeromq/test-sender.cpp0000664000175000017500000000135615165535636021320 0ustar00buildbuild00000000000000#include #include #include #include "zmq.hpp" #include "TZmqClient.h" #include "Storage.h" using apache::thrift::std::shared_ptr; using apache::thrift::transport::TZmqClient; using apache::thrift::protocol::TBinaryProtocol; int main(int argc, char** argv) { const char* endpoint = "epgm://eth0;239.192.1.1:5555"; int socktype = ZMQ_PUB; int incr = 1; if (argc > 1) { incr = atoi(argv[1]); } zmq::context_t ctx(1); shared_ptr transport(new TZmqClient(ctx, endpoint, socktype)); shared_ptr protocol(new TBinaryProtocol(transport)); StorageClient client(protocol); transport->open(); client.incr(incr); usleep(50000); return 0; } thrift-0.23.0/contrib/zeromq/TZmqServer.h0000664000175000017500000000411515165535636020606 0ustar00buildbuild00000000000000/* * 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_SERVER_TZMQSERVER_H_ #define _THRIFT_SERVER_TZMQSERVER_H_ 1 #include #include #include namespace apache { namespace thrift { namespace server { class TZmqServer : public TServer { public: TZmqServer( std::shared_ptr processor, zmq::context_t& ctx, const std::string& endpoint, int type) : TServer(processor) , processor_(processor) , zmq_type_(type) , sock_(ctx, type) { if(zmq_type_ == ZMQ_SUB) { sock_.setsockopt(ZMQ_SUBSCRIBE, "", 0) ; // listen to all messages sock_.connect(endpoint.c_str()) ; } else { sock_.bind(endpoint.c_str()); } } bool serveOne(int recv_flags = 0); void serve() { while (true) { serveOne(); } } zmq::socket_t& getSocket() { return sock_; } private: std::shared_ptr processor_; int zmq_type_; zmq::socket_t sock_; }; class TZmqMultiServer { public: void serveOne(long timeout = -1); void serveForever(); std::vector& servers() { return servers_; } private: zmq::pollitem_t* setupPoll(); void serveActive(zmq::pollitem_t* items, long timeout); std::vector servers_; }; }}} // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TZMQSERVER_H_ thrift-0.23.0/contrib/zeromq/README.md0000664000175000017500000000365215165535636017637 0ustar00buildbuild00000000000000This directory contains some glue code to allow Thrift RPCs to be sent over ZeroMQ. Included are client and server implementations for Python and C++, along with a simple demo interface (with a working client and server for each language). Thrift was designed for stream-based interfaces like TCP, but ZeroMQ is message-based, so there is a small impedance mismatch. Most of issues are hidden from developers, but one cannot be: oneway methods have to be handled differently from normal ones. ZeroMQ requires the messaging pattern to be declared at socket creation time, so an application cannot decide on a message-by-message basis whether to send a reply. Therefore, this implementation makes it the client's responsibility to ensure that ZMQ_REQ sockets are used for normal methods and ZMQ_DOWNSTREAM sockets are used for oneway methods. In addition, services that expose both types of methods have to expose two servers (on two ports), but the TZmqMultiServer makes it easy to run the two together in the same thread. This code was tested with ZeroMQ 2.0.7 and pyzmq afabbb5b9bd3. To build, simply install Thrift and ZeroMQ, then run "make". If you install in a non-standard location, make sure to set THRIFT to the location of the Thrift code generator on the make command line and PKG_CONFIG_PATH to a path that includes the pkgconfig files for both Thrift and ZeroMQ. The test servers take no arguments. Run the test clients with no arguments to retrieve the stored value or with an integer argument to increment it by that amount. This code is not quite what I would consider production-ready. It doesn't support all of the normal hooks into Thrift, and its performance is sub-optimal because it does some unnecessary copying. Deprecation notice: Csharp is not a supported Apache Thrift target anymore. Instead netstd is the recommended replacement. This code is left "as is" for educational purposes unless someone converts it to netstd thrift-0.23.0/contrib/zeromq/Makefile0000664000175000017500000000175115165535636020016 0ustar00buildbuild00000000000000THRIFT = thrift CXXFLAGS += -g3 -O0 GENNAMES = Storage storage_types GENHEADERS = $(addsuffix .h, $(GENNAMES)) GENSRCS = $(addsuffix .cpp, $(GENNAMES)) GENOBJS = $(addsuffix .o, $(GENNAMES)) PYLIBS = storage/__init__.py PROGS = test-client test-server test-sender test-receiver all: $(PYLIBS) $(PROGS) test-client: test-client.o TZmqClient.o $(GENOBJS) $(CXX) $^ -o $@ -lzmq -lthrift test-server: test-server.o TZmqServer.o $(GENOBJS) $(CXX) $^ -o $@ -lzmq -lthrift test-sender: test-sender.o TZmqClient.o $(GENOBJS) $(CXX) $^ -o $@ -lzmq -lthrift test-receiver: test-receiver.o TZmqServer.o $(GENOBJS) $(CXX) $^ -o $@ -lzmq -lthrift test-client.o test-server.o test-sender.o test-receiver.o: $(GENSRCS) storage/__init__.py: storage.thrift $(RM) $(dir $@) $(THRIFT) --gen py $< mv gen-py/$(dir $@) . $(GENSRCS): storage.thrift $(THRIFT) --gen cpp $< mv $(addprefix gen-cpp/, $(GENSRCS) $(GENHEADERS)) . clean: $(RM) -r *.o $(PROGS) storage $(GENSRCS) $(GENHEADERS) .PHONY: clean thrift-0.23.0/contrib/zeromq/test-server.py0000775000175000017500000000306715167543515021215 0ustar00buildbuild00000000000000#!/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. # import zmq import TZmqServer import storage.ttypes import storage.Storage class StorageHandler(storage.Storage.Iface): def __init__(self): self.value = 0 def incr(self, amount): self.value += amount def get(self): return self.value def main(): handler = StorageHandler() processor = storage.Storage.Processor(handler) ctx = zmq.Context() reqrep_server = TZmqServer.TZmqServer(processor, ctx, "tcp://0.0.0.0:9090", zmq.REP) oneway_server = TZmqServer.TZmqServer(processor, ctx, "tcp://0.0.0.0:9091", zmq.PULL) multiserver = TZmqServer.TZmqMultiServer() multiserver.servers.append(reqrep_server) multiserver.servers.append(oneway_server) multiserver.serveForever() if __name__ == "__main__": main() thrift-0.23.0/contrib/zeromq/TZmqServer.cpp0000664000175000017500000000554115165535636021145 0ustar00buildbuild00000000000000/* * 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 "TZmqServer.h" #include #include using apache::thrift::std::shared_ptr; using apache::thrift::transport::TMemoryBuffer; using apache::thrift::protocol::TProtocol; namespace apache { namespace thrift { namespace server { bool TZmqServer::serveOne(int recv_flags) { zmq::message_t msg; bool received = sock_.recv(&msg, recv_flags); if (!received) { return false; } shared_ptr inputTransport(new TMemoryBuffer((uint8_t*)msg.data(), msg.size())); shared_ptr outputTransport(new TMemoryBuffer()); shared_ptr inputProtocol( inputProtocolFactory_->getProtocol(inputTransport)); shared_ptr outputProtocol( outputProtocolFactory_->getProtocol(outputTransport)); shared_ptr transport(new TMemoryBuffer); processor_->process(inputProtocol, outputProtocol, nullptr); if (zmq_type_ == ZMQ_REP) { uint8_t* buf; uint32_t size; outputTransport->getBuffer(&buf, &size); msg.rebuild(size); std::memcpy(msg.data(), buf, size); (void)sock_.send(msg); } return true; } void TZmqMultiServer::serveOne(long timeout) { boost::scoped_ptr items(setupPoll()); serveActive(items.get(), timeout); } void TZmqMultiServer::serveForever() { boost::scoped_ptr items(setupPoll()); while (true) { serveActive(items.get(), -1); } } zmq::pollitem_t* TZmqMultiServer::setupPoll() { zmq::pollitem_t* items = new zmq::pollitem_t[servers_.size()]; for (int i = 0; i < servers_.size(); ++i) { items[i].socket = servers_[i]->getSocket(); items[i].events = ZMQ_POLLIN; } return items; } void TZmqMultiServer::serveActive(zmq::pollitem_t* items, long timeout) { int rc = zmq::poll(items, servers_.size(), timeout); if (rc == 0) { return; } for (int i = 0; i < servers_.size(); ++i) { if ((items[i].revents & ZMQ_POLLIN) != 0) { // Should we pass ZMQ_NOBLOCK here to be safe? servers_[i]->serveOne(); } } } }}} // apache::thrift::server thrift-0.23.0/contrib/zeromq/storage.thrift0000664000175000017500000000155115165535636021242 0ustar00buildbuild00000000000000/* * 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. */ service Storage { oneway void incr(1: i32 amount); i32 get(); } thrift-0.23.0/contrib/zeromq/test-client.cpp0000664000175000017500000000163615165535636021317 0ustar00buildbuild00000000000000#include #include #include #include "zmq.hpp" #include "TZmqClient.h" #include "Storage.h" using apache::thrift::std::shared_ptr; using apache::thrift::transport::TZmqClient; using apache::thrift::protocol::TBinaryProtocol; int main(int argc, char** argv) { const char* endpoint = "tcp://127.0.0.1:9090"; int socktype = ZMQ_REQ; int incr = 0; if (argc > 1) { incr = atoi(argv[1]); if (incr) { socktype = ZMQ_PUSH; endpoint = "tcp://127.0.0.1:9091"; } } zmq::context_t ctx(1); shared_ptr transport(new TZmqClient(ctx, endpoint, socktype)); shared_ptr protocol(new TBinaryProtocol(transport)); StorageClient client(protocol); transport->open(); if (incr) { client.incr(incr); usleep(50000); } else { int value = client.get(); std::cout << value << '\n'; } return 0; } thrift-0.23.0/contrib/zeromq/csharp/0000775000175000017500000000000015170007142017610 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/zeromq/csharp/ThriftZMQ.sln0000775000175000017500000000471615165535636022213 0ustar00buildbuild00000000000000 Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftZMQ", "ThriftZMQ.csproj", "{17C63B90-DFD7-42AC-A7B0-749E6876C0A1}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "..\..\..\lib\csharp\src\Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|Mixed Platforms = Release|Mixed Platforms Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Any CPU.ActiveCfg = Debug|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|Mixed Platforms.Build.0 = Debug|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.ActiveCfg = Debug|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Debug|x86.Build.0 = Debug|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Any CPU.ActiveCfg = Release|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.ActiveCfg = Release|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|Mixed Platforms.Build.0 = Release|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.ActiveCfg = Release|x86 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1}.Release|x86.Build.0 = Release|x86 {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|x86.ActiveCfg = Debug|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Mixed Platforms.Build.0 = Release|Any CPU {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal thrift-0.23.0/contrib/zeromq/csharp/AssemblyInfo.cs0000664000175000017500000000347615170007142022544 0ustar00buildbuild00000000000000/** * 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; // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. [assembly: AssemblyTitle("ZmqServer")] [assembly: AssemblyDescription("Zmq Examples")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("The Apache Software Foundation")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. [assembly: AssemblyVersion("0.23.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. //[assembly: AssemblyDelaySign(false)] //[assembly: AssemblyKeyFile("")] thrift-0.23.0/contrib/zeromq/csharp/TZmqClient.cs0000664000175000017500000000340315165535636022213 0ustar00buildbuild00000000000000using System; using ZMQ; using System.IO; using Thrift.Transport; namespace ZmqClient { public class TZmqClient : TTransport { Socket _sock; String _endpoint; MemoryStream _wbuf = new MemoryStream (); MemoryStream _rbuf = new MemoryStream (); void debug (string msg) { //Uncomment to enable debug // Console.WriteLine (msg); } public TZmqClient (Context ctx, String endpoint, SocketType sockType) { _sock = ctx.Socket (sockType); _endpoint = endpoint; } public override void Open () { _sock.Connect (_endpoint); } public override void Close () { throw new NotImplementedException (); } public override bool IsOpen { get { throw new NotImplementedException (); } } public override int Read (byte[] buf, int off, int len) { debug ("Client_Read"); if (off != 0 || len != buf.Length) throw new NotImplementedException (); if (_rbuf.Length == 0) { //Fill the Buffer with the complete ZMQ Message which needs to be(?!) the complete Thrift response debug ("Client_Read Filling buffer.."); byte[] tmpBuf = _sock.Recv (); debug (string.Format("Client_Read filled with {0}b",tmpBuf.Length)); _rbuf.Write (tmpBuf, 0, tmpBuf.Length); _rbuf.Position = 0; //For reading } int ret = _rbuf.Read (buf, 0, len); if (_rbuf.Length == _rbuf.Position) //Finished reading _rbuf.SetLength (0); debug (string.Format ("Client_Read return {0}b, remaining {1}b", ret, _rbuf.Length - _rbuf.Position)); return ret; } public override void Write (byte[] buf, int off, int len) { debug ("Client_Write"); _wbuf.Write (buf, off, len); } public override void Flush () { debug ("Client_Flush"); _sock.Send (_wbuf.GetBuffer ()); _wbuf = new MemoryStream (); } } } thrift-0.23.0/contrib/zeromq/csharp/ThriftZMQ.csproj0000775000175000017500000000741015165535636022711 0ustar00buildbuild00000000000000 Debug x86 9.0.21022 2.0 {17C63B90-DFD7-42AC-A7B0-749E6876C0A1} Exe ZmqServer ThriftZMQ v3.5 3.5 publish\ true Disk false Foreground 7 Days false false true 0 1.0.0.0 false false true true full false bin\Debug DEBUG prompt 4 x86 true AllRules.ruleset none false bin\Release prompt 4 x86 true AllRules.ruleset False .\clrzmq.dll False ..\..\..\lib\csharp\Thrift.dll False .NET Framework 3.5 SP1 Client Profile false False .NET Framework 3.5 SP1 true False Windows Installer 3.1 true thrift-0.23.0/contrib/zeromq/csharp/Main.cs0000664000175000017500000000226515165535636021052 0ustar00buildbuild00000000000000using System; using System.Threading; using Thrift.Protocol; using ZMQ; using ZmqServer; using ZmqClient; namespace ZmqServer { class MainClass { public static void Main (string[] args) { new Thread(Server.serve).Start(); Client.work(); } static class Server{ public static void serve(){ StorageHandler s=new StorageHandler(); Storage.Processor p=new Storage.Processor(s); ZMQ.Context c=new ZMQ.Context(); TZmqServer tzs=new TZmqServer(p,c,"tcp://127.0.0.1:9090",ZMQ.SocketType.PAIR); tzs.Serve(); } class StorageHandler:Storage.Iface{ int val=0; public void incr(int amount){ val+=amount; Console.WriteLine("incr({0})",amount); } public int get(){ return val; } } } static class Client{ public static void work() { Context ctx=new Context(); TZmqClient tzc=new TZmqClient(ctx,"tcp://127.0.0.1:9090",SocketType.PAIR); TBinaryProtocol p=new TBinaryProtocol(tzc); Storage.Client client=new Storage.Client(p); tzc.Open(); Console.WriteLine(client.@get()); client.incr(1); client.incr(41); Console.WriteLine(client.@get()); } } } } thrift-0.23.0/contrib/zeromq/csharp/TZmqServer.cs0000664000175000017500000000232115165535636022241 0ustar00buildbuild00000000000000using System; using Thrift; using Thrift.Server; using Thrift.Transport; using Thrift.Protocol; using ZMQ; using System.IO; using System.Collections.Generic; namespace ZmqServer { public class TZmqServer { Socket _socket ; TProcessor _processor; void debug (string msg) { //Uncomment to enable debug // Console.WriteLine (msg); } public TZmqServer (TProcessor processor, Context ctx, String endpoint, SocketType sockType) { new TSimpleServer (processor,null); _socket = ctx.Socket (sockType); _socket.Bind (endpoint); _processor = processor; } public void ServeOne () { debug ("Server_ServeOne"); Byte[] msg = _socket.Recv (); MemoryStream istream = new MemoryStream (msg); MemoryStream ostream = new MemoryStream (); TProtocol tProtocol = new TBinaryProtocol (new TStreamTransport (istream, ostream)); _processor.Process (tProtocol, tProtocol); if (ostream.Length != 0) { byte[] newBuf = new byte[ostream.Length]; Array.Copy (ostream.GetBuffer (), newBuf, ostream.Length); debug (string.Format ("Server_ServeOne sending {0}b", ostream.Length)); _socket.Send (newBuf); } } public void Serve () { while (true) ServeOne (); } } } thrift-0.23.0/contrib/zeromq/TZmqClient.h0000664000175000017500000000335315165535636020561 0ustar00buildbuild00000000000000/* * 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_TRANSPORT_TZMQCLIENT_H_ #define _THRIFT_TRANSPORT_TZMQCLIENT_H_ 1 #include #include namespace apache { namespace thrift { namespace transport { class TZmqClient : public TTransport { public: TZmqClient(zmq::context_t& ctx, const std::string& endpoint, int type) : sock_(ctx, type) , endpoint_(endpoint) , wbuf_() , rbuf_() , msg_() , zmq_type_(type) {} void open() { if(zmq_type_ == ZMQ_PUB) { sock_.bind(endpoint_.c_str()); } else { sock_.connect(endpoint_.c_str()); } } uint32_t read_virt(uint8_t* buf, uint32_t len); void write_virt(const uint8_t* buf, uint32_t len); uint32_t writeEnd(); protected: zmq::socket_t sock_; std::string endpoint_; TMemoryBuffer wbuf_; TMemoryBuffer rbuf_; zmq::message_t msg_; int zmq_type_; }; }}} // apache::thrift::transport #endif // #ifndef _THRIFT_TRANSPORT_TZMQCLIENT_H_ thrift-0.23.0/contrib/zeromq/TZmqClient.py0000664000175000017500000000401315165535636020754 0ustar00buildbuild00000000000000# # 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 zmq from cStringIO import StringIO from thrift.transport.TTransport import TTransportBase, CReadableTransport class TZmqClient(TTransportBase, CReadableTransport): def __init__(self, ctx, endpoint, sock_type): self._sock = ctx.socket(sock_type) self._endpoint = endpoint self._wbuf = StringIO() self._rbuf = StringIO() def open(self): self._sock.connect(self._endpoint) def read(self, size): ret = self._rbuf.read(size) if len(ret) != 0: return ret self._read_message() return self._rbuf.read(size) def _read_message(self): msg = self._sock.recv() self._rbuf = StringIO(msg) def write(self, buf): self._wbuf.write(buf) def flush(self): msg = self._wbuf.getvalue() self._wbuf = StringIO() self._sock.send(msg) # Implement the CReadableTransport interface. @property def cstringio_buf(self): return self._rbuf # NOTE: This will probably not actually work. def cstringio_refill(self, prefix, reqlen): while len(prefix) < reqlen: self.read_message() prefix += self._rbuf.getvalue() self._rbuf = StringIO(prefix) return self._rbuf thrift-0.23.0/contrib/fb303/0000775000175000017500000000000015165535636015652 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/TClientInfo.cpp0000664000175000017500000001216715165535636020543 0ustar00buildbuild00000000000000/* * 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 namespace apache { namespace thrift { namespace server { using namespace apache::thrift; using namespace apache::thrift::transport; TClientInfoConnection::TClientInfoConnection() { call_[kNameLen - 1] = '\0'; // insure NUL terminator is there eraseAddr(); eraseCall(); } void TClientInfoConnection::recordAddr(const sockaddr* addr) { eraseAddr(); initTime(); ncalls_ = 0; if (addr != nullptr) { if (addr->sa_family == AF_INET) { memcpy((void*)&addr_.ipv4, (const void *)addr, sizeof(sockaddr_in)); } else if (addr->sa_family == AF_INET6) { memcpy((void*)&addr_.ipv6, (const void *)addr, sizeof(sockaddr_in6)); } } } void TClientInfoConnection::eraseAddr() { addr_.ipv4.sin_family = AF_UNSPEC; } const char* TClientInfoConnection::getAddr(char* buf, int len) const { switch (addr_.ipv4.sin_family) { case AF_INET: return inet_ntop(AF_INET, &addr_.ipv4.sin_addr, buf, len); case AF_INET6: return inet_ntop(AF_INET6, &addr_.ipv6.sin6_addr, buf, len); default: return nullptr; } } void TClientInfoConnection::recordCall(const char* name) { strncpy(call_, name, kNameLen - 1); // NUL terminator set in constructor ncalls_++; } void TClientInfoConnection::eraseCall() { call_[0] = '\0'; } const char* TClientInfoConnection::getCall() const { if (call_[0] == '\0') { return nullptr; } return call_; } void TClientInfoConnection::getTime(timespec* time) const { *time = time_; } uint64_t TClientInfoConnection::getNCalls() const { return ncalls_; } void TClientInfoConnection::initTime() { clock_gettime(CLOCK_REALTIME, &time_); } TClientInfoConnection* TClientInfo::getConnection(int fd, bool grow) { if (fd < 0 || (!grow && fd >= info_.size())) { return nullptr; } return &info_[fd]; } size_t TClientInfo::size() const { return info_.size(); } void* TClientInfoServerHandler::createContext(boost::shared_ptr input, boost::shared_ptr output) { (void)input; (void)output; return (void*) new Connect(&clientInfo_); } void TClientInfoServerHandler::deleteContext(void* connectionContext, boost::shared_ptr input, boost::shared_ptr output) { Connect* call = static_cast(connectionContext); if (call->callInfo_) { call->callInfo_->eraseCall(); } delete call; } void TClientInfoServerHandler::processContext(void* connectionContext, shared_ptr transport) { Connect* call = static_cast(connectionContext); if (call->callInfo_ == nullptr) { if (typeid(*(transport.get())) == typeid(TSocket)) { TSocket* tsocket = static_cast(transport.get()); int fd = tsocket->getSocketFD(); if (fd < 0) { return; } call->callInfo_ = call->clientInfo_->getConnection(fd, true); assert(call->callInfo_ != nullptr); socklen_t len; call->callInfo_->recordAddr(tsocket->getCachedAddress(&len)); } } } void TClientInfoServerHandler::getStatsStrings(vector& result) { result.clear(); timespec now; clock_gettime(CLOCK_REALTIME, &now); for (int i = 0; i < clientInfo_.size(); ++i) { TClientInfoConnection* info = clientInfo_.getConnection(i, false); const char* callStr = info->getCall(); if (callStr == nullptr) { continue; } char addrBuf[INET6_ADDRSTRLEN]; const char* addrStr = info->getAddr(addrBuf, sizeof addrBuf); if (addrStr == nullptr) { // cerr << "no addr!" << '\n'; continue; } timespec start; info->getTime(&start); double secs = (double)(now.tv_sec - start.tv_sec) + (now.tv_nsec - start.tv_nsec)*0.000000001; char buf[256]; snprintf(buf, sizeof buf, "%d %s %s %.3f %llu", i, addrStr, callStr, secs, (uint64_t)info->getNCalls()); result.push_back(buf); } } void* TClientInfoCallHandler::getContext(const char* fn_name, void* serverContext) { if (serverContext) { TClientInfoConnection* callInfo = static_cast(serverContext)->callInfo_; if (callInfo != nullptr) { callInfo->recordCall(fn_name); } } return nullptr; } } } } // namespace apache::thrift::server thrift-0.23.0/contrib/fb303/if/0000775000175000017500000000000015165535636016250 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/if/fb303.thrift0000664000175000017500000000465415165535636020320 0ustar00buildbuild00000000000000/* * 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. */ /** * fb303.thrift */ namespace java com.facebook.fb303 namespace cpp facebook.fb303 namespace perl Facebook.FB303 namespace netstd Facebook.FB303.Test /** * Common status reporting mechanism across all services */ enum fb_status { DEAD = 0, STARTING = 1, ALIVE = 2, STOPPING = 3, STOPPED = 4, WARNING = 5, } /** * Standard base service */ service FacebookService { /** * Returns a descriptive name of the service */ string getName(), /** * Returns the version of the service */ string getVersion(), /** * Gets the status of this service */ fb_status getStatus(), /** * User friendly description of status, such as why the service is in * the dead or warning state, or what is being started or stopped. */ string getStatusDetails(), /** * Gets the counters for this service */ map getCounters(), /** * Gets the value of a single counter */ i64 getCounter(1: string key), /** * Sets an option */ void setOption(1: string key, 2: string value), /** * Gets an option */ string getOption(1: string key), /** * Gets all options */ map getOptions(), /** * Returns a CPU profile over the given time interval (client and server * must agree on the profile format). */ string getCpuProfile(1: i32 profileDurationInSec), /** * Returns the unix time that the server has been running since */ i64 aliveSince(), /** * Tell the server to reload its configuration, reopen log files, etc */ oneway void reinitialize(), /** * Suggest a shutdown to the server */ oneway void shutdown(), } thrift-0.23.0/contrib/fb303/global_header.mk0000664000175000017500000000234715165535636020761 0ustar00buildbuild00000000000000# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #define thrift_template # $(1) : $(2) # $$(THRIFT) $(3) $(4) $(5) $(6) $(7) $(8) $$< #endef define thrift_template XTARGET := $(shell perl -e '@val = split("\/","$(2)"); $$last = pop(@val);split("\\.",$$last);print "$(1)/"."gen-cpp/"."@_[0]"."_types.cpp\n"' ) ifneq ($$(XBUILT_SOURCES),) XBUILT_SOURCES := $$(XBUILT_SOURCES) $$(XTARGET) else XBUILT_SOURCES := $$(XTARGET) endif $$(XTARGET) : $(2) $$(THRIFT) -o $1 $3 $$< endef clean-common: rm -rf gen-* thrift-0.23.0/contrib/fb303/TClientInfo.h0000664000175000017500000002327515165535636020212 0ustar00buildbuild00000000000000/* * 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 _FACEBOOK_THRIFT_SERVER_TCLIENTINFO_H_ #define _FACEBOOK_THRIFT_SERVER_TCLIENTINFO_H_ 1 // for inet_ntop -- #include #include #include #include namespace apache { namespace thrift { namespace server { using namespace apache::thrift; using namespace apache::thrift::transport; using namespace apache::thrift::concurrency; using boost::shared_ptr; using std::string; using std::vector; /** * StableVector -- a minimal vector class where growth is automatic and * vector elements never move as the vector grows. Allocates new space * as needed, but does not copy old values. * * A level vector stores a list of storage vectors containing the actual * elements. Levels are added as needed, doubling in size each time. * Locking is only done when a level is added. Access is amortized * constant time. */ template class StableVector { /// The initial allocation as an exponent of 2 static const uint32_t kInitialSizePowOf2 = 10; /// The initial allocation size static const uint32_t kInitialVectorSize = 1 << kInitialSizePowOf2; /// This bound is guaranteed not to be exceeded on 64-bit archs static const int kMaxLevels = 64; /// Values are kept in one or more of these typedef vector Vect; /// One or more value vectors are kept in one of these typedef vector LevelVector; Mutex mutex_; /// current size size_t size_; _Atomic_word vectLvl_; LevelVector vects_; public: /** * Constructor -- initialize the level vector and allocate the * initial storage vector */ StableVector() : size_(0) , vectLvl_(0) { vects_.reserve(kMaxLevels); Vect* storageVector(new Vect(1 << kInitialSizePowOf2)); vects_.push_back(storageVector); } private: /** * make sure the requested number of storage levels have been allocated. */ void expand(uint32_t level) { // we need the guard to insure that we only allocate once. Guard g(mutex_); while (level > vectLvl_) { Vect* levelVect(new Vect(1 << (vectLvl_ + kInitialSizePowOf2))); vects_.push_back(levelVect); // we need to make sure this is done after levelVect is inserted // (what we want is effectively a memory barrier here). __gnu_cxx::__atomic_add(&vectLvl_, 1); } } /** * Given an index, determine which level and element of that level is * required. Grows if needed. */ void which(uint32_t n, uint32_t* vno, uint32_t* idx) { if (n >= size_) { size_ = n + 1; } if (n < kInitialVectorSize) { *idx = n; *vno = 0; } else { uint32_t upper = n >> kInitialSizePowOf2; *vno = CHAR_BIT*sizeof(upper) - __builtin_clz(upper); *idx = n - (1 << (*vno + kInitialSizePowOf2 - 1)); if (*vno > vectLvl_) { expand(*vno); } } } public: /** * Given an index, return a reference to that element, perhaps after * allocating additional space. * * @param n a positive integer */ T& operator[](uint32_t n) { uint32_t vno; uint32_t idx; which(n, &vno, &idx); return (*vects_[vno])[idx]; } /** * Return the present size of the vector. */ size_t size() const { return size_; } }; /** * This class embodies the representation of a single connection during * processing. We'll keep one of these per file descriptor in TClientInfo. */ class TClientInfoConnection { public: const static int kNameLen = 32; private: typedef union IPAddrUnion { sockaddr_in ipv4; sockaddr_in6 ipv6; }; char call_[kNameLen]; ///< The name of the thrift call IPAddrUnion addr_; ///< The client's IP address timespec time_; ///< Time processing started uint64_t ncalls_; ///< # of calls processed public: /** * Constructor; insure that no client address or thrift call name is * represented. */ TClientInfoConnection(); /** * A connection has been made; record its address. Since this is the * first we'll know of a connection we start the timer here as well. */ void recordAddr(const sockaddr* addr); /** * Mark the address as empty/unknown. */ void eraseAddr(); /** * Return a string representing the present address, or nullptr if none. * Copies the string into the buffer provided. */ const char* getAddr(char* buf, int len) const; /** * A call has been made on this connection; record its name. Since this is * called for every thrift call processed, we also do our call count here. */ void recordCall(const char* name); /** * Invoked when processing has ended to clear the call name. */ void eraseCall(); /** * Return as string the thrift call either currently being processed or * most recently processed if the connection is still open for additional * calls. Returns nullptr if a call hasn't been made yet or processing * has ended. */ const char* getCall() const; /** * Get the timespec for the start of this connection (specifically, when * recordAddr() was first called). */ void getTime(timespec* time) const; /** * Return the number of calls made on this connection. */ uint64_t getNCalls() const; private: void initTime(); }; /** * Store for info about a server's clients -- specifically, the client's IP * address and the call it is executing. This information is indexed by * socket file descriptor and in the present implementation is updated * asynchronously, so it may only approximate reality. */ class TClientInfo { private: StableVector info_; public: /** * Return the info object for a given file descriptor. If "grow" is true * extend the info vector if required (such as for a file descriptor not seen * before). If "grow" is false and the info vector isn't large enough, * or if "fd" is negative, return nullptr. */ TClientInfoConnection* getConnection(int fd, bool grow); size_t size() const; }; /** * This derivation of TServerEventHandler encapsulates the main status vector * and provides context to the server's processing loop via overrides. * Together with TClientInfoCallHandler (derived from TProcessorEventHandler) * it integrates client info collection into the server. */ class TClientInfoServerHandler : public TServerEventHandler { private: TClientInfo clientInfo_; public: /** * One of these is constructed for each open connection/descriptor and links * to both the status vector (clientInfo_) and that descriptor's entry * within it. */ struct Connect { TClientInfo* clientInfo_; TClientInfoConnection* callInfo_; explicit Connect(TClientInfo* clientInfo) : clientInfo_(clientInfo) , callInfo_(nullptr) { } }; /** * Generate processor context; we don't know what descriptor we belong to * yet -- we'll get hooked up in contextProcess(). */ void* createContext(boost::shared_ptr input, boost::shared_ptr output); /** * Mark our slot as unused and delete the context created in createContext(). */ void deleteContext(void* processorContext, boost::shared_ptr input, boost::shared_ptr output); /** * Called in the processing loop just before the server invokes the * processor itself, on the first call we establish which descriptor * we correspond to and set it to that socket's peer IP address. This * also has the side effect of initializing call counting and connection * timing. We won't know which call we're handling until the handler * first gets called in TClientInfoCallHandler::getContext(). */ void processContext(void* processorContext, shared_ptr transport); /** * Get status report for server in the form of a vector of strings. * Each active client appears as one string in the format: * * FD IPADDR CALLNAME DURATION NCALLS * * where "FD" is the file descriptor for the client's socket, "IPADDR" * is the IP address (as reported by accept()), "CALLNAME" is the * current or most recent Thrift function name, "DURATION" is the * duration of the connection, while NCALLS is the number of Thrift * calls made since the connection was made. A single space separates * fields. */ void getStatsStrings(vector& result); }; /** * This class derives from TProcessorEventHandler to gain access to the * function name for the current Thrift call. We need two versions of * this -- TClientInfoCallStatsHandler is the other -- since in the latter * case we pass through to TFunctionStatHandler to perform Thrift call * stats. */ class TClientInfoCallHandler : public TProcessorEventHandler { public: virtual void* getContext(const char* fn_name, void* serverContext); }; } } } // namespace apache::thrift::server #endif // !_FACEBOOK_THRIFT_SERVER_TCLIENTINFO_H_ thrift-0.23.0/contrib/fb303/LICENSE0000664000175000017500000000135515165535636016663 0ustar00buildbuild00000000000000Licensed 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. thrift-0.23.0/contrib/fb303/global_footer.mk0000664000175000017500000000146315165535636021025 0ustar00buildbuild00000000000000# # 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. # thriftstyle : $(XBUILT_SOURCES) thrift-0.23.0/contrib/fb303/bootstrap.sh0000775000175000017500000000160215165535636020225 0ustar00buildbuild00000000000000#!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # To be safe include -I flag aclocal -I ./aclocal automake -a autoconf ./configure --config-cache $* thrift-0.23.0/contrib/fb303/java/0000775000175000017500000000000015165535636016573 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/java/src/0000775000175000017500000000000015165535636017362 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/java/src/FacebookBase.java0000664000175000017500000000522215165535636022532 0ustar00buildbuild00000000000000/* * 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 com.facebook.fb303; import java.util.AbstractMap; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; public abstract class FacebookBase implements FacebookService.Iface { private String name_; private long alive_; private final ConcurrentHashMap counters_ = new ConcurrentHashMap(); private final ConcurrentHashMap options_ = new ConcurrentHashMap(); protected FacebookBase(String name) { name_ = name; alive_ = System.currentTimeMillis() / 1000; } public String getName() { return name_; } public abstract fb_status getStatus(); public String getStatusDetails() { return ""; } public void deleteCounter(String key) { counters_.remove(key); } public void resetCounter(String key) { counters_.put(key, 0L); } public long incrementCounter(String key) { long val = getCounter(key) + 1; counters_.put(key, val); return val; } public long incrementCounter(String key, long increment) { long val = getCounter(key) + increment; counters_.put(key, val); return val; } public long setCounter(String key, long value) { counters_.put(key, value); return value; } public AbstractMap getCounters() { return counters_; } public long getCounter(String key) { Long val = counters_.get(key); if (val == null) { return 0; } return val.longValue(); } public void setOption(String key, String value) { options_.put(key, value); } public String getOption(String key) { return options_.get(key); } public AbstractMap getOptions() { return options_; } public long aliveSince() { return alive_; } public String getCpuProfile() { return ""; } public void reinitialize() {} public void shutdown() {} } thrift-0.23.0/contrib/fb303/java/build.properties0000664000175000017500000000036415165535636022013 0ustar00buildbuild00000000000000# Maven Ant tasks Jar details mvn.ant.task.version=2.1.3 mvn.repo=https://repo1.maven.org/maven2 mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version} mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar thrift-0.23.0/contrib/fb303/java/build.xml0000664000175000017500000001776415165535636020433 0ustar00buildbuild00000000000000 thrift-0.23.0/contrib/fb303/py/0000775000175000017500000000000015167543515016277 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/py/fb303_scripts/0000775000175000017500000000000015167543515020663 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py0000664000175000017500000001347715167543515024463 0ustar00buildbuild00000000000000#!/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. # import sys import os from optparse import OptionParser from thrift.Thrift import * from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from fb303 import * from fb303.ttypes import * def service_ctrl( command, port, trans_factory=None, prot_factory=None): """ service_ctrl is a generic function to execute standard fb303 functions @param command: one of stop, start, reload, status, counters, name, alive @param port: service's port @param trans_factory: TTransportFactory to use for obtaining a TTransport. Default is TBufferedTransportFactory @param prot_factory: TProtocolFactory to use for obtaining a TProtocol. Default is TBinaryProtocolFactory """ if command in ["status"]: try: status = fb303_wrapper('status', port, trans_factory, prot_factory) status_details = fb303_wrapper('get_status_details', port, trans_factory, prot_factory) msg = fb_status_string(status) if (len(status_details)): msg += " - %s" % status_details print(msg) return 2 if status == fb_status.ALIVE else 3 except Exception: print("Failed to get status") return 3 # scalar commands if command in ["version", "alive", "name"]: try: result = fb303_wrapper(command, port, trans_factory, prot_factory) print(result) return 0 except Exception: print("failed to get ", command) return 3 # counters if command in ["counters"]: try: counters = fb303_wrapper('counters', port, trans_factory, prot_factory) for counter in counters: print("%s: %d" % (counter.encode('utf-8'), counters[counter])) return 0 except Exception: print("failed to get counters") return 3 # Only root should be able to run the following commands if os.getuid() == 0: # async commands if command in ["stop", "reload"]: try: fb303_wrapper(command, port, trans_factory, prot_factory) return 0 except Exception: print("failed to tell the service to ", command) return 3 else: if command in ["stop", "reload"]: print("root privileges are required to stop or reload the service.") return 4 print("The following commands are available:") for command in ["counters", "name", "version", "alive", "status"]: print("\t%s" % command) print("The following commands are available for users with root privileges:") for command in ["stop", "reload"]: print("\t%s" % command) return 0 def fb303_wrapper(command, port, trans_factory=None, prot_factory=None): sock = TSocket.TSocket('localhost', port) # use input transport factory if provided if (trans_factory is None): trans = TTransport.TBufferedTransport(sock) else: trans = trans_factory.getTransport(sock) # use input protocol factory if provided if (prot_factory is None): prot = TBinaryProtocol.TBinaryProtocol(trans) else: prot = prot_factory.getProtocol(trans) # initialize client and open transport fb303_client = FacebookService.Client(prot, prot) trans.open() if (command == 'reload'): fb303_client.reinitialize() elif (command == 'stop'): fb303_client.shutdown() elif (command == 'status'): return fb303_client.getStatus() elif (command == 'version'): return fb303_client.getVersion() elif (command == 'get_status_details'): return fb303_client.getStatusDetails() elif (command == 'counters'): return fb303_client.getCounters() elif (command == 'name'): return fb303_client.getName() elif (command == 'alive'): return fb303_client.aliveSince() trans.close() def fb_status_string(status_enum): if (status_enum == fb_status.DEAD): return "DEAD" if (status_enum == fb_status.STARTING): return "STARTING" if (status_enum == fb_status.ALIVE): return "ALIVE" if (status_enum == fb_status.STOPPING): return "STOPPING" if (status_enum == fb_status.STOPPED): return "STOPPED" if (status_enum == fb_status.WARNING): return "WARNING" def main(): # parse command line options parser = OptionParser() commands = ["stop", "counters", "status", "reload", "version", "name", "alive"] parser.add_option("-c", "--command", dest="command", help="execute this API", choices=commands, default="status") parser.add_option("-p", "--port", dest="port", help="the service's port", default=9082) (options, args) = parser.parse_args() status = service_ctrl(options.command, options.port) sys.exit(status) if __name__ == '__main__': main() thrift-0.23.0/contrib/fb303/py/fb303_scripts/__init__.py0000664000175000017500000000146215165535636023002 0ustar00buildbuild00000000000000# # 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. # __all__ = ['fb303_simple_mgmt'] thrift-0.23.0/contrib/fb303/py/fb303/0000775000175000017500000000000015165535636017117 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/py/fb303/FacebookBase.py0000664000175000017500000000376615165535636022011 0ustar00buildbuild00000000000000#!/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. # import time import FacebookService import thrift.reflection.limited from ttypes import fb_status class FacebookBase(FacebookService.Iface): def __init__(self, name): self.name = name self.alive = int(time.time()) self.counters = {} def getName(self, ): return self.name def getVersion(self, ): return '' def getStatus(self, ): return fb_status.ALIVE def getCounters(self): return self.counters def resetCounter(self, key): self.counters[key] = 0 def getCounter(self, key): if self.counters.has_key(key): return self.counters[key] return 0 def incrementCounter(self, key): self.counters[key] = self.getCounter(key) + 1 def setOption(self, key, value): pass def getOption(self, key): return "" def getOptions(self): return {} def getOptions(self): return {} def aliveSince(self): return self.alive def getCpuProfile(self, duration): return "" def getLimitedReflection(self): return thrift.reflection.limited.Service() def reinitialize(self): pass def shutdown(self): pass thrift-0.23.0/contrib/fb303/py/setup.py0000664000175000017500000000303715167543515020014 0ustar00buildbuild00000000000000#!/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. # import sys from setuptools import Extension, setup setup(name='thrift_fb303', version='1.0.0', description='Python bindings for the Apache Thrift FB303', author=['Apache Thrift Developers'], author_email=['dev@thrift.apache.org'], url='http://thrift.apache.org', license='Apache License 2.0', packages=[ 'fb303', 'fb303_scripts', ], classifiers=[ 'Development Status :: 7 - Inactive', 'Environment :: Console', 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Topic :: Software Development :: Libraries', 'Topic :: System :: Networking' ], ) thrift-0.23.0/contrib/fb303/py/Makefile.am0000664000175000017500000000265515165535636020346 0ustar00buildbuild00000000000000# # 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. # DESTDIR ?= / distdir: $(MAKE) $(AM_MAKEFLAGS) distdir-am EXTRA_DIST = setup.py src all: all-local: $(thrift_home)/bin/thrift --gen py $(top_srcdir)/if/fb303.thrift mv gen-py/fb303/* fb303 $(PYTHON) setup.py build # We're ignoring prefix here because site-packages seems to be # the equivalent of /usr/local/lib in Python land. # 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) clean: clean-local clean-local: $(RM) -r build check-local: all thrift-0.23.0/contrib/fb303/README.md0000664000175000017500000000235515165535636017136 0ustar00buildbuild00000000000000Project FB303: The Facebook Bassline ------------------------------------ * Curious about the 303? * http://en.wikipedia.org/wiki/Roland_TB-303 * Why the name? * The TB303 makes bass lines. .Bass is what lies underneath any strong tune. ..fb303 is the shared root of all thrift services. ...fb303 => FacebookBase303. * How do I use this? * Take a look at the examples to see how your backend project can and should inherit from this service. * What does it provide? * A standard interface to monitoring, dynamic options and configuration, uptime reports, activity, etc. * I want more. * Think carefully first about whether the functionality you are going to add belongs here or in your application. If it can be abstracted and is generally useful, then it probably belongs somewhere in the fb303 tree. Keep in mind, not every product has to use ALL the functionality of fb303, but every product CANNOT use functionality that is NOT in fb303. * Is this open source? * Yes. fb303 is distributed under the Thrift Software License. See the LICENSE file for more details. * Installation * fb303 is configured/built/installed similar to Thrift. See the README in the Thrift root directory for more information. * Who wrote this README? * mcslee@facebook.com thrift-0.23.0/contrib/fb303/php/0000775000175000017500000000000015165535636016441 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/php/FacebookBase.php0000664000175000017500000000353015165535636021457 0ustar00buildbuild00000000000000name_ = $name; } public function getName() { return $this->name_; } public function getVersion() { return ''; } public function getStatus() { return null; } public function getStatusDetails() { return ''; } public function getCounters() { return array(); } public function getCounter($key) { return null; } public function setOption($key, $value) { return; } public function getOption($key) { return ''; } public function getOptions() { return array(); } public function aliveSince() { return 0; } public function getCpuProfile($duration) { return ''; } public function getLimitedReflection() { return array(); } public function reinitialize() { return; } public function shutdown() { return; } } thrift-0.23.0/contrib/fb303/acinclude.m40000664000175000017500000001322315165535636020044 0ustar00buildbuild00000000000000dnl Copyright (C) 2009 Facebook dnl Copying and distribution of this file, with or without modification, dnl are permitted in any medium without royalty provided the copyright dnl notice and this notice are preserved. AC_DEFUN([FB_INITIALIZE], [ AM_INIT_AUTOMAKE([ foreign 1.9.5 no-define ]) if test "x$1" = "xlocalinstall"; then wdir=`pwd` # To use $wdir undef quote. # ########## AC_PREFIX_DEFAULT([`pwd`/install]) echo fi AC_PROG_CC AC_PROG_CXX AC_PROG_RANLIB(RANLIB, ranlib) AC_PATH_PROGS(BASH, bash) AC_PATH_PROGS(PERL, perl) AC_PATH_PROGS(PYTHON, python) AC_PATH_PROGS(AR, ar) AC_PATH_PROGS(ANT, ant) PRODUCT_MK="" ]) AC_DEFUN([FB_WITH_EXTERNAL_PATH], [ cdir=`pwd` AC_MSG_CHECKING([Checking EXTERNAL_PATH set to]) AC_ARG_WITH([externalpath], [ --with-externalpath=DIR User specified path to external facebook components.], [ if test "x${EXTERNAL_PATH}" != "x"; then echo "" echo "ERROR: You have already set EXTERNAL_PATH in your environment" echo "Cannot override it using --with-externalpath. Unset EXTERNAL_PATH to use this option" exit 1 fi EXTERNAL_PATH=$withval ], [ if test "x${EXTERNAL_PATH}" = "x"; then EXTERNAL_PATH=$1 fi ] ) if test "x${EXTERNAL_PATH}" = "x"; then export EXTERNAL_PATH="$cdir/external" GLOBAL_HEADER_MK="include ${EXTERNAL_PATH}/global_header.mk" GLOBAL_FOOTER_MK="include ${EXTERNAL_PATH}/global_footer.mk" else export EXTERNAL_PATH GLOBAL_HEADER_MK="include ${EXTERNAL_PATH}/global_header.mk" GLOBAL_FOOTER_MK="include ${EXTERNAL_PATH}/global_footer.mk" fi AC_MSG_RESULT($EXTERNAL_PATH) if test ! -d ${EXTERNAL_PATH}; then echo "" echo "ERROR: EXTERNAL_PATH set to an nonexistent directory ${EXTERNAL_PATH}" exit 1 fi AC_SUBST(EXTERNAL_PATH) AC_SUBST(GLOBAL_HEADER_MK) AC_SUBST(GLOBAL_FOOTER_MK) ]) # Set option to enable shared mode. Set DEBUG and OPT for use in Makefile.am. AC_DEFUN([FB_ENABLE_DEFAULT_OPT_BUILD], [ AC_MSG_CHECKING([whether to enable optimized build]) AC_ARG_ENABLE([opt], [ --disable-opt Set up debug mode.], [ ENABLED_OPT=$enableval ], [ ENABLED_OPT="yes" ] ) if test "$ENABLED_OPT" = "yes" then CFLAGS="-Wall -O3" CXXFLAGS="-Wall -O3" else CFLAGS="-Wall -g" CXXFLAGS="-Wall -g" fi AC_MSG_RESULT($ENABLED_OPT) AM_CONDITIONAL([OPT], [test "$ENABLED_OPT" = yes]) AM_CONDITIONAL([DEBUG], [test "$ENABLED_OPT" = no]) ]) # Set option to enable debug mode. Set DEBUG and OPT for use in Makefile.am. AC_DEFUN([FB_ENABLE_DEFAULT_DEBUG_BUILD], [ AC_MSG_CHECKING([whether to enable debug build]) AC_ARG_ENABLE([debug], [ --disable-debug Set up opt mode.], [ ENABLED_DEBUG=$enableval ], [ ENABLED_DEBUG="yes" ] ) if test "$ENABLED_DEBUG" = "yes" then CFLAGS="-Wall -g" CXXFLAGS="-Wall -g" else CFLAGS="-Wall -O3" CXXFLAGS="-Wall -O3" fi AC_MSG_RESULT($ENABLED_DEBUG) AM_CONDITIONAL([DEBUG], [test "$ENABLED_DEBUG" = yes]) AM_CONDITIONAL([OPT], [test "$ENABLED_DEBUG" = no]) ]) # Set option to enable static libs. AC_DEFUN([FB_ENABLE_DEFAULT_STATIC], [ SHARED="" STATIC="" AC_MSG_CHECKING([whether to enable static mode]) AC_ARG_ENABLE([static], [ --disable-static Set up shared mode.], [ ENABLED_STATIC=$enableval ], [ ENABLED_STATIC="yes" ] ) if test "$ENABLED_STATIC" = "yes" then LTYPE=".a" else LTYPE=".so" SHARED_CXXFLAGS="-fPIC" SHARED_CFLAGS="-fPIC" SHARED_LDFLAGS="-shared -fPIC" AC_SUBST(SHARED_CXXFLAGS) AC_SUBST(SHARED_CFLAGS) AC_SUBST(SHARED_LDFLAGS) fi AC_MSG_RESULT($ENABLED_STATIC) AC_SUBST(LTYPE) AM_CONDITIONAL([STATIC], [test "$ENABLED_STATIC" = yes]) AM_CONDITIONAL([SHARED], [test "$ENABLED_STATIC" = no]) ]) # Set option to enable shared libs. AC_DEFUN([FB_ENABLE_DEFAULT_SHARED], [ SHARED="" STATIC="" AC_MSG_CHECKING([whether to enable shared mode]) AC_ARG_ENABLE([shared], [ --disable-shared Set up static mode.], [ ENABLED_SHARED=$enableval ], [ ENABLED_SHARED="yes" ] ) if test "$ENABLED_SHARED" = "yes" then LTYPE=".so" SHARED_CXXFLAGS="-fPIC" SHARED_CFLAGS="-fPIC" SHARED_LDFLAGS="-shared -fPIC" AC_SUBST(SHARED_CXXFLAGS) AC_SUBST(SHARED_CFLAGS) AC_SUBST(SHARED_LDFLAGS) else LTYPE=".a" fi AC_MSG_RESULT($ENABLED_SHARED) AC_SUBST(LTYPE) AM_CONDITIONAL([SHARED], [test "$ENABLED_SHARED" = yes]) AM_CONDITIONAL([STATIC], [test "$ENABLED_SHARED" = no]) ]) # Generates define flags and conditionals as specified by user. # This gets enabled *only* if user selects --enable- otion. AC_DEFUN([FB_ENABLE_FEATURE], [ ENABLE="" flag="$1" value="$3" AC_MSG_CHECKING([whether to enable $1]) AC_ARG_ENABLE([$2], [ --enable-$2 Enable $2.], [ ENABLE=$enableval ], [ ENABLE="no" ] ) AM_CONDITIONAL([$1], [test "$ENABLE" = yes]) if test "$ENABLE" = "yes" then if test "x${value}" = "x" then AC_DEFINE([$1]) else AC_DEFINE_UNQUOTED([$1], [$value]) fi fi AC_MSG_RESULT($ENABLE) ]) # can also use eval $2=$withval;AC_SUBST($2) AC_DEFUN([FB_WITH_PATH], [ USRFLAG="" USRFLAG=$1 AC_MSG_CHECKING([Checking $1 set to]) AC_ARG_WITH([$2], [ --with-$2=DIR User specified path.], [ LOC=$withval eval $USRFLAG=$withval ], [ LOC=$3 eval $USRFLAG=$3 ] ) AC_SUBST([$1]) AC_MSG_RESULT($LOC) ]) AC_DEFUN([FB_SET_FLAG_VALUE], [ SETFLAG="" AC_MSG_CHECKING([Checking $1 set to]) SETFLAG=$1 eval $SETFLAG=\"$2\" AC_SUBST([$SETFLAG]) AC_MSG_RESULT($2) ]) # NOTES # if using if else bourne stmt you must have more than a macro in it. # EX1 is not correct. EX2 is correct # EX1: if test "$XX" = "yes"; then # AC_SUBST(xx) # fi # EX2: if test "$XX" = "yes"; then # xx="foo" # AC_SUBST(xx) # fi thrift-0.23.0/contrib/fb303/aclocal/0000775000175000017500000000000015165535636017250 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/aclocal/ax_javac_and_java.m40000664000175000017500000000740115165535636023113 0ustar00buildbuild00000000000000dnl @synopsis AX_JAVAC_AND_JAVA dnl @synopsis AX_CHECK_JAVA_CLASS(CLASSNAME) dnl dnl Test for the presence of a JDK, and (optionally) specific classes. dnl dnl If "JAVA" is defined in the environment, that will be the only dnl java command tested. Otherwise, a hard-coded list will be used. dnl Similarly for "JAVAC". dnl dnl AX_JAVAC_AND_JAVA does not currently support testing for a particular dnl Java version, testing for only one of "java" and "javac", or dnl compiling or running user-provided Java code. dnl dnl After AX_JAVAC_AND_JAVA runs, the shell variables "success" and dnl "ax_javac_and_java" are set to "yes" or "no", and "JAVAC" and dnl "JAVA" are set to the appropriate commands. dnl dnl AX_CHECK_JAVA_CLASS must be run after AX_JAVAC_AND_JAVA. dnl It tests for the presence of a class based on a fully-qualified name. dnl It sets the shell variable "success" to "yes" or "no". dnl dnl @category Java dnl @version 2009-02-09 dnl @license AllPermissive dnl dnl Copyright (C) 2009 David Reiss dnl Copying and distribution of this file, with or without modification, dnl are permitted in any medium without royalty provided the copyright dnl notice and this notice are preserved. AC_DEFUN([AX_JAVAC_AND_JAVA], [ dnl Hard-coded default commands to test. JAVAC_PROGS="javac,jikes,gcj -C" JAVA_PROGS="java,kaffe" dnl Allow the user to specify an alternative. if test -n "$JAVAC" ; then JAVAC_PROGS="$JAVAC" fi if test -n "$JAVA" ; then JAVA_PROGS="$JAVA" fi AC_MSG_CHECKING(for javac and java) echo "public class configtest_ax_javac_and_java { public static void main(String args@<:@@:>@) { } }" > configtest_ax_javac_and_java.java success=no oIFS="$IFS" IFS="," for JAVAC in $JAVAC_PROGS ; do IFS="$oIFS" echo "Running \"$JAVAC configtest_ax_javac_and_java.java\"" >&AS_MESSAGE_LOG_FD if $JAVAC configtest_ax_javac_and_java.java >&AS_MESSAGE_LOG_FD 2>&1 ; then IFS="," for JAVA in $JAVA_PROGS ; do IFS="$oIFS" echo "Running \"$JAVA configtest_ax_javac_and_java\"" >&AS_MESSAGE_LOG_FD if $JAVA configtest_ax_javac_and_java >&AS_MESSAGE_LOG_FD 2>&1 ; then success=yes break 2 fi done fi done rm -f configtest_ax_javac_and_java.java configtest_ax_javac_and_java.class if test "$success" != "yes" ; then AC_MSG_RESULT(no) JAVAC="" JAVA="" else AC_MSG_RESULT(yes) fi ax_javac_and_java="$success" ]) AC_DEFUN([AX_CHECK_JAVA_CLASS], [ AC_MSG_CHECKING(for Java class [$1]) echo "import $1; public class configtest_ax_javac_and_java { public static void main(String args@<:@@:>@) { } }" > configtest_ax_javac_and_java.java echo "Running \"$JAVAC configtest_ax_javac_and_java.java\"" >&AS_MESSAGE_LOG_FD if $JAVAC configtest_ax_javac_and_java.java >&AS_MESSAGE_LOG_FD 2>&1 ; then AC_MSG_RESULT(yes) success=yes else AC_MSG_RESULT(no) success=no fi rm -f configtest_ax_javac_and_java.java configtest_ax_javac_and_java.class ]) AC_DEFUN([AX_CHECK_ANT_VERSION], [ AC_MSG_CHECKING(for ant version > $2) ANT_VALID=`expr $($1 -version 2>/dev/null | sed -n 's/.*version \(@<:@0-9\.@:>@*\).*/\1/p') \>= $2` if test "x$ANT_VALID" = "x1" ; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) ANT="" fi ]) thrift-0.23.0/contrib/fb303/aclocal/ax_boost_base.m40000664000175000017500000001470015165535636022324 0ustar00buildbuild00000000000000##### http://autoconf-archive.cryp.to/ax_boost_base.html # # SYNOPSIS # # AX_BOOST_BASE([MINIMUM-VERSION]) # # DESCRIPTION # # Test for the Boost C++ libraries of a particular version (or newer) # # If no path to the installed boost library is given the macro # searchs under /usr, /usr/local, /opt and /opt/local and evaluates # the $BOOST_ROOT environment variable. Further documentation is # available at . # # This macro calls: # # AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) # # And sets: # # HAVE_BOOST # # LAST MODIFICATION # # 2007-07-28 # # COPYLEFT # # Copyright (c) 2007 Thomas Porschberg # # Copying and distribution of this file, with or without # modification, are permitted in any medium without royalty provided # the copyright notice and this notice are preserved. AC_DEFUN([AX_BOOST_BASE], [ AC_ARG_WITH([boost], AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]), [ if test "$withval" = "no"; then want_boost="no" elif test "$withval" = "yes"; then want_boost="yes" ac_boost_path="" else want_boost="yes" ac_boost_path="$withval" fi ], [want_boost="yes"]) if test "x$want_boost" = "xyes"; then boost_lib_version_req=ifelse([$1], ,1.20.0,$1) boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` if test "x$boost_lib_version_req_sub_minor" = "x" ; then boost_lib_version_req_sub_minor="0" fi WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) succeeded=no dnl first we check the system location for boost libraries dnl this location ist chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM if test "$ac_boost_path" != ""; then BOOST_LDFLAGS="-L$ac_boost_path/lib" BOOST_CPPFLAGS="-I$ac_boost_path/include" else for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib" BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" break; fi done fi CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS_SAVED="$LDFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes ],[ ]) AC_LANG_POP([C++]) dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version if test "x$succeeded" != "xyes"; then _version=0 if test "$ac_boost_path" != ""; then BOOST_LDFLAGS="-L$ac_boost_path/lib" if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp fi VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" done fi else for ac_boost_path in /usr /usr/local /opt /opt/local ; do if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp best_path=$ac_boost_path fi done fi done VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" BOOST_LDFLAGS="-L$best_path/lib" if test "x$BOOST_ROOT" != "x"; then if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` V_CHECK=`expr $stage_version_shorten \>\= $_version` if test "$V_CHECK" = "1" ; then AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) BOOST_CPPFLAGS="-I$BOOST_ROOT" BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib" fi fi fi fi CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes ],[ ]) AC_LANG_POP([C++]) fi if test "$succeeded" != "yes" ; then if test "$_version" = "0" ; then AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) else AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) fi else AC_SUBST(BOOST_CPPFLAGS) AC_SUBST(BOOST_LDFLAGS) AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) fi CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" fi ]) thrift-0.23.0/contrib/fb303/aclocal/ax_thrift_internal.m40000664000175000017500000000210515165535636023374 0ustar00buildbuild00000000000000dnl @synopsis AX_THRIFT_GEN(SHORT_LANGUAGE, LONG_LANGUAGE, DEFAULT) dnl @synopsis AX_THRIFT_LIB(SHORT_LANGUAGE, LONG_LANGUAGE, DEFAULT) dnl dnl Allow a particular language generator to be disabled. dnl Allow a particular language library to be disabled. dnl dnl These macros have poor error handling and are poorly documented. dnl They are intended only for internal use by the Thrift compiler. dnl dnl @version 2008-02-20 dnl @license AllPermissive dnl dnl Copyright (C) 2009 David Reiss dnl Copying and distribution of this file, with or without modification, dnl are permitted in any medium without royalty provided the copyright dnl notice and this notice are preserved. AC_DEFUN([AX_THRIFT_LIB], [ AC_ARG_WITH($1, AS_HELP_STRING([--with-$1], [build the $2 library @<:@default=$3@:>@]), [with_$1="$withval"], [with_$1=$3] ) have_$1=no dnl What we do here is going to vary from library to library, dnl so we can't really generalize (yet!). ]) thrift-0.23.0/contrib/fb303/aclocal/ax_cxx_compile_stdcxx_11.m40000664000175000017500000001073415165535636024417 0ustar00buildbuild00000000000000# ============================================================================ # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html # ============================================================================ # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the C++11 # standard; if necessary, add switches to CXXFLAGS to enable support. # # The first argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for an extended mode. # # The second argument, if specified 'mandatory' or if left unspecified, # indicates that baseline C++11 support is required and that the macro # should error out if no mode with that support is found. If specified # 'optional', then configuration proceeds regardless, after defining # HAVE_CXX11 if and only if a supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 3 m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; ]) AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl m4_if([$1], [], [], [$1], [ext], [], [$1], [noext], [], [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], [$2], [optional], [ax_cxx_compile_cxx11_required=false], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl AC_LANG_PUSH([C++])dnl ac_success=no AC_CACHE_CHECK(whether $CXX supports C++11 features by default, ax_cv_cxx_compile_cxx11, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [ax_cv_cxx_compile_cxx11=yes], [ax_cv_cxx_compile_cxx11=no])]) if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi m4_if([$1], [noext], [], [dnl if test x$ac_success = xno; then for switch in -std=gnu++11; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) m4_if([$1], [ext], [], [dnl if test x$ac_success = xno; then for switch in -std=c++11; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) fi else if test x$ac_success = xno; then HAVE_CXX11=0 AC_MSG_NOTICE([No compiler with C++11 support was found]) else HAVE_CXX11=1 AC_DEFINE(HAVE_CXX11,1, [define if the compiler supports basic C++11 syntax]) fi AC_SUBST(HAVE_CXX11) fi ]) thrift-0.23.0/contrib/fb303/cpp/0000775000175000017500000000000015165535636016434 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/fb303/cpp/ServiceTracker.cpp0000664000175000017500000004004515165535636022057 0ustar00buildbuild00000000000000/* * 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 "FacebookBase.h" #include "ServiceTracker.h" #include using namespace std; using namespace facebook::fb303; using namespace apache::thrift::concurrency; uint64_t ServiceTracker::CHECKPOINT_MINIMUM_INTERVAL_SECONDS = 60; int ServiceTracker::LOG_LEVEL = 5; ServiceTracker::ServiceTracker(facebook::fb303::FacebookBase *handler, void (*logMethod)(int, const string &), bool featureCheckpoint, bool featureStatusCheck, bool featureThreadCheck, Stopwatch::Unit stopwatchUnit) : handler_(handler), logMethod_(logMethod), featureCheckpoint_(featureCheckpoint), featureStatusCheck_(featureStatusCheck), featureThreadCheck_(featureThreadCheck), stopwatchUnit_(stopwatchUnit), checkpointServices_(0) { if (featureCheckpoint_) { time_t now = time(nullptr); checkpointTime_ = now; } else { checkpointTime_ = 0; } } /** * Registers the beginning of a "service method": basically, any of * the implementations of Thrift remote procedure calls that a * FacebookBase handler is handling. Controls concurrent * services and reports statistics (via log and via fb303 counters). * Throws an exception if the server is not ready to handle service * methods yet. * * note: The relationship between startService() and finishService() * is currently defined so that a call to finishService() should only * be matched to this call to startService() if this method returns * without exception. It wouldn't be a problem to implement things * the other way, so that *every* start needed a finish, but this * convention was chosen to match the way an object's constructor and * destructor work together, i.e. to work well with ServiceMethod * objects. * * @param const ServiceMethod &serviceMethod A reference to the ServiceMethod * object instantiated at the start * of the service method. */ void ServiceTracker::startService(const ServiceMethod &serviceMethod) { // note: serviceMethod.timer_ automatically starts at construction. // log service start logMethod_(5, serviceMethod.signature_); // check handler ready if (featureStatusCheck_ && !serviceMethod.featureLogOnly_) { // note: Throwing exceptions before counting statistics. See note // in method header. // note: A STOPPING server is not accepting new connections, but it // is still handling any already-connected threads -- so from the // service method's point of view, a status of STOPPING is a green // light. facebook::fb303::fb_status status = handler_->getStatus(); if (status != facebook::fb303::ALIVE && status != facebook::fb303::STOPPING) { if (status == facebook::fb303::STARTING) { throw ServiceException("Server starting up; please try again later"); } else { throw ServiceException("Server not alive; please try again later"); } } } // check server threads if (featureThreadCheck_ && !serviceMethod.featureLogOnly_) { // note: Might want to put these messages in reportCheckpoint() if // log is getting spammed. if (threadManager_ != nullptr) { size_t idle_count = threadManager_->idleWorkerCount(); if (idle_count == 0) { stringstream message; message << "service " << serviceMethod.signature_ << ": all threads (" << threadManager_->workerCount() << ") in use"; logMethod_(3, message.str()); } } } } /** * Logs a significant step in the middle of a "service method"; see * startService. * * @param const ServiceMethod &serviceMethod A reference to the ServiceMethod * object instantiated at the start * of the service method. * @return int64_t Elapsed units (see stopwatchUnit_) since ServiceMethod * instantiation. */ int64_t ServiceTracker::stepService(const ServiceMethod &serviceMethod, const string &stepName) { stringstream message; string elapsed_label; int64_t elapsed = serviceMethod.timer_.elapsedUnits(stopwatchUnit_, &elapsed_label); message << serviceMethod.signature_ << ' ' << stepName << " [" << elapsed_label << ']'; logMethod_(5, message.str()); return elapsed; } /** * Registers the end of a "service method"; see startService(). * * @param const ServiceMethod &serviceMethod A reference to the ServiceMethod * object instantiated at the start * of the service method. */ void ServiceTracker::finishService(const ServiceMethod &serviceMethod) { // log end of service stringstream message; string duration_label; int64_t duration = serviceMethod.timer_.elapsedUnits(stopwatchUnit_, &duration_label); message << serviceMethod.signature_ << " finish [" << duration_label << ']'; logMethod_(5, message.str()); // count, record, and maybe report service statistics if (!serviceMethod.featureLogOnly_) { if (!featureCheckpoint_) { // lifetime counters // (note: No need to lock statisticsMutex_ if not doing checkpoint; // FacebookService::incrementCounter() is already thread-safe.) handler_->incrementCounter("lifetime_services"); } else { statisticsMutex_.lock(); // note: No exceptions expected from this code block. Wrap in a try // just to be safe. try { // lifetime counters // note: Good to synchronize this with the increment of // checkpoint services, even though incrementCounter() is // already thread-safe, for the sake of checkpoint reporting // consistency (i.e. since the last checkpoint, // lifetime_services has incremented by checkpointServices_). handler_->incrementCounter("lifetime_services"); // checkpoint counters checkpointServices_++; checkpointDuration_ += duration; // per-service timing // note kjv: According to my tests it is very slightly faster to // call insert() once (and detect not-found) than calling find() // and then maybe insert (if not-found). However, the difference // is tiny for small maps like this one, and the code for the // faster solution is slightly less readable. Also, I wonder if // the instantiation of the (often unused) pair to insert makes // the first algorithm slower after all. map >::iterator iter; iter = checkpointServiceDuration_.find(serviceMethod.name_); if (iter != checkpointServiceDuration_.end()) { iter->second.first++; iter->second.second += duration; } else { checkpointServiceDuration_.insert(make_pair(serviceMethod.name_, make_pair(1, duration))); } // maybe report checkpoint // note: ...if it's been long enough since the last report. time_t now = time(nullptr); uint64_t check_interval = now - checkpointTime_; if (check_interval >= CHECKPOINT_MINIMUM_INTERVAL_SECONDS) { reportCheckpoint(); } } catch (...) { statisticsMutex_.unlock(); throw; } statisticsMutex_.unlock(); } } } /** * Logs some statistics gathered since the last call to this method. * * note: Thread race conditions on this method could cause * misreporting and/or undefined behavior; the caller must protect * uses of the object variables (and calls to this method) with a * mutex. * */ void ServiceTracker::reportCheckpoint() { time_t now = time(nullptr); uint64_t check_count = checkpointServices_; uint64_t check_interval = now - checkpointTime_; uint64_t check_duration = checkpointDuration_; // export counters for timing of service methods (by service name) handler_->setCounter("checkpoint_time", check_interval); map >::iterator iter; uint64_t count; for (iter = checkpointServiceDuration_.begin(); iter != checkpointServiceDuration_.end(); ++iter) { count = iter->second.first; handler_->setCounter(string("checkpoint_count_") + iter->first, count); if (count == 0) { handler_->setCounter(string("checkpoint_speed_") + iter->first, 0); } else { handler_->setCounter(string("checkpoint_speed_") + iter->first, iter->second.second / count); } } // reset checkpoint variables // note: Clearing the map while other threads are using it might // cause undefined behavior. checkpointServiceDuration_.clear(); checkpointTime_ = now; checkpointServices_ = 0; checkpointDuration_ = 0; // get lifetime variables uint64_t life_count = handler_->getCounter("lifetime_services"); uint64_t life_interval = now - handler_->aliveSince(); // log checkpoint stringstream message; message << "checkpoint_time:" << check_interval << " checkpoint_services:" << check_count << " checkpoint_speed_sum:" << check_duration << " lifetime_time:" << life_interval << " lifetime_services:" << life_count; if (featureThreadCheck_ && threadManager_ != nullptr) { size_t worker_count = threadManager_->workerCount(); size_t idle_count = threadManager_->idleWorkerCount(); message << " total_workers:" << worker_count << " active_workers:" << (worker_count - idle_count); } logMethod_(4, message.str()); } /** * Remembers the thread manager used in the server, for monitoring thread * activity. * * @param shared_ptr threadManager The server's thread manager. */ void ServiceTracker::setThreadManager(boost::shared_ptr threadManager) { threadManager_ = threadManager; } /** * Logs messages to stdout; the passed message will be logged if the * passed level is less than or equal to LOG_LEVEL. * * This is the default logging method used by the ServiceTracker. An * alternate logging method (that accepts the same parameters) may be * specified to the constructor. * * @param int level A level associated with the message: higher levels * are used to indicate higher levels of detail. * @param string message The message to log. */ void ServiceTracker::defaultLogMethod(int level, const string &message) { if (level <= LOG_LEVEL) { string level_string; time_t now = time(nullptr); char now_pretty[26]; ctime_r(&now, now_pretty); now_pretty[24] = '\0'; switch (level) { case 1: level_string = "CRITICAL"; break; case 2: level_string = "ERROR"; break; case 3: level_string = "WARNING"; break; case 5: level_string = "DEBUG"; break; case 4: default: level_string = "INFO"; break; } cout << '[' << level_string << "] [" << now_pretty << "] " << message << '\n'; } } /** * Creates a Stopwatch, which can report the time elapsed since its * creation. * */ Stopwatch::Stopwatch() { gettimeofday(&startTime_, nullptr); } void Stopwatch::reset() { gettimeofday(&startTime_, nullptr); } uint64_t Stopwatch::elapsedUnits(Stopwatch::Unit unit, string *label) const { timeval now_time; gettimeofday(&now_time, nullptr); time_t duration_secs = now_time.tv_sec - startTime_.tv_sec; uint64_t duration_units; switch (unit) { case UNIT_SECONDS: duration_units = duration_secs + (now_time.tv_usec - startTime_.tv_usec + 500000) / 1000000; if (nullptr != label) { stringstream ss_label; ss_label << duration_units << " secs"; label->assign(ss_label.str()); } break; case UNIT_MICROSECONDS: duration_units = duration_secs * 1000000 + now_time.tv_usec - startTime_.tv_usec; if (nullptr != label) { stringstream ss_label; ss_label << duration_units << " us"; label->assign(ss_label.str()); } break; case UNIT_MILLISECONDS: default: duration_units = duration_secs * 1000 + (now_time.tv_usec - startTime_.tv_usec + 500) / 1000; if (nullptr != label) { stringstream ss_label; ss_label << duration_units << " ms"; label->assign(ss_label.str()); } break; } return duration_units; } /** * Creates a ServiceMethod, used for tracking a single service method * invocation (via the ServiceTracker). The passed name of the * ServiceMethod is used to group statistics (e.g. counts and durations) * for similar invocations; the passed signature is used to uniquely * identify the particular invocation in the log. * * note: A version of this constructor is provided that automatically * forms a signature the name and a passed numeric id. Silly, sure, * but commonly used, since it often saves the caller a line or two of * code. * * @param ServiceTracker *tracker The service tracker that will track this * ServiceMethod. * @param const string &name The service method name (usually independent * of service method parameters). * @param const string &signature A signature uniquely identifying the method * invocation (usually name plus parameters). */ ServiceMethod::ServiceMethod(ServiceTracker *tracker, const string &name, const string &signature, bool featureLogOnly) : tracker_(tracker), name_(name), signature_(signature), featureLogOnly_(featureLogOnly) { // note: timer_ automatically starts at construction. // invoke tracker to start service // note: Might throw. If it throws, then this object's destructor // won't be called, which is according to plan: finishService() is // only supposed to be matched to startService() if startService() // returns without error. tracker_->startService(*this); } ServiceMethod::ServiceMethod(ServiceTracker *tracker, const string &name, uint64_t id, bool featureLogOnly) : tracker_(tracker), name_(name), featureLogOnly_(featureLogOnly) { // note: timer_ automatically starts at construction. stringstream ss_signature; ss_signature << name << " (" << id << ')'; signature_ = ss_signature.str(); // invoke tracker to start service // note: Might throw. If it throws, then this object's destructor // won't be called, which is according to plan: finishService() is // only supposed to be matched to startService() if startService() // returns without error. tracker_->startService(*this); } ServiceMethod::~ServiceMethod() { // invoke tracker to finish service // note: Not expecting an exception from this code, but // finishService() might conceivably throw an out-of-memory // exception. try { tracker_->finishService(*this); } catch (...) { // don't throw } } uint64_t ServiceMethod::step(const std::string &stepName) { return tracker_->stepService(*this, stepName); } thrift-0.23.0/contrib/fb303/cpp/FacebookBase.cpp0000664000175000017500000000653615165535636021456 0ustar00buildbuild00000000000000/* * 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 "FacebookBase.h" using namespace facebook::fb303; using apache::thrift::concurrency::Guard; FacebookBase::FacebookBase(std::string name) : name_(name) { aliveSince_ = (int64_t) time(nullptr); } inline void FacebookBase::getName(std::string& _return) { _return = name_; } void FacebookBase::setOption(const std::string& key, const std::string& value) { Guard g(optionsLock_); options_[key] = value; } void FacebookBase::getOption(std::string& _return, const std::string& key) { Guard g(optionsLock_); _return = options_[key]; } void FacebookBase::getOptions(std::map & _return) { Guard g(optionsLock_); _return = options_; } int64_t FacebookBase::incrementCounter(const std::string& key, int64_t amount) { counters_.lock(); // if we didn't find the key, we need to write lock the whole map to create it ReadWriteCounterMap::iterator it = counters_.find(key); if (it == counters_.end()) { // we need to check again to make sure someone didn't create this key // already while we released the lock it = counters_.find(key); if(it == counters_.end()){ counters_[key].value = amount; counters_.unlock(); return amount; } } it->second.lock(); int64_t count = it->second.value + amount; it->second.value = count; it->second.unlock(); counters_.unlock(); return count; } int64_t FacebookBase::setCounter(const std::string& key, int64_t value) { counters_.lock(); // if we didn't find the key, we need to write lock the whole map to create it ReadWriteCounterMap::iterator it = counters_.find(key); if (it == counters_.end()) { counters_[key].value = value; counters_.unlock(); return value; } it->second.lock(); it->second.value = value; it->second.unlock(); counters_.unlock(); return value; } void FacebookBase::getCounters(std::map& _return) { // we need to lock the whole thing and actually build the map since we don't // want our read/write structure to go over the wire counters_.lock(); for(ReadWriteCounterMap::iterator it = counters_.begin(); it != counters_.end(); ++it) { _return[it->first] = it->second.value; } counters_.unlock(); } int64_t FacebookBase::getCounter(const std::string& key) { int64_t rv = 0; counters_.lock(); ReadWriteCounterMap::iterator it = counters_.find(key); if (it != counters_.end()) { it->second.lock(); rv = it->second.value; it->second.unlock(); } counters_.unlock(); return rv; } inline int64_t FacebookBase::aliveSince() { return aliveSince_; } thrift-0.23.0/contrib/fb303/cpp/ServiceTracker.h0000664000175000017500000001524715165535636021532 0ustar00buildbuild00000000000000/* * 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. */ /** * ServiceTracker is a utility class for logging and timing service * calls to a fb303 Thrift server. Currently, ServiceTracker offers * the following features: * * . Logging of service method start, end (and duration), and * optional steps in between. * * . Automatic check of server status via fb303::getStatus() * with a ServiceException thrown if server not alive * (at method start). * * . A periodic logged checkpoint reporting lifetime time, lifetime * service count, and per-method statistics since the last checkpoint * time (at method finish). * * . Export of fb303 counters for lifetime and checkpoint statistics * (at method finish). * * . For TThreadPoolServers, a logged warning when all server threads * are busy (at method start). (Must call setThreadManager() after * ServiceTracker instantiation for this feature to be enabled.) * * Individual features may be enabled or disabled by arguments to the * constructor. The constructor also accepts a pointer to a logging * method -- if no pointer is passed, the tracker will log to stdout. * * ServiceTracker defines private methods for service start, finish, * and step, which are designed to be accessed by instantiating a * friend ServiceMethod object, as in the following example: * * #include * class MyServiceHandler : virtual public MyServiceIf, * public facebook::fb303::FacebookBase * { * public: * MyServiceHandler::MyServiceHandler() : mServiceTracker(this) {} * void MyServiceHandler::myServiceMethod(int userId) { * // note: Instantiating a ServiceMethod object starts a timer * // and tells the ServiceTracker to log the start. Might throw * // a ServiceException. * ServiceMethod serviceMethod(&mServiceTracker, * "myServiceMethod", * userId); * ... * // note: Calling the step method tells the ServiceTracker to * // log the step, with a time elapsed since start. * serviceMethod.step("post parsing, begin processing"); * ... * // note: When the ServiceMethod object goes out of scope, the * // ServiceTracker will log the total elapsed time of the method. * } * ... * private: * ServiceTracker mServiceTracker; * } * * The step() method call is optional; the startService() and * finishService() methods are handled by the object's constructor and * destructor. * * The ServiceTracker is (intended to be) thread-safe. * * Future: * * . Come up with something better for logging than passing a * function pointer to the constructor. * * . Add methods for tracking errors from service methods, e.g. * ServiceTracker::reportService(). */ #ifndef SERVICETRACKER_H #define SERVICETRACKER_H #include #include #include #include #include #include #include namespace apache { namespace thrift { namespace concurrency { class ThreadManager; }}} namespace facebook { namespace fb303 { class FacebookBase; class ServiceMethod; class Stopwatch { public: enum Unit { UNIT_SECONDS, UNIT_MILLISECONDS, UNIT_MICROSECONDS }; Stopwatch(); uint64_t elapsedUnits(Unit unit, std::string *label = nullptr) const; void reset(); private: timeval startTime_; }; class ServiceTracker { friend class ServiceMethod; public: static uint64_t CHECKPOINT_MINIMUM_INTERVAL_SECONDS; static int LOG_LEVEL; ServiceTracker(facebook::fb303::FacebookBase *handler, void (*logMethod)(int, const std::string &) = &ServiceTracker::defaultLogMethod, bool featureCheckpoint = true, bool featureStatusCheck = true, bool featureThreadCheck = true, Stopwatch::Unit stopwatchUnit = Stopwatch::UNIT_MILLISECONDS); void setThreadManager(boost::shared_ptr threadManager); private: facebook::fb303::FacebookBase *handler_; void (*logMethod_)(int, const std::string &); boost::shared_ptr threadManager_; bool featureCheckpoint_; bool featureStatusCheck_; bool featureThreadCheck_; Stopwatch::Unit stopwatchUnit_; apache::thrift::concurrency::Mutex statisticsMutex_; time_t checkpointTime_; uint64_t checkpointServices_; uint64_t checkpointDuration_; std::map > checkpointServiceDuration_; void startService(const ServiceMethod &serviceMethod); int64_t stepService(const ServiceMethod &serviceMethod, const std::string &stepName); void finishService(const ServiceMethod &serviceMethod); void reportCheckpoint(); static void defaultLogMethod(int level, const std::string &message); }; class ServiceMethod { friend class ServiceTracker; public: ServiceMethod(ServiceTracker *tracker, const std::string &name, const std::string &signature, bool featureLogOnly = false); ServiceMethod(ServiceTracker *tracker, const std::string &name, uint64_t id, bool featureLogOnly = false); ~ServiceMethod(); uint64_t step(const std::string &stepName); private: ServiceTracker *tracker_; std::string name_; std::string signature_; bool featureLogOnly_; Stopwatch timer_; }; class ServiceException : public std::exception { public: explicit ServiceException(const std::string &message, int code = 0) : message_(message), code_(code) {} ~ServiceException() throw() {} virtual const char *what() const throw() { return message_.c_str(); } int code() const throw() { return code_; } private: std::string message_; int code_; }; }} // facebook::fb303 #endif thrift-0.23.0/contrib/fb303/cpp/FacebookBase.h0000664000175000017500000000543515165535636021120 0ustar00buildbuild00000000000000/* * 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 _FACEBOOK_TB303_FACEBOOKBASE_H_ #define _FACEBOOK_TB303_FACEBOOKBASE_H_ 1 #include "FacebookService.h" #include #include #include #include #include #include namespace facebook { namespace fb303 { using apache::thrift::concurrency::Mutex; using apache::thrift::server::TServer; struct ReadWriteInt : Mutex {int64_t value;}; struct ReadWriteCounterMap : Mutex, std::map {}; /** * Base Facebook service implementation in C++. * */ class FacebookBase : virtual public FacebookServiceIf { protected: FacebookBase(std::string name); virtual ~FacebookBase() {} public: void getName(std::string& _return); virtual void getVersion(std::string& _return) { _return = ""; } virtual fb_status getStatus() = 0; virtual void getStatusDetails(std::string& _return) { _return = ""; } void setOption(const std::string& key, const std::string& value); void getOption(std::string& _return, const std::string& key); void getOptions(std::map & _return); int64_t aliveSince(); virtual void reinitialize() {} virtual void shutdown() { if (server_.get() != nullptr) { server_->stop(); } } int64_t incrementCounter(const std::string& key, int64_t amount = 1); int64_t setCounter(const std::string& key, int64_t value); void getCounters(std::map& _return); int64_t getCounter(const std::string& key); /** * Set server handle for shutdown method */ void setServer(boost::shared_ptr server) { server_ = server; } void getCpuProfile(std::string& _return, int32_t durSecs) { _return = ""; } private: std::string name_; int64_t aliveSince_; std::map options_; Mutex optionsLock_; ReadWriteCounterMap counters_; boost::shared_ptr server_; }; }} // facebook::tb303 #endif // _FACEBOOK_TB303_FACEBOOKBASE_H_ thrift-0.23.0/contrib/fb303/cpp/Makefile.am0000664000175000017500000000530215165535636020470 0ustar00buildbuild00000000000000# # 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. # @GLOBAL_HEADER_MK@ @PRODUCT_MK@ # User specified path variables set in configure.ac. # thrift_home # THRIFT = $(thrift_home)/bin/thrift # User defined conditionals and conditonal statements set up in configure.ac. if DEBUG DEBUG_CPPFLAGS = -DDEBUG_TIMING endif # Set common flags recognized by automake. # DO NOT USE CPPFLAGS, CXXFLAGS, CFLAGS, LDFLAGS here! Set in configure.ac and|or override on command line. # USE flags AM_CXXFLAGS, AM_CFLAGS, AM_CPPFLAGS, AM_LDFLAGS, LDADD in this section. AM_CPPFLAGS = -I.. AM_CPPFLAGS += -Igen-cpp AM_CPPFLAGS += -I$(thrift_home)/include/thrift AM_CPPFLAGS += $(BOOST_CPPFLAGS) AM_CPPFLAGS += $(FB_CPPFLAGS) $(DEBUG_CPPFLAGS) # GENERATE BUILD RULES # Set Program/library specific flags recognized by automake. # Use _ to set prog / lib specific flag s # foo_CXXFLAGS foo_CPPFLAGS foo_LDFLAGS foo_LDADD fb303_lib = gen-cpp/FacebookService.cpp gen-cpp/fb303_types.cpp FacebookBase.cpp ServiceTracker.cpp # Static -- multiple libraries can be defined if STATIC lib_LIBRARIES = libfb303.a libfb303_a_SOURCES = $(fb303_lib) INTERNAL_LIBS = libfb303.a endif # Shared -- multiple libraries can be defined if SHARED shareddir = $(prefix)/lib shared_PROGRAMS = libfb303.so libfb303_so_SOURCES = $(fb303_lib) libfb303_so_CXXFLAGS = $(SHARED_CXXFLAGS) libfb303_so_LDFLAGS = $(SHARED_LDFLAGS) INTERNAL_LIBS = libfb303.so endif # Set up Thrift specific activity here. # We assume that a +types.cpp will always be built from .thrift. $(eval $(call thrift_template,.,../if/fb303.thrift,-I $(thrift_home)/share --gen cpp:pure_enums )) include_fb303dir = $(includedir)/thrift/fb303 include_fb303_HEADERS = FacebookBase.h ServiceTracker.h gen-cpp/FacebookService.h gen-cpp/fb303_types.h include_fb303ifdir = $(prefix)/share/fb303/if include_fb303if_HEADERS = ../if/fb303.thrift BUILT_SOURCES = thriftstyle # Add to pre-existing target clean clean-local: clean-common @GLOBAL_FOOTER_MK@ thrift-0.23.0/contrib/fb303/Makefile.am0000664000175000017500000000201415165535636017703 0ustar00buildbuild00000000000000# # 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. # @GLOBAL_HEADER_MK@ @PRODUCT_MK@ SUBDIRS = . if WITH_CPP SUBDIRS += cpp endif if WITH_JAVA SUBDIRS += java endif if WITH_PHP SUBDIRS += php endif if WITH_PYTHON SUBDIRS += py endif BUILT_SOURCES = clean-local: clean-common @GLOBAL_FOOTER_MK@ thrift-0.23.0/contrib/fb303/configure.ac0000664000175000017500000001255415165535636020147 0ustar00buildbuild00000000000000# Autoconf input file # $Id$ # AC - autoconf # FB - facebook # # 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. # ######################################################################### # DO NOT TOUCH EXCEPT TO CHANGE REV# IN AC_INIT AC_PREREQ(2.52) AC_INIT([libfb303],[20080209]) #AC_CONFIG_AUX_DIR([/usr/share/automake-1.9]) # To install locally FB_INITIALIZE([localinstall]) AC_PREFIX_DEFAULT([/usr/local]) ############################################################################ # User Configurable. Change With CAUTION! # User can include custom makefile rules. Uncomment and update only in PRODUCT_MK. # Include where appropriate in any Makefile.am as @PRODUCT_MK@ #PRODUCT_MK="include ${EXTERNAL_PATH}/shared/build/.mk" # Default path to external Facebook components and shared build toools I.e fb303 etc. # To point to other locations set environment variable EXTERNAL_PATH. # To change the current default you must change bootstrap.sh. FB_WITH_EXTERNAL_PATH([`pwd`]) AC_ARG_VAR([PY_PREFIX], [Prefix for installing Python modules. (Normal --prefix is ignored for Python because Python has different conventions.) Default = "/usr"]) AS_IF([test "x$PY_PREFIX" = x], [PY_PREFIX="/usr"]) ########################################################################## # User Configurable # Pre-defined macro to set opt build mode. Run with --disable-shared option to turn off optimization. FB_ENABLE_DEFAULT_OPT_BUILD # Predefined macro to set static library mode. Run with --disable-static option to turn off static lib mode. FB_ENABLE_DEFAULT_STATIC # Personalized feature generator. Creates defines/conditionals and --enable --disable command line options. # FB_ENABLE_FEATURE([FEATURE], [feature]) OR FB_ENABLE_FEATURE([FEATURE], [feature], [\"\"]) # Example: Macro supplies -DFACEBOOK at compile time and "if FACEBOOK endif" capabilities. # Personalized path generator Sets default paths. Provides --with-xx=DIR options. # FB_WITH_PATH([_home], [path], [] # Example: sets $(thrift_home) variable with default path set to /usr/local. FB_WITH_PATH([thrift_home], [thriftpath], [/usr/local]) AX_CXX_COMPILE_STDCXX_11([noext]) AX_THRIFT_LIB(cpp, [C++], yes) have_cpp=no if test "$with_cpp" = "yes"; then # Require boost 1.40.0 or later AX_BOOST_BASE([1.40.0]) if test "x$succeeded" = "xyes"; then have_cpp="yes" fi fi AM_CONDITIONAL([WITH_CPP], [test "$have_cpp" = "yes"]) AX_THRIFT_LIB(java, [Java], yes) if test "$with_java" = "yes"; then AX_JAVAC_AND_JAVA AC_PATH_PROG([ANT], [ant]) AX_CHECK_ANT_VERSION($ANT, 1.7) AC_SUBST(CLASSPATH) AC_SUBST(ANT_FLAGS) if test "x$JAVAC" != "x" && test "x$JAVAC" != "x" && test "x$ANT" != "x" ; then have_java="yes" fi fi AM_CONDITIONAL(WITH_JAVA, [test "$have_java" = "yes"]) AX_THRIFT_LIB(php, [PHP], yes) if test "$with_php" = "yes"; then AC_PATH_PROG([PHP], [php]) if test "x$PHP" != "x" && test "x$PHP" != "x:" ; then have_php="yes" fi fi AM_CONDITIONAL(WITH_PHP, [test "$have_php" = "yes"]) AX_THRIFT_LIB(python, [Python], yes) if test "$with_python" = "yes"; then AM_PATH_PYTHON(2.4,, :) if test "x$PYTHON" != "x" && test "x$PYTHON" != "x:" ; then have_python="yes" fi fi AM_CONDITIONAL(WITH_PYTHON, [test "$have_python" = "yes"]) # Generates Makefile from Makefile.am. Modify when new subdirs are added. # Change Makefile.am also to add subdirectly. AC_CONFIG_FILES(Makefile cpp/Makefile py/Makefile) # Check for headers AC_CHECK_HEADERS([inttypes.h]) AC_CHECK_HEADERS([netinet/in.h]) ############################################################################ # DO NOT TOUCH. AC_SUBST(PRODUCT_MK) AC_OUTPUT ############################################################################# ######### FINISH ############################################################ echo "EXTERNAL_PATH $EXTERNAL_PATH" echo echo "Building C++ Library ......... : $have_cpp" echo "Building Java Library ........ : $have_java" echo "Building Python Library ...... : $have_python" echo "Building PHP Library ......... : $have_php" # # NOTES FOR USER # Short cut to create conditional flags. #enable_facebook="yes" #AM_CONDITIONAL([FACEBOOK], [test "$enable_facebook" = yes]) #enable_hdfs="yes" #AM_CONDITIONAL([HDFS], [test "$enable_hdfs" = yes]) # Enable options with --enable and --disable configurable. #AC_MSG_CHECKING([whether to enable FACEBOOK]) #FACEBOOK="" #AC_ARG_ENABLE([facebook], # [ --enable-facebook Enable facebook.], # [ # ENABLE_FACEBOOK=$enableval # ], # [ # ENABLE_FACEBOOK="no" # ] #) #AM_CONDITIONAL([FACEBOOK], [test "$ENABLE_FACEBOOK" = yes]) #AC_MSG_RESULT($ENABLE_FACEBOOK) thrift-0.23.0/contrib/mingw-cross-compile.sh0000775000175000017500000000075615165535636021302 0ustar00buildbuild00000000000000#!/bin/sh set -e ./configure \ --disable-libs \ --build=i686-pc-linux-gnu \ --host=i586-mingw32msvc \ CC=i586-mingw32msvc-gcc CXX=i586-mingw32msvc-g++ make # Check two locations to be compatible with libtool 1.5.26 or 2.2.6b. if test -f compiler/cpp/.libs/thrift.exe ; then i586-mingw32msvc-strip compiler/cpp/.libs/thrift.exe -o ./thrift.exe else i586-mingw32msvc-strip compiler/cpp/thrift.exe -o ./thrift.exe fi echo "Finished compiling with resulting exe" ls -l ./thrift.exe thrift-0.23.0/contrib/README.md0000664000175000017500000000143015165535636016312 0ustar00buildbuild00000000000000Apache Thrift contrib folder ======================================== The code in the /contrib folder is not maintained on a regular basis and its purpose is mainly to serve as repository of (a) sample code what can be done with Thrift and (b) possibly helpfil utilities or other potentially useful stuff. You are of course free to provide patches for it, but other than that, the contrib stuff may or may not work for your purpose, environment or software version, as it does not part of regular testing procedures. Below are some links (3rd-party sites) that lead you to some fairly good explanations of how it works. * https://drewdevault.com/2020/06/06/Add-a-contrib-directory.html * https://softwareengineering.stackexchange.com/questions/252053/whats-in-the-contrib-folder thrift-0.23.0/contrib/vagrant/0000775000175000017500000000000015165535636016477 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/vagrant/centos-6.5/0000775000175000017500000000000015165535636020300 5ustar00buildbuild00000000000000thrift-0.23.0/contrib/vagrant/centos-6.5/README.md0000664000175000017500000000520515165535636021561 0ustar00buildbuild00000000000000Apache Thrift Centos 6.5 Vagrant Support ======================================== This directory is the Vagrant project directory for Apache Thrift running on Centos 6.5. The Vagrantfile in this directory configures a Vagrant provisioned VM launched under VirtualBox. To use this project you must have a recent version of VirtualBox and Vagrant installed (in that order). To run the VM, open a shell, clone Apache Thrift, change to this directory and enter the Vagrant up command. $ git clone https://github.com/apache/thrift $ cd thrift/contrib/vagrant/centos-6.5 $ vagrant up This will download and launch the base box VM under VirtualBox and run the Apache Thrift provisioning script. This will take up to an hour depending on your hardware and network. Once complete you can login to the box with Vagrant ssh. The thrift source tree from your host os is mounted at /thrift. $ vagrant ssh [vagrant@thrift ~]$ cd /thrift [vagrant@thrift thrift]$ compiler/cpp/thrift --version Thrift version The provisioning script (inside the Vagrantfile) runs ./bootstrap.sh, ./configure, make and make check, but does not install thrift. To install thrift run "make install". The Vagrant base box used here is a minimal Centos 6.5 VirtualBox with 2GB RAM and 2 CPUs. For more Vagrant information: https://www.vagrantup.com. A summary of the base box preparation follows: root password: vagrant #Create the vagrant user and give it sudo permission adduser vagrant passwd vagrant visudo : vagrant ALL=(ALL) NOPASSWD: ALL #Defaults requiretty #Shut down the firewall and disable it service iptables stop chkconfig iptables off #Setup the vagrant ssh public key to allow vagrant to ssh mkdir /home/vagrant/.ssh chmod 700 /home/vagrant/.ssh cd /home/vagrant/.ssh wget --no-check-certificate 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' -O authorized_keys chmod 600 /home/vagrant/.ssh/authorized_keys chown -R vagrant /home/vagrant/.ssh #Install EPEL (Extra Packages for Enterprise Linux) but protect the base #repositories so that EPEL does not mask base packages yum -y install yum-plugin-protectbase rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm #Install perl, dynamic kernel modules, dev tools and kernel headers to support #Virtual box additions yum -y install perl yum -y --enablerepo epel install dkms yum -y groupinstall "Development Tools" yum -y install kernel-devel #Update everything and reboot yum update reboot #Install the VirtualBox Guest additions (using VirtualBox iso) mount /dev/cdrom /mnt /mnt/VBoxLinuxAdditions.run umount /mnt See the Vagrantfile for further details thrift-0.23.0/contrib/vagrant/centos-6.5/Vagrantfile0000664000175000017500000002272115165535636022471 0ustar00buildbuild00000000000000# -*- mode: ruby -*- # vi: set ft=ruby : # 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. # APACHE THRIFT PROVISIONING SCRIPT ############################################################## # This script is used to configure the base Centos 6.5 # Vagrant box for Apache Thrift compiler and lib builds. # The base box is Centos 6.5 with no additional packages # except those required to support VirtualBox Guest tools: # perl, dkms, kernel-devel and the "Development Tools" group. # The epel repo was also added along with the # yum-plugin-protectbase package to prefer base repo packages. # The script below provisions ALL languages. This will take # time. You can greatly reduce the build time by commenting # out the LIB provisioning for uneeded language libraries. # Expect full provisioning to take 30 minutes on a fast # machine with an excellent Internet connection (and another # 15 minutes for the build). # # Machine accounts: # - User: vagrant/vagrant # - Admin: root/vagrant # Vagrant public ssh key also installed ############################################################## $build_and_test = <